From 152be331918c106ec74142524651d03e11a28ee6 Mon Sep 17 00:00:00 2001 From: Reimar Date: Sun, 24 Mar 2024 22:24:44 +0100 Subject: [PATCH] Use HTML for Holyc files as well --- Copy.HC | 48 +- file_index.xslt | 21 +- public/Wb/Adam/ABlkDev/ADskA.HC.HTML | 283 + public/Wb/Adam/ABlkDev/ADskB.HC.HTML | 222 + public/Wb/Adam/ABlkDev/DskChk.HC.HTML | 475 + public/Wb/Adam/ABlkDev/DskPrt.HC.HTML | 198 + public/Wb/Adam/ABlkDev/FileMgr.HC.HTML | 822 ++ public/Wb/Adam/ABlkDev/MakeABlkDev.HC.HTML | 39 + public/Wb/Adam/ABlkDev/Mount.HC.HTML | 190 + public/Wb/Adam/ADbg.HC.HTML | 301 + public/Wb/Adam/ADefine.HC.HTML | 68 + public/Wb/Adam/AExts.HC.HTML | 126 + public/Wb/Adam/AHash.HC.HTML | 462 + public/Wb/Adam/AMath.HC.HTML | 166 + public/Wb/Adam/AMathODE.HC.HTML | 719 ++ public/Wb/Adam/AMem.HC.HTML | 210 + public/Wb/Adam/AMouse.HC.HTML | 51 + public/Wb/Adam/ARegistry.HC.HTML | 234 + public/Wb/Adam/ASnd.HC.HTML | 440 + public/Wb/Adam/AutoComplete/ACDictGen.HC.HTML | 292 + public/Wb/Adam/AutoComplete/ACFill.HC.HTML | 257 + public/Wb/Adam/AutoComplete/ACInit.HC.HTML | 200 + public/Wb/Adam/AutoComplete/ACTask.HC.HTML | 314 + public/Wb/Adam/AutoComplete/MakeAC.HC.HTML | 37 + public/Wb/Adam/CPURep.HC.HTML | 103 + public/Wb/Adam/Ctrls/CtrlsA.HC.HTML | 419 + public/Wb/Adam/Ctrls/CtrlsBttn.HC.HTML | 122 + public/Wb/Adam/Ctrls/CtrlsSlider.HC.HTML | 245 + public/Wb/Adam/Ctrls/MakeCtrls.HC.HTML | 39 + public/Wb/Adam/DevInfo.HC.HTML | 251 + public/Wb/Adam/DolDoc/DocBin.HC.HTML | 173 + public/Wb/Adam/DolDoc/DocChar.HC.HTML | 683 ++ public/Wb/Adam/DolDoc/DocClipBoard.HC.HTML | 156 + public/Wb/Adam/DolDoc/DocCodeTools.HC.HTML | 689 ++ public/Wb/Adam/DolDoc/DocDblBuf.HC.HTML | 141 + public/Wb/Adam/DolDoc/DocEd.HC.HTML | 296 + public/Wb/Adam/DolDoc/DocExt.HC.HTML | 45 + public/Wb/Adam/DolDoc/DocFile.HC.HTML | 388 + public/Wb/Adam/DolDoc/DocFind.HC.HTML | 615 ++ public/Wb/Adam/DolDoc/DocForm.HC.HTML | 375 + public/Wb/Adam/DolDoc/DocGet.HC.HTML | 274 + public/Wb/Adam/DolDoc/DocGr.HC.HTML | 194 + public/Wb/Adam/DolDoc/DocHighlight.HC.HTML | 191 + public/Wb/Adam/DolDoc/DocInit.HC.HTML | 143 + public/Wb/Adam/DolDoc/DocLink.HC.HTML | 389 + public/Wb/Adam/DolDoc/DocMacro.HC.HTML | 242 + public/Wb/Adam/DolDoc/DocNew.HC.HTML | 416 + public/Wb/Adam/DolDoc/DocPlain.HC.HTML | 642 ++ public/Wb/Adam/DolDoc/DocPopUp.HC.HTML | 348 + public/Wb/Adam/DolDoc/DocPutKey.HC.HTML | 760 ++ public/Wb/Adam/DolDoc/DocPutS.HC.HTML | 367 + public/Wb/Adam/DolDoc/DocRecalc.HC.HTML | 1355 +++ public/Wb/Adam/DolDoc/DocRecalcLib.HC.HTML | 244 + public/Wb/Adam/DolDoc/DocRun.HC.HTML | 134 + public/Wb/Adam/DolDoc/DocTerm.HC.HTML | 244 + public/Wb/Adam/DolDoc/DocTree.HC.HTML | 274 + public/Wb/Adam/DolDoc/DocWidgetWiz.HC.HTML | 1194 +++ public/Wb/Adam/DolDoc/MakeDoc.HC.HTML | 100 + public/Wb/Adam/God/GodBible.HC.HTML | 379 + public/Wb/Adam/God/GodDoodle.HC.HTML | 223 + public/Wb/Adam/God/GodExt.HC.HTML | 57 + public/Wb/Adam/God/GodSong.HC.HTML | 202 + public/Wb/Adam/God/HolySpirit.HC.HTML | 190 + public/Wb/Adam/God/MakeGod.HC.HTML | 40 + public/Wb/Adam/Gr/Gr.HH | 0 public/Wb/Adam/Gr/Gr.HH.HTML | 211 + public/Wb/Adam/Gr/GrAsm.HC.HTML | 441 + public/Wb/Adam/Gr/GrBitMap.HC.HTML | 2085 ++++ public/Wb/Adam/Gr/GrComposites.HC.HTML | 375 + public/Wb/Adam/Gr/GrDC.HC.HTML | 465 + public/Wb/Adam/Gr/GrEnd.HC.HTML | 60 + public/Wb/Adam/Gr/GrExt.HC.HTML | 39 + public/Wb/Adam/Gr/GrGlbls.HC.HTML | 86 + public/Wb/Adam/Gr/GrInitA.HC.HTML | 52 + public/Wb/Adam/Gr/GrInitB.HC.HTML | 240 + public/Wb/Adam/Gr/GrMath.HC.HTML | 836 ++ public/Wb/Adam/Gr/GrPalette.HC.HTML | 124 + public/Wb/Adam/Gr/GrPrimatives.HC.HTML | 1853 ++++ public/Wb/Adam/Gr/GrScrn.HC.HTML | 454 + public/Wb/Adam/Gr/GrSpritePlot.HC.HTML | 506 + public/Wb/Adam/Gr/GrTextBase.HC.HTML | 394 + public/Wb/Adam/Gr/MakeGr.HC.HTML | 64 + public/Wb/Adam/Gr/ScrnCast.HC.HTML | 127 + public/Wb/Adam/Gr/SpriteBitMap.HC.HTML | 701 ++ public/Wb/Adam/Gr/SpriteCode.HC.HTML | 634 ++ public/Wb/Adam/Gr/SpriteEd.HC.HTML | 1209 +++ public/Wb/Adam/Gr/SpriteMain.HC.HTML | 1269 +++ public/Wb/Adam/Gr/SpriteMesh.HC.HTML | 1539 +++ public/Wb/Adam/Gr/SpriteNew.HC.HTML | 220 + public/Wb/Adam/Gr/SpriteSideBar.HC.HTML | 126 + public/Wb/Adam/Host.HC.HTML | 101 + public/Wb/Adam/InFile.HC.HTML | 171 + public/Wb/Adam/InsReg.HC.HTML | 95 + public/Wb/Adam/MakeAdam.HC.HTML | 63 + public/Wb/Adam/Menu.HC.HTML | 274 + public/Wb/Adam/Opt/Boot/BootDVD.HC.HTML | 219 + public/Wb/Adam/Opt/Boot/BootDVDIns.HC.HTML | 63 + public/Wb/Adam/Opt/Boot/BootHD.HC.HTML | 124 + public/Wb/Adam/Opt/Boot/BootHDIns.HC.HTML | 91 + public/Wb/Adam/Opt/Boot/BootMHD.HC.HTML | 138 + public/Wb/Adam/Opt/Boot/BootMHD2.HC.HTML | 154 + public/Wb/Adam/Opt/Boot/BootMHDIns.HC.HTML | 183 + public/Wb/Adam/Opt/Boot/BootRAM.HC.HTML | 91 + public/Wb/Adam/Opt/Boot/DskISORedSea.HC.HTML | 219 + public/Wb/Adam/Opt/Boot/MakeBoot.HC.HTML | 37 + public/Wb/Adam/Opt/Utils/Diff.HC.HTML | 384 + public/Wb/Adam/Opt/Utils/DocUtils.HC.HTML | 187 + public/Wb/Adam/Opt/Utils/Find.HC.HTML | 288 + public/Wb/Adam/Opt/Utils/HeapLog.HC.HTML | 242 + public/Wb/Adam/Opt/Utils/LineRep.HC.HTML | 140 + public/Wb/Adam/Opt/Utils/LinkChk.HC.HTML | 110 + public/Wb/Adam/Opt/Utils/MakeUtils.HC.HTML | 46 + public/Wb/Adam/Opt/Utils/MemRep.HC.HTML | 262 + public/Wb/Adam/Opt/Utils/Merge.HC.HTML | 108 + public/Wb/Adam/Opt/Utils/Profiler.HC.HTML | 133 + public/Wb/Adam/Opt/Utils/StrUtils.HC.HTML | 237 + public/Wb/Adam/Opt/Utils/TOS.HC.HTML | 107 + public/Wb/Adam/Opt/Utils/ToDolDoc.HC.HTML | 50 + public/Wb/Adam/Opt/Utils/ToTXT.HC.HTML | 163 + public/Wb/Adam/TaskRep.HC.HTML | 61 + public/Wb/Adam/TaskSettings.HC.HTML | 151 + public/Wb/Adam/Training.HC.HTML | 215 + public/Wb/Adam/WallPaper.HC.HTML | 196 + public/Wb/Adam/Win.HC.HTML | 573 + public/Wb/Adam/WinMgr.HC.HTML | 894 ++ public/Wb/Apps/Budget/BgtAccts.HC.HTML | 114 + public/Wb/Apps/Budget/BgtEntry.HC.HTML | 114 + public/Wb/Apps/Budget/BgtFile.HC.HTML | 171 + public/Wb/Apps/Budget/BgtMain.HC.HTML | 261 + public/Wb/Apps/Budget/BgtStrs.HC.HTML | 163 + public/Wb/Apps/Budget/BgtTemplate.HC.HTML | 213 + public/Wb/Apps/Budget/Budget.HC.HTML | 108 + public/Wb/Apps/Budget/Install.HC.HTML | 36 + public/Wb/Apps/Budget/Load.HC.HTML | 43 + public/Wb/Apps/Budget/Run.HC.HTML | 35 + public/Wb/Apps/GrModels/BallGen.HC.HTML | 159 + public/Wb/Apps/GrModels/Load.HC.HTML | 39 + public/Wb/Apps/GrModels/ManGen.HC.HTML | 351 + public/Wb/Apps/GrModels/Models.HC.HTML | 56 + public/Wb/Apps/GrModels/Run.HC.HTML | 33 + public/Wb/Apps/KeepAway/KeepAway.HC.HTML | 740 ++ public/Wb/Apps/KeepAway/Load.HC.HTML | 37 + public/Wb/Apps/KeepAway/Run.HC.HTML | 33 + public/Wb/Apps/Logic/Load.HC.HTML | 37 + public/Wb/Apps/Logic/Logic.HC.HTML | 621 ++ public/Wb/Apps/Logic/Run.HC.HTML | 33 + .../Apps/Psalmody/Examples/childish.HC.HTML | 55 + .../Wb/Apps/Psalmody/Examples/night.HC.HTML | 114 + .../Wb/Apps/Psalmody/Examples/prosper.HC.HTML | 87 + public/Wb/Apps/Psalmody/Help.DD.HTML | 10 +- public/Wb/Apps/Psalmody/Install.HC.HTML | 33 + public/Wb/Apps/Psalmody/JukeBox.HC.HTML | 231 + public/Wb/Apps/Psalmody/JukePuppet.HC.HTML | 126 + public/Wb/Apps/Psalmody/Load.HC.HTML | 43 + public/Wb/Apps/Psalmody/Psalmody.HC.HTML | 95 + public/Wb/Apps/Psalmody/PsalmodyCtrls.HC.HTML | 120 + public/Wb/Apps/Psalmody/PsalmodyDraw.HC.HTML | 440 + public/Wb/Apps/Psalmody/PsalmodyFile.HC.HTML | 458 + public/Wb/Apps/Psalmody/PsalmodyMain.HC.HTML | 829 ++ public/Wb/Apps/Psalmody/Run.HC.HTML | 34 + public/Wb/Apps/Span/Install.HC.HTML | 32 + public/Wb/Apps/Span/Load.HC.HTML | 41 + public/Wb/Apps/Span/Run.HC.HTML | 34 + public/Wb/Apps/Span/Span.HH | 0 public/Wb/Apps/Span/Span.HH.HTML | 80 + public/Wb/Apps/Span/SpanBridge.HC.HTML | 111 + public/Wb/Apps/Span/SpanDerive.HC.HTML | 78 + public/Wb/Apps/Span/SpanMain.HC.HTML | 499 + public/Wb/Apps/Span/SpanNew.HC.HTML | 157 + public/Wb/Apps/Strut/Load.HC.HTML | 37 + public/Wb/Apps/Strut/Run.HC.HTML | 34 + public/Wb/Apps/Strut/Strut.HC.HTML | 667 ++ public/Wb/Apps/TimeClock/Install.HC.HTML | 39 + public/Wb/Apps/TimeClock/Load.HC.HTML | 38 + public/Wb/Apps/TimeClock/TimeClk.HC.HTML | 182 + public/Wb/Apps/Titanium/Load.HC.HTML | 37 + public/Wb/Apps/Titanium/Run.HC.HTML | 33 + public/Wb/Apps/Titanium/Titanium.HC.HTML | 996 ++ public/Wb/Apps/ToTheFront/AIs/Human.HC.HTML | 197 + .../Wb/Apps/ToTheFront/AIs/SimpleAI.HC.HTML | 110 + public/Wb/Apps/ToTheFront/Install.HC.HTML | 33 + public/Wb/Apps/ToTheFront/Load.HC.HTML | 44 + public/Wb/Apps/ToTheFront/Run.HC.HTML | 33 + public/Wb/Apps/ToTheFront/TTFDraw.HC.HTML | 243 + public/Wb/Apps/ToTheFront/TTFFire.HC.HTML | 309 + public/Wb/Apps/ToTheFront/TTFGlbls.HC.HTML | 139 + public/Wb/Apps/ToTheFront/TTFInit.HC.HTML | 445 + public/Wb/Apps/ToTheFront/TTFLib.HC.HTML | 152 + public/Wb/Apps/ToTheFront/TTFMove.HC.HTML | 160 + public/Wb/Apps/ToTheFront/TTFVis.HC.HTML | 254 + public/Wb/Apps/ToTheFront/ToTheFront.HC.HTML | 245 + public/Wb/Apps/Vocabulary/Load.HC.HTML | 37 + public/Wb/Apps/Vocabulary/Run.HC.HTML | 33 + public/Wb/Apps/Vocabulary/VocabQuiz.HC.HTML | 88 + public/Wb/Apps/X-Caliber/Load.HC.HTML | 38 + public/Wb/Apps/X-Caliber/Run.HC.HTML | 33 + public/Wb/Apps/X-Caliber/X-Caliber.HC.HTML | 1549 +++ public/Wb/Apps/X-Caliber/XCCtrls.HC.HTML | 185 + public/Wb/Compiler/Asm.HC.HTML | 1145 ++ public/Wb/Compiler/AsmInit.HC.HTML | 240 + public/Wb/Compiler/AsmLib.HC.HTML | 206 + public/Wb/Compiler/AsmResolve.HC.HTML | 248 + public/Wb/Compiler/BackA.HC.HTML | 689 ++ public/Wb/Compiler/BackB.HC.HTML | 750 ++ public/Wb/Compiler/BackC.HC.HTML | 802 ++ public/Wb/Compiler/BackFA.HC.HTML | 638 ++ public/Wb/Compiler/BackFB.HC.HTML | 662 ++ public/Wb/Compiler/BackLib.HC.HTML | 739 ++ public/Wb/Compiler/CExcept.HC.HTML | 284 + public/Wb/Compiler/CExts.HC.HTML | 77 + public/Wb/Compiler/CHash.HC.HTML | 172 + public/Wb/Compiler/CInit.HC.HTML | 361 + public/Wb/Compiler/CMain.HC.HTML | 733 ++ public/Wb/Compiler/CMisc.HC.HTML | 200 + public/Wb/Compiler/CompilerA.HH | 0 public/Wb/Compiler/CompilerA.HH.HTML | 437 + public/Wb/Compiler/CompilerB.HH | 0 public/Wb/Compiler/CompilerB.HH.HTML | 110 + public/Wb/Compiler/Lex.HC.HTML | 1226 +++ public/Wb/Compiler/LexLib.HC.HTML | 306 + public/Wb/Compiler/OpCodes.DD.HTML | 2 +- public/Wb/Compiler/OptLib.HC.HTML | 596 ++ public/Wb/Compiler/OptPass012.HC.HTML | 1319 +++ public/Wb/Compiler/OptPass3.HC.HTML | 653 ++ public/Wb/Compiler/OptPass4.HC.HTML | 720 ++ public/Wb/Compiler/OptPass5.HC.HTML | 121 + public/Wb/Compiler/OptPass6.HC.HTML | 216 + public/Wb/Compiler/OptPass789A.HC.HTML | 1183 +++ public/Wb/Compiler/PrsExp.HC.HTML | 1209 +++ public/Wb/Compiler/PrsLib.HC.HTML | 354 + public/Wb/Compiler/PrsStmt.HC.HTML | 1253 +++ public/Wb/Compiler/PrsVar.HC.HTML | 752 ++ public/Wb/Compiler/Templates.HC.HTML | 543 + public/Wb/Compiler/UAsm.HC.HTML | 713 ++ .../Demo/AcctExample/HomeKeyPlugIns.HC.HTML | 320 + .../Wb/Demo/AcctExample/HomeLocalize.HC.HTML | 52 + public/Wb/Demo/AcctExample/HomeSys.HC.HTML | 78 + .../Wb/Demo/AcctExample/HomeWrappers.HC.HTML | 66 + public/Wb/Demo/AcctExample/MakeHome.HC.HTML | 47 + public/Wb/Demo/AcctExample/Once.HC.HTML | 70 + .../Wb/Demo/AcctExample/PersonalNotes.DD.HTML | 204 +- public/Wb/Demo/AcctExample/Registry.HC.HTML | 37 + .../Wb/Demo/AcctExample/TOS/MakeTOS.HC.HTML | 39 + public/Wb/Demo/AcctExample/TOS/TOSCfg.HC.HTML | 92 + .../Wb/Demo/AcctExample/TOS/TOSDistro.HC.HTML | 418 + public/Wb/Demo/AcctExample/TOS/TOSExt.HC.HTML | 341 + .../Wb/Demo/AcctExample/TOS/TOSMisc.HC.HTML | 194 + .../Wb/Demo/AcctExample/TOS/TOSTheme.HC.HTML | 233 + public/Wb/Demo/Asm/AsmAndC1.HC.HTML | 106 + public/Wb/Demo/Asm/AsmAndC2.HC.HTML | 116 + public/Wb/Demo/Asm/AsmAndC3.HC.HTML | 54 + public/Wb/Demo/Asm/AsmHelloWorld.HC.HTML | 81 + public/Wb/Demo/Asm/BuzzFizz.HC.HTML | 215 + public/Wb/Demo/Asm/DivByHand.HC.HTML | 52 + public/Wb/Demo/Asm/MulByHand.HC.HTML | 100 + public/Wb/Demo/Asm/PutDec.HC.HTML | 80 + public/Wb/Demo/Carry.HC.HTML | 76 + public/Wb/Demo/ClassMeta.HC.HTML | 111 + public/Wb/Demo/CompileDemo.HC.HTML | 68 + public/Wb/Demo/DateTime.HC.HTML | 42 + public/Wb/Demo/DbgDemo.HC.HTML | 57 + public/Wb/Demo/Define.HC.HTML | 67 + public/Wb/Demo/Directives.HC.HTML | 44 + public/Wb/Demo/DolDoc/CallBack.HC.HTML | 95 + public/Wb/Demo/DolDoc/ClickCallBack.HC.HTML | 78 + public/Wb/Demo/DolDoc/CursorMove.HC.HTML | 69 + public/Wb/Demo/DolDoc/Data.HC.HTML | 94 + public/Wb/Demo/DolDoc/DefineStr.HC.HTML | 53 + public/Wb/Demo/DolDoc/FileRead.HC.HTML | 111 + public/Wb/Demo/DolDoc/Form.HC.HTML | 82 + public/Wb/Demo/DolDoc/MenuBttn.HC.HTML | 106 + public/Wb/Demo/DolDoc/MenuSprite.HC.HTML | 63 + public/Wb/Demo/DolDoc/NumBible.HC.HTML | 59 + public/Wb/Demo/DolDoc/TextDemo.HC.HTML | 54 + public/Wb/Demo/DolDoc/TreeDemo.HC.HTML | 70 + public/Wb/Demo/DolDoc/UnusedDefine.HC.HTML | 113 + public/Wb/Demo/Dsk/BlkDevRep.HC.HTML | 44 + public/Wb/Demo/Dsk/DataBase.HC.HTML | 95 + public/Wb/Demo/Dsk/DskRaw.HC.HTML | 72 + public/Wb/Demo/Dsk/FPrintF.HC.HTML | 80 + public/Wb/Demo/Dsk/SerializeTree.HC.HTML | 66 + public/Wb/Demo/Dsk/UnusedSpaceRep.HC.HTML | 43 + public/Wb/Demo/Exceptions.HC.HTML | 78 + public/Wb/Demo/ExtChars.HC.HTML | 66 + public/Wb/Demo/Games/BattleLines.HC.HTML | 413 + public/Wb/Demo/Games/BigGuns.HC.HTML | 346 + public/Wb/Demo/Games/BlackDiamond.HC.HTML | 430 + public/Wb/Demo/Games/BomberGolf.HC.HTML | 389 + .../Wb/Demo/Games/CastleFrankenstein.HC.HTML | 627 ++ public/Wb/Demo/Games/CharDemo.HC.HTML | 222 + public/Wb/Demo/Games/CircleTrace.HC.HTML | 159 + public/Wb/Demo/Games/Collision.HC.HTML | 185 + public/Wb/Demo/Games/Digits.HC.HTML | 111 + public/Wb/Demo/Games/DunGen.HC.HTML | 478 + public/Wb/Demo/Games/ElephantWalk.HC.HTML | 117 + public/Wb/Demo/Games/FlapBat.HC.HTML | 305 + public/Wb/Demo/Games/FlatTops.HC.HTML | 919 ++ public/Wb/Demo/Games/Halogen.HC.HTML | 193 + public/Wb/Demo/Games/MassSpring.HC.HTML | 200 + public/Wb/Demo/Games/Maze.HC.HTML | 143 + public/Wb/Demo/Games/RainDrops.HC.HTML | 220 + public/Wb/Demo/Games/RawHide.HC.HTML | 622 ++ public/Wb/Demo/Games/Rocket.HC.HTML | 237 + public/Wb/Demo/Games/RocketScience.HC.HTML | 328 + public/Wb/Demo/Games/Squirt.HC.HTML | 415 + public/Wb/Demo/Games/Stadium/Stadium.HC.HTML | 165 + .../Wb/Demo/Games/Stadium/StadiumGen.HC.HTML | 64 + public/Wb/Demo/Games/Talons.HC.HTML | 1264 +++ public/Wb/Demo/Games/TheDead.HC.HTML | 218 + public/Wb/Demo/Games/TicTacToe.HC.HTML | 156 + public/Wb/Demo/Games/TreeCheckers.HC.HTML | 388 + public/Wb/Demo/Games/Varoom.HC.HTML | 734 ++ public/Wb/Demo/Games/Wenceslas.HC.HTML | 623 ++ public/Wb/Demo/Games/Whap.HC.HTML | 204 + public/Wb/Demo/Games/Zing.HC.HTML | 236 + public/Wb/Demo/Games/ZoneOut.HC.HTML | 349 + public/Wb/Demo/GlblVars.HC.HTML | 107 + public/Wb/Demo/Graphics/3DPoly.HC.HTML | 148 + public/Wb/Demo/Graphics/BSpline.HC.HTML | 66 + public/Wb/Demo/Graphics/Balloon.HC.HTML | 69 + public/Wb/Demo/Graphics/Blot.HC.HTML | 72 + public/Wb/Demo/Graphics/Bounce.HC.HTML | 78 + public/Wb/Demo/Graphics/Box.HC.HTML | 81 + public/Wb/Demo/Graphics/Cartesian.HC.HTML | 79 + public/Wb/Demo/Graphics/CharAnimation.HC.HTML | 61 + public/Wb/Demo/Graphics/Collision.HC.HTML | 73 + .../Wb/Demo/Graphics/CommonAncestor.HC.HTML | 151 + public/Wb/Demo/Graphics/Doodle.HC.HTML | 78 + public/Wb/Demo/Graphics/EdSprite.HC.HTML | 123 + public/Wb/Demo/Graphics/Elephant.HC.HTML | 236 + public/Wb/Demo/Graphics/Extents.HC.HTML | 76 + public/Wb/Demo/Graphics/FontEd.HC.HTML | 183 + public/Wb/Demo/Graphics/Grid.HC.HTML | 61 + public/Wb/Demo/Graphics/Hanoi.HC.HTML | 185 + public/Wb/Demo/Graphics/Lattice.HC.HTML | 297 + public/Wb/Demo/Graphics/Life.HC.HTML | 129 + public/Wb/Demo/Graphics/LightTable.HC.HTML | 680 ++ public/Wb/Demo/Graphics/Lines.HC.HTML | 57 + public/Wb/Demo/Graphics/LowPassFilter.HC.HTML | 114 + public/Wb/Demo/Graphics/MathAudioDemo.HC.HTML | 137 + public/Wb/Demo/Graphics/MouseDemo.HC.HTML | 42 + public/Wb/Demo/Graphics/NetOfDots.HC.HTML | 47 + public/Wb/Demo/Graphics/Palette.HC.HTML | 58 + public/Wb/Demo/Graphics/PanText.HC.HTML | 66 + public/Wb/Demo/Graphics/Pick.HC.HTML | 117 + public/Wb/Demo/Graphics/Pick3D.HC.HTML | 357 + public/Wb/Demo/Graphics/PoleZeros.HC.HTML | 204 + public/Wb/Demo/Graphics/PredatorPrey.HC.HTML | 112 + public/Wb/Demo/Graphics/RotateTank.HC.HTML | 91 + public/Wb/Demo/Graphics/ScrnCapture.HC.HTML | 46 + public/Wb/Demo/Graphics/ScrollBars.HC.HTML | 100 + public/Wb/Demo/Graphics/Shading.HC.HTML | 208 + public/Wb/Demo/Graphics/Shadow.HC.HTML | 133 + public/Wb/Demo/Graphics/Slider.HC.HTML | 141 + public/Wb/Demo/Graphics/Speedline.HC.HTML | 81 + public/Wb/Demo/Graphics/SpritePlot.HC.HTML | 92 + public/Wb/Demo/Graphics/SpritePlot3D.HC.HTML | 84 + public/Wb/Demo/Graphics/SpritePut.HC.HTML | 70 + public/Wb/Demo/Graphics/SpritePutExt.HC.HTML | 57 + public/Wb/Demo/Graphics/SpriteRaw.HC.HTML | 69 + public/Wb/Demo/Graphics/SpriteText.HC.HTML | 81 + public/Wb/Demo/Graphics/SunMoon.HC.HTML | 74 + public/Wb/Demo/Graphics/Symmetry.HC.HTML | 93 + public/Wb/Demo/Graphics/Transform.HC.HTML | 253 + public/Wb/Demo/Graphics/WallPaperCtrl.HC.HTML | 139 + public/Wb/Demo/Graphics/WallPaperFish.HC.HTML | 146 + public/Wb/Demo/Graphics/WinZBuf.HC.HTML | 54 + public/Wb/Demo/InFile/InPopUp.HC.HTML | 43 + public/Wb/Demo/InFile/InSetIP.HC.HTML | 44 + public/Wb/Demo/KeyBitMap.HC.HTML | 71 + public/Wb/Demo/LastClass.HC.HTML | 64 + public/Wb/Demo/Lectures/64BitAsmQuiz.DD.HTML | 6 +- public/Wb/Demo/Lectures/AndNotMod.HC.HTML | 75 + public/Wb/Demo/Lectures/FixedPoint.HC.HTML | 127 + .../Demo/Lectures/FixedPointAdvanced.HC.HTML | 204 + .../Wb/Demo/Lectures/GraphicsCPULoad.HC.HTML | 65 + public/Wb/Demo/Lectures/InterruptDemo.HC.HTML | 116 + public/Wb/Demo/Lectures/MiniCompiler.HC.HTML | 277 + public/Wb/Demo/Lectures/MiniGrLib.HC.HTML | 163 + public/Wb/Demo/Lectures/NegDisp.HC.HTML | 87 + public/Wb/Demo/Lectures/Optimization.HC.HTML | 139 + public/Wb/Demo/Lectures/PCIInterrupts.HC.HTML | 104 + public/Wb/Demo/Lectures/Ring3.HC.HTML | 106 + public/Wb/Demo/Lectures/ScrnMemory.HC.HTML | 80 + public/Wb/Demo/MagicPairs.HC.HTML | 406 + public/Wb/Demo/MemDemo.HC.HTML | 95 + public/Wb/Demo/MsgLoop.HC.HTML | 54 + public/Wb/Demo/MultiCore/Interrupts.HC.HTML | 54 + public/Wb/Demo/MultiCore/LoadTest.HC.HTML | 79 + public/Wb/Demo/MultiCore/Lock.HC.HTML | 83 + public/Wb/Demo/MultiCore/MPAdd.HC.HTML | 116 + public/Wb/Demo/MultiCore/MPPrint.HC.HTML | 48 + public/Wb/Demo/MultiCore/MPRadix.HC.HTML | 173 + public/Wb/Demo/MultiCore/Palindrome.HC.HTML | 127 + public/Wb/Demo/MultiCore/Primes.HC.HTML | 106 + public/Wb/Demo/NullCase.HC.HTML | 50 + public/Wb/Demo/OnceDemo.HC.HTML | 43 + public/Wb/Demo/ParenWarn.HC.HTML | 48 + public/Wb/Demo/PhoneNumWords.HC.HTML | 94 + public/Wb/Demo/Print.HC.HTML | 64 + public/Wb/Demo/Progress.HC.HTML | 111 + public/Wb/Demo/Prompt.HC.HTML | 56 + public/Wb/Demo/PullDownMenu.HC.HTML | 120 + public/Wb/Demo/RadixSort.HC.HTML | 93 + public/Wb/Demo/RandDemo.HC.HTML | 95 + public/Wb/Demo/RegistryDemo.HC.HTML | 58 + public/Wb/Demo/RevFileDemo/Rev.HC.HTML | 53 + public/Wb/Demo/ScrnCodes.HC.HTML | 58 + public/Wb/Demo/Snd/ASCIIOrgan.HC.HTML | 80 + public/Wb/Demo/Snd/MorseCode.HC.HTML | 207 + public/Wb/Demo/Snd/OhGreat.HC.HTML | 72 + public/Wb/Demo/Snd/WaterFowl.HC.HTML | 187 + .../Wb/Demo/SortFileDemo/F64FileGen.HC.HTML | 57 + .../Wb/Demo/SortFileDemo/F64FileSort.HC.HTML | 103 + public/Wb/Demo/Spy.HC.HTML | 93 + public/Wb/Demo/StkGrow.HC.HTML | 84 + public/Wb/Demo/SubIntAccess.HC.HTML | 60 + public/Wb/Demo/SubSwitch.HC.HTML | 52 + public/Wb/Demo/SuggestSpelling.HC.HTML | 123 + public/Wb/Demo/Templates/Game1.HC.HTML | 121 + public/Wb/Demo/Templates/Lex1.HC.HTML | 47 + public/Wb/Demo/Templates/MultiCore1.HC.HTML | 60 + public/Wb/Demo/Templates/ODE1.HC.HTML | 74 + public/Wb/Demo/Templates/Registry1.HC.HTML | 41 + public/Wb/Demo/Templates/Util1.HC.HTML | 45 + public/Wb/Demo/Templates/Util2.HC.HTML | 85 + public/Wb/Demo/TimeIns.HC.HTML | 66 + .../Wb/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML | 51 + public/Wb/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML | 39 + public/Wb/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML | 420 + public/Wb/Demo/WebLogDemo/WebLogRep.HC.HTML | 559 + .../Wb/Demo/WebLogDemo/WebLogScramble.HC.HTML | 100 + public/Wb/Demo/WordSearch.HC.HTML | 184 + public/Wb/Doc/Asm.DD.HTML | 6 +- public/Wb/Doc/AutoComplete.DD.HTML | 8 +- public/Wb/Doc/BlkChain.DD.HTML | 8 +- public/Wb/Doc/Boot.DD.HTML | 36 +- public/Wb/Doc/CharOverview.DD.HTML | 12 +- public/Wb/Doc/Charter.DD.HTML | 2 +- public/Wb/Doc/CmdLineOverview.DD.HTML | 8 +- public/Wb/Doc/Comm.HC.HTML | 163 + public/Wb/Doc/Credits.DD.HTML | 18 +- public/Wb/Doc/Ctrls.DD.HTML | 4 +- public/Wb/Doc/Customize.DD.HTML | 6 +- public/Wb/Doc/CutCorners.DD.HTML | 10 +- public/Wb/Doc/DbgOverview.DD.HTML | 58 +- public/Wb/Doc/Define.DD.HTML | 8 +- public/Wb/Doc/Demands.DD.HTML | 22 +- public/Wb/Doc/Directives.DD.HTML | 2 +- public/Wb/Doc/DolDoc.DD.HTML | 4 +- public/Wb/Doc/DolDocOverview.DD.HTML | 16 +- public/Wb/Doc/Features.DD.HTML | 4 +- public/Wb/Doc/FileLowLevel.DD.HTML | 2 +- public/Wb/Doc/FileMgr.DD.HTML | 14 +- public/Wb/Doc/FileUtils.DD.HTML | 30 +- public/Wb/Doc/Frame.DD.HTML | 2 +- public/Wb/Doc/GRFiles.DD.HTML | 4 +- public/Wb/Doc/Glossary.DD.HTML | 2 +- public/Wb/Doc/GraphicsOverview.DD.HTML | 68 +- public/Wb/Doc/GuideLines.DD.HTML | 52 +- public/Wb/Doc/Hash.DD.HTML | 16 +- public/Wb/Doc/HeapDbg.DD.HTML | 2 +- public/Wb/Doc/HelpIndex.DD.HTML | 2 +- public/Wb/Doc/HelpSystem.DD.HTML | 4 +- public/Wb/Doc/HolyC.DD.HTML | 62 +- public/Wb/Doc/InFile.DD.HTML | 12 +- public/Wb/Doc/Install.DD.HTML | 22 +- public/Wb/Doc/Job.DD.HTML | 28 +- public/Wb/Doc/KeyAlloc.DD.HTML | 14 +- public/Wb/Doc/KeyDev.DD.HTML | 16 +- public/Wb/Doc/Lex.DD.HTML | 4 +- public/Wb/Doc/MemOverview.DD.HTML | 38 +- public/Wb/Doc/Menus.DD.HTML | 10 +- public/Wb/Doc/Mouse.DD.HTML | 10 +- public/Wb/Doc/Msgs.DD.HTML | 2 +- public/Wb/Doc/MultiCore.DD.HTML | 14 +- public/Wb/Doc/ODE.DD.HTML | 8 +- public/Wb/Doc/Once.DD.HTML | 22 +- public/Wb/Doc/Options.DD.HTML | 18 +- public/Wb/Doc/Pags.DD.HTML | 4 +- public/Wb/Doc/PreProcessor.DD.HTML | 6 +- public/Wb/Doc/Print.DD.HTML | 60 +- public/Wb/Doc/Profiler.DD.HTML | 6 +- public/Wb/Doc/Que.DD.HTML | 2 +- public/Wb/Doc/Quirks.DD.HTML | 22 +- public/Wb/Doc/RedSea.DD.HTML | 10 +- public/Wb/Doc/Resource.DD.HTML | 4 +- public/Wb/Doc/ScopingLinkage.DD.HTML | 20 +- public/Wb/Doc/Snd.DD.HTML | 2 +- public/Wb/Doc/Sprite.DD.HTML | 8 +- public/Wb/Doc/SpriteEd.DD.HTML | 2 +- public/Wb/Doc/SpriteEdText.DD.HTML | 2 +- public/Wb/Doc/StdOutTask.DD.HTML | 4 +- public/Wb/Doc/StdTempleOSPC.DD.HTML | 2 +- public/Wb/Doc/Strategy.DD.HTML | 2 +- public/Wb/Doc/Streams.DD.HTML | 6 +- public/Wb/Doc/TextBase.DD.HTML | 26 +- public/Wb/Doc/TimeCycles.DD.HTML | 2 +- public/Wb/Doc/TimeDate.DD.HTML | 6 +- public/Wb/Doc/TimeHPET.DD.HTML | 4 +- public/Wb/Doc/TimeJiffy.DD.HTML | 8 +- public/Wb/Doc/Tips.DD.HTML | 116 +- public/Wb/Doc/Transform.DD.HTML | 30 +- public/Wb/Doc/Welcome.DD.HTML | 110 +- public/Wb/Doc/WhyNotMore.DD.HTML | 16 +- public/Wb/Doc/Widget.DD.HTML | 4 +- public/Wb/Home/Copy.HC | 98 + public/Wb/Home/DoDistro.HC.HTML | 80 + public/Wb/Home/Doc/AboutTempleOS.DD.HTML | 72 + public/Wb/Home/Doc/Asm.DD.HTML | 84 + public/Wb/Home/Doc/AutoComplete.DD.HTML | 55 + public/Wb/Home/Doc/Bit.DD.HTML | 46 + public/Wb/Home/Doc/BlkChain.DD.HTML | 75 + public/Wb/Home/Doc/Boot.DD.HTML | 142 + public/Wb/Home/Doc/CharOverview.DD.HTML | 66 + public/Wb/Home/Doc/Charter.DD.HTML | 158 + public/Wb/Home/Doc/CmdLineOverview.DD.HTML | 81 + public/Wb/Home/Doc/Comm.HC.HTML | 163 + public/Wb/Home/Doc/CompilerOverview.DD.HTML | 44 + public/Wb/Home/Doc/Credits.DD.HTML | 113 + public/Wb/Home/Doc/Ctrls.DD.HTML | 35 + public/Wb/Home/Doc/Customize.DD.HTML | 39 + public/Wb/Home/Doc/CutCorners.DD.HTML | 69 + public/Wb/Home/Doc/D3.DD.HTML | 39 + public/Wb/Home/Doc/Date.DD.HTML | 33 + public/Wb/Home/Doc/DbgFunSeg.DD.HTML | 33 + public/Wb/Home/Doc/DbgOverview.DD.HTML | 102 + public/Wb/Home/Doc/Define.DD.HTML | 47 + public/Wb/Home/Doc/Demands.DD.HTML | 150 + public/Wb/Home/Doc/DemoIndex.DD.HTML | 46 + public/Wb/Home/Doc/Directives.DD.HTML | 39 + public/Wb/Home/Doc/DolDoc.DD.HTML | 35 + public/Wb/Home/Doc/DolDocOverview.DD.HTML | 151 + public/Wb/Home/Doc/EdPullDown.DD.HTML | 109 + public/Wb/Home/Doc/FAQ.DD.HTML | 83 + public/Wb/Home/Doc/Features.DD.HTML | 98 + public/Wb/Home/Doc/FileLowLevel.DD.HTML | 53 + public/Wb/Home/Doc/FileMgr.DD.HTML | 107 + public/Wb/Home/Doc/FileMgrPullDown.DD.HTML | 63 + public/Wb/Home/Doc/FileUtils.DD.HTML | 60 + public/Wb/Home/Doc/Frame.DD.HTML | 33 + public/Wb/Home/Doc/GRFiles.DD.HTML | 78 + public/Wb/Home/Doc/Glossary.DD.HTML | 67 + public/Wb/Home/Doc/God.DD.HTML | 33 + public/Wb/Home/Doc/GraphicsOverview.DD.HTML | 148 + public/Wb/Home/Doc/GuideLines.DD.HTML | 219 + public/Wb/Home/Doc/Hash.DD.HTML | 79 + public/Wb/Home/Doc/HeapDbg.DD.HTML | 33 + public/Wb/Home/Doc/HelloWorld.DD.HTML | 130 + public/Wb/Home/Doc/HelpIndex.DD.HTML | 124 + public/Wb/Home/Doc/HelpSystem.DD.HTML | 41 + public/Wb/Home/Doc/HolyC.DD.HTML | 354 + public/Wb/Home/Doc/InFile.DD.HTML | 49 + public/Wb/Home/Doc/Install.DD.HTML | 109 + public/Wb/Home/Doc/Job.DD.HTML | 71 + public/Wb/Home/Doc/KeyAlloc.DD.HTML | 68 + public/Wb/Home/Doc/KeyDev.DD.HTML | 52 + public/Wb/Home/Doc/Lex.DD.HTML | 35 + public/Wb/Home/Doc/MemOverview.DD.HTML | 143 + public/Wb/Home/Doc/Menus.DD.HTML | 64 + public/Wb/Home/Doc/Mouse.DD.HTML | 51 + public/Wb/Home/Doc/Msgs.DD.HTML | 33 + public/Wb/Home/Doc/MultiCore.DD.HTML | 53 + public/Wb/Home/Doc/NewASCII.DD.HTML | 57 + public/Wb/Home/Doc/ODE.DD.HTML | 40 + public/Wb/Home/Doc/Once.DD.HTML | 47 + public/Wb/Home/Doc/Options.DD.HTML | 58 + public/Wb/Home/Doc/Pags.DD.HTML | 35 + public/Wb/Home/Doc/PreProcessor.DD.HTML | 54 + public/Wb/Home/Doc/Print.DD.HTML | 144 + public/Wb/Home/Doc/Profiler.DD.HTML | 42 + public/Wb/Home/Doc/Que.DD.HTML | 34 + public/Wb/Home/Doc/Quirks.DD.HTML | 101 + public/Wb/Home/Doc/RedSea.DD.HTML | 83 + public/Wb/Home/Doc/Reliability.DD.HTML | 71 + public/Wb/Home/Doc/Requirements.DD.HTML | 63 + public/Wb/Home/Doc/Resource.DD.HTML | 42 + public/Wb/Home/Doc/ScopingLinkage.DD.HTML | 178 + public/Wb/Home/Doc/Snd.DD.HTML | 36 + public/Wb/Home/Doc/Sprite.DD.HTML | 43 + public/Wb/Home/Doc/SpriteBitMap.DD.HTML | 38 + public/Wb/Home/Doc/SpriteEd.DD.HTML | 43 + public/Wb/Home/Doc/SpriteEdText.DD.HTML | 34 + public/Wb/Home/Doc/SpriteMain.DD.HTML | 53 + public/Wb/Home/Doc/SpriteSideBar.DD.HTML | 39 + public/Wb/Home/Doc/StandBy.DD.HTML | 48 + public/Wb/Home/Doc/Start.DD.HTML | 36 + public/Wb/Home/Doc/StdOutTask.DD.HTML | 35 + public/Wb/Home/Doc/StdTempleOSPC.DD.HTML | 237 + public/Wb/Home/Doc/Strategy.DD.HTML | 138 + public/Wb/Home/Doc/Streams.DD.HTML | 48 + public/Wb/Home/Doc/TOSZ.DD.HTML | 43 + public/Wb/Home/Doc/TextBase.DD.HTML | 50 + public/Wb/Home/Doc/TimeCycles.DD.HTML | 34 + public/Wb/Home/Doc/TimeDate.DD.HTML | 37 + public/Wb/Home/Doc/TimeHPET.DD.HTML | 34 + public/Wb/Home/Doc/TimeJiffy.DD.HTML | 38 + public/Wb/Home/Doc/Tips.DD.HTML | 280 + public/Wb/Home/Doc/Transform.DD.HTML | 56 + public/Wb/Home/Doc/Welcome.DD.HTML | 278 + public/Wb/Home/Doc/WhyNotMore.DD.HTML | 118 + public/Wb/Home/Doc/Widget.DD.HTML | 84 + public/Wb/Home/Doc/Windows.DD.HTML | 34 + public/Wb/Home/MakeHome.HC.HTML | 44 + public/Wb/Home/Registry.HC.HTML | 34 + public/Wb/Home/Src/Adam/ABlkDev/ADskA.HC.HTML | 283 + public/Wb/Home/Src/Adam/ABlkDev/ADskB.HC.HTML | 222 + .../Wb/Home/Src/Adam/ABlkDev/DskChk.HC.HTML | 475 + .../Wb/Home/Src/Adam/ABlkDev/DskPrt.HC.HTML | 198 + .../Wb/Home/Src/Adam/ABlkDev/FileMgr.HC.HTML | 822 ++ .../Home/Src/Adam/ABlkDev/MakeABlkDev.HC.HTML | 39 + public/Wb/Home/Src/Adam/ABlkDev/Mount.HC.HTML | 190 + public/Wb/Home/Src/Adam/ADbg.HC.HTML | 301 + public/Wb/Home/Src/Adam/ADefine.HC.HTML | 68 + public/Wb/Home/Src/Adam/AExts.HC.HTML | 126 + public/Wb/Home/Src/Adam/AHash.HC.HTML | 462 + public/Wb/Home/Src/Adam/AMath.HC.HTML | 166 + public/Wb/Home/Src/Adam/AMathODE.HC.HTML | 719 ++ public/Wb/Home/Src/Adam/AMem.HC.HTML | 210 + public/Wb/Home/Src/Adam/AMouse.HC.HTML | 51 + public/Wb/Home/Src/Adam/ARegistry.HC.HTML | 234 + public/Wb/Home/Src/Adam/ASnd.HC.HTML | 440 + .../Src/Adam/AutoComplete/ACDictGen.HC.HTML | 292 + .../Home/Src/Adam/AutoComplete/ACFill.HC.HTML | 257 + .../Home/Src/Adam/AutoComplete/ACInit.HC.HTML | 200 + .../Home/Src/Adam/AutoComplete/ACTask.HC.HTML | 314 + .../Home/Src/Adam/AutoComplete/MakeAC.HC.HTML | 37 + public/Wb/Home/Src/Adam/CPURep.HC.HTML | 103 + public/Wb/Home/Src/Adam/Ctrls/CtrlsA.HC.HTML | 419 + .../Wb/Home/Src/Adam/Ctrls/CtrlsBttn.HC.HTML | 122 + .../Home/Src/Adam/Ctrls/CtrlsSlider.HC.HTML | 245 + .../Wb/Home/Src/Adam/Ctrls/MakeCtrls.HC.HTML | 39 + public/Wb/Home/Src/Adam/DevInfo.HC.HTML | 251 + public/Wb/Home/Src/Adam/DolDoc/DocBin.HC.HTML | 173 + .../Wb/Home/Src/Adam/DolDoc/DocChar.HC.HTML | 683 ++ .../Home/Src/Adam/DolDoc/DocClipBoard.HC.HTML | 156 + .../Home/Src/Adam/DolDoc/DocCodeTools.HC.HTML | 689 ++ .../Wb/Home/Src/Adam/DolDoc/DocDblBuf.HC.HTML | 141 + public/Wb/Home/Src/Adam/DolDoc/DocEd.HC.HTML | 296 + public/Wb/Home/Src/Adam/DolDoc/DocExt.HC.HTML | 45 + .../Wb/Home/Src/Adam/DolDoc/DocFile.HC.HTML | 388 + .../Wb/Home/Src/Adam/DolDoc/DocFind.HC.HTML | 615 ++ .../Wb/Home/Src/Adam/DolDoc/DocForm.HC.HTML | 375 + public/Wb/Home/Src/Adam/DolDoc/DocGet.HC.HTML | 274 + public/Wb/Home/Src/Adam/DolDoc/DocGr.HC.HTML | 194 + .../Home/Src/Adam/DolDoc/DocHighlight.HC.HTML | 191 + .../Wb/Home/Src/Adam/DolDoc/DocInit.HC.HTML | 143 + .../Wb/Home/Src/Adam/DolDoc/DocLink.HC.HTML | 389 + .../Wb/Home/Src/Adam/DolDoc/DocMacro.HC.HTML | 242 + public/Wb/Home/Src/Adam/DolDoc/DocNew.HC.HTML | 416 + .../Wb/Home/Src/Adam/DolDoc/DocPlain.HC.HTML | 642 ++ .../Wb/Home/Src/Adam/DolDoc/DocPopUp.HC.HTML | 348 + .../Wb/Home/Src/Adam/DolDoc/DocPutKey.HC.HTML | 760 ++ .../Wb/Home/Src/Adam/DolDoc/DocPutS.HC.HTML | 367 + .../Wb/Home/Src/Adam/DolDoc/DocRecalc.HC.HTML | 1355 +++ .../Home/Src/Adam/DolDoc/DocRecalcLib.HC.HTML | 244 + public/Wb/Home/Src/Adam/DolDoc/DocRun.HC.HTML | 134 + .../Wb/Home/Src/Adam/DolDoc/DocTerm.HC.HTML | 244 + .../Wb/Home/Src/Adam/DolDoc/DocTree.HC.HTML | 274 + .../Home/Src/Adam/DolDoc/DocWidgetWiz.HC.HTML | 1194 +++ .../Wb/Home/Src/Adam/DolDoc/MakeDoc.HC.HTML | 100 + public/Wb/Home/Src/Adam/God/GodBible.HC.HTML | 379 + public/Wb/Home/Src/Adam/God/GodDoodle.HC.HTML | 223 + public/Wb/Home/Src/Adam/God/GodExt.HC.HTML | 57 + public/Wb/Home/Src/Adam/God/GodSong.HC.HTML | 202 + public/Wb/Home/Src/Adam/God/HSNotes.DD.HTML | 433 + .../Wb/Home/Src/Adam/God/HolySpirit.HC.HTML | 190 + public/Wb/Home/Src/Adam/God/MakeGod.HC.HTML | 40 + public/Wb/Home/Src/Adam/God/Vocab.DD.HTML | 7600 +++++++++++++ public/Wb/Home/Src/Adam/Gr/Gr.HH.HTML | 211 + public/Wb/Home/Src/Adam/Gr/GrAsm.HC.HTML | 441 + public/Wb/Home/Src/Adam/Gr/GrBitMap.HC.HTML | 2085 ++++ .../Wb/Home/Src/Adam/Gr/GrComposites.HC.HTML | 375 + public/Wb/Home/Src/Adam/Gr/GrDC.HC.HTML | 465 + public/Wb/Home/Src/Adam/Gr/GrEnd.HC.HTML | 60 + public/Wb/Home/Src/Adam/Gr/GrExt.HC.HTML | 39 + public/Wb/Home/Src/Adam/Gr/GrGlbls.HC.HTML | 86 + public/Wb/Home/Src/Adam/Gr/GrInitA.HC.HTML | 52 + public/Wb/Home/Src/Adam/Gr/GrInitB.HC.HTML | 240 + public/Wb/Home/Src/Adam/Gr/GrMath.HC.HTML | 836 ++ public/Wb/Home/Src/Adam/Gr/GrPalette.HC.HTML | 124 + .../Wb/Home/Src/Adam/Gr/GrPrimatives.HC.HTML | 1853 ++++ public/Wb/Home/Src/Adam/Gr/GrScrn.HC.HTML | 454 + .../Wb/Home/Src/Adam/Gr/GrSpritePlot.HC.HTML | 506 + public/Wb/Home/Src/Adam/Gr/GrTextBase.HC.HTML | 394 + public/Wb/Home/Src/Adam/Gr/MakeGr.HC.HTML | 64 + public/Wb/Home/Src/Adam/Gr/ScrnCast.HC.HTML | 127 + .../Wb/Home/Src/Adam/Gr/SpriteBitMap.HC.HTML | 701 ++ public/Wb/Home/Src/Adam/Gr/SpriteCode.HC.HTML | 634 ++ public/Wb/Home/Src/Adam/Gr/SpriteEd.HC.HTML | 1209 +++ public/Wb/Home/Src/Adam/Gr/SpriteMain.HC.HTML | 1269 +++ public/Wb/Home/Src/Adam/Gr/SpriteMesh.HC.HTML | 1539 +++ public/Wb/Home/Src/Adam/Gr/SpriteNew.HC.HTML | 220 + .../Wb/Home/Src/Adam/Gr/SpriteSideBar.HC.HTML | 126 + public/Wb/Home/Src/Adam/Host.HC.HTML | 101 + public/Wb/Home/Src/Adam/InFile.HC.HTML | 171 + public/Wb/Home/Src/Adam/InsReg.HC.HTML | 95 + public/Wb/Home/Src/Adam/MakeAdam.HC.HTML | 63 + public/Wb/Home/Src/Adam/Menu.HC.HTML | 274 + .../Wb/Home/Src/Adam/Opt/Boot/BootDVD.HC.HTML | 219 + .../Home/Src/Adam/Opt/Boot/BootDVDIns.HC.HTML | 63 + .../Wb/Home/Src/Adam/Opt/Boot/BootHD.HC.HTML | 124 + .../Home/Src/Adam/Opt/Boot/BootHDIns.HC.HTML | 91 + .../Wb/Home/Src/Adam/Opt/Boot/BootMHD.HC.HTML | 138 + .../Home/Src/Adam/Opt/Boot/BootMHD2.HC.HTML | 154 + .../Home/Src/Adam/Opt/Boot/BootMHDIns.HC.HTML | 183 + .../Wb/Home/Src/Adam/Opt/Boot/BootRAM.HC.HTML | 91 + .../Src/Adam/Opt/Boot/DskISORedSea.HC.HTML | 219 + .../Home/Src/Adam/Opt/Boot/MakeBoot.HC.HTML | 37 + .../Wb/Home/Src/Adam/Opt/Utils/Diff.HC.HTML | 384 + .../Home/Src/Adam/Opt/Utils/DocUtils.HC.HTML | 187 + .../Wb/Home/Src/Adam/Opt/Utils/Find.HC.HTML | 288 + .../Home/Src/Adam/Opt/Utils/HeapLog.HC.HTML | 242 + .../Home/Src/Adam/Opt/Utils/LineRep.HC.HTML | 140 + .../Home/Src/Adam/Opt/Utils/LinkChk.HC.HTML | 110 + .../Home/Src/Adam/Opt/Utils/MakeUtils.HC.HTML | 46 + .../Wb/Home/Src/Adam/Opt/Utils/MemRep.HC.HTML | 262 + .../Wb/Home/Src/Adam/Opt/Utils/Merge.HC.HTML | 108 + .../Home/Src/Adam/Opt/Utils/Profiler.HC.HTML | 133 + .../Home/Src/Adam/Opt/Utils/StrUtils.HC.HTML | 237 + public/Wb/Home/Src/Adam/Opt/Utils/TOS.HC.HTML | 107 + .../Home/Src/Adam/Opt/Utils/ToDolDoc.HC.HTML | 50 + .../Wb/Home/Src/Adam/Opt/Utils/ToTXT.HC.HTML | 163 + public/Wb/Home/Src/Adam/TaskRep.HC.HTML | 61 + public/Wb/Home/Src/Adam/TaskSettings.HC.HTML | 151 + public/Wb/Home/Src/Adam/Training.HC.HTML | 215 + public/Wb/Home/Src/Adam/WallPaper.HC.HTML | 196 + public/Wb/Home/Src/Adam/Win.HC.HTML | 573 + public/Wb/Home/Src/Adam/WinMgr.HC.HTML | 894 ++ public/Wb/Home/Src/Apps/Budget/Accts.DD.HTML | 42 + .../Wb/Home/Src/Apps/Budget/BgtAccts.HC.HTML | 114 + .../Wb/Home/Src/Apps/Budget/BgtEntry.HC.HTML | 114 + .../Wb/Home/Src/Apps/Budget/BgtFile.HC.HTML | 171 + .../Wb/Home/Src/Apps/Budget/BgtMain.HC.HTML | 261 + .../Wb/Home/Src/Apps/Budget/BgtStrs.HC.HTML | 163 + .../Home/Src/Apps/Budget/BgtTemplate.HC.HTML | 213 + public/Wb/Home/Src/Apps/Budget/Budget.HC.HTML | 108 + .../Wb/Home/Src/Apps/Budget/Install.HC.HTML | 36 + public/Wb/Home/Src/Apps/Budget/Load.HC.HTML | 43 + public/Wb/Home/Src/Apps/Budget/Run.HC.HTML | 35 + .../Wb/Home/Src/Apps/GrModels/BallGen.HC.HTML | 159 + public/Wb/Home/Src/Apps/GrModels/Load.HC.HTML | 39 + .../Wb/Home/Src/Apps/GrModels/ManGen.HC.HTML | 351 + .../Wb/Home/Src/Apps/GrModels/Models.HC.HTML | 56 + public/Wb/Home/Src/Apps/GrModels/Run.HC.HTML | 33 + .../Home/Src/Apps/KeepAway/KeepAway.HC.HTML | 740 ++ public/Wb/Home/Src/Apps/KeepAway/Load.HC.HTML | 37 + public/Wb/Home/Src/Apps/KeepAway/Run.HC.HTML | 33 + public/Wb/Home/Src/Apps/Logic/Load.HC.HTML | 37 + public/Wb/Home/Src/Apps/Logic/Logic.HC.HTML | 621 ++ public/Wb/Home/Src/Apps/Logic/Run.HC.HTML | 33 + .../Apps/Psalmody/Examples/childish.HC.HTML | 55 + .../Src/Apps/Psalmody/Examples/night.HC.HTML | 114 + .../Apps/Psalmody/Examples/prosper.HC.HTML | 87 + public/Wb/Home/Src/Apps/Psalmody/Help.DD.HTML | 58 + .../Wb/Home/Src/Apps/Psalmody/Install.HC.HTML | 33 + .../Wb/Home/Src/Apps/Psalmody/JukeBox.HC.HTML | 231 + .../Home/Src/Apps/Psalmody/JukePuppet.HC.HTML | 126 + public/Wb/Home/Src/Apps/Psalmody/Load.HC.HTML | 43 + .../Home/Src/Apps/Psalmody/Psalmody.HC.HTML | 95 + .../Src/Apps/Psalmody/PsalmodyCtrls.HC.HTML | 120 + .../Src/Apps/Psalmody/PsalmodyDraw.HC.HTML | 440 + .../Src/Apps/Psalmody/PsalmodyFile.HC.HTML | 458 + .../Src/Apps/Psalmody/PsalmodyMain.HC.HTML | 829 ++ public/Wb/Home/Src/Apps/Psalmody/Run.HC.HTML | 34 + public/Wb/Home/Src/Apps/Span/Install.HC.HTML | 32 + public/Wb/Home/Src/Apps/Span/Load.HC.HTML | 41 + public/Wb/Home/Src/Apps/Span/Run.HC.HTML | 34 + public/Wb/Home/Src/Apps/Span/Span.HH.HTML | 80 + .../Wb/Home/Src/Apps/Span/SpanBridge.HC.HTML | 111 + .../Wb/Home/Src/Apps/Span/SpanDerive.HC.HTML | 78 + public/Wb/Home/Src/Apps/Span/SpanMain.HC.HTML | 499 + public/Wb/Home/Src/Apps/Span/SpanNew.HC.HTML | 157 + public/Wb/Home/Src/Apps/Strut/Load.HC.HTML | 37 + public/Wb/Home/Src/Apps/Strut/Run.HC.HTML | 34 + public/Wb/Home/Src/Apps/Strut/Strut.HC.HTML | 667 ++ .../Home/Src/Apps/TimeClock/Install.HC.HTML | 39 + .../Wb/Home/Src/Apps/TimeClock/Load.HC.HTML | 38 + .../Home/Src/Apps/TimeClock/TimeClk.HC.HTML | 182 + public/Wb/Home/Src/Apps/Titanium/Load.HC.HTML | 37 + public/Wb/Home/Src/Apps/Titanium/Run.HC.HTML | 33 + .../Home/Src/Apps/Titanium/Titanium.HC.HTML | 996 ++ .../Src/Apps/ToTheFront/AIs/Human.HC.HTML | 197 + .../Src/Apps/ToTheFront/AIs/SimpleAI.HC.HTML | 110 + .../Home/Src/Apps/ToTheFront/Install.HC.HTML | 33 + .../Wb/Home/Src/Apps/ToTheFront/Load.HC.HTML | 44 + .../Wb/Home/Src/Apps/ToTheFront/Run.HC.HTML | 33 + .../Home/Src/Apps/ToTheFront/TTFDraw.HC.HTML | 243 + .../Home/Src/Apps/ToTheFront/TTFFire.HC.HTML | 309 + .../Home/Src/Apps/ToTheFront/TTFGlbls.HC.HTML | 139 + .../Home/Src/Apps/ToTheFront/TTFInit.HC.HTML | 445 + .../Home/Src/Apps/ToTheFront/TTFLib.HC.HTML | 152 + .../Home/Src/Apps/ToTheFront/TTFMove.HC.HTML | 160 + .../Home/Src/Apps/ToTheFront/TTFVis.HC.HTML | 254 + .../Src/Apps/ToTheFront/ToTheFront.HC.HTML | 245 + .../Wb/Home/Src/Apps/Vocabulary/Load.HC.HTML | 37 + .../Wb/Home/Src/Apps/Vocabulary/Run.HC.HTML | 33 + .../Src/Apps/Vocabulary/VocabQuiz.HC.HTML | 88 + .../Wb/Home/Src/Apps/X-Caliber/Load.HC.HTML | 38 + public/Wb/Home/Src/Apps/X-Caliber/Run.HC.HTML | 33 + .../Home/Src/Apps/X-Caliber/X-Caliber.HC.HTML | 1549 +++ .../Home/Src/Apps/X-Caliber/XCCtrls.HC.HTML | 185 + public/Wb/Home/Src/Compiler/Asm.HC.HTML | 1145 ++ public/Wb/Home/Src/Compiler/AsmInit.HC.HTML | 240 + public/Wb/Home/Src/Compiler/AsmLib.HC.HTML | 206 + .../Wb/Home/Src/Compiler/AsmResolve.HC.HTML | 248 + public/Wb/Home/Src/Compiler/BackA.HC.HTML | 689 ++ public/Wb/Home/Src/Compiler/BackB.HC.HTML | 750 ++ public/Wb/Home/Src/Compiler/BackC.HC.HTML | 802 ++ public/Wb/Home/Src/Compiler/BackFA.HC.HTML | 638 ++ public/Wb/Home/Src/Compiler/BackFB.HC.HTML | 662 ++ public/Wb/Home/Src/Compiler/BackLib.HC.HTML | 739 ++ public/Wb/Home/Src/Compiler/CExcept.HC.HTML | 284 + public/Wb/Home/Src/Compiler/CExts.HC.HTML | 77 + public/Wb/Home/Src/Compiler/CHash.HC.HTML | 172 + public/Wb/Home/Src/Compiler/CInit.HC.HTML | 361 + public/Wb/Home/Src/Compiler/CMain.HC.HTML | 733 ++ public/Wb/Home/Src/Compiler/CMisc.HC.HTML | 200 + public/Wb/Home/Src/Compiler/CompilerA.HH.HTML | 437 + public/Wb/Home/Src/Compiler/CompilerB.HH.HTML | 110 + public/Wb/Home/Src/Compiler/Lex.HC.HTML | 1226 +++ public/Wb/Home/Src/Compiler/LexLib.HC.HTML | 306 + public/Wb/Home/Src/Compiler/OpCodes.DD.HTML | 1328 +++ public/Wb/Home/Src/Compiler/OptLib.HC.HTML | 596 ++ .../Wb/Home/Src/Compiler/OptPass012.HC.HTML | 1319 +++ public/Wb/Home/Src/Compiler/OptPass3.HC.HTML | 653 ++ public/Wb/Home/Src/Compiler/OptPass4.HC.HTML | 720 ++ public/Wb/Home/Src/Compiler/OptPass5.HC.HTML | 121 + public/Wb/Home/Src/Compiler/OptPass6.HC.HTML | 216 + .../Wb/Home/Src/Compiler/OptPass789A.HC.HTML | 1183 +++ public/Wb/Home/Src/Compiler/PrsExp.HC.HTML | 1209 +++ public/Wb/Home/Src/Compiler/PrsLib.HC.HTML | 354 + public/Wb/Home/Src/Compiler/PrsStmt.HC.HTML | 1253 +++ public/Wb/Home/Src/Compiler/PrsVar.HC.HTML | 752 ++ public/Wb/Home/Src/Compiler/Templates.HC.HTML | 543 + public/Wb/Home/Src/Compiler/UAsm.HC.HTML | 713 ++ .../Demo/AcctExample/HomeKeyPlugIns.HC.HTML | 320 + .../Src/Demo/AcctExample/HomeLocalize.HC.HTML | 52 + .../Home/Src/Demo/AcctExample/HomeSys.HC.HTML | 78 + .../Src/Demo/AcctExample/HomeWrappers.HC.HTML | 66 + .../Src/Demo/AcctExample/MakeHome.HC.HTML | 47 + .../Wb/Home/Src/Demo/AcctExample/Once.HC.HTML | 70 + .../Src/Demo/AcctExample/PersonalMenu.DD.HTML | 128 + .../Demo/AcctExample/PersonalNotes.DD.HTML | 532 + .../Src/Demo/AcctExample/Registry.HC.HTML | 37 + .../Src/Demo/AcctExample/TOS/MakeTOS.HC.HTML | 39 + .../Src/Demo/AcctExample/TOS/TOSCfg.HC.HTML | 92 + .../Demo/AcctExample/TOS/TOSDistro.HC.HTML | 418 + .../Src/Demo/AcctExample/TOS/TOSExt.HC.HTML | 341 + .../Src/Demo/AcctExample/TOS/TOSMisc.HC.HTML | 194 + .../Src/Demo/AcctExample/TOS/TOSTheme.HC.HTML | 233 + public/Wb/Home/Src/Demo/Asm/AsmAndC1.HC.HTML | 106 + public/Wb/Home/Src/Demo/Asm/AsmAndC2.HC.HTML | 116 + public/Wb/Home/Src/Demo/Asm/AsmAndC3.HC.HTML | 54 + .../Home/Src/Demo/Asm/AsmHelloWorld.HC.HTML | 81 + public/Wb/Home/Src/Demo/Asm/BuzzFizz.HC.HTML | 215 + public/Wb/Home/Src/Demo/Asm/DivByHand.HC.HTML | 52 + public/Wb/Home/Src/Demo/Asm/MulByHand.HC.HTML | 100 + public/Wb/Home/Src/Demo/Asm/PutDec.HC.HTML | 80 + public/Wb/Home/Src/Demo/Carry.HC.HTML | 76 + public/Wb/Home/Src/Demo/ClassMeta.HC.HTML | 111 + public/Wb/Home/Src/Demo/CompileDemo.HC.HTML | 68 + public/Wb/Home/Src/Demo/DateTime.HC.HTML | 42 + public/Wb/Home/Src/Demo/DbgDemo.HC.HTML | 57 + public/Wb/Home/Src/Demo/Define.HC.HTML | 67 + public/Wb/Home/Src/Demo/Directives.HC.HTML | 44 + .../Wb/Home/Src/Demo/DolDoc/CallBack.HC.HTML | 95 + .../Src/Demo/DolDoc/ClickCallBack.HC.HTML | 78 + .../Home/Src/Demo/DolDoc/CursorMove.HC.HTML | 69 + public/Wb/Home/Src/Demo/DolDoc/Data.HC.HTML | 94 + .../Wb/Home/Src/Demo/DolDoc/DefineStr.HC.HTML | 53 + .../Wb/Home/Src/Demo/DolDoc/DemoDoc.DD.HTML | 204 + .../Wb/Home/Src/Demo/DolDoc/FileRead.HC.HTML | 111 + public/Wb/Home/Src/Demo/DolDoc/Form.HC.HTML | 82 + .../Wb/Home/Src/Demo/DolDoc/MenuBttn.HC.HTML | 106 + .../Home/Src/Demo/DolDoc/MenuSprite.HC.HTML | 63 + .../Wb/Home/Src/Demo/DolDoc/NumBible.HC.HTML | 59 + .../Wb/Home/Src/Demo/DolDoc/TextDemo.HC.HTML | 54 + .../Wb/Home/Src/Demo/DolDoc/TreeDemo.HC.HTML | 70 + .../Home/Src/Demo/DolDoc/UnusedDefine.HC.HTML | 113 + public/Wb/Home/Src/Demo/Dsk/BlkDevRep.HC.HTML | 44 + public/Wb/Home/Src/Demo/Dsk/DataBase.HC.HTML | 95 + public/Wb/Home/Src/Demo/Dsk/DskRaw.HC.HTML | 72 + public/Wb/Home/Src/Demo/Dsk/FPrintF.HC.HTML | 80 + .../Home/Src/Demo/Dsk/SerializeTree.HC.HTML | 66 + .../Home/Src/Demo/Dsk/UnusedSpaceRep.HC.HTML | 43 + public/Wb/Home/Src/Demo/Exceptions.HC.HTML | 78 + public/Wb/Home/Src/Demo/ExtChars.HC.HTML | 66 + .../Home/Src/Demo/Games/BattleLines.HC.HTML | 413 + public/Wb/Home/Src/Demo/Games/BigGuns.HC.HTML | 346 + .../Home/Src/Demo/Games/BlackDiamond.HC.HTML | 430 + .../Wb/Home/Src/Demo/Games/BomberGolf.HC.HTML | 389 + .../Src/Demo/Games/CastleFrankenstein.HC.HTML | 627 ++ .../Wb/Home/Src/Demo/Games/CharDemo.HC.HTML | 222 + .../Home/Src/Demo/Games/CircleTrace.HC.HTML | 159 + .../Wb/Home/Src/Demo/Games/Collision.HC.HTML | 185 + public/Wb/Home/Src/Demo/Games/Digits.HC.HTML | 111 + public/Wb/Home/Src/Demo/Games/DunGen.HC.HTML | 478 + .../Home/Src/Demo/Games/ElephantWalk.HC.HTML | 117 + public/Wb/Home/Src/Demo/Games/FlapBat.HC.HTML | 305 + .../Wb/Home/Src/Demo/Games/FlatTops.HC.HTML | 919 ++ public/Wb/Home/Src/Demo/Games/Halogen.HC.HTML | 193 + .../Wb/Home/Src/Demo/Games/MassSpring.HC.HTML | 200 + public/Wb/Home/Src/Demo/Games/Maze.HC.HTML | 143 + .../Wb/Home/Src/Demo/Games/RainDrops.HC.HTML | 220 + public/Wb/Home/Src/Demo/Games/RawHide.HC.HTML | 622 ++ public/Wb/Home/Src/Demo/Games/Rocket.HC.HTML | 237 + .../Home/Src/Demo/Games/RocketScience.HC.HTML | 328 + public/Wb/Home/Src/Demo/Games/Squirt.HC.HTML | 415 + .../Src/Demo/Games/Stadium/Stadium.HC.HTML | 165 + .../Src/Demo/Games/Stadium/StadiumBG.DD.HTML | 32 + .../Src/Demo/Games/Stadium/StadiumGen.HC.HTML | 64 + public/Wb/Home/Src/Demo/Games/Talons.HC.HTML | 1264 +++ public/Wb/Home/Src/Demo/Games/TheDead.HC.HTML | 218 + .../Wb/Home/Src/Demo/Games/TicTacToe.HC.HTML | 156 + .../Home/Src/Demo/Games/TreeCheckers.HC.HTML | 388 + public/Wb/Home/Src/Demo/Games/Varoom.HC.HTML | 734 ++ .../Wb/Home/Src/Demo/Games/Wenceslas.HC.HTML | 623 ++ public/Wb/Home/Src/Demo/Games/Whap.HC.HTML | 204 + public/Wb/Home/Src/Demo/Games/Zing.HC.HTML | 236 + public/Wb/Home/Src/Demo/Games/ZoneOut.HC.HTML | 349 + public/Wb/Home/Src/Demo/GlblVars.HC.HTML | 107 + .../Wb/Home/Src/Demo/Graphics/3DPoly.HC.HTML | 148 + .../Wb/Home/Src/Demo/Graphics/BSpline.HC.HTML | 66 + .../Wb/Home/Src/Demo/Graphics/Balloon.HC.HTML | 69 + public/Wb/Home/Src/Demo/Graphics/Blot.HC.HTML | 72 + .../Wb/Home/Src/Demo/Graphics/Bounce.HC.HTML | 78 + public/Wb/Home/Src/Demo/Graphics/Box.HC.HTML | 81 + .../Home/Src/Demo/Graphics/Cartesian.HC.HTML | 79 + .../Src/Demo/Graphics/CharAnimation.HC.HTML | 61 + .../Home/Src/Demo/Graphics/Collision.HC.HTML | 73 + .../Src/Demo/Graphics/CommonAncestor.HC.HTML | 151 + .../Wb/Home/Src/Demo/Graphics/Doodle.HC.HTML | 78 + .../Home/Src/Demo/Graphics/EdSprite.HC.HTML | 123 + .../Home/Src/Demo/Graphics/Elephant.HC.HTML | 236 + .../Wb/Home/Src/Demo/Graphics/Extents.HC.HTML | 76 + .../Wb/Home/Src/Demo/Graphics/FontEd.HC.HTML | 183 + public/Wb/Home/Src/Demo/Graphics/Grid.HC.HTML | 61 + .../Wb/Home/Src/Demo/Graphics/Hanoi.HC.HTML | 185 + .../Wb/Home/Src/Demo/Graphics/Lattice.HC.HTML | 297 + public/Wb/Home/Src/Demo/Graphics/Life.HC.HTML | 129 + .../Home/Src/Demo/Graphics/LightTable.HC.HTML | 680 ++ .../Wb/Home/Src/Demo/Graphics/Lines.HC.HTML | 57 + .../Src/Demo/Graphics/LowPassFilter.HC.HTML | 114 + .../Src/Demo/Graphics/MathAudioDemo.HC.HTML | 137 + .../Home/Src/Demo/Graphics/MouseDemo.HC.HTML | 42 + .../Home/Src/Demo/Graphics/NetOfDots.HC.HTML | 47 + .../Wb/Home/Src/Demo/Graphics/Palette.HC.HTML | 58 + .../Wb/Home/Src/Demo/Graphics/PanText.HC.HTML | 66 + public/Wb/Home/Src/Demo/Graphics/Pick.HC.HTML | 117 + .../Wb/Home/Src/Demo/Graphics/Pick3D.HC.HTML | 357 + .../Home/Src/Demo/Graphics/PoleZeros.HC.HTML | 204 + .../Src/Demo/Graphics/PredatorPrey.HC.HTML | 112 + .../Home/Src/Demo/Graphics/RotateTank.HC.HTML | 91 + .../Src/Demo/Graphics/ScrnCapture.HC.HTML | 46 + .../Home/Src/Demo/Graphics/ScrollBars.HC.HTML | 100 + .../Wb/Home/Src/Demo/Graphics/Shading.HC.HTML | 208 + .../Wb/Home/Src/Demo/Graphics/Shadow.HC.HTML | 133 + .../Wb/Home/Src/Demo/Graphics/Slider.HC.HTML | 141 + .../Home/Src/Demo/Graphics/Speedline.HC.HTML | 81 + .../Home/Src/Demo/Graphics/SpritePlot.HC.HTML | 92 + .../Src/Demo/Graphics/SpritePlot3D.HC.HTML | 84 + .../Home/Src/Demo/Graphics/SpritePut.HC.HTML | 70 + .../Src/Demo/Graphics/SpritePutExt.HC.HTML | 57 + .../Home/Src/Demo/Graphics/SpriteRaw.HC.HTML | 69 + .../Home/Src/Demo/Graphics/SpriteText.HC.HTML | 81 + .../Wb/Home/Src/Demo/Graphics/SunMoon.HC.HTML | 74 + .../Home/Src/Demo/Graphics/Symmetry.HC.HTML | 93 + .../Home/Src/Demo/Graphics/Transform.HC.HTML | 253 + .../Src/Demo/Graphics/WallPaperCtrl.HC.HTML | 139 + .../Src/Demo/Graphics/WallPaperFish.HC.HTML | 146 + .../Wb/Home/Src/Demo/Graphics/WinZBuf.HC.HTML | 54 + public/Wb/Home/Src/Demo/InFile/InEd.DD.HTML | 259 + .../Wb/Home/Src/Demo/InFile/InPopUp.HC.HTML | 43 + .../Wb/Home/Src/Demo/InFile/InSetIP.HC.HTML | 44 + public/Wb/Home/Src/Demo/KeyBitMap.HC.HTML | 71 + public/Wb/Home/Src/Demo/LastClass.HC.HTML | 64 + .../Src/Demo/Lectures/64BitAsmQuiz.DD.HTML | 137 + .../Home/Src/Demo/Lectures/AndNotMod.HC.HTML | 75 + .../Home/Src/Demo/Lectures/FixedPoint.HC.HTML | 127 + .../Demo/Lectures/FixedPointAdvanced.HC.HTML | 204 + .../Src/Demo/Lectures/GraphicsCPULoad.HC.HTML | 65 + .../Src/Demo/Lectures/InterruptDemo.HC.HTML | 116 + .../Src/Demo/Lectures/MiniCompiler.HC.HTML | 277 + .../Home/Src/Demo/Lectures/MiniGrLib.HC.HTML | 163 + .../Wb/Home/Src/Demo/Lectures/NegDisp.HC.HTML | 87 + .../Src/Demo/Lectures/Optimization.HC.HTML | 139 + .../Src/Demo/Lectures/PCIInterrupts.HC.HTML | 104 + .../Wb/Home/Src/Demo/Lectures/Ring3.HC.HTML | 106 + .../Home/Src/Demo/Lectures/ScrnMemory.HC.HTML | 80 + public/Wb/Home/Src/Demo/MagicPairs.HC.HTML | 406 + public/Wb/Home/Src/Demo/MemDemo.HC.HTML | 95 + public/Wb/Home/Src/Demo/MsgLoop.HC.HTML | 54 + .../Src/Demo/MultiCore/Interrupts.HC.HTML | 54 + .../Home/Src/Demo/MultiCore/LoadTest.HC.HTML | 79 + .../Wb/Home/Src/Demo/MultiCore/Lock.HC.HTML | 83 + .../Wb/Home/Src/Demo/MultiCore/MPAdd.HC.HTML | 116 + .../Home/Src/Demo/MultiCore/MPPrint.HC.HTML | 48 + .../Home/Src/Demo/MultiCore/MPRadix.HC.HTML | 173 + .../Src/Demo/MultiCore/Palindrome.HC.HTML | 127 + .../Wb/Home/Src/Demo/MultiCore/Primes.HC.HTML | 106 + public/Wb/Home/Src/Demo/NullCase.HC.HTML | 50 + public/Wb/Home/Src/Demo/OnceDemo.HC.HTML | 43 + public/Wb/Home/Src/Demo/ParenWarn.HC.HTML | 48 + public/Wb/Home/Src/Demo/PhoneNumWords.HC.HTML | 94 + public/Wb/Home/Src/Demo/Print.HC.HTML | 64 + public/Wb/Home/Src/Demo/Progress.HC.HTML | 111 + public/Wb/Home/Src/Demo/Prompt.HC.HTML | 56 + public/Wb/Home/Src/Demo/PullDownMenu.HC.HTML | 120 + public/Wb/Home/Src/Demo/RadixSort.HC.HTML | 93 + public/Wb/Home/Src/Demo/RandDemo.HC.HTML | 95 + public/Wb/Home/Src/Demo/RegistryDemo.HC.HTML | 58 + .../Src/Demo/RevFileDemo/DemoPoemBwd.DD.HTML | 73 + .../Wb/Home/Src/Demo/RevFileDemo/Rev.HC.HTML | 53 + public/Wb/Home/Src/Demo/ScrnCodes.HC.HTML | 58 + .../Wb/Home/Src/Demo/Snd/ASCIIOrgan.HC.HTML | 80 + public/Wb/Home/Src/Demo/Snd/MorseCode.HC.HTML | 207 + public/Wb/Home/Src/Demo/Snd/OhGreat.HC.HTML | 72 + public/Wb/Home/Src/Demo/Snd/WaterFowl.HC.HTML | 187 + .../Src/Demo/SortFileDemo/F64FileGen.HC.HTML | 57 + .../Src/Demo/SortFileDemo/F64FileSort.HC.HTML | 103 + public/Wb/Home/Src/Demo/Spy.HC.HTML | 93 + public/Wb/Home/Src/Demo/StkGrow.HC.HTML | 84 + public/Wb/Home/Src/Demo/SubIntAccess.HC.HTML | 60 + public/Wb/Home/Src/Demo/SubSwitch.HC.HTML | 52 + .../Wb/Home/Src/Demo/SuggestSpelling.HC.HTML | 123 + .../Wb/Home/Src/Demo/Templates/Game1.HC.HTML | 121 + .../Wb/Home/Src/Demo/Templates/Lex1.HC.HTML | 47 + .../Src/Demo/Templates/MultiCore1.HC.HTML | 60 + .../Wb/Home/Src/Demo/Templates/ODE1.HC.HTML | 74 + .../Home/Src/Demo/Templates/Registry1.HC.HTML | 41 + .../Wb/Home/Src/Demo/Templates/Util1.HC.HTML | 45 + .../Wb/Home/Src/Demo/Templates/Util2.HC.HTML | 85 + public/Wb/Home/Src/Demo/TimeIns.HC.HTML | 66 + .../Demo/ToHtmlToTXTDemo/DemoInPage.DD.HTML | 49 + .../Src/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML | 51 + .../Src/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML | 39 + .../Src/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML | 420 + .../Src/Demo/WebLogDemo/WebLogRep.HC.HTML | 559 + .../Demo/WebLogDemo/WebLogScramble.HC.HTML | 100 + public/Wb/Home/Src/Demo/WordSearch.HC.HTML | 184 + public/Wb/Home/Src/Doc/AboutTempleOS.DD.HTML | 72 + public/Wb/Home/Src/Doc/Asm.DD.HTML | 84 + public/Wb/Home/Src/Doc/AutoComplete.DD.HTML | 55 + public/Wb/Home/Src/Doc/Bit.DD.HTML | 46 + public/Wb/Home/Src/Doc/BlkChain.DD.HTML | 75 + public/Wb/Home/Src/Doc/Boot.DD.HTML | 142 + public/Wb/Home/Src/Doc/CharOverview.DD.HTML | 66 + public/Wb/Home/Src/Doc/Charter.DD.HTML | 158 + .../Wb/Home/Src/Doc/CmdLineOverview.DD.HTML | 81 + public/Wb/Home/Src/Doc/Comm.HC.HTML | 163 + .../Wb/Home/Src/Doc/CompilerOverview.DD.HTML | 44 + public/Wb/Home/Src/Doc/Credits.DD.HTML | 113 + public/Wb/Home/Src/Doc/Ctrls.DD.HTML | 35 + public/Wb/Home/Src/Doc/Customize.DD.HTML | 39 + public/Wb/Home/Src/Doc/CutCorners.DD.HTML | 69 + public/Wb/Home/Src/Doc/D3.DD.HTML | 39 + public/Wb/Home/Src/Doc/Date.DD.HTML | 33 + public/Wb/Home/Src/Doc/DbgFunSeg.DD.HTML | 33 + public/Wb/Home/Src/Doc/DbgOverview.DD.HTML | 102 + public/Wb/Home/Src/Doc/Define.DD.HTML | 47 + public/Wb/Home/Src/Doc/Demands.DD.HTML | 150 + public/Wb/Home/Src/Doc/DemoIndex.DD.HTML | 46 + public/Wb/Home/Src/Doc/Directives.DD.HTML | 39 + public/Wb/Home/Src/Doc/DolDoc.DD.HTML | 35 + public/Wb/Home/Src/Doc/DolDocOverview.DD.HTML | 151 + public/Wb/Home/Src/Doc/EdPullDown.DD.HTML | 109 + public/Wb/Home/Src/Doc/FAQ.DD.HTML | 83 + public/Wb/Home/Src/Doc/Features.DD.HTML | 98 + public/Wb/Home/Src/Doc/FileLowLevel.DD.HTML | 53 + public/Wb/Home/Src/Doc/FileMgr.DD.HTML | 107 + .../Wb/Home/Src/Doc/FileMgrPullDown.DD.HTML | 63 + public/Wb/Home/Src/Doc/FileUtils.DD.HTML | 60 + public/Wb/Home/Src/Doc/Frame.DD.HTML | 33 + public/Wb/Home/Src/Doc/GRFiles.DD.HTML | 78 + public/Wb/Home/Src/Doc/Glossary.DD.HTML | 67 + public/Wb/Home/Src/Doc/God.DD.HTML | 33 + .../Wb/Home/Src/Doc/GraphicsOverview.DD.HTML | 148 + public/Wb/Home/Src/Doc/GuideLines.DD.HTML | 219 + public/Wb/Home/Src/Doc/Hash.DD.HTML | 79 + public/Wb/Home/Src/Doc/HeapDbg.DD.HTML | 33 + public/Wb/Home/Src/Doc/HelloWorld.DD.HTML | 130 + public/Wb/Home/Src/Doc/HelpIndex.DD.HTML | 124 + public/Wb/Home/Src/Doc/HelpSystem.DD.HTML | 41 + public/Wb/Home/Src/Doc/HolyC.DD.HTML | 354 + public/Wb/Home/Src/Doc/InFile.DD.HTML | 49 + public/Wb/Home/Src/Doc/Install.DD.HTML | 109 + public/Wb/Home/Src/Doc/Job.DD.HTML | 71 + public/Wb/Home/Src/Doc/KeyAlloc.DD.HTML | 68 + public/Wb/Home/Src/Doc/KeyDev.DD.HTML | 52 + public/Wb/Home/Src/Doc/Lex.DD.HTML | 35 + public/Wb/Home/Src/Doc/MemOverview.DD.HTML | 143 + public/Wb/Home/Src/Doc/Menus.DD.HTML | 64 + public/Wb/Home/Src/Doc/Mouse.DD.HTML | 51 + public/Wb/Home/Src/Doc/Msgs.DD.HTML | 33 + public/Wb/Home/Src/Doc/MultiCore.DD.HTML | 53 + public/Wb/Home/Src/Doc/NewASCII.DD.HTML | 57 + public/Wb/Home/Src/Doc/ODE.DD.HTML | 40 + public/Wb/Home/Src/Doc/Once.DD.HTML | 47 + public/Wb/Home/Src/Doc/Options.DD.HTML | 58 + public/Wb/Home/Src/Doc/Pags.DD.HTML | 35 + public/Wb/Home/Src/Doc/PreProcessor.DD.HTML | 54 + public/Wb/Home/Src/Doc/Print.DD.HTML | 144 + public/Wb/Home/Src/Doc/Profiler.DD.HTML | 42 + public/Wb/Home/Src/Doc/Que.DD.HTML | 34 + public/Wb/Home/Src/Doc/Quirks.DD.HTML | 101 + public/Wb/Home/Src/Doc/RedSea.DD.HTML | 83 + public/Wb/Home/Src/Doc/Reliability.DD.HTML | 71 + public/Wb/Home/Src/Doc/Requirements.DD.HTML | 63 + public/Wb/Home/Src/Doc/Resource.DD.HTML | 42 + public/Wb/Home/Src/Doc/ScopingLinkage.DD.HTML | 178 + public/Wb/Home/Src/Doc/Snd.DD.HTML | 36 + public/Wb/Home/Src/Doc/Sprite.DD.HTML | 43 + public/Wb/Home/Src/Doc/SpriteBitMap.DD.HTML | 38 + public/Wb/Home/Src/Doc/SpriteEd.DD.HTML | 43 + public/Wb/Home/Src/Doc/SpriteEdText.DD.HTML | 34 + public/Wb/Home/Src/Doc/SpriteMain.DD.HTML | 53 + public/Wb/Home/Src/Doc/SpriteSideBar.DD.HTML | 39 + public/Wb/Home/Src/Doc/StandBy.DD.HTML | 48 + public/Wb/Home/Src/Doc/Start.DD.HTML | 36 + public/Wb/Home/Src/Doc/StdOutTask.DD.HTML | 35 + public/Wb/Home/Src/Doc/StdTempleOSPC.DD.HTML | 237 + public/Wb/Home/Src/Doc/Strategy.DD.HTML | 138 + public/Wb/Home/Src/Doc/Streams.DD.HTML | 48 + public/Wb/Home/Src/Doc/TOSZ.DD.HTML | 43 + public/Wb/Home/Src/Doc/TextBase.DD.HTML | 50 + public/Wb/Home/Src/Doc/TimeCycles.DD.HTML | 34 + public/Wb/Home/Src/Doc/TimeDate.DD.HTML | 37 + public/Wb/Home/Src/Doc/TimeHPET.DD.HTML | 34 + public/Wb/Home/Src/Doc/TimeJiffy.DD.HTML | 38 + public/Wb/Home/Src/Doc/Tips.DD.HTML | 280 + public/Wb/Home/Src/Doc/Transform.DD.HTML | 56 + public/Wb/Home/Src/Doc/Welcome.DD.HTML | 278 + public/Wb/Home/Src/Doc/WhyNotMore.DD.HTML | 118 + public/Wb/Home/Src/Doc/Widget.DD.HTML | 84 + public/Wb/Home/Src/Doc/Windows.DD.HTML | 34 + .../TSheikhs/171207SerialPort.DD.HTML | 78 + public/Wb/Home/Src/Home/DoDistro.HC.HTML | 80 + .../Home/Src/Home/Doc/AboutTempleOS.DD.HTML | 72 + public/Wb/Home/Src/Home/Doc/Asm.DD.HTML | 84 + .../Wb/Home/Src/Home/Doc/AutoComplete.DD.HTML | 55 + public/Wb/Home/Src/Home/Doc/Bit.DD.HTML | 46 + public/Wb/Home/Src/Home/Doc/BlkChain.DD.HTML | 75 + public/Wb/Home/Src/Home/Doc/Boot.DD.HTML | 142 + .../Wb/Home/Src/Home/Doc/CharOverview.DD.HTML | 66 + public/Wb/Home/Src/Home/Doc/Charter.DD.HTML | 158 + .../Home/Src/Home/Doc/CmdLineOverview.DD.HTML | 81 + public/Wb/Home/Src/Home/Doc/Comm.HC.HTML | 163 + .../Src/Home/Doc/CompilerOverview.DD.HTML | 44 + public/Wb/Home/Src/Home/Doc/Credits.DD.HTML | 113 + public/Wb/Home/Src/Home/Doc/Ctrls.DD.HTML | 35 + public/Wb/Home/Src/Home/Doc/Customize.DD.HTML | 39 + .../Wb/Home/Src/Home/Doc/CutCorners.DD.HTML | 69 + public/Wb/Home/Src/Home/Doc/D3.DD.HTML | 39 + public/Wb/Home/Src/Home/Doc/Date.DD.HTML | 33 + public/Wb/Home/Src/Home/Doc/DbgFunSeg.DD.HTML | 33 + .../Wb/Home/Src/Home/Doc/DbgOverview.DD.HTML | 102 + public/Wb/Home/Src/Home/Doc/Define.DD.HTML | 47 + public/Wb/Home/Src/Home/Doc/Demands.DD.HTML | 150 + public/Wb/Home/Src/Home/Doc/DemoIndex.DD.HTML | 46 + .../Wb/Home/Src/Home/Doc/Directives.DD.HTML | 39 + public/Wb/Home/Src/Home/Doc/DolDoc.DD.HTML | 35 + .../Home/Src/Home/Doc/DolDocOverview.DD.HTML | 151 + .../Wb/Home/Src/Home/Doc/EdPullDown.DD.HTML | 109 + public/Wb/Home/Src/Home/Doc/FAQ.DD.HTML | 83 + public/Wb/Home/Src/Home/Doc/Features.DD.HTML | 98 + .../Wb/Home/Src/Home/Doc/FileLowLevel.DD.HTML | 53 + public/Wb/Home/Src/Home/Doc/FileMgr.DD.HTML | 107 + .../Home/Src/Home/Doc/FileMgrPullDown.DD.HTML | 63 + public/Wb/Home/Src/Home/Doc/FileUtils.DD.HTML | 60 + public/Wb/Home/Src/Home/Doc/Frame.DD.HTML | 33 + public/Wb/Home/Src/Home/Doc/GRFiles.DD.HTML | 78 + public/Wb/Home/Src/Home/Doc/Glossary.DD.HTML | 67 + public/Wb/Home/Src/Home/Doc/God.DD.HTML | 33 + .../Src/Home/Doc/GraphicsOverview.DD.HTML | 148 + .../Wb/Home/Src/Home/Doc/GuideLines.DD.HTML | 219 + public/Wb/Home/Src/Home/Doc/Hash.DD.HTML | 79 + public/Wb/Home/Src/Home/Doc/HeapDbg.DD.HTML | 33 + .../Wb/Home/Src/Home/Doc/HelloWorld.DD.HTML | 130 + public/Wb/Home/Src/Home/Doc/HelpIndex.DD.HTML | 124 + .../Wb/Home/Src/Home/Doc/HelpSystem.DD.HTML | 41 + public/Wb/Home/Src/Home/Doc/HolyC.DD.HTML | 354 + public/Wb/Home/Src/Home/Doc/InFile.DD.HTML | 49 + public/Wb/Home/Src/Home/Doc/Install.DD.HTML | 109 + public/Wb/Home/Src/Home/Doc/Job.DD.HTML | 71 + public/Wb/Home/Src/Home/Doc/KeyAlloc.DD.HTML | 68 + public/Wb/Home/Src/Home/Doc/KeyDev.DD.HTML | 52 + public/Wb/Home/Src/Home/Doc/Lex.DD.HTML | 35 + .../Wb/Home/Src/Home/Doc/MemOverview.DD.HTML | 143 + public/Wb/Home/Src/Home/Doc/Menus.DD.HTML | 64 + public/Wb/Home/Src/Home/Doc/Mouse.DD.HTML | 51 + public/Wb/Home/Src/Home/Doc/Msgs.DD.HTML | 33 + public/Wb/Home/Src/Home/Doc/MultiCore.DD.HTML | 53 + public/Wb/Home/Src/Home/Doc/NewASCII.DD.HTML | 57 + public/Wb/Home/Src/Home/Doc/ODE.DD.HTML | 40 + public/Wb/Home/Src/Home/Doc/Once.DD.HTML | 47 + public/Wb/Home/Src/Home/Doc/Options.DD.HTML | 58 + public/Wb/Home/Src/Home/Doc/Pags.DD.HTML | 35 + .../Wb/Home/Src/Home/Doc/PreProcessor.DD.HTML | 54 + public/Wb/Home/Src/Home/Doc/Print.DD.HTML | 144 + public/Wb/Home/Src/Home/Doc/Profiler.DD.HTML | 42 + public/Wb/Home/Src/Home/Doc/Que.DD.HTML | 34 + public/Wb/Home/Src/Home/Doc/Quirks.DD.HTML | 101 + public/Wb/Home/Src/Home/Doc/RedSea.DD.HTML | 83 + .../Wb/Home/Src/Home/Doc/Reliability.DD.HTML | 71 + .../Wb/Home/Src/Home/Doc/Requirements.DD.HTML | 63 + public/Wb/Home/Src/Home/Doc/Resource.DD.HTML | 42 + .../Home/Src/Home/Doc/ScopingLinkage.DD.HTML | 178 + public/Wb/Home/Src/Home/Doc/Snd.DD.HTML | 36 + public/Wb/Home/Src/Home/Doc/Sprite.DD.HTML | 43 + .../Wb/Home/Src/Home/Doc/SpriteBitMap.DD.HTML | 38 + public/Wb/Home/Src/Home/Doc/SpriteEd.DD.HTML | 43 + .../Wb/Home/Src/Home/Doc/SpriteEdText.DD.HTML | 34 + .../Wb/Home/Src/Home/Doc/SpriteMain.DD.HTML | 53 + .../Home/Src/Home/Doc/SpriteSideBar.DD.HTML | 39 + public/Wb/Home/Src/Home/Doc/StandBy.DD.HTML | 48 + public/Wb/Home/Src/Home/Doc/Start.DD.HTML | 36 + .../Wb/Home/Src/Home/Doc/StdOutTask.DD.HTML | 35 + .../Home/Src/Home/Doc/StdTempleOSPC.DD.HTML | 237 + public/Wb/Home/Src/Home/Doc/Strategy.DD.HTML | 138 + public/Wb/Home/Src/Home/Doc/Streams.DD.HTML | 48 + public/Wb/Home/Src/Home/Doc/TOSZ.DD.HTML | 43 + public/Wb/Home/Src/Home/Doc/TextBase.DD.HTML | 50 + .../Wb/Home/Src/Home/Doc/TimeCycles.DD.HTML | 34 + public/Wb/Home/Src/Home/Doc/TimeDate.DD.HTML | 37 + public/Wb/Home/Src/Home/Doc/TimeHPET.DD.HTML | 34 + public/Wb/Home/Src/Home/Doc/TimeJiffy.DD.HTML | 38 + public/Wb/Home/Src/Home/Doc/Tips.DD.HTML | 280 + public/Wb/Home/Src/Home/Doc/Transform.DD.HTML | 56 + public/Wb/Home/Src/Home/Doc/Welcome.DD.HTML | 278 + .../Wb/Home/Src/Home/Doc/WhyNotMore.DD.HTML | 118 + public/Wb/Home/Src/Home/Doc/Widget.DD.HTML | 84 + public/Wb/Home/Src/Home/Doc/Windows.DD.HTML | 34 + public/Wb/Home/Src/Home/MakeHome.HC.HTML | 44 + public/Wb/Home/Src/Home/Registry.HC.HTML | 34 + public/Wb/Home/Src/HomeKeyPlugIns.HC.HTML | 233 + public/Wb/Home/Src/HomeLocalize.HC.HTML | 50 + public/Wb/Home/Src/HomeSys.HC.HTML | 69 + public/Wb/Home/Src/HomeWrappers.HC.HTML | 57 + .../Wb/Home/Src/Kernel/BlkDev/DskATA.HC.HTML | 642 ++ .../Home/Src/Kernel/BlkDev/DskATAId.HC.HTML | 324 + .../Home/Src/Kernel/BlkDev/DskAddDev.HC.HTML | 271 + .../Wb/Home/Src/Kernel/BlkDev/DskBlk.HC.HTML | 140 + .../Home/Src/Kernel/BlkDev/DskBlkDev.HC.HTML | 218 + .../Home/Src/Kernel/BlkDev/DskCDDVD.HC.HTML | 274 + .../Home/Src/Kernel/BlkDev/DskCFile.HC.HTML | 296 + .../Home/Src/Kernel/BlkDev/DskCache.HC.HTML | 176 + .../Wb/Home/Src/Kernel/BlkDev/DskClus.HC.HTML | 176 + .../Wb/Home/Src/Kernel/BlkDev/DskCopy.HC.HTML | 134 + .../Wb/Home/Src/Kernel/BlkDev/DskDirA.HC.HTML | 242 + .../Wb/Home/Src/Kernel/BlkDev/DskDirB.HC.HTML | 225 + .../Src/Kernel/BlkDev/DskDirContext.HC.HTML | 118 + .../Wb/Home/Src/Kernel/BlkDev/DskDrv.HC.HTML | 397 + .../Wb/Home/Src/Kernel/BlkDev/DskFile.HC.HTML | 149 + .../Wb/Home/Src/Kernel/BlkDev/DskFind.HC.HTML | 182 + .../Wb/Home/Src/Kernel/BlkDev/DskFmt.HC.HTML | 123 + .../Wb/Home/Src/Kernel/BlkDev/DskStrA.HC.HTML | 374 + .../Wb/Home/Src/Kernel/BlkDev/DskStrB.HC.HTML | 120 + .../Home/Src/Kernel/BlkDev/FileSysFAT.HC.HTML | 990 ++ .../Src/Kernel/BlkDev/FileSysRedSea.HC.HTML | 666 ++ .../Home/Src/Kernel/BlkDev/MakeBlkDev.HC.HTML | 54 + public/Wb/Home/Src/Kernel/Compress.HC.HTML | 339 + public/Wb/Home/Src/Kernel/Display.HC.HTML | 152 + public/Wb/Home/Src/Kernel/EdLite.HC.HTML | 386 + .../Wb/Home/Src/Kernel/FontCyrillic.HC.HTML | 163 + public/Wb/Home/Src/Kernel/FontStd.HC.HTML | 163 + public/Wb/Home/Src/Kernel/FunSeg.HC.HTML | 391 + public/Wb/Home/Src/Kernel/Job.HC.HTML | 533 + public/Wb/Home/Src/Kernel/KCfg.HC.HTML | 204 + public/Wb/Home/Src/Kernel/KDataTypes.HC.HTML | 354 + public/Wb/Home/Src/Kernel/KDate.HC.HTML | 227 + public/Wb/Home/Src/Kernel/KDbg.HC.HTML | 683 ++ public/Wb/Home/Src/Kernel/KDefine.HC.HTML | 249 + public/Wb/Home/Src/Kernel/KExcept.HC.HTML | 180 + public/Wb/Home/Src/Kernel/KExts.HC.HTML | 140 + public/Wb/Home/Src/Kernel/KGlbls.HC.HTML | 66 + public/Wb/Home/Src/Kernel/KHashA.HC.HTML | 296 + public/Wb/Home/Src/Kernel/KHashB.HC.HTML | 281 + public/Wb/Home/Src/Kernel/KInts.HC.HTML | 246 + public/Wb/Home/Src/Kernel/KLoad.HC.HTML | 281 + public/Wb/Home/Src/Kernel/KMain.HC.HTML | 269 + public/Wb/Home/Src/Kernel/KMathA.HC.HTML | 679 ++ public/Wb/Home/Src/Kernel/KMathB.HC.HTML | 188 + public/Wb/Home/Src/Kernel/KMisc.HC.HTML | 357 + public/Wb/Home/Src/Kernel/KStart16.HC.HTML | 237 + public/Wb/Home/Src/Kernel/KStart32.HC.HTML | 148 + public/Wb/Home/Src/Kernel/KStart64.HC.HTML | 131 + public/Wb/Home/Src/Kernel/KTask.HC.HTML | 576 + public/Wb/Home/Src/Kernel/KUtils.HC.HTML | 502 + public/Wb/Home/Src/Kernel/KernelA.HH.HTML | 3938 +++++++ public/Wb/Home/Src/Kernel/KernelB.HH.HTML | 325 + public/Wb/Home/Src/Kernel/KernelC.HH.HTML | 799 ++ public/Wb/Home/Src/Kernel/KeyDev.HC.HTML | 250 + public/Wb/Home/Src/Kernel/Mem/BlkPool.HC.HTML | 104 + .../Wb/Home/Src/Kernel/Mem/HeapCtrl.HC.HTML | 64 + .../Wb/Home/Src/Kernel/Mem/MAllocFree.HC.HTML | 495 + public/Wb/Home/Src/Kernel/Mem/MakeMem.HC.HTML | 39 + public/Wb/Home/Src/Kernel/Mem/MemPag.HC.HTML | 198 + .../Home/Src/Kernel/Mem/MemPhysical.HC.HTML | 212 + .../Wb/Home/Src/Kernel/Mem/PageTables.HC.HTML | 236 + public/Wb/Home/Src/Kernel/MultiProc.HC.HTML | 420 + public/Wb/Home/Src/Kernel/PCIBIOS.HC.HTML | 320 + public/Wb/Home/Src/Kernel/QSort.HC.HTML | 135 + public/Wb/Home/Src/Kernel/Sched.HC.HTML | 356 + .../Src/Kernel/SerialDev/Keyboard.HC.HTML | 523 + .../Kernel/SerialDev/MakeSerialDev.HC.HTML | 36 + .../Home/Src/Kernel/SerialDev/Message.HC.HTML | 275 + .../Home/Src/Kernel/SerialDev/Mouse.HC.HTML | 398 + public/Wb/Home/Src/Kernel/StrA.HC.HTML | 717 ++ public/Wb/Home/Src/Kernel/StrB.HC.HTML | 218 + public/Wb/Home/Src/Kernel/StrPrint.HC.HTML | 951 ++ public/Wb/Home/Src/Kernel/StrScan.HC.HTML | 370 + public/Wb/Home/Src/MakeHome.HC.HTML | 44 + public/Wb/Home/Src/Misc/DoDistro.HC.HTML | 80 + public/Wb/Home/Src/Misc/OSInstall.HC.HTML | 250 + public/Wb/Home/Src/Misc/OSTestSuite.HC.HTML | 1754 +++ public/Wb/Home/Src/Misc/PCIDevices.DD.HTML | 9460 +++++++++++++++++ public/Wb/Home/Src/Once.HC.HTML | 86 + public/Wb/Home/Src/PersonalMenu.DD.HTML | 161 + public/Wb/Home/Src/PersonalNotes.DD.HTML | 35 + public/Wb/Home/Src/StartOS.HC.HTML | 77 + public/Wb/HomeKeyPlugIns.HC.HTML | 233 + public/Wb/HomeLocalize.HC.HTML | 50 + public/Wb/HomeSys.HC.HTML | 69 + public/Wb/HomeWrappers.HC.HTML | 57 + public/Wb/Kernel/BlkDev/DskATA.HC.HTML | 642 ++ public/Wb/Kernel/BlkDev/DskATAId.HC.HTML | 324 + public/Wb/Kernel/BlkDev/DskAddDev.HC.HTML | 271 + public/Wb/Kernel/BlkDev/DskBlk.HC.HTML | 140 + public/Wb/Kernel/BlkDev/DskBlkDev.HC.HTML | 218 + public/Wb/Kernel/BlkDev/DskCDDVD.HC.HTML | 274 + public/Wb/Kernel/BlkDev/DskCFile.HC.HTML | 296 + public/Wb/Kernel/BlkDev/DskCache.HC.HTML | 176 + public/Wb/Kernel/BlkDev/DskClus.HC.HTML | 176 + public/Wb/Kernel/BlkDev/DskCopy.HC.HTML | 134 + public/Wb/Kernel/BlkDev/DskDirA.HC.HTML | 242 + public/Wb/Kernel/BlkDev/DskDirB.HC.HTML | 225 + public/Wb/Kernel/BlkDev/DskDirContext.HC.HTML | 118 + public/Wb/Kernel/BlkDev/DskDrv.HC.HTML | 397 + public/Wb/Kernel/BlkDev/DskFile.HC.HTML | 149 + public/Wb/Kernel/BlkDev/DskFind.HC.HTML | 182 + public/Wb/Kernel/BlkDev/DskFmt.HC.HTML | 123 + public/Wb/Kernel/BlkDev/DskStrA.HC.HTML | 374 + public/Wb/Kernel/BlkDev/DskStrB.HC.HTML | 120 + public/Wb/Kernel/BlkDev/FileSysFAT.HC.HTML | 990 ++ public/Wb/Kernel/BlkDev/FileSysRedSea.HC.HTML | 666 ++ public/Wb/Kernel/BlkDev/MakeBlkDev.HC.HTML | 54 + public/Wb/Kernel/Compress.HC.HTML | 339 + public/Wb/Kernel/Display.HC.HTML | 152 + public/Wb/Kernel/EdLite.HC.HTML | 386 + public/Wb/Kernel/FontCyrillic.HC.HTML | 163 + public/Wb/Kernel/FontStd.HC.HTML | 163 + public/Wb/Kernel/FunSeg.HC.HTML | 391 + public/Wb/Kernel/Job.HC.HTML | 533 + public/Wb/Kernel/KCfg.HC.HTML | 204 + public/Wb/Kernel/KDataTypes.HC.HTML | 354 + public/Wb/Kernel/KDate.HC.HTML | 227 + public/Wb/Kernel/KDbg.HC.HTML | 683 ++ public/Wb/Kernel/KDefine.HC.HTML | 249 + public/Wb/Kernel/KExcept.HC.HTML | 180 + public/Wb/Kernel/KExts.HC.HTML | 140 + public/Wb/Kernel/KGlbls.HC.HTML | 66 + public/Wb/Kernel/KHashA.HC.HTML | 296 + public/Wb/Kernel/KHashB.HC.HTML | 281 + public/Wb/Kernel/KInts.HC.HTML | 246 + public/Wb/Kernel/KLoad.HC.HTML | 281 + public/Wb/Kernel/KMain.HC.HTML | 269 + public/Wb/Kernel/KMathA.HC.HTML | 679 ++ public/Wb/Kernel/KMathB.HC.HTML | 188 + public/Wb/Kernel/KMisc.HC.HTML | 357 + public/Wb/Kernel/KStart16.HC.HTML | 237 + public/Wb/Kernel/KStart32.HC.HTML | 148 + public/Wb/Kernel/KStart64.HC.HTML | 131 + public/Wb/Kernel/KTask.HC.HTML | 576 + public/Wb/Kernel/KUtils.HC.HTML | 502 + public/Wb/Kernel/KernelA.HH | 0 public/Wb/Kernel/KernelA.HH.HTML | 3938 +++++++ public/Wb/Kernel/KernelB.HH | 0 public/Wb/Kernel/KernelB.HH.HTML | 325 + public/Wb/Kernel/KernelC.HH | 0 public/Wb/Kernel/KernelC.HH.HTML | 799 ++ public/Wb/Kernel/KeyDev.HC.HTML | 250 + public/Wb/Kernel/Mem/BlkPool.HC.HTML | 104 + public/Wb/Kernel/Mem/HeapCtrl.HC.HTML | 64 + public/Wb/Kernel/Mem/MAllocFree.HC.HTML | 495 + public/Wb/Kernel/Mem/MakeMem.HC.HTML | 39 + public/Wb/Kernel/Mem/MemPag.HC.HTML | 198 + public/Wb/Kernel/Mem/MemPhysical.HC.HTML | 212 + public/Wb/Kernel/Mem/PageTables.HC.HTML | 236 + public/Wb/Kernel/MultiProc.HC.HTML | 420 + public/Wb/Kernel/PCIBIOS.HC.HTML | 320 + public/Wb/Kernel/QSort.HC.HTML | 135 + public/Wb/Kernel/Sched.HC.HTML | 356 + public/Wb/Kernel/SerialDev/Keyboard.HC.HTML | 523 + .../Wb/Kernel/SerialDev/MakeSerialDev.HC.HTML | 36 + public/Wb/Kernel/SerialDev/Message.HC.HTML | 275 + public/Wb/Kernel/SerialDev/Mouse.HC.HTML | 398 + public/Wb/Kernel/StrA.HC.HTML | 717 ++ public/Wb/Kernel/StrB.HC.HTML | 218 + public/Wb/Kernel/StrPrint.HC.HTML | 951 ++ public/Wb/Kernel/StrScan.HC.HTML | 370 + public/Wb/MakeHome.HC.HTML | 44 + public/Wb/Misc/DoDistro.HC.HTML | 80 + public/Wb/Misc/OSInstall.HC.HTML | 250 + public/Wb/Misc/OSTestSuite.HC.HTML | 1754 +++ public/Wb/Once.HC.HTML | 86 + public/Wb/PersonalMenu.DD.HTML | 6 +- public/Wb/StartOS.HC.HTML | 77 + 1408 files changed, 308053 insertions(+), 748 deletions(-) create mode 100755 public/Wb/Adam/ABlkDev/ADskA.HC.HTML create mode 100755 public/Wb/Adam/ABlkDev/ADskB.HC.HTML create mode 100755 public/Wb/Adam/ABlkDev/DskChk.HC.HTML create mode 100755 public/Wb/Adam/ABlkDev/DskPrt.HC.HTML create mode 100755 public/Wb/Adam/ABlkDev/FileMgr.HC.HTML create mode 100755 public/Wb/Adam/ABlkDev/MakeABlkDev.HC.HTML create mode 100755 public/Wb/Adam/ABlkDev/Mount.HC.HTML create mode 100755 public/Wb/Adam/ADbg.HC.HTML create mode 100755 public/Wb/Adam/ADefine.HC.HTML create mode 100755 public/Wb/Adam/AExts.HC.HTML create mode 100755 public/Wb/Adam/AHash.HC.HTML create mode 100755 public/Wb/Adam/AMath.HC.HTML create mode 100755 public/Wb/Adam/AMathODE.HC.HTML create mode 100755 public/Wb/Adam/AMem.HC.HTML create mode 100755 public/Wb/Adam/AMouse.HC.HTML create mode 100755 public/Wb/Adam/ARegistry.HC.HTML create mode 100755 public/Wb/Adam/ASnd.HC.HTML create mode 100755 public/Wb/Adam/AutoComplete/ACDictGen.HC.HTML create mode 100755 public/Wb/Adam/AutoComplete/ACFill.HC.HTML create mode 100755 public/Wb/Adam/AutoComplete/ACInit.HC.HTML create mode 100755 public/Wb/Adam/AutoComplete/ACTask.HC.HTML create mode 100755 public/Wb/Adam/AutoComplete/MakeAC.HC.HTML create mode 100755 public/Wb/Adam/CPURep.HC.HTML create mode 100755 public/Wb/Adam/Ctrls/CtrlsA.HC.HTML create mode 100755 public/Wb/Adam/Ctrls/CtrlsBttn.HC.HTML create mode 100755 public/Wb/Adam/Ctrls/CtrlsSlider.HC.HTML create mode 100755 public/Wb/Adam/Ctrls/MakeCtrls.HC.HTML create mode 100755 public/Wb/Adam/DevInfo.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocBin.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocChar.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocClipBoard.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocCodeTools.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocDblBuf.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocEd.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocExt.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocFile.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocFind.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocForm.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocGet.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocGr.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocHighlight.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocInit.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocLink.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocMacro.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocNew.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocPlain.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocPopUp.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocPutKey.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocPutS.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocRecalc.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocRecalcLib.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocRun.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocTerm.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocTree.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/DocWidgetWiz.HC.HTML create mode 100755 public/Wb/Adam/DolDoc/MakeDoc.HC.HTML create mode 100755 public/Wb/Adam/God/GodBible.HC.HTML create mode 100755 public/Wb/Adam/God/GodDoodle.HC.HTML create mode 100755 public/Wb/Adam/God/GodExt.HC.HTML create mode 100755 public/Wb/Adam/God/GodSong.HC.HTML create mode 100755 public/Wb/Adam/God/HolySpirit.HC.HTML create mode 100755 public/Wb/Adam/God/MakeGod.HC.HTML mode change 100644 => 100755 public/Wb/Adam/Gr/Gr.HH create mode 100755 public/Wb/Adam/Gr/Gr.HH.HTML create mode 100755 public/Wb/Adam/Gr/GrAsm.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrBitMap.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrComposites.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrDC.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrEnd.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrExt.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrGlbls.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrInitA.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrInitB.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrMath.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrPalette.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrPrimatives.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrScrn.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrSpritePlot.HC.HTML create mode 100755 public/Wb/Adam/Gr/GrTextBase.HC.HTML create mode 100755 public/Wb/Adam/Gr/MakeGr.HC.HTML create mode 100755 public/Wb/Adam/Gr/ScrnCast.HC.HTML create mode 100755 public/Wb/Adam/Gr/SpriteBitMap.HC.HTML create mode 100755 public/Wb/Adam/Gr/SpriteCode.HC.HTML create mode 100755 public/Wb/Adam/Gr/SpriteEd.HC.HTML create mode 100755 public/Wb/Adam/Gr/SpriteMain.HC.HTML create mode 100755 public/Wb/Adam/Gr/SpriteMesh.HC.HTML create mode 100755 public/Wb/Adam/Gr/SpriteNew.HC.HTML create mode 100755 public/Wb/Adam/Gr/SpriteSideBar.HC.HTML create mode 100755 public/Wb/Adam/Host.HC.HTML create mode 100755 public/Wb/Adam/InFile.HC.HTML create mode 100755 public/Wb/Adam/InsReg.HC.HTML create mode 100755 public/Wb/Adam/MakeAdam.HC.HTML create mode 100755 public/Wb/Adam/Menu.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootDVD.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootDVDIns.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootHD.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootHDIns.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootMHD.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootMHD2.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootMHDIns.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/BootRAM.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/DskISORedSea.HC.HTML create mode 100755 public/Wb/Adam/Opt/Boot/MakeBoot.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/Diff.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/DocUtils.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/Find.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/HeapLog.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/LineRep.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/LinkChk.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/MakeUtils.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/MemRep.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/Merge.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/Profiler.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/StrUtils.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/TOS.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/ToDolDoc.HC.HTML create mode 100755 public/Wb/Adam/Opt/Utils/ToTXT.HC.HTML create mode 100755 public/Wb/Adam/TaskRep.HC.HTML create mode 100755 public/Wb/Adam/TaskSettings.HC.HTML create mode 100755 public/Wb/Adam/Training.HC.HTML create mode 100755 public/Wb/Adam/WallPaper.HC.HTML create mode 100755 public/Wb/Adam/Win.HC.HTML create mode 100755 public/Wb/Adam/WinMgr.HC.HTML create mode 100755 public/Wb/Apps/Budget/BgtAccts.HC.HTML create mode 100755 public/Wb/Apps/Budget/BgtEntry.HC.HTML create mode 100755 public/Wb/Apps/Budget/BgtFile.HC.HTML create mode 100755 public/Wb/Apps/Budget/BgtMain.HC.HTML create mode 100755 public/Wb/Apps/Budget/BgtStrs.HC.HTML create mode 100755 public/Wb/Apps/Budget/BgtTemplate.HC.HTML create mode 100755 public/Wb/Apps/Budget/Budget.HC.HTML create mode 100755 public/Wb/Apps/Budget/Install.HC.HTML create mode 100755 public/Wb/Apps/Budget/Load.HC.HTML create mode 100755 public/Wb/Apps/Budget/Run.HC.HTML create mode 100755 public/Wb/Apps/GrModels/BallGen.HC.HTML create mode 100755 public/Wb/Apps/GrModels/Load.HC.HTML create mode 100755 public/Wb/Apps/GrModels/ManGen.HC.HTML create mode 100755 public/Wb/Apps/GrModels/Models.HC.HTML create mode 100755 public/Wb/Apps/GrModels/Run.HC.HTML create mode 100755 public/Wb/Apps/KeepAway/KeepAway.HC.HTML create mode 100755 public/Wb/Apps/KeepAway/Load.HC.HTML create mode 100755 public/Wb/Apps/KeepAway/Run.HC.HTML create mode 100755 public/Wb/Apps/Logic/Load.HC.HTML create mode 100755 public/Wb/Apps/Logic/Logic.HC.HTML create mode 100755 public/Wb/Apps/Logic/Run.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/Examples/childish.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/Examples/night.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/Examples/prosper.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/Install.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/JukeBox.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/JukePuppet.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/Load.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/Psalmody.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/PsalmodyCtrls.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/PsalmodyDraw.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/PsalmodyFile.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/PsalmodyMain.HC.HTML create mode 100755 public/Wb/Apps/Psalmody/Run.HC.HTML create mode 100755 public/Wb/Apps/Span/Install.HC.HTML create mode 100755 public/Wb/Apps/Span/Load.HC.HTML create mode 100755 public/Wb/Apps/Span/Run.HC.HTML mode change 100644 => 100755 public/Wb/Apps/Span/Span.HH create mode 100755 public/Wb/Apps/Span/Span.HH.HTML create mode 100755 public/Wb/Apps/Span/SpanBridge.HC.HTML create mode 100755 public/Wb/Apps/Span/SpanDerive.HC.HTML create mode 100755 public/Wb/Apps/Span/SpanMain.HC.HTML create mode 100755 public/Wb/Apps/Span/SpanNew.HC.HTML create mode 100755 public/Wb/Apps/Strut/Load.HC.HTML create mode 100755 public/Wb/Apps/Strut/Run.HC.HTML create mode 100755 public/Wb/Apps/Strut/Strut.HC.HTML create mode 100755 public/Wb/Apps/TimeClock/Install.HC.HTML create mode 100755 public/Wb/Apps/TimeClock/Load.HC.HTML create mode 100755 public/Wb/Apps/TimeClock/TimeClk.HC.HTML create mode 100755 public/Wb/Apps/Titanium/Load.HC.HTML create mode 100755 public/Wb/Apps/Titanium/Run.HC.HTML create mode 100755 public/Wb/Apps/Titanium/Titanium.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/AIs/Human.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/AIs/SimpleAI.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/Install.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/Load.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/Run.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/TTFDraw.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/TTFFire.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/TTFGlbls.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/TTFInit.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/TTFLib.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/TTFMove.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/TTFVis.HC.HTML create mode 100755 public/Wb/Apps/ToTheFront/ToTheFront.HC.HTML create mode 100755 public/Wb/Apps/Vocabulary/Load.HC.HTML create mode 100755 public/Wb/Apps/Vocabulary/Run.HC.HTML create mode 100755 public/Wb/Apps/Vocabulary/VocabQuiz.HC.HTML create mode 100755 public/Wb/Apps/X-Caliber/Load.HC.HTML create mode 100755 public/Wb/Apps/X-Caliber/Run.HC.HTML create mode 100755 public/Wb/Apps/X-Caliber/X-Caliber.HC.HTML create mode 100755 public/Wb/Apps/X-Caliber/XCCtrls.HC.HTML create mode 100755 public/Wb/Compiler/Asm.HC.HTML create mode 100755 public/Wb/Compiler/AsmInit.HC.HTML create mode 100755 public/Wb/Compiler/AsmLib.HC.HTML create mode 100755 public/Wb/Compiler/AsmResolve.HC.HTML create mode 100755 public/Wb/Compiler/BackA.HC.HTML create mode 100755 public/Wb/Compiler/BackB.HC.HTML create mode 100755 public/Wb/Compiler/BackC.HC.HTML create mode 100755 public/Wb/Compiler/BackFA.HC.HTML create mode 100755 public/Wb/Compiler/BackFB.HC.HTML create mode 100755 public/Wb/Compiler/BackLib.HC.HTML create mode 100755 public/Wb/Compiler/CExcept.HC.HTML create mode 100755 public/Wb/Compiler/CExts.HC.HTML create mode 100755 public/Wb/Compiler/CHash.HC.HTML create mode 100755 public/Wb/Compiler/CInit.HC.HTML create mode 100755 public/Wb/Compiler/CMain.HC.HTML create mode 100755 public/Wb/Compiler/CMisc.HC.HTML mode change 100644 => 100755 public/Wb/Compiler/CompilerA.HH create mode 100755 public/Wb/Compiler/CompilerA.HH.HTML mode change 100644 => 100755 public/Wb/Compiler/CompilerB.HH create mode 100755 public/Wb/Compiler/CompilerB.HH.HTML create mode 100755 public/Wb/Compiler/Lex.HC.HTML create mode 100755 public/Wb/Compiler/LexLib.HC.HTML create mode 100755 public/Wb/Compiler/OptLib.HC.HTML create mode 100755 public/Wb/Compiler/OptPass012.HC.HTML create mode 100755 public/Wb/Compiler/OptPass3.HC.HTML create mode 100755 public/Wb/Compiler/OptPass4.HC.HTML create mode 100755 public/Wb/Compiler/OptPass5.HC.HTML create mode 100755 public/Wb/Compiler/OptPass6.HC.HTML create mode 100755 public/Wb/Compiler/OptPass789A.HC.HTML create mode 100755 public/Wb/Compiler/PrsExp.HC.HTML create mode 100755 public/Wb/Compiler/PrsLib.HC.HTML create mode 100755 public/Wb/Compiler/PrsStmt.HC.HTML create mode 100755 public/Wb/Compiler/PrsVar.HC.HTML create mode 100755 public/Wb/Compiler/Templates.HC.HTML create mode 100755 public/Wb/Compiler/UAsm.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/HomeKeyPlugIns.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/HomeLocalize.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/HomeSys.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/HomeWrappers.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/MakeHome.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/Once.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/Registry.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/TOS/MakeTOS.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/TOS/TOSCfg.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/TOS/TOSDistro.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/TOS/TOSExt.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/TOS/TOSMisc.HC.HTML create mode 100755 public/Wb/Demo/AcctExample/TOS/TOSTheme.HC.HTML create mode 100755 public/Wb/Demo/Asm/AsmAndC1.HC.HTML create mode 100755 public/Wb/Demo/Asm/AsmAndC2.HC.HTML create mode 100755 public/Wb/Demo/Asm/AsmAndC3.HC.HTML create mode 100755 public/Wb/Demo/Asm/AsmHelloWorld.HC.HTML create mode 100755 public/Wb/Demo/Asm/BuzzFizz.HC.HTML create mode 100755 public/Wb/Demo/Asm/DivByHand.HC.HTML create mode 100755 public/Wb/Demo/Asm/MulByHand.HC.HTML create mode 100755 public/Wb/Demo/Asm/PutDec.HC.HTML create mode 100755 public/Wb/Demo/Carry.HC.HTML create mode 100755 public/Wb/Demo/ClassMeta.HC.HTML create mode 100755 public/Wb/Demo/CompileDemo.HC.HTML create mode 100755 public/Wb/Demo/DateTime.HC.HTML create mode 100755 public/Wb/Demo/DbgDemo.HC.HTML create mode 100755 public/Wb/Demo/Define.HC.HTML create mode 100755 public/Wb/Demo/Directives.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/CallBack.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/ClickCallBack.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/CursorMove.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/Data.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/DefineStr.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/FileRead.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/Form.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/MenuBttn.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/MenuSprite.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/NumBible.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/TextDemo.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/TreeDemo.HC.HTML create mode 100755 public/Wb/Demo/DolDoc/UnusedDefine.HC.HTML create mode 100755 public/Wb/Demo/Dsk/BlkDevRep.HC.HTML create mode 100755 public/Wb/Demo/Dsk/DataBase.HC.HTML create mode 100755 public/Wb/Demo/Dsk/DskRaw.HC.HTML create mode 100755 public/Wb/Demo/Dsk/FPrintF.HC.HTML create mode 100755 public/Wb/Demo/Dsk/SerializeTree.HC.HTML create mode 100755 public/Wb/Demo/Dsk/UnusedSpaceRep.HC.HTML create mode 100755 public/Wb/Demo/Exceptions.HC.HTML create mode 100755 public/Wb/Demo/ExtChars.HC.HTML create mode 100755 public/Wb/Demo/Games/BattleLines.HC.HTML create mode 100755 public/Wb/Demo/Games/BigGuns.HC.HTML create mode 100755 public/Wb/Demo/Games/BlackDiamond.HC.HTML create mode 100755 public/Wb/Demo/Games/BomberGolf.HC.HTML create mode 100755 public/Wb/Demo/Games/CastleFrankenstein.HC.HTML create mode 100755 public/Wb/Demo/Games/CharDemo.HC.HTML create mode 100755 public/Wb/Demo/Games/CircleTrace.HC.HTML create mode 100755 public/Wb/Demo/Games/Collision.HC.HTML create mode 100755 public/Wb/Demo/Games/Digits.HC.HTML create mode 100755 public/Wb/Demo/Games/DunGen.HC.HTML create mode 100755 public/Wb/Demo/Games/ElephantWalk.HC.HTML create mode 100755 public/Wb/Demo/Games/FlapBat.HC.HTML create mode 100755 public/Wb/Demo/Games/FlatTops.HC.HTML create mode 100755 public/Wb/Demo/Games/Halogen.HC.HTML create mode 100755 public/Wb/Demo/Games/MassSpring.HC.HTML create mode 100755 public/Wb/Demo/Games/Maze.HC.HTML create mode 100755 public/Wb/Demo/Games/RainDrops.HC.HTML create mode 100755 public/Wb/Demo/Games/RawHide.HC.HTML create mode 100755 public/Wb/Demo/Games/Rocket.HC.HTML create mode 100755 public/Wb/Demo/Games/RocketScience.HC.HTML create mode 100755 public/Wb/Demo/Games/Squirt.HC.HTML create mode 100755 public/Wb/Demo/Games/Stadium/Stadium.HC.HTML create mode 100755 public/Wb/Demo/Games/Stadium/StadiumGen.HC.HTML create mode 100755 public/Wb/Demo/Games/Talons.HC.HTML create mode 100755 public/Wb/Demo/Games/TheDead.HC.HTML create mode 100755 public/Wb/Demo/Games/TicTacToe.HC.HTML create mode 100755 public/Wb/Demo/Games/TreeCheckers.HC.HTML create mode 100755 public/Wb/Demo/Games/Varoom.HC.HTML create mode 100755 public/Wb/Demo/Games/Wenceslas.HC.HTML create mode 100755 public/Wb/Demo/Games/Whap.HC.HTML create mode 100755 public/Wb/Demo/Games/Zing.HC.HTML create mode 100755 public/Wb/Demo/Games/ZoneOut.HC.HTML create mode 100755 public/Wb/Demo/GlblVars.HC.HTML create mode 100755 public/Wb/Demo/Graphics/3DPoly.HC.HTML create mode 100755 public/Wb/Demo/Graphics/BSpline.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Balloon.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Blot.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Bounce.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Box.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Cartesian.HC.HTML create mode 100755 public/Wb/Demo/Graphics/CharAnimation.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Collision.HC.HTML create mode 100755 public/Wb/Demo/Graphics/CommonAncestor.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Doodle.HC.HTML create mode 100755 public/Wb/Demo/Graphics/EdSprite.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Elephant.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Extents.HC.HTML create mode 100755 public/Wb/Demo/Graphics/FontEd.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Grid.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Hanoi.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Lattice.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Life.HC.HTML create mode 100755 public/Wb/Demo/Graphics/LightTable.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Lines.HC.HTML create mode 100755 public/Wb/Demo/Graphics/LowPassFilter.HC.HTML create mode 100755 public/Wb/Demo/Graphics/MathAudioDemo.HC.HTML create mode 100755 public/Wb/Demo/Graphics/MouseDemo.HC.HTML create mode 100755 public/Wb/Demo/Graphics/NetOfDots.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Palette.HC.HTML create mode 100755 public/Wb/Demo/Graphics/PanText.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Pick.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Pick3D.HC.HTML create mode 100755 public/Wb/Demo/Graphics/PoleZeros.HC.HTML create mode 100755 public/Wb/Demo/Graphics/PredatorPrey.HC.HTML create mode 100755 public/Wb/Demo/Graphics/RotateTank.HC.HTML create mode 100755 public/Wb/Demo/Graphics/ScrnCapture.HC.HTML create mode 100755 public/Wb/Demo/Graphics/ScrollBars.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Shading.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Shadow.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Slider.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Speedline.HC.HTML create mode 100755 public/Wb/Demo/Graphics/SpritePlot.HC.HTML create mode 100755 public/Wb/Demo/Graphics/SpritePlot3D.HC.HTML create mode 100755 public/Wb/Demo/Graphics/SpritePut.HC.HTML create mode 100755 public/Wb/Demo/Graphics/SpritePutExt.HC.HTML create mode 100755 public/Wb/Demo/Graphics/SpriteRaw.HC.HTML create mode 100755 public/Wb/Demo/Graphics/SpriteText.HC.HTML create mode 100755 public/Wb/Demo/Graphics/SunMoon.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Symmetry.HC.HTML create mode 100755 public/Wb/Demo/Graphics/Transform.HC.HTML create mode 100755 public/Wb/Demo/Graphics/WallPaperCtrl.HC.HTML create mode 100755 public/Wb/Demo/Graphics/WallPaperFish.HC.HTML create mode 100755 public/Wb/Demo/Graphics/WinZBuf.HC.HTML create mode 100755 public/Wb/Demo/InFile/InPopUp.HC.HTML create mode 100755 public/Wb/Demo/InFile/InSetIP.HC.HTML create mode 100755 public/Wb/Demo/KeyBitMap.HC.HTML create mode 100755 public/Wb/Demo/LastClass.HC.HTML create mode 100755 public/Wb/Demo/Lectures/AndNotMod.HC.HTML create mode 100755 public/Wb/Demo/Lectures/FixedPoint.HC.HTML create mode 100755 public/Wb/Demo/Lectures/FixedPointAdvanced.HC.HTML create mode 100755 public/Wb/Demo/Lectures/GraphicsCPULoad.HC.HTML create mode 100755 public/Wb/Demo/Lectures/InterruptDemo.HC.HTML create mode 100755 public/Wb/Demo/Lectures/MiniCompiler.HC.HTML create mode 100755 public/Wb/Demo/Lectures/MiniGrLib.HC.HTML create mode 100755 public/Wb/Demo/Lectures/NegDisp.HC.HTML create mode 100755 public/Wb/Demo/Lectures/Optimization.HC.HTML create mode 100755 public/Wb/Demo/Lectures/PCIInterrupts.HC.HTML create mode 100755 public/Wb/Demo/Lectures/Ring3.HC.HTML create mode 100755 public/Wb/Demo/Lectures/ScrnMemory.HC.HTML create mode 100755 public/Wb/Demo/MagicPairs.HC.HTML create mode 100755 public/Wb/Demo/MemDemo.HC.HTML create mode 100755 public/Wb/Demo/MsgLoop.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/Interrupts.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/LoadTest.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/Lock.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/MPAdd.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/MPPrint.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/MPRadix.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/Palindrome.HC.HTML create mode 100755 public/Wb/Demo/MultiCore/Primes.HC.HTML create mode 100755 public/Wb/Demo/NullCase.HC.HTML create mode 100755 public/Wb/Demo/OnceDemo.HC.HTML create mode 100755 public/Wb/Demo/ParenWarn.HC.HTML create mode 100755 public/Wb/Demo/PhoneNumWords.HC.HTML create mode 100755 public/Wb/Demo/Print.HC.HTML create mode 100755 public/Wb/Demo/Progress.HC.HTML create mode 100755 public/Wb/Demo/Prompt.HC.HTML create mode 100755 public/Wb/Demo/PullDownMenu.HC.HTML create mode 100755 public/Wb/Demo/RadixSort.HC.HTML create mode 100755 public/Wb/Demo/RandDemo.HC.HTML create mode 100755 public/Wb/Demo/RegistryDemo.HC.HTML create mode 100755 public/Wb/Demo/RevFileDemo/Rev.HC.HTML create mode 100755 public/Wb/Demo/ScrnCodes.HC.HTML create mode 100755 public/Wb/Demo/Snd/ASCIIOrgan.HC.HTML create mode 100755 public/Wb/Demo/Snd/MorseCode.HC.HTML create mode 100755 public/Wb/Demo/Snd/OhGreat.HC.HTML create mode 100755 public/Wb/Demo/Snd/WaterFowl.HC.HTML create mode 100755 public/Wb/Demo/SortFileDemo/F64FileGen.HC.HTML create mode 100755 public/Wb/Demo/SortFileDemo/F64FileSort.HC.HTML create mode 100755 public/Wb/Demo/Spy.HC.HTML create mode 100755 public/Wb/Demo/StkGrow.HC.HTML create mode 100755 public/Wb/Demo/SubIntAccess.HC.HTML create mode 100755 public/Wb/Demo/SubSwitch.HC.HTML create mode 100755 public/Wb/Demo/SuggestSpelling.HC.HTML create mode 100755 public/Wb/Demo/Templates/Game1.HC.HTML create mode 100755 public/Wb/Demo/Templates/Lex1.HC.HTML create mode 100755 public/Wb/Demo/Templates/MultiCore1.HC.HTML create mode 100755 public/Wb/Demo/Templates/ODE1.HC.HTML create mode 100755 public/Wb/Demo/Templates/Registry1.HC.HTML create mode 100755 public/Wb/Demo/Templates/Util1.HC.HTML create mode 100755 public/Wb/Demo/Templates/Util2.HC.HTML create mode 100755 public/Wb/Demo/TimeIns.HC.HTML create mode 100755 public/Wb/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML create mode 100755 public/Wb/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML create mode 100755 public/Wb/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML create mode 100755 public/Wb/Demo/WebLogDemo/WebLogRep.HC.HTML create mode 100755 public/Wb/Demo/WebLogDemo/WebLogScramble.HC.HTML create mode 100755 public/Wb/Demo/WordSearch.HC.HTML create mode 100755 public/Wb/Doc/Comm.HC.HTML create mode 100755 public/Wb/Home/Copy.HC create mode 100755 public/Wb/Home/DoDistro.HC.HTML create mode 100755 public/Wb/Home/Doc/AboutTempleOS.DD.HTML create mode 100755 public/Wb/Home/Doc/Asm.DD.HTML create mode 100755 public/Wb/Home/Doc/AutoComplete.DD.HTML create mode 100755 public/Wb/Home/Doc/Bit.DD.HTML create mode 100755 public/Wb/Home/Doc/BlkChain.DD.HTML create mode 100755 public/Wb/Home/Doc/Boot.DD.HTML create mode 100755 public/Wb/Home/Doc/CharOverview.DD.HTML create mode 100755 public/Wb/Home/Doc/Charter.DD.HTML create mode 100755 public/Wb/Home/Doc/CmdLineOverview.DD.HTML create mode 100755 public/Wb/Home/Doc/Comm.HC.HTML create mode 100755 public/Wb/Home/Doc/CompilerOverview.DD.HTML create mode 100755 public/Wb/Home/Doc/Credits.DD.HTML create mode 100755 public/Wb/Home/Doc/Ctrls.DD.HTML create mode 100755 public/Wb/Home/Doc/Customize.DD.HTML create mode 100755 public/Wb/Home/Doc/CutCorners.DD.HTML create mode 100755 public/Wb/Home/Doc/D3.DD.HTML create mode 100755 public/Wb/Home/Doc/Date.DD.HTML create mode 100755 public/Wb/Home/Doc/DbgFunSeg.DD.HTML create mode 100755 public/Wb/Home/Doc/DbgOverview.DD.HTML create mode 100755 public/Wb/Home/Doc/Define.DD.HTML create mode 100755 public/Wb/Home/Doc/Demands.DD.HTML create mode 100755 public/Wb/Home/Doc/DemoIndex.DD.HTML create mode 100755 public/Wb/Home/Doc/Directives.DD.HTML create mode 100755 public/Wb/Home/Doc/DolDoc.DD.HTML create mode 100755 public/Wb/Home/Doc/DolDocOverview.DD.HTML create mode 100755 public/Wb/Home/Doc/EdPullDown.DD.HTML create mode 100755 public/Wb/Home/Doc/FAQ.DD.HTML create mode 100755 public/Wb/Home/Doc/Features.DD.HTML create mode 100755 public/Wb/Home/Doc/FileLowLevel.DD.HTML create mode 100755 public/Wb/Home/Doc/FileMgr.DD.HTML create mode 100755 public/Wb/Home/Doc/FileMgrPullDown.DD.HTML create mode 100755 public/Wb/Home/Doc/FileUtils.DD.HTML create mode 100755 public/Wb/Home/Doc/Frame.DD.HTML create mode 100755 public/Wb/Home/Doc/GRFiles.DD.HTML create mode 100755 public/Wb/Home/Doc/Glossary.DD.HTML create mode 100755 public/Wb/Home/Doc/God.DD.HTML create mode 100755 public/Wb/Home/Doc/GraphicsOverview.DD.HTML create mode 100755 public/Wb/Home/Doc/GuideLines.DD.HTML create mode 100755 public/Wb/Home/Doc/Hash.DD.HTML create mode 100755 public/Wb/Home/Doc/HeapDbg.DD.HTML create mode 100755 public/Wb/Home/Doc/HelloWorld.DD.HTML create mode 100755 public/Wb/Home/Doc/HelpIndex.DD.HTML create mode 100755 public/Wb/Home/Doc/HelpSystem.DD.HTML create mode 100755 public/Wb/Home/Doc/HolyC.DD.HTML create mode 100755 public/Wb/Home/Doc/InFile.DD.HTML create mode 100755 public/Wb/Home/Doc/Install.DD.HTML create mode 100755 public/Wb/Home/Doc/Job.DD.HTML create mode 100755 public/Wb/Home/Doc/KeyAlloc.DD.HTML create mode 100755 public/Wb/Home/Doc/KeyDev.DD.HTML create mode 100755 public/Wb/Home/Doc/Lex.DD.HTML create mode 100755 public/Wb/Home/Doc/MemOverview.DD.HTML create mode 100755 public/Wb/Home/Doc/Menus.DD.HTML create mode 100755 public/Wb/Home/Doc/Mouse.DD.HTML create mode 100755 public/Wb/Home/Doc/Msgs.DD.HTML create mode 100755 public/Wb/Home/Doc/MultiCore.DD.HTML create mode 100755 public/Wb/Home/Doc/NewASCII.DD.HTML create mode 100755 public/Wb/Home/Doc/ODE.DD.HTML create mode 100755 public/Wb/Home/Doc/Once.DD.HTML create mode 100755 public/Wb/Home/Doc/Options.DD.HTML create mode 100755 public/Wb/Home/Doc/Pags.DD.HTML create mode 100755 public/Wb/Home/Doc/PreProcessor.DD.HTML create mode 100755 public/Wb/Home/Doc/Print.DD.HTML create mode 100755 public/Wb/Home/Doc/Profiler.DD.HTML create mode 100755 public/Wb/Home/Doc/Que.DD.HTML create mode 100755 public/Wb/Home/Doc/Quirks.DD.HTML create mode 100755 public/Wb/Home/Doc/RedSea.DD.HTML create mode 100755 public/Wb/Home/Doc/Reliability.DD.HTML create mode 100755 public/Wb/Home/Doc/Requirements.DD.HTML create mode 100755 public/Wb/Home/Doc/Resource.DD.HTML create mode 100755 public/Wb/Home/Doc/ScopingLinkage.DD.HTML create mode 100755 public/Wb/Home/Doc/Snd.DD.HTML create mode 100755 public/Wb/Home/Doc/Sprite.DD.HTML create mode 100755 public/Wb/Home/Doc/SpriteBitMap.DD.HTML create mode 100755 public/Wb/Home/Doc/SpriteEd.DD.HTML create mode 100755 public/Wb/Home/Doc/SpriteEdText.DD.HTML create mode 100755 public/Wb/Home/Doc/SpriteMain.DD.HTML create mode 100755 public/Wb/Home/Doc/SpriteSideBar.DD.HTML create mode 100755 public/Wb/Home/Doc/StandBy.DD.HTML create mode 100755 public/Wb/Home/Doc/Start.DD.HTML create mode 100755 public/Wb/Home/Doc/StdOutTask.DD.HTML create mode 100755 public/Wb/Home/Doc/StdTempleOSPC.DD.HTML create mode 100755 public/Wb/Home/Doc/Strategy.DD.HTML create mode 100755 public/Wb/Home/Doc/Streams.DD.HTML create mode 100755 public/Wb/Home/Doc/TOSZ.DD.HTML create mode 100755 public/Wb/Home/Doc/TextBase.DD.HTML create mode 100755 public/Wb/Home/Doc/TimeCycles.DD.HTML create mode 100755 public/Wb/Home/Doc/TimeDate.DD.HTML create mode 100755 public/Wb/Home/Doc/TimeHPET.DD.HTML create mode 100755 public/Wb/Home/Doc/TimeJiffy.DD.HTML create mode 100755 public/Wb/Home/Doc/Tips.DD.HTML create mode 100755 public/Wb/Home/Doc/Transform.DD.HTML create mode 100755 public/Wb/Home/Doc/Welcome.DD.HTML create mode 100755 public/Wb/Home/Doc/WhyNotMore.DD.HTML create mode 100755 public/Wb/Home/Doc/Widget.DD.HTML create mode 100755 public/Wb/Home/Doc/Windows.DD.HTML create mode 100755 public/Wb/Home/MakeHome.HC.HTML create mode 100755 public/Wb/Home/Registry.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ABlkDev/ADskA.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ABlkDev/ADskB.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ABlkDev/DskChk.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ABlkDev/DskPrt.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ABlkDev/FileMgr.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ABlkDev/MakeABlkDev.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ABlkDev/Mount.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ADbg.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ADefine.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AExts.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AHash.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AMath.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AMathODE.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AMem.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AMouse.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ARegistry.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/ASnd.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AutoComplete/ACDictGen.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AutoComplete/ACFill.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AutoComplete/ACInit.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AutoComplete/ACTask.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/AutoComplete/MakeAC.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/CPURep.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Ctrls/CtrlsA.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Ctrls/CtrlsBttn.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Ctrls/CtrlsSlider.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Ctrls/MakeCtrls.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DevInfo.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocBin.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocChar.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocClipBoard.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocCodeTools.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocDblBuf.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocEd.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocExt.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocFile.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocFind.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocForm.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocGet.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocGr.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocHighlight.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocInit.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocLink.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocMacro.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocNew.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocPlain.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocPopUp.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocPutKey.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocPutS.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocRecalc.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocRecalcLib.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocRun.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocTerm.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocTree.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/DocWidgetWiz.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/DolDoc/MakeDoc.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/God/GodBible.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/God/GodDoodle.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/God/GodExt.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/God/GodSong.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/God/HSNotes.DD.HTML create mode 100755 public/Wb/Home/Src/Adam/God/HolySpirit.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/God/MakeGod.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/God/Vocab.DD.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/Gr.HH.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrAsm.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrBitMap.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrComposites.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrDC.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrEnd.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrExt.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrGlbls.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrInitA.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrInitB.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrMath.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrPalette.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrPrimatives.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrScrn.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrSpritePlot.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/GrTextBase.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/MakeGr.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/ScrnCast.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/SpriteBitMap.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/SpriteCode.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/SpriteEd.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/SpriteMain.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/SpriteMesh.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/SpriteNew.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Gr/SpriteSideBar.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Host.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/InFile.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/InsReg.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/MakeAdam.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Menu.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootDVD.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootDVDIns.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootHD.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootHDIns.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootMHD.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootMHD2.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootMHDIns.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/BootRAM.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/DskISORedSea.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Boot/MakeBoot.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/Diff.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/DocUtils.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/Find.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/HeapLog.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/LineRep.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/LinkChk.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/MakeUtils.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/MemRep.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/Merge.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/Profiler.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/StrUtils.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/TOS.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/ToDolDoc.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Opt/Utils/ToTXT.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/TaskRep.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/TaskSettings.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Training.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/WallPaper.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/Win.HC.HTML create mode 100755 public/Wb/Home/Src/Adam/WinMgr.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/Accts.DD.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/BgtAccts.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/BgtEntry.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/BgtFile.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/BgtMain.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/BgtStrs.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/BgtTemplate.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/Budget.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/Install.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Budget/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/GrModels/BallGen.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/GrModels/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/GrModels/ManGen.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/GrModels/Models.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/GrModels/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/KeepAway/KeepAway.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/KeepAway/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/KeepAway/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Logic/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Logic/Logic.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Logic/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Examples/childish.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Examples/night.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Examples/prosper.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Help.DD.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Install.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/JukeBox.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/JukePuppet.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Psalmody.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/PsalmodyCtrls.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/PsalmodyDraw.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/PsalmodyFile.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/PsalmodyMain.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Psalmody/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/Install.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/Span.HH.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/SpanBridge.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/SpanDerive.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/SpanMain.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Span/SpanNew.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Strut/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Strut/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Strut/Strut.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/TimeClock/Install.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/TimeClock/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/TimeClock/TimeClk.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Titanium/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Titanium/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Titanium/Titanium.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/AIs/Human.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/AIs/SimpleAI.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/Install.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/TTFDraw.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/TTFFire.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/TTFGlbls.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/TTFInit.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/TTFLib.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/TTFMove.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/TTFVis.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/ToTheFront/ToTheFront.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Vocabulary/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Vocabulary/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/Vocabulary/VocabQuiz.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/X-Caliber/Load.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/X-Caliber/Run.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/X-Caliber/X-Caliber.HC.HTML create mode 100755 public/Wb/Home/Src/Apps/X-Caliber/XCCtrls.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/Asm.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/AsmInit.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/AsmLib.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/AsmResolve.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/BackA.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/BackB.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/BackC.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/BackFA.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/BackFB.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/BackLib.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/CExcept.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/CExts.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/CHash.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/CInit.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/CMain.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/CMisc.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/CompilerA.HH.HTML create mode 100755 public/Wb/Home/Src/Compiler/CompilerB.HH.HTML create mode 100755 public/Wb/Home/Src/Compiler/Lex.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/LexLib.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/OpCodes.DD.HTML create mode 100755 public/Wb/Home/Src/Compiler/OptLib.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/OptPass012.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/OptPass3.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/OptPass4.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/OptPass5.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/OptPass6.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/OptPass789A.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/PrsExp.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/PrsLib.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/PrsStmt.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/PrsVar.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/Templates.HC.HTML create mode 100755 public/Wb/Home/Src/Compiler/UAsm.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/HomeKeyPlugIns.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/HomeLocalize.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/HomeSys.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/HomeWrappers.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/MakeHome.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/Once.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/PersonalMenu.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/PersonalNotes.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/Registry.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/TOS/MakeTOS.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/TOS/TOSCfg.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/TOS/TOSDistro.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/TOS/TOSExt.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/TOS/TOSMisc.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/AcctExample/TOS/TOSTheme.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/AsmAndC1.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/AsmAndC2.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/AsmAndC3.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/AsmHelloWorld.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/BuzzFizz.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/DivByHand.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/MulByHand.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Asm/PutDec.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Carry.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/ClassMeta.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/CompileDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DateTime.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DbgDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Define.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Directives.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/CallBack.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/ClickCallBack.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/CursorMove.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/Data.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/DefineStr.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/DemoDoc.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/FileRead.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/Form.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/MenuBttn.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/MenuSprite.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/NumBible.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/TextDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/TreeDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/DolDoc/UnusedDefine.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Dsk/BlkDevRep.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Dsk/DataBase.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Dsk/DskRaw.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Dsk/FPrintF.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Dsk/SerializeTree.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Dsk/UnusedSpaceRep.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Exceptions.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/ExtChars.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/BattleLines.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/BigGuns.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/BlackDiamond.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/BomberGolf.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/CastleFrankenstein.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/CharDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/CircleTrace.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Collision.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Digits.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/DunGen.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/ElephantWalk.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/FlapBat.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/FlatTops.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Halogen.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/MassSpring.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Maze.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/RainDrops.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/RawHide.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Rocket.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/RocketScience.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Squirt.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Stadium/Stadium.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Stadium/StadiumBG.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Stadium/StadiumGen.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Talons.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/TheDead.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/TicTacToe.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/TreeCheckers.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Varoom.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Wenceslas.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Whap.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/Zing.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Games/ZoneOut.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/GlblVars.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/3DPoly.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/BSpline.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Balloon.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Blot.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Bounce.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Box.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Cartesian.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/CharAnimation.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Collision.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/CommonAncestor.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Doodle.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/EdSprite.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Elephant.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Extents.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/FontEd.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Grid.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Hanoi.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Lattice.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Life.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/LightTable.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Lines.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/LowPassFilter.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/MathAudioDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/MouseDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/NetOfDots.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Palette.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/PanText.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Pick.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Pick3D.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/PoleZeros.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/PredatorPrey.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/RotateTank.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/ScrnCapture.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/ScrollBars.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Shading.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Shadow.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Slider.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Speedline.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/SpritePlot.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/SpritePlot3D.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/SpritePut.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/SpritePutExt.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/SpriteRaw.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/SpriteText.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/SunMoon.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Symmetry.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/Transform.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/WallPaperCtrl.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/WallPaperFish.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Graphics/WinZBuf.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/InFile/InEd.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/InFile/InPopUp.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/InFile/InSetIP.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/KeyBitMap.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/LastClass.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/64BitAsmQuiz.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/AndNotMod.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/FixedPoint.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/FixedPointAdvanced.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/GraphicsCPULoad.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/InterruptDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/MiniCompiler.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/MiniGrLib.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/NegDisp.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/Optimization.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/PCIInterrupts.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/Ring3.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Lectures/ScrnMemory.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MagicPairs.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MemDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MsgLoop.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/Interrupts.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/LoadTest.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/Lock.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/MPAdd.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/MPPrint.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/MPRadix.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/Palindrome.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/MultiCore/Primes.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/NullCase.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/OnceDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/ParenWarn.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/PhoneNumWords.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Print.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Progress.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Prompt.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/PullDownMenu.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/RadixSort.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/RandDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/RegistryDemo.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/RevFileDemo/DemoPoemBwd.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/RevFileDemo/Rev.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/ScrnCodes.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Snd/ASCIIOrgan.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Snd/MorseCode.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Snd/OhGreat.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Snd/WaterFowl.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/SortFileDemo/F64FileGen.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/SortFileDemo/F64FileSort.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Spy.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/StkGrow.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/SubIntAccess.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/SubSwitch.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/SuggestSpelling.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Templates/Game1.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Templates/Lex1.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Templates/MultiCore1.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Templates/ODE1.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Templates/Registry1.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Templates/Util1.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/Templates/Util2.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/TimeIns.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/DemoInPage.DD.HTML create mode 100755 public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/WebLogDemo/WebLogRep.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/WebLogDemo/WebLogScramble.HC.HTML create mode 100755 public/Wb/Home/Src/Demo/WordSearch.HC.HTML create mode 100755 public/Wb/Home/Src/Doc/AboutTempleOS.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Asm.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/AutoComplete.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Bit.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/BlkChain.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Boot.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/CharOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Charter.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/CmdLineOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Comm.HC.HTML create mode 100755 public/Wb/Home/Src/Doc/CompilerOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Credits.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Ctrls.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Customize.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/CutCorners.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/D3.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Date.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/DbgFunSeg.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/DbgOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Define.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Demands.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/DemoIndex.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Directives.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/DolDoc.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/DolDocOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/EdPullDown.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/FAQ.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Features.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/FileLowLevel.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/FileMgr.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/FileMgrPullDown.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/FileUtils.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Frame.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/GRFiles.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Glossary.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/God.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/GraphicsOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/GuideLines.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Hash.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/HeapDbg.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/HelloWorld.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/HelpIndex.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/HelpSystem.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/HolyC.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/InFile.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Install.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Job.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/KeyAlloc.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/KeyDev.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Lex.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/MemOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Menus.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Mouse.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Msgs.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/MultiCore.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/NewASCII.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/ODE.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Once.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Options.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Pags.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/PreProcessor.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Print.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Profiler.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Que.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Quirks.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/RedSea.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Reliability.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Requirements.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Resource.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/ScopingLinkage.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Snd.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Sprite.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/SpriteBitMap.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/SpriteEd.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/SpriteEdText.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/SpriteMain.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/SpriteSideBar.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/StandBy.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Start.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/StdOutTask.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/StdTempleOSPC.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Strategy.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Streams.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/TOSZ.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/TextBase.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/TimeCycles.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/TimeDate.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/TimeHPET.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/TimeJiffy.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Tips.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Transform.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Welcome.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/WhyNotMore.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Widget.DD.HTML create mode 100755 public/Wb/Home/Src/Doc/Windows.DD.HTML create mode 100755 public/Wb/Home/Src/Downloads/TemplarLetters/TSheikhs/171207SerialPort.DD.HTML create mode 100755 public/Wb/Home/Src/Home/DoDistro.HC.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/AboutTempleOS.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Asm.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/AutoComplete.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Bit.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/BlkChain.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Boot.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/CharOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Charter.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/CmdLineOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Comm.HC.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/CompilerOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Credits.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Ctrls.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Customize.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/CutCorners.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/D3.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Date.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/DbgFunSeg.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/DbgOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Define.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Demands.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/DemoIndex.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Directives.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/DolDoc.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/DolDocOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/EdPullDown.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/FAQ.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Features.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/FileLowLevel.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/FileMgr.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/FileMgrPullDown.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/FileUtils.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Frame.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/GRFiles.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Glossary.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/God.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/GraphicsOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/GuideLines.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Hash.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/HeapDbg.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/HelloWorld.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/HelpIndex.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/HelpSystem.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/HolyC.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/InFile.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Install.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Job.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/KeyAlloc.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/KeyDev.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Lex.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/MemOverview.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Menus.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Mouse.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Msgs.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/MultiCore.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/NewASCII.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/ODE.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Once.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Options.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Pags.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/PreProcessor.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Print.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Profiler.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Que.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Quirks.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/RedSea.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Reliability.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Requirements.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Resource.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/ScopingLinkage.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Snd.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Sprite.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/SpriteBitMap.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/SpriteEd.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/SpriteEdText.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/SpriteMain.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/SpriteSideBar.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/StandBy.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Start.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/StdOutTask.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/StdTempleOSPC.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Strategy.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Streams.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/TOSZ.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/TextBase.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/TimeCycles.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/TimeDate.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/TimeHPET.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/TimeJiffy.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Tips.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Transform.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Welcome.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/WhyNotMore.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Widget.DD.HTML create mode 100755 public/Wb/Home/Src/Home/Doc/Windows.DD.HTML create mode 100755 public/Wb/Home/Src/Home/MakeHome.HC.HTML create mode 100755 public/Wb/Home/Src/Home/Registry.HC.HTML create mode 100755 public/Wb/Home/Src/HomeKeyPlugIns.HC.HTML create mode 100755 public/Wb/Home/Src/HomeLocalize.HC.HTML create mode 100755 public/Wb/Home/Src/HomeSys.HC.HTML create mode 100755 public/Wb/Home/Src/HomeWrappers.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskATA.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskATAId.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskAddDev.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskBlk.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskBlkDev.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskCDDVD.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskCFile.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskCache.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskClus.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskCopy.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskDirA.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskDirB.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskDirContext.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskDrv.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskFile.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskFind.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskFmt.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskStrA.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/DskStrB.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/FileSysFAT.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/FileSysRedSea.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/BlkDev/MakeBlkDev.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Compress.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Display.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/EdLite.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/FontCyrillic.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/FontStd.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/FunSeg.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Job.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KCfg.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KDataTypes.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KDate.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KDbg.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KDefine.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KExcept.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KExts.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KGlbls.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KHashA.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KHashB.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KInts.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KLoad.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KMain.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KMathA.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KMathB.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KMisc.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KStart16.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KStart32.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KStart64.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KTask.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KUtils.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/KernelA.HH.HTML create mode 100755 public/Wb/Home/Src/Kernel/KernelB.HH.HTML create mode 100755 public/Wb/Home/Src/Kernel/KernelC.HH.HTML create mode 100755 public/Wb/Home/Src/Kernel/KeyDev.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Mem/BlkPool.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Mem/HeapCtrl.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Mem/MAllocFree.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Mem/MakeMem.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Mem/MemPag.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Mem/MemPhysical.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Mem/PageTables.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/MultiProc.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/PCIBIOS.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/QSort.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/Sched.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/SerialDev/Keyboard.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/SerialDev/MakeSerialDev.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/SerialDev/Message.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/SerialDev/Mouse.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/StrA.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/StrB.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/StrPrint.HC.HTML create mode 100755 public/Wb/Home/Src/Kernel/StrScan.HC.HTML create mode 100755 public/Wb/Home/Src/MakeHome.HC.HTML create mode 100755 public/Wb/Home/Src/Misc/DoDistro.HC.HTML create mode 100755 public/Wb/Home/Src/Misc/OSInstall.HC.HTML create mode 100755 public/Wb/Home/Src/Misc/OSTestSuite.HC.HTML create mode 100755 public/Wb/Home/Src/Misc/PCIDevices.DD.HTML create mode 100755 public/Wb/Home/Src/Once.HC.HTML create mode 100755 public/Wb/Home/Src/PersonalMenu.DD.HTML create mode 100755 public/Wb/Home/Src/PersonalNotes.DD.HTML create mode 100755 public/Wb/Home/Src/StartOS.HC.HTML create mode 100755 public/Wb/HomeKeyPlugIns.HC.HTML create mode 100755 public/Wb/HomeLocalize.HC.HTML create mode 100755 public/Wb/HomeSys.HC.HTML create mode 100755 public/Wb/HomeWrappers.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskATA.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskATAId.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskAddDev.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskBlk.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskBlkDev.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskCDDVD.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskCFile.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskCache.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskClus.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskCopy.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskDirA.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskDirB.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskDirContext.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskDrv.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskFile.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskFind.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskFmt.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskStrA.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/DskStrB.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/FileSysFAT.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/FileSysRedSea.HC.HTML create mode 100755 public/Wb/Kernel/BlkDev/MakeBlkDev.HC.HTML create mode 100755 public/Wb/Kernel/Compress.HC.HTML create mode 100755 public/Wb/Kernel/Display.HC.HTML create mode 100755 public/Wb/Kernel/EdLite.HC.HTML create mode 100755 public/Wb/Kernel/FontCyrillic.HC.HTML create mode 100755 public/Wb/Kernel/FontStd.HC.HTML create mode 100755 public/Wb/Kernel/FunSeg.HC.HTML create mode 100755 public/Wb/Kernel/Job.HC.HTML create mode 100755 public/Wb/Kernel/KCfg.HC.HTML create mode 100755 public/Wb/Kernel/KDataTypes.HC.HTML create mode 100755 public/Wb/Kernel/KDate.HC.HTML create mode 100755 public/Wb/Kernel/KDbg.HC.HTML create mode 100755 public/Wb/Kernel/KDefine.HC.HTML create mode 100755 public/Wb/Kernel/KExcept.HC.HTML create mode 100755 public/Wb/Kernel/KExts.HC.HTML create mode 100755 public/Wb/Kernel/KGlbls.HC.HTML create mode 100755 public/Wb/Kernel/KHashA.HC.HTML create mode 100755 public/Wb/Kernel/KHashB.HC.HTML create mode 100755 public/Wb/Kernel/KInts.HC.HTML create mode 100755 public/Wb/Kernel/KLoad.HC.HTML create mode 100755 public/Wb/Kernel/KMain.HC.HTML create mode 100755 public/Wb/Kernel/KMathA.HC.HTML create mode 100755 public/Wb/Kernel/KMathB.HC.HTML create mode 100755 public/Wb/Kernel/KMisc.HC.HTML create mode 100755 public/Wb/Kernel/KStart16.HC.HTML create mode 100755 public/Wb/Kernel/KStart32.HC.HTML create mode 100755 public/Wb/Kernel/KStart64.HC.HTML create mode 100755 public/Wb/Kernel/KTask.HC.HTML create mode 100755 public/Wb/Kernel/KUtils.HC.HTML mode change 100644 => 100755 public/Wb/Kernel/KernelA.HH create mode 100755 public/Wb/Kernel/KernelA.HH.HTML mode change 100644 => 100755 public/Wb/Kernel/KernelB.HH create mode 100755 public/Wb/Kernel/KernelB.HH.HTML mode change 100644 => 100755 public/Wb/Kernel/KernelC.HH create mode 100755 public/Wb/Kernel/KernelC.HH.HTML create mode 100755 public/Wb/Kernel/KeyDev.HC.HTML create mode 100755 public/Wb/Kernel/Mem/BlkPool.HC.HTML create mode 100755 public/Wb/Kernel/Mem/HeapCtrl.HC.HTML create mode 100755 public/Wb/Kernel/Mem/MAllocFree.HC.HTML create mode 100755 public/Wb/Kernel/Mem/MakeMem.HC.HTML create mode 100755 public/Wb/Kernel/Mem/MemPag.HC.HTML create mode 100755 public/Wb/Kernel/Mem/MemPhysical.HC.HTML create mode 100755 public/Wb/Kernel/Mem/PageTables.HC.HTML create mode 100755 public/Wb/Kernel/MultiProc.HC.HTML create mode 100755 public/Wb/Kernel/PCIBIOS.HC.HTML create mode 100755 public/Wb/Kernel/QSort.HC.HTML create mode 100755 public/Wb/Kernel/Sched.HC.HTML create mode 100755 public/Wb/Kernel/SerialDev/Keyboard.HC.HTML create mode 100755 public/Wb/Kernel/SerialDev/MakeSerialDev.HC.HTML create mode 100755 public/Wb/Kernel/SerialDev/Message.HC.HTML create mode 100755 public/Wb/Kernel/SerialDev/Mouse.HC.HTML create mode 100755 public/Wb/Kernel/StrA.HC.HTML create mode 100755 public/Wb/Kernel/StrB.HC.HTML create mode 100755 public/Wb/Kernel/StrPrint.HC.HTML create mode 100755 public/Wb/Kernel/StrScan.HC.HTML create mode 100755 public/Wb/MakeHome.HC.HTML create mode 100755 public/Wb/Misc/DoDistro.HC.HTML create mode 100755 public/Wb/Misc/OSInstall.HC.HTML create mode 100755 public/Wb/Misc/OSTestSuite.HC.HTML create mode 100755 public/Wb/Once.HC.HTML create mode 100755 public/Wb/StartOS.HC.HTML diff --git a/Copy.HC b/Copy.HC index 1207b31..aaa35a1 100755 --- a/Copy.HC +++ b/Copy.HC @@ -4,11 +4,7 @@ U8 *FilenameToURL(U8 *filename, I64 line) { filename[StrLen(filename) - 2] = NULL; - U8 *htmlext = ""; - if (StrMatch(".DD", filename)) - htmlext = ".HTML"; - - return MStrPrint("/Wb%s%s#l%d", filename + 2, htmlext, line); + return MStrPrint("/Wb%s.HTML#l%d", filename + 2, line); } U8 *LinkCvt(U8 *link_st) @@ -56,7 +52,7 @@ CDirEntry *start_entry = FilesFind( CDirEntry *entry = start_entry; U8 *html_header = - "\n" + "\n" "\n" "\n" "\n" @@ -73,34 +69,26 @@ Del("C:/Home/Src", FALSE, TRUE); do { - U8 *new_name = MAlloc(2 * StrLen(entry->full_name)); + U8 *new_name = MAlloc(2 *StrLen(entry->full_name)); StrPrint(new_name, "/Home/Src%s", entry->full_name + 2); - if (StrMatch(".DD", entry->full_name)) { - FileExtRem(new_name); - CatPrint(new_name, ".DD.HTML"); - } else { - new_name[StrLen(new_name) - 2] = NULL; - } + new_name[StrLen(new_name) - 2] = NULL; + CatPrint(new_name, ".HTML"); - if (StrMatch(".DD", entry->full_name)) { - ToHtml( - entry->full_name, - new_name, - html_header, - body_header, - NULL, - NULL, - 80, - TRUE, - &LinkCvt, - ); + ToHtml( + entry->full_name, + new_name, + html_header, + body_header, + NULL, + NULL, + 80, + TRUE, + &LinkCvt, + ); + + Print("%s -> %s\n", entry->full_name, new_name); - Print("%s -> %s\n", entry->full_name, new_name); - } else { - Copy(entry->full_name, new_name); - } - } while (entry = entry->next); DirTreeDel(start_entry); diff --git a/file_index.xslt b/file_index.xslt index 8a70939..3598197 100644 --- a/file_index.xslt +++ b/file_index.xslt @@ -23,24 +23,31 @@ - + +
- - - + - +] + + + +
+
+ + + +] +
+
+
- -
diff --git a/public/Wb/Adam/ABlkDev/ADskA.HC.HTML b/public/Wb/Adam/ABlkDev/ADskA.HC.HTML new file mode 100755 index 0000000..9c2b216 --- /dev/null +++ b/public/Wb/Adam/ABlkDev/ADskA.HC.HTML @@ -0,0 +1,283 @@ + + + + + + + + + + + +
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+public U8 *DBlk(I64 blk,Bool write=FALSE)
+{//Dump disk block. Optionally, write.
+//If you set write to TRUE, the block will
+  //be written when you press <ESC>.
+  //See ::/Demo/Dsk/DskRaw.HC.
+  U8 *buf=MAlloc(BLK_SIZE);
+
+  BlkRead(Fs->cur_dv,buf,blk,1);
+  DocD(buf,BLK_SIZE);
+  if (write) {
+    "Edit and press <ESC> to write or <SHIFT-ESC>\n";
+    if (View) {
+      "Write\n";
+      BlkWrite(Fs->cur_dv,buf,blk,1);
+    }
+  }
+  return buf;
+}
+
+public U8 *DClus(I64 c,Bool write=FALSE,I64 num=0)
+{//Dump disk clus. Optionally, write.
+//If you set write to TRUE, the clus will
+  //be written when you press <ESC>.
+  //See ::/Demo/Dsk/DskRaw.HC.
+  //Do Dir("*",TRUE); to get clus numbers of files.
+  U8 *buf=MAlloc(Fs->cur_dv->spc<<BLK_SIZE_BITS);
+  c=ClusNumNext(Fs->cur_dv,c,num);
+  ClusRead(Fs->cur_dv,buf,c,1);
+  "Clus:%X\n",c;
+  DocD(buf,Fs->cur_dv->spc<<BLK_SIZE_BITS);
+  if (write) {
+    "Edit and press <ESC> to write or <SHIFT-ESC>\n";
+    if (View) {
+      "Write\n";
+      ClusWrite(Fs->cur_dv,buf,c,1);
+    }
+  }
+  return buf;
+}
+
+public U8 *Dump(U8 *filename,Bool write=FALSE)
+{//Dump file. Optionally, write.
+//If you set write to TRUE, the file will
+  //be written when you press <ESC>.
+  U8 *buf;
+  I64 size;
+  if (buf=FileRead(filename,&size)) {
+    DocD(buf,size);
+    if (write) {
+      "Edit and press <ESC> to write or <SHIFT-ESC>\n";
+      if (View) {
+        "Write\n";
+        FileWrite(filename,buf,size);
+      }
+    }
+  }
+  return buf;
+}
+
+public Bool Copy(U8 *src_files_find_mask,U8 *dst_files_find_mask=".")
+{//Copy files.
+//If the name ends in ".Z", it will
+  //be stored compressed.  If not ".Z"
+  //it will be stored uncompressed.
+  Bool res=TRUE;
+  CDirContext *dirc;
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st;
+  if (!(tmpde1=FilesFind(src_files_find_mask,FUF_CLUS_ORDER)))
+    return FALSE;
+  if (IsDir(dst_files_find_mask)) {
+    if (dirc=DirContextNew(dst_files_find_mask,TRUE)) {
+      tmpde=tmpde1;
+      while (tmpde) {
+        if (!(tmpde->attr & RS_ATTR_DIR)) {
+          st=FileNameAbs(tmpde->name);
+          if (!CopySingle(tmpde->full_name,st))
+            res=FALSE;
+          Free(st);
+        }
+        tmpde=tmpde->next;
+      }
+      DirContextDel(dirc);
+    }
+    DirTreeDel(tmpde1);
+    return res;
+  } else {
+    DirTreeDel(tmpde1);
+    return CopySingle(src_files_find_mask,dst_files_find_mask);
+  }
+}
+
+public Bool Move(U8 *f1,U8 *f2)
+{//Move files from one location to another or rename.
+  if (Copy(f1,f2)) {
+    Del(f1);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+I64 CopyTree2(CDirEntry *tmpde,I64 src_dir_len,I64 dst_dir_len,U8 *dst_dir)
+{
+  U8 *st;
+  I64 res=1;
+  while (tmpde) {
+    st=MAlloc(StrLen(tmpde->full_name)+dst_dir_len+2);
+    MemCpy(st,dst_dir,dst_dir_len);
+    StrCpy(st+dst_dir_len,tmpde->full_name+src_dir_len);
+    if (tmpde->attr & RS_ATTR_DIR) {
+      DirMk(st,LinkedLstCnt(tmpde->sub));
+      res+=CopyTree2(tmpde->sub,src_dir_len,dst_dir_len,dst_dir);
+    } else
+      if (CopySingle(tmpde->full_name,st))
+        res++;
+    Free(st);
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+public I64 CopyTree(U8 *src_files_find_mask,U8 *dst_files_find_mask,
+        Bool no_mask=TRUE)
+{//Copy directory tree.
+//Returns the count of copied files (not dirs).
+  CDirContext *dirc;
+  CDirEntry *tmpde=NULL;
+  I64 res=0,i1,i2;
+  U8 *st1,*st2;
+
+  st1=DirNameAbs(src_files_find_mask);
+  st2=DirNameAbs(dst_files_find_mask);
+  i1=StrLen(st1);
+  if (!StrNCmp(st1,st2,i1) && (st2[i1]=='/' || !st2[i1]) ) {
+    Free(st1);
+    Free(st2);
+    return 0;
+  }
+  Free(st1);
+  Free(st2);
+  if (dirc=DirContextNew(src_files_find_mask,TRUE,,no_mask)) {
+    tmpde=FilesFind(dirc->mask,FUF_RECURSE);
+    st1=DirCur;
+    DirContextDel(dirc);
+    i1=StrLen(st1);
+    if (i1==3) i1--;
+    if (dirc=DirContextNew(dst_files_find_mask,TRUE,TRUE)) {
+      st2=DirCur;
+      i2=StrLen(st2);
+      if (i2==3) i2--;
+      res=CopyTree2(tmpde,i1,i2,st2);
+      DirContextDel(dirc);
+      Free(st2);
+    }
+    DirTreeDel(tmpde);
+    Free(st1);
+  }
+  return res;
+}
+
+I64 DelTreeDirs(CDirEntry *tmpde1)
+{
+  I64 res=0;
+  CDirEntry *tmpde2;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR) {
+      if (tmpde1->sub)
+        res+=DelTreeDirs(tmpde1->sub);
+      res+=Del(tmpde1->full_name,TRUE,TRUE);
+    }
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return res;
+}
+I64 DelTreeFiles(CDirEntry *tmpde1)
+{
+  I64 res=0;
+  CDirEntry *tmpde2;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR) {
+      if (tmpde1->sub)
+        res+=DelTreeFiles(tmpde1->sub);
+    } else
+      res+=Del(tmpde1->full_name,FALSE,TRUE);
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return res;
+}
+public I64 DelTree(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Delete directory tree.
+  I64 res=0,fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (IsDir(files_find_mask)) {
+    res=DelTreeDirs(FilesFind(files_find_mask,fuf_flags));
+    res+=Del(files_find_mask,TRUE,TRUE);
+    res+=Del(files_find_mask,FALSE,TRUE);
+  } else
+    res=DelTreeFiles(FilesFind(files_find_mask,fuf_flags));
+  return res;
+}
+
+U0 TouchFile(U8 *filename,U8 *attr,CDate cdt=I64_MIN)
+{
+  CDrv *dv=Let2Drv(*filename);
+  CDirEntry de;
+  U8 *cur_dir=StrNew(filename),buf[STR_LEN];
+  if (FileFind(filename,&de,FUF_JUST_FILES)) {
+    Free(de.full_name);
+    if (!StrCmp(attr,"+?"))
+      "%-48ts %s\n",filename,StrPrintFlags(buf,Define("ST_FILE_ATTRS"),de.attr);
+    else {
+      StrFirstRem(cur_dir,":");
+      StrLastRem(cur_dir,"/");
+      if (!*cur_dir)
+        StrCpy(cur_dir,"/");
+      ScanFlags(&de.attr,Define("ST_FILE_ATTRS"),attr);
+      if (cdt==I64_MIN)
+        de.datetime=Now;
+      else
+        de.datetime=cdt;
+      DirNew(dv,cur_dir,&de,FALSE);
+    }
+  } else
+    PrintErr("File not found: \"%s\".\n",filename);
+  Free(cur_dir);
+}
+public U0 Touch(U8 *files_find_mask="*",U8 *attr="+?",
+        U8 *fu_flags=NULL,CDate cdt=I64_MIN)
+{/*Touch file attributes and DateTime.
+Default lists attributes.
+attr: "+?" =show current
+"+T" =resident
+RS_ATTR_READ_ONLY  ST_FILE_ATTRS
+To Set DateL:
+Touch(filename,"",,datetime);
+*/
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    TouchFile(tmpde->full_name,attr,cdt);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Adam/ABlkDev/ADskB.HC.HTML b/public/Wb/Adam/ABlkDev/ADskB.HC.HTML new file mode 100755 index 0000000..41c5b43 --- /dev/null +++ b/public/Wb/Adam/ABlkDev/ADskB.HC.HTML @@ -0,0 +1,222 @@ + + + + + + + + + + + +
+#help_index "File/Internal"
+I64 DirTreeSerializeSize(CDirEntry *tmpde)
+{
+  I64 res=0;
+  while (tmpde) {
+    res+=CDIR_SIZE+1;
+    if (tmpde->attr & RS_ATTR_DIR)
+      res+=DirTreeSerializeSize(tmpde->sub);
+    tmpde=tmpde->next;
+  }
+  return res+1;
+}
+I64 DirTreeSerializeFill(CDirEntry *tmpde,U8 *dst)
+{
+  I64 res=0,i;
+  while (tmpde) {
+    *dst++=1;
+    res++;
+    MemCpy(dst,&tmpde->start,CDIR_SIZE);
+    dst+=CDIR_SIZE;
+    res+=CDIR_SIZE;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      i=DirTreeSerializeFill(tmpde->sub,dst);
+      dst+=i;
+      res+=i;
+    }
+    tmpde=tmpde->next;
+  }
+  *dst=0;
+  return res+1;
+}
+public U8 *DirTreeSerialize(CDirEntry *tmpde,I64 *_size=NULL)
+{//Serialize tree returned from FilesFind() into a one contiguous U8 array.
+  I64 size=DirTreeSerializeSize(tmpde);
+  U8 *buf=MAlloc(size);
+  DirTreeSerializeFill(tmpde,buf);
+  if (_size) *_size=size;
+  return buf;
+}
+
+U8 *DirTreeUnserialize2(U8 *src,CDirEntry **tmpde)
+{
+  CDirEntry *tmpde1;
+  if (*src++) {
+    tmpde1=CAlloc(sizeof(CDirEntry));
+    *tmpde=tmpde1;
+    MemCpy(&tmpde1->start,src,CDIR_SIZE);
+    src+=CDIR_SIZE;
+    if (tmpde1->attr & RS_ATTR_DIR)
+      src=DirTreeUnserialize2(src,&tmpde1->sub);
+    src=DirTreeUnserialize2(src,&tmpde1->next);
+  } else
+    *tmpde=NULL;
+  return src;
+}
+public CDirEntry *DirTreeUnserialize(U8 *src)
+{//Unserialize tree to make it like a tree returned from FilesFind().
+  CDirEntry *tmpde=NULL;
+  DirTreeUnserialize2(src,&tmpde);
+  return tmpde;
+}
+
+#help_index "File/Program Routines"
+U0 FOFlatten(CDirEntry *tmpde,CDirEntry **a,I64 *i)
+{
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr&RS_ATTR_DIR) {
+      FOFlatten(tmpde->sub,a,i);
+      DirEntryDel(tmpde);
+    } else {
+      a[*i]=tmpde;
+      *i=*i+1;
+    }
+    tmpde=tmpde1;
+  }
+}
+
+I64 Size1(CDirEntry *tmpde,I64 *_fuf_flags,I64 round_to)
+{
+  U8 buf[BLK_SIZE];
+  I64 res=0,i;
+  CDrv *dv;
+  while (tmpde) {
+    if ((i=tmpde->size) && Bt(_fuf_flags,FUf_EXPAND) &&
+          !(tmpde->attr&RS_ATTR_DIR) &&
+          FileAttr(tmpde->name)&RS_ATTR_COMPRESSED) {
+      dv=Let2Drv(*tmpde->full_name);
+      BlkRead(dv,buf,Clus2Blk(dv,tmpde->clus),1);
+      i=(&buf)(CArcCompress *)->expanded_size;
+    }
+    if (round_to)
+      i=CeilU64(tmpde->size,round_to);
+    if (tmpde->attr&RS_ATTR_DIR)
+      i+=Size1(tmpde->sub,_fuf_flags,round_to);
+    tmpde->user_data=i;
+    res+=i;
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+public I64 Size(U8 *files_find_mask="/*",U8 *fu_flags=NULL,I64 round_to=0)
+{//Total size of files in mask. "+x" for expanded size.
+//Does not include directory size of base directory, but
+  //does include size of sub directories.
+  I64 fuf_flags=0,res=0;
+  CDirEntry *tmpde1=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND)) {
+    fuf_flags&=FUF_EXPAND;
+    res=Size1(tmpde1,&fuf_flags,round_to);
+    DirTreeDel(tmpde1);
+  }
+  return res;
+}
+
+public I64 FileCnt(CDirEntry *tmpde)
+{//Cnt of files in CDirEntry tree.
+  I64 cnt=0;
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR)
+      cnt+=FileCnt(tmpde->sub);
+    else
+      cnt++;
+    tmpde=tmpde->next;
+  }
+  return cnt;
+}
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+public I64 FF(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Files find. List files matching mask.
+  I64 cnt=0,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    PutFileLink(tmpde->full_name);
+    '\n';
+    cnt++;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return cnt;
+}
+
+public I64 Zip(U8 *files_find_mask="*",U8 *fu_flags=NULL)
+{//Compress files by moving to .Z filename.
+  U8 *st;
+  CDirEntry *tmpde,*tmpde1;
+  I64 res=0,fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (!IsDotZ(tmpde->full_name)) {
+      st=MStrPrint("%s.Z",tmpde->full_name);
+      res+=Move(tmpde->full_name,st);
+      Free(st);
+    }
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return res;
+}
+
+public I64 Unzip(U8 *files_find_mask="*.Z",U8 *fu_flags=NULL)
+{//Uncompress files by moving to not .Z filename.
+//You don't have to do this for normal operation.
+  //It automatically unzips ".Z" files.
+  U8 *st;
+  CDirEntry *tmpde,*tmpde1;
+  I64 res=0,fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (IsDotZ(tmpde->full_name)) {
+      st=StrNew(tmpde->full_name);
+      StrLastRem(st,".");
+      res+=Move(tmpde->full_name,st);
+      Free(st);
+    }
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/ABlkDev/DskChk.HC.HTML b/public/Wb/Adam/ABlkDev/DskChk.HC.HTML new file mode 100755 index 0000000..5a57f79 --- /dev/null +++ b/public/Wb/Adam/ABlkDev/DskChk.HC.HTML @@ -0,0 +1,475 @@ + + + + + + + + + + + +
+#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)"
+Bool ChkDskConfirm(Bool *_fix,Bool *_confirm)
+{
+  if (*_fix && *_confirm) {
+    "Fix ";
+    if (!YorN)
+      *_fix=FALSE;
+    *_confirm=FALSE;
+  }
+  return *_fix;
+}
+
+I64 RedSeaChkDskLst(CDrv *dv,CDirEntry *tmpde1,
+        U8 *bits,U8 *bits2,I64 size,I64 bpc)
+{
+  CDirEntry *tmpde2;
+  I64 i,j,errs=0;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)
+      errs+=RedSeaChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);
+    j=(tmpde1->size+bpc-1)/bpc;
+    for (i=0;i<j;i++) {
+      if (i+tmpde1->clus-dv->data_area>size) {
+        PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,
+              i+tmpde1->clus);
+        errs++;
+        break;
+      }
+      if (LBts(bits,i+tmpde1->clus-dv->data_area)) {
+        PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,
+              i+tmpde1->clus);
+        errs++;
+      }
+      if (!LBtr(bits2,i+tmpde1->clus-dv->data_area)) {
+        PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,
+              i+tmpde1->clus);
+        errs++;
+      }
+    }
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return errs;
+}
+
+I64 RedSeaChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
+{
+  I64 i,j,bpc,size,errs=0;
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),
+        *old_dir=StrNew(Fs->cur_dir),
+        *bits,*bits2;
+  CDirEntry *ptr,*ptr2;
+
+  Drv(drv_let);
+  "Scanning...\n";
+  size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;
+  bpc=dv->spc<<BLK_SIZE_BITS;
+  bits=CAlloc((size+7)>>3);
+  bits2=CAlloc((size+7)>>3+BLK_SIZE);
+  BlkRead(dv,bits2,dv->fat1,((size+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS);
+
+  //Get Root Dir size
+  ptr2=MAlloc(bpc);
+  BlkRead(dv,ptr2,dv->root_clus,1);
+  ptr=ptr2(U8 *)-offset(CDirEntry.start);
+  j=(ptr->size+bpc-1)/bpc;
+  Free(ptr2);
+
+  for (i=0;i<j;i++) {
+    if (i+dv->root_clus-dv->data_area>size) {
+      PrintErr("Invalid Clus: RootDir Clus:%X\n",i+dv->root_clus);
+      errs++;
+      break;
+    }
+    if (LBts(bits,i+dv->root_clus-dv->data_area)) {
+      PrintErr("Dbl Alloc: RootDir Clus:%X\n",i+dv->root_clus);
+      errs++;
+    }
+    if (!LBtr(bits2,i+dv->root_clus-dv->data_area)) {
+      PrintErr("UnAlloc: RootDir Clus:%X\n",i+dv->root_clus);
+      errs++;
+    }
+  }
+
+  errs+=RedSeaChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),
+        bits,bits2,size,bpc);
+  for (i=1;i<size;i++)
+    if (Bt(bits2,i)) {
+      PrintWarn("Shouldn't Alloc Clus:%0X\n",i+dv->data_area);
+      errs++;
+      if (ChkDskConfirm(_fix,_confirm))
+        RedSeaFreeClus(dv,i+dv->data_area,1);
+    }
+
+  Free(files_find_mask);
+  Free(bits);
+  Free(bits2);
+  Drv(Drv2Let(old_dv));
+  Cd(old_dir);
+  Free(old_dir);
+  return errs;
+}
+
+I64 FAT32ChkDskLst(CDrv *dv,CDirEntry *tmpde1,
+        U8 *bits,U32 *bits2,I64 size,I64 bpc)
+{
+  CDirEntry *tmpde2;
+  I64 i,c,errs=0;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)
+      errs+=FAT32ChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);
+    i=0;
+    c=tmpde1->clus;
+    while (0<c<0x0FFFFFF8) {
+      if (c>size) {
+        PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,c);
+        errs++;
+        break;
+      }
+      if (LBts(bits,c)) {
+        PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,c);
+        errs++;
+      }
+      if (!bits2[c]) {
+        PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,c);
+        errs++;
+      } else
+        bits2[c]=0;
+      c=ClusNumNext(dv,c);
+      i++;
+    }
+    if (!(tmpde1->attr & RS_ATTR_DIR)) {
+      i*=bpc;
+      if (tmpde1->size>i) {
+        PrintErr("Alloced File Too Short:%s\n",tmpde1->full_name);
+        errs++;
+      }
+      if (i>tmpde1->size+bpc-1) {
+        PrintWarn("Alloced File Too Long:%s\n",tmpde1->full_name);
+        errs++;
+      }
+    }
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return errs;
+}
+
+I64 FAT32ChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
+{
+  I64 i,bpc,size,c,errs=0;
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),
+        *old_dir=StrNew(Fs->cur_dir),
+        *bits;
+  U32 *bits2;
+  Drv(drv_let);
+  "Scanning...\n";
+  size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;
+  bpc=dv->spc<<BLK_SIZE_BITS;
+  bits=CAlloc((size+7)>>3);
+  bits2=CAlloc(size*4+BLK_SIZE);
+  BlkRead(dv,bits2,dv->fat1,(size*4+BLK_SIZE-1)>>BLK_SIZE_BITS);
+
+  c=dv->root_clus;
+  while (0<c<0x0FFFFFF8) {
+    if (c>size) {
+      PrintErr("Invalid Clus: RootDir Clus:%X\n",c);
+      errs++;
+      break;
+    }
+    if (LBts(bits,c)) {
+      PrintErr("Dbl Alloc: RootDir Clus:%X\n",c);
+      errs++;
+    }
+    if (!bits2[c]) {
+      PrintErr("UnAlloc: RootDir Clus:%X\n",c);
+      errs++;
+    } else
+      bits2[c]=0;
+    c=ClusNumNext(dv,c);
+  }
+
+  errs+=FAT32ChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),
+        bits,bits2,size,bpc);
+
+  bits2[1]=0; //See FAT32Fmt()
+  for (i=1;i<size;i++)
+    if (bits2[i]) {
+      PrintWarn("Shouldn't Alloc Clus:%0X\n",i);
+      errs++;
+      if (ChkDskConfirm(_fix,_confirm))
+        FAT32FreeClus(dv,i);
+    }
+  Free(files_find_mask);
+  Free(bits);
+  Free(bits2);
+  Drv(Drv2Let(old_dv));
+  Cd(old_dir);
+  Free(old_dir);
+  return errs;
+}
+
+public I64 DskChk(U8 drv_let=0,Bool fix=FALSE,Bool confirm=TRUE)
+{//Check disk for allocation errors and, optionally, fix.
+//You probably want to reformat and reinstall.
+  I64 errs=0;
+  CDrv *dv=Let2Drv(drv_let);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      errs=RedSeaChkDsk(drv_let,&fix,&confirm);
+      break;
+    case FSt_FAT32:
+      errs=FAT32ChkDsk(drv_let,&fix,&confirm);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+  if (errs) {
+    if (fix)
+      "It might be a little better.  ";
+    "Copy files to another partition or CD/DVD, "
+          "reformat, and copy back.  "
+          "Or, copy from a back-up.\n";
+  }
+  return errs;
+}
+
+U0 RedSeaDrvView(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
+        s=dv->size+dv->drv_offset-dv->data_area;
+  U8 *bitmap;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  WinMax;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DCFill;
+  try {
+    i=((s+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    i=0;
+    for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {
+      if (ScanKey)
+        break;
+      for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {
+        lohi=i*s;
+        c1=lohi/l;
+        if (Bt(bitmap,c1))
+          dc->color=ROP_XOR+BLUE^TRANSPARENT;
+        else
+          dc->color=ROP_XOR+WHITE^TRANSPARENT;
+        GrPlot(dc,x,y);
+        i++;
+      }
+    }
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  GetChar;
+
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+}
+U0 FAT32DrvView(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
+        s=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);
+  U32 *bitmap;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  WinMax;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DCFill;
+  try {
+    i=(s*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    i=0;
+    for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {
+      if (ScanKey)
+        break;
+      for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {
+        lohi=i*s;
+        c1=lohi/l;
+        if (bitmap[c1])
+          dc->color=ROP_XOR+BLUE^TRANSPARENT;
+        else
+          dc->color=ROP_XOR+WHITE^TRANSPARENT;
+        GrPlot(dc,x,y);
+        i++;
+      }
+    }
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  GetChar;
+
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+}
+public U0 DrvView(U8 drv_let=0)
+{//Drive view. Graph the allocation map's fragmentation.
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  Drv(drv_let);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      RedSeaDrvView(drv_let);
+      break;
+    case FSt_FAT32:
+      FAT32DrvView(drv_let);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+  Drv(Drv2Let(old_dv));
+}
+
+public U0 DskView(U8 drv_let=0)
+{//Disk view. Pie chart of partition sizes.
+  I64 i,j,attr,
+        h=Fs->pix_width,
+        v=Fs->pix_height,
+        radius;
+  CDrv *dv;
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  CDC *dc=DCAlias;
+  F64 sect_start,sect_end;
+
+  SettingsPush; //See SettingsPush
+  DocCursor;
+  DocClear;
+  DCFill;
+  if (h<v)
+    radius=0.4*h;
+  else
+    radius=0.4*v;
+  dc->color=BLACK;
+  GrCircle(dc,h>>1,v>>1,radius);
+
+  j=1;
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (bd==dv->bd && dv->fs_type) {
+      sect_start=-(dv->drv_offset*2*pi/(bd->max_blk+1));
+      sect_end  =-((dv->drv_offset+dv->size)*2*pi/(bd->max_blk+1));
+      dc->color=BLACK;
+      GrLine(dc,h>>1,v>>1,
+            h>>1+radius*Cos(sect_start),
+            v>>1+radius*Sin(sect_start));
+      GrLine(dc,h>>1,v>>1,
+            h>>1+radius*Cos(sect_end),
+            v>>1+radius*Sin(sect_end));
+
+      attr=DrvTextAttrGet(Drv2Let(dv));
+      dc->color=attr&15;
+      GrPrint(dc,0,v-FONT_HEIGHT*j,"%C %-8Z",Drv2Let(dv),
+            dv->fs_type,"ST_DRV_TYPES");
+      dc->color.c1=attr>>4;
+      dc->color|=ROPF_DITHER;
+      GrFloodFill(dc,
+            h>>1+(radius-4)*Cos((sect_start+sect_end)/2),
+            v>>1+(radius-4)*Sin((sect_start+sect_end)/2),FALSE);
+      j++;
+    }
+  }
+
+  GetChar(,FALSE);
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+}
+
+I64 RedSeaUnusedDrvSpace(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 res=0,i,l;
+  U8 *bitmap;
+  try {
+    l=dv->size+dv->drv_offset-dv->data_area;
+    i=((l+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    for (i=0;i<l;i++)
+      if (!Bt(bitmap,i))
+        res++;
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  return res*BLK_SIZE*dv->spc;
+}
+I64 FAT32UnusedDrvSpace(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 res=0,i,l;
+  U32 *bitmap;
+  try {
+    l=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);
+    i=(l*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    for (i=0;i<l;i++)
+      if (!bitmap[i])
+        res++;
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  return res*BLK_SIZE*dv->spc;
+}
+public I64 DrvUnused(U8 drv_let=0)
+{//Returns unused size in bytes.
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  U8 *old_dir=StrNew(Fs->cur_dir);
+  I64 res=0;
+  Drv(drv_let);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      res=RedSeaUnusedDrvSpace(drv_let);
+      break;
+    case FSt_FAT32:
+      res=FAT32UnusedDrvSpace(drv_let);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+  Drv(Drv2Let(old_dv));
+  Cd(old_dir);
+  Free(old_dir);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/ABlkDev/DskPrt.HC.HTML b/public/Wb/Adam/ABlkDev/DskPrt.HC.HTML new file mode 100755 index 0000000..18154e5 --- /dev/null +++ b/public/Wb/Adam/ABlkDev/DskPrt.HC.HTML @@ -0,0 +1,198 @@ + + + + + + + + + + + +
+#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically)"
+
+#define ROUND_DRV_TO    (63*255)
+#define DRV_HEADER      63
+
+class CPlannedDrv
+{
+  CPlannedDrv *next,*last;
+  I64 size;
+  Bool pri;
+};
+
+public I64 DskPrt(U8 drv_let=0,...)
+{/*Partition the disk containing partition drv_let.
+
+drv_let=0 means add new drive that is not already mounted.
+
+>DskPrt('C',0.5,0.25,0.25); //Make three.  50% C, 25% D, 25% E, round-up to blk.
+
+*/
+  CBlkDev *bd;
+  CPlannedDrv head,*tmppp;
+  CMasterBoot mbr;
+  Bool pri=TRUE;
+  I64 ext_base,drv_let2,pri_cnt=0,i,start_offset,offset,
+        total,remaining,cur_arg=0;
+  "This command does not play well\n"
+        "with other operating systems.\n"
+        "You really should use another\n"
+        "operating system's partitioner.\n"
+        "If you use this, it may, in fact,\n"
+        "make your hard drive impossible\n"
+        "to repartition with other operating\n"
+        "until you set block zero to zero\n"
+        "with $LK,\"BootMHDZero\",\"MN:BootMHDZero\"$()\n\n\n"
+        "Continue";
+  if (argc<=cur_arg && !YorN)
+    return 0;
+  '\n';
+
+  if (drv_let && !Let2BlkDev(drv_let,FALSE))
+    drv_let=0;
+  if (!drv_let && !(drv_let=Mount(TRUE)) ||
+        !(bd=Let2BlkDev(drv_let,FALSE)) || bd->type!=BDT_ATA)
+    return 0;
+
+  total=bd->max_blk+1;
+  QueInit(&head);
+  drv_let2=bd->first_drv_let;
+  remaining=FloorU64(bd->max_blk+1,ROUND_DRV_TO);
+  while (FloorU64(remaining,ROUND_DRV_TO)>=ROUND_DRV_TO) {
+    tmppp=MAlloc(sizeof(CPlannedDrv));
+    do {
+      "$RED$Partition %C$FG$\n",drv_let2;
+      tmppp->pri=FALSE;
+      if (pri) {
+        "Primary Partition";
+        if (argc>cur_arg || YorN) {
+          pri_cnt++;
+          tmppp->pri=TRUE;
+          if (pri_cnt==3)
+            pri=FALSE;
+        } else
+          pri=FALSE;
+      }
+      "\nBlocks Remaining:%d (0x%X)\n",
+            remaining-DRV_HEADER,remaining-DRV_HEADER;
+      if (argc>cur_arg)
+        tmppp->size=MinI64(CeilU64(MaxI64(remaining,DRV_HEADER),ROUND_DRV_TO),
+              CeilU64(argv[cur_arg++](F64)*total,ROUND_DRV_TO));
+      else
+        tmppp->size=CeilU64(GetI64("Size in Blocks  :",
+              remaining-DRV_HEADER)+DRV_HEADER,ROUND_DRV_TO);
+    } while (!(ROUND_DRV_TO<=tmppp->size<=FloorU64(remaining,ROUND_DRV_TO)));
+    QueIns(tmppp,head.last);
+    remaining-=tmppp->size;
+    drv_let2++;
+  }
+
+  "\n\n!!! Repartition Drive !!!\n\n";
+  tmppp=head.next;
+  drv_let2=bd->first_drv_let;
+  while (tmppp!=&head) {
+    "Drive %C:%08X ",drv_let2,tmppp->size;
+    if (tmppp->pri)
+      "Primary\n";
+    else
+      "Logical\n";
+    tmppp=tmppp->next;
+    drv_let2++;
+  }
+  if (!argc && !AreYouSure)
+    goto pd_done;
+
+  remaining=FloorU64(bd->max_blk+1,ROUND_DRV_TO)-ROUND_DRV_TO;
+  tmppp=head.next;
+  MemSet(&mbr,0,BLK_SIZE);
+  mbr.signature=0xAA55;
+  offset=0;
+  for (i=0;i<pri_cnt;i++) {
+    mbr.p[i].active=0x80;
+    mbr.p[i].start_head=0;
+    mbr.p[i].start_cyl=0x101;
+    mbr.p[i].type=1; //Will get set different.
+    mbr.p[i].end_head=0xFE;
+    mbr.p[i].end_cyl=0xFFFF;
+    mbr.p[i].offset=DRV_HEADER+offset;
+    mbr.p[i].size=tmppp->size-DRV_HEADER;
+    offset+=tmppp->size;
+    remaining-=tmppp->size;
+    tmppp=tmppp->next;
+  }
+  if (!i) i++;
+  if (tmppp!=&head) {
+    mbr.p[i].active=0x80;
+    mbr.p[i].start_head=0;
+    mbr.p[i].start_cyl=0x101;
+    mbr.p[i].type=0xF;
+    mbr.p[i].end_head=0xFE;
+    mbr.p[i].end_cyl=0xFFFF;
+    mbr.p[i].offset=offset;
+    mbr.p[i].size=remaining;
+    ext_base=offset;
+  }
+  ATAWriteBlks(bd,&mbr,0,1);
+
+  while (tmppp!=&head) {
+    start_offset=offset;
+    MemSet(&mbr,0,BLK_SIZE);
+    mbr.signature=0xAA55;
+
+    mbr.p[0].active=0x80;
+    mbr.p[0].start_head=1;
+    mbr.p[0].start_cyl=0x101;
+    mbr.p[0].type=1; //Will get set different.
+    mbr.p[0].end_head=0xFE;
+    mbr.p[0].end_cyl=0xFFFF;
+    mbr.p[0].offset=DRV_HEADER;
+    mbr.p[0].size=tmppp->size-DRV_HEADER;
+    offset+=tmppp->size;
+    tmppp=tmppp->next;
+    if (tmppp!=&head) {
+      mbr.p[1].active=0x80;
+      mbr.p[1].start_head=0;
+      mbr.p[1].start_cyl=0x101;
+      mbr.p[1].type=5;
+      mbr.p[1].end_head=0xFE;
+      mbr.p[1].end_cyl=0xFFFF;
+      mbr.p[1].offset=offset-ext_base;
+      mbr.p[1].size=tmppp->size;
+    }
+    ATAWriteBlks(bd,&mbr,start_offset,1);
+  }
+
+  bd->flags&=~(BDF_INITIALIZED | BDF_INIT_IN_PROGRESS);
+  BlkDevAdd(bd,,FALSE,TRUE);
+  for (i=bd->first_drv_let;i<drv_let2;i++)
+    Fmt(i,,FALSE);
+
+    pd_done:
+  while (head.next!=&head) {
+    tmppp=head.next;
+    QueRem(tmppp);
+    Free(tmppp);
+  }
+  return total;
+}
+
+ diff --git a/public/Wb/Adam/ABlkDev/FileMgr.HC.HTML b/public/Wb/Adam/ABlkDev/FileMgr.HC.HTML new file mode 100755 index 0000000..e760778 --- /dev/null +++ b/public/Wb/Adam/ABlkDev/FileMgr.HC.HTML @@ -0,0 +1,822 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+U0 DirFileDoc(CDoc *doc,CDirEntry *tmpde)
+{
+  while (tmpde) {
+    if (tmpde->attr & RS_ATTR_DIR) {
+      tmpde->user_data=DocPrint(doc,"$TR,\"%s\",U=0x%X$",tmpde->name,tmpde);
+      DocPrint(doc,"\n$ID,+2$");
+      if (tmpde->sub)
+        DirFileDoc(doc,tmpde->sub);
+      DocPrint(doc,"$ID,-2$");
+    } else {
+      tmpde->user_data=DocPrint(doc,"$MU,\"%s\",U=0x%X$",tmpde->name,tmpde);
+      DocPrint(doc,"\n");
+    }
+    tmpde=tmpde->next;
+  }
+}
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+
+#define FM_NORMAL       0
+#define FM_PICK_FILE    1
+#define FM_PICK_DIR     2
+
+class CFMUncollapsedLst
+{
+  CFMUncollapsedLst *next;
+  U8 *name;
+};
+
+CFMUncollapsedLst *FMCollectUncollapsedLst(CDoc *doc)
+{
+  CDocEntry *doc_e=doc->head.next;
+  CFMUncollapsedLst *res=NULL,*tmpc;
+  CDirEntry *tmpde;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TREE) {
+      if (!(doc_e->de_flags&DOCEF_CHECKED_COLLAPSED)) {
+        if (tmpde=doc_e->user_data) {
+          tmpc=MAlloc(sizeof(CFMUncollapsedLst));
+          tmpc->next=res;
+          res=tmpc;
+          tmpc->name=StrNew(tmpde->full_name);
+        }
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  return res;
+}
+
+U0 FMMarkUncollapsed(CDoc *doc,CFMUncollapsedLst *tmpc,
+        U8 *cur_entry,U8 *next_entry)
+{
+  CDocEntry *doc_e=doc->head.next;
+  CFMUncollapsedLst *tmpc1;
+  CDirEntry *tmpde;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TREE) {
+      tmpde=doc_e->user_data;
+      tmpc1=tmpc;
+      while (tmpc1) {
+        if (!StrCmp(tmpc1->name,tmpde->full_name)) {
+          doc_e->de_flags&=~DOCEF_CHECKED_COLLAPSED;
+          break;
+        }
+        tmpc1=tmpc1->next;
+      }
+      if (cur_entry) {
+        if (!StrNCmp(cur_entry,tmpde->full_name,StrLen(tmpde->full_name))) {
+          doc->cur_entry=doc_e;
+          if (StrLen(tmpde->full_name)==StrLen(cur_entry))
+            cur_entry=NULL;
+        } else if (next_entry) {
+          if (!StrNCmp(next_entry,
+                tmpde->full_name,StrLen(tmpde->full_name))) {
+            doc->cur_entry=doc_e;
+            if (StrLen(tmpde->full_name)==StrLen(next_entry))
+              cur_entry=NULL;
+          }
+        }
+      }
+    } else if (doc_e->type_u8==DOCT_MENU_VAL) {
+      tmpde=doc_e->user_data;
+      if (cur_entry) {
+        if (!StrNCmp(cur_entry,tmpde->full_name,StrLen(tmpde->full_name))) {
+          doc->cur_entry=doc_e;
+          if (StrLen(tmpde->full_name)==StrLen(cur_entry))
+            cur_entry=NULL;
+        } else if (next_entry) {
+          if (!StrNCmp(next_entry,
+                tmpde->full_name,StrLen(tmpde->full_name))) {
+            doc->cur_entry=doc_e;
+            if (StrLen(tmpde->full_name)==StrLen(next_entry))
+              cur_entry=NULL;
+          }
+        }
+      }
+    }
+    doc_e=doc_e->next;
+  }
+}
+
+U0 FMDelUncollapsedLst(CFMUncollapsedLst *tmpc)
+{
+  CFMUncollapsedLst *tmpc1;
+  while (tmpc) {
+    tmpc1=tmpc->next;
+    Free(tmpc->name);
+    Free(tmpc);
+    tmpc=tmpc1;
+  }
+}
+
+CDirEntry *FMRebuildDocDrv(U8 drv_let,CDoc *doc,CDirEntry **_head,Bool init)
+{
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st;
+  tmpde=CAlloc(sizeof(CDirEntry));
+  tmpde->full_name=MStrPrint("%C:/",drv_let);
+  tmpde->attr=RS_ATTR_DIR;
+  st=MStrPrint("%c:/*",drv_let);
+  if (init)
+    tmpde->sub=tmpde1=FilesFind(st,FUF_RECURSE);
+  else
+    tmpde1=NULL;
+  Free(st);
+  tmpde->user_data=DocPrint(doc,"$TR,\"%s\",U=0x%X$",tmpde->full_name,tmpde);
+  tmpde->next=*_head;
+  *_head=tmpde;
+  DocPrint(doc,"\n$ID,+2$");
+  DocBottom(doc);
+  if (init) {
+    DirFileDoc(doc,tmpde1);
+    while (tmpde1) {
+      tmpde1->parent=tmpde;
+      tmpde1=tmpde1->next;
+    }
+  }
+  DocPrint(doc,"$ID,-2$");
+  return tmpde;
+}
+
+#define DEF2_PROCESSED          1
+#define DEF2_NOT_INITIALIZED    2
+
+U0 FMRebuildDoc(CDoc **_doc,CDirEntry **_head,I64 mode)
+{
+  CDrv *dv;
+  I64 i;
+  CDoc *doc=*_doc,*doc2=sys_clip_doc,*parent_doc;
+  CFMUncollapsedLst *tmpc=NULL;
+  U8 *cur_entry=NULL,*next_entry=NULL;
+  CDocEntry *doc_ce;
+  CDirEntry *tmpde,*tmpde1,*cur_tree_entry;
+  if (!doc)
+    parent_doc=DocPut;
+  else {
+    parent_doc=doc->parent_doc;
+    Fs->put_doc=Fs->display_doc=NULL;
+    DocUnlock(doc);
+    Refresh;
+    DocLock(doc);
+    cur_tree_entry=NULL;
+    doc_ce=doc->cur_entry;
+    if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+      cur_tree_entry=doc_ce->user_data;
+    if (cur_tree_entry)
+      cur_entry=StrNew(cur_tree_entry->full_name);
+    tmpde=NULL;
+    if (doc_ce!=doc)
+      doc_ce=doc_ce->next;
+    while (doc_ce!=doc) {
+      if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+        tmpde=doc_ce->user_data;
+      else
+        tmpde=NULL;
+      if (tmpde) {
+        tmpde1=tmpde->parent;
+        while (tmpde1) {
+          if (tmpde1==cur_tree_entry) {
+            tmpde=NULL;
+            break;
+          } else
+            tmpde1=tmpde1->parent;
+        }
+        if (tmpde)
+          break;
+      }
+      doc_ce=doc_ce->next;
+    }
+    if (tmpde)
+      next_entry=StrNew(tmpde->full_name);
+
+    tmpc=FMCollectUncollapsedLst(doc);
+    DocDel(doc);
+  }
+  if (*_head) {
+    DirTreeDel(*_head);
+    *_head=NULL;
+  }
+  doc=DocNew;
+  doc->desc='FileMan';
+  doc->parent_doc=parent_doc;
+  doc->flags|=DOCF_FORM;
+  switch (mode) {
+    case FM_NORMAL:
+      DocPrint(doc,"$PURPLE$File Manager\n\n"
+            "$LK,\"Click for Help\",A=\"FI:::/Doc/FileMgr.DD\"$\n\n");
+      break;
+    case FM_PICK_FILE:
+      DocPrint(doc,"$PURPLE$Pick file and press <ESC>\n\n");
+      doc->flags|=DOCF_SIZE_MIN;
+      break;
+    case FM_PICK_DIR:
+      DocPrint(doc,"$PURPLE$Pick directory and press <ESC>\n\n");
+      doc->flags|=DOCF_SIZE_MIN;
+      break;
+  }
+  DocPrint(doc,"$LTBLUE$");
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (dv->bd->type==BDT_ATAPI) {
+      if (dv->bd->flags&BDF_INITIALIZED)
+        tmpde=FMRebuildDocDrv(Drv2Let(dv),doc,_head,TRUE);
+      else {
+        tmpde=FMRebuildDocDrv(Drv2Let(dv),doc,_head,FALSE);
+        tmpde->user_data2|=DEF2_NOT_INITIALIZED;
+      }
+    } else if (dv->fs_type==FSt_REDSEA || dv->fs_type==FSt_FAT32)
+      FMRebuildDocDrv(Drv2Let(dv),doc,_head,TRUE);
+  }
+  DocTop(doc);
+  FMMarkUncollapsed(doc,tmpc,cur_entry,next_entry);
+  DocCenter(doc);
+  DocRst(doc2,TRUE);
+  FMDelUncollapsedLst(tmpc);
+  Free(cur_entry);
+  Free(next_entry);
+  *_doc=doc;
+  DocLock(doc);
+  Fs->put_doc=Fs->display_doc=doc;
+}
+
+U0 FMRename(CDoc *doc)
+{
+  CEdFileName fn;
+  CDocEntry *doc_e=doc->cur_entry;
+  CDirEntry *tmpde=NULL,*parent;
+  if (doc_e->type_u8==DOCT_MENU_VAL) {
+    tmpde=doc_e->user_data;
+    if (parent=tmpde->parent) {
+      Cd(parent->full_name);
+      StrCpy(fn.name,tmpde->name);
+      if (DocForm(&fn)) {
+        Silent;
+        Move(tmpde->name,fn.name);
+        Silent(OFF);
+      }
+    }
+  } else if (doc_e->type_u8==DOCT_TREE) {
+    tmpde=doc_e->user_data;
+    if (parent=tmpde->parent) {
+      Cd(parent->full_name);
+      StrCpy(fn.name,tmpde->name);
+      if (DocForm(&fn)) {
+        if (StrCmp(tmpde->name,fn.name)) {
+          Silent;
+          if (CopyTree(tmpde->name,fn.name))
+            DelTree(tmpde->name);
+          Silent(OFF);
+        }
+      }
+    }
+  }
+}
+
+U0 FMMkDir(CDoc *doc)
+{
+  CEdFileName fn;
+  CDocEntry *doc_e=doc->cur_entry;
+  CDirEntry *tmpde=NULL,*parent;
+  *fn.name=0;
+  if (doc_e->type_u8==DOCT_MENU_VAL) {
+    tmpde=doc_e->user_data;
+    if (parent=tmpde->parent) {
+      Cd(parent->full_name);
+      if (DocForm(&fn)) {
+        Silent;
+        DirMk(fn.name);
+        Silent(OFF);
+      }
+    }
+  } else if (doc_e->type_u8==DOCT_TREE) {
+    tmpde=doc_e->user_data;
+    Cd(tmpde->full_name);
+    if (DocForm(&fn)) {
+      Silent;
+      DirMk(fn.name);
+      Silent(OFF);
+    }
+  }
+}
+
+U0 FMDelete(CDoc *doc)
+{
+  U8 *st;
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_MENU_VAL) {
+    tmpde=doc_ce->user_data;
+    Silent;
+    st=MStrPrint("Delete: %s",tmpde->full_name);
+    if (PopUpCancelOk(st))
+      Del(tmpde->full_name);
+    Free(st);
+    Silent(OFF);
+  } else if (doc_ce->type_u8==DOCT_TREE) {
+    tmpde=doc_ce->user_data;
+    Silent;
+    st=MStrPrint("Delete: %s",tmpde->full_name);
+    if (PopUpCancelOk(st))
+      DelTree(tmpde->full_name);
+    Free(st);
+    Silent(OFF);
+  }
+}
+
+U0 FMChgDsk(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    Silent;
+    DskChg(*tmpde->full_name);
+    Silent(OFF);
+  }
+}
+
+U0 FMMountISO(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_MENU_VAL && (tmpde=doc_ce->user_data))
+    MountFile(tmpde->full_name);
+}
+
+U0 FMUnmount(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  I64 drv_let;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    drv_let=*tmpde->full_name;
+    if (Let2BlkDev(drv_let)!=Let2BlkDev(':'))
+      Unmount(drv_let);
+  }
+}
+
+U0 FMFmtDrv(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  U8 *st=NULL;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    st=MStrPrint("Format Drive '%c'?\nAre You Sure?\n",*tmpde->full_name);
+    if (PopUpCancelOk(st)) {
+      Silent;
+      Fmt(*tmpde->full_name,,FALSE);
+      Silent(OFF);
+    }
+  }
+  Free(st);
+}
+
+U0 FMMakeISO(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    if (doc_ce->type_u8==DOCT_MENU_VAL)
+      tmpde=tmpde->parent;
+    if (tmpde && *tmpde->full_name) {
+      Silent;
+      RedSeaISO(,tmpde->full_name);
+      Silent(OFF);
+    }
+  }
+}
+
+U0 FMBurnISO(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    Silent;
+    DVDImageWrite(*tmpde->full_name);
+    Silent(OFF);
+  }
+}
+
+U0 FMCopy(CDoc *doc)
+{
+  CDoc *doc2=sys_clip_doc;
+  U8 *st;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e;
+  CDirEntry *tmpde,*tmpde1=NULL,*tmpde2;
+  Bool unlock_doc2=DocLock(doc2);
+  doc_e=doc2->head.next;
+
+  tmpde1=doc_ce->user_data;
+  if (doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde1=tmpde1->parent;
+  else if (doc_ce->type_u8!=DOCT_TREE)
+    tmpde1=NULL;
+  if (tmpde1) {
+    while (doc_e!=doc2) {
+      if (doc_e->type_u8==DOCT_MENU_VAL) {
+        tmpde=doc_e->user_data;
+        tmpde->user_data2|=DEF2_PROCESSED;
+        tmpde2=tmpde->parent;
+        if (!tmpde2 || !(tmpde2->user_data2&DEF2_PROCESSED)) {
+          Silent;
+          Copy(tmpde->full_name,tmpde1->full_name);
+          Silent(OFF);
+        }
+      } else if (doc_e->type_u8==DOCT_TREE) {
+        tmpde=doc_e->user_data;
+        tmpde->user_data2|=DEF2_PROCESSED;
+        tmpde2=tmpde->parent;
+        if (!tmpde2 || !(tmpde2->user_data2&DEF2_PROCESSED)) {
+          Silent;
+          if (*tmpde1->name)
+            st=MStrPrint("%s/%s",tmpde1->full_name,tmpde->name);
+          else
+            st=MStrPrint("%s%s",tmpde1->full_name,tmpde->name);
+          CopyTree(tmpde->full_name,st);
+          Free(st);
+          Silent(OFF);
+        }
+      }
+      doc_e=doc_e->next;
+    }
+  }
+  if (unlock_doc2)
+    DocUnlock(doc2);
+}
+
+#define FMR_INCLUDE             0
+#define FMR_ADAM_INCLUDE        1
+#define FMR_DELETE              2
+#define FMR_RENAME              3
+#define FMR_MKDIR               4
+#define FMR_PLAIN               5
+#define FMR_PASTE               6
+#define FMR_CHG_DSK             7
+#define FMR_FORMAT              8
+#define FMR_MOUNT_REDSEA_ISO_C  9
+#define FMR_UNMOUNT             10
+#define FMR_MAKE_REDSEA_ISO_C   11
+#define FMR_BURN_ISO            12
+#define FMR_HELP                13
+
+I64 PopUpFMRight(U8 *header=NULL,U8 *footer=NULL)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"$CM+LX,1,1 $$BT,\"INCLUDE                 \",LE=FMR_INCLUDE$"
+        "$CM+LX,29,0$$BT,\"ADAM INCLUDE            \",LE=FMR_ADAM_INCLUDE$"
+        "$CM+LX,1,3 $$BT,\"DELETE                  \",LE=FMR_DELETE$"
+        "$CM+LX,29,0$$BT,\"RENAME                  \",LE=FMR_RENAME$"
+        "$CM+LX,1,3 $$BT,\"MAKE DIRECTORY          \",LE=FMR_MKDIR$"
+        "$CM+LX,29,0$$BT,\"PLAIN-TEXT EDIT         \",LE=FMR_PLAIN$"
+        "$CM+LX,1,3 $$BT,\"PASTE CLIP FILES        \",LE=FMR_PASTE$"
+        "$CM+LX,29,0$$BT,\"CHANGE DISK(MOUNT IT)   \",LE=FMR_CHG_DSK$"
+        "$CM+LX,1,3 $$BT,\"FORMAT                  \",LE=FMR_FORMAT$"
+        "$CM+LX,1,3 $$BT,\"MOUNT ISO.C FILE        \","
+        "LE=FMR_MOUNT_REDSEA_ISO_C$"
+        "$CM+LX,29,0$$BT,\"UNMOUNT                 \",LE=FMR_UNMOUNT$"
+        "$CM+LX,1,3 $$BT,\"MAKE ISO.C (CD/DVD) FILE\",LE=FMR_MAKE_REDSEA_ISO_C$"
+        "$CM+LX,29,0$$BT,\"BURN ISO (CD/DVD) FILE  \",LE=FMR_BURN_ISO$"
+        "$CM+LX,1,3 $$BT,\"HELP                    \",LE=FMR_HELP$"
+        "$CM+LX,29,0$$BT,\"CANCEL                  \",LE=DOCM_CANCEL$\n");
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+U0 FMRightClick()
+{
+  switch (PopUpFMRight) {
+    case FMR_INCLUDE:
+      Msg(MSG_KEY_DOWN,0,0x3F0000003F);
+      break;
+    case FMR_ADAM_INCLUDE:
+      Msg(MSG_KEY_DOWN,0,0x23F0000023F);
+      break;
+    case FMR_DELETE:
+      Msg(MSG_KEY_DOWN,CH_CTRLY,0);
+      break;
+    case FMR_RENAME:
+      Msg(MSG_KEY_DOWN,'r',0);
+      break;
+    case FMR_MKDIR:
+      Msg(MSG_KEY_DOWN,'d',0);
+      break;
+    case FMR_PLAIN:
+      Msg(MSG_KEY_DOWN,CH_SHIFT_SPACE,0);
+      break;
+    case FMR_PASTE:
+      Msg(MSG_KEY_DOWN,0,SC_INS+SCF_SHIFT);
+      break;
+    case FMR_CHG_DSK:
+      Msg(MSG_KEY_DOWN,'c',0);
+      break;
+    case FMR_FORMAT:
+      Msg(MSG_KEY_DOWN,'f',0);
+      break;
+    case FMR_MOUNT_REDSEA_ISO_C:
+      Msg(MSG_KEY_DOWN,'i',0);
+      break;
+    case FMR_UNMOUNT:
+      Msg(MSG_KEY_DOWN,'u',0);
+      break;
+    case FMR_MAKE_REDSEA_ISO_C:
+      Msg(MSG_KEY_DOWN,'m',0);
+      break;
+    case FMR_BURN_ISO:
+      Msg(MSG_KEY_DOWN,'B',0);
+      break;
+    case FMR_HELP:
+      Msg(MSG_KEY_DOWN,CH_CTRLM,0x43200000432);
+      break;
+  }
+}
+
+U8 *fm_ms_str=NULL;
+U0 (*fp_old_final_scrn_update)(CDC *dc);
+
+U0 FMFinalScrnUpdate(CDC *dc)
+{
+  if (fm_ms_str) {
+    dc->color=LTRED;
+    GrPrint(dc,ms.pos.x,ms.pos.y,"%s",fm_ms_str);
+  }
+  (*fp_old_final_scrn_update)(dc);
+}
+
+public U8 *FileMgr(I64 mode=FM_NORMAL,CTask *mem_task=NULL)
+{//File manager. Also, used to choose files and dirs.
+  CDirEntry *head=NULL,*tmpde,*tmpde1,*tmpde2;
+  I64 sc,ch,arg1,arg2,msg_code;
+  CDoc *doc=NULL,*old_put_doc=DocPut,*old_display_doc=DocDisplay;
+  U8 *res=NULL,*st,*st2,*old_cur_dir=DirCur;
+  CDocEntry *doc_ce=NULL,*doc_e;
+  Bool okay;
+
+  SettingsPush; //See SettingsPush
+  fp_old_final_scrn_update=gr.fp_final_scrn_update;
+  MenuFilePush("::/Doc/FileMgrPullDown.DD");
+  FMRebuildDoc(&doc,&head,mode);
+  if (tmpde1=Cd2DirEntry(head,old_cur_dir))
+    doc->cur_entry=tmpde1->user_data;
+  while (tmpde1) {
+    if (tmpde1->attr&RS_ATTR_DIR)
+      tmpde1->user_data(CDocEntry *)->de_flags&=~DOCEF_CHECKED_COLLAPSED;
+    tmpde1=tmpde1->parent;
+  }
+  do {
+    DocUnlock(doc);
+    do msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_UP);
+    while (Fs!=sys_focus_task);
+    DocLock(doc);
+    switch (msg_code) {
+      case MSG_MS_R_UP:
+        DocUnlock(doc);
+        FMRightClick;
+        DocLock(doc);
+        break;
+      case MSG_MS_L_DOWN:
+        doc_ce=doc->cur_entry;
+        fm_ms_str=doc_ce->tag;
+        gr.fp_final_scrn_update=&FMFinalScrnUpdate;
+        break;
+      case MSG_MS_L_UP:
+        if (doc_ce) {
+          gr.fp_final_scrn_update=fp_old_final_scrn_update;
+          if (WinCursorPosSet(Fs,arg1+Fs->pix_left+Fs->scroll_x,
+                arg2+Fs->pix_top+Fs->scroll_y,TRUE)) {
+            doc_e=doc->cur_entry;
+            if (doc_e!=doc_ce) {
+              st2=NULL;
+              if (doc_e->type_u8==DOCT_MENU_VAL) {
+                tmpde1=doc_e->user_data;
+                if (tmpde1=tmpde1->parent)
+                  st2=StrNew(tmpde1->full_name);
+              } else if (doc_e->type_u8==DOCT_TREE) {
+                tmpde1=doc_e->user_data;
+                st2=StrNew(tmpde1->full_name);
+              }
+              if (st2 && doc_ce->type_u8==DOCT_MENU_VAL) {
+                tmpde=doc_ce->user_data;
+                Silent;
+                Move(tmpde->full_name,st2);
+                Silent(OFF);
+                FMRebuildDoc(&doc,&head,mode);
+              } else if (st2 && doc_ce->type_u8==DOCT_TREE) {
+                tmpde=doc_ce->user_data;
+                okay=TRUE;
+                tmpde2=tmpde1;
+                while (tmpde2) {
+                  if (tmpde2!=tmpde)
+                    tmpde2=tmpde2->parent;
+                  else {
+                    okay=FALSE;
+                    break;
+                  }
+                }
+                if (okay) {
+                  if (*tmpde1->name)
+                    st=MStrPrint("%s/%s",tmpde1->full_name,tmpde->name);
+                  else
+                    st=MStrPrint("%s%s",tmpde1->full_name,tmpde->name);
+                  if (StrCmp(tmpde->full_name,st)) {
+                    Silent;
+                    CopyTree(tmpde->full_name,st);
+                    DelTree(tmpde->full_name);
+                    Silent(OFF);
+                    FMRebuildDoc(&doc,&head,mode);
+                  }
+                  Free(st);
+                }
+              }
+              Free(st2);
+              FlushMsgs;
+            } else
+              if (doc_e->type_u8==DOCT_MENU_VAL) {
+                DocUnlock(doc);
+                Ed(doc_e->user_data(CDirEntry *)->full_name);
+                DocLock(doc);
+              }
+            doc_ce=NULL;
+          }
+        }
+        break;
+      case MSG_KEY_DOWN:
+        doc_ce=NULL;
+        ch=arg1; sc=arg2;
+        if (sc.u8[0]==SC_DELETE && !(sc&(SCF_SHIFT|SCF_CTRL)))
+          ch=CH_CTRLY;
+        if (ch && sc&SCF_ALT) goto fm_regular_key;
+        switch (ch) {
+          case '\n':
+            DocUnlock(doc);
+            FMRightClick;
+            DocLock(doc);
+            break;
+          start:
+            DocUnlock(doc);
+            case CH_CTRLV:
+              FMCopy(doc);
+              break;
+            case 'r':
+              FMRename(doc);
+              break;
+            case 'd':
+              FMMkDir(doc);
+              break;
+            case CH_CTRLY:
+              FMDelete(doc);
+              break;
+            case 'c':
+              FMChgDsk(doc);
+              break;
+            case 'i':
+              FMMountISO(doc);
+              break;
+            case 'u':
+              FMUnmount(doc);
+              break;
+            case 'm':
+              FMMakeISO(doc);
+              break;
+            case 'B':
+              FMBurnISO(doc);
+              break;
+            case 'f':
+              FMFmtDrv(doc);
+              break;
+          end:
+            FMRebuildDoc(&doc,&head,mode);
+            break;
+          case CH_SHIFT_ESC:
+            break;
+          case CH_SPACE:
+            if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
+              DocUnlock(doc);
+              Ed(doc->cur_entry->user_data(CDirEntry *)->full_name);
+              DocLock(doc);
+            } else
+              goto fm_regular_key;
+            break;
+          case CH_SHIFT_SPACE:
+            if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
+              DocUnlock(doc);
+              Plain(doc->cur_entry->user_data(CDirEntry *)->full_name);
+              DocLock(doc);
+            } else
+              goto fm_regular_key;
+            break;
+          case CH_ESC:
+            doc_ce=doc->cur_entry;
+            tmpde=doc_ce->user_data;
+            if (mode==FM_PICK_FILE && doc_ce->type_u8==DOCT_MENU_VAL)
+              res=StrNew(tmpde->full_name,mem_task);
+            else if (mode==FM_PICK_DIR) {
+              if (doc_ce->type_u8==DOCT_TREE)
+                res=StrNew(tmpde->full_name,mem_task);
+              else if (doc_ce->type_u8==DOCT_MENU_VAL &&
+                    (tmpde=tmpde->parent))
+                res=StrNew(tmpde->full_name,mem_task);
+            }
+            break;
+          default:
+            if (sc.u8[0]==SC_INS && sc&SCF_SHIFT && !(sc&SCF_CTRL)) {
+              FMCopy(doc);
+              FMRebuildDoc(&doc,&head,mode);
+            } else if (sc.u8[0]==SC_F5) {
+              if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
+                tmpde=doc->cur_entry->user_data;
+                DocUnlock(doc);
+                if (sc&SCF_SHIFT)
+                  AdamFile(tmpde->full_name);
+                else
+                  PopUpFile(tmpde->full_name);
+                DocLock(doc);
+              }
+            } else {
+fm_regular_key:
+              DocUnlock(doc);
+              PutKey(ch,sc);
+              DocLock(doc);
+            }
+        }
+        break;
+    }
+  } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  gr.fp_final_scrn_update=fp_old_final_scrn_update;
+  Fs->put_doc    =old_put_doc;
+  Fs->display_doc=old_display_doc;
+  SettingsPop;
+  DocDel(doc);
+  DirTreeDel(head);
+  Cd(old_cur_dir);
+  Free(old_cur_dir);
+  if (mode!=FM_NORMAL && !res)
+    res=StrNew("",mem_task);
+  MenuPop;
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/ABlkDev/MakeABlkDev.HC.HTML b/public/Wb/Adam/ABlkDev/MakeABlkDev.HC.HTML new file mode 100755 index 0000000..399fdde --- /dev/null +++ b/public/Wb/Adam/ABlkDev/MakeABlkDev.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "ADskA"
+#include "ADskB"
+#include "DskPrt"
+#include "Mount"
+#include "DskChk"
+#include "FileMgr"
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/ABlkDev/Mount.HC.HTML b/public/Wb/Adam/ABlkDev/Mount.HC.HTML new file mode 100755 index 0000000..34d6cb2 --- /dev/null +++ b/public/Wb/Adam/ABlkDev/Mount.HC.HTML @@ -0,0 +1,190 @@ + + + + + + + + + + + +
+#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
+U8 Mount2(U8 boot_drv_let,CDoc *_doc,Bool _caller_is_prtdsk)
+{//If _doc, called by ::/Kernel/KCfg.HC else called by Mount().
+  I64 cnt,total=0,num_hints,drv_let,type,unit,prt_num;
+  U8 blks_buf[STR_LEN],addr_buf[STR_LEN],base0_buf[STR_LEN],base1_buf[STR_LEN],
+        *filename=NULL,*filename2=NULL,res=0;
+  CATARep *head=NULL,*tmpha;
+  Bool whole_drv,make_free;
+  CDoc *doc;
+  if (boot_drv_let)
+    boot_drv_let=Let2Let(boot_drv_let);
+  do {
+    cnt=0;
+    if (!_doc)
+      DrvRep;
+    "\n****** Mount Drives ******\n"
+          "$GREEN$A$FG$-$GREEN$B$FG$ are RAM drives.\n"
+          "$GREEN$C$FG$-$GREEN$L$FG$ are ATA hard drives.\n"
+          "$GREEN$M$FG$-$GREEN$P$FG$ are ISO file read drives.\n"
+          "$GREEN$Q$FG$-$GREEN$S$FG$ are ISO file write drives.\n"
+          "$GREEN$T$FG$-$GREEN$Z$FG$ are ATAPI CD/DVD drives.\n"
+          "\nDrive Letter ($PURPLE$<ENTER>$FG$ to exit):";
+    drv_let=Let2Let(GetChar);
+    '\n';
+    if (type=Let2BlkDevType(drv_let)) {
+      whole_drv=FALSE;
+      if (_doc) { //Called by ::/Kernel/KCfg.HC
+        doc=_doc;
+        make_free=FALSE;
+      } else { //Called by Mount()
+        doc=DocNew;
+        DocPrint(doc,"CBlkDev *bd;\n");
+        make_free=TRUE;
+      }
+      unit=0;
+      prt_num=I64_MIN;
+      switch (type) {
+        case BDT_RAM:
+          "Addr of RAM disk ($PURPLE$<ENTER>$FG$ to MAlloc):";
+          GetS(addr_buf,STR_LEN);
+        case BDT_ISO_FILE_WRITE:
+          "Blks of 512 bytes:";
+          GetS(blks_buf,STR_LEN);
+          break;
+        case BDT_ISO_FILE_READ:
+          filename=GetStr("File Name:");
+          break;
+        case BDT_ATA:
+          prt_num=GetI64("Partition Num (Default=All):",prt_num);
+        case BDT_ATAPI:
+          num_hints=ATARep(,,&head);
+          if (type==BDT_ATAPI && boot_drv_let)
+            "<ENTER> to use booted CD/DVD\n"; //Only ::/Kernel/KCfg.HC
+          do {
+            if (num_hints)
+              "Enter dev number or\nport with $PURPLE$0x$FG$ prefix.\n"
+                    "I/O Port Base0:\n";
+            else
+              "Include $PURPLE$0x$FG$ prefix.\nI/O Port Base0:\n";
+            GetS(base0_buf,STR_LEN);
+          } while (!Str2I64(base0_buf) && (type!=BDT_ATAPI || !boot_drv_let));
+          if (1<=Str2I64(base0_buf)<=num_hints) {
+            tmpha=ATARepFind(head,Str2I64(base0_buf));
+            StrPrint(base0_buf,"0x%X",tmpha->base0);
+            StrPrint(base1_buf,"0x%X",tmpha->base1);
+            unit=tmpha->unit;
+          } else if (type!=BDT_ATAPI || *base0_buf) {
+            if (type==BDT_ATAPI)
+              StrCpy(base1_buf,"0");
+            else
+              do {
+                "I/O Port Base1:\n";
+                GetS(base1_buf,STR_LEN);
+              } while (!Str2I64(base1_buf));
+            do {
+              "\t$PURPLE$0$FG$=Master\n\t$PURPLE$1$FG$=Slave\nUnit:";
+              unit=GetChar-'0';
+            } while (!(0<=unit<=1));
+            '\n';
+          }
+          LinkedLstDel(head);
+          break;
+      }
+      DocPrint(doc,"bd=BlkDevNextFreeSlot(\'%C\',%d);bd->unit=%d;\n",
+            drv_let,type,unit);
+      switch (type) {
+        case BDT_RAM:
+          if (!*addr_buf) StrCpy(addr_buf,"0");
+          DocPrint(doc,"bd->RAM_dsk=%s;\n",addr_buf);
+        case BDT_ISO_FILE_WRITE:
+          if (!*blks_buf) StrCpy(blks_buf,"0");
+          DocPrint(doc,"bd->max_blk=(%s)-1;\n",blks_buf);
+          DocPrint(doc,"bd->drv_offset=19<<2+"
+                "(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
+          break;
+        case BDT_ISO_FILE_READ:
+          filename2=FileNameAbs(filename);
+          DocPrint(doc,"bd->file_dsk_name=AStrNew(\"%s\");\n",filename2);
+          DocPrint(doc,"bd->drv_offset=19<<2+"
+                "(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
+          break;
+        case BDT_ATA:
+        case BDT_ATAPI:
+          if (type==BDT_ATAPI && !*base0_buf) {
+            DocPrint(doc,"GetBaseUnit(bd);\n"); //Only ::/Kernel/KCfg.HC
+            if (drv_let==boot_drv_let)
+              make_free=TRUE;
+          } else
+            DocPrint(doc,"bd->base0=%s;bd->base1=%s;\n",base0_buf,base1_buf);
+          if (type==BDT_ATA && _caller_is_prtdsk) {
+            "\nReformat WHOLE drive!";
+            whole_drv=YorN;
+          }
+          break;
+      }
+      DocPrint(doc,"BlkDevAdd(bd,%d,%d,%d);\n",prt_num,whole_drv,make_free);
+      if (_doc) //Called by ::/Kernel/KCfg.HC
+        cnt++;
+      else { //Called by Mount()
+        if ((cnt=ExeDoc(doc)) && whole_drv) {
+          if (_caller_is_prtdsk) {
+            res=drv_let;
+            DskPrt(drv_let,1.0); //First mount whole drive.
+          } else
+            DskPrt(drv_let);
+        }
+        DocDel(doc);
+      }
+    }
+    total+=cnt;
+  } while (cnt && !_caller_is_prtdsk ||
+        !total && _doc); //At least 1 if Called by ::/Kernel/KCfg.HC
+  Free(filename);
+  Free(filename2);
+  return res;
+}
+
+public U8 Mount(Bool caller_is_prtdsk=FALSE)
+{//Mount drives. Called from DskPrt(Mount).
+  return Mount2(0,NULL,caller_is_prtdsk);
+}
+
+public U0 Unmount(U8 drv_let=0)
+{//Unmount drive(s).
+  BlkDevDel(Let2BlkDev(drv_let));
+}
+
+public U8 MountFile(U8 *filename)
+{//Mount ISO.C file.
+  U8 *filename2=ExtDft(filename,"ISO.C"),*filename3=FileNameAbs(filename2);
+  CDrv *dv=DrvMakeFreeSlot(DrvNextFreeLet('M')); //First BDT_ISO_FILE_READ
+  CBlkDev *bd=BlkDevNextFreeSlot(dv->drv_let,BDT_ISO_FILE_READ);
+  bd->drv_offset=19<<2+(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
+  bd->file_dsk_name=AStrNew(filename3);
+  BlkDevAdd(bd,,TRUE,TRUE);
+  Free(filename3);
+  Free(filename2);
+  return dv->drv_let;
+}
+
+ diff --git a/public/Wb/Adam/ADbg.HC.HTML b/public/Wb/Adam/ADbg.HC.HTML new file mode 100755 index 0000000..e388230 --- /dev/null +++ b/public/Wb/Adam/ADbg.HC.HTML @@ -0,0 +1,301 @@ + + + + + + + + + + + +
+#help_index "Debugging/Dump"
+Bool ClassRep2(CDoc *doc,U8 *_d,U8 *class_name=lastclass,
+        I64 depth,I64 max_depth,Bool dynamic,I64 types=HTT_CLASS,I64 offset=0)
+{//See ::/Demo/LastClass.HC.
+  I64 i,j,stars,*ptr;
+  CMemberLst *ml;
+  CDocEntry *doc_e;
+  Bool unlock;
+  CHashClass *tmpc,*tmpc2;
+  if (depth>=max_depth) return TRUE;
+  if (!(tmpc=HashFind(class_name,Fs->hash_table,types))) {
+    DocPrint(doc,"Class Not Found.\n");
+    return FALSE;
+  }
+  if (!ChkPtr(_d) || !ChkPtr(_d(U8 *)+tmpc->size)) {
+    DocPrint(doc,"Bad Ptr:%016X\n",_d);
+    return FALSE;
+  }
+  if (tmpc->base_class && !ClassRep2(doc,_d,tmpc->base_class->str,
+        depth,max_depth,dynamic,types,offset))
+    return FALSE;
+  unlock=DocLock(doc);
+  DocPrint(doc,"Class:\"%s\"\n",class_name);
+  ml=tmpc->member_lst_and_root;
+  while (ml) {
+    tmpc2=ml->member_class;
+    ptr=_d(U8 *)+ml->offset;
+    DocPrint(doc,"%08X ",ptr(U8 *)+offset);
+    stars=tmpc2->ptr_stars_cnt;
+    tmpc2=OptClassFwd(tmpc2);
+    tmpc2-=tmpc2->ptr_stars_cnt;
+    if (tmpc2->type & HTT_INTERNAL_TYPE) {
+      DocPrint(doc,"$GREEN$%-20ts:$FG$",ml->str);
+      if (stars==1 && (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8)) {
+        ptr=*ptr;
+        if (ChkPtr(ptr)) {
+          if (dynamic) {
+            doc_e=DocPrint(doc,"$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$\n");
+            doc_e->data=ptr;
+            DocDataFmt(doc,doc_e);
+          } else
+            DocPrint(doc,"%40ts\n",ptr);
+        }
+      } else if (!stars) {
+        j=MinI64(ml->dim.total_cnt,32);
+        if (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8) {
+          if (j==1) {
+            if (dynamic) {
+              doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U8,A=\"%%c\"$\n");
+              doc_e->data=ptr;
+            } else
+              DocPrint(doc,"%c\n",*ptr(U8 *));
+          } else {
+            if (dynamic) {
+              doc_e=DocPrint(doc,"$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$\n");
+              doc_e->data=ptr;
+              DocDataFmt(doc,doc_e);
+            } else
+              DocPrint(doc,"%40ts\n",ptr);
+          }
+        }
+        for (i=0;i<j;i++) {
+          switch (tmpc2->raw_type) {
+            case RT_I0:
+            case RT_U0:
+              break;
+            case RT_I8:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I8,A=\"%%02X\"$ ");
+                doc_e->data=ptr(I8 *)++;
+              } else
+                DocPrint(doc,"%02X ",*ptr(I8 *)++);
+              break;
+            case RT_U8:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U8,A=\"%%02X\"$ ");
+                doc_e->data=ptr(U8 *)++;
+              } else
+                DocPrint(doc,"%02X ",*ptr(U8 *)++);
+              break;
+            case RT_I16:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I16,A=\"%%04X\"$ ");
+                doc_e->data=ptr(I16 *)++;
+              } else
+                DocPrint(doc,"%04X ",*ptr(I16 *)++);
+              break;
+            case RT_U16:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U16,A=\"%%04X\"$ ");
+                doc_e->data=ptr(U16 *)++;
+              } else
+                DocPrint(doc,"%04X ",*ptr(U16 *)++);
+              break;
+            case RT_I32:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I32,A=\"%%08X\"$ ");
+                doc_e->data=ptr(I32 *)++;
+              } else
+                DocPrint(doc,"%08X ",*ptr(I32 *)++);
+              break;
+            case RT_U32:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U32,A=\"%%08X\"$ ");
+                doc_e->data=ptr(U32 *)++;
+              } else
+                DocPrint(doc,"%08X ",*ptr(U32 *)++);
+              break;
+            case RT_U64:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U64,A=\"%%08X\"$ ");
+                doc_e->data=ptr(U64 *)++;
+              } else
+                DocPrint(doc,"%08X ",*ptr(U64 *)++);
+              break;
+            case RT_F64:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=F64,A=\"%%16g\"$ ");
+                doc_e->data=ptr(F64 *)++;
+              } else
+                DocPrint(doc,"%16g ",*ptr(I64 *)++);
+              break;
+            default:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,A=\"%%016X\"$ ");
+                doc_e->data=ptr(I64 *)++;
+              } else
+                DocPrint(doc,"%016X ",*ptr(I64 *)++);
+          }
+          if (dynamic)
+            DocDataFmt(doc,doc_e);
+        }
+        if (j<ml->dim.total_cnt)
+          DocPrint(doc,"...");
+      } else
+        DocPrint(doc,"%016X",*ptr);
+      DocPrint(doc,"\n");
+    } else {
+      if (depth<2) {
+        if (stars==1 && !ChkPtr(*ptr))
+          DocPrint(doc,"%-20ts:%016X\n",ml->str,*ptr);
+        else {
+          DocPrint(doc,"$TR,\"%s\"$\n",ml->str);
+          DocPrint(doc,"$ID,2$");
+          if (!stars)
+            ClassRep2(doc,ptr,tmpc2->str,depth+1,max_depth,dynamic);
+          else if (stars==1)
+            ClassRep2(doc,*ptr,tmpc2->str,depth+1,max_depth,dynamic);
+          DocPrint(doc,"$ID,-2$");
+        }
+      } else
+        DocPrint(doc,"%-20ts\n",ml->str);
+    }
+    ml=ml->next;
+  }
+  if (unlock)
+    DocUnlock(doc);
+  return TRUE;
+}
+
+public U0 ClassRep(U8 *_d,U8 *class_name=lastclass,
+        I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
+{//Displays members of a record by using the compiler's info.
+  CDoc *doc;
+  if (IsRaw)
+    doc=DocNew;
+  else {
+    DocMax;
+    doc=DocPut;
+  }
+  if (fun)
+    ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_FUN,offset);
+  else
+    ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_CLASS,offset);
+  DocPrint(doc,"\n");
+  DocRecalc(doc);
+  if (IsRaw) {
+    DocDump(doc,100000);
+    DocDel(doc);
+  }
+}
+
+public U0 ClassRepD(U8 *_d,U8 *class_name=lastclass,
+        I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
+{//Dynamic ClassRep. Uses hex_ed widgit for live changes.
+  CDoc *doc;
+  if (IsRaw)
+    doc=DocNew;
+  else {
+    DocMax;
+    doc=DocPut;
+  }
+  if (fun)
+    ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_FUN,offset);
+  else
+    ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_CLASS,offset);
+  DocPrint(doc,"\n");
+  DocRecalc(doc);
+  if (IsRaw) {
+    DocDump(doc,100000);
+    DocDel(doc);
+  }
+}
+
+U0 UpdateRegVarImg(CHashFun *tmpf,U8 *_b,CTask *task)
+{
+  CMemberLst *ml;
+  CHashClass *tmpc;
+  ml=tmpf->member_lst_and_root;
+  while (ml) {
+    if (ml->reg!=REG_NONE) {
+      tmpc=OptClassFwd(ml->member_class);
+      MemCpy(_b+ml->offset,TaskRegAddr(task,ml->reg),tmpc->size);
+    }
+    ml=ml->next;
+  }
+}
+
+public U0 FunRep(U8 *st,U8 *rbp=NULL,I64 max_depth=2,CTask *task=NULL)
+{//Shows names and vals of a fun's local vars using compiler's info.
+  I64 size;
+  U8 *img;
+  CHashFun *tmpf=HashFind(st,Fs->hash_table,HTT_FUN);
+  CMemberLst *tmpm;
+  if (tmpf) {
+    if (rbp) {
+      if (task) {
+//tmpf->size is negative.  It's the bottom
+        //of the fun local var space relative to RBP .
+        size=tmpf->arg_cnt*8-tmpf->size+16;
+
+        img=MAlloc(size);
+        MemCpy(img,rbp+tmpf->size,size);
+        UpdateRegVarImg(tmpf,img-tmpf->size,task);
+        ClassRep(img-tmpf->size,st,max_depth,TRUE,rbp-img+tmpf->size);
+        Free(img);
+      } else
+        ClassRep(rbp,st,max_depth,TRUE);
+    } else {
+      tmpm=tmpf->member_lst_and_root;
+      while (tmpm) {
+        if (0<=tmpm->reg<REG_REGS_NUM)
+          "%08Z %s\n",tmpm->reg,"ST_U64_REGS",tmpm->str;
+        else
+          "%08tX %s\n",tmpm->offset,tmpm->str;
+        tmpm=tmpm->next;
+      }
+      "%08tX Stk Size\n",tmpf->size;
+    }
+  }
+}
+
+#help_index "Debugging/Unassemble"
+public U0 Uf(U8 *st)
+{//Unassembles a named fun
+  I64 i;
+  CHashSrcSym *tmpf;
+  CDbgInfo *dbg_info;
+  if (tmpf=HashFind(st,Fs->hash_table,HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+    if (tmpf->type&HTT_FUN)
+      FunRep(st);
+    if (dbg_info=tmpf->dbg_info) {
+      i=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+            -dbg_info->body[0];
+      Un(dbg_info->body[0],i);
+      "Code Size:%04X\n",i;
+    } else
+      U(HashVal(tmpf));
+  }
+}
+
+ diff --git a/public/Wb/Adam/ADefine.HC.HTML b/public/Wb/Adam/ADefine.HC.HTML new file mode 100755 index 0000000..c108a05 --- /dev/null +++ b/public/Wb/Adam/ADefine.HC.HTML @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+#help_index "Define;Char/Define"
+
+U0 LoadDocDefines()
+{
+  CBinFile *bfh=mem_boot_base-sizeof(CBinFile);
+
+  DefinePrint("DD_OS_NAME_VERSION","TempleOS V%0.2f",sys_os_version);
+  DefinePrint("DD_TEMPLEOS_AGE","%0.1f",
+        (Now-Str2Date("8/1/2003"))/ToF64(1<<32)/CDATE_YEAR_DAYS);
+
+  DefinePrint("DD_KERNEL","%08X",bfh);
+  bfh(I64)+=bfh->file_size-1;
+  DefinePrint("DD_KERNEL_END","%08X",bfh);
+
+  //DD_BOOT_HIGH_LOC_DVD
+
++] LineRep
+
+  DefinePrint("DD_MP_VECT","%08X",MP_VECT_ADDR);
+  DefinePrint("DD_MP_VECT_END","%08X",
+        MP_VECT_ADDR+COREAP_16BIT_INIT_END-COREAP_16BIT_INIT-1);
+
+  DefinePrint("DD_SYS_FIXED_AREA_BASE","%08X",SYS_FIXED_AREA);
+  DefinePrint("DD_SYS_FIXED_AREA_END","%08X",
+        SYS_FIXED_AREA+sizeof(CSysFixedArea)-1);
+  DefinePrint("DD_MEM_HEAP_BASE","%08X",mem_heap_base);
+  DefinePrint("DD_MEM_HEAP_LIMIT","%08X",mem_heap_limit);
+  DefinePrint("DD_MEM_MIN_MEG","%dMeg",MEM_MIN_MEG);
+  DefinePrint("DD_UNCACHED_ALIAS","%010X",dev.uncached_alias);
+  DefinePrint("DD_PHYSICAL_SPACE_END","%010X",
+        mem_physical_space-1);
+  DefinePrint("DD_MAPPED_SPACE_END","%010X",
+        mem_mapped_space-1);
+  DefinePrint("DD_JIFFY_HZ","%dHz",JIFFY_FREQ);
+}
+
+LoadDocDefines;
+
+ diff --git a/public/Wb/Adam/AExts.HC.HTML b/public/Wb/Adam/AExts.HC.HTML new file mode 100755 index 0000000..9e0cbab --- /dev/null +++ b/public/Wb/Adam/AExts.HC.HTML @@ -0,0 +1,126 @@ + + + + + + + + + + + +
+extern U0 ACDDef(I64 n,CTask *parent=NULL);
+extern U0 ACDDefsPut(CDoc *doc=NULL,U8 *st,I64 num=-1);
+extern U0 ACDFillin(I64 n);
+extern U0 ACFillIn(I64 n);
+extern U0 ACMan(I64 n,CTask *parent_task=NULL);
+extern I64 AdamFile(U8 *filename,Bool warn_ext=TRUE);
+extern Bool AutoComplete(Bool val=OFF);
+extern U0 ClipDel();
+extern CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type);
+extern Bool CtrlInside(CCtrl *c,I64 x,I64 y);
+extern U8 *DC2Sprite(CDC *tmpb);
+extern U0 DocBinDel(CDoc *doc,CDocBin *b);
+extern U0 DocBinsValidate(CDoc *doc);
+extern U0 DocBottom(CDoc *doc=NULL);
+extern U0 DocCenter(CDoc *doc=NULL,I64 recalc_flags=RECALCt_NORMAL);
+extern U0 DocClear(CDoc *doc=NULL,Bool clear_holds=FALSE);
+extern Bool DocCursor(Bool show=OFF,CDoc *doc=NULL);
+extern U0 DocD(U8 *buf,I64 cnt=0x80);
+extern U0 DocDataFmt(CDoc *doc,CDocEntry *doc_e,I64 d=DOCM_CANCEL);
+extern U0 DocDel(CDoc *doc);
+extern CDoc *DocDisplay(CTask *task=NULL);
+extern U0 DocDump(CDoc *doc,I64 uS_delay=0);
+extern CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e);
+extern U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e);
+extern Bool DocForm(U8 *_d,U8 *class_name=lastclass,
+        I64 dof_flags=0,U8 *header=NULL,U8 *footer=NULL);
+extern U0 DocHelpIdx(CDoc *doc,U8 *idx);
+extern Bool DocHighlightCursor(Bool show=OFF,CDoc *doc=NULL);
+extern U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2);
+extern U0 DocInsEntry(CDoc *doc,CDocEntry *doc_e);
+extern Bool DocLock(CDoc *doc);
+extern I64 DocMax(I64 i=I64_MAX);
+extern CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL);
+extern CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...);
+extern CDoc *DocPut(CTask *task=NULL);
+extern CDoc *DocRead(U8 *name=NULL,I64 flags=0);
+extern Bool DocRecalc(CDoc *doc,I64 recalc_flags=RECALCt_NORMAL);
+extern U0 DocRst(CDoc *doc,Bool is_old);
+extern CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL);
+extern U0 DocTop(CDoc *doc=NULL);
+extern Bool DocUnlock(CDoc *doc);
+extern U0 DocUpdateTaskDocs(CTask *task);
+extern U0 DrawCtrls(CTask *task);
+extern Bool Ed(U8 *link_st,I64 edf_dof_flags=0);
+extern U0 EdCodeTools(CDoc *doc);
+extern U8 *EdSprite(I64 bin_num);
+extern I64 ExeDoc(CDoc *doc,I64 ccf_flags=0);
+extern I64 FindWiz();
+extern I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX);
+extern Bool GrPlot0(CDC *dc,I64 x,I64 y);
+extern CMenuEntry *MenuEntryFind(CMenu *haystack_menu,U8 *needle_full_name);
+extern CMenu *MenuFilePush(U8 *filename);
+extern U0 MenuPop();
+extern CMenu *MenuPush(U8 *st);
+extern U8 Mount(Bool caller_is_prtdsk=FALSE);
+extern CTask *Noise(I64 mS,F64 min_ona,F64 max_ona);
+extern Bool Plain(U8 *filename,I64 edf_dof_flags=0);
+extern Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL);
+extern I64 PopUpColor(U8 *header=NULL,
+        Bool allow_transparent=TRUE,Bool allow_dft=TRUE);
+extern I64 PopUpColorDither(U8 *header=NULL);
+extern I64 PopUpColorLighting(U8 *header=NULL);
+extern I64 PopUpFile(U8 *filename,
+        Bool warn_ext=TRUE,CTask *parent=NULL,CTask **_pu_task=NULL);
+extern Bool PopUpForm(U8 *_d,U8 *class_name=lastclass,
+        I64 dof_flags=DOF_SIZE_MIN,U8 *header=NULL,U8 *footer=NULL);
+extern I64 PopUpGetI64(U8 *msg,I64 dft,I64 lo=I64_MIN,I64 hi=I64_MAX);
+extern U8 *PopUpGetStr(U8 *header=NULL);
+extern I64 PopUpMenu(CDoc *doc,I64 dof_flags=0);
+extern Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL);
+extern Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL);
+extern I64 PopUpRangeI64(
+        I64 lo,I64 hi,I64 step=1,U8 *header=NULL,U8 *footer=NULL);
+extern Bool PopUpTransform(I64 *r);
+extern I64 RedSeaISO(U8 *_iso_filename=NULL,U8 *_src_dir,
+        U8 *_stage2_filename=NULL);
+extern U0 Refresh(I64 cnt=1,Bool force=FALSE);
+extern U0 RegOneTimePopUp(I64 flag_num,U8 *msg);
+extern Bool RegWrite(U8 *path,U8 *fmt,...);
+extern U0 SettingsPop(CTask *task=NULL,I64 flags=0);
+extern CTaskSettings *SettingsPush(CTask *task=NULL,I64 flags=0);
+extern U0 TemplateCtrlSlider(CDoc *doc);
+extern Bool View();
+extern U0 ViewAnglesDel(CTask *task=NULL);
+extern CCtrl *ViewAnglesNew(CTask *task=NULL);
+extern Bool WinBorder(Bool val=OFF,CTask *task=NULL);
+extern CDoc *WinCursorPosSet(CTask *task,I64 msx,I64 msy,Bool set_cursor=TRUE);
+extern Bool WinHorz(I64 left,I64 right,CTask *task=NULL);
+extern U0 WinMax(CTask *task=NULL);
+extern U0 WinScrollNull(CTask *task,CD3I64 *s);
+extern U0 WinScrollRestore(CTask *task,CD3I64 *s);
+extern U0 WinScrollsInit(CTask *task);
+extern I64 WinToTop(CTask *task=NULL,Bool update_z_buf=TRUE);
+extern Bool WinVert(I64 top,I64 bottom,CTask *task=NULL);
+extern CWinMgrGlbls winmgr;
+
+ diff --git a/public/Wb/Adam/AHash.HC.HTML b/public/Wb/Adam/AHash.HC.HTML new file mode 100755 index 0000000..9d437d2 --- /dev/null +++ b/public/Wb/Adam/AHash.HC.HTML @@ -0,0 +1,462 @@ + + + + + + + + + + + +
+#help_index "Info;Hash/System;Cmd Line (Typically)"
+class CWho
+{
+  CHashGeneric *h;
+  U8 *idx;
+};
+
+I64 HashEntriesCompare(CWho *h1,CWho *h2)
+{
+  I64 i1,i2;
+  if (i1=StrCmp(h1->h->str,h2->h->str))
+    return i1;
+  i1=HashTypeNum(h1->h);
+  i2=HashTypeNum(h2->h);
+  return i1-i2;
+}
+
+I64 HashEntriesCompare2(CWho *h1,CWho *h2)
+{
+  CHashFun *tmpf1=h1->h,*tmpf2=h2->h;
+  I64 i1=HashVal(tmpf1),i2=HashVal(tmpf2);
+  if (i1==i2) {
+    i1=HashTypeNum(tmpf1);
+    i2=HashTypeNum(tmpf2);
+    if (i1==i2)
+      return StrCmp(tmpf1->str,tmpf2->str);
+  }
+  return i1-i2;
+}
+
+I64 HelpIndexCnt(U8 *ptr,U8 *idx)
+{
+  I64 cnt=0,ch,idx_len=StrLen(idx);
+  while (*ptr) {
+    if (!StrNCmp(ptr,idx,idx_len))
+      cnt++;
+    while (ch=*ptr++)
+      if (ch==';')
+        break;
+    if (!ch)
+      ptr--;
+  }
+  return cnt;
+}
+
+U8 *HelpIndexStr(U8 **_ptr,U8 *idx)
+{
+  U8 *ptr=*_ptr,*ptr2,*res;
+  I64 ch,idx_len=StrLen(idx);
+  while (*ptr) {
+    ptr2=ptr;
+    while (ch=*ptr++)
+      if (ch==';')
+        break;
+    if (!ch)
+      ptr--;
+    *_ptr=ptr;
+    if (!StrNCmp(ptr2,idx,idx_len)) {
+      if (ch==';')
+        ptr--;
+      *ptr=0;
+      res=StrNew(ptr2);
+      *ptr=ch;
+      return res;
+    }
+  }
+  return NULL;
+}
+
+U8 *HelpComment(CTask *task,CHash *tmph,U8 *_src_link)
+{
+  CDoc *doc;
+  CDocEntry *doc_e;
+  U8 *res=NULL,*ptr,*ptr2,*src_link=StrNew(_src_link);
+
+  if (*src_link=='F' && src_link[2]==':')
+    *src_link='P';
+  XTalkWait(task,"Ed(0x%X,DOF_DONT_WINMGR_SYNC|DOF_DONT_SHOW);\n",src_link);
+  Free(src_link);
+
+  doc=DocPut(task);
+  doc_e=doc->cur_entry;
+  if (tmph->type&HTT_FUN) {
+    if (Bt(&tmph(CHashFun *)->flags,Ff__EXTERN) ||
+          Bt(&tmph(CHashFun *)->flags,Ff_INTERNAL))
+      while (doc_e!=doc &&
+            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,';')))
+        doc_e=doc_e->next;
+    else
+      while (doc_e!=doc &&
+            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,'{')))
+        doc_e=doc_e->next;
+  }
+  if (doc_e!=doc) {
+    if (doc_e->de_flags&DOCEF_TAG) {
+      ptr=doc_e->tag;
+      if (ptr2=StrMatch("//",ptr))
+        ptr=ptr2+2;
+      else if (ptr2=StrMatch("/*",ptr))
+        ptr=ptr2+2;
+      else if (!StrNCmp(ptr,"public",6))
+        ptr+=6;
+      while (*ptr==CH_SPACE)
+        ptr++;
+      res=StrNew(ptr);
+      doc_e=doc_e->next;
+    }
+    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
+      if (doc_e->type_u8==DOCT_TAB) {
+        ptr=MStrPrint("%s ",res);
+        Free(res);
+        res=ptr;
+      } else if (doc_e->de_flags&DOCEF_TAG) {
+        ptr=MStrPrint("%s%s",res,doc_e->tag);
+        Free(res);
+        res=ptr;
+      }
+      doc_e=doc_e->next;
+    }
+  }
+  XTalkWait(task,"%c",CH_SHIFT_ESC);
+  if (res) {
+    ptr=MStrUtil(res,SUF_REM_TRAILING|SUF_REM_LEADING|SUF_SINGLE_SPACE);
+    Free(res);
+    res=ptr;
+  }
+  return res;
+}
+
+I64 HashEntriesCompare3(CWho *h1,CWho *h2)
+{
+  I64 i,i1=0,i2=0;
+  i=StrCmp(h1->idx,h2->idx);
+  if (i)
+    return i;
+  else {
+    if (h1->h->type&HTT_HELP_FILE)
+      i1=1;
+    if (h2->h->type&HTT_HELP_FILE)
+      i2=1;
+    i=i2-i1;
+    if (i)
+      return i;
+    else
+      return StrCmp(h1->h->str,h2->h->str);
+  }
+}
+
+public U0 Who(U8 *fu_flags=NULL,CHashTable *h=NULL,
+U8 *idx=NULL,CDoc *doc=NULL)
+{//Dump hash symbol table.
+// "+p" for only public symbols
+  // "+m" to order by number (normally alphabetical)
+  // "-r" just local hash table
+  CHashTable *table;
+  CHashSrcSym *tmph;
+  CHashGeneric *ptr;
+  CWho *lst;
+  I64 cnt,i,j,k,f=0;
+  U8 buf[512],*last_idx=StrNew(""),*cur_idx,*comment;
+  Bool recurse,publics,map;
+  CTask *task;
+
+  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (f&~(FUF_RECURSE|FUF_PUBLIC|FUF_MAP))
+    throw('FUF');
+  recurse=Bt(&f,FUf_RECURSE);
+  publics=Bt(&f,FUf_PUBLIC);
+  map    =Bt(&f,FUf_MAP);
+
+  if (!h) h=Fs->hash_table;
+
+  if (idx) {
+    task=User;
+    TaskWait(task);
+    LBtr(&task->display_flags,DISPLAYf_SHOW);
+  } else
+    task=NULL;
+
+  cnt=0;
+  table=h;
+  while (table) {
+    for (i=0;i<=table->mask;i++) {
+      tmph=table->body[i];
+      while (tmph) {
+        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
+              (tmph->type & HTF_PUBLIC || !publics)) {
+          if (!idx)
+            cnt++;
+          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx))
+            cnt+=HelpIndexCnt(cur_idx,idx);
+        }
+        tmph=tmph->next;
+      }
+    }
+    if (recurse)
+      table=table->next;
+    else
+      break;
+  }
+  if (!cnt) goto wh_done;
+
+  lst=CAlloc(cnt*sizeof(CWho));
+  j=0;
+  table=h;
+  while (table) {
+    for (i=0;i<=table->mask;i++) {
+      tmph=table->body[i];
+      while (tmph) {
+        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
+              (tmph->type & HTF_PUBLIC || !publics))
+          if (!idx)
+            lst[j++].h=tmph;
+          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx) &&
+                (k=HelpIndexCnt(cur_idx,idx)))
+            while (k--) {
+              lst[j].idx=HelpIndexStr(&cur_idx,idx);
+              lst[j++].h=tmph;
+            }
+        tmph=tmph->next;
+      }
+    }
+    if (recurse)
+      table=table->next;
+    else
+      break;
+  }
+
+  if (map)
+    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare2);
+  else if (idx)
+    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare3);
+  else
+    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare);
+
+  if (idx) {
+    progress1_max=cnt;
+    progress1=0;
+  }
+  for (i=0;i<cnt;i++) {
+    comment=NULL;
+    ptr=lst[i].h;
+    if (idx)
+      if (cur_idx=lst[i].idx) {
+        if (StrCmp(cur_idx,last_idx)) {
+          Free(last_idx);
+          last_idx=StrNew(cur_idx);
+          if (i)
+            DocPrint(doc,"\n\n");
+          DocPrint(doc,"$WW,0$$PURPLE$$TX+CX,\"%$Q\"$$FG$\n",cur_idx);
+        }
+      }
+
+    if (idx && ptr->type & HTT_HELP_FILE) {
+      DocPrint(doc,"$WW,1$");
+      DocType(doc,ptr->str);
+      DocPrint(doc,"$WW,0$");
+    } else {
+      if (ptr->type&HTG_SRC_SYM && ptr(CHashSrcSym *)->src_link) {
+        DocPrint(doc,"$LK,\"%-20s\",A=\"%s\"$",
+              ptr->str,ptr(CHashSrcSym *)->src_link);
+        if (idx)
+          comment=HelpComment(task,ptr,ptr(CHashSrcSym *)->src_link);
+      } else
+        DocPrint(doc,"%-20s",ptr->str);
+
+      if (!idx) {
+        if (ptr->type & HTT_DEFINE_STR) {
+          j=ptr(CHashDefineStr *)->cnt;
+          if (j==-1)
+            StrPrint(buf,"%-10t$Q   ",ptr(CHashDefineStr *)->data);
+          else
+            StrPrint(buf,"%-10t$Q %02X",ptr(CHashDefineStr *)->data,j);
+        } else if (ptr->type & HTT_GLBL_VAR)
+          StrPrint(buf,"%010X   ",ptr(CHashGlblVar *)->data_addr);
+        else
+          StrPrint(buf,"%010X   ",HashVal(ptr));
+        j=HashEntrySize(ptr);
+        if (j==-1)
+          CatPrint(buf," %04X            ",ptr->use_cnt);
+        else
+          CatPrint(buf," %04X %010X ",ptr->use_cnt,j);
+      } else
+        *buf=0;
+
+      k=ptr->type;
+      if (publics)
+        k&=~HTF_PUBLIC;
+      if (!(k&HTG_TYPE_MASK))
+        CatPrint(buf,"NULL ");
+      while (k) {
+        j=Bsf(k);
+        if (j<0)
+          break;
+        Btr(&k,j);
+        CatPrint(buf,"%Z ",j,"ST_HTT_TYPES");
+      }
+      DocPrint(doc,"%s",buf);
+      if (comment) {
+        DocPrint(doc,"$GREEN$%s$FG$",comment);
+        Free(comment);
+      }
+      DocPrint(doc,"\n");
+    }
+    Free(lst[i].idx);
+    if (idx)
+      progress1++;
+  }
+  Free(lst);
+  if (idx)
+    progress1=progress1_max=0;
+
+wh_done:
+  if (doc) {
+    if (doc->head.next==doc)
+      DocPrint(doc,"No Match");
+    else
+      DocRecalc(doc);
+  }
+  Free(last_idx);
+  Kill(task);
+}
+
+#help_index "Info;Hash;Cmd Line (Typically)"
+
+#define HDR_NUM 16
+public I64 HashDepthRep(CHashTable *table=NULL)
+{//Hash table linked-list chain depth report.
+//Histogram of collision count.
+  I64 i,j,longest=0,cnt=0,a[HDR_NUM];
+  CHash *tmph;
+  if (!table) table=Fs->hash_table;
+  MemSet(a,0,sizeof(a));
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    if (tmph) {
+      j=LinkedLstCnt(tmph);
+      if (j<HDR_NUM)
+        a[j]++;
+      cnt+=j;
+      if (j>longest)
+        longest=j;
+    }
+  }
+  "Histogram\n";
+  for (i=0;i<HDR_NUM;i++)
+    if (a[i])
+      "%02d:%d\n",i,a[i];
+  "Size:%d Count:%d Longest:%d\n",
+        table->mask+1,cnt,longest;
+  return longest;
+}
+
+#help_index "Help System"
+#help_file "::/Doc/HelpSystem"
+
+public U0 DocHelpIdx(CDoc *doc,U8 *idx)
+{//Put to doc report for given help idx.
+  Who("+p",,idx,doc);
+}
+
+public U0 PopUpHelpIndex(U8 *idx,CTask *parent=NULL)
+{//PopUp win report for given help idx.
+  U8 *buf;
+  buf=MStrPrint("DocHelpIdx(DocPut,\"%s\");View;",idx);
+  PopUp(buf,parent);
+  Free(buf);
+}
+
+#help_index "Hash/System"
+public U0 MapFileLoad(U8 *filename)
+{//Load map file so we have src line info.
+  U8 *st,*ptr,*name=ExtDft(filename,"MAP.Z"),
+        *absname=FileNameAbs(name);
+  CDoc *doc=DocRead(name);
+  CDocEntry *doc_e;
+  CHashSrcSym *tmph;
+  I64 i,j,base=0;
+  CDbgInfo *dbg_info;
+
+  FileExtRem(absname);
+  if (absname[1]==':' && StrLen(absname)>2 &&
+        (tmph=HashSingleTableFind(absname+2,Fs->hash_table,HTT_MODULE)))
+    base=tmph(CHashGeneric *)->user_data0+sizeof(CBinFile);
+
+  if (!doc) return;
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_LINK) {
+      if (*doc_e->tag)
+        st=MStrUtil(doc_e->tag,SUF_REM_TRAILING);
+      else
+        st=MStrUtil(doc_e->aux_str,SUF_REM_TRAILING);
+      if (tmph=HashSingleTableFind(st,Fs->hash_table,HTG_SRC_SYM)) {
+        if (*doc_e->tag) {
+          Free(tmph->src_link);
+          tmph->src_link=doc_e->aux_str;
+          ptr=tmph->src_link;
+          if (ptr[0] && ptr[1] && ptr[2]==':') {
+            if (ptr[3]==':')
+              ptr[3]=blkdev.boot_drv_let;
+            else if (ptr[3]=='~')
+              ptr[3]=*blkdev.home_dir;
+          }
+          doc_e->aux_str=NULL;
+        }
+        if (tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM) &&
+              !(dbg_info=tmph->dbg_info) && doc_e->bin_data &&
+              (dbg_info=doc_e->bin_data->data)) {
+          if (doc_e->bin_data->size>MSize(dbg_info))
+            "Corrupt Map Entry\n";
+          else {
+            doc_e->bin_data->data=NULL;
+            tmph->dbg_info=dbg_info;
+            for (i=dbg_info->min_line;i<=dbg_info->max_line+1;i++) {
+              j=i-dbg_info->min_line;
+              if (dbg_info->body[j])
+                dbg_info->body[j]=dbg_info->body[j]+base;
+            }
+          }
+        }
+      }
+      Free(st);
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+  Free(name);
+  Free(absname);
+}
+
+ diff --git a/public/Wb/Adam/AMath.HC.HTML b/public/Wb/Adam/AMath.HC.HTML new file mode 100755 index 0000000..6ed99c7 --- /dev/null +++ b/public/Wb/Adam/AMath.HC.HTML @@ -0,0 +1,166 @@ + + + + + + + + + + + +
+#help_index "Math"
+public U0 R2P(F64 *_mag=NULL,F64 *_arg=NULL,F64 x,F64 y)
+{//Rect to polar
+//Returns angle in range (-pi,pi]
+  if (_arg)
+    *_arg=Arg(x,y);
+  if (_mag)
+    *_mag=Sqrt(x*x+y*y);
+}
+
+public U0 P2R(F64 *_x=NULL,F64 *_y=NULL,F64 mag,F64 arg)
+{//Polar to Rect
+  if (_x)
+    *_x=mag*Cos(arg);
+  if (_y)
+    *_y=mag*Sin(arg);
+}
+
+public F64 Wrap(F64 theta,F64 base=-pi)
+{//Returns angle in range [base,base+2*pi)
+  F64 res=theta%(2*pi);
+  if (res>=base+2*pi)
+    res-=2*pi;
+  else if (res<base)
+    res+=2*pi;
+  return res;
+}
+
+public I64 DistSqrI64(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Distance-squared between 2 points.
+  I64 dx=x1-x2,dy=y1-y2;
+  return dx*dx+dy*dy;
+}
+
+public F64 ASin(F64 s)
+{//Arc Sin (Inverse Sin).
+  F64 c;
+  c=s*s;
+  if (c>=1.0)
+    return pi/2.0;
+  c=Sqrt(1.0-c);
+  return ATan(s/c);
+}
+
+public F64 ACos(F64 c)
+{//Arc Cos (Inverse Cos).
+  F64 s;
+  if (!c)
+    return pi/2.0;
+  s=c*c;
+  if (s>=1.0)
+    return 0.0;
+  s=Sqrt(1.0-s);
+  return ATan(s/c);
+}
+
+public F64 Sinh(F64 x)
+{//Hyperbolic Sine.
+  return 0.5*(Exp(x)-Exp(-x));
+}
+
+public F64 Cosh(F64 x)
+{//Hyperbolic Cosine.
+  return 0.5*(Exp(x)+Exp(-x));
+}
+
+#help_index "Math/Complex;Data Types/Complex"
+public Complex *CAdd(Complex *sum,Complex *n1,Complex *n2)
+{//sum=n1+n2
+  sum->x=n1->x+n2->x;
+  sum->y=n1->y+n2->y;
+  return sum;
+}
+
+public Complex *CSub(Complex *diff,Complex *n1,Complex *n2)
+{//diff=n1-n2
+  diff->x=n1->x-n2->x;
+  diff->y=n1->y-n2->y;
+  return diff;
+}
+
+public Complex *CMul(Complex *prod,Complex *n1,Complex *n2)
+{//prod=n1*n2
+  prod->x=n1->x*n2->x-n1->y*n2->y;
+  prod->y=n1->x*n2->y+n1->y*n2->x;
+  return prod;
+}
+
+public Complex *CDiv(Complex *quot,Complex *n1,Complex *n2)
+{//quot=n1/n2
+  F64 m1,arg1,m2,arg2;
+  R2P(&m1,&arg1,n1->x,n1->y);
+  R2P(&m2,&arg2,n2->x,n2->y);
+  m1/=m2;
+  arg1-=arg2;
+  quot->x=m1*Cos(arg1);
+  quot->y=m1*Sin(arg1);
+  return quot;
+}
+
+public Complex *CScale(Complex *dst,F64 s)
+{//dst*=s
+  dst->x*=s;
+  dst->y*=s;
+  return dst;
+}
+
+public Complex *CCopy(Complex *dst,Complex *src)
+{//dst=src
+  dst->x=src->x;
+  dst->y=src->y;
+  return dst;
+}
+
+public Complex *CEqu(Complex *dst,F64 x,F64 y)
+{//dst=(x,y)
+  dst->x=x;
+  dst->y=y;
+  return dst;
+}
+
+public Complex *CPoly(Complex *dst,I64 n,Complex *zeros,Complex *x)
+{//Eval complex polynomial
+  I64 i;
+  Complex n1,n2;
+  if (n>0) {
+    CSub(dst,x,&zeros[0]);
+    for (i=1;i<n;i++) {
+      CCopy(&n1,dst);
+      CMul(dst,&n1,CSub(&n2,x,&zeros[i]));
+    }
+  } else
+    CEqu(dst,1.0,0.0);
+  return dst;
+}
+
+ diff --git a/public/Wb/Adam/AMathODE.HC.HTML b/public/Wb/Adam/AMathODE.HC.HTML new file mode 100755 index 0000000..5832989 --- /dev/null +++ b/public/Wb/Adam/AMathODE.HC.HTML @@ -0,0 +1,719 @@ + + + + + + + + + + + +
+#help_index "Math/ODE"
+#help_file "::/Doc/ODE"
+
+//See ::/Doc/Credits.DD.
+
+F64 LowPass1(F64 a,F64 y0,F64 y,F64 dt=1.0)
+{//First order low pass filter
+  dt=Exp(-a*dt);
+  return y0*dt+y*(1.0-dt);
+}
+
+U0 ODERstPtrs(CMathODE *ode)
+{
+  I64 s=ode->n_internal*sizeof(F64);
+  F64 *ptr=ode->array_base;
+  ode->state_internal=ptr;      ptr(I64)+=s;
+  ode->state_scale=ptr;         ptr(I64)+=s;
+  ode->DstateDt=ptr;            ptr(I64)+=s;
+  ode->initial_state=ptr;       ptr(I64)+=s;
+  ode->tmp0=ptr;        ptr(I64)+=s;
+  ode->tmp1=ptr;        ptr(I64)+=s;
+  ode->tmp2=ptr;        ptr(I64)+=s;
+  ode->tmp3=ptr;        ptr(I64)+=s;
+  ode->tmp4=ptr;        ptr(I64)+=s;
+  ode->tmp5=ptr;        ptr(I64)+=s;
+  ode->tmp6=ptr;        ptr(I64)+=s;
+  ode->tmp7=ptr;
+}
+
+public CMathODE *ODENew(I64 n,F64 max_tolerance=1e-6,I64 flags=0)
+{//Make differential equation ctrl struct. See flags.
+  //The tolerance is not precise.
+  //You can min_tolerance and it will
+  //dynamically adjust tolerance to utilize
+  //the CPU.
+  I64 s=n*sizeof(F64);
+  CMathODE *ode=CAlloc(sizeof(CMathODE));
+  ode->t_scale=1.0;
+  ode->flags=flags;
+  ode->n_internal=ode->n=n;
+  ode->h=1e-6;
+  ode->h_min=1e-64;
+  ode->h_max=1e32;
+  ode->max_tolerance=ode->min_tolerance=ode->tolerance_internal=max_tolerance;
+  ode->win_task=ode->mem_task=Fs;
+  QueInit(&ode->next_mass);
+  QueInit(&ode->next_spring);
+  ode->state=CAlloc(s);
+  ode->array_base=MAlloc(12*s);
+  ODERstPtrs(ode);
+  return ode;
+}
+
+
+public Bool ODEPause(CMathODE *ode,Bool val=ON)
+{//Pause ODE.
+  Bool res;
+  if (!ode) return OFF;
+  res=LBEqu(&ode->flags,ODEf_PAUSED,val);
+  if (val)
+    while (Bt(&ode->flags,ODEf_BUSY))
+      Yield;
+  return res;
+}
+
+public U0 ODEDel(CMathODE *ode)
+{//Free ODE node, but not masses or springs.
+  I64 i;
+  if (!ode) return;
+  ODEPause(ode);
+  Free(ode->state);
+  Free(ode->array_base);
+  if (ode->slave_tasks) {
+    for (i=0;i<mp_cnt;i++)
+      Kill(ode->slave_tasks[i]);
+    Free(ode->slave_tasks);
+  }
+  Free(ode);
+}
+
+public I64 ODESize(CMathODE *ode)
+{//Mem size of ode ctrl, but not masses and springs.
+  if (!ode)
+    return 0;
+  else
+    return MSize2(ode->state)+MSize2(ode->array_base)+MSize2(ode);
+}
+
+U0 ODESetMassesPtrs(CMathODE *ode,F64 *state,F64 *DstateDt)
+{
+  COrder2D3 *ptr1=state(F64 *)+ode->n,
+        *ptr2=DstateDt(F64 *)+ode->n;
+  CMass *tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->state=ptr1++;
+    tmpm->DstateDt=ptr2++;
+    tmpm=tmpm->next;
+  }
+}
+
+U0 ODEState2Internal(CMathODE *ode)
+{
+  CMass *tmpm;
+  F64 *old_array_base;
+  I64 mass_cnt;
+
+  if (ode->flags&ODEF_HAS_MASSES) {
+    mass_cnt=0;
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      mass_cnt++;
+      tmpm=tmpm->next;
+    }
+    old_array_base=ode->array_base;
+    ode->n_internal=ode->n+6*mass_cnt;
+    ode->array_base=MAlloc(12*ode->n_internal*sizeof(F64),ode->mem_task);
+    Free(old_array_base);
+    ODERstPtrs(ode);
+
+    ODESetMassesPtrs(ode,ode->state_internal,ode->state_internal);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      MemCpy(tmpm->state,&tmpm->saved_state,sizeof(COrder2D3));
+      tmpm=tmpm->next;
+    }
+  }
+  MemCpy(ode->state_internal,ode->state,ode->n*sizeof(F64));
+}
+
+U0 ODEInternal2State(CMathODE *ode)
+{
+  CMass *tmpm;
+  MemCpy(ode->state,ode->state_internal,ode->n*sizeof(F64));
+  if (ode->flags&ODEF_HAS_MASSES) {
+    ODESetMassesPtrs(ode,ode->state_internal,ode->state_internal);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      MemCpy(&tmpm->saved_state,tmpm->state,sizeof(COrder2D3));
+      tmpm=tmpm->next;
+    }
+  }
+}
+
+public U0 ODERenum(CMathODE *ode)
+{//Renumber masses and springs.
+  I64 i;
+  CSpring *tmps;
+  CMass *tmpm;
+
+  i=0;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->num=i++;
+    tmpm=tmpm->next;
+  }
+
+  i=0;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps->num=i++;
+    tmps->end1_num=tmps->end1->num;
+    tmps->end2_num=tmps->end2->num;
+    tmps=tmps->next;
+  }
+}
+
+public CMass *MassFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
+{//Search for mass nearest to x,y,z.
+  CMass *tmpm,*best_mass=NULL;
+  F64 dd,best_dd=F64_MAX;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    dd=Sqr(tmpm->x-x)+Sqr(tmpm->y-y)+Sqr(tmpm->z-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_mass=tmpm;
+    }
+    tmpm=tmpm->next;
+  }
+  return best_mass;
+}
+
+public CSpring *SpringFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
+{//Find spring midpoint nearest x,y,z.
+  CSpring *tmps,*best_spring=NULL;
+  F64 dd,best_dd=F64_MAX;
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    dd=Sqr((tmps->end1->x+tmps->end2->x)/2-x)+
+          Sqr((tmps->end1->y+tmps->end2->y)/2-y)+
+          Sqr((tmps->end1->z+tmps->end2->z)/2-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_spring=tmps;
+    }
+    tmps=tmps->next;
+  }
+  return best_spring;
+}
+
+public U0 MassOrSpringFind(
+        CMathODE *ode,CMass **res_mass,CSpring **res_spring,
+        F64 x,F64 y,F64 z=0)
+{//Find spring or mass nearest x,y,z.
+  CMass   *tmpm,*best_mass=NULL;
+  CSpring *tmps,*best_spring=NULL;
+  F64 dd,best_dd=F64_MAX;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    dd=Sqr(tmpm->x-x)+Sqr(tmpm->y-y)+Sqr(tmpm->z-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_mass=tmpm;
+    }
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    dd=Sqr((tmps->end1->x+tmps->end2->x)/2-x)+
+          Sqr((tmps->end1->y+tmps->end2->y)/2-y)+
+          Sqr((tmps->end1->z+tmps->end2->z)/2-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_spring=tmps;
+      best_mass=NULL;
+    }
+    tmps=tmps->next;
+  }
+  if (res_mass)   *res_mass  =best_mass;
+  if (res_spring) *res_spring=best_spring;
+}
+
+public CMass *MassFindNum(CMathODE *ode,I64 num)
+{//Return mass number N.
+  CMass *tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->num==num)
+      return tmpm;
+    tmpm=tmpm->next;
+  }
+  return NULL;
+}
+
+public U0 ODERstInactive(CMathODE *ode)
+{//Set all masses and springs to ACTIVE for new trial.
+  CMass *tmpm;
+  CSpring *tmps;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->flags&=~MSF_INACTIVE;
+    tmpm=tmpm->next;
+  }
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps->flags&=~SSF_INACTIVE;
+    tmps=tmps->next;
+  }
+}
+
+U0 ODECalcSprings(CMathODE *ode)
+{
+  CSpring *tmps=ode->next_spring;
+  CMass *e1,*e2;
+  F64 d;
+  CD3 p;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->flags&SSF_INACTIVE) {
+      tmps->displacement=0;
+      tmps->f=0;
+    } else {
+      e1=tmps->end1;
+      e2=tmps->end2;
+      d=D3Norm(D3Sub(&p,&e2->state->x,&e1->state->x));
+      tmps->displacement=d-tmps->rest_len;
+      tmps->f=tmps->displacement*tmps->const;
+      if (tmps->f>0 && tmps->flags&SSF_NO_TENSION)
+        tmps->f=0;
+      else if (tmps->f<0 && tmps->flags&SSF_NO_COMPRESSION)
+        tmps->f=0;
+      if (d>0) {
+        D3MulEqu(&p,tmps->f/d);
+        D3AddEqu(&e1->DstateDt->DxDt,&p);
+        D3SubEqu(&e2->DstateDt->DxDt,&p);
+      }
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 ODECalcDrag(CMathODE *ode)
+{
+  CMass *tmpm;
+  F64 d,dd;
+  CD3 p;
+  if (ode->drag_v || ode->drag_v2 || ode->drag_v3) {
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags & MSF_INACTIVE) &&
+            tmpm->drag_profile_factor &&
+            (dd=D3NormSqr(&tmpm->state->DxDt))) {
+        d=ode->drag_v;
+        if (ode->drag_v2)
+          d+=ode->drag_v2*Sqrt(dd);
+        if (ode->drag_v3)
+          d+=dd*ode->drag_v3;
+        D3SubEqu(&tmpm->DstateDt->DxDt,
+              D3Mul(&p,d*tmpm->drag_profile_factor,&tmpm->state->DxDt));
+      }
+      tmpm=tmpm->next;
+    }
+  }
+}
+
+U0 ODEApplyAccelerationLimit(CMathODE *ode)
+{
+  CMass *tmpm;
+  F64 d;
+  if (ode->acceleration_limit) {
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags & MSF_INACTIVE) &&
+            (d=D3Norm(&tmpm->DstateDt->DxDt))>ode->acceleration_limit)
+        D3MulEqu(&tmpm->DstateDt->DxDt,ode->acceleration_limit/d);
+      tmpm=tmpm->next;
+    }
+  }
+}
+
+U0 ODEMPTask(CMathODE *ode)
+{
+  while (TRUE) {
+    while (!Bt(&ode->mp_not_done_flags,Gs->num))
+      Yield;
+    if (ode->mp_derive)
+      (*ode->mp_derive)(ode,ode->mp_t,
+            Gs->num,ode->mp_state,ode->mp_DstateDt);
+    LBtr(&ode->mp_not_done_flags,Gs->num);
+  }
+}
+
+U0 ODEMPWake(CMathODE *ode)
+{
+  I64 i;
+  if (!ode->slave_tasks) {
+    ode->slave_tasks=CAlloc(mp_cnt*sizeof(CTask *));
+    for (i=0;i<mp_cnt;i++)
+      ode->slave_tasks[i]=Spawn(&ODEMPTask,ode,"ODE Slave",i);
+  }
+  for (i=0;i<mp_cnt;i++) {
+    Suspend(ode->slave_tasks[i],FALSE);
+    MPInt(I_WAKE,i);
+  }
+}
+
+U0 ODEMPSleep(CMathODE *ode)
+{
+  I64 i;
+  if (ode->slave_tasks) {
+    while (ode->mp_not_done_flags)
+      Yield;
+    for (i=0;i<mp_cnt;i++)
+      Suspend(ode->slave_tasks[i]);
+  }
+}
+
+U0 ODECallMPDerivative(CMathODE *ode,F64 t,F64 *state,F64 *DstateDt)
+{
+  ode->mp_t=t;
+  ode->mp_state=state;
+  ode->mp_DstateDt=DstateDt;
+  ode->mp_not_done_flags=1<<mp_cnt-1;
+  do Yield;
+  while (ode->mp_not_done_flags);
+}
+
+U0 ODECallDerivative(CMathODE *ode,F64 t,F64 *state,F64 *DstateDt)
+{
+  CMass *tmpm;
+  if (ode->flags&ODEF_HAS_MASSES) {
+    ODESetMassesPtrs(ode,state,DstateDt);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags&MSF_INACTIVE)) {
+        D3Zero(&tmpm->DstateDt->DxDt);
+        D3Copy(&tmpm->DstateDt->x,&tmpm->state->DxDt);
+      }
+      tmpm=tmpm->next;
+    }
+    ODECalcSprings(ode);
+    ODECalcDrag(ode);
+    if (ode->mp_derive)
+      ODECallMPDerivative(ode,t,state,DstateDt);
+    if (ode->derive)
+      (*ode->derive)(ode,t,state,DstateDt);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags&MSF_INACTIVE)) {
+        if (tmpm->flags&MSF_FIXED) {
+          D3Zero(&tmpm->DstateDt->DxDt);
+          D3Zero(&tmpm->DstateDt->x);
+        } else if (tmpm->mass)
+          D3DivEqu(&tmpm->DstateDt->DxDt,tmpm->mass);
+      }
+      tmpm=tmpm->next;
+    }
+    ODEApplyAccelerationLimit(ode);
+  } else {
+    if (ode->mp_derive)
+      ODECallMPDerivative(ode,t,state,DstateDt);
+    if (ode->derive)
+      (*ode->derive)(ode,t,state,DstateDt);
+  }
+}
+
+U0 ODEOneStep(CMathODE *ode)
+{
+  I64 i;
+  ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+  for (i=0;i<ode->n_internal;i++)
+    ode->state_internal[i]+=ode->h*ode->DstateDt[i];
+  ode->t+=ode->h;
+}
+
+U0 ODERK4OneStep(CMathODE *ode)
+{
+  I64 i,n=ode->n_internal;
+  F64 xh,hh,h6,*dym,*dyt,*yt,*DstateDt;
+
+  dym =ode->tmp0;
+  dyt =ode->tmp1;
+  yt  =ode->tmp2;
+  DstateDt=ode->tmp3;
+  hh  =0.5*ode->h;
+  h6  =ode->h / 6.0;
+  xh  =ode->t + hh;
+
+  ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+  for (i=0;i<n;i++)
+    yt[i]=ode->state_internal[i]+hh*DstateDt[i];
+  ODECallDerivative(ode,xh,yt,dyt);
+  for (i=0;i<n;i++)
+    yt[i]=ode->state_internal[i]+hh*dyt[i];
+  ODECallDerivative(ode,xh,yt,dym);
+  for (i=0;i<n;i++) {
+    yt[i]=ode->state_internal[i]+ode->h*dym[i];
+    dym[i]+=dyt[i];
+  }
+  ode->t+=ode->h;
+  ODECallDerivative(ode,ode->t,yt,dyt);
+  for (i=0;i<n;i++)
+    ode->state_internal[i]+=h6*(DstateDt[i]+dyt[i]+2.0*dym[i]);
+}
+
+#define ODEa2 0.2
+#define ODEa3 0.3
+#define ODEa4 0.6
+#define ODEa5 1.0
+#define ODEa6 0.875
+#define ODEb21 0.2
+#define ODEb31 (3.0/40.0)
+#define ODEb32 (9.0/40.0)
+#define ODEb41 0.3
+#define ODEb42 (-0.9)
+#define ODEb43 1.2
+#define ODEb51 (-11.0/54.0)
+#define ODEb52 2.5
+#define ODEb53 (-70.0/27.0)
+#define ODEb54 (35.0/27.0)
+#define ODEb61 (1631.0/55296.0)
+#define ODEb62 (175.0/512.0)
+#define ODEb63 (575.0/13824.0)
+#define ODEb64 (44275.0/110592.0)
+#define ODEb65 (253.0/4096.0)
+#define ODEc1  (37.0/378.0)
+#define ODEc3  (250.0/621.0)
+#define ODEc4  (125.0/594.0)
+#define ODEc6  (512.0/1771.0)
+#define ODEdc1 (37.0/378.0-2825.0/27648.0)
+#define ODEdc3 (250.0/621.0-18575.0/48384.0)
+#define ODEdc4 (125.0/594.0-13525.0/55296.0)
+#define ODEdc5 (-277.0/14336.0)
+#define ODEdc6 (512.0/1771.0-0.25)
+
+U0 ODECashKarp(CMathODE *ode)
+{
+  I64 i,n=ode->n_internal;
+  F64 h=ode->h,*state=ode->state_internal,
+        *DstateDt=ode->DstateDt,*ak2,*ak3,*ak4,*ak5,*ak6,
+        *tmpstate,*stateerr,*outstate;
+
+  ak2=ode->tmp0;
+  ak3=ode->tmp1;
+  ak4=ode->tmp2;
+  ak5=ode->tmp3;
+  ak6=ode->tmp4;
+  tmpstate=ode->tmp5;
+  outstate=ode->tmp6;
+  stateerr=ode->tmp7;
+
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+ODEb21*h*DstateDt[i];
+  ODECallDerivative(ode,ode->t+ODEa2*h,tmpstate,ak2);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb31*DstateDt[i]+ODEb32*ak2[i]);
+  ODECallDerivative(ode,ode->t+ODEa3*h,tmpstate,ak3);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb41*DstateDt[i]+ODEb42*ak2[i]+ODEb43*ak3[i]);
+  ODECallDerivative(ode,ode->t+ODEa4*h,tmpstate,ak4);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb51*DstateDt[i]+
+          ODEb52*ak2[i]+ODEb53*ak3[i]+ODEb54*ak4[i]);
+  ODECallDerivative(ode,ode->t+ODEa5*h,tmpstate,ak5);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb61*DstateDt[i]+
+          ODEb62*ak2[i]+ODEb63*ak3[i]+ODEb64*ak4[i]+ODEb65*ak5[i]);
+  ODECallDerivative(ode,ode->t+ODEa6*h,tmpstate,ak6);
+
+  for (i=0;i<n;i++)
+    outstate[i]=state[i]+h*(ODEc1*DstateDt[i]+
+          ODEc3*ak3[i]+ODEc4*ak4[i]+ODEc6*ak6[i]);
+  for (i=0;i<n;i++)
+    stateerr[i]=h*(ODEdc1*DstateDt[i]+ODEdc3*ak3[i]+
+          ODEdc4*ak4[i]+ODEdc5*ak5[i]+ODEdc6*ak6[i]);
+}
+
+#define SAFETY 0.9
+#define PGROW  (-0.2)
+#define PSHRNK (-0.25)
+#define ERRCON 1.89e-4
+
+U0 ODERK5OneStep(CMathODE *ode)
+{
+  I64 i;
+  F64 errmax,tmp,*tmpstate=ode->tmp6,*stateerr=ode->tmp7;
+  while (TRUE) {
+    ode->h=Clamp(ode->h,ode->h_min,ode->h_max);
+    ODECashKarp(ode);
+    errmax=0.0;
+    for (i=0;i<ode->n_internal;i++) {
+      tmp=Abs(stateerr[i]/ode->state_scale[i]);
+      if (tmp>errmax)
+        errmax=tmp;
+    }
+    errmax/=ode->tolerance_internal;
+    if (errmax<=1.0 || ode->h==ode->h_min) break;
+    tmp=ode->h*SAFETY*errmax`PSHRNK;
+    if (tmp<0.1*ode->h)
+      ode->h*=0.1;
+    else
+      ode->h=tmp;
+  }
+  ode->t+=ode->h;
+  if (errmax>ERRCON)
+    ode->h*=SAFETY*errmax`PGROW;
+  else
+    ode->h*=5.0;
+  ode->h=Clamp(ode->h,ode->h_min,ode->h_max);
+  MemCpy(ode->state_internal,tmpstate,sizeof(F64)*ode->n_internal);
+}
+
+F64 ode_alloced_factor=0.75;
+
+U0 ODEsUpdate(CTask *task)
+{/* This routine is called by the window mgron a continuous
+basis to allow real-time simulation.  It is intended
+to provide ress good enough for games.  It uses a runge-kutta
+integrator which is a better algorithm than doing it with Euler.
+
+It is adaptive step-sized, so it slows down when an important
+event is taking place to improve accuracy, but in my implementation
+it has a timeout.
+*/
+  I64 i;
+  F64 d,start_time,timeout_time,t_desired,t_initial,interpolation;
+  CMathODE *ode;
+
+  if (task->next_ode==&task->next_ode)
+    task->last_ode_time=0;
+  else if (!Bt(&task->win_inhibit,WIf_SELF_ODE)) {
+//See GrUpdateTasks() and GrUpdateTaskODEs().
+    //We will not pick a time limit based on
+    //how busy the CPU is, what percent of the
+    //last refresh cycle was spent on ODE's
+    //and what the refresh cycle rate was.
+    start_time=tS;
+    d=1.0/winmgr.fps;
+    timeout_time=start_time+
+          (task->last_ode_time/d+0.1)/(winmgr.last_ode_time/d+0.1)*
+          ode_alloced_factor*d;
+    ode=task->next_ode;
+    while (ode!=&task->next_ode) {
+      t_initial=ode->t;
+      d=tS;
+      if (!(ode->flags&ODEF_STARTED)) {
+        ode->base_t=d;
+        ode->flags|=ODEF_STARTED;
+      }
+      d-=ode->base_t+t_initial;
+      t_desired=ode->t_scale*d+t_initial;
+      if (ode->flags&ODEF_PAUSED)
+        ode->base_t+=t_desired-ode->t; //Slip
+      else {
+        ode->flags|=ODEF_BUSY;
+        if (ode->flags&ODEF_PAUSED)
+          ode->base_t+=t_desired-ode->t; //Slip
+        else {
+          if (ode->derive || ode->mp_derive) {
+            if (ode->mp_derive)
+              ODEMPWake(ode);
+            ODEState2Internal(ode);
+            MemCpy(ode->initial_state,ode->state_internal,
+                  ode->n_internal*sizeof(F64));
+            while (ode->t<t_desired) {
+              ode->h_max=t_desired-ode->t;
+              ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+              for (i=0;i<ode->n_internal;i++)
+                ode->state_scale[i]=Abs(ode->state_internal[i])+
+                      Abs(ode->DstateDt[i]*ode->h)+ode->tolerance_internal;
+              ODERK5OneStep(ode);
+              if (tS>timeout_time) {
+                ode->base_t+=t_desired-ode->t; //Slip
+                goto ode_done;
+
+              }
+            }
+
+            //Interpolate if end time was not exact.
+            if (ode->t!=t_desired) {
+              if (interpolation=ode->t-t_initial) {
+                interpolation=(t_desired-t_initial)/interpolation;
+                if (interpolation!=1.0)
+                  for (i=0;i<ode->n_internal;i++)
+                    ode->state_internal[i]=(ode->state_internal[i]-
+                          ode->initial_state[i])*interpolation+
+                          ode->initial_state[i];
+              }
+              ode->t=t_desired;
+            }
+ode_done:
+            ODEInternal2State(ode);
+
+            //Convenience call to set vals
+            ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+
+            if (ode->mp_derive)
+              ODEMPSleep(ode);
+          }
+        }
+        ode->flags&=~ODEF_BUSY;
+      }
+      ode->base_t+=(1.0-ode->t_scale)*d;
+      ode=ode->next;
+    }
+
+    //Now, we will dynamically adjust tolerances.
+
+    //We will regulate the tolerances
+    //to fill the time we decided was
+    //okay to devote to ODE's.
+    //Since we might have multiple ODE's
+    //active we scale them by the same factor.
+
+    //This algorithm is probably not stable or very good, but it's something.
+
+    //Target is 75% of alloced time.
+    d=(tS-start_time)/(timeout_time-start_time)-0.75;
+
+    ode=task->next_ode;
+    while (ode!=&task->next_ode) {
+      if (!(ode->flags&ODEF_PAUSED) && ode->derive) {
+        if (ode->min_tolerance!=ode->max_tolerance) {
+          if (d>0)
+            ode->tolerance_internal*=10.0`d;
+          else
+            ode->tolerance_internal*=2.0`d;
+        }
+        ode->tolerance_internal=Clamp(ode->tolerance_internal,
+              ode->min_tolerance,ode->max_tolerance);
+      }
+      ode=ode->next;
+    }
+    winmgr.ode_time+=task->last_ode_time=tS-start_time;
+  }
+}
+
+ diff --git a/public/Wb/Adam/AMem.HC.HTML b/public/Wb/Adam/AMem.HC.HTML new file mode 100755 index 0000000..64e0d3c --- /dev/null +++ b/public/Wb/Adam/AMem.HC.HTML @@ -0,0 +1,210 @@ + + + + + + + + + + + +
+#help_index "Memory/Task"
+public I64 TaskMemAlloced(CTask *task=NULL,Bool override_validate=FALSE)
+{//Count of bytes alloced to a task, used+unused.
+  I64 res;
+  if (!task) task=Fs;
+  if (override_validate || TaskValidate(task)) {
+    res=task->code_heap->alloced_u8s;
+    if (task->code_heap!=task->data_heap)
+      res+=task->data_heap->alloced_u8s;
+    return res;
+  } else
+    return 0;
+}
+
+public I64 TaskMemUsed(CTask *task=NULL,Bool override_validate=FALSE)
+{//Count of bytes alloced to a task and in use.
+  I64 res;
+  if (!task) task=Fs;
+  if (override_validate || TaskValidate(task)) {
+    res=task->code_heap->used_u8s;
+    if (task->data_heap!=task->code_heap)
+      res+=task->data_heap->used_u8s;
+    return res;
+  } else
+    return 0;
+}
+
+#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
+public Bool HeapRep(CTask *task)
+{//Report status of task's heap.
+  I64 i,cnt;
+  CMemUnused *uum;
+
+  if (!task || task==Fs) {
+    "Task can't HeapRep on self.\n";
+    return FALSE;
+  }
+  if (!TaskValidate(task)) return FALSE;
+
+  PUSHFD
+  CLI
+  while (LBts(&task->code_heap->locked_flags,HClf_LOCKED))
+    PAUSE
+  if (task->data_heap!=task->code_heap)
+    while (LBts(&task->data_heap->locked_flags,HClf_LOCKED))
+      PAUSE
+
+  for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
+    cnt=0;
+    uum=task->code_heap->heap_hash[i];
+    while (uum) {
+      cnt+=uum->size;
+      uum=uum->next;
+    }
+    if (task->data_heap!=task->code_heap) {
+      uum=task->data_heap->heap_hash[i];
+      while (uum) {
+        cnt+=uum->size;
+        uum=uum->next;
+      }
+    }
+    if (cnt)
+      "%03X:%08X\n",i<<3,cnt;
+  }
+  '\n';
+
+  uum=task->code_heap->malloc_free_lst;
+  while (uum) {
+    "%X, ",uum->size;
+    uum=uum->next;
+  }
+  if (task->data_heap!=task->code_heap) {
+    uum=task->data_heap->malloc_free_lst;
+    while (uum) {
+      "%X, ",uum->size;
+      uum=uum->next;
+    }
+  }
+
+  if (task->data_heap!=task->code_heap)
+    LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
+  LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
+  POPFD
+
+  '\n';
+}
+
+#help_index "Memory/HeapCtrl;Debugging/Heap;Memory/Debugging"
+public Bool IsInHeapCtrl(U8 *a,CHeapCtrl *hc,Bool lock=TRUE)
+{//Check addr if in HeapCtrl.
+  CMemBlk *m;
+  PUSHFD
+  CLI
+  if (lock)
+    while (LBts(&hc->locked_flags,HClf_LOCKED))
+      PAUSE
+  m=hc->next_mem_blk;
+  while (m!=&hc->next_mem_blk) {
+    if (a>=m && a<m(U8 *)+m->pags<<MEM_PAG_BITS) {
+      if (lock)
+        LBtr(&hc->locked_flags,HClf_LOCKED);
+      POPFD
+      return TRUE;
+    }
+    m=m->next;
+  }
+  if (lock)
+    LBtr(&hc->locked_flags,HClf_LOCKED);
+  POPFD
+  return FALSE;
+}
+
+public Bool HeapCtrlWalk(CHeapCtrl *hc)
+{//Check integrity of HeapCtrl.
+  I64 i;
+  CMemUnused *uum;
+
+  PUSHFD
+  CLI
+  while (LBts(&hc->locked_flags,HClf_LOCKED))
+    PAUSE
+
+  for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
+    uum=hc->heap_hash[i];
+    while (uum) {
+      if (!IsInHeapCtrl(uum,hc,FALSE))
+        goto hc_false;
+      uum=uum->next;
+    }
+  }
+  uum=hc->malloc_free_lst;
+  while (uum) {
+    if (!IsInHeapCtrl(uum,hc,FALSE))
+      goto hc_false;
+    uum=uum->next;
+  }
+
+  #if _CFG_HEAP_DBG
+  CMemUsed *um,*um1;
+  um1=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
+  um=um1->next;
+  while (um!=um1) {
+    if (!IsInHeapCtrl(um,hc,FALSE))
+      goto hc_false;
+    um=um->next;
+  }
+#endif
+
+  LBtr(&hc->locked_flags,HClf_LOCKED);
+  POPFD
+  return TRUE;
+
+  hc_false:
+  LBtr(&hc->locked_flags,HClf_LOCKED);
+  POPFD
+  return FALSE;
+}
+
+#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
+public Bool IsInHeap(U8 *a,CTask *task=NULL,Bool lock=TRUE)
+{//Check addr if in task's heaps.
+  if (!task) task=Fs;
+  if (TaskValidate(task) && (IsInHeapCtrl(a,task->code_heap,lock)||
+        task->data_heap!=task->code_heap &&
+        IsInHeapCtrl(a,task->data_heap,lock)))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+public Bool HeapWalk(CTask *task=NULL)
+{//Check integrity of task's heaps.
+  if (!task) task=Fs;
+  if (!TaskValidate(task) || !HeapCtrlWalk(task->code_heap) ||
+        task->data_heap!=task->code_heap && !HeapCtrlWalk(task->data_heap))
+    return FALSE;
+  else
+    return TRUE;
+}
+
+ diff --git a/public/Wb/Adam/AMouse.HC.HTML b/public/Wb/Adam/AMouse.HC.HTML new file mode 100755 index 0000000..17f5253 --- /dev/null +++ b/public/Wb/Adam/AMouse.HC.HTML @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+#help_index "Graphics/Misc;Mouse/Ptr"
+
+<1>/* Graphics Not Rendered in HTML */
+
+gr.empty_sprite=<1>;
+
+<2>/* Graphics Not Rendered in HTML */
+
+<3>/* Graphics Not Rendered in HTML */
+
+public U0 DrawGrabMs(CDC *dc,I64 x,I64 y,Bool closed)
+{//This is a callback. See ::/Demo/Graphics/Grid.HC.
+  dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
+  dc->color=ROP_EQU;
+  if (closed)
+    Sprite3(dc,x,y,0,<2>);
+  else
+    Sprite3(dc,x,y,0,<3>);
+}
+gr.fp_draw_grab_ms=&DrawGrabMs;
+
+ diff --git a/public/Wb/Adam/ARegistry.HC.HTML b/public/Wb/Adam/ARegistry.HC.HTML new file mode 100755 index 0000000..ce02786 --- /dev/null +++ b/public/Wb/Adam/ARegistry.HC.HTML @@ -0,0 +1,234 @@ + + + + + + + + + + + +
+#help_index "Registry"
+#define REGISTRY_FILENAME "~/Registry.HC.Z"
+CDoc *sys_registry_doc=NULL;
+I64 sys_msg_flags[1]={0};
+F64 registry_version;
+
+Bool RegCache()
+{
+  Bool old_silent;
+  if (!sys_registry_doc) {
+    old_silent=Silent;
+    sys_registry_doc=DocRead(REGISTRY_FILENAME);
+    Silent(old_silent);
+    return FALSE;
+  } else
+    return TRUE;
+}
+
+public Bool RegDft(U8 *path,U8 *val,Bool is_adam_entry=FALSE)
+{//Add code doc tree branch to registry.
+  Bool res,unlock_doc;
+  RegCache;
+  unlock_doc=DocLock(sys_registry_doc);
+  if (!DocTreeFind(sys_registry_doc,path)) {
+    DocTreeMake(sys_registry_doc,path);
+    DocPrint(sys_registry_doc,"%s",val);
+    if (is_adam_entry) {
+      if (Fs==adam_task)
+        ExePrint("%s",val);
+      else
+        Adam("%s",val);
+    }
+    if (DrvIsWritable(*sys_registry_doc->filename.name))
+      DocWrite(sys_registry_doc);
+    res=FALSE;
+  } else
+    res=TRUE;
+  if (unlock_doc)
+    DocUnlock(sys_registry_doc);
+  return res;
+}
+
+public I64 RegExe(U8 *path)
+{//Execute doc tree branch in registry.
+  RegCache;
+  return DocTreeExe(sys_registry_doc,path);
+}
+
+public Bool RegWrite(U8 *path,U8 *fmt,...)
+{//Rewrite doc tree branch in registry.
+  Bool res;
+  RegCache;
+  res=DocTreeWriteJoin(sys_registry_doc,path,TRUE,fmt,argc,argv);
+  return res;
+}
+
+public I64 RegCnt(U8 *path)
+{//Tree branch cnt in registry.
+  I64 res=0;
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  Bool unlock_doc=DocLock(sys_registry_doc);
+  if (DocTreeFind(sys_registry_doc,path,
+        &tree_branch,&start_indent,&end_indent)) {
+    end_indent=end_indent->next;
+    while (start_indent!=end_indent) {
+      res++;
+      start_indent=start_indent->next;
+    }
+  }
+  if (unlock_doc)
+    DocUnlock(sys_registry_doc);
+  return res;
+}
+
+public Bool RegAppend(U8 *path,U8 *fmt,...)
+{//Append to doc tree branch in registry.
+  Bool res;
+  RegCache;
+  res=DocTreeAppendJoin(sys_registry_doc,path,TRUE,fmt,argc,argv);
+  return res;
+}
+ 
+public Bool OneTimePopUp(U8 *_flags,I64 flag_num,U8 *msg)
+{//See ::/Apps/X-Caliber/X-Caliber.HC.
+  Bool res=FALSE;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e;
+  if (!Bt(_flags,flag_num)) {
+    if (msg) DocPrint(doc,"%s",msg);
+    doc_e=DocPrint(doc,"\n$CB,\"Do not show this msg again.\",LE=1$");
+    DocPrint(doc,"$CM+CX,0,4$$BT,\"OKAY\",LE=1$\n");
+    if (PopUpMenu(doc)==1 && doc_e->de_flags&DOCEF_CHECKED_COLLAPSED) {
+      LBts(_flags,flag_num);
+      res=TRUE;
+    }
+    DocDel(doc);
+  }
+  return res;
+}
+
+U0 RegOneTimePopUp(I64 flag_num,U8 *msg)
+{//You're not supposed to make system pop-up flags, only me.
+  if (OneTimePopUp(sys_msg_flags,flag_num,msg))
+    RegWrite("Adam/SysMsgFlags","sys_msg_flags[0]=0x%X;\n",
+          sys_msg_flags[0]);
+}
+
+U0 RegInit()
+{
+  U8 buf[STR_LEN];
+  Bool version_present;
+  RegDft("Adam/SysMsgFlags","sys_msg_flags[0]=0;\n",TRUE);
+  StrPrint(buf,"registry_version=%4.3f;\n",sys_os_version);
+  version_present=RegDft("Adam/SysRegVer",buf,TRUE);
+  RegExe("Adam");
+  if (registry_version!=sys_os_version) {
+    RegWrite("Adam/SysRegVer",buf);
+    RegExe("Adam");
+  }
+}
+
+#help_index "Boot/Once;Registry/Once"
+#help_file "::/Doc/Once"
+
+public U0 AOnceFlush()
+{//Flush AOnce() buf.
+  RegWrite("Once/Adam","");
+}
+
+public U0 OnceFlush()
+{//Flush Once() buf.
+  RegWrite("Once/User","");
+}
+
+public U0 AOnce(U8 *fmt,...)
+{//Add Adam code to ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (!Bt(&sys_run_level,RLf_ONCE_ADAM))
+    AOnceFlush;
+  RegAppend("Once/Adam","%s\n",buf);
+  Free(buf);
+}
+
+public U0 Once(U8 *fmt,...)
+{//Add User code to ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (!Bt(&sys_run_level,RLf_ONCE_USER))
+    OnceFlush;
+  RegAppend("Once/User","%s\n",buf);
+  Free(buf);
+}
+
+public U0 AOnceDrv(U8 drv_let=0,U8 *fmt,...)
+{//Add Adam code to drv ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 old_drv_let=*sys_registry_doc->filename.name;
+  if (drv_let)
+    *sys_registry_doc->filename.name=drv_let;
+  if (!Bt(&sys_run_level,RLf_ONCE_ADAM))
+    AOnceFlush;
+  RegAppend("Once/Adam","%s\n",buf);
+  Free(buf);
+  *sys_registry_doc->filename.name=old_drv_let;
+}
+
+public U0 OnceDrv(U8 drv_let=0,U8 *fmt,...)
+{//Add User code to drv ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 old_drv_let=*sys_registry_doc->filename.name;
+  if (drv_let)
+    *sys_registry_doc->filename.name=drv_let;
+  if (!Bt(&sys_run_level,RLf_ONCE_USER))
+    OnceFlush;
+  RegAppend("Once/User","%s\n",buf);
+  Free(buf);
+  *sys_registry_doc->filename.name=old_drv_let;
+}
+
+public U0 OnceExe()
+{//Execute Once code. Call goes in ~/Once.HC.
+  try {
+
+    RegDft("Once/Adam","");
+    if (RegCnt("Once/Adam")>2) {
+      Adam("RegExe(\"Once/Adam\");");
+      AOnceFlush;
+    }
+    LBts(&sys_run_level,RLf_ONCE_ADAM);
+
+    RegDft("Once/User","");
+    if (RegCnt("Once/User")>2) {
+      RegExe("Once/User");
+      OnceFlush;
+    }
+    LBts(&sys_run_level,RLf_ONCE_USER);
+
+  } catch {
+    AOnceFlush;
+    LBts(&sys_run_level,RLf_ONCE_ADAM);
+    OnceFlush;
+    LBts(&sys_run_level,RLf_ONCE_USER);
+  }
+}
+
+ diff --git a/public/Wb/Adam/ASnd.HC.HTML b/public/Wb/Adam/ASnd.HC.HTML new file mode 100755 index 0000000..90ba6e8 --- /dev/null +++ b/public/Wb/Adam/ASnd.HC.HTML @@ -0,0 +1,440 @@ + + + + + + + + + + + +
+#help_index "Snd"
+public U0 SndTaskEndCB()
+{//Will turn-off snd when a task gets killed.
+  Snd;
+  Exit;
+}
+
+#help_index "Snd/Math;Math"
+public F64 Saw(F64 t,F64 period)
+{//Sawtooth. 0.0 - 1.0 think "(Sin+1)/2"
+  if (period) {
+    if (t>=0.0)
+      return t%period/period;
+    else
+      return 1.0+t%period/period;
+  } else
+    return 0.0;
+}
+
+public F64 FullSaw(F64 t,F64 period)
+{//Plus&Minus Sawtooth. 1.0 - -1.0 think "Sin"
+  if (period) {
+    if (t>=0.0)
+      return 2.0*(t%period/period)-1.0;
+    else
+      return 2.0*(t%period/period)+1.0;
+  } else
+    return 0.0;
+}
+
+public F64 Caw(F64 t,F64 period)
+{//Cawtooth. 1.0 - 0.0 think "(Cos+1)/2"
+  if (period) {
+    if (t>=0.0)
+      return 1.0-t%period/period;
+    else
+      return -(t%period)/period;
+  } else
+    return 1.0;
+}
+
+public F64 FullCaw(F64 t,F64 period)
+{//Plus&Minus Cawtooth. 1.0 - -1.0 think "Cos"
+  if (period) {
+    if (t>=0.0)
+      return -2.0*(t%period/period)+1.0;
+    else
+      return -2.0*(t%period/period)-1.0;
+  } else
+    return 1.0;
+}
+
+public F64 Tri(F64 t,F64 period)
+{//Triangle waveform. 0.0 - 1.0 - 0.0
+  if (period) {
+    t=2.0*(Abs(t)%period)/period;
+    if (t<=1.0)
+      return t;
+    else
+      return 2.0-t;
+  } else
+    return 0.0;
+}
+
+public F64 FullTri(F64 t,F64 period)
+{//Plus&Minus Triangle waveform. 0.0 - 1.0 - 0.0 - -1.0 -0.0
+  if (period) {
+    t=4.0*(t%period)/period;
+    if (t<=-1.0) {
+      if (t<=-3.0)
+        return t+4.0;
+      else
+        return -2.0-t;
+    } else {
+      if (t<=1.0)
+        return t;
+      else if (t<=3.0)
+        return 2.0-t;
+      else
+        return t-4.0;
+    }
+  } else
+    return 0.0;
+}
+
+#help_index "Snd/Music"
+
+public class CMusicGlbls
+{
+  U8    *cur_song;
+  CTask *cur_song_task;
+  I64   octave;
+  F64   note_len;
+  U8    note_map[7];
+  Bool  mute;
+  I64   meter_top,meter_bottom;
+  F64   tempo,stacatto_factor;
+
+  //If you wish to sync with a
+  //note in a Play() string.  0 is the start
+  I64   play_note_num;
+
+  F64   tM_correction,last_Beat,last_tM;
+} music={NULL,NULL,4,1.0,{0,2,3,5,7,8,10},FALSE,4,4,2.5,0.9,0,0,0,0};
+
+#help_index "Snd/Music;Time/Seconds"
+public F64 tM()
+{//Time in seconds synced to music subsystem.
+  return (cnts.jiffies+music.tM_correction)/JIFFY_FREQ;
+}
+
+public F64 Beat()
+{//Time in music beats.
+  F64 res,cur_tM;
+  PUSHFD
+  CLI
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_TMBEAT],0))
+      PAUSE
+  cur_tM=tM;
+  res=music.last_Beat;
+  if (music.tempo)
+    res+=(cur_tM-music.last_tM)*music.tempo;
+  music.last_tM=cur_tM;
+  music.last_Beat=res;
+  LBtr(&sys_semas[SEMA_TMBEAT],0);
+  POPFD
+  return res;
+}
+
+#help_index "Snd/Music"
+U8 *MusicSetOctave(U8 *st)
+{
+  I64 ch;
+  ch=*st++;
+  while ('0'<=ch<='9') {
+    music.octave=ch-'0';
+    ch=*st++;
+  }
+  return --st;
+}
+
+U8 *MusicSetMeter(U8 *st)
+{
+  I64 ch;
+  ch=*st++;
+  while (ch=='M') {
+    ch=*st++;
+    if ('0'<=ch<='9') {
+      music.meter_top=ch-'0';
+      ch=*st++;
+    }
+    if (ch=='/')
+      ch=*st++;
+    if ('0'<=ch<='9') {
+      music.meter_bottom=ch-'0';
+      ch=*st++;
+    }
+  }
+  return --st;
+}
+
+U8 *MusicSetNoteLen(U8 *st)
+{
+  Bool cont=TRUE;
+  do {
+    switch (*st++) {
+      case 'w': music.note_len=4.0;  break;
+      case 'h': music.note_len=2.0;  break;
+      case 'q': music.note_len=1.0;  break;
+      case 'e': music.note_len=0.5;   break;
+      case 's': music.note_len=0.25;   break;
+      case 't': music.note_len=2.0*music.note_len/3.0; break;
+      case '.': music.note_len=1.5*music.note_len; break;
+      default:
+        st--;
+        cont=FALSE;
+    }
+  } while (cont);
+  return st;
+}
+
+public I8 Note2Ona(I64 note,I64 octave=4)
+{//Note to ona. Mid C is ona=51, note=3 and octave=4.
+  if (note<3)
+    return (octave+1)*12+note;
+  else
+    return octave*12+note;
+}
+
+public I8 Ona2Note(I8 ona)
+{//Ona to note in octave. Mid C is ona=51, note=3 and octave=4.
+  return ona%12;
+}
+
+public I8 Ona2Octave(I8 ona)
+{//Ona to octave. Mid C is ona=51, note=3 and octave=4.
+  I64 note=ona%12,octave=ona/12;
+  if (note<3)
+    return octave-1;
+  else
+    return octave;
+}
+
+public U0 Play(U8 *st,U8 *words=NULL)
+{/* Notes are entered with a capital letter.
+
+Octaves are entered with a digit and
+stay set until changed.  Mid C is octave 4.
+
+Durations are entered with
+'w' whole note
+'h' half note
+'q' quarter note
+'e' eighth note
+'t' sets to 2/3rds the current duration
+'.' sets to 1.5 times the current duration
+durations stay set until changed.
+
+'(' tie, placed before the note to be extended
+
+music.meter_top,music.meter_bottom is set with
+"M3/4"
+"M4/4"
+etc.
+
+Sharp and flat are done with '#' or 'b'.
+
+The var music.stacatto_factor can
+be set to a range from 0.0 to 1.0.
+
+The var music.tempo is quarter-notes
+per second.  It defaults to
+2.5 and gets faster when bigger.
+*/
+  U8 *word,*last_st;
+  I64 note,octave,i=0,ona,timeout_val,timeout_val2;
+  Bool tie;
+  F64 d,on_jiffies,off_jiffies;
+  music.play_note_num=0;
+  while (*st) {
+    timeout_val=cnts.jiffies;
+    tie=FALSE;
+
+    do {
+      last_st=st;
+      if (*st=='(') {
+        tie=TRUE;
+        st++;
+      } else {
+        st=MusicSetMeter(st);
+        st=MusicSetOctave(st);
+        st=MusicSetNoteLen(st);
+      }
+    } while (st!=last_st);
+
+    if (!*st) break;
+    note=*st++-'A';
+    if (note<7) {
+      note=music.note_map[note];
+      octave=music.octave;
+      if (*st=='b') {
+        note--;
+        if (note==2)
+          octave--;
+        st++;
+      } else if (*st=='#') {
+        note++;
+        if (note==3)
+          octave++;
+        st++;
+      }
+      ona=Note2Ona(note,octave);
+    } else
+      ona=0;
+    if (words && (word=LstSub(i++,words)) && StrCmp(word," "))
+      "%s",word;
+
+    d=JIFFY_FREQ*music.note_len/music.tempo;
+    on_jiffies  =d*music.stacatto_factor;
+    off_jiffies =d*(1.0-music.stacatto_factor);
+
+    timeout_val+=on_jiffies;
+    timeout_val2=timeout_val+off_jiffies;
+
+    if (!music.mute)
+      Snd(ona);
+    SleepUntil(timeout_val);
+    music.tM_correction+=on_jiffies-ToI64(on_jiffies);
+
+    if (!music.mute && !tie)
+      Snd;
+    SleepUntil(timeout_val2);
+    music.tM_correction+=off_jiffies-ToI64(off_jiffies);
+
+    music.play_note_num++;
+  }
+}
+
+U0 MusicSettingsRst()
+{
+  music.play_note_num=0;
+  music.stacatto_factor=0.9;
+  music.tempo=2.5;
+  music.octave=4;
+  music.note_len=1.0;
+  music.meter_top=4;
+  music.meter_bottom=4;
+  SndRst;
+  PUSHFD
+  CLI
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_TMBEAT],0))
+      PAUSE
+  music.last_tM=tM;
+  music.last_Beat=0.0;
+  LBtr(&sys_semas[SEMA_TMBEAT],0);
+  POPFD
+}
+
+MusicSettingsRst;
+
+U0 CurSongTask()
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  while (TRUE)
+    Play(music.cur_song);
+}
+
+#help_index "Snd"
+
+#define SE_NOISE        0
+#define SE_SWEEP        1
+
+class CSoundEffectFrame
+{
+  I32   type;
+  I8    ona1,ona2;
+  F64   duration;
+};
+
+U0 SoundEffectEndTaskCB()
+{
+  Free(FramePtr("CSoundEffectFrame"));
+  music.mute--;
+  SndTaskEndCB;
+}
+
+U0 SoundEffectTask(CSoundEffectFrame *ns)
+{
+  I64 i,ona;
+  F64 t0=tS,t,timeout=t0+ns->duration;
+  FramePtrAdd("CSoundEffectFrame",ns);
+  Fs->task_end_cb=&SoundEffectEndTaskCB;
+  switch (ns->type) {
+    case SE_NOISE:
+      i=MaxI64(ns->ona2-ns->ona1,1);
+      while (tS<timeout) {
+        ona=RandU16%i+ns->ona1;
+        Snd(ona);
+        t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0);
+        if (t+tS>timeout)
+          t=timeout-tS;
+        Sleep(t);
+      }
+      break;
+    case SE_SWEEP:
+      while (tS<timeout) {
+        t=(tS-t0)/ns->duration;
+        ona=(1.0-t)*ns->ona1+t*ns->ona2;
+        Snd(ona);
+        t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0);
+        if (t+tS>timeout)
+          t=timeout-tS;
+        Sleep(t);
+      }
+      break;
+  }
+}
+
+public CTask *Noise(I64 mS,F64 min_ona,F64 max_ona)
+{//Make white noise for given number of mS.
+  CSoundEffectFrame *ns;
+  if (mS>0) {
+    ns=MAlloc(sizeof(CSoundEffectFrame));
+    ns->type=SE_NOISE;
+    ns->duration=mS/1000.0;
+    ns->ona1=min_ona;
+    ns->ona2=max_ona;
+    music.mute++;
+    return Spawn(&SoundEffectTask,ns,"Noise",,Fs);
+  } else
+    return NULL;
+}
+
+public CTask *Sweep(I64 mS,F64 ona1,F64 ona2)
+{//Sweep through freq range in given number of mS.
+  CSoundEffectFrame *ns;
+  if (mS>0) {
+    ns=MAlloc(sizeof(CSoundEffectFrame));
+    ns->type=SE_SWEEP;
+    ns->duration=mS/1000.0;
+    ns->ona1=ona1;
+    ns->ona2=ona2;
+    music.mute++;
+    return Spawn(&SoundEffectTask,ns,"Noise",,Fs);
+  } else
+    return NULL;
+}
+
+ diff --git a/public/Wb/Adam/AutoComplete/ACDictGen.HC.HTML b/public/Wb/Adam/AutoComplete/ACDictGen.HC.HTML new file mode 100755 index 0000000..1c787fb --- /dev/null +++ b/public/Wb/Adam/AutoComplete/ACDictGen.HC.HTML @@ -0,0 +1,292 @@ + + + + + + + + + + + +
+/*
+This file is a stand-alone program
+which will regenerate processed dictionary
+files from a raw Project Gutenberg
+dictionary file.
+
+See ::/Doc/Credits.DD.
+*/
+
+U0 ACDPreprocess(U8 *in_name,U8 *out_name)
+{/*
+<cr><nl>--> <nl>
+$       --> $$
+\'89    --> .
+*/
+  I64 ch,i;
+  U8 *src,*dst;
+  CDoc *doc;
+  CDocEntry *doc_e;
+  if (doc=DocRead(in_name,DOCF_PLAIN_TEXT_TABS|DOCF_DBL_DOLLARS)) {
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      if (doc_e->type_u8==DOCT_TEXT) {
+        src=dst=doc_e->tag;
+        while (ch=*src++) {
+          if (ch=='\\' && *src=='\'') {
+            src++;
+            i=0;
+            ch=ToUpper(*src++);
+            if ('0'<=ch<='9')
+              i+=ch-'0';
+            else if ('A'<=ch<='F')
+              i+=ch-'A'+10;
+            i<<=4;
+            ch=ToUpper(*src++);
+            if ('0'<=ch<='9')
+              i+=ch-'0';
+            else if ('A'<=ch<='F')
+              i+=ch-'A'+10;
+            *dst++=i;
+          } else
+            *dst++=ch;
+        }
+        *dst=0;
+      }
+      doc_e=doc_e->next;
+    }
+    StrCpy(doc->filename.name,out_name);
+    DocWrite(doc);
+    DocDel(doc);
+  }
+}
+
+I64 ACDNextCmd(U8 **_ptr)
+{
+  U8 *ptr=*_ptr,*ptr2;
+  I64 ch,res=-1;
+  do {
+    do {
+      if (!(ch=*ptr++)) goto ncmd_done;
+    } while (ch!='<');
+
+    ptr2=ptr;
+    do {
+      if (!(ch=*ptr2++)) goto ncmd_done;
+    } while (ch!='>');
+    *--ptr2=0;
+    res=LstMatch(ptr,"h1\0/h1\0def\0/def\0hw\0/hw\0tt\0/tt\0"
+          "ety\0@fld\0@cd\0@blockquote\0@wordforms\0@note\0@altname\0@chform\0"
+          "@cref\0@syn\0/ety\0@/fld\0@/cd\0@/blockquote\0@/wordforms\0@/note\0"
+          "@/altname\0@/chform\0@/cref\0@/syn\0");
+    *ptr2++='>';
+    ptr=ptr2;
+  } while (res<0);
+
+  ncmd_done:
+  *_ptr=ptr;
+  return res;
+}
+
+U8 *ACDNextEntry(U8 **_ptr)
+{
+  U8 *res,*ignore,*ptr=*_ptr,buf[ACD_BLK_SIZE],*out_ptr=buf;
+  I64 ch,l;
+  while (TRUE) {
+    while (TRUE) {
+      if (!(ch=*ptr++)) goto nentry_done;
+      if (ch!='<') {
+        *out_ptr++=ch;
+        if (ch=='$')
+          *out_ptr++=ch;
+      } else
+        break;
+    }
+    ignore="b>\0i>\0ppp>\0/b>\0/i>\0/p>\0"
+          "ets>\0col>\0spn>\0/ets>\0/col>\0/spn>\0er>\0as>\0cs>\0cd>\0ex>\0"
+          "/er>\0/as>\0/cs>\0/cd>\0/ex>\0"
+          "note>\0/note>\0blockquote>\0/blockquote>\0";
+    while (*ignore) {
+      l=StrLen(ignore);
+      if (!StrNCmp(ptr,ignore,l)) {
+        ptr+=l;
+        break;
+      } else
+        ignore+=l+1;
+    }
+    if (!*ignore)
+      break;
+  }
+nentry_done:
+  *out_ptr++=0;
+  res=StrNew(buf);
+  *_ptr=ptr-1;
+  return res;
+}
+
+I64 ACDCompareWords(U8 *e1,U8 *e2)
+{
+  return StrICmp(e1,e2);
+}
+
+U8 *ACDSortWords(U8 *start,I64 size,I64 word_cnt)
+{
+  U8 **ptr_array=MAlloc(sizeof(U8 *)*word_cnt),
+        *out_start=MAlloc(size),
+        *ptr=start,*ptr2;
+  I64 i=0;
+  while (*ptr) {
+    ptr_array[i++]=ptr;
+    ptr+=StrLen(ptr)+3;
+  }
+  "Sorting...\n"; Sleep(100);
+  QSortI64(ptr_array,word_cnt,&ACDCompareWords);
+  "Done...\n"; Sleep(100);
+
+  ptr=out_start;
+  for (i=0;i<word_cnt;i++) {
+    ptr2=ptr_array[i];
+    while (*ptr2)
+      *ptr++=*ptr2++;
+    *ptr++=*ptr2++; //zero
+    *ptr++=*ptr2++; //blk lo
+    *ptr++=*ptr2++; //blk hi
+  }
+  *ptr++=0;
+  return out_start;
+}
+
+U0 ACDGen(U8 *in_file)
+{
+  I64 cmd,size,word_cnt=0,largest_entry=0;
+  U8 *st,*in_ptr=FileRead(in_file,&size),*in_start=in_ptr,
+        *out_ptr=MAlloc(size),*out_start=out_ptr,
+        *word_ptr=MAlloc(size),*word_start=word_ptr,
+        *last_word="",*def_word_start=out_ptr,
+        *sorted_word_start;
+  U16 *d;
+  if (!in_ptr) return;
+  do {
+    cmd=ACDNextCmd(&in_ptr);
+    if (cmd==ACD_H1) {
+next_word:
+      if (out_ptr-def_word_start>largest_entry)
+        largest_entry=out_ptr-def_word_start;
+      def_word_start=out_ptr;
+      if (st=ACDNextEntry(&in_ptr)) {
+        if (*st) {
+          if (StrICmp(st,last_word)) {
+            word_cnt++;
+
+            *word_ptr++=ACD_WORD_CHAR;
+            last_word=word_ptr;
+            StrCpy(word_ptr,st);
+            word_ptr+=StrLen(st)+1;
+
+            d=word_ptr;
+            *d=(out_ptr-out_start)/ACD_BLK_SIZE;
+            word_ptr+=2;
+
+            *out_ptr++=ACD_WORD_CHAR;
+            StrCpy(out_ptr,st);
+            out_ptr+=StrLen(st)+1;
+          }
+          Free(st);
+
+          do {
+            do {
+              cmd=ACDNextCmd(&in_ptr);
+              if (cmd==ACD_H1)
+                goto next_word;
+            } while (cmd>=0 && !(cmd==ACD_DEF||cmd==ACD_PRONUNCIATION||
+                  cmd==ACD_POS||cmd==ACD_EXTRA));
+            if (cmd==ACD_DEF) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_DEF_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            } else if (cmd==ACD_PRONUNCIATION) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_PRONUNCIATION_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            } else if (cmd==ACD_POS) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_POS_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            } else if (cmd==ACD_EXTRA) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_EXTRA_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            }
+          } while (cmd==ACD_DEF||cmd==ACD_PRONUNCIATION||
+                cmd==ACD_POS||cmd==ACD_EXTRA);
+        } else
+          Free(st);
+      }
+    }
+  } while (cmd>=0);
+  *out_ptr++=ACD_END_CHAR;
+  *word_ptr++=ACD_END_CHAR;
+
+  Free(in_start);
+
+  "Blk Size      :%d\n",ACD_BLK_SIZE;
+  "Blk Cnt       :%04X\n",(out_ptr-out_start+ACD_BLK_SIZE-1)/ACD_BLK_SIZE;
+  "Largest Entry :%d\n",largest_entry;
+  "Word Count    :%d\n",word_cnt;
+
+  FileWrite(ACD_DEF_FILENAME,out_start,out_ptr-out_start);
+  "Def File Size :%d\n",out_ptr-out_start;
+
+  sorted_word_start=ACDSortWords(word_start,word_ptr-word_start,word_cnt);
+  FileWrite(ACD_WORD_FILENAME,sorted_word_start,word_ptr-word_start);
+  "Word File Size:%d\n",word_ptr-word_start;
+
+  Free(out_start);
+  Free(word_start);
+  Free(sorted_word_start);
+}
+
+Cd(__DIR__);
+ACDPreprocess("DICTIONARY.DD","DICTIONARY2.DD");
+ACDGen("DICTIONARY2.DD");
+
+ diff --git a/public/Wb/Adam/AutoComplete/ACFill.HC.HTML b/public/Wb/Adam/AutoComplete/ACFill.HC.HTML new file mode 100755 index 0000000..da4a8ad --- /dev/null +++ b/public/Wb/Adam/AutoComplete/ACFill.HC.HTML @@ -0,0 +1,257 @@ + + + + + + + + + + + +
+#help_index "AutoComplete/Dictionary"
+public U8 *ACDDefGet(U8 *st,I64 def_num=1)
+{//MAlloc str holding single dict definition of word.
+  CFile *f;
+  CHashGeneric *tmph;
+  U8 *res=NULL,*buf,*in_ptr,
+        *st2=MStrUtil(st,SUF_TO_UPPER);
+  tmph=HashFind(st2,ac.hash_table,HTT_DICT_WORD);
+  Free(st2);
+  if (tmph) {
+    if (f=FOpen(ACD_DEF_FILENAME,"r")) {
+      buf=MAlloc(ACD_BLK_SIZE*2+1);
+      buf[ACD_BLK_SIZE*2]=0; //terminate
+      FBlkRead(f,buf,tmph->user_data0*ACD_BLK_SIZE/BLK_SIZE,
+            ACD_BLK_SIZE*2/BLK_SIZE);
+      FClose(f);
+      in_ptr=buf;
+      while (in_ptr<buf+ACD_BLK_SIZE*2) {
+        while (*in_ptr!=ACD_WORD_CHAR && in_ptr<buf+ACD_BLK_SIZE*2)
+          in_ptr++;
+        if (*in_ptr++==ACD_WORD_CHAR) {
+          if (!StrICmp(st,in_ptr)) {
+            while (def_num && *in_ptr!=ACD_WORD_CHAR
+                  && in_ptr<buf+ACD_BLK_SIZE*2) {
+              if (*in_ptr==ACD_DEF_CHAR) {
+                if (!--def_num)
+                  break;
+                else
+                  in_ptr++;
+              } else
+                in_ptr++;
+            }
+            if (*in_ptr++==ACD_DEF_CHAR) {
+              res=StrNew(in_ptr);
+              break;
+            }
+          }
+        }
+      }
+      Free(buf);
+    }
+  }
+  return res;
+}
+
+public U8 *ACDDefsGet(U8 *st)
+{//MAlloc str with all dict definitions of word.
+  CFile *f;
+  CHashGeneric *tmph;
+  U8 *res=NULL,*buf,*in_ptr,*in_ptr2,
+        *st2=MStrUtil(st,SUF_TO_UPPER);
+  tmph=HashFind(st2,ac.hash_table,HTT_DICT_WORD);
+  Free(st2);
+  if (tmph) {
+    if (f=FOpen(ACD_DEF_FILENAME,"r")) {
+      buf=MAlloc(ACD_BLK_SIZE*2+1);
+      buf[ACD_BLK_SIZE*2]=0; //terminate
+      FBlkRead(f,buf,tmph->user_data0*ACD_BLK_SIZE/BLK_SIZE,
+            ACD_BLK_SIZE*2/BLK_SIZE);
+      FClose(f);
+      in_ptr=buf;
+      while (in_ptr<buf+ACD_BLK_SIZE*2) {
+        while (*in_ptr!=ACD_WORD_CHAR && in_ptr<buf+ACD_BLK_SIZE*2)
+          in_ptr++;
+        if (*in_ptr++==ACD_WORD_CHAR) {
+          if (!StrICmp(st,in_ptr)) {
+            in_ptr2=in_ptr;
+            in_ptr--;
+            while (*in_ptr2!=ACD_WORD_CHAR
+                  && in_ptr2<buf+ACD_BLK_SIZE*2) {
+              in_ptr2++;
+            }
+            res=MAlloc(in_ptr2+1-in_ptr);
+            MemCpy(res,in_ptr,in_ptr2-in_ptr);
+            res[in_ptr2-in_ptr]=ACD_END_CHAR;
+            break;
+          }
+        }
+      }
+      Free(buf);
+    }
+  }
+  return res;
+}
+
+/*Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block;
+*/
+public U8 *ACDWordPtAt(U8 *st)
+{//Point to word in word list.
+  I64 i;
+  U8 *start=acd.word_lst,*r=start,
+        *end=acd.word_lst+acd.word_lst_size;
+  if (!st || !*st)
+    return acd.word_lst;
+  if (acd.word_lst_size) {
+    while (start+3<end) {
+      r=(start+end)>>1;
+      while (TRUE) {
+        while (*r!=ACD_WORD_CHAR && r>acd.word_lst)
+          r--;
+        if ((r[2]==ACD_WORD_CHAR||r[1]==ACD_WORD_CHAR)&&r-3>acd.word_lst)
+          r--;
+        else
+          break;
+      }
+      if (*r==ACD_WORD_CHAR) {
+        i=StrICmp(st,r+1);
+        if (i<0)
+          end=r-1;
+        else if (i>0)
+          start=r+StrLen(r)+3;
+        else
+          return r;
+      } else
+        break;
+    }
+    r=(start+end)>>1;
+    while (TRUE) {
+      while (*r!=ACD_WORD_CHAR && r>acd.word_lst)
+        r--;
+      if ((r[2]==ACD_WORD_CHAR||r[1]==ACD_WORD_CHAR)&&r-3>acd.word_lst)
+        r--;
+      else
+        break;
+    }
+    if (*r==ACD_WORD_CHAR && StrICmp(st,r+1)>0)
+      r+=StrLen(r)+3;
+  }
+  if (*r==ACD_WORD_CHAR)
+    return r;
+  else
+    return acd.word_lst;
+}
+
+U0 ACDFillin(I64 n)
+{
+  U8 *s;
+  I64 len;
+  if (0<=n<acd.num_fillins) {
+    s=acd.fillins[n]+1;
+    len=StrLen(s);
+    if (len>ac.partial_len)
+      In(s+ac.partial_len);
+  }
+}
+
+public U0 ACDDefsPut(CDoc *doc=NULL,U8 *st,I64 num=-1)
+{//Put to doc a dictionary definition(s) of a word.
+  U8 *st2,*st3;
+  I64 ch,i=0;
+  if (!st) return;
+  if (*st==ACD_WORD_CHAR)
+    st++;
+  DocPrint(doc,"$WW,1$$RED$%s:$FG$\n\n",st);
+  if (num<0) {
+    if (st3=ACDDefsGet(st)) {
+      st2=st3;
+      while (ch=*st2++) {
+        switch (ch) {
+          case ACD_WORD_CHAR:
+            break;
+          case ACD_DEF_CHAR:
+            DocPrint(doc,"$GREEN$(%d)$FG$ %s\n",
+                  ++i,st2);
+            break;
+          case ACD_PRONUNCIATION_CHAR:
+            DocPrint(doc,"$LTGREEN$%s$FG$\n",st2);
+            break;
+          case ACD_POS_CHAR:
+            DocPrint(doc,"$BLACK$%s$FG$\n",st2);
+            break;
+          case ACD_EXTRA_CHAR:
+            DocPrint(doc,"$LTBLUE$%s$FG$\n",st2);
+            break;
+        }
+        st2+=StrLen(st2)+1;
+      }
+      Free(st3);
+    }
+  } else {
+    while (st2=ACDDefGet(st,++i)) {
+      if (i==num)
+        DocPrint(doc,"$GREEN$(%d)$FG$ %s\n",
+              i,st2);
+      Free(st2);
+    }
+  }
+}
+
+U0 ACDPopUpDef(U8 *st,I64 num=-1,CTask *parent=NULL)
+{
+  U8 *buf;
+  buf=MStrPrint("ACDDefsPut(DocPut,\"%s\",%d);View;",st,num);
+  PopUp(buf,parent);
+  Free(buf);
+}
+
+U0 ACDDef(I64 n,CTask *parent=NULL)
+{
+  if (0<=n<acd.num_fillins)
+    ACDPopUpDef(acd.fillins[n],-1,parent);
+}
+
+#help_index "AutoComplete"
+U0 ACFillIn(I64 n)
+{
+  U8 *s;
+  if (0<=--n<ac.num_fillins) {
+    s=ac.fillin_matches[n]->str;
+    if (StrLen(s)>ac.partial_len)
+      In(s+ac.partial_len);
+  }
+}
+
+U0 ACMan(I64 n,CTask *parent_task=NULL)
+{
+  CHashAC *tmpw;
+  CHashSrcSym *tmph;
+  if (0<=--n<ac.num_fillins && (tmpw=ac.fillin_matches[n]) &&
+        (tmph=HashFind(tmpw->str,Fs->hash_table,HTG_SRC_SYM)) &&
+        tmph->src_link)
+    PopUpEd(tmph->src_link,parent_task);
+}
+
+ diff --git a/public/Wb/Adam/AutoComplete/ACInit.HC.HTML b/public/Wb/Adam/AutoComplete/ACInit.HC.HTML new file mode 100755 index 0000000..e475f96 --- /dev/null +++ b/public/Wb/Adam/AutoComplete/ACInit.HC.HTML @@ -0,0 +1,200 @@ + + + + + + + + + + + +
+#help_index "AutoComplete/Dictionary"
+acd.has_words=FileFind(ACD_WORD_FILENAME);
+acd.has_defs =FileFind(ACD_DEF_FILENAME)||FileFind(ACD_DEF_FILENAME_Z);
+
+public U0 ACDWordsLoad()
+{//Put words from word list into hash table.
+  I64 size;
+  CHashGeneric *tmph;
+  U8 *in_ptr,*in_start,*st2;
+  U16 *d;
+  acd.num_words=0;
+  if (in_ptr=FileRead(ACD_WORD_FILENAME,&size)) {
+    in_start=in_ptr;
+    Free(acd.word_lst);
+    acd.word_lst=AMAlloc(size);
+    MemCpy(acd.word_lst,in_start,size);
+    acd.word_lst_size=size;
+
+    while (in_ptr<in_start+size) {
+      if (*in_ptr==ACD_WORD_CHAR)
+        in_ptr++;
+      if (*in_ptr) {
+        st2=MStrUtil(in_ptr,SUF_TO_UPPER);
+        tmph=ACAlloc(sizeof(CHashGeneric)+StrLen(st2)+1);
+        StrCpy(tmph+1,st2);
+        Free(st2);
+        in_ptr+=StrLen(in_ptr)+1;
+        tmph->str=tmph+1;
+        tmph->use_cnt=1;
+        tmph->type=HTT_DICT_WORD;
+        d=in_ptr;
+        tmph->user_data0=*d;
+        in_ptr+=2;
+        HashAdd(tmph,ac.hash_table);
+        acd.num_words++;
+      } else
+        in_ptr+=3;
+    }
+    Free(in_start);
+  }
+}
+
+#help_index "AutoComplete"
+CHashAC *ACHashAdd(U8 *w)
+{
+  CHashAC *tmpw=HashFind(w,ac.hash_table,HTT_WORD);
+  if (tmpw) {
+    tmpw->hits++;
+    return tmpw;
+  }
+  tmpw=ACAlloc(sizeof(CHashAC));
+  tmpw->str=AStrNew(w);
+  tmpw->type=HTT_WORD;
+  tmpw->use_cnt=1;
+  tmpw->hits=1;
+  HashAdd(tmpw,ac.hash_table);
+  ac.num_words++;
+  return tmpw;
+}
+
+U0 ACSingleFileAdd(U8 *buf)
+{
+  I64 ch;
+  U8 *ptr=buf,*ptr2,*ptr3;
+  while (TRUE) {
+    while (TRUE) {
+      if (ch=*ptr++) {
+        if (Bt(char_bmp_alpha_numeric,ch))
+          break;
+      } else
+        return;
+    }
+    ptr3=ptr;
+    ptr2=ptr;
+    ptr--;
+    while (TRUE) {
+      if (ch=*ptr2++) {
+        if (Bt(char_bmp_alpha_numeric,ch))
+          *ptr3++=ch;
+        else if (ch!=CH_CURSOR)
+          break;
+      } else {
+        ptr2--;
+        break;
+      }
+    }
+    *ptr3=0;
+    ACHashAdd(ptr);
+    ptr=ptr2;
+  }
+}
+
+U0 ACMainFileLstTraverse(U8 *files_find_mask)
+{
+  U8 *buf;
+  CDirEntry *tmpde,*tmpde1;
+  try {
+    tmpde=tmpde1=FilesFind(files_find_mask,
+          FUF_RECURSE|FUF_JUST_TXT|FUF_JUST_FILES|FUF_CLUS_ORDER);
+    while (tmpde) {
+      "%s\n",tmpde->full_name;
+      buf=FileRead(tmpde->full_name);
+      ACSingleFileAdd(buf);
+      Free(buf);
+      tmpde=tmpde->next;
+    }
+  } catch
+    Fs->catch_except=TRUE;
+  DirTreeDel(tmpde1);
+}
+
+U0 ACProgressTask(Bool *_start_flag)
+{
+  I64 start=blkdev.write_cnt;
+  progress1=0;
+  progress1_max=(Size(ACD_DEF_FILENAME_Z,"+x+s")+BLK_SIZE-1)>>BLK_SIZE_BITS;
+  StrCpy(progress1_desc,"Uncompressing Dictionary");
+  start=blkdev.write_cnt;
+  *_start_flag=TRUE;
+  while (progress1<progress1_max) {
+    progress1=blkdev.write_cnt-start;
+    Sleep(10);
+  }
+  *progress1_desc=progress1=progress1_max=0;
+}
+
+public U0 ACInit(U8 *mask=NULL)
+{//Read files and build AutoComplete statistics.
+  Bool start_flag;
+  CBlkDev *bd=Let2BlkDev;
+
+  LBtr(&sys_run_level,RLf_AUTO_COMPLETE);
+  AutoComplete;
+  while (LBts(&ac.flags,ACf_INIT_IN_PROGRESS))
+    Yield;
+  if (DrvIsWritable && FileFind(ACD_DEF_FILENAME_Z) &&
+        !FileFind(ACD_DEF_FILENAME)) {
+    if (bd->type!=BDT_RAM) {
+      start_flag=FALSE;
+      Spawn(&ACProgressTask,&start_flag);
+      while (!start_flag)
+        Yield;
+    }
+    Move(ACD_DEF_FILENAME_Z,ACD_DEF_FILENAME);
+  }
+
+  HashTableDel(ac.hash_table);
+  ac.hash_table=HashTableNew(2048,adam_task);
+
+  ac.num_words=0;
+  Free(ac.cur_word);
+  ac.cur_word=NULL;
+
+  if (mask)
+    ACMainFileLstTraverse(mask);
+
+  ACDWordsLoad;
+  LBtr(&ac.flags,ACf_INIT_IN_PROGRESS);
+  LBts(&sys_run_level,RLf_AUTO_COMPLETE);
+  AutoComplete(ON);
+}
+
+I64 AutoCompleteSize()
+{
+  if (ac.hash_table)
+    return HashTableSize2(ac.hash_table)+MSize2(acd.word_lst);
+  else
+    return 0;
+}
+
+ diff --git a/public/Wb/Adam/AutoComplete/ACTask.HC.HTML b/public/Wb/Adam/AutoComplete/ACTask.HC.HTML new file mode 100755 index 0000000..ebe2031 --- /dev/null +++ b/public/Wb/Adam/AutoComplete/ACTask.HC.HTML @@ -0,0 +1,314 @@ + + + + + + + + + + + +
+#help_index "AutoComplete/Dictionary"
+U0 ACDDictWordsAdd(U8 *st)
+{
+  I64 i;
+  U8 *ptr;
+  if (st && *st && (ptr=ACDWordPtAt(st))) {
+    for (i=0;i<ACD_FILLINS_NUM;i++) {
+      if (*ptr++!=ACD_WORD_CHAR)
+        break;
+      if (i) '\n';
+      acd.fillins[i]=ptr-1;
+      "$GREEN$'%d'$FG$ %-23ts",i,ptr;
+      ptr+=StrLen(ptr)+3;
+    }
+    acd.num_fillins=i;
+  }
+}
+
+#help_index "AutoComplete"
+U0 ACDocRst(I64 left,I64 top)
+{
+  CDoc *doc=DocPut;
+  DocRst(doc,TRUE);
+  doc->flags|=DOCF_SIZE_MIN;
+  Fs->border_src=BDS_CONST;
+  Fs->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  Fs->text_attr  =LTGRAY<<4+BLUE;
+  LBtr(&Fs->display_flags,DISPLAYf_SHOW);
+  WinHorz(left,Fs->win_right);
+  WinVert(top,Fs->win_bottom);
+  DocCursor;
+}
+
+I64 ACSkipCrap(U8 *src,I64 len)
+{
+  I64 j;
+  j=len-1;
+  while (j>=0) {
+    if (Bt(char_bmp_alpha_numeric,src[j]))
+      break;
+    else
+      j--;
+  }
+  return j+1;
+}
+
+I64 ACPriorWordInStr(U8 *src,U8 *dst,I64 len,I64 buf_size)
+{
+  I64 i,j=0,k;
+  i=len-1;
+  while (i>=0)
+    if (!Bt(char_bmp_alpha_numeric,src[i]))
+      break;
+    else
+      i--;
+  if (i>=-1 && len>0)
+    for (k=i+1;k<len && j<buf_size-1;k++)
+      dst[j++]=src[k];
+  dst[j]=0;
+  return i+1;
+}
+
+U0 ACFillInAdd(CHashAC *tmpw)
+{
+  I64 k;
+  if (ac.num_fillins<AC_FILLINS_NUM ||
+        tmpw->hits>ac.fillin_hits[ac.num_fillins-1]) {
+    for (k=ac.num_fillins-1;k>=0;k--) {
+      if (tmpw->hits<=ac.fillin_hits[k])
+        break;
+      else {
+        ac.fillin_matches[k+1]=ac.fillin_matches[k];
+        ac.fillin_hits[k+1]   =ac.fillin_hits[k];
+      }
+    }
+    ac.fillin_matches[k+1]=tmpw;
+    ac.fillin_hits[k+1]   =tmpw->hits;
+    if (ac.num_fillins<AC_FILLINS_NUM)
+      ac.num_fillins++;
+  }
+}
+
+U0 ACPutChoices(CDoc *focus_l,CDocEntry *doc_e,CTask *focus_task,
+        Bool force_refresh)
+{
+  I64 i,data_col;
+  U8 *buf,*buf1,*src=NULL,*st;
+  CHashAC *tmpw;
+  F64 timeout_time=tS+0.5;
+  CHashSrcSym *tmph;
+
+  src=DocScanLine(focus_l,doc_e,&data_col);
+  DocUnlock(focus_l);
+  i=StrLen(src);
+  buf =MAlloc(MaxI64(i+1,256));
+  buf1=MAlloc(MaxI64(i+1,256));
+  if (data_col==-1)
+    data_col=0;
+  data_col=ACPriorWordInStr(src,buf,data_col,256);
+  ac.partial_len=StrLen(buf);
+  data_col=ACSkipCrap(src,data_col);
+  data_col=ACPriorWordInStr(src,buf1,data_col,256);
+
+  if (!ac.cur_word || StrCmp(ac.cur_word,buf) || force_refresh) {
+    st=ac.cur_word;
+    ac.cur_word=AStrNew(buf);
+    Free(st);
+    ac.num_fillins=0;
+    if (*ac.cur_word)
+      for (i=0;i<=ac.hash_table->mask && tS<timeout_time;i++) {
+        tmpw=ac.hash_table->body[i];
+        while (tmpw) {
+          if (!MemCmp(ac.cur_word,tmpw->str,StrLen(ac.cur_word)))
+            ACFillInAdd(tmpw);
+          tmpw=tmpw->next;
+        }
+      }
+    ACDocRst(51,13);
+    if (ac.cur_word && *ac.cur_word) {
+      "$PURPLE$Word:%s$FG$\n",ac.cur_word;
+      for (i=0;i<ac.num_fillins;i++) {
+        st=ac.fillin_matches[i]->str;
+        "$GREEN$F%02d$FG$ ",i+1;
+        if (TaskValidate(focus_task) &&
+              (tmph=HashFind(st,focus_task->hash_table,HTG_SRC_SYM)) &&
+              tmph->src_link) {
+          if (tmph->type&HTF_PUBLIC)
+            "$RED$";
+          "$TX+UL+L+PU,\"%$Q\",A=\"%s\"$$FG$\n",st,tmph->src_link;
+        } else
+          "%s\n",st;
+      }
+      if (acd.has_words)
+        ACDDictWordsAdd(ac.cur_word);
+    } else if (FileFind("::/Doc/StandBy.DD.Z"))
+      Type("::/Doc/StandBy.DD.Z",0);
+  }
+  Free(src);
+  Free(buf);
+  Free(buf1);
+}
+
+U0 ACTaskNormal(I64 sc,I64 last_sc,
+        CTask *focus_task,CTask *original_focus_task)
+{
+  CDoc *doc;
+  CDocEntry *doc_e;
+  if ((doc=DocPut(focus_task)) &&
+        focus_task!=Fs && Bt(&focus_task->display_flags,DISPLAYf_SHOW)) {
+    DocLock(doc);
+    if (TaskValidate(focus_task) && original_focus_task==sys_focus_task &&
+          doc && doc==DocPut(focus_task) && (doc_e=doc->cur_entry)) {
+      if (doc_e==doc) doc_e=doc_e->last;
+      while (doc_e->last!=doc && (doc_e->type_u8==DOCT_NEW_LINE ||
+            doc_e->type_u8==DOCT_SOFT_NEW_LINE))
+        doc_e=doc_e->last;
+      while (doc_e->last->type_u8!=DOCT_NEW_LINE && doc_e->last!=doc)
+        doc_e=doc_e->last;
+      ACPutChoices(doc,doc_e,focus_task,ToBool(sc!=last_sc));
+    } else
+      DocUnlock(doc);
+  }
+  if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+    WinZBufUpdate;
+}
+
+U0 ACTaskCtrl(I64 sc,I64 last_sc,
+        CTask *focus_task,CTask *original_focus_task)
+{
+  if (TaskValidate(focus_task) &&
+        (focus_task->scroll_x || focus_task->scroll_y)) {
+    if (LBtr(&Fs->display_flags,DISPLAYf_SHOW))
+      WinZBufUpdate;
+  } else {
+    if (sc!=last_sc) {
+      if (sc&SCF_ALT) {
+        ACDocRst(27,3);
+        if (TaskValidate(original_focus_task) &&
+              !Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC))
+          KeyMapFamily(original_focus_task,0,
+                ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+        KeyMapCtrlAltFamily(
+              ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+      } else if (TaskValidate(original_focus_task) &&
+            !Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC)) {
+        ACDocRst(27,3);
+        KeyMapFamily(original_focus_task,SCF_CTRL,
+              ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+      }
+    }
+    if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+      WinZBufUpdate;
+  }
+}
+
+U0 ACTaskAlt(I64 sc,I64 last_sc,
+        CTask *,CTask *original_focus_task)
+{
+  if (sc!=last_sc && TaskValidate(original_focus_task) &&
+        !Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC)) {
+    ACDocRst(27,3);
+    KeyMapFamily(original_focus_task,SCF_ALT,
+          ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+  }
+  if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+    WinZBufUpdate;
+}
+
+U0 ACTaskEndCB()
+{
+  ac.task=NULL;
+  Exit;
+}
+
+U0 ACTask(I64)
+{
+  CTask *focus_task,*original_focus_task;
+  I64 ch,scan_code=0,last_scan_code=0;
+  CDoc *doc;
+  Fs->task_end_cb=&ACTaskEndCB;
+  DocTermNew;
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinHorz(51,Fs->win_right);
+  LBts(&Fs->display_flags,DISPLAYf_WIN_ON_TOP);
+  Fs->win_inhibit=WIG_NO_FOCUS_TASK_DFT;
+  Free(ac.cur_word);
+  ac.cur_word=NULL;
+  while (TRUE) {
+    if (scan_code&(SCF_CTRL|SCF_ALT) ||
+          GetTSC>KbdMsEvtTime+cnts.time_stamp_freq>>1) {
+      last_scan_code=scan_code;
+      scan_code=kbd.scan_code;
+    }
+    original_focus_task=focus_task=sys_focus_task;
+    while (TaskValidate(focus_task) &&
+          Bt(&focus_task->task_flags,TASKf_INPUT_FILTER_TASK))
+      focus_task=focus_task->parent_task;
+    if (scan_code&SCF_CTRL)
+      ACTaskCtrl(scan_code,last_scan_code,focus_task,original_focus_task);
+     else if (TaskValidate(focus_task)) {
+      if (scan_code&SCF_ALT)
+        ACTaskAlt(scan_code,last_scan_code,focus_task,original_focus_task);
+      else
+        ACTaskNormal(scan_code,last_scan_code,focus_task,original_focus_task);
+    }
+    Sleep(333);
+    if (ScanMsg(&ch,,1<<MSG_KEY_DOWN) && (ch==CH_ESC||ch==CH_SHIFT_ESC))
+      break;
+    doc=DocPut;
+    DocLock(doc);
+    if (doc->cur_entry->de_flags & DOCEF_LINK) {
+      '' CH_SPACE;
+      doc->cur_entry=doc;
+    }
+    DocUnlock(doc);
+  }
+}
+
+public Bool AutoComplete(Bool val=OFF)
+{//Turn AutoComplete OFF or ON.
+  Bool  old_val=FALSE;
+  while (Bt(&ac.flags,ACf_INIT_IN_PROGRESS))
+    Sleep(10);
+  if (val) {
+    if (Bt(&sys_run_level,RLf_AUTO_COMPLETE)) {
+      if (TaskValidate(ac.task))
+        old_val=TRUE;
+      else {
+        ac.task=Spawn(&ACTask,NULL,"AutoComplete");
+        TaskWait(ac.task);
+      }
+      WinToTop(ac.task);
+    }
+  } else {
+    if (TaskValidate(ac.task)) {
+      if (Bt(&sys_run_level,RLf_AUTO_COMPLETE))
+        old_val=TRUE;
+      Kill(ac.task);
+      DeathWait(&ac.task);
+    }
+  }
+  return old_val;
+}
+
+ diff --git a/public/Wb/Adam/AutoComplete/MakeAC.HC.HTML b/public/Wb/Adam/AutoComplete/MakeAC.HC.HTML new file mode 100755 index 0000000..6f6c714 --- /dev/null +++ b/public/Wb/Adam/AutoComplete/MakeAC.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+//See ::/Doc/AutoComplete.DD
+Cd(__DIR__);;
+#include "ACFill"
+#include "ACTask"
+#include "ACInit"
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/CPURep.HC.HTML b/public/Wb/Adam/CPURep.HC.HTML new file mode 100755 index 0000000..1e54e86 --- /dev/null +++ b/public/Wb/Adam/CPURep.HC.HTML @@ -0,0 +1,103 @@ + + + + + + + + + + + +
+#help_index "Info;Time/CPU Cycles;Processor"
+class CCPURep
+{
+  Bool mp_start,mp_end;
+  I64 mp_not_done_flags,
+      **swaps,
+      **cycles;
+};
+
+U0 MPCPURep(CCPURep *cr)
+{
+  I64 swaps=0,cycles_0,cycles_f;
+  while (!cr->mp_start)
+    Yield;
+  cycles_0=GetTSC;
+  while (!cr->mp_end) {
+    swaps++;
+    Yield;
+  }
+  cycles_f=GetTSC;
+  cr->swaps[Gs->num]=swaps;
+  cr->cycles[Gs->num]=cycles_f-cycles_0;
+  LBtr(&cr->mp_not_done_flags,Gs->num);
+}
+
+public U0 CPURep(Bool full=FALSE)
+{//Report number of cores and clock freq.
+  I64 i,total_swaps,total_cycles;
+  F64 t0,tf;
+  CCPURep cr;
+
+  if (!full)
+    "%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
+  else {
+    cr.swaps=CAlloc(sizeof(I64)*mp_cnt);
+    cr.cycles=CAlloc(sizeof(I64)*mp_cnt);
+    cr.mp_start=cr.mp_end=FALSE;
+    cr.mp_not_done_flags=1<<mp_cnt-1;
+    for (i=0;i<mp_cnt;i++)
+      Spawn(&MPCPURep,&cr,NULL,i);
+
+    t0=tS;
+    cr.mp_start=TRUE;
+    Sleep(2000);
+    cr.mp_end=TRUE;
+    while (cr.mp_not_done_flags)
+      Yield;
+    tf=tS;
+
+    "\n%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
+    "\n         Context\n"
+          "CPU     Swaps/s         Cycles\n"
+          "--- ------------- -----------------\n";
+    total_swaps=0;
+    total_cycles=0;
+    for (i=0;i<mp_cnt;i++) {
+      " %02X %13,d %17,d\n",i,
+            ToI64(cr.swaps[i]/(tf-t0)),ToI64(cr.cycles[i]/(tf-t0));
+      total_swaps+=cr.swaps[i];
+      total_cycles+=cr.cycles[i];
+    }
+    "--- ------------- -----------------\n";
+    "%03X %13,d %17,d\n",i,
+          ToI64(total_swaps/(tf-t0)),ToI64(total_cycles/(tf-t0));
+    "Avg %13,d %17,d\n\n",
+          ToI64(total_swaps/(tf-t0)/i),ToI64(total_cycles/(tf-t0)/i);
+    "Avg Cycles/Swap: %12.6f\n",ToF64(total_cycles)/total_swaps;
+    "Avg Time/Swap  : %12.6fns\n\n",(tf-t0)*1000000000.0*i/total_swaps;
+    Free(cr.swaps);
+    Free(cr.cycles);
+  }
+}
+
+ diff --git a/public/Wb/Adam/Ctrls/CtrlsA.HC.HTML b/public/Wb/Adam/Ctrls/CtrlsA.HC.HTML new file mode 100755 index 0000000..df8516c --- /dev/null +++ b/public/Wb/Adam/Ctrls/CtrlsA.HC.HTML @@ -0,0 +1,419 @@ + + + + + + + + + + + +
+public CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type)
+{//Find task ctrl given ctrl_type.
+  CCtrl *c;
+  c=haystack_task->next_ctrl;
+  while (c!=&haystack_task->next_ctrl) {
+    if (c->type==needle_type)
+      return c;
+    c=c->next;
+  }
+  return NULL;
+}
+
+U0 CtrlsUpdate(CTask *task)
+{
+  CCtrl *c;
+  c=task->next_ctrl;
+  while (c!=&task->next_ctrl) {
+    if (c->update_derived_vals)
+      (*c->update_derived_vals)(c);
+    if (c->flags&CTRLF_BORDER) {
+      c->scrn_left  =gr.pan_text_x+task->pix_left+c->left-FONT_WIDTH;
+      c->scrn_right =gr.pan_text_x+task->pix_left+c->right-FONT_WIDTH;
+      c->scrn_top   =gr.pan_text_y+task->pix_top+c->top-FONT_HEIGHT;
+      c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom-FONT_HEIGHT;
+    } else {
+      c->scrn_left  =gr.pan_text_x+task->pix_left+c->left;
+      c->scrn_right =gr.pan_text_x+task->pix_left+c->right;
+      c->scrn_top   =gr.pan_text_y+task->pix_top+c->top;
+      c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom;
+    }
+    c=c->next;
+  }
+}
+
+fp_update_ctrls=&CtrlsUpdate;
+
+Bool CtrlInsideRect(CCtrl *c,I64 x,I64 y)
+{//scrn coordinates
+  if (c->scrn_left<=x<=c->scrn_right &&
+        c->scrn_top<=y<=c->scrn_bottom)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+public Bool CtrlInside(CCtrl *c,I64 x,I64 y)
+{//Is x,y inside a ctrl?
+  if (c->flags&CTRLF_SHOW) {
+    if (c->inside_ctrl)
+      return (*c->inside_ctrl)(c,x,y);
+    else
+      return CtrlInsideRect(c,x,y);
+  } else
+    return FALSE;
+}
+
+U0 DrawCtrls(CTask *task)
+{
+  CCtrl *c;
+  CDC *dc=DCAlias(gr.dc2,task);
+  c=task->next_ctrl;
+  while (c!=&task->next_ctrl) {
+    if (c->flags&CTRLF_SHOW) {
+      if (c->flags&CTRLF_BORDER) {
+        if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
+          PUSHFD
+          CLI
+          while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+            PAUSE
+
+          task->win_left--; //Allow drawing on border
+          task->win_right++;
+          task->win_top--;
+          task->win_bottom++;
+          WinDerivedValsUpdate(task);
+
+          LBtr(&task->task_flags,TASKf_TASK_LOCK);
+          POPFD
+
+          if (c->draw_it)
+            (*c->draw_it)(dc,c);
+
+          PUSHFD
+          CLI
+          while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+            PAUSE
+
+          task->win_left++;
+          task->win_right--;
+          task->win_top++;
+          task->win_bottom--;
+          WinDerivedValsUpdate(task);
+
+          LBtr(&task->task_flags,TASKf_TASK_LOCK);
+          POPFD
+        }
+      } else
+        if (c->draw_it)
+          (*c->draw_it)(dc,c);
+    }
+    c=c->next;
+  }
+  DCDel(dc);
+}
+
+#define WIN_SCROLL_SIZE         8
+#define WIN_SCROLL_BORDER_BONUS 4
+U0 DrawWinScroll(CDC *dc,CCtrl *c)
+{
+  CWinScroll *s=c->state;
+
+  if (c->flags&CTRLF_CLICKED)
+    dc->color=s->color>>4;
+  else
+    dc->color=s->color&0xF;
+  GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
+
+  if (c->flags&CTRLF_CLICKED)
+    dc->color=s->color&0xF;
+  else
+    dc->color=s->color>>4;
+  GrRect(dc,c->left+2,c->top+2,c->right-c->left+1-4,c->bottom-c->top+1-4);
+}
+
+U0 WinDerivedScrollValsUpdate(CCtrl *c)
+{
+  CWinScroll *s=c->state;
+  I64 range;
+  if (s->max<s->min) s->max=s->min;
+  if (s->pos<s->min) s->pos=s->min;
+  if (s->pos>s->max) s->pos=s->max;
+  s->color=c->win_task->border_attr&0xF^0xF+
+        (c->win_task->border_attr&0xF)<<4;
+  range=s->max-s->min;
+  if (!range) range=1;
+  switch (c->type) {
+    case CTRLT_WIN_HSCROLL:
+      c->left  =gr.pan_text_x+FONT_WIDTH-WIN_SCROLL_BORDER_BONUS+
+            (s->pos-s->min)*(c->win_task->pix_width+2*WIN_SCROLL_BORDER_BONUS
+            -WIN_SCROLL_SIZE)/range;
+      c->right =c->left+WIN_SCROLL_SIZE-1;
+      c->top   =gr.pan_text_y+FONT_HEIGHT+
+            (FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_height;
+      c->bottom=c->top+WIN_SCROLL_SIZE-1;
+      break;
+    case CTRLT_WIN_VSCROLL:
+      c->left  =gr.pan_text_x+FONT_WIDTH+
+            (FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_width;
+      c->right =c->left+WIN_SCROLL_SIZE-1;
+      c->top   =gr.pan_text_y+FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS+
+            (s->pos-s->min)*(c->win_task->pix_height+
+            2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE)/range;
+      c->bottom=c->top+WIN_SCROLL_SIZE-1;
+      break;
+  }
+}
+
+U0 LeftClickHWinScroll(CCtrl *c,I64 x,I64,Bool down)
+{
+  CTask *task=c->win_task;
+  CWinScroll *s=c->state;
+  I64 range=task->pix_width+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
+  LBts(&s->flags,WSSf_SET_TO_POS);
+  s->pos=((x-(FONT_WIDTH-WIN_SCROLL_BORDER_BONUS))
+  *(s->max-s->min+1)+range/2)/range+s->min;
+  if (down)
+    c->flags|=CTRLF_CLICKED;
+  else
+    c->flags&=~CTRLF_CLICKED;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+U0 LeftClickVWinScroll(CCtrl *c,I64,I64 y,Bool down)
+{
+  CTask *task=c->win_task;
+  CWinScroll *s=c->state;
+  I64 range=task->pix_height+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
+  LBts(&s->flags,WSSf_SET_TO_POS);
+  s->pos=((y-(FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS))
+  *(s->max-s->min+1)+range/2)/range+s->min;
+  if (down)
+    c->flags|=CTRLF_CLICKED;
+  else
+    c->flags&=~CTRLF_CLICKED;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+U0 WheelChangeWinScroll(CCtrl *c,I64 delta)
+{
+  CWinScroll *s=c->state;
+  LBts(&s->flags,WSSf_SET_TO_POS);
+  s->pos+=delta;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+U0 WinScrollsInit(CTask *task)
+{
+  CCtrl *c;
+
+  if (!CtrlFindUnique(task,CTRLT_WIN_HSCROLL)) {
+    c=CAlloc(sizeof(CCtrl));
+    c->win_task=task;
+    c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
+    c->type=CTRLT_WIN_HSCROLL;
+    c->state=&task->horz_scroll;
+    c->update_derived_vals=&WinDerivedScrollValsUpdate;
+    c->draw_it=&DrawWinScroll;
+    c->left_click=&LeftClickHWinScroll;
+    QueIns(c,task->last_ctrl);
+  }
+
+  if (!CtrlFindUnique(task,CTRLT_WIN_VSCROLL)) {
+    c=CAlloc(sizeof(CCtrl));
+    c->win_task=task;
+    c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
+    c->type=CTRLT_WIN_VSCROLL;
+    c->state=&task->vert_scroll;
+    c->update_derived_vals=&WinDerivedScrollValsUpdate;
+    c->draw_it=&DrawWinScroll;
+    c->left_click=&LeftClickVWinScroll;
+    c->wheel_chg=&WheelChangeWinScroll;
+    QueIns(c,task->last_ctrl);
+  }
+  TaskDerivedValsUpdate(task);
+}
+#define VIEWANGLES_SPACING      22
+#define VIEWANGLES_RANGE        48
+#define VIEWANGLES_BORDER       2
+#define VIEWANGLES_SNAP         2
+
+U0 DrawViewAnglesCtrl(CDC *dc,CCtrl *c)
+{
+  I64 i,j;
+  CViewAngles *s=c->state;
+
+  dc->color=s->cbd;
+  GrRect(dc, c->left,c->top,VIEWANGLES_SPACING*4+3,
+        VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
+  dc->color=s->cbg;
+  GrRect(dc, c->left+VIEWANGLES_BORDER,c->top+VIEWANGLES_BORDER,
+        VIEWANGLES_SPACING*4+3-2*VIEWANGLES_BORDER,
+        VIEWANGLES_SPACING*2+VIEWANGLES_RANGE-2*VIEWANGLES_BORDER);
+  dc->color=s->cfg;
+  GrLine(dc,c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING,
+        c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING+
+        VIEWANGLES_RANGE-1);
+  GrLine(dc,c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING,
+        c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING+
+        VIEWANGLES_RANGE-1);
+  GrLine(dc,c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING,
+        c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING+
+        VIEWANGLES_RANGE-1);
+  for (i=1;i<VIEWANGLES_RANGE+1;i+=2*VIEWANGLES_SNAP) {
+    j=2-i/3&1;
+    GrLine(dc,c->left+VIEWANGLES_SPACING-j,c->bottom-VIEWANGLES_SPACING-i,
+          c->left+VIEWANGLES_SPACING+j,c->bottom
+          -VIEWANGLES_SPACING-i);
+    GrLine(dc,c->left+2*VIEWANGLES_SPACING+1-j,c->bottom-VIEWANGLES_SPACING-i,
+          c->left+2*VIEWANGLES_SPACING+1+j,c->bottom
+          -VIEWANGLES_SPACING-i);
+    GrLine(dc,c->left+3*VIEWANGLES_SPACING+2-j,c->bottom-VIEWANGLES_SPACING-i,
+          c->left+3*VIEWANGLES_SPACING+2+j,c->bottom
+          -VIEWANGLES_SPACING-i);
+  }
+
+  dc->color=s->cx;
+  GrPrint(dc,c->left+VIEWANGLES_SPACING-FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"X");
+  GrPrint(dc,c->left+VIEWANGLES_SPACING-3*FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
+        "%3d",s->sx*360/VIEWANGLES_RANGE);
+  i=c->left+VIEWANGLES_SPACING;
+  if (s->sx>VIEWANGLES_RANGE/2)
+    j=-VIEWANGLES_RANGE/2+s->sx;
+  else
+    j=s->sx+VIEWANGLES_RANGE/2;
+  j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
+  GrRect(dc,i-3,j-2,7,5);
+  dc->color=s->cx^8;
+  GrRect(dc,i-2,j-1,5,3);
+
+  dc->color=s->cy;
+  GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Y");
+  GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-3*FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
+        "%3d",s->sy*360/VIEWANGLES_RANGE);
+  i=c->left+2*VIEWANGLES_SPACING+1;
+  if (s->sy>VIEWANGLES_RANGE/2)
+    j=-VIEWANGLES_RANGE/2+s->sy;
+  else
+    j=s->sy+VIEWANGLES_RANGE/2;
+  j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
+  GrRect(dc,i-3,j-2,7,5);
+  dc->color=s->cy^8;
+  GrRect(dc,i-2,j-1,5,3);
+
+  dc->color=s->cz;
+  GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Z");
+  GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-3*FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
+        "%3d",s->sz*360/VIEWANGLES_RANGE);
+  i=c->left+3*VIEWANGLES_SPACING+2;
+  if (s->sz>VIEWANGLES_RANGE/2)
+    j=-VIEWANGLES_RANGE/2+s->sz;
+  else
+    j=s->sz+VIEWANGLES_RANGE/2;
+  j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
+  GrRect(dc,i-3,j-2,7,5);
+  dc->color=s->cz^8;
+  GrRect(dc,i-2,j-1,5,3);
+}
+
+U0 UpdateDerivedViewAnglesCtrl(CCtrl *c)
+{
+  CViewAngles *s=c->state;
+  c->left=c->win_task->pix_width-(VIEWANGLES_SPACING*4+3);
+  c->right=c->left+VIEWANGLES_SPACING*4+3;
+  c->top=c->win_task->pix_height-(VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
+  c->bottom=c->top+VIEWANGLES_SPACING*2+VIEWANGLES_RANGE;
+  s->sx=ClampI64(RoundI64(s->sx,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
+  s->sy=ClampI64(RoundI64(s->sy,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
+  s->sz=ClampI64(RoundI64(s->sz,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
+  s->ax=2*pi*s->sx/VIEWANGLES_RANGE;
+  s->ay=2*pi*s->sy/VIEWANGLES_RANGE;
+  s->az=2*pi*s->sz/VIEWANGLES_RANGE;
+}
+
+U0 LeftClickViewAngles(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CViewAngles *s=c->state;
+  I64 i;
+  i=VIEWANGLES_RANGE-1-(y-(c->top+VIEWANGLES_SPACING));
+  if (i>=VIEWANGLES_RANGE/2)
+    i-=VIEWANGLES_RANGE/2;
+  else
+    i+=VIEWANGLES_RANGE/2;
+  if (x<c->left+(c->right-c->left)/3)
+    s->sx=i;
+  else if (x<c->left+2*(c->right-c->left)/3)
+    s->sy=i;
+  else
+    s->sz=i;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+public CCtrl *ViewAnglesNew(CTask *task=NULL)
+{//Create view angle ctrl. See ::/Demo/Graphics/Shading.HC.
+  CCtrl *c;
+  CViewAngles *s;
+  if (!task) task=Fs;
+  if (!(c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES))) {
+    s=CAlloc(sizeof(CViewAngles),task);
+    c=CAlloc(sizeof(CCtrl));
+    s->cbd=BLUE;
+    s->cbg=LTBLUE;
+    s->cfg=BLACK;
+    s->cx=LTGREEN;
+    s->cy=GREEN;
+    s->cz=LTGREEN;
+    c->win_task=task;
+    c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+    c->type=CTRLT_VIEWING_ANGLES;
+    c->state=s;
+    c->draw_it=&DrawViewAnglesCtrl;
+    c->left_click=&LeftClickViewAngles;
+    c->update_derived_vals=&UpdateDerivedViewAnglesCtrl;
+    QueIns(c,task->last_ctrl);
+    TaskDerivedValsUpdate(task);
+  }
+  return c;
+}
+
+public U0 ViewAnglesDel(CTask *task=NULL)
+{//Free view angle ctrl.
+  CCtrl *c;
+  if (!task) task=Fs;
+  if (c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES)) {
+    QueRem(c);
+    Free(c->state);
+    Free(c);
+  }
+}
+
+ diff --git a/public/Wb/Adam/Ctrls/CtrlsBttn.HC.HTML b/public/Wb/Adam/Ctrls/CtrlsBttn.HC.HTML new file mode 100755 index 0000000..dff6898 --- /dev/null +++ b/public/Wb/Adam/Ctrls/CtrlsBttn.HC.HTML @@ -0,0 +1,122 @@ + + + + + + + + + + + +
+#define BTTN_BORDER     2
+
+#define BTF_DONT_FREE   1
+
+class CCtrlBttnState
+{
+  I64 state,num_states,flags;
+  U8 *state_texts;
+  CColorROPU32 *state_colors;
+};
+
+U0 DrawCtrlBttn(CDC *dc,CCtrl *c)
+{
+  CCtrlBttnState *s=c->state;
+  I64 l;
+  U8 *st;
+
+  dc->color=BLACK;
+  GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
+  if (!(st=LstSub(s->state,s->state_texts)))
+    st=s->state_texts;
+  dc->color=s->state_colors[s->state];
+  l=StrLen(st);
+  GrRect(dc,c->left+BTTN_BORDER,c->top+BTTN_BORDER,
+        c->right-c->left+1-BTTN_BORDER*2,
+        c->bottom-c->top+1-BTTN_BORDER*2);
+  dc->color=s->state_colors[s->state]^(WHITE<<16+WHITE);
+  GrPrint(dc,(c->left+c->right+1-l*FONT_WIDTH)>>1,
+        (c->top+c->bottom+1-FONT_HEIGHT)>>1,"%s",st);
+}
+
+U0 LeftClickCtrlBttn(CCtrl *c,I64,I64,Bool down)
+{
+  CCtrlBttnState *s=c->state;
+  if (down) {
+    s->state++;
+    if (s->state==s->num_states)
+      s->state=0;
+  }
+}
+
+public CCtrl *CtrlBttnNew(I64 x,I64 y,I64 width=-1,I64 height=-1,
+        I64 num_states=1,U8 *state_texts,
+        I32 *state_colors,CCtrlBttnState *_s=NULL)
+{//Create bttn ctrl. See ::/Apps/Strut/Strut.HC.
+  CCtrl *res;
+  CCtrlBttnState *s;
+  I64 i,j,l;
+  U8 *st;
+  if (width<0) {
+    l=1;
+    for (i=0;i<num_states;i++)
+      if (st=LstSub(i,state_texts)) {
+        j=StrLen(st);
+        if (j>l) l=j;
+      }
+    width=BTTN_BORDER*4+l*FONT_WIDTH;
+  }
+  if (height<0) height=BTTN_BORDER*4+FONT_HEIGHT;
+  res=CAlloc(sizeof(CCtrl));
+  if (_s) {
+    s=_s;
+    MemSet(s,0,sizeof(CCtrlBttnState));
+  } else {
+    s=CAlloc(sizeof(CCtrlBttnState));
+    s->flags=BTF_DONT_FREE;
+  }
+  s->num_states=num_states;
+  s->state_texts=state_texts;
+  s->state_colors=state_colors;
+  res->win_task=Fs;
+  res->flags=CTRLF_SHOW;
+  res->type=CTRLT_GENERIC;
+  res->state=s;
+  res->draw_it=&DrawCtrlBttn;
+  res->left_click=&LeftClickCtrlBttn;
+  res->left=x;
+  res->top=y;
+  res->right=res->left+width-1;
+  res->bottom=res->top+height-1;
+  QueIns(res,Fs->last_ctrl);
+  return res;
+}
+
+public U0 CtrlBttnDel(CCtrl *c)
+{//Free bttn ctrl.
+  QueRem(c);
+  if (!(c->flags&BTF_DONT_FREE))
+    Free(c->state);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Adam/Ctrls/CtrlsSlider.HC.HTML b/public/Wb/Adam/Ctrls/CtrlsSlider.HC.HTML new file mode 100755 index 0000000..22cad56 --- /dev/null +++ b/public/Wb/Adam/Ctrls/CtrlsSlider.HC.HTML @@ -0,0 +1,245 @@ + + + + + + + + + + + +
+class CTemplateCSSlider
+{
+  CTemplateCSSlider *next,*last;
+  U8 *name;
+  I64 num;
+};
+
+class CTemplateCS
+{
+  CTemplateCSSlider *next_slider,*last_slider;
+  I64 num_sliders,range,spacing,border;
+  U8 *glbl_name;
+};
+
+CTemplateCS *CtrlSliderGet()
+{
+  CTemplateCSSlider *tmps;
+  U8 *st,pmt[STR_LEN];
+  CTemplateCS *res=CAlloc(sizeof(CTemplateCS));
+
+  "$PURPLE$Ctrl Slider$FG$\n\n";
+
+  res->glbl_name=GetStr("Glbl Struct Name (ENTER for No Glbl):");
+  res->range=GetI64     ("Range   (%4d):",30);
+  res->spacing=GetI64("Spacing (%4d):",20);
+  res->border=GetI64 ("Border  (%4d):",2);
+
+  res->next_slider=res->last_slider=&res->next_slider;
+  while (TRUE) {
+    StrPrint(pmt,"Slider #%d Name:",res->num_sliders+1);
+    st=GetStr(pmt);
+    if (!*st) {
+      Free(st);
+      break;
+    }
+    tmps=CAlloc(sizeof(CTemplateCSSlider));
+    tmps->name=st;
+    QueIns(tmps,res->last_slider);
+    tmps->num=res->num_sliders++;
+  }
+  return res;
+}
+
+U0 TemplateCtrlSlider(CDoc *doc)
+{
+  CTask *task;
+  CTemplateCS *m=NULL;
+  CTemplateCSSlider *tmps;
+  I64 i;
+
+  DocUnlock(doc);
+  DocRecalc(doc);
+  DocCaptureUndo(doc,TRUE);
+
+  task=User("CTemplateCS **_m=0x%X;*_m=CtrlSliderGet;\n",&m);
+  while (!m)
+    Yield;
+
+  DocPrint(doc,
+"#define SLIDER_RANGE\t%d
+#define SLIDER_SPACING\t%d
+#define SLIDER_BORDER\t%d
+
+class CSliderState
+{
+",m->range,m->spacing,m->border);
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  I64 %s;\n",tmps->name);
+    tmps=tmps->next;
+  }
+  if (*m->glbl_name)
+    DocPrint(doc,"} %s;\n",m->glbl_name);
+  else
+    DocPrint(doc,"};\n");
+
+  DocPrint(doc,
+"
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,%d*SLIDER_SPACING+%d,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BLUE;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+    %d*SLIDER_SPACING+%d-2*SLIDER_BORDER,SLIDER_SPACING*2
+    +SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+",m->num_sliders+1,m->num_sliders,m->num_sliders+1,m->num_sliders);
+
+  for (i=0;i<m->num_sliders;i++)
+    DocPrint(doc,
+"  GrLine(dc,c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING,
+             c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+",i+1,i,i+1,i);
+
+  DocPrint(doc,"  dc->color=LTRED;\n");
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,
+"  GrPrint(dc,c->left+%d*SLIDER_SPACING+%d-FONT_WIDTH/2,
+    c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+    \"%%d\",s->%s*10/SLIDER_RANGE);\n",
+      tmps->num+1,tmps->num,tmps->name);
+    tmps=tmps->next;
+  }
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,
+        "  GrRect(dc,c->left+%d*SLIDER_SPACING+%d-3,"
+        "c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-2,7,5);\n",
+      tmps->num+1,tmps->num,tmps->name);
+    tmps=tmps->next;
+  }
+  DocPrint(doc,"  dc->color=YELLOW;\n");
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  GrRect(dc,c->left+%d*SLIDER_SPACING+%d-2,"
+        "c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-1,5,3);\n",
+      tmps->num+1,tmps->num,tmps->name);
+    tmps=tmps->next;
+  }
+  DocPrint(doc,
+"}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
+  c->right=c->left+%d*SLIDER_SPACING+%d;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+",m->num_sliders+1,m->num_sliders);
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  s->%s=ClampI64(s->%s,0,SLIDER_RANGE-1);\n",
+        tmps->name,tmps->name);
+    tmps=tmps->next;
+  }
+  DocPrint(doc,
+"}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool down)
+{
+  no_warn down;
+  CSliderState *s=c->state;
+");
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  ");
+    if (tmps!=m->next_slider)
+      DocPrint(doc,"else ");
+    if (tmps->next==&m->next_slider)
+      DocPrint(doc,"\n");
+    else
+      DocPrint(doc,"if (x<c->left+%d*SLIDER_SPACING+%d+SLIDER_SPACING/2)\n",
+        tmps->num+1,tmps->num);
+    DocPrint(doc,"    s->%s=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));\n",
+       tmps->name);
+    tmps=tmps->next;
+  }
+ 
+  DocPrint(doc,
+"  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+");
+  if (*m->glbl_name)
+    DocPrint(doc,"  c->state=&%s;\n"
+        "  MemSet(&%s,0,sizeof(CSliderState));\n",m->glbl_name,m->glbl_name);
+  else
+    DocPrint(doc,       "  c->state=CAlloc(sizeof(CSliderState));\n");
+  DocPrint(doc,
+"  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+");
+  if (!*m->glbl_name)
+    DocPrint(doc,"  Free(c->state);\n");
+  DocPrint(doc,
+"  Free(c);
+}
+");
+
+  Kill(task);  //This frees memory.
+
+  RegOneTimePopUp(ARf_MANAGE_SLIDER,
+    "Modify the code to your heart's content.\n"
+    "The code is no longer managed.\n");
+
+  DocLock(doc);
+}
+
+ diff --git a/public/Wb/Adam/Ctrls/MakeCtrls.HC.HTML b/public/Wb/Adam/Ctrls/MakeCtrls.HC.HTML new file mode 100755 index 0000000..128aaf8 --- /dev/null +++ b/public/Wb/Adam/Ctrls/MakeCtrls.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#help_index "Ctrls"
+#help_file "::/Doc/Ctrls"
+#include "CtrlsA"
+#include "CtrlsBttn"
+#include "CtrlsSlider"
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/DevInfo.HC.HTML b/public/Wb/Adam/DevInfo.HC.HTML new file mode 100755 index 0000000..1b99a40 --- /dev/null +++ b/public/Wb/Adam/DevInfo.HC.HTML @@ -0,0 +1,251 @@ + + + + + + + + + + + +
+#help_index "PCI;Processor;Devices;Info"
+
+//The file was downloaded from
+//http://www.pcidatabase.com/reports.php?type=tab-delimeted
+
+#define PCI_DEV_FILE "::/Misc/PCIDevices.DD.Z"
+
+/****
+//1) Download http://www.pcidatabase.com/reports.php?type=tab-delimeted
+//2) Rename to ::/Misc/PCIDevices.DD.Z
+//3) ToDolDoc("::/Misc/PCIDevices.DD.Z");
+//4) Edit and remove file header and tail
+//5) Text find-and-replace "=0A=" with "". (Doesn't seem necessary anmore.)
+//6) Run PCIDevFileGen(). (Doesn't seem necessary anmore.)
+
+public U0 PCIDevFileGen()
+{
+  Bool first=TRUE,del=FALSE,del2=FALSE,cont=FALSE;
+  CDoc *doc=DocRead(PCI_DEV_FILE,
+        DOCF_PLAIN_TEXT|DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next,*doc_e2;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (first) {
+      if (doc_e->type_u8==DOCT_TEXT) {
+        if (doc_e->tag[0]==';')
+          del=TRUE;
+      }
+      first=FALSE;
+    }
+    if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[StrLen(doc_e->tag)-1]=='=' &&
+          doc_e2->type_u8==DOCT_NEW_LINE) {
+      doc_e->tag[StrLen(doc_e->tag)-1]=CH_SPACE;
+      cont=TRUE;
+    }
+    del2=del;
+    if (doc_e->type_u8==DOCT_NEW_LINE) {
+      first=TRUE;
+      del2=FALSE;
+      if (cont) {
+        del=TRUE;
+        cont=FALSE;
+      }
+    }
+    if (del)
+      DocEntryDel(doc,doc_e);
+    del=del2;
+    doc_e=doc_e2;
+  }
+  DocWrite(doc);
+}
+****/
+
+//::/Misc/PCIDevices.DD
+U0 PCILookUpSingle(CDoc *doc,I64 m,I64 d,U8 **_vendor,U8 **_dev)
+{
+  Bool first=TRUE;
+  U8 buf[8],*vendor=NULL,*dev=NULL;
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (first) {
+      if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[0]!=';' &&
+            StrLen(doc_e->tag)>=4) {
+        buf[0](U16)='0x';
+        buf[2](U32)=doc_e->tag(U32 *)[0];
+        buf[6]=0;
+        if (Str2I64(buf)==m) {
+          doc_e=doc_e->next->next;
+          if (doc_e->type_u8==DOCT_TEXT) {
+            vendor=AStrNew(doc_e->tag);
+            first=FALSE;
+            break;
+          }
+        }
+      }
+      first=FALSE;
+    }
+    if (doc_e->type_u8==DOCT_NEW_LINE)
+      first=TRUE;
+    doc_e=doc_e->next;
+  }
+
+  if (vendor) {
+    while (doc_e!=doc) {
+      if (first) {
+        if (doc_e->type_u8==DOCT_TAB) {
+          doc_e=doc_e->next;
+          if (doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=4) {
+            buf[0](U16)='0x';
+            buf[2](U32)=doc_e->tag(U32 *)[0];
+            buf[6]=0;
+            if (Str2I64(buf)==d) {
+              doc_e=doc_e->next->next;
+              if (doc_e->type_u8==DOCT_TEXT) {
+                dev=AStrNew(doc_e->tag);
+                break;
+              }
+            }
+          }
+        } else
+          break;
+        first=FALSE;
+      }
+      if (doc_e->type_u8==DOCT_NEW_LINE)
+        first=TRUE;
+      doc_e=doc_e->next;
+    }
+  }
+
+  if (vendor)
+    *_vendor=vendor;
+  else
+    *_vendor=AStrNew("Unknown");
+
+  if (dev)
+    *_dev=dev;
+  else
+    *_dev=AStrNew("Unknown");
+}
+
+U0 PCILookUpDevs()
+{
+  CPCIDev *tmppci;
+  I64 w1,w2,b,d,f,timeout=32*8*2;
+  CDoc *doc;
+  if (dev.pci_head.next!=&dev.pci_head)
+    return;
+  doc=DocRead(PCI_DEV_FILE,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+  for (b=0;b<sys_pci_busses;b++)
+    for (d=0;d<32;d++)
+      for (f=0;f<8;f++) {
+        w1=PCIReadU16(b,d,f,0);
+        if (w1!=0xFFFF) {
+          tmppci=ACAlloc(sizeof(CPCIDev));
+          tmppci->bus=b;
+          tmppci->dev=d;
+          tmppci->fun=f;
+          tmppci->vendor=w1;
+          tmppci->dev_id=w2=PCIReadU16(b,d,f,2);
+          tmppci->sub_code=PCIReadU8(b,d,f,0xA);
+          tmppci->base_code=PCIReadU8(b,d,f,0xB);
+          PCILookUpSingle(doc,w1,w2,&tmppci->vendor_str,&tmppci->dev_id_str);
+          QueIns(tmppci,dev.pci_head.last);
+          timeout=32*8*2;
+        } else if (sys_pci_busses==256 && --timeout<=0)
+          goto lud_done;
+      }
+lud_done:
+  DocDel(doc);
+}
+
+public U0 PCIRep()
+{//Report description of PCI devices.
+  CPCIDev *tmppci;
+  "PCI Busses:%d\n",sys_pci_busses;
+  if (!FileFind(PCI_DEV_FILE)) {
+    "You don't have the PCI device file.\n";
+    return;
+  }
+  PCILookUpDevs;
+  tmppci=dev.pci_head.next;
+  while (tmppci!=&dev.pci_head) {
+    "%02X:%02X:%01X %02X%02X $GREEN$%s $CYAN$%s$FG$\n",
+          tmppci->bus,tmppci->dev,tmppci->fun,
+          tmppci->base_code,tmppci->sub_code,
+          tmppci->vendor_str,tmppci->dev_id_str;
+    tmppci=tmppci->next;
+  }
+}
+
+#help_index "Info;Memory/Info"
+public U0 MemBIOSRep()
+{//Report the memory ranges reported by the BIOS at boot.
+  U16           *m01=MEM_E801;
+  CMemE820      *m20=MEM_E820;
+  CMemRange     *tmpmr;
+  "Standard Addresses\n"
+        "000A0000-000BFFFF VGA\n"
+        "FEE00000-FEE00FFF See $LK,\"APIC\",A=\"MN:LAPIC_BASE\"$\n\n"
+        "32 Bit Device Mem\n";
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  tmpmr=dev.mem32_head.next;
+  while (tmpmr!=&dev.mem32_head) {
+    "%02X:%016X-%016X\n",
+          tmpmr->type,tmpmr->base,tmpmr->base+tmpmr->size-1;
+    tmpmr=tmpmr->next;
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+
+  "\nBIOS Memory Report 15:E801\n"
+        "01:0000000000000000-%016X\n",0x100000+m01[0]<<10-1;
+  "01:0000000001000000-%016X\n",SYS_16MEG_AREA_LIMIT+m01[1]<<16-1;
+
+  if (m20->type) {
+    '\n';
+    "BIOS Memory Report 15:E820\n";
+    while (m20->type) {
+      "%02X:%016X-%016X\n",m20->type,m20->base,m20->base+m20->len-1;
+      m20++;
+    }
+  }
+}
+
+public U0 MemPageRep()
+{//Page Table Report.
+  "MAPPED\t  :%010X with ",mem_mapped_space;
+  if (Bt(&mem_page_size,30))
+    "$RED$1GIG$FG$ pages\n";
+  else
+    "$RED$2MEG$FG$ pages\n";
+  "PML2\t  :%010X 2MEG  :%08X\n",
+        *MEM_PML2(U64 *),*MEM_2MEG_NUM(U64 *);
+  "PML3\t  :%010X 1GIG  :%08X\n",
+        *MEM_PML3(U64 *),*MEM_1GIG_NUM(U64 *);
+  "PML4\t  :%010X 512GIG:%08X\n",
+        *MEM_PML4(U64 *),*MEM_512GIG_NUM(U64 *);
+  "FIXED_AREA:%010X\n",SYS_FIXED_AREA;
+  "HEAP_BASE :%010X\nHEAP_LIMIT:%010X\n",mem_heap_base,mem_heap_limit;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocBin.HC.HTML b/public/Wb/Adam/DolDoc/DocBin.HC.HTML new file mode 100755 index 0000000..dccf733 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocBin.HC.HTML @@ -0,0 +1,173 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Bin"
+
+CDocBin *DocBinFindNum(CDoc *haystack_doc,I64 needle_num)
+{
+  CDocBin *b=haystack_doc->bin_head.next;
+  while (b!=&haystack_doc->bin_head) {
+    if (b->num==needle_num)
+      return b;
+    b=b->next;
+  }
+  return NULL;
+}
+
+CDocBin *DocBinFindTag(CDoc *haystack_doc,U8 *needle_tag)
+{
+  CDocBin *b;
+  if (needle_tag) {
+    b=haystack_doc->bin_head.next;
+    while (b!=&haystack_doc->bin_head) {
+      if (b->tag && !StrCmp(b->tag,needle_tag))
+        return b;
+      b=b->next;
+    }
+  }
+  return NULL;
+}
+
+U0 DocBinsValidate(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocBin *b,*b1;
+  CDocEntry *doc_e,*doc_e2;
+  I64 renum_num=0;
+  b=doc->bin_head.next;
+  while (b!=&doc->bin_head) {
+    b->use_cnt=0;
+    b->tmp_use_cnt=0;
+    b->renum_num=-1;
+    Free(b->tag);
+    b->tag=NULL;
+    b=b->next;
+  }
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (doc_e->de_flags & DOCEF_HAS_BIN) {
+      if (b=doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num)) {
+        if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+          b->tmp_use_cnt=I32_MAX;
+        if (!b->use_cnt++)
+          b->renum_num=++renum_num;
+        doc_e->bin_num=b->renum_num;
+        if (!b->tag && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+          b->tag=StrNew(doc_e->tag,doc->mem_task);
+      } else {
+        RawPrint(3000,"Bin Not Found");
+        doc_e->type=doc_e->de_flags=0;
+        doc_e->type_u8=DOCT_ERROR;
+      }
+    }
+    doc_e=doc_e2;
+  }
+
+  b=doc->bin_head.next;
+  doc->cur_bin_num=1;
+  while (b!=&doc->bin_head) {
+    b1=b->next;
+    if (!b->use_cnt) {
+      QueRem(b);
+      Free(b->data);
+      Free(b);
+    } else {
+      b->num=b->renum_num;
+      if (b->num>=doc->cur_bin_num)
+        doc->cur_bin_num=b->num+1;
+    }
+    b=b1;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 DocBinDel(CDoc *doc,CDocBin *b)
+{
+  if (doc && b && b->use_cnt) {
+    b->use_cnt--;
+    if (!b->use_cnt) {
+      QueRem(b);
+      Free(b->tag);
+      Free(b->data);
+      Free(b);
+    }
+  } else
+    RawPrint(3000,"DocBinDel");
+}
+
+I64 DocBinPtrRst(CDoc *doc,CDocEntry *doc_e)
+{
+  U8 *st,*st2;
+  CDoc *doc2;
+  CDocBin *tmpb,*tmpb2;
+  I64 i,bin_num=0;
+  if (doc_e->de_flags&DOCEF_HAS_BIN &&
+        doc_e->bin_ptr_link && StrLen(doc_e->bin_ptr_link)) {
+    bin_num=doc_e->bin_num;
+    st=StrNew(doc_e->bin_ptr_link);
+    st2=StrNew(st);
+    StrLastRem(st,",",st2);
+    i=Str2I64(st2);
+    if (i>0||*st2) {
+      doc2=DocRead(st);
+      if (i>0  && (tmpb2=DocBinFindNum(doc2,i)) ||
+            i==0 && (tmpb2=DocBinFindTag(doc2,st2))) {
+        i=1;
+        if (bin_num>0) {
+          if (tmpb=DocBinFindNum(doc,bin_num)) {
+            i=tmpb->use_cnt;
+            DocBinDel(doc,tmpb);
+          }
+        } else
+          bin_num=doc->cur_bin_num++;
+        tmpb=MAllocIdent(tmpb2,doc->mem_task);
+        tmpb->use_cnt=i;
+        tmpb->data=MAllocIdent(tmpb2->data,doc->mem_task);
+        tmpb->num=bin_num;
+        doc_e->bin_data=tmpb;
+        if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+          tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
+        else
+          tmpb->tag=NULL;
+        QueIns(tmpb,doc->bin_head.last);
+      } else
+        bin_num=0;
+      DocDel(doc2);
+    } else
+      bin_num=0;
+    Free(st2);
+    Free(st);
+    doc_e->bin_num=bin_num;
+  }
+  return bin_num;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocChar.HC.HTML b/public/Wb/Adam/DolDoc/DocChar.HC.HTML new file mode 100755 index 0000000..c0061aa --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocChar.HC.HTML @@ -0,0 +1,683 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Editor"
+
+public I64 EdCurU8(CDoc *doc)
+{//Return cur U8. See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry;
+  I64 res=-1;
+  if (doc_ce->type_u8==DOCT_TEXT &&
+        doc_ce->min_col<=doc->cur_col<doc_ce->max_col)
+    res=doc_ce->tag[doc->cur_col];
+  else if (doc_ce->type_u8==DOCT_TAB)
+    res='\t';
+  else if (doc_ce->type_u8==DOCT_NEW_LINE ||
+        doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
+    res='\n';
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public U0 EdCursorLeft(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor left. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  U8 *dst;
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
+  I64 cc=doc->cur_col,y=doc_ce->y;
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (sc>=0 && sc&SCF_CTRL) {
+    while (doc_ce->last!=doc && (doc_ce->last->y==y ||
+          doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
+      doc_ce=doc_ce->last;  //TODO: sel? recurse?
+    cc=doc_ce->min_col;
+  } else {
+    if (cc>doc_ce->min_col) {
+      if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+      }
+      cc--;
+      if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+        doc_ce=doc_ne;
+        cc=doc_ce->min_col;
+      }
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+    } else {
+      cc=doc_ce->min_col;
+      while (doc_ce->last!=doc &&
+            (doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
+            doc_ce->last->type_u8==DOCT_INDENT ||
+            doc_ce->last->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+        doc_ce=doc_ce->last;
+        if (sc>=0)
+          BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      }
+      if (doc_ce->last!=doc) {
+        doc_ce=doc_ce->last;
+        if (doc_ce->max_col>doc_ce->min_col) {
+          cc=doc_ce->max_col-1;
+          if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
+            dst=doc_ce->tag+cc;
+            doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+            *dst=0;
+            doc_ce->max_col=cc;
+            QueIns(doc_ne,doc_ce);
+            doc_ce=doc_ne;
+            cc=doc_ce->min_col;
+          }
+        } else
+          cc=doc_ce->max_col;
+        if (sc>=0)
+          BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      }
+    }
+  }
+  doc->cur_col=cc;
+  doc->cur_entry=doc_ce;
+  if (doc_ce!=original_ce)
+    DocFormBwd(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdCursorRight(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor right. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  U8 *dst;
+  CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
+  I64 cc=doc->cur_col,y=doc_ce->y,old_de_flags,old_color;
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (sc>=0 && sc&SCF_CTRL) {
+    while (doc_ce!=doc && doc_ce->next->y==y &&
+          doc_ce->next->type_u8!=DOCT_SOFT_NEW_LINE && doc_ce->next!=doc &&
+          (doc_ce->next->type_u8!=DOCT_NEW_LINE || !(doc->flags & DOCF_FORM)) ||
+          doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))
+      doc_ce=doc_ce->next;
+    if (doc_ce->max_col>doc_ce->min_col)
+      cc=doc_ce->max_col-1;
+    else
+      cc=doc_ce->min_col;
+  } else {
+    if (cc<doc_ce->max_col) {
+      if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+        doc_ce=doc_ne;
+        cc=doc_ce->min_col;
+      }
+      cc++;
+      old_de_flags=doc_ce->de_flags;
+      old_color=doc_ce->type;
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ne->type=DOCT_TEXT | old_color & -0x100;
+        doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+        doc_ce=doc_ne;
+        cc=doc_ce->min_col;
+      } else if (cc>=doc_ce->max_col) {
+        doc_ce=doc_ce->next;
+        cc=doc_ce->min_col;
+      }
+    } else {
+      if (doc_ce!=doc) {
+        if (cc<=doc_ce->min_col && sc>=0)
+          BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+        doc_ce=doc_ce->next;
+        while (doc_ce!=doc && doc_ce->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
+          if (sc>=0)
+            BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+          doc_ce=doc_ce->next;
+        }
+        cc=doc_ce->min_col;
+        if (doc_ce->type_u8==DOCT_SOFT_NEW_LINE) {
+          if (sc>=0)
+            BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+          doc_ce=doc_ce->next;
+          cc=doc_ce->min_col;
+        }
+      }
+    }
+  }
+  doc->cur_col=cc;
+  doc->cur_entry=doc_ce;
+  if (doc_ce!=original_ce)
+    DocFormFwd(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdLineUp(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor up. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  U8 *dst;
+  I64 y,x;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
+
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (doc_ce->type_u8==DOCT_HEX_ED) {
+    doc->cur_col=doc->cur_col-doc_ce->hex_ed_width*3;
+    if (doc->cur_col>=0) {
+      if (unlock)
+        DocUnlock(doc);
+      return;
+    } else
+      doc->cur_col=0;
+  }
+  x=doc->x; y=doc->y;
+  if (IsEditableText(doc_ce)) {
+    if (doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      doc_ne->x=doc_ce->x+doc->cur_col;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+    } else if (doc->cur_col==doc_ce->min_col && doc_ce->last!=doc)
+      doc_ce=doc_ce->last;
+  } else if (doc_ce->last!=doc)
+    doc_ce=doc_ce->last;
+  if (sc>=0)
+    BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+  doc->cur_entry=doc_ce;
+  DocFormBwd(doc);
+  doc_ce=doc->cur_entry;
+  while (doc_ce->last!=doc && (doc_ce->y>=y ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+    doc_ce=doc_ce->last;
+    if (sc>=0)
+      BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+  }
+  y=doc_ce->y;
+  doc->y=y;
+  while (doc_ce!=doc && (doc_ce->y>=y && doc_ce->x>=x ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+    if (sc>=0)
+      BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+    doc_ce=doc_ce->last;
+  }
+
+  if (doc_ce==doc || doc_ce->y<y)
+    doc_ce=doc_ce->next;
+  else {
+    if (!IsEditableText(doc_ce)) {
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+    } else {
+      if (doc_ce->next->x==x) {
+        doc_ce=doc_ce->next;
+        if (doc->flags & DOCF_FORM)
+          while (doc_ce->next->x==x &&
+                (!Bt(doldoc.type_flags_form,doc_ce->type_u8) &&
+                !(doc_ce->de_flags&DOCEF_LINK)||
+                doc_ce->de_flags&DOCEF_SKIP_IN_FORM))
+            doc_ce=doc_ce->next;
+      }
+    }
+  }
+  if (doc_ce->de_flags&DOCEF_TAG) {
+    doc->cur_col=x-doc_ce->x;
+    if (IsEditableText(doc_ce)) {
+      if (doc->cur_col>doc_ce->max_col)
+        doc->cur_col=doc_ce->max_col;
+    } else if (doc->cur_col>=doc_ce->max_col)
+      doc->cur_col=doc_ce->max_col-1;
+    if (doc->cur_col<doc_ce->min_col)
+      doc->cur_col=doc_ce->min_col;
+  } else {
+    if (doc_ce->type_u8==DOCT_HEX_ED) {
+      doc->cur_col=RoundI64((doc_ce->len-1)*3,doc_ce->hex_ed_width*3);
+      if (doc->cur_col<0)
+        doc->cur_col=0;
+    } else
+      doc->cur_col=doc_ce->min_col;
+  }
+  if (IsEditableText(doc_ce) && doc_ce->x<x) {
+    if (doc->cur_col<doc_ce->max_col-1) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      if (sc>=0) {
+        if (sc&SCF_SHIFT)
+          doc_ne->type=doc_ce->type | DOCET_SEL;
+        else
+          doc_ne->type=doc_ce->type & ~DOCET_SEL;
+      }
+      doc_ne->x=doc_ce->x+doc->cur_col;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+      doc_ce=doc_ne;
+      doc->cur_col=doc_ce->min_col;
+    }
+  }
+  doc->cur_entry=doc_ce;
+  DocFormFwd(doc);
+  doc->x=doc->cur_entry->x+doc->cur_col;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdLineDown(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor down. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  U8 *dst;
+  I64 y,x,old_de_flags=0,old_color;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne,*doc_ce2;
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (doc_ce->type_u8==DOCT_HEX_ED) {
+    doc->cur_col=doc->cur_col+doc_ce->hex_ed_width*3;
+    if (doc->cur_col>=doc_ce->len*3) {
+      doc->cur_entry=doc_ce=doc_ce->next;
+      doc->cur_col=doc_ce->min_col;
+      doc->x=doc_ce->x+doc->cur_col;
+      doc->y=doc_ce->y;
+    }
+    if (unlock)
+      DocUnlock(doc);
+    return;
+  }
+  x=doc->x; y=doc->y;
+  if (IsEditableText(doc_ce)) {
+    if (doc->cur_col>doc_ce->min_col && doc->cur_col<doc_ce->max_col-1) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      if (sc>=0) {
+        if (sc&SCF_SHIFT)
+          doc_ne->type=doc_ce->type | DOCET_SEL;
+        else
+          doc_ne->type=doc_ce->type & ~DOCET_SEL;
+      }
+      doc_ne->x=doc_ce->x+doc->cur_col;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+      doc_ce=doc_ne;
+      doc->cur_col=doc_ce->min_col;
+    }
+  }
+  doc_ce2=doc_ce;
+  while (doc_ce!=doc && (doc_ce->y<=y ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
+    doc_ce=doc_ce->next;
+  y=doc_ce->y;
+  doc->y=y;
+  while (doc_ce!=doc && (doc_ce->y<=y && doc_ce->x<=x ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+    old_de_flags=doc_ce->de_flags;
+    old_color=doc_ce->type;
+    doc_ce=doc_ce->next;
+  }
+  if (doc_ce->last!=doc && (doc_ce->x>x && doc_ce->last->y>=y || doc_ce->y>y)) {
+    doc_ce=doc_ce->last;
+    doc->cur_entry=doc_ce;
+    if (!((doc_ce->type_u8==DOCT_NEW_LINE ||
+          doc_ce->type_u8==DOCT_SOFT_NEW_LINE ||
+          doc_ce->type_u8==DOCT_INDENT) &&
+          (doc_ce->last->type_u8==DOCT_NEW_LINE ||
+          doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
+          doc_ce->last->type_u8==DOCT_INDENT)))
+      DocFormBwd(doc);
+    doc_ce=doc->cur_entry;
+  }
+  while (doc_ce2!=doc && (doc_ce2!=doc_ce || IsEditableText(doc_ce))) {
+    if ((doc_ce2->y<y || doc_ce2->x<x ||
+          doc_ce2->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP) ||
+          doc_ce2->x==x && !doc_ce2->max_col &&
+          Bt(doldoc.type_flags_nontag_invis,doc_ce2->type_u8)) && sc>=0)
+      BEqu(&doc_ce2->type,DOCEt_SEL,sc&SCF_SHIFT);
+    if (doc_ce2==doc_ce) break;
+    doc_ce2=doc_ce2->next;
+  }
+  if (doc_ce->de_flags&DOCEF_TAG) {
+    doc->cur_col=x-doc_ce->x;
+    if (IsEditableText(doc_ce)) {
+      if (doc->cur_col>doc_ce->max_col)
+        doc->cur_col=doc_ce->max_col;
+    } else if (doc->cur_col>=doc_ce->max_col)
+      doc->cur_col=doc_ce->max_col-1;
+    if (doc->cur_col<doc_ce->min_col)
+      doc->cur_col=doc_ce->min_col;
+  } else
+    doc->cur_col=doc_ce->min_col;
+  if (IsEditableText(doc_ce)&&doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
+    dst=doc_ce->tag+doc->cur_col;
+    doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+    *dst=0;
+    doc_ne->type=DOCT_TEXT | old_color & -0x100;
+    doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
+    doc_ce->max_col=doc->cur_col;
+    doc_ne->x=doc_ce->x+doc->cur_col;
+    QueIns(doc_ne,doc_ce);
+    doc_ce=doc_ne;
+    doc->cur_col=doc_ce->min_col;
+  }
+  doc->cur_entry=doc_ce;
+  DocFormFwd(doc);
+  if (!(doc->flags & DOCF_FORM))
+    while (doc_ce!=doc && doc_ce!=doc->cur_entry) {
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      doc_ce=doc_ce->next;
+    }
+  doc->x=doc->cur_entry->x+doc->cur_col;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 EdCharDel(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry;
+
+  if (doc_ce==doc) {
+    if (unlock)
+      DocUnlock(doc);
+    return;
+  }
+  if (doc_ce->max_col!=0 &&
+        (IsEditableText(doc_ce)||doc_ce->type_u8==DOCT_DATA)) {
+    if (doc_ce->type_u8==DOCT_DATA && doc_ce->de_flags & DOCEF_HAS_TERMINATOR &&
+          doc->cur_col==doc_ce->max_col-1) {
+      if (unlock)
+        DocUnlock(doc);
+      return;
+    }
+    if (doc->cur_col<doc_ce->max_col)
+      StrCpy(doc_ce->tag+doc->cur_col,doc_ce->tag+doc->cur_col+1);
+    if (doc->cur_col>=doc_ce->max_col-1) {
+      doc->cur_entry=doc_ce->next;
+      doc->cur_col=doc->cur_entry->min_col;
+    }
+    DocRemSoftNewLines(doc,doc->cur_entry);
+    if (unlock)
+      DocUnlock(doc);
+    return;
+  }
+  doc->cur_entry=doc_ce->next;
+  doc->cur_col=doc->cur_entry->min_col;
+  if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
+    DocEntryDel(doc,doc_ce);
+  DocRemSoftNewLines(doc,doc->cur_entry);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 ChkDollarBufSize(CDoc *doc)
+{
+  U8 *b;
+  if (doc->dollar_buf_ptr>=doc->dollar_buf_size-2) {
+    doc->dollar_buf_size<<=1;
+    b=MAlloc(doc->dollar_buf_size,doc->mem_task);
+    MemCpy(b,doc->dollar_buf,doc->dollar_buf_ptr);
+    Free(doc->dollar_buf);
+    doc->dollar_buf=b;
+  }
+}
+
+U0 EdCharIns(I64 ch,I64 sc,CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  U8 *st,*src,*dst;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
+  I64 i,j,m,y=doc_ce->y;
+
+  if (doc->flags & DOCF_IN_DOLLAR) {
+    if (!Bt(char_bmp_printable,ch))
+      goto ic_done;
+    ChkDollarBufSize(doc);
+    doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
+    if (ch=='$') {
+      if (doc->dollar_buf_ptr==2) {
+        doc->flags&=~DOCF_IN_DOLLAR;
+        doc->dollar_buf_ptr=0;
+        goto ic_cont;
+      } else {
+        doc->dollar_buf[doc->dollar_buf_ptr]=0;
+        doc->flags&=~DOCF_IN_DOLLAR;
+        DocPrint(doc,"%s",doc->dollar_buf);
+        doc->dollar_buf_ptr=0;
+        goto ic_done;
+      }
+    } else
+      goto ic_done;
+  }
+  if (ch=='$' && !(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
+    doc->flags|=DOCF_IN_DOLLAR;
+    doc->dollar_buf_ptr=0;
+    doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
+    goto ic_done;
+  }
+  if (ch=='\r') goto ic_done;
+
+    ic_cont:
+  if ((ch==CH_SPACE || ch=='\n') &&
+        !(sc & (SCF_CTRL|SCF_SHIFT)) &&
+        doc_ce->de_flags &
+        (DOCEF_LINK|DOCEF_TREE|DOCEF_LST|DOCEF_CHECK_COLLAPSABLE|
+        DOCEF_LEFT_MACRO|DOCEF_LEFT_EXP|DOCEF_LEFT_CB|DOCEF_LEFT_IN_STR |
+        DOCEF_RIGHT_MACRO|DOCEF_RIGHT_EXP|DOCEF_RIGHT_CB|DOCEF_RIGHT_IN_STR)) {
+    doc->cmd_U8=ch;
+    DocEntryRun(doc,doc_ce,FALSE);
+    DocLock(doc);
+    goto ic_done;
+  }
+  if (doc_ce->type_u8==DOCT_HEX_ED) {
+    if (doc_ce->de_flags&DOCEF_DEREF_DATA &&
+          !(doc_ce->de_flags&DOCEF_REMALLOC_DATA))
+      st=doc_ce->data;
+    else
+      st=&doc_ce->data;
+    i=doc->cur_col;
+    j=i%(doc_ce->hex_ed_width*3);
+    m=i/(doc_ce->hex_ed_width*3)*doc_ce->hex_ed_width;
+    if (j>=doc_ce->hex_ed_width<<1)
+      st[j-doc_ce->hex_ed_width<<1+m]=ch;
+    else {
+      ch=ToUpper(ch)-'0';
+      if (ch>9) {
+        ch+='0'-'A'+10;
+        if (!(10<=ch<=15))
+          goto ic_done;
+      }
+      m=j>>1+m;
+      if (j & 1)
+        st[m]=st[m] & 0xF0| ch;
+      else
+        st[m]=st[m] & 0xF | ch<<4;
+    }
+    doc->cur_col++;
+    goto ic_done;
+  }
+  if (doc->flags & DOCF_OVERSTRIKE) {
+    if (Bt(char_bmp_displayable,ch)) {
+ic_overstrike:
+      if (IsEditableText(doc_ce)) {
+        if (doc->cur_col<doc_ce->max_col) {
+          if (doc_ce->tag[doc->cur_col]) {
+            doc_ce->tag[doc->cur_col++]=ch;
+            goto ic_done;
+          }
+        } else {
+          doc_ce=doc_ce->next;
+          doc->cur_entry=doc_ce;
+          doc->cur_col=doc_ce->min_col;
+          goto ic_overstrike;
+        }
+      } else if (doc_ce->type_u8==DOCT_DATA) {
+        if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR) {
+          if (doc_ce->tag[doc->cur_col] &&
+                doc->cur_col<doc_ce->min_col+doc_ce->len) {
+            doc_ce->tag[doc->cur_col++]=ch;
+            if ( ! doc_ce->tag[doc->cur_col]) {
+              doc_ce->tag[doc->cur_col]='_';
+              doc_ce->tag[doc->cur_col+1]=0;
+            }
+          } else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA)
+            goto ic_not_overstrike;
+        } else if (doc_ce->tag[doc->cur_col])
+          doc_ce->tag[doc->cur_col++]=ch;
+        goto ic_done;
+      }
+      doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
+      doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
+      doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
+      QueIns(doc_ne,doc_ce->last);
+    } else if (ch=='\n') {
+      while (doc->cur_entry->next!=doc && doc->cur_entry->y==y)
+        doc->cur_entry=doc->cur_entry->next;
+      doc->cur_col=doc->cur_entry->min_col;
+    } else if (ch=='\t') {
+      if (doc->flags&DOCF_FORM)
+        goto ic_form_tab;
+    }
+    goto ic_done;
+  }
+ic_not_overstrike:
+  if (ch=='\n') {
+    if (sc&SCF_CTRL && !(sc&SCF_SHIFT)) {
+      doc_ne=DocEntryNewBase(doc,
+            DOCT_PAGE_BREAK|doc->settings_head.dft_text_attr<<8);
+    } else {
+      doc_ne=DocEntryNewBase(doc,
+            DOCT_NEW_LINE|doc->settings_head.dft_text_attr<<8);
+    }
+    DocInsEntry(doc,doc_ne);
+  } else if (ch=='\t') {
+    if (doc->flags&DOCF_FORM &&
+          (Bt(doldoc.type_flags_form,doc->cur_entry->type_u8) ||
+          doc->cur_entry->de_flags&DOCEF_LINK) &&
+          !(doc->cur_entry->de_flags&DOCEF_SKIP_IN_FORM)) {
+ic_form_tab:
+      doc->cur_entry=doc->cur_entry->next;
+      doc->cur_col=doc->cur_entry->min_col;
+      DocFormFwd(doc);
+      goto ic_done;
+    } else {
+      doc_ne=DocEntryNewBase(doc,DOCT_TAB|doc->settings_head.dft_text_attr<<8);
+      DocInsEntry(doc,doc_ne);
+    }
+  } else {
+    if (Bt(char_bmp_displayable,ch)) {
+      if (doc_ce->type_u8==DOCT_DATA) {
+        while (TRUE) {
+          i=doc_ce->len+doc_ce->min_col;
+          if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR)
+            i++;
+          if (doc_ce->max_col<i) {
+            st=doc_ce->tag;
+            doc_ce->max_col++;
+            for (i=doc_ce->max_col;i>doc->cur_col;i--)
+              st[i]=st[i-1];
+            st[doc->cur_col++]=ch;
+            break;
+          } else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA) {
+            st=MAlloc(doc_ce->max_col+8,doc->mem_task);
+            MemCpy(st,doc_ce->tag,doc_ce->max_col+1);
+            Free(doc_ce->tag);
+            doc_ce->tag=st;
+            doc_ce->len=MSize(st)-doc_ce->min_col-2; //See DataTagWidth
+            Free(doc_ce->data);
+            doc_ce->data=MAlloc(doc_ce->len+2,doc->mem_task);
+          } else
+            break;
+        }
+      } else if (IsEditableText(doc_ce)) {
+        dst=st=MAlloc(doc_ce->max_col+2,doc->mem_task);
+        src=doc_ce->tag;
+        i=doc->cur_col;
+        while (i-->0)
+          *dst++=*src++;
+        *dst++=ch;
+        while (*dst++=*src++);
+        Free(doc_ce->tag);
+        doc_ce->tag=st;
+        doc_ce->max_col++;
+        doc->cur_col++;
+      } else {
+        doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
+        doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
+        doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
+        doc_ne->x=doc_ce->x+1;
+        QueIns(doc_ne,doc_ce->last);
+      }
+    }
+  }
+ic_done:
+  DocRemSoftNewLines(doc,doc->cur_entry);
+  if (doc->cur_entry->de_flags & DOCEF_UPDATE_DATA &&
+        (doc->cur_entry->type_u8==DOCT_DATA ||
+        doc->cur_entry->type_u8==DOCT_CHECK_BOX))
+    DocDataScan(doc,doc->cur_entry);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 EdLineDel(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ce2;
+  I64 y;
+  y=doc->y;
+  while (doc_ce!=doc && doc_ce->y==y)
+    doc_ce=doc_ce->next;
+  doc->cur_entry=doc_ce;
+  doc->cur_col=doc_ce->min_col;
+  doc_ce=doc_ce->last;
+  while (doc_ce!=doc && doc_ce->y==y) {
+    doc_ce2=doc_ce->last;
+    if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
+      DocEntryDel(doc,doc_ce);
+    doc_ce=doc_ce2;
+  }
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocClipBoard.HC.HTML b/public/Wb/Adam/DolDoc/DocClipBoard.HC.HTML new file mode 100755 index 0000000..ed6b566 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocClipBoard.HC.HTML @@ -0,0 +1,156 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Clip"
+
+sys_clip_doc=DocNew;
+
+public U0 ClipDel()
+{//Delete everything on clip.
+  DocRst(sys_clip_doc,TRUE);
+}
+
+public U0 ClipCopy(CDoc *doc)
+{//Copy DOCET_SEL flagged entries to clip.
+  CDoc *doc2=sys_clip_doc;
+  Bool unlock_doc=DocLock(doc),
+        unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_e=doc->head.next,*doc_ne;
+  ClipDel;
+  while (doc_e!=doc) {
+    if (doc_e->type & DOCET_SEL) {
+      doc_e->type&=~DOCET_SEL;
+      if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
+        doc_ne=DocEntryCopy(doc2,doc_e);
+        QueIns(doc_ne,doc2->head.last);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public U0 ClipCut(CDoc *doc)
+{//Remove sel entries and place on clip.
+  CDoc *doc2=sys_clip_doc;
+  Bool unlock_doc=DocLock(doc),
+        unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_e=doc->head.next,*doc_e1,*doc_ne,*doc_e2=NULL;
+  ClipDel;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (doc_e->type & DOCET_SEL) {
+      doc_e->type&=~DOCET_SEL;
+      if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
+        doc_ne=DocEntryCopy(doc2,doc_e);
+        QueIns(doc_ne,doc2->head.last);
+      }
+      if (doc_e==doc->cur_entry || doc_e==doc_e2)
+        doc_e2=doc_e->next;
+      DocEntryDel(doc,doc_e);
+    }
+    doc_e=doc_e1;
+  }
+  if (doc_e2) {
+    doc->cur_entry=doc_e2;
+    doc->cur_col=doc_e2->min_col;
+  }
+  DocRemSoftNewLines(doc,NULL);
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public U0 ClipPaste(CDoc *doc)
+{//Insert copy of clip at insert pt, cur_entry.
+  CDoc *doc2=sys_clip_doc;
+  Bool unlock_doc=DocLock(doc),
+        unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e;
+  if (doc_ce->type_u8==DOCT_DATA) {
+    doc_e=doc2->head.next;
+    while (doc_e!=doc2) {
+      if (doc_e->de_flags&DOCEF_TAG)
+        DocPrintPartial(doc,"%s",doc_e->tag);
+      doc_e=doc_e->next;
+    }
+  } else
+    DocInsDoc(doc,doc2);
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public U0 DocCut(CDoc *doc,CDocEntry *start,CDocEntry *end)
+{//Del start to end entry, including end points.
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *doc_e1;
+  if (start!=doc && (start->last!=end || end==doc))
+    do {
+      doc_e1=start->next;
+      if (start==doc->cur_entry) {
+        doc->cur_entry=start->next;
+        doc->cur_col=doc->cur_entry->min_col;
+      }
+      DocEntryDel(doc,start);
+      if (start==end)
+        break;
+      start=doc_e1;
+    } while (start!=doc);
+  DocRemSoftNewLines(doc,NULL);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public CDoc *DocCopy(CDoc *doc,CDocEntry *start,CDocEntry *end)
+{//Copies start to end entry, including end points.
+  CDoc *doc2=DocNew;
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *doc_ne;
+  if (start!=doc && (start->last!=end || end==doc))
+    do {
+      if (!Bt(doldoc.type_flags_data,start->type_u8)) {
+        doc_ne=DocEntryCopy(doc2,start);
+        QueIns(doc_ne,doc2->head.last);
+      }
+      if (start==end)
+        break;
+      start=start->next;
+    } while (start!=doc);
+  if (unlock_doc)
+    DocUnlock(doc);
+  return doc2;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocCodeTools.HC.HTML b/public/Wb/Adam/DolDoc/DocCodeTools.HC.HTML new file mode 100755 index 0000000..2570272 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocCodeTools.HC.HTML @@ -0,0 +1,689 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+U0 EdReplaceTroubleOne(CDoc *doc,U8 *st_original,U8 *st_safe,I64 num,
+        Bool to_safe,Bool sel)
+{
+  U8 buf[STR_LEN];
+  StrPrint(buf,st_safe,num);
+  if (to_safe)
+    EdReplace(doc,st_original,buf,sel);
+  else
+    EdReplace(doc,buf,st_original,sel);
+}
+
+U0 EdReplaceTroubleAll(CDoc *doc,Bool to_safe,Bool sel)
+{
+  I64 i=0;
+  EdReplaceTroubleOne(doc,"#assert" ,"//<@%d@>"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"#define" ,"//<@%d@>"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"#include","//<@%d@>"  ,i++,to_safe,sel);
+//#if will match #if,#ifdef,#ifndef,#ifaot and #ifjit
+  EdReplaceTroubleOne(doc,"#if"     ,"//<@%d@>"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"#endif"  ,"//<@%d@>"  ,i++,to_safe,sel);
+//Convert #exe to union because we want that indent pattern.
+  EdReplaceTroubleOne(doc,"#exe"    ,"union @%d@",i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"'{'"     ,"'<@%d@>'"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"'}'"     ,"'<@%d@>'"  ,i++,to_safe,sel);
+}
+
+#define C_INDENT_SPACES         2
+#define ASM_RENUM_SPACING       5
+
+#define EF_REINDENT     0
+#define EF_CMP_CHK      1
+#define EF_RENUM_ASM    2
+#define EF_CTRL_SLIDER  3
+#define EF_CH_SC        4
+
+I64 PopUpEdFmt()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$LTBLUE$$MU,\"Compile Check\",LE=EF_CMP_CHK$\n"
+        "$MU,\"Reindent HolyC Fun (Beware braces in strings.)\","
+        "LE=EF_REINDENT$\n"
+        "$MU,\"Renum Asm Local @@ Labels for Fun\",LE=EF_RENUM_ASM$\n"
+        "$MU,\"Insert Template Code: Ctrl Slider\",LE=EF_CTRL_SLIDER$\n"
+        "$MU,\"Insert ASCII/Scan Code Hex Codes for key pressed\","
+        "LE=EF_CH_SC$\n\n"
+        "$MU,\"CANCEL\",LE=DOCM_CANCEL$\n\n"
+        "$GREEN$<ALT-BACKSPACE>$FG$ to undo if not happy\n"
+        "with the ress.\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CRILex
+{
+  CCmpCtrl *cc1,*cc2;
+  CQueVectU8 *indent;
+  I64 depth,exp_depth,one_shot;
+  Bool was_new_line,is_not_cont;
+};
+
+I64 EdRILex(CRILex *rx)
+{
+  rx->is_not_cont=FALSE;
+  I64 i;
+  CLexFile *tmpf;
+  do {
+    Lex(rx->cc1);
+    Lex(rx->cc2);
+    i=PrsKeyWord(rx->cc2);
+    if (rx->cc1->token=='\n' && rx->cc2->token==';' || rx->cc2->token=='{' ||
+          rx->cc2->token=='}' || rx->cc2->token==':' || rx->cc2->token==')' &&
+          !rx->exp_depth || i==KW_ELSE || i==KW_CATCH || i==KW_DO)
+      rx->is_not_cont=TRUE;
+    if (rx->was_new_line && (rx->cc1->token!=':' || i==KW_CASE ||
+          i==KW_DFT || i==KW_START || i==KW_END)) {
+      tmpf=rx->cc2->lex_include_stk;
+      while (tmpf->next)
+        tmpf=tmpf->next;
+      QueVectU8Put(rx->indent,tmpf->cur_entry->y,rx->depth+rx->one_shot);
+      rx->one_shot=0;
+    }
+    if (rx->cc2->token=='\n')
+      rx->was_new_line=TRUE;
+    else
+      rx->was_new_line=FALSE;
+  } while (rx->cc1->token=='\n');
+  return rx->cc1->token;
+}
+
+U0 EdRIExp(CRILex *rx)
+{
+  if (rx->cc1->token=='(') {
+    if (!rx->exp_depth++)
+      rx->depth+=3;
+    EdRILex(rx);
+    while (rx->cc1->token && rx->cc1->token!=')')
+      EdRIExp(rx);
+    if (!--rx->exp_depth) {
+      rx->depth-=3;
+      if (rx->depth<0) rx->depth=0;
+    }
+  } else if (rx->cc1->token=='[') {
+    if (!rx->exp_depth++)
+      rx->depth+=3;
+    EdRILex(rx);
+    while (rx->cc1->token && rx->cc1->token!=']')
+      EdRIExp(rx);
+    if (!--rx->exp_depth) {
+      rx->depth-=3;
+      if (rx->depth<0) rx->depth=0;
+    }
+  }
+  EdRILex(rx);
+}
+
+U0 EdRIStmt(CRILex *rx,Bool indent)
+{
+  I64 i;
+  Bool cont;
+  if (rx->cc1->token=='{') {
+    rx->depth++;
+    EdRILex(rx);
+    while (rx->cc1->token && rx->cc1->token!='}')
+      EdRIStmt(rx,FALSE);
+    if (--rx->depth<0) rx->depth=0;
+    EdRILex(rx);
+  } else {
+    if (indent) rx->depth++;
+    do {
+      cont=FALSE;
+      switch (PrsKeyWord(rx->cc1)) {
+        case KW_IF:
+          EdRILex(rx);
+          EdRIExp(rx);
+          EdRIStmt(rx,TRUE);
+          if (PrsKeyWord(rx->cc1)==KW_ELSE) {
+            EdRILex(rx);
+            if (PrsKeyWord(rx->cc1)==KW_IF && rx->cc2->token!='\n')
+              EdRIStmt(rx,FALSE);
+            else
+              EdRIStmt(rx,TRUE);
+          }
+          break;
+        case KW_TRY:
+          EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          if (PrsKeyWord(rx->cc1)==KW_CATCH) {
+            EdRILex(rx);
+            EdRIStmt(rx,TRUE);
+          }
+          break;
+        case KW_LOCK:
+          EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          break;
+        case KW_FOR:
+        case KW_WHILE:
+          EdRILex(rx);
+          EdRIExp(rx);
+          EdRIStmt(rx,TRUE);
+          break;
+        case KW_ASM:
+        case KW_CLASS:
+        case KW_UNION:
+          if (EdRILex(rx)==TK_IDENT)
+            EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          break;
+        case KW_DO:
+          EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          if (PrsKeyWord(rx->cc1)==KW_WHILE) {
+            EdRILex(rx);
+            EdRIExp(rx);
+          }
+          if (rx->cc1->token==';')
+            EdRILex(rx);
+          break;
+        case KW_SWITCH:
+          EdRILex(rx);
+          EdRIExp(rx);
+          if (rx->cc1->token=='{') {
+            rx->depth++;
+            EdRILex(rx);
+            i=0;
+            while (rx->cc1->token && rx->cc1->token!='}') {
+              switch (PrsKeyWord(rx->cc1)) {
+                case KW_START:
+                  rx->depth+=i; i=0;
+                  while (EdRILex(rx) && rx->cc1->token!=':');
+                  EdRILex(rx);
+                  i++;
+                  break;
+                case KW_END:
+                  rx->depth+=i; i=0;
+                  if (--rx->depth<0) rx->depth=0;
+                  while (EdRILex(rx) && rx->cc1->token!=':');
+                  EdRILex(rx);
+                  break;
+                case KW_CASE:
+                case KW_DFT:
+                  rx->depth+=i; i=0;
+                  while (EdRILex(rx) && rx->cc1->token!=':');
+                  EdRILex(rx);
+                  break;
+                default:
+                  if (rx->cc1->token)
+                    EdRIStmt(rx,TRUE);
+              }
+            }
+            if (--rx->depth<0) rx->depth=0;
+            EdRILex(rx);
+          }
+          break;
+        default:
+          if (rx->cc1->token==TK_IDENT && rx->cc1->hash_entry &&
+                rx->cc1->hash_entry->type&(HTT_OPCODE|HTT_ASM_KEYWORD)) {
+//          rx->one_shot=4-rx->depth;
+            do EdRILex(rx);
+            while (rx->cc2->token && rx->cc2->token!='\n');
+            rx->is_not_cont=TRUE;
+          } else {
+            while (rx->cc1->token && rx->cc1->token!=';' &&
+                  rx->cc1->token!=':') {
+              if (rx->cc2->token=='\n' && !rx->is_not_cont)
+                rx->one_shot=3;
+              EdRILex(rx);
+            }
+            if (rx->cc1->token==':')
+              cont=TRUE;
+            EdRILex(rx);
+          }
+      }
+    } while (cont && rx->cc1->token!='}');
+    if (indent && --rx->depth<0)
+      rx->depth=0;
+  }
+}
+
+CQueVectU8 *EdRICode(CDoc *doc)
+{
+  CQueVectU8 *res;
+  CRILex *rx=CAlloc(sizeof(CRILex));
+
+  rx->cc1=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
+  Free(rx->cc1->lex_include_stk->full_name);
+  LexAttachDoc(rx->cc1,rx->cc1->lex_include_stk,doc,,
+        doc->cur_entry,doc->cur_col);
+
+  rx->cc2=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
+  Free(rx->cc2->lex_include_stk->full_name);
+  LexAttachDoc(rx->cc2,rx->cc2->lex_include_stk,doc,,
+        doc->cur_entry,doc->cur_col);
+
+  rx->indent=QueVectU8New(doc->cur_entry->y);
+
+  Lex(rx->cc1);
+  EdRIStmt(rx,FALSE);
+
+  CmpCtrlDel(rx->cc1);
+  CmpCtrlDel(rx->cc2);
+  res=rx->indent;
+  Free(rx);
+  return res;
+}
+
+U0 EdRemFunLeadingSpace(CDoc *doc)
+{
+  Bool unlock=DocLock(doc),
+        start_of_line=TRUE;
+  U8 *ptr;
+  I64 ch,levels=1;
+  CDocEntry *doc_e,*doc_e2;
+
+  EdGoToFun(doc,FALSE,FALSE);
+  doc_e=doc->cur_entry->next;
+  do {
+    doc_e2=doc_e->next;
+    if (doc_e!=doc && doc_e!=doc->cur_entry &&
+          !(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X)))
+      switch (doc_e->type_u8) {
+        case DOCT_TEXT:
+          ptr=doc_e->tag;
+          if (start_of_line) {
+            while (*ptr==CH_SPACE)
+              ptr++;
+            if (*ptr)
+              start_of_line=FALSE;
+            ptr=StrNew(ptr,doc->mem_task);
+            Free(doc_e->tag);
+            doc_e->tag=ptr;
+          }
+          if (!*ptr)
+            DocEntryDel(doc,doc_e);
+          else {
+            while (ch=*ptr++)
+              if (ch=='{')
+                levels++;
+              else if (ch=='}') {
+                if (!--levels)
+                  break;
+              }
+            if (!levels) goto ls_done;
+          }
+          break;
+        case DOCT_TAB:
+          if (start_of_line)
+            DocEntryDel(doc,doc_e);
+          break;
+        case DOCT_NEW_LINE:
+          start_of_line=TRUE;
+          break;
+        default:
+          start_of_line=FALSE;
+      }
+    doc_e=doc_e2;
+  } while (doc_e!=doc->cur_entry);
+ls_done:
+  DocRecalc(doc);
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+class CRenum
+{
+  CRenum *next,*last;
+  U8 label[sizeof(CEdFindText.find_text)];
+};
+
+I64 EdRAGetU8(CDoc *doc)
+{
+  I64 res=-1;
+  while (doc->cur_entry!=doc &&
+        doc->cur_entry->type&DOCET_SEL && res<0) {
+    res=EdCurU8(doc);
+    EdCursorRight(doc);
+  }
+  return res;
+}
+
+U0 EdRACollect(CDoc *doc,CRenum *head)
+{
+  I64 ch,i;
+  CRenum *tmpr;
+  U8 buf[sizeof(CEdFindText.find_text)];
+  ch=EdRAGetU8(doc);
+  while (ch>=0) {
+    if (ch!='@')
+      ch=EdRAGetU8(doc);
+    else {
+      ch=EdRAGetU8(doc);
+      if (ch=='@') {
+        ch=EdRAGetU8(doc);
+        StrCpy(buf,"@@");
+        i=2;
+        while (ch>=0 && i<sizeof(CEdFindText.find_text)) {
+          if (Bt(char_bmp_alpha_numeric,ch))
+            buf[i++]=ch;
+          else
+            break;
+          ch=EdRAGetU8(doc);
+        }
+        if (i<sizeof(CEdFindText.find_text)) {
+          buf[i++]=0;
+          while (ch>=0 && Bt(char_bmp_white_space,ch))
+            ch=EdRAGetU8(doc);
+          if (ch==':') {
+            ch=EdRAGetU8(doc);
+            tmpr=MAlloc(sizeof(CRenum));
+            StrCpy(tmpr->label,buf);
+            QueIns(tmpr,head->last);
+          }
+        }
+      }
+    }
+  }
+//This is needed because we moved the
+  //cursor and it didn't recalc.
+  DocRecalc(doc);
+}
+
+U0 EdRenumAsm(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  I64 num=0;
+  CRenum head,*tmpr,*tmpr1;
+  U8    buf[sizeof(CEdFindText.find_text)],
+        buf2[sizeof(CEdFindText.find_text)];
+
+  QueInit(&head);
+  EdSelFun(doc,TRUE);
+  EdRACollect(doc,&head);
+
+  tmpr=head.next;
+  while (tmpr!=&head) {
+    tmpr1=tmpr->next;
+    num+=ASM_RENUM_SPACING;
+    StrPrint(buf,"@#%02d",num);
+    EdReplace(doc,tmpr->label,buf,TRUE,TRUE,TRUE);
+    Free(tmpr);
+    tmpr=tmpr1;
+  }
+
+  while (num) {
+    StrPrint(buf, "@#%02d",num);
+    StrPrint(buf2,"@@%02d",num);
+    EdReplace(doc,buf,buf2,TRUE,TRUE,TRUE);
+    num-=ASM_RENUM_SPACING;
+  }
+  EdSelAll(doc,FALSE);
+  DocRecalc(doc);
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 EdCodeTools2(CDoc *doc,I64 tool_action,Bool beep=TRUE)
+{
+  Bool okay,unlock=DocLock(doc),start_of_line=TRUE;
+  CDocEntry *doc_e,*doc_ne;
+  I64 i,start_y,end_y,x,r,goto_line_num;
+  U8 *b,*st,*st2,*prj_file;
+  CTask *task=NULL;
+  CJob *tmpc;
+  CQueVectU8 *indent;
+
+  DocRecalc(doc);
+  goto_line_num=doc->cur_entry->y+1;
+
+  DocCaptureUndo(doc,TRUE);
+  switch (tool_action) {
+    case EF_CMP_CHK:
+      okay=FALSE;
+      if (doc->flags&DOCF_PLAIN_TEXT)
+        DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
+      DocWrite(doc);
+      task=Spawn(&SrvCmdLine,NULL,"Srv",,Fs);
+      st2=DirCur;
+      st=MStrPrint("Cd(\"%s\");",st2);
+      tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+      Free(st2);
+      Free(st);
+      WinHorz(Fs->win_left,Fs->win_right, task);
+      WinVert(Fs->win_top, Fs->win_bottom,task);
+      if (JobResScan(tmpc,&r)) {
+        st=DirFile(doc->filename.name,,"PRJ.Z");
+        prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
+        Free(st);
+        if (FileFind(prj_file)) {
+          st2=DirFile(prj_file),
+                st=MStrPrint("Cd(\"%s\");",st2);
+          Free(st2);
+          tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|
+                1<<JOBf_FOCUS_MASTER|1<<JOBf_FREE_ON_COMPLETE);
+          Free(st);
+          st=MStrPrint("\"$WW,1$\";Cmp(\"%s\",\"SysTmp\",\"SysTmp\");",
+                prj_file);
+          tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+          Free(st);
+          if (JobResScan(tmpc,&r))
+            if (!r) {
+              tmpc=TaskExe(task,Fs,
+                    "Load(\"SysTmp\",LDF_JUST_LOAD);",
+                    1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+              if (JobResScan(tmpc,&r))
+                okay=TRUE;
+            }
+          tmpc=TaskExe(task,Fs,"Del(\"SysTmp.*\");",
+                1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+          JobResScan(tmpc,&r);
+        } else {
+          Free(prj_file);
+          st=DirFile(doc->filename.name,"Load","HC.Z");
+          prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
+          Free(st);
+          if (FileFind(prj_file))
+            st=MStrPrint("\"$WW,1$\";ExeFile(\"%s\",CCF_JUST_LOAD);",prj_file);
+          else
+            st=MStrPrint("\"$WW,1$\";ExeFile(\"%s\",CCF_JUST_LOAD);",
+                  doc->filename.name);
+          tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+          Free(st);
+          if (JobResScan(tmpc,&r) && r)
+            okay=TRUE;
+        }
+        Free(prj_file);
+      }
+      if (!okay) {
+        PopUpOk("Has Errors");
+        while (LBts(&sys_semas[SEMA_FIX],0))
+          Yield;
+        ToFileLine(dbg.fix_file_line,&st,&i);
+        LBtr(&sys_semas[SEMA_FIX],0);
+        if (!StrCmp(st,doc->filename.name))
+          goto_line_num=i;
+        Free(st);
+      }
+      break;
+    case EF_REINDENT:
+      start_y=doc->cur_entry->y;
+      EdReplaceTroubleAll(doc,TRUE,FALSE);
+      DocGoToLine(doc,start_y+1);
+      if (EdGoToFun(doc,FALSE,FALSE)) {
+        start_y=doc->cur_entry->y;
+        indent=EdRICode(doc);
+        DocUnlock(doc);
+        if (beep) {
+          Snd(86); Sleep(150); Snd;
+          Sleep(100);
+          Snd(86); Sleep(150); Snd;
+        }
+        DocLock(doc);
+        EdRemFunLeadingSpace(doc);
+        DocGoToLine(doc,start_y+1);
+        doc_e=doc->cur_entry;
+        end_y=start_y+indent->total_cnt;
+        while (start_y<=doc_e->y<end_y) {
+          if (doc_e!=doc && doc_e!=doc->cur_entry &&
+                !(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X))) {
+            if (doc_e->type_u8==DOCT_NEW_LINE||
+                  doc_e->type_u8==DOCT_SOFT_NEW_LINE)
+              start_of_line=TRUE;
+            else {
+              if (start_of_line) {
+                i=QueVectU8Get(indent,doc_e->y)*C_INDENT_SPACES;
+                x=doc_e->x+1;
+                while (i>8) {
+                  doc_ne=DocEntryNewBase(doc,
+                        DOCT_TAB|doc->settings_head.dft_text_attr<<8,,
+                        x,doc_e->y,doc_e->page_line_num);
+                  MemCpy(&doc_ne->settings,
+                        &doc_e->settings,sizeof(CDocSettings));
+                  QueIns(doc_ne,doc_e->last);
+                  i-=8;
+                  x+=8;
+                }
+                if (i>0) {
+                  b=MAlloc(i+1,doc->mem_task);
+                  MemSet(b,CH_SPACE,i);
+                  b[i]=0;
+                  doc_ne=DocEntryNewBase(doc,
+                        DOCT_TEXT|doc->settings_head.dft_text_attr<<8,,
+                        x,doc_e->y,doc_e->page_line_num);
+                  doc_ne->tag=b;
+                  doc_ne->max_col=1;
+                  MemCpy(&doc_ne->settings,
+                        &doc_e->settings,sizeof(CDocSettings));
+                  QueIns(doc_ne,doc_e->last);
+                }
+              }
+              start_of_line=FALSE;
+            }
+          }
+          doc_e=doc_e->next;
+        }
+        QueVectU8Del(indent);
+      }
+      start_y=doc->cur_entry->y;
+      EdReplaceTroubleAll(doc,FALSE,FALSE);
+      DocGoToLine(doc,start_y+1);
+      break;
+    case EF_RENUM_ASM:
+      if (EdGoToFun(doc,FALSE,TRUE)) {
+        if (EdCurU8(doc)=='{') {
+          EdCursorRight(doc);
+          DocRecalc(doc);
+        } else if (EdCurU8(doc)==':') {
+          EdCursorRight(doc);
+          if (EdCurU8(doc)==':')
+            EdCursorRight(doc);
+          DocRecalc(doc);
+        }
+        DocUnlock(doc);
+        if (beep) {
+          Snd(86); Sleep(150); Snd;
+          Sleep(100);
+          Snd(86); Sleep(150); Snd;
+        }
+        DocLock(doc);
+        EdRenumAsm(doc);
+      }
+      break;
+  }
+
+  DocRecalc(doc);
+  DocGoToLine(doc,goto_line_num);
+
+  DocUnlock(doc);
+  if (!unlock)
+    DocLock(doc);
+  if (task)
+    Kill(task,FALSE);
+}
+
+U0 EdPopUpChSC(I64 *_ch,I64 *_sc)
+{
+  I64 sc;
+  "Press A Key\n";
+  DocPut->flags|=DOCF_SIZE_MIN;
+  do GetMsg(_ch,&sc,1<<MSG_KEY_DOWN);
+  while (sc.u8[0]==SC_SHIFT || sc.u8[0]==SC_CTRL || sc.u8[0]==SC_ALT);
+  *_sc=sc;
+}
+
+U0 EdChSC(CDoc *doc)
+{
+  I64 ch,sc;
+  U8 buf[STR_LEN];
+  StrPrint(buf,"EdPopUpChSC(%d,%d);",&ch,&sc);
+  PopUp(buf,Fs);
+  if (ch==CH_BACKSPACE)
+    DocPrint(doc,"CH_BACKSPACE,0x%X",sc);
+  else if (ch=='\n')
+    DocPrint(doc,"'\n',0x%X",sc);
+  else if (CH_CTRLA<=ch<=CH_CTRLZ)
+    DocPrint(doc,"CH_CTRL%C,0x%X",ch+'@',sc);
+  else if (ch=='$')
+    DocPrint(doc,"'$$',0x%X",sc);
+  else if (ch=='\\')
+    DocPrint(doc,"'\\\\',0x%X",sc);
+  else if (ch=='\'')
+    DocPrint(doc,"'\\\'',0x%X",sc);
+  else if (ch==CH_ESC)
+    DocPrint(doc,"CH_ESC,0x%X",sc);
+  else if (ch==CH_SHIFT_ESC)
+    DocPrint(doc,"CH_SHIFT_ESC,0x%X",sc);
+  else if (ch==CH_SPACE)
+    DocPrint(doc,"CH_SPACE,0x%X",sc);
+  else if (ch==CH_SHIFT_SPACE)
+    DocPrint(doc,"CH_SHIFT_SPACE,0x%X",sc);
+  else if (Bt(char_bmp_displayable,ch))
+    DocPrint(doc,"'%c',0x%X",ch,sc);
+  else
+    DocPrint(doc,"0x%X,0x%X",ch,sc);
+}
+
+U0 EdCodeTools(CDoc *doc)
+{
+  I64 tool_action=PopUpEdFmt;
+  switch (tool_action) {
+    case EF_CMP_CHK:
+    case EF_REINDENT:
+    case EF_RENUM_ASM:
+      EdCodeTools2(doc,tool_action);
+      break;
+    case EF_CTRL_SLIDER:
+      TemplateCtrlSlider(doc);
+      break;
+    case EF_CH_SC:
+      EdChSC(doc);
+      break;
+  }
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocDblBuf.HC.HTML b/public/Wb/Adam/DolDoc/DocDblBuf.HC.HTML new file mode 100755 index 0000000..f86e075 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocDblBuf.HC.HTML @@ -0,0 +1,141 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Task;StdOut/Task"
+public CDoc *DocPut(CTask *task=NULL)
+{//Current document that StdOut Put() goes to.
+//Basically, StdOut unless double buffering.
+  CDoc *res;
+  if (!task) task=Fs;
+  if (Bt(&task->task_flags,TASKf_INPUT_FILTER_TASK))
+    task=task->parent_task;
+  if ((res=task->put_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
+    return res;
+  else
+    return NULL;
+}
+
+public CDoc *DocDisplay(CTask *task=NULL)
+{//StdOut displayed unless double buffering.
+  CDoc *res;
+  if (!task) task=Fs;
+  if ((res=task->display_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
+    return res;
+  else
+    return NULL;
+}
+
+public CDoc *DocBorder(CTask *task=NULL)
+{//Doc holding border of window text.
+  CDoc *res;
+  if (!task) task=Fs;
+  if ((res=task->border_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
+    return res;
+  else
+    return NULL;
+}
+
+public CDoc *DocDblBufStart(CTask *task=NULL)
+{//See ::/Demo/Spy.HC
+  Bool unlock_ddoc;
+  CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task),*res;
+  if (!pdoc || !ddoc || pdoc!=ddoc)
+    res=NULL; //Already Double buffering
+  else {
+    if (!task) task=Fs;
+    unlock_ddoc=DocLock(ddoc); //dont change during winupdate, so lock DocPut
+    res=DocNew(,task);
+    res->win_task               =ddoc->win_task;
+    res->max_entries            =ddoc->max_entries;
+    MemCpy(res->find_replace,ddoc->find_replace,sizeof(CEdFindText));
+    MemCpy(&res->filename,&ddoc->filename,sizeof(CEdFileName));
+    res->left_click_link        =ddoc->left_click_link;
+    res->right_click_link       =ddoc->right_click_link;
+    res->user_put_data  =ddoc->user_put_data;
+    res->user_put_key   =ddoc->user_put_key;
+    res->user_put_s             =ddoc->user_put_s;
+    res->parent_doc             =ddoc->parent_doc;
+    res->desc           =ddoc->desc;
+    res->user_data              =ddoc->user_data;
+    res->flags|=ddoc->flags&DOCG_DBL_BUF_FLAGS | DOCF_DONT_SHOW;
+    task->put_doc=res;
+    if (unlock_ddoc)
+      DocUnlock(ddoc);
+  }
+  return res;
+}
+
+public Bool DocDblBufEnd(CTask *task=NULL)
+{//See ::/Demo/Spy.HC
+  Bool res=FALSE;
+  CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
+  if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
+    if (!task) task=Fs;
+    ddoc->flags|=DOCF_DONT_SHOW;
+    pdoc->flags&=~DOCF_DONT_SHOW;
+    DocLock(ddoc);
+    task->display_doc=pdoc;
+    DocUnlock(ddoc);
+    DocDel(ddoc);
+    res=TRUE;
+  }
+  return res;
+}
+
+public Bool DocDblBufSwap(CTask *task=NULL)
+{//See ::/Demo/Spy.HC
+  Bool res=FALSE;
+  CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
+  if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
+    if (!task) task=Fs;
+    ddoc->flags|=DOCF_DONT_SHOW;
+    pdoc->flags&=~DOCF_DONT_SHOW;
+    DocLock(ddoc);
+    task->display_doc=pdoc;
+    DocUnlock(ddoc);
+    DocRst(ddoc,TRUE);
+    MemCpy(ddoc->find_replace,pdoc->find_replace,sizeof(CEdFindText));
+    MemCpy(&ddoc->filename,&pdoc->filename,sizeof(CEdFileName));
+    ddoc->max_entries           =pdoc->max_entries;
+    ddoc->flags                 =pdoc->flags&DOCG_DBL_BUF_FLAGS |
+          ddoc->flags&~DOCG_DBL_BUF_FLAGS;
+    ddoc->left_click_link       =pdoc->left_click_link;
+    ddoc->right_click_link      =pdoc->right_click_link;
+    ddoc->user_put_data         =pdoc->user_put_data;
+    ddoc->user_put_key          =pdoc->user_put_key;
+    ddoc->user_put_s            =pdoc->user_put_s;
+    ddoc->desc                  =pdoc->desc;
+    ddoc->user_data             =pdoc->user_data;
+    task->put_doc=ddoc;
+    res=TRUE;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocEd.HC.HTML b/public/Wb/Adam/DolDoc/DocEd.HC.HTML new file mode 100755 index 0000000..f728497 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocEd.HC.HTML @@ -0,0 +1,296 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+
+public Bool View()
+{//Go live for user interaction until <ESC> or <SHIFT-ESC>.
+  I64 ch;
+  do ch=DocGetKey;
+  while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  return ch==CH_ESC;
+}
+
+#help_index "DolDoc"
+U8 *EdOverStrikeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags & DOCF_OVERSTRIKE)
+    *st='O';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdAutoSaveCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags & DOCF_AUTO_SAVE)
+    *st='S';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdFilterCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->find_replace->filter_lines)
+    *st='F';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdDollarCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags & DOCF_IN_DOLLAR)
+    *st='$';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdMoreCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags&DOCF_MORE)
+    StrCpy(st,"More.");
+  else
+    StrCpy(st,".....");
+  return st;
+}
+
+U8 *EdDollarTypeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *src=DefineSub(doc->cur_entry->type_u8,"ST_DOC_CMDS"),
+        *st=CAlloc(8,mem_task);
+  if (doc->cur_entry==doc)
+    src="EOF";
+  else if (!src)
+    src="ERR";
+  StrPrint(st,"%-3ts",src);
+  return st;
+}
+
+public Bool DocEd(CDoc *doc,I64 dof_flags=0)
+{//Live for user interaction. End on <ESC> or <SHIFT-ESC>.
+  CDoc *old_put_doc       =DocPut,
+        *old_display_doc=DocDisplay,
+        *old_border_doc =DocBorder,*bdoc;
+  CDocEntry *doc_e;
+  I64 old_attr=Fs->text_attr,
+        old_top =Fs->win_top, old_bottom=Fs->win_bottom,
+        old_left=Fs->win_left,old_right =Fs->win_right,
+        old_title_src=Fs->title_src;
+  Bool res,unlock;
+  U8 *old_task_title;
+  if (dof_flags&DOF_WIN_MAX)
+    WinMax;
+
+  unlock=DocLock(doc);
+  doc->win_task=Fs;
+  bdoc=DocNew;
+  bdoc->flags|=DOCF_BORDER_DOC;
+  DocPrint(bdoc,"$CM+TY+LX+NC,0,-1$");
+  DocPrint(bdoc,"$TX+RX+BD,\"[X]\"$");
+  DocPrint(bdoc,"$BK,1$$TX+LX+BD,\"MENU\"$$BK,0$");
+
+  old_task_title=StrNew(Fs->task_title);
+  if (Fs->title_src!=TTS_LOCKED_CONST) {
+    Fs->title_src=TTS_ED_FILENAME;
+    MemCpy(Fs->task_title,doc->filename.name,STR_LEN-1);
+  }
+  doc_e=DocPrint(bdoc,"$DA-TRM-P+BD+RD+CX+IV,LEN=STR_LEN-1,"
+        "A=\"%%s...\",SCX=16$");
+  doc_e->data=&Fs->task_title;
+  DocDataFmt(bdoc,doc_e);
+
+  if (doc->flags & DOCF_ALLOW_UNDO) {
+    DocPrint(bdoc,"$CM+BY+LX+NC,1,1$");
+    doc_e=DocPrint(bdoc,"$DA+BD+RD-TRM,RT=U32,A=\"Undo:%%03d\"$\n");
+    doc_e->data=&doc->undo_cnt;
+    DocDataFmt(bdoc,doc_e);
+  }
+
+  DocPrint(bdoc,"$CM+BY+RX+NC,-31,1$");
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\"     \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdMoreCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdDollarTypeCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdFilterCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdOverStrikeCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdAutoSaveCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdDollarCB;
+  doc_e=DocPrint(bdoc,"$DA+BD+RD-TRM,A=\"Line:%%04d \"$");
+  doc_e->data=&doc->line;
+  DocDataFmt(bdoc,doc_e);
+  doc_e=DocPrint(bdoc,"$DA+BD+RD-TRM,A=\"Col:%%04d\"$\n");
+  doc_e->data=&doc->col;
+  DocDataFmt(bdoc,doc_e);
+
+  DocRecalc(bdoc);
+  DocRecalc(doc);
+  if (!(dof_flags&DOF_DONT_HOME))
+    DocTop(doc);
+  Fs->border_doc=bdoc;
+  if (doc!=old_display_doc)
+    doc->parent_doc=old_display_doc;
+  Fs->put_doc=Fs->display_doc=doc;
+  if (!(dof_flags&DOF_DONT_TEXT_ATTR))
+    Fs->text_attr=DOC_ATTR_DFT_TEXT;
+  if (!(dof_flags&DOF_DONT_SHOW)) {
+    LBts(&Fs->display_flags,DISPLAYf_SHOW);
+    WinZBufUpdate;
+  }
+  if (dof_flags&DOF_SIZE_MIN)
+    doc->flags|=DOCF_SIZE_MIN;
+
+  DocUnlock(doc);
+  if (!(dof_flags&DOF_DONT_WINMGR_SYNC)) {
+    Refresh(2,TRUE);
+    if (doc->flags&DOCF_SIZE_MIN)
+      Refresh(2,TRUE);
+  }
+  res=View;
+
+  DocLock(doc);
+  if (res) {
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX)
+        DocDataScan(doc,doc_e);
+      doc_e=doc_e->next;
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  Fs->border_doc =old_border_doc;
+  Fs->display_doc=old_display_doc;
+  Fs->put_doc    =old_put_doc;
+  Fs->text_attr  =old_attr;
+  if (Fs->title_src!=TTS_LOCKED_CONST) {
+    Fs->title_src  =old_title_src;
+    StrCpy(Fs->task_title,old_task_title);
+  }
+  Free(old_task_title);
+  DocDel(bdoc);
+  if (dof_flags&DOF_SIZE_MIN) {
+    WinHorz(old_left,old_right);
+    WinVert(old_top,old_bottom);
+  }
+  return res;
+}
+
+#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
+public Bool Ed(U8 *link_st,I64 edf_dof_flags=0)
+{//Invoke document editor.
+  U8 *filename,*needle_str;
+  I64 i,num;
+  Bool cont,res=FALSE;
+  CDoc *doc;
+
+  switch (i=EdLinkCvt(link_st,&filename,&needle_str,&num,edf_dof_flags)) {
+    case -1:
+      break;
+    case LK_DEF:
+      doc=DocNew;
+      doc->desc='DictDef';
+      ACDDefsPut(doc,filename,num);
+      goto ej_doc;
+    case LK_HELP_INDEX:
+      doc=DocNew;
+      doc->desc='HelpIndx';
+      DocHelpIdx(doc,filename);
+ej_doc:
+      if (!(edf_dof_flags&EDF_BAIL)) {
+        DocEd(doc);
+        DocDel(doc);
+      }
+      if (!(edf_dof_flags&EDF_WAS_WRITE))
+        res=TRUE;
+      break;
+    default:
+      if (IsRaw)
+        res=EdLite(filename,num,edf_dof_flags);
+      else {
+        cont=TRUE;
+        if (!(edf_dof_flags&EDF_BAIL) && !(LK_DOC<=i<=LK_DOC_LINE) &&
+              !FilesFindMatch(filename,FILEMASK_TXT) &&
+              !PopUpCancelOk(ST_WARN_ST "Not Text File\n\n"))
+          cont=FALSE;
+        if (cont)
+          res=DocFileEd(i,filename,needle_str,&num,edf_dof_flags);
+      }
+  }
+  Free(filename);
+  Free(needle_str);
+  return res;
+}
+
+public Bool Plain(U8 *filename,I64 edf_dof_flags=0)
+{//Edit document in plain text mode, so dollar signs are not special.
+  Bool res;
+  U8 *st=MStrPrint("PI:%s",filename);
+  res=Ed(st,edf_dof_flags);
+  Free(st);
+  return res;
+}
+
+#help_index "DolDoc;Job/Exe;Task/Job/Exe"
+public I64 PopUpEd(U8 *filename,CTask *parent=NULL,CTask **_pu_task=NULL)
+{//Create PopUp win task and edit a doc.
+  U8 *st=MStrPrint("Ed(\"%Q\");",filename);
+  I64 res=PopUp(st,parent,_pu_task);
+  Free(st);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocExt.HC.HTML b/public/Wb/Adam/DolDoc/DocExt.HC.HTML new file mode 100755 index 0000000..670d919 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocExt.HC.HTML @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+extern Bool DocEd(CDoc *doc,I64 dof_flags=0);
+extern I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,
+        Bool exited,I64 *_has_action=NULL);
+extern U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE);
+extern Bool DocGoToLine(CDoc *doc,I64 line_num);
+extern U0 DocLoad(CDoc *doc,U8 *src2,I64 size);
+extern U0 DocPrintAtomic(CDoc *doc=NULL,U8 *fmt,...);
+extern U0 DocPrintPartial(CDoc *doc=NULL,U8 *fmt,...);
+extern CDocEntry *DocPutS(CDoc *doc,U8 *st);
+extern U8 *DocSave(CDoc *doc,I64 *_size=NULL);
+extern I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e);
+extern I64 PopUpPickLst(U8 *lst);
+extern I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e);
+
+ diff --git a/public/Wb/Adam/DolDoc/DocFile.HC.HTML b/public/Wb/Adam/DolDoc/DocFile.HC.HTML new file mode 100755 index 0000000..099e603 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocFile.HC.HTML @@ -0,0 +1,388 @@ + + + + + + + + + + + +
+#help_index "DolDoc/File"
+
+public U0 DocLoad(CDoc *doc,U8 *src2,I64 size)
+{//Fetch doc from raw mem buf.
+  I64 i;
+  U8 *src;
+  Bool unlock=DocLock(doc);
+  CDocBin *tmpb;
+  doc->find_replace->filter_lines=0;
+  if (src2) {
+    DocPutS(doc,src2); //Too big DocPrint() is wasteful.
+    src=src2+StrLen(src2)+1;
+    i=size-(offset(CDocBin.end)-offset(CDocBin.start));
+    while (src<=src2+i) {
+      tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
+      MemCpy(&tmpb->start,src,offset(CDocBin.end)-offset(CDocBin.start));
+      src+=offset(CDocBin.end)-offset(CDocBin.start);
+      tmpb->data=MAlloc(tmpb->size,doc->mem_task);
+      if (tmpb->size) {
+        MemCpy(tmpb->data,src,tmpb->size);
+        src+=tmpb->size;
+      }
+      QueIns(tmpb,doc->bin_head.last);
+      if (tmpb->num>=doc->cur_bin_num)
+        doc->cur_bin_num=tmpb->num+1;
+    }
+  }
+  if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
+    DocBinsValidate(doc);
+  DocTop(doc); //Calls DocRecalc().  DOCT_CURSOR will be set.
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public CDoc *DocRead(U8 *name=NULL,I64 flags=0)
+{//Fetch doc from disk. See flags.
+  CDoc *doc=DocNew;
+  U8 *src,*name2;
+  I64 size=0;
+  CDirContext *dirc;
+  if (!name) name=blkdev.tmp_filename;
+  doc->flags|=flags;
+  name2=FileNameAbs(name);
+  StrCpy(doc->filename.name,name2);
+  if (src=FileRead(name2,&size,&doc->file_attr)) {
+    if (dirc=DirContextNew(name2)) {
+      DocLoad(doc,src,size);
+      DirContextDel(dirc);
+    }
+    Free(src);
+  }
+  Free(name2);
+  return doc;
+}
+
+public U8 *DocSave(CDoc *doc,I64 *_size=NULL)
+{//Store doc to raw mem buf.
+  CDocEntry *doc_e,*doc_e1;
+  CDocBin *b;
+  Bool unlock=DocLock(doc);
+  I64 ch,cnt=1;//terminator
+  U8 *st,*res,*dst,*src;
+
+  if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
+    DocBinsValidate(doc);
+  if (doc->flags&DOCF_NO_CURSOR)
+    DocRecalc(doc);
+  else {
+    DocRecalc(doc,RECALCF_ADD_CURSOR);
+    if (doc->head.next->type_u8==DOCT_CURSOR)
+      DocEntryDel(doc,doc->head.next); //If no cursor, DocLoad() puts at top.
+  }
+  for (doc_e=doc->head.next;doc_e!=doc;doc_e=doc_e->next) {
+    if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
+      switch (doc_e->type_u8) {
+        case DOCT_TAB:
+        case DOCT_PAGE_BREAK:
+        case DOCT_CURSOR:
+          cnt++;
+          break;
+        case DOCT_NEW_LINE:
+          if (doc->flags&DOCF_CARRIAGE_RETURN)
+            cnt+=2;
+          else
+            cnt++;
+          break;
+        case DOCT_SOFT_NEW_LINE:
+          break;
+        case DOCT_TEXT:
+          if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
+                DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP))&&
+                !(doc_e->type&DOCG_BL_IV_UL)) {
+            cnt+=StrLen(doc_e->tag);
+            if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)) ||
+                  doc->flags&DOCF_DBL_DOLLARS)
+              cnt+=StrOcc(doc_e->tag,'$');
+            break;
+          }
+        default:
+          st=Doc2PlainText(doc,doc_e);
+          cnt+=StrLen(st)+2;
+          Free(st);
+      }
+    }
+  }
+  for (b=doc->bin_head.next;b!=&doc->bin_head;b=b->next)
+    if (b->use_cnt>b->tmp_use_cnt)
+      cnt+=offset(CDocBin.end)-offset(CDocBin.start)+b->size;
+  res=MAlloc(cnt);
+  dst=res;
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (!Bt(doldoc.type_flags_data,doc_e->type_u8))
+      switch (doc_e->type_u8) {
+        case DOCT_CURSOR:
+          DocEntryDel(doc,doc_e);
+          *dst++=CH_CURSOR;
+          break;
+        case DOCT_TAB:
+          *dst++='\t';
+          break;
+        case DOCT_NEW_LINE:
+          if (doc->flags&DOCF_CARRIAGE_RETURN)
+            *dst++='\r';
+          *dst++='\n';
+          break;
+        case DOCT_SOFT_NEW_LINE:
+          break;
+        case DOCT_TEXT:
+          if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
+                DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
+                !(doc_e->type&DOCG_BL_IV_UL)) {
+            src=doc_e->tag;
+            while (ch=*src++) {
+              *dst++=ch;
+              if (ch=='$' && (!(doc->flags & (DOCF_PLAIN_TEXT|
+                    DOCF_PLAIN_TEXT_TABS)) || doc->flags&DOCF_DBL_DOLLARS))
+                *dst++=ch;
+            }
+            break;
+          }
+        default:
+          *dst++='$';
+          st=Doc2PlainText(doc,doc_e);
+          StrCpy(dst,st);
+          dst+=StrLen(st);
+          *dst++='$';
+          Free(st);
+      }
+    doc_e=doc_e1;
+  }
+  *dst++=0;
+  b=doc->bin_head.next;
+  if (b!=&doc->bin_head) {
+    do {
+      if (b->use_cnt>b->tmp_use_cnt) {
+        MemCpy(dst,&b->start,offset(CDocBin.end)-offset(CDocBin.start));
+        dst+=offset(CDocBin.end)-offset(CDocBin.start);
+        MemCpy(dst,b->data,b->size);
+        dst+=b->size;
+      }
+      b=b->next;
+    } while (b!=&doc->bin_head);
+  } else
+    cnt--; //No terminator
+  if (_size) *_size=cnt;
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public Bool DocWrite(CDoc *doc,Bool prompt=FALSE)
+{//Store doc to disk.
+  I64 size;
+  U8 *buf;
+  if (prompt && !DocForm(&doc->filename) ||
+        doc->filename.name[0]=='A' && doc->filename.name[2]==':')
+    return FALSE;  //CANCEL || LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE?
+  buf=DocSave(doc,&size);
+  FileWrite(doc->filename.name,buf,size,0,doc->file_attr);
+  Free(buf);
+  return TRUE;
+}
+
+#help_index "DolDoc"
+public U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2)
+{//Insert copy of doc2 into doc at insert pt, cur_entry.
+//TODO: DocRst
+  U8 *dst;
+  Bool unlock_doc,unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_ne,*doc_e=doc2->head.next,*doc_ce;
+  if (!doc) doc=DocPut;
+  unlock_doc=DocLock(doc),
+        DocRemSoftNewLines(doc,NULL);
+  doc_ce=doc->cur_entry;
+  if (doc_ce->type_u8==DOCT_TEXT && doc->cur_col>doc_ce->min_col) {
+    if (doc->cur_col<doc_ce->max_col) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      doc_ne->type=DOCT_TEXT | doc_ce->type & 0xFFFFFF00;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+      doc->cur_entry=doc_ne;
+      doc->cur_col=doc_ne->min_col;
+    } else
+      if (doc_ce!=doc)
+        doc->cur_entry=doc_ce->next;
+  }
+  while (doc_e!=doc2) {
+    if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE) {
+      doc_ne=DocEntryCopy(doc,doc_e);
+      QueIns(doc_ne,doc->cur_entry->last);
+    }
+    doc_e=doc_e->next;
+  }
+  DocRecalc(doc);
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+#help_index "DolDoc/Compiler;Compiler/Directive"
+public U0 StreamDoc(CDoc *doc)
+{//Inject doc into compile stream. Use inside #exe{}.
+//TODO: DocRst
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      StreamPrint("%s",doc_e->tag);
+    else if (doc_e->type_u8==DOCT_NEW_LINE)
+      StreamPrint("\n");
+    else if (doc_e->type_u8==DOCT_TAB)
+      StreamPrint("\t");
+    doc_e=doc_e->next;
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+#help_index "DolDoc"
+Bool DocCaptureUndo(CDoc *doc,Bool force=FALSE)
+{
+  Bool res=FALSE,unlock;
+  I64 time_stamp,flags;
+  CDocUndo *u;
+  if (doc->flags&DOCF_ALLOW_UNDO) {
+    unlock=DocLock(doc);
+    time_stamp=GetTSC;
+    if (doc->flags&DOCF_UNDO_DIRTY &&
+          time_stamp>doc->undo_head.last->time_stamp+cnts.time_stamp_freq<<4 ||
+          force) {
+      u=CAlloc(sizeof(CDocUndo),doc->mem_task);
+      u->time_stamp=time_stamp;
+      flags=doc->flags;
+      doc->flags&=~DOCF_NO_CURSOR;
+      u->body=DocSave(doc,&u->size);
+      doc->flags=flags;
+      QueIns(u,doc->undo_head.last);
+      doc->flags&=~DOCF_UNDO_DIRTY;
+      doc->undo_cnt++;
+      u->doc_flags=doc->flags;
+      res=TRUE;
+      if (doc->flags&DOCF_AUTO_SAVE)
+        DocWrite(doc);
+    }
+    if (unlock)
+      DocUnlock(doc);
+  }
+  return res;
+}
+ 
+U0 DocUndoRestore(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocUndo *u=doc->undo_head.last,*u_next,*u_last;
+  if (u!=&doc->undo_head) {
+    QueRem(u);
+    u_next=doc->undo_head.next;
+    u_last=doc->undo_head.last;
+    QueInit(&doc->undo_head);
+    DocRst(doc,TRUE);
+    doc->flags=u->doc_flags&~DOCF_NO_CURSOR;
+    DocLoad(doc,u->body,u->size);
+    doc->flags=u->doc_flags;
+    DocUndoDel(doc,u);
+    doc->undo_head.next=u_next;
+    doc->undo_head.last=u_last;
+  }
+  DocUndoCntSet(doc);
+  doc->flags&=~DOCF_UNDO_DIRTY;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+#help_index "Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
+public Bool DocType(CDoc *doc=NULL,U8 *filename,I64 trailing_new_lines=1)
+{//Output txt or graphic file to document.
+  Bool res=FALSE;
+  CDoc *doc2;
+  if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return FALSE;
+  if (FilesFindMatch(filename,FILEMASK_TXT)) {
+    doc2=DocRead(filename);
+    DocInsDoc(doc,doc2);
+    if (IsRaw)
+      DocDump(doc2,100000);
+    DocDel(doc2);
+    res=TRUE;
+  } else if (FilesFindMatch(filename,"*.GR*")) {
+    DocGR(doc,filename);
+    res=TRUE;
+  }
+  if (res)
+    DocPrint(doc,"%h*c",trailing_new_lines,'\n');
+  return res;
+}
+
+#help_index "Graphics/GR Files;"\
+        "File/Cmd Line (Typically);DolDoc/Cmd Line (Typically);"\
+        "StdOut;Cmd Line (Typically)"
+public Bool Type(U8 *filename,I64 trailing_new_lines=1)
+{//Output txt or graphic file to command line.
+  return DocType(,filename,trailing_new_lines);
+}
+
+#help_index "DolDoc/File"
+
+public U8 *DocLineRead(U8 *filename,I64 line,CTask *mem_task=NULL)
+{//Extract line from stored doc file. (Slow.)
+  U8 *res=NULL;
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  if (DocGoToLine(doc,line) && doc->cur_entry->type_u8==DOCT_TEXT)
+    res=StrNew(doc->cur_entry->tag,mem_task);
+  DocDel(doc);
+  return res;
+}
+
+public U8 *DocLineWrite(U8 *filename,I64 line,U8 *st)
+{//Write line to stored doc file. (Slow.)
+  U8 *res=NULL;
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  if (DocGoToLine(doc,line)) {
+    if (doc->cur_entry->type_u8==DOCT_TEXT) {
+      Free(doc->cur_entry->tag);
+      doc->cur_entry->tag=StrNew(st);
+    } else
+      DocPrint(doc,"%s",st);
+    DocTop(doc);
+    DocWrite(doc);
+  }
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocFind.HC.HTML b/public/Wb/Adam/DolDoc/DocFind.HC.HTML new file mode 100755 index 0000000..e7de5ed --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocFind.HC.HTML @@ -0,0 +1,615 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Editor"
+
+public Bool DocGoToLine(CDoc *doc,I64 line_num) //one based
+{//Nearest to specified line num.  Move cur_entry & center.
+  Bool res=FALSE,unlock;
+  if (doc) {
+    unlock=DocLock(doc);
+    doc->x=0;
+    doc->y=line_num-1;
+    DocRecalc(doc,RECALCt_FIND_CURSOR);
+    DocCenter(doc);
+    if (doc->cur_entry->y==line_num-1)
+      res=TRUE;
+    if (unlock)
+      DocUnlock(doc);
+  }
+  return res;
+}
+
+public Bool DocFind(CDoc *haystack_doc,I64 start_line_num=I64_MIN,
+U8 *needle,I64 match=1)
+{//Find str by searching tags. Move cur_entry & center.
+  Bool res=FALSE,unlock;
+  CDocEntry *doc_e;
+  U8 *ptr;
+  I64 i;
+  if (haystack_doc) {
+    unlock=DocLock(haystack_doc);
+    if (start_line_num==I64_MIN) {
+      res=TRUE;
+      doc_e=haystack_doc->head.next;
+    } else {
+      res=DocGoToLine(haystack_doc,start_line_num);
+      doc_e=haystack_doc->cur_entry;
+    }
+    if (res) {
+      if (needle) {
+        res=FALSE;
+        while (doc_e!=haystack_doc) {
+          if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
+//TODO: handle multi-DocEntry strs
+                (ptr=StrIMatch(needle,doc_e->tag))) {
+            i=ptr-doc_e->tag;
+            if (!--match) {
+              haystack_doc->cur_entry=doc_e;
+              if (i<doc_e->min_col) i=doc_e->min_col;
+              if (i>doc_e->max_col) i=doc_e->max_col;
+              haystack_doc->cur_col=i;
+              res=TRUE;
+              break;
+            }
+          }
+          doc_e=doc_e->next;
+        }
+      } else
+        res=FALSE;
+    }
+    if (!res) DocBottom(haystack_doc);
+    DocCenter(haystack_doc);
+    if (unlock)
+      DocUnlock(haystack_doc);
+  }
+  return res;
+}
+
+public Bool DocAnchorFind(CDoc *haystack_doc,U8 *needle_str)
+{//Find named anchor. Move cur_entry & center.
+  Bool res=FALSE,unlock;
+  CDocEntry *doc_e;
+  if (haystack_doc) {
+    unlock=DocLock(haystack_doc);
+    doc_e=haystack_doc->head.next;
+    if (needle_str)
+      while (doc_e!=haystack_doc) {
+        if (doc_e->type_u8==DOCT_ANCHOR && doc_e->de_flags & DOCEF_AUX_STR) {
+          if (!StrCmp(needle_str,doc_e->aux_str)) {
+            haystack_doc->cur_entry=doc_e;
+            haystack_doc->cur_col=doc_e->min_col;
+            res=TRUE;
+            break;
+          }
+        }
+        doc_e=doc_e->next;
+      }
+    if (!res) DocBottom(haystack_doc);
+    DocCenter(haystack_doc);
+    if (unlock)
+      DocUnlock(haystack_doc);
+  }
+  return res;
+}
+
+public U0 EdFindNext(CDoc *doc)
+{//Editor F3 find next, possibly doing replaces.
+  Bool unlock=DocLock(doc);
+  U8 *ptr,*ptr2,*ptr3;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce;
+  I64 sf_flags;
+  if (doc->find_replace->match_case)
+    sf_flags=0;
+  else
+    sf_flags=SFF_IGNORE_CASE;
+  if (doc->find_replace->whole_labels)
+    sf_flags|=SFG_WHOLE_LABELS;
+  do {
+    if (doc_e!=doc) {
+      if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
+            !(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP))) {
+        if (doc_e->type & DOCET_SEL ||
+              !doc->find_replace->scan_sel_text) {
+          if (doc->find_replace->scan_fwd) {
+            if (doc_e==doc_ce) {
+              ptr=doc_ce->tag+doc->cur_col+1;
+              if (ptr-doc_ce->tag>=doc_ce->max_col)
+                goto fn_skip;
+              if (ptr-doc_ce->tag<doc_ce->min_col)
+                ptr=doc_ce->tag+doc_ce->min_col;
+            } else
+              ptr=doc_e->tag;
+            if (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
+              doc->cur_entry=doc_e;
+              doc->cur_col=ptr-doc_e->tag;
+              if (doc->cur_col>=doc_e->max_col)
+                doc->cur_col=doc_e->max_col-1;
+              if (doc->cur_col<doc_e->min_col)
+                doc->cur_col=doc_e->min_col;
+              DocCenter(doc);
+              if (unlock)
+                DocUnlock(doc);
+              return;
+            }
+          } else {
+            ptr2=NULL;
+            ptr=doc_e->tag+doc_e->min_col;
+            if (doc_e==doc_ce)
+              ptr3=doc_ce->tag+doc->cur_col;
+            else
+              ptr3=doc_e->tag+doc_e->max_col;
+            while (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
+              if (ptr>=ptr3)
+                break;
+              ptr2=ptr++;
+            }
+            if (ptr2 && ptr2<ptr3) {
+              doc->cur_entry=doc_e;
+              doc->cur_col=ptr2-doc_e->tag;
+              if (doc->cur_col>=doc_e->max_col)
+                doc->cur_col=doc_e->max_col-1;
+              if (doc->cur_col<doc_e->min_col)
+                doc->cur_col=doc_e->min_col;
+              DocCenter(doc);
+              if (unlock)
+                DocUnlock(doc);
+              return;
+            }
+          }
+        }
+      }
+    }
+fn_skip:
+    if (doc->find_replace->scan_fwd)
+      doc_e=doc_e->next;
+    else
+      doc_e=doc_e->last;
+  } while (doc_e!=doc_ce);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdSelAll(CDoc *doc,Bool sel)
+{//Set state of DOCET_SEL on all entries.
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    BEqu(&doc_e->type,DOCEt_SEL,sel);
+    doc_e=doc_e->next;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public Bool EdFindPaired(CDoc *doc,U8 plus,U8 minus,
+Bool fwd,Bool abort_on_dbl_colon=FALSE)
+{//Find { } or ( ) pair. Move cur_entry & center.
+  Bool unlock=DocLock(doc),res=FALSE;
+  U8 *ptr;
+  I64 ch,levels=0,colons=0,original_col=doc->cur_col;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce,*original_ce=doc_ce;
+  if (abort_on_dbl_colon && EdCurU8(doc)==':')
+    colons=1;
+  else
+    colons=0;
+  do {
+    if (doc_e!=doc) {
+      if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
+            !(doc_e->de_flags&DOCEF_FILTER_SKIP)) {
+        if (fwd) {
+          if (doc_e==doc_ce)
+            ptr=doc_e->tag+doc->cur_col+1;
+          else
+            ptr=doc_e->tag;
+          if (ptr-doc_e->tag<doc_e->min_col)
+            ptr=doc_e->tag+doc_e->min_col;
+          if (ptr-doc_e->tag>=doc_e->max_col)
+            goto pa_skip;
+          while (ch=*ptr++)
+            if (abort_on_dbl_colon && ch==':') {
+              if (++colons==2) {
+                doc->cur_entry=doc_e;
+                doc->cur_col=ptr-doc_e->tag-1;
+                EdCursorLeft(doc);
+                res=FALSE;
+                goto pa_done;
+              }
+            } else {
+              colons=0;
+              if (ch==plus)
+                levels++;
+              else if (ch==minus) {
+                if (!levels--) {
+                  doc->cur_entry=doc_e;
+                  doc->cur_col=ptr-doc_e->tag-1;
+                  res=doc->cur_entry!=original_ce ||
+                        doc->cur_col!=original_col;
+                  goto pa_done;
+                }
+              }
+            }
+        } else {
+          if (doc_e==doc_ce) {
+            ptr=doc_e->tag+doc->cur_col-1;
+            if (ptr-doc_e->tag>=doc_e->max_col)
+              ptr=doc_e->tag+doc_e->max_col-1;
+          } else
+            ptr=doc_e->tag+doc_e->max_col-1;
+          if (ptr-doc_e->tag<doc_e->min_col)
+            goto pa_skip;
+          while (ptr>=doc_e->tag+doc_e->min_col) {
+            ch=*ptr--;
+            if (abort_on_dbl_colon && ch==':') {
+              if (++colons==2) {
+                doc->cur_entry=doc_e;
+                doc->cur_col=ptr-doc_e->tag+1;
+                res=FALSE;
+                goto pa_done;
+              }
+            } else {
+              colons=0;
+              if (ch==plus)
+                levels++;
+              else if (ch==minus) {
+                if (!levels--) {
+                  doc->cur_entry=doc_e;
+                  doc->cur_col=ptr-doc_e->tag+1;
+                  res=doc->cur_entry!=original_ce ||
+                        doc->cur_col!=original_col;
+                  goto pa_done;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+pa_skip:
+    if (fwd)
+      doc_e=doc_e->next;
+    else
+      doc_e=doc_e->last;
+  } while (doc_e!=doc_ce);
+pa_done:
+  DocRecalc(doc);
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public Bool EdGoToFun(CDoc *doc,Bool fwd,Bool abort_on_dbl_colon)
+{//Move cur_entry to start of cur fun and center.(Shoddy)
+  Bool unlock=DocLock(doc),res=FALSE;
+  I64 ch,levels,colons;
+  if (fwd) {
+    levels=0;
+    colons=0;
+    while (doc->cur_entry!=doc) {
+      ch=EdCurU8(doc);
+      if (abort_on_dbl_colon && ch==':') {
+        if (++colons==2) {
+          EdCursorLeft(doc);
+          break;
+        }
+      } else {
+        colons=0;
+        if (ch=='{')
+          levels++;
+        else if (ch=='}' && !levels--)
+          break;
+      }
+      EdCursorRight(doc);
+    }
+    DocRecalc(doc);
+    if (doc->cur_entry!=doc)
+      res=TRUE;
+  } else {
+    while (EdFindPaired(doc,'}','{',FALSE,abort_on_dbl_colon));
+    if (doc->cur_entry!=doc) {
+      ch=EdCurU8(doc);
+      if (abort_on_dbl_colon && ch==':')
+        res=TRUE;
+      else {
+        if (ch=='{')
+          res=TRUE;
+      }
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public U0 EdSelFun(CDoc *doc,Bool abort_on_dbl_colon=FALSE)
+{//Set DOCET_SEL on all entries in cur fun.
+  Bool unlock=DocLock(doc);
+  U8 *ptr;
+  I64 ch,levels=0,colons=0;
+  CDocEntry *doc_e;
+  EdSelAll(doc,FALSE);
+  EdGoToFun(doc,FALSE,abort_on_dbl_colon);
+  if (EdCurU8(doc)=='{')
+    levels--;
+  else if (abort_on_dbl_colon && EdCurU8(doc)==':') {
+    EdCursorRight(doc);
+    if (EdCurU8(doc)==':')
+      EdCursorRight(doc);
+  }
+  doc_e=doc->cur_entry;
+  while (doc_e!=doc) {
+    doc_e->type|=DOCET_SEL;
+    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
+      ptr=doc_e->tag;
+      if (doc_e==doc->cur_entry)
+        ptr+=doc->cur_col;
+      while (ch=*ptr++)
+        if (abort_on_dbl_colon && ch==':') {
+          if (++colons==2)
+            goto sf_done;
+        } else {
+          colons=0;
+          if (ch=='{')
+            levels++;
+          else if (ch=='}' && !levels--)
+            goto sf_done;
+        }
+    }
+    doc_e=doc_e->next;
+  }
+sf_done:
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+#define RSAC_REPLACE    0
+#define RSAC_SKIP       1
+#define RSAC_ALL        2
+
+I64 PopUpReplaceSkipAllCancel(U8 *header=NULL,U8 *footer=NULL)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"$CM+LX,1,4$$BT,\"REPLACE\",LE=RSAC_REPLACE$"
+        "$CM+LX,17,0$$BT,\"SKIP\",LE=RSAC_SKIP$"
+        "$CM+LX,1,3$$BT,\"ALL\",LE=RSAC_ALL$"
+        "$CM+LX,17,0$$BT,\"CANCEL\",LE=DOCM_CANCEL$\n");
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 EdFindReplace(CDoc *doc)
+{
+  Bool found,unlock;
+  I64 cmd,i,j,plen,rlen,dlen,res=-1,sf_flags;
+  U8 *src,*dst,*dst2;
+  CDocEntry *doc_ce,*doc_e,*doc_marker=NULL;
+  if (doc->find_replace->pmt)
+    cmd=RSAC_REPLACE;
+  else
+    cmd=RSAC_ALL;
+  if (!doc->find_replace->pmt || DocForm(doc->find_replace)) {
+    res=0;
+    unlock=DocLock(doc);
+    if (doc->find_replace->match_case || doc->find_replace->local_var)
+      sf_flags=0;
+    else
+      sf_flags=SFF_IGNORE_CASE;
+    if (doc->find_replace->whole_labels || doc->find_replace->local_var)
+      sf_flags|=SFG_WHOLE_LABELS;
+
+    if (i=doc->find_replace->filter_lines) {
+      doc_ce=doc->head.next;
+      while (doc_ce!=doc) {
+        if (doc_ce->de_flags&DOCEF_TAG && doc_ce->tag &&
+              !(doc_ce->de_flags&DOCEF_FILTER_SKIP) &&
+              StrFind(doc->find_replace->find_text,doc_ce->tag,sf_flags)) {
+          doc_ce->type|=DOCET_SEL;
+          res++;
+        } else
+          doc_ce->type&=~DOCET_SEL;
+        doc_ce=doc_ce->next;
+      }
+
+      doc_ce=doc->head.next;
+      while (doc_ce!=doc) {
+        if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP)) {
+          found=FALSE;
+
+          doc_e=doc_ce;
+          while (doc_e!=doc && doc_e->y>doc_ce->y-i) {
+            if (doc_e->type&DOCET_SEL) {
+              found=TRUE;
+              break;
+            } else
+              doc_e=doc_e->last;
+          }
+
+          if (!found) {
+            doc_e=doc_ce;
+            while (doc_e!=doc && doc_e->y<doc_ce->y+i) {
+              if (doc_e->type&DOCET_SEL) {
+                found=TRUE;
+                break;
+              } else
+                doc_e=doc_e->next;
+            }
+          }
+
+          if (!found)
+            doc_ce->de_flags|=DOCEF_FILTER_SKIP;
+        }
+
+        doc_ce=doc_ce->next;
+      }
+      EdSelAll(doc,FALSE);
+      goto fr_unlock_done;
+    }
+
+    if (doc->find_replace->local_var)
+      EdSelFun(doc);
+
+    if (!doc->find_replace->replace && !doc->find_replace->local_var) {
+      EdFindNext(doc);
+      goto fr_unlock_done;
+    }
+    plen=StrLen(doc->find_replace->find_text);
+    if (!plen)
+      goto fr_unlock_done;
+    rlen=StrLen(doc->find_replace->replace_text);
+    if (doc->head.next!=doc) {
+      doc_e=doc_marker=DocSplitTag(doc,doc->cur_entry,doc->cur_col,
+            doc->cur_entry->x+doc->cur_col,doc->cur_entry->y,DOCT_MARKER);
+      do {
+        if (doc_e==doc) {
+          if (doc->find_replace->scan_fwd)
+            doc_e=doc_e->next;
+          else
+            doc_e=doc_e->last;
+          if (doc_e==doc_marker)
+            break;
+        }
+        if (doc_e->type_u8==DOCT_TEXT &&
+              !(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP)) &&
+              (doc_e->type & DOCET_SEL ||
+              !doc->find_replace->scan_sel_text&&
+              !doc->find_replace->local_var)) {
+          src=doc_e->tag;
+          while (src) {
+            src=StrFind(doc->find_replace->find_text,src,sf_flags);
+            if (src) {
+              doc->cur_col=src-doc_e->tag;
+              doc->cur_entry=doc_e;
+              if (cmd!=RSAC_ALL)
+                DocCenter(doc);
+              if (cmd!=RSAC_ALL) {
+                DocUnlock(doc);
+                cmd=PopUpReplaceSkipAllCancel("");
+                DocLock(doc);
+                if (cmd<0)
+                  goto fr_unlock_done;
+              }
+              doc_e=doc->cur_entry;
+              src=doc->cur_col+doc_e->tag;
+              if (cmd==RSAC_REPLACE || cmd==RSAC_ALL) {
+                dlen=StrLen(doc_e->tag);
+                doc_e->max_col=dlen+rlen-plen;
+                dst=MAlloc(doc_e->max_col+1,doc->mem_task);
+                dst2=dst;
+                j=src-doc_e->tag;
+                for (i=0;i<j;i++)
+                  *dst++=doc_e->tag[i];
+                for (i=0;i<rlen;i++)
+                  *dst++=doc->find_replace->replace_text[i];
+                src=dst;
+                for (i=j+plen;i<=dlen;i++)
+                  *dst++=doc_e->tag[i];
+                Free(doc_e->tag);
+                doc_e->tag=dst2;
+                doc->cur_col=src-doc_e->tag;
+                doc->cur_entry=doc_e;
+                if (cmd!=RSAC_ALL) {
+                  DocRemSoftNewLines(doc,doc->cur_entry);
+                  DocRecalc(doc);
+                }
+                doc_e=doc->cur_entry;
+                src=doc->cur_col+doc_e->tag;
+                res++;
+              } else
+                src++;
+            }
+          }
+        }
+        if (doc->find_replace->scan_fwd)
+          doc_e=doc_e->next;
+        else
+          doc_e=doc_e->last;
+      } while (doc_e!=doc_marker);
+    }
+fr_unlock_done:
+    if (doc_marker)
+      DocEntryDel(doc,doc_marker);
+    DocRemSoftNewLines(doc,NULL);
+    DocRecalc(doc);
+    DocCenter(doc);
+    if (unlock)
+      DocUnlock(doc);
+  }
+  return res;
+}
+
+public I64 EdReplace(CDoc *doc,U8 *find,U8 *replace,
+Bool sel=TRUE,Bool match_case=TRUE,Bool whole_labels=FALSE)
+{//Find & replace using editor's cmd.
+  CEdFindText old_find_replace;
+  Bool unlock;
+  I64 i,res=-1;
+  if (!doc) return -1;
+  unlock=DocLock(doc);
+  MemCpy(&old_find_replace,doc->find_replace,sizeof(CEdFindText));
+  MemSet(doc->find_replace,0,sizeof(CEdFindText));
+  i=StrLen(find);
+  if (i<sizeof(CEdFindText.find_text)) {
+    MemCpy(doc->find_replace->find_text,find,i+1);
+    i=StrLen(replace);
+    if (i<sizeof(CEdFindText.replace_text)) {
+      MemCpy(doc->find_replace->replace_text,replace,i+1);
+      doc->find_replace->replace=TRUE;
+      doc->find_replace->scan_sel_text=sel;
+      doc->find_replace->match_case=match_case;
+      doc->find_replace->whole_labels=whole_labels;
+      doc->find_replace->pmt=FALSE;
+      res=EdFindReplace(doc);
+    }
+  }
+  MemCpy(doc->find_replace,&old_find_replace,sizeof(CEdFindText));
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+class CEdLineGoTo
+{
+  I64 line format "$DA,A=\"Go to Line:%d\"$";
+};
+
+U0 EdGoToLine(CDoc *doc)
+{//Prompt with form and go to line num.
+  CEdLineGoTo gtl;
+  gtl.line=1;
+  if (DocForm(&gtl))
+    DocGoToLine(doc,gtl.line);
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocForm.HC.HTML b/public/Wb/Adam/DolDoc/DocForm.HC.HTML new file mode 100755 index 0000000..4833647 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocForm.HC.HTML @@ -0,0 +1,375 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Form"
+
+U0 DocFormFwd(CDoc *doc,Bool giveup=FALSE)
+{
+  CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
+  if (doc->flags & DOCF_FORM) {
+    if (doc_e==doc) goto ff_recover;
+    while (!Bt(doldoc.type_flags_form,doc_e->type_u8) &&
+          !(doc_e->de_flags&DOCEF_LINK) ||
+          doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
+      doc_e=doc_e->next;
+      if (doc_e==doc) {
+ff_recover:
+        doc->cur_col=0;
+        if (!giveup) {
+          doc->cur_entry=doc_e->last;
+          DocFormBwd(doc,TRUE);
+        } else
+          doc->cur_entry=doc;
+        return;
+      }
+    }
+  }
+  while (doc_e->type_u8==DOCT_INDENT)
+    doc_e=doc_e->next;
+  if (doc_e!=doc_e2) {
+    doc->cur_col=doc_e->min_col;
+    doc->cur_entry=doc_e;
+  }
+}
+
+U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE)
+{
+  CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
+  if (doc->flags & DOCF_FORM) {
+    while (!Bt(doldoc.type_flags_form,doc_e->type_u8) &&
+          !(doc_e->de_flags&DOCEF_LINK) ||
+          doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
+      doc_e=doc_e->last;
+      if (doc_e==doc) {
+        doc->cur_col=0;
+        if (!giveup) {
+          doc->cur_entry=doc_e->next;
+          DocFormFwd(doc,TRUE);
+        } else
+          doc->cur_entry=doc;
+        return;
+      }
+    }
+  }
+  while (doc_e->type_u8==DOCT_INDENT)
+    doc_e=doc_e->next;
+  if (doc_e!=doc_e2) {
+    doc->cur_col=doc_e->min_col;
+    doc->cur_entry=doc_e;
+  }
+}
+
+U0 DocDataFmt(CDoc *doc,CDocEntry *doc_e,I64 d=DOCM_CANCEL)
+{
+  I64 i;
+  U8 *ptr,*ptr2;
+  CHashDefineStr *tmph;
+  if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
+        doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
+    if (d==DOCM_CANCEL) {
+      if (doc_e->de_flags&DOCEF_DEREF_DATA &&
+            !(doc_e->de_flags&DOCEF_REMALLOC_DATA)) {
+        if (!(ptr=doc_e->data)) return;
+      } else
+        ptr=&doc_e->data;
+      switch (doc_e->raw_type) {
+        case RT_I0:
+        case RT_U0:     d=0;            break;
+        case RT_I8:     d=*ptr(I8 *);   break;
+        case RT_U8:     d=*ptr(U8 *);   break;
+        case RT_I16:    d=*ptr(I16 *);  break;
+        case RT_U16:    d=*ptr(U16 *);  break;
+        case RT_I32:    d=*ptr(I32 *);  break;
+        case RT_U32:    d=*ptr(U32 *);  break;
+        default:        d=*ptr(I64 *);
+      }
+    }
+    if (doc_e->type_u8==DOCT_DATA) {
+      if (doc_e->de_flags & DOCEF_REMALLOC_DATA) {
+        ptr=MStrPrint(doc_e->aux_str,d,doc_e->my_fmt_data);
+        i=StrLen(ptr);
+        if (!doc_e->data) {
+          doc_e->data=CAlloc(2,doc->mem_task);
+          doc_e->len=MSize(doc_e->data)-2;
+        }
+        if (doc_e->len+doc_e->min_col>i)
+          MemCpy(doc_e->tag,ptr,i+1);
+        else {
+          ptr2=MAlloc(i+8,doc->mem_task);
+          doc_e->len=MSize(ptr2)-doc_e->min_col-2;       //See DataTagWidth
+          MemCpy(ptr2,ptr,i+1);
+          Free(doc_e->tag);
+          doc_e->tag=ptr2;
+        }
+        Free(ptr);
+      } else {
+        StrPrint(doc_e->tag,doc_e->aux_str,d,doc_e->my_fmt_data);
+        i=StrLen(doc_e->tag);
+      }
+      if (doc_e->de_flags & DOCEF_HAS_TERMINATOR) {
+        doc_e->tag[i++]='_';
+        doc_e->tag[i]=0;
+      }
+      doc_e->max_col=i;
+    } else if (doc_e->de_flags & DOCEF_LST) {
+      if (doc_e->de_flags & DOCEF_DEFINE && (tmph=HashFind(doc_e->define_str,
+            doc->win_task->hash_table,HTT_DEFINE_STR)) && 0<=d<tmph->cnt) {
+        ptr=MStrPrint("[%s]",tmph->sub_idx[d]);
+        Free(doc_e->tag);
+        doc_e->tag=StrNew(ptr,doc->mem_task);
+        Free(ptr);
+      } else {
+        Free(doc_e->tag);
+        doc_e->tag=StrNew("[]",doc->mem_task);
+      }
+    } else {
+      if (d)
+        doc_e->de_flags|=DOCEF_CHECKED_COLLAPSED;
+      else
+        doc_e->de_flags&=~DOCEF_CHECKED_COLLAPSED;
+    }
+  }
+}
+
+U0 DocDataScan(CDoc *doc,CDocEntry *doc_e)
+{
+  I64 i,d;
+  U8 *ptr,*ptr1,*ptr2;
+  CHashDefineStr *tmph;
+  if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
+        doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
+    if (doc_e->de_flags&DOCEF_DEREF_DATA &&
+          !(doc_e->de_flags&DOCEF_REMALLOC_DATA)) {
+      if (!(ptr=doc_e->data)) return;
+    } else
+      ptr=&doc_e->data;
+    if (doc_e->type_u8==DOCT_DATA) {
+      i=StrLen(doc_e->tag);
+      if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
+        doc_e->tag[--i]=0;
+      if (i>doc_e->len+doc_e->min_col)
+        doc_e->tag[doc_e->len+doc_e->min_col]=0;
+      if (RT_I8<=doc_e->raw_type<=RT_U32) {
+        StrScan(doc_e->tag,doc_e->aux_str,&d,doc_e->my_fmt_data);
+        if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
+          doc_e->tag[i]='_';
+      } else if (RT_I64<=doc_e->raw_type<=RT_UF64) {
+        if (doc_e->de_flags & DOCEF_REMALLOC_DATA) {
+          ptr=MAlloc(i-doc_e->min_col+8,doc->mem_task);
+          MemCpy(ptr,doc_e->tag+doc_e->min_col,i-doc_e->min_col+1);
+          Free(doc_e->data);
+          doc_e->data=ptr;
+          doc_e->len=MSize(ptr)-1;
+        } else
+          StrScan(doc_e->tag,doc_e->aux_str,ptr,doc_e->my_fmt_data);
+        if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
+          doc_e->tag[i]='_';
+        return;
+      }
+    } else if (doc_e->de_flags & DOCEF_LST) {
+      d=0;
+      if (doc_e->tag && doc_e->de_flags & DOCEF_DEFINE &&
+            (tmph=HashFind(doc_e->define_str,
+            doc->win_task->hash_table,HTT_DEFINE_STR))) {
+        ptr1=ptr2=StrNew(doc_e->tag);
+        if (*ptr2=='[') {
+          ptr2++;
+          i=StrLen(ptr2);
+          if (ptr2[i-1]==']')
+            ptr2[i-1]=0;
+        }
+        d=LstMatch(ptr2,tmph->data);
+        Free(ptr1);
+      }
+    } else {
+      if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+        d=TRUE;
+      else
+        d=FALSE;
+    }
+    switch (doc_e->raw_type) {
+      case RT_I8:
+      case RT_U8:
+        *ptr(U8 *)=d;
+      case RT_I0:
+      case RT_U0:
+        break;
+      case RT_I16:
+      case RT_U16:
+        *ptr(U16 *)=d;
+        break;
+      case RT_I32:
+      case RT_U32:
+        *ptr(U32 *)=d;
+        break;
+      default:
+        *ptr(I64 *)=d;
+    }
+  }
+}
+
+#help_index "DolDoc/Input;StdIn/DolDoc"
+public Bool DocForm(U8 *_d,U8 *class_name=lastclass,
+    I64 dof_flags=0,U8 *header=NULL,U8 *footer=NULL)
+{//User input. Supply a class name that has format definitions.
+//See ::/Demo/DolDoc/Form.HC and ::/Demo/LastClass.HC.
+  CMemberLst *ml;
+  CDocEntry *doc_e;
+  U8 *format;
+  CHashClass *tmpc,*tmpc2;
+  CDoc *doc;
+  Bool res=FALSE;
+  I64 old_border_src=Fs->border_src,has_action;
+  if (!(tmpc=HashFind(class_name,Fs->hash_table,HTT_CLASS)))
+    return FALSE;
+  doc=DocNew;
+  doc->desc='Form';
+  if (header) DocPrint(doc,"%s",header);
+  doc->flags|=DOCF_OVERSTRIKE|DOCF_FORM;
+  if (dof_flags&DOF_SIZE_MIN)
+    doc->flags|=DOCF_SIZE_MIN;
+  ml=tmpc->member_lst_and_root;
+  while (ml) {
+    if ((format=MemberMetaData("format",ml)) &&
+          (doc_e=DocPrint(doc,"%s",format))) {
+      tmpc2=ml->member_class;
+      if ((doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_LST ||
+            doc_e->type_u8==DOCT_CHECK_BOX) && !tmpc2->ptr_stars_cnt) {
+        tmpc2=OptClassFwd(tmpc2);
+        tmpc2-=tmpc2->ptr_stars_cnt;
+        if (tmpc2->type & HTT_INTERNAL_TYPE) {
+          if (ml->dim.next) { //Array
+            if (tmpc2->raw_type==RT_U8 &&
+                  LBtr(&doc_e->de_flags,&DOCEf_DFT_LEN)) {
+              doc_e->len=ml->dim.total_cnt;
+              if (doc_e->de_flags&DOCEF_HAS_TERMINATOR)
+                doc_e->len--;
+              Free(doc_e->tag);  //See DataTagWidth
+              doc_e->tag=MAlloc(doc_e->len+doc_e->min_col+2,
+                    doc->mem_task); //+2 because "_\0"
+            }
+          } else if (LBtr(&doc_e->de_flags,DOCEf_DFT_RAW_TYPE))
+            doc_e->raw_type=tmpc2->raw_type;
+        }
+      }
+      if (doc_e->de_flags&DOCEF_REMALLOC_DATA) {
+        doc_e->user_data=_d+ml->offset;
+        doc_e->data=*doc_e->user_data(U8 **);
+      } else
+        doc_e->data=_d+ml->offset;
+      doc_e->my_fmt_data=MemberMetaData("data",ml);
+      DocDataFmt(doc,doc_e);
+    }
+    ml=ml->next;
+  }
+  if (footer) DocPrint(doc,"%s",footer);
+  if (doc->head.next!=doc)      {
+    Fs->border_src=BDS_CONST;
+    DocRecalc(doc);
+    if (DocEd(doc,dof_flags)) {
+      doc_e=doc->cur_entry;
+      res=TRUE;
+      if (doc_e!=doc) {
+        if (DocEntryRun(doc,doc_e,TRUE,&has_action)==DOCM_CANCEL && has_action)
+          res=FALSE;
+        DocUnlock(doc);
+      }
+    }
+  }
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->de_flags&DOCEF_REMALLOC_DATA) {
+      *doc_e->user_data(U8 **)=doc_e->data;
+      doc_e->data=NULL;
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+  Fs->border_src=old_border_src;
+  return res;
+}
+
+U0 DocMenuEndTaskCB()
+{
+  WinToTop;
+  throw;
+}
+
+public I64 DocMenu(CDoc *m,I64 dof_flags=0)
+{//Run menu chooser doc. Returns menu doc unlocked.
+  U8 *old_end_cb=Fs->task_end_cb;
+  Bool old_break_shift_esc=LBts(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC);
+  CDocEntry *doc_e;
+  I64 old_border_src=Fs->border_src,res=DOCM_CANCEL,has_action;
+  Fs->task_end_cb=&DocMenuEndTaskCB;
+  try {
+    if (m) {
+      m->desc='Menu';
+      Fs->border_src=BDS_CONST;
+dm_restart:
+      if (DocEd(m,dof_flags)) {
+        doc_e=m->cur_entry;
+        if (doc_e!=m) {
+          res=DocEntryRun(m,doc_e,TRUE,&has_action);
+          DocUnlock(m);
+          if (!has_action) {
+            res=DOCM_CANCEL;
+            dof_flags|=DOF_DONT_HOME;
+            goto dm_restart;
+          }
+        }
+      }
+    }
+  } catch {
+    if (!Fs->except_ch) {
+      if (!(dof_flags & DOF_INTERCEPT_TASK_END))
+        Exit;
+      Fs->catch_except=TRUE;
+    }
+  }
+  LBEqu(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC,old_break_shift_esc);
+  Fs->border_src=old_border_src;
+  Fs->task_end_cb=old_end_cb;
+  return res;
+}
+
+public I64 PopUpMenu(CDoc *doc,I64 dof_flags=0)
+{//Run menu chooser doc in PopUp win task.
+  doc->flags|=DOCF_SIZE_MIN | DOCF_FORM;
+  return PopUpPrint("DocMenu(0x%X,0x%X);",doc,dof_flags);
+}
+
+public Bool PopUpForm(U8 *_d,U8 *class_name=lastclass,
+        I64 dof_flags=DOF_SIZE_MIN,U8 *header=NULL,U8 *footer=NULL)
+{//See ::/Demo/DolDoc/Form.HC and ::/Demo/LastClass.HC.
+  return PopUpPrint("DocForm(0x%X,0x%X,0x%X,0x%X,0x%X);",_d,class_name,
+        dof_flags,header,footer);
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocGet.HC.HTML b/public/Wb/Adam/DolDoc/DocGet.HC.HTML new file mode 100755 index 0000000..0ed7ea4 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocGet.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+U0 EdUndoFilter(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->head.next;
+  while (doc_ce!=doc) {
+    doc_ce->de_flags&=~DOCEF_FILTER_SKIP;
+    doc_ce=doc_ce->next;
+  }
+  doc->find_replace->filter_lines=0;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public I64 DocGetKey(I64 *_sc=NULL)
+{//Called by View. You probably don't need this.
+  I64 ch,sc;
+  Bool cont,old_key_desc;
+  do {
+    old_key_desc=LBtr(&Fs->win_inhibit,WIf_SELF_KEY_DESC);
+    do ch=GetKey(&sc,TRUE);
+    while (sc&SCF_KEY_DESC);
+    LBEqu(&Fs->win_inhibit,WIf_SELF_KEY_DESC,old_key_desc);
+
+    DocRecalc(DocPut);
+    cont=FALSE;
+    if ((ch==CH_ESC || ch==CH_SHIFT_ESC) && //Check for exit filter mode
+          DocPut && DocPut->find_replace->filter_lines) {
+      EdUndoFilter(DocPut);
+      cont=TRUE;
+    }
+  } while (cont);
+  if (_sc) *_sc=sc;
+  return ch;
+}
+
+#help_index "DolDoc/Input;StdIn/DolDoc"
+public U8 *DocScanLine(CDoc *doc,CDocEntry *doc_e,
+        I64 *cur_col=NULL,CDocEntry **_do_e_end=NULL)
+{//Start at entry in doc,make and return one line as str.
+  CDocEntry *doc_e2=doc_e;
+  Bool unlock=DocLock(doc);
+  U8 *dst,*src,*start,*res;
+  I64 i=0;
+  if (cur_col)
+    *cur_col=-1;
+  while (doc_e2!=doc && doc_e2->type_u8!=DOCT_NEW_LINE) {
+    if (doc_e2->de_flags&DOCEF_TAG && doc_e2->tag) {
+      src=doc_e2->tag;
+      i+=StrLen(src);
+    } else if (doc_e2->type_u8==DOCT_TAB)
+      i++;
+    else if (doc_e2->type_u8==DOCT_SHIFTED_X ||
+          doc_e2->type_u8==DOCT_SHIFTED_Y) {
+      if (doc_e2->attr<0)
+        i++;
+      i+=6; //$SY,3$
+    }
+    doc_e2=doc_e2->next;
+  }
+  res=MAlloc(i+1);
+  dst=res;
+  while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
+    start=dst;
+    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
+      src=doc_e->tag;
+      while (*src)
+        *dst++=*src++;
+    } else if (doc_e->type_u8==DOCT_TAB)
+      *dst++='\t';
+    else if (doc_e->type_u8==DOCT_SHIFTED_Y) {
+      *dst(U32 *)++='$SY,';
+      if (doc_e->attr<0)
+        *dst++='-';
+      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
+      *dst++='$';
+    } else if (doc_e->type_u8==DOCT_SHIFTED_X) {
+      *dst(U32 *)++='$SX,';
+      if (doc_e->attr<0)
+        *dst++='-';
+      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
+      *dst++='$';
+    }
+    if (doc_e==doc->cur_entry && cur_col)
+      *cur_col=start-res+doc->cur_col;
+    doc_e=doc_e->next;
+  }
+  if (_do_e_end) *_do_e_end=doc_e;
+  *dst=0;
+  if (doc_e==doc->cur_entry && cur_col && !doc->cur_col)
+    *cur_col=dst-res;
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+U8 *DocGetStr2(I64 flags=0)
+{//Flags
+  CDoc *doc;
+  CDocEntry *doc_e,*doc_e_end;
+  U8 *st,*st2,*res;
+  I64 ch,sc;
+  "$PT$";
+  do {
+    ch=DocGetKey(&sc);
+    if (ch==CH_ESC) {
+      if (doc=DocPut) {
+        DocLock(doc);
+        if (doc->doc_signature==DOC_SIGNATURE_VAL && doc->cur_entry!=doc) {
+          doc_e=DocEntryCopy(doc,doc->cur_entry);
+          DocBottom(doc);
+          DocEntryRun(doc,doc_e,TRUE);
+          DocEntryDel(doc,doc_e);
+        }
+        DocUnlock(doc);
+      }
+      if (flags&GSF_WITH_NEW_LINE)
+        break;
+    } if (ch==CH_SHIFT_ESC) {
+      if (flags&GSF_SHIFT_ESC_EXIT)
+        Exit;
+      else {
+        res=StrNew("");
+        goto gs_done;
+      }
+    }
+//<CTRL-SHIFT-ENTER> is a blank line without entry
+  } while (flags&GSF_WITH_NEW_LINE || ch!='\n' ||
+        sc&SCF_CTRL && sc&SCF_SHIFT);
+
+  doc=DocPut;
+  DocLock(doc);
+  if (flags&GSF_WITH_NEW_LINE) {
+    doc_e=doc->cur_entry;
+    do doc_e=doc_e->last;
+    while (doc_e!=doc && doc_e->type_u8!=DOCT_PMT);
+    doc_e=doc_e->next;
+    if (res=DocScanLine(doc,doc_e,NULL,&doc_e_end)) {
+      while (doc_e_end!=doc && doc_e_end->type_u8==DOCT_NEW_LINE) {
+        st2=MStrPrint("%s\n",res);
+        Free(res);
+        res=st2;
+        if (st=DocScanLine(doc,doc_e_end->next,NULL,&doc_e_end)) {
+          st2=MStrPrint("%s%s",res,st);
+          Free(st);
+          Free(res);
+          res=st2;
+        }
+      }
+    }
+  } else {
+    doc_e=doc->cur_entry;
+    do doc_e=doc_e->last;
+    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
+          doc_e->type_u8!=DOCT_PMT);
+    if (doc_e!=doc && doc_e->type_u8!=DOCT_PMT) {
+      do doc_e=doc_e->last;
+      while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
+            doc_e->type_u8!=DOCT_PMT);
+    }
+    doc_e=doc_e->next;
+    res=DocScanLine(doc,doc_e,NULL);
+  }
+  DocUnlock(doc);
+gs_done:
+  "$PT$$FG$$BG$";
+  return res;
+}
+
+#help_index "Keyboard Devices;Char/Input;StdIn"
+public I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX)
+{//Prompt user for I64 expression.
+  Bool okay;
+  U8 *st;
+  I64 res;
+  while (TRUE) {
+    if (msg)
+      "" msg,dft;
+    st=GetStr;
+    if (!*st) {
+      Free(st);
+      return dft;
+    }
+    try {
+      res=ExePrint2("ToI64(%s);",st);
+      okay=TRUE;
+    } catch {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+    }
+    Free(st);
+    if (okay && lo<=res<=hi)
+      return res;
+  }
+}
+
+public F64 GetF64(U8 *msg=NULL,F64 dft=0,F64 lo=F64_MIN,F64 hi=F64_MAX)
+{//Prompt user for F64 expression.
+  Bool okay;
+  U8 *st;
+  F64 res;
+  while (TRUE) {
+    if (msg)
+      "" msg,dft;
+    st=GetStr;
+    if (!*st) {
+      Free(st);
+      return dft;
+    }
+    try {
+      res=ExePrint2("ToF64(%s);",st)(F64);
+      okay=TRUE;
+    } catch {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+    }
+    Free(st);
+    if (okay && lo<=res<=hi)
+      return res;
+  }
+}
+
+public CDate GetDate(U8 *msg=NULL,CDate dft=I64_MIN,
+        CDate lo=I64_MIN,CDate hi=I64_MAX)
+{//Prompt user for date expression. (Use Now() if you want current time.)
+  U8 *st;
+  CDate res;
+  if (dft==I64_MIN) dft=Now;
+  while (TRUE) {
+    if (msg)
+      "" msg,dft,dft;
+    st=GetStr;
+    if (!*st) {
+      Free(st);
+      return dft;
+    }
+    res=Str2Date(st);
+    Free(st);
+    if (res>=lo && res<=hi)
+      return res;
+  }
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocGr.HC.HTML b/public/Wb/Adam/DolDoc/DocGr.HC.HTML new file mode 100755 index 0000000..d1f1744 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocGr.HC.HTML @@ -0,0 +1,194 @@ + + + + + + + + + + + +
+#help_index "Graphics/Input"
+
+public I64 PopUpColor(U8 *header=NULL,
+        Bool allow_transparent=TRUE,Bool allow_dft=TRUE)
+{//Chooser for 16-color, default or transparent.
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  if (allow_transparent)
+    DocPrint(doc,"$MU,\"TRANSPARENT\",LE=TRANSPARENT$\n");
+  for (i=0;i<COLORS_NUM;i++)
+    DocPrint(doc,"$BG,%d$$MU,\"__%-8Z__\",LE=%d$$BG$\n",i,i,"ST_COLORS",i);
+  if (allow_dft)
+    DocPrint(doc,"$BG,WHITE$$MU,\"DEFAULT\",LE=DOC_DFT$$BG$");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public I64 PopUpColorLighting(U8 *header=NULL)
+{//Chooser for std TempleOS DCLighting() color.
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"\nSingle-Sided means front and back different."
+        "\nDouble-Sided means front and back same."
+        "\n"
+        "\nHalf-Range means 0 to [0,7]"
+        "\n                 [8,15]-8 to [8,15]"
+        "\nFull-Range means 0 to [0,7] to [0,7]+8"
+        "\n");
+  DocPrint(doc,
+        "\n$LTPURPLE$Single-Sided Full-Range Double-Sided Full-Range\n$BLACK$");
+  for (i=0;i<COLORS_NUM/2;i++) {
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$ ",i,i,"ST_COLORS",i);
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$\n",i,i,"ST_COLORS",
+          ROPF_TWO_SIDED+i);
+  }
+  DocPrint(doc,
+        "\n$LTPURPLE$Single-Sided Half-Range Double-Sided Half-Range\n$BLACK$");
+  for (i=0;i<COLORS_NUM;i++) {
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$ ",
+          i,i,"ST_COLORS",ROPF_HALF_RANGE_COLOR+i);
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$\n",
+          i,i,"ST_COLORS",ROPF_TWO_SIDED+ROPF_HALF_RANGE_COLOR+i);
+  }
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CTransformForm
+{
+  F64 x_scale   format "$DA-TRM,A=\"X Scale :%12.6f\"$\n";
+  F64 y_scale   format "$DA-TRM,A=\"Y Scale :%12.6f\"$\n";
+  F64 z_scale   format "$DA-TRM,A=\"Z Scale :%12.6f\"$\n";
+  F64 theta_z   format "\nAngles are in degrees\n"
+                       "$DA-TRM,A=\"Z-Axis  :%12.6f\"$\n";
+  F64 theta_y   format "$DA-TRM,A=\"Y-Axis  :%12.6f\"$\n";
+  F64 theta_x   format "$DA-TRM,A=\"X-Axis  :%12.6f\"$\n";
+  F64 x_offset  format "\n$DA-TRM,A=\"X Offset:%12.6f\"$\n";
+  F64 y_offset  format "$DA-TRM,A=\"Y Offset:%12.6f\"$\n";
+  F64 z_offset  format "$DA-TRM,A=\"Z Offset:%12.6f\"$\n";
+};
+
+#help_index "Graphics/Input;Graphics/Math/3D Transformation"
+public Bool PopUpTransform(I64 *r)
+{//Prompt for Mat4x4 transform.
+  CTransformForm *tf=MAlloc(sizeof(CTransformForm));
+  tf->x_scale=1.0;
+  tf->y_scale=1.0;
+  tf->z_scale=1.0;
+  tf->theta_x=0.0;
+  tf->theta_y=0.0;
+  tf->theta_z=0.0;
+  tf->x_offset=0.0;
+  tf->y_offset=0.0;
+  tf->z_offset=0.0;
+  if (PopUpForm(tf)) {
+    MemSet(r,0,16*sizeof(I64));
+    r[0] =tf->x_scale*GR_SCALE;
+    r[5] =tf->y_scale*GR_SCALE;
+    r[10]=tf->z_scale*GR_SCALE;
+    r[15]=GR_SCALE;
+
+    Mat4x4RotZ(r,tf->theta_z*pi/180.0);
+    Mat4x4RotY(r,tf->theta_y*pi/180.0);
+    Mat4x4RotX(r,tf->theta_x*pi/180.0);
+
+    r[3] =tf->x_offset*GR_SCALE;
+    r[7] =tf->y_offset*GR_SCALE;
+    r[11]=tf->z_offset*GR_SCALE;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+#help_index "Graphics/Input"
+#define PU_SPACING      10
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,i1,j1;
+  CDoc *doc=DocPut(task);
+  for (j=0;j<17;j++)
+    for (i=0;i<17;i++) {
+      if (j<16)
+        j1=j;
+      else
+        j1=TRANSPARENT;
+      if (i<16)
+        i1=i;
+      else
+        i1=TRANSPARENT;
+      dc->color=j1+i1<<16+ROPF_DITHER;
+      GrRect(dc,i*PU_SPACING,j*PU_SPACING+FramePtr("DitherFrame",task),
+            PU_SPACING,PU_SPACING);
+    }
+  i=(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH;
+  if (doc->max_x>i) i=doc->max_x;
+  WinHorz(task->win_left,task->win_left+i,task);
+  WinVert(task->win_top,task->win_top+doc->max_y+
+        (17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH,task);
+}
+
+I64 DitherColor2(U8 *header=NULL)
+{
+  I64 msg_code,arg1,arg2,res=-1,i,j;
+  DocClear;
+  "%s",header;
+  DocRecalc(DocPut);
+  FramePtrAdd("DitherFrame",(DocPut->max_y+1)*FONT_HEIGHT);
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_KEY_DOWN);
+    if (msg_code==MSG_MS_L_DOWN) {
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP);
+      i=arg1/PU_SPACING;
+      j=(arg2-FramePtr("DitherFrame"))/PU_SPACING;
+      if (arg1>=0 && arg2>=0 && 0<=j<17 && 0<=i<17) {
+        if (j==16) j=TRANSPARENT;
+        if (i==16) i=TRANSPARENT;
+        res=j+i<<16+ROPF_DITHER;
+        goto dc_done;
+      }
+    }
+  } while (!(msg_code==MSG_KEY_DOWN && (arg1==CH_ESC || arg1==CH_SHIFT_ESC)));
+  do GetMsg(&arg1,&arg2,1<<MSG_KEY_UP);
+  while (!arg1);
+dc_done:
+  SettingsPop;
+  FramePtrDel("DitherFrame");
+  return res;
+}
+
+public I64 PopUpColorDither(U8 *header=NULL)
+{//Chooser for 2 x 16 colors or transparent.
+  U8 buf[STR_LEN];
+  StrPrint(buf,"DitherColor2(0x%X);",header);
+  return PopUp(buf,Fs);
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocHighlight.HC.HTML b/public/Wb/Adam/DolDoc/DocHighlight.HC.HTML new file mode 100755 index 0000000..08e5714 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocHighlight.HC.HTML @@ -0,0 +1,191 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+CColorROPU32 highlight_hash_type_colors[HTt_TYPES_NUM]=
+        DOC_COLOR_EXPORT_SYS_SYM,0,DOC_COLOR_DEFINE_STR,DOC_COLOR_GLBL_VAR,
+        DOC_COLOR_CLASS,DOC_COLOR_KEYWORD,DOC_COLOR_FUN,0,0,DOC_COLOR_KEYWORD,
+        DOC_COLOR_KEYWORD,DOC_COLOR_KEYWORD,DOC_COLOR_REG,0,0,0,0};
+
+U32 *DocHighlight(CDocEntry *doc_e,U8 *src,I64 len,I64 _tmp_u32_attr)
+{//Be aware of ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+  U32 *res=MAlloc((len+1)*sizeof(U32)),*dst=res;
+  U8 *ptr;
+  CDocSettings *s=&doc_e->settings;
+  I64 ch,ch1,last_ch,tmp_u32_attr,mask_tmp_u32_attr=_tmp_u32_attr&0xFFFFF000,
+        comment_depth,brace_depth=s->brace_depth,paren_depth=s->paren_depth;
+  CHash *tmph;
+  switch [s->state] {
+    case DOCSS_NORMAL:
+hl_normal:
+      while (len) {
+        while (len && !Bt(char_bmp_alpha_numeric,*src)) {
+          tmp_u32_attr=_tmp_u32_attr;
+          ch1=*src++;
+          switch (ch1) {
+            case '/':
+              if (len>=2) {
+                if (*src=='/') {
+                  tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+                  *dst++=ch1+tmp_u32_attr;
+                  *dst++=*src++ +tmp_u32_attr;
+                  len-=2;
+                  goto hl_cpp_comment;
+                } else if (*src=='*') {
+                  tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+                  *dst++=ch1+tmp_u32_attr;
+                  *dst++=*src++ +tmp_u32_attr;
+                  len-=2;
+                  comment_depth=1;
+                  goto hl_comment;
+                }
+              }
+              break;
+            case '\'':
+              tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
+              *dst++=ch1+tmp_u32_attr;
+              len--;
+              goto hl_single_quote;
+            case '\"':
+              tmp_u32_attr=DOC_COLOR_STR<<8|mask_tmp_u32_attr;
+              *dst++=ch1+tmp_u32_attr;
+              len--;
+              goto hl_dbl_quote;
+            case '(':
+              if (paren_depth++&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+            case ')':
+              if (--paren_depth&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+            case '{':
+              if (brace_depth++&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+            case '}':
+              if (--brace_depth&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+          }
+          *dst++=ch1+tmp_u32_attr;
+          if (!--len) goto hl_normal_done;
+        }
+        ptr=src;
+        while (len && Bt(char_bmp_alpha_numeric,*src)) {
+          src++;
+          len--;
+        }
+        ch=*src;
+        *src=0;
+        if (tmph=HashFind(ptr,adam_task->hash_table,
+              HTT_EXPORT_SYS_SYM|HTT_DEFINE_STR|HTT_GLBL_VAR|HTT_CLASS|
+              HTT_INTERNAL_TYPE|HTT_FUN|HTT_KEYWORD|HTT_ASM_KEYWORD|
+              HTT_OPCODE|HTT_REG))
+          tmp_u32_attr=highlight_hash_type_colors[HashTypeNum(tmph)]<<8|
+                mask_tmp_u32_attr;
+        else
+          tmp_u32_attr=_tmp_u32_attr;
+        while (ch1=*ptr++)
+          *dst++=ch1+tmp_u32_attr;
+        *src=ch;
+      }
+hl_normal_done:
+      s->state=DOCSS_NORMAL;
+      s->comment_depth=0;
+      break;
+    case DOCSS_SINGLE_QUOTE:
+      tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
+hl_single_quote:
+      last_ch=0;
+      while (len--) {
+        ch1=*src++;
+        *dst++=ch1+tmp_u32_attr;
+        if (last_ch!='\\' && ch1=='\'')
+          goto hl_normal;
+        if (last_ch=='\\' && ch1=='\\')
+          last_ch=0;
+        else
+          last_ch=ch1;
+      }
+      s->state=DOCSS_SINGLE_QUOTE;
+      s->comment_depth=0;
+      break;
+    case DOCSS_DBL_QUOTE:
+      tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
+hl_dbl_quote:
+      last_ch=0;
+      while (len--) {
+        ch1=*src++;
+        *dst++=ch1+tmp_u32_attr;
+        if (last_ch!='\\' && ch1=='\"')
+          goto hl_normal;
+        if (last_ch=='\\' && ch1=='\\')
+          last_ch=0;
+        else
+          last_ch=ch1;
+      }
+      s->state=DOCSS_DBL_QUOTE;
+      s->comment_depth=0;
+      break;
+    case DOCSS_COMMENT:
+      tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+      comment_depth=s->comment_depth;
+hl_comment:
+      last_ch=0;
+      while (len--) {
+        ch1=*src++;
+        *dst++=ch1+tmp_u32_attr;
+        if (last_ch=='*' && ch1=='/') {
+          if (!--comment_depth)
+            goto hl_normal;
+        } else if (last_ch=='/' && ch1=='*')
+          comment_depth++;
+        last_ch=ch1;
+      }
+      s->state=DOCSS_COMMENT;
+      s->comment_depth=comment_depth;
+      break;
+    case DOCSS_CPP_Z_COMMENT:
+      tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+hl_cpp_comment:
+      while (len--)
+        *dst++=*src++ +tmp_u32_attr;
+      s->state=DOCSS_CPP_Z_COMMENT;
+      s->comment_depth=0;
+      break;
+  }
+  s->paren_depth=paren_depth;
+  s->brace_depth=brace_depth;
+  *dst=0;
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocInit.HC.HTML b/public/Wb/Adam/DolDoc/DocInit.HC.HTML new file mode 100755 index 0000000..3e23b4a --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocInit.HC.HTML @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+U0 DocInit()
+{//CMD Defines
+  CCmpCtrl *cc;
+  I64 i;
+  CHashGeneric *tmph;
+
+  DefineLstLoad("ST_DOC_CMDS",
+        "TX\0CR\0SR\0TB\0PB\0CU\0MK\0PT\0CL\0PL\0LM\0RM\0HD\0FO\0ID\0FG\0"
+        "BG\0FD\0BD\0WW\0HL\0BK\0IV\0UL\0SX\0SY\0CM\0AN\0LK\0BT\0"
+        "DA\0CB\0LS\0MA\0MU\0HX\0TR\0SP\0IB\0IS\0SO\0HC\0ER\0");
+  DefineLstLoad("ST_DOC_FLAGS",
+        "T\0LEN\0A\0D\0HTML\0LE\0LM\0RE\0RM\0BI\0BP\0RT\0SX\0SY\0SCX\0U\0"
+        "LC\0LIS\0RC\0RIS\0LX\0CX\0RX\0TY\0CY\0BY\0"
+        "HL\0WW\0BK\0IV\0SEL\0UL\0"
+        "TC\0PRY\0MRX\0WR\0L\0X\0Q\0FST\0B\0S\0BD\0C\0CA\0RD\0UD\0P\0M\0"
+        "TRM\0Z\0H\0TR\0LS\0SK\0PU\0SIF\0FS\0NC\0DD\0DL\0DRT\0");
+  DefineLstLoad("ST_LINK_TYPES",
+        "FI\0FA\0FF\0FL\0MN\0PI\0PF\0PL\0BF\0DN\0HI\0AD\0AI\0AA\0AF\0AL\0");
+
+  doldoc.hash=HashTableNew(512);
+  HashDefineLstAdd("ST_DOC_CMDS",DHT_DOC_CMD,doldoc.hash);
+  HashDefineLstAdd("ST_DOC_FLAGS",DHT_DOC_FLAG,doldoc.hash);
+  HashDefineLstAdd("ST_COLORS",DHT_COLOR,doldoc.hash);
+
+  MemSet(doldoc.dft_de_flags,   0,sizeof(doldoc.dft_de_flags));
+  MemSet(doldoc.dft_type_flags, 0,sizeof(doldoc.dft_type_flags));
+  cc=CmpCtrlNew("TX+T;DA+P+TRM+T+DL+DRT;CM+LE+RE;AN+T;LK+L+UL+T;MA+X+UL+T;"
+        "MU+X+UL+T;BT+X+B+T;CB+CA+P+T+DRT;LS+LS+P+T+DRT;HX+P+Z;TR+TR+C+CA+UL+T;"
+        "SP+T;IB+T;IS+T;SO+T;HC+T;",CCF_DONT_FREE_BUF);
+  cc->htc.hash_table_lst=NULL;
+  Lex(cc);
+  while (cc->token==TK_IDENT) {
+    if (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_CMD)) {
+      i=tmph->user_data0;
+      Lex(cc);
+      PrsDocFlags(cc,&doldoc.dft_de_flags[i],&doldoc.dft_type_flags[i]);
+    }
+    if (cc->token==';')
+      Lex(cc);
+  }
+  CmpCtrlDel(cc);
+
+  for (i=0;i<DOCT_TYPES_NUM;i++)
+    doldoc.dft_de_flags[i]&=~DOCG_BL_IV_UL;
+
+  doldoc.type_flags_form[0]=0;
+  for (i=0;i<DOCT_TYPES_NUM;i++)
+    if (Bt(&doldoc.dft_de_flags[i],DOCEf_TAG) && i!=DOCT_TEXT || i==DOCT_HEX_ED)
+      Bts(doldoc.type_flags_form,i);
+
+      //Don't forget cmp_type_flags_src_code.
+  doldoc.type_flags_nontag_invis[0]=
+        1<<DOCT_PMT|
+        1<<DOCT_PAGE_LEN|
+        1<<DOCT_LEFT_MARGIN|
+        1<<DOCT_RIGHT_MARGIN|
+        1<<DOCT_HEADER|
+        1<<DOCT_FOOTER|
+        1<<DOCT_INDENT|
+        1<<DOCT_FOREGROUND|
+        1<<DOCT_BACKGROUND|
+        1<<DOCT_DFT_FOREGROUND|
+        1<<DOCT_DFT_BACKGROUND|
+        1<<DOCT_WORD_WRAP|
+        1<<DOCT_HIGHLIGHT|
+        1<<DOCT_BLINK|
+        1<<DOCT_INVERT|
+        1<<DOCT_UNDERLINE|
+        1<<DOCT_SHIFTED_X|
+        1<<DOCT_SHIFTED_Y|
+        1<<DOCT_SPRITE;
+
+  doldoc.type_flags_data[0]=1<<DOCT_DATA|1<<DOCT_HEX_ED|1<<DOCT_CHECK_BOX;
+
+  doldoc.type_flags_chk_dup[0]=
+        1<<DOCT_LEFT_MARGIN|
+        1<<DOCT_RIGHT_MARGIN|
+        1<<DOCT_HEADER|
+        1<<DOCT_FOOTER|
+        1<<DOCT_FOREGROUND|
+        1<<DOCT_BACKGROUND|
+        1<<DOCT_DFT_FOREGROUND|
+        1<<DOCT_DFT_BACKGROUND|
+        1<<DOCT_WORD_WRAP|
+        1<<DOCT_HIGHLIGHT|
+        1<<DOCT_BLINK|
+        1<<DOCT_INVERT|
+        1<<DOCT_UNDERLINE|
+        1<<DOCT_SHIFTED_X|
+        1<<DOCT_SHIFTED_Y;
+
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_RIGHT);
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_LEFT);
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_UP);
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_DOWN);
+  Bts(doldoc.clean_scan_codes,SC_PAGE_UP);
+  Bts(doldoc.clean_scan_codes,SC_PAGE_DOWN);
+  Bts(doldoc.clean_scan_codes,SC_ALT);
+  Bts(doldoc.clean_scan_codes,SC_CTRL);
+  Bts(doldoc.clean_scan_codes,SC_SHIFT);
+  Bts(doldoc.clean_scan_codes,SC_CAPS);
+  Bts(doldoc.clean_scan_codes,SC_NUM);
+  Bts(doldoc.clean_scan_codes,SC_SCROLL);
+  Bts(doldoc.clean_scan_codes,SC_HOME);
+  Bts(doldoc.clean_scan_codes,SC_END);
+  Bts(doldoc.clean_scan_codes,SC_GUI);
+  Bts(doldoc.clean_scan_codes,SC_BACKSPACE); //Handled specially
+}
+
+DocInit;
+
+ diff --git a/public/Wb/Adam/DolDoc/DocLink.HC.HTML b/public/Wb/Adam/DolDoc/DocLink.HC.HTML new file mode 100755 index 0000000..14a9ee1 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocLink.HC.HTML @@ -0,0 +1,389 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Link"
+
+/* See TempleOS Link Types.
+"filename"
+"FI:filename"
+"FA:haystack_filename,needle_anchor_str"
+"FF:haystack_filename,needle_str"
+"FF:haystack_filename,needle_str:occurnum"
+"FL:filename,linenum"
+"MN:SymName"
+"PI:filename"
+"PF:haystack_filename,needle_str"
+"PF:haystack_filename,needle_str:occurnum"
+"PL:filename,linenum"
+"BF:haystack_bible_book,needle_str"
+"DN:word"
+"DN:word,defnum"
+"HI:index"
+"AD:code_address_number"
+
+To edit a doc structure already in memory. See SpriteEdText().
+"AI:doc_address"
+"AA:haystack_doc_address,needle_anchor_str"
+"AF:haystack_doc_address,needle_str"
+"AF:haystack_doc_address,needle_str:occurnum"
+"AL:doc_address,linenum"
+*/
+
+#define LK_FILE         0
+#define LK_FILE_ANCHOR  1
+#define LK_FILE_FIND    2
+#define LK_FILE_LINE    3
+#define LK_MAN_PAGE     4
+#define LK_PLAIN        5
+#define LK_PLAIN_FIND   6
+#define LK_PLAIN_LINE   7
+#define LK_BIBLE_FIND   8
+#define LK_DEF          9
+#define LK_HELP_INDEX   10
+#define LK_ADDR         11
+#define LK_DOC          12 //See SpriteEdText()
+#define LK_DOC_ANCHOR   13
+#define LK_DOC_FIND     14
+#define LK_DOC_LINE     15
+#define LK_PLACE_ANCHOR 16
+
+public U8 *DocEntryLink(CDoc *doc,CDocEntry *doc_e)
+{//MAlloc new str, either tag or aux_str if link.
+  if (doc_e->de_flags&DOCEF_LINK) {
+    if (doc_e->de_flags & DOCEF_AUX_STR)
+      return StrNew(doc_e->aux_str,doc->mem_task);
+    else if (doc_e->de_flags & DOCEF_TAG)
+      return StrNew(doc_e->tag,doc->mem_task);
+  }
+  return NULL;
+}
+
+Bool DocFileEd(I64 _type,U8 *filename,
+        U8 *needle_str,I64 *_num,I64 edf_dof_flags)
+{
+  I64 type=_type,flags=0,old_border_src=Fs->border_src;
+  CDocEntry *doc_e;
+  CDoc *doc;
+  Bool old_silent=Bt(&Fs->display_flags,DISPLAYf_SILENT),
+        res=FALSE,other_found=FALSE;
+  U8 *st1,*st2;
+  try {
+    switch (type) {
+      case LK_PLAIN:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+      case LK_DOC:
+        type=LK_FILE;
+        break;
+      case LK_DOC_ANCHOR:
+        type=LK_FILE_ANCHOR;
+        break;
+      case LK_PLAIN_FIND:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+      case LK_DOC_FIND:
+        type=LK_FILE_FIND;
+        break;
+      case LK_PLAIN_LINE:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+      case LK_DOC_LINE:
+        type=LK_FILE_LINE;
+        break;
+      case LK_BIBLE_FIND:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+        break;
+    }
+
+    flags|=DOCF_ALLOW_UNDO;
+
+    if (LK_DOC<=_type<=LK_DOC_LINE) {
+      doc=Str2I64(filename);//See SpriteEdText()
+      res=TRUE;
+    } else {
+      st1=StrNew(filename);
+      st2=StrNew(filename);
+      StrLastRem(st1,"/",st2); //st2 is name without dir
+      if (!FileNameChk(st2))
+        doc=NULL;
+      else {
+        Silent;
+        if (Bt(&edf_dof_flags,EDf_BAIL)) //if bail, scan parents
+          res=FileFind(filename,,
+                FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        else if (!(res=FileFind(filename,,FUF_JUST_FILES)))
+          other_found=FileFind(filename,,
+                FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        doc=DocRead(filename,flags);
+        doc->desc='Edit';
+        Silent(old_silent);
+        Fs->border_src=BDS_ED_FILENAME_DRV;
+      }
+      Free(st1);
+      Free(st2);
+    }
+    if (!doc||doc->doc_signature!=DOC_SIGNATURE_VAL)
+      res=FALSE;
+    else {
+      if (Bt(&edf_dof_flags,EDf_COLLAPSE))
+        DocCollapse(TRUE,doc);
+      else if (Bt(&edf_dof_flags,EDf_UNCOLLAPSE))
+        DocCollapse(FALSE,doc);
+
+      if (res || other_found)
+        switch (type) {
+          case LK_FILE_LINE:
+            res=DocGoToLine(doc,*_num);
+            break;
+          case LK_FILE_ANCHOR:
+            res=DocAnchorFind(doc,needle_str);
+            break;
+          case LK_FILE_FIND:
+            res=DocFind(doc,,needle_str,*_num);
+            break;
+          case LK_BIBLE_FIND:
+            res=DocFind(doc,*_num,needle_str);
+            break;
+          default:
+            DocCenter(doc);
+        }
+      *_num=doc->cur_entry->y+1;
+
+      if (edf_dof_flags&EDF_WAS_WRITE)
+        res=FALSE;
+      if (!(edf_dof_flags&EDF_BAIL)) {
+        if (*doc->filename.name)
+          doc->filename.dirc=DirContextNew(doc->filename.name);
+        else
+          doc->filename.dirc=NULL;
+        if (DocEd(doc,edf_dof_flags|DOF_DONT_HOME)) {
+          DocLock(doc);
+          doc_e=doc->cur_entry;
+          if (doc_e!=doc)
+            DocEntryRun(doc,doc_e,TRUE);
+          DocUnlock(doc);
+          if (!(LK_DOC<=_type<=LK_DOC_LINE)) {
+            DocWrite(doc);
+            if (edf_dof_flags&EDF_WAS_WRITE)
+              res=TRUE;
+          }
+        }
+        DirContextDel(doc->filename.dirc);
+      }
+      if (!(LK_DOC<=_type<=LK_DOC_LINE))
+        DocDel(doc);
+    }
+  } catch {
+    Silent(old_silent);
+    res=FALSE;
+  }
+  Fs->border_src=old_border_src;
+  return res;
+}
+
+#define DFT_ADDR_LINK_BIN_SIZE  64
+
+public I64 EdLinkCvt(U8 *link_st,U8 **_filename=NULL,U8 **_needle_str=NULL,
+        I64 *_num=NULL,I64 edf_dof_flags=0)
+{//Editor Link--> filename, needle_str and line number.
+  U8 *st,*ptr,*src,*filename=NULL,*needle_str=NULL,*filename2;
+  I64 res,i,num=1;
+  CHashSrcSym *tmph;
+  if (!link_st||!*link_st) {
+    if (edf_dof_flags&EDF_BAIL)
+      return -1;
+    link_st=blkdev.tmp_filename;
+  }
+  st=StrNew(link_st);
+  res=LK_FILE;
+  if (StrLen(st)>3 && st[2]==':') {
+    st[2]=0;
+    filename2=st+3;
+    switch (res=DefineMatch(st,"ST_LINK_TYPES",LMF_IGNORE_CASE)) {
+      case LK_MAN_PAGE:
+        if (tmph=HashFind(filename2,Fs->hash_table,HTG_SRC_SYM))
+          res=EdLinkCvt(tmph->src_link,&filename,
+                &needle_str,&num,edf_dof_flags);
+        else
+          res=-1;
+        goto lc_done;
+      case LK_ADDR:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          i=Str2I64(ptr+1);
+        } else
+          i=DFT_ADDR_LINK_BIN_SIZE;
+        if (ptr=SrcEdLink(ExePrint("%s;",filename2),i)) {
+          res=EdLinkCvt(ptr,&filename,&needle_str,&num,edf_dof_flags);
+          Free(ptr);
+        } else
+          res=-1;
+        goto lc_done;
+      case LK_DEF:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          i=Str2I64(ptr+1);
+        } else
+          i=-1;
+        filename=StrNew(filename2);
+        num=i;
+        goto lc_done;
+      case LK_HELP_INDEX:
+        filename=StrNew(filename2);
+        goto lc_done;
+      case LK_BIBLE_FIND:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          src=ptr+1;
+          while (*src) { //We do not allow ending verse
+            if (*src=='-')
+              *src=0;
+            src++;
+          }
+          needle_str=StrNew(ptr+1);
+        }
+        i=DefineMatch(filename2,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE);
+        if (i<0)
+          res=-1;
+        else {
+          num=Str2I64(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
+          filename2=BIBLE_FILENAME;
+        }
+        break;
+      case LK_FILE_LINE:
+      case LK_PLAIN_LINE:
+      case LK_DOC_LINE:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          num=Str2I64(ptr+1);
+        }
+        break;
+      case LK_FILE_ANCHOR:
+      case LK_DOC_ANCHOR:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          needle_str=StrNew(ptr+1);
+        }
+        break;
+      case LK_FILE_FIND:
+      case LK_PLAIN_FIND:
+      case LK_DOC_FIND:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          needle_str=StrNew(ptr+1);
+          if (ptr=StrLastOcc(needle_str,":")) {
+            *ptr=0;
+            num=Str2I64(ptr+1);
+          }
+        }
+        break;
+    }
+  } else
+    filename2=st;
+  if (res>=0) {
+    if (LK_DOC<=res<=LK_DOC_LINE)
+      filename=StrNew(filename2); //Holds document address as number.
+    else
+      filename=FileNameAbs(filename2,FUF_Z_OR_NOT_Z);
+  }
+lc_done:
+  Free(st);
+  if (_filename)
+    *_filename=filename;
+  else
+    Free(filename);
+  if (_needle_str)
+    *_needle_str=needle_str;
+  else
+    Free(needle_str);
+  if (_num)
+    *_num=num;
+  return res;
+}
+
+public Bool DocLinkChk(CDoc *doc,U8 *link_st)
+{//Check for bad Editor Link.
+  U8 *filename,*st;
+  Bool res=FALSE;
+  CDirContext *dirc;
+  if (link_st) {
+    st=FileNameAbs(doc->filename.name);
+    dirc=DirContextNew(st);
+    Free(st);
+    switch (EdLinkCvt(link_st,&filename)) {
+      case -1:
+        break;
+      case LK_FILE_LINE:
+      case LK_PLAIN_LINE:
+      case LK_FILE:
+//We don't check line number
+        res=FileFind(filename,,
+              FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        break;
+      case LK_BIBLE_FIND:
+        st=StrNew(link_st+3);
+        if (StrOcc(st,','))
+          StrLastRem(st,",");
+        if (DefineMatch(st,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE)>=0)
+          res=TRUE;
+        Free(st);
+        break;
+      default://TODO: Need to validate HI: and DN:
+        if (Ed(link_st,EDF_BAIL))
+          res=TRUE;
+    }
+    Free(filename);
+    DirContextDel(dirc);
+  }
+  return res;
+}
+
+public U8 *DocLinkFile(U8 *link_st,CTask *mem_task=NULL)
+{//Return the file for an Editor Link Types.
+  U8 *filename=NULL,*st,*res=NULL;
+  if (link_st) {
+    switch (EdLinkCvt(link_st,&filename)) {
+      case LK_FILE:
+      case LK_FILE_ANCHOR:
+      case LK_FILE_FIND:
+      case LK_FILE_LINE:
+      case LK_PLAIN:
+      case LK_PLAIN_FIND:
+      case LK_PLAIN_LINE:
+        st=FileNameAbs(filename,FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        res=StrNew(st);
+        Free(st);
+        break;
+      case LK_BIBLE_FIND:
+        res=StrNew(BIBLE_FILENAME,mem_task);
+        break;
+    }
+    Free(filename);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocMacro.HC.HTML b/public/Wb/Adam/DolDoc/DocMacro.HC.HTML new file mode 100755 index 0000000..3af88d9 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocMacro.HC.HTML @@ -0,0 +1,242 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+U8 captured_macro_name[STR_LEN];
+StrCpy(captured_macro_name,"Test");
+
+I64 sys_macro_repeat_n=1;
+
+U0 SysMacroStripKey(CJob *macro_head,I64 arg1,I64 arg2)
+{
+  CJob *tmpc,*tmpc1;
+  tmpc=macro_head->next;
+  while (tmpc!=macro_head) {
+    tmpc1=tmpc->next;
+    if (tmpc->job_code==JOBT_MSG &&
+          (tmpc->msg_code==MSG_KEY_DOWN || tmpc->msg_code==MSG_KEY_UP ||
+          tmpc->msg_code==MSG_KEY_DOWN_UP) &&
+          arg1 && tmpc->aux1==arg1 || !arg1 && tmpc->aux2==arg2) {
+      QueRem(tmpc);
+      JobDel(tmpc);
+    }
+    tmpc=tmpc1;
+  }
+}
+
+#define MT_NULL 0
+#define MT_MSG  1
+#define MT_CHAR 2
+
+class CMacroTmp
+{
+  CMacroTmp *next,*last;
+  I64 type;
+  U8 buf[STR_LEN];
+};
+
+CMacroTmp *Cmd2MT(CJob *tmpc)
+{
+  U8 buf[8];
+  CMacroTmp *tmpmt=CAlloc(sizeof(CMacroTmp));
+  if (Bt(char_bmp_macro,tmpc->aux1) && tmpc->msg_code==MSG_KEY_DOWN) {
+    tmpmt->type=MT_CHAR;
+    buf[0]=tmpc->aux1;
+    buf[1]=0;
+    StrPrint(tmpmt->buf,"%Q",buf);
+  } else {
+    tmpmt->type=MT_MSG;
+    StrPrint(tmpmt->buf,"Msg(0x%X,0x%X,0x%X);",
+          tmpc->msg_code,tmpc->aux1,tmpc->aux2);
+  }
+  return tmpmt;
+}
+
+U8 *SysMacro2Str(CJob *macro_head)
+{
+  CJob *tmpc;
+  I64 cnt=1; //terminating zero
+  U8 *ptr,*m;
+  CMacroTmp *tmpmt,*tmpmt1,head;
+  LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+
+  QueInit(&head);
+  head.type=MT_NULL;
+  tmpc=macro_head->next;
+  while (tmpc!=macro_head) {
+    tmpmt=Cmd2MT(tmpc);
+    QueIns(tmpmt,head.last);
+    cnt+=StrLen(tmpmt->buf);
+    if (tmpmt->type==MT_CHAR) {
+      if (tmpmt->last->type!=MT_CHAR)
+        cnt+=StrLen("\"");
+      if (tmpmt->next->type!=MT_CHAR)
+        cnt+=StrLen("\";");
+    }
+    tmpc=tmpc->next;
+  }
+
+  m=MAlloc(cnt);
+  ptr=m;
+
+  tmpmt=head.next;
+  while (tmpmt!=&head) {
+    tmpmt1=tmpmt->next;
+    if (tmpmt->type==MT_MSG) {
+      StrCpy(ptr, tmpmt->buf);
+      ptr+=StrLen(tmpmt->buf);
+    } else {
+      if (tmpmt->last->type!=MT_CHAR) {
+        StrCpy(ptr, "\"");
+        ptr+=StrLen("\"");
+      }
+      StrCpy(ptr,tmpmt->buf);
+      ptr+=StrLen(tmpmt->buf);
+      if (tmpmt->next->type!=MT_CHAR) {
+        StrCpy(ptr, "\";");
+        ptr+=StrLen("\";");
+      }
+    }
+    Free(tmpmt);
+    tmpmt=tmpmt1;
+  }
+  *ptr=0;
+  return m;
+}
+
+U0 PlaySysMacro(I64 n=1)
+{
+  CTask *task=sys_focus_task;
+  U8 *m;
+  if (TaskValidate(task)) {
+    LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+    m=SysMacro2Str(&sys_macro_head);
+    while (n-- && TaskValidate(task)) {
+      if (task==Fs)
+        InStr("%s",m);
+      else
+        XTalkStrWait(task,"%s",m);
+    }
+    Free(m);
+  }
+}
+
+U0 EdInsCapturedMacro()
+{
+  U8 *st=SysMacro2Str(&sys_macro_head);
+  if (sys_focus_task) {
+    XTalk(sys_focus_task,"$MA+LIS,T=\"%s\",LM=\"%$Q\"$",
+          captured_macro_name,st);
+    Free(st);
+  }
+}
+
+#define SM_RECORD       0
+#define SM_INS          1
+#define SM_PLAY         2
+#define SM_REPEAT_N     3
+#define SM_STOP         4
+
+I64 PopUpMacroMenu()
+{
+  I64 res=0;
+  U8 buf[STR_LEN];
+  CJob *tmpc;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e=DocPrint(doc,"$DA-P,LEN=STR_LEN-1,A=\"Name:%%s\"$");
+  doc_e->data=captured_macro_name;
+  DocDataFmt(doc,doc_e);
+
+  doc_e=DocPrint(doc,"\n$DA,A=\"Repeat N:%%d\"$");
+  doc_e->data=&sys_macro_repeat_n;
+  DocDataFmt(doc,doc_e);
+
+  DocPrint(doc,"\n"
+        "$CM+LX,1,3$$BT,\"RECORD\",LE=SM_RECORD$"
+        "$CM+LX,17,0$$BT,\"INSERT\",LE=SM_INS$"
+        "$CM+LX,1,3$$BT,\"PLAY\",LE=SM_PLAY$"
+        "$CM+LX,17,0$$BT,\"REPEAT N\",LE=SM_REPEAT_N$"
+        "$CM+LX,1,3$$BT,\"STOP\",LE=SM_STOP$"
+        "$CM+LX,17,0$$BT,\"CANCEL\",LE=DOCM_CANCEL$"
+        "\n\n\n$GREEN$SHIFT-F2$FG$ will play macro.\n");
+  doc->flags|=DOCF_SIZE_MIN | DOCF_FORM;
+  StrPrint(buf,"DocMenu(%d);",doc);
+  sys_macro_task=Spawn(&SrvCmdLine,NULL,"Macro Popup",,Fs);
+  Fs->popup_task=sys_macro_task;
+  LBts(&sys_macro_task->display_flags,DISPLAYf_WIN_ON_TOP);
+  tmpc=TaskExe(sys_macro_task,Fs,buf,
+        1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+  JobResScan(tmpc,&res);
+  Fs->popup_task=NULL;
+  Kill(sys_macro_task);
+  sys_macro_task=NULL;
+  DocDataScan(doc,doc_e);
+  DocDel(doc);
+  return res;
+}
+
+U0 MacroTask(I64)
+{
+  I64 i;
+  StrCpy(captured_macro_name,"Click Here");
+  sys_macro_repeat_n=1;
+  do {
+    i=PopUpMacroMenu;
+    WinRefocus(sys_focus_task);
+    switch (i) {
+      case SM_RECORD:
+        LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+        QueDel(&sys_macro_head,TRUE);
+        LBts(&sys_semas[SEMA_RECORD_MACRO],0);
+        break;
+      case SM_PLAY:
+        PlaySysMacro;
+        break;
+      case SM_REPEAT_N:
+        PlaySysMacro(sys_macro_repeat_n);
+        break;
+      case SM_STOP:
+        LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+        break;
+      case SM_INS:
+        LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+        EdInsCapturedMacro;
+        break;
+    }
+  } while (i>=0);
+}
+
+U0 EdMacroUtil()
+{
+  if (!sys_macro_task)
+    Spawn(&MacroTask,NULL,"Macro");
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocNew.HC.HTML b/public/Wb/Adam/DolDoc/DocNew.HC.HTML new file mode 100755 index 0000000..e23b1b9 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocNew.HC.HTML @@ -0,0 +1,416 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+public Bool DocLock(CDoc *doc)
+{//Make this task have exclusive access to this doc.
+  if (!Bt(&doc->locked_flags,DOClf_LOCKED) || doc->owning_task!=Fs) {
+    while (LBts(&doc->locked_flags,DOClf_LOCKED))
+      Yield;
+    if (doc->owning_task!=Fs)
+      LBEqu(&doc->flags,DOCf_BREAK_UNLOCKED,BreakLock(Fs));
+    doc->owning_task=Fs;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+public Bool DocUnlock(CDoc *doc)
+{//Release exclusive lock on access to doc.
+  Bool unlock_break;
+  if (Bt(&doc->locked_flags,DOClf_LOCKED) && doc->owning_task==Fs) {
+    doc->owning_task=0;
+    unlock_break=Bt(&doc->flags,DOCf_BREAK_UNLOCKED);
+    LBtr(&doc->locked_flags,DOClf_LOCKED);
+    if (unlock_break)
+      BreakUnlock(Fs);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool IsEditableText(CDocEntry *doc_e)
+{
+  if (doc_e->type_u8==DOCT_TEXT&&!(doc_e->de_flags&DOCEG_DONT_EDIT))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+CDocEntry *DocEntryNewBase(CDoc *doc,I64 type,I64 de_flags=0,
+        I64 x=0,I64 y=0,I64 page_line_num=0)
+{//See also MAllocIdent and CDocEntry.
+  CDocEntry *res=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
+  res->type=type;
+  res->de_flags=de_flags|doldoc.dft_de_flags[type.u8[0]];
+  res->x=x;
+  res->y=y;
+  res->page_line_num=page_line_num;
+  return res;
+}
+
+CDocEntry *DocEntryNewTag(CDoc *doc,CDocEntry *doc_ce,U8 *tag)
+{
+  I64 l=StrLen(tag);
+  CDocEntry *res=DocEntryNewBase(doc,doc_ce->type,doc_ce->de_flags,
+        doc_ce->x,doc_ce->y,doc_ce->page_line_num);
+  res->de_flags=doc_ce->de_flags; //Override
+  res->max_col=l;
+  res->tag=MAlloc(l+1,doc->mem_task);
+  MemCpy(res->tag,tag,l+1);
+  MemCpy(&res->settings,&doc_ce->settings,sizeof(CDocSettings));
+  return res;
+}
+
+public U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e)
+{//Free entry and all parts of entry.
+  if (!doc || doc==doc_e)
+    RawPrint(3000,"DocEntryDel");
+  else {
+    if (doc->cur_entry==doc_e)
+      doc->cur_entry=doc_e->next;
+    QueRem(doc_e);
+    if (doc_e->de_flags & DOCEF_TAG)
+      Free(doc_e->tag);
+    if (doc_e->de_flags & DOCEF_AUX_STR)
+      Free(doc_e->aux_str);
+    if (doc_e->de_flags & DOCEF_DEFINE)
+      Free(doc_e->define_str);
+    if (doc_e->de_flags & DOCEF_HTML_LINK)
+      Free(doc_e->html_link);
+    if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+      Free(doc_e->left_macro);
+    if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
+      Free(doc_e->right_macro);
+    if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+      Free(doc_e->bin_ptr_link);
+    if (doc_e->de_flags & DOCEF_HAS_BIN)
+      DocBinDel(doc,doc_e->bin_data);
+    if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
+      Free(doc_e->data);
+    Free(doc_e);
+  }
+}
+
+public I64 DocEntrySize(CDoc *,CDocEntry *doc_e)
+{//Mem size of entry and all parts.
+  I64 res;
+  if (!doc_e) return 0;
+  res=MSize2(doc_e);
+  if (doc_e->de_flags & DOCEF_TAG)
+    res+=MSize2(doc_e->tag);
+  if (doc_e->de_flags & DOCEF_AUX_STR)
+    res+=MSize2(doc_e->aux_str);
+  if (doc_e->de_flags & DOCEF_DEFINE)
+    res+=MSize2(doc_e->define_str);
+  if (doc_e->de_flags & DOCEF_HTML_LINK)
+    res+=MSize2(doc_e->html_link);
+  if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+    res+=MSize2(doc_e->left_macro);
+  if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
+    res+=MSize2(doc_e->right_macro);
+  if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+    res+=MSize2(doc_e->bin_ptr_link);
+  if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
+    res+=MSize2(doc_e->data);
+  return res;
+}
+
+U0 DocUndoDel(CDoc *,CDocUndo *u)
+{
+  Free(u->body);
+  Free(u);
+}
+
+U0 DocUndoCntSet(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocUndo *u=doc->undo_head.next;
+  doc->undo_cnt=0;
+  while (u!=&doc->undo_head) {
+    doc->undo_cnt++;
+    u=u->next;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e)
+{//Make copy of entry and all parts of entry.
+  CDocEntry *doc_ne;
+  CDocBin *tmpb;
+  CTask *task=doc->mem_task;
+  doc_ne=MAllocIdent(doc_e,task);
+  doc_ne->next=doc_ne;
+  doc_ne->last=doc_ne;
+  if (doc_e->de_flags & DOCEF_TAG)
+    doc_ne->tag=MAllocIdent(doc_e->tag,task);
+  if (doc_e->de_flags & DOCEF_AUX_STR)
+    doc_ne->aux_str=MAllocIdent(doc_e->aux_str,task);
+  if (doc_e->de_flags & DOCEF_DEFINE)
+    doc_ne->define_str=MAllocIdent(doc_e->define_str,task);
+  if (doc_e->de_flags & DOCEF_HTML_LINK)
+    doc_ne->html_link=MAllocIdent(doc_e->html_link,task);
+  if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+    doc_ne->left_macro=MAllocIdent(doc_e->left_macro,task);
+  if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
+    doc_ne->right_macro=MAllocIdent(doc_e->right_macro,task);
+  if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+    doc_ne->bin_ptr_link=MAllocIdent(doc_e->bin_ptr_link,task);
+  if (doc_e->de_flags & DOCEF_HAS_BIN) {
+    tmpb=MAllocIdent(doc_e->bin_data,task);
+    tmpb->data=MAllocIdent(doc_e->bin_data->data,task);
+    doc_ne->bin_num=doc->cur_bin_num;
+    tmpb->num=doc->cur_bin_num++;
+    doc_ne->bin_data=tmpb;
+    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+      tmpb->tag=StrNew(doc_e->tag,task);
+    else
+      tmpb->tag=NULL;
+    QueIns(tmpb,doc->bin_head.last);
+  }
+  if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
+    doc_ne->data=MAllocIdent(doc_e->data,task);
+  return doc_ne;
+}
+
+U0 DocRemSoftNewLines(CDoc *doc=NULL,CDocEntry *doc_e=NULL)
+{
+  CDocEntry *doc_e2,*saved_ll=doc_e;
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  if (!doc_e) doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (doc_e->type_u8==DOCT_SOFT_NEW_LINE) {
+      if (doc->cur_entry==doc_e) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc->cur_entry->min_col;
+      }
+      DocEntryDel(doc,doc_e);
+    } else if (saved_ll && doc_e->type_u8==DOCT_NEW_LINE)
+      break;
+    doc_e=doc_e2;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocInsEntry(CDoc *doc,CDocEntry *doc_e)
+{//Insert entry into doc, updating its vals.
+  U8 *dst;
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
+
+  doc_e->x=doc_ce->x;
+  doc_e->y=doc_ce->y;
+  doc_e->page_line_num=doc_ce->page_line_num;
+  MemCpy(&doc_e->settings,&doc_ce->settings,sizeof(CDocSettings));
+  if (doc->cur_col>0 &&
+        doc_ce->type_u8==DOCT_TEXT &&
+        !(doc_ce->de_flags&(DOCEF_TAG_CB|DOCEF_DEFINE|DOCEF_AUX_STR|
+        DOCEF_HTML_LINK|DOCEF_BIN_PTR_LINK)) &&
+        doc->cur_col<doc_ce->max_col) {
+    dst=doc_ce->tag+doc->cur_col;
+    doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+    *dst=0;
+    doc_ne->type=DOCT_TEXT|doc_ce->type&0xFFFFFF00;
+    doc_ce->max_col=doc->cur_col;
+    QueIns(doc_ne,doc_ce);
+    doc->cur_col=0;
+    doc_ce=doc_ne;
+  }
+  if (doc_ce->type_u8==DOCT_TEXT && doc->cur_col>=doc_ce->max_col) {
+    QueIns(doc_e,doc_ce);
+    doc->cur_entry=doc_e->next;
+  } else {
+    QueIns(doc_e,doc_ce->last);
+    doc->cur_entry=doc_ce;
+  }
+  doc->cur_col=doc->cur_entry->min_col;
+  DocRemSoftNewLines(doc,doc->cur_entry);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocRst(CDoc *doc,Bool is_old)
+{//Del all entries and set doc to dfts.
+  Bool unlock;
+  CDocEntry *doc_e,*doc_e2;
+  CDocUndo *u,*u8;
+  CDocSettings *s;
+  CDocBin *b,*b1;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  if (is_old) {
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      doc_e2=doc_e->next;
+      DocEntryDel(doc,doc_e);
+      doc_e=doc_e2;
+    }
+    u=doc->undo_head.next;
+    while (u!=&doc->undo_head) {
+      u8=u->next;
+      DocUndoDel(doc,u);
+      u=u8;
+    }
+    b=doc->bin_head.next;
+    while (b!=&doc->bin_head) {
+      b1=b->next;
+      QueRem(b);
+      Free(b->data);
+      Free(b);
+      b=b1;
+    }
+  }
+//Check DocInsDoc
+  doc->flags&=DOCF_BREAK_UNLOCKED;
+  doc->head.next=doc->head.last=doc;
+  QueInit(&doc->bin_head);
+  QueInit(&doc->undo_head);
+  doc->undo_head.time_stamp=0;
+  doc->undo_cnt=0;
+  doc->cur_bin_num=1;
+  doc->dollar_buf_ptr=0;
+  doc->cmd_U8=CH_SPACE;
+  doc->page_line_num=0;
+  doc->best_d=I64_MAX;
+
+  s=&doc->settings_head;
+  s->left_margin=DOC_DFT;
+  s->right_margin=DOC_DFT;
+  s->indent=0;
+  s->page_len=66;
+  s->header=DOC_DFT;
+  s->footer=DOC_DFT;
+  s->state=DOCSS_NORMAL;
+  s->comment_depth=0;
+  s->paren_depth=0;
+  s->brace_depth=0;
+  s->shifted_x=0;
+  s->shifted_y=0;
+  s->cur_text_attr=s->dft_text_attr=DOC_ATTR_DFT_TEXT;
+
+  doc_e=&doc->head;
+  doc_e->type=DOCT_ERROR;
+  doc_e->de_flags=0;
+  doc_e->x=0;
+  doc_e->y=0;
+  doc_e->min_col=0;
+  doc_e->max_col=0;
+  doc_e->page_line_num=doc->page_line_num;
+  MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
+
+  DocTop(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocDel(CDoc *doc)
+{//Free entire doc and entries.
+  if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return;
+  DocLock(doc);
+  doc->doc_signature=0;
+  DocRst(doc,TRUE);
+  Free(doc->find_replace);
+  Free(doc->dollar_buf);
+  DocUnlock(doc);
+  Free(doc);
+}
+
+public I64 DocSize(CDoc *doc)
+{//Mem size of doc and all its entries.
+  Bool unlock;
+  CDocEntry *doc_e;
+  CDocUndo *u;
+  CDocBin *b;
+  I64 res=0;
+
+  if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return 0;
+  unlock=DocLock(doc);
+
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    res+=DocEntrySize(doc,doc_e);
+    doc_e=doc_e->next;
+  }
+
+  u=doc->undo_head.next;
+  while (u!=&doc->undo_head) {
+    res+=MSize2(u->body);
+    res+=MSize2(u);
+    u=u->next;
+  }
+
+  b=doc->bin_head.next;
+  while (b!=&doc->bin_head) {
+    res+=MSize2(b->data);
+    res+=MSize2(b);
+    b=b->next;
+  }
+
+  res+=MSize2(doc->find_replace);
+  res+=MSize2(doc->dollar_buf);
+  res+=MSize2(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+#help_index "DolDoc"
+public CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL)
+{//MAlloc new DolDoc. (Begin a new doc.)
+  CDoc *doc;
+  if (!task) task=Fs;
+  doc=CAlloc(sizeof(CDoc),task);
+  if (filename)
+    StrCpy(doc->filename.name,filename);
+  else
+    StrCpy(doc->filename.name,blkdev.tmp_filename);
+  doc->find_replace=CAlloc(sizeof(CEdFindText),task);
+  doc->find_replace->scan_fwd=TRUE;
+  doc->find_replace->match_case=TRUE;
+  doc->find_replace->pmt=TRUE;
+  doc->left_click_link=&EdLeftClickLink;
+  doc->dollar_buf_size=84;
+  doc->dollar_buf=MAlloc(doc->dollar_buf_size,task);
+  doc->max_entries=I64_MAX;
+  doc->win_task=task;
+  doc->mem_task=task;
+  DocRst(doc,FALSE);
+  doc->doc_signature=DOC_SIGNATURE_VAL;
+  return doc;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocPlain.HC.HTML b/public/Wb/Adam/DolDoc/DocPlain.HC.HTML new file mode 100755 index 0000000..e1c78f1 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocPlain.HC.HTML @@ -0,0 +1,642 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+I64 PrsDocFlagSingle(CCmpCtrl *cc,I64 *_de_flags,U32 *_type,Bool turn_on)
+{
+  I64 res=-1;
+  CHashGeneric *tmph;
+  if (cc->token==TK_IDENT &&
+        (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_FLAG))) {
+    res=tmph->user_data0;
+    if (res<64) {
+      BEqu(_de_flags,res,turn_on);
+      switch (res) {
+        case DOCEf_BLINK:
+        case DOCEf_INVERT:
+        case DOCEf_UNDERLINE:
+        case DOCEf_SEL:
+          BEqu(_type,res,turn_on);
+          break;
+      }
+    }
+    Lex(cc);    //skip flag
+  }
+  return res;
+}
+
+I64 PrsDocFlags(CCmpCtrl *cc,I64 *_de_flags,U32 *_type)
+{
+  I64 res=-1;
+  Bool turn_on;
+  while (TRUE) {
+    if (cc->token=='+')
+      turn_on=TRUE;
+    else if (cc->token=='-')
+      turn_on=FALSE;
+    else
+      break;
+    Lex(cc);
+    res=PrsDocFlagSingle(cc,_de_flags,_type,turn_on);
+  }
+  return res;
+}
+
+U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e)
+{//TODO: break strs
+  I64 i,j,attr=doc_e->attr,
+        t1,f1,de_flags,type;
+  U8 *buf,*buf2;
+
+  if (doc_e->type_u8==DOCT_FOREGROUND &&
+        doc->flags&DOCF_COLOR_NAMES && 0<=attr<COLORS_NUM) {
+    buf=StrNew(DefineSub(attr,"ST_COLORS"));
+    attr=DOC_DFT;
+  } else
+    buf=StrNew(DefineSub(doc_e->type_u8,"ST_DOC_CMDS"));
+  if (doc_e->type_u8!=DOCT_ERROR) {
+    f1=doldoc.dft_de_flags[doc_e->type_u8];
+    t1=doc_e->type_u8|doldoc.dft_type_flags[doc_e->type_u8];
+
+    de_flags=doc_e->de_flags&~(DOCG_BL_IV_UL|DOCEF_SEL|
+          DOCEF_HIGHLIGHT|DOCEF_WORD_WRAP|DOCEF_SKIP|DOCEF_FILTER_SKIP);
+    for (i=0;i<DOCEf_FLAGS_NUM;i++)
+      if (Bt(&f1,i)!=Bt(&de_flags,i)) {
+        if (Bt(&de_flags,i)) {
+          if (!(1<<i&DOCEG_HAS_ARG)) {
+            buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
+            Free(buf); buf=buf2;
+          }
+        } else {
+          buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
+          Free(buf); buf=buf2;
+        }
+      }
+    type=doc_e->type&~DOCET_SEL;
+    for (i=DOCEt_BLINK;i<=DOCEt_UNDERLINE;i++)
+      if (Bt(&t1,i)!=Bt(&type,i)) {
+        if (Bt(&type,i))
+          buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
+        else
+          buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
+        Free(buf); buf=buf2;
+      }
+    buf2=MStrPrint("%s,",buf);
+    Free(buf); buf=buf2;
+    switch [doc_e->type_u8] {
+      case DOCT_HEX_ED:
+        buf2=MStrPrint("%s%d,",buf,doc_e->len);
+        Free(buf); buf=buf2;
+        buf2=MStrPrint("%s%d,",buf,doc_e->hex_ed_width);
+        Free(buf); buf=buf2;
+        break;
+      case DOCT_FOREGROUND:
+      case DOCT_BACKGROUND:
+      case DOCT_DFT_FOREGROUND:
+      case DOCT_DFT_BACKGROUND:
+        if (doc->flags&DOCF_COLOR_NAMES && 0<=attr<COLORS_NUM) {
+          buf2=MStrPrint("%s%Z,",buf,doc_e->attr,"ST_COLORS");
+          Free(buf); buf=buf2;
+          break;
+        }
+      case DOCT_PAGE_LEN:
+      case DOCT_LEFT_MARGIN:
+      case DOCT_RIGHT_MARGIN:
+      case DOCT_HEADER:
+      case DOCT_FOOTER:
+      case DOCT_INDENT:
+      case DOCT_WORD_WRAP:
+      case DOCT_HIGHLIGHT:
+      case DOCT_BLINK:
+      case DOCT_INVERT:
+      case DOCT_UNDERLINE:
+      case DOCT_SHIFTED_X:
+      case DOCT_SHIFTED_Y:
+        if (attr!=DOC_DFT) {
+          buf2=MStrPrint("%s%d,",buf,doc_e->attr);
+          Free(buf); buf=buf2;
+        }
+      case DOCT_TYPES_NUM-1: //nobound switch
+        break;
+    }
+    de_flags=doc_e->de_flags & DOCEG_HAS_ARG;
+    while (de_flags) {
+      j=Bsf(de_flags);
+      Btr(&de_flags,j);
+      switch [j] {
+        case DOCEf_TAG:
+          if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_MACRO &&
+                (doc_e->de_flags&DOCEF_LEFT_MACRO &&
+                !StrCmp(doc_e->tag,doc_e->left_macro) ||
+                doc_e->de_flags&DOCEF_RIGHT_MACRO &&
+                !StrCmp(doc_e->tag,doc_e->right_macro)) ||
+                doc_e->de_flags&DOCEF_LST && !StrCmp(doc_e->tag,"[]") &&
+                doc_e->de_flags&DOCEF_DEFINE) {
+            buf2=buf;
+            buf=NULL;
+          } else {
+            if (doc_e->type_u8==DOCT_CHECK_BOX) {
+              if (StrLen(doc_e->tag)>=4)
+                buf2=doc_e->tag+4;
+              else
+                buf2="";
+            } else if (doc_e->de_flags & DOCEF_TREE) {
+              if (StrLen(doc_e->tag)>=3)
+                buf2=doc_e->tag+3;
+              else
+                buf2="";
+            } else
+              buf2=doc_e->tag;
+            if (Bt(&doldoc.dft_de_flags[doc_e->type_u8],DOCEf_TAG))
+              buf2=MStrPrint("%s\"%$Q\",",buf,buf2);
+            else
+              buf2=MStrPrint("%sT=\"%$Q\",",buf,buf2);
+          }
+          break;
+        case DOCEf_LEN:
+          buf2=MStrPrint("%sLEN=%d,",buf,doc_e->len);
+          break;
+        case DOCEf_AUX_STR:
+          buf2=MStrPrint("%sA=\"%$Q\",",buf,doc_e->aux_str);
+          break;
+        case DOCEf_DEFINE:
+          buf2=MStrPrint("%sD=\"%$Q\",",buf,doc_e->define_str);
+          break;
+        case DOCEf_HTML_LINK:
+          buf2=MStrPrint("%sHTML=\"%$Q\",",buf,doc_e->html_link);
+          break;
+        case DOCEf_LEFT_EXP:
+          buf2=MStrPrint("%sLE=%d,",buf,doc_e->left_exp);
+          break;
+        case DOCEf_LEFT_MACRO:
+          buf2=MStrPrint("%sLM=\"%$Q\",",buf,doc_e->left_macro);
+          break;
+        case DOCEf_RIGHT_EXP:
+          buf2=MStrPrint("%sRE=%d,",buf,doc_e->right_exp);
+          break;
+        case DOCEf_RIGHT_MACRO:
+          buf2=MStrPrint("%sRM=\"%$Q\",",buf,doc_e->right_macro);
+          break;
+        case DOCEf_HAS_BIN:
+          buf2=MStrPrint("%sBI=%d,",buf,doc_e->bin_num);
+          break;
+        case DOCEf_BIN_PTR_LINK:
+          buf2=MStrPrint("%sBP=\"%$Q\",",buf,doc_e->bin_ptr_link);
+          break;
+        case DOCEf_RAW_TYPE:
+          if (doc_e->type_u8==DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I8 ||
+                doc_e->type_u8!=DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I64)
+            buf2=MStrPrint("%sRT=%Z,",buf,doc_e->raw_type,"ST_RAW_TYPES");
+          break;
+        case DOCEf_SHIFTED_X:
+          j=doc_e->type.u16[1]&0x1F;
+          if (j&0x10) j|=0xFFFFFFF0;
+          buf2=MStrPrint("%sSX=%d,",buf,j);
+          break;
+        case DOCEf_SHIFTED_Y:
+          j=doc_e->type>>21 &0x1F;
+          if (j&0x10) j|=0xFFFFFFF0;
+          buf2=MStrPrint("%sSY=%d,",buf,j);
+          break;
+        case DOCEf_SCROLLING_X:
+          buf2=MStrPrint("%sSCX=%d,",buf,doc_e->scroll_len);
+          break;
+        case DOCEf_USER_DATA:
+          buf2=MStrPrint("%sU=0x%X,",buf,doc_e->user_data);
+          break;
+        case DOCEf_FLAGS_NUM-1: //nobound switch
+          break;
+      }
+      Free(buf); buf=buf2;
+    }
+    buf[StrLen(buf)-1]=0;  //Kill last comma
+  }
+  buf2=StrNew(buf,doc->mem_task); //exact allocation
+  Free(buf);
+  return buf2;
+}
+
+CDocEntry *PrsDollarCmd(CDoc *doc,U8 *st)
+{//Uses Lex() to parse a string and make Doc entries.
+  I64 i,j,de_flags,processed_flags,attr=DOC_DFT;
+  U8 *ptr,*st2;
+  CDocEntry *doc_e=NULL;
+  CHashGeneric *tmph;
+  CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
+  CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;
+  try {
+    cc->htc.hash_table_lst=NULL;
+    if (Lex(cc)==TK_IDENT) {
+      if (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_CMD|DHT_COLOR)) {
+        if (tmph->type&DHT_DOC_CMD)
+          i=tmph->user_data0;
+        else {//DHT_COLOR
+          i=DOCT_FOREGROUND;
+          attr=tmph->user_data0;
+        }
+      } else
+        goto pd_err;
+      Lex(cc); //skip cmd code
+      doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
+      doc_e->type=i;
+      doc_e->de_flags=doldoc.dft_de_flags[i];
+      doc_e->type|=doldoc.dft_type_flags[i];
+      doc_e->raw_type=RT_I64;
+      doc_e->len=DOCE_LEN_DFT;
+      j=PrsDocFlags(cc,&doc_e->de_flags,&doc_e->type);
+      cc->htc.hash_table_lst=old_hash_table_lst;
+      switch [i] {
+        case DOCT_CHECK_BOX:
+          doc_e->raw_type=RT_I8;
+          break;
+        case DOCT_HEX_ED:
+          while (cc->token==',')
+            Lex(cc);
+          if (cc->token)
+            doc_e->len=LexExpressionI64(cc);
+          else
+            goto pd_err;
+          while (cc->token==',')
+            Lex(cc);
+          if (cc->token)
+            doc_e->hex_ed_width=LexExpressionI64(cc);
+          else
+            goto pd_err;
+          break;
+        case DOCT_PAGE_LEN:
+        case DOCT_LEFT_MARGIN:
+        case DOCT_RIGHT_MARGIN:
+        case DOCT_HEADER:
+        case DOCT_FOOTER:
+        case DOCT_INDENT:
+        case DOCT_FOREGROUND:
+        case DOCT_BACKGROUND:
+        case DOCT_DFT_FOREGROUND:
+        case DOCT_DFT_BACKGROUND:
+        case DOCT_WORD_WRAP:
+        case DOCT_HIGHLIGHT:
+        case DOCT_BLINK:
+        case DOCT_INVERT:
+        case DOCT_UNDERLINE:
+        case DOCT_SHIFTED_X:
+        case DOCT_SHIFTED_Y:
+          while (cc->token==',')
+            Lex(cc);
+          if (cc->token)
+            doc_e->attr=LexExpressionI64(cc);
+          else
+            doc_e->attr=attr;
+          break;
+#assert DOCT_ERROR==DOCT_TYPES_NUM-1
+        case DOCT_ERROR:
+          goto pd_err;
+      }
+
+      processed_flags=0;
+      while (TRUE) {
+        cc->htc.hash_table_lst=NULL;
+        while (cc->token==',')
+          Lex(cc);
+        cc->htc.hash_table_lst=old_hash_table_lst;
+        j=PrsDocFlagSingle(cc,&doc_e->de_flags,&doc_e->type,TRUE);
+        if (!(de_flags=~processed_flags & doc_e->de_flags & DOCEG_HAS_ARG))
+          break;
+        if (cc->token=='=')
+          Lex(cc);
+        else
+          j=Bsf(de_flags);
+        if (j<0 || Bts(&processed_flags,j))
+          goto pd_err;
+        switch [j] {//TODO: Might check for expression errors
+          case DOCEf_TAG:
+            if (!doc_e->tag) {
+//If a $MA,LM=""$, Tag is filled when the LM is processed.
+              //if doc_e->df_flags&DOCEF_LST,
+              // Tag is filled when the Define is processed.
+              //(The dft_flag1.tag calls this after.)
+              if (cc->token==TK_STR) {
+                st2=LexExtStr(cc);
+                if (i==DOCT_CHECK_BOX) {
+                  st=MStrPrint("[X] %s",st2);
+                  Free(st2);
+                  doc_e->min_col=1;
+                } else if (doc_e->de_flags & DOCEF_LST) {
+                  if (*st2!='[') {
+                    st=MStrPrint("[%s]",st2);
+                    Free(st2);
+                  } else
+                    st=st2;
+                  doc_e->min_col=1;
+                } else if (doc_e->de_flags & DOCEF_TREE) {
+                  st=MStrPrint("+] %s",st2);
+                  Free(st2);
+                  doc_e->min_col=1;
+                } else
+                  st=st2;
+                doc_e->tag=StrNew(st,doc->mem_task);
+                Free(st);
+              } else
+                goto pd_err;
+            }
+            break;
+          case DOCEf_LEN:
+            if (cc->token) {
+              doc_e->len=LexExpression(cc);
+              doc_e->de_flags&=~DOCEF_DFT_LEN;
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_AUX_STR:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->aux_str=StrNew(st2,doc->mem_task);
+              Free(st2);
+//Anchor
+              if (i==DOCT_DATA) { //See DocForm()
+                if (ptr=StrMatch(":",doc_e->aux_str))
+                  doc_e->min_col=ptr-doc_e->aux_str+1;
+                doc_e->tag=MAlloc(doc_e->len+doc_e->min_col+2,
+                      doc->mem_task); //+2 because "_\0"
+              }
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_DEFINE:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->define_str=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (doc_e->de_flags&DOCEF_LST && !doc_e->tag)
+                doc_e->tag=StrNew("[]",doc->mem_task);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_HTML_LINK:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->html_link=StrNew(st2,doc->mem_task);
+              Free(st2);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_LEFT_EXP:
+            if (cc->token)
+              doc_e->left_exp=LexExpression(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_LEFT_MACRO:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->left_macro=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (i==DOCT_MACRO && !doc_e->tag)
+                doc_e->tag=StrNew(doc_e->left_macro,doc->mem_task);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_RIGHT_EXP:
+            if (cc->token)
+              doc_e->right_exp=LexExpression(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_RIGHT_MACRO:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->right_macro=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (i==DOCT_MACRO && !doc_e->tag)
+                doc_e->tag=StrNew(doc_e->right_macro,doc->mem_task);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_HAS_BIN:
+            if (cc->token)
+              doc_e->bin_num=LexExpressionI64(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_BIN_PTR_LINK:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->bin_ptr_link=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (!DocBinPtrRst(doc,doc_e))
+                doc_e->type=DOCT_ERROR;
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_RAW_TYPE:
+            if (cc->token==TK_IDENT) {
+              j=DefineMatch(cc->cur_str,"ST_RAW_TYPES");
+              if (j<0)
+                goto pd_err;
+              doc_e->raw_type=j;
+              doc_e->de_flags&=~DOCEF_DFT_RAW_TYPE;
+              Lex(cc);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_SHIFTED_X:
+            if (cc->token)
+              doc_e->type|=(LexExpressionI64(cc) & 0x1F)<<16;
+            else
+              goto pd_err;
+            break;
+          case DOCEf_SHIFTED_Y:
+            if (cc->token)
+              doc_e->type|=(LexExpressionI64(cc) & 0x1F)<<21;
+            else
+              goto pd_err;
+            break;
+          case DOCEf_SCROLLING_X:
+            if (cc->token)
+              doc_e->scroll_len=LexExpressionI64(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_USER_DATA:
+            if (cc->token)
+              doc_e->user_data=LexExpression(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_FLAGS_NUM-1: //nobound switch
+            break;
+        }
+      }
+    } else {
+pd_err:
+      if (!doc_e)
+        doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
+      doc_e->type=DOCT_ERROR;
+      doc_e->de_flags=0;
+    }
+    if (doc_e->de_flags&DOCEF_LST && (doc_e->de_flags&DOCEF_REMALLOC_DATA ||
+          !(doc_e->de_flags&DOCEF_DEREF_DATA))) {
+      DocDataScan(doc,doc_e);
+      DocDataFmt(doc,doc_e);
+    }
+    CmpCtrlDel(cc);
+  } catch {
+    Fs->catch_except=TRUE;
+    if (!doc_e)
+      doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
+    doc_e->type=DOCT_ERROR;
+    doc_e->de_flags=0;
+  }
+  return doc_e;
+}
+
+U0 DocEntryToggle(CDoc *doc)
+{
+  Bool unlock=DocLock(doc),old_color_names;
+  CDocEntry *doc_ce=doc->cur_entry,*cl1,*doc_ce2;
+  U8 ch,*st,*st2;
+  I64 i,j,k;
+  if (doc_ce!=doc &&
+        !(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
+    if (doc_ce->type_u8==DOCT_TEXT && !(doc_ce->de_flags &
+          ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|
+          DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
+          !(doc_ce->type&DOCG_BL_IV_UL)) {
+      doc_ce2=doc_ce->last;
+      for (k=0;k<20;k++) {
+        if (doc_ce2!=doc) {
+          cl1=doc_ce2->last;
+          if (doc_ce2->type_u8==DOCT_TEXT &&
+                doc_ce->de_flags==doc_ce2->de_flags &&
+                doc_ce->type==doc_ce2->type) {
+            i=StrLen(doc_ce2->tag);
+            j=StrLen(doc_ce->tag);
+            st=MAlloc(i+j+1,doc->mem_task);
+            MemCpy(st,doc_ce2->tag,i);
+            MemCpy(st+i,doc_ce->tag,j+1);
+            Free(doc_ce->tag);
+            doc_ce->tag=st;
+            doc_ce->max_col=i+j;
+            doc->cur_col+=i;
+            DocEntryDel(doc,doc_ce2);
+          } else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
+            DocEntryDel(doc,doc_ce2);
+          else
+            break;
+          doc_ce2=cl1;
+        } else
+          break;
+      }
+      doc_ce2=doc_ce->next;
+      for (k=0;k<20;k++) {
+        if (doc_ce2!=doc) {
+          cl1=doc_ce2->next;
+          if (doc_ce2->type_u8==DOCT_TEXT &&
+                doc_ce->de_flags==doc_ce2->de_flags &&
+                doc_ce->type==doc_ce2->type) {
+            i=StrLen(doc_ce->tag);
+            j=StrLen(doc_ce2->tag);
+            st=MAlloc(i+j+1,doc->mem_task);
+            MemCpy(st,doc_ce->tag,i);
+            MemCpy(st+i,doc_ce2->tag,j+1);
+            Free(doc_ce->tag);
+            doc_ce->tag=st;
+            doc_ce->max_col=i+j;
+            DocEntryDel(doc,doc_ce2);
+          } else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
+            DocEntryDel(doc,doc_ce2);
+          else
+            break;
+          doc_ce2=cl1;
+        } else
+          break;
+      }
+      i=doc->cur_col;
+      while (i>doc_ce->min_col && doc_ce->tag[i]!='$')
+        i--;
+      j=doc->cur_col+1;
+      while (j<doc_ce->max_col && doc_ce->tag[j]!='$')
+        j++;
+      if (i<j-1 && doc_ce->min_col<=i<j<doc_ce->max_col &&
+            doc_ce->tag[i]=='$' && doc_ce->tag[j]=='$') {
+        ch=doc_ce->tag[j+1];
+        doc_ce->tag[j+1]=0;
+        st=StrNew(doc_ce->tag+i);
+        doc_ce->tag[j+1]=ch;
+        StrCpy(doc_ce->tag+i,doc_ce->tag+j+1);
+        doc->cur_col=i;
+        st2=MStrPrint("%q",st);
+        if (doc_ce=DocPrint(doc,st2)) {
+          doc->cur_entry=doc_ce;
+          doc->cur_col=doc_ce->min_col;
+        }
+        Free(st);
+        Free(st2);
+      }
+    } else {
+      old_color_names=LBts(&doc->flags,DOCf_COLOR_NAMES);
+      st=Doc2PlainText(doc,doc_ce);
+      LBEqu(&doc->flags,DOCf_COLOR_NAMES,old_color_names);
+      DocEntryDel(doc,doc_ce);
+      DocPrint(doc,"$$%$Q$$",st);
+    }
+    DocRecalc(doc);
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 DocFlagsToggle(CDoc *doc,I64 tog_flags)
+{
+  Bool  unlock=DocLock(doc);
+  I64 size,flags=doc->flags^tog_flags;
+  U8 *st;
+  CDocUndo *u_next,*u_last;
+
+  doc->flags=doc->flags&~DOCF_NO_CURSOR|DOCF_COLOR_NAMES;
+  st=DocSave(doc,&size);
+
+  u_next=doc->undo_head.next;
+  u_last=doc->undo_head.last;
+  doc->undo_head.next=doc->undo_head.last=&doc->undo_head;
+
+  DocRst(doc,TRUE);
+  doc->undo_head.next=u_next;
+  doc->undo_head.last=u_last;
+  DocUndoCntSet(doc);
+  doc->flags=flags&~(DOCF_NO_CURSOR|DOCG_BL_IV_UL|DOCF_WORD_WRAP);
+  DocLoad(doc,st,size);
+  doc->flags|=flags&DOCF_NO_CURSOR;
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+  Free(st);
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocPopUp.HC.HTML b/public/Wb/Adam/DolDoc/DocPopUp.HC.HTML new file mode 100755 index 0000000..26e734f --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocPopUp.HC.HTML @@ -0,0 +1,348 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+public CTask *PopUpViewDoc(CDoc *doc,I64 dof_flags=0)
+{//Pass doc to PopUp win task for viewing.
+  U8 *buf=MStrPrint("DocEd(0x%X,0x%X);",doc,dof_flags);
+  CTask *task=Spawn(&SrvCmdLine,NULL,"View",,Fs);
+  TaskExe(task,NULL,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  Free(buf);
+  return task;
+}
+
+public CTask *PopUpViewPrint(U8 *fmt,...)
+{//View Print stmt in PopUp win task.
+  CTask *task=Spawn(&SrvCmdLine,NULL,"View",,Fs);
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CDoc *doc=DocNew(,task);
+  DocPrint(doc,buf);
+  Free(buf);
+  buf=MStrPrint("DocEd(0x%X);",doc);
+  TaskExe(task,NULL,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  Free(buf);
+  return task;
+}
+
+#help_index "DolDoc/Input;File/FileNames;StdIn/DolDoc"
+public U8 *PopUpPickFile(U8 *dir=NULL)
+{//Filename chooser.  Uses FileMgr().
+  U8 *res,*st,*st2;
+  if (dir)
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",dir);
+  else {
+    st2=DirCur;
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",st2);
+    Free(st2);
+  }
+  res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public U8 *PopUpPickDir(U8 *dir=NULL)
+{//File dir name chooser.  Uses FileMgr().
+  U8 *res,*st,*st2;
+  if (dir)
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",dir);
+  else {
+    st2=DirCur;
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",st2);
+    Free(st2);
+  }
+  res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public U8 *FileNameForm(U8 *dft=NULL,I64 dof_flags=0,CTask *mem_task=NULL)
+{//Text filename form in cur win, not PopUp.
+  CEdFileName fn;
+  if (dft)
+    StrCpy(fn.name,dft);
+  else
+    *fn.name=0;
+  if (DocForm(&fn,,dof_flags))
+    return StrNew(fn.name,mem_task);
+  else
+    return NULL;
+}
+
+public U8 *PopUpFileName(U8 *dft=NULL,I64 dof_flags=0)
+{//Filename chooser. Uses form, not FileMgr().
+  U8 *st=MStrPrint("FileNameForm(\"%Q\",0x%X,Fs->parent_task);",
+        dft,dof_flags|DOF_SIZE_MIN),*res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+#help_index "DolDoc"
+Bool PopUpCd()
+{
+  Bool res;
+  U8 *st=PopUpPickDir;
+  if (st) {
+    res=Cd(st);
+    Free(st);
+  } else
+    res=FALSE;
+  return res;
+}
+
+#help_index "DolDoc/Input;Char/Lists;StdIn/DolDoc"
+public I64 PopUpPickLst(U8 *lst)
+{//Prompt for lst entry in PopUp win task.
+  I64 res,i=0;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$LTBLUE$");
+  while (*lst) {
+    if (*lst=='@') {//Check for '@' alias lst entry
+      i--;
+      lst++;
+    }
+    DocPrint(doc,"$MU,\"%s\",LE=%d$\n",lst,i++);
+    lst+=StrLen(lst)+1;
+  }
+  DocPrint(doc,"\n$MU,\"CANCEL\",LE=DOCM_CANCEL$\n");
+  res=PopUpMenu(doc);
+  DocDel(doc);
+  return res;
+}
+
+#help_index "DolDoc/Input;Char/Lists;Char/Define;StdIn/DolDoc"
+public U8 *PopUpPickDefineSub(U8 *dname)
+{//Prompt for Define lst entry in PopUp win task.
+  return PopUpPickLst(Define(dname));
+}
+
+#help_index "DolDoc/Input;StdIn/DolDoc"
+public I64 PopUp1(U8 *b1,I64 n1,U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with one bttn.
+  I64 i,l1=StrLen(b1);
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"$CM+CX,%d,4$$BT,\"%s\",LE=%d$\n",-l1/2,b1,n1);
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public I64 PopUp2(U8 *b1,I64 n1,U8 *b2,I64 n2,U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with two bttns.
+  I64 i,l1=StrLen(b1),l2=StrLen(b2),y;
+  CDoc *doc=DocNew;
+  if (header) {
+    DocPrint(doc,"%s",header);
+    y=4;
+  } else {
+    DocPrint(doc,"%*s\n",l1+l2+10,"");
+    y=3;
+  }
+  DocPrint(doc,"$CM+CX,%d,%d$$BT,\"%s\",LE=%d$",-(l1+l2+3)>>1,y,b1,n1);
+  DocPrint(doc,"$CM+CX,%d,0$$BT,\"%s\",LE=%d$\n" ,-(l1+l2+3)>>1+l1+6,b2,n2);
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with OKAY bttn.
+  return PopUp1("OKAY",1,header,footer)>0;
+}
+
+public Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with NO/YES bttns.
+  return PopUp2("YES",1,"NO",0,header,footer)>0;
+}
+
+public Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task CANCEL/OKAY bttns.
+  return PopUp2("OKAY",1,"CANCEL",0,header,footer)>0;
+}
+
+U8 *PopUpGetStr2(U8 *header,CTask *mem_task)
+{
+  U8 *res,*st;
+  if (header)
+    "%s",header;
+  st=GetStr(,,GSF_WITH_NEW_LINE);
+  res=StrNew(st,mem_task);
+  Free(st);
+  return res;
+}
+
+public U8 *PopUpGetStr(U8 *header=NULL)
+{//Prompt for text str in PopUp win task.
+  U8 *st=MStrPrint("PopUpGetStr2(0x%X,0x%X);",header,Fs),
+        *res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public I64 PopUpGetI64(U8 *msg,I64 dft,I64 lo=I64_MIN,I64 hi=I64_MAX)
+{//Prompt for I64 text expression in PopUp win task.
+  U8 *st=MStrPrint("GetI64(0x%X,0x%X,0x%X,0x%X);",msg,dft,lo,hi);
+  I64 res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public F64 PopUpGetF64(U8 *msg,F64 dft,F64 lo=F64_MIN,F64 hi=F64_MAX)
+{//Prompt for F64 text expression in PopUp win task.
+  U8 *st=MStrPrint("GetF64(0x%X,0x%X(F64),0x%X(F64),0x%X(F64));",msg,dft,lo,hi);
+  F64 res=PopUp(st,Fs)(F64);
+  Free(st);
+  return res;
+}
+
+public I64 PopUpRangeI64(I64 lo,I64 hi,I64 step=1,
+        U8 *header=NULL,U8 *footer=NULL)
+{//Evenly-spaced I64 range chooser in PopUp win task.
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"$LTBLUE$");
+  for (i=lo;i<=hi;i+=step)
+    DocPrint(doc,"$MU,\"%d\",LE=%d$\n",i,i);
+  if (footer)
+    DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public F64 PopUpRangeF64(F64 lo,F64 hi,F64 step,
+    U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
+{//Evenly-spaced F64 range chooser in PopUp win task.
+  F64 d;
+  I64 i;
+  U8 buf[STR_LEN];
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"$LTBLUE$");
+  for (d=lo;d<=hi;d+=step) {
+    StrPrint(buf,fmt,d);
+    DocPrint(doc,"$MU,\"%s\",LE=0x%X$\n",buf,d);
+  }
+  if (footer)
+    DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i(F64);
+}
+
+public F64 PopUpRangeF64Exp(F64 lo,F64 hi,F64 factor,
+    U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
+{//Exp-spaced F64 range chooser in PopUp win task.
+  F64 d;
+  I64 i;
+  U8 buf[STR_LEN];
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"$LTBLUE$");
+  for (d=lo;d<=hi;d*=factor) {
+    StrPrint(buf,fmt,d);
+    DocPrint(doc,"$MU,\"%s\",LE=0x%X$\n",buf,d);
+  }
+  if (footer)
+    DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i(F64);
+}
+
+public F64 PopUpRangeF64Log(F64 lo,F64 hi,I64 steps,
+    U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
+{//Log-spaced F64 range chooser in PopUp win task.
+  return PopUpRangeF64Exp(lo,hi,Exp(Ln(hi/lo)/(steps-1)),fmt,header,footer);
+}
+
+#help_index "Job/Exe;Task/Job/Exe;Compiler"
+public I64 AdamFile(U8 *filename,Bool warn_ext=TRUE)
+{//Make adam_task execute file.
+  Bool okay=TRUE;
+  U8 *name=FileNameAbs(filename),
+        *name2=ExtDft(name,"HC.Z");
+  I64 res=0;
+  if (warn_ext &&
+        !FilesFindMatch(name2,FILEMASK_JIT) &&
+        !PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n"))
+    okay=FALSE;
+  if (okay)
+    res=Adam("#include \"%s\";",name2);
+  Free(name2);
+  Free(name);
+  return res;
+}
+
+public I64 PopUpFile(U8 *filename,Bool warn_ext=TRUE,
+        CTask *parent=NULL,CTask **_pu_task=NULL)
+{//ExeFile2() in PopUp task. Cont as User.
+  Bool okay=TRUE;
+  U8 *st,*name=FileNameAbs(filename),
+        *name2=ExtDft(name,"HC.Z");
+  I64 res=0;
+  if (warn_ext &&
+        !FilesFindMatch(name2,FILEMASK_JIT) &&
+        !PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n"))
+    okay=FALSE;
+  if (okay) {
+    st=MStrPrint(
+          "\"$$WW+H,1$$\";In(\"ExeFile2(\\\"%s\\\",CCF_CMD_LINE);\\n\");"
+          "UserTaskCont;",
+          name2);
+    res=PopUp(st,parent,_pu_task);
+    Free(st);
+  }
+  Free(name2);
+  Free(name);
+  return res;
+}
+
+public I64 PopUpRunFile(U8 *filename,I64 ccf_flags=0,...)
+{//ExeFile() with args using LastFun() in PopUp task.
+  U8 *st,*name=FileNameAbs(filename),
+        *name2=ExtDft(name,"HC.Z");
+  I64 res=0;
+  st=MStrPrint(
+        "\"$$WW+H,1$$\";ExeFile2(\"%s\",0x%X);LastFun(0x%X,0x%X);",
+        name2,ccf_flags,argc,argv);
+  res=PopUp(st,Fs);
+  Free(st);
+  Free(name2);
+  Free(name);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocPutKey.HC.HTML b/public/Wb/Adam/DolDoc/DocPutKey.HC.HTML new file mode 100755 index 0000000..24b2d8f --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocPutKey.HC.HTML @@ -0,0 +1,760 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+
+public U0 DocPutKey(CDoc *doc,I64 ch=0,I64 sc=0)
+{//PutKey(ch,sc) at doc insert pt, cur_entry.
+  I64 i,x,y;
+  CDoc *m;
+  CDocEntry *doc_ce;
+  U8 *st,*st2;
+  Bool unlock;
+
+  if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return;
+  if (doc->user_put_key && (*doc->user_put_key)(doc,doc->user_put_data,ch,sc))
+    return;
+  unlock=DocLock(doc);
+  if (!Bt(doldoc.clean_scan_codes,sc.u8[0]))
+    doc->flags|=DOCF_UNDO_DIRTY;
+  DocCaptureUndo(doc);
+  if (Bt(char_bmp_printable,ch) && !(sc&(SCF_CTRL|SCF_ALT))) {
+    if (sc&SCF_KEY_DESC) {
+      st=Char2KeyName(ch,FALSE);
+      KeyDescSet("Char  /'%s'",st);
+      Free(st);
+    } else
+      EdCharIns(ch,sc,doc);
+  } else {
+    doc_ce=doc->cur_entry;
+    x=doc->x; y=doc->y;
+    if (sc&SCF_ALT)
+      switch (ch) {
+        case CH_BACKSPACE: //<CTRL-H>
+          if (!(sc&(SCF_SHIFT|SCF_CTRL))) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Undo");
+            else
+              DocUndoRestore(doc);
+          }
+          break;
+      }
+    else
+      switch (ch) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_DOWN:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Down, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Down");
+                } else
+                  EdLineDown(doc,sc);
+                break;
+              } else
+                sc&=~SCF_CTRL;
+//Fall Through to SC_END
+            case SC_END:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/GoTo Doc End, Sel");
+                  else
+                    KeyDescSet("Edit/GoTo Doc End");
+                } else {
+                  while (doc_ce!=doc) {
+                    BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+                    doc_ce=doc->cur_entry=doc_ce->next;
+                  }
+                  doc->cur_col=doc_ce->min_col;
+                  DocFormBwd(doc);
+                }
+              }
+              break;
+            case SC_CURSOR_UP:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Up, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Up");
+                } else
+                  EdLineUp(doc,sc);
+                break;
+              } else
+                sc&=~SCF_CTRL;
+//Fall Through to SC_HOME
+            case SC_HOME:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/GoTo Top of Doc, Sel");
+                  else
+                    KeyDescSet("Edit/GoTo Top of Doc");
+                } else {
+                  if (doc_ce==doc) doc_ce=doc_ce->last;
+                  while (doc_ce!=doc) {
+                    BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+                    doc_ce=doc->cur_entry=doc_ce->last;
+                  }
+                  doc_ce=doc->cur_entry=doc->head.next;
+                  doc->cur_col=doc_ce->min_col;
+                  DocFormFwd(doc);
+                }
+              }
+              break;
+            case SC_PAGE_DOWN:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Page Down, Sel");
+                  else
+                    KeyDescSet("Edit/Page Down");
+                } else {
+                  i=doc_ce->y+doc->win_task->win_height-1;
+                  if (doc_ce->type_u8==DOCT_HEX_ED)
+                    i+=doc->cur_col/3/doc_ce->hex_ed_width;
+                  while (doc_ce!=doc &&
+                        (doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y<i ||
+                        doc_ce->type_u8==DOCT_HEX_ED &&
+                        doc_ce->y+doc->cur_col/3/doc_ce->hex_ed_width<i)) {
+                    EdLineDown(doc,sc);
+//paranoid check for stuck on same node
+                    if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
+                      break;
+                    doc_ce=doc->cur_entry;
+                  }
+                }
+              }
+              break;
+            case SC_PAGE_UP:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Page Up, Sel");
+                  else
+                    KeyDescSet("Edit/Page Up");
+                }else {
+                  i=doc_ce->y-(doc->win_task->win_height-1);
+                  if (doc_ce->type_u8==DOCT_HEX_ED)
+                    i+=doc->cur_col/3/doc_ce->hex_ed_width;
+                  while (doc_ce->last!=doc &&
+                        (doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y>i ||
+                        doc_ce->type_u8==DOCT_HEX_ED &&
+                        doc_ce->y+doc->cur_col/3/doc_ce->hex_ed_width>i) &&
+                        doc_ce->y!=doc->head.next->y) {
+                    EdLineUp(doc,sc);
+//paranoid check for stuck on same node
+                    if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
+                      break;
+                    doc_ce=doc->cur_entry;
+                  }
+                }
+              }
+              break;
+            case SC_CURSOR_LEFT:
+              if (sc&SCF_KEY_DESC) {
+                if (sc&SCF_CTRL)
+                  KeyDescSet("Edit/GoTo Start of Line");
+                else {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Left, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Left");
+                }
+              } else
+                EdCursorLeft(doc,sc);
+              break;
+            case SC_CURSOR_RIGHT:
+              if (sc&SCF_KEY_DESC) {
+                if (sc&SCF_CTRL)
+                  KeyDescSet("Edit/GoTo End of Line");
+                else {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Right, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Right");
+                }
+              } else
+                EdCursorRight(doc,sc);
+              break;
+            case SC_DELETE:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cut To Clip");
+                  else
+                    KeyDescSet("Char  /Delete");
+                } else {
+                  if (sc&SCF_SHIFT)
+                    ClipCut(doc);
+                  else
+                    EdCharDel(doc);
+                }
+              }
+              break;
+            case SC_INS:
+              if (sc&(SCF_SHIFT|SCF_CTRL)!=(SCF_SHIFT|SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Paste Clip");
+                  else if (sc&SCF_CTRL)
+                    KeyDescSet("Edit/Copy to Clip");
+                  else
+                    KeyDescSet("Edit/Toggle Overstrike");
+                } else {
+                  if (sc&SCF_SHIFT)
+                    ClipPaste(doc);
+                  else if (sc&SCF_CTRL)
+                    ClipCopy(doc);
+                  else
+                    doc->flags^=DOCF_OVERSTRIKE;
+                }
+              }
+              break;
+            case SC_F1...SC_F10:
+              if (sc&SCF_CTRL) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Cmd /Src Code of Sym");
+                  else
+                    KeyDescSet("Edit/Autocomplete Sym");
+                } else {
+                  DocUnlock(doc);
+                  if (AutoComplete(ON)) {
+                    if (sc&SCF_SHIFT)
+                      ACMan(sc.u8[0]-SC_F1+1,Fs);
+                    else
+                      ACFillIn(sc.u8[0]-SC_F1+1);
+                  }
+                  DocLock(doc);
+                }
+              } else {
+                switch (sc.u8[0]) {
+                  case SC_F1:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /About");
+                      else
+                        KeyDescSet("Cmd /Help");
+                    } else {
+                      if (sc&SCF_SHIFT)
+                        Ed("::/Doc/AboutTempleOS.DD.Z");
+                      else
+                        Ed("::/Doc/HelpIndex.DD.Z");
+                    }
+                    break;
+                  case SC_F2:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Edit/Play Macro");
+                      else
+                        KeyDescSet("Edit/Macro");
+                    } else {
+                      DocUnlock(doc);
+                      if (sc&SCF_SHIFT) {
+                        if (TaskValidate(sys_macro_task))
+                          PostMsgWait(sys_macro_task,
+                                MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+                        SysMacroStripKey(&sys_macro_head,ch,sc);
+                        PlaySysMacro;
+                      } else
+                        EdMacroUtil;
+                      DocLock(doc);
+                    }
+                    break;
+                  case SC_F3:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Edit/Find Last");
+                      else
+                        KeyDescSet("Edit/Find Next");
+                    }else {
+                      doc->find_replace->scan_fwd=!(sc&SCF_SHIFT);
+                      EdFindNext(doc);
+                    }
+                    break;
+                  case SC_F4:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /Insert Directory Name");
+                      else
+                        KeyDescSet("Cmd /Insert FileName");
+                    } else {
+                      DocUnlock(doc);
+                      if (sc&SCF_SHIFT)
+                        st=PopUpPickDir;
+                      else
+                        st=PopUpPickFile;
+                      DocLock(doc);
+                      if (st) {
+                        DocPrintPartial(doc,"%s",st);
+                        Free(st);
+                      }
+                    }
+                    break;
+                  case SC_F5:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /Adam Include");
+                      else
+                        KeyDescSet("Cmd /Run (Execute)");
+                    } else {
+                      if (st2=DocEntryLink(doc,doc_ce)) {
+                        st=DocLinkFile(st2);
+                        Free(st2);
+                      } else {
+                        DocWrite(doc);
+                        st=StrNew(doc->filename.name);
+                      }
+                      if (st2=DirFile(st,"Run","HC.Z")) {
+                        if (FileFind(st2)) {
+                          Free(st);
+                          st=st2;
+                        } else
+                          Free(st2);
+                      }
+                      if (st) {
+                        if (sc&SCF_SHIFT)
+                          AdamFile(st);
+                        else
+                          PopUpFile(st);
+                        Free(st);
+                      }
+                    }
+                    break;
+                  case SC_F6:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /God Doodle");
+                      else
+                        KeyDescSet("Cmd /God Song");
+                    } else {
+//::/Adam/God/HSNotes.DD
+                      if (sc&SCF_SHIFT) {
+                        DocUnlock(doc);
+                        GodDoodle;
+                        DocLock(doc);
+                      } else
+                        GodSong;
+                    }
+                    break;
+                  case SC_F7:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /God Passage");
+                      else
+                        KeyDescSet("Cmd /God Word");
+                    } else {
+//::/Adam/God/HSNotes.DD
+                      FifoU8Flush(god.fifo);
+                      GodBitsIns(GOD_GOOD_BITS,KbdMsEvtTime>>GOD_BAD_BITS);
+                      if (sc&SCF_SHIFT)
+                        GodBiblePassage;
+                      else
+                        GodWord;
+                    }
+                    break;
+                }
+              }
+              break;
+          }
+          break;
+        case CH_CTRLA:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Save As");
+            else if (DocWrite(doc,TRUE)&&(st=FileNameAbs(doc->filename.name))) {
+              DirContextDel(doc->filename.dirc);
+              doc->filename.dirc=DirContextNew(st);
+              Free(st);
+            }
+          }
+          break;
+        case CH_CTRLB:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Toggle Border");
+            else
+              WinBorder(Bt(&doc->win_task->display_flags,
+                    DISPLAYf_NO_BORDER),doc->win_task);
+          }
+          break;
+        case CH_CTRLC:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Copy to Clip");
+            else
+              ClipCopy(doc);
+          }
+          break;
+        case CH_CTRLD:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /File Manager");
+            else {
+              DocUnlock(doc);
+              FileMgr;
+              DocLock(doc);
+            }
+          }
+          break;
+        case CH_CTRLF:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Search Files");
+            else
+              FindWiz;
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Find & Replace");
+            else
+              EdFindReplace(doc);
+          }
+          break;
+        case CH_CTRLG:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/GoTo Line Num");
+            else
+              EdGoToLine(doc);
+          }
+          break;
+        case CH_BACKSPACE: //<CTRL-H>
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Char  /Back Space");
+            else {
+              DocCaptureUndo(doc);
+              doc_ce=doc->cur_entry;
+              if (doc->cur_col<=doc_ce->min_col) {
+                doc_ce=doc->cur_entry=doc_ce->last;
+                if (doc_ce!=doc && doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
+                  doc_ce=doc->cur_entry=doc_ce->last;
+                if (doc_ce==doc || doc_ce->type_u8==DOCT_PMT) {
+                  doc_ce=doc->cur_entry=doc_ce->next;
+                  doc->cur_col=doc_ce->min_col;
+                } else {
+                  doc->cur_col=doc_ce->max_col;
+                  if (doc->cur_col>doc_ce->min_col)
+                    doc->cur_col--;
+                  EdCharDel(doc);
+                }
+              } else {
+                doc->cur_col--;
+                EdCharDel(doc);
+              }
+            }
+          }
+          break;
+        case CH_CTRLI:
+          if (sc.u8[0]!=SC_TAB) {
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Unindent 2");
+              else
+                DocPrint(doc,"$ID,-2$");
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Indent 2");
+              else
+                DocPrint(doc,"$ID,2$");
+            }
+          }
+          break;
+        case '\n':
+          if (sc&SCF_KEY_DESC) {
+            if (sc&SCF_SHIFT)
+              KeyDescSet("Char  /Return");
+            else
+              KeyDescSet("Char  /Page Break");
+          } else
+            EdCharIns(ch,sc,doc);
+          break;
+        case CH_CTRLK:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Blinking Text Off");
+            else
+              DocPrint(doc,"$BK,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Blinking Text On");
+            else
+              DocPrint(doc,"$BK,1$");
+          }
+          break;
+        case CH_CTRLL:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Code Tools");
+            else {
+              DocUnlock(doc);
+              EdCodeTools(doc);
+              DocLock(doc);
+            }
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Insert Text Widgets Wizard");
+            else {
+              DocUnlock(doc);
+              EdInsWidgetWiz;
+              DocLock(doc);
+            }
+          }
+          break;
+        case CH_CTRLM:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Personal Notes");
+            else
+              Ed("~/PersonalNotes.DD.Z");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Personal Menu");
+            else {
+              m=DocRead("~/PersonalMenu.DD.Z");
+              DocMenu(m);
+              DocDel(m);
+            }
+          }
+          break;
+        case CH_CTRLO:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Collapse");
+            else
+              DocCollapse(TRUE,doc);
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Uncolapse");
+            else
+              DocCollapse(FALSE,doc);
+          }
+          break;
+        case CH_CTRLP:
+          if (doc->flags & (DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Toggle Super or Sub script");
+            else {
+              DocPrint(doc,"$SY,0$");
+              doc->flags&=~(DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE);
+            }
+          } else if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Toggle Subscript");
+            else {
+              DocPrint(doc,"$SY,3$");
+              doc->flags|=DOCF_SUBSCRIPT_MODE;
+            }
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Toggle Superscript");
+            else {
+              DocPrint(doc,"$SY,-3$");
+              doc->flags|=DOCF_SUPERSCRIPT_MODE;
+            }
+          }
+          break;
+        case CH_CTRLQ:
+          break;
+        case CH_CTRLR:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Sprite Graphic Resource");
+            else
+              if (!(doc->flags&DOCF_FORM) &&
+                    !(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
+                DocUnlock(doc);
+                if (doc_ce->type_u8==DOCT_SPRITE)
+                  EdSpriteEd(doc);
+                else
+                  EdSpriteIns(doc);
+                DocLock(doc);
+              }
+          }
+          break;
+        case CH_CTRLS:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Toggle AutoSave");
+            else
+              LBtc(&doc->flags,DOCf_AUTO_SAVE);
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Save");
+            else
+              DocWrite(doc);
+          }
+          break;
+        case CH_CTRLT:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Single Entry Toggle Plain Text");
+            else if (!(doc->flags&DOCF_FORM))
+              DocEntryToggle(doc);
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Toggle Plain Text Display");
+            else if (!(doc->flags&DOCF_FORM))
+              DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
+          }
+          break;
+        case CH_CTRLU:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Underline Off");
+            else
+              DocPrint(doc,"$UL,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Underline On");
+            else
+              DocPrint(doc,"$UL,1$");
+          }
+          break;
+        case CH_CTRLV:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Paste Clip");
+            else
+              ClipPaste(doc);
+          }
+          break;
+        case CH_CTRLW:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Word Wrap Off");
+            else
+              DocPrint(doc,"$WW,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Word Wrap On");
+            else
+              DocPrint(doc,"$WW,1$");
+          }
+          break;
+        case CH_CTRLX:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Cut To Clip");
+            else
+              ClipCut(doc);
+          }
+          break;
+        case CH_CTRLY:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Delete Line");
+            else
+              EdLineDel(doc);
+          }
+          break;
+        case CH_CTRLZ:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Inverted Text Off");
+            else
+              DocPrint(doc,"$IV,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Inverted Text On");
+            else
+              DocPrint(doc,"$IV,1$");
+          }
+          break;
+        case '0'...'9':
+          if (sc&SCF_CTRL) {
+            if (sc&SCF_KEY_DESC) {
+              if (sc&SCF_SHIFT)
+                KeyDescSet("Cmd /Word Definition");
+              else
+                KeyDescSet("Edit/Autocomplete Word");
+            } else {
+              if (AutoComplete(ON)) {
+                DocUnlock(doc);
+                if (sc&SCF_SHIFT)
+                  ACDDef(ch-'0',Fs);
+                else
+                  ACDFillin(ch-'0');
+                DocLock(doc);
+              }
+            }
+          }
+          break;
+        case '[':
+          if (sc&SCF_CTRL) {
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching brace");
+              else
+                EdFindPaired(doc,'}','{',FALSE);
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching bracket");
+              else
+                EdFindPaired(doc,']','[',FALSE);
+            }
+          }
+          break;
+        case ']':
+          if (sc&SCF_CTRL) {
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching brace");
+              else
+                EdFindPaired(doc,'{','}',TRUE);
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching bracket");
+              else
+                EdFindPaired(doc,'[',']',TRUE);
+            }
+          }
+          break;
+      }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  if (!(doc->flags&DOCF_DONT_SWAP_OUT))
+    Yield;
+}
+
+Bool KDDocPutKey(I64 ch,I64 scan_code)
+{
+  CDoc *doc;
+  if (doc=DocPut)
+    DocPutKey(doc,ch,scan_code);
+  return FALSE;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocPutS.HC.HTML b/public/Wb/Adam/DolDoc/DocPutS.HC.HTML new file mode 100755 index 0000000..42903a3 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocPutS.HC.HTML @@ -0,0 +1,367 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+
+CDocEntry *DocPutS(CDoc *doc,U8 *st)
+{//Don't use this.  Use DocPrint().
+//Does not handle partial Doc entries.
+  //Returns last newly created dollar-sign CDocEntry or NULL.
+  U8 *ptr=st,*ptr2,*st2,*ptr3,*ptr4,*src,
+        *char_bmp;
+  Bool unlock;
+  I64 ch,j;
+  CDocEntry *doc_e=NULL,*res=NULL,*doc_ce;
+  if (!st || !doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return NULL;
+  unlock=DocLock(doc);
+  if (doc->flags & DOCF_PLAIN_TEXT_TABS)
+    char_bmp=char_bmp_zero_cr_nl_cursor;
+  else if (doc->flags & DOCF_PLAIN_TEXT)
+    char_bmp=char_bmp_zero_tab_cr_nl_cursor;
+  else
+    char_bmp=char_bmp_zero_tab_cr_nl_cursor_dollar;
+  doc_ce=doc->cur_entry;
+  while (*ptr) {
+    ptr2=ptr;
+    do ch=*ptr++;
+    while (!Bt(char_bmp,ch) || ch==CH_CURSOR && doc->flags&DOCF_NO_CURSOR);
+    ptr--;
+    if (!ch) {
+      if (j=ptr-ptr2) {
+        doc_e=DocEntryNewBase(doc,
+              DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
+        if (doc->flags & DOCF_NO_CURSOR) {
+          src=MAlloc(j+1);
+          MemCpy(src,ptr2,j+1);
+          StrUtil(src,SUF_REM_CTRL_CHARS);
+          j=StrLen(src);
+        } else
+          src=ptr2;
+        doc_e->tag=MAlloc(j+1,doc->mem_task);
+        MemCpy(doc_e->tag,src,j+1);
+        doc_e->max_col=j;
+        DocInsEntry(doc,doc_e);
+        if (doc->flags & DOCF_NO_CURSOR)
+          Free(src);
+      }
+    } else {
+      if (j=ptr-ptr2) {
+        *ptr=0;
+        doc_e=DocEntryNewBase(doc,
+              DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
+        if (doc->flags & DOCF_NO_CURSOR) {
+          src=MAlloc(j+1);
+          MemCpy(src,ptr2,j+1);
+          ptr3=src;
+          ptr4=src;
+          while (*ptr3)
+            if (*ptr3!=CH_CURSOR)
+              *ptr4++=*ptr3++;
+            else
+              ptr3++;
+          *ptr4=0;
+          j=ptr4-src;
+        } else
+          src=ptr2;
+        doc_e->tag=MAlloc(j+1,doc->mem_task);
+        MemCpy(doc_e->tag,src,j+1);
+        doc_e->max_col=j;
+        DocInsEntry(doc,doc_e);
+        if (doc->flags & DOCF_NO_CURSOR)
+          Free(src);
+        *ptr=ch;
+      }
+      switch (ch) {
+        case CH_CURSOR:
+          doc_e=DocEntryNewBase(doc,
+                DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
+          DocInsEntry(doc,doc_e);
+          ptr++;
+          break;
+        case '\t':
+          doc_e=DocEntryNewBase(doc,
+                DOCT_TAB|doc->settings_head.dft_text_attr<<8);
+          DocInsEntry(doc,doc_e);
+          ptr++;
+          break;
+        case '$':
+          ptr++; //skip first dollar
+          ptr2=ptr;
+          while (*ptr && *ptr!='$')
+            ptr++;
+          if (*ptr) {
+            *ptr=0; //zero second dollar
+            if (ptr-1==ptr2 && *ptr2==CH_CURSOR) {
+              doc_e=DocEntryNewBase(doc,
+                    DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
+              DocInsEntry(doc,doc_e);
+              ptr2++;
+            }
+            if (ptr==ptr2) {
+              doc_e=DocEntryNewBase(doc,
+                    DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
+              doc_e->max_col=1;
+              if (doc->flags & DOCF_DBL_DOLLARS)
+                doc_e->tag=StrNew("$$",doc->mem_task);
+              else
+                doc_e->tag=StrNew("$",doc->mem_task);
+              DocInsEntry(doc,doc_e);
+            } else {
+              st2=MAlloc(ptr-ptr2+1);
+              ptr3=ptr2;
+              ptr4=st2;
+              while (ch=*ptr3++) {
+                if (ch==CH_CURSOR) {
+                  doc_e=DocEntryNewBase(doc,
+                        DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
+                  DocInsEntry(doc,doc_e);
+                } else
+                  *ptr4++=ch;
+              }
+              *ptr4=0;
+              if (doc_e=PrsDollarCmd(doc,st2)) {
+                res=doc_e;
+                DocInsEntry(doc,doc_e);
+              }
+              Free(st2);
+            }
+            *ptr++='$';
+          }
+          break;
+        default:
+          doc_e=DocEntryNewBase(doc,
+                DOCT_NEW_LINE|doc->settings_head.dft_text_attr<<8);
+          DocInsEntry(doc,doc_e);
+          if (ch=='\r')
+            while (*ptr=='\r')
+              ptr++;
+          if (*ptr=='\n')
+            ptr++;
+          while (*ptr=='\r')
+            ptr++;
+      }
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...)
+{//You must not print partial doc cmds.
+//Returns last newly created dollar-sign CDocEntry or NULL.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CDocEntry *res=DocPutS(doc,buf);
+  Free(buf);
+  return res;
+}
+
+public U0 DocPrintPartial(CDoc *doc=NULL,U8 *fmt,...)
+{//Lets you print half a doc cmd, if you like.
+  U8 *buf,*st,*src,*dst,*ptr,*ptr2;
+  Bool unlock;
+  CDocEntry *doc_ce,*doc_ne;
+  I64 ch,i,j;
+  if (!doc && !(doc=DocPut))
+    return;
+  buf=StrPrintJoin(NULL,fmt,argc,argv);
+  ptr=buf;
+  if (doc->user_put_s && (*doc->user_put_s)(doc,doc->user_put_data,buf)) {
+    Free(buf);
+    return;
+  }
+  unlock=DocLock(doc);
+  if (doc->cur_entry->type_u8==DOCT_DATA)
+    while (ch=*ptr++)
+      DocPutKey(doc,ch,0);
+  else
+    while (ch=*ptr) {
+      if (!Bt(char_bmp_safe_dollar,ch) ||
+            doc->flags & (DOCF_OVERSTRIKE|DOCF_IN_DOLLAR)) {
+        DocPutKey(doc,ch,0);
+        ptr++;
+      } else {
+        ptr2=ptr++;
+        while (TRUE) {
+          ch=*ptr++;
+          if (!Bt(char_bmp_safe_dollar,ch))
+            break;
+        }
+        ptr--;
+        *ptr=0;
+        doc_ce=doc->cur_entry;
+        j=ptr-ptr2;
+        if (IsEditableText(doc_ce)) {
+          dst=st=MAlloc(doc_ce->max_col+j+1,doc->mem_task);
+          src=doc_ce->tag;
+          i=doc->cur_col;
+          doc->cur_col+=j;
+          doc_ce->max_col+=j;
+          while (i-->0)
+            *dst++=*src++;
+          while (j-->0)
+            *dst++=*ptr2++;
+          while (*dst++=*src++);
+          Free(doc_ce->tag);
+          doc_ce->tag=st;
+        } else {
+          doc_ne=DocEntryNewTag(doc,doc_ce,ptr2);
+          doc_ne->type=DOCT_TEXT|doc->settings_head.dft_text_attr<<8;
+          doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
+          QueIns(doc_ne,doc_ce->last);
+          doc->cur_entry=doc_ne;
+          doc->cur_col=StrLen(ptr2);
+        }
+        *ptr=ch;
+        DocRemSoftNewLines(doc,doc->cur_entry);
+      }
+    }
+  if (unlock)
+    DocUnlock(doc);
+  if (!(doc->flags&DOCF_DONT_SWAP_OUT))
+    Yield;
+  Free(buf);
+}
+
+Bool KDDocPutS(U8 *st)
+{
+  CDoc *doc;
+  if (doc=DocPut)
+    DocPrintPartial(doc,"%s",st);
+  return FALSE;
+}
+
+public U0 DocPrintAtomic(CDoc *doc=NULL,U8 *fmt,...)
+{//Prints multiple whole cmds all-at-once. Might need this when printing trees.
+  U8 *buf;
+  Bool unlock;
+  I64 old_flags;
+  if (!doc && !(doc=DocPut))
+    return;
+  buf=StrPrintJoin(NULL,fmt,argc,argv);
+  unlock=DocLock(doc);
+  old_flags=doc->flags;
+  doc->flags|=DOCF_NO_CURSOR;
+  DocPrint(doc,"%s",buf);
+  DocRecalc(doc);
+  doc->flags=old_flags;
+  if (unlock)
+    DocUnlock(doc);
+  Free(buf);
+}
+
+U0 DocDump(CDoc *doc,I64 uS_delay=0)
+{
+  U8 *st;
+  CDocEntry *doc_e,*doc_e2;
+  Bool unlock=DocLock(doc);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    st=DocScanLine(doc,doc_e,NULL,&doc_e2);
+    "%s",st;
+    Free(st);
+    doc_e=doc_e2;
+    if (doc_e->type_u8==DOCT_NEW_LINE) {
+      '\n';
+      Busy(uS_delay);
+      doc_e=doc_e->next;
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public CDocEntry *DocPutLine(CDoc *doc=NULL,CDocEntry *doc_e)
+{//Send line from other doc to StdOut DocPut.
+  I64 ch;
+  U8 *ptr,*ptr2;
+  Bool unlock;
+  if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return NULL;
+  unlock=DocLock(doc);
+  while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
+    if (doc_e->de_flags&DOCEF_TAG) {
+      ptr=doc_e->tag;
+      do {
+        ptr2=ptr;
+        while (ch=*ptr)
+          if (ch=='$')
+            break;
+          else
+            ptr++;
+        *ptr=0;
+        "%s",ptr2;
+        *ptr=ch;
+        if (ch=='$') {
+          "$$";
+          ptr++;
+        }
+      } while (ch);
+    } else if (doc_e->type_u8==DOCT_TAB)
+      '\t';
+    doc_e=doc_e->next;
+  }
+  '\n';
+  if (doc_e!=doc)
+    doc_e=doc_e->next;
+  if (unlock)
+    DocUnlock(doc);
+  return doc_e;
+}
+
+#help_index "Debugging/Dump;DolDoc/Cmd Line (Typically);"\
+        "Cmd Line (Typically);DolDoc/Output;StdOut/DolDoc"
+public U0 DocDm(U8 *buf,I64 cnt=0x80)
+{//Dump live chunk of mem showing addresses. Can be edited.
+  CDocEntry *doc_e;
+  CDoc *doc=DocPut;
+  Bool unlock=DocLock(doc);
+  doc_e=DocPrint(doc,"$HX-Z,%d,16$",cnt);
+  doc_e->data=buf;
+  doc->cur_entry=doc_e->next;
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocD(U8 *buf,I64 cnt=0x80)
+{//Dump live chunk of mem showing offsets. Can be edited.
+  CDocEntry *doc_e;
+  CDoc *doc=DocPut;
+  Bool unlock=DocLock(doc);
+  doc_e=DocPrint(doc,"$HX,%d,16$",cnt);
+  doc_e->data=buf;
+  doc->cur_entry=doc_e->next;
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocRecalc.HC.HTML b/public/Wb/Adam/DolDoc/DocRecalc.HC.HTML new file mode 100755 index 0000000..8208557 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocRecalc.HC.HTML @@ -0,0 +1,1355 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+I64 DocWordWrapDel(CDoc *doc,CDocEntry *doc_e,
+        Bool full_refresh,Bool same_win,I64 left_margin,I64 right_margin,
+        CDocEntry **_best_doc_e,I64 *_best_col)
+{
+  CDocEntry *doc_e2;
+  U8 *ptr;
+  I64 j,k;
+  if (doc_e->de_flags&DOCEF_TAG && doc_e->tag)
+    k=StrLen(doc_e->tag);
+  else
+    k=0;
+  if (full_refresh)
+    while (TRUE) {
+      doc_e2=doc_e->next;
+      if (doc_e2->type_u8==DOCT_SOFT_NEW_LINE && !same_win) {
+        if (doc->cur_entry==doc_e2) {
+          doc->cur_entry=doc_e2->next;
+          doc->cur_col=doc->cur_entry->min_col;
+        }
+        if (*_best_doc_e==doc_e2) {
+          *_best_doc_e=doc_e2->next;
+          *_best_col=0;
+        }
+        DocEntryDel(doc,doc_e2);
+      } else if (IsEditableText(doc_e) &&
+            doc_e->de_flags==doc_e2->de_flags && doc_e->type==doc_e2->type) {
+        j=StrLen(doc_e2->tag);
+        ptr=MAlloc(k+j+1,doc->mem_task);
+        MemCpy(ptr,doc_e->tag,k);
+        MemCpy(ptr+k,doc_e2->tag,j+1);
+        Free(doc_e->tag);
+        doc_e->tag=ptr;
+        if (doc->cur_entry==doc_e2) {
+          doc->cur_entry=doc_e;
+          doc->cur_col+=k;
+        }
+        if (*_best_doc_e==doc_e2) {
+          *_best_doc_e=doc_e;
+          *_best_col=0;
+        }
+        DocEntryDel(doc,doc_e2);
+        k+=j;
+        if (k>(right_margin-left_margin+1)<<1)
+          break;
+      } else
+        break;
+    }
+  if (doc_e->de_flags & DOCEF_SCROLLING_X)
+    k=doc_e->scroll_len;
+  return k;
+}
+
+U0 DocRecalcXY(CDoc *doc,CDocEntry *doc_e,
+        I64 k,I64 left,I64 width,I64 height,I64 left_margin,I64 right_margin,
+        I64 x0,I64 y0,I64 *_x,I64 *_y)
+{
+  I64 i,x=*_x,y=*_y;
+  if (doc_e->de_flags & DOCEF_MARGIN_REL_X) {
+    if (doc_e->de_flags & DOCEF_LEFT_X)
+      x=left_margin-left;
+    else if (doc_e->de_flags & DOCEF_RIGHT_X)
+      x=right_margin-(k-1)-left;
+    else if (doc_e->de_flags & DOCEF_CENTER_X)
+      x=(right_margin+left_margin)>>1-k>>1-left;
+  } else {
+    if (doc_e->de_flags & DOCEF_LEFT_X)
+      x=x0;
+    else if (doc_e->de_flags & DOCEF_RIGHT_X)
+      x=width+x0-k;
+    else if (doc_e->de_flags & DOCEF_CENTER_X)
+      x=(width+x0-k)>>1;
+  }
+  i=y;
+  if (doc_e->de_flags & DOCEF_PAGE_REL_Y) {
+    doc->flags|=DOCF_BWD_MOVEMENT;
+    if (doc_e->de_flags & DOCEF_TOP_Y)
+      y-=doc_e->page_line_num;
+    else if (doc_e->de_flags & DOCEF_BOTTOM_Y)
+      y+=doc_e->settings.page_len-doc_e->page_line_num;
+    else if (doc_e->de_flags & DOCEF_CENTER_Y)
+      y+=doc_e->settings.page_len>>1-doc_e->page_line_num;
+  } else {
+    doc->flags|=DOCF_BWD_MOVEMENT;
+    if (doc_e->de_flags & DOCEF_TOP_Y)
+      y=y0;
+    else if (doc_e->de_flags & DOCEF_BOTTOM_Y)
+      y=height-1+y0;
+    else if (doc_e->de_flags & DOCEF_CENTER_Y)
+      y=height>>1+y0;
+  }
+  if (y!=i) {
+    doc->page_line_num+=y-i;
+    if (doc->page_line_num<0)
+      doc->page_line_num=doc_e->settings.page_len+
+            doc->page_line_num%doc_e->settings.page_len;
+    else
+      doc->page_line_num=doc->page_line_num%doc_e->settings.page_len;
+    if (doc_e->settings.header!=DOC_DFT &&
+          doc->page_line_num<doc_e->settings.header) {
+      y+=doc_e->settings.header-doc->page_line_num;
+      doc->page_line_num=doc_e->settings.header;
+    }
+    if (doc_e->settings.footer==DOC_DFT) {
+      if (doc->page_line_num>=doc_e->settings.page_len) {
+        if (doc_e->settings.header==DOC_DFT)
+          doc->page_line_num=0;
+        else {
+          doc->page_line_num=doc_e->settings.header;
+          y+=doc_e->settings.header;
+        }
+      }
+    } else {
+      if (doc->page_line_num>=
+            doc_e->settings.page_len-doc_e->settings.footer) {
+        y+=doc_e->settings.footer;
+        if (doc_e->settings.header==DOC_DFT)
+          doc->page_line_num=0;
+        else {
+          doc->page_line_num=doc_e->settings.header;
+          y+=doc_e->settings.header;
+        }
+      }
+    }
+  }
+  *_x=x;
+  *_y=y;
+}
+
+CDocEntry *DocSplitTag(CDoc *doc,CDocEntry *doc_e,I64 i,I64 x,I64 y,I64 type_u8)
+{//Split tag at i, insert DOCT_SOFT_NEW_LINE, DOCT_MARKER or DOCT_CURSOR
+  U8 *ptr;
+  CDocEntry *doc_e2;
+  if (doc_e->type_u8==DOCT_TEXT && i) {
+    if (i<StrLen(doc_e->tag)) {
+      doc_e2=MAllocIdent(doc_e,doc->mem_task);
+      doc_e2->tag=StrNew(doc_e->tag+i,doc->mem_task);
+      doc_e2->de_flags=doc_e->de_flags&~DOCEG_HAS_ALLOC|DOCEF_TAG;
+      QueIns(doc_e2,doc_e);
+      if (doc->cur_entry==doc_e && doc->cur_col>=i) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc->cur_col-i;
+      }
+      doc_e->tag[i]=0;
+      ptr=StrNew(doc_e->tag,doc->mem_task);
+      Free(doc_e->tag);
+      doc_e->tag=ptr;
+    }
+  } else
+    doc_e=doc_e->last;
+  doc_e2=DocEntryNewBase(doc,type_u8|doc_e->type & 0xFFFFFF00,
+        doc_e->de_flags&~DOCEG_HAS_ARG,x,y,doc_e->page_line_num);
+  MemCpy(&doc_e2->settings,&doc_e->settings,sizeof(CDocSettings));
+  QueIns(doc_e2,doc_e);
+  return doc_e2;
+}
+
+CDocEntry *DocWordWrapAdd(CDoc *doc,CDocEntry *doc_e,
+        I64 *_k,I64 left,I64 right_margin,I64 x,I64 y)
+{
+  CDocEntry *doc_e2;
+  I64 j,i=right_margin+1-(x+left),  //Space left on line
+        ii=x+1-doc_e->settings.left_margin;
+  if (IsEditableText(doc_e)) {
+    if (doc->cur_entry==doc_e->next) {
+      if (doc->cur_col==doc_e->next->min_col)
+        i--;
+    } else {
+      if (doc->cur_entry==doc_e && doc->cur_col==i)
+        i--;
+    }
+    if (*_k>i) {
+      for (j=i;j>8-ii && j>=0;j--)
+        if (doc_e->tag[j]==CH_SPACE || doc_e->tag[j]==CH_SHIFT_SPACE) {
+          i=j+1;
+          break;
+        }
+      if (0<i<*_k) {
+        DocSplitTag(doc,doc_e,i,x,y,DOCT_SOFT_NEW_LINE);
+        *_k=StrLen(doc_e->tag);
+        return NULL;
+      }
+    }
+    if (*_k==i)
+      return NULL;
+  }
+  if (*_k>=i) {
+    doc_e2=doc_e->last;
+    if (doc_e2->type_u8!=DOCT_SOFT_NEW_LINE &&
+          doc_e2->type_u8!=DOCT_NEW_LINE &&
+          doc_e2->type_u8!=DOCT_CURSOR_MOVEMENT) {
+      doc_e2=DocEntryNewBase(doc,DOCT_SOFT_NEW_LINE|doc_e->type&0xFFFFFF00,
+            DOCEF_WORD_WRAP|doc_e->de_flags&(DOCEF_HIGHLIGHT|DOCG_BL_IV_UL|
+            DOCEF_SKIP|DOCEF_FILTER_SKIP),x,y,doc_e->last->page_line_num);
+      MemCpy(&doc_e2->settings,&doc_e->settings,sizeof(CDocSettings));
+      QueIns(doc_e2,doc_e->last);
+      return doc_e2;
+    }
+  }
+  return NULL;
+}
+
+I64 DocTmpAttr(CDoc *doc,CDocEntry *doc_e,I64 cur_u8_attr)
+{
+  I64 tmp_u32_attr;
+  doc_e->de_flags=doc->flags& (DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT) |
+        doc_e->de_flags&~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT);
+  tmp_u32_attr=(cur_u8_attr&0xF0)<<8|
+        doc->flags&DOCG_BL_IV_UL|(doc_e->settings.shifted_x&0x1F)<<16|
+        (doc_e->settings.shifted_y&0x1F)<<21;
+  if (doc_e->de_flags & DOCEF_HAS_BIN && *doc_e->tag=='<')
+    tmp_u32_attr.u8[1]|=DOC_COLOR_BIN;
+  else
+    switch (doc_e->type_u8) {
+      case DOCT_SPRITE:
+        if (doc_e->de_flags & DOCEF_LEFT_EXP)
+          tmp_u32_attr.u8[1]|=cur_u8_attr&15;
+        else if (doc_e->de_flags & DOCEF_LINK)
+          tmp_u32_attr.u8[1]|=DOC_COLOR_LINK;
+        else if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+          tmp_u32_attr.u8[1]|=DOC_COLOR_MACRO;
+        else if (doc_e->de_flags & (DOCEF_TREE|DOCEF_LST))
+          tmp_u32_attr.u8[1]|=DOC_COLOR_TREE;
+        else
+          tmp_u32_attr.u8[1]|=DOC_COLOR_BIN;
+        break;
+      case DOCT_HTML_CODE:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_BIN;
+        break;
+      case DOCT_LINK:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_LINK;
+        break;
+      case DOCT_MACRO:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_MACRO;
+        break;
+      case DOCT_ANCHOR:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_ANCHOR;
+        break;
+      case DOCT_TREE:
+      case DOCT_LST:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_TREE;
+        break;
+      default:
+        tmp_u32_attr.u8[1]|=cur_u8_attr&15;
+    }
+  doc_e->type.u8[1]=tmp_u32_attr.u8[1];
+  tmp_u32_attr|=doc_e->type&0xFFFF0000;
+  if (doc_e==doc->cur_entry && !(doc->flags&DOCF_DONT_HIGHLIGHT_CURSOR) &&
+        doc_e->type_u8!=DOCT_TEXT)
+    tmp_u32_attr^=0xFF00;
+  doc_e->settings.final_u32_attr=tmp_u32_attr;
+  return tmp_u32_attr;
+}
+
+public Bool DocRecalc(CDoc *doc,I64 recalc_flags=RECALCt_NORMAL)
+{//Recalc and fmt.  Also used by WinMgr to draw on scrn.
+  I64 i,ii,j,k,x,x0,y,y0,D,d2,col,col2,best_col=0,best_d=I64_MAX,xx,yy,zz,
+        num_entries=0,i_jif,cur_u8_attr,tmp_u32_attr,
+        cursor_y=I64_MIN,left_margin,right_margin,y_plot_top,y_plot_bottom,
+        top,left,bottom,right,width,height,scroll_x,scroll_y,pix_top,pix_left;
+  CDocEntry reg *doc_e,reg *doc_e2,*best_doc_e,*next_clear_found=NULL,
+        *added_cursor=NULL;
+  CDocBin *tmpb;
+  CDocSettings *s;
+  Bool del_doc_e,skipped_update,tree_collapsed,same_win,more=FALSE,
+        find_cursor=FALSE,blink_flag,full_refresh=TRUE,unlock,clear_holds;
+  CTask *win_task,*mem_task;
+  CDC *dc;
+  U8 *bptr,*ptr,buf[STR_LEN],ch;
+  U32 *u32_ptr,*hl;
+  I32 *depth_buf=NULL;
+  F64 cur_time=tS;
+  CWinScroll *vss,*hss;
+  CHashDefineStr *tmph;
+
+  if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return FALSE;
+
+    //WinMgr updates all wins (30000.0/1001), 33.33333mS
+  if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN && doc->owning_task!=Fs) {
+    i_jif=cnts.jiffies+JIFFY_FREQ/250; //4 ms
+    while (Bt(&doc->locked_flags,DOClf_LOCKED)) {
+      if (cnts.jiffies>=i_jif)
+        return FALSE; //Bail-out if doc locked.
+      Yield;
+    }
+  }
+
+  unlock=DocLock(doc);
+  if (doc->doc_signature!=DOC_SIGNATURE_VAL) {
+    DocUnlock(doc);
+    return FALSE;
+  }
+
+  win_task=doc->win_task;
+  mem_task=doc->mem_task;
+  blink_flag=Blink;
+  dc=NULL;
+  switch [recalc_flags&RECALCG_MASK] {
+    case RECALCt_FIND_CURSOR:
+      find_cursor=TRUE;
+      if (win_task)
+        dc=DCAlias(gr.dc2,win_task); //Necessary for sprites
+      break;
+    case RECALCt_TO_SCRN:
+      if (doc->updates_cnt++%(ToI64(winmgr.fps/10)+1) &&
+            !Bt(&doc->flags,DOCf_DO_FULL_REFRESH) &&
+            !(doc->flags&DOCF_BWD_MOVEMENT))
+        full_refresh=FALSE;
+      if (win_task)
+        dc=DCAlias(gr.dc2,win_task);
+      break;
+  }
+
+  PUSHFD
+  CLI
+  left  =win_task->win_left;
+  right =win_task->win_right;
+  width =win_task->win_width;
+  scroll_x=win_task->scroll_x;
+  scroll_y=win_task->scroll_y;
+  top   =win_task->win_top;
+  bottom=win_task->win_bottom;
+  height=win_task->win_height;
+  pix_left  =win_task->pix_left;
+  pix_top   =win_task->pix_top;
+  left_margin=left;
+  right_margin=right;
+  POPFD
+  if (doc->flags&DOCF_BORDER_DOC) {
+    scroll_x=0;
+    scroll_y=0;
+  }
+  best_doc_e=doc->cur_entry;
+
+  if (!(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)) &&
+        FilesFindMatch(doc->filename.name,FILEMASK_SRC))
+    doc->flags|=DOCF_HIGHLIGHT;
+  else
+    doc->flags&=~DOCF_HIGHLIGHT;
+
+  x=y=0;
+  doc->page_line_num=0;
+  if (full_refresh && !find_cursor) {
+    doc->x=x;
+    doc->y=y;
+  }
+
+  hss=&win_task->horz_scroll;
+  vss=&win_task->vert_scroll;
+  if (doc->flags&DOCF_BORDER_DOC) {
+    doc->top_line_num=0;
+    doc->line_start_col=0;
+    recalc_flags&=~RECALCF_HAS_CURSOR;
+    if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN)
+      doc->settings_head.cur_text_attr=
+            doc->settings_head.dft_text_attr=win_task->border_attr;
+  } else {
+    if (recalc_flags&RECALCF_HAS_CURSOR && full_refresh) {
+      if (Bt(&hss->flags,WSSf_SET_TO_POS)||Bt(&vss->flags,WSSf_SET_TO_POS)) {
+        if (!(doc->flags&DOCF_NO_SCROLL_BARS)) {
+          if (Bt(&hss->flags,WSSf_SET_TO_POS)) {
+            doc->line_start_col=hss->pos;
+            LBtr(&hss->flags,WSSf_SET_TO_POS);
+          }
+          if (Bt(&vss->flags,WSSf_SET_TO_POS)) {
+            doc->top_line_num=vss->pos;
+            LBtr(&vss->flags,WSSf_SET_TO_POS);
+          }
+        }
+        doc->x=doc->line_start_col+width/2;
+        doc->y=doc->top_line_num+height/2;
+        find_cursor=TRUE;
+      }
+    }
+    if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN)
+      doc->settings_head.cur_text_attr=
+            doc->settings_head.dft_text_attr=win_task->text_attr;
+  }
+  x0=doc->line_start_col;
+  y0=doc->top_line_num;
+  same_win=top   ==doc->old_win_top &&
+        bottom==doc->old_win_bottom &&
+        left  ==doc->old_win_left &&
+        right ==doc->old_win_right &&
+        doc->cur_entry==doc->old_cur_entry &&
+        doc->cur_col==doc->old_cur_col;
+  if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN) {
+    y_plot_top=y0-scroll_y/FONT_HEIGHT;
+    y_plot_bottom=y0+height-1-scroll_y/FONT_HEIGHT;
+    if (!(doc->flags&DOCF_BORDER_DOC) &&
+          !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+      DocBorderLstDraw(doc);
+  }
+
+  if (doc->cur_col<=doc->cur_entry->min_col)
+    doc->cur_col=doc->cur_entry->min_col;
+  doc_e=doc->head.next;
+  doc_e->de_flags&=~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT);
+  if (doc_e==doc->head.next)
+    s=&doc->settings_head;
+  else
+    s=&doc_e->last->settings;
+  doc->flags=doc_e->de_flags& (DOCG_BL_IV_UL|DOCEF_WORD_WRAP) |
+        doc->flags&~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP);
+  cur_u8_attr=s->cur_text_attr;
+  if (doc_e==doc->head.next) {
+    doc->flags&=~DOCF_BWD_MOVEMENT;
+    if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN && full_refresh)
+      doc->flags&=~DOCF_HAS_SONG;
+  } else
+    doc->flags=doc_e->de_flags& DOCEF_HIGHLIGHT |
+          doc->flags&~DOCEF_HIGHLIGHT;
+
+  if (doc->head.next==doc) {
+    best_doc_e=doc;
+    best_col=0;
+    doc->cur_entry=doc;
+    doc->cur_col=0;
+    doc_e=doc;
+  }
+  skipped_update= doc_e==doc && doc->head.next!=doc;
+
+  if (full_refresh) {
+    doc->min_x=I32_MAX; doc->min_y=I32_MAX;
+    doc->max_x=I32_MIN; doc->max_y=I32_MIN;
+  }
+  while (doc_e!=doc) {
+    while (TRUE) {
+      del_doc_e=FALSE;
+      if (doc_e->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
+        doc_e2=doc_e;
+        goto rc_skip;
+      }
+      MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
+      s=&doc_e->settings;
+      if (doc_e->de_flags & (DOCEF_TAG_CB|DOCEF_DEFINE) &&
+            !(doc_e->de_flags & DOCEF_LST)) {
+        Free(doc_e->tag);
+        if (doc_e->de_flags & DOCEF_TAG_CB) {
+          if (doc_e->tag_cb)
+            doc_e->tag=(*doc_e->tag_cb)(doc,doc_e,mem_task);
+          else
+            doc_e->tag=StrNew("",mem_task);
+        } else {
+          if (tmph=HashFind(doc_e->define_str,
+                win_task->hash_table,HTT_DEFINE_STR))
+            doc_e->tag=StrNew(tmph->data,mem_task);
+          else
+            doc_e->tag=CAlloc(1,mem_task);
+        }
+        doc_e->max_col=StrLen(doc_e->tag);
+        if (doc->cur_entry==doc_e && doc->cur_col>=doc_e->max_col) {
+          if (doc_e->max_col)
+            doc->cur_col=doc_e->max_col-1;
+          else
+            doc->cur_col=0;
+        }
+      }
+      k=DocWordWrapDel(doc,doc_e,full_refresh,same_win,
+            left_margin,right_margin,&best_doc_e,&best_col);
+      if (doc_e->de_flags & (DOCEF_LEFT_X|DOCEF_RIGHT_X|DOCEF_CENTER_X|
+            DOCEF_TOP_Y|DOCEF_BOTTOM_Y|DOCEF_CENTER_Y))
+        DocRecalcXY(doc,doc_e,k,
+              left,width,height,left_margin,right_margin,x0,y0,&x,&y);
+      if (full_refresh && k>0 && doc->flags & DOCF_WORD_WRAP &&
+            (doc_e2=DocWordWrapAdd(doc,doc_e,&k,left,right_margin,x,y)))
+        doc_e=doc_e2;
+      else
+        break;
+    }
+
+    if (full_refresh) {
+      doc_e->x=x;
+      doc_e->y=y;
+      doc_e->page_line_num=doc->page_line_num;
+      if (x<doc->min_x) doc->min_x=x;
+      if (y<doc->min_y) doc->min_y=y;
+      if (find_cursor) {
+        D=DocCharDist(doc,x,y);
+        col=0;
+      }
+    }
+    col2=0;
+
+    tmp_u32_attr=DocTmpAttr(doc,doc_e,cur_u8_attr);
+    if (doc_e==doc->cur_entry) {
+      cursor_y=doc_e->y;
+      if (recalc_flags&RECALCF_ADD_CURSOR && !added_cursor) {
+        if (doc_e->type_u8==DOCT_TEXT && 0<doc->cur_col<k &&
+              !(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
+              DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
+              !(doc_e->type&DOCG_BL_IV_UL)) {
+          added_cursor=DocSplitTag(doc,doc_e,doc->cur_col,x,y,DOCT_CURSOR);
+          k=StrLen(doc_e->tag);
+        } else {
+          added_cursor=doc_e2=DocEntryNewBase(doc,
+                DOCT_CURSOR|doc_e->type&0xFFFFFF00,
+                doc_e->de_flags&~DOCEG_HAS_ARG,x,y,doc->page_line_num);
+          MemCpy(&doc_e2->settings,&doc_e->settings,sizeof(CDocSettings));
+          if (doc_e->type_u8==DOCT_TEXT && doc->cur_col>=k)
+            QueIns(doc_e2,doc_e);
+          else
+            QueInsRev(doc_e2,doc_e);
+        }
+      }
+    }
+
+    if (doc_e->de_flags & DOCEF_REFRESH_DATA &&
+          (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX ||
+          doc_e->de_flags & DOCEF_LST)) {
+      DocDataFmt(doc,doc_e);
+      k=StrLen(doc_e->tag);
+    }
+    if (doc_e->de_flags&DOCEF_TAG) {
+      ptr=doc_e->tag;
+      if (doc_e->de_flags & DOCEF_TREE) {
+        if (k>=2) {
+          if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+            *ptr++='+';
+          else
+            *ptr++='-';
+          *ptr++=']';
+          ptr=doc_e->tag;
+        }
+      } else if (doc_e->de_flags & DOCEF_HAS_BIN) {
+        if (*ptr=='<' && full_refresh && '0'<=ptr[1]<='9') {
+          ptr=MStrPrint("<%d>",doc_e->bin_num);
+          Free(doc_e->tag);
+          doc_e->tag=StrNew(ptr,mem_task);
+          Free(ptr);
+          ptr=doc_e->tag;
+          k=StrLen(ptr);
+        }
+      } else if (doc_e->type_u8==DOCT_CHECK_BOX) {
+        if (k>=3) {
+          *ptr++='[';
+          if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+            *ptr++='X';
+          else
+            *ptr++=CH_SPACE;
+          *ptr++=']';
+          ptr=doc_e->tag;
+        }
+      }
+      if (doc_e->de_flags & DOCEF_SCROLLING_X) {
+        j=StrLen(doc_e->tag);
+        if (j && doc_e->scroll_len) {
+          i_jif=ToI64(cur_time*FONT_WIDTH*DOC_SCROLL_SPEED)%(j*FONT_WIDTH);
+          tmp_u32_attr=tmp_u32_attr & 0xFFE0FF00|
+                (FONT_WIDTH-1-i_jif&(FONT_WIDTH-1))<<16;
+#assert FONT_WIDTH==8
+          i_jif>>=3;
+          for (k=0;k<doc_e->scroll_len;k++) {
+            ch=ptr[(i_jif+k)%j];
+            if (!Bt(char_bmp_displayable,ch)) ch='.';
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+              if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                    !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+              else
+                TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+            }
+            x++;
+          }
+        }
+        if (find_cursor)  {
+          D=DocCharDist(doc,doc_e->x,doc_e->y);
+          col=doc_e->min_col;
+        }
+        col2=doc_e->scroll_len; //TODO This is flawed
+      } else {
+        if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+              !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER)) {
+          while (ch=*ptr++) {
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW))
+              TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+            else
+              if (find_cursor) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D) {
+                  D=d2;
+                  col=col2;
+                }
+              }
+            col2++;
+            x++;
+          }
+        } else {
+          if (doc_e->type_u8==DOCT_TEXT && doc_e->de_flags&DOCEF_HIGHLIGHT)
+            hl=DocHighlight(doc_e,ptr,k,tmp_u32_attr);
+          else
+            hl=NULL;
+          if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+//Technically we should do this for scrolling_x, too.
+            if (y>y_plot_bottom)
+              more=TRUE;
+            else if (y>=y_plot_top) {
+              if (hl)
+                TextLenAttrStr(win_task,x-x0,y-y0,k,hl);
+              else
+                TextLenStr(win_task,x-x0,y-y0,k,tmp_u32_attr,ptr);
+            }
+            col2+=k;
+            x+=k;
+          } else {
+            if (find_cursor) {
+              while (k--) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D) {
+                  D=d2;
+                  col=col2;
+                }
+                col2++;
+                x++;
+              }
+            } else {
+              col2+=k;
+              x+=k;
+            }
+          }
+          Free(hl);
+        }
+      }
+    }
+    switch [doc_e->type_u8] {
+      case DOCT_TEXT:
+        if (!col2 && !(doc_e->de_flags
+              &(DOCEF_TREE|DOCEF_LST|DOCEF_TAG_CB|DOCEF_DEFINE|
+              DOCEF_AUX_STR|DOCEF_HTML_LINK|DOCEF_BIN_PTR_LINK)))
+          del_doc_e=TRUE;
+        break;
+      case DOCT_HEX_ED:
+        if (doc_e->de_flags&DOCEF_DEREF_DATA &&
+              !(doc_e->de_flags&DOCEF_REMALLOC_DATA))
+          bptr=doc_e->data;
+        else
+          bptr=&doc_e->data;
+        k=doc_e->hex_ed_width; //columns
+        for (i=0;i<doc_e->len;i+=k) {
+          if (doc_e->de_flags & DOCEF_ZERO_BASED)
+            StrPrint(buf,"%08tX ",i);
+          else
+            StrPrint(buf,"%08tX ",bptr);
+          ptr=buf;
+          while (ch=*ptr++) {
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+              if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                    !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+              else
+                TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+            }
+            if (find_cursor) {
+              d2=DocCharDist(doc,x,y);
+              if (d2<D) {
+                D=d2;
+                col=i*3;
+              }
+            }
+            x++;
+          }
+          if (i+k>doc_e->len) k=doc_e->len-i;
+          for (j=0;j<k;j++) {
+            StrPrint(buf,"%02tX",*bptr++);
+            ptr=buf;
+            while (ch=*ptr++) {
+              if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                    !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+                if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                      !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                  TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+                else
+                  TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+              }
+              if (find_cursor) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D) {
+                  D=d2;
+                  col=col2;
+                }
+              }
+              col2++;
+              x++;
+            }
+            x++;
+          }
+          bptr-=j;
+          x+=(doc_e->hex_ed_width-k)*3;
+          for (j=0;j<k;j++) {
+            ch=*bptr++;
+            if (!Bt(char_bmp_displayable,ch)) ch='.';
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+              if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                    !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+              else
+                TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+            }
+            if (find_cursor) {
+              d2=DocCharDist(doc,x,y);
+              if (d2<D) {
+                D=d2;
+                col=col2;
+              }
+            }
+            col2++;
+            x++;
+          }
+          y++;
+          x-=doc_e->hex_ed_width*3+k+9;
+        }
+        break;
+      case DOCT_NEW_LINE:
+      case DOCT_SOFT_NEW_LINE:
+        if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+              !(doc_e->de_flags&DOCEF_DONT_DRAW)&&
+              y_plot_top<=y<=y_plot_bottom)
+          TextLenAttr(win_task,x-x0,y-y0,width-(x-x0),cur_u8_attr<<8);
+        if (doc_e->de_flags&DOCEF_HIGHLIGHT && s->state==DOCSS_CPP_Z_COMMENT)
+          s->state=DOCSS_NORMAL;
+        y++;
+        doc->page_line_num++;
+rc_start_of_line:
+        if (s->left_margin==DOC_DFT)
+          x=s->indent;
+        else
+          x=s->indent+s->left_margin;
+rc_adjust_xy:
+        i=s->indent+s->left_margin;
+        if (x<i)
+          x=i;
+        if (doc->page_line_num<0)
+          doc->page_line_num=s->page_len+doc->page_line_num%s->page_len;
+        else {
+          if (doc->page_line_num>=s->page_len) {
+            doc->page_line_num-=s->page_len;
+            if (doc->page_line_num>=s->page_len) //avoid extra divide
+              doc->page_line_num=doc->page_line_num%s->page_len;
+          }
+        }
+        if (s->header!=DOC_DFT) {
+          if (doc->page_line_num<s->header) {
+            y+=s->header-doc->page_line_num;
+            doc->page_line_num=s->header;
+            goto rc_start_of_line;
+          }
+        }
+        if (s->footer==DOC_DFT) {
+          if (doc->page_line_num>=s->page_len) {
+            if (s->header==DOC_DFT)
+              doc->page_line_num=0;
+            else {
+              doc->page_line_num=s->header;
+              y+=s->header;
+            }
+            goto rc_start_of_line;
+          }
+        } else {
+          if (doc->page_line_num>=s->page_len-s->footer) {
+            y+=s->footer;
+            if (s->header==DOC_DFT)
+              doc->page_line_num=0;
+            else {
+              doc->page_line_num=s->header;
+              y+=s->header;
+            }
+            goto rc_start_of_line;
+          }
+        }
+        break;
+      case DOCT_TAB:
+        k=(x+8) & ~7;
+        if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+              !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER)) {
+          while (x<k) {
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW))
+              TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+CH_SPACE);
+            if (find_cursor) {
+              d2=DocCharDist(doc,x,y);
+              if (d2<D)
+                D=d2;
+            }
+            x++;
+          }
+        } else {
+          k-=x;
+          if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+            if (y_plot_top<=y<=y_plot_bottom)
+              TextLenStr(win_task,x-x0,y-y0,k,tmp_u32_attr,"        ");
+            x+=k;
+          } else {
+            if (find_cursor) {
+              while (k--) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D)
+                  D=d2;
+                x++;
+              }
+            } else
+              x+=k;
+          }
+        }
+        break;
+      case DOCT_PAGE_BREAK:
+        doc->flags|=DOCF_BWD_MOVEMENT;
+        y+=s->page_len-doc_e->page_line_num;
+        doc->page_line_num=0;
+        goto rc_start_of_line;
+      case DOCT_CURSOR:
+        if (!find_cursor && !(doc->flags & DOCF_NO_CURSOR)) {
+          doc->cur_entry=doc_e->next;
+          doc->cur_col=doc->cur_entry->min_col;
+        }
+        if (doc_e!=added_cursor)
+          del_doc_e=TRUE;
+        break;
+      case DOCT_PMT:
+        cur_u8_attr=cur_u8_attr&0xF0|DOC_COLOR_PMT;
+        if (y==cursor_y) {
+          doc->cur_entry=doc_e->next;
+          doc->cur_col=doc->cur_entry->min_col;
+        }
+        break;
+      case DOCT_CLEAR:
+        next_clear_found=doc_e;
+        if (doc_e->de_flags&DOCEF_HOLD)
+          clear_holds=TRUE;
+        else
+          clear_holds=FALSE;
+        break;
+      case DOCT_PAGE_LEN:
+        s->page_len=doc_e->attr;
+        if (doc_e->de_flags & DOCEF_WIN_REL)
+          s->page_len+=height;
+        goto rc_adjust_xy;
+      case DOCT_LEFT_MARGIN:
+        i=doc_e->attr;
+        left_margin=left+i;
+        s->left_margin=i;
+        goto rc_start_of_line;
+      case DOCT_RIGHT_MARGIN:
+        if (doc_e->de_flags & DOCEF_WIN_REL)
+          i=width-1-doc_e->attr;
+        else
+          i=doc_e->attr;
+        right_margin=left+i;
+        s->right_margin=i;
+        goto rc_adjust_xy;
+      case DOCT_HEADER:
+        s->header=doc_e->attr;
+        goto rc_adjust_xy;
+      case DOCT_FOOTER:
+        s->footer=doc_e->attr;
+        goto rc_adjust_xy;
+      case DOCT_INDENT:
+        if (doc_e->de_flags & DOCEF_LEFT_X)
+          i=doc_e->attr;
+        else
+          i=s->indent+doc_e->attr;
+        s->indent=i;
+        goto rc_start_of_line;
+      case DOCT_FOREGROUND:
+        cur_u8_attr&=0xF0;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0x0F;
+        else
+          cur_u8_attr|=doc_e->attr;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_BACKGROUND:
+        cur_u8_attr&=0x0F;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0xF0;
+        else
+          cur_u8_attr|=doc_e->attr<<4;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_DFT_FOREGROUND:
+        cur_u8_attr&=0xF0;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0xF;
+        else
+          cur_u8_attr|=doc_e->attr;
+        s->dft_text_attr=s->dft_text_attr&0xF0|cur_u8_attr&0x0F;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_DFT_BACKGROUND:
+        cur_u8_attr&=0x0F;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0xF0;
+        else
+          cur_u8_attr|=doc_e->attr<<4;
+        s->dft_text_attr=s->dft_text_attr&0x0F|cur_u8_attr&0xF0;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_WORD_WRAP:
+        if (doc_e->attr)
+          doc->flags|=DOCF_WORD_WRAP;
+        else
+          doc->flags&=~DOCF_WORD_WRAP;
+        break;
+      case DOCT_HIGHLIGHT:
+        if (doc_e->attr)
+          doc->flags|=DOCF_HIGHLIGHT;
+        else
+          doc->flags&=~DOCF_HIGHLIGHT;
+        break;
+      case DOCT_BLINK:
+        if (doc_e->attr)
+          doc->flags|=DOCF_BLINK;
+        else
+          doc->flags&=~DOCF_BLINK;
+        break;
+      case DOCT_INVERT:
+        if (doc_e->attr)
+          doc->flags|=DOCF_INVERT;
+        else
+          doc->flags&=~DOCF_INVERT;
+        break;
+      case DOCT_UNDERLINE:
+        if (doc_e->attr)
+          doc->flags|=DOCF_UNDERLINE;
+        else
+          doc->flags&=~DOCF_UNDERLINE;
+        break;
+      case DOCT_SHIFTED_X:
+        s->shifted_x=doc_e->attr;
+        break;
+      case DOCT_SHIFTED_Y:
+        s->shifted_y=doc_e->attr;
+        break;
+      case DOCT_CURSOR_MOVEMENT:
+        doc->flags|=DOCF_BWD_MOVEMENT;
+        x+=doc_e->cursor_x_offset;
+        if (doc_e->de_flags & DOCEF_PAGE_REL_Y) {
+          i=doc->page_line_num;
+          if (doc_e->de_flags & DOCEF_TOP_Y)
+            doc->page_line_num=0;
+          else if (doc_e->de_flags & DOCEF_BOTTOM_Y)
+            doc->page_line_num=s->page_len-1;
+          else if (doc_e->de_flags & DOCEF_CENTER_Y)
+            doc->page_line_num=s->page_len>>1;
+          y+=doc->page_line_num-i;
+        }
+        y+=doc_e->cursor_y_offset;
+        doc->page_line_num+=doc_e->cursor_y_offset;
+        goto rc_adjust_xy;
+      case DOCT_SPRITE:
+        if (!doc_e->bin_data && doc->flags&DOCEF_HAS_BIN)
+          doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num);
+        if ((tmpb=doc_e->bin_data) &&
+              !tmpb->tag && doc_e->tag && *doc_e->tag)
+          tmpb->tag=StrNew(doc_e->tag,mem_task);
+        if (tmpb && dc) {
+          DCRst(dc);
+          dc->flags&=~(DCF_DONT_DRAW|DCF_LOCATE_NEAREST);
+          if (recalc_flags&RECALCG_MASK!=RECALCt_TO_SCRN ||
+                doc_e->de_flags&DOCEF_DONT_DRAW)
+            dc->flags|=DCF_DONT_DRAW;
+          bptr=tmpb->data;
+          ii=SpriteTypeMask(bptr);
+          if (ii&1<<SPT_TYPES_NUM) {
+            bptr=gr.empty_sprite;
+            ii=SpriteTypeMask(bptr);
+          }
+          if (ii&(1<<SPT_FLOOD_FILL|1<<SPT_FLOOD_FILL_NOT))
+            i=cur_u8_attr>>4 &0xF ^ win_task->text_attr>>4 & 0xF;
+          else {
+            i=tmp_u32_attr>>12&0xF ^ win_task->text_attr>>4 & 0xF;
+            if (tmp_u32_attr & DOCET_SEL)
+              i^=0xF;
+            if (tmp_u32_attr & DOCET_INVERT)
+              i^=0xF;
+            if (blink_flag &&
+                  (doc_e==doc->cur_entry || tmp_u32_attr&DOCET_BLINK))
+              i^=0xF;
+          }
+          dc->color=i;
+          if (find_cursor)
+            dc->flags|=DCF_LOCATE_NEAREST;
+          dc->cur_x=(doc->x-x0)*FONT_WIDTH+pix_left+scroll_x;
+          dc->cur_y=(doc->y-y0)*FONT_HEIGHT+pix_top+scroll_y;
+          dc->cur_z=0;
+          dc->bkcolor=i;
+          if (doc_e->de_flags & DOCEF_FROM_START) {
+            xx=(x-k-x0)*FONT_WIDTH; //TODO: scrolling text is not length k
+            yy=(y-y0)*FONT_HEIGHT;
+            zz=0;
+          } else {
+            xx=(x-x0)*FONT_WIDTH;
+            yy=(y-y0)*FONT_HEIGHT;
+            zz=0;
+          }
+          if (ii&(1<<SPT_MESH|1<<SPT_SHIFTABLE_MESH)) {
+            if (!depth_buf) {
+              DCDepthBufAlloc(dc);
+              depth_buf=dc->depth_buf;
+            } else
+              dc->depth_buf=depth_buf;
+            Mat4x4IdentEqu(dc->r);
+            Mat4x4RotZ(dc->r,cur_time*3.1);
+            Mat4x4RotY(dc->r,cur_time*1.9);
+            Mat4x4RotX(dc->r,cur_time);
+            dc->flags|=DCF_TRANSFORMATION;
+            dc->x=xx;
+            dc->y=yy;
+            dc->z=GR_Z_ALL;
+            xx=0; yy=0; zz=0;
+          }
+          Sprite3(dc,xx,yy,zz,bptr);
+          dc->depth_buf=NULL;
+          dc->flags&=~(DCF_LOCATE_NEAREST|DCF_DONT_DRAW|DCF_TRANSFORMATION);
+          if (dc->nearest_dist<=D) {
+            D=dc->nearest_dist;
+            col=doc_e->min_col;
+          }
+        }
+        break;
+      case DOCT_SONG:
+        if (sys_focus_task==win_task &&
+              recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+              !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+          if (doc_e->aux_str &&
+                (!music.cur_song || StrCmp(music.cur_song,doc_e->aux_str))) {
+            Free(music.cur_song);
+            MusicSettingsRst;
+            music.cur_song=AStrNew(doc_e->aux_str);
+          }
+        }
+        doc->flags|=DOCF_HAS_SONG;
+        break;
+      case DOCT_HTML_CODE:
+        if (recalc_flags&RECALCF_TO_HTML &&
+              doc_e->de_flags&DOCEF_TAG && doc_e->tag)
+          x-=StrLen(doc_e->tag);
+        break;
+      case DOCT_TYPES_NUM-1: //nobound switch
+      default:
+        break;
+    }
+
+    if (doc_e->de_flags & DOCEF_HAS_BORDER)
+      TextBorder(win_task,doc_e->x-x0,x-x0-1,doc_e->y-y0,y-y0,
+            tmp_u32_attr.u8[1],ToBool(doc_e->de_flags & DOCEF_SOLID_BORDER));
+    if (full_refresh) {
+      switch (doc_e->type_u8) {
+        case DOCT_CHECK_BOX:
+          doc_e->max_col=2;
+          break;
+        case DOCT_LST:
+        case DOCT_TREE:
+        case DOCT_BTTN:
+        case DOCT_LINK:
+        case DOCT_MENU_VAL:
+        case DOCT_MACRO:
+          doc_e->max_col=1;
+          break;
+        default:
+          if (doc_e->de_flags & (DOCEF_TREE|DOCEF_LST))
+            doc_e->max_col=1;
+          else
+            doc_e->max_col=col2;
+      }
+
+      if (x>doc->max_x) doc->max_x=x;
+      if (y>doc->max_y) doc->max_y=y;
+      if (D<=best_d && !(doc_e->de_flags&DOCEF_NO_CLICK_ON)) {
+        best_d=D;
+        best_doc_e=doc_e;
+        best_col=col;
+      }
+      if (doc_e->de_flags & DOCEF_TREE) {
+        if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+          tree_collapsed=TRUE;
+        else
+          tree_collapsed=FALSE;
+        doc_e2=doc_e->next;
+        while (doc_e2!=doc && doc_e2->type_u8!=DOCT_INDENT &&
+              !(doc_e2->de_flags & DOCEF_TREE))
+          doc_e2=doc_e2->next;
+        if (doc_e2->type_u8==DOCT_INDENT) {
+          j=i=s->indent;
+          do {
+            if (tree_collapsed)
+              doc_e2->de_flags|=DOCEF_SKIP;
+            else
+              doc_e2->de_flags&=~DOCEF_SKIP;
+            if (doc_e2->type_u8==DOCT_INDENT) {
+              if (doc_e2->de_flags & DOCEF_LEFT_X)
+                j=doc_e2->attr;
+              else
+                j+=doc_e2->attr;
+            }
+            doc_e2=doc_e2->next;
+          } while (doc_e2!=doc && j>i);
+        }
+      }
+    }
+
+    doc_e2=doc_e->next;
+rc_skip:
+    while (doc_e2!=doc && doc_e2->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
+      if (doc_e2==doc->cur_entry) {
+        doc->cur_entry=doc_e2->next;
+        doc->cur_col=doc->cur_entry->min_col;
+      }
+      if (full_refresh) {
+        doc_e2->x=x;
+        doc_e2->y=y;
+        doc_e2->page_line_num=doc->page_line_num;
+        MemCpy(&doc_e2->settings,s,sizeof(CDocSettings));
+        doc_e2->type.u8[1]=cur_u8_attr;
+        doc_e2->de_flags=doc->flags
+              &(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT) |
+              doc_e2->de_flags&~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT);
+      }
+      doc_e2=doc_e2->next;
+    }
+
+    if (full_refresh) {
+      if (del_doc_e) {
+        if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))) {
+          if (doc_e==doc->cur_entry) {
+            doc->cur_entry=doc_e2;
+            doc->cur_col=doc_e2->min_col;
+          }
+          if (best_doc_e==doc_e) {
+            best_doc_e=doc_e2;
+            best_col=doc_e2->min_col;  //TODO: might be bug
+          }
+          DocEntryDel(doc,doc_e);
+        }
+      }
+    }
+    num_entries++;
+    if (!full_refresh && doc_e->y>y_plot_bottom)
+      break;
+    doc_e=doc_e2;
+  }
+
+  if (full_refresh) {
+    if (doc->cur_entry==doc && recalc_flags&RECALCF_ADD_CURSOR) {
+      doc_e2=DocEntryNewBase(doc,DOCT_CURSOR,,x,y,doc->page_line_num);
+      MemCpy(&doc_e2->settings,s,sizeof(CDocSettings));
+      QueInsRev(doc_e2,doc);
+    }
+
+    if (doc->min_x>doc->max_x) {
+      doc->max_x=0;
+      doc->min_x=0;
+    }
+    if (doc->min_y>doc->max_y) {
+      doc->max_y=0;
+      doc->min_y=0;
+    }
+
+    //Update header
+    if (!skipped_update) {
+      doc_e->x=x;
+      doc_e->y=y;
+      doc_e->page_line_num=doc->page_line_num;
+      MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
+      doc_e->type.u8[1]=cur_u8_attr;
+      if (find_cursor) {
+        D=DocCharDist(doc,x,y);
+        if (D<best_d && !(doc_e->de_flags&DOCEF_NO_CLICK_ON)) {
+          best_d=D;
+          best_doc_e=doc_e;
+          best_col=0;
+        }
+      }
+    }
+    if (doc->flags & DOCF_SIZE_MIN) {
+      if (Bt(&win_task->display_flags,DISPLAYf_NO_BORDER)) {
+        if (left<0)
+          left=0;
+        i=left+doc->max_x-doc->min_x;
+        if (i>TEXT_COLS-1)
+          i=TEXT_COLS-1;
+        WinHorz(left,i,win_task);
+        if (top<0)
+          top=0;
+        i=top+doc->max_y-doc->min_y;
+        if (i>TEXT_ROWS-1)
+          i=TEXT_ROWS-1;
+        WinVert(top,i,win_task);
+      } else {
+        if (left<1)
+          left=1;
+        i=left+doc->max_x-doc->min_x;
+        if (i>TEXT_COLS-2)
+          i=TEXT_COLS-2;
+        WinHorz(left,i,win_task);
+        if (top<1)
+          top=1;
+        i=top+doc->max_y-doc->min_y;
+        if (i>TEXT_ROWS-2)
+          i=TEXT_ROWS-2;
+        WinVert(top,i,win_task);
+      }
+    }
+    if (find_cursor) {
+      doc->cur_entry=best_doc_e;
+      doc->cur_col=best_col;
+      DocFormBwd(doc);
+//We need this because text coordinates are used
+      if (best_d<FONT_WIDTH)
+        best_d=0;
+      doc->best_d=best_d;
+    }
+
+    if (doc->cur_entry->type_u8!=DOCT_HEX_ED) {
+      doc->y=doc->cur_entry->y;
+      doc->x=doc->cur_entry->x+doc->cur_col;
+    } else {
+      doc->y=doc->cur_entry->y+doc->cur_col/3/doc->cur_entry->hex_ed_width;
+      x=doc->cur_col%(doc->cur_entry->hex_ed_width*3);
+      i=x/doc->cur_entry->hex_ed_width;
+      doc->x=doc->cur_entry->x+9;
+      if (i<2)
+        doc->x+=x>>1*3+x&1;
+      else
+        doc->x+=doc->cur_entry->hex_ed_width*3+
+              (x-doc->cur_entry->hex_ed_width<<1);
+    }
+    doc->line=doc->y+1;
+    doc->col=doc->x+1;
+
+    if (recalc_flags&RECALCF_HAS_CURSOR) {
+      if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN) {
+        x=0;
+        y=0;
+      } else {
+        x=scroll_x/FONT_WIDTH;
+        y=scroll_y/FONT_HEIGHT;
+      }
+      if (doc->top_line_num-y+height-1>doc->max_y)
+        doc->top_line_num=doc->max_y-(height-1)+y;
+      if (doc->top_line_num-y<doc->min_y)
+        doc->top_line_num=doc->min_y+y;
+
+      if (doc->y-doc->top_line_num+y>height-1)
+        doc->top_line_num=doc->y-(height-1)+y;
+      if (doc->y-doc->top_line_num+y<0)
+        doc->top_line_num=doc->y+y;
+
+      if (doc->line_start_col-x+width-1>doc->max_x)
+        doc->line_start_col=doc->max_x-(width-1)+x;
+      if (doc->line_start_col-x<doc->min_x)
+        doc->line_start_col=doc->min_x+x;
+
+      if (doc->x-doc->line_start_col+x>width-1)
+        doc->line_start_col=doc->x-(width-1)+x;
+      if (doc->x-doc->line_start_col+x<0)
+        doc->line_start_col=doc->x+x;
+    }
+  }
+  if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+        recalc_flags&RECALCF_HAS_CURSOR) {
+    x=doc->x-doc->line_start_col+left +scroll_x/FONT_WIDTH;
+    y=doc->y-doc->top_line_num+top+scroll_y/FONT_HEIGHT;
+    if (0<=x<=right && 0<=y<=bottom &&
+          x<TEXT_COLS && y<TEXT_ROWS &&
+          !(doc->flags&DOCF_HIDE_CURSOR)) {
+      u32_ptr=gr.text_base+y*TEXT_COLS+x;
+      *u32_ptr|=DOCET_BLINK;
+      *u32_ptr^=0xFF00;
+    }
+    if (full_refresh) {
+      if (!(doc->flags&DOCF_NO_SCROLL_BARS)) {
+        if (!Bt(&hss->flags,WSSf_SET_TO_POS)) {
+          hss->min=doc->min_x;
+          if (doc->max_x-width+1<hss->min)
+            hss->max=hss->min;
+          else
+            hss->max=doc->max_x-width+1;
+          hss->pos=doc->line_start_col;
+        }
+        if (!Bt(&vss->flags,WSSf_SET_TO_POS)) {
+          vss->min=doc->min_y;
+          if (doc->max_y-height+1<vss->min)
+            vss->max=vss->min;
+          else
+            vss->max=doc->max_y-height+1;
+          vss->pos=doc->top_line_num;
+        }
+      }
+      LBEqu(&doc->flags,DOCf_MORE,more);
+    }
+  }
+  if (!same_win) {
+    doc->old_win_top=top;
+    doc->old_win_bottom=bottom;
+    doc->old_win_left=left;
+    doc->old_win_right=right;
+    doc->old_cur_entry=doc->cur_entry;
+    doc->old_cur_col=doc->old_cur_col;
+  }
+  if (doc->flags & DOCF_HAS_SONG)
+    LBts(&win_task->task_flags,TASKf_HAS_SONG);
+  if (full_refresh) {
+    i=num_entries-doc->max_entries;
+    if (next_clear_found) {
+      DocDelToEntry(doc,next_clear_found,clear_holds);
+      DocRecalc(doc,recalc_flags);
+    } else if (i>1024) {
+      DocDelToNum(doc,i);
+      DocRecalc(doc,recalc_flags);
+    }
+  }
+  DCDel(dc);
+  Free(depth_buf);
+  if (unlock)
+    DocUnlock(doc);
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocRecalcLib.HC.HTML b/public/Wb/Adam/DolDoc/DocRecalcLib.HC.HTML new file mode 100755 index 0000000..8531126 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocRecalcLib.HC.HTML @@ -0,0 +1,244 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+I64 DocCharDist(CDoc *doc,I64 x,I64 y)
+{
+#assert FONT_WIDTH==FONT_HEIGHT
+  return (SqrI64(doc->x-x)+SqrI64(doc->y-y))*FONT_WIDTH*FONT_WIDTH;
+}
+
+U0 DocDelToNum(CDoc *doc,I64 num)
+{
+  CDocEntry *doc_e=doc->head.next,*doc_e2;
+  while (num-->0 && doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))) {
+      if (doc_e==doc->cur_entry) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc_e2->min_col;
+      }
+      DocEntryDel(doc,doc_e);
+    }
+    doc_e=doc_e2;
+  }
+}
+
+U0 DocDelToEntry(CDoc *doc,CDocEntry *clear_entry,Bool clear_holds)
+{
+  CDocEntry *doc_e=doc->head.next,*doc_e2;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))||clear_holds) {
+      if (doc_e==doc->cur_entry) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc_e2->min_col;
+      }
+      DocEntryDel(doc,doc_e);
+    }
+    if (doc_e==clear_entry)
+      break;
+    doc_e=doc_e2;
+  }
+}
+
+U0 DocBorderLstDraw(CDoc *doc)
+{
+  CTask *win_task=doc->win_task;
+  I64 i,y=-1,attr=win_task->border_attr<<8;
+  U64 ch;
+  CDoc *tmpl=doc;
+  CD3I64 saved_scroll;
+  while (tmpl && tmpl->doc_signature==DOC_SIGNATURE_VAL) {
+    y+=(Bsr(tmpl->desc)+7)>>3+1; //StrLen+1
+    tmpl=tmpl->parent_doc;
+  }
+  tmpl=doc;
+  if (y>win_task->win_height)
+    y=win_task->win_height;
+  WinScrollNull(win_task,&saved_scroll);
+  while (tmpl && tmpl->doc_signature==DOC_SIGNATURE_VAL) {
+    ch=tmpl->desc;
+    i=(Bsr(ch)+7)>>3;   //StrLen
+    ch=EndianI64(ch<<((8-i)<<3));
+    attr=win_task->border_attr<<8;
+    while (i-- && y>0) {
+      TextChar(win_task,TRUE,-1,--y,attr+ch&0xFF);
+      ch>>=8;
+    }
+    y--;
+    tmpl=tmpl->parent_doc;
+  }
+  WinScrollRestore(win_task,&saved_scroll);
+}
+
+public U0 DocTop(CDoc *doc=NULL)
+{//Move cursor, cur_entry, to top.
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  doc->cur_entry=doc->head.next;
+  doc->cur_col=doc->cur_entry->min_col;
+  doc->x=0;
+  doc->y=0;
+  doc->line_start_col=0;
+  doc->top_line_num=0;
+
+  DocFormFwd(doc);
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocCenter(CDoc *doc=NULL,I64 recalc_flags=RECALCt_NORMAL)
+{//Center win on doc cursor, cur_entry.
+  Bool unlock;
+  CTask *task;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  task=doc->win_task;
+  DocRecalc(doc,recalc_flags);
+  if (!(doc->flags&DOCF_BORDER_DOC))
+    doc->top_line_num=doc->y-(task->win_height+1)>>1;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocBottom(CDoc *doc=NULL)
+{//Move cursor, cur_entry, to bottom.
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  doc->cur_entry=doc;
+  doc->cur_col=0;
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocClear(CDoc *doc=NULL,Bool clear_holds=FALSE)
+{//Clear all doc entries, except +H, hold entries.
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  DocBottom(doc);
+  if (clear_holds)
+    DocPrint(doc,"$CL+H$");
+  else
+    DocPrint(doc,"$CL$");
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public Bool DocCursor(Bool show=OFF,CDoc *doc=NULL)
+{//Show or hide cursor.
+  if (!doc && !(doc=DocPut))
+    return FALSE;
+  return !LBEqu(&doc->flags,DOCf_HIDE_CURSOR,!show);
+}
+
+public Bool DocHighlightCursor(Bool show=OFF,CDoc *doc=NULL)
+{//Highlight or Don't highlight cursor.
+  if (!doc && !(doc=DocPut))
+    return FALSE;
+  return !LBEqu(&doc->flags,DOCf_DONT_HIGHLIGHT_CURSOR,!show);
+}
+
+public Bool DocScroll(Bool val=OFF,CDoc *doc=NULL)
+{//Turn scroll bars OFF/ON.
+  if (!doc && !(doc=DocPut))
+    return FALSE;
+  return !LBEqu(&doc->flags,DOCf_NO_SCROLL_BARS,!val);
+}
+
+public U0 DocCollapse(Bool collapse=TRUE,CDoc *doc=NULL)
+{//Collapse or uncollapse all tree widgets.
+  CDocEntry *doc_e;
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->de_flags&DOCEF_TREE)
+      BEqu(&doc_e->de_flags,DOCEf_CHECKED_COLLAPSED,collapse);
+    doc_e=doc_e->next;
+  }
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
+public I64 DocMax(I64 i=I64_MAX)
+{//Set max document entries. (Cmd line buffer size.)
+//Adjusts the size of the cmd line buf.
+  //Normally, the cmd line deletes entries
+  //when more are added and the old scroll up.
+  //See max_entries.
+  I64 res;
+  CDoc *doc;
+  if (doc=DocPut) {
+    res=doc->max_entries;
+    doc->max_entries=i;
+    return res;
+  } else
+    return 0;
+}
+
+#help_index "DolDoc/Task;StdOut/Task"
+U0 DocUpdateTaskDocs(CTask *task)
+{//This is called from GrUpdateTaskWin() by the winmgr at 30fps.
+  CDoc *doc;
+  CD3I64 saved_scroll;
+  if (task->border_src==BDS_CUR_DRV && task->cur_dv)
+    task->border_attr=DrvTextAttrGet(Drv2Let(task->cur_dv));
+  if (task->title_src==TTS_TASK_NAME)
+    StrCpy(task->task_title,task->task_name);
+  if ((doc=DocDisplay(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
+    if (task->border_src==BDS_ED_FILENAME_DRV)
+      task->border_attr=DrvTextAttrGet(*doc->filename.name);
+    if (task->title_src==TTS_ED_FILENAME)
+      MemCpy(task->task_title,doc->filename.name,STR_LEN-1);
+    DocRecalc(doc,RECALCt_TO_SCRN|RECALCF_HAS_CURSOR);
+  }
+  if ((doc=DocBorder(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
+    WinScrollNull(task,&saved_scroll);
+    DocRecalc(doc,RECALCt_TO_SCRN);
+    WinScrollRestore(task,&saved_scroll);
+  }
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocRun.HC.HTML b/public/Wb/Adam/DolDoc/DocRun.HC.HTML new file mode 100755 index 0000000..54fffcc --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocRun.HC.HTML @@ -0,0 +1,134 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+public I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,
+        Bool exited,I64 *_has_action=NULL)
+{//Do action on final entry sel by user.
+//Sometimes returns locked, sometimes unlocked
+  U8 ch=doc->cmd_U8,*st;
+  I64 res=DOCM_CANCEL,has_action=FALSE;
+  CHashDefineStr *tmph;
+  DocLock(doc);
+  if (!exited) {
+    if (doc_e->de_flags & DOCEF_ESC) {
+      Msg(MSG_KEY_DOWN,CH_ESC,0,1<<JOBf_DONT_FILTER);
+      has_action=TRUE;
+      goto er_done;
+    } if (doc_e->de_flags & DOCEF_QUIT) {
+      Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0,1<<JOBf_DONT_FILTER);
+      has_action=TRUE;
+      goto er_done;
+    } else if (doc_e->de_flags & DOCEF_CHECK_COLLAPSABLE) {
+      doc_e->de_flags^=DOCEF_CHECKED_COLLAPSED;
+      has_action=TRUE;
+    }
+  }
+  try {
+    if (ch==CH_SPACE) {
+      if (doc_e->de_flags & DOCEF_LINK && doc->left_click_link) {
+        res=(*doc->left_click_link)(doc,doc_e);
+        has_action=TRUE;
+      }
+      if (doc_e->de_flags & DOCEF_LEFT_EXP) {
+        res=doc_e->left_exp;
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_LEFT_CB && doc_e->left_cb) {
+        DocUnlock(doc);
+        res=(*doc_e->left_cb)(doc,doc_e);
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_LEFT_MACRO) {
+        if (doc_e->de_flags & DOCEF_POPUP) {
+          st=StrNew(doc_e->left_macro);
+          DocUnlock(doc);
+          PopUp(st,Fs);
+          Free(st);
+        } else {
+          if (doc_e->de_flags & DOCEF_LEFT_IN_STR)
+            InStr("%s",doc_e->left_macro);
+          else
+            In("%s",doc_e->left_macro);
+        }
+        has_action=TRUE;
+      }
+      if (!exited && doc_e->de_flags & DOCEF_LST &&
+            doc_e->de_flags & DOCEF_DEFINE &&
+            (tmph=HashFind(doc_e->define_str,
+            doc->win_task->hash_table,HTT_DEFINE_STR)) &&
+            (res=PopUpPickLst(tmph->data))!=DOCM_CANCEL) {
+        DocDataFmt(doc,doc_e,res);
+        DocDataScan(doc,doc_e);
+        has_action=TRUE;
+      }
+    } else if (ch=='\n') {
+      if (doc_e->de_flags & DOCEF_LINK && doc->right_click_link) {
+        res=(*doc->right_click_link)(doc,doc_e);
+        has_action=TRUE;
+      }
+      if (doc_e->de_flags & DOCEF_RIGHT_EXP) {
+        res=doc_e->right_exp;
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_RIGHT_CB && doc_e->right_cb) {
+        DocUnlock(doc);
+        res=(*doc_e->right_cb)(doc,doc_e);
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_RIGHT_MACRO) {
+        if (doc_e->de_flags & DOCEF_POPUP) {
+          st=StrNew(doc_e->right_macro);
+          DocUnlock(doc);
+          PopUp(st,Fs);
+          Free(st);
+        } else {
+          if (doc_e->de_flags & DOCEF_RIGHT_IN_STR)
+            InStr("%s",doc_e->right_macro);
+          else
+            In("%s",doc_e->right_macro);
+        }
+        has_action=TRUE;
+      }
+    }
+  }
+  catch
+    DocBottom(doc);
+  doc->cmd_U8=CH_SPACE;
+er_done:
+  if (_has_action) *_has_action=has_action;
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocTerm.HC.HTML b/public/Wb/Adam/DolDoc/DocTerm.HC.HTML new file mode 100755 index 0000000..9084bc5 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocTerm.HC.HTML @@ -0,0 +1,244 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Task;StdOut/Task"
+public CDoc *DocBorderNew(CDoc *pdoc)
+{//Make new std border doc.
+  CDocEntry *doc_e;
+  CDoc *bdoc;
+
+  bdoc=DocNew;
+  bdoc->flags|=DOCF_BORDER_DOC;
+  if (pdoc) {
+    DocPrint(bdoc,"$CM+H+BY+RX+NC,-7,1$");
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdFilterCB;
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdOverStrikeCB;
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdDollarCB;
+    DocPrint(bdoc,"$CM+H+BY+RX+NC,-18,1$");
+    doc_e=DocPrint(bdoc,"$TX+BD+TC,\"     \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdMoreCB;
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdDollarTypeCB;
+  }
+  DocPrint(bdoc,"$CM+H+TY+NC,0,-1$");
+  doc_e=DocPrint(bdoc,"$DA+H-TRM-P+BD+RD+CX+IV,LEN=STR_LEN-1,"
+        "A=\"%%s...\",SCX=15$");
+  doc_e->data=&Fs->task_title;
+  DocDataFmt(bdoc,doc_e);
+  DocPrint(bdoc,"$CM+H+NC,1,0$$TX+H+BD+IV,\"%X\"$",Fs);
+  DocPrint(bdoc,"$TX+H+RX+BD,\"[X]\"$");
+  DocPrint(bdoc,"$BK,1$$TX+H+LX+BD,\"MENU\"$$BK,0$");
+  return bdoc;
+}
+
+public U0 DocTermNew()
+{//Make into term win task with Put/Display/Border docs.
+  CDoc *pdoc=DocNew;
+  pdoc->right_click_link=&TermRightClickLink;
+  pdoc->max_entries=4096;
+  Fs->border_src=BDS_CUR_DRV;
+  pdoc->desc='Term';
+  Fs->put_doc=Fs->display_doc=pdoc;
+  Fs->border_doc=DocBorderNew(pdoc);
+  Fs->cur_menu=MenuFile("::/Doc/EdPullDown.DD");
+  WinScrollsInit(Fs);
+  Raw(OFF);
+}
+
+#help_index "DolDoc"
+
+#define RIGHT_INCLUDE   0
+#define RIGHT_AINCLUDE  1
+#define RIGHT_COPY      2
+#define RIGHT_MOVE      3
+#define RIGHT_DELETE    4
+#define RIGHT_TYPE      5
+#define RIGHT_ED        6
+#define RIGHT_MOUNT     7
+#define RIGHT_PLAIN     8
+#define RIGHT_INFILE    9
+
+I64 PopUpTermRight(U8 *header)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"\n\n"
+        "TXT=%s\nDD =%s\nJIT=%s\nGR =%s"
+        "$CM+LX,1,3 $$BT,\"Include           JIT\",LE=RIGHT_INCLUDE$"
+        "$CM+LX,25,0$$BT,\"Adam Include      JIT\",LE=RIGHT_AINCLUDE$"
+        "$CM+LX,1,3 $$BT,\"Copy                 \",LE=RIGHT_COPY$"
+        "$CM+LX,25,0$$BT,\"Move or Rename       \",LE=RIGHT_MOVE$"
+        "$CM+LX,1,3 $$BT,\"Delete               \",LE=RIGHT_DELETE$"
+        "$CM+LX,25,0$$BT,\"Type           TXT;GR\",LE=RIGHT_TYPE$"
+        "$CM+LX,1,3 $$BT,\"DolDoc Edit        DD\",LE=RIGHT_ED$"
+        "$CM+LX,25,0$$BT,\"Mount           ISO.C\",LE=RIGHT_MOUNT$"
+        "$CM+LX,1,3 $$BT,\"Plain Text Edit   TXT\",LE=RIGHT_PLAIN$"
+        "$CM+LX,25,0$$BT,\"Infile             IN\",LE=RIGHT_INFILE$"
+        "$CM+LX,1,3 $$BT,\"Cancel               \",LE=DOCM_CANCEL$\n",
+        FILEMASK_TXT,FILEMASK_DD,FILEMASK_JIT,FILEMASK_GR);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e)
+{//Called with doc locked, exit unlocked
+  Bool res;
+  U8 *st;
+  if (st=DocEntryLink(doc,doc_e)) {
+    DocUnlock(doc);
+    if (doc_e->de_flags & DOCEF_POPUP)
+      res=PopUpEd(st);
+    else
+      res=Ed(st);
+    Free(st);
+    return res;
+  }
+}
+
+I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e)
+{//Called with doc locked, exit unlocked
+  Bool send_new_line=FALSE,res=FALSE;
+  U8 *st,*st2;
+  I64 i;
+  CEdFileName fn;
+  if (st2=DocEntryLink(doc,doc_e)) {
+    if (st=DocLinkFile(st2)) {
+      DocUnlock(doc);
+      if ((i=PopUpTermRight(st))>=0) {
+        DocBottom(doc);
+        switch (i) {
+          case RIGHT_INCLUDE:
+            if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "#include \"%s\";\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            ExeFile(st,CCF_CMD_LINE);
+            res=TRUE;
+            break;
+          case RIGHT_AINCLUDE:
+            if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "Adam(\"#include \\\"%s\\\"\" );\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            AdamFile(st,FALSE);
+            res=TRUE;
+            break;
+          case RIGHT_COPY:
+            StrCpy(fn.name,st);
+            if (DocForm(&fn)) {
+              res=ToBool(Copy(st,fn.name));
+            } else
+              send_new_line=TRUE;
+            break;
+          case RIGHT_MOVE:
+            StrCpy(fn.name,st);
+            if (DocForm(&fn))
+              res=Move(st,fn.name);
+            else
+              send_new_line=TRUE;
+            break;
+          case RIGHT_DELETE:
+            res=ToBool(Del(st));
+            break;
+          case RIGHT_TYPE:
+            res=Type(st);
+            break;
+          case RIGHT_ED:
+            if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_DD)) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not DolDoc File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "Ed(\"%s\");\n$PT$$FG$$BG$",st;
+            res=Ed(st);
+            break;
+          case RIGHT_MOUNT:
+            if (FileExtDot(st) && !FilesFindMatch(st,"*.ISO.C")) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .ISO.C File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "MountFile(\"%s\");\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            MountFile(st);
+            res=TRUE;
+            break;
+          case RIGHT_PLAIN:
+            "Plain(\"%s\");\n$PT$$FG$$BG$",st;
+            res=Plain(st);
+            break;
+          case RIGHT_INFILE:
+            if (FileExtDot(st) && !FilesFindMatch(st,"*.IN*")) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .IN File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "InFile(\"%s\");\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            InFile(st);
+            res=TRUE;
+            break;
+        }
+      } else
+        send_new_line=TRUE;
+      Free(st);
+    } else
+      send_new_line=TRUE;
+    Free(st2);
+  } else
+    send_new_line=TRUE;
+  DocBottom(doc);
+  "$PT$$FG$$BG$";
+  if (send_new_line)
+    '\n';
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocTree.HC.HTML b/public/Wb/Adam/DolDoc/DocTree.HC.HTML new file mode 100755 index 0000000..513de88 --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocTree.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Tree"
+
+public Bool DocTreeFind(CDoc *haystack_doc,U8 *needle_path,
+  CDocEntry **_tree_entry=NULL,
+  CDocEntry **_start_indent=NULL, CDocEntry **_end_indent=NULL)
+{//Find tree widget start and end.
+  I64 i=0,k=0;
+  U8 *st1=StrNew(needle_path),*st2=MAlloc(StrLen(needle_path)+1);
+  Bool res=FALSE,unlock_doc=DocLock(haystack_doc);
+  CDocEntry *doc_e=haystack_doc->head.next;
+  if (_tree_entry) *_tree_entry=haystack_doc;
+  if (_start_indent) *_start_indent=haystack_doc;
+  if (_end_indent) *_end_indent=haystack_doc;
+  while (*st1 && doc_e!=haystack_doc) {
+    StrFirstRem(st1,"/",st2);
+    if (*st2) {
+      while (doc_e!=haystack_doc) {
+        if (doc_e->type_u8==DOCT_INDENT)
+          i+=doc_e->attr;
+        else if (i==k && doc_e->de_flags&DOCEF_TREE &&
+              !StrCmp(doc_e->tag+3,st2)) {
+          if (*st1)
+            break;
+          else {
+            if (_tree_entry) *_tree_entry=doc_e;
+            i=0;
+            while (doc_e!=haystack_doc && doc_e->type_u8!=DOCT_INDENT)
+              doc_e=doc_e->next;
+            if (doc_e!=haystack_doc) {
+              i=doc_e->attr;
+              if (_start_indent) *_start_indent=doc_e;
+              doc_e=doc_e->next;
+              while (doc_e!=haystack_doc && i>0) {
+                if (doc_e->type_u8==DOCT_INDENT) {
+                  i+=doc_e->attr;
+                  if (i<=0) {
+                    if (_end_indent) *_end_indent=doc_e;
+                    res=TRUE;
+                    break;
+                  }
+                }
+                doc_e=doc_e->next;
+              }
+            }
+            goto ft_done;
+          }
+        }
+        doc_e=doc_e->next;
+      }
+      k+=2;
+    }
+  }
+ft_done:
+  if (unlock_doc)
+    DocUnlock(haystack_doc);
+  Free(st1);
+  Free(st2);
+  return res;
+}
+
+public Bool DocTreeFFind(U8 *name,U8 *path)
+{//Find tree widget in file.
+  CDoc *doc=DocRead(name);
+  Bool res=DocTreeFind(doc,path);
+  DocDel(doc);
+  return res;
+}
+
+public Bool DocTreeMake(CDoc *doc,U8 *path)
+{//Make tree widget.
+  I64 i=0,j=I64_MIN,k=0;
+  U8 *st1=StrNew(path),
+        *st2=MAlloc(StrLen(path)+1),
+        *st3=StrNew(path);
+  Bool res=TRUE,unlock_doc=DocLock(doc);
+  CDocEntry *doc_e=doc->head.next;
+  doc->cur_entry=doc;
+  doc->cur_col=0;
+  while (*st1 && doc_e!=doc) {
+    StrFirstRem(st1,"/",st2);
+    if (*st2) {
+      while (doc_e!=doc) {
+        if (doc_e->type_u8==DOCT_INDENT) {
+          i+=doc_e->attr;
+          if (i==j) {
+            doc->cur_entry=doc_e;
+            doc->cur_col=0;
+            goto mt_done;
+          }
+        } else if (i==k && doc_e->de_flags&DOCEF_TREE &&
+              !StrCmp(doc_e->tag+3,st2)) {
+          Free(st3);
+          st3=StrNew(st1);
+          j=i;
+          if (!*st1)
+            res=FALSE;
+          else
+            break;
+        }
+        doc_e=doc_e->next;
+      }
+      k+=2;
+    }
+  }
+mt_done:
+  if (res) {
+    while (*st3) {
+      StrFirstRem(st3,"/",st2);
+      if (*st2) {
+        DocPrint(doc,"$TR+C,\"%s\"$\n$ID,2$",st2);
+        doc->cur_entry=DocPrint(doc,"$ID,-2$");
+        doc->cur_col=0;
+      }
+    }
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+  Free(st1);
+  Free(st2);
+  Free(st3);
+  return res;
+}
+
+Bool DocTreeWriteJoin(CDoc *doc,U8 *path,Bool write,U8 *fmt,I64 argc,I64 *argv)
+{//Rewrite doc tree branch.
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  Bool res,unlock_doc=DocLock(doc);
+  if (res=DocTreeFind(doc,path,
+        &tree_branch,&start_indent,&end_indent)) {
+    DocCut(doc,start_indent->next,end_indent->last);
+    doc->cur_entry=start_indent->next;
+    doc->cur_col=doc->cur_entry->min_col;
+  } else
+    DocTreeMake(doc,path);
+  DocPrint(doc,"%s",buf);
+  if (write && DrvIsWritable(*doc->filename.name))
+    DocWrite(doc);
+  if (unlock_doc)
+    DocUnlock(doc);
+  Free(buf);
+  return res;
+}
+
+Bool DocTreeAppendJoin(CDoc *doc,U8 *path,Bool write,U8 *fmt,I64 argc,I64 *argv)
+{//Append to doc tree branch.
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  Bool res,unlock_doc=DocLock(doc);
+  if (res=DocTreeFind(doc,path,
+        &tree_branch,&start_indent,&end_indent)) {
+    doc->cur_entry=end_indent;
+    doc->cur_col=doc->cur_entry->min_col;
+  } else
+    DocTreeMake(doc,path);
+  DocPrint(doc,"%s",buf);
+  if (write && DrvIsWritable(*doc->filename.name))
+    DocWrite(doc);
+  if (unlock_doc)
+    DocUnlock(doc);
+  Free(buf);
+  return res;
+}
+
+public Bool DocTreeWrite(CDoc *doc,U8 *path,Bool write=TRUE,U8 *fmt,...)
+{//Rewrite doc tree branch.
+  return DocTreeWriteJoin(doc,path,write,fmt,argc,argv);
+}
+
+public Bool DocTreeAppend(CDoc *doc,U8 *path,Bool write=TRUE,U8 *fmt,...)
+{//Append to doc tree branch.
+  return DocTreeAppendJoin(doc,path,write,fmt,argc,argv);
+}
+
+public Bool DocTreeFWrite(U8 *name,U8 *path,U8 *fmt,...)
+{//Rewrite doc tree branch in file.
+  CDoc *doc=DocRead(name);
+  Bool res=DocTreeWriteJoin(doc,path,TRUE,fmt,argc,argv);
+  DocDel(doc);
+  return res;
+}
+
+public Bool DocTreeFAppend(U8 *name,U8 *path,U8 *fmt,...)
+{//Append to doc tree branch in file.
+  CDoc *doc=DocRead(name);
+  Bool res=DocTreeAppendJoin(doc,path,TRUE,fmt,argc,argv);
+  DocDel(doc);
+  return res;
+}
+
+#help_index "DolDoc/Compiler;Compiler"
+public I64 ExeDoc(CDoc *doc,I64 ccf_flags=0)
+{//JIT Compile and execute a document.
+  I64 res;
+  Bool okay=TRUE,unlock_doc=DocLock(doc);
+  CCmpCtrl *cc=CmpCtrlNew(,ccf_flags|CCF_DONT_FREE_BUF);
+  if (Fs->last_cc!=&Fs->next_cc)
+    cc->opts=Fs->last_cc->opts;
+  QueIns(cc,Fs->last_cc);
+  LexAttachDoc(cc,,doc);
+  try {
+    Lex(cc);
+    res=ExeCmdLine(cc);
+  } catch {
+    if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+      res=0;
+    }
+  }
+  QueRem(cc);
+  if (okay)
+    CmpCtrlDel(cc); //TODO: can crash
+  if (unlock_doc)
+    DocUnlock(doc);
+  return res;
+}
+
+#help_index "DolDoc/Tree;DolDoc/Compiler;Compiler"
+public I64 DocTreeExe(CDoc *doc,U8 *path)
+{//Execute doc tree branch.
+  CDoc *doc2;
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  I64 res=0;
+  if (DocTreeFind(doc,path,&tree_branch,&start_indent,&end_indent)) {
+    doc2=DocCopy(doc,tree_branch,end_indent);
+    res=ExeDoc(doc2);
+    DocDel(doc2);
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+  return res;
+}
+
+public I64 DocTreeFExe(U8 *name,U8 *path)
+{//Execute doc tree branch in file.
+  I64 res;
+  CDoc *doc=DocRead(name);
+  res=DocTreeExe(doc,path);
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/DocWidgetWiz.HC.HTML b/public/Wb/Adam/DolDoc/DocWidgetWiz.HC.HTML new file mode 100755 index 0000000..7187f8c --- /dev/null +++ b/public/Wb/Adam/DolDoc/DocWidgetWiz.HC.HTML @@ -0,0 +1,1194 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+U8 *ctrl_L_footer=
+        "\n$MU-X+Q,\"Abort\",LE=DOCM_CANCEL$\n"
+        "\n\n$LK+PU,\"Click for Help\",A=\"FI:::/Doc/Widget.DD\"$\n";
+
+I64 PopUpLinkType(Bool include_anchor)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Link Type Menu\"$\n"
+        "\n$LTBLUE$$MU,\"To file\",LE=LK_FILE$\n"
+        "$MU,\"To anchor in file\",LE=LK_FILE_ANCHOR$\n"
+        "$MU,\"To str in file\",LE=LK_FILE_FIND$\n"
+        "$MU,\"To line in file\",LE=LK_FILE_LINE$\n"
+        "$MU,\"To man page\",LE=LK_MAN_PAGE$\n"
+        "$MU,\"To plain-text file\",LE=LK_PLAIN$\n"
+        "$MU,\"To str in plain-text file\",LE=LK_PLAIN_FIND$\n"
+        "$MU,\"To line in plain-text file\",LE=LK_PLAIN_LINE$\n"
+        "$MU,\"To Bible chapter line and verse\",LE=LK_BIBLE_FIND$\n"
+        "$MU,\"To Dictionary Definition\",LE=LK_DEF$\n"
+        "$MU,\"To Help Index\",LE=LK_HELP_INDEX$\n"
+        "$MU,\"To Addr\",LE=LK_ADDR$\n");
+  if (include_anchor)
+    DocPrint(doc,"$MU,\"Place Anchor\",LE=LK_PLACE_ANCHOR$\n");
+  DocPrint(doc,"%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CEdFileLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512];
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdFileAnchorLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Anchor Label  :%s\"$\n";
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdFileFindLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Str        :%s\"$\n";
+  I64   num             format "$DA-TRM,A=\"Occurrence Num:%04d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdFileLineLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512];
+  I64   num             format "$DA-TRM,A=\"Line Num      :%04d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdManPageLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Label         :%s\"$\n";
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdAddrLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Addr Exp   :%s\"$\n";
+  I64   num             format "$DA-TRM,A=\"Bin Size      :%04d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdPlaceAnchor
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Anchor Label  :%s\"$\n";
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up,
+        quote           format "$CB,\"Quote\"$\n",
+        hide            format "$CB,\"Hide\"$\n";
+};
+
+class CEdBibleLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book            format "$LS,D=\"ST_BIBLE_BOOKS\"$\n";
+  U8    aux[512]        format "$DA-P,A=\"Chapter Verse :%s\"$\n";
+  I64   num;
+
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdDefLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Word          :%s\"$\n";
+  I64   num             format "$DA-TRM,A=\"Def Num       :%4d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdProject
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512];
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+Bool GetLink(I64 type,U8 **_tag,U8 **_link,Bool *_pop_up,
+        Bool *_quote,U8 **_html_link)
+{
+  CEdFileLink *e=CAlloc(sizeof(CEdFileLink));
+  Bool res=FALSE;
+  if (type>=0) {
+    e->num=1;
+    switch (type) {
+      case LK_FILE:
+        if (DocForm(e,,,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("FI:%s",e->file);
+        }
+        break;
+      case LK_PLAIN:
+        if (DocForm(e,,,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("PI:%s",e->file);
+        }
+        break;
+      case LK_FILE_ANCHOR:
+        if (DocForm(e,"CEdFileAnchorLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("FA:%s,%s",e->file,e->aux);
+        }
+        break;
+      case LK_FILE_FIND:
+        if (DocForm(e,"CEdFileFindLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (e->num==1) {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("FF:%s,%s",e->file,e->aux);
+          } else {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("FF:%s,%s:%d",e->file,e->aux,e->num);
+          }
+        }
+        break;
+      case LK_PLAIN_FIND:
+        if (DocForm(e,"CEdFileFindLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (e->num==1) {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("PF:%s,%s",e->file,e->aux);
+          } else {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("PF:%s,%s:%d",e->file,e->aux,e->num);
+          }
+        }
+        break;
+      case LK_FILE_LINE:
+        if (DocForm(e,"CEdFileLineLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("FL:%s,%d",e->file,e->num);
+        }
+        break;
+      case LK_PLAIN_LINE:
+        if (DocForm(e,"CEdFileLineLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("PL:%s,%d",e->file,e->num);
+        }
+        break;
+      case LK_MAN_PAGE:
+        if (DocForm(e,"CEdManPageLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("MN:%s",e->aux);
+        }
+        break;
+      case LK_PLACE_ANCHOR:
+        if (DocForm(e,"CEdPlaceAnchor",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag) {
+            if (e->hide)
+              *_tag=StrNew("");
+            else
+              *_tag=StrNew(e->aux);
+          } else
+            *_tag=StrNew(e->tag);
+          *_link=StrNew(e->aux);
+        }
+        break;
+      case LK_BIBLE_FIND:
+        if (DocForm(e,"CEdBibleLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=MStrPrint("%Z,%s",e->book,"ST_BIBLE_BOOKS",e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("BF:%Z,%s",e->book,"ST_BIBLE_BOOKS",e->aux);
+        }
+        break;
+      case LK_DEF:
+        e->num=-1;
+        if (DocForm(e,"CEdDefLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          if (e->num<0)
+            *_link=MStrPrint("DN:%s",e->aux);
+          else
+            *_link=MStrPrint("DN:%s,%d",e->aux,e->num);
+
+        }
+        break;
+      case LK_HELP_INDEX:
+        if (DocForm(e,"CEdManPageLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("HI:%s",e->aux);
+        }
+        break;
+      case LK_ADDR:
+        e->num=DFT_ADDR_LINK_BIN_SIZE;
+        if (DocForm(e,"CEdAddrLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (e->num==DFT_ADDR_LINK_BIN_SIZE) {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("AD:%s",e->aux);
+          } else {
+            if (!*e->tag)
+              *_tag=MStrPrint("%s,%d",e->aux,e->num);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("AD:%s,%d",e->aux,e->num);
+          }
+        }
+        break;
+    }
+  }
+  if (*e->html_link)
+    *_html_link=StrNew(e->html_link);
+  else
+    *_html_link=NULL;
+  if (e->pop_up)
+    *_pop_up=TRUE;
+  else
+    *_pop_up=FALSE;
+  if (e->quote)
+    *_quote=TRUE;
+  else
+    *_quote=FALSE;
+  Free(e);
+  return res;
+}
+
+U0 EdInsLink()
+{
+  U8 *tag=NULL,*link=NULL,*st=NULL,*html_link=NULL,*pop_up_st;
+  Bool pop_up=FALSE,quote=FALSE;
+  I64 type=PopUpLinkType(TRUE);
+  if (type>=0) {
+    if (GetLink(type,&tag,&link,&pop_up,&quote,&html_link)) {
+      if (pop_up)
+        pop_up_st="+PU";
+      else
+        pop_up_st="";
+      switch (type) {
+        case LK_PLACE_ANCHOR:
+          if (html_link)
+            st=MStrPrint("$AN,\"%$Q\",A=\"%$Q\",HTML=\"%$Q\"$",
+                  tag,link,html_link);
+          else
+            st=MStrPrint("$AN,\"%$Q\",A=\"%$Q\"$",tag,link);
+          break;
+        default:
+          if (html_link)
+            st=MStrPrint("$LK%s,\"%$Q\",A=\"%$Q\",HTML=\"%$Q\"$",
+                  pop_up_st,tag,link,html_link);
+          else
+            st=MStrPrint("$LK%s,\"%$Q\",A=\"%$Q\"$",pop_up_st,tag,link);
+      }
+    }
+  }
+  if (st) {
+    if (quote)
+      "%$Q",st;
+    else
+      "%s",st;
+  }
+  Free(tag);
+  Free(link);
+  Free(html_link);
+  Free(st);
+}
+
+I64 PopUpColorType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Color Type Menu\"$\n"
+        "\n$LTBLUE$$MU,\"Foreground\",LE=DOCT_FOREGROUND$\n"
+        "$MU,\"Background\",LE=DOCT_BACKGROUND$\n"
+        "$MU,\"Default Foreground\",LE=DOCT_DFT_FOREGROUND$\n"
+        "$MU,\"Default Background\",LE=DOCT_DFT_BACKGROUND$\n"
+        "%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 PopUpPageSettingType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Page Setting Menu\"$\n"
+        "\n$LTBLUE$$MU,\"Page Length\",LE=DOCT_PAGE_LEN$\n"
+        "$MU,\"Page Header\",LE=DOCT_HEADER$\n"
+        "$MU,\"Page Footer\",LE=DOCT_FOOTER$\n"
+        "$MU,\"Left Margin\",LE=DOCT_LEFT_MARGIN$\n"
+        "$MU,\"Right Margin\",LE=DOCT_RIGHT_MARGIN$\n"
+        "%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+U0 EdInsColor()
+{
+  I64 type=PopUpColorType,col=DOC_DFT;
+  if (type>=0) {
+    col=PopUpColor(,FALSE);
+    if (col==DOC_DFT)
+      "$%Z$",type,"ST_DOC_CMDS";
+    else if (col>=0)
+      "$%Z,%d$",type,"ST_DOC_CMDS",col;
+  }
+}
+
+class CEdPageSetting1
+{
+  U8    val[512]        format "$DA-P,A=\"Setting Val:%s\"$\n";
+  Bool  winrel;
+};
+
+class CEdPageSetting2
+{
+  U8    val[512]        format "$DA-P,A=\"Setting Val:%s\"$\n";
+  Bool  winrel          format "$CB,\"Win Relative\"$\n";
+};
+
+U0 EdInsPageSetting()
+{
+  I64 type=PopUpPageSettingType;
+  CEdPageSetting1 *e=CAlloc(sizeof(CEdPageSetting1));
+  if (type>=0) {
+    if (type==DOCT_RIGHT_MARGIN||type==DOCT_PAGE_LEN) {
+      if (DocForm(e(CEdPageSetting2 *))) {
+        if (e->winrel) {
+          if (*e->val)
+            "$%Z+WR,%s$",type,"ST_DOC_CMDS",e->val;
+          else
+            "$%Z+WR,0$",type,"ST_DOC_CMDS";
+        } else {
+          if (*e->val)
+            "$%Z,%s$",type,"ST_DOC_CMDS",e->val;
+          else
+            "$%Z$",type,"ST_DOC_CMDS";
+        }
+      }
+    } else {
+      if (DocForm(e)) {
+        if (*e->val)
+          "$%Z,%s$",type,"ST_DOC_CMDS",e->val;
+        else
+          "$%Z$",type,"ST_DOC_CMDS";
+      }
+    }
+  }
+  Free(e);
+}
+
+#define WIZ_HIGHLIGHT_ON        (DOCT_ERROR+1)
+#define WIZ_HIGHLIGHT_OFF       (DOCT_ERROR+2)
+
+I64 PopUpWidgetType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Text Widgets Menu\"$\n"
+        "\n$LTBLUE$$MU,\"Link\",LE=DOCT_LINK$\n"
+        "$MU,\"Text\",LE=DOCT_TEXT$\n"
+        "$MU,\"Tree Branch\",LE=DOCT_TREE$\n"
+        "$MU,\"Color\",LE=DOCT_FOREGROUND$\n"
+        "$MU,\"Page Settings\",LE=DOCT_PAGE_LEN$\n"
+        "$MU,\"Cursor Movement\",LE=DOCT_CURSOR_MOVEMENT$\n"
+        "$MU,\"Macro\",LE=DOCT_MACRO$\n"
+        "$MU,\"Bttn\",LE=DOCT_BTTN$\n"
+        "$MU,\"Check Box\",LE=DOCT_CHECK_BOX$\n"
+        "$MU,\"List\",LE=DOCT_LST$\n"
+        "$MU,\"Menu Val\",LE=DOCT_MENU_VAL$\n"
+        "$MU,\"Data\",LE=DOCT_DATA$\n"
+        "$MU,\"Hex Edit\",LE=DOCT_HEX_ED$\n"
+        "$MU,\"Syntax Highlight ON\",LE=WIZ_HIGHLIGHT_ON$\n"
+        "$MU,\"Syntax Highlight OFF\",LE=WIZ_HIGHLIGHT_OFF$\n"
+        "$MU,\"HTML\",LE=DOCT_HTML_CODE$\n"
+        "$MU,\"Song\",LE=DOCT_SONG$\n"
+        "%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CEdText
+{
+  U8    tag[512]  format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  Bool  left_x    format "$CB,\"Left X\"$\n",
+        center_x  format "$CB,\"Center X\"$\n",
+        right_x   format "$CB,\"Right X\"$\n",
+        margin_rel format "$CB,\"Margin Rel X\"$\n",
+        blink     format "$CB,\"Blink\"$\n",
+        invert    format "$CB,\"Invert\"$\n",
+        underline format "$CB,\"Underline\"$\n",
+        tree      format "$CB,\"Tree\"$\n",
+        collapsed format "$CB,\"Collapsed\"$\n";
+  U8    scroll_x [512]  format "$DA-P,A=\"Scroll X Length Expression:%s\"$\n",
+        shift_x  [512]  format "$DA-P,A=\"X Offset Expression       :%s\"$\n",
+        shift_y  [512]  format "$DA-P,A=\"Y Offset Expression       :%s\"$\n",
+        define_str[512] format "$DA-P,A=\"Define Str                :%s\"$\n",
+        html_link[512]  format "$DA-P,A=\"Html Link                 :%s\"$\n";
+};
+
+U0 EdInsText()
+{
+  U8 *st,buf[512];
+  CEdText *e=CAlloc(sizeof(CEdText));
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->left_x  )  CatPrint(buf,"+LX");
+    if (e->center_x)  CatPrint(buf,"+CX");
+    if (e->right_x )  CatPrint(buf,"+RX");
+    if (e->margin_rel) CatPrint(buf,"+MRX");
+    if (e->blink)     CatPrint(buf,"+BK");
+    if (e->invert)    CatPrint(buf,"+IV");
+    if (e->underline) CatPrint(buf,"+UL");
+    if (e->tree)      CatPrint(buf,"+TR");
+    if (e->collapsed) CatPrint(buf,"+C");
+    st=MStrPrint("%q",e->tag);
+    "$TX%s,\"%$Q\"",buf,st;
+    Free(st);
+    if (*e->shift_x)
+      ",SX=%s",e->shift_x;
+    if (*e->shift_y)
+      ",SY=%s",e->shift_y;
+    if (*e->scroll_x)
+      ",SCX=%s",e->scroll_x;
+    if (*e->define_str) {
+      st=MStrPrint("%q",e->define_str);
+      ",D=\"%$Q\"",st;
+      Free(st);
+    }
+    if (*e->html_link) {
+      st=MStrPrint("%q",e->html_link);
+      ",HTML=\"%$Q\"",st;
+      Free(st);
+    }
+    "$";
+  }
+  Free(e);
+}
+
+class CEdSong
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        song[512]       format "$DA-P,A=\"Song          :%s\"$\n";
+};
+
+U0 EdInsSong()
+{
+  CEdSong *e=CAlloc(sizeof(CEdSong));
+  if (DocForm(e,,,,ctrl_L_footer))
+    "$SO,\"%$Q\",A=\"%s\"$",e->tag,e->song;
+  Free(e);
+}
+
+class CEdHtmlCode
+{
+  U8    tag[512]        format "$DA-P,A=\"Html Code:%s\"$\n";
+};
+
+U0 EdInsHtml()
+{
+  CEdHtmlCode *e=CAlloc(sizeof(CEdHtmlCode));
+  if (DocForm(e,,,,ctrl_L_footer))
+    "$HC,\"%$Q\"$",e->tag;
+  Free(e);
+}
+
+class CEdMacroMenu
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text                  :%s\"$\n",
+        left_macro[512] format "$DA-P,A=\"Left Click Macro          :%s\"$\n",
+        left_exp[512]   format "$DA-P,A=\"Left Click Expression     :%s\"$\n";
+  Bool  popup           format "$CB,\"PopUp\"$\n",
+        left_is_in_str  format "$CB,\"Left is InStr\"$\n",
+        left_x          format "$CB,\"Left X \"$\n",
+        center_x        format "$CB,\"Center X \"$\n",
+        right_x         format "$CB,\"Right X \"$\n",
+        margin_rel      format "$CB,\"Margin Rel X\"$\n",
+        blink           format "$CB,\"Blink\"$\n",
+        invert          format "$CB,\"Invert\"$\n",
+        underline       format "$CB,\"Underline\"$\n",
+        escape          format "$CB,\"Escape\"$\n";
+  U8    scroll_x[512]   format "$DA-P,A=\"Scroll X Length Expression:%s\"$\n",
+        shift_x[512]    format "$DA-P,A=\"X Offset Expression       :%s\"$\n",
+        shift_y[512]    format "$DA-P,A=\"Y Offset Expression       :%s\"$\n";
+};
+
+U0 EdInsMacroMenu(Bool is_macro)
+{
+  U8 *st,buf[512];
+  CEdMacroMenu *e=CAlloc(sizeof(CEdMacroMenu));
+  e->underline=TRUE;
+  e->escape=TRUE;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->popup)       CatPrint(buf,"+PU-X");
+    if (e->left_x  )    CatPrint(buf,"+LX");
+    if (e->center_x)    CatPrint(buf,"+CX");
+    if (e->right_x )    CatPrint(buf,"+RX");
+    if (e->margin_rel)  CatPrint(buf,"+MRX");
+    if (e->blink)       CatPrint(buf,"+BK");
+    if (e->invert)      CatPrint(buf,"+IV");
+    if (!e->underline)  CatPrint(buf,"-UL");
+    if (!e->escape)     CatPrint(buf,"-X");
+    if (e->left_is_in_str) CatPrint(buf,"+LIS");
+    if (*e->tag || is_macro) {
+      if (is_macro) {
+        if (*e->tag) {
+          st=MStrPrint("%q",e->tag);
+          "$MA%s,\"%$Q\"",buf,st;
+          Free(st);
+        } else
+          "$MA%s",buf;
+      } else {
+        st=MStrPrint("%q",e->tag);
+        "$MU%s,\"%$Q\"",buf,st;
+        Free(st);
+      }
+      if (*e->left_exp)
+        ",LE=%s",e->left_exp;
+      if (*e->left_macro) {
+        st=MStrPrint("%q",e->left_macro);
+        ",LM=\"%$Q\"",st;
+        Free(st);
+      }
+      if (*e->shift_x)
+        ",SX=%s",e->shift_x;
+      if (*e->shift_y)
+        ",SY=%s",e->shift_y;
+      if (*e->scroll_x)
+        ",SCX=%s",e->scroll_x;
+      "$";
+    }
+  }
+  Free(e);
+}
+
+class CEdBttn
+{
+  U8    tag[512]   format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  Bool  popup      format "$CB,\"PopUp\"$\n",
+        left_x     format "$CB,\"Left X \"$\n",
+        center_x   format "$CB,\"Center X \"$\n",
+        right_x    format "$CB,\"Right X \"$\n",
+        margin_rel format "$CB,\"Margin Rel X\"$\n",
+        escape     format "$CB,\"Escape\"$\n";
+  U8    left_macro[512] format "$DA-P,A=\"Left Click Macro:%s\"$\n";
+  Bool  left_is_in_str  format "$CB,\"Left is InStr\"$\n";
+  U8    left_exp[512]   format "$DA-P,A=\"Left Click Expression:%s\"$\n";
+  Bool  quote           format "$CB,\"Quote\"$\n";
+};
+
+U0 EdInsBttn()
+{
+  U8 *st,buf[512];
+  CEdBttn *e=CAlloc(sizeof(CEdBttn));
+  e->escape=TRUE;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->popup)    CatPrint(buf,"+PU-X");
+    if (e->left_x  ) CatPrint(buf,"+LX");
+    if (e->center_x) CatPrint(buf,"+CX");
+    if (e->right_x ) CatPrint(buf,"+RX");
+    if (e->margin_rel) CatPrint(buf,"+MRX");
+    if (!e->escape)     CatPrint(buf,"-X");
+    if (e->left_is_in_str) CatPrint(buf,"+LIS");
+    if (*e->tag) {
+      if (e->quote) {
+        st=MStrPrint("%q",e->tag);
+        "$$BT%s,\\\"%$Q\\\"",buf,st;
+        Free(st);
+        if (*e->left_exp)
+          ",LE=%s",e->left_exp;
+        if (*e->left_macro) {
+          st=MStrPrint("%q",e->left_macro);
+          ",LM=\\\"%$Q\\\"",st;
+          Free(st);
+        }
+        "$$";
+      } else {
+        st=MStrPrint("%q",e->tag);
+        "$BT%s,\"%$Q\"",buf,st;
+        Free(st);
+        if (*e->left_exp)
+          ",LE=%s",e->left_exp;
+        if (*e->left_macro) {
+          st=MStrPrint("%q",e->left_macro);
+          ",LM=\"%$Q\"",st;
+          Free(st);
+        }
+        "$";
+      }
+    }
+  }
+  Free(e);
+}
+
+class CEdCursorMovement
+{
+  U8    left_exp[512]    format "$DA-P,A=\"X Expression (LE):%s\"$\n",
+        right_exp[512]   format "$DA-P,A=\"Y Expression (RE):%s\"$\n";
+  Bool  left_x   format "$CB,\"Left   X \"$\n",
+        center_x format "$CB,\"Center X \"$\n",
+        right_x  format "$CB,\"Right  X \"$\n",
+        margin_rel format "$CB,\"Margin Rel X\"$\n",
+        top_y    format "$CB,\"Top    Y \"$\n",
+        center_y format "$CB,\"Center Y \"$\n",
+        bottom_y format "$CB,\"Bottom Y \"$\n",
+        page_rel format "$CB,\"Page Rel Y\"$\n",
+        quote    format "$CB,\"Quote\"$\n";
+};
+
+U0 EdInsCursorMovement()
+{
+  U8 buf[512];
+  CEdCursorMovement *e=CAlloc(sizeof(CEdCursorMovement));
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->left_x  )    CatPrint(buf,"+LX");
+    if (e->center_x)    CatPrint(buf,"+CX");
+    if (e->right_x )    CatPrint(buf,"+RX");
+    if (e->margin_rel)  CatPrint(buf,"+MRX");
+    if (e->top_y   )    CatPrint(buf,"+TY");
+    if (e->center_y)    CatPrint(buf,"+CY");
+    if (e->bottom_y)    CatPrint(buf,"+BY");
+    if (e->page_rel)    CatPrint(buf,"+PRY");
+    if (!*e->left_exp)  CatPrint(buf,"-LE");
+    if (!*e->right_exp) CatPrint(buf,"-RE");
+    if (e->quote)
+      "$";
+    "$CM%s",buf;
+    if (*e->left_exp)
+      ",LE=%s",e->left_exp;
+    if (*e->right_exp)
+      ",RE=%s",e->right_exp;
+    "$";
+    if (e->quote)
+      "$";
+  }
+  Free(e);
+}
+
+class CEdDataNum
+{
+  U8    fmt_str[512]    format "$DA-P,A=\"Format Str:%s\"$\n";
+  I64   len;
+  Bool  term            format "$CB,\"Form Field Terminator\"$\n",
+        remalloc,
+        refresh         format "$CB,\"Refresh Data\"$\n",
+        update          format "$CB,\"Update Data\"$\n";
+};
+
+class CEdDataStr
+{
+  U8    fmt_str[512]    format "$DA-P,A=\"Format Str:%s\"$\n";
+  I64   len             format "$DA,A=\"Length:%d\"$\n";
+  Bool  term            format "$CB,\"Zero Terminator\"$\n",
+        remalloc        format "$CB,\"Remalloc for Unlimited Length\"$\n",
+        refresh         format "$CB,\"Refresh Data\"$\n",
+        update          format "$CB,\"Update Data\"$\n";
+};
+
+U0 EdInsData()
+{
+  I64 i,type=RT_I64;
+  U8 *st,buf[512],raw_type[16];
+  CEdDataNum *e=CAlloc(sizeof(CEdDataNum));
+  e->term=TRUE;
+  e->len=DOCE_LEN_DFT;
+  if ((i=PopUpPickDefineSub("ST_NATURAL_TYPES"))>=0) {
+    *buf=0;
+    i+=RT_I8;
+    if (i==RT_F32)
+      i=RT_F64;
+    if (i==RT_UF32) {//U8 *
+      i=DocForm(e(CEdDataStr *),,,,ctrl_L_footer);
+      if (e->remalloc) {
+        CatPrint(buf,"+M");
+        e->term=TRUE;
+      } else
+        CatPrint(buf,"-P");
+    } else {
+      type=i;
+      i=DocForm(e,,,,ctrl_L_footer);
+    }
+    if (i) {
+      if (type==RT_I64)
+        *raw_type=0;
+      else
+        StrPrint(raw_type,",RT=%Z",type,"ST_RAW_TYPES");
+
+      if (!e->term)     CatPrint(buf,"-TRM");
+      if (e->refresh)   CatPrint(buf,"+RD");
+      if (e->update)    CatPrint(buf,"+UD");
+
+      st=MStrPrint("%q",e->fmt_str);
+      if (e->remalloc)
+        "$$DA%s,A=\\\"%$Q\\\"$$",buf,st;
+      else if (e->len==DOCE_LEN_DFT)
+        "$$DA%s%s,A=\\\"%$Q\\\"$$",buf,raw_type,st;
+      else
+        "$$DA%s,LEN=%d%s,A=\\\"%$Q\\\"$$",buf,e->len,raw_type,st;
+      Free(st);
+    }
+  }
+  Free(e);
+}
+
+class CEdCheckBox
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  Bool  refresh         format "$CB,\"Refresh Data\"$\n";
+  I64   type            format "$LS,D=\"ST_INT_SIZE_TYPES\"$\n";
+};
+
+U0 EdInsCheckBox()
+{
+  U8 *st,buf[512],raw_type[16];
+  CEdCheckBox *e=CAlloc(sizeof(CEdCheckBox));
+  e->type=RT_I8-RT_I8;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    e->type+=RT_I8;
+    if (e->type==RT_I8)
+      *raw_type=0;
+    else
+      StrPrint(raw_type,",RT=%Z",e->type,"ST_RAW_TYPES");
+    if (e->refresh)  CatPrint(buf,"+RD");
+    st=MStrPrint("%q",e->tag);
+    "$$CB%s%s,\\\"%$Q\\\"$$",buf,raw_type,st;
+    Free(st);
+  }
+  Free(e);
+}
+
+class CEdLst
+{
+  U8    tag[512]        format "$DA-P,A=\"Dft Sel    :%s\"$\n",
+        define_str[512] format "$DA-P,A=\"Define Str    :%s\"$\n";
+  Bool  refresh         format "$CB,\"Refresh Data\"$\n";
+  I64   type            format "$LS,D=\"ST_INT_SIZE_TYPES\"$\n";
+};
+
+U0 EdInsLst()
+{
+  U8 *st1,*st2,buf[512],raw_type[16];
+  CEdLst *e=CAlloc(sizeof(CEdLst));
+  e->type=RT_I64-RT_I8;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    e->type+=RT_I8;
+    if (e->type==RT_I64)
+      *raw_type=0;
+    else
+      StrPrint(raw_type,",RT=%Z",e->type,"ST_RAW_TYPES");
+    if (e->refresh)  CatPrint(buf,"+RD");
+    if (!*e->tag)
+      st1=NULL;
+    else
+      st1=MStrPrint("%q",e->tag);
+    st2=MStrPrint("%q",e->define_str);
+    if (st1)
+      "$$LS%s%s,\\\"%$Q\\\",D=\\\"%$Q\\\"$$",buf,raw_type,st1,st2;
+    else
+      "$$LS%s%s,D=\\\"%$Q\\\"$$",buf,raw_type,st2;
+    Free(st1);
+    Free(st2);
+  }
+  Free(e);
+}
+
+class CEdHexEd
+{
+  I64   cnt     format "$DA,A=\"Count:%d\"$\n",
+        cols    format "$DA,A=\"Columns:%d\"$\n";
+  Bool  zero    format "$CB,\"Zero Based\"$\n",
+        refresh format "$CB,\"Refresh Data\"$\n";
+};
+
+U0 EdInsHexEd()
+{
+  U8 buf[512];
+  CEdHexEd *e=CAlloc(sizeof(CEdHexEd));
+  e->cnt=128;
+  e->cols=4;
+  e->zero=TRUE;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (!e->zero)  CatPrint(buf,"-Z");
+    if (e->refresh)  CatPrint(buf,"+RD");
+    "$$HX%s,%d,%d$$",buf,e->cnt,e->cols;
+  }
+  Free(e);
+}
+
+class CEdBin
+{
+  U8    tag[512]                format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  I64   bin_num                 format "$DA,A=\"Bin Num:%d\"$\n";
+  U8    bin_ptr_link_file[512]  format "$DA-P,A=\"File:%s\"$\n";
+  I64   bin_ptr_link_bin_num    format "$DA,A=\"File Bin Num:%d\"$\n";
+  U8    bin_ptr_link_tag[512]   format "$DA-P,A=\"File Bin Tag:%s\"$\n";
+};
+
+U0 EdInsBin(I64 bin_num,I64 type)
+{
+  CEdBin *e=CAlloc(sizeof(CEdBin));
+  StrPrint(e->tag,"<%d>",bin_num);
+  e->bin_num=bin_num;
+  e->bin_ptr_link_bin_num=1;
+  if (DocForm(e,,,
+        "Note: Normally, you enter no file,\n"
+        "just a bin num.  If You enter a\n"
+        "file, enter a file bin num or a file\n"
+        "bin tag.\n\n",ctrl_L_footer)) {
+    if (*e->bin_ptr_link_file) {
+      if (*e->bin_ptr_link_tag)
+        "$%Z,\"%$Q\",BI=%d,BP=\"%s,%s\"$",type,"ST_DOC_CMDS",e->tag,e->bin_num,
+              e->bin_ptr_link_file,e->bin_ptr_link_tag;
+      else
+        "$%Z,\"%$Q\",BI=%d,BP=\"%s,%d\"$",type,"ST_DOC_CMDS",e->tag,e->bin_num,
+              e->bin_ptr_link_file,e->bin_ptr_link_bin_num;
+    } else {
+      if (DocBinFindNum(DocPut,e->bin_num))
+        "$%Z,\"%$Q\",BI=%d$",type,"ST_DOC_CMDS",e->tag,e->bin_num;
+      else
+        PopUpOk("Invalid Binary Num");
+    }
+  }
+  Free(e);
+}
+
+class CEdTree
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  I64   indent          format "$DA,A=\"Indention:%d\"$\n";
+  Bool  collapsed       format "$CB,\"Collapsed\"$\n";
+};
+
+U0 EdInsTree()
+{
+  U8 *st1,*st2,buf[512];
+  CEdTree *e=CAlloc(sizeof(CEdTree));
+  e->collapsed=TRUE;
+  e->indent=2;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (!e->collapsed)  CatPrint(buf,"-C");
+    st1=MStrPrint("%q",e->tag);
+    st2=MStrPrint("$TR%s,\"%$Q\"$\n$ID,%d$*\n$ID,%d$",
+          buf,st1,e->indent,-e->indent);
+    DocPrintAtomic(DocPut,"%s",st2);
+    Free(st1);
+    Free(st2);
+  }
+  Free(e);
+}
+
+U0 EdInsWidgetWiz()
+{
+  I64 type=PopUpWidgetType;
+  switch (type) {
+    case DOCT_FOREGROUND:
+      EdInsColor;
+      break;
+    case DOCT_PAGE_LEN:
+      EdInsPageSetting;
+      break;
+    case DOCT_LINK:
+      EdInsLink;
+      break;
+    case DOCT_TEXT:
+      EdInsText;
+      break;
+    case DOCT_TREE:
+      EdInsTree;
+      break;
+    case DOCT_MACRO:
+      EdInsMacroMenu(TRUE);
+      break;
+    case DOCT_MENU_VAL:
+      EdInsMacroMenu(FALSE);
+      break;
+    case DOCT_CURSOR_MOVEMENT:
+      EdInsCursorMovement;
+      break;
+    case DOCT_BTTN:
+      EdInsBttn;
+      break;
+    case DOCT_DATA:
+      EdInsData;
+      break;
+    case DOCT_CHECK_BOX:
+      EdInsCheckBox;
+      break;
+    case DOCT_LST:
+      EdInsLst;
+      break;
+    case DOCT_HEX_ED:
+      EdInsHexEd;
+      break;
+    case DOCT_SONG:
+      EdInsSong;
+      break;
+    case WIZ_HIGHLIGHT_ON:
+      "$HL,1$";
+      break;
+    case WIZ_HIGHLIGHT_OFF:
+      "$HL,0$";
+      break;
+    case DOCT_HTML_CODE:
+      EdInsHtml;
+  }
+}
+
+#define EST_SPRITE              0
+#define EST_SPRITE_PTR          1
+#define EST_DUP_SPRITE          2
+#define EST_SPRITE_SIZE         3
+#define EST_SPRITE_MACRO        4
+#define EST_SPRITE_MENU         5
+#define EST_SPRITE_LINK         6
+
+I64 PopUpSpriteType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Graphic Sprite Resource Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/Resource.DD.Z\"$\n\n"
+        "$LTBLUE$$MU,\"Make Sprite\",LE=EST_SPRITE$$FG$\t "
+        "Start by making a sprite.\n"
+        "$LTBLUE$$MU,\"Ptr to Sprite\",LE=EST_SPRITE_PTR$$FG$\t "
+        "Insert pointer into src code.\n"
+        "$LTBLUE$$MU,\"Duplicate Sprite\",LE=EST_DUP_SPRITE$$FG$ "
+        "Make dup image for in a doc.\n"
+        "$LTBLUE$$MU,\"Sprite Size\",LE=EST_SPRITE_SIZE$$FG$\t "
+        "Insert size of a sprite into src code.\n"
+        "$LTBLUE$$MU,\"Sprite Macro\",LE=EST_SPRITE_MACRO$$FG$\t "
+        "Create icon with auto-text payload.\n"
+        "$LTBLUE$$MU,\"Sprite Menu Item\",LE=EST_SPRITE_MENU$$FG$ "
+        "Create icon with numeric payload.\n"
+        "$LTBLUE$$MU,\"Sprite Link\",LE=EST_SPRITE_LINK$$FG$\t "
+        "Create icon with link payload.\n\n"
+        "$LTBLUE$$MU,\"Abort\",LE=DOCM_CANCEL$\n\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CEdMacroSprite
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text       :%s\"$\n",
+        exp[512]        format "$DA-P,A=\"Macro          :%s\"$\n";
+  Bool  escape          format "$CB,\"Escape\"$\n",
+        popup           format "$CB,\"PopUp\"$\n",
+        is_in_str               format "$CB,\"InStr\"$\n";
+};
+
+class CEdMenuSprite
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text       :%s\"$\n",
+        exp[512]        format "$DA-P,A=\"Expression     :%s\"$\n";
+  Bool  escape          format "$CB,\"Escape\"$\n",
+        popup,
+        is_in_str;
+};
+
+U8 *EdSpriteLink(Bool *_pop_up,U8 **_html_link)
+{
+  U8 *res=NULL,*tag=NULL,*link=NULL;
+  Bool quote=FALSE;
+  I64 type=PopUpLinkType(FALSE);
+  *_html_link=NULL;
+  if (type>=0 && GetLink(type,&tag,&link,_pop_up,&quote,_html_link))
+    res=MStrPrint("\"%$Q\",A=\"%$Q\"",tag,link);
+  Free(tag);
+  Free(link);
+  return res;
+}
+
+U8 *EdSprite(I64 bin_num)
+{
+  I64 type=PopUpSpriteType;
+  Bool pop_up;
+  U8 *st,*st1=NULL,*st2=NULL,buf[1024],*html_link=NULL;
+  CEdMacroSprite *e=CAlloc(sizeof(CEdMacroSprite));
+  *buf=0;
+  switch (type) {
+    case EST_SPRITE:
+      st1=MStrPrint("\"<%d>\"",bin_num);
+      break;
+    case EST_SPRITE_MACRO:
+      e->escape=TRUE;
+      if (DocForm(e,,,,ctrl_L_footer)) {
+        CatPrint(buf,"+UL");
+        if (e->is_in_str) CatPrint(buf,"+LIS");
+        if (e->popup)   CatPrint(buf,"+PU");
+        if (e->escape)  CatPrint(buf,"+X");
+        st=MStrPrint("%q",e->exp);
+        st1=MStrPrint("\"%$Q\",LM=\"%$Q\"",e->tag,st);
+        Free(st);
+      }
+      break;
+    case EST_SPRITE_MENU:
+      e->escape=TRUE;
+      if (DocForm(e,"CEdMenuSprite",,,ctrl_L_footer)) {
+        if (e->escape)  CatPrint(buf,"+X");
+        st1=MStrPrint("\"%$Q\",LE=%s",e->tag,e->exp);
+      }
+      break;
+    case EST_SPRITE_LINK:
+      CatPrint(buf,"+L");
+      st1=EdSpriteLink(&pop_up,&html_link);
+      if (pop_up)
+        CatPrint(buf,"+PU");
+      break;
+    case EST_SPRITE_PTR:
+      EdInsBin(--bin_num,DOCT_INS_BIN);
+      break;
+    case EST_SPRITE_SIZE:
+      EdInsBin(--bin_num,DOCT_INS_BIN_SIZE);
+      break;
+    case EST_DUP_SPRITE:
+      EdInsBin(--bin_num,DOCT_SPRITE);
+      break;
+  }
+  if (st1) {
+    if (html_link)
+      st2=MStrPrint("$SP%s,%s,HTML=\"%$Q\",BI=%d$",buf,st1,html_link,bin_num);
+    else
+      st2=MStrPrint("$SP%s,%s,BI=%d$",buf,st1,bin_num);
+    Free(st1);
+  }
+  Free(e);
+  Free(html_link);
+  return st2;
+}
+
+ diff --git a/public/Wb/Adam/DolDoc/MakeDoc.HC.HTML b/public/Wb/Adam/DolDoc/MakeDoc.HC.HTML new file mode 100755 index 0000000..1aabc1e --- /dev/null +++ b/public/Wb/Adam/DolDoc/MakeDoc.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#help_index "DolDoc"
+#help_file "::/Doc/DolDoc"
+
+/*
+TempleOS DolDoc's can have "cursor movement" cmds which can move the cursor up
+the scrn and layer on existing text.  It can also have callback funs which
+supply live, changing text.  For these reasons, you can't assume you know
+where the vis portion of the document is and must process much
+of the document each time it is placed on the scrn, becoming CPU
+intensive on big documents.
+See ::/Doc/DolDocOverview.DD
+*/
+
+//Hash Types
+#define DHT_DOC_CMD     1
+#define DHT_DOC_FLAG    2
+#define DHT_COLOR       4
+
+public class CDolDocGlbls
+{
+  CHashTable *hash;
+  I64   dft_de_flags            [DOCT_TYPES_NUM],
+        type_flags_nontag_invis [(DOCT_TYPES_NUM+63)/64],
+        type_flags_form         [(DOCT_TYPES_NUM+63)/64],
+        type_flags_data         [(DOCT_TYPES_NUM+63)/64],
+        type_flags_chk_dup      [(DOCT_TYPES_NUM+63)/64],
+        clean_scan_codes        [4];
+  I32   dft_type_flags          [DOCT_TYPES_NUM];
+} doldoc;
+MemSet(&doldoc,0,sizeof(CDolDocGlbls));
+
+#help_index "God"
+#define BIBLE_FILENAME  "::/Misc/Bible.TXT.Z"
+
+#include "DocExt"
+#include "DocBin"
+#include "DocNew"
+#include "DocForm"
+#include "DocDblBuf"
+#include "DocPlain"
+#include "DocInit"
+#include "DocHighlight"
+#include "DocRecalcLib"
+#include "DocRecalc"
+#include "DocFile"
+#include "DocClipBoard"
+#include "DocRun"
+#include "DocGet"
+#include "DocChar"
+#include "DocFind"
+#include "DocLink"
+#include "DocEd"
+#include "DocPopUp"
+#include "DocGr"
+#include "DocMacro"
+#include "DocWidgetWiz"
+#include "DocPutKey"
+#include "DocPutS"
+#include "DocCodeTools"
+#include "DocTree"
+#include "DocTerm"
+
+KeyDevAdd(&KDDocPutKey,&KDDocPutS,0x80000000,TRUE);
+fp_getstr2=&DocGetStr2;
+fp_doc_put=&DocPut;
+
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/God/GodBible.HC.HTML b/public/Wb/Adam/God/GodBible.HC.HTML new file mode 100755 index 0000000..ec06683 --- /dev/null +++ b/public/Wb/Adam/God/GodBible.HC.HTML @@ -0,0 +1,379 @@ + + + + + + + + + + + +
+#help_index "God"
+U0 BibleInit()
+{
+  DefineLstLoad("ST_BIBLE_BOOKS",
+        "Genesis\0"
+        "Exodus\0"
+        "Leviticus\0"
+        "Numbers\0"
+        "Deuteronomy\0"
+        "Joshua\0"
+        "Judges\0"
+        "Ruth\0"
+        "1 Samuel\0"
+        "2 Samuel\0"
+        "1 Kings\0"
+        "2 Kings\0"
+        "1 Chronicles\0"
+        "2 Chronicles\0"
+        "Ezra\0"
+        "Nehemiah\0"
+        "Esther\0"
+        "Job\0"
+        "Psalms\0"
+        "Proverbs\0"
+        "Ecclesiastes\0"
+        "Song of Songs\0"
+        "Isaiah\0"
+        "Jeremiah\0"
+        "Lamentations\0"
+        "Ezekiel\0"
+        "Daniel\0"
+        "Hosea\0"
+        "Joel\0"
+        "Amos\0"
+        "Obadiah\0"
+        "Jonah\0"
+        "Micah\0"
+        "Nahum\0"
+        "Habakkuk\0"
+        "Zephaniah\0"
+        "Haggai\0"
+        "Zechariah\0"
+        "Malachi\0"
+        "Matthew\0"
+        "Mark\0"
+        "Luke\0"
+        "John\0"
+        "Acts\0"
+        "Romans\0"
+        "1 Corinthians\0"
+        "2 Corinthians\0"
+        "Galatians\0"
+        "Ephesians\0"
+        "Philippians\0"
+        "Colossians\0"
+        "1 Thessalonians\0"
+        "2 Thessalonians\0"
+        "1 Timothy\0"
+        "2 Timothy\0"
+        "Titus\0"
+        "Philemon\0"
+        "Hebrews\0"
+        "James\0"
+        "1 Peter\0"
+        "2 Peter\0"
+        "1 John\0"
+        "2 John\0"
+        "3 John\0"
+        "Jude\0"
+        "Revelation\0");
+  DefineLstLoad("ST_BIBLE_BOOK_LINES",
+        "297\0"
+        "5068\0"
+        "9123\0"
+        "12005\0"
+        "15977\0"
+        "19168\0"
+        "21329\0"
+        "23598\0"
+        "23902\0"
+        "26892\0"
+        "29345\0"
+        "32241\0"
+        "34961\0"
+        "37633\0"
+        "40756\0"
+        "41671\0"
+        "42963\0"
+        "43605\0"
+        "46190\0"
+        "53793\0"
+        "56267\0"
+        "56966\0"
+        "57332\0"
+        "61806\0"
+        "66736\0"
+        "67217\0"
+        "71804\0"
+        "73189\0"
+        "73876\0"
+        "74130\0"
+        "74615\0"
+        "74697\0"
+        "74860\0"
+        "75241\0"
+        "75416\0"
+        "75604\0"
+        "75806\0"
+        "75932\0"
+        "76684\0"
+        "76908\0"
+        "79970\0"
+        "81941\0"
+        "85266\0"
+        "87803\0"
+        "90914\0"
+        "92110\0"
+        "93323\0"
+        "94088\0"
+        "94514\0"
+        "94869\0"
+        "95153\0"
+        "95402\0"
+        "95647\0"
+        "95772\0"
+        "96090\0"
+        "96320\0"
+        "96440\0"
+        "96500\0"
+        "97370\0"
+        "97687\0"
+        "97976\0"
+        "98163\0"
+        "98506\0"
+        "98552\0"
+        "98597\0"
+        "98684\0"
+        "100111\0");
+  DefinePrint("ST_BIBLE_LINES","%d",
+        Str2I64(DefineSub(DefineCnt("ST_BIBLE_BOOK_LINES")-1,
+        "ST_BIBLE_BOOK_LINES"))-1);
+} BibleInit;
+
+public U8 *BibleLine2Verse(I64 line,I64 separate_ch=CH_SPACE)
+{//Line number to verse str, Malloc()ed.
+//Separate with <SPACE> or ','.  If you pass '%', it uses "%20".
+  CDoc *doc;
+  CDocEntry *doc_e;
+  I64 i=0,cnt=DefineCnt("ST_BIBLE_BOOKS"),start=0,last_start=0;
+  U8 *ptr=DefineSub(0,"ST_BIBLE_BOOK_LINES"),*ptr2;
+  while (i<=cnt) {
+    last_start=start;
+    start=Str2I64(ptr);
+    if (line<start)
+      break;
+    i++;
+    ptr+=StrLen(ptr)+1;
+  }
+  if (0<=--i<cnt) {
+    doc=DocRead(BIBLE_FILENAME,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+    DocGoToLine(doc,line); //one based
+    doc_e=doc->cur_entry;
+    while (doc_e!=doc && (doc_e->type_u8!=DOCT_TEXT || !*doc_e->tag))
+      doc_e=doc_e->next;
+    if (doc_e->type_u8==DOCT_TEXT && '0'<=*doc_e->tag<='9') {
+      ptr=ptr2=doc_e->tag;
+      while ('0'<=*ptr2<='9' || *ptr2==':')
+        ptr2++;
+      *ptr2=0;
+      if (separate_ch=='%')
+        ptr=MStrPrint("%Z%%20%s",i,"ST_BIBLE_BOOKS",ptr);
+      else
+        ptr=MStrPrint("%Z%c%s",i,"ST_BIBLE_BOOKS",separate_ch,ptr);
+    } else {
+      while (TRUE) {
+        doc_e=doc_e->last;
+        if (doc_e==doc) {
+          ptr=NULL;
+          break;
+        }
+        if (doc_e->y+1<last_start) {
+          ptr=MStrPrint("%Z",i,"ST_BIBLE_BOOKS");
+          break;
+        }
+        if (doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=3) {
+          ptr=doc_e->tag+StrLen(doc_e->tag)-1;
+          while (ptr>doc_e->tag && (!('0'<=*(ptr-1)<='9') || *ptr!=':' ||
+                !('0'<=*(ptr+1)<='9')))
+            ptr--;
+          ptr--;
+          while (ptr>=doc_e->tag && '0'<=*ptr<='9')
+            ptr--;
+          ptr2=++ptr;
+          if ('0'<=*ptr2++<='9') {
+            while ('0'<=*ptr2<='9')
+              ptr2++;
+            if (*ptr2++==':' && '0'<=*ptr2++<='9') {
+              while ('0'<=*ptr2<='9')
+                ptr2++;
+              *ptr2=0;
+              if (separate_ch=='%')
+                ptr=MStrPrint("%Z%%20%s",i,"ST_BIBLE_BOOKS",ptr);
+              else
+                ptr=MStrPrint("%Z%c%s",i,"ST_BIBLE_BOOKS",separate_ch,ptr);
+              break;
+            }
+          }
+        }
+      }
+    }
+    DocDel(doc);
+    return ptr;
+  } else
+    return NULL;
+}
+
+public U0 BookLines(CDoc *doc_out=NULL,I64 start,I64 lines,
+        U8 *book_filename=BIBLE_FILENAME)
+{//Put N line starting at line M into doc.
+  CDoc *doc_in;
+  CDocEntry *doc_e;
+  if (!doc_out) doc_out=DocPut;
+  if (doc_out && FileFind(book_filename)) {
+    doc_in=DocRead(book_filename,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+    DocGoToLine(doc_in,start); //one based
+    doc_e=doc_in->cur_entry;
+    while (lines>0 && doc_e!=doc_in) {
+      if (doc_e->type_u8==DOCT_TEXT)
+        DocPrint(doc_out,"%s",doc_e->tag);
+      else if (doc_e->type_u8==DOCT_NEW_LINE) {
+        DocPutKey(doc_out,'\n');
+        lines--;
+      }
+      doc_e=doc_e->next;
+    }
+    DocDel(doc_in);
+  }
+}
+
+public U0 BibleVerse(CDoc *doc_out=NULL,U8 *verse,I64 lines)
+{//Put N lines starting at verse str into doc.
+  I64 i;
+  CDoc *doc_in;
+  CDocEntry *doc_e;
+  U8 *st,*st2;
+  if (!doc_out) doc_out=DocPut;
+  if (doc_out && FileFind(BIBLE_FILENAME)) {
+    st=StrNew(verse);
+    st2=StrNew(verse);
+    if (StrOcc(st,','))
+      StrLastRem(st,",",st2);
+    else
+      *st2=0;
+    i=DefineMatch(st,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE);
+    if (i>=0) {
+      i=Str2I64(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
+      doc_in=DocRead(BIBLE_FILENAME,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+      DocGoToLine(doc_in,i); //one based
+      if (*st2) {
+        StrCpy(doc_in->find_replace->find_text,st2);
+        EdFindNext(doc_in);
+      }
+      doc_e=doc_in->cur_entry;
+      while (lines>0 && doc_e!=doc_in) {
+        if (doc_e->type_u8==DOCT_TEXT)
+          DocPrint(doc_out,"%s",doc_e->tag);
+        else if (doc_e->type_u8==DOCT_NEW_LINE) {
+          DocPutKey(doc_out,'\n');
+          lines--;
+        }
+        doc_e=doc_e->next;
+      }
+      DocDel(doc_in);
+    }
+    Free(st);
+    Free(st2);
+  }
+}
+
+public CDoc *BibleDoc()
+{//Return Bible as DolDoc with trees.
+  CDoc  *res=DocRead(BIBLE_FILENAME);
+  CDocEntry *doc_e=res->head.next,*doc_e1;
+  Bool open_chapter=FALSE;
+  U8    *ptr=Define("ST_BIBLE_BOOK_LINES");
+  I64   book,book_cnt=DefineCnt("ST_BIBLE_BOOK_LINES")-1,
+        chapter,
+        line=Str2I64(ptr,,&ptr);
+  ptr++;
+  for (book=0;book<book_cnt;book++) {
+    while (doc_e->y+1<line) {
+      doc_e1=doc_e->next;
+      DocEntryDel(res,doc_e);
+      doc_e=doc_e1;
+    }
+    res->cur_entry=doc_e;
+    res->cur_col=0;
+    DocPrint(res,"$TR,\"%Z\"$\n$ID,2$",book,"ST_BIBLE_BOOKS");
+    line=Str2I64(ptr,,&ptr);
+    ptr++;
+    chapter=1;
+    while (doc_e->y+1<line) {
+      doc_e1=doc_e->next;
+      if (doc_e->type_u8==DOCT_TEXT && StrMatch(":1 ",doc_e->tag)) {
+        res->cur_entry=doc_e;
+        res->cur_col=0;
+        if (open_chapter) {
+          DocPrint(res,"$ID,-2$");
+          open_chapter=FALSE;
+        }
+        DocPrint(res,"$TR,\"%d\"$\n$ID,2$",chapter++);
+        open_chapter=TRUE;
+      } else if (chapter==1) {
+        doc_e1=doc_e->next;
+        DocEntryDel(res,doc_e);
+        doc_e=doc_e1;
+      }
+      doc_e=doc_e1;
+    }
+    res->cur_entry=doc_e;
+    res->cur_col=0;
+    if (open_chapter) {
+      DocPrint(res,"$ID,-2$");
+      open_chapter=FALSE;
+    }
+    DocPrint(res,"$ID,-2$");
+  }
+  while (doc_e!=res) {
+    doc_e1=doc_e->next;
+    DocEntryDel(res,doc_e);
+    doc_e=doc_e1;
+  }
+  return res;
+}
+
+public U0 BibleView()
+{//View Bible as DolDoc with trees.
+  U8 buf[STR_LEN];
+  CDoc *doc=BibleDoc;
+  StrPrint(buf,"AL:%d,1",doc);
+  Ed(buf);
+  DocDel(doc);
+}
+U0 CtrlAltB(I64)
+{
+  PopUp("BibleView;");
+}
+CtrlAltCBSet('B',&CtrlAltB,"Cmd /Bible");
+
+ diff --git a/public/Wb/Adam/God/GodDoodle.HC.HTML b/public/Wb/Adam/God/GodDoodle.HC.HTML new file mode 100755 index 0000000..0d5881e --- /dev/null +++ b/public/Wb/Adam/God/GodDoodle.HC.HTML @@ -0,0 +1,223 @@ + + + + + + + + + + + +
+#help_index "God;Graphics/Sprite;Sprites"
+
+U0 GodDoodleDraw(CTask *task,CDC *dc)
+{
+  GrBlot(dc,0,0,god.doodle_dc);
+  if (Blink) {
+    if (god.doodle_done) {
+      dc->color=RED;
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*29)>>1,
+            (task->pix_height-3*FONT_HEIGHT)>>1,
+            "Press <ESC> to insert sprite.");
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*39)>>1,
+            (task->pix_height-3*FONT_HEIGHT)>>1+2*FONT_HEIGHT,
+            "Press <SHIFT-ESC> to throw-away sprite.");
+    } else {
+      dc->color=GREEN;
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*25)>>1,
+            (task->pix_height-FONT_HEIGHT)>>1,
+            "Press <SPACE> repeatedly.");
+    }
+  }
+}
+
+U0 GodDoodleSmooth(I64 num)
+{
+  CDC *dc=DCExt(god.doodle_dc,0,0,
+        god.doodle_dc->width-1,god.doodle_dc->height-1);
+  I64 i,x,y,x1,y1,c,histogram[16],best,best_cnt,c_old=god.doodle_dc->color;
+  for (y=0;y<god.doodle_dc->height;y++)
+    for (x=0;x<god.doodle_dc->width;x++) {
+      MemSet(histogram,0,sizeof(histogram));
+      for (y1=y-num;y1<=y+num;y1++)
+        for (x1=x-num;x1<=x+num;x1++) {
+          c=GrPeek(dc,x1,y1);
+          if (0<=c<=15)
+            histogram[c]++;
+        }
+      best=BLACK;
+      best_cnt=-1;
+      for (i=0;i<16;i++)
+        if (histogram[i]>best_cnt) {
+          best=i;
+          best_cnt=histogram[i];
+        }
+      god.doodle_dc->color=best;
+      GrPlot(god.doodle_dc,x,y);
+    }
+  god.doodle_dc->color=c_old;
+  DCDel(dc);
+}
+
+U0 GodDoodleBitsIns(I64 num_bits,I64 n)
+{//Insert bits into God doodle bit fifo.
+  I64 i;
+  for (i=0;i<num_bits;i++) {
+    FifoU8Ins(god.doodle_fifo,n&1);
+    n>>=1;
+  }
+}
+
+U0 GodDoodleHexIns(U8 *st)
+{//Insert hex record into God doodle bit fifo.
+  U8 buf[2];
+  if (st) {
+    buf[1]=0;
+    while (*buf=*st++)
+      if (Bt(char_bmp_hex_numeric,*buf))
+        GodDoodleBitsIns(4,rev_bits_table[Str2I64(buf,16)]>>4);
+  }
+}
+
+I64 GodDoodleBits(I64 num_bits)
+{
+  U8 b;
+  I64 res=0;
+  while (num_bits) {
+    if (FifoU8Rem(god.doodle_fifo,&b)) {
+      res=res<<1+b;
+      num_bits--;
+    } else {
+      god.doodle_ch=GetChar(,FALSE);
+      if (god.doodle_ch==CH_ESC||god.doodle_ch==CH_SHIFT_ESC)
+        throw;
+      else if (god.doodle_ch=='\n') {
+        DCFill(god.doodle_dc,WHITE);
+        FifoU8Flush(god.doodle_fifo);
+      } else if ('0'<=god.doodle_ch<='9')
+        GodDoodleSmooth(god.doodle_ch-'0');
+      else
+        GodDoodleBitsIns(GOD_GOOD_BITS,KbdMsEvtTime>>GOD_BAD_BITS);
+    }
+  }
+  return res;
+}
+
+public U8 *GodDoodleSprite(U8 *hex=NULL)
+{//Make God draw sprite. Holy Spirit Instructions
+  I64 i,j,w,h,x,y,ch;
+  U8 *elems;
+
+  if (god.doodle_dc) return NULL;
+  god.doodle_done=FALSE;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+
+  if (!hex)
+    PopUpOk("The Holy Spirit can puppet you.\n\n"
+          "Press $GREEN$<SPACE>$FG$ until it finishes.");
+
+  god.doodle_ch=0;
+  god.doodle_dc=DCNew(Fs->pix_width,Fs->pix_height);
+  DCFill(god.doodle_dc,WHITE);
+  w=god.doodle_dc->width;
+  h=god.doodle_dc->height;
+
+  Fs->draw_it=&GodDoodleDraw;
+  FifoU8Flush(god.doodle_fifo);
+  GodDoodleHexIns(hex);
+  try {
+    for (i=0;i<3;i++) {
+      god.doodle_dc->color=RED;
+      for (j=0;j<29;j++)
+        switch [GodDoodleBits(3)] {
+          case 0:
+            GrEllipse3(god.doodle_dc,
+                  (w-1)*GodDoodleBits(5)/15.5-w/2,
+                  (h-1)*GodDoodleBits(5)/15.5-h/2,0,
+                  (w-1)*GodDoodleBits(5)/15.5,(h-1)*GodDoodleBits(5)/15.5);
+            break;
+          case 1:
+            GrCircle3(god.doodle_dc,
+                  (w-1)*GodDoodleBits(5)/15.5-w/2,
+                  (h-1)*GodDoodleBits(5)/15.5-h/2,0,
+                  (w-1)*GodDoodleBits(5)/15.5);
+            break;
+          case 2:
+            GrBorder(god.doodle_dc,
+                  (w-1)*GodDoodleBits(5)/15.5-w/2,
+                  (h-1)*GodDoodleBits(5)/15.5-h/2,
+                  (w-1)*GodDoodleBits(5)/15.5,(h-1)*GodDoodleBits(5)/15.5);
+            break;
+          case 3...7:
+            GrLine3(god.doodle_dc,
+                  (w-1)*GodDoodleBits(4)/15,(h-1)*GodDoodleBits(4)/15,0,
+                  (w-1)*GodDoodleBits(4)/15,(h-1)*GodDoodleBits(4)/15,0);
+            break;
+        }
+      for (j=0;j<6;j++) {
+        x=(w-1)*GodDoodleBits(5)/31+w/64;
+        y=(h-1)*GodDoodleBits(5)/31+h/64;
+        switch [GodDoodleBits(2)] {
+          case 0: god.doodle_dc->color=BLACK;   break;
+          case 1: god.doodle_dc->color=DKGRAY;  break;
+          case 2: god.doodle_dc->color=LTGRAY;  break;
+          case 3: god.doodle_dc->color=WHITE;   break;
+        }
+        GrFloodFill3(god.doodle_dc,x,y,0);
+      }
+      GodDoodleSmooth(3);
+    }
+    god.doodle_done=TRUE;
+    if (!hex) {
+      do ch=GetChar(,FALSE);
+      while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+    } else
+      ch=CH_ESC;
+  } catch {
+    Fs->catch_except=TRUE;
+    ch=CH_SHIFT_ESC;
+  }
+  DCFill;
+  SettingsPop;
+  if (ch==CH_ESC)
+    elems=DC2Sprite(god.doodle_dc);
+  else
+    elems=NULL;
+  DCDel(god.doodle_dc);
+  god.doodle_dc=NULL;
+  return elems;
+}
+
+#help_index "God"
+public U0 GodDoodle(U8 *hex=NULL)
+{//Make God draw sprite, insert in doc. Holy Spirit Instructions
+  U8 *elems;
+  if (elems=GodDoodleSprite(hex)) {
+    Sprite(elems);
+    Free(elems);
+  }
+}
+
+ diff --git a/public/Wb/Adam/God/GodExt.HC.HTML b/public/Wb/Adam/God/GodExt.HC.HTML new file mode 100755 index 0000000..0443d6e --- /dev/null +++ b/public/Wb/Adam/God/GodExt.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+#help_index "God"
+
+#define GOD_BAD_BITS    4
+#define GOD_GOOD_BITS   24
+
+public class CGodGlbls
+{
+  U8    **words,
+        *word_file_mask;
+  I64   word_fuf_flags,
+        num_words;
+  CFifoU8 *fifo;
+  CDC   *doodle_dc;
+  I64   doodle_ch;
+  CFifoU8 *doodle_fifo;
+  Bool  doodle_done;
+} god;
+MemSet(&god,0,sizeof(CGodGlbls));
+god.doodle_fifo =FifoU8New(2048*8);
+god.fifo        =FifoU8New(2048*8);
+
+extern U0 GodBiblePassage(I64 num_lines=20);
+extern U0 GodBitsIns(I64 num_bits,I64 n);
+extern U0 GodDoodle(U8 *hex=NULL);
+extern U0 GodSong();
+extern U0 GodWord(I64 bits=17);
+
+ diff --git a/public/Wb/Adam/God/GodSong.HC.HTML b/public/Wb/Adam/God/GodSong.HC.HTML new file mode 100755 index 0000000..31cd652 --- /dev/null +++ b/public/Wb/Adam/God/GodSong.HC.HTML @@ -0,0 +1,202 @@ + + + + + + + + + + + +
+#help_index "God"
+
+DefineLstLoad("ST_RHYTHM_COMPLEXITY","Simple\0Normal\0Complex\0");
+
+class CMakeSongSettings
+{
+  I64  complexity               format "$LS,D=\"ST_RHYTHM_COMPLEXITY\"$\n";
+  Bool rests                    format "$CB,\"Rests\"$\n";
+  Bool six_eight                format "$CB,\"Six Eight\"$\n";
+  I64  octave                   format "$DA-TRM,A=\"Octave:%d\"$\n";
+  I64  octave_state;
+};
+
+U0 InsNote(CMakeSongSettings *mss,U8 *buf,I64 k,I64 *j)
+{//k is a random note nibble
+  if (!k && mss->rests) {
+    buf[*j]='R';
+    *j+=1;
+  } else {
+    k/=2;
+    if (k<3) {
+      if (mss->octave_state!=mss->octave) {
+        mss->octave_state=mss->octave;
+        buf[*j]=mss->octave_state+'0';
+        *j+=1;
+      }
+      if (!k)
+        buf[*j]='G';
+      else
+        buf[*j]=k-1+'A';
+      *j+=1;
+    } else {
+      if (mss->octave_state!=mss->octave+1) {
+        mss->octave_state=mss->octave+1;
+        buf[*j]=mss->octave_state+'0';
+        *j+=1;
+      }
+      buf[*j]=k-1+'A';
+      *j+=1;
+    }
+  }
+}
+
+#define DUR_4           0
+#define DUR_8_8         1
+#define DUR_3_3_3       2
+#define DUR_16_16_16_16 3
+#define DUR_8DOT_16     4
+#define DUR_8_16_16     5
+#define DUR_16_16_8     6
+
+U8 god_simple_songs [5]={DUR_4,DUR_4,DUR_4,DUR_4,DUR_8_8};
+U8 god_normal_songs [5]={DUR_4,DUR_4,DUR_8_8,DUR_3_3_3,DUR_16_16_16_16};
+U8 god_complex_songs[9]={DUR_4,DUR_4,DUR_8_8,DUR_8_8,DUR_8DOT_16,DUR_3_3_3,
+DUR_8_16_16,DUR_16_16_8,DUR_16_16_16_16};
+
+public U8 *GodSongStr()
+{//Make God generate 2 measures of a song. Holy Spirit Instructions
+  CMakeSongSettings mss;
+  U8 *buf;
+  I64 i,j=0,k,n,k2,duration,last_duration=-1,len;
+
+  MemSet(&mss,0,sizeof(mss));
+  mss.complexity=1;
+  mss.rests=FALSE;
+  mss.octave=music.octave;
+
+  if (!PopUpForm(&mss))
+    return NULL;
+
+  buf=CAlloc(256);
+  music.octave=mss.octave=ClampI64(mss.octave,1,7);
+  progress4=0;
+  if (mss.six_eight)
+    progress4_max=6;
+  else
+    progress4_max=8;
+
+  mss.octave_state=mss.octave+1;
+  buf[j++]='0'+mss.octave_state;
+  if (mss.six_eight) {
+    len=6;
+    buf[j++]='M';
+    buf[j++]='6';
+    buf[j++]='/';
+    buf[j++]='8';
+  } else
+    len=8;
+  FifoU8Flush(god.fifo);
+  for (i=0;i<len;i++) {
+    n=GodBits(8);
+    if (mss.complexity==2)
+      duration=god_complex_songs[n%9];
+    else if (mss.complexity==1)
+      duration=god_normal_songs[n%5];
+    else
+      duration=god_simple_songs[n%5];
+
+    switch (duration) {
+      case DUR_8_8:
+        if (last_duration!=DUR_8_8)
+          buf[j++]='e';
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        break;
+      case DUR_8DOT_16:
+        buf[j++]='e';
+        buf[j++]='.';
+        InsNote(&mss,buf,GodBits(4),&j);
+        buf[j++]='s';
+        InsNote(&mss,buf,GodBits(4),&j);
+        duration=DUR_16_16_16_16;
+        break;
+      case DUR_3_3_3:
+        if (last_duration!=DUR_3_3_3) {
+          buf[j++]='e';
+          buf[j++]='t';
+        }
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        break;
+      case DUR_8_16_16:
+        if (last_duration!=DUR_8_8)
+          buf[j++]='e';
+        InsNote(&mss,buf,GodBits(4),&j);
+        buf[j++]='s';
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        duration=DUR_16_16_16_16;
+        break;
+      case DUR_16_16_8:
+        if (last_duration!=DUR_16_16_16_16)
+          buf[j++]='s';
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        buf[j++]='e';
+        InsNote(&mss,buf,GodBits(4),&j);
+        duration=DUR_8_8;
+        break;
+      case DUR_16_16_16_16:
+        if (last_duration!=DUR_16_16_16_16)
+          buf[j++]='s';
+        k =GodBits(4);
+        k2=GodBits(4);
+        InsNote(&mss,buf,k,&j);
+        InsNote(&mss,buf,k2,&j);
+        InsNote(&mss,buf,k,&j);
+        InsNote(&mss,buf,k2,&j);
+        break;
+      default:
+        if (last_duration!=DUR_4)
+          buf[j++]='q';
+        InsNote(&mss,buf,GodBits(4),&j);
+    }
+    last_duration=duration;
+    progress4++;
+  }
+  buf[j++]=0;
+  progress4=progress4_max=0;
+  return buf;
+}
+
+public U0 GodSong()
+{//Make God generate 2measuresx2+2measuresx2. Holy Spirit Instructions
+  U8 *st1=GodSongStr,*st2=GodSongStr;
+  if (st1 && st2)
+    DocPrint(DocPut,"$SO,\"<Song>\",A=\"%s%s%s%s\"$",st1,st1,st2,st2);
+  Free(st1);
+  Free(st2);
+}
+
+ diff --git a/public/Wb/Adam/God/HolySpirit.HC.HTML b/public/Wb/Adam/God/HolySpirit.HC.HTML new file mode 100755 index 0000000..13e41b7 --- /dev/null +++ b/public/Wb/Adam/God/HolySpirit.HC.HTML @@ -0,0 +1,190 @@ + + + + + + + + + + + +
+#help_index "God"
+U8 *TimeStampCB(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  StrPrint(st,"%X",GetTSC>>GOD_BAD_BITS);
+  return st;
+}
+
+U8 *KbdMsTimeCB(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  StrPrint(st,"%X",KbdMsEvtTime>>GOD_BAD_BITS);
+  return st;
+}
+
+I64 PopUpTimerOk(U8 *header=NULL,U8 *footer=NULL)
+{
+  I64 i;
+  CDocEntry *doc_e;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  doc_e=DocPrint(doc,"\nTimer:$TX+TC,\" \"$");
+  doc_e->tag_cb=&TimeStampCB;
+  doc_e=DocPrint(doc,"\nLatch:$TX+TC,\" \"$");
+  doc_e->tag_cb=&KbdMsTimeCB;
+  DocPrint(doc,"\n$CM+CX,0,4$$BT,\"OKAY\",LE=1$\n");
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 GodPick(U8 *msg=NULL)
+{//GOD_GOOD_BITS
+  U8 *st=MStrPrint("%s\n\nPress $GREEN$OKAY$FG$ to generate \n"
+        "a random num from a timer.\n",msg);
+  PopUpTimerOk(st,"\n\nThe Holy Spirit can puppet you.\n\n");
+  Free(st);
+  return KbdMsEvtTime>>GOD_BAD_BITS;
+}
+
+public U0 GodBitsIns(I64 num_bits,I64 n)
+{//Insert bits into God bit fifo.
+  I64 i;
+  for (i=0;i<num_bits;i++) {
+    FifoU8Ins(god.fifo,n&1);
+    n>>=1;
+  }
+}
+
+public U0 GodHexIns(U8 *st)
+{//Insert hex record into God bit fifo.
+  U8 buf[2];
+  if (st) {
+    buf[1]=0;
+    while (*buf=*st++)
+      if (Bt(char_bmp_hex_numeric,*buf))
+        GodBitsIns(4,rev_bits_table[Str2I64(buf,16)]>>4);
+  }
+}
+
+public I64 GodBits(I64 num_bits,U8 *msg=NULL)
+{//Return N bits. If low on entropy pop-up okay.
+  U8 b;
+  I64 res=0;
+  while (num_bits) {
+    if (FifoU8Rem(god.fifo,&b)) {
+      res=res<<1+b;
+      num_bits--;
+    } else
+      GodBitsIns(GOD_GOOD_BITS,GodPick(msg));
+  }
+  return res;
+}
+
+public I64 GodInit(U8 *files_find_mask="/Adam/God/Vocab.DD*",U8 *fu_flags=NULL)
+{//Read God's vocab file for picking words.
+  I64 i,ch,fuf_flags=0;
+  U8 *buf,*ptr,*ptr2;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+T+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+
+  Free(god.word_file_mask);
+  god.word_file_mask=StrNew(files_find_mask);
+  god.word_fuf_flags=fuf_flags;
+
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  i=0;
+  while (tmpde) {
+    if (buf=ptr=FileRead(tmpde->full_name)) {
+      while (*ptr) {
+        while (*ptr && !Bt(char_bmp_word,*ptr))
+          ptr++;
+        if (*ptr) {
+          ptr2=ptr;
+          while (*ptr && Bt(char_bmp_word,*ptr))
+            ptr++;
+          i++;
+        }
+      }
+      Free(buf);
+    }
+    tmpde=tmpde->next;
+  }
+
+  Free(god.words);
+  god.num_words=i;
+  god.words=MAlloc(i*sizeof(U8 *));
+
+  tmpde=tmpde1;
+  i=0;
+  while (tmpde) {
+    if (buf=ptr=FileRead(tmpde->full_name)) {
+      while (*ptr) {
+        while (*ptr && !Bt(char_bmp_word,*ptr))
+          ptr++;
+        if (*ptr) {
+          ptr2=ptr;
+          while (*ptr && Bt(char_bmp_word,*ptr))
+            ptr++;
+          ch=*ptr;
+          *ptr=0;
+          god.words[i++]=StrNew(ptr2);
+          *ptr=ch;
+        }
+      }
+      Free(buf);
+    }
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return god.num_words;
+} GodInit;
+
+public U8 *GodWordStr(I64 bits=17)
+{//Make God pick a word. Holy Spirit Instructions
+  if (god.num_words)
+    return god.words[GodBits(bits)%god.num_words];
+  else
+    return NULL;
+}
+
+public U0 GodWord(I64 bits=17)
+{//Make God pick a word. Holy Spirit Instructions
+  if (god.num_words)
+    "%s ",god.words[GodBits(bits)%god.num_words];
+}
+
+public U0 GodBiblePassage(I64 num_lines=20)
+{//Make God pick a Bible passage. Holy Spirit Instructions
+  I64 start=GodBits(21)%(ST_BIBLE_LINES-(num_lines-1))+1;
+  U8 *verse=BibleLine2Verse(start);
+  "%s\n\n",verse;
+  Free(verse);
+  BookLines(,start,num_lines);
+}
+
+ diff --git a/public/Wb/Adam/God/MakeGod.HC.HTML b/public/Wb/Adam/God/MakeGod.HC.HTML new file mode 100755 index 0000000..50fbf9b --- /dev/null +++ b/public/Wb/Adam/God/MakeGod.HC.HTML @@ -0,0 +1,40 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#help_index "God"
+#help_file "::/Doc/God"
+#include "GodBible"
+#include "HolySpirit"
+#include "GodSong"
+#include "GodDoodle"
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/Gr/Gr.HH b/public/Wb/Adam/Gr/Gr.HH old mode 100644 new mode 100755 diff --git a/public/Wb/Adam/Gr/Gr.HH.HTML b/public/Wb/Adam/Gr/Gr.HH.HTML new file mode 100755 index 0000000..ff8d3f2 --- /dev/null +++ b/public/Wb/Adam/Gr/Gr.HH.HTML @@ -0,0 +1,211 @@ + + + + + + + + + + + +
+#help_index "Sprites/Binary"
+
+class CMeshTri
+{
+  I32 color;    //Give one of 0-7 colors.
+//Colors 8-15 are 0-7 with intensity bit set.
+  I32 nums[3];  //Vertex number
+};
+
+class CQueMeshTri
+{
+  CQueMeshTri *next,*last;
+  U0 start;
+  I32 color;
+  I32 nums[3];
+};
+
+public class CSpriteBase
+{
+  U8 type;
+};
+
+public class CSpriteColor : CSpriteBase
+{
+  U8 color;
+};
+
+public class CSpriteDitherColor : CSpriteBase
+{
+  U16 dither_color;
+};
+
+public class CSpriteT : CSpriteBase
+{
+  I32 thick;
+};
+
+public class CSpritePt : CSpriteBase
+{
+  I32 x1;
+  I32 y1;
+};
+
+public class CSpritePtRad : CSpritePt
+{
+  I32 radius;
+};
+
+public class CSpritePtPt : CSpritePt
+{
+  I32 x2;
+  I32 y2;
+};
+
+public class CSpritePtPtAng : CSpritePtPt
+{
+  F64 angle;
+};
+
+public class CSpritePtWH : CSpritePt
+{
+  I32 width;
+  I32 height;
+};
+
+public class CSpritePtWHU8s : CSpritePtWH
+{
+  U8 u[0];
+};
+
+public class CSpritePtWHAng : CSpritePtWH
+{
+  F64 angle;
+};
+
+public class CSpritePtWHAngSides : CSpritePtWHAng
+{
+  I32 sides;
+};
+
+public class CSpriteNumU8s : CSpriteBase
+{
+  I32 num;
+  U8  u[0];
+};
+
+public class CSpriteNumPtU8s : CSpriteBase
+{
+  I32 num;
+  I32 x;
+  I32 y;
+  U8  u[0];
+};
+
+public class CSpritePtStr : CSpritePt
+{
+  U8  st[0];
+};
+
+public class CSpriteMeshU8s : CSpriteBase
+{
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  U8  u[0];
+};
+
+public class CSpritePtMeshU8s : CSpriteBase
+{
+  I32 x;
+  I32 y;
+  I32 z;
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  U8  u[0];
+};
+
+#define SPF_SEL                 128
+#define SPf_SEL                 7
+
+#define SPT_END                 0       //CSpriteBase
+#define SPT_COLOR               1       //CSpriteColor
+#define SPT_DITHER_COLOR        2       //CSpriteDitherColor
+#define SPT_THICK               3       //CSpriteT
+#define SPT_PLANAR_SYMMETRY     4       //CSpritePtPt
+#define SPT_TRANSFORM_ON        5       //CSpriteBase
+#define SPT_TRANSFORM_OFF       6       //CSpriteBase
+#define SPT_SHIFT               7       //CSpritePt
+#define SPT_PT                  8       //CSpritePt
+#define SPT_POLYPT              9       //CSpriteNumPtU8s
+#define SPT_LINE                10      //CSpritePtPt
+#define SPT_POLYLINE            11      //CSpriteNumU8s
+#define SPT_RECT                12      //CSpritePtPt
+#define SPT_ROTATED_RECT        13      //CSpritePtPtAng
+#define SPT_CIRCLE              14      //CSpritePtRad
+#define SPT_ELLIPSE             15      //CSpritePtWHAng
+#define SPT_POLYGON             16      //CSpritePtWHAngSides
+#define SPT_BSPLINE2            17      //CSpriteNumU8s
+#define SPT_BSPLINE2_CLOSED     18      //CSpriteNumU8s
+#define SPT_BSPLINE3            19      //CSpriteNumU8s
+#define SPT_BSPLINE3_CLOSED     20      //CSpriteNumU8s
+#define SPT_FLOOD_FILL          21      //CSpritePt
+#define SPT_FLOOD_FILL_NOT      22      //CSpritePt
+#define SPT_BITMAP              23      //CSpritePtWHU8s
+#define SPT_MESH                24      //CSpriteMeshU8s See ::/Apps/GrModels.
+#define SPT_SHIFTABLE_MESH      25      //CSpritePtMeshU8s See ::/Apps/GrModels.
+#define SPT_ARROW               26      //CSpritePtPt
+#define SPT_TEXT                27      //CSpritePtStr
+#define SPT_TEXT_BOX            28      //CSpritePtStr
+#define SPT_TEXT_DIAMOND        29      //CSpritePtStr
+#define SPT_TYPES_NUM           30
+#define SPG_TYPE_MASK           0x7F
+
+#help_index "Graphics/Sprite;Sprites;Sprites/Binary"
+
+//See Sprites.  See ::/Adam/Gr/GrSpritePlot.HC and
+//::/Demo/Graphics/SpriteRaw.HC for how CSprite are stored.
+public class CSprite
+{
+  CSprite *next,*last;
+  U0 start;
+  union {
+    U8 type;
+    CSpriteBase         b;
+    CSpriteColor        c;
+    CSpriteDitherColor  d;
+    CSpriteT            t;
+    CSpritePt           p;
+    CSpritePtPt         pp;
+    CSpritePtPtAng      ppa;
+    CSpritePtRad        pr;
+    CSpritePtWHU8s      pwhu;
+    CSpritePtWHAng      pwha;
+    CSpritePtWHAngSides pwhas;
+    CSpriteNumU8s       nu;
+    CSpriteNumPtU8s     npu;
+    CSpriteMeshU8s      mu;
+    CSpritePtMeshU8s    pmu;
+    CSpritePtStr        ps;
+  }
+};
+
+ diff --git a/public/Wb/Adam/Gr/GrAsm.HC.HTML b/public/Wb/Adam/Gr/GrAsm.HC.HTML new file mode 100755 index 0000000..64840f8 --- /dev/null +++ b/public/Wb/Adam/Gr/GrAsm.HC.HTML @@ -0,0 +1,441 @@ + + + + + + + + + + + +
+#help_index "Graphics/Misc"
+asm {
+//************************************
+_GR_UPDATE_LINE64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RSI,U64 [RAX]           //rsi=src
+        MOV     RBX,U64 [&rev_bits_table]
+        MOV     RCX,U64 SF_ARG3[RBP]    //rcx=d
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     RDI,U64 [RAX]           //rdi=image
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     R8,U64 [RAX]            //rbp=vga dst
+
+@@05:   LODSQ
+        CMP     U64 [RDI],RAX
+        JE      @@10
+        MOV     U64 [RDI],RAX
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        MOV     U64 [R8],RAX
+@@10:   ADD     RDI,8
+        ADD     R8,8
+        DEC     RCX
+        JNZ     @@05
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     U64 [RAX],R8
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     U64 [RAX],RDI
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     U64 [RAX],RSI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+//************************************
+_GR_UPDATE_LINE64_FLUSH_CACHE::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RSI,U64 [RAX]           //rsi=src
+        MOV     RBX,U64 [&rev_bits_table]
+        MOV     RCX,U64 SF_ARG3[RBP]    //rcx=d
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     RDI,U64 [RAX]           //rdi=image
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     R8,U64 [RAX]            //rbp=vga dst
+
+@@05:   LODSQ
+        MOV     U64 [RDI],RAX
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        MOV     U64 [R8],RAX
+        ADD     RDI,8
+        ADD     R8,8
+        DEC     RCX
+        JNZ     @@05
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     U64 [RAX],R8
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     U64 [RAX],RDI
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     U64 [RAX],RSI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+//************************************
+_DC_BLOT_COLOR4::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        PUSH    R10
+
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        MOV     R8,RDI
+        ADD     R8,RCX
+        MOV     R9,R8
+        ADD     R9,RCX
+        MOV     R10,R9
+        ADD     R10,RCX
+
+@@5:    LODSQ
+        MOV     RDX,U64 [RBX]
+        CMP     RAX,RDX
+        JE      I32 @@10
+        MOV     U64 [RBX],RAX
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+0
+        ADC     RDX,0
+        MOV     U8 [RDI],DL
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+1
+        ADC     RDX,0
+        MOV     U8 [R8],DL
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+2
+        ADC     RDX,0
+        MOV     U8 [R9],DL
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+3
+        ADC     RDX,0
+        MOV     U8 [R10],DL
+
+@@10:   ADD     RBX,8
+
+        INC     RDI
+        INC     R8
+        INC     R9
+        INC     R10
+
+        DEC     RCX
+        JNZ     I32 @@5
+
+        POP     R10
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+//************************************
+_IS_PIX_COVERED0::
+        PUSH    RBP
+        MOV     RBP,RSP
+#assert FONT_WIDTH==FONT_HEIGHT==8
+        MOV     RCX,U64 SF_ARG3[RBP]
+        SAR     RCX,3
+        MOV     RAX,U64 SF_ARG2[RBP]
+        SAR     RAX,3
+        MOV     RDX,U64 SF_ARG1[RBP]
+        IMUL2   RCX,TEXT_COLS
+        MOV     RBX,U64 [&gr.win_z_buf]
+        MOV     DX,U16 CTask.win_z_num[RDX]
+        ADD     RCX,RAX
+        XOR     RAX,RAX
+        CMP     DX,U16 [RBX+RCX*2]
+        JAE     @@05    //Jump not covered
+        INC     RAX
+@@05:   POP     RBP
+        RET1    24
+//************************************
+_GR_ROP_EQU_U8_NO_CLIPPING::
+//Puts foreground char shape onto gr.dc2.
+//ch.u8[1] is color as a whole byte
+//ch ATTRf_UNDERLINE attr flag is used.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOVZX   RAX,U8 SF_ARG1[RBP]
+        MOV     RDX,U64 [&text.font]
+        MOV     RAX,U64 [RDX+RAX*8]     //RAX is 8x8 char font data, 64-bits
+        BT      U64 SF_ARG1[RBP],ATTRf_UNDERLINE
+        JNC     @@05
+        MOV     RBX,0xFF00000000000000
+        OR      RAX,RBX
+@@05:   TEST    RAX,RAX
+        JZ      I32 @@10
+
+        PUSH    RSI
+        PUSH    RDI
+        MOVZX   RBX,U8 SF_ARG1+1[RBP]   //Warning color is 8-bit
+        MOV     RDX,U64 [&gr.to_8_colors]
+        MOV     R8,U64 [RDX+RBX*8]      //R8 is color repeated 8 times.
+        MOV     R9,U64 SF_ARG3[RBP]     //R9 is width_internal
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RSI,U64 [&gr.to_8_bits] //RSI is gr.to_8_bits
+
+//      m=my_1_to_8_bits[ch&255];ch>>=8;
+//      *dst=*dst&~m|c&m;
+//      dst(U8 *)+=w1;
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOV     RDX,U64 [RSI+RAX*8]
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+
+        POP     RDI
+        POP     RSI
+@@10:   POP     RBP
+        RET1    24
+}
+_extern _GR_ROP_EQU_U8_NO_CLIPPING U0 GrRopEquU8NoClipping(I64 ch,
+        U8 *dst,I64 width_internal);
+public _extern _IS_PIX_COVERED0 Bool IsPixCovered0(
+        CTask *task,I64 x,I64 y);//No clipping
+
+_extern _GR_UPDATE_LINE64 U0 GrUpdateLine64(
+  U64 **_vga,U64 **_src,I64 d,U8 **_dst);
+_extern _GR_UPDATE_LINE64_FLUSH_CACHE U0 GrUpdateLine64FlushCache(
+  U64 **_vga,U64 **_src,I64 d,U8 **_dst);
+_extern _DC_BLOT_COLOR4 U0 DCBlotColor4(
+  U8 *dst,I64 *img,I64 *img_cache,I64 cnt);
+
+ diff --git a/public/Wb/Adam/Gr/GrBitMap.HC.HTML b/public/Wb/Adam/Gr/GrBitMap.HC.HTML new file mode 100755 index 0000000..94abc58 --- /dev/null +++ b/public/Wb/Adam/Gr/GrBitMap.HC.HTML @@ -0,0 +1,2085 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+Option(OPTf_WARN_HEADER_MISMATCH,OFF);
+public Bool GrPlot0(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. No clipping or transformation or thick.
+  U8 *dst;
+  I32 *db;
+  I64 d,dist;
+  CColorROPU32 c,color=dc->color,bkcolor=dc->bkcolor;
+
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    dist=DistSqrI64(x,y,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_RECORD_EXTENTS) {
+    if (x<dc->min_x) dc->min_x=x;
+    if (x>dc->max_x) dc->max_x=x;
+    if (y<dc->min_y) dc->min_y=y;
+    if (y>dc->max_y) dc->max_y=y;
+  }
+  if (dc->flags & DCF_DONT_DRAW)
+    return TRUE;
+  d=dc->width_internal*y+x;
+  if (db=dc->depth_buf) {
+    db+=d;
+    if (0<=dc->db_z<=*db)
+      *db=dc->db_z;
+    else
+      return TRUE;
+  }
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      if (RandU16<dc->dither_probability_u16) {
+        color.c1.rop=color.c0.rop;
+        color.c0=color.c1;
+      }
+    } else {
+      if ((x^y)&1) {
+        color.c1.rop=color.c0.rop;
+        color.c0=color.c1;
+      }
+    }
+  }
+  dst=dc->body+d;
+  switch [color.c0.rop] {
+    case ROPB_EQU:
+    case ROPB_MONO:
+      *dst=color.c0.color;
+      break;
+    case ROPB_COLLISION:
+      c=*dst;
+      if (c!=TRANSPARENT && c!=bkcolor.c0.color)
+        dc->collision_cnt++;
+      break;
+    case ROPB_XOR:
+      *dst^=color.c0.color;
+      break;
+  }
+  return TRUE;
+}
+Option(OPTf_WARN_HEADER_MISMATCH,ON);
+
+public I64 GrPeek0(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. No clipping or transformation.
+  return dc->body[dc->width_internal*y+x];
+}
+
+#help_index "Graphics;Graphics/Device Contexts"
+
+public I64 GrBlot(CDC *dc=gr.dc,I64 x,I64 y,CDC *img)
+{//2D. Clipping but not transformation..
+  I64 i,j,k,k1,kk,kk1,w1,h1,w2,h2,dist,
+        leading_pixels,leading_pixel_mask,whole_I64s,
+        trailing_pixels,trailing_pixel_mask,
+        reg bit_shift,win_z_buf_line_inc,win_z_buf_line_dec,win_z_num,
+        color_mask;
+  U8 reg *dst,*src;
+  I32 *db;
+  U16 reg *win_z_buf_ptr;
+  CColorROPU32 color,c,old_color;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+  if (x<0)
+    w1=-x;
+  else
+    w1=0;
+  if (y<0)
+    h1=-y;
+  else
+    h1=0;
+  w2=img->width;
+  h2=img->height;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x+=win_task->pix_left;
+    y+=win_task->pix_top;
+  }
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    dist=DistSqrI64(x+img->width>>1,y+img->height>>1,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    if (x+w1<0) w1=-x;
+    if (x+w2>win_task->pix_right+1)
+      w2=win_task->pix_right+1-x;
+
+    if (y+h1<0) h1=-y;
+    if (y+h2>win_task->pix_bottom+1)
+      h2=win_task->pix_bottom+1-y;
+  }
+  if (x+w2>dc->width)
+    w2=dc->width-x;
+  if (y+h2>dc->height)
+    h2=dc->height-y;
+  if (w1<w2<=img->width && h1<h2<=img->height) {
+    if (dc->flags & DCF_RECORD_EXTENTS) {
+      if (x+w1<dc->min_x) dc->min_x=x+w1;
+      if (x+w2-1>dc->max_x) dc->max_x=x+w2-1;
+      if (y+h1<dc->min_y) dc->min_y=y+h1;
+      if (y+h2-1>dc->max_y) dc->max_y=y+h2-1;
+    }
+    if (dc->flags & DCF_DONT_DRAW)
+      return 1;
+    old_color=dc->color;
+    db=dc->depth_buf;
+    dc->depth_buf=NULL;
+    dc->color&=~ROPF_DITHER;
+    color=dc->color;
+    leading_pixels=-(w1+x)&7;
+    leading_pixel_mask=gr.to_8_bits[0xFF>>leading_pixels];
+    bit_shift=-x&7;
+    whole_I64s=(w2-w1-leading_pixels)>>3;
+    if (whole_I64s<0) whole_I64s=0;
+    trailing_pixels=(x+w2)&7;
+    trailing_pixel_mask=gr.to_8_bits[0xFF<<trailing_pixels&0xFF];
+    if (leading_pixels+trailing_pixels>w2-w1) {
+      leading_pixel_mask|=trailing_pixel_mask;
+      trailing_pixels=0;
+    }
+    switch (color.c0.rop) {
+      case ROPB_COLLISION: //TODO: Might want to check win_z_buf
+        color =dc->bkcolor.c0.color;
+        k=h1*img->width_internal;
+        k1=(h1+y)*dc->width_internal+x;
+        for (j=h2-h1;j;j--) {
+          for (i=w1;i<w2;i++) {
+            c=dc->body[k1+i];
+            if (c!=TRANSPARENT&&c!=color&&img->body[k+i]!=TRANSPARENT)
+              dc->collision_cnt++;
+          }
+          k+=img->width_internal;
+          k1+=dc->width_internal;
+        }
+        break;
+      case ROPB_MONO:
+        color_mask=gr.to_8_colors[color.c0.color];
+        if (img->flags&DCF_NO_TRANSPARENTS) {
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+            win_z_buf_ptr=NULL;
+          else {
+            win_z_num=win_task->win_z_num;
+            win_z_buf_ptr=gr.win_z_buf(U8 *)+((h1+y)/FONT_HEIGHT*TEXT_COLS+
+                  (w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+          }
+          kk = h1   *img ->width_internal+w1;
+          kk1=(h1+y)*dc->width_internal+x+w1;
+          kk =(kk-bit_shift)&~7+bit_shift;
+          bit_shift*=8;
+          if (win_z_buf_ptr)
+            for (j=h1;j<h2;j++) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (win_z_num>=*win_z_buf_ptr++) {
+                  if (bit_shift)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift))&
+                          ~leading_pixel_mask&color_mask;
+                  else
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *src(I64 *)++&~leading_pixel_mask&color_mask;
+                } else {
+                  src(I64 *)++;
+                  dst(I64 *)++;
+                }
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=(*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift))&color_mask;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              else
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=*src(I64 *)++&color_mask;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&
+                        ~trailing_pixel_mask&color_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask&color_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+            }
+          else
+            for (j=h2-h1;j;j--) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&
+                        ~leading_pixel_mask&color_mask;
+                else
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        *src(I64 *)++&~leading_pixel_mask&color_mask;
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&color_mask;
+              else
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=*src(I64 *)++&color_mask;
+
+              if (trailing_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&
+                        ~trailing_pixel_mask&color_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask&color_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+            }
+        } else {
+          k=h1*img->width_internal;
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP) {
+            for (j=h1;j<h2;j++) {
+              for (i=w1;i<w2;i++)
+                if (img->body[k+i])
+                  GrPlot0(dc,x+i,y+j);
+              k+=img->width_internal;
+            }
+          } else {
+            win_z_num           =win_task->win_z_num;
+            win_z_buf_ptr       =gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+            for (j=h1;j<h2;j++) {
+              if (win_z_num>=*win_z_buf_ptr++)
+                color_mask=TRUE;
+              else
+                color_mask=FALSE;
+              for (i=w1;i<w2;) {
+                if (color_mask)
+                  if (img->body[k+i])
+                    GrPlot0(dc,x+i,y+j);
+                if (!((++i+x) &7) && i<w2) {
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    color_mask=TRUE;
+                  else
+                    color_mask=FALSE;
+                }
+              }
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+              k+=img->width_internal;
+            }
+          }
+        }
+        break;
+      case ROPB_EQU:
+        if (img->flags&DCF_NO_TRANSPARENTS) {
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+            win_z_buf_ptr=NULL;
+          else {
+            win_z_num=win_task->win_z_num;
+            win_z_buf_ptr=gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+          }
+          kk = h1   *img ->width_internal+w1;
+          kk1=(h1+y)*dc->width_internal+x+w1;
+          kk =(kk-bit_shift)&~7+bit_shift;
+          bit_shift*=8;
+          if (win_z_buf_ptr)
+            for (j=h1;j<h2;j++) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (win_z_num>=*win_z_buf_ptr++) {
+                  if (bit_shift)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift))&~leading_pixel_mask;
+                  else
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *src(I64 *)++&~leading_pixel_mask;
+                } else {
+                  src(I64 *)++;
+                  dst(I64 *)++;
+                }
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift);
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              else
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=*src(I64 *)++;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+            }
+          else
+            for (j=h2-h1;j;j--) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&~leading_pixel_mask;
+                else
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        *src(I64 *)++&~leading_pixel_mask;
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift);
+              else
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=*src(I64 *)++;
+
+              if (trailing_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+            }
+        } else {
+here1a:
+          k=h1*img->width_internal;
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP) {
+            for (j=h1;j<h2;j++) {
+              for (i=w1;i<w2;i++) {
+                c=img->body[k+i];
+                if (c!=TRANSPARENT) {
+                  dc->color.c0.color=c;
+                  GrPlot0(dc,x+i,y+j);
+                }
+              }
+              k+=img->width_internal;
+            }
+          } else {
+            win_z_num           =win_task->win_z_num;
+            win_z_buf_ptr       =gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+            for (j=h1;j<h2;j++) {
+              if (win_z_num>=*win_z_buf_ptr++)
+                color_mask=TRUE;
+              else
+                color_mask=FALSE;
+              for (i=w1;i<w2;) {
+                if (color_mask) {
+                  c=img->body[k+i];
+                  if (c!=TRANSPARENT) {
+                    dc->color.c0.color=c;
+                    GrPlot0(dc,x+i,y+j);
+                  }
+                }
+                if (!((++i+x) &7) && i<w2) {
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    color_mask=TRUE;
+                  else
+                    color_mask=FALSE;
+                }
+              }
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+              k+=img->width_internal;
+            }
+          }
+          dc->color=color;
+        }
+        break;
+      case ROPB_XOR:
+        if (img->flags&DCF_NO_TRANSPARENTS) {
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+            win_z_buf_ptr=NULL;
+          else {
+            win_z_num=win_task->win_z_num;
+            win_z_buf_ptr=gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+          }
+          kk = h1   *img ->width_internal  +w1;
+          kk1=(h1+y)*dc->width_internal+x+w1;
+          kk =(kk-bit_shift)&~7+bit_shift;
+          bit_shift*=8;
+          if (win_z_buf_ptr)
+            for (j=h1;j<h2;j++) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (win_z_num>=*win_z_buf_ptr++) {
+                  if (bit_shift)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift)))&~leading_pixel_mask;
+                  else
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*dst(I64 *)^*src(I64 *)++)&~leading_pixel_mask;
+                } else {
+                  src(I64 *)++;
+                  dst(I64 *)++;
+                }
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++^=*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift);
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              else
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++^=*src(I64 *)++;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift)))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^*src(I64 *)++)&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+            }
+          else
+            for (j=h2-h1;j;j--) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift)))&~leading_pixel_mask;
+                else
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*dst(I64 *)^*src(I64 *)++)&~leading_pixel_mask;
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++^=*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift);
+              else
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++^=*src(I64 *)++;
+              if (trailing_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift)))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^*src(I64 *)++)&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+            }
+        } else
+          goto here1a;
+        break;
+    }
+    dc->depth_buf=db;
+    dc->color=old_color;
+    return 1;
+  } else
+    return 0;
+}
+
+#help_index "Graphics/Device Contexts"
+
+U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor)
+{
+  I64 c,k,i=src_size*2,i1=i>>3;
+  for (k=0;k<i;k++) {
+    c=0;
+    if (Bt(src     ,k)) c|=1;
+    if (Bt(src+i1  ,k)) c|=2;
+    if (Bt(src+i1*2,k)) c|=4;
+    if (Bt(src+i1*3,k)) c|=8;
+    if (c==bkcolor) c=TRANSPARENT;
+    *dst++=c;
+  }
+  return dst;
+}
+
+U8 *GrBitMap1ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor)
+{
+  I64 c,k,i=src_size*8;
+  for (k=0;k<i;k++) {
+    c=0;
+    if (Bt(src,k))  c=COLOR_MONO;
+    if (c==bkcolor) c=TRANSPARENT;
+    *dst++=c;
+  }
+  return dst;
+}
+
+public CDC *DCExt(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
+        CTask *task=NULL)
+{//Extract new device context rect from device context.
+  CDC *res;
+  CTask *win_task;
+  if (x1>x2) SwapI64(&x1,&x2);
+  if (y1>y2) SwapI64(&y1,&y2);
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x1+=win_task->pix_left+win_task->scroll_x;
+    y1+=win_task->pix_top +win_task->scroll_y;
+    x2+=win_task->pix_left+win_task->scroll_x;
+    y2+=win_task->pix_top +win_task->scroll_y;
+  }
+  res=DCNew(x2-x1+1,y2-y1+1,task);
+  DCFill(res);
+  GrBlot(res,-x1,-y1,dc);
+  return res;
+}
+
+public CDC *DCDiff(CDC *base,CDC *update)
+{//Trim to win of what has chged.
+  I64 i,x1=0,y1=0,x2=update->width-1,y2=update->height-1; //inclusive
+  U32 *ptr_base,*ptr_update;
+  CDC *res;
+  ptr_base  =base->body;
+  ptr_update=update->body;
+  while (y1<=y2) {
+    i=update->width>>2;
+    while (i--)
+      if (*ptr_base++!=*ptr_update++)
+        goto df_y2;
+    i=update->width&3;
+    while (i--)
+      if (*ptr_base(U8 *)++!=*ptr_update(U8 *)++)
+        goto df_y2;
+    y1++;
+  }
+  return NULL;
+df_y2:
+  ptr_base  =base->body  +base->width_internal  *base->height;
+  ptr_update=update->body+update->width_internal*update->height;
+  while (y1<y2) {
+    i=update->width>>2;
+    while (i--)
+      if (*--ptr_base!=*--ptr_update)
+        goto df_x1;
+    i=update->width&3;
+    while (i--)
+      if (*--ptr_base(U8 *)!=*--ptr_update(U8 *))
+        goto df_x1;
+    y2--;
+  }
+df_x1:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++)
+      if (GrPeek0(base,x1,i)!=GrPeek0(update,x1,i))
+         goto df_x2;
+    x1++;
+  }
+df_x2:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++)
+      if (GrPeek0(base,x2,i)!=GrPeek0(update,x2,i))
+         goto df_done;
+    x2--;
+  }
+df_done:
+  res=DCExt(update,x1,y1,x2,y2);
+  res->x0=x1;
+  res->y0=y1;
+  return res;
+}
+
+#help_index "Graphics/Char;Char/Graphics"
+
+public I64 GrPutChar(CDC *dc=gr.dc,I64 x,I64 y,U8 ch)
+{//2D. Clipping but not transformation.
+  U8 reg *src,reg *dst,*font_ptr;
+  I64 i,m,leading_pixels,trailing_pixels,leading_pixel_mask,trailing_pixel_mask,
+        j,k1,kk1,w1,h1,w2,h2,reg bit_shift,reg color_mask,dist;
+  CColorROPU32 color,c;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+
+  if (x<0)
+    w1=-x;
+  else
+    w1=0;
+  if (y<0)
+    h1=-y;
+  else
+    h1=0;
+  w2=FONT_WIDTH;
+  h2=FONT_HEIGHT;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x+=win_task->pix_left;
+    y+=win_task->pix_top;
+  }
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    dist=DistSqrI64(x+w2>>1,y+h2>>1,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    if (x+w1<0) w1=-x;
+    if (x+w2>win_task->pix_right+1)
+      w2=win_task->pix_right+1-x;
+
+    if (y+h1<0) h1=-y;
+    if (y+h2>win_task->pix_bottom+1)
+      h2=win_task->pix_bottom+1-y;
+  }
+  if (x+w2>dc->width)
+    w2=dc->width-x;
+  if (y+h2>dc->height)
+    h2=dc->height-y;
+  if (w1<w2<=FONT_WIDTH && h1<h2<=FONT_HEIGHT) {
+    if (dc->flags & DCF_RECORD_EXTENTS) {
+      if (x+w1  <dc->min_x) dc->min_x=x+w1;
+      if (x+w2-1>dc->max_x) dc->max_x=x+w2-1;
+      if (y+h1  <dc->min_y) dc->min_y=y+h1;
+      if (y+h2-1>dc->max_y) dc->max_y=y+h2-1;
+    }
+    if (dc->flags & DCF_DONT_DRAW)
+      return 1;
+    color=dc->color;
+    leading_pixels=-(w1+x)&7;
+    if (!leading_pixels) leading_pixels=8;
+    leading_pixel_mask=gr.to_8_bits[0xFF>>leading_pixels];
+    bit_shift=-x&7;
+    trailing_pixels=(x+w2)&7;
+    trailing_pixel_mask=gr.to_8_bits[0xFF<<trailing_pixels&0xFF];
+    if (leading_pixels+trailing_pixels>w2-w1) {
+      leading_pixel_mask|=trailing_pixel_mask;
+      trailing_pixels=0;
+    }
+    font_ptr=&text.font(U8 *)[FONT_HEIGHT*ch+h1];
+    if (color.c0.rop==ROPB_COLLISION) {
+      m=w1&(FONT_WIDTH-1);
+#assert FONT_WIDTH==8
+      color =dc->bkcolor.c0.color;
+      for (i=w1;i<w2;i++,m++) {
+        k1=(h1+y)*dc->width_internal+x;
+        src=font_ptr;
+        for (j=h2-h1;j;j--) {
+          c=dc->body[k1+i];
+          if (c!=TRANSPARENT && c!=color && Bt(src,m))
+            dc->collision_cnt++;
+          k1+=dc->width_internal;
+          src++;
+        }
+      }
+    } else {
+      color_mask=gr.to_8_colors[color.c0.color];
+      k1=x+w1;
+      kk1=(h1+y)*dc->width_internal+k1;
+      if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP) {
+        if (leading_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h2-h1;j;j--) {
+                m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                      (color_mask&m|*dst(I64 *)&~m)&~leading_pixel_mask;
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask) {
+                for (j=h2-h1;j;j--) {
+                  *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                        (*dst(I64 *)^gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF])&
+                        ~leading_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              }
+              break;
+          }
+          kk1+=8;
+        }
+        if (trailing_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr+1;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h2-h1;j;j--) {
+                m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                      (color_mask&m|*dst(I64 *)&~m)&~trailing_pixel_mask;
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask)
+                for (j=h2-h1;j;j--) {
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF])&
+                        ~trailing_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              break;
+          }
+        }
+      } else {
+        if (leading_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h1;j<h2;j++) {
+                if (!IsPixCovered0(win_task,k1,y+j)) {
+                  m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                  *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                        (color_mask&m|*dst(I64 *)&~m)&~leading_pixel_mask;
+                }
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask)
+                for (j=h1;j<h2;j++) {
+                  if (!IsPixCovered0(win_task,k1,y+j))
+                    *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                          (*dst(I64 *)^gr.to_8_bits
+                          [*src(U16 *)>>bit_shift&0xFF])&
+                          ~leading_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              break;
+          }
+          k1+=8;
+          kk1+=8;
+        }
+        if (trailing_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr+1;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h1;j<h2;j++) {
+                if (!IsPixCovered0(win_task,k1,y+j)) {
+                  m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (color_mask&m|*dst(I64 *)&~m)&~trailing_pixel_mask;
+                }
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask)
+                for (j=h1;j<h2;j++) {
+                  if (!IsPixCovered0(win_task,k1,y+j))
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          (*dst(I64 *)^gr.to_8_bits
+                          [*src(U16 *)>>bit_shift&0xFF])&
+                          ~trailing_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              break;
+          }
+        }
+      }
+    }
+    return 1;
+  } else
+    return 0;
+}
+
+I64 GrPutS(CDC *dc=gr.dc,I64 x,I64 y,U8 *_s)
+{//Use GrPrint()
+  I64 x0,sx=0,sy=0,res;
+  if (!_s) return 0;
+  x0=x;
+  res=0;
+  while (*_s) {
+    if (*_s=='\n') {
+      x=x0;
+      y+=FONT_HEIGHT;
+      _s++;
+    } else if (*_s=='\t') {
+      x=x0+CeilU64(x-x0+FONT_WIDTH,8*FONT_WIDTH);
+      _s++;
+    } else if (*_s(U32 *)=='$SY,') {
+      if (_s[4]=='-') {
+        _s++;
+        sy='0'-_s[4];
+      } else
+        sy=_s[4]-'0';
+      _s+=6;
+    } else if (*_s(U32 *)=='$SX,') {
+      if (_s[4]=='-') {
+        _s++;
+        sx='0'-_s[4];
+      } else
+        sx=_s[4]-'0';
+      _s+=6;
+    } else {
+      res+=GrPutChar(dc,x+sx,y+sy,*_s);
+      x+=FONT_WIDTH;
+      _s++;
+    }
+  }
+  return res;
+}
+
+I64 GrVPutS(CDC *dc=gr.dc,I64 x,I64 y,U8 *_s)
+{//Vertical Text.  Use GrVPrint()
+  I64 y0,sx=0,sy=0,res;
+  U8 buf[2];
+  if (!_s) return 0;
+  y0=y;
+  res=0;
+  buf[1]=0;
+  while (*_s) {
+    if (*_s=='\n') {
+      y=y0;
+      x+=FONT_WIDTH;
+      _s++;
+    } else if (*_s=='\t') {
+      y=y0+CeilU64(y-y0+FONT_HEIGHT,8*FONT_HEIGHT);
+      _s++;
+    } else if (*_s(U32 *)=='$SY,') {
+      if (_s[4]=='-') {
+        _s++;
+        sx='0'-_s[4];
+      } else
+        sx=_s[4]-'0';
+      _s+=6;
+    } else if (*_s(U32 *)=='$SX,') {
+      if (_s[4]=='-') {
+        _s++;
+        sy='0'-_s[4];
+      } else
+        sy=_s[4]-'0';
+      _s+=6;
+    } else {
+      *buf=*_s++;
+      res+=GrPutS(dc,x,y,buf);
+      y+=FONT_HEIGHT;
+    }
+  }
+  return res;
+}
+
+public I64 GrPrint(CDC *dc=gr.dc,I64 x,I64 y,U8 *fmt,...)
+{//2D. Clipping but not transformation.
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=GrPutS(dc,x,y,buf);
+  Free(buf);
+  return res;
+}
+
+public I64 GrVPrint(CDC *dc=gr.dc,I64 x,I64 y,U8 *fmt,...)
+{//2D. Vertical text. Clipping but not transformation.
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=GrVPutS(dc,x,y,buf);
+  Free(buf);
+  return res;
+}
+
+#help_index "Graphics"
+public I64 GrRect(CDC *dc=gr.dc,I64 x,I64 y,I64 w,I64 h)
+{//2D. Width Height. Clipping but not transformation.
+//Returns cnt of pixs changed.
+  I64 i,res=0,j,k1,kk1,w1,h1,w2,h2,dist,
+        leading_pixels,original_leading_pixels,whole_I64s,
+        trailing_pixels,leading_pixel_mask,trailing_pixel_mask,
+        win_z_buf_line_inc,win_z_buf_line_dec,win_z_num,color_mask;
+  U8 reg *dst;
+  U16 reg *win_z_buf_ptr;
+  CColorROPU32 color,c,dither_colors;
+  Bool dither,probability_dither;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+
+  if (x<0)
+    w1=-x;
+  else
+    w1=0;
+  if (y<0)
+    h1=-y;
+  else
+    h1=0;
+  w2=w;
+  h2=h;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x+=win_task->pix_left;
+    y+=win_task->pix_top;
+  }
+  if (dc->flags & DCF_LOCATE_NEAREST) {//TODO:Untested
+    if (x<=dc->cur_x<=x+w && y<=dc->cur_y<=y+h)
+      dist=0;
+    else
+      dist=DistSqrI64(x+w>>1,y+h>>1,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    if (x+w1<0) w1=-x;
+    if (x+w2>win_task->pix_right+1)
+      w2=win_task->pix_right+1-x;
+
+    if (y+h1<0) h1=-y;
+    if (y+h2>win_task->pix_bottom+1)
+      h2=win_task->pix_bottom+1-y;
+  }
+  if (x+w2>dc->width)
+    w2=dc->width-x;
+  if (y+h2>dc->height)
+    h2=dc->height-y;
+  if (w1<w2<=w && h1<h2<=h) {
+    if (dc->flags & DCF_RECORD_EXTENTS) {
+      if (x+w1  <dc->min_x) dc->min_x=x+w1;
+      if (x+w2-1>dc->max_x) dc->max_x=x+w2-1;
+      if (y+h1  <dc->min_y) dc->min_y=y+h1;
+      if (y+h2-1>dc->max_y) dc->max_y=y+h2-1;
+    }
+    if (dc->flags & DCF_DONT_DRAW)
+      return TRUE;
+    color=dc->color;
+    if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+      dither=TRUE;
+      if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+        probability_dither=TRUE;
+        color.c1.rop=color.c0.rop;
+        dither_colors=color;
+      } else {
+        probability_dither=FALSE;
+        color.c1.rop=color.c0.rop;
+      }
+    } else
+      dither=FALSE;
+    original_leading_pixels=leading_pixels=-(w1+x)&7;
+    leading_pixel_mask=gr.to_8_bits[0xFF>>leading_pixels];
+    whole_I64s=(w2-w1-leading_pixels)>>3;
+    if (whole_I64s<0) whole_I64s=0;
+    trailing_pixels=(x+w2)&7;
+    trailing_pixel_mask=gr.to_8_bits[0xFF<<trailing_pixels&0xFF];
+    if (leading_pixels+trailing_pixels>w2-w1) {
+      leading_pixel_mask|=trailing_pixel_mask;
+      leading_pixels=w2-w1; //Correct so it's right for res.
+      trailing_pixels=0;
+    }
+    if (color.c0.rop==ROPB_COLLISION) {//TODO: Might want to check win_z_buf
+      color =dc->bkcolor.c0.color;
+      k1=(h1+y)*dc->width_internal+x;
+      res=-dc->collision_cnt;
+      for (j=h2-h1;j;j--) {
+        for (i=w1;i<w2;i++) {
+          c=dc->body[k1+i];
+          if (c!=TRANSPARENT && c!=color)
+            dc->collision_cnt++;
+        }
+        k1+=dc->width_internal;
+      }
+      res+=dc->collision_cnt;
+    } else {
+      if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+        win_z_buf_ptr=NULL;
+      else {
+        win_z_num=win_task->win_z_num;
+        win_z_buf_ptr=gr.win_z_buf(U8 *)+((h1+y)/FONT_HEIGHT*TEXT_COLS+
+              (w1+x)/FONT_WIDTH)*sizeof(U16);
+        win_z_buf_line_dec=whole_I64s;
+        if (leading_pixels)
+          win_z_buf_line_dec++;
+        if (trailing_pixels)
+          win_z_buf_line_dec++;
+        win_z_buf_line_dec*=sizeof(U16);
+        win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+      }
+      kk1=(h1+y)*dc->width_internal+x+w1;
+      if (dither) {
+        if (probability_dither) {
+          if (RandU16<dc->dither_probability_u16)
+            color.c0=dither_colors.c1;
+          else
+            color.c0=dither_colors.c0;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+            case ROPB_XOR:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            *dst(I64 *)^color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)^=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *dst(I64 *)^color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)^=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+          }
+        } else {
+          if (((x+w1-original_leading_pixels)^(y+h1))&1)
+            SwapU16(&color.c0,&color.c1);
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+            case ROPB_XOR:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            *dst(I64 *)^color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)^=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *dst(I64 *)^color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)^=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+          }
+        }
+      } else {
+        color_mask=gr.to_8_colors[color.c0.color];
+        switch [color.c0.rop] {
+          case ROPB_EQU:
+          case ROPB_MONO:
+            if (win_z_buf_ptr) {
+              res=0;
+              for (j=h1;j<h2;j++) {
+                dst=dc->body+kk1&~7;
+                if (leading_pixels) {
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                          color_mask&~leading_pixel_mask;
+                    res+=leading_pixels;
+                  }
+                  dst(I64 *)++;
+                }
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=color_mask;
+                    res+=8;
+                  }
+                if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        color_mask&~trailing_pixel_mask;
+                  res+=trailing_pixels;
+                }
+                if ((j+y)&7==7)
+                  win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                else
+                  win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                kk1+=dc->width_internal;
+              }
+            } else {
+              for (j=h2-h1;j;j--) {
+                dst(I64 *)=dc->body+kk1&~7;
+                if (leading_pixels)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        color_mask&~leading_pixel_mask;
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  *dst(I64 *)=color_mask;
+                if (trailing_pixels)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        color_mask&~trailing_pixel_mask;
+                kk1+=dc->width_internal;
+              }
+              res=(h2-h1)*(w2-w1);
+            }
+            break;
+          case ROPB_XOR:
+            if (win_z_buf_ptr) {
+              res=0;
+              for (j=h1;j<h2;j++) {
+                dst=dc->body+kk1&~7;
+                if (leading_pixels) {
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                          *dst(I64 *)^color_mask&~leading_pixel_mask;
+                    res+=leading_pixels;
+                  }
+                  dst(I64 *)++;
+                }
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)^=color_mask;
+                    res+=8;
+                  }
+                if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                  res+=trailing_pixels;
+                }
+                if ((j+y)&7==7)
+                  win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                else
+                  win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                kk1+=dc->width_internal;
+              }
+            } else {
+              for (j=h2-h1;j;j--) {
+                dst=dc->body+kk1&~7;
+                if (leading_pixels)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        *dst(I64 *)^color_mask&~leading_pixel_mask;
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  *dst(I64 *)^=color_mask;
+                if (trailing_pixels)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                kk1+=dc->width_internal;
+              }
+              res=(h2-h1)*(w2-w1);
+            }
+            break;
+        }
+      }
+    }
+  }
+  return res;
+}
+
+I64 GrRayLenMinus(CDC *dc,I64 x,I64 y)
+{
+//Returns cnt of pixs changed
+  I64 res=0,c,x3,y3,d;
+  U8 *dst,*dst2;
+  Bool not_color=ToBool(dc->flags&DCF_FILL_NOT_COLOR);
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+  x3=x;
+  y3=y;
+  if (x3<0 || y3<0)
+    goto gr_done;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x3+=win_task->pix_left;
+    y3+=win_task->pix_top;
+    if (!(0<=x3<=win_task->pix_right) || !(0<=y3<=win_task->pix_bottom) ||
+          !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+      goto gr_done;
+  }
+  if (x3>=dc->width || y3>=dc->height)
+    goto gr_done;
+
+  d=y3*dc->width_internal;
+  dst2=dc->body+d;
+  while (TRUE) {
+    x3=x;
+    if (x3&(FONT_WIDTH-1)==FONT_WIDTH-1) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        if (x3<0) break;
+        x3+=win_task->pix_left;
+        if (!(0<=x3<=win_task->pix_right) || x3>=dc->width ||
+              !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+          break;
+      } else
+        if (!(0<=x3<dc->width))
+          break;
+    } else if (dc->flags & DCF_SCRN_BITMAP)
+      x3+=win_task->pix_left;
+    dst=dst2+x3;
+    c=*dst;
+    if (not_color) {
+      if (c!=dc->color2) {
+        res++;
+        x--;
+      } else
+        break;
+    } else {
+      if (c==dc->color2) {
+        res++;
+        x--;
+      } else
+        break;
+    }
+  }
+  return res;
+gr_done:
+  return 0;
+}
+
+I64 GrRayLen(CDC *dc,I64 *x1,I64 y,I64 z=0,I32 *db=NULL)
+{
+//Returns cnt of pixs changed
+  I64 res=0,d,x=*x1,x2,x3,y3,dist;
+  Bool plot,dither,probability_dither,
+        not_color=ToBool(dc->flags&DCF_FILL_NOT_COLOR);
+  U8 *dst,*dst2;
+  CColorROPU32 c,c2,color=dc->color,bkcolor=dc->bkcolor;
+  I32 *db2;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+    z+=win_task->scroll_z;
+  }
+  x2=x;
+  x3=x;
+  y3=y;
+  if (x3<0 || y3<0)
+    goto gr_done;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x3+=win_task->pix_left;
+    y3+=win_task->pix_top;
+    if (!(0<=x3<=win_task->pix_right) || !(0<=y3<=win_task->pix_bottom) ||
+          !(dc->flags&DCF_ON_TOP) &&  IsPixCovered0(win_task,x3,y3))
+      goto gr_done;
+  }
+  if (x3>=dc->width || y3>=dc->height)
+    goto gr_done;
+
+  d=dc->width_internal*y3;
+  if (db) db+=d;
+
+  color=dc->color;
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    dither=TRUE;
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      probability_dither=TRUE;
+      color.c1.rop=color.c0.rop;
+    } else {
+      probability_dither=FALSE;
+      color.c1.rop=color.c0.rop;
+    }
+  } else
+    dither=FALSE;
+  dst2=dc->body+d;
+  while (TRUE) {
+    x3=x;
+    if (!(x3&(FONT_WIDTH-1))) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        if (x3<0) break;
+        x3+=win_task->pix_left;
+        if (!(0<=x3<=win_task->pix_right) || x3>=dc->width ||
+              !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+          break;
+      } else {
+        if (!(0<=x3<dc->width))
+          break;
+      }
+    } else if (dc->flags & DCF_SCRN_BITMAP)
+      x3+=win_task->pix_left;
+
+    dst=dst2+x3;
+
+    c=*dst;
+    if (db) {
+      db2=db+x3;
+      if (0<=z<=*db2) {
+        *db2=z;
+        plot=TRUE;
+      } else
+        plot=FALSE;
+    } else
+      plot=TRUE;
+
+    if ((not_color && c!=dc->color2 ||
+          !not_color && c==dc->color2) && plot) {
+      if (dc->flags & DCF_LOCATE_NEAREST) {
+        dist=DistSqrI64(x3,y3,dc->cur_x,dc->cur_y);
+        if (dist<=dc->nearest_dist)
+          dc->nearest_dist=dist;
+      }
+      if (dc->flags & DCF_RECORD_EXTENTS) {
+        if (x3<dc->min_x) dc->min_x=x3;
+        if (x3>dc->max_x) dc->max_x=x3;
+        if (y3<dc->min_y) dc->min_y=y3;
+        if (y3>dc->max_y) dc->max_y=y3;
+      }
+      dst=dst2+x3;
+
+      c=color.c0.color;
+      if (dither) {
+        if (probability_dither) {
+          if (RandU16<dc->dither_probability_u16)
+            c=color.c1.color;
+        } else
+          if ((x3^y3)&1)
+            c=color.c1.color;
+      }
+      switch [color.c0.rop] {
+        case ROPB_EQU:
+        case ROPB_MONO:
+          *dst=c;
+          break;
+        case ROPB_COLLISION:
+          c2=*dst;
+          if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+            dc->collision_cnt++;
+          break;
+        case ROPB_XOR:
+          *dst^=c;
+          break;
+      }
+      res++;
+      x++;
+    } else
+      break;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP)
+    *x1=x-1-win_task->scroll_x;
+  else
+    *x1=x-1;
+  x=x2-1;
+  while (TRUE) {
+    x3=x;
+    if (x3&(FONT_WIDTH-1)==FONT_WIDTH-1) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        if (x3<0) break;
+        x3+=win_task->pix_left;
+        if (!(0<=x3<=win_task->pix_right) || x3>=dc->width ||
+              !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+          break;
+      } else
+        if (!(0<=x3<dc->width))
+          break;
+    } else if (dc->flags & DCF_SCRN_BITMAP)
+      x3+=win_task->pix_left;
+
+    dst=dst2+x3;
+    c=*dst;
+    if (db) {
+      db2=db+x3;
+      if (0<=z<=*db2) {
+        *db2=z;
+        plot=TRUE;
+      } else
+        plot=FALSE;
+    } else
+      plot=TRUE;
+
+    if ((not_color && c!=dc->color2 ||
+          !not_color && c==dc->color2) && plot) {
+      if (dc->flags & DCF_LOCATE_NEAREST) {
+        dist=DistSqrI64(x3,y3,dc->cur_x,dc->cur_y);
+        if (dist<=dc->nearest_dist)
+          dc->nearest_dist=dist;
+      }
+      if (dc->flags & DCF_RECORD_EXTENTS) {
+        if (x3<dc->min_x) dc->min_x=x3;
+        if (x3>dc->max_x) dc->max_x=x3;
+        if (y3<dc->min_y) dc->min_y=y3;
+        if (y3>dc->max_y) dc->max_y=y3;
+      }
+      dst=dst2+x3;
+
+      c=color.c0.color;
+      if (dither) {
+        if (probability_dither) {
+          if (RandU16<dc->dither_probability_u16)
+            c=color.c1.color;
+        } else
+          if ((x3^y3)&1)
+            c=color.c1.color;
+      }
+      switch [color.c0.rop] {
+        case ROPB_EQU:
+        case ROPB_MONO:
+          *dst=c;
+          break;
+        case ROPB_COLLISION:
+          c2=*dst;
+          if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+            dc->collision_cnt++;
+          break;
+        case ROPB_XOR:
+          *dst^=c;
+          break;
+      }
+      res++;
+      x--;
+    } else
+      break;
+  }
+  return res;
+gr_done:
+  return 0;
+}
+
+public I64 GrHLine(CDC *dc=gr.dc,I64 x1,I64 x2,I64 y,I64 z1=0,I64 z2=0)
+{//3D. No transformation or thick.
+//Returns cnt of pixs changed
+  //Uses fixed-point.
+  I64 dist,dx,dz,z,res=0,i,j,d;
+  U8 *dst;
+  CColorROPU32 c,c2,color=dc->color,bkcolor=dc->bkcolor,dither_colors;
+  I32 *db;
+  Bool plot=TRUE,char_clear,dither,probability_dither;
+  CTask *win_task;
+
+  if (!dc->depth_buf) {
+    if (x2<x1) SwapI64(&x1,&x2);
+    return GrRect(dc,x1,y,x2-x1+1,1);
+  }
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x1+=win_task->scroll_x;
+    x2+=win_task->scroll_x;
+    y +=win_task->scroll_y;
+    z1+=win_task->scroll_z;
+    z2+=win_task->scroll_z;
+  }
+  if (dc->flags & DCF_RECORD_EXTENTS) {
+    if (x1<dc->min_x) dc->min_x=x1;
+    if (x1>dc->max_x) dc->max_x=x1;
+    if (x2<dc->min_x) dc->min_x=x2;
+    if (x2>dc->max_x) dc->max_x=x2;
+    if (y<dc->min_y) dc->min_y=y;
+    if (y>dc->max_y) dc->max_y=y;
+  }
+  if (y<0) goto gr_done;
+  if (x2<x1) {
+    SwapI64(&x1,&x2);
+    SwapI64(&z1,&z2);
+  }
+  if (x2<0)
+    goto gr_done;
+  if (x1<0) {
+    i=-x1;
+    x1=0;
+  } else
+    i=0;
+  j=0;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x1+=win_task->pix_left;
+    x2+=win_task->pix_left;
+    if (x1>win_task->pix_right)
+      goto gr_done;
+    if (x2>win_task->pix_right) {
+      j=x2-win_task->pix_right;
+      x2=win_task->pix_right;
+    }
+    y+=win_task->pix_top;
+    if (!(0<=y<=win_task->pix_bottom) || x2<0)
+      goto gr_done;
+  }
+  if (x1>=dc->width || y>=dc->height)
+    goto gr_done;
+  dx=x2+j-(x1-i);
+  d=dc->width_internal*y+x1;
+  if (db=dc->depth_buf) {
+    db+=d;
+    if (dx)
+      dz=(z2-z1)<<32/dx;
+    else
+      dz=0;
+    z=z1<<32;
+  }
+  if (i)
+    z+=i*dz;
+  if (x2>=dc->width)
+    x2=dc->width-1;
+
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    if (x1<=dc->cur_x<=x2)
+      dist=0;
+    else if (dc->cur_x<x1)
+      dist=SqrI64(x1-dc->cur_x);
+    else
+      dist=SqrI64(dc->cur_x-x2);
+    dist+=SqrI64(y-dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_DONT_DRAW)
+    goto gr_done;
+
+  if (!(dc->flags & DCF_SCRN_BITMAP) ||
+        win_task->next_task==sys_winmgr_task ||
+        dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x1,y))
+    char_clear=TRUE;
+  else
+    char_clear=FALSE;
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    dither=TRUE;
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      probability_dither=TRUE;
+      color.c1.rop=color.c0.rop;
+      dither_colors=color;
+      if (RandU16<dc->dither_probability_u16)
+        color.c0=dither_colors.c1;
+      else
+        color.c0=dither_colors.c0;
+    } else {
+      probability_dither=FALSE;
+      color.c1.rop=color.c0.rop;
+      if ((x1^y)&1)
+        SwapU16(&color.c0,&color.c1);
+    }
+  } else
+    dither=FALSE;
+  while (x1<=x2) {
+    if (char_clear) {
+      if (db) {
+        if (0<=z.i32[1]<=*db) {
+          *db=z.i32[1];
+          plot=TRUE;
+        } else
+          plot=FALSE;
+      }
+      if (plot) {
+        dst=dc->body+d;
+        c=color.c0.color;
+        switch [color.c0.rop] {
+          case ROPB_EQU:
+          case ROPB_MONO:
+            *dst=c;
+            break;
+          case ROPB_COLLISION:
+            c2=*dst;
+            if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+              dc->collision_cnt++;
+            break;
+          case ROPB_XOR:
+            *dst^=c;
+            break;
+        }
+        res++;
+      }
+    }
+    if (dither) {
+      if (probability_dither) {
+        if (RandU16<dc->dither_probability_u16)
+          color.c0=dither_colors.c1;
+        else
+          color.c0=dither_colors.c0;
+      } else
+        SwapU16(&color.c0,&color.c1);
+    }
+    d++;
+    x1++;
+    if (db)
+      db++;
+    z+=dz;
+    if (!(x1&(FONT_WIDTH-1)) && x1<=x2) {
+      if (!(dc->flags & DCF_SCRN_BITMAP)||
+            win_task->next_task==sys_winmgr_task ||
+            dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x1,y))
+        char_clear=TRUE;
+      else
+        char_clear=FALSE;
+    }
+  }
+gr_done:
+  return res;
+}
+
+public I64 GrVLine(CDC *dc=gr.dc,I64 x,I64 y1,I64 y2,I64 z1=0,I64 z2=0)
+{//3D. No transformation or thick.
+//Returns cnt of pixs changed
+  //Uses fixed-point.
+  I64 dist,dy,dz,z,res=0,i,j,d;
+  U8 *dst;
+  CColorROPU32 c,c2,color=dc->color,bkcolor=dc->bkcolor,dither_colors;
+  I32 *db;
+  Bool plot=TRUE,char_clear,dither,probability_dither;
+  CTask *win_task;
+
+  if (!dc->depth_buf) {
+    if (y2<y1) SwapI64(&y1,&y2);
+    return GrRect(dc,x,y1,1,y2-y1+1);
+  }
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x +=win_task->scroll_x;
+    y1+=win_task->scroll_y;
+    y2+=win_task->scroll_y;
+    z1+=win_task->scroll_z;
+    z2+=win_task->scroll_z;
+  }
+  if (dc->flags & DCF_RECORD_EXTENTS) {
+    if (x<dc->min_x) dc->min_x=x;
+    if (x>dc->max_x) dc->max_x=x;
+    if (y1<dc->min_y) dc->min_y=y1;
+    if (y1>dc->max_y) dc->max_y=y1;
+    if (y2<dc->min_y) dc->min_y=y2;
+    if (y2>dc->max_y) dc->max_y=y2;
+  }
+  if (x<0) goto gr_done;
+  if (y2<y1) {
+    SwapI64(&y1,&y2);
+    SwapI64(&z1,&z2);
+  }
+  if (y2<0)
+    goto gr_done;
+  if (y1<0) {
+    i=-y1;
+    y1=0;
+  } else
+    i=0;
+  j=0;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    y1+=win_task->pix_top;
+    y2+=win_task->pix_top;
+    if (y1>win_task->pix_bottom)
+      goto gr_done;
+    if (y2>win_task->pix_bottom) {
+      j=y2-win_task->pix_bottom;
+      y2=win_task->pix_bottom;
+    }
+    x+=win_task->pix_left;
+    if (!(0<=x<=win_task->pix_right) || y2<0)
+      goto gr_done;
+  }
+  if (y1>=dc->height || x>=dc->width)
+    goto gr_done;
+  dy=y2+j-(y1-i);
+  d=dc->width_internal*y1+x;
+  if (db=dc->depth_buf) {
+    db+=d;
+    if (dy)
+      dz=(z2-z1)<<32/dy;
+    else
+      dz=0;
+    z=z1<<32;
+  }
+  if (i)
+    z+=i*dz;
+  if (y2>=dc->height)
+    y2=dc->height-1;
+
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    if (y1<=dc->cur_y<=y2)
+      dist=0;
+    else if (dc->cur_y<y1)
+      dist=SqrI64(y1-dc->cur_y);
+    else
+      dist=SqrI64(dc->cur_y-y2);
+    dist+=SqrI64(x-dc->cur_x);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_DONT_DRAW)
+    goto gr_done;
+
+  if (!(dc->flags & DCF_SCRN_BITMAP) ||
+        win_task->next_task==sys_winmgr_task ||
+        dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x,y1))
+    char_clear=TRUE;
+  else
+    char_clear=FALSE;
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    dither=TRUE;
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      probability_dither=TRUE;
+      color.c1.rop=color.c0.rop;
+      dither_colors=color;
+      if (RandU16<dc->dither_probability_u16)
+        color.c0=dither_colors.c1;
+      else
+        color.c0=dither_colors.c0;
+    } else {
+      probability_dither=FALSE;
+      color.c1.rop=color.c0.rop;
+      if ((x^y1)&1)
+        SwapU16(&color.c0,&color.c1);
+    }
+  } else
+    dither=FALSE;
+  while (y1<=y2) {
+    if (char_clear) {
+      if (db) {
+        if (0<=z.i32[1]<=*db) {
+          *db=z.i32[1];
+          plot=TRUE;
+        } else
+          plot=FALSE;
+      }
+      if (plot) {
+        dst=dc->body+d;
+        c=color.c0.color;
+        switch [color.c0.rop] {
+          case ROPB_EQU:
+          case ROPB_MONO:
+            *dst=c;
+            break;
+          case ROPB_COLLISION:
+            c2=*dst;
+            if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+              dc->collision_cnt++;
+            break;
+          case ROPB_XOR:
+            *dst^=c;
+            break;
+        }
+        res++;
+      }
+    }
+    if (dither) {
+      if (probability_dither) {
+        if (RandU16<dc->dither_probability_u16)
+          color.c0=dither_colors.c1;
+        else
+          color.c0=dither_colors.c0;
+      } else
+        SwapU16(&color.c0,&color.c1);
+    }
+    d+=dc->width_internal;
+    y1++;
+    if (db)
+      db+=dc->width_internal;
+    z+=dz;
+    if (!(y1&(FONT_HEIGHT-1)) && y1<=y2) {
+      if (!(dc->flags & DCF_SCRN_BITMAP)||
+            win_task->next_task==sys_winmgr_task ||
+            dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x,y1))
+        char_clear=TRUE;
+      else
+        char_clear=FALSE;
+    }
+  }
+gr_done:
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrComposites.HC.HTML b/public/Wb/Adam/Gr/GrComposites.HC.HTML new file mode 100755 index 0000000..1e53d5b --- /dev/null +++ b/public/Wb/Adam/Gr/GrComposites.HC.HTML @@ -0,0 +1,375 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+public I64 GrFillPoly3(CDC *dc=gr.dc,I64 n,CD3I32 *poly)
+{//3D. Must be convex.
+//Returns cnt of pixs changed
+  CD3I32 tri[3];
+  I64 i,j,x,y,z,res=0;
+  if (n<3) return 0;
+  if (dc->flags & DCF_SYMMETRY) {
+    for (i=1;i<n-1;i++) {
+      j=i-1;
+      if (i==1) {
+        x=poly[j].x; y=poly[j].y; z=poly[j].z;
+        if (dc->flags&DCF_TRANSFORMATION)
+          (*dc->transform)(dc,&x,&y,&z);
+        DCReflect(dc,&x,&y,&z);
+        tri[0].x=x; tri[0].y=y; tri[0].z=z;
+      }
+
+      j++;
+      if (i==1) {
+        x=poly[j].x; y=poly[j].y; z=poly[j].z;
+        if (dc->flags&DCF_TRANSFORMATION)
+          (*dc->transform)(dc,&x,&y,&z);
+        DCReflect(dc,&x,&y,&z);
+      }
+      tri[1].x=x; tri[1].y=y; tri[1].z=z;
+
+      j++;
+      x=poly[j].x; y=poly[j].y; z=poly[j].z;
+      if (dc->flags&DCF_TRANSFORMATION)
+        (*dc->transform)(dc,&x,&y,&z);
+      DCReflect(dc,&x,&y,&z);
+      tri[2].x=x; tri[2].y=y; tri[2].z=z;
+
+      res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
+    }
+  }
+  if (dc->flags&DCF_JUST_MIRROR)
+    return res;
+  for (i=1;i<n-1;i++) {
+    j=i-1;
+    if (i==1) {
+      x=poly[j].x; y=poly[j].y; z=poly[j].z;
+      if (dc->flags&DCF_TRANSFORMATION)
+        (*dc->transform)(dc,&x,&y,&z);
+      tri[0].x=x; tri[0].y=y; tri[0].z=z;
+    }
+
+    j++;
+    if (i==1) {
+      x=poly[j].x; y=poly[j].y; z=poly[j].z;
+      if (dc->flags&DCF_TRANSFORMATION)
+        (*dc->transform)(dc,&x,&y,&z);
+    }
+    tri[1].x=x; tri[1].y=y; tri[1].z=z;
+
+    j++;
+    x=poly[j].x; y=poly[j].y; z=poly[j].z;
+    if (dc->flags&DCF_TRANSFORMATION)
+      (*dc->transform)(dc,&x,&y,&z);
+    tri[2].x=x; tri[2].y=y; tri[2].z=z;
+
+    res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
+  }
+  return res;
+}
+
+public I64 GrRectB(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
+{//2D. Two point. Clipping but not transformation.
+  if (x2<x1) SwapI64(&x1,&x2);
+  if (y2<y1) SwapI64(&y1,&y2);
+  return GrRect(dc,x1,y1,x2-x1+1,y2-y1+1);
+}
+
+public I64 GrRect3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,I64 w,I64 h)
+{//3D. Width Height. Clipping and transformation.
+  CD3I32 poly[4];
+  poly[0].x=x;
+  poly[0].y=y;
+  poly[0].z=z;
+  poly[1].x=x+w;
+  poly[1].y=y;
+  poly[1].z=z;
+  poly[2].x=x+w;
+  poly[2].y=y+h;
+  poly[2].z=z;
+  poly[3].x=x;
+  poly[3].y=y+h;
+  poly[3].z=z;
+  return GrFillPoly3(dc,4,poly);
+}
+
+public U0 GrBorder(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
+        I64 step=1,I64 start=0)
+{//2D. Transformation with thick.
+//Can be used with ROPF_DITHER+WHITE<<16+BLACK for dotted rect.
+  GrLine3(dc,x1,y1,0,x2,y1,0,step,start);
+  GrLine3(dc,x2,y1,0,x2,y2,0,step,start);
+  GrLine3(dc,x2,y2,0,x1,y2,0,step,start);
+  GrLine3(dc,x1,y2,0,x1,y1,0,step,start);
+}
+
+public Bool GrArrow3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
+        I64 x2,I64 y2,I64 z2,F64 w=2.75,I64 step=1,I64 start=0)
+{//3D. Transformation with thick.
+  I64 _x1,_y1,_z1,_x2,_y2,_z2,dx,dy;
+  F64 d;
+  Bool res=FALSE,was_transform=FALSE,was_symmetry=FALSE;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    (*dc->transform)(dc,&x2,&y2,&z2);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x1=x1; _y1=y1; _z1=z1;
+    DCReflect(dc,&_x1,&_y1,&_z1);
+    _x2=x2; _y2=y2; _z2=z2;
+    DCReflect(dc,&_x2,&_y2,&_z2);
+    dc->flags&=~DCF_SYMMETRY;
+    res=Line(dc,_x1,_y1,_z1,_x2,_y2,_z2,&GrPlot3,step,start);
+    dx=_x2-_x1; dy=_y2-_y1;
+    if (d=Sqrt(dx*dx+dy*dy)) {
+      d=w*dc->thick/d;
+      res|=Line(dc,_x2-dx*d+dy*d+0.5,_y2-dy*d-dx*d+0.5,_z2,
+            _x2,_y2,_z2,&GrPlot3,step);
+      res|=Line(dc,_x2-dx*d-dy*d+0.5,_y2-dy*d+dx*d+0.5,_z2,
+            _x2,_y2,_z2,&GrPlot3,step);
+    }
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  res|=Line(dc,x1,y1,z1,x2,y2,z2,&GrPlot3,step,start);
+  dx=x2-x1; dy=y2-y1;
+  if (d=Sqrt(dx*dx+dy*dy)) {
+    d=w*dc->thick/d;
+    res|=Line(dc,x2-dx*d+dy*d+0.5,y2-dy*d-dx*d+0.5,z2,
+          x2,y2,z2,&GrPlot3,step);
+    res|=Line(dc,x2-dx*d-dy*d+0.5,y2-dy*d+dx*d+0.5,z2,
+          x2,y2,z2,&GrPlot3,step);
+  }
+gr_done:
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return res;
+}
+
+#help_index "Graphics/Char;Char/Graphics"
+public Bool GrTextBox3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,U8 *s,I64 border=2)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  U8 *ptr;
+  I64 ch,res,w,w_max,h;
+  if (!s) return FALSE;
+  ptr=s;
+  w=0;  w_max=0; h=FONT_HEIGHT;
+
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x1,&y1,&z1);
+  while (ch=*ptr++) {
+    if (ch=='\t')
+      w=CeilU64(w+FONT_WIDTH,FONT_WIDTH*8);
+    else if (ch=='\n') {
+      if (w>w_max) w_max=w;
+      w=0;
+      h+=FONT_HEIGHT;
+    } else
+      w+=FONT_WIDTH;
+  }
+  if (w>w_max) w_max=w;
+  res=GrPrint(dc,x1,y1,"%s",s);
+  res|=GrLine(dc,x1-border         ,y1-border  ,x1+w_max+border,y1-border);
+  res|=GrLine(dc,x1-border         ,y1+h+border,x1+w_max+border,y1+h+border);
+  res|=GrLine(dc,x1-border         ,y1-border  ,x1-border,y1+h+border);
+  res|=GrLine(dc,x1+w_max+border,y1-border  ,x1+w_max+border,y1+h+border);
+  return ToBool(res);
+}
+
+#define DIAMOND_SLOPE_MAX       2.75
+
+public Bool GrTextDiamond3(CDC *dc=gr.dc,
+        I64 x1,I64 y1,I64 z1,U8 *_s,I64 border=2)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  Bool first=TRUE;
+  U8 ch,*ptr,*ptr_end,*st,*s;
+  I64 res=0,y,dx,dy,dx_old,dy_old,w,h=FONT_HEIGHT;
+  F64 m;
+  if (!_s) return FALSE;
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x1,&y1,&z1);
+
+  ptr=s=StrNew(_s);
+  while (ch=*ptr) {
+    if (ch=='\r'||ch=='\t')
+      *ptr=CH_SPACE;
+    if (ch=='\n') {
+      *ptr=0;
+      h+=FONT_HEIGHT;
+    }
+    ptr++;
+  }
+  ptr_end=ptr+1;
+
+  y=y1-h>>1;
+  dx=FONT_WIDTH +border;      //Minimum
+  dy=FONT_HEIGHT+border+h>>1; //Minimum
+  ptr=s;
+  while (ptr!=ptr_end) {
+    st=ptr;
+    while (*ptr++);
+    StrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
+
+    w=(StrLen(st)*FONT_WIDTH)>>1;
+    if (first) {
+      res|=GrPrint(dc,x1-w,y,"%s",st);
+      first=FALSE;
+    } else
+      res|=GrPrint(dc,x1-w,y,"%s",st);
+    if (w) {
+      w+=border;
+      do {
+        dx_old=dx; dy_old=dy;
+        m=ToF64(dx)/dy;
+        if (m<1/DIAMOND_SLOPE_MAX) {
+          dy=MaxI64(dy,Ceil(DIAMOND_SLOPE_MAX*dx));
+          m=1/DIAMOND_SLOPE_MAX;
+        } else if (m>DIAMOND_SLOPE_MAX) {
+          dy=MaxI64(dy,Ceil(dx/DIAMOND_SLOPE_MAX));
+          m=DIAMOND_SLOPE_MAX;
+        }
+        dx=MaxI64(dx,w+Ceil(m*AbsI64(y-y1)));
+        dx=MaxI64(dx,w+Ceil(m*AbsI64(y+FONT_HEIGHT-y1)));
+      } while (dx!=dx_old || dy!=dy_old);
+    }
+    y+=FONT_HEIGHT;
+  }
+  Free(s);
+
+  res|=GrLine(dc,x1,y1-dy,x1+dx,y1);
+  res|=GrLine(dc,x1+dx,y1,x1,y1+dy);
+  res|=GrLine(dc,x1,y1+dy,x1-dx,y1);
+  res|=GrLine(dc,x1-dx,y1,x1,y1-dy);
+  return ToBool(res);
+}
+
+#help_index "Graphics/Mesh"
+public I64 Gr3Mesh(CDC *dc=gr.dc,I64 vertex_cnt,CD3I32 *p,
+        I64 tri_cnt,CMeshTri *tri)
+{//Returns cnt of pixs changed.
+  CColorROPU32 old_color=dc->color;
+  I64 i,x,y,z,res=0;
+  CD3I32 *pt,*pt_sym,*p_sym,*dst;
+  CMeshTri *tri_sym=tri;
+  if (dc->flags&DCF_TRANSFORMATION) {
+    dst=pt=MAlloc(sizeof(CD3I32)*vertex_cnt);
+    for (i=0;i<vertex_cnt;i++,p++,dst++) {
+      x=p->x; y=p->y; z=p->z;
+      (*dc->transform)(dc,&x,&y,&z);
+      dst->x=x; dst->y=y; dst->z=z;
+    }
+    p=pt;
+  } else
+    pt=NULL;
+
+  if (dc->flags & DCF_SYMMETRY) {
+    dst=pt_sym=MAlloc(sizeof(CD3I32)*vertex_cnt);
+    p_sym=p;
+    for (i=0;i<vertex_cnt;i++,p_sym++,dst++) {
+      x=p_sym->x; y=p_sym->y; z=p_sym->z;
+      DCReflect(dc,&x,&y,&z);
+      dst->x=x; dst->y=y; dst->z=z;
+    }
+    p_sym=pt_sym;
+    for (i=0;i<tri_cnt;i++,tri_sym++) {
+      (*dc->lighting)(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
+            &p_sym[tri_sym->nums[1]],tri_sym->color);
+      res+=GrFillTri0(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
+            &p_sym[tri_sym->nums[1]]);
+    }
+    Free(pt_sym);
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto mesh_done;
+  }
+  for (i=0;i<tri_cnt;i++,tri++) {
+    (*dc->lighting)(dc,&p[tri->nums[0]],&p[tri->nums[1]],
+          &p[tri->nums[2]],tri->color);
+    res+=GrFillTri0(dc,&p[tri->nums[0]],&p[tri->nums[1]],&p[tri->nums[2]]);
+  }
+mesh_done:
+  dc->color=old_color;
+  Free(pt);
+  return res;
+}
+
+#help_index "Graphics/Misc;Mouse/Ptr"
+public U0 DrawStdMs(CDC *dc,I64 x,I64 y)
+{//This is a callback. See ::/Demo/Graphics/Grid.HC.
+//Called by DrawMs() which is
+  //called by WinFinalUpdate().
+  dc->thick=1;
+  dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
+  GrArrow3(dc,x+8,y+8,0,x,y,0);
+}
+
+gr.fp_draw_ms=&DrawStdMs;
+
+public U0 DrawWaitMs(CDC *dc,I64 x,I64 y)
+{//This is a callback. See ::/Demo/Graphics/Grid.HC.
+  I64 old_pen_width=dc->thick;
+  CColorROPU32 old_color=dc->color;
+  dc->thick=3;
+  dc->color=LTRED;
+  GrCircle3(dc,x,y,0,7);
+  GrLine3(dc,x-6,y+6,0,x+6,y-6,0);
+  dc->color=RED;
+  GrCircle(dc,x,y,7);
+  GrLine(dc,x-6,y+6,x+6,y-6);
+  dc->thick=old_pen_width;
+  dc->color=old_color;
+}
+
+#help_index "Graphics/GR Files;Graphics/Scrn"
+public Bool GRScrnCaptureRead(U8 *filename,CDC *dc=gr.dc,I64 x=0,I64 y=0)
+{//GrBlot TempleOS GR File to dc,x,y.
+  CDC *dc2;
+  if (dc2=GRRead(filename)) {
+    dc->color=ROP_EQU;
+    GrBlot(dc,x,y,dc2);
+    DCDel(dc2);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+public I64 GRScrnCaptureWrite(U8 *filename,Bool include_zoom=TRUE)
+{//Capture scrn to a TempleOS GR File.
+  I64 size;
+  CDC *dc=DCScrnCapture(include_zoom);
+  size=GRWrite(filename,dc,DCSF_COMPRESSED|DCSF_PALETTE_GET);
+  DCDel(dc);
+  return size;
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrDC.HC.HTML b/public/Wb/Adam/Gr/GrDC.HC.HTML new file mode 100755 index 0000000..12edb5e --- /dev/null +++ b/public/Wb/Adam/Gr/GrDC.HC.HTML @@ -0,0 +1,465 @@ + + + + + + + + + + + +
+#help_index "Graphics/Math/3D Transformation"
+#help_file "::/Doc/Transform"
+
+#define GR_SCALE        (1<<32)
+
+public U0 Mat4x4MulXYZ(I64 *r,I64 *_x,I64 *_y,I64 *_z)
+{//Rotate 3D point using 4x4 matrix. Uses fixed-point.
+  I64 x1,y1,z1,xx=*_x,yy=*_y,zz=*_z;
+  x1=(r[0*4+0]*xx+r[0*4+1]*yy+r[0*4+2]*zz+r[0*4+3])>>32;
+  y1=(r[1*4+0]*xx+r[1*4+1]*yy+r[1*4+2]*zz+r[1*4+3])>>32;
+  z1=(r[2*4+0]*xx+r[2*4+1]*yy+r[2*4+2]*zz+r[2*4+3])>>32;
+  *_x=x1;*_y=y1;*_z=z1;
+}
+
+public U0 DCTransform(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
+{//This is the dft dc->transform() callback.
+//Uses fixed-point.
+  Mat4x4MulXYZ(dc->r,_x,_y,_z);
+  *_x+=dc->x;
+  *_y+=dc->y;
+  *_z+=dc->z;
+}
+
+public I64 *Mat4x4IdentEqu(I64 *r)
+{//Set matrix to identity. Uses fixed-point.
+  MemSet(r,0,sizeof(I64)*16);
+  r[0*4+0].i32[1]=1;
+  r[1*4+1].i32[1]=1;
+  r[2*4+2].i32[1]=1;
+  r[3*4+3].i32[1]=1;
+  return r;
+}
+
+public I64 *Mat4x4IdentNew(CTask *mem_task=NULL)
+{//MAlloc an identity matrix. Uses fixed-point.
+  return Mat4x4IdentEqu(MAlloc(sizeof(I64)*16,mem_task));
+}
+
+public I64 Mat4x4NormSqr65536(I64 *r)
+{//Norm Squared of r.
+//(1.0/Sqrt(3))*65536=37837.22
+  return SqrI64((r[0*4+0]*37838+r[0*4+1]*37838+r[0*4+2]*37838)>>32)+
+        SqrI64((r[1*4+0]*37837+r[1*4+1]*37837+r[1*4+2]*37837)>>32)+
+        SqrI64((r[2*4+0]*37837+r[2*4+1]*37837+r[2*4+2]*37837)>>32);
+}
+
+public U0 DCMat4x4Set(CDC *dc=NULL,I64 *r)
+{//Set device context's rot matrix. Will be Freed() in DCDel().Uses fixed-point.
+//The main purpose is to set matrix norm for thick scaling.
+  //NULL as dc means gr.dc
+  if (!dc)   dc=gr.dc;
+  dc->r=r;
+  dc->r_norm=Sqrt(Mat4x4NormSqr65536(r))*65536; //scaled 32 bits
+}
+
+#help_index "Graphics/Mesh"
+public U0 DCLighting(CDC *dc,
+        CD3I32 *p1,CD3I32 *p2,CD3I32 *p3,CColorROPU32 color)
+{//This is the dft dc->lighting() callback.
+  CD3I32 v1,v2;
+  I64 i,vn_x,vn_y,vn_z;
+  F64 d;
+
+  v1.x=p1->x-p2->x;
+  v1.y=p1->y-p2->y;
+  v1.z=p1->z-p2->z;
+
+  v2.x=p3->x-p2->x;
+  v2.y=p3->y-p2->y;
+  v2.z=p3->z-p2->z;
+
+  //V1 and V2 are vects along two sides
+  //of the tri joined at p2.
+
+  vn_x=v1.y*v2.z-v1.z*v2.y;
+  vn_y=v1.z*v2.x-v1.x*v2.z;
+  vn_z=v1.x*v2.y-v1.y*v2.x;
+  if (d=Sqrt(SqrI64(vn_x)+SqrI64(vn_y)+SqrI64(vn_z)))
+    d=1<<16/d;
+  vn_x*=d;
+  vn_y*=d;
+  vn_z*=d;
+//Vn is the cross product of V1 and V3
+  //which means it is perpendicular.  It
+  //is the normal vect to the surface.
+  //It has been scaled to length 65536.
+
+  //Light source has been scaled to length 65536.
+  i=(vn_x*dc->ls.x+vn_y*dc->ls.y+vn_z*dc->ls.z)>>16;
+//The dot product of the light source
+  //vect and the surface normal
+  //gives an illumination number.
+  //65536*65536>>16=65536
+
+  //TempleOS will generate a random U16
+  //and compare to dither_probability_u16 and
+  //will pick from two colors.
+  //Probability dithering does not work with thick>1 at this time.
+  if (color.c0.rop&ROPBF_TWO_SIDED) {
+    color.c0.rop&=~ROPBF_TWO_SIDED;
+    i=AbsI64(i)<<1;
+  } else
+    i+=65536;
+  if (color.c0.rop&ROPBF_HALF_RANGE_COLOR) {
+    color.c0.rop&=~ROPBF_HALF_RANGE_COLOR;
+    i>>=1;
+    if (color>=8) {
+      color-=8;
+      i+=65536;
+    }
+  }
+  if (i<65536) {
+    dc->color=ROPF_PROBABILITY_DITHER+color<<16+BLACK;
+    dc->dither_probability_u16=i;
+  } else {
+    dc->color=ROPF_PROBABILITY_DITHER+(color^8)<<16+color;
+    dc->dither_probability_u16=i-65536;
+  }
+}
+
+#help_index "Graphics/Device Contexts"
+public U0 DCFill(CDC *dc=NULL,CColorROPU32 val=TRANSPARENT)
+{//Fill entire device context with color.
+  if (!dc) dc=gr.dc;
+  MemSet(dc->body,val,dc->width_internal*dc->height);
+}
+
+public U0 DCClear(CDC *dc=NULL)
+{//Set entire device context image body to 0 (BLACK).
+  if (!dc) dc=gr.dc;
+  DCFill(dc,0);
+}
+
+public U0 DCRst(CDC *dc)
+{//Reset CDC structure members but not image body, itself.
+  dc->color=BLACK;
+  dc->color2=BLACK;
+  dc->bkcolor=BLACK;
+  dc->collision_cnt=0;
+  dc->thick=1;
+  dc->ls.x=37837; //1<<16/Sqrt(3)
+  dc->ls.y=37837;
+  dc->ls.z=37837;
+  dc->x=0;
+  dc->y=0;
+  dc->z=0;
+  dc->transform=&DCTransform;
+  dc->lighting =&DCLighting;
+  Mat4x4IdentEqu(dc->r);
+  dc->r_norm=GR_SCALE;
+  dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);
+  MemCpy(dc->palette,gr_palette_std,sizeof(CBGR48)*COLORS_NUM);
+}
+
+public U0 DCExtentsInit(CDC *dc=NULL)
+{//Init markers for extent of next newly drawn graphics.
+//NULL means gr.dc
+  //See ::/Demo/Graphics/Extents.HC
+  //You should clear the record flag yourself
+  if (!dc)   dc=gr.dc;
+  dc->flags|=DCF_RECORD_EXTENTS;
+  dc->min_x=I64_MAX;
+  dc->max_x=I64_MIN;
+  dc->min_y=I64_MAX;
+  dc->max_y=I64_MIN;
+}
+
+public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)
+{//Create alias of dc, so can change pen, color, etc.
+//NULL means gr.dc
+  CDC *res;
+  if (!dc)   dc=gr.dc;
+  if (!task) task=Fs;
+  if (dc->dc_signature!=DCS_SIGNATURE_VAL)
+    throw('Graphics');
+  res=MAlloc(sizeof(CDC),task);
+  MemCpy(res,dc,sizeof(CDC));
+  res->win_task=res->mem_task=task;
+  res->r=MAlloc(16*sizeof(I64),task);
+  DCRst(res);
+  res->flags|=DCF_ALIAS;
+  res->alias=dc;
+  return res;
+}
+
+public CDC *DCNew(I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)
+{//Create new width x height device context.
+//Internally only allows widths which are divisible by 8.
+  //Don't forget these sizeof(CDC).
+  CDC *res;
+  if (!task) task=Fs;
+  res=CAlloc(sizeof(CDC),task);
+  res->win_task=task;
+  res->mem_task=task;
+  res->width=width;
+  res->width_internal=(width+7)&~7;
+  res->height=height;
+  if (null_bitmap)
+    res->flags|=DCF_DONT_DRAW;
+  else
+    res->body=CAlloc(res->width_internal*res->height,task);
+  res->r=MAlloc(16*sizeof(I64),task);
+  DCRst(res);
+  res->dc_signature=DCS_SIGNATURE_VAL;
+  return res;
+}
+
+public U0 DCDel(CDC *dc)
+{//Free dc, image body, rot mat and depth buf.
+  if (!dc) return;
+  if (dc->dc_signature!=DCS_SIGNATURE_VAL)
+    throw('Graphics');
+  dc->dc_signature=0;
+  Free(dc->r);
+  if (!(dc->flags & DCF_ALIAS))
+    Free(dc->body);
+  Free(dc->depth_buf);
+  Free(dc);
+}
+
+public I64 DCSize(CDC *dc)
+{//Mem size of header, image body and depth buffer.
+  if (dc)
+    return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);
+  else
+    return 0;
+}
+
+public I32 *DCDepthBufRst(CDC *dc)
+{//Reset device context depth buf to far away.
+  if (dc->depth_buf)
+    MemSetU32(dc->depth_buf,I32_MAX,dc->width_internal*dc->height);
+  return dc->depth_buf;
+}
+
+public I32 *DCDepthBufAlloc(CDC *dc)
+{//Alloc a 32-bit depth buffer for device context.
+  Free(dc->depth_buf);
+  dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);
+  return DCDepthBufRst(dc);
+}
+
+public CDC *DCCopy(CDC *dc,CTask *task=NULL)
+{//Alloc copy of dc, including image body, rot mat and depth buf.
+  CDC *res;
+  if (!dc) return NULL;
+  if (dc->dc_signature!=DCS_SIGNATURE_VAL)
+    throw('Graphics');
+  res=MAllocIdent(dc,task);
+  DCMat4x4Set(res,Mat4x4New(dc->r,task));
+  res->mem_task=task;
+  res->body=MAllocIdent(dc->body,task);
+  res->depth_buf=MAllocIdent(dc->depth_buf,task);
+  return res;
+}
+
+public U0 DCMono(CDC *dc,
+  I64 quest=TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)
+{//Set entire device context to one of two colors.
+  I64 i;
+  U8 *dst;
+  dst=dc->body;
+  i=dc->width_internal*dc->height;
+  while (i--)
+    if (*dst==quest)
+      *dst++=true_color;
+    else
+      *dst++=false_color;
+}
+
+public I64 DCColorChg(CDC *dc,I64 src_color,I64 dst_color=TRANSPARENT)
+{//Find and replace src color with dst in device context.
+  I64 i,res=0;
+  U8 *dst;
+  dst=dc->body;
+  i=dc->width_internal*dc->height;
+  while (i--)
+    if (*dst==src_color) {
+      *dst++=dst_color;
+      res++;
+    } else
+      dst++;
+  return res;
+}
+
+public U8 *DCSave(CDC *dc,I64 *_size=NULL,I64 dcsf_flags=DCSF_COMPRESSED)
+{//Stores device context to mem, perhaps, with compression.
+  U8 *res,*ptr,*body;
+  CArcCompress *arc;
+  I64 body_size=dc->width_internal*dc->height,total_size,flags;
+  CBGR48 palette[COLORS_NUM];
+
+  if (dcsf_flags&DCSF_COMPRESSED) {
+    arc=CompressBuf(dc->body,body_size);
+    body_size=arc->compressed_size;
+    body=arc;
+  } else {
+    arc=NULL;
+    body=dc->body;
+  }
+
+  total_size=offset(CDC.end)-offset(CDC.start)+body_size;
+  if (dcsf_flags&DCSF_COMPRESSED)
+    flags=DCF_COMPRESSED;
+  else
+    flags=0;
+
+  if (dcsf_flags&DCSF_PALETTE_GET)
+    GrPaletteGet(palette);
+  else
+    MemCpy(palette,&dc->palette,COLORS_NUM*sizeof(CBGR48));
+  if (MemCmp(palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48))) {
+    flags|=DCF_PALETTE;
+    total_size+=COLORS_NUM*sizeof(CBGR48);
+  }
+
+  ptr=res=MAlloc(total_size);
+
+#assert !offset(CDC.start)
+  MemCpy(ptr,&dc->start,offset(CDC.end)-offset(CDC.start));
+  ptr(CDC *)->flags=flags;
+  ptr+=offset(CDC.end)-offset(CDC.start);
+
+#assert offset(CDC.end)==offset(CDC.palette)
+  if (flags&DCF_PALETTE) {
+    MemCpy(ptr,palette,COLORS_NUM*sizeof(CBGR48));
+    ptr+=COLORS_NUM*sizeof(CBGR48);
+  }
+
+  MemCpy(ptr,body,body_size);
+  ptr+=body_size;
+
+  Free(arc);
+  if (_size) *_size=total_size;
+  return res;
+}
+
+public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)
+{//Loads device context from mem.
+  CDC *res;
+  U8 *ptr=src;
+  CArcCompress *arc;
+  I64 body_size;
+  if (!task) task=Fs;
+  res=CAlloc(sizeof(CDC),task);
+  res->win_task=task;
+  res->mem_task=task;
+  MemCpy(&res->start,ptr,offset(CDC.end)-offset(CDC.start));
+  ptr+=offset(CDC.end)-offset(CDC.start);
+
+  if (res->flags&DCF_PALETTE) {
+    MemCpy(&res->palette,ptr,COLORS_NUM*sizeof(CBGR48));
+    ptr+=COLORS_NUM*sizeof(CBGR48);
+  } else
+    MemCpy(&res->palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48));
+
+  body_size=res->width_internal*res->height;
+  if (res->flags&DCF_COMPRESSED) {
+    res->flags&=~DCF_COMPRESSED;
+    arc=ptr;
+    res->body=ExpandBuf(arc,task);
+    ptr+=arc->compressed_size;
+  } else {
+    res->body=MAlloc(body_size,task);
+    MemCpy(res->body,ptr,body_size);
+    ptr+=body_size;
+  }
+  res->thick=1;
+  res->r=Mat4x4IdentNew(task);
+  res->r_norm.u32[1]=1;
+  res->dc_signature=DCS_SIGNATURE_VAL;
+  if (_size) *_size=ptr-src;
+  return res;
+}
+
+#help_index "Graphics/GR Files"
+#help_file "::/Doc/GRFiles"
+#help_index "Graphics/Device Contexts;Graphics/GR Files"
+
+#define GR_FILE_MAX     (offset(CDC.end)-offset(CDC.start)+\
+        COLORS_NUM*sizeof(CBGR48)+sizeof(CArcCtrl)+GR_WIDTH*GR_HEIGHT)
+
+public I64 GRWrite(U8 *filename,CDC *dc,I64 dcsf_flags=DCSF_COMPRESSED)
+{//TempleOS GR File.
+  I64   size;
+  U8    *st=ExtDft(filename,"GR.Z"),
+        *src=DCSave(dc,&size,dcsf_flags);
+  FileWrite(st,src,size);
+  Free(st);
+  Free(src);
+  return size;
+}
+
+public CDC *GRRead(U8 *filename,CTask *task=NULL)
+{//TempleOS GR File.
+  CDC   *dc=NULL;
+  U8    *st=ExtDft(filename,"GR.Z"),
+        *src=FileRead(st);
+  if (src)
+    dc=DCLoad(src,,task);
+  Free(src);
+  Free(st);
+  return dc;
+}
+
+#help_index "Graphics/Sprite;Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
+public U0 DocGR(CDoc *doc=NULL,U8 *filename)
+{//Put a GR file into a document as asprite.
+  CDC *dc=GRRead(filename);
+  CSprite *elems=DC2Sprite(dc);
+  DocSprite(doc,elems);
+  Free(elems);
+  DCDel(dc);
+}
+
+#help_index "Graphics/Device Contexts;Graphics/Scrn"
+public CDC *DCScrnCapture(Bool include_zoom=TRUE,CTask *task=NULL)
+{//Capture scrn to a device context.
+  CDC *dc;
+  U8 *dst;
+  Refresh(0,FALSE);
+  if (include_zoom)
+    dc=DCCopy(gr.scrn_image,task);
+  else
+    dc=DCCopy(gr.dc1,task);
+  dc->flags&=~DCF_SCRN_BITMAP;
+  dst=MAlloc(dc->width_internal*dc->height,task);
+//Pick background color that never occurs. COLOR_INVALID
+  GrBitMap4ToBitMap8(dst,dc->body,
+        (dc->width_internal*dc->height)>>1,COLOR_INVALID);
+  Free(dc->body);
+  dc->body=dst;
+  return dc;
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrEnd.HC.HTML b/public/Wb/Adam/Gr/GrEnd.HC.HTML new file mode 100755 index 0000000..351ed8b --- /dev/null +++ b/public/Wb/Adam/Gr/GrEnd.HC.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+#help_index "Graphics/Scrn"
+
+U0 CtrlAltZ(I64 sc)
+{
+  if (sc&SCF_SHIFT)
+    GrScaleZoom(0.5);
+  else
+    GrScaleZoom(2.0);
+}
+CtrlAltCBSet('Z',&CtrlAltZ,"Cmd /Zoom In",
+        "Cmd /Zoom Out");
+
+U0 Scrn2Clip(I64)
+{
+  CDC *dc=DCScrnCapture;
+  U8 *elems=DC2Sprite(dc);
+  Bool unlock_doc=DocLock(sys_clip_doc);
+  ClipDel;
+  DocSprite(sys_clip_doc,elems);
+  if (unlock_doc)
+    DocUnlock(sys_clip_doc);
+  Free(elems);
+  DCDel(dc);
+}
+U0 CtrlAltS(I64)
+{
+  Spawn(&Scrn2Clip);
+}
+CtrlAltCBSet('S',&CtrlAltS,"Cmd /Scrn Shot to Clip");
+
+ diff --git a/public/Wb/Adam/Gr/GrExt.HC.HTML b/public/Wb/Adam/Gr/GrExt.HC.HTML new file mode 100755 index 0000000..f6873f3 --- /dev/null +++ b/public/Wb/Adam/Gr/GrExt.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+extern U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor);
+extern I64 GrBlot3(CDC *dc,I64 x1,I64 y1,I64 z1,CDC *img);
+extern I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL);
+extern U8 *SpriteQue2Sprite(CSprite *head,I64 *_size=NULL);
+extern CSprite *SpriteSetSettings(CDC *dc=NULL,CSprite *head,I64 elem_num,
+        I64 x=0,I64 y=0,CColorROPU32 *_color=NULL,I64 *_thick=NULL,
+        I64 *_xx=NULL,I64 *_yy=NULL);
+
+ diff --git a/public/Wb/Adam/Gr/GrGlbls.HC.HTML b/public/Wb/Adam/Gr/GrGlbls.HC.HTML new file mode 100755 index 0000000..1128344 --- /dev/null +++ b/public/Wb/Adam/Gr/GrGlbls.HC.HTML @@ -0,0 +1,86 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+public class CGrGlbls
+{
+  I64   *to_8_bits,*to_8_colors;
+  CDC   *scrn_image,    //Read only.
+        *dc,            //Persistent
+        *dc1,
+        *dc2,           //Updated every refresh
+        *dc_cache,
+        *zoomed_dc;
+  U32   *text_base;     //See TextBase Layer. (Similar to 0xB8000 but 32 bits)
+  U16   *win_z_buf;
+
+  #define SPHT_ELEM_CODE        1
+  CHashTable *sprite_hash;
+
+  U16   *win_uncovered_bitmap;
+  I64   highest_uncovered;
+  U16   *vga_text_cache;
+  I64   pan_text_x,pan_text_y;  //[-7,7]
+  U0    (*fp_final_scrn_update)(CDC *dc);//Mouse cursor is handled here.
+  U0    (*fp_wall_paper)(CTask *task);
+  U0    (*fp_draw_ms)(CDC *dc,I64 x,I64 y);
+  U0    (*fp_draw_grab_ms)(CDC *dc,I64 x,I64 y,Bool closed);
+  U8    *empty_sprite; //Gets assigned gr.empty_sprite
+
+  #define GR_PEN_BRUSHES_NUM 64
+  CDC   *pen_brushes[GR_PEN_BRUSHES_NUM],
+        *collision_pen_brushes[GR_PEN_BRUSHES_NUM],
+        *even_pen_brushes[GR_PEN_BRUSHES_NUM],
+        *odd_pen_brushes[GR_PEN_BRUSHES_NUM];
+  I8    circle_lo[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM],
+        circle_hi[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM];
+
+  #define GR_SCRN_ZOOM_MAX      8
+  U8    *scrn_zoom_tables[GR_SCRN_ZOOM_MAX+1];
+  I64   scrn_zoom,sx,sy;
+
+  //When zoomed, this keeps the mouse centered.
+  Bool  continuous_scroll,
+        hide_row,hide_col;
+} gr;
+
+//See RLf_VGA
+//See SysGrInit()
+//Allows consts to be used instead of vars.
+HashPublic("GR_WIDTH",HTT_DEFINE_STR);;
+HashPublic("GR_HEIGHT",HTT_DEFINE_STR);;
+
+#help_index "Char;TextBase Layer/Char"
+DefinePrint("TEXT_ROWS","%d",text.rows);;;
+HashPublic("TEXT_ROWS",HTT_DEFINE_STR);;;
+DefinePrint("TEXT_COLS","%d",text.cols);;;
+HashPublic("TEXT_COLS",HTT_DEFINE_STR);;;
+
+ diff --git a/public/Wb/Adam/Gr/GrInitA.HC.HTML b/public/Wb/Adam/Gr/GrInitA.HC.HTML new file mode 100755 index 0000000..88c5c38 --- /dev/null +++ b/public/Wb/Adam/Gr/GrInitA.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+U0 GrInit1()
+{
+  DefineLstLoad("ST_SPRITE_ELEM_TYPES",
+        "End\0Color\0Dither Color\0"
+        "Thick\0Planar Symmetry\0Transform On\0Transform Off\0Shift\0"
+        "Point\0PolyPoint\0Line\0PolyLine\0Rect\0Rotated Rect\0"
+        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2 Closed\0"
+        "BSpline3\0BSpline3 Closed\0"
+        "Flood Fill\0Flood Fill Not Color\0BitMap\0Mesh\0Shiftable Mesh\0"
+        "Arrow\0Text\0Text Box\0Text Diamond\0");
+  DefineLstLoad("ST_SPRITE_ELEM_CODES",
+        "End\0Color\0Color\0"
+        "Thick\0PlanarSymmetry\0Transform\0Transform\0Shift\0"
+        "Pt\0PolyPt\0Line\0PolyLine\0Rect\0Rect\0"
+        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2\0BSpline3\0BSpline3\0"
+        "FloodFill\0FloodFill\0BitMap\0Mesh\0Mesh\0"
+        "Arrow\0Text\0TextBox\0TextDiamond\0");
+}
+GrInit1;
+
+ diff --git a/public/Wb/Adam/Gr/GrInitB.HC.HTML b/public/Wb/Adam/Gr/GrInitB.HC.HTML new file mode 100755 index 0000000..0bb9e8f --- /dev/null +++ b/public/Wb/Adam/Gr/GrInitB.HC.HTML @@ -0,0 +1,240 @@ + + + + + + + + + + + +
+#help_index "Graphics/Scrn"
+
+U0 GrSetUpTables()
+{
+  CDC *dc;
+  I64 i,j,k,l,m,x,y,rr;
+  U8 *dst;
+
+  k=0;
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++)
+      if (Bt(&i,j))
+        gr.to_8_bits(U8 *)[k++]=0xFF;
+      else
+        gr.to_8_bits(U8 *)[k++]=0x00;
+  k=0;
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++)
+      gr.to_8_colors(U8 *)[k++]=i;
+
+  for (i=0;i<GR_PEN_BRUSHES_NUM;i++) {
+    k=i+1;
+
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr) {
+          if (x-1-i>>1<gr.circle_lo[i][i-y])
+            gr.circle_lo[i][i-y]=x-1-i>>1;
+          if (x-1-i>>1>gr.circle_hi[i][i-y])
+            gr.circle_hi[i][i-y]=x-1-i>>1;
+        }
+
+    dc=DCNew(i,i);
+    gr.pen_brushes[i]=dc;
+    dc->color=COLOR_MONO;
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+
+    dc=DCNew(i,i);
+    gr.collision_pen_brushes[i]=dc;
+    dc->color=COLOR_INVALID;//Want color that never occurs.
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+
+    dc=DCNew(i,i);
+    gr.even_pen_brushes[i]=dc;
+    dc->color=COLOR_MONO;
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (!(((x-1)^(y-1))&1) && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+
+    dc=DCNew(i,i);
+    gr.odd_pen_brushes[i]=dc;
+    dc->color=COLOR_MONO;
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (((x-1)^(y-1))&1 && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+  }
+  if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
+    MemSet(text.vga_text_alias,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
+    MemSet(gr.vga_text_cache,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
+  } else {
+    OutU8(VGAP_IDX,VGAR_MAP_MASK);
+    OutU8(VGAP_DATA,0x0F);
+//Virtual Box crashes on the following for some reason.
+    //    MemSet(text.vga_alias,0,GR_HEIGHT*GR_WIDTH>>3);
+    MemSet(gr.scrn_image->body,0,GR_WIDTH*GR_HEIGHT>>1);
+  }
+  for (i=1;i<=GR_SCRN_ZOOM_MAX;i++) {
+    dst=gr.scrn_zoom_tables[i]=MAlloc(256*i);
+    for (j=0;j<256;j++) {
+      m=0;
+      for (k=0;k<8;k++) {
+        if (Bt(&j,k)) {
+          for (l=0;l<i;l++)
+            Bts(&m,l+k*i);
+        }
+      }
+      for (l=0;l<i;l++)
+        dst[j+l*256]=m.u8[l];
+    }
+  }
+}
+
+#help_index "Graphics/Scrn;Windows"
+
+U0 WinZBufFill(CTask *task)
+{//Not public
+  I64 y,t,b,l,r,w;
+  if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
+    if (task->win_top-1>0)
+      t=task->win_top-1;
+    else
+      t=0;
+    if (task->win_bottom+1<TEXT_ROWS)
+      b=task->win_bottom+1;
+    else
+      b=TEXT_ROWS-1;
+    if (task->win_left-1>0)
+      l=task->win_left-1;
+    else
+      l=0;
+    if (task->win_right+1<TEXT_COLS)
+      r=task->win_right+1;
+    else
+      r=TEXT_COLS-1;
+  } else {
+    if (task->win_top>0)
+      t=task->win_top;
+    else
+      t=0;
+    if (task->win_bottom<TEXT_ROWS)
+      b=task->win_bottom;
+    else
+      b=TEXT_ROWS-1;
+    if (task->win_left>0)
+      l=task->win_left;
+    else
+      l=0;
+    if (task->win_right<TEXT_COLS)
+      r=task->win_right;
+    else
+      r=TEXT_COLS-1;
+  }
+  t=ClampI64(t,0,TEXT_ROWS-1);
+  b=ClampI64(b,t,TEXT_ROWS-1);
+  l=ClampI64(l,0,TEXT_COLS-1);
+  r=ClampI64(r,l,TEXT_COLS-1);
+  if (w=r-l+1)
+    for (y=t;y<=b;y++)
+      MemSetU16(gr.win_z_buf(U8 *)+(y*TEXT_COLS+l)*sizeof(U16),
+            task->win_z_num,w);
+}
+
+public U0 WinZBufUpdate()
+{//Might have to call if doing graphics outside winmgr callback routines.
+//Call it if, for example, when a pop-up window closes and you need to refresh
+  //before graphics.
+  I64 i,z=1;
+  U16 *ptr;
+  CTask *task,*task1;
+  if (gr.win_z_buf) {
+    LBtr(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);
+    task1=task=sys_winmgr_task;
+    do {
+      if (!TaskValidate(task)) break;
+      if (Bt(&task->display_flags,DISPLAYf_SHOW)) {
+        task->win_z_num=z++;
+        WinZBufFill(task);
+      }
+      task=task->next_task;
+    } while (task!=task1 && z<0x10000);
+
+    MemSet(gr.win_uncovered_bitmap,0,(gr.highest_uncovered+7)>>3+1);
+    gr.highest_uncovered=z-1;
+    for (ptr=gr.win_z_buf,i=TEXT_ROWS*TEXT_COLS;i;i--)
+      Bts(gr.win_uncovered_bitmap,*ptr++);
+  }
+}
+
+#help_index "Graphics"
+U0 GrInit2()
+{
+  MemSet(&gr,0,sizeof(CGrGlbls));
+  gr.sprite_hash=HashTableNew(512);
+  HashDefineLstAdd("ST_SPRITE_ELEM_CODES",SPHT_ELEM_CODE,gr.sprite_hash);
+  gr.scrn_zoom=1;
+
+  PaletteSetStd;
+  fp_set_std_palette=&PaletteSetStd;
+  GrPaletteIndicesSet;
+
+  gr.to_8_bits  =MAlloc(256*sizeof(I64));
+  gr.to_8_colors=MAlloc(256*sizeof(I64));
+
+  gr.text_base=CAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U32));
+  gr.vga_text_cache=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
+  gr.win_uncovered_bitmap=CAlloc(65536/8);
+  gr.highest_uncovered=0;
+  gr.win_z_buf=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
+
+  gr.dc2=DCNew(GR_WIDTH,GR_HEIGHT);
+  gr.dc2->flags|=DCF_SCRN_BITMAP;
+  gr.dc_cache=DCNew(GR_WIDTH,GR_HEIGHT);
+
+  gr.dc=DCNew(GR_WIDTH,GR_HEIGHT);
+  gr.dc->flags|=DCF_SCRN_BITMAP|DCF_ON_TOP;
+  DCFill;
+
+  gr.dc1=DCNew(GR_WIDTH,GR_HEIGHT);
+  gr.dc1->flags|=DCF_SCRN_BITMAP;
+
+  gr.scrn_image=DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
+  gr.zoomed_dc   =DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
+  gr.zoomed_dc->flags|=DCF_SCRN_BITMAP;
+}
+
+GrInit2;
+
+ diff --git a/public/Wb/Adam/Gr/GrMath.HC.HTML b/public/Wb/Adam/Gr/GrMath.HC.HTML new file mode 100755 index 0000000..b1df487 --- /dev/null +++ b/public/Wb/Adam/Gr/GrMath.HC.HTML @@ -0,0 +1,836 @@ + + + + + + + + + + + +
+#help_index "Graphics/Math"
+
+public I64 gr_x_offsets[8]={-1, 0, 1,-1,1,-1,0,1},
+           gr_y_offsets[8]={-1,-1,-1, 0,0, 1,1,1},
+          gr_x_offsets2[4]={ 0,-1, 1, 0},
+          gr_y_offsets2[4]={-1, 0, 0, 1};
+
+public Bool Line(U8 *aux_data,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),I64 step=1,I64 start=0)
+{//Step through line segment calling callback.
+//Uses fixed-point.
+  I64 i,j,d,dx=x2-x1,dy=y2-y1,dz=z2-z1,_x,_y,_z,
+        adx=AbsI64(dx),ady=AbsI64(dy),adz=AbsI64(dz);
+  Bool first=TRUE;
+  if (adx>=ady) {
+    if (adx>=adz) {
+      if (d=adx) {
+        if (dx>=0)
+          dx=0x100000000;
+        else
+          dx=-0x100000000;
+        dy=dy<<32/d;
+        dz=dz<<32/d;
+      }
+    } else {
+      if (d=adz) {
+        dx=dx<<32/d;
+        dy=dy<<32/d;
+        if (dz>=0)
+          dz=0x100000000;
+        else
+          dz=-0x100000000;
+      }
+    }
+  } else {
+    if (ady>=adz) {
+      if (d=ady) {
+        dx=dx<<32/d;
+        if (dy>=0)
+          dy=0x100000000;
+        else
+          dy=-0x100000000;
+        dz=dz<<32/d;
+      }
+    } else {
+      if (d=adz) {
+        dx=dx<<32/d;
+        dy=dy<<32/d;
+        if (dz>=0)
+          dz=0x100000000;
+        else
+          dz=-0x100000000;
+      }
+    }
+  }
+  x1<<=32; y1<<=32; z1<<=32;
+  for (j=0;j<start;j++) {
+    x1+=dx; y1+=dy; z1+=dz;
+  }
+  if (step!=1 && step!=0) {
+    dx*=step;
+    dy*=step;
+    dz*=step;
+    d/=step;
+  }
+  for (i=start;i<=d;i++) {
+    if ((_x!=x1.i32[1] || _y!=y1.i32[1] || _z!=z1.i32[1] || first) &&
+          !(*fp_plot)(aux_data,x1.i32[1],y1.i32[1],z1.i32[1]))
+      return FALSE;
+    first=FALSE;
+    _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+    x1+=dx; y1+=dy; z1+=dz;
+  }
+  if (step==1 && (_x!=x2||_y!=y2||_z!=z2) && !(*fp_plot)(aux_data,x2,y2,z2))
+    return FALSE;
+  return TRUE;
+}
+
+#help_index "Graphics/Math/3D Transformation"
+public I64 *Mat4x4MulMat4x4Equ(I64 *dst,I64 *m1,I64 *m2)
+{//Multiply 4x4 matrices and store in dst. Uses fixed-point.
+//Conceptually, the transform m1 is applied after m2
+  I64 i,j,k;
+  F64 sum;
+  for (i=0;i<4;i++) {
+    for (j=0;j<4;j++) {
+      sum=0;
+      for (k=0;k<4;k++)
+        sum+=ToF64(m1[k+4*j])*ToF64(m2[i+4*k]);
+      dst[i+4*j]=sum/GR_SCALE;
+    }
+  }
+  return dst;
+}
+
+public I64 *Mat4x4MulMat4x4New(I64 *m1,I64 *m2,CTask *mem_task=NULL)
+{//Multiply 4x4 matrices. Return MAlloced matrix. Uses fixed-point.
+//Conceptually, the transform m1 is applied after m2
+  return Mat4x4MulMat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),m1,m2);
+}
+
+public I64 *Mat4x4Equ(I64 *dst,I64 *src)
+{//Copy 4x4 Rot matrix.
+  MemCpy(dst,src,sizeof(I64)*16);
+  return dst;
+}
+
+public I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL)
+{//Return MAlloced copy of 4x4 Rot matrix.
+  return Mat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),src);
+}
+
+public I64 *Mat4x4RotX(I64 *m,F64 phi)
+{//Rot matrix about X axis. Uses fixed-point.
+  F64 my_cos=Cos(phi)*GR_SCALE,my_sin=Sin(phi)*GR_SCALE;
+  I64 r[16],r2[16];
+  MemSet(r,0,sizeof(r));
+  r[5]=my_cos;
+  r[10]=my_cos;
+  r[9]=my_sin;
+  r[6]=-my_sin;
+  r[0]=GR_SCALE;
+  r[15]=GR_SCALE;
+  return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
+}
+
+public I64 *Mat4x4RotY(I64 *m,F64 omega)
+{//Rot matrix about Y axis. Uses fixed-point.
+  F64 my_cos=Cos(omega)*GR_SCALE,my_sin=Sin(omega)*GR_SCALE;
+  I64 r[16],r2[16];
+  MemSet(r,0,sizeof(r));
+  r[0]=my_cos;
+  r[10]=my_cos;
+  r[8]=-my_sin;
+  r[2]=my_sin;
+  r[5]=GR_SCALE;
+  r[15]=GR_SCALE;
+  return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
+}
+
+public I64 *Mat4x4RotZ(I64 *m,F64 theta)
+{//Rot matrix about Z axis. Uses fixed-point.
+  F64 my_cos=Cos(theta)*GR_SCALE,my_sin=Sin(theta)*GR_SCALE;
+  I64 r[16],r2[16];
+  MemSet(r,0,sizeof(r));
+  r[0]=my_cos;
+  r[5]=my_cos;
+  r[4]=my_sin;
+  r[1]=-my_sin;
+  r[10]=GR_SCALE;
+  r[15]=GR_SCALE;
+  return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
+}
+
+public I64 *Mat4x4Scale(I64 *m,F64 s)
+{//Scale 4x4 matrix by value.
+  I64 i;
+  for (i=0;i<16;i++)
+    m[i]*=s;
+  return m;
+}
+
+public U0 DCThickScale(CDC *dc=gr.dc)
+{//Scale device context's thick by norm of transformation.
+  I64 d;
+  if (dc->flags&DCF_TRANSFORMATION) {
+    if (dc->thick) {
+      d=dc->thick*dc->r_norm+0x80000000; //Round
+      dc->thick=d.i32[1];
+      if (dc->thick<1)
+        dc->thick=1;
+    }
+  }
+}
+
+public I64 *Mat4x4TranslationEqu(I64 *r,I64 x,I64 y,I64 z)
+{//Set translation values in 4x4 matrix. Uses fixed-point.
+  r[0*4+3]=x<<32;
+  r[1*4+3]=y<<32;
+  r[2*4+3]=z<<32;
+  r[3*4+3]=GR_SCALE;
+  return r;
+}
+
+public I64 *Mat4x4TranslationAdd(I64 *r,I64 x,I64 y,I64 z)
+{//Add translation to 4x4 matrix. Uses fixed-point.
+  r[0*4+3]+=x<<32;
+  r[1*4+3]+=y<<32;
+  r[2*4+3]+=z<<32;
+  r[3*4+3]=GR_SCALE;
+  return r;
+}
+
+public Bool DCSymmetrySet(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
+{//2D. Set device context's symmetry.
+  F64 d;
+  if (y1==y2 && x1==x2)
+    return FALSE;
+  dc->sym.snx=y2-y1;
+  dc->sym.sny=x1-x2;
+  dc->sym.snz=0;
+  if (d=Sqrt(SqrI64(dc->sym.snx)+
+        SqrI64(dc->sym.sny)+
+        SqrI64(dc->sym.snz))) {
+    d=GR_SCALE/d;
+    dc->sym.snx *= d;
+    dc->sym.sny *= d;
+    dc->sym.snz *= d;
+  }
+  dc->sym.sx=x1;
+  dc->sym.sy=y1;
+  dc->sym.sz=0;
+  return TRUE;
+}
+
+public Bool DCSymmetry3Set(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
+        I64 x2,I64 y2,I64 z2,I64 x3,I64 y3,I64 z3)
+{//3D. Set device context's symmetry.
+  F64 d,x,y,z,xx,yy,zz;
+  I64 xx1,yy1,zz1,xx2,yy2,zz2,*r;
+  xx1=x1-x2; yy1=y1-y2; zz1=z1-z2;
+  xx2=x3-x2; yy2=y3-y2; zz2=z3-z2;
+  if (!xx1 && !yy1 && !zz1 ||
+        !xx2 && !yy2 && !zz2 ||
+        xx1==xx2 && yy1==yy2 && zz1==zz2)
+    return FALSE;
+
+  x=yy1*zz2-zz1*yy2;
+  y=-xx1*zz2+zz1*xx2;
+  z=xx1*yy2-yy1*xx2;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    r=dc->r;
+    xx=x*r[0]+y*r[1]+z*r[2];
+    yy=x*r[4]+y*r[5]+z*r[6];
+    zz=x*r[8]+y*r[9]+z*r[10];
+    x=xx; y=yy; z=zz;
+  }
+  if (d=Sqrt(Sqr(x)+Sqr(y)+Sqr(z))) {
+    d=GR_SCALE/d;
+    dc->sym.snx = d*x;
+    dc->sym.sny = d*y;
+    dc->sym.snz = d*z;
+  }
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x1,&y1,&z1);
+  dc->sym.sx=x1;
+  dc->sym.sy=y1;
+  dc->sym.sz=z1;
+  return TRUE;
+}
+
+public U0 DCReflect(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
+{//Reflect 3D point about device context's symmetry. Uses fixed-point.
+  I64 x=*_x<<32,y=*_y<<32,z=*_z<<32,
+        xx=*_x-dc->sym.sx,yy=*_y-dc->sym.sy,zz=*_z-dc->sym.sz,
+        d=(xx*dc->sym.snx+yy*dc->sym.sny+zz*dc->sym.snz)>>16,
+        xn,yn,zn,xx2,yy2,zz2;
+  xn=d*dc->sym.snx>>15;
+  yn=d*dc->sym.sny>>15;
+  zn=d*dc->sym.snz>>15;
+  xx=x-xn;
+  yy=y-yn;
+  zz=z-zn;
+  xx2=x+xn;
+  yy2=y+yn;
+  zz2=z+zn;
+  if (SqrI64(xx>>16 -dc->sym.sx<<16)+
+        SqrI64(yy>>16 -dc->sym.sy<<16)+
+        SqrI64(zz>>16 -dc->sym.sz<<16)<
+        SqrI64(xx2>>16-dc->sym.sx<<16)+
+        SqrI64(yy2>>16-dc->sym.sy<<16)+
+        SqrI64(zz2>>16-dc->sym.sz<<16)) {
+    *_x=xx.i32[1]; *_y=yy.i32[1]; *_z=zz.i32[1];
+  } else {
+    *_x=xx2.i32[1]; *_y=yy2.i32[1]; *_z=zz2.i32[1];
+  }
+}
+
+#help_index "Graphics/Math"
+#define GR_SCALE1_BITS  24
+#define GR_SCALE2_BITS  8
+public Bool Circle(U8 *aux_data,I64 cx,I64 cy,I64 cz,I64 radius,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
+        I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//Step through circle arc calling callback.
+  I64 i,j,len=Ceil(len_radians*radius),
+        x,y,x1,y1,s1,s2,c;
+  F64 t;
+  if (radius<=0||!step) return TRUE;
+  t=1.0/radius;
+  c=1<<GR_SCALE1_BITS*Cos(t);
+  if (step<0) {
+    step=-step;
+    s2=1<<GR_SCALE1_BITS*Sin(t);
+    s1=-s2;
+  } else {
+    s1=1<<GR_SCALE1_BITS*Sin(t);
+    s2=-s1;
+  }
+  if (start_radians) {
+    x=radius*Cos(start_radians);
+    y=-radius*Sin(start_radians);
+  } else {
+    x=radius;
+    y=0;
+  }
+  x<<=GR_SCALE2_BITS;
+  y<<=GR_SCALE2_BITS;
+  for (i=0;i<=len;i+=step) {
+    if (!(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
+      return FALSE;
+    for (j=0;j<step;j++) {
+      x1=(c*x+s1*y)>>GR_SCALE1_BITS;
+      y1=(s2*x+c*y)>>GR_SCALE1_BITS;
+      x=x1; y=y1;
+    }
+  }
+  return TRUE;
+}
+
+public Bool Ellipse(U8 *aux_data,I64 cx,I64 cy,I64 cz,
+        I64 x_radius,I64 y_radius,Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
+        F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//Step through ellipse arc calling callback.
+  I64 i,j,len,
+        x,y,_x,_y,x1,y1,x2,y2, s1,s2,c, s12,s22,c2;
+  F64 t;
+  Bool first=TRUE;
+  if (x_radius<=0 || y_radius<=0 || !step)
+    return TRUE;
+  if (x_radius>=y_radius) {
+    t=1.0/x_radius;
+    len=Ceil(len_radians*x_radius);
+  } else {
+    t=1.0/y_radius;
+    len=Ceil(len_radians*y_radius);
+  }
+
+  c=1<<GR_SCALE1_BITS*Cos(t);
+  if (step<0) {
+    step=-step;
+    s2=1<<GR_SCALE1_BITS*Sin(t);
+    s1=-s2;
+  } else {
+    s1=1<<GR_SCALE1_BITS*Sin(t);
+    s2=-s1;
+  }
+
+  c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
+  s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
+  s22=-s12;
+
+  if (start_radians) {
+    x=x_radius*Cos(start_radians);
+    y=-x_radius*Sin(start_radians);
+  } else {
+    x=x_radius;
+    y=0;
+  }
+  x<<=GR_SCALE2_BITS;
+  y<<=GR_SCALE2_BITS;
+  x2=x;
+  y2=y;
+
+  y1=y2*y_radius/x_radius;
+  x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
+  y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
+
+  for (i=0;i<=len;i+=step) {
+    if ((x>>GR_SCALE2_BITS!=_x || y>>GR_SCALE2_BITS!=_y || first) &&
+          !(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
+      return FALSE;
+
+    _x=x>>GR_SCALE2_BITS; _y=y>>GR_SCALE2_BITS; first=FALSE;
+    for (j=0;j<step;j++) {
+      x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
+      y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
+      x2=x1;
+      y2=y1;
+      y1=y1*y_radius/x_radius;
+      x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
+      y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
+    }
+  }
+  return TRUE;
+}
+
+public Bool RegPoly(U8 *aux_data,I64 cx,I64 cy,I64 cz,
+        I64 x_radius,I64 y_radius,I64 sides,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
+        F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//Step through regular polygon calling callback.
+  I64 i,n,x,y,x1,y1,x2,y2,
+        xx1,yy1,xx2,yy2,
+        s1,s2,c, s12,s22,c2;
+  F64 angle_step;
+
+  if (sides<=0 || x_radius<=0 || y_radius<=0)
+    return TRUE;
+
+  angle_step=2*pi/sides;
+  n=len_radians*sides/(2*pi);
+
+  s1=1<<GR_SCALE1_BITS*Sin(angle_step);
+  s2=-s1;
+  c=1<<GR_SCALE1_BITS*Cos(angle_step);
+
+  s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
+  s22=-s12;
+  c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
+
+  if (start_radians) {
+    x=x_radius*Cos(start_radians);
+    y=-x_radius*Sin(start_radians);
+  } else {
+    x=x_radius;
+    y=0;
+  }
+  x<<=GR_SCALE2_BITS;
+  y<<=GR_SCALE2_BITS;
+  x2=x;
+  y2=y;
+
+  y1=y2*y_radius/x_radius;
+  x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
+  y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
+
+  xx1=cx+x>>GR_SCALE2_BITS;
+  yy1=cy+y>>GR_SCALE2_BITS;
+  for (i=0;i<n;i++) {
+    x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
+    y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
+    x2=x1;
+    y2=y1;
+    y1=y1*y_radius/x_radius;
+    x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
+    y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
+    xx2=cx+x>>GR_SCALE2_BITS;
+    yy2=cy+y>>GR_SCALE2_BITS;
+    if (!Line(aux_data,xx1,yy1,cz,xx2,yy2,cz,fp_plot,step))
+      return FALSE;
+    xx1=xx2; yy1=yy2;
+  }
+  return TRUE;
+}
+
+#help_index "Graphics/Data Types/D3I32;Math/Data Types/D3I32;Data Types/D3I32"
+public F64 D3I32Dist(CD3I32 *p1,CD3I32 *p2)
+{//Distance
+  return Sqrt(SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z));
+}
+
+public I64 D3I32DistSqr(CD3I32 *p1,CD3I32 *p2)
+{//Distance Squared
+  return SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z);
+}
+
+public F64 D3I32Norm(CD3I32 *p)
+{//Norm
+  return Sqrt(SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z));
+}
+
+public I64 D3I32NormSqr(CD3I32 *p)
+{//Norm Squared
+  return SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z);
+}
+
+#help_index "Graphics/Math"
+public Bool Bezier2(U8 *aux_data,CD3I32 *ctrl,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
+{//Go in 2nd order bezier calling callback.
+  I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
+  F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
+        x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
+        x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
+        t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
+        D3I32Dist(&ctrl[1],&ctrl[2])+
+        D3I32Dist(&ctrl[2],&ctrl[0]),
+        s=0.5/d,t1,t2;
+  xx=x0; yy=y0; zz=z0;
+  if (first && !(*fp_plot)(aux_data,xx,yy,zz))
+    return FALSE;
+  for (t=0.0;t<=1.0;t+=s) {
+    t1=t*(1.0-t);
+    t2=t*t;
+    x=x0+x1*t1+x2*t2;
+    y=y0+y1*t1+y2*t2;
+    z=z0+z1*t1+z2*t2;
+    dx=AbsI64(x-xx);
+    dy=AbsI64(y-yy);
+    dz=AbsI64(z-zz);
+    if (dx>dy)
+      d_max=dx;
+    else
+      d_max=dy;
+    if (dz>d_max)
+      d_max=dz;
+    if (!d_max)
+      s*=1.1;
+    else {
+      s*=0.9;
+      if (!(*fp_plot)(aux_data,x,y,z))
+        return FALSE;
+      xx=x;yy=y;zz=z;
+    }
+  }
+  x=ctrl[2].x; y=ctrl[2].y; z=ctrl[2].z;
+  if ((xx!=x || yy!=y || zz!=z) &&
+        !(*fp_plot)(aux_data,x,y,z))
+    return FALSE;
+  return TRUE;
+}
+
+public Bool Bezier3(U8 *aux_data,CD3I32 *ctrl,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
+{//Go in 3rd order bezier calling callback.
+  I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
+  F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
+        x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
+        x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
+        x3=ctrl[3].x-x0,y3=ctrl[3].y-y0,z3=ctrl[3].z-z0,
+        t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
+        D3I32Dist(&ctrl[1],&ctrl[2])+
+        D3I32Dist(&ctrl[2],&ctrl[3])+
+        D3I32Dist(&ctrl[3],&ctrl[0]),
+        s=0.5/d,nt,t1,t2,t3;
+  xx=x0; yy=y0; zz=z0;
+  if (first && !(*fp_plot)(aux_data,xx,yy,zz))
+    return FALSE;
+  for (t=0.0;t<=1.0;t+=s) {
+    nt=1.0-t;
+    t1=t*nt*nt;
+    t2=t*t*nt;
+    t3=t*t*t;
+    x=x0+x1*t1+x2*t2+x3*t3;
+    y=y0+y1*t1+y2*t2+y3*t3;
+    z=z0+z1*t1+z2*t2+z3*t3;
+    dx=AbsI64(x-xx);
+    dy=AbsI64(y-yy);
+    dz=AbsI64(z-zz);
+    if (dx>dy)
+      d_max=dx;
+    else
+      d_max=dy;
+    if (dz>d_max)
+      d_max=dz;
+    if (!d_max)
+      s*=1.1;
+    else {
+      s*=0.9;
+      if (!(*fp_plot)(aux_data,x,y,z))
+        return FALSE;
+      xx=x;yy=y;zz=z;
+    }
+  }
+  x=ctrl[3].x; y=ctrl[3].y; z=ctrl[3].z;
+  if ((xx!=x || yy!=y || zz!=z) &&
+        !(*fp_plot)(aux_data,x,y,z))
+    return FALSE;
+  return TRUE;
+}
+
+public Bool BSpline2(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
+{//Go in 2nd order spline calling callback.
+  I64 i,j;
+  CD3I32 *c;
+  Bool first;
+  if (cnt<3) return FALSE;
+  first=TRUE;
+  if (closed) {
+    cnt++;
+    c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
+    j=1;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
+      c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
+      c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
+      j+=2;
+    }
+    c[j].x=(ctrl[0].x+ctrl[cnt-2].x)/2.0;
+    c[j].y=(ctrl[0].y+ctrl[cnt-2].y)/2.0;
+    c[j].z=(ctrl[0].z+ctrl[cnt-2].z)/2.0;
+
+    c[0].x=(c[1].x+c[j].x)/2.0;
+    c[0].y=(c[1].y+c[j].y)/2.0;
+    c[0].z=(c[1].z+c[j].z)/2.0;
+    j=2;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=2;
+    }
+    c[j].x=c[0].x;
+    c[j].y=c[0].y;
+    c[j].z=c[0].z;
+  } else {
+    c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
+    c[0].x=ctrl[0].x;
+    c[0].y=ctrl[0].y;
+    c[0].z=ctrl[0].z;
+    c[cnt*2-2].x=ctrl[cnt-1].x;
+    c[cnt*2-2].y=ctrl[cnt-1].y;
+    c[cnt*2-2].z=ctrl[cnt-1].z;
+    j=1;
+    for (i=0;i<cnt-1;i++) {
+      c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
+      c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
+      c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
+      j+=2;
+    }
+    j=2;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=2;
+    }
+  }
+  for (i=0;i<cnt*2-2;i+=2) {
+    if (!Bezier2(aux_data,&c[i],fp_plot,first))
+      return FALSE;
+    first=FALSE;
+  }
+  Free(c);
+  return TRUE;
+}
+
+public Bool BSpline3(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
+{//Go in 3rd order spline calling callback.
+  I64 i,j;
+  F64 x,y,z;
+  CD3I32 *c;
+  Bool first;
+  if (cnt<3) return FALSE;
+  first=TRUE;
+  if (closed) {
+    cnt++;
+    c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
+    j=1;
+    for (i=0;i<cnt-2;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      c[j].x=(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=(ctrl[i+1].z-z)/3.0+z;
+      j++;
+      c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
+      j+=2;
+    }
+    x=ctrl[cnt-2].x;
+    y=ctrl[cnt-2].y;
+    z=ctrl[cnt-2].z;
+    c[j].x=(ctrl[0].x-x)/3.0+x;
+    c[j].y=(ctrl[0].y-y)/3.0+y;
+    c[j].z=(ctrl[0].z-z)/3.0+z;
+    j++;
+    c[j].x=2.0*(ctrl[0].x-x)/3.0+x;
+    c[j].y=2.0*(ctrl[0].y-y)/3.0+y;
+    c[j].z=2.0*(ctrl[0].z-z)/3.0+z;
+
+    c[0].x=(c[1].x+c[j].x)/2.0;
+    c[0].y=(c[1].y+c[j].y)/2.0;
+    c[0].z=(c[1].z+c[j].z)/2.0;
+
+    j=3;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=3;
+    }
+    c[j].x=c[0].x;
+    c[j].y=c[0].y;
+    c[j].z=c[0].z;
+  } else {
+    c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
+    c[0].x=ctrl[0].x;
+    c[0].y=ctrl[0].y;
+    c[0].z=ctrl[0].z;
+    c[cnt*3-3].x=ctrl[cnt-1].x;
+    c[cnt*3-3].y=ctrl[cnt-1].y;
+    c[cnt*3-3].z=ctrl[cnt-1].z;
+    j=1;
+    for (i=0;i<cnt-1;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      c[j].x=(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=(ctrl[i+1].z-z)/3.0+z;
+      j++;
+      c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
+      j+=2;
+    }
+    j=3;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=3;
+    }
+  }
+  for (i=0;i<cnt*3-3;i+=3) {
+    if (!Bezier3(aux_data,&c[i],fp_plot,first))
+      return FALSE;
+    first=FALSE;
+  }
+  Free(c);
+  return TRUE;
+}
+
+#define CC_LEFT         1
+#define CC_RIGHT        2
+#define CC_TOP          4
+#define CC_BOTTOM       8
+
+public Bool ClipLine(I64 *_x1,I64 *_y1,I64 *_x2,I64 *_y2,
+        I64 left,I64 top,I64 right,I64 bottom)
+{//Clip x1,y1 x2,y2 with left,top,right,bottom.
+  I64 x,y,x1=*_x1,y1=*_y1,x2=*_x2,y2=*_y2,
+        cc,cc1,cc2;
+  if (y1>bottom)
+    cc1=CC_BOTTOM;
+  else if (y1<top)
+    cc1=CC_TOP;
+  else
+    cc1=0;
+  if (x1>right)
+    cc1|=CC_RIGHT;
+  else if (x1<left)
+    cc1|=CC_LEFT;
+
+  if (y2>bottom)
+    cc2=CC_BOTTOM;
+  else if (y2<top)
+    cc2=CC_TOP;
+  else
+    cc2=0;
+  if (x2>right)
+    cc2|=CC_RIGHT;
+  else if (x2<left)
+    cc2|=CC_LEFT;
+
+  while (TRUE) {
+    if (!(cc1|cc2))
+      return TRUE;
+    if (cc1&cc2)
+      return FALSE;
+
+    if (cc1)
+      cc=cc1;
+    else
+      cc=cc2;
+
+    if (cc&CC_BOTTOM) {
+      x=x1+(x2-x1)*(bottom-y1)/(y2-y1);
+      y=bottom;
+    } else if (cc&CC_TOP) {
+      x=x1+(x2-x1)*(top-y1)/(y2-y1);
+      y=top;
+    } else if (cc&CC_RIGHT) {
+      y=y1+(y2-y1)*(right-x1)/(x2-x1);
+      x=right;
+    } else {
+      y=y1+(y2-y1)*(left-x1)/(x2-x1);
+      x=left;
+    }
+
+    if (cc==cc1) {
+      *_x1=x1=x;
+      *_y1=y1=y;
+      if (y1>bottom)
+        cc1=CC_BOTTOM;
+      else if (y1<top)
+        cc1=CC_TOP;
+      else
+        cc1=0;
+      if (x1>right)
+        cc1|=CC_RIGHT;
+      else if (x1<left)
+        cc1|=CC_LEFT;
+    } else {
+      *_x2=x2=x;
+      *_y2=y2=y;
+      if (y2>bottom)
+        cc2=CC_BOTTOM;
+      else if (y2<top)
+        cc2=CC_TOP;
+      else
+        cc2=0;
+      if (x2>right)
+        cc2|=CC_RIGHT;
+      else if (x2<left)
+        cc2|=CC_LEFT;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrPalette.HC.HTML b/public/Wb/Adam/Gr/GrPalette.HC.HTML new file mode 100755 index 0000000..67331c3 --- /dev/null +++ b/public/Wb/Adam/Gr/GrPalette.HC.HTML @@ -0,0 +1,124 @@ + + + + + + + + + + + +
+#help_index "Graphics/Color"
+public U8 gr_rainbow_10[10]={
+  BLACK,BROWN,RED,LTRED,YELLOW,GREEN,BLUE,PURPLE,LTGRAY,WHITE};
+
+DefineLstLoad("ST_RAINBOW_10",
+  "BLACK\0BROWN\0RED\0LTRED\0YELLOW\0GREEN\0BLUE\0PURPLE\0LTGRAY\0WHITE\0");
+
+U0 GrPaletteIndicesSet()
+{//There is a level of indirection that we identity map.
+// Set 16-colors to use first 16 DAC BGR entries, so we
+// never need to worry about indexes, just DAC palette settings.
+  I64 i;
+  if (!Bt(&sys_run_level,RLf_VGA)) return;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_VGA],0))
+    Yield;
+  InU8(VGAP_INPUT_STAT); //Rsts attr index/data
+  for (i=0;i<COLORS_NUM;i++) {
+    OutU8(VGAP_ATTR_INDEX,i);
+    OutU8(VGAP_ATTR_DATA_WRITE,i);
+  }
+  OutU8(VGAP_ATTR_INDEX,0x20);
+  OutU8(VGAP_ATTR_DATA_WRITE,0); //Dummy write
+  InU8(VGAP_INPUT_STAT); //Rsts attr index/data
+  LBtr(&sys_semas[SEMA_VGA],0);
+  POPFD
+}
+
+public U0 GrPaletteColorSet(I64 color_num,CBGR48 bgr48)
+{//VGA has 6-bits for blue, for green, and for red.
+  if (!Bt(&sys_run_level,RLf_VGA)) return;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_VGA],0))
+    Yield;
+  OutU8(VGAP_PALETTE_MASK,0xFF);
+  OutU8(VGAP_REG_WRITE,color_num);
+  OutU8(VGAP_PALETTE_DATA,bgr48.r>>10);
+  OutU8(VGAP_PALETTE_DATA,bgr48.g>>10);
+  OutU8(VGAP_PALETTE_DATA,bgr48.b>>10);
+  LBtr(&sys_semas[SEMA_VGA],0);
+  POPFD
+}
+
+public CBGR48 GrPaletteColorGet(I64 color_num)
+{//VGA has 6-bits for blue, for green, and for red.
+  CBGR48 res=0;
+  if (!Bt(&sys_run_level,RLf_VGA)) return 0;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_VGA],0))
+    Yield;
+  OutU8(VGAP_PALETTE_MASK,0xFF);
+  OutU8(VGAP_REG_READ,color_num);
+  res.r=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
+  res.g=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
+  res.b=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
+  LBtr(&sys_semas[SEMA_VGA],0);
+  POPFD
+  return res;
+}
+
+public CBGR48 gr_palette_std[COLORS_NUM]={
+0x000000000000,0x00000000AAAA,0x0000AAAA0000,0x0000AAAAAAAA,
+0xAAAA00000000,0xAAAA0000AAAA,0xAAAA55550000,0xAAAAAAAAAAAA,
+0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
+0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0xFFFFFFFFFFFF};
+
+public CBGR48 gr_palette_gray[COLORS_NUM]={
+0x000000000000,0x111111111111,0x222222222222,0x333333333333,
+0x444444444444,0x555555555555,0x666666666666,0x777777777777,
+0x888888888888,0x999999999999,0xAAAAAAAAAAAA,0xBBBBBBBBBBBB,
+0xCCCCCCCCCCCC,0xDDDDDDDDDDDD,0xEEEEEEEEEEEE,0xFFFFFFFFFFFF};
+
+public U0 GrPaletteGet(CBGR48 *bgr48)
+{//16 colors
+  I64 i;
+  for (i=0;i<COLORS_NUM;i++)
+    bgr48[i]=GrPaletteColorGet(i);
+}
+
+public U0 GrPaletteSet(CBGR48 *bgr48)
+{//16 colors
+  I64 i;
+  for (i=0;i<COLORS_NUM;i++)
+    GrPaletteColorSet(i,bgr48[i]);
+}
+
+public U0 PaletteSetStd()
+{//Activate std palette.
+  GrPaletteSet(gr_palette_std);
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrPrimatives.HC.HTML b/public/Wb/Adam/Gr/GrPrimatives.HC.HTML new file mode 100755 index 0000000..f652252 --- /dev/null +++ b/public/Wb/Adam/Gr/GrPrimatives.HC.HTML @@ -0,0 +1,1853 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+public Bool GrClamp(CDC *dc=gr.dc,I64 *left,I64 *top,I64 *right,I64 *bottom,
+        I64 width=0,I64 height=0)
+{//Returns scrn, not window coordinates.
+  CTask *win_task;
+  *left=0;
+  *top=0;
+  *right=dc->width-1;
+  *bottom=dc->height-1;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    if (GR_WIDTH-1<*right)
+      *right=GR_WIDTH-1;
+    if (GR_HEIGHT-1<*bottom)
+      *bottom=GR_HEIGHT-1;
+    if (win_task->pix_left>*left)
+      *left=win_task->pix_left;
+    if (win_task->pix_top>*top)
+      *top=win_task->pix_top;
+    if (win_task->pix_right<*right)
+      *right=win_task->pix_right;
+    if (win_task->pix_bottom<*bottom)
+      *bottom=win_task->pix_bottom;
+  }
+  *left-=width;
+  *right+=width;
+  *top-=height;
+  *bottom+=height;
+  return *left<=*right && *top<=*bottom;
+}
+
+Bool DCClipLine(CDC *dc=gr.dc,I64 *x1,I64 *y1,I64 *x2,I64 *y2,
+        I64 width=0,I64 height=0)
+{//Also converts window to scrn coordinates
+  I64 left,top,right,bottom;
+  CTask *win_task;
+  if (GrClamp(dc,&left,&top,&right,&bottom,width,height)) {
+    if (dc->flags & DCF_SCRN_BITMAP) {
+      win_task=dc->win_task;
+      *x1+=win_task->pix_left+win_task->scroll_x;
+      *y1+=win_task->pix_top+win_task->scroll_y;
+      *x2+=win_task->pix_left+win_task->scroll_x;
+      *y2+=win_task->pix_top+win_task->scroll_y;
+    }
+    return ClipLine(x1,y1,x2,y2,left,top,right,bottom);
+  } else
+    return FALSE;
+}
+
+public Bool GrPlot(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. Clipping but No transformation or thick.
+  I32 *db=dc->depth_buf;
+  CTask *win_task;
+  CColorROPU32 old_color;
+  dc->depth_buf=NULL;
+  if (dc->brush) {
+    old_color=dc->color;
+    if (dc->color.c0.rop!=ROPB_COLLISION)
+      dc->color.c0.rop=ROPB_MONO;
+    GrBlot(dc,x,y,dc->brush);
+    dc->color=old_color;
+  } else if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->pix_left+win_task->scroll_x;
+    y+=win_task->pix_top+win_task->scroll_y;
+    if (win_task->pix_left<=x<=win_task->pix_right &&
+          win_task->pix_top<=y<=win_task->pix_bottom &&
+          0<=x<dc->width && 0<=y<dc->height &&
+          (win_task->next_task==sys_winmgr_task ||
+          dc->flags&DCF_ON_TOP ||
+          !IsPixCovered0(win_task,x,y)))
+      GrPlot0(dc,x,y);
+  } else
+    if (0<=x<dc->width && 0<=y<dc->height)
+      GrPlot0(dc,x,y);
+  dc->depth_buf=db;
+  return TRUE;
+}
+
+Bool GrPlot1(CDC *dc=gr.dc,I64 x,I64 y)
+{//Clipping but No transformation or thick, called with db_z set
+  CTask *win_task;
+  CColorROPU32 old_color;
+  if (dc->brush) {
+    old_color=dc->color;
+    if (dc->color.c0.rop!=ROPB_COLLISION)
+      dc->color.c0.rop=ROPB_MONO;
+    if (dc->depth_buf)
+      GrBlot3(dc,x,y,dc->db_z,dc->brush);
+    else
+      GrBlot(dc,x,y,dc->brush);
+    dc->color=old_color;
+  } else if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->pix_left+win_task->scroll_x;
+    y+=win_task->pix_top+win_task->scroll_y;
+    if (win_task->pix_left<=x<=win_task->pix_right &&
+          win_task->pix_top <=y<=win_task->pix_bottom &&
+          0<=x<dc->width && 0<=y<dc->height &&
+          (win_task->next_task==sys_winmgr_task ||
+          dc->flags&DCF_ON_TOP ||
+          !IsPixCovered0(win_task,x,y)))
+      GrPlot0(dc,x,y);
+  } else
+    if (0<=x<dc->width && 0<=y<dc->height)
+      GrPlot0(dc,x,y);
+  return TRUE;
+}
+
+public I64 GrPeek(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. Clipping but no transformation.
+//Returns pix color or -1 if off-scrn or covered.
+  CTask *win_task;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->pix_left+win_task->scroll_x;
+    y+=win_task->pix_top+win_task->scroll_y;
+    if (!(win_task->pix_left<=x<=win_task->pix_right)  ||
+          !(win_task->pix_top <=y<=win_task->pix_bottom) ||
+          !(0<=x<dc->width) || !(0<=y<dc->height) ||
+          win_task->next_task!=sys_winmgr_task &&
+          !(dc->flags&DCF_ON_TOP) &&
+          IsPixCovered0(win_task,x,y))
+      return -1;
+  } else
+    if (!(0<=x<dc->width) || !(0<=y<dc->height))
+      return -1;
+  return GrPeek0(dc,x,y);
+}
+
+/*
+
+This is an easier to understand
+version of the nonrecursive routine below.
+I64 GrFloodFillRay(CDC *dc,I64 x,I64 y,I64 z,I32 *db)
+{
+  I64 res,j,x1,ray_len,ray_len2;
+
+  if (UnusedStk<0x80)
+    Panic("Stk Overflow",Fs);
+
+  res=ray_len=GrRayLen(dc,&x,y,z,db);
+  y--;
+  j=ray_len;
+  x1=x;
+  while (j>0) {
+    if (ray_len2=GrRayLenMinus(dc,x1,y))
+      res+=GrFloodFillRay(dc,x1,y,z,db);
+    j-=ray_len2+1;
+    x1-=ray_len2+1;
+  }
+  y+=2;
+  j=ray_len;
+  x1=x;
+  while (j>0) {
+    if (ray_len2=GrRayLenMinus(dc,x1,y))
+      res+=GrFloodFillRay(dc,x1,y,z,db);
+    j-=ray_len2+1;
+    x1-=ray_len2+1;
+  }
+  return res;
+}
+*/
+
+class CFFRay
+{
+  I64 state,x,y,j,x1,ray_len,ray_len2;
+};
+
+I64 GrFloodFillRay(CDC *dc,I64 x,I64 y,I64 z,I32 *db)
+{//See the above commented-out routine for an easier to understand version.
+//Returns cnt of pixs changed
+  I64 res=0;
+//We don't dynamically calculate the size to avoid
+  //fragmentation of memory.
+  CFFRay *f_dc=MAlloc(sizeof(CFFRay)*0x80000),*f=f_dc;
+  f->x=x;
+  f->y=y;
+  f->state=0;
+  do {
+    switch [f->state] {
+      case 0:
+        f->state++;
+        res+=f->ray_len=GrRayLen(dc,&f->x,f->y,z,db);
+        f->y--;
+        f->j=f->ray_len;
+        f->x1=f->x;
+        break;
+      case 1:
+        if (f->j>0) {
+          f->state++;
+          if (f->ray_len2=GrRayLenMinus(dc,f->x1,f->y)) {
+            f[1].x=f->x1;
+            f[1].y=f->y;
+            f[1].state=0;
+            f++;
+          }
+        } else
+          f->state+=2;
+        break;
+      case 2:
+        f->state--;
+        f->j-=f->ray_len2+1;
+        f->x1-=f->ray_len2+1;
+        break;
+      case 3:
+        f->state++;
+        f->y+=2;
+        f->j=f->ray_len;
+        f->x1=f->x;
+        break;
+      case 4:
+        if (f->j>0) {
+          f->state++;
+          if (f->ray_len2=GrRayLenMinus(dc,f->x1,f->y)) {
+            f[1].x=f->x1;
+            f[1].y=f->y;
+            f[1].state=0;
+            f++;
+          }
+        } else
+          f->state+=2;
+        break;
+      case 5:
+        f->state--;
+        f->j-=f->ray_len2+1;
+        f->x1-=f->ray_len2+1;
+        break;
+      case 6:
+        f--;
+        break;
+    }
+  } while (f>=f_dc);
+  Free(f_dc);
+  return res;
+}
+
+public I64 GrFloodFill(CDC *dc=gr.dc,I64 x,I64 y,
+        Bool not_color=FALSE,I64 z=0,I32 *db=NULL)
+{//2D. Ignore z and db.
+//not_color=TRUE means fill up to everything which is not the current color.
+  //not_color=FALSE means fill all parts equ to the color under the point.
+  //Returns cnt of pixs changed
+  I64 res=0,j,old_flags=dc->flags;
+  CColorROPU32 old_color2=dc->color2;
+  CDC *old_brush;
+  if (dc->flags & DCF_DONT_DRAW) //TODO
+    return 0;
+  old_brush=dc->brush;
+  dc->brush=NULL;
+  if ((j=GrPeek(dc,x,y))>=0) {
+    if (not_color) {
+      dc->color2=dc->color.c0.color;
+      dc->flags|=DCF_FILL_NOT_COLOR;
+    } else {
+      dc->color2=j;
+      if (dc->color.c1.rop&ROPBF_DITHER) {
+        if (dc->color2.c0.color==dc->color.c0.color &&
+              dc->color.c0.color==dc->color.c1.color)
+          goto ff_done;
+      } else if (dc->color2.c0.color==dc->color.c0.color)
+        goto ff_done;
+      dc->flags&=~DCF_FILL_NOT_COLOR;
+    }
+    if (not_color && j!=dc->color2 ||
+          !not_color)
+      res=GrFloodFillRay(dc,x,y,z,db);
+  }
+ff_done:
+  dc->brush=old_brush;
+  dc->flags=old_flags;
+  dc->color2=old_color2;
+  return res;
+}
+
+I64 GrFillSemiCircle(CDC *dc=gr.dc,I64 cx,I64 cy,I64 z=0,I64 diameter,I64 n)
+{//2D. Clipping but not transformation.
+  I64 res=0,i,k,r=diameter>>1,rr;
+  if (diameter>=1)
+    switch (n) {
+      case 0:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(r-i))+cx,
+                  Sqrt(rr-SqrI64(r-i))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 1:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(i-r))+cx,
+                  Sqrt(rr-SqrI64(i-r))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 2:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(r-i))+cy,
+                  Sqrt(rr-SqrI64(r-i))+cy,z,z);
+        }
+        break;
+      case 3:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(i-r))+cy,
+                  Sqrt(rr-SqrI64(i-r))+cy,z,z);
+        }
+        break;
+      case 4:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(r-i))+cx,
+                  Sqrt(rr-SqrI64(r-i))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 5:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(i-r))+cx,
+                  Sqrt(rr-SqrI64(i-r))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 6:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(r-i))+cy,
+                  Sqrt(rr-SqrI64(r-i))+cy,z,z);
+        }
+        break;
+      case 7:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(i-r))+cy,
+                  Sqrt(rr-SqrI64(i-r))+cy,z,z);
+        }
+        break;
+    }
+  return res;
+}
+
+public I64 GrFillCircle(CDC *dc=gr.dc,I64 cx,I64 cy,I64 z=0,I64 diameter)
+{//2D. Clipping but not transformation.
+  I64 res=0,i,k,r=diameter>>1,rr;
+  if (diameter>=1) {
+    if (diameter<GR_PEN_BRUSHES_NUM)
+      for (i=0;i<diameter;i++)
+        res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+              gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+    else {
+      k=diameter+1;
+      rr=SqrI64((k+1)>>1);
+      for (i=0;i<=r;i++)
+        res+=GrHLine(dc,-Sqrt(rr-SqrI64(r-i))+cx,
+              Sqrt(rr-SqrI64(r-i))+cx,cy+i-r,z,z);
+      for (;i<k;i++)
+        res+=GrHLine(dc,-Sqrt(rr-SqrI64(i-r))+cx,
+              Sqrt(rr-SqrI64(i-r))+cx,cy+i-r,z,z);
+    }
+  }
+  return res;
+}
+
+public Bool GrPlot3B(CDC *dc=gr.dc,I64 x,I64 y,I64 z)
+{//3D. Clipping and transformation but no thick.
+  I64 _x,_y,_z;
+  Bool was_transform=FALSE,was_symmetry=FALSE;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x,&y,&z);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x=x; _y=y; _z=z;
+    DCReflect(dc,&_x,&_y,&_z);
+    dc->flags&=~DCF_SYMMETRY;
+    dc->db_z=_z;
+    GrPlot1(dc,_x,_y);
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  dc->db_z=z;
+  GrPlot1(dc,x,y);
+gr_done:
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return TRUE;
+}
+
+public Bool GrPlot3(CDC *dc=gr.dc,I64 x,I64 y,I64 z)
+{//3D. Clipping and transformation and thick.
+  I64 _x,_y,_z,w,dist;
+  CColorROPU32 old_color=dc->color;
+  Bool record,was_transform=FALSE,was_symmetry=FALSE;
+  CTask *win_task;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x,&y,&z);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x=x; _y=y; _z=z;
+    DCReflect(dc,&_x,&_y,&_z);
+    dc->flags&=~DCF_SYMMETRY;
+    GrPlot3(dc,_x,_y,_z);
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  w=dc->thick>>1;
+  dc->db_z=z;
+  if (dc->brush || w<=0)
+    GrPlot1(dc,x,y);
+  else if (dc->thick<GR_PEN_BRUSHES_NUM) {
+    if (dc->color.c0.rop!=ROPB_COLLISION)
+      dc->color.c0.rop=ROPB_MONO;
+    if (dc->depth_buf) {
+      if (dc->color.c1.rop&ROPBF_DITHER) {
+        dc->color.c1.rop=dc->color.c0.rop;
+        if (((x-w)^(y-w))&1) {
+          record=GrBlot3(dc,x-w,y-w,z,gr.odd_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot3(dc,x-w,y-w,z,gr.even_pen_brushes[dc->thick]);
+        } else {
+          record=GrBlot3(dc,x-w,y-w,z,gr.even_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot3(dc,x-w,y-w,z,gr.odd_pen_brushes[dc->thick]);
+        }
+      } else {
+        if (dc->color.c0.rop==ROPB_COLLISION) {
+          if (dc->color.c0.color!=dc->bkcolor.c0.color &&
+                dc->color.c0.color!=TRANSPARENT)
+            record=GrBlot3(dc,x-w,y-w,z,
+                  gr.collision_pen_brushes[dc->thick]);
+          else
+            record=FALSE;
+        } else
+          record=GrBlot3(dc,x-w,y-w,z,gr.pen_brushes[dc->thick]);
+      }
+    } else {
+      if (dc->color.c1.rop&ROPBF_DITHER) {
+        dc->color.c1.rop=dc->color.c0.rop;
+        if (((x-w)^(y-w))&1) {
+          record=GrBlot(dc,x-w,y-w,gr.odd_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot(dc,x-w,y-w,gr.even_pen_brushes[dc->thick]);
+        } else {
+          record=GrBlot(dc,x-w,y-w,gr.even_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot(dc,x-w,y-w,gr.odd_pen_brushes[dc->thick]);
+        }
+      } else {
+        if (dc->color.c0.rop==ROPB_COLLISION) {
+          if (dc->color.c0.color!=dc->bkcolor.c0.color &&
+                dc->color.c0.color!=TRANSPARENT)
+            record=GrBlot(dc,x-w,y-w,gr.collision_pen_brushes[dc->thick]);
+          else
+            record=FALSE;
+        } else
+          record=GrBlot(dc,x-w,y-w,gr.pen_brushes[dc->thick]);
+      }
+    }
+    if (record) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        win_task=dc->win_task;
+        x+=win_task->pix_left+win_task->scroll_x;
+        y+=win_task->pix_top+win_task->scroll_y;
+      }
+      if (dc->flags & DCF_LOCATE_NEAREST) {
+        dist=DistSqrI64(x,y,dc->cur_x,dc->cur_y);
+        if (dist<=dc->nearest_dist)
+          dc->nearest_dist=dist;
+      }
+      if (dc->flags & DCF_RECORD_EXTENTS) {
+        if (x-w<dc->min_x) dc->min_x=x-w;
+        if (y-w<dc->min_y) dc->min_y=y-w;
+        if (dc->thick & 1) {
+          if (x+w>dc->max_x) dc->max_x=x+w;
+          if (y+w>dc->max_y) dc->max_y=y+w;
+        } else {
+          if (x+w-1>dc->max_x) dc->max_x=x+w-1;
+          if (y+w-1>dc->max_y) dc->max_y=y+w-1;
+        }
+      }
+    }
+  } else
+    GrFillCircle(dc,x,y,dc->db_z,dc->thick);
+gr_done:
+  dc->color=old_color;
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return TRUE;
+}
+
+Bool GrLinePlot0(CDC *dc,I64 x,I64 y,I64 z)
+{//This is a callback.
+  CTask *win_task=dc->win_task;
+  if (!(dc->flags & DCF_SCRN_BITMAP) ||
+        win_task->next_task==sys_winmgr_task ||
+        dc->flags&DCF_ON_TOP ||
+        !IsPixCovered0(win_task,x,y)) {
+    dc->db_z=z;
+    GrPlot0(dc,x,y);
+  }
+  return TRUE;
+}
+
+Bool GrLinePlot(CDC *dc,I64 x,I64 y,I64 z)
+{//This is a callback.
+  dc->db_z=z;
+  GrPlot1(dc,x,y);
+  return TRUE;
+}
+
+public Bool GrLine(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
+        I64 step=1,I64 start=0)
+{//2D. Clipping but not transformation.
+  Bool res=FALSE;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  if (step==1 && !start && !dc->brush && !dc->depth_buf) {
+    if (DCClipLine(dc,&x1,&y1,&x2,&y2))
+      res=Line(dc,x1,y1,0,x2,y2,0,&GrLinePlot0,step,start);
+  } else
+    res=Line(dc,x1,y1,0,x2,y2,0,&GrLinePlot,step,start);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool GrCircle(CDC *dc=gr.dc,I64 cx,I64 cy,I64 radius,
+  I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//2D. Clipping but not transformation.
+  Bool res;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  res=Circle(dc,cx,cy,0,radius,&GrLinePlot,step,start_radians,len_radians);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool GrEllipse(CDC *dc=gr.dc,
+                I64 cx,I64 cy,
+                I64 x_radius,I64 y_radius,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//2D. Clipping but not transformation.
+  Bool res;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  res=Ellipse(dc,cx,cy,0,x_radius,y_radius,&GrLinePlot,
+        rot_angle,step,start_radians,len_radians);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool GrRegPoly(CDC *dc=gr.dc,
+                I64 cx,I64 cy,
+                I64 x_radius,I64 y_radius,I64 sides,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//2D. Clipping but no transform or thick.
+  Bool res;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  res=RegPoly(dc,cx,cy,0,x_radius,y_radius,sides,
+        &GrLinePlot,rot_angle,step,start_radians,len_radians);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool Gr2Bezier(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//2nd order. Clipping but no transform or thick.
+  return Bezier2(dc,ctrl,&GrLinePlot);
+}
+
+public Bool Gr3Bezier(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//3rd order. Clipping but no transform or thick.
+  return Bezier3(dc,ctrl,&GrLinePlot);
+}
+
+public Bool Gr2BSpline(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//2nd order. Clipping but no transform or thick.
+  return BSpline2(dc,ctrl,cnt,&GrLinePlot,closed);
+}
+
+public Bool Gr3BSpline(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//3rd order. Clipping but no transform or thick.
+  return BSpline3(dc,ctrl,cnt,&GrLinePlot,closed);
+}
+
+I64 GrLineFat3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
+        I64 width,I64 start=0)
+{//Step through line segment calling callback.
+//Uses fixed-point.
+  I64 res=0,i,j,d,dx=x2-x1,dy=y2-y1,dz=z2-z1,_x,_y,_z,d_lo,d_hi,
+        adx=AbsI64(dx),ady=AbsI64(dy),adz=AbsI64(dz);
+  if (width>0) {
+    if (adx>=ady) {
+      if (adx>=adz) {
+        if (d=adx) {
+          if (dx>=0)
+            dx=0x100000000;
+          else
+            dx=-0x100000000;
+          dy=dy<<32/d;
+          dz=dz<<32/d;
+        }
+      } else {
+        if (d=adz) {
+          dx=dx<<32/d;
+          dy=dy<<32/d;
+          if (dz>=0)
+            dz=0x100000000;
+          else
+            dz=-0x100000000;
+        }
+      }
+      x1<<=32; y1<<=32; z1<<=32;
+      for (j=0;j<start;j++) {
+        x1+=dx; y1+=dy; z1+=dz;
+      }
+      if (start>=d)
+        res+=GrFillCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width);
+      else {
+        if (width==1)
+          for (i=start;i<=d;i++) {
+            dc->db_z=z1.i32[1];
+            res+=GrPlot1(dc,x1.i32[1],y1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+        else {
+          i=width*Sqrt(SqrI64(adx)+SqrI64(ady))/adx;
+          d_lo=i>>1; d_hi=(i-1)>>1;
+
+          if (dx>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,2);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,7);
+          for (i=start;i<=d;i++) {
+            res+=GrVLine(dc,x1.i32[1],y1.i32[1]-d_lo,y1.i32[1]+d_hi,
+                  z1.i32[1],z1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+          x1-=dx; y1-=dy; z1-=dz;
+          if (dx>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,3);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,6);
+        }
+      }
+    } else {
+      if (ady>=adz) {
+        if (d=ady) {
+          dx=dx<<32/d;
+          if (dy>=0)
+            dy=0x100000000;
+          else
+            dy=-0x100000000;
+          dz=dz<<32/d;
+        }
+      } else {
+        if (d=adz) {
+          dx=dx<<32/d;
+          dy=dy<<32/d;
+          if (dz>=0)
+            dz=0x100000000;
+          else
+            dz=-0x100000000;
+        }
+      }
+      x1<<=32; y1<<=32; z1<<=32;
+      for (j=0;j<start;j++) {
+        x1+=dx; y1+=dy; z1+=dz;
+      }
+      if (start>=d)
+        res+=GrFillCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width);
+      else {
+        if (width==1)
+          for (i=start;i<=d;i++) {
+            dc->db_z=z1.i32[1];
+            res+=GrPlot1(dc,x1.i32[1],y1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+        else {
+          i=width*Sqrt(SqrI64(ady)+SqrI64(adx))/ady;
+          d_lo=i>>1; d_hi=(i-1)>>1;
+
+          if (dy>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,0);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,5);
+          for (i=start;i<=d;i++) {
+            res+=GrHLine(dc,x1.i32[1]-d_lo,x1.i32[1]+d_hi,y1.i32[1],
+                  z1.i32[1],z1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+          x1-=dx; y1-=dy; z1-=dz;
+          if (dy>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,1);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,4);
+        }
+      }
+    }
+  }
+  return res;
+}
+
+public Bool GrLine3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
+        I64 step=1,I64 start=0)
+{//3D. Transformation with thick.
+  I64 _x1,_y1,_z1,_x2,_y2,_z2;
+  Bool res=FALSE,was_transform=FALSE,was_symmetry=FALSE;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    (*dc->transform)(dc,&x2,&y2,&z2);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x1=x1; _y1=y1; _z1=z1;
+    DCReflect(dc,&_x1,&_y1,&_z1);
+    _x2=x2; _y2=y2; _z2=z2;
+    DCReflect(dc,&_x2,&_y2,&_z2);
+    dc->flags&=~DCF_SYMMETRY;
+    if (step==1 && !dc->brush) {
+      if (!start && dc->thick<2 && !dc->depth_buf) {//TODO: clip z depbuf
+        if (DCClipLine(dc,&_x1,&_y1,&_x2,&_y2))
+          res=Line(dc,_x1,_y1,0,_x2,_y2,0,&GrLinePlot0,step,start);
+      } else {
+        if (GrLineFat3(dc,_x1,_y1,_z1,_x2,_y2,_z2,dc->thick,start))
+          res=TRUE;
+      }
+    } else
+      res=Line(dc,_x1,_y1,_z1,_x2,_y2,_z2,&GrPlot3,step,start);
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  if (step==1 && !dc->brush) {
+    if (!start && dc->thick<2 && !dc->depth_buf) {//TODO: clip z depbuf
+      if (DCClipLine(dc,&x1,&y1,&x2,&y2))
+        res|=Line(dc,x1,y1,0,x2,y2,0,&GrLinePlot0,step,start);
+    } else {
+      if (GrLineFat3(dc,x1,y1,z1,x2,y2,z2,dc->thick,start))
+        res=TRUE;
+    }
+  } else
+    res|=Line(dc,x1,y1,z1,x2,y2,z2,&GrPlot3,step,start);
+gr_done:
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return res;
+}
+
+#help_index "Graphics/Char;Char/Graphics"
+
+public Bool GrPutChar3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 ch)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x,&y,&z);
+  return GrPutChar(dc,x,y,ch);
+}
+
+public I64 GrPrint3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *fmt,...)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res;
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x,&y,&z);
+  res=GrPrint(dc,x,y,"%s",buf);
+  Free(buf);
+  return res;
+}
+
+public I64 GrVPrint3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *fmt,...)
+{//3D. Vertical text. Transformation. DCF_SYMMETRY is silly.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res;
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x,&y,&z);
+  res=GrVPrint(dc,x,y,"%s",buf);
+  Free(buf);
+  return res;
+}
+
+#help_index "Graphics"
+
+public Bool GrEllipse3(CDC *dc=gr.dc,
+                I64 cx,I64 cy,I64 cz,
+                I64 x_radius,I64 y_radius,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//3D. Transformation with thick.
+  Bool res;
+  I64 x,y,z,xx,yy,zz;
+  F64 m1,arg1,m2,arg2,s,c;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    dc->flags&=~DCF_TRANSFORMATION;
+    (*dc->transform)(dc,&cx,&cy,&cz);
+
+    c=Cos(rot_angle);
+    s=Sin(rot_angle);
+
+    x_radius<<=16;
+    y_radius<<=16;
+
+    xx=0;
+    yy=0;
+    zz=0;
+    (*dc->transform)(dc,&xx,&yy,&zz);
+
+    x=x_radius*c;
+    y=x_radius*s;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m1,&arg1,x,y);
+
+    x=-y_radius*s;
+    y=y_radius*c;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m2,&arg2,x,y);
+    m2*=Abs(Sin(arg2-arg1));
+
+    res=Ellipse(dc,cx,cy,cz,
+          m1/0x10000,m2/0x10000,&GrPlot3,-arg1,step,start_radians,len_radians);
+    dc->flags|=DCF_TRANSFORMATION;
+  } else
+    res=Ellipse(dc,cx,cy,cz,x_radius,y_radius,&GrPlot3,
+          rot_angle,step,start_radians,len_radians);
+  return res;
+}
+
+public Bool GrCircle3(CDC *dc=gr.dc,I64 cx,I64 cy,I64 cz,I64 radius,
+  I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//3D. Transformation with thick.
+  if (dc->flags & DCF_TRANSFORMATION)
+    return GrEllipse3(dc,cx,cy,cz,radius,radius,0,step,
+          start_radians,len_radians);
+  else
+    return Circle(dc,cx,cy,cz,radius,&GrPlot3,step,
+          start_radians,len_radians);
+}
+
+public Bool GrRegPoly3(CDC *dc=gr.dc,
+                I64 cx,I64 cy,I64 cz,
+                I64 x_radius,I64 y_radius,I64 sides,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//3D. Clipping and transform and thick.
+  Bool res;
+  I64 x,y,z,xx,yy,zz;
+  F64 m1,arg1,m2,arg2,s,c;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    dc->flags&=~DCF_TRANSFORMATION;
+    (*dc->transform)(dc,&cx,&cy,&cz);
+
+    c=Cos(rot_angle);
+    s=Sin(rot_angle);
+
+    x_radius<<=16;
+    y_radius<<=16;
+
+    xx=0;
+    yy=0;
+    zz=0;
+    (*dc->transform)(dc,&xx,&yy,&zz);
+
+    x=x_radius*c;
+    y=x_radius*s;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m1,&arg1,x,y);
+
+    x=-y_radius*s;
+    y=y_radius*c;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m2,&arg2,x,y);
+    m2*=Abs(Sin(arg2-arg1));
+
+    res=RegPoly(dc,cx,cy,cz,
+          m1/0x10000,m2/0x10000,sides,&GrPlot3,-arg1,
+          step,start_radians,len_radians);
+    dc->flags|=DCF_TRANSFORMATION;
+  } else
+    res=RegPoly(dc,cx,cy,cz,x_radius,y_radius,sides,&GrPlot3,
+          rot_angle,step,start_radians,len_radians);
+  return res;
+}
+
+public I64 GrFloodFill3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,Bool not_color=FALSE)
+{//3D. Transformation.
+//not_color=TRUE means fill up to everything which is not the current color.
+  //not_color=FALSE means fill all parts equ to the color under the point.
+  //Returns cnt of pixs changed
+  I64 res,old_flags=dc->flags,
+        _x,_y,_z;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    dc->flags&=~DCF_TRANSFORMATION;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x=x1; _y=y1; _z=z1;
+    DCReflect(dc,&_x,&_y,&_z);
+    dc->flags&=~DCF_SYMMETRY;
+    res=GrFloodFill(dc,_x,_y,not_color,_z,dc->depth_buf);
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  res=GrFloodFill(dc,x1,y1,not_color,z1,dc->depth_buf);
+gr_done:
+  dc->flags=old_flags;
+  return res;
+}
+
+#help_index "Graphics;Graphics/Device Contexts"
+
+Option(OPTf_WARN_HEADER_MISMATCH,OFF);
+public I64 GrBlot3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,CDC *img)
+{//3D. Clipping and transformation.
+  CColorROPU32 old_color=dc->color;
+  I64  color,reg i,j,w=img->width,h=img->height,
+        d1,dx1,dy1,dz1,
+        reg d2,dx2,dy2,dz2,
+        adx1,ady1,adz1,
+        adx2,ady2,adz2,
+        x2,y2,z2,x3,y3,z3,
+        dw,reg dh,x,y,_x1,_y1,_z1,_x2,_y2,_z2,_x3,_y3,_z3,
+        last_x,last_y,res=0;
+  Bool first;
+  CDC *old_brush=dc->brush;
+
+  if (dc->depth_buf || dc->flags & (DCF_TRANSFORMATION | DCF_SYMMETRY)) {
+    x2=x1+w; y2=y1; z2=z1;
+    x3=x1; y3=y1+h; z3=z1;
+    if (dc->flags & DCF_TRANSFORMATION) {
+      (*dc->transform)(dc,&x1,&y1,&z1);
+      (*dc->transform)(dc,&x2,&y2,&z2);
+      (*dc->transform)(dc,&x3,&y3,&z3);
+    }
+    if (dc->flags & DCF_SYMMETRY) {
+      _x1=x1; _y1=y1; _z1=z1;
+      DCReflect(dc,&_x1,&_y1,&_z1);
+      _x2=x2; _y2=y2; _z2=z2;
+      DCReflect(dc,&_x2,&_y2,&_z2);
+      _x3=x3; _y3=y3; _z3=z3;
+      DCReflect(dc,&_x3,&_y3,&_z3);
+      dx1=_x2-_x1; dy1=_y2-_y1; dz1=_z2-_z1;
+      dx2=_x3-_x1; dy2=_y3-_y1; dz2=_z3-_z1;
+      adx1=AbsI64(dx1); ady1=AbsI64(dy1); adz1=AbsI64(dz1);
+      adx2=AbsI64(dx2); ady2=AbsI64(dy2); adz2=AbsI64(dz2);
+
+      if (adx1>=ady1) {
+        if (adx1>=adz1)
+          d1=adx1;
+        else
+          d1=adz1;
+      } else {
+        if (ady1>=adz1)
+          d1=ady1;
+        else
+          d1=adz1;
+      }
+      if (adx2>=ady2) {
+        if (adx2>=adz2)
+          d2=adx2;
+        else
+          d2=adz2;
+      } else {
+        if (ady2>=adz2)
+          d2=ady2;
+        else
+          d2=adz2;
+      }
+
+      if (AbsI64(d1)!=w ||AbsI64(d2)!=h) {
+        d1<<=1;
+        d2<<=1;
+      }
+      if (d1) {
+        dx1=dx1<<32/d1;
+        dy1=dy1<<32/d1;
+        dz1=dz1<<32/d1;
+      } else
+        goto normal_image;
+      if (d2) {
+        dx2=dx2<<32/d2;
+        dy2=dy2<<32/d2;
+        dz2=dz2<<32/d2;
+      } else
+        goto normal_image;
+      dc->brush=NULL;
+      x=0;y=0;
+      dw=w<<32/d1;
+      dh=h<<32/d2;
+
+      first=TRUE;
+      _x1<<=32; _y1<<=32; _z1<<=32;
+      for (j=0;j<=d1;j++) {
+        _x2=_x1; _y2=_y1; _z2=_z1;
+        y=0;
+        for (i=0;i<=d2;i++) {
+          if (_x2.i32[1]!=last_x || _y2.i32[1]!=last_y ||first) {
+            if ((color=GrPeek(img,x.i32[1],y.i32[1]))>=0) {
+              if (dc->color.c0.rop==ROPB_MONO) {
+                if (color) {
+                  dc->color=old_color&~ROPF_DITHER;
+                  if (dc->depth_buf) {
+                    dc->db_z=_z2.i32[1];
+                    GrPlot1(dc,_x2.i32[1],_y2.i32[1]);
+                  } else
+                    GrPlot(dc,_x2.i32[1],_y2.i32[1]);
+                }
+              } else {
+                if (color!=TRANSPARENT) {
+                  dc->color=old_color&~COLORROP_NO_ROP0_MASK|color;
+                  if (dc->depth_buf) {
+                    dc->db_z=_z2.i32[1];
+                    GrPlot1(dc,_x2.i32[1],_y2.i32[1]);
+                  } else
+                    GrPlot(dc,_x2.i32[1],_y2.i32[1]);
+                }
+              }
+            }
+          }
+          first=FALSE;
+          last_x=_x2.i32[1]; last_y=_y2.i32[1];
+          _x2+=dx2; _y2+=dy2; _z2+=dz2;
+          y+=dh;
+        }
+        _x1+=dx1; _y1+=dy1; _z1+=dz1;
+        x+=dw;
+      }
+      res=1;
+normal_image:
+      if (dc->flags&DCF_JUST_MIRROR)
+        goto gr_done;
+    }
+    dx1=x2-x1; dy1=y2-y1; dz1=z2-z1;
+    dx2=x3-x1; dy2=y3-y1; dz2=z3-z1;
+    adx1=AbsI64(dx1); ady1=AbsI64(dy1); adz1=AbsI64(dz1);
+    adx2=AbsI64(dx2); ady2=AbsI64(dy2); adz2=AbsI64(dz2);
+
+    if (adx1>=ady1) {
+      if (adx1>=adz1)
+        d1=adx1;
+      else
+        d1=adz1;
+    } else {
+      if (ady1>=adz1)
+        d1=ady1;
+      else
+        d1=adz1;
+    }
+    if (adx2>=ady2) {
+      if (adx2>=adz2)
+        d2=adx2;
+      else
+        d2=adz2;
+    } else {
+      if (ady2>=adz2)
+        d2=ady2;
+      else
+        d2=adz2;
+    }
+    if (AbsI64(d1)!=w ||AbsI64(d2)!=h) {
+      d1<<=1;
+      d2<<=1;
+    }
+    if (d1) {
+      dx1=dx1<<32/d1;
+      dy1=dy1<<32/d1;
+      dz1=dz1<<32/d1;
+    } else
+      goto gr_done;
+    if (d2) {
+      dx2=dx2<<32/d2;
+      dy2=dy2<<32/d2;
+      dz2=dz2<<32/d2;
+    } else
+      goto gr_done;
+    dc->brush=NULL;
+    x=0;y=0;
+    dw=w<<32/d1;
+    dh=h<<32/d2;
+
+    first=TRUE;
+    x1<<=32; y1<<=32; z1<<=32;
+    for (j=0;j<=d1;j++) {
+      x2=x1; y2=y1; z2=z1;
+      y=0;
+      for (i=0;i<=d2;i++) {
+        if (x2.i32[1]!=last_x || y2.i32[1]!=last_y || first) {
+          if ((color=GrPeek(img,x.i32[1],y.i32[1]))>=0) {
+            if (dc->color.c0.rop==ROPB_MONO) {
+              if (color) {
+                dc->color=old_color&~ROPF_DITHER;
+                if (dc->depth_buf) {
+                  dc->db_z=z2.i32[1];
+                  GrPlot1(dc,x2.i32[1],y2.i32[1]);
+                } else
+                  GrPlot(dc,x2.i32[1],y2.i32[1]);
+              }
+            } else {
+              if (color!=TRANSPARENT) {
+                dc->color=old_color&~COLORROP_NO_ROP0_MASK|color;//COLOR
+                if (dc->depth_buf) {
+                  dc->db_z=z2.i32[1];
+                  GrPlot1(dc,x2.i32[1],y2.i32[1]);
+                } else
+                  GrPlot(dc,x2.i32[1],y2.i32[1]);
+              }
+            }
+          }
+        }
+        first=FALSE;
+        last_x=x2.i32[1]; last_y=y2.i32[1];
+        x2+=dx2; y2+=dy2; z2+=dz2;
+        y+=dh;
+      }
+      x1+=dx1; y1+=dy1; z1+=dz1;
+      x+=dw;
+    }
+    res=1;  //TODO: check off scrn
+  } else
+    res=GrBlot(dc,x1,y1,img);
+gr_done:
+  dc->color=old_color;
+  dc->brush=old_brush;
+  return res;
+}
+Option(OPTf_WARN_HEADER_MISMATCH,ON);
+
+#help_index "Graphics"
+
+public Bool Gr2Bezier3(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//2nd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*3);
+    for (i=0;i<3;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*3);
+    for (i=0;i<3;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=Bezier2(dc,ctrl3,&GrPlot3);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=Bezier2(dc,ctrl,&GrPlot3);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public Bool Gr3Bezier3(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//3rd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*4);
+    for (i=0;i<4;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*4);
+    for (i=0;i<4;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=Bezier3(dc,ctrl3,&GrPlot3);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=Bezier3(dc,ctrl,&GrPlot3);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public I64 Gr2BSpline3(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//2nd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=BSpline2(dc,ctrl3,cnt,&GrPlot3,closed);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=BSpline2(dc,ctrl,cnt,&GrPlot3,closed);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public Bool Gr3BSpline3(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//3rd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=BSpline3(dc,ctrl3,cnt,&GrPlot3,closed);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=BSpline3(dc,ctrl,cnt,&GrPlot3,closed);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public I64 GrFillTri0(CDC *dc=gr.dc,CD3I32 *p1,CD3I32 *p2,CD3I32 *p4)
+{//3D. Returns cnt of pixs changed
+  I64 x1,x2,y1,y2,z1,z2,dx1,dy1,dz1,dx2,dy2,dz2,res=0,i,min,max;
+  CTask *win_task;
+
+  if (AbsI64(p1->y-p2->y)+AbsI64(p1->y-p4->y)<=
+        AbsI64(p1->x-p2->x)+AbsI64(p1->x-p4->x)) {
+//p1 is min x
+    if (p4->x<p2->x)
+      SwapI64(&p4,&p2);
+    if (p2->x<p1->x)
+      SwapI64(&p2,&p1);
+
+      //p2y<=p4y
+    if (p4->y<p2->y)
+      SwapI64(&p4,&p2);
+
+    min=0;
+    max=dc->height;
+    if (dc->flags & DCF_SCRN_BITMAP) {
+      win_task=dc->win_task;
+      min-=win_task->scroll_y+win_task->pix_top;
+      max-=win_task->scroll_y+win_task->pix_top;
+      if (max>win_task->pix_bottom-(win_task->scroll_y+win_task->pix_top))
+        max=win_task->pix_bottom-(win_task->scroll_y+win_task->pix_top);
+    }
+
+    if ((dy2=p4->y-p1->y)<0) {
+      dy1=p2->y-p1->y;
+      dx1=(p1->x-p2->x)<<32/dy1;
+      dz1=(p1->z-p2->z)<<32/dy1;
+
+      dx2=(p1->x-p4->x)<<32/dy2;
+      dz2=(p1->z-p4->z)<<32/dy2;
+      x1=x2=p1->x<<32; y1=p1->y; z1=z2=p1->z<<32;
+      if (y1+dy2<min) {
+        i=min-(y1+dy2);
+        if (i>-dy2) goto ft_done;
+        dy2+=i;
+      }
+      if (y1>=max) {
+        i=y1-max+1;
+        if (i>-dy2)
+          i=-dy2;
+        dy2+=i;
+        y1-=i;
+        x1+=dx1*i;
+        x2+=dx2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dy2++) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1--;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dy2=p2->y-p4->y) {
+        dx2=(p4->x-p2->x)<<32/dy2;
+        dz2=(p4->z-p2->z)<<32/dy2;
+        if (y1+dy2<min) {
+          i=min-(y1+dy2);
+          if (i>-dy2) goto ft_done;
+          dy2+=i;
+        }
+        if (y1>=max) {
+          i=y1-max+1;
+          if (i>-dy2) goto ft_done;
+          dy2+=i;
+          y1-=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dy2++<=0) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1--;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else if ((dy2=p2->y-p1->y)>0) {
+      dy1=p4->y-p1->y;
+      dx1=(p4->x-p1->x)<<32/dy1;
+      dz1=(p4->z-p1->z)<<32/dy1;
+
+      dx2=(p2->x-p1->x)<<32/dy2;
+      dz2=(p2->z-p1->z)<<32/dy2;
+      x1=x2=p1->x<<32; y1=p1->y; z1=z2=p1->z<<32;
+      if (y1+dy2>=max) {
+        i=y1+dy2-max+1;
+        if (i>dy2) goto ft_done;
+        dy2-=i;
+      }
+      if (y1<min) {
+        i=min-y1;
+        if (i>dy2)
+          i=dy2;
+        dy2-=i;
+        y1+=i;
+        x1+=dx1*i;
+        x2+=dx2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dy2--) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1++;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dy2=p4->y-p2->y) {
+        dx2=(p4->x-p2->x)<<32/dy2;
+        dz2=(p4->z-p2->z)<<32/dy2;
+        if (y1+dy2>=max) {
+          i=y1+dy2-max+1;
+          if (i>dy2) goto ft_done;
+          dy2-=i;
+        }
+        if (y1<min) {
+          i=min-y1;
+          if (i>dy2) goto ft_done;
+          dy2-=i;
+          y1+=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dy2-->=0) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1++;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else {
+      if (dy1=p2->y-p1->y) {
+        dx1=(p2->x-p1->x)<<32/dy1;
+        dz1=(p2->z-p1->z)<<32/dy1;
+        if (dy2=p2->y-p4->y) {
+          dx2=(p2->x-p4->x)<<32/dy2;
+          dz2=(p2->z-p4->z)<<32/dy2;
+        } else {
+          dx2=0;
+          dz2=0;
+        }
+        x1=x2=p2->x<<32; y1=p2->y; z1=z2=p2->z<<32;
+        if (y1<min) {
+          i=min-y1;
+          if (i>-dy1)
+            i=-dy1;
+          dy1+=i;
+          y1+=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dy1++<=0) {
+          if (y1<max)
+            res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+          y1++;
+          x1+=dx1;
+          x2+=dx2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+      if (dy1=p4->y-p1->y) {
+        dx1=(p1->x-p4->x)<<32/dy1;
+        dz1=(p1->z-p4->z)<<32/dy1;
+        if (dy2=p4->y-p2->y) {
+          dx2=(p2->x-p4->x)<<32/dy2;
+          dz2=(p2->z-p4->z)<<32/dy2;
+        } else {
+          dx2=0;
+          dz2=0;
+        }
+        x1=x2=p4->x<<32; y1=p4->y; z1=z2=p4->z<<32;
+        if (y1-dy1<min) {
+          i=min-(y1-dy1);
+          if (i>dy1) goto ft_done;
+          dy1-=i;
+        }
+        if (y1>=max) {
+          i=y1-max+1;
+          if (i>dy1) goto ft_done;
+          dy1-=i;
+          y1-=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dy1-->=0) {
+          res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+          y1--;
+          x1+=dx1;
+          x2+=dx2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+    }
+  } else {
+//p1 is min y
+    if (p4->y<p2->y)
+      SwapI64(&p4,&p2);
+    if (p2->y<p1->y)
+      SwapI64(&p2,&p1);
+
+      //p2x<=p4x
+    if (p4->x<p2->x)
+      SwapI64(&p4,&p2);
+
+    min=0;
+    max=dc->width;
+    if (dc->flags & DCF_SCRN_BITMAP) {
+      win_task=dc->win_task;
+      min-=win_task->scroll_x+win_task->pix_left;
+      max-=win_task->scroll_x+win_task->pix_left;
+      if (max>win_task->pix_right-(win_task->scroll_x+win_task->pix_left))
+        max=win_task->pix_right-(win_task->scroll_x+win_task->pix_left);
+    }
+
+    if ((dx2=p4->x-p1->x)<0) {
+      dx1=p2->x-p1->x;
+      dy1=(p1->y-p2->y)<<32/dx1;
+      dz1=(p1->z-p2->z)<<32/dx1;
+
+      dy2=(p1->y-p4->y)<<32/dx2;
+      dz2=(p1->z-p4->z)<<32/dx2;
+      y1=y2=p1->y<<32; x1=p1->x; z1=z2=p1->z<<32;
+      if (x1+dx2<min) {
+        i=min-(x1+dx2);
+        if (i>-dx2) goto ft_done;
+        dx2+=i;
+      }
+      if (x1>=max) {
+        i=x1-max+1;
+        if (i>-dx2)
+          i=-dx2;
+        dx2+=i;
+        x1-=i;
+        y1+=dy1*i;
+        y2+=dy2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dx2++) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1--;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dx2=p2->x-p4->x) {
+        dy2=(p4->y-p2->y)<<32/dx2;
+        dz2=(p4->z-p2->z)<<32/dx2;
+        if (x1+dx2<min) {
+          i=min-(x1+dx2);
+          if (i>-dx2) goto ft_done;
+          dx2+=i;
+        }
+        if (x1>=max) {
+          i=x1-max+1;
+          if (i>-dx2) goto ft_done;
+          dx2+=i;
+          x1-=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dx2++<=0) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1--;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else if ((dx2=p2->x-p1->x)>0) {
+      dx1=p4->x-p1->x;
+      dy1=(p4->y-p1->y)<<32/dx1;
+      dz1=(p4->z-p1->z)<<32/dx1;
+
+      dy2=(p2->y-p1->y)<<32/dx2;
+      dz2=(p2->z-p1->z)<<32/dx2;
+      y1=y2=p1->y<<32; x1=p1->x; z1=z2=p1->z<<32;
+      if (x1+dx2>=max) {
+        i=x1+dx2-max+1;
+        if (i>dx2) goto ft_done;
+        dx2-=i;
+      }
+      if (x1<min) {
+        i=min-x1;
+        if (i>dx2)
+          i=dx2;
+        dx2-=i;
+        x1+=i;
+        y1+=dy1*i;
+        y2+=dy2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dx2--) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1++;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dx2=p4->x-p2->x) {
+        dy2=(p4->y-p2->y)<<32/dx2;
+        dz2=(p4->z-p2->z)<<32/dx2;
+        if (x1+dx2>=max) {
+          i=x1+dx2-max+1;
+          if (i>dx2) goto ft_done;
+          dx2-=i;
+        }
+        if (x1<min) {
+          i=min-x1;
+          if (i>dx2) goto ft_done;
+          dx2-=i;
+          x1+=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dx2-->=0) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1++;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else {
+      if (dx1=p2->x-p1->x) {
+        dy1=(p2->y-p1->y)<<32/dx1;
+        dz1=(p2->z-p1->z)<<32/dx1;
+        if (dx2=p2->x-p4->x) {
+          dy2=(p2->y-p4->y)<<32/dx2;
+          dz2=(p2->z-p4->z)<<32/dx2;
+        } else {
+          dy2=0;
+          dz2=0;
+        }
+        y1=y2=p2->y<<32; x1=p2->x; z1=z2=p2->z<<32;
+        if (x1<min) {
+          i=min-x1;
+          if (i>-dx1)
+            i=-dx1;
+          dx1+=i;
+          x1+=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dx1++<=0) {
+          if (x1<max)
+            res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+          x1++;
+          y1+=dy1;
+          y2+=dy2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+      if (dx1=p4->x-p1->x) {
+        dy1=(p1->y-p4->y)<<32/dx1;
+        dz1=(p1->z-p4->z)<<32/dx1;
+        if (dx2=p4->x-p2->x) {
+          dy2=(p2->y-p4->y)<<32/dx2;
+          dz2=(p2->z-p4->z)<<32/dx2;
+        } else {
+          dy2=0;
+          dz2=0;
+        }
+        y1=y2=p4->y<<32; x1=p4->x; z1=z2=p4->z<<32;
+        if (x1-dx1<min) {
+          i=min-(x1-dx1);
+          if (i>dx1) goto ft_done;
+          dx1-=i;
+        }
+        if (x1>=max) {
+          i=x1-max+1;
+          if (i>dx1) goto ft_done;
+          dx1-=i;
+          x1-=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dx1-->=0) {
+          res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+          x1--;
+          y1+=dy1;
+          y2+=dy2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+    }
+  }
+ft_done:
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrScrn.HC.HTML b/public/Wb/Adam/Gr/GrScrn.HC.HTML new file mode 100755 index 0000000..2eba4fb --- /dev/null +++ b/public/Wb/Adam/Gr/GrScrn.HC.HTML @@ -0,0 +1,454 @@ + + + + + + + + + + + +
+#help_index "Graphics/Scrn"
+
+U0 GrUpdateTaskODEs(CTask *task)
+{
+  sys_task_being_scrn_updated=task;
+  try
+    ODEsUpdate(task);
+  catch {
+    LBts(&task->win_inhibit,WIf_SELF_ODE);
+    "Exception in WinMgr: Update Task ODEs\n";
+    PutExcept;
+    Sleep(3000);
+    VGAFlush;
+  }
+  sys_task_being_scrn_updated=NULL;
+}
+
+U0 GrUpdateTaskWin(CTask *task)
+{ //Draw a win.  Only Core0 tasks have a win.
+  CDC *dc;
+  CD3I64 saved_scroll;
+  sys_task_being_scrn_updated=task;
+  try {
+    if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER))
+      TextBorder(Fs,task->win_left,task->win_right,task->win_top,
+            task->win_bottom,task->border_attr,task==sys_focus_task);
+    TextRect(task->win_left,task->win_right,
+          task->win_top,task->win_bottom,task->text_attr<<8);
+    if (task==sys_winmgr_task) {
+      if (gr.fp_wall_paper)
+        (*gr.fp_wall_paper)(task);
+    } else if (!(task->win_inhibit&WIF_SELF_DOC))
+      DocUpdateTaskDocs(task);
+    if (TaskValidate(task)) {
+      if (task->draw_it) {
+        dc=DCAlias(gr.dc2,task);
+        (*task->draw_it)(task,dc);
+        DCDel(dc);
+      }
+      if (TaskValidate(task)) {
+        WinScrollNull(task,&saved_scroll);
+        DrawCtrls(task);
+        WinScrollRestore(task,&saved_scroll);
+      }
+    }
+  } catch {
+    if (task!=Fs && TaskValidate(task)) {
+      LBtr(&task->display_flags,DISPLAYf_SHOW);
+      "Exception in WinMgr: Update Task Win\n";
+      PutExcept;
+      Sleep(3000);
+      VGAFlush;
+    }
+  }
+  sys_task_being_scrn_updated=NULL;
+}
+
+U0 GrUpdateTasks()
+{//Only called by WinMgr
+  I64 i;
+  CTask *task,*task1;
+  try {
+    winmgr.ode_time=0;
+    if (Bt(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0))
+      WinZBufUpdate;
+    task1=task=sys_winmgr_task;
+    do { //Loop through Core0 tasks.
+      if (!TaskValidate(task)) break;
+      if (Bt(&task->display_flags,DISPLAYf_SHOW) &&
+            Bt(gr.win_uncovered_bitmap,task->win_z_num))
+        GrUpdateTaskWin(task);
+      if (!TaskValidate(task)) break;
+      task=task->next_task;
+    } while (task!=task1);
+
+    for (i=0;i<mp_cnt;i++) { //Loop through all cores.
+      task1=task=cpu_structs[i].seth_task;
+      do {
+        if (!TaskValidate(task)) break;
+        GrUpdateTaskODEs(task);
+        if (!TaskValidate(task)) break;
+        task=task->next_task;
+      } while (task!=task1);
+    }
+  } catch {
+    PutExcept(FALSE);
+    Dbg("Exception in WinMgr");
+  }
+  winmgr.last_ode_time=winmgr.ode_time;
+  ode_alloced_factor=LowPass1(0.1,ode_alloced_factor,
+        Clamp(Gs->idle_factor-0.1,0.2,0.8),1/winmgr.fps);
+  sys_task_being_scrn_updated=NULL;
+}
+
+U0 GrFixZoomScale()
+{
+  gr.scrn_zoom=ClampI64(gr.scrn_zoom,1,GR_SCRN_ZOOM_MAX);
+  if (gr.scrn_zoom==1) {
+    gr.sx=0;
+    gr.sy=0;
+  } else {
+    gr.sx=ClampI64(gr.sx,0,GR_WIDTH-GR_WIDTH/gr.scrn_zoom)&~7;
+    gr.sy=ClampI64(gr.sy,0,GR_HEIGHT-GR_HEIGHT/gr.scrn_zoom);
+  }
+}
+
+public U0 GrScaleZoom(F64 scale)
+{//Multiply zoom factor larger or smaller.
+  F64 s=gr.scrn_zoom;
+  gr.scrn_zoom=gr.scrn_zoom*scale;
+  GrFixZoomScale;
+  s/=gr.scrn_zoom;
+  ms.scale.x*=s;
+  ms.scale.y*=s;
+  ms.scale.z*=s;
+  ms.offset.x=ms.pos.x-(ms.pos.x-ms.offset.x)*s;
+  ms.offset.y=ms.pos.y-(ms.pos.y-ms.offset.y)*s;
+  ms.offset.z=ms.pos.z-(ms.pos.z-ms.offset.z)*s;
+  gr.sx=ms.pos.x-gr.zoomed_dc->width >>1/gr.scrn_zoom;
+  gr.sy=ms.pos.y-gr.zoomed_dc->height>>1/gr.scrn_zoom;
+  GrFixZoomScale;
+}
+
+U0 GrZoomInScrn()
+{
+  GrFixZoomScale;
+  I64 plane,row,col,k,l,
+        d2=gr.zoomed_dc->width>>3/gr.scrn_zoom,
+        d4=gr.zoomed_dc->width_internal>>3,
+        d5=d4-d2*gr.scrn_zoom,
+        d3=gr.zoomed_dc->height/gr.scrn_zoom,
+        d6=(gr.zoomed_dc->height-d3)*gr.dc1->width_internal>>3,
+        d7=gr.zoomed_dc->height%gr.scrn_zoom*d4;
+  U8 *src,*src2,*dst,*src3,*map=gr.scrn_zoom_tables[gr.scrn_zoom];
+
+  src=gr.dc1->body+gr.sx>>3+gr.sy*gr.dc1->width_internal>>3;
+  dst=gr.zoomed_dc->body;
+  for (plane=1;plane<0x10;plane<<=1) {
+    row=d3;
+    while (row--) {
+      k=gr.scrn_zoom;
+      while (k--) {
+        src2=src;
+        col=d2;
+        while (col--) {
+          src3=&map[*src2++];
+          l=gr.scrn_zoom;
+          while (l--) {
+            *dst++=*src3;
+            src3+=256;
+          }
+        }
+        l=d5;
+        while (l--)
+          *dst++=0;
+      }
+      src+=d4;
+    }
+    l=d7;
+    while (l--)
+      *dst++=0;
+    src+=d6;
+  }
+}
+
+U0 GrUpdateTextBG()
+{
+  I64 reg RSI *dst=gr.dc2->body,reg R13 c,row,col,
+        num_rows=TEXT_ROWS,num_cols=TEXT_COLS,i,j,cur_ch,
+        reg R12 w1=gr.dc2->width_internal,w2=-7*w1+8,w3=7*w1,w4=0;
+  U32 *src=gr.text_base;
+  Bool blink_flag=Blink;
+  U8 *dst2=dst;
+
+  if (gr.pan_text_x||gr.hide_col) {
+    gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
+    j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
+    num_cols-=j;
+    if (gr.pan_text_x<0) {
+      src+=j;
+      i=FONT_WIDTH*j+gr.pan_text_x;
+    } else
+      i=gr.pan_text_x;
+    dst2=dst(U8 *)+i;
+    w4=j;
+    w3+=j*FONT_WIDTH;
+
+    j*=FONT_WIDTH;
+    dst(U8 *)=gr.dc2->body;
+    for (row=num_rows*FONT_HEIGHT;row--;) {
+      for (col=i;col--;)
+        *dst(U8 *)++=0;
+      dst(U8 *)+=w1-i-j;
+      for (col=j;col--;)
+        *dst(U8 *)++=0;
+    }
+  }
+  dst=dst2;
+
+  if (gr.pan_text_y||gr.hide_row) {
+    gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
+    j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
+    num_rows-=j;
+    if (gr.pan_text_y<0) {
+      src+=w1/FONT_WIDTH*j;
+      i=w1*(FONT_HEIGHT*j+gr.pan_text_y);
+    } else
+      i=w1*gr.pan_text_y;
+    dst2=dst(U8 *)+i;
+
+    j*=w1*FONT_HEIGHT;
+    dst(U8 *)=gr.dc2->body;
+    for (row=i;row--;)
+      *dst(U8 *)++=0;
+    dst(U8 *)=gr.dc2->body+TEXT_ROWS*TEXT_COLS*FONT_HEIGHT*FONT_WIDTH-j;
+    for (row=j;row--;)
+      *dst(U8 *)++=0;
+  }
+  dst=dst2;
+
+  for (row=num_rows;row--;) {
+    for (col=num_cols;col--;) {
+      cur_ch=*src++;
+      if (cur_ch & (ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
+        if (cur_ch & ATTRF_SEL)
+          cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+        if (cur_ch & ATTRF_INVERT)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+        if (cur_ch & ATTRF_BLINK && blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      }
+      c=gr.to_8_colors[cur_ch.u8[1]>>4];
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      dst(U8 *)+=w2;
+    }
+    src+=w4;
+    dst(U8 *)+=w3;
+  }
+}
+
+U0 GrUpdateTextFG()
+{//See TextBase Layer.
+  U32 *src=gr.text_base;
+  I64 i,j,cur_ch,*dst=gr.dc2->body,
+        w1=gr.dc2->width_internal,w2=7*w1,w4=0,
+        num_rows=TEXT_ROWS,num_cols=TEXT_COLS,row,col;
+  U8 *dst_start=gr.dc2->body,*dst_end=dst_start+w1*gr.dc2->height-7*w1-8;
+  Bool blink_flag=Blink;
+
+  if (gr.pan_text_x||gr.hide_col) {
+    gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
+    j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
+    num_cols-=j;
+    if (gr.pan_text_x<0) {
+      src+=j;
+      dst(U8 *)+=FONT_WIDTH*j;
+    }
+    w4=j;
+    w2+=j*FONT_WIDTH;
+  }
+
+  if (gr.pan_text_y||gr.hide_row) {
+    gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
+    j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
+    num_rows-=j;
+    if (gr.pan_text_y<0) {
+      src+=w1/FONT_WIDTH*j;
+      dst(U8 *)+=w1*FONT_HEIGHT*j;
+    }
+  }
+
+  for (row=num_rows;row--;) {
+    for (col=num_cols;col--;) {
+      cur_ch=*src++;
+      if (cur_ch & (ATTRF_UNDERLINE|ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
+        if (cur_ch & ATTRF_SEL)
+          cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+        if (cur_ch & ATTRF_INVERT)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+        if (cur_ch & ATTRF_BLINK && blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      }
+      if (i=cur_ch.u16[1]&0x3FF+gr.pan_text_x+gr.pan_text_y<<5) {
+        j=i&0x1F;
+        if (j&0x10) j|=~0x1F;
+        i>>=5;
+        if (i&0x10) i|=~0x1F;
+        i=w1*i+j;
+        if (dst_start<=dst(U8 *)+i<dst_end)
+          GrRopEquU8NoClipping(cur_ch&(ATTRF_UNDERLINE+0xFFF),dst(U8 *)+i,w1);
+      } else
+        GrRopEquU8NoClipping(cur_ch&(ATTRF_UNDERLINE+0xFFF),dst,w1);
+      dst(U8 *)+=8;
+    }
+    src+=w4;
+    dst(U8 *)+=w2;
+  }
+}
+
+U0 DCBlotColor8(CDC *dc,CDC *img)
+{
+  U8  *src=img->body,*b0=dc->body;
+  I64 j,k,d0=img->width_internal*img->height;
+  for (k=0;k<d0;k++) {
+    j=*src++;
+    if (j!=TRANSPARENT)
+      *b0++=j;
+    else
+      b0++;
+  }
+}
+
+U0 GrUpdateTextModeText()
+{
+  U32 *src=gr.text_base;
+  I64 cur_ch,i=TEXT_COLS*TEXT_ROWS;
+  U16 *dst=text.vga_text_alias,*dst2=gr.vga_text_cache;
+  Bool blink_flag=Blink;
+  if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
+    while (i--) {
+      cur_ch=*src++;
+      if (cur_ch & ATTRF_SEL)
+        cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+      if (cur_ch & ATTRF_INVERT)
+        cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      if (cur_ch & ATTRF_BLINK)
+        if (blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      *dst++=*dst2++=cur_ch&0x7FFF;
+    }
+  } else {
+    while (i--) {
+      cur_ch=*src++;
+      if (cur_ch & ATTRF_SEL)
+        cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+      if (cur_ch & ATTRF_INVERT)
+        cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      if (cur_ch & ATTRF_BLINK)
+        if (blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      cur_ch&=0x7FFF;
+      if (*dst2!=cur_ch)
+        *dst++=*dst2++=cur_ch;
+      else {
+        dst++;
+        dst2++;
+      }
+    }
+  }
+}
+
+U0 GrUpdateVGAGraphics()
+{//Update Graphic Card
+  I64 row,plane,d=gr.zoomed_dc->width_internal>>6;
+  U32 *src,*vga,*dst;
+  if (gr.scrn_zoom==1)
+    src=gr.dc1->body;
+  else {
+    GrZoomInScrn;
+    src=gr.zoomed_dc->body;
+  }
+  dst=gr.scrn_image->body;
+  if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
+    for (plane=1;plane<0x10;plane<<=1) {
+      OutU8(VGAP_IDX,VGAR_MAP_MASK);
+      OutU8(VGAP_DATA,plane);
+      vga=text.vga_alias;
+      row=gr.zoomed_dc->height;
+      while (row--)
+        GrUpdateLine64FlushCache(&vga,&src,d,&dst);
+    }
+  } else {
+    for (plane=1;plane<0x10;plane<<=1) {
+      OutU8(VGAP_IDX,VGAR_MAP_MASK);
+      OutU8(VGAP_DATA,plane);
+      vga=text.vga_alias;
+      row=gr.zoomed_dc->height;
+      while (row--)
+        GrUpdateLine64(&vga,&src,d,&dst);
+    }
+  }
+}
+
+U0 GrUpdateScrn()
+{//Called by the Window Manager HERE, 30 times a second.
+  CDC *dc;
+  if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
+    GrUpdateTasks;
+  else {
+    GrUpdateTextBG;
+    GrUpdateTextFG;
+    GrUpdateTasks;
+    DCBlotColor8(gr.dc2,gr.dc);
+  }
+
+  dc=DCAlias(gr.dc2,Fs);
+  dc->flags|=DCF_ON_TOP;
+  if (gr.fp_final_scrn_update)
+    (*gr.fp_final_scrn_update)(dc);
+  DCDel(dc);
+
+  if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
+    GrUpdateTextModeText;
+  else {
+    DCBlotColor4(gr.dc1->body,gr.dc2->body,gr.dc_cache->body,
+          gr.dc2->height*gr.dc2->width_internal>>3);
+    GrUpdateVGAGraphics;
+  }
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrSpritePlot.HC.HTML b/public/Wb/Adam/Gr/GrSpritePlot.HC.HTML new file mode 100755 index 0000000..376a839 --- /dev/null +++ b/public/Wb/Adam/Gr/GrSpritePlot.HC.HTML @@ -0,0 +1,506 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+/*
+CSprites are stored as a sequence of var
+length operations with a 1-byte type leading
+each operation.  They are stored, one after another,
+in a chunk of memory terminated by a zero.
+Sprite3() shows how the CSprite unions are used.
+
+SpriteElemSize() will return the size of a single
+element, while SpriteSize() will return the size
+of an entire list.  Look at sprite_elem_base_sizes.
+
+See ::/Apps/GrModels for an example of
+making CSprite by hand.  It uses SPT_MESH,
+one of the most complicated.
+*/
+
+public U0 Sprite3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,
+        Bool just_one_elem=FALSE)
+{//Plot a sprite into a CDC.
+  CSprite *tmpg=elems-offset(CSprite.start);
+  I64 i,j,k,x1,y1,z1,x2,y2,
+        *old_r,*r2,old_flags=dc->flags,old_pen_width=dc->thick;
+  I32 *ptr;
+  CColorROPU32 old_color=dc->color;
+  CDC *img;
+  CD3I32 *p,*p2;
+  CGrSym old_sym;
+  MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));
+  if (dc->flags & DCF_LOCATE_NEAREST)
+    dc->nearest_dist=I64_MAX;
+  while (tmpg->type&SPG_TYPE_MASK) {
+    switch (tmpg->type&SPG_TYPE_MASK) {
+      case SPT_COLOR:
+        dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tmpg->c.color;
+        break;
+      case SPT_DITHER_COLOR:
+        dc->color=dc->color&~COLORROP_COLORS_MASK|
+              tmpg->d.dither_color.u8[0]|
+              tmpg->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER;
+        break;
+      case SPT_THICK:
+        dc->thick=tmpg->t.thick;
+        DCThickScale(dc);
+        break;
+      case SPT_TRANSFORM_ON:
+        if (!(dc->flags&DCF_TRANSFORMATION)) {
+          x-=dc->x;
+          y-=dc->y;
+          z-=dc->z;
+        }
+        dc->flags|=DCF_TRANSFORMATION;
+        break;
+      case SPT_TRANSFORM_OFF:
+        if (dc->flags&DCF_TRANSFORMATION) {
+          x+=dc->x;
+          y+=dc->y;
+          z+=dc->z;
+        }
+        dc->flags&=~DCF_TRANSFORMATION;
+        break;
+      case SPT_PT:
+        GrPlot3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z);
+        break;
+      case SPT_TEXT:
+        GrPrint3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,"%s",tmpg->ps.st);
+        break;
+      case SPT_TEXT_BOX:
+        GrTextBox3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
+        break;
+      case SPT_TEXT_DIAMOND:
+        GrTextDiamond3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
+        break;
+      case SPT_FLOOD_FILL:
+        GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,FALSE);
+        break;
+      case SPT_FLOOD_FILL_NOT:
+        i=dc->color;
+        dc->color=dc->color.c0;
+        GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,TRUE);
+        dc->color=i;
+        break;
+      case SPT_SHIFT:
+        x+=tmpg->p.x1;
+        y+=tmpg->p.y1;
+        break;
+      case SPT_LINE:
+        GrLine3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z);
+        break;
+      case SPT_ARROW:
+        GrArrow3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z);
+        break;
+      case SPT_PLANAR_SYMMETRY:
+        if (DCSymmetry3Set(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z+1))
+          dc->flags|=DCF_SYMMETRY;
+        else
+          dc->flags&=~DCF_SYMMETRY;
+        break;
+      case SPT_BITMAP:
+        img=CAlloc(sizeof(CDC));
+        img->width=tmpg->pwhu.width;
+        img->width_internal=(tmpg->pwhu.width+7)&~7;
+        img->height=tmpg->pwhu.height;
+        img->body=&tmpg->pwhu.u;
+        img->dc_signature=DCS_SIGNATURE_VAL;
+        GrBlot3(dc,tmpg->pwhu.x1+x,tmpg->pwhu.y1+y,z,img);
+        Free(img);
+        break;
+      case SPT_RECT:
+        GrRect3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
+        break;
+      case SPT_ROTATED_RECT:
+        x1=tmpg->ppa.x1+x;
+        y1=tmpg->ppa.y1+y;
+        z1=z;
+        Mat4x4MulXYZ(dc->r,&x1,&y1,&z1);
+        old_r=dc->r;
+        dc->flags|=DCF_TRANSFORMATION;
+        r2=Mat4x4IdentNew;
+        Mat4x4RotZ(r2,-tmpg->ppa.angle);
+        Mat4x4TranslationEqu(r2,x1,y1,z1);
+        DCMat4x4Set(dc,Mat4x4MulMat4x4New(old_r,r2));
+        GrRect3(dc,0,0,0,
+              tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1);
+        Free(dc->r);
+        Free(r2);
+        DCMat4x4Set(dc,old_r);
+        dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
+        break;
+      case SPT_CIRCLE:
+        GrCircle3(dc,tmpg->pr.x1+x,tmpg->pr.y1+y,z,tmpg->pr.radius);
+        break;
+      case SPT_ELLIPSE:
+        GrEllipse3(dc,tmpg->pwha.x1+x,tmpg->pwha.y1+y,z,tmpg->pwha.width,
+              tmpg->pwha.height,tmpg->pwha.angle);
+        break;
+      case SPT_POLYGON:
+        GrRegPoly3(dc,tmpg->pwhas.x1+x,tmpg->pwhas.y1+y,z,tmpg->pwhas.width,
+              tmpg->pwhas.height,tmpg->pwhas.sides,tmpg->pwhas.angle);
+        break;
+      case SPT_POLYLINE:
+        ptr=&tmpg->nu.u;
+        x1=ptr[0];
+        y1=ptr[1];
+        for (i=1;i<tmpg->nu.num;i++) {
+          x2=ptr[i<<1];
+          y2=ptr[i<<1+1];
+          GrLine3(dc,x1+x,y1+y,z,x2+x,y2+y,z);
+          x1=x2;y1=y2;
+        }
+        break;
+      case SPT_POLYPT:
+        x1=tmpg->npu.x;
+        y1=tmpg->npu.y;
+        ptr=&tmpg->npu.u;
+        k=tmpg->npu.num*3;
+        GrPlot3(dc,x1+x,y1+y,z);
+        for (i=0;i<k;i+=3) {
+          j=BFieldExtU32(ptr,i,3);
+          x1+=gr_x_offsets[j];
+          y1+=gr_y_offsets[j];
+          GrPlot3(dc,x1+x,y1+y,z);
+        }
+        break;
+      start:
+        p2=p=MAlloc(tmpg->nu.num*sizeof(CD3I32));
+        MemCpy(p,&tmpg->nu.u,tmpg->nu.num*sizeof(CD3I32));
+        for (i=0;i<tmpg->nu.num;i++,p2++) {
+          p2->x+=x;
+          p2->y+=y;
+          p2->z+=z;
+        }
+        case SPT_BSPLINE2:
+          Gr2BSpline3(dc,p,tmpg->nu.num,FALSE);
+          break;
+        case SPT_BSPLINE3:
+          Gr3BSpline3(dc,p,tmpg->nu.num,FALSE);
+          break;
+        case SPT_BSPLINE2_CLOSED:
+          Gr2BSpline3(dc,p,tmpg->nu.num,TRUE);
+          break;
+        case SPT_BSPLINE3_CLOSED:
+          Gr3BSpline3(dc,p,tmpg->nu.num,TRUE);
+          break;
+      end:
+        Free(p);
+        break;
+      case SPT_MESH:
+        p2=p=MAlloc(tmpg->mu.vertex_cnt*sizeof(CD3I32));
+        MemCpy(p,&tmpg->mu.u,tmpg->mu.vertex_cnt*sizeof(CD3I32));
+        for (i=0;i<tmpg->mu.vertex_cnt;i++,p2++) {
+          p2->x+=x;
+          p2->y+=y;
+          p2->z+=z;
+        }
+        Gr3Mesh(dc,tmpg->mu.vertex_cnt,p,tmpg->mu.tri_cnt,
+              (&tmpg->mu.u)(U8 *)+sizeof(CD3I32)*tmpg->mu.vertex_cnt);
+        Free(p);
+        break;
+      case SPT_SHIFTABLE_MESH:
+        if (dc->flags&DCF_TRANSFORMATION) {
+          dc->x+=tmpg->pmu.x;
+          dc->y+=tmpg->pmu.y;
+          dc->z+=tmpg->pmu.z;
+          x1=x;
+          y1=y;
+          z1=z;
+        } else {
+          x1=tmpg->pmu.x+x;
+          y1=tmpg->pmu.y+y;
+          z1=tmpg->pmu.z+z;
+        }
+        p2=p=MAlloc(tmpg->pmu.vertex_cnt*sizeof(CD3I32));
+        MemCpy(p,&tmpg->pmu.u,tmpg->pmu.vertex_cnt*sizeof(CD3I32));
+        for (i=0;i<tmpg->pmu.vertex_cnt;i++,p2++) {
+          p2->x+=x1;
+          p2->y+=y1;
+          p2->z+=z1;
+        }
+        Gr3Mesh(dc,tmpg->pmu.vertex_cnt,p,tmpg->pmu.tri_cnt,
+              (&tmpg->pmu.u)(U8 *)+sizeof(CD3I32)*tmpg->pmu.vertex_cnt);
+        Free(p);
+        if (dc->flags&DCF_TRANSFORMATION) {
+          dc->x-=tmpg->pmu.x;
+          dc->y-=tmpg->pmu.y;
+          dc->z-=tmpg->pmu.z;
+        }
+        break;
+    }
+    if (just_one_elem) break;
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+  MemCpy(&dc->sym,&old_sym,sizeof(CGrSym));
+  dc->color=old_color;
+  dc->thick=old_pen_width;
+  dc->flags=dc->flags&~(DCF_SYMMETRY|DCF_TRANSFORMATION) |
+        old_flags&(DCF_SYMMETRY|DCF_TRANSFORMATION);
+}
+
+public U0 Sprite3B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems)
+{//Plot a sprite into a CDC, post transform xyz translation.
+  I64 old_x=dc->x,old_y=dc->y,old_z=dc->z,
+        old_flags=dc->flags&DCF_TRANSFORMATION;
+  dc->x=x; dc->y=y; dc->z=z;
+  dc->flags|=DCF_TRANSFORMATION;
+  Sprite3(dc,0,0,0,elems);
+  dc->x=old_x; dc->y=old_y; dc->z=old_z;
+  dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
+}
+
+public U0 Sprite3Mat4x4B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)
+{//Plot rotated by matrix.
+  I64 r[16],*old_r=dc->r,new_m[16],
+        old_flags=dc->flags&DCF_TRANSFORMATION;
+  MemCpy(new_m,m,16*sizeof(I64));
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4TranslationAdd(new_m,x,y,z);
+  dc->r=Mat4x4MulMat4x4Equ(r,old_r,new_m);
+  Sprite3(dc,0,0,0,elems);
+  dc->r=old_r;
+  dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
+}
+
+public U0 Sprite3XB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 phi=0)
+{//Plot rotated around X axis.
+  I64 r[16];
+  Mat4x4IdentEqu(r);
+  Mat4x4RotX(r,phi);
+  Sprite3Mat4x4B(dc,x,y,z,elems,r);
+}
+
+public U0 Sprite3YB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 omega=0)
+{//Plot rotated around Y axis.
+  I64 r[16];
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,omega);
+  Sprite3Mat4x4B(dc,x,y,z,elems,r);
+}
+
+public U0 Sprite3ZB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 theta=0)
+{//Plot rotated around Z axis.
+  I64 r[16];
+  Mat4x4IdentEqu(r);
+  Mat4x4RotZ(r,theta);
+  Sprite3Mat4x4B(dc,x,y,z,elems,r);
+}
+
+public U0 SpriteExtents(U8 *elems,I64 *min_x=NULL,I64 *max_x=NULL,
+                                   I64 *min_y=NULL,I64 *max_y=NULL)
+{//Ignores flood fills.
+  CDC *dc=DCNew(I32_MAX,I32_MAX,Fs,TRUE);
+  DCExtentsInit(dc);
+  Sprite3(dc,I32_MAX/2,I32_MAX/2,I32_MAX/2,elems);
+  if (dc->min_x<=dc->max_x) {
+    dc->min_x-=I32_MAX/2;
+    dc->max_x-=I32_MAX/2;
+  }
+  if (dc->min_y<=dc->max_y) {
+    dc->min_y-=I32_MAX/2;
+    dc->max_y-=I32_MAX/2;
+  }
+  if (min_x) *min_x=dc->min_x;
+  if (max_x) *max_x=dc->max_x;
+  if (min_y) *min_y=dc->min_y;
+  if (max_y) *max_y=dc->max_y;
+  DCDel(dc);
+}
+
+public CDC *Sprite2DC(U8 *elems)
+{//Convert sprite to device context.
+  CDC *res;
+  I64 min_x,max_x,min_y,max_y;
+  SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);
+  res=DCNew(max_x-min_x+1,max_y-min_y+1);
+  Sprite3(res,-min_x,-min_y,0,elems);
+  return res;
+}
+
+public U8 *SpriteInterpolate(F64 t,U8 *elems0,U8 *elems1)
+{//The two CSprite should be ident except for points shifted around.
+//t ranges from 0.0 to 1.0.
+  I64 i,t1=GR_SCALE*t,t0=GR_SCALE-t1;
+  I32 *ptr0,*ptr1,*ptrr;
+  CD3I32 *p0,*p1,*pr;
+  U8 *res;
+  CSprite *tmpg0=elems0-offset(CSprite.start),
+        *tmpg1=elems1-offset(CSprite.start),*tmpgr;
+  if (t<0.5) {
+    i=SpriteSize(elems0),
+          res=MAlloc(i);
+    MemCpy(res,elems0,i);
+  } else {
+    i=SpriteSize(elems1),
+          res=MAlloc(i);
+    MemCpy(res,elems1,i);
+  }
+  tmpgr=res-offset(CSprite.start);
+  while (tmpg0->type&SPG_TYPE_MASK) {
+    if (tmpg0->type&SPG_TYPE_MASK!=tmpg1->type&SPG_TYPE_MASK)
+      throw('Graphics');
+    switch (tmpg0->type&SPG_TYPE_MASK) {
+      case SPT_ROTATED_RECT:
+        tmpgr->ppa.angle=(tmpg0->ppa.angle*t0+tmpg1->ppa.angle*t1)/GR_SCALE;
+      case SPT_RECT:
+      case SPT_LINE:
+      case SPT_ARROW:
+      case SPT_PLANAR_SYMMETRY:
+        tmpgr->pp.x2=(tmpg0->pp.x2*t0+tmpg1->pp.x2*t1)>>32;
+        tmpgr->pp.y2=(tmpg0->pp.y2*t0+tmpg1->pp.y2*t1)>>32;
+      case SPT_TEXT:
+      case SPT_TEXT_BOX:
+      case SPT_TEXT_DIAMOND:
+      case SPT_PT:
+      case SPT_FLOOD_FILL:
+      case SPT_FLOOD_FILL_NOT:
+      case SPT_SHIFT:
+        tmpgr->p.x1=(tmpg0->p.x1*t0+tmpg1->p.x1*t1)>>32;
+        tmpgr->p.y1=(tmpg0->p.y1*t0+tmpg1->p.y1*t1)>>32;
+        break;
+      case SPT_CIRCLE:
+        tmpgr->pr.radius=(tmpg0->pr.radius*t0+tmpg1->pr.radius*t1)>>32;
+        tmpgr->pr.x1=(tmpg0->pr.x1*t0+tmpg1->pr.x1*t1)>>32;
+        tmpgr->pr.y1=(tmpg0->pr.y1*t0+tmpg1->pr.y1*t1)>>32;
+        break;
+      case SPT_ELLIPSE:
+      case SPT_POLYGON:
+        tmpgr->pwha.x1=(tmpg0->pwha.x1*t0+tmpg1->pwha.x1*t1)>>32;
+        tmpgr->pwha.y1=(tmpg0->pwha.y1*t0+tmpg1->pwha.y1*t1)>>32;
+        tmpgr->pwha.width =(tmpg0->pwha.width *t0+tmpg1->pwha.width*t1)>>32;
+        tmpgr->pwha.height=(tmpg0->pwha.height*t0+tmpg1->pwha.height*t1)>>32;
+        break;
+      case SPT_BITMAP:
+        tmpgr->pwhu.x1=(tmpg0->pwhu.x1*t0+tmpg1->pwhu.x1*t1)>>32;
+        tmpgr->pwhu.y1=(tmpg0->pwhu.y1*t0+tmpg1->pwhu.y1*t1)>>32;
+        break;
+      case SPT_POLYLINE:
+        ptr0=&tmpg0->nu.u;
+        ptr1=&tmpg1->nu.u;
+        ptrr=&tmpgr->nu.u;
+        for (i=0;i<tmpg0->nu.num;i++) {
+          ptrr[i<<1]=(ptr0[i<<1]*t0+ptr1[i<<1]*t1)>>32;
+          ptrr[i<<1+1]=(ptr0[i<<1+1]*t0+ptr1[i<<1+1]*t1)>>32;
+        }
+        break;
+      case SPT_POLYPT:
+        tmpgr->npu.x=(tmpg0->npu.x*t0+tmpg1->npu.x*t1)>>32;
+        tmpgr->npu.y=(tmpg0->npu.y*t0+tmpg1->npu.y*t1)>>32;
+        break;
+      case SPT_BSPLINE2:
+      case SPT_BSPLINE3:
+      case SPT_BSPLINE2_CLOSED:
+      case SPT_BSPLINE3_CLOSED:
+        p0=&tmpg0->nu.u;
+        p1=&tmpg1->nu.u;
+        pr=&tmpgr->nu.u;
+        for (i=0;i<tmpg0->nu.num;i++) {
+          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
+          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
+          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
+        }
+        break;
+      case SPT_MESH:
+        p0=&tmpg0->mu.u;
+        p1=&tmpg1->mu.u;
+        pr=&tmpgr->mu.u;
+        for (i=0;i<tmpg0->mu.vertex_cnt;i++) {
+          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
+          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
+          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
+        }
+        break;
+      case SPT_SHIFTABLE_MESH:
+        p0=&tmpg0->pmu.u;
+        p1=&tmpg1->pmu.u;
+        pr=&tmpgr->pmu.u;
+        for (i=0;i<tmpg0->pmu.vertex_cnt;i++) {
+          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
+          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
+          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
+        }
+        break;
+    }
+    tmpg0(U8 *)+=SpriteElemSize(tmpg0);
+    tmpg1(U8 *)+=SpriteElemSize(tmpg1);
+    tmpgr(U8 *)+=SpriteElemSize(tmpgr);
+  }
+  return res;
+}
+
+#help_index "Graphics/Sprite;DolDoc/Output;StdOut/DolDoc"
+public CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL)
+{//Put a sprite into a document.  You can, optionally, supply a fmt string
+//for DolDoc cmd with a %d for the bin_num.
+  I64 size;
+  U8 *st;
+  Bool unlock;
+  CDocEntry *doc_e;
+  CDocBin *tmpb;
+  if (!doc && !(doc=DocPut)) return NULL;
+  unlock=DocLock(doc);
+  size=SpriteSize(elems);
+  tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
+  tmpb->size=size;
+  tmpb->data=MAlloc(size,doc->mem_task);
+  MemCpy(tmpb->data,elems,size);
+  tmpb->num=doc->cur_bin_num;
+  tmpb->use_cnt=1;
+  QueIns(tmpb,doc->bin_head.last);
+  if (fmt)
+    st=MStrPrint(fmt,doc->cur_bin_num++);
+  else
+    st=MStrPrint("$SP,\"\",BI=%d$",doc->cur_bin_num++);
+  doc_e=DocPrint(doc,"%s",st);
+  Free(st);
+  doc_e->bin_data=tmpb;
+  if (doc_e && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+    tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
+  if (unlock)
+    DocUnlock(doc);
+  return doc_e;
+}
+
+public CDocEntry *Sprite(U8 *elems,U8 *fmt=NULL)
+{//Put sprite to the command-line, DocPut.
+//If you set fmt, then include dollars ("$SP ...$") and leave %d for num.
+  CDoc *doc;
+  if (doc=DocPut)
+    return DocSprite(doc,elems,fmt);
+  return NULL;
+}
+
+ diff --git a/public/Wb/Adam/Gr/GrTextBase.HC.HTML b/public/Wb/Adam/Gr/GrTextBase.HC.HTML new file mode 100755 index 0000000..862ffad --- /dev/null +++ b/public/Wb/Adam/Gr/GrTextBase.HC.HTML @@ -0,0 +1,394 @@ + + + + + + + + + + + +
+#help_index "TextBase Layer;Char/TextBase Layer"
+#help_file "::/Doc/TextBase"
+
+asm {
+//************************************
+_TEXT_CHAR::
+//Bool TextChar(CTask *task,Bool allow_border=FALSE,I64 x,I64 y,I64 d);
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RCX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 CTask.scroll_x[RCX]
+        SAR     RBX,3
+        ADD     RBX,U64 SF_ARG3[RBP]
+        MOV     RAX,U64 CTask.scroll_y[RCX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG4[RBP]
+
+        TEST    U8 SF_ARG2[RBP],0xFF
+        JNZ     @@10
+
+//Border not allowed
+        TEST    RBX,RBX         //Check X
+        JS      @@05
+        ADD     RBX,U64 CTask.win_left[RCX]
+        CMP     RBX,U64 CTask.win_right[RCX]
+        JG      @@05
+        TEST    RBX,RBX
+        JS      @@05
+        CMP     RBX,TEXT_COLS
+        JGE     @@05
+        TEST    RAX,RAX         //Check Y
+        JS      @@05
+        ADD     RAX,U64 CTask.win_top[RCX]
+        CMP     RAX,U64 CTask.win_bottom[RCX]
+        JG      @@05
+        TEST    RAX,RAX
+        JS      @@05
+        CMP     RAX,TEXT_ROWS
+        JGE     @@05
+        JMP     @@15
+
+@@05:   XOR     RAX,RAX         //return FALSE
+        POP     RBP
+        RET1    40
+
+//Border allowed
+@@10:   MOV     RDX,-1          //Check X
+        CMP     RBX,RDX
+        JL      @@05
+        ADD     RBX,U64 CTask.win_left[RCX]
+        MOV     RDX,U64 CTask.win_right[RCX]
+        INC     RDX
+        CMP     RBX,RDX
+        JG      @@05
+        TEST    RBX,RBX
+        JS      @@05
+        CMP     RBX,TEXT_COLS
+        JGE     @@05
+        MOV     RDX,-1          //Check Y
+        CMP     RAX,RDX
+        JL      @@05
+        ADD     RAX,U64 CTask.win_top[RCX]
+        MOV     RDX,U64 CTask.win_bottom[RCX]
+        INC     RDX
+        CMP     RAX,RDX
+        JG      @@05
+        TEST    RAX,RAX
+        JS      @@05
+        CMP     RAX,TEXT_ROWS
+        JGE     @@05
+
+@@15:   IMUL2   RAX,TEXT_COLS
+        ADD     RBX,RAX
+        SHL     RBX,2
+        ADD     RBX,U64 [&gr.text_base]
+        MOV     RAX,U64 SF_ARG5[RBP]
+        MOV     U32 [RBX],EAX
+
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    40
+//************************************
+_TEXT_LEN_STR::
+//Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,I64 attr,U8 *s)
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG6[RBP]
+        MOV     RDI,U64 CTask.scroll_x[RBX]
+        SAR     RDI,3
+        ADD     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        TEST    RDI,RDI
+        JNS     @@05
+        ADD     RCX,RDI
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@05:   ADD     RDI,U64 CTask.win_left[RBX]
+        MOV     RDX,RCX
+        ADD     RDX,RDI
+        DEC     RDX
+        CMP     RDX,U64 CTask.win_right[RBX]
+        JLE     @@10
+        MOV     RAX,RDX
+        SUB     RAX,U64 CTask.win_right[RBX]
+        SUB     RDX,RAX
+        SUB     RCX,RAX
+@@10:   TEST    RDI,RDI
+        JNS     @@15
+        ADD     RCX,RDI
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@15:   INC     RDX
+        SUB     RDX,TEXT_COLS
+        JLE     @@20
+        SUB     RCX,RDX
+@@20:   CMP     RCX,1
+        JL      @@30
+
+        MOV     RAX,U64 CTask.scroll_y[RBX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG3[RBP]
+        TEST    RAX,RAX
+        JS      @@30
+        ADD     RAX,U64 CTask.win_top[RBX]
+        CMP     RAX,U64 CTask.win_bottom[RBX]
+        JG      @@30
+        TEST    RAX,RAX
+        JS      @@30
+        CMP     RAX,TEXT_ROWS
+        JGE     @@30
+
+        IMUL2   RAX,TEXT_COLS
+        ADD     RDI,RAX
+        SHL     RDI,2
+        ADD     RDI,U64 [&gr.text_base]
+        MOV     RAX,U64 SF_ARG5[RBP]
+@@25:   LODSB
+        STOSD
+        DEC     RCX
+        JNZ     @@25
+
+        POP     RDI
+        POP     RSI
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    48
+
+@@30:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    48
+//************************************
+_TEXT_LEN_ATTR_STR::
+//Bool TextLenAttrStr(CTask *task,I64 x,I64 y,I64 len,U32 *_attr)
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG5[RBP]
+        MOV     RDI,U64 CTask.scroll_x[RBX]
+        SAR     RDI,3
+        ADD     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        TEST    RDI,RDI
+        JNS     @@05
+        ADD     RCX,RDI
+        SHL     RDI,2
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@05:   ADD     RDI,U64 CTask.win_left[RBX]
+        MOV     RDX,RCX
+        ADD     RDX,RDI
+        DEC     RDX
+        CMP     RDX,U64 CTask.win_right[RBX]
+        JLE     @@10
+        MOV     RAX,RDX
+        SUB     RAX,U64 CTask.win_right[RBX]
+        SUB     RDX,RAX
+        SUB     RCX,RAX
+@@10:   TEST    RDI,RDI
+        JNS     @@15
+        ADD     RCX,RDI
+        SHL     RDI,2
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@15:   INC     RDX
+        SUB     RDX,TEXT_COLS
+        JLE     @@20
+        SUB     RCX,RDX
+@@20:   CMP     RCX,1
+        JL      @@30
+
+        MOV     RAX,U64 CTask.scroll_y[RBX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG3[RBP]
+        TEST    RAX,RAX
+        JS      @@30
+        ADD     RAX,U64 CTask.win_top[RBX]
+        CMP     RAX,U64 CTask.win_bottom[RBX]
+        JG      @@30
+        TEST    RAX,RAX
+        JS      @@30
+        CMP     RAX,TEXT_ROWS
+        JGE     @@30
+
+        IMUL2   RAX,TEXT_COLS
+        ADD     RDI,RAX
+        SHL     RDI,2
+        ADD     RDI,U64 [&gr.text_base]
+@@25:   MOVSD
+        DEC     RCX
+        JNZ     @@25
+
+        POP     RDI
+        POP     RSI
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    40
+
+@@30:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    40
+//************************************
+_TEXT_LEN_ATTR:://Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,I64 attr)
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 CTask.scroll_x[RBX]
+        SAR     RDI,3
+        ADD     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        TEST    RDI,RDI
+        JNS     @@05
+        ADD     RCX,RDI
+        XOR     RDI,RDI
+@@05:   ADD     RDI,U64 CTask.win_left[RBX]
+        MOV     RDX,RCX
+        ADD     RDX,RDI
+        DEC     RDX
+        CMP     RDX,U64 CTask.win_right[RBX]
+        JLE     @@10
+        MOV     RAX,RDX
+        SUB     RAX,U64 CTask.win_right[RBX]
+        SUB     RDX,RAX
+        SUB     RCX,RAX
+@@10:   TEST    RDI,RDI
+        JNS     @@15
+        ADD     RCX,RDI
+        XOR     RDI,RDI
+@@15:   INC     RDX
+        SUB     RDX,TEXT_COLS
+        JLE     @@20
+        SUB     RCX,RDX
+@@20:   CMP     RCX,1
+        JL      @@35
+
+        MOV     RAX,U64 CTask.scroll_y[RBX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG3[RBP]
+        TEST    RAX,RAX
+        JS      @@35
+        ADD     RAX,U64 CTask.win_top[RBX]
+        CMP     RAX,U64 CTask.win_bottom[RBX]
+        JG      @@35
+        TEST    RAX,RAX
+        JS      @@35
+        CMP     RAX,TEXT_ROWS
+        JGE     @@35
+
+        IMUL2   RAX,TEXT_COLS
+        ADD     RDI,RAX
+        SHL     RDI,2
+        ADD     RDI,U64 [&gr.text_base]
+        MOV     RBX,U64 SF_ARG5[RBP]
+        MOV     RSI,RDI
+@@25:   LODSD
+        TEST    AL,AL
+        JNZ     @@30
+        MOV     RAX,RBX
+        STOSD
+        DEC     RCX
+        JNZ     @@25
+
+@@30:   POP     RDI
+        POP     RSI
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    40
+
+@@35:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    40
+}
+public _extern _TEXT_CHAR Bool TextChar(CTask *task,Bool allow_border=FALSE,
+I64 x,I64 y,I64 d); //Plot char. 30fps in Fs->draw_it() callback.
+public _extern _TEXT_LEN_STR Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,
+I64 attr,U8 *s); //Plot str with len.  30fps in Fs->draw_it() callback.
+public _extern _TEXT_LEN_ATTR_STR Bool TextLenAttrStr(CTask *task,I64 x,I64 y,
+I64 len,U32 *_attr); //Plot attr str with len.  30fps in Fs->draw_it() callback.
+public _extern _TEXT_LEN_ATTR Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,
+I64 attr); //Plot attrs with len.  30fps in Fs->draw_it() callback.
+
+public U0 TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...)
+{//Plot chars. 30fps in Fs->draw_it() callback.
+//You probably want GrPrint() or just Print().
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  TextLenStr(task,x,y,StrLen(buf),attr<<8,buf);
+  Free(buf);
+}
+
+public U0 TextBorder(CTask *task=NULL,
+        I64 l,I64 r,I64 t,I64 b,I64 attr,Bool solid)
+{//Plot border square. 30fps in Fs->draw_it() callback.
+//Draws window borders or DolDoc text bttn borders.
+  //Set task=sys_winmgr_task for no clipping.
+  I64 i;
+  if (!task) task=Fs;
+  attr<<=8;
+  TextChar(task,,l-1,t-1,text.border_chars[6+solid]+attr);
+  TextChar(task,,r+1,t-1,text.border_chars[8+solid]+attr);
+  TextChar(task,,l-1,b+1,text.border_chars[10+solid]+attr);
+  TextChar(task,,r+1,b+1,text.border_chars[12+solid]+attr);
+  for (i=l;i<=r;i++) {
+    TextChar(task,,i,t-1,text.border_chars[2+solid]+attr);
+    TextChar(task,,i,b+1,text.border_chars[2+solid]+attr);
+  }
+  for (i=t;i<=b;i++) {
+    TextChar(task,,l-1,i,text.border_chars[4+solid]+attr);
+    TextChar(task,,r+1,i,text.border_chars[4+solid]+attr);
+  }
+}
+
+public U0 TextRect(I64 l,I64 r,I64 t,I64 b,I64 d)
+{//Fill text rect. 30fps in Fs->draw_it() callback.
+  I64 y,w;
+  if (l>r || t>b) return;
+  if (t<0) t=0;
+  if (b>=TEXT_ROWS) b=TEXT_ROWS-1;
+  if (l<0) l=0;
+  if (r>=TEXT_COLS) r=TEXT_COLS-1;
+  if (w=r-l+1)
+    for (y=t;y<=b;y++)
+      MemSetU32(gr.text_base(U8 *)+(y*TEXT_COLS+l)*sizeof(U32),d,w);
+}
+
+
+ diff --git a/public/Wb/Adam/Gr/MakeGr.HC.HTML b/public/Wb/Adam/Gr/MakeGr.HC.HTML new file mode 100755 index 0000000..7914c17 --- /dev/null +++ b/public/Wb/Adam/Gr/MakeGr.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#include "GrInitA"
+#include "Gr.HH"
+#include "GrExt"
+#include "GrGlbls"
+#include "GrTextBase"
+#include "GrAsm"
+#include "GrPalette"
+#include "GrDC"
+#include "GrInitB"
+#include "GrMath"
+#include "GrScrn"
+#include "GrBitMap"
+#include "GrPrimatives"
+#include "GrComposites"
+#include "ScrnCast"
+
+#define SPE_ABORT       (-1)
+#define SPE_EXIT        0
+#define SPE_CONT        1
+#include "SpriteNew"
+#include "GrSpritePlot"
+#include "SpriteMesh"
+#include "SpriteBitMap"
+#include "SpriteCode"
+#include "SpriteSideBar"
+#include "SpriteEd"
+#include "SpriteMain"
+
+#include "GrEnd"
+
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/Gr/ScrnCast.HC.HTML b/public/Wb/Adam/Gr/ScrnCast.HC.HTML new file mode 100755 index 0000000..83affc4 --- /dev/null +++ b/public/Wb/Adam/Gr/ScrnCast.HC.HTML @@ -0,0 +1,127 @@ + + + + + + + + + + + +
+#help_index "ScrnCast;Graphics/Device Contexts;Graphics/GR Files"
+
+#define MV_FILE_MAX     0x007FF000
+
+public I64 GR2MV(U8 *print_fmt="VID%03d.MV",
+        U8 *files_find_mask,U8 *fu_flags=NULL)
+{/*Merge GR lst to MV file.
+"+d" will delete GR list files.
+*/
+  I64 fuf_flags=0,file_num=0,size;
+  CDirEntry *tmpde,*tmpde1;
+  U8 *base,*dst,*src,*st;
+  CDC *dc,*dc_base=DCNew(GR_WIDTH,GR_HEIGHT);
+  CDate cdt;
+  Bool old_silent;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND);
+  if (progress1_max=LinkedLstCnt(tmpde1)) {
+    dst=base=MAlloc(MV_FILE_MAX);
+    while (tmpde) {
+      dc=GRRead(tmpde->full_name);
+      GrBlot(dc_base,dc->x0,dc->y0,dc);
+      if (dst+GR_FILE_MAX>base+MV_FILE_MAX) {
+        st=MStrPrint(print_fmt,file_num++);
+        FileWrite(st,base,dst-base);
+        Free(st);
+        dst=base;
+
+        cdt=dc->cdt;
+        dc=DCCopy(dc_base);
+        dc->cdt=cdt;
+      }
+      src=DCSave(dc,&size);
+      DCDel(dc);
+      MemCpy(dst,src,size);
+      dst+=size;
+      Free(src);
+      if (fuf_flags&FUF_DEL) {
+        old_silent=Silent;
+        Del(tmpde->full_name);
+        Silent(old_silent);
+      }
+      progress1++;
+      tmpde=tmpde->next;
+    }
+    if (dst>base) {
+      st=MStrPrint(print_fmt,file_num++);
+      FileWrite(st,base,dst-base);
+      Free(st);
+    }
+    Free(base);
+  }
+  progress1=progress1_max=0;
+  DirTreeDel(tmpde1);
+  DCDel(dc_base);
+  return file_num;
+}
+
+#help_index "ScrnCast;Snd/AU Files"
+public U0 SndShift(CSndData *head,F64 dt=0)
+{//Shift CSndData in time.
+  CSndData *tmpsd,*tmpsd1;
+  if (dt) {
+    tmpsd=head->next;
+    while (tmpsd!=head) {
+      tmpsd1=tmpsd->next;
+      tmpsd->tS-=dt;
+      if (tmpsd->tS<tmpsd->last->tS) {
+        QueRem(tmpsd);
+        Free(tmpsd);
+      }
+      tmpsd=tmpsd1;
+    }
+  }
+}
+
+public I64 AUWrite(U8 *filename,CSndData *head,CDate *t0_now,F64 t0_tS)
+{//Write AU file.
+  CSndData *tmpsd;
+  CAUData *base,*dst;
+  I64 size=(1+QueCnt(head))*sizeof(CAUData);
+  U8 *st=ExtDft(filename,"AU");
+  base=dst=MAlloc(size);
+  tmpsd=head;
+  do {
+    dst->cdt=t0_now(I64)+ToI64(CDATE_FREQ*(tmpsd->tS-t0_tS));
+    dst->ona=tmpsd->ona;
+    dst++;
+    tmpsd=tmpsd->next;
+  } while (tmpsd!=head);
+  FileWrite(st,base,dst(U8 *)-base(U8 *));
+  Free(base);
+  Free(st);
+  return size;
+}
+
+ diff --git a/public/Wb/Adam/Gr/SpriteBitMap.HC.HTML b/public/Wb/Adam/Gr/SpriteBitMap.HC.HTML new file mode 100755 index 0000000..46cb9ac --- /dev/null +++ b/public/Wb/Adam/Gr/SpriteBitMap.HC.HTML @@ -0,0 +1,701 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+#define SPBM_EXIT               0
+#define SPBM_MAIN_MENU          1
+#define SPBM_COLOR              2
+#define SPBM_DITHER_COLOR       3
+#define SPBM_WIDTH              4
+#define SPBM_PT                 5
+#define SPBM_LINE               6
+#define SPBM_ARROW              7
+#define SPBM_RECT               8
+#define SPBM_CIRCLE             9
+#define SPBM_TEXT               10
+#define SPBM_TEXT_BOX           11
+#define SPBM_TEXT_DIAMOND       12
+#define SPBM_FLOOD_FILL         13
+#define SPBM_FLOOD_FILL_NOT     14
+#define SPBM_POLYLINE           15
+#define SPBM_POLYPT             16
+#define SPBM_COPY               17
+#define SPBM_DELETE             18
+#define SPBM_PASTE              19
+#define SPBM_PASTE_TRANSPARENT  20
+#define SPBM_FIND_AND_REPLACE   21
+#define SPBM_TRIM_TO_EXTENTS    22
+#define SPBM_ADD_OUTLINE        23
+#define SPBM_ETCH               24
+#define SPBM_UNDO               25
+#define SPBM_SAVE_GR            26
+
+U0 GrInit4()
+{
+  DefineLstLoad("ST_SPRITE_BITMAP_MENU",
+        "Exit\0Main Menu\0Color\0Dither Color\0Width\0Point\0Line\0Arrow\0"
+        "Rect\0Circle\0Text\0Text Box\0Text Diamond\0Flood Fill\0"
+        "Flood Fill Not Color\0PolyLine\0PolyPoint\0Copy\0Delete\0Paste\0"
+        "Paste Transparent\0Find and Replace\0Trim to Extents\0Add Outline\0"
+        "Etch\0Undo\0Save GR\0");
+}
+GrInit4;
+
+I64 PopUpSpriteBitMap(CColorROPU32 color,I64 width)
+{
+  I64 res;
+  U8 *st1,*st2,buf[STR_LEN];
+  CDoc *doc=DocNew;
+
+  Color2Str(buf,color);
+  if (color&ROPF_DITHER) {
+    st1="";
+    st2=buf;
+  } else {
+    st1=buf;
+    st2="";
+  }
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite BitMap Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteBitMap.DD.Z\"$\n"
+        "\n$LTBLUE$$MU-UL,\"Color        %s\",LE=SPBM_COLOR$\n"
+        "$MU-UL,\"Dither Color %s\",LE=SPBM_DITHER_COLOR$\n"
+        "$MU-UL,\"Width        %d\",LE=SPBM_WIDTH$\n"
+        "$MU-UL,\"Find & Replace Color\",LE=SPBM_FIND_AND_REPLACE$\n"
+        "$MU-UL,\"Trim to Extents\",LE=SPBM_TRIM_TO_EXTENTS$\n"
+        "$MU-UL,\"Add Outline\",LE=SPBM_ADD_OUTLINE$\n"
+        "$MU-UL,\"Etch\",LE=SPBM_ETCH$\n"
+        "\n$MU-UL,\"Point\",LE=SPBM_PT$\n"
+        "$MU-UL,\"Line\",LE=SPBM_LINE$\n"
+        "$MU-UL,\"Arrow\",LE=SPBM_ARROW$\n"
+        "$MU-UL,\"Rect\",LE=SPBM_RECT$\n"
+        "$MU-UL,\"Circle\",LE=SPBM_CIRCLE$\n"
+        "$MU-UL,\"Text\",LE=SPBM_TEXT$\n"
+        "$MU-UL,\"Text Box\",LE=SPBM_TEXT_BOX$\n"
+        "$MU-UL,\"Text Diamond\",LE=SPBM_TEXT_DIAMOND$\n"
+        "$MU-UL,\"Flood Fill\",LE=SPBM_FLOOD_FILL$\n"
+        "$MU-UL,\"Flood Fill Not Color\",LE=SPBM_FLOOD_FILL_NOT$\n"
+        "$MU-UL,\"PolyLine\",LE=SPBM_POLYLINE$\n"
+        "$MU-UL,\"PolyPoint\",LE=SPBM_POLYPT$\n"
+        "\n$MU-UL,\"Copy to Clip\",LE=SPBM_COPY$\n"
+        "$MU-UL,\"Delete to Clip\",LE=SPBM_DELETE$\n"
+        "$MU-UL,\"Paste Clip\",LE=SPBM_PASTE$\n"
+        "$MU-UL,\"Paste Transparent Clip\",LE=SPBM_PASTE_TRANSPARENT$\n"
+        "\n$MU-UL,\"Save GR File\",LE=SPBM_SAVE_GR$\n"
+        "\n$MU-UL,\"Undo\",LE=SPBM_UNDO$\n"
+        "\n$PURPLE$$MU-UL,\"+] Sprite Main Menu\",LE=SPBM_MAIN_MENU$$LTBLUE$\n"
+        "$MU-UL,\"Exit  Sprite\",LE=SPBM_EXIT$\n"
+        "$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$\n"
+        "\nRight-Click to get back to this menu.",st1,st2,width);
+  res=PopUpMenu(doc);
+  DocDel(doc);
+  return res;
+}
+
+U0 GrBitMapEdPrepPersistentDC(CDC *dc,I64 xx1,I64 yy1,CDC *img)
+{
+  DCFill(dc);
+  GrBlot(dc,xx1,yy1,img);
+}
+
+U0 GrBitMapEdTrimToExtents(CDC **_img,I64 *_xx1,I64 *_yy1,
+        I64 *_xx2,I64 *_yy2,CColorROPU32 bkcolor)
+{
+  CDC *img=*_img;
+  I64 i,c,
+        x1=0,y1=0,x2=img->width-1,y2=img->height-1; //inclusive
+  while (y1<y2) {
+    for (i=x1;i<=x2;i++) {
+      c=GrPeek(img,i,y1);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_y2;
+    }
+    y1++;
+  }
+
+  tr_y2:
+  while (y1<y2) {
+    for (i=x1;i<=x2;i++) {
+      c=GrPeek(img,i,y2);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_x1;
+    }
+    y2--;
+  }
+
+  tr_x1:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++) {
+      c=GrPeek(img,x1,i);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_x2;
+    }
+    x1++;
+  }
+
+  tr_x2:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++) {
+      c=GrPeek(img,x2,i);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_done;
+    }
+    x2--;
+  }
+
+  tr_done:
+  *_img=DCExt(img,x1,y1,x2,y2);
+  *_xx1+=x1;                *_yy1+=y1;
+  *_xx2+=x2-(img->width-1); *_yy2+=y2-(img->height-1); //not inclusive
+  DCDel(img);
+}
+
+U0 GrBitMapEdAddOutline(CDC *img,I64 width,
+        CColorROPU32 color,CColorROPU32 bkcolor)
+{
+  I64 i,j,k,c;
+  CColorROPU32 old_color;
+  CDC *src;
+  if (img->width && img->height) {
+    old_color=img->color;
+    img->color=color;
+    while (width-->0) {
+      src=DCExt(img,0,0,img->width-1,img->height-1);
+      for (i=0;i<img->height;i++)
+        for (j=0;j<img->width;j++)
+          if (GrPeek(src,j,i)==bkcolor)
+            for (k=0;k<8;k++) {
+              c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
+              if (c>=0 && c!=bkcolor) {
+                GrPlot(img,j,i);
+                break;
+              }
+            }
+      DCDel(src);
+    }
+    img->color=old_color;
+  }
+}
+
+U0 GrBitMapEdEtch(CDC *img,I64 width,CColorROPU32 bkcolor)
+{
+  I64 i,j,k,c;
+  CColorROPU32 old_color;
+  CDC *src;
+  if (img->width && img->height) {
+    old_color=img->color;
+    img->color=bkcolor;
+    while (width-->0) {
+      src=DCExt(img,0,0,img->width-1,img->height-1);
+      for (i=0;i<img->height;i++)
+        for (j=0;j<img->width;j++)
+          if (GrPeek(src,j,i)!=bkcolor)
+            for (k=0;k<8;k++) {
+              c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
+              if (c<0 || c==bkcolor) {
+                GrPlot(img,j,i);
+                break;
+              }
+            }
+      DCDel(src);
+    }
+    img->color=old_color;
+  }
+}
+
+I64 SpriteBitMapEd(CDoc *,CDocEntry *doc_e,CDC *dc,I64 *_xx1,I64 *_yy1,
+        I64 *_xx2,I64 *_yy2,CDC **_img,CColorROPU32 bkcolor)
+{
+  I64 i,j,mode=SPBM_LINE,color=BLACK,width=1,msg_code,arg1,arg2,x1,y1,x11,y11,
+        x22,y22,res,xx1=*_xx1,yy1=*_yy1,xx2=*_xx2,yy2=*_yy2,
+        old_de_flags=doc_e->de_flags;
+  Bool down=FALSE;
+  U8 *st=NULL;
+  CEdFileName filename;
+  CDC *img=*_img,
+        *clip=NULL,*undo=NULL,*dc2;
+  SettingsPush; //See SettingsPush
+
+  doc_e->de_flags|=DOCEF_DONT_DRAW;
+  goto bm_menu;
+
+  while (TRUE) {
+    if (kbd.scan_code&SCF_CTRL)//grab scroll update?
+      GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+
+    dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+    dc->thick=1;
+    GrBorder(dc,xx1-1,yy1-1,xx2,yy2);//This is done little bit too often.
+
+    while (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_DOWN|1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN)) {
+      switch (msg_code) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case CH_SHIFT_ESC:
+              res=SPE_ABORT;
+              goto bm_key_up_done;
+            case CH_ESC:
+              res=SPE_CONT;
+              goto bm_key_up_done;
+            case 'c': //eye-dropper
+              dc2=DCScrnCapture(FALSE);
+              color=GrPeek(dc2,ms.pos.x,ms.pos.y)^15;//Mouse cursor is XORed.
+              DCDel(dc2);
+              break;
+            case 't': //Set to transparent color
+              color=TRANSPARENT;
+              break;
+          }
+          break;
+
+        case MSG_MS_R_DOWN:
+bm_menu:
+          DCFill(dc);
+          StrCpy(Fs->task_title,"Sprite BitMap Menu");
+          i=PopUpSpriteBitMap(color,width);
+          if (i>=0)
+            StrCpy(Fs->task_title,DefineSub(i,"ST_SPRITE_BITMAP_MENU"));
+          switch (i) {
+            case DOCM_CANCEL:
+              res=SPE_ABORT;
+              goto bm_done;
+            case SPBM_EXIT:
+              res=SPE_EXIT;
+              goto bm_done;
+            case SPBM_MAIN_MENU:
+              res=SPE_CONT;
+              goto bm_done;
+            case SPBM_COLOR:
+              i=PopUpColor(,,FALSE);
+              if (i>=0) color=i;
+              goto bm_menu;
+            case SPBM_FIND_AND_REPLACE:
+              i=PopUpColor("Find Color\n",,FALSE);
+              if (i>=0) {
+                j=PopUpColor("Replace Color\n",,FALSE);
+                if (j>=0) {
+                  DCColorChg(img,i,j);
+                  GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                }
+              }
+              goto bm_menu;
+            case SPBM_TRIM_TO_EXTENTS:
+              GrBitMapEdTrimToExtents(&img,&xx1,&yy1,&xx2,&yy2,bkcolor);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              goto bm_menu;
+            case SPBM_ADD_OUTLINE:
+              i=PopUpRangeI64(1,16,1,"Outline Width\n");
+              if (i>=0) {
+                GrBitMapEdAddOutline(img,i,color,bkcolor);
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              }
+              goto bm_menu;
+            case SPBM_ETCH:
+              i=PopUpRangeI64(1,16,1,"Etch Width\n");
+              if (i>=0) {
+                GrBitMapEdEtch(img,i,bkcolor);
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              }
+              goto bm_menu;
+            case SPBM_SAVE_GR:
+              *filename.name=0;
+              if (DocForm(&filename) && *filename.name)
+                GRWrite(filename.name,img,DCSF_COMPRESSED|DCSF_PALETTE_GET);
+              goto bm_menu;
+            case SPBM_DITHER_COLOR:
+              i=PopUpColorDither;
+              if (i>=0) color=i;
+              goto bm_menu;
+            case SPBM_WIDTH:
+              i=PopUpRangeI64(1,16,1,"Thick\n");
+              if (i>=0) width=i;
+              goto bm_menu;
+            case SPBM_UNDO:
+              if (undo) {
+                DCFill(img,bkcolor);
+                img->color=ROP_EQU;
+                GrBlot(img,0,0,undo);
+                DCDel(undo);
+                undo=NULL;
+              }
+              goto bm_menu;
+            case SPBM_PT:
+            case SPBM_LINE:
+            case SPBM_ARROW:
+            case SPBM_RECT:
+            case SPBM_CIRCLE:
+            case SPBM_FLOOD_FILL:
+            case SPBM_FLOOD_FILL_NOT:
+            case SPBM_POLYPT:
+            case SPBM_POLYLINE:
+            case SPBM_COPY:
+            case SPBM_DELETE:
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              mode=i;
+              break;
+            case SPBM_TEXT:
+            case SPBM_TEXT_BOX:
+            case SPBM_TEXT_DIAMOND:
+              Free(st);
+              st=PopUpGetStr("Enter text and press <ESC>.\n");
+              if (st && *st)
+                mode=i;
+              else
+                goto bm_menu;
+              break;
+          }
+          DCDel(undo);
+          undo=DCExt(img,0,0,img->width-1,img->height-1);
+          undo->bkcolor=bkcolor;
+          Refresh(2,TRUE);      //Let popup close
+          GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+          down=FALSE;
+          break;
+        case MSG_MS_L_DOWN:
+          switch (mode) {
+            case SPBM_PT:
+              img->color=color;
+              img->thick=width;
+              GrPlot3(img,arg1-xx1,arg2-yy1,0);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            start:
+              if (down)
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              x1=arg1; y1=arg2;
+              down=TRUE;
+              dc->color=color;
+              dc->thick=width;
+              case SPBM_LINE:
+                GrLine3(dc,x1,y1,0,arg1,arg2,0);
+                break;
+              case SPBM_ARROW:
+                GrArrow3(dc,x1,y1,0,arg1,arg2,0);
+                break;
+              case SPBM_RECT:
+                GrRect(dc,x1,y1,1,1);
+                break;
+              case SPBM_CIRCLE:
+                GrCircle3(dc,x1,y1,0,1);
+                break;
+              case SPBM_COPY:
+              case SPBM_DELETE:
+                dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+                dc->thick=1;
+                GrBorder(dc,x1,y1,x1,y1);
+                break;
+            end:
+              break;
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              if (clip) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (mode==SPBM_PASTE) {
+                  clip->flags|=DCF_NO_TRANSPARENTS;
+                  GrBlot(dc,arg1,arg2,clip);
+                  clip->flags&=~DCF_NO_TRANSPARENTS;
+                } else {
+                  dc2=DCCopy(clip);
+                  DCColorChg(dc2,bkcolor);
+                  GrBlot(dc,arg1,arg2,dc2);
+                  DCDel(dc2);
+                }
+              }
+              break;
+            case SPBM_TEXT:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrPrint(dc,arg1,arg2,"%s",st);
+              break;
+            case SPBM_TEXT_BOX:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextBox3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_TEXT_DIAMOND:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextDiamond3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_FLOOD_FILL:
+              img->color=color;
+              GrFloodFill(img,arg1-xx1,arg2-yy1);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_FLOOD_FILL_NOT:
+              img->color=color;
+              GrFloodFill(img,arg1-xx1,arg2-yy1,TRUE);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_POLYLINE:
+              if (!down) {
+                x1=arg1; y1=arg2;
+                down=TRUE;
+                dc->color=color;
+                dc->thick=width;
+                GrLine3(dc,x1,y1,0,arg1,arg2,0);
+              }
+              break;
+            case SPBM_POLYPT:
+              x1=arg1; y1=arg2;
+              down=TRUE;
+              img->color=color;
+              img->thick=width;
+              GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+          }
+          break;
+        case MSG_MS_MOVE:
+          switch (mode) {
+            case SPBM_LINE:
+            case SPBM_ARROW:
+            case SPBM_POLYLINE:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                dc->color=color;
+                dc->thick=width;
+                if (mode==SPBM_ARROW)
+                  GrArrow3(dc,x1,y1,0,arg1,arg2,0);
+                else
+                  GrLine3(dc,x1,y1,0,arg1,arg2,0);
+              }
+              break;
+            case SPBM_RECT:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (x1<arg1) {
+                  x11=x1;
+                  x22=arg1;
+                } else {
+                  x11=arg1;
+                  x22=x1;
+                }
+                if (y1<arg2) {
+                  y11=y1;
+                  y22=arg2;
+                } else {
+                  y11=arg2;
+                  y22=y1;
+                }
+                dc->color=color;
+                GrRect(dc,x11,y11,x22-x11+1,y22-y11+1);
+              }
+              break;
+            case SPBM_COPY:
+            case SPBM_DELETE:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (x1<arg1) {
+                  x11=x1;
+                  x22=arg1;
+                } else {
+                  x11=arg1;
+                  x22=x1;
+                }
+                if (y1<arg2) {
+                  y11=y1;
+                  y22=arg2;
+                } else {
+                  y11=arg2;
+                  y22=y1;
+                }
+                dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+                dc->thick=1;
+                GrBorder(dc,x11,y11,x22,y22);
+              }
+              break;
+            case SPBM_CIRCLE:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                dc->color=color;
+                dc->thick=width;
+                GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
+              }
+              break;
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              if (clip) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (mode==SPBM_PASTE) {
+                  clip->flags|=DCF_NO_TRANSPARENTS;
+                  GrBlot(dc,arg1,arg2,clip);
+                  clip->flags&=~DCF_NO_TRANSPARENTS;
+                } else {
+                  dc2=DCCopy(clip);
+                  DCColorChg(dc2,bkcolor);
+                  GrBlot(dc,arg1,arg2,dc2);
+                  DCDel(dc2);
+                }
+              }
+              break;
+            case SPBM_TEXT:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrPrint(dc,arg1,arg2,"%s",st);
+              break;
+            case SPBM_TEXT_BOX:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextBox3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_TEXT_DIAMOND:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextDiamond3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_POLYPT:
+              if (down) {
+                img->color=color;
+                img->thick=width;
+                GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                x1=arg1; y1=arg2;
+              }
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (mode) {
+            case SPBM_LINE:
+            case SPBM_ARROW:
+            case SPBM_POLYPT:
+            case SPBM_POLYLINE:
+              img->color=color;
+              img->thick=width;
+              if (mode==SPBM_ARROW)
+                GrArrow3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+              else
+                GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              if (mode==SPBM_POLYLINE) {
+                x1=arg1; y1=arg2;
+              } else
+                down=FALSE;
+              break;
+            case SPBM_RECT:
+              img->color=color;
+              if (x1<arg1) {
+                x11=x1;
+                x22=arg1;
+              } else {
+                x11=arg1;
+                x22=x1;
+              }
+              if (y1<arg2) {
+                y11=y1;
+                y22=arg2;
+              } else {
+                y11=arg2;
+                y22=y1;
+              }
+              GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
+              down=FALSE;
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_COPY:
+            case SPBM_DELETE:
+              if (x1<arg1) {
+                x11=x1;
+                x22=arg1;
+              } else {
+                x11=arg1;
+                x22=x1;
+              }
+              if (y1<arg2) {
+                y11=y1;
+                y22=arg2;
+              } else {
+                y11=arg2;
+                y22=y1;
+              }
+              DCDel(clip);
+              clip=DCExt(img,x11-xx1,y11-yy1,x22-xx1,y22-yy1);
+              clip->bkcolor=bkcolor;
+              if (mode==SPBM_DELETE) {
+                img->color=bkcolor;
+                GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
+              }
+              goto bm_menu;
+            case SPBM_CIRCLE:
+              img->color=color;
+              img->thick=width;
+              GrCircle3(img,x1-xx1,y1-yy1,0,
+                    Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
+              down=FALSE;
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              if (clip) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (mode==SPBM_PASTE) {
+                  clip->flags|=DCF_NO_TRANSPARENTS;
+                  GrBlot(img,arg1-xx1,arg2-yy1,clip);
+                  clip->flags&=~DCF_NO_TRANSPARENTS;
+                } else {
+                  dc2=DCCopy(clip);
+                  DCColorChg(dc2,bkcolor);
+                  GrBlot(img,arg1-xx1,arg2-yy1,dc2);
+                  DCDel(dc2);
+                }
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              }
+              break;
+            case SPBM_TEXT:
+              img->color=color;
+              GrPrint(img,arg1-xx1,arg2-yy1,"%s",st);
+              goto bm_menu;
+            case SPBM_TEXT_BOX:
+              img->color=color;
+              GrTextBox3(img,arg1-xx1,arg2-yy1,0,st);
+              goto bm_menu;
+            case SPBM_TEXT_DIAMOND:
+              img->color=color;
+              GrTextDiamond3(img,arg1-xx1,arg2-yy1,0,st);
+              goto bm_menu;
+          }
+          break;
+      }
+    }
+    Refresh;
+  }
+bm_key_up_done:
+  GetMsg(,,1<<MSG_KEY_UP);
+bm_done:
+  DCDel(clip);
+  DCDel(undo);
+  Free(st);
+  DCFill(dc);
+  SettingsPop;
+  doc_e->de_flags=old_de_flags;
+  *_img=img;
+  *_xx1=xx1,*_yy1=yy1,*_xx2=xx2,*_yy2=yy2;
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Gr/SpriteCode.HC.HTML b/public/Wb/Adam/Gr/SpriteCode.HC.HTML new file mode 100755 index 0000000..e43a4cf --- /dev/null +++ b/public/Wb/Adam/Gr/SpriteCode.HC.HTML @@ -0,0 +1,634 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+U0 SpriteElem2Code(CDoc *doc,CSprite *tmpg)
+{
+  U8 buf1[STR_LEN],buf2[STR_LEN];
+  I32 *ptr;
+  I64 i,j,k,col,width_internal;
+  CD3I32 *p;
+  CMeshTri *tri;
+  if (!doc) doc=DocPut;
+  DocPrint(doc,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_CODES");
+  switch (tmpg->type&SPG_TYPE_MASK) {
+    case SPT_COLOR:
+      DocPrint(doc,"{%s}",
+            Color2Str(buf1,tmpg->c.color));
+      break;
+    case SPT_DITHER_COLOR:
+      DocPrint(doc,"{%s}",
+            Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
+            tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
+      break;
+    case SPT_TRANSFORM_ON:
+      DocPrint(doc,"{ON}");
+      break;
+    case SPT_TRANSFORM_OFF:
+      DocPrint(doc,"{OFF}");
+      break;
+    case SPT_LINE:
+    case SPT_ARROW:
+    case SPT_PLANAR_SYMMETRY:
+      DocPrint(doc,"{(%d,%d),(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
+            tmpg->pp.x2,tmpg->pp.y2);
+      break;
+    case SPT_RECT:
+      DocPrint(doc,"{(%d,%d):(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
+            tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
+      break;
+    case SPT_ROTATED_RECT:
+      DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->ppa.x1,tmpg->ppa.y1,
+            tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1,
+            180/pi*Wrap(tmpg->ppa.angle));
+      break;
+    case SPT_PT:
+    case SPT_FLOOD_FILL:
+    case SPT_SHIFT:
+      DocPrint(doc,"{(%d,%d)}",tmpg->p.x1,tmpg->p.y1);
+      break;
+    case SPT_FLOOD_FILL_NOT:
+      DocPrint(doc,"{(%d,%d),TRUE}",tmpg->p.x1,tmpg->p.y1);
+      break;
+    case SPT_CIRCLE:
+      DocPrint(doc,"{(%d,%d):%d}",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
+      break;
+    case SPT_THICK:
+      DocPrint(doc,"{%d}",tmpg->t.thick);
+      break;
+    case SPT_ELLIPSE:
+      DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->pwha.x1,tmpg->pwha.y1,
+            tmpg->pwha.width,tmpg->pwha.height,180/pi*Wrap(tmpg->pwha.angle));
+      break;
+    case SPT_POLYGON:
+      DocPrint(doc,"{%d,(%d,%d):(%d,%d),%0.4f}",tmpg->pwhas.sides,
+            tmpg->pwhas.x1,tmpg->pwhas.y1,
+            tmpg->pwhas.width,tmpg->pwhas.height,
+            180/pi*Wrap(tmpg->pwhas.angle));
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      DocPrint(doc,"{(%d,%d),\"%Q\"}",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
+      break;
+    case SPT_POLYLINE:
+      ptr=&tmpg->nu.u;
+      DocPrint(doc,"{");
+      for (i=0;i<tmpg->nu.num;i++,ptr+=2) {
+        DocPrint(doc,"(%d,%d)",ptr[0],ptr[1]);
+        if (i+1<tmpg->nu.num) DocPrint(doc,",");
+        if (i&3==3 && i+1<tmpg->nu.num)
+          DocPrint(doc,"\n");
+      }
+      DocPrint(doc,"}");
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      ptr=&tmpg->nu.u;
+      DocPrint(doc,"{");
+      for (i=0;i<tmpg->nu.num;i++,ptr+=3) {
+        DocPrint(doc,"(%d,%d,%d)",ptr[0],ptr[1],ptr[2]);
+        if (i+1<tmpg->nu.num) DocPrint(doc,",");
+        if (i&3==3 && i+1<tmpg->nu.num)
+          DocPrint(doc,"\n");
+      }
+      if (tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE2||
+            tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE3)
+        DocPrint(doc,",FALSE}");
+      else
+        DocPrint(doc,",TRUE}");
+      break;
+    case SPT_POLYPT:
+      DocPrint(doc,"{(%d,%d),",tmpg->npu.x,tmpg->npu.y);
+      ptr=&tmpg->npu.u;
+      col=16;
+      for (i=0;i<tmpg->npu.num;i++) {
+        DocPrint(doc,"%d",BFieldExtU32(ptr,i*3,3));
+        if (++col>=64 && i+1<tmpg->npu.num) {
+          DocPrint(doc,"\n");
+          col=0;
+        }
+      }
+      DocPrint(doc,"}");
+      break;
+    case SPT_BITMAP:
+      DocPrint(doc,"{(%d,%d):(%d,%d),\n",tmpg->pwhu.x1,tmpg->pwhu.y1,
+            tmpg->pwhu.width,tmpg->pwhu.height);
+      width_internal=(tmpg->pwhu.width+7)&~7;
+      if (width_internal<80)
+        k=width_internal;
+      else
+        k=64;
+      ptr=&tmpg->pwhu.u;
+      col=0;
+      for (j=0;j<tmpg->pwhu.height;j++)
+        for (i=0;i<width_internal;i++,ptr(U8 *)++) {
+          if (i>=tmpg->pwhu.width)
+            DocPrint(doc,"_");
+          else if (*ptr(U8 *)<16)
+            DocPrint(doc,"%X",*ptr(U8 *));
+          else
+            DocPrint(doc,"%c",CH_SHIFT_SPACE);
+          if (++col>=k && (i+1<width_internal||j+1<tmpg->pwhu.height)) {
+            DocPrint(doc,"\n");
+            col=0;
+          }
+        }
+      DocPrint(doc,"}");
+      break;
+    case SPT_MESH:
+      DocPrint(doc,"{FALSE,");
+      p=&tmpg->mu.u;
+      col=0;
+      for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
+        DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
+        if (i+1<tmpg->mu.vertex_cnt) DocPrint(doc,",");
+        if (++col==4) {
+          DocPrint(doc,"\t//%d\n",i);
+          col=0;
+        }
+      }
+      DocPrint(doc,":");
+      tri=p;
+      for (i=0;i<tmpg->mu.tri_cnt;i++,tri++) {
+        DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
+              tri->nums[0],tri->nums[1],tri->nums[2]);
+        if (i+1<tmpg->mu.tri_cnt) DocPrint(doc,",");
+        if (++col>=3 && i+1<tmpg->mu.tri_cnt) {
+          DocPrint(doc,"\n");
+          col=0;
+        }
+      }
+      DocPrint(doc,"}");
+      break;
+    case SPT_SHIFTABLE_MESH:
+      DocPrint(doc,"{TRUE,(%d,%d,%d):",tmpg->pmu.x,tmpg->pmu.y,tmpg->pmu.z);
+      p=&tmpg->pmu.u;
+      col=1;
+      for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) {
+        DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
+        if (i+1<tmpg->pmu.vertex_cnt) DocPrint(doc,",");
+        if (++col==4) {
+          DocPrint(doc,"\t//%d\n",i);
+          col=0;
+        }
+      }
+      DocPrint(doc,":");
+      tri=p;
+      for (i=0;i<tmpg->pmu.tri_cnt;i++,tri++) {
+        DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
+              tri->nums[0],tri->nums[1],tri->nums[2]);
+        if (i+1<tmpg->pmu.tri_cnt) DocPrint(doc,",");
+        if (++col>=3 && i+1<tmpg->pmu.tri_cnt) {
+          DocPrint(doc,"\n");
+          col=0;
+        }
+      }
+      DocPrint(doc,"}");
+      break;
+  }
+    DocPrint(doc,";\n");
+}
+
+public U0 Sprite2Code(CDoc *doc=NULL,U8 *elems)
+{//Sprite to text.
+  CSprite *tmpg=elems-offset(CSprite.start);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    SpriteElem2Code(doc,tmpg);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+}
+
+CSprite *Code2SpriteElem(CCmpCtrl *cc,I64 type)
+{
+  I64 i,num1,num2,size;
+  CSprite *res,g;
+  CColorROPU32 color;
+  U8 *st,*ptr;
+  CQueD3I32 headp,*tmpp,*tmpa1;
+  CQueMeshTri headt,*tmpt,*tmpt1;
+  CQueVectU8 *tmpv;
+  MemSet(&g,0,sizeof(CSprite));
+  switch (type) {
+    start:
+      case SPT_COLOR:
+      case SPT_DITHER_COLOR:
+        st=LexFirstRem(cc,"}");
+        color=Str2ColorU32(st);
+        Free(st);
+        Lex(cc); //Skip color
+        g.c.color=color.c0.color;
+        if (color&ROPF_DITHER) {
+          g.d.dither_color.u8[1]=color.c1.color;
+          g.type=SPT_DITHER_COLOR;
+        } else
+          g.type=SPT_COLOR;
+        break;
+      case SPT_TRANSFORM_ON:
+      case SPT_TRANSFORM_OFF:
+        Lex(cc); //Skip {
+        if (LexExpressionI64(cc))
+          g.type=SPT_TRANSFORM_ON;
+        else
+          g.type=SPT_TRANSFORM_OFF;
+        break;
+      case SPT_LINE:
+      case SPT_ARROW:
+      case SPT_PLANAR_SYMMETRY:
+        Lex(cc); //Skip {
+        g.type=type;
+        LexD2I32(cc,&g.pp.x1);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        LexD2I32(cc,&g.pp.x2);
+        break;
+      case SPT_RECT:
+      case SPT_ROTATED_RECT:
+        Lex(cc); //Skip {
+        LexD2I32(cc,&g.pp.x1);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+        LexD2I32(cc,&g.pp.x2);
+        g.ppa.x2+=g.pp.x1;
+        g.ppa.y2+=g.pp.y1;
+        if (cc->token==',') {
+          Lex(cc); //Skip ,
+          g.ppa.angle=pi/180*LexExpressionF64(cc);
+          g.type=SPT_ROTATED_RECT;
+        } else
+          g.type=SPT_RECT;
+        break;
+      case SPT_PT:
+      case SPT_SHIFT:
+        Lex(cc); //Skip {
+        g.type=type;
+        LexD2I32(cc,&g.p.x1);
+        break;
+      case SPT_FLOOD_FILL:
+      case SPT_FLOOD_FILL_NOT:
+        Lex(cc); //Skip {
+        LexD2I32(cc,&g.p.x1);
+        if (cc->token==',') {
+          Lex(cc); //Skip ,
+          i=LexExpressionI64(cc);
+        } else
+          i=0;
+        if (i)
+          g.type=SPT_FLOOD_FILL_NOT;
+        else
+          g.type=SPT_FLOOD_FILL;
+        break;
+      case SPT_THICK:
+        Lex(cc); //Skip {
+        g.t.thick=LexExpressionI64(cc);
+        g.type=SPT_THICK;
+        break;
+      case SPT_CIRCLE:
+        Lex(cc); //Skip {
+        g.type=SPT_CIRCLE;
+        LexD2I32(cc,&g.pr.x1);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+        g.pr.radius=LexExpressionI64(cc);
+        break;
+      case SPT_POLYGON:
+        Lex(cc); //Skip {
+        g.pwhas.sides=LexExpressionI64(cc);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+      case SPT_ELLIPSE:
+        Lex(cc); //Skip {
+        g.type=type;
+        LexD2I32(cc,&g.pwha.x1);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+        LexD2I32(cc,&g.pwha.width);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        g.pwha.angle=pi/180*LexExpressionF64(cc);
+        break;
+    end:
+      size=SpriteElemSize(&g)+offset(CSprite.start);
+      res=MAlloc(size);
+      MemCpy(res,&g,size);
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      Lex(cc); //Skip {
+      g.type=type;
+      LexD2I32(cc,&g.ps.x1);
+      if (cc->token!=',')
+        LexExcept(cc,"Expecting ',' at ");
+      if (Lex(cc)==TK_STR)  //Skip ,
+        st=LexExtStr(cc);
+      else
+        LexExcept(cc,"Expecting string at ");
+      size=SpriteElemQuedBaseSize(type);
+      i=StrLen(st)+1;
+      res=MAlloc(size+i);
+      MemCpy(res,&g,size);
+      MemCpy(res(U8 *)+size,st,i);
+      Free(st);
+      break;
+    case SPT_POLYLINE:
+      Lex(cc); //Skip {
+      g.type=SPT_POLYLINE;
+      QueInit(&headp);
+      while (cc->token=='(') {
+        tmpp=CAlloc(sizeof(CQueD3I32));
+        LexD2I32(cc,&tmpp->p);
+        QueIns(tmpp,headp.last);
+        g.nu.num++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (g.nu.num<2)
+        LexExcept(cc,"Expecting point at ");
+      size=SpriteElemQuedBaseSize(SPT_POLYLINE);
+      res=MAlloc(size+g.nu.num*sizeof(CD2I32));
+      MemCpy(res,&g,size);
+      ptr=&res->nu.u;
+      tmpp=headp.next;
+      while (tmpp!=&headp) {
+        tmpa1=tmpp->next;
+        MemCpy(ptr,&tmpp->p,sizeof(CD2I32));
+        ptr+=sizeof(CD2I32);
+        Free(tmpp);
+        tmpp=tmpa1;
+      }
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      Lex(cc); //Skip {
+      QueInit(&headp);
+      while (cc->token=='(') {
+        tmpp=CAlloc(sizeof(CQueD3I32));
+        LexD3I32(cc,&tmpp->p);
+        QueIns(tmpp,headp.last);
+        g.nu.num++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (g.nu.num<2)
+        LexExcept(cc,"Expecting point at ");
+      size=SpriteElemQuedBaseSize(type);
+      res=MAlloc(size+g.nu.num*sizeof(CD3I32));
+      if (LexExpressionI64(cc)) {
+        if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
+          g.type=SPT_BSPLINE2_CLOSED;
+        else
+          g.type=SPT_BSPLINE3_CLOSED;
+      } else {
+        if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
+          g.type=SPT_BSPLINE2;
+        else
+          g.type=SPT_BSPLINE3;
+      }
+      MemCpy(res,&g,size);
+      ptr=&res->nu.u;
+      tmpp=headp.next;
+      while (tmpp!=&headp) {
+        tmpa1=tmpp->next;
+        MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
+        ptr+=sizeof(CD3I32);
+        Free(tmpp);
+        tmpp=tmpa1;
+      }
+      break;
+    case SPT_POLYPT:
+      Lex(cc); //Skip {
+      LexD2I32(cc,&g.npu.x);
+      if (cc->token!=',')
+        LexExcept(cc,"Expecting ',' at ");
+      tmpv=QueVectU8New;
+      while (TRUE) {
+        if (!(i=LexGetChar(cc)))
+          LexExcept(cc,"Expecting '}' at ");
+        if (i=='}')
+          break;
+        if ('0'<=i<='7')
+          QueVectU8Put(tmpv,g.npu.num++,i-'0');
+      }
+      Bts(&cc->flags,CCf_USE_LAST_U16);
+      Lex(cc); //Load '}'
+      g.type=SPT_POLYPT;
+      size=SpriteElemQuedBaseSize(SPT_POLYPT);
+      res=CAlloc(size+(g.npu.num*3+7)>>3);
+      MemCpy(res,&g,size);
+      ptr=&res->npu.u;
+      for (i=0;i<g.npu.num;i++)
+        BFieldOrU32(ptr,i*3,QueVectU8Get(tmpv,i));
+      QueVectU8Del(tmpv);
+      break;
+    case SPT_BITMAP:
+      Lex(cc); //Skip {
+      LexD2I32(cc,&g.pwhu.x1);
+      if (cc->token!=':')
+        LexExcept(cc,"Expecting ':' at ");
+      Lex(cc); //Skip :
+      LexD2I32(cc,&g.pwhu.width);
+      if (cc->token!=',')
+        LexExcept(cc,"Expecting ',' at ");
+      tmpv=QueVectU8New;
+      num1=0;
+      while (TRUE) {
+        if (!(i=ToUpper(LexGetChar(cc))))
+          LexExcept(cc,"Expecting '}' at ");
+        if (i=='}')
+          break;
+        if ('0'<=i<='9')
+          QueVectU8Put(tmpv,num1++,i-'0');
+        else if ('A'<=i<='F')
+          QueVectU8Put(tmpv,num1++,i-'A'+10);
+        else if (i==CH_SPACE||i==CH_SHIFT_SPACE)
+          QueVectU8Put(tmpv,num1++,TRANSPARENT);
+        else if (i=='_')
+          QueVectU8Put(tmpv,num1++,0);
+      }
+      Bts(&cc->flags,CCf_USE_LAST_U16);
+      Lex(cc); //Load '}'
+      g.type=SPT_BITMAP;
+      size=SpriteElemQuedBaseSize(SPT_BITMAP);
+      res=CAlloc(size+num1);
+      MemCpy(res,&g,size);
+      ptr=&res->pwhu.u;
+      for (i=0;i<num1;i++)
+        *ptr++=QueVectU8Get(tmpv,i);
+      QueVectU8Del(tmpv);
+      break;
+    case SPT_MESH:
+    case SPT_SHIFTABLE_MESH:
+      Lex(cc); //Skip {
+      if (LexExpressionI64(cc)) {
+        g.type=SPT_SHIFTABLE_MESH;
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        LexD3I32(cc,&g.pmu.x);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+      } else {
+        g.type=SPT_MESH;
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+      }
+      num1=0;
+      QueInit(&headp);
+      while (cc->token=='(') {
+        tmpp=CAlloc(sizeof(CQueD3I32));
+        LexD3I32(cc,&tmpp->p);
+        QueIns(tmpp,headp.last);
+        num1++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (cc->token!=':')
+        LexExcept(cc,"Expecting ':' at ");
+      Lex(cc); //Skip :
+      num2=0;
+      QueInit(&headt);
+      while (cc->token=='(') {
+        tmpt=CAlloc(sizeof(CQueMeshTri));
+        st=LexFirstRem(cc,",");
+        tmpt->color=Str2ColorU32(st);
+        Free(st);
+        Lex(cc); //Skip color
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        tmpt->nums[0]=LexExpressionI64(cc);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        tmpt->nums[1]=LexExpressionI64(cc);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        tmpt->nums[2]=LexExpressionI64(cc);
+        if (cc->token!=')')
+          LexExcept(cc,"Expecting ')' at ");
+        Lex(cc); //Skip )
+        QueIns(tmpt,headt.last);
+        num2++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (g.type==SPT_MESH) {
+        g.mu.vertex_cnt=num1;
+        g.mu.tri_cnt=num2;
+        size=SpriteElemQuedBaseSize(SPT_MESH);
+      } else {
+        g.pmu.vertex_cnt=num1;
+        g.pmu.tri_cnt=num2;
+      }
+      size=SpriteElemQuedBaseSize(g.type);
+      res=MAlloc(size+num1*sizeof(CD3I32)+num2*sizeof(CMeshTri));
+      MemCpy(res,&g,size);
+      ptr=res(U8 *)+size;
+      tmpp=headp.next;
+      while (tmpp!=&headp) {
+        tmpa1=tmpp->next;
+        MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
+        ptr+=sizeof(CD3I32);
+        Free(tmpp);
+        tmpp=tmpa1;
+      }
+      tmpt=headt.next;
+      while (tmpt!=&headt) {
+        tmpt1=tmpt->next;
+        MemCpy(ptr,&tmpt->start,sizeof(CMeshTri));
+        ptr+=sizeof(CMeshTri);
+        Free(tmpt);
+        tmpt=tmpt1;
+      }
+      break;
+  }
+  if (cc->token!='}')
+    LexExcept(cc,"Expecting '}' at ");
+  if (Lex(cc)!=';')
+    LexExcept(cc,"Expecting ';' at ");
+  return res;
+}
+
+public U8 *Code2Sprite(CDoc *doc,I64 *_size=NULL)
+{//Text to sprite.
+  CSprite head;
+  U8 *res;
+  Bool okay=TRUE,unlock_doc=DocLock(doc);
+  CCmpCtrl *cc=CmpCtrlNew(,CCF_DONT_FREE_BUF);
+  CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;
+  CHashGeneric *tmph;
+  I64 i,size=0;
+  QueInit(&head);
+  LexAttachDoc(cc,,doc);
+  try {
+    do {
+      cc->htc.hash_table_lst=NULL;
+      if (Lex(cc)==TK_IDENT && //Skip ;
+            (tmph=HashFind(cc->cur_str,gr.sprite_hash,SPHT_ELEM_CODE))) {
+        i=tmph->user_data0;
+        cc->htc.hash_table_lst=old_hash_table_lst;
+        if (Lex(cc)=='{') //Skip ident
+          QueIns(Code2SpriteElem(cc,i),head.last);
+      } else if (cc->token)
+        LexExcept(cc,"Expecting sprite element type name at ");
+    } while (cc->token);
+    okay=TRUE;
+  } catch {
+    Fs->catch_except=TRUE;
+    okay=FALSE;
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+  if (okay) {
+    CmpCtrlDel(cc); //TODO: can crash
+    res=SpriteQue2Sprite(&head,&size);
+  } else {
+    res=NULL;
+    size=0;
+  }
+  if (_size) *_size=size;
+  QueDel(&head);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Gr/SpriteEd.HC.HTML b/public/Wb/Adam/Gr/SpriteEd.HC.HTML new file mode 100755 index 0000000..8117f52 --- /dev/null +++ b/public/Wb/Adam/Gr/SpriteEd.HC.HTML @@ -0,0 +1,1209 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+CSprite *SpriteSetSettings(CDC *dc=NULL,CSprite *head,I64 elem_num,
+        I64 x=0,I64 y=0,CColorROPU32 *_color=NULL,I64 *_thick=NULL,
+        I64 *_xx=NULL,I64 *_yy=NULL)
+{
+  CSprite *res=head->next;
+  I64 thick=1,xx=0,yy=0;
+  CColorROPU32 color=BLACK;
+  if (dc) DCRst(dc);
+  while (elem_num-->0 && res!=head) {
+    switch (res->type&SPG_TYPE_MASK) {
+      case SPT_COLOR:
+        color=res->c.color;
+        if (dc) dc->color=color;
+        break;
+      case SPT_DITHER_COLOR:
+        color=res->d.dither_color.u8[0]|
+              res->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER;
+        if (dc) dc->color=color;
+        break;
+      case SPT_THICK:
+        thick=res->t.thick;
+        if (dc) dc->thick=thick;
+        break;
+      case SPT_SHIFT:
+        xx+=res->p.x1;
+        yy+=res->p.y1;
+        x+=res->p.x1;
+        y+=res->p.y1;
+        break;
+      case SPT_PLANAR_SYMMETRY:
+        if (dc) {
+          if (DCSymmetry3Set(dc,res->pp.x1+x,res->pp.y1+y,0,
+                res->pp.x2+x,res->pp.y2+y,0,
+                res->pp.x2+x,res->pp.y2+y,1))
+            dc->flags|=DCF_SYMMETRY;
+          else
+            dc->flags&=~DCF_SYMMETRY;
+        }
+        break;
+    }
+    res=res->next;
+  }
+  if (_color) *_color=color;
+  if (_thick) *_thick=thick;
+  if (_xx) *_xx=xx;
+  if (_yy) *_yy=yy;
+  return res;
+}
+
+Bool SpritePolyPtPlot(CSprite *head,I64 x,I64 y,I64)
+{
+  CSprite *tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_PT));
+  tmpg->type=SPT_PT;
+  tmpg->p.x1=x;
+  tmpg->p.y1=y;
+  QueIns(tmpg,head->last);
+  return TRUE;
+}
+
+CSprite *Sprite2SpriteQue(U8 *elems)
+{
+  I64 s;
+  CSprite *res=CAlloc(sizeof(CSprite)),
+        *tmpg=elems-offset(CSprite.start),*tmpg1;
+  QueInit(res);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    tmpg1=MAlloc(SpriteElemSize(tmpg)+offset(CSprite.start));
+    s=SpriteElemSize(tmpg);
+    MemCpy(&tmpg1->start,&tmpg->start,s);
+    QueIns(tmpg1,res->last);
+    tmpg(U8 *)+=s;
+  }
+  return res;
+}
+
+U8 *SpriteQue2Sprite(CSprite *head,I64 *_size=NULL)
+{
+  I64 i,size=sprite_elem_base_sizes[SPT_END];
+  CSprite *tmpg=head->next;
+  U8 *res,*dst;
+  while (tmpg!=head) {
+    size+=SpriteElemSize(tmpg);
+    tmpg=tmpg->next;
+  }
+  if (_size) *_size=size;
+  res=dst=MAlloc(size);
+  tmpg=head->next;
+  while (tmpg!=head) {
+    i=SpriteElemSize(tmpg);
+    MemCpy(dst,&tmpg->start,i);
+    dst+=i;
+    tmpg=tmpg->next;
+  }
+  *dst=SPT_END;
+  return res;
+}
+
+U0 SpriteEdUpdate(CDoc *doc,CDocEntry *doc_ce,CSprite *head)
+{
+  CDocBin *tmpb=doc_ce->bin_data;
+  I64 size;
+  Bool unlock=DocLock(doc);
+  Free(tmpb->data);
+  tmpb->data=SpriteQue2Sprite(head,&size);
+  tmpb->size=size;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 SpriteSetOrigin(CSprite *head,I64 dx,I64 dy,I64 dz)
+{
+  I64 i;
+  I32 *ptr;
+  CD3I32 *p;
+  CSprite *tmpg=head->next;
+  while (tmpg!=head) {
+    if (Bt(&tmpg->type,SPf_SEL))
+      switch (tmpg->type&SPG_TYPE_MASK) {
+        case SPT_ARROW:
+        case SPT_LINE:
+        case SPT_PLANAR_SYMMETRY:
+        case SPT_RECT:
+        case SPT_ROTATED_RECT:
+          tmpg->pp.x2+=dx;
+          tmpg->pp.y2+=dy;
+        case SPT_PT:
+        case SPT_FLOOD_FILL:
+        case SPT_FLOOD_FILL_NOT:
+        case SPT_TEXT:
+        case SPT_TEXT_BOX:
+        case SPT_TEXT_DIAMOND:
+        case SPT_CIRCLE:
+        case SPT_BITMAP:
+        case SPT_ELLIPSE:
+        case SPT_POLYGON:
+          tmpg->p.x1+=dx;
+          tmpg->p.y1+=dy;
+          break;
+        case SPT_POLYLINE:
+          ptr=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++) {
+            ptr[i<<1]+=dx;
+            ptr[i<<1+1]+=dy;
+          }
+          break;
+        case SPT_POLYPT:
+          tmpg->npu.x+=dx;
+          tmpg->npu.y+=dy;
+          break;
+        case SPT_BSPLINE2:
+        case SPT_BSPLINE3:
+        case SPT_BSPLINE2_CLOSED:
+        case SPT_BSPLINE3_CLOSED:
+          p=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++,p++) {
+            p->x+=dx;
+            p->y+=dy;
+            p->z+=dz;
+          }
+          break;
+        case SPT_MESH:
+          p=&tmpg->mu.u;
+          for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
+            p->x+=dx;
+            p->y+=dy;
+            p->z+=dz;
+          }
+          break;
+        case SPT_SHIFTABLE_MESH:
+          tmpg->pmu.x+=dx;
+          tmpg->pmu.y+=dy;
+          tmpg->pmu.z+=dz;
+          break;
+      }
+    tmpg=tmpg->next;
+  }
+}
+
+CSprite *SpriteTransformCircle(I64 *r,CSprite *tmpg)
+{
+  I64 x,y,z;
+  F64 m1,arg1,m2,radius=tmpg->pr.radius<<16;
+  CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(SPT_ELLIPSE));
+  tmpg1->type=SPT_ELLIPSE;
+
+  x=tmpg->pr.x1; y=tmpg->pr.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->pwha.x1=x;
+  tmpg1->pwha.y1=y;
+
+  x=radius; y=0; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m1,&arg1,x,y);
+
+  x=0; y=radius; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  m2=Sqrt(x*x+y*y);
+
+  tmpg1->pwha.width =ToI64(m1)/0x10000;
+  tmpg1->pwha.height=ToI64(m2)/0x10000;
+  tmpg1->pwha.angle=-arg1;
+
+  tmpg1->type|=tmpg->type&SPF_SEL;
+  return tmpg1;
+}
+
+CSprite *SpriteTransformEllipse(I64 *r,CSprite *tmpg)
+{
+  I64 x,y,z;
+  F64 m1,arg1,m2,arg2,s,c,x_radius=tmpg->pwha.width<<16,
+        y_radius=tmpg->pwha.height<<16;
+  CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(tmpg->type&SPG_TYPE_MASK));
+  tmpg1->type=tmpg->type;
+  if (tmpg->type&SPG_TYPE_MASK==SPT_POLYGON)
+    tmpg1->pwhas.sides=tmpg->pwhas.sides;
+
+  x=tmpg->pwha.x1; y=tmpg->pwha.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->pwha.x1=x;
+  tmpg1->pwha.y1=y;
+
+  c=Cos(-tmpg->pwha.angle);
+  s=Sin(-tmpg->pwha.angle);
+
+  x=x_radius*c;
+  y=x_radius*s;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m1,&arg1,x,y);
+
+  x=-y_radius*s;
+  y=y_radius*c;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m2,&arg2,x,y);
+  m2*=Abs(Sin(arg2-arg1));
+
+  tmpg1->pwha.width=ToI64(m1)/0x10000;
+  if (tmpg1->pwha.width<1) tmpg1->pwha.width=1;
+  tmpg1->pwha.height=ToI64(m2)/0x10000;
+  if (tmpg1->pwha.height<1) tmpg1->pwha.height=1;
+  tmpg1->pwha.angle=-arg1;
+
+  tmpg1->type|=tmpg->type&SPF_SEL;
+  return tmpg1;
+}
+
+CSprite *SpriteTransformRect(I64 *r,CSprite *tmpg,F64 theta)
+{
+  I64 x,y,z,w,h;
+  F64 m1,arg1,m2,arg2,s,c,
+        x_radius=(tmpg->pp.x2-tmpg->pp.x1)<<16,
+        y_radius=(tmpg->pp.y2-tmpg->pp.y1)<<16;
+  CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(SPT_ROTATED_RECT));
+  tmpg1->type=SPT_ROTATED_RECT;
+
+  x=tmpg->pp.x1; y=tmpg->pp.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->ppa.x1=x;
+  tmpg1->ppa.y1=y;
+
+  c=Cos(-theta);
+  s=Sin(-theta);
+
+  x=x_radius*c;
+  y=x_radius*s;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m1,&arg1,x,y);
+
+  x=-y_radius*s;
+  y=y_radius*c;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m2,&arg2,x,y);
+  m2*=Abs(Sin(arg2-arg1));
+
+  w=ToI64(m1)/0x10000;
+  if (w<1) w=1;
+  h=ToI64(m2)/0x10000;
+  if (h<1) h=1;
+  tmpg1->ppa.x2=tmpg1->ppa.x1+w;
+  tmpg1->ppa.y2=tmpg1->ppa.y1+h;
+  tmpg1->ppa.angle=-arg1;
+
+  tmpg1->type|=tmpg->type&SPF_SEL;
+  return tmpg1;
+}
+
+CSprite *SpriteTransformBitMap(I64 *r,CSprite *tmpg)
+{
+  CDC *img,*dc3;
+  U8 *elems;
+  I64 x,y,z,minx,maxx,miny,maxy,minz,maxz;
+  CSprite *tmpg1;
+
+  x=tmpg->pwhu.x1; y=tmpg->pwhu.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  minx=maxx=x;
+  miny=maxy=y;
+  minz=maxz=z;
+
+  x=tmpg->pwhu.x1; y=tmpg->pwhu.y1+tmpg->pwhu.height; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  if (x<minx) minx=x;
+  if (x>maxx) maxx=x;
+  if (y<miny) miny=y;
+  if (y>maxy) maxy=y;
+  if (z<minz) minz=z;
+  if (z>maxz) maxz=z;
+
+  x=tmpg->pwhu.x1+tmpg->pwhu.width; y=tmpg->pwhu.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  if (x<minx) minx=x;
+  if (x>maxx) maxx=x;
+  if (y<miny) miny=y;
+  if (y>maxy) maxy=y;
+  if (z<minz) minz=z;
+  if (z>maxz) maxz=z;
+
+  x=tmpg->pwhu.x1+tmpg->pwhu.width; y=tmpg->pwhu.y1+tmpg->pwhu.height; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  if (x<minx) minx=x;
+  if (x>maxx) maxx=x;
+  if (y<miny) miny=y;
+  if (y>maxy) maxy=y;
+  if (z<minz) minz=z;
+  if (z>maxz) maxz=z;
+
+  dc3=DCNew(maxx-minx+1,maxy-miny+1);
+
+  img=CAlloc(sizeof(CDC));
+  img->width=tmpg->pwhu.width;
+  img->width_internal=(tmpg->pwhu.width+7)&~7;
+  img->height=tmpg->pwhu.height;
+  img->body=&tmpg->pwhu.u;
+  img->dc_signature=DCS_SIGNATURE_VAL;
+
+  dc3->color=TRANSPARENT;
+  GrRect(dc3,0,0,maxx-minx+1,maxy-miny+1);
+
+  Free(dc3->r);
+  DCMat4x4Set(dc3,r);
+  dc3->flags|=DCF_TRANSFORMATION;
+
+  dc3->x=tmpg->pwhu.x1-minx;
+  dc3->y=tmpg->pwhu.y1-miny;
+  dc3->z=-minz;
+  GrBlot3(dc3,0,0,0,img);
+  Free(img);
+
+  elems=DC2Sprite(dc3);
+  dc3->r=NULL;
+  DCDel(dc3);
+  tmpg1=CAlloc(offset(CSprite.start)+MSize(elems));
+  MemCpy(tmpg1(U8 *)+offset(CSprite.start),elems,MSize(elems));
+  tmpg1->type=tmpg->type;
+
+  x=tmpg->pwhu.x1; y=tmpg->pwhu.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->pwhu.x1=x;
+  tmpg1->pwhu.y1=y;
+
+  return tmpg1;
+}
+
+U0 SpriteTransformQue(CSprite *head,I64 *r)
+{
+  I64 i,j,k,num,x,y,z,x1,y1,z1,x2,y2,z2,x3,y3,z3;
+  I32 *ptr;
+  CD3I32 *p;
+  CSprite *tmpg=head->next,head2,*tmpg1,*tmpg2,*tmpg3;
+  while (tmpg!=head) {
+    if (Bt(&tmpg->type,SPf_SEL))
+      switch (tmpg->type&SPG_TYPE_MASK) {
+        case SPT_THICK:
+          tmpg->t.thick*=Sqrt(Mat4x4NormSqr65536(r))/65536;
+          if (tmpg->t.thick<0) tmpg->t.thick=0;
+          break;
+        case SPT_PLANAR_SYMMETRY:
+        case SPT_ARROW:
+        case SPT_LINE:
+          x=tmpg->pp.x2; y=tmpg->pp.y2; z=0;
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          tmpg->pp.x2=x;
+          tmpg->pp.y2=y;
+        case SPT_PT:
+        case SPT_FLOOD_FILL:
+        case SPT_FLOOD_FILL_NOT:
+        case SPT_TEXT:
+        case SPT_TEXT_BOX:
+        case SPT_TEXT_DIAMOND:
+          x=tmpg->p.x1; y=tmpg->p.y1; z=0;
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          tmpg->p.x1=x;
+          tmpg->p.y1=y;
+          break;
+        case SPT_BITMAP:
+          tmpg1=SpriteTransformBitMap(r,tmpg);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_ROTATED_RECT:
+          tmpg1=SpriteTransformRect(r,tmpg,tmpg->ppa.angle);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_RECT:
+          tmpg1=SpriteTransformRect(r,tmpg,0);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_CIRCLE:
+          tmpg1=SpriteTransformCircle(r,tmpg);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_ELLIPSE:
+        case SPT_POLYGON:
+          tmpg1=SpriteTransformEllipse(r,tmpg);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_POLYLINE:
+          ptr=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++) {
+            x=ptr[i<<1]; y=ptr[i<<1+1]; z=0;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            ptr[i<<1]=x;
+            ptr[i<<1+1]=y;
+          }
+          break;
+        case SPT_POLYPT:
+          QueInit(&head2);
+          x=tmpg->npu.x; y=tmpg->npu.y; z=0;
+          x1=x; y1=y; z1=z;  //unrotated cur coordinates
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          ptr=&tmpg->npu.u;
+          k=tmpg->npu.num*3;
+          x2=x; y2=y; z2=z;  //rotated start coordinates
+          x3=x; y3=y; z3=z;  //lag 1 rotated coordinates
+          for (i=0;i<k;i+=3) {
+            j=BFieldExtU32(ptr,i,3);
+            x1+=gr_x_offsets[j];
+            y1+=gr_y_offsets[j];
+            x=x1; y=y1; z=z1;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            Line(&head2,x3-x2,y3-y2,0,x-x2,y-y2,0,&SpritePolyPtPlot);
+            x3=x; y3=y; z3=z;
+          }
+
+          num=0;
+          tmpg1=head2.next;
+          x3=0; y3=0; z3=0;
+          while (tmpg1!=&head2) {
+            tmpg2=tmpg1->next;
+            if (tmpg1->p.x1==x3 && tmpg1->p.y1==y3) {
+              QueRem(tmpg1);
+              Free(tmpg1);
+            } else {
+              num++;
+              x3=tmpg1->p.x1;
+              y3=tmpg1->p.y1;
+            }
+            tmpg1=tmpg2;
+          }
+
+          tmpg3=CAlloc(SpriteElemQuedBaseSize(SPT_POLYPT)+(num*3+7)>>3);
+          tmpg3->npu.x=x2;
+          tmpg3->npu.y=y2;
+          ptr=&tmpg3->npu.u;
+          x3=0;y3=0; z3=0;
+          i=0;
+          tmpg1=head2.next;
+          while (tmpg1!=&head2) {
+            tmpg2=tmpg1->next;
+            BFieldOrU32(ptr,i,
+                  polypt_map[SignI64(tmpg1->p.x1-x3)+1+
+                  3*(SignI64(tmpg1->p.y1-y3)+1)]);
+            i+=3;
+            x3=tmpg1->p.x1;y3=tmpg1->p.y1;
+            QueRem(tmpg1);
+            Free(tmpg1);
+            tmpg1=tmpg2;
+          }
+          tmpg3->type=SPT_POLYPT|tmpg->type&SPF_SEL;
+          tmpg3->npu.num=num;
+          QueIns(tmpg3,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg3;
+          break;
+        case SPT_BSPLINE2:
+        case SPT_BSPLINE3:
+        case SPT_BSPLINE2_CLOSED:
+        case SPT_BSPLINE3_CLOSED:
+          p=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++,p++) {
+            x=p->x; y=p->y; z=p->z;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            p->x=x;
+            p->y=y;
+            p->z=z;
+          }
+          break;
+        case SPT_SHIFTABLE_MESH:
+          x=tmpg->pmu.x; y=tmpg->pmu.y; z=tmpg->pmu.z;
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          tmpg->pmu.x=x;
+          tmpg->pmu.y=y;
+          tmpg->pmu.z=z;
+          p=&tmpg->pmu.u;
+          for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) {
+            x=p->x; y=p->y; z=p->z;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            p->x=x;
+            p->y=y;
+            p->z=z;
+          }
+          break;
+        case SPT_MESH:
+          p=&tmpg->mu.u;
+          for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
+            x=p->x; y=p->y; z=p->z;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            p->x=x;
+            p->y=y;
+            p->z=z;
+          }
+          break;
+      }
+    tmpg=tmpg->next;
+  }
+}
+
+I64 SpriteQueSelCnt(CSprite *head,Bool val=TRUE)
+{
+  I64 res=0;
+  CSprite *tmpg=head->next;
+  val=ToBool(val);
+  while (tmpg!=head) {
+    if (Bt(&tmpg->type,SPf_SEL)==val)
+      res++;
+    tmpg=tmpg->next;
+  }
+  return res;
+}
+
+I64 SpriteQueSelAll(CSprite *head,Bool val=TRUE)
+{
+  I64 res=0;
+  CSprite *tmpg=head->next;
+  while (tmpg!=head) {
+    BEqu(&tmpg->type,SPf_SEL,val);
+    res++;
+    tmpg=tmpg->next;
+  }
+  return res;
+}
+
+Bool SpriteEdText(CSprite **_head,I64 *_cur_elem_num)
+{
+  Bool res;
+  CSprite *head=*_head;
+  U8 *elems=SpriteQue2Sprite(head);
+  CDoc *doc=DocNew,*doc2,*old_put=DocPut;
+  StrPrint(doc->filename.name,"AI:0x%X",doc);
+  DocPrint(doc,"//$PURPLE$$TX+CX,\"Sprite Edit as Text\"$$FG$\n"
+        "//$LK+PU+CX,\"Click for Help\","
+        "A=\"FI:::/Doc/SpriteEdText.DD.Z\"$\n\n");
+  Sprite2Code(doc,elems);
+  Free(elems);
+  while (TRUE) {
+    if (res=PopUpPrint("DocEd(0x%X,0x%X);",doc,0)) {
+      Fs->put_doc=doc2=DocNew;
+      "$WW,1$";
+      if (elems=Code2Sprite(doc)) {
+        DocDel(doc2);
+        Fs->put_doc=old_put;
+        QueDel(head);
+        Free(head);
+        head=Sprite2SpriteQue(elems);
+        Free(elems);
+        *_cur_elem_num=QueCnt(head); //TODO: Might want to improve this.
+        break;
+      } else {
+        PopUpPrint("DocEd(0x%X,0x%X);",doc2,0);
+        DocDel(doc2);
+        Fs->put_doc=old_put;
+      }
+    } else
+      break;
+  }
+  DocDel(doc);
+  if (_head) *_head=head;
+  return res;
+}
+
+#define SPED_SEL_UNSEL_ALL      0
+#define SPED_SEL                2
+#define SPED_SEL_RECTS          3
+#define SPED_UNSEL              4
+#define SPED_UNSEL_RECTS        5
+#define SPED_SHIFT_PTS          6
+#define SPED_SHIFT_RECTS        7
+#define SPED_SHIFT_SEL          8
+#define SPED_TRANSFORM_SEL      9
+#define SPED_SET_ORIGIN         10
+#define SPED_SHIFT_SUB_ORIGIN   11
+#define SPED_TEXT_ED            12
+#define SPED_INS_CLIP           13
+#define SPED_MAIN_MENU          14
+#define SPED_EXIT               15
+
+U0 GrInit3()
+{
+  DefineLstLoad("ST_SPRITE_ED_MENU","Select/Unselect All\0 \0Select\0"
+        "Select Rects\0Unselect\0Unselect Rects\0Shift Points\0Shift Rects\0"
+        "Shift Selected\0Transform Selected\0Set Origin\0"
+        "Insert Shift SubOrigin\0Edit as Text\0Insert Clip\0Main Menu\0");
+}
+GrInit3;
+
+I64 PopUpSpriteEd(CSprite **_head,I64 *_cur_elem_num)
+{
+  U8 *st;
+  CTask *pu_task;
+  I64 res;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite Edit Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteEd.DD.Z\"$\n\n"
+        "$LTBLUE$$MU-UL,\"Select/Unselect All\",LE=SPED_SEL_UNSEL_ALL$\n"
+        "$MU-UL,\"Select Elems\",LE=SPED_SEL$\n"
+        "$MU-UL,\"Select Elems with Rects\",LE=SPED_SEL_RECTS$\n"
+        "$MU-UL,\"Unsel Elems\",LE=SPED_UNSEL$\n"
+        "$MU-UL,\"Unsel Elems with Rects\",LE=SPED_UNSEL_RECTS$\n\n"
+        "$MU-UL,\"Shift Points\",LE=SPED_SHIFT_PTS$\n"
+        "$MU-UL,\"Shift Points with Rects\",LE=SPED_SHIFT_RECTS$\n"
+        "$MU-UL,\"Shift Selected Elems\",LE=SPED_SHIFT_SEL$\n"
+        "$MU-UL,\"Transform Selected Elems\",LE=SPED_TRANSFORM_SEL$\n\n"
+        "$MU-UL,\"Set Origin\",LE=SPED_SET_ORIGIN$\n"
+        "$MU-UL,\"Insert Shift SubOrigin\",LE=SPED_SHIFT_SUB_ORIGIN$\n\n"
+        "$MU-UL,\"Edit as Text\",LE=SPED_TEXT_ED$\n"
+        "$MU-UL,\"Insert Clip Sprite's\",LE=SPED_INS_CLIP$\n\n"
+        "$PURPLE$$MU-UL,\"+] Sprite Main Menu\",LE=SPED_MAIN_MENU$$LTBLUE$\n"
+        "$MU-UL,\"Exit  Sprite\",LE=SPED_EXIT$\n"
+        "$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$");
+  st=MStrPrint("SpriteSideBarTask(0x%X,0x%X,0x%X);",Fs,_head,_cur_elem_num);
+  PopUp(st,NULL,&pu_task);
+  Free(st);
+  res=PopUpMenu(doc);
+  if (TaskValidate(pu_task)) {
+    *_head=SpriteSideBar2SpriteQue(DocPut(pu_task),*_head,_cur_elem_num);
+    Kill(pu_task);
+  }
+  DocDel(doc);
+  return res;
+}
+
+#define SPEDT_SIMPLE_PT         0
+#define SPEDT_WIDTH_HEIGHT      1
+
+#define SPEDF_SEL               1
+
+class CEdSprite
+{
+  CEdSprite *next,*last;
+  CSprite *g;
+  I32 type,num,flags,xx,yy,zz;
+  I32 *x,*y,*z,*w,*h;
+};
+
+CEdSprite *EdSpriteNew(I64 type,CSprite *tmpg)
+{
+  CEdSprite *res=CAlloc(sizeof(CEdSprite));
+  res->g=tmpg;
+  if (tmpg->type&SPF_SEL)
+    res->flags|=SPEDF_SEL;
+  res->type=type;
+  return res;
+}
+
+U0 SpritePtQueNew(U8 *elems,I64 x,I64 y,CEdSprite *head)
+{
+  I64 i,num=0;
+  I32 *ptr;
+  CD3I32 *p;
+  CEdSprite *tmpes;
+  CSprite *tmpg=elems-offset(CSprite.start);
+  QueInit(head);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    switch (tmpg->type&SPG_TYPE_MASK) {
+      case SPT_ELLIPSE:
+      case SPT_POLYGON:
+        tmpes=EdSpriteNew(SPEDT_WIDTH_HEIGHT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->pwha.x1;
+        tmpes->y=&tmpg->pwha.y1;
+        tmpes->w=&tmpg->pwha.width;
+        tmpes->h=&tmpg->pwha.height;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        goto pq_x1_y1;
+      case SPT_RECT:
+      case SPT_ROTATED_RECT:
+      case SPT_LINE:
+      case SPT_ARROW:
+      case SPT_PLANAR_SYMMETRY:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->pp.x2;
+        tmpes->y=&tmpg->pp.y2;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+      case SPT_TEXT:
+      case SPT_TEXT_BOX:
+      case SPT_TEXT_DIAMOND:
+      case SPT_PT:
+      case SPT_BITMAP:
+      case SPT_FLOOD_FILL:
+      case SPT_FLOOD_FILL_NOT:
+      case SPT_CIRCLE:
+pq_x1_y1:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->p.x1;
+        tmpes->y=&tmpg->p.y1;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        break;
+      case SPT_SHIFT:
+        x+=tmpg->p.x1;
+        y+=tmpg->p.y1;
+        break;
+      case SPT_POLYLINE:
+        ptr=&tmpg->nu.u;
+        for (i=0;i<tmpg->nu.num;i++) {
+          tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+          tmpes->xx=x;
+          tmpes->yy=y;
+          tmpes->x=&ptr[i<<1];
+          tmpes->y=&ptr[i<<1+1];
+          tmpes->num=num;
+          QueIns(tmpes,head->last);
+        }
+        break;
+      case SPT_POLYPT:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->npu.x;
+        tmpes->y=&tmpg->npu.y;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        break;
+      case SPT_BSPLINE2:
+      case SPT_BSPLINE3:
+      case SPT_BSPLINE2_CLOSED:
+      case SPT_BSPLINE3_CLOSED:
+        p=&tmpg->nu.u;
+        for (i=0;i<tmpg->nu.num;i++) {
+          tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+          tmpes->xx=x;
+          tmpes->yy=y;
+          tmpes->x=&p[i].x;
+          tmpes->y=&p[i].y;
+          tmpes->z=&p[i].z;
+          tmpes->num=num;
+          QueIns(tmpes,head->last);
+        }
+        break;
+      case SPT_MESH:
+        break;
+      case SPT_SHIFTABLE_MESH:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->pmu.x;
+        tmpes->y=&tmpg->pmu.y;
+        tmpes->z=&tmpg->pmu.z;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        break;
+    }
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+    num++;
+  }
+}
+
+U0 SpriteCtrlPtsDraw(CDC *dc,CEdSprite *head)
+{
+  I64 x,y;
+  CEdSprite *tmpes;
+  Refresh;
+  DCFill(dc);
+  if (Blink(20)) {
+    tmpes=head->next;
+    while (tmpes!=head) {
+      switch (tmpes->type) {
+        case SPEDT_SIMPLE_PT:
+          x=*tmpes->x+tmpes->xx;
+          y=*tmpes->y+tmpes->yy;
+          break;
+        case SPEDT_WIDTH_HEIGHT:
+          x=*tmpes->w+*tmpes->x+tmpes->xx;
+          y=*tmpes->h+*tmpes->y+tmpes->yy;
+          break;
+      }
+      if (tmpes->flags&SPEDF_SEL)
+        dc->color=RED;
+      else
+        dc->color=BLACK;
+      GrRect(dc,x-2,y-2,4,4);
+      dc->color=WHITE;
+      GrRect(dc,x-1,y-1,2,2);
+      tmpes=tmpes->next;
+    }
+  }
+}
+
+U0 SpriteCtrlPtsMove(CEdSprite *head,I64 dx,I64 dy)
+{
+  CEdSprite *tmpes;
+  tmpes=head->next;
+  while (tmpes!=head) {
+    if (tmpes->flags&SPEDF_SEL)
+      switch (tmpes->type) {
+        case SPEDT_SIMPLE_PT:
+          if (tmpes->x) *tmpes->x+=dx;
+          if (tmpes->y) *tmpes->y+=dy;
+          break;
+        case SPEDT_WIDTH_HEIGHT:
+          if (tmpes->w) *tmpes->w+=dx;
+          if (tmpes->h) *tmpes->h+=dy;
+          break;
+      }
+    tmpes=tmpes->next;
+  }
+}
+
+Bool SpriteSelUnselShiftPts(U8 *elems,I64 x,I64 y,I64 *_cur_elem_num,I64 mode)
+{
+  I64 msg_code,arg1,arg2,xx,yy,xx2,yy2,dd,best_dd,cur_elem_num;
+  Bool res=TRUE;
+  CDC *dc=DCAlias;
+  CEdSprite head,*tmpes,*best_es;
+
+  SpritePtQueNew(elems,x,y,&head);
+  cur_elem_num=0;
+  if (head.next!=&head) {
+    while (TRUE) {
+      SpriteCtrlPtsDraw(dc,&head); //has Refresh
+      switch (msg_code=ScanMsg(&arg1,&arg2,
+            1<<MSG_MS_R_UP|1<<MSG_MS_L_DOWN|1<<MSG_KEY_DOWN)) {
+        case MSG_MS_L_DOWN:
+          switch (mode) {
+            case SPED_SEL:
+            case SPED_UNSEL:
+            case SPED_SHIFT_PTS:
+              xx=arg1; yy=arg2;
+              best_dd=I64_MAX;
+              tmpes=head.next;
+              while (tmpes!=&head) {
+                switch (tmpes->type) {
+                  case SPEDT_SIMPLE_PT:
+                    dd=SqrI64(*tmpes->x+tmpes->xx-xx)+
+                          SqrI64(*tmpes->y+tmpes->yy-yy);
+                    break;
+                  case SPEDT_WIDTH_HEIGHT:
+                    dd=SqrI64(*tmpes->x+*tmpes->w+tmpes->xx-xx)+
+                          SqrI64(*tmpes->y+*tmpes->h+tmpes->yy-yy);
+                    break;
+                }
+                if (dd<best_dd) {
+                  best_dd=dd;
+                  best_es=tmpes;
+                }
+                tmpes=tmpes->next;
+              }
+              cur_elem_num=best_es->num;
+              if (mode!=SPED_UNSEL) {
+                best_es->flags|=SPEDF_SEL;
+                best_es->g->type|=SPF_SEL;
+              } else {
+                best_es->flags&=~SPEDF_SEL;
+                best_es->g->type&=~SPF_SEL;
+              }
+              break;
+            start:
+              xx2=xx=arg1; yy2=yy=arg2;
+              while (TRUE) {
+                SpriteCtrlPtsDraw(dc,&head);
+                dc->color=ROPF_DITHER+WHITE<<16+RED;
+                GrBorder(dc,xx,yy,xx2,yy2);
+                if (msg_code=ScanMsg(&arg1,&arg2,
+                      1<<MSG_MS_MOVE|1<<MSG_MS_L_UP)) {
+                  if (msg_code==MSG_MS_MOVE) {
+                    xx2=arg1; yy2=arg2;
+                  } else
+                    break;
+                }
+              }
+              if (xx2<xx) SwapI64(&xx,&xx2);
+              if (yy2<yy) SwapI64(&yy,&yy2);
+              tmpes=head.next;
+              while (tmpes!=&head) {
+                switch (tmpes->type) {
+                  case SPEDT_SIMPLE_PT:
+                    if (xx<=*tmpes->x+tmpes->xx<=xx2 &&
+                          yy<=*tmpes->y+tmpes->yy<=yy2) {
+                      if (mode!=SPED_UNSEL_RECTS) {
+                        tmpes->flags|=SPEDF_SEL;
+                        tmpes->g->type|=SPF_SEL;
+                      } else {
+                        tmpes->flags&=~SPEDF_SEL;
+                        tmpes->g->type&=~SPF_SEL;
+                      }
+                    }
+                    break;
+                  case SPEDT_WIDTH_HEIGHT:
+                    if (xx<=*tmpes->x+*tmpes->w+tmpes->xx<=xx2 &&
+                          yy<=*tmpes->y+*tmpes->h+tmpes->yy<=yy2) {
+                      if (mode!=SPED_UNSEL_RECTS) {
+                        tmpes->flags|=SPEDF_SEL;
+                        tmpes->g->type|=SPF_SEL;
+                      } else {
+                        tmpes->flags&=~SPEDF_SEL;
+                        tmpes->g->type&=~SPF_SEL;
+                      }
+                    }
+                    break;
+                }
+                tmpes=tmpes->next;
+              }
+              case SPED_SEL_RECTS:
+              case SPED_UNSEL_RECTS:
+                break;
+              case SPED_SHIFT_RECTS:
+                do {
+                  SpriteCtrlPtsDraw(dc,&head);
+                  msg_code=ScanMsg(&arg1,&arg2,
+                        1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN);
+                  if (msg_code==MSG_KEY_DOWN) goto gs_key;
+                } while (msg_code!=MSG_MS_L_DOWN);
+                xx=arg1;yy=arg2;
+                break;
+            end:
+          }
+          switch (mode) {
+            case SPED_SHIFT_PTS:
+            case SPED_SHIFT_RECTS:
+              do {
+                SpriteCtrlPtsDraw(dc,&head);
+                if (msg_code=ScanMsg(&arg1,&arg2,
+                      1<<MSG_MS_MOVE|1<<MSG_MS_L_UP)) {
+                  SpriteCtrlPtsMove(&head,arg1-xx,arg2-yy);
+                  xx=arg1;yy=arg2;
+                }
+              } while (msg_code!=MSG_MS_L_UP);
+              tmpes=head.next;
+              while (tmpes!=&head) {
+                tmpes->flags&=~SPEDF_SEL;
+                tmpes->g->type&=~SPF_SEL;
+                tmpes=tmpes->next;
+              }
+              break;
+          }
+          break;
+        case MSG_KEY_DOWN:
+gs_key:
+          switch (arg1.u8[0]) {
+            case CH_SHIFT_ESC:
+              res=FALSE;
+            case CH_ESC:
+              GetMsg(&arg1,&arg2,1<<MSG_KEY_UP);
+              goto gs_done;
+            case 'p':
+            case 'P':
+              mode&=~1;
+              break;
+            case 'r':
+            case 'R':
+              mode|=1;
+              break;
+          }
+          break;
+        case MSG_MS_R_UP:
+          goto gs_done;
+      }
+    }
+gs_done:
+    QueDel(&head,TRUE);
+  }
+  DCFill(dc);
+  DCDel(dc);
+  if (_cur_elem_num && res)
+    *_cur_elem_num=cur_elem_num;
+  return res;
+}
+
+I64 SpriteEd(CDoc *doc,CDocEntry *doc_ce,I64 x,I64 y,
+        CSprite **_head,I64 *_cur_elem_num)
+{
+  CDocEntry *doc_e2;
+  CDocBin *tmpb;
+  Bool unlock;
+  I64 i,r[16],msg_code,arg1,arg2,xx,yy,
+        old_de_flags;
+  CSprite *head2,*next,*last,*tmpg,*insert_pt;
+
+  old_de_flags=doc_ce->de_flags;
+  tmpb=doc_ce->bin_data;
+  DocUnlock(doc);
+  SpriteQueSelAll(*_head,FALSE);
+  do {
+    if (winmgr.fps<10)
+      doc_ce->de_flags|=DOCEF_DONT_DRAW;
+    StrCpy(Fs->task_title,"Sprite Edit Menu");
+    i=PopUpSpriteEd(_head,_cur_elem_num);
+    SpriteEdUpdate(doc,doc_ce,*_head);
+    if (0<=i<SPED_EXIT) {
+      StrCpy(Fs->task_title,DefineSub(i,"ST_SPRITE_ED_MENU"));
+      switch (i) {
+        case SPED_SEL_UNSEL_ALL:
+          if (!SpriteQueSelCnt(*_head))
+            SpriteQueSelAll(*_head);
+          else
+            SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SET_ORIGIN:
+          SpriteQueSelAll(*_head);
+          doc_ce->de_flags=old_de_flags;
+          GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP);
+          SpriteSetOrigin(*_head,x-arg1,y-arg2,0);
+          SpriteEdUpdate(doc,doc_ce,*_head);
+          SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SHIFT_SEL:
+          if (!SpriteQueSelCnt(*_head))
+            SpriteQueSelAll(*_head);
+          doc_ce->de_flags=old_de_flags;
+          GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN);
+          xx=arg1; yy=arg2;
+          do {
+            msg_code=GetMsg(&arg1,&arg2,
+                  1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+            SpriteSetOrigin(*_head,arg1-xx,arg2-yy,0);
+            xx=arg1; yy=arg2;
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          } while (msg_code!=MSG_MS_L_UP);
+          if (!SpriteQueSelCnt(*_head,FALSE))
+            SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SEL:
+        case SPED_SEL_RECTS:
+        case SPED_UNSEL:
+        case SPED_UNSEL_RECTS:
+        case SPED_SHIFT_PTS:
+        case SPED_SHIFT_RECTS:
+          RegOneTimePopUp(ARf_CSPRITE_PTS_RECTANGLES,
+                "You can switch between points\n"
+                "and rectangles with '$GREEN$p$FG$' and '$GREEN$r$FG$'.\n"
+                "Press '$GREEN$r$FG$' after one rectangle\n"
+                "to OR another rectangle.\n");
+          doc_ce->de_flags=old_de_flags;
+          if (SpriteSelUnselShiftPts(tmpb->data,x,y,_cur_elem_num,i)) {
+            QueDel(*_head);
+            Free(*_head);
+            *_head=Sprite2SpriteQue(tmpb->data);
+          } else
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          break;
+        case SPED_TRANSFORM_SEL:
+          if (!SpriteQueSelCnt(*_head))
+            SpriteQueSelAll(*_head);
+          if (PopUpTransform(r)) {
+            SpriteTransformQue(*_head,r);
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          }
+          if (!SpriteQueSelCnt(*_head,FALSE))
+            SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SHIFT_SUB_ORIGIN:
+          doc_ce->de_flags=old_de_flags;
+          insert_pt=SpriteSetSettings(,*_head,*_cur_elem_num);
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_SHIFT));
+          tmpg->type=SPT_SHIFT;
+          tmpg->p.x1=0;
+          tmpg->p.y1=0;
+          QueIns(tmpg,insert_pt->last);
+          GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN);
+          xx=arg1; yy=arg2;
+          do {
+            msg_code=GetMsg(&arg1,&arg2,
+                  1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+            tmpg->p.x1=arg1-xx;
+            tmpg->p.y1=arg2-yy;
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          } while (msg_code!=MSG_MS_L_UP);
+          *_cur_elem_num+=1;
+          break;
+        case SPED_INS_CLIP:
+          RegOneTimePopUp(ARf_CSPRITE_INS_CLIP,
+                "You will probably want to shift around\n"
+                "the location of element groups.  Use\n"
+                "'Insert shift sub-origin' after picking the\n"
+                "element to insert before.  Or,\n"
+                "use 'shift points'.\n");
+          insert_pt=SpriteSetSettings(,*_head,*_cur_elem_num);
+          unlock=DocLock(sys_clip_doc);
+          doc_e2=sys_clip_doc->head.next;
+          while (doc_e2!=sys_clip_doc) {
+            if (doc_e2->type_u8==DOCT_SPRITE) {
+              head2=Sprite2SpriteQue(doc_e2->bin_data->data);
+              if (head2->next!=head2) {
+                tmpg=head2->next;
+                while (tmpg!=head2) {
+                  *_cur_elem_num+=1;
+                  tmpg=tmpg->next;
+                }
+                next=head2->next;
+                last=head2->last;
+                insert_pt->last->next=next;
+                next->last=insert_pt->last;
+                insert_pt->last=last;
+                last->next=insert_pt;
+              }
+              Free(head2);
+            }
+            doc_e2=doc_e2->next;
+          }
+          if (unlock)
+            DocUnlock(sys_clip_doc);
+          SpriteEdUpdate(doc,doc_ce,*_head);
+          break;
+        case SPED_TEXT_ED:
+          if (SpriteEdText(_head,_cur_elem_num))
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          break;
+      }
+    }
+  } while (i!=DOCM_CANCEL && i!=SPED_EXIT && i!=SPED_MAIN_MENU);
+  doc_ce->de_flags=old_de_flags;
+
+  switch (i) {
+    case DOCM_CANCEL:   return SPE_ABORT;
+    case SPED_EXIT:     return SPE_EXIT;
+    case SPED_MAIN_MENU:        return SPE_CONT;
+  }
+}
+
+#help_index "Graphics/Sprite;Sprites;Graphics/Math/3D Transformation"
+public U8 *SpriteTransform(U8 *elems,I64 *r)
+{//Rotate Sprite using 4x4 matrix. Uses fixed-point.
+  U8 *res;
+  CSprite *head=Sprite2SpriteQue(elems);
+  SpriteQueSelAll(head);
+  SpriteTransformQue(head,r);
+  res=SpriteQue2Sprite(head);
+  QueDel(head);
+  Free(head);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Gr/SpriteMain.HC.HTML b/public/Wb/Adam/Gr/SpriteMain.HC.HTML new file mode 100755 index 0000000..808abdd --- /dev/null +++ b/public/Wb/Adam/Gr/SpriteMain.HC.HTML @@ -0,0 +1,1269 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+#define SPT_MENU        -2
+#define SPT_INS_SCRN_BITMAP             -3
+#define SPT_INS_TRANSPARENT_SCRN_BITMAP -4
+#define SPT_ED_MENU     -5
+#define SPT_EXIT        -6
+
+I64 PopUpSpriteMain(CSprite **_head,I64 *_cur_elem_num,
+        CDoc *_doc,CDocEntry *_doc_e)
+{
+  CTask *pu_task;
+  I64   res;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_de;
+  U8    *st;
+
+  doc_de=DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite Main Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteMain.DD.Z\"$\n"
+        "\n$LTBLUE$$DA+M,A=\"Tag Text:%%s\"$\n\n");
+  doc_de->data=StrNew(_doc_e->tag,doc->mem_task);
+  DocDataFmt(doc,doc_de);
+
+  DocPrint(doc,"$MU-UL,\"Color (4-bit)\",LE=SPT_COLOR$\n"
+        "$MU-UL,\"Dither Color (4-bit)\",LE=SPT_DITHER_COLOR$\n"
+        "$MU-UL,\"Thick\",LE=SPT_THICK$\n"
+        "$MU-UL,\"Planar Symmetry\",LE=SPT_PLANAR_SYMMETRY$\n"
+        "\n$MU-UL,\"Point\",LE=SPT_PT$\n"
+        "$MU-UL,\"Line\",LE=SPT_LINE$\n"
+        "$MU-UL,\"Arrow\",LE=SPT_ARROW$\n"
+        "$MU-UL,\"Rect\",LE=SPT_RECT$\n"
+        "$MU-UL,\"Circle\",LE=SPT_CIRCLE$\n"
+        "$MU-UL,\"Ellipse\",LE=SPT_ELLIPSE$\n"
+        "$MU-UL,\"Polygon\",LE=SPT_POLYGON$\n"
+        "$MU-UL,\"Text\",LE=SPT_TEXT$\n"
+        "$MU-UL,\"Text Box\",LE=SPT_TEXT_BOX$\n"
+        "$MU-UL,\"Text Diamond\",LE=SPT_TEXT_DIAMOND$\n"
+        "$MU-UL,\"Flood Fill\",LE=SPT_FLOOD_FILL$\n"
+        "$MU-UL,\"Flood Fill Not Color\",LE=SPT_FLOOD_FILL_NOT$\n"
+        "$MU-UL,\"PolyLine\",LE=SPT_POLYLINE$\n"
+        "$MU-UL,\"PolyPoint\",LE=SPT_POLYPT$\n"
+        "$MU-UL,\"BSpline2\",LE=SPT_BSPLINE2$\n"
+        "$MU-UL,\"BSpline3\",LE=SPT_BSPLINE3$\n"
+        "$MU-UL,\"BSpline2 Closed\",LE=SPT_BSPLINE2_CLOSED$\n"
+        "$MU-UL,\"BSpline3 Closed\",LE=SPT_BSPLINE3_CLOSED$\n"
+        "$MU-UL,\"Insert Scrn-Captured BitMap\",LE=SPT_INS_SCRN_BITMAP$\n"
+        "$MU-UL,\"Insert Transparent Scrn-Captured BitMap\","
+        "LE=SPT_INS_TRANSPARENT_SCRN_BITMAP$\n"
+        "$PURPLE$$MU-UL,\"+] Create or Edit 3D Mesh\",LE=SPT_MESH$\n"
+        "$MU-UL,\"+] Create or Edit Shiftable 3D Mesh\","
+        "LE=SPT_SHIFTABLE_MESH$\n"
+        "$MU-UL,\"+] Convert to BitMap or Edit BitMap\","
+        "LE=SPT_BITMAP$$LTBLUE$\n"
+        "\n$MU-UL,\"Transform On  (for use with 3D icons)\","
+        "LE=SPT_TRANSFORM_ON$\n"
+        "$MU-UL,\"Transform Off (for use with 3D icons)\","
+        "LE=SPT_TRANSFORM_OFF$\n"
+        "\n"
+        "$PURPLE$$MU-UL,\"+] Sprite Edit Menu\",LE=SPT_ED_MENU$$LTBLUE$\n"
+        "$MU-UL,\"Exit  Sprite\",LE=SPT_EXIT$\n"
+        "$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$\n"
+        "\nRight-Click to get back to this menu.");
+  st=MStrPrint("SpriteSideBarTask(0x%X,0x%X,0x%X);",Fs,_head,_cur_elem_num);
+  PopUp(st,NULL,&pu_task);
+  Free(st);
+  res=PopUpMenu(doc);
+  if (TaskValidate(pu_task)) {
+    *_head=SpriteSideBar2SpriteQue(DocPut(pu_task),*_head,_cur_elem_num);
+    Kill(pu_task);
+  }
+  Free(_doc_e->tag);
+  _doc_e->tag=StrNew(doc_de->data,_doc->mem_task);
+  _doc->cur_col=0;
+  DocDel(doc);
+  return res;
+}
+
+Bool PopUpExtents(I64 *_x1,I64 *_x2,I64 *_y1,I64 *_y2)
+{
+  I64 res;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e;
+  doc_e=DocPrint(doc,"  $DA,A=\"x1:%%d\"$\n");
+  doc_e->data=_x1;
+  DocDataFmt(doc,doc_e);
+  doc_e=DocPrint(doc,"  $DA,A=\"x2:%%d\"$\n");
+  doc_e->data=_x2;
+  DocDataFmt(doc,doc_e);
+  doc_e=DocPrint(doc,"  $DA,A=\"y1:%%d\"$\n");
+  doc_e->data=_y1;
+  DocDataFmt(doc,doc_e);
+  doc_e=DocPrint(doc,"  $DA,A=\"y2:%%d\"$\n\n");
+  doc_e->data=_y2;
+  DocDataFmt(doc,doc_e);
+
+  DocPrint(doc," $BT,\"Use These Extents\",LE=TRUE$");
+  DocPrint(doc,"$CM,3,0$$BT,\"Drag-Out New Extents\",LE=FALSE$\n\n");
+  do res=PopUpMenu(doc);
+  while (res!=FALSE && res!=TRUE);
+  DocDel(doc);
+  return res;
+}
+
+U0 SpriteScrnInit(CDC *dc,I64,I64)
+{
+//Uses fixed-point.
+  I64 xx,yy,old_pen_width=dc->thick;
+  CColorROPU32 old_color=dc->color;
+  Refresh;
+  DCFill(dc);
+  if (dc->flags&DCF_SYMMETRY) {
+    dc->flags&=~DCF_SYMMETRY;
+    dc->thick=1;
+    xx=dc->sym.sny*8192;
+    yy=-dc->sym.snx*8192;
+    dc->color=RED;
+    GrLine3(dc,dc->sym.sx-xx.i32[1],dc->sym.sy-yy.i32[1],0,
+          dc->sym.sx+xx.i32[1],dc->sym.sy+yy.i32[1],0,3,0);
+    dc->color=WHITE;
+    GrLine3(dc,dc->sym.sx-xx.i32[1],dc->sym.sy-yy.i32[1],0,
+          dc->sym.sx+xx.i32[1],dc->sym.sy+yy.i32[1],0,3,1);
+    dc->color=BLACK;
+    GrLine3(dc,dc->sym.sx-xx.i32[1],dc->sym.sy-yy.i32[1],0,
+          dc->sym.sx+xx.i32[1],dc->sym.sy+yy.i32[1],0,3,2);
+    dc->flags|=DCF_SYMMETRY;
+  }
+  dc->color=old_color;
+  dc->thick=old_pen_width;
+}
+
+CSprite *SMLine(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrLine3(dc,x1,y1,0,x2,y2,0);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrLine3(dc,x1,y1,0,x2,y2,0);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_LINE));
+  res->type=SPT_LINE;
+  res->pp.x1=x1-x;
+  res->pp.y1=y1-y;
+  res->pp.x2=x2-x;
+  res->pp.y2=y2-y;
+  return res;
+}
+
+CSprite *SMArrow(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrArrow3(dc,x1,y1,0,x2,y2,0);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrArrow3(dc,x1,y1,0,x2,y2,0);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_ARROW));
+  res->type=SPT_ARROW;
+  res->pp.x1=x1-x;
+  res->pp.y1=y1-y;
+  res->pp.x2=x2-x;
+  res->pp.y2=y2-y;
+  return res;
+}
+
+CSprite *SMPlanarSymmetry(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,old_width,old_flags;
+  CSprite *res;
+  old_width=dc->thick;
+  old_flags=dc->flags;
+  dc->flags&=~DCF_SYMMETRY;
+  dc->thick=1;
+  do {
+    dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+    GrLine3(dc,x1,y1,0,x2,y2,0);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->flags=old_flags&DCF_SYMMETRY|dc->flags&~DCF_SYMMETRY;
+  dc->thick=old_width;
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_PLANAR_SYMMETRY));
+  res->type=SPT_PLANAR_SYMMETRY;
+  res->pp.x1=x1-x;
+  res->pp.y1=y1-y;
+  res->pp.x2=x2-x;
+  res->pp.y2=y2-y;
+  return res;
+}
+
+CSprite *SMRect(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,
+        xx1=arg1,yy1=arg2,xx2=arg1,yy2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrRect3(dc,xx1,yy1,0,xx2-xx1,yy2-yy1);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+    if (x2<x1) {
+      xx1=x2; xx2=x1;
+    } else {
+      xx1=x1; xx2=x2;
+    }
+    if (y2<y1) {
+      yy1=y2; yy2=y1;
+    } else {
+      yy1=y1; yy2=y2;
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrRect3(dc,xx1,yy1,0,xx2-xx1,yy2-yy1);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_RECT));
+  res->type=SPT_RECT;
+  res->pp.x1=xx1-x;
+  res->pp.y1=yy1-y;
+  res->pp.x2=xx2-x;
+  res->pp.y2=yy2-y;
+  return res;
+}
+
+CSprite *SMScrnBitMap(I64 eletype,CDC *dc,CDC *dc2,I64 x,I64 y,
+        I64 arg1,I64 arg2,CColorROPU32 bm_bkcolor)
+{
+  I64 i,msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,
+        xx1=arg1,yy1=arg2,xx2=arg1,yy2=arg2,old_width;
+  CDC *dc3,*img;
+  CSprite *res;
+  old_width=dc2->thick;
+  dc2->thick=1;
+  do {
+    dc2->color=ROPF_DITHER+WHITE<<16+BLACK;
+    GrBorder(dc2,xx1+Fs->pix_left+Fs->scroll_x,yy1+Fs->pix_top+Fs->scroll_y,
+          xx2+Fs->pix_left+Fs->scroll_x,yy2+Fs->pix_top+Fs->scroll_y);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+    if (x2<x1) {
+      xx1=x2; xx2=x1;
+    } else {
+      xx1=x1; xx2=x2;
+    }
+    if (y2<y1) {
+      yy1=y2; yy2=y1;
+    } else {
+      yy1=y1; yy2=y2;
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  xx2++; yy2++;
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_BITMAP)+((xx2-xx1+7)&~7)*(yy2-yy1));
+  res->type=SPT_BITMAP;
+  res->pwhu.width=xx2-xx1;
+  res->pwhu.height=yy2-yy1;
+  res->pwhu.x1=0;
+  res->pwhu.y1=0;
+  SpriteScrnInit(dc,x,y);
+  i=gr.scrn_zoom;
+  GrScaleZoom(1.0/i);
+  Refresh(2,TRUE);
+
+  dc3=DCScrnCapture;
+  img=DCExt(dc3,Fs->pix_left+Fs->scroll_x+xx1,Fs->pix_top+Fs->scroll_y+yy1,
+        Fs->pix_left+Fs->scroll_x+xx2-1,Fs->pix_top+Fs->scroll_y+yy2-1);
+  if (eletype==SPT_INS_TRANSPARENT_SCRN_BITMAP)
+    DCColorChg(img,bm_bkcolor);
+  GrScaleZoom(i);
+  MemCpy(&res->pwhu.u,img->body,((xx2-xx1+7)&~7)*(yy2-yy1));
+  DCDel(img);
+  DCDel(dc3);
+  dc2->thick=old_width;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_SELF_GRAB_SCROLL;
+  return res;
+}
+
+CSprite *SMCircle(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2)));
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2)));
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_CIRCLE));
+  res->type=SPT_CIRCLE;
+  res->pr.x1=x1-x;
+  res->pr.y1=y1-y;
+  res->pr.radius=Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2));
+  return res;
+}
+
+CSprite *SMEllipse(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  F64 angle1,angle2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrEllipse3(dc,(x1+x2)>>1,(y1+y2)>>1,0,AbsI64(x1-x2)>>1,AbsI64(y1-y2)>>1);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_ELLIPSE));
+  res->type=SPT_ELLIPSE;
+  res->pwha.x1=(x1+x2)>>1-x;
+  res->pwha.y1=(y1+y2)>>1-y;
+  res->pwha.width =AbsI64(x1-x2)>>1;
+  res->pwha.height=AbsI64(y1-y2)>>1;
+  angle2=Arg(x2-(res->pwha.x1+x),y2-(res->pwha.y1+y));
+  if (res->pwha.width<res->pwha.height)
+    angle2-=pi/2.0;
+  do {
+    angle1=Arg(x2-(res->pwha.x1+x),y2-(res->pwha.y1+y));
+    if (res->pwha.width>=res->pwha.height)
+      res->pwha.angle=-(angle1-angle2);
+    else
+      res->pwha.angle=-(angle1-angle2)+pi/2.0;
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrEllipse3(dc,res->pwha.x1+x,res->pwha.y1+y,0,
+          res->pwha.width,res->pwha.height,res->pwha.angle);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  angle1=Arg(x2-(res->pwha.x1+x),y2-(res->pwha.y1+y));
+  if (res->pwha.width>=res->pwha.height)
+    res->pwha.angle=-(angle1-angle2);
+  else
+    res->pwha.angle=-(angle1-angle2)+pi/2.0;
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrEllipse3(dc,res->pwha.x1+x,res->pwha.y1+y,0,
+        res->pwha.width,res->pwha.height,res->pwha.angle);
+  return res;
+}
+
+CSprite *SMPolygon(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,I64 sides,
+        CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  F64 angle1,angle2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrRegPoly3(dc,(x1+x2)>>1,(y1+y2)>>1,0,
+          AbsI64(x1-x2)>>1,AbsI64(y1-y2)>>1,sides);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_POLYGON));
+  res->type=SPT_POLYGON;
+  res->pwhas.x1=(x1+x2)>>1-x;
+  res->pwhas.y1=(y1+y2)>>1-y;
+  res->pwhas.width =AbsI64(x1-x2)>>1;
+  res->pwhas.height=AbsI64(y1-y2)>>1;
+  res->pwhas.sides=sides;
+  angle2=Arg(x2-(res->pwhas.x1+x),y2-(res->pwhas.y1+y));
+  if (res->pwhas.width<res->pwhas.height)
+    angle2-=pi/2.0;
+  do {
+    angle1=Arg(x2-(res->pwhas.x1+x),y2-(res->pwhas.y1+y));
+    if (res->pwhas.width>=res->pwhas.height)
+      res->pwhas.angle=-(angle1-angle2);
+    else
+      res->pwhas.angle=-(angle1-angle2)+pi/2.0;
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrRegPoly3(dc,res->pwhas.x1+x,res->pwhas.y1+y,0,
+          res->pwhas.width,res->pwhas.height,
+          res->pwhas.sides,res->pwhas.angle);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  angle1=Arg(x2-(res->pwhas.x1+x),y2-(res->pwhas.y1+y));
+  if (res->pwhas.width>=res->pwhas.height)
+    res->pwhas.angle=-(angle1-angle2);
+  else
+    res->pwhas.angle=-(angle1-angle2)+pi/2.0;
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrRegPoly3(dc,res->pwhas.x1+x,res->pwhas.y1+y,0,
+        res->pwhas.width,res->pwhas.height,res->pwhas.sides,
+        res->pwhas.angle);
+  return res;
+}
+
+CSprite *SMPolyLineFamily(I64 eletype,CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,
+        CColorROPU32 color)
+{
+  I64 i,num=0,msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  I32 *ptr;
+  CD3I32 *p;
+  CSprite *res,*tmpg,*tmpg1,head2;
+
+  QueInit(&head2);
+  do {
+    do {
+      dc->color=color&COLORROP_NO_ROP0_MASK;
+      if (num)
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_L_UP+1<<MSG_MS_MOVE+1<<MSG_MS_R_UP);
+      dc->color=TRANSPARENT;
+      if (num)
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+      x2=arg1; y2=arg2;
+    } while (msg_code!=MSG_MS_L_UP && msg_code!=MSG_MS_R_UP);
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    if (msg_code==MSG_MS_L_UP) {
+      if (num)
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+      res=CAlloc(SpriteElemQuedBaseSize(SPT_PT));
+      res->type=SPT_PT;
+      res->p.x1=x2-x;
+      res->p.y1=y2-y;
+      QueIns(res,head2.last);
+      x1=x2;y1=y2;
+      num++;
+    }
+  } while (msg_code!=MSG_MS_R_UP);
+
+  switch (eletype) {
+    case SPT_POLYLINE:
+      if (num>1) {
+        res=CAlloc(SpriteElemQuedBaseSize(SPT_POLYLINE)+num*sizeof(CD2I32));
+        ptr=&res->nu.u;
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          ptr[i<<1]=tmpg1->p.x1;
+          ptr[i<<1+1]=tmpg1->p.y1;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res->type=SPT_POLYLINE;
+        res->nu.num=num;
+      } else {
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res=NULL;
+      }
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      if (num>2) {
+        res=CAlloc(SpriteElemQuedBaseSize(eletype)+num*sizeof(CD3I32));
+        p=&res->nu.u;
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          p[i].x=tmpg1->p.x1;
+          p[i].y=tmpg1->p.y1;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res->type=eletype;
+        res->nu.num=num;
+      } else {
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res=NULL;
+      }
+      break;
+  }
+  return res;
+}
+
+CSprite *SMPolyPoint(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 i,num=0,msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,x3,y3;
+  I32 *ptr;
+  CSprite *res,*tmpg,*tmpg1,head2;
+
+  QueInit(&head2);
+  x3=arg1-x; y3=arg2-y;
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    x2=arg1; y2=arg2;
+    GrLine3(dc,x1,y1,0,x2,y2,0);
+    Line(&head2,x1-x,y1-y,0,x2-x,y2-y,0,&SpritePolyPtPlot);
+    x1=x2;y1=y2;
+  } while (msg_code!=MSG_MS_L_UP);
+
+  num=0;
+  res=head2.next;
+  x1=x3; y1=y3;
+  while (res!=&head2) {
+    tmpg=res->next;
+    if (res->p.x1==x1 && res->p.y1==y1) {
+      QueRem(res);
+      Free(res);
+    } else {
+      num++;
+      x1=res->p.x1;
+      y1=res->p.y1;
+    }
+    res=tmpg;
+  }
+
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_POLYPT)+(num*3+7)>>3);
+  res->npu.x=x3;
+  res->npu.y=y3;
+  ptr=&res->npu.u;
+  x1=x3; y1=y3;
+  i=0;
+  tmpg1=head2.next;
+  while (tmpg1!=&head2) {
+    tmpg=tmpg1->next;
+    BFieldOrU32(ptr,i,polypt_map[SignI64(tmpg1->p.x1-x1)+1+
+          3*(SignI64(tmpg1->p.y1-y1)+1)]);
+    i+=3;
+    x1=tmpg1->p.x1;y1=tmpg1->p.y1;
+    QueRem(tmpg1);
+    Free(tmpg1);
+    tmpg1=tmpg;
+  }
+  res->type=SPT_POLYPT;
+  res->npu.num=num;
+  return res;
+}
+
+U0 SMTextFamily(I64 eletype,CDoc *doc,CDocEntry *doc_ce,CSprite *head,CDC *dc,
+        I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color,I64 *_cur_elem_num,
+        I64 old_de_flags)
+{
+  CSprite *tmpg,*insert_pt=SpriteSetSettings(,head,*_cur_elem_num);
+  I64 msg_code,x1,y1;
+  U8 *st;
+  doc_ce->de_flags|=DOCEF_DONT_DRAW;
+  st=PopUpGetStr("Enter text and press <ESC>.\n");
+  doc_ce->de_flags=old_de_flags;
+  if (st && *st) {
+    x1=0; y1=0;
+    do {
+      dc->color=color&COLORROP_NO_ROP0_MASK;
+      switch (eletype) {
+        case SPT_TEXT:          GrPrint3(dc,x1,y1,0,"%s",st);   break;
+        case SPT_TEXT_BOX:      GrTextBox3(dc,x1,y1,0,st);      break;
+        case SPT_TEXT_DIAMOND:  GrTextDiamond3(dc,x1,y1,0,st);  break;
+      }
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+      SpriteScrnInit(dc,x,y);
+      x1=arg1; y1=arg2;
+    } while (msg_code!=MSG_MS_L_UP);
+    tmpg=CAlloc(SpriteElemQuedBaseSize(eletype)+StrLen(st)+1);
+    tmpg->type=eletype;
+    tmpg->ps.x1=x1-x;
+    tmpg->ps.y1=y1-y;
+    StrCpy(tmpg->ps.st,st);
+    QueIns(tmpg,insert_pt->last);
+    SpriteEdUpdate(doc,doc_ce,head);
+    *_cur_elem_num+=1;
+  }
+  Free(st);
+}
+
+I64 SMBitMap(I64 eletype,CDoc *doc,CDocEntry *doc_ce,CSprite *head,
+        CDC *dc,I64 xx,I64 yy,I64 arg1,I64 arg2,CColorROPU32 bm_bkcolor,
+        Bool sel,I64 xx1=0,I64 yy1=0,I64 xx2=0,I64 yy2=0,I64 *_cur_elem_num)
+{
+  I64 i,msg_code,x=xx,y=yy,x1=arg1,y1=arg2,x2=arg1,y2=arg2,old_width;
+  CSprite *tmpg,*tmpg1,*insert_pt;
+  CDC *img;
+
+  insert_pt=SpriteSetSettings(,head,*_cur_elem_num,xx,yy,,,&x,&y);
+  x+=xx; y+=yy;
+
+  if (sel) {
+    xx1=arg1; yy1=arg2;
+    xx2=arg1; yy2=arg2;
+    old_width=dc->thick;
+    dc->thick=1;
+    do {
+      dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+      GrBorder(dc,xx1,yy1,xx2,yy2);
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+      SpriteScrnInit(dc,x,y);
+      x2=arg1; y2=arg2;
+      if (x2<x1) {
+        xx1=x2; xx2=x1;
+      } else {
+        xx1=x1; xx2=x2;
+      }
+      if (y2<y1) {
+        yy1=y2; yy2=y1;
+      } else {
+        yy1=y1; yy2=y2;
+      }
+    } while (msg_code!=MSG_MS_L_UP);
+    dc->thick=old_width;
+  }
+
+  xx2++; yy2++;
+  tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_BITMAP)+
+        ((xx2-xx1+7)&~7)*(yy2-yy1));
+  tmpg->type=SPT_BITMAP;
+  tmpg->pwhu.width=xx2-xx1;
+  tmpg->pwhu.height=yy2-yy1;
+  tmpg->pwhu.x1=xx1-x;
+  tmpg->pwhu.y1=yy1-y;
+  img=DCNew(tmpg->pwhu.width,tmpg->pwhu.height,Fs);
+  img->color=bm_bkcolor;
+  GrRect(img,0,0,tmpg->pwhu.width,tmpg->pwhu.height);
+  tmpg1=insert_pt;
+  if (tmpg1==head || tmpg1->type&SPG_TYPE_MASK!=SPT_BITMAP) {
+    SpriteSetSettings(img,head,0,-(xx1-x),-(yy1-y));
+    x=xx; y=yy;
+    Sprite3(img,-(xx1-x),-(yy1-y),0,doc_ce->bin_data->data);
+    QueDel(head);
+    insert_pt=head->next=head->last=head;
+    *_cur_elem_num=1;
+  } else {
+    SpriteSetSettings(img,head,*_cur_elem_num,-(xx1-x),-(yy1-y));
+    Sprite3(img,-(xx1-x),-(yy1-y),0,&tmpg1->start,TRUE);
+    insert_pt=tmpg1->next;
+    QueRem(tmpg1);
+    Free(tmpg1);
+  }
+  MemCpy(&tmpg->pwhu.u,img->body,((xx2-xx1+7)&~7)*(yy2-yy1));
+
+  switch (i=SpriteBitMapEd(doc,doc_ce,dc,&xx1,&yy1,
+        &xx2,&yy2,&img,bm_bkcolor)) {
+    case SPE_EXIT:
+    case SPE_CONT:
+      Free(tmpg);
+      tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_BITMAP)+
+            ((xx2-xx1+7)&~7)*(yy2-yy1));
+      tmpg->type=eletype;
+      tmpg->pwhu.width=xx2-xx1;
+      tmpg->pwhu.height=yy2-yy1;
+      tmpg->pwhu.x1=xx1-x;
+      tmpg->pwhu.y1=yy1-y;
+      MemCpy(&tmpg->pwhu.u,img->body,((xx2-xx1+7)&~7)*(yy2-yy1));
+      break;
+  }
+  QueIns(tmpg,insert_pt->last);
+  DCDel(img);
+  SpriteEdUpdate(doc,doc_ce,head);
+  return i;
+}
+
+U0 SMMesh(CDoc *doc,CDocEntry *doc_ce,CSprite *head,I64 *_cur_elem_num)
+{
+  CSprite *tmpg,*insert_pt=SpriteSetSettings(,head,*_cur_elem_num),
+        *tmpg1=insert_pt;
+  CD3I32 *p;
+  I64 i,size,x1,y1,z1;
+  I32 *mesh,*old_mesh;
+  if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_MESH)
+    old_mesh=&tmpg1->mu.vertex_cnt;
+  else if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    x1=tmpg1->pmu.x;
+    y1=tmpg1->pmu.y;
+    z1=tmpg1->pmu.z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x+=x1;
+      p->y+=y1;
+      p->z+=z1;
+    }
+    old_mesh=&tmpg1->pmu.vertex_cnt;
+  } else
+    old_mesh=NULL;
+  if (mesh=SpriteMeshEd(old_mesh,&size,TRUE)) {
+    tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_MESH)-sizeof(I32)*2+size);
+    tmpg->type=SPT_MESH;
+    MemCpy(&tmpg->mu.vertex_cnt,mesh,size);
+    Free(mesh);
+    QueIns(tmpg,insert_pt->last);
+    SpriteEdUpdate(doc,doc_ce,head);
+    if (old_mesh) {
+      insert_pt=tmpg;
+      QueRem(tmpg1);
+      Free(tmpg1);
+      SpriteEdUpdate(doc,doc_ce,head);
+    } else
+      *_cur_elem_num+=1;
+  } else if (old_mesh && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    x1=tmpg1->pmu.x;
+    y1=tmpg1->pmu.y;
+    z1=tmpg1->pmu.z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x-=x1;
+      p->y-=y1;
+      p->z-=z1;
+    }
+  }
+}
+
+U0 SMShiftableMesh(CDoc *doc,CDocEntry *doc_ce,CSprite *head,
+        I64 x,I64 y,I64 arg1,I64 arg2,I64 *_cur_elem_num)
+{
+  CSprite *tmpg,*insert_pt=SpriteSetSettings(,head,*_cur_elem_num),
+        *tmpg1=insert_pt;
+  CD3I32 *p;
+  I64 i,size,z,x1,y1,z1;
+  I32 *mesh,*old_mesh;
+  if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_MESH) {
+    z=0;
+    x1=-(arg1-x);
+    y1=-(arg2-y);
+    z1=z;
+    p=&tmpg1->mu.u;
+    for (i=0;i<tmpg1->mu.vertex_cnt;i++,p++) {
+      p->x+=x1;
+      p->y+=y1;
+      p->z+=z1;
+    }
+    old_mesh=&tmpg1->mu.vertex_cnt;
+  } else if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    z=-tmpg1->pmu.z;
+    x1=tmpg1->pmu.x-(arg1-x);
+    y1=tmpg1->pmu.y-(arg2-y);
+    z1=tmpg1->pmu.z+z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x+=x1;
+      p->y+=y1;
+      p->z+=z1;
+    }
+    old_mesh=&tmpg1->pmu.vertex_cnt;
+  } else {
+    z=0;
+    old_mesh=NULL;
+  }
+  if (mesh=SpriteMeshEd(old_mesh,&size,TRUE)) {
+    tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_SHIFTABLE_MESH)-sizeof(I32)*2+size);
+    tmpg->type=SPT_SHIFTABLE_MESH;
+    MemCpy(&tmpg->pmu.vertex_cnt,mesh,size);
+    Free(mesh);
+    tmpg->pmu.x=arg1-x;
+    tmpg->pmu.y=arg2-y;
+    tmpg->pmu.z=-z;
+    QueIns(tmpg,insert_pt->last);
+    SpriteEdUpdate(doc,doc_ce,head);
+    if (old_mesh) {
+      insert_pt=tmpg;
+      QueRem(tmpg1);
+      Free(tmpg1);
+      SpriteEdUpdate(doc,doc_ce,head);
+    } else
+      *_cur_elem_num+=1;
+  } else if (old_mesh && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    x1=tmpg1->pmu.x-(arg1-x);
+    y1=tmpg1->pmu.y-(arg2-y);
+    z1=tmpg1->pmu.z+z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x-=x1;
+      p->y-=y1;
+      p->z-=z1;
+    }
+  } else if (old_mesh && tmpg1->type&SPG_TYPE_MASK==SPT_MESH) {
+    x1=-(arg1-x);
+    y1=-(arg2-y);
+    z1= z;
+    p=&tmpg1->mu.u;
+    for (i=0;i<tmpg1->mu.vertex_cnt;i++,p++) {
+      p->x-=x1;
+      p->y-=y1;
+      p->z-=z1;
+    }
+  }
+}
+
+U0 SMTaskTitleSet(I64 eletype)
+{
+  Fs->title_src=TTS_CONST; //Violates TTS_LOCKED_CONST
+  switch (eletype) {
+    case SPT_INS_SCRN_BITMAP:
+      StrCpy(Fs->task_title,"Insert Scrn BitMap");
+      break;
+    case SPT_INS_TRANSPARENT_SCRN_BITMAP:
+      StrCpy(Fs->task_title,"Insert Transparent Scrn BitMap");
+      break;
+    default:
+      if (eletype>=0)
+        StrCpy(Fs->task_title,DefineSub(eletype,"ST_SPRITE_ELEM_TYPES"));
+  }
+  Fs->border_src=BDS_CONST;
+}
+
+I64 SpriteMainEd(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  I64 res,i,x,y,arg1,arg2,xx,yy,xx1,yy1,xx2,yy2,thick,eletype=SPT_MENU,
+        cur_elem_num,old_border_src=Fs->border_src,old_title_src=Fs->title_src,
+        old_de_flags=doc_ce->de_flags;
+  CColorROPU32 bm_bkcolor,color;
+  CSprite *head,*tmpg,*insert_pt;
+  CDC *dc=DCAlias(,Fs),*dc2=DCAlias(,sys_winmgr_task),*dc3;
+  U8 *old_task_title=StrNew(Fs->task_title);
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  Refresh(2,TRUE);
+  dc2->flags|=DCF_ON_TOP;
+  head=Sprite2SpriteQue(doc_ce->bin_data->data);
+  cur_elem_num=QueCnt(head);
+  xx=(doc_ce->x+doc_ce->max_col-doc->line_start_col)*FONT_WIDTH;
+  yy=(doc_ce->y-doc->top_line_num)*FONT_HEIGHT;
+
+  while (TRUE) {
+    insert_pt=SpriteSetSettings(dc,head,cur_elem_num,xx,yy,
+          &color,&thick,&x,&y);
+    x+=xx; y+=yy;
+    DCFill;
+    if (eletype==SPT_MENU) {
+      Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+            -WIF_SELF_BORDER-WIF_SELF_GRAB_SCROLL;
+      if (winmgr.fps<10)
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+      StrCpy(Fs->task_title,old_task_title);
+      Fs->border_src=old_border_src;
+      Fs->title_src =old_title_src;
+
+      xx-=StrLen(doc_ce->tag)*FONT_WIDTH;
+      eletype=PopUpSpriteMain(&head,&cur_elem_num,doc,doc_ce);
+      xx+=StrLen(doc_ce->tag)*FONT_WIDTH;
+      insert_pt=SpriteSetSettings(dc,head,cur_elem_num,x,y,
+            &color,&thick,&x,&y);
+      x+=xx; y+=yy;
+
+      SpriteEdUpdate(doc,doc_ce,head);
+      switch (eletype) {
+        case SPT_FLOOD_FILL:
+        case SPT_FLOOD_FILL_NOT:
+          RegOneTimePopUp(ARf_FLOODFILL,
+                ST_WARN_ST "This is affected by what's underneath\n"
+                "when it is drawn.  You will probably want to\n"
+                "convert it to a bitmap.\n\n"
+                "A tip on artistry you might consider\n"
+                "is using lines to fill regions because\n"
+                "brush strokes look cool.\n");
+          break;
+        case SPT_PLANAR_SYMMETRY:
+          RegOneTimePopUp(ARf_PLANAR_SYMMETRY,
+                "Right-click to turn-off symmetry.\n");
+          break;
+      }
+      doc_ce->de_flags=old_de_flags;
+    }
+    SMTaskTitleSet(eletype);
+    switch (eletype) {
+      case SPT_COLOR:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColor(,,FALSE);
+        if (i>=0) {
+          color=i;
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_COLOR));
+          tmpg->type=SPT_COLOR;
+          tmpg->c.color=color;
+          QueIns(tmpg,insert_pt->last);
+          SpriteEdUpdate(doc,doc_ce,head);
+          cur_elem_num++;
+        }
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_DITHER_COLOR:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColorDither;
+        if (i>=0) {
+          color=i;
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_DITHER_COLOR));
+          tmpg->type=SPT_DITHER_COLOR;
+          tmpg->d.dither_color=color.c0.color|color.c1.color<<8;
+          QueIns(tmpg,insert_pt->last);
+          SpriteEdUpdate(doc,doc_ce,head);
+          cur_elem_num++;
+        }
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_ED_MENU:
+        switch (SpriteEd(doc,doc_ce,x,y,&head,&cur_elem_num)) {
+          case SPE_ABORT:       eletype=DOCM_CANCEL;    break;
+          case SPE_EXIT:        eletype=SPT_EXIT;       break;
+          case SPE_CONT:        eletype=SPT_MENU;       break;
+        }
+        break;
+      case SPT_MESH:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        SMMesh(doc,doc_ce,head,&cur_elem_num);
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_SHIFTABLE_MESH:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        if (PopUpNoYes("Study the $LK,\"X-Caliber\","
+              "A=\"FF:::/PersonalMenu.DD.Z,X-Caliber\"$ icon.\n\n"
+              "It has black rectangle background with stars.  The\n"
+              "mesh is in front and rotates.  To keep the background\n"
+              "rectangle from rotating, "
+              "$GREEN$TRANSFORM OFF$FG$ has been used.\n\n"
+              "The X-Caliber mesh has a different origin for rotation.\n"
+              "To avoid clipping, it also has also been moved in the\n"
+              "negative Z direction by editing the sprite as text\n"
+              "and changing the first vector.\n\n"
+              "For the mesh you are creating, use same origin as\n"
+              "the rest of the sprite?  If $GREEN$YES$FG$, you can always\n"
+              "shift the mesh origin point in the sprite edit menu.\n")) {
+          doc_ce->de_flags=old_de_flags;
+          arg1=x; arg2=y;
+          SMShiftableMesh(doc,doc_ce,head,x,y,arg1,arg2,&cur_elem_num);
+          eletype=SPT_MENU;
+        } else
+          PopUpOk("Select Origin.\n");
+        doc_ce->de_flags=old_de_flags;
+        break;
+      case SPT_INS_SCRN_BITMAP:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        PopUpOk("Drag-out a rect for the extents of the\nbitmap.\n");
+        doc_ce->de_flags=old_de_flags;
+        Fs->win_inhibit=WIG_TASK_DFT|WIF_FOCUS_TASK_MS_L|WIF_FOCUS_TASK_MS_R|
+              WIF_FOCUS_TASK_BORDER-WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+        break;
+      case SPT_BITMAP:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColor("Background Color\n\n",,FALSE);
+        if (i<0)
+          eletype=SPT_MENU;
+        else {
+          bm_bkcolor=i;
+          SpriteEdUpdate(doc,doc_ce,head);
+          SpriteExtents(doc_ce->bin_data->data,&xx1,&xx2,&yy1,&yy2);
+          if (!(xx1<=xx2 && yy1<=yy2))
+            xx1=xx2=yy1=yy2=0;
+          if (PopUpExtents(&xx1,&xx2,&yy1,&yy2)) {
+            doc_ce->de_flags=old_de_flags;
+            xx1+=xx; yy1+=yy;
+            xx2+=xx; yy2+=yy;
+            if (SMBitMap(eletype,doc,doc_ce,head,dc,xx,yy,arg1,arg2,bm_bkcolor,
+                  FALSE,xx1,yy1,xx2,yy2,&cur_elem_num)==SPE_EXIT) {
+              res=SPE_EXIT;
+              goto ei_done;
+            }
+            eletype=SPT_MENU;
+          }
+        }
+        doc_ce->de_flags=old_de_flags;
+        break;
+      case SPT_INS_TRANSPARENT_SCRN_BITMAP:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColor("Color to Become Transparent\n\n",,FALSE);
+        if (i<0)
+          eletype=SPT_MENU;
+        else {
+          bm_bkcolor=i;
+          PopUpOk("Drag-out a rect for the extents of the\nbitmap.\n");
+        }
+        doc_ce->de_flags=old_de_flags;
+        Fs->win_inhibit=WIG_TASK_DFT|WIF_FOCUS_TASK_MS_L|WIF_FOCUS_TASK_MS_R|
+              WIF_FOCUS_TASK_BORDER-WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+        break;
+      case SPT_THICK:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpRangeI64(1,16,1,"Thick\n");
+        if (i>=1) {
+          thick=i;
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_THICK));
+          tmpg->type=SPT_THICK;
+          tmpg->t.thick=thick;
+          QueIns(tmpg,insert_pt->last);
+          SpriteEdUpdate(doc,doc_ce,head);
+          cur_elem_num++;
+        }
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_TRANSFORM_ON:
+      case SPT_TRANSFORM_OFF:
+        tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_TRANSFORM_ON));
+        if (eletype==SPT_TRANSFORM_ON)
+          tmpg->type=SPT_TRANSFORM_ON;
+        else
+          tmpg->type=SPT_TRANSFORM_OFF;
+        QueIns(tmpg,insert_pt->last);
+        SpriteEdUpdate(doc,doc_ce,head);
+        cur_elem_num++;
+        eletype=SPT_MENU;
+        break;
+      case SPT_POLYGON:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpRangeI64(3,16,1,"Num of Sides\n");
+        doc_ce->de_flags=old_de_flags;
+        if (i<3)
+          eletype=SPT_MENU;
+        break;
+      case SPT_TEXT:
+      case SPT_TEXT_BOX:
+      case SPT_TEXT_DIAMOND:
+        SMTextFamily(eletype,doc,doc_ce,head,dc,xx,yy,arg1,arg2,
+              color,&cur_elem_num,old_de_flags);
+        eletype=SPT_MENU;
+        break;
+    }
+
+    if (eletype!=SPT_MENU) {
+      insert_pt=SpriteSetSettings(dc,head,cur_elem_num,xx,yy,
+            &color,&thick,&x,&y);
+      x+=xx; y+=yy;
+      SpriteScrnInit(dc,x,y);
+      if (eletype==SPT_EXIT) {
+        res=SPE_EXIT;
+        goto ei_done;
+      } else if (eletype==DOCM_CANCEL) {
+        res=SPE_ABORT;
+        goto ei_done;
+      }
+      switch (GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_R_UP|1<<MSG_MS_L_DOWN)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case CH_ESC:
+              res=SPE_EXIT;
+              goto ei_done;
+            case CH_SHIFT_ESC:
+              res=SPE_ABORT;
+              goto ei_done;
+            case 'c': //eye-dropper
+              dc3=DCScrnCapture(FALSE);
+              color=GrPeek(dc3,ms.pos.x,ms.pos.y)^15;//Mouse cursor is XORed.
+              DCDel(dc3);
+              tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_COLOR));
+              tmpg->type=SPT_COLOR;
+              tmpg->c.color=color;
+              QueIns(tmpg,insert_pt->last);
+              SpriteEdUpdate(doc,doc_ce,head);
+              cur_elem_num++;
+              break;
+            case 't': //Set to transparent color
+              tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_COLOR));
+              tmpg->type=SPT_COLOR;
+              tmpg->c.color=TRANSPARENT;
+              QueIns(tmpg,insert_pt->last);
+              SpriteEdUpdate(doc,doc_ce,head);
+              cur_elem_num++;
+              break;
+          }
+          break;
+        case MSG_MS_R_UP:
+          if (eletype==SPT_PLANAR_SYMMETRY) {
+            tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_PLANAR_SYMMETRY));
+            tmpg->type=SPT_PLANAR_SYMMETRY;
+            QueIns(tmpg,insert_pt->last);
+            SpriteEdUpdate(doc,doc_ce,head);
+            cur_elem_num++;
+            eletype=SPT_MENU;
+          } else
+            eletype=SPT_MENU;
+          break;
+        case MSG_MS_L_DOWN:
+          switch (eletype) {
+            start:
+              case SPT_LINE:
+                tmpg=SMLine(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_ARROW:
+                tmpg=SMArrow(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_PLANAR_SYMMETRY:
+                tmpg=SMPlanarSymmetry(dc,x,y,arg1,arg2);
+                eletype=SPT_MENU;
+                break;
+              case SPT_RECT:
+                tmpg=SMRect(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_INS_SCRN_BITMAP:
+              case SPT_INS_TRANSPARENT_SCRN_BITMAP:
+                tmpg=SMScrnBitMap(eletype,dc,dc2,x,y,arg1,arg2,bm_bkcolor);
+                eletype=SPT_MENU;
+                break;
+              case SPT_CIRCLE:
+                tmpg=SMCircle(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_ELLIPSE:
+                tmpg=SMEllipse(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_POLYGON:
+                tmpg=SMPolygon(dc,x,y,arg1,arg2,i,color);
+                eletype=SPT_MENU;
+                break;
+              case SPT_PT:
+              case SPT_FLOOD_FILL:
+              case SPT_FLOOD_FILL_NOT:
+                tmpg=CAlloc(SpriteElemQuedBaseSize(eletype));
+                tmpg->type=eletype;
+                tmpg->p.x1=arg1-x;
+                tmpg->p.y1=arg2-y;
+                break;
+              case SPT_POLYLINE:
+              case SPT_BSPLINE2:
+              case SPT_BSPLINE3:
+              case SPT_BSPLINE2_CLOSED:
+              case SPT_BSPLINE3_CLOSED:
+                tmpg=SMPolyLineFamily(eletype,dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_POLYPT:
+                tmpg=SMPolyPoint(dc,x,y,arg1,arg2,color);
+                break;
+            end:
+              if (tmpg) {
+                QueIns(tmpg,insert_pt->last);
+                SpriteEdUpdate(doc,doc_ce,head);
+                cur_elem_num++;
+              }
+              break;
+            case SPT_BITMAP:
+              if (SMBitMap(eletype,doc,doc_ce,head,dc,xx,yy,
+                    arg1,arg2,bm_bkcolor,TRUE,,,,,&cur_elem_num)==SPE_EXIT) {
+                res=SPE_EXIT;
+                goto ei_done;
+              }
+              doc_ce->de_flags=old_de_flags;
+              eletype=SPT_MENU;
+              break;
+            case SPT_SHIFTABLE_MESH:
+              GetMsg(NULL,NULL,1<<MSG_MS_L_UP);
+              doc_ce->de_flags|=DOCEF_DONT_DRAW;
+              SMShiftableMesh(doc,doc_ce,head,x,y,arg1,arg2,&cur_elem_num);
+              doc_ce->de_flags=old_de_flags;
+              eletype=SPT_MENU;
+              break;
+          }
+          break;
+      }
+    }
+  }
+ei_done:
+  DCFill;
+  SettingsPop;
+  doc_ce->de_flags=old_de_flags;
+  DCDel(dc);
+  DCDel(dc2);
+  StrCpy(Fs->task_title,old_task_title);
+  Free(old_task_title);
+  Fs->border_src=old_border_src;
+  Fs->title_src =old_title_src;
+  QueDel(head);
+  Free(head);
+  return res;
+}
+
+U0 EdSpriteIns(CDoc *doc)
+{
+  Bool unlock;
+  U8 *st;
+  CDocEntry *doc_e;
+  CDocBin *tmpb;
+  if (Fs!=doc->mem_task)
+    throw('Graphics');
+  if (st=EdSprite(doc->cur_bin_num)) {
+    unlock=DocLock(doc);
+    tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
+    tmpb->size=sprite_elem_base_sizes[SPT_END];
+    tmpb->data=CAlloc(tmpb->size,doc->mem_task);
+    tmpb->num=doc->cur_bin_num++;
+    tmpb->use_cnt=1;
+    QueIns(tmpb,doc->bin_head.last);
+    doc_e=DocPrint(doc,"%s",st);
+    doc_e->bin_data=tmpb;
+    Free(st);
+    if (doc_e) {
+      if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+        tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
+      doc->cur_entry=doc_e;
+      doc->cur_col=0;
+      DocUnlock(doc);
+      DocRecalc(doc);
+      if (SpriteMainEd(doc)==SPE_ABORT) {
+        DocLock(doc);
+        DocEntryDel(doc,doc_e);
+      } else
+        SpriteSelAll(tmpb->data,FALSE);
+    } else
+      DocBinDel(doc,tmpb);
+    if (unlock)
+      DocUnlock(doc);
+  }
+  if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
+    DocBinsValidate(doc);
+}
+
+U0 EdSpriteEd(CDoc *doc)
+{
+  CDocEntry *doc_ce;
+  CDocBin *tmpb;
+  CSprite *old_csprite;
+  I64   old_size;
+  Bool unlock=DocLock(doc);
+  doc_ce=doc->cur_entry;
+  tmpb=doc_ce->bin_data;
+  old_size=tmpb->size;
+  old_csprite=tmpb->data;
+  tmpb->data=MAllocIdent(old_csprite,doc->mem_task);
+  DocUnlock(doc);
+  if (SpriteMainEd(doc)==SPE_ABORT) {
+    DocLock(doc);
+    Free(tmpb->data);
+    tmpb->data=old_csprite;
+    tmpb->size=old_size;
+  } else {
+    SpriteSelAll(tmpb->data,FALSE);
+    Free(old_csprite);
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+ diff --git a/public/Wb/Adam/Gr/SpriteMesh.HC.HTML b/public/Wb/Adam/Gr/SpriteMesh.HC.HTML new file mode 100755 index 0000000..5d52a61 --- /dev/null +++ b/public/Wb/Adam/Gr/SpriteMesh.HC.HTML @@ -0,0 +1,1539 @@ + + + + + + + + + + + +
+#help_index "Graphics/Mesh"
+#define MESH_WORKSPACE_SIZE     4000
+
+#define VF_SEL          1
+#define VF_COPIED       2
+#define VF_IGNORE       4
+
+class CMeshEdVertex
+{
+  CMeshEdVertex *next,*last,*copy;
+
+  U0 start;
+  CD3I32 p; //World coordinates of the point.
+  U0 end;
+  CD3I32 p0,
+        pt; //Transformed coordinates.  (Scrn)
+  I32 num,flags;
+};
+
+#define TF_SEL  1
+#define TF_COPIED       2
+
+class CMeshEdTri
+{
+  CMeshEdTri *next,*last;
+
+  U0 start;
+  CMeshTri mt;
+  U0 end;
+
+  I32 cpu_num,flags; //Draw different tris with different cores.
+  CMeshEdVertex *t[3];
+};
+
+class CMeshFrame
+{
+  I64 ms_z,thickness; //Mouse Z-coordinate
+  I64 ed_mode,cx,cy;
+  CColorROPU32 cur_color;
+  Bool grid_on,flip_y,sel_rect,vertex_on,closed,pad[3];
+  I64 mp_not_done_flags; //Used for multiprocessing signaling.
+  F64 view_scale;
+  CDC *dc;
+  I32 *depth_buf;
+  I64 *w2s,*s2w; //Scrn-to-world and world-to-scrn transform matrices.
+  I64 vertex_cnt,tri_cnt; //Set by MeshSize
+  CMeshEdVertex vertex_head,*cur_vertex,*chain_pred;
+  CMeshEdTri    tri_head,*cur_tri;
+  I64 x1,y1,x2,y2,cur_snap;
+};
+
+CMeshEdVertex *MeshVertexNew(CMeshFrame *e,I64 x,I64 y,I64 z)
+{
+  CMeshEdVertex *tmpv=CAlloc(sizeof(CMeshEdVertex));
+  tmpv->p.x=x;
+  tmpv->p.y=y;
+  tmpv->p.z=z;
+  QueIns(tmpv,e->vertex_head.last);
+  return tmpv;
+}
+
+CMeshEdTri *MeshTriNew(CMeshFrame *e,CColorROPU32 color,
+        CMeshEdVertex *v1,CMeshEdVertex *v2,CMeshEdVertex *v3)
+{
+  static I64 cpu_num=0;
+  CMeshEdTri *tmpt=CAlloc(sizeof(CMeshEdTri));
+  tmpt->cpu_num=cpu_num++%mp_cnt;
+  tmpt->mt.color=color;
+  tmpt->t[0]=v1;
+  tmpt->t[1]=v2;
+  tmpt->t[2]=v3;
+  QueIns(tmpt,e->tri_head.last);
+  return tmpt;
+}
+
+CMeshEdVertex *MeshVertexFindScrPt(CMeshFrame *e,I64 x,I64 y)
+{//Scrn coordinates
+  CMeshEdVertex *res=NULL,*tmpv=e->vertex_head.next;
+  I64 dd,dz,best_dd=I64_MAX,best_dz=I64_MAX;
+  while (tmpv!=&e->vertex_head) {
+    if (!(tmpv->flags&VF_IGNORE)) {
+      dd=SqrI64(x-tmpv->pt.x)+SqrI64(y-tmpv->pt.y);
+      dz=AbsI64(e->ms_z-tmpv->p.z);
+      if (dd<best_dd || dd==best_dd && dz<best_dz) {
+        res=tmpv;
+        best_dd=dd;
+        best_dz=dz;
+      }
+    }
+    tmpv=tmpv->next;
+  }
+  return res;
+}
+
+CMeshEdVertex *MeshVertexFindNum(CMeshFrame *haystack_e,I64 needle_num)
+{
+  CMeshEdVertex *tmpv=haystack_e->vertex_head.next;
+  while (tmpv!=&haystack_e->vertex_head) {
+    if (tmpv->num==needle_num)
+      return tmpv;
+    tmpv=tmpv->next;
+  }
+  return NULL;
+}
+
+U0 MeshTriDel(CMeshFrame *e,CMeshEdTri *tmpt)
+{
+  if (tmpt) {
+    if (tmpt==e->cur_tri)
+      e->cur_tri=NULL;
+    QueRem(tmpt);
+    Free(tmpt);
+  }
+}
+
+U0 MeshVertexDel(CMeshFrame *e,CMeshEdVertex *tmpv)
+{
+  I64 i;
+  CMeshEdTri *tmpt,*tmpt1;
+  if (tmpv) {
+    tmpt=e->tri_head.next;
+    while (tmpt!=&e->tri_head) {
+      tmpt1=tmpt->next;
+      for (i=0;i<3;i++)
+        if (tmpt->t[i]==tmpv)
+          break;
+      if (i<3)
+        MeshTriDel(e,tmpt);
+      tmpt=tmpt1;
+    }
+    if (tmpv==e->cur_vertex)
+      e->cur_vertex=NULL;
+    if (tmpv==e->chain_pred)
+      e->chain_pred=NULL;
+    QueRem(tmpv);
+    Free(tmpv);
+  }
+}
+
+U0 MeshFence(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv,*tmpv1,*tmpv_last=NULL,*tmpv1_last=NULL,
+        *start=e->chain_pred->next,*end=e->vertex_head.last;
+  tmpv=start;
+  while (TRUE) {
+    tmpv1=MeshVertexNew(e,tmpv->p.x,tmpv->p.y,tmpv->p.z+e->thickness);
+    if (tmpv_last) {
+      MeshTriNew(e,e->cur_color,tmpv_last,tmpv,tmpv1);
+      MeshTriNew(e,e->cur_color,tmpv1,tmpv1_last,tmpv_last);
+    }
+    tmpv_last=tmpv;
+    tmpv1_last=tmpv1;
+    if (tmpv==end)
+      break;
+    tmpv=tmpv->next;
+  }
+  if (e->closed && tmpv_last) {
+    MeshTriNew(e,e->cur_color,tmpv_last,start,end->next);
+    MeshTriNew(e,e->cur_color,end->next,tmpv1_last,tmpv_last);
+  }
+}
+
+U0 MeshPolygon(CMeshFrame *e,CMeshEdVertex *start,CMeshEdVertex *end,Bool rev)
+{
+  CMeshEdVertex *tmpv,*tmpv1;
+  if (start!=end) {
+    tmpv=start;
+    tmpv1=tmpv->next;
+    while (tmpv1!=end) {
+      if (rev)
+        MeshTriNew(e,e->cur_color,tmpv1,tmpv,end);
+      else
+        MeshTriNew(e,e->cur_color,tmpv,tmpv1,end);
+      tmpv=tmpv->next;
+      tmpv1=tmpv1->next;
+    }
+  }
+}
+
+U0 MeshPrism(CMeshFrame *e)
+{
+  CMeshEdVertex *start=e->chain_pred->next,*end=e->vertex_head.last;
+  MeshFence(e);
+  MeshPolygon(e,start,end,FALSE);
+  MeshPolygon(e,end->next,e->vertex_head.last,TRUE);
+}
+
+U0 MeshVertexSelAll(CMeshFrame *e,Bool val)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    if (val)
+      tmpv->flags|=VF_SEL;
+    else
+      tmpv->flags&=~VF_SEL;
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshTriSelAll(CMeshFrame *e,Bool val)
+{
+  CMeshEdTri *tmpt=e->tri_head.next;
+  while (tmpt!=&e->tri_head) {
+    if (val)
+      tmpt->flags|=TF_SEL;
+    else
+      tmpt->flags&=~TF_SEL;
+    tmpt=tmpt->next;
+  }
+}
+
+U0 MeshVertexIgnoreSet(CMeshFrame *e,Bool val)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    tmpv->flags&=~VF_IGNORE;
+    if (tmpv->flags&VF_SEL && val)
+      tmpv->flags|=VF_IGNORE;
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshP0Capture(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    MemCpy(&tmpv->p0,&tmpv->p,sizeof(CD3I32));
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshP0Offset(CMeshFrame *e,I64 dx,I64 dy,I64 dz)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL) {
+      tmpv->p.x=tmpv->p0.x+dx;
+      tmpv->p.y=tmpv->p0.y+dy;
+      tmpv->p.z=tmpv->p0.z+dz;
+    }
+    tmpv=tmpv->next;
+  }
+}
+
+#define SEL_MESH_EQU    0
+#define SEL_MESH_OR     1
+#define SEL_MESH_AND    2
+
+U0 MeshVertexSelRect(CMeshFrame *e,I64 sel_mode,I64 x1,I64 x2,I64 y1,I64 y2)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (x1>x2) SwapI64(&x1,&x2);
+  if (y1>y2) SwapI64(&y1,&y2);
+  while (tmpv!=&e->vertex_head) {
+    if (x1<=tmpv->pt.x<=x2 &&
+          y1<=tmpv->pt.y<=y2) {
+      if (sel_mode==SEL_MESH_AND)
+        tmpv->flags&=~VF_SEL;
+      else
+        tmpv->flags|=VF_SEL;
+    } else if (sel_mode==SEL_MESH_EQU)
+      tmpv->flags&=~VF_SEL;
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshTriSelRect(CMeshFrame *e,I64 sel_mode,I64 x1,I64 x2,I64 y1,I64 y2)
+{
+  CMeshEdTri *tmpt=e->tri_head.next;
+  if (x1>x2) SwapI64(&x1,&x2);
+  if (y1>y2) SwapI64(&y1,&y2);
+  while (tmpt!=&e->tri_head) {
+    if (x1<=tmpt->t[0]->pt.x<=x2 &&
+          y1<=tmpt->t[0]->pt.y<=y2 &&
+          x1<=tmpt->t[1]->pt.x<=x2 &&
+          y1<=tmpt->t[1]->pt.y<=y2 &&
+          x1<=tmpt->t[2]->pt.x<=x2 &&
+          y1<=tmpt->t[2]->pt.y<=y2) {
+      if (sel_mode==SEL_MESH_AND)
+        tmpt->flags&=~TF_SEL;
+      else
+        tmpt->flags|=TF_SEL;
+    } else {
+      if (sel_mode==SEL_MESH_EQU)
+        tmpt->flags&=~TF_SEL;
+      else if (sel_mode==SEL_MESH_AND) {
+        if (x1<=tmpt->t[0]->pt.x<=x2 &&
+              y1<=tmpt->t[0]->pt.y<=y2 ||
+              x1<=tmpt->t[1]->pt.x<=x2 &&
+              y1<=tmpt->t[1]->pt.y<=y2 ||
+              x1<=tmpt->t[2]->pt.x<=x2 &&
+              y1<=tmpt->t[2]->pt.y<=y2)
+          tmpt->flags&=~TF_SEL;
+      }
+    }
+    tmpt=tmpt->next;
+  }
+}
+
+I64 MeshSelCnt(CMeshFrame *e)
+{
+  I64 res=0;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  CMeshEdTri *tmpt=e->tri_head.next;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL)
+      res++;
+    tmpv=tmpv->next;
+  }
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags&TF_SEL)
+      res++;
+    tmpt=tmpt->next;
+  }
+  return res;
+}
+
+U0 MeshSwapAxes(CMeshFrame *e,I64 o1,I64 o2)
+{
+  Bool unsel;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshVertexSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL)
+      SwapU32((&tmpv->p)(U8 *)+o1,(&tmpv->p)(U8 *)+o2);
+    tmpv=tmpv->next;
+  }
+  if (unsel)
+    MeshVertexSelAll(e,FALSE);
+}
+
+U0 MeshInvertAxis(CMeshFrame *e,I64 o)
+{
+  Bool unsel;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshVertexSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL)
+      *((&tmpv->p)(U8 *)+o)(I32 *)=-*((&tmpv->p)(U8 *)+o)(I32 *);
+    tmpv=tmpv->next;
+  }
+  if (unsel)
+    MeshVertexSelAll(e,FALSE);
+}
+
+U0 MeshTransformSel(CMeshFrame *e)
+{
+  Bool unsel;
+  I64 r[16],x,y,z;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (PopUpTransform(r)) {
+    if (!MeshSelCnt(e)) {
+      MeshVertexSelAll(e,TRUE);
+      unsel=TRUE;
+    } else
+      unsel=FALSE;
+    while (tmpv!=&e->vertex_head) {
+      if (tmpv->flags&VF_SEL) {
+        x=tmpv->p.x; y=tmpv->p.y; z=tmpv->p.z;
+        Mat4x4MulXYZ(r,&x,&y,&z);
+        tmpv->p.x=x; tmpv->p.y=y; tmpv->p.z=z;
+      }
+      tmpv=tmpv->next;
+    }
+    if (unsel)
+      MeshVertexSelAll(e,FALSE);
+  }
+}
+
+U0 MeshColorTris(CMeshFrame *e)
+{
+  Bool unsel;
+  CMeshEdTri *tmpt=e->tri_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshTriSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags & TF_SEL)
+      tmpt->mt.color=e->cur_color;
+    tmpt=tmpt->next;
+  }
+  if (unsel)
+    MeshTriSelAll(e,FALSE);
+}
+
+U0 MeshRevTris(CMeshFrame *e)
+{
+  Bool unsel;
+  CMeshEdTri *tmpt=e->tri_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshTriSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags & TF_SEL)
+      SwapI64(&tmpt->t[1],&tmpt->t[2]);
+    tmpt=tmpt->next;
+  }
+  if (unsel)
+    MeshTriSelAll(e,FALSE);
+}
+
+U0 MeshRecalcCxCy(CTask *task,CMeshFrame *e)
+{
+  e->cx=RoundI64(task->pix_width/2 -task->horz_scroll.pos,e->cur_snap);
+  e->cy=RoundI64(task->pix_height/2-task->vert_scroll.pos,e->cur_snap);
+}
+
+U0 MeshCurSnap(CMeshFrame *e)
+{
+  I64 x1,y1,z1,x2,y2,z2;
+  if (e->w2s) {
+    x1=e->cur_snap<<16; y1=0; z1=0;
+    Mat4x4MulXYZ(e->w2s,&x1,&y1,&z1);
+    x2=0; y2=e->cur_snap<<16; z2=0;
+    Mat4x4MulXYZ(e->w2s,&x2,&y2,&z2);
+    ms_grid.x=Max(1,MaxI64(x1,x2)>>16);
+    ms_grid.y=Max(1,MaxI64(y1,y2)>>16);
+    ms_grid.z=Min(ms_grid.x,ms_grid.y);
+  }
+}
+
+U0 MeshScaleZoom(CMeshFrame *e,F64 scale)
+{
+  CTask *task=Fs;
+  I64   x=ms.pos.x-task->pix_left-task->scroll_x-task->pix_width/2,
+        y=ms.pos.y-task->pix_top-task->scroll_y-task->pix_height/2;
+  task->horz_scroll.pos*=scale;
+  task->vert_scroll.pos*=scale;
+  task->horz_scroll.pos+=scale*x-x;
+  task->vert_scroll.pos+=scale*y-y;
+  e->view_scale*=scale;
+  MeshRecalcCxCy(task,e);
+  MeshCurSnap(e);
+}
+
+U0 MPDrawIt(CMeshFrame *e)
+{//Multiprocessing draw it, called by each core.
+
+  //Makes a copy of e->dc so we can change dc->color member and stuff.
+  CDC *dc=DCAlias(e->dc,e->dc->win_task);
+
+  CMeshEdTri *tmpt=e->tri_head.next;
+  I64 i,*old_r=dc->r;
+
+  //DCAlias() allocs a new identity rotation matrix.
+  //We want e->dc's rotation matrix.
+  dc->r=e->dc->r;
+  dc->depth_buf=e->depth_buf;
+  MemCpy(&dc->ls,&e->dc->ls,sizeof(CD3I32));
+
+  //... and translation (shift) vals.
+  dc->x=e->dc->x;
+  dc->y=e->dc->y;
+  dc->z=e->dc->z;
+  dc->flags|=DCF_TRANSFORMATION;
+
+  if (e->grid_on)
+//Draw grid with different cores.
+    for (i=-500+25*Gs->num;i<=500;i+=25*mp_cnt) {
+      if (i) {
+        dc->color=DKGRAY;
+        GrLine3(dc,i,-500,0,i,500,0);
+        dc->color=LTGRAY;
+        GrLine3(dc,-500,i,0,500,i,0);
+      }
+    }
+  if (!Gs->num) {
+    dc->color=RED;      //Y-Axis red
+    GrLine3(dc,0,0,0,0,500,0);
+    dc->color=ROPF_DITHER+RED;   //Y-Axis red
+    GrLine3(dc,0,-500,0,0,0,0);
+
+    dc->color=YELLOW;   //X-Axis yellow
+    GrLine3(dc,0,0,0,500,0,0);
+    dc->color=ROPF_DITHER+YELLOW;        //X-Axis yellow
+    GrLine3(dc,-500,0,0,0,0,0);
+
+    dc->color=GREEN;    //Z-Axis green
+    GrLine3(dc,0,0,0,0,0,500);
+    dc->color=ROPF_DITHER+GREEN;         //Z-Axis green
+    GrLine3(dc,0,0,-500,0,0,0);
+  }
+
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->cpu_num==Gs->num) {
+      if (tmpt->flags & TF_SEL) {
+        if (Blink)
+          dc->color=ROPF_DITHER+WHITE<<16+RED;
+        else
+          dc->color=ROPF_DITHER+RED<<16+WHITE;
+        GrFillTri0(dc,&tmpt->t[0]->pt,&tmpt->t[1]->pt,&tmpt->t[2]->pt);
+      } else {
+        (*dc->lighting)(dc,&tmpt->t[0]->pt,&tmpt->t[1]->pt,
+              &tmpt->t[2]->pt,tmpt->mt.color);
+        GrFillTri0(dc,&tmpt->t[0]->pt,&tmpt->t[1]->pt,&tmpt->t[2]->pt);
+      }
+    }
+    tmpt=tmpt->next;
+  }
+  dc->r=old_r;
+
+  //e->dc's depth buf was copied but we don't want it freed during DCDel().
+  dc->depth_buf=NULL;
+
+  DCDel(dc);
+  LBtr(&e->mp_not_done_flags,Gs->num);
+}
+
+I64 *MeshW2S(CMeshFrame *e,CTask *task)
+{//World to scrn coordinate transform matrix.
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s=c->state;
+  I64 *r=Mat4x4IdentNew(task);
+  Mat4x4Scale(r,e->view_scale);
+  Mat4x4RotZ(r,s->az);
+  Mat4x4RotY(r,s->ay);
+  if (e->flip_y)
+    Mat4x4RotX(r,s->ax);
+  else
+    Mat4x4RotX(r,s->ax+pi);
+  return r;
+}
+
+I64 *MeshS2W(CMeshFrame *e,CTask *task)
+{//Scrn to world coordinate transform matrix.
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s=c->state;
+  I64 *r=Mat4x4IdentNew(task);
+  if (e->flip_y)
+    Mat4x4RotX(r,-s->ax);
+  else
+    Mat4x4RotX(r,-(s->ax+pi));
+  Mat4x4RotY(r,-s->ay);
+  Mat4x4RotZ(r,-s->az);
+  Mat4x4Scale(r,1/e->view_scale);
+  return r;
+}
+
+I64 *MeshSetW2S(CMeshFrame *e,CTask *task)
+{
+  Free(e->w2s);
+  e->w2s=MeshW2S(e,task);
+  Free(e->s2w);
+  e->s2w=MeshS2W(e,task);
+//returned matrix is assigned to dc->r and will be freed by DCDel().
+  return Mat4x4New(e->w2s,task);
+}
+
+U0 MeshCursorW(CMeshFrame *e,CTask *task,I64 *_x,I64 *_y,I64 *_z)
+{
+  I64   x_shadow,y_shadow,z_shadow,
+        xc=ms.pos.x-task->pix_left-task->scroll_x-e->cx,
+        yc=ms.pos.y-task->pix_top-task->scroll_y-e->cy,zc=0,
+        x=0,y=0,z=e->ms_z,
+        i,x2,y2,z2;
+  Mat4x4MulXYZ(e->w2s,&x,&y,&z); //scrn of Z vect
+
+  //Converges onto a solution for zc, an unknown.
+  for (i=0;i<128;i++) {
+    x_shadow=xc-x; //Shadow of mouse cursor on xy plane
+    y_shadow=yc-y;
+    z_shadow=zc-z;
+    Mat4x4MulXYZ(e->s2w,&x_shadow,&y_shadow,&z_shadow);
+    x2=0; y2=0; z2=-z_shadow;
+    Mat4x4MulXYZ(e->w2s,&x2,&y2,&z2);
+    zc+=Round(Sqrt(x2*x2+y2*y2+z2*z2))*SignI64(z2);
+  }
+
+  x=xc-x;
+  y=yc-y;
+  z=zc-z;
+  Mat4x4MulXYZ(e->s2w,&x,&y,&z);
+  x=RoundI64(x,e->cur_snap);
+  y=RoundI64(y,e->cur_snap);
+  z=RoundI64(e->ms_z,e->cur_snap);
+  *_x=x; *_y=y; *_z=z;
+}
+
+CMeshEdVertex   sys_clip_vertex_head;
+CMeshEdTri      sys_clip_tri_head;
+
+U0 MeshClipInit()
+{
+  QueInit(&sys_clip_vertex_head);
+  QueInit(&sys_clip_tri_head);
+}
+
+U0 MeshClipRst()
+{
+  QueDel(&sys_clip_vertex_head,TRUE);
+  QueDel(&sys_clip_tri_head,TRUE);
+  MeshClipInit;
+}
+
+U0 MeshClipCopy(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next,*tmpv2;
+  CMeshEdTri    *tmpt=e->tri_head.next,*tmpt2;
+
+  MeshClipRst;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL) {
+      tmpv->copy=tmpv2=ACAlloc(sizeof(CMeshEdVertex));
+      MemCpy(&tmpv2->p,&tmpv->p,sizeof(CD3I32));
+      QueIns(tmpv2,sys_clip_vertex_head.last);
+      tmpv->flags|=VF_COPIED;
+      tmpv->flags&=~VF_SEL;
+    } else {
+      tmpv->copy=NULL;
+      tmpv->flags&=~(VF_COPIED|VF_SEL);
+    }
+    tmpv=tmpv->next;
+  }
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags&TF_SEL &&
+          tmpt->t[0]->copy && tmpt->t[1]->copy && tmpt->t[2]->copy) {
+      tmpt2=ACAlloc(sizeof(CMeshEdTri));
+      tmpt2->t[0]=tmpt->t[0]->copy;
+      tmpt2->t[1]=tmpt->t[1]->copy;
+      tmpt2->t[2]=tmpt->t[2]->copy;
+      tmpt2->mt.color=tmpt->mt.color;
+      QueIns(tmpt2,sys_clip_tri_head.last);
+      tmpt->flags|=TF_COPIED;
+      tmpt->flags&=~TF_SEL;
+    } else
+      tmpt->flags&=~(TF_COPIED|TF_SEL);
+    tmpt=tmpt->next;
+  }
+}
+
+U0 MeshClipCut(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next,*tmpv1;
+  CMeshEdTri    *tmpt=e->tri_head.next,*tmpt1;
+  MeshClipCopy(e);
+  while (tmpt!=&e->tri_head) {
+    tmpt1=tmpt->next;
+    if (tmpt->flags&TF_COPIED)
+      MeshTriDel(e,tmpt);
+    tmpt=tmpt1;
+  }
+  while (tmpv!=&e->vertex_head) {
+    tmpv1=tmpv->next;
+    if (tmpv->flags&VF_COPIED)
+      MeshVertexDel(e,tmpv);
+    tmpv=tmpv1;
+  }
+}
+
+U0 MeshClipDel(CMeshFrame *e)
+{//Technically not clip
+  CMeshEdVertex *tmpv=e->vertex_head.next,*tmpv1;
+  CMeshEdTri    *tmpt=e->tri_head.next,*tmpt1;
+  while (tmpt!=&e->tri_head) {
+    tmpt1=tmpt->next;
+    if (tmpt->flags&TF_SEL)
+      MeshTriDel(e,tmpt);
+    tmpt=tmpt1;
+  }
+  while (tmpv!=&e->vertex_head) {
+    tmpv1=tmpv->next;
+    if (tmpv->flags&VF_SEL)
+      MeshVertexDel(e,tmpv);
+    tmpv=tmpv1;
+  }
+}
+
+U0 MeshClipPaste(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv2=sys_clip_vertex_head.next,*tmpv;
+  CMeshEdTri    *tmpt2=sys_clip_tri_head.next,*tmpt;
+
+  MeshVertexSelAll(e,FALSE);
+  MeshTriSelAll(e,FALSE);
+  while (tmpv2!=&sys_clip_vertex_head) {
+    tmpv2->copy=tmpv=CAlloc(sizeof(CMeshEdVertex));
+    MemCpy(&tmpv->p,&tmpv2->p,sizeof(CD3I32));
+    QueIns(tmpv,e->vertex_head.last);
+    tmpv->flags|=VF_SEL;
+    tmpv2=tmpv2->next;
+  }
+
+  while (tmpt2!=&sys_clip_tri_head) {
+    tmpt=MeshTriNew(e,tmpt2->mt.color,tmpt2->t[0]->copy,
+          tmpt2->t[1]->copy,tmpt2->t[2]->copy);
+    tmpt->flags|=TF_SEL;
+    tmpt2=tmpt2->next;
+  }
+}
+
+MeshClipInit;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CMeshFrame *e=FramePtr("CMeshFrame",task);
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  F64 d;
+  I64 i,x,y,z;
+  CMeshEdVertex *tmpv;
+
+  task->horz_scroll.min=-(MESH_WORKSPACE_SIZE-task->pix_width)/2;
+  task->horz_scroll.max= (MESH_WORKSPACE_SIZE-task->pix_width)/2;
+  task->vert_scroll.min=-(MESH_WORKSPACE_SIZE-task->pix_height)/2;
+  task->vert_scroll.max= (MESH_WORKSPACE_SIZE-task->pix_height)/2;
+  TaskDerivedValsUpdate(task);
+  MeshRecalcCxCy(task,e);
+
+  dc->flags|=DCF_TRANSFORMATION;
+
+  Free(dc->r); //Set rotmat doesn't free old dc->r matrix.
+  DCMat4x4Set(dc,MeshSetW2S(e,task));
+
+  dc->x=e->cx;
+  dc->y=e->cy;
+//z-vals less than zero are in front of scrn and not drawn.
+  //we want to shift all Z-vals into a drawable range.
+  //GR_Z_ALL is set to half of the Z-range which is an I32.
+  dc->z=GR_Z_ALL;
+
+  //Light source set to mouse.
+  MeshCursorW(e,task,&x,&y,&z);
+  dc->ls.x=x;
+  dc->ls.y=y;
+  dc->ls.z=z;
+  d=1<<16/D3I32Norm(&dc->ls); //Light source normalized to 65536.
+  dc->ls.x*=d;
+  dc->ls.y*=d;
+  dc->ls.z*=d;
+
+  DCDepthBufAlloc(dc);
+
+  tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    x=tmpv->p.x; y=tmpv->p.y; z=tmpv->p.z;
+    (*dc->transform)(dc,&x,&y,&z);
+    tmpv->pt.x=x; tmpv->pt.y=y; tmpv->pt.z=z;
+    tmpv=tmpv->next;
+  }
+
+  e->mp_not_done_flags=1<<mp_cnt-1; //Issue jobs to all cores.
+  e->dc=dc;
+  e->depth_buf=dc->depth_buf;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPDrawIt,e,i);
+
+  tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    x=tmpv->pt.x; y=tmpv->pt.y; z=tmpv->pt.z;
+    if (e->vertex_on) {
+      if (Blink(10)) //This blinks at 10 Hz.
+        dc->color=ROPF_DITHER+BLACK<<16+WHITE;
+      else
+        dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+      GrLine(dc,x-3,y-3,x+3,y+3);
+      GrLine(dc,x-3,y+3,x+3,y-3);
+    }
+    if (tmpv->flags&VF_SEL) {
+      if (e->ed_mode=='t') {
+        if (Blink(10)) //This blinks at 10 Hz.
+          dc->color=ROPF_DITHER+e->cur_color.c0.color<<16+
+                e->cur_color.c0.color^8;
+        else
+          dc->color=ROPF_DITHER+(e->cur_color.c0.color^8)<<16+
+                e->cur_color.c0.color;
+      } else {
+        if (Blink)
+          dc->color=ROPF_DITHER+RED<<16+WHITE;
+        else
+          dc->color=ROPF_DITHER+WHITE<<16+RED;
+      }
+      GrCircle(dc,x,y,3);
+    }
+    tmpv=tmpv->next;
+  }
+
+  if (CtrlInside(c,ms.presnap.x,ms.presnap.y)||winmgr.show_menu) {
+    GridInit;
+    task->win_inhibit=WIF_SELF_DOC;
+  } else {
+    MeshCurSnap(e);
+    task->win_inhibit=WIG_TASK_DFT|WIF_SELF_DOC-WIF_SELF_FOCUS-WIF_SELF_BORDER
+          -WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU-WIF_SELF_GRAB_SCROLL;
+  }
+
+  MeshCursorW(e,task,&x,&y,&z);
+  if (z<0)
+    dc->color=ROP_XOR+RED^TRANSPARENT;
+  else
+    dc->color=ROP_XOR+TRANSPARENT;
+  GrPrint(dc,0,0,"%6.3f%% (%d,%d,%d)",e->view_scale*100,x,y,z);
+  dc->thick=1;
+  dc->color&=0xF;
+  if (Blink(10))
+    dc->color^=0xF;
+  GrLine3(dc,x,y,z,x,y,0);
+
+  if (e->sel_rect) {
+    dc->flags&=~DCF_TRANSFORMATION;
+    dc->thick=1;
+    if (Blink)
+      dc->color=ROPF_DITHER+RED<<16+WHITE;
+    else
+      dc->color=ROPF_DITHER+WHITE<<16+RED;
+    GrBorder(dc,e->x1,e->y1,e->x2,e->y2);
+  }
+//Wait for all cores to complete.
+  while (e->mp_not_done_flags)
+    Yield;
+}
+
+U0 MeshInit(CMeshFrame *e,Bool flip_y)
+{
+  MemSet(e,0,sizeof(CMeshFrame));
+  QueInit(&e->vertex_head);
+  QueInit(&e->tri_head);
+  e->ed_mode='v';
+  e->grid_on=TRUE;
+  e->vertex_on=TRUE;
+  e->ms_z=0;
+  e->thickness=25;
+  e->closed=TRUE;
+  e->view_scale=1.0;
+  e->w2s=NULL;
+  e->s2w=NULL;
+  e->cur_color=RED;
+  e->cur_snap=5;
+  e->flip_y=flip_y;
+  e->sel_rect=FALSE;
+  e->cur_tri=NULL;
+  e->cur_vertex=NULL;
+  e->chain_pred=NULL;
+}
+
+U0 MeshLoad(CMeshFrame *e,U8 *src)
+{
+  I64 i,j,x,y,z;
+  CColorROPU32 color;
+  CMeshEdVertex *tmpv,*va[3];
+
+  QueInit(&e->vertex_head);
+  QueInit(&e->tri_head);
+
+  e->vertex_cnt  =*src(I32 *)++;
+  e->tri_cnt=*src(I32 *)++;
+  for (i=0;i<e->vertex_cnt;i++) {
+    x=*src(I32 *)++;
+    y=*src(I32 *)++;
+    z=*src(I32 *)++;
+    tmpv=MeshVertexNew(e,x,y,z);
+    tmpv->num=i;
+  }
+  for (i=0;i<e->tri_cnt;i++) {
+    color=*src(I32 *)++;
+    for (j=0;j<3;j++)
+      va[j]=MeshVertexFindNum(e,*src(I32 *)++);
+    MeshTriNew(e,color,va[0],va[1],va[2]);
+  }
+}
+
+I64 MeshSize(CMeshFrame *e)
+{
+  I64 i;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  CMeshEdTri    *tmpt=e->tri_head.next;
+
+  e->vertex_cnt=0;
+  while (tmpv!=&e->vertex_head) {
+    tmpv->num=e->vertex_cnt++;
+    tmpv=tmpv->next;
+  }
+
+  e->tri_cnt=0;
+  while (tmpt!=&e->tri_head) {
+    e->tri_cnt++;
+    for (i=0;i<3;i++)
+      tmpt->mt.nums[i]=tmpt->t[i]->num;
+    tmpt=tmpt->next;
+  }
+  return sizeof(I32)*2+
+        (offset(CMeshEdVertex.end)-offset(CMeshEdVertex.start))*e->vertex_cnt+
+        (offset(CMeshEdTri.end)-offset(CMeshEdTri.start))*e->tri_cnt;
+}
+
+I32 *MeshSave(CMeshFrame *e,I64 *_size=NULL)
+{
+  I64 size=MeshSize(e);
+  U8 *res=MAlloc(size),*dst=res;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  CMeshEdTri    *tmpt=e->tri_head.next;
+
+  *dst(I32 *)++=e->vertex_cnt;
+  *dst(I32 *)++=e->tri_cnt;
+
+  e->vertex_cnt=0;
+  while (tmpv!=&e->vertex_head) {
+    MemCpy(dst,&tmpv->start,offset(CMeshEdVertex.end)
+    -offset(CMeshEdVertex.start));
+    dst+=offset(CMeshEdVertex.end)-offset(CMeshEdVertex.start);
+    tmpv=tmpv->next;
+  }
+
+  e->tri_cnt=0;
+  while (tmpt!=&e->tri_head) {
+    MemCpy(dst,&tmpt->start,offset(CMeshEdTri.end)-offset(CMeshEdTri.start));
+    dst+=offset(CMeshEdTri.end)-offset(CMeshEdTri.start);
+    tmpt=tmpt->next;
+  }
+  if (_size) *_size=size;
+  return res;
+}
+
+U0 MeshCleanUp(CMeshFrame *e)
+{
+  QueDel(&e->vertex_head,TRUE);
+  QueDel(&e->tri_head,TRUE);
+  Free(e->w2s);
+  Free(e->s2w);
+}
+
+U0 MeshUpdateMenu(CMeshFrame *e)
+{
+  CMenuEntry *tmpse;
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Grid"))
+    tmpse->checked=ToBool(e->grid_on);
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Vertex"))
+    tmpse->checked=ToBool(e->vertex_on);
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/PlaceVertex"))
+    tmpse->checked=ToBool(e->ed_mode=='v');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/MoveVertex"))
+    tmpse->checked=ToBool(e->ed_mode=='m');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/MoveVertexZ"))
+    tmpse->checked=ToBool(e->ed_mode=='M');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Triangle"))
+    tmpse->checked=ToBool(e->ed_mode=='t');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Polygon"))
+    tmpse->checked=ToBool(e->ed_mode=='n');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Fence"))
+    tmpse->checked=ToBool(e->ed_mode=='f');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Prism"))
+    tmpse->checked=ToBool(e->ed_mode=='p');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/FlipY"))
+    tmpse->checked=ToBool(e->flip_y);
+}
+
+I32 *SpriteMeshEd(I32 *head=NULL,I64 *_size=NULL,Bool flip_y=FALSE)
+{/*Fmt for mesh:
+{
+I32 vertex_cnt;
+I32 tri_cnt;
+CD3I32 vertices[];
+CMeshTri tris[];
+}
+
+If head points to a mesh, it will load it.
+
+Returns a newly malloced mesh or NULL.
+
+See ::/Demo/Graphics/SpritePlot3D.HC.
+*/
+  CCtrl *c=CtrlFindUnique(Fs,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s,*old_s;
+  I64 i,msg_code,sel_mode,arg1,arg2,make_tri_vertex_num=0,x,y,z;
+  CD3I32 p0a,p0b;
+  CMeshEdVertex *va[3],*tmpv;
+  Bool adjusting_z=FALSE,moving,save_and_exit;
+  CMeshFrame e;
+
+  if (c) {
+    old_s=MAlloc(sizeof(CViewAngles));
+    MemCpy(old_s,c->state,sizeof(CViewAngles));
+  } else {
+    c=ViewAnglesNew;
+    old_s=NULL;
+  }
+
+  s=c->state;
+  s->sx=0;
+  s->sy=0;
+  s->sz=0;
+  s->cx=YELLOW;
+  s->cy=RED;
+  s->cz=GREEN;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  Delete(,,SC_DELETE);"
+        "  DelLast(,CH_BACKSPACE);"
+        "  Cut(,CH_CTRLX);"
+        "  Copy(,CH_CTRLC);"
+        "  Paste(,CH_CTRLV);"
+        "  SelectAll(,'A');"
+        "  UnSelectAll(,'U');"
+        "  SelectRect(,'a');"
+        "  UnSelectRect(,'u');"
+        "  OrSelectRect(,'o');"
+        "  JumpToZ(,'j');"
+        "  ResetColor(,'C');"
+        "  ReverseTri(,'r');"
+        "}"
+        "Mode {"
+        "  PlaceVertex(,'v');"
+        "  MoveVertex(,'m');"
+        "  MoveVertexZ(,'M');"
+        "  Triangle(,'t');"
+        "  Polygon(,'n');"
+        "  Fence(,'f');"
+        "  Prism(,'p');"
+        "}"
+        "Settings {"
+        "  Color(,'c');"
+        "  Snap(,'s');"
+        "}"
+        "View {"
+        "  ZoomIn(,'z');"
+        "  ZoomOut(,'Z');"
+        "  NullAngles(,'N');"
+        "  FlipY(,'y');"
+        "  Grid(,'g');"
+        "  Vertex(,'V');"
+        "  ToggleBorder(,CH_CTRLB);"
+        "}"
+        "Transforms {"
+        "  Transform(,'T');"
+        "  SwapXY(,'1');"
+        "  SwapXZ(,'2');"
+        "  SwapYZ(,'3');"
+        "  InvertX(,'4');"
+        "  InvertY(,'5');"
+        "  InvertZ(,'6');"
+        "  ReverseTri(,'R');"
+        "}");
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  RegOneTimePopUp(ARf_MESH_ED,
+        "$GREEN$Right Mouse$FG$: Hold and move to shift cursor z\n"
+        "$GREEN$'j'$FG$: Jump cursor Z to nearest vertex's Z\n"
+        "$GREEN$'v'$FG$: Place Vertex Mode\n"
+        "$GREEN$'m'$FG$: Move Vertex Mode\n"
+        "$GREEN$'M'$FG$: Move Vertex Z\n"
+        "$GREEN$'t'$FG$: Form Triangle Mode\n"
+        "$GREEN$'n'$FG$: Polygon Mode\n"
+        "$GREEN$'f'$FG$: Fence Mode\n"
+        "$GREEN$'p'$FG$: Prism Mode\n"
+        "$GREEN$'c'$FG$: Set color\n"
+        "$GREEN$'s'$FG$: Set snap\n"
+        "\nSee menu at top of scrn for more.\n");
+
+  Fs->win_inhibit=WIG_TASK_DFT|WIF_SELF_DOC-WIF_SELF_FOCUS-WIF_SELF_BORDER
+        -WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU-WIF_SELF_GRAB_SCROLL;
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+  MeshInit(&e,flip_y);
+  if (head)
+    MeshLoad(&e,head);
+  FramePtrAdd("CMeshFrame",&e);
+  Fs->draw_it=&DrawIt;
+  MeshCurSnap(&e);
+  MeshRecalcCxCy(Fs,&e);
+
+  try {//In case of <CTRL-ALT-c>
+    while (TRUE) {
+      MeshUpdateMenu(&e);
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|
+            1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP);
+me_restart:
+      switch (msg_code) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case 0:
+              switch (arg2.u8[0]) {
+                case SC_DELETE:
+                  if (arg2&SCF_SHIFT)
+                    goto me_clip_cut;
+                  else {
+                    if (MeshSelCnt(&e))
+                      MeshClipDel(&e);
+                    else if (e.ed_mode!='t')
+                      MeshVertexDel(&e,MeshVertexFindScrPt(&e,
+                            ms.presnap.x-Fs->pix_left-Fs->scroll_x,
+                            ms.presnap.y-Fs->pix_top-Fs->scroll_y));
+                    MeshVertexSelAll(&e,FALSE);
+                    MeshTriSelAll(&e,FALSE);
+                    make_tri_vertex_num=0;
+                  }
+                  break;
+                case SC_INS:
+                  if (arg2&SCF_CTRL)
+                    goto me_clip_copy;
+                  else if (arg2&SCF_SHIFT)
+                    goto me_clip_paste;
+              }
+              break;
+            case CH_BACKSPACE:
+              switch (e.ed_mode) {
+                case 'n':
+                case 'f':
+                case 'p':
+                case 'v':
+                  MeshVertexDel(&e,e.cur_vertex);
+                  break;
+                case 't':
+                  if (make_tri_vertex_num) {
+                    MeshVertexSelAll(&e,FALSE);
+                    MeshTriSelAll(&e,FALSE);
+                    make_tri_vertex_num=0;
+                  } else
+                    MeshTriDel(&e,e.cur_tri);
+                  break;
+              }
+              break;
+            case 'f':
+            case 'p':
+              e.thickness=PopUpGetI64("Thickness (%d):",e.thickness);
+            case 'n':
+              if (arg1=='n' || arg1=='p')
+                e.closed=TRUE;
+              else
+                e.closed=PopUpNoYes("Closed?\n");
+me_chain:
+              e.chain_pred=e.vertex_head.last;
+            case 't':
+              MeshVertexSelAll(&e,FALSE);
+              MeshTriSelAll(&e,FALSE);
+            case 'v':
+            case 'm':
+            case 'M':
+              adjusting_z=FALSE;
+              moving=FALSE;
+              e.ed_mode=arg1;
+              make_tri_vertex_num=0;
+              Snd;
+              break;
+            case 'T':
+              MeshTransformSel(&e);
+              break;
+            case 'A':
+              MeshTriSelAll(&e,TRUE);
+              if (e.ed_mode!='t')
+                MeshVertexSelAll(&e,TRUE);
+              else
+                MeshVertexSelAll(&e,FALSE);
+              make_tri_vertex_num=0;
+              break;
+            case 'U':
+              MeshTriSelAll(&e,FALSE);
+              MeshVertexSelAll(&e,FALSE);
+              make_tri_vertex_num=0;
+              break;
+            case 'a':
+            case 'u':
+            case 'o':
+              if (arg1=='a')
+                sel_mode=SEL_MESH_EQU;
+              else if (arg1=='u')
+                sel_mode=SEL_MESH_AND;
+              else
+                sel_mode=SEL_MESH_OR;
+              if ((msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|
+                    1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP))
+                    !=MSG_MS_L_DOWN) {
+                Beep; Beep;
+                goto me_restart;
+              }
+              e.x1=arg1; e.y1=arg2;
+              e.x2=arg1; e.y2=arg2;
+              e.sel_rect=TRUE;
+              while (TRUE) {
+                msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN|
+                      1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|
+                      1<<MSG_MS_R_UP);
+                if (msg_code==MSG_MS_MOVE) {
+                  e.x2=arg1; e.y2=arg2;
+                } else if (msg_code==MSG_MS_L_UP) {
+                  e.x2=arg1; e.y2=arg2;
+                  break;
+                } else {
+                  e.sel_rect=FALSE;
+                  Beep; Beep;
+                  goto me_restart;
+                }
+              }
+              e.sel_rect=FALSE;
+              MeshTriSelRect(&e,sel_mode,e.x1,e.x2,e.y1,e.y2);
+              if (e.ed_mode!='t')
+                MeshVertexSelRect(&e,sel_mode,e.x1,e.x2,e.y1,e.y2);
+              else
+                MeshVertexSelAll(&e,FALSE);
+              make_tri_vertex_num=0;
+              break;
+            case CH_CTRLB:
+              WinBorder(Bt(&Fs->display_flags,DISPLAYf_NO_BORDER));
+              break;
+            case CH_CTRLC:
+me_clip_copy:
+              if (e.ed_mode=='t') {
+                Beep;Beep;
+              } else
+                MeshClipCopy(&e);
+              break;
+            case CH_CTRLV:
+me_clip_paste:
+              if (e.ed_mode=='t') {
+                Beep;Beep;
+              } else {
+                MeshClipPaste(&e);
+                e.ed_mode='m';
+              }
+              break;
+            case CH_CTRLX:
+me_clip_cut:
+              if (e.ed_mode=='t') {
+                Beep;Beep;
+              } else
+                MeshClipCut(&e);
+              break;
+            case CH_SHIFT_ESC:
+              save_and_exit=FALSE;
+              goto me_done;
+            case CH_ESC:
+              save_and_exit=TRUE;
+              goto me_done;
+            case 'z':
+              MeshScaleZoom(&e,1.5);
+              break;
+            case 'Z':
+              MeshScaleZoom(&e,1/1.5);
+              break;
+            case 'c':
+              e.cur_color=PopUpColorLighting;
+              break;
+            case 's':
+              i=PopUpRangeI64(1,25,1,"New Snap\n");
+              if (i>=1)
+                e.cur_snap=i;
+              MeshCurSnap(&e);
+              MeshRecalcCxCy(Fs,&e);
+              break;
+            case 'g':
+              e.grid_on=!e.grid_on;
+              break;
+            case 'V':
+              e.vertex_on=!e.vertex_on;
+              break;
+            case 'N':
+              s->sx=s->sy=s->sz=0;
+              break;
+            case 'y':
+              e.flip_y=!e.flip_y;
+              break;
+            case 'j':
+              if (moving)
+                MeshVertexIgnoreSet(&e,TRUE);
+              if (tmpv=MeshVertexFindScrPt(&e,
+                    ms.pos.x-Fs->pix_left-Fs->scroll_x,
+                    ms.pos.y-Fs->pix_top-Fs->scroll_y)) {
+                Noise(25,86,110);
+                e.ms_z=RoundI64(tmpv->p.z,e.cur_snap);
+              } else {
+                Beep; Beep;
+                e.ms_z=0;
+              }
+              MeshVertexIgnoreSet(&e,FALSE);
+              if (moving) {
+                MeshCursorW(&e,Fs,&x,&y,&z);
+                if (adjusting_z)
+                  MeshP0Offset(&e,0,0,z-p0a.z);
+                else
+                  MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+                p0a.x=x;
+                p0a.y=y;
+                p0a.z=z;
+                MeshP0Capture(&e);
+              }
+              break;
+            case '1':
+              MeshSwapAxes(&e,offset(CD3I32.x),offset(CD3I32.y));
+              break;
+            case '2':
+              MeshSwapAxes(&e,offset(CD3I32.x),offset(CD3I32.z));
+              break;
+            case '3':
+              MeshSwapAxes(&e,offset(CD3I32.y),offset(CD3I32.z));
+              break;
+            case '4':
+              MeshInvertAxis(&e,offset(CD3I32.x));
+              break;
+            case '5':
+              MeshInvertAxis(&e,offset(CD3I32.y));
+              break;
+            case '6':
+              MeshInvertAxis(&e,offset(CD3I32.z));
+              break;
+            case 'r':
+              if (e.cur_tri)
+                SwapI64(&e.cur_tri->t[1],&e.cur_tri->t[2]);
+              break;
+            case 'C':
+              MeshColorTris(&e);
+              break;
+            case 'R':
+              MeshRevTris(&e);
+              break;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          switch (e.ed_mode) {
+            case 'm':
+              if (!moving) {
+                if (!MeshSelCnt(&e) &&
+                      (tmpv=MeshVertexFindScrPt(&e,arg1,arg2))) {
+                  tmpv->flags|=VF_SEL;
+                  e.ms_z=RoundI64(tmpv->p.z,e.cur_snap);
+                }
+                if (MeshSelCnt(&e)) {
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  p0a.x=x;
+                  p0a.y=y;
+                  p0a.z=z;
+                  MeshP0Capture(&e);
+                  moving=TRUE;
+                }
+              }
+              break;
+            case 'M':
+              if (!adjusting_z && !moving) {
+                if (!MeshSelCnt(&e) &&
+                      (tmpv=MeshVertexFindScrPt(&e,arg1,arg2))) {
+                  tmpv->flags|=VF_SEL;
+                  e.ms_z=RoundI64(tmpv->p.z,e.cur_snap);
+                }
+                if (MeshSelCnt(&e)) {
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  p0a.x=x;
+                  p0a.y=y;
+                  p0a.z=z;
+                  MeshP0Capture(&e);
+                  moving=TRUE;
+
+                  p0b.x=ms.presnap.x;
+                  p0b.y=ms.presnap.y;
+                  p0b.z=e.ms_z;
+                  adjusting_z=TRUE;
+                  Snd(ClampI64(Freq2Ona(3*e.ms_z+1500),0,I8_MAX));
+                }
+              }
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (e.ed_mode) {
+            case 'n':
+            case 'f':
+            case 'p':
+            case 'v':
+              Noise(25,86,110);
+              MeshCursorW(&e,Fs,&x,&y,&z);
+              e.cur_vertex=MeshVertexNew(&e,x,y,z);
+              break;
+            case 'm':
+            case 'M':
+              if (moving) {
+                if (adjusting_z) {
+                  e.ms_z=RoundI64(Sign(p0b.y-ms.presnap.y)
+                  *Sqrt(Sqr(p0b.x-ms.presnap.x)+Sqr(p0b.y-ms.presnap.y))
+                  +p0b.z,e.cur_snap);
+                  Snd;
+                  adjusting_z=FALSE;
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  MeshP0Offset(&e,0,0,z-p0a.z);
+                } else {
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+                }
+                MeshTriSelAll(&e,FALSE);
+                MeshVertexSelAll(&e,FALSE);
+                moving=FALSE;
+              }
+              break;
+            case 't':
+              if (tmpv=MeshVertexFindScrPt(&e,arg1,arg2)) {
+                for (i=0;i<make_tri_vertex_num;i++)
+                  if (va[i]==tmpv) {
+                    Beep; Beep;
+                    break;
+                  }
+                if (i==make_tri_vertex_num) {
+                  Noise(25,86,110);
+                  va[make_tri_vertex_num++]=tmpv;
+                  tmpv->flags|=VF_SEL;
+                  if (make_tri_vertex_num==3) {
+                    e.cur_tri=MeshTriNew(&e,e.cur_color,va[0],va[1],va[2]);
+                    for (i=0;i<make_tri_vertex_num;i++)
+                      va[i]->flags&=~VF_SEL;
+                    make_tri_vertex_num=0;
+                  }
+                }
+              }
+              break;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+          if (!adjusting_z && e.ed_mode!='M' &&
+                (e.chain_pred==e.vertex_head.last ||
+                e.ed_mode!='n' && e.ed_mode!='f' && e.ed_mode!='p')) {
+            if (moving) {
+              MeshCursorW(&e,Fs,&x,&y,&z);
+              MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+              p0a.x=x;
+              p0a.y=y;
+              p0a.z=z;
+              MeshP0Capture(&e);
+            }
+            p0b.x=ms.presnap.x;
+            p0b.y=ms.presnap.y;
+            p0b.z=e.ms_z;
+            adjusting_z=TRUE;
+            Snd(ClampI64(Freq2Ona(3*e.ms_z+1500),0,I8_MAX));
+          }
+          break;
+        case MSG_MS_R_UP:
+          if (adjusting_z) {
+            e.ms_z=RoundI64(Sign(p0b.y-ms.presnap.y)
+            *Sqrt(Sqr(p0b.x-ms.presnap.x)+Sqr(p0b.y-ms.presnap.y))
+            +p0b.z,e.cur_snap);
+            Snd;
+            adjusting_z=FALSE;
+            if (moving) {
+              MeshCursorW(&e,Fs,&x,&y,&z);
+              MeshP0Offset(&e,0,0,z-p0a.z);
+              p0a.x=x;
+              p0a.y=y;
+              p0a.z=z;
+              MeshP0Capture(&e);
+            }
+          } else  if (e.ed_mode=='n') {
+            if (e.chain_pred && e.chain_pred!=e.vertex_head.last)
+              MeshPolygon(&e,e.chain_pred->next,e.vertex_head.last,FALSE);
+            arg1=e.ed_mode;
+            goto me_chain;
+          } else if (e.ed_mode=='f') {
+            if (e.chain_pred && e.chain_pred!=e.vertex_head.last)
+              MeshFence(&e);
+            arg1=e.ed_mode;
+            goto me_chain;
+          } else if (e.ed_mode=='p') {
+            if (e.chain_pred && e.chain_pred!=e.vertex_head.last)
+              MeshPrism(&e);
+            arg1=e.ed_mode;
+            goto me_chain;
+          }
+          break;
+        case MSG_MS_MOVE:
+          if (adjusting_z) {
+            e.ms_z=RoundI64(Sign(p0b.y-ms.presnap.y)
+            *Sqrt(Sqr(p0b.x-ms.presnap.x)+Sqr(p0b.y-ms.presnap.y))
+            +p0b.z,e.cur_snap);
+            Snd(ClampI64(Freq2Ona(3*e.ms_z+1500),0,I8_MAX));
+          }
+          if (moving) {
+            MeshCursorW(&e,Fs,&x,&y,&z);
+            if (adjusting_z)
+              MeshP0Offset(&e,0,0,z-p0a.z);
+            else
+              MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+            p0a.x=x;
+            p0a.y=y;
+            p0a.z=z;
+            MeshP0Capture(&e);
+          }
+          break;
+      }
+    }
+me_done:
+  } catch
+    Fs->catch_except=TRUE;
+  SettingsPop;
+  MenuPop;
+  if (save_and_exit)
+    head=MeshSave(&e,_size);
+  else
+    head=NULL;
+  MeshCleanUp(&e);
+  FramePtrDel("CMeshFrame");
+  if (old_s) {
+    MemCpy(c->state,old_s,sizeof(CViewAngles));
+    Free(old_s);
+  } else
+    ViewAnglesDel;
+  return head;
+}
+
+ diff --git a/public/Wb/Adam/Gr/SpriteNew.HC.HTML b/public/Wb/Adam/Gr/SpriteNew.HC.HTML new file mode 100755 index 0000000..c75aad5 --- /dev/null +++ b/public/Wb/Adam/Gr/SpriteNew.HC.HTML @@ -0,0 +1,220 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+#help_file "::/Doc/Sprite"
+
+U8 polypt_map[9]={0,1,2,3,0,4,5,6,7};
+
+I64 sprite_elem_base_sizes[SPT_TYPES_NUM]={
+  sizeof(CSpriteBase),          //SPT_END
+  sizeof(CSpriteColor),         //SPT_COLOR
+  sizeof(CSpriteDitherColor),   //SPT_DITHER_COLOR
+  sizeof(CSpriteT),             //SPT_THICK
+  sizeof(CSpritePtPt),          //SPT_PLANAR_SYMMETRY
+  sizeof(CSpriteBase),          //SPT_TRANSFORM_ON
+  sizeof(CSpriteBase),          //SPT_TRANSFORM_OFF
+  sizeof(CSpritePt),            //SPT_SHIFT
+  sizeof(CSpritePt),            //SPT_PT
+  sizeof(CSpriteNumPtU8s),      //SPT_POLYPT
+  sizeof(CSpritePtPt),          //SPT_LINE
+  sizeof(CSpriteNumU8s),        //SPT_POLYLINE
+  sizeof(CSpritePtPt),          //SPT_RECT
+  sizeof(CSpritePtPtAng),       //SPT_ROTATED_RECT
+  sizeof(CSpritePtRad),         //SPT_CIRCLE
+  sizeof(CSpritePtWHAng),       //SPT_ELLIPSE
+  sizeof(CSpritePtWHAngSides),  //SPT_POLYGON
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE2
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE2_CLOSED
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE3
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE3_CLOSED
+  sizeof(CSpritePt),            //SPT_FLOOD_FILL
+  sizeof(CSpritePt),            //SPT_FLOOD_FILL_NOT
+  sizeof(CSpritePtWHU8s),       //SPT_BITMAP
+  sizeof(CSpriteMeshU8s),       //SPT_MESH
+  sizeof(CSpritePtMeshU8s),     //SPT_SHIFTABLE_MESH
+  sizeof(CSpritePtPt),          //SPT_ARROW
+  sizeof(CSpritePtStr),         //SPT_TEXT
+  sizeof(CSpritePtStr),         //SPT_TEXT_BOX
+  sizeof(CSpritePtStr),         //SPT_TEXT_DIAMOND
+};
+
+I64 SpriteElemQuedBaseSize(I64 type)
+{
+  return sprite_elem_base_sizes[type&SPG_TYPE_MASK]+offset(CSprite.start);
+}
+
+I64 SpriteElemSize(CSprite *tmpg)
+{
+  I64 i=sprite_elem_base_sizes[tmpg->type&SPG_TYPE_MASK];
+  switch (tmpg->type&SPG_TYPE_MASK) {
+    case SPT_POLYLINE:
+      i+=tmpg->nu.num*sizeof(CD2I32);
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      i+=StrLen(tmpg->ps.st)+1;
+      break;
+    case SPT_BITMAP:
+      i+=((tmpg->pwhu.width+7)&~7)*tmpg->pwhu.height;
+      break;
+    case SPT_POLYPT:
+      i+=(tmpg->npu.num*3+7)>>3;
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      i+=tmpg->nu.num*sizeof(CD3I32);
+      break;
+    case SPT_MESH:
+      i+=tmpg->mu.vertex_cnt*sizeof(CD3I32)+
+            tmpg->mu.tri_cnt*sizeof(CMeshTri);
+      break;
+    case SPT_SHIFTABLE_MESH:
+      i+=tmpg->pmu.vertex_cnt*sizeof(CD3I32)+
+            tmpg->pmu.tri_cnt*sizeof(CMeshTri);
+      break;
+  }
+  return i;
+}
+
+public I64 SpriteSize(U8 *elems)
+{//Walk sprite elements and return size of sprite as binary data.
+  CSprite *tmpg=elems-offset(CSprite.start),*tmpg1=tmpg;
+  while (tmpg->type&SPG_TYPE_MASK)
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  return tmpg(U8 *)-tmpg1(U8 *)+sprite_elem_base_sizes[SPT_END];
+}
+
+I64 SpriteTypeMask(U8 *elems)
+{
+  I64 res=0;
+  CSprite *tmpg=elems-offset(CSprite.start);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    if (tmpg->type&SPG_TYPE_MASK>=SPT_TYPES_NUM)
+      return 1<<SPT_TYPES_NUM;
+    Bts(&res,tmpg->type&SPG_TYPE_MASK);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+  return res;
+}
+
+U0 SpriteSelAll(U8 *elems,Bool val)
+{
+  CSprite *tmpg=elems-offset(CSprite.start);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    BEqu(&tmpg->type,SPf_SEL,val);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+}
+
+public U8 *DC2Sprite(CDC *tmpb)
+{//Convert device context to sprite.
+  CSprite *tmpg;
+  tmpg=CAlloc(sprite_elem_base_sizes[SPT_BITMAP]+
+        tmpb->width_internal*tmpb->height+
+        sprite_elem_base_sizes[SPT_END])
+  (U8 *)-offset(CSprite.start);
+  tmpg->type=SPT_BITMAP;
+  tmpg->pwhu.width=tmpb->width;
+  tmpg->pwhu.height=tmpb->height;
+  tmpg->pwhu.x1=0;
+  tmpg->pwhu.y1=0;
+  MemCpy(&tmpg->pwhu.u,tmpb->body,tmpb->width_internal*tmpb->height);
+  return tmpg(U8 *)+offset(CSprite.start);
+}
+
+public U8 *SpriteElem2Summary(CSprite *tmpg)
+{//Study ::/Demo/Graphics/SpriteText.HC.
+  U8 buf[STR_LEN],buf2[STR_LEN];
+  I32 *ptr;
+  StrPrint(buf,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_TYPES");
+  switch (tmpg->type&SPG_TYPE_MASK) {
+    case SPT_COLOR:
+      CatPrint(buf," %s",Color2Str(buf2,tmpg->c.color));
+      break;
+    case SPT_DITHER_COLOR:
+      CatPrint(buf," %s",Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
+            tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
+      break;
+    case SPT_PT:
+    case SPT_FLOOD_FILL:
+    case SPT_FLOOD_FILL_NOT:
+    case SPT_SHIFT:
+      CatPrint(buf," (%d,%d)",tmpg->p.x1,tmpg->p.y1);
+      break;
+    case SPT_LINE:
+    case SPT_ARROW:
+    case SPT_PLANAR_SYMMETRY:
+    case SPT_RECT:
+    case SPT_ROTATED_RECT:
+      CatPrint(buf," (%d,%d),(%d,%d)",tmpg->pp.x1,tmpg->pp.y1,
+            tmpg->pp.x2,tmpg->pp.y2);
+      break;
+    case SPT_CIRCLE:
+      CatPrint(buf," (%d,%d):%dR",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
+      break;
+    case SPT_THICK:
+      CatPrint(buf," %d",tmpg->t.thick);
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      CatPrint(buf," %d,%d:%-16t$Q",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
+      break;
+    case SPT_POLYLINE:
+    case SPT_POLYPT:
+      ptr=&tmpg->npu.x;
+      CatPrint(buf," %d (%d,%d)",tmpg->npu.num,ptr[0],ptr[1]);
+      break;
+    case SPT_ELLIPSE:
+    case SPT_POLYGON:
+    case SPT_BITMAP:
+      CatPrint(buf," (%d,%d):%dW,%dH",tmpg->pwhu.x1,tmpg->pwhu.y1,
+            tmpg->pwhu.width,tmpg->pwhu.height);
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      CatPrint(buf," %d",tmpg->nu.num);
+      break;
+    case SPT_MESH:
+      CatPrint(buf," %dV,%dT",tmpg->mu.vertex_cnt,tmpg->mu.tri_cnt);
+      break;
+    case SPT_SHIFTABLE_MESH:
+      CatPrint(buf," %dV,%dT",tmpg->pmu.vertex_cnt,tmpg->pmu.tri_cnt);
+      break;
+  }
+  return StrNew(buf);
+}
+
+ diff --git a/public/Wb/Adam/Gr/SpriteSideBar.HC.HTML b/public/Wb/Adam/Gr/SpriteSideBar.HC.HTML new file mode 100755 index 0000000..e2b8da3 --- /dev/null +++ b/public/Wb/Adam/Gr/SpriteSideBar.HC.HTML @@ -0,0 +1,126 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+CSprite *SpriteSideBar2SpriteQue(CDoc *doc,CSprite *head,I64 *_cur_elem_num)
+{//For the side-bar
+  CSprite *res=CAlloc(sizeof(CSprite)),*tmpg;
+  CDocEntry *doc_e=doc->head.next;
+  Bool found=FALSE;
+  I64 num=0;
+  QueInit(res);
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_MENU_VAL && doc_e->left_exp>=0) {
+      tmpg=SpriteSetSettings(,head,doc_e->left_exp);
+      if (tmpg!=head) {
+        tmpg=MAllocIdent(tmpg);
+        BEqu(&tmpg->type,SPf_SEL,Bt(&doc_e->type,DOCEt_SEL));
+        if (*_cur_elem_num==doc_e->left_exp) {
+          *_cur_elem_num=num;
+          found=TRUE;
+        }
+        QueIns(tmpg,res->last);
+        num++;
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  if (!found)
+    *_cur_elem_num=num;
+  QueDel(head);
+  Free(head);
+  return res;
+}
+
+U0 SpriteSideBarPickNew(CDoc *doc,CSprite *head,I64 old_num)
+{
+  CSprite *tmpg;
+  CDocEntry *doc_cur_e=NULL,*doc_e;
+  I64 cur_elem_num=0;
+  U8 *st;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite SideBar\"$\n"
+        "$LK+PU+CX,\"Click for Help\","
+        "A=\"FI:::/Doc/SpriteSideBar.DD.Z\"$\n\n");
+  tmpg=head->next;
+  while (tmpg!=head) {
+    st=SpriteElem2Summary(tmpg);
+    if (cur_elem_num==old_num)
+      doc_cur_e=doc_e=
+            DocPrint(doc,"$LTRED$$MU-UL,\"%$Q\",LE=%d$\n",st,cur_elem_num++);
+    else
+      doc_e=DocPrint(doc,"$LTBLUE$$MU-UL,\"%$Q\",LE=%d$\n",st,cur_elem_num++);
+    BEqu(&doc_e->de_flags,DOCEf_SEL,Bt(&tmpg->type,&SPf_SEL));
+    BEqu(&doc_e->type,DOCEt_SEL,Bt(&tmpg->type,SPf_SEL));
+    Free(st);
+    tmpg=tmpg->next;
+  }
+  if (cur_elem_num==old_num)
+    doc_cur_e=DocPrint(doc,"$LTRED$$MU-UL,\"END\",LE=%d$\n",cur_elem_num);
+  else
+    DocPrint(doc,"$LTBLUE$$MU-UL,\"END\",LE=%d$\n",cur_elem_num);
+  if (doc_cur_e)
+    doc->cur_entry=doc_cur_e;
+}
+
+U0 SpriteSideBarTask2(CTask *grand_parent)
+{
+  I64 w,h;
+  CTask *parent=Fs->parent_task,*pu_task;
+  while (TRUE) {
+    pu_task=grand_parent->popup_task;
+    if (TaskValidate(pu_task)) {
+      w=parent->win_right-parent->win_left;
+      WinHorz(pu_task->win_right+2,pu_task->win_right+2+w,parent);
+      h=parent->win_bottom-parent->win_top;
+      WinVert(pu_task->win_top,pu_task->win_top+h,parent);
+    }
+    Refresh;
+  }
+}
+
+U0 SpriteSideBarTask(CTask *parent,CSprite **_head,I64 *_cur_elem_num)
+{
+  CDocEntry *doc_e;
+  CDoc *doc=DocPut;
+  Spawn(&SpriteSideBarTask2,parent,"CSpriteTask",,Fs);
+  doc->flags|=DOCF_SIZE_MIN|DOCF_FORM;
+  while (TRUE) {
+    SpriteSideBarPickNew(doc,*_head,*_cur_elem_num);
+    DocHighlightCursor(,doc);
+    View;
+    doc_e=doc->cur_entry;
+    if (doc_e->type_u8==DOCT_MENU_VAL)
+      *_cur_elem_num=doc_e->left_exp;
+    *_head=SpriteSideBar2SpriteQue(doc,*_head,_cur_elem_num);
+    DocClear(doc);
+  }
+}
+
+ diff --git a/public/Wb/Adam/Host.HC.HTML b/public/Wb/Adam/Host.HC.HTML new file mode 100755 index 0000000..f3a7e15 --- /dev/null +++ b/public/Wb/Adam/Host.HC.HTML @@ -0,0 +1,101 @@ + + + + + + + + + + + +
+#help_index "Misc/Host"
+
+public Bool HostChgDsk(U8 *iso_filename)
+{//Help user change CD/DVD or ISO_file.
+  Bool res=FALSE;
+  SettingsPush; //See SettingsPush
+  try {
+    AutoComplete;
+    WinBorder;
+    WinMax;
+    DocClear;
+    "$PURPLE$$TX+CX,\"Set to %s\"$$FG$\n\n\n\n",iso_filename;
+    switch (ins_reg.host_vm) {
+      case VM_VMWARE:
+        if (IsDotC(iso_filename))
+"
+Click CDROM Icon in bottom-right border of VMware window.
+
+Click \"Settings\".
+
+Set ISO image to \"%s\".
+When browsing, change the file mask from \"*.iso\" to \"All Files\".
+
+",iso_filename;
+          else
+"
+Click CDROM Icon in bottom-right border of VMware window.
+
+Click \"Settings\".
+
+Set ISO image to \"%s\".
+
+",iso_filename;
+        break;
+      case VM_QEMU:
+"
+Change to QEMU monitor using <CTRL-ALT-2>
+
+Get the CDROM designation.
+
+        >info block
+
+Use the designation.
+
+        >eject ide1-cd0
+
+Use the designation.
+
+        >change ide1-cd0 %s
+
+Change back to QEMU using <CTRL-ALT-1>
+
+",iso_filename;
+        break;
+      default:
+"
+Place the CDDVD %s in the drive.
+
+",iso_filename;
+    }
+    if (PressAKey!=CH_SHIFT_ESC) {
+      ">DskChg('T');\n\n";
+      DskChg('T');
+      res=TRUE;
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/InFile.HC.HTML b/public/Wb/Adam/InFile.HC.HTML new file mode 100755 index 0000000..c27c559 --- /dev/null +++ b/public/Wb/Adam/InFile.HC.HTML @@ -0,0 +1,171 @@ + + + + + + + + + + + +
+#help_index "InFile;Help System/Training"
+#help_file "::/Doc/InFile"
+
+public U0 InGetStr(U8 *st)
+{//Wait for user to type certain str.
+  I64 ch,sc;
+  U8 buf[256],*st2;
+  while (*st) {
+    ch=GetKey(&sc,FALSE);
+    if (sc.u8[0]!=SC_SHIFT &&
+          sc.u8[0]!=SC_ALT &&
+          sc.u8[0]!=SC_CTRL) {
+      if (ch==*st) {
+        '' ch;
+        st++;
+      } else {
+        st2=Char2KeyName(*st);
+        StrPrint(buf,"Press the $GREEN$<%s>$FG$ key.",st2);
+        Free(st2);
+        PopUpOk(buf);
+      }
+    }
+  }
+}
+
+public U0 InPrint(I64 mS=100,U8 *fmt,...)
+{//Print message with delay after each char.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=buf;
+  I64 ch;
+  while (ch=*st++) {
+    '' ch;
+    Sleep(mS);
+  }
+  Free(buf);
+}
+
+public U0 InGetKey(I64 scan_code,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
+{//Wait for user to press certain key.
+  I64 sc,ch;
+  U8 buf[STR_LEN],*st;
+  do {
+    ch=GetKey(&sc);
+    if (sc.u8[0]!=SC_PRTSCRN1 &&
+          !(sc.u8[0]==SC_SHIFT && scan_code&SCF_SHIFT) &&
+          !(sc.u8[0]==SC_CTRL && scan_code&SCF_CTRL) &&
+          !(sc.u8[0]==SC_ALT && scan_code&SCF_ALT) ) {
+      if (sc&sc_mask!=scan_code&sc_mask) {
+        st=ScanCode2KeyName(scan_code);
+        StrPrint(buf,"Press the $GREEN$<%s>$FG$ key",st);
+        Free(st);
+        PopUpOk(buf);
+      }
+    }
+  } while (sc&sc_mask!=scan_code&sc_mask);
+  Msg(MSG_KEY_DOWN,ch,sc);
+}
+
+public I64 InGetChar(...)
+{//Wait for user to press one of set of chars.
+  I64 i,sc,ch;
+  U8 buf[512],*st;
+  while (TRUE) {
+    ch=GetKey(&sc);
+    if (sc.u8[0]!=SC_SHIFT && sc.u8[0]!=SC_ALT && sc.u8[0]!=SC_CTRL) {
+      for (i=0;i<argc;i++)
+        if (ch==argv[i]) {
+          Msg(MSG_KEY_DOWN,ch,sc);
+          return ch;
+        }
+      StrPrint(buf,"Press ");
+      for (i=0;i<argc;i++) {
+        st=Char2KeyName(argv[i]);
+        CatPrint(buf,"$GREEN$<%s>$FG$",st);
+        Free(st);
+        if (argc==i+1)
+          CatPrint(buf,".");
+        else if (argc==i+2)
+          CatPrint(buf," or ");
+        else
+          CatPrint(buf,", ");
+      }
+      PopUpOk(buf);
+    }
+  }
+}
+
+public U0 InUntilKey(I64 scan_code,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
+{//Let user type until he presses certain key.
+  I64 sc,ch;
+  do {
+    ch=GetKey(&sc);
+    Msg(MSG_KEY_DOWN,ch,sc);
+  } while (sc&sc_mask!=scan_code&sc_mask);
+}
+
+public I64 InUntilChar(...)
+{//Let user type until he presses one of set of chars.
+  I64 i,sc,ch;
+  while (TRUE) {
+    ch=GetKey(&sc);
+    Msg(MSG_KEY_DOWN,ch,sc);
+    for (i=0;i<argc;i++)
+      if (ch==argv[i])
+        return ch;
+  }
+}
+
+public Bool InView()
+{//Let user type until <ESC> or <SHIFT-ESC>.
+  Bool res=View;
+  DocBottom;
+  return res;
+}
+
+#help_index "InFile;Help System/Training;Mouse"
+I64 in_plot_l,in_plot_r;
+
+Bool InSetMsPlot(I64 mS,I64 x,I64 y,I64 z)
+{
+  MsSet(x,y,z,in_plot_l,in_plot_r);
+  Sleep(mS);
+  return TRUE;
+}
+
+public U0 InSetMs(I64 mS=7,I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,
+                I64 l=I64_MAX,I64 r=I64_MAX)
+{//Move mouse to spot at certain speed.
+  if (!(0<=x<GR_WIDTH))
+    x=ms.pos.x;
+  if (!(0<=y<GR_HEIGHT))
+    y=ms.pos.y;
+  if (z==I64_MAX)
+    z=ms.pos.z;
+  if (!(FALSE<=l<=TRUE))
+    l=ms.lb;
+  if (!(FALSE<=r<=TRUE))
+    r=ms.rb;
+  in_plot_l=l; in_plot_r=r;
+  Line(mS,ms.pos.x,ms.pos.y,ms.pos.z,x,y,z,&InSetMsPlot);
+}
+
+ diff --git a/public/Wb/Adam/InsReg.HC.HTML b/public/Wb/Adam/InsReg.HC.HTML new file mode 100755 index 0000000..68c6212 --- /dev/null +++ b/public/Wb/Adam/InsReg.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+#help_index "Registry/Install Registration"
+
+public CInsReg ins_reg;
+MemSet(&ins_reg,0,sizeof(CInsReg));
+
+DefineLstLoad("ST_HOST_OSES","Other\0Native\0Linux\0Windows\0");
+DefineLstLoad("ST_HOST_VMS","Other\0Native\0VMware\0QEMU\0VirtualBox\0");
+
+#define RR_UNREGISTER   -1
+#define RR_REGISTER     0
+#define RR_REREGISTER   1
+
+public Bool InsReg(U8 drv_let=0,I64 action=RR_REGISTER)
+{//Register this install in local Registry.HC file.
+  CInsReg r;
+  I64 old_drv_let;
+  Bool res=FALSE;
+
+  if (action==RR_UNREGISTER) {
+    MemSet(&r,0,sizeof(CInsReg));
+    res=TRUE;
+  } else if (action==RR_REREGISTER || !ins_reg.registered) {
+    MemCpy(&r,&ins_reg,sizeof(CInsReg));
+    r.registered=TRUE;
+    if (PopUpForm(&r))
+      res=TRUE;
+  }
+
+  if (res) {
+    old_drv_let=*sys_registry_doc->filename.name;
+    if (drv_let)
+      *sys_registry_doc->filename.name=drv_let;
+    RegWrite("Adam/InsReg",
+        "#help_index \"Registry/Install Registration\"\n"
+        "MemSet(&ins_reg,0,sizeof(CInsReg));\n"
+        "ins_reg.registered=%d;\n"
+        "ins_reg.host_os=%d;\n"
+        "ins_reg.host_vm=%d;\n"
+        "\n#define INS_REG_PERSONAL_INITIALS \"%s\"\n"
+        "StrCpy(ins_reg.initials,\"%s\");\n"
+        "HashPublic(\"INS_REG_PERSONAL_INITIALS\",HTT_DEFINE_STR);\n"
+        "\n#define INS_REG_MACHINE_NUM %d\n"
+        "ins_reg.machine_num=%d;\n"
+        "HashPublic(\"INS_REG_MACHINE_NUM\",HTT_DEFINE_STR);\n"
+        "\n\"InsReg:%%s:%%d\\n\","
+        "INS_REG_PERSONAL_INITIALS,INS_REG_MACHINE_NUM;\n"
+        "\n#help_index \"\"\n"
+        ,r.registered,r.host_os,r.host_vm,
+        r.initials,r.initials,r.machine_num,r.machine_num);
+    *sys_registry_doc->filename.name=old_drv_let;
+    RegExe("Adam/InsReg");
+  }
+  return res;
+}
+
+public Bool InsRereg(U8 drv_let=0)
+{//Reregister this install in local Registry.HC file.
+  return InsReg(drv_let,RR_REREGISTER);
+}
+
+public Bool InsUnreg(U8 drv_let=0)
+{//Unregister this install in local Registry.HC file.
+  return InsReg(drv_let,RR_UNREGISTER);
+}
+
+ diff --git a/public/Wb/Adam/MakeAdam.HC.HTML b/public/Wb/Adam/MakeAdam.HC.HTML new file mode 100755 index 0000000..4f723a5 --- /dev/null +++ b/public/Wb/Adam/MakeAdam.HC.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "AExts"
+#include "AMath"
+#include "Training"
+#include "AMem"
+#include "TaskRep"
+#include "AMathODE"
+#include "Gr/MakeGr"
+#include "ASnd"
+#include "ABlkDev/MakeABlkDev"
+#include "Menu"
+#include "Win"
+#include "WinMgr"
+#include "ADbg"
+#include "::/Adam/God/GodExt"
+#include "DolDoc/MakeDoc"
+LBts(&sys_run_level,RLf_DOC);
+#include "Ctrls/MakeCtrls"
+#include "InFile"
+#include "ARegistry"
+#include "InsReg"
+#include "AutoComplete/MakeAC"
+#include "God/MakeGod"
+#include "AHash"
+#include "TaskSettings"
+#include "CPURep"
+#include "DevInfo"
+#include "ADefine"
+#include "WallPaper"
+#include "AMouse"
+#include "Host"
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/Menu.HC.HTML b/public/Wb/Adam/Menu.HC.HTML new file mode 100755 index 0000000..678b30b --- /dev/null +++ b/public/Wb/Adam/Menu.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+#help_index "Menus"
+#help_file "::/Doc/Menus"
+
+CTask *MenuTask()
+{
+  CTask *res=sys_focus_task;
+  while (res && !res->cur_menu)
+    res=res->parent_task;
+  return res;
+}
+
+CMenuEntry *sys_cur_submenu_entry=NULL;
+
+public CMenuEntry *MenuSubEntryFind(
+        CMenuEntry *haystack_first,U8 *needle_entry_name)
+{//You probably don't need this. Use dir / and MenuEntryFind().
+  while (haystack_first) {
+    if (!StrCmp(haystack_first->name,needle_entry_name))
+      return haystack_first;
+    haystack_first=haystack_first->next;
+  }
+  return NULL;
+}
+
+public CMenuEntry *MenuEntryFind(CMenu *haystack_menu,U8 *needle_full_name)
+{//Find pulldown entry. Fs->cur_menu is probably the menu you want.
+//Just 2 levels -- across top and down are valid, currently.
+  U8 *st,*st2;
+  CMenuEntry *tmpse;
+  if (!haystack_menu || !needle_full_name)
+    return NULL;
+  st=StrNew(needle_full_name);
+  st2=StrNew(needle_full_name);
+  tmpse=(&haystack_menu->sub)(U8 *)-offset(CMenuEntry.sub);
+  while (*st && tmpse) {
+    StrFirstRem(st,"/",st2);
+    tmpse=MenuSubEntryFind(tmpse->sub,st2);
+  }
+  Free(st);
+  Free(st2);
+  return tmpse;
+}
+
+CMenuEntry *MenuNewSub(CCmpCtrl *cc,CTask *task)
+{
+  CMenuEntry *tmpme=NULL,*tmpse;
+  if (cc->token==TK_IDENT) {
+    tmpme=CAlloc(sizeof(CMenuEntry),task);
+    if (StrLen(cc->cur_str)>31)
+      cc->cur_str[31]=0;
+    StrCpy(tmpme->name,cc->cur_str);
+    if (Lex(cc)=='(') {
+      tmpme->msg_code=MSG_KEY_DOWN_UP;
+      if (Lex(cc)!=',' && cc->token!=')')
+        tmpme->msg_code=LexExpressionI64(cc);
+      if (cc->token==',')
+        Lex(cc);
+      if (cc->token!=',' && cc->token!=')')
+        tmpme->arg1=LexExpressionI64(cc);
+      if (cc->token==',')
+        Lex(cc);
+      if (cc->token!=',' && cc->token!=')')
+        tmpme->arg2=LexExpressionI64(cc);
+      if (cc->token!=')')
+        LexExcept(cc,"Missing ')' at ");
+      if (Lex(cc)!=';')
+        LexExcept(cc,"Missing ';' at");
+      Lex(cc); //Skip ;
+    } else if (cc->token=='{') {
+      Lex(cc); //Skip {
+      tmpme->dir=TRUE;
+      tmpse=&tmpme->sub;
+      while (tmpse && cc->token!='}')
+        tmpse=tmpse->next=MenuNewSub(cc,task);
+      if (cc->token!='}')
+        LexExcept(cc,"Missing '}' at ");
+      else
+        Lex(cc); //Skip }
+    } else
+      LexExcept(cc,"Expecting '{' at ");
+  }
+  return tmpme;
+}
+
+public CMenu *MenuNew(U8 *st,I64 flags=0,CTask *task=NULL)
+{//Parse a menu. You probably don't need this.
+  CMenu *m;
+  CMenuEntry *tmpse;
+  CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
+  if (!task) task=Fs;
+  Lex(cc);
+  m=CAlloc(sizeof(CMenu),task);
+  m->task=task;
+  m->flags=flags;
+  m->attr =BLUE<<4+YELLOW;
+  tmpse=&m->sub;
+  while (tmpse)
+    tmpse=tmpse->next=MenuNewSub(cc,task);
+  CmpCtrlDel(cc);
+  return m;
+}
+
+public CMenu *MenuFile(U8 *filename,I64 flags=0,CTask *task=NULL)
+{//Parse a pulldown menu file. You probably don't need this.
+  CMenu *m;
+  U8 *st=MStrPrint("#include \"%s\"",filename);
+  m=MenuNew(st,flags,task);
+  Free(st);
+  return m;
+}
+
+U0 MenuDelSub(CMenuEntry *tmpme)
+{
+  CMenuEntry *tmpse,*tmpse1;
+  if (tmpme) {
+    tmpse=tmpme->sub;
+    while (tmpse) {
+      tmpse1=tmpse->next;
+      MenuDelSub(tmpse);
+      tmpse=tmpse1;
+    }
+    Free(tmpme);
+  }
+}
+
+public U0 MenuDel(CMenu *m)
+{//Delete a manu. You probably don't need this.
+  CMenuEntry *tmpme,*tmpme1;
+  if (!m) return;
+  tmpme=m->sub;
+  while (tmpme) {
+    tmpme1=tmpme->next;
+    MenuDelSub(tmpme);
+    tmpme=tmpme1;
+  }
+  Free(m);
+}
+
+I64 MenuEntryWidth(CMenuEntry *tmpme)
+{
+  I64 res=StrLen(tmpme->name);
+  CMenuEntry *tmpse=tmpme->sub;
+  while (tmpse) {
+    res=MaxI64(res,StrLen(tmpse->name));
+    tmpse=tmpse->next;
+  }
+  return res+1;
+}
+
+public CMenu *MenuPush(U8 *st)
+{//Save old pulldown menu and replace with new from str.
+  CMenu *m=MenuNew(st);
+  m->next=Fs->cur_menu;
+  Fs->cur_menu=m;
+  return m;
+}
+
+public CMenu *MenuFilePush(U8 *filename)
+{//Save old pulldown menu and replace with new from file.
+  CMenu *m=MenuFile(filename);
+  m->next=Fs->cur_menu;
+  Fs->cur_menu=m;
+  return m;
+}
+
+public U0 MenuPop()
+{//Restore old pulldown menu. Delete just-deactivated menu.
+  CMenu *m=Fs->cur_menu;
+  if (!m) return;
+  Fs->cur_menu=m->next;
+  MenuDel(m);
+}
+
+U0 DrawMenu(CDC *dc)
+{
+  CMenu *m;
+  CMenuEntry *tmpme,*tmpse,*cur_submenu=NULL;
+  U8 *st=NULL;
+  CTask *task=MenuTask;
+  I64 i,w,x0,y0,x1=ms.pos.x,y1=ms.pos.y;
+  if (!TaskValidate(task) || !(m=task->cur_menu)) {
+    sys_cur_submenu_entry=NULL;
+    return;
+  }
+  dc->color=m->attr>>4;
+  GrRect(dc,0,0,GR_WIDTH,FONT_HEIGHT);
+  x0=0;
+  tmpme=m->sub;
+  while (tmpme) {
+    w=MenuEntryWidth(tmpme)*FONT_WIDTH;
+    if (x0<=x1<x0+w) {
+      if (0<=y1<FONT_HEIGHT) {
+        dc->color=m->attr&15;
+        GrRect(dc,x0,0,w,FONT_HEIGHT);
+        dc->color=m->attr>>4;
+      } else
+        dc->color=m->attr&15;
+      GrPrint(dc,x0,0,"%s",tmpme->name);
+      y0=FONT_HEIGHT;
+      tmpse=tmpme->sub;
+      while (tmpse) {
+        if (tmpse->checked)
+          i=m->attr^0xFF;
+        else
+          i=m->attr;
+        if (y0<=y1<y0+FONT_HEIGHT) {
+          if (tmpse->msg_code==MSG_KEY_DOWN||
+                tmpse->msg_code==MSG_KEY_DOWN_UP) {
+            if (!tmpse->arg2)
+              tmpse->arg2=Char2ScanCode(tmpse->arg1);
+            st=ScanCode2KeyName(tmpse->arg2);
+          }
+          sys_cur_submenu_entry=cur_submenu=tmpse;
+          dc->color=i&15;
+          GrRect(dc,x0,y0,w,FONT_HEIGHT);
+          dc->color=i>>4;
+          GrPrint(dc,x0,y0,"%s",tmpse->name);
+          if (st) {
+            dc->color=i>>4;
+            GrRect(dc,x0+w,y0-FONT_HEIGHT,
+                  (StrLen(st)+1)*FONT_WIDTH,FONT_HEIGHT*3);
+            dc->color=i&15;
+            GrPrint(dc,x0+w,y0,"%s",st);
+            Free(st);
+          }
+        } else {
+          dc->color=i>>4;
+          GrRect(dc,x0,y0,w,FONT_HEIGHT);
+          dc->color=i&15;
+          GrPrint(dc,x0,y0,"%s",tmpse->name);
+        }
+        y0+=FONT_HEIGHT;
+        tmpse=tmpse->next;
+      }
+    } else {
+      dc->color=m->attr&15;
+      GrPrint(dc,x0,0,"%s",tmpme->name);
+    }
+    x0+=w;
+    tmpme=tmpme->next;
+  }
+  sys_cur_submenu_entry=cur_submenu;
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootDVD.HC.HTML b/public/Wb/Adam/Opt/Boot/BootDVD.HC.HTML new file mode 100755 index 0000000..f002b4e --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootDVD.HC.HTML @@ -0,0 +1,219 @@ + + + + + + + + + + + +
+#define BOOT_HIGH_LOC_DVD       ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_DVD","%08X",BOOT_HIGH_LOC_DVD<<4);
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_DVD_END","%08X",BOOT_RAM_LIMIT-1);
+
+asm {
+USE16
+BDVD_START::
+//DL is supposed to have the BIOS drive number
+        CLD
+        MOV     AX,BOOT_HIGH_LOC_DVD
+        MOV     ES,AX
+
+        CLI
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE
+        STI
+
+        CALL    BDVD_GET_RIP
+BDVD_GET_RIP:
+        POP     BX
+        SUB     BX,BDVD_GET_RIP-BDVD_START
+        SHR     BX,4
+//This copies this bootloader's code to 0x00096600
+        MOV     AX,CS
+        ADD     AX,BX
+        MOV     DS,AX
+        MOV     CX,DVD_BOOT_LOADER_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_DVD
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_DVD:BDVD_MAIN
+        DU16    BDVD_MAIN-BDVD_START,BOOT_HIGH_LOC_DVD;
+
+BDVD_BIOS_DRV_NUM:      DU8     0;
+BDVD_PAGE:              DU8     0;
+
+BDVD_DAP:               DU8     16,0,1,0; //One blk at a time
+BDVD_DAP_BUF:           DU16    0,0;
+BDVD_DAP_BLK:           DU64    0;
+        
+BDVD_TEMPLEOS_MSG:
+        DU8     "Loading TempleOS",0;
+
+BDVD_NOT64_MSG:
+        DU8     "TempleOS requires a 64-bit capable processor.\n\r",0;
+
+//These get patched.
+BDVD_BLK_LO::           DU16    0;
+BDVD_BLK_HI::           DU16    0;
+BDVD_BLK_CNT::          DU16    0;
+BDVD_SHIFT_BLKS::       DU16    0;
+BDVD_PROGRESS_STEP::    DU32    0;
+BDVD_PROGRESS_VAL::     DU32    0;
+
+BDVD_PUT_CHAR::
+        MOV     AH,0xE
+        MOV     BL,7 //Might be foreground color on some BIOS's
+        MOV     BH,U8 [BDVD_PAGE-BDVD_START]
+        INT     0x10
+BDVD_RET::
+        RET
+BDVD_PUTS::
+@@1:    LODSB
+        TEST    AL,AL
+        JZ      BDVD_RET
+        CALL    BDVD_PUT_CHAR
+        JMP     @@1
+
+BDVD_MAIN::
+        MOV     U8 [BDVD_BIOS_DRV_NUM-BDVD_START],DL //Passed in by BIOS
+
+        MOV     AH,0xF
+        INT     0x10
+        MOV     U8 [BDVD_PAGE-BDVD_START],BH //Video page
+
+        MOV     EAX,0x80000000
+        CPUID
+        CMP     EAX,0x80000001
+        JB      @@05
+
+        MOV     EAX,0x80000001
+        CPUID
+        BT      EDX,29
+        JC      @@15
+@@05:   MOV     SI,BDVD_NOT64_MSG-BDVD_START
+        CALL    BDVD_PUTS
+@@10:   JMP     @@10
+
+@@15:   MOV     SI,BDVD_TEMPLEOS_MSG-BDVD_START
+        CALL    BDVD_PUTS
+
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        XOR     ECX,ECX
+        MOV     CX,U16 [BDVD_BLK_CNT-BDVD_START]
+
+        MOV     EAX,(80-7-9)*65536      //80 columns
+        XOR     EDX,EDX
+        DIV     ECX
+        MOV     U32 [BDVD_PROGRESS_STEP-BDVD_START],EAX
+        MOV     U32 [BDVD_PROGRESS_VAL-BDVD_START],0
+
+        MOV     AX,U16 [BDVD_BLK_LO-BDVD_START]
+        MOV     DX,U16 [BDVD_BLK_HI-BDVD_START]
+
+@@20:   PUSH    CX      //Blk cnt
+
+//READ BLK
+        PUSH    AX      //Blk lo
+        PUSH    DX      //Blk hi
+        PUSH    ES      //Buf seg
+        MOV     U16 [BDVD_DAP_BLK-BDVD_START],AX
+        MOV     U16 [BDVD_DAP_BLK+2-BDVD_START],DX
+        MOV     AX,ES
+        MOV     U16 [BDVD_DAP_BUF+2-BDVD_START],AX //ES:0000
+        MOV     SI,BDVD_DAP-BDVD_START //DS:SI=DAP
+        MOV     AH,0x42
+        MOV     DL,U8 [BDVD_BIOS_DRV_NUM-BDVD_START]
+        INT     0x13
+
+        POP     AX      //ES
+        ADD     AX,DVD_BLK_SIZE/16
+        MOV     ES,AX
+        POP     DX
+        POP     AX
+        INC     AX
+        JNZ     @@25
+        INC     DX
+
+@@25:   PUSH    AX
+        MOV     BX,U16 [BDVD_PROGRESS_VAL+2-BDVD_START]
+        MOV     EAX,U32 [BDVD_PROGRESS_STEP-BDVD_START]
+        ADD     U32 [BDVD_PROGRESS_VAL-BDVD_START],EAX
+        CMP     U16 [BDVD_PROGRESS_VAL+2-BDVD_START],BX
+        JE      @@30
+        MOV     AL,'.'
+        CALL    BDVD_PUT_CHAR
+@@30:   POP     AX
+
+        POP     CX
+        LOOP    @@20
+
+//Shift backward to align
+        PUSH    DS
+        MOV     BX,U16 [BDVD_SHIFT_BLKS-BDVD_START]
+        SHL     BX,BLK_SIZE_BITS-4
+        MOV     CX,U16 [BDVD_BLK_CNT-BDVD_START]
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        ADD     AX,BX
+        MOV     DS,AX
+@@35:   PUSH    CX
+        XOR     SI,SI
+        XOR     DI,DI
+        MOV     CX,DVD_BLK_SIZE/4
+        REP_MOVSD
+        MOV     AX,DS
+        ADD     AX,DVD_BLK_SIZE/16
+        MOV     DS,AX
+        MOV     AX,ES
+        ADD     AX,DVD_BLK_SIZE/16
+        MOV     ES,AX
+        POP     CX
+        LOOP    @@35
+        POP     DS
+
+//See BootDVDProbe().
+        MOV     EBX,U32 [BDVD_BLK_LO-BDVD_START]
+        MOV     AX,U16 [BDVD_SHIFT_BLKS-BDVD_START]
+        SHL     EAX,16
+        MOV     AX,BOOT_SRC_DVD  //See sys_boot_src
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_RAM_BASE:0000
+        DU16    0,BOOT_RAM_BASE/16;
+//Continues here ::/Kernel/KStart16.HC
+BDVD_END::
+#assert BDVD_END-BDVD_START<DVD_BOOT_LOADER_SIZE
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootDVDIns.HC.HTML b/public/Wb/Adam/Opt/Boot/BootDVDIns.HC.HTML new file mode 100755 index 0000000..6d3592b --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootDVDIns.HC.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+//See Install Documentation.
+//Study my account examples: Cfg Strs, Update Funs
+
+#include "BootDVD"
+#include "DskISORedSea"
+
+#help_index "Install"
+
+#define KERNEL_BIN_C    "Kernel.BIN.C"
+#define BOOT_DIR        "/0000Boot"
+#define BOOT_DIR_KERNEL_BIN_C   BOOT_DIR "/0000" KERNEL_BIN_C
+
+U0 MakeAll()
+{
+  if (Cmp("/Compiler/Compiler","Compiler",,':'))
+    throw;
+  if (Cmp("/Kernel/Kernel","Kernel",,':'))
+    throw;
+}
+
+public U0 BootDVDIns(U8 drv_let=0)
+{//See ::/Misc/DoDistro.HC.
+  try {
+    if (!Drv(drv_let))
+      throw;
+    MakeAll;
+    Move("/Kernel/Kernel.BIN.Z",BOOT_DIR_KERNEL_BIN_C);
+  } catch {
+    PutExcept;
+    Beep;
+  }
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootHD.HC.HTML b/public/Wb/Adam/Opt/Boot/BootHD.HC.HTML new file mode 100755 index 0000000..58706ba --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootHD.HC.HTML @@ -0,0 +1,124 @@ + + + + + + + + + + + +
+#define MODULE_SIZE             1*BLK_SIZE
+#define BOOT_HIGH_LOC_HD        ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+MODULE_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_HD","%08X",BOOT_HIGH_LOC_HD<<4);
+
+asm {
+USE16
+BHD_CODE::
+
+#define BHD_START (BHD_CODE-offset(CFAT32Boot.code))
+
+        CLD
+
+        MOV     AX,BOOT_HIGH_LOC_HD
+        MOV     ES,AX
+
+        CLI
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE+MODULE_SIZE
+        STI
+
+        CALL    BHD_GET_RIP
+BHD_GET_RIP:
+        POP     BX
+        SUB     BX,BHD_GET_RIP-BHD_START
+        SHR     BX,4
+//This copies this bootloader's code to 0x00096C00
+        MOV     AX,CS
+        ADD     AX,BX
+        MOV     DS,AX
+        MOV     CX,MODULE_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_HD
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_HD:BHD_HISTART
+        DU16    BHD_HISTART-BHD_START,BOOT_HIGH_LOC_HD;
+
+BHD_BIOS_DRV_NUM: DU8   0;
+
+//Gets patched by BootHDIns().
+BHD_BLK_CNT::   DU16    0;
+
+BHD_DAP:        DU8     16,0,1,0; //One blk at a time
+BHD_DAP_BUF:    DU16    0,0;
+//Gets patched by BootHDIns().
+BHD_DAP_BLK::   //64-bit
+BHD_DAP_BLK_LO: DU32    0;
+BHD_DAP_BLK_HI: DU32    0;
+
+BHD_HISTART:
+        MOV     U8 [BHD_BIOS_DRV_NUM-BHD_START],DL //Passed in by BIOS
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        XOR     ECX,ECX
+        MOV     CX,U16 [BHD_BLK_CNT-BHD_START]
+
+@@05:   PUSH    CX      //Blk cnt
+
+//READ BLK
+        PUSH    ES      //Buf seg
+        MOV     AX,ES
+        MOV     U16 [BHD_DAP_BUF+2-BHD_START],AX //ES:0000
+        MOV     SI,BHD_DAP-BHD_START //DS:SI=DAP
+        MOV     AH,0x42
+        MOV     DL,U8 [BHD_BIOS_DRV_NUM-BHD_START]
+        INT     0x13
+
+        POP     AX      //ES
+        ADD     AX,BLK_SIZE/16
+        MOV     ES,AX
+        INC     U32 [BHD_DAP_BLK_LO-BHD_START]
+        JNZ     @@10
+        INC     U32 [BHD_DAP_BLK_HI-BHD_START]
+
+@@10:   POP     CX
+        LOOP    @@05
+
+        XOR     EBX,EBX
+        MOV     EAX,BOOT_SRC_HARDDRV //See sys_boot_src
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_RAM_BASE:0000
+        DU16    0,BOOT_RAM_BASE/16;
+//Continues here ::/Kernel/KStart16.HC
+BHD_END::
+#assert BHD_END-BHD_START<MODULE_SIZE-2
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootHDIns.HC.HTML b/public/Wb/Adam/Opt/Boot/BootHDIns.HC.HTML new file mode 100755 index 0000000..d1ad294 --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootHDIns.HC.HTML @@ -0,0 +1,91 @@ + + + + + + + + + + + +
+//See Install Documentation.
+//Study my account examples: Cfg Strs, Update Funs
+
+#include "BootHD"
+
+#help_index "Install"
+
+#define KERNEL_BIN_C    "Kernel.BIN.C"
+
+U0 MakeAll()
+{
+  if (Cmp("/Compiler/Compiler","Compiler",,':'))
+    throw;
+  if (Cmp("/Kernel/Kernel","Kernel",,':'))
+    throw;
+}
+
+public U0 BootHDIns(U8 drv_let=0)
+{//MakeAll and install new boot-loader.
+  CDrv *dv;
+  CFAT32Boot br;
+  CDirEntry de;
+  I64 i;
+  try {
+    if (!Drv(drv_let))
+      throw;
+    dv=Fs->cur_dv;
+    MakeAll;
+    switch (Let2BlkDevType(dv->drv_let)) {
+      case BDT_RAM:
+      case BDT_ATA:
+        Move("/Kernel/Kernel.BIN.Z","/" KERNEL_BIN_C);
+        if (!FileFind("/" KERNEL_BIN_C,&de,FUF_JUST_FILES))
+          "No Kernel.BIN.C\n";
+        else {
+          Free(de.full_name);
+          "Modifying partition boot record.\n";
+          BlkRead(dv,&br,dv->drv_offset,1);
+          br.jump_and_nop[0]=OC_JMP_REL8;
+          br.jump_and_nop[1]=offset(CFAT32Boot.code)-2;
+#assert offset(CFAT32Boot.code)>=offset(CRedSeaBoot.code)
+          br.jump_and_nop[2]=OC_NOP;
+          *BHD_BLK_CNT(U16 *)=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+          *BHD_DAP_BLK(I64 *)=Clus2Blk(dv,de.clus);
+          for (i=0;i<BHD_END-BHD_CODE;i++)
+            br.code[i]=BHD_CODE(U8 *)[i];
+#assert sizeof(CFAT32Boot.code)>=BHD_END-BHD_CODE
+          for (;i<sizeof(CFAT32Boot.code);i++)
+            br.code[i]=0;
+          BlkWrite(dv,&br,dv->drv_offset,1);
+        }
+        break;
+      default:
+        throw;
+    }
+  } catch {
+    PutExcept;
+    Beep;
+  }
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootMHD.HC.HTML b/public/Wb/Adam/Opt/Boot/BootMHD.HC.HTML new file mode 100755 index 0000000..edbad66 --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootMHD.HC.HTML @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+#define MODULE_SIZE             1*BLK_SIZE
+#define BOOT_HIGH_LOC_MHD       ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+MODULE_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_MHD","%08X",BOOT_HIGH_LOC_MHD<<4);
+
+asm {
+USE16
+BMHD_START::
+BMHD_CODE::
+        CLD
+
+        MOV     AX,BOOT_HIGH_LOC_MHD
+
+        CLI
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE+MODULE_SIZE
+        STI
+
+        PUSHFW
+        PUSH    DS
+        PUSH    ES
+        PUSH    FS
+        PUSH    GS
+        PUSH    ECX
+        PUSH    EBX
+        PUSH    EDX
+        PUSH    EBP
+
+        MOV     ES,AX
+
+        CALL    BMHD_GET_RIP
+BMHD_GET_RIP:
+        POP     BX
+        SUB     BX,BMHD_GET_RIP-BMHD_START
+        MOV     CX,BX
+        SHR     BX,4
+//This copies this bootloader's code to 0x00096C00
+        MOV     AX,CS
+        PUSH    AX
+        ADD     AX,BX
+        MOV     DS,AX
+        MOV     U16 [BMHD_OLD_CS_RIP-BMHD_START],CX
+        POP     U16 [BMHD_OLD_CS_RIP+2-BMHD_START]
+
+        MOV     CX,MODULE_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_MHD
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_MHD:BMHD_HISTART
+        DU16    BMHD_HISTART-BMHD_START,BOOT_HIGH_LOC_MHD;
+
+BMHD_BIOS_DRV_NUM:      DU8     0;
+BMHD_OLD_CS_RIP:                DU16    0,0;
+//Gets patched by BootHDIns().
+BMHD_BLK_CNT::          DU16    0;
+
+BMHD_DAP:               DU8     16,0,1,0; //One blk at a time
+BMHD_DAP_BUF:           DU16    0,0;
+//Gets patched by BootHDIns().
+BMHD_DAP_BLK::  //64-bit
+BMHD_DAP_BLK_LO:        DU32    0;
+BMHD_DAP_BLK_HI:        DU32    0;
+
+BMHD_HISTART:
+        MOV     U8 [BMHD_BIOS_DRV_NUM-BMHD_START],DL //Passed in by BIOS
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        XOR     ECX,ECX
+        MOV     CX,U16 [BMHD_BLK_CNT-BMHD_START]
+
+@@05:   PUSH    CX      //Blk cnt
+
+//READ BLK
+        PUSH    ES      //Buf seg
+        MOV     AX,ES
+        MOV     U16 [BMHD_DAP_BUF+2-BMHD_START],AX //ES:0000
+        MOV     SI,BMHD_DAP-BMHD_START //DS:SI=DAP
+        MOV     AH,0x42
+        MOV     DL,U8 [BMHD_BIOS_DRV_NUM-BMHD_START]
+        INT     0x13
+
+        POP     AX      //ES
+        ADD     AX,BLK_SIZE/16
+        MOV     ES,AX
+        INC     U32 [BMHD_DAP_BLK_LO-BMHD_START]
+        JNZ     @@10
+        INC     U32 [BMHD_DAP_BLK_HI-BMHD_START]
+
+@@10:   POP     CX
+        LOOP    @@05
+
+        MOV     DL,U8 [BMHD_BIOS_DRV_NUM-BMHD_START]
+        MOV     EBX,U32 [BMHD_OLD_CS_RIP-BMHD_START]
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_RAM_BASE:0000
+        DU16    0,BOOT_RAM_BASE/16;
+//Continues here BMHD2_START
+BMHD_END::
+#assert BMHD_END-BMHD_START<=440
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootMHD2.HC.HTML b/public/Wb/Adam/Opt/Boot/BootMHD2.HC.HTML new file mode 100755 index 0000000..fde5e41 --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootMHD2.HC.HTML @@ -0,0 +1,154 @@ + + + + + + + + + + + +
+#define MODULE_SIZE             2*BLK_SIZE
+#define BOOT_HIGH_LOC_MHD2      ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+MODULE_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_MHD2","%08X",BOOT_HIGH_LOC_MHD2<<4);
+
+asm {
+USE16
+BMHD2_START::
+        MOV     U32 FS:[0],'B'+0x2000+('2'+0x2000)<<16
+
+        MOV     AX,BOOT_HIGH_LOC_MHD2
+        MOV     ES,AX
+//This copies this bootloader's code to 0x00096A00
+        MOV     AX,CS
+        MOV     DS,AX
+        MOV     U32 [BMHD2_OLD_CS_RIP-BMHD2_START],EBX
+        MOV     U8 [BMHD2_BIOS_DRV_NUM-BMHD2_START],DL
+
+        MOV     CX,MODULE_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_MHD2
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_MHD2:BMHD2_HISTART
+        DU16    BMHD2_HISTART-BMHD2_START,BOOT_HIGH_LOC_MHD2;
+
+BMHD2_BOOT_MSG::
+        DU8     256 DUP(0);
+
+BMHD2_BIOS_DRV_NUM:     DU8     0;
+BMHD2_PAGE:             DU8     0;
+BMHD2_BLK_ARRAY::       DU64 8 DUP(0);
+
+BMHD2_DAP:              DU8     16,0,1,0; //One blk at a time
+BMHD2_DAP_BUF:          DU16    0,0;
+BMHD2_DAP_BLK:: //64-bit
+BMHD2_DAP_BLK_LO:       DU32    0;
+BMHD2_DAP_BLK_HI:       DU32    0;
+
+BMHD2_PUT_CHAR::
+        MOV     AH,0xE
+        MOV     BL,7 //Might be foreground color on some BIOS's
+        MOV     BH,U8 [BMHD2_PAGE-BMHD2_START]
+        INT     0x10
+BMHD2_RET::
+        RET
+BMHD2_PUTS::
+@@1:    LODSB
+        TEST    AL,AL
+        JZ      BMHD2_RET
+        CALL    BMHD2_PUT_CHAR
+        JMP     @@1
+
+BMHD2_GETCHAR:
+        XOR     AH,AH
+        INT     0x16
+        PUSH    AX
+        MOV     AH,0x0E
+        MOV     BX,0x07
+        INT     0x10
+        POP     AX
+        RET
+
+BMHD2_HISTART:
+        MOV     AH,0xF
+        INT     0x10
+        MOV     U8 [BMHD2_PAGE-BMHD2_START],BH //Video page
+
+        MOV     U32 FS:[0],0
+@@5:    MOV     SI,BMHD2_BOOT_MSG-BMHD2_START
+        CALL    BMHD2_PUTS
+        CALL    BMHD2_GETCHAR
+        CMP     AL,'0'
+        JB      @@5
+        CMP     AL,'8'
+        JAE     @@5
+        AND     EAX,7
+
+        MOV     EBX,U32 BMHD2_BLK_ARRAY-BMHD2_START[EAX*8]
+        MOV     EAX,U32 BMHD2_BLK_ARRAY+4-BMHD2_START[EAX*8]
+
+        TEST    EBX,EBX
+        JNZ     @@10
+        TEST    EAX,EAX
+        JZ      @@5
+
+@@10:   MOV     U32 [BMHD2_DAP_BLK_LO-BMHD2_START],EBX
+        MOV     U32 [BMHD2_DAP_BLK_HI-BMHD2_START],EAX
+
+        MOV     AX,U16 [BMHD2_OLD_CS_RIP-BMHD2_START]
+        SHR     AX,4
+        ADD     AX,U16 [BMHD2_OLD_CS_RIP+2-BMHD2_START]
+        MOV     U16 [BMHD2_DAP_BUF+2-BMHD2_START],AX //ES:0000
+        MOV     SI,BMHD2_DAP-BMHD2_START //DS:SI=DAP
+        MOV     DL,U8 [BMHD2_BIOS_DRV_NUM-BMHD2_START]
+        MOV     AH,0x42
+        INT     0x13
+
+        POP     EBP
+        POP     EDX
+        POP     EBX
+        POP     ECX
+        XOR     EAX,EAX
+        POP     GS
+        POP     FS
+        POP     ES
+        POP     DS
+        POPFW
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP xxxx:yyyy
+BMHD2_OLD_CS_RIP:
+        DU16    0,0;
+BMHD2_END::
+//Continues here ::/Adam/Opt/Boot/BootHD.HC
+#assert BMHD2_END-BMHD2_START<MODULE_SIZE
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootMHDIns.HC.HTML b/public/Wb/Adam/Opt/Boot/BootMHDIns.HC.HTML new file mode 100755 index 0000000..9f2bd46 --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootMHDIns.HC.HTML @@ -0,0 +1,183 @@ + + + + + + + + + + + +
+//See Install Documentation.
+//Study my account examples: Cfg Strs, Update Funs
+
+#include "BootMHD"
+#include "BootMHD2"
+
+#help_index "Install"
+
+#define BOOT_DIR        "/0000Boot"
+//Stage 2 of master boot loader
+#define BOOT_DIR_BOOTMHD2_BIN_C BOOT_DIR "/BootMHD2.BIN.C"
+//Old master boot record
+#define BOOT_DIR_OLDMBR_BIN_C   BOOT_DIR "/OldMBR.BIN.C"
+
+public U0 BootMHDOldRead(U8 src_drv,U8 dst_drv)
+{//Reads MBR from disk drive containing src partition.
+//Writes a single blk file to dst BOOT_DIR.
+  CBlkDev *bd=Let2BlkDev(src_drv);
+  CDrv *dv;
+  CMasterBoot mbr;
+  Drv(dst_drv);
+  dv=Fs->cur_dv;
+  if (dv->fs_type!=FSt_REDSEA && dv->fs_type!=FSt_FAT32)
+    PrintErr("File System Not Supported\n");
+  else {
+//Bypass partition bounds-checking
+    BlkDevLock(bd);
+    ATAReadBlks(bd,&mbr,0,1);
+    BlkDevUnlock(bd);
+
+    Drv(dst_drv);
+    DirMk(BOOT_DIR);
+    FileWrite(BOOT_DIR_OLDMBR_BIN_C,&mbr,BLK_SIZE);
+  }
+}
+
+public U0 BootMHDOldWrite(U8 src_drv,U8 dst_drv)
+{//Reads OldMBR from src drive BOOT_DIR.
+//writes it to the MBR of the drive with dst partition.
+  CBlkDev *bd=Let2BlkDev(dst_drv);
+  CMasterBoot *mbr;
+  Drv(src_drv);
+  if (mbr=FileRead(BOOT_DIR_OLDMBR_BIN_C)) {
+//Bypass partition bounds-checking
+    BlkDevLock(bd);
+    ATAWriteBlks(bd,mbr,0,1);
+    BlkDevUnlock(bd);
+  }
+  Free(mbr);
+}
+
+public U0 BootMHDZero(U8 dst_drv)
+{//Set MBR of disk with dst partition to zero.
+
+  //This is dangerous!!
+  //The TempleOS partitioner doesn't play well
+  //with other operating systems at this time and you need
+  //to do this on a drive partitioned by TempleOS
+  //if you wish to partition with another operating system.
+  CBlkDev *bd=Let2BlkDev(dst_drv);
+  CMasterBoot mbr;
+  MemSet(&mbr,0,BLK_SIZE);
+//Bypass partition bounds-checking
+  BlkDevLock(bd);
+  ATAWriteBlks(bd,&mbr,0,1);
+  BlkDevUnlock(bd);
+}
+
+public Bool BootMHDIns(U8 drv_let,U8 *drv_lst=NULL)
+{//Create new MBR on the disk that has drv_let as a partition.
+//Puts stage 2 in BOOT_DIR of drv_let.
+  CBlkDev *bd,*bd1;
+  CDrv *dv,*p1;
+  CMasterBoot mbr;
+  CDirEntry de;
+  I64 i,j,size,*_q;
+  U8 *menu_ptr,*ptr,ch,buf[STR_LEN];
+  Bool res=FALSE;
+
+  try {
+    if (drv_lst) {
+      StrCpy(buf,drv_lst);
+      StrUtil(buf,SUF_TO_UPPER);
+    } else {
+      j=0;
+      for (i='A';i<='Z';i++)
+        buf[j++]=i;
+      buf[j++]=0;
+    }
+    Drv(drv_let);
+    dv=Fs->cur_dv;
+    if (dv->fs_type!=FSt_REDSEA && dv->fs_type!=FSt_FAT32)
+      PrintErr("File System Not Supported\n");
+    else {
+      bd=dv->bd;
+      if (!FileFind(BOOT_DIR_OLDMBR_BIN_C,,FUF_JUST_FILES))
+        BootMHDOldRead(drv_let,drv_let);
+
+      _q=BMHD2_BLK_ARRAY;
+      MemSet(_q,0,sizeof(I64)*8);
+      menu_ptr=BMHD2_BOOT_MSG;
+      StrPrint(menu_ptr,"\n\r\n\rTempleOS Boot Loader\n\r\n\r");
+      j=0;
+      if (FileFind(BOOT_DIR_OLDMBR_BIN_C,&de,FUF_JUST_FILES)) {
+        Free(de.full_name);
+        *_q++=Clus2Blk(dv,de.clus);
+        CatPrint(menu_ptr,"0. Old Boot Record\n\r");
+        j++;
+      }
+
+      ptr=buf;
+      while (ch=*ptr++) {
+        if ((p1=Let2Drv(ch,FALSE)) && (bd1=p1->bd) && bd1==bd) {
+          *_q=p1->drv_offset;
+          "Drive %C:%16X\n",Drv2Let(p1),*_q;
+          CatPrint(menu_ptr,"%d. Drive %C\n\r",j++,Drv2Let(p1));
+          _q++;
+        }
+      }
+      CatPrint(menu_ptr,"\n\rSelection:");
+
+      size=BMHD2_END-BMHD2_START;
+      FileWrite(BOOT_DIR_BOOTMHD2_BIN_C,BMHD2_START,size);
+
+      if (!FileFind(BOOT_DIR_BOOTMHD2_BIN_C,&de,FUF_JUST_FILES))
+        "No Boot Loader Image\n";
+      else {
+        Free(de.full_name);
+        *BMHD_BLK_CNT(U16 *)=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+        *BMHD_DAP_BLK(I64 *)=Clus2Blk(dv,de.clus);
+//Bypass partition bounds-checking
+        BlkDevLock(bd);
+        ATAReadBlks(bd,&mbr,0,1);
+        for (i=0;i<BMHD_END-BMHD_CODE;i++)
+          mbr.code[i]=BMHD_CODE(U8 *)[i];
+#assert sizeof(CMasterBoot.code)>=BMHD_END-BMHD_CODE
+        for (;i<sizeof(CMasterBoot.code);i++)
+          mbr.code[i]=0;
+        if (!mbr.media_id)
+          mbr.media_id=RandU32;
+        mbr.zero=0;
+        mbr.signature=0xAA55;
+
+        ATAWriteBlks(bd,&mbr,0,1);
+        BlkDevUnlock(bd);
+        res=TRUE;
+      }
+    }
+  } catch
+    PutExcept;
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/BootRAM.HC.HTML b/public/Wb/Adam/Opt/Boot/BootRAM.HC.HTML new file mode 100755 index 0000000..9a05223 --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/BootRAM.HC.HTML @@ -0,0 +1,91 @@ + + + + + + + + + + + +
+#help_index "Call"
+asm {
+_HI_CALL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 16[RBP]
+        TEST    RAX,RAX
+        JZ      @@05
+        CALL    RAX
+@@05:   POP     RBP
+        RET1    8
+//************************************
+_HI_MEMCPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_MOVSB
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+}
+_extern _HI_CALL I64 HiCall(U8 *machine_code);
+_extern _HI_MEMCPY U8 *HiMemCpy(U8 *dst,U8 *src,I64 cnt);
+
+#help_index "Boot"
+public U0 BootRAM(U8 *filename=NULL)
+{//Softboot Kernel.BIN file. No hardware reset.
+  I64 size;
+  CKernel *hi_image,*lo_image=mem_boot_base-sizeof(CBinFile),
+        reg *sys_ram_reboot;
+  if (!filename)
+    filename="::/" KERNEL_BIN_C;
+  do if (!(hi_image=FileRead(filename,&size))) return;
+  while (hi_image<0x100000); //If alloc from low 640K, just get another copy.
+
+  do sys_ram_reboot=MAlloc(SYS_RAM_REBOOT_END-SYS_RAM_REBOOT,Fs->code_heap);
+  while (sys_ram_reboot<0x100000);
+
+  hi_image->boot_src=BOOT_SRC_RAM;
+  hi_image->boot_blk=0;
+  hi_image->boot_patch_table_base=lo_image(U8 *)+hi_image->h.patch_table_offset;
+  hi_image->sys_run_level =lo_image->sys_run_level&(RLF_VGA|RLF_16BIT);
+  MemCpy(&hi_image->start,&lo_image->start,
+        sizeof(CKernel)-offset(CKernel.start));
+
+  CLI
+  if (mp_cnt>1)
+    MPHalt;
+
+  HiMemCpy(sys_ram_reboot,SYS_RAM_REBOOT,SYS_RAM_REBOOT_END-SYS_RAM_REBOOT);
+  HiMemCpy(lo_image,hi_image,size);
+  HiCall(sys_ram_reboot);
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/DskISORedSea.HC.HTML b/public/Wb/Adam/Opt/Boot/DskISORedSea.HC.HTML new file mode 100755 index 0000000..1f7490e --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/DskISORedSea.HC.HTML @@ -0,0 +1,219 @@ + + + + + + + + + + + +
+#help_index "File/CD DVD"
+
+U0 FillU16Palindrome(CPalindromeU16 *dst,U16 w)
+{
+  dst->big=EndianU16(w);
+  dst->little=w;
+}
+
+U0 FillU32Palindrome(CPalindromeU32 *dst,I64 d)
+{
+  dst->big=EndianU32(d);
+  dst->little=d;
+}
+
+class CElTorito
+{
+  U16 w[16];
+  U8 bootable; //88=bootable 00=not bootable
+  U8 media_type; //0=no emulation 4=hard disk
+  U16 load_seg; //0000->07C0
+  U8 sys_type;
+  U8 zero;
+  U16 sect_cnt;
+  U32 load_rba; //start addr of virtual disk
+  U8 zero2[20];
+};
+
+U0 RedSeaISO9660Stage1(U8 *iso_filename,U8 *stage2_filename)
+{
+  CDirEntry de;
+  CFile *out_file=NULL;
+  U8    *stage1_buf=CAlloc(DVD_BOOT_LOADER_SIZE);
+  if (FileFind(stage2_filename,&de) && (out_file=FOpen(iso_filename,"wc+"))) {
+    MemCpy(stage1_buf,BDVD_START,BDVD_END-BDVD_START);
+    *(BDVD_BLK_LO       -BDVD_START+stage1_buf)(U32 *)=de.clus>>2;
+    *(BDVD_BLK_CNT      -BDVD_START+stage1_buf)(U16 *)=
+          (de.size+DVD_BLK_SIZE-1)>>(BLK_SIZE_BITS+2);
+    *(BDVD_SHIFT_BLKS   -BDVD_START+stage1_buf)(U16 *)=de.clus&3;
+    if (de.clus&3)
+      *(BDVD_BLK_CNT    -BDVD_START+stage1_buf)(U16 *)+=1;
+    FBlkWrite(out_file,stage1_buf,
+          20<<2+1<<2,DVD_BOOT_LOADER_SIZE/BLK_SIZE);
+    FClose(out_file);
+  }
+  Free(stage1_buf);
+}
+
+U0 RedSeaISO9660(U8 *iso_filename,U8 drv_let)
+{
+  CDrv  *dv=Let2Drv(drv_let);
+  CISOPriDesc *iso_pri=CAlloc(DVD_BLK_SIZE),
+        *iso_boot=CAlloc(DVD_BLK_SIZE),
+        *iso_sup=CAlloc(DVD_BLK_SIZE),
+        *iso_term=CAlloc(DVD_BLK_SIZE);
+  I64 iso_size=0,i,j;
+  U32 *d;
+  CElTorito *et=CAlloc(DVD_BLK_SIZE);
+  U8    *zero_buf=CAlloc(DVD_BLK_SIZE);
+  CFile *out_file=NULL;
+
+  if (out_file=FOpen(iso_filename,"wc+")) {
+    iso_size=FSize(out_file)/DVD_BLK_SIZE;
+    for (i=0;i<dv->bd->drv_offset;i+=4)
+      FBlkWrite(out_file,zero_buf,i,4);
+
+    iso_pri->type=ISOT_PRI_VOL_DESC;
+    StrCpy(iso_pri->id,"CD001");
+    iso_pri->version=1;
+    FillU16Palindrome(&iso_pri->vol_set_size,1);
+    FillU16Palindrome(&iso_pri->vol_seq_num,1);
+    FillU16Palindrome(&iso_pri->log_block_size,DVD_BLK_SIZE);
+    FillU32Palindrome(&iso_pri->vol_space_size,iso_size);
+    FillU32Palindrome(&iso_pri->root_dir_record,dv->root_clus);
+    iso_pri->file_structure_version=1;
+    StrCpy(iso_pri->publisher_id,"TempleOS RedSea");
+
+    MemCpy(iso_sup,iso_pri,DVD_BLK_SIZE);
+    iso_sup->type=ISOT_SUPPLEMENTARY_DESC;
+
+    iso_boot->type=ISOT_BOOT_RECORD;
+    StrCpy(iso_boot->id,"CD001");
+    iso_boot->version=1;
+    StrCpy(iso_boot(U8 *)+7,"EL TORITO SPECIFICATION");
+
+    FBlkWrite(out_file,iso_pri,16<<2,4);
+    iso_term->type=ISOT_TERMINATOR;
+    StrCpy(iso_term->id,"CD001");
+    iso_term->version=1;
+
+    d=iso_boot(U8 *)+0x47;
+    *d=20<<2>>2;
+    FBlkWrite(out_file,iso_boot,17<<2,4);
+
+    FBlkWrite(out_file,iso_sup,18<<2,4);
+    FBlkWrite(out_file,iso_term,19<<2,4);
+
+    et->w[0]=1;
+    StrCpy(&et->w[2],"TempleOS");
+    et->w[15]=0xAA55;
+    j=0;
+    for (i=0;i<16;i++) //Checksum
+      j+=et->w[i];
+    et->w[14]=-j;
+    et->bootable=0x88;
+    et->media_type=0;//0=no emu 2=1.44meg 4=hard drive
+    et->sect_cnt=4;  //5 seems like the limit, 4 is safer
+    et->load_rba=20<<2>>2+1;
+    FBlkWrite(out_file,et,20<<2,4);
+    FClose(out_file);
+  }
+  Free(zero_buf);
+  Free(et);
+  Free(iso_pri);
+  Free(iso_boot);
+  Free(iso_sup);
+  Free(iso_term);
+}
+
+I64 RedSeaISOPass1(CDirEntry *tmpde)
+{
+  I64 dir_entry_cnt=3+LinkedLstCnt(tmpde),res=0;
+  while (tmpde) {
+    if (tmpde->attr & RS_ATTR_DIR) {
+      if (tmpde->sub)
+        res+=RedSeaISOPass1(tmpde->sub);
+      else
+        res+=BLK_SIZE; //Empty dir
+    } else
+      res+=CeilU64(tmpde->size,BLK_SIZE);
+    tmpde=tmpde->next;
+  }
+  res+=CeilU64(dir_entry_cnt<<6,BLK_SIZE); //Size in bytes
+#assert CDIR_SIZE==64
+  return res;
+}
+public I64 RedSeaISO(U8 *_iso_filename=NULL,U8 *_src_dir,
+        U8 *_stage2_filename=NULL)
+{//See ::/Misc/DoDistro.HC. Must be ISO.C
+  I64 i,res,root_cnt,root_dir_blks,bitmap_blks,bitmap_blks1;
+  CDirEntry *tmpde;
+  U8 buf[STR_LEN],*iso_filename,*src_dir,*stage2_filename;
+  CDrv *dv=DrvMakeFreeSlot(DrvNextFreeLet('Q')); //First BDT_ISO_FILE_WRITE
+  CBlkDev *bd=BlkDevNextFreeSlot(dv->drv_let,BDT_ISO_FILE_WRITE);
+
+  if (!IsDir(_src_dir))
+    PrintErr("'%s' is not a dir.\n",_src_dir);
+  else {
+    if (!_iso_filename)
+      _iso_filename=blkdev.dft_iso_c_filename;
+    iso_filename=ExtChg(_iso_filename,"ISO.C");
+    src_dir=DirNameAbs(_src_dir);
+    if (_stage2_filename) {
+      stage2_filename=FileNameAbs(_stage2_filename);
+      *stage2_filename=dv->drv_let;
+      i=StrLen(src_dir);
+      if (i!=3) //If not root
+        i++;    //Skip slash
+      StrCpy(stage2_filename+3,stage2_filename+i);
+    } else
+      stage2_filename=NULL;
+    tmpde=FilesFind(src_dir,FUF_RECURSE);
+    root_cnt=LinkedLstCnt(tmpde)+3;
+    root_dir_blks=CeilU64(root_cnt<<6,BLK_SIZE)>>BLK_SIZE_BITS;
+    if (res=RedSeaISOPass1(tmpde)>>BLK_SIZE_BITS) {
+      bd->drv_offset=19<<2+(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
+      bitmap_blks=1;
+      do {
+        bitmap_blks1=bitmap_blks;
+        bitmap_blks=(res+bitmap_blks+BLK_SIZE<<3-1)/BLK_SIZE<<3;
+      } while (bitmap_blks!=bitmap_blks1);
+
+      bd->max_blk=CeilI64(bd->drv_offset+1+bitmap_blks+res,4);
+      bd->max_blk--; //Inclusive.
+      bd->file_dsk_name=AStrNew(iso_filename);
+      bd->init_root_dir_blks=root_dir_blks;
+      BlkDevAdd(bd,,TRUE,TRUE);
+      StrPrint(buf,"%C:/",dv->drv_let);
+      CopyTree(src_dir,buf,TRUE);
+      RedSeaISO9660Stage1(iso_filename,stage2_filename);
+      DrvDel(dv);
+      BlkDevDel(bd);
+    }
+    Free(stage2_filename);
+    Free(src_dir);
+    Free(iso_filename);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Opt/Boot/MakeBoot.HC.HTML b/public/Wb/Adam/Opt/Boot/MakeBoot.HC.HTML new file mode 100755 index 0000000..181a93f --- /dev/null +++ b/public/Wb/Adam/Opt/Boot/MakeBoot.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "BootDVDIns"
+#include "BootHDIns"
+#include "BootMHDIns"
+#include "BootRAM"
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/Opt/Utils/Diff.HC.HTML b/public/Wb/Adam/Opt/Utils/Diff.HC.HTML new file mode 100755 index 0000000..5a18dbd --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/Diff.HC.HTML @@ -0,0 +1,384 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+#define DS_USE_FILE1    0
+#define DS_USE_FILE2    1
+#define DS_REMAINDER_1  2
+#define DS_REMAINDER_2  3
+#define DS_ABORT_FILE   4
+
+I64 PopUpDiffMenu()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$CM+LX,2,4$$FG$$BT,\"USE FILE1\",LE=DS_USE_FILE1$"
+        "$CM+LX,24,0$$CYAN$$BT,\"USE FILE2\",LE=DS_USE_FILE2$"
+        "$CM+LX,2,4$$FG$$BT,\"REMAINDER ALL FILE1\",LE=DS_REMAINDER_1$"
+        "$CM+LX,24,0$$CYAN$$BT,\"REMAINDER ALL FILE2\",LE=DS_REMAINDER_2$"
+        "$CM+LX,2,4$$FG$$BT,\"ABORT FILE\",LE=DS_ABORT_FILE$"
+        "$CM+LX,24,0$$FG$$BT,\"ABORT ALL FILES\",LE=DOCM_CANCEL$\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 DiffEntriesCompare(CDocEntry *doc_e1,CDocEntry *doc_e2)
+{
+  return StrCmp(doc_e1->tag,doc_e2->tag);
+}
+
+#define DF_MODIFIED                     0x01
+#define DF_DONT_MODIFIED                0x02
+#define DF_REMAINDER_ALL_FILE1          0x04
+#define DF_REMAINDER_ALL_FILE2          0x08
+#define DF_ABORT_FILE                   0x10
+#define DF_ABORT_ALL_FILES              0x20
+#define DF_NO_MORE_PMTS_THIS_FILE       0x40
+
+U0 DiffSel(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,
+        I64 j2_lo,I64 j2_hi,I64 cnt1,I64 cnt2,
+        CDocEntry **doc_unsorted1,CDocEntry **doc_unsorted2)
+{
+  CDocEntry *doc_e,*doc_e1,*doc_e2;
+  Bool use_file1;
+  I64 i,old_flags;
+  CDoc *cur_l;
+  if (!(*_df_flags & (DF_ABORT_FILE|DF_ABORT_ALL_FILES))) {
+    "$RED$";
+    if (0<=j1_lo<cnt1)
+      "%d,",doc_unsorted1[j1_lo]->y+1;
+    else if (0<=j1_hi-1<cnt1)
+      "%d,",doc_unsorted1[j1_hi-1]->y+1;
+    else
+      "***,";
+    if (0<=j2_lo<cnt2)
+      "%d",doc_unsorted2[j2_lo]->y+1;
+    else if (0<=j2_hi-1<cnt2)
+      "%d",doc_unsorted2[j2_hi-1]->y+1;
+    else
+      "***";
+    "---------------------$FG$\n";
+    if (j1_lo<=0)
+      i=0;
+    else
+      i=j1_lo-1;
+    while (i<j1_hi) {
+      if (cur_l=DocPut) {
+        old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+        cur_l->flags|=DOCF_PLAIN_TEXT;
+      }
+      "%s",doc_unsorted1[i++]->tag;
+      if (cur_l)
+        cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+      '\n';
+    }
+    "$CYAN$";
+    if (j2_lo<=0)
+      i=0;
+    else
+      i=j2_lo-1;
+    while (i<j2_hi) {
+      if (cur_l=DocPut) {
+        old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+        cur_l->flags|=DOCF_PLAIN_TEXT;
+      }
+      "%s",doc_unsorted2[i++]->tag;
+      if (cur_l)
+        cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+      '\n';
+    }
+    "$FG$";
+
+    use_file1=TRUE;
+    if (!(*_df_flags & DF_NO_MORE_PMTS_THIS_FILE)) {
+      switch (PopUpDiffMenu) {
+        case DS_USE_FILE1:
+          break;
+        case DS_USE_FILE2:
+          use_file1=FALSE;
+          break;
+        case DS_REMAINDER_1:
+          *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE2|
+                DF_REMAINDER_ALL_FILE1|DF_NO_MORE_PMTS_THIS_FILE;
+          break;
+        case DS_REMAINDER_2:
+          *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE1|
+                DF_REMAINDER_ALL_FILE2|DF_NO_MORE_PMTS_THIS_FILE;
+          break;
+        case DS_ABORT_FILE:
+          *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_FILE|
+                DF_NO_MORE_PMTS_THIS_FILE;
+          break;
+        default:
+          *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_ALL_FILES|
+                DF_NO_MORE_PMTS_THIS_FILE;
+      }
+    }
+    if (*_df_flags & DF_REMAINDER_ALL_FILE2 &&
+          !(*_df_flags & (DF_DONT_MODIFIED|DF_REMAINDER_ALL_FILE1)))
+      use_file1=FALSE;
+    if (!use_file1) {
+      *_df_flags|=DF_MODIFIED;
+      doc_e1=doc_unsorted1[j1_lo]->last;
+      if (j1_lo<j1_hi) {
+        doc_e=doc_unsorted1[j1_lo];
+        while (doc_e!=doc_unsorted1[j1_hi]) {
+          doc_e2=doc_e->next;
+          DocEntryDel(doc,doc_e);
+          doc_e=doc_e2;
+        }
+      }
+      if (j2_lo<j2_hi) {
+        doc_e=doc_unsorted2[j2_lo];
+        while (doc_e!=doc_unsorted2[j2_hi]) {
+          doc_e2=DocEntryCopy(doc,doc_e);
+          QueIns(doc_e2,doc_e1);
+          doc_e1=doc_e2;
+          doc_e=doc_e->next;
+        }
+      }
+    }
+  }
+}
+
+Bool DiffSub(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,I64 j2_lo,I64 j2_hi,
+        I64 cnt1,I64 cnt2,CDocEntry **doc_sorted1,CDocEntry **doc_sorted2,
+        CDocEntry **doc_unsorted1,CDocEntry **doc_unsorted2)
+{
+  I64 i,i1=0,i2=0,i2b,j1,j2,n,
+        best_j1,best_j2,best_score=0,score;
+  Bool res=FALSE;
+
+  if (j1_lo>=j1_hi || j2_lo>=j2_hi) {
+    if (j1_lo<j1_hi || j2_lo<j2_hi) {
+      DiffSel(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,
+            doc_unsorted1,doc_unsorted2);
+      return TRUE;
+    } else
+      return FALSE;
+  }
+
+  //Locate longest matching str in intervals
+  while (i1<cnt1 && i2<cnt2) {
+    if (!(j1_lo<=doc_sorted1[i1]->user_data<j1_hi)) //user_data is the new y
+      i1++;
+    else if (!(j2_lo<=doc_sorted2[i2]->user_data<j2_hi)) //user_data is new y
+      i2++;
+    else {
+      i=StrCmp(doc_sorted1[i1]->tag,doc_sorted2[i2]->tag);
+      if (i>0)
+        i2++;
+      else if (i<0)
+        i1++;
+      else {
+        i2b=i2;
+        while (!StrCmp(doc_sorted1[i1]->tag,doc_sorted2[i2]->tag)) {
+          if (j2_lo<=doc_sorted2[i2]->user_data<j2_hi) {//user_data is the new y
+            score=0;
+            j1=doc_sorted1[i1]->user_data; //user_data is the new y
+            j2=doc_sorted2[i2]->user_data; //user_data is the new y
+            n=j1_hi-j1;
+            if (j2_hi-j2<n)
+              n=j2_hi-j2;
+            while (score<n) {
+              if (!StrCmp(doc_unsorted1[j1+score]->tag,
+                    doc_unsorted2[j2+score]->tag))
+                score++;
+              else
+                break;
+            }
+            if (score>best_score) {
+              best_score=score;
+              best_j1=j1;
+              best_j2=j2;
+            }
+          }
+          i2++;
+          if (i2>=cnt2)
+            break;
+        }
+        i2=i2b;
+        i1++;
+      }
+    }
+  }
+  if (!best_score) {
+    DiffSel(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,
+          doc_unsorted1,doc_unsorted2);
+    return TRUE;
+  } else {
+    if (DiffSub(doc,_df_flags,j1_lo,best_j1,j2_lo,best_j2,cnt1,cnt2,
+          doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2))
+      res=TRUE;
+    if (DiffSub(doc,_df_flags,best_j1+best_score,j1_hi,best_j2+best_score,
+          j2_hi,cnt1,cnt2,
+          doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2))
+      res=TRUE;
+    return res;
+  }
+}
+
+Bool DiffBins(CDoc *doc1,CDoc *doc2)
+{
+  CDocBin *tmpb1=doc1->bin_head.next,
+        *tmpb2=doc2->bin_head.next;
+
+  if (tmpb1->last->last->num!=tmpb2->last->last->num)
+    return TRUE;
+  while (tmpb1!=&doc1->bin_head) {
+    if (tmpb1->size!=tmpb2->size ||
+          MemCmp(tmpb1->data,tmpb2->data,tmpb1->size))
+      return TRUE;
+    tmpb1=tmpb1->next;
+    tmpb2=tmpb2->next;
+  }
+  return FALSE;
+}
+
+public Bool Diff(U8 *dst_file,U8 *src_file,I64 *_df_flags=NULL)
+{//Report differences between two files and merge differences
+//from src_file to dst_file.  Don't use _df_flags arg. (Used by Merge().)
+  CDoc *doc1=DocRead(dst_file,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR),
+        *doc2=DocRead(src_file,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e,**doc_sorted1,**doc_sorted2,**doc_unsorted1,**doc_unsorted2;
+  I64 i,cnt1=0,cnt2=0,df_flags;
+  Bool res=FALSE;
+
+  if (_df_flags)
+    df_flags=*_df_flags;
+  else
+    df_flags=0;
+  df_flags&=DF_ABORT_ALL_FILES;
+
+  doc_e=doc1->head.next;
+  while (doc_e!=doc1) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      doc_e->user_data=cnt1++; //user_data is the new y
+    doc_e=doc_e->next;
+  }
+
+  doc_e=doc2->head.next;
+  while (doc_e!=doc2) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      doc_e->user_data=cnt2++; //user_data is the new y
+    doc_e=doc_e->next;
+  }
+
+  doc_sorted1=MAlloc(cnt1*sizeof(CDocEntry *));
+  doc_unsorted1=MAlloc((cnt1+1)*sizeof(CDocEntry *));
+  i=0;
+  doc_e=doc1->head.next;
+  while (doc_e!=doc1) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      doc_sorted1[i]=doc_e;
+      doc_unsorted1[i++]=doc_e;
+    }
+    doc_e=doc_e->next;
+  }
+  doc_unsorted1[i]=doc1;
+  QSortI64(doc_sorted1,cnt1,&DiffEntriesCompare);
+
+  doc_sorted2=MAlloc(cnt2*sizeof(CDocEntry *));
+  doc_unsorted2=MAlloc((cnt2+1)*sizeof(CDocEntry *));
+  i=0;
+  doc_e=doc2->head.next;
+  while (doc_e!=doc2) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      doc_sorted2[i]=doc_e;
+      doc_unsorted2[i++]=doc_e;
+    }
+    doc_e=doc_e->next;
+  }
+  doc_unsorted2[i]=doc2;
+  QSortI64(doc_sorted2,cnt2,&DiffEntriesCompare);
+
+  res=DiffSub(doc1,&df_flags,0,cnt1,0,cnt2,cnt1,cnt2,
+        doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2);
+  if (df_flags&DF_MODIFIED && !(df_flags&DF_DONT_MODIFIED))
+    DocWrite(doc1);
+
+  if (DiffBins(doc1,doc2)) {
+    "$RED$Bin Data is Different$FG$\n";
+    res=TRUE;
+  }
+
+  DocDel(doc1);
+  DocDel(doc2);
+  Free(doc_sorted1);
+  Free(doc_sorted2);
+  Free(doc_unsorted1);
+  Free(doc_unsorted2);
+  if (_df_flags)
+    *_df_flags=df_flags;
+  return res;
+}
+
+#help_index "Cmd Line (Typically);Info"
+I64 ZRepCompare(CDirEntry *e1,CDirEntry *e2)
+{
+  return SignI64(e2->user_data(F64)-e1->user_data(F64));
+}
+public U0 ZipRep(U8 *files_find_mask="/*",U8 *fu_flags=NULL,
+  Bool just_text_not_graphics=TRUE)
+{//Report file compressibility.
+//Dft is just src files.  (Used to spot
+  //src files with redundancy in them.)
+  I64 i=0,cnt,size,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1,**sort_buf;
+  U8 *buf;
+  CArcCompress *arc;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+F+S");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  cnt=FileCnt(tmpde);
+  sort_buf=MAlloc(sizeof(CDirEntry *)*cnt);
+  while (tmpde) {
+    sort_buf[i++]=tmpde;
+    buf=FileRead(tmpde->full_name,&size);
+    if (just_text_not_graphics)
+      size=StrLen(buf);
+    arc=CompressBuf(buf,size);
+    Free(buf);
+    tmpde->user_data(F64)=100.0*arc->compressed_size/arc->expanded_size;
+    Free(arc);
+    tmpde=tmpde->next;
+  }
+  QSortI64(sort_buf,cnt,&ZRepCompare);
+  for (i=0;i<cnt;i++) {
+    "%4.1f%% %04X ",sort_buf[i]->user_data,sort_buf[i]->size;
+    PutFileLink(sort_buf[i]->full_name);
+    '\n';
+  }
+  Free(sort_buf);
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/DocUtils.HC.HTML b/public/Wb/Adam/Opt/Utils/DocUtils.HC.HTML new file mode 100755 index 0000000..1a9e676 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/DocUtils.HC.HTML @@ -0,0 +1,187 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Cmd Line (Typically)"
+
+U0 CursorRemFile(U8 *filename)
+{//Rem ASCII 5 cursor from one file.
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+  DocWrite(doc);
+  DocDel(doc);
+}
+public U0 CursorRem(U8 *files_find_mask="*")
+{//Rem ASCII 5 cursor.
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+T+f+F+O");
+  CDirEntry *tmpde=FilesFind(files_find_mask,fuf_flags),*tmpde1=tmpde;
+  while (tmpde) {
+    CursorRemFile(tmpde->full_name);
+    Touch(tmpde->full_name,"",,tmpde->datetime);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+U0 CollapseFile(U8 *filename,Bool collapse=TRUE)
+{//Collapse DolDoc trees in one file.
+  CDoc *doc=DocRead(filename,DOCF_NO_CURSOR);
+  DocCollapse(collapse,doc);
+  DocWrite(doc);
+  DocDel(doc);
+}
+public U0 Collapse(U8 *files_find_mask="*",
+        Bool collapse=TRUE,U8 *fu_flags=NULL)
+{//Collapse DolDoc trees.
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+$+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  CDirEntry *tmpde=FilesFind(files_find_mask,fuf_flags),*tmpde1=tmpde;
+  while (tmpde && !Bt(&fuf_flags,FUf_CANCEL)) {
+    CollapseFile(tmpde->full_name,collapse);
+    Touch(tmpde->full_name,"",,tmpde->datetime);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+I64 DocOptEntry(CDoc *,CDocEntry *doc_e,I64 fuf_flags)
+{
+  U8 *st,*st2,**_dst;
+  I64 i,res=0;
+
+  if (doc_e->de_flags&DOCEF_LINK && doc_e->de_flags&(DOCEF_AUX_STR|DOCEF_TAG)) {
+    if (doc_e->de_flags & DOCEF_AUX_STR && doc_e->de_flags & DOCEF_TAG &&
+          !MemCmp(doc_e->aux_str,"FI:",3) &&
+          !StrCmp(doc_e->aux_str+3,doc_e->tag)) {
+      Free(doc_e->aux_str);
+      doc_e->aux_str=NULL;
+      doc_e->de_flags&=~DOCEF_AUX_STR;
+      res++;
+    }
+    if (doc_e->de_flags & DOCEF_AUX_STR)
+      _dst=&doc_e->aux_str;
+    else
+      _dst=&doc_e->tag;
+    if (StrMatch(".Z",*_dst)) {
+      st=DocLinkFile(*_dst);
+      if (FileFind(st)) {
+        if (IsDotZ(st))
+          st[StrLen(st)-2]=0;
+        i=StrLen(st);
+        if ((st2=StrMatch(st,*_dst)) && st2[i]=='.' && st2[i+1]=='Z') {
+          StrCpy(st2+i,st2+i+2);
+          res++;
+        }
+      }
+      Free(st);
+    }
+    if (fuf_flags&FUF_RISKY) {
+      if (doc_e->de_flags & DOCEF_AUX_STR) {
+        if (st=StrMatch(".Z",doc_e->aux_str)) {
+          StrCpy(st,st+2);
+          res++;
+        }
+      }
+      if (doc_e->de_flags&DOCEF_TAG) {
+        if (st=StrMatch(".Z",doc_e->tag)) {
+          StrCpy(st,st+2);
+          res++;
+        }
+      }
+    }
+  }
+  return res;
+}
+I64 DocOptDoc(CDoc *doc,I64 fuf_flags)
+{//Optimize Doc.
+  Bool unlock=DocLock(doc);
+  I64 res=0;
+  CDocEntry *doc_e,*doc_e1,*doc_e_last;
+  DocRecalc(doc);
+  doc_e_last=NULL;
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (res+=DocOptEntry(doc,doc_e,fuf_flags))
+      res+=DocOptEntry(doc,doc_e,fuf_flags);
+    if (doc_e_last && doc_e_last->type&~0xFF00==doc_e->type&~0xFF00 &&
+       doc_e_last->de_flags==doc_e->de_flags &&
+       Bt(doldoc.type_flags_chk_dup,doc_e->type_u8) &&
+       doc_e_last->attr==doc_e->attr) {
+      DocEntryDel(doc,doc_e);
+      res++;
+    } else
+      doc_e_last=doc_e;
+    doc_e=doc_e1;
+  }
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+I64 DocOptFile(U8 *filename,I64 fuf_flags)
+{//Optimize file.
+  I64 res;
+  CDoc *doc=DocRead(filename);
+  if (res=DocOptDoc(doc,fuf_flags)) {
+    "-%d:%s\n",res,doc->filename.name;
+    DocWrite(doc);
+  }
+  DocDel(doc);
+  return res;
+}
+I64 DocOptLst(CDirEntry *tmpde,I64 fuf_flags)
+{
+  I64 res=0;
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      if (tmpde->sub) {
+        "Scanning Directory: %s\n",tmpde->full_name;
+        res+=DocOptLst(tmpde->sub,fuf_flags);
+      }
+    } else
+      res+=DocOptFile(tmpde->full_name,fuf_flags);
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+  return res;
+}
+public I64 DocOpt(U8 *files_find_mask="*",U8 *fu_flags=NULL)
+{//Optimize DolDoc files, eliminating aux_str's and .Z's.
+//+R flag for aggressively risky.
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+$");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  return DocOptLst(FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND),
+        fuf_flags&~FUG_FILES_FIND);
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/Find.HC.HTML b/public/Wb/Adam/Opt/Utils/Find.HC.HTML new file mode 100755 index 0000000..0f97350 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/Find.HC.HTML @@ -0,0 +1,288 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+#define FND_REPLACE     0
+#define FND_SKIP        1
+#define FND_ALL         2
+#define FND_ED          3
+#define FND_ABORT_FILE  4
+#define FND_SKIP_FILE   5
+
+I64 PopUpFindMenu()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$CM+LX,2,4$$BT,\"REPLACE\",LE=FND_REPLACE$"
+        "$CM+LX,22,0$$BT,\"SKIP\",LE=FND_SKIP$"
+        "$CM+LX,2,4$$BT,\"ALL\",LE=FND_ALL$"
+        "$CM+LX,22,0$$BT,\"ABORT ALL\",LE=DOCM_CANCEL$"
+        "$CM+LX,2,4$$BT,\"EDIT\",LE=FND_ED$"
+        "$CM+LX,22,0$$BT,\"ABORT FILE\",LE=FND_ABORT_FILE$"
+        "$CM+LX,2,4$$BT,\"SKIP FILE\",LE=FND_SKIP_FILE$\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 FindFile(U8 *needle_str,U8 *haystack_filename,
+        I64 *_fuf_flags,U8 *replace_text)
+{//Have you confused with FileFind()?
+  Bool first_on_line,write_this_file=FALSE,cont=!Bt(_fuf_flags,FUf_CANCEL);
+  U8 *src,*dst,*dst2,*name_buf=NULL;
+  I64 i,j,plen,rlen,dlen,cnt=0,old_flags,ss_flags;
+  CDoc *cur_l,*doc=DocRead(haystack_filename,
+        DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e;
+
+  if (Bt(_fuf_flags,FUf_IGNORE))
+    ss_flags=SFF_IGNORE_CASE;
+  else
+    ss_flags=0;
+  if (Bt(_fuf_flags,FUf_WHOLE_LABELS))
+    ss_flags|=SFG_WHOLE_LABELS;
+  if (Bt(_fuf_flags,FUf_WHOLE_LABELS_BEFORE))
+    ss_flags|=SFF_WHOLE_LABELS_BEFORE;
+  if (Bt(_fuf_flags,FUf_WHOLE_LABELS_AFTER))
+    ss_flags|=SFF_WHOLE_LABELS_AFTER;
+
+  plen=StrLen(needle_str);
+  if (replace_text)
+    rlen=StrLen(replace_text);
+  doc_e=doc->head.next;
+  while (doc_e!=doc && cont) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      src=doc_e->tag;
+      first_on_line=TRUE;
+      while (src && cont) {
+        if (src=StrFind(needle_str,src,ss_flags)) {
+          cnt++;
+          if (first_on_line || Bt(_fuf_flags,FUf_REPLACE)) {
+            first_on_line=FALSE;
+            PutFileLink(haystack_filename,,doc_e->y+1,TRUE);
+            name_buf=MStrPrint("%s,%d",haystack_filename,doc_e->y+1);
+            if (cur_l=DocPut) {
+              old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+              cur_l->flags|=DOCF_PLAIN_TEXT;
+            }
+            " %s\n",doc_e->tag;
+            if (cur_l)
+              cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+          }
+          if (Bt(_fuf_flags,FUf_REPLACE)) {
+            if (Bt(_fuf_flags,FUf_ALL))
+              i=FND_ALL;
+            else {
+              i=PopUpFindMenu;
+              if (i<0) {
+                LBts(_fuf_flags,FUf_CANCEL);
+                cont=FALSE;
+                write_this_file=FALSE;
+              } else if (i==FND_ALL)
+                LBts(_fuf_flags,FUf_ALL);
+              else if (i==FND_ABORT_FILE) {
+                cont=FALSE;
+                write_this_file=FALSE;
+              } else if (i==FND_SKIP_FILE)
+                cont=FALSE;
+            }
+            if (i==FND_REPLACE || i==FND_ALL) {
+              dlen=StrLen(doc_e->tag);
+              dst=MAlloc(dlen+1+rlen-plen);
+              dst2=dst;
+              j=src-doc_e->tag;
+              for (i=0;i<j;i++)
+                *dst++=doc_e->tag[i];
+              for (i=0;i<rlen;i++)
+                *dst++=replace_text[i];
+              src=dst;
+              for (i=j+plen;i<=dlen;i++)
+                *dst++=doc_e->tag[i];
+              Free(doc_e->tag);
+              doc_e->tag=dst2;
+              if (cur_l=DocPut) {
+                old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+                cur_l->flags|=DOCF_PLAIN_TEXT;
+              }
+              "%12s,%04d*%s\n",haystack_filename,doc_e->y+1,dst2;
+              if (cur_l)
+                cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+              write_this_file=TRUE;
+            } else {
+              src++;
+              if (i==FND_ED) {
+                Free(name_buf);
+                name_buf=StrNew(doc->filename.name);
+                doc->flags&=~DOCF_NO_CURSOR;
+                doc->cur_entry=doc_e;
+                doc->cur_col=doc_e->min_col;
+                DocWrite(doc);
+                DocDel(doc);
+                "Wrote:%s\n",name_buf;
+                Ed(name_buf);
+                doc=DocRead(name_buf, DOCF_PLAIN_TEXT_TABS);
+                doc_e=doc->cur_entry;
+                if (doc_e->last!=doc) doc_e=doc_e->last;
+                src=NULL;
+                write_this_file=FALSE;
+              }
+            }
+          } else
+            src++;
+          Free(name_buf);
+          name_buf=NULL;
+        }
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  if (write_this_file) {
+    DocWrite(doc);
+    "Wrote:%s\n",doc->filename.name;
+  }
+  DocDel(doc);
+  return cnt;
+}
+
+public I64 Find(U8 *needle_str,U8 *files_find_mask="*",
+        U8 *fu_flags=NULL,U8 *replace_text=NULL)
+{/*Find occurrences of a string in files.
+This does not do regular expressions.
+Anyway, it's good for searching and replacing.
+Let's say it stands for global replace ;-)
+
+"+r" =recurse
+"+i" =ignore case
+"+l" =whole labels only.
+This will check for a nonlabel character before
+and after.  If you have a var, "dd" and don't
+want to match words like "Add", you
+set this flag and it will see that the characters
+before or after "dd" are label characters.
+"+lb"=only checks for label chars before.
+"+la"=only checks for label chars after.
+*/
+  I64 cnt=0,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+i+f+F+T");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (fuf_flags&~(FUG_FILES_FIND|FUF_IGNORE|FUF_ALL|
+        FUF_WHOLE_LABELS|FUF_WHOLE_LABELS_BEFORE|FUF_WHOLE_LABELS_AFTER))
+    throw('FUF');
+  LBEqu(&fuf_flags,FUf_REPLACE,replace_text);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND);
+  fuf_flags&=FUF_ALL|FUF_REPLACE|FUF_IGNORE|FUF_WHOLE_LABELS|
+        FUF_WHOLE_LABELS_BEFORE|FUF_WHOLE_LABELS_AFTER;
+  while (tmpde && !Bt(&fuf_flags,FUf_CANCEL)) {
+    cnt+=FindFile(needle_str,tmpde->full_name,&fuf_flags,replace_text);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return cnt;
+}
+
+public I64 FileOcc(U8 *needle_str,
+        U8 *files_find_mask="*",U8 *fu_flags="+r+i+l")
+{/*Silently return occurrences of a string in files.
+"+r"=recurse
+"+i"=ignore case
+"+l"=whole labels only.
+"+lb"=only checks for label chars before.
+"+la"=only checks for label chars after.
+*/
+  I64 cnt=0;
+  Bool old_silent=Silent(TRUE);
+  cnt=Find(needle_str,files_find_mask,fu_flags);
+  Silent(old_silent);
+  return cnt;
+}
+
+class CFind
+{
+  U8    find_text[STR_LEN] format "$DA-P,"
+        "A=\"FIND        :%s\"$\n";
+  U8    replace_text[STR_LEN] format "$DA-P,"
+        "A=\"REPLACE     :%s\"$\n";
+  Bool  replace         format "$CB,\"REPLACE\"$\n";
+  Bool  match_case      format "$CB,\"MATCH CASE\"$\n";
+  Bool  whole_labels    format "$CB,\"WHOLE LABELS\"$\n";
+  U8    filemask[STR_LEN] format "$DA-P,A=\"FILE MASK   :%s\"$\n";
+  Bool  recurse         format "$CB,\"RECURSE\"$\n";
+};
+
+I64 FindWiz()
+{
+  CDoc *doc;
+  U8 buf[32],*dir,*st;
+  CFind *g=CAlloc(sizeof(CFind));
+  I64 res=0;
+  g->recurse=TRUE;
+  StrCpy(g->filemask,FILEMASK_TXT);
+  if (doc=DocPut) {
+    StrCpy(g->find_text,doc->find_replace->find_text);
+    StrCpy(g->replace_text,doc->find_replace->replace_text);
+    g->replace=doc->find_replace->replace;
+    g->match_case=doc->find_replace->match_case;
+    g->whole_labels=doc->find_replace->whole_labels;
+  }
+  if (DocForm(g,,0,"$PURPLE$$TX+CX,\"Find\"$\n$FG$")) {
+    if (doc) {
+      StrCpy(doc->find_replace->find_text,g->find_text);
+      StrCpy(doc->find_replace->replace_text,g->replace_text);
+      doc->find_replace->replace=g->replace;
+      doc->find_replace->match_case=g->match_case;
+      doc->find_replace->whole_labels=g->whole_labels;
+    }
+    dir=PopUpPickDir;
+    if (*dir) {
+      *buf=0;
+      if (g->match_case)
+        CatPrint(buf,"-i");
+      if (!g->recurse)
+        CatPrint(buf,"-r");
+      if (g->whole_labels)
+        CatPrint(buf,"+l");
+      if (g->replace)
+        st=MStrPrint("\"$$WW+H,1$$\";Cd(\"%s\");"
+              "Find(\"%Q\",\"%Q\",\"%Q\",\"%Q\");UserTaskCont;",
+              dir,g->find_text,g->filemask,buf,g->replace_text);
+      else
+        st=MStrPrint("\"$$WW+H,1$$\";Cd(\"%s\");"
+              "Find(\"%Q\",\"%Q\",\"%Q\");UserTaskCont;",
+              dir,g->find_text,g->filemask,buf);
+      res=PopUp(st);
+    }
+    Free(dir);
+  }
+  Free(g);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/HeapLog.HC.HTML b/public/Wb/Adam/Opt/Utils/HeapLog.HC.HTML new file mode 100755 index 0000000..9f1e398 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/HeapLog.HC.HTML @@ -0,0 +1,242 @@ + + + + + + + + + + + +
+#help_index "Debugging/Heap;Memory/Debugging"
+#help_file "::/Doc/HeapDbg"
+
+#define HL_CALLER_DEPTH 5 //Feel free to change this.
+#define HL_HASH_SIZE    0x1000
+
+class CHeapLog
+{
+  CHeapLog *next,*last;
+  union {
+    U8 *addr;
+    I64 size;
+  }
+  I64 cnt;
+  U8 *caller[HL_CALLER_DEPTH];
+};
+
+class CHeapLogHash
+{
+  CHeapLog *next,*last;
+};
+
+CHeapCtrl *heaplog_hc_watched,*heaplog_hc=NULL;
+CHeapLogHash *heaplog_head=NULL;
+
+U0 HeapLogMAlloc(U8 *addr)
+{
+  CHeapLog *tmphl;
+  I64 i;
+  if (MHeapCtrl(addr)==heaplog_hc_watched) {
+    tmphl=MAlloc(sizeof(CHeapLog),heaplog_hc);
+    tmphl->addr=addr;
+    for (i=0;i<HL_CALLER_DEPTH;i++)
+      tmphl->caller[i]=Caller(i+2);
+    i=addr>>3 &(HL_HASH_SIZE-1);
+    PUSHFD
+    CLI
+    while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+      PAUSE
+    QueIns(tmphl,heaplog_head[i].last);
+    LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+    POPFD
+  }
+}
+
+U0 HeapLogFree(U8 *addr)
+{
+  I64 i;
+  CHeapLog *tmphl;
+  if (!addr) return;
+  if (MHeapCtrl(addr)==heaplog_hc_watched) {
+    i=addr>>3 &(HL_HASH_SIZE-1);
+    PUSHFD
+    CLI
+    while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+      PAUSE
+    tmphl=heaplog_head[i].next;
+    while (tmphl!=&heaplog_head[i]) {
+      if (addr==tmphl->addr) {
+        QueRem(tmphl);
+        LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+        POPFD
+        Free(tmphl);
+        return;
+      }
+      tmphl=tmphl->next;
+    }
+    LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+    POPFD
+  }
+}
+
+public Bool HeapLog(Bool val=ON,CTask *task=NULL)
+{//Turn on.  Collect data.  Call HeapLogAddrRep() or  HeapLogSizeRep().
+  I64 i;
+  if (val) {
+    if (Bt(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+      "HeapLog Already Active\n";
+      return TRUE;
+    } else {
+      if (!task) task=Fs;
+      if (TaskValidate(task))
+        heaplog_hc_watched=task->data_heap;
+      else
+        heaplog_hc_watched=task;//Actually, not a task, must be a HeapCtrl.
+      PUSHFD
+      CLI
+      while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+        PAUSE
+      heaplog_hc=HeapCtrlInit(,,sys_data_bp);
+      ext[EXT_HEAPLOG_MALLOC]=&HeapLogMAlloc;
+      ext[EXT_HEAPLOG_FREE]=&HeapLogFree;
+      heaplog_head=MAlloc(sizeof(CHeapLogHash)*HL_HASH_SIZE,heaplog_hc);
+      for (i=0;i<HL_HASH_SIZE;i++)
+        QueInit(&heaplog_head[i]);
+      LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+      POPFD
+      LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);
+      return FALSE;
+    }
+  } else {
+    if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+      "HeapLog Not Active\n";
+      return FALSE;
+    } else {
+      HeapCtrlDel(heaplog_hc);
+      heaplog_head=heaplog_hc=NULL;
+      ext[EXT_HEAPLOG_MALLOC]=NULL;
+      ext[EXT_HEAPLOG_FREE]=NULL;
+      return TRUE;
+    }
+  }
+}
+
+public U0 HeapLogAddrRep(Bool leave_it=OFF)
+{//Call HeapLog() first and collect data.
+  I64 i,j,total=0;
+  CHeapLog *tmphl,hl;
+  if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+    "HeapLog Not Active\n";
+    return;
+  }
+  "$WW,0$";
+  while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+    PAUSE
+  for (i=0;i<HL_HASH_SIZE;i++) {
+    tmphl=heaplog_head[i].next;
+    while (tmphl!=&heaplog_head[i]) {
+//Take snapshot in case modified. (while we work)
+      MemCpy(&hl,tmphl,sizeof(CHeapLog));
+      "$PURPLE$%08X$FG$ %08X",MSize(hl.addr),hl.addr;
+      for (j=0;j<HL_CALLER_DEPTH;j++)
+        " %P",hl.caller[j];
+      '\n';
+      total+=MSize(hl.addr);
+      tmphl=hl.next;
+    }
+  }
+  LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+  "\n$LTRED$Total:%08X$FG$\n",total;
+  LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);
+  if (!leave_it)
+    HeapLog(OFF);
+}
+
+public U0 HeapLogSizeRep(Bool leave_it=OFF)
+{//Call HeapLog() first and collect data.
+  I64 i,j,k,total=0;
+  CHeapLog *tmphla,hla,*tmphls,*tmphls1;
+  CHeapLogHash *size_head;
+  if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+    "HeapLog Not Active\n";
+    return;
+  }
+
+  size_head=MAlloc(sizeof(CHeapLogHash)*HL_HASH_SIZE,heaplog_hc);
+  for (i=0;i<HL_HASH_SIZE;i++)
+    QueInit(&size_head[i]);
+
+  "$WW,0$";
+  while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+    PAUSE
+  for (i=0;i<HL_HASH_SIZE;i++) {
+    tmphla=heaplog_head[i].next;
+    while (tmphla!=&heaplog_head[i]) {
+//Take snapshot in case modified. (while we work)
+      MemCpy(&hla,tmphla,sizeof(CHeapLog));
+      k=(MSize(hla.addr)>>3+hla.caller[0])&(HL_HASH_SIZE-1);
+      tmphls=size_head[k].next;
+      while (tmphls!=&size_head[k]) {
+        if (MSize(hla.addr)==tmphls->size) {
+          for (j=0;j<HL_CALLER_DEPTH;j++)
+            if (hla.caller[j]!=tmphls->caller[j])
+              goto hl_next;
+          tmphls->cnt++;
+          goto hl_found;
+        }
+hl_next:
+        tmphls=tmphls->next;
+      }
+      tmphls=MAlloc(sizeof(CHeapLog),heaplog_hc);
+      MemCpy(tmphls,&hla,sizeof(CHeapLog));
+      tmphls->cnt=1;
+      tmphls->size=MSize(hla.addr);
+      QueIns(tmphls,size_head[k].last);
+hl_found:
+      tmphla=hla.next;
+    }
+  }
+  LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+
+  for (i=0;i<HL_HASH_SIZE;i++) {
+    tmphls=size_head[i].next;
+    while (tmphls!=&size_head[i]) {
+      tmphls1=tmphls->next;
+      "%08X*%08X=%08X",tmphls->size,tmphls->cnt,tmphls->size*tmphls->cnt;
+      for (j=0;j<HL_CALLER_DEPTH;j++)
+        " %P",tmphls->caller[j];
+      '\n';
+      total+=tmphls->size*tmphls->cnt;
+      Free(tmphls);
+      tmphls=tmphls1;
+    }
+  }
+  Free(size_head);
+
+  "\n$LTRED$Total:%08X$FG$\n",total;
+  LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);
+  if (!leave_it)
+    HeapLog(OFF);
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/LineRep.HC.HTML b/public/Wb/Adam/Opt/Utils/LineRep.HC.HTML new file mode 100755 index 0000000..ac646b8 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/LineRep.HC.HTML @@ -0,0 +1,140 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+I64 LineRep1(CDirEntry *tmpde)
+{
+  CDoc *doc;
+  I64 res=0,i;
+  while (tmpde) {
+    i=0;
+    if (tmpde->attr&RS_ATTR_DIR)
+      i=LineRep1(tmpde->sub);
+    else {
+      doc=DocRead(tmpde->full_name);
+      if (doc->head.next!=doc)
+        i=doc->head.last->y+2;
+      DocDel(doc);
+    }
+    tmpde->user_data=i;
+    res+=i;
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+U0 LineRep2(CDoc *doc,CDirEntry *tmpde)
+{
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR) {
+      DocPrint(doc,"%8,d $TR+C,\"%s\"$\n$ID,2$",tmpde->user_data,tmpde->name);
+      LineRep2(doc,tmpde->sub);
+      DocPrint(doc,"$ID,-2$");
+    } else
+      DocPrint(doc,"%8,d $LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->user_data,tmpde->name,tmpde->full_name);
+    tmpde=tmpde->next;
+  }
+}
+public I64 LineRep(U8 *files_find_mask="/*",U8 *fu_flags=NULL)
+{//Source line-of-code count report.
+  I64 fuf_flags=0,res=0;
+  CDoc *doc=DocNew;
+  CDirEntry *tmpde1=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+S");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (tmpde1=FilesFind(files_find_mask,fuf_flags)) {
+    res=LineRep1(tmpde1);
+    DocPrint(doc,"%8,d $TR+C,\"%s\"$\n$ID,2$",res,files_find_mask);
+    LineRep2(doc,tmpde1);
+    DocPrint(doc,"$ID,-2$");
+    DirTreeDel(tmpde1);
+  }
+  DocInsDoc(DocPut,doc);
+  DocDel(doc);
+  return res;
+}
+
+I64 SizeRep1(CDirEntry *tmpde,I64 *_fuf_flags)
+{
+  I64 res=0,i;
+  U8 buf[BLK_SIZE];
+  CDrv *dv;
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR)
+      i=SizeRep1(tmpde->sub,_fuf_flags);
+    else if ((i=tmpde->size) && Bt(_fuf_flags,FUf_EXPAND) &&
+          FileAttr(tmpde->name)&RS_ATTR_COMPRESSED) {
+      dv=Let2Drv(*tmpde->full_name);
+      BlkRead(dv,buf,Clus2Blk(dv,tmpde->clus),1);
+      i=(&buf)(CArcCompress *)->expanded_size;
+    }
+    tmpde->user_data=i;
+    res+=i;
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+U0 SizeRep2(CDoc *doc,CDirEntry *tmpde)
+{
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR) {
+      DocPrint(doc,"%10,d $TR+C,\"%s\"$\n$ID,2$",
+            tmpde->user_data,tmpde->name);
+      SizeRep2(doc,tmpde->sub);
+      DocPrint(doc,"$ID,-2$");
+    } else {
+      DocPrint(doc,"%10,d ",tmpde->user_data);
+      DocPrint(doc,"$LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->name,tmpde->full_name);
+    }
+    tmpde=tmpde->next;
+  }
+}
+public I64 SizeRep(U8 *files_find_mask="/*",U8 *fu_flags=NULL)
+{//Report file sizes. "+x" for expanded size of compressed files.
+  I64 fuf_flags=0,res=0;
+  CDoc *doc=DocNew;
+  CDirEntry *tmpde1=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND)) {
+    fuf_flags&=FUF_EXPAND;
+    res=SizeRep1(tmpde1,&fuf_flags);
+    DocPrint(doc,"%10,d $TR+C,\"%s\"$\n$ID,2$",res,files_find_mask);
+    SizeRep2(doc,tmpde1);
+    DocPrint(doc,"$ID,-2$");
+    DirTreeDel(tmpde1);
+  }
+  DocInsDoc(DocPut,doc);
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/LinkChk.HC.HTML b/public/Wb/Adam/Opt/Utils/LinkChk.HC.HTML new file mode 100755 index 0000000..e36417e --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/LinkChk.HC.HTML @@ -0,0 +1,110 @@ + + + + + + + + + + + +
+#help_index "Debugging;Cmd Line (Typically)"
+
+I64 LinkChkDoc(CDoc *doc,I64 *_fuf_flags)
+{
+  U8 *st;
+  Bool found,unlock=DocLock(doc);
+  CDoc *old_doc;
+  CDocEntry *doc_e=doc->head.next;
+  I64 res=0;
+  while (doc_e!=doc) {
+    if (ScanKey) {
+      LBts(_fuf_flags,FUf_CANCEL);
+      break;
+    }
+    if (st=DocEntryLink(doc,doc_e)) {
+      old_doc=DocPut;
+      DocLock(old_doc);
+      Fs->put_doc=doc;
+      found=DocLinkChk(doc,st);
+      Fs->put_doc=old_doc;
+      DocUnlock(old_doc);
+      if (!found) {
+        PutFileLink(doc->filename.name,,doc_e->y);
+        "$RED$ %04d:%s\n$FG$",doc_e->y,st;
+        res++;
+      }
+      Free(st);
+    } else if (doc_e->type_u8==DOCT_ERROR) {
+      PutFileLink(doc->filename.name,,doc_e->y);
+      "$RED$ Doc Error\n$FG$";
+      res++;
+    }
+    doc_e=doc_e->next;
+  }
+  if (unlock) DocUnlock(doc);
+  return res;
+}
+
+I64 LinkChkFile(U8 *filename,I64 *_fuf_flags)
+{
+  I64 res;
+  CDoc *doc=DocRead(filename,DOCF_NO_CURSOR);
+  res=LinkChkDoc(doc,_fuf_flags);
+  DocDel(doc);
+  return res;
+}
+public I64 LinkChk(U8 *files_find_mask="/*",U8 *fu_flags=NULL)
+{//Check documents for broken file links.
+  I64 fuf_flags=0,res=0;
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st;
+  progress2_max=1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+$+f+F+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde && !Bt(&fuf_flags,FUf_CANCEL)) {
+
+    st=MStrPrint("Before %s Broke:%d",tmpde->full_name,res);
+    if (StrLen(st)>PROGRESS_DESC_LEN-1)
+      st[PROGRESS_DESC_LEN-1]=0;
+    StrCpy(progress2_desc,st);
+    Free(st);
+    Yield;
+
+    res+=LinkChkFile(tmpde->full_name,&fuf_flags);
+
+    st=MStrPrint("After %s Broke:%d",tmpde->full_name,res);
+    if (StrLen(st)>PROGRESS_DESC_LEN-1)
+      st[PROGRESS_DESC_LEN-1]=0;
+    StrCpy(progress2_desc,st);
+    Free(st);
+    Yield;
+
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  progress2_max=0;
+  return res;
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/MakeUtils.HC.HTML b/public/Wb/Adam/Opt/Utils/MakeUtils.HC.HTML new file mode 100755 index 0000000..c570100 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/MakeUtils.HC.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Diff"
+#include "Find"
+#include "HeapLog"
+#include "LineRep"
+#include "LinkChk"
+#include "MemRep"
+#include "Merge"
+#include "Profiler"
+#include "StrUtils"
+#include "DocUtils"
+#include "ToDolDoc"
+#include "ToTXT"
+#include "TOS"
+Cd("..");;
+
+ diff --git a/public/Wb/Adam/Opt/Utils/MemRep.HC.HTML b/public/Wb/Adam/Opt/Utils/MemRep.HC.HTML new file mode 100755 index 0000000..a48593e --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/MemRep.HC.HTML @@ -0,0 +1,262 @@ + + + + + + + + + + + +
+#help_index "Info;Memory/Info;Cmd Line (Typically)"
+
+I64 TSSSize(CTSS *tss)
+{
+  return MSize2(tss)+MSize2(tss->st0)+MSize2(tss->st1)+MSize2(tss->st2);
+}
+
+I64 PenBrushesSize()
+{
+  I64 res=0,i;
+  for (i=0;i<GR_PEN_BRUSHES_NUM;i++)
+    res+=DCSize(gr.pen_brushes[i])+DCSize(gr.collision_pen_brushes[i])+
+          DCSize(gr.even_pen_brushes[i])+DCSize(gr.odd_pen_brushes[i]);
+  return res;
+}
+
+I64 ScrnZoomTablesSize()
+{
+  I64 res=0,i;
+  for (i=1;i<=GR_SCRN_ZOOM_MAX;i++)
+    res+=MSize2(gr.scrn_zoom_tables[i]);
+  return res;
+}
+
+I64 TaskStkSize(CTask *task)
+{
+  CTaskStk *tmps=task->stk;
+  I64 res=0;
+  while (tmps) {
+    res+=MSize2(tmps);
+    tmps=tmps->next_stk;
+  }
+  return res;
+}
+
+I64 TaskQueSize(CTask *task)
+{
+  CJob *tmpc,*tmpc1;
+  I64 res=0;
+  PUSHFD
+  CLI
+  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+
+  tmpc1=&task->srv_ctrl.next_waiting;
+  tmpc=tmpc1->next;
+  while (tmpc!=tmpc1) {
+    res+=MSize2(tmpc)+MSize2(tmpc->aux_str);
+    tmpc=tmpc->next;
+  }
+
+  tmpc1=&task->srv_ctrl.next_done;
+  tmpc=tmpc1->next;
+  while (tmpc!=tmpc1) {
+    res+=MSize2(tmpc)+MSize2(tmpc->aux_str);
+    tmpc=tmpc->next;
+  }
+
+  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  POPFD
+  return res;
+}
+
+I64 BlkDevsSize()
+{
+  I64 i,j,res=MSize2(blkdev.blkdevs);
+  CBlkDev *bd;
+  for (i=0;i<BLKDEVS_NUM;i++) {
+    bd=&blkdev.blkdevs[i];
+    if (bd->bd_signature==BD_SIGNATURE_VAL) {
+      j=(bd->max_blk+1)<<BLK_SIZE_BITS;
+      if (bd->type==BDT_RAM)
+        "RAMDsk %C\t:%010X/%010X\n",
+              bd->first_drv_let,j-DrvUnused(bd->first_drv_let),j;
+      res+=MSize2(bd->dev_id_record);
+    }
+  }
+  return res;
+}
+
+I64 DrvsSize()
+{
+  I64 i,res=MSize2(blkdev.drvs);
+  for (i=0;i<DRVS_NUM;i++)
+    res+=MSize2(blkdev.drvs[i].cur_fat_blk)+MSize2(blkdev.drvs[i].fis);
+  return res;
+}
+
+Bool MemRepTask(CTask *task,Bool override_validate=FALSE)
+{
+  I64 i,j,k,m,n;
+  CDoc *pdoc,*ddoc,*bdoc;
+  CCmpCtrl *cc;
+  CMathODE *o;
+  CCPU *c;
+  CTask *task1;
+
+  if (!override_validate && !TaskValidate(task))
+    return FALSE;
+  if (task==Fs)
+    task->rsp=GetRSP;
+  "$BLACK$%-27t$Q#%08X$FG$\n",task->task_title,task;
+  "$ID,2$Heap\t:%010X/%010X\n",TaskMemUsed(task,override_validate),
+        TaskMemAlloced(task,override_validate);
+
+  i=UnusedStk(task);
+  j=TaskStkSize(task);
+  if (0<=i<=task->stk->stk_size)
+    "Stk\t\t:%010X/%010X\n",j-i,j;
+  else
+    "Stk\t\t:$RED$$BK,1$Overflow$BK,0$$FG$/%010X\n",j;
+
+  "HashTable\t:%010X\n",HashTableSize2(task->hash_table);
+  "FPU\t\t:%010X\n",MSize2(task->fpu_mmx);
+  "DirCur\t:%010X\n",MSize2(task->cur_dir);
+
+  if (pdoc=DocPut(task))
+    "PutDoc\t:%010X\n",DocSize(pdoc);
+  if ((ddoc=DocDisplay(task)) && pdoc!=ddoc)
+    "DisplayDoc\t:%010X\n",DocSize(ddoc);
+  if (bdoc=DocBorder(task))
+    "BorderDoc\t:%010X\n",DocSize(bdoc);
+
+  cc=task->next_cc;
+  while (cc!=&task->next_cc) {
+    "CmpCtrl\t:%010X\n",CmpCtrlSize(cc);
+    cc=cc->next;
+  }
+
+  o=task->next_ode;
+  while (o!=&task->next_ode) {
+    "CMathODE\t:%010X\n",ODESize(o);
+    o=o->next;
+  }
+
+  if (task==sys_winmgr_task) {
+    "gr.pen_brushes\t:%010X\n",PenBrushesSize;
+    "gr.scrn_zoom_tbles\t:%010X\n",ScrnZoomTablesSize;
+    "scrncast.dc\t:%010X\n",DCSize(scrncast.dc);
+    "scrncast.dc2_alias\t:%010X\n",DCSize(scrncast.dc2_alias);
+  } else if (task==adam_task) {
+    j=0;k=0;m=0;n=0;
+    for (i=0;i<mp_cnt;i++) {
+      c=&cpu_structs[i];
+      k+=TSSSize(c->tss);
+      task1=c->seth_task;
+      do {
+        if (task1!=adam_task) {//adam task located in Kernel mem
+          j+=MSize2(task1);
+          m+=MSize2(task1->code_heap);
+          if (task1->data_heap!=task1->code_heap)
+            m+=MSize2(task1->code_heap);
+        }
+        n+=TaskQueSize(task1);
+        task1=task1->next_task;
+      } while (task1!=c->seth_task);
+      task1=c->idle_task;
+      j+=MSize2(task1);
+      m+=MSize2(task1->code_heap);
+      if (task1->data_heap!=task1->code_heap)
+        m+=MSize2(task1->code_heap);
+    }
+    "TaskStructs\t:%010X\n",j;
+    "TSSes\t:%010X\n",k;
+    "HeapCtrls\t:%010X\n",m;
+    if (n)
+      "TaskQues\t:%010X\n",n;
+    "BlkDevs\t:%010X\n",BlkDevsSize;
+    "Drvs\t:%010X\n",DrvsSize;
+    if (blkdev.cache_base)
+      "DskCache\t:%010X\n",
+            MSize2(blkdev.cache_base)+MSize2(blkdev.cache_hash_table)+
+            MSize2(blkdev.cache_ctrl);
+    "Clip\t:%010X\n",DocSize(sys_clip_doc);
+    "AutoComplete:%010X\n",CallExtStr("AutoCompleteSize");
+    "gr.to_8_bits\t:%010X\n",MSize2(gr.to_8_bits);
+    "gr.to_8_colors\t:%010X\n",MSize2(gr.to_8_colors);
+    "gr.text_base\t:%010X\n",MSize2(gr.text_base);
+    "gr.vga_text_cache\t:%010X\n",MSize2(gr.vga_text_cache);
+    "gr.win_z_buf\t:%010X\n",MSize2(gr.win_z_buf)+
+          MSize2(gr.win_uncovered_bitmap);
+    "gr.dc\t\t:%010X\n",DCSize(gr.dc);
+    "gr.dc1\t\t:%010X\n",DCSize(gr.dc1);
+    "gr.dc2\t\t:%010X\n",DCSize(gr.dc2);
+    "gr.dc_cache\t\t:%010X\n",DCSize(gr.dc_cache);
+    "gr.scrn_image\t:%010X\n",DCSize(gr.scrn_image);
+    "gr.zoomed_dc\t:%010X\n",DCSize(gr.zoomed_dc);
+  }
+  "$ID,-2$";
+  return TRUE;
+}
+
+public U0 MemRep()
+{//Memory usage report.
+  I64 i;
+  CTask *task;
+  CCPU *c;
+  CBinFile *bfh=mem_boot_base-sizeof(CBinFile);
+  bfh(I64)+=bfh->file_size-1;
+
+  "$BLACK$Low Memory\t:0000100000$FG$\n$ID,2$";
+  "Kernel\t:%010X-%010X\n",mem_boot_base-sizeof(CBinFile),bfh;
+
+  "VGA\t\t:00000A0000-00000BFFFF\n";
+  "$ID,-2$$BLACK$High Memory\t:0000100000-%010X$FG$\n",
+        mem_heap_limit;
+  "SYS_FIXED_AREA\t:%010X-%010X\n",
+        SYS_FIXED_AREA,SYS_FIXED_AREA+sizeof(CSysFixedArea)-1;
+
+  if (sys_data_bp) {
+    "$BLACK$Code Heap\t:%010X/%010X$FG$\n",
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s;
+    "$BLACK$Data Heap\t:%010X/%010X$FG$\n",
+          sys_data_bp->used_u8s,sys_data_bp->alloced_u8s;
+  } else
+    "$BLACK$Code/Data Heap\t:%010X/%010X$FG$\n",
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s;
+
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    "$PURPLE$CPU%d$FG$\n$ID,2$",i;
+    task=c->seth_task;
+    do {
+      if (!MemRepTask(task))
+        break;
+      task=task->next_task;
+    } while (task!=c->seth_task);
+    MemRepTask(c->idle_task,TRUE);
+    "$ID,-2$";
+  }
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/Merge.HC.HTML b/public/Wb/Adam/Opt/Utils/Merge.HC.HTML new file mode 100755 index 0000000..a4b2059 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/Merge.HC.HTML @@ -0,0 +1,108 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+CDirEntry MGFind(CDirEntry *needle_entry,CDirEntry *haystack_lst)
+{
+  while (haystack_lst) {
+    if (!StrCmp(needle_entry->name,haystack_lst->name))
+      return haystack_lst;
+    haystack_lst=haystack_lst->next;
+  }
+  return NULL;
+}
+
+U0 Merge2(CDirEntry *tmpde1,CDirEntry *tmpde2,I64 *_fuf_flags,I64 *_df_flags)
+{
+  CDirEntry *tmpde;
+  while (tmpde1 && !(*_df_flags & DF_ABORT_ALL_FILES)) {
+    tmpde=MGFind(tmpde1,tmpde2);
+    if (!tmpde)
+      "$BROWN$Does Not Exist:%s$FG$\n",tmpde1->full_name;
+    else {
+      if (tmpde1->attr & RS_ATTR_DIR)
+        Merge2(tmpde1->sub,tmpde->sub,_fuf_flags,_df_flags);
+      else {
+        if (AbsI64(tmpde1->datetime-tmpde->datetime)>CDATE_FREQ*2) {//slop
+          "%s",tmpde1->full_name;
+          '\n';
+          if (Bt(_fuf_flags,FUf_DIFF)) {
+            if (FilesFindMatch(tmpde1->full_name,FILEMASK_TXT))
+              Diff(tmpde->full_name,tmpde1->full_name,_df_flags);
+          }
+        }
+      }
+    }
+    tmpde1=tmpde1->next;
+  }
+}
+public U0 Merge(U8 *dst_files_find_mask="/*",U8 *src_files_find_mask="/*",
+  U8 *fu_flags=NULL)
+{/*Merge text files from one list into another.
+Report files whos date/time is different.
+
+"+d" will do Diff() on files and prompt to
+merge changes from source files into
+destination files.
+*/
+  I64 df_flags=0,fuf_flags=0;
+  CDirEntry *tmpde1=NULL,*tmpde2=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (fuf_flags&~(FUG_FILES_FIND|FUF_DIFF))
+    throw('FUF');
+  PrintWarn("This is based strictly on file dates.\n");
+  tmpde1=FilesFind(src_files_find_mask,fuf_flags&FUG_FILES_FIND);
+  tmpde2=FilesFind(dst_files_find_mask,fuf_flags&FUG_FILES_FIND);
+  fuf_flags&=FUF_DIFF;
+  Merge2(tmpde1,tmpde2,&fuf_flags,&df_flags);
+  DirTreeDel(tmpde1);
+  DirTreeDel(tmpde2);
+}
+
+#help_index "Utils;Cmd Line (Typically)"
+
+public U0 NewFiles(U8 *files_find_mask="/*",CDate cdt=0,U8 *fu_flags=NULL)
+{//Report files newer than a certain date.
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  if (!cdt) cdt=sys_compile_time;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (tmpde->datetime>cdt)
+      "%s\n",tmpde->full_name;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/Profiler.HC.HTML b/public/Wb/Adam/Opt/Utils/Profiler.HC.HTML new file mode 100755 index 0000000..33a7b46 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/Profiler.HC.HTML @@ -0,0 +1,133 @@ + + + + + + + + + + + +
+#help_index "Debugging/Profiler;Profiler;Cmd Line (Typically)/Profiler"
+#help_file "::/Doc/Profiler"
+
+#define PF_ARRAY_CNT 0x100000
+I64 pf_jiffy_start,pf_jiffy_end;
+I64 *pf_array=NULL;
+I64 pf_cpu=0;
+I64 pf_buf_in_ptr=0,pf_depth;
+I64 pf_prof_active=0;
+
+U0 ProfTimerInt(CTask *task)
+{//See profiler_timer_irq.
+  I64 i,k;
+  if (Bt(&pf_prof_active,0))
+    for (k=0;k<=pf_depth;k++) {
+      if (task==Gs->idle_task)
+        i=SYS_IDLE_PT;
+      else
+        i=TaskCaller(task,k,TRUE);
+      if (pf_buf_in_ptr<PF_ARRAY_CNT) {
+        pf_array[pf_buf_in_ptr++]=i;
+        pf_jiffy_end=cnts.jiffies;
+      }
+    }
+}
+
+public U0 Prof(I64 depth=0,I64 cpu_num=0)
+{/*Start collecting profiler statistics.
+Profilers report where time is spent
+by sampling RIP during the 1000Hz
+timer interrupt.
+
+Do a ProfRep(), (profiler report)
+after you have collected data.
+*/
+  if (!(0<=cpu_num<mp_cnt))
+    ST_ERR_ST "Invalid CPU\n";
+  else {
+    cpu_structs[pf_cpu].profiler_timer_irq=NULL;
+    pf_cpu=cpu_num;
+
+    pf_depth=depth;
+    pf_buf_in_ptr=0;
+    if (!pf_array)
+      pf_array=AMAlloc(sizeof(I64)*PF_ARRAY_CNT);
+    pf_jiffy_end=pf_jiffy_start=cnts.jiffies;
+    LBts(&pf_prof_active,0);
+    cpu_structs[pf_cpu].profiler_timer_irq=&ProfTimerInt;
+  }
+}
+
+I64 ProfCompare(U8 *i1,U8 *i2)
+{
+  return i1-i2;
+}
+
+public U0 ProfRep(I64 filter_cnt=1,Bool leave_it=OFF)
+{//Profiler report. Call Prof() first and collect data.
+  I64 i,hits,rip,last_rip=0,routine_total=0;
+  F64 total_time;
+  U8 buf[256],buf2[256],last_buf[256];
+  if (!LBtr(&pf_prof_active,0))
+    "Profiler Not Active\n";
+  if (!pf_buf_in_ptr)
+    "No Profiler Statistic\n";
+  else {
+    if (!(total_time=pf_jiffy_end-pf_jiffy_start))
+      total_time=1;
+    QSortI64(pf_array,pf_buf_in_ptr,&ProfCompare);
+    *last_buf=0;
+    for (i=0;i<pf_buf_in_ptr;i+=hits) {
+      rip=pf_array[i];
+      hits=0;
+      do hits++;
+      while (i+hits<pf_buf_in_ptr && pf_array[i+hits]==rip);
+
+      StrPrint(buf,"%p",rip);
+      StrFirstRem(buf,"+",buf2);
+      if (StrCmp(buf2,last_buf)) {
+        if (*last_buf && routine_total>=filter_cnt)
+          "$GREEN$%6.2f %08X:%s\n$FG$",100*routine_total/total_time,
+                routine_total,last_buf;
+        StrCpy(last_buf,buf2);
+        routine_total=0;
+      }
+      routine_total+=hits;
+      if (hits>=filter_cnt) {
+        "%6.2f %08X:%P\n",100*hits/total_time,hits,rip;
+        last_rip=rip;
+      }
+    }
+    if (*last_buf && routine_total>=filter_cnt)
+      "$GREEN$%6.2f %08X:%s\n$FG$",100*routine_total/total_time,
+            routine_total,last_buf;
+    "Total Time:%0.6fs\n",total_time/JIFFY_FREQ;
+    if (leave_it) {
+      cpu_structs[pf_cpu].profiler_timer_irq=&ProfTimerInt;
+      LBts(&pf_prof_active,0);
+    } else
+      cpu_structs[pf_cpu].profiler_timer_irq=NULL;
+  }
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/StrUtils.HC.HTML b/public/Wb/Adam/Opt/Utils/StrUtils.HC.HTML new file mode 100755 index 0000000..07755d0 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/StrUtils.HC.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+I64 DEPtrCompare(CDocEntry **e1,CDocEntry **e2)
+{
+  return StrCmp((*e1)->tag,(*e2)->tag);
+}
+
+public I64 Sort(U8 *_in_name,U8 *_out_name=NULL,
+        I64 entry_lines=1,Bool unique=FALSE)
+{//Sort lines of a text file. Removes blank lines.
+  U8 *in_name,*out_name,*st;
+  CDoc *doc;
+  CDocEntry *doc_e,*doc_e1,**a;
+  I64 i,j,cnt=0,res;
+
+  if (!_in_name) return 0;
+  in_name=ExtDft(_in_name,"DD.Z");
+  if (_out_name)
+    out_name=ExtDft(_out_name,"DD.Z");
+  else
+    out_name=StrNew(in_name);
+
+  doc=DocRead(in_name,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      cnt++;
+    doc_e=doc_e->next;
+  }
+  a=MAlloc(cnt*sizeof(CDocEntry *));
+  doc_e=doc->head.next;
+  i=0;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (doc_e->type_u8==DOCT_TEXT) {
+      QueRem(doc_e);
+      a[i++]=doc_e;
+    } else
+      DocEntryDel(doc,doc_e);
+    doc_e=doc_e1;
+  }
+  QSort(a,cnt/entry_lines,entry_lines*sizeof(CDocEntry *),&DEPtrCompare);
+
+  res=0;
+  st=NULL;
+  for (i=0;i<cnt;) {
+    if (!unique || !st || StrCmp(a[i]->tag,st)) {
+      st=a[i]->tag;
+      for (j=0;j<entry_lines && i<cnt;j++,i++) {
+        QueIns(a[i],doc->head.last);
+        doc->cur_entry=&doc->head;
+        doc->cur_col=0;
+        DocPrint(doc,"\n");
+      }
+      res++;
+    } else
+      for (j=0;j<entry_lines && i<cnt;j++,i++) {
+        QueIns(a[i],doc->head.last);
+        DocEntryDel(doc,a[i]);
+      }
+  }
+  StrCpy(doc->filename.name,out_name);
+  DocWrite(doc);
+
+  Free(a);
+  DocDel(doc);
+  Free(in_name);
+  Free(out_name);
+  return res; //Num Entries
+}
+
+I64 DocWordsFile(CDoc *doc_out=NULL,U8 *filename,U32 *char_bmp)
+{
+  U8 *ptr,*ptr2;
+  I64 res=0,ch;
+  CDoc *doc_in=DocRead(filename);
+  CDocEntry *doc_e=doc_in->head.next;
+  while (doc_e!=doc_in) {
+    if (doc_e->de_flags & DOCEF_TAG) {
+      ptr=doc_e->tag;
+      while (*ptr) {
+        while (*ptr && !Bt(char_bmp,*ptr))
+          ptr++;
+
+        ptr2=ptr;
+        while (*ptr && Bt(char_bmp,*ptr))
+          ptr++;
+
+        ch=*ptr;
+        *ptr=0;
+        if (*ptr2) {
+          DocPrint(doc_out,"%s\n",ptr2);
+          res++;
+        }
+        *ptr=ch;
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc_in);
+  return res;
+}
+public I64 Words(U8 *files_find_mask="*",U32 *char_bmp=char_bmp_alpha,
+        U8 *fu_flags=NULL)
+{//Break file into list of not-unique words.
+  I64 fuf_flags=0,res=0;
+  CDoc *doc_out=DocNew;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+T");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    res+=DocWordsFile(doc_out,tmpde->full_name,char_bmp);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  DocInsDoc(NULL,doc_out);
+  DocDel(doc_out);
+  return res;
+}
+
+I64 LongLinesFile(U8 *filename,I64 cols)
+{
+  I64 res=0;
+  CDoc *doc=DocRead(filename);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_NEW_LINE && doc_e->x>=cols+1)
+      res++;
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+  if (res) {
+    "%04d ",res;
+    PutFileLink(filename);
+    '\n';
+  }
+  return res;
+}
+public I64 LongLines(U8 *files_find_mask="*",I64 cols=80,U8 *fu_flags=NULL)
+{//Report files with lines of too many cols.
+  I64 res=0,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+S");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (LongLinesFile(tmpde->full_name,cols))
+      res++;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return res;
+}
+
+U0 SUFile(U8 *filename,I64 suf_flags,F64 indent_scale_factor)
+{//String utility on a single file
+//See SU Flags
+  U8 *dst;
+  Bool chged=FALSE;
+  I64 reduced=0;
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      dst=MStrUtil(doc_e->tag,suf_flags,indent_scale_factor);
+      if (StrCmp(dst,doc_e->tag)) {
+        reduced+=StrLen(doc_e->tag)-StrLen(dst);
+        chged=TRUE;
+        Free(doc_e->tag);
+        doc_e->tag=dst;
+      } else
+        Free(dst);
+    }
+    doc_e=doc_e->next;
+  }
+  if (chged) {
+    "Reduced %s by %d chars\n",filename,reduced;
+    DocWrite(doc);
+  }
+  DocDel(doc);
+}
+public U0 SU(U8 *files_find_mask,I64 suf_flags,U8 *fu_flags=NULL,
+        F64 indent_scale_factor=0)
+{//Apply StrUtil() on files.
+//You can convert spaces to tabs, for example,
+  //or removing trailing spaces on lines.
+  //See SUF Flags.
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F+T");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    SUFile(tmpde->full_name,suf_flags,indent_scale_factor);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+public U0 S2T(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Spaces to tabs.
+//Use "Hard Space" (SHIFT-SPACE) for spaces
+  //in string consts in your code.
+  SU(files_find_mask,SUF_S2T|SUF_REM_TRAILING,fu_flags);
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/TOS.HC.HTML b/public/Wb/Adam/Opt/Utils/TOS.HC.HTML new file mode 100755 index 0000000..67cdb2d --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/TOS.HC.HTML @@ -0,0 +1,107 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS"
+
+U0 TOSStaffIns()
+{//Completes TOS install from TOS_Staff.ISO
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  "$PURPLE$$TX+CX,\"Complete TOS install from TOS_Staff.ISO\"$$FG$\n\n\n\n";
+  InsRereg;
+
+  "\nDownload TOS_Supplemental1.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental2.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental3.ISO.C\tfrom http://www.templeos.org\n";
+
+  if (PressAKey!=CH_SHIFT_ESC) {
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental1.ISO.C"))
+      CopyTree("T:/","~/Sup1");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental2.ISO.C"))
+      CopyTree("T:/","~/Sup2");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental3.ISO.C"))
+      CopyTree("T:/","~/Sup3");
+
+    Once("TOSBootHDIns;");
+    "\nDo you wish to run >TOSRegen; to generate\n the "
+          "distro ISO's ";
+    if (YorN) {
+      Once("TOSRegen;");
+      BootRAM("C:/" KERNEL_BIN_C); //Boot so TOSRegen cmd is available.
+    } else {
+      "\nReboot ";
+      if (YorN)
+        Reboot;
+    }
+  }
+  SettingsPop;
+}
+
+public U0 TOSStdIns()
+{//Completes TOS install from TOS_Distro.ISO
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  "$PURPLE$$TX+CX,\"Complete TOS install from TOS_Distro.ISO\"$$FG$\n\n\n\n";
+  InsRereg;
+
+  "\nDownload TOS_Supplemental1.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental2.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental3.ISO.C\tfrom http://www.templeos.org\n";
+
+  if (PressAKey!=CH_SHIFT_ESC) {
+    if (FileFind("/Demo/AcctExample"))
+      CopyTree("::/Demo/AcctExample","~");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental1.ISO.C"))
+      CopyTree("T:/","~/Sup1");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental2.ISO.C"))
+      CopyTree("T:/","~/Sup2");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental3.ISO.C"))
+      CopyTree("T:/","~/Sup3");
+
+    Once("TOSBootHDIns;");
+    "\nDo you wish to run >TOSRegen; to generate\n the distro ISO's ";
+    if (YorN) {
+      Once("TOSRegen;");
+      BootRAM("C:/" KERNEL_BIN_C); //Boot so TOSRegen cmd is available.
+    } else {
+      "\nReboot ";
+      if (YorN)
+        Reboot;
+    }
+  }
+  SettingsPop;
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/ToDolDoc.HC.HTML b/public/Wb/Adam/Opt/Utils/ToDolDoc.HC.HTML new file mode 100755 index 0000000..83dafd9 --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/ToDolDoc.HC.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically);DolDoc/Conversion;DolDoc/Cmd Line (Typically)"
+
+public U0 ToDolDoc(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Convert text file to DolDoc by making double $'s.
+  CDoc *doc;
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    "%s\n",tmpde->full_name;
+    doc=DocRead(tmpde->full_name,DOCF_PLAIN_TEXT|DOCF_DBL_DOLLARS);
+    DocWrite(doc);
+    DocDel(doc);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Adam/Opt/Utils/ToTXT.HC.HTML b/public/Wb/Adam/Opt/Utils/ToTXT.HC.HTML new file mode 100755 index 0000000..bf8c4fe --- /dev/null +++ b/public/Wb/Adam/Opt/Utils/ToTXT.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Conversion"
+
+U0 TXTPutS(CDoc *doc,U8 *st,I64 *_col)
+{
+  U8 *ch,*ptr;
+  while (ch=*st++) {
+    switch (ch) {
+      case '\t':
+        do {
+          DocPutKey(doc,CH_SPACE,0);
+          *_col=*_col+1;
+        } while (*_col&7);
+        break;
+
+      start:
+        case 'pi':      ptr="pi";       break;
+        case 'theta':   ptr="theta";    break;
+        case 'phi':     ptr="phi";      break;
+        case 'omega':   ptr="omega";    break;
+        case 'inf':     ptr="inf";      break;
+        case 'u':       ptr="u";        break;
+        case CH_SHIFT_SPACE: ptr=" ";   break;
+      end:
+        DocPrint(doc,ptr);
+        *_col=*_col+StrLen(ptr);
+        break;
+
+      default:
+        if (CH_SPACE<=ch<0x7F || ch=='\n')
+          DocPutKey(doc,ch,0);
+        else
+          DocPrint(doc,".");
+        *_col=*_col+1;
+    }
+  }
+}
+
+public CDoc *Doc2TXT(CDoc *doc_in)
+{//Cvt DolDoc doc to plain text.
+  CDocEntry *doc_e,*doc_e2;
+  I64 y,col;
+  CDoc *doc_out=DocNew;
+  Bool unlock_doc_in=DocLock(doc_in),no_bwd,line_has_html_code=FALSE;
+  DocRecalc(doc_in);
+
+  doc_out->flags|=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+
+  doc_e=doc_in->head.next;
+  col=doc_e->x;
+  y=doc_e->y;
+  while (doc_e!=doc_in) {
+    if (!(doc_e->de_flags&DOCEF_SKIP)) {
+      while (y<doc_e->y) {
+        TXTPutS(doc_out,"\n",&col);
+        y++;
+        col=0;
+        line_has_html_code=FALSE;
+      }
+      if (doc_e->type_u8==DOCT_HTML_CODE)
+        line_has_html_code=TRUE;
+
+      no_bwd=TRUE;
+      doc_e2=doc_e->next;
+      while (doc_e2!=doc_in && doc_e2->y==doc_e->y) {
+        if (doc_e2->x<doc_e->x) {
+          no_bwd=FALSE;
+          break;
+        }
+        doc_e2=doc_e2->next;
+      }
+      if (no_bwd && !(doc_e->type_u8==DOCT_NEW_LINE && line_has_html_code))
+        while (col<doc_e->x)
+          TXTPutS(doc_out," ",&col);
+
+      switch (doc_e->type_u8) {
+        case DOCT_TEXT:
+          TXTPutS(doc_out,doc_e->tag,&col);
+          break;
+        case DOCT_TAB:
+          TXTPutS(doc_out,"\t",&col);
+          break;
+        case DOCT_HTML_CODE:
+          break;
+        case DOCT_SPRITE:
+          break;
+        default:
+          if (doc_e->de_flags&DOCEF_TAG)
+            TXTPutS(doc_out,doc_e->tag,&col);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  while (y<doc_e->y) {
+    TXTPutS(doc_out,"\n",&col);
+    y++;
+    col=0;
+  }
+  doc_out->cur_entry=&doc_out->head;
+  DocRecalc(doc_out);
+
+  if (unlock_doc_in)
+    DocUnlock(doc_in);
+  return doc_out;
+}
+
+#help_index "Cmd Line (Typically);DolDoc/Conversion;DolDoc/Cmd Line (Typically)"
+public U0 ToTXT(U8 *_in_name,U8 *_out_name=NULL,I64 width=70)
+{//Convert DolDocfile to plain text.
+  U8 *in_name,*out_name;
+  CDoc *doc_in,*doc_out;
+
+  SettingsPush; //See SettingsPush
+  WinHorz(0,width-1); //Sets doc width for word wrap.
+
+  in_name=ExtDft(_in_name,"DD.Z");
+  if (_out_name)
+    out_name=ExtDft(_out_name,"TXT");
+  else
+    out_name=ExtChg(_in_name,"TXT");
+
+  doc_in=DocRead(in_name);
+  doc_out=Doc2TXT(doc_in);
+  StrCpy(&doc_out->filename.name,out_name);
+
+  SettingsPop;
+
+  DocWrite(doc_out);
+  DocDel(doc_in);
+  DocDel(doc_out);
+  Free(in_name);
+  Free(out_name);
+}
+
+ diff --git a/public/Wb/Adam/TaskRep.HC.HTML b/public/Wb/Adam/TaskRep.HC.HTML new file mode 100755 index 0000000..d0e386e --- /dev/null +++ b/public/Wb/Adam/TaskRep.HC.HTML @@ -0,0 +1,61 @@ + + + + + + + + + + + +
+#help_index "Info;Task"
+U0 TaskRepTask(CTask *task,I64 indent)
+{
+  CTask *task1;
+  "%h*c$MA,T=\"%08X\",LM=\"Kill(0x%X);\n\",$ $BLACK$#%d$FG$ "
+        "$TX,\"%$Q...\",SCX=16$\n",indent,CH_SPACE,task,task,task->task_num,
+        task->task_title;
+  "%h*c%08X %04X:%04X:%08X\n",indent+2,CH_SPACE,TaskMemAlloced(task),
+        task->task_flags,task->display_flags,task->win_inhibit;
+  task1=task->next_child_task;
+  while (task1!=(&task->next_child_task)(U8 *)
+        -offset(CTask.next_sibling_task)) {
+    TaskRepTask(task1,indent+2);
+    task1=task1->next_sibling_task;
+  }
+}
+
+public U0 TaskRep()
+{//Report current tasks on all cores.
+  I64 i;
+  CCPU *c;
+  PUSHFD
+  CLI
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    "$PURPLE$CPU%02X$FG$\n",i;
+    TaskRepTask(c->seth_task,2);
+  }
+  POPFD
+}
+
+ diff --git a/public/Wb/Adam/TaskSettings.HC.HTML b/public/Wb/Adam/TaskSettings.HC.HTML new file mode 100755 index 0000000..8b58bcf --- /dev/null +++ b/public/Wb/Adam/TaskSettings.HC.HTML @@ -0,0 +1,151 @@ + + + + + + + + + + + +
+#help_index "Task/Settings"
+
+public CTaskSettings *SettingsPush(CTask *task=NULL,I64 flags=0)
+{//Typically, called at start of an application.
+//It saves many settings so they can be restored
+  //at the end of the application with SettingsPop().
+
+  CTaskSettings *tmpse;
+  CDoc *doc;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return NULL;
+  tmpse=CAlloc(sizeof(CTaskSettings),task);
+  tmpse->cur_dir=DirCur(task,task);
+  tmpse->draw_it=task->draw_it;
+  GrPaletteGet(tmpse->palette);
+  tmpse->task_end_cb=task->task_end_cb;
+
+  if (!(flags&TSF_SAME_SONG)) {
+    if (tmpse->song_task=task->song_task) {
+      Suspend(task->song_task);
+      Snd;
+    }
+    task->song_task=NULL;
+  }
+
+  if (tmpse->animate_task=task->animate_task)
+    Suspend(task->animate_task);
+  task->animate_task=NULL;
+
+  if (doc=DocPut(task)) {
+    tmpse->hide_cursor=!Bt(&doc->flags,DOCf_HIDE_CURSOR);
+    tmpse->highlight_cursor=!Bt(&doc->flags,DOCf_DONT_HIGHLIGHT_CURSOR);
+    tmpse->scroll=!Bt(&doc->flags,DOCf_NO_SCROLL_BARS);
+  }
+
+  tmpse->left=task->win_left;
+  tmpse->right=task->win_right;
+  tmpse->top=task->win_top;
+  tmpse->bottom=task->win_bottom;
+
+  tmpse->scroll_x=task->scroll_x;
+  tmpse->scroll_y=task->scroll_y;
+  tmpse->scroll_z=task->scroll_z;
+
+  tmpse->win_inhibit=task->win_inhibit;
+  tmpse->text_attr=task->text_attr;
+  StrCpy(tmpse->task_title,task->task_title);
+  tmpse->title_src  =task->title_src;
+  tmpse->border_attr=task->border_attr;
+  tmpse->border_src =task->border_src;
+  tmpse->border=!Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+  if (TaskValidate(ac.task))
+    tmpse->autocomplete=TRUE;
+  else
+    tmpse->autocomplete=FALSE;
+
+  tmpse->next=task->next_settings;
+  task->next_settings=tmpse;
+  return tmpse;
+}
+
+U0 SettingsPop2(CTask *task,CTaskSettings *tmpse)
+{
+  CDoc *doc;
+
+  if (doc=DocPut(task)) {
+    LBEqu(&doc->flags,DOCf_HIDE_CURSOR,!tmpse->hide_cursor);
+    LBEqu(&doc->flags,DOCf_DONT_HIGHLIGHT_CURSOR,!tmpse->highlight_cursor);
+    LBEqu(&doc->flags,DOCf_NO_SCROLL_BARS,!tmpse->scroll);
+  }
+
+  WinBorder(tmpse->border,task);
+  WinHorz(tmpse->left,tmpse->right,task);
+  WinVert(tmpse->top,tmpse->bottom,task);
+  task->scroll_x=tmpse->scroll_x;
+  task->scroll_y=tmpse->scroll_y;
+  task->scroll_z=tmpse->scroll_z;
+  task->win_inhibit=tmpse->win_inhibit;
+  task->text_attr=tmpse->text_attr;
+  task->border_attr=tmpse->border_attr;
+  task->border_src =tmpse->border_src;
+  task->title_src  =tmpse->title_src;
+  StrCpy(task->task_title,tmpse->task_title);
+  AutoComplete(tmpse->autocomplete);
+  GrPaletteSet(tmpse->palette);
+  Snd;
+}
+
+public U0 SettingsPop(CTask *task=NULL,I64 flags=0)
+{//Typically, called at end of an application.
+  CTaskSettings *tmpse;
+  if (!task) task=Fs;
+  if (!TaskValidate(task))
+    return;
+  if (tmpse=task->next_settings) {
+    task->next_settings=tmpse->next;
+    Cd(tmpse->cur_dir);
+    Free(tmpse->cur_dir);
+    task->draw_it=tmpse->draw_it;
+    task->task_end_cb=tmpse->task_end_cb;
+
+    if (task->animate_task)
+      Kill(task->animate_task);
+    if (task->animate_task=tmpse->animate_task)
+      Suspend(task->animate_task,FALSE);
+
+    if (!(flags&TSF_SAME_SONG)) {
+      if (task->song_task)
+        Kill(task->song_task);
+      if (task->song_task=tmpse->song_task)
+        Suspend(task->song_task,FALSE);
+    }
+
+    SettingsPop2(task,tmpse); //Do it to get ress fast
+    Refresh(,TRUE);
+    SettingsPop2(task,tmpse); //Redo in case was lost by old update
+
+    Free(tmpse);
+  }
+}
+
+ diff --git a/public/Wb/Adam/Training.HC.HTML b/public/Wb/Adam/Training.HC.HTML new file mode 100755 index 0000000..d8db1f5 --- /dev/null +++ b/public/Wb/Adam/Training.HC.HTML @@ -0,0 +1,215 @@ + + + + + + + + + + + +
+#help_index "Help System"
+
+U8 *KeyMapKeyMStrPrint(I64 sc,U0 (*fp_hndlr)(I64 sc),
+        U8 *desc,CTask *task=NULL)
+{
+  I64 i=9,k,c;
+  U8 *st,*st2,*res,*ptr;
+  CHashTable *old_hash=Fs->hash_table;
+  st=ScanCode2KeyName(sc);
+  if (sc&SCF_CTRL)      i+=5;
+  if (sc&SCF_ALT)       i+=4;
+  if (sc&(SCF_SHIFT|SCF_NO_SHIFT)) i+=6;
+  if (TaskValidate(task))
+    Fs->hash_table=task->hash_table;
+  st2=SrcEdLink(fp_hndlr,256);
+  Fs->hash_table=old_hash;
+
+  k=*desc(U32 *);
+  if (k=='Edit')        c=BLUE;
+  else if (k=='Dol ')   c=GREEN;
+  else if (k=='Cmd ')   c=RED;
+  else                  c=BLACK;
+
+  res=MStrPrint("%-*s $FG,%d$$TX+UL+L+PU,\"%$Q\",A=\"%s\"$$FG$\n",
+        i,st,c,desc,st2);
+  Free(st);
+  Free(st2);
+
+  ptr=res;
+  while (*ptr) {
+    if (*ptr==CH_SPACE)
+      *ptr=CH_SHIFT_SPACE;
+    ptr++;
+  }
+
+  return res;
+}
+
+U0 KeyMapKeyPrint(I64 sc,U0 (*fp_hndlr)(I64 sc),U8 *desc,CTask *task=NULL)
+{
+  U8 *st=KeyMapKeyMStrPrint(sc,fp_hndlr,desc,task);
+  "%s",st;
+  Free(st);
+}
+
+U0 KeyMapCtrlAltFamily(Bool no_shift,Bool shift)
+{
+  I64 i,no_shift_f;
+  if (no_shift && shift)
+    no_shift_f=SCF_NO_SHIFT;
+  else
+    no_shift_f=0;
+  if (no_shift) KeyMapKeyPrint(SC_DELETE+SCF_CTRL+SCF_ALT+no_shift_f,
+          &Reboot,"Cmd /Reboot");
+  if (no_shift) KeyMapKeyPrint(SC_ESC+SCF_CTRL+SCF_ALT+no_shift_f,
+          &User,"Cmd /Terminal Window");
+  if (no_shift) KeyMapKeyPrint(SC_TAB+SCF_CTRL+SCF_ALT+no_shift_f,
+          &WinToTop,"Cmd /Next Focus Task");
+
+  for (i=0;i<26;i++)
+    if (keydev.fp_ctrl_alt_cbs[i]) {
+      if (no_shift && keydev.ctrl_alt_no_shift_descs[i])
+        KeyMapKeyPrint(Char2ScanCode(i+'a')+SCF_CTRL+SCF_ALT+no_shift_f,
+              keydev.fp_ctrl_alt_cbs[i],keydev.ctrl_alt_no_shift_descs[i]);
+      if (shift && keydev.ctrl_alt_shift_descs[i])
+        KeyMapKeyPrint(Char2ScanCode(i+'a')+SCF_CTRL+SCF_ALT+SCF_SHIFT,
+              keydev.fp_ctrl_alt_cbs[i],keydev.ctrl_alt_shift_descs[i]);
+    }
+}
+
+U0 KMComparePrepare(U8 *buf,I64 *src)
+{
+  I64 i,*dst=buf;
+  U8 *ptr;
+  if (src) {
+    *dst++=*src++;
+    *dst++=*src++;
+    *dst++=*src++;
+    *dst++=*src++;
+    *dst(U8 *)=0;
+    if (ptr=StrMatch("SHIFT",buf)) {
+      for (i=0;i<5;i++)
+        ptr[i]=CH_SHIFT_SPACE;
+      if (ptr=StrMatch("$",buf))
+        *ptr=255;
+    }
+  } else
+    *buf=0;
+}
+
+I64 KMCompare(U8 *e1,U8 *e2)
+{
+  U8 buf1[STR_LEN],buf2[STR_LEN];
+  KMComparePrepare(buf1,e1);
+  KMComparePrepare(buf2,e2);
+  return StrCmp(buf1,buf2);
+}
+
+U0 KeyMapFamily2(U8 **entries,CTask *task,I64 scf)
+{
+  I64 i,arg1,arg2;
+  for (i=0;i<256;i++) {
+    arg2=scf|i|SCF_KEY_DESC;
+    arg1=ScanCode2Char(arg2);
+    *keydev.desc=0;
+    keydev.hndlr=NULL;
+    if (TaskValidate(task) && !Bt(&task->win_inhibit,WIf_SELF_KEY_DESC)) {
+      if (task==Fs)
+        PutKey(arg1,arg2);
+      else
+        PostMsg(task,MSG_KEY_DOWN,arg1,arg2);
+      Refresh(0,TRUE);
+      Sleep(1); //Open loop because might be no response.  TODO: Drops msgs.
+    }
+    if (*keydev.desc && StrNCmp(keydev.desc,"Char  /",7))
+      entries[i]=KeyMapKeyMStrPrint(arg2,keydev.hndlr,keydev.desc,task);
+  }
+}
+
+U0 KeyMapFamily(CTask *task,I64 scf,Bool no_shift,Bool shift)
+{
+  I64 i,cnt=0;
+  U8 **entries=CAlloc(2*256*sizeof(U8 *)),**ptr=entries;
+  if (no_shift) {
+    if (shift)
+      KeyMapFamily2(ptr,task,scf+SCF_NO_SHIFT);
+    else
+      KeyMapFamily2(ptr,task,scf);
+    ptr+=256;
+    cnt+=256;
+  }
+  if (shift) {
+    KeyMapFamily2(ptr,task,scf+SCF_SHIFT);
+    ptr+=256;
+    cnt+=256;
+  }
+  QSortI64(entries,cnt,&KMCompare);
+  for (i=0;i<cnt;i++)
+    if (entries[i]) {
+      "%s",entries[i];
+      Free(entries[i]);
+    }
+  Free(entries);
+}
+
+public U0 KeyMap(CTask *task=NULL)
+{//Report desc of all keys.
+  Bool old_key_desc;
+  if (!task) task=Fs;
+  old_key_desc=LBtr(&task->win_inhibit,WIf_SELF_KEY_DESC);
+  DocMax;
+  KeyMapFamily(task,0,TRUE,TRUE);
+  KeyMapFamily(task,SCF_CTRL,TRUE,TRUE);
+  KeyMapFamily(task,SCF_ALT,TRUE,TRUE);
+  KeyMapCtrlAltFamily(TRUE,TRUE);
+  LBEqu(&task->win_inhibit,WIf_SELF_KEY_DESC,old_key_desc);
+  "\nKeyMap Completed.\n";
+}
+
+#help_index "Help System/Training"
+public U0 TipOfDay(U8 *tip_file="::/Doc/Tips.DD")
+{//Print random tip-of-day from ::/Doc/Tips.DD.
+  I64 i=RandU16;
+  CDoc *doc=DocRead(tip_file),*doc2=DocNew;
+  CDocEntry *doc_e=doc->head.next;
+  "$WW,1$\n";
+  while (TRUE) {
+    if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*')
+      if (!i--) break;
+    doc_e=doc_e->next;
+  }
+  if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*') {
+    while (doc_e!=doc) {
+      if (doc_e->type_u8!=DOCT_ERROR)
+        DocInsEntry(doc2,DocEntryCopy(doc2,doc_e));
+      doc_e=doc_e->next;
+      if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*')
+        break;
+    }
+  }
+  DocInsDoc(DocPut,doc2);
+  DocDel(doc2);
+  DocDel(doc);
+}
+
+ diff --git a/public/Wb/Adam/WallPaper.HC.HTML b/public/Wb/Adam/WallPaper.HC.HTML new file mode 100755 index 0000000..7a7e7d1 --- /dev/null +++ b/public/Wb/Adam/WallPaper.HC.HTML @@ -0,0 +1,196 @@ + + + + + + + + + + + +
+#help_index "Windows"
+
+class CWallPaperGlbls
+{
+  I64   last_calc_idle_cnt,last_swap_cnter[MP_PROCESSORS_NUM];
+  F64   last_calc_idle_delta_time;
+  U8    top_line[STR_LEN];
+} *wall=CAlloc(sizeof(CWallPaperGlbls));
+wall->last_calc_idle_delta_time=1.0;
+
+class CTaskWallPaperData
+{
+  I64   alloced_u8s,used_u8s;
+  U8    caller_stk[STR_LEN-$];
+};
+
+U0 WallPaper(CTask *_task)
+{
+  I64 i,j,l=TEXT_ROWS-1;
+  CTask *task;
+  CTaskWallPaperData *wpd;
+  CHashTable *old_hash=Fs->hash_table;
+  CCPU *c;
+  CDateStruct ds;
+  U8 *st;
+  _task->text_attr=BLUE<<4+WHITE;
+  if (sys_data_bp) {
+    TextPrint(Fs,0,l--,BLUE<<4+YELLOW,
+          "%010X/%010X %010X/%010X%12td%12td%12td",
+          sys_data_bp->used_u8s,sys_data_bp->alloced_u8s,
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s,
+          cmp.compiled_lines,blkdev.read_cnt,blkdev.write_cnt);
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+          "______Data_Heap______ ______Code_Heap______ "
+          "___Lines___ ___Reads___ __Writes___");
+  } else {
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+          "%010X/%010X%12td%12td%12td",
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s,
+          cmp.compiled_lines,blkdev.read_cnt,blkdev.write_cnt);
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+          "____CodeData_Heap____ "
+          "___Lines___ ___Reads___ ___Writes__");
+  }
+  TextPrint(Fs,0,l--,BLUE<<4+WHITE,"ProgressBars:%016X %016X %016X %016X",
+        progress1,progress2,progress3,progress4);
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    if (winmgr.t->calc_idle_cnt!=wall->last_calc_idle_cnt) {
+      wall->last_calc_idle_delta_time=winmgr.t->calc_idle_delta_time;
+      wall->last_swap_cnter[i]=winmgr.t->last_swap_cnter[i];
+      winmgr.t->last_swap_cnter[i]=c->swap_cnter;
+    }
+
+    task=c->seth_task;
+    do {
+      wpd=&task->wallpaper_data;
+      if (!TaskValidate(task)) break;
+      if (!(winmgr.updates&31)) {
+        if (c==Gs)
+          Fs->hash_table=task->hash_table;
+        else //precaution
+          Fs->hash_table=old_hash;
+        StrPrint(wpd->caller_stk,"    %-18tp %-18tp %-18tp %-18tp",
+              TaskCaller(task,0),TaskCaller(task,1),
+              TaskCaller(task,2),TaskCaller(task,3));
+      }
+      TextPrint(Fs,0,l--,BLUE<<4+YELLOW,wpd->caller_stk);
+      j=UnusedStk(task);
+      if (j<0)
+        Panic("Stk Overflow",task);
+      if (!(winmgr.updates&31)) {
+        wpd->alloced_u8s=TaskMemAlloced(task);
+        wpd->used_u8s   =TaskMemUsed(task);
+      }
+      TextPrint(Fs,0,l--,BLUE<<4+BROWN,
+            "  %-18ts #%08X %010X %010X/%010X %04X:%02tX:%08X",
+            task->task_title,task,j,wpd->used_u8s,wpd->alloced_u8s,
+            task->task_flags,task->display_flags,task->win_inhibit);
+      if (!TaskValidate(task)) break;
+      task=task->next_task;
+    } while (task!=c->seth_task);
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,"CPU%02X %2tf%% ContextSwaps/s:%9,d",i,
+          100.0*(1.0-c->idle_factor),ToI64((winmgr.t->last_swap_cnter[i]
+          -wall->last_swap_cnter[i])/wall->last_calc_idle_delta_time));
+  }
+  TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+        "  ___Description____ #__Task__ UnusedStk_ _UsedMem__/_AllocMem_ "
+        "______Flags_____");
+
+  if (!(winmgr.updates&31) || !*wall->top_line) {
+    Date2Struct(&ds,Now+local_time_offset);
+    i=sys_code_bp->alloced_u8s-sys_code_bp->used_u8s;
+    if (sys_data_bp)
+      i+=sys_data_bp->alloced_u8s-sys_data_bp->used_u8s;
+    StrPrint(wall->top_line,
+          "%3tZ %02d/%02d %02d:%02d:%02d FPS:%2tf Mem:%010X CPU",
+          ds.day_of_week,"ST_DAYS_OF_WEEK",ds.mon,ds.day_of_mon,
+          ds.hour,ds.min,ds.sec,winmgr.fps,i);
+  }
+  TextPrint(Fs,0,0,BLUE<<4+WHITE,wall->top_line);
+
+  if (scrncast.record)
+    TextPrint(Fs,44-4,0,BLUE<<4+RED,"*");
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    if (i&1)
+      TextPrint(Fs,44+i*2,0,BLUE<<4+WHITE,"%2tf",100.0*(1.0-c->idle_factor));
+    else
+      TextPrint(Fs,44+i*2,0,BLUE<<4+YELLOW,"%2tf",100.0*(1.0-c->idle_factor));
+  }
+
+  st=ScanCode2KeyName(kbd.last_down_scan_code);
+  TextPrint(Fs,80-18,0,BLUE<<4+YELLOW,"%18ts",st);
+  Free(st);
+
+  Fs->hash_table=old_hash;
+  wall->last_calc_idle_cnt=winmgr.t->calc_idle_cnt;
+}
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+U0 DrawTermBttn(CDC *dc,CCtrl *c)
+{
+  if (Blink)
+    Sprite3(dc,c->left,c->top,0,<1>);
+}
+
+U0 LeftClickTermBttn(CCtrl *,I64,I64,Bool down)
+{
+  if (down)
+    User;
+}
+
+CCtrl *TermBttnNew()
+{
+  I64 min_x,max_x,min_y,max_y;
+  CCtrl *c=ACAlloc(sizeof(CCtrl));
+
+  c->win_task=sys_winmgr_task;
+  c->flags=CTRLF_SHOW;
+  c->type=CTRLT_GENERIC;
+  c->draw_it=&DrawTermBttn;
+  c->left_click=&LeftClickTermBttn;
+
+  SpriteExtents(<1>,&min_x,&max_x,&min_y,&max_y);
+//min must be zero
+  c->left=sys_winmgr_task->pix_width-(max_x-min_x+1);
+  c->right=c->left+(max_x-min_x+1)-1;
+  c->top=sys_winmgr_task->pix_height-(max_y-min_y+1);
+  c->bottom=c->top+(max_y-min_y+1)-1;
+
+  QueIns(c,sys_winmgr_task->last_ctrl);
+  TaskDerivedValsUpdate(sys_winmgr_task);
+
+  return c;
+}
+
+U0 WallPaperInit()
+{
+  TermBttnNew;
+  gr.fp_wall_paper=&WallPaper;
+}
+
+ diff --git a/public/Wb/Adam/Win.HC.HTML b/public/Wb/Adam/Win.HC.HTML new file mode 100755 index 0000000..95548e8 --- /dev/null +++ b/public/Wb/Adam/Win.HC.HTML @@ -0,0 +1,573 @@ + + + + + + + + + + + +
+#help_index "Windows"
+#help_file "::/Doc/Windows"
+
+CMsStateGlbls old_ms={{-1000,-1000,0},{-1000,-1000,0},{-1000,-1000,0},
+  {0,0,0},{1.0,1.0,1.0},0.0,GetTSC,0.350,0,0,
+  FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE
+};
+
+public CWinMgrGlbls winmgr={0,0,0,WINMGR_FPS,tS,tS,NULL,FALSE,FALSE,FALSE};
+winmgr.t=CAlloc(sizeof(CWinMgrTimingGlbls));
+winmgr.t->last_calc_idle_time=tS;
+
+U0 ProgressBarsRegTf(U8 *path=NULL)
+{
+  F64 t,p1,p2,p3,p4;
+  if (path) {
+    t=tS;
+    if (progress1_t0) p1=t-progress1_t0; else p1=0;
+    if (progress2_t0) p2=t-progress2_t0; else p2=0;
+    if (progress3_t0) p3=t-progress3_t0; else p3=0;
+    if (progress4_t0) p4=t-progress4_t0; else p4=0;
+    RegWrite(path,"progress1_tf=%0.3f;progress2_tf=%0.3f;\n"
+          "progress3_tf=%0.3f;progress4_tf=%0.3f;\n",p1,p2,p3,p4);
+  }
+}
+
+#define PROGRESS_BAR_HEIGHT     20
+#define PROGRESS_BAR_WIDTH      (3*GR_WIDTH/4)
+U0 DrawProgressBars(CDC *dc)
+{
+  I64 i,j,k,n,m;
+  U8 *st,*st2;
+  for (i=0;i<PROGRESS_BARS_NUM;i++) {
+    if (m=sys_progresses[i].max) {
+      dc->color=BLACK;
+      GrRect(dc,
+            (GR_WIDTH-PROGRESS_BAR_WIDTH)/2,
+            (GR_HEIGHT-(PROGRESS_BARS_NUM*2-1-i*4)*PROGRESS_BAR_HEIGHT)/2,
+            PROGRESS_BAR_WIDTH,PROGRESS_BAR_HEIGHT);
+
+      dc->color=LTGREEN;
+      n=sys_progresses[i].val;
+      if (n>m)
+        n=m;
+      GrRect(dc,
+            (GR_WIDTH-PROGRESS_BAR_WIDTH)/2+2,
+            (GR_HEIGHT-(PROGRESS_BARS_NUM*2-1-i*4)*PROGRESS_BAR_HEIGHT)/2+2,
+            n*(PROGRESS_BAR_WIDTH-4)/m,
+            PROGRESS_BAR_HEIGHT-4);
+
+      if (m>1) {
+        dc->color=BLACK;
+        k=m-1;
+        if (k>19) k=19;
+        for (j=0;j<=k;j++)
+          GrLine(dc,
+                (GR_WIDTH-PROGRESS_BAR_WIDTH)/2+1+j*
+                (PROGRESS_BAR_WIDTH-4)/ToF64(k+1),
+                (GR_HEIGHT-(PROGRESS_BARS_NUM*2-1-i*4)*
+                PROGRESS_BAR_HEIGHT)/2+4,
+                (GR_WIDTH-PROGRESS_BAR_WIDTH)/2+1+j*
+                (PROGRESS_BAR_WIDTH-4)/ToF64(k+1),
+                (GR_HEIGHT-(PROGRESS_BARS_NUM*2-3-i*4)*
+                PROGRESS_BAR_HEIGHT)/2-4);
+      }
+
+      dc->color=GREEN;
+      if (*sys_progresses[i].desc)
+        st=StrNew(sys_progresses[i].desc);
+      else
+        st=MStrPrint("%d/%d",n,m);
+      if (sys_progresses[i].t0) {
+        st2=MStrPrint("%s %fs",st,tS-sys_progresses[i].t0);
+        Free(st);
+      } else
+        st2=st;
+      if (sys_progresses[i].tf) {
+        st=MStrPrint("%s/%fs",st2,sys_progresses[i].tf);
+        Free(st2);
+      } else
+        st=st2;
+      GrPrint(dc,(GR_WIDTH-FONT_WIDTH*StrLen(st))/2,(GR_HEIGHT-FONT_HEIGHT-
+            (PROGRESS_BARS_NUM*2-2-i*4)*PROGRESS_BAR_HEIGHT)/2,"%s",st);
+      Free(st);
+    }
+  }
+}
+
+U0 DrawWinGrid(CDC *dc)
+{
+  F64 d;
+  dc->color=BLACK;
+  dc->thick=1;
+  for (d=ms_grid.x_offset;d<GR_WIDTH; d+=ms_grid.x)
+    GrLine(dc,d,0,d,GR_HEIGHT-1);
+  for (d=ms_grid.y_offset;d<GR_HEIGHT;d+=ms_grid.y)
+    GrLine(dc,0,d,GR_WIDTH-1,d);
+}
+
+U0 WinGrid(Bool val)
+{
+  CGridGlbls last_grid;
+  MemCpy(&last_grid,&ms_grid,sizeof(CGridGlbls));
+  if (!val || PopUpForm(&ms_grid)) {
+    if (!val)
+      GridInit;
+    ms_hard.prescale.x*=last_grid.x_speed/ms_grid.x_speed;
+    ms_hard.prescale.y*=last_grid.y_speed/ms_grid.y_speed;
+    ms_hard.prescale.z*=last_grid.z_speed/ms_grid.z_speed;
+  } else
+    MemCpy(&ms_grid,&last_grid,sizeof(CGridGlbls));
+}
+U0 CtrlAltG(I64 sc)
+{
+  if (sc&SCF_SHIFT)
+    PopUp("WinGrid(OFF);");
+  else
+    PopUp("WinGrid(ON);");
+}
+CtrlAltCBSet('G',&CtrlAltG,"Cmd /Grid On",
+        "Cmd /Grid Off");
+
+CTask *ext_ASCII_task;
+U0 ExtendedASCII()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"Sel Char and Press <ESC>\n$LTBLUE$");
+  for (i=0;i<256;i++) {
+    if (i>=CH_SHIFT_SPACE && i!=0x7F) {
+      if (i==CH_SHIFT_SPACE)
+        DocPrint(doc,"$MU-UL,\"\\x1F\",LE=%d$",i);
+      else if (i=='$')
+        DocPrint(doc,"$MU-UL,\"\\x24\",LE=%d$",i);
+      else if (i=='\"'||i=='\\')
+        DocPrint(doc,"$MU-UL,\"\\%c\",LE=%d$",i,i);
+      else
+        DocPrint(doc,"$MU-UL,\"%c\",LE=%d$",i,i);
+    } else
+      DocPrint(doc," ");
+    if (i&15==15)
+      DocPrint(doc,"\n");
+  }
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  if (i>=0)
+    PostMsg(ext_ASCII_task,MSG_KEY_DOWN_UP,i,Char2ScanCode(i));
+}
+
+U0 CtrlAltA(I64)
+{
+  if (ext_ASCII_task=sys_focus_task)
+    Spawn(&ExtendedASCII);
+}
+CtrlAltCBSet('A',&CtrlAltA,"Cmd /Extended ASCII");
+
+public U0 WinScrollNull(CTask *task,CD3I64 *s)
+{//If panning a window has been done, restore to zero.
+  s->x=task->scroll_x;
+  s->y=task->scroll_y;
+  s->z=task->scroll_z;
+  task->scroll_x=0;
+  task->scroll_y=0;
+  task->scroll_z=0;
+}
+
+public U0 WinScrollRestore(CTask *task,CD3I64 *s)
+{//Set window pan value to stored value.
+  task->scroll_x=s->x;
+  task->scroll_y=s->y;
+  task->scroll_z=s->z;
+}
+
+U0 DrawMs(CDC *dc)
+{
+  I64 x,y;
+  PUSHFD
+  CLI
+  x=ms.pos.x;
+  y=ms.pos.y;
+  POPFD
+  if (ms.show && ms_hard.installed) {
+    if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
+      gr.text_base[ms.pos_text.x+ms.pos_text.y*TEXT_COLS]^=0x7F00;
+    else {
+      if (gr.fp_draw_ms) {
+        if (ms.lb)
+          dc->color=ROP_XOR+LTPURPLE^TRANSPARENT;
+        else if (ms.rb)
+          dc->color=ROP_XOR+LTCYAN^TRANSPARENT;
+        else
+          dc->color=ROP_XOR+BLACK^TRANSPARENT;
+        if (winmgr.grab_scroll && gr.fp_draw_grab_ms)
+          (*gr.fp_draw_grab_ms)(dc,x,y,winmgr.grab_scroll_closed);
+        else
+          (*gr.fp_draw_ms)(dc,x,y);
+      }
+    }
+  }
+}
+
+U0 WinFinalUpdate(CDC *dc)
+{
+  if (ms_grid.show)
+    DrawWinGrid(dc);
+  if (ms_grid.coord)
+    GrPrint(dc,GR_WIDTH-FONT_WIDTH*10,FONT_HEIGHT*3,
+          "(%03d,%03d)",ms.pos.x,ms.pos.y);
+  DrawProgressBars(dc);
+  if (winmgr.show_menu)
+    DrawMenu(dc);
+  else
+    sys_cur_submenu_entry=NULL;
+  DrawMs(dc);
+}
+
+gr.fp_final_scrn_update=&WinFinalUpdate;
+
+U0 WinMsUpdate()
+{
+  I64 dd;
+  Bool set=FALSE;
+  if (ms_hard.installed) {
+    ms.has_wheel=ms_hard.has_wheel;
+    if (ms_hard.evt) {
+      MsUpdate(ms_hard.pos.x,ms_hard.pos.y,ms_hard.pos.z,
+            ms_hard.bttns[0],ms_hard.bttns[1]);
+      ms_hard.evt=FALSE;
+      set=TRUE;
+    }
+  }
+
+  if (set) {
+    if (ms_hard.installed) {
+      ms.speed=ms_hard.speed;
+      ms.timestamp=ms_hard.timestamp;
+    }
+  } else
+    ms.speed*=0.95;
+  if (gr.scrn_zoom!=1) {
+    if (gr.continuous_scroll)
+      GrScaleZoom(1.0);
+    else {
+      dd=(ms.pos.x-gr.sx)*gr.scrn_zoom;
+      if (!(8<=dd<GR_WIDTH-8))
+        GrScaleZoom(1.0);
+      else {
+        dd=(ms.pos.y-gr.sy)*gr.scrn_zoom;
+        if (!(8<=dd<GR_HEIGHT-8))
+          GrScaleZoom(1.0);
+      }
+    }
+  }
+}
+
+public CTask *WinRefocus(CTask *task=NULL)
+{//Reset the focus task if NULL.
+  PUSHFD
+  CLI
+  if (!task) {
+    task=sys_winmgr_task->last_task;
+    while (TaskValidate(task) && task!=sys_winmgr_task) {
+      if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+        sys_focus_task=task;
+        break;
+      }
+      task=task->last_task;
+    }
+  }
+  POPFD
+  return sys_focus_task;
+}
+
+I64 WinOnTopWindows()
+{
+  CTask *task,*task1,*first_moved_fwd=NULL;
+  I64 res=0;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  task=sys_winmgr_task->next_task;
+  while (task!=sys_winmgr_task && task!=first_moved_fwd) {
+    task1=task->next_task;
+    if (!TaskValidate(task)) {
+      POPFD
+      return res;
+    }
+    if (Bt(&task->display_flags,DISPLAYf_WIN_ON_TOP) &&
+          task!=sys_winmgr_task->last_task) {
+      TaskQueRem(task);
+      TaskQueIns(task,sys_winmgr_task);
+      res++;
+      if (!first_moved_fwd)
+        first_moved_fwd=task;
+    }
+    task=task1;
+  }
+  POPFD
+  return res;
+}
+
+public I64 WinToTop(CTask *task=NULL,Bool update_z_buf=TRUE)
+{//Put task's win on top of window stack.
+  CTask *task1;
+  I64 res=0;
+  if (!task) task=Fs;
+  if (!TaskValidate(task) || task->gs->num)
+    return 0;
+  TaskDerivedValsUpdate(task,FALSE);
+  if (!sys_winmgr_task || task==sys_winmgr_task)
+    return 0;
+  PUSHFD
+  CLI
+  if (!TaskValidate(task)) {
+    POPFD
+    return 0;
+  }
+  if (task!=sys_winmgr_task->last_task) {
+    TaskQueRem(task);
+    TaskQueIns(task,sys_winmgr_task);
+    res++;
+  }
+  if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+    sys_focus_task=task;
+  if (res && !Bt(&task->display_flags,DISPLAYf_CHILDREN_NOT_ON_TOP)) {
+    task1=task->next_child_task;
+    while (task1!=&task->next_child_task) {
+      if (!TaskValidate(task1))
+        break;
+      res+=WinToTop(task1,FALSE);
+      task1=task1->next_sibling_task;
+    }
+    if (task->popup_task &&
+          task->popup_task->parent_task==task)
+      res+=WinToTop(task->popup_task,FALSE);
+  }
+  POPFD
+  res+=WinOnTopWindows;
+  if (res && update_z_buf)
+    WinZBufUpdate;
+  return res;
+}
+ext[EXT_WIN_TO_TOP]=&WinToTop;
+
+public CTask *WinFocus(CTask *task=NULL)
+{//Set task as focus task.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (!TaskValidate(task)||Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+    task=WinRefocus(sys_focus_task);
+  WinToTop(sys_focus_task=task);
+  POPFD
+  return sys_focus_task;
+}
+ext[EXT_WIN_FOCUS]=&WinFocus;
+
+public Bool WinHorz(I64 left,I64 right,CTask *task=NULL)
+{//Set task's win left and right columns.
+  I64 d=right-left;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return FALSE;
+  if (d<0) d=0;
+  if (left>=TEXT_COLS) {
+    left=TEXT_COLS-1;
+    right=left+d;
+  }
+  if (right<0) {
+    right=0;
+    left=right-d;
+  }
+  if (left>right) {
+    if (left>0)
+      right=left;
+    else
+      left=right;
+  }
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  if (task->win_left!=left || task->win_right!=right) {
+    task->win_left=left;
+    task->win_right=right;
+    TaskDerivedValsUpdate(task);
+    POPFD
+    return TRUE;
+  } else {
+    POPFD
+    return FALSE;
+  }
+}
+
+public Bool WinVert(I64 top,I64 bottom,CTask *task=NULL)
+{//Set task's win top and bottom rows.
+  I64 d=bottom-top;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return FALSE;
+  if (d<0) d=0;
+  if (top>=TEXT_ROWS) {
+    top=TEXT_ROWS-1;
+    bottom=top+d;
+  }
+  if (bottom<=0) {
+    bottom=1;
+    top=bottom-d;
+  }
+  if (top>bottom) {
+    if (top>=0)
+      bottom=top;
+    else
+      top=bottom;
+  }
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  if (task->win_top!=top || task->win_bottom!=bottom) {
+    task->win_top=top;
+    task->win_bottom=bottom;
+    TaskDerivedValsUpdate(task);
+    POPFD
+    return TRUE;
+  } else {
+    POPFD
+    return FALSE;
+  }
+}
+
+public U0 WinTileHorz()
+{//Tile windows horizontally top-to-bottom.
+  CTask *task,*last_task=Fs;
+  I64 cnt,c,i,vert_size,no_border;
+
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  task=sys_winmgr_task;
+  cnt=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+      cnt++;
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+
+  task=sys_winmgr_task;
+  i=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+      no_border=Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+      c=cnt- i&~3;
+      if (!c)
+        c=1;
+      else if (c>4)
+        c=4;
+      vert_size=(TEXT_ROWS-1)/c;
+
+      WinHorz(1-no_border,TEXT_COLS-2+no_border,task);
+      WinVert((i&3)*vert_size+2-no_border,(i&3+1)*vert_size+no_border,task);
+      last_task=task;
+      if (i&3==3)
+        WinVert(task->win_top,TEXT_ROWS-2,task);
+      i++;
+    }
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+  WinVert(last_task->win_top,TEXT_ROWS-2,last_task);
+  POPFD
+}
+
+public U0 WinTileVert()
+{//Tile windows vertically side-by-side.
+  CTask *task,*last_task=Fs;
+  I64 cnt,c,i,horz_size,no_border;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  task=sys_winmgr_task;
+  cnt=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+      cnt++;
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+
+  task=sys_winmgr_task;
+  i=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+      no_border=Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+      c=cnt- i&~3;
+      if (!c)
+        c=1;
+      else if (c>4)
+        c=4;
+      horz_size=TEXT_COLS/c;
+      WinHorz((i&3)*horz_size+1-no_border,(i&3+1)*horz_size-1+no_border,task);
+      WinVert(2-no_border,TEXT_ROWS-2+no_border,task);
+      last_task=task;
+      if (i&3==3)
+        WinHorz(task->win_left,TEXT_COLS-2,task);
+      i++;
+    }
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+  WinHorz(last_task->win_left,TEXT_COLS-2,last_task);
+  POPFD
+}
+
+public U0 WinMax(CTask *task=NULL)
+{//Maximize task's window
+  I64 no_border;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  no_border=Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+  WinHorz(1-no_border,TEXT_COLS-2+no_border,task);
+  WinVert(2-no_border,TEXT_ROWS-2+no_border,task);
+  WinToTop(task);
+  POPFD
+}
+
+public Bool WinBorder(Bool val=OFF,CTask *task=NULL)
+{//Turn off (or on) window border.
+  Bool old_has_border;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return FALSE;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  old_has_border=!Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+  if (val) {
+    if (!old_has_border) {
+      LBtr(&task->display_flags,DISPLAYf_NO_BORDER);
+      task->win_left++; task->win_right--;
+      task->win_top++;  task->win_bottom--;
+      TaskDerivedValsUpdate(task,FALSE);
+    }
+  } else {
+    if (old_has_border) {
+      LBts(&task->display_flags,DISPLAYf_NO_BORDER);
+      task->win_left--; task->win_right++;
+      task->win_top--;  task->win_bottom++;
+      TaskDerivedValsUpdate(task,FALSE);
+    }
+  }
+  POPFD
+  return old_has_border;
+}
+
+ diff --git a/public/Wb/Adam/WinMgr.HC.HTML b/public/Wb/Adam/WinMgr.HC.HTML new file mode 100755 index 0000000..6fb4f67 --- /dev/null +++ b/public/Wb/Adam/WinMgr.HC.HTML @@ -0,0 +1,894 @@ + + + + + + + + + + + +
+#help_index "Windows;Task/Delay"
+
+public U0 Refresh(I64 cnt=1,Bool force=FALSE)
+{//Wait for 30fps WinMgr to start & finish scrn refresh.
+  //0,FALSE Cnt Sync to WinMgr.
+  //0,TRUE  Pump Msgs.
+  //1 Cnt Wait and Pump Msgs.
+  //2 Cnt Make Sure to do a Full Refresh
+  //and Set Cur Pos.
+  Bool  old_full_refresh,
+        old_idle=LBts(&Fs->task_flags,TASKf_IDLE);
+  CDoc *old_doc=DocPut;
+  I64 update_cnt;
+  if (!cnt&&force)
+    LBts(&sys_semas[SEMA_JUST_PUMP_MSGS],0);
+  while (Bt(&sys_semas[SEMA_REFRESH_IN_PROGRESS],0)) {
+    if (force && sys_winmgr_task)
+      sys_winmgr_task->wake_jiffy=cnts.jiffies;
+    Yield;
+  }
+  if (cnt>1 && old_doc)
+    old_full_refresh=LBts(&old_doc->flags,DOCf_DO_FULL_REFRESH);
+  update_cnt=winmgr.updates+cnt;
+  while (winmgr.updates<update_cnt) {
+    if (force && sys_winmgr_task)
+      sys_winmgr_task->wake_jiffy=cnts.jiffies;
+    Sleep(1);
+  }
+  if (old_doc)
+    LBEqu(&old_doc->flags,DOCf_DO_FULL_REFRESH,old_full_refresh);
+  LBEqu(&Fs->task_flags,TASKf_IDLE,old_idle);
+}
+
+#help_index "Windows"
+
+I64 WinQueIPMsgs(Bool que)
+{
+  static CD3I64 single_ms={0,0,0};
+  F64 time=tS;
+  I64 msg_code=0,arg1,arg2,single_arg1,single_arg2;
+  CTask *task_focus=sys_focus_task;
+
+  if (task_focus && !winmgr.grab_scroll) {
+    arg1=ms.pos.x-task_focus->pix_left-task_focus->scroll_x;
+    arg2=ms.pos.y-task_focus->pix_top-task_focus->scroll_y;
+    single_arg1=single_ms.x-task_focus->pix_left-task_focus->scroll_x;
+    single_arg2=single_ms.y-task_focus->pix_top-task_focus->scroll_y;
+    if (old_ms.presnap.x!=ms.presnap.x || old_ms.presnap.y!=ms.presnap.y) {
+      if (que)
+        TaskMsg(task_focus,0,
+              MSG_MS_MOVE,arg1,arg2,0);
+      msg_code=MSG_MS_MOVE;
+    }
+//TODO que msg for ms.pos.z?
+    if (ms.left_dbl_time) {
+      if (time>ms.left_dbl_time) {
+        if (ms.left_dbl) {
+          if (!ms.left_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_D_DOWN,arg1,arg2,0);
+            ms.left_down_sent=TRUE;
+            msg_code=MSG_MS_L_D_DOWN;
+          }
+          if (!ms.lb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_D_UP,arg1,arg2,0);
+            ms.left_dbl_time=0;
+            msg_code=MSG_MS_L_D_UP;
+          }
+        } else {
+          if (!ms.left_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_DOWN,single_arg1,single_arg2,0);
+            ms.left_down_sent=TRUE;
+            msg_code=MSG_MS_L_DOWN;
+          }
+          if (!ms.lb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_UP,arg1,arg2,0);
+            ms.left_dbl_time=0;
+            msg_code=MSG_MS_L_UP;
+          }
+        }
+      } else {
+        if (ms.lb && !ms_last.lb) {
+          ms.left_dbl_time=time;
+          ms.left_dbl=TRUE;
+        }
+      }
+    } else {
+      if (TaskValidate(task_focus) &&
+            Bt(&task_focus->win_inhibit,WIf_FOCUS_TASK_MS_L_D)) {
+        if (ms.lb  && !ms_last.lb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_L_DOWN,arg1,arg2,0);
+          msg_code=MSG_MS_L_DOWN;
+        } else if (!ms.lb && ms_last.lb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_L_UP,arg1,arg2,0);
+          msg_code=MSG_MS_L_UP;
+        }
+      } else {
+        if (ms.lb  && !ms_last.lb) {
+          ms.left_dbl=FALSE;
+          ms.left_down_sent=FALSE;
+          ms.left_dbl_time=time+ms.dbl_time;
+          single_ms.x=ms.pos.x;
+          single_ms.y=ms.pos.y;
+        }
+      }
+    }
+
+    if (ms.right_dbl_time) {
+      if (time>ms.right_dbl_time) {
+        if (ms.right_dbl) {
+          if (!ms.right_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_D_DOWN,arg1,arg2,0);
+            ms.right_down_sent=TRUE;
+            msg_code=MSG_MS_R_D_DOWN;
+          }
+          if (!ms.rb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_D_UP,arg1,arg2,0);
+            ms.right_dbl_time=0;
+            msg_code=MSG_MS_R_D_UP;
+          }
+        } else {
+          if (!ms.right_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_DOWN,single_arg1,single_arg2,0);
+            ms.right_down_sent=TRUE;
+            msg_code=MSG_MS_R_DOWN;
+          }
+          if (!ms.rb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_UP,arg1,arg2,0);
+            ms.right_dbl_time=0;
+            msg_code=MSG_MS_R_UP;
+          }
+        }
+      } else {
+        if (ms.rb && !ms_last.rb) {
+          ms.right_dbl_time=time;
+          ms.right_dbl=TRUE;
+        }
+      }
+    } else {
+      if (TaskValidate(task_focus) &&
+            Bt(&task_focus->win_inhibit,WIf_FOCUS_TASK_MS_R_D)) {
+        if (ms.rb  && !ms_last.rb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_R_DOWN,arg1,arg2,0);
+          msg_code=MSG_MS_R_DOWN;
+        } else if (!ms.rb && ms_last.rb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_R_UP,arg1,arg2,0);
+          msg_code=MSG_MS_R_UP;
+        }
+      } else {
+        if (ms.rb  && !ms_last.rb) {
+          ms.right_dbl=FALSE;
+          ms.right_down_sent=FALSE;
+          ms.right_dbl_time=time+ms.dbl_time;
+          single_ms.x=ms.pos.x;
+          single_ms.y=ms.pos.y;
+        }
+      }
+    }
+
+    MemCpy(&ms_last,&ms,sizeof(CMsStateGlbls));
+    MemCpy(&old_ms,&ms,sizeof(CMsStateGlbls));
+  }
+  return msg_code;
+}
+
+U0 WinCalcIdles()
+{
+  F64 calc_idle_time;
+  I64 i,k,total_jiffies,total_jiffies_delta,idle_pt_hits[MP_PROCESSORS_NUM];
+  CCPU *c;
+  CWinMgrTimingGlbls *t=winmgr.t;
+
+  if ((t->calc_idle_delta_time=
+        (calc_idle_time=tS)-t->last_calc_idle_time)>.25) {
+    PUSHFD
+    CLI
+    total_jiffies=cpu_structs[0].total_jiffies;
+    for (i=0;i<mp_cnt;i++)
+      idle_pt_hits[i]=cpu_structs[i].idle_pt_hits;
+    POPFD
+
+    total_jiffies_delta=total_jiffies-t->last_total_jiffies;
+    for (i=0;i<mp_cnt;i++) {
+      c=&cpu_structs[i];
+      if (total_jiffies_delta && (k=idle_pt_hits[i]-t->last_idle_pt_hits[i])>=0)
+        c->idle_factor=Clamp(ToF64(k)/total_jiffies_delta,0.01,0.99);
+      else
+        c->idle_factor=0.01;
+      t->last_idle_pt_hits[i]=idle_pt_hits[i];
+    }
+    t->last_total_jiffies=total_jiffies;
+    t->last_calc_idle_time=calc_idle_time;
+    t->calc_idle_cnt++;
+  }
+}
+
+I64 WinMgrSleep(Bool flush_msgs=FALSE)
+{
+  I64 timeout_val,msg_code=0;
+  CCtrl *c;
+  Bool que;
+  F64 t,t_delta;
+  U8 *st;
+  CDC *diff;
+  CDate cdt;
+
+  TimeCal;
+  if ((t_delta=(t=tS)-winmgr.last_refresh_tS)>0.01)
+    winmgr.fps=Max(1.0/t_delta,1);
+  else
+    winmgr.fps=99;
+  winmgr.last_refresh_tS=t;
+  WinCalcIdles;
+
+  if (flush_msgs)
+    FifoI64Flush(kbd.scan_code_fifo);
+  else if (TaskValidate(sys_focus_task)) {
+    KbdMsgsQue;
+
+    que=TRUE;
+    if (TaskValidate(sys_focus_task) &&
+          !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_CTRLS)) {
+      c=sys_focus_task->next_ctrl;
+      while (c!=&sys_focus_task->next_ctrl) {
+        if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+          que=FALSE;
+          break;
+        }
+        c=c->next;
+      }
+    }
+    msg_code=WinQueIPMsgs(que);
+  } else {
+    WinRefocus(sys_focus_task);
+    if (!TaskValidate(sys_focus_task))
+      FifoI64Flush(kbd.scan_code_fifo);
+  }
+  if (sys_focus_task)
+    LBtr(&sys_focus_task->task_flags,TASKf_HAS_SONG);
+  WinMsUpdate;
+
+  if (!LBtr(&sys_semas[SEMA_JUST_PUMP_MSGS],0)) {
+    t=tS+WINMGR_PERIOD/8;
+    while (winmgr.ideal_refresh_tS<t)
+      winmgr.ideal_refresh_tS+=WINMGR_PERIOD;
+    timeout_val=cnts.jiffies+(winmgr.ideal_refresh_tS-tS)*JIFFY_FREQ;
+    LBts(&sys_semas[SEMA_REFRESH_IN_PROGRESS],0);
+    GrUpdateScrn;
+    LBtr(&sys_semas[SEMA_REFRESH_IN_PROGRESS],0);
+    if (scrncast.record  && !scrncast.just_audio) {
+      cdt=scrncast.t0_now(I64)+ToI64(CDATE_FREQ*(tS-scrncast.t0_tS));
+      if (!scrncast.dc) {
+        scrncast.dc=DCCopy(scrncast.dc2_alias);
+        scrncast.dc->cdt=cdt;
+        st=MStrPrint(scrncast.print_fmt,cdt);
+        GRWrite(st,scrncast.dc);
+        Free(st);
+      } else if (MemCmp(scrncast.dc->body,
+            scrncast.dc2_alias->body,MSize(scrncast.dc2_alias->body))) {
+        diff=DCDiff(scrncast.dc,scrncast.dc2_alias);
+        diff->cdt=cdt;
+        st=MStrPrint(scrncast.print_fmt,cdt);
+        GRWrite(st,diff);
+        Free(st);
+        DCDel(diff);
+        Free(scrncast.dc->body);
+        scrncast.dc->body=MAllocIdent(scrncast.dc2_alias->body);
+      }
+    } else if (scrncast.dc) {
+      DCDel(scrncast.dc); //TODO: MemRep can crash.
+      scrncast.dc=NULL;
+    }
+    if (sys_focus_task && !Bt(&sys_focus_task->task_flags,TASKf_HAS_SONG)) {
+      Free(music.cur_song);
+      music.cur_song=NULL;
+    }
+    if (music.cur_song) {
+      if (!music.cur_song_task)
+        music.cur_song_task=Spawn(&CurSongTask,NULL,"Song");
+    } else if (music.cur_song_task) {
+      Kill(music.cur_song_task);
+      music.cur_song_task=NULL;
+    }
+    winmgr.updates++;
+    if (ms_hard.install_attempts) //Don't call before boot mouse install attempt
+      KbdMsHndlr(FALSE,TRUE);
+    SleepUntil(timeout_val);
+  }
+  return msg_code;
+}
+
+CDoc *WinCursorPosSet(CTask *task,I64 msx,I64 msy,Bool set_cursor=TRUE)
+{
+  CDoc *res=NULL;
+  Bool unlock;
+  I64 x0,y0;
+  if (!task) task=Fs;
+  if (WinInside(msx,msy,task)) {
+    if ((res=DocDisplay(task)) && res->flags&DOCF_DONT_SHOW)
+      res=NULL;
+    else if (set_cursor) {
+      unlock=DocLock(res);
+      if (res->doc_signature!=DOC_SIGNATURE_VAL)
+        res=NULL;
+      else {
+        x0=res->line_start_col;
+        y0=res->top_line_num;
+        DocRecalc(res,RECALCF_HAS_CURSOR);
+        res->x=(msx-task->pix_left-task->scroll_x)/FONT_WIDTH +x0;
+        res->y=(msy-task->pix_top -task->scroll_y)/FONT_HEIGHT+y0;
+        DocRecalc(res,RECALCt_FIND_CURSOR);
+        task->scroll_x=0;
+        task->scroll_y=0;
+        task->scroll_z=0;
+        if (unlock)
+          DocUnlock(res);
+      }
+    }
+    WinToTop(task);
+  }
+  return res;
+}
+
+Bool WinKeyNavMenu()
+{
+  I64 i,old_key_cnt;
+  CD3I64 old_pos,new_pos;
+  CMenu *m;
+  CMenuEntry *tmpme;
+  CTask *focus=MenuTask;
+  if (Bt(kbd.down_bitmap,SC_GUI) && focus && (m=focus->cur_menu)) {
+    winmgr.show_menu=TRUE;
+    sys_cur_submenu_entry=NULL;
+    old_pos.x=ms.pos.x; old_pos.y=ms.pos.y;
+    ms.pos.x=new_pos.x=ms.pos.y=new_pos.y=0;
+    while (Bt(kbd.down_bitmap,SC_GUI)) {
+      old_key_cnt=kbd.cnt;
+      if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_LEFT) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        if (new_pos.x) {
+          i=0;
+          tmpme=m->sub;
+          while (tmpme) {
+            if (i+MenuEntryWidth(tmpme)*FONT_WIDTH==new_pos.x) {
+              new_pos.x=i;
+              break;
+            }
+            i+=MenuEntryWidth(tmpme)*FONT_WIDTH;
+            tmpme=tmpme->next;
+          }
+        }
+        new_pos.y=0;
+      } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        i=0;
+        tmpme=m->sub;
+        while (tmpme) {
+          if (i==new_pos.x) {
+            if (tmpme->next)
+              new_pos.x=i+MenuEntryWidth(tmpme)*FONT_WIDTH;
+            break;
+          }
+          i+=MenuEntryWidth(tmpme)*FONT_WIDTH;
+          tmpme=tmpme->next;
+        }
+        new_pos.y=0;
+      } else if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_UP) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        new_pos.y-=FONT_HEIGHT;
+      } else if (Bt(kbd.down_bitmap,SC_CURSOR_DOWN)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_DOWN) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        new_pos.y+=FONT_HEIGHT;
+      }
+      new_pos.x=ClampI64(new_pos.x,0,GR_WIDTH-1);
+      new_pos.y=ClampI64(new_pos.y,0,GR_HEIGHT-1);
+      ms.pos.x=new_pos.x; ms.pos.y=new_pos.y;
+      WinMgrSleep(TRUE);
+      if (!sys_cur_submenu_entry)
+        ms.pos.y=new_pos.y=0;
+    }
+    if (sys_cur_submenu_entry)
+      TaskMsg(sys_focus_task,0,sys_cur_submenu_entry->msg_code,
+            sys_cur_submenu_entry->arg1,sys_cur_submenu_entry->arg2,0);
+    winmgr.show_menu=FALSE;
+    ms.pos.x=old_pos.x; ms.pos.y=old_pos.y;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+U0 WinMgrTask(I64)
+{
+  CTask *task=Fs;
+  CDoc *doc;
+  CDocEntry *doc_e;
+  I64 x,y,z,msg_code,
+        my_ms_z=0,left,top,
+        old_flags=GetRFlags;
+  Bool has_border;
+  CCtrl *c;
+  WinHorz(0,TEXT_COLS-1);
+  WinVert(0,TEXT_ROWS-1);
+  LBts(&Fs->display_flags,DISPLAYf_NO_BORDER);
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  gr.dc->win_task=Fs;
+  Fs->win_inhibit&=~WIF_SELF_CTRLS;
+  GrSetUpTables;
+  scrncast.dc2_alias=DCAlias(gr.dc2);
+  WinZBufUpdate;
+  LBts(&sys_run_level,RLf_WINMGR);
+  while (TRUE) {
+    try {
+wmt_start:
+      if (Bt(&sys_run_level,RLf_ADAM_SERVER))
+        TaskKillDying;
+      WinMgrSleep;
+
+      task=Fs->last_task;
+      while (TRUE) {
+        CLI
+        if (!TaskValidate(task)) {
+          SetRFlags(old_flags);
+          goto wmt_start;
+        }
+        TaskDerivedValsUpdate(task,FALSE);
+        task=task->last_task;
+        SetRFlags(old_flags);
+        if (task==Fs)
+          break;
+      }
+      TaskDerivedValsUpdate(Fs,FALSE);
+
+      task=Fs->last_task;
+      while (TRUE) {
+        CLI
+        if (!TaskValidate(task)) {
+          SetRFlags(old_flags);
+          goto wmt_start;
+        }
+        if (WinInside(ms.pos.x,ms.pos.y,task,FONT_WIDTH)) {
+          SetRFlags(old_flags);
+          break;
+        }
+        if (task==Fs) { //Shouldn't happen
+          SetRFlags(old_flags);
+          goto wmt_start;
+        }
+        task=task->last_task;
+        SetRFlags(old_flags);
+      }
+
+      if (Bt(&task->display_flags,DISPLAYf_NO_BORDER))
+        has_border=FALSE;
+      else
+        has_border=TRUE;
+
+      winmgr.show_menu=FALSE;
+      sys_cur_submenu_entry=NULL;
+      if (TaskValidate(sys_focus_task) &&
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MENU)) {
+        if (WinKeyNavMenu)
+          goto wmt_start;
+        if (task==Fs && 0<=ms.pos.y<FONT_HEIGHT && ms_hard.installed) {
+          winmgr.show_menu=TRUE;
+          if (ms.lb && !old_ms.lb) {
+            winmgr.show_menu=TRUE;
+            while (ms.lb)
+              WinMgrSleep(TRUE);
+            if (sys_cur_submenu_entry)
+              TaskMsg(sys_focus_task,0,
+                    sys_cur_submenu_entry->msg_code,
+                    sys_cur_submenu_entry->arg1,
+                    sys_cur_submenu_entry->arg2,0);
+            winmgr.show_menu=FALSE;
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+
+      //grab scroll
+      if (!Bt(&task->win_inhibit,WIf_SELF_GRAB_SCROLL) &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_GRAB_SCROLL)) &&
+            kbd.scan_code&SCF_CTRL && TaskValidate(task)) {
+        winmgr.grab_scroll_closed=FALSE;
+        winmgr.grab_scroll=TRUE;
+        while (kbd.scan_code&SCF_CTRL && TaskValidate(task) && (!ac.task ||
+              !WinInside(ms.pos.x,ms.pos.y,ac.task,FONT_WIDTH))) {
+          if (ms.lb) {
+            winmgr.grab_scroll_closed=TRUE;
+            x=ms.pos.x-task->scroll_x;
+            y=ms.pos.y-task->scroll_y;
+            z=ms.pos.z-task->scroll_z;
+            while (ms.lb && kbd.scan_code&SCF_CTRL && TaskValidate(task)) {
+              task->scroll_x=(ms.pos.x-x)&~7;
+              task->scroll_y=(ms.pos.y-y)&~7;
+              task->scroll_z=ms.pos.z-z;
+              WinMgrSleep(TRUE);
+            }
+            winmgr.grab_scroll_closed=FALSE;
+          } else if (ms.rb)  {
+            task->scroll_x=0;
+            task->scroll_y=0;
+            task->scroll_z=0;
+            WinMgrSleep(TRUE);
+          } else
+            WinMgrSleep;
+        }
+        winmgr.grab_scroll=FALSE;
+        goto wmt_start;
+      } else
+        winmgr.grab_scroll=FALSE;
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_CTRLS) &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_CTRLS))) {
+        if (ms.lb && !old_ms.lb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->flags&CTRLF_CAPTURE_LEFT_MS) {
+                while (ms.lb && TaskValidate(task)) {
+                  if (c->left_click)
+                    (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                  WinMgrSleep;
+                }
+                if (c->left_click)
+                  (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+                old_ms.lb=FALSE;
+                goto wmt_start;
+              } else {
+                if (c->left_click)
+                  (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                old_ms.lb=TRUE;
+                goto wmt_start;
+              }
+            }
+            c=c->next;
+          }
+        }
+        if (old_ms.lb && !ms.lb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->left_click)
+                (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+              old_ms.lb=FALSE;
+              goto wmt_start;
+            }
+            c=c->next;
+          }
+        }
+        if (ms.rb && !old_ms.rb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->flags&CTRLF_CAPTURE_RIGHT_MS) {
+                while (ms.rb && TaskValidate(task)) {
+                  if (c->right_click)
+                    (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                  WinMgrSleep;
+                }
+                if (c->right_click)
+                  (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+                old_ms.rb=FALSE;
+                goto wmt_start;
+              } else {
+                if (c->right_click)
+                  (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                old_ms.rb=TRUE;
+                goto wmt_start;
+              }
+            }
+            c=c->next;
+          }
+        }
+        if (old_ms.rb && !ms.rb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->right_click)
+                (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+              old_ms.rb=FALSE;
+              goto wmt_start;
+            }
+            c=c->next;
+          }
+        }
+        if (ms.has_wheel && my_ms_z!=ms.pos.z) {
+          if (task==sys_focus_task) {
+            c=task->next_ctrl;
+            while (c!=&task->next_ctrl) {
+              if (c->wheel_chg) {
+                (*c->wheel_chg)(c,ms.pos.z-my_ms_z);
+                my_ms_z=ms.pos.z;
+                goto wmt_start;
+              }
+              c=c->next;
+            }
+            my_ms_z=ms.pos.z;
+          } else if (!sys_focus_task)
+            my_ms_z=ms.pos.z;
+        }
+      }
+
+      if (task==Fs)
+        goto wmt_start;
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_L)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_L))) {
+        if (!old_ms.lb && ms.lb) {
+          if (doc=WinCursorPosSet(task,ms.pos.x,ms.pos.y)) {
+            DocLock(doc);
+            if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+              doc_e=doc->cur_entry;
+              if (doc_e!=doc) {
+                if (doc_e->de_flags & DOCEF_HAS_BORDER)
+                  doc_e->de_flags|=DOCEF_SOLID_BORDER;
+              }
+            }
+            DocUnlock(doc);
+            old_ms.lb=TRUE;
+            goto wmt_start;
+          }
+        }
+      }
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_R)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_R))) {
+        if (!old_ms.rb && ms.rb) {
+          if (WinCursorPosSet(task,ms.pos.x,ms.pos.y)) {
+            old_ms.rb=TRUE;
+            goto wmt_start;
+          }
+        }
+      }
+      if (!Bt(&task->win_inhibit,WIf_SELF_BORDER) && has_border &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_BORDER))) {
+        if (old_ms.lb && !ms.lb) {
+          if (ms.pos_text.y==task->win_top-1) {
+            if (task->win_left<=ms.pos_text.x<task->win_left+4) {
+              TaskMsg(task,0,MSG_KEY_DOWN,CH_CTRLM,0x43200000432,0);
+              old_ms.lb=FALSE;
+              goto wmt_start;
+            } else if (task->win_right-2<=ms.pos_text.x<=task->win_right) {
+              if (DocPut(task))
+                TaskMsg(task,0,MSG_KEY_DOWN,CH_SHIFT_ESC,0,0);
+              else
+                Kill(task,FALSE);
+              old_ms.lb=FALSE;
+              goto wmt_start;
+            }
+          }
+        }
+      }
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_L)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_L))) {
+        if (old_ms.lb && !ms.lb) {
+          if (doc=WinCursorPosSet(task,ms.pos.x,ms.pos.y,FALSE)) {
+            do msg_code=WinMgrSleep;
+            while (TaskValidate(task) && (ms.lb || ms.left_dbl_time));
+            if (TaskValidate(task)) {
+              if (msg_code==MSG_MS_L_UP) {
+                if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                  DocLock(doc);
+                  if (TaskValidate(task)) {
+                    if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                      doc_e=doc->cur_entry;
+                      if (doc_e!=doc) {
+                        if (doc_e->de_flags & DOCEF_HAS_BORDER)
+                          doc_e->de_flags&=~DOCEF_SOLID_BORDER;
+                        if (doc_e->de_flags & (DOCEF_TREE|DOCEF_LST|
+                              DOCEF_LINK|DOCEF_CHECK_COLLAPSABLE|
+                              DOCEF_LEFT_CB|DOCEF_LEFT_MACRO|DOCEF_LEFT_EXP))
+                          TaskMsg(task,0,MSG_KEY_DOWN,CH_SPACE,0,0);
+                      }
+                    }
+                    DocUnlock(doc);
+                  }
+                }
+              } else if (msg_code==MSG_MS_L_D_UP)
+                TaskMsg(task,0,MSG_KEY_DOWN,CH_ESC,0,0);
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_R)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_R))) {
+        if (old_ms.rb && !ms.rb) {
+          if (doc=WinCursorPosSet(task,ms.pos.x,ms.pos.y,FALSE)) {
+            do msg_code=WinMgrSleep;
+            while (TaskValidate(task) && (ms.rb || ms.right_dbl_time));
+            if (TaskValidate(task)) {
+              if (msg_code==MSG_MS_R_UP) {
+                if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                  DocLock(doc);
+                  if (TaskValidate(task)) {
+                    if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                      doc_e=doc->cur_entry;
+                      if (doc_e!=doc) {
+                        if (doc_e->de_flags&(DOCEF_LINK|
+                              DOCEF_RIGHT_CB|DOCEF_RIGHT_MACRO|DOCEF_RIGHT_EXP))
+                          TaskMsg(task,0,MSG_KEY_DOWN,'\n',0,0);
+                      }
+                    }
+                    DocUnlock(doc);
+                  }
+                }
+              } else if (msg_code==MSG_MS_R_D_UP)
+                TaskMsg(task,0,MSG_KEY_DOWN,CH_SHIFT_ESC,0,0);
+            }
+            old_ms.rb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_BORDER) && has_border &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_BORDER))) {
+        if (ms.lb && !old_ms.lb) {
+          if (task->win_top==ms.pos_text.y+1 &&
+                task->win_left-1<=ms.pos_text.x<=task->win_right+1) {
+            if (task->win_left<=ms.pos_text.x<task->win_left+4) {
+              old_ms.lb=TRUE;
+              goto wmt_start;
+            }
+            if (task->win_right-2<=ms.pos_text.x<=task->win_right) {
+              old_ms.lb=TRUE;
+              goto wmt_start;
+            }
+            x=ms.pos_text.x-task->win_left;
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(ms.pos_text.x-x,task->win_width-1+ms.pos_text.x-x,task);
+                WinVert(ms.pos_text.y+1,task->win_height+ms.pos_text.y,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_left==ms.pos_text.x+1 &&
+                task->win_top-1<=ms.pos_text.y<=task->win_bottom+1) {
+            y=ms.pos_text.y-task->win_top;
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(ms.pos_text.x+1,task->win_width+ms.pos_text.x,task);
+                WinVert(ms.pos_text.y-y,
+                      task->win_height-1+ms.pos_text.y-y,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_right+1==ms.pos_text.x &&
+                task->win_bottom+1==ms.pos_text.y) {
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(task->win_left,ms.pos_text.x-1,task);
+                WinVert(task->win_top,ms.pos_text.y-1,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_bottom==ms.pos_text.y-1 &&
+                task->win_left<=ms.pos_text.x<=task->win_right) {
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinVert(task->win_top,ms.pos_text.y-1,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_right==ms.pos_text.x-1 &&
+                task->win_top<=ms.pos_text.y<=task->win_bottom) {
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(task->win_left,ms.pos_text.x-1,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+    } catch {
+      Beep;
+      Fs->catch_except=TRUE;
+      task=Fs;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Apps/Budget/BgtAccts.HC.HTML b/public/Wb/Apps/Budget/BgtAccts.HC.HTML new file mode 100755 index 0000000..55a5316 --- /dev/null +++ b/public/Wb/Apps/Budget/BgtAccts.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+U0 BgtAcctsUpdate()
+{
+  CBgtEntry     *tmpb;
+  CBgtTemplate  *tmpt;
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    if (tmpb->type!=BE_TEMPLATE_COPY) {
+      tmpb->credit_idx=StrFileAdd(tmpb->credit,
+            &accts_table_strs,accts_table);
+      tmpb->debit_idx =StrFileAdd(tmpb->debit,
+            &accts_table_strs,accts_table);
+    }
+    tmpb=tmpb->next;
+  }
+  tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    tmpt->b.credit_idx=StrFileAdd(tmpt->b.credit,
+          &accts_table_strs,accts_table);
+    tmpt->b.debit_idx =StrFileAdd(tmpt->b.debit,
+          &accts_table_strs,accts_table);
+    tmpt=tmpt->next;
+  }
+}
+
+U0 BgtAcctsWrite()
+{
+  BgtAcctsUpdate;
+  StrFileWrite(bgt_accts_file,accts_table,TRUE);
+}
+
+U0 BgtAcctsRead()
+{
+  I64   i,max_num;
+  U8    *colors,**s=StrFileRead(bgt_accts_file,&max_num,&colors,TRUE);
+  StrFileDel(accts_table);
+  accts_table=HashTableNew(512);
+  accts_table_strs=0;
+  for (i=0;i<=max_num;i++)
+    if (s[i])
+      StrFileAdd(s[i],&accts_table_strs,accts_table,colors[i]);
+  StrFileArrDel(s,max_num);
+  Free(colors);
+}
+
+I64 BgtAcctColor(U8 *st)
+{
+  CHashGeneric *tmph;
+  if (tmph=HashFind(st,accts_table,SFT_GENERIC))
+    return tmph->user_data1;
+  else
+    return BLACK;
+}
+
+U8 *BgtPopUpAcct(U8 *header=NULL,U8 *dft=NULL)
+{
+  I64 i;
+  U8 *res;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e,*doc_dft=NULL;
+  CHashGeneric *tmph;
+
+  if (header)
+    DocPrint(doc,"%s",header);
+
+  for (i=0;i<=accts_table->mask;i++) {
+    tmph=accts_table->body[i];
+    while (tmph) {
+      doc_e=DocPrint(doc,"$FG,%d$$MU-UL,\"%s\",LE=0x%X$\n",
+            tmph->user_data1,tmph->str,tmph->str);
+      if (dft && !StrCmp(dft,tmph->str))
+        doc_dft=doc_e;
+      tmph=tmph->next;
+    }
+  }
+
+  if (doc_dft) {
+    doc->cur_entry=doc_dft;
+    doc->cur_col=0;
+  }
+  res=PopUpMenu(doc,DOF_DONT_HOME);
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Apps/Budget/BgtEntry.HC.HTML b/public/Wb/Apps/Budget/BgtEntry.HC.HTML new file mode 100755 index 0000000..063c4cc --- /dev/null +++ b/public/Wb/Apps/Budget/BgtEntry.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+U0 BgtEntryDel2(CBgtEntry *tmpb)
+{
+  if (tmpb->type!=BE_TEMPLATE_COPY) {
+    Free(tmpb->credit);
+    Free(tmpb->debit);
+    Free(tmpb->desc);
+  }
+}
+
+CBgtEntry *BgtEntryCopy(CBgtEntry *tmpb,Bool periodic_copy)
+{
+  CBgtEntry *res=MAlloc(sizeof(CBgtEntry));
+  MemCpy(res,tmpb,sizeof(CBgtEntry));
+  if (periodic_copy) {
+    res->credit=StrNew(tmpb->credit);
+    res->debit =StrNew(tmpb->debit);
+    res->desc  =StrNew(tmpb->desc);
+  }
+  return res;
+}
+
+U0 BgtEntryDel(CBgtEntry *tmpb)
+{
+  BgtEntryDel2(tmpb);
+  Free(tmpb);
+}
+
+U0 BgtIns(CBgtEntry *tmpb)
+{
+  CBgtEntry     *tmpb1=b_head.next;
+  while (tmpb1!=&b_head && tmpb1->date<tmpb->date)
+    tmpb1=tmpb1->next;
+  QueIns(tmpb,tmpb1->last);
+}
+
+class CBgtEntryForm
+{
+  U8    date[512]       format "$DA-P,A=\"Date              :%s\"$\n";
+  F64   amount          format "Amount            $$$DA,A=\"%10.2f\"$\n";
+  U8    credit[512]     format "$DA-P,A=\"Credit (from) Acct:%s\"$\n";
+  U8    debit [512]     format "$DA-P,A=\"Debit  (to)   Acct:%s\"$\n";
+  U8    desc  [512]     format "$DA-P,A=\"Desc              :%s\"$\n";
+};
+
+CBgtEntry *BgtEntryPmt(CBgtEntry *dft=NULL)
+{
+  CBgtEntryForm b;
+  CBgtEntry *tmpb;
+  U8 *st;
+  MemSet(&b,0,sizeof(CBgtEntryForm));
+  StrCpy(&b.date,"*");
+  if (dft) {
+    StrPrint(b.date,"%D",dft->date);
+    b.amount=dft->amount;
+    StrCpy(b.credit,dft->credit);
+    StrCpy(b.debit ,dft->debit);
+    StrCpy(b.desc  ,dft->desc);
+  }
+  while (TRUE)
+    if (PopUpForm(&b)) {
+      if (!*b.credit) {
+        st=BgtPopUpAcct("Credit Acct\n\n");
+        if (st!=DOCM_CANCEL)
+          StrCpy(b.credit,st);
+      } else if (!*b.debit) {
+        st=BgtPopUpAcct("Debit Acct\n\n");
+        if (st!=DOCM_CANCEL)
+          StrCpy(b.debit,st);
+      } else {
+        tmpb=CAlloc(sizeof(CBgtEntry));
+        tmpb->date  =Str2Date(b.date);
+        tmpb->amount=b.amount;
+        tmpb->credit=StrNew(b.credit);
+        tmpb->debit =StrNew(b.debit);
+        tmpb->desc  =StrNew(b.desc);
+        tmpb->type  =BE_NORMAL;
+        StrFileAdd(tmpb->credit,&accts_table_strs,accts_table);
+        StrFileAdd(tmpb->debit,&accts_table_strs,accts_table);
+        return tmpb;
+      }
+    } else
+      return NULL;
+}
+
+ diff --git a/public/Wb/Apps/Budget/BgtFile.HC.HTML b/public/Wb/Apps/Budget/BgtFile.HC.HTML new file mode 100755 index 0000000..660e642 --- /dev/null +++ b/public/Wb/Apps/Budget/BgtFile.HC.HTML @@ -0,0 +1,171 @@ + + + + + + + + + + + +
+U0 BgtDataRead()
+{
+  CBgtEntry     *tmpb;
+  CBgtTemplate  *tmpt;
+  I64           i,cnt,size;
+  U8            *b,*ptr;
+  I64           max_num;
+  U8            **s=StrFileRead(bgt_string_file,&max_num);
+
+  MemSet(&b_head,0,sizeof(CBgtEntry));
+  QueInit(&b_head);
+  b_head.date=Now;
+  MemSet(&t_head,0,sizeof(CBgtTemplate));
+  QueInit(&t_head);
+  t_head.b.date=Now;
+
+  if (ptr=b=FileRead(bgt_data_file,&size)) {
+    cnt=*ptr(I64 *)++;
+    for (i=0;i<cnt;i++) {
+      tmpb=CAlloc(sizeof(CBgtEntry));
+      MemCpy(&tmpb->start,ptr,BE_SIZE);
+      tmpb->credit=StrNew(s[tmpb->credit_idx]);
+      tmpb->debit =StrNew(s[tmpb->debit_idx]);
+      tmpb->desc  =StrNew(s[tmpb->desc_idx]);
+      QueIns(tmpb,b_head.last);
+      ptr+=BE_SIZE;
+    }
+
+    cnt=*ptr(I64 *)++;
+    for (i=0;i<cnt;i++) {
+      tmpt=CAlloc(sizeof(CBgtTemplate));
+      MemCpy(&tmpt->start,ptr,BT_SIZE);
+      ptr+=BT_SIZE;
+      MemCpy(&tmpt->b.start,ptr,BE_SIZE);
+      ptr+=BE_SIZE;
+      tmpt->b.credit=StrNew(s[tmpt->b.credit_idx]);
+      tmpt->b.debit =StrNew(s[tmpt->b.debit_idx]);
+      tmpt->b.desc  =StrNew(s[tmpt->b.desc_idx]);
+      QueIns(tmpt,t_head.last);
+    }
+  }
+
+  StrFileArrDel(s,max_num);
+  Free(b);
+
+  BgtAcctsUpdate;
+}
+
+U0 BgtDataWrite()
+{
+  I64 i,num=0,size,cnt1,cnt2;
+  CHashTable    *table=HashTableNew(1024);
+  CBgtEntry     *tmpb;
+  CBgtTemplate  *tmpt;
+  CHashGeneric *tmph;
+  U8 *buf,*ptr;
+
+  for (i=0;i<=accts_table->mask;i++) {
+    tmph=accts_table->body[i];
+    while (tmph) {
+      StrFileAdd(tmph->str,&num,table); //Cosmetics -- make accts appear first.
+      tmph=tmph->next;
+    }
+  }
+
+  tmpb=b_head.next;
+  cnt1=0;
+  while (tmpb!=&b_head) {
+    if (tmpb->type!=BE_TEMPLATE_COPY) {
+      tmpb->credit_idx  =StrFileAdd(tmpb->credit,&num,table);
+      tmpb->debit_idx   =StrFileAdd(tmpb->debit,&num,table);
+      tmpb->desc_idx            =StrFileAdd(tmpb->desc,&num,table);
+      cnt1++;
+    }
+    tmpb=tmpb->next;
+  }
+
+  tmpt=t_head.next;
+  cnt2=0;
+  while (tmpt!=&t_head) {
+    tmpt->b.credit_idx  =StrFileAdd(tmpt->b.credit,&num,table);
+    tmpt->b.debit_idx   =StrFileAdd(tmpt->b.debit,&num,table);
+    tmpt->b.desc_idx            =StrFileAdd(tmpt->b.desc,&num,table);
+    cnt2++;
+    tmpt=tmpt->next;
+  }
+  StrFileWrite(bgt_string_file,table);
+  StrFileDel(table);
+
+  size=sizeof(I64)*2+cnt1*BE_SIZE+cnt2*(BT_SIZE+BE_SIZE);
+  buf=ptr=MAlloc(size);
+
+  MemCpy(ptr,&cnt1,sizeof(I64));
+  ptr+=sizeof(I64);
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    if (tmpb->type!=BE_TEMPLATE_COPY) {
+      MemCpy(ptr,&tmpb->start,BE_SIZE);
+      ptr+=BE_SIZE;
+    }
+    tmpb=tmpb->next;
+  }
+
+  MemCpy(ptr,&cnt2,sizeof(I64));
+  ptr+=sizeof(I64);
+  tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    MemCpy(ptr,&tmpt->start,BT_SIZE);
+    ptr+=BT_SIZE;
+    MemCpy(ptr,&tmpt->b.start,BE_SIZE);
+    ptr+=BE_SIZE;
+    tmpt=tmpt->next;
+  }
+
+  FileWrite(bgt_data_file,buf,size);
+  Free(buf);
+}
+
+U0 BgtDel()
+{
+  CBgtEntry     *tmpb,*tmpb1;
+  CBgtTemplate  *tmpt,*tmpt1;
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    tmpb1=tmpb->next;
+    BgtEntryDel2(tmpb);
+    Free(tmpb);
+    tmpb=tmpb1;
+  }
+  tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    tmpt1=tmpt->next;
+    BgtEntryDel2(&tmpt->b);
+    Free(tmpt);
+    tmpt=tmpt1;
+  }
+  StrFileDel(accts_table);
+  accts_table=NULL;
+  accts_table_strs=0;
+}
+
+ diff --git a/public/Wb/Apps/Budget/BgtMain.HC.HTML b/public/Wb/Apps/Budget/BgtMain.HC.HTML new file mode 100755 index 0000000..ce86b2d --- /dev/null +++ b/public/Wb/Apps/Budget/BgtMain.HC.HTML @@ -0,0 +1,261 @@ + + + + + + + + + + + +
+extern U0 BgtRegen();
+
+Bool BgtPutKey(CDoc *doc,U8 *,I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+  no_warn sc;
+  CBgtEntry *tmpb,*tmpb1;
+  CBgtTemplate *tmpt,*tmpt1;
+  CDocEntry *doc_ce;
+  U8 *st;
+  switch (ch) {
+    case '\n':
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL) {
+        tmpb=doc_ce->user_data;
+        if (tmpt=tmpb->template) {
+          if (tmpt1=BgtTemplatePmt(tmpt)) {
+            QueRem(tmpt);
+            BgtTemplatePurge(tmpt);
+            BgtEntryDel2(&tmpt->b);
+            Free(tmpt);
+            QueIns(tmpt1,t_head.last);
+            BgtTemplateExpand(tmpt1);
+            BgtRegen;
+          }
+        } else {
+          if (tmpb1=BgtEntryPmt(tmpb)) {
+            QueRem(tmpb);
+            BgtEntryDel(tmpb);
+            BgtIns(tmpb1);
+            BgtRegen;
+          }
+        }
+      }
+      return TRUE;
+    case CH_CTRLY:
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL) {
+        tmpb=doc_ce->user_data;
+        if (tmpt=tmpb->template) {
+          QueRem(tmpt);
+          BgtTemplateDel(tmpt);
+        } else {
+          QueRem(tmpb);
+          BgtEntryDel(tmpb);
+        }
+        BgtRegen;
+      }
+      return TRUE;
+    case 'a':
+      PopUpOk(  "Set the name and color of your accounts.\n"
+            "To delete accounts, manually edit\n"
+            "$GREEN$~/Budget/Accts.DD.Z$FG$.");
+      if (PopUpEd(bgt_accts_file,Fs)) {
+        BgtAcctsRead;
+        BgtRegen;
+      }
+      return TRUE;
+    case 'v':
+      if ((st=BgtPopUpAcct("View Acct\n\n",view_acct))>=0) {
+        StrCpy(view_acct,st);
+        BgtRegen;
+      }
+      return TRUE;
+    case 'n':
+      if (tmpb1=BgtEntryPmt) {
+        BgtIns(tmpb1);
+        BgtRegen;
+      }
+      return TRUE;
+    case 't':
+      if (tmpt1=BgtTemplatePmt) {
+        QueIns(tmpt1,t_head.last);
+        BgtTemplateExpand(tmpt1);
+        BgtRegen;
+      }
+      return TRUE;
+    case 'c':
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL)
+        tmpb=doc_ce->user_data;
+      else
+        tmpb=NULL;
+      if (tmpb1=BgtEntryPmt(tmpb)) {
+        BgtIns(tmpb1);
+        BgtRegen;
+      }
+      return TRUE;
+    case 'p':
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL) {
+        tmpb=doc_ce->user_data;
+        if (tmpt1=BgtTemplatePmt(,tmpb)) {
+          BgtTemplateExpand(tmpt1,TRUE);
+          BgtTemplateDel(tmpt1);
+          BgtRegen;
+        }
+      }
+      return TRUE;
+  }
+  return FALSE;
+}
+
+U0 BgtRegen()
+{
+  I64 timeout_jiffy,c,color=COLOR_INVALID;
+  F64 balance=0;
+  CDoc *doc,*pdoc,*ddoc;
+  CDocEntry *doc_ce;
+  CBgtEntry *tmpb=b_head.next,*tmpb_ce;
+  doc=DocNew;
+  doc->flags|=DOCF_FORM;
+  while (tmpb!=&b_head) {
+    if (!StrCmp(view_acct,tmpb->credit))
+      balance-=tmpb->amount;
+    if (!StrCmp(view_acct,tmpb->debit))
+      balance+=tmpb->amount;
+    c=BgtAcctColor(tmpb->credit);
+    if (c!=color) {
+      color=c;
+      DocPrint(doc,"$FG,%d$",color);
+    }
+    tmpb->doc_e=DocPrint(doc,
+          "$MU-UL,\"%D %8ts %8ts:%8.2f %8.2f:%$Q\",U=0x%X$\n",
+          tmpb->date,tmpb->credit,tmpb->debit,balance,
+          tmpb->amount,tmpb->desc,tmpb);
+    tmpb=tmpb->next;
+  }
+  DocRecalc(doc);
+
+  if (pdoc=Fs->put_doc) {
+    DocLock(pdoc);
+//Now, we want to preserve old position in doc, using ugly brute force.
+    //It's tricky -- can't use old line num because of editor filters.
+
+    //The price we pay for using the standard document editor is this kludge.
+    //When I originally wrote my budget program, I did not have separate budget
+    //and line entries, so we never had to resync.
+
+    doc_ce=pdoc->cur_entry;
+    timeout_jiffy=cnts.jiffies+JIFFY_FREQ; //Max one second.
+    while (doc_ce!=pdoc && cnts.jiffies<timeout_jiffy) {
+      while (doc_ce->type_u8!=DOCT_MENU_VAL || !(tmpb_ce=doc_ce->user_data)) {
+        doc_ce=doc_ce->next;
+        if (doc_ce==pdoc) goto br_cont;
+      }
+      tmpb=b_head.next;
+      while (tmpb!=&b_head) {
+        if (tmpb==tmpb_ce) {
+          doc->cur_entry=tmpb->doc_e;
+          doc->cur_col=0;
+          DocCenter(doc);
+          goto br_cont;
+        }
+        tmpb=tmpb->next;
+      }
+      doc_ce=doc_ce->next;
+    }
+  }
+
+  br_cont:
+  ddoc=Fs->display_doc;
+  Fs->put_doc    =doc;
+  Fs->display_doc=doc;
+  DocDel(pdoc);
+  if (pdoc!=ddoc)
+    DocDel(ddoc);
+  doc->user_put_key=&BgtPutKey;
+}
+
+U0 Budget(U8 *dirname="~/Budget")
+{
+  CDoc *pdoc,*ddoc,*old_put,*old_display;
+
+  Cd(dirname);
+  bgt_string_file       =FileNameAbs("Strs.DD.Z");
+  bgt_accts_file        =FileNameAbs("Accts.DD.Z");
+  bgt_data_file         =FileNameAbs("Bgt.DATA.Z");
+
+  BgtAcctsRead;
+  BgtDataRead;
+  CBgtTemplatesExpand;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  NewEntry(,'n');"
+        "  CopyEntry(,'c');"
+        "  PeriodicEntry(,'p');"
+        "  EditEntry(,'\n');"
+        "  DeleteEntry(,CH_CTRLY);"
+        "  NewTemplate(,'t');"
+        "  AcctsFile(,'a');"
+        "}"
+        "View {"
+        "  ViewAcct(,'v');"
+        "}"
+        );
+  StrCpy(view_acct,"BANK");
+  DocMax;
+  old_put        =Fs->put_doc;
+  old_display    =Fs->display_doc;
+  Fs->put_doc    =NULL;
+  Fs->display_doc=NULL;
+  BgtRegen;
+  try
+    if (View) {
+      BgtDataWrite;
+      BgtAcctsWrite;
+    }
+  catch
+    PutExcept;
+
+  pdoc=Fs->put_doc;
+  ddoc=Fs->display_doc;
+  Fs->put_doc    =old_put;
+  Fs->display_doc=old_display;
+  DocDel(pdoc);
+  if (pdoc!=ddoc)
+    DocDel(ddoc);
+
+  SettingsPop;
+  BgtDel;
+  MenuPop;
+}
+
+ diff --git a/public/Wb/Apps/Budget/BgtStrs.HC.HTML b/public/Wb/Apps/Budget/BgtStrs.HC.HTML new file mode 100755 index 0000000..7eee491 --- /dev/null +++ b/public/Wb/Apps/Budget/BgtStrs.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+#define SFT_GENERIC     1
+
+public U8 **StrFileRead(U8 *name,I64 *_max_num=NULL,
+        U8 **_colors=NULL,Bool no_nums=FALSE)
+{
+  CDoc          *doc=DocRead(name,DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
+  CDocEntry     *doc_e=doc->head.next;
+  I64           i,max_num=0;
+  U8            *ptr,**res,*colors;
+
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      if (no_nums)
+        i=++max_num;
+      else {
+        i=Str2I64(doc_e->tag,,&ptr);
+        if (i>max_num) max_num=i;
+        if (*ptr==',') ptr++;
+        ptr=StrNew(ptr);
+        Free(doc_e->tag);
+        doc_e->tag=ptr;
+      }
+      doc_e->user_data=i;
+    }
+    doc_e=doc_e->next;
+  }
+
+  res=CAlloc(sizeof(U8 *)*(max_num+1));
+  colors=CAlloc(sizeof(U8)*(max_num+1));
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT && 0<=doc_e->user_data<=max_num) {
+      res[doc_e->user_data]=doc_e->tag;
+      doc_e->tag=NULL;
+      colors[doc_e->user_data]=doc_e->type.u8[1]&15;
+    }
+    doc_e=doc_e->next;
+  }
+
+  DocDel(doc);
+  if (_max_num) *_max_num=max_num;
+  if (_colors)
+    *_colors=colors;
+  else
+    Free(colors);
+  return res;
+}
+
+public U0 StrFileArrDel(U8 **a,I64 max_num)
+{
+  I64 i;
+  for (i=0;i<=max_num;i++)
+    Free(a[i]);
+  Free(a);
+}
+
+public I64 StrFileAdd(U8 *st,I64 *_num,
+        CHashTable *table,I64 color=COLOR_INVALID)
+{
+  CHashGeneric *tmph;
+  if (!st) return 0;
+  if (!(tmph=HashFind(st,table,SFT_GENERIC))) {
+    tmph=CAlloc(sizeof(CHashGeneric));
+    tmph->type=SFT_GENERIC;
+    tmph->str=StrNew(st);
+    tmph->user_data0=(*_num)++;
+    HashAdd(tmph,table);
+  }
+  if (color!=COLOR_INVALID)
+    tmph->user_data1=color;
+  return tmph->user_data0;
+}
+
+I64 StrEntriesCompare(CHashGeneric *h1,CHashGeneric *h2)
+{
+  return h1->user_data0-h2->user_data0;
+}
+
+public U0 StrFileWrite(U8 *name,CHashTable *table,Bool no_nums=FALSE)
+{
+  I64 i,j,cnt,color=BLACK;
+  CDoc *doc=DocNew(name);
+  CHashGeneric *tmph,**a;
+  if (table) {
+    cnt=0;      //Count Strings
+    for (i=0;i<=table->mask;i++)
+      cnt+=LinkedLstCnt(table->body[i]);
+    a=MAlloc(cnt*sizeof(CHashGeneric *));
+    j=0;        //Load Strings
+    for (i=0;i<=table->mask;i++) {
+      tmph=table->body[i];
+      while (tmph) {
+        a[j++]=tmph;
+        tmph=tmph->next;
+      }
+    }
+    QSortI64(a,cnt,&StrEntriesCompare);
+    for (i=0;i<cnt;i++) {
+      tmph=a[i];
+      if (tmph->user_data1&15!=color) {
+        DocPrint(doc,"$FG,%d$",tmph->user_data1&15);
+        color=tmph->user_data1&15;
+      }
+      if (no_nums)
+        DocPrint(doc,"%s\n",tmph->str);
+      else
+        DocPrint(doc,"%d,%s\n",tmph->user_data0,tmph->str);
+    }
+    Free(a);
+  }
+  doc->flags|=DOCF_NO_CURSOR;
+  DocWrite(doc);
+  DocDel(doc);
+}
+
+public U0 StrFileDel(CHashTable *table)
+{
+  I64 i;
+  CHashGeneric *tmph,*tmph1;
+  if (!table) return;
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      tmph1=tmph->next;
+      Free(tmph->str);
+      Free(tmph);
+      tmph=tmph1;
+    }
+  }
+  Free(table->body);
+  Free(table);
+}
+
+ diff --git a/public/Wb/Apps/Budget/BgtTemplate.HC.HTML b/public/Wb/Apps/Budget/BgtTemplate.HC.HTML new file mode 100755 index 0000000..354c5f3 --- /dev/null +++ b/public/Wb/Apps/Budget/BgtTemplate.HC.HTML @@ -0,0 +1,213 @@ + + + + + + + + + + + +
+U0 BgtTemplatePurge(CBgtTemplate *tmpt)
+{
+  CBgtEntry     *tmpb,*tmpb1;
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    tmpb1=tmpb->next;
+    if (tmpb->template==tmpt) {
+      QueRem(tmpb);
+      BgtEntryDel2(tmpb);
+      Free(tmpb);
+    }
+    tmpb=tmpb1;
+  }
+}
+
+U0 BgtTemplateDel(CBgtTemplate *tmpt)
+{
+  BgtTemplatePurge(tmpt);
+  BgtEntryDel2(&tmpt->b);
+  Free(tmpt);
+}
+
+U0 BgtTemplateExpand(CBgtTemplate *tmpt,Bool periodic_copy=FALSE)
+{
+  CDate         d,start,end;
+  CDateStruct   ds;
+  CBgtEntry     *tmpb;
+  Bool          first=TRUE;
+
+  start=MyStr2Date(tmpt->start_date);
+  end  =MyStr2Date(tmpt->end_date);
+  tmpt->b.template=tmpt;
+  switch (tmpt->type) {
+    case BT_INTERVAL:
+      d=start;
+      while (d<=end) {
+        if (!first || !periodic_copy) {
+          tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+          tmpb->date=d;
+          if (periodic_copy)
+            tmpb->template=NULL;
+          else
+            tmpb->type=BE_TEMPLATE_COPY;
+          BgtIns(tmpb);
+        }
+        d+=tmpt->period*0x100000000;
+        first=FALSE;
+      }
+      break;
+    case BT_MONTHLY:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        if (++ds.mon>12) {
+          ds.mon=1;
+          ds.year++;
+        }
+        first=FALSE;
+      }
+      break;
+    case BT_BIMONTHLY:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        ds.mon+=2;
+        if (ds.mon>12) {
+          ds.mon-=12;
+          ds.year++;
+        }
+        first=FALSE;
+      }
+      break;
+    case BT_SEMIANNUAL:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        ds.mon+=6;
+        if (ds.mon>12) {
+          ds.mon-=12;
+          ds.year++;
+        }
+        first=FALSE;
+      }
+      break;
+    case BT_ANNUAL:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        ds.year++;
+        first=FALSE;
+      }
+      break;
+  }
+}
+
+U0 CBgtTemplatesExpand()
+{
+  CBgtTemplate  *tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    BgtTemplateExpand(tmpt);
+    tmpt=tmpt->next;
+  }
+}
+
+CBgtTemplate *BgtTemplatePmt(CBgtTemplate *dft_t=NULL,CBgtEntry *dft_b=NULL)
+{
+  CBgtTemplate  t,*tmpt;
+  CBgtEntry     *tmpb;
+  MemSet(&t,0,sizeof(CBgtTemplate));
+  if (dft_t) {
+    MemCpy(&t.start,&dft_t->start,BT_SIZE);
+    dft_b=&dft_t->b;
+  } else {
+    t.type=BT_INTERVAL;
+    if (dft_b)
+      StrPrint(&t.start_date,"%D",dft_b->date);
+    else
+      StrCpy(&t.start_date,"[");
+    StrCpy(&t.end_date,"]");
+  }
+  while (TRUE)
+    if (PopUpForm(&t) && ((t.type==BT_INTERVAL && t.period>0) ||
+          t.type>BT_INTERVAL)) {
+      if (tmpb=BgtEntryPmt(dft_b)) {
+        tmpt=CAlloc(sizeof(CBgtTemplate));
+        MemCpy(&tmpt->start,&t.start,BT_SIZE);
+        MemCpy(&tmpt->b,tmpb,sizeof(CBgtEntry));
+        Free(tmpb);
+        return tmpt;
+      }
+    } else
+      break;
+  return NULL;
+}
+
+ diff --git a/public/Wb/Apps/Budget/Budget.HC.HTML b/public/Wb/Apps/Budget/Budget.HC.HTML new file mode 100755 index 0000000..c6f7a47 --- /dev/null +++ b/public/Wb/Apps/Budget/Budget.HC.HTML @@ -0,0 +1,108 @@ + + + + + + + + + + + +
+U8 *bgt_string_file;
+U8 *bgt_accts_file;
+U8 *bgt_data_file;
+
+#define BE_NORMAL               0
+#define BE_GAS                  1
+#define BE_ANNIVERSARY          2
+#define BE_PRICE                3
+#define BE_TEMPLATE_COPY        4
+
+extern class CBgtTemplate;
+
+class CBgtEntry
+{
+  CBgtEntry *next,*last;
+
+  U0 start;
+  CDate date;
+  U16 type,flags;
+  U32 credit_idx,debit_idx,desc_idx;
+  F64 amount;
+  U0 end;
+
+  U8 *credit,*debit,*desc;
+  CBgtTemplate *template;
+  CDocEntry *doc_e;
+} b_head;
+#define BE_SIZE (offset(CBgtEntry.end)-offset(CBgtEntry.start))
+
+#define BT_NULL         0
+#define BT_INTERVAL     1
+#define BT_MONTHLY      2
+#define BT_BIMONTHLY    3
+#define BT_SEMIANNUAL   4
+#define BT_ANNUAL       5
+
+DefineLstLoad("ST_BGT_TEMPLATE_TYPES",
+        "Null\0Interval\0Monthly\0Bimonthly\0Semiannual\0Annual\0");
+
+class CBgtTemplate
+{
+  CBgtTemplate *next,*last;
+
+  U0 start;
+  U16 type              format "$LS,D=\"ST_BGT_TEMPLATE_TYPES\"$\n";
+  U16 flags;
+  U8 start_date[16]     format "$DA-P,A=\"Start Date:%s\"$\n";
+  U8 end_date[16]       format "$DA-P,A=\"End Date  :%s\"$\n";
+  F64 period            format "$DA,A=\"Period    :%8.2f\"$\n";
+  U0 end;
+
+  CBgtEntry b;
+} t_head;
+#define BT_SIZE (offset(CBgtTemplate.end)-offset(CBgtTemplate.start))
+
+U8 view_acct[512];
+CHashTable *accts_table=NULL;
+I64 accts_table_strs=0;
+
+CDate MyStr2Date(U8 *st)
+{
+  CDateStruct   ds;
+  CDate         res;
+  if (st&&*st) {
+    if (StrOcc(st,'['))
+      res=b_head.next->date;
+    else if (StrOcc(st,']'))
+      res=b_head.last->date;
+    else
+      res=Str2Date(st);
+  } else
+    res=Now;
+  Date2Struct(&ds,res);
+  if (ds.year>2050)
+    ds.year-=100;
+  return Struct2Date(&ds);
+}
+
+ diff --git a/public/Wb/Apps/Budget/Install.HC.HTML b/public/Wb/Apps/Budget/Install.HC.HTML new file mode 100755 index 0000000..03cd450 --- /dev/null +++ b/public/Wb/Apps/Budget/Install.HC.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+if (!FileFind("~/Budget",,FUF_JUST_DIRS)) {
+  DirMk("~/Budget");
+  Copy("Accts.DD.Z","~/Budget");
+}
+
+ diff --git a/public/Wb/Apps/Budget/Load.HC.HTML b/public/Wb/Apps/Budget/Load.HC.HTML new file mode 100755 index 0000000..feea5f3 --- /dev/null +++ b/public/Wb/Apps/Budget/Load.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+#help_index "Finance"
+
+Cd(__DIR__);;
+#include "BgtStrs"
+#include "Budget"
+#include "BgtAccts"
+#include "BgtEntry"
+#include "BgtTemplate"
+#include "BgtFile"
+#include "BgtMain"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/Budget/Run.HC.HTML b/public/Wb/Apps/Budget/Run.HC.HTML new file mode 100755 index 0000000..9a7a9a4 --- /dev/null +++ b/public/Wb/Apps/Budget/Run.HC.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+#include "Install" //Might as well always install
+Budget;
+
+ diff --git a/public/Wb/Apps/GrModels/BallGen.HC.HTML b/public/Wb/Apps/GrModels/BallGen.HC.HTML new file mode 100755 index 0000000..c917f0c --- /dev/null +++ b/public/Wb/Apps/GrModels/BallGen.HC.HTML @@ -0,0 +1,159 @@ + + + + + + + + + + + +
+//Makes a mesh ball.
+
+#define VERTICES_NUM    1024
+#define TRIS_NUM        1024
+
+class Ball
+{
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  CD3I32            v[VERTICES_NUM];
+  CMeshTri t[TRIS_NUM];
+} *b;
+
+class BallDefineStruct
+{
+  F64 radius    format   "$DA-TRM,A=\"Radius         :%8.3f\"$\n";
+  I64 n_longitude format "$DA-TRM,A=\"Longitude Faces:%5d\"$\n";
+  I64 n_lattitude format "$DA-TRM,A=\"Lattitude Rings:%5d\"$\n";
+};
+
+U0 BDInit(BallDefineStruct *bd)
+{
+  MemSet(bd,0,sizeof(BallDefineStruct));
+  bd->n_longitude=16;
+  bd->n_lattitude=8;
+  bd->radius     =20.0;
+}
+
+U0 BDCorrect(BallDefineStruct *bd)
+{
+  bd->n_longitude=(bd->n_longitude+1)/2;
+  bd->n_lattitude=(bd->n_lattitude+1)/2;
+}
+
+I64 AddVertex(BallDefineStruct *,I64 x,I64 y,I64 z)
+{
+  I64 i;
+  for (i=0;i<b->vertex_cnt;i++)
+    if (b->v[i].x==x && b->v[i].y==y && b->v[i].z==z)
+      return i;
+  i=b->vertex_cnt++;
+  b->v[i].x=x;
+  b->v[i].y=y;
+  b->v[i].z=z;
+  return i;
+}
+
+I64 AddTri(BallDefineStruct *,I64 c,I64 n0,I64 n1,I64 n2)
+{
+  I64 res=b->tri_cnt++;
+  b->t[res].color=c;
+  b->t[res].nums[0]=n0;
+  b->t[res].nums[1]=n1;
+  b->t[res].nums[2]=n2;
+  return res;
+}
+
+U8 *Ball2CSprite()
+{
+//See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+  U8 *res=MAlloc(sizeof(CSpriteMeshU8s)+
+        b->vertex_cnt*sizeof(CD3I32)+b->tri_cnt*sizeof(CMeshTri)
+  +sprite_elem_base_sizes[SPT_END]),
+        *dst=res;
+  *dst++ =SPT_MESH;
+  *dst(I32 *)++ =b->vertex_cnt;
+  *dst(I32 *)++ =b->tri_cnt;
+  MemCpy(dst,&b->v,b->vertex_cnt*sizeof(CD3I32));
+  dst+=b->vertex_cnt*sizeof(CD3I32);
+  MemCpy(dst,&b->t,b->tri_cnt*sizeof(CMeshTri));
+  dst+=b->tri_cnt*sizeof(CMeshTri);
+  *dst++ =SPT_END;
+  return res;
+}
+
+public U8 *BallGen()
+{
+  U8 *res;
+  I64 i,j,n,m,c,p1,p2,p3,p4;
+  BallDefineStruct bd1,bd2;
+  F64 r,r1,r2,z1,z2,d_a1,d_a2;
+
+  BDInit(&bd1);
+
+  while (TRUE) {
+    if (!DocForm(&bd1))
+      return NULL;
+    MemCpy(&bd2,&bd1,sizeof(BallDefineStruct));
+    BDCorrect(&bd2);
+
+    c=PopUpColorLighting;
+    if (c<0)  return NULL;
+
+    b=CAlloc(sizeof(Ball));
+    r=bd2.radius;
+    n=bd2.n_lattitude;
+    m=bd2.n_longitude;
+    d_a1=2*pi/n/4;
+    d_a2=2*pi/m/2;
+    for (j=-n;j<n;j++) {
+      r1=r*Cos( j   *d_a1);
+      r2=r*Cos((j+1)*d_a1);
+      z1=r*Sin( j   *d_a1);
+      z2=r*Sin((j+1)*d_a1);
+      for (i=0;i<m;i++) {
+        p1=AddVertex(&bd2,r1*Cos((2*i  +j)*d_a2),r1*Sin((2*i  +j)*d_a2),z1);
+        p2=AddVertex(&bd2,r1*Cos((2*i+2+j)*d_a2),r1*Sin((2*i+2+j)*d_a2),z1);
+        p3=AddVertex(&bd2,r2*Cos((2*i+1+j)*d_a2),r2*Sin((2*i+1+j)*d_a2),z2);
+        p4=AddVertex(&bd2,r2*Cos((2*i+3+j)*d_a2),r2*Sin((2*i+3+j)*d_a2),z2);
+        AddTri(&bd2,c,p1,p2,p3);
+        AddTri(&bd2,c,p3,p2,p4);
+      }
+    }
+
+    res=Ball2CSprite;
+    "%h7c",'\n';
+    Sprite(res,"\t\t$SP,\"<1>\",BI=%d$");
+    "%h7c",'\n';
+    "Vertices:%d\n",b->vertex_cnt;
+    Free(b);
+    "Do another";
+    if (YorN)
+      Free(res);
+    else
+      break;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Apps/GrModels/Load.HC.HTML b/public/Wb/Apps/GrModels/Load.HC.HTML new file mode 100755 index 0000000..ca13d9b --- /dev/null +++ b/public/Wb/Apps/GrModels/Load.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#help_index "Misc"
+
+Cd(__DIR__);;
+#include "ManGen"
+#include "BallGen"
+#include "Models"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/GrModels/ManGen.HC.HTML b/public/Wb/Apps/GrModels/ManGen.HC.HTML new file mode 100755 index 0000000..bacff26 --- /dev/null +++ b/public/Wb/Apps/GrModels/ManGen.HC.HTML @@ -0,0 +1,351 @@ + + + + + + + + + + + +
+//Makes a mesh man.
+
+#define VERTICES_NUM    1024
+#define TRIS_NUM        1024
+
+class Man
+{
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  CD3I32   v[VERTICES_NUM];
+  CMeshTri t[TRIS_NUM];
+} *m;
+
+class ManDefineStruct
+{
+  F64 head_rad   format
+        "$DA-TRM,A=\"Head Radius                :%8.3f\"$\n";
+
+  F64 torso_len  format
+        "$DA-TRM,A=\"Torso Length               :%8.3f\"$\n";
+  F64 arm_len    format
+        "$DA-TRM,A=\"Arm Length                 :%8.3f\"$\n";
+  F64 hand_len   format
+        "$DA-TRM,A=\"Hand Length                :%8.3f\"$\n";
+  F64 leg_len    format
+        "$DA-TRM,A=\"Leg Length                 :%8.3f\"$\n";
+  F64 foot_len   format
+        "$DA-TRM,A=\"Foot Length                :%8.3f\"$\n";
+  F64 torso_width format
+        "$DA-TRM,A=\"Torso Width                :%8.3f\"$\n";
+  F64 torso_depth format
+        "$DA-TRM,A=\"Torso Depth                :%8.3f\"$\n";
+  F64 arm_rad    format
+        "$DA-TRM,A=\"Arm Radius                 :%8.3f\"$\n";
+  F64 hand_rad   format
+        "$DA-TRM,A=\"Hand Radius                :%8.3f\"$\n";
+  F64 leg_rad    format
+        "$DA-TRM,A=\"Leg Radius                 :%8.3f\"$\n";
+  F64 foot_rad   format
+        "$DA-TRM,A=\"Foot Radius                :%8.3f\"$\n\n";
+
+  F64 r_shoulder_a1      format
+        "$DA-TRM,A=\"R.Shoulder Front/Back Angle:%8.3f\"$\n";
+  F64 l_shoulder_a1      format
+        "$DA-TRM,A=\"L.Shoulder Front/Back Angle:%8.3f\"$\n";
+  F64 r_hip_a1   format
+        "$DA-TRM,A=\"R.Hip Front/Back Angle     :%8.3f\"$\n";
+  F64 l_hip_a1   format
+        "$DA-TRM,A=\"L.Hip Front/Back Angle     :%8.3f\"$\n";
+
+  F64 r_shoulder_a2      format
+        "$DA-TRM,A=\"R.Shoulder Side Angle      :%8.3f\"$\n";
+  F64 l_shoulder_a2      format
+        "$DA-TRM,A=\"L.Shoulder Side Angle      :%8.3f\"$\n";
+  F64 r_hip_a2   format
+        "$DA-TRM,A=\"R.Hip Side Angle           :%8.3f\"$\n";
+  F64 l_hip_a2   format
+        "$DA-TRM,A=\"L.Hip Side Angle           :%8.3f\"$\n";
+
+  F64 r_elbow_a  format
+        "$DA-TRM,A=\"R.Elbow Angle              :%8.3f\"$\n";
+  F64 l_elbow_a  format
+        "$DA-TRM,A=\"L.Elbow Angle              :%8.3f\"$\n";
+  F64 r_knee_a   format
+        "$DA-TRM,A=\"R.Knee Angle               :%8.3f\"$\n";
+  F64 l_knee_a   format
+        "$DA-TRM,A=\"L.Knee Angle               :%8.3f\"$\n";
+
+  F64 r_wrist_a  format
+        "$DA-TRM,A=\"R.Wrist Angle              :%8.3f\"$\n";
+  F64 l_wrist_a  format
+        "$DA-TRM,A=\"L.Wrist Angle              :%8.3f\"$\n";
+  F64 r_ankle_a  format
+        "$DA-TRM,A=\"R.Ankle Angle              :%8.3f\"$\n";
+  F64 l_ankle_a  format
+        "$DA-TRM,A=\"L.Ankle Angle              :%8.3f\"$\n";
+
+};
+
+U0 MDInit(ManDefineStruct *md)
+{
+  MemSet(md,0,sizeof(ManDefineStruct));
+
+  md->head_rad  =5.0;
+
+  md->torso_len =35.0;
+  md->arm_len   =30.0;
+  md->hand_len  =8.0;
+  md->leg_len   =32.0;
+  md->foot_len  =16.0;
+  md->torso_width=20.0;
+  md->torso_depth=10.0;
+  md->arm_rad   =3.5;
+  md->hand_rad  =2.0;
+  md->leg_rad   =4.0;
+  md->foot_rad  =3.0;
+
+  md->r_shoulder_a1     =30;
+  md->l_shoulder_a1     =-30;
+  md->r_hip_a1  =-45;
+  md->l_hip_a1  =45;
+
+  md->r_shoulder_a2     =10;
+  md->l_shoulder_a2     =10;
+  md->r_hip_a2  =-5;
+  md->l_hip_a2  =-5;
+
+  md->r_elbow_a =30;
+  md->l_elbow_a =0;
+  md->r_knee_a  =0;
+  md->l_knee_a  =30;
+
+  md->r_wrist_a =0;
+  md->l_wrist_a =0;
+  md->r_ankle_a =0;
+  md->l_ankle_a =0;
+}
+
+U0 MDCorrect(ManDefineStruct *md)
+{
+  md->r_ankle_a    =-md->r_ankle_a;
+  md->l_ankle_a    =-md->l_ankle_a;
+  md->r_knee_a    =-md->r_knee_a;
+  md->l_knee_a    =-md->l_knee_a;
+  md->r_hip_a2     =-md->r_hip_a2;
+  md->r_shoulder_a2=-md->r_shoulder_a2;
+  md->r_ankle_a+=90;
+  md->l_ankle_a+=90;
+
+  md->foot_len-=md->leg_rad;
+
+  md->r_elbow_a+=md->r_shoulder_a1;
+  md->l_elbow_a+=md->l_shoulder_a1;
+  md->r_knee_a+=md->r_hip_a1;
+  md->l_knee_a+=md->l_hip_a1;
+
+  md->r_wrist_a+=md->r_elbow_a;
+  md->l_wrist_a+=md->l_elbow_a;
+  md->r_ankle_a+=md->r_knee_a;
+  md->l_ankle_a+=md->l_knee_a;
+}
+
+I64 AddVertex(ManDefineStruct *md,I64 x,I64 y,I64 z)
+{
+  I64 res=m->vertex_cnt++;
+  m->v[res].x=-x;
+  m->v[res].y=-y-md->leg_len-md->foot_rad*2;
+  m->v[res].z=-z;
+  return res;
+}
+
+I64 AddTri(ManDefineStruct *,I64 c,I64 n0,I64 n1,I64 n2)
+{
+  I64 res=m->tri_cnt++;
+  m->t[res].color=c;
+  m->t[res].nums[0]=n1;
+  m->t[res].nums[1]=n0;
+  m->t[res].nums[2]=n2;
+  return res;
+}
+
+U0 AddBox(ManDefineStruct *md,I64 c,I64 x1,I64 y1,I64 z1,
+        F64 w,F64 h,F64 d,F64 h2,F64 h3,F64 az,F64 ay,F64 ax,
+        I64 *ox,I64 *oy,I64 *oz)
+{
+  I64 *r;
+  I64 p1a,p2a,p3a,p4a;
+  I64 p1b,p2b,p3b,p4b;
+  I64 wx=w/2,wy=0,wz=0,hx=0,hy=h,hz=0,h2x=0,h2y=h2,h2z=0,
+        h3x=0,h3y=h3,h3z=0,dx=0,dy=0,dz=d/2;
+
+  r=Mat4x4IdentNew;
+  Mat4x4RotZ(r,az*pi/180.0);
+  Mat4x4RotY(r,ay*pi/180.0);
+  Mat4x4RotX(r,ax*pi/180.0);
+  Mat4x4MulXYZ(r,&wx,&wy,&wz);
+  Mat4x4MulXYZ(r,&hx,&hy,&hz);
+  Mat4x4MulXYZ(r,&h2x,&h2y,&h2z);
+  Mat4x4MulXYZ(r,&h3x,&h3y,&h3z);
+  Mat4x4MulXYZ(r,&dx,&dy,&dz);
+
+  p1a=AddVertex(md,x1+dx        -wx+h2x,y1+dy   -wy+h2y,z1+dz   -wz+h2z);
+  p2a=AddVertex(md,x1+dx        +wx+h2x,y1+dy   +wy+h2y,z1+dz   +wz+h2z);
+  p3a=AddVertex(md,x1+dx+hx-wx    ,y1+dy+hy-wy    ,z1+dz+hz-wz);
+  p4a=AddVertex(md,x1+dx+hx+wx    ,y1+dy+hy+wy    ,z1+dz+hz+wz);
+  AddTri(md,c,p1a,p2a,p3a);
+  AddTri(md,c,p4a,p3a,p2a);
+
+  p1b=AddVertex(md,x1-dx        -wx+h2x,y1-dy   -wy+h2y,z1-dz   -wz+h2z);
+  p2b=AddVertex(md,x1-dx        +wx+h2x,y1-dy   +wy+h2y,z1-dz   +wz+h2z);
+  p3b=AddVertex(md,x1-dx+hx-wx    ,y1-dy+hy-wy    ,z1-dz+hz-wz);
+  p4b=AddVertex(md,x1-dx+hx+wx    ,y1-dy+hy+wy    ,z1-dz+hz+wz);
+  AddTri(md,c,p1b,p2b,p3b);
+  AddTri(md,c,p4b,p3b,p2b);
+
+  AddTri(md,c,p1a,p2a,p1b);
+  AddTri(md,c,p2b,p1b,p2a);
+  AddTri(md,c,p3a,p4a,p3b);
+  AddTri(md,c,p4b,p3b,p4a);
+  AddTri(md,c,p1a,p3a,p1b);
+  AddTri(md,c,p3b,p1b,p3a);
+  AddTri(md,c,p2a,p4a,p2b);
+  AddTri(md,c,p4b,p2b,p4a);
+
+  *ox=x1+hx-h3x;
+  *oy=y1+hy-h3y;
+  *oz=z1+hz-h3z;
+
+  Free(r);
+}
+
+U8 *Man2CSprite()
+{
+//See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+  U8 *res=MAlloc(sizeof(CSpriteMeshU8s)+
+        m->vertex_cnt*sizeof(CD3I32)+m->tri_cnt*sizeof(CMeshTri)+
+        sprite_elem_base_sizes[SPT_END]),
+        *dst=res;
+  *dst++ =SPT_MESH;
+  *dst(I32 *)++ =m->vertex_cnt;
+  *dst(I32 *)++ =m->tri_cnt;
+  MemCpy(dst,&m->v,m->vertex_cnt*sizeof(CD3I32));
+  dst+=m->vertex_cnt*sizeof(CD3I32);
+  MemCpy(dst,&m->t,m->tri_cnt*sizeof(CMeshTri));
+  dst+=m->tri_cnt*sizeof(CMeshTri);
+  *dst++ =SPT_END;
+  return res;
+}
+
+public U8 *ManGen()
+{
+  U8 *res;
+  I64 x,y,z,c1,c2,c3,c4;
+  ManDefineStruct md1,md2;
+  MDInit(&md1);
+
+  while (TRUE) {
+    if (!DocForm(&md1))
+      return NULL;
+    MemCpy(&md2,&md1,sizeof(ManDefineStruct));
+    MDCorrect(&md2);
+
+    c1=PopUpColorLighting("$BK,1$Shirt$BK,0$\n");
+    if (c1<0) return NULL;
+    c2=PopUpColorLighting("$BK,1$Pants$BK,0$\n");
+    if (c2<0) return NULL;
+    c3=PopUpColorLighting("$BK,1$Skin$BK,0$\n");
+    if (c3<0) return NULL;
+    c4=PopUpColorLighting("$BK,1$Shoes$BK,0$\n");
+    if (c4<0) return NULL;
+
+    m=CAlloc(sizeof(Man));
+
+    //Head
+    AddBox(&md2,c3,0,md2.torso_len+md2.head_rad*2,0,
+          md2.head_rad*2,-md2.head_rad*2,md2.head_rad*2,0,0, 0,0,0,
+          &x,&y,&z);
+
+    //Torso
+    AddBox(&md2,c1,0,md2.torso_len,0,
+          md2.torso_width,-md2.torso_len,md2.torso_depth,0,0, 0,0,0,
+          &x,&y,&z);
+
+    //Right Arm
+    AddBox(&md2,c1,-md2.torso_width/2-md2.arm_rad,md2.torso_len-md2.arm_rad,0,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,md2.arm_rad,0,
+          md2.r_shoulder_a2,0,md2.r_shoulder_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,0,0,
+          md2.r_shoulder_a2,0,md2.r_elbow_a,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.hand_len,md2.hand_rad*2,0,0,
+          md2.r_shoulder_a2,0,md2.r_wrist_a,&x,&y,&z);
+
+    //Left Arm
+    AddBox(&md2,c1,md2.torso_width/2+md2.arm_rad,md2.torso_len-md2.arm_rad,0,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,md2.arm_rad,0,
+          md2.l_shoulder_a2,0,md2.l_shoulder_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,0,0,
+          md2.l_shoulder_a2,0,md2.l_elbow_a,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.hand_len,md2.hand_rad*2,0,0,
+          md2.l_shoulder_a2,0,md2.l_wrist_a,&x,&y,&z);
+
+    //Right Leg
+    AddBox(&md2,c2,-md2.torso_width/2+md2.leg_rad,0,0,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,0,
+          md2.r_hip_a2,0,md2.r_hip_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,md2.foot_rad,
+          md2.r_hip_a2,0,md2.r_knee_a,&x,&y,&z);
+    AddBox(&md2,c4,x,y,z,
+          md2.leg_rad*2,-md2.foot_len,md2.foot_rad*2,md2.leg_rad,0,
+          md2.r_hip_a2,0,md2.r_ankle_a,&x,&y,&z);
+
+    //Left Leg
+    AddBox(&md2,c2,md2.torso_width/2-md2.leg_rad,0,0,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,0,
+          md2.l_hip_a2,0,md2.l_hip_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,md2.foot_rad,
+          md2.l_hip_a2,0,md2.l_knee_a,&x,&y,&z);
+    AddBox(&md2,c4,x,y,z,
+          md2.leg_rad*2,-md2.foot_len,md2.foot_rad*2,md2.leg_rad,0,
+          md2.l_hip_a2,0,md2.l_ankle_a,&x,&y,&z);
+
+    res=Man2CSprite;
+    "%h7c",'\n';
+    Sprite(res,"\t\t$SP,\"<1>\",BI=%d$");
+    "%h7c",'\n';
+    Free(m);
+    "Do another";
+    if (YorN)
+      Free(res);
+    else
+      break;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Apps/GrModels/Models.HC.HTML b/public/Wb/Apps/GrModels/Models.HC.HTML new file mode 100755 index 0000000..11d031d --- /dev/null +++ b/public/Wb/Apps/GrModels/Models.HC.HTML @@ -0,0 +1,56 @@ + + + + + + + + + + + +
+#define T_MAN   0
+#define T_BALL  1
+
+U0 Models()
+{
+  I64 i;
+  Bool old_form=LBts(&(DocPut)->flags,DOCf_FORM);
+  DocClear;
+  "Make a CSprite model.  Then, cut-and-Paste it.\n\n";
+  "$LM,4$";
+  "\n\n$BT,\"Man\",LE=T_MAN$\n\n";
+  "\n\n$BT,\"Ball\",LE=T_BALL$\n\n";
+  "$LM,0$";
+  i=DocMenu(DocPut);
+  LBEqu(&(DocPut)->flags,DOCf_FORM,old_form);
+  DocBottom;
+  switch (i) {
+    case T_MAN:
+      ManGen;
+      break;
+    case T_BALL:
+      BallGen;
+      break;
+  }
+}
+
+ diff --git a/public/Wb/Apps/GrModels/Run.HC.HTML b/public/Wb/Apps/GrModels/Run.HC.HTML new file mode 100755 index 0000000..93bac8d --- /dev/null +++ b/public/Wb/Apps/GrModels/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Models;
+ diff --git a/public/Wb/Apps/KeepAway/KeepAway.HC.HTML b/public/Wb/Apps/KeepAway/KeepAway.HC.HTML new file mode 100755 index 0000000..2fb39de --- /dev/null +++ b/public/Wb/Apps/KeepAway/KeepAway.HC.HTML @@ -0,0 +1,740 @@ + + + + + + + + + + + +
+//The ball and men were generated
+//with ::/Apps/GrModels/Run.HC.
+//They were cut-and-pasted here.
+
+
+                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <9>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <11>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <12>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <13>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <14>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <15>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <16>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <17>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <18>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <19>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <20>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <21>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <22>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <23>/* Graphics Not Rendered in HTML */
+
+
+
+class Frame
+{
+  U8 *img[2];
+  F64 dt;
+};
+
+#define COURT_BORDER            10
+#define COLLISION_DAMP          0.8
+#define AIR_VISCOSITY           0.1
+
+#define GRAVITY_ACCELERATION    500
+#define SHOT_VELOCITY           400
+#define DRIBBLE_T               0.25
+#define MAN_VELOCITY            150
+#define MAN_SQR_RADIUS          (20*20)
+#define FOUL_VELOCITY_THRESHOLD 50
+#define JUMP_VELOCITY           250
+#define ROLL_VELOCITY_THRESHOLD 100
+#define RANDOM_MAN_ACCELERATION 30
+
+#define HEAD_Z_OFFSET   200
+#define HAND_X_OFFSET   30
+#define HAND_Y_OFFSET   20
+#define HAND_SQR_OFFSET \
+        (HAND_X_OFFSET*HAND_X_OFFSET+HAND_Y_OFFSET*HAND_Y_OFFSET)
+#define HAND_Z_OFFSET   110
+
+#define FIRST_STANDING          0
+
+#define RUNNING_IMGS_NUM        4
+#define FIRST_RUNNING   0
+#define LAST_RUNNING    (FIRST_RUNNING+RUNNING_IMGS_NUM-1)
+
+#define SHOOTING_IMGS_NUM       5
+#define FIRST_SHOOTING  (LAST_RUNNING+1)
+#define LAST_SHOOTING   (FIRST_SHOOTING+SHOOTING_IMGS_NUM-1)
+
+#define DRIBBLING_IMGS_NUM      4
+#define FIRST_DRIBBLING (LAST_SHOOTING+1)
+#define LAST_DRIBBLING  (FIRST_DRIBBLING+DRIBBLING_IMGS_NUM-1)
+
+#define STOPPED_DRIBBLING_IMGS_NUM      2
+#define FIRST_STOPPED_DRIBBLING (LAST_DRIBBLING+1)
+#define LAST_STOPPED_DRIBBLING  \
+        (FIRST_STOPPED_DRIBBLING+STOPPED_DRIBBLING_IMGS_NUM-1)
+
+Frame imgs[LAST_STOPPED_DRIBBLING+1]={
+  {{<6>,<7>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<2>,<3>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<6>,<7>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<4>,<5>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<8>,<9>},0.1},{{<10>,<11>},0.2},
+  {{<12>,<13>},0.2},{{<12>,<13>},0.1},{{<14>,<15>},0.1},
+  {{<20>,<21>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<16>,<17>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<20>,<21>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<18>,<19>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<20>,<21>},DRIBBLE_T/STOPPED_DRIBBLING_IMGS_NUM},
+  {{<22>,<23>},DRIBBLE_T/STOPPED_DRIBBLING_IMGS_NUM},
+};
+
+RegDft("TempleOS/KeepAway","I64 best_score0=0,best_score1=9999;\n");
+RegExe("TempleOS/KeepAway");
+
+F64 game_t_end,foul_t_end;
+I64 score0,score1;
+
+#define PER_SIDE_NUM    3
+#define OBJS_NUM        (PER_SIDE_NUM*2+1)
+Bool someone_shooting,someone_has_ball;
+F64 shot_land_t;
+        
+class Obj
+{
+  I64 team; //-1 is ball
+  F64 x,y,z,DxDt,DyDt,DzDt,theta,radius,stolen_t0;
+  F64 get_ball_dt,get_ball_theta,nearest_man_dd,last_t0,next_t0,foul_t0;
+  I64 last_img,next_img;
+  Bool stopped,shooting,has_ball,nearest_ball,pad[4];
+} objs[OBJS_NUM],*ball,*human,*last_owner;
+
+/*Just to be different, I didn't use the built-in
+DCF_TRANSFORMATION flag in this game.
+Instead, I chose a 45 degree angle
+between Y and Z as the view point.
+If I had used the transform, I would
+have to make all my men taller.
+This is a little simpler, and faster,
+but adds lots of factor 2 vals.
+
+I also didn't use the CMathODE feat,
+just to be different.
+*/
+
+U0 DrawObj(CDC *dc,Obj *o,F64 tt)
+{
+  U8 *tmps;
+  F64 r1=Max(9-0.1*o->z,1),r2=Max(r1/4,1);
+
+  if (o==human)
+    dc->color=LTRED;
+  else
+    dc->color=BLACK;
+  GrEllipse(dc,o->x,o->y/2,r1,r2);
+  GrFloodFill(dc,o->x,o->y/2);
+
+  if (o==ball)
+    Sprite3(dc,o->x,(o->y-o->z)/2,GR_Z_ALL-o->y,<1>);
+  else {
+    tmps=SpriteInterpolate((tt-o->last_t0)/(o->next_t0-o->last_t0),
+          imgs[o->last_img].img[o->team],
+          imgs[o->next_img].img[o->team]);
+    Sprite3YB(dc,o->x,(o->y-o->z)/2,GR_Z_ALL-o->y,tmps,o->theta);
+    Free(tmps);
+  }
+}
+
+I64 ObjCompare(Obj *o1,Obj *o2)
+{
+  return o1->y-o2->y;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 tt=tS,d,d_down,d_up;
+  I64 i;
+  Obj *o_sort[OBJS_NUM],*o;
+
+  DCDepthBufAlloc(dc);
+  dc->ls.x=10000;
+  dc->ls.y=60000;
+  dc->ls.z=10000;
+  d=65535/D3I32Norm(&dc->ls);
+  dc->ls.x*=d;
+  dc->ls.y*=d;
+  dc->ls.z*=d;
+
+  dc->thick=2;
+  dc->color=RED;
+  GrBorder(dc,COURT_BORDER,COURT_BORDER,
+        task->pix_width -1-COURT_BORDER,
+        task->pix_height-1-COURT_BORDER);
+  for (i=0;i<OBJS_NUM;i++) {
+    o=o_sort[i]=&objs[i];
+    if (o!=ball) {
+      if (o->has_ball) {
+        ball->x=o->x+HAND_X_OFFSET*Cos(o->theta-pi/2)+HAND_Y_OFFSET*Cos(o->theta);
+//The factor 2 is because the man is not transformed.
+        ball->y=o->y+HAND_X_OFFSET*Sin(o->theta-pi/2)/2+HAND_Y_OFFSET*Sin(o->theta)/2;
+        if (ball->z+ball->radius*2>o->z+HAND_Z_OFFSET)
+          ball->z=o->z+HAND_Z_OFFSET-ball->radius*2;
+      } else if (o->shooting) {
+        ball->x=o->x;
+        ball->y=o->y;
+        ball->z=o->z+HEAD_Z_OFFSET;
+      }
+      if (tt>o->next_t0) {
+        if (o->has_ball && (ball->z+ball->radius*2>=o->z+HAND_Z_OFFSET ||
+              Abs(ball->DzDt)<30)) {
+//This is an approximation.  My instinct tells me the viscosity term
+          //needs an Exp().  However, we should be syncronized to img frames,
+          //so we don't have to be perfect.
+          d_down=1.0;
+          d_up  =1.0/COLLISION_DAMP;
+//Up bounce takes higher % because speed lost in collision.
+          ball->DzDt=-((d_down+d_up)*
+                (o->z+HAND_Z_OFFSET-ball->radius*4)/(1.0-AIR_VISCOSITY)+
+                0.5*GRAVITY_ACCELERATION*(
+                Sqr(DRIBBLE_T*d_up/(d_down+d_up))-
+                Sqr(DRIBBLE_T*d_down/(d_down+d_up)) ))/DRIBBLE_T;
+        }
+        o->last_t0=tt;
+        o->last_img=o->next_img++;
+        if (o->stopped) {
+          if (o->has_ball) {
+            if (!(FIRST_STOPPED_DRIBBLING<=o->next_img<=LAST_STOPPED_DRIBBLING))
+              o->next_img=FIRST_STOPPED_DRIBBLING;
+          } else
+            o->next_img=FIRST_STANDING;
+          o->stopped=FALSE;
+        } else if (o->shooting) {
+          if (!(FIRST_SHOOTING<=o->last_img<=LAST_SHOOTING))
+            o->next_img=FIRST_SHOOTING;
+          if (o->next_img>LAST_SHOOTING) {
+            o->next_img=FIRST_STANDING;
+            someone_has_ball=someone_shooting=o->has_ball=o->shooting=FALSE;
+            ball->DxDt=o->DxDt+SHOT_VELOCITY/sqrt2*Cos(o->theta-pi/2);
+            ball->DyDt=o->DyDt+SHOT_VELOCITY/sqrt2*Sin(o->theta-pi/2);
+            ball->DzDt=o->DzDt+SHOT_VELOCITY/sqrt2;
+            shot_land_t=tt+(ball->DzDt+Sqrt(Sqr(ball->DzDt)+
+                2*GRAVITY_ACCELERATION*ball->z))/GRAVITY_ACCELERATION;
+          } else {
+            ball->DxDt=0;
+            ball->DyDt=0;
+            ball->DzDt=0;
+          }
+        } else if (o->has_ball) {
+          if (FIRST_RUNNING<=o->next_img<=LAST_RUNNING)
+            o->next_img+=FIRST_DRIBBLING-FIRST_RUNNING;
+          if (!(FIRST_DRIBBLING<=o->next_img<=LAST_DRIBBLING))
+            o->next_img=FIRST_DRIBBLING;
+        } else {
+          if (FIRST_DRIBBLING<=o->next_img<=LAST_DRIBBLING)
+            o->next_img+=FIRST_RUNNING-FIRST_DRIBBLING;
+          if (!(FIRST_RUNNING<=o->next_img<=LAST_RUNNING))
+            o->next_img=FIRST_RUNNING;
+        }
+        o->next_t0+=imgs[o->last_img].dt;
+        if (o->next_t0<=tt)
+          o->next_t0=tt+imgs[o->last_img].dt;
+      }
+    }
+  }
+
+  QSortI64(o_sort,OBJS_NUM,&ObjCompare);
+  for (i=0;i<OBJS_NUM;i++)
+    DrawObj(dc,o_sort[i],tt);
+  tt=(game_t_end-tS)/60;
+  if (tt<=0) {
+    dc->color=RED;
+    tt=0;
+    if (Blink)
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*9)>>1,
+            (task->pix_height-FONT_HEIGHT)>>1,"Game Over");
+  } else {
+    if (tS<foul_t_end) {
+      dc->color=LTRED;
+      if (Blink)
+        GrPrint(dc,(task->pix_width-FONT_WIDTH*4)>>1,
+              (task->pix_height-FONT_HEIGHT)>>1,"Foul");
+    }
+    dc->color=BLACK;
+  }
+  GrPrint(dc,0,0,"Time:%d:%04.1f  Score:",ToI64(tt),(tt-ToI64(tt))*60);
+  GrPrint  (dc,FONT_WIDTH*27,0,"Best Score:");
+
+  dc->color=LTCYAN;
+  GrPrint(dc,FONT_WIDTH*20,0,"%02d",score0);
+  dc->color=LTPURPLE;
+  GrPrint(dc,FONT_WIDTH*23,0,"%02d",score1);
+
+  dc->color=LTCYAN;
+  GrPrint(dc,FONT_WIDTH*39,0,"%02d",best_score0);
+  dc->color=LTPURPLE;
+  GrPrint(dc,FONT_WIDTH*42,0,"%02d",best_score1);
+}
+
+U0 Shoot(Obj *o)
+{
+  if (!someone_shooting && o->has_ball) {
+    someone_shooting=o->stopped=o->shooting=TRUE;
+    o->has_ball=FALSE;
+  }
+}
+
+U0 AnimateTask(CTask *parent_task)
+{
+  F64 d,dx,dy,dt,dx2,dy2,t0=tS;
+  I64 i,j;
+  Bool gets_ball;
+  Obj *o,*nearest_ball[2];
+  while (TRUE) {
+    dt=tS-t0;
+    t0=tS;
+
+    if (game_t_end && game_t_end<t0) {
+      game_t_end=0;
+      Beep;
+      if (score0-score1>best_score0-best_score1) {
+        best_score0=score0;
+        best_score1=score1;
+        Snd(86);Sleep(100); Snd;Sleep(100);
+        Snd(86);Sleep(100); Snd;Sleep(100);
+      }
+    }
+
+    if (game_t_end) {
+      MemSet(&nearest_ball,0,sizeof(nearest_ball));
+      for (i=0;i<OBJS_NUM;i++) {
+        o=&objs[i];
+        o->nearest_ball=FALSE;
+        if (o!=ball) {
+          d=0;
+          for (j=0;j<5;j++) //Iterative estimate of how long to get ball.
+            d=Sqrt(Sqr(ball->DxDt*d+ball->x-o->x)+
+                  Sqr(ball->DyDt*d+ball->y-o->y))/MAN_VELOCITY;
+          o->get_ball_dt=d;
+          o->get_ball_theta=Arg(ball->DxDt*d+ball->x-o->x,
+                ball->DyDt*d+ball->y-o->y);
+          if (o!=last_owner && !nearest_ball[o->team] ||
+                o->get_ball_dt<nearest_ball[o->team]->get_ball_dt)
+            nearest_ball[o->team]=o;
+        }
+      }
+      nearest_ball[0]->nearest_ball=TRUE;
+      nearest_ball[1]->nearest_ball=TRUE;
+
+      for (i=0;i<OBJS_NUM;i++) {
+        o=&objs[i];
+        if (o==ball) {
+          o->x+=dt*o->DxDt;
+          o->y+=dt*o->DyDt;
+          if (!someone_shooting)
+            o->z+=dt*(o->DzDt-0.5*GRAVITY_ACCELERATION*dt);
+        } else {
+          if (!o->has_ball) {
+            if (t0-o->stolen_t0>2.0 && !someone_shooting) {
+              dx=ball->x-o->x;
+              dy=ball->y-o->y;
+              if (dx*dx+dy*dy<HAND_SQR_OFFSET && ball->z<o->z+HAND_Z_OFFSET) {
+                gets_ball=TRUE;
+                for (j=0;j<PER_SIDE_NUM*2;j++)
+                  if (j!=i && objs[j].has_ball) {
+                    if (Rand<2.0*dt) {
+                      objs[j].stolen_t0=t0;
+                      objs[j].has_ball=FALSE;
+                    } else
+                      gets_ball=FALSE;
+                  }
+                if (gets_ball) {
+                  someone_has_ball=o->has_ball=TRUE;
+                  if (o!=last_owner) {
+                    if (o->team) {
+                      if (t0<shot_land_t+0.1)
+                        score1+=6;
+                      else
+                        score1+=2;
+                      Noise(250,74,74);
+                    } else {
+                      if (t0<shot_land_t+0.1)
+                        score0+=6;
+                      else
+                        score0+=2;
+                      Noise(250,86,86);
+                    }
+                    last_owner=o;
+                  }
+                }
+              }
+            }
+          } else if (o!=human && Rand<0.25*dt)
+            Shoot(o);
+          if (!o->shooting) {
+            if (o==human) {
+              dx=(ms.pos.x-parent_task->pix_left-parent_task->scroll_x)-o->x;
+              dy=(ms.pos.y-parent_task->pix_top-parent_task->scroll_y)*2-o->y;
+            } else {
+              if (!someone_has_ball && o->nearest_man_dd>4*MAN_SQR_RADIUS &&
+                    o->nearest_ball) {
+                dx=o->DxDt=MAN_VELOCITY*Cos(o->get_ball_theta);
+                dy=o->DyDt=MAN_VELOCITY*Sin(o->get_ball_theta);
+              } else {
+                dx=o->DxDt+=RANDOM_MAN_ACCELERATION/sqrt2*RandI16/I16_MAX*dt;
+                dy=o->DyDt+=RANDOM_MAN_ACCELERATION/sqrt2*RandI16/I16_MAX*dt;
+              }
+            }
+            d=Sqrt(dx*dx+dy*dy);
+            if (d>=1.0) {
+              o->theta=Arg(dx,dy)+pi/2;
+              dx*=MAN_VELOCITY/sqrt2*dt/d;
+              dy*=MAN_VELOCITY/sqrt2*dt/d;
+              o->nearest_man_dd=F64_MAX;
+              for (j=0;j<PER_SIDE_NUM*2;j++)
+                if (j!=i) {
+                  dx2=objs[j].x-o->x;
+                  dy2=objs[j].y-o->y;
+                  d=Sqr(dx2)+Sqr(dy2);
+                  if (d<o->nearest_man_dd)
+                    o->nearest_man_dd=d;
+                  if (d<MAN_SQR_RADIUS) {
+                    if (d) {
+                      d=Sqrt(d);
+                      dx2/=d;
+                      dy2/=d;
+                    }
+                    if (t0>o->foul_t0+0.15) {
+                      d=(dx-objs[j].DxDt)*dx2+(dy-objs[j].DyDt)*dy2;
+                      if (o==human && t0>o->foul_t0+1.0 &&
+                            dt && d/dt>FOUL_VELOCITY_THRESHOLD &&
+                            objs[j].team) {
+                        Noise(250,62,62);
+                        score1+=1;
+                        foul_t_end=t0+1.0;
+                      }
+                      o->foul_t0=t0;
+                    }
+                  }
+                }
+              if (t0<o->foul_t0+0.15) {
+                dx=-dx;
+                dy=-dy;
+              }
+              o->x+=dx;
+              o->y+=dy;
+              o->stopped=FALSE;
+            } else
+              o->stopped=TRUE;
+          }
+          if (o->DzDt)
+            o->z+=dt*(o->DzDt-0.5*GRAVITY_ACCELERATION*dt);
+        }
+
+        if (o->x+o->radius>=parent_task->pix_width-COURT_BORDER) {
+          o->x=parent_task->pix_width-COURT_BORDER-1-o->radius;
+          o->DxDt=-COLLISION_DAMP*o->DxDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+        if (o->x-o->radius<COURT_BORDER) {
+          o->x=COURT_BORDER+o->radius;
+          o->DxDt=-COLLISION_DAMP*o->DxDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+
+        if (o->y+o->radius*2>=(parent_task->pix_height-COURT_BORDER)*2) {
+          o->y=(parent_task->pix_height-COURT_BORDER)*2-1-o->radius*2;
+          o->DyDt=-COLLISION_DAMP*o->DyDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+        if (o->y-o->radius*2<2*COURT_BORDER) {
+          o->y=COURT_BORDER*2+o->radius*2;
+          o->DyDt=-COLLISION_DAMP*o->DyDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+
+        if (o->z-o->radius*2<0) {
+          o->z=o->radius*2;
+          o->DzDt=-COLLISION_DAMP*o->DzDt;
+          if (o->DzDt>ROLL_VELOCITY_THRESHOLD)
+            Noise(10,74,86);
+          if (o!=ball)
+            o->DzDt=0;
+        } else if (o->z-o->radius*2>0)
+          o->DzDt-=GRAVITY_ACCELERATION*dt;
+        if (o==ball) {
+          d=Exp(-AIR_VISCOSITY*dt);
+          o->DxDt*=d;
+          o->DyDt*=d;
+          o->DzDt*=d;
+        }
+      }
+    }
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  someone_shooting=FALSE;
+  shot_land_t=0;
+  MemSet(&objs,0,sizeof(objs));
+  for (i=0;i<PER_SIDE_NUM*2;i++) {
+    objs[i].team=i&1;
+    objs[i].x=Fs->pix_width/2;
+    objs[i].y=2*Fs->pix_height/2;
+    objs[i].next_img=objs[i].last_img=FIRST_RUNNING;
+  }
+  last_owner=NULL;
+  human=&objs[0];
+  ball =&objs[i];
+  ball->team=-1;
+  ball->x=0.5*Fs->pix_width/2;
+  ball->y=0.5*2*Fs->pix_height/2;
+  ball->radius=11;
+  ball->z=ball->radius;
+  score0=score1=0;
+  game_t_end=tS+3*60;
+  foul_t_end=0;
+}
+
+U0 KeepAway()
+{
+  I64 msg_code,arg1,arg2;
+
+  PopUpOk(
+        "Pass or hand-off to your team to score points.$FG$\n\n"
+        "\t2 points for successful hand-off.\n"
+        "\t6 points for successful pass.\n"
+        "\t1 point penalty for foul.\n\n"
+        "Left-Click\tto pass.\n\n"
+        "Right-Click\tto jump.\n");
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK+YELLOW<<4;
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Shoot(,CH_SPACE);"
+        "  Jump(,'j');"
+        "}"
+        );
+
+  Init;
+  Fs->draw_it=&DrawIt;
+  Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
+
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|1<<MSG_KEY_DOWN);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+ka_shoot:
+          Shoot(human);
+          break;
+        case MSG_MS_R_DOWN:
+ka_jump:
+          human->DzDt=JUMP_VELOCITY;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              Init;
+              break;
+            case 'j':
+              goto ka_jump;
+            case CH_SPACE:
+              goto ka_shoot;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto ka_done;
+          }
+          break;
+      }
+    }
+ka_done: //Don't goto out of try
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/KeepAway","I64 best_score0=%d,best_score1=%d;\n",
+        best_score0,best_score1);
+}
+
+ diff --git a/public/Wb/Apps/KeepAway/Load.HC.HTML b/public/Wb/Apps/KeepAway/Load.HC.HTML new file mode 100755 index 0000000..08328e4 --- /dev/null +++ b/public/Wb/Apps/KeepAway/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "KeepAway"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/KeepAway/Run.HC.HTML b/public/Wb/Apps/KeepAway/Run.HC.HTML new file mode 100755 index 0000000..e1f6751 --- /dev/null +++ b/public/Wb/Apps/KeepAway/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+KeepAway;
+ diff --git a/public/Wb/Apps/Logic/Load.HC.HTML b/public/Wb/Apps/Logic/Load.HC.HTML new file mode 100755 index 0000000..d72082d --- /dev/null +++ b/public/Wb/Apps/Logic/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Misc"
+
+Cd(__DIR__);;
+#include "Logic"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/Logic/Logic.HC.HTML b/public/Wb/Apps/Logic/Logic.HC.HTML new file mode 100755 index 0000000..8c1a190 --- /dev/null +++ b/public/Wb/Apps/Logic/Logic.HC.HTML @@ -0,0 +1,621 @@ + + + + + + + + + + + +
+#define TABLE_SIZE_MAX 0x10000
+
+I64 output_found,passes,table_size;
+
+U8 *gate_type_table =NULL,
+   *displayed_design=NULL,
+   *added_this_pass =NULL;
+
+U16 *input1_table=NULL,
+    *input2_table=NULL,
+    *input3_table=NULL;
+
+#define CONNECT_WIDTH   16
+#define GATE_WIDTH      37
+
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+
+U8 *gate_type_lst="NULL\0OUTPUT\0INPUT\0"
+     "NOT\0AND\0OR\0NAND\0NOR\0XOR\0AND3\0OR3\0NAND3\0NOR3\0";
+
+#define GT_NULL   0  //Specifies that table entry has not been filled-in
+#define GT_OUTPUT 1  //Specifies the table entry is a desired output
+#define GT_INPUT  2  //Specifies that table entry comes from an input signal
+
+#define GT_FIRST_REAL_GATE 3
+#define GT_NOT          3
+#define GT_AND          4
+#define GT_OR           5
+#define GT_NAND         6
+#define GT_NOR          7
+#define GT_XOR          8
+#define GT_AND3         9
+#define GT_OR3          10
+#define GT_NAND3        11
+#define GT_NOR3         12
+#define GT_ENTRIES_NUM  13
+
+#define SEL_GATES_NUM   128
+
+U8 *imgs[GT_ENTRIES_NUM]={NULL,NULL,NULL,
+<NOT>,<AND>,<OR>,<NAND>,<NOR>,<XOR>,<AND3>,<OR3>,<NAND3>,<NOR3>};
+
+I64 num_inputs_entered,num_outputs_entered;
+I64 num_sel_gates,
+    sel_gates[SEL_GATES_NUM];
+
+U0 GetGates()
+{
+  I64 i;
+  U8 *st;
+
+  "\nEnter the available gate types in the order you prefer them to be used.\n"
+        "Your choices are:\n";
+  for (i=GT_FIRST_REAL_GATE;i<GT_ENTRIES_NUM;i++)
+    "%z ",i,gate_type_lst;
+  '\n';
+
+  num_sel_gates=0;
+  while (num_sel_gates<GT_ENTRIES_NUM) {
+    "%d",num_sel_gates;
+    st=GetStr(" Gate: ");
+    if (!*st) {
+      Free(st);
+      return;
+    }
+    i=LstMatch(st,gate_type_lst,LMF_IGNORE_CASE);
+    Free(st);
+    if (i<GT_FIRST_REAL_GATE)
+      "Invalid response\n";
+    else
+      sel_gates[num_sel_gates++]=i;
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+
+  do {
+    table_size=GetI64("\nTable size in hex (3 input=0x100,4=0x10000): ",0);
+    if (table_size>TABLE_SIZE_MAX)
+      "Too large\n";
+    else if (table_size<1) {
+      "No table specified, aborting.\n";
+      throw;
+    }
+  } while (table_size>TABLE_SIZE_MAX);
+
+  gate_type_table =CAlloc(table_size*sizeof(U8));
+  displayed_design=MAlloc((table_size+7)/8);
+  added_this_pass =MAlloc((table_size+7)/8);
+  input1_table    =MAlloc(table_size*sizeof(U16));
+  input2_table    =MAlloc(table_size*sizeof(U16));
+  input3_table    =MAlloc(table_size*sizeof(U16));
+
+  "\nEnter the hex truth table column values of inputs.\n";
+  if (table_size<=0x100)
+    "For example, enter A=0xF0, B=0xCC and C=0xAA.\n";
+  else
+    "For example, enter A=0xFF00, B=0xF0F0, C=0xCCCC and D=0xAAAA.\n";
+  num_inputs_entered=0;
+  while (TRUE) {
+    "Input %C: ",'A'+num_inputs_entered;
+    i=GetI64("",-1);
+    if (i<0) break;
+    if (i>table_size)
+      "Too large\n";
+    else {
+      if (gate_type_table[i])
+        "Duplicate\n";
+      else {
+        gate_type_table[i]=GT_INPUT;
+        input1_table[i]=num_inputs_entered++;
+      }
+    }
+  }
+  if (!num_inputs_entered) {
+    "No inputs specified, aborting.\n";
+    throw;
+  }
+
+  "\nEnter the hex truth table columns values of the outputs.\n";
+  num_outputs_entered=0;
+  while (TRUE) {
+    "Output %C: ",'A'+num_outputs_entered;
+    i=GetI64("",-1);
+    if (i<0) break;
+    if (i>table_size)
+      "Too large\n";
+    else {
+      if (gate_type_table[i]==GT_INPUT)
+        "To produce this output, connect to input %C\n",
+              'A'+input1_table[i];
+      else if (gate_type_table[i]==GT_OUTPUT)
+        "Duplicate\n";
+      else {
+        gate_type_table[i]=GT_OUTPUT;
+        input1_table[i]=num_outputs_entered++;
+      }
+    }
+  }
+
+  if (!num_outputs_entered) {
+    "No output specified, aborting.\n";
+    throw;
+  }
+}
+
+U0 DrawDesign(CDC *dc,I64 *_y,I64 output,I64 depth,I64 *_x_out,I64 *_y_out)
+{
+  I64 y=*_y,type=gate_type_table[output],
+        xx=(passes-depth)*(GATE_WIDTH+CONNECT_WIDTH),yy=y,
+        x1,y1,x2,y2,x3,y3;
+  if (_x_out) *_x_out=xx;
+  if (_y_out) *_y_out=yy;
+  if (Bt(displayed_design,output) && type!=GT_INPUT) {
+    dc->color=GREEN;
+    GrPrint(dc,xx-FONT_WIDTH*3,y-4,"Dup");
+    y+=10;
+  } else
+    switch (type) {
+      case GT_INPUT:
+        dc->color=GREEN;
+        GrPrint(dc,xx-FONT_WIDTH-4,y-4,"%C",'A'+input1_table[output]);
+        y+=10;
+        break;
+      case GT_NOT:
+        if (!Bt(displayed_design,output)) {
+          y+=16;
+          DrawDesign(dc,&y,input1_table[output],depth+1,&x1,&y1);
+          yy=y1;
+
+          dc->color=BLUE;
+          Sprite3(dc,xx,yy,0,imgs[type]);
+
+          dc->color=RED;
+          GrLine(dc,xx-GATE_WIDTH,yy,x1,y1);
+          if (_y_out) *_y_out=yy;
+        }
+        break;
+      case GT_AND:
+      case GT_OR:
+      case GT_NAND:
+      case GT_NOR:
+      case GT_XOR:
+        if (!Bt(displayed_design,output)) {
+          y+=24;
+          DrawDesign(dc,&y,input1_table[output],depth+1,&x1,&y1);
+          DrawDesign(dc,&y,input2_table[output],depth+1,&x2,&y2);
+          yy=(y1+y2)/2;
+
+          dc->color=BLUE;
+          Sprite3(dc,xx,yy,0,imgs[type]);
+
+          dc->color=RED;
+          GrLine(dc,xx-GATE_WIDTH,yy-4,x1,y1);
+          GrLine(dc,xx-GATE_WIDTH,yy+4,x2,y2);
+          if (_y_out) *_y_out=yy;
+        }
+        break;
+      case GT_AND3:
+      case GT_OR3:
+      case GT_NAND3:
+      case GT_NOR3:
+        if (!Bt(displayed_design,output)) {
+          y+=32;
+          DrawDesign(dc,&y,input1_table[output],depth+1,&x1,&y1);
+          DrawDesign(dc,&y,input2_table[output],depth+1,&x2,&y2);
+          DrawDesign(dc,&y,input3_table[output],depth+1,&x3,&y3);
+          yy=(y1+y2+y3)/3;
+
+          dc->color=BLUE;
+          Sprite3(dc,xx,yy,0,imgs[type]);
+
+          dc->color=RED;
+          GrLine(dc,xx-GATE_WIDTH,yy-8,x1,y1);
+          GrLine(dc,xx-GATE_WIDTH,yy  ,x2,y2);
+          GrLine(dc,xx-GATE_WIDTH,yy+8,x3,y3);
+          if (_y_out) *_y_out=yy;
+        }
+        break;
+    }
+  dc->color=BLACK;
+  GrPrint(dc,xx,yy+3,"%04X",output);
+  Bts(displayed_design,output);
+  if (_y) *_y=y;
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 y=0;
+  MemSet(displayed_design,0,(table_size+7)/8*sizeof(Bool));
+  DrawDesign(dc,&y,output_found,0,NULL,NULL);
+}
+
+U0 FillNot(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i)) {
+      progress1=i;
+      j= (~i) & (table_size-1);
+      old_type=gate_type_table[j];
+      if (old_type<GT_INPUT) {
+        gate_type_table[j]=GT_NOT;
+        input1_table[j]=i;
+        Bts(added_this_pass,j);
+        *chged=TRUE;
+        if (old_type==GT_OUTPUT) {
+          if (output_found<0) output_found=j;
+          *num_outputs_found=*num_outputs_found+1;
+        }
+      }
+    }
+}
+
+U0 FillAnd(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (i & k) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_AND;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillOr(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (i | k) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_OR;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillNAnd(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (~ (i & k)) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_NAND;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillNOr(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (~ (i | k)) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_NOR;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillXor(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (i ^ k) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_XOR;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillAnd3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (i & k & l) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_AND3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+U0 FillOr3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (i | k | l) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_OR3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+U0 FillNAnd3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (~(i & k & l)) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_NAND3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+U0 FillNOr3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (~(i | k | l)) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_NOR3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+I64 FillGateTable()
+{
+  I64 current_gate,num_outputs_found=0;
+  Bool chged=TRUE;
+  passes=1;
+  output_found=-1;
+  ProgressBarsRst;
+  progress1_max=table_size;
+  '\n';
+  while (num_outputs_found<num_outputs_entered && chged) {
+    "Pass : %d\n",passes++;
+    chged=FALSE;
+    MemSet(added_this_pass,0,(table_size+7)/8);
+    for (current_gate=0;current_gate<num_sel_gates &&
+          num_outputs_found<num_outputs_entered;current_gate++) {
+      switch (sel_gates[current_gate]) {
+        case GT_NOT:   FillNot  (&chged,&num_outputs_found); break;
+        case GT_AND:   FillAnd  (&chged,&num_outputs_found); break;
+        case GT_OR:    FillOr   (&chged,&num_outputs_found); break;
+        case GT_NAND:  FillNAnd (&chged,&num_outputs_found); break;
+        case GT_NOR:   FillNOr  (&chged,&num_outputs_found); break;
+        case GT_XOR:   FillXor  (&chged,&num_outputs_found); break;
+        case GT_AND3:  FillAnd3 (&chged,&num_outputs_found); break;
+        case GT_OR3:   FillOr3  (&chged,&num_outputs_found); break;
+        case GT_NAND3: FillNAnd3(&chged,&num_outputs_found); break;
+        case GT_NOR3:  FillNOr3 (&chged,&num_outputs_found); break;
+      }
+    }
+  }
+  ProgressBarsRst;
+  return num_outputs_found;
+}
+
+U0 CleanUp()
+{
+  Free(gate_type_table);
+  Free(displayed_design);
+  Free(added_this_pass);
+  Free(input1_table);
+  Free(input2_table);
+  Free(input3_table);
+}
+
+U0 DigitalLogic()
+{
+  gate_type_table =NULL;
+  displayed_design=NULL;
+  added_this_pass =NULL;
+  input1_table    =NULL;
+  input2_table    =NULL;
+  input3_table    =NULL;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder(ON);
+  WinMax;
+  DocClear;
+  GetGates;
+  try {
+    Init;
+    if (FillGateTable) {
+      DocCursor;
+      DocClear;
+      Fs->draw_it=&DrawIt;
+      GetChar;
+      DocClear;
+      Refresh(2,TRUE);
+      DocBottom;
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+}
+
+ diff --git a/public/Wb/Apps/Logic/Run.HC.HTML b/public/Wb/Apps/Logic/Run.HC.HTML new file mode 100755 index 0000000..23a5137 --- /dev/null +++ b/public/Wb/Apps/Logic/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+DigitalLogic;
+ diff --git a/public/Wb/Apps/Psalmody/Examples/childish.HC.HTML b/public/Wb/Apps/Psalmody/Examples/childish.HC.HTML new file mode 100755 index 0000000..9815331 --- /dev/null +++ b/public/Wb/Apps/Psalmody/Examples/childish.HC.HTML @@ -0,0 +1,55 @@ + + + + + + + + + + + +
+//9 has words
+U0 Song()
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 2.480;
+  music.stacatto_factor= 0.902;
+  try {
+    while (!ScanKey) {
+      Play("5qEsCDCDqCDeEGsE4B5E4B5eC4B5sD4A5D4A",
+            "Be \0like \0 \0a \0 \0child \0 \0 \0 \0"
+            "some \0 \0re\0 \0spect.\n\0 \0 \0 \0 \0 \0");
+      Play("5qEsCDCDqCDeEGsE4B5E4B5eC4B5sD4A5D4A",
+            "Ma\0tur\0 \0i\0 \0ty \0 \0 \0 \0don't \0 \0"
+            "ne\0 \0glect.\n\0 \0 \0 \0 \0 \0");
+      Play("4eB5DqF4sGAGAqAAA5etD4AA5sD4B5D4B");
+      Play("4eB5DqF4sGAGAqAAA5etD4AA5sD4B5D4B");
+    }
+  } catch
+    PutExcept;
+  Snd;
+}
+
+Song;
+
+ diff --git a/public/Wb/Apps/Psalmody/Examples/night.HC.HTML b/public/Wb/Apps/Psalmody/Examples/night.HC.HTML new file mode 100755 index 0000000..d8b8087 --- /dev/null +++ b/public/Wb/Apps/Psalmody/Examples/night.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+//9 has graphics
+
+         <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+#define X       330
+#define Y       35
+
+F64 t0=Beat;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  F64 x,y,dt=Beat-t0;
+  Sprite3(dc,X,Y,0,<1>);
+  if (Beat-t0<24) {
+    if (Rand<0.7) {
+      dc->color=YELLOW;
+      GrPlot(dc,X-12,Y+1);
+      GrPlot(dc,X-12,Y+2);
+      GrPlot(dc,X-11,Y+4);
+      GrPlot(dc,X+10,Y+4);
+      GrPlot(dc,X+4,Y+4);
+      GrPlot(dc,X+5,Y+4);
+      GrPlot(dc,X+6,Y+4);
+      GrPlot(dc,X+7,Y+5);
+      GrPlot(dc,X+8,Y+5);
+    }
+    for (i=0;i<512;i++) {
+      x=1.0-Rand`3.0;
+      y=Rand;
+      x=5.0*Sin(pi*Sqrt(y))*x;
+      y=25.0*y;
+      if (Rand*(x*x+2.0)*Sqrt(y)<4.0) {
+        if (Rand<0.5)
+          dc->color=BLUE;
+        else
+          dc->color=LTBLUE;
+      } else
+        dc->color=YELLOW;
+      if (RandI16<0)
+        x=-x;
+      x+=150.0*Sin(pi*dt)/(35-y)`1.5;
+      GrPlot(dc,X+x,Y-y);
+    }
+  }
+}
+
+U0 Song()
+{
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+LTGRAY;
+  Fs->draw_it=&DrawIt;
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo=2.0;
+  try {
+    "$BG+H,BLACK$$FD+H,LTGRAY$";
+    while (TRUE) {
+      t0=Beat;
+      "$WHITE$God said this was a dirge.\n$FG$";
+      Play("5FqDqD4eA5CqEqEqDqDq",
+            "Gone \0to \0sleep \0for \0the \0fi\0nal \0time.\n\0");
+      Play("5FqDqD4eA5CqEqEqDqDq",
+            "Gone \0to \0sleep \0for \0the \0fi\0nal \0time.\n\0");
+      Play("5DqGqFeGFqFqEqE4qBq",
+            " \0Ash \0to... \0and \0 \0dust \0to \0dust.\n\0");
+      Play("5DqGqFeGFqFqEqE4qBq",
+            " \0Ash \0to... \0and \0 \0dust \0to \0dust.\n\0");
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+Song;
+
+ diff --git a/public/Wb/Apps/Psalmody/Examples/prosper.HC.HTML b/public/Wb/Apps/Psalmody/Examples/prosper.HC.HTML new file mode 100755 index 0000000..e26b2c5 --- /dev/null +++ b/public/Wb/Apps/Psalmody/Examples/prosper.HC.HTML @@ -0,0 +1,87 @@ + + + + + + + + + + + +
+//9 has graphics
+
+//When using flood-fill in a graphic
+//element, you probably want to
+//convert it to a bitmap using the
+//feature in the <CTRL-r> menu.
+
+   <1>/* Graphics Not Rendered in HTML */
+
+
+   <2>/* Graphics Not Rendered in HTML */
+
+
+F64 t0=Beat;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 dt=Beat-t0;
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4RotZ(dc->r,0.25*Sin(2*dt));
+  Mat4x4Scale(dc->r,1.5+0.5*Sin(dt/3));
+  DCMat4x4Set(dc,dc->r);
+  if (ToI64(dt)&1)
+    Sprite3B(dc,12.0*dt%task->pix_width,20,0,<1>);
+  else
+    Sprite3B(dc,12.0*dt%task->pix_width,20,0,<2>);
+}
+
+U0 Song()
+{
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=GREEN<<4+YELLOW;
+  Fs->draw_it=&DrawIt;
+  Fs->task_end_cb=&SndTaskEndCB;
+
+  MusicSettingsRst;
+  music.tempo=3.5;
+  try {
+    while (!ScanKey) {
+      t0=Beat;
+      Play("5qG4G5D4B5sDCDCqRCG",
+            "$CL$$BG,9$\n\n$BG,2$$CM-LE,3$$FG,14$Baa, \0"
+            "the \0grass \0is \0green.\n\0 \0 \0 \0 \0 \0 \0");
+      Play("5G4G5D4B5sDCDCqRCG",
+            "This \0must \0be \0a \0dream.\n\0 \0 \0 \0 \0 \0 \0");
+      Play("5EeGF4qBB5D4AeGGqR",
+            "Thanks, \0my \0 \0shep\0herd.  \0You \0are \0good.\n\0 \0 \0");
+      Play("5EeGF4qBB5D4AeGGqR",
+            "Thanks, \0my \0 \0shep\0herd.  \0You \0are \0good.\n\0 \0 \0");
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+Song;
+
+ diff --git a/public/Wb/Apps/Psalmody/Help.DD.HTML b/public/Wb/Apps/Psalmody/Help.DD.HTML index c7fe12b..d7f30c2 100755 --- a/public/Wb/Apps/Psalmody/Help.DD.HTML +++ b/public/Wb/Apps/Psalmody/Help.DD.HTML @@ -37,22 +37,22 @@ * The clip can be used to cut and paste. * Psalmody uses HolyC files as the song format! See -::/Apps/Psalmody/Examples/prosper.HC. The Psalmody program does not fully parse +::/Apps/Psalmody/Examples/prosper.HC. The Psalmody program does not fully parse the songs when loading them back in, so changes made outside Psalmody will be lost, like if you add graphics. * The first line of the HolyC song files is a comment with a category recognized -by JukeBox(). The categories are "no nothing", "has words", "has graphics", or +by JukeBox(). The categories are "no nothing", "has words", "has graphics", or "special". The third character in the song comment is a digit rating number, -shown in JukeBox(). You can set the song rating in JukeBox() by pressing 0-9. +shown in JukeBox(). You can set the song rating in JukeBox() by pressing 0-9. You can request your reward from God by pressing r. You can press <DEL> to delete songs. -* You can take the Play() stmts out of a song file and place them in your +* You can take the Play() stmts out of a song file and place them in your programs. You can also add a song to a document with <CTRL-l>, but you should do it after pressing <CTRL-t> because the clip-insert in <CTRL-l> is screwy. See this <Song> after pressing <CTRL-t>, now. -* You can call JukeBox("~/Psalmody"); to play your songs. +* You can call JukeBox("~/Psalmody"); to play your songs. diff --git a/public/Wb/Apps/Psalmody/Install.HC.HTML b/public/Wb/Apps/Psalmody/Install.HC.HTML new file mode 100755 index 0000000..2dce866 --- /dev/null +++ b/public/Wb/Apps/Psalmody/Install.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+if (!FileFind("~/Psalmody",,FUF_JUST_DIRS))
+  DirMk("~/Psalmody");
+
+ diff --git a/public/Wb/Apps/Psalmody/JukeBox.HC.HTML b/public/Wb/Apps/Psalmody/JukeBox.HC.HTML new file mode 100755 index 0000000..ffa2e52 --- /dev/null +++ b/public/Wb/Apps/Psalmody/JukeBox.HC.HTML @@ -0,0 +1,231 @@ + + + + + + + + + + + +
+CTask *JukeReward(U8 *msg)
+{
+  U8 *buf;
+  CDoc *doc;
+  CTask *res=Spawn(&SrvCmdLine,NULL,"Reward",,Fs);
+  StrCpy(res->task_title,"Reward");
+  res->title_src=TTS_LOCKED_CONST;
+
+  doc=DocNew(,res);
+  DocPrint(doc,"$WW+H,1$$RED$%s",msg);
+
+  buf=MStrPrint("DocEd(0x%X);",doc);
+  TaskExe(res,NULL,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  Free(buf);
+  TaskWait(res);
+
+  res->border_src =BDS_CONST;
+  res->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  res->text_attr  =LTGRAY<<4+BLUE;
+  res->win_inhibit=WIG_NO_FOCUS_TASK_DFT;
+  WinHorz(Fs->win_right+2,TEXT_COLS-2,res);
+  WinVert(2,TEXT_ROWS-2,res);
+
+  WinFocus(Fs->parent_task);
+  return res;
+}
+
+CTask *SingleSong(U8 *msg,U8 *name)
+{
+  CTask *task=Spawn(&SrvCmdLine,NULL,name,,Fs);
+  StrCpy(task->task_title,name);
+  task->title_src=TTS_LOCKED_CONST;
+  TaskExe(task,Fs,";",1<<JOBf_WAKE_MASTER|1<<JOBf_FREE_ON_COMPLETE);
+  WinHorz(task->win_left,task->win_left+50,task);
+  WinVert(2,2+8,task);
+  task->win_inhibit=WIG_NO_FOCUS_TASK_DFT;
+  TaskExe(task,NULL,msg,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  DocPut(task)->max_entries=100;
+  return task;
+}
+
+#define JB_RUN_LEVEL_NULL       0
+#define JB_RUN_LEVEL_ONE        1
+#define JB_RUN_LEVEL_TWO        2
+
+Bool JBPutKey(CDoc *doc,U8 *,I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e;
+  CDirEntry *tmpde;
+  I64 i;
+  U8 *st;
+  CDoc *doc2;
+  if (!(sc&(SCF_ALT|SCF_CTRL|SCF_SHIFT))
+        && doc_ce->type_u8==DOCT_MENU_VAL && doc_ce->left_exp>=0) {
+    tmpde=doc_ce->left_exp;
+    if (sc.u8[0]==SC_DELETE ) {
+      Beep;
+      Silent;
+      Del(tmpde->full_name);
+      Silent(OFF);
+    } else if ('0'<=ch<='9') {
+      if (StrLen(doc_ce->tag)>1)
+        doc_ce->tag[0]=ch;
+      doc2=DocRead(tmpde->full_name);
+      DocGoToLine(doc2,1);
+      doc_e=doc2->cur_entry;
+      if (doc_e!=doc2 && doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=3) {
+        doc_e->tag[2]=ch;
+        DocWrite(doc2);
+      }
+      DocDel(doc2);
+      return TRUE;
+    } else if (ch=='r') {
+      if (!DocTreeFFind(tmpde->full_name,"Reward1")) {
+        doc2=DocRead(tmpde->full_name);
+        DocGoToLine(doc2,2);
+        DocPrint(doc2,
+              "\n$TR,\"Reward1\"$\n"
+              "$ID,2$CallExtStr(\"JukeReward\",\"\"\n"
+              "$TR,\"Reward2\"$\n"
+              "$ID,2$\n"
+              "$ID,-2$\n"
+              ");\n$ID,-2$\n"
+              );
+        DocWrite(doc2);
+        DocDel(doc2);
+      }
+      if (DocTreeFFind(tmpde->full_name,"Reward1/Reward2")) {
+        for (i=0;i<5;i++) {
+          st=MStrPrint("%s %s %s %s ",
+                GodWordStr,GodWordStr,GodWordStr,GodWordStr);
+          DocTreeFAppend(tmpde->full_name,"Reward1/Reward2",
+                "\"%s\"\n",st);
+          Free(st);
+        }
+        In(" ");
+      }
+      return TRUE;
+    } else if (ch==CH_SPACE||ch==CH_ESC)
+      tmpde->user_data++; //JB_RUN_LEVEL++
+//<SPACE> is followed by <ESC> --> JB_RUN_LEVEL_TWO
+      //Actual <ESC> just exits      --> JB_RUN_LEVEL_ONE
+  }
+  return FALSE;
+}
+
+public U0 JukeBox(U8 *dirname="~/Psalmody",U8 **_filename=NULL)
+{//_filename is for using this as a song-chooser program.
+  I64 i=0,rating;
+  U8 *st,*st2;
+  CDirEntry *tmpde,*tmpde1;
+  CDoc *doc=DocNew,*s;
+  CDocEntry *doc_e;
+  CTask *task=NULL;
+  if (_filename)
+    *_filename=NULL;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  try {
+    dirname=StrNew(dirname);
+    st=MStrPrint("%s/*.HC.Z",dirname);
+    tmpde=tmpde1=FilesFind(st);
+    Free(st);
+    Free(dirname);
+    doc->user_put_key=&JBPutKey;
+    DocPrint(doc,
+          "Key: $GREEN$Graphics $BLUE$Words $RED$No Nothing "
+          "$BLACK$Incomplete $CYAN$Special$FG$\n\n"
+          "$GREEN$<DEL>$FG$\tto delete a song.\n"
+          "'$GREEN$0$FG$'-'$GREEN$9$FG$'\tto rate a song.\n"
+          "'$GREEN$r$FG$'\tto get your reward from God.\n");
+    while (tmpde) {
+      if (!(i++%5))
+        DocPrint(doc,"\n");
+      if (FileOcc("Play(",tmpde->full_name,"")) {
+        st=StrNew(tmpde->name);
+        FileExtRem(st);
+        s=DocRead(tmpde->full_name);
+        doc_e=s->head.next;
+        while (doc_e!=s && doc_e->type_u8!=DOCT_TEXT)
+          doc_e=doc_e->next;
+        rating='0';
+        if (doc_e!=s && doc_e->type_u8==DOCT_TEXT) {
+          if ('0'<=doc_e->tag[2]<='9')
+            rating=doc_e->tag[2];
+          if (StrMatch("incomplete",doc_e->tag))
+            DocPrint(doc,"$BLACK$");
+          else if (StrMatch("has graphics",doc_e->tag))
+            DocPrint(doc,"$GREEN$");
+          else if (StrMatch("has words",doc_e->tag))
+            DocPrint(doc,"$BLUE$");
+          else if (StrMatch("special",doc_e->tag))
+            DocPrint(doc,"$CYAN$");
+          else if (StrMatch("no nothing",doc_e->tag)) {
+            DocPrint(doc,"$RED$");
+            if (FileOcc("\\0",tmpde->full_name,"")) {
+              s->cur_entry=doc_e->next;
+              s->cur_col=0;
+              DocEntryDel(s,doc_e);
+              DocPrint(s,"//0 has words\n");
+              DocWrite(s);
+            }
+          }
+          DocPrint(doc,"$MU-UL,\"%c%-8ts\",LE=%d$ ",rating,st,tmpde);
+          tmpde->user_data=JB_RUN_LEVEL_NULL;
+        }
+        DocDel(s);
+        Free(st);
+      }
+      tmpde=tmpde->next;
+    }
+    DocPrint(doc,"\n$CYAN$$MU-UL,\"DONE\",LE=%d$\n",DOCM_CANCEL);
+    while (TRUE) {
+      if (_filename)
+        tmpde=PopUpMenu(doc,DOF_INTERCEPT_TASK_END);
+      else
+        tmpde=PopUpMenu(doc);
+      if (task)
+        Kill(task);
+      if (tmpde<=0) break;
+      st2=StrNew(tmpde->name);
+      if (_filename) {
+        Free(*_filename);
+        *_filename=StrNew(tmpde->full_name);
+      }
+      if (tmpde->user_data==JB_RUN_LEVEL_ONE) break; //<ESC>
+      tmpde->user_data=JB_RUN_LEVEL_NULL; //Rst from <SPACE>
+      FileExtRem(st2);
+      st=MStrPrint("ExeFile(\"%s\");",tmpde->full_name);
+      MusicSettingsRst;
+      task=SingleSong(st,st2);
+      Free(st2);
+      Free(st);
+    }
+    DocDel(doc);
+    DirTreeDel(tmpde1);
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+ diff --git a/public/Wb/Apps/Psalmody/JukePuppet.HC.HTML b/public/Wb/Apps/Psalmody/JukePuppet.HC.HTML new file mode 100755 index 0000000..3199670 --- /dev/null +++ b/public/Wb/Apps/Psalmody/JukePuppet.HC.HTML @@ -0,0 +1,126 @@ + + + + + + + + + + + +
+U0 SongPuppet(CTask *task,I64 passes)
+{
+  CDbgInfo *dbg_info;
+  I64 i,start,end,rip,last_rip;
+  CHashFun *tmpf=NULL;
+  for (i=0;i<250 && TaskValidate(task);i++) {
+    if (tmpf=HashFind("Song",task->hash_table,HTT_FUN))
+      break;
+    Sleep(1);
+  }
+  if (tmpf && (dbg_info=tmpf->dbg_info)) {
+    start=dbg_info->body[0];
+    end  =dbg_info->body[dbg_info->max_line+1-dbg_info->min_line];
+    last_rip=0;
+    while (TRUE) {
+      i=0;
+      while (TaskValidate(task) && (rip=TaskCaller(task,i++))) {
+        if (start<=rip<end) {
+          if (rip<last_rip && --passes<=0)
+            return;
+          last_rip=rip;
+        }
+      }
+      Sleep(1);
+    }
+  }
+}
+
+U0 JukeSongPuppet(CTask *juke_task,I64 passes,I64 song_num,U8 *name)
+{
+  Bool found;
+  CTask *task;
+  I64 i;
+
+  if (FileExtDot(name))
+    FileExtRem(name);
+  BirthWait(&juke_task->popup_task);
+  TaskWait(juke_task->popup_task);
+  PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP+SCF_CTRL);
+  TaskWait(juke_task->popup_task);
+  for (i=0;i<song_num;i++) {
+    PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    TaskWait(juke_task->popup_task);
+  }
+
+  PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  TaskWait(juke_task->popup_task);
+  Sleep(500);
+
+  found=FALSE;
+  task=Fs->next_task;
+  while (task!=Fs) {
+    if (!StrCmp(task->task_title,name)) {
+      found=TRUE;
+      break;
+    }
+    task=task->next_task;
+  }
+
+  if (found) {//Position cursor on song title during song
+    TaskWait(juke_task->popup_task);
+    PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP+SCF_CTRL);
+    TaskWait(juke_task->popup_task);
+    for (i=0;i<song_num;i++) {
+      PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+      TaskWait(juke_task->popup_task);
+    }
+    SongPuppet(task,passes);
+  }
+  Kill(task);
+}
+
+public U0 JukeSongsPuppet(U8 *dirname="~/Psalmody",I64 passes=2,
+        I64 start_song=0,I64 end_song=I64_MAX)
+{//Help make music video by puppeting JukeBox task.
+  I64 i;
+  CDirEntry *tmpde,*tmpde1;
+  CTask *juke_task=User("JukeBox(0x%X);\n",dirname);
+  F64 t0;
+  Cd(dirname);
+  tmpde1=FilesFind("*",FUF_RECURSE|FUF_JUST_TXT|FUF_JUST_FILES);
+  for (tmpde=tmpde1,i=0;tmpde && i<start_song;i++)
+    tmpde=tmpde->next;
+  if (scrncast.record)
+    t0=scrncast.t0_tS;
+  else
+    t0=tS;
+  for (i=start_song;tmpde && i<end_song;i++) {
+    "%12.6fs %s\n",tS-t0,tmpde->full_name;
+    JukeSongPuppet(juke_task,passes,i,tmpde->name);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  Kill(juke_task);
+}
+
+ diff --git a/public/Wb/Apps/Psalmody/Load.HC.HTML b/public/Wb/Apps/Psalmody/Load.HC.HTML new file mode 100755 index 0000000..acad725 --- /dev/null +++ b/public/Wb/Apps/Psalmody/Load.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+#help_index "Snd/Music/Apps"
+
+Cd(__DIR__);;
+#include "JukeBox"
+#include "JukePuppet"
+#include "Psalmody"
+#include "PsalmodyCtrls"
+#include "PsalmodyDraw"
+#include "PsalmodyFile"
+#include "PsalmodyMain"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/Psalmody/Psalmody.HC.HTML b/public/Wb/Apps/Psalmody/Psalmody.HC.HTML new file mode 100755 index 0000000..cc0e05d --- /dev/null +++ b/public/Wb/Apps/Psalmody/Psalmody.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+/*
+This uses four types of ctrls
+
+  1) The pull-down menu.
+
+  2) The CCtrl type for the tempo/stacatto sliders.
+
+  3) The active CDoc sprite bttns with macros for left/record/play/right.
+
+  4) Hand-made ctrls for the kbdgraphic, notes and staff.
+
+This uses four types of output
+
+  1) The CDoc for the text and bttns and kbdgraphic.
+
+  2) The Fs->draw_it() for the staff region, drawn every refresh.
+
+  3) The gr.dc persistent layer for the note chooser, meter chooser.  The 
+persistent layer is used during drag-and-drop.
+
+  4) The Fs->next_ctrl for the tempo/stacatto sliders.
+
+See GrUpdateTaskWin(), GrUpdateTasks() and GrUpdateScrn().
+*/
+
+#define PSMT_HEAD       0
+#define PSMT_NOTE       1
+#define PSMT_METER      2
+
+#define PSMf_SEL        0
+#define PSMF_SEL        1
+#define PSMf_SHARP      1
+#define PSMf_FLAT       2
+#define PSMf_TIE        3
+
+class PsmNote
+{
+  PsmNote *next,*last;
+  I64 x,y;
+  U8 *word;
+  I64 type,flags;
+  I64 ona,meter_top,meter_bottom;
+  I64 duration,width;
+  U8 ascii[32];
+};
+
+//Tool types
+#define PSMTT_PTR_TOOL  0
+#define PSMTT_BOX_TOOL  1
+
+class PsmCtrl
+{
+  PsmNote head;
+  PsmNote clip;
+  CMenuEntry *incomplete_entry,*record_entry;
+  I64 scrn_x,tool;
+  PsmNote *cur_note;
+  CDC *dc2;
+  Bool playing;
+} psm;
+
+U8 *psm_note_lst="A\0A#\0B\0C\0C#\0D\0D#\0E\0F\0F#\0G\0G#\0";
+U8 psm_note_map[12]={6,6,5,4,4,3,3,2,1,1,0,0};
+U8 psm_note_inverse_map[7]={10,8,7,5,3,2,0};
+
+ diff --git a/public/Wb/Apps/Psalmody/PsalmodyCtrls.HC.HTML b/public/Wb/Apps/Psalmody/PsalmodyCtrls.HC.HTML new file mode 100755 index 0000000..e81049e --- /dev/null +++ b/public/Wb/Apps/Psalmody/PsalmodyCtrls.HC.HTML @@ -0,0 +1,120 @@ + + + + + + + + + + + +
+#define TEMPO_SPACING 15
+#define TEMPO_RANGE   80
+#define TEMPO_BORDER  2
+
+class TempoState
+{
+  I64 tempo,stacatto;
+} tempo_state;
+
+U0 DrawTempoCtrl(CDC *dc,CCtrl *c)
+{
+  TempoState *s=c->state;
+
+  dc->color=LTGREEN;
+  GrRect(dc, c->left,c->top,TEMPO_SPACING*3+2,TEMPO_SPACING*2+TEMPO_RANGE);
+  dc->color=BLACK;
+  GrRect(dc, c->left+TEMPO_BORDER,c->top+TEMPO_BORDER,
+        TEMPO_SPACING*3+2-2*TEMPO_BORDER,
+        TEMPO_SPACING*2+TEMPO_RANGE-2*TEMPO_BORDER);
+  dc->color=WHITE;
+  GrLine(dc,c->left+TEMPO_SPACING,c->top+TEMPO_SPACING,
+        c->left+TEMPO_SPACING,c->top+TEMPO_SPACING+TEMPO_RANGE-1);
+  GrLine(dc,c->left+2*TEMPO_SPACING+1,c->top+TEMPO_SPACING,
+        c->left+2*TEMPO_SPACING+1,c->top+TEMPO_SPACING+TEMPO_RANGE-1);
+
+  dc->color=LTGREEN;
+  GrPrint(dc,c->left+TEMPO_SPACING-FONT_WIDTH/2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE+3,"%d",s->tempo*10/TEMPO_RANGE);
+  GrPrint(dc,c->left+2*TEMPO_SPACING+1-FONT_WIDTH/2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE+3,"%d",
+        s->stacatto*10/TEMPO_RANGE);
+  GrRect(dc,c->left+TEMPO_SPACING-3,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->tempo-2 ,7,5);
+  GrRect(dc,c->left+2*TEMPO_SPACING+1-3,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->stacatto-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+TEMPO_SPACING-2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->tempo-1 ,5,3);
+  GrRect(dc,c->left+2*TEMPO_SPACING+1-2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->stacatto-1,5,3);
+
+  dc->color=GREEN;
+  GrVPrint(dc,c->left+TEMPO_BORDER+2,c->top+TEMPO_SPACING+2,"Tempo");
+  GrVPrint(dc,c->right-TEMPO_BORDER-2-FONT_WIDTH,
+        c->top+TEMPO_SPACING+2,"Stacatto");
+}
+
+U0 UpdateDerivedTempoCtrl(CCtrl *c)
+{
+  TempoState *s=c->state;
+  c->right=c->left+TEMPO_SPACING*3+2;
+  c->bottom=c->top+TEMPO_SPACING*2+TEMPO_RANGE;
+  s->tempo =ClampI64(s->tempo,0,TEMPO_RANGE-1);
+  s->stacatto=ClampI64(s->stacatto,0,TEMPO_RANGE-1);
+}
+
+U0 LeftClickTempo(CCtrl *c,I64 x,I64 y,Bool)
+{
+  TempoState *s=c->state;
+  if (x<(c->right+c->left)/2)
+    s->tempo=TEMPO_RANGE-1-(y-(c->top+TEMPO_SPACING));
+  else
+    s->stacatto=TEMPO_RANGE-1-(y-(c->top+TEMPO_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *TempoNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&tempo_state;
+  c->draw_it=&DrawTempoCtrl;
+  c->left_click=&LeftClickTempo;
+  c->update_derived_vals=&UpdateDerivedTempoCtrl;
+  c->left=396;
+  c->top=96;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 TempoDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Apps/Psalmody/PsalmodyDraw.HC.HTML b/public/Wb/Apps/Psalmody/PsalmodyDraw.HC.HTML new file mode 100755 index 0000000..580ff22 --- /dev/null +++ b/public/Wb/Apps/Psalmody/PsalmodyDraw.HC.HTML @@ -0,0 +1,440 @@ + + + + + + + + + + + +
+
+        
+        <1>/* Graphics Not Rendered in HTML */
+        
+        <2>/* Graphics Not Rendered in HTML */
+        
+        <3>/* Graphics Not Rendered in HTML */
+        
+        <4>/* Graphics Not Rendered in HTML */
+        
+        <5>/* Graphics Not Rendered in HTML */
+        
+        <6>/* Graphics Not Rendered in HTML */
+        
+        
+        <7>/* Graphics Not Rendered in HTML */
+        
+                
+        <8>/* Graphics Not Rendered in HTML */
+        
+        
+        <9>/* Graphics Not Rendered in HTML */
+        
+        
+        <10>/* Graphics Not Rendered in HTML */
+        
+        
+        <11>/* Graphics Not Rendered in HTML */
+        
+        
+        
+        
+        
+        
+        
+        <12>/* Graphics Not Rendered in HTML */
+        
+        
+                
+        
+        <13>/* Graphics Not Rendered in HTML */
+        
+        <14>/* Graphics Not Rendered in HTML */
+        
+        <15>/* Graphics Not Rendered in HTML */
+        
+        
+        <16>/* Graphics Not Rendered in HTML */
+
+#define PSM_NOTE_SPACING        9
+#define PSM_DURATIONS_NUM       12
+
+F64 psm_durations[PSM_DURATIONS_NUM+1]={
+2*.25/3,.25,2*.5/3,.5,2.0/3.0,0.5*1.5,1.0,1.5,2.0,3.0,4.0,6.0,1000000.0};
+U8 *psm_duration_lst="st\0s\0et\0e\0qt\0e.\0q\0q.\0h\0h.\0w\0w.\0";
+U8 *psm_duration_imgs[PSM_DURATIONS_NUM]={
+        <1>,<1>,<2>,<2>,<3>,<2>,<3>,<3>,<4>,<4>,<5>,<5>};
+Bool psm_triplet_durations[PSM_DURATIONS_NUM]={TRUE,FALSE,TRUE,
+        FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
+
+Bool PsmBlink()
+{
+  if (Blink || psm.playing)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool PsmHasWords(U8 *st)
+{
+  if (st && *st && (StrLen(st)>1 || *st!=CH_SPACE && *st!=CH_SHIFT_SPACE))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool PsmIsDotted(I64 duration)
+{
+  U8 *st=LstSub(duration,psm_duration_lst);
+  if (st[1]=='.')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 PsmMarkSel(I64 x1,I64 x2,Bool sel)
+{
+  PsmNote *tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    if (sel) {
+      if (x1<=tmpn->x<=x2)
+        tmpn->flags|=PSMF_SEL;
+    } else
+      tmpn->flags&=~PSMF_SEL;
+    tmpn=tmpn->next;
+  }
+}
+
+U0 PsmSetWidth(PsmNote *tmpn)
+{
+  if (tmpn->type==PSMT_METER)
+    tmpn->width=12;
+  else {
+    tmpn->width=PSM_NOTE_SPACING;
+    if (PsmIsDotted(tmpn->duration))
+      tmpn->width+=PSM_NOTE_SPACING/2;
+    if (Bt(&tmpn->flags,PSMf_SHARP) || Bt(&tmpn->flags,PSMf_FLAT))
+      tmpn->width+=PSM_NOTE_SPACING;
+  }
+}
+
+U0 PsmSetOctave(I64 octave)
+{
+  I64 i;
+  U8 buf[STR_LEN];
+  CMenuEntry *tmpse;
+  for (i=1;i<=7;i++) {
+    StrPrint(buf,"Snd/Octave%d",i);
+    if (tmpse=MenuEntryFind(Fs->cur_menu,buf)) {
+      if (i==octave)
+        tmpse->checked=TRUE;
+      else
+        tmpse->checked=FALSE;
+    }
+  }
+}
+
+U0 DrawNote(CDC *dc,I64 x,I64 y,I64 duration)
+{
+  if (0<=duration<=PSM_DURATIONS_NUM) {
+    Sprite3(dc,x,y,0,psm_duration_imgs[duration]);
+    if (psm_triplet_durations[duration])
+      Sprite3(dc,x,y,0,<16>);
+    if (PsmIsDotted(duration))
+      Sprite3(dc,x,y,0,<15>);
+  }
+}
+
+U0 DrawTimeSignature(CDC *dc,I64 x,I64 y,I64 top,I64 bottom)
+{
+  GrPrint(dc,x,y,"%d",top);
+  GrPrint(dc,x,y+FONT_HEIGHT,"%d",bottom);
+}
+
+U0 PsmRecalcNoteXY()
+{
+  F64 measure_len=4,measure_left=measure_len;
+  PsmNote *tmpn=psm.head.next;
+  I64 x=8-psm.scrn_x,ona,note,octave;
+  while (TRUE) {
+    tmpn->x=x;
+    tmpn->y=50;
+    if (tmpn==&psm.head)
+      break;
+    else {
+      if (tmpn->type!=PSMT_METER) {
+        if (tmpn->ona) {
+          ona=tmpn->ona;
+          if (Bt(&tmpn->flags,PSMf_SHARP))
+            ona--;
+          if (Bt(&tmpn->flags,PSMf_FLAT))
+            ona++;
+          octave=Ona2Octave(ona);
+          note  =Ona2Note  (ona);
+          note=music.note_map[*LstSub(note,psm_note_lst)-'A'];
+          if (note<3)
+            octave++;
+          tmpn->y=(15+(psm_note_map[note]-7*(octave-4)))*4;
+        }
+      }
+      x+=tmpn->width;
+      if (tmpn->type==PSMT_METER) {
+        measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
+        measure_left=0;
+      } else
+        measure_left-=psm_durations[tmpn->duration];
+      if (measure_left<0.001) {
+        x+=PSM_NOTE_SPACING;
+        measure_left=measure_len;
+      }
+    }
+    tmpn=tmpn->next;
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  PsmNote *tmpn;
+  I64 i,x,y,
+        w=task->pix_width;
+  F64 measure_len=4,measure_left=measure_len;
+
+  dc->color=BLACK;
+  for (i=1;i<6;i++)
+    GrLine(dc,0,i*8,w,i*8);
+  for (i=7;i<12;i++)
+    GrLine(dc,0,i*8,w,i*8);
+
+  PsmRecalcNoteXY;
+  if (psm.cur_note->x<64) {
+    psm.scrn_x-=128;
+    PsmRecalcNoteXY;
+  }
+  if (psm.cur_note->x>=GR_WIDTH-64) {
+    psm.scrn_x+=128;
+    PsmRecalcNoteXY;
+  }
+
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    x=tmpn->x;
+    y=tmpn->y;
+    if (measure_left<0.001) {
+      dc->color=BLACK;
+      GrLine(dc,x-PSM_NOTE_SPACING,8,x-PSM_NOTE_SPACING,11*8);
+      measure_left=measure_len;
+    }
+    if (tmpn->type==PSMT_METER) {
+      if (tmpn==psm.cur_note && PsmBlink)
+        dc->color=BROWN;
+      else
+        dc->color=BLACK;
+      DrawTimeSignature(dc,x,5*8,tmpn->meter_top,tmpn->meter_bottom);
+      measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
+      measure_left=0;
+    } else {
+      if (tmpn==psm.cur_note && PsmBlink) {
+        dc->color=BROWN;
+        GrPrint(dc,x+8,y,"%s",tmpn->word);
+      } else if (tmpn->flags&PSMF_SEL)
+        dc->color=RED;
+      else {
+        if (tmpn->ona)
+          dc->color=BLACK;
+        else
+          dc->color=LTGRAY;
+        if (PsmHasWords(tmpn->word))
+          dc->color=GREEN;
+      }
+      DrawNote(dc,x,y,tmpn->duration);
+      if (PsmIsDotted(tmpn->duration))
+        x+=PSM_NOTE_SPACING/2;
+      if (Bt(&tmpn->flags,PSMf_SHARP))
+        Sprite3(dc,x,y,0,<13>);
+      else if (Bt(&tmpn->flags,PSMf_FLAT))
+        Sprite3(dc,x,y,0,<14>);
+      measure_left-=psm_durations[tmpn->duration];
+    }
+    tmpn=tmpn->next;
+  }
+
+  if (psm.cur_note==&psm.head && PsmBlink)
+    dc->color=BROWN;
+  else
+    dc->color=BLACK;
+  Sprite3(dc,psm.head.x,50,0,<12>);
+}
+
+#define PSM_NOTE_BOX_X  220
+#define PSM_NOTE_BOX_Y  (13*FONT_HEIGHT+14)
+U0 PsmSetPickNoteBoxX(I64 duration,I64 *x)
+{
+  I64 i;
+  *x=PSM_NOTE_BOX_X;
+  for (i=0;i<duration;i++) {
+    if (PsmIsDotted(i))
+      *x+=PSM_NOTE_SPACING/2;
+    *x+=PSM_NOTE_SPACING+4;
+  }
+}
+
+I64 PsmGetPickNoteBoxDuration(I64 xx,I64 yy)
+{
+  I64 i,x1,x2;
+  if (PSM_NOTE_BOX_Y-14<=yy<PSM_NOTE_BOX_Y+6) {
+    for (i=0;i<PSM_DURATIONS_NUM;i++) {
+      PsmSetPickNoteBoxX(i,&x1);
+      PsmSetPickNoteBoxX(i+1,&x2);
+      if (x1<=xx+PSM_NOTE_SPACING/2<x2)
+        return i;
+    }
+  }
+  return -1;
+}
+
+U0 DrawPickNoteBox()
+{
+  I64 i,x;
+  for (i=0;i<PSM_DURATIONS_NUM;i++) {
+    PsmSetPickNoteBoxX(i,&x);
+    if (PsmIsDotted(i))
+      psm.dc2->color=RED;
+    else if (psm_triplet_durations[i])
+      psm.dc2->color=LTRED;
+    else
+      psm.dc2->color=BLACK;
+    DrawNote(psm.dc2,x,PSM_NOTE_BOX_Y,i);
+  }
+}
+
+#define PSM_TOOLS_X     450
+#define PSM_TOOLS_Y     13*FONT_HEIGHT
+
+U0 DrawPickTools()
+{
+  if (psm.tool==PSMTT_BOX_TOOL)
+    psm.dc2->color=ROPF_DITHER+WHITE<<16+RED;
+  else
+    psm.dc2->color=ROPF_DITHER+WHITE<<16+BLACK;
+  GrBorder(psm.dc2,PSM_TOOLS_X,PSM_TOOLS_Y,PSM_TOOLS_X+10,PSM_TOOLS_Y+10);
+
+  if (psm.tool==PSMTT_PTR_TOOL)
+    psm.dc2->color=RED;
+  else
+    psm.dc2->color=BLACK;
+  (*gr.fp_draw_ms)(psm.dc2,PSM_TOOLS_X+15,PSM_TOOLS_Y);
+  psm.dc2->color=BLACK;
+}
+
+Bool PsmGetPickToolBox(I64 xx,I64 yy)
+{
+  if (PSM_TOOLS_X<=xx<PSM_TOOLS_X+27 && PSM_TOOLS_Y<=yy<PSM_TOOLS_Y+15) {
+    PsmMarkSel(0,0,FALSE);
+    if (xx<PSM_TOOLS_X+13)
+      psm.tool=PSMTT_BOX_TOOL;
+    else
+      psm.tool=PSMTT_PTR_TOOL;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+#define PSM_METERS_NUM  7
+I64 meter_tops[PSM_METERS_NUM]  ={2,3,4,5,6,7,9},
+   meter_bottoms[PSM_METERS_NUM]={4,4,4,4,8,8,8};
+
+#define PSM_METER_X     485
+#define PSM_METER_Y     13*FONT_HEIGHT
+#define PSM_METER_W     12
+Bool PsmGetPickMeterBox(I64 xx,I64 yy,I64 *top,I64 *bottom)
+{
+  I64 i;
+  if (PSM_METER_X<=xx<PSM_METER_X+PSM_METER_W*PSM_METERS_NUM &&
+        PSM_METER_Y<=yy<PSM_METER_Y+2*FONT_HEIGHT) {
+    i=(xx-PSM_METER_X)/PSM_METER_W;
+    *top=meter_tops[i];
+    *bottom=meter_bottoms[i];
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 DrawPickMeterBox()
+{
+  I64 i;
+  psm.dc2->color=BLACK;
+  for (i=0;i<PSM_METERS_NUM;i++)
+    DrawTimeSignature(psm.dc2,PSM_METER_X+i*PSM_METER_W,PSM_METER_Y,
+          meter_tops[i],meter_bottoms[i]);
+}
+
+U0 DrawDC2()
+{
+  DCFill;
+  DrawPickNoteBox;
+  DrawPickMeterBox;
+  DrawPickTools;
+}
+
+
+<17>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+U0 PsmMenu(I64 psm_octave)
+{
+  DocClear;
+  "$BG,WHITE$$FD,GREEN$$CM,0,12$\n";
+  Sprite(<17>);
+  '\n\n\n\n\n';
+
+  DrawDC2;
+
+  "$LTGREEN$<SPACE>$FG$\t\tRest\n"
+        "$LTGREEN$<BACKSPACE>$FG$\tDeletes Last Note\n"
+        "$LTGREEN$Left Mouse$FG$\tDrag note or shift word\n"
+        "$LTGREEN$Right Mouse$FG$\tChange duration or set word\n";
+  Sprite(<6>,"$SP+LIS,\"\","
+        "LM=\"Msg(MSG_KEY_DOWN,0,SCF_CTRL|SC_CURSOR_LEFT);\",BI=%d$");
+  "   ";
+  if (psm.playing)
+    Sprite(<9>,"$SP,\"\",LM=\"x\",BI=%d$");
+  else
+    Sprite(<8>,"$SP,\"\",LM=\"x\",BI=%d$");
+  "   ";
+  if (psm.record_entry->checked) {
+    psm.record_entry->checked=TRUE;
+    Sprite(<10>,"$SP,\"\",LM=\"z\",BI=%d$");
+  } else
+    Sprite(<11>,"$SP,\"\",LM=\"z\",BI=%d$");
+  "   ";
+  Sprite(<7>,"$SP+LIS,\"\","
+        "LM=\"Msg(MSG_KEY_DOWN,0,SCF_CTRL|SC_CURSOR_RIGHT);\",BI=%d$");
+  "$CM+LX,0,6$";
+  PsmSetOctave(psm_octave);
+  Refresh(2);
+}
+
+ diff --git a/public/Wb/Apps/Psalmody/PsalmodyFile.HC.HTML b/public/Wb/Apps/Psalmody/PsalmodyFile.HC.HTML new file mode 100755 index 0000000..36f5d5e --- /dev/null +++ b/public/Wb/Apps/Psalmody/PsalmodyFile.HC.HTML @@ -0,0 +1,458 @@ + + + + + + + + + + + +
+U0 PsmNoteDel(PsmNote *tmpn)
+{
+  Free(tmpn->word);
+  Free(tmpn);
+}
+
+PsmNote *PsmNoteCopy(PsmNote *tmpn)
+{
+  PsmNote *tmpn1=MAllocIdent(tmpn);
+  if (tmpn->word)
+    tmpn1->word=StrNew(tmpn->word);
+  else
+    tmpn1->word=NULL;
+  return tmpn1;
+}
+
+U0 PsmSongDel(PsmNote *head)
+{
+  PsmNote *tmpn,*tmpn1;
+  tmpn=head->next;
+  while (tmpn!=head) {
+    tmpn1=tmpn->next;
+    PsmNoteDel(tmpn);
+    tmpn=tmpn1;
+  }
+  QueInit(head);
+}
+
+U0 PsmCutToClip()
+{
+  PsmNote *tmpn,*tmpn1;
+  PsmSongDel(&psm.clip);
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    tmpn1=tmpn->next;
+    if (tmpn->flags&PSMF_SEL) {
+      if (psm.cur_note==tmpn)
+        psm.cur_note=tmpn->next;
+      QueRem(tmpn);
+      tmpn->flags&=~PSMF_SEL;
+      QueIns(tmpn,psm.clip.last);
+    }
+    tmpn=tmpn1;
+  }
+}
+
+U0 PsmPasteClip()
+{
+  PsmNote *tmpn,*tmpn1;
+  tmpn=psm.clip.next;
+  while (tmpn!=&psm.clip) {
+    tmpn1=PsmNoteCopy(tmpn);
+    QueIns(tmpn1,psm.cur_note->last);
+    tmpn=tmpn->next;
+  }
+}
+
+U0 PsmCopyToClip()
+{
+  PsmNote *tmpn,*tmpn1;
+  PsmSongDel(&psm.clip);
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    if (tmpn->flags&PSMF_SEL) {
+      tmpn->flags&=~PSMF_SEL;
+      tmpn1=PsmNoteCopy(tmpn);
+      QueIns(tmpn1,psm.clip.last);
+    }
+    tmpn=tmpn->next;
+  }
+}
+
+PsmNote *PsmFindNote(I64 x,I64)
+{
+  PsmNote *tmpn=psm.head.next;
+  PsmRecalcNoteXY;
+  x+=PSM_NOTE_SPACING/2;
+  while (x>tmpn->next->x && tmpn!=&psm.head)
+    tmpn=tmpn->next;
+  return tmpn;
+}
+
+U8 *PsmMusicSetOctave(U8 *st,I64 *psm_octave)
+{
+  while ('0'<=*st<='9')
+    *psm_octave=*st++ -'0';
+  return st;
+}
+
+U8 *PsmMusicSetNoteLen(U8 *st,F64 *psm_duration)
+{
+  Bool cont=TRUE;
+  do {
+    switch (*st++) {
+      case 'w': *psm_duration=4.0;  break;
+      case 'h': *psm_duration=2.0;  break;
+      case 'q': *psm_duration=1.0;  break;
+      case 'e': *psm_duration=0.5;  break;
+      case 's': *psm_duration=0.25; break;
+      case 't': *psm_duration=2.0* *psm_duration/3.0;   break;
+      case '.': *psm_duration=1.5* *psm_duration;       break;
+      default:
+        st--;
+        cont=FALSE;
+    }
+  } while (cont);
+  return st;
+}
+
+U0 PsmLoadSongStr(U8 *st,I64 *psm_octave,F64 *psm_duration)
+{
+  PsmNote *tmpn,*tmpn1;
+  I64 note,i=0;
+  while (*st) {
+    tmpn=CAlloc(sizeof(PsmNote));
+    while (*st && !('A'<=*st<='G') && *st!='R') {
+      if (*st=='M') {
+        tmpn1=CAlloc(sizeof(PsmNote));
+        tmpn1->type=PSMT_METER;
+        st++;
+        if ('1'<=*st<='9')
+          tmpn1->meter_top=*st++-'0';
+        else
+          tmpn1->meter_top=4;
+        if (*st=='/')
+          st++;
+        if ('1'<=*st<='9')
+          tmpn1->meter_bottom=*st++-'0';
+        else
+          tmpn1->meter_bottom=4;
+        PsmSetWidth(tmpn1);
+        QueIns(tmpn1,psm.head.last);
+      }
+      while (*st=='(') {
+        Bts(&tmpn->flags,PSMf_TIE);
+        st++;
+      }
+      st=PsmMusicSetOctave(st,psm_octave);
+      st=PsmMusicSetNoteLen(st,psm_duration);
+    }
+    if (!*st) {
+      PsmNoteDel(tmpn);
+      break;
+    }
+    note=*st++-'A';
+    if (note<7) {
+      note=music.note_map[note];
+      if (*st=='b') {
+        Bts(&tmpn->flags,PSMf_FLAT);
+        note--;
+        st++;
+        if (note<0) //Ab
+          note=11;
+        else if (note==2) //Cb
+          *psm_octave-=1;
+      } else if (*st=='#') {
+        Bts(&tmpn->flags,PSMf_SHARP);
+        note++;
+        st++;
+        if (note>11) //G#
+          note=0;
+        else if (note==3) //B#
+          *psm_octave+=1;
+      }
+      tmpn->ona=Note2Ona(note,*psm_octave);
+    } else
+      tmpn->ona=0;
+    if (*psm_duration<=2*.25/3)
+      i=0;
+    else if (*psm_duration<=.25)
+      i=1;
+    else if (*psm_duration<=2*.5/3)
+      i=2;
+    else if (*psm_duration<=.5)
+      i=3;
+    else if (*psm_duration<=2.0/3)
+      i=4;
+    else if (*psm_duration<=.5*1.5)
+      i=5;
+    else if (*psm_duration<=1.0)
+      i=6;
+    else if (*psm_duration<=1.5)
+      i=7;
+    else if (*psm_duration<=2.0)
+      i=8;
+    else if (*psm_duration<=3.0)
+      i=9;
+    else if (*psm_duration<=4.0)
+      i=10;
+    else
+      i=11;
+    tmpn->duration=i;
+    tmpn->type=PSMT_NOTE;
+    PsmSetWidth(tmpn);
+    QueIns(tmpn,psm.cur_note->last);
+  }
+}
+
+U0 PsmLoadSong(U8 *filename,I64 *psm_octave,F64 *psm_duration)
+{
+  U8 *st;
+  PsmNote *tmpn;
+  CCmpCtrl *cc=CmpCtrlNew(MStrPrint("#include \"%s\"",filename));
+  if (FileOcc("incomplete",filename,""))
+    psm.incomplete_entry->checked=TRUE;
+  else
+    psm.incomplete_entry->checked=FALSE;
+  while (Lex(cc)) {
+    if (cc->token==TK_IDENT)
+      if (!StrCmp(cc->cur_str,"Play")) {
+        if (Lex(cc)=='(')
+          if (Lex(cc)==TK_STR) {
+            tmpn=psm.head.last;
+            st=LexExtStr(cc);
+            PsmLoadSongStr(st,psm_octave,psm_duration);
+            if (cc->token==',') {
+              if (Lex(cc)==TK_STR) {
+                st=LexExtStr(cc);
+                do {
+                  do tmpn=tmpn->next;
+                  while (tmpn!=&psm.head && tmpn->type==PSMT_METER);
+                  if (tmpn!=&psm.head)
+                    tmpn->word=StrNew(st);
+                  st+=StrLen(st)+1;
+                } while (*st);
+              }
+            }
+          }
+      } else if (!StrCmp(cc->cur_str,"music") &&
+            Lex(cc)=='.' && Lex(cc)==TK_IDENT) {
+        if (!StrCmp(cc->cur_str,"tempo")) {
+          if (Lex(cc)=='=' && Lex(cc)==TK_F64) {
+            music.tempo=cc->cur_f64-0.0005;
+            tempo_state.tempo=Round(TEMPO_RANGE*(music.tempo-0.5)/4.4);
+          }
+        } else if (!StrCmp(cc->cur_str,"stacatto_factor")) {
+          if (Lex(cc)=='=' && Lex(cc)==TK_F64) {
+            music.stacatto_factor=cc->cur_f64-0.0005;
+            tempo_state.stacatto=
+                  Round(TEMPO_RANGE*(music.stacatto_factor-0.12)/0.88);
+          }
+        }
+      }
+  }
+  CmpCtrlDel(cc);
+}
+
+U8 *PsmCvtSong()
+{
+  PsmNote *tmpn;
+  U8 *st,*src,*dst;
+  I64 i,ona,note,octave,last_octave,last_duration;
+
+  i=0;
+  tmpn=psm.head.next;
+  last_octave=I64_MIN;
+  last_duration=-1;
+  while (tmpn!=&psm.head) {
+    dst=&tmpn->ascii;
+    if (tmpn->type==PSMT_METER) {
+      *dst++='M';
+      *dst++=tmpn->meter_top+'0';
+      *dst++='/';
+      *dst++=tmpn->meter_bottom+'0';
+    } else {
+      if (tmpn->ona) {
+        ona=tmpn->ona;
+        if (Bt(&tmpn->flags,PSMf_SHARP))
+          ona--;
+        if (Bt(&tmpn->flags,PSMf_FLAT))
+          ona++;
+        octave=Ona2Octave(ona);
+        note  =Ona2Note  (ona);
+        note=music.note_map[*LstSub(note,psm_note_lst)-'A'];
+      }
+      if (Bt(&tmpn->flags,PSMf_TIE))
+        *dst++='(';
+      if (octave!=last_octave && tmpn->ona) {
+        *dst++=octave+'0';
+        last_octave=octave;
+      }
+      if (tmpn->duration!=last_duration) {
+        src=LstSub(tmpn->duration,psm_duration_lst);
+        *dst++=src[0];
+        if (src[1])
+          *dst++=src[1];
+        last_duration=tmpn->duration;
+      }
+      if (tmpn->ona) {
+        src=LstSub(note,psm_note_lst);
+        *dst++=src[0];
+        if (src[1])
+          *dst++=src[1];
+        else if (Bt(&tmpn->flags,PSMf_FLAT))
+          *dst++='b';
+        else if (Bt(&tmpn->flags,PSMf_SHARP))
+          *dst++='#';
+      } else
+        *dst++='R';
+    }
+    *dst++=0;
+    i+=StrLen(tmpn->ascii);
+    tmpn=tmpn->next;
+  }
+
+  st=MAlloc(i+1);
+  dst=st;
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    StrCpy(dst,tmpn->ascii);
+    dst+=StrLen(tmpn->ascii);
+    tmpn=tmpn->next;
+  }
+  *dst++=0;
+  return st;
+}
+
+U8 *PsmSaveSong(U8 *dirname,U8 *full_filename)
+{
+  CDoc *doc=DocNew(full_filename);
+  Bool has_words;
+  PsmNote *tmpn,*tmpn1;
+  F64 measure_len=4,two_measure_left=2*measure_len;
+  I64 ch;
+  U8 *ptr;
+
+  Free(PsmCvtSong); //set tmpn->ascii;
+
+  music.tempo=4.4*tempo_state.tempo/TEMPO_RANGE+0.5;
+  music.stacatto_factor=0.88*tempo_state.stacatto/TEMPO_RANGE+0.12;
+
+  has_words=FALSE;
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    if (PsmHasWords(tmpn->word)) has_words=TRUE;
+    tmpn=tmpn->next;
+  }
+  if (psm.incomplete_entry->checked)
+    DocPrint(doc,"//0 incomplete\n");
+  else if (has_words)
+    DocPrint(doc,"//0 has words\n");
+  else
+    DocPrint(doc,"//0 no nothing\n");
+
+  DocPrint(doc,
+        "U0 Song()\n"
+        "{\n"
+        "  Fs->task_end_cb=&SndTaskEndCB;\n"
+        "  MusicSettingsRst;\n"
+        "  music.tempo=%6.3f;\n"
+        "  music.stacatto_factor=%6.3f;\n"
+        "  try {\n"
+        "    while (!ScanKey) {\n"
+        "\tPlay(\"",music.tempo+0.0005,music.stacatto_factor+0.0005);
+
+  tmpn=psm.head.next;
+  tmpn1=tmpn;
+  has_words=FALSE;
+  while (tmpn!=&psm.head) {
+    DocPrint(doc,"%s",tmpn->ascii);
+    if (PsmHasWords(tmpn->word)) has_words=TRUE;
+    if (tmpn->type==PSMT_METER) {
+      measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
+      two_measure_left=0;
+    } else
+      two_measure_left-=psm_durations[tmpn->duration];
+    tmpn=tmpn->next;
+    if (two_measure_left<0.001 && tmpn!=&psm.head) {
+      if (has_words) {
+        DocPrint(doc,"\",\n\t\t\"");
+        while (tmpn1!=tmpn) {
+          if (tmpn1->type!=PSMT_METER) {
+            if (ptr=tmpn1->word) {
+              while (ch=*ptr) {
+                if (ch==CH_SPACE)
+                  *ptr=CH_SHIFT_SPACE;
+                ptr++;
+              }
+              DocPrint(doc,"%Q\\0",tmpn1->word);
+            } else
+              DocPrint(doc,"%c\\0",CH_SHIFT_SPACE);
+          }
+          tmpn1=tmpn1->next;
+        }
+      }
+      DocPrint(doc,"\");\n"
+            "\tPlay(\"");
+      two_measure_left=2*measure_len;
+      tmpn1=tmpn;
+      has_words=FALSE;
+    }
+  }
+  if (has_words) {
+    DocPrint(doc,"\",\n\t\t\"");
+    while (tmpn1!=tmpn) {
+      if (tmpn1->type!=PSMT_METER) {
+        if (ptr=tmpn1->word) {
+          while (ch=*ptr) {
+            if (ch==CH_SPACE)
+              *ptr=CH_SHIFT_SPACE;
+            ptr++;
+          }
+          DocPrint(doc,"%Q\\0",tmpn1->word);
+        } else
+          DocPrint(doc,"%c\\0",CH_SHIFT_SPACE);
+      }
+      tmpn1=tmpn1->next;
+    }
+  }
+  DocPrint(doc,"\");\n"
+        "    }\n"
+        "  } catch\n"
+        "    PutExcept;\n"
+        "  Snd;\n"
+        "}\n"
+        "\n"
+        "Song;\n");
+  DocRecalc(doc);
+  if (full_filename)
+    Free(full_filename);
+  else
+    StrPrint(doc->filename.name,"%s/Tmp.HC.Z",dirname);
+  DocWrite(doc,TRUE);
+  full_filename=StrNew(doc->filename.name);
+  DocDel(doc);
+  return full_filename;
+}
+
+ diff --git a/public/Wb/Apps/Psalmody/PsalmodyMain.HC.HTML b/public/Wb/Apps/Psalmody/PsalmodyMain.HC.HTML new file mode 100755 index 0000000..f17184f --- /dev/null +++ b/public/Wb/Apps/Psalmody/PsalmodyMain.HC.HTML @@ -0,0 +1,829 @@ + + + + + + + + + + + +
+#define PSMR_FLAT               -8
+#define PSMR_SHARP              -7
+#define PSMR_TIE                -6
+#define PSMR_REST               -5
+#define PSMR_INS_NOTE           -4
+#define PSMR_DELETE_NOTE        -3
+#define PSMR_SET_WORD           -2
+
+F64 PopUpDuration()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$GREEN$$MU,\"Set Word\",LE=PSMR_SET_WORD$\n"
+        "$MU,\"Toggle Sharp\",LE=PSMR_SHARP$\n"
+        "$MU,\"Toggle Flat\",LE=PSMR_FLAT$\n"
+        "$MU,\"Toggle Tie\",LE=PSMR_TIE$\n"
+        "$MU,\"Make Rest\",LE=PSMR_REST$\n"
+        "$MU,\"Insert Note\",LE=PSMR_INS_NOTE$\n"
+        "$MU,\"Delete Note\",LE=PSMR_DELETE_NOTE$\n\n");
+  for (i=0;i<PSM_DURATIONS_NUM;i++)
+    DocPrint(doc,"$MU,\"%7.5f\",LE=%d$\n",psm_durations[i],i);
+  DocPrint(doc,"\n$MU,\"CANCEL\",LE=DOCM_CANCEL$\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+U0 PsmRightClick(I64 x,I64 y)
+{
+  U8 *st,*st2;
+  PsmNote *tmpn,*tmpn1;
+  I64 i,old_doc_flags;
+  if (DocPut) old_doc_flags=DocPut->flags;
+  psm.cur_note=tmpn=PsmFindNote(x,y);
+  if (tmpn!=&psm.head) {
+    Fs->win_inhibit=WIG_USER_TASK_DFT;
+    i=PopUpDuration;
+    if (0<=i<PSM_DURATIONS_NUM) {
+      if (tmpn->type==PSMT_NOTE)
+        tmpn->duration=i;
+    } else {
+      switch (i) {
+        case PSMR_REST:
+          if (tmpn->type==PSMT_NOTE)
+            tmpn->ona=0;
+          break;
+        case PSMR_SHARP:
+          if (tmpn->type==PSMT_NOTE && tmpn->ona) {
+            if (Btr(&tmpn->flags,PSMf_FLAT))
+              tmpn->ona++;
+            if (Btc(&tmpn->flags,PSMf_SHARP))
+              tmpn->ona--;
+            else
+              tmpn->ona++;
+          }
+          break;
+        case PSMR_FLAT:
+          if (tmpn->type==PSMT_NOTE && tmpn->ona) {
+            if (Btr(&tmpn->flags,PSMf_SHARP))
+              tmpn->ona--;
+            if (Btc(&tmpn->flags,PSMf_FLAT))
+              tmpn->ona++;
+            else
+              tmpn->ona--;
+          }
+          break;
+        case PSMR_TIE:
+          if (tmpn->type==PSMT_NOTE)
+            Btc(&tmpn->flags,PSMf_TIE);
+          break;
+        case PSMR_SET_WORD:
+          if (tmpn->type==PSMT_NOTE) {
+            if (DocPut) DocPut->flags&=~DOCF_FORM;
+            if (PsmHasWords(tmpn->word))
+              st2=MStrPrint("\nWord(\"%Q\"):",tmpn->word);
+            else
+              st2=MStrPrint("\nWord(\"\"):");
+            DocBottom;
+            st=GetStr(st2);
+            Free(st2);
+            Free(tmpn->word);
+            if (*st) {
+              tmpn->word=MStrPrint("%q",st);
+              Free(st);
+            } else
+              tmpn->word=StrNew(" ");
+            if (DocPut) DocPut->flags=DocPut->flags&
+                    ~DOCF_FORM|old_doc_flags&DOCF_FORM;
+          }
+          break;
+        case PSMR_INS_NOTE:
+          tmpn1=PsmNoteCopy(tmpn);
+          QueIns(tmpn1,tmpn);
+          break;
+        case PSMR_DELETE_NOTE:
+          psm.cur_note=tmpn->next;
+          QueRem(tmpn);
+          PsmNoteDel(tmpn);
+          break;
+      }
+    }
+    PsmSetWidth(psm.cur_note);
+    Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+          -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  }
+}
+
+U0 PsmLeftClickPickNoteBox(I64 duration)
+{
+  I64 o,n,msg_code,arg1,arg2;
+  PsmNote *tmpn,*tmpn1;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+    if (msg_code==MSG_MS_MOVE) {
+      DrawDC2;
+      DrawNote(psm.dc2,arg1,arg2,duration);
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  if (arg2<13*FONT_HEIGHT) {
+    if (arg1>psm.head.last->x)
+      tmpn1=psm.head.last;
+    else if (arg1<psm.head.next->x)
+      tmpn1=&psm.head;
+    else
+      tmpn1=PsmFindNote(arg1-PSM_NOTE_SPACING/2,arg2);
+    tmpn=CAlloc(sizeof(PsmNote));
+    tmpn->type=PSMT_NOTE;
+    arg2=arg2/4-15;
+    n=arg2%7;
+    o=4+arg2/-7;
+    if (n<0) {
+      n+=7;
+      o++;
+    }
+    n=psm_note_inverse_map[n];
+    if (n<3)
+      o--;
+    tmpn->ona=Note2Ona(n,o);
+    tmpn->duration=duration;
+    PsmSetWidth(tmpn);
+    QueIns(tmpn,tmpn1);
+    psm.cur_note=tmpn->next;
+  }
+  DrawDC2;
+}
+
+U0 PsmLeftClickPickMeterBox(I64 top,I64 bottom)
+{
+  I64 msg_code,arg1,arg2;
+  PsmNote *tmpn,*tmpn1;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+    if (msg_code==MSG_MS_MOVE) {
+      DrawDC2;
+      DrawTimeSignature(psm.dc2,arg1,arg2,top,bottom);
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  if (arg2<13*FONT_HEIGHT) {
+    if (arg1>=psm.head.x)
+      tmpn1=psm.head.last;
+    else if (arg1<psm.head.next->x)
+      tmpn1=&psm.head;
+    else
+      tmpn1=PsmFindNote(arg1-PSM_NOTE_SPACING/2,arg2);
+    tmpn=CAlloc(sizeof(PsmNote));
+    tmpn->type=PSMT_METER;
+    tmpn->meter_top=top;
+    tmpn->meter_bottom=bottom;
+    PsmSetWidth(tmpn);
+    QueIns(tmpn,tmpn1);
+    psm.cur_note=tmpn->next;
+  }
+  DrawDC2;
+}
+
+U0 PsmLeftClickStaffPtr(I64 x,I64 y)
+{
+  PsmNote *tmpn,*tmpn1;
+  I64 o,n,msg_code,arg1,arg2,n_original,o_original;
+  psm.cur_note=tmpn=PsmFindNote(x,y);
+  if (tmpn!=&psm.head) {
+    if (tmpn->type==PSMT_NOTE) {
+      o_original=Ona2Octave(tmpn->ona);
+      n_original=Ona2Note  (tmpn->ona);
+      do {
+        msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+        if (msg_code==MSG_MS_L_UP) {
+          tmpn1=PsmFindNote(arg1,arg2);
+          if (tmpn1==&psm.head || tmpn1==tmpn)
+            goto move_note;
+          else {
+            Free(tmpn1->word);
+            tmpn1->word=tmpn->word;
+            tmpn->word=NULL;
+            tmpn->ona=Note2Ona(n_original,o_original);
+          }
+        } else {
+move_note:
+          arg2=arg2/4-15;
+          n=arg2%7;
+          o=4+arg2/-7;
+          if (n<0) {
+            n+=7;
+            o++;
+          }
+          n=psm_note_inverse_map[n];
+          if (n<3)
+            o--;
+          tmpn->ona=Note2Ona(n,o);
+        }
+      } while (msg_code!=MSG_MS_L_UP);
+      PsmSetWidth(tmpn);
+    }
+  }
+}
+
+U0 PsmLeftClickStaffBox(I64 x,I64 y)
+{
+  I64 msg_code,arg1,arg2;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+    DrawDC2;
+    psm.dc2->color=ROPF_DITHER+WHITE<<16+BLACK;
+    GrBorder(psm.dc2,x,y,arg1,arg2);
+    if (msg_code==MSG_MS_L_UP) {
+      if (x>arg1) SwapI64(&x,&arg1);
+      PsmMarkSel(x,arg1,TRUE);
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  DrawDC2;
+}
+
+U0 PsmLeftClick(I64 x,I64 y)
+{
+  I64 duration,top,bottom;
+  if (y<13*FONT_HEIGHT) {
+    if (psm.tool==PSMTT_PTR_TOOL)
+      PsmLeftClickStaffPtr(x,y);
+    else
+      PsmLeftClickStaffBox(x,y);
+  } else {
+    duration=PsmGetPickNoteBoxDuration(x,y);
+    if (0<=duration<PSM_DURATIONS_NUM)
+      PsmLeftClickPickNoteBox(duration);
+    else if (PsmGetPickMeterBox(x,y,&top,&bottom))
+      PsmLeftClickPickMeterBox(top,bottom);
+    else if (PsmGetPickToolBox(x,y))
+      DrawDC2;
+  }
+}
+
+U8 PsmCvtDuration(F64 d)
+{
+  F64 d1,d2;
+  I64 j;
+  for (j=0;j<PSM_DURATIONS_NUM;j++) {
+    d1=psm_durations[j];
+    d2=psm_durations[j+1];
+    if (d<d1*d2/(d1+d2))
+      return j;
+  }
+  return 0;
+}
+
+#define PSM_KEYS_NUM    20
+class PsmKey
+{
+  U8 x,w,h,ascii;
+};
+
+#define PSM_W_W 16
+#define PSM_W_H 36
+#define PSM_B_W 8
+#define PSM_B_H 20
+
+PsmKey psm_kbd[PSM_KEYS_NUM]={
+  { 2*PSM_W_W-4,PSM_B_W,PSM_B_H,'e' },
+  { 3*PSM_W_W-4,PSM_B_W,PSM_B_H,'r' },
+  { 4*PSM_W_W-4,PSM_B_W,PSM_B_H,'t' },
+  { 6*PSM_W_W-4,PSM_B_W,PSM_B_H,'u' },
+  { 7*PSM_W_W-4,PSM_B_W,PSM_B_H,'i' },
+  { 9*PSM_W_W-4,PSM_B_W,PSM_B_H,'p' },
+  {10*PSM_W_W-4,PSM_B_W,PSM_B_H,'[' },
+  {11*PSM_W_W-4,PSM_B_W,PSM_B_H,']' },
+
+  { 0*PSM_W_W,PSM_W_W,PSM_W_H,'a' },
+  { 1*PSM_W_W,PSM_W_W,PSM_W_H,'s' },
+  { 2*PSM_W_W,PSM_W_W,PSM_W_H,'d' },
+  { 3*PSM_W_W,PSM_W_W,PSM_W_H,'f' },
+  { 4*PSM_W_W,PSM_W_W,PSM_W_H,'g' },
+  { 5*PSM_W_W,PSM_W_W,PSM_W_H,'h' },
+  { 6*PSM_W_W,PSM_W_W,PSM_W_H,'j' },
+  { 7*PSM_W_W,PSM_W_W,PSM_W_H,'k' },
+  { 8*PSM_W_W,PSM_W_W,PSM_W_H,'l' },
+  { 9*PSM_W_W,PSM_W_W,PSM_W_H,';' },
+  {10*PSM_W_W,PSM_W_W,PSM_W_H,'\'' },
+  {11*PSM_W_W,PSM_W_W,PSM_W_H,'\n'},
+};
+
+U0 PsmDownKey(I64 x,I64 y)
+{
+  I64 i;
+  PsmKey *o;
+  y-=FONT_HEIGHT*13;
+  if (0<=y<PSM_W_H) {
+    x-=16;
+    for (i=0;i<PSM_KEYS_NUM;i++) {
+      o=&psm_kbd[i];
+      if (o->x<=x<o->x+o->w && y<o->h) {
+        Msg(MSG_KEY_DOWN,o->ascii,0);
+        return;
+      }
+    }
+  }
+}
+
+U0 PsmUpKey(I64 x,I64 y)
+{
+  I64 i;
+  PsmKey *o;
+  y-=FONT_HEIGHT*13;
+  if (0<=y<PSM_W_H) {
+    x-=16;
+    for (i=0;i<PSM_KEYS_NUM;i++) {
+      o=&psm_kbd[i];
+      if (o->x<=x<o->x+o->w && y<o->h) {
+        Msg(MSG_KEY_UP,o->ascii,0);
+        return;
+      }
+    }
+  }
+}
+
+U0 PsmPushMode(I64 psm_octave)
+{
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  PsmMenu(psm_octave);
+}
+
+U0 PsmPopMode()
+{
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  DCFill;
+}
+
+#define PSMF_CD         1
+#define PSMF_INCOMPLETE 2
+
+U0 Psalmody(U8 *dirname="~/Psalmody")
+{
+  Bool was_playing,is_null=TRUE,was_null=TRUE;
+  I64 arg1,arg2,msg_code=0,col,ona=0,last_ona=0,
+        psm_octave=4,timeout_val,timeout_val2,old_doc_flags;
+  U8 *filename=NULL,*st,*st2;
+  PsmNote *tmpn;
+  F64 psm_duration=1.0,d,evt_time=tS,note_down_time=tS;
+  CCtrl *c=TempoNew;
+
+  if (DocPut) old_doc_flags=DocPut->flags;
+  SettingsPush; //See SettingsPush
+
+  MusicSettingsRst;
+  tempo_state.tempo=Round(TEMPO_RANGE*(music.tempo-0.5)/4.4);
+  tempo_state.stacatto=Round(TEMPO_RANGE*(music.stacatto_factor-0.12)/0.88);
+
+  if (DocPut) DocPut->flags|=DOCF_FORM;
+
+  MemSet(&psm,0,sizeof(PsmCtrl));
+  psm.scrn_x=0;
+  psm.head.next=psm.head.last=&psm.head;
+  psm.clip.next=psm.clip.last=&psm.clip;
+  psm.cur_note=&psm.head;
+  psm.dc2=DCAlias;
+
+  MenuPush(
+        "File {"
+        "  New(,'.');"
+        "  ChgDir(MSG_CMD,PSMF_CD);"
+        "  Open(,CH_CTRLO);"
+        "  SaveAs(,CH_CTRLA);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  Cut(,CH_CTRLX);"
+        "  Copy(,CH_CTRLC);"
+        "  Paste(,CH_CTRLV);"
+        "  RightMenu(,'\n');"
+        "  BackSpace(,CH_BACKSPACE);"
+        "  DeleteNote(,,SC_DELETE);"
+        "  ClearSong(,'.');"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  GoBegin(,,0x4CB0000044B);"
+        "  GoEnd(,,0x4CD0000044D);"
+        "}"
+        "Song {"
+        "  Play(,'x');"
+        "  Record(,'z');"
+        "  Random(,',');"
+        "  MarkIncomplete(MSG_CMD,PSMF_INCOMPLETE);"
+        "}"
+        "Snd {"
+        "  Octave1(,'1');"
+        "  Octave2(,'2');"
+        "  Octave3(,'3');"
+        "  Octave4(,'4');"
+        "  Octave5(,'5');"
+        "  Octave6(,'6');"
+        "  Octave7(,'7');"
+        "}"
+        "Help {"
+        "  Help(,,SC_F1);"
+        "}"
+        );
+  psm.incomplete_entry=MenuEntryFind(Fs->cur_menu,"Song/MarkIncomplete");
+  psm.record_entry=MenuEntryFind(Fs->cur_menu,"Song/Record");
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+
+  dirname=StrNew(dirname);
+  PsmPushMode(psm_octave);
+  col=0;
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      was_playing=FALSE;
+mo_start:
+      if (ms.pos_text.y-Fs->win_top<18)
+        msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP|
+              1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_UP|
+              1<<MSG_MS_MOVE|1<<MSG_CMD);
+      else
+        msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP|
+              1<<MSG_MS_MOVE|1<<MSG_CMD);
+mo_got_msg:
+      if (msg_code==MSG_KEY_DOWN && arg1==CH_SPACE && !arg2) {
+//The Window Mgr sets the Doc cur_entry to a bttn
+        //and generates a <SPACE> when the Doc Bttns are clicked.
+        //This is so that kbd and mouse are the same for Doc's.
+        //We must now pass the <SPACE> onto the Doc hndlr.
+        PutKey(arg1,arg2);
+        goto mo_start;
+      }
+      if (msg_code!=MSG_MS_MOVE) {
+        DocBottom;
+        if (was_playing || DocPut->cur_entry->y>=Fs->win_height-2) {
+          PsmMenu(psm_octave);
+          col=0;
+        }
+      }
+
+      ona=Note2Ona(3,psm_octave+1); //C
+      is_null=TRUE;
+      switch (msg_code) {
+        case MSG_CMD:
+          PsmPopMode;
+          switch (arg1) {
+            case PSMF_CD:
+              st2=dirname;
+              if (dirname=PopUpPickDir) {
+                Free(st2);
+                Free(filename);
+                filename=NULL;
+              } else
+                dirname=st2;
+              break;
+            case PSMF_INCOMPLETE:
+              psm.incomplete_entry->checked=!psm.incomplete_entry->checked;
+              break;
+          }
+          PsmPushMode(psm_octave);
+          col=0;
+          break;
+        case MSG_KEY_DOWN:
+          evt_time=tS;
+          if ('0'<=arg1<='9') {
+            psm_octave=arg1-'0';
+            PsmMenu(psm_octave);
+            col=0;
+          } else {
+            switch (arg1) {
+              start:
+                case 'a':       ona-=8;         break;
+                case 's':       ona-=7;         break;
+                case 'e':       ona-=6;         break;
+                case 'd':       ona-=5;         break;
+                case 'r':       ona-=4;         break;
+                case 'f':       ona-=3;         break;
+                case 't':       ona-=2;         break;
+                case 'g':       ona--;          break;
+                case 'h':                       break;
+                case 'u':       ona++;          break;
+                case 'j':       ona+=2;         break;
+                case 'i':       ona+=3;         break;
+                case 'k':       ona+=4;         break;
+                case 'l':       ona+=5;         break;
+                case 'p':       ona+=6;         break;
+                case ';':       ona+=7;         break;
+                case '[':       ona+=8;         break;
+                case '\'':      ona+=9;         break;
+                case ']':       ona+=10;        break;
+                case CH_SPACE:  ona=0;          break;
+              end:
+                is_null=FALSE;
+                break;
+
+              case 0:
+                switch (arg2.u8[0]) {
+                  case SC_CURSOR_LEFT:
+                    if (arg2&SCF_CTRL) {
+                      while (psm.cur_note->last!=&psm.head) {
+                        psm.cur_note=psm.cur_note->last;
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                      }
+                    } else {
+                      if (psm.cur_note->last!=&psm.head) {
+                        psm.cur_note=psm.cur_note->last;
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                      }
+                    }
+                    break;
+                  case SC_CURSOR_RIGHT:
+                    if (arg2&SCF_CTRL) {
+                      while (psm.cur_note!=&psm.head) {
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                        psm.cur_note=psm.cur_note->next;
+                      }
+                    } else {
+                      if (psm.cur_note!=&psm.head) {
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                        psm.cur_note=psm.cur_note->next;
+                      }
+                    }
+                    break;
+                  case SC_DELETE:
+                    if (arg2&SCF_SHIFT)
+                      PsmCutToClip;
+                    else {
+                      tmpn=psm.cur_note;
+                      psm.cur_note=tmpn->next;
+                      if (tmpn!=&psm.head) {
+                        QueRem(tmpn);
+                        PsmNoteDel(tmpn);
+                      }
+                    }
+                    break;
+                  case SC_INS:
+                    if (arg2&SCF_SHIFT)
+                      PsmPasteClip;
+                    else if (arg2&SCF_CTRL)
+                      PsmCopyToClip;
+                    break;
+                  case SC_F1:
+                    PsmPopMode;
+                    PopUpEd("::/Apps/Psalmody/Help.DD.Z",Fs);
+                    PsmPushMode(psm_octave);
+                    col=0;
+                    break;
+                }
+                break;
+              case ',':
+                Free(filename);
+                filename=NULL;
+                PsmPopMode;
+                music.octave=psm_octave;
+                if (st2=GodSongStr) {
+                  PsmLoadSongStr(st2,&psm_octave,&psm_duration);
+                  Free(st2);
+                }
+                PsmPushMode(psm_octave);
+                col=0;
+                break;
+              case CH_CTRLO:
+                PsmPopMode;
+                RegOneTimePopUp(ARf_PSALMODY_JUKEBOX,
+                      "Sel a song and preview it.\n"
+                      "$GREEN$<SHIFT-ESC>$FG$ to load it into Psalmody.\n\n"
+                      ST_WARN_ST " Graphics and other embelishments\n"
+                      "will be lost because Psalmody can't\n"
+                      "parse HolyC programs completely.\n");
+                Free(filename);
+                filename=NULL;
+                JukeBox(dirname,&filename);
+                if (filename) {
+                  psm.scrn_x=0;
+                  psm_duration=1.0;
+                  psm_octave=4;
+                  PsmSongDel(&psm.head);
+                  psm.cur_note=&psm.head;
+                  PsmLoadSong(filename,&psm_octave,&psm_duration);
+                  psm.record_entry->checked=FALSE;
+                  psm.cur_note=psm.head.next;
+                }
+                PsmPushMode(psm_octave);
+                col=0;
+                break;
+              case CH_CTRLA:
+                PsmPopMode;
+                filename=PsmSaveSong(dirname,filename);
+                PsmPushMode(psm_octave);
+                break;
+              case CH_CTRLC:
+                PsmCopyToClip;
+                break;
+              case CH_CTRLV:
+                PsmPasteClip;
+                break;
+              case CH_CTRLX:
+                PsmCutToClip;
+                break;
+              case '.':
+                PsmMenu(psm_octave);
+                col=0;
+                Free(filename);
+                filename=NULL;
+                psm_duration=1.0;
+                psm_octave=4;
+                PsmSongDel(&psm.head);
+                psm.cur_note=&psm.head;
+                psm.scrn_x=0;
+                break;
+              case '\n':
+                if (psm.cur_note!=&psm.head)
+                  PsmRightClick(psm.cur_note->x,psm.cur_note->y);
+                break;
+              case 'x':
+                if (was_playing)
+                  break;
+                col=0;
+                psm.playing=TRUE;
+                PsmMenu(psm_octave);
+                tmpn=psm.cur_note;
+                while (tmpn!=&psm.head) {
+                  if (tmpn->type!=PSMT_METER) {
+                    timeout_val=cnts.jiffies;
+                    if (ms.pos_text.y-Fs->win_top<18)
+                      msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|
+                            1<<MSG_MS_L_DOWN|1<<MSG_MS_R_UP|1<<MSG_CMD);
+                    else
+                      msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|
+                            1<<MSG_MS_L_DOWN|1<<MSG_CMD);
+                    if (msg_code) {
+                      Snd;
+                      psm.playing=FALSE;
+                      was_playing=TRUE;
+                      if (ms.pos_text.y-Fs->win_top>=18 &&
+                            msg_code==MSG_MS_L_DOWN)
+                        goto mo_start;
+                      else
+                        goto mo_got_msg;
+                    }
+                    psm.cur_note=tmpn;
+                    psm.scrn_x+=tmpn->x-0.33*GR_WIDTH;
+                    if (PsmHasWords(tmpn->word))
+                      "%s",tmpn->word;
+                    Snd(tmpn->ona);
+
+                    music.tempo=4.4*tempo_state.tempo/TEMPO_RANGE+0.5;
+                    music.stacatto_factor=
+                          0.88*tempo_state.stacatto/TEMPO_RANGE+0.12;
+                    d=JIFFY_FREQ*psm_durations[tmpn->duration]/music.tempo;
+                    if (Bt(&tmpn->flags,PSMf_TIE)) {
+                      timeout_val+=d;
+                      timeout_val2=timeout_val;
+                    } else {
+                      timeout_val+=d*music.stacatto_factor;
+                      timeout_val2=timeout_val+
+                            d*(1.0-music.stacatto_factor);
+                    }
+                    SleepUntil(timeout_val);
+                    Snd;
+                    SleepUntil(timeout_val2);
+                  }
+                  tmpn=tmpn->next;
+                }
+                psm.cur_note=&psm.head;
+                psm.scrn_x+=psm.cur_note->x-GR_WIDTH/2;
+                psm.playing=FALSE;
+                PsmMenu(psm_octave);
+                col=0;
+                Snd;
+                break;
+              case CH_BACKSPACE:
+                tmpn=psm.cur_note->last;
+                if (tmpn!=&psm.head) {
+                  QueRem(tmpn);
+                  PsmNoteDel(tmpn);
+                }
+                if (col) {
+                  '' CH_BACKSPACE;
+                  col--;
+                }
+                break;
+              case 'z':
+                if (psm.record_entry->checked)
+                  psm.record_entry->checked=FALSE;
+                else {
+                  psm.record_entry->checked=TRUE;
+                  psm_duration=1.0;
+                  psm_octave=4;
+                  psm.scrn_x=0;
+                }
+                PsmMenu(psm_octave);
+                col=0;
+                break;
+              case CH_ESC:
+                PsmPopMode;
+                filename=PsmSaveSong(dirname,filename);
+                PsmPushMode(psm_octave);
+              case CH_SHIFT_ESC:
+                goto mo_done;
+            }
+          }
+          break;
+        case MSG_KEY_UP:
+          evt_time=tS;
+          break;
+        case MSG_MS_MOVE:
+          if (arg2>18*FONT_HEIGHT)
+            Fs->win_inhibit=WIG_USER_TASK_DFT;
+          else
+            Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER
+                  -WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+          break;
+        case MSG_MS_L_DOWN:
+          PsmDownKey(arg1,arg2);
+          PsmLeftClick(arg1,arg2);
+          break;
+        case MSG_MS_L_UP:
+          PsmUpKey(arg1,arg2);
+          break;
+        default:
+          PsmRightClick(arg1,arg2);
+      }
+      if (is_null)
+        ona=0;
+      if (ona!=last_ona || is_null!=was_null) {
+        if (!ona) {
+          if (is_null)
+            st="";
+          else
+            st="R";
+        } else
+          st=LstSub(Ona2Note(ona),psm_note_lst);
+        Snd(ona);
+        if (psm.record_entry->checked) {
+          if (!was_null) {
+            music.tempo=4.4*tempo_state.tempo/TEMPO_RANGE+0.5;
+            music.stacatto_factor=0.88*tempo_state.stacatto/TEMPO_RANGE+0.12;
+            tmpn->duration=PsmCvtDuration(
+                  music.tempo*(evt_time-note_down_time));
+            PsmSetWidth(tmpn);
+            QueIns(tmpn,psm.cur_note->last);
+          }
+          if (!is_null) {
+            note_down_time=tS;
+            tmpn=CAlloc(sizeof(PsmNote));
+            tmpn->type=PSMT_NOTE;
+            tmpn->ona=ona;
+            if (st[1]=='#')
+              Bts(&tmpn->flags,PSMf_SHARP);
+          }
+        }
+        last_ona=ona;
+        was_null=is_null;
+        "%s",st;
+        col+=StrLen(st);
+        if (col>=Fs->win_width-1) {
+          '\n';
+          col=0;
+        }
+      }
+    }
+mo_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  PsmPopMode;
+  PsmSongDel(&psm.head);
+  PsmSongDel(&psm.clip);
+  TempoDel(c);
+  DCFill;
+  DCDel(psm.dc2);
+  DocClear;
+  SettingsPop;
+  if (DocPut) DocPut->flags=DocPut->flags&~DOCF_FORM|old_doc_flags&DOCF_FORM;
+  Free(dirname);
+  MenuPop;
+}
+
+ diff --git a/public/Wb/Apps/Psalmody/Run.HC.HTML b/public/Wb/Apps/Psalmody/Run.HC.HTML new file mode 100755 index 0000000..02995c8 --- /dev/null +++ b/public/Wb/Apps/Psalmody/Run.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Psalmody;
+
+ diff --git a/public/Wb/Apps/Span/Install.HC.HTML b/public/Wb/Apps/Span/Install.HC.HTML new file mode 100755 index 0000000..bf52ff2 --- /dev/null +++ b/public/Wb/Apps/Span/Install.HC.HTML @@ -0,0 +1,32 @@ + + + + + + + + + + + +
+DirMk("~/Span");
+
+ diff --git a/public/Wb/Apps/Span/Load.HC.HTML b/public/Wb/Apps/Span/Load.HC.HTML new file mode 100755 index 0000000..0cb1671 --- /dev/null +++ b/public/Wb/Apps/Span/Load.HC.HTML @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "Span.HH"
+#include "SpanDerive"
+#include "SpanBridge"
+#include "SpanNew"
+#include "SpanMain"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/Span/Run.HC.HTML b/public/Wb/Apps/Span/Run.HC.HTML new file mode 100755 index 0000000..afca3d0 --- /dev/null +++ b/public/Wb/Apps/Span/Run.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Span;
+
+ diff --git a/public/Wb/Apps/Span/Span.HH b/public/Wb/Apps/Span/Span.HH old mode 100644 new mode 100755 diff --git a/public/Wb/Apps/Span/Span.HH.HTML b/public/Wb/Apps/Span/Span.HH.HTML new file mode 100755 index 0000000..1df594a --- /dev/null +++ b/public/Wb/Apps/Span/Span.HH.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+#define SPAN_VERSION    1.0
+
+class SpanHeader
+{
+F64 version;
+I32 num_masses,num_springs;
+};
+
+class MyMass:CMass
+{
+F64 radius,cost,load_t;
+CColorROPU32 color;
+} *cursor_mass;
+
+class MySpring:CSpring
+{
+F64 compression_strength,tensile_strength,cost;
+F64 base_compression_strength,base_tensile_strength,
+base_const,base_cost;
+
+CColorROPU32 color;
+I32 thick;
+};
+
+CMathODE *ode=NULL;
+
+CCtrlBttnState run_bttn,mode_bttn;
+
+CColorROPU32 run_colors[2]={RED,GREEN};
+
+#define MD_MASS         0
+#define MD_CONCRETE     1
+#define MD_STEEL        2
+#define MD_WIRE         3
+#define MD_MOVE         4
+#define MD_DELETE       5
+#define MD_MODES_NUM    6
+CColorROPU32 mode_colors[MD_MODES_NUM]=
+{BROWN,LTGRAY,DKGRAY,RED,PURPLE,RED};
+  DefineLstLoad("ST_SPAN_MODES","Mass\0Concrete\0Steel\0Wire\0Move\0Delete\0");
+
+  class SpanAnimateStruct
+          {
+    U8 *saved_ode;
+  F64 elapsed_t,start_wall_t;
+} a;
+
+extern MyMass *PlaceMass(I64 x, I64 y);
+extern F64 SpanTime();
+
+ diff --git a/public/Wb/Apps/Span/SpanBridge.HC.HTML b/public/Wb/Apps/Span/SpanBridge.HC.HTML new file mode 100755 index 0000000..48b6640 --- /dev/null +++ b/public/Wb/Apps/Span/SpanBridge.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+#define STRENGTH_SCALE  1.5e7
+#define SPRING_SCALE    6.0e6
+#define COST_SCALE      375.0
+#define MASS_RADIUS     3.0
+#define MASS_MASS       10.0
+#define WIRE_PERCENT    0.99
+
+#define RIVER_BANK_COLS 5
+#define SKY_LINES       40
+
+#define FIXED_X1        ((RIVER_BANK_COLS-1)*FONT_WIDTH)
+#define FIXED_X2        ((RIVER_BANK_COLS-4)*FONT_WIDTH)
+#define FIXED_X3        (TEXT_COLS*FONT_WIDTH>>1)
+#define FIXED_Y1        ((SKY_LINES+1)*FONT_HEIGHT)
+#define FIXED_Y2        ((SKY_LINES+5)*FONT_HEIGHT)
+#define FIXED_Y3        ((TEXT_ROWS-8)*FONT_HEIGHT)
+
+#define LOAD_WEIGHTS    8
+
+U0 SpanBridge1Init(CMathODE *)
+{
+  I64 i;
+
+  MyMass *tmpm;
+  tmpm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(GR_WIDTH-FIXED_X2,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y2);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X1,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X2,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X1,FIXED_Y2);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X3,FIXED_Y3);
+  tmpm->flags|=MSF_FIXED;
+
+  for (i=0;i<LOAD_WEIGHTS;i++) {
+    tmpm=PlaceMass(FIXED_X1+(i+1)*(GR_WIDTH-2*FIXED_X1)/(LOAD_WEIGHTS+1),
+          FIXED_Y1);
+    tmpm->load_t=(i+1.0)/LOAD_WEIGHTS;
+    tmpm->color=RED;
+  }
+
+  DocClear;
+  "$BG,LTCYAN$%h*c",SKY_LINES,'\n';
+  for (i=0;i<10;i++) {
+    "$BG,BROWN$%h*c",RIVER_BANK_COLS,CH_SPACE;
+    "$BG,LTCYAN$%h*c",TEXT_COLS-2*RIVER_BANK_COLS,CH_SPACE;
+    "$BG,BROWN$%h*c\n",RIVER_BANK_COLS,CH_SPACE;
+  }
+  for (i=0;i<5;i++)  {
+    "$BG,BROWN$%h*c",RIVER_BANK_COLS+i,CH_SPACE;
+    "$BG,BLUE$%h*c",TEXT_COLS/2-RIVER_BANK_COLS-2*i,CH_SPACE;
+    "$BG,BROWN$%h*c",2*i,CH_SPACE;
+    "$BG,BLUE$%h*c",TEXT_COLS/2-RIVER_BANK_COLS-2*i,CH_SPACE;
+    "$BG,BROWN$%h*c\n",RIVER_BANK_COLS+i,CH_SPACE;
+  }
+}
+
+U0 AdjustLoads(CMathODE *ode)
+{
+  MyMass *tmpm=ode->next_mass;
+  F64 d,tt=SpanTime/10.0;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->load_t) {
+      if (tt) {
+        d=Abs(Sin(tmpm->load_t*pi+tt)); //0.0<=d<=1.0
+        tmpm->mass=100.0*Sqr(Sqr(d+1.0));
+        tmpm->radius=7.0*d+2.0;
+      } else {
+        tmpm->mass=MASS_MASS;
+        tmpm->radius=MASS_RADIUS;
+      }
+    }
+    tmpm=tmpm->next;
+  }
+}
+
+ diff --git a/public/Wb/Apps/Span/SpanDerive.HC.HTML b/public/Wb/Apps/Span/SpanDerive.HC.HTML new file mode 100755 index 0000000..1a6563c --- /dev/null +++ b/public/Wb/Apps/Span/SpanDerive.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+//The forces due to springs and drag are
+  //automatically handled by the
+  //ode code.  We can add new forces
+  //here.
+  CTask *task=ode->win_task;
+  F64 d,dd;
+  CD3 p,p2;
+  MyMass *tmpm1,*tmpm2;
+
+  //Collisions
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      D3Sub(&p,&tmpm2->state->x,&tmpm1->state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=Sqr(tmpm1->radius+tmpm2->radius)) {
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr(Sqr(tmpm1->radius+tmpm2->radius)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&tmpm2->DstateDt->DxDt,&p);
+        D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+      }
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    if (!(tmpm1->flags&MSF_FIXED))
+      tmpm1->DstateDt->DyDt+=10.0*tmpm1->mass; //Gravity
+    tmpm1=tmpm1->next;
+  }
+
+  if (cursor_mass) {
+    p2.x=ms.pos.x-task->pix_left-task->scroll_x;
+    p2.y=ms.pos.y-task->pix_top-task->scroll_y;
+    p2.z=0;
+    D3Sub(&p,&p2,&cursor_mass->state->x);
+    d=10.0*D3NormSqr(&p);
+    D3MulEqu(&p,d);
+    D3AddEqu(&cursor_mass->DstateDt->DxDt,&p);
+  }
+}
+
+ diff --git a/public/Wb/Apps/Span/SpanMain.HC.HTML b/public/Wb/Apps/Span/SpanMain.HC.HTML new file mode 100755 index 0000000..69b7f25 --- /dev/null +++ b/public/Wb/Apps/Span/SpanMain.HC.HTML @@ -0,0 +1,499 @@ + + + + + + + + + + + +
+F64 SpanTime()
+{
+  if (run_bttn.state)
+    return a.elapsed_t+tS-a.start_wall_t;
+  else
+    return a.elapsed_t;
+}
+
+F64 Cost(CMathODE *ode)
+{
+  MyMass   *tmpm;
+  MySpring *tmps;
+  F64 res=0;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    res+=tmpm->cost;
+    tmpm=tmpm->next;
+  }
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    res+=tmps->cost;
+    tmps=tmps->next;
+  }
+  return res;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  MyMass   *tmpm;
+  MySpring *tmps;
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (!(tmps->flags&SSF_INACTIVE)) {
+      dc->color=tmps->color;
+      dc->thick=tmps->thick;
+      GrLine3(dc,tmps->end1->x,tmps->end1->y,0,
+            tmps->end2->x,tmps->end2->y,0);
+    }
+    tmps=tmps->next;
+  }
+
+  if (cursor_mass) {
+    dc->color=RED;
+    dc->thick=2;
+    GrLine3(dc,ms.pos.x-task->pix_left-task->scroll_x,
+          ms.pos.y-task->pix_top-task->scroll_y,0,
+          cursor_mass->x,cursor_mass->y,0);
+  }
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (!(tmpm->flags&MSF_INACTIVE)) {
+      dc->color=BLACK;
+      GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+      GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);
+      dc->color=tmpm->color;
+      GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+      GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);
+      dc->color=BLACK;
+      GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+    }
+    tmpm=tmpm->next;
+  }
+
+  dc->color=BLACK;
+  GrPrint(dc,90,0,"Cost:%12.2,f",Cost(ode));
+  GrPrint(dc,90,FONT_HEIGHT,"Time:%12.2f",SpanTime);
+}
+
+MyMass *PlaceMass(I64 x, I64 y)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass));
+  tmpm->drag_profile_factor=1.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->mass=MASS_MASS;
+  tmpm->radius=MASS_RADIUS;
+  tmpm->cost=25.0*COST_SCALE;
+  tmpm->color=YELLOW;
+  QueIns(tmpm,ode->last_mass);
+  return tmpm;
+}
+
+U0 NullSpring(MySpring *tmps,F64 scale)
+{
+  F64 d=D3Dist(&tmps->end1->x,&tmps->end2->x);
+  tmps->rest_len=d*scale;
+  tmps->compression_strength=
+        tmps->base_compression_strength/(tmps->rest_len+1.0);
+  tmps->tensile_strength=tmps->base_tensile_strength/(tmps->rest_len+1.0);
+  tmps->const=tmps->base_const/(tmps->rest_len+1.0);
+  tmps->cost=tmps->base_cost*tmps->rest_len;
+}
+
+U0 MoveMass(MyMass *tmpm,I64 x, I64 y)
+{
+  MySpring *tmps;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->DxDt=0;
+  tmpm->DyDt=0;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->end1==tmpm || tmps->end2==tmpm) {
+      if (tmps->flags&SSF_NO_COMPRESSION)
+        NullSpring(tmps,WIRE_PERCENT);
+      else
+        NullSpring(tmps,1.0);
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 DelSpring(MySpring *tmps)
+{
+  QueRem(tmps);
+  Free(tmps);
+}
+
+U0 DelMass(MyMass *tmpm)
+{
+  MySpring *tmps,*tmps1;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps1=tmps->next;
+    if (tmps->end1==tmpm || tmps->end2==tmpm)
+      DelSpring(tmps);
+    tmps=tmps1;
+  }
+  QueRem(tmpm);
+  Free(tmpm);
+}
+
+U0 DrawSpring(CDC *dc,MyMass *tmpm,I64 x,I64 y)
+{
+  switch (mode_bttn.state) {
+    case MD_CONCRETE:
+      dc->color=LTGRAY;
+      dc->thick=2;
+      break;
+    case MD_STEEL:
+      dc->color=DKGRAY;
+      dc->thick=2;
+      break;
+    case MD_WIRE:
+      dc->color=RED;
+      dc->thick=1;
+      break;
+  }
+  GrLine3(dc,tmpm->x,tmpm->y,0,x,y,0);
+}
+
+U0 PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  switch (mode_bttn.state) {
+    case MD_CONCRETE:
+      tmps->base_const        = 3.00*SPRING_SCALE;
+      tmps->base_compression_strength=10.00*STRENGTH_SCALE;
+      tmps->base_tensile_strength    = 0.35*STRENGTH_SCALE;
+      tmps->base_cost                 = 0.30*COST_SCALE;
+      NullSpring(tmps,1.0);
+      tmps->color=LTGRAY;
+      tmps->thick=2;
+      break;
+    case MD_STEEL:
+      tmps->base_const        = 1.00*SPRING_SCALE;
+      tmps->base_compression_strength= 1.00*STRENGTH_SCALE;
+      tmps->base_tensile_strength    = 1.00*STRENGTH_SCALE;
+      tmps->base_cost                 = 1.00*COST_SCALE;
+      NullSpring(tmps,1.0);
+      tmps->color=DKGRAY;
+      tmps->thick=2;
+      break;
+    case MD_WIRE:
+      tmps->base_const        = 0.25*SPRING_SCALE;
+      tmps->base_compression_strength= 0.00;
+      tmps->base_tensile_strength    = 0.50*STRENGTH_SCALE;
+      tmps->base_cost                 = 0.10*COST_SCALE;
+      NullSpring(tmps,WIRE_PERCENT);
+      tmps->color=RED;
+      tmps->thick=1;
+      tmps->flags|=SSF_NO_COMPRESSION;
+      break;
+  }
+  QueIns(tmps,ode->last_spring);
+}
+
+U0 AnimateTask(SpanAnimateStruct *a)
+{
+  MySpring *tmps,*tmps1;
+  Bool old_run=FALSE;
+  F64 f;
+  while (TRUE) {
+    tmps=ode->next_spring;
+    while (tmps!=&ode->next_spring) {
+      tmps1=tmps->next;
+      f=tmps->f;
+      if (f>0 &&  f>tmps->compression_strength &&
+            !(tmps->flags&SSF_NO_COMPRESSION)||
+            f<0 && -f>tmps->tensile_strength &&
+            !(tmps->flags&SSF_NO_TENSION))
+        tmps->flags|=SSF_INACTIVE;
+      tmps=tmps1;
+    }
+    AdjustLoads(ode);
+    Refresh; //CMathODE updated once per refresh.
+    if (old_run!=run_bttn.state) {
+      if (run_bttn.state) {
+        if (!a->elapsed_t || !a->saved_ode) {
+          Free(a->saved_ode);
+          a->saved_ode=SpanSave(ode);
+        }
+        a->start_wall_t=tS;
+        ODEPause(ode,OFF);
+      } else {
+        ODEPause(ode);
+        a->elapsed_t+=tS-a->start_wall_t;
+      }
+      old_run=run_bttn.state;
+    }
+  }
+}
+
+U0 Init(SpanAnimateStruct *a)
+{
+  SpanDel(ode);
+  ode=SpanNew;
+
+  run_bttn.state=0;
+  Refresh(2); //Allow stop to reg in animate task.
+
+  if (a->saved_ode)
+    SpanLoad(ode,a->saved_ode);
+  else
+    SpanBridge1Init(ode);
+  a->elapsed_t=0;
+  cursor_mass=NULL;
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 3.636;
+  music.stacatto_factor= 0.902;
+  while (TRUE) {
+    Play("5q.EeDqED4G5DhE");
+    Play("5q.EeDqED4G5DhE");
+    Play("5q.FeEFEqF4G5EhF");
+    Play("5q.FeEFEqF4G5EhF");
+  }
+}
+
+U0 Span()
+{
+  I64 msg_code,arg1,arg2;
+  MyMass   *tmpm1=NULL,*tmpm2=NULL;
+  MySpring *tmps;
+  CCtrl *bt_run,*bt_mode;
+  U8 *src;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BROWN<<4+BLACK;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+
+  bt_run =CtrlBttnNew(0,0,                80,,
+        2,"Stopped\0Running\0",run_colors,&run_bttn);
+  bt_mode=CtrlBttnNew(0,3.0*FONT_HEIGHT,80,,
+        MD_MODES_NUM,Define("ST_SPAN_MODES"),mode_colors,&mode_bttn);
+  a.saved_ode=NULL;
+
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  New(,CH_CTRLN);"
+        "  Open(,CH_CTRLO);"
+        "  SaveAs(,CH_CTRLA);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  RunStop(,CH_SPACE);"
+        "  Mass(,'m');"
+        "  Concrete(,'c');"
+        "  Steel(,'s');"
+        "  Wire(,'w');"
+        "  Move(,'v');"
+        "  Delete(,'d');"
+        "}"
+        );
+
+  ode=NULL;
+  Init(&a);
+  Fs->animate_task=Spawn(&AnimateTask,&a,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  PopUpOk(
+        "Build a bridge to hold-up the\n"
+        "red masses.  Test your design\n"
+        "by pressing run/stop.\n\n"
+        "The lowest cost bridge that\n"
+        "stays standing wins.\n\n"
+        "For a variation, try without\n"
+        "using the center base point.\n"
+        "\n"
+        "Use\n"
+        "\t$GREEN$'m'$FG$ass\n"
+        "\t$GREEN$'c'$FG$oncrete\n"
+        "\t$GREEN$'s'$FG$teel\n"
+        "\t$GREEN$'w'$FG$ire\n"
+        "\nto sel materials.\n");
+
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|
+            1<<MSG_MS_L_UP|1<<MSG_KEY_DOWN|1<<MSG_MS_MOVE);
+      DCFill(dc);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+          cursor_mass=tmpm1=tmpm2=NULL;
+          switch (mode_bttn.state) {
+            case MD_MASS:
+              PlaceMass(arg1,arg2);
+              break;
+            case MD_CONCRETE:
+            case MD_STEEL:
+            case MD_WIRE:
+              tmpm1=MassFind(ode,arg1,arg2);
+              break;
+            case MD_MOVE:
+              if (run_bttn.state)
+                cursor_mass=MassFind(ode,arg1,arg2);
+              else
+                if (tmpm1=MassFind(ode,arg1,arg2))
+                  MoveMass(tmpm1,arg1,arg2);
+              break;
+            case MD_DELETE:
+              MassOrSpringFind(ode,&tmpm1,&tmps,arg1,arg2);
+              if (tmpm1)
+                DelMass(tmpm1);
+              if (tmps)
+                DelSpring(tmps);
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (mode_bttn.state) {
+            case MD_CONCRETE:
+            case MD_STEEL:
+            case MD_WIRE:
+              if (tmpm1 && (tmpm2=MassFind(ode,arg1,arg2)) && tmpm1!=tmpm2)
+                PlaceSpring(tmpm1,tmpm2);
+              break;
+            case MD_MOVE:
+              if (!run_bttn.state && tmpm1)
+                MoveMass(tmpm1,arg1,arg2);
+              break;
+          }
+          cursor_mass=tmpm1=tmpm2=NULL;
+          break;
+        case MSG_MS_MOVE:
+          switch (mode_bttn.state) {
+            case MD_MOVE:
+              if (!run_bttn.state && tmpm1)
+                MoveMass(tmpm1,arg1,arg2);
+              break;
+            case MD_CONCRETE:
+            case MD_STEEL:
+            case MD_WIRE:
+              if (tmpm1) {
+                DrawSpring(dc,tmpm1,arg1,arg2);
+              }
+              break;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+          mode_bttn.state++;
+          if (mode_bttn.state>=MD_MODES_NUM)
+            mode_bttn.state=0;
+          cursor_mass=tmpm1=tmpm2=NULL;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              if (!SpanTime || !a.saved_ode) {
+                Free(a.saved_ode);
+                a.saved_ode=SpanSave(ode);
+              }
+              Init(&a);
+              break;
+            case CH_CTRLN:
+              Free(a.saved_ode);
+              a.saved_ode=NULL;
+              Init(&a);
+              break;
+            case CH_CTRLO:
+              if (src=SpanRead) {
+                Free(a.saved_ode);
+                a.saved_ode=src;
+                Init(&a);
+              }
+              break;
+            case CH_CTRLA:
+              if (!SpanTime || !a.saved_ode) {
+                Free(a.saved_ode);
+                a.saved_ode=SpanSave(ode);
+              }
+              Init(&a);
+              SpanWrite(ode);
+              break;
+            case CH_SPACE:
+              run_bttn.state=!run_bttn.state;
+              break;
+            case 'c':
+              mode_bttn.state=MD_CONCRETE;
+              break;
+            case 's':
+              mode_bttn.state=MD_STEEL;
+              break;
+            case 'w':
+              mode_bttn.state=MD_WIRE;
+              break;
+            case 'm':
+              mode_bttn.state=MD_MASS;
+              break;
+            case 'v':
+              mode_bttn.state=MD_MOVE;
+              break;
+            case 'd':
+              mode_bttn.state=MD_DELETE;
+              break;
+            case CH_ESC:
+              if (!SpanTime || !a.saved_ode) {
+                Free(a.saved_ode);
+                a.saved_ode=SpanSave(ode);
+              }
+              Init(&a);
+              SpanWrite(ode);
+            case CH_SHIFT_ESC:
+              goto span_done;
+          }
+          break;
+      }
+    }
+span_done: //Don't goto out of try
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+  CtrlBttnDel(bt_run);
+  CtrlBttnDel(bt_mode);
+  SpanDel(ode);
+  DCFill(dc);
+  DCDel(dc);
+  MenuPop;
+}
+
+ diff --git a/public/Wb/Apps/Span/SpanNew.HC.HTML b/public/Wb/Apps/Span/SpanNew.HC.HTML new file mode 100755 index 0000000..992f4a1 --- /dev/null +++ b/public/Wb/Apps/Span/SpanNew.HC.HTML @@ -0,0 +1,157 @@ + + + + + + + + + + + +
+CMathODE *SpanNew()
+{
+  CMathODE *ode=ODENew(0,1e-4,ODEF_HAS_MASSES|ODEF_PAUSED);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+  QueIns(ode,Fs->last_ode);
+  return ode;
+}
+
+U0 SpanDel(CMathODE *ode)
+{
+  if (ode) {
+    QueRem(ode);
+    QueDel(&ode->next_mass,TRUE);
+    QueDel(&ode->next_spring,TRUE);
+    ODEDel(ode);
+  }
+}
+
+#define M_SIZE (sizeof(MyMass)  -offset(CMass.start))
+#define S_SIZE (sizeof(MySpring)-offset(CSpring.start))
+
+U8 *SpanSave(CMathODE *ode,I64 *_size=NULL)
+{
+  I64 cnt;
+  U8 *res,*ptr;
+  MyMass   *tmpm;
+  MySpring *tmps;
+  SpanHeader h;
+
+  ODERenum(ode);
+  h.version=SPAN_VERSION;
+  if (ode->next_mass!=&ode->next_mass)
+    h.num_masses=ode->last_mass->num+1;
+  else
+    h.num_masses=0;
+  if (ode->next_spring!=&ode->next_spring)
+    h.num_springs=ode->last_spring->num+1;
+  else
+    h.num_springs=0;
+
+  cnt=sizeof(SpanHeader)+h.num_masses*M_SIZE+h.num_springs*S_SIZE;
+
+  ptr=res=MAlloc(cnt);
+  MemCpy(ptr,&h,sizeof(SpanHeader));
+  ptr+=sizeof(SpanHeader);
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    MemCpy(ptr,&tmpm->start,M_SIZE);
+    ptr+=M_SIZE;
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    MemCpy(ptr,&tmps->start,S_SIZE);
+    ptr+=S_SIZE;
+    tmps=tmps->next;
+  }
+  if (_size) *_size=cnt;
+  return res;
+}
+
+Bool SpanWrite(CMathODE *ode)
+{
+  U8 *name,*buf;
+  I64 size;
+  Bool res=FALSE,old_silent=Silent;
+  DirMk("~/Span");
+  Silent(old_silent);
+  if (name=PopUpFileName("~/Span/Game.DATA")) {
+    if (buf=SpanSave(ode,&size)) {
+      FileWrite(name,buf,size);
+      Free(buf);
+      res=TRUE;
+    }
+    Free(name);
+  }
+  return res;
+}
+
+U0 SpanLoad(CMathODE *ode,U8 *src)
+{
+  I64 i;
+  MyMass   *tmpm;
+  MySpring *tmps;
+  SpanHeader h;
+
+  if (!src) return;
+
+  MemCpy(&h,src,sizeof(SpanHeader));
+  src+=sizeof(SpanHeader);
+
+  for (i=0;i<h.num_masses;i++) {
+    tmpm=CAlloc(sizeof(MyMass));
+    MemCpy(&tmpm->start,src,M_SIZE);
+    src+=M_SIZE;
+    QueIns(tmpm,ode->last_mass);
+  }
+
+  for (i=0;i<h.num_springs;i++) {
+    tmps=CAlloc(sizeof(MySpring));
+    MemCpy(&tmps->start,src,S_SIZE);
+    src+=S_SIZE;
+    QueIns(tmps,ode->last_spring);
+    tmps->end1=MassFindNum(ode,tmps->end1_num);
+    tmps->end2=MassFindNum(ode,tmps->end2_num);
+  }
+}
+
+U8 *SpanRead()
+{
+  U8 *src=NULL,*name;
+  Bool old_silent=Silent;
+  DirMk("~/Span");
+  Silent(old_silent);
+  if (name=PopUpPickFile("~/Span")) {
+    src=FileRead(name);
+    Free(name);
+  }
+  return src;
+}
+
+
+ diff --git a/public/Wb/Apps/Strut/Load.HC.HTML b/public/Wb/Apps/Strut/Load.HC.HTML new file mode 100755 index 0000000..b739757 --- /dev/null +++ b/public/Wb/Apps/Strut/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "Strut"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/Strut/Run.HC.HTML b/public/Wb/Apps/Strut/Run.HC.HTML new file mode 100755 index 0000000..828cc1b --- /dev/null +++ b/public/Wb/Apps/Strut/Run.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Strut;
+
+ diff --git a/public/Wb/Apps/Strut/Strut.HC.HTML b/public/Wb/Apps/Strut/Strut.HC.HTML new file mode 100755 index 0000000..7a5ec6c --- /dev/null +++ b/public/Wb/Apps/Strut/Strut.HC.HTML @@ -0,0 +1,667 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+#define STARS_NUM       8192
+I64 stars_x[STARS_NUM],stars_y[STARS_NUM];
+
+#define RADIUS  7
+
+class MyMass:CMass
+{
+  U8 *img;
+};
+
+class MySpring:CSpring
+{
+  I64 type,action_key;
+};
+
+//Main Modses
+#define MMD_EDIT        0
+#define MMD_PLAY        1
+#define MMD_MODES_NUM   2
+CColorROPU32 main_mode_colors[MMD_MODES_NUM]={LTRED,LTGREEN};
+DefineLstLoad("ST_MAIN_MODES","Edit\0Play\0");
+CCtrlBttnState main_mode_bttn;
+
+//Edit Modes
+#define EMD_MASS        0
+#define EMD_SPRING      1
+#define EMD_CONNECTOR   2
+#define EMD_THRUSTER    3
+#define EMD_MOVE        4
+#define EMD_MODES_NUM   5
+CColorROPU32 edit_mode_colors[EMD_MODES_NUM]={LTGRAY,LTCYAN,CYAN,YELLOW,LTBLUE};
+DefineLstLoad("ST_EDIT_MODES","Mass\0Spring\0Connector\0Thruster\0Move\0");
+CCtrlBttnState edit_mode_bttn;
+
+CTask *task;
+F64 zoom;
+I64 next_action_key,action_scan_codes[10];
+CMathODE *ode=NULL;
+
+U0 S2W(F64 sx,F64 sy,F64 *_wx,F64 *_wy)
+{
+  sx-=task->pix_left+task->scroll_x;
+  sy-=task->pix_top +task->scroll_y;
+  *_wx=sx/zoom;
+  *_wy=sy/zoom;
+}
+
+U0 W2S(F64 wx,F64 wy,F64 *_sx,F64 *_sy)
+{
+  *_sx=wx*zoom; *_sy=wy*zoom;
+}
+
+#define ZOOM_STEPS      20
+
+U0 Zoom(F64 d)
+{
+  F64 sx,sy,wx,wy;
+  I64 i,x=ms.pos.x,y=ms.pos.y;
+  d=Exp(Ln(d)/ZOOM_STEPS);
+  for (i=0;i<ZOOM_STEPS;i++) {
+    S2W(x,y,&wx,&wy);
+    zoom=Clamp(zoom*d,0.02,50);
+    W2S(wx,wy,&sx,&sy);
+    task->scroll_x=ms.pos.x-sx-task->pix_left;
+    task->scroll_y=ms.pos.y-sy-task->pix_top;
+    Sleep(10);
+  }
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  F64 theta,d,x1,y1,x2,y2;
+  MyMass   *tmpm;
+  MySpring *tmps;
+
+  tmpm=ode->next_mass;
+  if (tmpm!=&ode->next_mass) {
+    task->scroll_x=-tmpm->x*zoom+task->pix_width >>1;
+    task->scroll_y=-tmpm->y*zoom+task->pix_height>>1;
+  }
+
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4Scale(dc->r,zoom);
+
+  switch (main_mode_bttn.state) {
+    case MMD_EDIT:
+      task->text_attr=DKGRAY<<4+WHITE;
+      dc->color=BLACK;
+      break;
+    case MMD_PLAY:
+      task->text_attr=BLACK<<4+WHITE;
+      dc->color=WHITE;
+      for (i=0;i<STARS_NUM;i++)
+        GrPlot3(dc,stars_x[i],stars_y[i],0);
+      break;
+  }
+
+  if (main_mode_bttn.state==MMD_EDIT) {
+    if (edit_mode_bttn.state==EMD_CONNECTOR) {
+      dc->color=CYAN;
+      S2W(FONT_WIDTH*11,FONT_HEIGHT*7,&x1,&y1);
+      GrPutChar3(dc,x1,y1,0,next_action_key);
+    } else if (edit_mode_bttn.state==EMD_THRUSTER) {
+      dc->color=YELLOW;
+      S2W(FONT_WIDTH*11,FONT_HEIGHT*7,&x1,&y1);
+      GrPutChar3(dc,x1,y1,0,next_action_key);
+    }
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->type==EMD_SPRING) {
+      dc->color=LTCYAN;
+      GrLine3(dc,tmps->end1->x,tmps->end1->y,0,
+            tmps->end2->x,tmps->end2->y,0);
+    } else if (tmps->type==EMD_CONNECTOR) {
+      dc->color=CYAN;
+      GrLine3(dc,tmps->end1->x,tmps->end1->y,0,
+            tmps->end2->x,tmps->end2->y,0);
+    }
+    tmps=tmps->next;
+  }
+
+  dc->color=LTGRAY;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    Sprite3(dc,tmpm->x,tmpm->y,0,tmpm->img);
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    x1=tmps->end1->x; y1=tmps->end1->y;
+    x2=tmps->end2->x; y2=tmps->end2->y;
+    if (tmps->type==EMD_THRUSTER) {
+      theta=Arg(x2-x1,y2-y1);
+      if (Bt(kbd.down_bitmap,action_scan_codes[tmps->action_key-'0'])) {
+        dc->flags|=DCF_SYMMETRY;
+        DCSymmetry3Set(dc,x1,y1,256,x1,y1,0,x1-256*Cos(theta),y1-256*Sin(theta),0);
+        for (i=0;i<8;i++) {
+          d=20*Rand+6;
+          if (d<10)
+            dc->color=BLUE;
+          else if (d<16)
+            dc->color=LTBLUE;
+          else
+            dc->color=YELLOW;
+          GrLine3(dc,x1-3*Cos(theta),y1-3*Sin(theta),0,
+                x1-d*Cos(theta)+0.5*d*Sin(theta),
+                y1-d*Sin(theta)-0.5*d*Cos(theta),0);
+          GrLine3(dc,x1-2*d*Cos(theta),y1-2*d*Sin(theta),0,
+                x1-d*Cos(theta)+0.5*d*Sin(theta),
+                y1-d*Sin(theta)-0.5*d*Cos(theta),0);
+        }
+        dc->flags&=~DCF_SYMMETRY;
+      }
+      Sprite3ZB(dc,x1,y1,0,<3>,theta);
+      if (zoom>0.5) {
+        dc->color=YELLOW;
+        GrPutChar3(dc,(x1*7+x2)/8,(y1*7+y2)/8,0,tmps->action_key);
+      }
+    } else if (tmps->type==EMD_CONNECTOR) {
+      if (zoom>0.5) {
+        dc->color=CYAN;
+        GrPutChar3(dc,(x1*7+x2)/8,(y1*7+y2)/8,0,tmps->action_key);
+      }
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+//The forces due to springs and drag are
+  //automatically handled by the
+  //ode code.  We can add new forces
+  //here.
+  F64 d,dd;
+  CD3 p;
+  MyMass *tmpm1,*tmpm2;
+  MySpring *tmps;
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      D3Sub(&p,&tmpm2->state->x,&tmpm1->state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=Sqr(2*RADIUS)) {
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr(Sqr(2*RADIUS)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&tmpm2->DstateDt->DxDt,&p);
+        D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+      }
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (main_mode_bttn.state==MMD_PLAY && tmps->type==EMD_THRUSTER &&
+          Bt(kbd.down_bitmap,action_scan_codes[tmps->action_key-'0'])) {
+      D3Sub(&p,&tmps->end2->state->x,&tmps->end1->state->x);
+      D3Unit(&p);
+      D3MulEqu(&p,2000);
+      D3AddEqu(&tmps->end1->DstateDt->DxDt,&p);
+    }
+    tmps=tmps->next;
+  }
+}
+
+MyMass *PlaceMass(I64 x, I64 y)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass));
+  tmpm->mass=1.0;
+  tmpm->drag_profile_factor=100.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  QueIns(tmpm,ode->last_mass);
+  return tmpm;
+}
+
+MySpring *PlaceSpring(MyMass *tmpm1,MyMass *tmpm2,I64 type)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  F64 d=D3Dist(&tmpm1->x,&tmpm2->x);
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  tmps->rest_len=d;
+  tmps->type=type;
+  if (type==EMD_THRUSTER)
+    tmps->const=0;
+  else
+    tmps->const=2500000/Sqr(d);
+  tmps->action_key=next_action_key;
+  QueIns(tmps,ode->last_spring);
+  return tmps;
+}
+
+U0 CenterMasses()
+{
+  CD3 p;
+  MyMass *tmpm1,*tmpm2;
+  tmpm1=ode->next_mass;
+  if (tmpm1!=&ode->next_mass) {
+    D3Copy(&p,&tmpm1->x);
+    tmpm2=ode->next_mass;
+    while (tmpm2!=&ode->next_mass) {
+      D3SubEqu(&tmpm2->x,&p);
+      tmpm2=tmpm2->next;
+    }
+  }
+}
+
+U0 NullSprings()
+{
+  MySpring *tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps->rest_len=D3Dist(&tmps->end1->x,&tmps->end2->x);
+    tmps=tmps->next;
+  }
+}
+
+U0 BreakConnectors()
+{
+  MySpring *tmps=ode->next_spring,*tmps1;
+  while (tmps!=&ode->next_spring) {
+    tmps1=tmps->next;
+    if (tmps->type==EMD_CONNECTOR &&
+          Bt(kbd.down_bitmap,action_scan_codes[tmps->action_key-'0'])) {
+      QueRem(tmps);
+      Free(tmps);
+    }
+    tmps=tmps1;
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  task=Fs;
+  for (i=0;i<=9;i++)
+    action_scan_codes[i]=Char2ScanCode('0'+i);
+  for (i=0;i<STARS_NUM;i++) {
+    stars_x[i]=RandU32%8192-4096;
+    stars_y[i]=RandU32%8192-4096;
+  }
+  next_action_key='1';
+  zoom=1.0;
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->acceleration_limit=5e3;
+  ode->drag_v2=0.000002;
+  ode->drag_v3=0.0000001;
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  if (ode) {
+    QueRem(ode);
+    QueDel(&ode->next_mass,TRUE);
+    QueDel(&ode->next_spring,TRUE);
+    ODEDel(ode);
+    ode=NULL;
+  }
+}
+
+U0 PlayShip()
+{
+  I64 arg1,arg2;
+  F64 last_noise=0;
+  Bool okay;
+  ODEPause(ode,OFF);
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  EditShip(,CH_SPACE);"
+        "}"
+        "Play {"
+        "  Center(,'c');"
+        "  Damp(,'d');"
+        "  Action0(,'0');"
+        "  Action1(,'1');"
+        "  Action2(,'2');"
+        "  Action3(,'3');"
+        "  Action4(,'4');"
+        "  Action5(,'5');"
+        "  Action6(,'6');"
+        "  Action7(,'7');"
+        "  Action8(,'8');"
+        "  Action9(,'9');"
+        "}"
+        "View {"
+        "  ZoomIn(,'z');"
+        "  ZoomOut(,'Z');"
+        "}"
+        );
+  DocClear;
+  try {
+    while (main_mode_bttn.state==MMD_PLAY) {
+      BreakConnectors;
+      switch (ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '0'...'9':
+              if (tS>last_noise+0.25) {
+                Noise(250,18,46);
+                last_noise=tS;
+              }
+              break;
+            case 'z':
+              Spawn(&Zoom,2.0(I64));
+              break;
+            case 'Z':
+              Spawn(&Zoom,0.5(I64));
+              break;
+            case 'c':
+              CenterMasses;
+              break;
+            case 'd':
+              ode->drag_v2=0.002;
+              ode->drag_v3=0.0001;
+              break;
+            case CH_SPACE:
+              if (++main_mode_bttn.state==MMD_MODES_NUM)
+                main_mode_bttn.state=0;
+              GetMsg(,,1<<MSG_KEY_UP);
+              goto ps_done;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              throw;
+          }
+          break;
+        case MSG_KEY_UP:
+          switch (arg1) {
+            case 'd':
+              ode->drag_v2=0.000002;
+              ode->drag_v3=0.0000001;
+              break;
+          }
+          break;
+      }
+      Refresh;
+    }
+ps_done: //Don't goto out of try
+    okay=TRUE;
+  } catch {
+    Fs->catch_except=TRUE;
+    okay=FALSE;
+  }
+  MenuPop;
+  if (!okay)
+    throw;
+}
+
+U0 EditShip()
+{
+  I64 arg1,arg2;
+  F64 wx,wy;
+  Bool okay;
+  MyMass *tmpm1=NULL,*tmpm2=NULL;
+  CCtrl *bt_edit_mode=CtrlBttnNew(0,5*FONT_HEIGHT+4,80,,EMD_MODES_NUM,
+        Define("ST_EDIT_MODES"),edit_mode_colors,&edit_mode_bttn);
+  ODEPause(ode);
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  PlayShip(,CH_SPACE);"
+        "  Center(,'c');"
+        "  Damp(,'d');"
+        "}"
+        "Edit {"
+        "  Move(,'v');"
+        "  Mass(,'m');"
+        "  Spring(,'s');"
+        "  Connector(,'n');"
+        "  Thruster(,'t');"
+        "  Restart(,'\n');"
+        "  Action0(,'0');"
+        "  Action1(,'1');"
+        "  Action2(,'2');"
+        "  Action3(,'3');"
+        "  Action4(,'4');"
+        "  Action5(,'5');"
+        "  Action6(,'6');"
+        "  Action7(,'7');"
+        "  Action8(,'8');"
+        "  Action9(,'9');"
+        "}"
+        "View {"
+        "  ZoomIn(,'z');"
+        "  ZoomOut(,'Z');"
+        "}"
+        );
+  DocClear;
+  try {
+    while (main_mode_bttn.state==MMD_EDIT) {
+      switch (ScanMsg(&arg1,&arg2,
+            1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|
+            1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_MS_L_DOWN:
+          switch (edit_mode_bttn.state) {
+            case EMD_MASS:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              tmpm1=PlaceMass(wx,wy);
+              if (ode->next_mass==tmpm1)
+                tmpm1->img=<1>;
+              else
+                tmpm1->img=<2>;
+              tmpm1=NULL;
+              break;
+            case EMD_SPRING:
+            case EMD_CONNECTOR:
+            case EMD_THRUSTER:
+            case EMD_MOVE:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              tmpm1=MassFind(ode,wx,wy);
+              tmpm2=NULL;
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (edit_mode_bttn.state) {
+            case EMD_MASS:
+              break;
+            case EMD_SPRING:
+            case EMD_CONNECTOR:
+            case EMD_THRUSTER:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              if (tmpm1 && (tmpm2=MassFind(ode,wx,wy)) && tmpm1!=tmpm2)
+                PlaceSpring(tmpm1,tmpm2,edit_mode_bttn.state);
+              tmpm1=tmpm2=NULL;
+              break;
+            case EMD_MOVE:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              if (tmpm1) {
+                tmpm1->x=wx;
+                tmpm1->y=wy;
+                tmpm1->z=0;
+                NullSprings;
+              }
+              tmpm1=tmpm2=NULL;
+              break;
+          }
+          break;
+        case MSG_MS_MOVE:
+          switch (edit_mode_bttn.state) {
+            case EMD_MOVE:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              if (tmpm1) {
+                tmpm1->x=wx;
+                tmpm1->y=wy;
+                tmpm1->z=0;
+                NullSprings;
+              }
+              break;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+          if (++edit_mode_bttn.state==EMD_MODES_NUM)
+            edit_mode_bttn.state=0;
+          break;
+        case MSG_MS_R_UP:
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case '0'...'9':
+              next_action_key=arg1;
+              break;
+            case 'c':
+              CenterMasses;
+              break;
+            case 'd':
+              ODEPause(ode,OFF);
+              ode->drag_v2=0.002;
+              ode->drag_v3=0.0001;
+              break;
+            case 'v':
+              edit_mode_bttn.state=EMD_MOVE;
+              break;
+            case 'm':
+              edit_mode_bttn.state=EMD_MASS;
+              break;
+            case 'n':
+              edit_mode_bttn.state=EMD_CONNECTOR;
+              break;
+            case 's':
+              edit_mode_bttn.state=EMD_SPRING;
+              break;
+            case 't':
+              edit_mode_bttn.state=EMD_THRUSTER;
+              break;
+            case 'z':
+              Spawn(&Zoom,2.0(I64));
+              break;
+            case 'Z':
+              Spawn(&Zoom,0.5(I64));
+              break;
+            case CH_SPACE:
+              if (++main_mode_bttn.state==MMD_MODES_NUM)
+                main_mode_bttn.state=0;
+              GetMsg(,,1<<MSG_KEY_UP);
+              goto es_done;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              throw;
+          }
+          break;
+        case MSG_KEY_UP:
+          switch (arg1) {
+            case 'd':
+              ODEPause(ode);
+              ode->drag_v2=0.000002;
+              ode->drag_v3=0.0000001;
+              break;
+          }
+          break;
+      }
+      Refresh;
+    }
+es_done: //Don't goto out of try
+    okay=TRUE;
+  } catch {
+    Fs->catch_except=TRUE;
+    okay=FALSE;
+  }
+  MenuPop;
+  CtrlBttnDel(bt_edit_mode);
+  if (!okay)
+    throw;
+}
+
+U0 Strut()
+{
+  CCtrl *bt_main_mode;
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit|=WIF_SELF_MS_L|WIF_SELF_MS_R|WIG_DBL_CLICK;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  "\n$WW,1$$PURPLE$$TX+CX,\"Build a ship.\"$$FG$\n\n"
+        "Sel mass mode.\tLeft-click to place masses.\n"
+        "Sel spring mode.\tLeft-drag to make members.\n"
+        "Sel thruster mode.\tPress a digit, 0-9.  Drag to make thruster.\n"
+        "Sel connector mode.\tPress a digit, 0-9.  "
+        "Drag to make breakable connector.\n\n"
+        "Press $GREEN$<SPACE>$FG$ to run the game.  Press digits to operate "
+        "thrusters and break connectors.\n\n"
+        "Press $GREEN$<z>$FG$ or $GREEN$<SHIFT-Z>$FG$ to zoom in/out.\n\n";
+
+  PressAKey;
+  bt_main_mode=CtrlBttnNew(
+        (GR_WIDTH-4*FONT_WIDTH-16)>>1,1*FONT_HEIGHT+4,80,,MMD_MODES_NUM,
+        Define("ST_MAIN_MODES"),main_mode_colors,&main_mode_bttn);
+  DocClear;
+  Init;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      EditShip;
+      PlayShip;
+    }
+  } catch {
+    CleanUp;
+    Fs->catch_except=TRUE;
+  }
+  SettingsPop;
+  CtrlBttnDel(bt_main_mode);
+}
+
+ diff --git a/public/Wb/Apps/TimeClock/Install.HC.HTML b/public/Wb/Apps/TimeClock/Install.HC.HTML new file mode 100755 index 0000000..5600040 --- /dev/null +++ b/public/Wb/Apps/TimeClock/Install.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+if (!FileFind("~/TimeClock",,FUF_JUST_DIRS)) {
+  DirMk("~/TimeClock");
+  DocClear;
+  "After Loading, type $GREEN$PunchIn;$FG$, "
+  "$GREEN$PunchOut;$FG$ or $GREEN$TimeRep;$FG$\n"
+  "You might want to make PLUGINS for hot keys.\n\n\n";
+}
+
+
+ diff --git a/public/Wb/Apps/TimeClock/Load.HC.HTML b/public/Wb/Apps/TimeClock/Load.HC.HTML new file mode 100755 index 0000000..81a242f --- /dev/null +++ b/public/Wb/Apps/TimeClock/Load.HC.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+#help_index "Misc"
+
+Cd(__DIR__);;
+#include "TimeClk"
+#include "Install" //Might as well always install
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/TimeClock/TimeClk.HC.HTML b/public/Wb/Apps/TimeClock/TimeClk.HC.HTML new file mode 100755 index 0000000..e0d3d0f --- /dev/null +++ b/public/Wb/Apps/TimeClock/TimeClk.HC.HTML @@ -0,0 +1,182 @@ + + + + + + + + + + + +
+#define TIME_FILENAME   "~/TimeClock/TimeFile.DATA.Z"
+
+#define TET_EOF         0
+#define TET_PUNCH_IN    1
+#define TET_PUNCH_OUT   2
+
+class TimeEntry
+{
+  TimeEntry *next,*last;
+  U8 type;
+  CDate datetime;
+  U8 *desc;
+};
+
+U0 TimeFileRead(TimeEntry *header)
+{
+  U8 *buf,*ptr;
+  I64 type;
+  TimeEntry *tmpt;
+  buf=FileRead(TIME_FILENAME);
+  if (!buf)
+    buf=CAlloc(1);
+  QueInit(header);
+  ptr=buf;
+  while (type=*ptr++) {
+    tmpt=CAlloc(sizeof(TimeEntry));
+    tmpt->type=type;
+    tmpt->datetime=*ptr(CDate *)++;
+    tmpt->desc=StrNew(ptr);
+    ptr+=StrLen(ptr)+1;
+    QueIns(tmpt,header->last);
+  }
+  Free(buf);
+}
+
+U0 TimeFileWrite(TimeEntry *header)
+{
+  U8 *buf,*ptr;
+  TimeEntry *tmpt;
+  I64 size=1; //for EOF
+
+  tmpt=header->next;
+  while (tmpt!=header) {
+    size+=sizeof(U8)+sizeof(CDate)+StrLen(tmpt->desc)+1;
+    tmpt=tmpt->next;
+  }
+  buf=MAlloc(size);
+
+  ptr=buf;
+  tmpt=header->next;
+  while (tmpt!=header) {
+    *ptr++=tmpt->type;
+    *ptr(CDate *)++=tmpt->datetime;
+    StrCpy(ptr,tmpt->desc);
+    ptr+=StrLen(tmpt->desc)+1;
+    tmpt=tmpt->next;
+  }
+  *ptr=TET_EOF;
+  FileWrite(TIME_FILENAME,buf,size);
+  Free(buf);
+}
+
+U0 TimeEntriesDel(TimeEntry *header)
+{
+  TimeEntry *tmpt=header->next,*tmpt1;
+  while (tmpt!=header) {
+    tmpt1=tmpt->next;
+    Free(tmpt->desc);
+    Free(tmpt);
+    tmpt=tmpt1;
+  }
+  Free(header);
+}
+
+public Bool TimeRep(TimeEntry **_header=NULL)
+{
+  Bool is_in=FALSE,first=TRUE;
+  I64 week,cur_week=-1,week_total;
+  TimeEntry *tmpt,*header=MAlloc(sizeof(TimeEntry));
+  if (_header) *_header=header;
+  TimeFileRead(header);
+  tmpt=header->next;
+  while (tmpt!=header) {
+    week=tmpt->datetime.date/7;  //TODO
+    if (week!=cur_week) {
+      if (!first) {
+        if (is_in)
+          week_total+=Now;
+        "Week Total:%T\n",week_total-local_time_offset;
+      } else
+        first=FALSE;
+      cur_week=week;
+      week_total=0;
+    }
+    if (tmpt->type==TET_PUNCH_IN) {
+      "$RED$IN ";
+      if (!is_in)
+        week_total-=tmpt->datetime;
+      is_in=TRUE;
+    } else {
+      "$RED$OUT";
+      if (is_in)
+        week_total+=tmpt->datetime;
+      is_in=FALSE;
+    }
+    " %D %T:$FG$\n%s\n",tmpt->datetime,tmpt->datetime,tmpt->desc;
+    tmpt=tmpt->next;
+  }
+  if (is_in)
+    week_total+=Now;
+  "$RED$Week Total:%T$FG$\n",week_total-local_time_offset;
+  if (!_header)
+    TimeEntriesDel(header);
+  return is_in;
+}
+
+public U0 PunchOut()
+{
+  TimeEntry *tmpt,*header;
+  if (!TimeRep(&header))
+    "$BK,1$Already Punched-Out$BK,0$\n";
+  else {
+    tmpt=MAlloc(sizeof(TimeEntry));
+    tmpt->type=TET_PUNCH_OUT;
+    tmpt->datetime=Now;
+    "\nEnter Description.\nPress <ESC> when done.\n";
+    if (!(tmpt->desc=GetStr(,,GSF_WITH_NEW_LINE)))
+      tmpt->desc=CAlloc(1);
+    QueIns(tmpt,header->last);
+    TimeFileWrite(header);
+  }
+  TimeEntriesDel(header);
+}
+
+public U0 PunchIn()
+{
+  TimeEntry *tmpt,*header;
+  if (TimeRep(&header))
+    "$BK,1$Already Punched-In$BK,0$\n";
+  else {
+    tmpt=MAlloc(sizeof(TimeEntry));
+    tmpt->type=TET_PUNCH_IN;
+    tmpt->datetime=Now;
+    "\nEnter Description.\nPress <ESC> when done.\n";
+    if (!(tmpt->desc=GetStr(,,GSF_WITH_NEW_LINE)))
+      tmpt->desc=CAlloc(1);
+    QueIns(tmpt,header->last);
+    TimeFileWrite(header);
+  }
+  TimeEntriesDel(header);
+}
+
+ diff --git a/public/Wb/Apps/Titanium/Load.HC.HTML b/public/Wb/Apps/Titanium/Load.HC.HTML new file mode 100755 index 0000000..49f3987 --- /dev/null +++ b/public/Wb/Apps/Titanium/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "Titanium"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/Titanium/Run.HC.HTML b/public/Wb/Apps/Titanium/Run.HC.HTML new file mode 100755 index 0000000..8f59b4d --- /dev/null +++ b/public/Wb/Apps/Titanium/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Titanium;
+ diff --git a/public/Wb/Apps/Titanium/Titanium.HC.HTML b/public/Wb/Apps/Titanium/Titanium.HC.HTML new file mode 100755 index 0000000..461e0e9 --- /dev/null +++ b/public/Wb/Apps/Titanium/Titanium.HC.HTML @@ -0,0 +1,996 @@ + + + + + + + + + + + +
+RegDft("TempleOS/Titanium","I64 best_score=0;\n");
+RegExe("TempleOS/Titanium");
+
+#define MAP_HEIGHT      4096
+
+#define B_LEN   10
+#define B_SPEED 5
+#define B_NUM   128
+class Bullet
+{
+  I64 x,y,dx,dy,dx2,dy2;
+  Bool dead,missile,pad[6];
+} b[B_NUM];
+I64 bullets_fired,missile_bmp;
+
+I64 x,y,dx,dy,finish_line;
+F64 theta,t0,tf,snd_timeout;
+
+#define PHASES_GROUPS   8
+#define HACK_DIST       5
+
+#define U_ENEMY_NUM     (PHASES_GROUPS*64)
+#define U_FRIENDLY_NUM  (PHASES_GROUPS*16)
+#define U_NUM   (U_FRIENDLY_NUM+U_ENEMY_NUM)
+class Unit
+{
+  I64 x,y,best_dd;
+  F64 theta,phase;
+  Bool friendly,dead,tank,CIA,pad[4];
+} u[U_NUM];
+
+#define ET_MAN          0
+#define ET_TANK         1
+#define ET_MISSILE      2
+#define ET_BUILDING     3
+#define E_NUM           512
+class Explosion
+{
+  I64 x,y,num,type;
+  F64 t0,tf;
+  Bool dead,pad[7];
+} e[E_NUM];
+
+I64 total_score,friendly_fire,enemy_by_friendly,friendly_left,enemy_left,
+    main_loop_pass;
+Bool game_over;
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+
+
+U8 *friendly_imgs[4]={<5>,<4>,<5>,<6>};
+
+
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+        <8>/* Graphics Not Rendered in HTML */
+
+
+
+        <9>/* Graphics Not Rendered in HTML */
+
+
+
+U8 *CIA_neeger_imgs[4]={<8>,<7>,<8>,<9>};
+
+
+
+
+        <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <11>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <12>/* Graphics Not Rendered in HTML */
+
+
+
+
+U8 *friendly_hacking_imgs[4]={<10>,<11>,<10>,<12>};
+
+
+
+
+        <13>/* Graphics Not Rendered in HTML */
+
+
+
+        <14>/* Graphics Not Rendered in HTML */
+
+
+
+        <15>/* Graphics Not Rendered in HTML */
+
+
+
+U8 *enemy_imgs[4]={<14>,<13>,<14>,<15>};
+
+
+
+
+        <16>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <17>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <18>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+        <19>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+U8 *enemy_hacking_imgs[4]={<17>,<16>,<17>,<18>};
+
+
+
+
+
+
+
+        <20>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <21>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+        <22>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <23>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+#define LS_APTS_NUM             20
+#define LS_MOUNTAINS_NUM        3
+#define LS_NUM                  128
+class LandScapeItem
+{
+  I64 x,y;
+  U8 *img;
+} ls[LS_NUM];
+
+#define LS_TYPES        4
+U8 *landscape_imgs[LS_TYPES]=
+  {<20>,<21>,<22>,<23>};
+
+U0 ExplosionDraw(CDC *dc,Explosion *tmpe,I64 y)
+{
+  I64 i,n1,n2,n3,n4,n5;
+  F64 t=(tS-tmpe->t0)/(tmpe->tf-tmpe->t0);
+  Seed(tmpe->num+1);
+
+  switch (tmpe->type) {
+    case ET_MAN:        n1=8;   n2=0;  n3=0;  n4=18;  n5=28;    break;
+    case ET_TANK:       n1=64;  n2=14; n3=24; n4=60;  n5=90;    break;
+    case ET_MISSILE:    n1=128; n2=30; n3=60; n4=100; n5=200;   break;
+    case ET_BUILDING:   n1=128; n2=80; n3=80; n4=200; n5=300;   break;
+  }
+  for (i=0;i<n1;i++) {
+    if (i&2)
+      switch (tmpe->type) {
+        case ET_MAN:
+          if (i&1)
+            dc->color=WHITE;
+          else
+            dc->color=LTGRAY;
+          break;
+        case ET_MISSILE:
+          if (i&1) {
+            if (i&4)
+              dc->color=RED;
+            else
+              dc->color=DKGRAY;
+          } else
+            dc->color=YELLOW;
+          break;
+        case ET_TANK:
+          if (i&1) {
+            if (i&4)
+              dc->color=RED;
+            else
+              dc->color=DKGRAY;
+          } else
+            dc->color=LTRED;
+          break;
+        case ET_BUILDING:
+          if (i&1) {
+            if (i&4)
+              dc->color=BLACK;
+            else
+              dc->color=DKGRAY;
+          } else
+            dc->color=LTGRAY;
+          break;
+      }
+    else if (i&1)
+      dc->color=WHITE;
+    else
+      dc->color=LTGRAY;
+    GrLine(dc,tmpe->x+n2*(Rand-.5),y+n3/2*Rand,
+          tmpe->x+n4*t*(Rand-.5),y-n5/2*t*Rand);
+  }
+}
+
+I64 mp_not_done_flags;
+U0 MPMenDraw(CDC *dc2)
+{
+  CTask *task=dc2->win_task;
+  CDC *dc=DCAlias(dc2,task);
+  I64 i,r[16],lo=Gs->num*U_NUM/mp_cnt,hi=(Gs->num+1)*U_NUM/mp_cnt,
+        yy,phase,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
+  Unit *tmpu;
+  Explosion *tmpe;
+  U8 *tmps,**_tmps;
+  F64 tt,ts=tS;
+
+  for (i=Gs->num;i<E_NUM;i+=mp_cnt) {
+    tmpe=&e[i];
+    yy=(tmpe->y-scroll_y)&(MAP_HEIGHT-1);
+    if (-32<=yy<=task->pix_bottom+32 && !tmpe->dead) {
+      ExplosionDraw(dc,tmpe,yy);
+      if (tS>tmpe->tf)
+        tmpe->dead=TRUE;
+    }
+  }
+  for (i=lo;i<hi;i++) {
+    tmpu=&u[i];
+    yy=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
+    if (-32<=yy<=task->pix_bottom+32) {
+      if (!tmpu->dead) {
+        Mat4x4IdentEqu(r);
+        Mat4x4RotY(r,tmpu->theta);
+        Mat4x4RotX(r,pi/6);
+        Mat4x4Scale(r,0.3);
+        if (tmpu->tank)
+          Sprite3Mat4x4B(dc,tmpu->x,yy,GR_Z_ALL,<19>,r);
+        else {
+          if (tmpu->best_dd<(2*HACK_DIST)*(2*HACK_DIST)) {//It's neat so times 2
+            if (tmpu->friendly)
+              _tmps=friendly_hacking_imgs;
+            else
+              _tmps=enemy_hacking_imgs;
+            tt=4*Wrap(tmpu->phase+20*ts,0)/(2*pi);
+          } else {
+            if (tmpu->friendly) {
+              if (tmpu->CIA && Blink)
+                _tmps=CIA_neeger_imgs;
+              else
+                _tmps=friendly_imgs;
+            } else
+              _tmps=enemy_imgs;
+            tt=4*Wrap(tmpu->phase+5*ts,0)/(2*pi);
+          }
+          phase=tt; tt%=1.0;
+          tmps=SpriteInterpolate(tt,_tmps[phase&3],_tmps[(phase+1)&3]);
+          Sprite3Mat4x4B(dc,tmpu->x,yy,GR_Z_ALL,tmps,r);
+          Free(tmps);
+        }
+      }
+    }
+  }
+
+  dc->depth_buf=NULL;
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+  Seed; //Return Seth task to timer-based.
+}
+
+U0 MissilePos(I64 m,F64 theta,I64 *_x,I64 *_y)
+{
+  I64 n;
+  if (m<2)
+    n=-1;
+  else
+    n=1;
+  *_x=x+3.0*Cos(theta)-(15.0-(m&1)<<3)*Cos(theta-n*pi/2);
+  *_y=y+3.0*Sin(theta)-(15.0-(m&1)<<3)*Sin(theta-n*pi/2);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,m,xx,yy,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
+  F64 tt,ts=tS;
+  Bullet *tmpb;
+
+  dc->color=ROPF_DITHER|BROWN<<16|YELLOW;
+  GrRect3(dc,0,0,0,dc->width,dc->height);
+
+  for (i=0;i<LS_NUM;i++) {
+    yy=(ls[i].y-scroll_y)&(MAP_HEIGHT-1);
+    if (-32<=yy<=task->pix_bottom+32)
+      Sprite3(dc,ls[i].x,yy,0,ls[i].img);
+  }
+
+  dc->thick=3;
+  dc->color=BROWN;
+  GrLine3(dc,0,  (finish_line-scroll_y)&(MAP_HEIGHT-1),0,
+        GR_WIDTH,(finish_line-scroll_y)&(MAP_HEIGHT-1),0);
+
+  dc->color=LTGRAY;
+  for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
+    if (!tmpb->dead) {
+      if (tmpb->missile)
+        Sprite3ZB(dc,tmpb->x>>32,tmpb->y>>32,0,<2>,pi/2+Arg(tmpb->dx,tmpb->dy));
+      else
+        GrLine(dc,tmpb->x>>32,tmpb->y>>32,
+              (tmpb->x+tmpb->dy*B_LEN)>>32,
+              (tmpb->y+tmpb->dx*B_LEN)>>32);
+    }
+
+  DCDepthBufAlloc(dc);
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPMenDraw,dc,i);
+  while (mp_not_done_flags)
+    Yield;
+  Free(dc->depth_buf);
+  dc->depth_buf=NULL;
+
+  for (m=0;m<4;m++)
+    if (Bt(&missile_bmp,m)) {
+      MissilePos(m,theta,&xx,&yy);
+      Sprite3ZB(dc,xx,yy,0,<3>,theta);
+    }
+  Sprite3ZB(dc,x,y,0,<1>,theta);
+
+  if (tf) {
+    tt=tf;
+    dc->color=RED;
+    if (game_over && Blink)
+      GrPrint(dc,task->pix_width/2-9*FONT_WIDTH/2,task->pix_height/2,
+            "Game Over");
+  } else {
+    tt=ts;
+    if (!enemy_left || !friendly_left)
+      game_over=TRUE;
+  }
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Enemy:%d Friends:%d Friendly Fire:%d Time:%6.2f Bullets:%d",
+        enemy_left,friendly_left,friendly_fire,tt-t0,bullets_fired);
+  GrPrint(dc,0,8,"Total Score:%,d High Score:%,d",
+        total_score,best_score);
+}
+
+Explosion *ExplosionNew(I64 x,I64 y)
+{
+  I64 i;
+  for (i=0;i<E_NUM;i++)
+    if (e[i].dead) {
+      e[i].x=x;
+      e[i].y=y;
+      e[i].dead=FALSE;
+      return &e[i];
+    }
+  return NULL;
+}
+
+U0 ManDie(Unit *tmpu,Bool by_human)
+{
+  Explosion *tmpe;
+
+  tmpu->dead=TRUE;
+  if (by_human) {
+    if (tmpe=ExplosionNew(tmpu->x,tmpu->y)) {
+      tmpe->t0=tS;
+      if (tmpu->tank) {
+        tmpe->type=ET_TANK;
+        tmpe->tf=tmpe->t0+0.40;
+      } else {
+        tmpe->type=ET_MAN;
+        tmpe->tf=tmpe->t0+0.20;
+      }
+    }
+  }
+
+  if (tmpu->friendly) {
+    friendly_left--;
+    if (by_human)
+      friendly_fire++;
+  } else {
+    enemy_left--;
+    if (!by_human)
+      enemy_by_friendly++;
+  }
+  if (by_human && !snd_timeout) {
+    snd_timeout=tS+0.01;
+    if (tmpu->friendly)
+      Snd(46);
+    else
+      Snd(22);
+  }
+}
+
+U0 ExplosionDo(I64 x,I64 y,I64 scroll_y)
+{
+  I64 i,x2,y2;
+  Explosion *tmpe;
+  Unit *tmpu;
+  if (tmpe=ExplosionNew(x,y+scroll_y)) {
+    tmpe->t0=tS;
+    tmpe->type=ET_MISSILE;
+    tmpe->tf=tmpe->t0+1.0;
+  }
+  for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+    if (!tmpu->dead) {
+      x2=tmpu->x;
+      y2=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
+      if (SqrI64(x-x2)+SqrI64(y-y2)<100*100)
+        ManDie(tmpu,TRUE);
+    }
+  }
+  for (i=0;i<LS_APTS_NUM;i++) {
+    x2=ls[i].x;
+    y2=(ls[i].y-scroll_y)&(MAP_HEIGHT-1);
+    if (SqrI64(x-x2)+SqrI64(y-y2)<100*100) {
+      if (tmpe=ExplosionNew(x2,y2+scroll_y)) {
+        tmpe->t0=tS;
+        tmpe->type=ET_BUILDING;
+        tmpe->tf=tmpe->t0+2.0;
+      }
+    }
+  }
+}
+
+U0 CheckCollisions()
+{
+  I64 i,n1,x,y,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
+  Unit *tmpu;
+  Bullet *tmpb;
+  CDC   *dc2=DCNew(GR_WIDTH,GR_HEIGHT);
+  dc2->color=LTRED;
+  for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
+    if (!tmpb->dead && !tmpb->missile)  //Bullets not missiles
+      GrLine(dc2,tmpb->x>>32,tmpb->y>>32,
+            (tmpb->x+tmpb->dx*B_LEN)>>32,
+            (tmpb->y+tmpb->dy*B_LEN)>>32);
+
+  dc2->color  =ROP_COLLISION;
+  dc2->bkcolor=BLACK;
+  for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+    if (!tmpu->dead) {
+      x=tmpu->x;
+      y=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
+      if (0<=x<GR_WIDTH && 0<=y<GR_HEIGHT) {
+        dc2->collision_cnt=0;
+        GrRect(dc2,x-3,y-9,6,8);
+        if (dc2->collision_cnt)
+          ManDie(tmpu,TRUE);
+      }
+    }
+  }
+  DCDel(dc2);
+
+  for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
+    if (!tmpb->dead && tmpb->missile)  { //Missiles not bullets
+      x=tmpb->x>>32;
+      y=tmpb->y>>32;
+      for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+        if (tmpu->tank)
+          n1=16;
+        else
+          n1=6;
+        if (!tmpu->dead && AbsI64(x-tmpu->x-n1)+
+              AbsI64(y-(tmpu->y-scroll_y)&(MAP_HEIGHT-1)+n1)<n1<<1) {
+          tmpb->dead=TRUE;
+          ExplosionDo(x,y,scroll_y);
+        }
+      }
+      if (!tmpb->dead)
+        for (i=0;i<LS_APTS_NUM;i++)
+          if (2*SqrI64(x-ls[i].x)+
+                3*SqrI64(y+35-(ls[i].y-scroll_y)&(MAP_HEIGHT-1))<2*60*60) {
+            tmpb->dead=TRUE;
+            ExplosionDo(x,y,scroll_y);
+          }
+    }
+}
+
+U0 Init()
+{
+  I64 i,xx,yy,scroll_y=MAP_HEIGHT-100;
+  Unit *tmpu;
+
+  snd_timeout=0;
+  Snd;
+
+  total_score=0;
+  game_over=FALSE;
+  main_loop_pass=0;
+
+  x=Fs->pix_width>>1;
+  y=0.9*Fs->pix_height;
+  finish_line=scroll_y+y;
+  dx=0;
+  dy=0;
+  theta=-pi/2;
+
+  for (i=0;i<LS_NUM;i++) {
+    ls[i].x=(Fs->pix_width-100)*RandU32/U32_MAX+50;
+    ls[i].y=(MAP_HEIGHT-100)*RandU32/U32_MAX+50;
+    ls[i].img=landscape_imgs[RandU16%(LS_TYPES-2)];
+  }
+
+  for (i=0;i<LS_APTS_NUM;i++)
+    ls[i].img=landscape_imgs[LS_TYPES-1]; //Apartment
+
+  for (;i<LS_APTS_NUM+LS_MOUNTAINS_NUM;i++)
+    ls[i].img=landscape_imgs[LS_TYPES-2]; //mountain
+
+  MemSet(u,0,sizeof(u));
+  for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+    if (i<U_FRIENDLY_NUM) {
+      tmpu->friendly=TRUE;
+      if (!(i&7)) {
+        xx=(Fs->pix_width-200)*RandU32/U32_MAX;
+        yy=(MAP_HEIGHT-200)*RandU32/U32_MAX;
+      }
+      if (!(i&63))
+        tmpu->CIA=TRUE;
+      else
+        tmpu->CIA
+
+
+
+
+
+
+=FALSE;
+    } else {
+      tmpu->friendly=FALSE;
+      if (!(i&31)) {
+        xx=(Fs->pix_width-200)*RandU32/U32_MAX;
+        yy=(MAP_HEIGHT-200)*RandU32/U32_MAX;
+      }
+      if (!(i&15))
+        tmpu->tank=TRUE;
+    }
+    tmpu->dead=FALSE;
+    tmpu->x=xx+64*RandI32/I32_MAX+100;
+    tmpu->y=yy+64*RandU32/I32_MAX-64+100;
+    tmpu->best_dd=I64_MAX;
+    tmpu->theta=pi/2;
+    tmpu->phase=2*pi*Rand;
+  }
+  for (i=0;i<B_NUM;i++)
+    b[i].dead=TRUE;
+  for (i=0;i<E_NUM;i++) {
+    e[i].dead=TRUE;
+    e[i].num=i;
+  }
+  friendly_left=U_FRIENDLY_NUM;
+  enemy_left   =U_ENEMY_NUM;
+  enemy_by_friendly=0;
+  bullets_fired=0;
+  missile_bmp =15;
+  friendly_fire=0;
+  t0=tS;
+  tf=0;
+}
+
+U0 FireBullet()
+{
+  I64 i,j;
+  F64 a;
+  Bullet *tmpb;
+  for (i=0;i<B_NUM-1;i++)
+    if (b[i].dead)
+      break;
+  tmpb=&b[i];
+
+  j=x+28.0*Cos(theta);
+  tmpb->x=j<<32;
+  j=y+28.0*Sin(theta);
+  tmpb->y=j<<32;
+
+  tmpb->dx2=(B_SPEED*Cos(theta)+dx)*0x100000000;
+  tmpb->dy2= B_SPEED*Sin(theta)*0x100000000;
+  a=Arg(tmpb->dx2,tmpb->dy2);
+  tmpb->dx=Sin(a)*0x100000000;
+  tmpb->dy=Cos(a)*0x100000000;
+  bullets_fired++;
+  tmpb->dead=FALSE;
+  tmpb->missile=FALSE;
+  if (!snd_timeout) {
+    snd_timeout=tS+0.0005;
+    Snd(74);
+  }
+}
+
+Bool FireMissile(I64 n)
+{
+  I64 i,m;
+  F64 a;
+  Bullet *tmpb;
+  Bool res=FALSE;
+
+  m=n;
+  if (Btr(&missile_bmp,++m) || Btr(&missile_bmp,++m))
+    res=TRUE;
+
+  if (res) {
+    for (i=0;i<B_NUM-1;i++)
+      if (b[i].dead)
+        break;
+    tmpb=&b[i];
+
+    MissilePos(m,theta,&tmpb->x,&tmpb->y);
+    tmpb->x<<=32;
+    tmpb->y<<=32;
+
+    tmpb->dx2=(B_SPEED*Cos(theta)+dx)*0x100000000;
+    tmpb->dy2= B_SPEED*Sin(theta)*0x100000000;
+    a=Arg(tmpb->dx2,tmpb->dy2);
+    tmpb->dx=Sin(a)*0x100000000;
+    tmpb->dy=Cos(a)*0x100000000;
+    tmpb->dead=FALSE;
+    tmpb->missile=TRUE;
+    if (!snd_timeout) {
+      snd_timeout=tS+0.0005;
+      Snd(74);
+    }
+  }
+}
+
+U0 MenMove(I64 phase_group)
+{
+  I64 i,j,dd,best,best_dd;
+  for (i=phase_group;i<U_FRIENDLY_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=U_FRIENDLY_NUM;
+      best_dd=I64_MAX;
+      for (j=U_FRIENDLY_NUM;j<U_NUM;j++) {
+        if (!u[j].dead) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd!=I64_MAX) {
+        u[i].x+=4*SignI64(u[best].x-u[i].x);
+        u[i].y+=4*SignI64(u[best].y-u[i].y);
+        u[i].theta=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
+      }
+    }
+  }
+  for (i=U_FRIENDLY_NUM+phase_group;i<U_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=0;
+      best_dd=I64_MAX;
+      for (j=0;j<U_FRIENDLY_NUM;j++) {
+        if (!u[j].dead) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd!=I64_MAX) {
+        u[i].x+=4*SignI64(u[best].x-u[i].x);
+        u[i].y+=4*SignI64(u[best].y-u[i].y);
+        u[i].theta=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
+      }
+    }
+  }
+}
+
+U0 MenFight(I64 phase_group)
+{
+  I64 i,j,dd,best,best_dd;
+  for (i=phase_group;i<U_FRIENDLY_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=U_FRIENDLY_NUM;
+      best_dd=I64_MAX;
+      for (j=U_FRIENDLY_NUM;j<U_NUM;j++) {
+        if (!u[j].dead && u[i].y-u[j].y<8) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
+        ManDie(&u[best],FALSE);
+    }
+  }
+  for (i=U_FRIENDLY_NUM+phase_group;i<U_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=0;
+      best_dd=I64_MAX;
+      for (j=0;j<U_FRIENDLY_NUM;j++) {
+        if (!u[j].dead&& u[i].y-u[j].y<8) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
+        ManDie(&u[best],FALSE);
+    }
+  }
+}
+
+U0 Titanium()
+{
+  I64 i,msg_code,ch,sc;
+  Bool gun_on;
+
+  I64 next_update_jiffy;
+  SettingsPush; //See SettingsPush
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fire(,CH_SPACE);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  LeftMissile(,,SC_CURSOR_LEFT|SCF_CTRL);"
+        "  RightMissile(,,SC_CURSOR_RIGHT|SCF_CTRL);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  "\nScoring:\n"
+        "\tEnemy Killed\t\t+3\n"
+        "\tEnemy by Friendly\t+5\n"
+        "\tFriendly Fire\t\t-100\n"
+        "\tBullets Fired\t\t-1\n"
+        "\tGame Time\t\t-10 per second\n"
+        "\tSurviving Friendlies\t+250\n\n"
+        "Sweep side-to-side while shooting, "
+        "holding down $GREEN$<SPACE>$FG$.\n\n";
+  PressAKey;
+
+  Init;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+
+  gun_on=FALSE;
+
+  try {
+    while (TRUE) {
+      next_update_jiffy=cnts.jiffies+JIFFY_FREQ/100;
+      while (msg_code=ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN+1<<MSG_KEY_UP)) {
+        switch (msg_code) {
+          case MSG_KEY_DOWN:
+            switch (ch) {
+              case 0:
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    if (sc&SCF_CTRL)
+                      FireMissile(1);
+                    break;
+                  case SC_CURSOR_LEFT:
+                    if (sc&SCF_CTRL)
+                      FireMissile(-1);
+                    break;
+                }
+                break;
+              case CH_SHIFT_ESC:
+              case CH_ESC:
+                goto to_done;
+              case '\n':
+                Init;
+                break;
+              case CH_SPACE:
+                gun_on=TRUE;
+                break;
+            }
+            break;
+          case MSG_KEY_UP:
+            if (ch==CH_SPACE)
+              gun_on=FALSE;
+            else if (sc.u8[0]==SC_CURSOR_RIGHT||sc.u8[0]==SC_CURSOR_LEFT)
+              theta=-pi/2;
+            break;
+        }
+      }
+
+      for (i=0;i<B_NUM;i++) {
+        if (!b[i].dead) {
+          b[i].x+=b[i].dx2;
+          b[i].y+=b[i].dy2;
+          if (b[i].y<0||b[i].x<0||
+                b[i].x>>32>=Fs->pix_width||
+                b[i].y>>32>=Fs->pix_height)
+            b[i].dead=TRUE;
+        }
+      }
+
+      dx=0;
+      if (!Bt(kbd.down_bitmap,SC_CTRL)) {
+        if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+          theta=-pi/2-15.0*pi/180.0;
+          dx=-2;
+        } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+          theta=-pi/2+15.0*pi/180.0;
+          dx=2;
+        }
+      }
+      x+=dx;
+      while (x>=Fs->pix_width)
+        x-=Fs->pix_width;
+      while (x<0)
+        x+=Fs->pix_width;
+
+        //It takes too much CPU do do all these all the time.
+      switch [main_loop_pass&7] {
+        case 0:
+          switch [main_loop_pass>>3&7] {
+            case 0:
+              if (--y<20)
+                game_over=TRUE;
+            case 2:
+            case 4:
+            case 6:
+              MenFight(main_loop_pass>>4%PHASES_GROUPS);
+              break;
+            case 1:
+            case 3:
+            case 5:
+            case 7:
+              MenMove (main_loop_pass>>4%PHASES_GROUPS);
+              break;
+          }
+        case 4:
+          break;
+        case 2:
+        case 6:
+          if (gun_on)
+            FireBullet;
+          break;
+        case 1:
+        case 3:
+        case 5:
+        case 7:
+          CheckCollisions;
+          break;
+      }
+      main_loop_pass++;
+
+      if (snd_timeout && tS>snd_timeout) {
+        snd_timeout=0;
+        Snd;
+      }
+      SleepUntil(next_update_jiffy);
+
+      total_score=3*(U_ENEMY_NUM-enemy_left)+5*enemy_by_friendly
+            -100*friendly_fire-10*(tS-t0)-bullets_fired;
+      if (game_over) {
+        tf=tS;
+        Sleep(750);
+        FlushMsgs;
+        while (!ScanKey(&ch)&&friendly_left||tS-tf<1.5) {
+          total_score+=250;
+          Snd(86); Sleep(150);
+          Snd;    Sleep(50);
+          friendly_left--;
+        }
+        total_score+=250*friendly_left;
+        if (total_score>best_score)
+          best_score=total_score;
+        if (!ch) ch=GetChar(,FALSE);
+        if (ch==CH_ESC||ch==CH_SHIFT_ESC)
+          goto to_done;
+        gun_on=FALSE;
+        Init;
+      }
+    }
+to_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  }
+  catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/Titanium","I64 best_score=%d;\n",best_score);
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/AIs/Human.HC.HTML b/public/Wb/Apps/ToTheFront/AIs/Human.HC.HTML new file mode 100755 index 0000000..de9d1cb --- /dev/null +++ b/public/Wb/Apps/ToTheFront/AIs/Human.HC.HTML @@ -0,0 +1,197 @@ + + + + + + + + + + + +
+U0 PlayerIndirect()
+{
+  Unit *tmpu=NULL;
+  I64 i,remaining=0,msg_code,arg1,arg2;
+  F64 target_x,target_y;
+  ViewPlayerSet(cur_player);
+  for (i=0;i<UNITS_NUM;i++) {
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0 && tmpu->indirect_fire)
+      remaining++;
+  }
+  while (remaining) {
+    if (!alive_cnt[0] || !alive_cnt[1])
+      throw('GameOver',TRUE);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        CharDo(arg1);
+        break;
+      case MSG_MS_L_DOWN:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (tmpu=UnitFind(cursor_row,cursor_col)) {
+            if (tmpu->player==enemy_player || tmpu->fired ||
+                  !tmpu->indirect_fire)
+              tmpu=NULL;
+            else {
+              RowCol2XY(&fire_radius_x,&fire_radius_y,tmpu->row,tmpu->col);
+              fire_radius=tmpu->range*2*HEX_RADIUS;
+            }
+          }
+        }
+        break;
+      case MSG_MS_L_UP:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          RowCol2XY(&target_x,&target_y,cursor_row,cursor_col);
+          if (!tmpu)
+            Beep;
+          else {
+            if (Sqrt(Sqr(fire_radius_x-target_x)+Sqr(fire_radius_y-target_y))>
+                  fire_radius)
+              Beep;
+            else {
+              IndirectAdd(tmpu,cursor_row,cursor_col);
+              remaining--;
+            }
+          }
+        }
+        tmpu=NULL;
+        fire_radius=0;
+        break;
+      case MSG_MS_R_UP:
+        if (CursorInWin(Fs,arg1,arg2))
+          throw('PhaseOvr',TRUE);
+        break;
+    }
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+U0 PlayerMove()
+{
+  Unit *tmpu=NULL;
+  I64 msg_code,arg1,arg2;
+  ViewPlayerSet(cur_player);
+  while (TRUE) {
+    if (!alive_cnt[0] || !alive_cnt[1])
+      throw('GameOver',TRUE);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        CharDo(arg1);
+        break;
+      case MSG_MS_L_DOWN:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (tmpu=UnitFind(cursor_row,cursor_col)) {
+            if (tmpu->player==enemy_player || !tmpu->remaining_movement)
+              tmpu=NULL;
+          }
+        }
+        break;
+      case MSG_MS_L_UP:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (!tmpu)
+            Beep;
+          else {
+            UnitMove(tmpu,arg1,arg2);
+            break;
+          }
+        }
+        tmpu=NULL;
+        break;
+      case MSG_MS_R_UP:
+        if (CursorInWin(Fs,arg1,arg2))
+          throw('PhaseOvr',TRUE);
+        break;
+    }
+  }
+}
+
+U0 PlayerDirect()
+{
+  Unit *tmpu=NULL,*target;
+  I64 msg_code,arg1,arg2;
+  ViewPlayerSet(cur_player);
+  while (TRUE) {
+    if (!alive_cnt[0] || !alive_cnt[1])
+      throw('GameOver',TRUE);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        CharDo(arg1);
+        break;
+      case MSG_MS_L_DOWN:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (tmpu=UnitFind(cursor_row,cursor_col)) {
+            if (tmpu->player==enemy_player || tmpu->fired ||
+                  tmpu->indirect_fire)
+              tmpu=NULL;
+            else {
+              VRSetUp(cur_player);
+              RowCol2XY(&fire_radius_x,&fire_radius_y,tmpu->row,tmpu->col);
+              fire_radius=tmpu->range*2*HEX_RADIUS;
+              VisRecalc(VR_ONE_FRIENDLY_UNIT,tmpu);
+            }
+          }
+        }
+        break;
+      case MSG_MS_L_UP:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          target=UnitFind(cursor_row,cursor_col);
+          if (!tmpu)
+            Beep;
+          else {
+            if (!target || target->player!=enemy_player ||
+                  !Bt(&target->vis,0))
+              Beep;
+            else
+              UnitDirectFire(tmpu,target);
+            VisRecalc(VR_UPDATE_FRIENDLY_UNIT,tmpu);
+          }
+        }
+        tmpu=NULL;
+        fire_radius=0;
+        break;
+      case MSG_MS_R_UP:
+        if (CursorInWin(Fs,arg1,arg2))
+          throw('PhaseOvr',TRUE);
+        break;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/AIs/SimpleAI.HC.HTML b/public/Wb/Apps/ToTheFront/AIs/SimpleAI.HC.HTML new file mode 100755 index 0000000..fad3384 --- /dev/null +++ b/public/Wb/Apps/ToTheFront/AIs/SimpleAI.HC.HTML @@ -0,0 +1,110 @@ + + + + + + + + + + + +
+Unit *UnitNearestFind(I64 row,I64 col,I64 player,Bool in_LOS,F64 range=-1)
+{
+  I64 i;
+  F64 dd,best_dd=F64_MAX,x1,y1,x2,y2;
+  Unit *best=NULL;
+//Sqrt() is slow, so work with squared distances.
+  if (range<0)
+    range=F64_MAX;
+  else
+    range*=range;
+  RowCol2XY(&x1,&y1,row,col);
+  for (i=0;i<UNITS_NUM;i++)
+    if (units[player][i].life>0) {
+      if (!in_LOS || LOS(row,col,units[player][i].row,units[player][i].col)) {
+        RowCol2XY(&x2,&y2,units[player][i].row,units[player][i].col);
+        dd=Sqr(x2-x1)+Sqr(y2-y1);
+        if (dd<=range && dd<best_dd) {
+          best=&units[player][i];
+          best_dd=dd;
+        }
+      }
+    }
+  return best;
+}
+
+U0 PlayerIndirect()
+{
+  Unit *target,*tmpu;
+  I64 i;
+  for (i=0;i<UNITS_NUM;i++) {
+    UserChk;
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0 && tmpu->indirect_fire &&
+          (target=UnitNearestFind(tmpu->row,tmpu->col,enemy_player,TRUE,
+          tmpu->range*2*HEX_RADIUS)))
+      IndirectAdd(tmpu,target->row,target->col);
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+U0 PlayerMove()
+{
+  Unit *target,*tmpu;
+  I64 i;
+  F64 x,y;
+  for (i=0;i<UNITS_NUM;i++) {
+    UserChk;
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0) {
+//Cheats because it violates Line-of-Sight
+      if (target=UnitNearestFind(tmpu->row,tmpu->col,enemy_player,FALSE)) {
+        RowCol2XY(&x,&y,target->row,target->col);
+        if (!UnitMove(tmpu,x,y)) {
+          RowCol2XY(&x,&y,tmpu->row,tmpu->col);
+          UnitMove(tmpu,x+RandI16,y+RandI16);
+        }
+      }
+    }
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+U0 PlayerDirect()
+{
+  Unit *target,*tmpu;
+  I64 i;
+  for (i=0;i<UNITS_NUM;i++) {
+    UserChk;
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0 && !tmpu->indirect_fire &&
+          (target=UnitNearestFind(tmpu->row,tmpu->col,enemy_player,TRUE,
+          tmpu->range*2*HEX_RADIUS))) {
+      UnitDirectFire(tmpu,target);
+      Sleep(250*animation_delay);
+    }
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+
+ diff --git a/public/Wb/Apps/ToTheFront/Install.HC.HTML b/public/Wb/Apps/ToTheFront/Install.HC.HTML new file mode 100755 index 0000000..061d29a --- /dev/null +++ b/public/Wb/Apps/ToTheFront/Install.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+DirMk("~/ToTheFront");
+
+
+ diff --git a/public/Wb/Apps/ToTheFront/Load.HC.HTML b/public/Wb/Apps/ToTheFront/Load.HC.HTML new file mode 100755 index 0000000..4f61c33 --- /dev/null +++ b/public/Wb/Apps/ToTheFront/Load.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "TTFGlbls"
+#include "TTFLib"
+#include "TTFInit"
+#include "TTFVis"
+#include "TTFFire"
+#include "TTFMove"
+#include "TTFDraw"
+#include "ToTheFront"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/ToTheFront/Run.HC.HTML b/public/Wb/Apps/ToTheFront/Run.HC.HTML new file mode 100755 index 0000000..d5240cf --- /dev/null +++ b/public/Wb/Apps/ToTheFront/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+ToTheFront;
+ diff --git a/public/Wb/Apps/ToTheFront/TTFDraw.HC.HTML b/public/Wb/Apps/ToTheFront/TTFDraw.HC.HTML new file mode 100755 index 0000000..ce35e29 --- /dev/null +++ b/public/Wb/Apps/ToTheFront/TTFDraw.HC.HTML @@ -0,0 +1,243 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+U0 UnitDraw(CDC *dc,Unit *tmpu,I64 x,I64 y,F64 f)
+{
+  x+=x0; y+=y0;
+  if (tmpu->infantry)
+    Sprite3(dc,x,y,0,tmpu->img);
+  else
+    Sprite3ZB(dc,x,y,0,tmpu->img,f);
+  if (phase&~1==PHASE_INDIRECT && tmpu->indirect_fire &&
+        !tmpu->fired && tmpu->player==cur_player) {
+    dc->thick=2;
+    if (cur_player)
+      dc->color=PURPLE;
+    else
+      dc->color=CYAN;
+    GrCircle3(dc,x,y,0,20*Saw(4*tS,2.0));
+    GrCircle3(dc,x,y,0,20*Saw(4*tS+1.0,2.0));
+    dc->thick=1;
+  }
+}
+
+U0 UnitsDraw(CDC *dc)
+{
+  I64 i,j;
+  F64 x,y;
+  Unit *tmpu;
+  for (j=0;j<2;j++) {
+    for (i=0;i<UNITS_NUM;i++) {
+      tmpu=&units[j][i];
+      if (tmpu==target_unit) {
+        if (target_hit)
+          dc->color=RED;
+        else
+          dc->color=GREEN;
+      } else {
+        if (j)
+          dc->color=LTPURPLE;
+        else
+          dc->color=LTCYAN;
+      }
+      if (tmpu->life>0 && Bt(&tmpu->vis[view_player],0) &&
+            tmpu!=moving_unit) {
+        RowCol2XY(&x,&y,tmpu->row,tmpu->col);
+        if (phase&~1==PHASE_MOVE && tmpu->remaining_movement ||
+              (phase&~1==PHASE_INDIRECT&& tmpu->indirect_fire||
+              phase&~1==PHASE_DIRECT&&!tmpu->indirect_fire) && !tmpu->fired ||
+              Blink(5))
+          UnitDraw(dc,tmpu,x,y,tmpu->facing*60.0*pi/180.0);
+      }
+    }
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 x,y;
+  I64 i,j,r,c;
+  U8 buf[STR_LEN];
+  IndirectOrders *tmpi;
+
+  //Erase text beneath.
+  dc->color=WHITE;
+  GrRect(dc,-task->scroll_x,-task->scroll_y,dc->width,dc->height);
+
+  map_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,x0,y0,map_dc);
+
+  i=ms.pos.x-task->pix_left-task->scroll_x;
+  j=ms.pos.y-task->pix_top -task->scroll_y;
+  if (CursorInWin(task,i,j)) {
+    i-=x0; j-=y0;
+    CursorUpdate(task,i,j);
+  }
+  RowCol2XY(&x,&y,cursor_row,cursor_col);
+
+  //Roads require multiple cursor fills
+  dc->color=YELLOW;
+  c=terrain[cursor_row][cursor_col];
+  for (i=-(HEX_SIDE+DCOS)/2;i<=(HEX_SIDE+DCOS)/2;i++) {
+    if (GrPeek(dc,x+i+x0,y+y0)==c)
+      GrFloodFill(dc,x+i+x0,y+y0);
+    for (j=-HEX_SIDE/2;j<=HEX_SIDE/2;j++)
+      if (GrPeek(dc,x+j+x0,y+i+y0)==c)
+        GrFloodFill(dc,x+j+x0,y+i+y0);
+  }
+
+  UnitsDraw(dc);
+  if (firing) {
+    dc->color=BLACK;
+    GrCircle(dc,fire_x+x0,fire_y+y0,2);
+  }
+  if (indirect_explosion) {
+    for (i=0;i<7;i++) {
+      if (indirect_row&1)
+        c=indirect_col+col_offsets_odd[i];
+      else
+        c=indirect_col+col_offsets_even[i];
+      r=indirect_row+row_offsets[i];
+      if (0<=r<map_rows && 0<=c<map_cols) {
+        RowCol2XY(&x,&y,r,c);
+        for (j=0;j<10;j++)  {
+          if (j&1)
+            dc->color=LTRED;
+          else
+            dc->color=YELLOW;
+          GrCircle(dc,x+RandU16%HEX_SIDE-HEX_SIDE/2+x0,
+                y+RandU16%HEX_SIDE-HEX_SIDE/2+y0,2);
+        }
+      }
+    }
+  }
+  if (moving_unit && moving_unit->vis[view_player]) {
+    dc->color=YELLOW;
+    UnitDraw(dc,moving_unit,move_x,move_y,move_facing);
+  }
+  ProgressBarsRst;
+  if (moving_unit) {
+    if (ms.pos.y<GR_HEIGHT/2) {
+      progress4_max=moving_unit->movement;
+      progress4=moving_unit->remaining_movement;
+    } else {
+      progress1_max=moving_unit->movement;
+      progress1=moving_unit->remaining_movement;
+    }
+  }
+  if (fire_radius) {
+    dc->color=YELLOW;
+    GrCircle(dc,fire_radius_x+x0,fire_radius_y+y0,fire_radius-1);
+    GrCircle(dc,fire_radius_x+x0,fire_radius_y+y0,fire_radius+1);
+    dc->color=RED;
+    GrCircle(dc,fire_radius_x+x0,fire_radius_y+y0,fire_radius);
+  }
+  if (Blink(10)) {
+    tmpi=indirect_head.next;
+    while (tmpi!=&indirect_head) {
+      if (tmpi->attacker->player==view_player) {
+        RowCol2XY(&x,&y,tmpi->row,tmpi->col);
+        Sprite3(dc,x+x0,y+y0,0,<1>);
+      }
+      tmpi=tmpi->next;
+    }
+  }
+  if (Bt(kbd.down_bitmap,SC_SHIFT)) {
+    if (show_vis_row!=cursor_row || show_vis_col!=cursor_col) {
+      show_vis_row=cursor_row;
+      show_vis_col=cursor_col;
+      VisRecalcMap(show_vis_row,show_vis_col);
+    }
+
+    dc->color=LTGRAY;
+    for (j=0;j<map_rows;j++)
+      for (i=0;i<map_cols;i++)
+        if (!vis_map[j][i]) {
+          RowCol2XY(&x,&y,j,i);
+          GrLine(dc,x-6+x0,y-6+y0,x+6+x0,y+6+y0);
+          GrLine(dc,x+6+x0,y-6+y0,x-6+x0,y+6+y0);
+          GrLine(dc,x+x0,y-6+y0,x+x0,y+6+y0);
+          GrLine(dc,x+6+x0,y+y0,x-6+x0,y+y0);
+        }
+  }
+  if (i=StrLen(msg_buf)*FONT_WIDTH) {
+    dc->color=BLACK;
+    GrRect(dc,(task->pix_width-i)>>1-10-task->scroll_x,
+          (task->pix_height-FONT_HEIGHT)>>1-10-task->scroll_y,
+          i+20,FONT_HEIGHT+20);
+
+    dc->color=YELLOW;
+    GrRect(dc,(task->pix_width-i)>>1-7-task->scroll_x,
+          (task->pix_height-FONT_HEIGHT)>>1-7-task->scroll_y,
+          i+14,FONT_HEIGHT+14);
+
+    dc->color=RED;
+    GrPrint(dc,(task->pix_width-i)>>1-task->scroll_x,
+          (task->pix_height-FONT_HEIGHT)>>1-task->scroll_y,
+          msg_buf);
+    if (msg_off_timeout) {
+      if (msg_off_timeout-cnts.jiffies<3*JIFFY_FREQ/2*animation_delay)
+        Snd;
+      if (cnts.jiffies>msg_off_timeout)
+        *msg_buf=0;
+    }
+  }
+
+  dc->color=WHITE;
+  GrRect(dc,-task->scroll_x,-task->scroll_y,
+        (13+7+10+10)*FONT_WIDTH,FONT_HEIGHT);
+
+  if (phase&~1==PHASE_INDIRECT)
+    StrPrint(buf,"Turn:%2d Artillery",turn);
+  else if (phase&~1==PHASE_MOVE)
+    StrPrint(buf,"Turn:%2d Move",turn);
+  else
+    StrPrint(buf,"Turn:%2d Fire",turn);
+  dc->color=BLACK;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y,buf);
+
+  StrPrint(buf,"%3d Units",alive_cnt[0]);
+  if (cur_player || Blink)
+    dc->color=CYAN;
+  else
+    dc->color=LTCYAN;
+  GrPrint(dc,-task->scroll_x+(13+7)*FONT_WIDTH,-task->scroll_y,buf);
+
+  StrPrint(buf,"%3d Units",alive_cnt[1]);
+  if (!cur_player || Blink)
+    dc->color=PURPLE;
+  else
+    dc->color=LTPURPLE;
+  GrPrint(dc,-task->scroll_x+(13+7+10)*FONT_WIDTH,-task->scroll_y,buf);
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/TTFFire.HC.HTML b/public/Wb/Apps/ToTheFront/TTFFire.HC.HTML new file mode 100755 index 0000000..34dd67d --- /dev/null +++ b/public/Wb/Apps/ToTheFront/TTFFire.HC.HTML @@ -0,0 +1,309 @@ + + + + + + + + + + + +
+U0 AttackHeader(Unit *tmpu,U8 *st,Unit *target)
+{
+  I64 i=9+StrLen(st);
+  if (target) {
+    i+=9;
+    if (target->armor)
+      i+=8;
+    else
+      i+=10;
+  }
+  '\n\n';
+  "$BLACK$%h*c$FG$\n",i,'-';
+  if (tmpu->player)
+    "$PURPLE$Player 2$FG$ ";
+  else
+    "$CYAN$Player 1$FG$ ";
+  "%s",st;
+  if (target) {
+    if (target->player)
+      " $PURPLE$Player 2";
+    else
+      " $CYAN$Player 1";
+    if (target->armor)
+      " Armored";
+    else
+      " Unarmored";
+    '$FG$';
+  }
+  '\n';
+  "$BLACK$%h*c$FG$\n",i,'-';
+}
+
+F64 HitDamage(Unit *tmpu,Unit *target,I64 facing=1,F64 range_factor=0)
+{
+  F64 d,res=200.0*Rand;
+  "\nRoll Out of 200\t\t:%6.2f Damage\n",res;
+  if (target->armor) {
+    d=target->armor/100.0*(5-facing)/5.0;
+    if (d>=0) {
+      "Armor Attack\t\t:%6.2f\n",ToF64(tmpu->armored_attack);
+      res*=(tmpu->armored_attack/100.0)/d;
+    } else
+      res=0;
+    "Armor(%z) Defense\t:%6.2f\n",facing,
+          "Front\0FrontSide\0RearSide\0Rear\0",100*d;
+  } else {
+    d=1.0-range_factor;
+    if (d>0) {
+      "Unarmored Attack\t:%6.2f\n",ToF64(tmpu->unarmored_attack);
+      "Range Adjust\t\t:%6.2f%%\n",100*d;
+      res*=(tmpu->unarmored_attack/100.0)*d;
+    } else
+      res=0;
+  }
+  "Attack/Defense Adjusted\t:%6.2f Damage\n",res;
+  return Round(res);
+}
+
+Bool DamageDo(Unit *target,F64 damage)
+{
+  if (damage>0) {
+    if (target->armor)
+      "Armor Hit Score %6.2f\t:",damage;
+    else
+      "%3d Life - %3f Damage\t=",target->life,damage;
+    if (damage>=target->life) {
+      "$RED$Killed$FG$\n";
+      Noise(1000*animation_delay,74,98);
+      Sleep(1000*animation_delay);
+      target->life=0;
+      VisRecalc(VR_FRIENDLY_UNIT_DIED,target);
+      alive_cnt[target->player]--;
+      return TRUE;
+    } else {
+      if (target->armor) {
+        if (damage>0.6*target->life) {
+          target->movement=0;
+          "$RED$Immobilized$FG$\n";
+        } else
+          "$GREEN$No Penetration$FG$\n";
+      } else {
+        target->life-=damage;
+        "$RED$%6.2f Life$FG$\n",ToF64(target->life);
+      }
+      return FALSE;
+    }
+  } else
+    return FALSE;
+}
+
+U0 IndirectAdd(Unit *tmpu,I64 row,I64 col)
+{
+  IndirectOrders *tmpi;
+  if (tmpu->life<=0 || tmpu->range<=0)
+    return;
+  tmpu->fired=TRUE;
+  tmpi=CAlloc(sizeof(IndirectOrders));
+  tmpi->attacker=tmpu;
+  tmpi->row=row;
+  tmpi->col=col;
+  QueIns(tmpi,indirect_head.last);
+}
+
+Bool BulletPlot(U0,I64 x,I64 y,I64)
+{
+  fire_x=x; fire_y=y;
+  firing=TRUE;
+  Sleep(3*animation_delay);
+  return TRUE;
+}
+
+U0 UnitDirectFire(Unit *tmpu,Unit *target)
+{
+  I64 r,c,facing,
+        t1=terrain[tmpu->row][tmpu->col],t2=terrain[target->row][target->col];
+  F64 x1,y1,x2,y2,d,a,range_factor;
+  if (tmpu->life<=0 || target->life<=0 || tmpu->range<=0)
+    return;
+  AttackHeader(tmpu,"DirectFire",target);
+  RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
+  RowCol2XY(&x2,&y2,target->row,target->col);
+  d=100*Rand;
+  "+%5.2f  Roll\n",d;
+  d+=tmpu->accuracy;
+  "+%2d.00  Accuracy\n",tmpu->accuracy;
+
+  range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);
+  "-%5.2f%% of Range\n",100*range_factor;
+  d-=100*range_factor;
+  if (t2==TREES) {
+    "-30.00  Target in Trees Penalty\n";
+    d-=30;
+  }
+  if (t1==MOUNTAINS && t2!=MOUNTAINS) {
+    "+30.00  High Ground Bonus\n";
+    d+=30;
+  }
+  "_______\n";
+  target_unit=target;
+  if (d>=0) {
+    "+%5.2f  Hit\n",d;
+    target_hit=TRUE;
+    Noise(500*animation_delay,34,41);
+    Sleep(500*animation_delay);
+    Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);
+  } else {
+    "-%5.2f  Miss\n",-d;
+    target_hit=FALSE;
+    Noise(1000*animation_delay,69,74);
+    Sleep(1000*animation_delay);
+    a=pi*2*Rand;
+    d=(0.5-d/100)*HEX_SIDE;
+    Line(NULL,x1,y1,0,x2+d*Cos(a),y2+d*Sin(a),0,&BulletPlot);
+  }
+  firing=FALSE;
+  tmpu->fired=TRUE;
+  if (target_hit) {
+    r=target->row;c=target->col;
+    if ((facing=HexMoveOne(&r,&c,x1,y1))>=0)
+      facing=FacingChg(facing,target->facing);
+    else
+      facing=0;
+    DamageDo(target,HitDamage(tmpu,target,facing,range_factor));
+  }
+  while (scrncast.ona) //see Snd()
+    Yield;
+  target_unit=NULL;
+}
+
+Bool HexOccupy(Bool overrun,Unit *tmpu,Unit *target)
+{
+  I64 t2=terrain[target->row][target->col];
+  F64 damage;
+  if (tmpu->life<=0 || target->life<=0)
+    return FALSE;
+  if (overrun)
+    AttackHeader(tmpu,"OverRun",target);
+  else
+    AttackHeader(tmpu,"CloseAssault",target);
+  Noise(500*animation_delay,34,41);
+  Sleep(500*animation_delay);
+  tmpu->fired=TRUE;
+  target->fired=TRUE;
+  damage=HitDamage(tmpu,target);
+  if (overrun) {
+    damage*=2.0;
+    "x2 OverRun Bonus\t=%6.2f Damage\n",damage;
+    if (t2!=PLAINS) {
+      damage/=2.0;
+      "/2 Terrain Penalty\t=%6.2f Damage\n",damage;
+    }
+  } else {
+    damage*=3.0;
+    "x3 CloseAssault Bonus\t=%6.2f Damage\n",damage;
+  }
+  if (DamageDo(target,Round(damage))) {
+    "$RED$Success$FG$\n";
+    while (scrncast.ona) //see Snd()
+      Yield;
+    return TRUE;
+  } else {
+    tmpu->life=0;
+    VisRecalc(VR_FRIENDLY_UNIT_DIED,tmpu);
+    alive_cnt[tmpu->player]--;
+    "$RED$Failure$FG$\n";
+    while (scrncast.ona) //see Snd()
+      Yield;
+    return FALSE;
+  }
+}
+
+U0 IndirectResolveAll()
+{
+  I64 i,r,c;
+  F64 x1,y1,x2,y2,d,range_factor;
+  Unit *tmpu,*target;
+  IndirectOrders *tmpi=indirect_head.next,*tmpi1;
+  while (tmpi!=*indirect_head) {
+    tmpi1=tmpi->next;
+    tmpu=tmpi->attacker;
+    AttackHeader(tmpu,"IndirectFire",NULL);
+    RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
+    RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);
+    d=100*Rand;
+    "+%5.2f  Roll\n",d;
+    d+=tmpu->accuracy;
+    "+%2d.00  Accuracy\n",tmpu->accuracy;
+    range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);
+    "-%5.2f%% of Range\n",100*range_factor;
+    d-=100*range_factor;
+    '_______\n';
+
+
+    if (d>=0) {
+      "+%5.2f  Hit\n",d;
+      Noise(500*animation_delay,34,41);
+      Sleep(500*animation_delay);
+    } else {
+      "-%5.2f  Miss\n",-d;
+      Noise(1000*animation_delay,69,74);
+      Sleep(1000*animation_delay);
+      i=RandU16%6;
+      if (tmpi->row&1)
+        tmpi->col+=col_offsets_odd[i];
+      else
+        tmpi->col+=col_offsets_even[i];
+      tmpi->row+=row_offsets[i];
+      RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);
+    }
+
+    Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);
+    firing=FALSE;
+    tmpu->fired=TRUE;
+    indirect_row=tmpi->row;
+    indirect_col=tmpi->col;
+    indirect_explosion=TRUE;
+    for (i=0;i<7;i++) {
+      if (tmpi->row&1)
+        c=tmpi->col+col_offsets_odd[i];
+      else
+        c=tmpi->col+col_offsets_even[i];
+      r=tmpi->row+row_offsets[i];
+      if (0<=r<map_rows && 0<=c<map_cols && (target=UnitFind(r,c))) {
+        AttackHeader(tmpu,"IndirectFire",target);
+        DamageDo(target,HitDamage(tmpu,target));
+      }
+    }
+    Noise(2000*animation_delay,70,74);
+    Sleep(2000*animation_delay);
+    while (scrncast.ona) //see Snd()
+      Yield;
+    indirect_explosion=FALSE;
+
+    QueRem(tmpi);
+    Free(tmpi);
+    tmpi=tmpi1;
+  }
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/TTFGlbls.HC.HTML b/public/Wb/Apps/ToTheFront/TTFGlbls.HC.HTML new file mode 100755 index 0000000..dfaf2b7 --- /dev/null +++ b/public/Wb/Apps/ToTheFront/TTFGlbls.HC.HTML @@ -0,0 +1,139 @@ + + + + + + + + + + + +
+#define MAP_WIDTH               640     //Change this, if you like.
+#define UNITS_NUM               32      //Change this, if you like.
+#define HEX_SIDE                11
+
+U0 InitDefines()
+{
+  DefinePrint("MAP_HEIGHT","%d",(GR_HEIGHT-FONT_HEIGHT*2)*MAP_WIDTH/GR_WIDTH);
+  DefinePrint("DCOS",      "%12.9f",    HEX_SIDE*Cos(60.0/180*pi));
+  DefinePrint("DSIN",      "%12.9f",    HEX_SIDE*Sin(60.0/180*pi));
+  DefinePrint("HEX_RADIUS","%12.9f",    HEX_SIDE*Sin(60.0/180*pi)+0.01); //Slop
+} InitDefines;
+
+I64     map_cols=(MAP_WIDTH-DCOS)/(2*HEX_SIDE+2*DCOS),
+        map_rows=ToI64((MAP_HEIGHT-DSIN)/DSIN)&~1,
+        map_width=map_cols*(2*HEX_SIDE+2*DCOS)+DCOS,
+        map_height=map_rows*DSIN+DSIN+1,
+        x0,y0;
+
+CDC     *map_dc;
+U8      terrain[map_rows][map_cols];
+
+//Centers of hexes
+class Pt
+{
+  F64 x,y;
+};
+Pt      hex_centers[map_rows][map_cols];
+
+I64     show_vis_row,show_vis_col;
+Bool    roads[map_rows][map_cols],
+        rivers[map_rows][map_cols],
+        vis_map[map_rows][map_cols];
+
+//Other options for PLAINS are WHITE or YELLOW
+#define PLAINS          LTGREEN
+#define TREES           GREEN
+#define MOUNTAINS       DKGRAY
+
+//These are used to display a range circle when they player
+//is firing.
+F64     fire_radius,fire_radius_x,fire_radius_y;
+
+//These display "phase", "turn" and "game over".
+U8      msg_buf[STR_LEN];
+I64     msg_off_timeout; //Jiffies. Goes away after a time.
+
+//Unit types
+#define UT_INFANTRY     0
+#define UT_ARTILLERY    1
+#define UT_LT_TANK      2
+#define UT_MD_TANK      3
+
+class Unit
+{
+  U8    *img;
+  I64   num,row,col,
+        armored_attack,unarmored_attack,armor;
+  I8    type,player,facing,movement,life,
+        range,remaining_movement,accuracy;
+  Bool  vis[2],fired,infantry,indirect_fire,pad[3];
+};
+
+Unit    units[2][UNITS_NUM];
+
+// Bt(vis_unit_bitmap,player1+player0*((UNITS_NUM+7)&~7))
+U8      vis_unit_bitmap[2][(((UNITS_NUM+7)&~7)*UNITS_NUM)>>3];
+
+#define PHASE_START     0
+#define PHASE_INDIRECT  0
+#define PHASE_INDIRECT0 0
+#define PHASE_INDIRECT1 1
+#define PHASE_MOVE      2
+#define PHASE_MOVE0     2
+#define PHASE_MOVE1     3
+#define PHASE_DIRECT    4
+#define PHASE_DIRECT0   4
+#define PHASE_DIRECT1   5
+#define PHASE_END       6
+
+I64     phase,cur_player,enemy_player,view_player,turn,
+        cursor_row,cursor_col,alive_cnt[2],
+        player_indirect[2],player_move[2],player_direct[2];
+F64     animation_delay=0.5;
+
+Bool    moving=FALSE;
+I64     move_x,move_y;
+F64     move_facing;
+Unit    *moving_unit;
+extern I64 HexMoveOne(I64 *_row,I64 *_col,F64 x,F64 y);
+
+class IndirectOrders
+{
+  IndirectOrders *next,*last;
+  Unit  *attacker;
+  I64   row,col;
+} indirect_head;
+
+Bool    firing=FALSE;
+I64     fire_x,fire_y;
+Unit    *target_unit;
+Bool    target_hit;
+
+Bool    indirect_explosion=FALSE;
+I64     indirect_row,indirect_col;
+
+I64     row_offsets[7]={-1,-2,-1,1,2,1,0};
+I64     col_offsets_even[7]={-1, 0, 0,0,0,-1,0};
+I64     col_offsets_odd [7]={ 0, 0, 1,1,0, 0,0};
+
+ diff --git a/public/Wb/Apps/ToTheFront/TTFInit.HC.HTML b/public/Wb/Apps/ToTheFront/TTFInit.HC.HTML new file mode 100755 index 0000000..14a171c --- /dev/null +++ b/public/Wb/Apps/ToTheFront/TTFInit.HC.HTML @@ -0,0 +1,445 @@ + + + + + + + + + + + +
+/*I got tricky by not defining a color
+right away in these CSprites so they can
+work for both players by setting dc->color
+before drawing them.  I actually made these
+graphics by defining a color in the <CTRL-r>
+menu, drawing the unit and deleting the color.
+
+I had to leave a gap between the tank tread
+and body because of how it is rendered when rotated.
+*/
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+//This is an infantry.
+
+<3>/* Graphics Not Rendered in HTML */
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+U0 DrawHexes()
+{
+  F64 dx=2*HEX_SIDE+2*DCOS,dy=2*DSIN,
+        x,y,x1,y1,x2,y2;
+  I64 i,j;
+  map_dc->color=WHITE;
+  GrRect(map_dc,0,0,map_dc->width,map_dc->height);
+  map_dc->color=BLACK;
+  y=0;
+  for (j=0;j<map_rows;j+=2) {
+    x=DCOS;
+    GrLine(map_dc,x,y,x-DCOS,y+DSIN);
+    GrLine(map_dc,x-DCOS,y+DSIN,x,y+2*DSIN);
+    for (i=0;i<map_cols;i++) {
+      x1=x; y1=y;
+      x2=x1+HEX_SIDE; y2=y1;
+      GrLine(map_dc,x1,y1,x2,y2);
+      x1=x2; y1=y2;
+      x2+=DCOS; y2+=DSIN;
+      GrLine(map_dc,x1,y1,x2,y2);
+      GrLine(map_dc,x2,y2,x2-DCOS,y2+DSIN);
+      x1=x2; y1=y2;
+      x2+=HEX_SIDE;
+      GrLine(map_dc,x1,y1,x2,y2);
+      GrLine(map_dc,x2,y2,x2+DCOS,y2+DSIN);
+      x1=x2; y1=y2;
+      x2+=DCOS; y2-=DSIN;
+      if (j || i<map_cols-1)
+        GrLine(map_dc,x1,y1,x2,y2);
+      x+=dx;
+    }
+    y+=dy;
+  }
+  x=DCOS;
+  for (i=0;i<map_cols;i++) {
+    x1=x; y1=y;
+    x2=x1+HEX_SIDE; y2=y1;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x1=x2; y1=y2;
+    x2+=DCOS; y2+=DSIN;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x1=x2; y1=y2;
+    x2+=HEX_SIDE;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x1=x2; y1=y2;
+    x2+=DCOS; y2-=DSIN;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x+=dx;
+  }
+}
+
+U0 MakeTerrain(U8 color,I64 cnt,I64 clus_lo,I64 clus_hi)
+{
+  I64 i,j,l,row,col;
+  for (i=0;i<cnt;i++) {
+    col=RandU32%map_cols;
+    row=RandU32%map_rows;
+    l=clus_lo+RandU16%(clus_hi-clus_lo+1);
+    for (j=0;j<l;j++) {
+      terrain[row][col]=color;
+      Toward(&row,&col,RandU16%6);
+      col=ClampI64(col,0,map_cols-1);
+      row=ClampI64(row,0,map_rows-1);
+    }
+  }
+}
+
+U0 MakeRivers()
+{
+  I64 i,row,col,direction;
+  for (i=0;i<4;i++) {
+    row=RandU32%map_rows;
+    col=RandU32%map_cols;
+    direction=RandU16%6;
+    while (TRUE) {
+      rivers[row][col]=TRUE;
+      Toward(&row,&col,direction);
+      if (!(0<=row<map_rows && 0<=col<map_cols))
+        break;
+      if (!(RandU16&3))
+        direction=(direction+(7-RandU16%3))%6;
+    }
+  }
+}
+
+U0 MakeRoads()
+{
+  I64 i,row,col,direction;
+  for (i=0;i<5;i++) {
+    row=RandU32%map_rows;
+    col=RandU32%map_cols;
+    direction=RandU16%6;
+    while (TRUE) {
+      roads[row][col]=TRUE;
+      Toward(&row,&col,direction);
+      if (!(0<=row<map_rows && 0<=col<map_cols))
+        break;
+      if (!(RandU16%3))
+        direction=(direction+(7-RandU16%3))%6;
+    }
+  }
+}
+
+U0 DrawTerrain()
+{
+  I64 i,j;
+  F64 x,y;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      map_dc->color=terrain[j][i];
+      RowCol2XY(&x,&y,j,i);
+      GrFloodFill(map_dc,x,y);
+    }
+}
+
+U0 DrawRivers()
+{
+  I64 i,j,k,r,c;
+  F64 x1,y1,x2,y2;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      if (rivers[j][i]) {
+        RowCol2XY(&x1,&y1,j,i);
+        for (k=0;k<6;k++) {
+          r=j;c=i;
+          Toward(&r,&c,k);
+          if (0<=r<map_rows && 0<=c<map_cols &&
+                rivers[r][c]) {
+            RowCol2XY(&x2,&y2,r,c);
+            map_dc->color=LTBLUE;
+            map_dc->thick=4;
+            GrLine3(map_dc,x1,y1,0,x2,y2,0);
+            map_dc->color=BLUE;
+            map_dc->thick=2;
+            GrLine3(map_dc,x1,y1,0,x2,y2,0);
+          }
+        }
+      }
+    }
+}
+
+U0 DrawRoads()
+{
+  I64 i,j,k,r,c;
+  F64 x1,y1,x2,y2;
+  map_dc->color=RED;
+  map_dc->thick=3;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      if (roads[j][i]) {
+        RowCol2XY(&x1,&y1,j,i);
+        for (k=0;k<6;k++) {
+          r=j;c=i;
+          Toward(&r,&c,k);
+          if (0<=r<map_rows && 0<=c<map_cols &&
+                roads[r][c]) {
+            RowCol2XY(&x2,&y2,r,c);
+            GrLine3(map_dc,x1,y1,0,x2,y2,0);
+          }
+        }
+      }
+    }
+}
+
+U0 DrawDots()
+{
+  I64 i,j;
+  F64 x,y;
+  map_dc->color=BLACK;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      RowCol2XY(&x,&y,j,i);
+      GrPlot(map_dc,x,y);
+    }
+}
+
+U0 HexCentersCalc()
+{
+  I64 i,j;
+  F64 x,y;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      x=(2*HEX_SIDE+2*DCOS)*i+HEX_SIDE/2+DCOS;
+      if (j&1)
+        x+=HEX_SIDE+DCOS;
+      y=DSIN*(j+1);
+      hex_centers[j][i].x=x;
+      hex_centers[j][i].y=y;
+    }
+}
+
+U0 InitMap()
+{
+  HexCentersCalc;
+  DrawHexes;
+  MemSet(terrain,PLAINS,sizeof(terrain));
+  MemSet(roads,FALSE,sizeof(roads));
+  MemSet(rivers,FALSE,sizeof(rivers));
+  MemSet(vis_map,FALSE,sizeof(vis_map));
+  MakeTerrain(MOUNTAINS,0.03*map_cols*map_cols,5,35);
+  MakeTerrain(TREES,0.03*map_cols*map_cols,5,35);
+  DrawTerrain;
+  MakeRivers;
+  DrawRivers;
+  MakeRoads;
+  DrawRoads;
+  DrawDots;
+}
+
+U0 InitUnits()
+{
+  I64 i,j,row,col,type;
+  Unit *tmpu;
+  MemSet(units,0,sizeof(units));
+  alive_cnt[0]=alive_cnt[1]=UNITS_NUM;
+  for (j=0;j<2;j++)
+    for (i=0;i<alive_cnt[j];i++) {
+      tmpu=&units[j][i];
+      tmpu->player=j;
+      tmpu->num=i;
+      tmpu->life=100;
+      tmpu->facing=RandU16%6;
+      if (!j) {
+        if (i>=UNITS_NUM/2) {
+          if (i>=15*UNITS_NUM/16)
+            type=UT_ARTILLERY;
+          else
+            type=UT_INFANTRY;
+        } else {
+          if (i>=UNITS_NUM/4)
+            type=UT_MD_TANK;
+          else
+            type=UT_LT_TANK;
+        }
+      } else {
+        if (i>=UNITS_NUM/2) {
+          if (i>=15*UNITS_NUM/16)
+            type=UT_ARTILLERY;
+          else
+            type=UT_INFANTRY;
+        } else {
+          if (i>=UNITS_NUM/4)
+            type=UT_MD_TANK;
+          else
+            type=UT_LT_TANK;
+        }
+      }
+      tmpu->type=type;
+      switch (type) {
+        case UT_INFANTRY:
+          tmpu->infantry=TRUE;
+          tmpu->indirect_fire=FALSE;
+          tmpu->armor    =0;
+          tmpu->armored_attack  =15;
+          tmpu->unarmored_attack=180;
+          tmpu->accuracy=45;
+          tmpu->range    =5;
+          tmpu->movement=4;
+          tmpu->img      =<1>;
+          break;
+        case UT_ARTILLERY:
+          tmpu->infantry=TRUE;
+          tmpu->indirect_fire=TRUE;
+          tmpu->armor    =0;
+          tmpu->armored_attack  =60;
+          tmpu->unarmored_attack=180;
+          tmpu->accuracy=25;
+          tmpu->range    =20;
+          tmpu->movement=2;
+          tmpu->img      =<2>;
+          break;
+        case UT_LT_TANK:
+          tmpu->infantry=FALSE;
+          tmpu->indirect_fire=FALSE;
+          tmpu->armor    =30;
+          tmpu->armored_attack  =40;
+          tmpu->unarmored_attack=60;
+          tmpu->accuracy=25;
+          tmpu->range    =8;
+          tmpu->movement=24;
+          tmpu->img      =<3>;
+          break;
+        case UT_MD_TANK:
+          tmpu->infantry=FALSE;
+          tmpu->indirect_fire=FALSE;
+          tmpu->armor    =60;
+          tmpu->armored_attack  =60;
+          tmpu->unarmored_attack=80;
+          tmpu->accuracy=25;
+          tmpu->range    =12;
+          tmpu->movement=16;
+          tmpu->img      =<4>;
+          break;
+      }
+      do {
+        row=RandU32%map_rows;
+        col=RandU32%(map_cols/3);
+        if (j)
+          col+=2*map_cols/3;
+      } while (UnitFind(row,col));
+      tmpu->row=row;
+      tmpu->col=col;
+      LBts(&tmpu->vis[cur_player],0);
+    }
+}
+
+U0 ViewPlayerSet(I8 p)
+{
+  CMenuEntry *tmpse;
+  view_player=p;
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Player1"))
+    tmpse->checked= view_player==0;
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Player2"))
+    tmpse->checked= view_player==1;
+}
+
+U0 Init()
+{
+  DocClear;
+  "GameSeed(0x%X)\n",Seed(PopUpGetI64("GameSeed(0x%X):",Seed));
+  moving_unit=NULL;
+  InitMap;
+  ViewPlayerSet(cur_player=0);
+  enemy_player=1;
+  if (map_width<GR_WIDTH) {
+    x0=(MAP_WIDTH-map_width)>>1;
+    y0=(MAP_HEIGHT-map_height)>>1+FONT_HEIGHT;
+  } else {
+    x0=0;
+    y0=FONT_HEIGHT;
+  }
+  InitUnits;
+  QueInit(&indirect_head);
+  turn=0;
+  fire_radius=0;
+  show_vis_row=-1;
+  show_vis_col=-1;
+  *msg_buf=0;
+  msg_off_timeout=0;
+  phase=PHASE_END;
+}
+
+U0 CleanUp()
+{
+  QueDel(&indirect_head,TRUE);
+}
+
+U0 PlayerPick(U8 *dirname,I64 player)
+{
+  I64 i=0;
+  U8 *st;
+  CDirEntry *tmpde,*tmpde1,*tmpde2;
+  CDoc *doc=DocNew;
+  Bool *old_silent=Silent;
+  st=MStrPrint("%s/*.HC*",dirname);
+  tmpde=FilesFind(st);
+  Free(st);
+  tmpde2=FilesFind("~/ToTheFront/*.HC*");
+  tmpde1=tmpde;
+  Silent(old_silent);
+
+  DocPrint(doc,"Player %d Type\n\n$LTBLUE$",player+1);
+  while (tmpde1) {
+    if (!(i++&3))
+      DocPrint(doc,"\n");
+    st=StrNew(tmpde1->name);
+    FileExtRem(st);
+    tmpde1->user_data=DocPrint(doc,"$MU-UL,\"%-10ts\",LE=%d$ ",st,tmpde1);
+    Free(st);
+    tmpde1=tmpde1->next;
+  }
+  tmpde1=tmpde2;
+  while (tmpde1) {
+    if (!(i++&3))
+      DocPrint(doc,"\n");
+    st=StrNew(tmpde1->name);
+    FileExtRem(st);
+    tmpde1->user_data=DocPrint(doc,"$MU-UL,\"%-10ts\",LE=%d$ ",st,tmpde1);
+    Free(st);
+    tmpde1=tmpde1->next;
+  }
+  DocPrint(doc,"\n\n\n$FG$Create your own AI in ~/ToTheFront.");
+  while ((tmpde1=PopUpMenu(doc))<=0);
+  ExeFile(tmpde1->full_name);
+  DocDel(doc);
+  DirTreeDel(tmpde);
+  DirTreeDel(tmpde2);
+  ExePrint("player_indirect[%d]=&PlayerIndirect;"
+        "player_move[%d]=&PlayerMove;"
+        "player_direct[%d]=&PlayerDirect;",
+        player,player,player);
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/TTFLib.HC.HTML b/public/Wb/Apps/ToTheFront/TTFLib.HC.HTML new file mode 100755 index 0000000..7b93698 --- /dev/null +++ b/public/Wb/Apps/ToTheFront/TTFLib.HC.HTML @@ -0,0 +1,152 @@ + + + + + + + + + + + +
+U0 Toward(I64 *_row,I64 *_col,I64 direction)
+{
+  switch (direction) {
+    case 0:
+      *_row-=2;
+      break;
+    case 1:
+      if (*_row&1) *_col+=1;
+      *_row-=1;
+      break;
+    case 2:
+      if (*_row&1) *_col+=1;
+      *_row+=1;
+      break;
+    case 3:
+      *_row+=2;
+      break;
+    case 4:
+      if (!(*_row&1)) *_col-=1;
+      *_row+=1;
+      break;
+    case 5:
+      if (!(*_row&1)) *_col-=1;
+      *_row-=1;
+      break;
+  }
+}
+
+I64 FacingChg(I64 f1,I64 f2)
+{
+  I64 res=(f1+6-f2)%6;
+  if (res>=3)
+    return 6-res;
+  else
+    return res;
+}
+
+U0 RowCol2XY(F64 *_x,F64 *_y,I64 row,I64 col)
+{
+  Pt *c;
+  row=ClampI64(row,0,map_rows);
+  col=ClampI64(col,0,map_cols);
+  c=&hex_centers[row][col];
+  *_x=c->x;
+  *_y=c->y;
+}
+
+U0 XY2RowCol(I64 *_row,I64 *_col,F64 x,F64 y)
+{
+  *_col=(x-DCOS/2)/(HEX_SIDE+DCOS);
+  if (*_col&1)
+    *_row=ToI64((y-DSIN)/(2*DSIN))*2+1;
+  else
+    *_row=ToI64(y/(2*DSIN))*2;
+  *_col>>=1;
+  *_row=ClampI64(*_row,0,map_rows-1);
+  *_col=ClampI64(*_col,0,map_cols-1);
+}
+
+Unit *UnitFind(I64 row,I64 col)
+{//Finds unit in a hexagon.
+  I64 i,j;
+  for (j=0;j<2;j++)
+    for (i=0;i<UNITS_NUM;i++)
+      if (units[j][i].life>0 &&
+            units[j][i].row==row &&
+            units[j][i].col==col)
+        return &units[j][i];
+  return NULL;
+}
+
+Bool CursorInWin(CTask *task,I64 x,I64 y)
+{
+  if (0<=x+task->scroll_x<task->pix_width &&
+        0<=y+task->scroll_y<task->pix_height)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 CursorUpdate(CTask *task,I64 x,I64 y)
+{
+  if (CursorInWin(task,x,y))
+    XY2RowCol(&cursor_row,&cursor_col,x,y);
+}
+
+class LOSCtrl
+{
+  I64 r1,c1,r2,c2,distance;
+};
+
+Bool LOSPlot(LOSCtrl *l,I64 x,I64 y,I64 z)
+{//We got tricky and used z as the distance from the start of the line.
+  I64 row,col;
+  XY2RowCol(&row,&col,x,y);
+  if ((row!=l->r1 || col!=l->c1) &&
+        (row!=l->r2 || col!=l->c2) &&
+        terrain[row][col]!=PLAINS) {
+    if (terrain[l->r1][l->c1]==MOUNTAINS) {
+      if (terrain[row][col]==MOUNTAINS || z>l->distance>>1)
+        return FALSE;
+    } else if (terrain[l->r2][l->c2]==MOUNTAINS) {
+      if (terrain[row][col]==MOUNTAINS || z<=l->distance>>1)
+        return FALSE;
+    } else
+      return FALSE;
+  }
+  return TRUE;
+}
+
+Bool LOS(I64 r1,I64 c1,I64 r2,I64 c2)
+{
+  F64 x1,y1,x2,y2;
+  LOSCtrl l;
+  RowCol2XY(&x1,&y1,r1,c1);
+  RowCol2XY(&x2,&y2,r2,c2);
+  l.r1=r1; l.c1=c1;
+  l.r2=r2; l.c2=c2;
+  l.distance=Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2));
+  return Line(&l,x1,y1,0,x2,y2,l.distance,&LOSPlot);
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/TTFMove.HC.HTML b/public/Wb/Apps/ToTheFront/TTFMove.HC.HTML new file mode 100755 index 0000000..e7cc87b --- /dev/null +++ b/public/Wb/Apps/ToTheFront/TTFMove.HC.HTML @@ -0,0 +1,160 @@ + + + + + + + + + + + +
+U8 movement_costs[16];
+movement_costs[PLAINS]=2;
+movement_costs[TREES]=6;
+movement_costs[MOUNTAINS]=10;
+
+I64 HexMoveOneCost(Unit *tmpu,I64 r,I64 c,I64 facing)
+{
+  I64 res;
+  if (tmpu->infantry)
+    res=0;
+  else {
+    res=FacingChg(facing,tmpu->facing);
+    if (res>0) res--;
+  }
+  if (roads[r][c] && roads[tmpu->row][tmpu->col])
+    res+=1;
+  else {
+    if (tmpu->infantry)
+      res+=2;
+    else {
+      res+=movement_costs[terrain[r][c]];
+      if (rivers[r][c])
+        res=tmpu->movement;
+    }
+  }
+  return res;
+}
+
+I64 HexMoveOne(I64 *_row,I64 *_col,F64 x,F64 y)
+{
+  I64 direction,best_direction=-1,r,c;
+  F64 dd,best_dd,x1,y1;
+  RowCol2XY(&x1,&y1,*_row,*_col);
+  best_dd=Sqr(x1-x)+Sqr(y1-y);
+  for (direction=0;direction<6;direction++) {
+    r=*_row; c=*_col;
+    Toward(&r,&c,direction);
+    RowCol2XY(&x1,&y1,r,c);
+    dd=Sqr(x1-x)+Sqr(y1-y);
+    if (0<=r<map_rows && 0<=c<map_cols && dd<best_dd) {
+      best_dd=dd;
+      best_direction=direction;
+    }
+  }
+  if (best_direction>=0) {
+    Toward(_row,_col,best_direction);
+    return best_direction;
+  } else
+    return -1;
+}
+
+Bool UnitMovePlot(U0,I64 x,I64 y,I64)
+{
+  move_x=x; move_y=y;
+  Sleep(5*animation_delay);
+  return TRUE;
+}
+
+U0 UnitMoveAnimation(Unit *tmpu,I64 r,I64 c,I64 facing)
+{
+  F64 x1,y1,x2,y2,f=facing*60.0*pi/180.0;
+  moving_unit=tmpu;
+  RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
+  move_x=x1; move_y=y1;
+  moving=TRUE;
+  if (tmpu->infantry)
+    Snd(53);
+  else {
+    move_facing=tmpu->facing*60.0*pi/180.0;
+    Snd(41);
+    while (Wrap(f-move_facing,-pi)<=0) {
+      move_facing-=0.03;
+      Sleep(5*animation_delay);
+    }
+    while (Wrap(f-move_facing,-pi)>0) {
+      move_facing+=0.03;
+      Sleep(5*animation_delay);
+    }
+    Snd(34);
+  }
+  move_facing=f;
+  RowCol2XY(&x2,&y2,r,c);
+  Line(NULL,x1,y1,0,x2,y2,0,&UnitMovePlot);
+  Snd;
+  moving_unit=NULL;
+  moving=FALSE;
+}
+ 
+Bool UnitMove(Unit *tmpu,I64 x,I64 y)
+{
+  Unit *target;
+  I64 r,c,r0=tmpu->row,c0=tmpu->col,i,facing;
+  while (tmpu->remaining_movement>0) {
+    r=tmpu->row;
+    c=tmpu->col;
+    if ((facing=HexMoveOne(&r,&c,x,y))<0)
+      break;
+    else {
+      i=HexMoveOneCost(tmpu,r,c,facing);
+      if (i>tmpu->movement)
+        i=tmpu->movement;
+      if (!tmpu->fired && tmpu->remaining_movement>=i &&
+            tmpu->remaining_movement>=tmpu->movement>>1 &&
+            (target=UnitFind(r,c)) && target->player!=tmpu->player &&
+            tmpu->infantry!=target->infantry) {
+        if (!HexOccupy(ToBool(target->infantry),tmpu,target)) {
+          tmpu=NULL;
+          break;
+        }
+        i=tmpu->remaining_movement;
+      }
+      if (tmpu->remaining_movement>=i && !UnitFind(r,c)) {
+        UnitMoveAnimation(tmpu,r,c,facing);
+        tmpu->facing=facing;
+        tmpu->remaining_movement-=i;
+        tmpu->row=r;
+        tmpu->col=c;
+        VisRecalc(VR_UPDATE_FRIENDLY_UNIT,tmpu);
+        LBEqu(&tmpu->vis[enemy_player],0,
+              VisRecalc(VR_ONE_ENEMY_UNIT,tmpu));
+      } else
+        break;
+    }
+  }
+  if (!tmpu || tmpu->row!=r0 || tmpu->col!=c0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/TTFVis.HC.HTML b/public/Wb/Apps/ToTheFront/TTFVis.HC.HTML new file mode 100755 index 0000000..8fc4e7c --- /dev/null +++ b/public/Wb/Apps/ToTheFront/TTFVis.HC.HTML @@ -0,0 +1,254 @@ + + + + + + + + + + + +
+#define VR_ONE_FRIENDLY_UNIT    0
+#define VR_UPDATE_FRIENDLY_UNIT 1
+#define VR_FRIENDLY_UNIT_DIED   3
+#define VR_ONE_ENEMY_UNIT       4
+#define VR_ALL_UNITS            5
+
+class MPCtrl1
+{
+  I64 mode,lo,hi;
+  Unit *tmpu;
+};
+
+class MPCtrl2
+{
+  I64 lo,hi,row,col;
+};
+
+
+U0 VRSetUp(I64 player)
+{
+  I64 i;
+  Unit *ut0,*ut1;
+  ut0=&units[player][0];
+  ut1=&units[player^1][0];
+  for (i=0;i<UNITS_NUM;i++,ut0++,ut1++) {
+    LBtr(&ut1->vis[player],0);
+    LBEqu(&ut0->vis[player],0,ut0->life>0);
+  }
+}
+
+U0 VRMerge(I64 player)
+{
+  I64 i,j;
+  Unit *ut1;
+  U8 *dst,*src,*mask=CAlloc((UNITS_NUM+7)>>3);
+  for (j=0;j<UNITS_NUM;j++) {//p0
+    src=&vis_unit_bitmap[player][(((UNITS_NUM+7)&~7)*j)>>3];
+    dst=mask;
+    for (i=0;i<(UNITS_NUM+7)>>3;i++) //player1
+      *dst++|=*src++;
+  }
+  ut1=&units[player^1][0];
+  for (j=0;j<UNITS_NUM;j++,ut1++)
+    LBEqu(&ut1->vis[player],0,Bt(mask,j) && ut1->life>0);
+  Free(mask);
+}
+
+Bool MPVisRecalc(MPCtrl1 *job)
+{
+  Bool res=FALSE,seen;
+  I64 i,j,row,col;
+  F64 x1,y1,x2,y2,dd,range;
+  Unit *ut0,*ut1;
+  ut0=&units[cur_player][job->lo];
+  ut1=&units[enemy_player][job->lo];
+  if (job->tmpu) {
+    row=job->tmpu->row;
+    col=job->tmpu->col;
+    range=job->tmpu->range*2*HEX_RADIUS;
+    range*=range;
+  }
+  switch (job->mode) {
+    case VR_UPDATE_FRIENDLY_UNIT:
+    case VR_ONE_FRIENDLY_UNIT:
+      if (job->mode==VR_UPDATE_FRIENDLY_UNIT)
+        range=F64_MAX;
+      RowCol2XY(&x1,&y1,row,col);
+      for (i=job->lo;i<job->hi;i++,ut1++) {
+        seen=FALSE;
+        if (ut1->life>0 &&
+              LOS(row,col,ut1->row,ut1->col)) {
+          RowCol2XY(&x2,&y2,ut1->row,ut1->col);
+          dd=Sqr(x2-x1)+Sqr(y2-y1);
+          if (dd<range) {
+            seen=TRUE;
+            LBts(&ut1->vis[cur_player],0);
+          }
+        }
+        if (job->mode==VR_UPDATE_FRIENDLY_UNIT)
+          LBEqu(&vis_unit_bitmap[cur_player],
+                i+job->tmpu->num*((UNITS_NUM+7)&~7),seen);
+      }
+      break;
+    case VR_ONE_ENEMY_UNIT:
+      RowCol2XY(&x1,&y1,row,col);
+      for (i=job->lo;i<job->hi;i++,ut1++)
+        if (ut1->life>0 &&
+              LOS(row,col,ut1->row,ut1->col)) {
+          LBts(&vis_unit_bitmap[enemy_player],
+                job->tmpu->num+i*((UNITS_NUM+7)&~7));
+          res=TRUE;
+        } else
+          LBtr(&vis_unit_bitmap[enemy_player],
+                job->tmpu->num+i*((UNITS_NUM+7)&~7));
+      break;
+    case VR_ALL_UNITS:
+      ut0=&units[cur_player][0];
+      for (i=0;i<UNITS_NUM;i++,ut0++)
+        if (ut0->life>0) {
+          RowCol2XY(&x1,&y1,ut0->row,ut0->col);
+          ut1=&units[enemy_player][job->lo];
+          for (j=job->lo;j<job->hi;j++,ut1++) {
+            if (ut1->life>0 &&
+                  LOS(ut0->row,ut0->col,ut1->row,ut1->col)) {
+              LBts(&ut1->vis[cur_player],0);
+              LBts(&vis_unit_bitmap[cur_player],j+i*((UNITS_NUM+7)&~7));
+            } else
+              LBtr(&vis_unit_bitmap[cur_player],j+i*((UNITS_NUM+7)&~7));
+          }
+        } else
+          for (j=job->lo;j<job->hi;j++)
+            LBtr(&vis_unit_bitmap[cur_player],j+i*((UNITS_NUM+7)&~7));
+      ut0=&units[enemy_player][0];
+      for (i=0;i<UNITS_NUM;i++,ut0++)
+        if (ut0->life>0) {
+          RowCol2XY(&x1,&y1,ut0->row,ut0->col);
+          ut1=&units[cur_player][job->lo];
+          for (j=job->lo;j<job->hi;j++,ut1++) {
+            if (ut1->life>0 &&
+                  LOS(ut0->row,ut0->col,ut1->row,ut1->col)) {
+              LBts(&ut1->vis[enemy_player],0);
+              LBts(&vis_unit_bitmap[enemy_player],j+i*((UNITS_NUM+7)&~7));
+            } else
+              LBtr(&vis_unit_bitmap[enemy_player],j+i*((UNITS_NUM+7)&~7));
+          }
+        } else
+          for (j=job->lo;j<job->hi;j++)
+            LBtr(&vis_unit_bitmap[enemy_player],j+i*((UNITS_NUM+7)&~7));
+      break;
+  }
+  return res;
+}
+
+Bool VisRecalc(I64 mode,Unit *tmpu=NULL)
+{
+  I64 i,hi,k,cnt;
+  Bool res;
+/*The compiler doesn't go out of it's way
+to know if something is const.;-)  This
+just compiles with the val at compile
+time, an advantage of just-in-time over
+AOT binaries.  TempleOS has a limited
+stk size, so don't get in the habit.
+MAlloc() would probably be the better choice.
+*/
+  MPCtrl1 job[mp_cnt];
+  CJob *cmd[mp_cnt];
+
+  if (mode==VR_FRIENDLY_UNIT_DIED) {
+    MemSet((&vis_unit_bitmap[enemy_player])(U8 *)+
+          (tmpu->num*((UNITS_NUM+7)&~7))>>3,0,(UNITS_NUM+7)>>3);
+    VRMerge(enemy_player);
+    return 0; //Return any value--don't care
+  }
+
+  cnt=mp_cnt; //Cores
+  hi=UNITS_NUM;
+  if (mode==VR_ONE_ENEMY_UNIT) {
+    for (hi--;hi>=0;hi--)
+      if (units[enemy_player][hi].life>0)
+        break;
+    hi++;
+  }
+  k=hi;
+  if (hi/mp_cnt<2)
+    cnt=1;
+  for (i=0;i<cnt;i++) {
+    job[i].mode=mode;
+    job[i].tmpu=tmpu;
+    job[i].hi=k;
+    k-=hi/cnt;
+    if (k<0) k=0;
+    if (i==cnt-1) k=0;
+    job[i].lo=k;
+  }
+
+  res=FALSE;
+  for (i=0;i<cnt;i++)
+    cmd[i]=JobQue(&MPVisRecalc,&job[i],i,0);
+  for (i=0;i<cnt;i++)
+    if (JobResGet(cmd[i]))
+      res=TRUE;
+  if (mode==VR_UPDATE_FRIENDLY_UNIT)
+    VRMerge(cur_player);
+  return res;
+}
+
+U0 MPVisRecalcMap(MPCtrl2 *job)
+{
+  I64 i,j;
+  for (j=job->lo;j<job->hi;j++)
+    for (i=0;i<map_cols;i++)
+      if (LOS(job->row,job->col,j,i))
+        vis_map[j][i]=TRUE;
+      else
+        vis_map[j][i]=FALSE;
+}
+
+U0 VisRecalcMap(I64 row,I64 col)
+{
+  I64 i,hi,k,cnt;
+  MPCtrl2 job[mp_cnt];
+  CJob *cmd[mp_cnt];
+
+  cnt=mp_cnt; //Cores
+  hi=map_rows;
+  k=hi;
+  if (hi/mp_cnt<2)
+    cnt=1;
+  for (i=0;i<cnt;i++) {
+    job[i].row=row;
+    job[i].col=col;
+    job[i].hi=k;
+    k-=hi/cnt;
+    if (k<0) k=0;
+    if (i==cnt-1) k=0;
+    job[i].lo=k;
+  }
+  for (i=0;i<cnt;i++)
+    cmd[i]=JobQue(&MPVisRecalcMap,&job[i],i,0);
+  for (i=0;i<cnt;i++)
+    JobResGet(cmd[i]);
+}
+
+ diff --git a/public/Wb/Apps/ToTheFront/ToTheFront.HC.HTML b/public/Wb/Apps/ToTheFront/ToTheFront.HC.HTML new file mode 100755 index 0000000..2a8b75f --- /dev/null +++ b/public/Wb/Apps/ToTheFront/ToTheFront.HC.HTML @@ -0,0 +1,245 @@ + + + + + + + + + + + +
+U0 AnimationDelaySet()
+{
+  animation_delay=PopUpRangeF64(0,100,25,"%3f% %%","Animation Delay\n")/100;
+}
+
+U0 TurnNew()
+{
+  I64 i,j;
+  for (j=0;j<2;j++)
+    for (i=0;i<UNITS_NUM;i++) {
+      units[j][i].remaining_movement=units[j][i].movement;
+      units[j][i].fired=FALSE;
+    }
+  phase=PHASE_START;
+  moving_unit=NULL;
+
+  SleepUntil(msg_off_timeout);
+  msg_off_timeout=cnts.jiffies+JIFFY_FREQ*2*animation_delay+1;
+  Snd(74);
+  StrPrint(msg_buf,"Turn %d",++turn);
+  VRSetUp(0);
+  VRSetUp(1);
+  VisRecalc(VR_ALL_UNITS);
+  cur_player=(turn&1)^1;
+  enemy_player=cur_player^1;
+}
+
+U0 PhaseNew()
+{
+  cur_player^=1;
+  enemy_player=cur_player^1;
+  if (++phase>=PHASE_END) {
+    IndirectResolveAll;
+    TurnNew;
+  }
+
+  SleepUntil(msg_off_timeout);
+  msg_off_timeout=cnts.jiffies+JIFFY_FREQ*2*animation_delay+1;
+  Snd(74);
+  switch (phase) {
+    case PHASE_INDIRECT0:
+    case PHASE_INDIRECT1:
+      StrPrint(msg_buf,"Player %d Artillery Plot",cur_player+1);
+      break;
+    case PHASE_MOVE0:
+    case PHASE_MOVE1:
+      StrPrint(msg_buf,"Player %d Move",cur_player+1);
+      break;
+    case PHASE_DIRECT0:
+    case PHASE_DIRECT1:
+      StrPrint(msg_buf,"Player %d Fire",cur_player+1);
+      break;
+  }
+}
+
+U0 CharDo(U8 ch)
+{
+  I64 old_inhibit,old_draw_it;
+  Bool old_cursor;
+  switch (ch) {
+    case CH_ESC:
+    case CH_SHIFT_ESC:
+      throw('ExitGame',TRUE);
+    case CH_SPACE:
+      throw('PhaseOvr',TRUE);
+    case '\n':
+      throw('NewGame',TRUE);
+    case '1':
+      ViewPlayerSet(0);
+      break;
+    case '2':
+      ViewPlayerSet(1);
+      break;
+    case 'c':
+      old_draw_it=Fs->draw_it;
+      old_inhibit=Fs->win_inhibit;
+      Fs->draw_it=Fs->next_settings->draw_it;
+      Fs->win_inhibit=WIG_USER_TASK_DFT;
+      old_cursor=DocCursor(ON);
+      DocBottom;
+      "\n$GREEN$<SHIFT-ESC>$FG$ to return to game.\n";
+      View;
+      DocBottom;
+      DocCursor(old_cursor);
+      Fs->win_inhibit=old_inhibit;
+      Fs->draw_it=old_draw_it;
+      break;
+    case 'd':
+      AnimationDelaySet;
+      break;
+  }
+}
+
+U0 UserChk()
+{
+  I64 ch;
+  if (!alive_cnt[0] || !alive_cnt[1])
+    throw('GameOver',TRUE);
+  if (ch=ScanChar)
+    CharDo(ch);
+}
+
+U0 TaskEndCB()
+{
+  Snd;
+  progress4=progress4_max=progress1=progress1_max=0;
+  Exit;
+}
+
+I64 PhaseDo()
+{
+  I64 res='ExitGame';
+  PhaseNew;
+  try {
+    if (phase&~1==PHASE_INDIRECT)
+      Call(player_indirect[cur_player]);
+    else if (phase&~1==PHASE_MOVE)
+      Call(player_move[cur_player]);
+    else
+      Call(player_direct[cur_player]);
+  } catch {
+    res=Fs->except_ch;
+    Fs->catch_except=TRUE;
+  }
+  return res;
+}
+
+U0 ToTheFront()
+{
+  I64 res,ch;
+  map_dc=DCNew(MAP_WIDTH,MAP_HEIGHT);
+
+  SettingsPush; //See SettingsPush
+  Cd(__DIR__);
+  Fs->win_inhibit|=WIF_SELF_MS_L|WIF_SELF_MS_R|WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  EndPhase(,CH_SPACE);"
+        "  Restart(,'\n');"
+        "}"
+        "View {"
+        "  Player1(,'1');"
+        "  Player2(,'2');"
+        "  OddsCalculations(,'c');"
+        "  LOS(,0,SCF_SHIFT);"
+        "}"
+        "Settings {"
+        "  AnimationDelay(,'d');"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocMax;
+  Init;
+  PlayerPick("AIs",0);
+  PlayerPick("AIs",1);
+
+  PopUpOk("$PURPLE$$TX+CX,\"ToTheFront\"$$FG$\n\n"
+        "$GREEN${Left-click}$FG$ to move or fire units.\n"
+        "$GREEN$<SPACE>$FG$\tor $GREEN${Right-click}$FG$ to end phase.\n"
+        "$GREEN$<SHIFT>$FG$\tto show line-of-sight.\n"
+        "$GREEN$<ENTER>$FG$\tto start new game.\n"
+        "$GREEN$  1$FG$\tPlayer 1 view.\n"
+        "$GREEN$  2$FG$\tPlayer 2 view.\n"
+        "$GREEN$  c$FG$\tView odds calculations.\n"
+        "$GREEN$  d$FG$\tSet animation delay.");
+  Fs->task_end_cb=&TaskEndCB; //<CTRL-ALT-x>
+  Fs->draw_it=&DrawIt;
+  try {
+    do {
+      res=PhaseDo;
+      if (res=='GameOver') {
+        while (TRUE) {
+          msg_off_timeout=0;
+          StrCpy(msg_buf,"Game Over");
+          Snd;
+          ch=GetChar(,FALSE);
+          if (ch=='\n') {
+            CleanUp;
+            Init;
+            break;
+          } else if (ch==CH_ESC || ch==CH_SHIFT_ESC) {
+            res='ExitGame';
+            break;
+          } else if (ch=='1')
+            ViewPlayerSet(0);
+          else if (ch=='2')
+            ViewPlayerSet(1);
+          else if (ch=='d')
+            AnimationDelaySet;
+        }
+      } else if (res=='NewGame') {
+        CleanUp;
+        Init;
+      }
+    } while (res!='ExitGame');
+  } catch
+    PutExcept;
+  ProgressBarsRst;
+
+  SettingsPop;
+  DCDel(map_dc);
+  CleanUp;
+  MenuPop;
+  Seed;
+}
+
+ diff --git a/public/Wb/Apps/Vocabulary/Load.HC.HTML b/public/Wb/Apps/Vocabulary/Load.HC.HTML new file mode 100755 index 0000000..6875d95 --- /dev/null +++ b/public/Wb/Apps/Vocabulary/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "VocabQuiz"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/Vocabulary/Run.HC.HTML b/public/Wb/Apps/Vocabulary/Run.HC.HTML new file mode 100755 index 0000000..03b504a --- /dev/null +++ b/public/Wb/Apps/Vocabulary/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+VocabQuiz;
+ diff --git a/public/Wb/Apps/Vocabulary/VocabQuiz.HC.HTML b/public/Wb/Apps/Vocabulary/VocabQuiz.HC.HTML new file mode 100755 index 0000000..2abad5f --- /dev/null +++ b/public/Wb/Apps/Vocabulary/VocabQuiz.HC.HTML @@ -0,0 +1,88 @@ + + + + + + + + + + + +
+U8 *RandVocabWord()
+{
+  I64 i;
+  U8 *ptr;
+  if (!acd.num_words)
+    return NULL;
+  i=RandU32%acd.num_words;
+  ptr=acd.word_lst;
+  while (i-- && *ptr==ACD_WORD_CHAR)
+    ptr+=StrLen(ptr)+3;
+  if (*ptr++!=ACD_WORD_CHAR)
+    return NULL;
+  else
+    return ptr;
+}
+
+U0 VocabQuiz()
+{
+  I64 ch,i,num;
+  U8 *right_word,*words[4];
+  if (!FileFind(ACD_DEF_FILENAME)) {
+    "Uncompressed dictionary not present.\n";
+    return;
+  }
+  do {
+    right_word=RandVocabWord;
+    for (i=0;i<4;i++)
+      words[i]=RandVocabWord;
+    num=RandU32&3;
+    words[num]=right_word;
+
+    "$WW,1$$CM-LE,5$$RED$$BK,1$%s$BK,0$:$FG$$LM,4$\n",right_word;
+    for (i=0;i<4;i++)
+      "\n\n$GREEN$$BT-X,\"%d\",LM=\"%d\"$$FG$"
+            "$LM,7$%s\n$LM,4$",i+1,i+1,ACDDefGet(words[i]);
+    "\n\n$LTBLUE$Answer:$FG$";
+    do {
+      ch=GetKey(,TRUE);
+      DocBottom;
+      if ('1'<=ch<='4') {
+        '\n';
+        if (ch-'1'==num) {
+          "$LTGREEN$Correct\n$FG$";
+          Snd(74);
+        } else {
+          "$LTRED$Incorrect\n$FG$";
+          Snd(46);
+        }
+        Sleep(500);
+        Snd;
+        ACDPopUpDef(right_word);
+        break;
+      }
+    } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+    "$LM,0$\n";
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+}
+
+ diff --git a/public/Wb/Apps/X-Caliber/Load.HC.HTML b/public/Wb/Apps/X-Caliber/Load.HC.HTML new file mode 100755 index 0000000..ce3951b --- /dev/null +++ b/public/Wb/Apps/X-Caliber/Load.HC.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "XCCtrls"
+#include "X-Caliber"
+
+#help_index ""
+
+ diff --git a/public/Wb/Apps/X-Caliber/Run.HC.HTML b/public/Wb/Apps/X-Caliber/Run.HC.HTML new file mode 100755 index 0000000..11a3b88 --- /dev/null +++ b/public/Wb/Apps/X-Caliber/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+XCaliber;
+ diff --git a/public/Wb/Apps/X-Caliber/X-Caliber.HC.HTML b/public/Wb/Apps/X-Caliber/X-Caliber.HC.HTML new file mode 100755 index 0000000..6f59533 --- /dev/null +++ b/public/Wb/Apps/X-Caliber/X-Caliber.HC.HTML @@ -0,0 +1,1549 @@ + + + + + + + + + + + +
+#define  XMSGF_ANTISPIN         0
+#define  XMSGF_SOLAR_STORM      1
+RegDft("TempleOS/XCaliber",
+        "I64 best_score=0;\n"
+        "I64 msg_flags=0;\n"
+        );
+RegExe("TempleOS/XCaliber");
+
+#define MT_HUMAN_SHIP           0
+#define MT_ENEMY_SHIP           1
+#define MT_SOLAR_FLARE          2
+#define MT_ION                  3
+#define MT_ANTIMATTER_BALL      4
+#define MT_ANTIMATTER_SPLAT     5
+#define MT_MISSILE              6
+
+class MyMass:CMass
+{
+  F64 temperature,radius,die_timeout;
+  I64 type;
+  Bool no_overlap;
+};
+
+class MySpring:CSpring
+{
+  F64 strength;
+  I64 color;
+};
+
+#define SPIN_GAIN               0.25
+#define MASSES_NUM              8
+#define SPRINGS_NUM             16
+#define MISSILES_NUM            2
+#define ST_HUMAN1               0
+#define ST_ENEMY1               1
+#define ST_ENEMY2               2
+extern class Ship;
+
+#define MISSILE_LEN             5
+class Missile
+{
+  Missile *next,*last;
+  F64 tons,fuse_time,die_timeout;
+  MyMass p_front,p_back;
+  MySpring s[5];
+  U8 *img;
+  Ship *owner,*target;
+  Bool active,launched,exploding;
+  U8 label[5];
+} missile_head;
+
+class Ship
+{
+  Ship *next,*last;
+  I64 type,masses,springs;
+  MyMass   p[MASSES_NUM];
+  MySpring s[SPRINGS_NUM];
+  F64 fire_rate;
+  F64 reload_timeout,spacewalk_timeout;
+  F64 die_time,die_timeout;
+  I64 spacewalk_side;
+  F64 laser_temperature;
+  Missile missiles[MISSILES_NUM];
+  Bool lasering,exploding,laser_overheat;
+} ship_head,*human;
+
+F64 human_t_left,human_t_right,human_antispin;
+
+class Shot
+{
+  Shot *next,*last;
+  F64 radius,fuse_time;
+  I64 splats;
+  MyMass p;
+} shot_head;
+
+F64 t_solar_storm;
+Bool alarm;
+
+#define THRUST_MAX      200.0
+#define ANTISPIN_MAX    25.0
+#define SPACEWALK_TIME  7.5
+
+#define CMD_NULL        0
+#define CMD_SPIN_LEFT   1
+#define CMD_SPIN_RIGHT  2
+#define CMD_THRUST      3
+#define CMD_FIRE        4
+#define CMD_EXIT        5
+Bool game_over,show_level_msg;
+
+#define STARS_NUM       100
+I64 stars_x[STARS_NUM],stars_y[STARS_NUM];
+
+CMathODE *ode=NULL;
+I64 level,score,remaining;
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+<3>/* Graphics Not Rendered in HTML */
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+<6>/* Graphics Not Rendered in HTML */
+
+<7>/* Graphics Not Rendered in HTML */
+
+<8>/* Graphics Not Rendered in HTML */
+
+
+//********************************** Ship
+Bool CheckOverlap()
+{
+  CD3 p;
+  MyMass *tmpm,*tmpm1;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=ode->next_mass;
+    while (tmpm1!=&ode->next_mass) {
+      if (tmpm!=tmpm1 && !tmpm->no_overlap && !tmpm1->no_overlap) {
+        D3Sub(&p,&tmpm->x,&tmpm1->x);
+        if (D3NormSqr(&p)<=Sqr(tmpm->radius+tmpm1->radius))
+          return TRUE;
+      }
+      tmpm1=tmpm1->next;
+    }
+    tmpm=tmpm->next;
+  }
+  return FALSE;
+}
+
+U0 MissileNew(Ship *tmpsp,I64 n)
+{
+  I64 i;
+  CD3 p,p1,p2;
+  Missile *tmpmi=&tmpsp->missiles[n];
+  MemSet(tmpmi,0,sizeof(Missile));
+
+  D3Equ(&tmpmi->p_front.x,
+        (tmpsp->p[n+1].x+tmpsp->p[n+3].x)/2,
+        (tmpsp->p[n+1].y+tmpsp->p[n+3].y)/2,0);
+  D3Copy(&tmpmi->p_back.x,&tmpmi->p_front.x);
+
+  if (n&1)
+    StrCpy(tmpmi->label,"L");
+  else
+    StrCpy(tmpmi->label,"R");
+  tmpmi->owner=tmpsp;
+  tmpmi->tons=0.5;
+  tmpmi->p_front.mass=0.1;
+  tmpmi->p_front.type=MT_MISSILE;
+  tmpmi->p_back.mass =0.1;
+  tmpmi->p_back.type =MT_MISSILE;
+  tmpmi->p_front.radius=2;
+  tmpmi->p_back.radius =2;
+  tmpmi->p_front.no_overlap=TRUE;
+  tmpmi->p_back.no_overlap =TRUE;
+  D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x);
+  D3Sub(&p2,&tmpsp->p[0].x,&tmpsp->p[2].x);
+  D3Unit(D3Add(&p,&p1,&p2));
+  D3AddEqu(&tmpmi->p_front.x,D3MulEqu(D3Copy(&p1,&p),MISSILE_LEN/2+1));
+  D3SubEqu(&tmpmi->p_back.x ,D3MulEqu(D3Copy(&p1,&p),MISSILE_LEN/2-1));
+  D3Copy(&tmpmi->p_front.DxDt,&tmpsp->p[n].DxDt);
+  D3Copy(&tmpmi->p_back.DxDt,&tmpsp->p[n].DxDt);
+  QueIns(&tmpmi->p_front,ode->last_mass);
+  QueIns(&tmpmi->p_back, ode->last_mass);
+
+  tmpmi->s[0].end1=&tmpmi->p_front;
+  tmpmi->s[0].end2=&tmpmi->p_back;
+  tmpmi->s[1].end1=&tmpmi->p_front;
+  tmpmi->s[1].end2=&tmpsp->p[n+1];
+  tmpmi->s[2].end1=&tmpmi->p_back;
+  tmpmi->s[2].end2=&tmpsp->p[n+1];
+  tmpmi->s[3].end1=&tmpmi->p_front;
+  tmpmi->s[3].end2=&tmpsp->p[n+3];
+  tmpmi->s[4].end1=&tmpmi->p_back;
+  tmpmi->s[4].end2=&tmpsp->p[n+3];
+ 
+  for (i=0;i<5;i++) {
+    tmpmi->s[i].const=10000;
+    tmpmi->s[i].strength  =20000;
+    tmpmi->s[i].color=BLACK;
+    tmpmi->s[i].rest_len=D3Dist(&tmpmi->s[i].end1->x,&tmpmi->s[i].end2->x);
+    QueIns(&tmpmi->s[i],ode->last_spring);
+  }
+  tmpmi->img=<7>;
+  tmpmi->active=TRUE;
+  QueIns(tmpmi,missile_head.last);
+}
+
+Ship *ShipNew(I64 x,I64 y,I64 type)
+{
+  I64 i;
+  Ship *tmpsp=CAlloc(sizeof(Ship));
+
+  switch (tmpsp->type=type) {
+    case ST_HUMAN1:
+      tmpsp->fire_rate=25;
+      tmpsp->masses=5;
+      tmpsp->p[0].x=x;
+      tmpsp->p[0].y=y;
+      tmpsp->p[1].x=x+3;
+      tmpsp->p[1].y=y+10;
+      tmpsp->p[2].x=x-3;
+      tmpsp->p[2].y=y+10;
+      tmpsp->p[3].x=x+20;
+      tmpsp->p[3].y=y+20;
+      tmpsp->p[4].x=x-20;
+      tmpsp->p[4].y=y+20;
+
+      for (i=0;i<tmpsp->masses;i++) {
+        tmpsp->p[i].mass=1;
+        tmpsp->p[i].type=MT_HUMAN_SHIP;
+        if (i<3)
+          tmpsp->p[i].radius=2.5;
+        else
+          tmpsp->p[i].radius=4;
+        tmpsp->p[i].drag_profile_factor=3;
+        QueIns(&tmpsp->p[i],ode->last_mass);
+      }
+      tmpsp->p[3].mass/=10.0;
+      tmpsp->p[4].mass/=10.0;
+
+      tmpsp->springs=7;
+      tmpsp->s[0].end1=&tmpsp->p[0];
+      tmpsp->s[0].end2=&tmpsp->p[1];
+      tmpsp->s[1].end1=&tmpsp->p[2];
+      tmpsp->s[1].end2=&tmpsp->p[0];
+      tmpsp->s[2].end1=&tmpsp->p[1];
+      tmpsp->s[2].end2=&tmpsp->p[2];
+      tmpsp->s[3].end1=&tmpsp->p[1];
+      tmpsp->s[3].end2=&tmpsp->p[3];
+      tmpsp->s[4].end1=&tmpsp->p[0];
+      tmpsp->s[4].end2=&tmpsp->p[3];
+      tmpsp->s[5].end1=&tmpsp->p[2];
+      tmpsp->s[5].end2=&tmpsp->p[4];
+      tmpsp->s[6].end1=&tmpsp->p[0];
+      tmpsp->s[6].end2=&tmpsp->p[4];
+
+      for (i=0;i<tmpsp->springs;i++) {
+        tmpsp->s[i].rest_len=
+              D3Dist(&tmpsp->s[i].end1->x,&tmpsp->s[i].end2->x);
+        tmpsp->s[i].const=10000;
+        tmpsp->s[i].strength  =30000;
+        if (i<=2)
+          tmpsp->s[i].color=LTCYAN;
+        else
+          tmpsp->s[i].color=LTGRAY;
+        QueIns(&tmpsp->s[i],ode->last_spring);
+      }
+      MissileNew(tmpsp,0);
+      MissileNew(tmpsp,1);
+      remaining=0;
+
+      break;
+    case ST_ENEMY1:
+      tmpsp->fire_rate=2.5;
+      tmpsp->masses=3;
+      tmpsp->p[0].x=x;
+      tmpsp->p[0].y=y;
+      tmpsp->p[1].x=x+15;
+      tmpsp->p[1].y=y;
+      tmpsp->p[2].x=x;
+      tmpsp->p[2].y=y+15;
+
+      for (i=0;i<tmpsp->masses;i++) {
+        tmpsp->p[i].mass=1;
+        tmpsp->p[i].type=MT_ENEMY_SHIP;
+        tmpsp->p[i].radius=7;
+        tmpsp->p[i].drag_profile_factor=3;
+        QueIns(&tmpsp->p[i],ode->last_mass);
+      }
+
+      tmpsp->springs=3;
+      tmpsp->s[0].end1=&tmpsp->p[0];
+      tmpsp->s[0].end2=&tmpsp->p[1];
+      tmpsp->s[1].end1=&tmpsp->p[1];
+      tmpsp->s[1].end2=&tmpsp->p[2];
+      tmpsp->s[2].end1=&tmpsp->p[2];
+      tmpsp->s[2].end2=&tmpsp->p[0];
+
+      for (i=0;i<tmpsp->springs;i++) {
+        tmpsp->s[i].rest_len=
+              D3Dist(&tmpsp->s[i].end1->x,&tmpsp->s[i].end2->x);
+        tmpsp->s[i].const=10000;
+        tmpsp->s[i].strength  =20000;
+        tmpsp->s[i].color=BLACK;
+        QueIns(&tmpsp->s[i],ode->last_spring);
+      }
+      remaining++;
+      break;
+    case ST_ENEMY2:
+      tmpsp->fire_rate=5.0;
+      tmpsp->masses=5;
+      tmpsp->p[0].x=x;
+      tmpsp->p[0].y=y;
+      tmpsp->p[1].x=x-7;
+      tmpsp->p[1].y=y+10;
+      tmpsp->p[2].x=x+7;
+      tmpsp->p[2].y=y+10;
+      tmpsp->p[3].x=x-14;
+      tmpsp->p[3].y=y+20;
+      tmpsp->p[4].x=x+14;
+      tmpsp->p[4].y=y+20;
+
+      for (i=0;i<tmpsp->masses;i++) {
+        tmpsp->p[i].mass=1;
+        tmpsp->p[i].type=MT_ENEMY_SHIP;
+        tmpsp->p[i].radius=6;
+        tmpsp->p[i].drag_profile_factor=5;
+        QueIns(&tmpsp->p[i],ode->last_mass);
+      }
+
+      tmpsp->springs=7;
+      tmpsp->s[0].end1=&tmpsp->p[0];
+      tmpsp->s[0].end2=&tmpsp->p[1];
+      tmpsp->s[1].end1=&tmpsp->p[0];
+      tmpsp->s[1].end2=&tmpsp->p[2];
+      tmpsp->s[2].end1=&tmpsp->p[1];
+      tmpsp->s[2].end2=&tmpsp->p[2];
+      tmpsp->s[3].end1=&tmpsp->p[1];
+      tmpsp->s[3].end2=&tmpsp->p[3];
+      tmpsp->s[4].end1=&tmpsp->p[2];
+      tmpsp->s[4].end2=&tmpsp->p[4];
+      tmpsp->s[5].end1=&tmpsp->p[2];
+      tmpsp->s[5].end2=&tmpsp->p[3];
+      tmpsp->s[6].end1=&tmpsp->p[1];
+      tmpsp->s[6].end2=&tmpsp->p[4];
+
+      for (i=0;i<tmpsp->springs;i++) {
+        tmpsp->s[i].rest_len=
+              D3Dist(&tmpsp->s[i].end1->x,&tmpsp->s[i].end2->x);
+        tmpsp->s[i].const= 40000;
+        tmpsp->s[i].strength  =75000;
+        if (i>=3)
+          tmpsp->s[i].color=LTPURPLE;
+        else
+          tmpsp->s[i].color=BLACK;
+        QueIns(&tmpsp->s[i],ode->last_spring);
+      }
+      remaining++;
+      break;
+  }
+  QueIns(tmpsp,ship_head.last);
+  return tmpsp;
+}
+
+U0 MissileDel(Missile *tmpmi)
+{
+  I64 i;
+  if (tmpmi->active) {
+    QueRem(tmpmi);
+    for(i=0;i<5;i++)
+      QueRem(&tmpmi->s[i]);
+    QueRem(&tmpmi->p_front);
+    QueRem(&tmpmi->p_back);
+    tmpmi->active=FALSE;
+  }
+}
+
+U0 ShipDel(Ship *tmpsp)
+{
+  I64 i;
+  if (!tmpsp) return;
+  for (i=0;i<tmpsp->masses;i++)
+    QueRem(&tmpsp->p[i]);
+  for (i=0;i<tmpsp->springs;i++)
+    QueRem(&tmpsp->s[i]);
+  for (i=0;i<2;i++)
+    MissileDel(&tmpsp->missiles[i]);
+  QueRem(tmpsp);
+  Free(tmpsp);
+  remaining--;
+}
+
+U0 PlaceShip(I64 type)
+{
+  Ship *tmpsp;
+  if (CheckOverlap)
+    return;
+  while (TRUE) {
+    tmpsp=ShipNew(RandU16%(Fs->pix_width-20)+10,
+          RandU16%(Fs->pix_height-20)+10,type);
+    if (CheckOverlap)
+      ShipDel(tmpsp);
+    else
+      break;
+  }
+}
+
+//********************************** Human Ship
+
+I64 Tweaked()
+{
+  CD3 p,p1,p2;
+  if (human) {
+    D3Sub(&p1,&human->p[0].x,&human->p[1].x);
+    D3Sub(&p2,&human->p[0].x,&human->p[2].x);
+    D3Unit(D3Add(&p,&p1,&p2));
+    D3Sub(&p1,&human->p[0].x,&human->p[3].x);
+    D3Sub(&p2,&human->p[0].x,&human->p[4].x);
+    D3Unit(&p1);
+    D3Unit(&p2);
+    if (!(human->s[3].flags&SSF_INACTIVE) && D3Dot(&p,&p1)>Cos(20*pi/180))
+      return 3;
+    if (!(human->s[5].flags&SSF_INACTIVE) && D3Dot(&p,&p2)>Cos(20*pi/180))
+      return 4;
+    return 0;
+  }
+}
+
+U0 AllDel(CMathODE *ode)
+{
+  Ship *tmpsp,*tmpsp1;
+  QueRem(ode);
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    tmpsp1=tmpsp->next;
+    ShipDel(tmpsp);
+    tmpsp=tmpsp1;
+  }
+  human=NULL;
+  QueDel(&shot_head,TRUE);
+  ODEDel(ode);
+}
+
+Bool LaserPlot(CDC *dc,I64 x,I64 y,I64)
+{
+  I64 c;
+  c=GrPeek(dc,x,y);
+  if (c!=BLACK && c!=WHITE)
+    return FALSE;
+  else {
+    GrPlot(dc,x,y);
+    return TRUE;
+  }
+}
+
+//**********************************
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j;
+  F64 arg;
+  Ship *tmpsp;
+  Shot *tmps;
+  Missile *tmpmi;
+  CD3 p,p1,p2;
+  F64 t_left,t_right,spin,d,x,y;
+  MySpring *tmpsps;
+  MyMass *tmpm;
+  U8 *img;
+  Bool draw_laser_line=FALSE;
+
+  if (ode!=task->last_ode) return;
+
+  dc->color=WHITE;
+  GrPrint(dc,0,0,"Level:%d Score:%d High Score:%d",level,score,best_score);
+  if (game_over) {
+    if (Blink)
+      GrPrint(dc,(task->pix_width-9*FONT_WIDTH)/2,
+            (task->pix_height-FONT_HEIGHT)/2,"Game Over");
+  } else if (show_level_msg) {
+    if (Blink)
+      GrPrint(dc,(task->pix_width-8*FONT_WIDTH)/2,
+            (task->pix_height-FONT_HEIGHT)/2+50,"Level %d",level);
+  }
+
+  for (i=0;i<STARS_NUM;i++)
+    GrPlot(dc,stars_x[i],stars_y[i]);
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type==MT_ANTIMATTER_SPLAT) {
+      dc->color=LTGREEN;
+      GrPlot(dc,tmpm->x,tmpm->y);
+    } else if (tmpm->type==MT_ION) {
+      dc->color=YELLOW;
+      GrPlot(dc,tmpm->x,tmpm->y);
+    }
+    tmpm=tmpm->next;
+  }
+
+  tmpsps=ode->next_spring;
+  while (tmpsps!=&ode->next_spring) {
+    if (!(tmpsps->flags&SSF_INACTIVE) && tmpsps->color) {
+      dc->color=tmpsps->color;
+      GrLine(dc,tmpsps->end1->x,tmpsps->end1->y,
+            tmpsps->end2->x,tmpsps->end2->y);
+    }
+    tmpsps=tmpsps->next;
+  }
+
+  tmpmi=missile_head.next;
+  while (tmpmi!=&missile_head) {
+    if (tmpmi->active) {
+      if (tmpmi->launched && tmpmi->exploding) {
+        d=(tS-tmpmi->fuse_time)/(tmpmi->die_timeout-tmpmi->fuse_time);
+        d=70*Sin(pi*d)*tmpmi->tons+1;
+        for (i=1;i<d;i++) {
+          if (i&1)
+            dc->color=YELLOW;
+          else
+            dc->color=LTRED;
+          GrCircle(dc,tmpmi->p_front.x,tmpmi->p_front.y,i);
+        }
+      } else
+        Sprite3ZB(dc,(tmpmi->p_front.x+tmpmi->p_back.x)/2,
+              (tmpmi->p_front.y+tmpmi->p_back.y)/2,0,tmpmi->img,
+              Arg(tmpmi->p_front.x-tmpmi->p_back.x,
+              tmpmi->p_front.y-tmpmi->p_back.y));
+    }
+    tmpmi=tmpmi->next;
+  }
+
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    if (!tmpsp->exploding) {
+      switch (tmpsp->type) {
+        case ST_HUMAN1:
+          if (tmpsp->spacewalk_side) {
+            t_left=0;
+            t_right=0;
+          } else {
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x))) {
+              D3Sub(&p2,&tmpsp->p[0].DxDt,&tmpsp->p[1].DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_left =Clamp(human_t_left+SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[2].x))) {
+              D3Sub(&p2,&tmpsp->p[0].DxDt,&tmpsp->p[2].DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_right=Clamp(human_t_right-SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+          }
+
+          D3Sub(&p1,&tmpsp->p[1].x,&tmpsp->p[0].x);
+          D3Sub(&p2,&tmpsp->p[2].x,&tmpsp->p[0].x);
+          D3Unit(D3Add(&p,&p1,&p2));
+
+          if (!(tmpsp->s[3].flags&SSF_INACTIVE)) {
+            dc->color=YELLOW;
+            D3AddEqu(D3Mul(&p1,t_left/25,&p),&tmpsp->p[3].x);
+            GrLine(dc,tmpsp->p[1].x,tmpsp->p[1].y,p1.x,p1.y);
+            arg=Arg(p.x,p.y);
+            Sprite3ZB(dc,tmpsp->p[3].x,tmpsp->p[3].y,0,<thruster>,arg);
+          }
+
+          if (!(tmpsp->s[5].flags&SSF_INACTIVE)) {
+            dc->color=YELLOW;
+            D3AddEqu(D3Mul(&p2,t_right/25,&p),&tmpsp->p[4].x);
+            GrLine(dc,tmpsp->p[2].x,tmpsp->p[2].y,p2.x,p2.y);
+            arg=Arg(p.x,p.y);
+            Sprite3ZB(dc,tmpsp->p[4].x,tmpsp->p[4].y,0,<thruster>,arg);
+          }
+
+          if (tS>tmpsp->reload_timeout)
+            img=<gun_ready>;
+          else
+            img=<gun_busy>;
+          arg=Arg(p.x,p.y);
+          switch (level) {
+            case 3:
+              if (!(tmpsp->s[3].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[3].x,tmpsp->p[3].y,0,img,arg);
+              if (!(tmpsp->s[5].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[4].x,tmpsp->p[4].y,0,img,arg);
+            case 2:
+              if (!(tmpsp->s[1].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[1].x,tmpsp->p[1].y,0,img,arg);
+              if (!(tmpsp->s[2].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[2].x,tmpsp->p[2].y,0,img,arg);
+            case 1:
+              Sprite3ZB(dc,tmpsp->p[0].x,tmpsp->p[0].y,0,img,arg);
+              break;
+            default:
+              Sprite3ZB(dc,tmpsp->p[0].x,tmpsp->p[0].y,0,<Laser>,arg);
+              if (tmpsp->lasering && !tmpsp->laser_overheat) {
+                draw_laser_line=TRUE;
+                Snd(74);
+              }
+          }
+
+          ctrl_panel.laser_temperature=tmpsp->laser_temperature;
+
+          if (tmpsp->spacewalk_side) {
+            d=1.0-(tmpsp->spacewalk_timeout-tS)/SPACEWALK_TIME;
+            if (d>1.0) {
+              tmpsp->spacewalk_side=0;
+              ctrl_panel.spacewalk=FALSE;
+            } else {
+              if (d<0.5) {
+                d=d*2;
+                x=tmpsp->p[0].x*(1.0-d)+
+                      tmpsp->p[tmpsp->spacewalk_side].x*(d);
+                y=tmpsp->p[0].y*(1.0-d)+
+                      tmpsp->p[tmpsp->spacewalk_side].y*(d);
+              } else {
+                d=(d-0.5)*2;
+                x=tmpsp->p[tmpsp->spacewalk_side].x*(1.0-d)+
+                      tmpsp->p[0].x*(d);
+                y=tmpsp->p[tmpsp->spacewalk_side].y*(1.0-d)+
+                      tmpsp->p[0].y*(d);
+              }
+              Sprite3ZB(dc,x,y,0,<spacewalk>,arg+0.75*Sin(tS*2));
+            }
+          } else {
+            if (ctrl_panel.spacewalk) {
+              if (tmpsp->spacewalk_side=Tweaked)
+                tmpsp->spacewalk_timeout=tS+SPACEWALK_TIME;
+              else
+                ctrl_panel.spacewalk=FALSE;
+            }
+          }
+          break;
+        case ST_ENEMY2:
+          for (i=3;i<tmpsp->masses;i++) {
+            dc->color=PURPLE;
+            GrCircle(dc,tmpsp->p[i].x,tmpsp->p[i].y,tmpsp->p[i].radius);
+            GrFloodFill(dc,tmpsp->p[i].x,tmpsp->p[i].y+2,TRUE);
+            dc->color=WHITE;
+            GrCircle(dc,tmpsp->p[i].x,tmpsp->p[i].y,tmpsp->p[i].radius);
+          }
+        case ST_ENEMY1:
+          D3DivEqu(D3Sub(&p1,&tmpsp->p[1].x,&tmpsp->p[0].x),2.0);
+          D3DivEqu(D3Sub(&p2,&tmpsp->p[2].x,&tmpsp->p[0].x),2.0);
+          D3Unit(D3Add(&p,&p1,&p2));
+          if (tS>tmpsp->reload_timeout)
+            img=<gun_ready>;
+          else
+            img=<gun_busy>;
+          arg=Arg(p.x,p.y);
+          Sprite3ZB(dc,tmpsp->p[0].x,tmpsp->p[0].y,0,img,arg);
+          arg=Arg(p1.x,p1.y);
+          Sprite3ZB(dc,tmpsp->p[0].x+p1.x,tmpsp->p[0].y+p1.y,0,
+                <EnemySide>,arg);
+          arg=Arg(p2.x,p2.y);
+          Sprite3ZB(dc,tmpsp->p[0].x+p2.x,tmpsp->p[0].y+p2.y,0,
+                <EnemySide>,arg);
+          break;
+      }
+      for (i=0;i<tmpsp->masses;i++) {
+        dc->color=YELLOW;
+        if (tmpsp->p[i].temperature>=1.0)
+          GrCircle(dc,tmpsp->p[i].x,tmpsp->p[i].y,
+                tmpsp->p[i].temperature);
+      }
+    }
+    else if (tmpsp->die_time<=tS<=tmpsp->die_timeout)
+      for (j=0;j<tmpsp->masses;j++) {
+        d=(tS-tmpsp->die_time)/(tmpsp->die_timeout-tmpsp->die_time);
+        d=7*Sin(pi*d)*(6+j)+1;
+        for (i=1;i<d;i++) {
+          if (i&1)
+            dc->color=YELLOW;
+          else
+            dc->color=LTRED;
+          GrCircle(dc,tmpsp->p[j].x,tmpsp->p[j].y,i);
+        }
+      }
+    tmpsp=tmpsp->next;
+  }
+
+  tmps=shot_head.next;
+  while (tmps!=&shot_head) {
+    if (tmps->radius<1.0) {
+      dc->color=LTGREEN;
+      GrPlot(dc,tmps->p.x,tmps->p.y);
+    } else {
+      dc->color=YELLOW;
+      GrCircle(dc,tmps->p.x,tmps->p.y,tmps->radius);
+      if (tmps->radius>=2.0)
+        GrFloodFill(dc,tmps->p.x,tmps->p.y,TRUE);
+      dc->color=LTGREEN;
+      GrCircle(dc,tmps->p.x,tmps->p.y,tmps->radius);
+    }
+    tmps=tmps->next;
+  }
+
+  if (human && draw_laser_line) {
+    D3Sub(&p1,&human->p[1].x,&human->p[0].x);
+    D3Sub(&p2,&human->p[2].x,&human->p[0].x);
+    D3Unit(D3Add(&p,&p1,&p2));
+    dc->color=LTBLUE;
+    Line(dc,human->p[0].x-10*p.x,human->p[0].y-10*p.y,0,
+          human->p[0].x-800*p.x,human->p[0].y-800*p.y,0,&LaserPlot);
+  }
+
+  tmpmi=missile_head.next;
+  while (tmpmi!=&missile_head) {
+    if (tmpsp=tmpmi->target) {
+      dc->color=LTRED;
+      GrCircle(dc,tmpsp->p[0].x,tmpsp->p[0].y,10);
+      GrPrint(dc,tmpsp->p[0].x+12,tmpsp->p[0].y-4,tmpmi->label);
+    }
+    tmpmi=tmpmi->next;
+  }
+}
+
+U0 Explosion(MyMass *tmpm1,MyMass *tmpm2,F64 tons)
+{
+  MyMass *tmpm;
+  CD3 p1;
+  F64 d;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm!=tmpm1 && tmpm!=tmpm2) {
+      D3Sub(&p1,&tmpm->state->x,&tmpm1->state->x);
+      d=D3NormSqr(&p1)-tmpm->radius*tmpm->radius;
+      if (d<100.0*100.0) {
+        if (d<1)
+          d=1;
+        else
+          d=Sqrt(d);
+        d=250000*tons/d`2;
+        D3MulEqu(&p1,d);
+        D3AddEqu(&tmpm->DstateDt->DxDt,&p1);
+      }
+    }
+    tmpm=tmpm->next;
+  }
+}
+
+Ship TargetGet(Missile *tmpmi)
+{
+  Ship *tmpsp,*res=NULL;
+  F64 dd,best_dd=F64_MAX;
+  I64 i;
+  CD3 p,p1,p2;
+  D3Unit(D3Sub(&p,&tmpmi->p_front.state->x,&tmpmi->p_back.state->x));
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    if (!tmpsp->exploding && tmpsp!=tmpmi->owner)
+      for (i=0;i<tmpsp->masses;i++) {
+        D3Sub(&p1,&tmpsp->p[i].state->x,&tmpmi->p_front.state->x);
+        D3Unit(D3Copy(&p2,&p1));
+        D3Cross(&p1,&p,&p2);
+        if (D3Dot(&p,&p2)>0 && D3Norm(&p1)<=pi/16) {
+          dd=D3NormSqr(&p1);
+          if (dd<best_dd) {
+            best_dd=dd;
+            res=tmpsp;
+          }
+        }
+      }
+    tmpsp=tmpsp->next;
+  }
+  return res;
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+  I64 i;
+  F64 d,dd,dd2,spin,t_left,t_right,theta_err,theta_thrust,DthetaDt;
+  CTask *task=ode->win_task;
+  CD3 p,p1,p2;
+  Ship *tmpsp;
+  Missile *tmpmi;
+  MyMass *tmpm,*tmpm1;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type!=MT_SOLAR_FLARE && tmpm->type!=MT_ION) {
+      d=tmpm->state->x;
+      if (d-tmpm->radius<0)
+        tmpm->DstateDt->DxDt+=Sqr(Sqr(Sqr(d-tmpm->radius)));
+      if (d+tmpm->radius>task->pix_width)
+        tmpm->DstateDt->DxDt-=Sqr(Sqr(Sqr((d+tmpm->radius)-task->pix_width)));
+      d=tmpm->state->y;
+      if (d-tmpm->radius<0)
+        tmpm->DstateDt->DyDt+=Sqr(Sqr(Sqr(d-tmpm->radius)));
+      if (d+tmpm->radius>task->pix_height)
+        tmpm->DstateDt->DyDt-=Sqr(Sqr(Sqr((d+tmpm->radius)-task->pix_height)));
+    }
+    if (tmpm->type!=MT_ION && tmpm->type!=MT_ANTIMATTER_SPLAT) {
+      tmpm1=ode->next_mass;
+      while (tmpm1!=&ode->next_mass) {
+        if (tmpm!=tmpm1) {
+          if (tmpm1->type==MT_ANTIMATTER_SPLAT) {
+            if (tmpm->type==MT_HUMAN_SHIP || tmpm->type==MT_ENEMY_SHIP) {
+              D3Sub(&p,&tmpm->state->x,&tmpm1->state->x);
+              dd=D3NormSqr(&p)+1;
+              if (dd<100000) {
+                D3MulEqu(&p,100000/dd);
+                D3AddEqu(&tmpm1->DstateDt->DxDt,&p);
+              }
+            }
+          } else if (tmpm1->type!=MT_ION) {
+            D3Sub(&p,&tmpm->state->x,&tmpm1->state->x);
+            dd=D3NormSqr(&p);
+            dd2=Sqr(tmpm->radius+tmpm1->radius);
+            if (dd<=dd2) {
+              d=Sqrt(dd)+0.0001;
+              D3MulEqu(&p,Sqr(Sqr(dd2-dd))/d);
+              D3AddEqu(&tmpm ->DstateDt->DxDt,&p);
+              D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+            }
+          }
+        }
+        tmpm1=tmpm1->next;
+      }
+    }
+    tmpm=tmpm->next;
+  }
+
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    if (tmpsp->exploding && tmpsp->die_time<=tS<=tmpsp->die_timeout)
+      for (i=0;i<tmpsp->masses;i++)
+        Explosion(&tmpsp->p[i],NULL,tmpsp->p[i].radius/250.0);
+    switch (tmpsp->type) {
+      case ST_HUMAN1:
+        if (!tmpsp->exploding) {
+          if (tmpsp->spacewalk_side) {
+            t_left=0;
+            t_right=0;
+            d=1.0-(tmpsp->spacewalk_timeout-tS)/SPACEWALK_TIME;
+            if (0.485<d<0.515) {
+              D3Unit(D3Sub(&p,&tmpsp->p[2].state->x,&tmpsp->p[1].state->x));
+              if (tmpsp->spacewalk_side==3) {
+                tmpsp->p[3].DstateDt->DxDt-=10*THRUST_MAX*p.x;
+                tmpsp->p[3].DstateDt->DyDt-=10*THRUST_MAX*p.y;
+                tmpsp->p[1].DstateDt->DxDt+=10*THRUST_MAX*p.x;
+                tmpsp->p[1].DstateDt->DyDt+=10*THRUST_MAX*p.y;
+              } else {
+                tmpsp->p[4].DstateDt->DxDt+=10*THRUST_MAX*p.x;
+                tmpsp->p[4].DstateDt->DyDt+=10*THRUST_MAX*p.y;
+                tmpsp->p[2].DstateDt->DxDt-=10*THRUST_MAX*p.x;
+                tmpsp->p[2].DstateDt->DyDt-=10*THRUST_MAX*p.y;
+              }
+            }
+          } else {
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].state->x,
+                  &tmpsp->p[1].state->x))) {
+              D3Sub(&p2,&tmpsp->p[0].state->DxDt,&tmpsp->p[1].state->DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_left =Clamp(human_t_left+SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].state->x,
+                  &tmpsp->p[2].state->x))) {
+              D3Sub(&p2,&tmpsp->p[0].state->DxDt,&tmpsp->p[2].state->DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_right=Clamp(human_t_right-SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+
+            D3Sub(&p1,&tmpsp->p[0].state->x,&tmpsp->p[1].state->x);
+            D3Sub(&p2,&tmpsp->p[0].state->x,&tmpsp->p[2].state->x);
+            D3Unit(D3Add(&p,&p1,&p2));
+            if (!(tmpsp->s[3].flags&SSF_INACTIVE)) {
+              D3Mul(&p1,t_left,&p);
+              D3AddEqu(&tmpsp->p[3].DstateDt->DxDt,&p1);
+            }
+            if (!(tmpsp->s[5].flags&SSF_INACTIVE)) {
+              D3Mul(&p2,t_right,&p);
+              D3AddEqu(&tmpsp->p[4].DstateDt->DxDt,&p2);
+            }
+          }
+        }
+        break;
+    }
+    tmpsp=tmpsp->next;
+  }
+
+  tmpmi=missile_head.next;
+  while (tmpmi!=&missile_head) {
+    if (tmpmi->active) {
+      if (tmpmi->launched) {
+        if (tmpmi->exploding)
+          Explosion(&tmpmi->p_front,&tmpmi->p_back,tmpmi->tons);
+        else {
+//Guide missile
+          if (tmpsp=tmpmi->target) {
+            D3Unit(D3Sub(&p,&tmpmi->p_front.state->x,
+                  &tmpmi->p_back.state->x));
+            D3Sub(&p1,&tmpsp->p[0].state->x,&tmpmi->p_front.state->x);
+            d=D3Norm(&p1);
+            D3Unit(&p1);
+            theta_err=D3Dot(&p,&p1);
+            D3Sub(&p1,&tmpmi->p_front.state->DxDt,&tmpmi->p_back.state->DxDt);
+            D3Cross(&p2,&p,&p1);
+            DthetaDt=D3Norm(&p2);
+            if (p2.z<0)
+              DthetaDt=-DthetaDt;
+            theta_thrust=Clamp(200*(theta_err+2*DthetaDt)/(d+200),-pi/8,pi/8);
+            p2.x=p.x*Cos(theta_thrust)-p.y*Sin(theta_thrust);
+            p2.y=p.y*Cos(theta_thrust)+p.x*Sin(theta_thrust);
+            p2.z=0;
+            D3AddEqu(&tmpmi->p_back.DstateDt->DxDt,D3MulEqu(&p2,THRUST_MAX));
+          }
+        }
+      } else
+        tmpmi->target=TargetGet(tmpmi);
+    } else
+      tmpmi->target=NULL;
+    tmpmi=tmpmi->next;
+  }
+}
+
+U0 CheckDamage()
+{
+  I64 i,j,death_score;
+  Ship *tmpsp,*tmpsp1;
+  MyMass *tmpm,*tmpm1,*best_mass;
+  CD3 p,p1,p2;
+  F64 d,best_distance;
+  Bool facing_sun=FALSE;
+
+  if (human) {
+    D3Sub(&p1,&human->p[1].x,&human->p[0].x);
+    D3Sub(&p2,&human->p[2].x,&human->p[0].x);
+    D3Add(&p,&p1,&p2);
+    if (p.x>0)
+      facing_sun=TRUE;
+  }
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type==MT_ION) {
+      if (facing_sun) {
+        tmpm1=ode->next_mass;
+        while (tmpm1!=&ode->next_mass) {
+          if (tmpm1->type==MT_HUMAN_SHIP) {
+            D3Sub(&p,&tmpm1->x,&tmpm->x);
+            if (D3NormSqr(&p)<Sqr(tmpm1->radius))
+              tmpm1->temperature+=3.0;
+          }
+          tmpm1=tmpm1->next;
+        }
+      }
+    } else if (tmpm->type==MT_ANTIMATTER_SPLAT) {
+      tmpm1=ode->next_mass;
+      while (tmpm1!=&ode->next_mass) {
+        if (tmpm1->type!=MT_ION && tmpm1->type!=MT_ANTIMATTER_SPLAT) {
+          D3Sub(&p,&tmpm1->x,&tmpm->x);
+          if (D3NormSqr(&p)<Sqr(tmpm1->radius))
+            tmpm1->temperature+=0.4;
+        }
+        tmpm1=tmpm1->next;
+      }
+    } else
+      tmpm->temperature*=0.9;
+    tmpm=tmpm->next;
+  }
+
+  if (human) {
+    human->laser_temperature*=0.975;
+
+    if (human->laser_overheat) {
+      if (human->laser_temperature<LASER_THRESHOLD_TEMP)
+        human->laser_overheat=FALSE;
+    }
+    if (!human->laser_overheat && human->lasering) {
+      if (human->laser_temperature>=LASER_TEMP_MAX) {
+        human->laser_overheat=TRUE;
+        Snd;
+      } else {
+        human->laser_temperature+=1.0;
+        D3Sub(&p1,&human->p[0].x,&human->p[1].x);
+        D3Sub(&p2,&human->p[0].x,&human->p[2].x);
+        D3Unit(D3Add(&p,&p1,&p2));
+        p2.x=p.y;
+        p2.y=-p.x;
+        p2.z=0;
+        best_mass=NULL;
+        best_distance=F64_MAX;
+        tmpm=ode->next_mass;
+        while (tmpm!=&ode->next_mass) {
+          D3Sub(&p1,&human->p[0].x,&tmpm->x);
+          if (Abs(D3Dot(&p1,&p2))<tmpm->radius &&
+                D3Dot(&p1,&p)<0.0) {
+            d=D3NormSqr(&p1);
+            if (d<best_distance) {
+              best_distance=d;
+              best_mass=tmpm;
+            }
+          }
+          tmpm=tmpm->next;
+        }
+        if (best_mass)
+          best_mass->temperature+=1.0;
+      }
+    }
+  }
+
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    tmpsp1=tmpsp->next;
+    death_score=0;
+    switch (tmpsp->type) {
+      case ST_HUMAN1:
+        if (tmpsp->exploding) {
+          if (tS>tmpsp->die_timeout)  {
+            ShipDel(tmpsp);
+            human=NULL;
+          }
+        } else
+          for (i=0;i<tmpsp->springs;i++) {
+            if (Abs(tmpsp->s[i].f)>tmpsp->s[i].strength) {
+              tmpsp->s[i].flags|=SSF_INACTIVE;
+              if (i==4)
+                MissileDel(&tmpsp->missiles[0]);
+              else if (i==5)
+                MissileDel(&tmpsp->missiles[1]);
+            }
+            if (tmpsp->s[i].flags&SSF_INACTIVE && i<3)
+              death_score++;
+          }
+        break;
+      default:
+        if (tmpsp->exploding) {
+          if (tS>tmpsp->die_timeout) {
+            ShipDel(tmpsp);
+            score+=level;
+            if (score>best_score)
+              best_score=score;
+          }
+        } else {
+          j=0;
+          for (i=0;i<tmpsp->springs;i++) {
+            if (tmpsp->s[i].flags&SSF_INACTIVE)
+              j++;
+            else if (Abs(tmpsp->s[i].f)>tmpsp->s[i].strength) {
+              tmpsp->s[i].flags|=SSF_INACTIVE;
+              j++;
+            }
+          }
+          if (j>1)
+            death_score++;
+        }
+    }
+    if (!tmpsp->exploding) {
+      for (i=0;i<tmpsp->masses;i++)
+        if (tmpsp->p[i].temperature>MASS_TEMP_MAX)
+          death_score++;
+      if (death_score) {
+        tmpsp->exploding=TRUE;
+        tmpsp->die_time=tS;
+        tmpsp->die_timeout=tS+0.75;
+        Noise(750,74,93);
+        if (tmpsp->type==ST_HUMAN1)
+          game_over=TRUE;
+      }
+    }
+    tmpsp=tmpsp1;
+  }
+}
+
+//********************************** Shots
+
+Shot *ShotNew(I64 type,CD3 *_p,CD3 *_v,F64 r,F64 fuse_time,
+        CD3 *_p_gun_offset=NULL)
+{
+  Shot *tmps=CAlloc(sizeof(Shot));
+  D3Copy(&tmps->p.x,_p);
+  tmps->radius=r;
+  tmps->splats=20*r;
+  tmps->fuse_time=tS+fuse_time;
+  tmps->p.mass=0.3*r*r*r;
+  tmps->p.type=type;
+  if (_p_gun_offset)
+    D3AddEqu(&tmps->p.x,_p_gun_offset);
+  D3Copy(&tmps->p.DxDt,_v);
+  QueIns(&tmps->p,ode->last_mass);
+  QueIns(tmps,shot_head.last);
+}
+
+U0 SolarFlares()
+{
+  CD3 p,v,p1,p2;
+  CTask *task=ode->win_task;
+  if (!alarm && t_solar_storm-2.0<tS<t_solar_storm+1.0) {
+    Sweep(2000,74,93);
+    alarm=TRUE;
+  }
+  if (t_solar_storm<tS) {  //If solar storm has arrived
+    if (tS<t_solar_storm+5.0) { //If solar storm not over
+      if (Rand<.1) {
+        D3Equ(&p,-300,Rand*task->pix_height,0);
+        D3Equ(&v,200.0,0,0);
+        ShotNew(MT_SOLAR_FLARE,&p,&v,25,0.1);
+      }
+    } else {
+      t_solar_storm=tS+25*Rand;  //Schedule next solar storm
+      alarm=FALSE;
+    }
+  }
+}
+
+U0 FireOneGun(Ship *tmpsp,I64 n,F64 r,F64 fuse_time)
+{
+  I64 ona;
+  CD3 p,v,p1,p2;
+  Shot *tmps;
+  D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x);
+  D3Sub(&p2,&tmpsp->p[0].x,&tmpsp->p[2].x);
+  D3Unit(D3Add(&p,&p1,&p2));
+  D3MulEqu(D3Copy(&p1,&p),r+tmpsp->p[0].radius+5);
+  D3AddEqu(D3MulEqu(D3Copy(&v,&p),1000/(r+1)),&tmpsp->p[n].DxDt);
+  tmps=ShotNew(MT_ANTIMATTER_BALL,&tmpsp->p[n].x,&v,r,fuse_time,&p1);
+  D3MulEqu(&p,tmps->p.mass/tmpsp->p[n].mass/100.0);
+  D3SubEqu(&tmpsp->p[n].DxDt,&p);
+  tmpsp->reload_timeout=tS+r/tmpsp->fire_rate;
+  ona=Freq2Ona(500/r);
+  Noise(100,ona,ona+12);
+}
+
+U0 FireOneMissile(Ship *tmpsp,I64 n)
+{
+  I64 i;
+  Missile *tmpmi=&tmpsp->missiles[n];
+  if (!tmpmi->launched && tmpmi->target) {
+    tmpmi->fuse_time=tS+1.0;
+    tmpmi->die_timeout=tmpmi->fuse_time+0.125;
+    tmpmi->img=<8>;
+    for (i=1;i<5;i++)
+      tmpmi->s[i].flags|=SSF_INACTIVE;
+    tmpmi->launched=TRUE;
+    Sweep(250,53,56);
+  }
+}
+
+U0 HumanFireGunBegin()
+{
+  F64 r=3.0*ctrl_panel.shot_radius/CTRL_PANEL_RANGE+0.5,
+        fuse_time=ToF64(ctrl_panel.fuse_time+1)/CTRL_PANEL_RANGE;
+  if (human) {
+    if (!human->exploding && !human->spacewalk_side && tS>human->reload_timeout)
+      switch (level) {
+        case 3:
+          if (!(human->s[3].flags&SSF_INACTIVE))
+            FireOneGun(human,3,r,fuse_time);
+          if (!(human->s[5].flags&SSF_INACTIVE))
+            FireOneGun(human,4,r,fuse_time);
+        case 2:
+          if (!(human->s[1].flags&SSF_INACTIVE))
+            FireOneGun(human,1,r,fuse_time);
+          if (!(human->s[2].flags&SSF_INACTIVE))
+            FireOneGun(human,2,r,fuse_time);
+        case 1:
+          FireOneGun(human,0,r,fuse_time);
+          break;
+      }
+  }
+}
+
+U0 HumanFireMissileBegin(I64 n)
+{
+  if (human && !human->exploding &&
+        !human->spacewalk_side && tS>human->reload_timeout)
+    FireOneMissile(human,n);
+}
+
+U0 HumanFireLaserBegin()
+{
+  if (human && !human->exploding &&
+        !human->spacewalk_side && tS>human->reload_timeout)
+    human->lasering=TRUE;
+}
+U0 HumanFireLaserEnd()
+{
+  if (human && !human->exploding) {
+    human->lasering=FALSE;
+    Snd;
+  }
+}
+
+U0 SplatNew(Shot *tmps,F64 die_time,F64 start,F64 end)
+{
+  MyMass *tmpm;
+  F64 theta=Arg(tmps->p.DxDt,tmps->p.DyDt);
+  I64 i;
+  for (i=0;i<tmps->splats;i++) {
+    tmpm=CAlloc(sizeof(MyMass));
+    D3Copy(&tmpm->x,&tmps->p.x);
+    tmpm->radius=1;
+    tmpm->mass=1;
+    tmpm->die_timeout=tS+die_time;
+    if (tmps->p.type==MT_SOLAR_FLARE)
+      tmpm->type=MT_ION;
+    else
+      tmpm->type=MT_ANTIMATTER_SPLAT;
+    D3Copy(&tmpm->DxDt,&tmps->p.DxDt);
+    tmpm->DxDt+=50*Sqr(tmps->radius)*Rand*
+          Sin(start+theta+(end-start)*i/tmps->splats);
+    tmpm->DyDt+=50*Sqr(tmps->radius)*Rand*
+          Cos(start+theta+(end-start)*i/tmps->splats);
+    QueIns(tmpm,ode->last_mass);
+  }
+}
+
+U0 ExpireShots()
+{
+  Shot *tmps=shot_head.next,*tmps1;
+  while (tmps!=&shot_head) {
+    tmps1=tmps->next;
+    if (tS>tmps->fuse_time) {
+      if (tmps->p.type==MT_SOLAR_FLARE)
+        SplatNew(tmps,1.0,3*pi/8,5*pi/8);
+      else
+        SplatNew(tmps,.2,0,2*pi);
+      QueRem(tmps);
+      QueRem(&tmps->p);
+      Free(tmps);
+    }
+    tmps=tmps1;
+  }
+}
+
+U0 ExpireSplats()
+{
+  MyMass *tmpm,*tmpm1;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=tmpm->next;
+    if ((tmpm->type==MT_ION || tmpm->type==MT_ANTIMATTER_SPLAT) &&
+          tS>tmpm->die_timeout) {
+      QueRem(tmpm);
+      Free(tmpm);
+    }
+    tmpm=tmpm1;
+  }
+}
+
+U0 ExpireMissiles()
+{
+  I64 i;
+  F64 dd,best_dd;
+  Missile *tmpmi=missile_head.next,*tmpm1;
+  while (tmpmi!=&missile_head) {
+    tmpm1=tmpmi->next;
+    if (tmpmi->launched) {
+      best_dd=F64_MAX;
+      if (tmpmi->target)
+        for (i=0;i<tmpmi->target->masses;i++) {
+          dd=D3DistSqr(&tmpmi->p_front.x,&tmpmi->target->p[i].x);
+          if (dd<best_dd)
+            best_dd=dd;
+        }
+      if (!tmpmi->exploding && (best_dd<30*30 || tS>tmpmi->fuse_time)) {
+        tmpmi->p_front.mass=10.0; //They go flying, if too light.
+        tmpmi->p_back.mass =10.0;
+        tmpmi->exploding=TRUE;
+        Noise(50,93,105);
+      } else if (tS>tmpmi->die_timeout)
+        MissileDel(tmpmi);
+    }
+    tmpmi=tmpm1;
+  }
+}
+
+//********************************** AI
+
+U0 AI()
+{
+  CD3 p,p1,p2;
+  Ship *tmpsp=ship_head.next;
+  if (human && !human->exploding) {
+    while (tmpsp!=&ship_head) {
+      D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x);
+      D3Sub(&p2,&tmpsp->p[0].x,&tmpsp->p[2].x);
+      D3Add(&p,&p1,&p2);
+      D3Sub(&p1,&human->p[0].x,&tmpsp->p[0].x);
+      if (D3Dot(D3Unit(&p),D3Unit(&p1))>0.995 &&
+            tS>tmpsp->reload_timeout) {
+        FireOneGun(tmpsp,0,1.5+.5,.4);
+      }
+      tmpsp=tmpsp->next;
+    }
+  }
+}
+
+//********************************** Init
+U0 InitLevel()
+{
+  I64 i;
+  MyMass *tmpm,*tmpm1;
+
+  t_solar_storm=0;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=tmpm->next;
+    if (tmpm->type==MT_ION || tmpm->type==MT_ANTIMATTER_SPLAT) {
+      QueRem(tmpm);
+      Free(tmpm);
+    }
+    tmpm=tmpm1;
+  }
+  if (level==1)
+    OneTimePopUp(&msg_flags,XMSGF_SOLAR_STORM,
+          "Face away from Sun in solar storm.\n");
+  if (level==4)
+    OneTimePopUp(&msg_flags,XMSGF_ANTISPIN,
+          "Press $GREEN$<CURSOR-DOWN>$FG$ for anti-spin stabilizer.\n");
+  human=ShipNew(Fs->pix_width/2,Fs->pix_height/2,ST_HUMAN1);
+  for (i=0;i<level+2;i++)
+    PlaceShip(ST_ENEMY1);
+  PlaceShip(ST_ENEMY2);
+  show_level_msg=TRUE;
+  ODEPause(ode);
+}
+
+U0 Init()
+{
+  I64 i;
+  game_over=FALSE;
+  score=0;
+  level=1;
+
+  QueInit(&ship_head);
+  QueInit(&shot_head);
+  QueInit(&missile_head);
+
+  for (i=0;i<STARS_NUM;i++) {
+    stars_x[i]=RandU16%GR_WIDTH;
+    stars_y[i]=RandU16%GR_HEIGHT;
+  }
+
+  human_t_left=0;
+  human_t_right=0;
+  human_antispin=0;
+
+  InitLevel;
+}
+
+//********************************** Main
+U0 XCaliber()
+{
+  I64 ch,msg_code,arg1,arg2,sc;
+  CCtrl *cp=CtrlPanelNew;
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+WHITE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Game {"
+        "  Restart(,'\n');"
+        "  LevelUp(,'+');"
+        "  LevelDown(,'-');"
+        "}"
+        "Play {"
+        "  Fire(,CH_SPACE);"
+        "  Thrust(,,SC_CURSOR_UP);"
+        "  StopSpin(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  LeftMissile(,,SC_CURSOR_LEFT|SCF_CTRL);"
+        "  RightMissile(,,SC_CURSOR_RIGHT|SCF_CTRL);"
+        "  Spackwalk(,'w');"
+        "  LongerFuse(,,SC_CURSOR_RIGHT|SCF_SHIFT);"
+        "  ShorterFuse(,,SC_CURSOR_LEFT|SCF_SHIFT);"
+        "  LargerShot(,,SC_CURSOR_UP|SCF_SHIFT);"
+        "  SmallerShot(,,SC_CURSOR_DOWN|SCF_SHIFT);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  Fs->draw_it=&DrawIt;
+  do {
+    ode=ODENew(0,0.01,ODEF_HAS_MASSES);
+    ode->derive=&MyDerivative;
+    ode->min_tolerance=1e-9;
+    ode->drag_v3=0.00001;
+    Init;
+    QueIns(ode,Fs->last_ode);
+    ch=0;
+    do {
+      while (!game_over && !show_level_msg &&
+            (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP))) {
+        switch (msg_code) {
+          case MSG_KEY_DOWN:
+            ch=arg1; sc=arg2;
+            switch (ch) {
+              case 0:
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    if (sc&SCF_CTRL)
+                      HumanFireMissileBegin(0);
+                    else if (sc&SCF_SHIFT)
+                      ctrl_panel.fuse_time+=2;
+                    else
+                      human_t_right=THRUST_MAX;
+                    break;
+                  case SC_CURSOR_LEFT:
+                    if (sc&SCF_CTRL)
+                      HumanFireMissileBegin(1);
+                    else if (sc&SCF_SHIFT)
+                      ctrl_panel.fuse_time-=2;
+                    else
+                      human_t_left =THRUST_MAX;
+                    break;
+                  case SC_CURSOR_UP:
+                    if (sc&SCF_SHIFT)
+                      ctrl_panel.shot_radius+=2;
+                    else {
+                      human_t_right=THRUST_MAX;
+                      human_t_left =THRUST_MAX;
+                    }
+                    break;
+                  case SC_CURSOR_DOWN:
+                    if (sc&SCF_SHIFT)
+                      ctrl_panel.shot_radius-=2;
+                    else
+                      human_antispin=ANTISPIN_MAX;
+                    break;
+                }
+                break;
+              case CH_SPACE:
+                if (level<4)
+                  HumanFireGunBegin;
+                else
+                  HumanFireLaserBegin;
+                break;
+              case 'w':
+                ctrl_panel.spacewalk=TRUE;
+                break;
+              case '+':
+                level++;
+                break;
+              case '-':
+                level--;
+                break;
+            }
+            break;
+          case MSG_KEY_UP:
+            ch=arg1; sc=arg2;
+            switch (ch) {
+              case 0:
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    human_t_right=0;
+                    break;
+                  case SC_CURSOR_LEFT:
+                    human_t_left =0;
+                    break;
+                  case SC_CURSOR_UP:
+                    human_t_right=0;
+                    human_t_left =0;
+                    break;
+                  case SC_CURSOR_DOWN:
+                    human_antispin=0;
+                    break;
+                }
+                break;
+              case '\n':
+                ch=0;
+                break;
+              case CH_SPACE:
+                if (level>=4)
+                  HumanFireLaserEnd;
+                break;
+            }
+            break;
+        }
+      }
+      AI;
+      SolarFlares;
+      ExpireShots;
+      ExpireSplats;
+      ExpireMissiles;
+      CheckDamage;
+      Refresh; //msgs are only qued by winmgr
+      if (show_level_msg) {
+        ch=GetKey(&sc);
+        if (ch=='\n')
+          ch=0;
+        ODEPause(ode,OFF);
+        show_level_msg=FALSE;
+      } else if (game_over) {
+        ch=ScanChar;
+      } else {
+        if (!remaining) {
+          level++;
+          ShipDel(human);
+          human=NULL;
+          InitLevel;
+        }
+      }
+    } while (ch!=CH_ESC && ch!='\n' && ch!=CH_SHIFT_ESC);
+    AllDel(ode);
+  } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  SettingsPop;
+  CtrlPanelDel(cp);
+  MenuPop;
+  RegWrite("TempleOS/XCaliber",
+        "I64 best_score=%d;\n"
+        "I64 msg_flags=%d;\n",best_score,msg_flags);
+}
+
+ diff --git a/public/Wb/Apps/X-Caliber/XCCtrls.HC.HTML b/public/Wb/Apps/X-Caliber/XCCtrls.HC.HTML new file mode 100755 index 0000000..d669b5e --- /dev/null +++ b/public/Wb/Apps/X-Caliber/XCCtrls.HC.HTML @@ -0,0 +1,185 @@ + + + + + + + + + + + +
+#define LASER_TEMP_MAX          30.0
+#define LASER_THRESHOLD_TEMP    10.0
+#define MASS_TEMP_MAX           5.0
+
+class CtrlPanelState
+{
+  I64 shot_radius,fuse_time;
+  F64 laser_temperature;
+  Bool spacewalk;
+} ctrl_panel;
+
+#define CTRL_PANEL_SPACING 33
+#define CTRL_PANEL_RANGE   30
+#define CTRL_PANEL_BORDER  2
+#define CTRL_PANEL_BTTN_SIZE    12
+
+#define TMP_Y   (+2)
+
+U0 DrawCtrlPanelCtrl(CDC *dc,CCtrl *c)
+{
+  CtrlPanelState *s=c->state;
+  F64 d,d_range;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,CTRL_PANEL_SPACING*3+2,
+        CTRL_PANEL_SPACING*2+CTRL_PANEL_RANGE+CTRL_PANEL_BTTN_SIZE);
+  dc->color=DKGRAY;
+  GrRect(dc, c->left+CTRL_PANEL_BORDER,c->top+CTRL_PANEL_BORDER,
+        CTRL_PANEL_SPACING*3+2-2*CTRL_PANEL_BORDER,
+        CTRL_PANEL_SPACING*2+CTRL_PANEL_RANGE+CTRL_PANEL_BTTN_SIZE
+        -2*CTRL_PANEL_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+CTRL_PANEL_SPACING,(c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING,c->left+CTRL_PANEL_SPACING,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE-1);
+  GrLine(dc,c->left+2*CTRL_PANEL_SPACING+1,(c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING,c->left+2*CTRL_PANEL_SPACING+1,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE-1);
+
+  dc->color=BLACK;
+  GrRect(dc,(c->left+c->right+1)/2-9*FONT_WIDTH/2-3,
+        c->top+CTRL_PANEL_BORDER+(CTRL_PANEL_SPACING-FONT_HEIGHT)/2,
+        9*FONT_WIDTH+6,FONT_HEIGHT+6);
+
+  if (s->spacewalk)
+    dc->color=YELLOW;
+  else
+    dc->color=DKGRAY;
+  GrRect(dc,(c->left+c->right+1)/2-9*FONT_WIDTH/2-2,
+        c->top+CTRL_PANEL_BORDER+1+(CTRL_PANEL_SPACING-FONT_HEIGHT)/2,
+        9*FONT_WIDTH+4,FONT_HEIGHT+4);
+
+  dc->color=RED;
+  GrPrint(dc,(c->left+c->right+1)/2-9*FONT_WIDTH/2,
+        c->top+CTRL_PANEL_BORDER+3+
+        (CTRL_PANEL_SPACING-FONT_HEIGHT)/2,"SpaceWalk");
+  GrPrint(dc,c->left+CTRL_PANEL_SPACING-4*FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING-FONT_HEIGHT-2,"Size");
+  GrPrint(dc,c->left+2*CTRL_PANEL_SPACING+1-4*FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING-FONT_HEIGHT-2,"Fuse");
+  dc->color=LTRED;
+  GrPrint(dc,c->left+CTRL_PANEL_SPACING-FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE+3,
+        "%d",s->shot_radius*10/CTRL_PANEL_RANGE);
+  GrPrint(dc,c->left+2*CTRL_PANEL_SPACING+1-FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE+3,
+        "%d",s->fuse_time*10/CTRL_PANEL_RANGE);
+  GrRect(dc,c->left+CTRL_PANEL_SPACING-3,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->shot_radius-2 ,7,5);
+  GrRect(dc,c->left+2*CTRL_PANEL_SPACING+1-3,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->fuse_time-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+CTRL_PANEL_SPACING-2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->shot_radius-1 ,5,3);
+  GrRect(dc,c->left+2*CTRL_PANEL_SPACING+1-2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->fuse_time-1,5,3);
+
+  d_range=c->right-c->left-5-5;
+  d=s->laser_temperature*d_range/LASER_TEMP_MAX;
+  dc->color=BLACK;
+  GrRect(dc,c->left+5-1,c->bottom+TMP_Y-2,d_range+2,2+1+1);
+  if (d>1.0) {
+    dc->color=GREEN;
+    GrRect(dc,c->left+5,c->bottom+TMP_Y-1,Min(d,d_range/3),2);
+    if (d>=d_range/3) {
+      dc->color=YELLOW;
+      GrRect(dc,c->left+5+d_range/3,c->bottom+TMP_Y-1,
+            Min(d,2*d_range/3)-d_range/3,2);
+      if (d>=2*d_range/3) {
+        dc->color=RED;
+        GrRect(dc,c->left+5+2*d_range/3,c->bottom+TMP_Y-1,d-2*d_range/3,2);
+      }
+    }
+  }
+}
+
+U0 UpdateDerivedCtrlPanelCtrl(CCtrl *c)
+{
+  CtrlPanelState *s=c->state;
+  c->left=c->win_task->pix_width-(CTRL_PANEL_SPACING*3+2);
+  c->right=c->left+CTRL_PANEL_SPACING*3+2;
+  c->top=c->win_task->pix_height-(CTRL_PANEL_SPACING*2+
+        CTRL_PANEL_RANGE+CTRL_PANEL_BTTN_SIZE);
+  c->bottom=c->top+CTRL_PANEL_SPACING*2+CTRL_PANEL_RANGE;
+
+  s->shot_radius=ClampI64(s->shot_radius,0,CTRL_PANEL_RANGE-1);
+  s->fuse_time=ClampI64(s->fuse_time,0,CTRL_PANEL_RANGE-1);
+}
+
+U0 LeftClickCtrlPanel(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CtrlPanelState *s=c->state;
+  if (y<c->top+CTRL_PANEL_BORDER+(CTRL_PANEL_SPACING-FONT_HEIGHT)/2+
+        FONT_HEIGHT+6)
+    s->spacewalk=TRUE;
+  else {
+    if (x<(c->right+c->left)/2)
+      s->shot_radius=CTRL_PANEL_RANGE-1
+            -(y-(c->top+CTRL_PANEL_SPACING+CTRL_PANEL_BTTN_SIZE));
+    else
+      s->fuse_time=CTRL_PANEL_RANGE-1
+            -(y-(c->top+CTRL_PANEL_SPACING+CTRL_PANEL_BTTN_SIZE));
+  }
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *CtrlPanelNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  MemSet(&ctrl_panel,0,sizeof(ctrl_panel));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&ctrl_panel;
+  c->draw_it=&DrawCtrlPanelCtrl;
+  c->left_click=&LeftClickCtrlPanel;
+  c->update_derived_vals=&UpdateDerivedCtrlPanelCtrl;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 CtrlPanelDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Compiler/Asm.HC.HTML b/public/Wb/Compiler/Asm.HC.HTML new file mode 100755 index 0000000..851864f --- /dev/null +++ b/public/Wb/Compiler/Asm.HC.HTML @@ -0,0 +1,1145 @@ + + + + + + + + + + + +
+Bool PrsAsmImm(CCmpCtrl *cc,CAsmArg *arg)
+{
+  if (arg->imm_or_off_present)
+    LexExcept(cc,"Already one immediate at ");
+  arg->imm_or_off_present=TRUE;
+  arg->num.local_asm_undef_hash=NULL;
+  arg->num.glbl_asm_undef_hash=NULL;
+  cc->asm_undef_hash=NULL;
+  cc->abs_cnts=0;
+  cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);
+  if (!IsLexExpression2Bin(cc,&arg->num.machine_code))
+    LexSkipEol(cc);
+  else {
+    if (cc->abs_cnts.externs)
+      LexExcept(cc,"Extern Not Allowed at ");
+    if (cc->flags & CCF_UNRESOLVED) {
+      if (cc->flags & CCF_LOCAL) {
+        arg->num.local_asm_undef_hash=cc->asm_undef_hash;
+        cc->asm_undef_hash=NULL;
+      } else {
+        arg->num.glbl_asm_undef_hash=cc->asm_undef_hash;
+        cc->asm_undef_hash=NULL;
+      }
+    } else {
+      arg->num.i=Call(arg->num.machine_code);
+      arg->num.glbl_asm_undef_hash=cc->asm_undef_hash;
+      cc->asm_undef_hash=NULL;
+      Free(arg->num.machine_code);
+      arg->num.machine_code=NULL;
+    }
+  }
+  return TRUE;
+}
+
+U0 PrsAsmArg(CCmpCtrl *cc,CAsmArg *arg,Bool rel)
+{
+  CHashGeneric *tmph,*tmph1;
+  CHashReg *tmpr;
+  MemSet(arg,0,sizeof(CAsmArg));
+  arg->seg =REG_NONE;
+  arg->reg1=REG_NONE;
+  arg->reg2=REG_NONE;
+  arg->scale=1;
+  while (TRUE) {
+    if (cc->token==TK_IDENT) {
+      if (tmph=cc->hash_entry) {
+        if (tmph->type&HTG_TYPE_MASK==HTT_REG) {
+          tmpr=tmph;
+          arg->reg1_type=tmpr->reg_type;
+          switch (tmpr->reg_type) {
+            start:
+              case REGT_R8:
+                arg->size=1;
+                break;
+              case REGT_R16:
+                arg->size=2;
+                break;
+              case REGT_R32:
+                arg->size=4;
+                break;
+              case REGT_R64:
+                arg->size=8;
+                break;
+            end:
+              arg->reg1=tmpr->reg_num;
+              Lex(cc);
+              return;
+            case REGT_SEG:
+              arg->seg=tmpr->reg_num;
+              if (Lex(cc)!=':') {
+                arg->just_seg=TRUE;
+                return;
+              } else
+                Lex(cc); //skip ":"
+              break;
+            case REGT_FSTK:
+            case REGT_MM:
+            case REGT_XMM:
+              arg->size=8;
+              arg->reg1=tmpr->reg_num;
+              Lex(cc);
+              return;
+          }
+        } else {
+          if ((tmph->type&HTG_TYPE_MASK==HTT_CLASS||
+                tmph->type&HTG_TYPE_MASK==HTT_INTERNAL_TYPE) &&
+                (tmph1=HashFind(cc->cur_str,cmp.asm_hash,HTT_ASM_KEYWORD)))
+            tmph=tmph1;
+          if (tmph->type&HTG_TYPE_MASK==HTT_ASM_KEYWORD) {
+            switch (tmph->user_data0) {
+              case AKW_I8:
+              case AKW_U8:
+                arg->size=1;
+                break;
+              case AKW_I16:
+              case AKW_U16:
+                arg->size=2;
+                break;
+              case AKW_I32:
+              case AKW_U32:
+                arg->size=4;
+                break;
+              case AKW_I64:
+              case AKW_U64:
+                arg->size=8;
+                break;
+              default:
+                LexExcept(cc,"syntax error at ");
+            }
+            Lex(cc); //skip keyword
+          } else
+            goto pa_asm_direct_imm;
+        }
+      } else {
+pa_asm_direct_imm:
+        PrsAsmImm(cc,arg);
+        arg->num.abs_cnts=cc->abs_cnts;
+        if (arg->size<=1 && !rel && arg->num.abs_cnts&1) {
+          if (cc->aotc->seg_size==16)
+            arg->size=2;
+          else
+            arg->size=4;
+        }
+        if (cc->token!='[')
+          return;
+      }
+    } else if (cc->token=='[') {
+      arg->indirect=TRUE;
+      Lex(cc); // skip [
+      while (cc->token && cc->token!=']') {
+        if (cc->token==TK_IDENT) {
+          if (tmph=cc->hash_entry) {
+            if (tmph->type&HTG_TYPE_MASK==HTT_REG &&
+                  REGT_R16<=tmph(CHashReg *)->reg_type<=REGT_R64) {
+              tmpr=tmph;
+              arg->reg2_type=tmpr->reg_type;
+              if (arg->reg1==REG_NONE) {
+                if (tmpr->reg_num&7==REG_RSP) {
+                  arg->reg1=4;
+                  arg->reg2=tmpr->reg_num;
+                } else
+                  arg->reg1=tmpr->reg_num;
+              } else
+                arg->reg2=tmpr->reg_num;
+              Lex(cc);
+            } else
+              goto pa_asm_indirect_imm;
+          } else
+            goto pa_asm_indirect_imm;
+        } else if (cc->token=='*') {
+          Lex(cc);
+          if (cc->token!=TK_I64)
+            LexExcept(cc,"Expecting scale factor at ");
+          arg->scale=cc->cur_i64;
+          Lex(cc); //skip scale
+          if (arg->reg2!=REG_NONE) {
+            SwapI64(&arg->reg1,&arg->reg2);
+            SwapI64(&arg->reg1_type,&arg->reg2_type);
+          }
+        } else if (cc->token=='+') {
+          Lex(cc); //skip '+'
+        } else {
+pa_asm_indirect_imm:
+          PrsAsmImm(cc,arg);
+          arg->num.abs_cnts=cc->abs_cnts;
+        }
+      }
+      if (cc->token!=']')
+        LexExcept(cc,"Missing ']' at ");
+      Lex(cc); //skip ]
+      return;
+    } else
+      goto pa_asm_direct_imm;
+  }
+}
+
+I64 AsmMakeArgMask(CCmpCtrl *cc,CAsmArg *arg)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 res;
+  if (arg->just_seg) {
+    switch (arg->seg) {
+      case 0: res=1<<ARGT_ES|1<<ARGT_SREG; break;
+      case 1: res=1<<ARGT_CS|1<<ARGT_SREG; break;
+      case 2: res=1<<ARGT_SS|1<<ARGT_SREG; break;
+      case 3: res=1<<ARGT_DS|1<<ARGT_SREG; break;
+      case 4: res=1<<ARGT_FS|1<<ARGT_SREG; break;
+      case 5: res=1<<ARGT_GS|1<<ARGT_SREG; break;
+    }
+    goto mm_done;
+  }
+  if (arg->reg1_type==REGT_FSTK) {
+    if (arg->reg1)
+      res=1<<ARGT_STI;
+    else
+      res=1<<ARGT_ST0|1<<ARGT_STI;
+    goto mm_done;
+  }
+  res=cmp.size_arg_mask[arg->size];
+  if (aotc->seg_size==64)
+    res&=0xFF0FFFFFFF;
+
+  if (arg->reg1!=REG_NONE && arg->imm_or_off_present && !arg->num.i &&
+        !arg->num.glbl_asm_undef_hash && !arg->num.local_asm_undef_hash)
+    arg->imm_or_off_present=FALSE;  //Zero displacement
+
+  if (arg->reg2!=REG_NONE || arg->scale!=1) {
+    res&=0x0000FF0000;
+    goto mm_done;
+  }
+
+  if (arg->indirect) {
+    if (arg->imm_or_off_present)
+      res&=0x00FFFF0000;
+    else
+      res&=0x000FFF0000;
+  } else {
+    if (arg->imm_or_off_present)
+      res&=0x000F000FFE;
+    else
+      res&=0x3F0FFFF000;
+  }
+  if (arg->seg!=REG_NONE)
+    res&=0x00FFFF0000;
+  if (arg->reg1==REG_NONE) {
+    if (arg->indirect)
+      res&=0x00FFFF0000;
+    else if (arg->num.i<0) {
+      if (arg->num.i>=I8_MIN)
+        res&=0x8FE;
+      else if (arg->num.i>=I16_MIN)
+        res&=0x8EE;
+      else if (arg->num.i>=I32_MIN)
+        res&=0x8CE;
+      else
+        res&=0x88E;
+    } else {
+      if (arg->num.i<=I8_MAX)
+        res&=0xFFE;
+      else if (arg->num.i<=U8_MAX)
+        res&=0xFEE;
+      else if (arg->num.i<=I16_MAX)
+        res&=0xEEE;
+      else if (arg->num.i<=U16_MAX)
+        res&=0xECE;
+      else if (arg->num.i<=I32_MAX)
+        res&=0xCCE;
+      else if (arg->num.i<=U32_MAX)
+        res&=0xC8E;
+      else
+        res&=0x88E;
+    }
+  } else {
+    res&=  0x3F00FFF000;
+    if (!arg->indirect) //M8-M64
+      res&=0xFFFF0FFFFF;
+  }
+  switch (arg->reg1) {
+    case REG_RAX: res&=~0x3000000000; break;
+    case REG_RCX: res&=~0x2F00000000; break;
+    case REG_RDX: res&=~0x1F00000000; break;
+    default:      res&=~0x3F00000000;
+  }
+mm_done:
+  return res;
+}
+
+Bool AsmStoreNum(CCmpCtrl *cc,CAsmNum2 *num2,I64 cnt,Bool U8_avail)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i;
+  CAOTAbsAddr *tmpa;
+
+  if (!num2->imm_flag)
+    num2->num.i-=num2->rel;
+  for (i=0;i<cnt;i++) {
+    if (num2->U8_cnt==1) {
+      if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+        AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I8+num2->imm_flag,
+              aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+              num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+              U8_avail);
+      else if (!num2->imm_flag && !(I8_MIN<=num2->num.i<=I8_MAX))
+        LexExcept(cc,"Branch out of range at ");
+      if (num2->imm_flag) {
+        if (num2->num.abs_cnts.abs_addres&1) {
+          tmpa=CAlloc(sizeof(CAOTAbsAddr));
+          tmpa->next=aotc->abss;
+          aotc->abss=tmpa;
+          tmpa->rip=aotc->rip;
+          tmpa->type=AAT_ADD_U8;
+        }
+      } else {
+        if (num2->num.abs_cnts.c_addres&1) {
+          tmpa=CAlloc(sizeof(CAOTAbsAddr));
+          tmpa->next=aotc->abss;
+          aotc->abss=tmpa;
+          tmpa->rip=aotc->rip;
+          tmpa->type=AAT_SUB_U8;
+        }
+      }
+      AOTStoreCodeU8(cc,num2->num.i);
+    } else {
+      if (num2->U8_cnt==2) {
+        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I16+num2->imm_flag,
+                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+                U8_avail);
+        else if (!num2->imm_flag && !(I16_MIN<=num2->num.i<=I16_MAX))
+          LexExcept(cc,"Branch out of range at ");
+        if (num2->imm_flag) {
+          if (num2->num.abs_cnts.abs_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_ADD_U16;
+          }
+        } else {
+          if (num2->num.abs_cnts.c_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_SUB_U16;
+          }
+        }
+        AOTStoreCodeU8(cc,num2->num.i.u8[0]);
+        AOTStoreCodeU8(cc,num2->num.i.u8[1]);
+      } else if (num2->U8_cnt==4) {
+        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I32+num2->imm_flag,
+                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+                U8_avail);
+        else if (!num2->imm_flag && !(I32_MIN<=num2->num.i<=I32_MAX))
+          LexExcept(cc,"Branch out of range at ");
+        if (num2->imm_flag) {
+          if (num2->num.abs_cnts.abs_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_ADD_U32;
+          }
+        } else {
+          if (num2->num.abs_cnts.c_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_SUB_U32;
+          }
+        }
+        AOTStoreCodeU32(cc,num2->num.i);
+      } else if (num2->U8_cnt==8) {
+        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I64+num2->imm_flag,
+                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+                U8_avail);
+        if (num2->imm_flag) {
+          if (num2->num.abs_cnts.abs_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_ADD_U64;
+          }
+        } else {
+          if (num2->num.abs_cnts.c_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_SUB_U64;
+          }
+        }
+        AOTStoreCodeU64(cc,num2->num.i);
+      }
+      if (U8_avail && !num2->num.local_asm_undef_hash &&
+            !num2->num.glbl_asm_undef_hash &&
+            !num2->imm_flag && -124<=num2->num.i<=123) {
+        LexWarn(cc,"could use I8 displacement at ");
+        return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+U8 asm_seg_prefixes[6]={0x26,0x2E,0x36,0x3E,0x64,0x65};
+
+Bool PrsAsmInst(CCmpCtrl *cc,CHashOpcode *tmpo,I64 argcnt)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i,j,arg1,arg2,om,seg,arg1mask,arg2mask;
+  CAsmArg *tmpa1,*tmpa2;
+  Bool ModrM_complete,U8_avail=FALSE,found_second_possible=FALSE;
+  CInst *tmpins;
+  CAsmIns cur,best;
+
+  best.U8_cnt=255;
+  if (argcnt>0)
+    arg1mask=AsmMakeArgMask(cc,&aotc->arg1);
+  else
+    arg1mask=1;
+  if (argcnt>1)
+    arg2mask=AsmMakeArgMask(cc,&aotc->arg2);
+  else
+    arg2mask=1;
+  for (i=0;i<tmpo->inst_entry_cnt;i++) {
+    tmpins=&tmpo->ins[i];
+    if (tmpins->arg1==ARGT_REL8 || tmpins->arg2==ARGT_REL8)
+      U8_avail=TRUE;
+    if (Bt(&arg1mask,tmpins->arg1) && Bt(&arg2mask,tmpins->arg2) &&
+          (!(tmpins->flags&IEF_NOT_IN_64_BIT) || aotc->seg_size!=64)) {
+      MemSet(&cur,0,sizeof(CAsmIns));
+      cur.tmpins=tmpins;
+      ModrM_complete=FALSE;
+      cur.is_dft=ToBool(tmpins->flags & IEF_DFT);
+      if (aotc->seg_size==64) {
+        if (tmpins->flags & IEF_48_REX)
+          cur.REX=0x48;
+        else
+          cur.REX=0x40;
+      }
+      cur.disp.imm_flag=TRUE;
+      cur.imm.imm_flag=TRUE;
+      om=tmpins->opcode_modifier;
+      arg1=tmpins->arg1;
+      arg2=tmpins->arg2;
+      tmpa1=&aotc->arg1;
+      tmpa2=&aotc->arg2;
+      cur.last_opcode_U8=tmpins->opcode[tmpins->opcode_cnt-1];
+
+      if (tmpins->slash_val<8) {
+        cur.ModrM|=tmpins->slash_val<<3;
+        cur.has_ModrM=TRUE;
+      }
+
+      if (aotc->seg_size==16 && tmpins->flags & IEF_OP_SIZE32 ||
+            aotc->seg_size!=16 && tmpins->flags & IEF_OP_SIZE16)
+        cur.has_operand_prefix=TRUE;
+
+      if (om==OM_IB)      cur.imm.U8_cnt=1;
+      else if (om==OM_IW) cur.imm.U8_cnt=2;
+      else if (om==OM_ID) cur.imm.U8_cnt=4;
+
+      if (om==OM_CB) {
+        cur.imm.U8_cnt=1;
+        cur.imm.imm_flag=FALSE;
+      } else if (om==OM_CW) {
+        cur.imm.U8_cnt=2;
+        cur.imm.imm_flag=FALSE;
+      } else if (om==OM_CD) {
+        cur.imm.U8_cnt=4;
+        cur.imm.imm_flag=FALSE;
+      }
+
+      if (argcnt==1) {
+        if (best.U8_cnt!=255 && !found_second_possible && !best.is_dft) {
+          found_second_possible=TRUE;
+          if (!aotc->arg1.size)
+            PrintWarn("no size specified at %s,%04d\n",
+                  cc->lex_include_stk->full_name,
+                  cc->lex_include_stk->line_num-1);
+        }
+        if (tmpins->flags & IEF_PLUS_OPCODE) {
+          if (tmpins->slash_val==SV_R_REG) {
+            cur.last_opcode_U8|=tmpa1->reg1&7;
+            if (tmpa1->reg1&15>7)
+              cur.REX|=1;
+            if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+              cur.has_REX=TRUE;
+          } else {//SV_I_REG
+            if (tmpa1->reg1_type==REGT_FSTK)
+              cur.last_opcode_U8+=tmpa1->reg1;
+          }
+        }
+        if (arg1==ARGT_R64 || arg1==ARGT_RM64 || arg1==ARGT_M64)
+          cur.REX|=8;
+        if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_M8<=arg1<=ARGT_M64) {
+          if (aotc->seg_size==16)
+            cur.has_addr_prefix=TRUE;
+
+          cur.has_ModrM=TRUE;
+          if (tmpa1->imm_or_off_present && tmpa1->indirect &&
+                tmpa1->reg1==REG_NONE) {
+            cur.ModrM=cur.ModrM+5;
+            MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+            cur.disp.U8_cnt=4;
+            if (aotc->seg_size==64)
+              cur.disp.imm_flag=FALSE;
+          } else {
+            if (tmpa1->reg2==REG_NONE && tmpa1->scale==1) {
+              cur.ModrM|=tmpa1->reg1&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            } else {
+              cur.ModrM|=4;
+              cur.has_SIB=TRUE;
+              if (tmpa1->scale==1)
+                cur.SIB=0;
+              else if (tmpa1->scale==2)
+                cur.SIB=0x40;
+              else if (tmpa1->scale==4)
+                cur.SIB=0x80;
+              else if (tmpa1->scale==8)
+                cur.SIB=0xC0;
+              if (tmpa1->reg2==REG_NONE) {
+                ModrM_complete=TRUE;
+                cur.SIB|=(tmpa1->reg1&7)<<3+REG_RBP;
+                if (tmpa1->reg1&15>7)
+                  cur.REX|=2;
+                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+                cur.disp.U8_cnt=4;
+              } else {
+                cur.SIB|=(tmpa1->reg1&7)<<3+tmpa1->reg2&7;
+                if (tmpa1->reg1&15>7)
+                  cur.REX|=2;
+                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+                if (tmpa1->reg2&15>7)
+                  cur.REX|=1;
+                if (tmpa1->reg2>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+                if (tmpa1->reg2&7==REG_RBP &&
+                      !tmpa1->imm_or_off_present && tmpa1->indirect) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                  ModrM_complete=TRUE;
+                }
+              }
+            }
+            if (!ModrM_complete) {
+              if (tmpa1->imm_or_off_present) {
+                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+                if (!cur.disp.num.machine_code &&
+                      I8_MIN<=cur.disp.num.i<=I8_MAX) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                } else if (aotc->seg_size==16) {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=2;
+                } else {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=4;
+                }
+              } else if (!tmpa1->indirect) {
+                cur.has_addr_prefix=FALSE;
+                cur.ModrM|=0xC0;
+              } else {
+                if (tmpa1->reg1&7==REG_RBP) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                }
+              }
+            }
+          }
+        } else if (ARGT_REL8<=arg1<=ARGT_REL32 || ARGT_IMM8<=arg1<=ARGT_IMM64 ||
+              ARGT_UIMM8<=arg1<=ARGT_UIMM64) {
+          if (arg1==ARGT_IMM64 || arg2==ARGT_UIMM64)
+            cur.REX|=8;
+          MemCpy(&cur.imm.num,&tmpa1->num,sizeof(CAsmNum));
+        }
+      } else if (argcnt==2) {
+        if (best.U8_cnt!=255 && !found_second_possible && !best.is_dft) {
+          found_second_possible=TRUE;
+          if (!aotc->arg1.size && !aotc->arg2.size)
+            PrintWarn("no size specified at %s,%04d\n",
+                  cc->lex_include_stk->full_name,
+                  cc->lex_include_stk->line_num-1);
+        }
+        if (tmpins->flags & IEF_PLUS_OPCODE) {
+          if (tmpins->slash_val==SV_R_REG) {
+            if (ARGT_AL<=arg1<=ARGT_RAX) {
+              cur.last_opcode_U8|=tmpa2->reg1&7;
+              if (tmpa2->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa2->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            } else {
+              cur.last_opcode_U8|=tmpa1->reg1&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            }
+          } else {//SV_I_REG
+            if (tmpa1->reg1_type==REGT_FSTK)
+              cur.last_opcode_U8|=tmpa1->reg1;
+            if (tmpa2->reg1_type==REGT_FSTK)
+              cur.last_opcode_U8|=tmpa2->reg1;
+          }
+        }
+        if (arg1==ARGT_RM64 || arg2==ARGT_RM64 ||
+              arg1==ARGT_M64 || arg2==ARGT_M64 ||
+              arg1==ARGT_R64 || arg2==ARGT_R64)
+          cur.REX|=8;
+        if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_RM8<=arg2<=ARGT_RM64 ||
+              ARGT_M8<=arg1<=ARGT_M64  || ARGT_M8<=arg2<=ARGT_M64) {
+          if (aotc->seg_size==16)
+            cur.has_addr_prefix=TRUE;
+          cur.has_ModrM=TRUE;
+          if (ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
+            tmpa1=&aotc->arg2;
+            tmpa2=&aotc->arg1;
+          }
+          if (tmpins->slash_val==SV_R_REG) {
+            if (tmpa2->just_seg)
+              cur.ModrM|=tmpa2->seg<<3;
+            else {
+              if (tmpa2->reg1==REG_NONE) {
+                cur.ModrM|=(tmpa1->reg1&7)<<3;
+                if (tmpa1->reg1&15>7)
+                  cur.REX|=4;
+                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+              } else {
+                cur.ModrM|=(tmpa2->reg1&7)<<3;
+                if (tmpa2->reg1&15>7)
+                  cur.REX|=4;
+                if (tmpa2->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+              }
+            }
+          }
+          if (tmpa1->reg2==REG_NONE && tmpa1->scale==1) {
+            if (tmpa1->reg1!=REG_NONE) {
+              cur.ModrM|=tmpa1->reg1&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            }
+          } else {
+            cur.ModrM|=4;
+            cur.has_SIB=TRUE;
+            if (tmpa1->scale==1)
+              cur.SIB=0;
+            else if (tmpa1->scale==2)
+              cur.SIB=0x40;
+            else if (tmpa1->scale==4)
+              cur.SIB=0x80;
+            else if (tmpa1->scale==8)
+              cur.SIB=0xC0;
+            if (tmpa1->reg2==REG_NONE) {
+              ModrM_complete=TRUE;
+              cur.SIB|=(tmpa1->reg1&7)<<3+5;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=2;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+              MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+              cur.disp.U8_cnt=4;
+            } else {
+              cur.SIB|=(tmpa1->reg1&7)<<3+tmpa1->reg2&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=2;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+              if (tmpa1->reg2&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg2>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+              if (tmpa1->reg2&7==REG_RBP &&
+                    !tmpa1->imm_or_off_present && tmpa1->indirect) {
+                cur.ModrM|=0x40;
+                cur.disp.U8_cnt=1;
+                ModrM_complete=TRUE;
+              }
+            }
+          }
+          if (!ModrM_complete) {
+            if (tmpa1->imm_or_off_present &&
+                  tmpa1->indirect && tmpa1->reg1==REG_NONE) {
+              cur.ModrM=cur.ModrM&0xF8+5;
+              MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+              cur.disp.U8_cnt=4;
+              if (aotc->seg_size==64)
+                cur.disp.imm_flag=FALSE;
+            } else {
+              if (tmpa1->imm_or_off_present) {
+                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+                if (!cur.disp.num.machine_code &&
+                      I8_MIN<=cur.disp.num.i<=I8_MAX) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                } else if (aotc->seg_size==16) {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=2;
+                } else {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=4;
+                }
+              } else if (!tmpa1->indirect) {
+                cur.has_addr_prefix=FALSE;
+                cur.ModrM|=0xC0;
+              } else {
+                if (tmpa1->reg1&7==REG_RBP) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                }
+              }
+            }
+          }
+        } else if (ARGT_MOFFS8<=arg1<=ARGT_MOFFS64) {
+          MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+          if (aotc->seg_size==16)
+            cur.disp.U8_cnt=2;
+          else
+            cur.disp.U8_cnt=4;
+          cur.has_addr_prefix=FALSE;
+        } else if (ARGT_MOFFS8<=arg2<=ARGT_MOFFS64) {
+          MemCpy(&cur.disp.num,&tmpa2->num,sizeof(CAsmNum));
+          if (aotc->seg_size==16)
+            cur.disp.U8_cnt=2;
+          else
+            cur.disp.U8_cnt=4;
+          cur.has_addr_prefix=FALSE;
+        } else if (ARGT_IMM8<=arg1<=ARGT_IMM64 ||
+              ARGT_UIMM8<=arg1<=ARGT_UIMM64) {
+          MemCpy(&cur.imm.num,&tmpa1->num,sizeof(CAsmNum));
+          if (arg1==ARGT_IMM8 || arg1==ARGT_UIMM8) cur.imm.U8_cnt=1;
+          else if (arg1==ARGT_IMM16 || arg1==ARGT_UIMM16) cur.imm.U8_cnt=2;
+          else if (arg1==ARGT_IMM32 || arg1==ARGT_UIMM32) cur.imm.U8_cnt=4;
+          else {
+            cur.imm.U8_cnt=8;
+            cur.REX|=8;
+          }
+        }
+        if (ARGT_IMM8<=arg2<=ARGT_IMM64 ||
+              ARGT_UIMM8<=arg2<=ARGT_UIMM64) {
+          MemCpy(&cur.imm.num,&tmpa2->num,sizeof(CAsmNum));
+          if (arg2==ARGT_IMM8 || arg2==ARGT_UIMM8) cur.imm.U8_cnt=1;
+          else if (arg2==ARGT_IMM16 || arg2==ARGT_UIMM16) cur.imm.U8_cnt=2;
+          else if (arg2==ARGT_IMM32 || arg2==ARGT_UIMM32) {
+            cur.imm.U8_cnt=4;
+            if (tmpins->flags&IEF_REX_ONLY_R8_R15 && arg2==ARGT_UIMM32)
+              cur.REX&=~8;
+          } else {
+            cur.imm.U8_cnt=8;
+            cur.REX|=8;
+          }
+        }
+      }
+      cur.U8_cnt=tmpins->opcode_cnt+cur.disp.U8_cnt+cur.imm.U8_cnt;
+      if (cur.has_ModrM) cur.U8_cnt++;
+      if (cur.has_SIB) cur.U8_cnt++;
+      if (aotc->seg_size==64 && cur.REX&0x40==0x40 &&
+            (cur.REX!=0x40 || cur.has_REX) &&
+            (cur.REX&7 || !(tmpins->flags&IEF_REX_ONLY_R8_R15 ||
+            tmpins->flags&IEF_REX_XOR_LIKE && tmpa1->reg1==tmpa2->reg1 &&
+            cur.ModrM&0xC0==0xC0)))
+        cur.U8_cnt++;
+      if (cur.U8_cnt<best.U8_cnt &&
+            !(tmpins->flags & IEF_DONT_SWITCH_MODES &&
+            (cur.has_addr_prefix || cur.has_operand_prefix)))
+        MemCpy(&best,&cur,sizeof(CAsmIns));
+    }
+  }
+  if (best.U8_cnt<255) {
+    tmpins=best.tmpins;
+    seg=REG_NONE;
+    if (argcnt>1 && aotc->arg2.seg!=REG_NONE && !aotc->arg2.just_seg)
+      seg=aotc->arg2.seg;
+    else if (argcnt>0 && aotc->arg1.seg!=REG_NONE && !aotc->arg1.just_seg)
+      seg=aotc->arg1.seg;
+    if (seg!=REG_NONE)
+      AOTStoreCodeU8(cc,asm_seg_prefixes[seg]);
+    if (best.has_operand_prefix)
+      AOTStoreCodeU8(cc,OC_OP_SIZE_PREFIX); //Operand size override
+    if (best.has_addr_prefix  || aotc->seg_size==16 && cur.has_SIB)
+      AOTStoreCodeU8(cc,OC_ADDR_SIZE_PREFIX); //Operand size override
+    if (aotc->seg_size==64 && best.REX&0x40==0x40 &&
+          (best.REX!=0x40 || best.has_REX) &&
+          (best.REX&7||!(tmpins->flags&IEF_REX_ONLY_R8_R15 ||
+          tmpins->flags&IEF_REX_XOR_LIKE && tmpa1->reg1==tmpa2->reg1 &&
+          best.ModrM&0xC0==0xC0)))
+      AOTStoreCodeU8(cc,best.REX);
+    for (j=0;j<tmpins->opcode_cnt-1;j++)
+      AOTStoreCodeU8(cc,tmpins->opcode[j]);
+    AOTStoreCodeU8(cc,best.last_opcode_U8);
+
+    if (best.has_ModrM)
+      AOTStoreCodeU8(cc,best.ModrM);
+    if (best.has_SIB)
+      AOTStoreCodeU8(cc,best.SIB);
+
+    if (best.disp.U8_cnt) {
+      best.disp.rel=aotc->rip+best.disp.U8_cnt+best.imm.U8_cnt;
+      if (!AsmStoreNum(cc,&best.disp,1,U8_avail))
+        return FALSE;
+    }
+
+    if (best.imm.U8_cnt) {
+      best.imm.rel=aotc->rip+best.imm.U8_cnt;
+      if (!AsmStoreNum(cc,&best.imm,1,U8_avail))
+        return FALSE;
+    }
+    if (tmpins->flags&IEF_ENDING_ZERO) //ENTER inst
+      AOTStoreCodeU8(cc,0);
+    return TRUE;
+  }
+  LexExcept(cc,"Invalid inst at ");
+}
+
+U0 PrsAsmDefine(CCmpCtrl *cc,I64 U8_cnt)
+{
+  Bool is_dup;
+  I64 i,dup_val;
+  U8 *ptr;
+  CAsmNum2 num2;
+  num2.U8_cnt=U8_cnt;
+
+  while (cc->token && cc->token!=';') {
+    num2.num.local_asm_undef_hash=NULL;
+    num2.num.glbl_asm_undef_hash=NULL;
+    if (cc->token==TK_STR) {
+      ptr=cc->cur_str;
+      i=cc->cur_str_len-1;
+      while (i--)
+        AOTStoreCodeU8(cc,*ptr++);
+      Lex(cc);  //Skip Str
+    } else {
+      is_dup=FALSE;
+      cc->abs_cnts=0;
+      cc->asm_undef_hash=NULL;
+      cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);
+      if (!IsLexExpression2Bin(cc,&num2.num.machine_code))
+        LexSkipEol(cc);
+      else {
+        if (cc->abs_cnts.externs)
+          LexExcept(cc,"Extern Not Allowed at ");
+        if (cc->flags & CCF_UNRESOLVED) {
+          if (cc->flags & CCF_LOCAL) {
+            num2.num.local_asm_undef_hash=cc->asm_undef_hash;
+            cc->asm_undef_hash=NULL;
+          } else {
+            num2.num.glbl_asm_undef_hash=cc->asm_undef_hash;
+            cc->asm_undef_hash=NULL;
+          }
+        } else {
+          i=Call(num2.num.machine_code);
+          Free(num2.num.machine_code);
+        }
+      }
+      if (cc->token==TK_IDENT && cc->hash_entry) {
+        if (cc->hash_entry->type & HTT_ASM_KEYWORD &&
+              cc->hash_entry->user_data0==AKW_DUP) {
+          is_dup=TRUE;
+          if (Lex(cc)!='(')
+            LexExcept(cc,"Expecting '(' at ");
+          Lex(cc); //skip (
+          dup_val=AsmLexExpression(cc);
+          if (cc->token!=')')
+            LexExcept(cc,"Expecting ')' at ");
+          Lex(cc); //SKIP )
+        }
+      }
+      num2.rel=0;
+      num2.imm_flag=TRUE;
+      num2.num.abs_cnts=cc->abs_cnts;
+      if (is_dup) {
+        if (num2.num.local_asm_undef_hash || num2.num.glbl_asm_undef_hash)
+          LexExcept(cc,"Undefined DUP cnt at ");
+        num2.num.i=dup_val;
+        AsmStoreNum(cc,&num2,i,FALSE);
+      } else {
+        num2.num.i=i;
+        AsmStoreNum(cc,&num2,1,FALSE);
+      }
+    }
+    if (cc->token==',')
+      Lex(cc);
+  }
+  if (cc->token!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+}
+
+U0 PrsBinFile(CCmpCtrl *cc)
+{
+  I64 i,size;
+  U8 *buf,*st;
+  if (cc->token!=TK_STR)
+    LexExcept(cc,"Expecting string at ");
+  st=ExtDft(cc->cur_str,"BIN");
+  buf=FileRead(st,&size);
+  Free(st);
+  for (i=0;i<size;i++)
+    AOTStoreCodeU8(cc,buf[i]);
+  if (Lex(cc)!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+}
+
+U0 PrsAsmBlk(CCmpCtrl *cc,I64 cmp_flags)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i,j,k,argcnt,
+        old_flags=cc->flags & CCF_ASM_EXPRESSIONS;
+  CHashOpcode *tmpo;
+  CHashExport *tmpex;
+  U8 *next_last_label;
+  CCodeMisc *g_lb;
+
+  aotc->seg_size=64;
+  cc->flags|=CCF_ASM_EXPRESSIONS;
+  if (!(cmp_flags&CMPF_ONE_ASM_INS)) {
+    if (cc->token!='{')
+      LexExcept(cc,"Expecting '{' at ");
+    Lex(cc);
+  }
+  while (cc->token && cc->token!='}') {
+    AsmLineLst(cc);
+    if (cc->token==TK_IDENT && cc->hash_entry) {
+      if (cc->hash_entry->type&HTT_ASM_KEYWORD) {
+        i=cc->hash_entry->user_data0;
+        Lex(cc); //skip keyword
+        switch (i) {
+          case AKW_IMPORT:
+            while (cc->token && cc->token!=';') {
+              if (cc->token!=TK_IDENT)
+                LexExcept(cc,"Expecting identifier at ");
+              else {
+                tmpex=NULL;
+                tmpex=CAlloc(sizeof(CHashExport));
+                tmpex->str=cc->cur_str;
+                cc->cur_str=0;
+                tmpex->type=HTT_EXPORT_SYS_SYM|HTF_UNRESOLVED;
+                HashAdd(tmpex,cc->htc.glbl_hash_table);
+                tmpex->type|=HTF_IMPORT;
+                if (Lex(cc)==',')
+                  Lex(cc); //skip ','
+              }
+            }
+            if (cc->token!=';')
+              LexExcept(cc,"Missing ';' at");
+            Lex(cc); //skip ';';
+            break;
+          case AKW_ORG:
+            if (cc->htc.local_var_lst)
+              LexExcept(cc,"ORG not allowed in fun asm blk ");
+            if (aotc->org!=INVALID_PTR)
+              LexExcept(cc,"Just one org allowed ");
+            if (aotc->rip)
+              LexExcept(cc,"ORG must be at beginning ");
+            aotc->org=AsmLexExpression(cc);
+            break;
+          case AKW_ALIGN:
+            if (cc->htc.local_var_lst)
+              LexExcept(cc,"ALIGN not allowed in fun asm blk ");
+            i=AsmLexExpression(cc);
+            j=Bsf(i);
+            if (!i || j!=Bsr(i))
+              LexExcept(cc,"ALIGN must be power of two at ");
+            if (!(cc->flags&CCF_AOT_COMPILE) && i>8)
+              LexExcept(cc,"In JIT mode, max ALIGN is 8 ");
+            if (j>aotc->max_align_bits) aotc->max_align_bits=j;
+            i=CeilU64(aotc->rip,i);
+            if (cc->token!=',')
+              LexExcept(cc,"Expecting ',' at ");
+            Lex(cc);
+            k=AsmLexExpression(cc);
+            for (j=aotc->rip;j<i;j++)
+              AOTStoreCodeU8(cc,k);
+            break;
+          case AKW_DU8:
+            PrsAsmDefine(cc,1);
+            break;
+          case AKW_DU16:
+            PrsAsmDefine(cc,2);
+            break;
+          case AKW_DU32:
+            PrsAsmDefine(cc,4);
+            break;
+          case AKW_DU64:
+            PrsAsmDefine(cc,8);
+            break;
+          case AKW_BINFILE:
+            PrsBinFile(cc);
+            break;
+          case AKW_LIST:
+            aotc->lst=TRUE;
+            break;
+          case AKW_NOLIST:
+            aotc->lst=FALSE;
+            break;
+          case AKW_USE16:
+            aotc->seg_size=16;
+            break;
+          case AKW_USE32:
+            aotc->seg_size=32;
+            break;
+          case AKW_USE64:
+            aotc->seg_size=64;
+            break;
+          default:
+            LexExcept(cc,"Syntax error at ");
+        }
+      } else if (cc->hash_entry->type & HTT_OPCODE) {
+        tmpo=cc->hash_entry;
+        Lex(cc); //skip opcode
+        argcnt=0;
+        if (tmpo->ins[0].arg1) {
+          argcnt++;
+          if (ARGT_REL8<=tmpo->ins[0].arg1<=ARGT_REL32)
+            PrsAsmArg(cc,&aotc->arg1,TRUE);
+          else
+            PrsAsmArg(cc,&aotc->arg1,FALSE);
+          if (tmpo->ins[0].arg2) {
+            argcnt++;
+            if (cc->token!=',')
+              LexExcept(cc,"Expecting ',' at ");
+            else {
+              Lex(cc); //skip ','
+              if (ARGT_REL8<=tmpo->ins[0].arg2<=ARGT_REL32)
+                PrsAsmArg(cc,&aotc->arg2,TRUE);
+              else
+                PrsAsmArg(cc,&aotc->arg2,FALSE);
+            }
+          }
+        }
+        PrsAsmInst(cc,tmpo,argcnt);
+      } else if (cc->hash_entry->type & HTT_EXPORT_SYS_SYM) {
+        if (Btr(&cc->hash_entry->type,HTf_UNRESOLVED)) {
+          if (cc->hash_entry->type & HTF_LOCAL) {
+            cc->hash_entry(CHashExport *)->val=aotc->rip;
+            if (Lex(cc)!=':')
+              LexExcept(cc,"Expecting ':' at ");
+            Lex(cc);
+          } else {
+            if (cc->hash_entry->type & HTF_IMPORT)
+              LexExcept(cc,"attempt to define import at ");
+            cc->hash_entry(CHashExport *)->val=aotc->rip;
+            next_last_label=cc->hash_entry->str;
+            Lex(cc); //Skip cur_str
+            if (cc->token!=':' && cc->token!=TK_DBL_COLON)
+              LexExcept(cc,"Expecting ':' at ");
+            if (cc->token==TK_DBL_COLON) {
+              cc->hash_entry->type|=HTF_EXPORT;
+              HashSrcFileSet(cc,cc->hash_entry);
+
+              AOTLocalsResolve(cc);
+              aotc->last_label=next_last_label;
+            }
+            Lex(cc);
+          }
+        } else if (cc->hash_entry(CHashExport *)->val==aotc->rip) {
+          Lex(cc); //Skip cur_str
+          if (cc->token!=':' && cc->token!=TK_DBL_COLON)
+            LexExcept(cc,"Expecting ':' at ");
+          Lex(cc);
+        } else
+          LexExcept(cc,"Redefinition at ");
+      } else
+        LexExcept(cc,"Syntax error at ");
+    } else if (cc->token==TK_IDENT) {
+      tmpex=CAlloc(sizeof(CHashExport));
+      tmpex->str=cc->cur_str;
+      cc->cur_str=0;
+      tmpex->type=HTT_EXPORT_SYS_SYM;
+      tmpex->val=aotc->rip;
+      Lex(cc);  //Skip cur_str
+      if (cc->token!=':' && cc->token!=TK_DBL_COLON)
+        LexExcept(cc,"Expecting ':' at ");
+      else {
+        if (*tmpex->str=='@' && tmpex->str[1]=='@') {
+          if (cc->token==TK_DBL_COLON)
+            LexExcept(cc,"No local glbl exports at ");
+          HashAdd(tmpex,cc->htc.local_hash_table);
+        } else
+          HashAdd(tmpex,cc->htc.glbl_hash_table);
+        if (cc->htc.local_var_lst) {//AsmBlk in fun? Also add goto-like label.
+          if (!(g_lb=COCGoToLabelFind(cc,tmpex->str))) {
+            g_lb=COCMiscNew(cc,CMT_ASM_LABEL);
+            g_lb->str=StrNew(tmpex->str);
+          } else if (g_lb->flags&CMF_DEFINED)
+            LexExcept(cc,"Duplicate goto label at ");
+          g_lb->type=CMT_ASM_LABEL;
+          g_lb->flags|=CMF_DEFINED;
+          g_lb->rip=aotc->rip;
+          g_lb->use_cnt++; //Disable warning on unused labels.
+          ICAdd(cc,IC_LABEL,g_lb,0);
+        }
+        if (cc->token==TK_DBL_COLON) {
+          tmpex->type|=HTF_EXPORT;
+          HashSrcFileSet(cc,tmpex);
+
+          AOTLocalsResolve(cc);
+          aotc->last_label=tmpex->str;
+        }
+        Lex(cc);
+      }
+    } else if (cc->token==';')
+      Lex(cc);
+    else
+      LexExcept(cc,"Syntax error at ");
+    if (cmp_flags&CMPF_ONE_ASM_INS && (cc->token!=TK_IDENT ||
+          !(tmpo=cc->hash_entry) ||
+          !(tmpo->type&(HTT_OPCODE|HTT_ASM_KEYWORD))))
+      break;
+  }
+  AOTLocalsResolve(cc);
+  aotc->lst=FALSE;
+  cc->flags&=cc->flags&~CCF_ASM_EXPRESSIONS|old_flags;
+}
+
+ diff --git a/public/Wb/Compiler/AsmInit.HC.HTML b/public/Wb/Compiler/AsmInit.HC.HTML new file mode 100755 index 0000000..a822b58 --- /dev/null +++ b/public/Wb/Compiler/AsmInit.HC.HTML @@ -0,0 +1,240 @@ + + + + + + + + + + + +
+U0 AsmPrsInsFlags(CCmpCtrl *cc,CInst *tmpins)
+{
+  I64 i;
+  while (TRUE) {
+    switch (cc->token) {
+      case TK_IDENT:
+        if ((i=LstMatch(cc->cur_str,"NO\0CB\0CW\0CD\0CP\0IB\0IW\0ID\0"))>=0) {
+          tmpins->opcode_modifier=i;
+          break;
+        } else
+          return;
+      case TK_I64:
+        if (cc->cur_i64==16)
+          tmpins->flags|=IEF_OP_SIZE16;
+        else if (cc->cur_i64==32)
+          tmpins->flags|=IEF_OP_SIZE32;
+        else
+          return;
+        break;
+      case '+':
+        tmpins->flags|=IEF_PLUS_OPCODE;
+      case '/':
+        if (Lex(cc)==TK_I64 && cc->cur_i64<8)
+          tmpins->slash_val=cc->cur_i64;
+        else if (cc->token==TK_IDENT) {
+          if (!StrCmp(cc->cur_str,"R"))
+            tmpins->slash_val=SV_R_REG;
+          else if (!StrCmp(cc->cur_str,"I"))
+            tmpins->slash_val=SV_I_REG;
+          else
+            return;
+        } else
+          return;
+        break;
+      case '!': tmpins->flags|=IEF_DONT_SWITCH_MODES;   break;
+      case '&': tmpins->flags|=IEF_DFT;                 break;
+      case '%': tmpins->flags|=IEF_NOT_IN_64_BIT;       break;
+      case '=': tmpins->flags|=IEF_48_REX;              break;
+      case '`': tmpins->flags|=IEF_REX_ONLY_R8_R15;     break;
+      case '^': tmpins->flags|=IEF_REX_XOR_LIKE;                break;
+      case '*': tmpins->flags|=IEF_STI_LIKE;            break;
+      case '$': tmpins->flags|=IEF_ENDING_ZERO;         break;
+      default:
+        return;
+    }
+    Lex(cc);
+  }
+}
+
+U0 AsmHashLoad()
+{//See ::/Compiler/OpCodes.DD.
+  I64 i,j,size,size_max;
+  CInternalType *tmpit;
+  CCmpCtrl *cc;
+  CHashGeneric *tmph;
+  CHashReg *tmpr;
+  CHashOpcode *tmpo,*tmpo2,*tmpo_max;
+  CInst *tmpins;
+  CHashClass *tmpc;
+
+  cmp.size_arg_mask[0]=0x3FF0FFFFFE;
+  cmp.size_arg_mask[1]=0x1110111112;
+  cmp.size_arg_mask[2]=0x2220222224;
+  cmp.size_arg_mask[4]=0x0440444448;
+  cmp.size_arg_mask[8]=0x0880888880;
+
+  cmp.asm_hash=HashTableNew(1024);
+  size_max=offset(CHashOpcode.ins)+sizeof(CInst)<<5;
+  tmpo_max=MAlloc(size_max);
+
+  cc=CmpCtrlNew(FileRead("OpCodes.DD"),,"OpCodes.DD.Z");
+  cc->htc.hash_table_lst=NULL;
+  Lex(cc);
+  while (cc->token) {
+    if (cc->token!=TK_IDENT)
+      LexExcept(cc,"Expecting identifier at ");
+    i=LstMatch(cc->cur_str,"NONE\0R8\0R16\0R32\0R64\0SEG\0FSTK\0"
+          "MM\0XMM\0OPCODE\0KEYWORD\0ASM_KEYWORD\0");
+    if (i<=0)
+      LexExcept(cc,"Unknown Stmt");
+    Lex(cc); //skip keyword
+    if (cc->token!=TK_IDENT)
+      LexExcept(cc,"Expecting identifier at ");
+    switch (i) {
+      case REGT_R8...REGT_XMM:
+        tmpr=CAlloc(sizeof(CHashReg));
+        tmpr->str=cc->cur_str;
+        cc->cur_str=NULL;
+        Lex(cc); //skip keyword name
+        if (cc->token!=TK_I64)
+          LexExcept(cc,"Expecting int at ");
+        tmpr->type=HTT_REG;
+        tmpr->reg_type=i;
+        tmpr->reg_num=cc->cur_i64;
+        HashAdd(tmpr,cmp.asm_hash);
+        Lex(cc); //Skip INT
+        break;
+      case: //OPCODE
+        if (cc->token!=TK_IDENT)
+          LexExcept(cc,"Expecting opcode at ");
+        MemSet(tmpo_max,0,size_max);
+        tmpo_max->type=HTT_OPCODE;
+        tmpo_max->inst_entry_cnt=0;
+        tmpo_max->str=cc->cur_str;
+        cc->cur_str=0;
+        Lex(cc);        //Skip OPCODE
+        while (cc->token && cc->token!=';' && cc->token!=':') {
+          tmpins=&tmpo_max->ins[tmpo_max->inst_entry_cnt];
+          tmpins->ins_entry_num=tmpo_max->inst_entry_cnt++;
+          tmpins->slash_val=SV_NONE; //Not zero!!
+          while (cc->token==TK_I64) {
+            tmpins->opcode[tmpins->opcode_cnt++]=cc->cur_i64;
+            Lex(cc);
+          }
+          if (cc->token==',')
+            Lex(cc);
+          else if (cc->token!=';')
+            LexExcept(cc,"Expecting ',' at ");
+
+          AsmPrsInsFlags(cc,tmpins);
+
+          tmpins->uasm_slash_val=tmpins->slash_val;
+          if (tmpins->flags&IEF_STI_LIKE && tmpins->slash_val!=SV_I_REG)
+            tmpins->uasm_slash_val=SV_STI_LIKE;
+
+          tmpins->arg1=tmpins->arg2=tmpins->size1=tmpins->size2=0;
+          if (cc->token==TK_IDENT) {
+            j=DefineMatch(cc->cur_str,"ST_ARG_TYPES");
+            tmpins->arg1=j;
+            if (Bt(&cmp.size_arg_mask[1],j))
+              tmpins->size1=8;
+            else if (Bt(&cmp.size_arg_mask[2],j))
+              tmpins->size1=16;
+            else if (Bt(&cmp.size_arg_mask[4],j))
+              tmpins->size1=32;
+            else if (Bt(&cmp.size_arg_mask[8],j))
+              tmpins->size1=64;
+
+            if (Lex(cc)==TK_IDENT) {
+              j=DefineMatch(cc->cur_str,"ST_ARG_TYPES");
+              Lex(cc);
+              tmpins->arg2=j;
+              if (Bt(&cmp.size_arg_mask[1],j))
+                tmpins->size2=8;
+              else if (Bt(&cmp.size_arg_mask[2],j))
+                tmpins->size2=16;
+              else if (Bt(&cmp.size_arg_mask[4],j))
+                tmpins->size2=32;
+              else if (Bt(&cmp.size_arg_mask[8],j))
+                tmpins->size2=64;
+            }
+          }
+        }
+        size=offset(CHashOpcode.ins)+sizeof(CInst)*tmpo_max->inst_entry_cnt;
+        tmpo=MAlloc(size);
+        MemCpy(tmpo,tmpo_max,size);
+        tmpo->use_cnt=0;
+        if (HashFind(tmpo->str,cmp.asm_hash,HTT_OPCODE))
+          LexExcept(cc,"Duplicate OPCODE entry ");
+        HashAdd(tmpo,cmp.asm_hash);
+        //Parse aliases.
+        if (cc->token==':') {
+          while (Lex(cc)==TK_IDENT) {
+            tmpo2=MAllocIdent(tmpo);
+            tmpo2->str=cc->cur_str;
+            cc->cur_str=0;
+            tmpo2->oc_flags|=OCF_ALIAS;
+            if (HashFind(tmpo2->str,cmp.asm_hash,HTT_OPCODE))
+              LexExcept(cc,"Duplicate OPCODE ALIAS entry ");
+            HashAdd(tmpo2,cmp.asm_hash);
+          }
+        }
+        break;
+      case: //KEYWORD
+      case: //ASM_KEYWORD
+        tmph=CAlloc(sizeof(CHashGeneric));
+        tmph->str=cc->cur_str;
+        cc->cur_str=NULL;
+        Lex(cc); //skip keyword name
+        if (cc->token!=TK_I64)
+          LexExcept(cc,"Expecting int at ");
+        tmph->user_data0=cc->cur_i64;
+        if (i==10)
+          tmph->type=HTT_KEYWORD;
+        else
+          tmph->type=HTT_ASM_KEYWORD;
+        HashAdd(tmph,cmp.asm_hash);
+        Lex(cc); //Skip INT
+        break;
+    }
+    if (cc->token!=';')
+      LexExcept(cc,"Missing ';' at");
+    Lex(cc); //Skip ';'
+  }
+  Free(tmpo_max);
+  CmpCtrlDel(cc);
+  for (i=0;i<INTERNAL_TYPES_NUM;i++) {
+    tmpit=&internal_types_table[i];
+    tmpc=PrsClassNew;
+    tmpc->type=HTT_INTERNAL_TYPE;
+    tmpc->raw_type=tmpit->type;
+    Bts(&tmpc->flags,Cf_INTERNAL_TYPE);
+    tmpc->size=tmpit->size;
+    tmpc->str=AStrNew(tmpit->name);
+    HashAdd(tmpc,cmp.asm_hash);
+    cmp.internal_types[tmpc->raw_type]=tmpc;
+  }
+  adam_task->hash_table->next=cmp.asm_hash;
+}
+
+ diff --git a/public/Wb/Compiler/AsmLib.HC.HTML b/public/Wb/Compiler/AsmLib.HC.HTML new file mode 100755 index 0000000..84dc385 --- /dev/null +++ b/public/Wb/Compiler/AsmLib.HC.HTML @@ -0,0 +1,206 @@ + + + + + + + + + + + +
+U0 AOTStoreCodeU8(CCmpCtrl *cc,U8 b)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i=aotc->rip>>AOT_BIN_BLK_BITS;
+  CAOTBinBlk *tmpbin=aotc->bin;
+  while (i--)
+    if (!(tmpbin=tmpbin->next)) {
+      i=aotc->rip>>AOT_BIN_BLK_BITS+1;
+      tmpbin=&aotc->bin;
+      while (i--) {
+        if (!tmpbin->next)
+          tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+        tmpbin=tmpbin->next;
+      }
+      break;
+    }
+  tmpbin->body[aotc->rip++ & (AOT_BIN_BLK_SIZE-1)]=b;
+  if (aotc->lst) {
+    if (aotc->lst_col>=24) {
+      '\n';
+      aotc->lst_col=0;
+    }
+    "%02X ",b;
+    aotc->lst_col+=3;
+  }
+  if (aotc->rip>aotc->num_bin_U8s)
+    aotc->num_bin_U8s=aotc->rip;
+}
+
+U0 AOTStoreCodeU32(CCmpCtrl *cc,U32 d)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i=aotc->rip>>AOT_BIN_BLK_BITS,j=(aotc->rip+sizeof(U32))>>AOT_BIN_BLK_BITS;
+  U32 *_d;
+  CAOTBinBlk *tmpbin;
+  if (i!=j)
+    for (i=0;i<sizeof(U32);i++)
+      AOTStoreCodeU8(cc,d.u8[i]);
+  else {
+    tmpbin=aotc->bin;
+    while (i--)
+      if (!(tmpbin=tmpbin->next)) {
+        i=aotc->rip>>AOT_BIN_BLK_BITS+1;
+        tmpbin=&aotc->bin;
+        while (i--) {
+          if (!tmpbin->next)
+            tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+          tmpbin=tmpbin->next;
+        }
+        break;
+      }
+    _d=tmpbin->body+ aotc->rip&(AOT_BIN_BLK_SIZE-1);
+    *_d=d;
+    aotc->rip+=sizeof(U32);
+    if (aotc->lst) {
+      if (aotc->lst_col>=24) {
+        '\n';
+        aotc->lst_col=0;
+      }
+      "%08X ",d;
+      aotc->lst_col+=9;
+    }
+    if (aotc->rip>aotc->num_bin_U8s)
+      aotc->num_bin_U8s=aotc->rip;
+  }
+}
+
+U0 AOTStoreCodeU64(CCmpCtrl *cc,U64 q)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64   i=aotc->rip>>AOT_BIN_BLK_BITS,
+        j=(aotc->rip+sizeof(I64))>>AOT_BIN_BLK_BITS, *_q;
+  CAOTBinBlk *tmpbin;
+  if (i!=j)
+    for (i=0;i<sizeof(I64);i++)
+      AOTStoreCodeU8(cc,q.u8[i]);
+  else {
+    tmpbin=aotc->bin;
+    while (i--)
+      if (!(tmpbin=tmpbin->next)) {
+        i=aotc->rip>>AOT_BIN_BLK_BITS+1;
+        tmpbin=&aotc->bin;
+        while (i--) {
+          if (!tmpbin->next)
+            tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+          tmpbin=tmpbin->next;
+        }
+        break;
+      }
+    _q=tmpbin->body+ aotc->rip&(AOT_BIN_BLK_SIZE-1);
+    *_q=q;
+    aotc->rip+=sizeof(I64);
+    if (aotc->lst) {
+      if (aotc->lst_col>=24) {
+        '\n';
+        aotc->lst_col=0;
+      }
+      "%016X ",q;
+      aotc->lst_col+=17;
+    }
+    if (aotc->rip>aotc->num_bin_U8s)
+      aotc->num_bin_U8s=aotc->rip;
+  }
+}
+
+U0 AOTStoreCodeU8At(CCmpCtrl *cc,I64 rip,...)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CAOTBinBlk *tmpbin;
+  I64 i,j;
+  for (j=0;j<argc;j++) {
+    i=rip>>AOT_BIN_BLK_BITS+1;
+    tmpbin=&aotc->bin;
+    while (i--) {
+      if (!tmpbin->next) {
+        tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+        tmpbin->next->next=NULL;
+      }
+      tmpbin=tmpbin->next;
+    }
+    tmpbin->body[rip++ & (AOT_BIN_BLK_SIZE-1)]=argv[j];
+  }
+  if (rip>aotc->num_bin_U8s)
+    aotc->num_bin_U8s=rip;
+}
+
+I64 AsmLexExpression(CCmpCtrl *cc)
+{
+  U8 *machine_code;
+  I64 res=0;
+  cc->asm_undef_hash=NULL;
+  cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);
+  cc->abs_cnts=0;
+  if (!IsLexExpression2Bin(cc,&machine_code))
+    LexSkipEol(cc);
+  else {
+    if (cc->abs_cnts.externs)
+      LexExcept(cc,"Extern Not Allowed at ");
+    if (cc->flags & CCF_UNRESOLVED)
+      LexExcept(cc,"Undefined sym at ");
+    res=Call(machine_code);
+    Free(machine_code);
+  }
+  return res;
+}
+
+U0 AsmLineLst(CCmpCtrl *cc)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CLexFile *tmpf=cc->lex_include_stk;
+  CDocEntry *doc_e=tmpf->line_start,*doc_e2;
+  if (aotc->lst && aotc->lst_last_lfn==tmpf && doc_e) {
+    if (doc_e2=aotc->lst_last_line) {
+      if (tmpf->flags& LFSF_DOC) {
+        while (doc_e2->y<doc_e->y) {
+          "%h*c%08X ",24-aotc->lst_col,CH_SPACE,aotc->lst_last_rip;
+          aotc->lst_col=0;
+          doc_e2=LexPutLine(cc,doc_e2);
+        }
+      } else {
+        while (*doc_e2(U8 *) && doc_e2!=doc_e) {
+          "%h*c%08X ",24-aotc->lst_col,CH_SPACE,aotc->lst_last_rip;
+          aotc->lst_col=0;
+          doc_e2=LexPutLine(cc,doc_e2);
+        }
+      }
+      aotc->lst_last_line=doc_e2;
+    } else
+      aotc->lst_last_line=doc_e;
+  } else {
+    aotc->lst_last_line=NULL;
+    aotc->lst_last_lfn=tmpf;
+  }
+  aotc->lst_last_rip=aotc->rip;
+}
+
+ diff --git a/public/Wb/Compiler/AsmResolve.HC.HTML b/public/Wb/Compiler/AsmResolve.HC.HTML new file mode 100755 index 0000000..e5ca283 --- /dev/null +++ b/public/Wb/Compiler/AsmResolve.HC.HTML @@ -0,0 +1,248 @@ + + + + + + + + + + + +
+U0 AsmResolve(CCmpCtrl *cc,CAsmUnresolvedRef *tmpu,U8 *label,Bool undefined)
+{
+  CAOTImportExport *tmpie;
+  CAsmUndefHash *tmpauh;
+  I64 res=Call(tmpu->machine_code);
+  if (undefined) {
+    tmpauh=tmpu->asm_undef_hash;
+    while (tmpauh) {
+      if (tmpauh->hash->type & HTF_UNRESOLVED) {
+        tmpie=CAlloc(sizeof(CAOTImportExport));
+        tmpie->next=tmpauh->hash->ie_lst;
+        tmpauh->hash->ie_lst=tmpie;
+        tmpie->rip=tmpu->rip;
+        tmpie->aot=cc->aot;
+        tmpie->type=tmpu->type;
+      }
+      tmpauh=tmpauh->next; //Technically, more than one won't work.
+    }
+  } else if (!(tmpu->type&IEF_IMM_NOT_REL)) {
+    res-=tmpu->rel_rip;
+    if (tmpu->type==IET_REL_I8 && !(I8_MIN<=res<=I8_MAX) ||
+          tmpu->type==IET_REL_I16 && !(I16_MIN<=res<=I16_MAX)) {
+      PrintErr("Branch out of range at line:%04d %s\n",
+            tmpu->line_num,label);
+      LexExcept(cc);
+    }
+    if (tmpu->U8_avail && tmpu->type>IET_IMM_U8 && -124<=res<=123)
+      PrintWarn("could use I8 displacement at line:%04d %s %s\n",
+            tmpu->line_num,cc->aotc->last_label,label);
+  }
+  AOTStoreCodeU8At(cc,tmpu->rip,res.u8[0]);
+  if (tmpu->type>=IET_REL_I16) {
+    AOTStoreCodeU8At(cc,tmpu->rip+1,res.u8[1]);
+    if (tmpu->type>=IET_REL_I32) {
+      AOTStoreCodeU8At(cc,tmpu->rip+2,res.u8[2],res.u8[3]);
+      if (tmpu->type>=IET_REL_I64)
+        AOTStoreCodeU8At(cc,tmpu->rip+4,res.u8[4],res.u8[5],
+              res.u8[6],res.u8[7]);
+    }
+  }
+}
+
+U0 AOTLocalsResolve(CCmpCtrl *cc)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CAsmUnresolvedRef *tmpu=aotc->local_unresolved,*tmpu1;
+  CAsmUndefHash *tmpauh;
+  Bool undefined;
+  U8 *label=NULL;
+
+  while (tmpu) {
+    undefined=FALSE;
+    tmpu1=tmpu->next;
+    tmpauh=tmpu->asm_undef_hash;
+    while (tmpauh) {
+      if (tmpauh->hash->type & HTF_UNRESOLVED) {
+        PrintErr("Undefined sym at line:%04d %s %s\n",
+              tmpu->line_num,aotc->last_label,tmpauh->hash->str);
+        LexExcept(cc);
+      }
+      label=tmpauh->hash->str;
+      tmpauh=tmpauh->next;
+    }
+    if (!undefined)
+      AsmResolve(cc,tmpu,label,FALSE);
+    Free(tmpu->machine_code);
+    LinkedLstDel(tmpu->asm_undef_hash);
+    Free(tmpu);
+    tmpu=tmpu1;
+  }
+  HashTableDel(cc->htc.local_hash_table);
+  cc->htc.hash_table_lst=cc->htc.local_hash_table=HashTableNew(16);
+  cc->htc.local_hash_table->next=cc->htc.glbl_hash_table;
+  aotc->local_unresolved=NULL;
+}
+
+U0 AOTGlblsResolve(CCmpCtrl *cc,CAOT *tmpaot)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CHashFun *tmpf;
+  CAsmUnresolvedRef *tmpu=aotc->glbl_unresolved,*tmpu1;
+  I64 i,j;
+  CAOTImportExport *tmpie,*tmpie1;
+  CAsmUndefHash *tmpauh;
+  CHashExport *tmpex;
+  U8 *label;
+  Bool undefined;
+  CExternUsage *tmpeu,*tmpeu8;
+
+  while (tmpu) {
+    label=NULL;
+    undefined=FALSE;
+    tmpu1=tmpu->next;
+    tmpauh=tmpu->asm_undef_hash;
+    while (tmpauh) {
+      if (tmpauh->hash->type & HTF_UNRESOLVED) {
+        tmpex=tmpauh->hash;
+        if (tmpex->type & HTT_EXPORT_SYS_SYM&& tmpex->type & HTF_UNRESOLVED &&
+              !(tmpex->type & HTF_IMPORT) &&
+              (tmpf=HashFind(tmpex->str,cc->htc.hash_table_lst,HTT_FUN)) &&
+              !Bt(&tmpf->flags,Cf_EXTERN)) {
+          tmpex->val=tmpf->exe_addr;
+          tmpex->type&=~HTF_UNRESOLVED;
+          label=tmpauh->hash->str;
+        } else {
+          if (!(tmpex->type & HTF_IMPORT)) {
+            if (cc->htc.local_var_lst) {
+              tmpex->type|=HTF_GOTO_LABEL;
+              tmpex->use_cnt++;
+            } else {
+              PrintErr("Undefined sym at line:%04d %s\n",
+                    tmpu->line_num,tmpex->str);
+              LexExcept(cc);
+            }
+          } else if (undefined) {
+            PrintErr("Two imports in same expression "
+                  "not allowed at line:%04d %s\n",
+                  tmpu->line_num,tmpex->str);
+            LexExcept(cc);
+          }
+          undefined=TRUE;
+        }
+      } else
+        label=tmpauh->hash->str;
+      tmpauh=tmpauh->next;
+    }
+    AsmResolve(cc,tmpu,label,undefined);
+    Free(tmpu->machine_code);
+    LinkedLstDel(tmpu->asm_undef_hash);
+    Free(tmpu);
+    tmpu=tmpu1;
+  }
+
+  for (i=0;i<=cc->htc.glbl_hash_table->mask;i++) {
+    tmpex=cc->htc.glbl_hash_table->body[i];
+    while (tmpex) {
+      if (tmpex->type & (HTF_IMPORT|HTF_GOTO_LABEL)) {
+        if (tmpex->use_cnt && (tmpie=tmpex->ie_lst)) {
+          if (tmpex->type&HTF_GOTO_LABEL)
+            tmpie->flags|=IEF_GOTO_LABEL;
+          if (tmpex->import_name)
+            tmpie->str=StrNew(tmpex->import_name);
+          else
+            tmpie->str=StrNew(tmpex->str);
+          do {
+            tmpie1=tmpie->next;
+            QueIns(tmpie,tmpaot->last_ie);
+          } while (tmpie=tmpie1);
+          tmpex->ie_lst=NULL;
+        }
+      } else if (tmpex->type & (HTF_EXPORT|HTF_RESOLVE)) {
+        if (tmpex->type & HTF_UNRESOLVED) {
+          PrintErr("Undefined sym at %s\n",tmpex->str);
+          LexExcept(cc);
+        }
+        if (tmpex->type & HTF_RESOLVE) {
+          tmpf=tmpex;
+          tmpeu=tmpf->ext_lst;
+          while (tmpeu) {
+            tmpeu8=tmpeu->next;
+            j=tmpf->exe_addr-(tmpeu->rip+4);
+            AOTStoreCodeU8At(cc,tmpeu->rip,j.u8[0],j.u8[1],j.u8[2],j.u8[3]);
+            Free(tmpeu);
+            tmpeu=tmpeu8;
+          }
+        }
+        if (tmpex->type & HTF_EXPORT) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_REL32_EXPORT;
+          if (tmpex->type & HTT_FUN)
+            tmpie->rip=tmpf->exe_addr;
+          else if (tmpex->type & HTT_GLBL_VAR)
+            tmpie->rip=tmpex(CHashGlblVar *)->data_addr_rip;
+          else
+            tmpie->rip=tmpex->val;
+          tmpie->aot=cc->aot;
+          if (tmpex->type & HTF_IMM)
+            tmpie->type++;
+          tmpie->str=StrNew(tmpex->str);
+          tmpie->src_link=StrNew(tmpex->src_link);
+          QueIns(tmpie,tmpaot->last_ie);
+        }
+      }
+      tmpex=tmpex->next;
+    }
+  }
+}
+
+U0 AsmUnresolvedAdd(CCmpCtrl *cc,U8 *machine_code,I64 type,I64 rip,I64 rel_rip,
+        CAsmUndefHash *local_asm_undef_hash,CAsmUndefHash *glbl_asm_undef_hash,
+        I64 line_num,Bool U8_avail)
+{
+  CAsmUnresolvedRef *tmpu=MAlloc(sizeof(CAsmUnresolvedRef));
+  tmpu->machine_code=machine_code;
+  tmpu->type=type;
+  tmpu->rip=rip;
+  tmpu->rel_rip=rel_rip;
+  tmpu->aot=cc->aot;
+  tmpu->imm_flag=FALSE;
+  tmpu->line_num=line_num;
+  tmpu->U8_avail=U8_avail;
+  tmpu->str=NULL;
+  if (local_asm_undef_hash) {
+    tmpu->asm_undef_hash=local_asm_undef_hash;
+    tmpu->next=cc->aotc->local_unresolved;
+    cc->aotc->local_unresolved=tmpu;
+  } else {
+    tmpu->asm_undef_hash=glbl_asm_undef_hash;
+    tmpu->next=cc->aotc->glbl_unresolved;
+    cc->aotc->glbl_unresolved=tmpu;
+    if (glbl_asm_undef_hash->hash->type & HTF_IMPORT) {
+      tmpu->str=StrNew(glbl_asm_undef_hash->hash->str);
+      if (glbl_asm_undef_hash->hash->type & HTF_IMM)
+        tmpu->imm_flag=TRUE;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Compiler/BackA.HC.HTML b/public/Wb/Compiler/BackA.HC.HTML new file mode 100755 index 0000000..f742abd --- /dev/null +++ b/public/Wb/Compiler/BackA.HC.HTML @@ -0,0 +1,689 @@ + + + + + + + + + + + +
+U0 ICAddEct(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,I64 op,I64 rip)
+{
+  I64 i,tmp,res_reg=REG_RAX;
+  Bool swap=FALSE;
+  if (r3!=res_reg) {
+    swap^=TRUE;
+    SwapI64(&t2,&t3);
+    SwapI64(&r2,&r3);
+    SwapI64(&d2,&d3);
+  }
+  if (t2.raw_type>=RT_I64 && r2!=res_reg && t2&MDG_REG_DISP_SIB_RIP) {
+    if (t1&MDF_REG && !(r2==r1 && t2&MDG_REG_DISP_SIB))
+      res_reg=r1;
+    ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
+    i=ICModr1(res_reg,t2,r2,d2);
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICRex(tmpi,i.u8[1]);
+    ICU16(tmpi,i.u8[2]<<8+op);
+    ICModr2(tmpi,i,,d2,rip);
+  } else {
+    if (t2&MDF_REG)
+      tmp=r2;
+    else
+      tmp=REG_RCX;
+
+    if (t1&MDF_REG)
+      res_reg=r1;
+
+    if (tmp==res_reg)
+      res_reg=REG_RDX;
+    if (swap) {
+      if (r3==tmp && t3&MDG_REG_DISP_SIB)
+        tmp=REG_RCX;
+      ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t2,r2,d2,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
+    } else {
+      if (r2==res_reg && t2&MDG_REG_DISP_SIB)
+        res_reg=REG_RDX;
+      ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t2,r2,d2,rip);
+    }
+    i=0x48;
+    if (res_reg>7)
+      i+=4;
+    if (tmp>7)
+      i++;
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICU24(tmpi,0xC00000+i+(tmp&7)<<16+(res_reg&7)<<19+op<<8);
+  }
+  ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+U0 ICAddSubEctImm(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,I64 d,I64 op,I64 rip)
+{
+  I64 i;
+  if (op.u8[0]==0x2B) {
+    op=0x0003;
+    d=-d;
+  }
+  if (t1&MDF_REG) {
+    if (!(t2&MDF_REG)) {
+      ICMov(tmpi,t1,r1,d1,t2,r2,d2,rip);
+      t2=t1;
+      r2=r1;
+      d2=d1;
+    }
+    if (r1==r2) {
+      if (r1>7)
+        i=0x49;
+      else
+        i=0x48;
+      if (!d &&
+            (op.u8[0]==0x03||op.u8[0]==0x2B||op.u8[0]==0x33||op.u8[0]==0x0B))
+        return;
+      else if (d==1 && op.u8[0]==0x03) {
+        ICU24(tmpi,0xC0FF00+op.u8[1]<<19+i+(r1&7)<<16);
+        return;
+      } else if (d==-1 && op.u8[0]==0x03) {
+        ICU24(tmpi,0xC8FF00+i+(r1&7)<<16);
+        return;
+      } else if (I8_MIN<=d<=I8_MAX) {
+        ICU24(tmpi,0xC08300+op.u8[1]<<19+i+(r1&7)<<16);
+        ICU8(tmpi,d);
+        return;
+      } else if (I32_MIN<=d<=I32_MAX) {
+        ICU24(tmpi,0xC08100+op.u8[1]<<19+i+(r1&7)<<16);
+        ICU32(tmpi,d);
+        return;
+      }
+    }
+    if (op.u8[0]==0x03 && I32_MIN<=d<=I32_MAX &&
+          !Bt(&cmp.non_ptr_vars_mask,r2)) {
+      i=ICModr1(r1,MDF_DISP+RT_I64,r2,d);
+      i.u8[1]|=0x48;
+      ICU24(tmpi,i.u8[2]<<16+0x8D00+i.u8[1]);
+      ICModr2(tmpi,i,,d,rip);
+      return;
+    }
+  }
+  switch (Bsr(t1)) {
+    case MDf_REG:
+    case MDf_DISP:
+    case MDf_SIB:
+    case MDf_RIP_DISP32:
+      if (t1!=t2 || r1!=r2 || d1!=d2) {
+        ICMov(tmpi,t1,r1,d1,t2,r2,d2,rip);
+        t2=t1;
+        r2=r1;
+        d2=d1;
+      }
+
+      if (!d &&(op.u8[0]==0x03||op.u8[0]==0x2B||op.u8[0]==0x33||op.u8[0]==0x0B))
+        return;
+
+      if (op.u8[0]==0x03 && d==-1) //add -1
+        op.u8[1]=1; //Decrement slash val
+
+      if (op.u8[0]==0x03 && (d==1 || d==-1)) {  //Add
+        i=ICModr1(op.u8[1],t1,r1,d1);
+        if (!(t1&MDF_REG) && tmpi->ic_flags&ICF_LOCK)
+          ICU8(tmpi,OC_LOCK_PREFIX);
+        switch (t1.raw_type) {
+          case RT_I8:
+          case RT_U8:
+            ICRex(tmpi,i.u8[1]);
+            ICU16(tmpi,i.u8[2]<<8+0xFE);
+            break;
+          case RT_I16:
+          case RT_U16:
+            ICOpSizeRex(tmpi,i.u8[1]);
+            ICU16(tmpi,i.u8[2]<<8+0xFF);
+            break;
+          default:
+            ICRex(tmpi,i.u8[1]);
+            ICU16(tmpi,i.u8[2]<<8+0xFF);
+        }
+        ICModr2(tmpi,i,,d1,rip);
+        return;
+      }
+      if (I8_MIN<=d<=I8_MAX || t1&(RTG_MASK-RTF_UNSIGNED)==RT_I8) {
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_IMM_U8+op.u8[1],rip+1);
+        ICU8(tmpi,d);
+        return;
+      }
+      if (I32_MIN<=d<=I32_MAX || t1.raw_type<RT_I64) {
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_IMM_U32+op.u8[1],rip);
+        if (t1&(RTG_MASK-RTF_UNSIGNED)==RT_I16)
+          ICU16(tmpi,d);
+        else
+          ICU32(tmpi,d);
+        return;
+      }
+      break;
+    case MDf_STK:
+      ICAddSubEctImm(tmpi,MDF_REG+RT_I64,REG_RAX,0,t2,r2,d2,d,op,rip);
+      ICPushRegs(tmpi,1<<REG_RAX);
+      return;
+  }
+  ICAddEct(tmpi,t1,r1,d1,MDF_IMM+RT_I64,0,d,t2,r2,d2,op.u8[0],rip);
+}
+
+U0 ICSub(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,I64 rip)
+{
+  I64 i=0x48,op=0x2B;
+  Bool swap=FALSE;
+  if (r3!=REG_RAX) {
+    swap=TRUE;
+    SwapI64(&t2,&t3);
+    SwapI64(&r2,&r3);
+    SwapI64(&d2,&d3);
+  }
+  if (t2.raw_type>=RT_I64 && r2.u8[0]!=REG_RAX &&
+        (!(t2&MDF_SIB) || r2.u8[1]&15!=REG_RAX) && t2&MDG_REG_DISP_SIB_RIP) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+    if (!swap) {
+      op=0x03;
+      ICU24(tmpi,0xD8F748);
+    }
+    i=ICModr1(REG_RAX,t2,r2,d2);
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICRex(tmpi,i.u8[1]);
+    ICU16(tmpi,i.u8[2]<<8+op);
+    ICModr2(tmpi,i,,d2,rip);
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    if (!(t3&MDF_REG) || t3.raw_type<RT_I64) {
+      if (swap) {
+        swap=FALSE;
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+        r2=REG_RAX;
+        r3=REG_RCX;
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+        r3=REG_RAX;
+        r2=REG_RCX;
+      }
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+      r2=REG_RCX;
+    }
+    if (swap) {
+      op=0x03;
+      ICU24(tmpi,0xD9F748);
+    }
+    if (r3>7)
+      i++;
+    if (r2>7)
+      i+=4;
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICU24(tmpi,0xC00000+i+(r3&7)<<16+(r2&7)<<19+op<<8);
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,r2,0,rip);
+  }
+}
+
+U0 ICMul(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i,r2,r=REG_RAX,j;
+  CICArg *arg1,*arg2;
+  Bool alt;
+  if (tmpi->arg1.type&MDF_IMM) {
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+    alt=TRUE;
+  } else {
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+    alt=FALSE;
+  }
+  i=arg2->disp;
+  if (!(tmpi->ic_class->raw_type&RTF_UNSIGNED) &&
+        arg2->type&MDF_IMM && I32_MIN<=i<=I32_MAX) {
+    if (tmpi->res.type==MDF_REG+RT_I64) {
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            arg1->type,arg1->reg,arg1->disp,rip);
+      r=tmpi->res.reg;
+    } else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,arg1->reg,arg1->disp,rip);
+    if (r>7)
+      j=0xC0004D;
+    else
+      j=0xC00048;
+    if (I8_MIN<=i<=I8_MAX)
+      ICU32(tmpi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
+    else {
+      ICU24(tmpi,0x6900+j+(r&7)<<16+(r&7)<<19);
+      ICU32(tmpi,i);
+    }
+  } else {
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED)
+      i=0xE0F748;
+    else
+      i=0xE8F748;
+    if (alt) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      r2=REG_RCX;
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,arg2->reg,arg2->disp,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,arg2->reg,arg2->disp,rip);
+      if (!(arg1->type&MDF_REG) || arg1->type.raw_type<RT_I64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+              arg1->type,arg1->reg,arg1->disp,rip);
+        r2=REG_RCX;
+      } else
+        r2=arg1->reg;
+    }
+    if (r2>7) {
+      i++;
+      r2&=7;
+    }
+    ICU24(tmpi,i+r2<<16);
+  }
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,r,0,rip);
+}
+
+U0 ICMulEqu(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i=tmpi->arg2.disp,r=REG_RAX,j;
+  if (!(tmpi->ic_class->raw_type&RTF_UNSIGNED) &&
+        tmpi->arg2.type&MDF_IMM && I32_MIN<=i<=I32_MAX) {
+    if (tmpi->ic_flags & ICF_BY_VAL) {
+      if (tmpi->arg1.type==MDF_REG+RT_I64)
+        r=tmpi->arg1.reg;
+      else
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      if (r>7)
+        j=0xC0004D;
+      else
+        j=0xC00048;
+      if (I8_MIN<=i<=I8_MAX)
+        ICU32(tmpi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
+      else {
+        ICU24(tmpi,0x6900+j+(r&7)<<16+(r&7)<<19);
+        ICU32(tmpi,i);
+      }
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,r,0,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      r=REG_RBX;
+      if (I8_MIN<=i<=I8_MAX)
+        ICU32(tmpi,i<<24+0xDB6B48);
+      else {
+        ICU24(tmpi,0xDB6948);
+        ICU32(tmpi,i);
+      }
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,REG_RBX,0,rip);
+    }
+  } else {
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED)
+      i=0xE3F748;
+    else
+      i=0xEBF748;
+    if (tmpi->ic_flags & ICF_BY_VAL) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICU24(tmpi,i);
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      ICU24(tmpi,i);
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    }
+  }
+  if (tmpi->res.type.mode)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,r,0,rip);
+}
+
+U0 ICDiv(CIntermediateCode *tmpi,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+    ICZero(tmpi,REG_RDX);
+    ICU24(tmpi,0xF1F748);
+  } else {
+    ICU16(tmpi,0x9948);
+    ICU24(tmpi,0xF9F748);
+  }
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICDivEqu(CIntermediateCode *tmpi,Bool is_mod,I64 rip)
+{
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+          tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+      ICZero(tmpi,REG_RDX);
+      ICU24(tmpi,0xF1F748);
+    } else {
+      ICU16(tmpi,0x9948);
+      ICU24(tmpi,0xF9F748);
+    }
+    if (is_mod)
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RDX,0,rip);
+    else
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+//dangerous might clobber RBX in Mov, but it doesn't
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+tmpi->arg1_type_pointed_to,
+          REG_RBX,0,rip);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+      ICZero(tmpi,REG_RDX);
+      ICU24(tmpi,0xF1F748);
+    } else {
+      ICU16(tmpi,0x9948);
+      ICU24(tmpi,0xF9F748);
+    }
+    if (is_mod)
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RBX,0,
+            MDF_REG+RT_I64,REG_RDX,0,rip);
+    else
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RBX,0,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+  if (tmpi->res.type.mode) {
+    if (is_mod)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RDX,0,rip);
+    else
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+U0 ICMod(CIntermediateCode *tmpi,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+    ICZero(tmpi,REG_RDX);
+    ICU24(tmpi,0xF1F748);
+  } else {
+    ICU16(tmpi,0x9948);
+    ICU24(tmpi,0xF9F748);
+  }
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RDX,0,rip);
+}
+
+U0 ICAddSubEctEqu(CIntermediateCode *tmpi,U8 type_pointed_to,
+        CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,
+        CICType t3,I64 r3,I64 d3,I64 op,I64 rip)
+{
+  Bool done;
+  I64 res_reg,tmp,i;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (t3&MDF_IMM) {
+      ICAddSubEctImm(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,t2&MDG_MASK+
+            type_pointed_to,r2,d2,d3,op,rip);
+      if (t1.mode)
+        ICMov(tmpi,t1,r1,d1,t2&MDG_MASK+type_pointed_to,r2,d2,rip);
+      return;
+    } else {
+      done=FALSE;
+      if (type_pointed_to>=RT_I64) {
+        if (!t1.mode && t2&MDG_REG_DISP_SIB_RIP) {
+          if (t3&MDF_REG)
+            tmp=r3;
+          else {
+            tmp=REG_RCX;
+            ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t3,r3,d3,rip);
+          }
+          i=ICModr1(tmp,t2&MDG_MASK+type_pointed_to,r2,d2);
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          ICRex(tmpi,i.u8[1]);
+          ICU16(tmpi,i.u8[2]<<8+op.u8[5]);
+          ICModr2(tmpi,i,,d2,rip);
+          return;
+        }
+        if (t3.raw_type>=RT_I64 && t3&MDG_REG_DISP_SIB_RIP) {
+          if (t2&MDF_REG)
+            res_reg=r2;
+          else {
+            res_reg=REG_RCX;
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+          }
+          i=ICModr1(res_reg,t3&MDG_MASK+type_pointed_to,r3,d3);
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          ICRex(tmpi,i.u8[1]);
+          ICU16(tmpi,i.u8[2]<<8+op.u8[0]);
+          ICModr2(tmpi,i,,d3,rip);
+          ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
+                MDF_REG+RT_I64,res_reg,0,rip);
+          done=TRUE;
+        }
+      }
+      if (!done) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+        if (t2&MDF_REG && r2!=REG_RAX)
+          res_reg=r2;
+        else {
+          res_reg=REG_RCX;
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+                t2&MDG_MASK+type_pointed_to,r2,d2,rip);
+        }
+        if (tmpi->ic_flags&ICF_LOCK)
+          ICU8(tmpi,OC_LOCK_PREFIX);
+        if (res_reg>7)
+          ICU8(tmpi,0x4C);
+        else
+          ICU8(tmpi,0x48);
+        ICU16(tmpi,0xC000+op.u8[0]+(res_reg&7)<<11);
+        ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
+              MDF_REG+RT_I64,res_reg,0,rip);
+      }
+    }
+  } else {
+    done=FALSE;
+    if (t3&MDF_IMM && op.u8[2]) {
+      if (!d3.u32[1]) {
+        if (tmpi->ic_flags&ICF_RES_NOT_USED &&
+              t2&MDF_REG && d3(U64)<=I8_MAX) {
+          ICSlashOp(tmpi,MDF_DISP+type_pointed_to,r2,0,0x838000+op.u8[4],rip);
+          ICU8(tmpi,d3);
+          done=TRUE;
+        } else if (op.u8[2]==0x24) {//AND
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_DISP+type_pointed_to,REG_RCX,0,rip);
+          res_reg=REG_RAX;
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          ICU16(tmpi,op.u8[3]<<8+0x40);
+          ICU32(tmpi,d3);
+          ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
+                MDF_REG+RT_I64,res_reg,0,rip);
+          done=TRUE;
+        } else if (type_pointed_to<RT_I64) {//OR/XOR
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_DISP+type_pointed_to,REG_RCX,0,rip);
+          res_reg=REG_RAX;
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          if (d3.u16[1]) {
+            ICU16(tmpi,op.u8[3]<<8+0x40);
+            ICU32(tmpi,d3);
+          } else if (d3.u8[1]) {
+            ICU24(tmpi,op.u8[3]<<16+0x4000+OC_OP_SIZE_PREFIX);
+            ICU16(tmpi,d3);
+          } else {
+            ICU16(tmpi,op.u8[2]<<8+0x40);
+            ICU8(tmpi,d3);
+          }
+          ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
+                MDF_REG+RT_I64,res_reg,0,rip);
+          done=TRUE;
+        }
+      }
+    }
+    if (!done) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            MDF_DISP+type_pointed_to,REG_RCX,0,rip);
+      res_reg=REG_RBX;
+      if (tmpi->ic_flags&ICF_LOCK)
+        ICU8(tmpi,OC_LOCK_PREFIX);
+      ICU8(tmpi,0x48);
+      ICU16(tmpi,0xC000+op.u8[0]+(res_reg&7)<<11);
+      ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,res_reg,0,rip);
+    }
+  }
+  if (t1.mode)
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+U0 ICShift(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,
+        I64 us,I64 is,I64 rip)
+{
+  I64 i=0x48,res_reg;
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+        tmpi->ic_flags & ICF_USE_UNSIGNED)
+    is=us;
+  if (t1&MDF_REG) {
+    res_reg=r1;
+    if (res_reg>7)
+      i++;
+  } else
+    res_reg=REG_RAX;
+  if (t3&MDF_IMM) {
+    ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t2,r2,d2,rip);
+    if (d3==1)
+      ICU24(tmpi,i+is.u16[2]<<8+(res_reg&7)<<16);
+    else {
+      ICU24(tmpi,i+is.u16[0]<<8+(res_reg&7)<<16);
+      ICU8(tmpi,d3);
+    }
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t2,r2,d2,rip);
+    ICU24(tmpi,i+is.u16[1]<<8+(res_reg&7)<<16);
+  }
+  ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+U0 ICShiftEqu(CIntermediateCode *tmpi,U8 type_pointed_to,
+        CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,
+        CICType t3,I64 r3,I64 d3,I64 us,I64 is,I64 rip)
+{
+  I64 res_reg;
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+        tmpi->ic_flags & ICF_USE_UNSIGNED)
+    is=us;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (!(t3&MDF_IMM))
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
+    if (t2&MDF_REG)
+      res_reg=r2;
+    else {
+      res_reg=REG_RAX;
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            t2&MDG_MASK+type_pointed_to,r2,d2,rip);
+    }
+    if (res_reg>7)
+      ICU8(tmpi,0x49);
+    else
+      ICU8(tmpi,0x48);
+    if (t3&MDF_IMM) {
+      if (d3==1)
+        ICU16(tmpi,is.u16[2]+(res_reg&7)<<8);
+      else {
+        ICU16(tmpi,is.u16[0]+(res_reg&7)<<8);
+        ICU8(tmpi,d3);
+      }
+    } else
+      ICU16(tmpi,is.u16[1]+(res_reg&7)<<8);
+    ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
+          MDF_REG+RT_I64,res_reg,0,rip);
+  } else {
+    if (!(t3&MDF_IMM))
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,t2,r2,d2,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+type_pointed_to,REG_RDX,0,rip);
+    res_reg=REG_RAX;
+    ICU8(tmpi,0x48);
+    if (t3&MDF_IMM) {
+      if (d3==1)
+        ICU16(tmpi,is.u16[2]+(res_reg&7)<<8);
+      else {
+        ICU16(tmpi,is.u16[0]+(res_reg&7)<<8);
+        ICU8(tmpi,d3);
+      }
+    } else
+      ICU16(tmpi,is.u16[1]+(res_reg&7)<<8);
+    ICMov(tmpi,
+          MDF_DISP+type_pointed_to,REG_RDX,0,MDF_REG+RT_I64,res_reg,0,rip);
+  }
+  if (t1.mode)
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+ diff --git a/public/Wb/Compiler/BackB.HC.HTML b/public/Wb/Compiler/BackB.HC.HTML new file mode 100755 index 0000000..f4143a1 --- /dev/null +++ b/public/Wb/Compiler/BackB.HC.HTML @@ -0,0 +1,750 @@ + + + + + + + + + + + +
+U0 ICUnaries(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICNot(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i;
+  if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {
+    i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);
+    ICRex(tmpi,i.u8[1]);
+    ICU16(tmpi,i.u8[2]<<8+0xF6); //TEST ?,0xFF
+    ICModr2(tmpi,i,,tmpi->arg1.disp,rip+1);
+    ICU8(tmpi,0xFF);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICTest(tmpi,REG_RAX);
+  }
+  ICU24(tmpi,0xC0940F);   //SETZ AL
+  ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_U64,REG_RAX,0,rip);
+}
+
+U0 ICAndAnd(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 r2;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r2=REG_RDX;
+  } else
+    r2=tmpi->arg1.reg;
+  ICZero(tmpi,REG_RAX);
+  ICTest(tmpi,r2);
+  ICU16(tmpi,0x0874);
+  ICTest(tmpi,REG_RCX);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC0FF48);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICOrOr(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i=0x48,r2;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r2=REG_RDX;
+  } else
+    r2=tmpi->arg1.reg;
+
+  if (r2>7) {
+    i++;
+    r2&=7;
+  }
+  ICZero(tmpi,REG_RAX);
+  ICU24(tmpi,0xC80B00+i+r2<<16);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC0FF48);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICXorXor(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 r2;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  if (!(tmpi->arg1.type&MDF_REG)) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r2=REG_RDX;
+  } else
+    r2=tmpi->arg1.reg;
+  ICZero(tmpi,REG_RBX);
+  ICTest(tmpi,r2);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC3FF48);
+
+  ICZero(tmpi,REG_RAX);
+  ICTest(tmpi,REG_RCX);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC0FF48);
+
+  ICU24(tmpi,0xC33348);
+
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICCmp(CIntermediateCode *tmpi,I64 us,I64 is,I64 rip)
+{
+  I64 r1,d1,r2,i=0x48,j=tmpi->arg2.disp;
+  if (tmpi->arg2.type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
+    if (!(tmpi->ic_flags&(ICF_POP_CMP|ICF_PUSH_CMP)) &&
+          tmpi->arg1.type&MDF_DISP && //TODO
+          tmpi->arg1.type.raw_type>=RT_I64 && tmpi->arg1.reg!=REG_RAX) {
+      r1=tmpi->arg1.reg;
+      d1=tmpi->arg1.disp;
+      ICZero(tmpi,REG_RAX);
+      if (r1>7)
+        i++;
+      if (I8_MIN<=j<=I8_MAX)
+        i+=0x388300;
+      else
+        i+=0x388100;
+      if (!d1) {
+        ICU24(tmpi,0x000000+i+(r1&7)<<16);
+      } else if (I8_MIN<=d1<=I8_MAX) {
+        ICU24(tmpi,0x400000+i+(r1&7)<<16);
+        ICU8(tmpi,d1);
+      } else {
+        ICU24(tmpi,0x800000+i+(r1&7)<<16);
+        ICU32(tmpi,d1);
+      }
+      if (I8_MIN<=j<=I8_MAX)
+        ICU8(tmpi,j);
+      else
+        ICU32(tmpi,j);
+    } else {
+      if (tmpi->ic_flags & ICF_POP_CMP) {
+        ICPopRegs(tmpi,1<<REG_RCX);
+        r1=REG_RCX;
+      } else {
+        if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)
+          r1=tmpi->arg1.reg;
+        else {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+          r1=REG_RCX;
+        }
+      }
+      ICZero(tmpi,REG_RAX);
+      if (r1>7)
+        i++;
+      if (I8_MIN<=j<=I8_MAX) {
+        ICU24(tmpi,0xF88300+i+(r1&7)<<16);
+        ICU8(tmpi,j);
+      } else {
+        ICU24(tmpi,0xF88100+i+(r1&7)<<16);
+        ICU32(tmpi,j);
+      }
+    }
+    if (tmpi->ic_flags & ICF_PUSH_CMP)
+      ICPush(tmpi,MDF_IMM+RT_I64,0,j,rip);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+          tmpi->ic_flags & ICF_USE_UNSIGNED)
+      is=us;
+    ICU16(tmpi,0x300+is);
+    ICU24(tmpi,0xC0FF48);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    if (tmpi->arg2.type&MDF_REG && tmpi->arg2.reg!=REG_RAX)
+      r2=tmpi->arg2.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      r2=REG_RCX;
+    }
+    if (tmpi->ic_flags & ICF_POP_CMP) {
+      ICPopRegs(tmpi,1<<REG_RDX);
+      r1=REG_RDX;
+    } else {
+      if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)
+        r1=tmpi->arg1.reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+        r1=REG_RDX;
+      }
+    }
+    ICZero(tmpi,REG_RAX);
+    if (r2>7)
+      i++;
+    if (r1>7)
+      i+=4;
+    if (tmpi->ic_flags & ICF_PUSH_CMP)
+      ICPushRegs(tmpi,1<<r2);
+    ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+          tmpi->ic_flags & ICF_USE_UNSIGNED)
+      is=us;
+    ICU16(tmpi,0x300+is);
+    ICU24(tmpi,0xC0FF48);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+U0 ICBitOps(CIntermediateCode *tmpi,CICArg *arg1,CICArg *arg2,
+        CIntermediateCode *tmpi2,I64 op,I64 op_imm,I64 rip)
+{//TODO:not fully utilizing Modr
+  Bool res_not_used=ToBool(tmpi2->ic_flags&ICF_RES_NOT_USED);
+  I64 r1,t2,r2,d2,i=0x48;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    t2=arg2->type&MDG_MASK+RT_I64; //TODO: check overflow
+    r2=arg2->reg;
+    d2=arg2->disp;
+    if (!(t2&MDG_REG_DISP_SIB_RIP) || !(r2.u8[0]!=REG_RAX&&(!(t2&MDF_SIB) ||
+        r2.u8[1]&15!=REG_RAX) || res_not_used)) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+      t2=MDF_REG+RT_I64;
+      r2=REG_RCX;
+      d2=0;
+    }
+    if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))
+      r1=arg1->reg;
+    else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      r1=REG_RDX;
+    } else
+      r1=0;
+  } else {
+    t2=MDF_DISP+RT_I64;
+    d2=0;
+    if (arg2->type&MDF_REG && (arg2->reg!=REG_RAX||res_not_used))
+      r2=arg2->reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip);
+      r2=REG_RCX;
+    }
+    if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))
+      r1=arg1->reg;
+    else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      r1=REG_RDX;
+    } else
+      r1=0;
+  }
+  if (!res_not_used)
+    ICZero(tmpi,REG_RAX);
+  if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)
+    ICU8(tmpi,OC_LOCK_PREFIX);
+  if (arg1->type&MDF_IMM && arg1->disp<32)
+    t2=t2&MDG_MASK+RT_U32;
+  i=ICModr1(r1,t2,r2,d2);
+  ICRex(tmpi,i.u8[1]);
+  if (arg1->type&MDF_IMM && arg1->disp<64) {
+    ICU24(tmpi,i.u8[2]<<16+op_imm);
+    ICModr2(tmpi,i,,d2,rip+1);
+    ICU8(tmpi,arg1->disp);
+  } else {
+    ICU24(tmpi,i.u8[2]<<16+op);
+    ICModr2(tmpi,i,,d2,rip);
+  }
+  if (!res_not_used) {
+    ICU24(tmpi,0xC0920F); //SETC AL
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+U0 ICToUpper(CIntermediateCode *tmpi,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  ICU32(tmpi,0x61F88348);
+  ICU16(tmpi,0x0A7C);
+  ICU32(tmpi,0x7AF88348);
+  ICU16(tmpi,0x047F);
+  ICU32(tmpi,0xE0C08348);
+}
+
+U0 ICToI64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{
+  ICFCvt(cc,tmpi,REG_RAX,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,TRUE,CN_INST,rip);
+}
+
+U0 ICToF64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{
+  ICFCvt(cc,tmpi,REG_RAX,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,FALSE,CN_INST,rip);
+}
+
+U0 ICToBool(CCmpCtrl *,CIntermediateCode *tmpi,I64 rip)
+{
+  I64 r;
+  if (tmpi->arg1.type&MDF_REG)
+    r=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r=REG_RAX;
+  }
+  ICTest(tmpi,r);
+  ICU24(tmpi,0xC0950F);   //SETNZ AL
+  ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL
+}
+
+U0 ICPreIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  I64 r;
+  CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpc->ptr_stars_cnt && tmpc1->size!=1) {
+      ICAddSubEctImm(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);
+    } else
+      ICSlashOp(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RCX;
+    }
+    if (tmpc->ptr_stars_cnt &&
+          tmpc1->size!=1) {
+      ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+            tmpc1->size,op.u16[3],rip);
+    } else
+      ICSlashOp(tmpi,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);
+  }
+}
+
+U0 ICPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  I64 r;
+  CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    if (tmpc->ptr_stars_cnt &&  tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG &&
+          !(tmpi->res.type&MDF_REG && tmpi->res.reg==tmpi->arg1.reg))
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RCX;
+    }
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);
+    if (tmpc->ptr_stars_cnt &&  tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);
+  }
+}
+
+U0 ICDerefPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  CICType t;
+  I64 r;
+  CHashClass *tmpc1=tmpi->ic_class;
+  t=tmpi->res.type.raw_type;
+  if (t>tmpi->arg1_type_pointed_to)
+    t=tmpi->arg1_type_pointed_to;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RDX;
+    }
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,r,0,rip);
+    if (tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,tmpi->arg1.type&MDG_MASK+RT_I64,
+            tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RCX;
+    }
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r,0,rip);
+    if (tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,r,0,MDF_DISP+RT_I64,r,0,
+            tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,MDF_DISP+RT_I64,r,0,op,rip);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,REG_RDX,0,rip);
+  }
+}
+
+U0 ICAssignPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  CHashClass *tmpc1=tmpi->ic_class2-1;
+  I64 r;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RDX;
+    }
+    ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpc1->size!=1 || tmpi->arg1.type&MDF_STK)
+      ICAddSubEctImm(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+            MDF_REG+RT_I64,r,0,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_I64,REG_RDX,0,rip);
+    ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,REG_RDX,0,
+            MDF_REG+RT_I64,REG_RCX,0,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,MDF_DISP+RT_I64,REG_RDX,0,op,rip);
+  }
+}
+
+U0 ICCmpAndBranch(CIntermediateCode *tmpi,Bool has_res,I64 rip,
+   I64 us,I64 is,I64 not_us,I64 not_is,U8 *buf,I64 rip2)
+{
+  I64 r1,r2,i=0x48,j,res_reg;
+  CICType t1,t2;
+  Bool short_jmp,swap,done;
+  CCodeMisc *lb;
+  CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;
+
+  j=arg1->disp;
+  if (arg1->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
+    SwapI64(&arg1,&arg2);
+    swap=TRUE;
+    us=not_us;
+    is=not_is;
+  } else
+    swap=FALSE;
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+        tmpi->ic_flags & ICF_USE_UNSIGNED)
+    is=us;
+
+  j=arg2->disp;
+  if (arg2->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
+    if (!has_res && arg1->type&MDG_REG_DISP_SIB_RIP)
+      ICAddSubEctImm(tmpi,arg1->type,arg1->reg,arg1->disp,
+            arg1->type,arg1->reg,arg1->disp,j,0x073B,rip2);
+    else {
+      if (arg1->type&MDF_REG)
+        r1=arg1->reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+              arg1->reg,arg1->disp,rip2);
+        r1=REG_RDX;
+      }
+      if (!j) {
+        if (is.u8[2]==0x7C) {
+          ICTest(tmpi,r1);
+          is=0x78880F;
+        } else if (is.u8[2]==0x7D) {
+          ICTest(tmpi,r1);
+          is=0x79890F;
+        } else if (is.u8[2]==0x74 || is.u8[2]==0x75)
+          ICTest(tmpi,r1);
+        else {
+          if (r1>7)
+            i++;
+          ICU24(tmpi,0xF88300+i+(r1&7)<<16);
+          ICU8(tmpi,j);
+        }
+      } else {
+        if (r1>7)
+          i++;
+        if (I8_MIN<=j<=I8_MAX) {
+          ICU24(tmpi,0xF88300+i+(r1&7)<<16);
+          ICU8(tmpi,j);
+        } else {
+          ICU24(tmpi,0xF88100+i+(r1&7)<<16);
+          ICU32(tmpi,j);
+        }
+      }
+    }
+    if (has_res) {
+      if (!swap) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_IMM+RT_I64,0,j,rip2);
+        res_reg=REG_RCX;
+      } else
+        res_reg=r1;
+    }
+  } else {
+    done=FALSE;
+    t1=arg1->type;
+    r1=arg1->reg;
+    r2=arg2->reg;
+    t2=arg2->type;
+    if (t2.raw_type>=RT_I64 && !has_res && t2&MDG_DISP_SIB_RIP) {
+      if (!(t1&MDF_REG) || t1.raw_type<RT_I64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,
+              arg1->reg,arg1->disp,rip2);
+        r1=REG_RAX;
+      }
+      i=ICModr1(r1,t2,r2,arg2->disp);
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+0x3B);
+      ICModr2(tmpi,i,,arg2->disp,rip2);
+      done=TRUE;
+    } else if (t1.raw_type>=RT_I64 && t1&MDG_REG_DISP_SIB_RIP) {
+      if (!(t2&MDF_REG) || t2.raw_type<RT_I64) {
+        if (t1&MDF_REG && r1==REG_RAX) {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,
+                arg2->reg,arg2->disp,rip2);
+          r2=REG_RCX;
+        } else {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+                arg2->reg,arg2->disp,rip2);
+          r2=REG_RAX;
+        }
+      }
+      i=ICModr1(r2,t1,r1,arg1->disp);
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+0x39);
+      ICModr2(tmpi,i,,arg1->disp,rip2);
+      if (has_res)
+        res_reg=r2;
+      done=TRUE;
+    }
+    if (!done) {
+      if (arg2->type&MDF_REG)
+        r2=arg2->reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip2);
+        r2=REG_RAX;
+      }
+      if (arg1->type&MDF_REG)
+        r1=arg1->reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
+              arg1->reg,arg1->disp,rip2);
+        r1=REG_RCX;
+      }
+      if (r2>7)
+        i++;
+      if (r1>7)
+        i+=4;
+      ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
+      if (has_res)
+        res_reg=r2;
+    }
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+  if (has_res)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,res_reg,0,rip2);
+}
+
+U0 ICTestAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)
+{
+  I64 i;
+  Bool short_jmp;
+  CCodeMisc *lb;
+
+  if (!(tmpi->arg1.type&MDF_REG)) {
+    if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {
+      i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+0xF6);
+      ICModr2(tmpi,i,,tmpi->arg1.disp,rip2+1);
+      ICU8(tmpi,0xFF);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      ICTest(tmpi,REG_RAX);
+    }
+  } else
+    ICTest(tmpi,tmpi->arg1.reg);
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICFlagBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf)
+{
+  I64 i;
+  Bool short_jmp;
+  CCodeMisc *lb;
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+ diff --git a/public/Wb/Compiler/BackC.HC.HTML b/public/Wb/Compiler/BackC.HC.HTML new file mode 100755 index 0000000..46abb8d --- /dev/null +++ b/public/Wb/Compiler/BackC.HC.HTML @@ -0,0 +1,802 @@ + + + + + + + + + + + +
+U0 ICAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)
+{
+  U64 i;
+  I64 it,t1,r1,d1,r2;
+  Bool short_jmp,swap,override;
+  CCodeMisc *lb;
+  CICArg *arg1,*arg2;
+
+  if (tmpi->arg1.type&MDF_IMM) {
+    swap=TRUE;
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+  } else {
+    swap=FALSE;
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+  }
+
+  if (arg2->type&MDF_IMM && arg2->disp>U32_MAX)
+    override=TRUE;
+  else
+    override=FALSE;
+
+  if (arg1->type.raw_type<arg2->type.raw_type)
+    it=arg1->type.raw_type;
+  else
+    it=arg2->type.raw_type;
+
+  i=arg2->disp;
+  if (arg2->type&MDF_IMM && i<=U32_MAX) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,arg1->reg,arg1->disp,rip2);
+    if (i<=U8_MAX)
+      ICU16(tmpi,i<<8+0xA8);
+    else if (i<=U16_MAX)
+      ICU32(tmpi,i<<16+0xA900+OC_OP_SIZE_PREFIX);
+    else {
+      ICU8(tmpi,0xA9);
+      ICU32(tmpi,i);
+    }
+  } else {
+    t1=MDF_REG+it;
+    d1=0;
+    if (swap && !override) {
+      if (arg1->type&MDF_REG) {
+        r1=arg1->reg;
+        swap=TRUE;
+      } else {
+        r1=REG_RCX;
+        swap=FALSE;
+      }
+      if (arg2->type&MDF_REG) {
+        r2=arg2->reg;
+        swap=FALSE;
+      } else
+        r2=REG_RDX;
+      if (swap) {
+        if (!(arg1->type&MDF_REG) || r1!=arg1->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        if (arg2->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg2->type&MDG_MASK+it;
+          r2=arg2->reg;
+          d1=arg2->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        i=ICModr1(r1,t1,r2,d1);
+      } else {
+        if (arg1->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+it;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        if (!(arg2->type&MDF_REG) || r2!=arg2->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        i=ICModr1(r2,t1,r1,d1);
+      }
+    } else {
+      if (arg2->type&MDF_REG) {
+        r2=arg2->reg;
+        swap=FALSE;
+      } else {
+        r2=REG_RDX;
+        swap=TRUE;
+      }
+      if (arg1->type&MDF_REG) {
+        r1=arg1->reg;
+        swap=TRUE;
+      } else
+        r1=REG_RCX;
+      if (override)
+        swap=FALSE;
+      if (swap) {
+        if (arg2->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg2->type&MDG_MASK+it;
+          r2=arg2->reg;
+          d1=arg2->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        if (!(arg1->type&MDF_REG) || r1!=arg1->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        i=ICModr1(r1,t1,r2,d1);
+      } else {
+        if (!(arg2->type&MDF_REG) || r2!=arg2->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        if (arg1->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+it;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        i=ICModr1(r2,t1,r1,d1);
+      }
+    }
+    switch (it) {
+      case RT_I8:
+      case RT_U8:
+        ICRex(tmpi,i.u8[1]);
+        ICU16(tmpi,i.u8[2]<<8+0x84);
+        break;
+      case RT_U16:
+      case RT_I16:
+        ICOpSizeRex(tmpi,i.u8[1]);
+        ICU16(tmpi,i.u8[2]<<8+0x85);
+        break;
+      default:
+        ICRex(tmpi,i.u8[1]);
+        ICU16(tmpi,i.u8[2]<<8+0x85);
+    }
+    ICModr2(tmpi,i,,d1,rip2);
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICAssign(CIntermediateCode *tmpi,I64 rip)
+{
+  CIntermediateCode *tmpi1;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+          tmpi->arg1.reg,tmpi->arg1.disp,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG) {
+      if (!(tmpi1=OptLag1(tmpi)) || tmpi1->ic_code!=IC_ADD_CONST ||
+            tmpi1->res.type!=MDF_REG+RT_I64 || tmpi1->res.reg!=tmpi->arg1.reg ||
+            tmpi1->arg1.type!=MDF_REG+RT_I64 ||
+            tmpi1->arg1.reg!=tmpi->arg1.reg ||
+            (tmpi->arg2.type&MDF_REG || tmpi->arg2.type&MDF_DISP) &&
+            tmpi->arg2.reg==tmpi->arg1.reg ||
+            tmpi->res.type.mode || tmpi1->ic_flags&~ICG_NO_CVT_MASK) {
+        ICMov(tmpi,
+              MDF_DISP+tmpi->arg1_type_pointed_to,
+              tmpi->arg1.reg,tmpi->arg1.disp,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+        if (tmpi->res.type.mode)
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      } else {
+        tmpi->ic_flags=(tmpi->ic_flags|tmpi1->ic_flags)&
+              ~ICF_CODE_FINAL|ICF_DONT_RESTORE;
+        tmpi->arg1.disp=tmpi1->ic_data;
+        OptSetNOP1(tmpi1); //This better not be last pass!
+        ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,
+              tmpi->arg1.reg,tmpi->arg1.disp,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      }
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      if (tmpi->res.type.mode)
+        ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    }
+  }
+}
+
+U0 ICBrBitOps(CIntermediateCode *tmpi,I64 rip,
+        I64 op,I64 op_imm,I64 is,U8 *buf,I64 rip2)
+{
+  I64 i,t,r1,r2,d1,d2,t1,t2;
+  CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;
+  Bool short_jmp;
+  CCodeMisc *lb;
+
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->ic_flags&ICF_SWAP && !(arg2->type&MDF_REG) &&
+          (!(arg2->type&MDF_IMM) ||arg2->disp>63)||
+          !(tmpi->ic_flags&ICF_SWAP) && arg2->type&MDF_IMM &&
+          arg2->disp<64 || arg2->type&MDF_STK) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);
+      t2=MDF_REG+RT_I64;
+      r2=REG_RCX;
+      d2=0;
+    } else {
+      t2=arg2->type;
+      if (t2&MDF_IMM && arg2->disp<64)
+        r2=0;
+      else
+        r2=arg2->reg;
+      d2=arg2->disp;
+    }
+    if (!(tmpi->ic_flags&ICF_SWAP) && !(arg1->type&MDF_REG) &&
+          (!(arg1->type&MDF_IMM) || arg1->disp>63) ||
+          tmpi->ic_flags&ICF_SWAP && arg1->type&MDF_IMM &&
+          arg1->disp<64 || arg1->type&MDF_STK) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);
+      t1=MDF_REG+RT_I64;
+      r1=REG_RDX;
+      d1=0;
+    } else {
+      t1=arg1->type;
+      if (t1&MDF_IMM && arg1->disp<64)
+        r1=0;
+      else
+        r1=arg1->reg;
+      d1=arg1->disp;
+    }
+  } else {
+    t1=MDF_DISP+RT_I64;
+    t2=MDF_DISP+RT_I64;
+    d1=0;
+    d2=0;
+    if (arg2->type&MDF_REG)
+      r2=arg2->reg;
+    else if (!(tmpi->ic_flags&ICF_SWAP) || !(arg2->type&MDF_IMM) ||
+          arg2->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);
+      r2=REG_RCX;
+    } else
+      r2=0;
+    if (arg1->type&MDF_REG)
+      r1=arg1->reg;
+    else if (tmpi->ic_flags&ICF_SWAP ||
+          !(arg1->type&MDF_IMM) || arg1->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);
+      r1=REG_RDX;
+    } else
+      r1=0;
+  }
+  if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)
+    ICU8(tmpi,OC_LOCK_PREFIX);
+  if (tmpi->ic_flags&ICF_SWAP) {
+    if (arg2->type&MDF_IMM && arg2->disp<32) {
+      if (op==0xA30F && arg2->disp<8) {
+        t=t1&MDG_MASK+RT_U8;
+        op_imm=0xF6; //TEST
+      } else
+        t=t1&MDG_MASK+RT_U32;
+    } else
+      t=t1;
+    i=ICModr1(r2,t,r1,d1);
+    SwapI64(&arg1,&arg2);
+  } else {
+    if (arg1->type&MDF_IMM && arg1->disp<32) {
+      if (op==0xA30F && arg1->disp<8) {
+        t=t2&MDG_MASK+RT_U8;
+        op_imm=0xF6; //TEST
+      } else
+        t=t2&MDG_MASK+RT_U32;
+    } else
+      t=t2;
+    i=ICModr1(r1,t,r2,d2);
+  }
+  ICRex(tmpi,i.u8[1]);
+  if (op_imm==0xF6) {//TEST
+    ICU16(tmpi,i.u8[2]<<8+op_imm);
+    ICModr2(tmpi,i,,arg2->disp,rip2+1);
+    ICU8(tmpi,1<<arg1->disp);
+    if (is==0x72820F)
+      is=0x75850F;
+    else
+      is=0x74840F;
+  } else if (arg1->type&MDF_IMM && arg1->disp<64) {
+    ICU24(tmpi,i.u8[2]<<16+op_imm);
+    ICModr2(tmpi,i,,arg2->disp,rip2+1);
+    ICU8(tmpi,arg1->disp);
+  } else {
+    ICU24(tmpi,i.u8[2]<<16+op);
+    ICModr2(tmpi,i,,arg2->disp,rip2);
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICQueInit(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1;
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RAX;
+  }
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);
+}
+
+U0 ICQueIns(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1,r2;
+  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)
+    r2=tmpi->arg2.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+    r2=REG_RAX;
+  }
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RDX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r2,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,REG_RBX,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);
+}
+
+U0 ICQueInsRev(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1,r2;
+  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)
+    r2=tmpi->arg2.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+    r2=REG_RAX;
+  }
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RDX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,0,MDF_REG+RT_I64,r2,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,REG_RBX,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);
+}
+
+U0 ICQueRem(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1;
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RAX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);
+  ICU24(tmpi,0x1A8948);
+  ICU32(tmpi,sizeof(U8 *)<<24+0x538948);
+}
+
+U0 ICMinMax(CIntermediateCode *tmpi,I64 op,I64 rip2)
+{
+  I64 r1,i1=0x48;
+  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RAX) {
+    r1=tmpi->arg2.reg;
+    if (r1>7) {
+      i1++;
+      r1&=7;
+    }
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  } else {
+    if (tmpi->arg1.reg==REG_RAX && tmpi->arg1.type&MDG_REG_DISP_SIB) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+      r1=REG_RDX;
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+      if (tmpi->arg1.type==MDF_REG+RT_I64) {
+        r1=tmpi->arg1.reg;
+        if (r1>7) {
+          i1++;
+          r1&=7;
+        }
+      } else {
+        r1=REG_RDX;
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      }
+    }
+  }
+  ICU24(tmpi,0xC03B00+r1<<16+i1);
+  ICU32(tmpi,0xC0000F00+op<<16+r1<<24+i1);
+}
+
+U0 ICSqr(CIntermediateCode *tmpi,I64 op,I64 rip2)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip2);
+}
+
+U0 ICModU64(CIntermediateCode *tmpi,I64 rip2)
+{
+  CICType t1;
+  I64 r1,d1;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+  if (tmpi->arg1.reg!=REG_RAX && tmpi->arg1.reg!=REG_RDX &&
+        tmpi->arg1.type&MDG_REG_DISP_SIB &&
+        tmpi->arg1.type.raw_type>=RT_I64) {
+    t1=tmpi->arg1.type;
+    r1=tmpi->arg1.reg;
+    d1=tmpi->arg1.disp;
+  } else {
+    t1=MDF_REG+RT_I64;
+    r1=REG_RBX;
+    d1=0;
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip2);
+  ICZero(tmpi,REG_RDX);
+  ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_DIV,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip2);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        MDF_REG+RT_I64,REG_RDX,0,rip2);
+}
+
+U0 ICSwap(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1,r2;
+  if (tmpi->arg1.type&MDF_REG)
+    r1=tmpi->arg1.reg;
+  else
+    r1=REG_RAX;
+  if (tmpi->arg2.type&MDF_REG)
+    r2=tmpi->arg2.reg;
+  else
+    r2=REG_RAX;
+  if (r1==r2) {
+    if (r1==REG_RAX)
+      r1=REG_RBX;
+    else
+      r2=REG_RAX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,r2,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+  ICMov(tmpi,MDF_REG+RT_I64,r1,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  switch (tmpi->ic_code) {
+    case IC_SWAP_U8:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U8,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U8,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U8,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U8,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+    case IC_SWAP_U16:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U16,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U16,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U16,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U16,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+    case IC_SWAP_U32:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U32,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U32,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U32,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U32,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+    case IC_SWAP_I64:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U64,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U64,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U64,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U64,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+  }
+}
+
+U0 ICAndEqu(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 i,bit;
+  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
+        tmpi->ic_flags&ICF_RES_NOT_USED) {
+    i=~tmpi->arg2.disp;
+    bit=Bsf(i);
+    if (0<=bit==Bsr(i)) {
+      tmpi->arg2.disp=bit;
+      tmpi->arg2.reg=0;
+      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
+      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xB30F,0x30BA0F,rip2);
+      return;
+    }
+  }
+  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x210425240423,rip2);
+}
+
+U0 ICOrEqu(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 i,bit;
+  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
+        tmpi->ic_flags&ICF_RES_NOT_USED) {
+    i=tmpi->arg2.disp;
+    bit=Bsf(i);
+    if (0<=bit==Bsr(i) && i>I8_MAX) {
+      tmpi->arg2.disp=bit;
+      tmpi->arg2.reg=0;
+      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
+      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xAB0F,0x28BA0F,rip2);
+      return;
+    }
+  }
+  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x09010D0C010B,rip2);
+}
+
+U0 ICXorEqu(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 i,bit;
+  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
+        tmpi->ic_flags&ICF_RES_NOT_USED) {
+    i=tmpi->arg2.disp;
+    bit=Bsf(i);
+    if (0<=bit==Bsr(i)) {
+      tmpi->arg2.disp=bit;
+      tmpi->arg2.reg=0;
+      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
+      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xBB0F,0x38BA0F,rip2);
+      return;
+    }
+  }
+  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x310635340633,rip2);
+}
+
+U0 ICSwitch(CIntermediateCode *tmpi,I64 rip,
+        Bool nobound,CCmpCtrl *cc,U8 *buf,I64 rip2)
+{
+  I64 i,j,cnt,min,max,begin,r;
+  CCodeMisc *lb;
+  Bool short_jmp;
+  CAOTAbsAddr *tmpa;
+  if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg&7==REG_RSP)
+    r=REG_RDX;
+  else
+    r=tmpi->arg1.reg;
+  if (nobound)
+    ICMov(tmpi,MDF_REG+RT_I64,r,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  else {
+    if (tmpi->arg2.type&MDF_IMM) {
+      j=tmpi->arg2.disp;
+      ICMov(tmpi,MDF_REG+RT_I64,r,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      if (I8_MIN<=j<=I8_MAX) {
+        i=0xF88348+(r&7)<<16;
+        if (r>7) i++;
+        ICU24(tmpi,i);
+        ICU8(tmpi,j);
+      } else if (I32_MIN<=j<=I32_MAX) {
+        i=0xF88148+(r&7)<<16;
+        if (r>7) i++;
+        ICU24(tmpi,i);
+        ICU32(tmpi,j);
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+        i=0xC13B48+(r&7)<<19;
+        if (r>7) i+=4;
+        ICU24(tmpi,i);
+      }
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,r,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      i=0xC13B48+(r&7)<<19;
+      if (r>7) i+=4;
+      ICU24(tmpi,i);
+    }
+
+    rip+=tmpi->ic_cnt;
+    lb=tmpi->ic_data(CCodeMisc *)->dft;
+    short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+    if (!buf && lb->addr!=INVALID_PTR) {
+      i=lb->addr-(rip+2);
+      if (I8_MIN<=i<=I8_MAX)
+        short_jmp=TRUE;
+    }
+    if (short_jmp) {
+      tmpi->ic_flags|=ICF_SHORT_JMP;
+      ICU16(tmpi,(lb->addr-(rip+2))<<8+0x73);
+    } else {
+      tmpi->ic_flags&=~ICF_SHORT_JMP;
+      ICU16(tmpi,0x830F);
+      ICU32(tmpi,lb->addr-(rip+6));
+    }
+  }
+
+  lb=tmpi->ic_data;
+  begin=lb->begin->addr;
+  if (!buf && begin!=INVALID_PTR) {
+    min=I64_MAX;
+    max=I64_MIN;
+    for (i=0;i<lb->range;i++) {
+      if (lb->jmp_table[i]->addr==INVALID_PTR) {
+        min=I64_MIN;
+        max=I64_MAX;
+        break;
+      } else {
+        j=lb->jmp_table[i]->addr-begin;
+        min=MinI64(min,j);
+        max=MaxI64(max,j);
+      }
+    }
+    if (I8_MIN<=min<=max<=I8_MAX)
+      lb->flags|=CMF_I8_JMP_TABLE;
+    else if (U8_MIN<=min<=max<=U8_MAX)
+      lb->flags|=CMF_U8_JMP_TABLE;
+    else if (I16_MIN<=min<=max<=I16_MAX)
+      lb->flags|=CMF_I16_JMP_TABLE;
+    else if (U16_MIN<=min<=max<=U16_MAX)
+      lb->flags|=CMF_U16_JMP_TABLE;
+  }
+
+  if (lb->flags&CMF_I8_JMP_TABLE) {
+    if (r<8)
+      ICU8(tmpi,0x48);
+    else
+      ICU8(tmpi,0x49);
+    ICU24(tmpi,0x98BE0F+(r&7)<<16);
+    cnt=1;
+  } else if (lb->flags&CMF_U8_JMP_TABLE) {
+    if (r<8)
+      cnt=2;
+    else {
+      ICU8(tmpi,0x49);
+      cnt=1;
+    }
+    ICU24(tmpi,0x98B60F+(r&7)<<16);
+  } else if (lb->flags&CMF_I16_JMP_TABLE) {
+    if (r<8)
+      ICU8(tmpi,0x48);
+    else
+      ICU8(tmpi,0x4A);
+    ICU32(tmpi,0x451CBF0F+(r&7)<<27);
+    cnt=0;
+  } else if (lb->flags&CMF_U16_JMP_TABLE) {
+    if (r<8)
+      cnt=1;
+    else {
+      ICU8(tmpi,0x4A);
+      cnt=0;
+    }
+    ICU32(tmpi,0x451CB70F+(r&7)<<27);
+  } else {
+    if (r<8)
+      cnt=2;
+    else {
+      ICU8(tmpi,0x42);
+      cnt=1;
+    }
+    ICU24(tmpi,0x851C8B+(r&7)<<19);
+  }
+  if (buf && cc->flags&CCF_AOT_COMPILE) {
+    tmpa=CAlloc(sizeof(CAOTAbsAddr));
+    tmpa->next=cc->aotc->abss;
+    tmpa->type=AAT_ADD_U32;
+    cc->aotc->abss=tmpa;
+    tmpa->rip=rip2+tmpi->ic_cnt;
+    ICU32(tmpi,lb->addr+cc->aotc->rip);
+  } else
+    ICU32(tmpi,lb->addr+buf);
+
+  if (lb->flags&(CMF_I8_JMP_TABLE|CMF_U8_JMP_TABLE|
+        CMF_I16_JMP_TABLE|CMF_U16_JMP_TABLE)) {
+    ICU16(tmpi,0xC381); //ADD EBX,0x12345678
+    if (buf && cc->flags&CCF_AOT_COMPILE) {
+      tmpa=CAlloc(sizeof(CAOTAbsAddr));
+      tmpa->next=cc->aotc->abss;
+      tmpa->type=AAT_ADD_U32;
+      cc->aotc->abss=tmpa;
+      tmpa->rip=rip2+tmpi->ic_cnt;
+      ICU32(tmpi,begin+cc->aotc->rip);
+    } else
+      ICU32(tmpi,begin+buf);
+  } else
+    cnt+=6;
+  ICU16(tmpi,0xE3FF); //JMP EBX
+  for (i=0;i<cnt;i++) //Code must always shrink, not expand
+    ICU8(tmpi,OC_NOP);
+  tmpi->ic_flags&=~ICF_CODE_FINAL;
+}
+
+U0 ICLocalVarInit(CIntermediateCode *tmpi)
+{
+  ICU24(tmpi,0xC48B48);
+  ICU16(tmpi,0x5748);
+  ICU24(tmpi,0xF88B48);
+  ICU24(tmpi,0xC1C748);
+  ICU32(tmpi,tmpi->ic_data);
+  ICU16(tmpi,sys_var_init_val<<8+0xB0);
+  ICU24(tmpi,0xAA48F3);
+  ICU16(tmpi,0x5F48);
+}
+
+ diff --git a/public/Wb/Compiler/BackFA.HC.HTML b/public/Wb/Compiler/BackFA.HC.HTML new file mode 100755 index 0000000..399d0c2 --- /dev/null +++ b/public/Wb/Compiler/BackFA.HC.HTML @@ -0,0 +1,638 @@ + + + + + + + + + + + +
+#define CN_A2   0
+#define CN_A1   1
+#define CN_INST 2
+#define CN_RES  3
+
+U0 CmpNoteFloatOp(CCmpCtrl *cc,CIntermediateCode *tmpi,
+        Bool dont_pushable,Bool dont_popable,I64 pos)
+{
+  Bool link=FALSE;
+  if (cc->pass==7 && cc->last_float_op_ic &&
+        cc->last_dont_popable && dont_pushable) {
+    switch [pos] {
+      case CN_A2:
+        if (cc->last_float_op_ic!=tmpi && cc->dont_push_float)
+          link=TRUE;
+        break;
+      case CN_A1:
+        if (cc->last_float_op_ic!=tmpi && cc->dont_push_float)
+          link=TRUE;
+        break;
+      case CN_INST:
+        if (cc->last_float_op_ic!=tmpi) {
+          if (cc->dont_push_float) {
+            if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG &&
+                  cc->last_float_op_ic->res.reg!=REG_R8)
+              tmpi->ic_flags|=ICF_ALT_TEMPLATE;
+            else
+              tmpi->ic_flags&=~ICF_ALT_TEMPLATE;
+            link=TRUE;
+          }
+        } else {
+          if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG &&
+                cc->last_float_op_pos!=CN_A1)
+            tmpi->ic_flags|=ICF_ALT_TEMPLATE;
+          else
+            tmpi->ic_flags&=~ICF_ALT_TEMPLATE;
+          link=TRUE;
+        }
+        break;
+      case CN_RES:
+        if (cc->last_float_op_ic==tmpi && cc->last_float_op_pos==CN_INST)
+          link=TRUE;
+        break;
+    }
+    if (link) {
+      if (!Bts(&cc->last_float_op_ic->ic_flags,
+            ICf_DONT_POP_FLOAT0+cc->last_ic_float_op_num))
+        cc->last_float_op_ic->ic_flags&=~ICF_CODE_FINAL;
+      if (!Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0+cc->cur_ic_float_op_num))
+        tmpi->ic_flags&=~ICF_CODE_FINAL;
+    }
+  }
+  cc->last_float_op_ic=tmpi;
+  cc->last_dont_pushable=dont_pushable;
+  cc->last_dont_popable=dont_popable;
+  cc->last_ic_float_op_num=cc->cur_ic_float_op_num++;
+  cc->last_float_op_pos=pos;
+  if (cc->cur_ic_float_op_num>4)
+    throw('Compiler');
+}
+
+U0 CmpSetFloatOpPushPop(CCmpCtrl *cc,CIntermediateCode *tmpi,
+        Bool *dont_push_float,Bool *dont_pop_float)
+{
+  if (cc->pass==7) {
+    *dont_push_float=FALSE;
+    *dont_pop_float =FALSE;
+    tmpi->ic_flags&=~ICF_CODE_FINAL;
+  } else {
+    *dont_push_float=Bt(&tmpi->ic_flags,
+          ICf_DONT_PUSH_FLOAT0+cc->cur_ic_float_op_num);
+    *dont_pop_float=Bt(&tmpi->ic_flags,
+          ICf_DONT_POP_FLOAT0+cc->cur_ic_float_op_num);
+  }
+}
+
+U0 ICCopyTemplate(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,
+  Bool off_the_record,Bool dont_pushable,Bool dont_popable,I64 pos)
+{
+  Bool dont_push_float,dont_pop_float,alt;
+  U8 *ptr;
+  I64 i=0;
+  if (!off_the_record) {
+    if (tmpi->ic_flags&ICF_ALT_TEMPLATE)
+      alt=TRUE;
+    else
+      alt=FALSE;
+    CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  } else {
+    dont_push_float=FALSE;
+    dont_pop_float=FALSE;
+    alt=FALSE;
+  }
+  if (alt && dont_push_float && !dont_pop_float) {
+    ptr=cmp_templates_dont_push2[op];
+    i=cmp_templates_dont_push2[op+1]-ptr;
+  }
+  if (!i) {
+    if (dont_push_float) {
+      if (dont_pop_float) {
+        ptr=cmp_templates_dont_push_pop[op];
+        i=cmp_templates_dont_push_pop[op+1]-ptr;
+      } else {
+        ptr=cmp_templates_dont_push[op];
+        i=cmp_templates_dont_push[op+1]-ptr;
+      }
+    } else {
+      if (dont_pop_float) {
+        ptr=cmp_templates_dont_pop[op];
+        i=cmp_templates_dont_pop[op+1]-ptr;
+      } else {
+        ptr=cmp_templates[op];
+        i=cmp_templates[op+1]-ptr;
+      }
+    }
+  }
+  MemCpy(&tmpi->ic_body[tmpi->ic_cnt],ptr,i);
+  if (!off_the_record)
+    CmpNoteFloatOp(cc,tmpi,dont_pushable,dont_popable,pos);
+  tmpi->ic_cnt+=i;
+}
+
+U0 ICFCvt(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 r1,
+        CICType t2,I64 r2,I64 d2,Bool to_int,I64 pos,I64 rip)
+{
+  I64 rsp_size=0,op1,op2;
+  Bool dont_push_float,dont_pop_float;
+
+  if (to_int) {
+    op1=SLASH_OP_FLD;
+    op2=SLASH_OP_FISTTP;
+  } else {
+    op1=SLASH_OP_FILD;
+    op2=SLASH_OP_FSTP;
+  }
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (!dont_push_float) {
+    if (!(t2.raw_type>=RT_I64 && t2&MDG_DISP_SIB_RIP)) {
+      ICPush(tmpi,t2,r2,d2,rip);
+      t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      rsp_size=8;
+    } else {
+      if (!dont_pop_float) {
+        rsp_size=8;
+        ICAddRSP(tmpi,-8);
+      }
+    }
+    ICSlashOp(tmpi,t2,r2,d2,op1,rip);
+  } else {
+    if (!dont_pop_float) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    }
+  }
+  if (to_int)
+    CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,pos);
+  else
+    CmpNoteFloatOp(cc,tmpi,FALSE,TRUE,pos);
+  if (dont_pop_float) {
+    if (rsp_size)
+      ICAddRSP(tmpi,rsp_size);
+  } else {
+    ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,rip);
+    ICPop(tmpi,MDF_REG+RT_I64,r1,0,rip);
+  }
+}
+
+U0 ICFCvt2(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 r1,
+        CICType t2,I64 r2,I64 d2,Bool to_int,I64 rip)
+{
+  I64 rsp_size=0,op1,op2;
+  if (to_int) {
+    op1=SLASH_OP_FLD;
+    op2=SLASH_OP_FISTTP;
+  } else {
+    op1=SLASH_OP_FILD;
+    op2=SLASH_OP_FSTP;
+  }
+  if (!(t2.raw_type>=RT_I64 && t2&MDG_DISP_SIB_RIP)) {
+    ICPush(tmpi,t2,r2,d2,rip);
+    t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+    rsp_size=8;
+  } else {
+    rsp_size=8;
+    ICAddRSP(tmpi,-8);
+  }
+  ICSlashOp(tmpi,t2,r2,d2,op1,rip);
+  ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,rip);
+  ICPop(tmpi,MDF_REG+RT_I64,r1,0,rip);
+  cc->last_dont_pushable=cc->last_dont_popable=FALSE; //TODO: improve this
+}
+
+U0 ICFUnaryMinus(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf2,I64 rip)
+{
+  CICArg *arg1=&tmpi->arg1;
+  I64 rsp_size=0,builtin1=0,t1,r1,d1;
+  Bool dont_push_float,dont_pop_float;
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (!dont_push_float) {
+    if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+      t1=arg1->type;
+      r1=arg1->reg;
+      d1=arg1->disp;
+    } else {
+      if (arg1->type&MDF_IMM) {
+        if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+          t1=MDF_RIP_DISP32+RT_I64;
+          r1=REG_RIP;
+          d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+        }
+      } else {
+        ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+        rsp_size+=8;
+      }
+    }
+    if (builtin1)
+      ICU16(tmpi,builtin1);
+    else
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip);
+  }
+  if (!dont_pop_float && !rsp_size) {
+    rsp_size=8;
+    ICAddRSP(tmpi,-8);
+  }
+  ICU16(tmpi,0xE0D9); //FCHS
+  CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+  if (dont_pop_float) {
+    if (rsp_size)
+      ICAddRSP(tmpi,rsp_size);
+  } else {
+    ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+    ICPop(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,rip);
+  }
+}
+
+U0 ICFMod(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{//for MOD
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (tmpi->ic_flags&ICF_ALT_TEMPLATE)
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  }
+//TODO: unpushable,unpop?  Not sure
+  ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
+  if (!dont_pop_float)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFPow(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{//for POW
+  I64 i;
+  CAOTImportExport *tmpie;
+  CHashExport *tmpex=HashFind("SYS_POW",
+        cc->htc.hash_table_lst,HTT_EXPORT_SYS_SYM);
+
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  if (cc->flags&CCF_AOT_COMPILE) {
+    if (!tmpex) {
+      tmpex=CAlloc(sizeof(CHashExport));
+      tmpex->str=StrNew("SYS_POW");
+      tmpex->type=HTT_EXPORT_SYS_SYM|HTF_UNRESOLVED|HTF_IMPORT;
+      HashAdd(tmpex,cc->htc.glbl_hash_table);
+    }
+    if (tmpex->type&HTF_IMPORT) {
+      if (GetOption(OPTf_USE_IMM64)) {
+        ICU16(tmpi,0xBB48);
+        ICU64(tmpi,0);
+        if (buf) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_IMM_I64;
+          tmpie->rip=rip+tmpi->ic_cnt-8;
+          tmpie->next=tmpex->ie_lst;
+          tmpex->ie_lst=tmpie;
+        }
+        ICU16(tmpi,0xD3FF);
+      } else {
+        ICU8(tmpi,0xE8);
+        ICU32(tmpi,-(rip+tmpi->ic_cnt+4));
+        if (buf) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_REL_I32;
+          tmpie->rip=rip+tmpi->ic_cnt-4;
+          tmpie->next=tmpex->ie_lst;
+          tmpex->ie_lst=tmpie;
+        }
+      }
+    } else {//Kernel
+      if (tmpex->type&HTF_UNRESOLVED)
+        throw('Compiler');
+      else {
+        i=tmpex->val-(rip+tmpi->ic_cnt+5);
+        if (!(I32_MIN<=i<=I32_MAX)) {
+          throw('Compiler');
+//          ICU16(tmpi,0xBB48);
+          //        ICU64(tmpi,tmpex->val);
+          //        ICU16(tmpi,0xD3FF);
+        } else {
+          ICU8(tmpi,0xE8);
+          ICU32(tmpi,i);
+        }
+      }
+    }
+  } else {
+    i=tmpex->val-(rip+tmpi->ic_cnt+5);
+    if (!(I32_MIN<=i<=I32_MAX)) {
+      ICU16(tmpi,0xBB48);
+      ICU64(tmpi,tmpex->val);
+      ICU16(tmpi,0xD3FF);
+    } else {
+      ICU8(tmpi,0xE8);
+      ICU32(tmpi,i);
+    }
+  }
+  tmpi->ic_flags&=~ICF_CODE_FINAL;
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFOp(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,U8 *buf2,I64 rip)
+{//for ADD,SUB,DIV,MUL
+  CICArg *arg1,*arg2;
+  Bool dont_push_float,dont_pop_float,alt;
+  I64 rsp_size=0,builtin1=0,builtin2=0,t1,r1,d1,t2,r2,d2;
+
+  if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+    alt=TRUE;
+  } else {
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+    alt=FALSE;
+  }
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+      t2=arg2->type;
+      r2=arg2->reg;
+      d2=arg2->disp;
+    } else {
+      if (arg2->type&MDF_IMM) {
+        if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+          t2=MDF_RIP_DISP32+RT_I64;
+          r2=REG_RIP;
+          d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+        }
+      } else {
+        ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+        rsp_size+=8;
+      }
+    }
+  } else {
+    if (alt) {
+      if (!(arg2->type&MDF_STK)) {
+        if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else {
+          if (arg1->type&MDF_IMM) {
+            if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+              t1=MDF_RIP_DISP32+RT_I64;
+              r1=REG_RIP;
+              d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
+            t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+            rsp_size+=8;
+          }
+        }
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+            if (r1==REG_RSP+REG_RSP<<8)
+              d1+=8;
+          }
+        }
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    } else {
+      if (!(arg1->type&MDF_STK)) {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else {
+          if (arg1->type&MDF_IMM) {
+            if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+              t1=MDF_RIP_DISP32+RT_I64;
+              r1=REG_RIP;
+              d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
+            t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+            rsp_size+=8;
+            if (r2==REG_RSP+REG_RSP<<8)
+              d2+=8;
+          }
+        }
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    }
+  }
+  if (!dont_pop_float && !rsp_size) {
+    rsp_size=8;
+    ICAddRSP(tmpi,-8);
+  }
+  if (!dont_push_float) {
+    if (builtin2 && !builtin1) {
+      alt=!alt;
+      SwapI64(&t1,&t2);
+      SwapI64(&r1,&r2);
+      SwapI64(&d1,&d2);
+      SwapI64(&builtin1,&builtin2);
+    }
+    if (builtin1)
+      ICU16(tmpi,builtin1);
+    else
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip);
+  }
+  if (alt)
+    switch (op.u8[0]) {
+      case 4: op=SLASH_OP_FSUBR; break;
+      case 6: op=SLASH_OP_FDIVR; break;
+    }
+  if (builtin2) {
+    ICU16(tmpi,builtin2);
+    ICU16(tmpi,op.u16[2]);
+  } else
+    ICSlashOp(tmpi,t2,r2,d2,op,rip);
+  CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+  if (dont_pop_float) {
+    if (rsp_size)
+      ICAddRSP(tmpi,rsp_size);
+  } else {
+    if (rsp_size==8)
+      ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+    else if (rsp_size>8) {
+      ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
+            SLASH_OP_FSTP,rip);
+      ICAddRSP(tmpi,rsp_size-8);
+    }
+    ICPop(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,rip);
+  }
+}
+
+U0 ICFCmp(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
+      if (tmpi->ic_flags&ICF_POP_CMP)
+        ICPopRegs(tmpi,1<<REG_RAX);
+      else
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    } else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->ic_flags&ICF_POP_CMP)
+      ICPopRegs(tmpi,1<<REG_RDX);
+    else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  }
+  if (tmpi->ic_flags&ICF_PUSH_CMP)
+    ICPushRegs(tmpi,1<<REG_RAX);
+  ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,FALSE,CN_INST);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFModEqu(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (dont_push_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+    }
+//TODO: unpushable,unpop?  Not sure
+    ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
+    if (tmpi->arg1_type_pointed_to!=RT_F64)
+      ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+    ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+          tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else {
+    if (dont_push_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,tmpi->arg1.type,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,tmpi->arg1.type,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+    }
+//TODO: unpushable,unpop?  Not sure
+    ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
+    if (tmpi->arg1_type_pointed_to!=RT_F64)
+      ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+    ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+ diff --git a/public/Wb/Compiler/BackFB.HC.HTML b/public/Wb/Compiler/BackFB.HC.HTML new file mode 100755 index 0000000..342f976 --- /dev/null +++ b/public/Wb/Compiler/BackFB.HC.HTML @@ -0,0 +1,662 @@ + + + + + + + + + + + +
+U0 ICFOpEqu(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,U8 *buf2,I64 rip)
+{//for ADD,SUB,DIV,MUL
+  CICArg *arg1=&tmpi->arg1,
+        *arg2=&tmpi->arg2;
+  Bool dont_push_float,dont_pop_float,p1_mem;
+  I64 rsp_size=0,builtin2=0,
+        t1,r1,d1,t2,r2,d2;
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_pop_float)
+    throw('Compiler');
+
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    p1_mem=FALSE;
+    if (dont_push_float) {
+      if (tmpi->arg1_type_pointed_to!=RT_F64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              arg1->reg,arg1->disp,rip);
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+        ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+        rsp_size+=8;
+      } else {
+        if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;
+          r1=arg1->reg;
+          d1=arg1->disp;
+          p1_mem=TRUE;
+        } else {
+          ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+                arg1->reg,arg1->disp,rip);
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+        }
+      }
+    } else {
+      if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              arg1->reg,arg1->disp,rip);
+        if (tmpi->arg1_type_pointed_to!=RT_F64)
+          ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      } else {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;
+          r1=arg1->reg;
+          d1=arg1->disp;
+          p1_mem=TRUE;
+        } else {
+          ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+                arg1->reg,arg1->disp,rip);
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+          if (r2==REG_RSP+REG_RSP<<8)
+            d2+=8;
+        }
+      }
+    }
+    if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to==RT_F64)) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    }
+    if (!dont_push_float) {
+      if (builtin2)
+        ICU16(tmpi,builtin2);
+      else
+        ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);
+    }
+    switch (op.u8[0]) {
+      case 4: op=SLASH_OP_FSUBR; break;
+      case 6: op=SLASH_OP_FDIVR; break;
+    }
+    ICSlashOp(tmpi,t1,r1,d1,op,rip);
+    CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
+    if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FSTP,rip);
+      if (rsp_size)
+        ICAddRSP(tmpi,rsp_size);
+    } else {
+      if (rsp_size==8)
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+      else if (rsp_size>8) {
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
+              SLASH_OP_FSTP,rip);
+        ICAddRSP(tmpi,rsp_size-8);
+      }
+      if (tmpi->arg1_type_pointed_to!=RT_F64) {
+        ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+        ICMov(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,arg1->reg,
+              arg1->disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+      } else
+        ICPop(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              arg1->reg,arg1->disp,rip);
+    }
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            arg1->reg,arg1->disp,rip);
+  } else {
+    if (tmpi->arg1_type_pointed_to>=RT_I64)
+      p1_mem=TRUE;
+    else
+      p1_mem=FALSE;
+    if (dont_push_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+        ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+      } else
+        ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+      rsp_size+=8;
+    } else {
+      if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+        if (tmpi->arg1_type_pointed_to!=RT_F64)
+          ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      } else {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+        rsp_size+=8;
+        if (r2==REG_RSP+REG_RSP<<8)
+          d2+=8;
+      }
+    }
+    if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to==RT_F64)) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    }
+    if (!dont_push_float) {
+      if (builtin2)
+        ICU16(tmpi,builtin2);
+      else
+        ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);
+    }
+
+    switch (op.u8[0]) {
+      case 4: op=SLASH_OP_FSUBR; break;
+      case 6: op=SLASH_OP_FDIVR; break;
+    }
+    ICSlashOp(tmpi,t1,r1,d1,op,rip);
+    CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
+    if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {
+      ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,
+            REG_RCX,0,SLASH_OP_FSTP,rip);
+      if (rsp_size)
+        ICAddRSP(tmpi,rsp_size);
+    } else {
+      if (rsp_size==8)
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+      else if (rsp_size>8) {
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
+              SLASH_OP_FSTP,rip);
+        ICAddRSP(tmpi,rsp_size-8);
+      }
+      ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    }
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+ 
+U0 ICFCmpAndBranch(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip,
+   I64 us,I64 not_us,U8 *buf,I64 rip2)
+{
+  CICArg *arg1,*arg2;
+  Bool dont_push_float,dont_pop_float,alt,short_jmp;
+  I64 i,rsp_size=0,builtin1=0,builtin2=0,t1,r1,d1,t2,r2,d2;
+  CCodeMisc *lb;
+  U8 *buf2;
+
+  if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+    alt=TRUE;
+  } else {
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+    alt=FALSE;
+  }
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+  else
+    buf2=buf;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (tmpi->ic_flags&ICF_POP_CMP && alt) {
+      t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      rsp_size+=8;
+    } else {
+      if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+        t2=arg2->type;
+        r2=arg2->reg;
+        d2=arg2->disp;
+      } else {
+        if (arg2->type&MDF_IMM) {
+          if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
+                tmpi->ic_flags&ICF_PUSH_CMP) {
+            t2=MDF_RIP_DISP32+RT_I64;
+            r2=REG_RIP;
+            d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+          }
+        } else {
+          ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
+          t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+          rsp_size+=8;
+        }
+      }
+    }
+  } else {
+    if (alt) {
+      if (!(arg2->type&MDF_STK)) {
+        if (tmpi->ic_flags&ICF_POP_CMP) {
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+        } else {
+          if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+            t1=arg1->type;
+            r1=arg1->reg;
+            d1=arg1->disp;
+          } else {
+            if (arg1->type&MDF_IMM) {
+              if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+                t1=MDF_RIP_DISP32+RT_I64;
+                r1=REG_RIP;
+                d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+              }
+            } else {
+              ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);
+              t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+              rsp_size+=8;
+            }
+          }
+        }
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
+                  tmpi->ic_flags&ICF_PUSH_CMP) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+            if (r1==REG_RSP+REG_RSP<<8)
+              d1+=8;
+          }
+        }
+      } else {
+        if (tmpi->ic_flags&ICF_POP_CMP)
+          ICPopRegs(tmpi,1<<REG_RDX);
+        else
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+                arg1->reg,arg1->disp,rip2);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip2);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    } else {
+      if (!(arg1->type&MDF_STK)) {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
+                  tmpi->ic_flags&ICF_PUSH_CMP) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        if (tmpi->ic_flags&ICF_POP_CMP) {
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+          if (r2==REG_RSP+REG_RSP<<8)
+            d1+=8;
+        } else {
+          if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+            t1=arg1->type;
+            r1=arg1->reg;
+            d1=arg1->disp;
+          } else {
+            if (arg1->type&MDF_IMM) {
+              if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+                t1=MDF_RIP_DISP32+RT_I64;
+                r1=REG_RIP;
+                d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+              }
+            } else {
+              ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);
+              t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+              rsp_size+=8;
+              if (r2==REG_RSP+REG_RSP<<8)
+                d2+=8;
+            }
+          }
+        }
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip2);
+        if (tmpi->ic_flags&ICF_POP_CMP)
+          ICPopRegs(tmpi,1<<REG_RDX);
+        else
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+                arg1->reg,arg1->disp,rip2);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    }
+  }
+  if (!dont_push_float) {
+    if (builtin1)
+      ICU16(tmpi,builtin1);
+    else
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip2);
+  }
+  if (!alt)
+    us=not_us;
+  if (builtin2)
+    ICU16(tmpi,builtin2);
+  else
+    ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip2);
+  if (tmpi->ic_flags&ICF_PUSH_CMP) {
+    t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+    if (!rsp_size) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    } else if (rsp_size==16)
+      d2=8;
+
+    if (alt) {
+      ICU16(tmpi,0xF1DF);         //FCOMIP
+      ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);
+    } else {
+      ICU16(tmpi,0xF1DB);         //FCOMI
+      ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);
+      ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP
+    }
+  } else {
+    ICU16(tmpi,0xF1DF);   //FCOMIP
+    ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP
+  }
+  CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
+
+  if (tmpi->ic_flags&ICF_PUSH_CMP) {
+    if (r2.u8[0]==REG_RSP) {
+      while (d2 && rsp_size) {
+        ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
+        rsp_size-=8;
+        d2-=8;
+      }
+    } else {
+      while (rsp_size) {
+        ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
+        rsp_size-=8;
+      }
+      ICPush(tmpi,t2,r2,d2,rip2);
+    }
+  } else {
+    while (rsp_size) {
+      ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
+      rsp_size-=8;
+    }
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,i<<8+us.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,us.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICFMul(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  if (tmpi->arg1.type&MDF_IMM && tmpi->arg1.type&RTG_MASK==RT_F64 &&
+        tmpi->arg1.disp(F64)==1.0) {
+    CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  } else if (tmpi->arg2.type&MDF_IMM &&
+        tmpi->arg2.type&RTG_MASK==RT_F64&& tmpi->arg2.disp(F64)==1.0) {
+    CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FMUL,buf,rip);
+}
+
+U0 ICFDiv(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  if (tmpi->arg2.type&MDF_IMM && tmpi->arg2.type&RTG_MASK==RT_F64 &&
+        tmpi->arg2.disp(F64)==1.0) {
+    CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FDIV,buf,rip);
+}
+
+U0 ICFAdd(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (tmpi->arg1.type&MDF_IMM && !tmpi->arg1.disp) {
+    if (dont_push_float) {
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else if (dont_pop_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
+    } else {
+      CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    }
+  } else if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {
+    if (dont_push_float) {
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else if (dont_pop_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
+    } else {
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+    }
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FADD,buf,rip);
+}
+
+U0 ICFSub(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {
+    CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+    if (dont_push_float) {
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else if (dont_pop_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
+    } else {
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+    }
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FSUB,buf,rip);
+}
+
+U0 ICFPreIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+  if (tmpi->res.type.mode)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFPostIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+  if (tmpi->res.type.mode)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RDX,0,rip);
+}
+
+U0 ICFTemplateFun(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (!dont_push_float)
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+
+  ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+  if (tmpi->res.type.mode && !(tmpi->ic_flags & ICF_RES_TO_F64) &&
+        !(tmpi->ic_flags & ICF_RES_TO_INT))
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+ diff --git a/public/Wb/Compiler/BackLib.HC.HTML b/public/Wb/Compiler/BackLib.HC.HTML new file mode 100755 index 0000000..a58f72a --- /dev/null +++ b/public/Wb/Compiler/BackLib.HC.HTML @@ -0,0 +1,739 @@ + + + + + + + + + + + +
+/*Intermediate Code to Machine Code
+
+RAX,RBX,RCX and RDX can be clobbered by
+each intermediate code's output code.
+However, intermediate codes must be
+coupled together based on the arg and
+res type specifications in the
+CICArg.  RAX is the most common reg
+for coupling intermediate codes.
+
+Internal calculations take place on
+64-bit vals, so anything which has
+found it's way into a reg has been
+sign or zero extended to 64-bits.
+*/
+
+U0 ICU8(CIntermediateCode *tmpi,U8 b)
+{
+  tmpi->ic_body[tmpi->ic_cnt++]=b;
+}
+
+U0 ICRex(CIntermediateCode *tmpi,U8 b)
+{
+  if (b)
+    tmpi->ic_body[tmpi->ic_cnt++]=b;
+}
+
+U0 ICOpSizeRex(CIntermediateCode *tmpi,U8 b)
+{
+  tmpi->ic_body[tmpi->ic_cnt++]=OC_OP_SIZE_PREFIX;
+  if (b)
+    tmpi->ic_body[tmpi->ic_cnt++]=b;
+}
+
+U0 ICU16(CIntermediateCode *tmpi,U16 w)
+{
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U16)=w;
+  tmpi->ic_cnt+=2;
+}
+
+U0 ICU24(CIntermediateCode *tmpi,U32 d)
+{//Writes extra harmless overhanging byte.
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;
+  tmpi->ic_cnt+=3;
+}
+
+U0 ICU32(CIntermediateCode *tmpi,U32 d)
+{
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;
+  tmpi->ic_cnt+=4;
+}
+
+U0 ICU64(CIntermediateCode *tmpi,U64 q)
+{
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U64)=q;
+  tmpi->ic_cnt+=8;
+}
+
+U0 ICAddRSP(CIntermediateCode *tmpi,I64 i,Bool optimize=TRUE)
+{
+  I64 j,last_start;
+  CIntermediateCode *tmpil1;
+  if (optimize) {
+    tmpil1=tmpi;
+    if (tmpi->ic_last_start<0 && !tmpi->ic_cnt &&
+          (tmpil1=OptLag1(tmpi)) && tmpil1->ic_last_start<0)
+      tmpil1=NULL;
+    if (tmpil1) {
+      j=tmpil1->ic_cnt;
+      if (tmpil1->ic_last_start==j-4 && tmpil1->ic_body[j-3]==0x83 &&
+            tmpil1->ic_body[j-4]==0x48) {
+        if (tmpil1->ic_body[j-2]==0xEC)
+          j=-tmpil1->ic_body[j-1](I8);
+        else if (tmpil1->ic_body[j-2]==0xC4)
+          j=tmpil1->ic_body[j-1](I8);
+        else
+          j=0;
+      } else if (tmpil1->ic_last_start==j-7 && tmpil1->ic_body[j-6]==0x81 &&
+            tmpil1->ic_body[j-7]==0x48) {
+        if (tmpil1->ic_body[j-5]==0xEC)
+          j=-tmpil1->ic_body[j-4](I32);
+        else if (tmpil1->ic_body[j-5]==0xC4)
+          j=tmpil1->ic_body[j-4](I32);
+        else
+          j=0;
+      } else
+        j=0;
+      if (j) {
+        if (tmpi==tmpil1) {
+          tmpi->ic_cnt=tmpi->ic_last_start;
+          i+=j;
+        } else if (!(tmpi->ic_flags&ICF_PREV_DELETED)) {
+          tmpil1->ic_flags|=ICF_DEL_PREV_INS;
+          tmpi->ic_flags=tmpi->ic_flags&~ICF_CODE_FINAL|ICF_PREV_DELETED;
+          i+=j;
+        }
+      }
+    }
+  }
+  last_start=tmpi->ic_cnt;
+  if (i>0) {
+    if (i<=I8_MAX)
+      ICU32(tmpi,0xC48348+i<<24);
+    else if (i<=I32_MAX) {
+      ICU24(tmpi,0xC48148);
+      ICU32(tmpi,i);
+    } else
+      throw('Compiler');
+  } else if (i<0) {
+    i=-i;
+    if (i<=I8_MAX)
+      ICU32(tmpi,0xEC8348+i<<24);
+    else if (i<=I32_MAX) {
+      ICU24(tmpi,0xEC8148);
+      ICU32(tmpi,i);
+    } else
+      throw('Compiler');
+  }
+  if (optimize && tmpi->ic_cnt>last_start)
+    tmpi->ic_last_start=last_start;
+}
+
+extern U0 ICMov(CIntermediateCode *tmpi,
+        CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip);
+
+#define MODR_REG                        0
+#define MODR_INDIRECT_REG               1
+#define MODR_D8_INDIRECT_REG            2
+#define MODR_D32_INDIRECT_REG           3
+#define MODR_SIB_INDIRECT_REG           4
+#define MODR_SIB_D8_INDIRECT_REG        5
+#define MODR_SIB_D32_INDIRECT_REG       6
+#define MODR_RIP_REL                    7
+#define MODR_RIP_REL_IMM_U32            8
+
+I64 ICModr1(I64 r,CICType t2,I64 r2,I64 d2)
+{//res.u8[0] is type
+//res.u8[1] is REX
+  //res.u8[2] is ModR
+  //res.u8[3] is SIB
+  I64 res=0;
+  if (t2.raw_type<RT_I64)
+    res.u8[1]=0x40;
+  else
+    res.u8[1]=0x48;
+  if (r>7) {
+    res.u8[1]+=4;
+    r&=7;
+  }
+  switch (Bsr(t2)) {
+    case MDf_REG:
+      if (r2>7) {
+        res.u8[1]++;
+        r2&=7;
+      }
+      res.u8[2]=0xC0+r<<3+r2;
+      res.u8[0]=MODR_REG;
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4 && r2<4))
+        res.u8[1]=0;
+      break;
+    case MDf_DISP:
+      if (r2>7) {
+        res.u8[1]++;
+        r2&=7;
+      }
+      if (!d2 && r2!=REG_RBP) {
+        res.u8[2]=r<<3+r2;
+        res.u8[0]=MODR_INDIRECT_REG;
+      } else if (I8_MIN<=d2<=I8_MAX) {
+        res.u8[2]=0x40+r<<3+r2;
+        res.u8[0]=MODR_D8_INDIRECT_REG;
+      } else {
+        res.u8[2]=0x80+r<<3+r2;
+        res.u8[0]=MODR_D32_INDIRECT_REG;
+      }
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
+        res.u8[1]=0;
+      break;
+    case MDf_SIB:
+      if (7<r2.u8[0]<REG_NONE)
+        res.u8[1]++;
+      if (r2.u8[1]&15>7)
+        res.u8[1]+=2;
+      if (r2.u8[0]==REG_NONE) {
+        res.u8[3]=5+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
+        res.u8[2]=4+r<<3;
+        res.u8[0]=MODR_SIB_D32_INDIRECT_REG;
+      } else {
+        res.u8[3]=r2.u8[0]&7+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
+        if (!d2 && r2.u8[0]&7!=REG_RBP) {
+          res.u8[2]=4+r<<3;
+          res.u8[0]=MODR_SIB_INDIRECT_REG;
+        } else if (I8_MIN<=d2<=I8_MAX) {
+          res.u8[2]=0x44+r<<3;
+          res.u8[0]=MODR_SIB_D8_INDIRECT_REG;
+        } else {
+          res.u8[2]=0x84+r<<3;
+          res.u8[0]=MODR_SIB_D32_INDIRECT_REG;
+        }
+      }
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
+        res.u8[1]=0;
+      break;
+    case MDf_RIP_DISP32:
+      res.u8[2]=0x05+r<<3;
+      res.u8[0]=MODR_RIP_REL;
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
+        res.u8[1]=0;
+      break;
+  }
+  return res;
+}
+
+U0 ICModr2(CIntermediateCode *tmpi,I64 i,CICType t=0,I64 d,I64 rip=0)
+{
+  switch [i.u8[0]] {
+    case MODR_REG:
+      break;
+    case MODR_INDIRECT_REG:
+      break;
+    case MODR_D8_INDIRECT_REG:
+      ICU8(tmpi,d);
+      break;
+    case MODR_D32_INDIRECT_REG:
+      ICU32(tmpi,d);
+      break;
+    case MODR_SIB_INDIRECT_REG:
+      ICU8(tmpi,i.u8[3]);
+      break;
+    case MODR_SIB_D8_INDIRECT_REG:
+      ICU8(tmpi,i.u8[3]);
+      ICU8(tmpi,d);
+      break;
+    case MODR_SIB_D32_INDIRECT_REG:
+      ICU8(tmpi,i.u8[3]);
+      ICU32(tmpi,d);
+      break;
+    case MODR_RIP_REL_IMM_U32:
+      switch (t.raw_type) {
+        case RT_I8:
+        case RT_U8:
+          d--;
+          break;
+        case RT_I16:
+        case RT_U16:
+          d-=2;
+          break;
+        default:
+          d-=4;
+      }
+    case MODR_RIP_REL:
+      ICU32(tmpi,d-(rip+4+tmpi->ic_cnt));
+      tmpi->ic_flags&=~ICF_CODE_FINAL;
+      break;
+  }
+}
+
+#define SLASH_OP_INC            0x0003000000FFFE00
+#define SLASH_OP_DEC            0x052B000000FFFE01
+#define SLASH_OP_NOT            0x0000000000F7F602
+#define SLASH_OP_NEG            0x0000000000F7F603
+#define SLASH_OP_IMM_U8         0x0000000000838000
+#define SLASH_OP_IMM_U32        0x0000000000818300
+#define SLASH_OP_MUL            0x0000000000F7F604
+#define SLASH_OP_IMUL           0x0000000000F7F605
+#define SLASH_OP_DIV            0x0000000000F7F606
+#define SLASH_OP_MOV            0x0000000000898800
+#define SLASH_OP_MOV_IMM        0x0000000000C7C600
+#define SLASH_OP_PUSH           0x0000000000FFFF06
+#define SLASH_OP_POP            0x00000000008F8F00
+#define SLASH_OP_FADD           0x0000C1DE01DCDC00
+#define SLASH_OP_FSUB           0x0000E9DE01DCDC04
+#define SLASH_OP_FSUBR          0x0000E1DE01DCDC05
+#define SLASH_OP_FMUL           0x0000C9DE01DCDC01
+#define SLASH_OP_FDIV           0x0000F9DE01DCDC06
+#define SLASH_OP_FDIVR          0x0000F1DE01DCDC07
+#define SLASH_OP_FLD            0x0000000001DDDD00
+#define SLASH_OP_FSTP           0x0000000001DDDD03
+#define SLASH_OP_FISTTP         0x0000000001DDDD01
+#define SLASH_OP_FILD           0x0000000001DFDF05
+
+U0 ICSlashOp(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 op,I64 rip)
+{
+  I64 i;
+  if (t1&MDF_REG && !op.u8[3])
+    t1=t1&(MDG_MASK|RTF_UNSIGNED)+RT_I64; //Set to 64 bit,preserving unsigned
+  i=ICModr1(op.u8[0],t1,r1,d1);
+  if (tmpi->ic_flags&ICF_LOCK && !(t1&MDF_REG) &&
+        op&~7!=SLASH_OP_MOV && op!=SLASH_OP_MOV_IMM)
+    ICU8(tmpi,OC_LOCK_PREFIX);
+  switch (t1.raw_type) {
+    case RT_I8:
+    case RT_U8:
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+op.u8[1]);
+      break;
+    case RT_I16:
+    case RT_U16:
+      ICOpSizeRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+op.u8[2]);
+      break;
+    default:
+      if (i.u8[1]!=0x48 || !op.u8[3])
+        ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+op.u8[2]);
+  }
+  if (i.u8[0]==MODR_RIP_REL&& (op==SLASH_OP_MOV_IMM || op&~7==SLASH_OP_IMM_U32))
+    i.u8[0]=MODR_RIP_REL_IMM_U32;
+  ICModr2(tmpi,i,t1,d1,rip);
+}
+
+U0 ICPush(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)
+{
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      if (r1>7)
+        ICU16(tmpi,0x5049+(r1&7)<<8);
+      else
+        ICU8(tmpi,0x50+r1);
+      return;
+    case MDf_IMM:
+      if (I8_MIN<=d1<=I8_MAX)
+        ICU16(tmpi,0x6A+d1<<8);
+      else if (I32_MIN<=d1<=I32_MAX) {
+        ICU8(tmpi,0x68);
+        ICU32(tmpi,d1);
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);
+        ICU8(tmpi,0x50+REG_RBX);
+      }
+      return;
+    case MDf_STK:
+      return;
+    case MDf_DISP:
+    case MDf_SIB:
+    case MDf_RIP_DISP32:
+      switch (t1.raw_type) {
+        case RT_I64:
+        case RT_U64:
+        case RT_F64:
+          ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_PUSH,rip);
+          return;
+      }
+      break;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);
+  ICU16(tmpi,0x5048+REG_RBX<<8);
+}
+
+U0 ICPushRegs(CIntermediateCode *tmpi,I64 mask)
+{
+  I64 i;
+  for (i=0;i<REG_REGS_NUM;i++) {
+    if (Bt(&mask,i)) {
+      if (i>7)
+        ICU16(tmpi,0x5049+(i&7)<<8);
+      else
+        ICU8(tmpi,0x50+i);
+    }
+  }
+}
+
+U0 ICPop(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)
+{
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      if (r1>7)
+        ICU16(tmpi,0x5849+(r1&7)<<8);
+      else
+        ICU8(tmpi,0x58+r1);
+      break;
+    case MDf_DISP:
+    case MDf_RIP_DISP32:
+    case MDf_SIB:
+      if (t1.raw_type<RT_I64) {
+        ICU8(tmpi,0x58+REG_RBX);
+        ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
+      } else
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_POP,rip);
+      break;
+    case MDf_STK:
+    case MDf_IMM:
+      ICU8(tmpi,0x58+REG_RBX);
+      ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
+      break;
+    default:
+      ICAddRSP(tmpi,8);
+  }
+}
+
+U0 ICPopRegs(CIntermediateCode *tmpi,I64 mask)
+{
+  I64 i;
+  for (i=REG_REGS_NUM-1;i>=0;i--) {
+    if (Bt(&mask,i)) {
+      if (i>7)
+        ICU16(tmpi,0x5849+(i&7)<<8);
+      else
+        ICU8(tmpi,0x58+i);
+    }
+  }
+}
+
+U0 ICZero(CIntermediateCode *tmpi,I64 r)
+{
+  if (r>7) {
+    r&=7;
+    ICU24(tmpi,0xC0334D+r<<16+r<<19);
+  } else
+    ICU16(tmpi,0xC033+r<<8+r<<11);
+}
+
+U0 ICTest(CIntermediateCode *tmpi,I64 r)
+{
+  I64 i=0xC08548; //TEST R,R
+  if (r>7) {
+    i+=5;
+    r&=7;
+  }
+  ICU24(tmpi,i+r<<16+r<<19);
+}
+
+I64 ICBuiltInFloatConst(F64 d)
+{//Returns 2-byte opcode for FLD const or zero
+  if (!d)
+    return 0xEED9;
+  else if (d==1.0)
+    return 0xE8D9;
+  else if (GetOption(OPTf_NO_BUILTIN_CONST))
+    return 0;
+  else if (d==pi)
+    return 0xEBD9;
+  else if (d==log2_10)
+    return 0xE9D9;
+  else if (d==log2_e)
+    return 0xEAD9;
+  else if (d==log10_2)
+    return 0xECD9;
+  else if (d==loge_2)
+    return 0xEDD9;
+  else
+    return 0;
+}
+
+U0 ICMov(CIntermediateCode *tmpi,
+        CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip)
+{
+  I64 i,cnt1,cnt2,b1_rex,b2_rex,b1,b2,b1_modr,b2_modr,
+        b1_r1,b1_r2,b2_r1,b2_r2,last_start=tmpi->ic_cnt;
+  CIntermediateCode *tmpil1;
+  Bool old_lock=Btr(&tmpi->ic_flags,ICf_LOCK);
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      if (t2&MDF_IMM) {
+        if (!d2)
+          ICZero(tmpi,r1);
+        else if (0<=d2<=U8_MAX) {
+          ICZero(tmpi,r1);
+          if (r1>7)
+            ICU24(tmpi,d2<<16+(0xB0+r1&7)<<8+0x41);
+          else if (r1>3)
+            ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);
+          else
+            ICU16(tmpi,d2<<8+0xB0+r1);
+        } else if (I8_MIN<=d2<0) {
+          if (r1>7) {
+            r1&=7;
+            ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x41);
+            ICU32(tmpi,0xC0BE0F4D+r1<<24+r1<<27);
+          } else {
+            if (r1>3)
+              ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);
+            else
+              ICU16(tmpi,d2<<8+0xB0+r1);
+            ICU32(tmpi,0xC0BE0F48+r1<<24+r1<<27);
+          }
+        } else if (0<=d2<=U32_MAX) {
+          if (r1>7) {
+            r1&=7;
+            ICU16(tmpi,(0xB8+r1)<<8+0x41);
+            ICU32(tmpi,d2);
+          } else {
+            ICU8(tmpi,0xB8+r1);
+            ICU32(tmpi,d2);
+          }
+        } else if (I32_MIN<=d2<0) {
+          if (r1>7) {
+            r1&=7;
+            ICU16(tmpi,(0xB8+r1)<<8+0x41);
+            ICU32(tmpi,d2);
+            ICU24(tmpi,0xC0634D+r1<<16+r1<<19);
+          } else {
+            ICU8(tmpi,0xB8+r1);
+            ICU32(tmpi,d2);
+            ICU24(tmpi,0xC06348+r1<<16+r1<<19);
+          }
+        } else {
+          i=0xB848;
+          if (r1>7) {
+            i++;
+            r1&=7;
+          }
+          ICU16(tmpi,i+r1<<8);
+          ICU64(tmpi,d2);
+        }
+      } else if (t2&MDF_STK)
+        ICPop(tmpi,t1,r1,d1,rip);
+      else {
+        if (r1==r2 && t2&MDF_REG)
+          goto move_done;
+        if (t2&MDF_REG)
+          t2=MDF_REG+RT_I64;
+        i=ICModr1(r1,t2,r2,d2);
+        if (t2.raw_type!=RT_U32)
+          i|=0x4800;
+        ICRex(tmpi,i.u8[1]);
+        switch (t2.raw_type) {
+          case RT_I8:
+            ICU24(tmpi,i.u8[2]<<16+0xBE0F);
+            break;
+          case RT_I16:
+            ICU24(tmpi,i.u8[2]<<16+0xBF0F);
+            break;
+          case RT_I32:
+            ICU16(tmpi,i.u8[2]<<8+0x63);
+            break;
+
+          case RT_U8:
+            ICU24(tmpi,i.u8[2]<<16+0xB60F);
+            break;
+          case RT_U16:
+            ICU24(tmpi,i.u8[2]<<16+0xB70F);
+            break;
+          default:
+            ICU16(tmpi,i.u8[2]<<8+0x8B);
+        }
+        ICModr2(tmpi,i,,d2,rip);
+      }
+      break;
+    case MDf_STK:
+      if (tmpi->ic_flags&ICF_PUSH_CMP)
+        ICPopRegs(tmpi,1<<REG_RBX);
+      if (t1.raw_type<t2.raw_type)
+        ICPush(tmpi,t2&MDG_MASK+t1.raw_type,r2,d2,rip);
+      else
+        ICPush(tmpi,t2,r2,d2,rip);
+      if (tmpi->ic_flags&ICF_PUSH_CMP)
+        ICPushRegs(tmpi,1<<REG_RBX);
+      break;
+    case MDf_DISP:
+    case MDf_RIP_DISP32:
+    case MDf_SIB:
+      if (t2&MDF_IMM && (t1.raw_type<RT_I64 || (I32_MIN<=d2<=I32_MAX))) {
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_MOV_IMM,rip);
+        switch (t1.raw_type) {
+          case RT_I8:
+          case RT_U8:
+            ICU8(tmpi,d2);
+            break;
+          case RT_I16:
+          case RT_U16:
+            ICU16(tmpi,d2);
+            break;
+          default:
+            ICU32(tmpi,d2);
+        }
+      } else {
+        if (t2&MDF_REG)
+          ICSlashOp(tmpi,t1,r1,d1,r2+SLASH_OP_MOV,rip);
+        else {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t2,r2,d2,rip);
+          ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
+        }
+      }
+      break;
+  }
+move_done:
+  if (!((t1|t2)&(MDF_STK|MDF_RIP_DISP32))) {
+    tmpil1=tmpi;
+    if (tmpi->ic_last_start<0 && (tmpil1=OptLag1(tmpi)) &&
+          tmpil1->ic_last_start<0)
+      tmpil1=NULL;
+    if (tmpil1) {
+      if (tmpil1==tmpi)
+        cnt1=last_start-tmpil1->ic_last_start;
+      else {
+        if (!(tmpil1->ic_flags&ICF_CODE_FINAL))
+          tmpi->ic_flags&=~ICF_CODE_FINAL;
+        if (last_start)
+          cnt1=0;
+        else
+          cnt1=tmpil1->ic_cnt-tmpil1->ic_last_start;
+      }
+      cnt2=tmpi->ic_cnt-last_start;
+      if (cnt1 && cnt1==cnt2) {
+        b1_rex=tmpil1->ic_body[tmpil1->ic_last_start];
+        b2_rex=tmpi->ic_body[last_start];
+        if (b1_rex&0x48==0x48 && b2_rex&0x48==0x48) {
+          for (i=1;i<cnt1;i++)
+            if ((b1=tmpil1->ic_body[tmpil1->ic_last_start+i])==
+                  (b2=tmpi->ic_body[last_start+i])) {
+              if (i==1 && (b2==0x89 || b2==0x8B)) {
+                b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];
+                b1_r1=b1_modr&7 +Bt(&b1_rex,0)<<3;
+                b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;
+                b2_modr=tmpi->ic_body[last_start+2];
+                b2_r1=b2_modr&7   +Bt(&b2_rex,0)<<3;
+                b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;
+                if (cnt1==3 && b2_modr&0xC0==0xC0) {
+                  if (b2_r1==b2_r2)
+                    goto move_redundant;
+                  if (b1_modr&0xC0==0xC0) {
+                    if (b1_r1==b2_r2 && b2_r1==b1_r2)
+                      goto move_redundant;
+                  }
+                } else if (b1_rex!=b2_rex || b1_r1==b1_r2 || (t1|t2)&MDF_SIB)
+                  break;
+              } else if (b1_rex!=b2_rex)
+                break;
+            } else if (i!=1)
+              break;
+            else if (b2!=0x89 && b2!=0x8B)
+              break;
+            else {
+              b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];
+              b1_r1=b1_modr&7   +Bt(&b1_rex,0)<<3;
+              b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;
+              b2_modr=tmpi->ic_body[last_start+2];
+              b2_r1=b2_modr&7   +Bt(&b2_rex,0)<<3;
+              b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;
+              if (cnt1==3 && b2_modr&0xC0==0xC0) {
+                if (b2_r1==b2_r2)
+                  goto move_redundant;
+                if (b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89) {
+                  if (b1_modr&0xC0==0xC0) {
+                    if (b1_r1==b2_r1 && b1_r2==b2_r2 ||
+                          b1_r1==b2_r2 && b2_r1==b1_r2)
+                      goto move_redundant;
+                  }
+                  if (b1_rex!=b2_rex)
+                    break;
+                } else
+                  break;
+              } else if (b1_r1==b1_r2 || (t1|t2)&MDF_SIB || b1_rex!=b2_rex ||
+                    !(b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89))
+                break;
+            }
+          if (i==cnt1) {
+move_redundant:
+            tmpi->ic_cnt=last_start;
+          }
+        }
+      }
+    }
+  }
+  if (tmpi->ic_cnt>last_start>tmpi->ic_last_start)
+    tmpi->ic_last_start=last_start;
+  BEqu(&tmpi->ic_flags,ICf_LOCK,old_lock);
+}
+
+U0 ICLea(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CCmpCtrl *cc,U8 *buf,I64 rip)
+{
+  I64 i;
+  CAOTAbsAddr *tmpa;
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      i=ICModr1(r1,t2,r2,d2);
+      i.u8[1]|=0x48;
+      ICU24(tmpi,i.u8[2]<<16+0x8D00+i.u8[1]);
+      ICModr2(tmpi,i,,d2,rip);
+      break;
+    case MDf_STK:
+      if (t2&MDF_RIP_DISP32) {
+        ICU8(tmpi,0x68);
+        ICU32(tmpi,d2);
+        if (cc->flags&CCF_AOT_COMPILE && buf && !(cc->flags&CCF_NO_ABSS)) {
+          tmpa=CAlloc(sizeof(CAOTAbsAddr));
+          tmpa->next=cc->aotc->abss;
+          tmpa->type=AAT_ADD_U32;
+          cc->aotc->abss=tmpa;
+          tmpa->rip=rip+tmpi->ic_cnt-4;
+        }
+        tmpi->ic_flags&=~ICF_CODE_FINAL;
+        break;
+      } // Fall thru
+    default:
+      ICLea(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,cc,buf,rip);
+      ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RCX,0,rip);
+  }
+}
+
+U0 ICDeref(CIntermediateCode *tmpi,I64 rip)
+{
+  CICType t;
+  t=tmpi->res.type.raw_type;
+  if (t>tmpi->arg1_type_pointed_to)
+    t=tmpi->arg1_type_pointed_to;
+  if (tmpi->arg1.type&MDF_REG)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,REG_RCX,0,rip);
+  }
+}
+
+ diff --git a/public/Wb/Compiler/CExcept.HC.HTML b/public/Wb/Compiler/CExcept.HC.HTML new file mode 100755 index 0000000..0c1c54a --- /dev/null +++ b/public/Wb/Compiler/CExcept.HC.HTML @@ -0,0 +1,284 @@ + + + + + + + + + + + +
+U0 LexPutToken(CCmpCtrl *cc)
+{//Print cur token to StdOut. (Crude)
+  '"';
+  if (cc->token==TK_IDENT || cc->token==TK_STR)
+    "%s",cc->cur_str;
+  else if (cc->token==TK_I64)
+    "INT:%X",cc->cur_i64;
+  else if (cc->token==TK_CHAR_CONST)
+    "U8:%X",cc->cur_i64;
+  else if (cc->token==TK_F64)
+    "FLOAT:%e",cc->cur_f64;
+  else if (cc->token=='\n')
+    "<NEW_LINE>";
+  else if (Bt(char_bmp_displayable,cc->token))
+    '' cc->token;
+  else {
+    "T:%X",cc->token;
+  }
+  "\" ";
+}
+
+U8 *LexPutLine(CCmpCtrl *cc,U8 *start)
+{//Print cur pos to end of line to StdOut.
+  I64 ch;
+  U8 *ptr;
+  if (!start) return NULL;
+  if (cc->lex_include_stk->flags&LFSF_DOC)
+    return DocPutLine(cc->lex_include_stk->doc,start);
+  else {
+    ptr=start;
+    while (ch=*ptr++) {
+      if (ch=='\n') {
+        if (*ptr=='\r')
+          ptr++;
+        break;
+      } else if (ch=='\r') {
+        if (*ptr=='\n')
+          ptr++;
+        break;
+      }
+      '' ch;
+    }
+    if (!ch) ptr--;
+    '\n';
+    return ptr;
+  }
+  return NULL;
+}
+
+U0 LexPutPos(CCmpCtrl *cc)
+{//Print token, line link and, then, LexPutLine().
+  LexPutToken(cc);
+  FixSet(cc->lex_include_stk->full_name,cc->lex_include_stk->line_num);
+  if (IsRaw)
+    "%s,%d ",cc->lex_include_stk->full_name,cc->lex_include_stk->line_num;
+  else {
+    PutFileLink(cc->lex_include_stk->full_name,,cc->lex_include_stk->line_num);
+    AdamErr("%s,%d\n",
+          cc->lex_include_stk->full_name,cc->lex_include_stk->line_num);
+    '' CH_SPACE;
+  }
+  LexPutLine(cc,cc->lex_include_stk->line_start);
+}
+
+U0 LexWarn(CCmpCtrl *cc,U8 *str=NULL)
+{//Print warn msg, then, LexPutPos().
+  if (str) PrintWarn(str);
+  if (cc->htc.fun) {
+    "in fun '%s'.\n",cc->htc.fun->str;
+    if (IsRaw)
+      "%s\n",cc->htc.fun->src_link;
+    else {
+      "$LK,\"%s\"$\n",cc->htc.fun->src_link;
+      AdamErr("%s\n",cc->htc.fun->src_link);
+    }
+  } else
+    LexPutPos(cc);
+  cc->warning_cnt++;
+}
+
+U0 LexExcept(CCmpCtrl *cc,U8 *str=NULL)
+{//Print err msg, LexPutPos() and throw exception.
+  if (!Bt(&sys_run_level,RLf_ADAM_SERVER)) {
+    Raw(ON);
+    "Note: Still in boot phase.\n";
+  }
+  if (str) PrintErr(str);
+  if (!IsRaw)
+    AdamErr("Task:%08X %s\n",Fs,str);
+  LexPutPos(cc);
+  cc->error_cnt++;
+  FlushMsgs;
+  if (!Bt(&sys_run_level,RLf_ADAM_SERVER))
+    Dbg("Type \"Fix;\"");
+  throw('Compiler');
+}
+
+U0 UndefinedExtern()
+{
+  PrintErr("Undefined Extern\nat %P\n",Caller);
+  throw('UndefExt');
+}
+
+U0 UnusedExternWarning(CCmpCtrl *cc,CHashClass *tmpc)
+{
+  PrintWarn("Unused extern '%s'\n",tmpc->str);
+  cc->warning_cnt++;
+}
+
+U0 ParenWarning(CCmpCtrl *cc)
+{
+  if (Bt(&cc->opts,OPTf_WARN_PAREN) &&
+        !(cc->lex_include_stk->flags&LFSF_DEFINE))
+    LexWarn(cc,"Unnecessary parenthesis ");
+}
+
+U0 ICClassPut(CHashClass *c)
+{
+  I64 i;
+  if (!c) return;
+  if (c->ptr_stars_cnt>4) {
+    PrintErr("put_class ptrcnt=%d\n",c->ptr_stars_cnt);
+    while (TRUE)
+//TODO:
+      Yield;
+  }
+  for (i=0;i<c->ptr_stars_cnt;i++)
+    '*';
+  c-=c->ptr_stars_cnt;
+  if (c->str)
+    "%s",c->str;
+  else {
+    PrintErr("put_class str=NULL\n");
+    while (TRUE)
+//TODO:
+      Yield;
+  }
+  '' CH_SPACE;
+}
+
+U0 ICArgPut(CICArg *a,I64 type_pointed_to)
+{
+  if (type_pointed_to)
+    "[%Z](%Z) %Z ",a->type.raw_type,"ST_RAW_TYPES",
+          type_pointed_to,"ST_RAW_TYPES",Bsr(a->type>>8)+1,"ST_TY_TYPES";
+  else
+    "%Z %Z ",a->type.raw_type,"ST_RAW_TYPES",
+          Bsr(a->type>>8)+1,"ST_TY_TYPES";
+  switch (Bsr(a->type)) {
+    case MDf_STK:
+      "STK";
+      break;
+    case MDf_IMM:
+      "#%X",a->disp;
+      break;
+    case MDf_REG:
+      "%Z",a->reg,"ST_U64_REGS";
+      break;
+    case MDf_DISP:
+      "%X[%Z]",a->disp,a->reg,"ST_U64_REGS";
+      break;
+    case MDf_RIP_DISP32:
+      "[%X]",a->disp;
+      break;
+    case MDf_SIB:
+      if (a->disp)
+        "%X",a->disp;
+      if (a->reg==REG_RIP)
+        '[';
+      else
+        "[%Z+",a->reg&15,"ST_U64_REGS";
+      "%Z",a->reg>>8&15,"ST_U64_REGS";
+      switch (a->reg>>14) {
+        case 0: "]";   break;
+        case 1: "*2]"; break;
+        case 2: "*4]"; break;
+        case 3: "*8]"; break;
+      }
+      break;
+  }
+  '' CH_SPACE;
+}
+
+U0 ICPut(CCmpCtrl *cc,CIntermediateCode *tmpi)
+{
+  I64 opcode=tmpi->ic_code,i;
+  if (opcode>=IC_END_EXP && opcode!=IC_NOP2) {
+    "%15ts %016X ",intermediate_code_table[opcode].name,tmpi->ic_data;
+    if (cc->pass) {
+      if (tmpi->res.type.mode) {
+        "$PURPLE$RES:$FG$";
+        ICArgPut(&tmpi->res,0);
+      }
+      if (tmpi->arg1.type.mode) {
+        "$PURPLE$ARG1:$FG$";
+        if (intermediate_code_table[tmpi->ic_code].type==IST_DEREF ||
+              intermediate_code_table[tmpi->ic_code].type==IST_ASSIGN)
+          ICArgPut(&tmpi->arg1,tmpi->arg1_type_pointed_to);
+        else
+          ICArgPut(&tmpi->arg1,0);
+      }
+      if (tmpi->arg2.type.mode) {
+        "$PURPLE$ARG2:$FG$";
+        ICArgPut(&tmpi->arg2,0);
+      }
+      "$PURPLE$:$FG$";
+    }
+    ICClassPut(tmpi->ic_class);
+    if (tmpi->ic_flags & ICF_LOCK)
+      "$BROWN$lock$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG2_TO_F64)
+      "$LTBLUE$a2d$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG2_TO_INT)
+      "$GREEN$a2i$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG1_TO_F64)
+      "$LTBLUE$a1d$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG1_TO_INT)
+      "$GREEN$a1i$FG$ ";
+    if (tmpi->ic_flags & ICF_RES_TO_F64)
+      "$LTBLUE$rd$FG$ ";
+    if (tmpi->ic_flags & ICF_RES_TO_INT)
+      "$GREEN$ri$FG$ ";
+    if (tmpi->ic_flags & ICF_USE_F64)
+      "[F64] ";
+    if (tmpi->ic_flags & ICF_USE_UNSIGNED)
+      "[unsigned] ";
+    if (tmpi->ic_flags & ICF_USE_INT)
+      "[int] ";
+    if (tmpi->ic_flags & ICF_RES_NOT_USED)
+      "NO_RES ";
+    if (tmpi->ic_flags & ICF_BY_VAL)
+      "BY_VAL ";
+    if (tmpi->ic_flags & ICF_PUSH_RES)
+      "PUSH ";
+    if (tmpi->ic_flags & ICF_PUSH_CMP)
+      "PUSH_CMP ";
+    if (tmpi->ic_flags & ICF_POP_CMP)
+      "POP_CMP ";
+    if (tmpi->ic_flags & ICF_DEL_PREV_INS)
+      "DEL_PREV ";
+    if (tmpi->ic_flags & ICF_PREV_DELETED)
+      "PREV_DEL ";
+    for (i=0;i<3;i++) {
+      if (Bt(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0+i))
+        "DONT_PUSH#%d ",i;
+      if (Bt(&tmpi->ic_flags,ICf_DONT_POP_FLOAT0+i))
+        "DONT_POP#%d ",i;
+    }
+    if (tmpi->ic_flags & ICF_ALT_TEMPLATE)
+      "ALT_TMP ";
+    '\n';
+  }
+}
+
+ diff --git a/public/Wb/Compiler/CExts.HC.HTML b/public/Wb/Compiler/CExts.HC.HTML new file mode 100755 index 0000000..a46fe69 --- /dev/null +++ b/public/Wb/Compiler/CExts.HC.HTML @@ -0,0 +1,77 @@ + + + + + + + + + + + +
+import U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e);
+import U0 DocBinsValidate(CDoc *doc);
+import U0 DocDel(CDoc *doc);
+import U0 DocLoad(CDoc *doc,U8 *src2,I64 size);
+import CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL);
+import CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...);
+import CDocEntry *DocPutLine(CDoc *doc,CDocEntry *doc_e);
+import I64 DocSize(CDoc *doc);
+import Bool DocWrite(CDoc *doc,Bool prompt=FALSE);
+extern U8 *CmdLinePmt();
+extern I64 HashEntrySize2(CHashSrcSym *tmph);
+extern Bool IsLexExpression2Bin(CCmpCtrl *cc,U8 **_machine_code);
+extern I64 Lex(CCmpCtrl *cc);
+extern I64 LexExpression(CCmpCtrl *cc);
+extern I64 LexGetChar(CCmpCtrl *cc);
+extern CCodeMisc *OptLabelFwd(CCodeMisc *lb);
+extern CIntermediateCode *OptPass012(CCmpCtrl *cc);
+extern U0 OptPass3(CCmpCtrl *cc,COptReg *reg_offsets);
+extern U0 OptPass4(CCmpCtrl *cc,COptReg *reg_offsets,I64 *_type);
+extern U0 OptPass5(CCmpCtrl *cc);
+extern U0 OptPass6(CCmpCtrl *cc);
+extern I64 OptPass789A(
+        CCmpCtrl *cc,COptReg *reg_offsets,U8 *buf,CDbgInfo **_dbg);
+extern CHashClass *PrsClass(
+        CCmpCtrl *cc,I64 keyword,I64 fsp_flags,Bool is_extern);
+extern CHashFun *PrsFunJoin(
+        CCmpCtrl *cc,CHashClass *tmp_return,U8 *name,I64 fsp_flags);
+extern I64 PrsKeyWord(CCmpCtrl *cc);
+extern Bool PrsStmt(CCmpCtrl *cc,I64 try_cnt=0,
+        CCodeMisc *lb_break=NULL,I64 cmp_flags=CMPF_PRS_SEMICOLON);
+extern U0 PrsStreamBlk(CCmpCtrl *cc);
+extern CHashClass *PrsType(CCmpCtrl *cc,CHashClass **_tmpc1,
+        I64 *_mode,CMemberLst *tmpm,U8 **_ident,CHashFun **_fun_ptr,
+        CHashExport **_tmpex,CArrayDim *tmpad,I64 fsp_flags);
+extern I64 PrsUnaryModifier(CCmpCtrl *cc,CPrsStk *ps,
+        CMemberLst **_local_var,CArrayDim **_tmpad,I64 *unary_post_prec);
+extern I64 PrsUnaryTerm(
+        CCmpCtrl *cc,CPrsStk *ps,CMemberLst **_local_var,CArrayDim **_tmpad,
+        I64 *max_prec,I64 *unary_pre_prec,I64 *paren_prec);
+extern U0 PrsVarInit2(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,
+        CArrayDim *tmpad,U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass);
+_extern CMP_TEMPLATES                   U32 cmp_templates[1];
+_extern CMP_TEMPLATES_DONT_POP          U32 cmp_templates_dont_pop[1];
+_extern CMP_TEMPLATES_DONT_PUSH2        U32 cmp_templates_dont_push2[1];
+_extern CMP_TEMPLATES_DONT_PUSH         U32 cmp_templates_dont_push[1];
+_extern CMP_TEMPLATES_DONT_PUSH_POP     U32 cmp_templates_dont_push_pop[1];
+
+ diff --git a/public/Wb/Compiler/CHash.HC.HTML b/public/Wb/Compiler/CHash.HC.HTML new file mode 100755 index 0000000..aeaaaa8 --- /dev/null +++ b/public/Wb/Compiler/CHash.HC.HTML @@ -0,0 +1,172 @@ + + + + + + + + + + + +
+I64 HashEntrySize(CHashSrcSym *tmph)
+{//Logical size of a std system hash entry.
+  CDbgInfo *dbg_info;
+  CBinFile *bfh;
+  switch (HashTypeNum(tmph)) {
+    case HTt_DEFINE_STR:
+      return MSize(tmph(CHashDefineStr *)->data);
+    case HTt_GLBL_VAR:
+    case HTt_CLASS:
+    case HTt_INTERNAL_TYPE:
+      return tmph(CHashClass *)->size;
+    case HTt_FUN:
+      if (dbg_info=tmph->dbg_info)
+        return dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+              -dbg_info->body[0];
+      else
+        return -1;
+    case HTt_FILE:
+      return MSize(tmph(CHashGeneric *)->user_data0);
+    case HTt_MODULE:
+      if (StrCmp(tmph->str,KERNEL_MODULE_NAME))
+        return MSize(tmph(CHashGeneric *)->user_data0);
+      else {
+        bfh=mem_boot_base-sizeof(CBinFile);
+        return bfh->file_size;
+      }
+    case HTt_WORD:
+      return StrLen(tmph->str);
+  }
+  return -1;
+}
+
+I64 HashEntrySize2(CHashSrcSym *tmph)
+{//Memory size of a std system hash entry.
+  CDbgInfo *dbg_info;
+  I64 res=MSize2(tmph);
+  if (!(tmph->type&HTT_DICT_WORD))
+    res+=MSize2(tmph->str);
+  if (tmph->type & HTG_SRC_SYM) {
+    res+=MSize2(tmph->src_link);
+    res+=MSize2(tmph->idx);
+    res+=MSize2(tmph->import_name);
+    res+=LinkedLstSize(tmph->ie_lst);
+    if (tmph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM))
+      res+=MSize2(tmph->dbg_info);
+    if (tmph->type & HTT_CLASS)
+      res+=MemberLstSize(tmph);
+    else if (tmph->type & HTT_FUN) {
+      res+=MemberLstSize(tmph);
+      if (dbg_info=tmph->dbg_info)
+//This should be MSize() but it would crash on AOT .BIN.Z file funs.
+        res+=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+              -dbg_info->body[0];
+    } else if (tmph->type&HTT_DEFINE_STR)
+      res+=MSize2(tmph(CHashDefineStr *)->data);
+    else if (tmph->type & HTT_GLBL_VAR) {
+      res+=LinkedLstSize(tmph(CHashGlblVar *)->dim.next);
+      if (!(tmph(CHashGlblVar *)->flags&GVF_ALIAS))
+        res+=MSize2(tmph(CHashGlblVar *)->data_addr);
+      if (tmph(CHashGlblVar *)->fun_ptr)
+        res+=HashEntrySize2(tmph(CHashGlblVar *)->fun_ptr
+              -tmph(CHashGlblVar *)->fun_ptr->ptr_stars_cnt);
+    }
+  } else if (tmph->type & HTT_FILE)
+    res+=MSize2(tmph(CHashGeneric *)->user_data0);
+  else if (tmph->type & HTT_MODULE &&
+        StrCmp(tmph->str,KERNEL_MODULE_NAME))
+    res+=MSize2(tmph(CHashGeneric *)->user_data0);
+  return res;
+}
+
+I64 HashTableSize2(CHashTable *table)
+{//Memory size of std system hash table and all entries.
+  I64 i,res=0;
+  CHashSrcSym *tmph;
+  if (!table)
+    return 0;
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      res+=HashEntrySize2(tmph);
+      tmph=tmph->next;
+    }
+  }
+  res+=MSize2(table->body);
+  res+=MSize2(table);
+  return res;
+}
+
+U0 MapFileWrite(CHashTable *h,U8 *map_name,U8 drv_let)
+{
+  CHashSrcSym *tmph;
+  I64 i,size;
+  U8 *src_link;
+  CDoc *doc;
+  CDocBin *tmpb;
+  CDbgInfo *dbg_info;
+
+  doc=DocNew(map_name);
+  doc->flags|=DOCF_NO_CURSOR;
+  for (i=0;i<=h->mask;i++) {
+    tmph=h->body[i];
+    while (tmph) {
+      if (tmph->src_link && !(tmph->type & (HTF_IMPORT | HTF_PRIVATE))) {
+        src_link=StrNew(tmph->src_link);
+        if (drv_let && StrLen(src_link)>=4)
+          src_link[3]=drv_let;
+        if (dbg_info=tmph->dbg_info) {
+          size=offset(CDbgInfo.body)+
+                sizeof(U32)*(dbg_info->max_line+2-dbg_info->min_line);
+          if (size>MSize(dbg_info)) {
+            "Corrupt Map Entry\n";
+            dbg_info=NULL;
+          } else {
+            if (dbg_info->min_line<=dbg_info->max_line) {
+              tmpb=CAlloc(sizeof(CDocBin));
+              tmpb->size=size;
+              tmpb->data=MAlloc(size);
+              MemCpy(tmpb->data,dbg_info,size);
+              tmpb->num=doc->cur_bin_num++;
+              tmpb->use_cnt=1;
+              QueIns(tmpb,doc->bin_head.last);
+            } else
+              dbg_info=NULL;
+          }
+        }
+        if (dbg_info)
+          DocPrint(doc,"$LK,\"%s\",A=\"%s\",BI=%d$\n",
+                tmph->str,src_link,tmpb->num);
+        else
+          DocPrint(doc,"$LK,\"%s\",A=\"%s\"$\n",tmph->str,src_link);
+
+        Free(src_link);
+      }
+      tmph=tmph->next;
+    }
+  }
+  DocBinsValidate(doc);
+  DocWrite(doc);
+  DocDel(doc);
+}
+
+ diff --git a/public/Wb/Compiler/CInit.HC.HTML b/public/Wb/Compiler/CInit.HC.HTML new file mode 100755 index 0000000..0c8b5fd --- /dev/null +++ b/public/Wb/Compiler/CInit.HC.HTML @@ -0,0 +1,361 @@ + + + + + + + + + + + +
+#define INTERNAL_TYPES_NUM      17
+
+class CInternalType
+{
+  U8 type,size,name[8];
+} internal_types_table[INTERNAL_TYPES_NUM]={
+  {RT_I0,0,"I0i"},{RT_I0,0,"I0"},{RT_U0,0,"U0i"},{RT_U0,0,"U0"},
+  {RT_I8,1,"I8i"},{RT_I8,1,"I8"},{RT_I8,1,"Bool"},
+  {RT_U8,1,"U8i"},{RT_U8,1,"U8"},
+  {RT_I16,2,"I16i"},{RT_U16,2,"U16i"},
+  {RT_I32,4,"I32i"},{RT_U32,4,"U32i"},
+  {RT_I64,8,"I64i"},{RT_U64,8,"U64i"},
+  {RT_F64,8,"F64i"},{RT_F64,8,"F64"},
+};
+
+CIntermediateStruct intermediate_code_table[IC_ICS_NUM]={
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"END"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOP1"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"END_EXP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOP2"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"LABEL"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"CALL_START"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"CALL_END"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"CALL_END2"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RETURN_VAL"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RETURN_VAL2"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"IMM_I64"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"IMM_F64"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"STR_CONST"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ABS_ADDR"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ADDR_IMPORT"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"HEAP_GLBL"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SIZEOF"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"TYPE"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"GET_LABEL"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"RBP"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"REG"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"FS"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV_FS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GS"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV_GS"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"LEA"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_I64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_F64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_BOOL"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TOUPPER"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"HOLYC_TYPECAST"},
+  {IS_1_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ADDR"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"COM"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"NOT"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"UNARY_MINUS"},
+  {IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF"},
+  {IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF_PP"},
+  {IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF_MM"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"_PP"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"_MM"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"PP_"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"MM_"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SHL"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SHR"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SHL_CONST"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SHR_CONST"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"POWER"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"MUL"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"DIV"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"MOD"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"AND"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"OR"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"XOR"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ADD"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SUB"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"ADD_CONST"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SUB_CONST"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"EQU_EQU"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"NOT_EQU"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"LESS"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"GREATER_EQU"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"GREATER"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"LESS_EQU"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"PUSH_CMP"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"AND_AND"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"OR_OR"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"XOR_XOR"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN_PP"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN_MM"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SHL_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SHR_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"MUL_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"DIV_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"MOD_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"AND_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"OR_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"XOR_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ADD_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SUB_EQU"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"JMP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SUB_CALL"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SWITCH"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOBOUND_SWITCH"},
+  {IS_V_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ADD_RSP"},
+  {IS_V_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ADD_RSP1"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ENTER"},
+  {IS_0_ARG,0,IST_ASSIGN,FALSE,FALSE,0,0,0,"PUSH_REGS"},
+  {IS_0_ARG,0,IST_ASSIGN,FALSE,FALSE,0,0,0,"POP_REGS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"LEAVE"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RET"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_INDIRECT"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_INDIRECT2"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_IMPORT"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_EXTERN"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"ASM"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"PUSH"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"POP"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CLFLUSH"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"INVLPG"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U8"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U16"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U32"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U8"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U16"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U32"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RFLAGS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CARRY"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RFLAGS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RAX"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RAX"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RBP"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RBP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RSP"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RSP"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"RIP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"RDTSC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTC"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BSF"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BSR"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INIT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INS_REV"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_REM"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"STRLEN"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_ZERO"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_ZERO"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_CARRY"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_CARRY"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_EQU_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_LESS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_GREATER_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_GREATER"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_LESS_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2EQU_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2NOT_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2LESS"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2GREATER_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2GREATER"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2LESS_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_NOT_ZERO"},
+  {IS_1_ARG,0,IST_DEREF,FALSE,TRUE,0,0,0,"BR_MM_ZERO"},
+  {IS_1_ARG,0,IST_DEREF,FALSE,TRUE,0,0,0,"BR_MM_NOT_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_AND_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_AND_NOT_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_OR_OR_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_OR_OR_NOT_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U8"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U16"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U32"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ABS_I64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SIGN_I64"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"I64_MIN"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"U64_MIN"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"I64_MAX"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"U64_MAX"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"MOD_U64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SQRI64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SQRU64"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SQR"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ABS"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SQRT"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SIN"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"COS"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"TAN"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ATAN"},
+};
+
+U0 CmpLoadDefines()
+{
+  DefineLstLoad("ST_RAW_TYPES",
+        " \0 \0I0\0U0\0I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0"
+        "F32\0UF32\0F64\0UF64\0");
+  DefineLstLoad("ST_NATURAL_TYPES",
+        "I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0F64\0String\0");
+  DefineLstLoad("ST_INT_SIZE_TYPES",
+        "I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0");
+  DefineLstLoad("ST_TY_TYPES","NULL\0STK\0IMM\0REG\0DISP\0SIB\0RIP\0");
+  DefineLstLoad("ST_U8_REGS","AL\0CL\0DL\0BL\0AH\0CH\0DH\0BH\0"
+        "R8u8\0R9u8\0R10u8\0R11u8\0R12u8\0R13u8\0R14u8\0R15u8\0");
+  DefineLstLoad("ST_U8_REX_REGS","AL\0CL\0DL\0BL\0RSPu8\0RBPu8\0RSIu8\0RDIu8\0"
+        "R8u8\0R9u8\0R10u8\0R11u8\0R12u8\0R13u8\0R14u8\0R15u8\0");
+  DefineLstLoad("ST_U16_REGS","AX\0CX\0DX\0BX\0SP\0BP\0SI\0DI\0"
+        "R8u16\0R9u16\0R10u16\0R11u16\0R12u16\0R13u16\0R14u16\0R15u16\0");
+  DefineLstLoad("ST_U32_REGS","EAX\0ECX\0EDX\0EBX\0ESP\0EBP\0ESI\0EDI\0"
+        "R8u32\0R9u32\0R10u32\0R11u32\0R12u32\0R13u32\0R14u32\0R15u32\0");
+  DefineLstLoad("ST_U64_REGS","RAX\0RCX\0RDX\0RBX\0RSP\0RBP\0RSI\0RDI\0"
+        "R8\0R9\0R10\0R11\0R12\0R13\0R14\0R15\0");
+  DefineLstLoad("ST_MM_REGS","MM0\0MM1\0MM2\0MM3\0MM4\0MM5\0MM6\0MM7\0");
+  DefineLstLoad("ST_XMM_REGS",
+        "XMM0\0XMM1\0XMM2\0XMM3\0XMM4\0XMM5\0XMM6\0XMM7\0");
+  DefineLstLoad("ST_ARG_TYPES","NONE\0REL8\0REL16\0REL32\0"
+        "IMM8\0IMM16\0IMM32\0IMM64\0UIMM8\0UIMM16\0UIMM32\0UIMM64\0"
+        "R8\0R16\0R32\0R64\0RM8\0RM16\0RM32\0RM64\0"
+        "M8\0M16\0M32\0M64\0M1632\0M16N32\0M16N16\0M32N32\0"
+        "MOFFS8\0MOFFS16\0MOFFS32\0MOFFS64\0"
+        "AL\0AX\0EAX\0RAX\0CL\0DX\0 \0SREG\0"
+        "SS\0DS\0ES\0FS\0GS\0CS\0ST0\0STI\0"
+        "MM\0MM32\0MM64\0XMM\0XMM32\0XMM64\0XMM128\0XMM0\0");
+  DefineLstLoad("ST_SEG_REGS","ES\0CS\0SS\0DS\0FS\0GS\0");
+  DefineLstLoad("ST_FSTK_REGS","ST0\0ST1\0ST2\0ST3\0ST4\0ST5\0ST6\0ST7\0");
+}
+
+U0 CmpFillTables()
+{
+  I64 i;
+  U32 *d;
+
+  cmp.to_reg_vars_map=CAlloc(REG_REGS_NUM*sizeof(U8));
+  cmp.num_reg_vars=0;
+  cmp.reg_vars_mask=REGG_LOCAL_VARS;
+  for (i=0;i<REG_REGS_NUM;i++)
+    if (Bt(&cmp.reg_vars_mask,i))
+      cmp.to_reg_vars_map[cmp.num_reg_vars++]=i;
+
+  cmp.non_ptr_vars_map=CAlloc(REG_REGS_NUM*sizeof(U8));
+  cmp.num_non_ptr_vars=0;
+  cmp.non_ptr_vars_mask=REGG_LOCAL_NON_PTR_VARS;
+  for (i=0;i<REG_REGS_NUM;i++)
+    if (Bt(&cmp.non_ptr_vars_mask,i))
+      cmp.non_ptr_vars_map[cmp.num_non_ptr_vars++]=i;
+
+  cmp.dual_U16_tokens1=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['!']=TK_NOT_EQU<<16+'=';
+  d['&']=TK_AND_AND<<16+'&';
+  d['*']=TK_MUL_EQU<<16+'=';
+  d['+']=TK_PLUS_PLUS<<16+'+';
+  d['-']=TK_DEREFERENCE<<16+'>';
+  d['/']='*';
+  d[':']=TK_DBL_COLON<<16+':';
+  d['<']=TK_LESS_EQU<<16+'=';
+  d['=']=TK_EQU_EQU<<16+'=';
+  d['>']=TK_GREATER_EQU<<16+'=';
+  d['^']=TK_XOR_EQU<<16+'=';
+  d['|']=TK_OR_OR<<16+'|';
+  d['%']=TK_MOD_EQU<<16+'=';
+
+  cmp.dual_U16_tokens2=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['&']=TK_AND_EQU<<16+'=';
+  d['+']=TK_ADD_EQU<<16+'=';
+  d['-']=TK_MINUS_MINUS<<16+'-';
+  d['/']='/';
+  d['<']=TK_SHL<<16+'<';
+  d['>']=TK_SHR<<16+'>';
+  d['^']=TK_XOR_XOR<<16+'^';
+  d['|']=TK_OR_EQU<<16+'=';
+
+  cmp.dual_U16_tokens3=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['-']=TK_SUB_EQU<<16+'=';
+  d['/']=TK_DIV_EQU<<16+'=';
+
+  cmp.binary_ops=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['`']   =(PREC_EXP+ASSOCF_RIGHT)<<16+IC_POWER;
+  d[TK_SHL]=(PREC_EXP+ASSOCF_LEFT)<<16+IC_SHL;
+  d[TK_SHR]=(PREC_EXP+ASSOCF_LEFT)<<16+IC_SHR;
+
+  d['*']=PREC_MUL<<16+IC_MUL;
+  d['/']=(PREC_MUL+ASSOCF_LEFT)<<16+IC_DIV;
+  d['%']=(PREC_MUL+ASSOCF_LEFT)<<16+IC_MOD;
+
+  d['&']=PREC_AND<<16+IC_AND;
+
+  d['^']=PREC_XOR<<16+IC_XOR;
+
+  d['|']=PREC_OR<<16+IC_OR;
+
+  d['+']=PREC_ADD<<16+IC_ADD;
+  d['-']=(PREC_ADD+ASSOCF_LEFT)<<16+IC_SUB;
+
+  d['<']                =PREC_CMP<<16+IC_LESS;
+  d['>']                =PREC_CMP<<16+IC_GREATER;
+  d[TK_LESS_EQU]        =PREC_CMP<<16+IC_LESS_EQU;
+  d[TK_GREATER_EQU]     =PREC_CMP<<16+IC_GREATER_EQU;
+
+  d[TK_EQU_EQU] =PREC_CMP2<<16+IC_EQU_EQU;
+  d[TK_NOT_EQU] =PREC_CMP2<<16+IC_NOT_EQU;
+
+  d[TK_AND_AND] =PREC_AND_AND<<16+IC_AND_AND;
+
+  d[TK_XOR_XOR] =PREC_XOR_XOR<<16+IC_XOR_XOR;
+
+  d[TK_OR_OR]   =PREC_OR_OR<<16+IC_OR_OR;
+
+  d['=']         =(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_ASSIGN;
+  d[TK_SHL_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHL_EQU;
+  d[TK_SHR_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHR_EQU;
+  d[TK_MUL_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MUL_EQU;
+  d[TK_DIV_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_DIV_EQU;
+  d[TK_MOD_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MOD_EQU;
+  d[TK_AND_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_AND_EQU;
+  d[TK_OR_EQU] =(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_OR_EQU;
+  d[TK_XOR_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_XOR_EQU;
+  d[TK_ADD_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_ADD_EQU;
+  d[TK_SUB_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SUB_EQU;
+}
+
+ diff --git a/public/Wb/Compiler/CMain.HC.HTML b/public/Wb/Compiler/CMain.HC.HTML new file mode 100755 index 0000000..e3b69f3 --- /dev/null +++ b/public/Wb/Compiler/CMain.HC.HTML @@ -0,0 +1,733 @@ + + + + + + + + + + + +
+U8 *LexStmt2Bin(CCmpCtrl *cc,I64 *_type,I64 cmp_flags=0)
+{//Compile one cc stmt to bin code.
+  I64 size,i,j,k,*res=INVALID_PTR;
+  CCodeCtrl *tmpcbh;
+  if (_type) *_type=RT_I64;
+  Btr(&cc->flags,CCf_PASS_TRACE_PRESENT);
+  if (cc->aot_depth==2)
+    COCPush(cc);
+  COCInit(cc);
+  if (!PrsStmt(cc,,,cmp_flags)) {
+    if (cc->coc.coc_head.next!=&cc->coc.coc_head) {
+      cc->coc.coc_head.last->ic_flags&=~ICF_RES_NOT_USED;
+      ICAdd(cc,IC_RETURN_VAL2,0,0);
+      ICAdd(cc,IC_RET,0,0);
+      if (res=COCCompile(cc,&size,NULL,_type)) {
+        if (cc->flags&CCF_AOT_COMPILE) {
+          j=cc->aotc->rip;
+          k=(size+7)>>3;
+          for (i=0;i<k;i++)
+            AOTStoreCodeU64(cc,res[i]);
+          Free(res);
+          res=j;
+        }
+      }
+    } //TODO: else del misc?
+  } else //TODO: too dangerous to del Misc?
+    QueDel(&cc->coc.coc_head.next);
+  if (cc->aot_depth==2) {
+    tmpcbh=COCPopNoFree(cc);
+    COCAppend(cc,tmpcbh);
+  }
+  return res;
+}
+
+CAOT *CmpJoin(CCmpCtrl *cc,I64 cmp_flags,U8 *map_name=NULL,U8 mapfile_drv_let=0)
+{
+  CAOTCtrl *aotc,*old_aot=cc->aotc;
+  I64 i,j,l;
+  U8 *buf;
+  CAOTBinBlk *tmpbin;
+  CAOTImportExport *tmpie;
+  Bool okay=TRUE;
+  CLexHashTableContext *htc=MAlloc(sizeof(CLexHashTableContext));
+  CAOT *res=CAlloc(sizeof(CAOT)),*parent;
+  if (parent=cc->aot) {
+    res->parent_aot=parent;
+    QueIns(res,parent->last);
+  } else
+    QueInit(res);
+  cc->aot=res;
+
+  res->next_ie=res->last_ie=&res->next_ie;
+  cc->aotc=aotc=CAlloc(sizeof(CAOTCtrl));
+  cc->aot_depth++;
+
+  aotc->bin=CAlloc(sizeof(CAOTBinBlk));
+  aotc->max_align_bits=0;
+  aotc->org=INVALID_PTR;
+
+  MemCpy(htc,&cc->htc,sizeof(CLexHashTableContext));
+  if (cc->htc.fun)
+    cc->htc.glbl_hash_table=HashTableNew(128);
+  else
+    cc->htc.glbl_hash_table=HashTableNew(1024);
+  if (cc->flags&CCF_AOT_COMPILE) {
+    cc->htc.define_hash_table=cc->htc.glbl_hash_table;
+    if (cc->aot_depth<=1)
+      cc->htc.glbl_hash_table->next=cmp.asm_hash;
+    else
+      cc->htc.glbl_hash_table->next=htc->glbl_hash_table;
+  } else
+    cc->htc.glbl_hash_table->next=Fs->hash_table;
+  cc->htc.hash_table_lst=cc->htc.local_hash_table=HashTableNew(16);
+  cc->htc.local_hash_table->next=cc->htc.glbl_hash_table;
+  cc->htc.local_var_lst=cc->htc.fun; //HolyC local vars
+  cc->htc.fun=NULL;
+  try {
+    if (cmp_flags&CMPF_LEX_FIRST)
+      Lex(cc);
+    if (!(cmp_flags&CMPF_ONE_ASM_INS))
+      cmp_flags|=CMPF_PRS_SEMICOLON;
+    if (cc->flags&CCF_AOT_COMPILE) {
+      while (cc->token!=TK_EOF) {
+        buf=LexStmt2Bin(cc,NULL,cmp_flags);
+        if (buf!=INVALID_PTR) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_MAIN;
+          tmpie->rip=buf;
+          QueIns(tmpie,res->last_ie);
+        }
+        if (cmp_flags&CMPF_ASM_BLK)
+          break;
+      }
+    } else
+      PrsStmt(cc,,,cmp_flags);
+    AOTGlblsResolve(cc,res);
+  } catch {
+    if (Fs->except_ch=='Compiler' && !(cmp_flags&CMPF_ASM_BLK)) {
+      LexPutPos(cc);
+      Fs->catch_except=TRUE;
+    }
+    okay=FALSE;
+  }
+  if (!okay) {
+    if (cc->error_cnt<1)
+      cc->error_cnt=1;
+    cc->aot=res->parent_aot;
+    Free(res);
+    LinkedLstDel(aotc->bin);
+    res=NULL;
+  } else {
+    if (map_name)
+      MapFileWrite(cc->htc.glbl_hash_table,map_name,mapfile_drv_let);
+    HashTableDel(cc->htc.local_hash_table);
+    HashTableDel(cc->htc.glbl_hash_table);
+
+    if (!aotc->num_bin_U8s)
+      res->buf=NULL;
+    else {
+      if (cc->flags&CCF_AOT_COMPILE)
+        res->buf=MAlloc(aotc->num_bin_U8s);
+      else {
+        if (aotc->org==INVALID_PTR)
+          res->buf=MAlloc(aotc->num_bin_U8s,Fs->code_heap);
+        else
+          res->buf=aotc->org;
+      }
+      res->aot_U8s=aotc->num_bin_U8s;
+      tmpbin=aotc->bin;
+      j=0;
+      l=aotc->num_bin_U8s;
+      while (tmpbin) {
+        i=l;
+        if (i>AOT_BIN_BLK_SIZE)
+          i=AOT_BIN_BLK_SIZE;
+        MemCpy(res->buf+j,tmpbin->body,i);
+        j+=i;
+        l-=i;
+        tmpbin=tmpbin->next;
+      }
+    }
+    LinkedLstDel(aotc->bin);
+    res->abss=aotc->abss;
+    res->heap_glbls=aotc->heap_glbls;
+    res->max_align_bits=aotc->max_align_bits;
+    res->org=aotc->org;
+  }
+  cc->aot=parent;
+  MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
+  Free(htc);
+  Free(aotc);
+  cc->aotc=old_aot;
+  cc->aot_depth--;
+  return res;
+}
+
+CAOT *CmpBuf(U8 *buf,U8 *map_name=NULL,
+  I64 *error_cnt=NULL, I64 *warning_cnt=NULL,U8 mapfile_drv_let=0)
+{
+  CCmpCtrl *cc;
+  CAOT *res=NULL;
+  cc=CmpCtrlNew(buf,CCF_DONT_FREE_BUF);
+  cc->flags|=CCF_AOT_COMPILE;
+  QueIns(cc,Fs->last_cc);
+  res=CmpJoin(cc,CMPF_LEX_FIRST,map_name,mapfile_drv_let);
+  if (error_cnt)   *error_cnt=cc->error_cnt;
+  if (warning_cnt) *warning_cnt=cc->warning_cnt;
+  QueRem(cc);
+  if (res)
+    CmpCtrlDel(cc);
+  return res;
+}
+
+U0 CmpFixUpJITAsm(CCmpCtrl *cc,CAOT *tmpaot)
+{
+  I64 i,rip2=tmpaot->buf+tmpaot->rip,*str=NULL;
+  U8 *ptr;
+  CCodeMisc *g_lb;
+  CAOTAbsAddr *tmpa,*tmpa1;
+  CAOTImportExport *tmpie,*tmpie1;
+  CHashExport *tmpex;
+
+  tmpa=tmpaot->abss;
+  while (tmpa) {
+    tmpa1=tmpa->next;
+    ptr=rip2+tmpa->rip;
+    switch [tmpa->type] {
+      case AAT_ADD_U8:  *ptr(U8 *) +=rip2; break;
+      case AAT_SUB_U8:  *ptr(U8 *) -=rip2; break;
+      case AAT_ADD_U16: *ptr(U16 *)+=rip2; break;
+      case AAT_SUB_U16: *ptr(U16 *)-=rip2; break;
+      case AAT_ADD_U32: *ptr(U32 *)+=rip2; break;
+      case AAT_SUB_U32: *ptr(U32 *)-=rip2; break;
+      case AAT_ADD_U64: *ptr(I64 *)+=rip2; break;
+      case AAT_SUB_U64: *ptr(I64 *)-=rip2; break;
+    }
+    Free(tmpa);
+    tmpa=tmpa1;
+  }
+  tmpie=tmpaot->next_ie;
+  while (tmpie!=&tmpaot->next_ie) {
+    tmpie1=tmpie->next;
+    if (tmpie->str) {
+      Free(str);
+      str=tmpie->str;
+    }
+    switch (tmpie->type) {
+      case IET_REL32_EXPORT:
+      case IET_IMM32_EXPORT:
+      case IET_REL64_EXPORT:
+      case IET_IMM64_EXPORT:
+        tmpex=CAlloc(sizeof(CHashExport));
+        tmpex->str=str;
+        str=NULL;
+        tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+        if (tmpie->type==IET_IMM32_EXPORT||tmpie->type==IET_IMM64_EXPORT)
+          tmpex->val=tmpie->rip;
+        else
+          tmpex->val=tmpie->rip+rip2;
+        tmpex->src_link=tmpie->src_link;
+        tmpie->src_link=NULL;
+        HashAdd(tmpex,Fs->hash_table);
+        SysSymImportsResolve(tmpex->str);
+        break;
+      case IET_REL_I0...IET_IMM_I64:
+        if (tmpie->str) {
+          if (tmpie->flags&IEF_GOTO_LABEL) {
+            if(!(g_lb=COCGoToLabelFind(cc,str)))
+              "Unresolved Reference:%s\n",str;
+            else {
+              g_lb->use_cnt++;
+              g_lb=OptLabelFwd(g_lb);
+              i=g_lb->addr+tmpaot->buf;
+            }
+            tmpex=NULL;
+          } else {
+            if (!(tmpex=HashFind(str,Fs->hash_table,
+                  HTG_ALL-HTT_IMPORT_SYS_SYM)))
+              "Unresolved Reference:%s\n",str;
+            else {
+              if (tmpex->type & HTT_FUN)
+                i=tmpex(CHashFun *)->exe_addr;
+              else if (tmpex->type & HTT_GLBL_VAR)
+                i=tmpex(CHashGlblVar *)->data_addr;
+              else
+                i=tmpex->val;
+            }
+            g_lb=NULL;
+          }
+        }
+        if (tmpex || g_lb) {
+          ptr=tmpie->rip+rip2;
+          switch [tmpie->type] {
+            case IET_REL_I0:
+            case IET_IMM_U0:
+              break;
+            case IET_REL_I8:
+              if (!(I8_MIN<=i-ptr-1<=I8_MAX))
+                LexExcept(cc,"Branch out of range at ");
+              *ptr(U8 *) =i-ptr-1;
+              break;
+            case IET_IMM_U8:
+              *ptr(U8 *) =i;
+              break;
+            case IET_REL_I16:
+              if (!(I16_MIN<=i-ptr-2<=I16_MAX))
+                LexExcept(cc,"Branch out of range at ");
+              *ptr(U16 *)=i-ptr-2;
+              break;
+            case IET_IMM_U16:
+              *ptr(U16 *)=i;
+              break;
+            case IET_REL_I32:
+              if (!(I32_MIN<=i-ptr-4<=I32_MAX))
+                LexExcept(cc,"Branch out of range at ");
+              *ptr(U32 *)=i-ptr-4;
+              break;
+            case IET_IMM_U32:
+              *ptr(U32 *)=i;
+              break;
+            case IET_REL_I64:
+              *ptr(I64 *)=i-ptr-8;
+              break;
+            case IET_IMM_I64:
+              *ptr(I64 *)=i;
+              break;
+          }
+        }
+        break;
+    }
+    Free(tmpie->src_link);
+    Free(tmpie);
+    tmpie=tmpie1;
+  }
+  Free(str);
+  if (!cc->aot_depth && Bt(&cc->opts,OPTf_TRACE))
+    Un(rip2,tmpaot->aot_U8s,64);
+  QueRem(tmpaot);
+  Free(tmpaot);
+}
+
+U0 CmpFixUpAOTAsm(CCmpCtrl *cc,CAOT *tmpaot)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i,rip2=tmpaot->rip+cc->aotc->rip;
+  U8 *ptr;
+  CCodeMisc *g_lb=NULL;
+  CAOTAbsAddr *tmpa,*tmpa1;
+  CAOTImportExport *tmpie,*tmpie1;
+
+  tmpa=tmpaot->abss;
+  while (tmpa) {
+    tmpa1=tmpa->next;
+    tmpa->next=aotc->abss;
+    ptr=tmpaot->buf+tmpaot->rip+tmpa->rip;
+    switch [tmpa->type] {
+      case AAT_ADD_U8:  *ptr(U8 *)+=rip2;       break;
+      case AAT_SUB_U8:  *ptr(U8 *)-=rip2;       break;
+      case AAT_ADD_U16: *ptr(U16 *)+=rip2;      break;
+      case AAT_SUB_U16: *ptr(U16 *)-=rip2;      break;
+      case AAT_ADD_U32: *ptr(U32 *)+=rip2;      break;
+      case AAT_SUB_U32: *ptr(U32 *)-=rip2;      break;
+      case AAT_ADD_U64: *ptr(I64 *)+=rip2;      break;
+      case AAT_SUB_U64: *ptr(I64 *)-=rip2;      break;
+    }
+    aotc->abss=tmpa;
+    tmpa->rip+=rip2;
+    tmpa=tmpa1;
+  }
+
+  tmpie=tmpaot->next_ie;
+  while (tmpie!=&tmpaot->next_ie) {
+    tmpie1=tmpie->next;
+    QueRem(tmpie);
+    if (IET_REL_I0<=tmpie->type<=IET_IMM_I64) {
+      if (tmpie->str) {
+        if (tmpie->flags&IEF_GOTO_LABEL) {
+          if(!(g_lb=COCGoToLabelFind(cc,tmpie->str)))
+            "Unresolved Reference:%s\n",tmpie->str;
+          else {
+            g_lb->use_cnt++;
+            g_lb=OptLabelFwd(g_lb);
+          }
+        } else
+          g_lb=NULL;
+      }
+    } else
+      g_lb=NULL;
+
+    ptr=tmpaot->buf+tmpaot->rip+tmpie->rip;
+    if (g_lb) {
+      i=g_lb->addr+tmpaot->buf;
+      switch [tmpie->type] {
+        case IET_REL_I0:
+        case IET_IMM_U0:
+          break;
+        case IET_REL_I8:
+          if (!(I8_MIN<=i-ptr-1<=I8_MAX))
+            LexExcept(cc,"Branch out of range at ");
+          *ptr(U8 *) =i-ptr-1;
+          break;
+        case IET_IMM_U8:
+          *ptr(U8 *) =i;
+          break;
+        case IET_REL_I16:
+          if (!(I16_MIN<=i-ptr-2<=I16_MAX))
+            LexExcept(cc,"Branch out of range at ");
+          *ptr(U16 *)=i-ptr-2;
+          break;
+        case IET_IMM_U16:
+          *ptr(U16 *)=i;
+          break;
+        case IET_REL_I32:
+          if (!(I32_MIN<=i-ptr-4<=I32_MAX))
+            LexExcept(cc,"Branch out of range at ");
+          *ptr(U32 *)=i-ptr-4;
+          break;
+        case IET_IMM_U32:
+          *ptr(U32 *)=i;
+          break;
+        case IET_REL_I64:
+          *ptr(I64 *)=i-ptr-8;
+          break;
+        case IET_IMM_I64:
+          *ptr(I64 *)=i;
+          break;
+      }
+      Free(tmpie->src_link);
+      Free(tmpie);
+    } else {
+      switch (tmpie->type) {
+        start:
+          case IET_REL32_EXPORT:
+          case IET_IMM32_EXPORT:
+          case IET_REL64_EXPORT:
+          case IET_IMM64_EXPORT:
+          case IET_IMM_U0:
+          case IET_IMM_U8:
+          case IET_IMM_U16:
+          case IET_IMM_U32:
+          case IET_IMM_I64:
+          case IET_REL_I0:
+            break;
+          case IET_REL_I8:          *ptr(U8 *) -=rip2;      break;
+          case IET_REL_I16:         *ptr(U16 *)-=rip2;      break;
+          case IET_REL_I32:         *ptr(U32 *)-=rip2;      break;
+          case IET_REL_I64:         *ptr(I64 *)-=rip2;      break;
+        end:
+          tmpie->rip+=rip2;
+          break;
+      }
+      tmpie->aot=NULL;
+      QueIns(tmpie,tmpaot->parent_aot->last_ie);
+    }
+    tmpie=tmpie1;
+  }
+}
+
+I64 Cmp(U8 *filename,U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv_let=0)
+{//AOT Compile HC or PRJ file a and output BIN file. Returns err_cnt.
+  U8 *ptr,*fbuf=NULL,*fbuf2=NULL,*fbuf3=NULL,
+        *patch_table=MAlloc(0x20000);
+  CAOT *tmpaot;
+  I64 i,cnt,size=0,error_cnt=0,warning_cnt=0,aot_U8s=0;
+  CBinFile *bfh;
+  CAOTImportExport *tmpie,*tmpie1;
+  CAOTAbsAddr *tmpa,*tmpa1;
+  CAOTHeapGlblRef *tmphgr,*tmphgr1;
+  CAOTHeapGlbl *tmphg,*tmphg1;
+
+  fbuf=ExtDft(filename,"PRJ.Z");
+  fbuf2=MStrPrint("#include \"%s\"",fbuf);
+  if (map_name)
+    fbuf3=ExtDft(map_name,"MAP.Z");
+
+  if (tmpaot=CmpBuf(fbuf2,fbuf3,&error_cnt,&warning_cnt,mapfile_drv_let)) {
+    aot_U8s=tmpaot->aot_U8s;
+    ptr=patch_table;
+//See Load()
+    cnt=0;
+    tmpa=tmpaot->abss;
+    while (tmpa) {
+      if (!(tmpa->type&IEF_IMM_NOT_REL))
+        cnt++;
+      tmpa=tmpa->next;
+    }
+    if (cnt) {
+      *ptr++=IET_ABS_ADDR;
+      *ptr(U32 *)++=cnt;
+      *ptr++=0;
+      tmpa=tmpaot->abss;
+      while (tmpa) {
+        tmpa1=tmpa->next;
+        if (!(tmpa->type&IEF_IMM_NOT_REL))
+          *ptr(U32 *)++ =tmpa->rip;
+        Free(tmpa);
+        tmpa=tmpa1;
+      }
+    }
+    tmphg=tmpaot->heap_glbls;
+    while (tmphg) {
+      tmphg1=tmphg->next;
+      cnt=0;
+      tmphgr=tmphg->references;
+      while (tmphgr) {
+        cnt++;
+        tmphgr=tmphgr->next;
+      }
+      if (cnt) {
+        *ptr++=IET_DATA_HEAP;
+        *ptr(U32 *)++=cnt;
+        if (tmphg->str) {
+          i=StrLen(tmphg->str);
+          MemCpy(ptr,tmphg->str,i+1);
+          Free(tmphg->str);
+          ptr+=i+1;
+        } else
+          *ptr++=0;
+        *ptr(I64 *)++=tmphg->size;
+        tmphgr=tmphg->references;
+        while (tmphgr) {
+          tmphgr1=tmphgr->next;
+          *ptr(U32 *)++=tmphgr->rip;
+          Free(tmphgr);
+          tmphgr=tmphgr1;
+        }
+      }
+      Free(tmphg);
+      tmphg=tmphg1;
+    }
+
+    //Do exports first
+    tmpie=tmpaot->next_ie;
+    while (tmpie!=&tmpaot->next_ie) {
+      tmpie1=tmpie->next;
+      if (!tmpie->type || IET_REL32_EXPORT<=tmpie->type<=IET_IMM64_EXPORT) {
+        QueRem(tmpie);
+        *ptr++=tmpie->type;
+        *ptr(U32 *)++=tmpie->rip;
+        if (tmpie->str) {
+          i=StrLen(tmpie->str);
+          MemCpy(ptr,tmpie->str,i+1);
+          Free(tmpie->str);
+          ptr+=i+1;
+        } else
+          *ptr++=0;
+        Free(tmpie->src_link);
+        Free(tmpie);
+      }
+      tmpie=tmpie1;
+    }
+
+    //Do imports second
+    tmpie=tmpaot->next_ie;
+    while (tmpie!=&tmpaot->next_ie) {
+      tmpie1=tmpie->next;
+      QueRem(tmpie);
+      *ptr++=tmpie->type;
+      if (tmpie->aot)
+        tmpie->rip+=tmpie->aot->rip2;
+      *ptr(U32 *)++=tmpie->rip;
+      if (tmpie->str) {
+        i=StrLen(tmpie->str);
+        MemCpy(ptr,tmpie->str,i+1);
+        Free(tmpie->str);
+        ptr+=i+1;
+      } else
+        *ptr++=0;
+      Free(tmpie->src_link);
+      Free(tmpie);
+      tmpie=tmpie1;
+    }
+
+    *ptr++=IET_END;
+    MemSet(ptr,0,16);
+    i=ptr-patch_table;
+//Needs 16 ALIGN
+    size=(sizeof(CBinFile)+aot_U8s+i+15)&-16;
+    bfh=MAlloc(size);
+    bfh->jmp=0xEB+256*(sizeof(CBinFile)-2);
+#assert sizeof(CBinFile)-2<=I8_MAX
+    bfh->reserved=0;
+    bfh->bin_signature=BIN_SIGNATURE_VAL;
+    bfh->org=tmpaot->org;
+    bfh->module_align_bits=tmpaot->max_align_bits;
+    bfh->patch_table_offset=sizeof(CBinFile)+aot_U8s;
+    bfh->file_size=size;
+    MemCpy(bfh(U8 *)+sizeof(CBinFile),tmpaot->buf,aot_U8s);
+    MemCpy(bfh(U8 *)+sizeof(CBinFile)+aot_U8s,patch_table,
+          size-aot_U8s-sizeof(CBinFile));
+    Free(fbuf2);
+    if (out_name)
+      fbuf2=ExtDft(out_name,"BIN.Z");
+    else
+      fbuf2=ExtChg(fbuf,"BIN.Z");
+    FileWrite(fbuf2,bfh,size);
+    Free(bfh);
+    Free(tmpaot->buf);
+    QueDel(tmpaot);
+    Free(tmpaot);
+  }
+  Free(patch_table);
+  Free(fbuf);
+  Free(fbuf2);
+  Free(fbuf3);
+  Print("Errs:%d Warns:%d Code:%X Size:%X\n",
+        error_cnt,warning_cnt,aot_U8s,size);
+  return error_cnt;
+}
+
+I64 ExePutS(U8 *buf,U8 *filename=NULL,
+        I64 ccf_flags=0,CLexHashTableContext *htc=NULL)
+{//JIT Compile and execute text from a puts("").
+  I64 res;
+  Bool okay=TRUE;
+  CCmpCtrl *cc;
+  if (!filename)
+    filename=blkdev.tmp_filename;
+  cc=CmpCtrlNew(buf,ccf_flags|CCF_DONT_FREE_BUF,filename);
+  if (Fs->last_cc!=&Fs->next_cc) {
+    cc->opts=Fs->last_cc->opts;
+    if (htc) {
+      cc->flags=cc->flags &~CCF_ASM_EXPRESSIONS |
+            htc->old_flags&CCF_ASM_EXPRESSIONS;
+      MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
+    }
+  }
+  QueIns(cc,Fs->last_cc);
+  try {
+    Lex(cc);
+    res=ExeCmdLine(cc);
+  } catch {
+    if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+      res=0;
+    }
+  }
+  QueRem(cc);
+  if (okay)
+    CmpCtrlDel(cc); //TODO: can crash
+  return res;
+}
+
+I64 ExePrint(U8 *fmt,...)
+{//JIT Compile and execute text from a printf().
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=ExePutS(buf);
+  Free(buf);
+  return res;
+}
+
+I64 ExeFile(U8 *name,I64 ccf_flags=0)
+{//JIT Compile and execute a file.
+  I64 res;
+  U8 *name2=ExtDft(name,"HC.Z"),
+        *st=MStrPrint("#include \"%s\";",name2);
+  res=ExePutS(st,name,ccf_flags);
+  Free(st);
+  Free(name2);
+  return res;
+}
+
+I64 RunFile(U8 *name,I64 ccf_flags=0,...)
+{//ExeFile() with args using LastFun().
+  ExeFile(name,ccf_flags);
+  return LastFun(argc,argv);
+}
+
+I64 ExePutS2(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0)
+{//throws exceptions
+  I64 res;
+  CCmpCtrl *cc;
+  if (!filename)
+    filename=blkdev.tmp_filename;
+  cc=CmpCtrlNew(buf,ccf_flags|CCF_DONT_FREE_BUF,filename);
+  if (Fs->last_cc!=&Fs->next_cc)
+    cc->opts=Fs->last_cc->opts;
+  QueIns(cc,Fs->last_cc);
+  Lex(cc);
+  res=ExeCmdLine(cc);
+  QueRem(cc);
+  CmpCtrlDel(cc);
+  return res;
+}
+
+I64 ExePrint2(U8 *fmt,...)
+{//throws exceptions
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=ExePutS2(buf);
+  Free(buf);
+  return res;
+}
+
+I64 ExeFile2(U8 *name,I64 ccf_flags=0)
+{//throws exceptions
+  I64 res;
+  U8 *name2=ExtDft(name,"HC.Z"),*st=MStrPrint("#include \"%s\";",name2);
+  res=ExePutS2(st,name,ccf_flags);
+  Free(st);
+  Free(name2);
+  return res;
+}
+
+I64 RunFile2(U8 *name,I64 ccf_flags=0,...)
+{//ExeFile2() with args using LastFun(). throws exceptions.
+  ExeFile2(name,ccf_flags);
+  return LastFun(argc,argv);
+}
+
+I64 StreamExePrint(U8 *fmt,...)
+{//Causes value from stream to be used in an #exe{} block.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res=0;
+  CLexHashTableContext *htc;
+  CCmpCtrl *cc=Fs->last_cc;
+  if (cc==&Fs->next_cc)
+    PrintErr("Not Compiling\n");
+  else {
+    if (!(cc->flags&CCF_EXE_BLK))
+      LexExcept(cc,"StreamExePrint only allowed in AOT compiled #exe{} mode.");
+    if (htc=cc->htc.next)
+      res=ExePutS(buf,,,htc);
+  }
+  Free(buf);
+  return res;
+}
+
+U0 CInit()
+{
+  CmpLoadDefines;
+  CmpFillTables;
+  QueInit(&cmp.ic_nop);
+  cmp.ic_nop.ic_class=cmp.internal_types[RT_I64];
+  cmp.ic_nop.ic_code=IC_NOP1;
+  AsmHashLoad;
+  UAsmHashLoad;
+}
+
+CInit;
+
+ diff --git a/public/Wb/Compiler/CMisc.HC.HTML b/public/Wb/Compiler/CMisc.HC.HTML new file mode 100755 index 0000000..807e037 --- /dev/null +++ b/public/Wb/Compiler/CMisc.HC.HTML @@ -0,0 +1,200 @@ + + + + + + + + + + + +
+Bool Option(I64 num,Bool val)
+{//Set compiler Option to val.
+  return BEqu(&Fs->last_cc->opts,num,val);
+}
+
+Bool GetOption(I64 num)
+{//Get state of compiler option.
+  return Bt(&Fs->last_cc->opts,num);
+}
+
+asm {
+_LAST_FUN::     //See _CALL_IND
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        XOR     RAX,RAX
+        MOV     RAX,FS:CTask.last_fun[RAX]
+        TEST    RAX,RAX
+        JZ      @@10
+        MOV     RDX,U64 CHashFun.exe_addr[RAX]
+
+        MOV     RCX,U64 SF_ARG1[RBP]    //argc
+        MOV     RSI,U64 SF_ARG2[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        TEST    RDX,RDX
+        JZ      @@05
+
+        CALL    RDX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+
+@@05:   MOV     RCX,U64 SF_ARG1[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        XOR     RAX,RAX
+@@10:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+}
+_extern _LAST_FUN I64 LastFun(I64 argc,I64 *argv); //Execute last fun with args.
+
+I64 PassTrace(I64 i=0b10001111101)
+{//Ctrls which optimizer passes are displayed.
+  I64 old=Fs->last_cc->pass_trace;
+  if (i) Fs->last_cc->saved_pass_trace=i;
+  Fs->last_cc->pass_trace=i;
+  return old;
+}
+
+Bool Trace(Bool val=ON)
+{//Displays assembly code output from compiler.
+  return Option(OPTf_TRACE,val);
+}
+
+Bool Echo(Bool val)
+{//Displays text as it is being compiled.
+  return Option(OPTf_ECHO,val);
+}
+
+U0 StreamPrint(U8 *fmt,...)
+{//Injects text into the compile stream. Used in #exe{} blocks.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st;
+  CCmpCtrl *cc=Fs->last_cc;
+  CStreamBlk *tmpe=cc->last_stream_blk;
+  if (tmpe!=&cc->next_stream_blk) {
+    st=MStrPrint("%s%s",tmpe->body,buf);
+    Free(tmpe->body);
+    tmpe->body=st;
+  } else
+    PrintErr("No exe{} blk\n");
+  Free(buf);
+}
+
+U0 StreamDir()
+{
+  U8 *dirname;
+  if (dirname=DirFile(Fs->last_cc->lex_include_stk->full_name)) {
+    StreamPrint("\"%s\"",dirname);
+    Free(dirname);
+  }
+}
+
+CD2I32 *LexD2I32(CCmpCtrl *cc,CD2I32 *p)
+{//Not HolyC. Sprite-like lex 2D point.
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc); //Skip (
+  p->x=LexExpressionI64(cc);
+  if (cc->token!=',')
+    LexExcept(cc,"Expecting ',' at ");
+  Lex(cc); //Skip ,
+  p->y=LexExpressionI64(cc);
+  if (cc->token!=')')
+    LexExcept(cc,"Expecting ')' at ");
+  Lex(cc); //Skip )
+  return p;
+}
+
+CD3I32 *LexD3I32(CCmpCtrl *cc,CD3I32 *p)
+{//Not HolyC. Sprite-like lex 3D point.
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc); //Skip (
+  p->x=LexExpressionI64(cc);
+  if (cc->token!=',')
+    LexExcept(cc,"Expecting ',' at ");
+  Lex(cc); //Skip ,
+  p->y=LexExpressionI64(cc);
+  if (cc->token!=',')
+    LexExcept(cc,"Expecting ',' at ");
+  Lex(cc); //Skip ,
+  p->z=LexExpressionI64(cc);
+  if (cc->token!=')')
+    LexExcept(cc,"Expecting ')' at ");
+  Lex(cc); //Skip )
+  return p;
+}
+
+U8 *CmdLinePmt()
+{
+  I64 i;
+  U8 *res,*st;
+  if (Fs->new_answer) {
+    if (Fs->answer_type&~1!=RT_I0) {
+      if (Fs->answer_type==RT_F64)
+        "%8.6fs ansf=%15.7g\n",Fs->answer_time,Fs->answer;
+      else
+        "%8.6fs ans=0x%08X=%d\n",Fs->answer_time,Fs->answer,Fs->answer;
+    } else {
+      "%8.6fs\n",Fs->answer_time;
+      Fs->answer=0;
+    }
+    Fs->new_answer=FALSE;
+  }
+  if (st=DirCur) {
+    "%s",st;
+    Free(st);
+  }
+  '>';
+  if (IsDbgMode&&IsRaw)
+    RawDr;
+
+  LBts(&Fs->task_flags,TASKf_CMD_LINE_PMT);
+  st=GetStr(,,GSF_SHIFT_ESC_EXIT);
+  LBtr(&Fs->task_flags,TASKf_CMD_LINE_PMT);
+
+  i=StrLen(st);
+  res=MAlloc(i+1+2);
+  MemCpy(res,st,i+1);
+  i--;
+  while (i>=0 && Bt(char_bmp_white_space,res[i]))
+    i--;
+  i++;
+  if (i>0 && res[i-1]==';')
+    res[i++]=';'; //The Lex goes one beyond
+  res[i++]='\n';//#define goes to '\n'
+  res[i]=0;
+
+  Free(st);
+  return res;
+}
+
+ diff --git a/public/Wb/Compiler/CompilerA.HH b/public/Wb/Compiler/CompilerA.HH old mode 100644 new mode 100755 diff --git a/public/Wb/Compiler/CompilerA.HH.HTML b/public/Wb/Compiler/CompilerA.HH.HTML new file mode 100755 index 0000000..a120f35 --- /dev/null +++ b/public/Wb/Compiler/CompilerA.HH.HTML @@ -0,0 +1,437 @@ + + + + + + + + + + + +
+#help_index "Compiler/Internal"
+//Intermediate compiler codes
+#define IS_0_ARG        0
+#define IS_1_ARG        1
+#define IS_2_ARG        2
+#define IS_V_ARG        3 //Variable Arg Cnt
+
+#define IST_NULL        0
+#define IST_DEREF       1
+#define IST_ASSIGN      2
+#define IST_CMP         3
+        
+class CIntermediateStruct
+{
+  U8 arg_cnt,res_cnt,type;
+  Bool fpop,not_const,pad[3];
+  U8 *name;
+};
+
+#define IC_END                  0x00
+#define IC_NOP1                 0x01
+#define IC_END_EXP              0x02
+#define IC_NOP2                 0x03
+#define IC_LABEL                0x04
+#define IC_CALL_START           0x05
+#define IC_CALL_END             0x06
+#define IC_CALL_END2            0x07
+#define IC_RETURN_VAL           0x08
+#define IC_RETURN_VAL2          0x09
+#define IC_IMM_I64              0x0A
+#define IC_IMM_F64              0x0B
+#define IC_STR_CONST            0x0C
+#define IC_ABS_ADDR             0x0D
+#define IC_ADDR_IMPORT          0x0E
+#define IC_HEAP_GLBL            0x0F
+#define IC_SIZEOF               0x10
+#define IC_TYPE                 0x11
+#define IC_GET_LABEL            0x12
+#define IC_RBP                  0x13
+#define IC_REG                  0x14
+#define IC_FS                   0x15
+#define IC_MOV_FS               0x16
+#define IC_GS                   0x17
+#define IC_MOV_GS               0x18
+
+#define IC_LEA                  0x19
+#define IC_MOV                  0x1A
+
+#define IC_TO_I64               0x1B
+#define IC_TO_F64               0x1C
+#define IC_TO_BOOL              0x1D
+#define IC_TOUPPER              0x1E
+#define IC_HOLYC_TYPECAST       0x1F
+
+#define IC_ADDR                 0x20
+#define IC_COM                  0x21
+#define IC_NOT                  0x22
+#define IC_UNARY_MINUS          0x23
+
+#define IC_DEREF                0x24
+#define IC_DEREF_PP             0x25
+#define IC_DEREF_MM             0x26
+#define IC__PP                  0x27
+#define IC__MM                  0x28
+#define IC_PP_                  0x29
+#define IC_MM_                  0x2A
+
+#define IC_SHL                  0x2B
+#define IC_SHR                  0x2C
+#define IC_SHL_CONST            0x2D
+#define IC_SHR_CONST            0x2E
+#define IC_POWER                0x2F
+
+#define IC_MUL                  0x30
+#define IC_DIV                  0x31
+#define IC_MOD                  0x32
+
+#define IC_AND                  0x33
+
+#define IC_OR                   0x34
+#define IC_XOR                  0x35
+
+#define IC_ADD                  0x36
+#define IC_SUB                  0x37
+#define IC_ADD_CONST            0x38
+#define IC_SUB_CONST            0x39
+
+#define IC_EQU_EQU              0x3A
+#define IC_NOT_EQU              0x3B
+#define IC_LESS                 0x3C
+#define IC_GREATER_EQU          0x3D
+#define IC_GREATER              0x3E
+#define IC_LESS_EQU             0x3F
+#define IC_PUSH_CMP             0x40
+
+#define IC_AND_AND              0x41
+
+#define IC_OR_OR                0x42
+#define IC_XOR_XOR              0x43
+
+#define IC_ASSIGN               0x44
+#define IC_ASSIGN_PP            0x45
+#define IC_ASSIGN_MM            0x46
+
+#define IC_SHL_EQU              0x47
+#define IC_SHR_EQU              0x48
+#define IC_MUL_EQU              0x49
+#define IC_DIV_EQU              0x4A
+#define IC_MOD_EQU              0x4B
+#define IC_AND_EQU              0x4C
+#define IC_OR_EQU               0x4D
+#define IC_XOR_EQU              0x4E
+#define IC_ADD_EQU              0x4F
+#define IC_SUB_EQU              0x50
+
+#define IC_JMP                  0x51
+#define IC_SUB_CALL             0x52
+#define IC_SWITCH               0x53
+#define IC_NOBOUND_SWITCH               0x54
+
+#define IC_ADD_RSP              0x55
+#define IC_ADD_RSP1             0x56
+#define IC_ENTER                0x57
+#define IC_PUSH_REGS            0x58
+#define IC_POP_REGS             0x59
+#define IC_LEAVE                0x5A
+#define IC_RET                  0x5B
+
+#define IC_CALL                 0x5C
+#define IC_CALL_INDIRECT        0x5D
+#define IC_CALL_INDIRECT2       0x5E
+#define IC_CALL_IMPORT          0x5F
+#define IC_CALL_EXTERN          0x60
+
+#define IC_ASM                  0x61
+#define IC_PUSH                 0x62
+#define IC_POP                  0x63
+
+#define IC_CLFLUSH              0x64
+#define IC_INVLPG               0x65
+
+#define IC_IN_U8                0x66
+#define IC_IN_U16               0x67
+#define IC_IN_U32               0x68
+#define IC_OUT_U8               0x69
+#define IC_OUT_U16              0x6A
+#define IC_OUT_U32              0x6B
+
+#define IC_GET_RFLAGS           0x6C
+#define IC_CARRY                0x6D
+#define IC_SET_RFLAGS           0x6E
+#define IC_GET_RAX              0x6F
+#define IC_SET_RAX              0x70
+#define IC_GET_RBP              0x71
+#define IC_SET_RBP              0x72
+#define IC_GET_RSP              0x73
+#define IC_SET_RSP              0x74
+#define IC_RIP                  0x75
+
+#define IC_RDTSC                0x76
+
+#define IC_BT                   0x77
+#define IC_BTS                  0x78
+#define IC_BTR                  0x79
+#define IC_BTC                  0x7A
+#define IC_LBTS                 0x7B
+#define IC_LBTR                 0x7C
+#define IC_LBTC                 0x7D
+#define IC_BSF                  0x7E
+#define IC_BSR                  0x7F
+
+#define IC_QUE_INIT             0x80
+#define IC_QUE_INS              0x81
+#define IC_QUE_INS_REV          0x82
+#define IC_QUE_REM              0x83
+
+#define IC_STRLEN               0x84
+
+#define IC_BR_ZERO              0x85
+#define IC_BR_NOT_ZERO          0x86
+#define IC_BR_CARRY             0x87
+#define IC_BR_NOT_CARRY         0x88
+
+#define IC_BR_EQU_EQU           0x89
+#define IC_BR_NOT_EQU           0x8A
+#define IC_BR_LESS              0x8B
+#define IC_BR_GREATER_EQU       0x8C
+#define IC_BR_GREATER           0x8D
+#define IC_BR_LESS_EQU          0x8E
+
+#define IC_BR_EQU_EQU2          0x8F
+#define IC_BR_NOT_EQU2          0x90
+#define IC_BR_LESS2             0x91
+#define IC_BR_GREATER_EQU2      0x92
+#define IC_BR_GREATER2          0x93
+#define IC_BR_LESS_EQU2         0x94
+
+#define IC_BR_AND_ZERO          0x95
+#define IC_BR_AND_NOT_ZERO      0x96
+#define IC_BR_MM_ZERO           0x97
+#define IC_BR_MM_NOT_ZERO       0x98
+#define IC_BR_AND_AND_ZERO      0x99
+#define IC_BR_AND_AND_NOT_ZERO  0x9A
+#define IC_BR_OR_OR_ZERO        0x9B
+#define IC_BR_OR_OR_NOT_ZERO    0x9C
+
+#define IC_BR_BT                0x9D
+#define IC_BR_BTS               0x9E
+#define IC_BR_BTR               0x9F
+#define IC_BR_BTC               0xA0
+#define IC_BR_NOT_BT            0xA1
+#define IC_BR_NOT_BTS           0xA2
+#define IC_BR_NOT_BTR           0xA3
+#define IC_BR_NOT_BTC           0xA4
+
+#define IC_SWAP_U8              0xA5
+#define IC_SWAP_U16             0xA6
+#define IC_SWAP_U32             0xA7
+#define IC_SWAP_I64             0xA8
+
+#define IC_ABS_I64              0xA9
+#define IC_SIGN_I64             0xAA
+#define IC_MIN_I64              0xAB
+#define IC_MIN_U64              0xAC
+#define IC_MAX_I64              0xAD
+#define IC_MAX_U64              0xAE
+#define IC_MOD_U64              0xAF
+#define IC_SQR_I64              0xB0
+#define IC_SQR_U64              0xB1
+#define IC_SQR                  0xB2
+#define IC_ABS                  0xB3
+#define IC_SQRT                 0xB4
+#define IC_SIN                  0xB5
+#define IC_COS                  0xB6
+#define IC_TAN                  0xB7
+#define IC_ATAN                 0xB8
+#define IC_ICS_NUM              0xB9
+
+#define KW_INCLUDE      0
+#define KW_DEFINE       1
+#define KW_UNION        2
+#define KW_CATCH        3
+#define KW_CLASS        4
+#define KW_TRY          5
+#define KW_IF           6
+#define KW_ELSE         7
+#define KW_FOR          8
+#define KW_WHILE        9
+#define KW_EXTERN       10
+#define KW__EXTERN      11
+#define KW_RETURN       12
+#define KW_SIZEOF       13
+#define KW__INTERN      14
+#define KW_DO           15
+#define KW_ASM          16
+#define KW_GOTO         17
+#define KW_EXE          18
+#define KW_BREAK        19
+#define KW_SWITCH       20
+#define KW_START        21
+#define KW_END          22
+#define KW_CASE         23
+#define KW_DFT          24
+#define KW_PUBLIC       25
+#define KW_OFFSET       26
+#define KW_IMPORT       27
+#define KW__IMPORT      28
+#define KW_IFDEF        29
+#define KW_IFNDEF       30
+#define KW_IFAOT        31
+#define KW_IFJIT        32
+#define KW_ENDIF        33
+#define KW_ASSERT       34
+#define KW_REG          35
+#define KW_NOREG        36
+#define KW_LASTCLASS    37
+#define KW_NO_WARN      38
+#define KW_HELP_INDEX   39
+#define KW_HELP_FILE    40
+#define KW_STATIC       41
+#define KW_LOCK         42
+#define KW_DEFINED      43
+#define KW_INTERRUPT    44
+#define KW_HASERRCODE   45
+#define KW_ARGPOP       46
+#define KW_NOARGPOP     47
+
+#define AKW_ALIGN       64
+#define AKW_ORG         65
+#define AKW_I0          66
+#define AKW_I8          67
+#define AKW_I16         68
+#define AKW_I32         69
+#define AKW_I64         70
+#define AKW_U0          71
+#define AKW_U8          72
+#define AKW_U16         73
+#define AKW_U32         74
+#define AKW_U64         75
+#define AKW_F64         76
+#define AKW_DU8         77
+#define AKW_DU16        78
+#define AKW_DU32        79
+#define AKW_DU64        80
+#define AKW_DUP         81
+#define AKW_USE16       82
+#define AKW_USE32       83
+#define AKW_USE64       84
+#define AKW_IMPORT      85
+#define AKW_LIST        86
+#define AKW_NOLIST      87
+#define AKW_BINFILE     88
+#define KW_KWS_NUM      89
+
+#define CMP_TEMPLATE_INC        0x00
+#define CMP_TEMPLATE_DEC        0x01
+#define CMP_TEMPLATE_MOD        0x02
+#define CMP_TEMPLATE_LESS       0x03
+#define CMP_TEMPLATE_GREATER    0x04
+#define CMP_TEMPLATE_LESS_EQU   0x05
+#define CMP_TEMPLATE_GREATER_EQU 0x06
+#define CMP_TEMPLATE_STRLEN     0x07
+#define CMP_TEMPLATE_RDTSC      0x08
+#define CMP_TEMPLATE_SIGN_I64   0x09
+#define CMP_TEMPLATE_FSTP       0x0A
+#define CMP_TEMPLATE_FLD        0x0B
+#define CMP_TEMPLATE_SQR        0x0C
+#define CMP_TEMPLATE_ABS        0x0D
+#define CMP_TEMPLATE_SQRT       0x0E
+#define CMP_TEMPLATE_SIN        0x0F
+#define CMP_TEMPLATE_COS        0x10
+#define CMP_TEMPLATE_TAN        0x11
+#define CMP_TEMPLATE_ATAN       0x12
+
+#define ASSOCF_LEFT     1
+#define ASSOCF_RIGHT    2
+#define ASSOC_MASK      3
+
+#define PREC_NULL               0x00
+#define PREC_TERM               0x04
+#define PREC_UNARY_POST         0x08
+#define PREC_UNARY_PRE          0x0C
+#define PREC_EXP                0x10
+#define PREC_MUL                0x14
+#define PREC_AND                0x18
+#define PREC_XOR                0x1C
+#define PREC_OR                 0x20
+#define PREC_ADD                0x24
+#define PREC_CMP                0x28
+#define PREC_CMP2               0x2C
+#define PREC_AND_AND            0x30
+#define PREC_XOR_XOR            0x34
+#define PREC_OR_OR              0x38
+#define PREC_ASSIGN             0x3C
+
+#define PREC_MAX                0x40
+
+//Function/static/public flags
+#define FSF_PUBLIC              0x01
+#define FSF_ASM                 0x02
+#define FSF_STATIC              0x04
+#define FSF__                   0x08
+#define FSF_INTERRUPT           (1<<Ff_INTERRUPT)
+#define FSF_HASERRCODE          (1<<Ff_HASERRCODE)
+#define FSF_ARGPOP              (1<<Ff_ARGPOP)
+#define FSF_NOARGPOP            (1<<Ff_NOARGPOP)
+#define FSG_FUN_FLAGS1 (FSF_INTERRUPT|FSF_HASERRCODE|FSF_ARGPOP|FSF_NOARGPOP)
+#define FSG_FUN_FLAGS2 (FSG_FUN_FLAGS1|FSF_PUBLIC)
+
+//Byte 0
+#define PRS0_NULL               0x000000
+#define PRS0__EXTERN            0x000001
+#define PRS0__INTERN            0x000002
+#define PRS0__IMPORT            0x000003
+#define PRS0_EXTERN             0x000004
+#define PRS0_IMPORT             0x000005
+#define PRS0_TYPECAST           0x000006
+
+//Byte 1
+#define PRS1B_NULL              0
+#define PRS1_NULL               0x000000
+#define PRS1B_LOCAL_VAR         1
+#define PRS1_LOCAL_VAR          0x000100
+#define PRS1B_FUN_ARG           2
+#define PRS1_FUN_ARG            0x000200
+#define PRS1B_CLASS             3
+#define PRS1_CLASS              0x000300
+#define PRS1B_STATIC_LOCAL_VAR  4
+#define PRS1_STATIC_LOCAL_VAR   0x000400
+#define PRS1B__EXTERN_IMPORT    5
+#define PRS1_NOT_REALLY__EXTERN 0x000500
+
+#define PRSF_UNION              0x010000
+
+class COptReg
+{
+  I64   offset;
+  CMemberLst *m;
+};
+
+#define CMPF_ASM_BLK            1
+#define CMPF_ONE_ASM_INS        2
+#define CMPF_LEX_FIRST          4
+#define CMPF_PRS_SEMICOLON      8
+
+#help_index ""
+
+ diff --git a/public/Wb/Compiler/CompilerB.HH b/public/Wb/Compiler/CompilerB.HH old mode 100644 new mode 100755 diff --git a/public/Wb/Compiler/CompilerB.HH.HTML b/public/Wb/Compiler/CompilerB.HH.HTML new file mode 100755 index 0000000..3182ff0 --- /dev/null +++ b/public/Wb/Compiler/CompilerB.HH.HTML @@ -0,0 +1,110 @@ + + + + + + + + + + + +
+#help_index "Compiler"
+extern U0 CInit(Bool first);
+public extern I64 ExeFile(U8 *name,I64 ccf_flags=0);
+public extern I64 ExeFile2(U8 *name,I64 ccf_flags=0);
+public extern I64 ExePrint(U8 *fmt,...);
+public extern I64 ExePrint2(U8 *fmt,...);
+public extern I64 ExePutS(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0,
+        CLexHashTableContext *htc=NULL);
+public extern I64 ExePutS2(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0);
+public _extern _LAST_FUN I64 LastFun(I64 argc,I64 *argv);
+public extern I64 RunFile(U8 *name,I64 ccf_flags=0,...);
+public extern I64 RunFile2(U8 *name,I64 ccf_flags=0,...);
+public extern CCmpGlbls cmp;
+
+#help_index "Compiler/Directive"
+#help_file "::/Doc/Directives"
+public extern Bool Echo(Bool val);
+public extern Bool GetOption(I64 num);
+public extern I64 PassTrace(I64 i=0b1001111101);
+extern U0 StreamDir();
+public extern I64 StreamExePrint(U8 *fmt,...);
+public extern U0 StreamPrint(U8 *fmt,...);
+public extern Bool Trace(Bool val=ON);
+
+#help_index "Compiler/Lex"
+#help_file "::/Doc/Lex"
+extern U0 ClassMemberLstDel(CHashClass *c);
+public extern U0 CmpCtrlDel(CCmpCtrl *cc);
+public extern CCmpCtrl *CmpCtrlNew(U8 *buf=NULL,I64 flags=0,U8 *filename=NULL);
+public extern I64 CmpCtrlSize(CCmpCtrl *cc);
+public extern I64 IsLexExpression2Bin(
+        CCmpCtrl *cc,U8 **machine_code); //FALSE=no err
+public extern I64 Lex(CCmpCtrl *cc);
+public extern U0 LexAttachDoc(CCmpCtrl *cc,CLexFile *tmpf=NULL,
+        CDoc *doc=NULL,U8 *abs_filename=NULL,CDocEntry *doc_e=NULL,I64 col=0);
+public extern CD2I32 *LexD2I32(CCmpCtrl *cc,CD2I32 *p);
+public extern CD3I32 *LexD3I32(CCmpCtrl *cc,CD3I32 *p);
+public extern U0 LexExcept(CCmpCtrl *cc,U8 *str=NULL);
+public extern I64 LexExpression(CCmpCtrl *cc);
+public extern U8 *LexExpression2Bin(CCmpCtrl *cc,I64 *_type=NULL);
+public extern F64 LexExpressionF64(CCmpCtrl *cc);
+public extern I64 LexExpressionI64(CCmpCtrl *cc);
+public extern U8 *LexExtStr(CCmpCtrl *cc,I64 *_size=NULL,Bool lex_next=TRUE);
+public extern U8 *LexFirstRem(CCmpCtrl *cc,U8 *marker,I64 _len=NULL);
+public extern I64 LexGetChar(CCmpCtrl *cc);
+public extern U0 LexPopNoRestore(CCmpCtrl *cc);
+public extern U0 LexPopRestore(CCmpCtrl *cc);
+public extern U0 LexPush(CCmpCtrl *cc);
+public extern U0 LexPutLine(CCmpCtrl *cc,U8 *start);
+public extern U0 LexPutPos(CCmpCtrl *cc);
+public extern U0 LexPutToken(CCmpCtrl *cc);
+public extern U0 LexSkipEol(CCmpCtrl *cc);
+public extern U8 *LexStmt2Bin(
+        CCmpCtrl *cc,I64 *_type,I64 cmp_flags=CMPF_PRS_SEMICOLON);
+public extern U0 LexWarn(CCmpCtrl *cc,U8 *str=NULL);
+extern CMemberLst *MemberClassBaseFind(
+        CHashClass *needle_class,CHashClass *haystack_class);
+public extern CMemberLst *MemberFind(U8 *needle_str,CHashClass *haystack_class);
+extern U0 MemberLstDel(CMemberLst *tmpm);
+public extern I64 MemberMetaData(U8 *st,CMemberLst *ml);
+public extern CMemberLstMeta *MemberMetaFind(U8 *st,CMemberLst *ml);
+public extern CHashClass *OptClassFwd(CHashClass *tmpc);
+public extern I64 PrsKeyWord(CCmpCtrl *cc);
+
+#help_index "Compiler;Cmd Line (Typically)"
+extern I64 Cmp(U8 *filename,
+        U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv_let=0);
+
+#help_index "Debugging/Unassemble"
+public extern U8 *U(U8 *rip,I64 cnt=20,I64 seg_size=64);
+public extern U0 Ui(U8 *buf,U8 **_rip,I64 seg_size=64,
+        I64 *_jmp_dst=NULL,Bool just_ins=FALSE);
+public extern I64 Un(U8 *rip,I64 cnt=0x80,I64 seg_size=64);
+extern CUAsmGlbls uasm;
+
+#help_index "Hash/System"
+public extern I64 HashEntrySize(CHashSrcSym *tmph);
+public extern I64 HashEntrySize2(CHashSrcSym *tmph);
+public extern I64 HashTableSize2(CHashTable *table);
+
+ diff --git a/public/Wb/Compiler/Lex.HC.HTML b/public/Wb/Compiler/Lex.HC.HTML new file mode 100755 index 0000000..0e8b96d --- /dev/null +++ b/public/Wb/Compiler/Lex.HC.HTML @@ -0,0 +1,1226 @@ + + + + + + + + + + + +
+CLexFile *LexFilePush(CCmpCtrl *cc)
+{//#include file push.
+  CLexFile *res=CAlloc(sizeof(CLexFile));
+  if (res->next=cc->lex_include_stk)
+    res->depth=res->next->depth+1;
+  else
+    res->depth=-1; //Include depth starts with -1.
+  return cc->lex_include_stk=res;
+}
+
+CLexFile *LexFilePop(CCmpCtrl *cc)
+{//#include file pop.
+  CLexFile *tmpf;
+  if (tmpf=cc->lex_include_stk) {
+    if ((cc->lex_include_stk=tmpf->next) || !(cc->flags & CCF_DONT_FREE_BUF)) {
+      if (tmpf->flags & LFSF_DOC) {
+        if (tmpf->doc)
+          DocDel(tmpf->doc);
+      } else
+        Free(tmpf->buf);;
+    }
+    Free(tmpf->full_name);
+    Free(tmpf);
+  }
+  return cc->lex_include_stk;
+}
+
+CCmpCtrl *CmpCtrlNew(U8 *buf=NULL,I64 flags=0,U8 *filename=NULL)
+{//MAlloc and Init CCmpCtrl.
+//Frees buf in CmpCtrlDel unless CCF_DONT_FREE_BUF flag is set.
+  //FileName is for error reporting.  If files are #included,
+  //new names are used.  See Psalmody CmpCtrlNew.
+  CCmpCtrl *cc=CAlloc(sizeof(CCmpCtrl));
+  CLexFile *tmpf;
+  QueInit(cc);
+  cc->flags=flags;
+  cc->opts=1<<OPTf_WARN_UNUSED_VAR|1<<OPTf_WARN_HEADER_MISMATCH;
+  cc->htc.hash_mask=HTG_TYPE_MASK-HTT_IMPORT_SYS_SYM;
+  cc->htc.define_hash_table=cc->htc.hash_table_lst=
+        cc->htc.glbl_hash_table=cc->htc.local_hash_table=Fs->hash_table;
+  if (flags&CCF_KEEP_AT_SIGN)
+    cc->char_bmp_alpha_numeric=char_bmp_alpha_numeric_no_at;
+  else
+    cc->char_bmp_alpha_numeric=char_bmp_alpha_numeric;
+  tmpf=LexFilePush(cc);
+  QueInit(&cc->next_stream_blk);
+  if (filename)
+    tmpf->full_name=FileNameAbs(filename);
+  else
+    tmpf->full_name=StrNew(blkdev.tmp_filename);
+  if (flags & CCF_PMT)
+    buf=CAlloc(8);
+  tmpf->buf=tmpf->buf_ptr=tmpf->line_start=cc->cur_buf_ptr=buf;
+  tmpf->line_num=1;
+  return cc;
+}
+
+U0 CmpCtrlDel(CCmpCtrl *cc)
+{//Free CCmpCtrl.
+  while (LexFilePop(cc));
+  LinkedLstDel(cc->lex_prs_stk);
+  LinkedLstDel(cc->htc.next);
+  Free(cc->ps);
+  Free(cc->cur_str);
+  Free(cc->cur_help_idx);
+  Free(cc->dollar_buf);
+  Free(cc);
+}
+
+I64 CmpCtrlSize(CCmpCtrl *cc)
+{//Mem size of CCmpCtrl and its members.
+  CLexFile *tmpf=cc->lex_include_stk;
+  I64 res=0;
+  while (tmpf) {
+    if (tmpf->next || !(cc->flags & CCF_DONT_FREE_BUF)) {
+      if (tmpf->flags & LFSF_DOC) {
+        if (tmpf->doc)
+          res+=DocSize(tmpf->doc);
+      } else
+        res+=MSize2(tmpf->buf);
+    }
+    res+=MSize2(tmpf->full_name);
+    res+=MSize2(tmpf);
+    tmpf=tmpf->next;
+  }
+  res+=MSize2(cc->cur_str);
+  res+=MSize2(cc);
+  return res;
+}
+
+U32 lex_zeros=0;
+
+Bool LexDollar(CCmpCtrl *cc,CDoc *doc,CDocEntry *doc_e)
+{
+  U8 *st;
+  if (cc->flags&CCF_IN_QUOTES) {
+    Free(cc->dollar_buf);
+    st=Doc2PlainText(doc,doc_e);
+    cc->dollar_buf=MStrPrint("$%$Q$",st);
+    cc->dollar_cnt=2;
+    Free(st);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+I64 LexGetChar(CCmpCtrl *cc)
+{//Get one char from stream. Allow put-back one.
+  U8 *ptr,*src;
+  CLexFile *tmpf;
+  CDoc *doc;
+  CDocEntry *doc_e;
+  if (!Btr(&cc->flags,CCf_USE_LAST_U16)) {
+lgc_start1:
+    if (!(src=cc->cur_buf_ptr++)) {
+      cc->cur_buf_ptr=NULL;
+      goto lgc_here;
+    }
+    switch [cc->last_U16=*src++] {
+      case 0:
+lgc_here:
+        tmpf=cc->lex_include_stk;
+        if (tmpf->flags & LFSF_DOC) {
+          doc=tmpf->doc;
+          doc_e=tmpf->cur_entry;
+          doc_e=doc_e->next;
+lgc_start2:
+          if (doc_e!=doc) {
+            tmpf->cur_entry=doc_e;
+            switch [doc_e->type_u8] {
+              case DOCT_TEXT:
+                if (doc_e->de_flags & ~(DOCEF_TAG|DOCEF_DEFINE|DOCEF_TAG_CB|
+                      DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|
+                      DOCEF_SKIP|DOCEF_FILTER_SKIP) &&
+                      LexDollar(cc,doc,doc_e) && *(src=cc->dollar_buf)) {
+                  tmpf->line_num=doc_e->y+1;
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                } else if (*(src=doc_e->tag))
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                else {
+                  doc_e=doc_e->next;
+                  goto lgc_start2;
+                }
+                break;
+              case DOCT_NEW_LINE:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                tmpf->line_start=doc_e->next;
+                tmpf->line_num=doc_e->y+2;//+1 because NEW_LINE is on prev line
+//+1 because doc y starts at zero
+                cmp.compiled_lines++;
+                cc->last_U16='\n';
+                goto lgc_done;
+              case DOCT_TAB:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                tmpf->line_num=doc_e->y+1;
+                cc->last_U16='\t';
+                goto lgc_done;
+              case DOCT_INS_BIN:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                tmpf->line_num=doc_e->y+1;
+                Free(cc->cur_str);
+                cc->cur_str=NULL;
+                cc->cur_str_len=0;
+                if (doc_e->bin_data) {
+                  ptr=MAlloc(doc_e->bin_data->size);
+                  if (doc_e->bin_data->data)
+                    MemCpy(ptr,doc_e->bin_data->data,doc_e->bin_data->size);
+                  cc->cur_str=ptr;
+                  cc->cur_str_len=doc_e->bin_data->size;
+                }
+                cc->last_U16=TK_INS_BIN;
+                goto lgc_done;
+              case DOCT_INS_BIN_SIZE:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                if (doc_e->bin_data)
+                  cc->cur_i64=doc_e->bin_data->size;
+                else
+                  cc->cur_i64=0;
+                tmpf->line_num=doc_e->y+1;
+                cc->last_U16=TK_INS_BIN_SIZE;
+                goto lgc_done;
+              case DOCT_SHIFTED_Y:
+                if (LexDollar(cc,doc,doc_e) && *(src=cc->dollar_buf)) {
+                  tmpf->line_num=doc_e->y+1;
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                } else {
+                  tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                  tmpf->line_num=doc_e->y+1;
+                  if (doc_e->attr<0)
+                    cc->last_U16=TK_SUPERSCRIPT;
+                  else if (doc_e->attr>0)
+                    cc->last_U16=TK_SUBSCRIPT;
+                  else
+                    cc->last_U16=TK_NORMALSCRIPT;
+                  goto lgc_done;
+                }
+                break;
+              case DOCT_MARKER:
+              case DOCT_CURSOR:
+                doc_e=doc_e->next;
+                goto lgc_start2;
+              case 0xFF: //nobound switch
+              default:
+                if (LexDollar(cc,doc,doc_e) && *(src=cc->dollar_buf)) {
+                  tmpf->line_num=doc_e->y+1;
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                } else {
+                  doc_e=doc_e->next;
+                  goto lgc_start2;
+                }
+            }
+          }
+          if (doc_e!=doc)
+            goto lgc_start1;
+          tmpf->cur_entry=doc->head.last; //When take next, will still be end.
+        }
+        tmpf=cc->lex_include_stk;
+        if (tmpf->next) {
+          tmpf=LexFilePop(cc);
+          cc->cur_buf_ptr=tmpf->buf_ptr;
+          cc->flags&=~CCF_USE_LAST_U16;
+          if (!(cc->last_U16=tmpf->last_U16))
+            goto lgc_start1;
+        } else {
+          if (cc->flags & CCF_PMT) {
+            Free(tmpf->buf);
+            ptr=CmdLinePmt;
+            if (StrCmp(ptr,"\n") && !cc->pmt_line++ && !StrCmp(ptr,"?\n") &&
+                cc->flags & CCF_QUESTION_HELP) {
+              Free(ptr);
+              ptr=StrNew("Help;;\n");
+            }
+            tmpf->buf=tmpf->buf_ptr=tmpf->line_start=cc->cur_buf_ptr=ptr;
+            goto lgc_start1;
+          } else {
+            if (src)
+              cc->cur_buf_ptr=src-1;
+            cc->last_U16=TK_EOF;
+          }
+        }
+        break;
+      case CH_CURSOR:
+        goto lgc_start1;
+      case '\n':
+        tmpf=cc->lex_include_stk;
+        if (!(tmpf->flags & LFSF_DOC)) {
+          tmpf->line_num++;
+          cmp.compiled_lines++;
+          tmpf->line_start=src;
+        }
+        break;
+      case 0xFF: //nobound switch
+    }
+lgc_done:
+    if (cc->last_U16==CH_SHIFT_SPACE)
+      cc->last_U16=CH_SPACE;
+    if (cc->opts & OPTF_ECHO &&
+          cc->last_U16<256 && Bt(char_bmp_printable,cc->last_U16))
+      '' cc->last_U16;
+  }
+  return cc->last_U16;
+}
+
+U0 LexSkipEol(CCmpCtrl *cc)
+{//LexGetChar to NULL until end-of-line.
+  I64 ch;
+  do ch=LexGetChar(cc);
+  while (Bt(char_bmp_non_eol,ch));
+}
+
+U8 *LexFirstRem(CCmpCtrl *cc,U8 *marker,I64 _len=NULL)
+{//LexGetChar() chars making str until marker.
+  U8 *res,*ptr;
+  CQueVectU8 *tmpv=QueVectU8New;
+  I64 i,len=0;
+  while (TRUE) {
+    i=LexGetChar(cc);
+    if (!i||StrOcc(marker,i))
+      break;
+    QueVectU8Put(tmpv,len++,i);
+  }
+  if (i)
+    Bts(&cc->flags,CCf_USE_LAST_U16);
+  res=ptr=MAlloc(len+1);
+  for (i=0;i<len;i++)
+    *ptr++=QueVectU8Get(tmpv,i);
+  *ptr=0;
+  QueVectU8Del(tmpv);
+  if (_len) *_len=len;
+  return res;
+}
+
+U0 LexIncludeStr(CCmpCtrl *cc,U8 *abs_filename,U8 *src,Bool actual_file)
+{
+  LexBackupLastChar(cc);
+  CLexFile *tmpf=LexFilePush(cc);
+  if (actual_file)
+    tmpf->full_name=StrNew(abs_filename);
+  else
+    tmpf->full_name=StrNew(blkdev.tmp_filename);
+  tmpf->line_num=1;
+  tmpf->buf=tmpf->buf_ptr=tmpf->line_start=cc->cur_buf_ptr=src;
+}
+
+CDoc *LexDocRead(U8 *abs_filename,I64 flags)
+{
+  CDoc *doc=DocNew(abs_filename);
+  U8 *src;
+  I64 size=0;
+  doc->flags|=flags;
+  src=FileRead(abs_filename,&size);
+  if (!src || !size) {
+    Free(src);
+    src=CAlloc(1);
+    size=0;
+  }
+  DocLoad(doc,src,size);
+  Free(src);
+  return doc;
+}
+
+I64 cmp_type_flags_src_code[(DOCT_TYPES_NUM+63)/64]={
+  1<<DOCT_TEXT|1<<DOCT_TAB|1<<DOCT_INS_BIN|1<<DOCT_INS_BIN_SIZE};
+
+U0 LexAttachDoc(CCmpCtrl *cc,CLexFile *tmpf=NULL,
+        CDoc *doc=NULL,U8 *abs_filename=NULL,CDocEntry *doc_e=NULL,I64 col=0)
+{//Start lexing doc. Give either doc or abs_filename.
+  if (!doc)
+    doc=LexDocRead(abs_filename,DOCF_DBL_DOLLARS);
+  if (!tmpf) {
+    LexBackupLastChar(cc);
+    tmpf=LexFilePush(cc);
+  }
+  if (!doc_e)
+    doc_e=doc->head.next;
+  tmpf->full_name=StrNew(doc->filename.name);
+  tmpf->doc=doc;
+  while (doc_e!=doc) {
+    if (Bt(cmp_type_flags_src_code,doc_e->type_u8))
+      break;
+    doc_e=doc_e->next;
+    col=doc_e->min_col;
+  }
+  if (doc_e!=doc) {
+    col=ClampI64(col,doc_e->min_col,doc_e->max_col);
+    tmpf->line_start=doc_e;
+    tmpf->buf=NULL;
+    tmpf->line_num=doc_e->y+1;
+    if (doc_e->type_u8==DOCT_TEXT) {
+      tmpf->cur_entry=doc_e;
+      tmpf->buf_ptr=doc_e->tag;
+    } else {
+      tmpf->cur_entry=doc_e->last; //TODO: might be problem at begin of file
+      tmpf->buf_ptr=&lex_zeros;
+    }
+    tmpf->flags=LFSF_DOC;
+  } else {//TODO: DocDel(doc)?
+    col=0;
+    tmpf->buf=tmpf->buf_ptr=tmpf->line_start=CAlloc(1);
+    tmpf->line_num=1;
+    tmpf->flags=0;
+  }
+  cc->cur_buf_ptr=tmpf->buf_ptr+col;
+  tmpf->last_U16=0;
+}
+
+I64 LexInStr(CCmpCtrl *cc,U8 *buf,I64 size,Bool *done)
+{
+  I64 i=0,j,k,ch;
+  *done=TRUE;
+  while (i<size-1) {
+    ch=LexGetChar(cc);
+    if (!ch || ch=='"') {
+      buf[i++]=0;
+      return i;
+    } else if (ch=='\\') {
+      switch (ch=LexGetChar(cc)) {
+        case '0':
+          buf[i++]=0;
+          break;
+        case '\'':
+          buf[i++]='\'';
+          break;
+        case '\`':
+          buf[i++]='\`';
+          break;
+        case '\\':
+          buf[i++]='\\';
+          break;
+        case '"':
+          buf[i++]='"';
+          break;
+        case 'd':
+          buf[i++]='$';
+          break;
+        case 'n':
+          buf[i++]='\n';
+          break;
+        case 'r':
+          buf[i++]='\r';
+          break;
+        case 't':
+          buf[i++]='\t';
+          break;
+        case 'x':
+        case 'X':
+          j=0;
+          for (k=0;k<2;k++) {
+            ch=ToUpper(LexGetChar(cc));
+            if (Bt(char_bmp_hex_numeric,ch)) {
+              if (ch<='9')
+                j=j<<4+ch-'0';
+              else
+                j=j<<4+ch-'A'+10;
+            } else {
+              cc->flags|=CCF_USE_LAST_U16;
+              break;
+            }
+          }
+          buf[i++]=j;
+          break;
+        default:
+          cc->flags|=CCF_USE_LAST_U16;
+          buf[i++]='\\';
+      }
+    } else if (ch=='$') {
+      buf[i++]='$';
+      if (cc->dollar_cnt)
+        cc->dollar_cnt--;
+      else if (LexGetChar(cc)!='$') {
+        cc->dollar_cnt=1;
+        cc->flags|=CCF_USE_LAST_U16;
+      }
+    } else
+      buf[i++]=ch;
+  }
+  *done=FALSE;
+  return i;
+}
+
+I64 Lex(CCmpCtrl *cc)
+{//Fetch next token.
+  I64 i,j,k,l,ch;
+  CHash *tmph;
+  Bool str_done,in_str,neg_e;
+  U8 *fbuf,*buf2,*buf3,buf[STR_LEN];
+  cc->last_line_num=cc->lex_include_stk->line_num;
+  while (TRUE) {
+lex_cont:
+    switch [ch=LexGetChar(cc)] {
+      case 0:
+        return cc->token=TK_EOF;
+      case TK_SUPERSCRIPT:
+        ch='>';
+        goto lex_ident;
+      case TK_SUBSCRIPT:
+        ch='<';
+        goto lex_ident;
+      case TK_NORMALSCRIPT:
+        ch='=';
+        goto lex_ident;
+      case '@':
+        if (cc->flags&CCF_KEEP_AT_SIGN) {
+          cc->token=ch;
+          goto lex_end;
+        }
+      case 'A'...'Z':
+      case 'a'...'z':
+      case '_':
+      case 128...255:
+lex_ident:
+        i=0;
+        buf[i++]=ch;
+        while (TRUE) {
+          if (i>=STR_LEN)
+            LexExcept(cc,"Ident limited to STR_LEN chars at ");
+          else if (!(ch=LexGetChar(cc)))
+            break;
+          else if (Bt(cc->char_bmp_alpha_numeric,ch))
+            buf[i++]=ch;
+          else if (ch==TK_SUPERSCRIPT)
+            buf[i++]='>';
+          else if (ch==TK_SUBSCRIPT)
+            buf[i++]='<';
+          else if (ch==TK_NORMALSCRIPT)
+            buf[i++]='=';
+          else {
+            cc->flags|=CCF_USE_LAST_U16;
+            break;
+          }
+        }
+        buf[i++]=0;
+        tmph=NULL;
+        if (cc->htc.local_var_lst)
+          cc->local_var_entry=MemberFind(buf,cc->htc.local_var_lst);
+        else
+          cc->local_var_entry=NULL;
+        if (!cc->local_var_entry && cc->htc.hash_table_lst)
+          tmph=HashFind(buf,cc->htc.hash_table_lst,cc->htc.hash_mask);
+        if (tmph)
+          j=tmph->type;
+        else
+          j=0;
+        if (j & HTT_DEFINE_STR && !(cc->flags & CCF_NO_DEFINES)) {
+          LexIncludeStr(cc,
+                tmph->str,StrNew(tmph(CHashDefineStr *)->data),FALSE);
+          cc->lex_include_stk->flags|=LFSF_DEFINE;
+        } else {
+          cc->hash_entry=tmph;
+          Free(cc->cur_str);
+          cc->cur_str=StrNew(buf);
+          cc->cur_str_len=i;
+          cc->token=TK_IDENT;
+          goto lex_end;
+        }
+        break;
+      case '0'...'9':
+        i=ch-'0';
+        ch=ToUpper(LexGetChar(cc));
+        if (ch=='X') {
+          while (TRUE) {
+            ch=ToUpper(LexGetChar(cc));
+            if (Bt(char_bmp_hex_numeric,ch)) {
+              if (ch<='9')
+                i=i<<4+ch-'0';
+              else
+                i=i<<4+ch-'A'+10;
+            } else {
+              cc->cur_i64=i;
+              cc->flags|=CCF_USE_LAST_U16;
+              cc->token=TK_I64;
+              goto lex_end;
+            }
+          }
+        } else if (ch=='B') {
+          while (TRUE) {
+            ch=LexGetChar(cc);
+            if (ch=='0')
+              i=i<<1;
+            else if (ch=='1')
+              i=i<<1+1;
+            else {
+              cc->cur_i64=i;
+              cc->flags|=CCF_USE_LAST_U16;
+              cc->token=TK_I64;
+              goto lex_end;
+            }
+          }
+        }
+        while (TRUE) {
+          if (Bt(char_bmp_dec_numeric,ch))
+            i=i*10+ch-'0';
+          else {
+            if (ch=='.' || ch=='e' || ch=='E') break;
+lex_is_int:
+            cc->cur_i64=i;
+            cc->flags|=CCF_USE_LAST_U16;
+            cc->token=TK_I64;
+            goto lex_end;
+          }
+          ch=LexGetChar(cc);
+        }
+        if (ch=='.') {
+          ch=LexGetChar(cc);
+          if (ch=='.') {
+            cc->flags|=CCF_LAST_WAS_DOT;
+            goto lex_is_int;
+          }
+        }
+lex_float_start:
+        k=0;
+        while (TRUE) {
+          if (Bt(char_bmp_dec_numeric,ch)) {
+            i=i*10+ch-'0';
+            k++;
+          } else {
+            if (ch=='e' || ch=='E')
+              break;
+            cc->cur_f64=i*Pow10I64(-k);
+            cc->flags|=CCF_USE_LAST_U16;
+            cc->token=TK_F64;
+            goto lex_end;
+          }
+          ch=LexGetChar(cc);
+        }
+        ch=LexGetChar(cc);
+        neg_e=FALSE;
+        if (ch=='-') {
+          neg_e=TRUE;
+          ch=LexGetChar(cc);
+        }
+        j=0;
+        while (TRUE) {
+          if (Bt(char_bmp_dec_numeric,ch))
+            j=j*10+ch-'0';
+          else {
+            if (neg_e)
+              cc->cur_f64=i*Pow10I64(-j-k);
+            else
+              cc->cur_f64=i*Pow10I64(j-k);
+            cc->flags|=CCF_USE_LAST_U16;
+            cc->token=TK_F64;
+            goto lex_end;
+          }
+          ch=LexGetChar(cc);
+        }
+        break;
+      case '"':
+        cc->flags|=CCF_IN_QUOTES;
+        buf2=NULL;
+        i=0;
+        do {
+          j=LexInStr(cc,buf,STR_LEN,&str_done);
+          buf3=MAlloc(i+j);
+          if (buf2) {
+            MemCpy(buf3,buf2,i);
+            Free(buf2);
+            buf2=buf3;
+            MemCpy(buf2+i,buf,j);
+          } else {
+            buf2=buf3;
+            MemCpy(buf2,buf,j);
+          }
+          i+=j;
+        } while (!str_done);
+        Free(cc->cur_str);
+        cc->cur_str=MAlloc(i);
+        MemCpy(cc->cur_str,buf2,i);
+        Free(buf2);
+        cc->cur_str_len=i;
+        cc->flags&=~CCF_IN_QUOTES;
+        cc->token=TK_STR;
+        goto lex_end;
+      case '\'':
+        if (cc->flags&CCF_NO_CHAR_CONST)
+          break;
+        k=0;
+        for (j=0;j<8;j++) {
+          if (!(ch=LexGetChar(cc)) || ch=='\'')
+            break;
+          if (ch=='\\') {
+            switch (ch=LexGetChar(cc)) {
+              case '0':         k.u8[j]=0;      break;
+              case '\'':        k.u8[j]='\'';   break;
+              case '\`':        k.u8[j]='\`';   break;
+              case '"':         k.u8[j]='"';    break;
+              case '\\':        k.u8[j]='\\';   break;
+              case 'd':         k.u8[j]='$';    break;
+              case 'n':         k.u8[j]='\n';   break;
+              case 'r':         k.u8[j]='\r';   break;
+              case 't':         k.u8[j]='\t';   break;
+              case 'x':
+              case 'X':
+                i=0;
+                for (l=0;l<2;l++) {
+                  ch=ToUpper(LexGetChar(cc));
+                  if (Bt(char_bmp_hex_numeric,ch)) {
+                    if (ch<='9')
+                      i=i<<4+ch-'0';
+                    else
+                      i=i<<4+ch-'A'+10;
+                  } else {
+                    cc->flags|=CCF_USE_LAST_U16;
+                    break;
+                  }
+                }
+                k.u8[j]=i;
+                break;
+              default:
+                k.u8[j]='\\';
+                cc->flags|=CCF_USE_LAST_U16;
+            }
+          } else if (ch=='$') {
+            ch=LexGetChar(cc);
+            k.u8[j]='$';
+            if (ch!='$')
+              cc->flags|=CCF_USE_LAST_U16;
+          } else
+            k.u8[j]=ch;
+        }
+        if (ch!='\'' && (ch=LexGetChar(cc)) && ch!='\'')
+          LexExcept(cc,"Char const limited to 8 chars at ");
+        cc->cur_i64=k;
+        cc->token=TK_CHAR_CONST;
+        goto lex_end;
+      case '#':
+        if (cc->flags&CCF_KEEP_SIGN_NUM) {
+          cc->token=ch;
+          goto lex_end;
+        }
+        if (Lex(cc)!=TK_IDENT)  //skip '#'
+          goto lex_end;
+        if (!(tmph=cc->hash_entry))
+          goto lex_end;
+        if (!(tmph->type & HTT_KEYWORD))
+          goto lex_end;
+        switch (i=tmph(CHashGeneric *)->user_data0) {
+          case KW_INCLUDE:
+            if (Lex(cc)!=TK_STR)
+              goto lex_end;
+            fbuf=ExtDft(cc->cur_str,"HC.Z");
+            buf2=FileNameAbs(fbuf);
+            Free(fbuf);
+            if (Bt(&sys_run_level,RLf_DOC))
+              LexAttachDoc(cc,,,buf2);
+            else
+              LexIncludeStr(cc,buf2,FileRead(buf2),TRUE);
+            Free(buf2);
+            break;
+          case KW_DEFINE:
+            cc->flags|=CCF_NO_DEFINES;
+            if (Lex(cc)==TK_IDENT) {
+              tmph=CAlloc(sizeof(CHashDefineStr));
+              tmph->str=cc->cur_str;
+              cc->cur_str=0;
+              tmph->type=HTT_DEFINE_STR;
+              HashSrcFileSet(cc,tmph);
+
+              do ch=LexGetChar(cc); //skip space between define name and start
+              while (Bt(char_bmp_non_eol_white_space,ch));
+
+              i=j=0;
+              buf2=NULL;
+              if (ch) {
+                in_str=FALSE;
+                do {
+                  if (ch=='\\') {
+                    if (ch=LexGetChar(cc)) {
+                      if (ch!='\r' && ch!='\n') {
+                        buf[j++]='\\';
+                        buf[j++]=ch;
+                      } else if (ch=='\r' && LexGetChar(cc)!='\n')
+                        cc->flags|=CCF_USE_LAST_U16;
+                    } else {
+                      buf[j++]='\\';
+                      break;
+                    }
+                  } else if (ch!='\n') {
+                    if (ch=='\"')
+                      in_str=!in_str;
+                    buf[j++]=ch;
+                  } else
+                    break;
+                  while (ch=LexGetChar(cc)) {
+                    if (ch=='/') {
+                      ch=LexGetChar(cc);
+                      if (ch=='/' && !in_str) {
+                        do ch=LexGetChar(cc);
+                        while (Bt(char_bmp_non_eol,ch));
+                        break;
+                      } else {
+                        buf[j++]='/';
+                        cc->flags|=CCF_USE_LAST_U16;
+                      }
+                    } else if (ch=='\\') {
+                      if (ch=LexGetChar(cc)) {
+                        if (ch=='\"') {
+                          buf[j++]='\\';
+                          buf[j++]=ch;
+                        } else {
+                          cc->flags|=CCF_USE_LAST_U16;
+                          ch='\\';
+                          break;
+                        }
+                      }
+                    } else if (Bt(char_bmp_non_eol,ch)) {
+                      if (ch=='\"')
+                        in_str=!in_str;
+                      buf[j++]=ch;
+                    } else
+                      break;
+                    if (j>=STR_LEN-4) {//Spot for ['\'][ch],[ch],[0]
+                      buf[j++]=0;
+                      buf3=MAlloc(i+j);
+                      if (buf2) {
+                        MemCpy(buf3,buf2,i);
+                        Free(buf2);
+                        buf2=buf3;
+                        MemCpy(buf2+i,buf,j);
+                      } else {
+                        buf2=buf3;
+                        MemCpy(buf2,buf,j);
+                      }
+                      i+=j-1;
+                      j=0;
+                    }
+                  }
+                } while (ch=='\\');
+              }
+              buf[j++]=0;
+              buf3=MAlloc(i+j);
+              if (buf2) {
+                MemCpy(buf3,buf2,i);
+                Free(buf2);
+                buf2=buf3;
+                MemCpy(buf2+i,buf,j);
+              } else {
+                buf2=buf3;
+                MemCpy(buf2,buf,j);
+              }
+              tmph(CHashDefineStr *)->data=buf2;
+              tmph(CHashDefineStr *)->cnt=-1;
+              HashAdd(tmph,cc->htc.define_hash_table);
+            }
+            cc->flags&=~CCF_NO_DEFINES;
+            break;
+          case KW_ELSE:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_ELSE;
+              goto lex_end;
+            }
+lex_else:
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+
+          case KW_IF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IF;
+              goto lex_end;
+            }
+lex_if:
+            cc->flags|=CCF_IN_IF;
+            if (!Lex(cc)) {
+              cc->flags&=~CCF_IN_IF;
+              goto lex_end;
+            }
+            if (LexExpression(cc)) {
+              cc->flags&=~CCF_IN_IF;
+              switch (cc->token) {
+                case TK_IF:     goto lex_if;
+                case TK_IFDEF:  goto lex_ifdef;
+                case TK_IFNDEF: goto lex_ifndef;
+                case TK_IFAOT:  goto lex_ifaot;
+                case TK_IFJIT:  goto lex_ifjit;
+                case TK_ELSE:   goto lex_else;
+                case TK_ENDIF:  goto lex_cont;
+                default:        goto lex_end;
+              }
+            } else {
+              cc->flags&=~CCF_IN_IF;
+              if (cc->token!=TK_ENDIF && cc->token!=TK_ELSE) {
+                if (cc->token==TK_IF || cc->token==TK_IFDEF ||
+                      cc->token==TK_IFNDEF || cc->token==TK_IFAOT ||
+                      cc->token==TK_IFJIT)
+                  j=2;
+                else
+                  j=1;
+                do {
+                  if (ch=LexGetChar(cc)) {
+                    if (ch=='#') {
+                      if (!Lex(cc))
+                        goto lex_end;
+                      i=PrsKeyWord(cc);
+                      if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                            i==KW_IFAOT || i==KW_IFJIT)
+                        j++;
+                      else if (i==KW_ENDIF)
+                        j--;
+                      else if (i==KW_ELSE && j==1)
+                        break;
+                    }
+                  } else {
+                    cc->token=TK_EOF;
+                    goto lex_end;
+                  }
+                } while (j);
+              }
+            }
+            break;
+          case KW_IFDEF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFDEF;
+              goto lex_end;
+            }
+lex_ifdef:
+            cc->flags|=CCF_NO_DEFINES;
+            if (!Lex(cc)) {
+              cc->flags&=~CCF_NO_DEFINES;
+              goto lex_end;
+            }
+            cc->flags&=~CCF_NO_DEFINES;
+            if (cc->token!=TK_IDENT)
+              goto lex_end;
+            if (cc->hash_entry)
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_IFNDEF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFNDEF;
+              goto lex_end;
+            }
+lex_ifndef:
+            cc->flags|=CCF_NO_DEFINES;
+            if (!Lex(cc)) {
+              cc->flags&=~CCF_NO_DEFINES;
+              goto lex_end;
+            }
+            cc->flags&=~CCF_NO_DEFINES;
+            if (cc->token!=TK_IDENT)
+              goto lex_end;
+            if (!cc->hash_entry)
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_IFAOT:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFAOT;
+              goto lex_end;
+            }
+lex_ifaot:
+            if (cc->flags & CCF_AOT_COMPILE)
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_IFJIT:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFAOT;
+              goto lex_end;
+            }
+lex_ifjit:
+            if (!(cc->flags & CCF_AOT_COMPILE))
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_ENDIF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_ENDIF;
+              goto lex_end;
+            }
+            break;
+          case KW_ASSERT:
+            if (!Lex(cc))
+              goto lex_end;
+            if (!LexExpression(cc))
+              LexWarn(cc,"Assert Failed ");
+            goto lex_end;
+          case KW_EXE:
+            if (!Lex(cc))
+              goto lex_end;
+            PrsStreamBlk(cc);
+            goto lex_end;
+          case KW_HELP_INDEX:
+            if (Lex(cc)!=TK_STR)
+              goto lex_end;
+            Free(cc->cur_help_idx);
+            cc->cur_help_idx=LexExtStr(cc,,FALSE);
+            break;
+          case KW_HELP_FILE:
+            if (Lex(cc)!=TK_STR)
+              goto lex_end;
+            tmph=CAlloc(sizeof(CHashSrcSym));
+            fbuf=ExtDft(cc->cur_str,"DD.Z");
+            tmph->str=FileNameAbs(fbuf);
+            Free(fbuf);
+            tmph->type=HTT_HELP_FILE|HTF_PUBLIC;
+            HashSrcFileSet(cc,tmph);
+            HashAdd(tmph,cc->htc.glbl_hash_table);
+            break;
+        }
+        break;
+      case '\n':
+        if (!(cc->flags&CCF_KEEP_NEW_LINES))
+          break; //else fall through
+      case TK_INS_BIN:
+      case TK_INS_BIN_SIZE:
+        cc->token=ch;
+        goto lex_end;
+      case '.':
+        if (cc->flags&CCF_KEEP_DOT) {
+          cc->token=ch;
+          goto lex_end;
+        }
+        if (cc->flags&CCF_LAST_WAS_DOT) {
+          cc->flags&=~CCF_LAST_WAS_DOT;
+          goto lex_dot_dot;
+        }
+        ch=LexGetChar(cc);
+        if ('0'<=ch<='9') {
+          i=0;
+          goto lex_float_start;
+        } else if (ch=='.') {
+lex_dot_dot:
+          cc->token=TK_DOT_DOT;
+          if (LexGetChar(cc)=='.')
+            cc->token=TK_ELLIPSIS;
+          else
+            cc->flags|=CCF_USE_LAST_U16;
+          goto lex_end;
+        }
+        cc->flags|=CCF_USE_LAST_U16;
+        cc->token='.';
+        goto lex_end;
+      case '!':
+      case '$'...'&':
+      case '('...'-':
+      case '/':
+      case ':'...'?':
+      case '[':
+      case ']'...'^':
+      case '{'...'~':
+      case '`':
+        if (!(i=cmp.dual_U16_tokens1[ch])) {
+          if (ch=='$') {
+            ch=LexGetChar(cc);
+            if (ch=='$') {
+              cc->token='$';
+              goto lex_end;
+            } else if (ch) {
+              do ch=LexGetChar(cc);
+              while (ch && ch!='$');
+              if (!ch) {
+                cc->token=TK_EOF;
+                goto lex_end;
+              } else
+                goto lex_cont;
+            } else {
+              cc->flags|=CCF_USE_LAST_U16;
+              cc->token='$';
+              goto lex_end;
+            }
+          } else {
+            cc->token=ch;
+            goto lex_end;
+          }
+        } else {
+          j=LexGetChar(cc);
+          if (i.u16[0]==j) {
+            i>>=16;
+            if (!i) {// "/*"
+              j=1;
+              do {
+                if (!(ch=LexGetChar(cc)))
+                  return cc->token=TK_EOF;
+lex_check_comment:
+                if (ch=='*') {
+                  if (!(ch=LexGetChar(cc)))
+                    return cc->token=TK_EOF;
+                  if (ch=='/')
+                    j--;
+                  else
+                    goto lex_check_comment;
+                } else if (ch=='/') {
+                  if (!(ch=LexGetChar(cc)))
+                    return cc->token=TK_EOF;
+                  if (ch=='*')
+                    j++;
+                  else
+                    goto lex_check_comment;
+                }
+              } while (j);
+              goto lex_cont;
+            } else {
+              cc->token=i;
+              goto lex_end;
+            }
+          }
+          if (i=cmp.dual_U16_tokens2[ch]) {
+            if (i.u16[0]==j) {
+              i>>=16;
+              if (!i) {// "//"
+                LexSkipEol(cc);
+                if (cc->flags&CCF_KEEP_NEW_LINES) {
+                  cc->token='\n';
+                  goto lex_end;
+                } else
+                  goto lex_cont;
+              } else {
+                if (i==TK_SHL || i==TK_SHR) {
+                  j=LexGetChar(cc);
+                  if (j=='=') {
+                    if (i==TK_SHL)
+                      i=TK_SHL_EQU;
+                    else
+                      i=TK_SHR_EQU;
+                  } else
+                    cc->flags|=CCF_USE_LAST_U16;
+                }
+                cc->token=i;
+                goto lex_end;
+              }
+            }
+            if (i=cmp.dual_U16_tokens3[ch]) {
+              if (i.u16[0]==j) {
+                cc->token=i.u16[1];
+                goto lex_end;
+              }
+            }
+          }
+          cc->flags|=CCF_USE_LAST_U16;
+          cc->token=ch;
+          goto lex_end;
+        }
+      case TK_TKS_NUM:
+        break;
+    }
+  }
+lex_end:
+  LexGetChar(cc); //Do this so WAS_NEW_LINE is right
+  cc->flags|=CCF_USE_LAST_U16;
+  return cc->token;
+}
+
+ diff --git a/public/Wb/Compiler/LexLib.HC.HTML b/public/Wb/Compiler/LexLib.HC.HTML new file mode 100755 index 0000000..d641269 --- /dev/null +++ b/public/Wb/Compiler/LexLib.HC.HTML @@ -0,0 +1,306 @@ + + + + + + + + + + + +
+U0 LexBackupLastChar(CCmpCtrl *cc)
+{
+  CLexFile *tmpf=cc->lex_include_stk;
+  tmpf->buf_ptr=cc->cur_buf_ptr;
+  if (cc->flags & CCF_USE_LAST_U16) {
+    tmpf->last_U16=cc->last_U16;
+    cc->flags&=~CCF_USE_LAST_U16;
+  } else
+    tmpf->last_U16=0;
+}
+
+U0 LexPush(CCmpCtrl *cc)
+{//Create token-stream save point.
+  CLexFile *tmpf;
+  LexBackupLastChar(cc);
+  if (cc->lex_include_stk->last_U16)
+    cc->flags|=CCF_USE_LAST_U16;
+  tmpf=MAllocIdent(cc->lex_include_stk);
+  tmpf->next=cc->lex_prs_stk;
+  cc->lex_prs_stk=tmpf;
+}
+
+U0 LexPopRestore(CCmpCtrl *cc)
+{//Restore token-stream saved-point.
+//Bad things can happen if you cross an #include file boundary.
+  CLexFile *tmpf=cc->lex_prs_stk;
+  cc->cur_buf_ptr=tmpf->buf_ptr;
+  if (cc->last_U16=tmpf->last_U16)
+    cc->flags|=CCF_USE_LAST_U16;
+  else
+    cc->flags&=~CCF_USE_LAST_U16;
+  MemCpy(cc->lex_include_stk(U8 *)+sizeof(U8 *),tmpf(U8 *)+sizeof(U8 *),
+        sizeof(CLexFile)-sizeof(U8 *));
+  cc->lex_prs_stk=tmpf->next;
+  Free(tmpf);
+}
+
+U0 LexPopNoRestore(CCmpCtrl *cc)
+{//Don't restore token-stream saved-point.
+  CLexFile *tmpf=cc->lex_prs_stk;
+  cc->lex_prs_stk=tmpf->next;
+  Free(tmpf);
+}
+
+I64 MemberMetaData(U8 *needle_str,CMemberLst *haystack_member_lst)
+{//Find meta data name, return meta data val. See ::/Demo/ClassMeta.HC.
+  CMemberLstMeta *meta=haystack_member_lst->meta;
+  while (meta) {
+    if (!StrCmp(meta->str,needle_str))
+      return meta->user_data;
+    meta=meta->next;
+  }
+  return 0;
+}
+
+CMemberLstMeta *MemberMetaFind(U8 *needle_str,CMemberLst *haystack_member_lst)
+{//Find meta data name, return meta data struct. See ::/Demo/ClassMeta.HC.
+  CMemberLstMeta *meta=haystack_member_lst->meta;
+  while (meta) {
+    if (!StrCmp(meta->str,needle_str))
+      return meta;
+    meta=meta->next;
+  }
+  return NULL;
+}
+
+CMemberLst *MemberFind(U8 *needle_str,CHashClass *haystack_class)
+{//Find class member. See ClassRep() and DocForm().
+  I64 i;
+  CMemberLst *tmpm;
+  do {
+    tmpm=haystack_class->member_lst_and_root;
+    while (tmpm) {
+      if (!(i=StrCmp(tmpm->str,needle_str))) {
+        tmpm->use_cnt++;
+        return tmpm;
+      }
+      if (i<=0)
+        tmpm=tmpm->left;
+      else
+        tmpm=tmpm->right;
+    }
+  } while (haystack_class=haystack_class->base_class);
+  return NULL;
+}
+
+CMemberLst *MemberClassBaseFind(CHashClass *needle_class,
+        CHashClass *haystack_class)
+{//Find class member class base. For finding dup class local vars.
+  CMemberLst *tmpm;
+  tmpm=haystack_class->member_class_base_root;
+  while (tmpm) {
+    if (needle_class==tmpm->member_class_base)
+      return tmpm;
+    if (needle_class<tmpm->member_class_base)
+      tmpm=tmpm->left_class_base;
+    else
+      tmpm=tmpm->right_class_base;
+  }
+  return NULL;
+}
+
+U0 MemberAdd(CCmpCtrl *cc,CMemberLst *tmpm,CHashClass *tmpc,I64 mode)
+{
+  U8 *st=tmpm->str;
+  CMemberLst **tmpm1,*tmpm2;
+
+  if (MemberFind(st,tmpc) && StrCmp(st,"pad") &&
+        StrCmp(st,"reserved") && StrCmp(st,"_anon_"))
+    LexExcept(cc,"Duplicate member at ");
+  tmpm1=&tmpc->member_lst_and_root;
+  while (tmpm2=*tmpm1) {
+    if (StrCmp(tmpm2->str,st)<=0)
+      tmpm1=&tmpm2->left;
+    else
+      tmpm1=&tmpm2->right;
+  }
+  *tmpm1=tmpm;
+
+  if (mode==PRS1B_LOCAL_VAR) {
+    tmpm->member_class_base=
+        tmpm->member_class-tmpm->member_class->ptr_stars_cnt;
+    if (Bt(&cc->opts,OPTf_WARN_DUP_TYPES) &&
+         MemberClassBaseFind(tmpm->member_class_base,tmpc))
+      LexWarn(cc,"Duplicate type at ");
+    tmpm1=&tmpc->member_class_base_root;
+    while (tmpm2=*tmpm1) {
+      if (tmpm->member_class_base<tmpm2->member_class_base)
+        tmpm1=&tmpm2->left_class_base;
+      else if (tmpm->member_class_base>tmpm2->member_class_base)
+        tmpm1=&tmpm2->right_class_base;
+      else {
+        tmpm1=NULL;
+        break;
+      }
+    }
+    if (tmpm1)
+      *tmpm1=tmpm;
+  } else
+    tmpm->member_class_base=NULL;
+
+  tmpm->left=NULL;
+  tmpm->right=NULL;
+  tmpm->left_class_base=NULL;
+  tmpm->right_class_base=NULL;
+  tmpm2=tmpc->last_in_member_lst;
+  tmpm2->next=tmpc->last_in_member_lst=tmpm;
+}
+
+CMemberLst *MemberLstNew(I64 _reg)
+{
+  CMemberLst *res=CAlloc(sizeof(CMemberLst));
+  res->reg=_reg;
+  return res;
+}
+
+Bool  MemberLstCmp(CMemberLst *tmpm1,CMemberLst *tmpm2,I64 cnt=I64_MAX)
+{
+  while (tmpm1 && tmpm2 && cnt--) {
+    if (StrCmp(tmpm1->str,tmpm2->str) ||
+          tmpm1->member_class!=tmpm2->member_class ||
+          tmpm1->member_class_base!=tmpm2->member_class_base)
+      return FALSE;
+    if (tmpm1->flags&MLF_DFT_AVAILABLE || tmpm2->flags&MLF_DFT_AVAILABLE) {
+      if (tmpm1->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE)!=
+            tmpm2->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE))
+        return FALSE;
+      if (tmpm1->flags&MLF_STR_DFT_AVAILABLE) {
+        if (StrCmp(tmpm1->dft_val,tmpm2->dft_val))
+          return FALSE;
+      } else if (tmpm1->dft_val!=tmpm2->dft_val)
+        return FALSE;
+    }
+    tmpm1=tmpm1->next;
+    tmpm2=tmpm2->next;
+  }
+  if (cnt<0 || !tmpm1 && !tmpm2)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 MemberLstDel(CMemberLst *tmpm)
+{
+  CMemberLst *tmpm1;
+  CMemberLstMeta *tmp_meta,*tmp_meta1;
+  while (tmpm) {
+    tmpm1=tmpm->next;
+    Free(tmpm->str);
+    LinkedLstDel(tmpm->dim.next);
+    if (tmpm->flags & MLF_STR_DFT_AVAILABLE)
+      Free(tmpm->dft_val);
+    if (tmpm->flags & MLF_FUN)
+      HashDel(tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+    tmp_meta=tmpm->meta;
+    while (tmp_meta) {
+      tmp_meta1=tmp_meta->next;
+      Free(tmp_meta->str);
+      if (tmp_meta->flags&MLMF_IS_STR)
+        Free(tmp_meta->user_data);
+      Free(tmp_meta);
+      tmp_meta=tmp_meta1;
+    }
+    Free(tmpm);
+    tmpm=tmpm1;
+  }
+}
+
+U0 ClassMemberLstDel(CHashClass *tmpc)
+{
+  MemberLstDel(tmpc->member_lst_and_root);
+  tmpc->size=0;
+  tmpc->last_in_member_lst=&tmpc->member_lst_and_root;
+  tmpc->member_lst_and_root=NULL;
+  tmpc->member_class_base_root=NULL;
+  tmpc->member_cnt=0;
+  if (tmpc->type&HTT_FUN)
+    tmpc(CHashFun *)->arg_cnt=0;
+}
+
+I64 MemberLstSize(CHashClass *tmpc)
+{
+  CMemberLst *tmpm;
+  CMemberLstMeta *tmp_meta;
+  I64 res=0;
+  tmpm=tmpc->member_lst_and_root;
+  while (tmpm) {
+    res+=MSize2(tmpm->str);
+    res+=LinkedLstSize(tmpm->dim.next);
+    if (tmpm->flags & MLF_STR_DFT_AVAILABLE)
+      res+=MSize2(tmpm->dft_val);
+    if (tmpm->flags & MLF_FUN)
+      res+=HashEntrySize2(tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+    tmp_meta=tmpm->meta;
+    while (tmp_meta) {
+      res+=MSize2(tmp_meta->str);
+      if (tmp_meta->flags&MLMF_IS_STR)
+        res+=MSize2(tmp_meta->user_data);
+      res+=MSize2(tmp_meta);
+      tmp_meta=tmp_meta->next;
+    }
+    res+=MSize2(tmpm);
+    tmpm=tmpm->next;
+  }
+  return res;
+}
+
+U8 *LexExtStr(CCmpCtrl *cc,I64 *_size=NULL,Bool lex_next=TRUE)
+{//Lex TK_STR's to one combined str. _size includes terminator.
+  I64 len=cc->cur_str_len,len1,len2;
+  U8 *st=cc->cur_str,*st1,*st2;
+  cc->cur_str=NULL;
+  while (cc->token==TK_STR) {
+    st1=st;
+    len1=len;
+    if (!lex_next && LexGetChar(cc)!='\\') {
+      cc->flags|=CCF_USE_LAST_U16;
+      break;
+    }
+    if (Lex(cc)==TK_STR) {
+      len2=cc->cur_str_len;
+      st2=cc->cur_str;
+      cc->cur_str=NULL;
+      len=len1+len2-1;
+      st=MAlloc(len);
+      if (len1>1)
+        MemCpy(st,st1,len1-1);
+      MemCpy(st+len1-1,st2,len2);
+      Free(st1);
+      Free(st2);
+    }
+  }
+  if (_size) *_size=len;
+  return st;
+}
+
+ diff --git a/public/Wb/Compiler/OpCodes.DD.HTML b/public/Wb/Compiler/OpCodes.DD.HTML index c4b246a..cb17b3e 100755 --- a/public/Wb/Compiler/OpCodes.DD.HTML +++ b/public/Wb/Compiler/OpCodes.DD.HTML @@ -27,7 +27,7 @@
-/* See AsmHashLoad().
+/* See AsmHashLoad().
 
 '!'= IEF_DONT_SWITCH_MODES
 '&'= IEF_DFT
diff --git a/public/Wb/Compiler/OptLib.HC.HTML b/public/Wb/Compiler/OptLib.HC.HTML
new file mode 100755
index 0000000..02795dc
--- /dev/null
+++ b/public/Wb/Compiler/OptLib.HC.HTML
@@ -0,0 +1,596 @@
+
+
+
+
+
+
+
+
+
+
+
+
+CCodeMisc *OptLabelFwd(CCodeMisc *lb)
+{
+  CCodeMisc *lb1;
+  while (lb1=lb->fwd)
+    lb=lb1;
+  return lb;
+}
+
+CHashClass *OptClassFwd(CHashClass *tmpc)
+{//Class forwarding for unions and subclasses.
+  CHashClass *tmpc1;
+  while (tmpc1=tmpc->fwd_class)
+    tmpc=tmpc1;
+  return tmpc;
+}
+
+U0 OptSetNOP1(CIntermediateCode *tmpi)
+{
+  tmpi->ic_code=IC_NOP1;
+  tmpi->ic_flags=0;
+  tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;
+  tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;
+}
+
+U0 OptSetNOP2(CIntermediateCode *tmpi,I64 stk_delta=1)
+{
+  tmpi->ic_code=IC_NOP2;
+  tmpi->ic_data=stk_delta;
+  tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;
+  tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;
+}
+
+CIntermediateCode *OptFree(CIntermediateCode *tmpi)
+{//We might access freed entries in CICTreeLinks
+  QueRem(tmpi);
+  Free(tmpi);
+  return NULL;
+}
+
+CIntermediateCode *OptLag(CIntermediateCode *tmpi)
+{
+  do {
+    if (!tmpi->ic_code)
+      return NULL;
+    else
+      tmpi=tmpi->last;
+  } while (tmpi->ic_code<=IC_END_EXP);
+  return tmpi;
+}
+
+CIntermediateCode *OptLag1(CIntermediateCode *tmpi)
+{
+  do {
+    if (!tmpi->ic_code)
+      return NULL;
+    else
+      tmpi=tmpi->last;
+  } while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);
+  return tmpi;
+}
+
+CIntermediateCode *OptLag2(CIntermediateCode *tmpi)
+{
+  do {
+    if (!tmpi->ic_code)
+      return NULL;
+    else
+      tmpi=tmpi->last;
+  } while (tmpi->ic_code<IC_END_EXP);
+  return tmpi;
+}
+
+CIntermediateCode *OptLead1(CIntermediateCode *tmpi)
+{
+  do {
+    tmpi=tmpi->next;
+    if (!tmpi->ic_code)
+      return NULL;
+  } while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);
+  return tmpi;
+}
+
+I64 CmpOffset2Reg(I64 offset,COptReg *reg_offsets)
+{
+  I64 i;
+  for (i=0;i<REG_REGS_NUM;i++)
+    if (offset==reg_offsets[i].offset)
+      return i;
+  return -1;
+}
+
+#define FBO1_NOT_CONST  0
+#define FBO1_INT        1
+#define FBO1_F64        2
+
+Bool OptFixupBinaryOp1(CIntermediateCode *tmpi,
+     CIntermediateCode *tmpi1,CIntermediateCode *tmpi2,
+     Bool *is_unsigned)
+{
+  CIntermediateCode *tmpii;
+  CHashClass *tmpc=tmpi->ic_class,*tmpc1,*tmpc2;
+
+  if (tmpi1->ic_flags&ICF_RES_TO_INT)
+    tmpc1=cmp.internal_types[RT_I64];
+  else if (tmpi1->ic_flags&ICF_RES_TO_F64)
+    tmpc1=cmp.internal_types[RT_F64];
+  else {
+    tmpc1=OptClassFwd(tmpi1->ic_class);
+  }
+
+  if (tmpi2->ic_flags&ICF_RES_TO_INT)
+    tmpc2=cmp.internal_types[RT_I64];
+  else if (tmpi2->ic_flags&ICF_RES_TO_F64)
+    tmpc2=cmp.internal_types[RT_F64];
+  else {
+    tmpc2=OptClassFwd(tmpi2->ic_class);
+  }
+
+  if (tmpc1->raw_type>tmpc2->raw_type)
+    tmpc=tmpi->ic_class=tmpc1;
+  else
+    tmpc=tmpi->ic_class=tmpc2;
+
+  if (tmpc->raw_type==RT_F64) {
+    if (tmpi1->ic_code==IC_IMM_I64) {
+      tmpi1->ic_data(F64)=tmpi1->ic_data;
+      tmpi1->ic_class=cmp.internal_types[RT_F64];
+      tmpi1->ic_code=IC_IMM_F64;
+      tmpi1->ic_flags&=~ICF_RES_TO_F64;
+    } else
+      if (tmpc1->raw_type!=RT_F64)
+        tmpi1->ic_flags|=ICF_RES_TO_F64;
+    if (tmpi2->ic_code==IC_IMM_I64) {
+      tmpi2->ic_data(F64)=tmpi2->ic_data;
+      tmpi2->ic_class=cmp.internal_types[RT_F64];
+      tmpi2->ic_code=IC_IMM_F64;
+      tmpi2->ic_flags&=~ICF_RES_TO_F64;
+    } else
+      if (tmpc2->raw_type!=RT_F64)
+        tmpi2->ic_flags|=ICF_RES_TO_F64;
+    if (IC_LESS<=tmpi->ic_code<=IC_GREATER_EQU && (tmpii=OptLead1(tmpi)) &&
+          tmpii->ic_code!=IC_PUSH_CMP && tmpii->ic_code!=IC_AND_AND) {
+//We are looking for float comparisons to zero to convert to int.
+      if (tmpi1->ic_code==IC_IMM_F64 && !tmpi1->ic_data &&
+            tmpi2->ic_code==IC_DEREF && tmpc2==cmp.internal_types[RT_F64]) {
+        tmpi1->ic_code==IC_IMM_I64;
+        goto fb_here1;
+      } else if (tmpi2->ic_code==IC_IMM_F64 && !tmpi2->ic_data &&
+            tmpi1->ic_code==IC_DEREF && tmpc1==cmp.internal_types[RT_F64]) {
+        tmpi2->ic_code==IC_IMM_I64;
+fb_here1:
+        tmpi1->ic_flags&=~ICF_RES_TO_F64;
+        tmpi->ic_class=tmpi1->ic_class=tmpi2->ic_class=
+              cmp.internal_types[RT_I64];
+        *is_unsigned=FALSE;
+        return FBO1_NOT_CONST;
+      }
+      goto fb_here2;
+    } else {
+fb_here2:
+      if (tmpi1->ic_code==IC_IMM_F64 && tmpi2->ic_code==IC_IMM_F64 &&
+            !(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
+        tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+        OptSetNOP1(tmpi1);
+        OptSetNOP1(tmpi2);
+        return FBO1_F64;
+      } else
+        return FBO1_NOT_CONST;
+    }
+  }
+  *is_unsigned=tmpc1->raw_type&RTF_UNSIGNED || tmpc2->raw_type&RTF_UNSIGNED;
+  if (tmpi1->ic_code==IC_IMM_I64 && tmpi2->ic_code==IC_IMM_I64 &&
+        !(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
+    tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+    OptSetNOP1(tmpi1);
+    OptSetNOP1(tmpi2);
+    return FBO1_INT;
+  } else
+    return FBO1_NOT_CONST;
+}
+
+Bool OptFixupBinaryOp2(CIntermediateCode **tmpi1,CIntermediateCode **tmpi2)
+{
+  CIntermediateCode *tmpii1=*tmpi1,
+        *tmpii2=*tmpi2;
+  if (tmpii1->ic_code==IC_IMM_I64 && !(tmpii1->ic_flags & ICF_RES_TO_F64))
+    return TRUE;
+  if (tmpii2->ic_code==IC_IMM_I64 && !(tmpii2->ic_flags & ICF_RES_TO_F64)) {
+    *tmpi1=tmpii2;
+    *tmpi2=tmpii1;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+Bool OptFixupUnaryOp(CIntermediateCode *tmpi, CIntermediateCode *tmpi1,
+     Bool *is_unsigned)
+{
+  CHashClass *tmpc,*tmpc1;
+  tmpc1=OptClassFwd(tmpi1->ic_class);
+  tmpi->ic_class=tmpc1;
+  tmpc=tmpi->ic_class;
+  if (tmpc->raw_type==RT_F64) {
+    if (tmpi1->ic_code==IC_IMM_I64) {
+      tmpi1->ic_data(F64)=tmpi1->ic_data;
+      tmpi1->ic_class=cmp.internal_types[RT_F64];
+      tmpi1->ic_code=IC_IMM_F64;
+      tmpi1->ic_flags&=~ICF_RES_TO_F64;
+    } else
+      if (tmpc1->raw_type!=RT_F64)
+        tmpi1->ic_flags|=ICF_RES_TO_F64;
+    if (tmpi1->ic_code==IC_IMM_F64) {
+      tmpi->ic_flags|=tmpi1->ic_flags;
+      OptSetNOP1(tmpi1);
+      return FBO1_F64;
+    } else
+      return FBO1_NOT_CONST;
+  }
+  *is_unsigned=tmpc1->raw_type&RTF_UNSIGNED;
+  if (tmpi1->ic_code==IC_IMM_I64) {
+    tmpi->ic_flags|=tmpi1->ic_flags;
+    OptSetNOP1(tmpi1);
+    return FBO1_INT;
+  } else
+    return FBO1_NOT_CONST;
+}
+
+extern CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi);
+
+CIntermediateCode *OptBrZero(CCmpCtrl *cc,CIntermediateCode *tmpi)
+{
+  CCodeMisc *lb_true,*lb_false;
+  CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;
+  switch (tmpii->ic_code) {
+    case IC_NOT:
+      tmpi->ic_code=IC_BR_NOT_ZERO;
+      tmpi->ic_class=tmpii->ic_class;
+      tmpi->ic_flags|=tmpii->ic_flags;
+      tmpi->t.arg1_class=tmpii->t.arg1_class;
+      tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+      OptFree(tmpii);
+      return OptBrNotZero(cc,tmpi);
+    case IC_EQU_EQU...IC_LESS_EQU:
+      tmpi->ic_code=(tmpii->ic_code-IC_EQU_EQU)^1+IC_BR_EQU_EQU;
+      break;
+    case IC_OR_OR:
+      tmpi->ic_code=IC_BR_OR_OR_ZERO;
+      break;
+    case IC_AND_AND:
+      tmpi->ic_code=IC_BR_AND_AND_ZERO;
+      break;
+    case IC_AND:
+      tmpi->ic_code=IC_BR_AND_ZERO;
+      break;
+    case IC_MM_:
+      if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&
+            tmpii->ic_class->raw_type!=RT_F64)
+        tmpi->ic_code=IC_BR_MM_ZERO;
+      break;
+    case IC_CALL_END:
+      tmpii2=OptLag(tmpii);
+      switch (tmpii2->ic_code) {
+        start:
+          case IC_CARRY:
+            tmpii2->ic_code=IC_BR_NOT_CARRY;
+            break;
+          case IC_BT:
+            tmpii2->ic_code=IC_BR_NOT_BT;
+            break;
+          case IC_LBTS:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTS:
+            tmpii2->ic_code=IC_BR_NOT_BTS;
+            break;
+          case IC_LBTR:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTR:
+            tmpii2->ic_code=IC_BR_NOT_BTR;
+            break;
+          case IC_LBTC:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTC:
+            tmpii2->ic_code=IC_BR_NOT_BTC;
+            break;
+        end:
+          tmpii2->ic_data=tmpi->ic_data;
+          tmpii->ic_code=IC_CALL_END2;
+          OptSetNOP1(tmpi);
+          return tmpii;
+      }
+      break;
+  }
+  if (tmpi->ic_code!=IC_BR_ZERO) {
+    tmpi->ic_class=tmpii->ic_class;
+    tmpi->ic_flags|=tmpii->ic_flags;
+    tmpi->t.arg1_class=tmpii->t.arg1_class;
+    tmpi->t.arg2_class=tmpii->t.arg2_class;
+    tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+    tmpi->t.arg2_tree=tmpii->t.arg2_tree;
+    OptFree(tmpii);
+
+    if (tmpi->ic_flags&ICF_PUSH_CMP &&
+          IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&
+          !(tmpi->ic_flags&ICF_USE_F64)) {
+      tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;
+      tmpi->ic_flags&=~ICF_PUSH_CMP;
+      tmpii=tmpi->next; //IC_PUSH_CMP inst
+      while (tmpii->ic_code!=IC_PUSH_CMP)
+        tmpii=tmpii->next;
+      tmpii->t.arg1_tree=tmpi;
+      OptSetNOP1(tmpii);
+    }
+
+    lb_true=tmpi->ic_data;
+    if (tmpi->ic_code==IC_BR_AND_AND_ZERO) {
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->ic_data=lb_true;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_code=IC_BR_ZERO;
+      OptBrZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_ZERO;
+      tmpii=OptBrZero(cc,tmpii);
+      OptSetNOP1(tmpi);
+    } else if (tmpi->ic_code==IC_BR_OR_OR_ZERO) {
+      lb_false=COCMiscNew(cc,CMT_LABEL);
+      tmpi->ic_code=IC_LABEL;
+      tmpi->ic_flags=0;
+      tmpi->ic_data=lb_false;
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_data=lb_false;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      OptBrNotZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_ZERO;
+      tmpii=OptBrZero(cc,tmpii);
+    } else
+      tmpii=tmpi;
+    if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {
+      tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;
+      tmpi->ic_flags&=~ICF_POP_CMP;
+    }
+    return tmpii;
+  }
+  return tmpi;
+}
+
+CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi)
+{
+  CCodeMisc *lb_true,*lb_false;
+  CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;
+  switch (tmpii->ic_code) {
+    case IC_NOT:
+      tmpi->ic_code=IC_BR_ZERO;
+      tmpi->ic_class=tmpii->ic_class;
+      tmpi->ic_flags|=tmpii->ic_flags;
+      tmpi->t.arg1_class=tmpii->t.arg1_class;
+      tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+      OptFree(tmpii);
+      return OptBrZero(cc,tmpi);
+    case IC_EQU_EQU...IC_LESS_EQU:
+      tmpi->ic_code=tmpii->ic_code+IC_BR_EQU_EQU-IC_EQU_EQU;
+      break;
+    case IC_OR_OR:
+      tmpi->ic_code=IC_BR_OR_OR_NOT_ZERO;
+      break;
+    case IC_AND_AND:
+      tmpi->ic_code=IC_BR_AND_AND_NOT_ZERO;
+      break;
+    case IC_AND:
+      tmpi->ic_code=IC_BR_AND_NOT_ZERO;
+      break;
+    case IC_MM_:
+      if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&
+            tmpii->ic_class->raw_type!=RT_F64)
+        tmpi->ic_code=IC_BR_MM_NOT_ZERO;
+      break;
+    case IC_CALL_END:
+      tmpii2=OptLag(tmpii);
+      switch (tmpii2->ic_code) {
+        start:
+          case IC_CARRY:
+            tmpii2->ic_code=IC_BR_CARRY;
+            break;
+          case IC_BT:
+            tmpii2->ic_code=IC_BR_BT;
+            break;
+          case IC_LBTS:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTS:
+            tmpii2->ic_code=IC_BR_BTS;
+            break;
+          case IC_LBTR:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTR:
+            tmpii2->ic_code=IC_BR_BTR;
+            break;
+          case IC_LBTC:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTC:
+            tmpii2->ic_code=IC_BR_BTC;
+            break;
+        end:
+          tmpii2->ic_data=tmpi->ic_data;
+          tmpii->ic_code=IC_CALL_END2;
+          OptSetNOP1(tmpi);
+          return tmpii;
+      }
+      break;
+  }
+  if (tmpi->ic_code!=IC_BR_NOT_ZERO) {
+    tmpi->ic_class=tmpii->ic_class;
+    tmpi->ic_flags|=tmpii->ic_flags;
+    tmpi->t.arg1_class=tmpii->t.arg1_class;
+    tmpi->t.arg2_class=tmpii->t.arg2_class;
+    tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+    tmpi->t.arg2_tree=tmpii->t.arg2_tree;
+    OptFree(tmpii);
+
+    if (tmpi->ic_flags&ICF_PUSH_CMP &&
+          IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&
+          !(tmpi->ic_flags&ICF_USE_F64)) {
+      tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;
+      tmpi->ic_flags&=~ICF_PUSH_CMP;
+      tmpii=tmpi->next; //IC_PUSH_CMP inst
+      while (tmpii->ic_code!=IC_PUSH_CMP)
+        tmpii=tmpii->next;
+      tmpii->t.arg1_tree=tmpi;
+      OptSetNOP1(tmpii);
+    }
+
+    lb_true=tmpi->ic_data;
+    if (tmpi->ic_code==IC_BR_OR_OR_NOT_ZERO) {
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      OptBrNotZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      tmpii=OptBrNotZero(cc,tmpii);
+      OptSetNOP1(tmpi);
+    } else if (tmpi->ic_code==IC_BR_AND_AND_NOT_ZERO) {
+      lb_false=COCMiscNew(cc,CMT_LABEL);
+      tmpi->ic_code=IC_LABEL;
+      tmpi->ic_flags=0;
+      tmpi->ic_data=lb_false;
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_data=lb_false;
+      tmpii->ic_code=IC_BR_ZERO;
+      OptBrZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      tmpii=OptBrNotZero(cc,tmpii);
+    } else
+      tmpii=tmpi;
+    if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {
+      tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;
+      tmpi->ic_flags&=~ICF_POP_CMP;
+    }
+    return tmpii;
+  }
+  return tmpi;
+}
+
+U0 OptFixSizeOf(CIntermediateCode *tmpi1,
+        CIntermediateCode *tmpi_push,CHashClass *tmpcc)
+{
+  if (tmpi1->ic_code==IC_MUL && tmpi1->t.arg2_tree->ic_code==IC_SIZEOF) {
+    tmpi1->t.arg2_tree->ic_code=IC_IMM_I64;
+    tmpi1->t.arg2_tree->ic_class=tmpcc;
+    tmpi_push->ic_class=tmpcc;
+    if (tmpcc->ptr_stars_cnt) {
+      tmpcc--;
+      if (tmpcc->size==1)
+        goto here;
+      tmpi1->t.arg2_tree->ic_data=tmpcc->size;
+    } else {
+here:
+      if (tmpi_push==tmpi1)
+        tmpi1->t.arg2_tree->ic_data=1;
+      else {
+        OptSetNOP1(tmpi1->t.arg2_tree);
+        OptSetNOP1(tmpi1);
+      }
+    }
+  }
+}
+
+I64 CmpRawType(CHashClass *tmpc)
+{
+  if (tmpc) {
+    tmpc=OptClassFwd(tmpc);
+    return tmpc->raw_type;
+  }
+  return 0;
+}
+
+I64 CmpRawTypePointed(CHashClass *tmpc)
+{
+  if (tmpc) {
+    if (tmpc->ptr_stars_cnt)
+      tmpc--;
+    tmpc=OptClassFwd(tmpc);
+    return tmpc->raw_type;
+  }
+  return 0;
+}
+
+U0 CmpMinTypePointed(CIntermediateCode *tmpi,I64 pt1)
+{
+  I64 pt;
+  if ((pt=tmpi->arg1_type_pointed_to) && pt!=RT_F64 && 0<pt1<pt)
+    tmpi->arg1_type_pointed_to=pt;
+}
+
+U0 CmpF1PushPop(CIntermediateCode *tmpi,CIntermediateCode *tmpi2)
+{
+  if (intermediate_code_table[tmpi2->ic_code].fpop||
+        tmpi2->ic_flags&ICF_RES_TO_F64)
+    Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+}
+
+U0 CmpF2PushPop(CIntermediateCode *tmpi,
+        CIntermediateCode *tmpi1,CIntermediateCode *tmpi2)
+{
+  if ((tmpi2->ic_code==IC_MOV || tmpi2->ic_code==IC_IMM_F64) &&
+        !(tmpi2->ic_flags&ICF_RES_TO_F64) &&
+        (intermediate_code_table[tmpi1->ic_code].fpop ||
+        tmpi1->ic_flags&ICF_RES_TO_F64))
+    Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+  else if ((intermediate_code_table[tmpi2->ic_code].fpop ||
+        tmpi2->ic_flags&ICF_RES_TO_F64)&&
+        !(tmpi1->ic_flags&ICF_RES_TO_F64))
+    Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+}
+
+class COptMemberVar
+{
+  I64 score,offset_start,offset_end,lea_balance;
+  CMemberLst *m;
+};
+
+I64 OptMVCompare(COptMemberVar *mv1,COptMemberVar *mv2)
+{
+  return mv2->score-mv1->score;
+}
+
+ diff --git a/public/Wb/Compiler/OptPass012.HC.HTML b/public/Wb/Compiler/OptPass012.HC.HTML new file mode 100755 index 0000000..3c79339 --- /dev/null +++ b/public/Wb/Compiler/OptPass012.HC.HTML @@ -0,0 +1,1319 @@ + + + + + + + + + + + +
+/*OptPass012
+
+Pass#0
+When parsing the arg expressions to a function
+call, there is a call to OptPass012 to determine
+the type of the expression. OptPass012
+
+Pass#1&2
+Constant expressions are simplified.
+Eliminated opcodes are set to NOP.
+Types are determined by reconstructing an
+expression tree for operators
+CIntermediateCode.CICTreeLinks.
+
+Pointer arithmetic size is set, once
+the type is determined.
+
+Branches are expressed with short-circuit
+logic. 3-Arg comparisons are established.
+
+*/
+
+CIntermediateCode *OptPass012(CCmpCtrl *cc)
+{/*Simplify CONST arithmetic.
+Sets the class throughout Expression trees.
+Returns the type of an Expression for use
+in int<-->F64 conversions of fun
+args.
+*/
+  I64 code,i;
+  Bool is_unsigned;
+  CHashClass *tmpc,*tmpc1,*tmpc2;
+  CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpi3,*tmpi_push,
+        *last_with_class=NULL;
+  CCodeMisc *lb,*lb1,*lb2;
+  CPrsStk *ps;
+  if (!(ps=cc->ps))
+    ps=cc->ps=MAlloc(sizeof(CPrsStk));
+  ps->ptr=0;
+  ps->ptr2=0;
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    tmpc=tmpi->ic_class;
+    tmpi->ic_class2=tmpc;
+    tmpi_push=tmpi;
+    MemSet(&tmpi->arg1,0,3*sizeof(CICArg));
+    tmpi->arg1_type_pointed_to=0;
+    switch [intermediate_code_table[code].arg_cnt] {
+      case IS_V_ARG:
+        ps->ptr-=tmpi->ic_data>>2;
+        break;
+      case IS_2_ARG:
+        tmpi2=PrsPop(ps);
+        tmpc2=tmpi2->ic_class;
+        tmpi->t.arg2_tree=tmpi2;
+        tmpi->t.arg2_class=PrsPop(ps);
+      case IS_1_ARG:
+        tmpi1=PrsPop(ps);
+        tmpc1=tmpi1->ic_class;
+        tmpi->t.arg1_tree=tmpi1;
+        tmpi->t.arg1_class=PrsPop(ps);
+        break;
+      case IS_0_ARG: //nobound switch
+        break;
+    }
+    if (intermediate_code_table[code].not_const)
+      cc->flags|=CCF_NOT_CONST;
+    switch [code] {
+      case IC_IMM_F64:
+        tmpi->ic_flags&=~ICF_RES_TO_F64;
+        if (cc->pass==2 && tmpi->ic_flags&ICF_RES_TO_INT) {
+          tmpi->ic_data=ToI64(tmpi->ic_data(F64));
+          tmpi->ic_flags&=~ICF_RES_TO_INT;
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+        }
+        break;
+      case IC_IMM_I64:
+        tmpi->ic_flags&=~ICF_RES_TO_INT;
+        if (cc->pass==2 && tmpi->ic_flags&ICF_RES_TO_F64) {
+          tmpi->ic_data(F64)=ToF64(tmpi->ic_data);
+          tmpi->ic_flags&=~ICF_RES_TO_F64;
+          tmpi->ic_code=IC_IMM_F64;
+          tmpi->ic_class=cmp.internal_types[RT_F64];
+        }
+        break;
+      case IC_HOLYC_TYPECAST:
+        if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) {
+          if (tmpi->ic_class->raw_type==RT_F64)
+            tmpi1->ic_code=IC_IMM_F64;
+          else
+            tmpi1->ic_code=IC_IMM_I64;
+          tmpi1->ic_class=tmpi->ic_class;
+          tmpi1->ic_flags|=tmpi->ic_flags;
+          tmpi_push=tmpi1;
+          OptSetNOP1(tmpi);
+        } else {
+          if (tmpi->ic_data) {//was paren
+            if (!tmpi_push->ic_class->ptr_stars_cnt) {
+              if (tmpi_push->ic_class->raw_type==RT_F64)
+                tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+              else
+                tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+            }
+          } else {
+            tmpi1->ic_class=tmpi->ic_class;
+            tmpi1->ic_flags|=tmpi->ic_flags;
+            tmpi_push=tmpi1;
+            OptSetNOP1(tmpi);
+          }
+        }
+        break;
+      case IC_FS:
+      case IC_GS:
+//CALL,FS/GS,CALL_END,IMM,ADD,DEREF-->MOV_FS/GS
+        tmpi1=tmpi->next->next; //IMM
+        tmpi2=tmpi1->next; //ADD
+        tmpi3=tmpi2->next; //DEREF
+        if (tmpi1->ic_code==IC_IMM_I64 && tmpi2->ic_code==IC_ADD &&
+              tmpi3->ic_code==IC_DEREF &&
+              !(tmpi3->ic_flags&~ICG_NO_CVT_MASK)) {
+          tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags|tmpi3->ic_flags;
+          if (tmpi->ic_code==IC_FS)
+            tmpi->ic_code=IC_MOV_FS;
+          else
+            tmpi->ic_code=IC_MOV_GS;
+          tmpi->ic_data=tmpi1->ic_data;
+          tmpi->ic_class =tmpi3->ic_class;
+          tmpi->ic_class2=tmpi3->ic_class2;
+          OptSetNOP1(tmpi1);
+          OptSetNOP1(tmpi2);
+          OptSetNOP1(tmpi3);
+
+          tmpi1=tmpi->last; //CALL
+          tmpi2=tmpi->next; //CALL_END
+          tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+          OptSetNOP1(tmpi1);
+          OptSetNOP1(tmpi2);
+        }
+        break;
+      case IC_PUSH_CMP:
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_AND_AND)
+            tmpi1=OptLag(tmpi1);
+          if (tmpi1)
+            tmpi->ic_class=tmpi1->ic_class;
+        }
+        tmpi->ic_class2=tmpi->ic_class;
+        tmpi->ic_data=0;
+        if (tmpi->ic_class->raw_type==RT_F64)
+          tmpi->ic_flags|=ICF_USE_F64;
+        break;
+      case IC_COM:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi->ic_data=~tmpi1->ic_data;
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_flags|=tmpi1->ic_flags;
+          OptSetNOP1(tmpi1);
+        }
+        tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        break;
+      start:
+        case IC_NOT:
+          if (tmpc->raw_type==RT_F64) {
+            if (tmpi1->ic_code==IC_IMM_F64) {
+              tmpi->ic_data(F64)=!tmpi1->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            }
+            break;
+          }
+          if (tmpi1->ic_code==IC_IMM_I64) {
+            tmpi->ic_data=!tmpi1->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            OptSetNOP1(tmpi1);
+          }
+          break;
+        case IC_UNARY_MINUS:
+          if (i=OptFixupUnaryOp(tmpi,tmpi1,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              tmpi->ic_data=-tmpi1->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=-tmpi1->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          }
+          if (tmpc1->type&HTT_INTERNAL_TYPE && tmpc1->raw_type&RTF_UNSIGNED)
+            tmpi->ic_class=cmp.internal_types[tmpc1->raw_type-1];
+          break;
+        case IC_SHL_CONST:
+          if (i=OptFixupUnaryOp(tmpi,tmpi1,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<<tmpi->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<<tmpi->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)<<tmpi->ic_data;
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi1->ic_code==IC_SHL_CONST) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->ic_data+=tmpi1->ic_data;
+            OptSetNOP1(tmpi1);
+          }
+          break;
+        case IC_SHR_CONST:
+          if (i=OptFixupUnaryOp(tmpi,tmpi1,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>>tmpi->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>>tmpi->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)>>tmpi->ic_data;
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi1->ic_code==IC_SHR_CONST) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->ic_data+=tmpi1->ic_data;
+            OptSetNOP1(tmpi1);
+          }
+          break;
+        case IC_SHL:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<<tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<<tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64) << tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi2->ic_code==IC_IMM_I64) {
+            tmpi->ic_flags|=tmpi2->ic_flags;
+            tmpi->ic_data=tmpi2->ic_data;
+            tmpi->ic_code=IC_SHL_CONST;
+            OptSetNOP1(tmpi2);
+          }
+          break;
+        case IC_SHR:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>>tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>>tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64) >> tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi2->ic_code==IC_IMM_I64) {
+            tmpi->ic_flags|=tmpi2->ic_flags;
+            tmpi->ic_data=tmpi2->ic_data;
+            tmpi->ic_code=IC_SHR_CONST;
+            OptSetNOP1(tmpi2);
+          }
+          break;
+      end:
+        if (!tmpi_push->ic_class->ptr_stars_cnt) {
+          if (tmpi_push->ic_class->raw_type==RT_F64)
+            tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+          else
+            tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        }
+        break;
+      case IC_DEREF:
+        if (cc->pass==2) {
+          if (!tmpc->size)
+            LexWarn(cc,"Dereference U0 ");
+          if (tmpi1->ic_class->raw_type!=RT_F64) {
+            if (tmpi1->ic_code==IC__PP) {
+              tmpi->ic_code=IC_DEREF_PP;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            } else if (tmpi1->ic_code==IC__MM) {
+              tmpi->ic_code=IC_DEREF_MM;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            }
+          }
+        }
+        break;
+      case IC__PP:
+      case IC__MM:
+      case IC_PP_:
+      case IC_MM_:
+        if (cc->pass==2 && !tmpc->size)
+          LexWarn(cc,"Dereference U0 ");
+        break;
+      case IC_POWER:
+        tmpc=tmpi->ic_class=cmp.internal_types[RT_F64];
+        if (tmpc1->raw_type!=RT_F64)
+          tmpi1->ic_flags|=ICF_RES_TO_F64;
+        if (tmpc2->raw_type!=RT_F64)
+          tmpi2->ic_flags|=ICF_RES_TO_F64;
+        tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+        break;
+      start:
+        case IC_MUL:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)*tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)*tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)*tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (tmpi1->ic_code==IC_IMM_I64 && cc->pass==2) {
+              switch (i=tmpi1->ic_data) {
+                case 0:
+                  break;
+                case 1:
+                  tmpi2->ic_flags|=tmpi->ic_flags|tmpi1->ic_flags;
+                  tmpi2->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi2;
+                  OptSetNOP1(tmpi1);
+                  OptSetNOP1(tmpi);
+                  break;
+                default:
+                  if (Bsf(i)==Bsr(i)) {
+                    tmpi->ic_flags|=tmpi1->ic_flags;
+                    tmpi->t.arg1_class=tmpi->t.arg2_class;
+                    tmpi->ic_data=Bsf(i);
+                    tmpi->ic_code=IC_SHL_CONST;
+                    OptSetNOP1(tmpi1);
+                  }
+              }
+            } else if (tmpi2->ic_code==IC_IMM_I64) {
+              switch (i=tmpi2->ic_data) {
+                case 0:
+                  break;
+                case 1:
+                  tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                  break;
+                default:
+                  if (Bsf(i)==Bsr(i)) {
+                    tmpi->ic_flags|=tmpi2->ic_flags;
+                    tmpi->ic_data=Bsf(i);
+                    tmpi->ic_code=IC_SHL_CONST;
+                    OptSetNOP1(tmpi2);
+                  } else if (tmpi1->ic_code==IC_MUL && cc->pass==2) {
+                    if (tmpi1->t.arg1_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      tmpi1->t.arg1_tree->ic_data*=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      tmpi1->t.arg2_tree->ic_data*=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    }
+                  }
+              }
+            } else if (tmpi2->ic_code==IC_IMM_F64 && cc->pass==2) {
+              if (tmpi2->ic_data(F64)==1.0) {
+                tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                tmpi1->ic_class2=tmpi->ic_class2;
+                tmpi_push=tmpi1;
+                OptSetNOP1(tmpi2);
+                OptSetNOP1(tmpi);
+              } else if (tmpi1->ic_code==IC_MUL) {
+                if (tmpi1->t.arg1_tree->ic_code==IC_IMM_F64) {
+                  tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                  tmpi1->t.arg1_tree->ic_data(F64)*=tmpi2->ic_data(F64);
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_F64) {
+                  tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                  tmpi1->t.arg2_tree->ic_data(F64)*=tmpi2->ic_data(F64);
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                }
+              }
+            }
+          }
+          break;
+        case IC_DIV:
+          if ((tmpi2->ic_data || tmpi2->ic_code!=IC_IMM_I64 &&
+                tmpi2->ic_code!=IC_IMM_F64) &&
+                (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned))) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)/tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)/tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)/
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (tmpi2->ic_code==IC_IMM_I64 && (i=tmpi2->ic_data)) {
+              if (i==1) {
+                tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                tmpi1->ic_class2=tmpi->ic_class2;
+                tmpi_push=tmpi1;
+                OptSetNOP1(tmpi2);
+                OptSetNOP1(tmpi);
+              } else if (Bsf(i)==Bsr(i)) {
+                tmpi->ic_flags|=tmpi2->ic_flags;
+                tmpi->ic_data=Bsf(i);
+                tmpi->ic_code=IC_SHR_CONST;
+                OptSetNOP1(tmpi2);
+              }
+            }
+          }
+          break;
+        case IC_MOD:
+          if ((tmpi2->ic_data || tmpi2->ic_code!=IC_IMM_I64 &&
+                tmpi2->ic_code!=IC_IMM_F64) &&
+                (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned))) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)%tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)%tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)%
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (cc->pass==2 && tmpi2->ic_code==IC_IMM_I64 &&
+                (i=tmpi2->ic_data) && Bsf(i)==Bsr(i) &&
+                tmpi_push->ic_class->raw_type!=RT_F64 &&
+                tmpi_push->ic_class->raw_type&RTF_UNSIGNED) {//do only unsigned
+            tmpi2->ic_data=i-1;
+            tmpi->ic_code=IC_AND;
+          }
+          break;
+        case IC_AND:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data&tmpi2->ic_data;
+            if (i==FBO1_INT)
+              tmpi->ic_code=IC_IMM_I64;
+            else
+              tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_OR:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data|tmpi2->ic_data;
+            if (i==FBO1_INT)
+              tmpi->ic_code=IC_IMM_I64;
+            else
+              tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_XOR:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data^tmpi2->ic_data;
+            if (i==FBO1_INT)
+              tmpi->ic_code=IC_IMM_I64;
+            else
+              tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_ADD:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              tmpi->ic_data=tmpi1->ic_data+tmpi2->ic_data;
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)+
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (tmpi1->ic_code==IC_ABS_ADDR&&tmpi2->ic_code==IC_IMM_I64) {
+              tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+              tmpi->ic_data=tmpi1->ic_data+tmpi2->ic_data;
+              tmpi->ic_code=IC_ABS_ADDR;
+              OptSetNOP1(tmpi1);
+              OptSetNOP1(tmpi2);
+            } else if (cc->pass==2) {
+              if (tmpi1->ic_code==IC_IMM_I64) {
+                if (!tmpi1->ic_data) {
+                  tmpi2->ic_flags|=tmpi1->ic_flags|tmpi->ic_flags;
+                  tmpi2->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi2;
+                  OptSetNOP1(tmpi1);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi2->ic_code==IC_ADD||
+                      tmpi2->ic_code==IC_SUB) {
+                  if (tmpi2->t.arg1_tree->ic_code==IC_IMM_I64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    tmpi2->t.arg1_tree->ic_data+=tmpi1->ic_data;
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi2->t.arg2_tree->ic_code==IC_IMM_I64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    if (tmpi2->ic_code==IC_ADD)
+                      tmpi2->t.arg2_tree->ic_data+=tmpi1->ic_data;
+                    else
+                      tmpi2->t.arg2_tree->ic_data-=tmpi1->ic_data;
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              } else if (tmpi2->ic_code==IC_IMM_I64) {
+                if (!tmpi2->ic_data) {
+                  tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi1->ic_code==IC_ADD ||
+                      tmpi1->ic_code==IC_SUB) {
+                  if (tmpi1->t.arg1_tree->ic_code==IC_IMM_I64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    tmpi1->t.arg1_tree->ic_data+=tmpi2->ic_data;
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_I64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    if (tmpi1->ic_code==IC_ADD)
+                      tmpi1->t.arg2_tree->ic_data+=tmpi2->ic_data;
+                    else
+                      tmpi1->t.arg2_tree->ic_data-=tmpi2->ic_data;
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              } else if (tmpi1->ic_code==IC_IMM_F64) {
+                if (!tmpi1->ic_data) {
+                  tmpi2->ic_flags|=tmpi1->ic_flags|tmpi->ic_flags;
+                  tmpi2->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi2;
+                  OptSetNOP1(tmpi1);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi2->ic_code==IC_ADD||
+                      tmpi2->ic_code==IC_SUB) {
+                  if (tmpi2->t.arg1_tree->ic_code==IC_IMM_F64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    tmpi2->t.arg1_tree->ic_data(F64)+=tmpi1->ic_data(F64);
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi2->t.arg2_tree->ic_code==IC_IMM_F64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    if (tmpi2->ic_code==IC_ADD)
+                      tmpi2->t.arg2_tree->ic_data(F64)+=tmpi1->ic_data(F64);
+                    else
+                      tmpi2->t.arg2_tree->ic_data(F64)-=tmpi1->ic_data(F64);
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              } else if (tmpi2->ic_code==IC_IMM_F64) {
+                if (!tmpi2->ic_data) {
+                  tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi1->ic_code==IC_ADD ||
+                      tmpi1->ic_code==IC_SUB) {
+                  if (tmpi1->t.arg1_tree->ic_code==IC_IMM_F64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    tmpi1->t.arg1_tree->ic_data(F64)+=tmpi2->ic_data(F64);
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_F64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    if (tmpi1->ic_code==IC_ADD)
+                      tmpi1->t.arg2_tree->ic_data(F64)+=tmpi2->ic_data(F64);
+                    else
+                      tmpi1->t.arg2_tree->ic_data(F64)-=tmpi2->ic_data(F64);
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              }
+            }
+          }
+          break;
+        case IC_SUB:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              tmpi->ic_data=tmpi1->ic_data-tmpi2->ic_data;
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)-
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (cc->pass==2) {
+              if (tmpi2->ic_code==IC_IMM_I64) {
+                if (!tmpi2->ic_data) {
+                  tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else
+                  if (tmpi1->ic_code==IC_ADD ||
+                        tmpi1->ic_code==IC_SUB) {
+                    if (tmpi1->t.arg1_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      tmpi1->t.arg1_tree->ic_data-=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      if (tmpi1->ic_code==IC_ADD)
+                        tmpi1->t.arg2_tree->ic_data-=tmpi2->ic_data;
+                      else
+                        tmpi1->t.arg2_tree->ic_data+=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    }
+                  }
+              } else
+                if (tmpi2->ic_code==IC_IMM_F64) {
+                  if (!tmpi2->ic_data) {
+                    tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  } else
+                    if (tmpi1->ic_code==IC_ADD || tmpi1->ic_code==IC_SUB) {
+                      if (tmpi1->t.arg1_tree->ic_code==IC_IMM_F64) {
+                        tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                        tmpi1->t.arg1_tree->ic_data(F64)-=tmpi2->ic_data(F64);
+                        tmpi1->ic_class2=tmpi->ic_class2;
+                        tmpi_push=tmpi1;
+                        OptSetNOP1(tmpi2);
+                        OptSetNOP1(tmpi);
+                      } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_F64) {
+                        tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                        if (tmpi1->ic_code==IC_ADD)
+                          tmpi1->t.arg2_tree->ic_data(F64)-=tmpi2->ic_data(F64);
+                        else
+                          tmpi1->t.arg2_tree->ic_data(F64)+=tmpi2->ic_data(F64);
+                        tmpi1->ic_class2=tmpi->ic_class2;
+                        tmpi_push=tmpi1;
+                        OptSetNOP1(tmpi2);
+                        OptSetNOP1(tmpi);
+                      }
+                    }
+                }
+            }
+          }
+          break;
+        case IC_AND_AND:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data&&tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          break;
+        case IC_OR_OR:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data||tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          break;
+        case IC_XOR_XOR:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data^^tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          break;
+      end:
+        if (!tmpi_push->ic_class->ptr_stars_cnt) {
+          if (tmpi_push->ic_class->raw_type==RT_F64)
+            tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+          else if (is_unsigned)
+            tmpi_push->ic_class2=cmp.internal_types[RT_U64];
+          else
+            tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        }
+        break;
+      start:
+        case IC_EQU_EQU:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data==tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          } else
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          break;
+        case IC_NOT_EQU:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data!=tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          } else
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          break;
+        case IC_LESS:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)<tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+        case IC_GREATER_EQU:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>=tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>=tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)>=tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+        case IC_GREATER:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)>tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+        case IC_LESS_EQU:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<=tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<=tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)<=tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+      end:
+        tmpi->ic_flags&=~ICF_RES_TO_INT;
+        if (!tmpi_push->ic_class->ptr_stars_cnt) {
+          if (tmpi_push->ic_class->raw_type==RT_F64)
+            tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+          else if (is_unsigned)
+            tmpi_push->ic_class2=cmp.internal_types[RT_U64];
+          else
+            tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        }
+        if (tmpi_push->ic_flags & ICF_PUSH_CMP)
+          tmpi->ic_class=tmpi->ic_class2;
+        else
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+        break;
+      start:
+        if (cc->pass==2 && (!tmpc->size||!tmpc2->size))
+          LexWarn(cc,"Assign U0 ");
+        start:
+          case IC_MUL_EQU:
+            if (tmpi2->ic_code==IC_IMM_I64 && tmpc->raw_type!=RT_F64 &&
+                  tmpc2->raw_type!=RT_F64) {
+              if (i=tmpi2->ic_data) {
+                if (Bsf(i)==Bsr(i)) {
+                  tmpi2->ic_data=Bsf(i);
+                  tmpi->ic_code=IC_SHL_EQU;
+                }
+              }
+            }
+            break;
+          case IC_DIV_EQU:
+            if (tmpi2->ic_code==IC_IMM_I64 && tmpc->raw_type!=RT_F64 &&
+                  tmpc2->raw_type!=RT_F64 &&
+                  (i=tmpi2->ic_data) && Bsf(i)==Bsr(i)) {
+              tmpi2->ic_data=Bsf(i);
+              tmpi->ic_code=IC_SHR_EQU;
+            }
+            break;
+          case IC_MOD_EQU:
+            if (tmpi2->ic_code==IC_IMM_I64 && tmpc->raw_type!=RT_F64 &&
+                  tmpc2->raw_type!=RT_F64 &&
+                  (i=tmpi2->ic_data) && Bsf(i)==Bsr(i)) {
+              tmpi2->ic_data=i-1;
+              tmpi->ic_code=IC_AND_EQU;
+            }
+            break;
+          case IC_ADD_EQU:
+          case IC_SUB_EQU:
+            break;
+        end:
+          if (tmpi2->ic_class->raw_type==RT_F64)
+            tmpi->ic_flags=tmpi->ic_flags|ICF_USE_F64;
+          if (tmpc->raw_type==RT_F64) {
+            if (tmpc2->raw_type!=RT_F64)
+              tmpi2->ic_flags|=ICF_RES_TO_F64;
+          }
+          break;
+        case IC_ASSIGN:
+          if (tmpc->raw_type==RT_F64) {
+            if (tmpc2->raw_type!=RT_F64)
+              tmpi2->ic_flags|=ICF_RES_TO_F64;
+          } else {
+            if (tmpc2->raw_type==RT_F64)
+              tmpi2->ic_flags|=ICF_RES_TO_INT;
+          }
+          if (cc->pass==2 && tmpi1->ic_class->raw_type!=RT_F64) {
+            if (tmpi1->ic_code==IC__PP) {
+              tmpi->ic_code=IC_ASSIGN_PP;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              tmpi->t.class2=tmpi1->ic_class;
+              OptSetNOP1(tmpi1);
+            } else if (tmpi1->ic_code==IC__MM) {
+              tmpi->ic_code=IC_ASSIGN_MM;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              tmpi->t.class2=tmpi1->ic_class;
+              OptSetNOP1(tmpi1);
+            }
+          }
+          break;
+        case IC_SHL_EQU:
+        case IC_SHR_EQU:
+        case IC_AND_EQU:
+        case IC_OR_EQU:
+        case IC_XOR_EQU:
+          if (tmpc2->raw_type==RT_F64)
+            tmpi2->ic_flags|=ICF_RES_TO_INT;
+          break;
+      end:
+        break;
+      case IC_ENTER:
+      case IC_LEAVE:
+        tmpi->ic_data=-cc->htc.fun->size;
+        break;
+      case IC_ADD_RSP:
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_ADD_RSP) {
+            tmpi->ic_data+=tmpi1->ic_data;
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            OptSetNOP1(tmpi1);
+          }
+        }
+      case IC_ADD_RSP1:
+        break;
+      case IC_BSF:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi1->ic_data=Bsf(tmpi1->ic_data);
+          tmpi_push=tmpi1;
+          OptSetNOP1(OptLag(tmpi1));    //CALL_START
+          tmpi2=OptLead1(tmpi);
+          tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);            //CALL_END
+          OptSetNOP1(tmpi);             //BSF
+        }
+        break;
+      case IC_BSR:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi1->ic_data=Bsr(tmpi1->ic_data);
+          tmpi_push=tmpi1;
+          OptSetNOP1(OptLag(tmpi1));    //CALL_START
+          tmpi2=OptLead1(tmpi);
+          tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);            //CALL_END
+          OptSetNOP1(tmpi);             //BSR
+        }
+        break;
+      case IC_LBTS:
+      case IC_LBTR:
+      case IC_LBTC:
+        tmpi->ic_flags|=ICF_LOCK;
+        break;
+      case IC_TO_I64:
+        if (tmpi1->ic_code==IC_IMM_F64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_INT|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_data=ToI64(tmpi1->ic_data(F64));
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          tmpi->ic_class2=cmp.internal_types[RT_I64];
+          OptSetNOP1(tmpi1);
+        } else if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_F64|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_data=tmpi1->ic_data;
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          tmpi->ic_class2=cmp.internal_types[RT_I64];
+          OptSetNOP1(tmpi1);
+        }
+        if (tmpi1->ic_flags&ICF_RES_TO_F64) {
+          i=0;
+          tmpi2=tmpi1->last;
+          while (TRUE) {
+            if (tmpi2->ic_code==IC_CALL_START) {
+              if (!i) break;
+              i--;
+            } else if (tmpi2->ic_code==IC_CALL_END)
+              i++;
+            tmpi2=tmpi2->last;
+          }
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi1->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi1->ic_flags=tmpi->ic_flags|tmpi1->ic_flags&
+                ~(ICF_RES_TO_F64|ICF_PUSH_RES)|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi1->ic_class=cmp.internal_types[RT_I64];
+          tmpi1->ic_class2=cmp.internal_types[RT_I64];
+          tmpi_push=tmpi1;
+          OptSetNOP1(tmpi);
+        }
+        break;
+      case IC_TO_F64:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_F64|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_F64;
+          tmpi->ic_data(F64)=ToF64(tmpi1->ic_data);
+          tmpi->ic_class=cmp.internal_types[RT_F64];
+          tmpi->ic_class2=cmp.internal_types[RT_F64];
+          OptSetNOP1(tmpi1);
+        } else if (tmpi1->ic_code==IC_IMM_F64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_INT|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_F64;
+          tmpi->ic_data=tmpi1->ic_data;
+          tmpi->ic_class=cmp.internal_types[RT_F64];
+          tmpi->ic_class2=cmp.internal_types[RT_F64];
+          OptSetNOP1(tmpi1);
+        }
+        if (tmpi1->ic_flags&ICF_RES_TO_INT) {
+          i=0;
+          tmpi2=tmpi1->last;
+          while (TRUE) {
+            if (tmpi2->ic_code==IC_CALL_START) {
+              if (!i) break;
+              i--;
+            } else if (tmpi2->ic_code==IC_CALL_END)
+              i++;
+            tmpi2=tmpi2->last;
+          }
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi1->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi1->ic_flags=tmpi->ic_flags|tmpi1->ic_flags&
+                ~(ICF_RES_TO_INT|ICF_PUSH_RES)|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi1->ic_class=cmp.internal_types[RT_F64];
+          tmpi1->ic_class2=cmp.internal_types[RT_F64];
+          tmpi_push=tmpi1;
+          OptSetNOP1(tmpi);
+        }
+        break;
+      case IC_TO_BOOL:
+        if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_F64|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_data=ToBool(tmpi1->ic_data);
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          tmpi->ic_class2=cmp.internal_types[RT_I64];
+          OptSetNOP1(tmpi1);
+        }
+        break;
+      case IC_BR_ZERO:
+        tmpi_push=OptBrZero(cc,tmpi);
+        break;
+      case IC_BR_NOT_ZERO:
+        tmpi_push=OptBrNotZero(cc,tmpi);
+        break;
+      case IC_NOP1:
+        if (tmpi->ic_flags&ICF_PUSH_RES) {
+          tmpi1=tmpi;
+          do tmpi1=tmpi1->last;
+          while (tmpi1->ic_code==IC_NOP1);
+          tmpi1->ic_flags|=ICF_PUSH_RES;
+          tmpi->ic_flags&=~ICF_PUSH_RES;
+        }
+        break;
+      case IC_NOP2:
+        ps->ptr+=tmpi->ic_data<<1;
+        break;
+      case IC_LABEL:
+        lb=OptLabelFwd(tmpi->ic_data);
+        lb1=tmpi->ic_data;
+        while (lb2=lb1->fwd) {
+          lb1->fwd=lb;
+          lb1=lb2;
+        }
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_JMP) {
+            lb1=tmpi1->ic_data;
+            while (lb1->fwd)
+              lb1=lb1->fwd;
+            if (lb1==lb) {
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            }
+          } else if (tmpi1->ic_code==IC_LABEL) {
+            lb1=tmpi1->ic_data;
+            if (!lb1->fwd)
+              lb1->fwd=lb;
+            if (tmpi1=OptLag(tmpi1)) {
+              if (tmpi1->ic_code==IC_JMP) {
+                lb1=tmpi1->ic_data;
+                while (lb1->fwd)
+                  lb1=lb1->fwd;
+                if (lb1==lb) {
+                  tmpi->ic_flags|=tmpi1->ic_flags;
+                  OptSetNOP1(tmpi1);
+                }
+              }
+            }
+          }
+        }
+        break;
+      case IC_JMP:
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_LABEL) {
+            lb=OptLabelFwd(tmpi->ic_data);
+            lb1=OptLabelFwd(tmpi1->ic_data);
+            if (lb!=lb1)
+              lb1->fwd=lb;
+          }
+        }
+        break;
+      case IC_STR_CONST:
+      case IC_RBP:
+      case IC_MOV_FS:
+      case IC_MOV_GS:
+      case IC_RIP:
+      case IC_SIZEOF:
+      case IC_SQR:
+      case IC_ABS:
+      case IC_SQRT:
+      case IC_SIN:
+      case IC_COS:
+      case IC_TAN:
+      case IC_ATAN:
+      case IC_BR_CARRY:
+      case IC_BR_NOT_CARRY:
+      case IC_BR_EQU_EQU ...IC_BR_LESS_EQU:
+      case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
+      case IC_BR_OR_OR_NOT_ZERO:
+      case IC_BR_OR_OR_ZERO:
+      case IC_BR_AND_AND_NOT_ZERO:
+      case IC_BR_AND_AND_ZERO:
+      case IC_BR_AND_NOT_ZERO:
+      case IC_BR_AND_ZERO:
+      case IC_BR_MM_NOT_ZERO:
+      case IC_BR_MM_ZERO:
+      case IC_BR_BT:
+      case IC_BR_BTS:
+      case IC_BR_BTR:
+      case IC_BR_BTC:
+      case IC_BR_NOT_BT:
+      case IC_BR_NOT_BTS:
+      case IC_BR_NOT_BTR:
+      case IC_BR_NOT_BTC:
+      case IC_END:
+      case IC_ADDR:
+      case IC_RET:
+      case IC_END_EXP:
+      case IC_CALL_START:
+      case IC_CALL_END:
+      case IC_CALL_END2:
+      case IC_PUSH_REGS:
+      case IC_POP_REGS:
+      case IC_SUB_CALL:
+      case IC_CALL:
+      case IC_CALL_INDIRECT:
+      case IC_CALL_INDIRECT2:
+      case IC_CALL_EXTERN:
+      case IC_CALL_IMPORT:
+      case IC_PUSH:
+      case IC_POP:
+      case IC_INVLPG:
+      case IC_CLFLUSH:
+      case IC_GET_RFLAGS:
+      case IC_CARRY:
+      case IC_GET_RBP:
+      case IC_GET_RSP:
+      case IC_GET_RAX:
+      case IC_RETURN_VAL:
+      case IC_RETURN_VAL2:
+      case IC_ABS_ADDR:
+      case IC_HEAP_GLBL:
+      case IC_ADDR_IMPORT:
+      case IC_GET_LABEL:
+      case IC_TYPE:
+      case IC_RDTSC:
+      case IC_SET_RFLAGS:
+      case IC_SET_RBP:
+      case IC_SET_RSP:
+      case IC_SET_RAX:
+      case IC_SIGN_I64:
+      case IC_TOUPPER:
+      case IC_ABS_I64:
+      case IC_MIN_I64:
+      case IC_MAX_I64:
+      case IC_MIN_U64:
+      case IC_MAX_U64:
+      case IC_MOD_U64:
+      case IC_SQR_I64:
+      case IC_SQR_U64:
+      case IC_SWAP_U8:
+      case IC_SWAP_U16:
+      case IC_SWAP_U32:
+      case IC_SWAP_I64:
+      case IC_IN_U32:
+      case IC_IN_U16:
+      case IC_IN_U8:
+      case IC_STRLEN:
+      case IC_BT:
+      case IC_BTS:
+      case IC_BTR:
+      case IC_BTC:
+      case IC_QUE_INIT:
+      case IC_QUE_REM:
+      case IC_QUE_INS:
+      case IC_QUE_INS_REV:
+      case IC_OUT_U32:
+      case IC_OUT_U16:
+      case IC_OUT_U8:
+      case IC_NOBOUND_SWITCH:
+      case IC_SWITCH:
+      case IC_ASM:
+        break;
+      default:
+        "Pass:%d Missing IC hndlr\n",cc->pass;
+        ICPut(cc,tmpi);
+        LexExcept(cc,"Compiler Optimization Error at ");
+    }
+    if (intermediate_code_table[code].arg_cnt==IS_2_ARG) {
+      if (tmpi_push->ic_precedence&~ASSOC_MASK==PREC_ASSIGN)
+        OptFixSizeOf(tmpi2,tmpi_push,tmpi1->ic_class-1);
+      else {
+        OptFixSizeOf(tmpi1,tmpi_push,tmpi2->ic_class);
+        OptFixSizeOf(tmpi2,tmpi_push,tmpi1->ic_class);
+      }
+    }
+    if (intermediate_code_table[tmpi_push->ic_code].res_cnt) {
+      PrsPush(ps,tmpi->ic_class2);
+      PrsPush(ps,tmpi_push);
+    }
+    if (tmpi->ic_class) {
+      if (tmpi->ic_class->raw_type==RT_F64)
+        tmpi->ic_flags&=~ICF_RES_TO_F64;
+      else
+        tmpi->ic_flags&=~ICF_RES_TO_INT;
+      if (code>IC_END_EXP)
+        last_with_class=tmpi;
+    }
+    tmpi=tmpi->next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+//This is for determining type conversions for passing args to funs.
+  return last_with_class;
+}
+
+
+ diff --git a/public/Wb/Compiler/OptPass3.HC.HTML b/public/Wb/Compiler/OptPass3.HC.HTML new file mode 100755 index 0000000..8fedba1 --- /dev/null +++ b/public/Wb/Compiler/OptPass3.HC.HTML @@ -0,0 +1,653 @@ + + + + + + + + + + + +
+U0 OptPass3(CCmpCtrl *cc,COptReg *reg_offsets)
+{
+  CHashClass *tmpc,*tmpc1,*tmpc2;
+  CCodeMisc *lb;
+  CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpi_next,
+        *tmpil1,*tmpil2;
+  I64 code,i,j,l,member_cnt,used_reg_mask=0;
+  CMemberLst *tmpm;
+  COptMemberVar *mv=NULL;
+  CAOT *tmpaot;
+  CAOTImportExport *tmpie;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+
+  for (i=0;i<REG_REGS_NUM;i++) {
+    reg_offsets[i].offset=I64_MAX;
+    reg_offsets[i].m=NULL;
+  }
+  if (cc->htc.fun) {
+    member_cnt=cc->htc.fun->member_cnt;
+    if (Bt(&cc->htc.fun->flags,Ff_DOT_DOT_DOT))
+      member_cnt+=2;
+    mv=CAlloc(member_cnt*sizeof(COptMemberVar));
+    member_cnt=0;
+    tmpm=cc->htc.fun->member_lst_and_root;
+    while (tmpm) {
+      tmpc=OptClassFwd(tmpm->member_class);
+      if (0<=tmpm->reg<REG_REGS_NUM) {
+        if (Bts(&used_reg_mask,tmpm->reg))
+          PrintWarn("Reg in use\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                cc->lex_include_stk->full_name,
+                cc->lex_include_stk->line_num,tmpm->str,cc->htc.fun->str);
+        reg_offsets[tmpm->reg].offset=tmpm->offset;
+        reg_offsets[tmpm->reg].m=tmpm;
+      } else if (tmpc->raw_type!=RT_F64 && tmpm->reg!=REG_NONE ||
+            tmpm->reg==REG_ALLOC) {
+        if (tmpm->reg==REG_ALLOC)
+          mv[member_cnt].score=I64_MAX/2; //big but not too big
+        mv[member_cnt].offset_start=tmpm->offset;
+        mv[member_cnt].offset_end=tmpm->offset+MaxI64(1,tmpm->size);
+        mv[member_cnt++].m=tmpm;
+      } else if (tmpm->reg==REG_ALLOC)
+        PrintWarn("Can't reg var\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+              cc->lex_include_stk->full_name,
+              cc->lex_include_stk->line_num,tmpm->str,cc->htc.fun->str);
+      tmpm=tmpm->next;
+    }
+  } else
+    member_cnt=0;
+
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    tmpi_next=tmpi->next;
+    if (code==IC_NOP1)
+      OptFree(tmpi);
+    else {
+      if (tmpil1=OptLag(tmpi)) {
+        if (!(tmpil2=OptLag(tmpil1)))
+          tmpil2=&cmp.ic_nop;
+      } else
+        tmpil1=tmpil2=&cmp.ic_nop;
+      tmpc=tmpi->ic_class;
+      switch [intermediate_code_table[code].arg_cnt] {
+        case IS_V_ARG:
+          ps->ptr-=tmpi->ic_data>>3;
+          break;
+        case IS_2_ARG:
+          tmpi2=PrsPop(ps);
+          if (tmpi2->ic_flags&ICF_RES_TO_F64)
+            tmpc2=cmp.internal_types[RT_F64];
+          else if (tmpi2->ic_flags & ICF_RES_TO_INT)
+            tmpc2=cmp.internal_types[RT_I64];
+          else
+            tmpc2=tmpi->t.arg2_class;
+          tmpi->arg2.type=MDF_STK+CmpRawType(tmpc2);
+          tmpi->ic_flags|=ICF_ARG2_WAS_STK;
+        case IS_1_ARG:
+          tmpi1=PrsPop(ps);
+          if (tmpi1->ic_flags&ICF_RES_TO_F64)
+            tmpc1=cmp.internal_types[RT_F64];
+          else if (tmpi1->ic_flags & ICF_RES_TO_INT)
+            tmpc1=cmp.internal_types[RT_I64];
+          else
+            tmpc1=tmpi->t.arg1_class;
+          tmpi->arg1.type=MDF_STK+CmpRawType(tmpc1);
+          tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc1);
+          tmpi->ic_flags|=ICF_ARG1_WAS_STK;
+          break;
+        case IS_0_ARG: //nobound switch
+          break;
+      }
+      if (intermediate_code_table[code].res_cnt) {
+        tmpi->res.type=MDF_STK+CmpRawType(tmpc);
+        tmpi->ic_flags|=ICF_RES_WAS_STK;
+        PrsPush(ps,tmpi);
+      }
+      switch [code] {
+        case IC_IMM_F64:
+          tmpi->ic_flags&=~ICF_RES_TO_F64;
+          if (tmpi->ic_flags&ICF_RES_TO_INT) {
+            tmpi->ic_data=ToI64(tmpi->ic_data(F64));
+            tmpi->ic_flags&=~ICF_RES_TO_INT;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          break;
+        case IC_IMM_I64:
+          tmpi->ic_flags&=~ICF_RES_TO_INT;
+          if (tmpi->ic_flags&ICF_RES_TO_F64) {
+            tmpi->ic_data(F64)=ToF64(tmpi->ic_data);
+            tmpi->ic_flags&=~ICF_RES_TO_F64;
+            tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_RBP:
+          tmpi->ic_code=IC_REG;
+          tmpi->arg1.reg=REG_RBP;
+          break;
+        case IC_DEREF:
+          tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+          if (tmpi1->ic_code==IC_LEA) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->arg1.reg=tmpi1->arg1.reg;
+            tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type;
+            tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc);
+            tmpi->ic_code=IC_MOV;
+            OptFree(tmpi1);
+            if (tmpi->arg1.reg==REG_RBP)
+              for (i=0;i<member_cnt;i++)
+                if (mv[i].offset_start==tmpi->arg1.disp) {
+                  mv[i].lea_balance--;
+                  mv[i].score++;
+                  break;
+                }
+          } else if (tmpil1->ic_code==IC_ADD_CONST) {
+            if (tmpil2->ic_code==IC_REG) {
+              tmpi->ic_flags|=tmpil2->ic_flags|tmpil1->ic_flags;
+              tmpi->arg1.reg=tmpil2->arg1.reg;
+              tmpi->arg1.disp=tmpi->ic_data;
+              tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type;
+              tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc);
+              tmpi->ic_code=IC_MOV;
+              OptFree(tmpil2);
+              OptFree(tmpil1);
+            }
+          }
+          break;
+        case IC__PP:
+        case IC__MM:
+        case IC_PP_:
+        case IC_MM_:
+          CmpMinTypePointed(tmpi,CmpRawTypePointed(tmpi->t.arg1_class));
+        case IC_DEREF_PP:
+        case IC_DEREF_MM:
+          if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
+                tmpi1->arg1.reg==REG_RBP)
+            for (i=0;i<member_cnt;i++)
+              if (mv[i].offset_start==tmpi1->arg1.disp) {
+                mv[i].lea_balance--;
+                mv[i].score++;
+                break;
+              }
+          tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+          break;
+        case IC_MUL:
+        case IC_DIV:
+          if (tmpc->raw_type==RT_F64) {
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+            break;
+          }
+          break;
+        case IC_ADD:
+          if (tmpc->raw_type==RT_F64) {
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+            break;
+          }
+          if (OptFixupBinaryOp2(&tmpi1,&tmpi2)) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            if (tmpi->t.arg1_tree!=tmpi2)
+              tmpi->t.arg1_class=tmpi->t.arg2_class;
+            tmpi->ic_data=tmpi1->ic_data;
+            tmpi->ic_code=IC_ADD_CONST;
+            tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+            tmpi->arg2.type=MDF_NULL;
+            OptFree(tmpi1);
+            if (tmpil2->ic_code==IC_REG && tmpil2->arg1.reg==REG_RBP) {
+              tmpi->ic_flags|=tmpil2->ic_flags;
+              tmpi->ic_code=IC_LEA;
+              tmpi->arg1.reg=REG_RBP;
+              tmpi->arg1.type=MDF_DISP+tmpi->arg1.type.raw_type;
+              tmpi->arg1.disp=tmpi->ic_data;
+              for (i=0;i<member_cnt;i++)
+                if (mv[i].offset_start<=tmpi->ic_data<mv[i].offset_end) {
+                  mv[i].lea_balance++;
+                  mv[i].score++;
+                  break;
+                }
+              OptFree(tmpil2);
+            }
+          }
+          break;
+        case IC_SUB:
+          if (tmpc->raw_type==RT_F64) {
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+            break;
+          }
+          if (tmpi2->ic_code==IC_IMM_I64) {
+            tmpi->ic_flags|=tmpi2->ic_flags;
+            tmpi->ic_data=tmpi2->ic_data;
+            tmpi->ic_code=IC_SUB_CONST;
+            tmpi->arg2.type=MDF_NULL;
+            OptFree(tmpi2);
+          }
+          break;
+        case IC_LESS:
+        case IC_GREATER_EQU:
+        case IC_GREATER:
+        case IC_LESS_EQU:
+          if (tmpi->ic_flags&ICF_USE_F64)
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+          break;
+        case IC_MUL_EQU:
+        case IC_DIV_EQU:
+        case IC_ADD_EQU:
+        case IC_SUB_EQU:
+          if (tmpc->raw_type==RT_F64)
+            CmpF1PushPop(tmpi,tmpi2);
+        case IC_ASSIGN_PP:
+        case IC_ASSIGN_MM:
+        case IC_ASSIGN:
+        case IC_SHL_EQU:
+        case IC_SHR_EQU:
+        case IC_MOD_EQU:
+        case IC_AND_EQU:
+        case IC_OR_EQU:
+        case IC_XOR_EQU:
+          if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
+                tmpi1->arg1.reg==REG_RBP)
+            for (i=0;i<member_cnt;i++)
+              if (mv[i].offset_start==tmpi1->arg1.disp) {
+                mv[i].lea_balance--;
+                mv[i].score++;
+                break;
+              }
+          tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+          CmpMinTypePointed(tmpi,CmpRawTypePointed(tmpi->t.arg1_class));
+          break;
+        case IC_RETURN_VAL:
+        case IC_RETURN_VAL2:
+          if (tmpc) {
+            if (tmpc->raw_type==RT_F64 && tmpil1->ic_class->raw_type!=RT_F64)
+              tmpil1->ic_flags|=ICF_RES_TO_F64;
+            else if (tmpc->raw_type!=RT_F64 &&
+                  tmpil1->ic_class->raw_type==RT_F64)
+              tmpil1->ic_flags|=ICF_RES_TO_INT;
+          }
+          break;
+        case IC_SQR:
+        case IC_ABS:
+        case IC_SQRT:
+        case IC_SIN:
+        case IC_COS:
+        case IC_TAN:
+        case IC_ATAN:
+          if (tmpc->raw_type==RT_F64)
+            CmpF1PushPop(tmpi,tmpi1);
+          break;
+        case IC_NOBOUND_SWITCH:
+        case IC_SWITCH:
+          lb=OptLabelFwd(tmpi->ic_data(CCodeMisc *)->dft);
+          lb->use_cnt++;
+          break;
+        case IC_ASM:
+          tmpaot=tmpi->ic_data;
+          tmpie=tmpaot->next_ie;
+          while (tmpie!=&tmpaot->next_ie) {
+            if (IET_REL_I0<=tmpie->type<=IET_IMM_I64 &&
+                  tmpie->str && tmpie->flags&IEF_GOTO_LABEL &&
+                  (lb=COCGoToLabelFind(cc,tmpie->str)))
+              lb->use_cnt++; //Prevent deadcode elimination.
+            tmpie=tmpie->next;
+          }
+          break;
+        case IC_BR_NOT_EQU:
+        case IC_BR_EQU_EQU:
+          if ((tmpi1->ic_code==IC_IMM_I64 ||
+                tmpi1->ic_code==IC_IMM_F64) && !tmpi1->ic_data) {
+            OptFree(tmpi1);
+            MemCpy(&tmpi->arg1,&tmpi->arg2,sizeof(CICArg));
+            tmpi->arg2.type=MDF_NULL;
+            if (code==IC_BR_EQU_EQU)
+              code=tmpi->ic_code=IC_BR_ZERO;
+            else
+              code=tmpi->ic_code=IC_BR_NOT_ZERO;
+            tmpi1=tmpi2;
+            tmpc1=tmpc2;
+          } else if ((tmpi2->ic_code==IC_IMM_I64 ||
+                tmpi2->ic_code==IC_IMM_F64) && !tmpi2->ic_data) {
+            OptFree(tmpi2);
+            tmpi->arg2.type=MDF_NULL;
+            if (code==IC_BR_EQU_EQU)
+              code=tmpi->ic_code=IC_BR_ZERO;
+            else
+              code=tmpi->ic_code=IC_BR_NOT_ZERO;
+          } else
+            goto here1;
+        case IC_BR_ZERO:
+        case IC_BR_NOT_ZERO:
+          if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) {
+            if (code==IC_BR_ZERO ^^ tmpi1->ic_data) {
+              OptFree(tmpi1);
+              tmpi->arg1.type=MDF_NULL;
+              tmpi->ic_code=IC_JMP;
+            } else {
+              OptFree(tmpi1);
+              tmpi=OptFree(tmpi);
+              break;
+            }
+          }
+          goto here1;
+        case IC_BR_AND_ZERO:
+          if (tmpi1->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi1->ic_data);
+            if (0<=i==Bsf(tmpi1->ic_data)) {
+              tmpi1->ic_data=i;
+              tmpi->ic_flags|=ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_NOT_BT;
+              goto here1;
+            }
+          }
+          if (tmpi2->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi2->ic_data);
+            if (0<=i==Bsf(tmpi2->ic_data)) {
+              tmpi2->ic_data=i;
+              tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_NOT_BT;
+            }
+          }
+          goto here1;
+        case IC_BR_AND_NOT_ZERO:
+          if (tmpi1->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi1->ic_data);
+            if (0<=i==Bsf(tmpi1->ic_data)) {
+              tmpi1->ic_data=i;
+              tmpi->ic_flags|=ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_BT;
+              goto here1;
+            }
+          }
+          if (tmpi2->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi2->ic_data);
+            if (0<=i==Bsf(tmpi2->ic_data)) {
+              tmpi2->ic_data=i;
+              tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_BT;
+            }
+          }
+          goto here1;
+        case IC_BR_MM_ZERO:
+        case IC_BR_MM_NOT_ZERO:
+          if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
+                tmpi1->arg1.reg==REG_RBP)
+            for (i=0;i<member_cnt;i++)
+              if (mv[i].offset_start==tmpi1->arg1.disp) {
+                mv[i].lea_balance--;
+                mv[i].score++;
+                break;
+              }
+          tmpi->arg1_type_pointed_to=CmpRawType(tmpc);
+          goto here1;
+        case IC_BR_LESS:
+        case IC_BR_GREATER_EQU:
+        case IC_BR_GREATER:
+        case IC_BR_LESS_EQU:
+          if (tmpi->ic_flags&ICF_USE_F64)
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+        case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
+        case IC_BR_CARRY:
+        case IC_BR_NOT_CARRY:
+        case IC_GET_LABEL:
+        case IC_BR_BT:
+        case IC_BR_BTS:
+        case IC_BR_BTR:
+        case IC_BR_BTC:
+        case IC_BR_NOT_BT:
+        case IC_BR_NOT_BTS:
+        case IC_BR_NOT_BTR:
+        case IC_BR_NOT_BTC:
+        case IC_JMP:
+        case IC_SUB_CALL:
+here1:
+          if (tmpi->ic_flags&ICF_PUSH_CMP)
+            lb=tmpi->ic_data;
+          else
+            lb=OptLabelFwd(tmpi->ic_data);
+          lb->use_cnt++;
+          break;
+        case IC_NOP1:
+          tmpi=OptFree(tmpi);
+          break;
+        case IC_NOP2:
+          ps->ptr+=tmpi->ic_data;
+          break;
+        case IC_SHL_CONST:
+        case IC_SHR_CONST:
+        case IC_ENTER:
+        case IC_ADD_RSP:
+        case IC_ADD_RSP1:
+        case IC_CALL:
+        case IC_CALL_INDIRECT:
+        case IC_CALL_INDIRECT2:
+        case IC_CALL_EXTERN:
+        case IC_CALL_IMPORT:
+        case IC_PUSH:
+        case IC_POP:
+        case IC_INVLPG:
+        case IC_CLFLUSH:
+        case IC_GET_RFLAGS:
+        case IC_CARRY:
+        case IC_RDTSC:
+        case IC_SET_RFLAGS:
+        case IC_GET_RBP:
+        case IC_SET_RBP:
+        case IC_GET_RSP:
+        case IC_GET_RAX:
+        case IC_SET_RSP:
+        case IC_SET_RAX:
+        case IC_ABS_ADDR:
+        case IC_HEAP_GLBL:
+        case IC_ADDR_IMPORT:
+        case IC_TYPE:
+        case IC_BT:
+        case IC_BTS:
+        case IC_BTR:
+        case IC_BTC:
+        case IC_LBTS:
+        case IC_LBTR:
+        case IC_LBTC:
+        case IC_BSF:
+        case IC_BSR:
+        case IC_SIGN_I64:
+        case IC_TOUPPER:
+        case IC_TO_I64:
+        case IC_TO_F64:
+        case IC_TO_BOOL:
+        case IC_ABS_I64:
+        case IC_MIN_I64:
+        case IC_MAX_I64:
+        case IC_MIN_U64:
+        case IC_MAX_U64:
+        case IC_MOD_U64:
+        case IC_SQR_I64:
+        case IC_SQR_U64:
+        case IC_SWAP_U8:
+        case IC_SWAP_U16:
+        case IC_SWAP_U32:
+        case IC_SWAP_I64:
+        case IC_QUE_INIT:
+        case IC_QUE_INS:
+        case IC_QUE_INS_REV:
+        case IC_QUE_REM:
+        case IC_IN_U32:
+        case IC_IN_U16:
+        case IC_IN_U8:
+        case IC_STRLEN:
+        case IC_OUT_U32:
+        case IC_OUT_U16:
+        case IC_OUT_U8:
+        case IC_STR_CONST:
+        case IC_FS:
+        case IC_GS:
+        case IC_MOV_FS:
+        case IC_MOV_GS:
+        case IC_RIP:
+        case IC_PUSH_CMP:
+        case IC_REG:
+        case IC_COM:
+        case IC_HOLYC_TYPECAST:
+        case IC_NOT:
+        case IC_UNARY_MINUS:
+        case IC_POWER:
+        case IC_SHL:
+        case IC_SHR:
+        case IC_MOD:
+        case IC_AND:
+        case IC_OR:
+        case IC_XOR:
+        case IC_EQU_EQU:
+        case IC_NOT_EQU:
+        case IC_AND_AND:
+        case IC_OR_OR:
+        case IC_XOR_XOR:
+        case IC_LEAVE:
+        case IC_RET:
+        case IC_ADDR:
+        case IC_END:
+        case IC_END_EXP:
+        case IC_CALL_END:
+        case IC_CALL_END2:
+        case IC_CALL_START:
+        case IC_PUSH_REGS:
+        case IC_POP_REGS:
+        case IC_LABEL:
+          break;
+        default:
+          "Pass:%d Missing IC hndlr\n",cc->pass;
+          ICPut(cc,tmpi);
+          LexExcept(cc,"Compiler Optimization Error at ");
+      }
+    }
+    tmpi=tmpi_next;
+  }
+/* REGISTER VARIABLE ASSIGNMENT
+
+We just scored num occurrences of each [RBP] offset in the code to help decide
+which variables should be assigned to register variables.
+
+We counted the times each offset was added to RBP as a plus LEA and we subtract
+the times the offset is dereferenced.  If the address was calculated more times
+than the offset was dereferenced, the variable's address was passed or assigned
+and we cannot use a register because you can't take address of a reg var.
+
+RAX,RBX,RCX,RDX, R8 are free to be clobbered by each intermediate code.
+RAX and R8 links intermediate codes together.  R9 is used for stack machine
+temporaries.  RBP is used as stack frame.
+
+RSI,RDI,R10,R11,R12,R13,R14,R15 are used for reg vars.  R12 and R13, however,
+have a unusual ModR addressing mode in the x86_64 architecture, so I only use
+R12 and R13 as non-pointer register variables, such as index variables i,j,k.
+
+*/
+  if (cc->htc.fun) {
+    cc->htc.fun->used_reg_mask=cc->htc.fun->used_reg_mask&
+          ~(REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS)|used_reg_mask;
+    if (!Bt(&cc->opts,OPTf_NO_REG_VAR) &&
+          !(cc->flags & CCF_NO_REG_OPT)) {
+      QSort(mv,member_cnt,sizeof(COptMemberVar),&OptMVCompare);
+      while (member_cnt && !mv[member_cnt-1].score)
+        member_cnt--;
+      j=0;
+      for (i=0;i<member_cnt;i++) {
+        if (!mv[i].lea_balance && mv[i].offset_start) {//addr operator cancels
+          mv[j].m=mv[i].m;
+          mv[j].offset_start=mv[i].offset_start;
+          mv[j++].offset_end=mv[i].offset_end;
+        } else {
+          if (mv[i].m->reg==REG_ALLOC)
+            PrintWarn("Can't reg var\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                  cc->lex_include_stk->full_name,
+                  cc->lex_include_stk->line_num,mv[i].m->str,cc->htc.fun->str);
+        }
+      }
+      if (j>0) {
+        if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
+          "Fun:%s\n",cc->htc.fun->str;
+        if (j>cmp.num_reg_vars) {
+          l=0;
+          for (i=0;i<j && l<cmp.num_non_ptr_vars;i++) {
+            tmpm=mv[i].m;
+            tmpc=OptClassFwd(tmpm->member_class);
+            if (!tmpc->ptr_stars_cnt && !tmpm->dim.next) {
+              while (l<cmp.num_non_ptr_vars &&
+                    Bts(&cc->htc.fun->used_reg_mask,cmp.non_ptr_vars_map[l]))
+                l++;
+              if (l<cmp.num_non_ptr_vars) {
+                tmpm->reg=cmp.non_ptr_vars_map[l++];
+                reg_offsets[tmpm->reg].offset=mv[i].offset_start;
+                reg_offsets[tmpm->reg].m=tmpm;
+                if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
+                  "Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS",
+                        tmpm->str,reg_offsets[tmpm->reg].offset;
+                mv[i].offset_start=0; //flag as reg var
+                if (tmpm->size<8 &&
+                      !StrIMatch("Bool",tmpm->member_class->str) &&
+                      tmpm->member_class->type&HTT_INTERNAL_TYPE)
+                  PrintWarn("Using 64-bit reg var.\n "
+                        "$LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                        cc->lex_include_stk->full_name,
+                        cc->lex_include_stk->line_num,
+                        tmpm->str,cc->htc.fun->str);
+              }
+            }
+          }
+        }
+        l=0;
+        for (i=0;i<j && l<cmp.num_reg_vars;i++) {
+          tmpm=mv[i].m;
+//if not just flagged as reg var
+          if (mv[i].offset_start && (!mv[i].m->dim.next||
+                tmpm->offset>0 && StrCmp(tmpm->str,"argv"))) {
+            while (l<cmp.num_reg_vars &&
+                  Bts(&cc->htc.fun->used_reg_mask,cmp.to_reg_vars_map[l]))
+              l++;
+            if (l<cmp.num_reg_vars) {
+              tmpm->reg=cmp.to_reg_vars_map[l++];
+              reg_offsets[tmpm->reg].offset=mv[i].offset_start;
+              reg_offsets[tmpm->reg].m=tmpm;
+              if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
+                "Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS",
+                      tmpm->str,reg_offsets[tmpm->reg].offset;
+              if (tmpm->size<8 &&
+                    !StrIMatch("Bool",tmpm->member_class->str) &&
+                    tmpm->member_class->type&HTT_INTERNAL_TYPE)
+                PrintWarn("Using 64-bit reg var.\n "
+                      "$LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                      cc->lex_include_stk->full_name,
+                      cc->lex_include_stk->line_num,
+                      tmpm->str,cc->htc.fun->str);
+            }
+          }
+        }
+      }
+    }
+    Free(mv);
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+}
+
+
+ diff --git a/public/Wb/Compiler/OptPass4.HC.HTML b/public/Wb/Compiler/OptPass4.HC.HTML new file mode 100755 index 0000000..de8c4e2 --- /dev/null +++ b/public/Wb/Compiler/OptPass4.HC.HTML @@ -0,0 +1,720 @@ + + + + + + + + + + + +
+Bool OptIC4(CIntermediateCode *tmpi)
+{
+  I64 i;
+  CIntermediateCode *tmpil1,*tmpil2;
+
+  if (tmpi->ic_code<IC_IMM_I64) return FALSE;
+
+  tmpil1=tmpi;
+  if (!(tmpil2=OptLag1(tmpil1)))
+    return FALSE;
+
+  if (tmpil2->res.type&MDF_STK && !(tmpil2->ic_flags&ICF_PUSH_RES)) {
+    if (tmpil1->ic_code==IC_ADD_CONST && tmpil1->arg1.type&MDF_STK) {
+      if ((tmpil2->ic_code==IC_REG || tmpil2->ic_code==IC_MOV) &&
+            tmpil2->arg1.type&MDF_REG) {
+        i=tmpil1->ic_data;
+        if (I32_MIN<=i<=I32_MAX &&
+              !Bt(&cmp.non_ptr_vars_mask,tmpil2->arg1.reg)) {
+          tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+          tmpil1->ic_code=IC_LEA;
+          tmpil1->arg1.type=MDF_DISP+tmpil1->arg1.type.raw_type;
+          tmpil1->arg1.reg=tmpil2->arg1.reg;
+          tmpil1->arg1.disp=i;
+          OptFree(tmpil2);
+          return TRUE;
+        }
+      } else if (tmpil2->ic_code==IC_SHL_CONST && tmpil2->arg1.type&MDF_REG) {
+        i=tmpil1->ic_data;
+        if (I32_MIN<=i<=I32_MAX && tmpil2->arg1.reg!=REG_RSP &&
+              1<=tmpil2->ic_data<=3) {
+          tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+          tmpil1->ic_code=IC_LEA;
+          tmpil1->arg1.type=MDF_SIB+tmpil1->arg1.type.raw_type;
+          tmpil1->arg1.reg=tmpil2->arg1.reg<<8+REG_NONE;
+          if (tmpil2->ic_data==1)
+            tmpil1->arg1.reg|=0x4000;
+          else if (tmpil2->ic_data==2)
+            tmpil1->arg1.reg|=0x8000;
+          else
+            tmpil1->arg1.reg|=0xC000;
+          tmpil1->arg1.disp=i;
+          OptFree(tmpil2);
+          return TRUE;
+        }
+      }
+    }
+    if (tmpil2->ic_code==IC_MOV || tmpil2->ic_code==IC_REG) {
+      if (tmpil1->arg2.type&MDF_STK) {
+        if (tmpil2->ic_flags & ICF_RES_TO_INT) {
+          if (tmpil2->arg1.type&MDF_IMM)
+            tmpil2->arg1.disp=tmpil2->arg1.disp(F64);
+          else
+            tmpil1->ic_flags|=ICF_ARG2_TO_INT;
+        } else if (tmpil2->ic_flags&ICF_RES_TO_F64) {
+          if (tmpil2->arg1.type&MDF_IMM)
+            tmpil2->arg1.disp(F64)=tmpil2->arg1.disp;
+          else
+            tmpil1->ic_flags|=ICF_ARG2_TO_F64;
+        }
+        tmpil1->arg2.type=tmpil2->arg1.type&MDG_MASK+
+              MinI64(tmpil1->arg2.type.raw_type,
+              MinI64(tmpil2->res.type.raw_type,tmpil2->arg1.type.raw_type));
+        tmpil1->arg2.reg=tmpil2->arg1.reg;
+        tmpil1->arg2.disp=tmpil2->arg1.disp;
+        tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+        OptSetNOP2(tmpil2);
+        return TRUE;
+      }
+      if (tmpil1->arg1.type&MDF_STK) {
+        if (tmpil2->ic_flags & ICF_RES_TO_INT) {
+          if (tmpil2->arg1.type&MDF_IMM)
+            tmpil2->arg1.disp=tmpil2->arg1.disp(F64);
+          else
+            tmpil1->ic_flags|=ICF_ARG1_TO_INT;
+        } else if (tmpil2->ic_flags&ICF_RES_TO_F64) {
+          if (tmpil2->arg1.type&MDF_IMM) {
+            if (tmpil2->arg1.type&RTF_UNSIGNED)
+              tmpil2->arg1.disp(F64)=tmpil2->arg1.disp(U64);
+            else
+              tmpil2->arg1.disp(F64)=tmpil2->arg1.disp(I64);
+          } else
+            tmpil1->ic_flags|=ICF_ARG1_TO_F64;
+        }
+        tmpil1->arg1.type=tmpil2->arg1.type&MDG_MASK+
+              MinI64(tmpil1->arg1.type.raw_type,
+              MinI64(tmpil2->res.type.raw_type,tmpil2->arg1.type.raw_type));
+        CmpMinTypePointed(tmpil1,tmpil2->arg1_type_pointed_to);
+        tmpil1->arg1.reg=tmpil2->arg1.reg;
+        tmpil1->arg1.disp=tmpil2->arg1.disp;
+        tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+        OptSetNOP2(tmpil2);
+        return TRUE;
+      }
+    }
+    if (tmpil1->ic_code==IC_DEREF) {
+      if (tmpil2->ic_code==IC_ADD_CONST && tmpil2->arg1.type&MDF_REG &&
+            tmpil1->arg1.type&MDF_STK) {
+        i=tmpil2->ic_data;
+        if (I32_MIN<=i<=I32_MAX &&
+              !Bt(&cmp.non_ptr_vars_mask,tmpil2->arg1.reg)) {
+          tmpil1->ic_flags|=tmpil2->ic_flags;
+          tmpil1->ic_code=IC_MOV;
+          tmpil1->arg1.type=MDF_DISP+tmpil1->arg1_type_pointed_to;
+          tmpil1->arg1.reg=tmpil2->arg1.reg;
+          tmpil1->arg1.disp=i;
+          OptSetNOP2(tmpil2,-1);
+          return TRUE;
+        }
+      }
+      if (tmpil2->ic_code==IC_LEA && tmpil1->arg1.type&MDF_STK) {
+        tmpil1->ic_flags|=tmpil2->ic_flags;
+        tmpil1->ic_code=IC_MOV;
+        tmpil1->arg1.type=tmpil2->arg1.type&MDG_MASK+
+              tmpil1->arg1_type_pointed_to;
+        tmpil1->arg1.reg=tmpil2->arg1.reg;
+        tmpil1->arg1.disp=tmpil2->arg1.disp;
+        OptFree(tmpil2);
+        return TRUE;
+      }
+    }
+  }
+  if (tmpil1->ic_code==IC_DEREF) {
+    if (tmpil1->arg1.type&MDF_REG) {
+      tmpil1->arg1.type=MDF_DISP+tmpil1->arg1_type_pointed_to;
+      tmpil1->arg1.disp=0;
+      tmpil1->ic_code=IC_MOV;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+U0 OptPass4(CCmpCtrl *cc,COptReg *reg_offsets,I64 *_type)
+{
+  CHashClass *tmpc,*tmpc1,*tmpc2;
+  CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpil1,*tmpil2,*tmpil3,
+        *tmpi_next;
+  I64 code,i;
+  Bool dead_code=FALSE;
+  CCodeMisc *lb;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+
+  if (_type)
+    *_type=RT_I64;
+
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    tmpi_next=tmpi->next;
+    if (dead_code&&code!=IC_LABEL) {
+      if (code==IC_JMP||code==IC_SUB_CALL) {
+        lb=OptLabelFwd(tmpi->ic_data);
+        if (lb->use_cnt>0)
+          lb->use_cnt--;
+      }
+      tmpi=OptFree(tmpi);
+    } else {
+      tmpc=tmpi->ic_class;
+      tmpi1=tmpi2=&cmp.ic_nop;
+      if (tmpil1=OptLag2(tmpi)) {
+        if (tmpil2=OptLag2(tmpil1)) {
+          if (!(tmpil3=OptLag2(tmpil2)))
+            tmpil3=&cmp.ic_nop;
+        } else
+          tmpil2=tmpil3=&cmp.ic_nop;
+      } else
+        tmpil1=tmpil2=tmpil3=&cmp.ic_nop;
+      switch [intermediate_code_table[code].arg_cnt] {
+        case IS_V_ARG:
+          ps->ptr-=tmpi->ic_data>>3;
+          break;
+        case IS_2_ARG:
+          tmpi2=PrsPop(ps);
+          tmpc2=tmpi2->ic_class;
+        case IS_1_ARG:
+          tmpi1=PrsPop(ps);
+          tmpc1=tmpi1->ic_class;
+          break;
+        case IS_0_ARG: //nobound switch
+          break;
+      }
+      switch [code] {
+        case IC_IMM_I64:
+        case IC_TYPE:
+          tmpi->arg1.type=MDF_IMM+RT_I64;
+          tmpi->arg1.disp=tmpi->ic_data;
+          tmpi->ic_code=IC_MOV;
+          break;
+        case IC_IMM_F64:
+          tmpi->arg1.type=MDF_IMM+RT_I64;
+          tmpi->arg1.disp=tmpi->ic_data;
+          tmpi->arg1_type_pointed_to=RT_F64;
+          tmpi->ic_code=IC_MOV;
+          break;
+        case IC_MOV:
+          if (tmpi->arg1.type&MDF_DISP && tmpi->arg1.reg==REG_RBP) {
+            i=CmpOffset2Reg(tmpi->arg1.disp,reg_offsets);
+            if (i>=0) {
+              tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+              tmpi->arg1.reg=i;
+              tmpi->arg1.disp=0;
+            }
+          }
+          break;
+        case IC_DEREF:
+          if (tmpi1->ic_code==IC_LEA) {
+            if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
+              i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
+              if (i>=0) {
+                tmpi->ic_flags|=tmpi1->ic_flags;
+                tmpi->ic_code=IC_REG;
+                tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+                tmpi->arg1.reg=i;
+                tmpi->arg1.disp=0;
+                OptFree(tmpi1);
+              }
+            }
+          } else if ((tmpi1->ic_code==IC_ABS_ADDR ||
+                tmpi1->ic_code==IC_MOV &&
+                tmpi1->arg1.type==MDF_IMM+RT_I64 &&
+                0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
+            if (tmpi1->ic_code==IC_ABS_ADDR)
+              tmpi->arg1.disp=tmpi1->ic_data;
+            else
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->ic_code=IC_MOV;
+            tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1_type_pointed_to;
+            tmpi->arg1.reg=REG_RIP;
+            OptFree(tmpi1);
+          }
+          break;
+        case IC_BR_MM_ZERO:
+        case IC_BR_MM_NOT_ZERO:
+//(branch ++ to zero is unlikely)
+        case IC_DEREF_PP:
+        case IC_DEREF_MM:
+        case IC__PP:
+        case IC__MM:
+        case IC_PP_:
+        case IC_MM_:
+          if (tmpi1->ic_code==IC_LEA) {
+            if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
+              i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
+              if (i>=0) {
+                tmpi->ic_flags|=tmpi1->ic_flags;
+                tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+                tmpi->arg1.reg=i;
+                tmpi->arg1.disp=0;
+                tmpi->ic_flags|=ICF_BY_VAL;
+                OptSetNOP2(tmpi1);
+              } else
+                goto p4_lea_gone;
+            } else {
+p4_lea_gone:
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              tmpi->arg1.type=tmpi1->arg1.type;
+              tmpi->arg1.reg=tmpi1->arg1.reg;
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+              tmpi->ic_flags|=ICF_BY_VAL;
+              OptSetNOP2(tmpi1);
+            }
+          } else if ((tmpi1->ic_code==IC_ABS_ADDR || tmpi1->ic_code==IC_MOV &&
+                tmpi1->arg1.type==MDF_IMM+RT_I64 &&
+                0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            if (tmpi1->ic_code==IC_ABS_ADDR)
+              tmpi->arg1.disp=tmpi1->ic_data;
+            else
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1_type_pointed_to;
+            tmpi->arg1.reg=REG_RIP;
+            tmpi->ic_flags|=ICF_BY_VAL;
+            OptFree(tmpi1);
+          }
+          break;
+        case IC_ADD:
+          if (tmpi1->ic_code==IC_MOV && tmpi1->arg1.type==MDF_REG+RT_I64 ||
+                tmpi1->ic_code==IC_REG) {
+            if (tmpi2->ic_code==IC_MOV && tmpi2->arg1.type==MDF_REG+RT_I64 ||
+                  tmpi2->ic_code==IC_REG) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=0;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                goto p4_sib;
+              } else if (tmpi1->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=0;
+                tmpi->arg1.reg=tmpi2->arg1.reg+tmpi1->arg1.reg<<8;
+p4_sib:
+                tmpi->ic_flags|=(tmpi1->ic_flags|tmpi2->ic_flags)
+                &ICG_NO_CVT_MASK;
+                OptSetNOP2(tmpi1);
+                OptFree(tmpi2);
+
+                tmpi->ic_code=IC_LEA;
+                tmpi->arg1.type=MDF_SIB+RT_I64;
+                tmpi->arg1_type_pointed_to=RT_I64;
+
+                tmpi->arg2.type=MDF_NULL+tmpi->arg2.type.raw_type;
+              }
+            } else if (tmpi2->ic_code==IC_SHL_CONST &&
+                  tmpi2->arg1.type==MDF_REG+RT_I64 && tmpi2->ic_data<=3) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=0;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                if (tmpi2->ic_data==1)
+                  tmpi->arg1.reg|=0x4000;
+                else if (tmpi2->ic_data==2)
+                  tmpi->arg1.reg|=0x8000;
+                else
+                  tmpi->arg1.reg|=0xC000;
+                goto p4_sib;
+              }
+            }
+          } else if (tmpi1->ic_code==IC_LEA &&
+                tmpi1->arg1.type&MDF_DISP) {
+            if (tmpi1->arg1.reg==REG_RBP &&
+                  CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets)>=0)
+              break;
+            if (tmpi2->ic_code==IC_MOV && tmpi2->arg1.type==MDF_REG+RT_I64 ||
+                  tmpi2->ic_code==IC_REG) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                goto p4_sib;
+              } else if (tmpi1->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                tmpi->arg1.reg=tmpi2->arg1.reg+tmpi1->arg1.reg<<8;
+                goto p4_sib;
+              }
+            } else if (tmpi2->ic_code==IC_SHL_CONST &&
+                  tmpi2->arg1.type==MDF_REG+RT_I64 && tmpi2->ic_data<=3) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                if (tmpi2->ic_data==1)
+                  tmpi->arg1.reg|=0x4000;
+                else if (tmpi2->ic_data==2)
+                  tmpi->arg1.reg|=0x8000;
+                else
+                  tmpi->arg1.reg|=0xC000;
+                goto p4_sib;
+              }
+            }
+          }
+          break;
+        case IC_ASSIGN_PP:
+        case IC_ASSIGN_MM:
+//this val was stashed during pass012 for pointer arithmetic
+          tmpi->ic_class2=tmpi->t.class2; //See ic_class2
+        case IC_ASSIGN:
+        case IC_SHL_EQU:
+        case IC_SHR_EQU:
+        case IC_MUL_EQU:
+        case IC_DIV_EQU:
+        case IC_MOD_EQU:
+        case IC_AND_EQU:
+        case IC_OR_EQU:
+        case IC_XOR_EQU:
+        case IC_ADD_EQU:
+        case IC_SUB_EQU:
+          if (tmpi1->ic_code==IC_LEA) {
+            if (tmpi1->arg1.type&(MDF_DISP|MDF_SIB)) {
+              tmpi2=tmpi->next;
+              if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
+                i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
+                if (i>=0) {
+                  tmpi->ic_flags|=tmpi1->ic_flags;
+                  tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+                  tmpi->arg1.reg=i;
+                  tmpi->arg1.disp=0;
+                  OptSetNOP2(tmpi1);
+                } else {
+                  tmpi->ic_flags|=tmpi1->ic_flags;
+                  tmpi->arg1.type=MDF_DISP+tmpi->arg1.type.raw_type;
+                  tmpi->arg1.reg=REG_RBP;
+                  tmpi->arg1.disp=tmpi1->arg1.disp;
+                  OptSetNOP2(tmpi1);
+                }
+              } else {
+                tmpi->ic_flags|=tmpi1->ic_flags;
+                tmpi->arg1.type=tmpi1->arg1.type&MDG_MASK+
+                      tmpi->arg1.type.raw_type;
+                tmpi->arg1.reg=tmpi1->arg1.reg;
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                OptSetNOP2(tmpi1);
+              }
+              if (tmpi->res.type&MDF_STK && tmpi2->arg2.type&MDF_STK &&
+                    code!=IC_ASSIGN_PP && code!=IC_ASSIGN_MM) {
+                tmpi->res.type=tmpi->arg1.type;
+                tmpi->res.reg=tmpi->arg1.reg;
+                tmpi->res.disp=tmpi->arg1.disp;
+                tmpi2->arg2.type=tmpi->arg1.type;
+                tmpi2->arg2.reg=tmpi->arg1.reg;
+                tmpi2->arg2.disp=tmpi->arg1.disp;
+                CmpMinTypePointed(tmpi2,tmpi->arg1_type_pointed_to);
+              }
+              tmpi->ic_flags|=ICF_BY_VAL;
+            }
+          } else if ((tmpi1->ic_code==IC_ABS_ADDR ||
+                tmpi1->ic_code==IC_MOV && tmpi1->arg1.type==MDF_IMM+RT_I64 &&
+                0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            if (tmpi1->ic_code==IC_ABS_ADDR)
+              tmpi->arg1.disp=tmpi1->ic_data;
+            else
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1.type.raw_type;
+            tmpi->arg1.reg=REG_RIP;
+            tmpi->ic_flags|=ICF_BY_VAL;
+            OptSetNOP2(tmpi1);
+          }
+          break;
+        case IC_RETURN_VAL:
+        case IC_RETURN_VAL2:
+          if (!tmpi->ic_class) {
+            if (_type) {
+              tmpil1=tmpi;
+              while (tmpil1=OptLag1(tmpil1))
+                if (tmpil1->ic_class) {
+                  if (tmpil1->ic_flags & ICF_RES_TO_F64)
+                    *_type=RT_F64;
+                  else if (tmpil1->ic_flags & ICF_RES_TO_INT)
+                    *_type=RT_I64;
+                  else
+                    *_type=tmpil1->ic_class->raw_type;
+                  break;
+                }
+            }
+            tmpi->ic_class=cmp.internal_types[RT_I64];
+          } else if (_type)
+            *_type=tmpi->ic_class->raw_type;
+          break;
+        case IC_NOP1:
+          tmpi=OptFree(tmpi);
+          break;
+        case IC_BR_BT:
+        case IC_BR_BTS:
+        case IC_BR_BTR:
+        case IC_BR_BTC:
+        case IC_BR_NOT_BT:
+        case IC_BR_NOT_BTS:
+        case IC_BR_NOT_BTR:
+        case IC_BR_NOT_BTC:
+        case IC_BT:
+        case IC_BTS:
+        case IC_BTR:
+        case IC_BTC:
+        case IC_LBTS:
+        case IC_LBTR:
+        case IC_LBTC:
+          if (!(tmpi->ic_flags&ICF_BY_VAL)) {
+            if (tmpi2->ic_code==IC_ADDR) {
+              if (tmpi2->arg1.type&MDF_STK &&
+                    tmpi2->res.type&MDF_STK) {
+                if (tmpil2=OptLag1(tmpi2)) {
+                  if (tmpil2->ic_code==IC_LEA) {
+                    if (tmpil2->arg1.type&(MDF_IMM|MDG_REG_DISP_SIB_RIP)) {
+                      if (tmpi2) {
+                        tmpi->ic_flags|=tmpi2->ic_flags;
+                        OptFree(tmpi2);
+                      }
+                      tmpi->ic_flags|=tmpil2->ic_flags|ICF_BY_VAL;
+                      tmpi->arg2.type=tmpil2->arg1.type;
+                      tmpi->arg2.reg =tmpil2->arg1.reg;
+                      tmpi->arg2.disp=tmpil2->arg1.disp;
+                      OptFree(tmpil2);
+                    }
+                    break;
+                  } else if (tmpil2->ic_code!=IC_ABS_ADDR &&
+                        !(tmpil2->ic_code==IC_MOV &&
+                        tmpil2->arg1.type==MDF_IMM+RT_I64 &&
+                        0<=tmpil2->arg1.disp<=I32_MAX) ||
+                        tmpil2->ic_flags&ICF_NO_RIP)
+                    tmpil2=NULL;
+                  else {
+                    if (tmpil2->ic_code==IC_ABS_ADDR)
+                      tmpi->arg2.disp=tmpil2->ic_data;
+                    else
+                      tmpi->arg2.disp=tmpil2->arg1.disp;
+                  }
+                }
+              } else {
+                if (tmpi2->arg1.type==MDF_IMM+RT_I64 &&
+                      0<=tmpi2->arg1.disp<=I32_MAX &&
+                      !(tmpi2->ic_flags&ICF_NO_RIP)) {
+                  tmpil2=tmpi2;
+                  tmpi2=NULL;
+                  tmpi->arg2.disp=tmpil2->arg1.disp;
+                } else
+                  tmpil2=NULL;
+              }
+              if (tmpil2) {
+                if (tmpi2) {
+                  tmpi->ic_flags|=tmpi2->ic_flags;
+                  OptFree(tmpi2);
+                }
+                tmpi->ic_flags|=tmpil2->ic_flags|ICF_BY_VAL;
+                tmpi->arg2.type=MDF_RIP_DISP32+tmpi->arg2.type.raw_type;
+                tmpi->arg2.reg=REG_RIP;
+                OptFree(tmpil2);
+              }
+            } else if (tmpi2->ic_code==IC_MOV && tmpi2->res.type&MDF_STK &&
+                  tmpi2->arg1.type==MDF_IMM+RT_I64 &&
+                  0<=tmpi2->arg1.disp<=I32_MAX &&
+                  !(tmpi2->ic_flags&ICF_NO_RIP)) {
+              tmpi->arg2.disp=tmpi2->arg1.disp;
+              tmpi->ic_flags|=tmpi2->ic_flags|ICF_BY_VAL;
+              tmpi->arg2.type=MDF_RIP_DISP32+tmpi->arg2.type.raw_type;
+              tmpi->arg2.reg=REG_RIP;
+              OptFree(tmpi2);
+            }
+          }
+          break;
+        case IC_BR_EQU_EQU ...IC_BR_LESS_EQU:
+        case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
+        case IC_BR_CARRY:
+        case IC_BR_NOT_CARRY:
+        case IC_BR_ZERO:
+        case IC_BR_NOT_ZERO:
+          lb=tmpi->ic_data;
+          if (tmpi->ic_flags&ICF_PUSH_CMP) {
+            lb->flags|=CMF_POP_CMP;
+            lb->fwd=NULL;
+          }
+          break;
+        case IC_LABEL:
+          lb=tmpi->ic_data;
+          if (lb->use_cnt)
+            dead_code=FALSE;
+          break;
+        case IC_JMP:
+        case IC_RET:
+          dead_code=TRUE;
+          break;
+        case IC_NOP2:
+          ps->ptr+=tmpi->ic_data;
+          break;
+        case IC_CALL_END:
+        case IC_END_EXP:
+          if (!(tmpil1->ic_flags&ICF_PUSH_RES)) {
+            if (tmpi->ic_flags&ICF_RES_NOT_USED) {
+              tmpil1->ic_flags|=ICF_RES_NOT_USED;
+              tmpil1->res.type=MDF_NULL+tmpil1->res.type.raw_type;
+            } else if (tmpi->arg1.type&MDF_STK &&
+                  tmpil1->res.type&MDF_STK) {
+              tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+              tmpi->arg1.disp=0;
+              tmpil1->res.type=MDF_REG+tmpil1->res.type.raw_type;
+              tmpil1->res.disp=0;
+              if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG) {
+                tmpi->arg1.reg=REG_R8;
+                tmpil1->res.reg=REG_R8;
+              } else {
+                tmpi->arg1.reg=REG_RAX;
+                tmpil1->res.reg=REG_RAX;
+              }
+            }
+          }
+          break;
+        case IC_STR_CONST:
+        case IC_FS:
+        case IC_GS:
+        case IC_MOV_FS:
+        case IC_MOV_GS:
+        case IC_RIP:
+        case IC_RBP:
+        case IC_REG:
+        case IC_COM:
+        case IC_HOLYC_TYPECAST:
+        case IC_NOT:
+        case IC_UNARY_MINUS:
+        case IC_PUSH_CMP:
+        case IC_ADD_CONST:
+        case IC_SUB_CONST:
+        case IC_ENTER:
+        case IC_ADD_RSP:
+        case IC_ADD_RSP1:
+        case IC_CALL:
+        case IC_CALL_INDIRECT:
+        case IC_CALL_INDIRECT2:
+        case IC_CALL_EXTERN:
+        case IC_CALL_IMPORT:
+        case IC_PUSH:
+        case IC_POP:
+        case IC_INVLPG:
+        case IC_CLFLUSH:
+        case IC_GET_RFLAGS:
+        case IC_CARRY:
+        case IC_RDTSC:
+        case IC_SET_RFLAGS:
+        case IC_GET_RBP:
+        case IC_SET_RBP:
+        case IC_GET_RSP:
+        case IC_GET_RAX:
+        case IC_SET_RSP:
+        case IC_SET_RAX:
+        case IC_SHL_CONST:
+        case IC_LEA:
+        case IC_SHR_CONST:
+        case IC_POWER:
+        case IC_SHL:
+        case IC_SHR:
+        case IC_MUL:
+        case IC_DIV:
+        case IC_MOD:
+        case IC_AND:
+        case IC_OR:
+        case IC_XOR:
+        case IC_SUB:
+        case IC_EQU_EQU...IC_LESS_EQU:
+        case IC_AND_AND:
+        case IC_OR_OR:
+        case IC_XOR_XOR:
+        case IC_GET_LABEL:
+        case IC_ABS_ADDR:
+        case IC_HEAP_GLBL:
+        case IC_ADDR_IMPORT:
+        case IC_BSF:
+        case IC_BSR:
+        case IC_SIGN_I64:
+        case IC_TOUPPER:
+        case IC_TO_I64:
+        case IC_TO_F64:
+        case IC_TO_BOOL:
+        case IC_SQR:
+        case IC_ABS:
+        case IC_SQRT:
+        case IC_SIN:
+        case IC_COS:
+        case IC_TAN:
+        case IC_ATAN:
+        case IC_ABS_I64:
+        case IC_MIN_I64:
+        case IC_MAX_I64:
+        case IC_MIN_U64:
+        case IC_MAX_U64:
+        case IC_MOD_U64:
+        case IC_SQR_I64:
+        case IC_SQR_U64:
+        case IC_SWAP_U8:
+        case IC_SWAP_U16:
+        case IC_SWAP_U32:
+        case IC_SWAP_I64:
+        case IC_QUE_INIT:
+        case IC_QUE_INS:
+        case IC_QUE_INS_REV:
+        case IC_QUE_REM:
+        case IC_IN_U32:
+        case IC_IN_U16:
+        case IC_IN_U8:
+        case IC_STRLEN:
+        case IC_OUT_U32:
+        case IC_OUT_U16:
+        case IC_OUT_U8:
+        case IC_NOBOUND_SWITCH:
+        case IC_SWITCH:
+        case IC_END:
+        case IC_ADDR:
+        case IC_CALL_START:
+        case IC_LEAVE:
+        case IC_PUSH_REGS:
+        case IC_POP_REGS:
+        case IC_ASM:
+        case IC_BR_AND_NOT_ZERO:
+        case IC_BR_AND_ZERO:
+        case IC_SUB_CALL:
+        case IC_CALL_END2:
+          break;
+        default:
+          "Pass:%d Missing IC hndlr\n",cc->pass;
+          ICPut(cc,tmpi);
+          LexExcept(cc,"Compiler Optimization Error at ");
+      }
+      if (tmpi) {
+        while (OptIC4(tmpi));
+        code=tmpi->ic_code;
+        if (intermediate_code_table[code].res_cnt)
+          PrsPush(ps,tmpi);
+      }
+    }
+    tmpi=tmpi_next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+}
+
+ diff --git a/public/Wb/Compiler/OptPass5.HC.HTML b/public/Wb/Compiler/OptPass5.HC.HTML new file mode 100755 index 0000000..b5e794c --- /dev/null +++ b/public/Wb/Compiler/OptPass5.HC.HTML @@ -0,0 +1,121 @@ + + + + + + + + + + + +
+U0 OptPass5(CCmpCtrl *cc)
+{
+  CIntermediateCode *tmpi,*tmpi1;
+  I64 code,i;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    if (code>IC_NOP2) {
+      if (tmpi->ic_flags&ICF_PASS_TRACE) {
+        if (Bt(&cc->saved_pass_trace,5)) {
+          "%2d:",ps->ptr;
+          ICPut(cc,tmpi);
+        }
+      }
+      if (intermediate_code_table[code].arg_cnt==IS_V_ARG)
+        ps->ptr-=tmpi->ic_data>>3;
+      if (code==IC_PUSH_REGS) {
+        for (i=0;i<REG_REGS_NUM;i++)
+          if (Bt(&tmpi->ic_data,i))
+            ps->ptr++;
+      } else if (code==IC_POP_REGS) {
+        for (i=0;i<REG_REGS_NUM;i++)
+          if (Bt(&tmpi->ic_data,i))
+            ps->ptr--;
+      }
+      if (tmpi->arg2.type&MDF_STK) {
+        tmpi1=PrsPop(ps);
+        if (tmpi1->ic_code==IC_MOV || tmpi1->ic_code==IC_REG) {
+          if (tmpi1->ic_flags & ICF_RES_TO_INT) {
+            if (tmpi1->arg1.type&MDF_IMM)
+              tmpi1->arg1.disp=tmpi1->arg1.disp(F64);
+            else
+              tmpi->ic_flags|=ICF_ARG2_TO_INT;
+          } else if (tmpi1->ic_flags&ICF_RES_TO_F64) {
+            if (tmpi1->arg1.type&MDF_IMM)
+              tmpi1->arg1.disp(F64)=tmpi1->arg1.disp;
+            else
+              tmpi->ic_flags|=ICF_ARG2_TO_F64;
+          }
+          tmpi->arg2.type=tmpi1->arg1.type&MDG_MASK+
+                MinI64(tmpi->arg2.type.raw_type,
+                MinI64(tmpi1->res.type.raw_type,tmpi1->arg1.type.raw_type));
+          tmpi->arg2.reg=tmpi1->arg1.reg;
+          tmpi->arg2.disp=tmpi1->arg1.disp;
+          tmpi->ic_flags|=tmpi1->ic_flags&ICG_NO_CVT_MASK;
+          OptSetNOP2(tmpi1);
+        }
+      }
+
+      if (tmpi->arg1.type&MDF_STK) {
+        tmpi1=PrsPop(ps);
+        if (tmpi1->ic_code==IC_MOV || tmpi1->ic_code==IC_REG) {
+          if (tmpi1->ic_flags & ICF_RES_TO_INT) {
+            if (tmpi1->arg1.type&MDF_IMM)
+              tmpi1->arg1.disp=tmpi1->arg1.disp(F64);
+            else
+              tmpi->ic_flags|=ICF_ARG1_TO_INT;
+          } else if (tmpi1->ic_flags&ICF_RES_TO_F64) {
+            if (tmpi1->arg1.type&MDF_IMM) {
+              if (tmpi1->arg1.type&RTF_UNSIGNED)
+                tmpi1->arg1.disp(F64)=tmpi1->arg1.disp(U64);
+              else
+                tmpi1->arg1.disp(F64)=tmpi1->arg1.disp(I64);
+            } else
+              tmpi->ic_flags|=ICF_ARG1_TO_F64;
+          }
+          tmpi->arg1.type=tmpi1->arg1.type&MDG_MASK+
+                MinI64(tmpi->arg1.type.raw_type,
+                MinI64(tmpi1->res.type.raw_type,tmpi1->arg1.type.raw_type));
+          CmpMinTypePointed(tmpi,tmpi1->arg1_type_pointed_to);
+          tmpi->arg1.reg=tmpi1->arg1.reg;
+          tmpi->arg1.disp=tmpi1->arg1.disp;
+          tmpi->ic_flags|=tmpi1->ic_flags&ICG_NO_CVT_MASK;
+          OptSetNOP2(tmpi1);
+        }
+      }
+      if (tmpi->res.type&MDF_STK &&
+            !(tmpi->ic_flags&ICF_RES_NOT_USED))
+        PrsPush(ps,tmpi);
+    }
+    tmpi=tmpi->next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+}
+
+ diff --git a/public/Wb/Compiler/OptPass6.HC.HTML b/public/Wb/Compiler/OptPass6.HC.HTML new file mode 100755 index 0000000..43a0e1b --- /dev/null +++ b/public/Wb/Compiler/OptPass6.HC.HTML @@ -0,0 +1,216 @@ + + + + + + + + + + + +
+Bool OptIC6(CIntermediateCode *tmpi)
+{
+  CIntermediateCode *tmpil1;
+  if (tmpi->ic_code<IC_IMM_I64 || !(tmpil1=OptLag1(tmpi)))
+    return FALSE;
+  if (tmpil1->ic_code==IC_ADD_CONST && tmpi->ic_code==IC_DEREF &&
+        tmpi->ic_flags&ICF_ARG1_WAS_STK &&  tmpi->arg1.type&MDF_REG &&
+        tmpil1->res.type&MDF_REG && I32_MIN<=tmpil1->ic_data<=I32_MAX &&
+        !Bt(&cmp.non_ptr_vars_mask,tmpil1->arg1.reg)) {
+    if (tmpil1->arg1.type&MDF_REG) {
+      tmpi->ic_flags=tmpi->ic_flags&~ICF_ARG1_WAS_STK | tmpil1->ic_flags;
+      tmpi->ic_code=IC_MOV;
+      tmpi->arg1.type=MDF_DISP+tmpi->arg1_type_pointed_to;
+      tmpi->arg1.reg=tmpil1->arg1.reg;
+      tmpi->arg1.disp=tmpil1->ic_data;
+      OptSetNOP2(tmpil1,-1);
+    } else {
+      tmpil1->ic_code=IC_MOV;
+      tmpi->ic_code=IC_MOV;
+      tmpi->arg1.type=MDF_DISP+tmpi->arg1_type_pointed_to;
+      tmpi->arg1.disp=tmpil1->ic_data;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+U0 OptPass6Lag(CCmpCtrl *cc,CPrsStk *ps,CIntermediateCode *tmpi,
+        I64 *_stk_ptr,I64 reg_stk_size,I64 *_clobbered_reg_mask)
+{
+  I64 stk_ptr=*_stk_ptr,code,
+        clobbered_stk_tmp_mask,clobbered_reg_mask=*_clobbered_reg_mask;
+  CHashFun *tmpf;
+  code=tmpi->ic_code;
+  if (tmpi->ic_flags&ICF_PASS_TRACE && Bt(&cc->saved_pass_trace,6)) {
+    "%2d:",stk_ptr;
+    ICPut(cc,tmpi);
+  }
+  if (code==IC_CALL_START) {
+    if (reg_stk_size==1 && stk_ptr>0)
+      clobbered_stk_tmp_mask=REGG_STK_TMP;
+    else
+      clobbered_stk_tmp_mask=0;
+    if (tmpf=tmpi->ic_data) {
+      if (Bt(&tmpf->flags,Ff_INTERNAL))
+        clobbered_stk_tmp_mask=0;
+      else {
+        clobbered_stk_tmp_mask&=tmpf->clobbered_reg_mask;
+        clobbered_reg_mask|=tmpf->clobbered_reg_mask;
+      }
+    }
+    tmpi->ic_data=clobbered_stk_tmp_mask;
+    PrsPush(ps,stk_ptr);
+    PrsPush(ps,clobbered_stk_tmp_mask);
+  } else if (code==IC_CALL_END) {
+    tmpi->ic_data=PrsPop(ps);
+    stk_ptr=PrsPop(ps);
+  } else if (code==IC_CALL_END2) {
+    ps->ptr--;
+    stk_ptr=PrsPop(ps);
+  }
+  if (intermediate_code_table[code].arg_cnt==IS_V_ARG)
+    stk_ptr-=tmpi->ic_data>>3;
+  if (tmpi->arg2.type&MDF_STK) {
+    stk_ptr--;
+    if (stk_ptr<reg_stk_size) {
+      tmpi->arg2.type=MDF_REG+tmpi->arg2.type.raw_type;
+      tmpi->arg2.reg=Bsf(REGG_STK_TMP);
+      tmpi->arg2.disp=0;
+    }
+  }
+  if (tmpi->arg1.type&MDF_STK) {
+    stk_ptr--;
+    if (stk_ptr<reg_stk_size) {
+      tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+      tmpi->arg1.reg=Bsf(REGG_STK_TMP);
+      tmpi->arg1.disp=0;
+    }
+  }
+  if (tmpi->res.type&MDF_STK && !(tmpi->ic_flags & ICF_PUSH_RES)) {
+    stk_ptr++;
+    if (stk_ptr<=reg_stk_size) {
+      tmpi->res.type=MDF_REG+tmpi->res.type.raw_type;
+      tmpi->res.reg=Bsf(REGG_STK_TMP);
+      clobbered_reg_mask|=REGG_STK_TMP;
+      tmpi->res.disp=0;
+    }
+  }
+  while (OptIC6(tmpi));
+  if (tmpi->res.type.raw_type!=RT_F64 && !(tmpi->ic_flags&ICF_USE_F64))
+    tmpi->ic_flags|=ICF_USE_INT;
+  *_stk_ptr=stk_ptr;
+  *_clobbered_reg_mask=clobbered_reg_mask;
+}
+
+U0 OptPass6(CCmpCtrl *cc)
+{
+  CIntermediateCode *tmpi,*tmpi_next,*tmpil1,*tmpil2,*old_tmpil2;
+  I64 stk_ptr=0,reg_stk_size,clobbered_reg_mask=REGG_CLOBBERED;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+  if (Bt(&cc->opts,OPTf_NO_REG_VAR) || cc->flags&CCF_NO_REG_OPT)
+    reg_stk_size=0;
+  else
+    reg_stk_size=1;
+#assert REGG_STK_TMP==1<<9
+  tmpi=cc->coc.coc_head.next;
+  old_tmpil2=NULL;
+  tmpil1=tmpil2=&cmp.ic_nop;
+  while (tmpi->ic_code) {
+    if (tmpi->ic_code>IC_NOP2) {
+      if (tmpil1->ic_code>IC_NOP2)
+        tmpil2=tmpil1;
+      tmpil1=tmpi;
+      if (tmpi->arg2.type&MDF_STK) {
+        if (tmpil2->res.type&MDF_STK &&
+              !(tmpil2->ic_flags&ICF_PUSH_RES)) {
+          if (tmpi->ic_code==IC_ASSIGN && tmpi->ic_flags&ICF_BY_VAL &&
+                tmpi->ic_flags&ICF_RES_NOT_USED &&
+                tmpil2->ic_code!=IC_CALL_END &&
+                tmpil2->ic_code!=IC_CALL_END2 &&
+                tmpil2->ic_code!=IC_SET_RAX &&
+                !(tmpi->ic_flags&(ICF_ARG2_TO_F64|ICF_ARG2_TO_INT)) &&
+                !(tmpil2->ic_flags&(ICF_RES_TO_F64|ICF_RES_TO_INT))) {
+            tmpil2->res.type =tmpi->arg1.type&MDG_MASK+
+                  tmpi->arg1_type_pointed_to;
+            tmpil2->res.reg  =tmpi->arg1.reg;
+            tmpil2->res.disp =tmpi->arg1.disp;
+            tmpil2->ic_flags=tmpil2->ic_flags
+                  &~(ICF_RES_NOT_USED|ICF_RES_WAS_STK)
+            |tmpi->ic_flags&~(ICF_BY_VAL|ICF_ARG1_WAS_STK|ICF_ARG2_WAS_STK);
+            old_tmpil2=NULL;
+            OptSetNOP1(tmpi);
+          } else {
+            tmpi->arg2.type=MDF_REG+tmpi->arg2.type.raw_type;
+            tmpi->arg2.reg=REG_RAX;
+            tmpi->arg2.disp=0;
+            tmpil2->res.type=MDF_REG+tmpil2->res.type.raw_type;
+            tmpil2->res.reg=REG_RAX;
+            tmpil2->res.disp=0;
+          }
+        }
+      } else if (tmpi->arg1.type&MDF_STK && tmpil2->res.type&MDF_STK &&
+            !(tmpil2->ic_flags&ICF_PUSH_RES)) {
+        tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+        tmpi->arg1.disp=0;
+        tmpil2->res.type=MDF_REG+tmpil2->res.type.raw_type;
+        tmpil2->res.disp=0;
+        if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG) {
+          tmpi->arg1.reg=REG_R8;
+          tmpil2->res.reg=REG_R8;
+        } else {
+          tmpi->arg1.reg=REG_RAX;
+          tmpil2->res.reg=REG_RAX;
+        }
+      }
+      if (tmpi->ic_flags & ICF_PUSH_RES)
+        tmpi->res.type==MDF_STK+tmpi->res.type.raw_type;
+      if (old_tmpil2!=tmpil2) {
+        if (tmpil2->ic_code>IC_NOP2)
+          OptPass6Lag(cc,ps,tmpil2,&stk_ptr,reg_stk_size,&clobbered_reg_mask);
+        old_tmpil2=tmpil2;
+      }
+    }
+    tmpi_next=tmpi->next;
+    if (tmpi->ic_code<=IC_NOP2)
+      OptFree(tmpi);
+    tmpi=tmpi_next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+  if (cc->htc.fun) {
+    cc->htc.fun->used_reg_mask&=~REGG_STK_TMP;
+    cc->htc.fun->used_reg_mask|=clobbered_reg_mask;
+    cc->htc.fun->clobbered_reg_mask=clobbered_reg_mask;
+    if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT) &&
+          Bt(&cc->saved_pass_trace,6)) {
+      "Used      Reg Mask:%04X\n",cc->htc.fun->used_reg_mask;
+      "Clobbered Reg Mask:%04X\n",clobbered_reg_mask;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Compiler/OptPass789A.HC.HTML b/public/Wb/Compiler/OptPass789A.HC.HTML new file mode 100755 index 0000000..cddf502 --- /dev/null +++ b/public/Wb/Compiler/OptPass789A.HC.HTML @@ -0,0 +1,1183 @@ + + + + + + + + + + + +
+I64 OptPass789A(CCmpCtrl *cc,COptReg *reg_offsets,U8 *buf,CDbgInfo **_dbg)
+{/*cc->pass==7 is first time
+cc->pass==8 is second time
+cc->pass==9 is third time
+cc->pass==9 is fourth time and repeated until size stops shrinking
+size is now known
+cc->pass==10 is final pass, code is placed into buf.
+*/
+  CIntermediateCode *tmpi,*tmpi_next;
+  I64 i,cnt,num_lines=cc->max_line+1-cc->min_line,rip=0,rip2;
+  U8  *ptr,saved_arg1_arg2_r[3*sizeof(CICArg)];
+  CCodeMisc *lb;
+  CAOT *tmpaot;
+  CAOTAbsAddr *tmpa;
+  CAOTImportExport *tmpie;
+  CAOTHeapGlbl *tmphg;
+  CAOTHeapGlblRef *tmphgr;
+  CDbgInfo *dbg_info;
+  CAOTCtrl *aotc=cc->aotc;
+  Bool short_jmp;
+  CHashClass *tmpc;
+  CHashFun *tmpf;
+  CHashGlblVar *tmpg;
+  CExternUsage *tmpeu;
+
+  if (_dbg) {
+    *_dbg=dbg_info=CAlloc(offset(CDbgInfo.body)+sizeof(U32)*(num_lines+1));
+    dbg_info->min_line=cc->min_line;
+    dbg_info->max_line=cc->max_line;
+    if (cc->flags&CCF_AOT_COMPILE)
+      dbg_info->body[0]=aotc->rip;
+    else
+      dbg_info->body[0]=buf;
+  } else
+    dbg_info=NULL;
+
+  if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT) &&
+        Bt(&cc->saved_pass_trace,cc->pass))
+    "$BK,1$$LTRED$$IV,1$This code gets merged together and patched.\n"
+          "$FG$$IV,0$$BK,0$";
+
+  cc->last_float_op_ic=NULL;
+  tmpi=&cc->coc.coc_head;
+  tmpi->ic_last_start=-1;
+  tmpi->ic_cnt=0;
+  tmpi=tmpi->next;
+  while (tmpi->ic_code) {
+    tmpi_next=tmpi->next;
+    if (tmpi->ic_flags&ICF_PASS_TRACE && Bt(&cc->saved_pass_trace,cc->pass))
+      ICPut(cc,tmpi);
+    rip2=rip;
+    if (cc->flags&CCF_AOT_COMPILE)
+      rip2+=aotc->rip;
+    else
+      rip2+=buf;
+    cc->cur_ic_float_op_num=0;
+    if (!(tmpi->ic_flags &ICF_CODE_FINAL)) {
+      tmpi->ic_flags=tmpi->ic_flags&
+            ~(ICF_PREV_DELETED|ICF_DONT_RESTORE)|ICF_CODE_FINAL;
+      if (cc->pass==7)
+        cc->dont_push_float=Btr(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+      MemCpy(saved_arg1_arg2_r,&tmpi->arg1,3*sizeof(CICArg));
+      tmpi->ic_cnt=0;
+      tmpi->ic_last_start=-1;
+      if (tmpi->arg2.type.mode) {
+        if (tmpi->ic_flags & ICF_ARG2_TO_F64) {
+          ICFCvt(cc,tmpi,REG_RAX,tmpi->arg2.type,
+                tmpi->arg2.reg,tmpi->arg2.disp,FALSE,CN_A2,rip2);
+          tmpi->arg2.type=MDF_REG+RT_I64;
+          tmpi->arg2.reg=REG_RAX;
+          tmpi->arg2.disp=0;
+        } else if (tmpi->ic_flags & ICF_ARG2_TO_INT) {
+          ICFCvt(cc,tmpi,REG_RAX,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,TRUE,CN_A2,rip2);
+          tmpi->arg2.type=MDF_REG+RT_I64;
+          tmpi->arg2.reg=REG_RAX;
+          tmpi->arg2.disp=0;
+        }
+      }
+      if (tmpi->arg1.type.mode) {
+        if (tmpi->ic_flags & ICF_ARG1_TO_F64) {
+          ICFCvt(cc,tmpi,REG_RDX,tmpi->arg1.type,
+                tmpi->arg1.reg,tmpi->arg1.disp,FALSE,CN_A1,rip2);
+          tmpi->arg1.type=MDF_REG+RT_I64;
+          tmpi->arg1.reg=REG_RDX;
+          tmpi->arg1.disp=0;
+        } else if (tmpi->ic_flags & ICF_ARG1_TO_INT) {
+          ICFCvt(cc,tmpi,REG_RDX,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,TRUE,CN_A1,rip2);
+          tmpi->arg1.type=MDF_REG+RT_I64;
+          tmpi->arg1.reg=REG_RDX;
+          tmpi->arg1.disp=0;
+        }
+      }
+
+      switch [tmpi->ic_code] {
+        start:
+          start:
+            case IC_ABS_ADDR:
+              ICU16(tmpi,0xB848);
+              ICU64(tmpi,tmpi->ic_data);
+              if (buf && cc->flags&CCF_AOT_COMPILE &&
+                    !(cc->flags&(CCF_NO_ABSS|CCF_ASM_EXPRESSIONS))) {
+                tmpa=CAlloc(sizeof(CAOTAbsAddr));
+                tmpa->next=aotc->abss;
+                tmpa->type=AAT_ADD_U64;
+                aotc->abss=tmpa;
+                tmpa->rip=rip2+tmpi->ic_cnt-8;
+              }
+              break;
+            case IC_HEAP_GLBL:
+              ICU16(tmpi,0xB848);
+              ICU64(tmpi,0);
+              tmphg=tmpi->ic_data;
+              if (buf && cc->flags&CCF_AOT_COMPILE &&
+//TODO:is this necessary--flags?
+                    !(cc->flags&(CCF_NO_ABSS|CCF_ASM_EXPRESSIONS))) {
+                tmphgr=CAlloc(sizeof(CAOTHeapGlblRef));
+                tmphgr->next=tmphg->references;
+                tmphg->references=tmphgr;
+                tmphgr->rip=rip2+tmpi->ic_cnt-8;
+              }
+              break;
+            case IC_ADDR_IMPORT:
+              ICU8(tmpi,0xB8);
+              ICU32(tmpi,0);
+              if (buf && !(cc->flags&CCF_NO_ABSS)) {
+                tmpg=tmpi->ic_data;
+                tmpie=CAlloc(sizeof(CAOTImportExport));
+                tmpie->type=IET_IMM_U32;
+                tmpie->rip=rip2+tmpi->ic_cnt-4;
+                tmpie->next=tmpg->ie_lst;
+                tmpg->ie_lst=tmpie;
+              }
+              ICU24(tmpi,0xC06348);
+              break;
+            case IC_RIP:
+              ICU16(tmpi,0xB848);
+              ICU64(tmpi,rip2+tmpi->ic_cnt-2);
+              if (cc->flags&CCF_AOT_COMPILE && buf &&!(cc->flags&CCF_NO_ABSS)) {
+                tmpa=CAlloc(sizeof(CAOTAbsAddr));
+                tmpa->next=aotc->abss;
+                tmpa->type=AAT_ADD_U64;
+                aotc->abss=tmpa;
+                tmpa->rip=rip2+tmpi->ic_cnt-8;
+              }
+              break;
+          end:
+            ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  MDF_REG+RT_I64,REG_RAX,0,rip2);
+            break;
+          case IC_BR_CARRY:
+            ICFlagBranch(tmpi,rip,0x72820F,buf);
+            break;
+          case IC_BR_NOT_CARRY:
+            ICFlagBranch(tmpi,rip,0x73830F,buf);
+            break;
+          case IC_BR_ZERO:
+            ICTestAndBranch(tmpi,rip,0x74840F,buf,rip2);
+            break;
+          case IC_BR_NOT_ZERO:
+            ICTestAndBranch(tmpi,rip,0x75850F,buf,rip2);
+            break;
+          case IC_BR_MM_ZERO:
+            ICPreIncDec(tmpi,SLASH_OP_DEC,rip2);
+            ICFlagBranch(tmpi,rip,0x74840F,buf);
+            break;
+          case IC_BR_MM_NOT_ZERO:
+            ICPreIncDec(tmpi,SLASH_OP_DEC,rip2);
+            ICFlagBranch(tmpi,rip,0x75850F,buf);
+            break;
+          case IC_BR_EQU_EQU:
+            ICCmpAndBranch(tmpi,FALSE,rip,0x74840F,0x74840F,
+                  0x74840F,0x74840F,buf,rip2);
+            break;
+          case IC_BR_EQU_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x74840F,0x74840F,
+                  0x74840F,0x74840F,buf,rip2);
+            break;
+          case IC_BR_NOT_EQU:
+            ICCmpAndBranch(tmpi,FALSE,rip,0x75850F,0x75850F,
+                  0x75850F,0x75850F,buf,rip2);
+            break;
+          case IC_BR_NOT_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x75850F,0x75850F,
+                  0x75850F,0x75850F,buf,rip2);
+            break;
+          case IC_BR_LESS:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x72820F,0x77870F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x72820F,0x7C8C0F,
+                    0x77870F,0x7F8F0F,buf,rip2);
+            break;
+          case IC_BR_LESS2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x72820F,0x7C8C0F,
+                  0x77870F,0x7F8F0F,buf,rip2);
+            break;
+          case IC_BR_GREATER_EQU:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x73830F,0x76860F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x73830F,0x7D8D0F,
+                    0x76860F,0x7E8E0F,buf,rip2);
+            break;
+          case IC_BR_GREATER_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x73830F,0x7D8D0F,
+                  0x76860F,0x7E8E0F,buf,rip2);
+            break;
+          case IC_BR_GREATER:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x77870F,0x72820F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x77870F,0x7F8F0F,
+                    0x72820F,0x7C8C0F,buf,rip2);
+            break;
+          case IC_BR_GREATER2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x77870F,0x7F8F0F,
+                  0x72820F,0x7C8C0F,buf,rip2);
+            break;
+          case IC_BR_LESS_EQU:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x76860F,0x73830F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x76860F,0x7E8E0F,
+                    0x73830F,0x7D8D0F,buf,rip2);
+            break;
+          case IC_BR_LESS_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x76860F,0x7E8E0F,
+                  0x73830F,0x7D8D0F,buf,rip2);
+            break;
+          case IC_BR_BT:
+            ICBrBitOps(tmpi,rip,0xA30F,0x20BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_BTS:
+            ICBrBitOps(tmpi,rip,0xAB0F,0x28BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_BTR:
+            ICBrBitOps(tmpi,rip,0xB30F,0x30BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_BTC:
+            ICBrBitOps(tmpi,rip,0xBB0F,0x38BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_NOT_BT:
+            ICBrBitOps(tmpi,rip,0xA30F,0x20BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_NOT_BTS:
+            ICBrBitOps(tmpi,rip,0xAB0F,0x28BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_NOT_BTR:
+            ICBrBitOps(tmpi,rip,0xB30F,0x30BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_NOT_BTC:
+            ICBrBitOps(tmpi,rip,0xBB0F,0x38BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_AND_ZERO:
+            ICAndBranch(tmpi,rip,0x74840F,buf,rip2);
+            break;
+          case IC_BR_AND_NOT_ZERO:
+            ICAndBranch(tmpi,rip,0x75850F,buf,rip2);
+            break;
+          case IC_SUB_CALL:
+            lb=OptLabelFwd(tmpi->ic_data);
+            ICU8(tmpi,0xE8);
+            ICU32(tmpi,lb->addr-(rip+5));
+            break;
+          case IC_JMP:
+            lb=OptLabelFwd(tmpi->ic_data);
+            short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+            if (!buf && lb->addr!=INVALID_PTR &&
+                  I8_MIN+5<lb->addr-rip<I8_MAX-5)
+              short_jmp=TRUE;
+            if (short_jmp) {
+              tmpi->ic_flags|=ICF_SHORT_JMP;
+              i=lb->addr-(rip+2);
+              if (buf || i)
+                ICU16(tmpi,i<<8+0xEB);
+              else
+                tmpi->ic_code=IC_NOP1;
+            } else {
+              i=lb->addr-(rip+5);
+              ICU8(tmpi,0xE9);
+              ICU32(tmpi,i);
+            }
+            break;
+          case IC_LABEL:
+            lb=tmpi->ic_data;
+            lb->addr=rip;
+            if (lb->flags&CMF_POP_CMP) {
+              ICAddRSP(tmpi,-8,FALSE);
+              ICAddRSP(tmpi,8,FALSE);
+            }
+            if (lb->type==CMT_ASM_LABEL)
+              lb->addr+=lb->rip;
+            break;
+          case IC_STR_CONST:
+          case IC_GET_LABEL:
+            lb=tmpi->ic_data;
+            if (cc->flags&CCF_AOT_COMPILE)
+              i=lb->addr+aotc->rip;
+            else
+              i=lb->addr+buf;
+            ICLea(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  MDF_RIP_DISP32+RT_PTR,0,i,cc,buf,rip2);
+            break;
+          case IC_ASM:
+            tmpaot=tmpi->ic_data;
+            tmpi->ic_cnt+=tmpaot->aot_U8s;
+            if (buf) {
+              MemCpy(buf+rip,tmpaot->buf,tmpaot->aot_U8s);
+              Free(tmpaot->buf);
+              tmpaot->buf=buf;
+              tmpaot->rip=rip;
+              tmpaot->rip2=rip2;
+              if (cc->flags&CCF_AOT_COMPILE)
+                CmpFixUpAOTAsm(cc,tmpaot);
+              else
+                CmpFixUpJITAsm(cc,tmpaot);
+              cnt=tmpi->ic_cnt;
+              goto op789A_skip_copy;
+            }
+            break;
+          case IC_CALL:
+            i=tmpi->ic_data-(rip2+5);
+            if (!(I32_MIN<=i<=I32_MAX) && !(cc->flags&CCF_AOT_COMPILE)) {
+              ICU16(tmpi,0xBB48);
+              ICU64(tmpi,tmpi->ic_data);
+              ICU16(tmpi,0xD3FF);
+            } else {
+              ICU8(tmpi,0xE8);
+              ICU32(tmpi,i);
+            }
+            break;
+          case IC_CALL_EXTERN: //Only for static modules
+            ICU8(tmpi,0xE8);
+            ICU32(tmpi,0);
+            if (buf) {
+              tmpf=tmpi->ic_data;
+              tmpeu=CAlloc(sizeof(CExternUsage));
+              tmpeu->next=tmpf->ext_lst;
+              tmpf->ext_lst=tmpeu;
+              tmpeu->rip=rip2+1;
+            }
+            break;
+          case IC_CALL_INDIRECT2:
+            ICU16(tmpi,0xBB48);
+            if (cc->flags&CCF_AOT_COMPILE) i=rip2+tmpi->ic_cnt;
+            ICU64(tmpi,tmpi->ic_data);
+            ICU16(tmpi,0x13FF);
+            if (buf && cc->flags&CCF_AOT_COMPILE&& !(cc->flags&CCF_NO_ABSS)) {
+              tmpa=CAlloc(sizeof(CAOTAbsAddr));
+              tmpa->next=aotc->abss;
+              tmpa->type=AAT_ADD_U64;
+              aotc->abss=tmpa;
+              tmpa->rip=i;
+            }
+            break;
+          case IC_CALL_IMPORT:
+            if (GetOption(OPTf_USE_IMM64)) {
+              ICU16(tmpi,0xBB48);
+              ICU64(tmpi,0);
+              if (buf) {
+                tmpf=tmpi->ic_data;
+                tmpie=CAlloc(sizeof(CAOTImportExport));
+                tmpie->type=IET_IMM_I64;
+                tmpie->rip=rip2+tmpi->ic_cnt-8;
+                tmpie->next=tmpf->ie_lst;
+                tmpf->ie_lst=tmpie;
+              }
+              ICU16(tmpi,0xD3FF);
+            } else {
+              ICU8(tmpi,0xE8);
+              ICU32(tmpi,0);
+              if (buf) {
+                tmpf=tmpi->ic_data;
+                tmpie=CAlloc(sizeof(CAOTImportExport));
+                tmpie->type=IET_REL_I32;
+                tmpie->rip=rip2+tmpi->ic_cnt-4;
+                tmpie->next=tmpf->ie_lst;
+                tmpf->ie_lst=tmpie;
+              }
+            }
+            break;
+        end:
+          tmpi->ic_flags&=~ICF_CODE_FINAL;
+          break;
+        case IC_LEAVE:
+          if (cc->htc.fun) {
+            if (Bt(&cc->htc.fun->flags,Ff_INTERRUPT))
+              ICPopRegs(tmpi,REGG_CLOBBERED|cc->htc.fun->used_reg_mask&
+                    (REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS|REGG_STK_TMP));
+            else
+              ICPopRegs(tmpi,cc->htc.fun->used_reg_mask&
+                    (REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS));
+          }
+          if (tmpi->ic_data<=I16_MAX) {
+            if (tmpi->ic_data)
+              ICU8(tmpi,0xC9); //LEAVE
+            else
+              ICU8(tmpi,0x5D); //POP RBP
+          } else {
+            ICAddRSP(tmpi,tmpi->ic_data);
+            ICU8(tmpi,0x5D); //POP RBP
+          }
+          if (cc->htc.fun && Bt(&cc->htc.fun->flags,Ff_INTERRUPT)) {
+            if (Bt(&cc->htc.fun->flags,Ff_HASERRCODE))
+              ICAddRSP(tmpi,8);
+            ICU16(tmpi,0xCF48);
+          } else if (cc->htc.fun && cc->htc.fun->arg_cnt &&
+                (Bt(&cc->htc.fun->flags,Ff_RET1) ||
+                Bt(&cc->htc.fun->flags,Ff_ARGPOP)) &&
+                !Bt(&cc->htc.fun->flags,Ff_NOARGPOP)) {
+            ICU8(tmpi,0xC2);
+            ICU16(tmpi,cc->htc.fun->arg_cnt<<3);
+          } else
+            ICU8(tmpi,0xC3);
+          break;
+        case IC_RET:
+          ICU8(tmpi,0xC3);
+          break;
+        case IC_FS:
+          ICZero(tmpi,REG_RAX);
+          ICU32(tmpi,0x8B4864);
+          break;
+        case IC_GS:
+          ICZero(tmpi,REG_RAX);
+          ICU32(tmpi,0x8B4865);
+          break;
+        case IC_MOV_FS:
+          ICZero(tmpi,REG_RAX);
+          ICU8(tmpi,0x64);
+//It's ugly to use ic_class here
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                MDF_DISP+CmpRawType(tmpi->ic_class),REG_RAX,tmpi->ic_data,
+                rip2);
+          break;
+        case IC_MOV_GS:
+          ICZero(tmpi,REG_RAX);
+          ICU8(tmpi,0x65);
+//It's ugly to use ic_class here
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                MDF_DISP+CmpRawType(tmpi->ic_class),REG_RAX,tmpi->ic_data,
+                rip2);
+          break;
+        case IC_HOLYC_TYPECAST:
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_COM:
+          ICUnaries(tmpi,SLASH_OP_NOT,rip2);
+          break;
+        case IC_NOT:
+          ICNot(tmpi,rip2);
+          break;
+        case IC_UNARY_MINUS:
+          if (tmpi->res.type.raw_type==RT_F64)
+            ICFUnaryMinus(cc,tmpi,buf,rip2);
+          else
+            ICUnaries(tmpi,SLASH_OP_NEG,rip2);
+          break;
+        case IC_ADDR:
+        case IC_MOV:
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_DEREF:
+          ICDeref(tmpi,rip2);
+          break;
+        case IC_DEREF_PP:
+          ICDerefPostIncDec(tmpi,SLASH_OP_INC,rip2);
+          break;
+        case IC_DEREF_MM:
+          ICDerefPostIncDec(tmpi,SLASH_OP_DEC,rip2);
+          break;
+        case IC__PP:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPostIncDec(tmpi,SLASH_OP_INC,rip2);
+          else
+            ICFPostIncDec(cc,tmpi,CMP_TEMPLATE_INC,rip2);
+          break;
+        case IC__MM:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPostIncDec(tmpi,SLASH_OP_DEC,rip2);
+          else
+            ICFPostIncDec(cc,tmpi,CMP_TEMPLATE_DEC,rip2);
+          break;
+        case IC_PP_:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPreIncDec(tmpi,SLASH_OP_INC,rip2);
+          else
+            ICFPreIncDec(cc,tmpi,CMP_TEMPLATE_INC,rip2);
+          break;
+        case IC_MM_:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPreIncDec(tmpi,SLASH_OP_DEC,rip2);
+          else
+            ICFPreIncDec(cc,tmpi,CMP_TEMPLATE_DEC,rip2);
+          break;
+        case IC_LEA:
+          ICLea(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,cc,buf,rip2);
+          break;
+        case IC_POWER:
+          ICFPow(cc,tmpi,buf,rip2);
+          break;
+        case IC_SHL:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE0D1E0D3E0C1,0xE0D1E0D3E0C1,rip2);
+          break;
+        case IC_SHR:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE8D1E8D3E8C1,0xF8D1F8D3F8C1,rip2);
+          break;
+        case IC_MUL:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICMul(tmpi,rip2);
+          else
+            ICFMul(cc,tmpi,buf,rip2);
+          break;
+        case IC_DIV:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICDiv(tmpi,rip2);
+          else
+            ICFDiv(cc,tmpi,buf,rip2);
+          break;
+        case IC_MOD:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICMod(tmpi,rip2);
+          else
+            ICFMod(cc,tmpi,rip2);
+          break;
+        case IC_AND:
+          ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x23,rip2);
+          break;
+        case IC_OR:
+          ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x0B,rip2);
+          break;
+        case IC_XOR:
+          ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x33,rip2);
+          break;
+        case IC_ADD:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x03,rip2);
+          else
+            ICFAdd(cc,tmpi,buf,rip2);
+          break;
+        case IC_SUB:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICSub(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+          else
+            ICFSub(cc,tmpi,buf,rip2);
+          break;
+        case IC_EQU_EQU:
+          ICCmp(tmpi,0x75,0x75,rip2);
+          break;
+        case IC_NOT_EQU:
+          ICCmp(tmpi,0x74,0x74,rip2);
+          break;
+        case IC_LESS:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x73,0x7D,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_LESS,rip2);
+          break;
+        case IC_GREATER_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x72,0x7C,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_GREATER_EQU,rip2);
+          break;
+        case IC_GREATER:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x76,0x7E,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_GREATER,rip2);
+          break;
+        case IC_LESS_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x77,0x7F,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_LESS_EQU,rip2);
+          break;
+        case IC_AND_AND:
+          ICAndAnd(tmpi,rip2);
+          break;
+        case IC_OR_OR:
+          ICOrOr(tmpi,rip2);
+          break;
+        case IC_XOR_XOR:
+          ICXorXor(tmpi,rip2);
+          break;
+        case IC_ASSIGN:
+          ICAssign(tmpi,rip2);
+          break;
+        case IC_ASSIGN_PP:
+          ICAssignPostIncDec(tmpi,SLASH_OP_INC,rip2);
+          break;
+        case IC_ASSIGN_MM:
+          ICAssignPostIncDec(tmpi,SLASH_OP_DEC,rip2);
+          break;
+        case IC_SHL_EQU:
+          ICShiftEqu(tmpi,tmpi->arg1_type_pointed_to,
+                tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE0D1E0D3E0C1,0xE0D1E0D3E0C1,rip2);
+          break;
+        case IC_SHR_EQU:
+          ICShiftEqu(tmpi,tmpi->arg1_type_pointed_to,
+                tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE8D1E8D3E8C1,0xF8D1F8D3F8C1,rip2);
+          break;
+        case IC_MUL_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICMulEqu(tmpi,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FMUL,buf,rip2);
+          break;
+        case IC_DIV_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICDivEqu(tmpi,FALSE,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FDIV,buf,rip2);
+          break;
+        case IC_MOD_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICDivEqu(tmpi,TRUE,rip2);
+          else
+            ICFModEqu(cc,tmpi,rip2);
+          break;
+        case IC_AND_EQU:
+          ICAndEqu(tmpi,rip2);
+          break;
+        case IC_OR_EQU:
+          ICOrEqu(tmpi,rip2);
+          break;
+        case IC_XOR_EQU:
+          ICXorEqu(tmpi,rip2);
+          break;
+        case IC_ADD_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+                  tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                  0x010000000003,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FADD,buf,rip2);
+          break;
+        case IC_SUB_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+                  tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                  0x29000000052B,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FSUB,buf,rip2);
+          break;
+        case IC_SHL_CONST:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                MDF_IMM+RT_I64,0,tmpi->ic_data,
+                0xE0D1E0D3E0C1,0xE0D1E0D3E0C1,rip2);
+          break;
+        case IC_SHR_CONST:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                MDF_IMM+RT_I64,0,tmpi->ic_data,
+                0xE8D1E8D3E8C1,0xF8D1F8D3F8C1,rip2);
+          break;
+        case IC_ADD_CONST:
+          ICAddSubEctImm(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,tmpi->ic_data,
+                0x0003,rip2);
+          break;
+        case IC_SUB_CONST:
+          ICAddSubEctImm(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,tmpi->ic_data,
+                0x052B,rip2);
+          break;
+        case IC_ENTER:
+          ICU32(tmpi,0xEC8B4855);
+          if (tmpi->ic_data)
+            ICAddRSP(tmpi,-tmpi->ic_data,FALSE);
+          if (cc->htc.fun) {
+            if (Bt(&cc->htc.fun->flags,Ff_INTERRUPT))
+              ICPushRegs(tmpi,REGG_CLOBBERED|cc->htc.fun->used_reg_mask&
+                    (REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS|REGG_STK_TMP));
+            else {
+              if (sys_var_init_flag && i)
+                ICLocalVarInit(tmpi);
+              ICPushRegs(tmpi,cc->htc.fun->used_reg_mask
+                    &(REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS));
+            }
+            for (i=0;i<REG_REGS_NUM;i++)
+              if (reg_offsets[i]>0 && reg_offsets[i].offset!=I64_MAX) {
+                tmpc=OptClassFwd(reg_offsets[i].m->member_class);
+                ICMov(tmpi,MDF_REG+RT_I64,i,0,MDF_DISP+tmpc->raw_type,
+                      REG_RBP,reg_offsets[i].offset,rip2);
+              }
+          }
+          break;
+        case IC_ADD_RSP:
+          ICAddRSP(tmpi,tmpi->ic_data);
+          break;
+        case IC_CALL_INDIRECT:
+          if (I8_MIN<=tmpi->ic_data<=I8_MAX) {
+            ICU24(tmpi,0x2454FF);  //CALL disp[RSP]
+            ICU8(tmpi,tmpi->ic_data);
+          } else {
+            ICU24(tmpi,0x2494FF);  //CALL disp[RSP]
+            ICU32(tmpi,tmpi->ic_data);
+          }
+          break;
+        case IC_PUSH:
+          ICPush(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_POP:
+          ICU8(tmpi,0x58);
+          break;
+        case IC_INVLPG:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU24(tmpi,0x38010F);
+          break;
+        case IC_CLFLUSH:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU24(tmpi,0x38AE0F);
+          break;
+        case IC_GET_RFLAGS:
+          ICU8(tmpi,0x9C);
+          ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip2);
+          break;
+        case IC_CARRY:
+          ICU24(tmpi,0xC0920F); //SETC AL
+          ICU24(tmpi,0x01E083); //AND EAX,1
+          break;
+        case IC_RDTSC:
+          ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_RDTSC,TRUE,FALSE,FALSE,CN_INST);
+          break;
+        case IC_SET_RFLAGS:
+          ICPush(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU8(tmpi,0x9D);
+          break;
+        case IC_GET_RBP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_REG+RT_I64,REG_RBP,0,rip2);
+          break;
+        case IC_SET_RBP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RBP,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_GET_RSP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_REG+RT_I64,REG_RSP,0,rip2);
+          break;
+        case IC_SET_RSP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RSP,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_RETURN_VAL:
+        case IC_SET_RAX:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_RETURN_VAL2:
+        case IC_GET_RAX:
+          break;
+        case IC_BT:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xA30F,0x20BA0F,rip2);
+          break;
+        case IC_BTS:
+        case IC_LBTS:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xAB0F,0x28BA0F,rip2);
+          break;
+        case IC_BTR:
+        case IC_LBTR:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xB30F,0x30BA0F,rip2);
+          break;
+        case IC_BTC:
+        case IC_LBTC:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xBB0F,0x38BA0F,rip2);
+          break;
+        case IC_BSF:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU32(tmpi,0xC0BC0F48);
+          ICU16(tmpi,0x0375);
+          ICU24(tmpi,0xD0F748);
+          break;
+        case IC_BSR:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU32(tmpi,0xC0BD0F48);
+          ICU16(tmpi,0x0375);
+          ICU24(tmpi,0xD0F748);
+          break;
+        case IC_SIGN_I64:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_SIGN_I64,
+                TRUE,FALSE,FALSE,CN_INST);
+          break;
+        case IC_TOUPPER:
+          ICToUpper(tmpi,rip2);
+          break;
+        case IC_TO_I64:
+          ICToI64(cc,tmpi,rip2);
+          break;
+        case IC_TO_F64:
+          ICToF64(cc,tmpi,rip2);
+          break;
+        case IC_TO_BOOL:
+          ICToBool(cc,tmpi,rip2);
+          break;
+        case IC_SQR:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_SQR,rip2);
+          break;
+        case IC_ABS:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_ABS,rip2);
+          break;
+        case IC_SQRT:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_SQRT,rip2);
+          break;
+        case IC_SIN:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_SIN,rip2);
+          break;
+        case IC_COS:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_COS,rip2);
+          break;
+        case IC_TAN:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_TAN,rip2);
+          break;
+        case IC_ATAN:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_ATAN,rip2);
+          break;
+        case IC_ABS_I64:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU24(tmpi,0xC08548);
+          ICU16(tmpi,0x0379);
+          ICU24(tmpi,0xD8F748);
+          break;
+        case IC_MIN_I64:
+          ICMinMax(tmpi,0x4F,rip2);
+          break;
+        case IC_MAX_I64:
+          ICMinMax(tmpi,0x4C,rip2);
+          break;
+        case IC_MIN_U64:
+          ICMinMax(tmpi,0x47,rip2);
+          break;
+        case IC_MAX_U64:
+          ICMinMax(tmpi,0x42,rip2);
+          break;
+        case IC_MOD_U64:
+          ICModU64(tmpi,rip2);
+          break;
+        case IC_SQR_I64:
+          ICSqr(tmpi,SLASH_OP_IMUL,rip2);
+          break;
+        case IC_SQR_U64:
+          ICSqr(tmpi,SLASH_OP_MUL,rip2);
+          break;
+        case IC_SWAP_U8:
+        case IC_SWAP_U16:
+        case IC_SWAP_U32:
+        case IC_SWAP_I64:
+          ICSwap(tmpi,rip2);
+          break;
+        case IC_QUE_INIT:
+          ICQueInit(tmpi,rip2);
+          break;
+        case IC_QUE_INS:
+          ICQueIns(tmpi,rip2);
+          break;
+        case IC_QUE_INS_REV:
+          ICQueInsRev(tmpi,rip2);
+          break;
+        case IC_QUE_REM:
+          ICQueRem(tmpi,rip2);
+          break;
+        case IC_STRLEN:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_STRLEN,TRUE,FALSE,FALSE,CN_INST);
+          break;
+        case IC_IN_U32:
+          if (tmpi->arg1.type&MDF_IMM) {
+            ICU16(tmpi,0xC033);
+            if (tmpi->arg1.disp<=U8_MAX)
+              ICU16(tmpi,0xE5+tmpi->arg1.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+              ICU8(tmpi,0xED);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xC033);
+            ICU8(tmpi,0xED);
+          }
+          break;
+        case IC_IN_U16:
+          if (tmpi->arg1.type&MDF_IMM) {
+            ICU16(tmpi,0xC033);
+            if (tmpi->arg1.disp<=U8_MAX)
+              ICU24(tmpi,0xE500+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+              ICU16(tmpi,0xED00+OC_OP_SIZE_PREFIX);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xC033);
+            ICU16(tmpi,0xED00+OC_OP_SIZE_PREFIX);
+          }
+          break;
+        case IC_IN_U8:
+          if (tmpi->arg1.type&MDF_IMM) {
+            ICU16(tmpi,0xC033);
+            if (tmpi->arg1.disp<=U8_MAX)
+              ICU16(tmpi,0xE4+tmpi->arg1.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+              ICU8(tmpi,0xEC);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xC033);
+            ICU8(tmpi,0xEC);
+          }
+          break;
+        case IC_OUT_U32:
+          if (tmpi->arg2.type&MDF_IMM) {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            if (tmpi->arg2.disp<=U8_MAX)
+              ICU16(tmpi,0xE7+tmpi->arg2.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+              ICU8(tmpi,0xEF);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU8(tmpi,0xEF);
+          }
+          break;
+        case IC_OUT_U16:
+          if (tmpi->arg2.type&MDF_IMM) {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            if (tmpi->arg2.disp<=U8_MAX)
+              ICU24(tmpi,0xE700+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+              ICU16(tmpi,0xEF00+OC_OP_SIZE_PREFIX);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xEF00+OC_OP_SIZE_PREFIX);
+          }
+          break;
+        case IC_OUT_U8:
+          if (tmpi->arg2.type&MDF_IMM) {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            if (tmpi->arg2.disp<=U8_MAX)
+              ICU16(tmpi,0xE6+tmpi->arg2.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+              ICU8(tmpi,0xEE);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU8(tmpi,0xEE);
+          }
+          break;
+        case IC_NOBOUND_SWITCH:
+          ICSwitch(tmpi,rip,TRUE,cc,buf,rip2);
+          break;
+        case IC_SWITCH:
+          ICSwitch(tmpi,rip,FALSE,cc,buf,rip2);
+          break;
+        case IC_NOP1:
+        case IC_NOP2:
+          OptFree(tmpi);
+          goto op789A_next;
+        case IC_CALL_START:
+        case IC_PUSH_REGS:
+          ICPushRegs(tmpi,tmpi->ic_data);
+          break;
+        case IC_CALL_END:
+          ICPopRegs(tmpi,tmpi->ic_data);
+          if (tmpi->res.type.mode)
+            ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  MDF_REG+RT_I64,REG_RAX,0,rip2);
+          break;
+        case IC_POP_REGS:
+          ICPopRegs(tmpi,tmpi->ic_data);
+          break;
+        case IC_PUSH_CMP:
+        case IC_CALL_END2:
+        case IC_END:
+        case IC_ADD_RSP1:
+          break;
+        default:
+          "Pass:%d Missing IC hndlr\n",cc->pass;
+          ICPut(cc,tmpi);
+          LexExcept(cc,"Compiler Optimization Error at ");
+      }
+      if (tmpi->res.type.mode) {
+        if (tmpi->ic_flags & ICF_RES_TO_F64) {
+          if (tmpi->ic_code==IC_PUSH_CMP) {
+            ICU24(tmpi,0x242CDF); //FILD U64 [RSP]
+            ICU24(tmpi,0x241CDD); //FSTP U64 [RSP]
+          } else {
+            ICFCvt(cc,tmpi,REG_RAX,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  FALSE,CN_RES,rip2);
+            if (!Bt(&tmpi->ic_flags,ICf_DONT_POP_FLOAT0+
+                  cc->cur_ic_float_op_num-1))
+              ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                    MDF_REG+RT_I64,REG_RAX,0,rip2);
+          }
+        } else if (tmpi->ic_flags & ICF_RES_TO_INT) {
+          ICFCvt(cc,tmpi,REG_RAX,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                TRUE,CN_RES,rip2);
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                MDF_REG+RT_I64,REG_RAX,0,rip2);
+        }
+      }
+    }
+    cnt=tmpi->ic_cnt;
+    if (tmpi->ic_flags&ICF_DEL_PREV_INS) {
+      if (cc->pass>8)
+        cnt=tmpi->ic_last_start;
+      tmpi->ic_flags&=~ICF_DEL_PREV_INS;
+    }
+    if (cnt && buf)
+      MemCpy(buf+rip,tmpi->ic_body,cnt);
+op789A_skip_copy:
+    if (dbg_info && cc->min_line<=tmpi->ic_line<=cc->max_line) {
+      i=tmpi->ic_line-cc->min_line;
+      if (!dbg_info->body[i])
+        dbg_info->body[i]=rip2;
+    }
+    if (tmpi->ic_flags&ICF_PASS_TRACE &&
+          Bt(&cc->saved_pass_trace,cc->pass) && cnt) {
+      "$RED$";
+      if (buf)
+        Un(buf+rip,cnt,64);
+      else
+        Un(tmpi->ic_body,cnt,64);
+      "$FG$";
+    }
+    if (!(tmpi->ic_flags&(ICF_CODE_FINAL|ICF_DONT_RESTORE)))
+      MemCpy(&tmpi->arg1,saved_arg1_arg2_r,3*sizeof(CICArg));
+    rip+=cnt;
+    if (tmpi->ic_cnt>=IC_BODY_SIZE && tmpi->ic_code!=IC_ASM)
+      throw('Compiler');
+op789A_next:
+    tmpi=tmpi_next;
+  }
+
+  lb=cc->coc.coc_next_misc;
+  while (lb!=&cc->coc.coc_next_misc) {
+    switch (lb->type) {
+      case CMT_STR_CONST:
+        lb->addr=rip;
+        if (buf)
+          MemCpy(buf+rip,lb->str,lb->st_len);
+        rip+=lb->st_len;
+        break;
+      case CMT_JMP_TABLE:
+        lb->addr=rip;
+        ptr=buf+lb->addr;
+        if (lb->flags&(CMF_I8_JMP_TABLE|CMF_U8_JMP_TABLE)) {
+          if (buf)
+            for (i=0;i<lb->range;i++)
+              *ptr++=lb->jmp_table[i]->addr-lb->begin->addr;
+          rip+=lb->range;
+        } else if (lb->flags&(CMF_I16_JMP_TABLE|CMF_U16_JMP_TABLE)) {
+          if (buf)
+            for (i=0;i<lb->range;i++)
+              *ptr(U16 *)++=lb->jmp_table[i]->addr-lb->begin->addr;
+          rip+=lb->range<<1;
+        } else {
+          if (buf)
+            for (i=0;i<lb->range;i++) {
+              if (cc->flags&CCF_AOT_COMPILE && !(cc->flags&CCF_NO_ABSS)) {
+                tmpa=CAlloc(sizeof(CAOTAbsAddr));
+                tmpa->next=aotc->abss;
+                tmpa->type=AAT_ADD_U32;
+                aotc->abss=tmpa;
+                tmpa->rip=aotc->rip+lb->addr+i<<2;
+                *ptr(U32 *)++=lb->jmp_table[i]->addr+aotc->rip;
+              } else
+                *ptr(U32 *)++=lb->jmp_table[i]->addr+buf;
+            }
+          rip+=lb->range<<2;
+        }
+        break;
+      case CMT_FLOAT_CONSTS:
+        lb->addr=rip;
+        if (buf)
+          MemCpy(buf+lb->addr,lb->float_consts,lb->num_consts*sizeof(F64));
+        rip+=lb->num_consts*sizeof(F64);
+        break;
+    }
+    lb=lb->next;
+  }
+  if (dbg_info) {
+    if (cc->flags&CCF_AOT_COMPILE)
+      dbg_info->body[num_lines]=rip+aotc->rip;
+    else
+      dbg_info->body[num_lines]=rip+buf;
+  }
+  return rip;
+}
+
+ diff --git a/public/Wb/Compiler/PrsExp.HC.HTML b/public/Wb/Compiler/PrsExp.HC.HTML new file mode 100755 index 0000000..b953d83 --- /dev/null +++ b/public/Wb/Compiler/PrsExp.HC.HTML @@ -0,0 +1,1209 @@ + + + + + + + + + + + +
+#define PE_UNARY_TERM1          0
+#define PE_UNARY_TERM2          1
+#define PE_MAYBE_MODIFIERS      2
+#define PE_UNARY_MODIFIERS      3
+#define PE_DEREFERENCE          4
+#define PE_CHECK_BINARY_OPS1    5
+#define PE_CHECK_BINARY_OPS2    6
+#define PE_DO_UNARY_OP          7
+#define PE_DO_BINARY_OP         8
+#define PE_POP_HIGHER           9
+#define PE_PUSH_LOWER           10
+#define PE_POP_ALL1             11
+#define PE_POP_ALL2             12
+
+CIntermediateCode *PrsAddOp(CCmpCtrl *cc,I64 stk_op,CHashClass *tmpc)
+{
+  CIntermediateCode *tmpi=cc->coc.coc_head.last;
+  Bool div_sizeof=FALSE;
+  switch (stk_op.u16[0]) {
+    case IC_ADD:
+      if (tmpc->ptr_stars_cnt && !tmpi->ic_class->ptr_stars_cnt &&
+            tmpi->ic_class->raw_type!=RT_F64) {
+        ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+        ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+      }
+      break;
+    case IC_SUB:
+      if (tmpc->ptr_stars_cnt && tmpi->ic_class->raw_type!=RT_F64) {
+        if (!tmpi->ic_class->ptr_stars_cnt) {
+          ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+          ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+        } else
+          div_sizeof=TRUE;
+      }
+      break;
+    case IC_AND_AND:
+    case IC_OR_OR:
+      ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+      break;
+    case IC_ADD_EQU:
+    case IC_SUB_EQU:
+      if (tmpc->ptr_stars_cnt) {
+        ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+        ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+      }
+      break;
+  }
+  tmpi=ICAdd(cc,stk_op,0,tmpc);
+  if (stk_op.u8[3]&ECF_HAS_PUSH_CMP) {
+    tmpi->ic_flags|=ICF_POP_CMP;
+    ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+    ICAdd(cc,IC_AND_AND,0,cmp.internal_types[RT_I64],ICF_POP_CMP);
+  }
+  if (div_sizeof) {
+    tmpc--;
+    if (tmpc->size!=1) {
+      ICAdd(cc,IC_IMM_I64,tmpc->size,cmp.internal_types[RT_I64]);
+      ICAdd(cc,IC_DIV,0,cmp.internal_types[RT_I64]);
+      tmpc=cmp.internal_types[RT_I64];
+    }
+  }
+  return tmpi;
+}
+
+U0 PrsExpression2(CCmpCtrl *cc,I64 *_max_prec,CPrsStk *ps)
+{
+  I64 i,cur_op,stk_op,state,max_prec=PREC_NULL,unary_pre_prec,paren_prec,
+        unary_post_prec,left_prec=PREC_MAX;
+  CIntermediateCode *tmpi;
+  CHashClass *tmpc;
+  CMemberLst *local_var;
+  CArrayDim *tmpad=NULL;
+
+  goto pe_unary_term1;
+  while (TRUE) {
+    switch [state] {
+      case PE_UNARY_TERM1:
+pe_unary_term1:
+        unary_pre_prec=PREC_NULL;
+        unary_post_prec=PREC_NULL;
+        cc->flags&=~(CCF_PAREN+CCF_PREINC+CCF_PREDEC+CCF_POSTINC+
+              CCF_POSTDEC+CCF_FUN_EXP);
+      case PE_UNARY_TERM2:
+        state=PrsUnaryTerm(cc,ps,&local_var,&tmpad,
+              &max_prec,&unary_pre_prec,&paren_prec);
+        break;
+      case PE_UNARY_MODIFIERS:
+        state=PrsUnaryModifier(cc,ps,&local_var,&tmpad,&unary_post_prec);
+        break;
+      case PE_MAYBE_MODIFIERS:
+        if (cc->token=='(') { //Typecast or fun_ptr
+          cc->flags|=CCF_RAX;
+          state=PrsUnaryModifier(cc,ps,&local_var,&tmpad,&unary_post_prec);
+        } else
+          goto pe_check_binary_ops1;
+        break;
+      case PE_DEREFERENCE:
+        if (!(cc->flags&(CCF_PREINC|CCF_PREDEC|CCF_POSTINC|CCF_POSTDEC)))
+          i=IC_DEREF+PREC_UNARY_PRE<<16;
+        else {
+          if (cc->flags & CCF_POSTINC)
+            i=IC__PP+PREC_UNARY_POST<<16;
+          else if (cc->flags & CCF_POSTDEC)
+            i=IC__MM+PREC_UNARY_POST<<16;
+          else if (cc->flags & CCF_PREDEC)
+            i=IC_MM_+PREC_UNARY_PRE<<16;
+          else
+            i=IC_PP_+PREC_UNARY_PRE<<16;
+          cc->flags&=~(CCF_PREINC|CCF_PREDEC|CCF_POSTINC|CCF_POSTDEC);
+        }
+        tmpi=cc->coc.coc_head.last;
+        if (cc->flags & (CCF_RAX|CCF_ARRAY)) {
+          if (tmpi->ic_code==IC_DEREF)
+            tmpi->ic_code=i;
+        } else {
+          tmpc=OptClassFwd(tmpi->ic_class-1);
+          ICAdd(cc,i,0,tmpc);
+        }
+      case PE_CHECK_BINARY_OPS1:
+pe_check_binary_ops1:
+        if (paren_prec) {
+          if (unary_pre_prec || unary_post_prec) {
+            if (paren_prec<=unary_pre_prec && !unary_post_prec)
+              ParenWarning(cc);
+            paren_prec=PREC_NULL;
+          } else if (paren_prec<=PREC_UNARY_PRE+ASSOC_MASK)
+            ParenWarning(cc);
+        }
+        cur_op=cmp.binary_ops[cc->token];
+
+      case PE_CHECK_BINARY_OPS2:
+pe_check_binary_ops2:
+        stk_op=PrsPop(ps);
+        tmpc=PrsPop(ps);
+        if (!(0<stk_op.u8[2]<=PREC_UNARY_PRE+ASSOC_MASK))
+          goto pe_do_binary_op;
+
+      case PE_DO_UNARY_OP:
+        if (cur_op.u16[0]==IC_POWER &&
+              stk_op.u16[0]==IC_UNARY_MINUS) {
+          Lex(cc); //skip ` op
+          left_prec=cur_op.i8[2];
+          PrsPush(ps,tmpc);
+          PrsPush(ps,stk_op);
+          PrsPush(ps,cc->coc.coc_head.last->ic_class);
+          PrsPush(ps,cur_op);
+          goto pe_unary_term1;
+        } else {
+          tmpi=cc->coc.coc_head.last;
+          tmpc=tmpi->ic_class;
+          if (stk_op.u16[0]==IC_DEREF && tmpc->ptr_stars_cnt)
+            tmpc--;
+          else if (stk_op.u16[0]==IC_ADDR) {
+            cc->abs_cnts.c_addres++;
+            if (intermediate_code_table[tmpi->ic_code].type==IST_DEREF)
+              OptFree(tmpi);
+            tmpc++;
+          }
+          tmpc=OptClassFwd(tmpc);
+          if (stk_op)
+            ICAdd(cc,stk_op,0,tmpc);
+          goto pe_check_binary_ops2;
+        }
+
+      case PE_DO_BINARY_OP:
+pe_do_binary_op:
+        PrsPush(ps,tmpc);
+        PrsPush(ps,stk_op);
+        if (!cur_op)
+          goto pe_pop_all1;
+
+        switch (cur_op.u16[0]) {
+          case IC_ADD:
+          case IC_SUB:
+            tmpi=cc->coc.coc_head.last;
+            if (!tmpi->ic_class->ptr_stars_cnt &&
+                  tmpi->ic_class->raw_type!=RT_F64) {
+              ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+              ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+            }
+            break;
+          case IC_AND_AND:
+          case IC_OR_OR:
+            ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+            break;
+        }
+        if (cc->flags & CCF_FUN_EXP) {
+          ps->ptr2--;
+          cc->flags&=~CCF_FUN_EXP;
+        }
+        Lex(cc); //skip op
+        if (paren_prec>PREC_UNARY_PRE+ASSOC_MASK &&
+              paren_prec&~ASSOC_MASK<left_prec&~ASSOC_MASK+
+              paren_prec&ASSOCF_RIGHT &&
+              paren_prec&~ASSOC_MASK<cur_op.u8[2]&~ASSOC_MASK+
+              !(paren_prec&ASSOCF_RIGHT))
+          ParenWarning(cc);
+        if (cur_op.u8[2]>max_prec)
+          max_prec=cur_op.u8[2];
+        left_prec=cur_op.u8[2];
+        if (intermediate_code_table[cur_op.u16[0]].type==IST_ASSIGN) {
+          tmpi=cc->coc.coc_head.last;
+          tmpc=OptClassFwd(tmpi->ic_class);
+          if (intermediate_code_table[tmpi->ic_code].type!=IST_DEREF ||
+                !tmpc->ptr_stars_cnt && !Bt(&tmpc->flags,Cf_INTERNAL_TYPE))
+            LexExcept(cc,"Invalid lval at ");
+          tmpi->ic_code=IC_NOP1; //Important for setting class (pretty sure)
+          cur_op.u8[2]=PREC_ASSIGN|ASSOCF_RIGHT;
+        }
+
+      case PE_POP_HIGHER:
+pe_pop_higher:
+        stk_op=PrsPop(ps); //pop ops of higher prec
+        tmpc=PrsPop(ps);
+        if (!stk_op)
+          goto pe_push_lower;
+        else if (cur_op.u8[2]&~ASSOC_MASK==stk_op.u8[2]&~ASSOC_MASK) {
+          if (cur_op.u8[2]&ASSOCF_RIGHT)
+            goto pe_push_lower;
+        } else if (cur_op.u8[2]&~ASSOC_MASK<=stk_op.u8[2]&~ASSOC_MASK)
+          goto pe_push_lower;
+
+        tmpi=PrsAddOp(cc,stk_op,tmpc);
+
+        if (intermediate_code_table[cur_op.u16[0]].type==IST_CMP &&
+              intermediate_code_table[stk_op.u16[0]].type==IST_CMP) {
+          tmpi->ic_flags|=ICF_PUSH_CMP;
+          ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+          ICAdd(cc,IC_PUSH_CMP,0,tmpc);
+          cur_op.u8[3]|=ECF_HAS_PUSH_CMP;
+        } else if (cur_op.u16[0]==IC_AND_AND || cur_op.u16[0]==IC_OR_OR)
+          ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+        goto pe_pop_higher;
+
+      case PE_PUSH_LOWER:
+pe_push_lower:
+        PrsPush(ps,tmpc);
+        PrsPush(ps,stk_op);
+        PrsPush(ps,cc->coc.coc_head.last->ic_class);
+        PrsPush(ps,cur_op);
+        goto pe_unary_term1;
+
+      case PE_POP_ALL1:
+pe_pop_all1:
+        if (paren_prec>PREC_UNARY_PRE+ASSOC_MASK &&
+              paren_prec&~ASSOC_MASK<=left_prec&~ASSOC_MASK-
+              paren_prec&ASSOCF_LEFT-left_prec&ASSOCF_LEFT)
+          ParenWarning(cc);
+      case PE_POP_ALL2:
+pe_pop_all2:
+        stk_op=PrsPop(ps);
+        tmpc=PrsPop(ps);
+        if (!stk_op.u16[0])
+          goto pe_done;
+        PrsAddOp(cc,stk_op,tmpc);
+        goto pe_pop_all2;
+    }
+  }
+pe_done:
+  if (_max_prec)
+    *_max_prec=max_prec;
+}
+
+Bool PrsExpression(CCmpCtrl *cc,I64 *_max_prec,Bool end_exp,CPrsStk *_ps=NULL)
+{
+  Bool res=TRUE;
+  I64 old_flags=cc->flags;
+  CPrsStk *ps;
+  if (_ps)
+    ps=_ps;
+  else {
+    ps=MAlloc(sizeof(CPrsStk));
+    ps->ptr=0;
+    ps->ptr2=0;
+  }
+  PrsPush(ps,0); //terminate
+  PrsPush(ps,0); //terminate
+  try
+//try catch causes noreg vars in function
+          PrsExpression2(cc,_max_prec,ps);
+  catch {
+    if (Fs->except_ch=='Compiler') {
+      res=FALSE;
+      Fs->catch_except=TRUE;
+    }
+  }
+  if (!_ps) {
+    if (ps->ptr)
+      LexExcept(cc,"Compiler Parse Error at ");
+    Free(ps);
+  }
+  if (res) {
+    if (end_exp)
+      ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+    if (cc->coc.coc_head.last->ic_class==
+          cmp.internal_types[RT_U0])
+      LexWarn(cc,"U0 Expression ");
+  }
+  cc->flags|=old_flags&(CCF_PREINC|CCF_PREDEC);
+  return res;
+}
+
+U0 PrsSizeOf(CCmpCtrl *cc)
+{
+  CHashClass *tmpc;
+  CMemberLst *tmpm;
+  CDbgInfo *dbg_info;
+  I64 i;
+  if (cc->token!=TK_IDENT)
+    LexExcept(cc,"Invalid class at ");
+  if (tmpm=cc->local_var_entry) {
+    tmpc=tmpm->member_class;
+    i=tmpc->size*tmpm->dim.total_cnt;
+    if (Lex(cc)=='.')
+      goto pu_sizeof_member;
+  } else {
+    if (!(tmpc=cc->hash_entry) || !(tmpc->type &
+          (HTT_CLASS|HTT_INTERNAL_TYPE|HTT_GLBL_VAR|
+          HTT_FUN|HTT_EXPORT_SYS_SYM)))
+      LexExcept(cc,"Invalid class at ");
+    if (tmpc->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+      if (!(dbg_info=tmpc(CHashFun *)->dbg_info))
+        LexExcept(cc,"Size not defined at ");
+      i=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+            -dbg_info->body[0];
+      Lex(cc);
+    } else {
+      i=tmpc->size;
+      while (Lex(cc)=='.') {
+pu_sizeof_member:
+        if (!(tmpc->type & (HTT_CLASS|HTT_GLBL_VAR)))
+          LexExcept(cc,"Invalid class at ");
+        else if (tmpc->type & HTT_GLBL_VAR)
+          tmpc=tmpc(CHashGlblVar *)->var_class;
+        if (Lex(cc)!=TK_IDENT || !(tmpm=MemberFind(cc->cur_str,tmpc)))
+          LexExcept(cc,"Invalid member at ");
+        else if (cc->local_var_entry)
+          cc->local_var_entry->use_cnt--;
+        tmpc=tmpm->member_class;
+//Probably others like this:
+        #assert offset(CHashClass.size)==offset(CHashGlblVar.size)
+        i=tmpc->size*tmpm->dim.total_cnt;
+      }
+    }
+  }
+  if (cc->token=='*') {
+    while (Lex(cc)=='*');
+    i=sizeof(U8 *);
+  }
+  ICAdd(cc,IC_IMM_I64,i,cmp.internal_types[RT_I64]);
+}
+
+U0 PrsOffsetOf(CCmpCtrl *cc)
+{
+  CHashClass *tmpc;
+  CMemberLst *tmpm;
+  I64 i;
+  if (cc->token!=TK_IDENT)
+    LexExcept(cc,"Invalid class at ");
+  if (tmpm=cc->local_var_entry)
+    tmpc=tmpm->member_class;
+  else {
+    tmpc=cc->hash_entry;
+    if (!tmpc || !(tmpc->type & (HTT_CLASS|HTT_GLBL_VAR)))
+      LexExcept(cc,"Invalid class at ");
+    else if (tmpc->type & HTT_GLBL_VAR)
+      tmpc=tmpc(CHashGlblVar *)->var_class;
+  }
+  if (Lex(cc)!='.')
+    LexExcept(cc,"Expecting '.' at ");
+  i=0;
+  do {
+    if (Lex(cc)!=TK_IDENT || !(tmpm=MemberFind(cc->cur_str,tmpc)))
+      LexExcept(cc,"Invalid member at ");
+    else if (cc->local_var_entry)
+      cc->local_var_entry->use_cnt--;
+    i+=tmpm->offset;
+    tmpc=tmpm->member_class;
+  } while (Lex(cc)=='.');
+  ICAdd(cc,IC_IMM_I64,i,cmp.internal_types[RT_I64]);
+}
+
+I64 PrsFunCall(CCmpCtrl *cc,CPrsStk *ps,Bool indirect,CHashFun *tmpf)
+{
+  I64 i,argc_cnt,dft_val;
+  Bool is_first_arg=TRUE,needs_right_paren,is_print,is_putchars,
+        is_template_fun;
+  CHashClass *tmpc2,*last_class=NULL;
+  CMemberLst *tmpm;
+  CCodeCtrl *tmpcbh,*tmpcbh1;
+  CCodeMisc *cm;
+  CIntermediateCode *tmpi;
+
+  if (!tmpf) {
+    if (cc->token==TK_CHAR_CONST) {
+      if (!(tmpf=HashFind("PutChars",cc->htc.hash_table_lst,HTT_FUN)))
+        LexExcept(cc,"Missing header for Print() and PutChars() at ");
+      if (!cc->cur_i64) //empty char signals PutChars with variable
+        Lex(cc);
+      is_print=FALSE;
+      is_putchars=TRUE;
+    } else {
+      if (!(tmpf=HashFind("Print",cc->htc.hash_table_lst,HTT_FUN)))
+        LexExcept(cc,"Missing header for Print() and PutChars() at ");
+      if (!*cc->cur_str) //empty string signals Print with variable fmt_str
+        Lex(cc);
+      is_putchars=FALSE;
+      is_print=TRUE;
+    }
+  } else {
+    is_print=FALSE;
+    is_putchars=FALSE;
+  }
+
+  if (Bt(&tmpf->flags,Ff_INTERNAL)&& IC_SQR<=tmpf->exe_addr<=IC_ATAN)
+    is_template_fun=TRUE;
+  else
+    is_template_fun=FALSE;
+
+  if (indirect) {
+    if (!(cc->flags & (CCF_RAX | CCF_ARRAY)))
+      ICAdd(cc,IC_DEREF,0,cmp.internal_types[RT_PTR]);
+    cc->coc.coc_head.last->ic_class=cmp.internal_types[RT_PTR];
+    ICAdd(cc,IC_SET_RAX,0,cmp.internal_types[RT_PTR]);
+    ICAdd(cc,IC_NOP2,1,cmp.internal_types[RT_PTR]); //balance the books
+  }
+  COCPush(cc);
+  tmpcbh=cc->coc.coc_next;
+  cc->coc.coc_next=NULL;
+  i=tmpf->arg_cnt;
+  tmpm=tmpf->member_lst_and_root;
+  argc_cnt=0;
+  if (cc->token=='(') {
+    Lex(cc);
+    needs_right_paren=TRUE;
+  } else
+    needs_right_paren=FALSE;
+  while (i--) {
+    COCInit(cc);
+    if (!is_first_arg) {
+      if (is_print) {
+        if (cc->token==',')
+          Lex(cc);
+        else if (cc->token!=';')
+          LexExcept(cc,"Expecting ',' at ");
+      } else {
+        if (needs_right_paren) {
+          if (cc->token==',')
+            Lex(cc);
+          else if (cc->token!=')')
+            LexExcept(cc,"Expecting ',' at ");
+        }
+      }
+    }
+    if (tmpm->flags & MLF_DFT_AVAILABLE &&
+          (cc->token==')' || cc->token==',' || !needs_right_paren)) {
+      dft_val=tmpm->dft_val;
+      if (tmpm->flags & MLF_LASTCLASS && last_class)
+        dft_val=(last_class-last_class->ptr_stars_cnt)->str;
+      if (tmpm->flags & (MLF_STR_DFT_AVAILABLE|MLF_LASTCLASS) &&
+            cc->flags&CCF_AOT_COMPILE) {
+        cm=COCMiscNew(cc,CMT_STR_CONST);
+        ICAdd(cc,IC_STR_CONST,cm,cmp.internal_types[RT_U8]+1);
+        cm->st_len=StrLen(dft_val)+1;
+        cm->str=StrNew(dft_val);
+        cc->flags|=CCF_HAS_MISC_DATA;
+      } else
+        ICAdd(cc,IC_IMM_I64,dft_val,tmpm->member_class);
+    } else {
+      if (!PrsExpression(cc,NULL,FALSE,ps))
+        throw('Compiler');
+      else {
+        COCPush(cc);
+        cc->pass=0;      OptPass012(cc);
+        cc->pass=1; tmpi=OptPass012(cc);
+        COCPop(cc);
+        last_class=OptClassFwd(tmpi->ic_class);
+        tmpc2=OptClassFwd(tmpm->member_class);
+        if (tmpc2->raw_type==RT_F64 && !tmpm->dim.next &&
+              last_class->raw_type!=RT_F64)
+          tmpi->ic_flags|=ICF_RES_TO_F64;
+        else
+          if (tmpc2->raw_type!=RT_F64 && last_class->raw_type==RT_F64)
+            tmpi->ic_flags|=ICF_RES_TO_INT;
+      }
+    }
+    COCPush(cc);
+    is_first_arg=FALSE;
+    tmpm=tmpm->next;
+  }
+  if (tmpm && tmpm->flags & MLF_DOT_DOT_DOT) {
+    COCInit(cc);
+    tmpi=ICAdd(cc,IC_IMM_I64,0,tmpm->member_class);
+    COCPush(cc);
+    if (is_print) {
+      if (cc->token!=';') {
+        do {
+          if (!is_first_arg) {
+            if (cc->token==',')
+              Lex(cc);
+            else
+              LexExcept(cc,"Expecting ',' at ");
+          }
+          COCInit(cc);
+          if (!PrsExpression(cc,NULL,FALSE,ps))
+            throw('Compiler');
+          COCPush(cc);
+          is_first_arg=FALSE;
+          argc_cnt++;
+        } while (cc->token==',');
+      }
+    } else if (needs_right_paren) {
+      if (cc->token!=')') {
+        do {
+          if (!is_first_arg) {
+            if (cc->token==',')
+              Lex(cc);
+            else
+              LexExcept(cc,"Expecting ',' at ");
+          }
+          COCInit(cc);
+          if (!PrsExpression(cc,NULL,FALSE,ps))
+            throw('Compiler');
+          COCPush(cc);
+          is_first_arg=FALSE;
+          argc_cnt++;
+        } while (cc->token==',');
+      }
+    }
+    tmpi->ic_data=argc_cnt++; //++ so add_esp latter works
+  }
+  if (needs_right_paren) {
+    if (cc->token==')')
+      Lex(cc);
+    else
+      LexExcept(cc,"Missing ')' at ");
+  }
+  tmpcbh1=tmpcbh->coc_next;
+  tmpcbh->coc_next=cc->coc.coc_next;
+  cc->coc.coc_next=tmpcbh;
+  COCPop(cc);
+  tmpcbh=cc->coc.coc_next;
+  cc->coc.coc_next=tmpcbh1;
+  if (!is_template_fun)
+    ICAdd(cc,IC_CALL_START,tmpf,0);
+  if (indirect)
+    ICAdd(cc,IC_PUSH_REGS,1<<REG_RAX,tmpf->return_class);
+  while (tmpcbh) {
+    tmpcbh1=tmpcbh->coc_next;
+    COCAppend(cc,tmpcbh);
+    if (!Bt(&tmpf->flags,Ff_INTERNAL))
+      cc->coc.coc_head.last->ic_flags|=ICF_PUSH_RES;
+    tmpcbh=tmpcbh1;
+  }
+  if (Bt(&tmpf->flags,Ff_INTERNAL))
+    ICAdd(cc,tmpf->exe_addr,0,tmpf->return_class);
+  else {
+    if (indirect)
+      ICAdd(cc,IC_CALL_INDIRECT,
+            (argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+    else if (Bt(&tmpf->flags,Cf_EXTERN)) {
+      cc->abs_cnts.externs++;
+      if (cc->flags&CCF_AOT_COMPILE) {
+        if (tmpf->type&HTF_IMPORT)
+          ICAdd(cc,IC_CALL_IMPORT,tmpf,tmpf->return_class);
+        else
+          ICAdd(cc,IC_CALL_EXTERN,tmpf,tmpf->return_class);
+      } else
+        ICAdd(cc,IC_CALL_INDIRECT2,&tmpf->exe_addr,tmpf->return_class);
+    } else
+      ICAdd(cc,IC_CALL,tmpf->exe_addr,tmpf->return_class);
+    if ((Bt(&tmpf->flags,Ff_RET1) || Bt(&tmpf->flags,Ff_ARGPOP)) &&
+          !Bt(&tmpf->flags,Ff_NOARGPOP)) {
+      if (indirect) {
+        ICAdd(cc,IC_ADD_RSP1,(argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+        ICAdd(cc,IC_ADD_RSP,8,tmpf->return_class);
+      } else
+        ICAdd(cc,IC_ADD_RSP1,(argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+    } else {
+      if (indirect)
+        argc_cnt++;
+      ICAdd(cc,IC_ADD_RSP,(argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+    }
+  }
+  if (!is_template_fun)
+    ICAdd(cc,IC_CALL_END,tmpf,tmpf->return_class);
+  if (is_print||is_putchars)
+    ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+  cc->flags=(cc->flags|CCF_RAX) & ~(CCF_ARRAY|CCF_FUN_EXP);
+  return PE_UNARY_MODIFIERS;
+}
+
+I64 PrsUnaryTerm(CCmpCtrl *cc,CPrsStk *ps,CMemberLst **_local_var,
+        CArrayDim **_tmpad,I64 *max_prec,I64 *unary_pre_prec,I64 *paren_prec)
+{
+  I64 i,j;
+  CHashExport *tmpex;
+  CHashClass *tmpc;
+  CHashFun *tmpf;
+  CHashGlblVar *tmpg;
+  CMemberLst *tmpm;
+  CAsmUndefHash *tmpauh;
+  CCodeMisc *cm;
+  Bool paren_warn;
+
+  *_local_var=NULL;
+  *paren_prec=PREC_NULL;
+  switch (cc->token) {
+    start:
+      if (PREC_UNARY_PRE>*max_prec)
+        *max_prec=PREC_UNARY_PRE;
+      *unary_pre_prec=PREC_UNARY_PRE;
+      start:
+        case '~': i=IC_COM;             break;
+        case '!': i=IC_NOT;             break;
+        case '-': i=IC_UNARY_MINUS;     break;
+        case '*': i=IC_DEREF;           break;
+      end:
+        Lex(cc); //Skip op
+        break;
+      case '&':
+        if (Lex(cc)==TK_IDENT) {
+          if (tmpc=cc->hash_entry) {
+            if (tmpc->type & HTT_FUN) {
+              tmpf=tmpc;
+              if (!Bt(&tmpf->flags,Ff_INTERNAL)) {
+                if (Bt(&tmpf->flags,Cf_EXTERN)) {
+                  if (cc->flags&CCF_AOT_COMPILE) {
+                    if (cc->flags&CCF_ASM_EXPRESSIONS) {
+                      if (tmpex=HashFind(tmpf->str,cc->htc.hash_table_lst,
+                            HTT_EXPORT_SYS_SYM))
+                        goto pu_export_sys_sym;
+                      else
+                        goto pu_new_sys_sym;
+                    }
+                    LexExcept(cc,"Can't take addr of extern fun");
+                  }
+                  cc->abs_cnts.externs++;
+                  ICAdd(cc,IC_IMM_I64,
+                        &tmpf->exe_addr,cmp.internal_types[RT_PTR]);
+                  ICAdd(cc,IC_DEREF,0,cmp.internal_types[RT_PTR]);
+                } else {
+                  if (cc->flags&CCF_AOT_COMPILE) {
+                    ICAdd(cc,IC_ABS_ADDR,
+                          tmpf->exe_addr,cmp.internal_types[RT_PTR]);
+                    if (cc->flags&CCF_ASM_EXPRESSIONS)
+                      cc->abs_cnts.abs_addres++;
+                  } else
+                    ICAdd(cc,IC_IMM_I64,
+                          tmpf->exe_addr,cmp.internal_types[RT_PTR]);
+                }
+                cc->abs_cnts.c_addres++;
+                Lex(cc);
+                return PE_MAYBE_MODIFIERS;
+              }
+            } else if (tmpc->type & HTT_EXPORT_SYS_SYM) {
+              tmpex=tmpc;
+              if (cc->flags&CCF_ASM_EXPRESSIONS &&
+                    !(cc->flags&CCF_AOT_COMPILE) && tmpex->type&HTF_IMM) {
+                cc->abs_cnts.c_addres++;
+                ICAdd(cc,IC_IMM_I64,
+                      tmpex->val,cmp.internal_types[RT_PTR]);
+                Lex(cc);
+                return PE_MAYBE_MODIFIERS;
+              } else
+                goto pu_export_sys_sym;
+            }
+          } else if (cc->flags&CCF_ASM_EXPRESSIONS && !cc->local_var_entry)
+            goto pu_ident_but_not_local_var;
+        }
+        i=IC_ADDR;
+        break;
+    end:
+      PrsPush(ps,tmpc);
+      PrsPush(ps,PREC_UNARY_PRE<<16+i);
+      return PE_UNARY_TERM2;
+
+    start:
+      case TK_I64:
+      case TK_CHAR_CONST:
+      case TK_INS_BIN_SIZE:
+        if (cc->cur_i64<0)
+          ICAdd(cc,IC_IMM_I64,cc->cur_i64,cmp.internal_types[RT_U64]);
+        else
+          ICAdd(cc,IC_IMM_I64,cc->cur_i64,cmp.internal_types[RT_I64]);
+        Lex(cc);
+        break;
+      case TK_F64:
+        ICAdd(cc,IC_IMM_F64,cc->cur_f64(I64),cmp.internal_types[RT_F64]);
+        Lex(cc);
+        break;
+      case TK_STR:
+        cm=COCMiscNew(cc,CMT_STR_CONST);
+        ICAdd(cc,IC_STR_CONST,cm,cmp.internal_types[RT_U8]+1);
+        cm->str=LexExtStr(cc,&cm->st_len);
+        cc->flags|=CCF_HAS_MISC_DATA;
+        break;
+      case TK_INS_BIN:
+        cm=COCMiscNew(cc,CMT_STR_CONST);
+        ICAdd(cc,IC_STR_CONST,cm,cmp.internal_types[RT_U8]+1);
+        cm->str=cc->cur_str;
+        cm->st_len=cc->cur_str_len;
+        cc->cur_str=NULL;
+        cc->flags|=CCF_HAS_MISC_DATA;
+        Lex(cc);
+        break;
+      case '$':
+        if (cc->flags & CCF_ASM_EXPRESSIONS) {
+          cc->abs_cnts.abs_addres++;
+          if (cc->flags&CCF_AOT_COMPILE)
+            ICAdd(cc,IC_ABS_ADDR,cc->aotc->rip,cmp.internal_types[RT_PTR]);
+          else
+            ICAdd(cc,IC_IMM_I64,cc->aotc->rip,cmp.internal_types[RT_PTR]);
+        } else {
+          if (cc->flags&CCF_CLASS_DOL_OFFSET)
+            ICAdd(cc,IC_IMM_I64,cc->class_dol_offset,
+                  cmp.internal_types[RT_I64]);
+          else
+            ICAdd(cc,IC_RIP,0,cmp.internal_types[RT_PTR]);
+        }
+        Lex(cc);
+        break;
+    end:
+      if (PREC_TERM>*max_prec)
+        *max_prec=PREC_TERM;
+      return PE_MAYBE_MODIFIERS;
+
+    case '(':
+      if (Lex(cc)==TK_IDENT && cc->hash_entry &&
+            cc->hash_entry->type & (HTT_CLASS|HTT_INTERNAL_TYPE))
+        LexExcept(cc,"Use TempleOS postfix typecasting at ");
+      else {
+        if (PREC_TERM>*max_prec)
+          *max_prec=PREC_TERM;
+        if (cc->lex_include_stk->flags&LFSF_DEFINE)
+          paren_warn=FALSE;
+        else
+          paren_warn=TRUE;
+        if (!PrsExpression(cc,paren_prec,FALSE,ps))
+          throw('Compiler');
+        if (!paren_warn)
+          *paren_prec=PREC_NULL;
+        if (cc->token!=')')
+          LexExcept(cc,"Missing ')' at ");
+        Lex(cc); //skip )
+        cc->flags= cc->flags & ~CCF_ARRAY | CCF_RAX | CCF_PAREN;
+        return PE_UNARY_MODIFIERS;
+      }
+
+    start:
+      case '+':                                   break;
+      case TK_PLUS_PLUS:   cc->flags|=CCF_PREINC; break;
+      case TK_MINUS_MINUS: cc->flags|=CCF_PREDEC; break;
+    end:
+      if (PREC_UNARY_PRE>*max_prec)
+        *max_prec=PREC_UNARY_PRE;
+      *unary_pre_prec=PREC_UNARY_PRE;
+      Lex(cc);
+      return PE_UNARY_TERM2;
+
+    case TK_IDENT:
+      if (tmpm=cc->local_var_entry) {
+        if (PREC_TERM>*max_prec)
+          *max_prec=PREC_TERM;
+        cc->flags&=~(CCF_RAX|CCF_ARRAY|CCF_FUN_EXP);
+        tmpc=tmpm->member_class+1;
+        if (tmpm->flags & MLF_FUN && !(cc->flags&CCF_ASM_EXPRESSIONS)) {
+          PrsPopDeref(ps);
+          cc->flags|=CCF_FUN_EXP;
+          PrsPush2(ps,tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+        }
+        if (tmpm->dim.next) {
+          *_tmpad=tmpm->dim.next;
+          cc->flags|=CCF_ARRAY;
+        }
+        if (tmpm->flags&MLF_STATIC) {
+          if (cc->flags&CCF_AOT_COMPILE) {
+//      if (tmpg->flags&GVF_DATA_HEAP) //TODO
+            //    ICAdd(cc,IC_HEAP_GLBL,tmpm->static_data,tmpc);
+            //  else
+            ICAdd(cc,IC_ABS_ADDR,tmpm->static_data_rip,tmpc);
+          } else
+            ICAdd(cc,IC_IMM_I64,tmpm->static_data,tmpc);
+        } else {
+          if (cc->flags&CCF_ASM_EXPRESSIONS) {
+            i=PrsPop(ps);
+            ps->ptr--;
+            if (i.u16[0]!=IC_ADDR)
+              LexExcept(cc,"Expecting '&' at ");
+            ICAdd(cc,IC_IMM_I64,tmpm->offset,cmp.internal_types[RT_PTR]);
+            *_local_var=tmpm;
+            Lex(cc);
+            return PE_MAYBE_MODIFIERS;
+          } else {
+            if (tmpm->dim.next && tmpm->offset>0 &&
+                  StrCmp(tmpm->str,"argv")) {
+              tmpc++;
+              cc->flags&=~CCF_ARRAY;
+            }
+            ICAdd(cc,IC_RBP,0,tmpc);
+            ICAdd(cc,IC_IMM_I64,tmpm->offset,tmpc);
+            ICAdd(cc,IC_ADD,0,tmpc);
+          }
+        }
+        Lex(cc); //skip var name
+        *_local_var=tmpm;
+        return PE_UNARY_MODIFIERS;
+      }
+pu_ident_but_not_local_var:
+      if (!(tmpex=cc->hash_entry)) {
+        if (!(cc->flags & CCF_ASM_EXPRESSIONS))
+          LexExcept(cc,"Invalid lval at ");
+        tmpc=NULL;
+pu_new_sys_sym:
+        tmpex=CAlloc(sizeof(CHashExport),Fs->code_heap);
+        tmpex->str=cc->cur_str;
+        cc->cur_str=NULL;
+        if (!cc->htc.local_var_lst &&
+              *tmpex->str=='@' && tmpex->str[1]=='@') {
+          tmpex->type=HTT_EXPORT_SYS_SYM | HTF_UNRESOLVED | HTF_LOCAL;
+          HashAdd(tmpex,cc->htc.local_hash_table);
+        } else {
+          tmpex->type=HTT_EXPORT_SYS_SYM | HTF_UNRESOLVED;
+          if (tmpc)
+            HashAddAfter(tmpex,tmpc,cc->htc.glbl_hash_table);
+          else
+            HashAdd(tmpex,cc->htc.glbl_hash_table);
+        }
+      }
+      switch (Bsf(tmpex->type)) {
+        case HTt_EXPORT_SYS_SYM:
+pu_export_sys_sym:
+          if (PREC_TERM>*max_prec)
+            *max_prec=PREC_TERM;
+          if (!(tmpex->type & (HTF_IMM|HTF_IMPORT)))
+            cc->abs_cnts.abs_addres++;
+          if (tmpex->type & HTF_UNRESOLVED) {
+            if (!(cc->flags&CCF_ASM_EXPRESSIONS))
+              LexExcept(cc,"Illegal fwd ref at ");
+            tmpauh=MAlloc(sizeof(CAsmUndefHash));
+            tmpauh->hash=tmpex;
+            tmpauh->next=cc->asm_undef_hash;
+            cc->asm_undef_hash=tmpauh;
+            if (tmpex->type & HTF_LOCAL)
+              cc->flags|=CCF_UNRESOLVED|CCF_LOCAL;
+            else
+              cc->flags|=CCF_UNRESOLVED;
+            ICAdd(cc,IC_IMM_I64,
+                  &tmpex->val,cmp.internal_types[RT_PTR],ICF_NO_RIP);
+            ICAdd(cc,IC_DEREF,0,cmp.internal_types[RT_PTR]);
+          } else {
+            if (cc->flags&CCF_AOT_COMPILE && !(tmpex->type & HTF_IMM))
+              ICAdd(cc,IC_ABS_ADDR,tmpex->val,cmp.internal_types[RT_PTR]);
+            else {
+              if (tmpex->type&HTF_IMM)
+                cc->abs_cnts.c_addres++;
+              ICAdd(cc,IC_IMM_I64,tmpex->val,cmp.internal_types[RT_PTR]);
+            }
+          }
+          Lex(cc);
+          return PE_MAYBE_MODIFIERS;
+        case HTt_FUN:
+          if (PREC_TERM>*max_prec)
+            *max_prec=PREC_TERM;
+          Lex(cc);  //skip fun name
+          return PrsFunCall(cc,ps,FALSE,tmpex);
+        case HTt_GLBL_VAR:
+          if (PREC_TERM>*max_prec)
+            *max_prec=PREC_TERM;
+          tmpg=tmpex;
+          tmpc=tmpg->var_class+1;
+          cc->flags&=~(CCF_RAX|CCF_ARRAY|CCF_FUN_EXP);
+          if (tmpg->flags&GVF_ARRAY) {
+            *_tmpad=tmpg->dim.next;
+            cc->flags|=CCF_ARRAY;
+          }
+          if (cc->flags&CCF_AOT_COMPILE) {
+            if (tmpg->flags & GVF_EXTERN) //TODO
+              LexExcept(cc,"Feature not implemented ");
+            else {
+              if (tmpg->flags & GVF_IMPORT)
+                ICAdd(cc,IC_ADDR_IMPORT,tmpg,tmpc);
+              else {
+                if (tmpg->flags&GVF_DATA_HEAP)
+                  ICAdd(cc,IC_HEAP_GLBL,tmpg->heap_glbl,tmpc);
+                else
+                  ICAdd(cc,IC_ABS_ADDR,tmpg->data_addr_rip,tmpc);
+              }
+            }
+          } else {
+            if (tmpg->flags & GVF_EXTERN) {
+              cc->abs_cnts.externs++;
+              ICAdd(cc,IC_IMM_I64,&tmpg->data_addr,tmpc);
+              ICAdd(cc,IC_DEREF,0,tmpc);
+            } else
+              ICAdd(cc,IC_IMM_I64,tmpg->data_addr,tmpc);
+          }
+          Lex(cc);
+          if (tmpg->flags & GVF_FUN) {
+            PrsPopDeref(ps);
+            cc->flags|=CCF_FUN_EXP;
+            PrsPush2(ps,tmpg->fun_ptr-tmpg->fun_ptr->ptr_stars_cnt);
+          }
+          return PE_UNARY_MODIFIERS;
+        case HTt_CLASS:
+          PrsOffsetOf(cc);
+          return PE_MAYBE_MODIFIERS;
+        case HTt_KEYWORD:
+          switch (tmpex(CHashGeneric *)->user_data0) {
+            case KW_SIZEOF:
+              if (PREC_TERM>*max_prec)
+                *max_prec=PREC_TERM;
+              j=0;
+              while (Lex(cc)=='(')
+                j++;
+              PrsSizeOf(cc);
+              while (j--) {
+                if (cc->token!=')')
+                  LexExcept(cc,"Missing ')' at ");
+                Lex(cc);
+              }
+              return PE_MAYBE_MODIFIERS;
+            case KW_OFFSET:
+              if (PREC_TERM>*max_prec)
+                *max_prec=PREC_TERM;
+              j=0;
+              while (Lex(cc)=='(')
+                j++;
+              PrsOffsetOf(cc);
+              while (j--) {
+                if (cc->token!=')')
+                  LexExcept(cc,"Missing ')' at ");
+                Lex(cc);
+              }
+              return PE_MAYBE_MODIFIERS;
+            case KW_DEFINED:
+              if (PREC_TERM>*max_prec)
+                *max_prec=PREC_TERM;
+              j=0;
+              while (Lex(cc)=='(')
+                j++;
+              if (cc->token==TK_IDENT &&
+                    (cc->hash_entry || cc->local_var_entry))
+                ICAdd(cc,IC_IMM_I64,TRUE,cmp.internal_types[RT_I64]);
+              else
+                ICAdd(cc,IC_IMM_I64,FALSE,cmp.internal_types[RT_I64]);
+              Lex(cc);
+              while (j--) {
+                if (cc->token!=')')
+                  LexExcept(cc,"Missing ')' at ");
+                Lex(cc);
+              }
+              return PE_MAYBE_MODIFIERS;
+          }
+      }
+  }
+  LexExcept(cc,"Missing expression at ");
+}
+
+I64 PrsUnaryModifier(CCmpCtrl *cc,CPrsStk *ps,CMemberLst **_local_var,
+        CArrayDim **_tmpad,I64 *unary_post_prec)
+{
+  CHashClass *tmpc,*tmpc1;
+  CHashFun *fun_ptr;
+  CMemberLst *tmpm=*_local_var;
+  CIntermediateCode *tmpi,*tmpi1;
+  CArrayDim *tmpad1,tmpad2;
+  CCodeMisc *cm;
+  I64 mode,old_flags;
+  Bool was_paren=Btr(&cc->flags,CCf_PAREN);
+
+  *_local_var=NULL;
+  switch (cc->token) {
+    case '.':
+      if (tmpm)
+        tmpm->reg=REG_NONE;
+      goto um_join;
+
+    case TK_DEREFERENCE:
+      tmpi=cc->coc.coc_head.last;
+      if (!(cc->flags & (CCF_RAX | CCF_ARRAY)))
+        ICAdd(cc,IC_DEREF+PREC_UNARY_PRE<<16,0,tmpi->ic_class-1);
+      else
+        tmpi->ic_class--;
+
+        um_join:
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_TERM;
+      tmpc=cc->coc.coc_head.last->ic_class;
+      if ((!tmpc->ptr_stars_cnt || cc->flags & CCF_ARRAY) && cc->token=='.')
+        LexExcept(cc,"Must be address, not value ");
+      if (!(cc->flags & CCF_RAX))
+        tmpc--;
+      if (!(tmpc->type & HTT_CLASS))
+        LexExcept(cc,"Invalid class at ");
+      if (Lex(cc)!=TK_IDENT ||
+            !(tmpm=MemberFind(cc->cur_str,tmpc)))
+        LexExcept(cc,"Invalid member at ");
+      else if (cc->local_var_entry)
+        cc->local_var_entry->use_cnt--;
+      Lex(cc);  //skip member name
+      tmpc1=tmpm->member_class+1;
+      ICAdd(cc,IC_IMM_I64,tmpm->offset,tmpc1);
+      cc->flags&=~(CCF_RAX|CCF_ARRAY|CCF_FUN_EXP);
+      if (tmpm->dim.next) {
+        *_tmpad=tmpm->dim.next;
+        cc->flags|=CCF_ARRAY;
+      }
+      if(tmpm->flags & MLF_FUN) {
+        PrsPopDeref(ps);
+        PrsPush2(ps,tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+        cc->flags|=CCF_FUN_EXP;
+      }
+      ICAdd(cc,IC_ADD,0,tmpc1);
+      return PE_UNARY_MODIFIERS;
+    case '(':
+      if (cc->flags & CCF_FUN_EXP) {
+        if (!*unary_post_prec)
+          *unary_post_prec=PREC_TERM;
+        return PrsFunCall(cc,ps,TRUE,PrsPop2(ps));
+      }
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_TERM;
+      if (Lex(cc)!=TK_IDENT)
+        LexExcept(cc,"Invalid class at ");
+      if (Btr(&cc->flags,CCf_FUN_EXP))
+        ps->ptr2--;
+      cc->flags&=~CCF_ARRAY;
+      tmpc=cc->hash_entry;
+      Lex(cc);
+      mode=PRS0_TYPECAST|PRS1_NULL;
+      tmpc=PrsType(cc,&tmpc,&mode,NULL,NULL,&fun_ptr,NULL,&tmpad2,0);
+      if (fun_ptr) {
+        PrsPopDeref(ps);
+        Bts(&cc->flags,CCf_FUN_EXP);
+        PrsPush2(ps,fun_ptr);
+        cm=COCMiscNew(cc,CMT_HASH_ENTRY);
+        cm->h=fun_ptr;
+      }
+      if (*_tmpad=tmpad2.next) {
+        cc->flags|=CCF_ARRAY;
+        tmpc++;
+        cm=COCMiscNew(cc,CMT_ARRAY_DIM);
+        cm->dim=*_tmpad;
+      }
+      if (!(cc->flags&(CCF_RAX|CCF_ARRAY)))
+        tmpc++;
+      tmpi=cc->coc.coc_head.last;
+      tmpi->ic_class=tmpc;
+      ICAdd(cc,IC_HOLYC_TYPECAST,was_paren,tmpc);
+      if (cc->token!=')')
+        LexExcept(cc,"Missing ')' at ");
+      Lex(cc);
+      return PE_UNARY_MODIFIERS;
+    case '[':
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_TERM;
+      Lex(cc);
+      tmpc=OptClassFwd(cc->coc.coc_head.last->ic_class);
+      if (!tmpc->ptr_stars_cnt)
+        LexExcept(cc,"Not array or ptr ");
+      if (!(cc->flags & (CCF_ARRAY | CCF_RAX))) {
+        tmpc=OptClassFwd(tmpc-1);
+        if (!tmpc->ptr_stars_cnt)
+          LexExcept(cc,"Not array or ptr ");
+        ICAdd(cc,IC_DEREF+PREC_UNARY_PRE<<16,0,tmpc);
+      }
+      tmpc1=tmpc-1;
+      if (tmpad1=*_tmpad) {
+        ICAdd(cc,IC_IMM_I64,tmpad1->total_cnt*tmpc1->size,tmpc);
+        if (*_tmpad=tmpad1->next) {
+          old_flags=cc->flags;
+          if (!PrsExpression(cc,NULL,FALSE,ps))
+            throw('Compiler');
+          cc->flags=cc->flags&~CCF_FUN_EXP|old_flags&CCF_FUN_EXP;
+          if (cc->token!=']')
+            LexExcept(cc,"Missing ']' at ");
+          Lex(cc); //skip ]
+          tmpi1=cc->coc.coc_head.last;
+          tmpi1->ic_flags|=ICF_RES_TO_INT;
+          ICAdd(cc,IC_MUL,0,tmpc);
+          ICAdd(cc,IC_ADD,0,tmpc);
+          cc->flags|=CCF_RAX;
+          return PE_UNARY_MODIFIERS;
+        }
+      } else
+        ICAdd(cc,IC_IMM_I64,tmpc1->size,tmpc);
+      old_flags=cc->flags;
+      if (!PrsExpression(cc,NULL,FALSE,ps))
+        throw('Compiler');
+      cc->flags=cc->flags&~CCF_FUN_EXP|old_flags&CCF_FUN_EXP;
+      if (cc->token!=']')
+        LexExcept(cc,"Missing ']' at ");
+      Lex(cc); //skip ]
+      tmpi1=cc->coc.coc_head.last;
+      tmpi1->ic_flags|=ICF_RES_TO_INT;
+      ICAdd(cc,IC_MUL,0,tmpc);
+      ICAdd(cc,IC_ADD,0,tmpc);
+      cc->flags&=~(CCF_RAX|CCF_ARRAY);
+      return PE_UNARY_MODIFIERS;
+    start:
+      case TK_PLUS_PLUS:
+        cc->flags|=CCF_POSTINC;
+        break;
+      case TK_MINUS_MINUS:
+        cc->flags|=CCF_POSTDEC;
+        break;
+    end:
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_UNARY_POST;
+      Lex(cc);
+      return PE_DEREFERENCE;
+  }
+  return PE_DEREFERENCE;
+}
+
+U8 *LexExpression2Bin(CCmpCtrl *cc,I64 *_type=NULL)
+{//Compile cc expression. You call the code.
+  U8 *res;
+  I64 size;
+  Bool old_trace=Btr(&cc->flags,CCf_PASS_TRACE_PRESENT);
+  COCPush(cc);
+  COCInit(cc);
+  if (PrsExpression(cc,NULL,FALSE)) {
+    ICAdd(cc,IC_RETURN_VAL,0,0);
+    ICAdd(cc,IC_RET,0,0);
+    res=COCCompile(cc,&size,NULL,_type);
+  } else
+    res=NULL;
+  COCPop(cc);
+  BEqu(&cc->flags,CCf_PASS_TRACE_PRESENT,old_trace);
+  return res;
+}
+
+Bool IsLexExpression2Bin(CCmpCtrl *cc,U8 **_machine_code)
+{//Compile cc expression to bin. Return err status.
+  return ToBool(*_machine_code=LexExpression2Bin(cc));
+}
+
+I64 LexExpressionI64(CCmpCtrl *cc)
+{//Compile cc expression, forcing to I64 and eval.
+  U8 *machine_code;
+  I64 res,type;
+  if (machine_code=LexExpression2Bin(cc,&type)) {
+    res=Call(machine_code);
+    Free(machine_code);
+    if (type==RT_F64)
+      res=ToI64(res(F64));
+  } else
+    res=0;
+  return res;
+}
+
+F64 LexExpressionF64(CCmpCtrl *cc)
+{//Compile cc expression, forcing to F64 and eval.
+  U8 *machine_code;
+  I64 res,type;
+  if (machine_code=LexExpression2Bin(cc,&type)) {
+    res=Call(machine_code);
+    Free(machine_code);
+    if (type!=RT_F64)
+      res(F64)=ToF64(res);
+  } else
+    res=0;
+  return res(F64);
+}
+
+I64 LexExpression(CCmpCtrl *cc)
+{//Compile cc expression and eval.  Might be I64 or F64.
+  U8 *machine_code;
+  I64 res;
+  if (machine_code=LexExpression2Bin(cc)) {
+    res=Call(machine_code);
+    Free(machine_code);
+  } else
+    res=0;
+  return res;
+}
+
+ diff --git a/public/Wb/Compiler/PrsLib.HC.HTML b/public/Wb/Compiler/PrsLib.HC.HTML new file mode 100755 index 0000000..4a220ad --- /dev/null +++ b/public/Wb/Compiler/PrsLib.HC.HTML @@ -0,0 +1,354 @@ + + + + + + + + + + + +
+U0 PrsPush(CPrsStk *ps,I64 val)
+{
+  ps->stk[++ps->ptr]=val;
+}
+
+I64 PrsPop(CPrsStk *ps)
+{
+  return ps->stk[ps->ptr--];
+}
+
+U0 PrsPush2(CPrsStk *ps,I64 val)
+{
+  ps->stk2[++ps->ptr2]=val;
+}
+
+I64 PrsPop2(CPrsStk *ps)
+{
+  return ps->stk2[ps->ptr2--];
+}
+
+U0 PrsPopDeref(CPrsStk *ps)
+{
+  I64 i=PrsPop(ps);
+  CHashClass *tmpc=PrsPop(ps);
+  if (i.u16[0]!=IC_DEREF) {
+    PrsPush(ps,tmpc);
+    PrsPush(ps,i);
+  }
+}
+
+I64 PrsKeyWord(CCmpCtrl *cc)
+{//Cvt cur token to KEYWORD or -1.
+  CHashGeneric *tmph;
+  if (cc->token==TK_IDENT &&(tmph=cc->hash_entry) && tmph->type&HTT_KEYWORD)
+    return tmph->user_data0;
+  else
+    return -1;
+}
+
+CHashClass *PrsClassNew()
+{/*Ptrs to classes are handled by
+allocating 5 structures for each
+new class and representing a pointer
+to a class by advancing 1 struct fwd
+for one * and two fwd for two **.
+*/
+  I64 i;
+  CHashClass *res=CAlloc(sizeof(CHashClass)*(PTR_STARS_NUM+1),Fs->code_heap),
+        *tmpc=res;
+  for (i=0;i<=PTR_STARS_NUM;i++) {
+    tmpc->type=HTT_CLASS;
+    tmpc->raw_type=RT_PTR;
+    tmpc->size=sizeof(U8 *);
+    tmpc->ptr_stars_cnt=i;
+    tmpc++;
+  }
+  res->last_in_member_lst=&res->member_lst_and_root;
+  res->size=0;
+  return res;
+}
+
+CHashFun *PrsFunNew()
+{
+  I64 i;
+  CHashFun *res=CAlloc(sizeof(CHashFun)*(PTR_STARS_NUM+1),Fs->code_heap),
+        *tmpf=res;
+  for (i=0;i<=PTR_STARS_NUM;i++) {
+    tmpf->type=HTT_FUN;
+    tmpf->raw_type=RT_PTR;
+    tmpf->size=sizeof(U8 *);
+    tmpf->ptr_stars_cnt=i;
+    tmpf++;
+  }
+  res->last_in_member_lst=&res->member_lst_and_root;
+  res->size=0;
+  return res;
+}
+
+CIntermediateCode *ICAdd(CCmpCtrl *cc,
+   I64 opcode_and_precedence,I64 arg, CHashClass *c,I64 flags=0)
+{
+  CIntermediateCode *tmpi=MAlloc(sizeof(CIntermediateCode));
+  tmpi->ic_code=opcode_and_precedence.u16[0];
+  tmpi->ic_precedence=opcode_and_precedence.u16[1];
+  tmpi->ic_data=arg;
+  tmpi->ic_class=c;
+  if (cc->pass_trace) {
+    Bts(&cc->flags,CCf_PASS_TRACE_PRESENT);
+    flags|=ICF_PASS_TRACE;
+  }
+  if (cc->lock_cnt)
+    flags|=ICF_LOCK;
+  tmpi->ic_flags=flags;
+  tmpi->ic_line=cc->last_line_num;
+  QueIns(tmpi,cc->coc.coc_head.last);
+  return tmpi;
+}
+
+U0 COCInit(CCmpCtrl *cc)
+{
+  CCodeCtrl *tmpcbh=&cc->coc;
+  QueInit(&tmpcbh->coc_head.next);
+  QueInit(&tmpcbh->coc_next_misc);
+  tmpcbh->coc_head.ic_code=IC_END;
+}
+
+U0 COCPush(CCmpCtrl *cc)
+{
+  CCodeCtrl *tmpcbh=MAlloc(sizeof(CCodeCtrl));
+  MemCpy(tmpcbh,&cc->coc,sizeof(CCodeCtrl));
+  cc->coc.coc_next=tmpcbh;
+}
+
+CCmpCtrl *COCPopNoFree(CCmpCtrl *cc)
+{
+  CCodeCtrl *tmpcbh=cc->coc.coc_next;
+  MemCpy(&cc->coc,tmpcbh,sizeof(CCodeCtrl));
+  return tmpcbh;
+}
+
+U0 COCPop(CCmpCtrl *cc)
+{
+  Free(COCPopNoFree(cc));
+}
+
+U0 COCAppend(CCmpCtrl *cc, CCodeCtrl *tmpcbh)
+{
+  if (tmpcbh->coc_head.next!=&cc->coc.coc_head.next) {
+    cc->coc.coc_head.last->next=tmpcbh->coc_head.next;
+    tmpcbh->coc_head.next->last=cc->coc.coc_head.last;
+    cc->coc.coc_head.last=tmpcbh->coc_head.last;
+    tmpcbh->coc_head.last->next=&cc->coc.coc_head.next;
+  }
+  if (tmpcbh->coc_next_misc!=&cc->coc.coc_next_misc) {
+    cc->coc.coc_last_misc->next=tmpcbh->coc_next_misc;
+    tmpcbh->coc_next_misc->last=cc->coc.coc_last_misc;
+    cc->coc.coc_last_misc=tmpcbh->coc_last_misc;
+    tmpcbh->coc_last_misc->next=&cc->coc.coc_next_misc;
+  }
+  Free(tmpcbh);
+}
+
+CCodeMisc *COCMiscNew(CCmpCtrl *cc,I64 ty)
+{
+  CCodeMisc *res=CAlloc(sizeof(CCodeMisc));
+  res->addr=INVALID_PTR;
+  res->type=ty;
+  QueIns(res,cc->coc.coc_last_misc);
+  return res;
+}
+
+CCodeMisc *COCGoToLabelFind(CCmpCtrl *cc,U8 *name)
+{
+  CCodeMisc *cm=cc->coc.coc_next_misc;
+  while (cm!=&cc->coc.coc_next_misc) {
+    if ((cm->type==CMT_GOTO_LABEL||cm->type==CMT_ASM_LABEL) &&
+          !StrCmp(cm->str,name))
+      return cm;
+    cm=cm->next;
+  }
+  return NULL;
+}
+
+I64 COCFloatConstFind(CCmpCtrl *cc,F64 d)
+{
+  I64 i;
+  CCodeMisc *cm=cc->coc.coc_next_misc;
+  while (cm!=&cc->coc.coc_next_misc) {
+    if (cm->type==CMT_FLOAT_CONSTS) {
+      for (i=0;i<cm->num_consts;i++)
+        if (cm->float_consts[i]==d)
+          return cm->addr+i*sizeof(F64);
+      if (cm->num_consts<CM_CONSTS_NUM)  {
+        cm->float_consts[cm->num_consts++]=d;
+        return cm->addr+i*sizeof(F64);
+      }
+    }
+    cm=cm->next;
+  }
+  cm=COCMiscNew(cc,CMT_FLOAT_CONSTS);
+  cm->float_consts=MAlloc(CM_CONSTS_NUM*sizeof(F64));
+  cm->float_consts[cm->num_consts++]=d;
+  return cm->addr;
+}
+
+U0 COCDel(CCmpCtrl *cc,CCodeCtrl *coc)
+{
+  CCodeMisc *cm,*cm1;
+  U8 *undef=NULL;
+  QueDel(&coc->coc_head.next);
+  cm=coc->coc_next_misc;
+  while (cm!=&coc->coc_next_misc) {
+    cm1=cm->next;
+    switch (cm->type) {
+      case CMT_GOTO_LABEL:
+      case CMT_ASM_LABEL:
+        if (!(cm->flags&CMF_DEFINED)) {
+          undef=cm->str;
+          cm->str=NULL;
+        } else if (!cm->use_cnt) {
+          PrintWarn("Unused label %s\n",cm->str);
+          LexWarn(cc,"Unused label at ");
+        }
+        break;
+      case CMT_JMP_TABLE:
+        Free(cm->jmp_table);
+        break;
+      case CMT_FLOAT_CONSTS:
+        Free(cm->float_consts);
+        break;
+      case CMT_ARRAY_DIM:
+        LinkedLstDel(cm->dim);
+        break;
+      case CMT_HASH_ENTRY:
+        HashDel(cm->h);
+        break;
+    }
+    Free(cm->str);
+    Free(cm);
+    cm=cm1;
+  }
+  if (undef) {
+    PrintErr("Undefined goto label %s\n",undef);
+    Free(undef);
+    LexExcept(cc,"Undefined goto label at ");
+  }
+}
+
+U0 COCHeaderPut(CCmpCtrl *cc,I64 pass,Bool put)
+{
+  CIntermediateCode *tmpi;
+  if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT)) {
+    if (put) {
+      if (Bt(&cc->saved_pass_trace,pass-1)) {
+        "$IV,1$Pass %d:$IV,0$\n",pass-1;
+        tmpi=cc->coc.coc_head.next;
+        while (tmpi->ic_code) {
+          if (tmpi->ic_flags&ICF_PASS_TRACE)
+            ICPut(cc,tmpi);
+          tmpi=tmpi->next;
+        }
+      }
+    } else if (Bt(&cc->saved_pass_trace,pass))
+      "$IV,1$Pass %d:$IV,0$\n",pass;
+  }
+  cc->pass=pass;
+}
+
+U8 *COCCompile(CCmpCtrl *cc,I64 *_code_size,CDbgInfo **_dbg,I64 *_type)
+{
+  U8 *res;
+  CCodeMisc *lb;
+  I64 i,code_size,last_code_size;
+
+  COptReg reg_offsets[REG_REGS_NUM];
+  if (_dbg) *_dbg=NULL;
+  cc->pass=0;
+  COCHeaderPut(cc,1,TRUE);
+  OptPass012(cc);
+  COCHeaderPut(cc,2,TRUE);
+  OptPass012(cc);
+  COCHeaderPut(cc,3,TRUE);
+  OptPass3(cc,reg_offsets);
+  COCHeaderPut(cc,4,TRUE);
+  OptPass4(cc,reg_offsets,_type);
+  COCHeaderPut(cc,5,TRUE);
+  OptPass5(cc);
+  COCHeaderPut(cc,6,TRUE);
+  OptPass6(cc);
+  COCHeaderPut(cc,7,TRUE);
+
+  lb=cc->coc.coc_next_misc;
+  while (lb!=&cc->coc.coc_next_misc) {
+    if (lb->type==CMT_JMP_TABLE) {
+      for (i=0;i<lb->range;i++)
+        lb->jmp_table[i]=OptLabelFwd(lb->jmp_table[i]);
+      lb->dft=OptLabelFwd(lb->dft);
+    }
+    lb=lb->next;
+  }
+
+  COCHeaderPut(cc,7,FALSE);
+  OptPass789A(cc,reg_offsets,NULL,NULL);
+  COCHeaderPut(cc,8,FALSE);
+  OptPass789A(cc,reg_offsets,NULL,NULL);
+  COCHeaderPut(cc,9,FALSE);
+  code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
+  do {
+    last_code_size=code_size;
+    COCHeaderPut(cc,9,FALSE);
+    code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
+    if (code_size>last_code_size) {
+      "Pass:9 Code Size\n";
+      LexExcept(cc,"Compiler Optimization Error at ");
+    }
+  } while (code_size<last_code_size);
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    res=MAlloc(code_size);
+  else {
+    res=MAlloc(code_size,Fs->code_heap);
+    if (cc->htc.fun)
+      Fs->last_fun=cc->htc.fun;
+  }
+  COCHeaderPut(cc,10,FALSE);
+  code_size=OptPass789A(cc,reg_offsets,res,_dbg);
+
+  COCDel(cc,&cc->coc);
+  if (Bt(&cc->opts,OPTf_TRACE)) {
+    if (cc->flags&CCF_AOT_COMPILE) {
+      if (cc->aotc->seg_size==16)
+        Un(res,code_size,16);
+      else if (cc->aotc->seg_size==64)
+        Un(res,code_size,64);
+      else
+        Un(res,code_size,32);
+    } else
+      Un(res,code_size,64);
+  }
+  if (_code_size) *_code_size=code_size;
+  cc->saved_pass_trace=cc->pass_trace;
+  return res;
+}
+
+ diff --git a/public/Wb/Compiler/PrsStmt.HC.HTML b/public/Wb/Compiler/PrsStmt.HC.HTML new file mode 100755 index 0000000..f8c3012 --- /dev/null +++ b/public/Wb/Compiler/PrsStmt.HC.HTML @@ -0,0 +1,1253 @@ + + + + + + + + + + + +
+CHashClass *PrsClass(CCmpCtrl *cc,I64 keyword,I64 fsp_flags,Bool is_extern)
+{
+  CHashClass *tmpc,*base_class;
+  if (cc->token!=TK_IDENT)
+    LexExcept(cc,"Expecting identifier at ");
+  if (is_extern) {
+    tmpc=PrsClassNew;
+    tmpc->str=cc->cur_str;
+    cc->cur_str=NULL;
+    HashAdd(tmpc,cc->htc.glbl_hash_table);
+    LBts(&tmpc->flags,Cf_EXTERN);
+    HashSrcFileSet(cc,tmpc);
+    Lex(cc);
+  } else {
+    if (cc->flags&CCF_AOT_COMPILE)
+      tmpc=HashFind(cc->cur_str,cc->htc.glbl_hash_table,HTT_CLASS);
+    else
+      tmpc=HashSingleTableFind(cc->cur_str,cc->htc.glbl_hash_table,HTT_CLASS);
+    if (tmpc) {
+      if (!Bt(&tmpc->flags,Cf_EXTERN))
+        tmpc=NULL;
+      else if (tmpc->use_cnt<3)
+        UnusedExternWarning(cc,tmpc);
+    }
+    if (tmpc) {
+      Free(tmpc->src_link);
+      tmpc->src_link=NULL;
+      Free(tmpc->idx);
+      tmpc->idx=NULL;
+    } else {
+      tmpc=PrsClassNew;
+      tmpc->str=cc->cur_str;
+      cc->cur_str=NULL;
+      HashAdd(tmpc,cc->htc.glbl_hash_table);
+    }
+    LBtr(&tmpc->flags,Cf_EXTERN);
+    if (fsp_flags&FSF_PUBLIC)
+      tmpc->type|=HTF_PUBLIC;
+    tmpc->use_cnt=0;
+    if (cc->last_U16=='\n')
+      HashSrcFileSet(cc,tmpc,-1);
+    else
+      HashSrcFileSet(cc,tmpc,0);
+    if (Lex(cc)==':') {
+      if (Lex(cc)!=TK_IDENT || !(base_class=cc->hash_entry) ||
+            !(base_class->type&HTT_CLASS))
+        LexExcept(cc,"Invalid class at ");
+      if (Lex(cc)==',')
+        LexExcept(cc,"Only one base class allowed at this time at ");
+      tmpc->base_class=base_class;
+      tmpc->size+=base_class->size;
+    }
+    if (keyword==KW_UNION)
+      PrsVarLst(cc,tmpc,PRS0_NULL|PRS1_CLASS|PRSF_UNION);
+    else
+      PrsVarLst(cc,tmpc,PRS0_NULL|PRS1_CLASS);
+    tmpc->size+=tmpc->neg_offset;
+  }
+  return tmpc;
+}
+
+CHashFun *PrsFunJoin(CCmpCtrl *cc,CHashClass *tmp_return,
+        U8 *name,I64 fsp_flags)
+{
+  CMemberLst *tmpm,*header_lst;
+  CAOTCtrl *aotc=cc->aotc;
+  CHashClass *header_return;
+  CHashFun *tmpf;
+  I64 header_arg_cnt;
+  if (name) {//if not fun_ptr
+    if (cc->flags&CCF_AOT_COMPILE) {
+      if ((tmpf=HashFind(name,cc->htc.glbl_hash_table,HTT_FUN)) &&
+            tmpf->type & HTF_IMPORT)
+        tmpf=NULL;
+    } else
+      if ((tmpf=HashSingleTableFind(name,cc->htc.glbl_hash_table,HTT_FUN)) &&
+            !Bt(&tmpf->flags,Cf_EXTERN))
+        tmpf=NULL;
+    if (tmpf && tmpf->use_cnt<3)
+      UnusedExternWarning(cc,tmpf);
+  } else
+    tmpf=NULL;
+  if (tmpf) {
+    tmpf->used_reg_mask=REGG_CLOBBERED+REGG_SAVED+REGG_STK_TMP;
+    Free(tmpf->src_link);
+    tmpf->src_link=NULL;
+    Free(tmpf->idx);
+    tmpf->idx=NULL;
+    Free(name);
+    header_arg_cnt=tmpf->arg_cnt;
+    header_lst=tmpf->member_lst_and_root;
+    header_return=tmpf->return_class;
+    tmpf->member_lst_and_root=NULL;
+    ClassMemberLstDel(tmpf);
+  } else {
+    tmpf=PrsFunNew;
+    header_return=NULL;
+    tmpf->used_reg_mask=REGG_CLOBBERED+REGG_SAVED+REGG_STK_TMP;
+    tmpf->clobbered_reg_mask=REGG_CLOBBERED+REGG_STK_TMP;
+    tmpf->str=name;
+    if (cc->flags&CCF_AOT_COMPILE)
+      tmpf->exe_addr=aotc->rip;
+    else
+      tmpf->exe_addr=&UndefinedExtern;
+    LBts(&tmpf->flags,Cf_EXTERN);
+    tmpf->flags|=fsp_flags&FSG_FUN_FLAGS1;
+    if (name) //if not fun_ptr
+      HashAdd(tmpf,cc->htc.glbl_hash_table);
+  }
+  BEqu(&tmpf->type,HTf_PUBLIC,fsp_flags&FSF_PUBLIC);
+  tmpf->return_class=tmp_return;
+  tmpf->use_cnt=0;
+  HashSrcFileSet(cc,tmpf);
+  PrsVarLst(cc,tmpf,PRS0_NULL|PRS1_FUN_ARG);
+  tmpf->arg_cnt=tmpf->member_cnt;
+  if (0<tmpf->arg_cnt<<3<=I16_MAX && !Bt(&tmpf->flags,Ff_DOT_DOT_DOT))
+    LBts(&tmpf->flags,Ff_RET1);
+  tmpm=tmpf->member_lst_and_root;
+  while (tmpm) {
+    tmpm->offset+=16; //RBP+RETURN
+    tmpm=tmpm->next;
+  }
+  tmpf->size=0;
+  if (header_return) {
+    if (GetOption(OPTf_WARN_HEADER_MISMATCH)) {
+      if (tmpf->return_class!=header_return) {
+        PrintWarn("Fun Header return mismatch '%s'\n",tmpf->str);
+        cc->warning_cnt++;
+      }
+      if (!MemberLstCmp(tmpf->member_lst_and_root,header_lst,header_arg_cnt)) {
+        PrintWarn("Fun header args mismatch '%s'\n",tmpf->str);
+        cc->warning_cnt++;
+      }
+    }
+    MemberLstDel(header_lst);
+  }
+  return tmpf;
+}
+
+U0 PrsFun(CCmpCtrl *cc,CHashClass *tmp_return,U8 *name,I64 fsp_flags)
+{
+  CMemberLst *tmpm;
+  CCodeMisc *saved_leave_label;
+  I64 i,j,size,*r;
+  Bool old_trace;
+
+  cc->fun_lex_file=cc->lex_include_stk;
+  cc->min_line=cc->max_line=cc->lex_include_stk->line_num;
+
+  cc->flags&=~CCF_NO_REG_OPT;
+  cc->htc.local_var_lst=cc->htc.fun=PrsFunJoin(cc,tmp_return,name,fsp_flags);
+
+  COCPush(cc);
+  Btr(&cc->flags,CCf_PASS_TRACE_PRESENT);
+  COCInit(cc);
+  ICAdd(cc,IC_ENTER,0,0);
+  saved_leave_label=cc->lb_leave;
+  cc->lb_leave=COCMiscNew(cc,CMT_LABEL);
+  cc->flags&=~CCF_HAS_RETURN;
+  PrsStmt(cc,,,0);
+
+  if (cc->max_line<cc->min_line)
+    cc->max_line=cc->min_line;
+
+  if (cc->htc.fun->return_class->size && !(cc->flags&CCF_HAS_RETURN))
+    LexWarn(cc,"Function should return val ");
+  ICAdd(cc,IC_LABEL,cc->lb_leave,0);
+  cc->lb_leave=saved_leave_label;
+  ICAdd(cc,IC_LEAVE,0,cc->htc.fun->return_class);
+  cc->htc.fun->size&=~7;
+  if (cc->flags&CCF_AOT_COMPILE) {
+    cc->htc.fun->exe_addr=cc->aotc->rip;
+    cc->htc.fun->type|=HTF_EXPORT|HTF_RESOLVE;
+    r=COCCompile(cc,&size,&cc->htc.fun->dbg_info,NULL);
+    if (r) {
+      j=(size+7)>>3;
+      for (i=0;i<j;i++)
+        AOTStoreCodeU64(cc,r[i]);
+      Free(r);
+    }
+  } else {
+    old_trace=Btr(&cc->opts,OPTf_TRACE);
+    cc->htc.fun->exe_addr=COCCompile(
+          cc,&size,&cc->htc.fun->dbg_info,NULL);
+    if (old_trace) {
+      Bts(&cc->opts,OPTf_TRACE);
+      Un(cc->htc.fun->exe_addr,size,64);
+    }
+    SysSymImportsResolve(cc->htc.fun->str);
+  }
+  LBtr(&cc->htc.fun->flags,Cf_EXTERN);
+  COCPop(cc);
+  tmpm=cc->htc.fun->member_lst_and_root;
+  while (tmpm) {
+    if (tmpm->flags & MLF_NO_UNUSED_WARN) {
+      if (tmpm->use_cnt>1&&StrCmp(tmpm->str,"_anon_"))
+        PrintWarn("Unneeded no_warn\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+              cc->lex_include_stk->full_name,cc->lex_include_stk->line_num,
+              tmpm->str,cc->htc.fun->str);
+    } else if (!tmpm->use_cnt && GetOption(OPTf_WARN_UNUSED_VAR))
+      PrintWarn("Unused var\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+            cc->lex_include_stk->full_name,cc->lex_include_stk->line_num,
+            tmpm->str,cc->htc.fun->str);
+    tmpm=tmpm->next;
+  }
+  cc->htc.local_var_lst=cc->htc.fun=cc->fun_lex_file=NULL;
+}
+
+U0 PrsGlblVarLst(CCmpCtrl *cc,I64 saved_mode,CHashClass *saved_tmpc,
+  I64 saved_val,I64 fsp_flags)
+{
+  I64 i,j,mode,k,val;
+  U8 *st;
+  CHashExport *tmpex;
+  CHashGlblVar *tmpg;
+  CAOTCtrl *aotc=cc->aotc;
+  CAOTHeapGlbl *tmphg;
+  CHashClass *tmpc;
+  CHashFun *tmpf,*tmpf_fun_ptr;
+  CArrayDim tmpad;
+  Bool has_alias,undef_array_size,is_array;
+  while (TRUE) {
+    tmpc=PrsType(cc,&saved_tmpc,&saved_mode,NULL,&st,
+          &tmpf_fun_ptr,&tmpex,&tmpad,fsp_flags);
+
+    if (!st) return;
+    if (tmpad.next)
+      is_array=TRUE;
+    else if (tmpad.total_cnt<0) {
+      is_array=TRUE;
+      tmpc--;
+    } else
+      is_array=FALSE;
+
+    val=saved_val;
+    mode=saved_mode;
+    if (tmpex && mode&255==PRS0_EXTERN && !(cc->flags&CCF_AOT_COMPILE) &&
+          tmpex->type&HTT_EXPORT_SYS_SYM) {
+      val=tmpex->val;
+      mode=PRS0__EXTERN|PRS1_NOT_REALLY__EXTERN;
+    }
+    if (cc->token=='(') {
+      switch (mode&255) {
+        case PRS0__INTERN:
+          tmpf=PrsFunJoin(cc,tmpc,st,fsp_flags);
+          tmpf->exe_addr=val;
+          Bts(&tmpf->flags,Ff_INTERNAL);
+          LBtr(&tmpf->flags,Cf_EXTERN);
+          return;
+        case PRS0__EXTERN:
+          if (!(fsp_flags&FSF__) && !(mode&PRS1_NOT_REALLY__EXTERN))
+            LexExcept(cc,"Expecting label with underscore at ");
+          tmpf=PrsFunJoin(cc,tmpc,st,fsp_flags);
+          tmpf->exe_addr=val;
+          SysSymImportsResolve(tmpf->str);
+          LBtr(&tmpf->flags,Cf_EXTERN);
+          if (saved_mode&255==PRS0__EXTERN)
+            LBts(&tmpf->flags,Ff__EXTERN);
+          if (cc->flags&CCF_AOT_COMPILE)
+            tmpf->type|=HTF_RESOLVE;
+          return;
+        case PRS0_EXTERN:
+          PrsFunJoin(cc,tmpc,st,fsp_flags);
+          return;
+        case PRS0__IMPORT:
+          if (!(fsp_flags&FSF__))
+            LexExcept(cc,"Expecting label with underscore at ");
+        case PRS0_IMPORT:
+          if (!(cc->flags&CCF_AOT_COMPILE))
+            LexExcept(cc,"import not needed at ");
+          else {
+            tmpf=PrsFunJoin(cc,tmpc,st,fsp_flags);
+            tmpf->type|=HTF_IMPORT;
+            if (mode&255==PRS0__IMPORT)
+              tmpf->import_name=StrNew(val);
+            else
+              tmpf->import_name=StrNew(st);
+          }
+          return;
+        default:
+          PrsFun(cc,tmpc,st,fsp_flags);
+          return;
+      }
+    } else {
+      if (tmpad.total_cnt<0) {
+        i=0;
+        undef_array_size=TRUE;
+      } else {
+        i=tmpad.total_cnt;
+        undef_array_size=FALSE;
+      }
+      if (tmpf_fun_ptr)
+        j=sizeof(U8 *);
+      else
+        j=tmpc->size;
+      j*=i;
+      has_alias=FALSE;
+      tmphg=NULL;
+      switch (mode&255) {
+        case PRS0__EXTERN:
+          if (cc->flags&CCF_AOT_COMPILE) {
+            tmpg=CAlloc(sizeof(CHashGlblVar));
+            tmpg->data_addr_rip=val;
+            tmpg->type=HTT_GLBL_VAR | HTF_EXPORT;
+          } else {
+            tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+            tmpg->data_addr=val;
+            tmpg->type=HTT_GLBL_VAR;
+          }
+          tmpg->flags|=GVF_ALIAS;
+          break;
+        case PRS0__IMPORT:
+        case PRS0_IMPORT:
+          if (!(cc->flags&CCF_AOT_COMPILE))
+            LexExcept(cc,"import not needed at ");
+          else {
+            tmpg=CAlloc(sizeof(CHashGlblVar));
+            tmpg->type=HTT_GLBL_VAR | HTF_IMPORT;
+            if (mode&255==PRS0__IMPORT)
+              tmpg->import_name=StrNew(val);
+            else
+              tmpg->import_name=StrNew(st);
+          }
+          break;
+        case PRS0_EXTERN:
+          if (cc->flags&CCF_AOT_COMPILE) {
+            tmpg=CAlloc(sizeof(CHashGlblVar));
+            tmpg->type=HTT_GLBL_VAR;
+          } else {
+            tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+            tmpg->type=HTT_GLBL_VAR|HTF_UNRESOLVED;
+          }
+          break;
+        default:
+          if (cc->flags&CCF_AOT_COMPILE) {
+            if (Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)) {
+              if (cc->token=='=')
+                LexExcept(cc,"Can't init glbl var on data heap in AOT module ");
+              tmpg=CAlloc(sizeof(CHashGlblVar));
+              tmphg=tmpg->heap_glbl=CAlloc(sizeof(CAOTHeapGlbl));
+              tmphg->size=j;
+              tmphg->str=StrNew(st);
+              tmphg->next=aotc->heap_glbls;
+              aotc->heap_glbls=tmphg;
+              tmpg->flags=GVF_DATA_HEAP;
+              tmpg->type=HTT_GLBL_VAR; //TODO: HTF_EXPORT
+              if (tmpex && tmpex->type & HTT_GLBL_VAR) //TODO!! extern
+                LexExcept(cc,"Feature not implemented ");
+            } else {
+              tmpg=CAlloc(sizeof(CHashGlblVar));
+              if (cc->token=='=')
+                tmpg->data_addr=CAlloc(j);
+              if (tmpc->size>=8) //align
+                while (aotc->rip&7)
+                  AOTStoreCodeU8(cc,0);
+              else if (tmpc->size==4)
+                while (aotc->rip&3)
+                  AOTStoreCodeU8(cc,0);
+              else if (tmpc->size==2)
+                while (aotc->rip&1)
+                  AOTStoreCodeU8(cc,0);
+              tmpg->data_addr_rip=aotc->rip;
+              tmpg->type=HTT_GLBL_VAR | HTF_EXPORT;
+              if (tmpex && tmpex->type & HTT_GLBL_VAR)
+                has_alias=TRUE;
+              for (k=0;k<j;k++)
+                AOTStoreCodeU8(cc,0); //Init AOT glbl to zero.
+            }
+          } else {
+            if (Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)) {
+              tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+              tmpg->data_addr=MAlloc(j);
+              tmpg->flags=GVF_DATA_HEAP;
+            } else {
+              tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+              tmpg->data_addr=MAlloc(j,Fs->code_heap);
+            }
+            tmpg->type=HTT_GLBL_VAR;
+            if (tmpex && tmpex->type&HTT_GLBL_VAR &&
+                  tmpex->type&HTF_UNRESOLVED &&
+                  MHeapCtrl(tmpex)==MHeapCtrl(tmpg))
+              has_alias=TRUE;
+            if (sys_var_init_flag)
+              MemSet(tmpg->data_addr,sys_var_init_val,j);
+          }
+      }
+      tmpg->dim.next=tmpad.next;
+      if (fsp_flags&FSF_PUBLIC)
+        tmpg->type|=HTF_PUBLIC;
+      tmpg->var_class=tmpc;
+      tmpg->str=st;
+      tmpg->size=j;
+      tmpg->dim.total_cnt=i;
+      tmpg->use_cnt=0;
+      if (cc->last_U16=='\n')
+        HashSrcFileSet(cc,tmpg,-1);
+      else
+        HashSrcFileSet(cc,tmpg,0);
+      if (mode&255==PRS0_IMPORT || mode&255==PRS0__IMPORT)
+        tmpg->flags|=GVF_IMPORT;
+      if (mode&255==PRS0_EXTERN)
+        tmpg->flags|=GVF_EXTERN;
+      if (tmpf_fun_ptr) {
+        tmpg->fun_ptr=tmpf_fun_ptr;
+        tmpg->flags|=GVF_FUN;
+      }
+      if (is_array)
+        tmpg->flags|=GVF_ARRAY;
+      HashAdd(tmpg,cc->htc.glbl_hash_table);
+      if (!(cc->flags&CCF_AOT_COMPILE) && !(tmpg->flags&GVF_EXTERN))
+        SysSymImportsResolve(tmpg->str);
+      if (cc->token=='=') {
+        if (undef_array_size) {
+          LexPush(cc);
+          LexPush(cc);
+          Lex(cc);
+          PrsGlblInit(cc,tmpg,1);
+          LexPopNoRestore(cc);
+          tmpg->size=tmpg->dim.total_cnt*tmpc->size;
+          if (tmphg)
+            tmphg->size=tmpg->size;
+          if (cc->flags&CCF_AOT_COMPILE)
+            for (k=0;k<tmpg->size;k++)
+              AOTStoreCodeU8(cc,0);
+          else
+            if (sys_var_init_flag)
+              MemSet(tmpg->data_addr,sys_var_init_val,k);
+          LexPopRestore(cc);
+        }
+        LexPush(cc);
+        Lex(cc);
+        PrsGlblInit(cc,tmpg,2);
+        if (cc->flags&CCF_AOT_COMPILE)
+          for (k=0;k<tmpg->size;k++)
+            AOTStoreCodeU8At(cc,tmpg->data_addr_rip+k,tmpg->data_addr[k]);
+        LexPopNoRestore(cc);
+      }
+      if (has_alias) {
+        if (tmpex(CHashGlblVar *)->use_cnt<2) {
+          PrintWarn("Unused extern '%s'\n",tmpex(CHashGlblVar *)->str);
+          cc->warning_cnt++;
+        }
+        tmpex(CHashGlblVar *)->flags|=GVF_ALIAS;
+        tmpex(CHashGlblVar *)->data_addr=tmpg->data_addr;
+        tmpex(CHashGlblVar *)->data_addr_rip=tmpg->data_addr_rip;
+      }
+      if (cc->token==',')
+        Lex(cc);
+      else {
+        if (cc->token!=';')
+          LexExcept(cc,"Missing ';' at");
+        Lex(cc);
+        return;
+      }
+    }
+  }
+}
+
+U0 PrsIf(CCmpCtrl *cc,I64 try_cnt,CCodeMisc *lb_break)
+{
+  CCodeMisc *lb,*lb1;
+  I64 k;
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  Lex(cc);
+  lb=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_BR_ZERO,lb,0);
+  PrsStmt(cc,try_cnt,lb_break);
+  k=PrsKeyWord(cc);
+  if (k==KW_ELSE) {
+    Lex(cc);
+    lb1=COCMiscNew(cc,CMT_LABEL);
+    ICAdd(cc,IC_JMP,lb1,0);
+    ICAdd(cc,IC_LABEL,lb,0);
+    PrsStmt(cc,try_cnt,lb_break);
+    ICAdd(cc,IC_LABEL,lb1,0);
+  } else
+    ICAdd(cc,IC_LABEL,lb,0);
+}
+
+U0 PrsWhile(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeMisc *lb,*lb_done;
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  lb=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_LABEL,lb,0);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  Lex(cc);
+  lb_done=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_BR_ZERO,lb_done,0);
+  PrsStmt(cc,try_cnt,lb_done);
+  ICAdd(cc,IC_JMP,lb,0);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+}
+
+U0 PrsDoWhile(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeMisc *lb,*lb_done;
+  lb=COCMiscNew(cc,CMT_LABEL);
+  lb_done=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_LABEL,lb,0);
+  PrsStmt(cc,try_cnt,lb_done);
+  if (PrsKeyWord(cc)!=KW_WHILE)
+    LexExcept(cc,"Missing 'while' at");
+  if (Lex(cc)!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  ICAdd(cc,IC_BR_NOT_ZERO,lb,0);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+  if (Lex(cc)!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+}
+
+U0 PrsFor(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeCtrl *tmpcbh;
+  CCodeMisc *lb,*lb_done;
+
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  PrsStmt(cc,try_cnt);
+
+  lb=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_LABEL,lb,0);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  lb_done=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_BR_ZERO,lb_done,0);
+  if (cc->token!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+
+  COCPush(cc);
+  COCInit(cc);
+  if (cc->token!=')')
+    PrsStmt(cc,try_cnt,NULL,0);
+  COCPush(cc);
+  tmpcbh=COCPopNoFree(cc);
+  COCPop(cc);
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  Lex(cc);
+
+  PrsStmt(cc,try_cnt,lb_done);
+  COCAppend(cc,tmpcbh);
+  ICAdd(cc,IC_JMP,lb,0);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+}
+
+class CSubSwitch {
+  CSubSwitch *next,*last;
+  CCodeMisc *lb_start,*lb_break;
+};
+
+class CSwitchCase {
+  CSwitchCase *next;
+  CCodeMisc *label;
+  I64 val;
+  CSubSwitch *ss;
+};
+
+U0 PrsSwitch(CCmpCtrl *cc,I64 try_cnt)
+{
+  CSwitchCase *header=NULL,*tmps,*tmps1;        //Leaks on except
+  CSubSwitch head,*tmpss;                       //Leaks on except
+  CCodeMisc *lb_dft,*lb_fwd_case,*mc_jt,*lb_entry,**jmp_table;
+  CIntermediateCode *tmpi_sub,*tmpi_cmp,*tmpi_jmp,*tmpi_start;
+  Bool dft_found=FALSE,nobound;
+  I64 i,k_start=I64_MIN,k_end,lo=I64_MAX,hi=I64_MIN,range;
+
+  if (cc->token=='(')
+    nobound=FALSE;
+  else if (cc->token=='[')
+    nobound=TRUE;
+  else
+    LexExcept(cc,"Expecting '(' or '[' at ");
+  Lex(cc);
+  QueInit(&head);
+
+  head.last->lb_break=COCMiscNew(cc,CMT_LABEL);
+  head.last->lb_break->use_cnt++;
+  lb_dft=COCMiscNew(cc,CMT_LABEL);
+  lb_dft->use_cnt++;
+  mc_jt=COCMiscNew(cc,CMT_JMP_TABLE);
+  mc_jt->begin=COCMiscNew(cc,CMT_LABEL);
+  mc_jt->begin->use_cnt++;
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  tmpi_sub=ICAdd(cc,IC_IMM_I64,0,cmp.internal_types[RT_I64]);
+  ICAdd(cc,IC_SUB,0,cmp.internal_types[RT_I64]);
+  tmpi_cmp=ICAdd(cc,IC_IMM_I64,0,cmp.internal_types[RT_I64]);
+  if (nobound) {
+    ICAdd(cc,IC_NOBOUND_SWITCH,mc_jt,0);
+    if (cc->token!=']')
+      LexExcept(cc,"Missing ']' at ");
+  } else {
+    ICAdd(cc,IC_SWITCH,mc_jt,0);
+    if (cc->token!=')')
+      LexExcept(cc,"Missing ')' at ");
+  }
+  if (Lex(cc)!='{')
+    LexExcept(cc,"Expecting '{' at ");
+  Lex(cc);
+  ICAdd(cc,IC_LABEL,mc_jt->begin,0);
+  while (TRUE) {
+    while (cc->token && cc->token!='}') {
+sw_cont:
+      switch (PrsKeyWord(cc)) {
+        case KW_END:
+          goto sw_sub_end;
+        case KW_START:
+          if (Lex(cc)==':')
+            Lex(cc);
+          else
+            LexExcept(cc,"Expecting ':' at ");
+          tmpss=MAlloc(sizeof(CSubSwitch));
+          QueIns(tmpss,head.last);
+          head.last->lb_break=COCMiscNew(cc,CMT_LABEL);
+          head.last->lb_break->use_cnt++;
+          lb_fwd_case=COCMiscNew(cc,CMT_LABEL);
+          tmpi_jmp=ICAdd(cc,IC_JMP,lb_fwd_case,0);
+
+          tmpss->lb_start=COCMiscNew(cc,CMT_LABEL);
+          tmpi_start=ICAdd(cc,IC_LABEL,tmpss->lb_start,0);
+          while (cc->token && cc->token!='}') {
+            switch (PrsKeyWord(cc)) {
+              case KW_END:
+                OptFree(tmpi_jmp);
+                goto sw_sub_end;
+              case KW_START:
+              case KW_CASE:
+              case KW_DFT:
+                if (cc->coc.coc_head.last==tmpi_start) {
+                  OptFree(tmpi_jmp);
+                  tmpss->lb_start=NULL;
+                } else {
+                  ICAdd(cc,IC_RET,0,0);
+                  ICAdd(cc,IC_LABEL,lb_fwd_case,0);
+                  ICAdd(cc,IC_SUB_CALL,tmpss->lb_start,0);//In case fall-thru
+                }
+                goto sw_cont;
+              default:
+                PrsStmt(cc,try_cnt);
+            }
+          }
+          break;
+        case KW_CASE:
+          if (head.next!=&head) {
+            lb_fwd_case=COCMiscNew(cc,CMT_LABEL);
+            tmpi_jmp=ICAdd(cc,IC_JMP,lb_fwd_case,0);//In case fall-thru
+          }
+          Lex(cc);
+          lb_entry=COCMiscNew(cc,CMT_LABEL);
+          ICAdd(cc,IC_LABEL,lb_entry,0);
+          lb_entry->use_cnt++;
+          if (head.next!=&head) {
+            tmpss=head.next;
+            while (tmpss!=&head) {
+              if (tmpss->lb_start)
+                ICAdd(cc,IC_SUB_CALL,tmpss->lb_start,0);
+              tmpss=tmpss->next;
+            }
+            ICAdd(cc,IC_LABEL,lb_fwd_case,0);
+          }
+          if (cc->token==':') {
+            if (k_start==I64_MIN)
+              k_start=0;
+            else
+              k_start++;
+          } else
+            k_start=LexExpressionI64(cc);
+          if (k_start<lo) lo=k_start;
+          if (k_start>hi) hi=k_start;
+          if (cc->token==':') {
+            Lex(cc);
+            tmps=MAlloc(sizeof(CSwitchCase));
+            tmps->label=lb_entry;
+            tmps->val=k_start;
+            tmps->next=header;
+            header=tmps;
+          } else if (cc->token==TK_ELLIPSIS) {
+            Lex(cc);
+            k_end=LexExpressionI64(cc);
+            if (cc->token==':') {
+              Lex(cc);
+              if (k_end<lo) lo=k_end;
+              if (k_end>hi) hi=k_end;
+              if (k_start>k_end)
+                SwapI64(&k_start,&k_end);
+              for (i=k_start;i<=k_end;i++) {
+                tmps=MAlloc(sizeof(CSwitchCase));
+                tmps->label=lb_entry;
+                tmps->val=i;
+                tmps->next=header;
+                header=tmps;
+              }
+              k_start=k_end;
+            } else
+              LexExcept(cc,"Expecting ':' at ");
+          } else
+            LexExcept(cc,"Expecting ':' at ");
+          break;
+        case KW_DFT:
+          if (head.next!=&head) {
+            lb_fwd_case=COCMiscNew(cc,CMT_LABEL);
+            tmpi_jmp=ICAdd(cc,IC_JMP,lb_fwd_case,0);//In case fall-thru
+          }
+          Lex(cc);
+          ICAdd(cc,IC_LABEL,lb_dft,0);
+          if (cc->token==':')
+            Lex(cc);
+          else
+            LexExcept(cc,"Expecting ':' at ");
+          if (head.next!=&head) {
+            tmpss=head.next;
+            while (tmpss!=&head) {
+              if (tmpss->lb_start)
+                ICAdd(cc,IC_SUB_CALL,tmpss->lb_start,0);
+              tmpss=tmpss->next;
+            }
+            ICAdd(cc,IC_LABEL,lb_fwd_case,0);
+          }
+          dft_found=TRUE;
+          break;
+        default:
+          PrsStmt(cc,try_cnt,head.last->lb_break);
+      }
+    }
+sw_sub_end:
+    tmpss=head.last;
+    ICAdd(cc,IC_LABEL,tmpss->lb_break,0);
+    if (tmpss==&head) {
+      if (cc->token!='}')
+        LexExcept(cc,"Missing '}' at ");
+      Lex(cc);
+      break;
+    } else {
+      QueRem(tmpss);
+      Free(tmpss);
+      if (PrsKeyWord(cc)!=KW_END)
+        LexExcept(cc,"Missing 'end' at ");
+      if (Lex(cc)==':')
+        Lex(cc);
+      else
+        LexExcept(cc,"Expecting ':' at ");
+    }
+  }
+  if (!dft_found)
+    ICAdd(cc,IC_LABEL,lb_dft,0);
+
+  if (0<lo<=16)
+    lo=0;
+  range=hi-lo+1;
+  if (lo>hi || !(0<range<=0xFFFF))
+    LexExcept(cc,"switch range error at ");
+  jmp_table=MAlloc((sizeof(CCodeMisc *)*range+0x1FF)&~0x1FF);
+  MemSetI64(jmp_table,lb_dft,range);
+  tmpi_sub->ic_data=lo;
+  tmpi_cmp->ic_data=range;
+  tmps=header;
+  while (tmps) {
+    tmps1=tmps->next;
+    if (jmp_table[tmps->val-lo]!=lb_dft)
+      LexExcept(cc,"Duplicate case at ");
+    else
+      jmp_table[tmps->val-lo]=tmps->label;
+    Free(tmps);
+    tmps=tmps1;
+  }
+  mc_jt->dft=lb_dft;
+  mc_jt->jmp_table=jmp_table;
+  mc_jt->range=range;
+}
+
+U0 PrsNoWarn(CCmpCtrl *cc)
+{
+  CMemberLst *tmpm;
+  while (cc->token==TK_IDENT) {
+    if (!(tmpm=cc->local_var_entry))
+      LexExcept(cc,"Expecting local var at ");
+    tmpm->flags|=MLF_NO_UNUSED_WARN;
+    if (Lex(cc)==',')
+      Lex(cc);
+    else if (cc->token!=';')
+      LexExcept(cc,"Expecting ',' at ");
+  }
+}
+
+U0 PrsStreamBlk(CCmpCtrl *cc)
+{
+  CLexHashTableContext *htc=MAlloc(sizeof(CLexHashTableContext));
+  CStreamBlk *tmpe=MAlloc(sizeof(CStreamBlk));
+  tmpe->body=StrNew("");
+  QueIns(tmpe,cc->last_stream_blk);
+  COCPush(cc);
+  QueInit(&cc->coc.coc_next_misc);
+
+  MemCpy(htc,&cc->htc,sizeof(CLexHashTableContext));
+  htc->old_flags=cc->flags;
+  cc->htc.next=htc;
+  cc->htc.fun=cc->htc.local_var_lst=NULL;
+  cc->htc.define_hash_table=cc->htc.hash_table_lst=
+        cc->htc.glbl_hash_table=cc->htc.local_hash_table=Fs->hash_table;
+  cc->flags=cc->flags & ~(CCF_ASM_EXPRESSIONS|CCF_AOT_COMPILE) | CCF_EXE_BLK;
+  if (cc->token=='{')
+    Lex(cc);
+  else
+    LexExcept(cc,"Missing '}' at ");
+  while (cc->token && cc->token!='}')
+    ExeCmdLine(cc);
+
+  MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
+  cc->flags=cc->flags&~CCF_EXE_BLK |
+        htc->old_flags & (CCF_ASM_EXPRESSIONS|CCF_EXE_BLK|CCF_AOT_COMPILE);
+  Free(htc);
+  COCPop(cc);
+  QueRem(tmpe);
+  if (*tmpe->body)
+    LexIncludeStr(cc,"StreamBlk",tmpe->body,FALSE);
+  else
+    Free(tmpe->body);
+  Free(tmpe);
+  Lex(cc); //Skip '}'
+}
+
+U0 PrsTryBlk(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeMisc     *lb_catch,*lb_done,*lb_untry;
+  CHashClass    *tmpc=cmp.internal_types[RT_PTR];
+  CHashFun      *tmp_try=HashFind("SysTry",cc->htc.hash_table_lst,HTT_FUN),
+        *tmp_untry=HashFind("SysUntry",cc->htc.hash_table_lst,HTT_FUN);
+
+  if (!tmp_try || !tmp_untry)
+    LexExcept(cc,"Missing header for SysTry() and SysUntry() at ");
+
+  cc->flags|=CCF_NO_REG_OPT; //TODO:Currently no reg vars in funs with try/catch
+
+  lb_catch=COCMiscNew(cc,CMT_LABEL);
+  lb_done =COCMiscNew(cc,CMT_LABEL);
+  lb_untry=COCMiscNew(cc,CMT_LABEL);
+
+  ICAdd(cc,IC_CALL_START,0,0);
+  ICAdd(cc,IC_GET_LABEL,lb_untry,tmpc,ICF_PUSH_RES);
+  ICAdd(cc,IC_GET_LABEL,lb_catch,tmpc,ICF_PUSH_RES);
+  if (Bt(&tmp_try->flags,Cf_EXTERN)) {
+    cc->abs_cnts.externs++;
+    if (cc->flags&CCF_AOT_COMPILE)
+      ICAdd(cc,IC_CALL_IMPORT,tmp_try,tmpc);
+    else
+      ICAdd(cc,IC_CALL_INDIRECT2,&tmp_try->exe_addr,tmpc);
+  } else
+    ICAdd(cc,IC_CALL,tmp_try->exe_addr,tmpc);
+  if ((Bt(&tmp_try->flags,Ff_RET1) ||
+        Bt(&tmp_try->flags,Ff_ARGPOP)) && !Bt(&tmp_try->flags,Ff_NOARGPOP))
+    ICAdd(cc,IC_ADD_RSP1,16,tmpc);
+  else
+    ICAdd(cc,IC_ADD_RSP,16,tmpc);
+  ICAdd(cc,IC_CALL_END,0,tmpc);
+  ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+
+  PrsStmt(cc,try_cnt+1);
+
+  ICAdd(cc,IC_LABEL,lb_untry,0);
+  ICAdd(cc,IC_CALL_START,0,0);
+  if (Bt(&tmp_untry->flags,Cf_EXTERN)) {
+    cc->abs_cnts.externs++;
+    if (cc->flags&CCF_AOT_COMPILE)
+      ICAdd(cc,IC_CALL_IMPORT,tmp_untry,tmpc);
+    else
+      ICAdd(cc,IC_CALL_INDIRECT2,&tmp_untry->exe_addr,tmpc);
+  } else
+    ICAdd(cc,IC_CALL,tmp_untry->exe_addr,tmpc);
+  ICAdd(cc,IC_CALL_END,0,tmpc);
+  ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+
+  ICAdd(cc,IC_JMP,lb_done,0);
+
+  if (PrsKeyWord(cc)!=KW_CATCH)
+    LexExcept(cc,"Missing 'catch' at");
+
+  Lex(cc);
+  ICAdd(cc,IC_LABEL,lb_catch,0);
+  PrsStmt(cc,try_cnt+1);
+  ICAdd(cc,IC_RET,0,tmpc);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+}
+
+Bool PrsStmt(CCmpCtrl *cc,I64 try_cnt=0,
+  CCodeMisc *lb_break=NULL,I64 cmp_flags=CMPF_PRS_SEMICOLON)
+{
+  I64 i,fsp_flags=0;
+  CHashExport *tmpex;
+  CCodeMisc *g_lb;
+  U8 *import_name;
+  CHashFun *tmp_untry;
+  CAOT *tmpaot;
+  if (cmp_flags&CMPF_ONE_ASM_INS) {
+    if (cc->flags&CCF_AOT_COMPILE || cc->aot_depth)
+      PrsAsmBlk(cc,CMPF_ONE_ASM_INS);
+    else if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK|CMPF_ONE_ASM_INS))
+      CmpFixUpJITAsm(cc,tmpaot);
+    fsp_flags=FSF_ASM;
+  } else
+    while (TRUE) {
+      while (cc->token==',')
+        Lex(cc);
+      if (cc->token=='{') {
+        Lex(cc);
+        while (cc->token!='}' && cc->token!=TK_EOF)
+          PrsStmt(cc,try_cnt,lb_break);
+        if (cc->lex_include_stk==cc->fun_lex_file)
+          cc->max_line=cc->lex_include_stk->line_num;
+        if (Lex(cc)!=',') goto sm_done;
+      } else if (cc->token==';') {
+        if (cmp_flags&CMPF_PRS_SEMICOLON)
+          Lex(cc);
+        if (cc->token!=',') goto sm_done;
+      } else {
+        if (cc->token==TK_IDENT) {
+          if (tmpex=cc->hash_entry) {
+            if (tmpex->type & HTT_KEYWORD) {
+              i=tmpex(CHashGeneric *)->user_data0;
+              switch [i] {
+                case KW_KWS_NUM-1: //nobound switch
+                default: //A keyword that is not valid here is just a symbol.
+                  goto sm_not_keyword_afterall;
+                start:
+                  case KW_ASM:
+                    if (cc->htc.fun) {
+                      if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK))
+                        ICAdd(cc,IC_ASM,tmpaot,0);
+                      Lex(cc); //Skip '}' of asm{}
+                    } else {
+                      if (cc->flags&CCF_AOT_COMPILE || cc->aot_depth) {
+                        Lex(cc);
+                        PrsAsmBlk(cc,0);
+                        if (cc->flags&CCF_AOT_COMPILE && cc->aot_depth==1)
+                          Lex(cc); //Skip '}' of asm{}
+                      } else {
+                        if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK))
+                          CmpFixUpJITAsm(cc,tmpaot);
+                        Lex(cc); //Skip '}' of asm{}
+                      }
+                      fsp_flags=FSF_ASM;
+                    }
+                    break;
+                  start:
+                    Lex(cc);
+                    case KW_LOCK:
+                      cc->lock_cnt++;
+                      PrsStmt(cc,try_cnt);
+                      cc->lock_cnt--;
+                      break;
+                    case KW_TRY:
+                      PrsTryBlk(cc,try_cnt);
+                      break;
+                    case KW_IF:
+                      PrsIf(cc,try_cnt,lb_break);
+                      break;
+                    case KW_FOR:
+                      PrsFor(cc,try_cnt);
+                      break;
+                    case KW_WHILE:
+                      PrsWhile(cc,try_cnt);
+                      break;
+                    case KW_DO:
+                      PrsDoWhile(cc,try_cnt);
+                      break;
+                    case KW_SWITCH:
+                      PrsSwitch(cc,try_cnt);
+                      break;
+                  end:
+                end:
+                  if (cc->token!=',') goto sm_done;
+                  break;
+                start:
+                  if (cc->htc.fun)
+                    LexExcept(cc,"Not allowed in fun");
+                  Lex(cc);
+                  case KW__EXTERN:
+                    if (Bt(&cc->opts,OPTf_EXTERNS_TO_IMPORTS))
+                      goto sm_underscore_import;
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & HTT_EXPORT_SYS_SYM))
+                      LexExcept(cc,"Expecting system sym at ");
+                    if (*cc->cur_str=='_')
+                      fsp_flags|=FSF__;
+                    i=tmpex->val;
+                    Lex(cc);
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0__EXTERN|PRS1_NULL,tmpex,i,fsp_flags);
+                    break;
+                  case KW__IMPORT:
+sm_underscore_import:
+                    if (cc->token!=TK_IDENT)
+                      LexExcept(cc,"Expecting system sym at ");
+                    if (*cc->cur_str=='_')
+                      fsp_flags|=FSF__;
+                    import_name=cc->cur_str;
+                    cc->cur_str=0;
+                    if (Lex(cc)!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0__IMPORT|PRS1_NULL,tmpex,
+                          import_name,fsp_flags);
+                    Free(import_name);
+                    break;
+                  case KW_EXTERN:
+                    if (cc->token!=TK_IDENT)
+                      LexExcept(cc,"Expecting type at ");
+                    tmpex=cc->hash_entry;
+                    i=PrsKeyWord(cc);
+                    if (i==KW_CLASS||i==KW_UNION) {
+                      Lex(cc);
+                      PrsClass(cc,i,fsp_flags,TRUE);
+                      fsp_flags&=FSF_ASM;
+                      goto sm_semicolon;
+                    }
+                    if (!tmpex ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    if (Bt(&cc->opts,OPTf_EXTERNS_TO_IMPORTS))
+                      goto sm_import;
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0_EXTERN|PRS1_NULL,tmpex,0,fsp_flags);
+                    break;
+                  case KW_IMPORT:
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+sm_import:
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0_IMPORT|PRS1_NULL,tmpex,0,fsp_flags);
+                    break;
+                  case KW__INTERN:
+                    i=LexExpressionI64(cc);
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0__INTERN|PRS1_NULL,tmpex,i,fsp_flags);
+                    break;
+                end:
+                  fsp_flags&=FSF_ASM;
+                  break;
+                start:
+                  case KW_STATIC:
+                    fsp_flags=FSF_STATIC|fsp_flags&FSF_ASM;
+                    break;
+                  case KW_INTERRUPT:
+                    fsp_flags=FSF_INTERRUPT|FSF_NOARGPOP|
+                          fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_HASERRCODE:
+                    fsp_flags=FSF_HASERRCODE|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_ARGPOP:
+                    fsp_flags=FSF_ARGPOP|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_NOARGPOP:
+                    fsp_flags=FSF_NOARGPOP|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_PUBLIC:
+                    fsp_flags=FSF_PUBLIC|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                end:
+                  Lex(cc);
+                  break;
+                case KW_RETURN:
+                  if (!cc->htc.fun)
+                    LexExcept(cc,"Not in fun.  Can't return a val ");
+                  if (try_cnt) {
+                    tmp_untry=HashFind("SysUntry",
+                          cc->htc.hash_table_lst,HTT_FUN);
+                    for (i=0;i<try_cnt;i++) {
+                      if (Bt(&tmp_untry->flags,Cf_EXTERN)) {
+                        cc->abs_cnts.externs++;
+                        if (cc->flags&CCF_AOT_COMPILE)
+                          ICAdd(cc,IC_CALL_IMPORT,
+                                tmp_untry,cmp.internal_types[RT_PTR]);
+                        else
+                          ICAdd(cc,IC_CALL_INDIRECT2,
+                                &tmp_untry->exe_addr,
+                                cmp.internal_types[RT_PTR]);
+                      } else
+                        ICAdd(cc,IC_CALL,tmp_untry->exe_addr,
+                              cmp.internal_types[RT_PTR]);
+                    }
+                  }
+                  if (Lex(cc)!=';') {
+                    if (!cc->htc.fun->return_class->size)
+                      LexWarn(cc,"Function should NOT return val ");
+                    if (!PrsExpression(cc,NULL,FALSE))
+                      throw('Compiler');
+                    ICAdd(cc,IC_RETURN_VAL,0,cc->htc.fun->return_class);
+                    cc->flags|=CCF_HAS_RETURN;
+                  } else if (cc->htc.fun->return_class->size)
+                    LexWarn(cc,"Function should return val ");
+                  ICAdd(cc,IC_JMP,cc->lb_leave,0);
+                  goto sm_semicolon;
+                case KW_GOTO:
+                  if (Lex(cc)!=TK_IDENT)
+                    LexExcept(cc,"Expecting identifier at ");
+                  if (!(g_lb=COCGoToLabelFind(cc,cc->cur_str))) {
+                    g_lb=COCMiscNew(cc,CMT_GOTO_LABEL);
+                    g_lb->str=cc->cur_str;
+                    cc->cur_str=NULL;
+                  }
+                  g_lb->use_cnt++;
+                  ICAdd(cc,IC_JMP,g_lb,0);
+                  Lex(cc);
+                  goto sm_semicolon;
+                case KW_BREAK:
+                  Lex(cc);
+                  if (!lb_break)
+                    LexExcept(cc,"'break' not allowed\n");
+                  ICAdd(cc,IC_JMP,lb_break,0);
+                  goto sm_semicolon;
+                case KW_NO_WARN:
+                  Lex(cc);
+                  PrsNoWarn(cc);
+                  goto sm_semicolon;
+                case KW_UNION:
+                case KW_CLASS:
+                  Lex(cc);
+                  tmpex=PrsClass(cc,i,fsp_flags,FALSE);
+                  if (!cc->htc.fun && cc->token!=';') {
+                    PrsGlblVarLst(cc,PRS0_NULL|PRS1_NULL,tmpex,0,fsp_flags);
+                    fsp_flags&=FSF_ASM;
+                    break;
+                  } else {
+                    fsp_flags&=FSF_ASM;
+                    goto sm_semicolon;
+                  }
+              }
+            } else {//Ident, found in hash table, not keyword
+sm_not_keyword_afterall:
+              if (tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)) {
+                if (cc->htc.fun) {
+                  if (fsp_flags&FSF_STATIC)
+                    PrsVarLst(cc,cc->htc.fun,PRS0_NULL|PRS1_STATIC_LOCAL_VAR);
+                  else
+                    PrsVarLst(cc,cc->htc.fun,PRS0_NULL|PRS1_LOCAL_VAR);
+                  if (cc->token=='}') goto sm_done;
+                } else {
+                  Lex(cc);
+                  PrsGlblVarLst(cc,PRS0_NULL|PRS1_NULL,tmpex,0,fsp_flags);
+                }
+              } else {
+                if (tmpex->type & (HTT_OPCODE|HTT_ASM_KEYWORD)) {
+                  if (cc->htc.fun) {
+                    if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK|CMPF_ONE_ASM_INS))
+                      ICAdd(cc,IC_ASM,tmpaot,0);
+                  } else
+                    LexExcept(cc,"Use Asm Blk at ");
+                  if (cc->token!=',') goto sm_done;
+                } else
+                  goto sm_prs_exp;
+              }
+              fsp_flags&=FSF_ASM;
+            }
+          } else {//Ident, not in hash table
+            if (cc->local_var_entry)
+              goto sm_prs_exp;
+            if (!(g_lb=COCGoToLabelFind(cc,cc->cur_str))) {
+              g_lb=COCMiscNew(cc,CMT_GOTO_LABEL);
+              g_lb->str=cc->cur_str;
+              cc->cur_str=NULL;
+            } else if (g_lb->flags&CMF_DEFINED)
+              LexExcept(cc,"Duplicate goto label at ");
+            g_lb->flags|=CMF_DEFINED;
+            ICAdd(cc,IC_LABEL,g_lb,0);
+            if (Lex(cc)==':') //skip cur_str
+              Lex(cc); //skip colon
+            else
+              LexExcept(cc,"Undefined identifier at ");
+            if (!cc->htc.fun)
+              LexExcept(cc,"No global labels at ");
+            if (cc->token!=',') goto sm_done;
+          }
+        } else if (cc->token==TK_STR||cc->token==TK_CHAR_CONST) {
+          PrsFunCall(cc,NULL,FALSE,NULL);
+          goto sm_semicolon;
+        } else if (cc->token!=TK_EOF) {//Non-cur_str symbol, num or something
+sm_prs_exp:
+          if (!PrsExpression(cc,NULL,TRUE))
+            throw('Compiler');
+sm_semicolon:
+          if (cmp_flags&CMPF_PRS_SEMICOLON) {
+            if (cc->token==';')
+              Lex(cc);
+            else if (cc->token!=',')
+              LexExcept(cc,"Missing ';' at");
+          }
+          if (cc->token!=',') goto sm_done;
+        } else
+          goto sm_done; //TK_EOF
+      }
+    }
+sm_done:
+  return fsp_flags&FSF_ASM;
+}
+
+ diff --git a/public/Wb/Compiler/PrsVar.HC.HTML b/public/Wb/Compiler/PrsVar.HC.HTML new file mode 100755 index 0000000..4581aa5 --- /dev/null +++ b/public/Wb/Compiler/PrsVar.HC.HTML @@ -0,0 +1,752 @@ + + + + + + + + + + + +
+U0 PrsVarInit(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,CArrayDim *tmpad,
+        U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass)
+{
+  U8 *dst=*_dst,*machine_code;
+  I64 i,j,r,old_flags,type,size;
+  CMemberLst *tmpm;
+  CIntermediateCode *tmpi;
+  CAOTCtrl *aotc=cc->aotc;
+  CAOTAbsAddr *tmpa;
+  CAOTImportExport *tmpie;
+  Bool is_str;
+
+  tmpc=OptClassFwd(tmpc);
+  if (tmpm=tmpc->member_lst_and_root) {
+    if (cc->token!='{')
+      LexExcept(cc,"Expecting '{' at ");
+    LexPopNoRestore(cc);
+    LexPush(cc);
+    Lex(cc);
+    while (tmpm) {
+      PrsVarInit2(cc,&dst,tmpm->member_class,&tmpm->dim,
+            data_addr_rip,_base,data_heap,pass);
+      if (cc->token==',')
+        Lex(cc);
+      tmpm=tmpm->next;
+    }
+    LexPopNoRestore(cc);
+    if (cc->token!='}')
+      LexExcept(cc,"Missing '}' at ");
+    Lex(cc);
+  } else {
+    if (tmpc->ptr_stars_cnt==1 &&
+          ((tmpc-1)->raw_type==RT_I8 || (tmpc-1)->raw_type==RT_U8) &&
+          !tmpad && cc->token==TK_STR)
+      is_str=TRUE;
+    else
+      is_str=FALSE;
+    if (cc->flags&CCF_AOT_COMPILE && is_str) {
+      LexPopNoRestore(cc);
+      machine_code=LexExtStr(cc,&i);
+      if (pass==2) {
+        tmpa=CAlloc(sizeof(CAOTAbsAddr));
+        tmpa->next=aotc->abss;
+        tmpa->type=AAT_ADD_U64;
+        aotc->abss=tmpa;
+        tmpa->rip=data_addr_rip+dst-*_base;
+        *dst(I64 *)=aotc->rip;
+        for (j=0;j<i;j++)
+          AOTStoreCodeU8(cc,machine_code[j]);
+      }
+      Free(machine_code);
+    } else {
+      old_flags=cc->flags;
+      cc->flags=CCF_NO_ABSS | cc->flags &
+            ~(CCF_AOT_COMPILE|CCF_HAS_MISC_DATA|CCF_NOT_CONST);
+      machine_code=LexExpression2Bin(cc,&type);
+      if (old_flags&CCF_AOT_COMPILE &&
+            cc->flags&CCF_NOT_CONST &&
+            !Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)) {
+        cc->flags=cc->flags&~CCF_NO_ABSS|CCF_AOT_COMPILE;
+        Free(machine_code);
+        if (pass==2) {
+          MemSet(dst,0,tmpc->size);
+          LexPopRestore(cc);
+          Lex(cc);
+          COCPush(cc);
+          COCInit(cc);
+          ICAdd(cc,IC_ABS_ADDR,data_addr_rip,tmpc+1);
+          ICAdd(cc,IC_IMM_I64,dst-*_base,tmpc+1);
+          ICAdd(cc,IC_ADD,0,tmpc+1);
+          if (!PrsExpression(cc,NULL,TRUE))
+            throw('Compiler');
+          tmpi=cc->coc.coc_head.last;
+          if (tmpi->ic_code==IC_END_EXP) {
+            tmpi->ic_code=IC_NOP1;
+            tmpi->ic_flags=0;
+          }
+          ICAdd(cc,IC_ASSIGN,0,tmpc);
+          ICAdd(cc,IC_END_EXP,0,tmpc,ICF_RES_NOT_USED);
+          ICAdd(cc,IC_RET,0,0);
+          if (machine_code=COCCompile(cc,&size,NULL,NULL)) {
+            tmpie=CAlloc(sizeof(CAOTImportExport));
+            tmpie->type=IET_MAIN;
+            tmpie->rip=cc->aotc->rip;
+            QueIns(tmpie,cc->aot->last_ie);
+            for (i=0;i<size;i++)
+              AOTStoreCodeU8(cc,machine_code[i]);
+            Free(machine_code);
+          }
+          COCPop(cc);
+        } else
+          LexPopNoRestore(cc);
+      } else {
+        LexPopNoRestore(cc);
+        if (!machine_code)
+          throw('Compiler');
+        r=Call(machine_code);
+        if (!(cc->flags & CCF_HAS_MISC_DATA)||pass==1)
+          Free(machine_code);
+
+        if (type==RT_F64 &&
+              tmpc->raw_type!=RT_F64)
+          r=r(F64);
+        else if (type!=RT_F64 &&
+              tmpc->raw_type==RT_F64)
+          r(F64)=r;
+        MemCpy(dst,&r,tmpc->size);
+      }
+    }
+    dst+=tmpc->size;
+    cc->flags=cc->flags&
+          ~CCF_NO_ABSS|old_flags&(CCF_HAS_MISC_DATA|CCF_AOT_COMPILE);
+  }
+  *_dst=dst;
+}
+
+class CVI2
+{
+  CVI2 *next,*last;
+  U0 base;
+};
+
+U0 PrsVarInit2(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,
+        CArrayDim *tmpad,U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass)
+{
+  I64 i,j,cnt;
+  U8 *st,*_b;
+  CVI2 head,*tmpvi,*tmpvi1;
+  CArrayDim *tmpad1;
+  tmpc=OptClassFwd(tmpc);
+  if (tmpad1=tmpad->next) {
+    if (!tmpc->ptr_stars_cnt &&
+          (tmpc->raw_type==RT_I8 || tmpc->raw_type==RT_U8) &&
+          cc->token==TK_STR) {
+      LexPopNoRestore(cc);
+      st=LexExtStr(cc,&i);
+      if (tmpad1->cnt<0) {//[]
+        tmpad1->cnt=i;
+        tmpad->total_cnt=i*tmpad1->total_cnt;
+        Free(*_base);
+        if (data_heap)
+          *_base=MAlloc(i);
+        else
+          *_base=MAlloc(i,Fs->code_heap);
+        MemCpy(*_base,st,i);
+        *_dst=*_base+i;
+      } else {
+        MemCpy(*_dst,st,tmpad1->cnt);
+        *_dst+=tmpad1->cnt;
+      }
+      Free(st);
+      LexPush(cc);
+    } else {
+      if (cc->token=='{') {
+        LexPopNoRestore(cc);
+        LexPush(cc);
+        Lex(cc);
+      }
+      if (tmpad1->cnt<0) {//[]
+        QueInit(&head);
+        cnt=0;
+        while (cc->token!='}') {
+          tmpvi=MAlloc(offset(CVI2.base)+tmpad1->total_cnt*tmpc->size);
+          _b=&tmpvi->base;
+          PrsVarInit2(cc,&_b,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
+          QueIns(tmpvi,head.last);
+          if (cc->token==',')
+            Lex(cc);
+          cnt++;
+        }
+        Lex(cc); //skip '}'
+        tmpad1->cnt=cnt;
+        tmpad->total_cnt=cnt*tmpad1->total_cnt;
+        j=tmpad1->total_cnt*tmpc->size;
+        i=cnt*j;
+        Free(*_base);
+        if (data_heap)
+          *_base=_b=MAlloc(i);
+        else
+          *_base=_b=MAlloc(i,Fs->code_heap);
+        tmpvi=head.next;
+        while (tmpvi!=&head) {
+          tmpvi1=tmpvi->next;
+          MemCpy(_b,&tmpvi->base,j);
+          _b+=j;
+          Free(tmpvi);
+          tmpvi=tmpvi1;
+        }
+        *_dst=_b;
+      } else {
+        for (i=0;i<tmpad1->cnt;i++) {
+          PrsVarInit2(cc,_dst,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
+          if (tmpad1->cnt>1 && cc->token==',')
+            Lex(cc);
+        }
+        if (cc->token=='}')
+          Lex(cc);
+      }
+    }
+  } else {
+    PrsVarInit(cc,_dst,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
+    LexPush(cc);
+  }
+}
+
+U0 PrsGlblInit(CCmpCtrl *cc,CHashGlblVar *tmpg,I64 pass)
+{
+  U8 *dst=tmpg->data_addr;
+  PrsVarInit2(cc,&dst,tmpg->var_class,&tmpg->dim,
+        tmpg->data_addr_rip,&tmpg->data_addr,
+        Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)||
+        Bt(&cc->flags,CCf_AOT_COMPILE),pass);
+}
+
+U0 PrsStaticInit(CCmpCtrl *cc,CMemberLst *tmpm,I64 pass)
+{
+  U8 *machine_code,*dst=tmpm->static_data;
+  CHashClass *tmpc=tmpm->member_class;
+  I64 i,size;
+  CAOTImportExport *tmpie;
+
+  if (cc->flags&CCF_AOT_COMPILE && pass==2) {
+    COCPush(cc);
+    COCInit(cc);
+  }
+  PrsVarInit2(cc,&dst,tmpc,&tmpm->dim,tmpm->static_data_rip,
+        &tmpm->static_data,Bt(&cc->flags,CCf_AOT_COMPILE),pass);
+  if (cc->flags&CCF_AOT_COMPILE && pass==2) {
+    if (cc->coc.coc_head.next!=&cc->coc.coc_head) {
+      ICAdd(cc,IC_RET,0,0);
+      if (machine_code=COCCompile(cc,&size,NULL,NULL)) {
+        if (pass==2) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_MAIN;
+          tmpie->rip=cc->aotc->rip;
+          QueIns(tmpie,cc->aot->last_ie);
+          for (i=0;i<size;i++)
+            AOTStoreCodeU8(cc,machine_code[i]);
+        }
+        Free(machine_code);
+      }
+    } //TODO: else del misc?
+    COCPop(cc);
+  }
+}
+
+U0 PrsArrayDims(CCmpCtrl *cc,I64 mode,CArrayDim *dim)
+{//dim->next!=0 for array
+  CArrayDim *tmpad,*tmpad1;
+  I64 j;
+  dim->next=NULL;
+  dim->cnt=0;
+  dim->total_cnt=1;
+  tmpad1=&dim->next;
+  if (cc->token=='[') {
+    if (mode.u8[1]==PRS1B_FUN_ARG)
+      LexExcept(cc,"No arrays in fun args at ");
+    do {
+      if (Lex(cc)==']' && !dim->next)
+        j=0;
+      else {
+        if ((j=LexExpressionI64(cc))<0)
+          LexExcept(cc,"Invalid array size at ");
+      }
+      tmpad=MAlloc(sizeof(CArrayDim));
+      tmpad->next=NULL;
+      tmpad1=&dim;
+      do {
+        tmpad1->total_cnt*=j;
+        if (!tmpad1->next) {
+          tmpad1->next=tmpad;
+          break;
+        }
+        tmpad1=tmpad1->next;
+      } while (tmpad1);
+      tmpad1=tmpad;
+      tmpad->cnt=j;
+      tmpad->total_cnt=1;
+      if (cc->token!=']')
+        LexExcept(cc,"Missing ']' at ");
+    } while (Lex(cc)=='[');
+  }
+}
+
+CHashClass *PrsType(CCmpCtrl *cc,CHashClass **_tmpc1,
+  I64 *_mode,CMemberLst *tmpm,U8 **_ident,CHashFun **_fun_ptr,
+  CHashExport **_tmpex,CArrayDim *tmpad,I64 fsp_flags)
+{
+  I64 k,ptr_stars_cnt,mode=*_mode;
+  CHashClass *tmpc1=*_tmpc1,*tmpc2;
+  CHashFun *fun_ptr=NULL;
+  CHashExport *tmpex=NULL;
+
+  pt_start:
+  if (!tmpc1 || !(tmpc1->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+    LexExcept(cc,"Invalid class at ");
+
+  ptr_stars_cnt=0;
+  while (cc->token=='*') {
+    if (mode.u8[1]) {
+      LexPopNoRestore(cc);
+      LexPush(cc);
+    }
+    Lex(cc);
+    tmpc1++;
+    if (++ptr_stars_cnt>PTR_STARS_NUM)
+      LexExcept(cc,"Too many *'s at ");
+  }
+
+  k=PrsKeyWord(cc);
+  if (k==KW_UNION || k==KW_CLASS) {
+    Lex(cc);
+    tmpc2=PrsClass(cc,k,fsp_flags,mode&255==PRS0_EXTERN);
+    tmpc2->fwd_class=tmpc1;
+    tmpc1=tmpc2;
+    if (_tmpc1) *_tmpc1=tmpc1;
+    mode=PRS0_NULL|PRS1_NULL;
+    goto pt_start;
+  }
+
+  if (cc->token=='(') {
+    if (Lex(cc)!='*')
+      LexExcept(cc,"Expecting '*' at ");
+    ptr_stars_cnt=1; //fun_ptr
+    while (Lex(cc)=='*')
+      ptr_stars_cnt++; //fun_ptr
+    if (ptr_stars_cnt>PTR_STARS_NUM)
+      LexExcept(cc,"Too many *'s at ");
+  } else
+    ptr_stars_cnt=-1; //fun_ptr
+
+  if (_ident) {
+    if (cc->token==TK_IDENT) {
+      tmpex=cc->hash_entry;
+      *_ident=cc->cur_str;
+      cc->cur_str=NULL;
+      Lex(cc);
+    } else {
+      if (!mode.u8[1])
+        *_ident=NULL;
+      else if (cc->token==',' || cc->token==';' || cc->token==')') {
+        tmpex=NULL;
+        *_ident=StrNew("_anon_");
+        tmpm->flags|=MLF_NO_UNUSED_WARN;
+      } else
+        LexExcept(cc,"Expecting identifier at ");
+    }
+  }
+
+  if (ptr_stars_cnt>=0) { //fun_ptr
+    if (cc->token!=')')
+      LexExcept(cc,"Missing ')' at ");
+    if (Lex(cc)!='(')
+      LexExcept(cc,"Expecting '(' at ");
+    fun_ptr=PrsFunJoin(cc,tmpc1,NULL,fsp_flags)+ptr_stars_cnt;
+    tmpc1=cmp.internal_types[RT_PTR]+ptr_stars_cnt;
+  }
+  PrsArrayDims(cc,mode,tmpad);
+
+  tmpc2=OptClassFwd(tmpc1);
+  if (tmpc2->ptr_stars_cnt) {
+    tmpc2-=tmpc2->ptr_stars_cnt;
+    if (tmpc2->type&HTT_INTERNAL_TYPE && !tmpc2->size)
+      LexWarn(cc,"use \"U8 *\" instead of \"U0 *\" at ");
+  }
+
+  if (_mode)    *_mode=mode;
+  if (_fun_ptr) *_fun_ptr=fun_ptr;
+  if (_tmpex)   *_tmpex=tmpex;
+  return tmpc1;
+}
+
+U0 PrsDotDotDot(CCmpCtrl *cc,CHashFun *tmpf,I64 _reg)
+{
+  CMemberLst *tmpm;
+  CArrayDim *tmpad;
+
+  Bts(&tmpf->flags,Ff_DOT_DOT_DOT);
+
+  Lex(cc);
+  tmpm=MemberLstNew(_reg);
+  tmpm->flags=MLF_DOT_DOT_DOT;
+  tmpm->member_class=cmp.internal_types[RT_I64];
+  tmpm->str=StrNew("argc");
+  tmpm->offset=tmpf->size;
+  tmpm->size=8;
+  tmpf->size+=8;
+  MemberAdd(cc,tmpm,tmpf,PRS1B_FUN_ARG);
+
+  tmpm=MemberLstNew(_reg);
+  tmpm->flags=MLF_DOT_DOT_DOT;
+  tmpm->member_class=cmp.internal_types[RT_I64];
+  tmpm->str=StrNew("argv");
+  tmpm->dim.total_cnt=127; //arbitrary
+  tmpm->dim.next=tmpad=MAlloc(sizeof(CArrayDim));
+  tmpad->next=NULL;
+  tmpad->cnt=127; //arbitrary
+  tmpad->total_cnt=1;
+  tmpm->offset=tmpf->size;
+  tmpm->size=8; //Close enough
+  tmpf->size+=8;//Close enough
+  MemberAdd(cc,tmpm,tmpf,PRS1B_FUN_ARG);
+
+  if (cc->token==')')
+    Lex(cc);
+}
+
+U0 PrsVarLst(CCmpCtrl *cc,CHashClass *tmpc,I64 mode,I64 union_base=0)
+{
+  I64 i,k,old_flags=cc->flags,old_flags2,type,_reg;
+  CHashClass *tmpc1,*tmpc2;
+  CHash *tmph;
+  CMemberLst *tmpm;
+  CMemberLstMeta *tmp_meta;
+  U8 *machine_code;
+  Bool undef_array_size,first;
+  cc->flags|=CCF_DONT_MAKE_RES;
+  if (mode.u8[1]==PRS1B_CLASS)
+    cc->flags|=CCF_CLASS_DOL_OFFSET;
+  if ((mode.u8[1]!=PRS1B_LOCAL_VAR && mode.u8[1]!=PRS1B_STATIC_LOCAL_VAR ||
+        mode&PRSF_UNION) && (cc->token=='(' || cc->token=='{'))
+    Lex(cc);
+  while (TRUE) {
+    if (mode&PRSF_UNION)
+      cc->class_dol_offset=union_base;
+    else
+      cc->class_dol_offset=tmpc->size;
+    while (cc->token==';')
+      Lex(cc);
+    while (cc->token=='$') {
+      if (Lex(cc)!='=') //skip $
+        LexExcept(cc,"Expecting '=' at ");
+      Lex(cc); //skip =
+      cc->class_dol_offset=LexExpression(cc);
+      if (-cc->class_dol_offset>tmpc->neg_offset)
+        tmpc->neg_offset=-cc->class_dol_offset;
+      if (mode&PRSF_UNION)
+        union_base=cc->class_dol_offset;
+      else
+        tmpc->size=cc->class_dol_offset;
+      if (cc->token!=';')
+        LexExcept(cc,"Missing ';' at");
+      Lex(cc); //skip ;
+    }
+    if (cc->token==')' || cc->token=='}') {
+      Lex(cc);
+      goto pvl_done;
+    }
+    _reg=REG_UNDEF;
+pvl_restart1:
+    switch (PrsKeyWord(cc)) {
+      case KW_REG:
+        _reg=REG_ALLOC;
+        if (Lex(cc)==TK_IDENT) {
+          k=DefineMatch(cc->cur_str,"ST_U64_REGS");
+          if (k>=0) {
+            _reg=k;
+            Lex(cc);
+          }
+        }
+        goto pvl_restart1;
+      case KW_NOREG:
+        _reg=REG_NONE;
+        Lex(cc);
+        goto pvl_restart1;
+    }
+
+    if (cc->token==TK_ELLIPSIS && mode.u8[1]==PRS1B_FUN_ARG) {
+      PrsDotDotDot(cc,tmpc,_reg);
+      goto pvl_done;
+    }
+    if (cc->token==TK_IDENT)
+      tmph=cc->hash_entry;
+    else
+      tmph=NULL;
+    if (!tmph)
+      LexExcept(cc,"Expecting type at ");
+    k=PrsKeyWord(cc);
+    if (k==KW_UNION) {
+      Lex(cc);
+      PrsVarLst(cc,tmpc,mode|PRSF_UNION,tmpc->size);
+    } else {
+      if (!(tmph->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+        LexExcept(cc,"Expecting type at ");
+      first=TRUE;
+pvl_restart2:
+      tmpc1=tmph;
+      LexPush(cc);
+      Lex(cc); //skip type or ','
+      tmpm=MemberLstNew(_reg);
+      _reg=REG_UNDEF;
+      if (mode.u8[1]==PRS1B_STATIC_LOCAL_VAR) {
+        tmpm->flags|=MLF_STATIC;
+        tmpm->reg=REG_NONE;
+      }
+      if (mode.u8[1]==PRS1B_FUN_ARG || mode.u8[1]==PRS1B_LOCAL_VAR) {
+pvl_restart3:
+        switch (PrsKeyWord(cc)) {
+          case KW_REG:
+            tmpm->reg=REG_ALLOC;
+            LexPopNoRestore(cc);
+            LexPush(cc);
+            if (Lex(cc)==TK_IDENT) {
+              k=DefineMatch(cc->cur_str,"ST_U64_REGS");
+              if (k>=0) {
+                tmpm->reg=k;
+                LexPopNoRestore(cc);
+                LexPush(cc);
+                Lex(cc);
+              }
+            }
+            goto pvl_restart3;
+          case KW_NOREG:
+            tmpm->reg=REG_NONE;
+            LexPopNoRestore(cc);
+            LexPush(cc);
+            Lex(cc);
+            goto pvl_restart3;
+        }
+      }
+      tmpm->member_class=PrsType(cc,&tmpc1,&mode,tmpm,&tmpm->str,
+            &tmpm->fun_ptr,NULL,&tmpm->dim,0);
+      if (tmpm->fun_ptr)
+        tmpm->flags|=MLF_FUN;
+      if (first)
+        MemberAdd(cc,tmpm,tmpc,mode.u8[1]);
+      else
+        MemberAdd(cc,tmpm,tmpc,PRS1B_NULL);
+      tmpc->member_cnt++;
+
+      tmpc2=tmpm->member_class;
+      i=tmpc2->size*tmpm->dim.total_cnt;
+      switch (mode.u8[1]) {
+        case PRS1B_STATIC_LOCAL_VAR:
+          if (i<0) {
+            i=0;
+            undef_array_size=TRUE;
+          } else
+            undef_array_size=FALSE;
+          if (mode&PRSF_UNION)
+            LexExcept(cc,"Static unions are not implemented ");
+          k=(i+7)&~7;
+          if (cc->flags&CCF_AOT_COMPILE)
+            tmpm->static_data=MAlloc(k);
+          else
+            tmpm->static_data=MAlloc(k,Fs->code_heap);
+          if (cc->flags&CCF_AOT_COMPILE)        {
+            tmpm->static_data_rip=cc->aotc->rip;
+            k>>=3;
+            while (k--)
+              AOTStoreCodeU64(cc,0);
+          } else
+            if (sys_var_init_flag)
+              MemSet(tmpm->static_data,sys_var_init_val,k);
+          LexPopNoRestore(cc);
+          if (cc->token=='=') {
+            cc->flags=cc->flags&
+                  ~CCF_DONT_MAKE_RES|old_flags&CCF_DONT_MAKE_RES;
+            if (undef_array_size) {
+              LexPush(cc);
+              LexPush(cc);
+              Lex(cc); //skip =
+              PrsStaticInit(cc,tmpm,1);
+              LexPopNoRestore(cc);
+              i=tmpc2->size*tmpm->dim.total_cnt;
+              k=(i+7)&~7;
+              if (cc->flags&CCF_AOT_COMPILE)    {
+                k>>=3;
+                while (k--)
+                  AOTStoreCodeU64(cc,0);
+              } else
+                if (sys_var_init_flag)
+                  MemSet(tmpm->static_data,sys_var_init_val,k);
+              LexPopRestore(cc);
+            }
+            LexPush(cc);
+            Lex(cc); //skip =
+            PrsStaticInit(cc,tmpm,2);
+            LexPopNoRestore(cc);
+            if (cc->flags&CCF_AOT_COMPILE)
+              for (k=0;k<i;k++)
+                AOTStoreCodeU8At(cc,tmpm->static_data_rip+k,
+                      tmpm->static_data[k]);
+            tmpm->use_cnt=0;
+            cc->flags|=CCF_DONT_MAKE_RES;
+          }
+          if (cc->flags&CCF_AOT_COMPILE)
+            Free(tmpm->static_data);
+          break;
+        case PRS1B_LOCAL_VAR:
+          if (mode&PRSF_UNION) {
+            if (union_base-tmpc->size<i)
+              i=union_base-i-tmpc->size;
+            else
+              i=0;
+          }
+          if (i>=8)
+            tmpc->size=(tmpc->size-i)&~7;
+          else if (i>=4)
+            tmpc->size=(tmpc->size-i)&~3;
+          else if (i>=2)
+            tmpc->size=(tmpc->size-i)&~1;
+          else
+            tmpc->size-=i;
+          tmpm->offset=tmpc->size;
+          tmpm->size=i;
+          if (cc->token=='=') {
+            cc->flags=cc->flags&~CCF_DONT_MAKE_RES|
+                  old_flags&CCF_DONT_MAKE_RES;
+            LexPopRestore(cc);
+            Lex(cc);
+            if (!PrsExpression(cc,NULL,TRUE))
+              throw('Compiler');
+            tmpm->use_cnt=0;
+            cc->flags|=CCF_DONT_MAKE_RES;
+          } else
+            LexPopNoRestore(cc);
+          break;
+        case PRS1B_FUN_ARG:
+          if (mode&PRSF_UNION) {
+            tmpm->offset=union_base;
+            if (tmpc->size-union_base<8)
+              tmpc->size=8+union_base;
+          } else {
+            tmpm->offset=tmpc->size;
+            tmpc->size+=8;
+          }
+          tmpm->size=8;
+          if (cc->token=='=') {
+            Lex(cc);
+            if (PrsKeyWord(cc)==KW_LASTCLASS) {
+              tmpm->flags|=MLF_LASTCLASS;
+              Lex(cc);
+            } else {
+              old_flags2=cc->flags;
+              cc->flags&=~CCF_HAS_MISC_DATA;
+              machine_code=LexExpression2Bin(cc,&type);
+              if (!machine_code)
+                throw('Compiler');
+              tmpm->dft_val=Call(machine_code);
+              tmpc2=OptClassFwd(tmpc2);
+              if (tmpc2->raw_type==RT_F64) {
+                if (type!=RT_F64)
+                  tmpm->dft_val(F64)=tmpm->dft_val;
+              } else {
+                if (type==RT_F64)
+                  tmpm->dft_val=tmpm->dft_val(F64);
+              }
+              if (cc->flags & CCF_HAS_MISC_DATA) {
+                tmpm->dft_val=StrNew(tmpm->dft_val);
+                tmpm->flags|=MLF_STR_DFT_AVAILABLE;
+              }
+              Free(machine_code);
+              cc->flags|=old_flags2&CCF_HAS_MISC_DATA;
+            }
+            tmpm->flags|=MLF_DFT_AVAILABLE;
+          }
+          LexPopNoRestore(cc);
+          break;
+        case PRS1B_CLASS:
+          if (mode&PRSF_UNION) {
+            tmpm->offset=union_base;
+            if (tmpc->size-union_base<i)
+              tmpc->size=i+union_base;
+          } else {
+            tmpm->offset=tmpc->size;
+            tmpc->size+=i;
+          }
+          tmpm->size=i;
+          if (mode&PRSF_UNION)
+            cc->class_dol_offset=union_base;
+          else
+            cc->class_dol_offset=tmpc->size;
+
+          while (cc->token==TK_IDENT) {
+            tmp_meta=MAlloc(sizeof(CMemberLstMeta));
+            tmp_meta->next=tmpm->meta;
+            tmpm->meta=tmp_meta;
+            tmp_meta->str=cc->cur_str;
+            tmp_meta->flags=0;
+            cc->cur_str=NULL;
+            if (Lex(cc)==TK_STR) {
+              tmp_meta->user_data=LexExtStr(cc);
+              tmp_meta->flags|=MLMF_IS_STR;
+            } else
+              tmp_meta->user_data=LexExpression(cc);
+          }
+          LexPopNoRestore(cc);
+          break;
+      }
+      switch (cc->token) {
+        case ',':
+          if (mode.u8[1]==PRS1B_FUN_ARG && !(mode&PRSF_UNION))
+            Lex(cc);
+          else {
+            first=FALSE;
+            goto pvl_restart2;
+          }
+          break;
+        case ')':
+        case '}':
+          Lex(cc);
+          goto pvl_done;
+        case ';':
+          cc->flags=cc->flags&~CCF_DONT_MAKE_RES|
+                old_flags&CCF_DONT_MAKE_RES;
+          Lex(cc);
+          cc->flags|=CCF_DONT_MAKE_RES;
+          if ((mode.u8[1]==PRS1B_LOCAL_VAR||mode.u8[1]==
+                PRS1B_STATIC_LOCAL_VAR) && !(mode&PRSF_UNION))
+            goto pvl_done;
+          break;
+        default:
+          LexExcept(cc,"Missing ';' at");
+      }
+    }
+  }
+pvl_done:
+  cc->flags=cc->flags&~(CCF_CLASS_DOL_OFFSET|CCF_DONT_MAKE_RES)|
+        old_flags&(CCF_CLASS_DOL_OFFSET|CCF_DONT_MAKE_RES);
+}
+
+ diff --git a/public/Wb/Compiler/Templates.HC.HTML b/public/Wb/Compiler/Templates.HC.HTML new file mode 100755 index 0000000..4afeb40 --- /dev/null +++ b/public/Wb/Compiler/Templates.HC.HTML @@ -0,0 +1,543 @@ + + + + + + + + + + + +
+asm {
+//************************************
+CMP_TEMPLATES::
+        DU32    @@05,@@10,@@15,@@25,@@30,
+                @@35,@@40,@@45,@@55,@@60,
+                @@75,@@80,@@85,@@90,@@95,
+                @@100,@@105,@@110,@@120,@@130;
+
+@@05:   //INC
+        PUSH    RAX
+        FLD1
+        FADD    ST0,U64 [RSP]
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        PUSH    RAX
+        FLD1
+        FSUBR   ST0,U64 [RSP]
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@15:   //MOD
+        PUSH    RDX
+        PUSH    RAX
+        MOV     RBX,RSP
+        FLD     U64 [RBX]
+        FLD     U64 8[RBX]
+@@20:   FPREM
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@20
+        FSTP    U64 [RBX]
+        FFREE   ST0
+        FINCSTP
+        POP     RAX
+        ADD     RSP,8
+
+@@25:   //LESS
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD     U64 8[RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@30:   //GREATER
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 8[RSP]
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@35:   //LESS_EQU
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 8[RSP]
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@40:   //GREATER_EQU
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD     U64 8[RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@45: //StrLen
+        MOV     RDX,RAX
+@@50:   MOV     BL,U8 [RAX]
+        INC     RAX
+        TEST    BL,BL
+        JNZ     @@50
+        SUB     RAX,RDX
+        DEC     RAX
+
+@@55: //RDTSC
+        RDTSC
+        SHL     RDX,32
+        ADD     RAX,RDX
+
+@@60: //SignI64
+        TEST    RAX,RAX
+        JZ      @@70
+        JS      @@65
+        MOV     RAX,1
+        JMP     @@70
+@@65:   MOV     RAX,-1
+@@70:
+@@75:
+@@80:
+@@85: //Sqr
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FMUL    ST0,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@90: //Abs
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FABS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@95: //Sqrt
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSQRT
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@100: //Sin
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSIN
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@105: //Cos
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@110: //Tan
+        PUSH    RAX
+        FLD     U64 [RSP]
+@@115:  FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@115
+        FFREE   ST0
+        FINCSTP
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@120: //Atan
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD1
+@@125:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@125
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@130:
+
+//************************************
+CMP_TEMPLATES_DONT_POP::
+        DU32    @@05,@@10,@@15,@@20,@@25,
+                @@30,@@35,@@40,@@45,@@50,
+                @@55,@@60,@@65,@@70,@@75,
+                @@80,@@85,@@90,@@100,@@110;
+
+@@05:   //INC
+        PUSH    RAX
+        FLD1
+        FADD    ST0,U64 [RSP]
+        FST     U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        PUSH    RAX
+        FLD1
+        FSUBR   ST0,U64 [RSP]
+        FST     U64 [RSP]
+        POP     RAX
+
+@@15:
+@@20:
+@@25:
+@@30:
+@@35:
+@@40:
+@@45:
+@@50:
+@@55:
+@@60:
+        PUSH    RAX
+        FLD     U64 [RSP]
+        ADD     RSP,8
+
+@@65: //Sqr
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FMUL    ST0,ST0
+        ADD     RSP,8
+
+@@70: //Abs
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FABS
+        ADD     RSP,8
+
+@@75: //Sqrt
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSQRT
+        ADD     RSP,8
+
+@@80: //Sin
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSIN
+        ADD     RSP,8
+
+@@85: //Cos
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOS
+        ADD     RSP,8
+
+@@90: //Tan
+        PUSH    RAX
+        FLD     U64 [RSP]
+@@95:   FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@95
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@100: //Atan
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD1
+@@105:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@105
+        ADD     RSP,8
+@@110:
+
+//************************************
+CMP_TEMPLATES_DONT_PUSH::
+        DU32    @@05,@@10,@@15,@@20,@@30,
+                @@35,@@40,@@50,@@55,@@60,
+                @@65,@@70,@@75,@@80,@@85,
+                @@90,@@95,@@100,@@110,@@120;
+
+@@05:   //INC
+        SUB     RSP,8
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        SUB     RSP,8
+        FLD1
+        FSUBP   ST1,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@15:
+@@20:   //LESS
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        JZ      @@25
+        MOV     RAX,1
+        SBB     RAX,0
+@@25:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@30:   //GREATER
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@35:   //LESS_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@40:   //GREATER_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        JZ      @@45
+        MOV     RAX,0
+        ADC     RAX,0
+@@45:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+@@50:
+@@55:
+@@60:
+@@65: //FSTP
+        SUB     RSP,8
+        FSTP    U64 [RSP]
+        POP     RAX
+@@70:
+@@75: //Sqr
+        SUB     RSP,8
+        FMUL    ST0,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@80: //Abs
+        SUB     RSP,8
+        FABS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@85: //Sqrt
+        SUB     RSP,8
+        FSQRT
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@90: //Sin
+        SUB     RSP,8
+        FSIN
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@95: //Cos
+        SUB     RSP,8
+        FCOS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@100: //Tan
+        SUB     RSP,8
+@@105:  FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@105
+        FFREE   ST0
+        FINCSTP
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@110: //Atan
+        SUB     RSP,8
+        FLD1
+@@115:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@115
+        FSTP    U64 [RSP]
+        POP     RAX
+@@120:
+
+//************************************
+CMP_TEMPLATES_DONT_PUSH_POP::
+        DU32    @@05,@@10,@@15,@@20,@@25,
+                @@30,@@35,@@40,@@45,@@50,
+                @@55,@@60,@@65,@@70,@@75,
+                @@80,@@85,@@90,@@95,@@105;
+
+@@05:   //INC
+        SUB     RSP,8
+        FLD1
+        FADDP   ST1,ST0
+        FST     U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        SUB     RSP,8
+        FLD1
+        FSUBP   ST1,ST0
+        FST     U64 [RSP]
+        POP     RAX
+
+@@15:
+@@20:
+@@25:
+@@30:
+@@35:
+@@40:
+@@45:
+@@50:
+@@55:
+@@60:
+@@65: //Sqr
+        FMUL    ST0,ST0
+
+@@70: //Abs
+        FABS
+
+@@75: //Sqrt
+        FSQRT
+
+@@80: //Sin
+        FSIN
+
+@@85: //Cos
+        FCOS
+
+@@90: //Tan
+        FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@90
+        FFREE   ST0
+        FINCSTP
+
+@@95: //Atan
+        FLD1
+@@100:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@100
+@@105:
+
+//************************************
+CMP_TEMPLATES_DONT_PUSH2::
+        DU32    @@05,@@10,@@15,@@20,@@25,
+                @@35,@@45,@@50,@@55,@@60,
+                @@65,@@70,@@75,@@80,@@85,
+                @@90,@@95,@@100,@@105,@@110;
+
+@@05:
+@@10:
+
+@@15:
+@@20:   //LESS
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@25:   //GREATER
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        JZ      @@30
+        MOV     RAX,1
+        SBB     RAX,0
+@@30:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@35:   //LESS_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        JZ      @@40
+        MOV     RAX,0
+        ADC     RAX,0
+@@40:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@45:   //GREATER_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+@@50:
+@@55:
+@@60:
+@@65:
+@@70:
+@@75:
+@@80:
+@@85:
+@@90:
+@@95:
+@@100:
+@@105:
+@@110:
+}
+
+ diff --git a/public/Wb/Compiler/UAsm.HC.HTML b/public/Wb/Compiler/UAsm.HC.HTML new file mode 100755 index 0000000..563dd4d --- /dev/null +++ b/public/Wb/Compiler/UAsm.HC.HTML @@ -0,0 +1,713 @@ + + + + + + + + + + + +
+I64 InstEntriesCompare(CInst *tmpins1,CInst *tmpins2)
+{
+  I64 i1,i2,j=0,res=0,oc_cnt1=tmpins1->opcode_cnt,oc_cnt2=tmpins2->opcode_cnt;
+  if (tmpins1->flags&IEF_STI_LIKE)
+    oc_cnt1--;
+  if (tmpins2->flags&IEF_STI_LIKE)
+    oc_cnt2--;
+  while (TRUE) {
+    if (j<oc_cnt1 && j<oc_cnt2) {
+      if (res=tmpins1->opcode[j]-tmpins2->opcode[j])
+        return res;
+      j++;
+    } else {
+      if (res=oc_cnt1-oc_cnt2)
+        return res;
+
+      if (tmpins1->flags&IEF_STI_LIKE && tmpins2->flags&IEF_STI_LIKE)
+        return tmpins1->opcode[j]-tmpins2->opcode[j];
+
+      if (res=tmpins1->flags&IEF_STI_LIKE - tmpins2->flags&IEF_STI_LIKE)
+        return res;
+
+      if (res=tmpins1->slash_val-tmpins2->slash_val)
+        return res;
+
+      if (res=tmpins1->flags&IEF_OP_SIZE32 - tmpins2->flags&IEF_OP_SIZE32)
+        return res;
+
+      i1=Bt(&uasm.ins64_arg_mask,tmpins1->arg1) ||
+            Bt(&uasm.ins64_arg_mask,tmpins1->arg2);
+      i2=Bt(&uasm.ins64_arg_mask,tmpins2->arg1) ||
+            Bt(&uasm.ins64_arg_mask,tmpins2->arg2);
+      if (res=i1-i2)
+        return res;
+
+      if (res=tmpins1->flags&IEF_48_REX - tmpins2->flags&IEF_48_REX)
+        return res;
+
+      i1=tmpins1->arg2==ARGT_IMM64 || tmpins1->arg2==ARGT_UIMM64;
+      i2=tmpins2->arg2==ARGT_IMM64 || tmpins2->arg2==ARGT_UIMM64;
+      return i1-i2;
+    }
+  }
+}
+
+/*
+U0 DumpUAsmIns(CInst *tmpins)
+{
+  CHashOpcode *tmpo=tmpins(U8 *)-tmpins->ins_entry_num*sizeof(CInst)
+  -offset(CHashOpcode.ins);
+  "%10s:%02d,%02d SV:%02d\n",tmpo->str,
+        tmpins->arg1,tmpins->arg2,tmpins->slash_val;
+}
+U0 DumpUAsmTables()
+{
+  I64 k;
+  "16/32 Bit Table\n";
+  for (k=0;k<uasm.table_16_32_entries;k++)
+    DumpUAsmIns(uasm.table_16_32[k]);
+  "\n\n\n\n64 Bit Table\n";
+  for (k=0;k<uasm.table_64_entries;k++)
+    DumpUAsmIns(uasm.table_64[k]);
+}
+*/
+
+CInst *InstEntryFind(U8 *rip,I64 opsize,I64 seg_size)
+{//Binary Search
+  I64 i,j,n,m,k,arg1,arg2,o1,o2,oc_cnt;
+  CInst *tmpins,**table;
+  i=0;
+  if (seg_size==64) {
+    table=uasm.table_64;
+    j=uasm.table_64_entries-1;
+  } else {
+    table=uasm.table_16_32;
+    j=uasm.table_16_32_entries-1;
+  }
+  while (TRUE) {
+    k=(i+j)>>1;  //binary search
+    tmpins=table[k];
+//DumpUAsmIns(tmpins);
+    m=0;
+    n=0;
+    while (TRUE) { //ief_compare_start
+      arg1=tmpins->arg1;
+      arg2=tmpins->arg2;
+      oc_cnt=tmpins->opcode_cnt;
+      if (tmpins->flags&IEF_STI_LIKE)
+        oc_cnt--;
+      if (n<oc_cnt) {
+        o1=rip[n];
+        if (n==tmpins->opcode_cnt-1 && tmpins->flags & IEF_PLUS_OPCODE)
+          o1&=-8;
+        o2=tmpins->opcode[n++];
+        if (m=o1-o2)
+          goto ief_compare_done;
+      } else
+        switch [tmpins->uasm_slash_val] {
+          case 0...7:
+            if (!(m=rip[n]>>3&7-tmpins->slash_val)) {
+              if ((Bt(&uasm.mem_arg_mask,arg1) ||
+                    Bt(&uasm.mem_arg_mask,arg2)) &&
+                    rip[n]&0xC0==0xC0) {
+                m=1;
+                goto ief_compare_done;
+              }
+              if (opsize==16) {
+                if (tmpins->flags & IEF_OP_SIZE32) {
+                  m=-1;
+                  goto ief_compare_done;
+                }
+              } else {
+                if (tmpins->flags & IEF_OP_SIZE16) {
+                  m=1;
+                  goto ief_compare_done;
+                }
+              }
+              if (opsize==64||arg1==ARGT_M64||arg2==ARGT_M64) {
+                if (!Bt(&uasm.ins64_arg_mask,arg1)&&
+                      !Bt(&uasm.ins64_arg_mask,arg2)&&
+                      !(tmpins->flags&IEF_48_REX))
+                  m=1;
+              } else {
+                if (Bt(&uasm.ins64_arg_mask,arg1)||
+                      Bt(&uasm.ins64_arg_mask,arg2) ||
+                      tmpins->flags&IEF_48_REX)
+                  m=-1;
+              }
+            } else if ((Bt(&uasm.mem_arg_mask,arg1)||
+                  Bt(&uasm.mem_arg_mask,arg2)) &&
+                  rip[n]&0xC0==0xC0)
+              m=1;
+            goto ief_compare_done;
+          case SV_I_REG:
+            m=rip[n]>>3-tmpins->opcode[tmpins->opcode_cnt-1]>>3;
+            goto ief_compare_done;
+          case SV_STI_LIKE:
+            if (!(m=rip[n]>>3-tmpins->opcode[tmpins->opcode_cnt-1]>>3))
+              m=rip[n]-tmpins->opcode[tmpins->opcode_cnt-1];
+            goto ief_compare_done;
+          case SV_R_REG:
+          case SV_NONE:
+            m=0;
+            if (opsize==16) {
+              if (tmpins->flags & IEF_OP_SIZE32) {
+                m=-1;
+                goto ief_compare_done;
+              }
+            } else {
+              if (tmpins->flags & IEF_OP_SIZE16) {
+                m=1;
+                goto ief_compare_done;
+              }
+            }
+            if (opsize==64 || arg1==ARGT_M64 || arg2==ARGT_M64) {
+              if (!Bt(&uasm.ins64_arg_mask,arg1) &&
+                    !Bt(&uasm.ins64_arg_mask,arg2) &&
+                    !(tmpins->flags&IEF_48_REX)&& !(arg2==ARGT_NONE &&
+                    (ARGT_UIMM8<=arg1<=ARGT_UIMM64 ||
+                    ARGT_IMM8<=arg1<=ARGT_IMM64)))
+                m=1;
+              else if (tmpins->arg2==ARGT_IMM64 || tmpins->arg2==ARGT_UIMM64) {
+                if (arg2!=ARGT_IMM64&&arg2!=ARGT_UIMM64)
+                  m=1;
+              } else if (arg2==ARGT_IMM64||arg2==ARGT_UIMM64)
+                m=-1;
+            } else {
+              if (Bt(&uasm.ins64_arg_mask,arg1) ||
+                    Bt(&uasm.ins64_arg_mask,arg2) ||
+                    tmpins->flags&IEF_48_REX)
+                m=-1;
+            }
+            goto ief_compare_done;
+        }
+    }
+ief_compare_done:
+    if (m>0) {
+      if (k==i) {
+        k=j;
+        break;
+      } else
+        i=k;
+    } else if (m<0) {
+      if (k-i<=1) {
+        k=i;
+        break;
+      } else
+        j=k;
+    } else
+      break;
+  }
+  return table[k];
+}
+
+U0 UAsmHashLoad()
+{
+  CHashOpcode *tmph;
+  CInst *tmpins;
+  I64 i,j1,j2,k;
+
+  uasm.ins64_arg_mask=0x0880888880+1<<ARGT_ST0+1<<ARGT_STI;
+  uasm.signed_arg_mask=1<<ARGT_REL8+1<<ARGT_REL16+1<<ARGT_REL32+
+        1<<ARGT_IMM8+1<<ARGT_IMM16+1<<ARGT_IMM32+1<<ARGT_IMM64;
+  uasm.mem_arg_mask=1<<ARGT_M8+1<<ARGT_M16+1<<ARGT_M32+1<<ARGT_M64;
+
+  uasm.table_16_32_entries=uasm.table_64_entries=0;
+  for (i=0;i<=cmp.asm_hash->mask;i++) {
+    tmph=cmp.asm_hash->body[i];
+    while (tmph) {
+      if (tmph->type==HTT_OPCODE && !(tmph->oc_flags&OCF_ALIAS)) {
+        tmpins=&tmph->ins;
+        for (k=0;k<tmph->inst_entry_cnt;k++) {
+          uasm.table_16_32_entries++;
+          if (!(tmpins->flags&IEF_NOT_IN_64_BIT))
+            uasm.table_64_entries++;
+          tmpins++;
+        }
+      }
+      tmph=tmph->next;
+    }
+  }
+
+  j1=j2=0;
+  uasm.table_16_32=MAlloc(uasm.table_16_32_entries*sizeof(U8 *));
+  uasm.table_64   =MAlloc(uasm.table_64_entries   *sizeof(U8 *));
+  for (i=0;i<=cmp.asm_hash->mask;i++) {
+    tmph=cmp.asm_hash->body[i];
+    while (tmph) {
+      if (tmph->type==HTT_OPCODE && !(tmph->oc_flags&OCF_ALIAS)) {
+        tmpins=&tmph->ins;
+        for (k=0;k<tmph->inst_entry_cnt;k++) {
+          uasm.table_16_32[j1++]=tmpins;
+          if (!(tmpins->flags&IEF_NOT_IN_64_BIT))
+            uasm.table_64[j2++]=tmpins;
+          tmpins++;
+        }
+      }
+      tmph=tmph->next;
+    }
+  }
+  QSortI64(uasm.table_16_32,uasm.table_16_32_entries,&InstEntriesCompare);
+  QSortI64(uasm.table_64   ,uasm.table_64_entries   ,&InstEntriesCompare);
+}
+
+U0 Ui(U8 *buf,U8 **_rip,I64 seg_size=64,I64 *_jmp_dst=NULL,Bool just_ins=FALSE)
+{//Unassembles one inst
+  I64 i,disp,imm,opsize,opadd,
+        arg1,arg2,reloced_arg1,reloced_arg2,
+        arg1_size=0,arg2_size=0,reloced_arg1_size,reloced_arg2_size,
+        ModrM=-1,SIB=-1,scale,r1,r2,
+        Mod=-1,RM1=-1,RM2=-1,REX=-1,REX_r=0,REX_x=0,REX_b=0;
+  Bool cont;
+  CInst *tmpins,*tmpins2;
+  CHashOpcode *tmpo;
+  U8 *rip=*_rip,*ptr,*reloced_arg1_st,*reloced_arg2_st,
+        *bin_data_area1,*bin_data_area2,
+        line1[512],line2[512],buf2[512],arg1_st[512],
+        arg2_st[512],seg_overrides[32];
+
+  if (_jmp_dst) *_jmp_dst=-1;
+  if (seg_size==16) {
+    opsize=16;
+    opadd=16;
+  } else if (seg_size==32) {
+    opsize=32;
+    opadd=32;
+  } else {
+    opsize=32;
+    opadd=64;
+  }
+  *arg1_st=0;
+  *arg2_st=0;
+  if (!IsRaw && PutSrcLink(rip,1,line1))
+    CatPrint(line1,"\n");
+  else
+    *line1=0;
+
+  StrPrint(line1+StrLen(line1),"%24tp ",rip);
+  bin_data_area1=line1+StrLen(line1);
+  for (i=0;i<6;i++)
+    CatPrint(line1,"%02X",rip[i]);
+  CatPrint(line1," ");
+
+  StrPrint(line2,"%24tp ",rip+6);
+  bin_data_area2=line2+StrLen(line2);
+  for (i=6;i<12;i++)
+    CatPrint(line2,"%02X",rip[i]);
+
+  *seg_overrides=0;
+  cont=TRUE;
+  while (TRUE) {
+    switch (*rip) {
+      case 0x2E: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"CS:"); break;
+      case 0x36: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"SS:"); break;
+      case 0x3E: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"DS:"); break;
+      case 0x26: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"ES:"); break;
+      case 0x64: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"FS:"); break;
+      case 0x65: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"GS:"); break;
+      case OC_OP_SIZE_PREFIX:
+        if (opsize==16)
+          opsize=32;
+        else
+          opsize=16;
+        break;
+      case OC_ADDR_SIZE_PREFIX:
+        if (opadd==16)
+          opadd=32;
+        else
+          opadd=16;
+        break;
+      case 0x40...0x4F:
+        if (seg_size==64) {
+          REX=*rip;
+          if (REX>=0x48)
+            opsize=64;
+          REX_b=Bt(&REX,0)<<3;
+          REX_x=Bt(&REX,1)<<3;
+          REX_r=Bt(&REX,2)<<3;
+          break;
+        } //Fall thru if !64
+      default:
+        cont=FALSE;
+    }
+    if (cont)
+      rip++;
+    else
+      break;
+  }
+
+  tmpins=InstEntryFind(rip,opsize,seg_size);
+  if (opsize==32 && seg_size==64) {
+    tmpins2=InstEntryFind(rip,64,seg_size);
+    if (tmpins2!=tmpins && tmpins2->flags&IEF_REX_ONLY_R8_R15 ||
+          tmpins2->flags&IEF_REX_XOR_LIKE&& rip[1]>>3&7==rip[1]&7)
+      tmpins=tmpins2;
+  }
+
+  rip+=tmpins->opcode_cnt;
+  tmpo=tmpins(U8 *)-tmpins->ins_entry_num*sizeof(CInst)
+  -offset(CHashOpcode.ins);
+  if (just_ins)
+    *line1=0;
+  CatPrint(line1,tmpo->str);
+
+  arg1=tmpins->arg1;
+  arg2=tmpins->arg2;
+
+  if (arg1_size=tmpins->size1) {
+    if (Bt(&uasm.signed_arg_mask,arg1))
+      CatPrint(arg1_st,"I%d ",arg1_size);
+    else
+      CatPrint(arg1_st,"U%d ",arg1_size);
+  }
+
+  if (arg2_size=tmpins->size2) {
+    if (Bt(&uasm.signed_arg_mask,arg2))
+      CatPrint(arg2_st,"I%d ",arg2_size);
+    else
+      CatPrint(arg2_st,"U%d ",arg2_size);
+  }
+
+  if (tmpins->flags & IEF_PLUS_OPCODE) {
+    rip--;
+    RM1=*rip++ - tmpins->opcode[tmpins->opcode_cnt-1]+REX_b;
+    ptr=NULL;
+    if (ARGT_R8<=arg1<=ARGT_R64) {
+      if (arg1_size==8) {
+        if (REX!=-1)
+          ptr="ST_U8_REX_REGS";
+        else
+          ptr="ST_U8_REGS";
+      } else if (arg1_size==16)
+        ptr="ST_U16_REGS";
+      else if (arg1_size==32)
+        ptr="ST_U32_REGS";
+      else if (arg1_size==64)
+        ptr="ST_U64_REGS";
+      if (ptr)
+        CatPrint(arg1_st,"%Z",RM1,ptr);
+    } else {
+      if (arg2_size==8) {
+        if (REX!=-1)
+          ptr="ST_U8_REX_REGS";
+        else
+          ptr="ST_U8_REGS";
+      } else if (arg2_size==16)
+        ptr="ST_U16_REGS";
+      else if (arg2_size==32)
+        ptr="ST_U32_REGS";
+      else if (arg2_size==64)
+        ptr="ST_U64_REGS";
+      if (ptr)
+        CatPrint(arg2_st,"%Z",RM1,ptr);
+    }
+  }
+
+  if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_M8<=arg1<=ARGT_M64 ||
+        ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
+    if (ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
+      reloced_arg1=arg2;
+      reloced_arg2=arg1;
+      reloced_arg1_size=arg2_size;
+      reloced_arg2_size=arg1_size;
+      reloced_arg1_st=arg2_st;
+      reloced_arg2_st=arg1_st;
+    } else {
+      reloced_arg1=arg1;
+      reloced_arg2=arg2;
+      reloced_arg1_size=arg1_size;
+      reloced_arg2_size=arg2_size;
+      reloced_arg1_st=arg1_st;
+      reloced_arg2_st=arg2_st;
+    }
+
+    CatPrint(reloced_arg1_st,seg_overrides);
+    ModrM=*rip++;
+    Mod=ModrM>>6 & 3;
+    RM1=ModrM & 7+REX_b;
+    RM2=ModrM>>3 & 7+REX_r;
+    if (Mod<3 && RM1&7==4)
+      SIB=*rip++;
+    if (Mod==1) {
+      disp=*rip(U8 *)++;
+      CatPrint(reloced_arg1_st,"%02X",disp);
+    } else if (Mod==2) {
+      disp=*rip(U32 *)++;
+      CatPrint(reloced_arg1_st,"%08X",disp);
+    }
+    if (tmpins->slash_val<8)
+      RM2=-1;
+    else {
+      ptr=NULL;
+      if (reloced_arg2==ARGT_SREG) {
+        if (RM2<=5)
+          ptr="ST_SEG_REGS";
+      } else if (!(ARGT_IMM8<=reloced_arg2<=ARGT_IMM64) &&
+            !(ARGT_UIMM8<=reloced_arg2<=ARGT_UIMM64)) {
+        if (reloced_arg2_size==8) {
+          if (REX!=-1)
+            ptr="ST_U8_REX_REGS";
+          else
+            ptr="ST_U8_REGS";
+        } else if (reloced_arg2_size==16)
+          ptr="ST_U16_REGS";
+        else if (reloced_arg2_size==32)
+          ptr="ST_U32_REGS";
+        else if (reloced_arg2_size==64)
+          ptr="ST_U64_REGS";
+      }
+      if (ptr)
+        CatPrint(reloced_arg2_st,"%Z",RM2,ptr);
+    }
+    if (RM1&7==5 && !Mod) {
+      disp=*rip(I32 *)++;
+      if (seg_size==64) {
+        disp+=rip;
+        if (reloced_arg2==ARGT_IMM8 || reloced_arg2==ARGT_UIMM8)
+          disp++;
+        else if (reloced_arg2==ARGT_IMM16 || reloced_arg2==ARGT_UIMM16)
+          disp+=2;
+        else if (reloced_arg2==ARGT_IMM32 || reloced_arg2==ARGT_UIMM32)
+          disp+=4;
+        else if (reloced_arg2==ARGT_IMM64 || reloced_arg2==ARGT_UIMM64)
+          disp+=8;
+      }
+      CatPrint(reloced_arg1_st,"[%X]",disp);
+      RM1=-1;
+    } else {
+      if (Mod<3) {
+        if (RM1&7==4) {
+          RM1=-1;
+          r1=SIB & 7+REX_b;
+          r2=SIB>>3 & 7+REX_x;
+          scale=SIB>>6 &3;
+          if (scale==3)
+            scale=8;
+          else if (scale==2)
+            scale=4;
+          else if (scale==1)
+            scale=2;
+          else
+            scale=1;
+          if (seg_size==64)
+            ptr="ST_U64_REGS";
+          else
+            ptr="ST_U32_REGS";
+          if (r1==REG_RBP && !Mod) {
+            disp=*rip(U32 *)++;
+            CatPrint(reloced_arg1_st,"%08X[%Z*%d]",disp,r2,ptr,scale);
+          } else if (r2==4)
+            CatPrint(reloced_arg1_st,"[%Z]",r1,ptr);
+          else
+            CatPrint(reloced_arg1_st,"[%Z+%Z*%d]",r1,ptr,r2,ptr,scale);
+        } else {
+          if (opadd==16)
+            ptr="ST_U16_REGS";
+          else if (opadd==32)
+            ptr="ST_U32_REGS";
+          else
+            ptr="ST_U64_REGS";
+          CatPrint(reloced_arg1_st,"[%Z]",RM1,ptr);
+        }
+      } else {
+        ptr=NULL;
+        if (reloced_arg1_size==8) {
+          if (REX!=-1)
+            ptr="ST_U8_REX_REGS";
+          else
+            ptr="ST_U8_REGS";
+        } else if (reloced_arg1_size==16)
+          ptr="ST_U16_REGS";
+        else if (reloced_arg1_size==32)
+          ptr="ST_U32_REGS";
+        else if (reloced_arg1_size==64)
+          ptr="ST_U64_REGS";
+        if (ptr)
+          CatPrint(reloced_arg1_st,DefineSub(RM1,ptr));
+      }
+    }
+  }
+
+  switch (arg1) {
+    case ARGT_IMM8:
+    case ARGT_UIMM8:
+      imm=*rip(U8 *)++;
+      CatPrint(arg1_st,"%02X",imm);
+      if (tmpins->opcode[0]==0xCD && (ptr=DefineSub(imm,"ST_INT_NAMES")))
+        CatPrint(arg1_st," %s",ptr);
+      break;
+    case ARGT_IMM16:
+    case ARGT_UIMM16:
+      CatPrint(arg1_st,"%04X",*rip(U16 *)++);
+      break;
+    case ARGT_IMM32:
+    case ARGT_UIMM32:
+      CatPrint(arg1_st,"%08X",*rip(U32 *)++);
+      break;
+    case ARGT_IMM64:
+    case ARGT_UIMM64:
+      CatPrint(arg1_st,"%016X",*rip(I64 *)++);
+      break;
+    start:
+      case ARGT_REL8:
+        disp=*rip(I8 *)++;
+        break;
+      case ARGT_REL16:
+        disp=*rip(I16 *)++;
+        break;
+      case ARGT_REL32:
+        disp=*rip(I32 *)++;
+        break;
+    end:
+      disp+=rip;
+      if (IsDbgMode)
+        CatPrint(arg1_st,"%p ",disp);
+      else if (PutSrcLink(disp,512,buf2))
+        CatPrint(arg1_st,"%s ",buf2);
+      else
+        CatPrint(arg1_st,"%P ",disp);
+      if (_jmp_dst) *_jmp_dst=disp;
+      break;
+    case ARGT_MOFFS8...ARGT_MOFFS64:
+      CatPrint(arg1_st,seg_overrides);
+      if (arg1_size==8)
+        disp=*rip(U8 *)++;
+      else if (opadd==16)
+        disp=*rip(U16 *)++;
+      else
+        disp=*rip(U32 *)++;
+      CatPrint(arg1_st,"[%X]",disp);
+      break;
+    case ARGT_AL ... ARGT_DX:
+    case ARGT_SS ... ARGT_ST0:
+      CatPrint(arg1_st,"%z",arg1-ARGT_AL,
+            "AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
+      break;
+    case ARGT_STI:
+      rip--;
+      CatPrint(arg1_st,"%Z",*rip++ - tmpins->opcode[tmpins->opcode_cnt-1],
+            "ST_FSTK_REGS");
+      break;
+  }
+
+  switch (arg2) {
+    case ARGT_IMM8:
+    case ARGT_UIMM8:
+      CatPrint(arg2_st,"%02X",*rip(U8 *)++);
+      break;
+    case ARGT_IMM16:
+    case ARGT_UIMM16:
+      CatPrint(arg2_st,"%04X",*rip(U16 *)++);
+      break;
+    case ARGT_IMM32:
+    case ARGT_UIMM32:
+      CatPrint(arg2_st,"%08X",*rip(U32 *)++);
+      break;
+    case ARGT_IMM64:
+    case ARGT_UIMM64:
+      CatPrint(arg2_st,"%016X",*rip(I64 *)++);
+      break;
+    case ARGT_MOFFS8...ARGT_MOFFS64:
+      CatPrint(arg2_st,seg_overrides);
+      if (arg2_size==8)
+        disp=*rip(U8 *)++;
+      else if (opadd==16)
+        disp=*rip(U16 *)++;
+      else
+        disp=*rip(U32 *)++;
+      CatPrint(arg2_st,"[%X]",disp);
+      break;
+    case ARGT_AL ... ARGT_DX:
+    case ARGT_SS ... ARGT_ST0:
+      CatPrint(arg2_st,"%z",arg2-ARGT_AL,
+            "AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
+      break;
+    case ARGT_STI:
+      rip--;
+      CatPrint(arg2_st,"%Z",*rip++ -tmpins->opcode[tmpins->opcode_cnt-1],
+            "ST_FSTK_REGS");
+      break;
+  }
+  if (tmpins->flags&IEF_ENDING_ZERO)
+    rip++;
+
+  if (*arg1_st)
+    CatPrint(line1,"\t%s",arg1_st);
+  if (*arg2_st)
+    CatPrint(line1,",%s",arg2_st);
+  CatPrint(line1,"\n");
+  CatPrint(line2,"\n");
+  if (!just_ins) {
+    for (i=rip-(*_rip)(I64);i<6;i++) {
+      bin_data_area1[i<<1]=CH_SPACE;
+      bin_data_area1[i<<1+1]=CH_SPACE;
+    }
+    for (i=rip-(*_rip)(I64);i<12;i++) {
+      bin_data_area2[(i-6)<<1]=CH_SPACE;
+      bin_data_area2[(i-6)<<1+1]=CH_SPACE;
+    }
+  }
+  StrCpy(buf,line1);
+  if (!just_ins && rip-(*_rip)(I64)>6)
+    CatPrint(buf,line2);
+  *_rip=rip;
+}
+
+U8 *U(U8 *rip,I64 cnt=20,I64 seg_size=64)
+{//Unassembles a num of insts.
+  I64 i;
+  U8 buf[1024];
+  if (seg_size==16)
+    PrintWarn("16-bit unassembly is not well supported.\n");
+  "$HL,1$";
+  for (i=0;i<cnt;i++) {
+    Ui(buf,&rip,seg_size);
+    "%s",buf;
+  }
+  "$HL,0$";
+  return rip;
+}
+
+I64 Un(U8 *rip,I64 cnt=0x80,I64 seg_size=64)
+{//Unassembles a num of bytes
+  I64 i=0;
+  U8 buf[1024],*end_rip=rip(I64)+cnt;
+  if (seg_size==16)
+    PrintWarn("16-bit unassembly is not well supported.\n");
+  "$HL,1$";
+  while (rip<end_rip) {
+    Ui(buf,&rip,seg_size);
+    "%s",buf;
+    i++;
+  }
+  "$HL,0$";
+  return i;
+}
+
+ diff --git a/public/Wb/Demo/AcctExample/HomeKeyPlugIns.HC.HTML b/public/Wb/Demo/AcctExample/HomeKeyPlugIns.HC.HTML new file mode 100755 index 0000000..53214cd --- /dev/null +++ b/public/Wb/Demo/AcctExample/HomeKeyPlugIns.HC.HTML @@ -0,0 +1,320 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 TimeIns()
+{
+  CDate cdt;
+  cdt=Now;
+  "$IV,1$----%D %T----$IV,0$\n",cdt,cdt;
+}
+
+U0 FileLinkIns()
+{
+  U8 *st=PopUpPickFile;
+  st[0]=':';  //This is my personal code, not production. LOL
+  "$LK,\"%s\",A=\"FI:%s\"$",st+2,st;
+  Free(st);
+}
+
+U0 DirLinksIns()
+{
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st=PopUpPickDir,*st2;
+  st[0]=':';  //This is my personal code, not production. LOL
+  st2=MStrPrint("%s/*",st);
+  tmpde=tmpde1=FilesFind(st2,FUF_JUST_FILES);
+  while (tmpde) {
+    tmpde->full_name[0]=':';
+    "$LK,\"%s\",A=\"FI:%s\"$\n",tmpde->full_name+2,tmpde->full_name;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  Free(st);
+  Free(st2);
+}
+
+U0 DocHiddenDel(CDoc *doc=NULL)
+{
+  Bool unlock;
+  CDocEntry *doc_e,*doc_e1;
+  if (!doc) doc=DocPut;
+  if (doc) {
+    unlock=DocLock(doc);
+    DocRecalc(doc);
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      doc_e1=doc_e->next;
+      if (doc_e->de_flags&(DOCEF_FILTER_SKIP|DOCEF_SKIP))
+        DocEntryDel(doc,doc_e);
+      doc_e=doc_e1;
+    }
+    DocRecalc(doc);
+    if (unlock)
+      DocUnlock(doc);
+  }
+}
+
+Bool MyPutKey(I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+
+  //See Char for definition of scan codes.
+  //See Key Allocations.
+  //See Keyboard Devices.
+
+  //You can customize keys.  This routine
+  //is called before the main editor
+  //key hndlr DocPutKey().
+  //You can intercept any key.
+
+  //Return TRUE if you completely
+  //handled the key.
+  I64 i;
+  U8 *st1,*st2;
+  if (sc&SCF_ALT && !(sc&SCF_CTRL)) {
+    switch (ch) {
+      case 0:
+        switch (sc.u8[0]) {
+          case SC_F1:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTPURPLE");
+              else
+                "$LTPURPLE$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /PURPLE");
+              else
+                "$PURPLE$";
+            }
+            return TRUE;
+          case SC_F2:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTRED");
+              else
+                "$LTRED$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /RED");
+              else
+                "$RED$";
+            }
+            return TRUE;
+          case SC_F3:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTGREEN");
+              else
+                "$LTGREEN$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /GREEN");
+              else
+                "$GREEN$";
+            }
+            return TRUE;
+          case SC_F4:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Default Color");
+              else
+                "$FG$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /BLUE");
+              else
+                "$BLUE$";
+            }
+            return TRUE;
+          case SC_F8:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Cmd /DirLinksIns");
+              else
+                DirLinksIns;
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Cmd /FileLinkIns");
+              else
+                FileLinkIns;
+            }
+            return TRUE;
+        }
+        break;
+      case 'a':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete On");
+        else
+          AutoComplete(ON);
+        return TRUE;
+      case 'A':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete Off");
+        else
+          AutoComplete;
+        return TRUE;
+      case 'f': //With sync
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /FrameGrabber Sync");
+        else if (fg_on)
+          FrameGrabberToggle(FALSE,FALSE);
+        else
+          FrameGrabberToggle(TRUE,FALSE);
+        return TRUE;
+      case 'F': //With sync and intro TOS theme
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /FrameGrabber Intro");
+        else if (fg_on)
+          FrameGrabberToggle(FALSE,FALSE);
+        else
+          FrameGrabberToggle(TRUE,TRUE);
+        return TRUE;
+      case 'h':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileHorz");
+        else
+          WinTileHorz;
+        return TRUE;
+      case 'H':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Del Hidden Doc Entries");
+        else
+          DocHiddenDel;
+        return TRUE;
+      case 'm':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinMax");
+        else {
+          WinBorder;
+          WinMax;
+        }
+        return TRUE;
+      case 'v':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileVert");
+        else
+          WinTileVert;
+        return TRUE;
+      case 'l':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Put Link to Cur Pos on Clip");
+        else {
+          ClipDel;
+          st1=FileNameAbs(BIBLE_FILENAME);
+          st2=FileNameAbs(DocPut->filename.name);
+          if (!StrCmp(st1,st2)) {
+            Free(st1);
+            st1=BibleLine2Verse(DocPut->cur_entry->y+1,',');
+            DocPrint(sys_clip_doc,"$LK,\"BF:%s\"$",st1);
+          } else
+            DocPrint(sys_clip_doc,"$LK,\"FL:%s,%d\"$",
+                  st2,DocPut->cur_entry->y+1);
+          Free(st1);
+          Free(st2);
+        }
+        return TRUE;
+      case 'L':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Place Anchor, Put Link to Clip");
+        else {
+          i=RandU32;
+          ClipDel;
+          DocPrint(sys_clip_doc,"$LK,\"<TODO>\",A=\"FA:%s,ANC%d\"$",
+                DocPut->filename.name,i);
+          "$AN,\"<TODO>\",A=\"ANC%d\"$",i;
+        }
+        return TRUE;
+      case 'p':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /JukeBox");
+        else
+          PopUp("#include \"::/Apps/Psalmody/Load\";"
+                "JukeBox(\"::/Home/Sup3/Sup3Hymns\");");
+        return TRUE;
+      case 'P':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /Psalmody");
+        else
+          PopUp("#include \"::/Apps/Psalmody/Load\";"
+                "Psalmody(\"~/Sup3/Sup3Hymns\");");
+        return TRUE;
+
+        //Ins your own ALT-key plug-ins
+      case '1':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /pi");
+        else
+          'pi';
+        return TRUE;
+      case '2':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /theta");
+        else
+          'theta';
+        return TRUE;
+      case '3':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /phi");
+        else
+          'phi';
+        return TRUE;
+      case '4':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /omega");
+        else
+          'omega';
+        return TRUE;
+      case '9':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Indent 5");
+        else
+          "$ID,5$";
+        return TRUE;
+      case '0':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Unindent 5");
+        else
+          "$ID,-5$";
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+Bool MyPutS(U8 *)
+{
+  return FALSE;
+}
+
+KeyDevAdd(&MyPutKey,&MyPutS,0x20000000,TRUE);
+
+ diff --git a/public/Wb/Demo/AcctExample/HomeLocalize.HC.HTML b/public/Wb/Demo/AcctExample/HomeLocalize.HC.HTML new file mode 100755 index 0000000..a5fb469 --- /dev/null +++ b/public/Wb/Demo/AcctExample/HomeLocalize.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+Option(OPTf_WARN_PAREN,ON);
+Option(OPTf_WARN_DUP_TYPES,ON);
+
+KbdTypeMatic(0);
+
+// Las Vegas is -7 during summer, -8 during winter
+local_time_offset=-7*60*60*CDATE_FREQ; //Pacific
+// Remember you can set the time in the BIOS.
+
+//adjust these to set mouse move scale
+ms_hard.scale.x=0.5;
+ms_hard.scale.y=0.5;
+ms_hard.scale.z=5.0; //wheel
+
+//don't change these
+ms_hard.prescale.x=ms_hard.pos.x/ms_hard.scale.x;
+ms_hard.prescale.y=ms_hard.pos.y/ms_hard.scale.y;
+ms_hard.prescale.z=ms_hard.pos.z/ms_hard.scale.z;
+
+ diff --git a/public/Wb/Demo/AcctExample/HomeSys.HC.HTML b/public/Wb/Demo/AcctExample/HomeSys.HC.HTML new file mode 100755 index 0000000..e9f3e8d --- /dev/null +++ b/public/Wb/Demo/AcctExample/HomeSys.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 UserStartUp()
+{//Run each time a user a spawned
+  DocTermNew;
+  Type("::/Doc/Start.DD");
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+  Dir;
+  "80,849LOC:";
+  CPURep;
+}
+
+U0 SrvStartUp()
+{//Run each time a srv task is spawned.
+  DocTermNew;
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+}
+
+CTask *user1,*user2;
+
+U0 StartUpTasks()
+{
+  user1=User;
+  user2=User;
+  WinToTop(user1);
+  WinTileVert;
+  "Boot     Time:%7.3fs\n",tS;
+  XTalk(user1,"Cd;#include \"Once\";\n");
+  Silent;
+  ACInit("/*;!*/Bible.TXT*;!*.TXT"); //No Bible, no uncompressed DD.
+  Silent(OFF);
+  "AutoComplete Time:%7.3fs\n",tS;
+}
+
+if (DrvIsWritable(':')) {
+  DelTree("::/Tmp/ScrnShots");
+  DirMk("::/Tmp/ScrnShots");
+}
+
+StartUpTasks;
+
+"\nTempleOS V%5.3f\t%D %T\n\n",sys_os_version,sys_compile_time,sys_compile_time;
+
+ diff --git a/public/Wb/Demo/AcctExample/HomeWrappers.HC.HTML b/public/Wb/Demo/AcctExample/HomeWrappers.HC.HTML new file mode 100755 index 0000000..8ec70d8 --- /dev/null +++ b/public/Wb/Demo/AcctExample/HomeWrappers.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+#define FILEMASK_OFF_LIMITS "!*/Misc/PCIDevices.DD*;!*/Misc/Bible.TXT*;"\
+        "!*/Books?/*;!*/Sup1/Sup1Words/*;!*/Sup1/Sup1Bin/*;"\
+        "!*/God/Vocab.DD*"
+
+public I64 F(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in all text files.
+  return Find(needle_str,"/*",fu_flags);
+}
+
+public I64 F2(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in most text files.
+  return Find(needle_str,"/*;" FILEMASK_OFF_LIMITS,fu_flags);
+}
+
+public I64 R(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in most text files.
+  return Find(needle_str,"/*;" FILEMASK_OFF_LIMITS,fu_flags,replace_text);
+}
+
+public I64 FD(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in cur dir text files.
+  return Find(needle_str,"*",fu_flags);
+}
+
+public I64 FD2(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in most cur dir text files.
+  return Find(needle_str,"*;" FILEMASK_OFF_LIMITS,fu_flags);
+}
+
+public I64 RD(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in most cur dir text files.
+  return Find(needle_str,"*;" FILEMASK_OFF_LIMITS,fu_flags,replace_text);
+}
+
+ diff --git a/public/Wb/Demo/AcctExample/MakeHome.HC.HTML b/public/Wb/Demo/AcctExample/MakeHome.HC.HTML new file mode 100755 index 0000000..00ffaf0 --- /dev/null +++ b/public/Wb/Demo/AcctExample/MakeHome.HC.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+//If these are not present in /Home, it uses the version in the root dir.  You
+//can make your own, modified, version of these files in your /Home directory.
+#include "~/HomeLocalize"
+#include "/Adam/Opt/Boot/MakeBoot"
+#include "/Adam/Opt/Utils/MakeUtils"
+#include "~/HomeWrappers"
+MapFileLoad("::/Kernel/Kernel");
+MapFileLoad("::/Compiler/Compiler");
+
+#include "::/Apps/Psalmody/Load"
+#include "~/TOS/MakeTOS"
+#include "~/HomeKeyPlugIns"
+#include "~/HomeSys"
+Cd("..");;
+
+ diff --git a/public/Wb/Demo/AcctExample/Once.HC.HTML b/public/Wb/Demo/AcctExample/Once.HC.HTML new file mode 100755 index 0000000..25b97eb --- /dev/null +++ b/public/Wb/Demo/AcctExample/Once.HC.HTML @@ -0,0 +1,70 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+//This file is executed by the
+//first terminal window upon start-up.
+//See Once and Home Files.
+
+//  Type("::/Doc/Customize.DD");
+
+U0 Tmp()
+{
+  OnceExe;
+  switch (sys_boot_src.u16[0]) {
+    case BOOT_SRC_DVD:
+      "\nIf you answer 'No' you can play with\n"
+            "the live CD without installing.\n\n"
+            "Install onto hard drive ";
+      if (YorN) {
+        DocBottom;
+        if (RunFile("::/Misc/OSInstall",,FALSE)) {
+          Del("C:/Home/DoDistro.HC.Z");
+          Del("D:/Home/DoDistro.HC.Z");
+          OnceDrv('C',"\"\n\nRun TOSStaffIns;\n\n\n\";");
+          OnceDrv('D',""); //This command uses cached Registry file.
+          if (PressAKey!=CH_SHIFT_ESC)
+            Reboot; //Too dangerous for amateurs until reboot.
+        }
+      }
+      break;
+  }
+  if (FileFind("D:/Tmp/Logs/access.log")) {
+    In("\n\n%C",CH_ESC);
+    RunFile("::/Demo/WebLogDemo/WebLogRep",,
+          "D:/Tmp/Logs/*.log","D:/Home/WebLogRep.DD");
+    Del("D:/Tmp/Logs/*.log");
+  }
+}
+
+Tmp;
+
+ diff --git a/public/Wb/Demo/AcctExample/PersonalNotes.DD.HTML b/public/Wb/Demo/AcctExample/PersonalNotes.DD.HTML index 3240256..e6b1729 100755 --- a/public/Wb/Demo/AcctExample/PersonalNotes.DD.HTML +++ b/public/Wb/Demo/AcctExample/PersonalNotes.DD.HTML @@ -41,7 +41,7 @@ * DskChk CDROM -* Compiler Bug:
AUWrite() dst->cdt=t0_now+ToI64(CDATE_FREQ*(tmpsd->tS-t0_tS)); +* Compiler Bug: AUWrite() dst->cdt=t0_now+ToI64(CDATE_FREQ*(tmpsd->tS-t0_tS)); * Make MV files combine disjoint rects for same frame. @@ -51,14 +51,14 @@ * Does entire tool chain support super/sub script? -* 170624 DskChk() showed extra alloced clus for FAT32, Sup1Hymns. ClusNum was +* 170624 DskChk() showed extra alloced clus for FAT32, Sup1Hymns. ClusNum was '.'+1 and clus was zero. -* ::/Apps/X-Caliber/X-Caliber.HC +* ::/Apps/X-Caliber/X-Caliber.HC * Add asteroid harbor defense. * Afterburner thruster. -* ::/Apps/Titanium/Titanium.HC +* ::/Apps/Titanium/Titanium.HC * Lead-in at start of game with no enemy. * Have highway of death. * Fix straight shooting. @@ -67,20 +67,20 @@ * 64-Bit Device Memory is not implemented. -* Investigate why packet loss Training Sleep(1). +* Investigate why packet loss Training Sleep(1). * Add AVL or red/black binary tree library support. We have fixed-size stack. Auto-balancing binary tree is very needed. I've done everything myself. I don't want to ruin a perfect record. I'm in no hurry. -* SpriteEd shift pts, Ctrl pt for ellipse/polygon w,h is off when rotated. +* SpriteEd shift pts, Ctrl pt for ellipse/polygon w,h is off when rotated. -* God said this is bad. FL:::/Adam/DolDoc/DocFind.HC,41 +* God said this is bad. FL:::/Adam/DolDoc/DocFind.HC,41 * Backward <SHIFT-F3> is broken? -* Find() search sprite text? +* Find() search sprite text? -* Cannot include ':' in Document Links search string. +* Cannot include ':' in Document Links search string. * $DA fixed width string: <Del> or <BACKSPACE> permanently shortens. * 11/19/16 editor took long time after copying old testament onto clip and @@ -93,13 +93,13 @@ * Editor overstrike mode at cmd line with menu macro? Probably, many other overstrike issues. -* DOCT_HEX_ED with odd size, ASCII cannot be edited. +* DOCT_HEX_ED with odd size, ASCII cannot be edited. -* FL:::/Adam/Gr/SpriteEd.HC,789 Resize bitmap? +* FL:::/Adam/Gr/SpriteEd.HC,789 Resize bitmap? -* DOCEF_REMALLOC_DATA HexEdit Remalloc. +* DOCEF_REMALLOC_DATA HexEdit Remalloc. -* DOCF_DBL_DOLLARS in Reindention. +* DOCF_DBL_DOLLARS in Reindention. * Compiler Optimization: Local array vars --> reg. Might exist. @@ -112,30 +112,30 @@ * 12/25/2015 Copy-Paste index.html glitch if source window 40 columns. * 01/06/2016 Editor filter "str" applied to output from LineRep looks broken. -* Document, perhaps with video, GetStr() all the way down into PutKey() code. +* Document, perhaps with video, GetStr() all the way down into PutKey() code. * Better dictionary. * Good spell checker. * Good Bible search. -* Can MEM_EXTRA_HASH2_PAGS be just one? +* Can MEM_EXTRA_HASH2_PAGS be just one? -* Bible ranges in BibleVerse(). +* Bible ranges in BibleVerse(). -* ::/Demo/Games/FlatTops.HC is torpedo, not bombs. +* ::/Demo/Games/FlatTops.HC is torpedo, not bombs. -* Reset MPs with Core0StartMP() after boot. Free old task memory? +* Reset MPs with Core0StartMP() after boot. Free old task memory? * Use thick and pen_height when clipping with thick>1. -* ~/Sup1/Sup1Games/Rocks.HC. +* ~/Sup1/Sup1Games/Rocks.HC. * Asm LIST NOLIST bugs. -* Review writing to same cache-line from multicore. Do CTask->task_flags and +* Review writing to same cache-line from multicore. Do CTask->task_flags and others need to be in separate cache lines? -* Fix KbdLEDsSet(). +* Fix KbdLEDsSet(). * NumLock comes on with break key. * Hymns: mightest, finger @@ -143,14 +143,14 @@ * Get rid of JIFFY and HPET and just use tS. * Use "Rosetta Stone" in documentaion pointing to this: -::/Demo/ToHtmlToTXTDemo/ToHtml.HC. +::/Demo/ToHtmlToTXTDemo/ToHtml.HC. * Change %h*c so the character is not a arg? -* GrLineFat3() needs a little work. +* GrLineFat3() needs a little work. -* GrFillTri0() with both GrHLine() and GrVLine() don't match in -::/Demo/Games/CastleFrankenstein.HC causing wall spot pixels. +* GrFillTri0() with both GrHLine() and GrVLine() don't match in +::/Demo/Games/CastleFrankenstein.HC causing wall spot pixels. TODO? Meh @@ -160,20 +160,20 @@ * Asm could support R4u8 by adding 0x40 byte. -* Mem32DevAlloc() is broken. Devices should be in free spot of E820 report. +* Mem32DevAlloc() is broken. Devices should be in free spot of E820 report. -* SpriteEd: Strip SPT_SHIFT origin cmds? +* SpriteEd: Strip SPT_SHIFT origin cmds? * Clean-up ASCII #127 delete char? (No. Maybe, we want a new usage for 127 in future centuries.) -* Compiler: Exceptions don't free CCmpCtrl stuff. +* Compiler: Exceptions don't free CCmpCtrl stuff. -* ::/Adam/DolDoc/DocHighlight.HC for code comments at top of documents. +* ::/Adam/DolDoc/DocHighlight.HC for code comments at top of documents. * Unhandled exception msgs from MP's get overwritten by WinMgr. -* Diff("C:/Misc/Bible.TXT","D:/Misc/Bible.TXT"); Takes too long. +* Diff("C:/Misc/Bible.TXT","D:/Misc/Bible.TXT"); Takes too long. * Finish Pilgrim game. @@ -184,22 +184,22 @@ TODO: Too Hard, or Not Worth Doing. -* AutoComplete/Man() Jmp for user code. +* AutoComplete/Man() Jmp for user code. -* Bible sized nodes +* Bible sized nodes -* FileMgr() is bad with lots of files. +* FileMgr() is bad with lots of files. * Would be nice to have a routine telling how much free memory, so apps can plan a big alloc. This is doable, depending on how. * Log-to-file is inefficient because we load and save whole file. -* ICMov() PUSH_CMP and MDf_STK? Perhaps, it's okay. +* ICMov() PUSH_CMP and MDf_STK? Perhaps, it's okay. * Short FAT32 ~ names. -* Find() search text in sprites. +* Find() search text in sprites. * Links in text in sprites. @@ -211,56 +211,56 @@ U0 (*fp_old_draw_ms)(CDC *dc,I64 x,I64 y)=gr.fp_draw_ms; } -* Compiler: Get rid of 0x20000 limit. +* Compiler: Get rid of 0x20000 limit. -* GrFloodFillRay: Get rid of 0x80000 limit. +* GrFloodFillRay: Get rid of 0x80000 limit. Bugs -* 1/28/16 ::/Demo/Graphics/Pick3D.HC crashed in TestSuite. +* 1/28/16 ::/Demo/Graphics/Pick3D.HC crashed in TestSuite. * 1/12/16 make RAM drive 2288 blks, CopyTree("C:/Home","B:/Home"); Disk runs-out of space and hangs instead of reporting errors. -* Bug introduced around 11/1/15. Changed ::/Kernel/Sched.HC and now WinToTop is +* Bug introduced around 11/1/15. Changed ::/Kernel/Sched.HC and now WinToTop is called on Adam task at start-up, sometimes. Might be user's fault because of bad keys pressed during VMware power-on init. Might be fixed by -ACf_INIT_IN_PROGRESS. +ACf_INIT_IN_PROGRESS. -* 1/12/16 ATARepEntry shows corrupted bttns. Weird. Perhaps, my imagination. +* 1/12/16 ATARepEntry shows corrupted bttns. Weird. Perhaps, my imagination. 3rd Party Bugs * VMware: Stretch to full scrn * VMware: PC speaker sound distorted. * VMware: 8/2/2015 start-up. Probably multicore. -* VMware: CtrlAltDel on <CTRL-ALT-INS> +* VMware: CtrlAltDel on <CTRL-ALT-INS> * VMware: Size zero files don't copy out of mounted disk? (Might be fixed.) Bugs? Not really sure. -* Mount() crashes on bad drive. +* Mount() crashes on bad drive. * Graphics clipping: scrn y+top<0 for top<0? * 1/1/2015 Bug messing-up keyboard, like no CTRL key. Was working on Sprites. -* 4/13/14 Strut or RawHide crashed when sys_var_init_flag was set during +* 4/13/14 Strut or RawHide crashed when sys_var_init_flag was set during testsuite. Perhaps, floodfill? -* DskChk alloc unalloced. I don't know if I fixed this. +* DskChk alloc unalloced. I don't know if I fixed this. * 1/?/2015,8/10/2015 Macro sel in Menu did not go to shell? No, I think just <CTRL-m> twice. Not a bug. -* 5/7/14:Something like InSetMs caused hang, then reboot in TestSuite. -* 5/7/14:#63 Maybe, ::/Demo/Graphics/Pick3D.HC crashed in TestSuite. +* 5/7/14:Something like InSetMs caused hang, then reboot in TestSuite. +* 5/7/14:#63 Maybe, ::/Demo/Graphics/Pick3D.HC crashed in TestSuite. -* StrPrintJoin(,st); With st="\n\\"; (Forgot what this is talking about.) +* StrPrintJoin(,st); With st="\n\\"; (Forgot what this is talking about.) TODO? Not really, just angst. -* Should these be moved into CHashClass from CMemberLst and CHashGlblVar? +* Should these be moved into CHashClass from CMemberLst and CHashGlblVar? CArrayDim dim; CHashFun *fun_ptr; @@ -270,19 +270,19 @@ * Might want to warn switch[] dup case numbers. -* Make Clamp(), Min(), Max() into asm routines? +* Make Clamp(), Min(), Max() into asm routines? -* Add local vars to sym table in Dbg()? +* Add local vars to sym table in Dbg()? * Compiler: Prints two error messages for expressions in stmts. -* U() negative byte displacement, neg 32-bit disp. +* U() negative byte displacement, neg 32-bit disp. -* Race condition in ::/Demo/Games/FlatTops.HC torpedo. +* Race condition in ::/Demo/Games/FlatTops.HC torpedo. -* Links to self document if empty file name? Document Links +* Links to self document if empty file name? Document Links -* FUF_RECURSE would be nice if capital "+R". +* FUF_RECURSE would be nice if capital "+R". * Sprites in cmd line code. @@ -293,9 +293,9 @@ * Compiler: Type for either F64 or I64, like Print -- no conversion. * Compiler: Arg type ... that did do conversion, if we have one that doesn't. -* R("char_bmp_","set_"); +* R("char_bmp_","set_"); -* Clean-up code FileNameAbs(), does it need so many local var names? I guess no +* Clean-up code FileNameAbs(), does it need so many local var names? I guess no choice. @@ -306,41 +306,41 @@ * Should we get rid of drive mapping. It's ugly. -* Can we get rid of MSG_CMD? +* Can we get rid of MSG_CMD? * Make so just CdRom; command to copy entire disk to ::/CdRom directory? -* MP DepthBuf is a kludge because of dc->depth_buf=NULL in various graphics +* MP DepthBuf is a kludge because of dc->depth_buf=NULL in various graphics routines. * Improve editor undo, add redo. * Compiler: F32? -* International Date output: MPrintDate(). Every country make own version? -* International Date input: Str2Date(). +* International Date output: MPrintDate(). Every country make own version? +* International Date input: Str2Date(). -* DCF_SYMMETRY before transformation? (Currently, it's after.) +* DCF_SYMMETRY before transformation? (Currently, it's after.) -* TRANSPARENT does not work with ROPF_DITHER. +* TRANSPARENT does not work with ROPF_DITHER. -* ROP_XOR with thick>1 is broken. +* ROP_XOR with thick>1 is broken. -* GrPutChar3() with depth buf? +* GrPutChar3() with depth buf? -* Eliminate? ::/Adam/Ctrls/CtrlsA.HC? -* Eliminate? ::/Adam/AMathODE.HC? -* Eliminate? Complex? -* Eliminate? CDC.brush? -* Eliminate? Mat4x4MulXYZ() change to 3x3? -* Eliminate? ROP_XOR? +* Eliminate? ::/Adam/Ctrls/CtrlsA.HC? +* Eliminate? ::/Adam/AMathODE.HC? +* Eliminate? Complex? +* Eliminate? CDC.brush? +* Eliminate? Mat4x4MulXYZ() change to 3x3? +* Eliminate? ROP_XOR? -* WinMgrTask needs to do doc operations on PostMsg() msgs for ms_hard. Already -works for MsSet()? +* WinMgrTask needs to do doc operations on PostMsg() msgs for ms_hard. Already +works for MsSet()? * Should Msgs in PopUp queue get fwded to parent when task dies? -* Import Intel datasheets so we can use links in Code for documentation. I +* Import Intel datasheets so we can use links in Code for documentation. I tried a PDF-to-text convertor and it wasn't acceptible. * Switch stmt with sparse cases? Maybe, ban sparse switch stmts. @@ -350,26 +350,26 @@ * Compiler: Local var array/struct initialization. -* Compiler Optimization: Bools use r,rm in ICCmp() like in ICCmpAndBranch()? +* Compiler Optimization: Bools use r,rm in ICCmp() like in ICCmpAndBranch()? * Compiler: !F64 ~F64 * Compiler: &=, |= can overflow with Bts Btr on small data types? -* Implement RS_ATTR_FIXED fixed pos files? +* Implement RS_ATTR_FIXED fixed pos files? -* SIMD in Mat4x4MulXYZ? +* SIMD in Mat4x4MulXYZ? -* I use fixed-point in Circle(), Ellipse(), Mat4x4MulXYZ(), Mat4x4MulMat4x4New() +* I use fixed-point in Circle(), Ellipse(), Mat4x4MulXYZ(), Mat4x4MulMat4x4New() and others. God says I might want to change to float. -::/Demo/Lectures/FixedPoint.HC ::/Demo/Lectures/FixedPointAdvanced.HC. +::/Demo/Lectures/FixedPoint.HC ::/Demo/Lectures/FixedPointAdvanced.HC. -* Note: We will never put multiple Keyboard Tables. Each country must make +* Note: We will never put multiple Keyboard Tables. Each country must make their own version of TempleOS. The Intel Factory ROM will have just English. Our Charter bans multiple country or architectures in the same version. -* 12 border chars in scrn font codes 0x02-0x0D. TextBorder() RawDr() -::/Demo/Games/CharDemo.HC. LineFeed shows-up in <CTRL-m> PersonalMenu. +* 12 border chars in scrn font codes 0x02-0x0D. TextBorder() RawDr() +::/Demo/Games/CharDemo.HC. LineFeed shows-up in <CTRL-m> PersonalMenu. * Super-simple high speed serial needs flow control. <CTRL-s> and <CTRL-q>? @@ -394,8 +394,8 @@ * New editor widgets. -* Make use of flag potential in FilesFind() and possibly DirContextNew(). -* Sort options for FilesFind()? +* Make use of flag potential in FilesFind() and possibly DirContextNew(). +* Sort options for FilesFind()? * New HolyC language features? @@ -407,7 +407,7 @@ * Ticketmaster format stmts? Overflow "t='*'" and padding character? -* Move stuff out of Kernel module. +* Move stuff out of Kernel module. * $LK,L="FL:D:/Kernel/File.HC"$ instead of A= * $SP,B=1$ instead of $SP,BI=1$ @@ -416,13 +416,13 @@ * DCF_TRANSFORMATION|DCF_SYMMETRY|DCF_JUST_MIRROR -- maybe not both needed at once. -* More Controls? +* More Controls? * Compiler: More use of more floating-point stk? -* Compiler: More aggressive in CmpF2PushPop() with types besides MOV and F64. +* Compiler: More aggressive in CmpF2PushPop() with types besides MOV and F64. -* Playing with ::/Demo/Lectures/NegDisp.HC on CTask? +* Playing with ::/Demo/Lectures/NegDisp.HC on CTask? $=-CTASK_NEG_OFFSET offset(CTask.addr)==0 Spawn(): CAlloc() @@ -434,46 +434,46 @@ Test -* SpriteBitMap: Grabscroll? +* SpriteBitMap: Grabscroll? -* DrvMap() in MountFile(). +* DrvMap() in MountFile(). -* Return ress for GrBlot, GrRect, GrPutChar? -* Collision cnts for GrBlot, GrRect, GrPutChar? +* Return ress for GrBlot, GrRect, GrPutChar? +* Collision cnts for GrBlot, GrRect, GrPutChar? -* GetStr() or GetChar() in OSInstall didn't like focus change. +* GetStr() or GetChar() in OSInstall didn't like focus change. * Test on Dad's computer or other people's? -* ICDivEqu() assumes RBX. Is it okay? +* ICDivEqu() assumes RBX. Is it okay? * InFile PopUp of PopUp? -* FileMgr() help link scrolls out of window. +* FileMgr() help link scrolls out of window. -* MsHardDrvrInstall() throws exceptions? Doesn't work? Why mouse 0x9FC30? +* MsHardDrvrInstall() throws exceptions? Doesn't work? Why mouse 0x9FC30? * VirtualBox MP reboot? * Compiler: Err/Warn line nums? * Asm branch-out-of-range warn by one line? -* Make sure queue links safe in one direction. Task QueIns and QueRem for +* Make sure queue links safe in one direction. Task QueIns and QueRem for multicore cycling fwd through tasks. -* Test removable media id and RS_ATTR_RESIDENT. Touch("","+T"); +* Test removable media id and RS_ATTR_RESIDENT. Touch("","+T"); Uncategorized -* DiskCache during FileRead. <CTRL-ALT-c>, Kill(). +* DiskCache during FileRead. <CTRL-ALT-c>, Kill(). * MOV U8 [RSP+RCX],DL -* gr.scrn_image +* gr.scrn_image >Might want to do ZOOM in U8 graphics and convert scrn capture to U8 >Might want to rev bit order -* This Fs->catch_except=TRUE causes problems because it +* This Fs->catch_except=TRUE causes problems because it catches divide and out-of-mem. Not sure what to do, yet. * Release semaphores or break lock sema,usb_td @@ -481,7 +481,7 @@ * Might make CSprite flood fill operate on a separate bitmap and blotted at the end. * <CTRL-r> delete subsprite in menu near others -* make better heapwalk, do something with _CFG_HEAP_DBG. +* make better heapwalk, do something with _CFG_HEAP_DBG. * static var off of data heap. * could add "const" to not set CCF_NOT_CONST flag for trig, etc. diff --git a/public/Wb/Demo/AcctExample/Registry.HC.HTML b/public/Wb/Demo/AcctExample/Registry.HC.HTML new file mode 100755 index 0000000..3baaec9 --- /dev/null +++ b/public/Wb/Demo/AcctExample/Registry.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
++] Adam
++] TempleOS
++] Once
++] DemoCompany
++] WalnutZone
+
+ diff --git a/public/Wb/Demo/AcctExample/TOS/MakeTOS.HC.HTML b/public/Wb/Demo/AcctExample/TOS/MakeTOS.HC.HTML new file mode 100755 index 0000000..ef633a4 --- /dev/null +++ b/public/Wb/Demo/AcctExample/TOS/MakeTOS.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#include "TOSExt"
+#include "TOSCfg"
+#include "TOSMisc"
+#include "TOSDistro"
+
+Cd("..");;
+
+ diff --git a/public/Wb/Demo/AcctExample/TOS/TOSCfg.HC.HTML b/public/Wb/Demo/AcctExample/TOS/TOSCfg.HC.HTML new file mode 100755 index 0000000..0845fe0 --- /dev/null +++ b/public/Wb/Demo/AcctExample/TOS/TOSCfg.HC.HTML @@ -0,0 +1,92 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS/Cfg"
+
+#define SLOP    BLK_SIZE
+
+U0 TOSDbgDistro1()
+{
+  CBinFile *bfh=mem_boot_base-sizeof(CBinFile);
+  bfh(I64)+=bfh->file_size-1;
+  DefinePrint("TOS_DBG_DISTRO","0x%X",
+        CeilI64(SYS_KERNEL_END+SLOP,BLK_SIZE));
+  DefinePrint("TOS_DBG_DISTRO_END",  "0x%X",FloorI64(
+        (BOOT_RAM_LIMIT-(BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE))>>4<<4-
+        (bfh(I64)-SYS_KERNEL_END)-SLOP,BLK_SIZE));
+  DefinePrint("CFG_DBG_DISTRO_FILE","\"/Tmp/DbgDistro.BIN.Z\"");
+} TOSDbgDistro1;
+
+U0 TOSDbgDistro2()
+{
+  DefinePrint("CFG_DBG_DISTRO","\"a0x%X\n0x%X\n\"",TOS_DBG_DISTRO,
+        (TOS_DBG_DISTRO_END-TOS_DBG_DISTRO)/BLK_SIZE);
+  DefinePrint("CFG_DBG_DISTRO_START","\"0x%X\"",TOS_DBG_DISTRO);
+} TOSDbgDistro2;
+
+U0 TOSInit()
+{
+  switch (INS_REG_MACHINE_NUM) {
+    case 1: //TAD Native Machine
+      DefinePrint("CFG_RAM_DRVS",
+            "\"B\nScale2Mem(2048,0x100000,4*1024*1024*1024)\n\"");
+      DefinePrint("CFG_HARD_DRVS","\"C\ns0xFE00\n0xFE10\n0\"");
+      DefinePrint("CFG_DVD_DRVS","\"Ts0x1F0\n1\"");
+      DefinePrint("CFG_DSK_CACHE","\"Scale2Mem(0x80000,0x8000000)\n\"");
+      DefinePrint("TOS_HDS","\"CD\"");
+      DefinePrint("TOS_MASTER_BOOT_DRVS","\"C\"");
+      break;
+    default:
+      DefinePrint("CFG_RAM_DRVS",
+            "\"B\nScale2Mem(2048,0x100000,4*1024*1024*1024)\n\"");
+      DefinePrint("CFG_HARD_DRVS","\"\"");
+      DefinePrint("CFG_DVD_DRVS","\"\"");
+      DefinePrint("CFG_DSK_CACHE","\"Scale2Mem(0x80000,0x8000000)\n\"");
+      DefinePrint("TOS_HDS","\"CD\"");
+      DefinePrint("TOS_MASTER_BOOT_DRVS","\"C\"");
+  }
+} TOSInit;
+
+#define TOS_ISO_NAME    "B:/TOS_Distro.ISO.C"
+#define TOS_DISTRO_DIR  "B:/Distro"
+#define CFG_OPTS        "StaffMode\nMountIDEAuto\nCT\n"
+#define CFG_DBG_OPTS    "StaffMode\nMountIDEAuto\nCT"\
+                        "HeapInit\n130\nMemInit\n131\nVarInit\n132\n\n"
+#define CFG_DBGZ_OPTS   "StaffMode\nMountIDEAuto\nCT"\
+                        "HeapInit\n0\nMemInit\n0\nVarInit\n0\n\n"
+#define TOS_CFG         "\n" CFG_RAM_DRVS CFG_DVD_DRVS CFG_HARD_DRVS "\n"\
+                        CFG_DSK_CACHE CFG_OPTS
+#define TOS_DVD_CFG     "TB\n0x20000\nT \n\n\nStaffMode\nMountIDEAuto\nCT\n"
+#define TOS_DVD_DBG_CFG "A" CFG_DBG_DISTRO\
+                        "B\nScale2Mem(2048,0x40000)\n\n\n"\
+                        "NoMP\nTextMode\nDontProbe\nDbgDistro\n"\
+                        "C:" CFG_DBG_DISTRO_FILE "\n"\
+                        CFG_DBG_DISTRO_START "\n\n"
+
+ diff --git a/public/Wb/Demo/AcctExample/TOS/TOSDistro.HC.HTML b/public/Wb/Demo/AcctExample/TOS/TOSDistro.HC.HTML new file mode 100755 index 0000000..5995360 --- /dev/null +++ b/public/Wb/Demo/AcctExample/TOS/TOSDistro.HC.HTML @@ -0,0 +1,418 @@ + + + + + + + + + + + +
+//The CFG defines are ~/TOS/TOSCfg.HC.
+
+#help_index "Misc/TOS/Distro"
+
+#define MAKE_LITE       1
+#define MAKE_DBG        0
+#define MAKE_STAFF      1
+
+public U8 TOSGetDrv()
+{//Pmt for drv let.
+  I64 res;
+  "Drive (%s):",TOS_HDS;
+  res=Let2Let(GetChar);
+  '\n';
+  return res;
+}
+
+public U0 TOSBootHDIns(U8 drv_let=0)
+{//Make Compiler and Kernel. Reinstall Kernel.
+  drv_let=Let2Let(drv_let);
+  In(TOS_CFG);
+  BootHDIns(drv_let);
+  if (StrOcc(TOS_MASTER_BOOT_DRVS,drv_let))
+    BootMHDIns(drv_let);
+}
+
+public U0 TOSCopyDrv(U8 src,U8 dst)
+{//Fmt dst and copy entire drv.
+  U8 buf_s[STR_LEN],buf_d[STR_LEN];
+  src=Let2Let(src);
+  dst=Let2Let(dst);
+
+  if (dst=='D')
+    Fmt(dst,,FALSE,FSt_FAT32);
+  else
+    Fmt(dst,,FALSE,FSt_REDSEA);
+
+  StrPrint(buf_s,"%c:/",src);
+  StrPrint(buf_d,"%c:/",dst);
+  CopyTree(buf_s,buf_d);
+
+  DocClear;
+  Drv(dst);
+  TOSBootHDIns(dst);
+}
+
+public U0 TOSPmtAndCopyDrv()
+{//Pmt for drv lets. Then, Fmt dst and copy entire drv.
+   I64 src,dst;
+  "$RED$\nCopy Src Drive:\n$FG$";
+  src=TOSGetDrv;
+  "$RED$\nCopy Dst Drive:\n$FG$";
+  dst=TOSGetDrv;
+  TOSCopyDrv(src,dst);
+}
+
+U0 DistroPrep()
+{
+  AOnceFlush; //Don't want in Registry
+  OnceFlush;
+
+  Del("/Home/Demo*");
+  DelTree("/Home/*Tmp.DD.Z");
+
+  DelTree("/Tmp");
+  DirMk("/Tmp");
+  DirMk("/Tmp/ScrnShots");
+
+  Touch("/PersonalMenu.DD.Z","+T");
+  Touch("/Home/PersonalMenu.DD.Z","+T");
+
+  DelTree("/Demo/AcctExample");
+  CopyTree("/Home","/Demo/AcctExample");
+  DelTree("/Demo/AcctExample/TAD");
+  DelTree("/Demo/AcctExample/Sup1");
+  DelTree("/Demo/AcctExample/Sup2");
+  DelTree("/Demo/AcctExample/Sup3");
+  Del("/Demo/AcctExample/Test*");
+  if (FileFind("~/Sup1/Sup1Utils/SortHeaders.HC.Z"))
+    ExeFile("~/Sup1/Sup1Utils/SortHeaders.HC.Z");
+
+  CursorRem("/*");
+  DelTree("/Demo/*.BI*");
+  S2T("/*","+r+S");
+  DocOpt("/*","+R");
+  Move(ACD_DEF_FILENAME,ACD_DEF_FILENAME_Z);
+}
+
+U0 DbgDistroFilePrep()
+{
+  CBlkDev *bd;
+  if (!Let2Drv('A',FALSE)) {
+    In(CFG_DBG_DISTRO "\n");
+    Mount;
+  }
+  bd=Let2BlkDev('A');
+  Fmt('A',,FALSE,FSt_REDSEA);
+
+  DirMk("A:/Compiler");
+  Copy("C:/Compiler/Compiler.BIN.Z",    "A:/Compiler");
+  Copy("C:/Compiler/OpCodes.DD.Z",      "A:/Compiler");
+  Copy("C:/Compiler/CompilerA.HH.Z",    "A:/Compiler");
+  Copy("C:/Compiler/CompilerB.HH.Z",    "A:/Compiler");
+
+  DirMk("A:/Kernel");
+  Copy("C:/Kernel/*.HH*",               "A:/Kernel");
+  CopyTree("C:/Kernel/BlkDev",          "A:/Kernel/BlkDev");
+
+  Copy("C:/Home/Sup1/Sup1Distro/DbgStartOS.HC.Z","A:/StartOS.HC.Z");
+
+  DirMk("A:/Adam");
+  Copy("C:/Home/Sup1/Sup1Distro/DbgMakeAdam.HC.Z","A:/Adam/MakeAdam.HC.Z");
+  Copy("C:/Home/Sup1/Sup1Distro/DbgMount.HC.Z","A:/Adam");
+  Copy("C:/Adam/AExts.HC.Z",    "A:/Adam");
+  Copy("C:/Adam/AMath.HC.Z",    "A:/Adam");
+  Copy("C:/Adam/Training.HC.Z","A:/Adam");
+  Copy("C:/Adam/AMem.HC.Z",     "A:/Adam");
+  Copy("C:/Adam/TaskRep.HC.Z",  "A:/Adam");
+
+  FileWrite("C:" CFG_DBG_DISTRO_FILE,
+        bd->RAM_dsk,(bd->max_blk+1)<<BLK_SIZE_BITS);
+}
+
+
+U0 StdDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home");
+  DirMk(TOS_DISTRO_DIR "/Home");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+  Del(TOS_DISTRO_DIR BOOT_DIR "/OldMBR.BIN.C");
+  Del(TOS_DISTRO_DIR BOOT_DIR "/BootMHD2.BIN.C");
+}
+U0 MakeStdDistro()
+{
+  StdDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOSCD_SIZE",
+        "Download TempleOS V5.03 - Standard Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+U0 LiteDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home");
+  DirMk(TOS_DISTRO_DIR "/Home");
+  DelTree(TOS_DISTRO_DIR "/Apps");
+  DelTree(TOS_DISTRO_DIR "/Demo");
+  Copy(TOS_DISTRO_DIR "/Demo/Games/Talons.HC.Z",TOS_DISTRO_DIR "/Home");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+  Del(TOS_DISTRO_DIR BOOT_DIR "/OldMBR.BIN.C");
+  Del(TOS_DISTRO_DIR BOOT_DIR "/BootMHD2.BIN.C");
+  Del(TOS_DISTRO_DIR "/Adam/AutoComplete/ACDefs.DATA.Z");
+  Del(TOS_DISTRO_DIR "/Adam/AutoComplete/ACWords.DATA.Z");
+  Del(TOS_DISTRO_DIR "/Misc/Bible.TXT.Z");
+}
+U0 MakeLiteDistro()
+{
+  LiteDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOSCD_SIZE",
+        "Download TempleOS V5.03 - Standard Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+U0 DbgDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  DbgDistroFilePrep;
+  In(TOS_DVD_DBG_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home");
+  DirMk(TOS_DISTRO_DIR "/Home");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+  Del(TOS_DISTRO_DIR BOOT_DIR "/OldMBR.BIN.C");
+  Del(TOS_DISTRO_DIR BOOT_DIR "/BootMHD2.BIN.C");
+}
+U0 MakeDbgDistro()
+{
+  DbgDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOS_DBG_SIZE",
+        "Download TempleOS V5.03 - Debug Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+U0 StaffDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  In(TOS_DVD_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home/Sup1");
+  DelTree(TOS_DISTRO_DIR "/Home/Sup2");
+  DelTree(TOS_DISTRO_DIR "/Home/Sup3");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+}
+U0 MakeStaffDistro()
+{
+  StaffDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOS_STAFF_SIZE",
+        "Download TempleOS V5.03 - T.S. Company Internal Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+I64 UpdateLineCnts()
+{
+  I64 res;
+
+  DocClear;
+  Drv('C');
+  DistroPrep;
+
+  Cd("C:/");
+  DelTree("B:/TOS/TOS");
+  CopyTree("C:/Home","B:/TOS/TOS");
+  DelTree("C:/Home");
+
+  DocMax;
+  DocClear;
+  res=LineRep("C:/*","-r")+LineRep("C:/Adam/*")+
+        LineRep("C:/Compiler/*","-S+$")+LineRep("C:/Kernel/*");
+  CopyTree("B:/TOS/TOS","C:/Home");
+  DelTree("B:/TOS/TOS");
+
+  DocTreeFWrite("C:/Adam/ADefine.HC.Z","LineRep",
+        "DefinePrint(\"DD_TEMPLEOS_LOC\",\"%,d\");\n",res);
+  DefinePrint("DD_TEMPLEOS_LOC","%,d",res);
+
+  "Total LOC:%12,d\n\n",res;
+  return res;
+}
+
+U0 UpdateISODocDefines()
+{
+  try {
+    DefinePrint("DD_TEMPLEOSCD_SIZE",
+          "Download TempleOS V5.03 - Standard Distro (%0.1fMB)",
+          0.1*(10*Size("D:/Downloads/TOS_Distro.ISO","+s")/1024/1024));
+    DefinePrint("DD_TEMPLEOSCD_K_SIZE",
+          "%dKB",Size("D:/Downloads/TOS_Distro.ISO","+s")/1024);
+  } catch
+    Fs->catch_except=TRUE;
+}
+UpdateISODocDefines;
+
+
+I64 tos_progress;
+F64 tos_progress_t0;
+
+U0 TOSProgress(U8 *st)
+{
+  U8 buf[STR_LEN];
+  progress4=tos_progress;
+  progress3_max=1;
+  *progress4_desc=0;
+  progress4_max=9+MAKE_LITE+MAKE_DBG+MAKE_STAFF;
+  progress4_t0=tos_progress_t0;
+  StrPrint(buf,"%d. %s",++progress4,st);
+  "$PURPLE$$TX+CX,\"%s\"$$FG$\n",buf;
+  StrCpy(progress3_desc,buf);
+  tos_progress=progress4;
+}
+
+U0 TOSRegen2()
+{
+  I64 slash_home=0;
+  SettingsPush; //See SettingsPush
+  tos_progress=-1;
+  tos_progress_t0=tS;
+  RegExe("TempleOS/TOSRegen");
+
+  TOSProgress("DskChk All");
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DskChkAll;
+
+  TOSProgress("Update Line Cnts");
+  UpdateLineCnts;
+
+  TOSProgress("Copy C to D");
+  TOSCopyDrv('C','D');
+
+  TOSProgress("Make Standard Distro ISO");
+  MakeStdDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Distro.ISO");
+
+  TOSProgress("Make Supplemental1 ISO");
+  RedSeaISO("D:/Downloads/TOS_Supplemental1","C:/Home/Sup1");
+
+  TOSProgress("Make Supplemental2 ISO");
+  RedSeaISO("D:/Downloads/TOS_Supplemental2","C:/Home/Sup2");
+
+  TOSProgress("Make Supplemental3 ISO");
+  RedSeaISO("D:/Downloads/TOS_Supplemental3","C:/Home/Sup3");
+
+#if MAKE_LITE
+  TOSProgress("Make Lite Distro ISO");
+  MakeLiteDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Lite.ISO");
+#endif
+#if MAKE_DBG
+  TOSProgress("Make Dbg Distro ISO");
+  MakeDbgDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Dbg.ISO");
+#endif
+#if MAKE_STAFF
+  TOSProgress("Make Staff Distro ISO");
+  MakeStaffDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Staff.ISO");
+#endif
+
+  UpdateISODocDefines;
+  Cd("C:/");
+  DocClear;
+
+  TOSProgress("Check for Long Lines");
+  if (LongLines)
+    throw;
+
+  DocClear;
+  TOSProgress("Check for Broken DolDoc Links");
+  if (LinkChk)
+    throw;
+
+  TOSProgress("Find /Home");
+  slash_home=F2("/Home","-i+la");
+
+  TOSProgress("DskChk All");
+  Drv('C');
+  DskChkAll;
+
+  TOSProgress("Done");
+  SettingsPop;
+  "F2(\"/Home\") Cnt\t:%d\n",slash_home;
+  "Elapsed Time\t:%5.3fs\n",tS-progress4_t0;
+  ProgressBarsRst("TempleOS/TOSRegen");
+}
+
+public U0 TOSPreRegen()
+{//Copy bins from D:/Home/Sup1 to C:/Home/Sup1
+  Copy("D:/Home/" INS_REG_PERSONAL_INITIALS "/*",
+        "C:/Home/" INS_REG_PERSONAL_INITIALS);
+  DelTree("C:/Home/Sup1/Sup1Bin");
+  CopyTree("D:/Home/Sup1/Sup1Bin","C:/Home/Sup1/Sup1Bin");
+  Copy("D:/Home/Sup1/Sup1CodeScraps/Comm/TOSSocket*",
+        "C:/Home/Sup1/Sup1CodeScraps/Comm");
+  DelTree("C:/Downloads/Linux");
+  CopyTree("D:/Downloads/Linux","C:/Downloads/Linux");
+}
+
+public U0 TOSRegen()
+{//Generate distro ISO's
+  TOSBootHDIns('C');
+  Once("TOSRegen2;");
+  BootRAM("C:/Kernel/" KERNEL_BIN_C); //Boot to load TOS_CFG.
+}
+
+ diff --git a/public/Wb/Demo/AcctExample/TOS/TOSExt.HC.HTML b/public/Wb/Demo/AcctExample/TOS/TOSExt.HC.HTML new file mode 100755 index 0000000..340f4bf --- /dev/null +++ b/public/Wb/Demo/AcctExample/TOS/TOSExt.HC.HTML @@ -0,0 +1,341 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS/God;God/TOS"
+
+#define NIST_TIME_OFFSET        (tos_nist_offset-local_time_offset/CDATE_FREQ)
+#define NIST_TIME_TO_SWITCH     3
+
+#define GSRC_NIST_BEACON        0
+#define GSRC_HOTBITS            1
+#define GSRC_ANU_NIST           2
+#define GSRC_GOOGLE             3
+#define GSRC_RANDOM_ORG         4
+#define GSRC_RANDOM_NUMBERS_INFO 5
+#define GSRC_PASSWORD           6
+#define GSRC_GENERATE_DATA      7
+#define GSRC_VIRTUAL_NOTARY     8
+#define GSRC_TIMER              9
+
+#define GBP_SHORT       0
+#define GBP_MEDIUM      1
+#define GBP_LONG        2
+
+class CRandExtDec5Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,A=\"5 Decimal Digits from Hex:%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CHexWordForm
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,A=\"Hex Word Indices#0:%s\"$\n";
+  U8    rnd1[512]       format "$DA-P,A=\"Hex Word Indices#1:%s\"$\n";
+  U8    rnd2[512]       format "$DA-P,A=\"Hex Word Indices#2:%s\"$\n";
+  U8    rnd3[512]       format "$DA-P,A=\"Hex Word Indices#3:%s\"$\n";
+  U8    rnd4[512]       format "$DA-P,A=\"Hex Word Indices#4:%s\"$\n";
+  U8    rnd5[512]       format "$DA-P,A=\"Hex Word Indices#5:%s\"$\n";
+  U8    rnd6[512]       format "$DA-P,A=\"Hex Word Indices#6:%s\"$\n";
+  U8    rnd7[512]       format "$DA-P,A=\"Hex Word Indices#7:%s\"$\n";
+  U8    rnd8[512]       format "$DA-P,A=\"Hex Word Indices#8:%s\"$\n";
+  U8    rnd9[512]       format "$DA-P,A=\"Hex Word Indices#9:%s\"$\n";
+  U8    rndA[512]       format "$DA-P,A=\"Hex Word Indices#A:%s\"$\n";
+  U8    rndB[512]       format "$DA-P,A=\"Hex Word Indices#B:%s\"$\n";
+  I64   cert;
+};
+
+class CNISTBeaconHexWordForm
+{
+  I64   timestamp       format "$DA,A=\"TimeStamp:%d\"$\n";
+  U8    rnd0[512]       format "$DA-P,A=\"Hex Word Indices#0:%s\"$\n";
+  U8    rnd1[512]       format "$DA-P,A=\"Hex Word Indices#1:%s\"$\n";
+  U8    rnd2[512]       format "$DA-P,A=\"Hex Word Indices#2:%s\"$\n";
+  U8    rnd3[512]       format "$DA-P,A=\"Hex Word Indices#3:%s\"$\n";
+  U8    rnd4[512]       format "$DA-P,A=\"Hex Word Indices#4:%s\"$\n";
+  U8    rnd5[512]       format "$DA-P,A=\"Hex Word Indices#5:%s\"$\n";
+  U8    rnd6[512]       format "$DA-P,A=\"Hex Word Indices#6:%s\"$\n";
+  U8    rnd7[512]       format "$DA-P,A=\"Hex Word Indices#7:%s\"$\n";
+  U8    rnd8[512]       format "$DA-P,A=\"Hex Word Indices#8:%s\"$\n";
+  U8    rnd9[512]       format "$DA-P,A=\"Hex Word Indices#9:%s\"$\n";
+  U8    rndA[512]       format "$DA-P,A=\"Hex Word Indices#A:%s\"$\n";
+  U8    rndB[512]       format "$DA-P,A=\"Hex Word Indices#B:%s\"$\n";
+  I64   cert;
+};
+
+class CRandHex5Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P-TRM,LEN=5,"
+        "A=\"Line (5-Digit Hex):%5s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CRandHex8Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P-TRM,LEN=8,"
+        "A=\"Line (8-Digit Hex):%8s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CMoviesForm
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Movie #1-100 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CPaintings100Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Painting #00-99 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CPaintings1000Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Painting #000-999 (3 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CPoems100Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Poems #00-99 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CMetallicaForm
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Song #1-99 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CCertRandDec5Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,A=\"Line (Dec):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert            format "$DA,A=\"Certificate:%d\"$\n";
+};
+
+class CGodVideoForm
+{
+  U8    title[STR_LEN]  format "$DA-P,A=\"Title:%s\"$\n";
+  U8    serial[STR_LEN] format "$DA-P-TRM,LEN=11,A=\"SerialNum:%11s\"$\n";
+  I64   min             format "$DA,A=\"Minutes:%d\"$\n";
+  I64   sec             format "$DA,A=\"Seconds:%d\"$\n";
+};
+
+class CWebBibleForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Tag Text:%s\"$\n";
+  U8    special[STR_LEN] format "$DA-P,A=\"Bible Passage:%s\"$\n";
+  I64   min;
+  I64   sec;
+};
+
+class CYouTubeForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Title:%s\"$\n";
+  U8    special[STR_LEN] format "$DA-P-TRM,LEN=11,A=\"SerialNum:%11s\"$\n";
+  I64   min             format "$DA,A=\"Minutes:%d\"$\n";
+  I64   sec             format "$DA,A=\"Seconds:%d\"$\n";
+};
+
+class CImgurForm
+{
+  U8    tag[STR_LEN];
+  U8    special[STR_LEN] format "$DA-P,A=\"SerialNum:%s\"$\n";
+  I64   min             format "$DA,A=\"Width    :%d\"$\n";
+  I64   sec             format "$DA,A=\"Height   :%d\"$\n";
+};
+
+class CWikipediaForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Tag Text:%s\"$\n";
+  U8    special[STR_LEN] format "$DA-P,A=\"Index   :%s\"$\n";
+  I64   min;
+  I64   sec;
+};
+
+class CWebBookMarkForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Tag Text:%s\"$\n";
+  U8    special[STR_LEN];
+  I64   min;
+  I64   sec;
+};
+
+DefineLstLoad("ST_FAMLY_PHOTOS","Family1_58-78\0Family2_78-86\0"
+        "Family3_86-99\0Family4_99\0");
+
+class CFamilyPhotoForm
+{
+  I64   volume          format  "$LS,D=\"ST_FAMLY_PHOTOS\"$\n";
+  I64   part            format  "$DA,A=\"Part   :%d\"$\n";
+  U8    picture[STR_LEN] format "$DA-P,A=\"Picture:%s\"$\n";
+  I64   width           format  "$GREEN$640x427 or 640x960$FG$\n"
+                                "$DA,A=\"Width  :%d\"$\n";
+  I64   height          format  "$DA,A=\"Height :%d\"$\n";
+};
+
+class CBlogImgForm
+{
+  U8    picture[STR_LEN] format "$DA-P,A=\"Picture:%s\"$\n";
+  I64   width           format "$DA,A=\"Width  :%d\"$\n";
+  I64   height          format "$DA,A=\"Height :%d\"$\n";
+};
+
+class CBlogVideoForm
+{
+  U8    video[STR_LEN]  format "$DA-P,A=\"Video:%s\"$\n";
+  Bool  big             format "$CB,\"Big\"$\n";
+};
+
+extern U0 FreshenBlog();
+extern U0 GodBooksPassageU32(U32 rand_u32,U8 *files_find_mask,
+        U8 *file_mask="*",I64 len=512,I64 verbosity=GBP_MEDIUM);
+extern I64 GodHeaderIns(U8 *type=NULL);
+extern U0 GodVideoDigits(U8 *title,U8 *webpage,U8 *rnd,I64 digits,U8 *filename);
+extern U0 GodVideoU32(U32 rand_u32,U8 *filename);
+extern U0 GodWebIdx(U8 *title,U8 *webpage,U8 *rnd,I64 digits,U8 *filename)
+extern U0 GodWordBatch(CHexWordForm *gm,I64 radix,I64 digits);
+extern U0 TOSBookLines(U8 *book_filename,I64 book_lines,U8 *st,I64 num_lines,
+        I64 radix,Bool modulo,Bool plus_one);
+extern U0 TOSGodDoodle(I64 god_src,CNISTBeaconHexWordForm *gm=NULL);
+
+ diff --git a/public/Wb/Demo/AcctExample/TOS/TOSMisc.HC.HTML b/public/Wb/Demo/AcctExample/TOS/TOSMisc.HC.HTML new file mode 100755 index 0000000..d67c0fa --- /dev/null +++ b/public/Wb/Demo/AcctExample/TOS/TOSMisc.HC.HTML @@ -0,0 +1,194 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS"
+
+Bool    fg_on =FALSE;
+
+I64 CopyVideo()
+{
+  I64 res=0;
+  Bool old_silent=Silent;
+  Del("D:/Tmp/*.AU");
+  Del("D:/Tmp/*.MV");
+  Silent(old_silent);
+  SndShift(&scrncast.snd_head,0.185);
+  AUWrite("D:/Tmp/AUDIO",&scrncast.snd_head,scrncast.t0_now,scrncast.t0_tS);
+  QueDel(&scrncast.snd_head,TRUE);
+  GR2MV("D:/Tmp/VID%03d.MV","B:/Tmp","+d");
+  return res;
+}
+
+#help_index "ScrnCast/TOS"
+U0 DelScrnShots()
+{
+  Bool old_silent=Silent;
+  DelTree("B:/Tmp");
+  DirMk("B:/Tmp");
+  Del("D:/Tmp/*.AU");
+  Del("D:/Tmp/*.MV");
+  Del("C:/Tmp/*.AU");
+  Del("C:/Tmp/*.MV");
+  Silent(old_silent);
+}
+
+public U0 FrameGrabberToggle(Bool sync_tone,Bool tos_theme,
+        Bool just_audio=FALSE)
+{//The frame grabber saves GR files to B:/Tmp.
+  static F64 last_time=0;
+  if (tS-last_time>3.0) {
+    last_time=tS;
+    if (fg_on) {
+      fg_on=FALSE;
+      ScrnCast(OFF);
+      User("CopyVideo;Exit;\n");
+    } else {
+      DelScrnShots;
+      fg_on=TRUE;
+      ScrnCast(ON,just_audio);
+      if (sync_tone) {Beep;}
+      if (tos_theme) {User("ExeFile(\"~/TOS/TOSTheme\");Exit;\n");}
+    }
+  }
+}
+
+public U0 JukeSongTAD(I64 num,I64 passes=2)
+{//Make movie of one song.
+  if (!fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  Sleep(200);
+  JukeSongsPuppet("~/TAD/Songs",passes,num,num+1);
+  if (fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+}
+
+public U0 JukeSongSup(I64 vol,I64 num,I64 passes=2)
+{//Make movie of one song.
+  U8 *st=MStrPrint("~/Sup%d/Sup%dHymns",vol,vol);
+  if (!fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  JukeSongsPuppet(st,passes,num,num+1);
+  if (fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  Free(st);
+}
+
+public U0 JukeLines(I64 vol,I64 start_line,I64 end_line)
+{//Make movie of many lines of songs, starting at 0.
+  U8 *st=MStrPrint("~/Sup%d/Sup%dHymns",vol,vol);
+  if (!fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  JukeSongsPuppet(st,,start_line*5,end_line*5);
+  if (fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  Free(st);
+}
+
+public U0 TADHymns(I64 vol,I64 let)
+{//Make 2-lines of songs movie
+  I64 line=2*(ToUpper(let)-'A');
+  JukeLines(vol,line,line+2);
+}
+
+#help_index "Misc/TOS"
+public U0 DskChkAll()
+{//DskChk on C & D.
+  U8 *ptr=TOS_HDS;
+  while (*ptr) {
+    "DskChk('%c')\n",*ptr;
+    DskChk(*ptr++,TRUE);
+  }
+}
+
+public CDoc *DC2Doc(CDC *dc,I64 dx=0,I64 dy=0,I64 *_total_score=NULL)
+{//Use OCR to make a text DolDoc from CDC.
+  U8 byte_bit_cnts[256];
+  I64 i,j,*ptr,row,col,ch,best_ch,score,best_score,
+        cur_char_image,diff_image,total_score=0;
+  CDoc *doc=DocNew;
+
+  MemSet(byte_bit_cnts,0,sizeof(byte_bit_cnts));
+  for (i=0;i<256;i++)
+    for (j=0;j<7;j++)
+      if (Bt(&i,j))
+        byte_bit_cnts[i]++;
+
+  for (row=0;row<dc->height/FONT_HEIGHT;row++) {
+    for (col=0;col<dc->width/FONT_WIDTH;col++) {
+
+      cur_char_image=0;
+      for (i=0;i<FONT_HEIGHT;i++)
+        for (j=0;j<FONT_WIDTH;j++)
+          if (GrPeek(dc,col*FONT_WIDTH+j+dx,row*FONT_HEIGHT+i+dy)!=WHITE)
+            LBts(&cur_char_image,i*8+j);
+
+      best_score=I64_MAX;
+      best_ch=0;
+      ptr=&text.font[32];
+      for (ch=32;ch<127;ch++) {
+        diff_image=*ptr++ ^ cur_char_image;
+        score=0;
+        for (i=0;i<8;i++)
+          score+=byte_bit_cnts[diff_image.u8[i]];
+        if (score<best_score) {
+          best_score=score;
+          best_ch=ch;
+        }
+      }
+      if (best_ch=='$')
+        DocPrint(doc,"$$");
+      else
+        DocPrint(doc,"%c",best_ch);
+      total_score+=best_score;
+    }
+    DocPrint(doc,"\n");
+  }
+  if (_total_score) *_total_score=total_score;
+  return doc;
+}
+
+#define MEM_TEST_SIZE   1024*1024
+U0 MemTest()
+{
+  U8 *b;
+  while (sys_data_bp->alloced_u8s-sys_data_bp->used_u8s>0x1000000) {
+    b=MAlloc(MEM_TEST_SIZE,Fs->data_heap);
+    MemSet(b,0x88,MSize(b));
+    "Data:%X\n",sys_data_bp->alloced_u8s-sys_data_bp->used_u8s;
+    Yield;
+  }
+  while (sys_code_bp->alloced_u8s-sys_code_bp->used_u8s>0x1000000) {
+    b=MAlloc(MEM_TEST_SIZE,Fs->code_heap);
+    MemSet(b,0x88,MSize(b));
+    "Code:%X\n",sys_code_bp->alloced_u8s-sys_code_bp->used_u8s;
+    Yield;
+  }
+}
+
+ diff --git a/public/Wb/Demo/AcctExample/TOS/TOSTheme.HC.HTML b/public/Wb/Demo/AcctExample/TOS/TOSTheme.HC.HTML new file mode 100755 index 0000000..97d02f5 --- /dev/null +++ b/public/Wb/Demo/AcctExample/TOS/TOSTheme.HC.HTML @@ -0,0 +1,233 @@ + + + + + + + + + + + +
+/*
+This is one of the oldest songs.  I picked
+the random name "risen" and said to God
+"Oh, you're ambitious," thinking it was
+an epic name.  He laughed and gave an
+epic song!
+*/
+
+
+
+
+                                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                                <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                                <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                                <4>/* Graphics Not Rendered in HTML */
+
+
+
+F64 t0=Beat;
+
+#define WING    24
+#define BODY    8
+
+U0 Bird(CDC *dc,F64 wing_theta)
+{
+  CD3I32 p[3];
+  dc->color=WHITE;
+
+  p[0].x=0; p[0].y=0; p[0].z=-BODY;
+  p[1].x=0; p[1].y=0; p[1].z=BODY;
+  p[2].x=-WING*Cos(wing_theta); p[2].y=-WING*Sin(wing_theta); p[2].z=0;
+  GrFillPoly3(dc,3,p);
+
+  p[0].x=0; p[0].y=0; p[0].z=-BODY;
+  p[1].x=0; p[1].y=0; p[1].z=BODY;
+  p[2].x=WING*Cos(wing_theta); p[2].y=-WING*Sin(wing_theta); p[2].z=0;
+  GrFillPoly3(dc,3,p);
+
+  dc->color=ROPF_DITHER+WHITE<<16+LTGRAY;
+  dc->thick=3;
+  GrLine3(dc,0,0,-BODY,0,0,BODY);
+}
+
+#define SCALE           115
+#define ARM             112
+#define CHAIN           100
+#define CUP             28
+#define TILT            -.25
+#define ARM_Y           -(0.93*CHAIN)
+#define ARM_Z           -45
+
+#define BIRDS_NUM       7
+#define RANGE           40
+F64 bx[BIRDS_NUM],by[BIRDS_NUM];
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i;
+  F64 theta,dt=Beat-t0,d_chain=Sin(pi/64*Sin(pi*dt/4))*CHAIN;
+  if (t0) {
+    DCDepthBufAlloc(dc);
+    dc->flags|=DCF_TRANSFORMATION;
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1;
+    dc->y=task->pix_height>>1-SCALE;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotX(dc->r,TILT);
+    Mat4x4RotZ(dc->r,pi/64*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<3>);
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1-ARM;
+    dc->y=task->pix_height>>1-SCALE+CHAIN-d_chain;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotX(dc->r,TILT+pi/32*Sin(pi*dt/4));
+    Mat4x4RotY(dc->r,pi/32*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<2>);
+
+    Mat4x4IdentEqu(dc->r);
+    Mat4x4RotX(dc->r,TILT);
+    dc->color=BLACK;
+    GrLine3(dc,0,ARM_Y,ARM_Z,0,0,0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,CUP,0,-0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,-CUP,0,-0.707*CUP);
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1+ARM;
+    dc->y=task->pix_height>>1-SCALE+CHAIN+d_chain;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotX(dc->r,TILT-pi/32*Sin(pi*dt/4));
+    Mat4x4RotY(dc->r,-pi/32*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<2>);
+
+    Mat4x4IdentEqu(dc->r);
+    Mat4x4RotX(dc->r,TILT);
+    dc->color=BLACK;
+    GrLine3(dc,0,ARM_Y,ARM_Z,0,0,0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,CUP,0,-0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,-CUP,0,-0.707*CUP);
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1;
+    dc->y=task->pix_height>>1;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotZ(dc->r,0.6-pi/32*Sin(pi*dt/4));
+    Mat4x4RotX(dc->r,TILT-pi/32*Sin(pi*dt/4));
+    Mat4x4RotY(dc->r,-pi/32*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<4>);
+
+    if (dt>=12.0) {
+      Mat4x4IdentEqu(dc->r);
+      dc->x=task->pix_width>>1;
+      dc->y=task->pix_height>>1;
+      dc->z=GR_Z_ALL;
+      Mat4x4Scale(dc->r,.5+.04*dt);
+      Sprite3(dc,0,0,0,<1>);
+    }
+
+    dc->y=task->pix_height+60;
+    for (i=0;i<BIRDS_NUM;i++) {
+      bx[i]=Clamp(bx[i]+0.35*SignI64(RandI16),-RANGE,RANGE);
+      by[i]=Clamp(by[i]+0.35*SignI64(RandI16),-RANGE,RANGE);
+      theta=pi/2*i/BIRDS_NUM+0.2*pi*dt+pi/2;
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4RotX(dc->r,pi/2);
+      Mat4x4RotZ(dc->r,theta);
+      Mat4x4TranslationEqu(dc->r,230*Cos(theta)+bx[i],230*Sin(theta)+by[i],
+            -(120*i/BIRDS_NUM+16*dt));
+      Mat4x4RotX(dc->r,0.45*pi+pi);
+      Bird(dc,Sin(2*pi*dt+i*2*pi/BIRDS_NUM));
+    }
+  }
+}
+
+U0 TOSTheme()
+{
+  I64 i,old_update=gr.fp_final_scrn_update;
+  gr.fp_final_scrn_update=NULL;
+  t0=0;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  WinVert(0,TEXT_ROWS-1,Fs);
+  DocCursor;
+  DocClear;
+  Fs->text_attr=LTCYAN<<4+BLACK;
+  Fs->draw_it=&DrawIt;
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 2.85;
+  music.stacatto_factor= 0.902;
+  for (i=0;i<BIRDS_NUM;i++) {
+    bx[i]=RANGE*RandI16/RANGE;
+    by[i]=RANGE*RandI16/RANGE;
+  }
+  try {
+    "$BG+H,LTCYAN$";
+    Refresh(2);
+    for (i=0;i<1;i++) {
+      t0=Beat;
+      Play("5eDEqFFetEEFqDeCDDEetCGF");
+      Play("5eDEqFFetEEFqDeCDDEetCGF");
+      Play("5eDCqDE4eAA5etEEFEDG4B5DCqF");
+      Play("5eDCqDE4eAA5etEEFEDG4B5DCqF");
+    }
+    Refresh(2);
+  } catch
+    PutExcept;
+  SettingsPop;
+  gr.fp_final_scrn_update=old_update;
+}
+
+TOSTheme;
+
+ diff --git a/public/Wb/Demo/Asm/AsmAndC1.HC.HTML b/public/Wb/Demo/Asm/AsmAndC1.HC.HTML new file mode 100755 index 0000000..620c052 --- /dev/null +++ b/public/Wb/Demo/Asm/AsmAndC1.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+*/
+
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+        IMPORT  Beep;
+
+_BEEPS::
+//You can always clobber RAX,RBX,RCX,RDX,R8,R9.  The compiler expects that.
+//See REGG_CLOBBERED and REGG_STK_TMP.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RCX,U64 SF_ARG1[RBP]  //SF_ARG1
+
+@@05:   PUSH    RCX
+//U0 Beep(I8 ona=62,Bool busy=FALSE)
+        PUSH    FALSE   //Do not busy (spin) wait
+        PUSH    62      //500 Hz
+        CALL    Beep
+        POP     RCX
+        LOOP    @@05
+
+        POP     RBP
+        RET1    8       //Use special return. Pop one arg off of stack.
+
+//HolyC return vals are in RAX.  This function has no return value.
+}
+
+//_extern binds a asm sym to a function.
+//My convention is to put an underscore
+//on C callable asm routines.
+_extern _BEEPS U0 Beeps(I64 cnt);
+
+I64 AsmAndC1()
+{
+  I64 noreg i;  //Normally this would be stored in a reg
+//Check by unassembling with Uf("AsmAndC1").
+
+  i=GetI64("Num of beeps 1-5 (%d):",3,1,5);
+  Beeps(i);
+
+  asm {
+//You can clobber RAX,RBX,RCX,RDX.  The compiler expects that.
+
+    IMPORT      Snd; //Import an not use & or don't import and use &Snd.
+    MOV         RCX,&i[RBP] //You can clobber RAX,RBX,RCX,RDX.
+                //You better preserve the rest.
+@@05:   PUSH    RCX
+
+                //U0 Snd(I8 ona);
+    MOV         RAX,RCX //ona=loop*10+50
+    IMUL2       RAX,10 //TempleOS uses nonstandard opcodes
+                //to avoid multiple form of the same one.
+                //See ::/Compiler/OpCodes.DD.
+    ADD         RAX,40
+    PUSH        RAX
+    CALL        Snd
+
+    MOV         RCX,cnts.time_stamp_freq>>3 //JIT Const.  Simple delay loop
+@@10:   LOOP    @@10
+
+    POP         RCX
+    LOOP        @@05
+  }
+  Snd;
+  return i;
+}
+
+"Beeps:%d\n",AsmAndC1;
+
+ diff --git a/public/Wb/Demo/Asm/AsmAndC2.HC.HTML b/public/Wb/Demo/Asm/AsmAndC2.HC.HTML new file mode 100755 index 0000000..71ebcc3 --- /dev/null +++ b/public/Wb/Demo/Asm/AsmAndC2.HC.HTML @@ -0,0 +1,116 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+*/
+
+//This is to demo glbl var access.
+//Glbs defined elsewhere can accessed too, like cnts.jiffies.
+I64 glbl_ona=Freq2Ona(400),glbl_ona_step=10,glbl_ona_base=Freq2Ona(100);
+
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+JIFFIES_MSG:    DU8 "Jiffies:",0;
+
+//See ::/Kernel/StrA.HC and ::/Kernel/KUtils.HC.
+
+_BEEPS2::
+//You can clobber RAX,RBX,RCX,RDX,R8,R9.  The compiler expects that.
+//See REGG_CLOBBERED and REGG_STK_TMP.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RCX,U64 SF_ARG1[RBP] //SF_ARG1
+
+        PUSH    U64 [&cnts.jiffies]
+
+@@05:   PUSH    RCX
+//U0 Beep(I8 ona=62,Bool busy=FALSE)
+        PUSH    FALSE   //Do not busy (spin) wait
+        PUSH    U64 [&glbl_ona] //evaluated at run time
+        CALL    &Beep
+        POP     RCX
+        LOOP    @@05
+
+        PUSH    RSI     //See REGG_LOCAL_VARS & REGG_LOCAL_NON_PTR_VARS
+        MOV     RSI,JIFFIES_MSG
+        CALL    PUT_STR
+        POP     RSI
+
+        POP     RAX
+        SUB     RAX,U64 [&cnts.jiffies]
+        NEG     RAX
+        CALL    PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    PUT_CHARS
+
+        POP     RBP
+        RET1    8
+}
+
+//My convention is to put an underscore
+//on C callable asm routines.
+_extern _BEEPS2 U0 Beeps2(I64 cnt);
+
+U0 AsmAndC2()
+{
+  I64 reg R15 i;
+
+  i=GetI64("$PURPLE$\n\nNum of beeps 1-5 (%d):$FG$",3,1,5);
+  Beeps2(i);
+
+  asm {
+    LIST
+//You can clobber RAX,RBX,RCX,RDX, but preserve the rest.
+    MOV RCX,R15 //You can clobber RAX,RBX,RCX,RDX. Preserve the rest.
+    @@05:       PUSH    RCX
+
+//U0 Snd(I8 ona);
+    MOV RAX,RCX //ona=loop*10+100.0Hz
+    IMUL2       RAX,glbl_ona_step //Intentionally evaluated at compile time
+    ADD RAX,U64 [&glbl_ona_base]  //Intentionally evaluated at run time
+    PUSH        RAX
+    CALL        &Snd    //We can skip IMPORT with & if JIT compiling.
+    MOV RCX,cnts.time_stamp_freq>>3 //JIT Const.  Simple delay loop.
+@@10:   LOOP    @@10
+
+    POP RCX
+    LOOP        @@05
+  }
+  Snd;
+}
+
+AsmAndC2;
+
+ diff --git a/public/Wb/Demo/Asm/AsmAndC3.HC.HTML b/public/Wb/Demo/Asm/AsmAndC3.HC.HTML new file mode 100755 index 0000000..16fc983 --- /dev/null +++ b/public/Wb/Demo/Asm/AsmAndC3.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+*/
+
+U0 AsmAndC3()
+{
+  I64 i;
+  for (i=0;i<3;i++) {
+    "Meaning of life:";
+    MOV AL,0x41
+    STC
+    ADC AL,0 //Round-about way to make the not-special constant, 0x42.
+    CALL        PUT_HEX_U8
+    MOV RCX,cnts.time_stamp_freq>>5 //JIT Const.  Simple delay loop.
+@@1:    LOOP    @@1
+    '\n';
+  }
+}
+
+AsmAndC3;
+
+ diff --git a/public/Wb/Demo/Asm/AsmHelloWorld.HC.HTML b/public/Wb/Demo/Asm/AsmHelloWorld.HC.HTML new file mode 100755 index 0000000..41f9b5f --- /dev/null +++ b/public/Wb/Demo/Asm/AsmHelloWorld.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+
+These are many useful kernel
+routines ::/Kernel/StrA.HC
+intended to be called from
+asm.  Generally, they preserve
+regs.
+
+You can call any routine you
+like, C or asm, if you import it.
+Be aware that C routines do not
+preserve RAX,RBX,RCX,RDX,R8,R9.
+When calling from the shell or
+from C, preserve all other regs.
+
+*/
+
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+MY_WORLD_MSG:
+//Define U8 does not put terminating zeros
+//on strings.
+        DU8     "World\n",0;
+
+//My convention is to put an underscore
+//on C callable asm routines.
+_HELLO_WORLD::
+        PUSH    RSI     //See REGG_LOCAL_VARS & REGG_LOCAL_NON_PTR_VARS
+        MOV     RCX,10
+@@05:   MOV     RAX,RCX
+        CALL    PUT_HEX_U8
+        MOV     RAX,CH_SPACE
+        CALL    PUT_CHARS
+        MOV     RAX,'Hello ' //Supports multi-byte char consts
+        CALL    PUT_CHARS
+//We broke it in two pieces to show different ways.
+        MOV     RSI,MY_WORLD_MSG
+        CALL    PUT_STR
+        LOOP    @@05
+        POP     RSI
+        RET
+};
+
+Call(_HELLO_WORLD);
+
+ diff --git a/public/Wb/Demo/Asm/BuzzFizz.HC.HTML b/public/Wb/Demo/Asm/BuzzFizz.HC.HTML new file mode 100755 index 0000000..23b2b67 --- /dev/null +++ b/public/Wb/Demo/Asm/BuzzFizz.HC.HTML @@ -0,0 +1,215 @@ + + + + + + + + + + + +
+#define RANGE_START     1
+#define RANGE_END       100
+ 
+#define FIZZ_SPAN       6
+#define BUZZ_SPAN       7
+ 
+asm {
+_BUZZ_FIZZ::
+        PUSH    RBP
+        MOV     RBP,RSP //Always set-up stk frame.  (Stack Gets Traced)
+        PUSH    RSI     //See REGG_LOCAL_VARS & REGG_LOCAL_NON_PTR_VARS
+        PUSH    RDI
+        MOV     RSI,FIZZ_SPAN-RANGE_START%FIZZ_SPAN+1
+        MOV     RDI,BUZZ_SPAN-RANGE_START%BUZZ_SPAN+1
+        MOV     RAX,RANGE_START
+ 
+@@05:   CALL    PUT_HEX_U64
+        PUSH    RAX
+        MOV     RAX,CH_SPACE
+        CALL    PUT_CHARS
+
+        DEC     RSI
+        JNZ     @@10
+        MOV     RAX,'FIZZ '
+        CALL    PUT_CHARS
+        MOV     RSI,FIZZ_SPAN
+
+@@10:   DEC     RDI
+        JNZ     @@15
+        MOV     RAX,'BUZZ '
+        CALL    PUT_CHARS
+        MOV     RDI,BUZZ_SPAN
+ 
+@@15:   MOV     RAX,'\n'
+        CALL    PUT_CHARS
+        POP     RAX
+        INC     RAX
+        CMP     RAX,RANGE_END   //Actually only a 32-bit inst.
+        JBE     @@05
+
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+}
+ 
+Call(_BUZZ_FIZZ);
+
+/*
+       _BUZZ_FIZZ+0x0000 55           PUSH      U64 RBP
+       _BUZZ_FIZZ+0x0001 488BEC       MOV       U64 RBP,U64 RSP
+       _BUZZ_FIZZ+0x0004 56           PUSH      U64 RSI
+       _BUZZ_FIZZ+0x0005 57           PUSH      U64 RDI
+       _BUZZ_FIZZ+0x0006 BE06000000   MOV       U32 ESI,U32 00000006
+       _BUZZ_FIZZ+0x000B BF07000000   MOV       U32 EDI,U32 00000007
+       _BUZZ_FIZZ+0x0010 B801000000   MOV       U32 EAX,U32 00000001
+       _BUZZ_FIZZ+0x0015 E8C51F2BC0   CALL      I32 PUT_HEX_U64+0x0000
+       _BUZZ_FIZZ+0x001A 50           PUSH      U64 RAX
+       _BUZZ_FIZZ+0x001B B820000000   MOV       U32 EAX,U32 00000020
+       _BUZZ_FIZZ+0x0020 E81E202BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0025 48FFCE       DEC       U64 RSI
+       _BUZZ_FIZZ+0x0028 7514         JNZ       I8 _BUZZ_FIZZ+0x003E
+       _BUZZ_FIZZ+0x002A 48B846495A5A MOV       U64 RAX,I64 000000205A5A4946
+       _BUZZ_FIZZ+0x0030 20000000
+       _BUZZ_FIZZ+0x0034 E80A202BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0039 BE06000000   MOV       U32 ESI,U32 00000006
+       _BUZZ_FIZZ+0x003E 48FFCF       DEC       U64 RDI
+       _BUZZ_FIZZ+0x0041 7514         JNZ       I8 _BUZZ_FIZZ+0x0057
+       _BUZZ_FIZZ+0x0043 48B842555A5A MOV       U64 RAX,I64 000000205A5A5542
+       _BUZZ_FIZZ+0x0049 20000000
+       _BUZZ_FIZZ+0x004D E8F11F2BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0052 BF07000000   MOV       U32 EDI,U32 00000007
+       _BUZZ_FIZZ+0x0057 B80A000000   MOV       U32 EAX,U32 0000000A
+       _BUZZ_FIZZ+0x005C E8E21F2BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0061 58           POP       U64 RAX
+       _BUZZ_FIZZ+0x0062 48FFC0       INC       U64 RAX
+       _BUZZ_FIZZ+0x0065 4883F864     CMP       U64 RAX,I8 64
+       _BUZZ_FIZZ+0x0069 76AA         JNA       I8 _BUZZ_FIZZ+0x0015
+       _BUZZ_FIZZ+0x006B 5F           POP       U64 RDI
+       _BUZZ_FIZZ+0x006C 5E           POP       U64 RSI
+       _BUZZ_FIZZ+0x006D 5D           POP       U64 RBP
+       _BUZZ_FIZZ+0x006E C3           RET
+
+0000000000000001
+0000000000000002
+0000000000000003
+0000000000000004
+0000000000000005
+0000000000000006 FIZZ
+0000000000000007 BUZZ
+0000000000000008
+0000000000000009
+000000000000000A
+000000000000000B
+000000000000000C FIZZ
+000000000000000D
+000000000000000E BUZZ
+000000000000000F
+0000000000000010
+0000000000000011
+0000000000000012 FIZZ
+0000000000000013
+0000000000000014
+0000000000000015 BUZZ
+0000000000000016
+0000000000000017
+0000000000000018 FIZZ
+0000000000000019
+000000000000001A
+000000000000001B
+000000000000001C BUZZ
+000000000000001D
+000000000000001E FIZZ
+000000000000001F
+0000000000000020
+0000000000000021
+0000000000000022
+0000000000000023 BUZZ
+0000000000000024 FIZZ
+0000000000000025
+0000000000000026
+0000000000000027
+0000000000000028
+0000000000000029
+000000000000002A FIZZ BUZZ
+000000000000002B
+000000000000002C
+000000000000002D
+000000000000002E
+000000000000002F
+0000000000000030 FIZZ
+0000000000000031 BUZZ
+0000000000000032
+0000000000000033
+0000000000000034
+0000000000000035
+0000000000000036 FIZZ
+0000000000000037
+0000000000000038 BUZZ
+0000000000000039
+000000000000003A
+000000000000003B
+000000000000003C FIZZ
+000000000000003D
+000000000000003E
+000000000000003F BUZZ
+0000000000000040
+0000000000000041
+0000000000000042 FIZZ
+0000000000000043
+0000000000000044
+0000000000000045
+0000000000000046 BUZZ
+0000000000000047
+0000000000000048 FIZZ
+0000000000000049
+000000000000004A
+000000000000004B
+000000000000004C
+000000000000004D BUZZ
+000000000000004E FIZZ
+000000000000004F
+0000000000000050
+0000000000000051
+0000000000000052
+0000000000000053
+0000000000000054 FIZZ BUZZ
+0000000000000055
+0000000000000056
+0000000000000057
+0000000000000058
+0000000000000059
+000000000000005A FIZZ
+000000000000005B BUZZ
+000000000000005C
+000000000000005D
+000000000000005E
+000000000000005F
+0000000000000060 FIZZ
+0000000000000061
+0000000000000062 BUZZ
+0000000000000063
+0000000000000064
+*/
+
+ diff --git a/public/Wb/Demo/Asm/DivByHand.HC.HTML b/public/Wb/Demo/Asm/DivByHand.HC.HTML new file mode 100755 index 0000000..3c1a013 --- /dev/null +++ b/public/Wb/Demo/Asm/DivByHand.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+asm {
+_DIV_U64_BY_U64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        XOR     RDX,RDX
+        MOV     RCX,64
+        MOV     RAX,SF_ARG1[RBP]
+        MOV     RBX,SF_ARG2[RBP]
+@@1:    SHL1    RAX
+        RCL1    RDX
+        CMP     RBX,RDX
+        JA      @@2
+        INC     RAX
+        SUB     RDX,RBX
+@@2:    LOOP    @@1
+        POP     RBP
+        RET1    16
+}
+
+_extern _DIV_U64_BY_U64 I64 DivU64ByU64(I64 dividend,I64 divisor);
+
+"123456/10=%d\n",DivU64ByU64(123456,10);
+ diff --git a/public/Wb/Demo/Asm/MulByHand.HC.HTML b/public/Wb/Demo/Asm/MulByHand.HC.HTML new file mode 100755 index 0000000..62fc12e --- /dev/null +++ b/public/Wb/Demo/Asm/MulByHand.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+/*When I was a kid with a Commodore 64,
+the 6502 chip had no multiply inst
+and this is how we had to do it, except,
+I used more regs in this example.
+*/
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+//You can clobber RAX,RBX,RCX,RDX,R8,R9.  The compiler expects that.
+
+MUL_BY_HAND_U8_U8_TO_U16: //This is only for fun.
+//8bit * 8bit-->16bit
+//AL*BL-->AX
+        MOV     CL,8
+        SHL     AX,8
+@@05:   SHL1    AX
+        JNC     @@10
+        ADD     AL,BL
+@@10:   DEC     CL
+        JNZ     @@05
+        RET
+
+_MUL_BY_HAND_U8_U8_TO_U16::     //C callable
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     AL,U8 SF_ARG1[RBP] //SF_ARG1
+        MOV     BL,U8 SF_ARG2[RBP]
+        CALL    MUL_BY_HAND_U8_U8_TO_U16
+        MOVZX   RAX,AX
+        POP     RBP
+        RET1    16
+
+_MUL_U64_U64_TO_U128::
+//64bit * 64bit-->128bit
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP] //SF_ARG1
+        MUL     U64 SF_ARG2[RBP]        //Res RDX:RAX 128bit
+        MOV     U64 [RBX],RAX
+        MOV     U64 8[RBX],RDX
+        POP     RBP
+        RET1    24
+};
+
+//My convention is to put an underscore
+//on C callable asm routines.
+_extern _MUL_BY_HAND_U8_U8_TO_U16 U16 MulU8(U8 n1,U8 n2);
+
+class U128
+{
+  U64 lo,hi;
+};
+
+_extern _MUL_U64_U64_TO_U128 U0 MulU64(I64 n1,I64 n2,U128 *_prod);
+
+U0 MulByHand()
+{
+  U128 p;
+  "2*7   =0x%X\n",MulU8(2,7);
+  "100*10=0x%X\n",MulU8(100,10);
+
+  MulU64(0x0123456789ABCDEF,0x1000001,&p);
+  "0x0123466789ABCDEF*0x1000001=0x%016X%016X\n",p.hi,p.lo;
+}
+
+MulByHand;
+
+
+ diff --git a/public/Wb/Demo/Asm/PutDec.HC.HTML b/public/Wb/Demo/Asm/PutDec.HC.HTML new file mode 100755 index 0000000..5d7748d --- /dev/null +++ b/public/Wb/Demo/Asm/PutDec.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+asm {
+PUT_DEC_U64::
+//RAX is number to print in decimal.
+//Preserves all regs.
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,24          //24 char buffer on stack
+
+//Save regs which C code is free to clobber.  We don't have to for C callers,
+//but this function will be nice for ASM callers if it saves all regs.
+        PUSH_C_REGS
+
+        PUSH    RSI           //See REGG_LOCAL_VARS&REGG_LOCAL_NON_PTR_VARS
+        LEA     RSI,-1[RBP]     //Load addr of end of buffer.
+                                //We picked RSI because of PUT_STR
+                                //We'll move bwd
+        MOV     U8 [RSI],0      //Terminator
+
+        TEST    RAX,RAX         //Special case -- zero
+        JNZ     @@05
+        DEC     RSI
+        MOV     U8 [RSI],'0'
+        JMP     @@15
+
+@@05:   MOV     RBX,10          //Divides by 10
+
+@@10:   XOR     RDX,RDX
+        DIV     RBX             //RAX=(RDX:RAX)/RBX with remainder in RDX
+        ADD     RDX,'0'
+        DEC     RSI
+        MOV     U8 [RSI],DL
+        TEST    RAX,RAX
+        JNZ     @@10
+
+@@15:   CALL    PUT_STR
+        POP     RSI
+        POP_C_REGS
+        LEAVE
+        RET
+
+_DO_IT::        //The convention is C-callable routines have underscores.
+        MOV     RAX,122333221
+        CALL    PUT_DEC_U64
+        MOV     RAX,'\n'
+        CALL    PUT_CHARS
+        RET
+}
+
+Call(_DO_IT);
+
+ diff --git a/public/Wb/Demo/Carry.HC.HTML b/public/Wb/Demo/Carry.HC.HTML new file mode 100755 index 0000000..a3bacd9 --- /dev/null +++ b/public/Wb/Demo/Carry.HC.HTML @@ -0,0 +1,76 @@ + + + + + + + + + + + +
+//Shows the Carry function.  It holds the CPU carry flag.
+//U() Unassemble to make sure it is right.
+
+U0 BigCnt()
+{
+  U64 lo=0,hi=0;
+  "BigCnt\n";
+  while (hi<0x10) {
+    lo+=1<<58;
+    hi+=Carry;
+    "%016X %016X\n",hi,lo;
+  }
+}
+
+BigCnt;
+
+U0 BigShift()
+{
+  U64 lo=1,hi=0;
+  "Big Shift\n";
+  while (lo||hi) {
+    hi<<=1;
+    lo<<=1;
+    hi+=Carry;
+    "%016X %016X\n",hi,lo;
+  }
+}
+
+BigShift;
+
+U0 Branch()
+{
+  U64 i=0xFFCC3311,j;
+  'Branch\n';
+  for (j=0;j<64;j++) {
+    i<<=1;
+    if (Carry)
+      '1';
+    else
+      '0';
+  }
+  '\n';
+}
+
+Branch;
+
+ diff --git a/public/Wb/Demo/ClassMeta.HC.HTML b/public/Wb/Demo/ClassMeta.HC.HTML new file mode 100755 index 0000000..236bd4d --- /dev/null +++ b/public/Wb/Demo/ClassMeta.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+/*Demonstrates class meta data.
+Basically, we make use of the compiler's
+data about a class.  We can add to the
+compilers data arbitrary items, either string or
+or int or F64 (if you typecast).
+
+This stuff is not high performance.
+Don't get carried away -- it might be slow.
+*/
+
+U0 RankOut(I64 i)
+{
+  " %z",i,"Cadet\0Ensign\0Captain\0Admiral\0President\0";
+}
+
+class Test1Struct
+{
+  I64 age       print_str "%2d" dft_val 38;
+  I64 color     dft_val RED; //Accepts expressions
+  I64 rank      print_str "%1d" dft_val 6/2 output_fun &RankOut;
+};
+
+class Test2Struct
+{
+  I64 age        print_str "%2d" dft_val 38 percentile 54.20;
+  I64 rank       print_str "%1d" dft_val 5;
+  I64 serial_num print_str "%6d" dft_val 123456;
+};
+
+U0 DumpStruct(U8 *_d,U8 *class_name=lastclass)
+{//lastclass is keyword.  See ::/Demo/LastClass.HC.
+  CHashClass *tmpc=HashFind(class_name,Fs->hash_table,HTT_CLASS);
+  U8 *print_str;
+  I64 *q,dft_val;
+  U0 (* fp_output_fun)(I64 i);
+  F64 percentile;
+  if (!tmpc) return;
+  CMemberLst *ml;
+  ml=tmpc->member_lst_and_root;
+  while (ml) {
+    "%s:",ml->str;
+
+    //All our items are I64's.  If you want, you can check
+    //the data type of the member var.  See ClassRep().
+    q=_d+ml->offset;
+
+    if (print_str=MemberMetaData("print_str",ml))
+      "" print_str,*q;
+
+      //This is slightly ambiguous -- if no meta is present it will return zero.
+    if (dft_val=MemberMetaData("dft_val",ml))
+      " default:%d",dft_val;
+
+      //This corrects for the ambiguity, allowing zero percentile.
+    if (MemberMetaFind("percentile",ml)) {//check if it exists
+//We could use the CMemberLstMeta structure returned by
+      //MemberMetaFind() and save a search.
+      percentile=MemberMetaData("percentile",ml)(F64);
+      " percentile: %5.2f",percentile;
+    }
+
+    if (fp_output_fun=MemberMetaData("output_fun",ml))
+      (*fp_output_fun)(*q);
+    '\n';
+    ml=ml->next;
+  }
+}
+
+Test1Struct t1;
+t1.age=44;
+t1.rank=3;
+
+DumpStruct(&t1);
+
+Test2Struct t2;
+t2.age=22;
+t2.rank=2;
+t2.serial_num=55555;
+
+DumpStruct(&t2);
+
+ diff --git a/public/Wb/Demo/CompileDemo.HC.HTML b/public/Wb/Demo/CompileDemo.HC.HTML new file mode 100755 index 0000000..66e44a5 --- /dev/null +++ b/public/Wb/Demo/CompileDemo.HC.HTML @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+F64 glbl;
+
+F64 CompileDemo(U8 *st)
+{
+  I64 type;
+  U8 *machine_code;
+  CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
+  F64 res=0;
+  Lex(cc);  //Gotta get it started
+  "Compile \"%s\"\n",st;
+  do {
+    if (machine_code=LexExpression2Bin(cc,&type)) {
+      if (type!=RT_F64)
+        res=ToF64(Call(machine_code));
+      else
+        res=Call(machine_code)(F64);
+      Free(machine_code);
+    }
+    "res=%9.4f\n",res;
+    if (cc->token==';')
+      Lex(cc);
+  } while (cc->token!=TK_EOF);  //end of file?
+  CmpCtrlDel(cc);
+  return res;
+}
+
+CompileDemo("2+Cos(pi)");
+CompileDemo("1;2+4");
+CompileDemo("glbl=1;glbl*2;glbl/3;Sin(glbl)");
+
+//This is just like you typed-it on
+//the cmd line.
+ExePrint(
+"I64 i;"
+"for (i=0;i<10;i++) "
+"  \"%%d\n\",i;"
+);
+
+ diff --git a/public/Wb/Demo/DateTime.HC.HTML b/public/Wb/Demo/DateTime.HC.HTML new file mode 100755 index 0000000..1a802ad --- /dev/null +++ b/public/Wb/Demo/DateTime.HC.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+
+"\n\n%D %T\n\n\n",Now,Now;
+
+CDateStruct ds;
+Date2Struct(&ds,Now+local_time_offset);
+
+"Hour:%02d Minute:%02d Second:%02d\n\n\n",ds.hour,ds.min,ds.sec;
+
+"Day Name:%03tZ\n\n\n",ds.day_of_week,"ST_DAYS_OF_WEEK";
+
+"Month Name:%03tZ\n\n\n",ds.mon-1,"ST_MONTHS";
+
+ diff --git a/public/Wb/Demo/DbgDemo.HC.HTML b/public/Wb/Demo/DbgDemo.HC.HTML new file mode 100755 index 0000000..87d0fd7 --- /dev/null +++ b/public/Wb/Demo/DbgDemo.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+/*
+Press <CTRL-ALT-c> to break.
+
+Rerun Program
+
+Press <CTRL-ALT-d> to enter Dbg.
+> Dr;   //Dump Regs
+> G2;   //Cont program
+
+Press <CTRL-ALT-d> to enter Dbg.
+> Uf("DbgDemo");
+> U(_RIP);
+
+See Debugging
+*/
+
+U0 DbgDemo()
+{
+  I64 i=0;
+  while (TRUE)
+    if (!(i++%2000000))
+      ".";
+}
+
+DbgDemo;
+
+
+ diff --git a/public/Wb/Demo/Define.HC.HTML b/public/Wb/Demo/Define.HC.HTML new file mode 100755 index 0000000..d2354ad --- /dev/null +++ b/public/Wb/Demo/Define.HC.HTML @@ -0,0 +1,67 @@ + + + + + + + + + + + +
+//See Define.
+
+//These might be in the Adam task.
+DefineLoad("ST_YES_NO","(Yes or No)");
+DefineLoad("ST_EXIT","Exit");
+DefineLstLoad("ST_NO_YES_LST","No\0Yes\0");
+
+//New strings might be loaded for each user
+//to override.
+
+"Spanish";
+if (YorN) {
+  DefineLoad("ST_YES_NO","(Si or No)");
+  DefineLoad("ST_EXIT","Salida");
+  DefineLstLoad("ST_NO_YES_LST","No\0Si\0");
+}
+
+Bool Quit()
+{
+  Bool res;
+  U8 *st;
+  I64 i;
+  while (TRUE) {
+    "%S %S?","ST_EXIT","ST_YES_NO";
+    st=GetStr;
+    i=DefineMatch(st,"ST_NO_YES_LST",LMF_IGNORE_CASE);
+    if (i>=0) {
+      res=i;
+      break;
+    }
+    Free(st);
+  }
+  return res;
+}
+
+Quit;
+
+ diff --git a/public/Wb/Demo/Directives.HC.HTML b/public/Wb/Demo/Directives.HC.HTML new file mode 100755 index 0000000..d6ebfb5 --- /dev/null +++ b/public/Wb/Demo/Directives.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+U0 Directives()
+{
+  "Date\t:%s\n",__DATE__;
+  "Time\t:%s\n",__TIME__;
+  "File\t:%s\n",__FILE__;
+  "Dir\t:%s\n",__DIR__;
+  "Line\t:%d\n",__LINE__;
+  "CmdLine\t:%d\n",__CMD_LINE__;
+  "Inst1\t:%P:%08X\n",$,$;
+  "Inst2\t:%P:%08X\n",$,$;
+}
+
+Directives;
+
+ diff --git a/public/Wb/Demo/DolDoc/CallBack.HC.HTML b/public/Wb/Demo/DolDoc/CallBack.HC.HTML new file mode 100755 index 0000000..815f1b2 --- /dev/null +++ b/public/Wb/Demo/DolDoc/CallBack.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+U8 *tSCB(CDoc *,CDocEntry *,CTask *mem_task)
+{//This is called by the window mgr.
+//Things would get corrupted
+  //if the window mgr used it's own
+  //heap, so we use the owning task's heap.
+  U8 *st=MAlloc(64,mem_task);
+  CDate cdt=tS*CDATE_FREQ;
+//Doesn't have to be fixed width!!
+  StrPrint(st,"%d=%T",cdt,cdt);
+  return st;
+}
+
+U8 *CurTimeCB(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  CDate cdt=Now;
+  StrPrint(st,"%D %T",cdt,cdt);
+  return st;
+}
+
+U0 DoIt()
+{
+  CDoc *bdoc=DocBorder,*pdoc=DocPut;
+  CDocEntry *doc_e;
+
+  DocLock(bdoc);
+  DocBottom(bdoc);  //Ins at the bottom
+  DocPrint(bdoc,"$RED$$CM+BY+LX,5,-3$");
+//The DocPrint() routine returns the addr of the last entry.
+  doc_e=DocPrint(bdoc,"$TX+TC,\" \"$");
+//The TC flag is "has tag callback".
+
+  //Flags are explained here:
+  //::/Doc/DolDocOverview.DD    ::/Doc/Widget.DD
+  //Dollar Flags                ST_DOC_FLAGS
+  doc_e->tag_cb=&tSCB;
+  DocPrint(bdoc,"$FG$");
+  DocUnlock(bdoc);
+
+  //WARNING: If you use the put_doc you
+  //run the risk of the user pressing
+  //<CTRL-t> or using the clip, both
+  //of which will crash.        So, you might want
+  //to use the border_doc.
+
+  DocLock(pdoc);
+  DocPrint(pdoc,"$LTRED$");
+  doc_e=DocPrint(pdoc,"$TX+TC,\" \"$");
+  doc_e->tag_cb=&CurTimeCB;
+  DocPrint(pdoc,"$FG$");
+  DocUnlock(pdoc);
+
+  //Send carriage return, new line, so
+  //that the timer string is not part
+  //of the next cmd on the cmd line.
+  '\n';
+}
+
+U0 UndoIt()
+{//Clear-out entries without a +H hold flag.
+  DocClear(Fs->border_doc);
+}
+
+DoIt;
+
+ diff --git a/public/Wb/Demo/DolDoc/ClickCallBack.HC.HTML b/public/Wb/Demo/DolDoc/ClickCallBack.HC.HTML new file mode 100755 index 0000000..3959bbb --- /dev/null +++ b/public/Wb/Demo/DolDoc/ClickCallBack.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+I64 MyLeftCB1(CDoc *,CDocEntry *)
+{
+  I64 i;
+  for (i=500;i<1000;i+=25) {
+    Snd(Freq2Ona(i));
+    Sleep(10);
+  }
+  Snd;
+  return 0;
+}
+
+U0 ClickCallBack()
+{
+  CDocEntry *doc_e;
+  DocLock(DocPut);
+//The DocPrint() routine returns the addr of the last entry.
+  doc_e=DocPrint(DocPut,"\n$MA+LC,\"Click Me\"$ ");
+//The LC flag is "has left callback".
+
+  //Flags are explained here:
+  //::/Doc/DolDocOverview.DD    ::/Doc/Widget.DD
+  //Dollar Flags                ST_DOC_FLAGS
+  "(Not preserved if you press <CTRL-t>.)\n\n";
+  doc_e->left_cb=&MyLeftCB1;
+  DocUnlock(DocPut);
+}
+
+ClickCallBack;
+
+I64 MyLeftCB2(CDoc *,CDocEntry *)
+{
+  return cnts.jiffies;
+}
+
+U0 PopUpJiffiesCallBack(I64 i)
+{
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e=DocPrint(doc,
+        "Click %d more times\n\n\n$BT+LC,\"Jiffies\"$\n\n\n",i);
+  doc_e->left_cb=&MyLeftCB2;
+  "Current Jiffies:%d\n",PopUpMenu(doc);
+  DocDel(doc);
+}
+
+PopUpJiffiesCallBack(3);
+PopUpJiffiesCallBack(2);
+PopUpJiffiesCallBack(1);
+
+ diff --git a/public/Wb/Demo/DolDoc/CursorMove.HC.HTML b/public/Wb/Demo/DolDoc/CursorMove.HC.HTML new file mode 100755 index 0000000..bd72ef0 --- /dev/null +++ b/public/Wb/Demo/DolDoc/CursorMove.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+U0 CursorMovementDemo()
+{
+  I64 i;
+  for (i=0;i<100;i++) {
+    "%03d ",i;
+    "$CM,-4,1$";
+    if (i%10==9)
+      "$CM,4,-10$";
+  }
+
+  //+LX is relative to left side.
+  //See <CTRL-l> with cursor-movement for all the flags.
+  //Check "Quote" to set-up a cmd for in quotes.
+  "$CM+LX,0,+10$\n";
+}
+
+CursorMovementDemo;
+
+/*The word-wrap Off and On cmds are
+$WW,0$ and $WW,1$.
+
+You might need DocMax() to adjust
+the cmd line window buf size.
+It counts cmds, not lines.
+
+The +H flag will hold-onto an entry
+so it doesn't get pushed-out of the document.
+This is useful for a $WW+H,1$ cmd.
+
+See ::/Doc/DolDocOverview.DD for documentation on
+all flags and cmds.
+
+Note: the default page length is 66 lines
+and branching back more than the page length
+will rst the column to 1.  So, set page
+length to a large number if you want to
+branch back a long distance.
+*/
+
+ diff --git a/public/Wb/Demo/DolDoc/Data.HC.HTML b/public/Wb/Demo/DolDoc/Data.HC.HTML new file mode 100755 index 0000000..891811e --- /dev/null +++ b/public/Wb/Demo/DolDoc/Data.HC.HTML @@ -0,0 +1,94 @@ + + + + + + + + + + + +
+/*$DA   is the data widget.
+   -TRM flag is for var
+        width fields with a terminator
+        character.
+   +RD  refreshes the data.
+   +UD  updates the val when you edit it.
+
+   -P   Means it is a string var, basically.
+
+   ,32  sets the tag string width.
+        See Data Tag Width.
+
+   ,RT=I16 means the val is 2 bytes.
+        See DocDataFmt() and DocDataScan().
+*/
+
+I16 i=0;
+U8 buf[8];
+
+U0 UpdateGlblTask(I64)
+{
+  while (TRUE) {
+    i++;
+    Sleep(1);
+  }
+}
+
+U0 DataDemo()
+{
+  CDocEntry *doc_e;
+
+  //This is the command line document.
+  CDoc *doc=DocPut;
+
+  //We do this to prevent access to
+  //doc_e->data before it is set.
+  Bool unlock=DocLock(doc);
+
+  //You might set the DOCF_FORM flag.
+  //  doc->flags|=DOCF_FORM
+  //if you wish.
+
+  Spawn(&UpdateGlblTask,NULL,"Update Glbl",,Fs);
+
+  "Enter editor overstrike mode\n"
+        "and you can modify the val.\n"
+        "However, changes happen immediately,\n"
+        "so it's tricky.\n\n";
+//Use <CTRL-l> for the $DA...$ format.
+  doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I16,A=\"%%7d\"$\n");
+  doc_e->data=&i;
+
+  StrCpy(buf,"Terry");
+  doc_e=DocPrint(doc,"$DA-P+RD+UD,LEN=7,A=\"Str:%%s\"$\n");
+  doc_e->data=buf;
+
+  if (unlock)
+    DocUnlock(doc);
+}
+
+DataDemo;
+
+//See PopUpExtents().
+
+ diff --git a/public/Wb/Demo/DolDoc/DefineStr.HC.HTML b/public/Wb/Demo/DolDoc/DefineStr.HC.HTML new file mode 100755 index 0000000..44a7680 --- /dev/null +++ b/public/Wb/Demo/DolDoc/DefineStr.HC.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+/*The +D flag causes a define-string
+look-up and substitution.
+
+It is available in the <CTRL-l> text-widget
+menu under text entries for use in
+documentation.
+
+*/
+
+DefineLoad("COMPANY","Acme Inc");
+"Company: $TX,\"\",D=\"COMPANY\"$\n";
+
+DefinePrint("COMPANY_TIME","%T",Now);
+
+#exe {
+  StreamPrint(
+    "#define COMPANY_AGE %0.1f\n",
+    (Now-Str2Date("8/1/2003"))/ToF64(1<<32)/CDATE_YEAR_DAYS);
+};
+
+"Age : $TX,\"\",D=\"COMPANY_AGE\"$ years\n";
+"Time: $TX,\"\",D=\"COMPANY_TIME\"$\n";
+
+ diff --git a/public/Wb/Demo/DolDoc/FileRead.HC.HTML b/public/Wb/Demo/DolDoc/FileRead.HC.HTML new file mode 100755 index 0000000..444f861 --- /dev/null +++ b/public/Wb/Demo/DolDoc/FileRead.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+public U0 DocProfile(U8 *filename,I64 flags)
+{
+  I64 i,*cmd_stats=CAlloc(sizeof(I64)*DOCT_TYPES_NUM),
+        *flags_stats=CAlloc(sizeof(I64)*64),
+        *type_flags_stats=CAlloc(sizeof(I64)*64);
+//Note: word wrap is determined by
+  //doc->win_task when a CDoc is recalculated
+  //use DocRecalc().
+  CDoc *doc=DocRead(filename,flags);
+
+  //doc->head which is equ to doc is the
+  //header of the CQue and represents the end-of-file marker.
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    cmd_stats[doc_e->type_u8]++;
+    for (i=0;i<64;i++)
+      if (Bt(&doc_e->de_flags,i))
+        flags_stats[i]++;
+    for (i=16;i<32;i++)
+      if (Bt(&doc_e->type,i))
+        type_flags_stats[i]++;
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+
+  "$PURPLE$-------%s-------\n",filename;
+  "$GREEN$The lowest byte of the 32-bit 'doc_e->type', "
+        "'$PURPLE$doc_e->type.u8[0]$GREEN$', "
+        "is cmd and accessed with the union "
+        "'$PURPLE$doc_e->type_u8$GREEN$'.  "
+        "See $LK,\"CDocEntry\",A=\"MN:CDocEntry\"$, "
+        "$LK,\"Doc Type Defines\",A=\"MN:DOCT_TEXT\"$ and "
+        "$LK,\"Doc Type Codes\","
+        "A=\"FF:::/Adam/DolDoc/DocInit.HC,ST_DOC_CMDS\"$.\n"
+        "$FG$";
+  for (i=0;i<DOCT_TYPES_NUM;i++)
+    if (cmd_stats[i])
+      "%4Z:%d\n",i,"ST_DOC_CMDS",cmd_stats[i];
+
+  "\n$GREEN$'$PURPLE$doc_e->type.u8[1]$GREEN$' is "
+        "the scrn color attr of the "
+        "entry.  '$PURPLE$doc_e->type.u16[1]"
+        "$GREEN$' is some flags for blinking and "
+        "stuff.  See $LK,\"Doc Type Flag "
+        "Defines\",A=\"MN:DOCET_BLINK\"$.\n$FG$";
+
+  for (i=16;i<32;i++)
+    if (type_flags_stats[i])
+      "%4d:%d\n",i,type_flags_stats[i];
+
+  "$GREEN$\n'$PURPLE$doc_e->de_flags$GREEN$' is 64-bit.  "
+        "See $LK,\"Doc Flag Defines\",A=\"MN:DOCEf_TAG\"$ and "
+        "$LK,\"Doc Flag Codes\","
+        "A=\"FF:::/Adam/DolDoc/DocInit.HC,ST_DOC_FLAGS\"$.\n"
+        "$FG$";
+  for (i=0;i<64;i++)
+    if (flags_stats[i])
+      "%4Z:%d\n",i,"ST_DOC_FLAGS",flags_stats[i];
+
+  Free(cmd_stats);
+  Free(flags_stats);
+  PressAKey;
+  '\n';
+}
+
+/*See TipOfDay.
+
+Note: Not all CDocEntry's are full-sized nodes.
+Some are MAlloced with a smaller size to save
+mem.    They all have at least the size CDocEntryBase.
+
+Note: CDocEntry's should be alloced from the
+heap of the owning task, doc->mem_task.
+
+The flag arrays doldoc.type_flags_form, etc
+are useful.
+*/
+
+DocProfile("::/Doc/Welcome.DD",0);
+DocProfile("::/Doc/Welcome.DD",DOCF_PLAIN_TEXT);
+
+ diff --git a/public/Wb/Demo/DolDoc/Form.HC.HTML b/public/Wb/Demo/DolDoc/Form.HC.HTML new file mode 100755 index 0000000..d77ebc6 --- /dev/null +++ b/public/Wb/Demo/DolDoc/Form.HC.HTML @@ -0,0 +1,82 @@ + + + + + + + + + + + +
+class FDStruct
+{//Use <CTRL-l> and sel "Data", "List" or "Check Box"
+//to generate the formats.
+  F64 num1      format "$DA-TRM,A=\"Float 1:%12.8f\"$\n";
+  F64 num2      format "$DA-TRM,A=\"Float 2:%12e\"$\n";
+  I64 num3      format "$DA-TRM,A=\"Int   1:0x%016X\"$\n";
+  I64 num4      format "$DA-TRM,A=\"Int   2:%12d\"$\n";
+  I64 type      format "$LS,D=\"ST_PERSON_TYPE\"$\n";
+  U8  name[32]  format "$DA-P,A=\"Name   :%s\"$\n";
+  U8  *address1 format "$DA+M,A=\"Address:%s\"$\n"; //+M is unlimited len U8 *.
+  U8  *address2 format "$DA+M,A=\"Address:%s\"$\n"; //+M is unlimited len U8 *.
+  CDate datetime format "$DA-TRM,A=\"Date   :%8D\"$\n";
+  Bool  check   format "$CB,\"Check\"$\n";
+};
+
+U0 FormDemo()
+{
+  FDStruct fds;
+  DefineLstLoad("ST_PERSON_TYPE","Child\0Teen\0Adult\0");
+  fds.num1=12.3e-4;     //Set defaults
+  fds.num2=4.5e3;
+  fds.num3=0x1234;
+  fds.num4=-567;
+  fds.type=1;
+  StrCpy(&fds.name,"John");
+  fds.address1=StrNew("1234 Pine St.");
+  fds.address2=NULL;    //Init to NULL if empty.
+  fds.datetime=Now;
+  fds.check=TRUE;
+  if (DocForm(&fds)) {
+    "#1\t=%e\n",fds.num1;
+    "#2\t=%e\n",fds.num2;
+    "#3\t=%d\n",fds.num3;
+    "#4\t=%d\n",fds.num4;
+    "Type\t=%s\n",DefineSub(fds.type,"ST_PERSON_TYPE");
+    "Name\t=%s\n",fds.name;
+    "Address1=%s\n",fds.address1;
+    "Address2=%s\n",fds.address2;
+    "Date\t=%D\n",fds.datetime;
+    "Check\t=%d\n",fds.check;
+  } else
+    "Cancel\n";
+
+  "\n\nClassRep Example\n";
+  ClassRep(&fds);
+  Free(fds.address1);
+  Free(fds.address2);
+  //See also ClassRepD().
+}
+
+FormDemo;
+
+ diff --git a/public/Wb/Demo/DolDoc/MenuBttn.HC.HTML b/public/Wb/Demo/DolDoc/MenuBttn.HC.HTML new file mode 100755 index 0000000..16eb91a --- /dev/null +++ b/public/Wb/Demo/DolDoc/MenuBttn.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+//This example shows bttns.  Bttns return a menu val
+//unless you rig them to send macros.  Menu entries are
+//about the same as bttns, but don't have a border.
+
+I64 PopUpFreq()
+{//See also PopUpRangeI64()
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$TX+CX,\"Set Freq\"$\n" //Centered text
+        "$CM+LX,2,4$$BT,\"100 Hz\",LE=100$"
+        "$CM+LX,18,0$$BT,\"200 Hz\",LE=200$"
+        "$CM+LX,2,4$$BT,\"400 Hz\",LE=400$"
+        "$CM+LX,18,0$$BT,\"800 Hz\",LE=800$\n");
+  i=PopUpMenu(doc);
+  if (i<0) i=0; // <SHIFT-ESC>
+  DocDel(doc);
+  return i;
+}
+
+#define MU_NOTHING      0
+#define MU_SET_FREQ     1
+#define MU_SND_ON       2
+#define MU_SND_OFF      3
+
+U0 MenuBttn()
+{
+  Bool done=FALSE;
+  I64 i,j=0,freq=100;
+  I64 old_flags=DocPut->flags;
+//This allows keyboard navigation to skip nonselible entries.
+  DocPut->flags|=DOCF_FORM;
+  do {
+    DocClear;
+//Use <CTRL-l> to generate cursor movement expressions and check "Quote".
+    "$CM+CX-RE,-4$Menu Demo\n\n";
+    "$LM,8$"; //Set left margin
+//These are bttns that return a val from a menu selection.
+    if (!j)
+      "\n$BT,\"Snd On\",LE=MU_SND_ON$\n\n\n";
+    else
+      "\n$BT,\"Snd Off\",LE=MU_SND_OFF$\n\n\n";
+    "\n$BT,\"Set Freq\",LE=MU_SET_FREQ$\n\n\n"
+          "\n$BT,\"Nothing\",LE=MU_NOTHING$\n\n\n"
+          "\n$BT,\"Done\",LE=DOCM_CANCEL$\n\n\n";
+    i=DocMenu(DocPut);
+    DocBottom;
+    switch (i) {
+      case MU_NOTHING:
+        break;
+      case MU_SND_ON:
+        j=freq;
+        Snd(Freq2Ona(j));
+        break;
+      case MU_SND_OFF:
+        j=0;
+        Snd;
+        break;
+      case MU_SET_FREQ:
+        freq=PopUpFreq;
+        if (j) {
+          j=freq;
+          Snd(Freq2Ona(j));
+        }
+        break;
+      default:
+        done=TRUE;
+    }
+  } while (!done);
+  DocPut->flags=DocPut->flags&~DOCF_FORM |
+        old_flags & DOCF_FORM;
+  DocClear;
+  Snd;
+}
+
+MenuBttn;
+
+ diff --git a/public/Wb/Demo/DolDoc/MenuSprite.HC.HTML b/public/Wb/Demo/DolDoc/MenuSprite.HC.HTML new file mode 100755 index 0000000..ebcace6 --- /dev/null +++ b/public/Wb/Demo/DolDoc/MenuSprite.HC.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+U0 MenuSprite()
+{
+  I64 i;
+  DocPut->flags|=DOCF_FORM; //Cursor navigation will skip empty locations.
+  while (TRUE) {
+    DocClear;
+    '\n';
+
+    //Sprite with flags for left-expression and an exit.
+    //See doldoc.dft_de_flags.  Note the %d in the string for the sprite number.
+    Sprite(<1>,"$LTBLUE$$SP+X,\"50 Hz\",LE=50,BI=%d$");
+
+    "\n\n\n"
+          "$MU,\"100 Hz\",LE=100$\n"
+          "$MU,\"200 Hz\",LE=200$\n"
+          "$MU,\"CANCEL\",LE=DOCM_CANCEL$\n";
+    i=DocMenu(DocPut);
+    if (i>0)
+      Snd(Freq2Ona(i));
+    else
+      break;
+  }
+  Snd;
+  DocClear;
+  '\n';
+  DocPut->flags&=~DOCF_FORM;
+}
+
+MenuSprite;
+ diff --git a/public/Wb/Demo/DolDoc/NumBible.HC.HTML b/public/Wb/Demo/DolDoc/NumBible.HC.HTML new file mode 100755 index 0000000..0ad6517 --- /dev/null +++ b/public/Wb/Demo/DolDoc/NumBible.HC.HTML @@ -0,0 +1,59 @@ + + + + + + + + + + + +
+//  This makes a new Bible file
+//with line numbers.
+
+U0 NumBible()
+{
+  CDoc *doc_in=DocRead("::/Misc/Bible.TXT.Z",DOCF_PLAIN_TEXT_TABS),
+        *doc_out=DocNew("~/DemoNumBible.DD.Z");
+  CDocEntry *doc_e=doc_in->head.next;
+  while (doc_e!=doc_in) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      DocPrint(doc_out,"%05d %s",doc_e->y+1,doc_e->tag);
+      doc_e=doc_e->next;
+      if (doc_e->type_u8==DOCT_NEW_LINE) {
+        DocPrint(doc_out,"\n");
+        doc_e=doc_e->next;
+      }
+    } else if (doc_e->type_u8==DOCT_NEW_LINE) {
+      DocPrint(doc_out,"%05d\n",doc_e->y+1);
+      doc_e=doc_e->next;
+    } else
+      doc_e=doc_e->next;
+  }
+  doc_out->flags|=DOCF_NO_CURSOR;
+  DocWrite(doc_out);
+  DocDel(doc_out);
+  DocDel(doc_in);
+}
+
+NumBible;
+ diff --git a/public/Wb/Demo/DolDoc/TextDemo.HC.HTML b/public/Wb/Demo/DolDoc/TextDemo.HC.HTML new file mode 100755 index 0000000..48795f8 --- /dev/null +++ b/public/Wb/Demo/DolDoc/TextDemo.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+        "\nSuper    : 3$SY,-3$2$SY,0$=9\n\n"
+        "Sub      : H$SY,3$2$SY,0$O\n\n"
+        "Color    : $RED$Test$FG$\n\n"
+        "Blink    : $BK,1$Test$BK,0$\n\n"
+        "Invert   : $IV,1$Test$IV,0$\n\n"
+        "UnderLine: $UL,1$Test$UL,0$\n\n"
+        "Link     : $LK,\"Genesis,1:1\",\"BF:Genesis,1:1\"$\n\n\n"
+
+        "Bttn   :     $BT-X,\"OKAY\",LE=1$\n\n\n\n";
+
+//You can do it this way if you like.
+        "\nSuper    : 32=9\n\n"
+        "Sub      : H2O\n\n"
+//Can't see color because of syntax highlighting.  Press <CTRL-t>
+        "Color    : Test\n\n"
+        "Blink    : Test\n\n"
+        "Invert   : Test\n\n"
+        "UnderLine: Test\n\n"
+//<CTRL-SHIFT-T> on this link to toggle individual commands.
+        "Link     : Genesis,1:1\n\n\n"
+
+        "Bttn   :     OKAY\n\n\n\n";
+
+ diff --git a/public/Wb/Demo/DolDoc/TreeDemo.HC.HTML b/public/Wb/Demo/DolDoc/TreeDemo.HC.HTML new file mode 100755 index 0000000..cb6ddeb --- /dev/null +++ b/public/Wb/Demo/DolDoc/TreeDemo.HC.HTML @@ -0,0 +1,70 @@ + + + + + + + + + + + +
+U0 TreeSub(CDoc *doc,CDirEntry *tmpde)
+{
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      DocPrint(doc,"$TR,\"\"$");
+      DocPrint(doc,"$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$\n",
+            tmpde->name,tmpde->full_name);
+      if (tmpde->sub) {
+        DocPrint(doc,"$ID,+2$");
+        TreeSub(doc,tmpde->sub);
+        DocPrint(doc,"$ID,-2$");
+      }
+    } else
+      DocPrint(doc,"$LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->name,tmpde->full_name);
+//Note there is also a routine
+      //to delete an entire CDirEntry tree.
+      //See DirTreeDel().
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+}
+
+U0 TreeDemo()
+{
+  I64 fuf_flags=0;
+  CDoc *doc=DocNew;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  DocPrint(doc,"$TR-C,\"\"$\n");
+  DocPrint(doc,"$ID,+2$");
+  TreeSub(doc,FilesFind("/*",fuf_flags));
+  DocPrint(doc,"$ID,-2$");
+  DocInsDoc(DocPut,doc);
+  DocDel(doc);
+}
+ 
+TreeDemo;
+
+ diff --git a/public/Wb/Demo/DolDoc/UnusedDefine.HC.HTML b/public/Wb/Demo/DolDoc/UnusedDefine.HC.HTML new file mode 100755 index 0000000..59198ac --- /dev/null +++ b/public/Wb/Demo/DolDoc/UnusedDefine.HC.HTML @@ -0,0 +1,113 @@ + + + + + + + + + + + +
+/*Scans the sym table and checks
+each HTT_DEFINE_STR entry to see if
+it only occurs once in files.
+
+It's a brute force solution, but
+gets the job done... slowly.
+
+Find() returns a count of matches.
+
+FileOcc() is Find() with
+output Silent().
+*/
+
+U0 UnusedDefineScan()
+{
+  CDoc *old_put_doc,*old_display_doc,*doc;
+  I64 i,cnt=0;
+  CHashTable *table;
+  CHash *tmph;
+  CDocEntry *doc_e,*doc_e2;
+  Bool old_silent=IsSilent;
+
+  try {
+    table=Fs->hash_table;
+    while (table) {
+      for (i=0;i<=table->mask;i++) {
+        tmph=table->body[i];
+        while (tmph) {
+          if (tmph->type&HTT_DEFINE_STR)
+            cnt++;
+          tmph=tmph->next;
+        }
+      }
+      table=table->next;
+    }
+
+    progress1=0;
+    progress1_max=cnt;
+    StrCpy(progress1_desc,"Define Scan");
+
+    table=Fs->hash_table;
+    while (table) {
+      for (i=0;i<=table->mask;i++) {
+        tmph=table->body[i];
+        while (tmph) {
+          if (tmph->type&HTT_DEFINE_STR) {
+            progress1++;
+            if (FileOcc(tmph->str,"/*","+l-i+$")==1) {
+              doc=DocNew;
+              old_put_doc=DocPut;
+              old_display_doc=DocDisplay;
+              Fs->put_doc=Fs->display_doc=doc;
+              Find(tmph->str,"/*","+l-i+$");
+              Fs->put_doc=old_put_doc;
+              Fs->display_doc=old_display_doc;
+              doc_e=doc->head.next;
+              while (doc_e!=doc) {
+                if (doc_e->type_u8==DOCT_LINK) {
+                  "%s ",tmph->str;
+                  doc_e2=DocEntryCopy(doc,doc_e);
+                  DocInsEntry(old_put_doc,doc_e2);
+                  '\n';
+                }
+                doc_e=doc_e->next;
+              }
+              DocDel(doc);
+            }
+          }
+          tmph=tmph->next;
+        }
+      }
+      table=table->next;
+    }
+  } catch
+    PutExcept;
+
+  Silent(old_silent);
+  '\n';
+  ProgressBarsRst;
+}
+
+UnusedDefineScan;
+
+ diff --git a/public/Wb/Demo/Dsk/BlkDevRep.HC.HTML b/public/Wb/Demo/Dsk/BlkDevRep.HC.HTML new file mode 100755 index 0000000..f877e00 --- /dev/null +++ b/public/Wb/Demo/Dsk/BlkDevRep.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+U0 BlkDevRep()
+{//Block Device Report.
+  I64 i;
+  for (i=0;i<BLKDEVS_NUM;i++)
+    if (blkdev.blkdevs[i].bd_signature==BD_SIGNATURE_VAL)
+      //ClassRep() dumps any structure, automatically.
+      ClassRep(&blkdev.blkdevs[i]);
+      //The lastclass arg tells ClassRep the datatype.
+      //lastclass is a language feature of HolyC.
+      //See ::/Demo/LastClass.HC.
+}
+
+BlkDevRep;
+
+ diff --git a/public/Wb/Demo/Dsk/DataBase.HC.HTML b/public/Wb/Demo/Dsk/DataBase.HC.HTML new file mode 100755 index 0000000..c9e5469 --- /dev/null +++ b/public/Wb/Demo/Dsk/DataBase.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+#define DB_FILENAME     "~/DataBaseDemo.BIN"
+#define DB_ACCT_MAX     100
+#define DB_ACCT_BLKS    1
+
+class Acct
+{//Use <CTRL-l> to help generate formats.
+  U8 name[32] format "$DA-P,LEN=32,A=\"Name:%s\"$\n";
+  U8 addr[64] format "$DA-P,LEN=64,A=\"Addr:%s\"$\n";
+  U8 pad[DB_ACCT_BLKS*BLK_SIZE-64-32];
+};
+
+U0 InitDatabase()
+{ //Write new contiguous file
+  CFile *f=FOpen(DB_FILENAME,"w",DB_ACCT_MAX*DB_ACCT_BLKS);
+  FClose(f);
+}
+
+U0 WriteAcct()
+{
+  CFile *f;
+  Acct a;
+  I64 acctnum;
+
+  acctnum=GetI64("Acct #",-1);
+  if (0<=acctnum<DB_ACCT_MAX) {
+    MemSet(&a,0,BLK_SIZE);
+    if (DocForm(&a)) {
+      f=FOpen(DB_FILENAME,"w+");
+      FBlkWrite(f,&a,acctnum*DB_ACCT_BLKS,DB_ACCT_BLKS);
+      FClose(f);
+    }
+  }
+}
+
+U0 ReadAcct()
+{
+  CFile *f;
+  Acct a;
+  I64 acctnum;
+
+  acctnum=GetI64("Acct #",-1);
+  if (0<=acctnum<DB_ACCT_MAX) {
+    f=FOpen(DB_FILENAME,"r");
+    FBlkRead(f,&a,acctnum*DB_ACCT_BLKS,DB_ACCT_BLKS);
+    FClose(f);
+    ClassRep(&a);
+  }
+}
+
+U0 DatabaseDemo()
+{
+  I64 ch;
+  if (!FileFind(DB_FILENAME))
+    InitDatabase;
+  do {
+    "$GREEN$R$FG$ead acct, $GREEN$W$FG$rite acct or $GREEN$<SHIFT-ESC>$FG$:";
+    ch=ToUpper(GetChar);
+    '\n';
+    if (ch=='R') ReadAcct;
+    if (ch=='W') WriteAcct;
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+}
+
+DatabaseDemo;
+
+ diff --git a/public/Wb/Demo/Dsk/DskRaw.HC.HTML b/public/Wb/Demo/Dsk/DskRaw.HC.HTML new file mode 100755 index 0000000..7ac928e --- /dev/null +++ b/public/Wb/Demo/Dsk/DskRaw.HC.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+U0 RawAccess(I64 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  I64 blk,old_offset,old_size;
+  U8 *buf=MAlloc(BLK_SIZE);
+
+  DrvRep;
+  PressAKey;
+
+  ClassRep(dv);
+  PressAKey;
+
+  ClassRep(bd);
+  PressAKey;
+
+  //Temporarily change partition range to full device.
+  //Normally, you are limited to just your partition.
+  //This is obviously dangerous!
+  old_offset=dv->drv_offset;
+  old_size  =dv->size;
+  dv->drv_offset=0;
+  dv->size=bd->max_blk+1;
+
+  try {
+    blk=GetI64("Blk to Read: ",old_offset,0,bd->max_blk);
+    BlkRead(dv,buf,blk,1);
+    D(buf,BLK_SIZE);
+  } catch
+    PutExcept;
+
+  dv->drv_offset=old_offset;
+  dv->size  =old_size;
+
+  Free(buf);
+}
+
+RawAccess;
+
+//See BlkRead(), BlkWrite(), DrvLock(), DrvUnlock()
+//DBlk(), DClus(), BlkDevLock() and BlkDevUnlock().
+
+ diff --git a/public/Wb/Demo/Dsk/FPrintF.HC.HTML b/public/Wb/Demo/Dsk/FPrintF.HC.HTML new file mode 100755 index 0000000..eace17d --- /dev/null +++ b/public/Wb/Demo/Dsk/FPrintF.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+/*There is no FPrintF type function and no
+way to grow files. Therefore, use mem to
+hold the file until you are done.  The CDoc
+framework is convenient for this.
+*/
+
+U0 TreeSub(CDoc *doc,CDirEntry *tmpde)
+{
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      DocPrint(doc,"$TR,\"\"$");
+      DocPrint(doc,"$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$\n",
+            tmpde->name,tmpde->full_name);
+      if (tmpde->sub) {
+        DocPrint(doc,"$ID,+2$");
+        TreeSub(doc,tmpde->sub);
+        DocPrint(doc,"$ID,-2$");
+      }
+    } else
+      DocPrint(doc,"$LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->name,tmpde->full_name);
+//Note there is also a routine
+      //to delete an entire CDirEntry tree.
+      //See DirTreeDel().
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+}
+
+U0 FPrintFDemo(U8 *output_filename=NULL)
+{
+  I64 fuf_flags=0;
+  CDoc *doc=DocNew(output_filename);
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  DocPrint(doc,"$TR-C,\"\"$\n");
+  DocPrint(doc,"$ID,+2$");
+  TreeSub(doc,FilesFind("/*",fuf_flags));
+  DocPrint(doc,"$ID,-2$");
+  DocRecalc(doc);
+  if (output_filename)
+    DocWrite(doc,FALSE);
+  else
+    DocWrite(doc,TRUE);
+  DocDel(doc);
+}
+
+FPrintFDemo;
+
+ diff --git a/public/Wb/Demo/Dsk/SerializeTree.HC.HTML b/public/Wb/Demo/Dsk/SerializeTree.HC.HTML new file mode 100755 index 0000000..2b7733b --- /dev/null +++ b/public/Wb/Demo/Dsk/SerializeTree.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+/*You probably don't need this.  It makes a directory
+tree into a flat contiguous memory chunk, suitable for
+serial communication and rebuilds it into a tree on the
+other end.
+*/
+
+U0 SerializeTree()
+{
+  CDirEntry *tmpde=FilesFind("/Demo/*.DD*",FUF_RECURSE);
+  I64 size;
+  U8 *ptr;
+  CArcCompress *arc;
+
+  LineRep1(tmpde); //We have CDirEntry.fullname
+  LineRep2(DocPut,tmpde);
+  "$GREEN$***************$FG$\n";
+  ptr=DirTreeSerialize(tmpde,&size);
+  DirTreeDel(tmpde);
+  D(ptr,size);
+  "$GREEN$***************:%7d$FG$\n",size;
+  arc=CompressBuf(ptr,size);
+  Free(ptr);
+  D(arc,arc->compressed_size);
+  "$GREEN$***************:%7d$FG$\n",size;
+  ptr=ExpandBuf(arc);
+  size=arc->expanded_size;
+  Free(arc);
+  D(ptr,size);
+  "$GREEN$***************:%7d$FG$\n",size;
+  tmpde=DirTreeUnserialize(ptr);
+  LineRep2(DocPut,tmpde); //We don't have CDirEntry.fullname
+  DirTreeDel(tmpde);
+}
+
+SerializeTree;
+
+ diff --git a/public/Wb/Demo/Dsk/UnusedSpaceRep.HC.HTML b/public/Wb/Demo/Dsk/UnusedSpaceRep.HC.HTML new file mode 100755 index 0000000..4fabd75 --- /dev/null +++ b/public/Wb/Demo/Dsk/UnusedSpaceRep.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+U0 UnusedSpaceRep()
+{
+  I64 i;
+  CDrv *dv;
+  for (i=0;i<26;i++)
+    if ((dv=Let2Drv(i+'A',FALSE)) &&
+          (dv->fs_type==FSt_FAT32 || dv->fs_type==FSt_REDSEA))
+      "%C: %7.3f%% Free\n",
+            Drv2Let(dv),DrvUnused(Drv2Let(dv))*100.0/(dv->size*BLK_SIZE);
+}
+
+UnusedSpaceRep;
+
+ diff --git a/public/Wb/Demo/Exceptions.HC.HTML b/public/Wb/Demo/Exceptions.HC.HTML new file mode 100755 index 0000000..77fd668 --- /dev/null +++ b/public/Wb/Demo/Exceptions.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//WARNING: Don't return out of a catch{}.  This
+//might get fixed.
+
+//You can use PutExcept() in a catch stmt
+//and it will report args.
+Bool Prompt(I64 i)
+{
+  "%d ",i;
+  return YorN;
+}
+
+U0 D1()
+{
+  "D1\n";
+  if (Prompt(1)) throw('Point1');
+  if (Prompt(2)) throw('Point2');
+}
+
+U0 D2()
+{
+  "D2\n";
+  try {
+    D1;
+    if (Prompt(4)) throw('Point4');
+  } catch {
+    "D2 hndlr\n"
+          "Ch:%c:%P\n",Fs->except_ch,Fs->except_callers[0];
+    if (Fs->except_ch=='Point1') {
+      "Caught in D2\n";
+      Fs->catch_except=TRUE;
+    }
+  }
+}
+
+U0 Demo()
+{
+  try {
+    D2;
+    if (Prompt(3)) throw('Point3');
+  } catch {
+    "Demo hndlr\n"
+          "Ch:%c:%P\n",Fs->except_ch,Fs->except_callers[0];
+    Fs->catch_except=TRUE;
+  }
+}
+
+Demo;
+
+ diff --git a/public/Wb/Demo/ExtChars.HC.HTML b/public/Wb/Demo/ExtChars.HC.HTML new file mode 100755 index 0000000..b96c749 --- /dev/null +++ b/public/Wb/Demo/ExtChars.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+U8 face[8]={
+
+0b00111100,
+0b01000010,
+0b10100101,
+0b10000001,
+0b11000011,
+0b10111101,
+0b01000010,
+0b00111100,
+
+};
+
+
+text.font[255]=face[0](U64);
+
+"Face:.\n";
+
+//Chars 128-255 are treated as letters
+//by the compiler and everything else.
+//Enter them by holding ALT and
+//pressing a 3 digit decimal number or
+//press <CTRL-ALT-a>.
+
+U0 SrcExample()
+{
+  I64 f..=12345;
+  "f..=%d\n",f..;
+}
+
+SrcExample;
+//See ::/Demo/ScrnCodes.HC, ::/Demo/Graphics/CharAnimation.HC,
+//::/Demo/Games/CharDemo.HC and ::/Demo/Graphics/FontEd.HC.
+
+//See char_bmp_alpha and char_bmp_alpha_numeric.
+
+ diff --git a/public/Wb/Demo/Games/BattleLines.HC.HTML b/public/Wb/Demo/Games/BattleLines.HC.HTML new file mode 100755 index 0000000..0a5c1c5 --- /dev/null +++ b/public/Wb/Demo/Games/BattleLines.HC.HTML @@ -0,0 +1,413 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+#define FRAMES 6
+
+U8 *imgs[FRAMES]={
+<1>,<2>,<3>,<4>,<3>,<2>};
+
+F64 fire_end_time;
+
+class Trooper
+{
+  I64 x,y,dx,dy,att,def,rng,player;
+  F64 animate_time_base,fire_end_time;
+  Trooper *target;
+};
+
+#define TROOPERS_NUM 100
+Trooper tr[2][TROOPERS_NUM];
+
+Bool time_lapse=FALSE;
+
+#define TAP_MODE_RADIUS 50
+Bool tap_mode;
+
+#define AI_NOTHING 0
+#define AI_TARGET  1
+#define AI_RANDOM  2
+#define AI_AI_NUM  3
+I64 ai_mode;
+
+I64 ai_targets[10];
+
+U0 DrawTrooper(CTask *,CDC *dc,Trooper *tmpt)
+{
+  U8 *tmps;
+  I64 x,y,gx,gy;
+  F64 speed,tt;
+
+  if (tmpt->def>0) {
+    x=tmpt->dx>>28;
+    y=tmpt->dy>>28;
+    speed=0.5*Sqrt(x*x+y*y);
+
+    tt=tmpt->animate_time_base+tS*speed;
+    if (time_lapse) {
+      x=(tmpt->x+500*tmpt->dx)>>32;
+      y=(tmpt->y+500*tmpt->dy)>>32;
+    } else {
+      x=tmpt->x.i32[1];
+      y=tmpt->y.i32[1];
+    }
+    if (tmpt->target) {
+      gx=x;gy=y;
+      if (tmpt->dx<0) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,x,y,x,y+1);
+        gx-=13;
+        gy-=7;
+      } else {
+        dc->flags&=~DCF_SYMMETRY|DCF_JUST_MIRROR;
+        gx+=13;
+        gy-=7;
+      }
+
+      dc->color=BLACK;
+      Sprite3(dc,x+1,y,0,<5>);
+
+      if (!tmpt->player)
+        dc->color=LTCYAN;
+      else
+        dc->color=LTPURPLE;
+      Sprite3(dc,x,y,0,<5>);
+
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+      if (!tmpt->player)
+        dc->color=WHITE;
+      else
+        dc->color=LTBLUE;
+      GrLine3(dc,gx,gy,0,tmpt->target->x.i32[1],tmpt->target->y.i32[1],0);
+    } else {
+      if (tmpt->dx<0) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,x,y,x,y+1);
+      } else
+        dc->flags&=~DCF_SYMMETRY|DCF_JUST_MIRROR;
+      tmps=SpriteInterpolate(tt%1.0,imgs[tt%FRAMES],imgs[(tt+1.0)%FRAMES]);
+
+      dc->color=BLACK;
+      Sprite3(dc,x+1,y,0,tmps);
+
+      if (!tmpt->player)
+        dc->color=LTCYAN;
+      else
+        dc->color=LTPURPLE;
+      Sprite3(dc,x,y,0,tmps);
+
+      Free(tmps);
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    }
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  Trooper *tmpt=tr;
+  I64 i,j,cnt[2],
+        x=ms.pos.x-task->pix_left-task->scroll_x,
+        y=ms.pos.y-task->pix_top-task->scroll_y;
+  Bool repulsive=ms.pos.z>0 ^^ ms.rb,
+        active=!winmgr.grab_scroll && (ms.lb||ms.rb);
+
+  for (j=0;j<2;j++) {
+    cnt[j]=0;
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      if (tmpt->def>0) {
+        DrawTrooper(task,dc,tmpt);
+        cnt[j]++;
+      }
+    }
+  }
+  if (tap_mode) {
+    dc->color=YELLOW;
+    GrCircle(dc,x,y,TAP_MODE_RADIUS);
+  } else {
+    if (repulsive) {
+      if (active)
+        dc->color=LTRED;
+      else
+        dc->color=RED;
+    } else {
+      if (active)
+        dc->color=LTBLUE;
+      else
+        dc->color=BLUE;
+    }
+    GrCircle(dc,x,y,AbsI64(ms.pos.z));
+  }
+  dc->color=LTCYAN;
+  GrPrint(dc,(task->win_right-8)*FONT_WIDTH,0,"%03d",cnt[0]);
+  dc->color=LTPURPLE;
+  GrPrint(dc,(task->win_right-4)*FONT_WIDTH,0,"%03d",cnt[1]);
+}
+
+U0 DoAiTarget()
+{
+  I64 i,j;
+  Trooper *tmpt1,*tmpt0;
+  for (i=0;i<10;i++) {
+    tmpt0=&tr[0][ai_targets[i]];
+    for (j=0;j<10;j++) {
+      tmpt1=&tr[1][i*10+j];
+      tmpt1->dx=(tmpt0->x-tmpt1->x)>>11;
+      tmpt1->dy=(tmpt0->y-tmpt1->y)>>11;
+    }
+  }
+}
+
+U0 UpdatePos()
+{
+  I64 i,j;
+  Trooper *tmpt=tr;
+  for (j=0;j<2;j++)
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      tmpt->x+=tmpt->dx;
+      if (tmpt->x>=GR_WIDTH<<32) tmpt->x-=GR_WIDTH<<32;
+      if (tmpt->x<0) tmpt->x+=GR_WIDTH<<32;
+      tmpt->y+=tmpt->dy;
+      if (tmpt->y>=GR_HEIGHT<<32) tmpt->y-=GR_HEIGHT<<32;
+      if (tmpt->y<0) tmpt->y+=GR_HEIGHT<<32;
+    }
+}
+
+U0 ResolveFiring()
+{
+  I64 i,j,dd,dx,dy;
+  Trooper *tmpt=tr,*tmpt0,*tmpt1;
+
+  for (j=0;j<2;j++)
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      if (tmpt->target && tmpt->fire_end_time<tS) {
+        tmpt->target->def-=tmpt->att;
+        tmpt->fire_end_time=0;
+        tmpt->target=NULL;
+      }
+    }
+
+  for (i=0;i<TROOPERS_NUM;i++) {
+    tmpt0=&tr[0][i];
+    for (j=0;j<TROOPERS_NUM;j++) {
+      tmpt1=&tr[1][j];
+      if (tmpt0->def>0 && tmpt1->def>0) {
+        dx=(tmpt0->x-tmpt1->x)>>32;
+        dy=(tmpt0->y-tmpt1->y)>>32;
+        dd=dx*dx+dy*dy;
+        if (dd<tmpt0->rng && !tmpt0->target) {
+          fire_end_time=tmpt0->fire_end_time=tS+0.125;
+          Snd(86);
+          tmpt0->target=tmpt1;
+        }
+        if (dd<tmpt1->rng && !tmpt1->target) {
+          fire_end_time=tmpt1->fire_end_time=tS+0.125;
+          Snd(86);
+          tmpt1->target=tmpt0;
+        }
+      }
+    }
+  }
+
+  if (tS>=fire_end_time)
+    Snd;
+}
+
+U0 UpdateHumanVelocities()
+{
+  F64 intensity;
+  I64 i,j,dx,dy,d,
+        x=ms.pos.x-Fs->pix_left-Fs->scroll_x,
+        y=ms.pos.y-Fs->pix_top-Fs->scroll_y;
+  Bool active=!winmgr.grab_scroll&&(ms.lb||ms.rb);
+  Trooper *tmpt=&tr[0][0];
+  if (tap_mode) {
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      dx=x- tmpt->x.i32[1];
+      dy=y- tmpt->y.i32[1];
+      if ((d=dx*dx+dy*dy) && d<TAP_MODE_RADIUS*TAP_MODE_RADIUS) {
+        intensity=SqrI64(SqrI64(SqrI64(TAP_MODE_RADIUS)-d));
+        dx=intensity*dx/d;
+        dy=intensity*dy/d;
+        tmpt->dx=tmpt->dx-dx;
+        tmpt->dy=tmpt->dy-dy;
+      } else {
+        tmpt->dx-=0.2*tmpt->dx;
+        tmpt->dy-=0.2*tmpt->dy;
+      }
+    }
+  } else if (active) {
+    j=400000000*ms.pos.z;
+    if (ms.rb)
+      j=-j;
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      dx=x- tmpt->x.i32[1];
+      dy=y- tmpt->y.i32[1];
+      if (d=dx*dx+dy*dy) {
+        dx=j*dx/d;
+        dy=j*dy/d;
+        tmpt->dx=tmpt->dx-dx;
+        tmpt->dy=tmpt->dy-dy;
+      }
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,j,dx,dy;
+  Trooper *tmpt;
+  MsSet(,,25);
+  tap_mode=FALSE;
+  time_lapse=FALSE;
+  fire_end_time=0;
+  MemSet(tr,0,sizeof(tr));
+  for (i=0;i<10;i++) {
+    ai_targets[i]=RandU16%TROOPERS_NUM;
+    dx=RandI32;
+    dy=RandI32;
+    for (j=0;j<10;j++) {
+      tmpt=&tr[0][i*10+j];
+      tmpt->x=(GR_WIDTH-100-i*10)<<32;
+      tmpt->y=(GR_HEIGHT>>1-50+j*10)<<32;
+      tmpt->att=3;
+      tmpt->def=10;
+      tmpt->rng=50*50;
+      tmpt->animate_time_base=10*Rand;
+      tmpt->player=0;
+
+      tmpt=&tr[1][i*10+j];
+      tmpt->x=(100+i*10)<<32;
+      tmpt->y=(GR_HEIGHT>>1-50+j*10)<<32;
+      if (ai_mode==AI_RANDOM) {
+        tmpt->dx=dx;
+        tmpt->dy=dy;
+      }
+      tmpt->att=3;
+      tmpt->def=10;
+      tmpt->rng=50*50;
+      tmpt->animate_time_base=10*Rand;
+      tmpt->player=1;
+    }
+  }
+  ai_mode=RandU16%AI_AI_NUM;
+}
+
+U0 BattleLines()
+{
+  CMenuEntry *tmpse;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  TimeLapse(,'1');"
+        "  TapMode(,'2');"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=GREEN<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->draw_it=&DrawIt;
+  PopUpOk("The mouse wheel controls\n"
+        "the command force.\n"
+        "Attract or repel with\n"
+        "left or right bttn.\n\n");
+
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU;
+  try {
+    while (TRUE) {
+      switch (ScanChar) {
+        case '1':
+          time_lapse=!time_lapse;
+          tmpse=MenuEntryFind(Fs->cur_menu,"Play/TimeLapse");
+          tmpse->checked=time_lapse;
+          break;
+        case '2':
+          tap_mode=!tap_mode;
+          tmpse=MenuEntryFind(Fs->cur_menu,"Play/TapMode");
+          tmpse->checked=tap_mode;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto wg_done;
+        case '\n':
+          Init;
+          break;
+      }
+      Sleep(40);
+      if (ai_mode==AI_TARGET)
+        DoAiTarget;
+      UpdateHumanVelocities;
+      UpdatePos;
+      ResolveFiring;
+    }
+wg_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+}
+
+BattleLines;
+
+ diff --git a/public/Wb/Demo/Games/BigGuns.HC.HTML b/public/Wb/Demo/Games/BigGuns.HC.HTML new file mode 100755 index 0000000..9ffb18b --- /dev/null +++ b/public/Wb/Demo/Games/BigGuns.HC.HTML @@ -0,0 +1,346 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+class MyMass:CMass
+{
+  Bool collision;
+};
+
+#define MAP_WIDTH       2048
+#define MAP_HEIGHT      (GR_HEIGHT-3*FONT_HEIGHT)
+
+I64 gun_x,gun_y,active_map=0,gun_recoil;
+F64 gun_theta;
+CDC *map_dcs[2]={NULL,NULL};
+I16 elevs[MAP_WIDTH];
+
+F64 wind_x;
+#define DUST_NUM        512
+I64 dust_x[DUST_NUM],dust_y[DUST_NUM];
+
+CMathODE *ode=NULL;
+
+    <1>/* Graphics Not Rendered in HTML */
+
+
+    <2>/* Graphics Not Rendered in HTML */
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CDC *map=map_dcs[active_map&1];
+  MyMass *tmpm;
+  F64 theta=gun_theta;
+  I64 i,x,y,w,
+        h=-task->horz_scroll.pos,
+        v=-task->vert_scroll.pos;
+  task->horz_scroll.min=0;
+  task->horz_scroll.max=MAP_WIDTH-task->pix_width;
+  task->vert_scroll.min=0;
+  task->vert_scroll.max=MAP_HEIGHT-task->pix_height;
+  map->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,h,v,map);
+
+  Sprite3(dc,gun_x+h,gun_y+v,0,<2>);
+
+  if (theta<-pi/2) {
+    dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+    DCSymmetrySet(dc,gun_x+h,0,gun_x+h,1);
+    theta=-pi-theta;
+  }
+  Sprite3ZB(dc,
+        gun_x+h-gun_recoil*Cos(theta),
+        gun_y+v-gun_recoil*Sin(theta)-10,0,<1>,theta);
+  dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+
+  tmpm=ode->next_mass;
+  dc->color=BLACK;
+  map->color=ROP_COLLISION;
+  map->bkcolor=LTCYAN;
+  while (tmpm!=&ode->next_mass) {
+    map->collision_cnt=0;
+    GrCircle(map,tmpm->x,tmpm->y,2);
+    if (map->collision_cnt)
+      tmpm->collision=TRUE;
+
+    GrCircle(dc,tmpm->x+h,tmpm->y+v,2);
+
+    tmpm=tmpm->next;
+  }
+
+  dc->color=LTGRAY;
+  w=tS*wind_x;
+  for (i=0;i<DUST_NUM;i++) {
+    x=(dust_x[i]+w)%MAP_WIDTH;
+    y=dust_y[i];
+    if (y<elevs[x])
+      GrPlot(dc,x+h,y+v);
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+  MyMass *tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->DstateDt->DyDt+=1000.0*tmpm->mass;
+    tmpm->DstateDt->DxDt+=25.0*wind_x;
+    tmpm=tmpm->next;
+  }
+}
+
+U0 DrawMap()
+{
+  CDC *map=map_dcs[(active_map+1)&1];
+  I64 x;
+
+  map->color=LTCYAN;
+  GrRect(map,0,0,MAP_WIDTH,MAP_HEIGHT);
+
+  map->color=BLACK;
+  for (x=1;x<MAP_WIDTH;x++)
+    GrLine(map,x-1,elevs[x-1],x,elevs[x]);
+
+  map->color=BROWN;
+  GrFloodFill(map,0,MAP_HEIGHT-1,FALSE);
+
+  active_map++;
+}
+
+U0 FireTask(I64)
+{
+  MyMass *tmpm;
+  I64 i;
+  if (gun_recoil) return;
+
+  tmpm=CAlloc(sizeof(MyMass),Fs->parent_task);
+  tmpm->mass=10.0;
+  tmpm->drag_profile_factor=0.1;
+  tmpm->x=gun_x+27*Cos(gun_theta);
+  tmpm->y=gun_y-15+27*Sin(gun_theta);
+  tmpm->DxDt=600.0*Cos(gun_theta);
+  tmpm->DyDt=600.0*Sin(gun_theta);
+  tmpm->collision=FALSE;
+  while (sys_task_being_scrn_updated==Fs->parent_task)
+    Yield;
+  QueIns(tmpm,ode->last_mass);
+
+  Fs->task_end_cb=&SndTaskEndCB;
+  for (i=0;i<60;i++) {
+    Snd(50*Rand+10);
+    Sleep(2);
+    gun_recoil=i/12;
+  }
+  for (i=0;i<=60;i++) {
+    Sleep(1);
+    gun_recoil=5-i/12;
+  }
+}
+
+U0 ManageShots()
+{
+  I64 i;
+  MyMass *tmpm,*tmpm1;
+  Bool chged=FALSE;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=tmpm->next;
+    if (!(0<=tmpm->x<MAP_WIDTH) ||
+          tmpm->collision) {
+      QueRem(tmpm);
+      for (i=tmpm->x-4;i<=tmpm->x+4;i++)
+        if (0<=i<MAP_WIDTH)
+          elevs[i]=ClampI64(elevs[i]+10-2*AbsI64(i-tmpm->x),0,MAP_HEIGHT-2);
+      Free(tmpm);
+      chged=TRUE;
+    }
+    tmpm=tmpm1;
+  }
+  if (chged)
+    DrawMap;
+}
+
+U0 MoveTask(I64)
+{
+  static F64 quit_time=0;
+  if (quit_time)
+    quit_time=tS+0.1;
+  else {
+    Snd(34);
+    Fs->task_end_cb=&SndTaskEndCB;
+    quit_time=tS+0.1;
+    while (quit_time>tS)
+      Yield;
+    quit_time=0;
+  }
+}
+
+U0 Init()
+{
+  CDC *map;
+  I64 i,x,y,dy;
+  if (!map_dcs[0])
+    map_dcs[0]=DCNew(MAP_WIDTH,MAP_HEIGHT);
+  if (!map_dcs[1])
+    map_dcs[1]=DCNew(MAP_WIDTH,MAP_HEIGHT);
+  map=map_dcs[active_map&1];
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+
+  y=ToI64(0.7*MAP_HEIGHT)<<32;
+  dy=0;
+  for (x=0;x<MAP_WIDTH;x++) {
+    dy=ClampI64(SignI64(RandI16)<<30+dy,-3<<32,3<<32);
+    y=ClampI64(y+dy,ToI64(0.3*MAP_HEIGHT)<<32,(MAP_HEIGHT-2)<<32);
+    elevs[x]=y.i32[1];
+  }
+  gun_x=RandU32%(MAP_WIDTH-100)+50;
+  gun_y=elevs[gun_x];
+  gun_theta=0;
+  gun_recoil=0;
+  for (x=gun_x-20;x<=gun_x+20;x++)
+    elevs[x]=gun_y;
+
+  wind_x=RandI16/250.0;
+  for (i=0;i<DUST_NUM;i++) {
+    dust_x[i]=RandU16%MAP_WIDTH;
+    dust_y[i]=RandU16%MAP_HEIGHT;
+  }
+
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.0001;
+  ode->acceleration_limit=5e5;
+  QueIns(ode,Fs->last_ode);
+  Fs->horz_scroll.min=0;
+  Fs->horz_scroll.max=MAP_WIDTH-Fs->pix_width;
+  Fs->horz_scroll.pos=gun_x-Fs->pix_width/2;
+  Fs->vert_scroll.min=0;
+  Fs->vert_scroll.max=MAP_HEIGHT-Fs->pix_height;
+  Fs->vert_scroll.pos=0;
+  TaskDerivedValsUpdate;
+
+  DrawMap;
+}
+
+U0 CleanUp(CMathODE *ode)
+{
+  if (ode) {
+    QueRem(ode);
+    QueDel(&ode->next_mass,TRUE);
+    ODEDel(ode);
+  }
+}
+
+U0 BigGuns()
+{
+  I64 ch,sc;
+
+  PopUpOk(
+        "I refuse to rip-off the original\n"
+        "so this is intentionally crappy\n"
+        "and included for demonstration\n"
+        "purposes.\n\n"
+        "Write games, don't play them.\n");
+
+  PopUpOk("The map scrolls.\n");
+
+  SettingsPush; //See SettingsPush
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fire(,CH_SPACE);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder(ON);
+  WinMax;
+  DocCursor;
+  DocClear;
+  DocScroll;
+  Init;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      while (ScanKey(&ch,&sc))
+        switch (ch) {
+          case 0:
+            switch (sc.u8[0]) {
+              case SC_CURSOR_RIGHT:
+                gun_theta+=2.0*pi/180;
+                if (gun_theta>0)
+                  gun_theta=0;
+                else
+                  Spawn(&MoveTask,NULL,"Move",,Fs);
+                break;
+              case SC_CURSOR_LEFT:
+                gun_theta-=2.0*pi/180;
+                if (gun_theta<-pi)
+                  gun_theta=-pi;
+                else
+                  Spawn(&MoveTask,NULL,"Move",,Fs);
+                break;
+            }
+            break;
+          case '\n':
+            CleanUp(ode);
+            Init;
+            break;
+          case CH_SPACE:
+            Spawn(&FireTask,NULL,"Fire",,Fs);
+            break;
+          case CH_SHIFT_ESC:
+          case CH_ESC:
+            goto bg_done;
+        }
+      ManageShots;
+      Refresh;
+    }
+bg_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCDel(map_dcs[0]); map_dcs[0]=NULL;
+  DCDel(map_dcs[1]); map_dcs[1]=NULL;
+  CleanUp(ode);
+  MenuPop;
+}
+
+BigGuns;
+
+ diff --git a/public/Wb/Demo/Games/BlackDiamond.HC.HTML b/public/Wb/Demo/Games/BlackDiamond.HC.HTML new file mode 100755 index 0000000..c4d62bf --- /dev/null +++ b/public/Wb/Demo/Games/BlackDiamond.HC.HTML @@ -0,0 +1,430 @@ + + + + + + + + + + + +
+/*Sprites were created with <CTRL-r>
+and can be edited by moving the
+cursor on top and pressing <CTRL-r>.
+
+<CTRL-t> to see the num of the sprite
+and <CTRL-t> again to get back.  Nums
+are assigned by the editor.
+*/
+
+
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+//See ::/Doc/Credits.DD.
+
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                <9>/* Graphics Not Rendered in HTML */
+
+RegDft("TempleOS/BlackDiamond","I64 best_score=9999;\n");
+RegExe("TempleOS/BlackDiamond");
+
+#define MAP_HEIGHT      3000
+#define OBJS_NUM        128
+
+I64 x,y,scrn_top_y,penalty,chair_lift_num;
+I64 obj_x[OBJS_NUM],obj_y[OBJS_NUM],obj_types[OBJS_NUM],
+    obj_saved_x[OBJS_NUM],obj_saved_y[OBJS_NUM];
+Bool game_over;
+
+#define T_TREE          0
+#define T_LITTLE_ROCK   1
+#define T_BIG_ROCK      2
+#define T_WOLF          3
+#define T_CHAIR_LIFT    4
+U8 *imgs[5]={<3>,<4>,<5>,<6>,<9>};
+
+#define DC_WOLF_WIDTH   48
+#define DC_WOLF_HEIGHT  38
+U0 DrawRunningWolf(CDC *dc,I64 i)
+{//Draw wolf on small DC so bottom gets clipped looking like sunk into snow.
+//Then, copy onto main DC.
+  U8 *tmps;
+  CDC *dc_wolf=DCNew(DC_WOLF_WIDTH,DC_WOLF_HEIGHT);
+  DCFill(dc_wolf);
+  if (x<obj_x[i]) {
+    dc_wolf->flags|=DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR;
+    DCSymmetrySet(dc_wolf,DC_WOLF_WIDTH/2,0,DC_WOLF_WIDTH/2,1);
+  }
+  if (tS%1.0<0.5)
+    tmps=<6>;
+  else
+    tmps=<7>;
+  Sprite3ZB(dc_wolf,DC_WOLF_WIDTH/2,0.85*DC_WOLF_HEIGHT,
+        0,tmps,0.4*Sin(7*tS));
+  GrBlot(dc,obj_x[i]-DC_WOLF_WIDTH/2,
+        obj_y[i]-scrn_top_y-0.85*DC_WOLF_HEIGHT,dc_wolf);
+  DCDel(dc_wolf);
+  if (0<=(obj_y[i]-scrn_top_y)<GR_HEIGHT)
+    obj_x[i]+=3*SignI64(x-obj_x[i]);
+}
+
+U0 DrawMan(CDC *dc)
+{
+  if(dc->collision_cnt)
+    Sprite3(dc,x,y-scrn_top_y,0,<2>); //Red man
+  else
+    Sprite3(dc,x,y-scrn_top_y,0,<1>); //Normal man
+}
+
+#define WIRE_HEIGHT     595
+#define WIRE_WIDTH      121
+#define WIRE_DIP        800
+#define PULLY_WIDTH     13
+U0 DrawUpperChairLift(CDC *dc)
+{
+  I64 i=chair_lift_num,x,x1,y=obj_y[i]-scrn_top_y-WIRE_HEIGHT,y1;
+  Sprite3(dc,obj_x[i],y+13,0,<8>);
+  dc->thick=2;
+  for (x=-WIRE_WIDTH/2;x<GR_WIDTH+WIRE_WIDTH/2;x+=2) { //Pen width is 2, step 2.
+    x1=x-obj_x[i];
+    y1=y-WIRE_DIP/2+Cosh(Ln(WIRE_DIP)+(Abs(x1)-PULLY_WIDTH)/10000.0)+0.1*x1;
+    if (!(-PULLY_WIDTH<x1<PULLY_WIDTH)) {
+      GrPlot3(dc,x-WIRE_WIDTH/2,y1,0);
+      GrPlot3(dc,x+WIRE_WIDTH/2,y1,0);
+    }
+  }
+  dc->thick=1;
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  Bool man_drawn=FALSE;
+
+  for (i=0;i<OBJS_NUM;i++)
+    if (obj_y[i]-32<=y<=obj_y[i]) {
+      if (obj_types[i]==T_WOLF && AbsI64(x-obj_x[i])>3)
+        DrawRunningWolf(dc,i);
+      else
+        Sprite3(dc,obj_x[i],obj_y[i]-scrn_top_y,0,imgs[obj_types[i]]);
+    }
+
+  dc->collision_cnt=0;
+  dc->color=ROP_COLLISION;
+  dc->bkcolor=WHITE;
+  Sprite3(dc,x,y-scrn_top_y,0,<1>);
+  if (!game_over) {
+    if(dc->collision_cnt) {
+      Snd(58);
+      penalty++; //Time is irregular. Scoring is imperfect. 30fps more or less.
+    } else
+      Snd;
+  }
+
+  dc->color=ROP_EQU;
+  for (i=0;i<OBJS_NUM;i++) {
+    if (!man_drawn && obj_y[i]>=y) {
+      DrawMan(dc);
+      man_drawn=TRUE;
+    }
+    if (obj_types[i]==T_WOLF && AbsI64(x-obj_x[i])>3)
+      DrawRunningWolf(dc,i);
+    else
+      Sprite3(dc,obj_x[i],obj_y[i]-scrn_top_y,0,imgs[obj_types[i]]);
+  }
+  if (!man_drawn)
+    DrawMan(dc);
+  DrawUpperChairLift(dc);
+
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Penalty:%d Best:%d",penalty,best_score);
+  if (game_over && Blink) {
+    dc->color=RED;
+    GrPrint(dc,(Fs->pix_width-9*FONT_WIDTH)/2,
+          (Fs->pix_height-FONT_HEIGHT)/2,"Game Over");
+  }
+}
+
+I64 Compare(I64 e1,I64 e2)
+{
+  return e1-e2;
+}
+
+U0 Init()
+{
+  I64 i,j;
+  for (i=0;i<OBJS_NUM;i++) {
+    obj_saved_y[i]=RandU32%MAP_HEIGHT;
+    obj_saved_x[i]=RandU32%GR_WIDTH;
+    j=RandU16;
+    if (j&7)
+      obj_types[i]=T_TREE;
+    else if (j&31)
+      obj_types[i]=T_LITTLE_ROCK;
+    else if (j&63)
+      obj_types[i]=T_BIG_ROCK;
+    else
+      obj_types[i]=T_WOLF;
+  }
+  QSortI64(obj_saved_y,OBJS_NUM,&Compare); //Break associations. Doesn't matter.
+
+  chair_lift_num=RandU16%OBJS_NUM;
+  obj_types[chair_lift_num]=T_CHAIR_LIFT;
+}
+
+U0 BlackDiamond()
+{
+  I64 ch,sc;
+
+  MenuPush(
+        "File {"
+        "  New(,'\n');"
+        "  Restart(,CH_SPACE);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+
+  Init;
+  try {
+    while (TRUE) {
+bd_restart:
+      MemCpy(obj_x,obj_saved_x,sizeof(obj_x)); //Wolves move. We must reset the
+      MemCpy(obj_y,obj_saved_y,sizeof(obj_y)); //wolves if running same game.
+
+      game_over=FALSE;
+      scrn_top_y=0;
+      x=Fs->pix_width>>1; y=0;
+      penalty=0;
+      while (TRUE) {
+        if (ScanKey(&ch,&sc)) {
+          switch (ch) {
+            case 0:
+              if (!game_over)
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    x+=10;
+                    if (x>=Fs->pix_width) x-=Fs->pix_width;
+                    break;
+                  case SC_CURSOR_LEFT:
+                    x-=10;
+                    if (x<0) x+=Fs->pix_width;
+                    break;
+                  case SC_CURSOR_UP:
+                    y-=10;
+                    break;
+                  case SC_CURSOR_DOWN:
+                    y+=10;
+                    break;
+                }
+              break;
+
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto bd_done;
+
+            case '\n':
+              Init;
+              goto bd_restart;
+
+            case CH_SPACE:
+              game_over=TRUE;
+              while (scrn_top_y>0||y>0) {//Animate going back to top.
+                scrn_top_y=MaxI64(0,scrn_top_y-4);
+                y=MaxI64(0,y-4);
+                x+=SignI64(Fs->pix_width>>1-x);
+                Sleep(1);
+              }
+              Snd;
+              goto bd_restart;
+          }
+//Don't want keystrokes building-up in the buf.
+          FlushMsgs;
+        }
+        if (!game_over) {
+          y+=2;
+          scrn_top_y++;
+          if (y-scrn_top_y>Fs->pix_height) {//Animate scrolling scrn.
+            while (y-scrn_top_y>Fs->pix_height>>1) {
+              scrn_top_y+=2;
+              Sleep(1);
+            }
+          }
+          if (y>=MAP_HEIGHT) {
+            game_over=TRUE;
+            Beep;
+            if (penalty<=best_score) {
+              best_score=penalty;
+              Beep;
+            }
+          }
+        }
+        Sleep(10);
+      }
+    }
+bd_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/BlackDiamond","I64 best_score=%d;\n",best_score);
+}
+
+BlackDiamond; //Start game when #included.
+
+ diff --git a/public/Wb/Demo/Games/BomberGolf.HC.HTML b/public/Wb/Demo/Games/BomberGolf.HC.HTML new file mode 100755 index 0000000..a21e747 --- /dev/null +++ b/public/Wb/Demo/Games/BomberGolf.HC.HTML @@ -0,0 +1,389 @@ + + + + + + + + + + + +
+RegDft("TempleOS/BomberGolf","I64 best_score=99999;\n");
+RegExe("TempleOS/BomberGolf");
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <9>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <10>/* Graphics Not Rendered in HTML */
+
+
+#define MAP_WIDTH       600
+#define MAP_HEIGHT      600
+
+#define TREES_NUM       64
+class Tree
+{
+  I64 x,y;
+} trees[TREES_NUM];
+ 
+
+I64 target_cnt,key_cnt;
+
+
+#define TARGETS_NUM     10
+
+#define MDF_TANK                0
+#define MDF_BUNKER      1
+
+#define TANK_V          10.0
+
+class Target
+{
+  F64   x,y,theta;
+  U8    *alive_img,*dead_img1,*dead_img2;
+  U8    type;
+  Bool  dead,pad[6];
+} targets[TARGETS_NUM];
+
+#define FALL_TIME       3.00
+#define EXPLODE_TIME    0.25
+class Bomb
+{
+  Bomb *next,*last;
+  F64 x,y,t;
+  Bool exploding;
+} bomb_head;
+ 
+F64 v,x,y,
+    theta,thetaf; //thetaf is the final theta. theta is gradually changed until it reaches thetaf.
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j;
+  Bomb *tmpb;
+  Target *tmpt;
+  F64 ts=tS,dx,dy;
+
+  dc->color=ROPF_DITHER|BROWN<<16|YELLOW;
+  GrRect3(dc,0,0,0,dc->width,dc->height);
+
+  dc->x=task->pix_width>>1;
+  dc->y=task->pix_height>>1;
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4TranslationEqu(dc->r,x,y,0);
+  Mat4x4RotZ(dc->r,theta);
+  dc->color=BLACK;
+  GrBorder(dc,-MAP_WIDTH>>1,-MAP_HEIGHT>>1,MAP_WIDTH>>1,MAP_HEIGHT>>1);
+  for (i=0;i<TARGETS_NUM;i++) {
+    tmpt=&targets[i];
+    if (tmpt->dead) {
+      if (i&1) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetry3Set(dc,tmpt->x,tmpt->y,0,tmpt->x,tmpt->y,1,
+              tmpt->x+1024*Cos(tmpt->theta),tmpt->y+1024*Sin(tmpt->theta),0);
+      }
+      if (Blink(15))
+        Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->dead_img1,tmpt->theta);
+      else
+        Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->dead_img2,tmpt->theta);
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    } else
+      Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->alive_img,tmpt->theta);
+  }
+
+  for (i=0;i<TREES_NUM;i++)
+    Sprite3(dc,trees[i].x,trees[i].y,0,<2>);
+
+  for (i=0;i<TARGETS_NUM;i++) {
+    tmpt=&targets[i];
+    if (tmpt->dead) {
+      for (j=0;j<40;j++) {
+        dc->thick=4;
+        if (j&1)
+          dc->color=ROPF_DITHER|LTGRAY<<16|BLACK;
+        else
+          dc->color=ROPF_DITHER|DKGRAY<<16|LTGRAY;
+        dx=15*Sin(ts/4+j<<6)+j>>2;
+        dy=10*FullTri(ts/3+j/2.0,20)+j>>2;
+        GrPlot3(dc,tmpt->x+5+dx+0.5*dy,tmpt->y+0.5*dx+dy,0);
+      }
+    }
+  }
+
+  tmpb=bomb_head.next;
+  while (tmpb!=&bomb_head) {
+    if (tmpb->t+FALL_TIME<tS) {
+      if (Blink(10))
+        Sprite3(dc,tmpb->x,tmpb->y,0,<9>);
+      else
+        Sprite3(dc,tmpb->x,tmpb->y,0,<10>);
+    }
+    tmpb=tmpb->next;
+  }
+
+  dc->flags&=~DCF_TRANSFORMATION;
+  Sprite3(dc,task->pix_width>>1,task->pix_height>>1,0,<1>);
+  dc->color=RED;
+  GrPrint(dc,0,0,"Targets:%02d  KeyStrokes:%04d Best:%04d",
+        target_cnt,key_cnt,best_score);
+  if (!target_cnt && Blink(4))
+    GrPrint(dc,(task->pix_width-FONT_WIDTH*14)>>1,
+          (task->pix_height-FONT_HEIGHT)>>1-32,"Game Completed");
+}
+ 
+U0 BombHit(Bomb *tmpb)
+{
+  I64 i;
+  for (i=0;i<TARGETS_NUM;i++) {
+    if (!targets[i].dead &&
+          SqrI64(tmpb->x-targets[i].x)+SqrI64(tmpb->y-targets[i].y)<20*20) {
+      targets[i].dead=TRUE;
+      target_cnt--;
+    }
+  }
+  QueRem(tmpb);
+  Free(tmpb);
+}
+ 
+U0 BombDrop(F64 x,F64 y)
+{
+  Bomb *tmpb=MAlloc(sizeof(Bomb));
+  tmpb->x=x;
+  tmpb->y=y;
+  tmpb->t=tS;
+  tmpb->exploding=FALSE;
+  QueIns(tmpb,bomb_head.last);
+  Sweep(FALL_TIME*1000,74,62);
+}
+ 
+I64 AnimateTask(CTask *)
+{
+  F64 last_t=tS,dt;
+  I64 i;
+  Bomb *tmpb,*tmpb1;
+  Target *tmpt;
+  while (TRUE) {
+    dt=tS-last_t;
+    last_t=tS;
+
+    if (bomb_head.next==&bomb_head) {
+      if (target_cnt)
+        Snd(Freq2Ona(100+60*Clamp(0.1*(1.0+Abs(Wrap(thetaf-theta,-pi)))`4.0,-3,3)));
+      else if (key_cnt<best_score) {
+        best_score=key_cnt;
+        Sleep(150); Snd(74);Sleep(150);Snd;
+        Sleep(150); Snd(74);Sleep(150);Snd;
+      } else
+        Snd;
+    }
+
+    theta+=dt*(thetaf-theta);
+    x+=dt*v*Sin(theta);
+    y+=dt*v*Cos(theta);
+
+    for (i=0;i<TARGETS_NUM;i++) {
+      tmpt=&targets[i];
+      if (!tmpt->dead && tmpt->type==MDF_TANK) {
+        tmpt->x+=dt*TANK_V*Cos(tmpt->theta);
+        tmpt->y+=dt*TANK_V*Sin(tmpt->theta);
+        if (i&1)
+          tmpt->theta+=dt*pi/16;
+        else
+          tmpt->theta-=dt*pi/16;
+      }
+    }
+
+    tmpb=bomb_head.next;
+    while (tmpb!=&bomb_head) {
+      tmpb1=tmpb->next;
+      if (tmpb->t+FALL_TIME+EXPLODE_TIME<tS)
+        BombHit(tmpb);
+      else if (tmpb->t+FALL_TIME<tS && !tmpb->exploding) {
+        Noise(EXPLODE_TIME*1000,62,74);
+        tmpb->exploding=TRUE;
+      }
+      tmpb=tmpb1;
+    }
+
+    Sleep(10);
+  }
+  return 0;
+}
+ 
+U0 Init()
+{
+  I64 i;
+  Target *tmpt;
+
+  v=20;
+  x=-MAP_WIDTH>>1;
+  y=-MAP_HEIGHT>>1;
+  thetaf=theta=1*pi/4;
+
+  QueInit(&bomb_head);
+
+  MemSet(trees,0,sizeof(trees));
+  for (i=0;i<TREES_NUM;i++) {
+    trees[i].x=RandU32%MAP_WIDTH -MAP_WIDTH >>1;
+    trees[i].y=RandU32%MAP_HEIGHT-MAP_HEIGHT>>1;
+  }
+
+  MemSet(targets,0,sizeof(targets));
+  for (i=0;i<TARGETS_NUM;i++) {
+    tmpt=&targets[i];
+    tmpt->x=RandU32%MAP_WIDTH -MAP_WIDTH >>1;
+    tmpt->y=RandU32%MAP_HEIGHT-MAP_HEIGHT>>1;
+    if (i<TARGETS_NUM/3) {
+      tmpt->type=MDF_BUNKER;
+      tmpt->theta=(RandU16&3)*pi/2;
+      tmpt->alive_img=<6>;
+      tmpt->dead_img1=<7>;
+      tmpt->dead_img2=<8>;
+    } else {
+      tmpt->type=MDF_TANK;
+      tmpt->theta=Rand*2*pi;
+      tmpt->alive_img=<3>;
+      tmpt->dead_img1=<4>;
+      tmpt->dead_img2=<5>;
+    }
+  }
+  key_cnt=0;
+  target_cnt=TARGETS_NUM;
+}
+
+U0 CleanUp()
+{
+  QueDel(&bomb_head,TRUE);
+}
+
+U0 BomberGolf()
+{
+  I64 sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Faster(,,SC_CURSOR_UP);"
+        "  Slower(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Bomb(,CH_SPACE);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  Init;
+  try {
+    while (TRUE)
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_UP:
+              v+=10;
+              if (v>300) v=300;
+              break;
+            case SC_CURSOR_DOWN:
+              v-=10;
+              if (v<20) v=20;
+              break;
+            case SC_CURSOR_LEFT:
+              key_cnt++;
+              thetaf+=1.0/(Abs(Wrap(thetaf-theta,-pi))+2*pi);
+              break;
+            case SC_CURSOR_RIGHT:
+              key_cnt++;
+              thetaf-=1.0/(Abs(Wrap(thetaf-theta,-pi))+2*pi);
+              break;
+
+          }
+          break;
+        case CH_SPACE:
+          key_cnt++;
+          BombDrop(-x-0.8*FALL_TIME*v*Sin(theta),-y-0.8*FALL_TIME*v*Cos(theta));
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto bm_done;
+      }
+bm_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/BomberGolf","I64 best_score=%d;\n",best_score);
+}
+ 
+BomberGolf;
+
+ diff --git a/public/Wb/Demo/Games/CastleFrankenstein.HC.HTML b/public/Wb/Demo/Games/CastleFrankenstein.HC.HTML new file mode 100755 index 0000000..9dc6497 --- /dev/null +++ b/public/Wb/Demo/Games/CastleFrankenstein.HC.HTML @@ -0,0 +1,627 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+RegDft("TempleOS/CastleFrankenstein","F64 best_score=9999;\n");
+RegExe("TempleOS/CastleFrankenstein");
+
+//Set snap to 4 and width to 4
+//if you edit this map.
+
+//Don't forget to change the
+//starting pos.
+#define MAN_START_X     0
+#define MAN_START_Y     4.5
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#define MONSTER_SCALE   2.0
+
+                     <2>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+
+
+
+                     <3>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+
+
+                     <4>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+#define PLANT_SCALE     2.0
+
+
+
+                     <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+                       <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+#define SCRN_SCALE              512
+#define PLOT_GRID_WIDTH         24
+#define PLOT_GRID_HEIGHT        24
+#define MAN_HEIGHT              125
+
+#define MAP_SCALE       4
+I64 map_width,map_height;
+U8 *map=NULL,
+*panels_processed_bitmap=NULL;
+
+I64 man_xx,man_yy;
+F64 man_theta;
+
+F64 t0,tf;
+
+#define MONSTERS_NUM    10
+I64 monsters_left;
+class Monster
+{
+  I64 x,y;
+  Bool dead,pad[7];
+} monsters[MONSTERS_NUM];
+
+U0 CFTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  zz=SCRN_SCALE/3+*z;
+  if (zz<1) zz=1;
+  *x=SCRN_SCALE/2* *x/zz;
+  *y=SCRN_SCALE/2* (*y+MAN_HEIGHT)/zz;
+  *x+=dc->x;
+  *y+=dc->y;
+  *z+=dc->z;
+}
+
+#define LOS_SCALE       4
+
+Bool LOSPlot(U8 *,I64 x,I64 y,I64)
+{
+  if (!map[(y/LOS_SCALE)*map_width+(x/LOS_SCALE)])
+    return FALSE;
+  else
+    return TRUE;
+}
+
+Bool LOS(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Line of sight
+  return Line(NULL,x1*LOS_SCALE/SCRN_SCALE,y1*LOS_SCALE/SCRN_SCALE,0,
+        x2*LOS_SCALE/SCRN_SCALE,y2*LOS_SCALE/SCRN_SCALE,0,&LOSPlot);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,*r1,*r2,*r3,*s2w,xx,yy,zz,x,y,x1,y1,z1,
+        c,x1w,y1w,x1h,y1h,xh,yh,zh,
+        cx=task->pix_width/2,
+        cy=task->pix_height/2;
+  U8 *tmps;
+  F64 tt;
+  CD3I32 poly[4];
+  Monster *tmpm;
+
+  DCDepthBufAlloc(dc);
+  MemSet(panels_processed_bitmap,0,(map_width*map_height+7)>>3);
+
+  //World to scrn
+  Mat4x4RotZ(dc->r,man_theta+pi/2);
+  Mat4x4RotX(dc->r,pi/2);
+  DCMat4x4Set(dc,dc->r);
+
+  xh=-man_xx/SCRN_SCALE; yh=-man_yy/SCRN_SCALE; zh=0;
+  Mat4x4MulXYZ(dc->r,&xh,&yh,&zh);
+  Mat4x4TranslationEqu(dc->r,xh,yh,zh);
+
+  //Scrn to world
+  s2w=Mat4x4IdentNew(task);
+  Mat4x4RotX(s2w,-pi/2);
+  Mat4x4RotZ(s2w,-man_theta-pi/2);
+  xh=0; yh=0; zh=SCRN_SCALE;
+  Mat4x4MulXYZ(s2w,&xh,&yh,&zh);
+
+  //Rotate light source
+  xx=dc->ls.x; yy=dc->ls.y; zz=-dc->ls.z;
+  (*dc->transform)(dc,&xx,&yy,&zz);
+  dc->ls.x=xx; dc->ls.y=yy; dc->ls.z=zz;
+
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->transform=&CFTransform;
+  dc->x=cx;
+  dc->y=cy;
+  r1=Mat4x4IdentNew(task);
+  Mat4x4RotX(r1,-pi/2);
+  Mat4x4RotZ(r1,tS);
+  Mat4x4Scale(r1,MONSTER_SCALE);
+
+  r2=Mat4x4IdentNew(task);
+  Mat4x4Scale(r2,MONSTER_SCALE);
+
+  r3=Mat4x4IdentNew(task);
+  Mat4x4RotX(r3,-pi/2);
+  Mat4x4Scale(r3,PLANT_SCALE);
+
+  Seed(1);
+  x1h=man_xx+yh*PLOT_GRID_WIDTH/2+xh*(PLOT_GRID_HEIGHT-1);
+  y1h=man_yy-xh*PLOT_GRID_WIDTH/2+yh*(PLOT_GRID_HEIGHT-1);
+  xh>>=1; yh>>=1;
+  for (j=0;j<PLOT_GRID_HEIGHT*2;j++) {
+    x1w=x1h;
+    y1w=y1h;
+    for (i=0;i<PLOT_GRID_WIDTH*4;i++) {
+      xx=x1w/SCRN_SCALE; yy=y1w/SCRN_SCALE;
+      x=xx*SCRN_SCALE-man_xx; y=yy*SCRN_SCALE-man_yy;
+      if (1<=xx<map_width-1 && 1<=yy<map_height-1 &&
+            !LBts(panels_processed_bitmap,yy*map_width+xx)) {
+        if ((c=map[yy*map_width+xx]) &&
+              LOS(xx*SCRN_SCALE+SCRN_SCALE/2,yy*SCRN_SCALE+SCRN_SCALE/2,
+              man_xx,man_yy)) {
+          if (c==YELLOW)
+            dc->color=DKGRAY;
+          else
+            dc->color=c;
+          poly[0].x=x;
+          poly[0].y=y;
+          poly[0].z=0;
+          poly[1].x=x+SCRN_SCALE;
+          poly[1].y=y;
+          poly[1].z=0;
+          poly[2].x=x+SCRN_SCALE;
+          poly[2].y=y+SCRN_SCALE;
+          poly[2].z=0;
+          poly[3].x=x;
+          poly[3].y=y+SCRN_SCALE;
+          poly[3].z=0;
+          GrFillPoly3(dc,4,poly);
+          if (c==GREEN) {
+            x1=x+SCRN_SCALE/2;
+            y1=y+SCRN_SCALE/2;
+            z1=0;
+            DCTransform(dc,&x1,&y1,&z1);
+            if (z1>0)
+              Sprite3Mat4x4B(dc,x+SCRN_SCALE/2,y+SCRN_SCALE/2,0,<5>,r3);
+          } else if (c==YELLOW) {
+            x1=x+SCRN_SCALE/2;
+            y1=y+SCRN_SCALE/2;
+            z1=0;
+            DCTransform(dc,&x1,&y1,&z1);
+            if (z1>0)
+              Sprite3Mat4x4B(dc,x+SCRN_SCALE/2,y+SCRN_SCALE/2,0,<6>,r3);
+          }
+
+          if (!map[(yy+1)*map_width+xx]) {
+            dc->color=LTGRAY;
+            poly[0].x=x;
+            poly[0].y=y+SCRN_SCALE;
+            poly[0].z=0;
+            poly[1].x=x+SCRN_SCALE;
+            poly[1].y=y+SCRN_SCALE;
+            poly[1].z=0;
+            poly[2].x=x+SCRN_SCALE;
+            poly[2].y=y+SCRN_SCALE;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x;
+            poly[3].y=y+SCRN_SCALE;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+          if (!map[yy*map_width+xx+1]) {
+            dc->color=WHITE;
+            poly[0].x=x+SCRN_SCALE;
+            poly[0].y=y;
+            poly[0].z=0;
+            poly[1].x=x+SCRN_SCALE;
+            poly[1].y=y+SCRN_SCALE;
+            poly[1].z=0;
+            poly[2].x=x+SCRN_SCALE;
+            poly[2].y=y+SCRN_SCALE;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x+SCRN_SCALE;
+            poly[3].y=y;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+          if (!map[(yy-1)*map_width+xx]) {
+            dc->color=LTGRAY;
+            poly[0].x=x;
+            poly[0].y=y;
+            poly[0].z=0;
+            poly[1].x=x+SCRN_SCALE;
+            poly[1].y=y;
+            poly[1].z=0;
+            poly[2].x=x+SCRN_SCALE;
+            poly[2].y=y;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x;
+            poly[3].y=y;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+          if (!map[yy*map_width+xx-1]) {
+            dc->color=WHITE;
+            poly[0].x=x;
+            poly[0].y=y;
+            poly[0].z=0;
+            poly[1].x=x;
+            poly[1].y=y+SCRN_SCALE;
+            poly[1].z=0;
+            poly[2].x=x;
+            poly[2].y=y+SCRN_SCALE;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x;
+            poly[3].y=y;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+        }
+      }
+      x1w-=yh;
+      y1w+=xh;
+    }
+    x1h-=xh;
+    y1h-=yh;
+  }
+
+  //Draw Monsters
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    x=tmpm->x;
+    y=tmpm->y;
+    if (LOS(x,y,man_xx,man_yy)) {
+      x-=man_xx;
+      y-=man_yy;
+      xx=x;
+      yy=y;
+      zz=0;
+      DCTransform(dc,&xx,&yy,&zz);
+      if (zz>0) {
+        if (tmpm->dead)
+          Sprite3Mat4x4B(dc,x,y,0,<2>,r2);
+        else {
+          tt=Tri(tS,1.0);
+          tmps=SpriteInterpolate(tt,<3>,<4>);
+          Sprite3Mat4x4B(dc,x,y,0,tmps,r1);
+          Free(tmps);
+        }
+      }
+    }
+  }
+  Free(r1);
+  Free(r2);
+  Free(r3);
+
+  //Draw Map heads-up display, scaled 2 pixs
+  Free(dc->r);
+  DCMat4x4Set(dc,Mat4x4IdentNew(task));
+  dc->x=task->pix_width -2*map_width;
+  dc->y=task->pix_height-2*map_height;
+  dc->z=0;
+  dc->transform=&DCTransform;
+  dc->thick=2;
+  for (i=0;i<map_height;i++)
+    for (j=0;j<map_width;j++) {
+      dc->color=map[(map_height-1-i)*map_width+j];
+      GrPlot3(dc,2*j,2*i,0);
+    }
+
+    //Draw Things on heads-up Map
+  dc->color=LTPURPLE;
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+    if (!tmpm->dead)
+      GrPlot3(dc,2*(tmpm->x/SCRN_SCALE),
+            2*(map_height-1-tmpm->y/SCRN_SCALE),0);
+  dc->color=LTCYAN;
+  GrPlot3(dc,2*(man_xx/SCRN_SCALE),2*(map_height-1-man_yy/SCRN_SCALE),0);
+
+  if (tf) {
+    dc->color=LTRED;
+    if (Blink)
+      GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed");
+    tt=tf;
+  } else {
+    dc->color=LTGREEN;
+    GrLine(dc,cx-5,cy,cx+5,cy);
+    GrLine(dc,cx,cy-5,cx,cy+5);
+    tt=tS;
+  }
+  GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",
+        monsters_left,tt-t0,best_score);
+  Free(s2w);
+  Seed(0);
+}
+
+U0 Fire()
+{
+  I64 i,x,y;
+  F64 d,dx,dy,xx=Cos(man_theta),yy=Sin(man_theta);
+  Monster *tmpm;
+
+  Noise(100,53,74);
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    x=tmpm->x;
+    y=tmpm->y;
+    if (!tmpm->dead &&
+          LOS(x,y,man_xx,man_yy)) {
+      dx=x-man_xx;
+      dy=man_yy-y;
+      if (d=Sqrt(dx*dx+dy*dy)) {
+        dx/=d;
+        dy/=d;
+        if (dx*xx+dy*yy>0.995) {
+          tmpm->dead=TRUE;
+          if (!--monsters_left) {
+            tf=tS;
+            if (tf-t0<best_score)
+              best_score=tf-t0;
+          }
+        }
+      }
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,x,y;
+  CDC *dc;
+  Monster *tmpm;
+
+  DocClear;
+  "$BG,BLACK$%h*c",TEXT_ROWS/2,'\n';
+
+  dc=Sprite2DC(<1>);
+  map_width =dc->width/MAP_SCALE+2;
+  map_height=dc->height/MAP_SCALE+2;
+  Free(map);
+  Free(panels_processed_bitmap);
+  map=CAlloc(map_width*map_height*sizeof(U8));
+  panels_processed_bitmap=MAlloc((map_width*map_height+7)>>3);
+  for (y=0;y<map_height-2;y++)
+    for (x=0;x<map_width-2;x++)
+      map[(map_height-2-y)*map_width+x+1]=GrPeek(dc,x*MAP_SCALE,y*MAP_SCALE);
+  DCDel(dc);
+  man_xx=(1+MAN_START_X)*SCRN_SCALE;
+  man_yy=(map_height-1-MAN_START_Y)*SCRN_SCALE;
+  man_theta=0;
+
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    tmpm->dead=FALSE;
+    do {
+      tmpm->x=RandU64%((map_width-2)*SCRN_SCALE)+SCRN_SCALE;
+      tmpm->y=RandU64%((map_height-2)*SCRN_SCALE)+SCRN_SCALE;
+    } while (!map[(tmpm->y/SCRN_SCALE)*map_width+tmpm->x/SCRN_SCALE]);
+  }
+  monsters_left=MONSTERS_NUM;
+  tf=0;
+  t0=tS;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i,x,y,dd;
+  Monster *tmpm;
+
+  while (TRUE) {
+    dd=0.25*SCRN_SCALE*Sin(tS/2);
+    for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+      if (!tmpm->dead) {
+        x=tmpm->x;
+        y=tmpm->y;
+        if (i&1)
+          x+=dd;
+        else
+          y+=dd;
+        if (0<=x<=map_width*SCRN_SCALE &&
+              0<=y<=map_height*SCRN_SCALE &&
+              map[(y/SCRN_SCALE)*map_width+x/SCRN_SCALE]) {
+          if (!map[(y/SCRN_SCALE)*map_width+x/SCRN_SCALE+1] &&
+                x-RoundI64(x,SCRN_SCALE)>SCRN_SCALE/2 ||
+                !map[(y/SCRN_SCALE)*map_width+x/SCRN_SCALE-1] &&
+                x-RoundI64(x,SCRN_SCALE)<SCRN_SCALE/2)
+            x=RoundI64(x,SCRN_SCALE)+SCRN_SCALE/2;
+          if (!map[(y/SCRN_SCALE+1)*map_width+x/SCRN_SCALE] &&
+                y-RoundI64(y,SCRN_SCALE)>SCRN_SCALE/2 ||
+                !map[(y/SCRN_SCALE-1)*map_width+x/SCRN_SCALE] &&
+                y-RoundI64(y,SCRN_SCALE)<SCRN_SCALE/2)
+            y=RoundI64(y,SCRN_SCALE)+SCRN_SCALE/2;
+          tmpm->x=x;
+          tmpm->y=y;
+        }
+      }
+    Sleep(20);
+  }
+}
+
+U0 CleanUp()
+{
+  Free(map);
+  Free(panels_processed_bitmap);
+  map=NULL;
+  panels_processed_bitmap=NULL;
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("3q.A#eGAeA#qAq.A#eGeAeA#qA");
+    Play("3q.A#eGA#AqGq.A#eGA#AqG");
+    Play("4eA#AqGeA#AqGeA#AGAA#AqG");
+  }
+}
+
+U0 MoveMan(F64 theta)
+{
+  I64 x,y,color,step=SCRN_SCALE/2;
+  do {
+    x=man_xx+step*Cos(theta);
+    y=man_yy-step*Sin(theta);
+    x=Clamp(x,0,map_width*SCRN_SCALE);
+    y=Clamp(y,0,map_height*SCRN_SCALE);
+    color=map[y/SCRN_SCALE*map_width+x/SCRN_SCALE];
+    if (color==DKGRAY || color==GREEN) {
+      man_xx=x;
+      man_yy=y;
+      break;
+    } else
+      step>>=1;
+  } while (step);
+}
+
+#define MICRO_STEPS     4
+U0 RotateMan(F64 d)
+{
+  I64 i;
+  for (i=0;i<MICRO_STEPS;i++) {
+    man_theta+=d/MICRO_STEPS;
+    Sleep(15);
+  }
+}
+
+U0 CastleFrankenstein()
+{
+  I64 sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fwd(,,SC_CURSOR_UP);"
+        "  Bwd(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Fire(,CH_SPACE);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=DKGRAY<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case CH_SPACE:
+          Fire;
+          break;
+        case '\n':
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto fs_done;
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_RIGHT:
+              Spawn(&RotateMan,(pi/32)(I64));
+              break;
+            case SC_CURSOR_LEFT:
+              Spawn(&RotateMan,(-pi/32)(I64));
+              break;
+            case SC_CURSOR_UP:
+              MoveMan(man_theta);
+              break;
+            case SC_CURSOR_DOWN:
+              MoveMan(man_theta+pi);
+              break;
+          }
+          break;
+      }
+    }
+fs_done:
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/CastleFrankenstein","F64 best_score=%5.4f;\n",
+        best_score);
+}
+
+CastleFrankenstein;
+
+ diff --git a/public/Wb/Demo/Games/CharDemo.HC.HTML b/public/Wb/Demo/Games/CharDemo.HC.HTML new file mode 100755 index 0000000..bdca622 --- /dev/null +++ b/public/Wb/Demo/Games/CharDemo.HC.HTML @@ -0,0 +1,222 @@ + + + + + + + + + + + +
+/*
+Char graphics are how games on the C64 were made.  You don't need to do it
+this way, unless for fun.  You can just make device context bigger than
+the scrn and scroll around.
+
+See  ::/Demo/Games/RawHide.HC or ::/Demo/Games/BigGuns.HC.
+
+The nice thing about character graphics are the animations.
+*/
+
+#define MAP_WIDTH       (TEXT_COLS*2)
+#define MAP_HEIGHT      (TEXT_ROWS*2)
+
+#define CH_WATER        '^'
+#define CH_LAND         CH_SPACE
+#define CH_TREE         '*'
+
+U16 map[MAP_HEIGHT][MAP_WIDTH];
+
+I64 scrn_pix_x,scrn_pix_y;
+
+U0 DrawIt(CTask *task,CDC *)
+{
+  U16 *ptr;
+  I64 i,j,y=scrn_pix_y>>3;
+  gr.hide_col=gr.hide_row=TRUE;
+  gr.pan_text_x=7-scrn_pix_x&7;
+  gr.pan_text_y=7-scrn_pix_y&7;
+  for (i=0;i<task->win_height;i++) {
+    ptr=&map[y++][scrn_pix_x>>3];
+    for (j=0;j<task->win_width;j++)
+        //By the time you clip to window and handle Fs->scroll_x,Fs->scroll_y,
+        //it is too much trouble to do raw access to gr.text_base like we do
+        //in ::/Demo/Games/Maze.HC.
+      TextChar(task,FALSE,j,i,*ptr++);
+  }
+}
+
+U8 *old_font=text.font;
+U64 waves[4]={
+0x0011AA440011AA44,0x0022558800225588,
+0x0044AA110044AA11,0x0088552200885522};
+
+U0 AnimateEndCB()
+{
+  text.font=old_font;
+  Exit;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  U64 *font=MAlloc(256*8);
+  Fs->task_end_cb=&AnimateEndCB;
+  MemCpy(font,text.font,256*8);
+  text.font=font;
+  font[CH_TREE]=0x18187E7E3C3C18;
+  while (TRUE) {
+    font[CH_WATER]=waves[i++&0x3];
+    Sleep(200);
+    Refresh;
+  }
+}
+
+U0 ScrollTaskX(I64 sign)
+{
+  I64 i;
+  for (i=0;i<32;i++) {
+    scrn_pix_x=ClampI64(scrn_pix_x+sign,0,
+          (MAP_WIDTH-TEXT_COLS+1)*FONT_WIDTH);
+    Refresh;
+  }
+}
+
+U0 ScrollTaskY(I64 sign)
+{
+  I64 i;
+  for (i=0;i<32;i++) {
+    scrn_pix_y=ClampI64(scrn_pix_y+sign,0,
+          (MAP_HEIGHT-TEXT_ROWS+2)*FONT_HEIGHT);
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  I64 i,j,x,y;
+  scrn_pix_x=(MAP_WIDTH-TEXT_COLS)>>1*FONT_WIDTH;
+  scrn_pix_y=(MAP_HEIGHT-TEXT_ROWS)>>1*FONT_HEIGHT;
+
+  MemSetU16(map,CH_WATER+(BLUE<<4+LTBLUE)<<8,MAP_WIDTH*MAP_HEIGHT);
+  for (i=1;i<MAP_WIDTH-1;i++)
+    map[0][i]=map[MAP_HEIGHT-1][i]='.'+(BLUE<<4+RED)<<8;
+  for (i=1;i<MAP_HEIGHT-1;i++)
+    map[i][0]=map[i][MAP_WIDTH-1]='.'+(BLUE<<4+RED)<<8;
+  map[0][0]                     ='.'+(BLUE<<4+RED)<<8;
+  map[0][MAP_WIDTH-1]           ='.'+(BLUE<<4+RED)<<8;
+  map[MAP_HEIGHT-1][0]          ='.'+(BLUE<<4+RED)<<8;
+  map[MAP_HEIGHT-1][MAP_WIDTH-1]='.'+(BLUE<<4+RED)<<8;
+
+  for (i=0;i<20;i++) {
+    x=MAP_WIDTH*Rand;
+    y=MAP_HEIGHT*Rand;
+    for (j=0;j<1000;j++) {
+      map[y][x]=CH_LAND+(YELLOW<<4+BLACK)<<8;
+      x=ClampI64(x+RandU16%3-1,0,MAP_WIDTH-1);
+      y=ClampI64(y+RandU16%3-1,0,MAP_HEIGHT-1);
+    }
+  }
+  for (i=0;i<100;i++) {
+    do {
+      x=MAP_WIDTH*Rand;
+      y=MAP_HEIGHT*Rand;
+    } while (map[y][x].u8[0]!=CH_LAND);
+    for (j=0;j<100;j++) {
+      map[y][x]=CH_TREE+(YELLOW<<4+GREEN)<<8;
+      x=ClampI64(x+RandU16%3-1,0,MAP_WIDTH-1);
+      y=ClampI64(y+RandU16%3-1,0,MAP_HEIGHT-1);
+    }
+  }
+}
+
+U0 CleanUp()
+{
+  gr.pan_text_x=gr.pan_text_y=0;
+  gr.hide_col=gr.hide_row=FALSE;
+}
+
+U0 CharDemo()
+{
+  I64 sc;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "}"
+        );
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              Spawn(&ScrollTaskX,-1,"Scroll",,Fs);
+              break;
+            case SC_CURSOR_RIGHT:
+              Spawn(&ScrollTaskX,1,"Scroll",,Fs);
+              break;
+            case SC_CURSOR_UP:
+              Spawn(&ScrollTaskY,-1,"Scroll",,Fs);
+              break;
+            case SC_CURSOR_DOWN:
+              Spawn(&ScrollTaskY,1,"Scroll",,Fs);
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto sq_done;
+      }
+    }
+sq_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+CharDemo;
+
+ diff --git a/public/Wb/Demo/Games/CircleTrace.HC.HTML b/public/Wb/Demo/Games/CircleTrace.HC.HTML new file mode 100755 index 0000000..6a1298b --- /dev/null +++ b/public/Wb/Demo/Games/CircleTrace.HC.HTML @@ -0,0 +1,159 @@ + + + + + + + + + + + +
+//Practice tracing circles
+
+//Giotto, a famous artist, drew a freehand circle to get a job.
+
+RegDft("TempleOS/CircleTrace","F64 best_score=999;\n");
+RegExe("TempleOS/CircleTrace");
+
+I64 cx,cy;
+F64 avg_error=0,elapsed_time=0,total_error=0,score=999;
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE)
+    Play("5hEDC4A5RCDECR");
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  GrPrint(dc,0,0,"Error:%6.3f  Time:%6.3f  Score:%6.3f  Best:%8.3f",
+        avg_error,elapsed_time,score,best_score);
+}
+
+#define CIRCLE_RADIUS   100
+#define CIRCUMFERENCE   (2*pi*CIRCLE_RADIUS)
+
+Bool CTPlot(CDC *dc,I64 x,I64 y,I64)
+{
+  F64 rad=Sqrt(Sqr(x-cx)+Sqr(y-cy));
+  GrPlot(dc,x,y);
+  total_error+=Abs(rad-CIRCLE_RADIUS);
+  return TRUE;
+}
+
+U0 CircleTrace()
+{
+  I64 msg_code,arg1,arg2,x1,y1;
+  F64 rad,t0,total_distance;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  cx=Fs->pix_width/2;
+  cy=Fs->pix_height/2;
+
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+  Fs->draw_it=&DrawIt;
+
+  DCFill;
+  dc->color=ROP_XOR+BLACK^TRANSPARENT;
+  GrCircle(dc,cx,cy,CIRCLE_RADIUS);
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
+    switch (msg_code) {
+      case MSG_KEY_UP:
+        break;
+      case MSG_MS_L_DOWN:
+        DCFill;
+        dc->color=ROP_XOR+BLACK^TRANSPARENT;
+        GrCircle(dc,cx,cy,CIRCLE_RADIUS);
+        dc->color=ROP_XOR+RED^TRANSPARENT;
+        t0=tS;
+        total_distance=0.001;
+        total_error=0;
+        x1=arg1; y1=arg2;
+        do {
+          msg_code=ScanMsg(&arg1,&arg2,
+                1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          switch (msg_code) {
+            case MSG_MS_L_UP:
+              break;
+            case MSG_MS_MOVE:
+              if (x1!=arg1 || y1!=arg2) {
+                total_distance+=Sqrt(Sqr(x1-arg1)+Sqr(y1-arg2));
+                Line(dc,x1,y1,0,arg1,arg2,0,&CTPlot);
+                x1=arg1;y1=arg2;
+//undo overlapping pixs on segments
+                GrPlot(dc,x1,y1);
+                rad=Sqrt(Sqr(x1-cx)+Sqr(y1-cy));
+                total_error-=Abs(rad-CIRCLE_RADIUS);
+              }
+              break;
+          }
+          elapsed_time=tS-t0;
+          avg_error=total_error/total_distance;
+          score=elapsed_time*avg_error;
+
+          //Sleep()s until the next time the
+          //window mgr task runs.  The
+          //window mgr calls the UpdateWin() routine
+          //and places msgs in the que, so there's
+          //no need to do anything until the window mgr runs.
+          Refresh;
+
+        } while (msg_code!=MSG_MS_L_UP);
+        music.mute=TRUE; Sleep(200);
+        if (total_distance>0.95*CIRCUMFERENCE) {
+          if (score<best_score) {
+            Snd(86);Sleep(50);Snd;Sleep(50);
+            Snd(86);Sleep(50);Snd;Sleep(50);
+            Snd(86);Sleep(50);
+            best_score=score;
+          } else {
+            Snd(62);Sleep(50);
+          }
+        } else {
+          Snd(34);Sleep(1000);
+        }
+        Snd; Sleep(200); music.mute=FALSE;
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || arg1!=CH_SHIFT_ESC && arg1!=CH_ESC);
+  GetMsg(,,1<<MSG_KEY_UP);
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+  RegWrite("TempleOS/CircleTrace","F64 best_score=%5.4f;\n",best_score);
+}
+
+CircleTrace;  //Execute when #included
+
+ diff --git a/public/Wb/Demo/Games/Collision.HC.HTML b/public/Wb/Demo/Games/Collision.HC.HTML new file mode 100755 index 0000000..9fcd415 --- /dev/null +++ b/public/Wb/Demo/Games/Collision.HC.HTML @@ -0,0 +1,185 @@ + + + + + + + + + + + +
+/*Uses fixed-point arithmetic
+because it used to be faster than floating
+point.  See ::/Demo/Lectures/FixedPoint.HC.
+
+The decimal place is between
+bits 31 and 32.
+*/
+
+#define BALLS_NUM       64
+#define BALL_RADIUS     5
+
+I64 ball_x[BALLS_NUM],ball_y[BALLS_NUM],
+   ball_velocity_x[BALLS_NUM],ball_velocity_y[BALLS_NUM];
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  dc->color=RED;
+  for (i=0;i<BALLS_NUM;i++)
+    GrCircle(dc,ball_x[i].i32[1],ball_y[i].i32[1],BALL_RADIUS);
+}
+
+/****
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+Initial and final velocity vects
+with normal and tangential components.
+All masses are ident, so they
+have been dropped from the equations.
+
+Conservation of Momentum:
+
+V1it+V2it=V1ft+V2ft
+
+V1in+V2in=V1fn+V2fn
+
+Conservation of Energy:
+
+|V1i|2+|V2i|2=|V1f|2+|V2f|2
+****/
+
+U0 AnimateTask(I64)
+{
+  CTask *task=Fs->parent_task;
+  I64 i,j,h,v,distdist,
+        dia=(2*BALL_RADIUS)<<32,
+        diadia=SqrI64(2*BALL_RADIUS)<<32,
+        delta_x,delta_y,v_t1,v_n1,v_t2,v_n2;
+  F64 dist;
+  while (TRUE) {
+    h=task->pix_width;
+    v=task->pix_height;
+    for (i=0;i<BALLS_NUM;i++) {
+      ball_x[i]+=ball_velocity_x[i];
+      ball_y[i]+=ball_velocity_y[i];
+      if (ball_x[i]<BALL_RADIUS<<32) {
+        ball_velocity_x[i]*=-1;
+        ball_x[i]=BALL_RADIUS<<32;
+      }
+      if (ball_x[i]>=(h-BALL_RADIUS)<<32) {
+        ball_velocity_x[i]*=-1;
+        ball_x[i]=(h-BALL_RADIUS)<<32;
+      }
+      if (ball_y[i]<BALL_RADIUS<<32) {
+        ball_velocity_y[i]*=-1;
+        ball_y[i]=BALL_RADIUS<<32;
+      }
+      if (ball_y[i]>=(v-BALL_RADIUS)<<32) {
+        ball_velocity_y[i]*=-1;
+        ball_y[i]=(v-BALL_RADIUS)<<32;
+      }
+    }
+    for (i=0;i<BALLS_NUM;i++) {
+      for (j=i+1;j<BALLS_NUM;j++) {
+        delta_x=ball_x[i]-ball_x[j];
+        delta_y=ball_y[i]-ball_y[j];
+
+        //We shift 16 because multiplying
+        //two 32 shifted would yield 64 shifted
+        //and we want a 32 shifted res.
+        distdist=SqrI64(delta_x>>16)+SqrI64(delta_y>>16);
+
+        //We work with square instead of sqrt
+        //to avoid unnecessarily calculating
+        //square heads (They are slow.)
+        if (distdist && distdist<=diadia) {
+          dist=Sqrt(distdist); //shifted 16 bits
+          delta_x/=dist; //shifted 16
+          delta_y/=dist;
+
+          v_t1=(ball_velocity_x[i]>>16*delta_y-
+                ball_velocity_y[i]>>16*delta_x)>>16;
+          v_n1=(ball_velocity_x[i]>>16*delta_x+
+                ball_velocity_y[i]>>16*delta_y)>>16;
+          v_t2=(ball_velocity_x[j]>>16*delta_y-
+                ball_velocity_y[j]>>16*delta_x)>>16;
+          v_n2=(ball_velocity_x[j]>>16*delta_x+
+                ball_velocity_y[j]>>16*delta_y)>>16;
+
+          if (ball_velocity_x[i]>>16*ball_velocity_x[j]>>16+
+                ball_velocity_y[i]>>16*ball_velocity_y[j]>>16<=0) {
+            ball_velocity_x[i]= v_t1*delta_y-v_n1*delta_x;
+            ball_velocity_y[i]=-v_t1*delta_x-v_n1*delta_y;
+            ball_velocity_x[j]= v_t2*delta_y-v_n2*delta_x;
+            ball_velocity_y[j]=-v_t2*delta_x-v_n2*delta_y;
+          } else {
+            ball_velocity_x[i]= v_t1*delta_y+v_n2*delta_x;
+            ball_velocity_y[i]=-v_t1*delta_x+v_n2*delta_y;
+            ball_velocity_x[j]= v_t2*delta_y+v_n1*delta_x;
+            ball_velocity_y[j]=-v_t2*delta_x+v_n1*delta_y;
+          }
+
+          //Correct for overlap
+          dist=0x10000+(dia/0x10000-dist)/2;
+          ball_x[i]+=dist*delta_x;
+          ball_y[i]+=dist*delta_y;
+          ball_x[j]-=dist*delta_x;
+          ball_y[j]-=dist*delta_y;
+        }
+      }
+    }
+    Sleep(1);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<BALLS_NUM;i++) {
+    ball_x[i]=(RandU16%(Fs->pix_width-BALL_RADIUS*2)+BALL_RADIUS)<<32;
+    ball_y[i]=(RandU16%(Fs->pix_height-BALL_RADIUS*2)+BALL_RADIUS)<<32;
+    ball_velocity_x[i]=RandI32/4;
+    ball_velocity_y[i]=RandI32/4;
+  }
+}
+
+U0 Collision()
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar;
+  SettingsPop;
+}
+
+Collision;
+
+ diff --git a/public/Wb/Demo/Games/Digits.HC.HTML b/public/Wb/Demo/Games/Digits.HC.HTML new file mode 100755 index 0000000..4598bc9 --- /dev/null +++ b/public/Wb/Demo/Games/Digits.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+//This loads a lst of zero terminated
+//strings into the sym table and
+//gives a name to it.  Strings like
+//this are known as Define entries.
+
+//See ST_RAINBOW_10
+
+U0 PrintDigit(U8 ch)
+{
+//The %Z code displays a Define subentry
+  if ('0'<=ch<='9')
+    "$FG,%Z$%d$FG$",ch-'0',"ST_RAINBOW_10",ch-'0';
+}
+
+U0 PrintPattern(U8 *st)
+{
+  I64 ch;
+  while (ch=*st++)
+    PrintDigit(ch);
+  '\n';
+}
+
+U0 Digits()
+{
+  I64 num,ch,i;
+  U8 answer[1024];
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=DKGRAY<<4+WHITE;
+  DocClear;
+//Set default background and foreground
+  "$WW,1$$BG,DKGRAY$$FD,WHITE$"
+        "\nThis is a memory game.  "
+        "Try to remember the digits and enter them.  "
+        "They are colored based on electrical "
+        "engineering color codes.\n";
+  for (i=0;i<10;i++)
+    "$FG,%Z$%d: %Z\n",i,"ST_RAINBOW_10",i,i,"ST_RAINBOW_10";
+  "$FG$\n"; //set to default background
+  ch=PressAKey;
+  if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
+  while (TRUE) {
+restart:
+    num=0;
+//Set to zeros so we have terminators
+    MemSet(answer,0,sizeof(answer));
+    while (TRUE) {
+      DocClear;
+      "$WW,1$$BG,DKGRAY$$FD,WHITE$\n";
+      "Pattern\nLength:%d\n\n",num+1;
+      answer[num++]=RandU32%10+'0';
+      PrintPattern(answer);
+      ch=PressAKey;
+      if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
+      DocClear;
+      "$WW,1$$BG,DKGRAY$$FD,WHITE$\n";
+      "Guess\nLength:%d\n\n",num;
+      for (i=0;i<num;i++) {
+        ch=GetChar(,FALSE);
+        if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
+        PrintDigit(ch);
+        if (ch!=answer[i]) {
+          "\nScore:%d\n",num;
+          PrintPattern(answer);
+          Beep; Beep;
+          ch=PressAKey;
+          if (ch==CH_ESC||ch==CH_SHIFT_ESC)
+            goto dg_done;
+          else
+            goto restart;
+        }
+      }
+    }
+  }
+dg_done:
+  DocClear;
+  SettingsPop;
+}
+
+Digits;
+
+ diff --git a/public/Wb/Demo/Games/DunGen.HC.HTML b/public/Wb/Demo/Games/DunGen.HC.HTML new file mode 100755 index 0000000..be7ec76 --- /dev/null +++ b/public/Wb/Demo/Games/DunGen.HC.HTML @@ -0,0 +1,478 @@ + + + + + + + + + + + +
+RegDft("TempleOS/DunGen","F64 best_score=9999;\n");
+RegExe("TempleOS/DunGen");
+
+//Set snap to 4 and width to 4
+//if you edit this map.
+
+//Don't forget to change the
+//starting pos.
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+ 
+<4>/* Graphics Not Rendered in HTML */
+
+<5>/* Graphics Not Rendered in HTML */
+
+<6>/* Graphics Not Rendered in HTML */
+
+<7>/* Graphics Not Rendered in HTML */
+
+<8>/* Graphics Not Rendered in HTML */
+
+<9>/* Graphics Not Rendered in HTML */
+
+<10>/* Graphics Not Rendered in HTML */
+
+
+//These are indexed by color #.
+//See COLORS.
+
+U8 *tiles1[16]={NULL,<7> ,<5> ,NULL,NULL,NULL,NULL,NULL,
+  <6> ,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+
+U8 *tiles2[16]={NULL,<8> ,<5> ,NULL,NULL,NULL,NULL,NULL,
+  <6> ,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+
+#define SCRN_SCALE      24
+#define SCRN_WIDTH      24
+#define SCRN_HEIGHT     24
+I64 scrn_x,scrn_y;
+
+#define MAP_SCALE       4
+I64 map_width,map_height;
+U8 *map=NULL;
+
+I64 man_x,man_y,man_dx,man_dy;
+Bool man_attack;
+F64 man_attack_t0;
+
+#define MONSTERS_NUM    10
+I64 monsters_left;
+class Monster
+{
+  I64 x,y,dx,dy;
+  Bool dead,pad[7];
+} monsters[MONSTERS_NUM];
+
+F64 t0,tf;
+
+#define LOS_SCALE       4
+
+Bool LOSPlot(U8 *,I64 x,I64 y,I64)
+{
+  if (!map[(y/LOS_SCALE)*map_width+(x/LOS_SCALE)])
+    return FALSE;
+  else
+    return TRUE;
+}
+
+Bool LOS(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Line of sight
+  return Line(NULL,x1*LOS_SCALE+LOS_SCALE/2,y1*LOS_SCALE+LOS_SCALE/2,0,
+        x2*LOS_SCALE+LOS_SCALE/2,y2*LOS_SCALE+LOS_SCALE/2,0,&LOSPlot);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CDC *dc_t=DCAlias(gr.dc2,task);
+  I64 i,x,y,xx,yy,x1,y1,z1,color,
+        cx=task->pix_width/2,
+        cy=task->pix_height/2;
+  CD3I32 poly[4];
+  U8 **_tiles;
+  F64 tt;
+  Monster *tmpm;
+
+  if (Blink(5))
+    _tiles=tiles1;
+  else
+    _tiles=tiles2;
+
+  Mat4x4RotX(dc_t->r,60*2*pi/360);
+  Mat4x4RotZ(dc_t->r,15*2*pi/360);
+  DCMat4x4Set(dc_t,dc_t->r);
+  dc_t->x=task->pix_width/2;
+  dc_t->y=task->pix_height/2;
+  dc_t->flags|=DCF_TRANSFORMATION;
+
+  //You could make it much more efficient
+  //if you did it like ::/Demo/Games/BigGuns.HC
+  //with a CDC.
+
+  for (y=-SCRN_HEIGHT/2;y<SCRN_HEIGHT/2;y++) {
+    yy=y+scrn_y;
+    if (0<=yy<map_height)
+      for (x=-SCRN_WIDTH/2;x<SCRN_WIDTH/2;x++) {
+        xx=x+scrn_x;
+        if (0<=xx<map_width) {
+          if ((color=map[yy*map_width+xx]) &&
+                LOS(xx,yy,man_x,man_y)) {
+            if (_tiles[color]) {
+              x1=x*SCRN_SCALE;
+              y1=y*SCRN_SCALE;
+              z1=0;
+              DCTransform(dc_t,&x1,&y1,&z1);
+              Sprite3(dc,x1,y1,z1,_tiles[color]);
+            } else {//If no tile defined, do solid color.
+              poly[0].x=x*SCRN_SCALE;
+              poly[0].y=y*SCRN_SCALE;
+              poly[0].z=0;
+              poly[1].x=(x+1)*SCRN_SCALE-1;
+              poly[1].y=y*SCRN_SCALE;
+              poly[1].z=0;
+              poly[2].x=(x+1)*SCRN_SCALE;
+              poly[2].y=(y+1)*SCRN_SCALE-1;
+              poly[2].z=0;
+              poly[3].x=x*SCRN_SCALE-1;
+              poly[3].y=(y+1)*SCRN_SCALE-1;
+              poly[3].z=0;
+              dc_t->color=color;
+              GrFillPoly3(dc_t,4,poly);
+            }
+          }
+        }
+      }
+  }
+
+  for (y=-SCRN_HEIGHT/2;y<SCRN_HEIGHT/2;y++) {
+    yy=y+scrn_y;
+    if (0<=yy<map_height)
+      for (x=-SCRN_WIDTH/2;x<SCRN_WIDTH/2;x++) {
+        xx=x+scrn_x;
+        if (0<=xx<map_width) {
+          if (!map[yy*map_width+xx]) {
+            if (yy+1<map_height && LOS(xx,yy+1,man_x,man_y)) {
+              x1=x*SCRN_SCALE;
+              y1=y*SCRN_SCALE;
+              z1=0;
+              DCTransform(dc_t,&x1,&y1,&z1);
+              Sprite3(dc,x1,y1,z1,<9>);
+            }
+            if (xx+1<map_width && LOS(xx+1,yy,man_x,man_y)) {
+              x1=x*SCRN_SCALE;
+              y1=y*SCRN_SCALE;
+              z1=0;
+              DCTransform(dc_t,&x1,&y1,&z1);
+              Sprite3(dc,x1,y1,z1,<10>);
+            }
+          }
+        }
+      }
+  }
+
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+    if (!tmpm->dead && LOS(tmpm->x,tmpm->y,man_x,man_y)) {
+      x1=(tmpm->x-scrn_x)*SCRN_SCALE+SCRN_SCALE/2;
+      y1=(tmpm->y-scrn_y)*SCRN_SCALE+SCRN_SCALE/2;
+      z1=0;
+      DCTransform(dc_t,&x1,&y1,&z1);
+      if (tmpm->dx<0) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,x1,y1,x1,y1+1);
+      } else
+        dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+      Sprite3(dc,x1,y1,z1,<4>);
+    }
+
+  x1=(man_x-scrn_x)*SCRN_SCALE+SCRN_SCALE/2;
+  y1=(man_y-scrn_y)*SCRN_SCALE+SCRN_SCALE/2;
+  z1=0;
+  if (tS-man_attack_t0<0.2) {
+    x1+=Tri(tS-man_attack_t0,0.2)*SCRN_SCALE*man_dx;
+    y1+=Tri(tS-man_attack_t0,0.2)*SCRN_SCALE*man_dy;
+    if (man_dy!=1)
+      y1-=Saw(tS-man_attack_t0,0.2)*SCRN_SCALE;
+  }
+  DCTransform(dc_t,&x1,&y1,&z1);
+  if (man_dx<0) {
+    dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+    DCSymmetrySet(dc,x1,y1,x1,y1+1);
+  } else
+    dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+
+  if (tS-man_attack_t0<0.2)
+    Sprite3(dc,x1,y1,z1,<3>);
+  else
+    Sprite3(dc,x1,y1,z1,<2>);
+
+  DCDel(dc_t);
+
+  if (tf) {
+    dc->color=LTRED;
+    if (Blink)
+      GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed");
+    tt=tf;
+  } else {
+    dc->color=LTGREEN;
+    tt=tS;
+  }
+  GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",
+        monsters_left,tt-t0,best_score);
+}
+
+U0 Attack()
+{
+  I64 i;
+  Monster *tmpm;
+
+  man_attack_t0=tS;
+  Noise(100,53,74);
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    if (!tmpm->dead &&
+          man_x+man_dx==tmpm->x && man_y+man_dy==tmpm->y) {
+      tmpm->dead=TRUE;
+      if (!--monsters_left) {
+        tf=tS;
+        if (tf-t0<best_score)
+          best_score=tf-t0;
+      }
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,x,y;
+  CDC *dc;
+  Monster *tmpm;
+
+  dc=Sprite2DC(<1>);
+  map_width =dc->width/MAP_SCALE;
+  map_height=dc->height/MAP_SCALE;
+  Free(map);
+  map=MAlloc(map_width*map_height*sizeof(U8));
+  for (y=0;y<map_height;y++)
+    for (x=0;x<map_width;x++)
+      map[y*map_width+x]=GrPeek(dc,x*MAP_SCALE,y*MAP_SCALE);
+  DCDel(dc);
+
+  man_attack_t0=0;
+  man_attack=FALSE;
+  man_x=0;
+  man_y=4;
+  man_dx=0;
+  man_dy=0;
+  scrn_x=0;
+  scrn_y=0;
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    tmpm->dead=FALSE;
+    tmpm->dx=0;
+    tmpm->dy=0;
+    do {
+      tmpm->x=RandU64%(map_width-2)+1;
+      tmpm->y=RandU64%(map_height-2)+1;
+    } while (!map[(tmpm->y)*map_width+tmpm->x]);
+  }
+  monsters_left=MONSTERS_NUM;
+  tf=0;
+  t0=tS;
+}
+
+U0 CleanUp()
+{
+  Free(map);
+  map=NULL;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i,x,y,dx,dy;
+  Monster *tmpm;
+
+  while (TRUE) {
+    for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+      if (!tmpm->dead) {
+        dx=RandU16%3-1;
+        dy=RandU16%3-1;
+        x=tmpm->x+dx;
+        y=tmpm->y+dy;
+        if (0<=x<map_width && 0<=y<map_height && map[y*map_width+x]) {
+          tmpm->x=x;
+          tmpm->y=y;
+          tmpm->dx=dx;
+          tmpm->dy=dy;
+        }
+      }
+    Sleep(1000);
+  }
+}
+
+U0 DunGen()
+{
+  I64 ch,sc;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Attack(,CH_SPACE);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      switch (GetMsg(&ch,&sc,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          switch (ch) {
+            case '\n':
+              Init;
+              break;
+            case CH_SPACE:
+              man_attack=TRUE;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto dg_done;
+            case 0:
+              switch (sc.u8[0]) {
+                case SC_CURSOR_RIGHT:
+                  if (man_attack) {
+                    man_dx=1;
+                    man_dy=0;
+                    Attack;
+                  } else
+                    if (man_x+1<map_width &&
+                          map[man_y*map_width+(man_x+1)]==DKGRAY) {
+                      man_x++;
+                      if (man_x-scrn_x>SCRN_WIDTH/2-3) {
+                        scrn_x+=SCRN_WIDTH/2;
+                        if (scrn_x+SCRN_WIDTH/2>map_width)
+                          scrn_x=map_width-SCRN_WIDTH/2;
+                      }
+                    }
+                  break;
+                case SC_CURSOR_LEFT:
+                  if (man_attack) {
+                    man_dx=-1;
+                    man_dy=0;
+                    Attack;
+                  } else
+                    if (man_x-1>=0 &&
+                          map[man_y*map_width+(man_x-1)]==DKGRAY) {
+                      man_x--;
+                      if (man_x-scrn_x<-SCRN_WIDTH/2+3) {
+                        scrn_x-=SCRN_WIDTH/2;
+                        if (scrn_x-SCRN_WIDTH/2<0)
+                          scrn_x=SCRN_WIDTH/2;
+                      }
+                    }
+                  break;
+                case SC_CURSOR_UP:
+                  if (man_attack) {
+                    man_dx=0;
+                    man_dy=-1;
+                    Attack;
+                  } else
+                    if (man_y-1>=0 &&
+                          map[(man_y-1)*map_width+man_x]==DKGRAY) {
+                      man_y--;
+                      if (man_y-scrn_y<-SCRN_HEIGHT/2+3) {
+                        scrn_y-=SCRN_HEIGHT/2;
+                        if (scrn_y-SCRN_HEIGHT/2<0)
+                          scrn_y=SCRN_HEIGHT/2;
+                      }
+                    }
+                  break;
+                case SC_CURSOR_DOWN:
+                  if (man_attack) {
+                    man_dx=0;
+                    man_dy=1;
+                    Attack;
+                  } else
+                    if (man_y+1<map_height &&
+                          map[(man_y+1)*map_width+man_x]==DKGRAY) {
+                      man_y++;
+                      if (man_y-scrn_y>SCRN_HEIGHT/2-3) {
+                        scrn_y+=SCRN_HEIGHT/2;
+                        if (scrn_y+SCRN_HEIGHT/2>map_height)
+                          scrn_y=map_height-SCRN_HEIGHT/2;
+                      }
+                    }
+                  break;
+              }
+          }
+          break;
+        case MSG_KEY_UP:
+          if (ch==CH_SPACE)
+            man_attack=FALSE;
+          break;
+      }
+    }
+dg_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/DunGen","F64 best_score=%5.4f;\n",best_score);
+}
+
+DunGen;
+
+ diff --git a/public/Wb/Demo/Games/ElephantWalk.HC.HTML b/public/Wb/Demo/Games/ElephantWalk.HC.HTML new file mode 100755 index 0000000..10d97c7 --- /dev/null +++ b/public/Wb/Demo/Games/ElephantWalk.HC.HTML @@ -0,0 +1,117 @@ + + + + + + + + + + + +
+//Press <CTRL-t>.
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                /* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//The sprite was created with <CTRL-r>.
+
+U0 ElephantWalk()
+{
+  I64 sc,
+        x=Fs->pix_width>>1,y=Fs->pix_height>>1, //Fs is current CTask struct.
+        x_last=x;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  while (TRUE) {
+    DCFill;
+    if (x>x_last) {
+      DCSymmetrySet(,x,y,x,y-1);
+      gr.dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+    } else
+      gr.dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    x_last=x;
+    Sprite3ZB(gr.dc,x,y,0,<1>,Sin(8*tS)/4);//Use <CTRL-r> "Ptr to Sprite"
+    switch (GetKey(&sc)) {
+      case 0:
+        switch (sc.u8[0]) {//Scan code lowest byte
+          case SC_CURSOR_UP:
+            y-=32;
+            if (y<0)
+              y=Fs->pix_height;
+            break;
+          case SC_CURSOR_DOWN:
+            y+=32;
+            if (y>Fs->pix_height)
+              y=0;
+            break;
+          case SC_CURSOR_LEFT:
+            x-=32;
+            if (x<0)
+              x=Fs->pix_width;
+            break;
+          case SC_CURSOR_RIGHT:
+            x+=32;
+            if (x>Fs->pix_width)
+              x=0;
+            break;
+        }
+        break;
+      case CH_ESC:
+      case CH_SHIFT_ESC:
+        goto ew_done;
+    }
+  }
+ew_done:
+  DCFill;
+}
+
+ElephantWalk;
+
+ diff --git a/public/Wb/Demo/Games/FlapBat.HC.HTML b/public/Wb/Demo/Games/FlapBat.HC.HTML new file mode 100755 index 0000000..11e14ea --- /dev/null +++ b/public/Wb/Demo/Games/FlapBat.HC.HTML @@ -0,0 +1,305 @@ + + + + + + + + + + + +
+RegDft("TempleOS/FlapBat","F64 best_score=9999;\n");
+RegExe("TempleOS/FlapBat");
+
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+#define BORDER          6
+#define EAT_TIME        0.5
+#define FLAP_TIME       0.5
+#define BAT_BOX 10
+
+Bool flap_down,flap_up;
+F64 flap_phase,delta_phase,bat_y,bat_x,eat_timeout,flap_time;
+F64 frame_x,game_t0,game_tf;
+
+#define BUGS_NUM        32
+I32 bug_cnt,bugs_x[BUGS_NUM],bugs_y[BUGS_NUM];
+Bool bugs_dead[BUGS_NUM];
+
+#define GLOW_PERIOD     3.0
+F64 bugs_glow_phase[BUGS_NUM];
+
+CDC *limit_flood_fill_dc; //Prevent uncontrolled flood-fill flicker.
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,y,x,
+        h=MaxI64(1,task->pix_width-2*BORDER),
+        v=MaxI64(1,task->pix_height-2*BORDER);
+  U8 *tmps,*tmps2,*tmps3;
+  F64 tt=flap_phase*flap_phase*flap_phase,ts=tS;
+
+  bat_x=task->pix_width>>3;
+  Sprite3(dc,(7*task->pix_width)>>3,20,0,<5>);
+
+  dc->color=DKGRAY;
+  GrCircle(dc,bat_x+5+20*Saw(15*tS,2),bat_y,10+20*Saw(15*tS,2),5,-pi/4,pi/2);
+
+  tmps=SpriteInterpolate(tt,<1>,<2>);
+  if (eat_timeout && tS<eat_timeout) {
+    tmps2=SpriteInterpolate(tt,<3>,<4>);
+    tmps3=SpriteInterpolate(1.0-(eat_timeout-tS)/EAT_TIME,tmps2,tmps);
+    Free(tmps);
+    Free(tmps2);
+    tmps=tmps3;
+  }
+
+  DCFill(limit_flood_fill_dc);
+  Sprite3(limit_flood_fill_dc,16,32,0,tmps);
+  if (GrPeek(limit_flood_fill_dc,0,0)!=TRANSPARENT) {//Did FloodFill go crazy?
+    limit_flood_fill_dc->color=TRANSPARENT;
+    GrFloodFill(limit_flood_fill_dc,0,0);
+  }
+  GrBlot(dc,bat_x-16,bat_y-32,limit_flood_fill_dc);
+
+  Free(tmps);
+  for (i=0;i<BUGS_NUM;i++)
+    if (!bugs_dead[i]) {
+      x=(bugs_x[i]+frame_x)%h+BORDER;
+      y=bugs_y[i]%v+BORDER;
+      if (Saw(ts+bugs_glow_phase[i],GLOW_PERIOD)<0.2) {
+        if (i&1)
+          dc->color=YELLOW;
+        else
+          dc->color=LTGREEN;
+      } else
+        dc->color=BLACK;
+      GrPlot(dc,x,y);
+      GrPlot(dc,x+1,y);
+      dc->color=BLACK;
+      GrPlot(dc,x,y-1);
+    }
+  if (game_tf) {
+    dc->color=RED;
+    GrPrint(dc,(task->pix_width-FONT_WIDTH*14)/2,
+          (task->pix_height-FONT_HEIGHT)/2,"Game Completed");
+    tt=game_tf;
+  } else {
+    dc->color=BLACK;
+    tt=tS;
+  }
+  GrPrint(dc,0,0,"Bugs:%3.1f%% Time:%3.2f Best:%3.2f",
+        100.0*(BUGS_NUM-bug_cnt)/BUGS_NUM,tt-game_t0,best_score);
+}
+
+U0 CheckBugs(CTask *task)
+{
+  I64 i,x,y,
+        h=MaxI64(1,task->pix_width-2*BORDER),
+        v=MaxI64(1,task->pix_height-2*BORDER);
+  if (eat_timeout && eat_timeout-tS<0.75*EAT_TIME) {
+    Suspend(task->song_task,FALSE);
+    if (tS>=eat_timeout)
+      eat_timeout=0;
+  }
+  for (i=0;i<BUGS_NUM;i++)
+    if (!bugs_dead[i]) {
+      x=(bugs_x[i]+frame_x)%h+BORDER;
+      y=bugs_y[i]%v+BORDER;
+      if (AbsI64(x-bat_x)<BAT_BOX && AbsI64(y-bat_y)<BAT_BOX) {
+        bugs_dead[i]=TRUE;
+        eat_timeout=tS+EAT_TIME;
+        Snd(74);
+        Suspend(task->song_task);
+        bug_cnt--;
+      }
+    }
+  if (!game_tf && !bug_cnt) {
+    game_tf=tS;
+    Suspend(task->song_task);
+    Snd;
+    if (game_tf-game_t0<best_score)
+      best_score=game_tf-game_t0;
+  }
+  frame_x-=0.1;
+  if (frame_x<0)
+    frame_x+=h;
+}
+
+U0 Init()
+{
+  I64 i;
+  limit_flood_fill_dc=DCNew(32,40);
+  flap_down=flap_up=FALSE;
+  flap_phase=0;
+  bat_x=Fs->pix_width>>3;
+  bat_y=0;
+  frame_x=0;
+  bug_cnt=BUGS_NUM;
+  for (i=0;i<BUGS_NUM;i++) {
+    bugs_dead[i]=FALSE;
+    bugs_x[i]=RandU16;
+    bugs_y[i]=RandU16;
+    bugs_glow_phase[i]=GLOW_PERIOD*Rand;
+  }
+  Suspend(Fs->song_task,FALSE);
+  flap_time=eat_timeout=0;
+  delta_phase=game_tf=0;
+  game_t0=tS;
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("4eB5E4B5C4B5EsEFqE4eB5E4B5C4B5EsEF");
+    Play("5qE4eA5D4ABA5DsDCqD4eB5E4B5C4B");
+    Play("5EsEDqE");
+  }
+}
+
+U0 AnimateTask(I64)
+{
+  while (TRUE) {
+    if (flap_down) {
+      flap_down=FALSE;
+      delta_phase=-0.005*Min(1.0,(tS-flap_time)/FLAP_TIME);
+      flap_time=tS;
+    } else if (flap_up) {
+      flap_up=FALSE;
+      delta_phase= 0.005;
+    }
+    if (delta_phase<0) {
+      bat_y+=75*delta_phase;
+      delta_phase+=0.000015;
+    } else
+      bat_y+=0.15;
+    bat_y=Clamp(bat_y,BORDER,Fs->parent_task->pix_height-BORDER);
+    flap_phase=Clamp(flap_phase+delta_phase,0.0,1.0);
+    CheckBugs(Fs->parent_task);
+    Sleep(1);
+  }
+}
+
+U0 CleanUp()
+{
+  DCDel(limit_flood_fill_dc);
+}
+
+U0 FlapBat()
+{
+  Bool rst_space=TRUE;
+  I64 arg1,arg2;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Flap(,CH_SPACE);"
+        "}"
+        );
+
+  PopUpOk("Use $GREEN$<SPACE>$FG$ to flap.\nHold down to glide.");
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=LTGRAY<<4+WHITE;
+  WinBorder(ON);
+  WinHorz(1,TEXT_COLS/2);
+  WinVert(2,TEXT_ROWS/2);
+  DocCursor;
+  DocClear;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case CH_SPACE:
+              if (rst_space) {
+                flap_down=TRUE;
+                rst_space=FALSE;
+              }
+              break;
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto bl_done;
+          }
+          break;
+        case MSG_KEY_UP:
+          switch (arg1) {
+            case CH_SPACE:
+              flap_up=TRUE;
+              rst_space=TRUE;
+              break;
+          }
+          break;
+      }
+    }
+bl_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/FlapBat","F64 best_score=%5.4f;\n",best_score);
+}
+
+FlapBat;
+
+ diff --git a/public/Wb/Demo/Games/FlatTops.HC.HTML b/public/Wb/Demo/Games/FlatTops.HC.HTML new file mode 100755 index 0000000..3114c17 --- /dev/null +++ b/public/Wb/Demo/Games/FlatTops.HC.HTML @@ -0,0 +1,919 @@ + + + + + + + + + + + +
+#define GAME_SPEED_SCALE        0.1
+
+F64 game_speed,
+    launch_unit_x1,launch_unit_y1,launch_unit_x2,launch_unit_y2,launch_t,
+    return_unit_x1,return_unit_y1,return_unit_x2,return_unit_y2,return_t,
+    set_theta_unit_x1,set_theta_unit_y1,set_theta_unit_x2,set_theta_unit_y2,set_theta_t,
+    next_noise;
+CTask *main_task;
+
+#define OT_CARRIER      0
+#define OT_CRUISER      1
+#define OT_FIGHTER      2
+#define OT_TYPES_NUM    3
+
+#define OF_SHIP         1
+#define OF_ACTIVE       2
+#define OF_RETURNING    4
+#define OF_SHOOTING     8
+
+#define FIRE_WIDTH      56
+#define FIRE_HEIGHT     16
+#define FIRE_X_SCALE    0.5
+#define FIRE_Y_SCALE    0.5
+
+#define FIRE_COLORS     16
+U8 fire_colors[FIRE_COLORS]={
+YELLOW,YELLOW,LTRED,YELLOW, BLACK,YELLOW,RED,YELLOW,
+YELLOW,BLACK,YELLOW,LTRED, RED,YELLOW,DKGRAY,YELLOW};
+
+class Obj
+{
+  Obj *next,*last;
+  Obj *next_in_squadron,*last_in_squadron;
+  Obj *host;
+  U8  player,type;
+  U16 flags;
+  I16 squadron,member_num;
+  F64 x,y,theta,dtheta,
+        speed,turn_rate,
+        life_percent,
+        target_x,target_y,
+        ship_guns,ship_guns_range,
+        air_guns,air_guns_range,
+        fuel,max_fuel,fuel_burn_rate,
+        death_time,next_action_time;
+  I32 torpedos,max_torpedos;
+  F64 torpedos_range;
+  U8  fire[(FIRE_WIDTH*FIRE_HEIGHT+7)/8];
+} obj_head;
+
+class Torpedo
+{
+  Torpedo *next,*last;
+  Obj *target;
+  F64 x,y,theta,speed,timeout;
+} torpedo_head;
+
+#define SA_PARKED       0
+#define SA_LAUNCHING    1
+#define SA_FLYING       2
+#define SA_SET_theta    3
+#define SA_RETURNING    4
+#define SA_DEAD         5
+
+class Squadron : Obj
+{
+  I64 action,dead_mask,total_mask;
+} *squadrons;
+
+U0 SquadronIns(Obj *o,Obj *pred)
+{
+  Obj *succ=pred->next_in_squadron;
+  o->next_in_squadron=succ;
+  o->last_in_squadron=pred;
+  pred->next_in_squadron=o;
+  succ->last_in_squadron=o;
+}
+
+U0 SquadronRem(Obj *o)
+{
+  Obj *pred=o->last_in_squadron,*succ=o->next_in_squadron;
+  pred->next_in_squadron=succ;
+  succ->last_in_squadron=pred;
+}
+
+#define PLAYERS_NUM     2
+
+I64 num_carriers[PLAYERS_NUM]={2,3},
+    num_cruisers[PLAYERS_NUM]={2,3},
+    num_planes_per_squadron[PLAYERS_NUM]={6,5},
+    num_squadrons_per_carrier[PLAYERS_NUM]={2,3},
+    num_alive[PLAYERS_NUM],
+    num_squadrons;
+
+Obj *ObjFind(F64 x,F64 y,
+             I64 flag_mask=OF_ACTIVE|OF_RETURNING,I64 flag_val=OF_ACTIVE,
+             I64 type_mask=-1,I64 player_mask=-1,F64 *_d=NULL)
+{
+  Obj *tmpo=obj_head.next,*best=NULL;
+  F64 dd,best_dd=F64_MAX;
+  while (tmpo!=&obj_head) {
+    if (tmpo->flags&flag_mask==flag_val &&
+          Bt(&type_mask,tmpo->type)&&Bt(&player_mask,tmpo->player)) {
+      dd=Sqr(tmpo->x-x)+Sqr(tmpo->y-y);
+      if (dd<best_dd) {
+        best=tmpo;
+        best_dd=dd;
+      }
+    }
+    tmpo=tmpo->next;
+  }
+  if (_d) *_d=Sqrt(best_dd);
+  return best;
+}
+
+U0 ObjDel(Obj *tmpo)
+{
+  if (tmpo) {
+    if (tS<tmpo->death_time)
+      tmpo->flags&=~OF_ACTIVE;
+    else {
+      if (tmpo->squadron>=0)
+        SquadronRem(tmpo);
+      QueRem(tmpo);
+      if (tmpo->squadron>=0)
+        LBts(&squadrons[tmpo->squadron].dead_mask,tmpo->member_num);
+      num_alive[tmpo->player]--;
+      Free(tmpo);
+    }
+  }
+}
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+<6>/* Graphics Not Rendered in HTML */
+
+U8 *imgs[PLAYERS_NUM][OT_TYPES_NUM]={{<1>,<2>,<3>},{<4>,<5>,<6>}};
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,k;
+  F64 d,cur_time=tS;
+  Obj *tmpo;
+  Torpedo *tmpt;
+
+  tmpt=torpedo_head.next;
+  while (tmpt!=&torpedo_head) {
+    dc->color=WHITE;
+    GrPlot(dc,tmpt->x,tmpt->y);
+    tmpt=tmpt->next;
+  }
+
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->flags&OF_ACTIVE && tmpo->flags&OF_SHIP) {
+      Sprite3ZB(dc,tmpo->x,tmpo->y,0,
+            imgs[tmpo->player][tmpo->type],tmpo->theta+pi/2);
+
+      k=0;
+      for (j=0;j<FIRE_HEIGHT;j++)
+        for (i=0;i<FIRE_WIDTH;i++)
+          if (Bt(tmpo->fire,k++)) {
+            dc->color=fire_colors[ToI64(k+10*tS)&(FIRE_COLORS-1)];
+            GrPlot(dc,
+                  tmpo->x+FIRE_X_SCALE*(i-FIRE_WIDTH /2+(11*tS+i)%1.7)
+            *Cos(tmpo->theta)-
+                  FIRE_Y_SCALE*(j-FIRE_HEIGHT/2+(12*tS+j)%1.7)*Sin(tmpo->theta),
+                  tmpo->y+FIRE_Y_SCALE*(j-FIRE_HEIGHT/2+(19*tS+j)%1.7)
+            *Cos(tmpo->theta)+
+                  FIRE_X_SCALE*(i-FIRE_WIDTH /2+(13*tS+i)%1.7)*Sin(tmpo->theta));
+          }
+      if (Blink) {
+        dc->color=BLACK;
+        GrLine(dc,tmpo->x+5,tmpo->y,tmpo->x+5+10,tmpo->y);
+
+        if (tmpo->life_percent>0) {
+          if (tmpo->life_percent<33)
+            dc->color=RED;
+          else if (tmpo->life_percent<66)
+            dc->color=YELLOW;
+          else
+            dc->color=GREEN;
+          GrLine(dc,tmpo->x+5,tmpo->y,
+                tmpo->x+5+10*tmpo->life_percent/100,tmpo->y);
+        }
+
+        dc->color=BLACK;
+        GrLine(dc,tmpo->x+5,tmpo->y+2,tmpo->x+5+10,tmpo->y+2);
+        d=tmpo->fuel*100/tmpo->max_fuel;
+        if (d>0) {
+          if (d<33)
+            dc->color=RED;
+          else if (d<66)
+            dc->color=YELLOW;
+          else
+            dc->color=GREEN;
+          GrLine(dc,tmpo->x+5,tmpo->y+2,tmpo->x+5+10*d/100,tmpo->y+2);
+        }
+      }
+    }
+    tmpo=tmpo->next;
+  }
+
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->flags&OF_ACTIVE && !(tmpo->flags&OF_SHIP))
+      Sprite3ZB(dc,tmpo->x,tmpo->y,0,
+            imgs[tmpo->player][tmpo->type],tmpo->theta+pi/2);
+    if (tmpo->flags&OF_SHOOTING) {
+      dc->color=LTRED;
+      GrLine(dc,tmpo->x,tmpo->y,tmpo->target_x,tmpo->target_y,3);
+    }
+    tmpo=tmpo->next;
+  }
+
+  dc->flags|=DCF_TRANSFORMATION;
+  if (cur_time<launch_t) {
+    dc->color=LTGREEN;
+    GrArrow3(dc,launch_unit_x1,launch_unit_y1,0,
+          launch_unit_x2,launch_unit_y2,0);
+  }
+  if (cur_time<return_t) {
+    dc->color=LTRED;
+    GrArrow3(dc,return_unit_x1,return_unit_y1,0,
+          return_unit_x2,return_unit_y2,0);
+  }
+  if (cur_time<set_theta_t) {
+    dc->color=YELLOW;
+    GrArrow3(dc,set_theta_unit_x1,set_theta_unit_y1,0,
+          set_theta_unit_x2,set_theta_unit_y2,0);
+  }
+
+  dc->color=YELLOW;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y,
+        "Game Speed: %5.2f",game_speed);
+  dc->color=LTCYAN;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y+FONT_HEIGHT,
+        "Player 1: %d",num_alive[0]);
+  dc->color=LTPURPLE;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y+2*FONT_HEIGHT,
+        "Player 2: %d",num_alive[1]);
+
+  if ((!num_alive[0]||!num_alive[1]) && Blink) {
+    if (!num_alive[1]) {
+      dc->color=LTGREEN;
+      GrPrint(dc,task->pix_width>>1 -(FONT_WIDTH*14)/2-task->scroll_x,
+            task->pix_height>>1-FONT_HEIGHT/2-task->scroll_y,"Game Completed");
+    } else {
+      dc->color=LTRED;
+      GrPrint(dc,task->pix_width>>1 -(FONT_WIDTH*9)/2-task->scroll_x,
+            task->pix_height>>1-FONT_HEIGHT/2-task->scroll_y,"Game Over");
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,fighter,ship,player,squadron,
+        w=Fs->pix_width,h=Fs->pix_height;
+  Squadron *tmps;
+  Obj *tmpo,*tmpo1;
+  QueInit(&obj_head);
+  QueInit(&torpedo_head);
+
+  next_noise=tS;
+  Fs->scroll_x=0;
+  Fs->scroll_y=0;
+  game_speed=1.0;
+  launch_t=return_t=set_theta_t=0;
+  main_task=Fs;
+  num_squadrons=0;
+  for (player=0;player<PLAYERS_NUM;player++) {
+    num_alive[player]=0;
+    for (ship=0;ship<num_cruisers[player];ship++) {
+      tmpo1=CAlloc(sizeof(Obj));
+      num_alive[player]++;
+      tmpo1->type=OT_CRUISER;   tmpo1->player=player;
+      tmpo1->squadron=-1;       tmpo1->member_num=ship;
+      tmpo1->flags=OF_ACTIVE|OF_SHIP;
+      tmpo1->x=0.8*w*(Rand-0.5)+w>>1; tmpo1->y=0.8*h*(Rand-0.5)+h>>1;
+      tmpo1->host=NULL;
+      tmpo1->speed=35.0;        tmpo1->turn_rate=2.5;
+      tmpo1->theta=2*pi*(Rand-0.5);     tmpo1->dtheta=0;
+      tmpo1->life_percent=100.0;
+      tmpo1->fuel=tmpo1->max_fuel=100000;
+      tmpo1->fuel_burn_rate=100.0;
+      tmpo1->air_guns =5000;    tmpo1->air_guns_range =30.0;
+      tmpo1->ship_guns=10000;   tmpo1->ship_guns_range=30.0;
+      tmpo1->torpedos =tmpo1->max_torpedos=0;
+      tmpo1->torpedos_range =0.0;
+      tmpo1->next_action_time=0;
+      QueIns(tmpo1,obj_head.last);
+    }
+
+    for (ship=0;ship<num_carriers[player];ship++) {
+      tmpo1=CAlloc(sizeof(Obj));
+      num_alive[player]++;
+      tmpo1->type=OT_CARRIER;   tmpo1->player=player;
+      tmpo1->squadron=-1;       tmpo1->member_num=ship;
+      tmpo1->flags=OF_ACTIVE|OF_SHIP;
+      tmpo1->x=0.8*w*(Rand-0.5)+w>>1; tmpo1->y=0.8*h*(Rand-0.5)+h>>1;
+      tmpo1->host=NULL;
+      tmpo1->speed=28.0;        tmpo1->turn_rate=1.0;
+      tmpo1->theta=2*pi*(Rand-0.5);     tmpo1->dtheta=0;
+      tmpo1->life_percent=100.0;
+      tmpo1->fuel=tmpo1->max_fuel=750000;
+      tmpo1->fuel_burn_rate=500.0;
+      tmpo1->air_guns =5000;    tmpo1->air_guns_range =20.0;
+      tmpo1->ship_guns=2000;    tmpo1->ship_guns_range=30.0;
+      tmpo1->torpedos =tmpo1->max_torpedos=0;
+      tmpo1->torpedos_range =0.0;
+      tmpo1->next_action_time=0;
+      QueIns(tmpo1,obj_head.last);
+
+      for (squadron=0;squadron<num_squadrons_per_carrier[player];
+            squadron++,num_squadrons++) {
+        for (fighter=0;fighter<num_planes_per_squadron[player];fighter++) {
+          tmpo=CAlloc(sizeof(Obj));
+          num_alive[player]++;
+          tmpo->type=OT_FIGHTER;         tmpo->player=player;
+          tmpo->squadron=num_squadrons; tmpo->member_num=fighter;
+          tmpo->flags=0;
+          tmpo->host=tmpo1;
+          tmpo->speed=300.0;            tmpo->turn_rate=25.0;
+          tmpo->life_percent=100.0;
+          tmpo->fuel=tmpo->max_fuel=1000;
+          tmpo->fuel_burn_rate=1.0;
+          tmpo->air_guns =35000;        tmpo->air_guns_range =8.0;
+          tmpo->ship_guns=0;            tmpo->ship_guns_range=0.0;
+          tmpo->torpedos =tmpo->max_torpedos=1;
+          tmpo->torpedos_range =20.0;
+          QueIns(tmpo,obj_head.last);
+        }
+      }
+    }
+  }
+  squadrons=CAlloc(num_squadrons*sizeof(Squadron));
+  for (i=0,tmps=squadrons;i<num_squadrons;i++,tmps++) {
+    tmps->next_in_squadron=tmps->last_in_squadron=tmps;
+    tmps->squadron=i;
+  }
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      tmps->host  =tmpo->host;
+      tmps->player=tmpo->player;
+      tmps->total_mask=1<<num_planes_per_squadron[tmpo->player]-1;
+      SquadronIns(tmpo,tmps->last_in_squadron);
+    }
+    tmpo=tmpo->next;
+  }
+}
+
+U0 CleanUp()
+{
+  QueDel(&obj_head,TRUE);
+  QueDel(&torpedo_head,TRUE);
+  Free(squadrons);
+}
+
+Obj *ObjLaunch(I64 player,I64 squadron=-1,
+        Obj *host=NULL,F64 x=F64_MAX,F64 y=F64_MAX,F64 theta=F64_MAX)
+{
+  Obj *tmpo;
+  F64 cur_time=tS;
+  if (!host)
+    host=ObjFind(x,y,,,1<<OT_CARRIER,1<<player);
+  if (host && cur_time>host->next_action_time) {
+    if (theta==F64_MAX)
+      theta=Arg(x-host->x,y-host->y);
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->host==host && (squadron<0||tmpo->squadron==squadron) &&
+            !(tmpo->flags&OF_ACTIVE) &&
+            (tmpo->squadron<0||squadrons[tmpo->squadron].action==SA_PARKED||
+            squadrons[tmpo->squadron].action==SA_LAUNCHING)) {
+        if (tmpo->fuel<=0.0)
+//When low on fuel, not zero, gets launched and captured.
+          LBts(&squadrons[tmpo->squadron].dead_mask,tmpo->member_num);
+        else {
+          tmpo->flags=tmpo->flags&~OF_RETURNING|OF_ACTIVE;
+          tmpo->theta=host->theta;
+          if (x==F64_MAX || y==F64_MAX || Sqr(x-host->x)+Sqr(y-host->y)>3*3)
+            tmpo->dtheta=Wrap(theta-tmpo->theta,-pi);
+          else
+            tmpo->dtheta=0;
+          tmpo->x=host->x;
+          tmpo->y=host->y;
+          host->next_action_time=cur_time+0.25/game_speed;
+          return tmpo;
+        }
+      }
+      tmpo=tmpo->next;
+    }
+  }
+  return NULL;
+}
+
+Squadron *SquadronLaunch(I64 player,F64 x=F64_MAX,F64 y=F64_MAX)
+{
+  Squadron *tmps;
+  Obj *tmpo;
+  if (tmpo=ObjLaunch(player,,,x,y)) {
+    if (player==0) {
+      launch_unit_x1=tmpo->x;
+      launch_unit_y1=tmpo->y;
+      launch_unit_x2=ms.pos.x-main_task->pix_left-main_task->scroll_x;
+      launch_unit_y2=ms.pos.y-main_task->pix_top -main_task->scroll_y;
+      launch_t=tS+0.5;
+    }
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      if (tmps->action==SA_PARKED) {
+        tmps->action=SA_LAUNCHING;
+        tmps->theta=tmpo->theta+tmpo->dtheta;
+      }
+      return tmps;
+    }
+  }
+  return NULL;
+}
+
+Obj *ObjReturn(I64 player,F64 x,F64 y)
+{
+  Obj *tmpo;
+  if (tmpo=ObjFind(x,y,OF_ACTIVE,OF_ACTIVE,1<<OT_FIGHTER,1<<player))
+    tmpo->flags|=OF_RETURNING;
+  return tmpo;
+}
+
+Squadron *SquadronReturn(I64 player,F64 x,F64 y)
+{
+  Squadron *tmps;
+  Obj *tmpo;
+  if (tmpo=ObjReturn(player,x,y)) {
+    if (player==0) {
+      return_unit_x1=tmpo->x;
+      return_unit_y1=tmpo->y;
+      if (tmpo->host) {
+        return_unit_x2=tmpo->host->x;
+        return_unit_y2=tmpo->host->y;
+        return_t=tS+0.5;
+      }
+    }
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      if (tmps->action==SA_FLYING)
+        tmps->action=SA_RETURNING;
+      return tmps;
+    }
+  }
+  return NULL;
+}
+
+Obj *ObjSettheta(I64 player,F64 x=F64_MAX,F64 y=F64_MAX,F64 theta=F64_MAX)
+{
+  Obj *tmpo;
+  if ((tmpo=ObjFind(x,y,,,,1<<player)) && tmpo->flags&OF_ACTIVE &&
+        !(tmpo->flags&OF_RETURNING)) {
+    if (theta==F64_MAX)
+      theta=Arg(x-tmpo->x,y-tmpo->y);
+    tmpo->dtheta+=Wrap(theta-(tmpo->theta+tmpo->dtheta),-pi);
+    return tmpo;
+  }
+  return NULL;
+}
+
+Squadron *SquadronSettheta(I64 player,F64 x=F64_MAX,F64 y=F64_MAX,F64 theta=F64_MAX)
+{
+  Squadron *tmps;
+  Obj *tmpo;
+  if (tmpo=ObjSettheta(player,x,y,theta)) {
+    if (player==0) {
+      set_theta_unit_x1=tmpo->x;
+      set_theta_unit_y1=tmpo->y;
+      set_theta_unit_x2=ms.pos.x-main_task->pix_left-main_task->scroll_x;
+      set_theta_unit_y2=ms.pos.y-main_task->pix_top -main_task->scroll_y;
+      set_theta_t=tS+0.5;
+    }
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      if (tmps->action==SA_FLYING) {
+        tmps->action=SA_SET_theta;
+        tmps->theta=tmpo->theta+tmpo->dtheta;
+      }
+      return tmps;
+    }
+  }
+  return NULL;
+}
+
+U0 SquadronActions()
+{
+  I64 i,completed_mask;
+  Obj *tmpo;
+  Squadron *tmps;
+  for (i=0,tmps=squadrons;i<num_squadrons;i++,tmps++) {
+    completed_mask=0;
+    switch (tmps->action) {
+      case SA_LAUNCHING:
+        ObjLaunch(tmps->player,i,tmps->host,,,tmps->theta);
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          LBEqu(&completed_mask,tmpo->member_num,tmpo->flags&OF_ACTIVE);
+          tmpo=tmpo->next_in_squadron;
+        }
+        if (completed_mask|tmps->dead_mask==tmps->total_mask)
+          tmps->action=SA_FLYING;
+        break;
+      case SA_FLYING:
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          LBEqu(&completed_mask,tmpo->member_num,!(tmpo->flags&OF_ACTIVE));
+          tmpo=tmpo->next_in_squadron;
+        }
+        if (completed_mask|tmps->dead_mask==tmps->total_mask)
+          tmps->action=SA_PARKED;
+        break;
+      case SA_SET_theta:
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          tmpo->dtheta+=Wrap(tmps->theta-(tmpo->theta+tmpo->dtheta),-pi);
+          tmpo=tmpo->next_in_squadron;
+        }
+        tmps->action=SA_FLYING;
+        break;
+      case SA_RETURNING:
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          tmpo->flags|=OF_RETURNING;
+          LBEqu(&completed_mask,tmpo->member_num,!(tmpo->flags&OF_ACTIVE));
+          tmpo=tmpo->next_in_squadron;
+        }
+        if (completed_mask|tmps->dead_mask==tmps->total_mask)
+          tmps->action=SA_PARKED;
+        break;
+    }
+    if (tmps->dead_mask==tmps->total_mask)
+      tmps->action=SA_DEAD;
+  }
+}
+
+U0 AI(I64 player,F64 period)
+{
+  Obj *tmpo;
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->player==player) {
+      if (tmpo->type==OT_CARRIER && Rand<5*period)
+        SquadronLaunch(player,tmpo->x,tmpo->y);
+      if (tmpo->flags&OF_ACTIVE && !(tmpo->flags&OF_RETURNING) &&
+            Rand<10.0*period)
+        SquadronSettheta(player,tmpo->x,tmpo->y,tmpo->theta+pi/2*(Rand-0.5));
+    }
+    tmpo=tmpo->next;
+  }
+}
+
+U0 ShipDamage(Obj *tmpo,F64 d)
+{
+  I64 i,x=Rand*FIRE_WIDTH,y=Rand*FIRE_HEIGHT;
+  tmpo->life_percent-=d;
+  while (d>0) {
+    if (!Bts(tmpo->fire,y*FIRE_WIDTH+x))
+      d-=500.0/(FIRE_WIDTH*FIRE_HEIGHT);
+    else
+      d-=25.0/(FIRE_WIDTH*FIRE_HEIGHT);
+    i=RandI16&7;
+    x+=gr_x_offsets[i];
+    y+=gr_y_offsets[i];
+    while (x>=FIRE_WIDTH)
+      x-=FIRE_WIDTH;
+    while (x<0)
+      x+=FIRE_WIDTH;
+    while (y>=FIRE_HEIGHT)
+      y-=FIRE_HEIGHT;
+    while (y<0)
+      y+=FIRE_HEIGHT;
+  }
+}
+
+U0 ShipFix(Obj *tmpo,F64 d)
+{
+  tmpo->life_percent+=d;
+  if (tmpo->life_percent>=100.0) {
+    tmpo->life_percent=100.0;
+    MemSet(tmpo->fire,0,sizeof(Obj.fire));
+    return;
+  }
+  while (d>0)
+    if (Btr(tmpo->fire,FIRE_WIDTH*FIRE_HEIGHT*Rand))
+      d-=400.0/(FIRE_WIDTH*FIRE_HEIGHT);
+    else
+      d-=20.0/(FIRE_WIDTH*FIRE_HEIGHT);
+}
+
+U0 Combat(F64 period)
+{
+  F64 d;
+  Obj *tmpo,*tmpo1;
+  Torpedo *tmpt;
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    tmpo->flags&=~OF_SHOOTING;
+    if (tmpo->flags&OF_ACTIVE &&
+          (tmpo1=ObjFind(tmpo->x,tmpo->y,OF_ACTIVE,OF_ACTIVE,,
+          1<<(tmpo->player^1),&d))) {
+      tmpo->target_x=tmpo1->x;
+      tmpo->target_y=tmpo1->y;
+      if (tmpo1->flags&OF_SHIP) {
+        if (tmpo->torpedos && d<tmpo->torpedos_range && Rand<125*period) {
+          tmpo->torpedos--;
+          tmpt=CAlloc(sizeof(Torpedo));
+          tmpt->x=tmpo->x;
+          tmpt->y=tmpo->y;
+          tmpt->speed=100;
+          d/=tmpt->speed*(GAME_SPEED_SCALE*game_speed);
+          tmpo1->death_time=tmpt->timeout=tS+d;
+          tmpt->target=tmpo1;
+          tmpt->theta=Arg(tmpo1->x-tmpo->x,tmpo1->y-tmpo->y);
+          QueIns(tmpt,torpedo_head.last);
+          Sweep(2000,86,53);
+        } else if (tmpo->ship_guns>0 && d<tmpo->ship_guns_range) {
+          tmpo->flags|=OF_SHOOTING;
+          if (Rand<125.0*period) {
+            ShipDamage(tmpo1,tmpo->ship_guns*Rand*period);
+            if (Rand<10.0*period)
+              tmpo1->fuel*=0.75*Rand+0.25;
+          }
+          if (tS>next_noise) {
+            Noise(100,29,46);
+            next_noise=tS+0.1;
+          }
+        }
+      } else {
+        if (tmpo->air_guns>0 && d<tmpo->air_guns_range) {
+          tmpo->flags|=OF_SHOOTING;
+          if (Rand<125.0*period) {
+            tmpo1->life_percent-=tmpo->air_guns*Rand*period;
+            if (Rand<10.0*period)
+              tmpo1->fuel*=0.75*Rand+0.25;
+          }
+          if (tS>next_noise) {
+            Noise(25,62,86);
+            next_noise=tS+0.025;
+          }
+        }
+      }
+    }
+    tmpo=tmpo->next;
+  }
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    tmpo1=tmpo->next;
+    if (tmpo->type==OT_FIGHTER &&
+          (tmpo->life_percent<=0.0 || tmpo->flags&OF_ACTIVE &&
+          tmpo->fuel<=0.0 || tmpo->host &&
+          !(tmpo->flags&OF_ACTIVE) && tmpo->host->life_percent<=0.0))
+      ObjDel(tmpo);
+    tmpo=tmpo1;
+  }
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    tmpo1=tmpo->next;
+    if (tmpo->life_percent<=0.0)
+      ObjDel(tmpo);
+    tmpo=tmpo1;
+  }
+}
+
+#define ANIMATE_FREQ    50
+U0 AnimateTask(I64)
+{
+  Obj *tmpo;
+  Torpedo *tmpt,*tmpt1;
+  F64 d,period;
+
+  while (TRUE) {
+    period=GAME_SPEED_SCALE*game_speed/ANIMATE_FREQ;
+    SquadronActions;
+
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->flags&OF_ACTIVE && tmpo->fuel>0) {
+        if (tmpo->dtheta) {
+          d=tmpo->dtheta;
+          if (d> tmpo->turn_rate*period) d= tmpo->turn_rate*period;
+          if (d<-tmpo->turn_rate*period) d=-tmpo->turn_rate*period;
+          tmpo->theta +=d;
+          tmpo->dtheta-=d;
+        }
+        tmpo->x+=tmpo->speed*Cos(tmpo->theta)*period*tmpo->life_percent/100.0;
+        tmpo->y+=tmpo->speed*Sin(tmpo->theta)*period*tmpo->life_percent/100.0;
+        tmpo->fuel-=tmpo->speed*tmpo->fuel_burn_rate*period;
+      }
+      tmpo=tmpo->next;
+    }
+
+    tmpt=torpedo_head.next;
+    while (tmpt!=&torpedo_head) {
+      tmpt1=tmpt->next;
+      if (tS>tmpt->timeout) {
+        tmpo=tmpt->target;
+        if (Rand<0.333333) {
+          ShipDamage(tmpo,150*Rand*Rand);
+          if (Rand<0.333333)
+            tmpo->fuel*=0.75*Rand+0.25;
+        }
+        QueRem(tmpt);
+        Free(tmpt);
+      } else {
+        tmpt->x+=tmpt->speed*Cos(tmpt->theta)*period;
+        tmpt->y+=tmpt->speed*Sin(tmpt->theta)*period;
+      }
+      tmpt=tmpt1;
+    }
+
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->host && !(tmpo->flags&OF_ACTIVE)) {
+        tmpo->x=tmpo->host->x;
+        tmpo->y=tmpo->host->y;
+      }
+      tmpo=tmpo->next;
+    }
+
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->flags&OF_ACTIVE) {
+        if (tmpo->host) {
+          d=Sqrt(Sqr(tmpo->x-tmpo->host->x)+Sqr(tmpo->y-tmpo->host->y));
+          if (d<8 && tmpo->max_fuel-tmpo->fuel>30) {
+            tmpo->life_percent=100.0;
+            if (tmpo->host->fuel>0) {
+              d=tmpo->max_fuel-tmpo->fuel;
+              if (d>tmpo->host->fuel) d=tmpo->host->fuel;
+              tmpo->host->fuel-=d;
+              tmpo->fuel+=d;
+            }
+            tmpo->torpedos=tmpo->max_torpedos;
+            tmpo->x=tmpo->host->x;
+            tmpo->y=tmpo->host->y;
+            tmpo->flags&=~OF_ACTIVE;
+          } else if (d>tmpo->fuel-250)
+            tmpo->flags|=OF_RETURNING;
+          if (tmpo->flags&OF_RETURNING)
+            tmpo->dtheta+=Wrap(Arg(tmpo->host->x-tmpo->x,
+                  tmpo->host->y-tmpo->y)-(tmpo->theta+tmpo->dtheta),-pi);
+        } else if (tmpo->type==OT_CARRIER)
+          ShipFix(tmpo,2.5*period);
+      }
+      tmpo=tmpo->next;
+    }
+
+    AI(1,period);
+    Combat(period);
+    Sleep(1000/ANIMATE_FREQ);
+  }
+}
+
+U0 FlatTops()
+{
+  I64 arg1,arg2;
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLUE<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  PopUpOk("$GREEN${Left-Mouse}$FG$\t\tChange Course\n"
+        "$GREEN${Right-Mouse}$FG$\t\tLaunch Squadron\n"
+        "$GREEN${Right-Double-Mouse}$FG$\tReturn Squadron\n"
+        "$GREEN${Ctrl-Left Grab}$FG$\tScroll Scrn\n");
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Faster(,'+');"
+        "  Slower(,'-');"
+        "}"
+        );
+  Fs->win_inhibit|=WIF_SELF_MS_L|WIF_SELF_MS_R;
+  Init;
+  Fs->draw_it=&DrawIt;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  try {
+    while (TRUE)
+      switch (GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_UP|1<<MSG_MS_R_D_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto nv_done;
+            case '+':
+              game_speed*=1.5;
+              break;
+            case '-':
+              game_speed/=1.5;
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          SquadronSettheta(0,arg1,arg2);
+          break;
+        case MSG_MS_R_UP:
+          SquadronLaunch(0,arg1,arg2);
+          break;
+        case MSG_MS_R_D_UP:
+          SquadronReturn(0,arg1,arg2);
+          break;
+      }
+nv_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+FlatTops;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//Maybe use this in the future  <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Demo/Games/Halogen.HC.HTML b/public/Wb/Demo/Games/Halogen.HC.HTML new file mode 100755 index 0000000..d4ad81a --- /dev/null +++ b/public/Wb/Demo/Games/Halogen.HC.HTML @@ -0,0 +1,193 @@ + + + + + + + + + + + +
+#define ROAD_NUM        512
+#define ROAD_WIDTH_BY_2 200
+#define CAR_WIDTH_BY_2  100
+
+I64 road_x[ROAD_NUM],road_trend;
+F64 speed,distance;
+I64 road_ptr=0,car_x;
+F64 t_last;
+Bool crash;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 w=task->pix_width,h=task->pix_height;
+  I64 i,x,y,xx;
+  xx=w>>1-car_x+road_x[road_ptr&(ROAD_NUM-1)];
+
+  dc->color=LTGRAY;
+  for (i=0;i<ROAD_NUM;i++) {
+    x=w>>1-car_x+road_x[(i+road_ptr)&(ROAD_NUM-1)];
+    y=h-0.5*i;
+    if (y<(h+FONT_HEIGHT)>>1) break;
+    GrPlot(dc,x+ROAD_WIDTH_BY_2-0.4*i,y);
+    GrPlot(dc,x-ROAD_WIDTH_BY_2+0.4*i,y);
+  }
+  dc->color=WHITE;
+
+  x=w>>1-CAR_WIDTH_BY_2;
+  if (x<xx-ROAD_WIDTH_BY_2)
+    crash=TRUE;
+  GrLine(dc,x-10,h,x-40,h-100);
+  GrLine(dc,x+10,h,x+40,h-100);
+
+  x=w>>1+CAR_WIDTH_BY_2;
+  if (x>xx+ROAD_WIDTH_BY_2)
+    crash=TRUE;
+  GrLine(dc,x-10,h,x-40,h-100);
+  GrLine(dc,x+10,h,x+40,h-100);
+
+  dc->color=YELLOW;
+  if (crash)
+    GrPrint(dc,w>>1-FONT_WIDTH*4,(h-FONT_HEIGHT)>>1,"Game Over");
+}
+
+U0 UpdateRoad()
+{
+  F64 t0=tS;
+  distance+=speed*(t0-t_last);
+  t_last=t0;
+  while (distance>1.0) {
+    road_trend=ClampI64(road_trend+SignI64(RandU16%3-1),-5,5);
+    road_x[road_ptr&(ROAD_NUM-1)]=
+          road_x[(road_ptr-1)&(ROAD_NUM-1)]+=road_trend/3;
+    road_ptr++;
+    distance-=1.0;
+  }
+}
+
+U0 Init()
+{
+  I64 i,x=0;
+  DocClear;
+  "$BG,DKGRAY$%h*c",(TEXT_ROWS-1)/2,'\n';
+  speed=0;
+  distance=0;
+  road_trend=0;
+  road_ptr=0;
+  car_x=0;
+  for (i=0;i<ROAD_NUM;i++) {
+    road_x[i]=x;
+    road_trend=ClampI64(road_trend+SignI64(RandU16%3-1),-5,5);
+    x+=road_trend/3;
+  }
+  t_last=tS;
+  crash=FALSE;
+}
+
+U0 Halogen()
+{
+  I64 arg1,arg2,ch=0,sc=0;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+WHITE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Accelerate(,,SC_CURSOR_UP);"
+        "  Deccellerate(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Init;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          ch=arg1;sc=arg2;
+          switch (ch) {
+            case '\n':
+              Init;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto ha_done;
+          }
+          break;
+        case MSG_KEY_UP:
+          ch=arg1;sc=arg2;
+          if (!ch)
+            switch (sc.u8[0]) {
+              case SC_CURSOR_RIGHT:
+              case SC_CURSOR_LEFT:
+              case SC_CURSOR_UP:
+              case SC_CURSOR_DOWN:
+                sc=0;
+                break;
+            }
+          break;
+      }
+      switch (sc.u8[0]) {
+        case SC_CURSOR_RIGHT:
+          car_x++;
+          break;
+        case SC_CURSOR_LEFT:
+          car_x--;
+          break;
+        case SC_CURSOR_UP:
+          if (++speed>200) speed=200;
+          break;
+        case SC_CURSOR_DOWN:
+          if (--speed<0) speed=0;
+          break;
+      }
+      if (crash)
+        Snd;
+      else {
+        if (speed)
+          Snd(Freq2Ona(speed+10));
+        else
+          Snd;
+        UpdateRoad;
+      }
+      Sleep(10);
+    }
+ha_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  MenuPop;
+  DocClear;
+  SettingsPop;
+}
+
+Halogen;
+
+ diff --git a/public/Wb/Demo/Games/MassSpring.HC.HTML b/public/Wb/Demo/Games/MassSpring.HC.HTML new file mode 100755 index 0000000..e541a49 --- /dev/null +++ b/public/Wb/Demo/Games/MassSpring.HC.HTML @@ -0,0 +1,200 @@ + + + + + + + + + + + +
+class MyMass:CMass
+{
+  F64 radius;
+};
+
+class MySpring:CSpring
+{
+};
+
+CMathODE *ode=NULL;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  MyMass   *tmpm;
+  MySpring *tmps;
+
+  dc->color=RED;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    GrLine(dc,tmps->end1->x,tmps->end1->y,tmps->end2->x,tmps->end2->y);
+    tmps=tmps->next;
+  }
+
+  dc->color=BLACK;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+    tmpm=tmpm->next;
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{//The forces due to springs and drag are
+//automatically handled by the ode code.
+  //We can add new forces here.
+  F64 d,dd;
+  CD3 p;
+  MyMass *tmpm1,*tmpm2;
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      D3Sub(&p,&tmpm2->state->x,&tmpm1->state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=Sqr(tmpm1->radius+tmpm2->radius)) {
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr(Sqr(tmpm1->radius+tmpm2->radius)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&tmpm2->DstateDt->DxDt,&p);
+        D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+      }
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+}
+
+U0 PlaceMass(I64 x, I64 y)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass));
+  tmpm->mass=1.0;
+  tmpm->drag_profile_factor=100.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->radius=10*(Rand+0.25);
+  QueIns(tmpm,ode->last_mass);
+}
+
+U0 PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  tmps->const=10000;
+  tmps->rest_len=100;
+  QueIns(tmps,ode->last_spring);
+}
+
+U0 Init()
+{
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  QueRem(ode);
+  QueDel(&ode->next_mass,TRUE);
+  QueDel(&ode->next_spring,TRUE);
+  ODEDel(ode);
+}
+
+U0 MassSpringDemo()
+{
+  I64 msg_code,arg1,arg2;
+  MyMass *tmpm1=NULL,*tmpm2=NULL;
+
+  PopUpOk("Left-Click to place mas\n"
+        "Right-Click and drag to\n"
+        "connect with spring.\n\n"
+        "Springs are 100 pixs long.\n");
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+
+  Init;
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP|1<<MSG_KEY_DOWN);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+          PlaceMass(arg1,arg2);
+          break;
+        case MSG_MS_R_DOWN:
+          tmpm1=MassFind(ode,arg1,arg2);
+          tmpm2=NULL;
+          break;
+        case MSG_MS_R_UP:
+          if (tmpm1 && (tmpm2=MassFind(ode,arg1,arg2)) && tmpm1!=tmpm2)
+            PlaceSpring(tmpm1,tmpm2);
+          tmpm1=tmpm2=NULL;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto ms_done;
+          }
+          break;
+      }
+    }
+ms_done: //Don't goto out of try
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+MassSpringDemo;
+
+ diff --git a/public/Wb/Demo/Games/Maze.HC.HTML b/public/Wb/Demo/Games/Maze.HC.HTML new file mode 100755 index 0000000..36320b3 --- /dev/null +++ b/public/Wb/Demo/Games/Maze.HC.HTML @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+//See TextBase Layer.
+
+#define ATTR (BLACK<<12+WHITE<<8)
+
+U32 text[TEXT_ROWS][TEXT_COLS];
+
+U0 DrawIt(CTask *task,CDC *)
+{ //gr.text_base gets clear 30fps, so we must use our own permanent text array.
+  MemCpy(gr.text_base+TEXT_COLS,text,(TEXT_ROWS-1)*TEXT_COLS*sizeof(U32));
+
+  // You can copy it this way, if you like:
+  //  I64 i,j;
+  //  for (j=0;j<TEXT_ROWS;j++)
+  //    for (i=0;i<TEXT_COLS;i++)
+  //     TextChar(task,,i,j,text[j][i]);
+
+  TextPrint(task,0,0,ATTR>>8,"Draw a maze with left bttn.");
+  TextPrint(task,0,1,ATTR>>8,"Solve maze starting at right click.");
+}
+
+#define STK_SIZE 2048
+//We would put these as local vars
+//in SolveMaze() but the system stk size
+//is limited, so it's a bad habit.  The heap
+//is the normal TempleOS technique, but
+//it's a pain in this case.
+I64     stk_ptr,
+        stk_x  [STK_SIZE],
+        stk_y  [STK_SIZE],
+        stk_dir[STK_SIZE];
+
+//Four directions:
+//  0=Up,1=right,2=down,3=left
+I64     dir_x[4]={ 0,+1, 0,-1},  // Could use gr_x_offsets2,gr_y_offsets2
+        dir_y[4]={+1, 0,-1, 0};
+
+U0 SolveMaze(I64 x,I64 y)
+{
+  I64 dir=0;
+  stk_ptr=0;
+  stk_x[stk_ptr]=x;
+  stk_y[stk_ptr]=y;
+  stk_dir[stk_ptr++]=dir;
+  while (TRUE) {
+    if (!(0<=x<MinI64(Fs->win_width,TEXT_COLS)) ||
+          !(0<=y<MinI64(Fs->win_height,TEXT_ROWS)) ) {
+      Beep;Beep;
+      break;
+    }
+    if (!text[y][x].u8[0])
+      text[y][x]='.'+ATTR;
+    x+=dir_x[dir];
+    y+=dir_y[dir];
+//u8.[0] is the ASCII
+    if (text[y][x].u8[0]) {
+      x-=dir_x[dir];
+      y-=dir_y[dir];
+      if (++dir==4) {
+        if (--stk_ptr<0) return;
+        x=stk_x[stk_ptr];
+        y=stk_y[stk_ptr];
+        dir=stk_dir[stk_ptr];
+      }
+    } else {
+      dir=0;
+      stk_x[stk_ptr]=x;
+      stk_y[stk_ptr]=y;
+      stk_dir[stk_ptr++]=dir;
+      if (stk_ptr==STK_SIZE) return;
+      Sleep(100);
+      if (ScanChar)
+        throw;
+    }
+  }
+}
+
+U0 Maze()
+{
+  I64 ch,x,y;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  try
+    do {
+      MemSet(text,0,sizeof(text));
+      while (!(ch=ScanChar)) {
+        x=ms.pos_text.x-Fs->win_left-Fs->scroll_x/FONT_WIDTH;
+        y=ms.pos_text.y-Fs->win_top-Fs->scroll_y/FONT_HEIGHT;
+        if (ms.lb&&!winmgr.grab_scroll)
+          text[y][x]=CH_SPACE+ATTRF_INVERT+ATTR;
+        if (ms.rb&&!winmgr.grab_scroll) {
+          text[y][x]='*'+ATTR;
+          SolveMaze(x,y);
+          ch=GetChar;
+          break;
+        }
+        Refresh;
+      }
+    } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  catch
+    PutExcept;
+  SettingsPop;
+}
+
+Maze;
+
+ diff --git a/public/Wb/Demo/Games/RainDrops.HC.HTML b/public/Wb/Demo/Games/RainDrops.HC.HTML new file mode 100755 index 0000000..5af7302 --- /dev/null +++ b/public/Wb/Demo/Games/RainDrops.HC.HTML @@ -0,0 +1,220 @@ + + + + + + + + + + + +
+I64 sc_1,sc_2;
+
+#define DROPS_NUM       0x2000
+
+class Drop
+{
+  I32 x,y;
+} drops[DROPS_NUM];
+
+CDC *cur_dc;
+
+U0 DrawFrame(CTask *task,CDC *dc)
+{
+  I64 w=task->pix_width,h=task->pix_height,
+        cx=w>>1,cy=h>>1;
+
+  dc->color=LTRED;
+  GrLine(dc,cx-20,cy-50,cx,cy-150);
+  GrLine(dc,cx+20,cy-50,cx,cy-150);
+
+  dc->color=LTRED;
+  GrLine(dc,cx-100,cy-100,cx,cy);
+  GrLine(dc,cx+100,cy-100,cx,cy);
+  if (Bt(kbd.down_bitmap,sc_1)) {
+    dc->color=WHITE;
+    GrRect(dc,cx-2,cy-2,5,5);
+  }
+  dc->color=BLACK;
+  GrPrint(dc,cx+10,cy,"Press '1'");
+
+  dc->color=LTRED;
+  GrRect(dc,cx-20,cy+60,41,21);
+
+  dc->color=LTRED;
+  GrLine(dc,cx-200,cy,cx,cy+100);
+  GrLine(dc,cx+200,cy,cx,cy+100);
+  if (Bt(kbd.down_bitmap,sc_2)) {
+    dc->color=WHITE;
+    GrRect(dc,cx-2,cy+100-2,5,5);
+  }
+  dc->color=BLACK;
+  GrPrint(dc,cx+10,cy+100,"Press '2'");
+
+  dc->color=LTRED;
+  GrLine(dc,cx+400,cy+100,cx-250,cy+200);
+}
+
+U0 DrawDrops(CTask *,CDC *dc)
+{
+  I64 i;
+  dc->color=BLUE;
+  for (i=0;i<DROPS_NUM;i++)
+    if (drops[i].y>=0 && GrPeek(dc,drops[i].x,drops[i].y)==WHITE)
+      GrPlot(dc,drops[i].x,drops[i].y);
+}
+
+U0 UpdateCurBase(CTask *task,CDC *dc)
+{
+  cur_dc->color=ROP_EQU;
+  dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(cur_dc,-task->pix_left-task->scroll_x,
+        -task->pix_top-task->scroll_y,dc);
+  dc->flags&=~DCF_NO_TRANSPARENTS;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  DrawFrame(task,dc);
+  DrawDrops(task,dc);
+  UpdateCurBase(task,dc);
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i,j,cur_drop=0,c1,c2,x0,y0,x1,y1,w,h;
+  while (TRUE) {
+    w=Fs->parent_task->pix_width;
+    h=Fs->parent_task->pix_height;
+
+    for (i=0;i<2;i++) {
+      j=0;
+      do {
+        if (++cur_drop>=DROPS_NUM)
+          cur_drop=0;
+        if (drops[cur_drop].y<0)
+          break;
+        j++;
+      } while (j<=DROPS_NUM);
+
+      drops[cur_drop].x=RandU32%w;
+      drops[cur_drop].y=0;
+    }
+
+    for (i=0;i<DROPS_NUM;i++) {
+      if (drops[i].y>=0) {
+        if (drops[i].y>=h-1)
+          drops[i].y=-I32_MAX;
+        else {
+          x0=x1=drops[i].x;
+          y0=y1=drops[i].y;
+          if (GrPeek(cur_dc,x0,y0+1)==WHITE)
+            y1++;
+          else {
+            c1=GrPeek(cur_dc,x0+1,y0);
+            c2=GrPeek(cur_dc,x0-1,y0);
+            if (c1==WHITE && c2!=WHITE)
+              x1++;
+            else if (c2==WHITE && c1!=WHITE)
+              x1--;
+            else if (c1==WHITE && c2==WHITE) {
+              c1=GrPeek(cur_dc,x0+1,y0+1);
+              c2=GrPeek(cur_dc,x0-1,y0+1);
+              if (c1==WHITE && c2!=WHITE)
+                x1++;
+              else if (c2==WHITE && c1!=WHITE)
+                x1--;
+              else if (RandI16>=0)
+                x1++;
+              else
+                x1--;
+            }
+            if (GrPeek(cur_dc,x1,y1+1)==WHITE)
+              y1++;
+          }
+          if (GrPeek(cur_dc,x0,y0)==BLUE) {
+            cur_dc->color=WHITE;
+            GrPlot(cur_dc,x0,y0);
+          }
+          cur_dc->color=BLUE;
+          GrPlot(cur_dc,x1,y1);
+          drops[i].x=x1;
+          drops[i].y=y1;
+        }
+      }
+    }
+    Sleep(10);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  MemSet(drops,0,sizeof(drops));
+  for (i=0;i<DROPS_NUM;i++)
+    drops[i].y=-I32_MAX;
+}
+
+U0 RainDrops()
+{
+  I64 ch,sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  OpenUpper(,'1');"
+        "  OpenLower(,'2');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  cur_dc=DCNew(GR_WIDTH,GR_HEIGHT);
+  sc_1=Char2ScanCode('1');
+  sc_2=Char2ScanCode('2');
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    do
+      switch (ch=GetKey(&sc)) {
+        case '\n':
+          Init;
+          break;
+      }
+    while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  DCDel(cur_dc);
+}
+
+RainDrops;
+
+ diff --git a/public/Wb/Demo/Games/RawHide.HC.HTML b/public/Wb/Demo/Games/RawHide.HC.HTML new file mode 100755 index 0000000..f906b0d --- /dev/null +++ b/public/Wb/Demo/Games/RawHide.HC.HTML @@ -0,0 +1,622 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+RegDft("TempleOS/RawHide","F64 best_score=9999;\n");
+RegExe("TempleOS/RawHide");
+
+F64 t0,tf;
+I64 outside_cnt;
+
+#define MAP_WIDTH       1000
+#define MAP_HEIGHT      1000
+#define FENCE_WIDTH     320
+#define FENCE_HEIGHT    200
+#define MAP_BORDER      3
+CDC *map_dc;
+
+#define GATE_WIDTH      22
+#define GATE_HEIGHT     7
+F64 gate_theta,gate_t;
+
+
+
+<1>/* Graphics Not Rendered in HTML */  <2>/* Graphics Not Rendered in HTML */  <3>/* Graphics Not Rendered in HTML */
+
+
+<4>/* Graphics Not Rendered in HTML */  <5>/* Graphics Not Rendered in HTML */  <6>/* Graphics Not Rendered in HTML */
+
+
+<7>/* Graphics Not Rendered in HTML */  <8>/* Graphics Not Rendered in HTML */
+
+
+<9>/* Graphics Not Rendered in HTML */
+        <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+#define ANIMAL_WIDTH    20
+#define ANIMAL_HEIGHT   16
+
+U8 *cow_imgs[4]  ={<1>,<2>,<3>,<2>},
+   *bull_imgs[4] ={<4>,<5>,<6>,<5>},
+   *horse_imgs[4]={<7>,<8>,<7>,<8>};
+
+#define ANIMALS_NUM     100
+
+class Animal
+{
+  I64   num,x,y,dx,dy;
+  U8    **imgs;
+  U32   buddy;
+  U8    type,frame0;
+  Bool  dead,pad;
+} *a;
+
+//************************************
+#define WATERFALL_HEIGHT        (MAP_HEIGHT/20)
+#define WATERFALL_DROPS         512
+#define WATERFALL_ACCELERATION  10
+I32 *r_x,*r_width,*wfd_x;
+F64 *wfd_t0,waterfall_tf;
+I64 waterfall_x,waterfall_y,waterfall_width;
+
+U0 RiverNew()
+{
+  r_x=MAlloc(MAP_HEIGHT*sizeof(I32));
+  r_width=MAlloc(MAP_HEIGHT*sizeof(I32));
+  wfd_x=MAlloc(WATERFALL_DROPS*sizeof(I32));
+  wfd_t0=MAlloc(WATERFALL_DROPS*sizeof(F64));
+  waterfall_tf=Sqrt(2*WATERFALL_HEIGHT/WATERFALL_ACCELERATION);
+}
+
+U0 RiverMake()
+{
+  I64 i,x=2*MAP_WIDTH<<32/3,y,dx=0,w=15<<32;
+  waterfall_y=(MAP_HEIGHT-WATERFALL_HEIGHT)/2*Rand+
+    (MAP_HEIGHT-WATERFALL_HEIGHT)/4;
+  for (y=MAP_BORDER;y<MAP_HEIGHT-MAP_BORDER;y++) {
+    r_x[y]=x.i32[1]; r_width[y]=w.i32[1];
+    if (waterfall_y-5<y<waterfall_y+WATERFALL_HEIGHT+5) {
+      waterfall_width=r_width[y];
+      waterfall_x=r_x[y]-waterfall_width/2;
+    } else {
+      dx=ClampI64(dx+RandI32/64,-I32_MAX,I32_MAX)-I32_MAX/256;
+      w=ClampI64(w+RandI32*2,10*U32_MAX,150*U32_MAX);
+      x+=dx;
+    }
+  }
+  for (i=0;i<WATERFALL_DROPS;i++) {
+    wfd_x[i]=Rand*waterfall_width+waterfall_x;
+    wfd_t0[i]=tS-Rand*waterfall_tf;
+  }
+
+  //Plot waterfall cliff
+  Sprite3B(map_dc,waterfall_x,waterfall_y,0,<10>);
+
+  //Plot sand bar
+  x=0;
+  for (y=MAP_BORDER;y<MAP_HEIGHT-MAP_BORDER;y++) {
+    if (!(waterfall_y-9<y<waterfall_y+WATERFALL_HEIGHT+9)) {
+      map_dc->color=YELLOW;
+      map_dc->thick=r_width[y]+10;
+      GrPlot3(map_dc,r_x[y]+x.i32[1],y,0);
+    }
+    x=ClampI64(x+RandI32,-6*U32_MAX,6*U32_MAX);
+  }
+
+  //Plot water
+  for (y=MAP_BORDER;y<MAP_HEIGHT-MAP_BORDER;y++) {
+    map_dc->color=BLUE;
+    map_dc->thick=r_width[y];
+    GrPlot3(map_dc,r_x[y],y,0);
+  }
+}
+
+U0 RiverDel()
+{
+  Free(r_x);
+  Free(r_width);
+  Free(wfd_x);
+  Free(wfd_t0);
+}
+
+//************************************
+class RiverDrop
+{
+  RiverDrop *next,*last;
+  I64 y,dx,dy;
+} rd_head;
+Bool rd_lock;
+
+U0 RiverDropsDel()
+{
+  while (LBts(&rd_lock,0))
+    Yield;
+  QueDel(&rd_head,TRUE);
+  QueInit(&rd_head);
+  LBtr(&rd_lock,0);
+}
+
+U0 RiverDropsNext(CTask *mem_task)
+{
+  RiverDrop *tmpr,*tmpr1;
+  while (LBts(&rd_lock,0))
+    Yield;
+  tmpr=rd_head.next;
+  while (tmpr!=&rd_head) {
+    tmpr1=tmpr->next;
+    if (++tmpr->y>=MAP_HEIGHT-MAP_BORDER) {
+      QueRem(tmpr);
+      Free(tmpr);
+    } else {
+      do {
+        if (RandU16&1 && GrPeek(map_dc,r_x[tmpr->y]+tmpr->dx,
+              tmpr->y+tmpr->dy)==BLUE)
+          break;
+        tmpr->dx=ClampI64(tmpr->dx+RandU16%3-1,-r_width[tmpr->y]/2,
+              r_width[tmpr->y]/2);
+        tmpr->dy=ClampI64(tmpr->dy+RandU16%3-1,-r_width[tmpr->y]/2,
+              r_width[tmpr->y]/2);
+      } while (GrPeek(map_dc,r_x[tmpr->y]+tmpr->dx,
+            tmpr->y+tmpr->dy)!=BLUE &&
+            GrPeek(map_dc,r_x[tmpr->y],tmpr->y)==BLUE);//Might be reiniting
+    }
+    tmpr=tmpr1;
+  }
+  tmpr=MAlloc(sizeof(RiverDrop),mem_task);
+  tmpr->y=MAP_BORDER;
+  tmpr->dx=0;
+  tmpr->dy=0;
+  QueIns(tmpr,rd_head.last);
+  LBtr(&rd_lock,0);
+}
+
+U0 RiverDropsDraw(CDC *dc,I64 cx,I64 cy)
+{
+  I64 i;
+  F64 t=tS;
+  RiverDrop *tmpr;
+  while (LBts(&rd_lock,0))
+    Yield;
+  tmpr=rd_head.next;
+  dc->color=LTBLUE;
+  while (tmpr!=&rd_head) {
+    GrPlot(dc,r_x[tmpr->y]+tmpr->dx-cx,tmpr->y+tmpr->dy-cy);
+    tmpr=tmpr->next;
+  }
+  LBtr(&rd_lock,0);
+
+  dc->color=WHITE;
+  for (i=0;i<WATERFALL_DROPS;i++)
+    GrPlot(dc,wfd_x[i]-cx,waterfall_y+0.5*WATERFALL_ACCELERATION*
+          Sqr(waterfall_tf*Saw(t-wfd_t0[i],waterfall_tf))-cy);
+}
+
+//************************************
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  static I64 last_pos_x=0;
+  static Bool left=TRUE;
+  F64 t;
+  I64 i,frame=4*tS,
+        cx=(MAP_WIDTH -task->pix_width)/2,
+        cy=(MAP_HEIGHT-task->pix_height)/2;
+  if (task->scroll_x+cx<0)
+    task->scroll_x=-cx;
+  if (task->scroll_x+cx>MAP_WIDTH-task->pix_width)
+    task->scroll_x=MAP_WIDTH-task->pix_width-cx;
+  if (task->scroll_y+cy<0)
+    task->scroll_y=-cy;
+  if (task->scroll_y+cy>MAP_HEIGHT-task->pix_height)
+    task->scroll_y=MAP_HEIGHT-task->pix_height-cy;
+
+  map_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,-cx,-cy,map_dc);
+
+  RiverDropsDraw(dc,cx,cy);
+
+  for (i=0;i<ANIMALS_NUM;i++)
+    if (!a[i].dead) {
+      if (a[i].dx<0) {
+        dc->flags|=DCF_JUST_MIRROR|DCF_SYMMETRY;
+        DCSymmetrySet(dc,a[i].x.i32[1]-cx,0,a[i].x.i32[1]-cx,1);
+      }
+      Sprite3(dc,a[i].x.i32[1]-cx,a[i].y.i32[1]-cy,0,
+            a[i].imgs[(frame+a[i].frame0)&3]);
+      dc->flags&=~(DCF_JUST_MIRROR|DCF_SYMMETRY);
+    }
+
+  if (ms.pos.x-last_pos_x>0)
+    left=FALSE;
+  else if (ms.pos.x-last_pos_x<0)
+    left=TRUE;
+  if (left) {
+    dc->flags|=DCF_JUST_MIRROR|DCF_SYMMETRY;
+    DCSymmetrySet(dc,ms.pos.x-task->pix_left-task->scroll_x,0,
+          ms.pos.x-task->pix_left-task->scroll_x,1);
+  }
+  Sprite3(dc,ms.pos.x-task->pix_left-task->scroll_x,
+             ms.pos.y-task->pix_top -task->scroll_y,0,horse_imgs[frame&3]);
+  dc->flags&=~(DCF_JUST_MIRROR|DCF_SYMMETRY);
+  last_pos_x=ms.pos.x;
+
+  if (tf) {
+    dc->color=RED;
+    t=tf-t0;
+    if (Blink)
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*14)>>1-task->scroll_x,
+            (task->pix_height-FONT_HEIGHT)>>1-task->scroll_y,
+            "Game Completed");
+  } else {
+    dc->color=BLACK;
+    t=tS-t0;
+  }
+  GrPrint(dc,-task->scroll_x,-task->scroll_y,
+        "Outside:%03d Time:%7.2fs Best:%7.2fs",
+        outside_cnt,t,best_score);
+}
+
+U0 BuddySel(I64 i)
+{
+  I64 b,best_b=i,score,best_score=I64_MAX;
+  for (b=0;b<ANIMALS_NUM;b++) {
+    if (b!=i && !a[b].dead) {
+      score=RandU32%(512*512)+
+            SqrI64(a[b].x.i32[1]-a[i].x.i32[1])+
+            SqrI64(a[b].y.i32[1]-a[i].y.i32[1]);
+      if (score<best_score) {
+        best_score=score;
+        best_b=b;
+      }
+    }
+  }
+  a[i].buddy=best_b;
+}
+
+
+U0 RedrawGate()
+{
+  F64 tt=tS-gate_t;
+  I64 x1=FENCE_WIDTH-63,y1=FENCE_HEIGHT-1,dx,dy;
+
+  if (tt<0.5)
+    gate_theta=Clamp(gate_theta+0.02,0,pi/2);
+  else if (tt>5.0)
+    gate_theta=Clamp(gate_theta-0.02,0,pi/2);
+
+  dx=GATE_WIDTH*Cos(gate_theta); dy=-0.8*GATE_WIDTH*Sin(gate_theta);
+
+  map_dc->color=LTGREEN;
+  GrRect(map_dc,x1,y1-0.8*GATE_WIDTH-GATE_HEIGHT,
+        46,0.8*GATE_WIDTH+GATE_HEIGHT+3);
+
+  map_dc->color=BLACK;
+
+  GrLine(map_dc,x1,y1,x1+dx,y1+dy);
+  GrLine(map_dc,x1,y1,x1,y1-GATE_HEIGHT);
+  GrLine(map_dc,x1+dx,y1+dy,x1+dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1,y1-GATE_HEIGHT,x1+dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1,y1,x1+dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1,y1-GATE_HEIGHT,x1+dx,y1+dy);
+
+  GrLine(map_dc,x1+45,y1,x1+45-dx,y1+dy);
+  GrLine(map_dc,x1+45,y1,x1+45,y1-GATE_HEIGHT);
+  GrLine(map_dc,x1+45-dx,y1+dy,x1+45-dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1+45,y1-GATE_HEIGHT,x1+45-dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1+45,y1,x1+45-dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1+45,y1-GATE_HEIGHT,x1+45-dx,y1+dy);
+}
+
+Bool CheckMap(I64 x,I64 y)
+{
+  I64 i,j,c;
+  if (SqrI64(x-(waterfall_x+waterfall_width/2))>>1+
+        SqrI64(y-(waterfall_y+WATERFALL_HEIGHT/2))<2500)
+    return FALSE;
+  for (j=-4;j<=2;j++)
+    for (i=-4;i<=4;i++) {
+      c=GrPeek(map_dc,x+i,y+j);
+      if (c==LTGRAY || c==BLACK)
+        return FALSE;
+    }
+  return TRUE;
+}
+
+U0 AnimateTask(CTask *parent)
+{
+  I64 i,cx,cy,cursor_x,cursor_y,dd,ddx,ddy,cnt,max_speed=I64_MAX,updates=0,
+        my_outside_cnt;
+  F64 f,d,dx,dy,s,stress;
+  Animal *tmpa,*tmpa1;
+  while (TRUE) {
+    max_speed=ClampU64(max_speed,U32_MAX/3,200*U32_MAX);
+    cx=(MAP_WIDTH -parent->pix_width)/2,
+          cy=(MAP_HEIGHT-parent->pix_height)/2;
+    cursor_x=ms.pos.x+cx-parent->pix_left-parent->scroll_x;
+    cursor_y=ms.pos.y+cy-parent->pix_top -parent->scroll_y;
+    cnt=0;stress=0;
+    my_outside_cnt=0;
+    if (cursor_x<FENCE_WIDTH && cursor_y<FENCE_HEIGHT)
+      gate_t=tS;
+    RedrawGate;
+    for (i=0;i<ANIMALS_NUM;i++) {
+      tmpa=&a[i];
+      if (!tmpa->dead) {
+//Move away from horse
+        ddx=tmpa->x.i32[1]-cursor_x;
+        ddy=tmpa->y.i32[1]-cursor_y;
+        if (dd=SqrI64(ddx)+SqrI64(ddy)) {
+          d=Sqrt(dd);
+          dx=ddx/d;
+          dy=ddy/d;
+          f=5.0e2*U32_MAX/dd;
+          tmpa->dx+=f*dx;
+          tmpa->dy+=f*dy;
+        }
+
+        //Resel buddy about every ANIMALS_NUM*10ms=5.12 seconds
+        tmpa1=&a[tmpa->buddy];
+        if (tmpa1->dead || i==updates%ANIMALS_NUM) {
+          BuddySel(i);
+          tmpa1=&a[tmpa->buddy];
+        }
+
+        //Move toward buddy
+        ddx=tmpa->x.i32[1]-tmpa1->x.i32[1];
+        ddy=tmpa->y.i32[1]-tmpa1->y.i32[1];
+        if (dd=SqrI64(ddx)+SqrI64(ddy)) {
+          d=Sqrt(dd);
+          s=d`1.25-80;
+          stress+=Abs(s);
+          dx=ddx/d;
+          dy=ddy/d;
+          f=-0.001*s*U32_MAX;
+          tmpa->dx+=f*dx;
+          tmpa->dy+=f*dy;
+        }
+
+        //Make velocity similar to buddy
+        tmpa->dx+=0.1*(tmpa1->dx-tmpa->dx);
+        tmpa->dy+=0.1*(tmpa1->dy-tmpa->dy);
+
+        //Add random movement, limit speed and dampen speed
+        tmpa->dx=0.995*ClampI64(tmpa->dx+RandI32/32,-max_speed,max_speed);
+        tmpa->dy=0.995*ClampI64(tmpa->dy+RandI32/32,-max_speed,max_speed);
+
+        //Slow in river
+        if (GrPeek(map_dc,tmpa->x.i32[1],tmpa->y.i32[1])!=LTGREEN) {
+          tmpa->dx/=2;
+          tmpa->dy/=2;
+        }
+
+        if (CheckMap((tmpa->x+tmpa->dx)>>32,(tmpa->y+tmpa->dy)>>32)) {
+          tmpa->x+=tmpa->dx;
+          tmpa->y+=tmpa->dy;
+        }
+
+        //Keep on map
+        if (!(MAP_BORDER+ANIMAL_WIDTH/2
+              <=tmpa->x.i32[1]<MAP_WIDTH-MAP_BORDER-ANIMAL_WIDTH/2)) {
+          tmpa->x -=tmpa->dx;
+          tmpa->dx=-tmpa->dx;
+        }
+        if (!(MAP_BORDER+ANIMAL_HEIGHT
+              <=tmpa->y.i32[1]<MAP_HEIGHT-MAP_BORDER)) {
+          tmpa->y -=tmpa->dy;
+          tmpa->dy=-tmpa->dy;
+        }
+        cnt++;
+        if (tmpa->x>>32>=FENCE_WIDTH || tmpa->y>>32>=FENCE_HEIGHT)
+          my_outside_cnt++;
+      }
+    }
+    outside_cnt=my_outside_cnt;
+
+    if (!(updates&15))
+      RiverDropsNext(parent);
+
+    if (!tf && !outside_cnt) {
+      tf=tS;
+      music.mute=TRUE;
+      Snd(86);Sleep(200);Snd;Sleep(100);
+      if (tf-t0<best_score) {
+        best_score=tf-t0;
+        Snd(86);Sleep(200);Snd;Sleep(100);
+      }
+      music.mute=FALSE;
+    }
+
+    updates++;
+
+    if (cnt)
+      stress/=cnt;
+    else
+      stress=0;
+    if (stress>100.0) {
+      Yield;
+      max_speed=stress/5.0*U32_MAX; //Converge faster at start-up
+    } else {
+      Sleep(10);
+      max_speed=0; //Will be set to normal max speed
+    }
+  }
+}
+
+U0 SongTask(I64)
+{//Randomly generated (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5qC4etG5DC4B5DCECFqFC4sA5D4A5D4qB");
+    Play("5C4etG5DC4B5DCECFqFC4sA5D4A5D4qB");
+    Play("4sGAGA5qG4etG5GD4eBBqB5F4eBA5qE");
+    Play("4sGAGA5qG4etG5GD4eBBqB5F4eBA5qE");
+  }
+}
+
+U0 ReInit()
+{
+  I64 i;
+
+  RiverDropsDel;
+  map_dc->color=LTGREEN;
+  GrRect(map_dc,2,2,MAP_WIDTH-4,MAP_HEIGHT-4);
+
+  RiverMake;
+
+  //Plot fence
+  for (i=FENCE_WIDTH;i>0;i-=16)
+    Sprite3(map_dc,i,FENCE_HEIGHT,0,<9>);
+  map_dc->thick=1;
+  map_dc->color=BROWN;
+  for (i=0;i<FENCE_HEIGHT-16;i+=16)
+    GrLine(map_dc,FENCE_WIDTH-1,i,FENCE_WIDTH-1,i+7);
+  map_dc->color=LTGRAY;
+  GrLine(map_dc,FENCE_WIDTH,0,FENCE_WIDTH,FENCE_HEIGHT-6);
+  RedrawGate;
+
+  map_dc->thick=MAP_BORDER;
+  map_dc->color=RED;
+  GrBorder(map_dc,MAP_BORDER/2,MAP_BORDER/2,
+        MAP_WIDTH-(MAP_BORDER+1)/2,MAP_HEIGHT-(MAP_BORDER+1)/2);
+
+  for (i=MAP_BORDER;i<=MAP_HEIGHT-MAP_BORDER;i++)
+    RiverDropsNext(Fs);
+
+  MemSet(a,0,ANIMALS_NUM*sizeof(Animal));
+  for (i=0;i<ANIMALS_NUM;i++) {
+    a[i].num=i;
+    do {
+      a[i].x=(64+RandU32%(MAP_WIDTH-128))<<32;
+      a[i].y=(64+RandU32%(MAP_WIDTH-128))<<32;
+    } while (!CheckMap(a[i].x>>32,a[i].y>>32));
+    if (i&1)
+      a[i].imgs=cow_imgs;
+    else
+      a[i].imgs=bull_imgs;
+    a[i].frame0=RandU16&3;
+    BuddySel(i);
+  }
+  outside_cnt=ANIMALS_NUM;
+  gate_t=0;
+  gate_theta=0;
+  t0=tS;
+  tf=0;
+}
+
+U0 Init()
+{
+  RiverNew;
+  rd_lock=0;
+  QueInit(&rd_head);
+  map_dc=DCNew(MAP_WIDTH,MAP_HEIGHT);
+  a=MAlloc(ANIMALS_NUM*sizeof(Animal));
+  ReInit;
+}
+
+U0 CleanUp()
+{
+  DCDel(map_dc);
+  Free(a);
+  RiverDropsDel;
+  RiverDel;
+}
+
+U0 RawHide()
+{
+  I64 msg_code,arg1,arg2;
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+
+  PopUpOk(
+        "Coral the cattle.  The coral is in the\n"
+        "upper-left corner if you scroll.\n\n"
+        "Keep holding the $GREEN$<CTRL>$FG$ key and\n"
+        "scroll with $GREEN${CTRL-Left Grab}$FG$.");
+
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_SELF_GRAB_SCROLL-WIF_FOCUS_TASK_MENU;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_R_DOWN);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:  //Doesn't do anything, yet.
+          break;
+        case MSG_MS_R_DOWN:  //Doesn't do anything, yet.
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              ReInit;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto rh_done;
+          }
+          break;
+      }
+    }
+rh_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/RawHide","F64 best_score=%5.4f;\n",best_score);
+}
+
+RawHide;
+
+ diff --git a/public/Wb/Demo/Games/Rocket.HC.HTML b/public/Wb/Demo/Games/Rocket.HC.HTML new file mode 100755 index 0000000..5565473 --- /dev/null +++ b/public/Wb/Demo/Games/Rocket.HC.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+#define THRUST  100
+
+Bool    blast_off;
+CMass   m1, //Bottom of rocket
+        m2; //Top of rocket
+CSpring s;
+
+#define ROCKET_HEIGHT   40
+#define GROUND_Y        (GR_HEIGHT-3*FONT_HEIGHT)
+
+
+  <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+CDC     *dc2;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,x,y,cx=GR_WIDTH/2,cy=GROUND_Y;
+  Bool engine_on;
+  F64 nozzle_angle,theta=Arg(m2.x-m1.x,m2.y-m1.y);
+
+  Sprite3(dc,0,GROUND_Y,0,<2>);
+
+  if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) {
+    nozzle_angle=0;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+    nozzle_angle=pi/8;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+    nozzle_angle=-pi/8;
+    engine_on=TRUE;
+  } else
+    engine_on=FALSE;
+
+  if (engine_on) {
+    x=m1.x-10*Cos(theta+nozzle_angle);
+    y=m1.y-10*Sin(theta+nozzle_angle);
+    for (i=0;i<6;i++) {
+      if ((i^winmgr.updates)&1)
+        dc->color=YELLOW;
+      else
+        dc->color=RED;
+      GrLine(dc,cx+(m1.x+i*Cos(theta-pi/2)),cy-(m1.y+i*Sin(theta-pi/2)),cx+x,cy-y);
+      GrLine(dc,cx+(m1.x+i*Cos(theta+pi/2)),cy-(m1.y+i*Sin(theta+pi/2)),cx+x,cy-y);
+    }
+
+    for (i=0;i<10;i++) {
+      switch (RandU16&3) {
+        case 0: dc2->color=WHITE;       break;
+        case 1: dc2->color=LTGRAY;      break;
+        case 2: dc2->color=DKGRAY;      break;
+        case 3: dc2->color=BLACK;       break;
+      }
+      GrPlot(dc2,cx+(x+RandU16%12-6),cy-(y+RandU16%12-6));
+    }
+    Snd(22);
+  } else
+    Snd;
+  Sprite3ZB(dc,cx+(m1.x+m2.x)/2,cy-(m1.y+m2.y)/2,0,<1>,-theta);
+}
+
+U0 MyDerivative(CMathODE *,F64,COrder2D3 *,COrder2D3 *)
+{
+  Bool engine_on;
+  F64 nozzle_angle,theta=Arg(m2.state->x-m1.state->x,m2.state->y-m1.state->y);
+
+  if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) {
+    nozzle_angle=0;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+    nozzle_angle=pi/8;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+    nozzle_angle=-pi/8;
+    engine_on=TRUE;
+  } else
+    engine_on=FALSE;
+
+  if (engine_on) {
+    m1.DstateDt->DxDt+=THRUST*Cos(theta+nozzle_angle);
+    m1.DstateDt->DyDt+=THRUST*Sin(theta+nozzle_angle);
+  }
+  if (blast_off) {
+    m1.DstateDt->DyDt-=25; //Gravity
+    m2.DstateDt->DyDt-=25;
+  }
+}
+
+U0 Init()
+{
+  DocClear;
+  "$BG,LTCYAN$$GREEN$Up, Left, Right$FG$%h*c",ToI64(GROUND_Y/FONT_HEIGHT),'\n';
+
+  blast_off=FALSE;
+
+  //We don't clear que links.
+  MemSet(&m1.start,0,offset(CMass.end)-offset(CMass.start));
+  m1.y=0;
+
+  MemSet(&m2.start,0,offset(CMass.end)-offset(CMass.start));
+  m2.y=ROCKET_HEIGHT;
+
+  MemSet(&s.start,0,offset(CSpring.end)-offset(CSpring.start));
+  s.end1=&m1;
+  s.end2=&m2;
+  s.rest_len=ROCKET_HEIGHT;
+  s.const=10000;
+
+  DCFill;
+}
+
+U0 TaskEndCB()
+{
+  DCFill;
+  SndTaskEndCB;
+}
+
+U0 Rocket()
+{
+  CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES);
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Up(,,SC_CURSOR_UP);"
+        "  UpLeft(,,SC_CURSOR_LEFT);"
+        "  UpRight(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  dc2=DCAlias;
+  Fs->task_end_cb=&TaskEndCB;
+
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  Init;
+  QueIns(&m1,ode->last_mass);
+  QueIns(&m2,ode->last_mass);
+  QueIns(&s,ode->last_spring);
+
+  QueIns(ode,Fs->last_ode);
+
+  Fs->draw_it=&DrawIt;
+
+  try {
+    GetKey;
+    blast_off=TRUE;
+    while (TRUE) {
+      switch (GetChar(,FALSE)) {
+        case '\n':
+          Init;
+          GetKey;
+          blast_off=TRUE;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto rk_done;
+      }
+    }
+rk_done:
+  } catch
+    PutExcept;
+  QueRem(ode);
+  ODEDel(ode);
+  DocClear;
+  SettingsPop;
+  DCFill;
+  DCDel(dc2);
+  MenuPop;
+}
+
+Rocket;
+
+ diff --git a/public/Wb/Demo/Games/RocketScience.HC.HTML b/public/Wb/Demo/Games/RocketScience.HC.HTML new file mode 100755 index 0000000..c22ceb6 --- /dev/null +++ b/public/Wb/Demo/Games/RocketScience.HC.HTML @@ -0,0 +1,328 @@ + + + + + + + + + + + +
+#define THRUST  1000
+
+Bool    blast_off,plane_hit;
+
+CMass   m1, //Bottom of rocket
+        m2, //Top of rocket
+        m3; //Plane
+CSpring s;
+
+#define ROCKET_HEIGHT   40
+#define GROUND_Y        (GR_HEIGHT-3*FONT_HEIGHT)
+
+
+   <1>/* Graphics Not Rendered in HTML */
+
+
+
+   <2>/* Graphics Not Rendered in HTML */
+
+
+
+  <3>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+CDC     *dc2;
+CMathODE *ode;
+
+#define STATE_NOZZLE_ANGLE              0
+#define STATE_NOZZLE_ANGLE_VELOCITY     1
+#define STATE_NUM                       2
+
+CD3     target;
+F64     my_dbg,antispin_coefficient;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,x,y,cx=GR_WIDTH/2,cy=GROUND_Y;
+  F64 theta=Arg(m2.x-m1.x,m2.y-m1.y),
+        nozzle_angle=ode->state[STATE_NOZZLE_ANGLE];
+
+  if (blast_off) {
+    x=m1.x-10*Cos(theta+nozzle_angle);
+    y=m1.y-10*Sin(theta+nozzle_angle);
+    for (i=0;i<6;i++) {
+      if ((i^winmgr.updates)&1)
+        dc->color=YELLOW;
+      else
+        dc->color=RED;
+      GrLine(dc,cx+(m1.x+i*Cos(theta-pi/2)),cy-(m1.y+i*Sin(theta-pi/2)),cx+x,cy-y);
+      GrLine(dc,cx+(m1.x+i*Cos(theta+pi/2)),cy-(m1.y+i*Sin(theta+pi/2)),cx+x,cy-y);
+    }
+
+    for (i=0;i<10;i++) {
+      switch (RandU16&3) {
+        case 0: dc2->color=WHITE;       break;
+        case 1: dc2->color=LTGRAY;      break;
+        case 2: dc2->color=DKGRAY;      break;
+        case 3: dc2->color=BLACK;       break;
+      }
+      GrPlot(dc2,cx+(x+RandU16%12-6),cy-(y+RandU16%12-6));
+    }
+  }
+
+  if (plane_hit)
+    Sprite3(dc,cx+m3.x,cy-m3.y,0,<2>);
+  else
+    Sprite3(dc,cx+m3.x,cy-m3.y,0,<1>);
+
+  if (blast_off && !plane_hit) {
+    dc->color=ROP_COLLISION;
+    dc->bkcolor=LTCYAN;
+    dc->collision_cnt=0;
+    Sprite3ZB(dc,cx+(m1.x+m2.x)/2,cy-(m1.y+m2.y)/2,0,<3>,-theta);
+    if (dc->collision_cnt>100) {
+      Noise(1000,62,81);
+      plane_hit=TRUE;
+    } else
+      Snd(22);
+  } else if (!plane_hit)
+    Snd;
+
+  dc->color=ROP_EQU;
+  Sprite3(dc,0,GROUND_Y,0,<4>);
+  Sprite3ZB(dc,cx+(m1.x+m2.x)/2,cy-(m1.y+m2.y)/2,0,<3>,-theta);
+
+  dc->color=RED;
+  GrCircle(dc,cx+target.x,cy-target.y,5);
+
+  dc->color=BLUE;
+  GrCircle(dc,cx+m3.x,cy-m3.y,5);
+
+  dc->color=BLACK;
+  GrPrint(dc,0,FONT_HEIGHT,"%12.6f",my_dbg);
+}
+
+U0 MyDerivative(CMathODE *,F64,F64 *state,F64 *DstateDt)
+{
+  F64 d,discriminant,v,a,theta=Arg(m2.state->x-m1.state->x,m2.state->y-m1.state->y),
+        DthetaDt,collision_estimate_t,target_heading,target_angle_error,
+        desired_nozzle_angle;
+  CD3 p,p_target,p_body;
+
+  //Unit vect pointing to top of rocket from bottom.
+  D3Sub(&p_body,&m2.state->x,&m1.state->x);
+  D3Unit(&p_body);
+
+  //DthetaDt lets us prevent too much spin.
+  DthetaDt=antispin_coefficient*
+        (m2.state->DyDt*p_body.x-m2.state->DxDt*p_body.y-
+        m1.state->DyDt*p_body.x+m1.state->DxDt*p_body.y)/ROCKET_HEIGHT;
+
+  //p_target is vect from top of rocket to plane.
+  D3Sub(&p_target,&m3.state->x,&m2.state->x);
+
+  //d=0.5at^2+vt
+  d=D3Norm(&p_target);
+
+  D3Copy(&p,&p_target);
+  D3Unit(&p);
+  v=(m2.state->DxDt*p.x+m2.state->DyDt*p.y)-
+        (m3.state->DxDt*p.x+m3.state->DyDt*p.y);
+
+  a=THRUST/(m1.mass+m2.mass);
+
+  discriminant=v*v+4*0.5*a*d;
+  if (discriminant>0)
+    collision_estimate_t=(-v+Sqrt(discriminant))/a;
+  else
+    collision_estimate_t=0;
+  my_dbg=collision_estimate_t;
+
+  //Aim for projected pos of plane at time of impact.
+  D3Copy(&p,&m3.state->DxDt);
+  D3MulEqu(&p,collision_estimate_t);
+  D3AddEqu(&p_target,&p);
+
+  D3Copy(&target,&p_target);
+  D3AddEqu(&target,&m2.state->x);
+
+  target_heading=Arg(p_target.x,p_target.y);
+  target_angle_error=Wrap(theta-target_heading); //Force to range [-pi,pi)
+  desired_nozzle_angle=Clamp(50.0*DthetaDt+750*target_angle_error,-pi/8,pi/8);
+
+  //For realism we limit the speed the nozzle angle can change.
+  DstateDt[STATE_NOZZLE_ANGLE]=state[STATE_NOZZLE_ANGLE_VELOCITY];
+  DstateDt[STATE_NOZZLE_ANGLE_VELOCITY]=
+        Clamp(10000*(desired_nozzle_angle-state[STATE_NOZZLE_ANGLE]),
+        -1000,1000)-10.0*state[STATE_NOZZLE_ANGLE_VELOCITY]; //Damping
+
+  if (blast_off) {
+    m1.DstateDt->DxDt+=THRUST*Cos(theta+state[STATE_NOZZLE_ANGLE]);
+    m1.DstateDt->DyDt+=THRUST*Sin(theta+state[STATE_NOZZLE_ANGLE]);
+
+    m1.DstateDt->DyDt-=25; //Gravity
+    m2.DstateDt->DyDt-=25;
+  }
+
+  //For more realism reduce the mass of the rocket because of fuel.
+  //You might also factor-in fuel slosh in the tank.
+
+  //To do this, you would have to set-up state vars for mass and
+  //do A=F/m manually instead of relyin on ODECallDerivative() to divide
+  //by mass.
+}
+
+U0 Init()
+{
+  DocClear;
+  "$BG,LTCYAN$%h*c",ToI64(GROUND_Y/FONT_HEIGHT),'\n';
+
+  blast_off=FALSE;
+  plane_hit=FALSE;
+
+  do antispin_coefficient=PopUpRangeF64Exp(0.1,10.001,Sqrt(10),
+          "%9.4f","Anti-spin Coefficient\n\n");
+  while (!(0.1<=antispin_coefficient<10.001));
+
+  //We don't clear que links.
+  MemSet(&m1.start,0,offset(CMass.end)-offset(CMass.start));
+  m1.y=0;
+  m1.mass=1.0;
+
+  MemSet(&m2.start,0,offset(CMass.end)-offset(CMass.start));
+  m2.y=ROCKET_HEIGHT;
+  m2.mass=1.0;
+
+  MemSet(&m3.start,0,offset(CMass.end)-offset(CMass.start));
+  m3.y=400;
+  m3.x=-300;
+  m3.DxDt=50;
+  m3.mass=1.0;
+
+  MemSet(&s.start,0,offset(CSpring.end)-offset(CSpring.start));
+  s.end1=&m1;
+  s.end2=&m2;
+  s.rest_len=ROCKET_HEIGHT;
+  s.const=10000;
+
+  ode->state[STATE_NOZZLE_ANGLE]=0;
+  ode->state[STATE_NOZZLE_ANGLE_VELOCITY]=0;
+
+  DCFill;
+}
+
+U0 TaskEndCB()
+{
+  DCFill;
+  SndTaskEndCB;
+}
+
+U0 RocketScience()
+{
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Launch(,CH_SPACE);"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  dc2=DCAlias;
+  Fs->task_end_cb=&TaskEndCB;
+
+  ode=ODENew(STATE_NUM,1e-6,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  //  ode->t_scale=0.1; //Uncomment this to go in slow motion.
+
+  Init;
+  QueIns(&m1,ode->last_mass);
+  QueIns(&m2,ode->last_mass);
+  QueIns(&m3,ode->last_mass);
+  QueIns(&s,ode->last_spring);
+
+  QueIns(ode,Fs->last_ode);
+
+  Fs->draw_it=&DrawIt;
+
+  try {
+    GetKey;
+    blast_off=TRUE;
+    while (TRUE) {
+      switch (GetChar(,FALSE)) {
+        case '\n':
+          Init;
+          GetKey;
+          blast_off=TRUE;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto rs_done;
+      }
+    }
+rs_done:
+  } catch
+    PutExcept;
+  QueRem(ode);
+  ODEDel(ode);
+  DocClear;
+  SettingsPop;
+  DCFill;
+  DCDel(dc2);
+  MenuPop;
+}
+
+RocketScience;
+
+ diff --git a/public/Wb/Demo/Games/Squirt.HC.HTML b/public/Wb/Demo/Games/Squirt.HC.HTML new file mode 100755 index 0000000..d345f52 --- /dev/null +++ b/public/Wb/Demo/Games/Squirt.HC.HTML @@ -0,0 +1,415 @@ + + + + + + + + + + + +
+#define MT_HOSE         1
+#define MT_DROPLET      2
+class MyMass:CMass
+{
+  I64 type;
+  F64 radius;
+};
+
+#define ST_HOSE         1
+class MySpring:CSpring
+{
+  I64 type;
+};
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+        <2>/* Graphics Not Rendered in HTML */
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+#define HOSE_RADIUS     3
+#define LINK_SIZE       6
+#define NOZZLE_START_Y  (GR_HEIGHT-15*FONT_HEIGHT)
+#define NOZZLE_LEN      18
+#define FAUCET_X        (5*HOSE_RADIUS)
+#define FAUCET_Y        (GR_HEIGHT-12*FONT_HEIGHT)
+#define GROUND_Y        (GR_HEIGHT-3*FONT_HEIGHT)
+MyMass *faucet,*nozzle;
+F64 nozzle_theta;
+
+CMathODE *ode=NULL;
+F64 start_up_timeout;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  Bool first;
+  F64 dx,dy,d;
+  I64  x1b,y1b,x2b,y2b,
+        x1a,y1a,x2a,y2a;
+  MyMass   *tmpm,*tmpm1;
+  MySpring *tmps;
+  CD3I32 poly[4];
+
+  Sprite3(dc,0,GROUND_Y,0,<4>);
+  if (start_up_timeout>tS) {
+    ode->drag_v2=0.01; //Let hose settle during start-up
+    ode->drag_v3=0.0001;
+    dc->color=RED;
+    GrPrint(dc,(GR_WIDTH-FONT_WIDTH*6)>>1,GR_HEIGHT>>1,"Squirt");
+    return;
+  } else {
+    ode->drag_v2=0.0005;
+    ode->drag_v3=0.0000025;
+  }
+
+  tmpm=faucet;
+  dc->color=BLACK;
+  GrRect(dc,tmpm->x+8,tmpm->y,8,GROUND_Y-FAUCET_Y);
+  Sprite3(dc,tmpm->x,tmpm->y,0,<1>);
+  dc->color=BLACK;
+  GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+  dc->color=GREEN;
+  GrFloodFill(dc,tmpm->x,tmpm->y);
+
+  tmpm=nozzle;
+  tmpm1=nozzle->last;
+  dx=tmpm->x-tmpm1->x;
+  dy=tmpm->y-tmpm1->y;
+  nozzle_theta=Wrap(Arg(dx,dy));
+  Sprite3ZB(dc,tmpm->x,tmpm->y,0,<2>,nozzle_theta);
+  dc->color=BLACK;
+  GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+  dc->color=GREEN;
+  GrFloodFill(dc,tmpm->x,tmpm->y);
+
+  first=TRUE;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type==MT_HOSE) {
+      tmpm1=tmpm->last;
+      dx=tmpm->x-tmpm1->x;
+      dy=tmpm->y-tmpm1->y;
+      d=HOSE_RADIUS/Max(Sqrt(dx*dx+dy*dy),0.001);
+      dx*=d;
+      dy*=d;
+      x2a=tmpm->x-dy;
+      y2a=tmpm->y+dx;
+      x2b=tmpm->x+dy;
+      y2b=tmpm->y-dx;
+
+      if (first)
+        first=FALSE;
+      else {
+        dc->color=GREEN;
+        poly[0].x=x1a;
+        poly[0].y=y1a;
+        poly[0].z=0;
+        poly[1].x=x2a;
+        poly[1].y=y2a;
+        poly[1].z=0;
+        poly[2].x=x2b;
+        poly[2].y=y2b;
+        poly[2].z=0;
+        poly[3].x=x1b;
+        poly[3].y=y1b;
+        poly[3].z=0;
+        GrFillPoly3(dc,4,poly);
+      }
+
+      //Fill gaps
+      GrLine(dc,x2a,y2a,x2b,y2b);
+
+      x1a=x2a;
+      y1a=y2a;
+      x1b=x2b;
+      y1b=y2b;
+    } else if (tmpm->type==MT_DROPLET)
+      Sprite3(dc,tmpm->x,tmpm->y,0,<3>);
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->type==ST_HOSE) {
+      dx=tmps->end1->x-tmps->end2->x;
+      dy=tmps->end1->y-tmps->end2->y;
+      d=HOSE_RADIUS/Max(Sqrt(dx*dx+dy*dy),0.001);
+      dx*=d;
+      dy*=d;
+      dc->color=BLACK;
+      GrLine(dc,tmps->end1->x-dy,tmps->end1->y+dx,
+            tmps->end2->x-dy,tmps->end2->y+dx);
+      GrLine(dc,tmps->end1->x+dy,tmps->end1->y-dx,
+            tmps->end2->x+dy,tmps->end2->y-dx);
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *state,COrder2D3 *DstateDt)
+{//The forces due to springs and drag are
+//automatically handled by the
+  //ode code.  We can add new forces
+  //here.
+  no_warn t,state,DstateDt;
+  MyMass *tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    if (tmpm1->type==MT_HOSE) {
+      if (tmpm1->state->y+tmpm1->radius>GROUND_Y)
+        tmpm1->DstateDt->DyDt-=Sqr(Sqr(tmpm1->state->y+
+              tmpm1->radius-GROUND_Y))*tmpm1->mass;
+      else
+        tmpm1->DstateDt->DyDt+=500*tmpm1->mass;
+      if (tmpm1==nozzle || tmpm1==faucet) {
+        tmpm1->DstateDt->DxDt=0;
+        tmpm1->DstateDt->DyDt=0;
+      }
+    } else if (tmpm1->type==MT_DROPLET)
+      tmpm1->DstateDt->DyDt=500*tmpm1->mass;
+    tmpm1=tmpm1->next;
+  }
+}
+
+MyMass *PlaceMass(I64 type,I64 x, I64 y,F64 r,
+        F64 dx,F64 dy,F64 mass,CTask *mem_task)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass),mem_task);
+  tmpm->type=type;
+  tmpm->mass=mass;
+  tmpm->drag_profile_factor=250.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->DxDt=dx;
+  tmpm->DyDt=dy;
+  tmpm->radius=r;
+  QueIns(tmpm,ode->last_mass);
+  return tmpm;
+}
+
+MySpring PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  tmps->const=20000;
+  QueIns(tmps,ode->last_spring);
+  return tmps;
+}
+
+U0 HoseNew()
+{
+  I64 i;
+  MyMass *tmpm1=NULL,*tmpm;
+  MySpring *tmps;
+  for (i=FAUCET_X;i<GR_WIDTH;i+=LINK_SIZE) {
+    tmpm=PlaceMass(MT_HOSE,i/2,GROUND_Y-HOSE_RADIUS,HOSE_RADIUS,0,0,1.0,Fs);
+    if (tmpm1) {
+      tmps=PlaceSpring(tmpm,tmpm1);
+      tmps->rest_len=LINK_SIZE;
+      tmps->type=ST_HOSE;
+      nozzle=tmpm;
+    } else
+      faucet=tmpm;
+    tmpm1=tmpm;
+  }
+  faucet->y=FAUCET_Y;
+  nozzle->y=NOZZLE_START_Y;
+  nozzle_theta=0;
+}
+
+U0 AnimateTask(I64)
+{
+  MyMass   *tmpm,*tmpm1;
+  F64 dx,dy;
+  while (TRUE) {
+    dx=Cos(nozzle_theta);
+    dy=Sin(nozzle_theta);
+    PlaceMass(MT_DROPLET,
+          nozzle->x+NOZZLE_LEN*dx,nozzle->y+NOZZLE_LEN*dy,HOSE_RADIUS,
+          500*dx,500*dy,100.0,Fs->parent_task);
+    if (Rand<0.05) //faucet drip
+      PlaceMass(MT_DROPLET,
+            faucet->x,faucet->y,HOSE_RADIUS,
+            0,0,100.0,Fs->parent_task);
+
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      tmpm1=tmpm->next;
+      if (tmpm->type==MT_DROPLET && tmpm->y+tmpm->radius>GROUND_Y) {
+        QueRem(tmpm);
+        Free(tmpm);
+      }
+      tmpm=tmpm1;
+    }
+    Refresh;
+  }
+}
+
+#define NOZZLE_MOVE_STEPS       5
+#define NOZZLE_MOVE             15.0
+U0 MoveNozzleTaskX(I64 sign)
+{
+  I64 i;
+  for (i=0;i<NOZZLE_MOVE_STEPS;i++) {
+    nozzle->x=Clamp(nozzle->x+sign*NOZZLE_MOVE/NOZZLE_MOVE_STEPS,
+          HOSE_RADIUS*3,GR_WIDTH-HOSE_RADIUS*3);
+    Refresh;
+  }
+}
+
+U0 MoveNozzleTaskY(I64 sign)
+{
+  I64 i;
+  for (i=0;i<NOZZLE_MOVE_STEPS;i++) {
+    nozzle->y=Clamp(nozzle->y+sign*NOZZLE_MOVE/NOZZLE_MOVE_STEPS,
+          HOSE_RADIUS*3,GROUND_Y);
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  DocClear;
+  "$BG,LTCYAN$%h*c",ToI64(GROUND_Y/FONT_HEIGHT),'\n';
+
+  //Allow hose to settle.
+  start_up_timeout=tS+0.5;
+
+  ode=ODENew(0,5e-2,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->acceleration_limit=5e3;
+
+  HoseNew;
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  Refresh(NOZZLE_MOVE_STEPS); //Let nozzle move tasks die
+  QueRem(ode);
+  QueDel(&ode->next_mass,TRUE);
+  QueDel(&ode->next_spring,TRUE);
+  ODEDel(ode);
+  DocClear;
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5sDCDC4qA5DetDFFeDG4etA5EF4qG5eFC");
+    Play("5sDCDC4qA5DetDFFeDG4etA5EF4qG5eFC");
+    Play("5DCsG4A5G4AqBeBA5qEE4B5eC4B");
+    Play("5DCsG4A5G4AqBeBA5qEE4B5eC4B");
+  }
+}
+
+U0 Squirt()
+{
+  I64 sc;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "}"
+        );
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              Spawn(&MoveNozzleTaskX,-1,"Move Nozzle",,Fs);
+              break;
+            case SC_CURSOR_RIGHT:
+              Spawn(&MoveNozzleTaskX,1,"Move Nozzle",,Fs);
+              break;
+            case SC_CURSOR_UP:
+              Spawn(&MoveNozzleTaskY,-1,"Move Nozzle",,Fs);
+              break;
+            case SC_CURSOR_DOWN:
+              Spawn(&MoveNozzleTaskY,1,"Move Nozzle",,Fs);
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto sq_done;
+      }
+    }
+sq_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+Squirt;
+
+ diff --git a/public/Wb/Demo/Games/Stadium/Stadium.HC.HTML b/public/Wb/Demo/Games/Stadium/Stadium.HC.HTML new file mode 100755 index 0000000..b126114 --- /dev/null +++ b/public/Wb/Demo/Games/Stadium/Stadium.HC.HTML @@ -0,0 +1,165 @@ + + + + + + + + + + + +
+/*This shows how you can make a
+background very easily.
+*/
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+CDC *background;
+
+#define BALL_TIME       0.2
+#define FANS_NUM 10
+I64 x[FANS_NUM],y[FANS_NUM];
+Bool hit[FANS_NUM];
+F64 theta[FANS_NUM],ball_t;
+I64 target_x,target_y,pitcher_x,pitcher_y;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i,*r;
+  F64 xx,yy,t0;
+  background->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,0,0,background);
+  for (i=0;i<FANS_NUM;i++)
+    Sprite3ZB(dc,x[i],y[i],0,<fan>,theta[i]);
+  if (ball_t) {
+    t0=(tS-ball_t)/BALL_TIME;
+    if (t0>1.0)
+      ball_t=0;
+    else {
+      xx=t0*target_x+(1.0-t0)*pitcher_x;
+      yy=t0*target_y+(1.0-t0)*pitcher_y;
+      xx/=1.5-t0;
+      yy/=1.5-t0;
+      r=Mat4x4New(dc->r,dc->mem_task);
+      Mat4x4Scale(r,1.5-t0);
+      Free(dc->r);
+      DCMat4x4Set(dc,r);
+      dc->flags|=DCF_TRANSFORMATION;
+      Sprite3ZB(dc,xx,yy,0,<ball>,t0);
+    }
+  }
+  dc->color=RED;
+  GrPrint(dc,FONT_WIDTH,FONT_HEIGHT,"Peg the Fans");
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  F64 xx,yy,t0;
+  while (TRUE) {
+    if (ball_t) {
+      t0=(tS-ball_t)/BALL_TIME;
+      xx=t0*target_x+(1.0-t0)*pitcher_x;
+      yy=t0*target_y+(1.0-t0)*pitcher_y;
+    }
+    for (i=0;i<FANS_NUM;i++) {
+      if (ball_t)
+        if (Sqr(x[i]-xx)+Sqr(y[i]-yy)<200) {
+          hit[i]=TRUE;
+          theta[i]=-pi/2;
+        }
+      if (!hit[i]) {
+        x[i]+=SignI64(RandI16);
+        y[i]+=SignI64(RandI16);
+        theta[i]+=Sign(RandI16)/25.0;
+        if (!(0<=x[i]<GR_WIDTH)) x[i]=GR_WIDTH/2;
+        if (!(10<=y[i]<100)) y[i]=50;
+        if (!(-0.75<=theta[i]<0.75)) theta[i]=0;
+      }
+    }
+    Sleep(10);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<FANS_NUM;i++) {
+    x[i]=RandU16%GR_WIDTH;
+    y[i]=50;
+    theta[i]=0;
+    hit[i]=FALSE;
+  }
+}
+
+U0 Stadium()
+{
+  I64 msg_code,arg1,arg2,ch=0;
+
+  SettingsPush; //See SettingsPush
+  Cd(__DIR__);
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+
+  background=GRRead("StadiumBG");
+  Fs->draw_it=&DrawIt;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
+    if (msg_code==MSG_KEY_DOWN) {
+      ch=arg1;
+      if (ch=='\n')
+        Init;
+    } else {
+      target_x=arg1; target_y=arg2;
+      pitcher_x=GR_WIDTH/2; pitcher_y=GR_HEIGHT;
+      ball_t=tS;
+    }
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  GetMsg(,,1<<MSG_KEY_UP);
+
+  DCDel(background);
+  SettingsPop;
+  MenuPop;
+}
+
+Stadium;
+
+ diff --git a/public/Wb/Demo/Games/Stadium/StadiumGen.HC.HTML b/public/Wb/Demo/Games/Stadium/StadiumGen.HC.HTML new file mode 100755 index 0000000..88694de --- /dev/null +++ b/public/Wb/Demo/Games/Stadium/StadiumGen.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+//Generate "StadiumBG.GR.Z" from "StadiumBG.DD.Z"
+
+U0 StadiumGen()
+{
+  U0 (*fp_old_update)(CDC *dc);
+  CDC *dc,*dc2;
+
+  Cd(__DIR__);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor(OFF);
+  DocClear;
+  Type("StadiumBG.DD");
+  "$CM,0,%d$",TEXT_ROWS-3;
+  fp_old_update=gr.fp_final_scrn_update; //hide mouse cursor
+  gr.fp_final_scrn_update=NULL;
+
+  Refresh(2,TRUE);
+  dc2=DCScrnCapture;
+  dc=DCExt(dc2,0,FONT_HEIGHT,GR_WIDTH,GR_HEIGHT);
+  DCDel(dc2);
+
+  GRWrite("StadiumBG",dc,DCSF_COMPRESSED|DCSF_PALETTE_GET);
+  DCDel(dc);
+
+  DocCursor(ON);
+  gr.fp_final_scrn_update=fp_old_update;
+  DocClear;
+}
+
+StadiumGen;
+
+
+ diff --git a/public/Wb/Demo/Games/Talons.HC.HTML b/public/Wb/Demo/Games/Talons.HC.HTML new file mode 100755 index 0000000..b5e58a3 --- /dev/null +++ b/public/Wb/Demo/Games/Talons.HC.HTML @@ -0,0 +1,1264 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+RegDft("TempleOS/Talons","F64 best_score=9999;\n");
+RegExe("TempleOS/Talons");
+
+//Keep these power of two so shift is used instead of multiply
+//to index arrays.
+#define MAP_WIDTH               1024
+#define MAP_HEIGHT              1024
+
+#define MAP_SCALE               150
+#define DISPLAY_SCALE           100
+#define CTRLS_SCALE             0.05
+
+//I think I did these so the heads-up showed intelligable numbers.
+//Scaling is a mess.
+#define COORDINATE_SCALE        256
+#define COORDINATE_BITS         8
+
+#define WATER_ELEVATION         15
+#define BIRD_ELEVATION          10
+#define ROCK_ELEVATION          45
+#define SNOW_ELEVATION          55
+
+//Too big makes off-scrn draws take place.
+#define PANEL_SIZE_MAX          16
+
+
+
+
+
+                        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+#define LS_TYPES        3
+U8      *landscape_small_imgs[LS_TYPES]={<4>,<5>,<6>},
+        *landscape_large_imgs[LS_TYPES];
+
+#define B_NUM   256
+class Bird
+{
+  Bird *next,*last;
+  CD3I64 p;
+  F64 theta;
+} b_head[mp_cnt];
+
+class Obj
+{
+  Obj *next,*last;
+  CD3I64 p;
+  U8 *img;
+  Bool fish;
+};
+
+class Panel
+{//Polygon or Obj
+  Panel *next;
+  CD3I32 *pts;
+  I64 cnt;
+  U16 update,num_sides;
+  CColorROPU32 color;
+  Obj *next_obj,*last_obj;
+} *panel_head,*panels[MAP_HEIGHT][MAP_WIDTH];
+
+I64 critical_section_flag;
+I16 elevations[MAP_HEIGHT][MAP_WIDTH];
+CD3 normals[MAP_HEIGHT][MAP_WIDTH];
+
+class MPCtrl {
+  I64 init_not_done_flags,update_not_done_flags,app_not_done_flags;
+  I64 strip_width[MP_PROCESSORS_NUM];
+  Bool app_done;
+} mp;
+
+F64 game_t0,game_tf,pitch,roll,heading,phi,speed;
+Bool invert_pitch,rolled_over;
+I64 strip_height,x,y,z,fish_left;
+CD3 v;
+
+U0 WrapAngles()
+{
+  I64 r[4][4],x,y,z;
+
+  phi=Wrap(phi);
+  pitch=Wrap(-phi-pi/2);
+  if (Abs(pitch)>pi/2) {
+    invert_pitch=TRUE;
+    pitch=Wrap(pi-pitch);
+  } else
+    invert_pitch=FALSE;
+  roll=Wrap(roll);
+  if (invert_pitch ^^ -pi/2<=roll<pi/2)
+    rolled_over=FALSE;
+  else
+    rolled_over=TRUE;
+  heading=Wrap(heading,0);
+
+  //World to scrn coordinates
+  Mat4x4IdentEqu(r);
+  Mat4x4RotZ(r,heading);
+  Mat4x4RotX(r,phi);
+  Mat4x4RotZ(r,roll);
+
+  //We use velocity vector for dog-fighting.
+  x=0x100000000*speed; y=0; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  v.x=x/ToF64(0x100000000); v.y=y/ToF64(0x100000000); v.z=z/ToF64(0x100000000);
+}
+
+U0 EDTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  *z=zz=-*z;
+  if (zz>0) {
+    *x = dc->x + *x * DISPLAY_SCALE/zz; //Foreshortening
+    *y = dc->y - *y * DISPLAY_SCALE/zz;
+  } else {
+    *x = dc->x + *x;
+    *y = dc->y - *y;
+  }
+}
+
+U0 CalcNormals()
+{/*Find the normal vect with a curl.
+
+i,j and k are the axis unit vectors,
+not to be confused with my local index variables.
+
+i  j  k
+0  1  dz2
+1  0  dz1
+
+Normal:  dz1*i + dz2*j - k
+*/
+  I64 i,j;
+  for (j=0;j<MAP_HEIGHT-1;j++) {
+    for (i=0;i<MAP_WIDTH-1;i++) {
+      normals[j][i].x=elevations[j][i+1]-elevations[j][i];
+      normals[j][i].y=elevations[j+1][i]-elevations[j][i];
+      normals[j][i].z=-1;
+      D3Unit(&normals[j][i]);
+    }
+    MemSet(&normals[j][i],0,sizeof(CD3));
+  }
+  for (i=0;i<MAP_WIDTH-1;i++)
+    MemSet(&normals[j][i],0,sizeof(CD3));
+}
+
+Bool TestSameSlope(I64 x,I64 y,I64 w,I64 h)
+{
+  CD3 p,*s;
+  I64 k1,k2;
+  if (!(0<=x && x+w<MAP_WIDTH && 0<=y && y+h<MAP_HEIGHT))
+    return FALSE;
+  s=&normals[y][x];
+  for (k2=0;k2<h;k2++)
+    for (k1=0;k1<w;k1++)
+      if (D3NormSqr(D3Sub(&p,&normals[y+k2][x+k1],s))>.10)
+        return FALSE;
+  return TRUE;
+}
+
+U0 MPDoPanels(CTask *task)
+{
+  I64 i,j,l,k1,k2,w,h,threshold,lo,hi;
+  Bool cont;
+  Panel *tmpp,*start_ptr=NULL,*end_ptr=NULL;
+  CD3I32 *poly;
+  Obj *tmpo;
+  lo=Gs->num*(MAP_HEIGHT-1)/mp_cnt;
+  hi=(Gs->num+1)*(MAP_HEIGHT-1)/mp_cnt;
+  for (threshold=8;threshold>=1;threshold--)
+    for (j=lo;j<hi;j++) {
+      for (i=0;i<MAP_WIDTH-1;i++) {
+        if (!panels[j][i]) {
+          w=1;
+          h=1;
+          do {
+            cont=FALSE;
+            if (w<PANEL_SIZE_MAX && TestSameSlope(i,j,w+1,h)) {
+              w++;
+              cont=TRUE;
+            }
+            if (h<PANEL_SIZE_MAX && TestSameSlope(i,j,w,h+1)) {
+              h++;
+              cont=TRUE;
+            }
+          } while (cont);
+          if (w>=threshold || h>=threshold) {
+            tmpp=CAlloc(sizeof(Panel),task);
+            QueInit(&tmpp->next_obj);
+            l=elevations[j][i];
+            if (l<=WATER_ELEVATION*MAP_SCALE &&
+                  elevations[j][i+w-1]<=WATER_ELEVATION*MAP_SCALE &&
+                  elevations[j+h-1][i]<=WATER_ELEVATION*MAP_SCALE &&
+                  elevations[j+h-1][i+w-1]<=WATER_ELEVATION*MAP_SCALE) {
+              tmpp->color=BLUE;
+              if (Rand<0.05) {
+                tmpo=MAlloc(sizeof(Obj),task);
+                tmpo->p.x=(i+w/2)*MAP_SCALE;
+                tmpo->p.y=(j+h/2)*MAP_SCALE;
+                if (Rand<0.1) {
+                  tmpo->fish=FALSE;
+                  if (RandI16&1)
+                    tmpo->img=landscape_large_imgs[0]; //Boat
+                  else
+                    tmpo->img=landscape_large_imgs[1]; //Boat
+                  tmpo->p.z=(WATER_ELEVATION+2)*MAP_SCALE;
+                } else {
+                  tmpo->fish=TRUE;
+                  tmpo->img=<1>; //Fish
+                  tmpo->p.z=WATER_ELEVATION*MAP_SCALE;
+                }
+                QueIns(tmpo,tmpp->last_obj);
+              }
+            } else {
+              if (l<ROCK_ELEVATION*MAP_SCALE) {
+                if (RandI16&1)
+                  tmpp->color=LTGREEN;
+                else
+                  tmpp->color=GREEN+LTGREEN<<16+ROPF_DITHER;
+                if (Rand<0.03) {
+                  tmpo=MAlloc(sizeof(Obj),task);
+                  tmpo->p.x=(i+w/2)*MAP_SCALE;
+                  tmpo->p.y=(j+h/2)*MAP_SCALE;
+                  tmpo->p.z=l;
+                  tmpo->img=landscape_large_imgs[2]; //Tree
+                  tmpo->fish=FALSE;
+                  QueIns(tmpo,tmpp->last_obj);
+                }
+              } else if (l<SNOW_ELEVATION*MAP_SCALE) {
+                if (!(RandU16&3)) {
+                  if (RandI16&1)
+                    tmpp->color=LTGRAY;
+                  else
+                    tmpp->color=DKGRAY+LTGRAY<<16+ROPF_DITHER;
+                } else {
+                  if (RandI16&1)
+                    tmpp->color=LTGREEN;
+                  else
+                    tmpp->color=GREEN+LTGREEN<<16+ROPF_DITHER;
+                }
+              } else {
+                if (!(RandU16&3)) {
+                  if (RandI16&1)
+                    tmpp->color=WHITE;
+                  else
+                    tmpp->color=LTGRAY;
+                } else {
+                  if (RandI16&1)
+                    tmpp->color=LTGRAY+WHITE<<16+ROPF_DITHER;
+                  else
+                    tmpp->color=DKGRAY+LTGRAY<<16+ROPF_DITHER;
+                }
+              }
+            }
+            tmpp->num_sides=4;
+            poly=tmpp->pts=MAlloc(sizeof(CD3I32)*tmpp->num_sides,task);
+            poly[0].x=MAP_SCALE*i;
+            poly[0].y=MAP_SCALE*j;
+            poly[0].z=elevations[j][i];
+            poly[1].x=MAP_SCALE*(i+w);
+            poly[1].y=MAP_SCALE*j;
+            poly[1].z=elevations[j][i+w];
+            poly[2].x=MAP_SCALE*(i+w);
+            poly[2].y=MAP_SCALE*(j+h);
+            poly[2].z=elevations[j+h][i+w];
+            poly[3].x=MAP_SCALE*i;
+            poly[3].y=MAP_SCALE*(j+h);
+            poly[3].z=elevations[j+h][i];
+            tmpp->next=start_ptr;
+            start_ptr=tmpp;
+            if (!end_ptr)
+              end_ptr=tmpp;
+            for (k2=0;k2<h;k2++)
+              for (k1=0;k1<w;k1++)
+                panels[j+k2][i+k1]=tmpp;
+          }
+        }
+      }
+    }
+  if (end_ptr) {
+    while (LBts(&critical_section_flag,0))
+      Yield;
+    if (end_ptr)
+      end_ptr->next=panel_head;
+    panel_head=start_ptr;
+    LBtr(&critical_section_flag,0);
+  }
+  LBtr(&mp.init_not_done_flags,Gs->num);
+}
+
+U0 InitElevations()
+{
+  I64 i,j,l,x,y,xx,yy,x1,y1,x2,y2;
+  MemSet(elevations,0,sizeof(elevations));
+  for (i=0;i<MAP_WIDTH*MAP_HEIGHT/128;i++) {
+    x=RandU32%MAP_WIDTH;
+    y=RandU32%MAP_HEIGHT;
+    j=1<<(RandU32%6);
+    l=0;
+    while (j--) {
+      if (!l && RandU16<U16_MAX/4)
+        l=RandU16%(j+1);
+      if (l) {
+        x1=ClampI64(x-j,0,MAP_WIDTH-1);
+        x2=ClampI64(x+j,0,MAP_WIDTH-1);
+        y1=ClampI64(y-j,0,MAP_HEIGHT-1);
+        y2=ClampI64(y+j,0,MAP_HEIGHT-1);
+        for (yy=y1;yy<y2;yy++)
+          for (xx=x1;xx<x2;xx++)
+            elevations[yy][xx]+=MAP_SCALE/2;
+        l--;
+      }
+    }
+  }
+
+  for (j=0;j<MAP_HEIGHT;j++)
+    for (i=0;i<MAP_WIDTH;i++)
+      if (elevations[j][i]<WATER_ELEVATION*MAP_SCALE)
+        elevations[j][i]=WATER_ELEVATION*MAP_SCALE;
+}
+
+U0 InitMap()
+{/*We make a topographic data structure "elevations[][]"
+and convert it to panels. "panels[][]" holds the panels
+for each spot.
+*/
+  I64 i;
+  InitElevations;
+  MemSet(panels,0,sizeof(panels));
+  CalcNormals;
+  panel_head=NULL;
+  mp.init_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    Spawn(&MPDoPanels,Fs,"Do Panels",i);
+  while (mp.init_not_done_flags)
+    Sleep(1);
+}
+
+F64 claws_down;
+
+#define HAND_X  (1.0-claws_down)*(0.3*w)+claws_down*(0.4*w)
+#define HAND_Y  (1.0-claws_down)*(h-125)+claws_down*h
+
+
+
+
+<7>/* Graphics Not Rendered in HTML */
+<8>/* Graphics Not Rendered in HTML */
+
+
+
+U0 ClawDraw(CDC *dc,I64 x1,I64 y1,I64 x2,I64 y2,I64 w,I64 segments,Bool talon)
+{
+  I64 i,j;
+  for (i=0,j=segments;i<segments;i++,j--) {
+    dc->thick=w;
+    dc->color=BLACK;
+    GrLine3(dc,
+        j*x1/segments+i*x2/segments,
+        j*y1/segments+i*y2/segments,0,
+        (j-1)*x1/segments+(i+1)*x2/segments,
+        (j-1)*y1/segments+(i+1)*y2/segments,0);
+    dc->thick=w-2;
+    dc->color=YELLOW;
+    GrLine3(dc,
+        j*x1/segments+i*x2/segments,
+        j*y1/segments+i*y2/segments,0,
+        (j-1)*x1/segments+(i+1)*x2/segments,
+        (j-1)*y1/segments+(i+1)*y2/segments,0);
+  }
+  if (talon) {
+    if (y1<y2)
+      Sprite3B(dc,x1,y1,0,<7>);
+    else
+      Sprite3B(dc,x1,y1,0,<8>);
+  }
+}
+
+U0 ClawsDraw(CTask *task,CDC *dc)
+{
+  F64 claws_up=1.0-claws_down;
+  I64 w=task->pix_width,h=task->pix_height;
+  dc->flags|=DCF_SYMMETRY;
+  DCSymmetrySet(dc,w>>1,0,w>>1,1);
+
+  ClawDraw(dc,HAND_X-30,HAND_Y-50*claws_up,HAND_X-5,HAND_Y,     22,4,TRUE);
+  ClawDraw(dc,HAND_X-10,HAND_Y-60*claws_up,HAND_X,HAND_Y,       22,4,TRUE);
+  ClawDraw(dc,HAND_X+10,HAND_Y-60*claws_up,HAND_X,HAND_Y,       22,4,TRUE);
+  ClawDraw(dc,HAND_X+30,HAND_Y-50*claws_up,HAND_X+5,HAND_Y,     22,4,TRUE);
+  ClawDraw(dc,HAND_X+25,HAND_Y+40*claws_up,HAND_X+5,HAND_Y,     22,4,TRUE);
+
+  ClawDraw(dc,HAND_X,HAND_Y,6*w/20,h,38,5,FALSE);
+}
+
+CDC *main_dc;
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  main_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,0,0,main_dc);
+  if (claws_down)
+    ClawsDraw(task,dc);
+}
+
+/*
+<9>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Cores render strips that +/- 15%. The cores check the panel map array
+and render the panel for each square, marking-it done.
+
+The depth buf is not locked in the graphic routines
+so we get some glitches.
+*/
+
+I64 update_jiffy_limit;
+
+U0 MPDrawIt(CTask *task,CDC *dc)
+{
+  I64 j,update=winmgr.updates&65535,strip_width,*s2w,x1,y1,z1,xx,yy,
+        xh,yh,zh,yh2,xh2,x1h,y1h,x1wa,y1wa,x1wb,y1wb,x3,y3,z3,dd,dd_old,
+        cx=task->pix_width>>1,cy=task->pix_height>>1,r[16],*elems1,*elems_hard;
+  Panel reg *tmpp;
+  Bird  *tmpb;
+  Obj   *tmpo;
+  Bool  w_on_map,h_on_map;
+
+  xx=x/(MAP_SCALE*COORDINATE_SCALE);
+  yy=y/(MAP_SCALE*COORDINATE_SCALE);
+
+  //World to scrn coordinates
+  Mat4x4IdentEqu(dc->r);
+  Mat4x4RotZ(dc->r,heading);
+  Mat4x4RotX(dc->r,phi);
+  Mat4x4RotZ(dc->r,roll);
+  DCMat4x4Set(dc,dc->r);
+
+  //Scrn to world coordinates
+
+  //This gives us the vects for stepping through the grid in
+  //the direction the plane is facing. we step horizontally and vertically
+  //and use the reciprocal slope principle
+  //y=mx+b and y=(-1/m)x+b are perpendicular.
+
+  s2w=Mat4x4IdentNew;
+  Mat4x4RotZ(s2w,-roll);
+  Mat4x4RotX(s2w,-phi);
+  Mat4x4RotZ(s2w,-heading);
+
+  xh=0;
+  yh=0;
+  zh=-256;
+  Mat4x4MulXYZ(s2w,&xh,&yh,&zh);
+
+  //The layer for core1 is not cleared automatically
+  //it is persistent.  I have carefully syncronized to the update
+  //cycle initiated by Core0 to prevent flicker.
+
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->transform=&EDTransform;
+  dc->x=cx;
+  dc->y=cy;
+
+  //dc->x and the translation part of dc->r are ident in effect,
+  //but we use both to show-off.        We could add offsets together and
+  //use one or the other.
+
+  x1=-x>>COORDINATE_BITS;
+  y1=-y>>COORDINATE_BITS;
+  z1=-z>>COORDINATE_BITS;
+  Mat4x4MulXYZ(dc->r,&x1,&y1,&z1);
+  Mat4x4TranslationEqu(dc->r,x1,y1,z1);
+
+  //This is a refinement.
+  if (Abs(phi*180/pi)>90) {
+    x3=0;
+    y3=-cy;
+    z3=0;
+    Mat4x4MulXYZ(s2w,&x3,&y3,&z3);
+    xx+=x3;
+    yy+=y3;
+  }
+
+  if (Gs->num&1) {//alt left-right,right-left
+    yh2=-yh;
+    xh2=-xh;
+  } else {
+    yh2=yh;
+    xh2=xh;
+  }
+
+  //Calc starting point.
+  x1wa=xx<<8+xh*strip_height>>1/1.3*(Gs->num+1.15);
+  y1wa=yy<<8+yh*strip_height>>1/1.3*(Gs->num+1.15);
+  x1wb=0;
+  y1wb=0;
+
+  xh=-xh; //Back to front to help with depth.
+  yh=-yh;
+
+  //Take half steps to cover whole grid.
+  xh>>=1;  yh>>=1;
+  xh2>>=1; yh2>>=1;
+  w_on_map=FALSE;
+  dd_old=I64_MAX;
+  for (strip_width=0;cnts.jiffies<update_jiffy_limit;strip_width++) {
+    x1h=x1wa;
+    y1h=y1wa;
+    h_on_map=FALSE;
+    for (j=0;j<strip_height && cnts.jiffies<update_jiffy_limit;j++) {
+      x1=x1h>>8; y1=y1h>>8;
+      if (0<=x1<MAP_WIDTH && 0<=y1<MAP_HEIGHT) {
+        if ((tmpp=panels[y1][x1]) && tmpp->update!=update) {
+          tmpp->update=update;
+          if (tmpp->cnt>8*(1.1-Gs->idle_factor)) {
+            dc->color=tmpp->color;
+            tmpp->cnt=GrFillPoly3(dc,tmpp->num_sides,tmpp->pts);
+          } else
+            tmpp->cnt++;
+          tmpo=tmpp->next_obj;
+          while (tmpo!=&tmpp->next_obj) {
+            Sprite3(dc,tmpo->p.x,tmpo->p.y,tmpo->p.z,tmpo->img);
+            tmpo=tmpo->next;
+          }
+        }
+        h_on_map=TRUE;
+      } else if (h_on_map)
+        break;
+      x1h+=xh;
+      y1h+=yh;
+    }
+    if (h_on_map)
+      w_on_map=TRUE;
+    else if (w_on_map) {
+      strip_width=I64_MAX;
+      break;
+    }
+    x1wb-=yh2;
+    y1wb+=xh2;
+    if (strip_width&1) {
+      x1wa-=x1wb;
+      y1wa-=y1wb;
+    } else {
+      x1wa+=x1wb;
+      y1wa+=y1wb;
+    }
+    if (!w_on_map) {
+      dd=SqrI64(x1wa>>8-MAP_WIDTH>>1)+SqrI64(y1wa>>8-MAP_HEIGHT>>1);
+      if (dd>dd_old)
+        break;
+      dd_old=dd;
+    }
+  }
+
+  tmpb=b_head[Gs->num].next;
+  while (tmpb!=&b_head[Gs->num]) {
+    elems1=SpriteInterpolate(Tri(tS,0.2),<2>,<3>);
+
+    Mat4x4IdentEqu(r);
+    Mat4x4RotZ(r,tmpb->theta);
+    elems_hard=SpriteTransform(elems1,r);
+
+    Sprite3(dc,tmpb->p.x,tmpb->p.y,tmpb->p.z,elems_hard);
+    Free(elems_hard);
+    Free(elems1);
+
+    tmpb=tmpb->next;
+  }
+
+  Free(s2w);
+  mp.strip_width[Gs->num]=strip_width;
+  LBtr(&mp.update_not_done_flags,Gs->num);
+}
+
+U0 CoreAPTalonsTask(CTask *master_task)
+{
+  CDC *dc=DCAlias(main_dc,master_task);
+  while (!mp.app_done) {
+    while (!Bt(&mp.update_not_done_flags,Gs->num) && !mp.app_done)
+      Sleep(1);
+    if (!mp.app_done)
+      MPDrawIt(master_task,dc);
+  }
+
+  //We made an alias of this we don't want freed.
+  dc->depth_buf=NULL;
+
+  DCDel(dc);
+  LBtr(&mp.app_not_done_flags,Gs->num);
+}
+
+U0 DrawHorizon(CDC *dc)
+{
+  I64 x1,y1,z1,x2,y2,z2,xh,yh,zh,*s2w=Mat4x4IdentNew,
+        cx=Fs->pix_width>>1,
+        cy=Fs->pix_height>>1;
+  CD3I32 p[4];
+  I32 *old_db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  CColorROPU32 ground_color;
+
+  if (game_tf && fish_left)
+    DCFill(dc,BLACK);
+  else if (-pi/4<=Wrap(phi-pi)<pi/4)
+    DCFill(dc,LTCYAN);
+  else {
+    if (z/COORDINATE_SCALE<(WATER_ELEVATION+3)*MAP_SCALE)
+      ground_color=BLUE;
+    else
+      ground_color=LTGREEN;
+
+    Mat4x4IdentEqu(dc->r);
+    Mat4x4RotZ(dc->r,heading);
+    Mat4x4RotX(dc->r,phi);
+    Mat4x4RotZ(dc->r,roll);
+
+    DCMat4x4Set(dc,dc->r);
+    dc->flags&=~DCF_TRANSFORMATION;
+    dc->transform=&EDTransform;
+    dc->x=cx;
+    dc->y=cy;
+
+    Mat4x4RotZ(s2w,-roll);
+    Mat4x4RotX(s2w,-phi);
+    Mat4x4RotZ(s2w,-heading);
+
+    xh=0;
+    yh=0;
+    zh=-256;
+    Mat4x4MulXYZ(s2w,&xh,&yh,&zh);
+    Free(s2w);
+
+    x1=xh+yh*32; y1=yh-xh*32; z1=0;
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    x2=xh-yh*32; y2=yh+xh*32; z2=0;
+    (*dc->transform)(dc,&x2,&y2,&z2);
+    DCClipLine(dc,&x1,&y1,&x2,&y2);
+
+    MemSet(p,0,sizeof(p));
+    if (x2<x1) {
+      SwapI64(&x1,&x2);
+      SwapI64(&y1,&y2);
+    }
+    if (!x1 && x2==dc->width-1) {
+      p[0].x=0;
+      p[0].y=0;
+      p[1].x=dc->width-1;
+      p[1].y=0;
+      p[2].x=dc->width-1;
+      p[2].y=y2;
+      p[3].x=0;
+      p[3].y=y1;
+      if (rolled_over)
+        dc->color=ground_color;
+      else
+        dc->color=LTCYAN;
+      GrFillPoly3(dc,4,p);
+      p[0].y=dc->height-1;
+      p[1].y=dc->height-1;
+      if (rolled_over)
+        dc->color=LTCYAN;
+      else
+        dc->color=ground_color;
+      GrFillPoly3(dc,4,p);
+    } else {
+      if (y2<y1) {
+        SwapI64(&x1,&x2);
+        SwapI64(&y1,&y2);
+      }
+      if (!y1 && y2==dc->height-1) {
+        p[0].x=0;
+        p[0].y=0;
+        p[1].x=0;
+        p[1].y=dc->height-1;
+        p[2].x=x2;
+        p[2].y=dc->height-1;
+        p[3].x=x1;
+        p[3].y=0;
+        if (x1<x2 ^^ rolled_over)
+          dc->color=ground_color;
+        else
+          dc->color=LTCYAN;
+        GrFillPoly3(dc,4,p);
+        p[0].x=dc->width-1;
+        p[1].x=dc->width-1;
+        if (x1<x2 ^^ rolled_over)
+          dc->color=LTCYAN;
+        else
+          dc->color=ground_color;
+        GrFillPoly3(dc,4,p);
+      } else
+        DCFill(dc,LTCYAN); //Not correct.
+    }
+  }
+
+  dc->depth_buf=old_db;
+}
+
+U0 Core0Talons()
+{
+  CDC *dc=DCAlias(main_dc,Fs);
+  I64 i,xx,yy,elev,height,cx=Fs->pix_width>>1,cy=Fs->pix_height>>1;
+  F64 min_strip_width,tt;
+
+  update_jiffy_limit=cnts.jiffies+JIFFY_FREQ/40;
+
+  xx=x/(MAP_SCALE*COORDINATE_SCALE);
+  yy=y/(MAP_SCALE*COORDINATE_SCALE);
+  if (0<=xx<MAP_WIDTH && 0<=yy<MAP_HEIGHT)
+    elev=elevations[yy][xx];
+  else
+    elev=I64_MAX;
+
+  height=z/COORDINATE_SCALE-elev;
+  if (height<0 && elev>WATER_ELEVATION*MAP_SCALE && !game_tf) {
+    music.mute=TRUE;
+    Beep;
+    game_tf=tS;
+    music.mute=FALSE;
+  }
+
+  DrawHorizon(dc);
+
+  if (game_tf) {
+    tt=game_tf-game_t0;
+    if (Blink) {
+      dc->color=RED;
+      GrPrint(dc,(Fs->pix_width-9*FONT_WIDTH)/2,
+            (Fs->pix_height-FONT_HEIGHT)/2,"Game Over");
+    }
+  } else {
+    DCDepthBufRst(dc);
+    mp.update_not_done_flags=1<<mp_cnt-1;
+    MPDrawIt(Fs,dc);
+    while (mp.update_not_done_flags)
+      Sleep(1);
+
+    min_strip_width=F64_MAX;
+    for (i=0;i<mp_cnt;i++)
+      min_strip_width=Min(min_strip_width,32.0*mp.strip_width[i]/(i+32.0));
+    strip_height=ClampI64(
+          strip_height*Clamp(0.25*min_strip_width/strip_height,0.9,1.1),
+          64,1024);
+
+    tt=tS-game_t0;
+    if (tt<5.0 && Blink) {
+      dc->color=WHITE;
+      GrPrint(dc,(Fs->pix_width-13*FONT_WIDTH)/2,
+            (Fs->pix_height-FONT_HEIGHT)/2-4*FONT_HEIGHT,"Catch 10 Fish");
+    }
+  }
+
+  dc->thick=2;
+  if (game_tf && fish_left)
+    dc->color=WHITE;
+  else
+    dc->color=BLACK;
+  dc->flags&=~DCF_TRANSFORMATION;
+  GrLine3(dc,cx+5,cy,0,cx-5,cy,0);
+  GrLine3(dc,cx,cy+5,0,cx,cy-5,0);
+  if (invert_pitch)
+    GrPrint(dc,0,0,"Pitch:%5.1f Roll:%5.1f Heading:%5.1f "
+          "Height:%5d [Core Strip:%3d]",
+          pitch*180/pi,Wrap(roll+pi)*180/pi,Wrap(heading+pi,0)*180/pi,
+          height,strip_height);
+  else
+    GrPrint(dc,0,0,"Pitch:%5.1f Roll:%5.1f Heading:%5.1f "
+          "Height:%5d [Core Strip:%3d]",
+          pitch*180/pi,roll*180/pi,heading*180/pi,height,strip_height);
+  GrPrint(dc,0,FONT_HEIGHT,"Fish Remaining:%d Time:%3.2f Best:%3.2f",
+        fish_left,tt,best_score);
+
+  //We made an alias of this we don't want freed.
+  dc->depth_buf=NULL;
+  DCDel(dc);
+  Refresh;
+}
+
+
+Obj *FishFind(I64 x1,I64 y1,I64 *_dd)
+{
+  I64 dd,best_dd=I64_MAX;
+  Obj *res=NULL,*tmpo;
+  Panel *tmpp=panel_head;
+  while (tmpp) {
+    tmpo=tmpp->next_obj;
+    while (tmpo!=&tmpp->next_obj) {
+      if (tmpo->fish) {
+        dd=SqrI64(tmpo->p.x-x1)+SqrI64(tmpo->p.y-y1);
+        if (dd<best_dd) {
+          best_dd=dd;
+          res=tmpo;
+        }
+      }
+      tmpo=tmpo->next;
+    }
+    tmpp=tmpp->next;
+  }
+  *_dd=best_dd;
+  return res;
+}
+
+#define ANIMATE_MS      10
+
+U0 AnimateTask(I64)
+{//Steadily moves the airplane fwd.
+  I64 i,*s2w,x1,y1,z1,dx,dy,dz,dd;
+  F64 t0=tS,ms,theta,d;
+  Obj *tmpo;
+  Bird  *tmpb;
+  while (TRUE) {
+    ms=1000*(tS-t0);
+    t0=tS;
+    if (!game_tf) {
+//Scrn to world coordinates
+      s2w=Mat4x4IdentNew;
+      Mat4x4RotZ(s2w,-roll);
+      Mat4x4RotX(s2w,-phi);
+      Mat4x4RotZ(s2w,-heading);
+
+      dx=0;dy=0;dz=1<<16;
+      Mat4x4MulXYZ(s2w,&dx,&dy,&dz);
+      x-=speed*ms*COORDINATE_SCALE*dx/1<<16;
+      y-=speed*ms*COORDINATE_SCALE*dy/1<<16;
+      z-=speed*ms*COORDINATE_SCALE*dz/1<<16;
+      Free(s2w);
+      x1=x/COORDINATE_SCALE; y1=y/COORDINATE_SCALE; z1=z/COORDINATE_SCALE;
+      if (z1<(WATER_ELEVATION+3)*MAP_SCALE) {
+        if (z1<WATER_ELEVATION*MAP_SCALE) {
+          z=WATER_ELEVATION*MAP_SCALE*COORDINATE_SCALE;
+          if (invert_pitch) {
+            if (pitch<-pi/8)
+              phi+=ms/1000.0*Sign(3*pi/8-phi);
+          } else if (pitch<-pi/8)
+            phi+=ms/1000.0*Sign(-3*pi/8-phi);
+          WrapAngles;
+        }
+        speed=1.0;
+        if (rolled_over || !(tmpo=FishFind(x1,y1,&dd)))
+          claws_down=0;
+        else {
+          d=Sqrt(dd);
+          x1-=tmpo->p.x;
+          y1-=tmpo->p.y;
+          theta=ACos((dx*x1+dy*y1)/(d*1<<16));
+          if (theta>0 && d<MAP_SCALE*4)
+            claws_down=Saw(d,MAP_SCALE*4);
+          else
+            claws_down=0.01;
+          if (d<MAP_SCALE*2) {
+            if (!--fish_left) {
+              game_tf=tS;
+              if (game_tf-game_t0<best_score)
+                best_score=game_tf-game_t0;
+            }
+            QueRem(tmpo);
+            Free(tmpo);
+            music.mute=TRUE;
+            Snd(74); Sleep(200); Snd;
+            music.mute=FALSE;
+          }
+        }
+      } else {
+        claws_down=0;
+        if (-pi/4<=phi<=pi/4)
+          speed+=0.0005;
+        else if (-3*pi/4<=phi<=3*pi/4)
+          speed+=0.0001;
+        else
+          speed-=0.0001;
+        speed=Clamp(speed+(0.0005-0.0002*Abs(phi)/(pi/4)),0.1,5.0);
+      }
+
+      for (i=0;i<mp_cnt;i++) {
+        tmpb=b_head[i].next;
+        while (tmpb!=&b_head[i]) {
+          tmpb->p.x+=10*ms/1000*MAP_SCALE*Cos(tmpb->theta);
+          tmpb->p.y+=10*ms/1000*MAP_SCALE*Sin(tmpb->theta);
+          tmpb->p.z=BIRD_ELEVATION*MAP_SCALE+
+                elevations[tmpb->p.y/MAP_SCALE][tmpb->p.x/MAP_SCALE];
+          tmpb->theta+=2*pi*ms/1000/10;
+          tmpb=tmpb->next;
+        }
+      }
+    }
+    Refresh;
+  }
+}
+
+U0 MPEnd()
+{
+  update_jiffy_limit=0;
+  mp.app_not_done_flags=1<<mp_cnt-1-1;
+  mp.app_done=TRUE;
+//Wait for all cores to exit
+  while (mp.app_not_done_flags)
+    Sleep(1);
+}
+
+U0 TaskEndCB()
+{
+  MPEnd;
+  Exit;
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5eCGFsD4A5e.C4sG5eGDqCDeGsGG4qG");
+    Play("5eCGFsD4A5e.C4sG5eGDqCDeGsGG4qG");
+    Play("5eGECGC4A5FCsC4B5C4B5e.GsG4qGB");
+    Play("5eGECGC4A5FCsC4B5C4B5e.GsG4qGB");
+  }
+}
+
+U0 PreInit()
+{
+  I64 i,*r=Mat4x4IdentNew;
+  Mat4x4Scale(r,10.0);
+  for (i=0;i<LS_TYPES;i++)
+    landscape_large_imgs[i]=SpriteTransform(landscape_small_imgs[i],r);
+  Free(r);
+}
+
+U0 PostCleanUp()
+{
+  I64 i;
+  for (i=0;i<LS_TYPES;i++)
+    Free(landscape_large_imgs[i]);
+}
+
+U0 Init()
+{
+  I64 i,xx,yy;
+  Bird *tmpb;
+
+  main_dc=DCNew(GR_WIDTH,GR_HEIGHT);
+  critical_section_flag=0;
+  game_tf=0;
+  fish_left=10;
+
+  MemSet(&mp,0,sizeof(MPCtrl));
+  InitMap;
+  DCDepthBufAlloc(main_dc);
+
+  strip_height=128;
+
+  phi   =-90.0*pi/180.0;
+  roll  =0;
+  heading=0;
+  speed =2.5;
+  claws_down=0;
+  WrapAngles;
+
+  x=MAP_WIDTH>>1 *COORDINATE_SCALE*MAP_SCALE;
+  y=MAP_HEIGHT>>1*COORDINATE_SCALE*MAP_SCALE;
+  z=64           *COORDINATE_SCALE*MAP_SCALE;
+
+  xx=x/(MAP_SCALE*COORDINATE_SCALE);
+  yy=y/(MAP_SCALE*COORDINATE_SCALE);
+  z+=elevations[yy][xx]*COORDINATE_SCALE;
+
+  for (i=0;i<mp_cnt;i++)
+    QueInit(&b_head[i]);
+
+  for (i=0;i<B_NUM;i++) {
+    tmpb=MAlloc(sizeof(Bird));
+    tmpb->p.x=Rand*MAP_WIDTH*MAP_SCALE;
+    tmpb->p.y=Rand*MAP_HEIGHT*MAP_SCALE;
+    tmpb->p.z=BIRD_ELEVATION*MAP_SCALE+
+          elevations[tmpb->p.y/MAP_SCALE][tmpb->p.x/MAP_SCALE];
+    tmpb->theta=2*pi*Rand;
+    QueIns(tmpb,b_head[i%mp_cnt].last);
+  }
+
+  for (i=1;i<mp_cnt;i++)
+    Spawn(&CoreAPTalonsTask,Fs,"AP Talons",i);
+  Fs->task_end_cb=&TaskEndCB;
+  game_t0=tS;
+}
+
+U0 CleanUp()
+{
+  I64 i;
+  Panel *tmpp=panel_head,*tmpp1;
+  MPEnd;
+  while (tmpp) {
+    tmpp1=tmpp->next;
+    QueDel(&tmpp->next_obj);
+    Free(tmpp->pts);
+    Free(tmpp);
+    tmpp=tmpp1;
+  }
+  for (i=0;i<mp_cnt;i++) {
+    QueDel(&b_head[i]);
+    QueInit(&b_head[i]);
+  }
+  DCDel(main_dc);
+}
+
+U0 Talons()
+{
+  I64 ch,sc;
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Down(,,SC_CURSOR_UP);"
+        "  Up(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  "Initializing...\n";
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  PreInit;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try //in case <CTRL-ALT-c> is pressed.
+    do {
+      if (ScanKey(&ch,&sc)) {
+        switch (ch) {
+          case 0:
+            switch (sc.u8[0]) {
+              start:
+                case SC_CURSOR_DOWN:
+                  phi-=CTRLS_SCALE*Cos(roll);
+                  heading-=CTRLS_SCALE*Sin(roll)*Sin(phi);
+                  break;
+                case SC_CURSOR_UP:
+                  phi+=CTRLS_SCALE*Cos(roll);
+                  heading+=CTRLS_SCALE*Sin(roll)*Sin(phi);
+                  break;
+                case SC_CURSOR_RIGHT:
+                  roll+=CTRLS_SCALE;
+                  break;
+                case SC_CURSOR_LEFT:
+                  roll-=CTRLS_SCALE;
+                  break;
+              end:
+                WrapAngles;
+            }
+            break;
+          case '\n':
+            Fs->draw_it=NULL;
+            CleanUp;
+            Refresh;
+            Init;
+            Fs->draw_it=&DrawIt;
+            break;
+        }
+      } else
+        Core0Talons;
+    } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  PostCleanUp;
+  MenuPop;
+  RegWrite("TempleOS/Talons","F64 best_score=%5.4f;\n",best_score);
+}
+
+Talons;
+
+ diff --git a/public/Wb/Demo/Games/TheDead.HC.HTML b/public/Wb/Demo/Games/TheDead.HC.HTML new file mode 100755 index 0000000..b8ff650 --- /dev/null +++ b/public/Wb/Demo/Games/TheDead.HC.HTML @@ -0,0 +1,218 @@ + + + + + + + + + + + +
+//These are the coordinates of the player.
+I64 x=0,y=GR_HEIGHT/2;
+
+/*This is a FIFO (first-in first-out) data structure
+which keeps track of bullets.  When a new bullet is
+fired, the bullets_in val is increased by one.
+When a bullet expires, the bullets_out val is increased
+by one.  The in and out vals loop-around, back to
+the start of the arrays.  It is known as a ring-buffer.
+*/
+#define BULLETS_NUM 32
+I64 bullets_in=0,bullets_out=0,bx[BULLETS_NUM],by[BULLETS_NUM];
+
+//This is a fifo which keeps track of the bad guys.
+#define DEAD_NUM 32
+I64 dead_in=0,dead_out=0,gx[DEAD_NUM],gy[DEAD_NUM];
+Bool g_dead[DEAD_NUM];
+
+/*This is a sprite created and edited by pressing
+<CTRL-r>.  When created, they are assigned
+a num.  Press <CTRL-t>, to see the hidden DolDoc
+place holder for the sprite.  The text in quotes
+can be set to whatever you want or nothing,
+but the ending num can't be changed.  It
+is controled by the editor.
+*/
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+ 
+<2>/* Graphics Not Rendered in HTML */
+ 
+ 
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+
+//Called by the Window Mgr system task 30fps.
+//The task arg is the task owning the window.
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j;
+//<CTRL-t> now to see the DolDoc place holder
+  //where the sprite num is encoded. $IB...$ stands
+  //for "insert ptr to binary object".
+  Sprite3(dc,x,y,0,<1>);
+
+  i=bullets_out;
+  while (i!=bullets_in) {
+    j=i++ &(BULLETS_NUM-1);
+    GrLine(dc,bx[j],by[j],bx[j]-2,by[j]);
+  }
+  i=dead_out;
+  while (i!=dead_in) {
+    j=i++ &(BULLETS_NUM-1);
+    if (!g_dead[j]) {
+      if (gx[j]%10>4)
+        Sprite3(dc,gx[j],gy[j],0,<2>);
+      else
+        Sprite3(dc,gx[j],gy[j],0,<3>);
+    }
+  }
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"If you aspire to making games,");
+  GrPrint(dc,0,FONT_HEIGHT,"you must learn to make-up rules.");
+}
+
+U0 SongTask(I64)
+{//Randomly generate (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5qDqDsDCDC4etB5C4B5qCqCqCqCqDqDsDCDC4etB5C4B5qCqCqCqCqCq"
+          "CsCCCCetCCBeBBeBBqBqBqCqCsCCCCetCCBeBBeBBqBqB");
+  }
+}
+
+U0 TheDead()
+{
+  I64 i,j,i1,j1,k=0,sc=0,ch=0,msg_code,arg1,arg2;
+  Bool gun_on=FALSE;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Fire(,CH_SPACE);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    do {
+      if (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN | 1<<MSG_KEY_UP)) {
+//With keyboard msgs, the two msg args
+        //are the scan code and ascii val for the key.
+        sc=arg2; ch=arg1;
+
+        if (msg_code==MSG_KEY_DOWN) {
+//The low byte of the scan code identifies the key.
+          if (sc.u8[0]==SC_CURSOR_DOWN) {
+            y+=10;
+            if (y>GR_HEIGHT-30)
+              y=GR_HEIGHT-30;
+          } else if (sc.u8[0]==SC_CURSOR_UP) {
+            y-=10;
+            if (y<0)
+              y=0;
+          } else if (sc.u8[0]==SC_CURSOR_RIGHT ||
+                ch==CH_SPACE)
+            gun_on=TRUE;
+        } else if (msg_code==MSG_KEY_UP) {
+          if (sc.u8[0]==SC_CURSOR_RIGHT ||
+                ch==CH_SPACE)
+            gun_on=FALSE;
+        }
+      }
+
+      i=bullets_out;
+      while (i!=bullets_in) {
+        j=i++ &(BULLETS_NUM-1);
+        bx[j]+=5;
+        if (bx[j]>GR_WIDTH)
+          bullets_out++;
+        else {
+          i1=dead_out;
+          while (i1!=dead_in) {
+            j1=i1++ &(DEAD_NUM-1);
+            if (gy[j1]<=by[j]<=gy[j1]+38 &&
+                  gx[j1]<=bx[j]<=gx[j1]+40)
+              g_dead[j1]=TRUE;
+          }
+        }
+      }
+
+      if (gun_on) {
+        j=bullets_in&(BULLETS_NUM-1);
+        bx[j]=x+32;
+        by[j]=y+14;
+        bullets_in++;
+      }
+
+      //Runs one out of four passes through this loop.
+      if (!(k % 4)) {
+        i=dead_out;
+        while (i!=dead_in) {
+          j=i++ &(DEAD_NUM-1);
+          gx[j]-=1;
+          if (gx[j]<25)
+            dead_out++;
+        }
+      }
+
+      //Runs one out of 150 passes through this loop.
+      if (!(k%150)) {
+        j=dead_in&(DEAD_NUM-1);
+        gx[j]=GR_WIDTH-30;
+        gy[j]=RandU32%(GR_HEIGHT-50)+25;
+        g_dead[j]=FALSE;
+        dead_in++;
+      }
+      k++;
+
+      Sleep(10); //Swap this task out for 10 miliseconds.
+    } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+}
+
+TheDead; //Run program when #included
+
+ diff --git a/public/Wb/Demo/Games/TicTacToe.HC.HTML b/public/Wb/Demo/Games/TicTacToe.HC.HTML new file mode 100755 index 0000000..c9a4af8 --- /dev/null +++ b/public/Wb/Demo/Games/TicTacToe.HC.HTML @@ -0,0 +1,156 @@ + + + + + + + + + + + +
+I8  board  [9];
+I64 board_x[9]={150,250,350,150,250,350,150,250,350};
+I64 board_y[9]={150,150,150,250,250,250,350,350,350};
+
+U0 DrawX(CDC *dc,I64 x,I64 y)
+{
+  dc->thick=5;
+  GrLine3(dc,x-20,y-20,0,x+20,y+20,0);
+  GrLine3(dc,x+20,y-20,0,x-20,y+20,0);
+}
+
+U0 DrawO(CDC *dc,I64 x,I64 y)
+{
+  dc->thick=5;
+  GrCircle3(dc,x,y,0,25);
+}
+
+U0 DrawBoard(I64 player)
+{
+  I64 i;
+  CDC *dc=DCAlias;
+  DCFill;
+  dc->thick=5;
+  GrLine3(dc,200,100,0,200,400,0);
+  GrLine3(dc,300,100,0,300,400,0);
+  GrLine3(dc,100,200,0,400,200,0);
+  GrLine3(dc,100,300,0,400,300,0);
+  for (i=0;i<9;i++)
+    switch (board[i]) {
+      case 1:
+        DrawX(dc,board_x[i],board_y[i]);
+        break;
+      case 2:
+        DrawO(dc,board_x[i],board_y[i]);
+        break;
+
+    }
+//ms.pos.x,ms.pos.y are mouse x,y.
+    //ms.lb     is mouse left bttn
+  if (player==1)
+    DrawX(dc,ms.pos.x-Fs->pix_left,ms.pos.y-Fs->pix_top);
+  else
+    DrawO(dc,ms.pos.x-Fs->pix_left,ms.pos.y-Fs->pix_top);
+  DCDel(dc);
+}
+
+U0 TakeTurn(I64 player)
+{
+  I64 i,x=0,y=0;
+  while (!(100<=x<400) || !(100<=y<400) || board[i]) {
+    if (player==1)
+      Beep;
+    else
+      Beep(74);
+    while (!ms.lb) {
+      DrawBoard(player);
+      Refresh;
+    }
+    while (ms.lb) {
+      DrawBoard(player);
+      Refresh;
+    }
+    x=ms.pos.x-Fs->pix_left;
+    y=ms.pos.y-Fs->pix_top;
+    i=(x-100)/100+(y-100)/100*3;
+  }
+  board[i]=player;
+}
+
+Bool CheckWinner(I64 player)
+{
+  if (  player==board[0]==board[1]==board[2] ||
+        player==board[3]==board[4]==board[5] ||
+        player==board[6]==board[7]==board[8] ||
+
+        player==board[0]==board[3]==board[6] ||
+        player==board[1]==board[4]==board[7] ||
+        player==board[2]==board[5]==board[8] ||
+
+        player==board[0]==board[4]==board[8] ||
+        player==board[2]==board[4]==board[6]   )
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 DoGame()
+{
+  I64 moves=0;
+  MemSet(board,0,sizeof(board));
+  while (TRUE) {
+    TakeTurn(1);
+    if (CheckWinner(1)) {
+      Beep;
+      Beep;
+      Beep;
+      break;
+    }
+    if (++moves==9) break;
+
+    TakeTurn(2);
+    if (CheckWinner(2)) {
+      Beep(74);
+      Beep(74);
+      Beep(74);
+      break;
+    }
+    if (++moves==9) break;
+  }
+}
+
+U0 TicTacToe()
+{
+  WinMax;   //Maximize window
+  DocClear; //Clear window text.
+  "$GREEN$CTRL-ALT-c$FG$ to exit.\n";
+  try
+    while (TRUE)
+      DoGame;
+  catch
+    PutExcept;
+  DCFill;
+}
+
+TicTacToe;
+
+ diff --git a/public/Wb/Demo/Games/TreeCheckers.HC.HTML b/public/Wb/Demo/Games/TreeCheckers.HC.HTML new file mode 100755 index 0000000..d2e1b21 --- /dev/null +++ b/public/Wb/Demo/Games/TreeCheckers.HC.HTML @@ -0,0 +1,388 @@ + + + + + + + + + + + +
+U0 InitDefines()
+{
+  I64 w=GR_WIDTH,h=GR_HEIGHT-FONT_HEIGHT,cols,rows,
+        size=PopUpRangeI64(1,9,,"Size\n"),rad=16-size;
+  if (size<0) throw;
+  DefinePrint("UNITS_NUM","%d",4096/SqrI64(rad)&~1);
+  DefinePrint("CIRCLE_RAD","%d",rad);
+  DefinePrint("MOVE_CIRCLES","%d",40/rad);
+
+  cols=(w-8-rad)/(2*rad)&~1-1;
+  DefinePrint("BORDER_X","%d",(w+rad-cols*2*rad)/2);
+
+  rows=(h-8)/(2*rad)&~1;
+  DefinePrint("BORDER_Y","%d",(h-rows*2*rad)/2);
+
+} InitDefines;
+
+class Unit
+{
+  I64 num,x,y,player,link,color;
+  Bool alive,king;
+} u[UNITS_NUM];
+
+CDC *map_dc;
+I64 cur_player,num_alive[2],start_x,start_y,end_x,end_y;
+Bool show_start;
+
+U0 S2Circle(I64 *_x,I64 *_y)
+{
+  I64 i,j;
+  j=(*_y-BORDER_Y)/(CIRCLE_RAD*2);
+  if (j&1)
+    i=(*_x-CIRCLE_RAD-BORDER_X)/(CIRCLE_RAD*2);
+  else
+    i=(*_x-BORDER_X)/(CIRCLE_RAD*2);
+  *_y=j;
+  *_x=i;
+}
+
+U0 Circle2S(I64 *_x,I64 *_y)
+{
+  I64 j=*_y,i=*_x;
+  *_y=j*CIRCLE_RAD*2+CIRCLE_RAD+BORDER_Y;
+  *_x=i*CIRCLE_RAD*2+CIRCLE_RAD+BORDER_X;
+  if (j&1) *_x+=CIRCLE_RAD;
+}
+
+U0 S2W(I64 *_x,I64 *_y)
+{
+  S2Circle(_x,_y);
+  Circle2S(_x,_y);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i;
+  map_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,0,0,map_dc);
+
+  if (cur_player==0) {
+    dc->color=LTCYAN;
+    GrFloodFill(dc,0,0);
+    dc->color=CYAN;
+  } else {
+    dc->color=LTPURPLE;
+    GrFloodFill(dc,0,0);
+    dc->color=PURPLE;
+  }
+  GrPrint(dc,2,2,"Player %d",cur_player+1);
+
+  for (i=0;i<UNITS_NUM;i++)
+    if (u[i].alive) {
+      dc->color=u[i].color;
+      GrFloodFill(dc,u[i].x,u[i].y);
+    }
+  for (i=0;i<UNITS_NUM;i++)
+    if (u[i].alive && !u[i].king) {
+      dc->color=BLACK;
+      GrLine(dc,u[i].x,u[i].y,u[u[i].link].x,u[u[i].link].y);
+      if (Blink) {
+        dc->color=BLUE;
+        dc->thick=6;
+        GrPlot3(dc,(u[i].x+u[u[i].link].x)>>1,(u[i].y+u[u[i].link].y)>>1,0);
+      }
+    }
+  if (show_start) {
+    dc->color=LTRED;
+    GrLine(dc,start_x-4,start_y-4,start_x+4,start_y+4);
+    GrLine(dc,start_x-4,start_y+4,start_x+4,start_y-4);
+    GrLine(dc,start_x,start_y,end_x,end_y);
+  }
+  if ((num_alive[0]==1 || num_alive[1]==1) && Blink(4)) {
+    dc->color=BLACK;
+    GrPrint(dc,(task->pix_width-FONT_WIDTH*9)>>1,
+          (task->pix_height-FONT_HEIGHT)>>1,"Game Over");
+  }
+}
+
+Unit *UnitFind(I64 x,I64 y,I64 player)
+{
+  I64 i,dd,best_dd=I64_MAX;
+  Unit *res=NULL;
+  for (i=0;i<UNITS_NUM;i++) {
+    if (u[i].player==player && u[i].alive) {
+      dd=SqrI64(u[i].x-x)+SqrI64(u[i].y-y);
+      if (dd<best_dd) {
+        best_dd=dd;
+        res=&u[i];
+      }
+    }
+  }
+  return res;
+}
+
+U0 KillsChk(I64 x1,I64 y1,I64 player)
+{
+  I64 i,j,x2,y2,dd;
+  Bool found;
+  for (i=0;i<UNITS_NUM;i++) {
+    if (u[i].player!=player && u[i].alive && !u[i].king) {
+      x2=(u[i].x+u[u[i].link].x)>>1;
+      y2=(u[i].y+u[u[i].link].y)>>1;
+      dd=SqrI64(x2-x1)+SqrI64(y2-y1);
+      if (dd<=(CIRCLE_RAD+2)*(CIRCLE_RAD+2)) {
+        u[i].alive=FALSE;
+        Snd(62);Sleep(100);Snd;Sleep(25);
+        num_alive[u[i].player]--;
+        do {
+          found=FALSE;
+          for (j=0;j<UNITS_NUM;j++)
+            if (u[j].alive && u[j].player!=player && !u[j].king &&
+                  !u[u[j].link].alive) {
+              found=TRUE;
+              u[j].alive=FALSE;
+              Snd(62);Sleep(100);Snd;Sleep(25);
+              num_alive[u[j].player]--;
+            }
+        } while (found);
+      }
+    }
+  }
+}
+
+Bool UnitMove(Unit *tmpu,I64 x2,I64 y2)
+{
+  I64 i,r,c,r2,c2,x=start_x,y=start_y;
+  S2W(&x2,&y2);
+  c2=x2; r2=y2;
+  S2Circle(&c2,&r2);
+  for (i=0;i<MOVE_CIRCLES+1;i++) {
+    c=x; r=y;
+    S2Circle(&c,&r);
+    if (c==c2 && r==r2) {
+      end_x=tmpu->x=x2;
+      end_y=tmpu->y=y2;
+      return TRUE;
+    }
+    if (r2!=r) {
+      if (r&1) {
+        if (c<c2) c++;
+      } else {
+        if (c>c2) c--;
+      }
+    }
+    if (r2>r) {
+      x=c; y=++r;
+      Circle2S(&x,&y);
+    } else if (r2<r) {
+      x=c; y=--r;
+      Circle2S(&x,&y);
+    } else if (c2>c) {
+      x=++c; y=r;
+      Circle2S(&x,&y);
+    } else if (c2<c) {
+      x=--c; y=r;
+      Circle2S(&x,&y);
+    }
+  }
+  return FALSE;
+}
+
+CDC *DrawHexMap(I64 *_w,I64 *_h)
+{
+  CDC *dc=DCNew(*_w,*_h);
+  I64 i,j,x,y;
+  *_w=(dc->width-BORDER_X*2-CIRCLE_RAD)/(CIRCLE_RAD*2);
+  *_h=(dc->height-BORDER_Y*2)/(CIRCLE_RAD*2);
+  DCFill(dc,WHITE);
+  dc->color=LTGRAY;
+  for (j=0;j<*_h;j++) {
+    for (i=0;i<*_w;i++) {
+      x=i*CIRCLE_RAD*2+BORDER_X+CIRCLE_RAD;
+      y=j*CIRCLE_RAD*2+BORDER_Y+CIRCLE_RAD;
+      if (j&1) x+=CIRCLE_RAD;
+      S2W(&x,&y);
+      GrCircle(dc,x,y,CIRCLE_RAD);
+    }
+  }
+  *_w*=CIRCLE_RAD*2;
+  *_h*=CIRCLE_RAD*2;
+  return dc;
+}
+
+U0 Init()
+{
+  I64 i,j,j1,j2,dd,best_dd,best,w=Fs->pix_width,h=Fs->pix_height;
+
+  map_dc=DrawHexMap(&w,&h);
+  cur_player=0;
+
+  for (i=0;i<UNITS_NUM/2;i++) {
+    u[i].num=i;
+    u[i+UNITS_NUM/2].num=i+UNITS_NUM/2;
+
+ti_restart:
+    u[i].y=FloorI64(RandU32%h,CIRCLE_RAD*2)+CIRCLE_RAD;
+    u[i+UNITS_NUM/2].y=h-1-u[i].y;
+    j1=u[i].y/(CIRCLE_RAD*2);
+    j2=u[i+UNITS_NUM/2].y/(CIRCLE_RAD*2);
+    u[i].y+=BORDER_Y;
+    u[i+UNITS_NUM/2].y+=BORDER_Y;
+
+    if (!i) {
+      u[i].x=CIRCLE_RAD;
+      if (j1&1)
+        goto ti_restart;
+    } else
+      u[i].x=FloorI64(RandU32%((w-CIRCLE_RAD*2*2)/2),CIRCLE_RAD*2)+CIRCLE_RAD;
+    u[i+UNITS_NUM/2].x=w-1-u[i].x;
+
+    if (j1&1)
+      u[i].x+=CIRCLE_RAD;
+    if (j2&1)
+      u[i+UNITS_NUM/2].x+=CIRCLE_RAD;
+    u[i].x+=BORDER_X;
+    u[i+UNITS_NUM/2].x+=BORDER_X;
+
+    S2W(&u[i].x,&u[i].y);
+    S2W(&u[i+UNITS_NUM/2].x,&u[i+UNITS_NUM/2].y);
+
+    u[i].player=0;
+    u[i+UNITS_NUM/2].player=1;
+
+    u[i].alive=TRUE;
+    u[i+UNITS_NUM/2].alive=TRUE;
+
+    if (!i) {
+      u[i].color=LTCYAN;
+      u[i+UNITS_NUM/2].color=LTPURPLE;
+      u[i].king=TRUE;
+      u[i+UNITS_NUM/2].king=TRUE;
+    } else {
+      u[i].color=CYAN;
+      u[i+UNITS_NUM/2].color=PURPLE;
+      u[i].king=FALSE;
+      u[i+UNITS_NUM/2].king=FALSE;
+    }
+  }
+  for (i=0;i<UNITS_NUM/2;i++) {
+    if (!u[i].king) {
+      best_dd=I64_MAX;
+      for (j=0;j<UNITS_NUM/2;j++) {
+        if (i!=j) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if ((u[j].x<u[i].x || u[j].king) && dd<best_dd ) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].link=best;
+      u[i+UNITS_NUM/2].link=best+UNITS_NUM/2;
+    }
+  }
+  num_alive[0]=UNITS_NUM/2;
+  num_alive[1]=UNITS_NUM/2;
+}
+
+U0 CleanUp()
+{
+  DCDel(map_dc);
+}
+
+U0 TreeCheckers()
+{
+  I64 msg_code,arg1,arg2,ch,sc;
+  Unit *tmpu;
+
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  PopUpOk("Step on the link mid points.\n");
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU;
+  try {
+cn_start:
+    Init;
+    tmpu=NULL;
+    show_start=FALSE;
+    Fs->draw_it=&DrawIt;
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+      switch (msg_code) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              goto cn_start;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto cn_done;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          if (num_alive[0]>1 && num_alive[1]>1) {
+            tmpu=UnitFind(arg1,arg2,cur_player);
+            end_x=start_x=tmpu->x;
+            end_y=start_y=tmpu->y;
+            show_start=TRUE;
+          }
+          break;
+        case MSG_MS_MOVE:
+          if (tmpu)
+            UnitMove(tmpu,arg1,arg2);
+          break;
+        case MSG_MS_L_UP:
+          UnitMove(tmpu,arg1,arg2);
+          KillsChk(tmpu->x,tmpu->y,cur_player);
+          show_start=FALSE;
+          tmpu=NULL;
+          cur_player=1-cur_player;
+          break;
+      }
+    }
+cn_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+TreeCheckers;
+
+ diff --git a/public/Wb/Demo/Games/Varoom.HC.HTML b/public/Wb/Demo/Games/Varoom.HC.HTML new file mode 100755 index 0000000..fc78362 --- /dev/null +++ b/public/Wb/Demo/Games/Varoom.HC.HTML @@ -0,0 +1,734 @@ + + + + + + + + + + + +
+
+
+
+
+
+    <1>/* Graphics Not Rendered in HTML */
+
+
+
+    <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+    <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                 <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                 <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+RegDft("TempleOS/Varoom","F64 best_score=9999;\n");
+RegExe("TempleOS/Varoom");
+
+F64 distance,t0,tf;
+Bool game_over;
+
+#define BORDER          7500
+#define RADIUS          10000
+#define WIDTH           2000
+#define SHOULDER        200
+#define D_theta         (2*pi/360)   //Curve track slice is one degree.
+#define D_S             (2*pi*RADIUS/360) //Straight track is degree at 10000.
+#define DIPS            5
+#define DIP_DEPTH       50
+class Track
+{
+  Track *next,*last;
+  I32 num;
+  CColorROPU16 c,pad;
+  I64 x,z;
+  F64 theta,d;
+  CD3I32 left[4],center[4],right[4];
+} track_head,
+  *track_start[MP_PROCESSORS_NUM],*track_end[MP_PROCESSORS_NUM];
+
+CDC *track_map;
+#define MAP_BITS        9
+I64 t_minx,t_maxx,t_minz,t_maxz;
+
+#define BUSHES_NUM      512
+class Bush
+{
+  CD3I32 p;
+  Bool sym,pad[3];
+  U8 *img;
+} b[BUSHES_NUM];
+
+#define CARS_NUM        8
+class Car
+{
+  CD3I32 p;
+  F64 theta,dtheta,speed;
+  U8 *img;
+  Track *t;
+} c[CARS_NUM];
+
+I64 DipY(I64 x,I64 z)
+{
+  F64 m,a;
+  R2P(&m,&a,x,z);
+  return DIP_DEPTH*m*Cos(DIPS*a)/RADIUS;
+}
+
+#define CAR_LENGTH      400
+
+F64 Diptheta(I64 x,I64 z,F64 theta)
+{
+  F64 y_front,y_back;
+  y_front=DipY(x-CAR_LENGTH/2*Cos(theta),z-CAR_LENGTH/2*Sin(theta));
+  y_back =DipY(x+CAR_LENGTH/2*Cos(theta),z+CAR_LENGTH/2*Sin(theta));
+  return ASin((y_front-y_back)/CAR_LENGTH);
+}
+
+Track *TrackFind(Track *_tmpt,I64 x,I64 z)
+{
+  Track *res=_tmpt,*tmpt;
+  I64 dd,best=SqrI64(res->x-x)+SqrI64(res->z-z);
+
+  tmpt=_tmpt;
+  while (TRUE) {
+    tmpt=tmpt->next;
+    if (tmpt==&track_head)
+      tmpt=tmpt->next;
+    dd=SqrI64(tmpt->x-x)+SqrI64(tmpt->z-z);
+    if (dd<best) {
+      best=dd;
+      res=tmpt;
+    } else
+      break;
+  }
+  tmpt=_tmpt;
+  while (TRUE) {
+    tmpt=tmpt->last;
+    if (tmpt==&track_head)
+      tmpt=tmpt->last;
+    dd=SqrI64(tmpt->x-x)+SqrI64(tmpt->z-z);
+    if (dd<best) {
+      best=dd;
+      res=tmpt;
+    } else
+      break;
+  }
+  return res;
+}
+
+U0 TrackSlice(F64 *_x,F64 *_z,F64 theta,F64 d)
+{
+  F64 x=*_x,z=*_z,c=Cos(theta),s=Sin(theta),dx=d*s,dz=-d*c;
+  Track *tmpt,*last=track_head.last;
+  if (last==&track_head)
+    last=NULL;
+
+  tmpt=CAlloc(sizeof(Track));
+  if (last) {
+    MemCpy(&tmpt->center[0],&last->center[3],sizeof(CD3I32));
+    MemCpy(&tmpt->center[1],&last->center[2],sizeof(CD3I32));
+  }
+  tmpt->center[2].x=x+(WIDTH/2)*c+dx;
+  tmpt->center[2].z=z+(WIDTH/2)*s+dz;
+  tmpt->center[2].y=DipY(tmpt->center[2].x,tmpt->center[2].z);
+  tmpt->center[3].x=x-(WIDTH/2)*c+dx;
+  tmpt->center[3].z=z-(WIDTH/2)*s+dz;
+  tmpt->center[3].y=DipY(tmpt->center[3].x,tmpt->center[3].z);
+
+  if (last) {
+    MemCpy(&tmpt->left[0],&last->left[3],sizeof(CD3I32));
+    MemCpy(&tmpt->left[1],&last->left[2],sizeof(CD3I32));
+  }
+  tmpt->left[2].x=x-(WIDTH/2)*c+dx;
+  tmpt->left[2].z=z-(WIDTH/2)*s+dz;
+  tmpt->left[2].y=DipY(tmpt->left[2].x,tmpt->left[2].z);
+  tmpt->left[3].x=x-(WIDTH/2+SHOULDER)*c+dx;
+  tmpt->left[3].z=z-(WIDTH/2+SHOULDER)*s+dz;
+  tmpt->left[3].y=DipY(tmpt->left[3].x,tmpt->left[3].z);
+
+  if (last) {
+    MemCpy(&tmpt->right[0],&last->right[3],sizeof(CD3I32));
+    MemCpy(&tmpt->right[1],&last->right[2],sizeof(CD3I32));
+  }
+  tmpt->right[2].x=x+(WIDTH/2+SHOULDER)*c+dx;
+  tmpt->right[2].z=z+(WIDTH/2+SHOULDER)*s+dz;
+  tmpt->right[2].y=DipY(tmpt->right[2].x,tmpt->right[2].z);
+  tmpt->right[3].x=x+(WIDTH/2)*c+dx;
+  tmpt->right[3].z=z+(WIDTH/2)*s+dz;
+  tmpt->right[3].y=DipY(tmpt->right[3].x,tmpt->right[3].z);
+
+  tmpt->x=x;
+  tmpt->z=z;
+  tmpt->theta=theta;
+  tmpt->num=track_head.last->num+1;
+  tmpt->d  =track_head.last->d+d;
+
+  QueIns(tmpt,track_head.last);
+
+  if (tmpt->num&1)
+    tmpt->c=RED;
+  else
+    tmpt->c=WHITE;
+
+  if (x<t_minx) t_minx=x;
+  if (x>t_maxx) t_maxx=x;
+  if (z<t_minz) t_minz=z;
+  if (z>t_maxz) t_maxz=z;
+
+  x+=dx;
+  *_x=x;
+  z+=dz;
+  *_z=z;
+
+  if (x<t_minx) t_minx=x;
+  if (x>t_maxx) t_maxx=x;
+  if (z<t_minz) t_minz=z;
+  if (z>t_maxz) t_maxz=z;
+}
+
+U0 CoupleEnds()
+{
+  Track *first=track_head.next,*last=track_head.last;
+  MemCpy(&first->center[0],&last->center[3],sizeof(CD3I32));
+  MemCpy(&first->center[1],&last->center[2],sizeof(CD3I32));
+  MemCpy(&first->left[0]  ,&last->left[3]  ,sizeof(CD3I32));
+  MemCpy(&first->left[1]  ,&last->left[2]  ,sizeof(CD3I32));
+  MemCpy(&first->right[0] ,&last->right[3] ,sizeof(CD3I32));
+  MemCpy(&first->right[1] ,&last->right[2] ,sizeof(CD3I32));
+}
+
+U0 InitTrack()
+{
+  I64 i,j;
+  Track *tmpt;
+  F64 x,z,theta,d;
+
+  MemSet(&track_head,0,sizeof(Track));
+  QueInit(&track_head);
+
+  t_minx=t_minz=I64_MAX;
+  t_maxx=t_maxz=I64_MIN;
+
+  x=0; z=0; theta=0;
+  for (d=0;d<6*RADIUS;d+=D_S)
+    TrackSlice(&x,&z,theta,D_S);
+  for (i=0;i<180;i++,theta+=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (d=0;d<RADIUS;d+=D_S)
+    TrackSlice(&x,&z,theta,D_S);
+  for (i=0;i<90;i++,theta-=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (i=0;i<180;i++,theta+=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (i=0;i<90;i++,theta-=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (d=0;d<RADIUS;d+=D_S)
+    TrackSlice(&x,&z,theta,D_S);
+  for (i=0;i<180;i++,theta+=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+
+  CoupleEnds;
+
+  tmpt=track_head.next;
+  for (i=0;i<mp_cnt;i++) {
+    j=(i+1)*track_head.last->num/mp_cnt+1;
+    track_start[i]=tmpt;
+    while (tmpt!=&track_head && tmpt->num!=j)
+      tmpt=tmpt->next;
+    track_end[i]=tmpt;
+  }
+
+  t_minx-=BORDER; t_minz-=BORDER;
+  t_maxx+=BORDER; t_maxz+=BORDER;
+  track_map=DCNew((t_maxx-t_minx+1<<MAP_BITS-1)>>MAP_BITS,
+        (t_maxz-t_minz+1<<MAP_BITS-1)>>MAP_BITS);
+
+  track_map->color=LTGRAY;
+  GrRect(track_map,0,0,track_map->width,track_map->height);
+  tmpt=track_head.next;
+  track_map->color=YELLOW;
+  track_map->thick=3;
+  while (tmpt!=&track_head) {
+    GrPlot3(track_map,track_map->width-(tmpt->x-t_minx)>>MAP_BITS,
+          (tmpt->z-t_minz)>>MAP_BITS,0);
+    tmpt=tmpt->next;
+  }
+}
+
+#define HORIZON_DIP     200
+
+Bool PrepPoly(CD3I32 *p,I64 *r,I64 cx,I64 h,CD3I32 *poly)
+{
+  I64 x,y,z,i;
+  F64 s;
+  for (i=0;i<4;i++) {
+    x=p[i].x-c[0].p.x;
+    y=p[i].y-c[0].p.y;
+    z=p[i].z-c[0].p.z;
+    Mat4x4MulXYZ(r,&x,&y,&z);
+    s=100.0/(AbsI64(z)+50);
+    poly[i].y=s*y+h;
+    if (z<-200 || !(-h<poly[i].y<2*h))
+      return FALSE;
+    poly[i].x=s*x+cx;
+    poly[i].z=z+GR_Z_ALL;
+  }
+  return TRUE;
+}
+
+I64 mp_not_done_flags;
+
+U0 MPUpdateWin(CDC *dc2)
+{
+  CTask *task=dc2->win_task;
+  I64   i,x,y,z,
+        w=task->pix_width,h=task->pix_height,r[16],cx=w>>1;
+  F64   s,dip_theta=Diptheta(c[0].p.x,c[0].p.z,c[0].theta);
+  Car   *tmpc;
+  CD3I32 poly[4];
+  Track *tmpt,*tmpt1;
+  CDC   *dc=DCAlias(gr.dc2,task);
+
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,pi-c[0].theta);
+  Mat4x4RotX(r,75*pi/180-dip_theta);
+
+  dc->depth_buf=dc2->depth_buf;
+
+  //Track
+  tmpt =track_start[Gs->num];
+  tmpt1=track_end  [Gs->num];
+  while (tmpt!=tmpt1) {
+    dc->color=DKGRAY;
+    if (PrepPoly(&tmpt->center,r,cx,h,poly)) {
+      GrFillPoly3(dc,4,poly);
+      dc->color=tmpt->c;
+      if (PrepPoly(&tmpt->left,r,cx,h,poly))
+        GrFillPoly3(dc,4,poly);
+      if (PrepPoly(&tmpt->right,r,cx,h,poly))
+        GrFillPoly3(dc,4,poly);
+    }
+    tmpt=tmpt->next;
+  }
+
+  dc->flags|=DCF_TRANSFORMATION;
+  for (i=Gs->num;i<BUSHES_NUM;i+=mp_cnt) {
+    x=b[i].p.x-c[0].p.x; y=b[i].p.y-c[0].p.y; z=b[i].p.z-c[0].p.z;
+    Mat4x4MulXYZ(r,&x,&y,&z);
+    if (z>0) {
+      s=100.0/(AbsI64(z)+50);
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4Scale(dc->r,s*2);
+      DCMat4x4Set(dc,dc->r);
+      if (b[i].sym) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,s*x+cx,s*y+h,s*x+cx,s*y+h+10);
+      }
+      Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,b[i].img);
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    }
+  }
+  for (i=Gs->num+1;i<CARS_NUM;i+=mp_cnt) {
+    tmpc=&c[i];
+    x=tmpc->p.x-c[0].p.x; y=tmpc->p.y-c[0].p.y; z=tmpc->p.z-c[0].p.z;
+    Mat4x4MulXYZ(r,&x,&y,&z);
+    if (z>0) {
+      s=100.0/(AbsI64(z)+50);
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4Scale(dc->r,s*2);
+      Mat4x4RotX(dc->r,Diptheta(tmpc->p.x,tmpc->p.z,-tmpc->theta));
+      Mat4x4RotY(dc->r,tmpc->theta-c[0].theta);
+      DCMat4x4Set(dc,dc->r);
+      Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,tmpc->img);
+    }
+  }
+  dc->depth_buf=NULL;
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 VRTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  zz=400+*z;
+  if (zz<1) zz=1;
+  *x=400* *x/zz;
+  *y=400* *y/zz;
+  *x+=dc->x;
+  *y+=dc->y;
+  *z+=dc->z;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64   i,x,y,z,
+        w=task->pix_width,
+        h=task->pix_height,r[16],
+        cx=w>>1;
+  F64   s,dip_theta=Diptheta(c[0].p.x,c[0].p.z,c[0].theta);
+  Car   *tmpc=&c[0];
+
+  dc->color=LTCYAN;
+  GrRect(dc,0,0,w,HORIZON_DIP*Sin(dip_theta)+FONT_HEIGHT*4.5);
+
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,pi-c[0].theta);
+  Mat4x4RotX(r,75*pi/180-dip_theta);
+
+  DCDepthBufAlloc(dc);
+
+  //Sun
+  x=c[0].p.x; y=0; z=1000000-c[0].p.z;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  s=100.0/(AbsI64(z)+50);
+  if (y<0) {
+    dc->color=BROWN;
+    GrCircle(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_theta),15);
+    dc->color=YELLOW;
+    GrFloodFill(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_theta));
+  }
+
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPUpdateWin,dc,i);
+  while (mp_not_done_flags)
+    Yield;
+
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,tmpc->dtheta);
+  Mat4x4RotX(r,0.4-8*dip_theta); //Made this up
+  dc->transform=&VRTransform;
+  dc->x=task->pix_width>>1;
+  dc->y=task->pix_height-150;
+  dc->z=GR_Z_ALL;
+  Sprite3Mat4x4B(dc,0,0,-100,c[0].img,r);
+
+  //Map
+  GrBlot(dc,w-track_map->width,h-track_map->height,track_map);
+
+  dc->thick=2;
+  for (i=0;i<CARS_NUM;i++) {
+    if (i)
+      dc->color=LTPURPLE;
+    else
+      dc->color=LTCYAN;
+    GrPlot3(dc,w-(c[i].p.x-t_minx)>>MAP_BITS,
+               h-track_map->height+(c[i].p.z-t_minz)>>MAP_BITS,0);
+  }
+
+  if (game_over) {
+    dc->color=LTRED;
+    if (tf) {
+      s=tf-t0;
+      if (Blink)
+        GrPrint(dc,(w-FONT_WIDTH*14)/2,(h-FONT_HEIGHT)/2,"Game Completed");
+    } else {
+      s=99.9;
+      if (Blink)
+        GrPrint(dc,(w-FONT_WIDTH*9)/2,(h-FONT_HEIGHT)/2,"Game Over");
+    }
+  } else
+    s=tS-t0;
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"%0.1f%% Time:%0.2f Best:%0.2f",
+        100.0*distance/track_head.last->d,s,best_score);
+}
+
+U0 AnimateTask(I64)
+{
+  Car  *tmpc;
+  I64 i,x,z;
+  Bool on_track;
+  Track *tmpt,*tmpt2;
+  while (TRUE) {
+    if (!game_over)
+      Snd(12.0*Log2(c[0].speed/500+0.7));
+    else
+      Snd;
+    for (i=0;i<CARS_NUM;i++) {
+      tmpc=&c[i];
+      tmpc->p.x-=0.01*tmpc->speed*Cos(tmpc->theta-pi/2);
+      tmpc->p.z+=0.01*tmpc->speed*Sin(tmpc->theta-pi/2);
+      tmpt=TrackFind(tmpc->t,tmpc->p.x,tmpc->p.z);
+      if (i) {
+        if (tmpt!=tmpc->t) {
+          tmpt2=tmpt->next;
+          if (tmpt2==&track_head)
+            tmpt2=tmpt2->next;
+          tmpc->theta=Arg(-tmpt2->z+tmpc->p.z,-tmpt2->x+tmpc->p.x);
+        }
+      } else {
+        tmpc->theta+=0.01*tmpc->dtheta;
+        x=track_map->width-(tmpc->p.x-t_minx)>>MAP_BITS;
+        z=(tmpc->p.z-t_minz)>>MAP_BITS;
+        if (GrPeek(track_map,x,z)!=YELLOW) {
+          on_track=FALSE;
+          tmpc->speed-=0.01*tmpc->speed;
+          if (tmpc->speed<0) tmpc->speed=0;
+        } else
+          on_track=TRUE;
+      }
+      tmpc->t=tmpt;
+      tmpc->p.y=DipY(tmpc->p.x,tmpc->p.z);
+    }
+    if (!game_over && on_track) {
+      for (i=1;i<CARS_NUM;i++)
+        if (D3I32DistSqr(&c[i].p,&c[0].p)<CAR_LENGTH>>1*CAR_LENGTH>>1) {
+          game_over=TRUE;
+          Noise(500,22,34);
+          Sleep(500);
+          break;
+        }
+      if (!game_over) {
+        distance+=0.01*c[0].speed;
+        if (distance>track_head.last->d&& c[0].t->num<track_head.last->num>>1) {
+          tf=tS;
+          game_over=TRUE;
+          Beep;
+          if (tf-t0<best_score) {
+            best_score=tf-t0;
+            Beep;
+          }
+        }
+      }
+    }
+    Sleep(10);
+  }
+}
+
+U8 *imgs[8]={<1>,<1>,<2>,<2>,<3>,<4>,<4>,<4>};
+
+
+U0 InitBushes()
+{
+  Bush *tmpb;
+  I64 i,j,x,z;
+  track_map->color=LTGREEN;
+  track_map->thick=1;
+  for (i=0;i<BUSHES_NUM;i++) {
+    tmpb=&b[i];
+
+ib_restart:
+    tmpb->p.x=Rand*(t_maxx-t_minx)+t_minx;
+    tmpb->p.z=Rand*(t_maxz-t_minz)+t_minz;
+    x=track_map->width-(tmpb->p.x-t_minx)>>MAP_BITS;
+    z=(tmpb->p.z-t_minz)>>MAP_BITS;
+    for (j=0;j<8;j++)
+      if (GrPeek(track_map,x+gr_x_offsets[j],z+gr_y_offsets[j])!=LTGRAY)
+        goto ib_restart;
+
+    GrPlot(track_map,x,z);
+    tmpb->p.y=DipY(tmpb->p.x,tmpb->p.z);
+    tmpb->sym=RandU16&1;
+    tmpb->img=imgs[i&7];
+  }
+}
+
+
+U0 Init()
+{
+  Car   *tmpc;
+  Track *tmpt;
+  F64   d;
+  I64   i;
+
+  InitTrack;
+  InitBushes;
+  tmpt=track_head.next;
+  for (i=0;i<CARS_NUM;i++) {
+    tmpc=&c[i];
+    tmpc->t=tmpt;
+    tmpc->p.x=tmpt->x;
+    tmpc->p.z=tmpt->z;
+    tmpc->p.y=DipY(tmpc->p.x,tmpc->p.z);
+    tmpc->theta  =-tmpt->theta;
+    tmpc->dtheta=0;
+    if (!i) {
+      tmpc->img=<5>;
+      tmpc->speed=0;
+    } else {
+      tmpc->img=<6>;
+      tmpc->speed=2500.0;
+    }
+    d=(i+1)*track_head.last->d/CARS_NUM;
+    while (tmpt->next!=&track_head && tmpt->d<d)
+      tmpt=tmpt->next;
+  }
+  distance=0;
+  tf=0;
+  t0=tS;
+  game_over=FALSE;
+}
+
+U0 CleanUp()
+{
+  while (mp_not_done_flags)
+    Yield;
+  QueDel(&track_head,TRUE);
+  DCDel(track_map);
+}
+
+U0 Varoom()
+{
+  I64 sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Accelerator(,,SC_CURSOR_UP);"
+        "  Brake(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  try {
+    Fs->text_attr=YELLOW<<4+BLUE;
+    Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+          -WIF_SELF_GRAB_SCROLL-WIF_FOCUS_TASK_MENU;
+    AutoComplete;
+    WinBorder;
+    WinMax;
+    DocCursor;
+    DocClear;
+    Init;
+    Fs->draw_it=&DrawIt;
+    Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+    while (TRUE)
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              c[0].dtheta-=pi/60;
+              break;
+            case SC_CURSOR_RIGHT:
+              c[0].dtheta+=pi/60;
+              break;
+            case SC_CURSOR_UP:
+              c[0].speed+=300;
+              break;
+            case SC_CURSOR_DOWN:
+              c[0].speed-=900;
+              if (c[0].speed<0) c[0].speed=0;
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto vr_done;
+      }
+vr_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/Varoom","F64 best_score=%5.4f;\n",best_score);
+}
+
+Varoom;
+
+ diff --git a/public/Wb/Demo/Games/Wenceslas.HC.HTML b/public/Wb/Demo/Games/Wenceslas.HC.HTML new file mode 100755 index 0000000..279f923 --- /dev/null +++ b/public/Wb/Demo/Games/Wenceslas.HC.HTML @@ -0,0 +1,623 @@ + + + + + + + + + + + +
+RegDft("TempleOS/Wenceslas","F64 best_score=9999;\n");
+RegExe("TempleOS/Wenceslas");
+
+#define BORDER          5
+#define KING_STEP       6
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */  //See ::/Apps/GrModels for making 3D men.
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+ 
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+        <9>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+        <11>/* Graphics Not Rendered in HTML */
+
+
+U8 *king_imgs[4]={<2>,<1>,<2>,<3>};
+U8 *peasant_imgs[4]={<5>,<4>,<5>,<6>};
+
+
+#define TREES_NUM       8
+class Tree
+{
+  U16 x,y;
+  I64 fire_frame_idx;
+} trees[TREES_NUM];
+
+U64 snow_x,snow_y,new_snow_mS;
+#define SNOW_TILE_SIZE  128
+CDC *snow_tile;
+
+I64 king_x,king_y,king_mS,king_phase,
+    not_stopped_cnt;
+F64 king_timeout,king_theta,t0,tf,door_open_t0;
+I64 animate_mS,animate_phase;
+
+#define PEASANTS_NUM    10
+class Peasant
+{
+  Peasant *next,*last;
+  F64 x,y,theta,door_opened_t0;
+  Bool stopped;
+} peasant_head;
+
+class Step
+{
+  Step *next,*last;
+  U16 x,y;
+  F64 t0;
+} step_head,king_step_head;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 r[16],i,w=task->pix_width,h=task->pix_height,x,y;
+  U8 *img,*tmps;
+  Step *tmpst;
+  Peasant *tmpp;
+  F64 tt;
+
+  dc->thick=1;
+  for (i=0;i<TREES_NUM;i++) {
+    if (trees[i].y<=h/2) {//Draw trees behind house
+      if (trees[i].fire_frame_idx) {
+        if (trees[i].fire_frame_idx++&1)
+          img=<8>;
+        else
+          img=<9>;
+      } else
+        img=<7>;
+      Sprite3(dc,trees[i].x,trees[i].y,0,img);
+    }
+  }
+
+  Sprite3(dc,w/2,h/2,0,<10>);
+  if (tS<door_open_t0+1.0)
+    Sprite3(dc,w/2,h/2,0,<11>);
+
+  for (i=0;i<TREES_NUM;i++) {
+    if (trees[i].y>h/2) {//Draw trees in front of house
+      if (trees[i].fire_frame_idx) {
+        if (trees[i].fire_frame_idx++&1)
+          img=<8>;
+        else
+          img=<9>;
+      } else
+        img=<7>;
+      Sprite3(dc,trees[i].x,trees[i].y,0,img);
+    }
+  }
+
+  tmpst=step_head.next;
+  while (tmpst!=&step_head) {
+    if (tS-tmpst->t0<2.0)
+      dc->color=DKGRAY;
+    else
+      dc->color=LTGRAY;
+    dc->thick=4;
+    GrPlot3(dc,tmpst->x,tmpst->y,0);
+    tmpst=tmpst->next;
+  }
+
+  DCDepthBufAlloc(dc);
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->thick=1;
+  tmpp=peasant_head.next;
+  while (tmpp!=&peasant_head) {
+    Mat4x4IdentEqu(r);
+    Mat4x4RotY(r,tmpp->theta+pi/2);
+    Mat4x4RotX(r,pi/6);
+    if (tmpp->stopped)
+      Sprite3Mat4x4B(dc,tmpp->x,tmpp->y,GR_Z_ALL,peasant_imgs[0],r);
+    else {
+      tmps=SpriteInterpolate(Saw(animate_mS/250.0,1.0),
+            peasant_imgs[ animate_phase   &3],
+            peasant_imgs[(animate_phase+1)&3]);
+      Sprite3Mat4x4B(dc,tmpp->x,tmpp->y,GR_Z_ALL,tmps,r);
+      Free(tmps);
+    }
+    tmpp=tmpp->next;
+  }
+
+  dc->thick=1;
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,king_theta+pi/2);
+  Mat4x4RotX(r,pi/6);
+  if (tS>king_timeout)
+    Sprite3Mat4x4B(dc,king_x,king_y,GR_Z_ALL,king_imgs[0],r);
+  else {
+    tmps=SpriteInterpolate(Saw(king_mS/250.0,1.0),
+          king_imgs[ king_phase   &3],
+          king_imgs[(king_phase+1)&3]);
+    Sprite3Mat4x4B(dc,king_x,king_y,GR_Z_ALL,tmps,r);
+    Free(tmps);
+  }
+
+  dc->thick=1;
+  dc->color=ROP_MONO|WHITE;
+  for (y=snow_y%SNOW_TILE_SIZE-SNOW_TILE_SIZE;y<=h;y+=SNOW_TILE_SIZE)
+    for (x=snow_x%SNOW_TILE_SIZE-SNOW_TILE_SIZE;x<=w;x+=SNOW_TILE_SIZE)
+      GrBlot(dc,x,y,snow_tile);
+
+  if (tf) {
+    dc->color=LTRED;
+    if (Blink)
+      GrPrint(dc,w/2-(FONT_WIDTH*14)/2,h/2+FONT_HEIGHT,"Game Completed");
+    tt=tf;
+  } else {
+    tt=tS;
+  }
+  dc->color=LTBLUE;
+  GrPrint(dc,0,0,"Freezing Peasants:%d Time:%3.2f Best:%3.2f",
+        not_stopped_cnt,tt-t0,best_score);
+}
+
+U0 StepNew(CTask *task,I64 x,I64 y,F64 theta,Bool left_right,Bool king)
+{
+  Step *tmps;
+
+  if (king) {
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x;
+    tmps->y=y;
+    tmps->t0=tS;
+    QueIns(tmps,king_step_head.last);
+  }
+
+  if (left_right) {
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x-3.5*Sin(theta)+2.0*Cos(theta);
+    tmps->y=y+3.5*Cos(theta)+2.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x-3.5*Sin(theta)+5.0*Cos(theta);
+    tmps->y=y+3.5*Cos(theta)+5.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+  } else {
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x+3.5*Sin(theta)+0.0*Cos(theta);
+    tmps->y=y-3.5*Cos(theta)+0.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x+3.5*Sin(theta)+3.0*Cos(theta);
+    tmps->y=y-3.5*Cos(theta)+3.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+  }
+}
+
+U0 Init()
+{
+  I64 i,min_x,max_x,min_y,max_y,
+        w=Fs->pix_width,h=Fs->pix_height;
+  Peasant *tmpp;
+
+  snow_x=snow_y=0;
+  new_snow_mS=0;
+  snow_tile=DCNew(SNOW_TILE_SIZE,SNOW_TILE_SIZE);
+
+  SpriteExtents(<7>,&min_x,&max_x,&min_y,&max_y);
+  for (i=0;i<TREES_NUM;i++) {
+    trees[i].x=RandU16%(w-2*BORDER-(max_x-min_x+1))+BORDER-min_x;
+    trees[i].y=RandU16%(h-2*BORDER-(max_y-min_y+1))+BORDER-min_y;
+    trees[i].fire_frame_idx=0;
+  }
+
+  QueInit(&step_head);
+  QueInit(&king_step_head);
+
+  SpriteExtents(<12>,&min_x,&max_x,&min_y,&max_y);
+  QueInit(&peasant_head);
+  for (i=0;i<PEASANTS_NUM;i++) {
+    tmpp=MAlloc(sizeof(Peasant));
+    tmpp->x=RandU16%(w-2*BORDER-(max_x-min_x+1))+BORDER-min_x;
+    tmpp->y=RandU16%(h-2*BORDER-(max_y-min_y+1))+BORDER-min_y;
+    tmpp->theta=pi*2*Rand;
+    tmpp->door_opened_t0=0;
+    tmpp->stopped=FALSE;
+    QueIns(tmpp,peasant_head.last);
+  }
+  animate_phase=0;
+  animate_mS=0;
+  king_phase=0;
+  king_mS=0;
+  king_timeout=0;
+  king_x=w/2;
+  king_y=h/2;
+  king_theta=-pi/2;
+  door_open_t0=0;
+  t0=tS;
+  tf=0;
+}
+
+U0 CleanUp()
+{
+  DCDel(snow_tile);
+  QueDel(&peasant_head,TRUE);
+  QueDel(&step_head,TRUE);
+  QueDel(&king_step_head,TRUE);
+}
+
+U0 Follow(CTask *,Peasant *tmpp)
+{
+  Step *tmps=king_step_head.next;
+  F64 d,best_d=F64_MAX;
+  while (tmps!=&king_step_head) {
+    if ((d=Sqr(tmps->x-tmpp->x)+Sqr(tmps->y-tmpp->y)) &&
+          d<15*15) {
+      d+=1000*Sqr(tS-tmps->t0);
+      if (d<best_d) {
+        best_d=d;
+        tmpp->theta=Arg(tmps->x-tmpp->x,tmps->y-tmpp->y);
+      }
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 AnimateTask(I64)
+{
+  Step *tmps,*tmps1;
+  Peasant *tmpp;
+  I64 i,w,h;
+  while (TRUE) {
+    w=Fs->parent_task->pix_width;
+    h=Fs->parent_task->pix_height;
+
+    tmps=step_head.next;
+    while (tmps!=&step_head) {
+      tmps1=tmps->next;
+      if (tS-tmps->t0>5.0) {
+        QueRem(tmps);
+        Free(tmps);
+      }
+      tmps=tmps1;
+    }
+
+    tmps=king_step_head.next;
+    while (tmps!=&king_step_head) {
+      tmps1=tmps->next;
+      if (tS-tmps->t0>3.0) {
+        QueRem(tmps);
+        Free(tmps);
+      }
+      tmps=tmps1;
+    }
+
+    not_stopped_cnt=0;
+    tmpp=peasant_head.next;
+    while (tmpp!=&peasant_head) {
+      if (tmpp->stopped) {
+        if (tmpp->door_opened_t0 && tS>tmpp->door_opened_t0+1.0) {
+          tmpp->door_opened_t0=0;
+          tmpp->y=tmpp->x=-9999;
+        }
+      } else {
+        if (Sqr(tmpp->x-w/2)+Sqr(tmpp->y-h/2)<20*20) {
+          tmpp->stopped=TRUE;
+          tmpp->door_opened_t0=door_open_t0=tS;
+        }
+        for (i=0;i<TREES_NUM;i++) //Hang-out by fire
+          if (trees[i].fire_frame_idx &&
+                Sqr(tmpp->x-trees[i].x)+Sqr(tmpp->y-trees[i].y)<20*20) {
+            tmpp->stopped=TRUE;
+            break;
+          }
+        if (!tmpp->stopped) {
+          Follow(Fs->parent_task,tmpp);
+          tmpp->x+=Cos(tmpp->theta)/100;
+          tmpp->y+=Sin(tmpp->theta)/100;
+          if (!(BORDER/2<=tmpp->x<w-BORDER/2) ||
+                !(BORDER/2<=tmpp->y<h-BORDER/2)) {
+            tmpp->theta+=pi;
+            tmpp->x+=3*Cos(tmpp->theta)/100;
+            tmpp->y+=3*Sin(tmpp->theta)/100;
+          }
+          if (!animate_mS && animate_phase&1)
+            StepNew(Fs->parent_task,tmpp->x,tmpp->y,tmpp->theta,
+                  animate_phase&2,FALSE);
+          not_stopped_cnt++;
+        }
+      }
+      tmpp=tmpp->next;
+    }
+    if (!not_stopped_cnt && !tf) {
+      tf=tS;
+      music.mute=TRUE;
+      Snd(86);Sleep(200);Snd;Sleep(100);
+      if (tf-t0<best_score) {
+        best_score=tf-t0;
+        Snd(86);Sleep(200);Snd;Sleep(100);
+      }
+      music.mute=FALSE;
+    }
+
+    snow_x+=RandU16%3-1;
+    snow_y+=1-SignI64(RandU16&3);
+    if (new_snow_mS++>8) {
+      new_snow_mS=0;
+      snow_tile->color=WHITE;
+      GrPlot(snow_tile,RandU16&(SNOW_TILE_SIZE-1),RandU16&(SNOW_TILE_SIZE-1));
+    }
+
+    Sleep(1);
+    if (animate_mS++>=250) {
+      animate_mS=0;
+      animate_phase=(animate_phase+1)&3;
+    }
+    if (tS<king_timeout) {
+      if (king_mS++>=250) {
+        king_mS=0;
+        king_phase|=1;
+      }
+    }
+  }
+}
+
+U0 BurnTrees()
+{
+  I64 i;
+  for (i=0;i<TREES_NUM;i++)
+    if (Sqr(king_x-trees[i].x)+Sqr(king_y-trees[i].y)<10*10)
+      trees[i].fire_frame_idx=1;
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 2.480;
+  music.stacatto_factor= 0.902;
+  while (TRUE) {
+    Play("5eCCCDCC4qGeAGAB5qCC");
+    Play("5eCCCDCC4qGeAGAB5qCC");
+    Play("5eGFEDEDqC4eAGAB5qCC");
+  }
+}
+ 
+U0 Wenceslas()
+{
+  I64 sc;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  BurnTree(,CH_SPACE);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+
+  PopUpOk("
+Good King Wenceslas looked out
+On the feast of Stephen
+When the snow lay round about
+Deep and crisp and even
+Brightly shone the moon that night
+Though the frost was cruel
+When a poor man came in sight
+Gath'ring winter fuel
+
+\"Hither, page, and stand by me
+If thou know'st it, telling
+Yonder peasant, who is he?
+Where and what his dwelling?\"
+\"Sire, he lives a good league hence
+Underneath the mountain
+Right against the forest fence
+By Saint Agnes' fountain.\"
+
+\"Bring me flesh and bring me wine
+Bring me pine logs hither
+Thou and I will see him dine
+When we bear him thither.\"
+Page and monarch forth they went
+Forth they went together
+Through the rude wind's wild lament
+And the bitter weather
+
+");
+  PopUpOk("
+\"Sire, the night is darker now
+And the wind blows stronger
+Fails my heart, I know not how,
+I can go no longer.\"
+\"Mark my footsteps, my good page
+Tread thou in them boldly
+Thou shalt find the winter's rage
+Freeze thy blood less coldly.\"
+
+In his master's steps he trod
+Where the snow lay dinted
+Heat was in the very sod
+Which the Saint had printed
+Therefore, Christian men, be sure
+Wealth or rank possessing
+Ye who now will bless the poor
+Shall yourselves find blessing
+
+");
+  PopUpOk("
+$PURPLE$$TX+CX,\"Winceslas Game\"$$FG$
+
+Start fires by pressing $GREEN$<SPACE>$FG$
+on trees. (Yule logs)
+
+Lead peasants to fires.
+");
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto ws_done;
+        case CH_SPACE:
+          BurnTrees;
+          break;
+        case 0:
+          switch (sc.u8[0]) {
+            start:
+              case SC_CURSOR_RIGHT:
+                if (king_x+KING_STEP<Fs->pix_width-BORDER)
+                  king_x+=KING_STEP;
+                king_theta=0;
+                break;
+              case SC_CURSOR_LEFT:
+                if (king_x-KING_STEP>=BORDER)
+                  king_x-=KING_STEP;
+                king_theta=pi;
+                break;
+              case SC_CURSOR_DOWN:
+                if (king_y+KING_STEP<Fs->pix_height-BORDER)
+                  king_y+=KING_STEP;
+                king_theta=-pi/2;
+                break;
+              case SC_CURSOR_UP:
+                if (king_y-KING_STEP>=BORDER)
+                  king_y-=KING_STEP;
+                king_theta=pi/2;
+                break;
+            end:
+              king_mS=0;
+              king_phase=(king_phase+2)&2;
+              StepNew(Fs,king_x,king_y,king_theta,king_phase&2,TRUE);
+              king_timeout=tS+0.5;
+              break;
+          }
+      }
+    }
+ws_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/Wenceslas","F64 best_score=%5.4f;\n",best_score);
+}
+
+Wenceslas;
+
+ diff --git a/public/Wb/Demo/Games/Whap.HC.HTML b/public/Wb/Demo/Games/Whap.HC.HTML new file mode 100755 index 0000000..dcc0ca7 --- /dev/null +++ b/public/Wb/Demo/Games/Whap.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+#define BALLS_NUM       7
+#define SPRINGS_NUM     3
+
+#define STRETCH         500.0
+#define GRAVITY         50.0 //not really gravity
+#define BALL_RADIUS     5
+#define BASE_SIZE       10
+
+CMass balls[BALLS_NUM];
+CSpring springs[SPRINGS_NUM];
+F64 collision_t;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,
+        cx=task->pix_width>>1,
+        cy=task->pix_height>>1;
+  Bool snd_on=FALSE;
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Protect your base.");
+  GrRect(dc,cx-BASE_SIZE,cy-BASE_SIZE,BASE_SIZE*2,BASE_SIZE*2);
+  dc->color=CYAN;
+  GrRect(dc,cx-BASE_SIZE+2,cy-BASE_SIZE+2,BASE_SIZE*2-4,BASE_SIZE*2-4);
+  dc->color=YELLOW;
+  GrLine(dc,balls[0].x,balls[0].y,
+        ms.pos.x-task->pix_left-task->scroll_x,
+        ms.pos.y-task->pix_top-task->scroll_y);
+  for (i=0;i<SPRINGS_NUM;i++)
+    GrLine(dc,springs[i].end1->x,springs[i].end1->y,
+          springs[i].end2->x,springs[i].end2->y);
+
+  dc->color=LTCYAN;
+  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
+  GrFloodFill(dc,balls[0].x,balls[0].y,TRUE);
+  dc->color=BLACK;
+  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
+
+  for (i=1;i<BALLS_NUM;i++) {
+    dc->color=LTPURPLE;
+    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
+    GrFloodFill(dc,balls[i].x,balls[i].y,TRUE);
+    if (cx-BASE_SIZE-BALL_RADIUS<=balls[i].x<=cx+BASE_SIZE+BALL_RADIUS &&
+          cy-BASE_SIZE-BALL_RADIUS<=balls[i].y<=cy+BASE_SIZE+BALL_RADIUS)
+      snd_on=TRUE;
+    dc->color=BLACK;
+    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
+  }
+  if (snd_on)
+    Snd(74);
+  else
+    Snd;
+}
+
+U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *,COrder2D3 *)
+{
+  I64 i,j;
+  F64 d,dd;
+  CD3 p,p2;
+  CTask *task=ode->win_task;
+
+  D3SubEqu(D3Equ(&p2,
+        ms.pos.x-task->pix_left-task->scroll_x,
+        ms.pos.y-task->pix_top-task->scroll_y,0),
+        &balls[0].state->x);
+  D3AddEqu(&balls[0].DstateDt->DxDt,D3MulEqu(&p2,STRETCH));
+
+  D3Equ(&p2,task->pix_width>>1,task->pix_height>>1,0);
+  for (i=1;i<BALLS_NUM;i++) {
+    D3Sub(&p,&p2,&balls[i].state->x);
+    if (d=D3Norm(&p)) {
+//Gravity would be /(d*d*d), but that's too exponential.
+      D3MulEqu(&p,GRAVITY/d);
+      D3AddEqu(&balls[i].DstateDt->DxDt,&p);
+    }
+  }
+
+  for (i=0;i<BALLS_NUM;i++)
+    for (j=i+1;j<BALLS_NUM;j++) {
+      D3Sub(&p,&balls[j].state->x,&balls[i].state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=(2*BALL_RADIUS)*(2*BALL_RADIUS)) {
+        if (t-collision_t>0.05) {
+          Noise(50,102,105);
+          collision_t=t;
+        }
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr((2*BALL_RADIUS)*(2*BALL_RADIUS)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&balls[j].DstateDt->DxDt,&p);
+        D3SubEqu(&balls[i].DstateDt->DxDt,&p);
+      }
+    }
+
+  d=balls[0].state->x;
+  if (d-BALL_RADIUS<0)
+    balls[0].DstateDt->DxDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
+  if (d+BALL_RADIUS>task->pix_width)
+    balls[0].DstateDt->DxDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_width)));
+
+  d=balls[0].state->y;
+  if (d-BALL_RADIUS<0)
+    balls[0].DstateDt->DyDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
+  if (d+BALL_RADIUS>task->pix_height)
+    balls[0].DstateDt->DyDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_height)));
+}
+
+U0 Whap()
+{
+  I64 i;
+  CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES);
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        );
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+  MemSet(balls,0,BALLS_NUM*sizeof(CMass));
+  D3Equ(&balls[0].x,100,100,0);
+  for (i=1;i<BALLS_NUM;i++)
+    D3Equ(&balls[i].x,
+          RandI16%500+Fs->pix_width>>1,RandI16%500+Fs->pix_height>>1,0);
+  balls[0].x=ms.pos.x-Fs->pix_left-Fs->scroll_x;
+  balls[0].y=ms.pos.y-Fs->pix_top-Fs->scroll_y;
+  for (i=0;i<BALLS_NUM;i++) {
+    balls[i].mass=1.0;
+    balls[i].drag_profile_factor=1.0;
+    QueIns(&balls[i],ode->last_mass);
+  }
+  balls[2].x=balls[1].x+15;
+  balls[2].y=balls[1].y;
+  balls[3].x=balls[1].x;
+  balls[3].y=balls[1].y+15;
+  MemSet(springs,0,SPRINGS_NUM*sizeof(CSpring));
+  springs[0].end1=&balls[1];
+  springs[0].end2=&balls[2];
+  springs[0].rest_len=15;
+  springs[0].const=10000;
+  QueIns(&springs[0],ode->last_spring);
+  springs[1].end1=&balls[1];
+  springs[1].end2=&balls[3];
+  springs[1].rest_len=15;
+  springs[1].const=10000;
+  QueIns(&springs[1],ode->last_spring);
+  springs[2].end1=&balls[2];
+  springs[2].end2=&balls[3];
+  springs[2].rest_len=sqrt2*15;
+  springs[2].const=10000;
+  QueIns(&springs[2],ode->last_spring);
+
+  collision_t=0;
+  QueIns(ode,Fs->last_ode);
+
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar;
+  SettingsPop;
+  QueRem(ode);
+  ODEDel(ode);
+  MenuPop;
+}
+
+Whap;
+
+ diff --git a/public/Wb/Demo/Games/Zing.HC.HTML b/public/Wb/Demo/Games/Zing.HC.HTML new file mode 100755 index 0000000..8e3a260 --- /dev/null +++ b/public/Wb/Demo/Games/Zing.HC.HTML @@ -0,0 +1,236 @@ + + + + + + + + + + + +
+I64 box_x_min,box_x_max,box_y_min,box_y_max;
+
+class Arrow
+{
+  Arrow *next,*last;
+  F64 x,y,dx,dy;
+} head;
+
+   <1>/* Graphics Not Rendered in HTML */
+
+Bool bow_drawn;
+F64 bow_x,bow_y,bow_theta;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 theta,x,y,dx,dy,
+        str_w,str_h,draw_len;
+  Arrow *tmpa;
+  CD3I32 ctrl[5];
+  dc->color=RED;
+  GrBorder(dc,box_x_min,box_y_min,box_x_max,box_y_max);
+
+  x=ClampI64(ms.pos.x-task->pix_left-task->scroll_x,box_x_min,box_x_max);
+  y=ClampI64(ms.pos.y-task->pix_top-task->scroll_y, box_y_min,box_y_max);
+  dx=bow_x-x;
+  dy=bow_y-y;
+
+  if (bow_drawn && (dx|dy))
+    bow_theta=Arg(dx,dy);
+  else {
+    bow_x=x;
+    bow_y=y;
+  }
+
+  draw_len=Sqrt(dx*dx+dy*dy);
+  str_w=draw_len/3;
+  str_h=Sqrt(60*60-str_w*str_w);
+
+  dc->color=BLACK;
+  GrLine(dc,x-str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta),
+        y-str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta),
+        x,y);
+  GrLine(dc,x+str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta),
+        y+str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta),
+        x,y);
+
+  MemSet(ctrl,0,sizeof(ctrl));
+  ctrl[0].x=x-str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta);
+  ctrl[0].y=y-str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta);
+  ctrl[1].x=x-0.75*str_h/2*Cos(bow_theta+pi/2)+draw_len/2*Cos(bow_theta)+
+        str_w*Cos(bow_theta);
+  ctrl[1].y=y-0.75*str_h/2*Sin(bow_theta+pi/2)+draw_len/2*Sin(bow_theta)+
+        str_w*Sin(bow_theta);
+  ctrl[2].x=x+draw_len/2*Cos(bow_theta)+str_w*Cos(bow_theta);
+  ctrl[2].y=y+draw_len/2*Sin(bow_theta)+str_w*Sin(bow_theta);
+  ctrl[3].x=x+0.75*str_h/2*Cos(bow_theta+pi/2)+draw_len/2*Cos(bow_theta)+
+        str_w*Cos(bow_theta);
+  ctrl[3].y=y+0.75*str_h/2*Sin(bow_theta+pi/2)+draw_len/2*Sin(bow_theta)+
+        str_w*Sin(bow_theta);
+  ctrl[4].x=x+str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta);
+  ctrl[4].y=y+str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta);
+
+  dc->color=BROWN;
+  dc->thick=2;
+  Gr2BSpline3(dc,ctrl,5);
+  dc->thick=1;
+
+  if (bow_drawn)
+    Sprite3ZB(dc,x,y,0,<1>,bow_theta);
+
+  tmpa=head.next;
+  while (tmpa!=&head) {
+    theta=Arg(tmpa->dx,tmpa->dy);
+    Sprite3ZB(dc,tmpa->x,tmpa->y,0,<1>,theta);
+    tmpa=tmpa->next;
+  }
+}
+
+#define ANIMATE_SLEEP_MS        10
+
+U0 AnimateTask(I64)
+{
+  I64 x,y;
+  Arrow *tmpa,*tmpa1;
+  F64 dt,t0=tS;
+  while (TRUE) {
+    dt=tS-t0;
+    t0=tS;
+
+    x=ClampI64(ms.pos.x-Fs->parent_task->pix_left-Fs->parent_task->scroll_x,
+          box_x_min,box_x_max)+Fs->parent_task->pix_left+
+          Fs->parent_task->scroll_x;
+    y=ClampI64(ms.pos.y-Fs->parent_task->pix_top-Fs->parent_task->scroll_y,
+          box_y_min,box_y_max)+Fs->parent_task->pix_top+
+          Fs->parent_task->scroll_y;
+    if (ms.pos.x!=x || ms.pos.y!=y)
+      MsSet(x,y);
+
+    tmpa=head.next;
+    while (tmpa!=&head) {
+      tmpa1=tmpa->next;
+      tmpa->x+=tmpa->dx*dt;
+      tmpa->y+=tmpa->dy*dt;
+      if (!(-Fs->parent_task->scroll_x<=
+            tmpa->x<Fs->parent_task->pix_width-Fs->parent_task->scroll_x) ||
+            !(-Fs->parent_task->scroll_y<=
+            tmpa->y<Fs->parent_task->pix_height-Fs->parent_task->scroll_y)) {
+        QueRem(tmpa);
+        Free(tmpa);
+      }
+      tmpa=tmpa1;
+    }
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  I64 w=Fs->pix_width,
+        h=Fs->pix_height;
+  QueInit(&head);
+  bow_drawn=FALSE;
+  box_x_min=7*w/16;
+  box_y_min=6*h/8;
+  box_x_max=9*w/16;
+  box_y_max=7*h/8;
+  bow_theta=-pi/2;
+  bow_x=(box_x_min+box_x_max)/2;
+  bow_y=(box_y_min+box_y_max)/2;
+  MsSet(bow_x+Fs->pix_left+Fs->scroll_x,
+        bow_y+Fs->pix_top+Fs->scroll_y);
+}
+
+U0 CleanUp()
+{
+  QueDel(&head,TRUE);
+}
+
+U0 Zing()
+{
+  I64 arg1,arg2;
+  Arrow *tmpa;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+  try {
+    while (TRUE)
+      switch (GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto zi_done;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          bow_x=arg1;
+          bow_y=arg2;
+          bow_drawn=TRUE;
+          break;
+        case MSG_MS_L_UP:
+          if(arg1-bow_x || arg2-bow_y) {
+            tmpa=MAlloc(sizeof(Arrow));
+            tmpa->dx=10.0*(bow_x-arg1);
+            tmpa->dy=10.0*(bow_y-arg2);
+            tmpa->x=arg1;
+            tmpa->y=arg2;
+            QueIns(tmpa,head.last);
+            Noise(50,110,114);
+          }
+          bow_drawn=FALSE;
+          break;
+      }
+zi_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+Zing;
+
+ diff --git a/public/Wb/Demo/Games/ZoneOut.HC.HTML b/public/Wb/Demo/Games/ZoneOut.HC.HTML new file mode 100755 index 0000000..a02fb8e --- /dev/null +++ b/public/Wb/Demo/Games/ZoneOut.HC.HTML @@ -0,0 +1,349 @@ + + + + + + + + + + + +
+RegDft("TempleOS/ZoneOut","F64 best_score=9999;\n");
+RegExe("TempleOS/ZoneOut");
+
+
+
+
+
+
+
+
+
+
+                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+                   <3>/* Graphics Not Rendered in HTML */
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+#define THEM_NUM        10
+
+class Obj
+{
+  Obj *next,*last;
+  F64 t0,theta;
+  I64 x,y,z;
+  Bool hit,pad[7];
+} us,them[THEM_NUM],shots;
+I64 num_them;
+F64 t0,tf;
+
+#define SCRN_SCALE      512
+#define TANK_HEIGHT     32
+
+U0 ZOTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  zz=*z;
+  if (zz<1) zz=1;
+  *x=SCRN_SCALE/2* *x/zz;
+  *y=SCRN_SCALE/2* (*y+TANK_HEIGHT)/zz;
+  *x+=dc->x;
+  *y+=dc->y;
+  *z+=dc->z;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  Obj *tmpo;
+  I64 i,dd,y,w=task->pix_width,h=task->pix_height,cx=w>>1,cy=h>>1;
+  U8 *img;
+  F64 tt,theta;
+
+  theta=640*Wrap(2*us.theta)/pi;
+  Sprite3(dc,theta-1280,90,0,<4>);
+  Sprite3(dc,theta         ,90,0,<4>);
+  Sprite3(dc,theta+1280,90,0,<4>);
+
+  DCDepthBufAlloc(dc);
+  dc->transform=&ZOTransform;
+  dc->x=cx;
+  dc->y=cy;
+  Mat4x4TranslationEqu(dc->r,-us.x,-us.y,-us.z);
+  Mat4x4RotY(dc->r,us.theta-pi/2);
+  Mat4x4RotX(dc->r,pi/16);
+
+  dc->flags|=DCF_TRANSFORMATION;
+  for (i=0;i<THEM_NUM;i++) {
+    y=them[i].y;
+    tmpo=shots.next;
+    while (tmpo!=&shots) {
+      dd=SqrI64(them[i].x-tmpo->x)+SqrI64(them[i].z-tmpo->z);
+      if (dd<SCRN_SCALE/2*SCRN_SCALE/2) {
+        y-=Sqrt(dd);
+        if (!them[i].hit) {
+          them[i].hit=TRUE;
+          if (!--num_them) {
+            tf=tS;
+            if (tf-t0<best_score)
+              best_score=tf-t0;
+          }
+        }
+      }
+      tmpo=tmpo->next;
+    }
+    if (them[i].hit)
+      img=<2>;
+    else
+      img=<1>;
+    Sprite3YB(dc,them[i].x,y,them[i].z,img,-them[i].theta);
+  }
+  tmpo=shots.next;
+  while (tmpo!=&shots) {
+    Sprite3YB(dc,tmpo->x,tmpo->y,tmpo->z,<3>,-tmpo->theta);
+    tmpo=tmpo->next;
+  }
+  dc->flags&=~DCF_TRANSFORMATION;
+  dc->color=LTGREEN;
+  GrLine(dc,cx-5,cy,cx+5,cy);
+  GrLine(dc,cx,cy-5,cx,cy+5);
+  if (tf) {
+    dc->color=RED;
+    if (Blink)
+      GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed");
+    tt=tf;
+  } else {
+    dc->color=BLACK;
+    GrLine(dc,cx-5,cy,cx+5,cy);
+    GrLine(dc,cx,cy-5,cx,cy+5);
+    tt=tS;
+  }
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",num_them,tt-t0,best_score);
+}
+
+U0 Fire()
+{
+  Obj *tmpo=MAlloc(sizeof(Obj));
+  tmpo->x=us.x;
+  tmpo->y=TANK_HEIGHT;
+  tmpo->z=us.z;
+  tmpo->theta=us.theta;
+  tmpo->t0=tS;
+  QueIns(tmpo,shots.last);
+}
+
+U0 MoveUs(F64 theta)
+{
+  us.x+=0.1*SCRN_SCALE*Cos(theta);
+  us.z+=0.1*SCRN_SCALE*Sin(theta);
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  Obj *tmpo,*tmpo1;
+  while (TRUE) {
+    for (i=0;i<THEM_NUM;i++) {
+      them[i].x+=SCRN_SCALE/32*Cos(them[i].theta);
+      them[i].z+=SCRN_SCALE/32*Sin(them[i].theta);
+      them[i].theta+=Rand/100.0;
+    }
+    tmpo=shots.next;
+    while (tmpo!=&shots) {
+      tmpo1=tmpo->next;
+      if (tS-tmpo->t0>1.0) {
+        QueRem(tmpo);
+        Free(tmpo);
+      } else {
+        tmpo->x+=0.25*SCRN_SCALE*Cos(tmpo->theta);
+        tmpo->z+=0.25*SCRN_SCALE*Sin(tmpo->theta);
+      }
+      tmpo=tmpo1;
+    }
+    Sleep(20);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  DocClear;
+  "$BG,LTCYAN$%h12c",'\n';
+  QueInit(&shots);
+  MemSet(&us,0,sizeof(us));
+  MemSet(them,0,sizeof(them));
+  num_them=THEM_NUM;
+  for (i=0;i<THEM_NUM;i++) {
+    them[i].x=10000*Rand-5000;
+    them[i].z=10000*Rand-5000;
+    them[i].theta=2*pi*Rand;
+    them[i].hit=FALSE;
+  }
+  tf=0;
+  t0=tS;
+}
+
+U0 CleanUp()
+{
+  QueDel(&shots,TRUE);
+}
+
+U0 SongTask(I64)
+{//Randomly generate (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG");
+    Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG");
+    Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA");
+    Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA");
+  }
+}
+
+U0 ZoneOut()
+{
+  I64 sc;
+
+  PopUpOk(
+        "I refuse to rip-off the original\n"
+        "so this is intentionally crappy\n"
+        "and included for demonstration\n"
+        "purposes.\n\n"
+        "Write games, don't play them.\n");
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fwd(,,SC_CURSOR_UP);"
+        "  Bwd(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Fire(,CH_SPACE);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case CH_SPACE:
+          Fire;
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto zo_done;
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_RIGHT:
+              us.theta-=pi/256;
+              break;
+            case SC_CURSOR_LEFT:
+              us.theta+=pi/256;
+              break;
+            case SC_CURSOR_UP:
+              MoveUs(us.theta);
+              break;
+            case SC_CURSOR_DOWN:
+              MoveUs(us.theta+pi);
+              break;
+          }
+          break;
+      }
+    }
+zo_done:
+  } catch
+    PutExcept;
+  CleanUp;
+  DocClear;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/ZoneOut","F64 best_score=%5.4f;\n",best_score);
+}
+
+ZoneOut;
+
+ diff --git a/public/Wb/Demo/GlblVars.HC.HTML b/public/Wb/Demo/GlblVars.HC.HTML new file mode 100755 index 0000000..14e5b15 --- /dev/null +++ b/public/Wb/Demo/GlblVars.HC.HTML @@ -0,0 +1,107 @@ + + + + + + + + + + + +
+//Demonstrates dynamic initialization of vars.
+//Static vars are, essentually, global vars.
+
+class Test
+{
+  I32 time;
+  U8 name[8];
+};
+
+Test g1[]={
+  {10,"Name1"},
+  {(tS%10.0)*100,"Name2"}, //Dynamic initialization
+  {30,"Name3"}
+};
+
+D(g1,sizeof(g1));
+"Time 1:%d\n",g1[1].time;
+
+U0 Main1()
+{
+  static Test s1[]={
+  {10,"Static1"},
+        {(tS%10.0)*100,"Static2"}, //Dynamic initialization
+        {30,"Static3"}
+  };
+  D(s1,sizeof(s1));
+  "Time 2:%d\n",s1[1].time;
+}
+
+Main1;
+
+/*Now, we'll use the data heap glbl option
+to force global vars onto the data heap.
+
+You can turn the data heap flag
+on and off within your programs, leaving
+ones which need initialization on the code heap.
+
+You can't dynamically initialize data heap
+glbls--they are consts.  This might be a silly
+point, but might res in odd differences, perhaps
+from the order things are evaluated.
+
+Data heap glbls are good for AOT modules
+because they don't take-up room in the .BIN.Z file.
+*/
+
+#ifjit
+#exe {Option(OPTf_GLBLS_ON_DATA_HEAP,ON);};
+
+Test g2[]={
+  {10,"name1"},
+  {(tS%10.0)*100,"name2"}, //No dynamic initialization--cvted to const
+  {30,"name3"}
+};
+
+D(g2,sizeof(g2));
+"Time 3:%d\n",g2[1].time;
+
+U0 Main2()
+{
+  static Test s2[]={
+  {10,"static1"},
+        {(tS%10.0)*100,"static2"}, //No dynamic initialization--cvted to const
+        {30,"static3"}
+  };
+  D(s2,sizeof(s2));
+  "Time 4:%d\n",s2[1].time;
+}
+
+Main2;
+
+#exe {Option(OPTf_GLBLS_ON_DATA_HEAP,ON);};
+#endif
+
+'\n';
+
+ diff --git a/public/Wb/Demo/Graphics/3DPoly.HC.HTML b/public/Wb/Demo/Graphics/3DPoly.HC.HTML new file mode 100755 index 0000000..585d93c --- /dev/null +++ b/public/Wb/Demo/Graphics/3DPoly.HC.HTML @@ -0,0 +1,148 @@ + + + + + + + + + + + +
+U0 Main()
+{
+  F64 theta=0,phi=0,omega=0;
+  CD3I32 poly[4];
+  CDC *dc=DCAlias;
+  DCDepthBufAlloc(dc);
+  dc->flags|=DCF_TRANSFORMATION|DCF_SYMMETRY;
+  try {
+    while (!ScanChar) {
+      DCDepthBufRst(dc);
+      DCSymmetrySet(dc,Fs->pix_width/2,Fs->pix_height/2,
+            ms.pos.x-Fs->pix_left-Fs->scroll_x,
+            ms.pos.y-Fs->pix_top-Fs->scroll_y);
+      dc->color=LTBLUE;
+      GrLine(dc,Fs->pix_width/2,Fs->pix_height/2,
+            ms.pos.x-Fs->pix_left-Fs->scroll_x,
+            ms.pos.y-Fs->pix_top-Fs->scroll_y);
+
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4RotX(dc->r,omega);
+      Mat4x4RotY(dc->r,phi);
+      Mat4x4RotZ(dc->r,theta);
+      DCMat4x4Set(dc,dc->r);
+
+      dc->x=Fs->pix_width/2;
+      dc->y=Fs->pix_height/2;
+      dc->z=500;
+
+      dc->color=GREEN;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=0;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=0;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=0;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=0;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=RED;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=50;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=50;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=50;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=50;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=BLUE;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=-50;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=-50;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=-50;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=-50;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=RED+GREEN<<16+ROPF_DITHER;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=50;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=50;
+      poly[2].x=275;
+      poly[2].y=100;
+      poly[2].z=0;
+      poly[3].x=50;
+      poly[3].y=150;
+      poly[3].z=0;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=BLUE+GREEN<<16+ROPF_DITHER;
+      poly[0].x=100;
+      poly[0].y=200;
+      poly[0].z=-50;
+      poly[1].x=155;
+      poly[1].y=200;
+      poly[1].z=-50;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=0;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=0;
+      GrFillPoly3(dc,4,poly);
+
+      Refresh;
+      DCFill;
+      theta+=2.1*pi/180.0;
+      phi+=1.1*pi/180.0;
+      omega+=0.5*pi/180.0;
+    }
+  } catch
+    PutExcept;
+
+  DCFill;
+  DCDel(dc);
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Graphics/BSpline.HC.HTML b/public/Wb/Demo/Graphics/BSpline.HC.HTML new file mode 100755 index 0000000..6640b4a --- /dev/null +++ b/public/Wb/Demo/Graphics/BSpline.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+#define PTS_NUM 16
+
+U0 BSplineDemo()
+{
+  CDC *dc=DCAlias;
+  I64 arg1,arg2,i=0,msg_code;
+  CD3I32 c[PTS_NUM];
+
+  SettingsPush;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  DocClear;
+  "Sel ctrl points with left mouse.  Right when finished.\n";
+  DCFill;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_R_UP);
+    if (msg_code==MSG_MS_L_UP) {
+      c[i].x=arg1; c[i].y=arg2; c[i].z=0;
+      dc->color=GREEN;
+      GrCircle(dc,arg1,arg2,10);
+      i++;
+    }
+  } while (i<PTS_NUM && msg_code!=MSG_MS_R_UP);
+  dc->color=RED;
+  Gr2BSpline(dc,c,i,TRUE);
+  dc->color=BLUE;
+  Gr3BSpline(dc,c,i,TRUE);
+  DCDel(dc);
+  SettingsPop;
+
+  PressAKey;
+  DCFill;
+}
+
+BSplineDemo;
+
+ diff --git a/public/Wb/Demo/Graphics/Balloon.HC.HTML b/public/Wb/Demo/Graphics/Balloon.HC.HTML new file mode 100755 index 0000000..0f4a9e4 --- /dev/null +++ b/public/Wb/Demo/Graphics/Balloon.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+// Classic Commodore 64 Sprite
+
+U8 a[60]={0,127,0,1,255,192,3,255,224,3,231,224,
+          7,217,240,7,223,240,7,217,240,3,231,224,
+          3,255,224,3,255,224,2,255,160,1,127,64,
+          1,62,64,0,156,128,0,156,128,0,73,0,0,73,0,
+          0,62,0,0,62,0,0,28,0};
+
+U0 Balloon()
+{
+  I64 i,j,k;
+
+  CLI
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,0xF);
+  MemSetI64(text.vga_alias,0,640*480/64);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,RED+GREEN+8);
+  for (k=100;k<150;k++) {
+
+    for (i=0;i<20;i++)
+      for (j=0;j<3;j++)
+        *(text.vga_alias(I64)+0x1000+(i+k)*640/8+j)(U8 *)=a[i*3+j];
+
+    Busy(40000);
+
+    for (i=0;i<20;i++)
+      for (j=0;j<3;j++)
+        *(text.vga_alias(I64)+0x1000+(i+k)*640/8+j)(U8 *)=0;
+  }
+
+  STI
+  VGAFlush;
+}
+
+Balloon;
+
+ diff --git a/public/Wb/Demo/Graphics/Blot.HC.HTML b/public/Wb/Demo/Graphics/Blot.HC.HTML new file mode 100755 index 0000000..ab6c543 --- /dev/null +++ b/public/Wb/Demo/Graphics/Blot.HC.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+CDC *dc=DCAlias;
+CDC *img1=DCNew(64,64);
+CDC *img2=DCNew(512,512);
+
+img1->color=COLOR_MONO;
+img1->thick=3;
+GrCircle(img1,30,30,20);
+GrFloodFill3(img1,30,30,0,TRUE);
+GrLine3(img1,60,0,0,0,60,0);
+
+DCFill(img2);
+img2->color=RED;
+img2->brush=img1;
+GrCircle(img2,256-30,256-30,128,67);
+img2->color=BLUE;
+img2->thick=6;
+img2->brush=NULL;
+GrLine3(img2,128,128,0,256+128,256+128,0);
+GrLine3(img2,256+128,128,0,128,256+128,0);
+
+img2->color=YELLOW;
+GrRect(img2,256-20,256-20,40,40);
+
+I64 i;
+for (i=0;i<256;i+=4) {
+  Refresh;
+  DCFill;
+  GrBlot(dc,i-256,i-256,img2);
+  Sleep(10);
+}
+U8 *tmpg=DC2Sprite(img1);
+Sprite(tmpg);
+Free(tmpg);
+"%h9c",'\n';
+
+DCDel(img1);
+DCDel(img2);
+DCDel(dc);
+
+PressAKey;
+DCFill;
+
+ diff --git a/public/Wb/Demo/Graphics/Bounce.HC.HTML b/public/Wb/Demo/Graphics/Bounce.HC.HTML new file mode 100755 index 0000000..6fbb45d --- /dev/null +++ b/public/Wb/Demo/Graphics/Bounce.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//Uses fixed-point-arithmetic.
+
+I64 x[16],y[16],dx[16],dy[16];
+
+U0 Init()
+{
+  I64 i;
+  F64 theta;
+  MemSet(x,0,sizeof(x));
+  MemSet(y,0,sizeof(y));
+  for (i=0;i<16;i++) {
+    theta=Rand*2*pi;
+    dx[i]=I32_MAX*Cos(theta);
+    dy[i]=I32_MAX*Sin(theta);
+  }
+}
+ 
+U0 Bounce()
+{
+  CDC *dc=DCAlias;
+  I64 i,ch;
+  Init;
+  try {//Catch <CTRL-ALT-c>
+    do {
+      for (i=0;i<16;i++) {
+        dc->color=i;
+        GrPlot(dc,x[i].i32[1],y[i].i32[1]);
+        x[i]+=dx[i];
+        y[i]+=dy[i];
+        if (!(0<=x[i]<Fs->pix_width<<32)) {
+          x[i]-=dx[i];
+          dx[i]=-dx[i];
+        }
+        if (!(0<=y[i]<Fs->pix_height<<32)) {
+          y[i]-=dy[i];
+          dy[i]=-dy[i];
+        }
+      }
+      Yield;
+    } while (!(ch=ScanChar) || (ch!=CH_SHIFT_ESC && ch!=CH_ESC));
+  } catch
+    PutExcept;
+  DCFill(dc);
+  DCDel(dc);
+}
+ 
+Bounce;
+
+ diff --git a/public/Wb/Demo/Graphics/Box.HC.HTML b/public/Wb/Demo/Graphics/Box.HC.HTML new file mode 100755 index 0000000..ad6d4fd --- /dev/null +++ b/public/Wb/Demo/Graphics/Box.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+I64 glbl_r[4][4];
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 *old_r=dc->r;
+  dc->thick=2;
+  dc->color=RED;
+  dc->x=200;
+  dc->y=200;
+  dc->flags|=DCF_TRANSFORMATION;
+  DCMat4x4Set(dc,glbl_r); //This assigns to dc->r and sets r_norm.
+  GrLine3(dc,-100,-100,-100, -100, 100,-100);
+  GrLine3(dc,-100, 100,-100,  100, 100,-100);
+  GrLine3(dc, 100, 100,-100,  100,-100,-100);
+  GrLine3(dc, 100,-100,-100, -100,-100,-100);
+  GrLine3(dc,-100,-100, 100, -100, 100, 100);
+  GrLine3(dc,-100, 100, 100,  100, 100, 100);
+  GrLine3(dc, 100, 100, 100,  100,-100, 100);
+  GrLine3(dc, 100,-100, 100, -100,-100, 100);
+  GrLine3(dc,-100,-100, 100, -100,-100,-100);
+  GrLine3(dc,-100, 100, 100, -100, 100,-100);
+  GrLine3(dc, 100, 100, 100,  100, 100,-100);
+  GrLine3(dc, 100,-100, 100,  100,-100,-100);
+  dc->r=old_r;
+}
+
+U0 Box()
+{
+  F64 theta=0,phi=0,omega=0,s=1,s1=1.05;
+  SettingsPush; //See SettingsPush
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  while (!ScanChar) {
+    Mat4x4IdentEqu(glbl_r);
+    Mat4x4RotZ(glbl_r,theta);
+    Mat4x4RotX(glbl_r,phi);
+    Mat4x4RotZ(glbl_r,omega);
+    Mat4x4Scale(glbl_r,s);
+
+    Sleep(20);
+    theta+=2*pi/70;
+    phi+=2*pi/90;
+    omega+=2*pi/110;
+    s*=s1;
+    if ( !(0.2<s<1.4) ) s1=1/s1;
+  }
+  SettingsPop;
+}
+
+Box;
+
+ diff --git a/public/Wb/Demo/Graphics/Cartesian.HC.HTML b/public/Wb/Demo/Graphics/Cartesian.HC.HTML new file mode 100755 index 0000000..b7848df --- /dev/null +++ b/public/Wb/Demo/Graphics/Cartesian.HC.HTML @@ -0,0 +1,79 @@ + + + + + + + + + + + +
+//x must be global.
+//Might as well make y global.
+
+F64 x,y,y_last;
+
+U0 Cartesian()
+{
+  U8 *st;
+  I64 ch=0,h,v;
+  Bool first;
+  CDC *dc=DCAlias;
+  do {
+    DocClear;
+    "Enter algebraic equation to graph.\n"
+          "Example: y=2*x\n"
+          "y=";
+    if (st=GetStr) {
+      if (*st) {
+        h=Fs->pix_width/2;
+        v=Fs->pix_height/2;
+        dc->color=RED;
+        GrLine(dc,h,0,h,2*v+1);
+        GrLine(dc,0,v,2*h+1,v);
+        first=TRUE;
+        dc->color=BLACK;
+        for (x=-h;x<=h;x++) {
+          y=-ExePrint("ToF64(%s);",st)(F64);
+          if (!first)
+            GrLine(dc,x-1+h,y_last+v,x+h,y+v);
+          y_last=y;
+          first=FALSE;
+        }
+        ch=GetChar;
+      } else
+        ch=CH_SHIFT_ESC;
+      Free(st);
+    } else
+      ch=CH_SHIFT_ESC;
+    DCFill;
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  DCDel(dc);
+}
+
+Cartesian;
+
+//For better performance, compile the expression entered by the
+//user one time with LexExpression2Bin() and use Call().
+//See ::/Demo/CompileDemo.HC.
+
+ diff --git a/public/Wb/Demo/Graphics/CharAnimation.HC.HTML b/public/Wb/Demo/Graphics/CharAnimation.HC.HTML new file mode 100755 index 0000000..35b9376 --- /dev/null +++ b/public/Wb/Demo/Graphics/CharAnimation.HC.HTML @@ -0,0 +1,61 @@ + + + + + + + + + + + +
+U8 *old_font=text.font;
+
+// See ::/Kernel/FontStd.HC, ::/Demo/ScrnCodes.HC,
+//::/Demo/ExtChars.HC, and ::/Demo/Graphics/FontEd.HC.
+
+U64 waves[4]={
+0x0011AA440011AA44,0x0022558800225588,
+0x0044AA110044AA11,0x0088552200885522};
+
+U0 AnimateEndCB()
+{
+  text.font=old_font;
+  Exit;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  U64 *font=MAlloc(256*8);
+  Fs->task_end_cb=&AnimateEndCB;
+  MemCpy(font,text.font,256*8);
+  text.font=font;
+  while (TRUE) {
+    font[CH_SPACE]=waves[i++&0x3];
+    Sleep(100);
+  }
+}
+
+Spawn(&AnimateTask,NULL,"Animate",,Fs);
+TaskRep;
+
+ diff --git a/public/Wb/Demo/Graphics/Collision.HC.HTML b/public/Wb/Demo/Graphics/Collision.HC.HTML new file mode 100755 index 0000000..ead78e4 --- /dev/null +++ b/public/Wb/Demo/Graphics/Collision.HC.HTML @@ -0,0 +1,73 @@ + + + + + + + + + + + +
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 x,y;
+
+  x=ms.pos.x-task->pix_left;
+  y=ms.pos.y-task->pix_top;
+  Sprite3(dc,x,y,0,<1>);
+
+  x=task->pix_width>>1;
+  y=task->pix_height>>1;
+
+  dc->color=ROP_COLLISION;
+  dc->bkcolor=WHITE;
+  dc->collision_cnt=0;
+  Sprite3(dc,x,y,0,<1>);
+
+  dc->color=ROP_EQU;
+  GrPrint(dc,0,(task->pix_height-FONT_HEIGHT)>>1,
+        "Collisions:%d",dc->collision_cnt);
+
+  if (!dc->collision_cnt)
+    Sprite3(dc,x,y,0,<1>);
+  else
+    Sprite3(dc,x,y,0,<2>);
+}
+
+U0 Collision()
+{
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  PressAKey;
+  SettingsPop;
+}
+
+Collision;
+
+ diff --git a/public/Wb/Demo/Graphics/CommonAncestor.HC.HTML b/public/Wb/Demo/Graphics/CommonAncestor.HC.HTML new file mode 100755 index 0000000..051928e --- /dev/null +++ b/public/Wb/Demo/Graphics/CommonAncestor.HC.HTML @@ -0,0 +1,151 @@ + + + + + + + + + + + +
+#define N       32
+ 
+class Node
+{
+  Node *left,*right;
+  I64 n;
+};
+ 
+I64 n1,n2,common_ancestor;
+Node *root;
+ 
+#define X_SPACING       16
+#define Y_SPACING       45
+#define ARROW_SPACING   3
+ 
+U0 ShowTree(CDC *dc,Node *tmpn,I64 *_node_x,I64 *_tree_x,I64 y)
+{
+  I64 node_x;
+  if (tmpn) {
+    if (tmpn->left) {
+      ShowTree(dc,tmpn->left,&node_x,_tree_x,y+Y_SPACING);
+      dc->color=BLUE;
+      GrArrow3(dc,*_tree_x,y,0,
+            node_x+ARROW_SPACING,y+Y_SPACING-ARROW_SPACING,0);
+    }
+    if (tmpn->n==n1 || tmpn->n==n2) {
+      if (tmpn->n==common_ancestor)
+        dc->color=YELLOW;
+      else
+        dc->color=RED;
+    } else if (tmpn->n==common_ancestor)
+      dc->color=GREEN;
+    else
+      dc->color=BLUE;
+
+    *_node_x=*_tree_x;
+    GrPrint(dc,*_node_x,y,"%d",tmpn->n);
+    *_tree_x+=X_SPACING;
+
+    if (tmpn->right) {
+      ShowTree(dc,tmpn->right,&node_x,_tree_x,y+Y_SPACING);
+      dc->color=BLUE;
+      GrArrow3(dc,*_node_x,y,0,
+            node_x-ARROW_SPACING,y+Y_SPACING-ARROW_SPACING,0);
+    }
+  }
+}
+ 
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 node_x=0,tree_x=0;
+  ShowTree(dc,root,&node_x,&tree_x,20);
+}
+
+U0 TreeAdd(Node **_root,Node *tmpn)
+{
+  Node *root=*_root;
+  if (!root)
+    *_root=tmpn;
+  else if (tmpn->n==root->n)
+    Free(tmpn);
+  else if (tmpn->n<root->n)
+    TreeAdd(&root->left,tmpn);
+  else
+    TreeAdd(&root->right,tmpn);
+}
+
+U0 TreeNew()
+{
+  I64 i;
+  Node *tmpn;
+  for (i=0;i<N;i++) {
+    tmpn=CAlloc(sizeof(Node));
+    tmpn->n=RandU16%N;
+
+    if (i==N-1)
+      n1=tmpn->n;
+    else if (i==N-2)
+      n2=tmpn->n;
+
+    TreeAdd(&root,tmpn);
+    Sleep(50);
+  }
+}
+ 
+U0 TreeCommonAncestorFind(Node *root)
+{
+  if (root && root->n!=n1 && root->n!=n2) {
+    common_ancestor=root->n;
+    if (n1<root->n && n2<root->n)
+      TreeCommonAncestorFind(root->left);
+    else if (n1>root->n && n2>root->n)
+      TreeCommonAncestorFind(root->right);
+  }
+}
+ 
+U0 TreeCommonAncestor()
+{//Make tree and find common ancestor to n1 & n2.
+  root=NULL;
+  n1=n2=common_ancestor=0;
+
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  DocClear;
+  "Scroll with {CTRL-Left Grab}.\n";
+  try {
+    TreeNew;
+    TreeCommonAncestorFind(root);
+    PressAKey;
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+TreeCommonAncestor;
+/*Be careful with recursive routines in TempleOS
+because the stack does not grow and will overflow.
+
+See ::/Demo/StkGrow.HC.
+*/
+
+ diff --git a/public/Wb/Demo/Graphics/Doodle.HC.HTML b/public/Wb/Demo/Graphics/Doodle.HC.HTML new file mode 100755 index 0000000..61d432f --- /dev/null +++ b/public/Wb/Demo/Graphics/Doodle.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//This is a drawing program
+
+U0 Doodle()
+{
+  I64 msg_code,i,x1,y1,x2,y2,arg1,arg2,color=BLACK;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_MS_R_UP:
+        i=PopUpColor;
+        if (i>=0) color=i;
+        break;
+      case MSG_MS_L_DOWN:
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        dc->color=ROP_XOR+color^TRANSPARENT;
+        dc->thick=7;
+        do {
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          x2=arg1; y2=arg2;
+        } while (msg_code!=MSG_MS_L_UP);
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        break;
+      case MSG_KEY_DOWN:
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || !arg1);
+  GetMsg(,,1<<MSG_KEY_UP);
+  DCFill;
+  DCDel(dc);
+  SettingsPop;
+}
+
+Doodle;  //Execute when #included
+
+ diff --git a/public/Wb/Demo/Graphics/EdSprite.HC.HTML b/public/Wb/Demo/Graphics/EdSprite.HC.HTML new file mode 100755 index 0000000..650af96 --- /dev/null +++ b/public/Wb/Demo/Graphics/EdSprite.HC.HTML @@ -0,0 +1,123 @@ + + + + + + + + + + + +
+/*Add an outline to Sprites and
+print them to the cmd line.  They
+can be cut/pasted from there.
+*/
+<1>/* Graphics Not Rendered in HTML */
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+
+<6>/* Graphics Not Rendered in HTML */
+
+
+
+<7>/* Graphics Not Rendered in HTML */
+
+
+<8>/* Graphics Not Rendered in HTML */
+
+
+
+<9>/* Graphics Not Rendered in HTML */
+
+
+
+<10>/* Graphics Not Rendered in HTML */
+
+
+
+<11>/* Graphics Not Rendered in HTML */
+
+
+
+<12>/* Graphics Not Rendered in HTML */
+
+
+
+#define NUM     12
+
+U8 *in_img[NUM]={<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>};
+
+U0 OutLine()
+{
+  I64 n,minx,maxx,miny,maxy,w,h,i,j,k,c;
+  U8 *out_img;
+  CDC *dc;
+  for (n=0;n<NUM;n++) {
+    SpriteExtents(in_img[n],&minx,&maxx,&miny,&maxy);
+    w=maxx-minx+1+2;
+    h=maxy-miny+1+2;
+    dc=DCNew(w,h);
+    dc->color=TRANSPARENT;
+    GrRect(dc,0,0,w,h);
+    Sprite3(dc,-minx+1,-miny+1,0,in_img[n]);
+
+    for (i=0;i<h;i++)
+      for (j=0;j<w;j++)
+        if (GrPeek(dc,j,i)==TRANSPARENT) {
+          for (k=0;k<8;k++) {
+            c=GrPeek(dc,j+gr_x_offsets[k],i+gr_y_offsets[k]);
+            if (c!=-1 && c!=BLACK && c!=TRANSPARENT) {
+              dc->color=BLACK;
+              GrPlot(dc,j,i);
+              break;
+            }
+          }
+        }
+
+    out_img=DC2Sprite(dc);
+    '\n';
+    Sprite(out_img);
+    '\n\n\n\n';
+
+    DCDel(dc);
+    Free(out_img);
+  }
+}
+
+OutLine;
+
+ diff --git a/public/Wb/Demo/Graphics/Elephant.HC.HTML b/public/Wb/Demo/Graphics/Elephant.HC.HTML new file mode 100755 index 0000000..69d317c --- /dev/null +++ b/public/Wb/Demo/Graphics/Elephant.HC.HTML @@ -0,0 +1,236 @@ + + + + + + + + + + + +
+//Scroll Down
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+    <3>/* Graphics Not Rendered in HTML */
+
+
+
+    <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+    <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    <6>/* Graphics Not Rendered in HTML */
+
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  U8 *tmps;
+  Sprite3(dc,100,task->pix_height-60,0,<3>);
+  Sprite3(dc,194,task->pix_height-140,0,<4>);
+  Sprite3(dc,400,task->pix_height-10,0,<5>);
+  Sprite3(dc,50,task->pix_height-160,0,<6>);
+  tmps=SpriteInterpolate(Tri(tS,2.0),<1>,<2>);
+  Sprite3(dc,0,task->pix_height,0,tmps);
+  Free(tmps);
+}
+
+U0 SongTask(I64)
+{//Randomly generate (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("4qG5eCGqE4A5FCeDF4qB");
+    Play("4G5eCGqE4A5FCeDF4qB");
+    Play("4B5DeF4G5etE4BAqBAetA5EDeE4G");
+    Play("4qB5DeF4G5etE4BAqBAetA5EDeE4G");
+  }
+}
+
+U0 Main()
+{
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  Fs->text_attr=YELLOW<<4+BLACK;
+  "$BG,LTCYAN$%h31c",'\n';
+  View;
+  SettingsPop;
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Graphics/Extents.HC.HTML b/public/Wb/Demo/Graphics/Extents.HC.HTML new file mode 100755 index 0000000..61851bc --- /dev/null +++ b/public/Wb/Demo/Graphics/Extents.HC.HTML @@ -0,0 +1,76 @@ + + + + + + + + + + + +
+//Test image which we will determine the extents of.
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+U0 Extents()
+{
+  CDC *dc=DCAlias;
+  I64 min_x,max_x,min_y,max_y;
+
+  //Scrn, not win coordinates.
+  I64 h=Fs->pix_left+Fs->scroll_x,v=Fs->pix_top+Fs->scroll_y;
+
+  DocClear;
+  DCFill;
+
+  //This sets a flag to record the
+  //extents of what we draw and inits
+  //the max's and min's.  Vals are
+  //scrn coordinates.
+  DCExtentsInit(dc);
+
+  dc->thick=3;
+  Sprite3(dc,40,GR_HEIGHT>>1,0,<1>);
+
+  dc->color=LTRED;
+  dc->thick=1;
+
+  //This box is the extents.
+  GrLine(dc,dc->min_x-h,dc->min_y-v,dc->max_x-h,dc->min_y-v);
+  GrLine(dc,dc->min_x-h,dc->min_y-v,dc->min_x-h,dc->max_y-v);
+  GrLine(dc,dc->max_x-h,dc->max_y-v,dc->max_x-h,dc->min_y-v);
+  GrLine(dc,dc->max_x-h,dc->max_y-v,dc->min_x-h,dc->max_y-v);
+
+  DCDel(dc);
+  PressAKey;
+  DCFill;
+
+  SpriteExtents(<1>,&min_x,&max_x,&min_y,&max_y);
+  "X: %d to %d\n",min_x,max_x;
+  "Y: %d to %d\n",min_y,max_y;
+}
+
+Extents;
+
+ diff --git a/public/Wb/Demo/Graphics/FontEd.HC.HTML b/public/Wb/Demo/Graphics/FontEd.HC.HTML new file mode 100755 index 0000000..2c24ef1 --- /dev/null +++ b/public/Wb/Demo/Graphics/FontEd.HC.HTML @@ -0,0 +1,183 @@ + + + + + + + + + + + +
+/*After making a font...
+
+You can save it as a binary file with:
+        FileWrite("filename.BIN.Z",text.font,256*FONT_HEIGHT);
+
+You can load it with:
+        U64 *my_font=FileRead("filename.BIN.Z");
+        text.aux_font=my_font;
+
+<CTRL-ALT-f> will toggle main font and aux_font.
+
+If you want to change the system font permanently,
+save to a file with this font editor program
+and cut and paste the code into ::/Kernel/FontStd.HC.
+You will need to recompile Kernel by calling BootHDIns().
+
+See ::/Demo/ExtChars.HC, ::/Demo/Games/CharDemo.HC,
+::/Demo/Graphics/CharAnimation.HC and ::/Demo/ScrnCodes.HC.
+*/
+
+#define BLOW_UP_CHAR_X  (18*FONT_WIDTH)
+#define BLOW_UP_CHAR_Y  (4*FONT_HEIGHT)
+
+U8 cur_ch;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,k,c;
+  TextPrint(task,0,0,BLUE<<4+YELLOW,"Press <CTRL-ALT-f> to Toggle Aux Font.");
+  k=0;
+  for (i=0;i<16;i++)
+    for (j=0;j<16;j++) {
+      if (k==cur_ch) {
+        if (Blink)
+          c=(BLUE<<4+YELLOW)<<8 + k++;
+        else
+          c=(YELLOW<<4+BLUE)<<8 + k++;
+      } else
+        c=(BLUE<<4+WHITE)<<8 + k++;
+      TextChar(task,,j,i+2,c);
+    }
+
+  k=0;
+  for (i=0;i<FONT_HEIGHT;i++)
+    for (j=0;j<FONT_WIDTH;j++) {
+      if (Bt(&text.font[cur_ch],k++))
+        dc->color=YELLOW;
+      else
+        dc->color=BLUE;
+      GrRect(dc,BLOW_UP_CHAR_X+j*FONT_WIDTH,
+            BLOW_UP_CHAR_Y+i*FONT_HEIGHT,
+            FONT_WIDTH,FONT_HEIGHT);
+    }
+}
+
+U0 FESave(Bool pmt)
+{
+  U8 old_draw_it=Fs->draw_it;
+  CDoc *doc=DocNew;
+  I64 i;
+  for (i=0;i<256;i++) {
+    DocPrint(doc,"0x%016X,",text.font[i]);
+    if (Bt(char_bmp_safe_dollar,i))
+      DocPrint(doc,"//%c",i);
+    else if (i=='$')
+      DocPrint(doc,"//$$",i);
+    DocPrint(doc,"\n");
+  }
+  Fs->draw_it=NULL;
+  DocWrite(doc,pmt);
+  Fs->draw_it=old_draw_it;
+  DocDel(doc);
+}
+
+U0 FontEd()
+{
+  I64 msg_code,arg1,arg2,k;
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  SaveAs(,CH_CTRLA);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}");
+  AutoComplete;
+  DocCursor;
+  DocClear;
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+  cur_ch=0;
+  try {
+    Fs->draw_it=&DrawIt;
+    while (TRUE) {
+      switch (msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|1<<MSG_MS_MOVE)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case 0:
+              switch (arg2.u8[0]) {
+                case SC_CURSOR_LEFT:
+                  cur_ch--;
+                  break;
+                case SC_CURSOR_RIGHT:
+                  cur_ch++;
+                  break;
+                case SC_CURSOR_UP:
+                  cur_ch-=16;
+                  break;
+                case SC_CURSOR_DOWN:
+                  cur_ch+=16;
+                  break;
+
+              }
+              break;
+              goto fe_done;
+            case CH_CTRLA:
+              FESave(TRUE);
+              break;
+            case CH_ESC:
+              FESave(FALSE);
+            case CH_SHIFT_ESC:
+              goto fe_done;
+            default:
+              cur_ch=arg1;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+        case MSG_MS_R_DOWN:
+          if (0<=arg1<FONT_WIDTH*16 && 0<=arg2-2*FONT_HEIGHT<FONT_HEIGHT*16) {
+            cur_ch=(arg2/FONT_HEIGHT-2)*16+arg1/FONT_WIDTH;
+            break;
+          } //fall through
+        case MSG_MS_MOVE:
+          k=((arg2-BLOW_UP_CHAR_Y)/FONT_HEIGHT)*FONT_WIDTH+
+                (arg1-BLOW_UP_CHAR_X)/FONT_WIDTH;
+          if (0<=k<FONT_WIDTH*FONT_HEIGHT) {
+            if (ms.lb||msg_code==MSG_MS_L_DOWN)
+              Bts(&text.font[cur_ch],k);
+            if (ms.rb||msg_code==MSG_MS_R_DOWN)
+              Btr(&text.font[cur_ch],k);
+          }
+          break;
+      }
+    }
+fe_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  MenuPop;
+  SettingsPop;
+}
+
+FontEd;
+
+ diff --git a/public/Wb/Demo/Graphics/Grid.HC.HTML b/public/Wb/Demo/Graphics/Grid.HC.HTML new file mode 100755 index 0000000..706e348 --- /dev/null +++ b/public/Wb/Demo/Graphics/Grid.HC.HTML @@ -0,0 +1,61 @@ + + + + + + + + + + + +
+#define GRID    5
+
+U0 DrawMyMs(CDC *dc,I64 x,I64 y)
+{
+  dc->thick=1;
+  dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
+  GrRect(dc,x,y,GRID,GRID);
+}
+
+U0 GridDemo()
+{
+  CGridGlbls old_grid;
+  U0 (*old_draw_ms)(CDC *dc,I64 x,I64 y); //Can't init this type of var.
+  MemCpy(&old_grid,&ms_grid,sizeof(CGridGlbls));
+  GridInit;
+  ms_grid.snap=TRUE; //You can set other stuff.
+  ms_grid.x=GRID;
+  ms_grid.y=GRID;
+  old_draw_ms=gr.fp_draw_ms;
+  gr.fp_draw_ms=&DrawMyMs;
+  while (!ms.lb)  {//Left bttn to exit.
+    GrPlot(,ms.pos.x,ms.pos.y);
+    Yield;
+  }
+  DCFill;
+  gr.fp_draw_ms=old_draw_ms;
+  MemCpy(&ms_grid,&old_grid,sizeof(CGridGlbls));
+}
+
+GridDemo;
+
+ diff --git a/public/Wb/Demo/Graphics/Hanoi.HC.HTML b/public/Wb/Demo/Graphics/Hanoi.HC.HTML new file mode 100755 index 0000000..076bba6 --- /dev/null +++ b/public/Wb/Demo/Graphics/Hanoi.HC.HTML @@ -0,0 +1,185 @@ + + + + + + + + + + + +
+#define DISKS_NUM       6
+#define PEDESTAL_HEIGHT 20
+#define DISK_HEIGHT     7
+#define DISK_UNIT_WIDTH 5
+
+I64 poles_x[3];
+I64 disks_x[DISKS_NUM],disks_y[DISKS_NUM],disks_pole[DISKS_NUM];
+
+I64 OtherPole(I64 pole1,I64 pole2)
+{
+  return 3-pole1-pole2;
+}
+ 
+I64 TopDisk(I64 pole)
+{
+  I64 i;
+  for (i=0;i<DISKS_NUM;i++)
+    if (disks_pole[i]==pole)
+      return i;
+  return -1;
+}
+
+I64 PosInStk(I64 pole,I64 disk)
+{
+  I64 res=0,i;
+  for (i=DISKS_NUM-1;i>disk;i--)
+    if (disks_pole[i]==pole)
+      res++;
+  return res;
+}
+
+U0 SetDisksRestXY()
+{
+  I64 i;
+  for (i=0;i<DISKS_NUM;i++) {
+    disks_x[i]=poles_x[disks_pole[i]];
+    disks_y[i]=Fs->pix_height-PEDESTAL_HEIGHT
+          -(DISK_HEIGHT+1)/2-1-(DISK_HEIGHT+1)*PosInStk(disks_pole[i],i);
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i;
+
+  for (i=0;i<3;i++)
+    poles_x[i]=(1+i)*task->pix_width/4;
+
+  dc->color=BLACK;
+  GrRect(dc,poles_x[0]-50,task->pix_height-PEDESTAL_HEIGHT,
+        poles_x[2]-poles_x[0]+100,PEDESTAL_HEIGHT-FONT_HEIGHT);
+  dc->color=DKGRAY;
+  GrRect(dc,poles_x[0]-49,task->pix_height-PEDESTAL_HEIGHT+1,
+        poles_x[2]-poles_x[0]+98,PEDESTAL_HEIGHT-FONT_HEIGHT-2);
+
+  for (i=0;i<3;i++) {
+    dc->color=BLACK;
+    GrRect(dc,poles_x[i]-3,
+          task->pix_height-PEDESTAL_HEIGHT-(DISKS_NUM+1)*(DISK_HEIGHT+1),
+          7,(DISKS_NUM+1)*(DISK_HEIGHT+1));
+    dc->color=YELLOW;
+    GrRect(dc,poles_x[i]-2,
+          task->pix_height-PEDESTAL_HEIGHT+1-(DISKS_NUM+1)*(DISK_HEIGHT+1),
+          5,(DISKS_NUM+1)*(DISK_HEIGHT+1)-1);
+  }
+
+  for (i=0;i<DISKS_NUM;i++) {
+    dc->color=BLACK;
+    GrRect(dc,disks_x[i]-(i+1)*DISK_UNIT_WIDTH,
+          disks_y[i]-DISK_HEIGHT/2,(i+1)*(DISK_UNIT_WIDTH*2)+1,DISK_HEIGHT);
+    dc->color=gr_rainbow_10[i];
+    GrRect(dc,disks_x[i]-(i+1)*DISK_UNIT_WIDTH+1,
+          disks_y[i]-DISK_HEIGHT/2+1,(i+1)*(DISK_UNIT_WIDTH*2)-1,DISK_HEIGHT-2);
+  }
+}
+
+U0 MySleep()
+{
+  if (ScanChar)
+    throw;
+  Sleep(3);
+}
+
+U0 MoveDisks(I64 src_pole,I64 dst_pole,I64 num)
+{
+  I64 top,x,y;
+  if (num>1)
+    MoveDisks(src_pole,OtherPole(src_pole,dst_pole),num-1);
+  DocClear;
+  "$CM+BY,0,0$Disk:%d from %d to %d\n",TopDisk(src_pole),src_pole,dst_pole;
+
+  top=TopDisk(src_pole);
+  for (y=disks_y[top];
+        y>Fs->pix_height-PEDESTAL_HEIGHT-(DISK_HEIGHT+1)/2
+        -(DISK_HEIGHT+1)*(DISKS_NUM+2);y--) {
+    disks_y[top]=y;
+    MySleep;
+  }
+  if (src_pole<dst_pole)
+    for (x=poles_x[src_pole];x<=poles_x[dst_pole];x++) {
+      disks_x[top]=x;
+      MySleep;
+    }
+  else
+    for (x=poles_x[src_pole];x>=poles_x[dst_pole];x--) {
+      disks_x[top]=x;
+      MySleep;
+    }
+
+  disks_pole[top]=dst_pole;
+  for (y=disks_y[top];
+        y<Fs->pix_height-PEDESTAL_HEIGHT-(DISK_HEIGHT+1)/2-1
+        -(DISK_HEIGHT+1)*PosInStk(dst_pole,top);y++) {
+    disks_y[top]=y;
+    MySleep;
+  }
+  SetDisksRestXY;
+  if (num>1)
+    MoveDisks(OtherPole(src_pole,dst_pole),dst_pole,num-1);
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<3;i++)
+    poles_x[i]=(1+i)*Fs->pix_width/4;
+
+  for (i=0;i<DISKS_NUM;i++)
+    disks_pole[i]=0;
+
+  SetDisksRestXY;
+}
+
+U0 Hanoi()
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+
+  Sleep(1000);
+  try {
+    MoveDisks(0,2,DISKS_NUM);
+    Beep; Beep;
+    DocClear;
+    DocBottom;
+    PressAKey;
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+}
+
+Hanoi;
+
+ diff --git a/public/Wb/Demo/Graphics/Lattice.HC.HTML b/public/Wb/Demo/Graphics/Lattice.HC.HTML new file mode 100755 index 0000000..be3317c --- /dev/null +++ b/public/Wb/Demo/Graphics/Lattice.HC.HTML @@ -0,0 +1,297 @@ + + + + + + + + + + + +
+#define TURTLE_SIZE             4
+#define TURTLE_SPEED_STEP       2
+
+#define ANGLES  35
+F64 angles[ANGLES]={
+-2*pi/1,-2*pi/2,-2*pi/3,-2*pi/4,-2*pi/5,
+-2*pi/6,-2*pi/8,-2*pi/9,-2*pi/10,
+-2*pi/12,-2*pi/15,-2*pi/18,-2*pi/20,
+-2*pi/24,-2*pi/30,-2*pi/36,-2*pi/40,
+0,
+2*pi/40,2*pi/36,2*pi/30,2*pi/24,
+2*pi/20,2*pi/18,2*pi/15,2*pi/12,
+2*pi/10,2*pi/9,2*pi/8,2*pi/6,
+2*pi/5,2*pi/4,2*pi/3,2*pi/2,2*pi/1
+};
+
+class Turtle
+{
+  F64 x,y,z,speed,theta,w;
+  I64 dtheta_idx;
+  CColorROPU16 edge,middle;
+  Bool ends,first;
+} tt;
+
+U0 TurtlePlot(CDC *dc,Turtle *t,CColorROPU16 edge,CColorROPU16 middle)
+{
+  F64 w=t->w/2.0-1;
+  if (w<0) w=0;
+  dc->color=middle;
+  GrLine3(dc,t->x+w*Cos(t->theta+pi/2),t->y+w*Sin(t->theta+pi/2),t->z,
+        t->x+w*Cos(t->theta-pi/2),t->y+w*Sin(t->theta-pi/2),t->z);
+  w=t->w/2.0;
+  dc->color=edge;
+  GrPlot3(dc,t->x+w*Cos(t->theta+pi/2),t->y+w*Sin(t->theta+pi/2),t->z);
+  GrPlot3(dc,t->x+w*Cos(t->theta-pi/2),t->y+w*Sin(t->theta-pi/2),t->z);
+}
+
+U0 TurtleMicroMove(Turtle *t,F64 dt)
+{
+  t->x+=dt*t->speed*Cos(t->theta);
+  t->y+=dt*t->speed*Sin(t->theta);
+  t->theta=Wrap(t->theta+dt*angles[t->dtheta_idx]);
+}
+
+U0 TurtleEnd(CDC *dc,Turtle *t,CColorROPU16 edge,CColorROPU16 middle,F64 theta)
+{
+  F64 r,x,y2;
+  Turtle t2;
+  if (r=t->w) {
+    MemCpy(&t2,t,sizeof(Turtle));  //Save
+    x=0;
+    while (TRUE) {
+      t->x+=1/r*Cos(theta);
+      t->y+=1/r*Sin(theta);
+      x+=1/r;
+      y2=r*r-4*x*x;
+      if (y2>=0) {
+        t->w=Sqrt(y2);
+        TurtlePlot(dc,t,edge,middle);
+      } else
+        break;
+    }
+    MemCpy(t,&t2,sizeof(Turtle));
+  }
+}
+
+U0 TurtleMove(CDC *dc,Turtle *t,CColorROPU16 edge,CColorROPU16 middle)
+{
+  I64 i,l=16*AbsI64(t->w+1)*AbsI64(t->speed+1);
+
+  if (t->ends && t->first)
+    TurtleEnd(dc,t,edge,middle,t->theta+pi);
+  t->first=FALSE;
+
+  for (i=0;i<l;i++) {
+    TurtleMicroMove(t,1.0/l);
+    TurtlePlot(dc,t,edge,middle);
+  }
+  if (t->ends)
+    TurtleEnd(dc,t,edge,middle,t->theta);
+}
+
+U0 TurtleInit(Turtle *t)
+{
+  MemSet(t,0,sizeof(Turtle));
+  t->x=Fs->pix_width>>1;
+  t->y=Fs->pix_height>>1;
+  t->z=5;
+  t->edge=BLACK;
+  t->middle=YELLOW;
+  t->dtheta_idx=ANGLES/2;
+  t->first=TRUE;
+  t->ends=TRUE;
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  Turtle t2;
+  MemCpy(&t2,&tt,sizeof(Turtle));
+  GrPrint(dc,0,0,"Layer:%f Speed:%f theta:%5.1f dtheta:%5.1f Width:%f",
+        tt.z,tt.speed,tt.theta*180/pi,angles[tt.dtheta_idx]*180/pi,tt.w);
+
+  TurtleMove(dc,&t2,RED,LTRED);
+  dc->color=LTRED;
+  GrLine(dc,t2.x+TURTLE_SIZE*Cos(t2.theta+pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta+pi/2),
+        t2.x+TURTLE_SIZE*Cos(t2.theta-pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta-pi/2));
+  GrLine(dc,t2.x+TURTLE_SIZE*Cos(t2.theta+pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta+pi/2),
+        t2.x+TURTLE_SIZE*Cos(t2.theta),    t2.y+TURTLE_SIZE*Sin(t2.theta));
+  GrLine(dc,t2.x+TURTLE_SIZE*Cos(t2.theta-pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta-pi/2),
+        t2.x+TURTLE_SIZE*Cos(t2.theta),    t2.y+TURTLE_SIZE*Sin(t2.theta));
+}
+
+U0 SetMenu()
+{
+  I64 i;
+  U8 buf[STR_LEN];
+  CMenuEntry *tmpse;
+  for (i=0;i<=9;i++) {
+    StrPrint(buf,"Settings/Layer%d",i);
+    if (tmpse=MenuEntryFind(Fs->cur_menu,buf)) {
+      if (i==tt.z)
+        tmpse->checked=TRUE;
+      else
+        tmpse->checked=FALSE;
+    }
+  }
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Settings/Ends")) {
+    if (tt.ends)
+      tmpse->checked=TRUE;
+    else
+      tmpse->checked=FALSE;
+  }
+}
+
+U0 Lattice()
+{
+  Bool aim=FALSE;
+  I64 arg1,arg2;
+  CDC  *dc=DCAlias;
+  DCDepthBufAlloc(dc);
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Step(,CH_SPACE);"
+        "  Accelerator(,,SC_CURSOR_UP);"
+        "  Break(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        "Settings {"
+        "  Color(,'c');"
+        "  Wider(,'+');"
+        "  Narrower(,'-');"
+        "  Ends(,'e');"
+        "  Layer0(,'0');"
+        "  Layer1(,'1');"
+        "  Layer2(,'2');"
+        "  Layer3(,'3');"
+        "  Layer4(,'4');"
+        "  Layer5(,'5');"
+        "  Layer6(,'6');"
+        "  Layer7(,'7');"
+        "  Layer8(,'8');"
+        "  Layer9(,'9');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  TurtleInit(&tt);
+  SetMenu;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_FOCUS_TASK_MENU
+        -WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|
+            1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP|1<<MSG_MS_MOVE)) {
+        case MSG_MS_L_DOWN:
+          tt.first=TRUE;
+          tt.x=arg1;
+          tt.y=arg2;
+          break;
+        case MSG_MS_R_DOWN:
+          aim=TRUE;
+          tt.theta=Arg(arg1-tt.x,arg2-tt.y);
+          break;
+        case MSG_MS_MOVE:
+          if (aim)
+            tt.theta=Arg(arg1-tt.x,arg2-tt.y);
+          break;
+        case MSG_MS_R_UP:
+          tt.theta=Arg(arg1-tt.x,arg2-tt.y);
+          aim=FALSE;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case 0:
+              switch (arg2.u8[0]) {
+                case SC_CURSOR_LEFT:
+                  if (tt.dtheta_idx)
+                    tt.dtheta_idx--;
+                  break;
+                case SC_CURSOR_RIGHT:
+                  if (tt.dtheta_idx<ANGLES-1)
+                    tt.dtheta_idx++;
+                  break;
+                case SC_CURSOR_UP:
+                  tt.speed+=TURTLE_SPEED_STEP;
+                  break;
+                case SC_CURSOR_DOWN:
+                  if (tt.speed>=TURTLE_SPEED_STEP)
+                    tt.speed-=TURTLE_SPEED_STEP;
+                  break;
+              }
+              break;
+            case '0'...'9':
+              tt.z=arg1-'0';
+              SetMenu;
+              break;
+            case 'c':
+              tt.middle=PopUpColor("Mid Color\n\n");
+              tt.edge  =PopUpColor("Edge Color\n\n");
+              break;
+            case 'e':
+              tt.ends=!tt.ends;
+              break;
+            case '+':
+              tt.w++;
+              break;
+            case '-':
+              if (tt.w)
+                tt.w--;
+              break;
+            case '\n':
+              DCFill(dc);
+              TurtleInit(&tt);
+              SetMenu;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto lt_done;
+            case CH_SPACE:
+              TurtleMove(dc,&tt,tt.edge,tt.middle);
+              break;
+          }
+      }
+    }
+lt_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCFill(dc);
+  DCDel(dc);
+  MenuPop;
+}
+
+Lattice;
+
+ diff --git a/public/Wb/Demo/Graphics/Life.HC.HTML b/public/Wb/Demo/Graphics/Life.HC.HTML new file mode 100755 index 0000000..26a185e --- /dev/null +++ b/public/Wb/Demo/Graphics/Life.HC.HTML @@ -0,0 +1,129 @@ + + + + + + + + + + + +
+//Conway's Game of Life
+
+CDC *dc[2]; //dbl buf
+I64 cur_dc,;
+Bool restart;
+
+U0 DrawIt(CTask *,CDC *dc2)
+{
+  dc[cur_dc]->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc2,0,0,dc[cur_dc]);
+}
+
+U0 AnimateTask(I64)
+{
+  I64 x,y,x1,y1,cnt,next_dc;
+  while (TRUE) {
+    next_dc=cur_dc^1;
+start_over:
+    restart=FALSE;
+    DCClear(dc[next_dc]);
+    for (y=1;y<Fs->parent_task->pix_height-1;y++) {
+      for (x=1;x<Fs->parent_task->pix_width-1;x++) {
+        cnt=0;
+        for (y1=y-1;y1<=y+1;y1++)
+          for (x1=x-1;x1<=x+1;x1++)
+            if (GrPeek(dc[cur_dc],x1,y1)==GREEN)
+              cnt++;
+        if (restart) goto start_over;
+        if (GrPeek(dc[cur_dc],x,y)==GREEN) {
+          if (cnt==3) {
+            dc[next_dc]->color=GREEN;
+            GrPlot(dc[next_dc],x,y);
+          }
+        } else {
+//        if (cnt==3) {//Use this for the classic rules
+          if (cnt==2) {
+            dc[next_dc]->color=GREEN;
+            GrPlot(dc[next_dc],x,y);
+          }
+        }
+      }
+      Yield;
+    }
+    Sleep(50);
+    cur_dc=next_dc;
+  }
+}
+
+public U0 Life()
+{
+  I64 msg_code,cnt,x1,y1,x2,y2,arg1,arg2;
+
+  dc[0]=DCNew(GR_WIDTH,GR_HEIGHT);
+  dc[1]=DCNew(GR_WIDTH,GR_HEIGHT);
+  cur_dc=0;
+  restart=FALSE;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
+    switch (msg_code) {
+      case MSG_MS_L_DOWN:
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        cnt=0;
+        while (msg_code!=MSG_MS_L_UP) {
+          restart=TRUE;
+          dc[cur_dc]->color=GREEN;
+          dc[cur_dc]->thick=0.04*ms.speed;
+          GrLine3(dc[cur_dc],x1,y1,0,x2,y2,0);
+          restart=TRUE;
+          msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          x1=x2; y1=y2;
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc[cur_dc],x1,y1,0,x2,y2,0);
+        break;
+      case MSG_KEY_DOWN:
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || !arg1);
+  GetMsg(,,1<<MSG_KEY_UP);
+  SettingsPop;
+  DCFill;
+  DCDel(dc[0]);
+  DCDel(dc[1]);
+}
+
+Life;
+
+ diff --git a/public/Wb/Demo/Graphics/LightTable.HC.HTML b/public/Wb/Demo/Graphics/LightTable.HC.HTML new file mode 100755 index 0000000..b37bb71 --- /dev/null +++ b/public/Wb/Demo/Graphics/LightTable.HC.HTML @@ -0,0 +1,680 @@ + + + + + + + + + + + +
+/*
+There is a coarse and a fine-grained.
+The coarse gets flood-filled but the
+fine grained is only outlines.
+*/
+
+class Photon
+{
+  Photon *next,*last;
+  CD3 p,v,n,p_normal_inhibit;
+} p_root[mp_cnt];
+I64 p_root_locks;
+
+#define ANIMATE_JIFFIES (JIFFY_FREQ*0.01)
+I64 master_sleep_jiffy;
+CTask *animate_tasks[mp_cnt];
+
+#define LENS_COLOR      WHITE
+#define MIRROR_COLOR    DKGRAY
+CDC *map;
+
+I64 photon_cnt,mirror_cnt,snell_cnt,normal_inhibit,zero_normal;
+Bool full_speed,show_normals;
+
+U8      *bmp_refract,*bmp_reflect;
+F64     bmp_scale,find_normal_dist_sqr;
+I64     bmp_mem,bmp_width,bmp_height,bmp_norm_radius;
+
+#define BORDER  10
+I64 BmpPeek(U8 *bmp,I64 x,I64 y)
+{
+  return Bt(bmp,y*bmp_width+x);
+}
+
+U0 BmpPlot(U8 *bmp,I64 x,I64 y,I64)
+{
+  if (0<=x<bmp_width && 0<=y<bmp_height)
+    Bts(bmp,y*bmp_width+x);
+}
+
+U0 BmpLine(U8 *bmp,F64 x1,F64 y1,F64 x2,F64 y2)
+{
+  Line(bmp,x1*bmp_scale,y1*bmp_scale,0,x2*bmp_scale,y2*bmp_scale,0,&BmpPlot);
+}
+
+Photon *PhotonNew()
+{
+  I64 num=photon_cnt++%mp_cnt;
+  Photon *res=CAlloc(sizeof(Photon));
+  while (LBts(&p_root_locks,num))
+    Yield;
+  QueIns(res,p_root[num].last);
+  LBtr(&p_root_locks,num);
+  return res;
+}
+
+#define VECTOR 20
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  Photon *tmpp;
+  GrBlot(dc,0,0,map);
+  dc->color=WHITE;
+  GrPrint(dc,0,0,"Mem:0x%X %,dMeg Scale:%0.3f (%d,%d)-->(%d,%d)",
+        bmp_mem,bmp_mem/1024/1024,bmp_scale,
+        map->width,map->height,bmp_width,bmp_height);
+  GrPrint(dc,0,FONT_HEIGHT,
+        "PhotonCnt:%d MirrorCnt:%d SnellCnt:%d SnellInhibit:%d ZeroNormal:%d",
+        photon_cnt,mirror_cnt,snell_cnt,normal_inhibit,zero_normal);
+  for (i=0;i<mp_cnt;i++) {
+    while (LBts(&p_root_locks,i))
+      Yield;
+    tmpp=p_root[i].next;
+    while (tmpp!=&p_root[i]) {
+      dc->color=LTRED;
+      GrLine(dc,tmpp->p.x-VECTOR*tmpp->v.x,tmpp->p.y-VECTOR*tmpp->v.y,
+            tmpp->p.x,tmpp->p.y);
+      if (show_normals) {
+        dc->color=LTGREEN;
+        GrLine(dc,tmpp->p.x,tmpp->p.y,
+              tmpp->p.x+VECTOR*tmpp->n.x,tmpp->p.y+VECTOR*tmpp->n.y);
+      }
+      tmpp=tmpp->next;
+    }
+    LBtr(&p_root_locks,i);
+  }
+}
+
+#define WING    9
+
+U0 RayBurst(I64 x1,I64 y1,I64 x2,I64 y2)
+{
+  CD3 p,v,n,n2;
+  I64 i;
+  Photon *tmpp;
+  if ((x1!=x2 || y1!=y2) && BORDER+WING<x2<map->width-BORDER-WING &&
+        BORDER+WING<y2<map->height-BORDER-WING) {
+    D3Equ(&p,x2,y2);
+    D3Equ(&v,x2-x1,y2-y1);
+    D3Unit(&v);
+    D3Equ(&n,v.y,-v.x);
+
+    tmpp=PhotonNew;
+    D3Copy(&tmpp->p,&p);
+    D3Copy(&tmpp->v,&v);
+
+    for (i=2;i<=WING;i+=3) {
+      D3Mul(&n2,i,&n);
+
+      tmpp=PhotonNew;
+      D3Add(&tmpp->p,&p,&n2);
+      D3Copy(&tmpp->v,&v);
+
+      tmpp=PhotonNew;
+      D3Sub(&tmpp->p,&p,&n2);
+      D3Copy(&tmpp->v,&v);
+    }
+  }
+}
+
+U0 RandomBurst()
+{
+  I64 i;
+  F64 theta;
+  Photon *tmpp;
+  for (i=0;i<256;i++) {
+    tmpp=PhotonNew;
+    D3Equ(&tmpp->p,(Fs->pix_width-BORDER*2)*Rand+BORDER,
+                (Fs->pix_height-BORDER*2)*Rand+BORDER);
+    theta=2*pi*Rand;
+    D3Equ(&tmpp->v,Cos(theta),Sin(theta));
+  }
+}
+
+U0 FindNormal(U8 *bmp,Photon *tmpp)
+{
+  CD3 p,p1,p2;
+  F64 step,x,y,theta=Arg(tmpp->v.x,tmpp->v.y),phi;
+  I64 state;
+
+  D3Copy(&tmpp->p_normal_inhibit,&tmpp->p);
+
+  //Coarse grains has black and white filled-in BSplines.
+  //Fine grained has only white outline without being filled-in.
+
+  //Back-up a step and move fwd to get a fined-grained value
+  //for the point of contact.
+  D3SubEqu(&tmpp->p,&tmpp->v);
+  D3Mul(&p,bmp_scale,&tmpp->p);
+  D3Copy(&p1,&p);
+  while (BmpPeek(bmp,p1.x,p1.y)==BLACK &&
+        D3DistSqr(&p,&p1)<find_normal_dist_sqr)
+    D3AddEqu(&p1,&tmpp->v);
+  D3Copy(&p,&p1);
+  D3Div(&tmpp->p,&p,bmp_scale);
+
+  //Draw an arc one direction, finding point of contact.
+  for (step=1.0;step>=0.01;step/=4) {
+    for (phi=0;phi<=pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4-phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4-phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p1;
+      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4+phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4+phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p1;
+    }
+    for (;phi<=3*pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4-phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4-phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p1;
+    }
+  }
+fn_p1:
+  if (state)
+    D3Equ(&p1,x,y);
+  else
+    D3Copy(&p1,&tmpp->p);
+
+    //Draw an arc other direction, finding point of contact.
+  for (step=1.0;step>=0.01;step/=4) {
+    for (phi=0;phi<=pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4+phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4+phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p2;
+      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4-phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4-phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p2;
+    }
+    for (;phi<=3*pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4+phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4+phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p2;
+    }
+  }
+fn_p2:
+  if (state)
+    D3Equ(&p2,x,y);
+  else
+    D3Copy(&p2,&tmpp->p);
+
+  D3Sub(&p,&p1,&p2);
+  if (D3NormSqr(&p)<0.01) {
+    D3Equ(&tmpp->n,Cos(theta),Sin(theta));
+    lock {zero_normal++;}
+  } else {
+    D3Equ(&tmpp->n,p.y,-p.x);
+    if (D3Dot(&tmpp->n,&tmpp->v)<0)
+      D3Equ(&tmpp->n,-p.y,p.x);
+    D3Unit(&tmpp->n);
+  }
+}
+
+U0 Mirror(Photon *tmpp)
+{/*<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+thetaout = pi+thetan -  (thetain-thetan)
+
+*/
+  F64 theta=Arg(tmpp->v.x,tmpp->v.y),thetan;
+  FindNormal(bmp_reflect,tmpp);
+  thetan=Arg(tmpp->n.x,tmpp->n.y);
+
+  D3Equ(&tmpp->v,Cos(2*thetan+pi-theta),Sin(2*thetan+pi-theta));
+  lock {mirror_cnt++;}
+}
+
+U0 SnellsLaw(Photon *tmpp,I64 last,I64 next)
+{
+//n1 and n2 are refraction index.
+//n1 Sin(theta1) == n2 Sin(theta2)
+  F64 theta=Arg(tmpp->v.x,tmpp->v.y),thetan,n1,n2,theta1,theta2;
+  if (last==LENS_COLOR)
+    n1=1.5;
+  else
+    n1=1.0;
+  if (next==LENS_COLOR)
+    n2=1.5;
+  else
+    n2=1.0;
+  FindNormal(bmp_refract,tmpp);
+  thetan=Arg(tmpp->n.x,tmpp->n.y);
+
+  //Dot=m1m2Cos(theta);
+  theta1=ACos(D3Dot(&tmpp->n,&tmpp->v));
+  theta2=ASin(n1*Sin(theta1)/n2);
+  if (Wrap(theta-thetan)>=0)
+    theta=thetan+theta2;
+  else
+    theta=thetan-theta2;
+
+  D3Equ(&tmpp->v,Cos(theta),Sin(theta));
+  lock {snell_cnt++;}
+}
+
+U0 AnimateTask(I64)
+{
+  while (TRUE) {
+    master_sleep_jiffy+=ANIMATE_JIFFIES;
+    if (cnts.jiffies>=master_sleep_jiffy)
+      master_sleep_jiffy=cnts.jiffies+ANIMATE_JIFFIES;
+    SleepUntil(master_sleep_jiffy);
+  }
+}
+
+#define BABY_STEPS      4
+
+U0 MPAnimateTask(I64)
+{
+  I64   i,last_master_jiffy=0,
+        timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES,
+        last,next;
+  Bool  inhibit;
+  CD3   step;
+  Photon *tmpp,*root=&p_root[Gs->num];
+  while (TRUE) {
+    while (LBts(&p_root_locks,Gs->num))
+      Yield;
+    tmpp=root->next;
+    while (tmpp!=root) {
+      for (i=0;i<BABY_STEPS;i++) {
+        last=GrPeek(map,tmpp->p.x,tmpp->p.y);
+        D3Div(&step,&tmpp->v,BABY_STEPS);
+        D3AddEqu(&tmpp->p,&step);
+        if (tmpp->p.x<BORDER) {
+          tmpp->p.x=2*BORDER-tmpp->p.x;
+          tmpp->v.x=-tmpp->v.x;
+        }
+        if (tmpp->p.x>=map->width-BORDER) {
+          tmpp->p.x-=tmpp->p.x-map->width+BORDER;
+          tmpp->v.x=-tmpp->v.x;
+        }
+        if (tmpp->p.y<BORDER) {
+          tmpp->p.y=2*BORDER-tmpp->p.y;
+          tmpp->v.y=-tmpp->v.y;
+        }
+        if (tmpp->p.y>=map->height-BORDER) {
+          tmpp->p.y-=tmpp->p.y-map->height+BORDER;
+          tmpp->v.y=-tmpp->v.y;
+        }
+        next=GrPeek(map,tmpp->p.x,tmpp->p.y);
+
+        if (D3DistSqr(&tmpp->p_normal_inhibit,&tmpp->p)<4.0)
+          inhibit=TRUE;
+        else
+          inhibit=FALSE;
+
+        if (last!=next) {
+          if ((last==BLACK && next==LENS_COLOR) ||
+                (last==LENS_COLOR && next==BLACK)) {
+            if (inhibit)
+              lock {normal_inhibit++;}
+            else
+              SnellsLaw(tmpp,last,next);
+          } else if (last==BLACK && next==MIRROR_COLOR) {
+            if (inhibit)
+              lock {normal_inhibit++;}
+            else
+              Mirror(tmpp);
+          } else if (!inhibit)
+            D3Zero(&tmpp->p_normal_inhibit);
+        } else if (!inhibit)
+          D3Zero(&tmpp->p_normal_inhibit);
+      }
+
+      tmpp=tmpp->next;
+      if (cnts.jiffies>=timeout_jiffy)
+        break;
+    }
+    LBtr(&p_root_locks,Gs->num);
+    if (cnts.jiffies>=timeout_jiffy) {
+      Sleep(1);
+      timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES;
+    }
+    if (!full_speed) {
+      while (master_sleep_jiffy==last_master_jiffy)
+        Sleep(1);
+      last_master_jiffy=master_sleep_jiffy;
+      SleepUntil(master_sleep_jiffy);
+      timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES;
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  master_sleep_jiffy=cnts.jiffies;
+  full_speed=show_normals=FALSE;
+  photon_cnt=mirror_cnt=snell_cnt=normal_inhibit=zero_normal=0;
+  map=DCNew(Fs->pix_width,Fs->pix_height);
+  for (i=0;i<mp_cnt;i++) {
+    while (LBts(&p_root_locks,i))
+      Yield;
+    QueInit(&p_root[i]);
+    LBtr(&p_root_locks,i);
+  }
+//x*y=bmp_mem*8
+  //x/y=640/480
+  //x=640/480*y
+  //640/480*y^2=bmp_mem*8
+  //y=Sqrt(bmp_mem*8*480/640)
+  //bmp_scale=Sqrt(bmp_mem*8*480/640)/480
+  bmp_scale=Sqrt(bmp_mem/2*8*Fs->pix_height/Fs->pix_width)/Fs->pix_height;
+
+  find_normal_dist_sqr=2*Sqr(bmp_scale);
+#assert Sqrt(2)<=BORDER
+
+  bmp_width =bmp_scale*Fs->pix_width;
+  bmp_height=bmp_scale*Fs->pix_height;
+  bmp_refract=CAlloc(bmp_width*bmp_height/8);
+  bmp_reflect=CAlloc(bmp_width*bmp_height/8);
+  bmp_norm_radius=Min(10*bmp_scale,250);
+#assert 10<=BORDER
+}
+
+U0 CleanUp()
+{
+  I64 i;
+  for (i=0;i<mp_cnt;i++) {
+    while (LBts(&p_root_locks,i))
+      Yield;
+    QueDel(&p_root[i],TRUE);
+    LBtr(&p_root_locks,i);
+  }
+  DCDel(map);
+  Free(bmp_refract);
+  Free(bmp_reflect);
+}
+
+#define LTM_REFLECT_LINE        0
+#define LTM_REFLECT_SPLINE      1
+#define LTM_REFRACT_LINE        2
+#define LTM_REFRACT_SPLINE      3
+#define LTM_REFRACT_FLOOD_FILL  4
+#define LTM_TEST_RAY            5
+
+U0 LTMenuSet(I64 mode)
+{
+  CMenuEntry *entry=MenuEntryFind(Fs->cur_menu,"View/ToggleNormals");
+  if (show_normals)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/ReflectLine");
+  if (mode==LTM_REFLECT_LINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/ReflectSpline");
+  if (mode==LTM_REFLECT_SPLINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractLine");
+  if (mode==LTM_REFRACT_LINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractSpline");
+  if (mode==LTM_REFRACT_SPLINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractFloodFill");
+  if (mode==LTM_REFRACT_FLOOD_FILL)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/TestRay");
+  if (mode==LTM_TEST_RAY)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+}
+
+#define PTS_NUM 1024
+U0 LightTable()
+{
+  I64 msg_code,mode=LTM_REFLECT_LINE,i,cnt,arg1,arg2,x1,y1,x2,y2;
+  CD3I32 *c=MAlloc(PTS_NUM*sizeof(CD3I32));
+
+  p_root_locks=0;
+  MenuPush(
+        "File {"
+        "  Restart(,'\n');"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Mode {"
+        "  ReflectLine(,'0');"
+        "  ReflectSpline(,'1');"
+        "  RefractLine(,'2');"
+        "  RefractSpline(,'3');"
+        "  RefractFloodFill(,'4');"
+        "  TestRay(,'5');"
+        "}"
+        "Play {"
+        "  RandomBurst(,'r');"
+        "  ElapseTime(,'e');"
+        "}"
+        "View {"
+        "  ToggleNormals(,'n');"
+        "}"
+        );
+  LTMenuSet(mode);
+
+  MemBIOSRep;
+  bmp_mem=GetI64("\n\n\nHow much memory for the high resolution\n"
+        "shadow bitmap that helps improve the\n"
+        "accuracy of the normal vector estimate?\n"
+        "You can choose up to the largest\n"
+        "contiguous chunk of physical memory.\n\n"
+        "Mem (0x%0X):",1024*1024*16);
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-
+        WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU;
+  Fs->text_attr=BLACK<<4+WHITE; //Current CTask is Fs segment register.
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->draw_it=&DrawIt;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  for (i=0;i<mp_cnt;i++)
+    animate_tasks[i]=Spawn(&MPAnimateTask,NULL,"MPAnimate",i);
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_R_UP);
+lt_restart:
+      switch (msg_code) {
+        case MSG_MS_L_UP:
+          Sweep(100,90,100);
+          x2=arg1; y2=arg2;
+          switch (mode) {
+            case LTM_REFRACT_FLOOD_FILL:
+              map->color=LENS_COLOR;
+              GrFloodFill(map,x2,y2);
+              mode=LTM_REFLECT_LINE;
+              LTMenuSet(mode);
+              break;
+            case LTM_TEST_RAY:
+              RayBurst(x1,y1,x2,y2);
+              break;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          x1=arg1; y1=arg2;
+          switch (mode) {
+            case LTM_REFLECT_LINE:
+            case LTM_REFRACT_LINE:
+              if (mode==LTM_REFLECT_LINE)
+                map->color=ROP_XOR+MIRROR_COLOR;
+              else
+                map->color=ROP_XOR+LENS_COLOR;
+              while (TRUE) {
+                x2=arg1; y2=arg2;
+                GrLine(map,x1,y1,x2,y2);
+                msg_code=GetMsg(&arg1,&arg2,
+                      1<<MSG_KEY_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+                GrLine(map,x1,y1,x2,y2);
+                if (msg_code==MSG_KEY_DOWN)
+                  goto lt_restart;
+                else if (msg_code==MSG_MS_L_UP) {
+                  Sweep(100,90,100);
+                  x2=arg1; y2=arg2;
+                  break;
+                }
+              }
+              if (mode==LTM_REFLECT_LINE)
+                map->color=MIRROR_COLOR;
+              else
+                map->color=LENS_COLOR;
+              GrLine(map,x1,y1,x2,y2);
+              if (mode==LTM_REFLECT_LINE)
+                BmpLine(bmp_reflect,x1,y1,x2,y2);
+              else
+                BmpLine(bmp_refract,x1,y1,x2,y2);
+              break;
+            case LTM_REFLECT_SPLINE:
+            case LTM_REFRACT_SPLINE:
+              cnt=0;
+              if (mode==LTM_REFLECT_SPLINE)
+                map->color=ROP_XOR+MIRROR_COLOR;
+              else
+                map->color=ROP_XOR+LENS_COLOR;
+              do {
+                c[cnt].x=arg1; c[cnt].y=arg2; c[cnt].z=0;
+                Gr2BSpline(map,c,cnt+1);
+                msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_UP+
+                      1<<MSG_MS_MOVE+1<<MSG_MS_R_UP);
+                Gr2BSpline(map,c,cnt+1);
+                if (msg_code==MSG_KEY_DOWN)
+                  goto lt_restart;
+                else if (msg_code==MSG_MS_L_UP) {
+                  Sweep(100,90,100);
+                  cnt++;
+                }
+              } while (cnt<PTS_NUM-1 && msg_code!=MSG_MS_R_UP);
+              if (mode==LTM_REFLECT_SPLINE)
+                map->color=MIRROR_COLOR;
+              else
+                map->color=LENS_COLOR;
+              Gr2BSpline3(map,c,cnt);
+              for (i=0;i<cnt;i++) {
+                c[i].x*=bmp_scale;
+                c[i].y*=bmp_scale;
+              }
+              if (mode==LTM_REFLECT_SPLINE)
+                BSpline2(bmp_reflect,c,cnt,&BmpPlot);
+              else
+                BSpline2(bmp_refract,c,cnt,&BmpPlot);
+              mode=LTM_REFLECT_LINE;
+              LTMenuSet(mode);
+              break;
+          }
+          break;
+        case MSG_MS_R_UP:
+          i=PopUpPickLst("Reflect Line\0Reflect Spline\0Refract Line\0"
+                "Refract Spline\0Refract Flood Fill\0TestRay\0");
+          if (i>=0) {
+            mode=i;
+            LTMenuSet(mode);
+          }
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              mode=LTM_REFLECT_LINE;
+              LTMenuSet(mode);
+              break;
+            case 'r':
+              RandomBurst;
+              break;
+            case 'e':
+              full_speed=TRUE;
+              Sleep(1500);
+              FlushMsgs;
+              full_speed=FALSE;
+              break;
+            case 'n':
+              show_normals=!show_normals;
+              LTMenuSet(mode);
+              break;
+            case '0'...'5':
+              mode=arg1-'0';
+              LTMenuSet(mode);
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto lt_done;
+          }
+          break;
+      }
+    }
+lt_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  Free(c);
+  SettingsPop;
+  for (i=0;i<mp_cnt;i++)
+    Kill(animate_tasks[i]);
+  CleanUp;
+  MenuPop;
+}
+
+LightTable;
+
+ diff --git a/public/Wb/Demo/Graphics/Lines.HC.HTML b/public/Wb/Demo/Graphics/Lines.HC.HTML new file mode 100755 index 0000000..8445bf1 --- /dev/null +++ b/public/Wb/Demo/Graphics/Lines.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+U0 Main()
+{
+  I64 x1=0,y1=0,x2=0,y2=0,i=1,c=0;
+  I64 vx1=0,vy1=0,vx2=0,vy2=0;
+  CDC *dc=DCAlias;
+  while (!ScanChar) {
+    if (!--i) {
+      i=1000;
+      dc->color=c++&15;
+    }
+    GrLine(dc,x1,y1,x2,y2);
+    vx1=ClampI64(vx1+SignI64(RandI16),-5,5);
+    vy1=ClampI64(vy1+SignI64(RandI16),-5,5);
+    vx2=ClampI64(vx2+SignI64(RandI16),-5,5);
+    vy2=ClampI64(vy2+SignI64(RandI16),-5,5);
+    x1=ClampI64(x1+vx1,0,Fs->pix_width-1);
+    y1=ClampI64(y1+vy1,0,Fs->pix_height-1);
+    x2=ClampI64(x2+vx2,0,Fs->pix_width-1);
+    y2=ClampI64(y2+vy2,0,Fs->pix_height-1);
+    Sleep(1); //Replace this with Yield() ort Sleep(0) and see what happens!
+  }
+  DCFill(dc);
+  DCDel(dc);
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Graphics/LowPassFilter.HC.HTML b/public/Wb/Demo/Graphics/LowPassFilter.HC.HTML new file mode 100755 index 0000000..6007d57 --- /dev/null +++ b/public/Wb/Demo/Graphics/LowPassFilter.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+#define STEP_SIZE       400
+
+U0 LowPassFilterDemo()
+{
+  F64 y,y1,t,dt;
+  CDC *dc=DCAlias;
+
+  WinBorder;
+  WinMax;
+  DocClear;
+
+  dc->color=BLUE;
+  GrLine(dc,0,0,0,STEP_SIZE);
+  GrLine(dc,0,STEP_SIZE,GR_WIDTH/2,STEP_SIZE);
+  GrLine(dc,GR_WIDTH/2,STEP_SIZE,GR_WIDTH/2,0);
+  GrLine(dc,GR_WIDTH/2,0,GR_WIDTH,0);
+  PressAKey;
+
+  dc->color=CYAN;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=1.0;
+    if (t<GR_WIDTH/2)
+      y1=STEP_SIZE-STEP_SIZE*Exp(-0.01*t);
+    else
+      y1=STEP_SIZE*Exp(-0.01*(t-GR_WIDTH/2));
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  dc->color=BLACK;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=1.0;
+    if (t<GR_WIDTH/2)
+      y1=0.99*y+.01*STEP_SIZE;
+    else
+      y1=0.99*y;
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  dc->color=RED;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=Rand/10;
+    if (t<GR_WIDTH/2)
+      y1=LowPass1(.01,y,STEP_SIZE,dt);
+    else
+      y1=LowPass1(.01,y,0,dt);
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  dc->color=GREEN;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=Rand/10;
+    if (t<GR_WIDTH/2)
+      y1=LowPass1(.1,y,STEP_SIZE,dt);
+    else
+      y1=LowPass1(.1,y,0,dt);
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  DCDel(dc);
+  DCFill;
+}
+
+LowPassFilterDemo;
+
+ diff --git a/public/Wb/Demo/Graphics/MathAudioDemo.HC.HTML b/public/Wb/Demo/Graphics/MathAudioDemo.HC.HTML new file mode 100755 index 0000000..e56336e --- /dev/null +++ b/public/Wb/Demo/Graphics/MathAudioDemo.HC.HTML @@ -0,0 +1,137 @@ + + + + + + + + + + + +
+F64 MySin(F64 d)
+{ //Sin() does not have an address.
+  return Sin(d);
+}
+
+F64 MyCos(F64 d)
+{ //Cos() does not have an address.
+  return Cos(d);
+}
+
+U0 FunDraw1(CDC *dc,F64 (*f)(F64 t))
+{
+  I64 i,w=Fs->pix_width,h=Fs->pix_height;
+  F64 scale=h/5.0;
+  for (i=-w/2;i<=w/2;i++)
+    GrLine(dc,w/2+i,h/2-scale*f(i/scale*2*pi),
+          w/2+i+1,h/2-scale*f((i+1)/scale*2*pi));
+}
+
+U0 FunDraw2(CDC *dc,F64 (*f)(F64 t,F64 p),F64 T)
+{
+  I64 i,w=Fs->pix_width,h=Fs->pix_height;
+  F64 scale=h/5.0;
+  for (i=-w/2;i<=w/2;i++)
+    GrLine(dc,w/2+i,h/2-scale*f(i/scale,T),w/2+i+1,h/2-scale*f((i+1)/scale,T));
+}
+
+U0 Init(CDC *dc)
+{
+  I64 i,w=Fs->pix_width,h=Fs->pix_height;
+  F64 scale=h/5.0;
+  DocClear;
+  DCFill(dc);
+  dc->color=BLACK;
+  GrLine(dc,0,h/2,w-1,h/2);
+  GrLine(dc,w/2,0,w/2,h-1);
+  for (i=-2;i<=2;i++) {
+    dc->color=BLACK;
+    GrLine(dc,w/2-3,h/2-scale*i,w/2+3,h/2-scale*i);
+    if (i) {
+      dc->color=DKGRAY;
+      GrPrint(dc,w/2+5,h/2-scale*i-FONT_HEIGHT/2,"%5.1f",ToF64(i));
+    }
+  }
+  for (i=-4;i<=4;i++) {
+    dc->color=BLACK;
+    GrLine(dc,w/2+scale*i,h/2-3,w/2+scale*i,h/2+3);
+    if (i) {
+      dc->color=DKGRAY;
+      GrPrint(dc,
+            w/2+scale*i-7*FONT_WIDTH/2,h/2+5+FONT_HEIGHT,"%5.1f*T",ToF64(i));
+    }
+  }
+}
+
+U0 SndMathDemo()
+{
+  CDC *dc=DCAlias;
+
+  Init(dc);
+  dc->color=RED;
+  FunDraw1(dc,&MySin);
+  "$RED$Sin$FG$\n";
+  PressAKey;
+  dc->color=BLUE;
+  FunDraw2(dc,&Saw,1.0);
+  "$BLUE$Saw$FG$\n";
+  PressAKey;
+  dc->color=GREEN;
+  FunDraw2(dc,&FullSaw,1.0);
+  "$GREEN$FullSaw$FG$\n";
+  PressAKey;
+
+  Init(dc);
+  dc->color=RED;
+  FunDraw1(dc,&MyCos);
+  "$RED$Cos$FG$\n";
+  PressAKey;
+  dc->color=BLUE;
+  FunDraw2(dc,&Caw,1.0);
+  "$BLUE$Caw$FG$\n";
+  PressAKey;
+  dc->color=GREEN;
+  FunDraw2(dc,&FullCaw,1.0);
+  "$GREEN$FullCaw$FG$\n";
+  PressAKey;
+
+  Init(dc);
+  dc->color=RED;
+  FunDraw1(dc,&MySin);
+  "$RED$Sin$FG$\n";
+  PressAKey;
+  dc->color=BLUE;
+  FunDraw2(dc,&Tri,1.0);
+  "$BLUE$Tri$FG$\n";
+  PressAKey;
+  dc->color=GREEN;
+  FunDraw2(dc,&FullTri,1.0);
+  "$GREEN$FullTri$FG$\n";
+  PressAKey;
+
+  DCFill(dc);
+  DCDel(dc);
+}
+
+SndMathDemo;
+
+ diff --git a/public/Wb/Demo/Graphics/MouseDemo.HC.HTML b/public/Wb/Demo/Graphics/MouseDemo.HC.HTML new file mode 100755 index 0000000..f40578f --- /dev/null +++ b/public/Wb/Demo/Graphics/MouseDemo.HC.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+U0 Mouse()
+{
+  "Press left mouse bttn to exit.\n";
+  while (!ms.lb) { //Left bttn to exit.
+    GrPlot(,ms.pos.x,ms.pos.y);
+    Refresh;
+  }
+  DCFill;
+}
+
+Mouse;
+
+ diff --git a/public/Wb/Demo/Graphics/NetOfDots.HC.HTML b/public/Wb/Demo/Graphics/NetOfDots.HC.HTML new file mode 100755 index 0000000..a801c60 --- /dev/null +++ b/public/Wb/Demo/Graphics/NetOfDots.HC.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+//Press <F5> to compile and run.
+
+U0 NetOfDots()
+{
+  I64 i;
+  CDC *dc=DCAlias;
+  DocClear;
+  dc->color=RED;
+  for (i=0;i<480;i+=20)
+    GrLine(dc,i,0,0,480-i,3);
+  DCDel(dc);
+  PressAKey;
+  DCFill;
+}
+
+NetOfDots;  //Run when #included
+
+ diff --git a/public/Wb/Demo/Graphics/Palette.HC.HTML b/public/Wb/Demo/Graphics/Palette.HC.HTML new file mode 100755 index 0000000..f40ac12 --- /dev/null +++ b/public/Wb/Demo/Graphics/Palette.HC.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+U0 PaletteDemo()
+{
+  I64 i,j;
+  CBGR48 bgr;
+  for (i=0;i<COLORS_NUM;i++)
+    "$BLACK$$BG,%d$__%-8Z__$FG$$BG$\n",i,i,"ST_COLORS";
+
+  SettingsPush; //See SettingsPush
+//Alternatively, use GrPaletteSet(gr_palette_gray);
+  for (i=0;i<COLORS_NUM;i++) {
+    j=0xFFFF*i/(COLORS_NUM-1);
+    bgr.b=j;
+    bgr.g=j;
+    bgr.r=j;
+    GrPaletteColorSet(i,bgr);
+  }
+  PressAKey;
+
+  //You can do it this way, too.
+  GrPaletteColorSet(WHITE,0xFFFFFFFF0000);
+  PressAKey;
+
+  //SettingsPop() restores original palette
+  SettingsPop;
+}
+
+PaletteDemo;
+
+ diff --git a/public/Wb/Demo/Graphics/PanText.HC.HTML b/public/Wb/Demo/Graphics/PanText.HC.HTML new file mode 100755 index 0000000..a7227ca --- /dev/null +++ b/public/Wb/Demo/Graphics/PanText.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+U0 PanText()
+{
+  I64 i;
+  for (i=0;i<=7;i++) {
+    gr.pan_text_x=i;
+    Sleep(30);
+  }
+  i--;
+  for (;i>=-7;i--) {
+    gr.pan_text_x=i;
+    Sleep(30);
+  }
+  i++;
+  for (;i<=0;i++) {
+    gr.pan_text_x=i;
+    Sleep(30);
+  }
+
+  for (i=0;i<=7;i++) {
+    gr.pan_text_y=i;
+    Sleep(30);
+  }
+  i--;
+  for (;i>=-7;i--) {
+    gr.pan_text_y=i;
+    Sleep(30);
+  }
+  i++;
+  for (;i<=0;i++) {
+    gr.pan_text_y=i;
+    Sleep(30);
+  }
+}
+
+PanText;
+
+ diff --git a/public/Wb/Demo/Graphics/Pick.HC.HTML b/public/Wb/Demo/Graphics/Pick.HC.HTML new file mode 100755 index 0000000..37a9fa5 --- /dev/null +++ b/public/Wb/Demo/Graphics/Pick.HC.HTML @@ -0,0 +1,117 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+#define APPLES_NUM 128
+
+I64     x[APPLES_NUM],y[APPLES_NUM],
+        cur_apple,cur_dist;
+Bool    trigger;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i,best_dist=I64_MAX,best_apple=0;
+
+  dc->flags|=DCF_LOCATE_NEAREST;
+  dc->cur_x=ms.pos.x;
+  dc->cur_y=ms.pos.y;
+  dc->cur_z=0;
+  for (i=0;i<APPLES_NUM;i++) {
+    Sprite3(dc,x[i],y[i],0,<1>);
+    if (dc->nearest_dist<=best_dist) {
+//Distance to nearest pix, squared
+      //Sqrt() is expensive so we work with distance squared.
+      best_dist=dc->nearest_dist;
+      best_apple=i;
+    }
+  }
+  if (trigger) {
+    cur_apple=best_apple;
+    cur_dist=best_dist;
+    trigger=FALSE;
+  }
+  GrPrint(dc,FONT_WIDTH,FONT_HEIGHT,"Dist Squared:%d",cur_dist);
+}
+
+U0 Pick()
+{
+  I64 i,msg_code,arg1,arg2,delta_x,delta_y;
+  for (i=0;i<APPLES_NUM;i++) {
+    x[i]=RandU16%GR_WIDTH;
+    y[i]=RandU16%(GR_HEIGHT-FONT_HEIGHT*3)+FONT_HEIGHT*3;
+  }
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  DocCursor;
+  DocClear;
+
+  trigger=FALSE;
+  cur_apple=cur_dist=0;
+
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  try {
+    while (TRUE) {
+      if (GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN)==MSG_KEY_DOWN)
+        goto pi_done;
+
+        //Wait for window mgr to call DrawIt()
+      trigger=TRUE;
+      do Refresh;
+      while (trigger);
+
+      //Use scrn coordinates, not window (arg1,arg2)
+      //ms.pos.x and ms.pos.y are global vars updated
+      //updated by the window mgr to hold the
+      //scrn coordinates of the mouse.
+      delta_x=x[cur_apple]-ms.pos.x;
+      delta_y=y[cur_apple]-ms.pos.y;
+
+      do {
+        msg_code=GetMsg(&arg1,&arg2,
+              1<<MSG_KEY_DOWN|1<<MSG_MS_MOVE|1<<MSG_MS_L_UP);
+        if (msg_code==MSG_KEY_DOWN)
+          goto pi_done;
+        x[cur_apple]=ms.pos.x+delta_x;
+        y[cur_apple]=ms.pos.y+delta_y;
+      } while (msg_code!=MSG_MS_L_UP);
+    }
+pi_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+Pick;
+
+ diff --git a/public/Wb/Demo/Graphics/Pick3D.HC.HTML b/public/Wb/Demo/Graphics/Pick3D.HC.HTML new file mode 100755 index 0000000..16b84ac --- /dev/null +++ b/public/Wb/Demo/Graphics/Pick3D.HC.HTML @@ -0,0 +1,357 @@ + + + + + + + + + + + +
+//This is a whimsical program which demonstrates some techniques.
+
+#define BORDER          20
+
+#define PTY_PT  0
+#define PTY_CIRCLE      1
+#define PTY_LINE        2
+#define PTY_SPRITE      3
+#define PTY_NUM         4
+
+extern class PObj;
+
+class PPt
+{
+  CD3I32 p;
+};
+
+class PCircle
+{
+  PObj  *p;
+  I64   radius;
+};
+
+class PLine
+{
+  PObj  *p1,*p2;
+};
+
+class PCSprite
+{
+  PObj  *p;
+  U8    *img;
+  I64   *r,
+        *dr; //Rounding error might eventually screw this up
+}
+
+class PObj
+{
+  PObj  *next,*last;
+  I64   type,color;
+  union {
+    PPt         p;
+    PCircle     c;
+    PLine       l;
+    PCSprite    g;
+  };
+};
+
+class PickFrame
+{
+  PObj  o_head;
+  I64   o_cnts[PTY_NUM];
+  I64   cx,cy;
+};
+
+#define IMGS_NUM        3
+
+
+
+  <1>/* Graphics Not Rendered in HTML */
+
+
+
+  <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+  <3>/* Graphics Not Rendered in HTML */
+
+
+U8 *imgs[IMGS_NUM]={<1>,<2>,<3>};
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 *r,*old_r;
+  PickFrame *pf=FramePtr("PickFrame",task);
+  PObj *tmpo=pf->o_head.next;
+
+  pf->cx=task->pix_width>>1;
+  pf->cy=task->pix_height>>1;
+
+  DCDepthBufAlloc(dc);
+
+  dc->color=LTRED;
+  dc->thick=3;
+  GrBorder(dc,BORDER,BORDER,2*pf->cx-BORDER,2*pf->cy-BORDER);
+
+  while (tmpo!=&pf->o_head) {
+    dc->color=tmpo->color;
+    switch (tmpo->type) {
+      case PTY_PT:
+        GrLine(dc,pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y+2,
+              pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y-2);
+        GrLine(dc,pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y+2,
+              pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y-2);
+        break;
+      case PTY_CIRCLE:
+        GrCircle(dc,pf->cx+tmpo->c.p->p.p.x,pf->cy+tmpo->c.p->p.p.y,
+              tmpo->c.radius);
+        break;
+      case PTY_LINE:
+        GrLine(dc,pf->cx+tmpo->l.p1->p.p.x,pf->cy+tmpo->l.p1->p.p.y,
+              pf->cx+tmpo->l.p2->p.p.x,pf->cy+tmpo->l.p2->p.p.y);
+        break;
+      case PTY_SPRITE:
+        old_r=dc->r;
+        dc->r=tmpo->g.r;
+        dc->x=pf->cx+tmpo->g.p->p.p.x;
+        dc->y=pf->cy+tmpo->g.p->p.p.y;
+        dc->z=GR_Z_ALL;
+        dc->flags|=DCF_TRANSFORMATION;
+        Sprite3(dc,0,0,0,tmpo->g.img);
+        dc->flags&=~DCF_TRANSFORMATION;
+        dc->r=old_r;
+
+        //Updated each refresh, not guarenteed to be uniform.
+        //Rounding error might corrupt, as well.
+        r=Mat4x4MulMat4x4New(tmpo->g.dr,tmpo->g.r,task);
+        Free(tmpo->g.r);
+        tmpo->g.r=r;
+
+        break;
+    }
+    tmpo=tmpo->next;
+  }
+}
+
+PObj *PObjNew(PickFrame *pf,I64 type,I64 color)
+{
+  PObj *tmpo=CAlloc(sizeof(PObj));
+  tmpo->type=type;
+  tmpo->color=color;
+  pf->o_cnts[type]++;
+  QueIns(tmpo,pf->o_head.last);
+  return tmpo;
+}
+
+U0 PObjDel(PickFrame *pf,PObj *tmpo)
+{
+  QueRem(tmpo);
+  switch (tmpo->type) {
+    case PTY_SPRITE:
+      Free(tmpo->g.r);
+      Free(tmpo->g.dr);
+      break;
+  }
+  pf->o_cnts[tmpo->type]--;
+  Free(tmpo);
+}
+
+PObj *PPtNew(PickFrame *pf,I64 x,I64 y)
+{
+  PObj *tmpo=PObjNew(pf,PTY_PT,BLACK);
+  tmpo->p.p.x=x;
+  tmpo->p.p.y=y;
+  return tmpo;
+}
+
+PObj *PPtNum(PickFrame *pf,I64 num)
+{
+  PObj *tmpo=pf->o_head.next;
+  while (tmpo!=&pf->o_head) {
+    if (tmpo->type==PTY_PT && !num--)
+      return tmpo;
+    tmpo=tmpo->next;
+  }
+  return NULL;
+}
+
+PObj *PPtFind(PickFrame *pf,I64 x,I64 y)
+{
+  I64 dd,best_dd=I64_MAX;
+  PObj *tmpo=pf->o_head.next,*res=NULL;
+  while (tmpo!=&pf->o_head) {
+    if (tmpo->type==PTY_PT) {
+      dd=SqrI64(tmpo->p.p.x-x)+SqrI64(tmpo->p.p.y-y);
+      if (dd<best_dd) {
+        best_dd=dd;
+        res=tmpo;
+      }
+    }
+    tmpo=tmpo->next;
+  }
+  return res;
+}
+
+PObj *PCircleNew(PickFrame *pf,I64 p_num,I64 r)
+{
+  PObj *tmpo=PObjNew(pf,PTY_CIRCLE,RED);
+  tmpo->c.p=PPtNum(pf,p_num);
+  tmpo->c.radius=r;
+  return tmpo;
+}
+
+PObj *PLineNew(PickFrame *pf,I64 p1_num,I64 p2_num)
+{
+  PObj *tmpo=PObjNew(pf,PTY_LINE,GREEN);
+  tmpo->l.p1=PPtNum(pf,p1_num);
+  tmpo->l.p2=PPtNum(pf,p2_num);
+  return tmpo;
+}
+
+PObj *PCSpriteNew(PickFrame *pf,U8 *img,I64 p_num,I64 *r,I64 *dr)
+{
+  PObj *tmpo=PObjNew(pf,PTY_SPRITE,BLACK);
+  tmpo->g.p=PPtNum(pf,p_num);
+  tmpo->g.img=img;
+  tmpo->g.r=r;
+  tmpo->g.dr=dr;
+  return tmpo;
+}
+
+PickFrame *Init()
+{
+  PickFrame *pf=CAlloc(sizeof(PickFrame));
+  I64 i,*r,*dr;
+
+  pf->cx=Fs->pix_width>>1;
+  pf->cy=Fs->pix_height>>1;
+
+  pf->o_head.next=pf->o_head.last=&pf->o_head;
+  for (i=0;i<50;i++)
+    PPtNew(pf,RandI32%(pf->cx-BORDER),RandI32%(pf->cy-BORDER));
+  for (i=0;i<20;i++)
+    PCircleNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,6);
+  for (i=0;i<20;i++)
+    PLineNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,
+          pf->o_cnts[PTY_PT]*RandU16/U16_MAX);
+  for (i=0;i<10;i++) {
+    r=Mat4x4IdentNew;
+    dr=Mat4x4IdentNew;
+    Mat4x4RotZ(dr,0.05*2*(Rand-0.5));
+    Mat4x4RotY(dr,0.05*2*(Rand-0.5));
+    Mat4x4RotX(dr,0.05*2*(Rand-0.5));
+    PCSpriteNew(pf,imgs[IMGS_NUM*RandU16/U16_MAX],
+          pf->o_cnts[PTY_PT]*RandU16/U16_MAX,r,dr);
+  }
+  FramePtrSet("PickFrame",pf);
+  return pf;
+}
+
+U0 CleanUp(PickFrame *pf)
+{
+  PObj *tmpo=pf->o_head.next,*tmpo1;
+  while (tmpo!=&pf->o_head) {
+    tmpo1=tmpo->next;
+    PObjDel(pf,tmpo);
+    tmpo=tmpo1;
+  }
+  Free(pf);
+}
+
+U0 Pick3D()
+{
+  I64 msg_code,arg1,arg2;
+  PObj *tmpo;
+  PickFrame *pf=NULL;
+
+  FramePtrAdd("PickFrame");
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  "$BK,1$Move things around.$BK,0$\n";
+  pf=Init;
+  tmpo=NULL;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_MOVE)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp(pf);
+              pf=Init;
+              tmpo=NULL;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto pd_done;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          tmpo=PPtFind(pf,arg1-pf->cx,arg2-pf->cy);
+          break;
+        case MSG_MS_L_UP:
+          if (tmpo) {
+            tmpo->p.p.x=arg1-pf->cx;
+            tmpo->p.p.y=arg2-pf->cy;
+            tmpo=NULL;
+          }
+          break;
+        case MSG_MS_MOVE:
+          if (tmpo) {
+            tmpo->p.p.x=arg1-pf->cx;
+            tmpo->p.p.y=arg2-pf->cy;
+          }
+          break;
+      }
+    }
+pd_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  CleanUp(pf);
+  FramePtrDel("PickFrame");
+}
+
+Pick3D;
+
+ diff --git a/public/Wb/Demo/Graphics/PoleZeros.HC.HTML b/public/Wb/Demo/Graphics/PoleZeros.HC.HTML new file mode 100755 index 0000000..fae7a51 --- /dev/null +++ b/public/Wb/Demo/Graphics/PoleZeros.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+#define ZEROS_NUM       2
+Complex zeros[ZEROS_NUM]={{10.0,0},{-30,0}};
+#define POLES_NUM       2
+Complex poles[POLES_NUM]={{-20.0,-15.0},{-20.0,15.0}};
+
+F64 scale;
+
+Complex *PoleZeroFind(I64 x,I64 y)
+{
+  I64 i;
+  F64 dd,best_dd=F64_MAX;
+  Complex *res=NULL;
+  for (i=0;i<POLES_NUM;i++) {
+    dd=Sqr(poles[i].x-x)+Sqr(poles[i].y-y);
+    if (dd<best_dd) {
+      best_dd=dd;
+      res=&poles[i];
+    }
+  }
+  for (i=0;i<ZEROS_NUM;i++) {
+    dd=Sqr(zeros[i].x-x)+Sqr(zeros[i].y-y);
+    if (dd<best_dd) {
+      best_dd=dd;
+      res=&zeros[i];
+    }
+  }
+  return res;
+}
+
+F64 F(Complex *x)
+{
+  F64 m,a;
+  Complex num,denom,n1;
+
+  CPoly(&num,  ZEROS_NUM,zeros,x);
+  CPoly(&denom,POLES_NUM,poles,x);
+  CDiv(&n1,&num,&denom);
+
+  R2P(&m,&a,n1.x,n1.y);
+  if (ms.rb)
+    return pi+a;
+  else
+    return m;
+}
+
+F64 MPDraw(CTask *task)
+{
+  Complex xx;
+  I64 x,y,w=task->pix_width,h=task->pix_height,cx=w/2,cy=h/2,
+        lo=Gs->num*h/mp_cnt,hi=(Gs->num+1)*h/mp_cnt;
+  F64 yy,y_total=0;
+  CDC *dc=DCAlias(,task);
+  for (y=lo;y<hi;y++) {
+    for (x=0;x<w;x++) {
+      CEqu(&xx,x-cx,cy-y);
+      yy=scale*F(&xx);
+      dc->color=Clamp(yy,0,14);
+      y_total+=Clamp(yy,-14,14);
+      GrPlot(dc,x,y);
+    }
+  }
+  DCDel(dc);
+  return y_total;
+}
+
+U0 Draw()
+{
+  CJob *tmpm[MP_PROCESSORS_NUM];
+  F64 y_total,old_y_total=F64_MAX;
+  I64 i,w=Fs->pix_width,h=Fs->pix_height,cx=w/2,cy=h/2;
+  CDC *dc=DCAlias;
+  while (TRUE) {
+    for (i=0;i<mp_cnt;i++)
+      tmpm[i]=JobQue(&MPDraw,Fs,i,0);
+    y_total=0;
+    for (i=0;i<mp_cnt;i++)
+      y_total+=JobResGet(tmpm[i])(F64);
+
+    if (!y_total) break;
+    scale*=7*GR_WIDTH*GR_HEIGHT/y_total;
+    if (Abs(y_total-old_y_total)<1.0*GR_WIDTH*GR_HEIGHT)
+      break;
+    old_y_total=y_total;
+  }
+  dc->color=15;
+  GrLine(dc,0,cy,w,cy);
+  GrLine(dc,cx,0,cx,h);
+  for (i=0;i<ZEROS_NUM;i++)
+    GrPrint(dc,cx+zeros[i].x-FONT_WIDTH/2,cy-zeros[i].y-FONT_HEIGHT/2,"o");
+  for (i=0;i<POLES_NUM;i++)
+    GrPrint(dc,cx+poles[i].x-FONT_WIDTH/2,cy-poles[i].y-FONT_HEIGHT/2,"x");
+  DCDel(dc);
+}
+
+U0 PoleZeros()
+{
+  I64 msg_code,arg1,arg2,p11,p22,cx,cy;
+  Complex *tmpc=NULL;
+
+  PopUpOk(
+        "Drag the poles and zeros with left mouse.\n"
+        "Hold right mouse for phase plot.\n"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+  GrPaletteSet(gr_palette_gray);
+  GrPaletteColorSet(15,0xFFFF00000000); //White is red
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  scale=1.0;
+
+  try {
+    Draw;
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+
+            1<<MSG_MS_L_UP+1<<MSG_MS_R_DOWN+1<<MSG_MS_R_UP+1<<MSG_MS_MOVE);
+pz_msg:
+      cx=Fs->pix_width/2;
+      cy=Fs->pix_height/2;
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+          tmpc=PoleZeroFind(arg1-cx,cy-arg2);
+          break;
+        case MSG_MS_MOVE:
+          if (tmpc) {
+            p11=arg1;p22=arg2;
+//get to last mouse move
+            while (msg_code=ScanMsg(&arg1,&arg2,
+                  1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+
+                  1<<MSG_MS_L_UP+1<<MSG_MS_R_DOWN+
+                  1<<MSG_MS_R_UP+1<<MSG_MS_MOVE))
+              if (msg_code==MSG_MS_MOVE) {
+                p11=arg1;p22=arg2;
+              } else
+                goto pz_msg;
+
+            tmpc->x=p11-cx;
+            tmpc->y=cy-p22;
+            Draw;
+          }
+          break;
+        case MSG_MS_L_UP:
+          if (tmpc) {
+            tmpc->x=arg1-cx;
+            tmpc->y=cy-arg2;
+            tmpc=NULL;
+            Draw;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+        case MSG_MS_R_UP:
+          Draw;
+          break;
+        case MSG_KEY_DOWN:
+          if (arg1==CH_SHIFT_ESC||arg1==CH_ESC)
+            goto pz_done;
+      }
+      Refresh;
+    }
+pz_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCFill;
+}
+
+PoleZeros;
+
+ diff --git a/public/Wb/Demo/Graphics/PredatorPrey.HC.HTML b/public/Wb/Demo/Graphics/PredatorPrey.HC.HTML new file mode 100755 index 0000000..917c9e7 --- /dev/null +++ b/public/Wb/Demo/Graphics/PredatorPrey.HC.HTML @@ -0,0 +1,112 @@ + + + + + + + + + + + +
+//Classic 2nd order nonlinear ordinary differential equation
+
+I64 mp_not_done_flags;
+
+#define OX      10
+#define OY      GR_HEIGHT/2-FONT_HEIGHT
+
+#define MICRO_STEP      0.000001
+
+class State
+{
+  F64 wabbits,hawks,
+        d_wabbits,d_hawks; //Technically, these are not part of the state.
+};
+
+U0 Steps(State *s)
+{
+  I64 i;
+  for (i=0;i<10000;i++) {
+    s->d_wabbits=s->wabbits*(1.0-0.10*s->hawks);
+    s->d_hawks  =-s->hawks *(1.0-0.01*s->wabbits);
+    s->hawks  +=s->d_hawks  *MICRO_STEP;
+    s->wabbits+=s->d_wabbits*MICRO_STEP;
+  }
+}
+
+U0 PlotTrajectory(CTask *parent)
+{
+  I64 i;
+  CDC *dc=DCAlias(,parent);
+  State s;
+
+  MemSet(&s,0,sizeof(State));
+  s.wabbits=RandU16%100 +10;
+  s.hawks  =RandU16%10  +1;
+
+  for (i=0;i<1000;i++) {
+    dc->color=LTGREEN;
+    GrPlot(dc,s.wabbits+OX,OY-s.d_wabbits);
+    dc->color=LTRED;
+    GrPlot(dc,s.hawks  +OX,OY-s.d_hawks);
+    Steps(&s);
+  }
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 PredatorPrey()
+{
+  I64 i;
+  CDC *dc=DCAlias;
+
+  PopUpOk("This will plot multiple predator-prey\n"
+        "trajectories.  It restarts many times\n"
+        "with different, random, initial populations.\n");
+  SettingsPush; //See SettingsPush
+  try {
+    AutoComplete;
+    WinBorder;
+    WinMax;
+    DocClear;
+    Refresh;
+
+    dc->color=BLACK;
+    GrLine(dc,OX,0,OX,GR_HEIGHT-FONT_HEIGHT-1);
+    GrLine(dc,0,OY,GR_WIDTH-1,OY);
+    while (!ScanChar) {
+      mp_not_done_flags=1<<mp_cnt-1;
+      for (i=0;i<mp_cnt;i++)
+        JobQue(&PlotTrajectory,Fs,i);
+      do Yield;
+      while (mp_not_done_flags);
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCFill(dc);
+  DCDel(dc);
+}
+
+PredatorPrey;
+
+ diff --git a/public/Wb/Demo/Graphics/RotateTank.HC.HTML b/public/Wb/Demo/Graphics/RotateTank.HC.HTML new file mode 100755 index 0000000..50d47bd --- /dev/null +++ b/public/Wb/Demo/Graphics/RotateTank.HC.HTML @@ -0,0 +1,91 @@ + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+U0 RotateTank()
+{
+  CDC *dc=DCAlias;
+  DCDepthBufAlloc(dc);
+  dc->flags|=DCF_TRANSFORMATION;
+  WinHorz(TEXT_COLS/2-12,TEXT_COLS/2+12);
+  WinVert(TEXT_ROWS/2-12,TEXT_ROWS/2+12);
+  DocClear;
+  try {
+    while (!ScanChar) {
+      DCDepthBufRst(dc);
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4RotY(dc->r,0.25*Sin(tS/10*2*pi)+pi/2);
+      Mat4x4RotX(dc->r,0.4*Sin(tS/5*2*pi));
+      Mat4x4RotZ(dc->r,0.25*Sin(tS/10*2*pi)-pi/2);
+      Mat4x4Scale(dc->r,0.25+Saw(tS,5));
+      DCMat4x4Set(dc,dc->r);//Not needed--Sets scale for pen-width
+
+      dc->x=Fs->pix_width/2;
+      dc->y=Fs->pix_height/2;
+//Offsets the image Z so that no parts are clipped by
+      //the conceptual plane of the scrn.
+      dc->z=GR_Z_ALL;
+
+      Sprite3(dc,0,0,0,<1>);
+      Refresh;
+      DCFill;
+    }
+  } catch
+    PutExcept;
+
+  DCFill;
+  DCDel(dc);
+}
+
+RotateTank;
+
+ diff --git a/public/Wb/Demo/Graphics/ScrnCapture.HC.HTML b/public/Wb/Demo/Graphics/ScrnCapture.HC.HTML new file mode 100755 index 0000000..6332881 --- /dev/null +++ b/public/Wb/Demo/Graphics/ScrnCapture.HC.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+//See ::/Demo/Games/Stadium/StadiumGen.HC.
+
+U0 Main()
+{
+  "Capture scrn...\n";
+  PressAKey;
+  GRScrnCaptureWrite("~/DemoScrnShot");
+  "View captured scrn...\n";
+  PressAKey;
+  GRScrnCaptureRead("~/DemoScrnShot");
+  PressAKey;
+  DCFill;
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Graphics/ScrollBars.HC.HTML b/public/Wb/Demo/Graphics/ScrollBars.HC.HTML new file mode 100755 index 0000000..35a47df --- /dev/null +++ b/public/Wb/Demo/Graphics/ScrollBars.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+
+
+
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+#define MAP_HEIGHT      2048
+#define MAP_WIDTH       2048
+
+#define TREES_NUM       256
+
+I64 tree_x[TREES_NUM],tree_y[TREES_NUM];
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,h,v;
+
+  task->horz_scroll.min=0;
+  task->horz_scroll.max=MAP_WIDTH-task->pix_width;
+  task->vert_scroll.min=0;
+  task->vert_scroll.max=MAP_HEIGHT-task->pix_height;
+  TaskDerivedValsUpdate(task);
+
+  h=task->horz_scroll.pos;
+  v=task->vert_scroll.pos;
+
+  dc->color=BROWN;
+  dc->thick=4;
+  GrLine3(dc,2-h,2-v,0,MAP_WIDTH-3-h,2-v,0);
+  GrLine3(dc,2-h,MAP_HEIGHT-3-v,0,MAP_WIDTH-3-h,MAP_HEIGHT-3-v,0);
+  GrLine3(dc,2-h,2-v,0,2-h,MAP_HEIGHT-3-v,0);
+  GrLine3(dc,MAP_WIDTH-3-h,2-v,0,MAP_WIDTH-3-h,MAP_HEIGHT-3-v,0);
+
+  //Check bounds if you wish better performance.
+  for (i=0;i<TREES_NUM;i++)
+    Sprite3(dc,tree_x[i]-h,tree_y[i]-v,0,<Tree>);
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<TREES_NUM;i++) {
+    tree_x[i]=RandU16%MAP_WIDTH;
+    tree_y[i]=RandU16%MAP_HEIGHT;
+  }
+}
+
+U0 ScrollBars()
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  Fs->draw_it=&DrawIt;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DocScroll;
+
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+  GetChar(,FALSE);
+  SettingsPop;
+//If you care, you might want to
+  //save the original state of the
+  //scroll bars.
+}
+
+ScrollBars;
+
+ diff --git a/public/Wb/Demo/Graphics/Shading.HC.HTML b/public/Wb/Demo/Graphics/Shading.HC.HTML new file mode 100755 index 0000000..cf0afec --- /dev/null +++ b/public/Wb/Demo/Graphics/Shading.HC.HTML @@ -0,0 +1,208 @@ + + + + + + + + + + + +
+//"ls" is light source.
+
+U0 Lighting(CDC *dc,CD3I32 *ls,CD3I32 *poly,I64 color)
+{//color is a color from 0-7
+  CD3I32 v1,v2;
+  I64 *r=dc->r,i,vn_x,vn_y,vn_z;
+  F64 d;
+
+  v1.x=poly[0].x-poly[1].x;
+  v1.y=poly[0].y-poly[1].y;
+  v1.z=poly[0].z-poly[1].z;
+
+  v2.x=poly[2].x-poly[1].x;
+  v2.y=poly[2].y-poly[1].y;
+  v2.z=poly[2].z-poly[1].z;
+
+  //V1 and V2 are vects along two sides
+  //of the polygon joined at point[1].
+
+  vn_x=v1.y*v2.z-v1.z*v2.y;
+  vn_y=v1.z*v2.x-v1.x*v2.z;
+  vn_z=v1.x*v2.y-v1.y*v2.x;
+
+  if (d=Sqrt(SqrI64(vn_x)+SqrI64(vn_y)+SqrI64(vn_z)))
+    d=1<<16/d;
+  vn_x*=d;
+  vn_y*=d;
+  vn_z*=d;
+//Vn is the cross product of V1 and V3
+  //which means it is perpendicular.  It
+  //is the normal vect to the surface.
+  //It has been scaled to length 65536.
+  Mat4x4MulXYZ(r,&vn_x,&vn_y,&vn_z);
+  i=(vn_x*ls->x+vn_y*ls->y+vn_z*ls->z)>>16;
+//The dot product of the light source
+  //vect and the surface normal
+  //gives an illumination number.
+
+  //TempleOS will generate a random U16
+  //and compare to dither_probability_u16 and
+  //will pick from two colors.
+  //Probability dithering does not work with thick>1 at this time.
+  if (i<0) {
+    dc->color=ROPF_PROBABILITY_DITHER+BLACK<<16+color;
+    dc->dither_probability_u16=-i;
+  } else {
+    dc->color=ROPF_PROBABILITY_DITHER+(color^8)<<16+color;
+    dc->dither_probability_u16=i;
+  }
+}
+
+#define RINGS   8
+#define FACES   32
+#define SLOP    0.03 //Gaps appear without this.
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s=c->state;
+  F64 tt=0.5*(Sin(pi*2*(tS%10.0)/10.0)+2.0),
+        theta,theta2,phi,phi2,radius,d;
+  I64 i,j,cx=task->pix_width/2,cy=task->pix_height/2;
+  CD3I32 poly[3],ls;
+
+  dc->flags|=DCF_TRANSFORMATION;
+  DCDepthBufAlloc(dc);
+
+  Mat4x4IdentEqu(dc->r);
+  Mat4x4RotZ(dc->r,s->az);
+  Mat4x4RotY(dc->r,s->ay);
+  Mat4x4RotX(dc->r,s->ax+pi);
+  Mat4x4Scale(dc->r,tt);
+  DCMat4x4Set(dc,dc->r);
+
+  ls.x=-(ms.pos.x-task->pix_left-task->scroll_x-cx);
+  ls.y=-(ms.pos.y-task->pix_top-task->scroll_y-cy);
+  ls.z=GR_WIDTH/8;
+  d=1<<16/D3I32Norm(&ls);
+  ls.x*=d;
+  ls.y*=d;
+  ls.z*=d;
+
+  dc->x=cx;
+  dc->y=cy;
+  dc->z=MaxI64(cx,cy);
+  radius =MinI64(cx,cy)/2;
+
+  for (i=0;i<RINGS;i++) {
+    phi =    i*pi/2/RINGS;
+    phi2=(i+1)*pi/2/RINGS+SLOP;
+    for (j=0;j<FACES;j++) {
+      theta =j*2*pi/FACES;
+      theta2=(j+1)*2*pi/FACES+SLOP;
+
+      //Upper half
+      poly[0].x=radius*Cos(phi)*Cos(theta);
+      poly[0].y=radius*Cos(phi)*Sin(theta);
+      poly[0].z=radius*Sin(phi);
+      poly[1].x=radius*Cos(phi)*Cos(theta2);
+      poly[1].y=radius*Cos(phi)*Sin(theta2);
+      poly[1].z=radius*Sin(phi);
+      poly[2].x=radius*Cos(phi2)*Cos(theta+2*pi/FACES/2);
+      poly[2].y=radius*Cos(phi2)*Sin(theta+2*pi/FACES/2);
+      poly[2].z=radius*Sin(phi2);
+      Lighting(dc,&ls,poly,BLUE);
+      GrFillPoly3(dc,3,poly);
+
+      poly[2].x=radius*Cos(phi2)*Cos(theta +2*pi/FACES/2);
+      poly[2].y=radius*Cos(phi2)*Sin(theta +2*pi/FACES/2);
+      poly[2].z=radius*Sin(phi2);
+      poly[1].x=radius*Cos(phi2)*Cos(theta2+2*pi/FACES/2);
+      poly[1].y=radius*Cos(phi2)*Sin(theta2+2*pi/FACES/2);
+      poly[1].z=radius*Sin(phi2);
+      poly[0].x=radius*Cos(phi)*Cos(theta2);
+      poly[0].y=radius*Cos(phi)*Sin(theta2);
+      poly[0].z=radius*Sin(phi);
+      Lighting(dc,&ls,poly,BLUE);
+      GrFillPoly3(dc,3,poly);
+
+      //Lower half
+      poly[2].x=radius*Cos(phi)*Cos(theta);
+      poly[2].y=radius*Cos(phi)*Sin(theta);
+      poly[2].z=-radius*Sin(phi);
+      poly[1].x=radius*Cos(phi)*Cos(theta2);
+      poly[1].y=radius*Cos(phi)*Sin(theta2);
+      poly[1].z=-radius*Sin(phi);
+      poly[0].x=radius*Cos(phi2)*Cos(theta+2*pi/FACES/2);
+      poly[0].y=radius*Cos(phi2)*Sin(theta+2*pi/FACES/2);
+      poly[0].z=-radius*Sin(phi2);
+      Lighting(dc,&ls,poly,RED);
+      GrFillPoly3(dc,3,poly);
+
+      poly[0].x=radius*Cos(phi2)*Cos(theta +2*pi/FACES/2);
+      poly[0].y=radius*Cos(phi2)*Sin(theta +2*pi/FACES/2);
+      poly[0].z=-radius*Sin(phi2);
+      poly[1].x=radius*Cos(phi2)*Cos(theta2+2*pi/FACES/2);
+      poly[1].y=radius*Cos(phi2)*Sin(theta2+2*pi/FACES/2);
+      poly[1].z=-radius*Sin(phi2);
+      poly[2].x=radius*Cos(phi)*Cos(theta2);
+      poly[2].y=radius*Cos(phi)*Sin(theta2);
+      poly[2].z=-radius*Sin(phi);
+      Lighting(dc,&ls,poly,RED);
+      GrFillPoly3(dc,3,poly);
+    }
+  }
+}
+
+//See ::/Demo/Graphics/SpritePlot3D.HC.
+//for a CSprite example.
+
+//See SpriteMeshEd() for a fancy example.
+
+U0 Main()
+{
+  CCtrl *c=ViewAnglesNew;
+  CViewAngles *s=c->state;
+  s->sx=2*VIEWANGLES_SNAP;
+  s->sy=7*VIEWANGLES_SNAP;
+  s->sz=6*VIEWANGLES_SNAP;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  try {
+    "\n\nMove mouse to change light source.\n\n";
+    PressAKey;
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+  ViewAnglesDel;
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Graphics/Shadow.HC.HTML b/public/Wb/Demo/Graphics/Shadow.HC.HTML new file mode 100755 index 0000000..7316cf0 --- /dev/null +++ b/public/Wb/Demo/Graphics/Shadow.HC.HTML @@ -0,0 +1,133 @@ + + + + + + + + + + + +
+F64 theta,phi,omega,s;
+CDC *dc0,*dc1;
+
+
+
+
+
+
+
+
+                 <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+U0 GrBlackLighting(CDC *dc,CD3I32 *,CD3I32 *,CD3I32 *,CColorROPU32)
+{
+  dc->color=0;
+}
+
+U0 DrawShadow(CTask *task)
+{
+  I64 r[4][4],*r2;
+
+  Mat4x4IdentEqu(dc1->r);
+  Mat4x4RotZ(dc1->r,theta);
+  Mat4x4RotX(dc1->r,phi);
+  Mat4x4RotZ(dc1->r,omega);
+  Mat4x4Scale(dc1->r,s);
+  Mat4x4TranslationEqu(dc1->r,200,200,5000);
+  dc1->flags|=DCF_TRANSFORMATION;
+  DCMat4x4Set(dc1,dc1->r);
+
+  MemSet(r,0,sizeof(r));
+
+  r[0][0]=GR_SCALE;
+  r[1][1]=GR_SCALE/2; //Pick a plane for the shadow, to suit your taste.
+  r[1][2]=GR_SCALE/2; //It doesn't have to have a norm of 1.0.
+  r[2][2]=GR_SCALE;
+  r[3][3]=GR_SCALE;
+
+  Mat4x4TranslationEqu(r,0,-2200,1000);
+  r2=Mat4x4MulMat4x4New(r,dc1->r,task);
+  Free(dc1->r);
+  DCMat4x4Set(dc1,r2);
+
+  dc1->lighting=&GrBlackLighting;
+  Sprite3(dc1,0,0,0,<1>);
+}
+
+U0 DrawIt(CTask *task,CDC *)
+{
+  DCDepthBufRst(dc0);
+  Mat4x4IdentEqu(dc0->r);
+  Mat4x4RotZ(dc0->r,theta);
+  Mat4x4RotX(dc0->r,phi);
+  Mat4x4RotZ(dc0->r,omega);
+  Mat4x4Scale(dc0->r,s);
+  Mat4x4TranslationEqu(dc0->r,200,200,5000);
+  dc0->flags|=DCF_TRANSFORMATION;
+  DCMat4x4Set(dc0,dc0->r);
+  if (mp_cnt>1)
+    JobQue(&DrawShadow,task,1);
+  else
+    DrawShadow(task);
+  Sprite3(dc0,0,0,0,<1>);
+}
+
+U0 Shadow()
+{//The shadow image b.s.  Any is plausible.
+  dc0=DCAlias(gr.dc2,Fs);
+  dc1=DCAlias(gr.dc2,Fs);
+  DCDepthBufAlloc(dc0);
+  dc1->depth_buf=dc0->depth_buf;
+
+  theta=0;
+  phi=0;
+  omega=0;
+  s=1.5;
+
+  SettingsPush; //See SettingsPush
+  WinMax;
+  Fs->draw_it=&DrawIt;
+
+  while (!ScanChar) {
+    theta+=2*pi/70;
+    phi+=2*pi/90;
+    omega+=2*pi/110;
+    Sleep(20);
+  }
+  SettingsPop;
+  DCDel(dc0);
+  dc1->depth_buf=NULL;
+  DCDel(dc1);
+}
+
+Shadow;
+
+ diff --git a/public/Wb/Demo/Graphics/Slider.HC.HTML b/public/Wb/Demo/Graphics/Slider.HC.HTML new file mode 100755 index 0000000..382c214 --- /dev/null +++ b/public/Wb/Demo/Graphics/Slider.HC.HTML @@ -0,0 +1,141 @@ + + + + + + + + + + + +
+/*This was done with <CTRL-SHIFT-L> template code.
+It's conceptually easy to do a ctrl,
+but tedious.  You have complete freedom.
+
+See CCtrl.
+*/
+
+//Start of autocreated Code
+#define SLIDER_RANGE   30
+#define SLIDER_SPACING 20
+#define SLIDER_BORDER  2
+
+class CSliderState
+{
+  I64 left_pos;
+  I64 right_pos;
+} sld;
+
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,SLIDER_SPACING*3+2,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BLUE;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+        SLIDER_SPACING*3+2-2*SLIDER_BORDER,
+        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING,
+        c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
+        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  dc->color=LTRED;
+  GrPrint(dc,c->left+1*SLIDER_SPACING+0-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->left_pos*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->right_pos*10/SLIDER_RANGE);
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-2,7,5);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-1,5,3);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-1,5,3);
+}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
+  c->right=c->left+3*SLIDER_SPACING+2;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+  s->left_pos=ClampI64(s->left_pos,0,SLIDER_RANGE-1);
+  s->right_pos=ClampI64(s->right_pos,0,SLIDER_RANGE-1);
+}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CSliderState *s=c->state;
+  if (x<c->left+1*SLIDER_SPACING+0+SLIDER_SPACING/2)
+    s->left_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else
+    s->right_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&sld;
+  MemSet(&sld,0,sizeof(CSliderState));
+  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+//End of autocreated Code
+
+U0 Main()
+{
+  "This is to demo ctrls.\n";
+  CCtrl *c=SliderNew;
+  PressAKey;
+  "Left: %d  Right: %d\n",
+        sld.left_pos*10/SLIDER_RANGE,
+        sld.right_pos*10/SLIDER_RANGE;
+  SliderDel(c);
+  DocBottom;
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Graphics/Speedline.HC.HTML b/public/Wb/Demo/Graphics/Speedline.HC.HTML new file mode 100755 index 0000000..fe2103f --- /dev/null +++ b/public/Wb/Demo/Graphics/Speedline.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+//This is a drawing program
+
+public U0 SpeedLineDemo()
+{
+  I64 msg_code,cnt,x1,y1,x2,y2,arg1,arg2,color=BLACK;
+  CDC *dc=DCAlias;
+  dc->color=color;
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_MS_R_UP:
+        color=PopUpColor;
+        if (color>=0)
+          dc->color=color;
+        break;
+      case MSG_MS_L_DOWN:
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        cnt=0;
+        while (msg_code!=MSG_MS_L_UP) {
+          dc->thick=0.04*ms.speed;
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,
+                1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          x1=x2; y1=y2;
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        break;
+      case MSG_KEY_DOWN:
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || !arg1);
+  GetMsg(,,1<<MSG_KEY_UP);
+  DCFill;
+  DCDel(dc);
+  SettingsPop;
+}
+
+SpeedLineDemo;  //Execute when #included
+
+ diff --git a/public/Wb/Demo/Graphics/SpritePlot.HC.HTML b/public/Wb/Demo/Graphics/SpritePlot.HC.HTML new file mode 100755 index 0000000..f5b3552 --- /dev/null +++ b/public/Wb/Demo/Graphics/SpritePlot.HC.HTML @@ -0,0 +1,92 @@ + + + + + + + + + + + +
+/*Sprite graphics can be placed in src code.
+The binary graphic data is stored in the
+file after the text area.  <CTRL-r> is used
+to generate a sprite.  Press <CTRL-t> to
+toggle to plain text mode and see its
+text place holder $SP...$.  You can place any text
+in the tag quotes or none.  The text doesn't matter,
+but the BI=num does.  The num identifies
+the sprite and can't be changed by you.
+
+Insert a ptr to a sprite by pressing <CTRL-r>
+and "Ptr to Sprite".  This creates an "Insert Bin",
+$IB...$ DolDoc cmd you can see by toggling
+to text with <CTRL-t>.
+
+IB's behave like string consts in HolyC when
+compiled.  That is, they are ptrs to data.
+
+This file uses the persistent graphic
+device context CDC, gr.dc, while the other
+demo's use gr.dc2 which must be redrawn at
+30 fps by the window mgr task.  This demo
+is simpler because you do not need
+a window update callback routine.
+*/
+
+
+
+
+
+
+
+
+
+            <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+U0 SpritePlot()
+{
+  CDC *dc=DCAlias;
+  I64 i;
+  DocClear;
+  for (i=0;i<GR_WIDTH>>2;i++) {
+    DCFill;
+    Sprite3(dc,i,GR_HEIGHT>>1,0,<1>);
+    Sleep(3);
+  }
+  "Image size:%d\n",<1>;
+  DCDel(dc);
+  PressAKey;
+  DCFill;
+}
+
+SpritePlot;
+
+ diff --git a/public/Wb/Demo/Graphics/SpritePlot3D.HC.HTML b/public/Wb/Demo/Graphics/SpritePlot3D.HC.HTML new file mode 100755 index 0000000..254d4d8 --- /dev/null +++ b/public/Wb/Demo/Graphics/SpritePlot3D.HC.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+      <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+I64 glbl_r[4][4];
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 *old_r=dc->r;
+  dc->x=200;
+  dc->y=200;
+  dc->z=GR_Z_ALL;
+  dc->flags|=DCF_TRANSFORMATION;
+  DCDepthBufAlloc(dc);
+  DCMat4x4Set(dc,glbl_r); //This assigns to dc->r and sets r_norm.
+  DCDepthBufRst(dc);
+  Sprite3(dc,0,0,0,<1>);
+  dc->r=old_r;
+}
+
+U0 SpritePlot3D()
+{
+  F64 theta=0,phi=0;
+
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  while (!ScanChar) {
+    Mat4x4IdentEqu(glbl_r);
+    Mat4x4RotX(glbl_r,phi);
+    Mat4x4RotZ(glbl_r,theta);
+
+    Sleep(40);
+    theta+=2*pi/100;
+    phi+=2*pi/130;
+  }
+  SettingsPop;
+}
+
+SpritePlot3D;
+
+ diff --git a/public/Wb/Demo/Graphics/SpritePut.HC.HTML b/public/Wb/Demo/Graphics/SpritePut.HC.HTML new file mode 100755 index 0000000..1722827 --- /dev/null +++ b/public/Wb/Demo/Graphics/SpritePut.HC.HTML @@ -0,0 +1,70 @@ + + + + + + + + + + + +
+//Use <CTRL-r> to add or edit sprites
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+//Used by ::/Demo/Graphics/SpritePutExt.HC.
+
+U0 SpritePut()
+{
+  I64 i;
+  for (i=0;i<3;i++) {
+    "US Flag:";
+    Sprite(<1>);
+    "%h12c",'\n';
+  }
+  "US Map:";
+  Sprite(<2>);
+  "%h10c",'\n';
+}
+
+SpritePut; //Start program when #included
+
+ diff --git a/public/Wb/Demo/Graphics/SpritePutExt.HC.HTML b/public/Wb/Demo/Graphics/SpritePutExt.HC.HTML new file mode 100755 index 0000000..8743840 --- /dev/null +++ b/public/Wb/Demo/Graphics/SpritePutExt.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+/*If you press <CTRL-t> you will see this:
+
+$IB,"<1>",BI=1,BP="::/Demo/Graphics/SpritePut.HC,2"$
+
+That imports an external sprite.  It's
+called a DOCEF_BIN_PTR_LINK.  See BP="".
+
+Press <CTRL-r> and "Ptr to Sprite".
+Then, enter a file and the number of
+the sprite in the file.  Note: the
+number can get messed-up if you change
+the order of sprites in the source file.
+You can link to a tag string instead of a num.
+*/
+
+U0 SpritePutExt()
+{
+  I64 i;
+  for (i=0;i<3;i++) {
+    "US Map:";
+    Sprite(<1>);
+    "%h12c",'\n'; //"h" is a secondary arg.  Print 12 newline chars.
+  }
+}
+
+SpritePutExt;
+
+ diff --git a/public/Wb/Demo/Graphics/SpriteRaw.HC.HTML b/public/Wb/Demo/Graphics/SpriteRaw.HC.HTML new file mode 100755 index 0000000..f12be80 --- /dev/null +++ b/public/Wb/Demo/Graphics/SpriteRaw.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+//Normally, you make sprites with <CTRL-r>.
+//This shows how to build a sprite by hand.
+//See ::/Apps/GrModels.
+
+class MySprite
+{ // See Sprite Elem Types
+  CSpriteColor  color;
+  CSpritePtPt   line1;
+  CSpritePtPt   line2;
+  CSpritePtPt   line3;
+  CSpritePt     fill;
+  CSpriteBase   end;
+};
+
+
+U0 SpriteRawDemo()
+{
+  MySprite s;
+
+  MemSet(&s,0,sizeof(s));
+  s.color.type=SPT_COLOR;
+  s.color.color=GREEN;
+  s.line1.type=SPT_LINE;
+  s.line1.x2=100; s.line1.y2=50;
+  s.line2.type=SPT_LINE;
+  s.line2.x2=50; s.line2.y2=100;
+  s.line3.type=SPT_LINE;
+  s.line3.x1=100; s.line3.y1=50;
+  s.line3.x2=50; s.line3.y2=100;
+  s.fill.type=SPT_FLOOD_FILL;
+  s.fill.x1=20; s.fill.y1=20;
+  s.end.type=SPT_END;
+
+  Sprite(&s);
+  "%h13c",'\n';
+}
+
+SpriteRawDemo;
+
+ diff --git a/public/Wb/Demo/Graphics/SpriteText.HC.HTML b/public/Wb/Demo/Graphics/SpriteText.HC.HTML new file mode 100755 index 0000000..6db8a60 --- /dev/null +++ b/public/Wb/Demo/Graphics/SpriteText.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+
+                /* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+U0 SpriteText(U8 *elems)
+{
+  CSprite *tmpg=elems-offset(CSprite.start);
+  U8 *st;
+  while (tmpg->type&SPG_TYPE_MASK) {
+//Study this routine SpriteElem2Summary().
+    st=SpriteElem2Summary(tmpg);
+    "%s\n",st;
+    Free(st);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+}
+
+"$PURPLE$**** LINE SUMMARIES ****$FG$\n";
+SpriteText(<1>);
+
+"\n\n$PURPLE$**** ENTIRE SPRITE CODE ****$FG$\n";
+Sprite2Code(,<1>);
+
+ diff --git a/public/Wb/Demo/Graphics/SunMoon.HC.HTML b/public/Wb/Demo/Graphics/SunMoon.HC.HTML new file mode 100755 index 0000000..17f873c --- /dev/null +++ b/public/Wb/Demo/Graphics/SunMoon.HC.HTML @@ -0,0 +1,74 @@ + + + + + + + + + + + +
+/*gr.dc is the persistent layer.  You can access
+it directly but two tasks accessing it simultaneously
+with no DCAlias() will screw-up color and stuff.
+*/
+
+U0 SunMoon()
+{
+  I64 i,x,y,radius;
+
+  AutoComplete; //AutoComplete Off
+  WinBorder;    //No Border
+  WinMax;       //Maximize window
+  DocClear;     //Clear command-line text
+  Fs->text_attr=BLACK<<4+WHITE; //Current CTask is Fs segment register.
+
+  for (i=0;i<0x8000;i+=0x200) {
+//Sun
+    x=0.2*GR_WIDTH; y=0.5*GR_HEIGHT; radius=120;
+    gr.dc->color=DKGRAY;
+    GrCircle(gr.dc,x,y,radius);
+    gr.dc->color=ROPF_DITHER+RED<<16+YELLOW;
+    GrFloodFill(gr.dc,x,y);
+
+    //Moon
+    x=0.8*GR_WIDTH-i/0x200; y=0.5*GR_HEIGHT; radius=75;
+    gr.dc->color=DKGRAY;
+    GrCircle(gr.dc,x,y,radius);
+//<CTRL-ALT-a> for the "pi" character.
+    GrCircle(gr.dc,x+0.5*radius,y,1.2*radius,,pi-.31*pi,0.62*pi);
+    gr.dc->color=ROPF_PROBABILITY_DITHER+LTGRAY<<16+BLACK;
+    gr.dc->dither_probability_u16=i;    //U16 can be [0,65535]
+    GrFloodFill(gr.dc,x+0.5*radius,y);
+    gr.dc->dither_probability_u16=2*i;  //U16 can be [0,65535]
+    GrFloodFill(gr.dc,x-0.75*radius,y);
+
+    Refresh; //Typically 30 fps
+    DCFill;
+  }
+
+  Fs->text_attr=WHITE<<4+BLUE;
+}
+
+SunMoon;
+
+ diff --git a/public/Wb/Demo/Graphics/Symmetry.HC.HTML b/public/Wb/Demo/Graphics/Symmetry.HC.HTML new file mode 100755 index 0000000..c6fb04f --- /dev/null +++ b/public/Wb/Demo/Graphics/Symmetry.HC.HTML @@ -0,0 +1,93 @@ + + + + + + + + + + + +
+/*Demonstrates symmetry.
+Right-click and draw line of symmetry.
+If the line of symmetry is a point, symmetry is turned-off.
+*/
+
+U0 SymmetryDemo()
+{
+  I64 msg_code,x1,y1,x2,y2,arg1,arg2;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  dc->flags|=DCF_SYMMETRY;
+  DCSymmetrySet(dc,Fs->pix_width/2,0,Fs->pix_width/2,1);
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+
+          1<<MSG_MS_R_DOWN);
+    switch (msg_code) {
+      case MSG_MS_R_DOWN:
+        dc->flags&=~DCF_SYMMETRY;
+        dc->color=ROP_XOR+RED^TRANSPARENT;
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        while (msg_code!=MSG_MS_R_UP) {
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,
+                1<<MSG_MS_R_UP+1<<MSG_MS_MOVE);
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        if (DCSymmetry3Set(dc,x1,y1,0,x2,y2,0,x2,y2,1))
+          dc->flags|=DCF_SYMMETRY;
+        break;
+      case MSG_MS_L_DOWN:
+        dc->color=ROP_XOR+BLACK^TRANSPARENT;
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        while (msg_code!=MSG_MS_L_UP) {
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,
+                1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || (arg1!=CH_ESC && arg1!=CH_SHIFT_ESC));
+  GetMsg(,,1<<MSG_KEY_UP);
+  DCFill;
+  DCDel(dc);
+  SettingsPop;
+}
+
+SymmetryDemo;  //Execute when #included
+
+ diff --git a/public/Wb/Demo/Graphics/Transform.HC.HTML b/public/Wb/Demo/Graphics/Transform.HC.HTML new file mode 100755 index 0000000..a0d73fa --- /dev/null +++ b/public/Wb/Demo/Graphics/Transform.HC.HTML @@ -0,0 +1,253 @@ + + + + + + + + + + + +
+/*This highlights the 4th dimension
+of the transformation matrix which
+is used for storing translations (shifts)
+in matricies so they can be combined
+with a matrix multiplication.
+
+Scroll bar works.
+
+The multiplication takes place in the
+Sprite3ZB routine.
+*/
+
+#define SLIDER_SPACING 20
+#define SLIDER_RANGE   30
+#define SLIDER_BORDER  2
+
+class CSliderState
+{
+  I64 s1,s2,s3;
+  F64 arg1,arg2,scale;
+} s;
+
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTGREEN;
+  GrRect(dc, c->left,c->top,SLIDER_SPACING*4+3,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BROWN;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+        SLIDER_SPACING*4+3-2*SLIDER_BORDER,
+        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+SLIDER_SPACING,c->top+SLIDER_SPACING,
+        c->left+SLIDER_SPACING,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
+        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+3*SLIDER_SPACING+2,c->top+SLIDER_SPACING,
+        c->left+3*SLIDER_SPACING+2,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+
+  dc->color=LTGREEN;
+  GrPrint(dc,c->left+SLIDER_SPACING-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->s1*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->s2*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+3*SLIDER_SPACING+2-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->s3*10/SLIDER_RANGE);
+  GrRect(dc,c->left+SLIDER_SPACING-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s1-2 ,7,5);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s2-2,7,5);
+  GrRect(dc,c->left+3*SLIDER_SPACING+2-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s3-2,7,5);
+  dc->color=GREEN;
+  GrRect(dc,c->left+SLIDER_SPACING-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s1-1 ,5,3);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s2-1,5,3);
+  GrRect(dc,c->left+3*SLIDER_SPACING+2-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s3-1,5,3);
+}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*4+3)/2;
+  c->right=c->left+SLIDER_SPACING*4+3;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+  s->s1=ClampI64(s->s1,0,SLIDER_RANGE-1);
+  s->s2=ClampI64(s->s2,0,SLIDER_RANGE-1);
+  s->s3=ClampI64(s->s3,1,SLIDER_RANGE-1);
+  s->arg1=pi/2.0*s->s1/SLIDER_RANGE;
+  s->arg2=1.0*(s->s2-SLIDER_RANGE/2)/SLIDER_RANGE;
+  s->scale=2.0*s->s3/SLIDER_RANGE;
+}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CSliderState *s=c->state;
+  if (x<c->left+(c->right-c->left)/3)
+    s->s1=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else if (x<c->left+2*(c->right-c->left)/3)
+    s->s2=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else
+    s->s3=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&s;
+  MemSet(&s,0,sizeof(s));
+  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+#define MAP_HEIGHT      2048
+#define MAP_WIDTH       2048
+
+#define TREES_NUM       256
+
+I64 tree_x[TREES_NUM],tree_y[TREES_NUM];
+
+class MPCtrl {
+  I64 mp_cnt;
+  I64 r[16];
+  F64 a;
+} mp;
+
+I64 mp_not_done_flags;
+
+U0 MPDrawIt(CTask *task)
+{
+  CDC *dc=DCAlias(gr.dc2,task);
+  I64 i,lo=Gs->num*TREES_NUM/mp.mp_cnt,hi=(Gs->num+1)*TREES_NUM/mp.mp_cnt;
+  MemCpy(dc->r,mp.r,sizeof(I64)*16);
+  dc->flags|=DCF_TRANSFORMATION;
+  for (i=lo;i<hi;i++)
+    Sprite3ZB(dc,tree_x[i],
+          tree_y[i],0,<tree>,mp.a);
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,h,v;
+  task->horz_scroll.min=-s.scale*MAP_HEIGHT*Sin(s.arg1);
+  task->horz_scroll.max=s.scale*MAP_WIDTH*Cos(s.arg1)-task->pix_width;
+  task->vert_scroll.min=0;
+  task->vert_scroll.max=s.scale*(MAP_HEIGHT*Cos(s.arg1)+MAP_WIDTH*Sin(s.arg1))
+  -task->pix_height;
+  TaskDerivedValsUpdate(task);
+
+  h=task->horz_scroll.pos;
+  v=task->vert_scroll.pos;
+
+  Mat4x4RotZ(dc->r,s.arg1);
+  Mat4x4Scale(dc->r,s.scale);
+  DCMat4x4Set(dc,dc->r);
+  Mat4x4TranslationEqu(dc->r,-h,-v,0);
+  MemCpy(mp.r,dc->r,sizeof(I64)*16);
+  mp.a=s.arg2;
+
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp.mp_cnt;i++)
+    JobQue(&MPDrawIt,task,i);
+  while (mp_not_done_flags)
+    Yield;
+
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->color=BROWN;
+  dc->thick=4;
+  GrLine3(dc,2,2,0,MAP_WIDTH-3,2,0);
+  GrLine3(dc,2,MAP_HEIGHT-3,0,MAP_WIDTH-3,MAP_HEIGHT-3,0);
+  GrLine3(dc,2,2,0,2,MAP_HEIGHT-3,0);
+  GrLine3(dc,MAP_WIDTH-3,2,0,MAP_WIDTH-3,MAP_HEIGHT-3,0);
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<TREES_NUM;i++) {
+    tree_x[i]=RandU16%MAP_WIDTH;
+    tree_y[i]=RandU16%MAP_HEIGHT;
+  }
+}
+
+U0 TransformDemo(I64 _mp_cnt=mp_cnt)
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER
+        -WIF_SELF_GRAB_SCROLL-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  Fs->draw_it=&DrawIt;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DocScroll;
+
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+  CCtrl *c=SliderNew;
+  s.s1=0;
+  s.s2=SLIDER_RANGE/2;
+  s.s3=SLIDER_RANGE/2;
+
+  MemSet(&mp,0,sizeof(MPCtrl));
+  mp.mp_cnt=_mp_cnt;
+
+  View;
+  SliderDel(c);
+  SettingsPop;
+//You might want to save the original state of the scroll bars.
+}
+
+TransformDemo;
+
+ diff --git a/public/Wb/Demo/Graphics/WallPaperCtrl.HC.HTML b/public/Wb/Demo/Graphics/WallPaperCtrl.HC.HTML new file mode 100755 index 0000000..d9e0d74 --- /dev/null +++ b/public/Wb/Demo/Graphics/WallPaperCtrl.HC.HTML @@ -0,0 +1,139 @@ + + + + + + + + + + + +
+/*Done with <CTRL-SHIFT-L> template code
+that was modified.
+
+This is an advanced demo that shows
+that you can place ctrls on the
+wall paper.
+
+See ::/Demo/Graphics/Slider.HC
+and ::/Demo/Graphics/WallPaperFish.HC
+before messing with this program.
+
+It must be "Adam Included".
+*/
+
+#define SLIDER_RANGE   30
+#define SLIDER_SPACING 20
+#define SLIDER_BORDER  2
+
+class CSliderState
+{
+  I64 left_pos;
+  I64 right_pos;
+};
+
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,SLIDER_SPACING*3+2,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BLUE;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+        SLIDER_SPACING*3+2-2*SLIDER_BORDER,
+        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING,
+        c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
+        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  dc->color=LTRED;
+  GrPrint(dc,c->left+1*SLIDER_SPACING+0-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->left_pos*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->right_pos*10/SLIDER_RANGE);
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-2,7,5);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-1,5,3);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-1,5,3);
+}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
+  c->right=c->left+3*SLIDER_SPACING+2;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+  s->left_pos=ClampI64(s->left_pos,0,SLIDER_RANGE-1);
+  s->right_pos=ClampI64(s->right_pos,0,SLIDER_RANGE-1);
+}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CSliderState *s=c->state;
+  if (x<c->left+1*SLIDER_SPACING+0+SLIDER_SPACING/2)
+    s->left_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else
+    s->right_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c;
+  if (Fs!=adam_task) {
+    "Must be Adam Included with SHIFT-F5.\n"
+          "(Would crash when code mem was freed.)\n";
+    return NULL;
+  }
+  c=ACAlloc(sizeof(CCtrl));
+  c->win_task=sys_winmgr_task;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=ACAlloc(sizeof(CSliderState));
+  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,sys_winmgr_task->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c->state);
+  Free(c);
+}
+
+SliderNew;
+
+ diff --git a/public/Wb/Demo/Graphics/WallPaperFish.HC.HTML b/public/Wb/Demo/Graphics/WallPaperFish.HC.HTML new file mode 100755 index 0000000..f125ba7 --- /dev/null +++ b/public/Wb/Demo/Graphics/WallPaperFish.HC.HTML @@ -0,0 +1,146 @@ + + + + + + + + + + + +
+/* You "Adam include" this because you want the wallpaper
+routine to stay in mem even if this task is killed.
+
+  <CTRL-t> to see the hidden text needed for sprite elements.
+
+  <CTRL-r> to add a sprite to a document.
+*/
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+
+<6>/* Graphics Not Rendered in HTML */
+
+
+
+<7>/* Graphics Not Rendered in HTML */
+
+
+<8>/* Graphics Not Rendered in HTML */
+
+
+<9>/* Graphics Not Rendered in HTML */
+
+
+#define TYPES_OF_CRITTERS       3
+#define FRAMES_PER_CRITTER      4
+
+U8 *imgs[TYPES_OF_CRITTERS][FRAMES_PER_CRITTER]={
+  {<1>,<2>,<3>,<2>},
+  {<4>,<5>,<6>,<5>},
+  {<7>,<8>,<9>,<8>}
+};
+
+#define CRITTERS_NUM    16
+class Critter
+{
+  I64 x,y,dx,dy,type;
+  F64 t_offset;
+} wall_crits[CRITTERS_NUM];
+
+U0 (*old_wall_paper)(CTask *task);
+
+U0 WallPaperFish(CTask *task)
+{
+  I64 i,j,x,y;
+  CDC *dc=DCAlias(gr.dc2,task);
+  Critter *c=wall_crits;
+
+  task->text_attr=CYAN<<4+WHITE;
+  dc->color=BROWN;
+  for (i=0;i<GR_HEIGHT;i+=20) {
+    j=16*Tri(tS*10,20);
+    GrLine(dc,0,GR_HEIGHT-i-j,GR_HEIGHT-i-j,GR_HEIGHT);
+  }
+  for (i=0;i<CRITTERS_NUM;i++,c++) {
+    j=(tS*4+c->t_offset)%FRAMES_PER_CRITTER;
+    x=c->x>>16%GR_WIDTH;
+    if (x<0) x+=GR_WIDTH;
+    y=c->y>>16%GR_HEIGHT;
+    if (y<0) y+=GR_HEIGHT;
+    if (c->dx<0) {
+      dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+      DCSymmetrySet(dc,x,y-1,x,y+1);
+    } else
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    Sprite3(dc,x,y,0,imgs[c->type][j]);
+    c->x+=c->dx;  c->y+=c->dy;
+  }
+  DCDel(dc);
+
+  //Uncomment the following if you wish.
+  //old_wall_paper(task);
+}
+
+U0 WallInit()
+{
+  I64 i;
+  Critter *c;
+  if (Fs!=adam_task) {
+    "Must be Adam Included with SHIFT-F5.\n"
+          "(Would crash when code mem was freed.)\n";
+    return;
+  }
+  old_wall_paper=gr.fp_wall_paper;
+  c=wall_crits;
+  for (i=0;i<CRITTERS_NUM;i++,c++) {
+    c->x=(RandU16%GR_WIDTH)<<16;
+    c->y=(RandU16%GR_HEIGHT)<<16;
+    c->type=RandU16%TYPES_OF_CRITTERS;
+    c->dx=RandI16;
+    if (c->dx<0)
+      c->dx-=0x4000;
+    else
+      c->dx+=0x4000;
+    c->dy=RandI16;
+    c->t_offset=Rand*FRAMES_PER_CRITTER;
+  }
+  gr.fp_wall_paper=&WallPaperFish;
+}
+
+WallInit;
+
+ diff --git a/public/Wb/Demo/Graphics/WinZBuf.HC.HTML b/public/Wb/Demo/Graphics/WinZBuf.HC.HTML new file mode 100755 index 0000000..b10be15 --- /dev/null +++ b/public/Wb/Demo/Graphics/WinZBuf.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i,j;
+  U16 *ptr=gr.win_z_buf;
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Move the windows around and watch.");
+  for (i=0;i<TEXT_ROWS;i++)
+    for (j=0;j<TEXT_COLS;j++) {
+      dc->color=*ptr++&15;
+      GrPlot(dc,j,i+FONT_HEIGHT);
+    }
+}
+
+U0 ScrollBars()
+{
+  SettingsPush; //See SettingsPush
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar(,FALSE);
+  SettingsPop;
+}
+
+ScrollBars;
+
+ diff --git a/public/Wb/Demo/InFile/InPopUp.HC.HTML b/public/Wb/Demo/InFile/InPopUp.HC.HTML new file mode 100755 index 0000000..7ba36c5 --- /dev/null +++ b/public/Wb/Demo/InFile/InPopUp.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+/* This is not an InFile.  It uses InStr
+to run text as though from an InFile.
+
+This example shows how you can drive pop-up
+windows.
+*/
+
+In(" ");
+"PopUp #1:%X\n",PopUpNoYes;
+
+InStr("Msg(MSG_KEY_DOWN,0,SC_CURSOR_RIGHT);'' CH_SPACE;");
+"PopUp #2:%X\n",PopUpNoYes;
+
+ diff --git a/public/Wb/Demo/InFile/InSetIP.HC.HTML b/public/Wb/Demo/InFile/InSetIP.HC.HTML new file mode 100755 index 0000000..cafcfde --- /dev/null +++ b/public/Wb/Demo/InFile/InSetIP.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+U0 InSetMsDemo()
+{
+  I64 t,l;
+  WinBorder(ON);
+  l=Fs->pix_left+Fs->scroll_x;
+  t=Fs->pix_top+Fs->scroll_y;
+  MsSet(,,,FALSE,FALSE); //Mouse unclicked
+  InSetMs(,l-4,t-4);
+  InSetMs(20,l+20,t+20,,TRUE);
+  MsSet(,,,FALSE,FALSE);
+}
+
+InSetMsDemo;
+
+ diff --git a/public/Wb/Demo/KeyBitMap.HC.HTML b/public/Wb/Demo/KeyBitMap.HC.HTML new file mode 100755 index 0000000..60df410 --- /dev/null +++ b/public/Wb/Demo/KeyBitMap.HC.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+I64 x=0;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  Sprite3(dc,x%100,100,0,<1>);
+}
+
+U0 KeyDownBitMapDemo()
+{
+//This conversion routine is slow.
+  I64 i_sc=Char2ScanCode('i');
+
+  "Press and hold $GREEN$'i'$FG$.\n";
+  while (!Bt(kbd.down_bitmap,i_sc))
+    Yield;
+
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+
+  //kbd.down_bitmap is indexed with the
+  //merged scan code.  (left shift and
+  //right shift combined for example.)
+  //kbd.down_bitmap2 is indexed with the
+  //distinct scan code.  See Char and Scan Codes.
+
+  while (Bt(kbd.down_bitmap,i_sc)) {
+    x++;
+    Sleep(10);
+  }
+  SettingsPop;
+  FlushMsgs;
+}
+
+KeyDownBitMapDemo;
+
+ diff --git a/public/Wb/Demo/LastClass.HC.HTML b/public/Wb/Demo/LastClass.HC.HTML new file mode 100755 index 0000000..52f2525 --- /dev/null +++ b/public/Wb/Demo/LastClass.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+U0 StructName(U8 *d,U8 *class_name=lastclass)
+{//lastclass is the prev fun arg's class as a string.
+  "%X is a \"%s\".\n",d,class_name;
+}
+
+class Student
+{
+  Student *next;
+  I64 age;
+  U8 name[32];
+} a;
+
+class School
+{
+  U8 name[32];
+  Student *students;
+} s;
+
+I64 i;
+
+StructName(Fs);
+StructName(&a);
+StructName(&s);
+StructName(&i);
+PressAKey;
+
+//lastclass is used in ClassRep() and ClassRepD().
+ClassRepD(Gs);
+PressAKey;
+
+ClassRep(Fs);
+
+//See also DocForm(), ::/Demo/Dsk/BlkDevRep.HC and ::/Demo/ClassMeta.HC.
+
+ diff --git a/public/Wb/Demo/Lectures/64BitAsmQuiz.DD.HTML b/public/Wb/Demo/Lectures/64BitAsmQuiz.DD.HTML index 927c6f0..610db10 100755 --- a/public/Wb/Demo/Lectures/64BitAsmQuiz.DD.HTML +++ b/public/Wb/Demo/Lectures/64BitAsmQuiz.DD.HTML @@ -102,12 +102,12 @@ 2) The upper 32-bits are set to zero. 3) To set FS or GS, you use WRMSR to write a model specific reg. See
-IA32_FS_BASE and SET_FS_BASE. +IA32_FS_BASE and SET_FS_BASE. 4) Displacement addressing is now RIP relative, so RIP would be added to TSS_SOME_MEMBER. (Useless) -5) The R13 instruction takes one more byte because it is like REG_RBP in the +5) The R13 instruction takes one more byte because it is like REG_RBP in the ModR. 6) The R8 instruction needs a REX byte prefix to specify upper-8 reg. @@ -118,7 +118,7 @@ 8) To call a subroutine farther than 2Gig away, you put the address into RAX, then CALL RAX. -9) CALL REL32 is significantly faster. See ::/Demo/Lectures/InterruptDemo.HC. +9) CALL REL32 is significantly faster. See ::/Demo/Lectures/InterruptDemo.HC. 10) IN or OUT instructions happen at a fixed speed based on the original ISA bus clock. diff --git a/public/Wb/Demo/Lectures/AndNotMod.HC.HTML b/public/Wb/Demo/Lectures/AndNotMod.HC.HTML new file mode 100755 index 0000000..6b12051 --- /dev/null +++ b/public/Wb/Demo/Lectures/AndNotMod.HC.HTML @@ -0,0 +1,75 @@ + + + + + + + + + + + +
+//You may wonder why I use "&" instead of "%".
+
+#define SAMPLE_SIZE     100000000
+
+U0 TimeIns()
+{
+  I64 start1,end1,start2,end2,overhead_time,test_time;
+  I64 reg i,reg tmp;
+
+  CPURep;
+
+  //Measure Loop Overhead
+  start1=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++) {
+  }
+  end1=GetTSC;
+  overhead_time=end1-start1;
+
+  //Measure remainder...
+  start2=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    tmp=i%0x400;
+  end2=GetTSC;
+  test_time=end2-start2;
+  "Remainder Version #1 Cycles\t: %10.5f\n",
+        ToF64(test_time-overhead_time)/SAMPLE_SIZE;
+
+  //Measure remainder...
+  start2=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    tmp=i&0x3FF;
+  end2=GetTSC;
+  test_time=end2-start2;
+  "Remainder Version #2 Cycles\t: %10.5f\n",
+        ToF64(test_time-overhead_time)/SAMPLE_SIZE;
+}
+
+TimeIns;
+
+/*  Program Output
+8 Cores 2.660GHz
+Remainder Version #1 Cycles     :   26.85345
+Remainder Version #2 Cycles     :   -0.00800
+*/
+
+ diff --git a/public/Wb/Demo/Lectures/FixedPoint.HC.HTML b/public/Wb/Demo/Lectures/FixedPoint.HC.HTML new file mode 100755 index 0000000..37929c2 --- /dev/null +++ b/public/Wb/Demo/Lectures/FixedPoint.HC.HTML @@ -0,0 +1,127 @@ + + + + + + + + + + + +
+/*"Fixed point" means you use ints
+that are scaled by a value.  A common
+example would be using number of pennies
+instead of dollars with a float.
+
+Fixed-point used to be much faster,
+but modern processors do well with
+floats.  It also depends on the compiler
+and my compiler is poor with floats.
+
+I often use 64-bit ints with upper 32-bits
+as int and lower 32-bits as fraction.
+
+See ::/Demo/SubIntAccess.HC for how
+to access upper or lower 32-bits.
+
+For a complete lst of nonstandard compiler
+features, see ::/Doc/HolyC.DD.
+*/
+
+U0 Main()
+{
+  F64 t0,f_sum=0,f_val;
+  I64 i ,i_sum=0,i_val;
+
+  i_val= 2.0000002 *0x100000000;
+  t0=tS;
+  for (i=1000000000;i;i--)
+    i_sum+=i_val;
+  "Int Sum\t\t:%.9f Time:%7.3fs\n",i_sum/ToF64(0x100000000),tS-t0;
+
+  f_val= 2.0000002;
+  t0=tS;
+  for (i=1000000000;i;i--)
+    f_sum+=f_val;
+  "Float Sum\t:%.9f Time:%7.3fs\n",f_sum,tS-t0;
+  '\n';
+}
+
+U0 DoIt2()
+{
+  I64 i=0x123456789ABCDEF0;
+  "i\t\t=%X\n",i;
+
+  "i&0xFFFFFFFF\t=%X\n",i&0xFFFFFFFF;
+  "i>>32\t\t=%X\n",i>>32;
+
+  /*  Standard int types are declared
+with a special compiler feature which
+allows a structure to be accessed as a
+whole.  That's why the i variable can
+be accessed normally in addition to
+structure member access I64.  The actual
+intrinsic compiler type is U64i.
+
+public U64i union I64
+{
+  I8i i8[8];
+  U8i u8[8];
+  I16 i16[4];
+  U16 u16[4];
+  I32 i32[2];
+  U32 u32[2];
+};
+
+It's not quite as great as it seems
+because the compiler decides it cannot
+place i into a reg, so there is a
+penalty.
+
+For a complete lst of nonstandard compiler
+features, see ::/Doc/HolyC.DD.
+*/
+
+  "i.u32[0]\t=%X\n",i.u32[0];
+  "i.u32[1]\t=%X\n",i.u32[1];
+}
+
+CPURep;
+Main;
+DoIt2;
+
+//See ::/Demo/Lectures/FixedPointAdvanced.HC
+
+/*Program Output
+
+16 Cores 3.500GHz
+Int Sum         :2000000199.768690240 Time:  0.803s
+Float Sum       :2000000225.656127040 Time:  3.615s
+
+i               =123456789ABCDEF0
+i&0xFFFFFFFF    =9ABCDEF0
+i>>32           =12345678
+i.u32[0]        =9ABCDEF0
+i.u32[1]        =12345678
+*/
+
+ diff --git a/public/Wb/Demo/Lectures/FixedPointAdvanced.HC.HTML b/public/Wb/Demo/Lectures/FixedPointAdvanced.HC.HTML new file mode 100755 index 0000000..e50ccc0 --- /dev/null +++ b/public/Wb/Demo/Lectures/FixedPointAdvanced.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+/*"Fixed point" means you use ints
+that are scaled by a value.  A common
+example would be using number of pennies
+instead of dollars with a float.
+
+Fixed-point used to be much faster,
+but modern processors do well with
+floats.  It also depends on the compiler
+and my compiler is poor with floats.
+
+I often use 64-bit ints with upper 32-bits
+as int and lower 32-bits as fraction.
+
+See ::/Demo/SubIntAccess.HC for how
+to access upper or lower 32-bits.
+*/
+
+#define SAMPLE_SIZE     10000000
+
+I32 coordinates[65536];
+
+asm {
+_ASM_FIXED_POINT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,coordinates
+        MOV     RDI,ToI64(Sin(1.0)*0x100000000)
+        XOR     RBX,RBX //SUM
+        MOV     RCX,SAMPLE_SIZE-1
+@@05:   XOR     RDX,RDX
+        MOV     DX,CX
+        MOVSXD  RAX,U32 [RSI+RDX*4]
+        IMUL    RDI
+        SAR     RAX,32
+        ADD     RBX,RAX
+        DEC     RCX
+        JGE     @@05
+        MOV     RAX,RBX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+SINE_VAL:       DU64    Sin(1.0);
+RET_VAL:        DU64    0;
+
+_ASM_FLOAT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,coordinates
+        FLD     U64 [SINE_VAL]
+        FLDZ
+        MOV     RCX,SAMPLE_SIZE-1
+@@05:   XOR     RDX,RDX
+        MOV     DX,CX
+        FILD    U32 [RSI+RDX*4]
+        FMUL    ST0,ST2
+        FADDP   ST1,ST0
+        DEC     RCX
+        JGE     @@05
+        FISTP   U64 [RET_VAL]
+        MOV     RAX,U64 [RET_VAL]
+        FFREE   ST0
+        FINCSTP
+        POP     RSI
+        POP     RBP
+        RET
+}
+
+_extern _ASM_FIXED_POINT I64 AsmFixedPt();
+_extern _ASM_FLOAT I64 AsmFloat();
+
+U0 Main()
+{
+  I64 start,end,overhead_time,test_time;
+  F64 d1,fsum;
+  I64 reg i,tmp,reg d2,reg sum;
+
+  CPURep;
+
+  //Set-up some sample coordinates
+  for (i=0;i<65536;i++)
+    coordinates[i]=RandU32;
+
+    //Measure Loop Overhead
+  start=GetTSC;
+  for (i=SAMPLE_SIZE-1;i>=0;i--) {
+  }
+  end=GetTSC;
+  overhead_time=end-start;
+  "$RED$Overhead Cycles       :%10.5f$FG$\n",
+        ToF64(overhead_time)/SAMPLE_SIZE;
+
+  //Measure F64 arithmetic
+  // (Some of this is due to crappy
+  // compiler code.)
+  d1=Sin(1.0);
+  fsum=0;
+  start=GetTSC;
+  for (i=SAMPLE_SIZE-1;i>=0;i--)
+    fsum+=d1*coordinates[i&65535];
+  end=GetTSC;
+  test_time=end-start;
+  "Float Sum             :%X\n",ToI64(fsum);
+  "$RED$Float Cycles          :%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+  //Measure fixed point arithmetic
+  d2=Sin(1.0)*0x100000000;
+  sum=0;
+  start=GetTSC;
+  for (i=SAMPLE_SIZE-1;i>=0;i--) {
+    tmp=d2*coordinates[i&65535];
+    sum+=tmp.i32[1];
+  }
+  end=GetTSC;
+  test_time=end-start;
+  "Fixed-Point Sum       :%X\n",sum;
+  "$RED$Fixed-Point Cycles    :%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+  //Measure fixed point arithmetic
+  start=GetTSC;
+  sum=AsmFixedPt;
+  end=GetTSC;
+  test_time=end-start;
+  "Asm Fixed-Point Sum   :%X\n",sum;
+  "$RED$Asm Fixed-Point Cycles:%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+  //Measure float arithmetic
+  start=GetTSC;
+  sum=AsmFloat;
+  end=GetTSC;
+  test_time=end-start;
+  "Asm Float Sum         :%X\n",sum;
+  "$RED$Asm Float Cycles      :%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+}
+
+Main;
+
+/*  Program Output
+
+Machine 1:
+8 Cores 2.660GHz
+Overhead Cycles       :   2.00814
+Float Sum             :FFFFE1D361BEED68
+Float Cycles          :  10.16076
+Fixed-Point Sum       :FFFFE1D361729914
+Fixed-Point Cycles    :   5.29392
+Asm Fixed-Point Sum   :FFFFE1D361729914
+Asm Fixed-Point Cycles:   4.20464
+Asm Float Sum         :FFFFE1D361BEED56
+Asm Float Cycles      :   3.04635
+
+Machine 2:
+8 Cores 3.395GHz
+Overhead Cycles       :   4.87040
+Float Sum             :D20A01DB177
+Float Cycles          :  10.11558
+Fixed-Point Sum       :D209FD18CC7
+Fixed-Point Cycles    :   4.50618
+Asm Fixed-Point Sum   :D209FD18CC7
+Asm Fixed-Point Cycles:   3.02426
+Asm Float Sum         :D20A01DB17B
+Asm Float Cycles      :   3.21070
+
+*/
+
+ diff --git a/public/Wb/Demo/Lectures/GraphicsCPULoad.HC.HTML b/public/Wb/Demo/Lectures/GraphicsCPULoad.HC.HTML new file mode 100755 index 0000000..6d4d2ab --- /dev/null +++ b/public/Wb/Demo/Lectures/GraphicsCPULoad.HC.HTML @@ -0,0 +1,65 @@ + + + + + + + + + + + +
+//This is the fastest you can update the whole scrn.
+//See ::/Demo/Lectures/MiniGrLib.HC if this interests you.
+
+F64 VGAPattern(I64 p)
+{//This returns the time to update in seconds.
+  F64 start=tS;
+  I64 plane;
+  for (plane=1;plane<0x10;plane<<=1) {
+    OutU8(VGAP_IDX,VGAR_MAP_MASK);
+    OutU8(VGAP_DATA,plane);
+    MemSetI64(text.vga_alias,p,640*480/64);
+  }
+  return tS-start;
+}
+ 
+ 
+U0 GrDemo()
+{
+  I64 i;
+  F64 t;
+  CPURep;
+  for (i=0;i<16;i++) {
+    t=VGAPattern(0x5555555555555555);
+    "$GREEN$Rate:$RED$%5.1f FPS$FG$"
+          "  $GREEN$Load@30Hz:$RED$%5.1f%%$FG$\n",1/t,100*t*30.0;
+    t=VGAPattern(0x3333333333333333);
+    "$GREEN$Rate:$RED$%5.1f FPS$FG$"
+          "  $GREEN$Load@30Hz:$RED$%5.1f%%$FG$\n",1/t,100*t*30.0;
+  }
+//<CTRL-ALT-v> will flush scrn VGA cache.
+  VGAFlush;
+}
+
+GrDemo;
+
+ diff --git a/public/Wb/Demo/Lectures/InterruptDemo.HC.HTML b/public/Wb/Demo/Lectures/InterruptDemo.HC.HTML new file mode 100755 index 0000000..bcffaf6 --- /dev/null +++ b/public/Wb/Demo/Lectures/InterruptDemo.HC.HTML @@ -0,0 +1,116 @@ + + + + + + + + + + + +
+//This is the software interrupt num
+//we will use.  See Software Int's for
+//picking a num.  Nums are subject to change.
+
+#define I_F_UNARY_MINUS I_USER
+
+asm {
+
+//This changes the sign of the floating
+//point val in RAX
+F_UNARY_MINUS_INT::
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCHS
+        FSTP    U64 [RSP]
+        POP     RAX
+        IRET
+
+//This does the same thing, but not as
+//an interrupt.
+F_UNARY_MINUS_CALL::
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCHS
+        FSTP    U64 [RSP]
+        POP     RAX
+        RET
+
+//This invokes the interrupt version
+//with a C callable function.
+_F_UM_INT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,SF_ARG1[RBP]
+        INT     I_F_UNARY_MINUS
+        POP     RBP
+        RET1    8
+
+//This invokes the call version
+//with a C callable function.
+_F_UM_CALL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,SF_ARG1[RBP]
+        CALL    F_UNARY_MINUS_CALL
+        POP     RBP
+        RET1    8
+}
+
+_extern _F_UM_INT F64 UnaryMinusInt(F64 d);
+_extern _F_UM_CALL F64 UnaryMinusCall(F64 d);
+
+#define SAMPLE_SIZE     1000000
+U0 TimeIns()
+{
+  I64 start,end;
+  I64 i,old_irq;
+
+  CPURep;
+  old_irq=IntEntrySet(I_F_UNARY_MINUS,F_UNARY_MINUS_INT,IDTET_TRAP);
+
+  //Measure interrupt time
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    UnaryMinusInt(pi);
+  end=GetTSC;
+  "Interrupt Cycles: %10.5f\n",ToF64(end-start)/SAMPLE_SIZE;
+
+  //Measure call time
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    UnaryMinusCall(pi);
+  end=GetTSC;
+  "Call      Cycles: %10.5f\n",ToF64(end-start)/SAMPLE_SIZE;
+
+  IntEntrySet(I_F_UNARY_MINUS,old_irq,IDTET_IRQ);
+}
+
+TimeIns;
+
+/*  Program Output
+6 Cores 3.395GHz
+Interrupt Cycles:  573.98543
+Call      Cycles:    9.74349
+*/
+
+ diff --git a/public/Wb/Demo/Lectures/MiniCompiler.HC.HTML b/public/Wb/Demo/Lectures/MiniCompiler.HC.HTML new file mode 100755 index 0000000..cbfb5ce --- /dev/null +++ b/public/Wb/Demo/Lectures/MiniCompiler.HC.HTML @@ -0,0 +1,277 @@ + + + + + + + + + + + +
+/*
+-] Main Compiler
+  The mini compiler is like the main compiler, except the main compiler's 
+  lexical analyser removes comments and does preprocessing.  Lex(),Echo(ON).
+  
+  The main compiler generates Intermediate Code at the parser stage.  See 
+  PrsExpression(), PrsStmt().
+  
+  The main compiler optimizes   See Intermediate Code Attributes, 
+  Combining Consts, Choosing Reg Vars.  Use PassTrace() to see the optimization 
+  stages.
+  
+  The main compiler makes machine code in the back end.  See IC Struct, 
+  COCCompile and OptPass789A(), BackEnd.  Set Trace(ON) to see the output of the 
+  backend.
+
+-] Mini Compiler
+  For this mini compiler, some things you should know about 64-bit asm:
+  
+  * Putting a 0x48, known as the REX byte, in front of an inst makes it 64-bit 
+  size.
+  
+  * "PUSH EAX", "POP EAX" and "XOR EAX,EAX" will behave as 64-bit even without 
+  REX because the stk is always 64 bit and because the XOR clears the upper 
+  32-bits.
+  
+  It is okay in TempleOS to change RAX, RBX, RCX, RDX, R8 and R9 without 
+  restoring them to their original values.
+*/
+
+#define TK_EOF          0
+#define TK_NUM          1
+#define TK_OP           2
+#define TK_LEFT         3
+#define TK_RIGHT        4
+
+#define OP_MUL          1
+#define OP_DIV          2
+#define OP_ADD          3
+#define OP_SUB          4
+
+I64 Lex(U8 **_src,I64 *num)
+{//See Lex().
+  U8 *src=*_src;
+  I64 i;
+  while (TRUE) {
+    switch (*src) {
+      case 0:
+      case ';':
+        *_src=src;
+        return TK_EOF;
+      case CH_SPACE:
+      case '\r':
+      case '\n':
+        src++;
+        break;
+      case '0'...'9':
+        i=0;
+        do {
+          i=i*10+*src-'0';
+          src++;
+        } while ('0'<=*src<='9');
+        *num=i;
+        *_src=src;
+        return TK_NUM;
+      case '*':
+        *num=OP_MUL;
+        *_src=src+1;
+        return TK_OP;
+      case '/':
+        *num=OP_DIV;
+        *_src=src+1;
+        return TK_OP;
+      case '+':
+        *num=OP_ADD;
+        *_src=src+1;
+        return TK_OP;
+      case '-':
+        *num=OP_SUB;
+        *_src=src+1;
+        return TK_OP;
+      case '(':
+        *_src=src+1;
+        return TK_LEFT;
+      case ')':
+        *_src=src+1;
+        return TK_RIGHT;
+      default:
+        throw;
+    }
+  }
+}
+
+#define PREC_EOF        0
+#define PREC_TERM       1
+#define PREC_MUL        2
+#define PREC_ADD        3
+#define PREC_PAREN      4
+
+extern I64 Parse(U8 **_src,U8 **_dst);
+
+U0 PrsTerm(U8 **_src,U8 **_dst,I64 prec)
+{//See PrsExpression().
+  I64 i;
+  U8 *src2;
+  U8 *dst2;
+  if (Parse(_src,_dst)==PREC_TERM) {
+    src2=*_src;
+    dst2=*_dst;
+    while (TRUE) {
+//This is inefficient.  The main compiler doesn't back-up like this.
+      i=Parse(&src2,&dst2);
+      if (PREC_MUL<=i<prec) {
+        *_src=src2;
+        *_dst=dst2;
+      } else
+        break;
+    }
+  } else
+    throw;
+}
+
+I64 Parse(U8 **_src,U8 **_dst)
+{//See PrsExpression().
+//See Opcode Fmts for details on asm insts.
+  I64 i;
+  U8 *dst=*_dst;
+  switch (Lex(_src,&i)) {
+    case TK_EOF:
+      *dst++=0x58; //POP RAX
+      *dst++=0xC3; //RET
+      *_dst=dst;
+      return PREC_EOF;
+    case TK_NUM:
+      *dst++=0x48; //REX
+      *dst++=0xB8; //MOV RAX,immediate num
+      *dst(I64 *)++=i;
+
+      *dst++=0x50; //PUSH RAX
+      *_dst=dst;
+      return PREC_TERM;
+    case TK_LEFT:
+      PrsTerm(_src,_dst,PREC_PAREN);
+      if (Parse(_src,_dst)!=PREC_PAREN)
+        throw;
+      return PREC_TERM;
+    case TK_RIGHT:
+      return PREC_PAREN;
+    case TK_OP:
+      switch (i) {
+        case OP_MUL:
+          PrsTerm(_src,&dst,PREC_MUL);
+          *dst++=0x5A; //POP RDX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x48; //REX
+          *dst++=0x0F;
+          *dst++=0xAF; //IMUL RAX,RDX
+          *dst++=0xC2;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_MUL;
+        case OP_DIV:
+          PrsTerm(_src,&dst,PREC_MUL);
+          *dst++=0x5B; //POP RBX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x33; //XOR RDX,RDX
+          *dst++=0xD2;
+
+          *dst++=0x48; //REX
+          *dst++=0xF7; //IDIV RBX
+          *dst++=0xFB;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_MUL;
+        case OP_ADD:
+          PrsTerm(_src,&dst,PREC_ADD);
+          *dst++=0x5A; //POP RDX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x48; //REX
+          *dst++=0x03; //ADD RAX,RDX
+          *dst++=0xC2;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_ADD;
+        case OP_SUB:
+          PrsTerm(_src,&dst,PREC_ADD);
+          *dst++=0x5A; //POP RDX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x48; //REX
+          *dst++=0x2B; //SUB RAX,RDX
+          *dst++=0xC2;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_ADD;
+      }
+  }
+}
+
+U0 Main()
+{
+  U8 *src,*src2,*code,*dst;
+
+  //Fixed size, no buffer overrun check.
+  //You can make it fancier if you like.
+  code=MAlloc(512,Fs->code_heap);
+
+  while (TRUE) {
+    "This will compile an expression\n"
+          "consisting of ints, parentheses\n"
+          "and the operators +,-,* and /.\n";
+    src=GetStr;
+    if (*src) {
+      src2=src;
+      dst=code;
+      try {
+        PrsTerm(&src2,&dst,PREC_PAREN);
+        if (Parse(&src2,&dst)!=PREC_EOF)
+          throw;
+        "$RED$This code is not efficient, but the compiler is simple.$FG$\n";
+        Un(code,dst-code); //Unassemble the code we created.
+//Call() is a function.  See _CALL::
+        //See also CallInd().  See _CALL_IND::
+        "$LTBLUE$Answer:%d$FG$\n",Call(code);
+      } catch {
+        "$RED$Error$FG$\n";
+        PutExcept;
+      }
+      Free(src);
+    } else {
+      Free(src);
+      break;
+    }
+  }
+  Free(code);
+}
+
+Main;
+
+
+ diff --git a/public/Wb/Demo/Lectures/MiniGrLib.HC.HTML b/public/Wb/Demo/Lectures/MiniGrLib.HC.HTML new file mode 100755 index 0000000..d9ed957 --- /dev/null +++ b/public/Wb/Demo/Lectures/MiniGrLib.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+//See ::/Demo/Lectures/GraphicsCPULoad.HC
+U8 rev[256],    //The VGA bits are bwd
+
+   image[640*480/8];    //We need read-modify write.
+                        //0xA0000 alias memory can't be read.
+ 
+U0 MGInit()
+{
+  I64 i,j;
+  MemSet(image,0,sizeof(image));
+  MemSet(rev,0,sizeof(rev));
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++)
+      if (Bt(&i,j))
+        Bts(&rev[i],7-j);
+}
+ 
+U0 MGUpdate()
+{//Copy image to VGA memory
+//For better performance we could only write what's changed.
+  //0xA0000 alias is slower than normal RAM.
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,0xF);//All color planes at once -- Black and White
+  MemCpy(text.vga_alias,image,sizeof(image)); //Alias of 0xA0000
+}
+ 
+U0 MGPlot(I64 x,I64 y)
+{
+  if (0<=x<640 && 0<=y<480)
+    Bts(image,y*640+x^7);
+}
+ 
+U0 MGHLine(I64 x1,I64 x2,I64 y)
+{//Warning!  No clipping
+//For performance, we do as many whole-bytes as possible.
+  U8 *ptr;
+  I64 i,w,leading,trailing,whole_bytes;
+  if (x2<x1) SwapI64(&x1,&x2);
+  ptr=image+y*640/8+x1>>3;
+  w=x2-x1+1;
+  leading =8-x1&7;
+  trailing=(x2+1)&7;
+  if (leading+trailing>w)
+    *ptr|=rev[(0xFF00>>leading&(0x00FF<<trailing)>>8)];
+  else {
+    whole_bytes=(w-leading-trailing)>>3;
+    if (leading)
+      *ptr++|=rev[(0xFF00>>leading)&0xFF];
+    for (i=0;i<whole_bytes;i++)
+      *ptr++=0xFF;
+    if (trailing)
+      *ptr++|=rev[(0x00FF<<trailing)>>8];
+  }
+}
+ 
+U0 MGLine(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Warning!  No clipping
+  I64 dx=x2-x1,dy=y2-y1;
+  x1<<=32; x2<<=32;
+  y1<<=32; y2<<=32;
+  if (AbsI64(dx)>AbsI64(dy)) {
+    dy=dy<<32/AbsI64(dx);
+    dx=SignI64(dx)<<32;
+    while (x1!=x2) {
+      MGPlot(x1.i32[1],y1.i32[1]);
+      x1+=dx; y1+=dy;
+    }
+  } else {
+    dx=dx<<32/AbsI64(dy);
+    dy=SignI64(dy)<<32;
+    while (y1!=y2) {
+      MGPlot(x1.i32[1],y1.i32[1]);
+      x1+=dx; y1+=dy;
+    }
+  }
+  MGPlot(x1.i32[1],y1.i32[1]);
+}
+ 
+U0 MGCircle(I64 x,I64 y,F64 r)
+{
+  F64 s,c,x1,y1,x2,y2;
+  I64 len;
+  if (r<0) return;
+  x1=r; y1=0;
+  c=Cos(1/r);
+  s=Sin(1/r);
+  len=2*r*pi;
+  MGPlot(x+x1,y+y1);
+  while (len-->=0) {
+
+    //m1@a1 * m2@a2     = m1*m2@(arg1+arg2)
+
+    //(x1+y1i)*(x2+y2i) = x1*x2+(x1*y1+x2*y2)i-y1*y2
+
+    // meti=mCos(t)+imSin(t)
+
+    x2=x1; y2=y1;
+    x1=c*x2-s*y2;
+    y1=s*x2+c*y2;
+    MGPlot(x+x1,y+y1);
+  }
+}
+ 
+ 
+U0 MiniGrLibDemo()
+{
+  I64 i;
+  MGInit;
+
+  for (i=0;i<100;i++)
+    MGHLine(200+i,400+i,300+i);
+  for (i=0;i<500;i+=10)
+    MGLine(i,0,0,480-i);
+  for (i=0;i<300;i+=4)
+    MGCircle(200,100+i,i);
+  MGUpdate;
+  Busy(1500000);
+/*
+We are returning graphics to normal operations under TempleOS.
+It is not normal to by-pass the TempleOS graphcis routines.
+The TempleOS graphics don't know VGA has changed.
+This bit tells TempleOS to update whole scrn.
+*/
+  //<CTRL-ALT-v> will flush scrn VGA cache.
+  VGAFlush;
+}
+ 
+MiniGrLibDemo;
+
+//See RawPutChar() for text.
+//See ::/Demo/Lectures/ScrnMemory.HC for color.
+//See ::/Demo/Lectures/GraphicsCPULoad.HC.
+
+ diff --git a/public/Wb/Demo/Lectures/NegDisp.HC.HTML b/public/Wb/Demo/Lectures/NegDisp.HC.HTML new file mode 100755 index 0000000..8d101b6 --- /dev/null +++ b/public/Wb/Demo/Lectures/NegDisp.HC.HTML @@ -0,0 +1,87 @@ + + + + + + + + + + + +
+class Person
+{
+  U8 first    [32];
+  U8 last     [32];
+  U8 address1 [64];
+  U8 address2 [64];
+  U8 city     [32];
+  U8 state_zip[32];
+};
+
+U0 OffsetDemo1()
+{
+  Person *p=MAlloc(sizeof(Person));
+  StrCpy(p->first,    "Terry");
+  StrCpy(p->last,     "Davis");
+  StrCpy(p->address1, "8144 Sickle Lane");
+  StrCpy(p->address2, "");
+  StrCpy(p->city,     "Las Vegas");
+  StrCpy(p->state_zip,"NV 89128");
+}
+
+U(&OffsetDemo1,34);
+PressAKey;
+
+/*
+
+x86 has signed 8-bit  displacements
+    and signed 32-bit displacements.
+
+This example uses 8-bit negative displacements.
+
+*/
+
+class Person
+{ $=-128;
+U8 first    [32];
+U8 last     [32];
+U8 address1 [64];
+U8 address2 [64];
+U8 city     [32];
+U8 state_zip[32];
+};
+
+U0 OffsetDemo2()
+{
+  Person *p=MAlloc(sizeof(Person))(I64)+128;
+  StrCpy(p->first,    "Terry");
+  StrCpy(p->last,     "Davis");
+  StrCpy(p->address1, "8144 Sickle Lane");
+  StrCpy(p->address2, "");
+  StrCpy(p->city,     "Las Vegas");
+  StrCpy(p->state_zip,"NV 89128");
+}
+
+U(&OffsetDemo2,34);
+PressAKey;
+
+ diff --git a/public/Wb/Demo/Lectures/Optimization.HC.HTML b/public/Wb/Demo/Lectures/Optimization.HC.HTML new file mode 100755 index 0000000..8a6e793 --- /dev/null +++ b/public/Wb/Demo/Lectures/Optimization.HC.HTML @@ -0,0 +1,139 @@ + + + + + + + + + + + +
+/*The moral of this story is simple
+inst level optimizations
+don't matter much on a modern Intel CPU
+because they convert complex insts
+to a stream of RISC insts.
+
+I learned this the hard way when I thought
+I was greatly improving my compiler by
+cutting code by a third.  No significant
+speed-up.  Depressing.
+*/
+
+#define SAMPLES (8*10000000+1)
+
+asm {
+
+LIMIT:: DU64    SAMPLES;        //Memory reference should be bad, right?
+
+_BADLY_UNOPTIMIZED::
+        MOV     RAX,0
+        MOV     RCX,1
+@@05:   MOV     RDX,RCX
+        INC     RCX             //if no dependencies, Free!
+        ADD     RAX,RDX
+        MOV     RDX,LIMIT-16    //added 16 displacement to make it worse
+        CMP     RCX,U64 16[RDX]
+        JB      @@05
+        RET
+
+_WELL_OPTIMIZED1::
+        XOR     RAX,RAX
+        MOV     RCX,SAMPLES-1
+@@05:   ADD     RAX,RCX
+        DEC     RCX
+        JNZ     @@05
+        RET
+
+_WELL_OPTIMIZED2:: //Unrolled
+        XOR     RAX,RAX
+        MOV     RCX,SAMPLES-1
+@@05:   ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        JNZ     @@05
+        RET
+
+_WELL_OPTIMIZED3::
+        XOR     RAX,RAX
+        MOV     RCX,SAMPLES-1
+@@05:   ADD     RAX,RCX
+        LOOP    @@05    //Inst has slow speed, but saves code size.
+        RET
+}
+
+_extern _BADLY_UNOPTIMIZED I64 Loop1();
+_extern _WELL_OPTIMIZED1   I64 Loop2();
+_extern _WELL_OPTIMIZED2   I64 Loop3();
+_extern _WELL_OPTIMIZED3   I64 Loop4();
+
+I64 i;
+F64 t0;
+
+CPURep;
+
+"Bad Code\n";
+t0=tS;
+i=Loop1;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+"Good Code #1\n";
+t0=tS;
+i=Loop2;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+"Good Code #2\n";
+t0=tS;
+i=Loop3;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+"Good Code #3\n";
+t0=tS;
+i=Loop4;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+/*  Program Output
+8 Cores 2.660GHz
+Bad Code
+Res:3200000040000000 Time: 0.069966
+Good Code #1
+Res:3200000040000000 Time: 0.062567
+Good Code #2
+Res:3200000040000000 Time: 0.062907
+Good Code #3
+Res:3200000040000000 Time: 0.156359
+*/
+
+ diff --git a/public/Wb/Demo/Lectures/PCIInterrupts.HC.HTML b/public/Wb/Demo/Lectures/PCIInterrupts.HC.HTML new file mode 100755 index 0000000..35ba6cb --- /dev/null +++ b/public/Wb/Demo/Lectures/PCIInterrupts.HC.HTML @@ -0,0 +1,104 @@ + + + + + + + + + + + +
+//See PCI.
+
+#if mp_cnt>1
+#define DEST_CPU        1
+#else
+#define DEST_CPU        0
+#endif
+
+#assert I_USER==0x40
+
+interrupt U0 IntMy40()
+{
+  lock {progress1++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntMy41()
+{
+  lock {progress2++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntMy42()
+{
+  lock {progress3++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntMy43()
+{
+  lock {progress4++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+I64 vect[4]={&IntMy40,&IntMy41,&IntMy42,&IntMy43};
+
+U0 Main()
+{
+  I64 i;
+  U8 *da=dev.uncached_alias+IOAPIC_REG;
+  U32 *_d=dev.uncached_alias+IOAPIC_DATA;
+
+  ProgressBarsRst;
+  for (i=I_USER;i<I_USER+4;i++)
+    IntEntrySet(i,vect[i&3],IDTET_IRQ);
+
+    //There are like 4*6 vects.  Bus zero
+    //has the first four vects.
+  for (i=IOREDTAB;i<IOREDTAB+4*2;i+=2) {
+    *da=i+1;
+    *_d=dev.mp_apic_ids[DEST_CPU]<<24;
+    *da=i;
+    *_d=0x4000+0x40+(i-IOREDTAB)/2;
+  }
+
+  Sleep(1000);
+  "The keyboard and timer seem to be active.\n"
+        "IntA:%d IntB:%d IntC:%d IntD:%d\n\n"
+        "IntB is my keybaord and regs a single KEY-UP.\n"
+        "Rerun and press a few keys.\n",
+        progress1,progress2,progress3,progress4;
+
+  //Disable vects
+  for (i=IOREDTAB;i<IOREDTAB+4*2;i+=2) {
+    *da=i+1;
+    *_d=dev.mp_apic_ids[DEST_CPU]<<24;
+    *da=i;
+    *_d=0x14000+0x40+(i-IOREDTAB)/2;
+  }
+  ProgressBarsRst;
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Lectures/Ring3.HC.HTML b/public/Wb/Demo/Lectures/Ring3.HC.HTML new file mode 100755 index 0000000..b3b811f --- /dev/null +++ b/public/Wb/Demo/Lectures/Ring3.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+/*TempleOS runs exclusively in ring 0.
+Ring 0 is part of the Charter.
+This demo is for you to play around
+with ring 3.  TempleOS is for
+recreational programming, after all.
+
+This redirects the general protection
+fault, switches to ring 3, and generates
+a fault to switch back.
+*/
+
+U8 *old_stk,*new_rip;
+
+asm {
+INT_TO_RING0::  //Set to handle general protection 0xD fault temporarily.
+        INC     U64 [SYS_PROGRESS1]
+        PUSH    U32 CGDT.ds     //STKSEG
+        MOV     RAX,U64 [&old_stk]
+        PUSH    RAX
+        PUSH    U32 0           //FLAGS--interrupts off
+        PUSH    U32 CGDT.cs64
+        MOV     RAX,U64 [&new_rip]
+        PUSH    RAX
+        IRET
+}
+
+U0 Ring3Demo()
+{
+  U8 *old_vect;
+  "Progress1 Before:%X\n",progress1;
+  CLI
+  old_vect=IntEntrySet(0x0D,INT_TO_RING0,IDTET_TRAP,0);
+
+  TSSBusy(Gs->tss->tr_ring3,OFF);
+  SetRAX(Gs->tss->tr_ring3+3);
+  LTR   AX
+
+  asm {
+    MOV U64 [&old_stk],RSP
+
+    LEA RAX,[R3_CALLBACK]
+    MOV U64 [&new_rip],RAX
+
+    MOV AX,CGDT.ds_ring3+3
+    MOV DS,AX
+    MOV ES,AX
+
+    PUSH        U32 CGDT.ds_ring3+3     //STKSEG
+    PUSH        U64 [&old_stk]
+    PUSH        U32 0           //FLAGS--interrupts off
+    PUSH        U32 CGDT.cs64_ring3+3
+    LEA RAX,[R3_START]
+    PUSH        RAX
+    IRET
+
+    R3_START:
+    INC U64 [SYS_PROGRESS1]
+    CLI //This causes general protection fault #13
+
+    R3_CALLBACK:
+    MOV AX,CGDT.ds
+    MOV DS,AX
+    MOV ES,AX
+  }
+
+  TSSBusy(Gs->tss->tr,OFF);
+  SetRAX(Gs->tss->tr);
+  LTR   AX
+
+  IntEntrySet(0x0D,old_vect,IDTET_IRQ,0);
+  STI
+  "Progress1 After :%X\n",progress1;
+}
+
+Ring3Demo;
+
+ diff --git a/public/Wb/Demo/Lectures/ScrnMemory.HC.HTML b/public/Wb/Demo/Lectures/ScrnMemory.HC.HTML new file mode 100755 index 0000000..c30003a --- /dev/null +++ b/public/Wb/Demo/Lectures/ScrnMemory.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+//This just shows how scrn memory works.
+//See ::/Demo/Lectures/MiniGrLib.HC
+
+U0 PlotXY(I64 x,I64 y)
+{
+//Scrn bits are revd
+  LBts(text.vga_alias,y*GR_WIDTH+x^7);
+}
+
+U0 Main()
+{
+  I64 i;
+  //This makes all 4 color planes active.
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,WHITE);
+  MemSet(text.vga_alias,0,GR_WIDTH*GR_HEIGHT/8);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,RED);
+  for (i=0;i<200;i++)
+    PlotXY(i,i);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,GREEN);
+  for (i=0;i<200;i++)
+    PlotXY(100,i);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,BLUE);
+  for (i=0;i<200;i++)
+    PlotXY(200-i,i);
+/*If you want a mixed color sel multiple planes
+but you have to be sure the unseled planes
+are zero, so sel them and make them zero.
+You can't do reads on VGA memory, by the way.
+That means no read-modify-writes, too.
+*/
+  Busy(4000000);
+
+  //TempleOS has a 4 plane memory duplicate of the scrn, gr.scrn_image,
+  //and only writes actual changes.  See GrUpdateVGAGraphics().
+  //<CTRL-ALT-v> will flush scrn VGA cache.
+  VGAFlush;
+}
+
+Main;
+
+//See ::/Demo/Lectures/GraphicsCPULoad.HC.
+
+
+ diff --git a/public/Wb/Demo/MagicPairs.HC.HTML b/public/Wb/Demo/MagicPairs.HC.HTML new file mode 100755 index 0000000..354459b --- /dev/null +++ b/public/Wb/Demo/MagicPairs.HC.HTML @@ -0,0 +1,406 @@ + + + + + + + + + + + +
+/*The magic pairs problem:
+
+Let SumFact(n) be the sum of factors
+of n.
+
+Find all n1,n2 in a range such that
+
+SumFact(n1)-n1-1==n2  and
+SumFact(n2)-n2-1==n1
+
+-----------------------------------------------------
+To find SumFact(k), start with prime factorization:
+
+k=(p1^n1)(p2^n2) ... (pN^nN)
+
+THEN,
+
+SumFact(k)=(1+p1+p1^2...p1^n1)*(1+p2+p2^2...p2^n2)*
+(1+pN+pN^2...pN^nN)
+
+PROOF:
+
+Do a couple examples -- it's obvious:
+
+48=2^4*3
+
+SumFact(48)=(1+2+4+8+16)*(1+3)=1+2+4+8+16+3+6+12+24+48
+
+75=3*5^2
+
+SumFact(75)=(1+3)*(1+5+25)    =1+5+25+3+15+75
+
+Corollary:
+
+SumFact(k)=SumFact(p1^n1)*SumFact(p2^n2)*...*SumFact(pN^nN)
+
+*/
+
+//Primes are needed to sqrt(N).  Therefore, we can use U32.
+class PowPrime
+{
+  I64 n;
+  I64 sumfact; //Sumfacts for powers of primes are needed beyond sqrt(N)
+};
+
+class Prime
+{
+  U32 prime,pow_cnt;
+  PowPrime *pp;
+};
+
+I64 *PrimesNew(I64 N,I64 *_sqrt_primes,I64 *_cbrt_primes)
+{
+  I64 i,j,sqrt=Ceil(Sqrt(N)),cbrt=Ceil(N`(1/3.0)),sqrt_sqrt=Ceil(Sqrt(sqrt)),
+        sqrt_primes=0,cbrt_primes=0;
+  U8 *s=CAlloc((sqrt+1+7)/8);
+  Prime *primes,*p;
+
+  for (i=2;i<=sqrt_sqrt;i++) {
+    if (!Bt(s,i)) {
+      j=i*2;
+      while (j<=sqrt) {
+        Bts(s,j);
+        j+=i;
+      }
+    }
+  }
+  for (i=2;i<=sqrt;i++)
+    if (!Bt(s,i)) {
+      sqrt_primes++; //Count primes
+      if (i<=cbrt)
+        cbrt_primes++;
+    }
+
+  p=primes=CAlloc(sqrt_primes*sizeof(Prime));
+  for (i=2;i<=sqrt;i++)
+    if (!Bt(s,i)) {
+      p->prime=i;
+      p++;
+    }
+  Free(s);
+
+  *_sqrt_primes=sqrt_primes;
+  *_cbrt_primes=cbrt_primes;
+  return primes;
+}
+
+PowPrime *PowPrimesNew(I64 N,I64 sqrt_primes,Prime *primes,I64 *_num_powprimes)
+{
+  I64 i,j,k,sf,num_powprimes=0;
+  Prime *p;
+  PowPrime *powprimes,*pp;
+
+  p=primes;
+  for (i=0;i<sqrt_primes;i++) {
+    num_powprimes+=Floor(Ln(N)/Ln(p->prime));
+    p++;
+  }
+
+  p=primes;
+  pp=powprimes=MAlloc(num_powprimes*sizeof(PowPrime));
+  for (i=0;i<sqrt_primes;i++) {
+    p->pp=pp;
+    j=p->prime;
+    k=1;
+    sf=1;
+    while (j<N) {
+      sf+=j;
+      pp->n=j;
+      pp->sumfact=sf;
+      j*=p->prime;
+      pp++;
+      p->pow_cnt++;
+    }
+    p++;
+  }
+  *_num_powprimes=num_powprimes;
+  return powprimes;
+}
+
+I64 SumFact(I64 n,I64 sqrt_primes,Prime *p)
+{
+  I64 i,k,sf=1;
+  PowPrime *pp;
+  if (n<2)
+    return 1;
+  for (i=0;i<sqrt_primes;i++) {
+    k=0;
+    while (!(n%p->prime)) {
+      n/=p->prime;
+      k++;
+    }
+    if (k) {
+      pp=p->pp+(k-1);
+      sf*=pp->sumfact;
+      if (n==1)
+        return sf;
+    }
+    p++;
+  }
+  return sf*(1+n); //Prime
+}
+
+Bool TestSumFact(I64 n,I64 target_sf,I64 sqrt_primes,I64 cbrt_primes,Prime *p)
+{
+  I64 i=0,k,b,x1,x2;
+  PowPrime *pp;
+  F64 disc;
+  if (n<2)
+    return FALSE;
+  while (i++<cbrt_primes) {
+    k=0;
+    while (!(n%p->prime)) {
+      n/=p->prime;
+      k++;
+    }
+    if (k) {
+      pp=p->pp+(k-1);
+      if (ModU64(&target_sf,pp->sumfact))
+        return FALSE;
+      if (n==1) {
+        if (target_sf==1)
+          return TRUE;
+        else
+          return FALSE;
+      }
+    }
+    p++;
+  }
+/*  At this point we have three possible cases to test
+1)n==p1         ->sf==(1+p1)        ?
+2)n==p1*p1      ->sf==(1+p1+p1^2)   ?
+3)n==p1*p2      ->sf==(p1+1)*(p2+1) ?
+
+*/
+  if (1+n==target_sf) {
+    while (i++<sqrt_primes) {
+      k=0;
+      while (!(n%p->prime)) {
+        n/=p->prime;
+        k++;
+      }
+      if (k) {
+        pp=p->pp+(k-1);
+        if (ModU64(&target_sf,pp->sumfact))
+          return FALSE;
+        if (n==1) {
+          if (target_sf==1)
+            return TRUE;
+          else
+            return FALSE;
+        }
+      }
+      p++;
+    }
+    if (1+n==target_sf)
+      return TRUE;
+    else
+      return FALSE;
+  }
+
+  k=Sqrt(n);
+  if (k*k==n) {
+    if (1+k+n==target_sf)
+      return TRUE;
+    else
+      return FALSE;
+  } else {
+// n==p1*p2 -> sf==(p1+1)*(p2+1) ?  where p1!=1 && p2!=1
+    // if p1==1 || p2==1, it is FALSE because we checked a single prime above.
+
+    // sf==(p1+1)*(n/p1+1)
+    // sf==n+p1+n/p1+1
+    // sf*p1==n*p1+p1^2+n+p1
+    // p1^2+(n+1-sf)*p1+n=0
+    // x=(-b+/-sqrt(b^2-4ac))/2a
+    // a=1
+    // x=(-b+/-sqrt(b^2-4c))/2
+    // b=n+1-sf;c=n
+    b=n+1-target_sf;
+// x=(-b+/-sqrt(b^2-4n))/2
+    disc=b*b-4*n;
+    if (disc<0)
+      return FALSE;
+    x1=(-b-Sqrt(disc))/2;
+    if (x1<=1)
+      return FALSE;
+    x2=n/x1;
+    if (x2>1 && x1*x2==n)
+      return TRUE;
+    else
+      return FALSE;
+  }
+}
+
+U0 PutFactors(I64 n) //For debugging
+{
+  I64 i,k,sqrt=Ceil(Sqrt(n));
+  for (i=2;i<=sqrt;i++) {
+    k=0;
+    while (!(n%i)) {
+      k++;
+      n/=i;
+    }
+    if (k) {
+      "%d",i;
+      if (k>1)
+        "^%d",k;
+      '' CH_SPACE;
+    }
+  }
+  if (n!=1)
+    "%d ",n;
+}
+
+class RangeJob
+{
+  CDoc *doc;
+  I64 num,lo,hi,N,sqrt_primes,cbrt_primes;
+  Prime *primes;
+  CJob *cmd;
+} rj[mp_cnt];
+
+I64 TestCoreSubRange(RangeJob *r)
+{
+  I64 i,j,m,n,n2,sf,res=0,range=r->hi-r->lo,
+        *sumfacts=MAlloc(range*sizeof(I64)),
+        *residue =MAlloc(range*sizeof(I64));
+  U16 *pow_cnt =MAlloc(range*sizeof(U16));
+  Prime *p=r->primes;
+  PowPrime *pp;
+  MemSetI64(sumfacts,1,range);
+  for (n=r->lo;n<r->hi;n++)
+    residue[n-r->lo]=n;
+  for (j=0;j<r->sqrt_primes;j++) {
+    MemSet(pow_cnt,0,range*sizeof(U16));
+    m=1;
+    for (i=0;i<p->pow_cnt;i++) {
+      m*=p->prime;
+      n=m-r->lo%m;
+      while (n<range) {
+        pow_cnt[n]++;
+        n+=m;
+      }
+    }
+    for (n=0;n<range;n++)
+      if (i=pow_cnt[n]) {
+        pp=&p->pp[i-1];
+        sumfacts[n]*=pp->sumfact;
+        residue [n]/=pp->n;
+      }
+    p++;
+  }
+
+  for (n=0;n<range;n++)
+    if (residue[n]!=1)
+      sumfacts[n]*=1+residue[n];
+
+  for (n=r->lo;n<r->hi;n++) {
+    sf=sumfacts[n-r->lo];
+    n2=sf-n-1;
+    if (n<n2<r->N) {
+      if (r->lo<=n2<r->hi && sumfacts[n2-r->lo]-n2-1==n ||
+            TestSumFact(n2,sf,r->sqrt_primes,r->cbrt_primes,r->primes)) {
+        DocPrint(r->doc,"%u:%u\n",n,sf-n-1);
+        res++;
+      }
+    }
+  }
+  Free(pow_cnt);
+  Free(residue);
+  Free(sumfacts);
+  return res;
+}
+
+#define CORE_SUB_RANGE  0x1000
+
+I64 TestCoreRange(RangeJob *r)
+{
+  I64 i,n,res=0;
+  RangeJob rj;
+  MemCpy(&rj,r,sizeof(RangeJob));
+  for (i=r->lo;i<r->hi;i+=CORE_SUB_RANGE) {
+    rj.lo=i;
+    rj.hi=i+CORE_SUB_RANGE;
+    if (rj.hi>r->hi)
+      rj.hi=r->hi;
+    res+=TestCoreSubRange(&rj);
+
+    n=rj.hi-rj.lo;
+    lock {progress1+=n;}
+
+    Yield;
+  }
+  return res;
+}
+
+I64 MagicPairs(I64 N)
+{
+  F64 t0=tS;
+  I64 res=0;
+  I64 sqrt_primes,cbrt_primes,num_powprimes,
+        i,k,n=(N-1)/mp_cnt+1;
+  Prime *primes=PrimesNew(N,&sqrt_primes,&cbrt_primes);
+  PowPrime *powprimes=PowPrimesNew(N,sqrt_primes,primes,&num_powprimes);
+
+  "N:%u SqrtPrimes:%u CbrtPrimes:%u PowersOfPrimes:%u\n",
+        N,sqrt_primes,cbrt_primes,num_powprimes;
+  progress1=0;
+  *progress1_desc=0;
+  progress1_max=N;
+  k=2;
+  for (i=0;i<mp_cnt;i++) {
+    rj[i].doc=DocPut;
+    rj[i].num=i;
+    rj[i].lo=k;
+    k+=n;
+    if (k>N) k=N;
+    rj[i].hi=k;
+    rj[i].N=N;
+    rj[i].sqrt_primes=sqrt_primes;
+    rj[i].cbrt_primes=cbrt_primes;
+    rj[i].primes=primes;
+    rj[i].cmd=JobQue(&TestCoreRange,&rj[i],mp_cnt-1-i,0);
+  }
+  for (i=0;i<mp_cnt;i++)
+    res+=JobResGet(rj[i].cmd);
+  Free(powprimes);
+  Free(primes);
+  "Found:%u Time:%9.4f\n",res,tS-t0;
+  progress1=progress1_max=0;
+  return res;
+}
+
+MagicPairs(1000000);
+
+ diff --git a/public/Wb/Demo/MemDemo.HC.HTML b/public/Wb/Demo/MemDemo.HC.HTML new file mode 100755 index 0000000..89f155a --- /dev/null +++ b/public/Wb/Demo/MemDemo.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+U0 MemDemo()
+{
+  I64 i;
+"$HL,1$$BLACK$
+#define MEM_PAG_BITS            9
+#define MEM_PAG_SIZE            (1<<MEM_PAG_BITS)
+#define MEM_HEAP_HASH_SIZE      1024
+#define MEM_FREE_PAG_HASH_SIZE  0x100
+#define MEM_EXTRA_HASH2_PAGS    2
+
+public class CBlkPool
+{
+  CMemBlk *free_pag_hash[MEM_FREE_PAG_HASH_SIZE],
+          *free_pag_hash2[64-MEM_PAG_BITS];
+};
+
+public class CHeapCtrl
+{
+  CBlkPool *bp;
+  CMemUnused *heap_hash[MEM_HEAP_HASH_SIZE/sizeof(U8 *)];
+};
+
+public class CTask //The Fs segment reg points to current CTask.
+{
+  CHeapCtrl *code_heap,*data_heap;
+};
+$HL,0$$FG$
+
+";
+
+
+  "$PURPLE$Chunks in increments of 8 bytes, owned by the task.$FG$\n";
+  for (i=sizeof(CMemUnused);i<MEM_HEAP_HASH_SIZE;i+=8)
+    if (i==0x48)
+      "...\n";
+    else if (!(0x48<i<0x3C8))
+      "Fs->data_heap->heap_hash[%X/8]"
+          "$BLACK$ -->$FG$[X]$BLACK$ -->$FG$[X]$BLACK$ -->$FG$\n",i;
+  "\n\n";
+
+  "$PURPLE$Pages of 512 bytes, owned by the system.$FG$\n";
+  for (i=MEM_HEAP_HASH_SIZE;i<MEM_FREE_PAG_HASH_SIZE*MEM_PAG_SIZE;
+        i+=MEM_PAG_SIZE)
+    if (i==0x1200)
+      "...\n";
+    else if (!(0x1200<i<0x1F200))
+      "Fs->data_heap->bp->free_pag_hash[%X/512]"
+          "$BLACK$ -->$FG$[X]$BLACK$ -->$FG$[X]$BLACK$ -->$FG$\n",i;
+  "\n\n";
+
+  "$PURPLE$Powers of two, owned by the system.$FG$\n";
+  for (i=Bsf(MEM_FREE_PAG_HASH_SIZE*MEM_PAG_SIZE);i<64;i++)
+    if (i==0x1A)
+      "...\n";
+    else if (!(0x1A<=i<=0x36))
+      "Fs->data_heap->bp->free_pag_hash2[%X] %016X"
+          "$BLACK$ -->$FG$[X]$BLACK$ -->$FG$[X]$BLACK$ -->$FG$\n",i,
+          1<<i+MEM_EXTRA_HASH2_PAGS*MEM_PAG_SIZE;
+  "\n\n";
+}
+
+MemDemo;
+
+
+
+ diff --git a/public/Wb/Demo/MsgLoop.HC.HTML b/public/Wb/Demo/MsgLoop.HC.HTML new file mode 100755 index 0000000..764d3ea --- /dev/null +++ b/public/Wb/Demo/MsgLoop.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+U0 MsgLoop()
+{
+  I64 arg1,arg2,msg_code;
+  "Use msg_code defines in your programs instead of hardcoded nums.\n"
+        "<ESC> to Exit\n";
+
+  //We don't want the mouse bttns to reposition the cursor,
+  //so we inhibit the window mgr from processing them.
+
+  Fs->win_inhibit=WIF_SELF_MS_L|WIF_SELF_MS_R;
+
+  do {
+    msg_code=GetMsg(&arg1,&arg2,~(1<<MSG_NULL));
+    "CMD:%02X ARG1:%08X ARG2:%016X\n",msg_code,arg1,arg2;
+  } while (msg_code!=MSG_KEY_DOWN || arg1!=CH_ESC && arg1!=CH_SHIFT_ESC);
+  GetMsg(,,1<<MSG_KEY_UP);
+
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+}
+
+MsgLoop;
+
+// Press <CTRL-SHIFT-L> and "Insert ASCII/ScanCode".
+
+ diff --git a/public/Wb/Demo/MultiCore/Interrupts.HC.HTML b/public/Wb/Demo/MultiCore/Interrupts.HC.HTML new file mode 100755 index 0000000..18f5570 --- /dev/null +++ b/public/Wb/Demo/MultiCore/Interrupts.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+interrupt U0 IntBeepOn()
+{
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0; //signal end of interrupt
+  Snd(34);
+}
+
+interrupt U0 IntBeepOff()
+{
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+  Snd;
+}
+
+U0 IntTest()
+{//Modify interrupt descriptor table use by all cores.
+  IntEntrySet(I_USER,&IntBeepOn,IDTET_TRAP);
+  IntEntrySet(I_USER+1,&IntBeepOff,IDTET_TRAP);
+//Issue interupt to core1
+  MPInt(I_USER,1);
+  Sleep(1000);
+  MPInt(I_USER+1,1);
+}
+
+IntTest;
+
+ diff --git a/public/Wb/Demo/MultiCore/LoadTest.HC.HTML b/public/Wb/Demo/MultiCore/LoadTest.HC.HTML new file mode 100755 index 0000000..bb7211d --- /dev/null +++ b/public/Wb/Demo/MultiCore/LoadTest.HC.HTML @@ -0,0 +1,79 @@ + + + + + + + + + + + +
+Bool app_done;
+I64 app_done_ack;
+
+U0 Job1(I64)
+{//Compile Compiler
+  Silent;
+  while (!app_done) {
+    Cd("::/Compiler");
+    Cmp("Compiler");
+  }
+  lock {app_done_ack--;}
+}
+
+U0 Job2(I64)
+{//Log a file
+  while (!app_done) {
+    AdamLog("%F","::/Demo/MultiCore/LoadTest.HC");
+    Yield;
+  }
+  lock {app_done_ack--;}
+}
+
+U0 Job3(I64)
+{//Log a file
+  while (!app_done) {
+    Cd("::/Compiler");
+    AdamLog("%F","Compiler.PRJ.Z");
+    Yield;
+  }
+  lock {app_done_ack--;}
+}
+
+U0 Main()
+{
+  app_done=FALSE;
+  "Running MultiCore Test...\n";
+  Spawn(&Job1,,,1); //core #1
+  Spawn(&Job2,,,1);
+  Spawn(&Job3,,,1);
+  PressAKey;
+//We don't want to yank code from under MP cores.
+  app_done_ack=3;
+  app_done=TRUE;
+  while (app_done_ack)
+    Yield;
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/MultiCore/Lock.HC.HTML b/public/Wb/Demo/MultiCore/Lock.HC.HTML new file mode 100755 index 0000000..7c6eee6 --- /dev/null +++ b/public/Wb/Demo/MultiCore/Lock.HC.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+/*lock{} is a compiler stmt
+which places asm LOCK inst
+prefixes on code.  Only use it on
+read-modify-write stmts.
+It will generate invalid insts
+if you misuse it and it will crash.
+U() to see what code was generated.
+*/
+
+#define CNT     0x1000000
+
+I64 glbl;
+
+U0 MPUnlockedInc(I64)
+{
+  I64 i;
+  for (i=0;i<CNT;i++)
+    glbl++;
+}
+
+U0 UnlockedInc()
+{
+  CJob *tmpm0,*tmpm1;
+  glbl=0;
+  tmpm0=JobQue(&MPUnlockedInc,NULL,0,0);
+  tmpm1=JobQue(&MPUnlockedInc,NULL,1,0);
+  JobResGet(tmpm0);
+  JobResGet(tmpm1);
+  "Correct Cnt:%X Actual Cnt:%X\n",CNT*2,glbl;
+}
+
+U0 MPLockedInc(I64)
+{
+  I64 i;
+  for (i=0;i<CNT;i++)
+    lock  //Can be used without {}
+          glbl++;
+}
+
+U0 LockedInc()
+{
+  CJob *tmpm0,*tmpm1;
+  glbl=0;
+  tmpm0=JobQue(&MPLockedInc,NULL,0,0);
+  tmpm1=JobQue(&MPLockedInc,NULL,1,0);
+  JobResGet(tmpm0);
+  JobResGet(tmpm1);
+  "Correct Cnt:%X Actual Cnt:%X\n",CNT*2,glbl;
+}
+
+UnlockedInc;
+LockedInc;
+
+ diff --git a/public/Wb/Demo/MultiCore/MPAdd.HC.HTML b/public/Wb/Demo/MultiCore/MPAdd.HC.HTML new file mode 100755 index 0000000..68a613b --- /dev/null +++ b/public/Wb/Demo/MultiCore/MPAdd.HC.HTML @@ -0,0 +1,116 @@ + + + + + + + + + + + +
+I64 mp_n;
+
+I64 MPSum(I64 my_mp_cnt)
+{//We could use the formula n*(n+1)/2
+  I64 lo=mp_n*Gs->num/my_mp_cnt,
+        hi=mp_n*(Gs->num+1)/my_mp_cnt,
+        res=0,i;
+  for (i=lo;i<hi;i++)
+    res+=i;
+  return res;
+}
+
+I64 Sum(I64 n,I64 my_mp_cnt)
+{
+  CJob *tmpm[MP_PROCESSORS_NUM];
+  I64 res=0,i;
+  mp_n=n+1;
+  for (i=0;i<my_mp_cnt;i++)
+    tmpm[i]=JobQue(&MPSum,my_mp_cnt,i,0);
+  for (i=0;i<my_mp_cnt;i++)
+    res+=JobResGet(tmpm[i]);
+  return res;
+}
+
+#define SAMPLE_SIZE 100
+
+F64 Test(I64 n,I64 my_mp_cnt)
+{
+  I64 i,val=0;
+  F64 start,end;
+  start=tS;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    val+=Sum(n,my_mp_cnt);
+  end=tS;
+  "Val:%,d\n",val/SAMPLE_SIZE;
+  "$RED$N:%12,d Time:%10.8f$FG$\n",n,(end-start)/SAMPLE_SIZE;
+  return end-start;
+}
+
+#define VAL_MIN         1000
+#define TEST_MIN        3
+#define TEST_MAX        7
+#define TESTS_NUM       (TEST_MAX-TEST_MIN+1)
+#define PERCENT_MAX     200
+
+U0 MPAdd()
+{
+  I64 i,n,
+        h=Fs->pix_width,
+        v=Fs->pix_height;
+  F64 t1,t2,ress[TESTS_NUM];
+  CDC *dc=DCAlias;
+
+  for (i=0,n=VAL_MIN;i<TESTS_NUM;i++,n*=10) {
+    t1=Test(n,1);
+    t2=Test(n,mp_cnt);
+    ress[i]=t2*100.0/t1;
+    "$GREEN$%8.4f%%$FG$\n\n",ress[i];
+  }
+  PressAKey;
+
+  DocClear;
+
+  dc->color=BLUE;
+  for (i=PERCENT_MAX/10;i<PERCENT_MAX;i+=PERCENT_MAX/10) {
+    GrPrint(dc,0,v-ToF64(i)/PERCENT_MAX*v-FONT_HEIGHT,"%3d%%",i);
+    GrLine(dc,0,v-ToF64(i)/PERCENT_MAX*v,h,v-ToF64(i)/PERCENT_MAX*v);
+  }
+
+  for (i=0;i<TESTS_NUM-1;i++) {
+    dc->color=RED;
+    dc->thick=2;
+    GrLine3(dc,i*h/(TESTS_NUM-1),      v-ress[i  ]/PERCENT_MAX*v,0,
+          (i+1)*h/(TESTS_NUM-1),v-ress[i+1]/PERCENT_MAX*v,0);
+    dc->color=GREEN;
+    GrPrint(dc,i*h/(TESTS_NUM-1),v-FONT_HEIGHT,"10e%d",i+TEST_MIN);
+    GrLine(dc,i*h/(TESTS_NUM-1),0,i*h/(TESTS_NUM-1),v);
+  }
+  PressAKey;
+
+  DCFill;
+  DCDel(dc);
+}
+
+MPAdd;
+
+ diff --git a/public/Wb/Demo/MultiCore/MPPrint.HC.HTML b/public/Wb/Demo/MultiCore/MPPrint.HC.HTML new file mode 100755 index 0000000..34846f8 --- /dev/null +++ b/public/Wb/Demo/MultiCore/MPPrint.HC.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+U0 Job(CDoc *doc)
+{
+  I64 i;
+  for (i=0;i<2;i++)
+    DocPrint(doc,"$FG,%d$CPU%d ",Gs->num&15,Gs->num);
+}
+
+U0 MPPrintDemo()
+{
+  I64 i;
+  for (i=0;i<500;i++)
+    JobQue(&Job,DocPut,i%mp_cnt);
+  Sleep(500);
+  "$FG$\n";
+}
+
+MPPrintDemo;
+
+ diff --git a/public/Wb/Demo/MultiCore/MPRadix.HC.HTML b/public/Wb/Demo/MultiCore/MPRadix.HC.HTML new file mode 100755 index 0000000..dfa3c0f --- /dev/null +++ b/public/Wb/Demo/MultiCore/MPRadix.HC.HTML @@ -0,0 +1,173 @@ + + + + + + + + + + + +
+/*
+On an 8-core machine, this takes the top 3-bits
+of random numbers and distributes them to the 8 cores
+for sorting.  Then, it merge sorts them.
+*/
+
+#define NUM     1000000
+
+I64 my_mp_cnt=1<<Bsr(mp_cnt);//Power of 2
+
+I32 *arg1,*arg2;
+I32 *b[my_mp_cnt],bn[my_mp_cnt];
+I64 mp_not_done_flags;
+
+I64 Compare(I32 *e1,I32 *e2)
+{
+  return *e1-*e2;
+}
+
+U0 QSortU32(I32 *base,I64 num)
+{//By customizing, we dramatically improve it!
+//Cut and paste from QSortI64().
+  I64 i;
+  I32 *less,*greater,pivot;
+  if (num>1) {
+    do {
+      less=base;
+      greater=base+num;
+      pivot=base[num/2];
+      while (less<greater) {
+        if (*less<=pivot)
+          less++;
+        else {
+          greater--;
+          SwapU32(less,greater);
+        }
+      }
+      i=less-base;
+      if (i==num) {//All less or equ to pivot
+
+        //Point greater to first less
+        do greater--;
+        while (--i && *greater==pivot);
+
+        if (i) {
+          less=base+num/2; //Pivot was not moved, point to it
+          if (less<greater)
+            SwapU32(less,greater);
+          num=i;
+        } else //All equ
+          break;
+      } else if (i<num/2) {
+        QSortU32(base,i);
+        num-=i;
+        base=greater;
+      } else {
+        QSortU32(greater,num-i);
+        num=i;
+      }
+    } while (num>1);
+  }
+}
+
+U0 MPSort(I64 dummy=0)
+{
+  no_warn dummy;
+  QSortU32(b[Gs->num],bn[Gs->num]);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 MPRadixSortDemo(I64 dummy=0)
+{
+  no_warn dummy;
+  I64 i,j,k1,k2;
+  F64 t0;
+  arg1=MAlloc(NUM*sizeof(I32));
+  for (i=0;i<NUM;i++)
+    arg1[i]=RandI32;
+
+  arg2=MAlloc(NUM*sizeof(I32));
+
+  "$GREEN$QSort$FG$\n";
+  t0=tS;
+  MemCpy(arg2,arg1,sizeof(I32)*NUM);
+  QSort(arg2,NUM,sizeof(I32),&Compare);
+  "Time:%9.6f\n",tS-t0;
+  D(arg2+NUM/4);
+
+  "$GREEN$QSortU32$FG$\n";
+  t0=tS;
+  MemCpy(arg2,arg1,sizeof(I32)*NUM);
+  QSortU32(arg2,NUM);
+  "Time:%9.6f\n",tS-t0;
+  D(arg2+NUM/4);
+
+  for (i=0;i<my_mp_cnt;i++) {
+//We must do full size, just in case.
+    //There will be uneven split between cores
+    //depending on the distribution of rand numbers.
+    b[i]=MAlloc(NUM*sizeof(I32));
+    bn[i]=0;
+  }
+
+  if (my_mp_cnt<2) throw('MultCore');
+
+  "$GREEN$MP Radix QSortU32$FG$\n";
+  t0=tS;
+  k1=32-Bsr(my_mp_cnt);
+  k2=my_mp_cnt/2;
+  for (i=0;i<NUM;i++) {
+    j=arg1[i]>>k1+k2; //This is a preliminary radix sort.
+    b[j][bn[j]++]=arg1[i];
+  }
+  mp_not_done_flags=1<<my_mp_cnt-1;
+  for (i=0;i<my_mp_cnt;i++)
+    Spawn(&MPSort,NULL,NULL,i);
+  while (mp_not_done_flags)
+    Yield;
+  j=0;
+  for (i=0;i<my_mp_cnt;i++) {
+    MemCpy(&arg2[j],b[i],bn[i]*sizeof(I32));
+    j+=bn[i];
+  }
+  "Time:%9.6f\n",tS-t0;
+  D(arg2+NUM/4);
+
+  Free(arg1);
+  Free(arg2);
+  for (i=0;i<my_mp_cnt;i++)
+    Free(b[i]);
+}
+
+MPRadixSortDemo;
+
+/* Results on 8 Cores 3.397GHz Core i7:
+QSort
+Time: 0.759998
+QSortU32
+Time: 0.093684
+MP Radix QSortU32
+Time: 0.045450
+*/
+
+ diff --git a/public/Wb/Demo/MultiCore/Palindrome.HC.HTML b/public/Wb/Demo/MultiCore/Palindrome.HC.HTML new file mode 100755 index 0000000..4649d2e --- /dev/null +++ b/public/Wb/Demo/MultiCore/Palindrome.HC.HTML @@ -0,0 +1,127 @@ + + + + + + + + + + + +
+#define BORDER_CHARS    1
+
+U8 *buf;
+I64 size,mp_not_done_flags;
+CDoc *doc;
+
+U0 PDNormalize()
+{
+  U8 *r=MAlloc(size+2*BORDER_CHARS),
+        *src=buf,*dst=r;
+  I64 ch;
+  *dst++='['; //Border
+  while (size--) {
+    ch=*src++;
+    if ('a'<=ch<='z') //lower is most common so do first
+      *dst++=ch;
+    else if ('A'<=ch<='Z')
+      *dst++=ch+'a'-'A'; //Convert to lower
+  }
+  *dst++=']'; //Border
+  Free(buf);
+  buf=r;
+  size=dst-r-2*BORDER_CHARS;
+}
+
+U0 PDAnswer(U8 *a,I64 len)
+{
+  DocLock(doc);
+  a-=(len-1)/2;
+  DocPrint(doc,"CPU%02X Len:%2d ",Gs->num,len);
+  while (len--)
+    DocPrint(doc,"%C",*a++); //%C is toupper char
+  DocPrint(doc,"\n");
+  DocUnlock(doc);
+}
+
+U0 MPPalindrome(I64 dummy=0)
+{
+  no_warn dummy;
+  U8 *src=buf+BORDER_CHARS+size*Gs->num/mp_cnt,
+        *f,*b;
+  I64 len,best=0,
+        my_size=(size+mp_cnt-1)/mp_cnt;
+  while (my_size--) {
+
+    //Odd
+    f=src+1;
+    b=src-1;
+    while (*f==*b) {
+      f++;
+      b--;
+    }
+    len=f-b+1-2;
+    if (len>best) {
+      best=len;
+      PDAnswer(src,len);
+    }
+
+    //Even
+    f=src+1;
+    b=src;
+    while (*f==*b) {
+      f++;
+      b--;
+    }
+    len=f-b+1-2;
+    if (len>best) {
+      best=len;
+      PDAnswer(src,len);
+    }
+
+    src++;
+  }
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 Palindrome(U8 *filename)
+{
+  I64 i;
+  F64 t0=tS;
+
+  buf=FileRead(filename,&size);
+  PDNormalize;
+
+  doc=DocPut;
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPPalindrome,NULL,i);
+  while (mp_not_done_flags)
+    Yield;
+
+  Free(buf);
+  "Time:%9.5f\n",tS-t0;
+}
+
+Palindrome(BIBLE_FILENAME);
+
+ diff --git a/public/Wb/Demo/MultiCore/Primes.HC.HTML b/public/Wb/Demo/MultiCore/Primes.HC.HTML new file mode 100755 index 0000000..b121d5f --- /dev/null +++ b/public/Wb/Demo/MultiCore/Primes.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+U8 *master_bitmap;
+I64 prime_range,my_mp_cnt,pending;
+
+U0 PrimesJob(I64 i)
+{
+  I64 j,k,l=Sqrt(prime_range),
+        lo=i*prime_range/my_mp_cnt,
+        hi=(i+1)*prime_range/my_mp_cnt,
+        lo2=lo+sys_cache_line_width,
+        hi2=hi-sys_cache_line_width;
+  if (lo2>hi2) lo2=hi2;
+  for (j=2;j<=l;j++) {
+    if (!Bt(master_bitmap,j)) {
+      if (j>=lo)
+        k=j+j;
+      else {
+        k=lo-lo%j;
+        if (k<lo)
+          k+=j;
+      }
+      while (k<lo2) {
+        LBts(master_bitmap,k);
+        k+=j;
+      }
+      while (k<hi2) {
+        Bts(master_bitmap,k);
+        k+=j;
+      }
+      while (k<hi) {
+        LBts(master_bitmap,k);
+        k+=j;
+      }
+    }
+  }
+  lock pending--;
+}
+
+I64 Primes(I64 range,I64 _my_mp_cnt)
+{
+  I64 i,prime_cnt=0;
+  F64 t0=tS,tf;
+  prime_range=range;
+  if (_my_mp_cnt<=mp_cnt)
+    my_mp_cnt=_my_mp_cnt;
+  else
+    my_mp_cnt=mp_cnt;
+  master_bitmap=CAlloc((prime_range+7)/8+1);
+  Bts(master_bitmap,0);
+  Bts(master_bitmap,1);
+  pending=my_mp_cnt;
+  for (i=0;i<my_mp_cnt;i++)
+    JobQue(&PrimesJob,i,i);
+  while (pending)
+    Yield;
+  tf=tS;
+
+  for (i=0;i<prime_range;i++)
+    if (!Bt(master_bitmap,i))
+      prime_cnt++;
+
+  for (i=MaxI64(prime_range-100,0);i<prime_range;i++)
+    if (!Bt(master_bitmap,i))
+      "%d ",i;
+
+  "\n$RED$CPUs:%d PrimeRange:%,d PrimeCnt:%,d Time:%9.7,f$FG$\n",
+        my_mp_cnt,prime_range,prime_cnt,tf-t0;
+
+  Free(master_bitmap);
+  return prime_cnt;
+}
+
+Primes(100,1);
+Primes(100,mp_cnt);
+Primes(1000000,1);
+Primes(1000000,mp_cnt);
+
+ diff --git a/public/Wb/Demo/NullCase.HC.HTML b/public/Wb/Demo/NullCase.HC.HTML new file mode 100755 index 0000000..25d7808 --- /dev/null +++ b/public/Wb/Demo/NullCase.HC.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+//This shows a switch stmt with some null cases.
+//If no number for the case,
+//it uses one plus prev case number.
+
+U0 NullCase()
+{
+  I64 i;
+  for (i=0;i<20;i++)
+    switch (i) {
+      case: "Zero\n";   break; //Starts at zero
+      case: "One\n";    break; //One plus prev case.
+      case: "Two\n";    break;
+      case: "Three\n";  break;
+      case 10: "Ten\n"; break;
+      case: "Eleven\n"; break; //One plus prev case.
+    }
+}
+
+NullCase;
+
+ diff --git a/public/Wb/Demo/OnceDemo.HC.HTML b/public/Wb/Demo/OnceDemo.HC.HTML new file mode 100755 index 0000000..56da94e --- /dev/null +++ b/public/Wb/Demo/OnceDemo.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+U0 OnceDemo()
+{//Set code to execute next reboot.
+  Once("Beep;");
+  Once("Dir;"); //You can issue multiple and they get queued.
+  "Reboot ";
+  if (YorN)
+    BootRAM;
+}
+
+OnceDemo;
+
+//There are variants for adam AOnce().
+
+ diff --git a/public/Wb/Demo/ParenWarn.HC.HTML b/public/Wb/Demo/ParenWarn.HC.HTML new file mode 100755 index 0000000..174ce4b --- /dev/null +++ b/public/Wb/Demo/ParenWarn.HC.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+Option(OPTf_WARN_PAREN,ON);
+
+F64 d,d1=1,d2=1;
+
+d1=(d2=3.0);
+
+d1=(d2+3.0);
+
+d=(d1+d2)+(d1+d2);
+
+d=(2`3)`2;
+
+d=2`(3`2);
+
+d=-d1`(d+d2);
+
+Option(OPTf_WARN_PAREN,OFF);
+
+ diff --git a/public/Wb/Demo/PhoneNumWords.HC.HTML b/public/Wb/Demo/PhoneNumWords.HC.HTML new file mode 100755 index 0000000..9bd4934 --- /dev/null +++ b/public/Wb/Demo/PhoneNumWords.HC.HTML @@ -0,0 +1,94 @@ + + + + + + + + + + + +
+U8 char_map[26]="22233344455566677778889999";
+
+/*
+Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block; //definition offset in ::/Adam/AutoComplete/ACDefs.DATA
+*/
+U0 PhoneNumWords(U8 *num)
+{
+  I64 ch;
+  U8 *_num=StrNew(num),*dst=_num,
+        *dict=acd.word_lst,*st,*src;
+  while (*num) {
+    if ('0'<=*num<='9')
+      *dst++=*num;
+    num++;
+  }
+  *dst=0;
+
+  while (*dict++) {
+    if (StrLen(dict)>2) {
+      dst=st=StrNew(dict);
+      while (ch=ToUpper(*dst)) {
+        if ('A'<=ch<='Z')
+          *dst=char_map[ch-'A'];
+        else
+          *dst=CH_SPACE;
+        dst++;
+      }
+      *dst=0;
+
+      src=_num;
+      while (*src) {
+        if (!StrNCmp(st,src,StrLen(st))) {
+          ch=*src;
+          *src=0;
+          "%s",_num;
+          *src=ch;
+          "$GREEN$%s$FG$",dict;
+          "%s\n",src+StrLen(st);
+        }
+        src++;
+      }
+      Free(st);
+    }
+    dict+=StrLen(dict)+3;
+  }
+  Free(_num);
+  '\n';
+}
+
+U0 PNWDemo()
+{
+  U8 *st;
+  while ((st=GetStr("Phone Num:")) && *st) {
+    PhoneNumWords(st);
+    Free(st);
+  }
+  Free(st);
+}
+
+PNWDemo;
+
+ diff --git a/public/Wb/Demo/Print.HC.HTML b/public/Wb/Demo/Print.HC.HTML new file mode 100755 index 0000000..db06101 --- /dev/null +++ b/public/Wb/Demo/Print.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+//TempleOS supports standard Print()
+//codes and extended ones.
+//See Print("") Fmt Strings.
+
+//Demonstrates aux_fmt_num codes.
+
+"%10h?d\n",123456789;
+"%10h?d\n",12345;
+
+"%10h3d\n",123456789;
+"%10h3d\n",12345;
+
+"\nWith the ',' flag:\n";
+"%10,h3d\n",123456789;
+"%10,h3d\n",12345;
+
+"\nFloating Point:\n";
+"%16h?n\n",.00123456789;
+"%16h?n\n",12345.0;
+
+"%16.2h-6n\n",.00123456789;
+"%16.2h-6n\n",12345.0;
+
+'\n';
+
+"%h25c\n",'x'; //Print 25 x's
+
+"%h*c\n",25,'y'; //Print 25 y's
+
+'zzzz\n'; //PutChars() up to 8 characters.
+
+'\n';
+
+
+ diff --git a/public/Wb/Demo/Progress.HC.HTML b/public/Wb/Demo/Progress.HC.HTML new file mode 100755 index 0000000..6171a08 --- /dev/null +++ b/public/Wb/Demo/Progress.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+/*progress1-progress4 are just global vars
+shown on the wallpaper. I use them in debugging a lot.
+
+If you set progress1_max-progress4_max,
+then a progress bar will display.
+
+If you set progress1_t0-progress4_t0
+then the elapsed time will display.
+
+If you set progress1_tf-progress4_tf
+then the estimated time will display.
+*/
+
+U0 Main1()
+{
+  "\nWith description.\n";
+  PressAKey;
+  progress1_max=200;
+  StrCpy(progress1_desc,"Progress Demo"); //PROGRESS_DESC_LEN is max
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst;
+}
+Main1;
+
+U0 Main2()
+{
+  "\nWith description and elapsed time.\n";
+  PressAKey;
+  progress1_max=200;
+  progress1_t0=tS;
+  StrCpy(progress1_desc,"Progress Demo"); //PROGRESS_DESC_LEN is max
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst;
+}
+Main2;
+
+U0 Main3()
+{
+  "\nWith description, elapsed time and registry total time.\n";
+  PressAKey;
+  progress1_max=200;
+  progress1_t0=tS;
+  RegExe("DemoCompany/ProgressBars");
+  StrCpy(progress1_desc,"Progress Demo"); //PROGRESS_DESC_LEN is max
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst("DemoCompany/ProgressBars");
+}
+Main3;
+
+U0 Main4()
+{
+  "\nNo description.\n";
+  PressAKey;
+  progress1_max=200;
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst;
+}
+Main4;
+
+
+"\nNow, from asm...  It's handy for debugging.\n"
+"Watch the progress on the wallpaper.\n";
+WinBorder(ON);
+PressAKey;
+
+asm {
+_PROGRESS_DEMO::
+        MOV     RCX,12000000
+@@05:   MOV     U64 [&progress1],RCX
+        CALL    &Yield
+        LOOP    @@05
+        MOV     U64 [&progress1],RCX
+        RET
+}
+_extern _PROGRESS_DEMO U0 AsmProgressDemo();
+AsmProgressDemo;
+
+ diff --git a/public/Wb/Demo/Prompt.HC.HTML b/public/Wb/Demo/Prompt.HC.HTML new file mode 100755 index 0000000..6c7b784 --- /dev/null +++ b/public/Wb/Demo/Prompt.HC.HTML @@ -0,0 +1,56 @@ + + + + + + + + + + + +
+U0 PromptDemo()
+{
+  F64 d;
+  I64 i;
+  U8 *name;
+  CDate cdt;
+
+  "\n\nNow prompting from the cmd line.\n\n"
+        "$GREEN$<ENTER>$FG$ keeps default.\n\n";
+
+  i=GetI64("Enter int expression(%d):",123);
+  "Int=%d\n",i;
+
+  d=GetF64("Enter float expression(%12g):",1.2e3);
+  "Float=%e\n",d;
+
+  name=GetStr("Name (%s):","John");
+  "Name:%s\n",name;
+  Free(name);
+
+  cdt=GetDate("Date (%D):",Now);
+  "Date=%D\n",cdt;
+}
+
+PromptDemo;
+
+ diff --git a/public/Wb/Demo/PullDownMenu.HC.HTML b/public/Wb/Demo/PullDownMenu.HC.HTML new file mode 100755 index 0000000..19835b7 --- /dev/null +++ b/public/Wb/Demo/PullDownMenu.HC.HTML @@ -0,0 +1,120 @@ + + + + + + + + + + + +
+//See Menus
+
+#define M_OPTION1       1
+#define M_OPTION2       2
+
+U0 PullDownMenuDemo()
+{
+  I64 msg_code,arg1,arg2;
+  CMenuEntry *tmpse;
+
+  MenuPush(
+        "File {"
+        "  Open(,'O');"
+        "  Save(,'S');"
+        "  Exit(,CH_SHIFT_ESC);"
+        "}"
+        "Edit {"
+        "  Cut(,,SC_DELETE|SCF_SHIFT);"
+        "  Paste(,,SC_INS|SCF_SHIFT);"
+        "}"
+        "Misc {"
+        "  Beep(,CH_SPACE);"
+        "  Opt1(MSG_CMD,M_OPTION1);"
+        "  Opt2(MSG_CMD,M_OPTION2);"
+        "}"
+        "Help {"
+        "  Help(,,0x3B0000003B);"
+        "  About(,,0x23B0000023B);"
+        "}");
+
+  "A pull-down menu will appear "
+        "if you move the mouse to the top "
+        "of the scrn.\n\n";
+
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_CMD);
+    "\nCmd:%d ARG1:%X ARG2:%X\n\n",msg_code,arg1,arg2;
+
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        switch (arg1) {//ASCII
+          case CH_SPACE:
+            Beep;
+            break;
+          case 0:
+            switch (arg2.u8[0]) {//arg2=Scan code
+              case SC_F1:
+                if (arg2&SCF_SHIFT)
+                  "About PullDown Demo\n";
+                else
+                  "Test the menu.\n";
+                break;
+              case SC_DELETE:
+                if (arg2&SCF_SHIFT)
+                  "Cut\n";
+                break;
+              case SC_INS:
+                if (arg2&SCF_SHIFT)
+                  "Paste\n";
+                break;
+            }
+            break;
+        }
+        break;
+
+      case MSG_CMD:
+//I Recommend making your menu
+      //drive by key strokes, but you can
+      //use the MSG_CMD val.
+        switch (arg1) {
+          case M_OPTION1:
+            "Option # 1\n";
+            if (tmpse=MenuEntryFind(Fs->cur_menu,"Misc/Opt1"))
+              tmpse->checked=!tmpse->checked;
+            break;
+          case M_OPTION2:
+            "Option # 2\n";
+            if (tmpse=MenuEntryFind(Fs->cur_menu,"Misc/Opt2"))
+              tmpse->checked=!tmpse->checked;
+            break;
+        }
+        break;
+    }
+
+  } while (msg_code!=MSG_KEY_DOWN||(arg1!=CH_SHIFT_ESC && arg1!=CH_ESC));
+  MenuPop;
+}
+
+PullDownMenuDemo;
+
+ diff --git a/public/Wb/Demo/RadixSort.HC.HTML b/public/Wb/Demo/RadixSort.HC.HTML new file mode 100755 index 0000000..9dfef81 --- /dev/null +++ b/public/Wb/Demo/RadixSort.HC.HTML @@ -0,0 +1,93 @@ + + + + + + + + + + + +
+#define RADIX   256
+#define N       16
+
+U8 a[N];
+
+class Lst
+{
+  Lst *next;
+  U8 *a;
+} l[N],*r[RADIX];
+
+U0 DumpIn()
+{
+  I64 i;
+  "$RED$\n\nInput$FG$\n";
+  for (i=0;i<N;i++)
+    "%d:%d\n",i,a[i];
+}
+
+U0 DumpOut()
+{
+  I64 i,j=0;
+  Lst *tmpl;
+  "$RED$\n\nOutput$FG$\n";
+  for (i=0;i<RADIX;i++) {
+    tmpl=r[i];
+    while (tmpl) {
+      "%d:%d\n",j++,*tmpl->a;
+      tmpl=tmpl->next;
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  MemSet(r,0,sizeof(r));
+  for (i=0;i<N;i++) {
+    a[i]=RandU16&255;
+    l[i].next=NULL;
+    l[i].a=&a[i];
+  }
+}
+
+U0 Sort()
+{
+  I64 i;
+  for (i=0;i<N;i++) {
+    l[i].next=r[*l[i].a];
+    r[*l[i].a]=&l[i];
+  }
+}
+
+U0 RadixSort()
+{
+  Init;
+  DumpIn;
+  Sort;
+  DumpOut;
+}
+
+RadixSort;
+
+ diff --git a/public/Wb/Demo/RandDemo.HC.HTML b/public/Wb/Demo/RandDemo.HC.HTML new file mode 100755 index 0000000..a02ffaa --- /dev/null +++ b/public/Wb/Demo/RandDemo.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+U0 RandPts()
+{
+  I64 i;
+  F64 t0=tS;
+  do {
+    for (i=0;i<1024;i++) {
+      gr.dc->color=RandU16&15;
+      GrPlot(gr.dc,RandU32%GR_WIDTH,RandU32%GR_HEIGHT);
+    }
+    Yield;
+  } while (tS-t0<1);
+  DCFill;
+}
+
+U0 RandDemo()
+{
+  I64 i;
+
+  "Seed(0) will do timer XORed random numbers.  "
+        "A task starts with Seed(0) by dft.\n";
+  PressAKey;
+  Seed;
+  RandPts;
+  DCFill;
+
+  "\nSeed(num) will do deterministic, non-timer random numbers starting at "
+        "a specific seed.  You can run a specific video game over and over "
+        "by typing Seed(num) at the cmd line before the game.\n";
+  PressAKey;
+  Seed(1);
+  RandPts;
+  DCFill;
+
+  "\n\n\nWatch when we specify specific seeds:";
+
+  "\n\nSeed(1);\n";
+  Seed(1);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(2); Different, right?\n";
+  Seed(2);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(1); Repeats earlier values.\n";
+  Seed(1);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(0); Zero is special.\n";
+  Seed(0);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(0); Non-repeating.\n";
+  Seed(0);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  Seed; //Dft should be kept to zero.
+}
+
+RandDemo;
+
+ diff --git a/public/Wb/Demo/RegistryDemo.HC.HTML b/public/Wb/Demo/RegistryDemo.HC.HTML new file mode 100755 index 0000000..fd64fdf --- /dev/null +++ b/public/Wb/Demo/RegistryDemo.HC.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+/*The ~/Registry.HC.Z file is HolyC code.
+You can execute a tree branch of it.  The Adam
+branch is executed in the Adam task boot phase.
+Normally, you will place var declarations
+in the branch you make, but since an arthmetic expression
+is valid in HolyC you can place simple expressions
+without vars.
+*/
+
+RegDft("DemoCompany/Game1","F64 best_score=1.23;\n");
+RegDft("DemoCompany/Game1/SimpleVal","1234;\n");
+RegExe("DemoCompany/Game1");
+
+U0 Game()
+{
+  I64 i=RegExe("DemoCompany/Game1/SimpleVal");
+  "High Score:%6.5f\n",best_score;
+  "Val:%d\n",i;
+  i++;
+  best_score=tS;
+//You could combine these into one write by making
+  //the $TR...$ and $ID,2$, $ID,-2$, cmds yourself.
+  RegWrite("DemoCompany/Game1","F64 best_score=%9.5f;\n",best_score);
+  RegWrite("DemoCompany/Game1/SimpleVal","%d;\n",i);
+}
+
+Game;
+
+ diff --git a/public/Wb/Demo/RevFileDemo/Rev.HC.HTML b/public/Wb/Demo/RevFileDemo/Rev.HC.HTML new file mode 100755 index 0000000..889b3f0 --- /dev/null +++ b/public/Wb/Demo/RevFileDemo/Rev.HC.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+/*We use the internal routines from the text editor
+to cut and paste lines to rev the order of
+lines in a text file.
+*/
+
+Cd(__DIR__);;
+
+U0 Rev(U8 *in_name,U8 *out_name)
+{
+  CDoc  *doc_in =DocRead(in_name),
+        *doc_out=DocNew(out_name);
+  DocTop(doc_in);
+  while (doc_in->head.next!=doc_in) {
+    EdLineDown(doc_in,SC_CURSOR_DOWN|SCF_SHIFT);
+    ClipCut(doc_in);
+    DocTop(doc_out);
+    ClipPaste(doc_out);
+  }
+  DocWrite(doc_out);
+}
+
+Rev("DemoPoemBwd.DD.Z","~/DemoPoemFwd.DD.Z");
+
+ diff --git a/public/Wb/Demo/ScrnCodes.HC.HTML b/public/Wb/Demo/ScrnCodes.HC.HTML new file mode 100755 index 0000000..370e5a6 --- /dev/null +++ b/public/Wb/Demo/ScrnCodes.HC.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+/*See TextBase Layer for the format
+of the U32 you pass to TextChar()
+
+See ::/Doc/CharOverview.DD, ::/Demo/ExtChars.HC,
+and ::/Demo/Graphics/FontEd.HC.
+
+Hold <ALT> and press a 3 digit decimal number
+or press <CTRL-ALT-a> to enter extended characters.
+*/
+
+U0 DrawIt(CTask *task,CDC *)
+{
+  I64 i;
+  for (i=0;i<256;i++)
+    TextChar(task,,(i&15)*2,(i/16)*2,i+BLACK<<12+WHITE<<8);
+}
+
+U0 ScrnCodes()
+{
+  SettingsPush; //See SettingsPush
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar(,FALSE);
+  SettingsPop;
+}
+
+ScrnCodes;
+
+ diff --git a/public/Wb/Demo/Snd/ASCIIOrgan.HC.HTML b/public/Wb/Demo/Snd/ASCIIOrgan.HC.HTML new file mode 100755 index 0000000..3aad6dc --- /dev/null +++ b/public/Wb/Demo/Snd/ASCIIOrgan.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+//Practice your ASCII knowledge ;-)
+
+U0 SafePutChar(U8 ch)
+{
+  if (CH_SHIFT_SPACE<=ch<0x7F) {
+    if (ch=='$')
+      "%02X $RED$$$$FG$ ",ch;
+    else
+      "%02X $RED$%c$FG$ ",ch,ch;
+  } else
+    "%02X $RED$ $FG$ ",ch;
+}
+
+
+
+
+
+
+            <1>/* Graphics Not Rendered in HTML */
+
+U0 ASCIIOrgan()
+{
+  I64 i,ch;
+
+  for (i=0;i<32;i++) {
+    SafePutChar(i);
+    SafePutChar(i+32);
+    SafePutChar(i+64);
+    SafePutChar(i+96);
+    '\n';
+  }
+
+  "\nPress keys to make snds\n"
+        "and press $GREEN$<SHIFT-ESC>$FG$ to exit.\n";
+  do {
+//We don't want echo or scan codes, so we use NULL and FALSE...
+    ch=GetChar(,FALSE);
+    Snd(ch-CH_ESC);
+  } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  Snd;
+
+  //Note the %d in the string for sprite number.
+  '\n\n\n\n\n\n\n';
+  Sprite(<1>,"$SP+PU,\"Click for better organ\","
+        "LM=\"#include \\\"::/Apps/Psalmody/Run\\\";\",BI=%d$");
+  '\n\n\n\n\n';
+}
+
+ASCIIOrgan;
+
+ diff --git a/public/Wb/Demo/Snd/MorseCode.HC.HTML b/public/Wb/Demo/Snd/MorseCode.HC.HTML new file mode 100755 index 0000000..6759e51 --- /dev/null +++ b/public/Wb/Demo/Snd/MorseCode.HC.HTML @@ -0,0 +1,207 @@ + + + + + + + + + + + +
+#define M_DASH_THRESHOLD  0.140
+#define M_SPACE_THRESHOLD 0.300
+
+U8 *morse_lst=
+
+"A.-\0"
+"B-...\0"
+"C-.-.\0"
+"D-..\0"
+"E.\0"
+"F..-.\0"
+"G--.\0"
+"H....\0"
+"I..\0"
+"J.---\0"
+"K-.-\0"
+"L.-..\0"
+"M--\0"
+"N-.\0"
+"O---\0"
+"P.--.\0"
+"Q--.-\0"
+"R.-.\0"
+"S...\0"
+"T-\0"
+"U..-\0"
+"V...-\0"
+"W.--\0"
+"X-..-\0"
+"Y-.--\0"
+"Z--..\0"
+
+"1.----\0"
+"2..---\0"
+"3...--\0"
+"4....-\0"
+"5.....\0"
+"6-....\0"
+"7--...\0"
+"8---..\0"
+"9----.\0"
+"0-----\0"
+
+"/-..-.\0"
+"+.-.-.\0"
+"..-.-.-\0"
+",--..--\0"
+"?..--..\0"
+"(-.--.\0"
+")-.--.-\0"
+"--....-\0"
+"\".-..-.\0"
+"_..--.-\0"
+"'.----.\0"
+":---...\0"
+";-.-.-.\0"
+"=-...-\0";
+
+U0 MorseTable()
+{
+  U8 *st;
+  I64 i=0;
+  for (i=0;i<13;i++ ) {
+    if (st=LstSub(i,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    if (st=LstSub(i+13,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    if (st=LstSub(i+26,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    if (st=LstSub(i+39,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    '\n';
+  }
+  '\n';
+}
+
+F64 m_start,m_end,dt_down,dt_up;
+Bool space_sent;
+
+U8 *MorseTimes(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  StrPrint(st,"Down:%10.6f Up:%10.6f",dt_down,dt_up);
+  return st;
+}
+
+I64 MorseWaitKey()
+{
+  I64 ch;
+  F64 dt;
+  while (TRUE) {
+    if (m_start) {
+      GetMsg(NULL,NULL,1<<MSG_KEY_UP);
+      m_end=tS;
+      Snd;
+      dt_down=m_end-m_start;
+      m_start=0;
+      space_sent=FALSE;
+      if (dt_down<M_DASH_THRESHOLD)
+        return '.';
+      else
+        return '-';
+    } else {
+      if (!space_sent) {
+        while (!ScanMsg(&ch,NULL,1<<MSG_KEY_DOWN)) {
+          dt=tS-m_end;
+          if (dt>=M_SPACE_THRESHOLD) {
+            space_sent=TRUE;
+            return CH_SPACE;
+          }
+          Yield;
+        }
+      } else
+        ch=GetChar(,FALSE);
+      m_start=tS;
+      Snd(74);
+      if (ch==CH_SHIFT_ESC || ch==CH_ESC) {
+        '\n';
+        Snd;
+        throw; //exit program
+      }
+      dt_up=m_start-m_end;
+      if (!space_sent && dt_up>=M_SPACE_THRESHOLD) {
+        space_sent=TRUE;
+        return CH_SPACE;
+      }
+    }
+  }
+}
+
+U0 Morse()
+{
+  CDocEntry *doc_e;
+  I64 ch;
+  U8 buf[8],*dst,*src;
+
+  MorseTable;
+  m_start=0;
+  m_end=tS;
+  dt_down=0;
+  dt_up=0;
+  space_sent=TRUE;
+
+  "$GREEN$";
+
+  doc_e=DocPrint(DocPut,"$TX+TC,\" \"$");
+  doc_e->tag_cb=&MorseTimes;
+
+  "$FG$\n";
+
+  dst=buf;
+  while (TRUE) {
+    ch=MorseWaitKey;
+    if (ch==CH_SPACE) {
+      *dst=0;
+      src=morse_lst;
+      while (*src) {
+        if (!StrCmp(src+1,buf)) {
+          "$GREEN$%C$FG$",*src;
+          break;
+        } else
+          src+=StrLen(src)+1;
+      }
+      '' CH_SPACE;
+      dst=buf;
+    } else {
+      if (dst-buf<sizeof(buf)-1) {
+        '' ch;
+        *dst++=ch;
+      }
+    }
+  }
+  Snd;
+}
+
+Morse;
+
+ diff --git a/public/Wb/Demo/Snd/OhGreat.HC.HTML b/public/Wb/Demo/Snd/OhGreat.HC.HTML new file mode 100755 index 0000000..0442692 --- /dev/null +++ b/public/Wb/Demo/Snd/OhGreat.HC.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+U0 Song()
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  try //Catch <CTRL-ALT-c> exit
+    while (!ScanChar) {
+      Play("6hEqDC5B6CDhE",
+            "God \0is \0a \0g\0od \0of \0love.\n\0");
+      Play("5GqFEFhG6E",
+            " \0 \0 \0 \0 \0He \0");
+      Play("6qDC5B6CDhE5G",
+            "wat\0ches \0us \0from \0a\0bove.\n\0 \0");
+      Play("5qFEFhGB6qC",
+            " \0 \0 \0 \0Our \0world \0");
+      Play("6DhCeDC5hBG",
+            "is\0n't \0al\0ways \0nice.\n\0 \0");
+      Play("5qFEFhG6EqD",
+            " \0 \0 \0 \0Be\0fore \0");
+      Play("6C5B6CDhE5G",
+            "you \0gr\0ipe \0think \0twice.\n\0 \0");
+      Play("5qFEFhG6EqD",
+            " \0 \0 \0 \0He \0wat\0");
+      Play("6C5B6CDhE5G",
+            "ches \0us \0from \0a\0bove.\n\0 \0");
+      Play("5qFEFhG6EqD",
+            " \0 \0 \0 \0He'll \0smack \0");
+      Play("6C5B6CDhE5G",
+            "you \0with \0out \0a \0glove.\n\0 \0");
+      Play("5qFEFhGB6qC",
+            " \0 \0 \0 \0Our \0world \0");
+      Play("6DhCeDC5hBG",
+            "is\0n't \0al\0ways \0nice.\n\0 \0");
+      Play("5qFEFhG");
+    }
+  catch
+    PutExcept;
+  '\n';
+  Snd;
+}
+
+Song;
+
+ diff --git a/public/Wb/Demo/Snd/WaterFowl.HC.HTML b/public/Wb/Demo/Snd/WaterFowl.HC.HTML new file mode 100755 index 0000000..53eea47 --- /dev/null +++ b/public/Wb/Demo/Snd/WaterFowl.HC.HTML @@ -0,0 +1,187 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+U8 *poem=
+"To a Waterfowl
+by William Cullen Bryant
+
+Whither, 'midst falling dew,
+While glow the heavens with the last steps of day,
+Far, through their rosy depths, dost thou pursue
+Thy solitary way?
+
+Vainly the fowler's eye
+Might mark thy distant flight to do thee wrong,
+As, darkly painted on the crimson sky,
+Thy figure floats along.
+
+Seek'st thou the plashy brink
+Of weedy lake, or marge of river wide,
+Or where the rocking billows rise and sink
+On the chafed ocean side?
+
+There is a Power whose care
+Teaches thy way along that pathless coast,--
+The desert and illimitable air,--
+Lone wandering, but not lost.
+
+All day thy wings have fann'd
+At that far height, the cold thin atmosphere:
+Yet stoop not, weary, to the welcome land,
+Though the dark night is near.
+
+And soon that toil shall end,
+Soon shalt thou find a summer home, and rest,
+And scream among thy fellows; reed shall bend
+Soon o'er thy sheltered nest.
+
+Thou'rt gone, the abyss of heaven
+Hath swallowed up thy form; yet, on my heart
+Deeply hath sunk the lesson thou hast given,
+And shall not soon depart.
+
+He, who, from zone to zone,
+Guides through the boundless sky thy certain flight,
+In the long way that I must tread alone,
+Will lead my steps aright.
+";
+
+#define POEM_COLS       53
+#define POEM_TIME       65.0
+
+F64 t0;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64   w=task->pix_width,h=task->pix_height;
+  F64   t=1.04-(0.35+0.65*Caw(tS-t0,20))`3,s=1.0-0.5*t,
+        x=w*t,y=h*(0.35-.1*t);
+  dc->color=WHITE;
+  GrPrint(dc,w>>1-(POEM_COLS*FONT_WIDTH)>>1,
+        Caw(tS-t0,POEM_TIME)*(h-3*FONT_HEIGHT),poem);
+  dc->color=BLACK;
+  GrLine(dc,x,y,x-8*s,y+6*s*FullTri(tS,0.4));
+  GrLine(dc,x,y,x+8*s,y+6*s*FullTri(tS,0.4));
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+//This specifies a callback routine
+  //to be called when the task dies.
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5eEDC4B5C4B5C4BA5qReEDC4B5C");
+    Play("4B5C4BA5qReFEDEDEDC4qB");
+    Play("5ReFEDEDEDC4BqR");
+  }
+}
+
+U0 WaterFowl()
+{
+  SettingsPush; //See SettingsPush
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  t0=tS;
+  Fs->draw_it=&DrawIt;
+  Sprite(<1>);
+  "%h*c",TEXT_ROWS-2,'\n';
+  GetChar;
+  DocClear;
+  SettingsPop;
+}
+
+WaterFowl;
+
+
+ diff --git a/public/Wb/Demo/SortFileDemo/F64FileGen.HC.HTML b/public/Wb/Demo/SortFileDemo/F64FileGen.HC.HTML new file mode 100755 index 0000000..23e53cd --- /dev/null +++ b/public/Wb/Demo/SortFileDemo/F64FileGen.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+//This makes a file of N random double values.
+
+Cd(__DIR__);;
+
+U0 F64FileGenTXT(U8 *filename,I64 n)
+{
+  I64 i;
+  CDoc *doc=DocNew(filename);
+  DocPrint(doc,"//This is unsorted.\n");
+  for (i=0;i<n;i++)
+    DocPrint(doc,"%12.6f\n",Rand);
+  DocWrite(doc);
+  DocDel(doc);
+}
+F64FileGenTXT("~/DemoUnsortedF64.DD.Z",10);
+
+U0 F64FileGenDAT(U8 *filename,I64 n)
+{//File/CFile, ::/Demo/Dsk/DataBase.HC
+  I64 i;
+  F64 *a=MAlloc(n*sizeof(F64));
+  for (i=0;i<n;i++)
+    a[i]=Rand;
+  FileWrite(filename,a,n*sizeof(F64));
+  Free(a);
+}
+F64FileGenDAT("~/DemoUnsortedF64.DATA.Z",10);
+
+ diff --git a/public/Wb/Demo/SortFileDemo/F64FileSort.HC.HTML b/public/Wb/Demo/SortFileDemo/F64FileSort.HC.HTML new file mode 100755 index 0000000..0db7c84 --- /dev/null +++ b/public/Wb/Demo/SortFileDemo/F64FileSort.HC.HTML @@ -0,0 +1,103 @@ + + + + + + + + + + + +
+//This takes an input file of doubles and makes a sorted output file.
+
+Cd(__DIR__);;
+
+I64 Compare(F64 e1,F64 e2)
+{
+  return Sign(e1-e2);
+}
+
+U0 F64FileSortTXT(U8 *in_name,U8 *out_name)
+{
+  CCmpCtrl *cc;
+  I64 i,n;
+  F64 *a;
+  CDoc *doc;
+
+  //Pass1: Count the number of F64s.
+  n=0;
+  cc=CmpCtrlNew(MStrPrint("#include \"%s\"",in_name));
+  while (Lex(cc))
+    if (cc->token==TK_F64)
+      n++;
+  CmpCtrlDel(cc);
+
+  a=MAlloc(n*sizeof(F64));
+
+  //Pass2: Read F64s.
+  i=0;
+  cc=CmpCtrlNew(MStrPrint("#include \"%s\"",in_name));
+  while (Lex(cc))
+    if (cc->token==TK_F64)
+      a[i++]=cc->cur_f64;
+  CmpCtrlDel(cc);
+
+  QSortI64(a,n,&Compare); //Sort 64-bit sized values
+
+  //Save
+  doc=DocNew(out_name);
+  DocPrint(doc,"//This is sorted.\n");
+  for (i=0;i<n;i++)
+    DocPrint(doc,"%12.6f\n",a[i]);
+  DocWrite(doc);
+  DocDel(doc);
+
+  Free(a);
+}
+F64FileSortTXT("~/DemoUnsortedF64.DD.Z","~/DemoSortedF64.DD.Z");
+Type("~/DemoUnsortedF64.DD.Z");
+Type("~/DemoSortedF64.DD.Z");
+
+U0 F64FileSortDAT(U8 *in_name,U8 *out_name)
+{//File/CFile, ::/Demo/Dsk/DataBase.HC
+  I64 size;
+  F64 *a=FileRead(in_name,&size);
+  QSortI64(a,size/sizeof(F64),&Compare); //Sort 64-bit sized values
+  FileWrite(out_name,a,size);
+  Free(a);
+}
+F64FileSortDAT("~/DemoUnsortedF64.DATA.Z","~/DemoSortedF64.DATA.Z");
+
+U0 F64FileDumpDAT(U8 *in_name)
+{//File/CFile, ::/Demo/Dsk/DataBase.HC
+  I64 i,n,size;
+  F64 *a=FileRead(in_name,&size);
+  n=size/sizeof(F64);
+  "%s\n",in_name;
+  for (i=0;i<n;i++)
+    "%12.6f\n",a[i];
+  Free(a);
+}
+F64FileDumpDAT("~/DemoUnsortedF64.DATA.Z");
+F64FileDumpDAT("~/DemoSortedF64.DATA.Z");
+
+ diff --git a/public/Wb/Demo/Spy.HC.HTML b/public/Wb/Demo/Spy.HC.HTML new file mode 100755 index 0000000..1ca6169 --- /dev/null +++ b/public/Wb/Demo/Spy.HC.HTML @@ -0,0 +1,93 @@ + + + + + + + + + + + +
+//Pass the task structure you
+//wish to spy upon.
+
+U0 SpyStkRep(CTask *task)
+{
+  CDoc *doc=DocDblBufStart;
+  while (!ScanChar && TaskValidate(task)) {
+    StkRep(task);
+    '\n';
+    "$BK,1$PRESS A KEY$BK,0$\n";
+    DocDblBufSwap;
+    Refresh;
+  }
+  if (DocPut==doc) DocDblBufSwap;
+  DocDblBufEnd;
+}
+
+U0 SpyCallerRep(CTask *task)
+{
+  CDoc *doc=DocDblBufStart;
+  while (!ScanChar && TaskValidate(task)) {
+    CallerRep(task->rbp,task);
+    '\n';
+    "$BK,1$PRESS A KEY$BK,0$\n";
+    DocDblBufSwap;
+    Refresh;
+  }
+  if (DocPut==doc) DocDblBufSwap;
+  DocDblBufEnd;
+}
+
+U0 Spy()
+{
+  I64 i;
+  CTask *task;
+
+  while (TRUE) {
+    task=Fs->next_task;
+    while (task!=Fs) {
+      "$MA+X,T=\"Task:%08X:%16ts\",LM=\"0x%08X\n\"$\n",
+            task,task->task_name,task;
+      task=task->next_task;
+    }
+    '\n';
+    task=GetI64("Task Addr: ",0);
+    if (TaskValidate(task)) {
+      "\n\n\t$BT,\"StkRep\",LM=\"1\n\"$\n\n\n"
+            "\n\n\t$BT,\"CallerRep\",LM=\"2\n\"$\n\n\n";
+      i=GetI64("",0);
+      if (i==1)
+        SpyStkRep(task);
+      else if (i==2)
+        SpyCallerRep(task);
+      else
+        break;
+    } else
+      break;
+  }
+  '\n';
+}
+
+Spy;
+
+ diff --git a/public/Wb/Demo/StkGrow.HC.HTML b/public/Wb/Demo/StkGrow.HC.HTML new file mode 100755 index 0000000..e96850b --- /dev/null +++ b/public/Wb/Demo/StkGrow.HC.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+I64 Recurse(I64 n)
+{
+  if (n)
+    return 1+CallStkGrow(0x800,0x1000000,&Recurse,n-1);
+  else
+    return 0;
+}
+
+I64 Recurse2(I64 n)
+{
+  if (n)
+    return 1+Recurse2(n-1);
+  else
+    return 0;
+}
+
+I64 Recurse3(I64 n,I64 lo,I64 hi)
+{
+  if (lo<=n<hi)
+    return 1+Recurse3(n-1,lo,hi);
+  else if (n)
+    return Recurse3(n-1,lo,hi);
+  else
+    return 0;
+}
+
+#define DEPTH   (2*1024*1024)
+
+U0 StkGrowDemo()
+{
+  F64 t0;
+
+  t0=tS;
+  "%X:%X\n",DEPTH,Recurse(DEPTH);
+  "Time:%7.5fs\n",tS-t0;
+
+  //If you know the max stack ahead of time...
+  //Recurse2's stack is 16 because you have 1 arg,
+  //a return addr and no local variables.
+  t0=tS;
+  "%X:%X\n",DEPTH,CallStkGrow(DEPTH*16+0x800,DEPTH*16+0x800,&Recurse2,DEPTH);
+  "Time:%7.5fs\n",tS-t0;
+
+  //CallStkGrow() works with multiple args.
+  t0=tS;
+  "%X:%X\n",DEPTH,CallStkGrow(DEPTH*32+0x800,DEPTH*32+0x800,
+        &Recurse3,DEPTH,1000,2000);
+  "Time:%7.5fs\n",tS-t0;
+}
+
+StkGrowDemo;
+
+//Be careful because you can fragment memory.
+
+ diff --git a/public/Wb/Demo/SubIntAccess.HC.HTML b/public/Wb/Demo/SubIntAccess.HC.HTML new file mode 100755 index 0000000..b5a2d4f --- /dev/null +++ b/public/Wb/Demo/SubIntAccess.HC.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+/*TempleOS has a feature that allows
+access to bytes and words of larger
+ints.
+
+See U64i union.
+ 
+The versions with "i" are internal data types.
+Use "I64" instead of "U64i" and you
+will have access to subbytes and
+subwords.
+
+Unfortunately, byte access causes the
+compiler to not use a reg for the
+variable.
+
+See ::/Demo/Lectures/FixedPoint.HC.
+*/
+
+I64 q=0xFEDCBA9876543210,q1;
+
+"q\t\t=%016X\n",q;
+q1=q.i16[2];
+"q.i16[2]\t=%016X\n",q1;
+q1=q.u8[5];
+"q.u8[5]\t\t=%016X\n",q1;
+q1=q.i32[1].u8[2];
+"q.i32[1].u8[2]\t=%016X\n",q1;
+q1=q.i32[0].i8[1];
+"q.i32[0].i8[1]\t=%016X\n",q1;
+
+ diff --git a/public/Wb/Demo/SubSwitch.HC.HTML b/public/Wb/Demo/SubSwitch.HC.HTML new file mode 100755 index 0000000..3b4be5a --- /dev/null +++ b/public/Wb/Demo/SubSwitch.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+U0 SubSwitch()
+{
+  I64 i;
+  for (i=0;i<10;i++)
+    switch (i) {
+      case 0: "Zero ";  break;
+      case 2: "Two ";   break;
+      case 4: "Four ";  break;
+      start:
+        "[";
+        case 1: "One";  break;
+        case 3: "Three";break;
+        case 5: "Five"; break;
+      end:
+        "] ";
+        break;
+    }
+  '\n';
+}
+
+SubSwitch;
+
+ diff --git a/public/Wb/Demo/SuggestSpelling.HC.HTML b/public/Wb/Demo/SuggestSpelling.HC.HTML new file mode 100755 index 0000000..09a3de9 --- /dev/null +++ b/public/Wb/Demo/SuggestSpelling.HC.HTML @@ -0,0 +1,123 @@ + + + + + + + + + + + +
+/*This does a really crappy job of
+suggesting spellings.  Write a better
+one for fun.
+*/
+
+U8 *SuggestMatchForm(U8 *src)
+{
+  I64 ch,ch1=0;
+  U8 *res=MStrUtil(src,SUF_TO_UPPER),*dst;
+  dst=src=res;
+  while (ch=*src++)  {
+    if (!StrOcc("AEIOU",ch)) {
+      if (ch=='C') ch='K';
+      if (ch=='Z') ch='S';
+      if (ch!=ch1) //double chars to single
+        *dst++=ch;
+    }
+    ch1=ch;
+  }
+  *dst=0;
+  return res;
+}
+
+/*Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block; //definition offset in ::/Adam/AutoComplete/ACDefs.DATA
+*/
+
+Bool SuggestSpelling(U8 *word)
+{
+  U8 *dict=acd.word_lst,
+        *pf=SuggestMatchForm(word),
+        *wf;
+  I64 len=StrLen(pf),
+        num_cols=Fs->win_width/16,
+        col=0;
+  if (len)
+    while (*dict) {
+      wf=SuggestMatchForm(dict+1);
+      if (!StrNCmp(pf,wf,len)) {
+        "%16s",dict+1;
+        if (++col>=num_cols) {
+          col=0;
+          '\n';
+        }
+      }
+      Free(wf);
+      dict+=StrLen(dict+1)+4;
+    }
+  Free(pf);
+  '\n';
+  return ToBool(len);
+}
+
+U0 SuggestSpellingDemo()
+{
+  U8 *w;
+  while (TRUE) {
+    w=GetStr("Word:");
+    if (*w) {
+      SuggestSpelling(w);
+      Free(w);
+    } else
+      break;
+  }
+}
+
+//If you "Adam Include" this file, it will
+//install this command as a hot-key.
+
+U0 CtrlAltL(I64)
+{
+//ac.cur_word is only set if AutoComplete
+  //is running.
+  if (!TaskValidate(ac.task)) {
+    AutoComplete(ON);
+    Sleep(500);
+  }
+  PopUp("if (SuggestSpelling(ac.cur_word)) View;");
+}
+
+if (Fs!=adam_task)
+  SuggestSpellingDemo;
+else {
+  CtrlAltCBSet('L',&CtrlAltL,"Cmd /Suggest Spelling");
+//Appears in the Adam Task Window
+  "<CTRL-ALT-l> installed\n";
+}
+
+//Note: It would be more appropriate
+//to define a key in MyPutKey().
+
+ diff --git a/public/Wb/Demo/Templates/Game1.HC.HTML b/public/Wb/Demo/Templates/Game1.HC.HTML new file mode 100755 index 0000000..302b77a --- /dev/null +++ b/public/Wb/Demo/Templates/Game1.HC.HTML @@ -0,0 +1,121 @@ + + + + + + + + + + + +
+U0 DrawIt(CTask *task,CDC *dc)
+{
+}
+
+U0 AnimateTask(I64)
+{
+  while (TRUE) {
+    Sleep(10);
+  }
+}
+
+U0 Init()
+{
+}
+
+U0 CleanUp()
+{
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("4AB5C");
+  }
+}
+
+U0 MyGame()
+{
+  I64 sc;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE)
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              break;
+            case SC_CURSOR_RIGHT:
+              break;
+            case SC_CURSOR_UP:
+              break;
+            case SC_CURSOR_DOWN:
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto mg_done;
+      }
+mg_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+MyGame;
+
+ diff --git a/public/Wb/Demo/Templates/Lex1.HC.HTML b/public/Wb/Demo/Templates/Lex1.HC.HTML new file mode 100755 index 0000000..017fd25 --- /dev/null +++ b/public/Wb/Demo/Templates/Lex1.HC.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+U0 MyRead(U8 *filename)
+{
+  CCmpCtrl *cc=CmpCtrlNew(MStrPrint("#include \"%s\"",filename));
+  while (Lex(cc)) {
+    "%03d:",cc->token;
+    switch (cc->token) {
+        case TK_IDENT:          "IDENT:%s",cc->cur_str; break;
+        case TK_STR:            "STR:%s",cc->cur_str;   break;
+        case TK_CHAR_CONST:     "CHAR:%d",cc->cur_i64;  break;
+        case TK_I64:            "I64:%d",cc->cur_i64;   break;
+        case TK_F64:            "F64:%d",cc->cur_f64;   break;
+    }
+    '\n';
+  }
+  CmpCtrlDel(cc);
+}
+
+ diff --git a/public/Wb/Demo/Templates/MultiCore1.HC.HTML b/public/Wb/Demo/Templates/MultiCore1.HC.HTML new file mode 100755 index 0000000..f3de0be --- /dev/null +++ b/public/Wb/Demo/Templates/MultiCore1.HC.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+#define NUM     100
+
+I64 mp_not_done_flags,grand_total;
+
+U0 MPRoutine(CDoc *doc)
+{
+  I64 i,sum=0,
+        lo=NUM*Gs->num/mp_cnt,          //This is how to divide a job
+        hi=NUM*(Gs->num+1)/mp_cnt;
+  for (i=lo;i<hi;i++)
+    sum+=i;
+  DocPrint(doc,"Core#%d:%d-%d:%d\n",Gs->num,lo,hi-1,sum);
+  lock {grand_total+=sum;}
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 Main()
+{
+  I64 i;
+  grand_total=0;
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    Spawn(&MPRoutine,DocPut,NULL,i);
+  while (mp_not_done_flags)
+    Yield;
+  "Grand total:%d\n",grand_total;
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Templates/ODE1.HC.HTML b/public/Wb/Demo/Templates/ODE1.HC.HTML new file mode 100755 index 0000000..4740c62 --- /dev/null +++ b/public/Wb/Demo/Templates/ODE1.HC.HTML @@ -0,0 +1,74 @@ + + + + + + + + + + + +
+class MyMass:CMass
+{
+  F64 radius;
+};
+
+class MySpring:CSpring
+{
+};
+
+CMathODE *ode=NULL;
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+  MyMass *tmpm1,*tmpm2;
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+}
+
+U0 Init()
+{
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  QueRem(ode);
+  QueDel(&ode->next_mass,TRUE);
+  QueDel(&ode->next_spring,TRUE);
+  ODEDel(ode);
+}
+
+ diff --git a/public/Wb/Demo/Templates/Registry1.HC.HTML b/public/Wb/Demo/Templates/Registry1.HC.HTML new file mode 100755 index 0000000..bd62809 --- /dev/null +++ b/public/Wb/Demo/Templates/Registry1.HC.HTML @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+RegDft("MyCompany/MyApp","F64 best_score=9999;\n");
+RegExe("MyCompany/MyApp");
+
+U0 Main()
+{
+  GetChar;
+  RegWrite("MyCompany/MyApp","F64 best_score=%5.4f;\n",best_score);
+}
+
+Main;
+
+ diff --git a/public/Wb/Demo/Templates/Util1.HC.HTML b/public/Wb/Demo/Templates/Util1.HC.HTML new file mode 100755 index 0000000..170c043 --- /dev/null +++ b/public/Wb/Demo/Templates/Util1.HC.HTML @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+U0 MyUtil(U8 *files_find_mask,U8 *fu_flags=NULL)
+{
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    PutFileLink(tmpde->full_name);
+    '\n';
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Demo/Templates/Util2.HC.HTML b/public/Wb/Demo/Templates/Util2.HC.HTML new file mode 100755 index 0000000..40fb7b8 --- /dev/null +++ b/public/Wb/Demo/Templates/Util2.HC.HTML @@ -0,0 +1,85 @@ + + + + + + + + + + + +
+I64 MyUtilDoc(CDoc *doc,I64 fuf_flags)
+{
+  Bool unlock=DocLock(doc);
+  I64 res=0;
+  CDocEntry *doc_e;
+  DocRecalc(doc);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    res++;
+    doc_e=doc_e->next;
+  }
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+I64 MyUtilFile(U8 *filename,I64 fuf_flags)
+{
+  I64 res;
+  CDoc *doc=DocRead(filename);
+  if (res=MyUtilDoc(doc,fuf_flags)) {
+    "%8d:%s\n",res,doc->filename.name;
+    DocWrite(doc);
+  }
+  DocDel(doc);
+  return res;
+}
+I64 MyUtilLst(CDirEntry *tmpde,I64 fuf_flags)
+{
+  I64 res=0;
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      if (tmpde->sub) {
+        "Processing Directory: %s\n",tmpde->full_name;
+        res+=MyUtilLst(tmpde->sub,fuf_flags);
+      }
+    } else
+      res+=MyUtilFile(tmpde->full_name,fuf_flags);
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+  return res;
+}
+I64 MyUtil(U8 *files_find_mask="*",U8 *fu_flags=NULL)
+{
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+$");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  return MyUtilLst(FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND),
+        fuf_flags&~FUG_FILES_FIND);
+}
+
+ diff --git a/public/Wb/Demo/TimeIns.HC.HTML b/public/Wb/Demo/TimeIns.HC.HTML new file mode 100755 index 0000000..9331d31 --- /dev/null +++ b/public/Wb/Demo/TimeIns.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+/*Allows you to time insts.
+Results vary because the CPU does
+parallel and out-of-order execution.
+*/
+
+#define SAMPLE_SIZE     10000000
+
+U0 TimeIns()
+{
+  I64 i,start,end,overhead_time,test_time;
+  F64 d=5.0;
+
+  //Measure Loop Overhead
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++);
+  end=GetTSC;
+  overhead_time=end-start;
+  "\nOverhead Cycles:%12.6f\n",ToF64(overhead_time)/SAMPLE_SIZE;
+
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++) {
+    #exe {PassTrace(0b10000000000);};
+//Time these insts
+    d*=1.00001;
+    #exe {PassTrace(0);};
+  }
+  end=GetTSC;
+  test_time=end-start;
+
+  "Measured Cycles:%12.6f\n",ToF64(test_time-overhead_time)/SAMPLE_SIZE;
+}
+
+TimeIns;
+TimeIns;
+TimeIns;
+
+ diff --git a/public/Wb/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML b/public/Wb/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML new file mode 100755 index 0000000..eb1585a --- /dev/null +++ b/public/Wb/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+/* This converts ::/Demo/ToHtmlToTXTDemo/DemoInPage.DD to
+an html document named "OutPage.html".
+
+Notice that an entry like $TX,"GOOGLE",HTML="http://www.google.com"$
+will be converted to text in the html with an html link.
+
+I cheated by hardcoding www.templeos.org as the website
+for TempleOS Links.  Why don't you copy
+::/Demo/ToHtmlToTXTDemo/ToHtml.HC to your /Home directory
+and modify it?  You are welcome to link to
+http://www.templeos.org if you want file that come on the
+TempleOS distribution.
+
+You can pass html meta data as args to ToHtml().
+*/
+
+Cd(__DIR__);;
+#include "ToHtml"
+
+ToHtml("DemoInPage.DD.Z","~/DemoOutPage");
+
+ diff --git a/public/Wb/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML b/public/Wb/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML new file mode 100755 index 0000000..879e810 --- /dev/null +++ b/public/Wb/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+/* This converts ::/Demo/ToHtmlToTXTDemo/DemoInPage.DD to
+an plain ASCII text document named, "OutPage.DD".
+
+*/
+
+Cd(__DIR__);;
+
+ToTXT("DemoInPage.DD.Z","~/DemoOutPage");
+
+ diff --git a/public/Wb/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML b/public/Wb/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML new file mode 100755 index 0000000..8568ccd --- /dev/null +++ b/public/Wb/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML @@ -0,0 +1,420 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Conversion"
+
+//See ::/Doc/Credits.DD.
+
+#define DOCET_UNDEF_COLOR       0x100000000
+#define DOCET_LINK_UNDERLINE    0x200000000
+U0 HtmlPutS(CDoc *doc,I64 u32_attr,I64 *_old_u32_attr,Bool underline_update,
+        U8 *st,I64 *_col,U8 *style_bitmap=NULL)
+{
+  U8 *ch,*ptr;
+  u32_attr&=0xFFFFFF00;
+  if (u32_attr&DOCET_INVERT)
+    u32_attr.u8[1]=(u32_attr.u8[1]&15)<<4|u32_attr.u8[1]>>4;
+  if (underline_update &&
+        !(u32_attr&DOCET_UNDERLINE) && *_old_u32_attr&DOCET_UNDERLINE) {
+    if (!(*_old_u32_attr&DOCET_LINK_UNDERLINE))
+      DocPrint(doc,"</u>");
+    *_old_u32_attr&=~DOCET_LINK_UNDERLINE;
+  }
+  if (!(u32_attr&DOCET_BLINK) && *_old_u32_attr&DOCET_BLINK)
+    DocPrint(doc,"</blink>");
+  if (u32_attr&0xFF00!=*_old_u32_attr&0xFF00) {
+    if (!(*_old_u32_attr&DOCET_UNDEF_COLOR))
+      DocPrint(doc,"</span>");
+    DocPrint(doc,"<span class=c%02X>",u32_attr.u8[1]);
+    if (style_bitmap)
+      LBts(style_bitmap,u32_attr.u8[1]);
+  }
+  if (u32_attr&DOCET_BLINK && !(*_old_u32_attr&DOCET_BLINK))
+    DocPrint(doc,"<blink>");
+  if (underline_update) {
+    if (u32_attr&DOCET_UNDERLINE && !(*_old_u32_attr&DOCET_UNDERLINE))
+      DocPrint(doc,"<u>");
+  } else //Keep same underline status.
+    u32_attr=u32_attr&~DOCET_UNDERLINE | *_old_u32_attr&DOCET_UNDERLINE;
+
+  *_old_u32_attr=u32_attr | *_old_u32_attr&DOCET_LINK_UNDERLINE;
+
+  while (ch=*st++) {
+    switch (ch) {
+      case '\t':
+        do {
+          DocPutKey(doc,CH_SPACE,0);
+          *_col=*_col+1;
+        } while (*_col&7);
+        break;
+
+      start:
+        case 'pi':      ptr="pi";       break;
+        case 'theta':   ptr="theta";    break;
+        case 'phi':     ptr="phi";      break;
+        case 'omega':   ptr="omega";    break;
+        case 'inf':     ptr="inf";      break;
+        case 'u':       ptr="u";        break;
+      end:
+        DocPrint(doc,ptr);
+        *_col=*_col+StrLen(ptr);
+        break;
+
+      start:
+        case CH_SHIFT_SPACE: ptr=" ";   break;
+        case '&':       ptr="&amp;";    break;
+        case '<':       ptr="&lt;";     break;
+        case '>':       ptr="&gt;";     break;
+        case '"':       ptr="&quot;";   break;
+      end:
+        DocPrint(doc,ptr);
+        *_col=*_col+1;
+        break;
+
+      default:
+        if (CH_SPACE<=ch<0x7F || ch=='\n')
+          DocPutKey(doc,ch,0);
+        else
+          DocPrint(doc,".");
+        *_col=*_col+1;
+    }
+  }
+}
+
+U8 *TOSLinkCvt2(U8 *filename,I64 line_num)
+{// ::/  --> http://www.templeos.org/Wb/
+//Make your own LinkCvt routine
+  U8 *res=NULL,*st;
+  if (filename) {
+    st=ExtChg(filename,"html");
+    if (st && StrLen(st)>3 && !StrNCmp(st+1,":/",2))
+      res=MStrPrint("http://www.templeos.org/Wb/%s#l%d",st+3,line_num);
+    Free(st);
+  }
+  return res;
+}
+
+U8 *URLBibleGateway(U8 *src)
+{
+  U8 buf[STR_LEN],*dst=buf;
+  if (!MemCmp(src,"BF:",3))
+    src+=3;
+  while (*src) {
+    if (*src==CH_SPACE || *src==',')
+      *dst++='+';
+    else
+      *dst++=*src;
+    src++;
+  }
+  *dst=0;
+  if (StrOcc(buf,'-'))
+    return MStrPrint(
+          "http://www.biblegateway.com/passage/?search=%s&version=NIV",buf);
+  else
+    return MStrPrint(
+          "http://www.biblegateway.com/verse/en/%s",buf);
+}
+
+U8 *TOSLinkCvt1(U8 *link_st)
+{
+  static CDoc *bible=NULL;
+  static I64 locks=0;
+  U8 *res=NULL,*filename,*needle;
+  I64 i,num;
+  if (link_st) {
+    switch (i=EdLinkCvt(link_st,&filename,&needle,&num)) {
+      case LK_FILE_LINE:
+      case LK_PLAIN_LINE:
+      case LK_FILE:
+        res=TOSLinkCvt2(filename,num);
+        break;
+      case -1:
+      case LK_DEF:
+      case LK_HELP_INDEX:
+      case LK_DOC:
+      case LK_DOC_ANCHOR:
+      case LK_DOC_FIND:
+      case LK_DOC_LINE:
+        break;
+      case LK_BIBLE_FIND:
+        while (LBts(&locks,0))
+          Yield;
+        if (!bible)
+          bible=Adam("DocRead(\"%s\");",filename);
+        if (DocFind(bible,num,needle))
+          res=URLBibleGateway(link_st);
+        LBtr(&locks,0);
+        break;
+      default:
+        if (DocFileEd(i,filename,needle,&num,EDF_UNCOLLAPSE|EDF_BAIL))
+          res=TOSLinkCvt2(filename,num);
+    }
+    Free(filename);
+    Free(needle);
+  }
+  return res;
+}
+
+public CDoc *Doc2Html(CDoc *doc_in,U8 *html_header=NULL,U8 *body_header=NULL,
+        U8 *body_footer=NULL,U8 *html_footer=NULL,Bool line_anchors=TRUE,
+        U8 (*link_cvt)(U8 *link_st)=&TOSLinkCvt1,Bool line_nums=FALSE)
+{//Cvt DolDocdoc to HTML file.
+  CDocEntry *doc_e,*style,*doc_e2;
+  I64 i,y,old_y=I64_MIN,col,old_u32_attr=DOCET_UNDEF_COLOR,old_attr,digits;
+  U32 *hl,*src;
+  U8 *st,st_2[2],*link_st,*style_bitmap=CAlloc(256/8);
+  CBGR48 p[COLORS_NUM];
+  GrPaletteGet(p);
+  CDoc *doc_out=DocNew;
+  Bool unlock_doc_in=DocLock(doc_in),no_bwd;
+
+  old_attr=doc_in->win_task->text_attr;
+  doc_in->win_task->text_attr=DOC_ATTR_DFT_TEXT;
+
+  for (i=0xF0;i<=0xFF;i++)
+    LBts(style_bitmap,i);
+
+  DocRecalc(doc_in,RECALCt_NORMAL|RECALCF_TO_HTML);
+
+  digits=Log10(doc_in->head.last->y+1)+1;
+
+  st_2[0]=0; st_2[1]=0;
+  doc_out->flags|=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+
+  if (!html_header) html_header=
+          "<!DOCTYPE HTML>\n"
+          "<html>\n"
+          "<head>\n"
+          "<meta http-equiv=\"Content-Type\" "
+          "content=\"text/html;charset=US-ASCII\">\n"
+          "<meta name=\"generator\" content=\"TempleOS V5.03\">\n";
+  if (!body_header) body_header=
+          "<body>\n"
+          "<pre style=\"font-family:courier;font-size:10pt\">\n";
+  if (!body_footer) body_footer=
+          "</pre></body>\n";
+  if (!html_footer) html_footer=
+          "</html>\n";
+
+  DocPrint(doc_out,"%s",html_header);
+
+  DocPrint(doc_out,"<style type=\"text/css\">\n");
+  style=doc_out->cur_entry->last;
+  DocPrint(doc_out,
+        "</style>\n"
+        "</head>\n");
+  DocPrint(doc_out,"%s",body_header);
+
+  doc_e=doc_in->head.next;
+  col=doc_e->x;
+  y=doc_e->y;
+  while (doc_e!=doc_in) {
+    if (!(doc_e->de_flags&DOCEF_SKIP)) {
+      if (y!=old_y) {
+        if (line_anchors)
+          DocPrint(doc_out,"<a name=\"l%d\"></a>",y+1);
+        if (line_nums)
+          DocPrint(doc_out,"%0*d ",digits,y+1);
+        old_y=y;
+      }
+      while (y<doc_e->y) {
+        HtmlPutS(doc_out,doc_e->settings.final_u32_attr,&old_u32_attr,FALSE,
+              "\n",&col,style_bitmap);
+        if (++y!=old_y) {
+          if (line_anchors)
+            DocPrint(doc_out,"<a name=\"l%d\"></a>",y+1);
+          if (line_nums)
+            DocPrint(doc_out,"%0*d ",digits,y+1);
+          old_y=y;
+        }
+        col=0;
+      }
+
+      no_bwd=TRUE;
+      doc_e2=doc_e->next;
+      while (doc_e2!=doc_in && doc_e2->y==doc_e->y) {
+        if (doc_e2->x<doc_e->x) {
+          no_bwd=FALSE;
+          break;
+        }
+        doc_e2=doc_e2->next;
+      }
+
+      if (no_bwd)
+        while (col<doc_e->x)
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr&~DOCET_UNDERLINE,
+                &old_u32_attr,TRUE," ",&col,style_bitmap);
+
+      link_st=NULL;
+      if (doc_e->de_flags&DOCEF_HTML_LINK)
+        link_st=StrNew(doc_e->html_link);
+      else if (st=DocEntryLink(doc_in,doc_e)) {
+        link_st=link_cvt(st);
+        Free(st);
+      }
+
+      if (link_st) {
+        if (old_u32_attr&DOCET_UNDERLINE &&!(old_u32_attr&DOCET_LINK_UNDERLINE))
+          DocPrint(doc_out,"</u>");
+        if (old_u32_attr&DOCET_BLINK)
+          DocPrint(doc_out,"</blink>");
+        if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+          DocPrint(doc_out,"</span>");
+        old_u32_attr=DOCET_UNDEF_COLOR|DOCET_UNDERLINE|DOCET_LINK_UNDERLINE;
+        DocPrint(doc_out,"<a href=\"%s\">",link_st);
+      }
+
+      switch (doc_e->type_u8) {
+        case DOCT_TEXT:
+          if (doc_e->de_flags&DOCEF_HIGHLIGHT) {
+            if (doc_e->last==doc_in)
+              MemCpy(&doc_e->settings,&doc_in->settings_head,
+                    sizeof(CDocSettings));
+            else
+              MemCpy(&doc_e->settings,&doc_e->last->settings,
+                    sizeof(CDocSettings));
+            src=hl=DocHighlight(doc_e,doc_e->tag,StrLen(doc_e->tag),
+                  doc_e->type&0xFF00);
+            while (*src) {
+              st_2[0]=*src&0xFF;
+              HtmlPutS(doc_out,*src++,&old_u32_attr,TRUE,
+                    st_2,&col,style_bitmap);
+            }
+            Free(hl);
+          } else
+            HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                  &old_u32_attr,TRUE,doc_e->tag,&col,style_bitmap);
+          break;
+        case DOCT_TAB:
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr,&old_u32_attr,TRUE,
+                "\t",&col,style_bitmap);
+          break;
+        case DOCT_HTML_CODE:
+          if (old_u32_attr&DOCET_UNDERLINE &&
+                !(old_u32_attr&DOCET_LINK_UNDERLINE))
+            DocPrint(doc_out,"</u>");
+          if (old_u32_attr&DOCET_BLINK)
+            DocPrint(doc_out,"</blink>");
+          if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+            DocPrint(doc_out,"</span>");
+          old_u32_attr=DOCET_UNDEF_COLOR;
+          DocPrint(doc_out,"%s",doc_e->tag);
+          break;
+        case DOCT_SPRITE:
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                &old_u32_attr,TRUE,doc_e->tag,&col,style_bitmap);
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                &old_u32_attr,TRUE,"/* Graphics Not Rendered in HTML */",
+                &col,style_bitmap);
+          break;
+        default:
+          if (doc_e->de_flags&DOCEF_TAG)
+            HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                  &old_u32_attr,TRUE,doc_e->tag,&col,style_bitmap);
+      }
+      if (link_st) {
+        if (old_u32_attr&DOCET_UNDERLINE &&!(old_u32_attr&DOCET_LINK_UNDERLINE))
+          DocPrint(doc_out,"</u>");
+        if (old_u32_attr&DOCET_BLINK)
+          DocPrint(doc_out,"</blink>");
+        if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+          DocPrint(doc_out,"</span>");
+        DocPrint(doc_out,"</a>");
+        old_u32_attr=DOCET_UNDEF_COLOR|DOCET_UNDERLINE|DOCET_LINK_UNDERLINE;
+        Free(link_st);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  while (y++<doc_e->y) {
+    HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+          &old_u32_attr,TRUE,"\n",&col,style_bitmap);
+    col=0;
+  }
+  if (old_u32_attr&DOCET_UNDERLINE && !(old_u32_attr&DOCET_LINK_UNDERLINE))
+    DocPrint(doc_out,"</u>");
+  if (old_u32_attr&DOCET_BLINK)
+    DocPrint(doc_out,"</blink>");
+  if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+    DocPrint(doc_out,"</span>");
+  old_u32_attr=DOCET_UNDEF_COLOR;
+  DocPrint(doc_out,"%s",body_footer);
+  DocPrint(doc_out,"%s",html_footer);
+
+  doc_out->cur_entry=style->next;
+  for (i=0;i<256;i++)
+    if (Bt(style_bitmap,i))
+      DocPrint(doc_out,
+            ".c%02X{color:#%02x%02x%02x;background-color:#%02x%02x%02x;}\n",
+            i,p[i&15].r>>8,p[i&15].g>>8,p[i&15].b>>8,
+            p[i/16].r>>8,p[i/16].g>>8,p[i/16].b>>8);
+  doc_out->cur_entry=&doc_out->head;
+  DocRecalc(doc_out);
+
+  doc_in->win_task->text_attr=old_attr;
+
+  if (unlock_doc_in)
+    DocUnlock(doc_in);
+  return doc_out;
+}
+
+#help_index "Cmd Line (Typically);DolDoc/Conversion;DolDoc/Cmd Line (Typically)"
+public U0 ToHtml(U8 *_in_name,U8 *_out_name=NULL,U8 *html_header=NULL,
+        U8 *body_header=NULL,U8 *body_footer=NULL,U8 *html_footer=NULL,
+        I64 width=80,Bool line_anchors=TRUE,
+        U8 (*link_cvt)(U8 *link_st)=&TOSLinkCvt1,Bool line_nums=FALSE)
+{//Convert DolDocfile to HTML.
+//Supply your own link_cvt routine.
+  U8 *in_name,*out_name;
+  CDoc *doc_in,*doc_out;
+
+  SettingsPush; //See SettingsPush
+  WinHorz(0,width-1); //Sets doc width for word wrap.
+
+  in_name=ExtDft(_in_name,"HC.Z");
+  if (_out_name)
+    out_name=ExtDft(_out_name,"html");
+  else
+    out_name=ExtChg(_in_name,"html");
+
+  doc_in=DocRead(in_name);
+  doc_out=Doc2Html(doc_in,html_header,body_header,body_footer,html_footer,
+        line_anchors,link_cvt,line_nums);
+  StrCpy(&doc_out->filename.name,out_name);
+
+  SettingsPop;
+
+  DocWrite(doc_out);
+  DocDel(doc_in);
+  DocDel(doc_out);
+  Free(in_name);
+  Free(out_name);
+}
+
+ diff --git a/public/Wb/Demo/WebLogDemo/WebLogRep.HC.HTML b/public/Wb/Demo/WebLogDemo/WebLogRep.HC.HTML new file mode 100755 index 0000000..b362a8a --- /dev/null +++ b/public/Wb/Demo/WebLogDemo/WebLogRep.HC.HTML @@ -0,0 +1,559 @@ + + + + + + + + + + + +
+#define DOWNLOAD_FILE1          "TOS_Distro.ISO"
+#define DOWNLOAD_FILE1_SIZE     16000000
+
+#define HOURS_MAX               (24*3)
+
+class LogStruct
+{
+  LogStruct *next,*last;
+  LogStruct *ip_num_left,*ip_num_right;
+  U32 ip_num,code;
+  I64 size;
+  U8 *file,*link;
+  CDate datetime;
+};
+
+class LinkStruct
+{
+  LinkStruct *left,*right;
+  U8 *link,*file;
+  I64 cnt;
+};
+
+class BlockedStruct
+{
+  BlockedStruct *next,*last;
+  U32 ip_num;
+};
+
+U0 LogStructDel(LogStruct *tmplg)
+{
+  Free(tmplg->file);
+  Free(tmplg->link);
+  Free(tmplg);
+}
+
+U0 PrsSingleLogFile(LogStruct *head,U8 *name,CDate *_dstart,CDate *_dend)
+{
+  CDoc *doc=DocRead(name,
+        DOCF_PLAIN_TEXT_TABS|DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next;
+  U8 *src,*src2,*mon_lst=Define("ST_MONTHS");
+  LogStruct *tmplg;
+  CDateStruct ds;
+  I64 i;
+  "%$Q\n",name;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      tmplg=CAlloc(sizeof(LogStruct));
+      try {
+        src=doc_e->tag;
+        tmplg->ip_num.u8[3]=Str2I64(src,10,&src);
+        if (*src++!='.') throw;
+        tmplg->ip_num.u8[2]=Str2I64(src,10,&src);
+        if (*src++!='.') throw;
+        tmplg->ip_num.u8[1]=Str2I64(src,10,&src);
+        if (*src++!='.') throw;
+        tmplg->ip_num.u8[0]=Str2I64(src,10,&src);
+
+        do if (!*src) throw;
+        while (*src++!='[');
+        MemSet(&ds,0,sizeof(CDateStruct));
+        ds.day_of_mon=Str2I64(src,10,&src);
+        if (*src++!='/') throw;
+        src2=src;
+        do if (!*src2) throw;
+        while (*src2++!='/');
+        * --src2=0;
+        ds.mon=1+LstMatch(src,mon_lst,LMF_IGNORE_CASE);
+        src=++src2;
+        ds.year=Str2I64(src,10,&src);
+        if (*src++!=':') throw;
+        ds.hour=Str2I64(src,10,&src);
+        if (*src++!=':') throw;
+        ds.min=Str2I64(src,10,&src);
+        if (*src++!=':') throw;
+        ds.sec=Str2I64(src,10,&src);
+        tmplg->datetime=Struct2Date(&ds);
+        if (*src++!=CH_SPACE) throw;
+        i=Str2I64(src,10,&src);
+        tmplg->datetime-=(i/100+i%100/60.0)*CDATE_FREQ*60*60;
+        if (!(Str2Date("1/1/2017")<=tmplg->datetime<Str2Date("1/1/2050")))
+          throw;
+        if (tmplg->datetime<*_dstart) *_dstart=tmplg->datetime;
+        if (tmplg->datetime>*_dend)   *_dend  =tmplg->datetime;
+
+        do if (!*src) throw;
+        while (*src++!=']');
+
+        if (*src++!=CH_SPACE) throw;
+        if (*src++!='\"') throw;
+        if (!StrNCmp(src,"GET ",4)) {
+          src2=src+=4;
+          do if (!*src2) throw;
+          while (*src2++!=CH_SPACE);
+          * --src2=0;
+          tmplg->file=StrNew(src);
+          src=++src2;
+
+          do if (!*src) throw;
+          while (*src++!='\"');
+
+          tmplg->code=Str2I64(src,10,&src);
+          if (*src++!=CH_SPACE) throw;
+          tmplg->size=Str2I64(src,10,&src);
+          if (*src++!=CH_SPACE) throw;
+
+          if (*src++!='\"') throw;
+          src2=src;
+          do if (!*src2) throw;
+          while (*src2++!='\"');
+          * --src2=0;
+          tmplg->link=StrNew(src);
+          src=++src2;
+
+          QueIns(tmplg,head->last);
+        } else if (!StrNCmp(src,"HEAD ",5)) {
+          LogStructDel(tmplg);
+        } else
+          throw;
+      } catch {
+        Fs->catch_except=TRUE;
+        "%$Q\n",doc_e->tag;
+        LogStructDel(tmplg);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+}
+
+LogStruct *PrsLogFiles(U8 *files_find_mask,CDate *_dstart,CDate *_dend)
+{
+  LogStruct *head=CAlloc(sizeof(LogStruct));
+  CDirEntry *tmpde=FilesFind(files_find_mask),*tmpde1=tmpde;
+  QueInit(head);
+  while (tmpde) {
+    PrsSingleLogFile(head,tmpde->full_name,_dstart,_dend);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return head;
+}
+
+U0 LogLstDel(LogStruct *head)
+{
+  LogStruct *tmplg=head->next,*tmplg1;
+  while (tmplg!=head) {
+    tmplg1=tmplg->next;
+    LogStructDel(tmplg);
+    tmplg=tmplg1;
+  }
+}
+
+U0 BlockedStructAdd(BlockedStruct *head,U32 ip_num)
+{
+  BlockedStruct *tmpb=CAlloc(sizeof(BlockedStruct));
+  tmpb->ip_num=ip_num;
+  QueIns(tmpb,head->last);
+}
+
+Bool IsBlocked(BlockedStruct *head,U32 ip_num)
+{
+  BlockedStruct *tmpb=head->next;
+  while (tmpb!=head) {
+    if (tmpb->ip_num==ip_num)
+      return TRUE;
+    tmpb=tmpb->next;
+  }
+  return FALSE;
+}
+
+U0 BlockIPNuip(LogStruct *head)
+{
+  BlockedStruct blocked_head;
+  LogStruct *tmplg=head->next,*tmplg1;
+
+  QueInit(&blocked_head);
+
+  BlockedStructAdd(&blocked_head,68<<24+227<<16+61<<8+6);
+
+  //pass 1: collect robot lst
+  while (tmplg!=head) {
+    if (StrIMatch("ROBOT",tmplg->file) &&
+          !IsBlocked(&blocked_head,tmplg->ip_num))
+      BlockedStructAdd(&blocked_head,tmplg->ip_num);
+    tmplg=tmplg->next;
+  }
+
+  //pass 2: removed blocked ip_nuip
+  tmplg=head->next;
+  while (tmplg!=head) {
+    tmplg1=tmplg->next;
+    if (IsBlocked(&blocked_head,tmplg->ip_num)) {
+      QueRem(tmplg);
+      LogStructDel(tmplg);
+    }
+    tmplg=tmplg1;
+  }
+
+  QueDel(&blocked_head);
+}
+
+Bool IsDownLoad(LogStruct *tmplg)
+{
+  if (StrMatch(DOWNLOAD_FILE1,tmplg->file)&&tmplg->size>=
+        DOWNLOAD_FILE1_SIZE)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool IsIndex(LogStruct *tmplg)
+{
+  if (!StrCmp(tmplg->file,"/index.html") || !StrCmp(tmplg->file,"/"))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool IsKeeper(LogStruct *tmplg,CDate dstart,CDate dend)
+{
+  if (dstart<=tmplg->datetime<=dend && !StrOcc(tmplg->file,'?') &&
+    StrLen(tmplg->file)>2 && 'A'<=tmplg->file[1]<='Z' &&
+    tmplg->size && tmplg->file[StrLen(tmplg->file)-1]!='/' &&
+    (StrLen(tmplg->file)<3 || MemCmp(&tmplg->file[1],"Wb",2)) &&
+    (StrLen(tmplg->file)<7 || MemCmp(&tmplg->file[1],"Family",6))) {
+    return TRUE;
+
+}  else
+    return FALSE;
+}
+
+Bool IPNumTreeAdd(LogStruct **_head,LogStruct *tmplg)
+{
+  LogStruct *head;
+  if (UnusedStk<0x200) {
+    PrintErr("Stk Overflow");
+    throw;
+  }
+  if (head=*_head) {
+    if (tmplg->ip_num==head->ip_num)
+      return TRUE;
+    else if (tmplg->ip_num<head->ip_num)
+      return IPNumTreeAdd(&head->ip_num_left,tmplg);
+    else
+      return IPNumTreeAdd(&head->ip_num_right,tmplg);
+  } else {
+    tmplg->ip_num_left=NULL;
+    tmplg->ip_num_right=NULL;
+    *_head=tmplg;
+    return FALSE;
+  }
+}
+
+U0 LinkTreeAdd(LinkStruct **_root,LogStruct *tmplg)
+{
+  I64 i;
+  LinkStruct *root,*tmplk;
+  if (UnusedStk<0x200) {
+    PrintErr("Stk Overflow");
+    throw;
+  }
+  if (root=*_root) {
+    if (!(i=StrCmp(tmplg->link,root->link)))
+      root->cnt++;
+    else if (i<0)
+      LinkTreeAdd(&root->left,tmplg);
+    else
+      LinkTreeAdd(&root->right,tmplg);
+  } else {
+    tmplk=CAlloc(sizeof(LinkStruct));
+    tmplk->link=tmplg->link;
+    tmplk->cnt=1;
+    *_root=tmplk;
+  }
+}
+
+U0 FileTreeAdd(LinkStruct **_root,LogStruct *tmplg)
+{
+  I64 i;
+  LinkStruct *root,*tmplk;
+  if (UnusedStk<0x200) {
+    PrintErr("Stk Overflow");
+    throw;
+  }
+  if (root=*_root) {
+    if (!(i=StrCmp(tmplg->file,root->file)))
+      root->cnt++;
+    else if (i<0)
+      FileTreeAdd(&root->left,tmplg);
+    else
+      FileTreeAdd(&root->right,tmplg);
+  } else {
+    tmplk=CAlloc(sizeof(LinkStruct));
+    tmplk->file=tmplg->file;
+    tmplk->cnt=1;
+    *_root=tmplk;
+  }
+}
+
+U0 LinkTreeDel(LinkStruct *root)
+{
+  if (root) {
+    LinkTreeDel(root->left);
+    LinkTreeDel(root->right);
+    Free(root);
+  }
+}
+
+U0 LinkTreeTraverse(LinkStruct *root)
+{
+  if (root) {
+    LinkTreeTraverse(root->left);
+    "%3d:%$Q\n",root->cnt,root->link;
+    LinkTreeTraverse(root->right);
+  }
+}
+
+U0 FileTreeDel(LinkStruct *root)
+{
+  if (root) {
+    FileTreeDel(root->left);
+    FileTreeDel(root->right);
+    Free(root);
+  }
+}
+
+U0 FileTreeTraverse(LinkStruct *root)
+{
+  if (root) {
+    FileTreeTraverse(root->left);
+    "%3d:%$Q\n",root->cnt,root->file;
+    FileTreeTraverse(root->right);
+  }
+}
+
+U0 DownLoadRep(LogStruct *head,CDate dstart,CDate dend)
+{
+  I64 i,j,cnt,dups,
+        hours_start,hours_end,*hour_cnts,*dup_cnts,
+        days_start,days_end,*day_cnts,*day_dup_cnts;
+  LogStruct *tmplg=head->next,*dup_head=NULL;
+  LinkStruct *link_root=NULL;
+  CDateStruct ds;
+
+  i=dstart*24;hours_start=i.u32[1];
+  i=dend  *24;hours_end =i.u32[1];
+
+  days_start=(dstart+local_time_offset)>>32;
+  days_end  =(dend+local_time_offset)>>32;
+
+  hour_cnts=CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  dup_cnts =CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  day_cnts =CAlloc((days_end-days_start+1)*sizeof(I64));
+  day_dup_cnts=CAlloc((days_end-days_start+1)*sizeof(I64));
+  dups=cnt=0;
+  while (tmplg!=head) {
+    if (IsKeeper(tmplg,dstart,dend) && IsDownLoad(tmplg)) {
+      i=tmplg->datetime*24;
+      hour_cnts[i.u32[1]-hours_start]++;
+      day_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+      cnt++;
+      if (IPNumTreeAdd(&dup_head,tmplg)) {
+        day_dup_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+        dup_cnts[i.u32[1]-hours_start]++;
+        dups++;
+      }
+      LinkTreeAdd(&link_root,tmplg);
+    }
+    tmplg=tmplg->next;
+  }
+
+  "\n\nDownloads of /TOS_Distro.ISO\n";
+  for (i=dstart;i<=dend;i+=1<<32)
+    "%D  Dups:%5d  Total:%5d  Uniques:%5d\n",i,
+          day_dup_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start]-
+          day_dup_cnts[(i+local_time_offset)>>32-days_start];
+
+  "\n\nDownloads of /TOS_Distro.ISO\n"
+        "'-' is a dup.  '+' is not a dup.\n";
+  if (hours_end-hours_start>=HOURS_MAX)
+    i=hours_end-HOURS_MAX+1;
+  else
+    i=hours_start;
+  for (;i<=hours_end;i++) {
+    Date2Struct(&ds,i<<32/24+local_time_offset);
+    "%D %02d: ",i<<32/24,ds.hour;
+    for (j=0;j<dup_cnts[i-hours_start];j++)
+      '-';
+    for (;j<hour_cnts[i-hours_start];j++)
+      '+';
+    '\n';
+  }
+  "Total:%d  Dups:%d  Uniques:%d\n",cnt,dups,cnt-dups;
+
+  "\n\nDownloads of /TOS_Distro.ISO\n";
+  LinkTreeTraverse(link_root);
+  '\n';
+
+  LinkTreeDel(link_root);
+  Free(hour_cnts);
+  Free(dup_cnts);
+  Free(day_cnts);
+  Free(day_dup_cnts);
+}
+
+U0 FileRep(LogStruct *head,CDate dstart,CDate dend)
+{
+  LogStruct *tmplg=head->next;
+  LinkStruct *file_root=NULL;
+  while (tmplg!=head) {
+    if (IsKeeper(tmplg,dstart,dend))
+      FileTreeAdd(&file_root,tmplg);
+    tmplg=tmplg->next;
+  }
+  "\n\nFile Hits\n";
+  FileTreeTraverse(file_root);
+  '\n';
+  FileTreeDel(file_root);
+}
+
+U0 IndexRep(LogStruct *head,CDate dstart,CDate dend)
+{
+  I64 i,j,cnt,dups,
+        hours_start,hours_end,*hour_cnts,*dup_cnts,
+        days_start,days_end,*day_cnts,*day_dup_cnts;
+  LogStruct *tmplg=head->next,*dup_head=NULL;
+  LinkStruct *link_root=NULL;
+  CDateStruct ds;
+
+  i=dstart*24;hours_start=i.u32[1];
+  i=dend  *24;hours_end =i.u32[1];
+
+  days_start=(dstart+local_time_offset)>>32;
+  days_end  =(dend+local_time_offset)>>32;
+
+  hour_cnts=CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  dup_cnts =CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  day_cnts =CAlloc((days_end-days_start+1)*sizeof(I64));
+  day_dup_cnts=CAlloc((days_end-days_start+1)*sizeof(I64));
+  dups=cnt=0;
+  while (tmplg!=head) {
+    if (IsKeeper(tmplg,dstart,dend) && IsIndex(tmplg)) {
+      i=tmplg->datetime*24;
+      hour_cnts[i.u32[1]-hours_start]++;
+      day_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+      cnt++;
+      if (IPNumTreeAdd(&dup_head,tmplg)) {
+        day_dup_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+        dup_cnts[i.u32[1]-hours_start]++;
+        dups++;
+      }
+      LinkTreeAdd(&link_root,tmplg);
+    }
+    tmplg=tmplg->next;
+  }
+
+  "\n\nHits on /index.html\n"
+        "'-' is a dup.  '+' is not a dup.\n";
+  for (i=dstart;i<=dend;i+=1<<32)
+    "%D  Dups:%5d  Total:%5d  Uniques:%5d\n",i,
+          day_dup_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start]-
+          day_dup_cnts[(i+local_time_offset)>>32-days_start];
+
+  "\n\nHits on /index.html\n";
+  if (hours_end-hours_start>=HOURS_MAX)
+    i=hours_end-HOURS_MAX+1;
+  else
+    i=hours_start;
+  for (;i<=hours_end;i++) {
+    Date2Struct(&ds,i<<32/24+local_time_offset);
+    "%D %02d: ",i<<32/24,ds.hour;
+    for (j=0;j<dup_cnts[i-hours_start];j++)
+      '-';
+    for (;j<hour_cnts[i-hours_start];j++)
+      '+';
+    '\n';
+  }
+  "Total:%d  Dups:%d  Uniques:%d\n",cnt,dups,cnt-dups;
+
+  "\n\nHits on /index.html\n";
+  LinkTreeTraverse(link_root);
+  '\n';
+
+  LinkTreeDel(link_root);
+  Free(hour_cnts);
+  Free(dup_cnts);
+  Free(day_cnts);
+  Free(day_dup_cnts);
+}
+
+U0 WebLogRep(U8 *mask,U8 *output_filename)
+{
+  LogStruct *head;
+  CDate dstart=I64_MAX,dend=I64_MIN;
+
+  DocMax;
+
+  head=PrsLogFiles(mask,&dstart,&dend);
+  if (dstart>dend)
+    PrintErr("No Data.\n");
+  else {
+    dstart=GetDate("Start(%D):",dstart);
+    dend  =GetDate("End  (%D):",dend);
+    BlockIPNuip(head);
+
+    DocClear;
+    "$WW,0$";
+    IndexRep(head,dstart,dend);
+    FileRep(head,dstart,dend);
+    DownLoadRep(head,dstart,dend);
+
+    StrCpy(DocPut->filename.name,output_filename);
+    DocWrite(DocPut,TRUE);
+
+    "$WW,1$";
+  }
+  LogLstDel(head);
+}
+
+#if __CMD_LINE__
+Cd(__DIR__);;
+WebLogRep("*.log*","~/DemoWebLog.DD.Z");
+#endif
+
+ diff --git a/public/Wb/Demo/WebLogDemo/WebLogScramble.HC.HTML b/public/Wb/Demo/WebLogDemo/WebLogScramble.HC.HTML new file mode 100755 index 0000000..15af2d2 --- /dev/null +++ b/public/Wb/Demo/WebLogDemo/WebLogScramble.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+U8 key[4][256];
+
+U0 InitKey()
+{
+  I64 i,j;
+  for (i=0;i<4;i++) {
+    for (j=0;j<256;j++)
+      key[i][j]=j;
+    for (j=0;j<255;j++)
+      SwapU8(&key[i][j],&key[i][j+RandU32%(256-j)]);
+  }
+}
+
+U0 LogScrambleFile(U8 *name)
+{
+  CDoc *doc=DocRead(name,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next;
+  I64 i;
+  U32 num;
+  U8 *st,*st2;
+  "Scrambling: %s\n",name;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      st=MAlloc(StrLen(doc_e->tag)+1);
+      st2=MAlloc(StrLen(doc_e->tag)+1);
+      StrFirstRem(doc_e->tag," ",st);
+
+      for (i=3;i>=0;i--) {
+        StrFirstRem(st,".",st2);
+        num.u8[i]=key[i][Str2I64(st2)&255];
+      }
+
+      Free(st);
+      Free(st2);
+
+      st=MStrPrint("%d.%d.%d.%d %s",num.u8[3],num.u8[2],
+            num.u8[1],num.u8[0],doc_e->tag);
+      Free(doc_e->tag);
+      doc_e->tag=st;
+    }
+    doc_e=doc_e->next;
+  }
+  DocWrite(doc);
+  DocDel(doc);
+}
+U0 WebLogScramble(U8 *files_find_mask)
+{
+  CDirEntry *tmpde=FilesFind(files_find_mask,FUF_RECURSE|FUF_JUST_FILES),
+        *tmpde1=tmpde;
+  InitKey;
+  while (tmpde) {
+    LogScrambleFile(tmpde->full_name);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+U0 LogScrambleDemo()
+{
+  U8 *dirname;
+  Cd(__DIR__);
+  dirname=DirCur;
+  ST_WARN_ST "This will scramble all .log files in '%s'.\n\n",dirname;
+  Free(dirname);
+  if (AreYouSure)
+    WebLogScramble("*.log*");
+}
+
+LogScrambleDemo;
+
+ diff --git a/public/Wb/Demo/WordSearch.HC.HTML b/public/Wb/Demo/WordSearch.HC.HTML new file mode 100755 index 0000000..b0c604b --- /dev/null +++ b/public/Wb/Demo/WordSearch.HC.HTML @@ -0,0 +1,184 @@ + + + + + + + + + + + +
+//Simple and fancy way of searching
+
+//See ::/Apps/Vocabulary/VocabQuiz.HC.Z
+//for another example of dictionary usage.
+
+#define ROWS_NUM        20
+#define COLS_NUM        20
+#define DIM_MAX MaxI64(ROWS_NUM,COLS_NUM)
+
+U8 m[ROWS_NUM][COLS_NUM];
+
+U0 Init()
+{
+  I64 x,y;
+  for (y=0;y<ROWS_NUM;y++)
+    for (x=0;x<COLS_NUM;x++)
+      m[y][x]='A'+RandU16%26;
+}
+
+U0 Display()
+{
+  I64 x,y;
+  for (y=0;y<ROWS_NUM;y++) {
+    for (x=0;x<COLS_NUM;x++)
+      '' m[y][x];
+    '\n';
+  }
+}
+
+U0 GetWord(U8 *dst,I64 x,I64 y,I64 dx,I64 dy)
+{
+  while (0<=x<COLS_NUM && 0<=y<ROWS_NUM) {
+    *dst++=m[y][x];
+    y+=dy;
+    x+=dx;
+  }
+  *dst=0;
+}
+
+//************************************
+U0 Search(I64 dx,I64 dy)
+{
+  I64 x,y,i,n;
+  U8 buf[DIM_MAX+1],*ptr;
+  for (y=0;y<ROWS_NUM;y++)
+    for (x=0;x<COLS_NUM;x++) {
+      GetWord(buf,x,y,dx,dy);
+      n=StrLen(buf);
+      for (i=n;i>2;i--) {
+        buf[i]=0;
+        if ((ptr=ACDWordPtAt(buf)) && *ptr++==ACD_WORD_CHAR &&
+              !StrICmp(ptr,buf)) {
+          "%s ",buf;
+        }
+      }
+    }
+}
+
+U0 SimpleWordSearch()
+{
+  Search(1,0);
+  Search(0,1);
+  Search(-1,0);
+  Search(0,-1);
+  Search(1,1);
+  Search(-1,-1);
+  Search(1,-1);
+  Search(-1,1);
+  '\n';
+}
+
+//************************************
+U8 words[ROWS_NUM*COLS_NUM*8][DIM_MAX+1];
+U8 *word_ptrs[ROWS_NUM*COLS_NUM*8];
+
+U0 CollectWords(I64 dx,I64 dy,I64 *_n)
+{
+  I64 x,y,n=*_n;
+  for (y=0;y<ROWS_NUM;y++)
+    for (x=0;x<COLS_NUM;x++) {
+      GetWord(&words[n],x,y,dx,dy);
+      word_ptrs[n]=&words[n];
+      n++;
+    }
+  *_n=n;
+}
+
+I64 WordsCompare(U8 *e1,U8 *e2)
+{
+  return StrCmp(e1,e2);
+}
+
+/*Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block; //definition offset in ::/Adam/AutoComplete/ACDefs.DATA
+*/
+
+U0 DisplayWords(I64 n)
+{
+  I64 i=0,k;
+  U8 *w1,*w2,*dict=acd.word_lst;
+  for (i=0;i<n;i++)
+    while (*dict) {
+      w1=word_ptrs[i];
+      w2=dict+1;
+      while (*w2 && *w1==ToUpper(*w2)) {
+        w1++;
+        w2++;
+      }
+      if (ToUpper(*w2)>*w1)
+        break;
+      if (!*w2) {
+        if (StrLen(dict+1)>2) {
+          k=i;
+          while (k<n && !StrNICmp(word_ptrs[k++],dict+1,StrLen(dict+1)))
+            "%s ",dict+1;
+        }
+        w2=dict+1;
+        while (!StrICmp(w2,dict+1))
+          dict+=StrLen(dict+1)+4;
+      } else
+        dict+=StrLen(dict+1)+4;
+    }
+}
+
+U0 FancyWordSearch()
+{
+  I64 n=0;
+  CollectWords(1,0,&n);
+  CollectWords(0,1,&n);
+  CollectWords(-1,0,&n);
+  CollectWords(0,-1,&n);
+  CollectWords(1,1,&n);
+  CollectWords(-1,-1,&n);
+  CollectWords(1,-1,&n);
+  CollectWords(-1,1,&n);
+  QSortI64(word_ptrs,n,&WordsCompare);
+  DisplayWords(n);
+  '\n';
+}
+
+//************************************
+U0 WordSearch()
+{
+  Init;
+  Display;
+  '\n';
+  SimpleWordSearch;
+  FancyWordSearch;
+}
+
+WordSearch;
+
+ diff --git a/public/Wb/Doc/Asm.DD.HTML b/public/Wb/Doc/Asm.DD.HTML index 740c30a..7d34c33 100755 --- a/public/Wb/Doc/Asm.DD.HTML +++ b/public/Wb/Doc/Asm.DD.HTML @@ -73,12 +73,12 @@ Align to
num boundary and fill with fill_byte. ORG num - Set code addr for JIT or set module Load() addr -- has 16-byte CBinFile header + Set code addr for JIT or set module Load() addr -- has 16-byte CBinFile header and patch table trailing. BINFILE "FileName.BIN"; -See Assembly Language, ::/Demo/Asm/AsmAndC1.HC, ::/Demo/Asm/AsmAndC2.HC and -::/Demo/Asm/AsmAndC3.HC. +See Assembly Language, ::/Demo/Asm/AsmAndC1.HC, ::/Demo/Asm/AsmAndC2.HC and +::/Demo/Asm/AsmAndC3.HC.
diff --git a/public/Wb/Doc/AutoComplete.DD.HTML b/public/Wb/Doc/AutoComplete.DD.HTML index 1011d40..c219a94 100755 --- a/public/Wb/Doc/AutoComplete.DD.HTML +++ b/public/Wb/Doc/AutoComplete.DD.HTML @@ -27,9 +27,9 @@
-AutoComplete is the LTGRAY window on the right of the scrn.  ACInit() collects 
-words from all text files in subdirectories.  Normally, the call to ACInit() is 
-in HomeSys.HC.  It provides auto-complete for typing, jump-to-code and 
+AutoComplete is the LTGRAY window on the right of the scrn.  ACInit() collects 
+words from all text files in subdirectories.  Normally, the call to ACInit() is 
+in HomeSys.HC.  It provides auto-complete for typing, jump-to-code and 
 jump-to-dictionary functionality.
 
 <ALT-SHIFT-A>   Closes the LTGRAY AutoComplete window.
@@ -50,6 +50,6 @@
 
 If you have the raw Project Gutenberg dictionary file, you can generate the 
 TempleOS processed dictionary files with the stand-alone program 
-::/Adam/AutoComplete/ACDictGen.HC.
+::/Adam/AutoComplete/ACDictGen.HC.
 
diff --git a/public/Wb/Doc/BlkChain.DD.HTML b/public/Wb/Doc/BlkChain.DD.HTML index f9e5063..f56dbae 100755 --- a/public/Wb/Doc/BlkChain.DD.HTML +++ b/public/Wb/Doc/BlkChain.DD.HTML @@ -55,13 +55,13 @@ the end. I don't want to spoil fun, so of course I offer a way to get awesome performance -that is, ironically, superior. FBlkRead() and FBlkWrite() allow you to read a +that is, ironically, superior. FBlkRead() and FBlkWrite() allow you to read a block offset from the start of a file. Since files are all contiguous, this is incredibly efficient. You just have to declare the desired file size when you -create it with FOpen() and cannot change it. See ::/Demo/Dsk/DataBase.HC. +create it with FOpen() and cannot change it. See ::/Demo/Dsk/DataBase.HC. -If you like, you are encouraged to to do raw BlkRead() and BlkWrite() directly -on a drive. Just get a pointer to a CDrv with Let2Drv() and you are on your +If you like, you are encouraged to to do raw BlkRead() and BlkWrite() directly +on a drive. Just get a pointer to a CDrv with Let2Drv() and you are on your way! Your computer is supposed to be a fun toy! You can make an entire partition used for a database, or invent a file system. diff --git a/public/Wb/Doc/Boot.DD.HTML b/public/Wb/Doc/Boot.DD.HTML index ac643d6..84569c2 100755 --- a/public/Wb/Doc/Boot.DD.HTML +++ b/public/Wb/Doc/Boot.DD.HTML @@ -47,48 +47,48 @@ This means they usually can't just load the whole operating system and start it running. Some boot loaders, like Grub, have a capability of switching modes before handing-off control to the operating system. The operating system must -load the rest of itself. With TempleOS, the ::/Kernel.BIN.C file is loaded by -the boot sector. I try to put a minimum in the Kernel Module, so that it will +load the rest of itself. With TempleOS, the ::/Kernel.BIN.C file is loaded by +the boot sector. I try to put a minimum in the Kernel Module, so that it will always fit in 640K. When Kernel.BIN runs, it switches to 32-bit mode, then, to 64-bit mode allowing access to more memory. Then, it loads in the rest of -TempleOS by executing ::/StartOS.HC. +TempleOS by executing ::/StartOS.HC. All the boot related code for TempleOS is in the /Adam/Opt/Boot directory. -BootDVD.HC CD/DVD boot sector. -BootDVDIns.HC Prep for CD/DVD install by creating /0000Boot/0000Kernel.BIN.C. -If you are curious about CD/DVDs, see DskISORedSea.HC. To make a custom -bootable CD/DVD, look here Bootable CD. +BootDVD.HC CD/DVD boot sector. +BootDVDIns.HC Prep for CD/DVD install by creating /0000Boot/0000Kernel.BIN.C. +If you are curious about CD/DVDs, see DskISORedSea.HC. To make a custom +bootable CD/DVD, look here Bootable CD. -BootMHD.HC Stage 1 Master HD boot loader. -BootMHD2.HC Stage 2 Master HD boot loader. -BootMHDIns.HC Installs Master HD boot loader. +BootMHD.HC Stage 1 Master HD boot loader. +BootMHD2.HC Stage 2 Master HD boot loader. +BootMHDIns.HC Installs Master HD boot loader. BootMHD goes on block zero. /0000Boot/BootMHD2.BIN.C is stored as a file in a partition, risky and unusual, since most master boot loaders place stage 2 in a gap that's not in any partition. BootMHD2 displays a menu and boots a partition. -BootHD.HC HD partition boot record. -BootHDIns.HC Installs HD partition boot record. +BootHD.HC HD partition boot record. +BootHDIns.HC Installs HD partition boot record. BootHD is the boot record for a TempleOS partition. Each partition has its own partition boot record, the first block of the partition. My boot records don't access directories because that would make them too big for one block and would make them depend on a file system layout. Instead, they get patched with the LBA, logical block addresses, to load files. To update -with a new TempleOS kernel, you must create a ::/Kernel.BIN.C binary file and +with a new TempleOS kernel, you must create a ::/Kernel.BIN.C binary file and patch the boot loader so it knows the LBA blocks to load. Therefore, you usually recompile the kernel and update the boot sector at the same time with -BootHDIns(). BootMHDIns() will install a master boot loader. +BootHDIns(). BootMHDIns() will install a master boot loader. -With TempleOS, ::/Kernel.BIN.C loads ::/Compiler/Compiler.BIN so it can work +With TempleOS, ::/Kernel.BIN.C loads ::/Compiler/Compiler.BIN so it can work with source code from then on. It compiles start-up scripts beginning with -::/StartOS.HC into the Adam Task's memory including the code in the /Adam and /H +::/StartOS.HC into the Adam Task's memory including the code in the /Adam and /H ome directories. It is possible to do a fast reboot without doing a hardware reset. You might do -this when working on ::/Kernel.BIN.C or your start-up scripts when you want to -compile them effect. See BootRAM(). +this when working on ::/Kernel.BIN.C or your start-up scripts when you want to +compile them effect. See BootRAM(). /* Graphics Not Rendered in HTML */ diff --git a/public/Wb/Doc/CharOverview.DD.HTML b/public/Wb/Doc/CharOverview.DD.HTML index e72ccdc..095a0a9 100755 --- a/public/Wb/Doc/CharOverview.DD.HTML +++ b/public/Wb/Doc/CharOverview.DD.HTML @@ -34,7 +34,7 @@ Standard ASCII values range from 0 to 127. Values below 32 are ctrl key's. So, an ASCII #3 is a <CTRL-c>. TempleOS uses a few nonstandard values below 32. -See Char Definitions. +See Char Definitions. ASCII #5 is the cursor location in a saved file. ASCII #28 is <SHIFT-ESC>. @@ -46,20 +46,20 @@ A Key is typically specified with a scan code. TempleOS scan codes contain the key value in the lowest U8, and flags in the upper 3 bytes. See -Scan Code Flags and Scan Codes. +Scan Code Flags and Scan Codes. TempleOS stores scan codes in 8 bytes. Byte 0 is the code. NumPad keys, SHIFT, ALT, CTRL and GUI keys combined. - Byte 1-3 are flags + Byte 1-3 are flags The upper 4-bytes are copied from lower 4-bytes. Byte 4 is the code. Left, Right and NumPad keys distinct. - Byte 5-7 are flags + Byte 5-7 are flags -Run the program ::/Demo/MsgLoop.HC to examine scan code. Press <CTRL-SHIFT-l> +Run the program ::/Demo/MsgLoop.HC to examine scan code. Press <CTRL-SHIFT-l> and "Insert ASCII/ScanCode". -See Key Allocations and CKbdStateGlbls. +See Key Allocations and CKbdStateGlbls. A String is a bunch of ASCII characters terminated with a zero. diff --git a/public/Wb/Doc/Charter.DD.HTML b/public/Wb/Doc/Charter.DD.HTML index f9e4556..b802d17 100755 --- a/public/Wb/Doc/Charter.DD.HTML +++ b/public/Wb/Doc/Charter.DD.HTML @@ -95,7 +95,7 @@ libraries creates a hell that is no longer blissful. * The metric for resolving all TempleOS code governance issues is how fast the -compiler compiles itself and the kernel with BootHDIns(). The HolyC language +compiler compiles itself and the kernel with BootHDIns(). The HolyC language should be changed to optimize this metric, as I did when I changed type casting from prefix standard C to postfix HolyC, but we need a rule to prevent degenerating into a brainfuck language. diff --git a/public/Wb/Doc/CmdLineOverview.DD.HTML b/public/Wb/Doc/CmdLineOverview.DD.HTML index 1f0e9d2..05fd4a7 100755 --- a/public/Wb/Doc/CmdLineOverview.DD.HTML +++ b/public/Wb/Doc/CmdLineOverview.DD.HTML @@ -35,7 +35,7 @@ Look-up the function headers with AutoComplete by hitting <CTRL-SHIFT-F1> after typing the first few letters. -Click Here to see the directory cmd header. It accepts default args from C++. +Click Here to see the directory cmd header. It accepts default args from C++. >Dir("*.DD.Z"); @@ -48,7 +48,7 @@ shortcuts for #includeing files. Right-click or hit <ENTER> on a directory listing or press <F5> while editing. ->Ed("NewFile.HC.Z"); Invokes the editor. See Doc Link Type. +>Ed("NewFile.HC.Z"); Invokes the editor. See Doc Link Type. Most filenames end in .Z because they are stored compressed. @@ -57,7 +57,7 @@ >Drv('B'); B drive -The drive can be specified in a Cd() command as in: +The drive can be specified in a Cd() command as in: >Cd("B:/Tmp"); B drive >Cd("::/Demo"); Boot drive @@ -69,7 +69,7 @@ If a file is not found, .Z is added or removed and a search is done, again. If a file is still not found, all parent directories are searched. -You can place macros in your PersonalMenu for Cd() commands. <CTRL-m> to access +You can place macros in your PersonalMenu for Cd() commands. <CTRL-m> to access your menu. >Find("needle","/Demo/*.HC.Z;*.DD.Z;"); See File Utils. diff --git a/public/Wb/Doc/Comm.HC.HTML b/public/Wb/Doc/Comm.HC.HTML new file mode 100755 index 0000000..72312db --- /dev/null +++ b/public/Wb/Doc/Comm.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+/* RS232 serial ports no longer exist.
+Be sure to Adam Include this by placing
+it in your start-up scripts.
+*/
+
+#help_index "Comm"
+
+#define UART_THR                0
+#define UART_RDR                0
+#define UART_BRDL               0
+#define UART_IER                1
+#define UART_BRDH               1
+#define UART_IIR                2
+#define UART_LCR                3
+#define UART_MCR                4
+#define UART_LSR                5
+#define UART_MSR                6
+
+#define COMf_ENABLED    0
+class CComm
+{
+  I64   base,
+        flags;
+  CFifoU8 *RX_fifo;
+  CFifoU8 *TX_fifo;
+} comm_ports[5];
+
+U0 CommHndlr(I64 port)
+{
+  CComm *c=&comm_ports[port];
+  I64 b=0,stat;
+  if (Bt(&c->flags,COMf_ENABLED)) {
+    stat=InU8(c->base+UART_IIR);
+    if (stat & 4)       //RX
+      FifoU8Ins(c->RX_fifo,InU8(c->base+UART_RDR));
+    if (stat & 2) {     //TX
+      if (FifoU8Rem(c->TX_fifo,&b))
+        OutU8(c->base+UART_THR,b);
+      else
+        OutU8(c->base+UART_IER,1); //RX but no THR empty
+    }
+  }
+}
+
+interrupt U0 IRQComm3()
+{
+  CommHndlr(2);
+  CommHndlr(4);
+  OutU8(0x20,0x20);
+}
+
+interrupt U0 IRQComm4()
+{
+  CommHndlr(1);
+  CommHndlr(3);
+  OutU8(0x20,0x20);
+}
+
+U0 CommInit()
+{
+  MemSet(&comm_ports,0,sizeof(comm_ports));
+  comm_ports[1].base=0x3F8;
+  comm_ports[2].base=0x2F8;
+  comm_ports[3].base=0x3E8;
+  comm_ports[4].base=0x2E8;
+  IntEntrySet(0x23,&IRQComm3);
+  IntEntrySet(0x24,&IRQComm4);
+}
+CommInit;
+
+public CComm *CommInit8n1(I64 port,I64 baud)
+{
+  CComm *c=&comm_ports[port];
+
+  PUSHFD
+  CLI
+  if (LBts(&c->flags,COMf_ENABLED)) {
+    FifoU8Del(c->RX_fifo);
+    FifoU8Del(c->TX_fifo);
+  }
+  c->RX_fifo=FifoU8New(256);
+  c->TX_fifo=FifoU8New(256);
+  OutU8(c->base+UART_LCR,0);    //Set for IER
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_LCR,0x80); //Enable baud rate control
+  OutU8(c->base+UART_BRDL,(0x180/(baud/300)) & 0xFF);   //LSB
+  OutU8(c->base+UART_BRDH,(0x180/(baud/300)) / 256);    //MSB
+  OutU8(c->base+UART_LCR,3);    //8-none-1
+
+  InU8(c->base+UART_RDR);       //read garbage
+  InU8(c->base+UART_LSR);
+
+  OutU8(c->base+UART_MCR,4);
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_MCR,0xA);  //out2 and rts
+  OutU8(0x21,InU8(0x21) & (0xFF-0x18)); //Enable 8259 IRQ 3 & 4
+  OutU8(c->base+UART_IER,1);    //RX but no THR empty
+  POPFD
+
+  return c;
+}
+
+public U0 CommPutChar(I64 port,U8 b)
+{
+  CComm *c=&comm_ports[port];
+  PUSHFD
+  CLI
+  FifoU8Ins(c->TX_fifo,b);
+  OutU8(c->base+UART_IER,3);    //RX and THR empty
+  POPFD
+  Sleep(10); //!!! Remove this line!!!  Linux echo_socket is too slow.
+}
+
+U0 CommPutS(I64 port,U8 *st)
+{
+  I64 b;
+  while (b=*st++)
+    CommPutChar(port,b);
+}
+
+public U0 CommPutBlk(I64 port,U8 *buf,I64 cnt)
+{
+  while (cnt--)
+    CommPutChar(port,*buf++);
+}
+
+public U0 CommPrint(I64 port,U8 *fmt,...)
+{
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CommPutS(port,buf);
+  Free(buf);
+}
+
+ diff --git a/public/Wb/Doc/Credits.DD.HTML b/public/Wb/Doc/Credits.DD.HTML index c6d8ec8..0ee38aa 100755 --- a/public/Wb/Doc/Credits.DD.HTML +++ b/public/Wb/Doc/Credits.DD.HTML @@ -37,20 +37,20 @@ the src code is including on all distro's, from the kernel to the compiler to the boot loaders! It is public domain, not GPL. -*)
::/Kernel/FontStd.HC, is taken from FreeDOS. It's public domain. +*) ::/Kernel/FontStd.HC, is taken from FreeDOS. It's public domain. -*) ::/Kernel/FontCyrillic.HC, is taken from OrientDisplay without permission. +*) ::/Kernel/FontCyrillic.HC, is taken from OrientDisplay without permission. -*) ATA Reg and Cmd Definitions are originally from Linux. Later, I got the +*) ATA Reg and Cmd Definitions are originally from Linux. Later, I got the spec. -*) The heap algorithm, ::/Kernel/Mem/MAllocFree.HC, is adapted from one I saw at +*) The heap algorithm, ::/Kernel/Mem/MAllocFree.HC, is adapted from one I saw at Ticketmaster when I worked on their VAX operating system. -*) The LZW compression algorithm, ::/Kernel/Compress.HC, came from a magazine +*) The LZW compression algorithm, ::/Kernel/Compress.HC, came from a magazine and I implemented it when I worked for Ticketmaster. -*) The adaptive-step-size-Runge-Kutta algorithm, ::/Adam/AMathODE.HC, is adapted +*) The adaptive-step-size-Runge-Kutta algorithm, ::/Adam/AMathODE.HC, is adapted from the book, Numeric Recipies in C. *) The mountain in some games is from http://www.public-domain-photos.com. The @@ -66,7 +66,7 @@ *) I included PCIDevice Lst File. *) Thanks to whoever wrote this CppHtml.HC.Z. I'm a novice on web stuff and you -helped me with html. See ::/Demo/ToHtmlToTXTDemo/ToHtml.HC. +helped me with html. See ::/Demo/ToHtmlToTXTDemo/ToHtml.HC. *) I looked at bootable CD boot sects, but didn't learn anything, finding it easier to make my own. @@ -83,9 +83,9 @@ windows like Windows. Instead, I made one window per task with no child windows. He also guided my progress, very obviously. -*) I got Webster's Dictionary and The King James Bible from Project Gutenberg. +*) I got Webster's Dictionary and The King James Bible from Project Gutenberg. -*) John Carmack inspired me to use "Clamp" as a name instead of "Limit". He +*) John Carmack inspired me to use "Clamp" as a name instead of "Limit". He inspired me to use "needle" and "haystack" as names. He inspired me to simplify my Frames-Per-Second code. diff --git a/public/Wb/Doc/Ctrls.DD.HTML b/public/Wb/Doc/Ctrls.DD.HTML index 27cf588..a6691b8 100755 --- a/public/Wb/Doc/Ctrls.DD.HTML +++ b/public/Wb/Doc/Ctrls.DD.HTML @@ -28,8 +28,8 @@
 To create a TempleOS graphic ctrl, you define callback functions and insert a 
-CCtrl structure in the CTask queue.  See ::/Demo/Graphics/Slider.HC, 
-::/Demo/Graphics/ScrollBars.HC and TermBttnNew.  There is a template-code ctrl 
+CCtrl structure in the CTask queue.  See ::/Demo/Graphics/Slider.HC, 
+::/Demo/Graphics/ScrollBars.HC and TermBttnNew.  There is a template-code ctrl 
 generator, if you press <CTRL-SHIFT-L>.
 
diff --git a/public/Wb/Doc/Customize.DD.HTML b/public/Wb/Doc/Customize.DD.HTML index 954d358..d00bed8 100755 --- a/public/Wb/Doc/Customize.DD.HTML +++ b/public/Wb/Doc/Customize.DD.HTML @@ -29,11 +29,11 @@
 
 * You can adjust the mouse movement rate by setting global vars in your start-up 
-file.  See mouse scale.
+file.  See mouse scale.
 
 * You can set your local time zone by setting the local_time_offset global var 
-in a start-up file.  It's units are CDATE_FREQ.  See local time.
+in a start-up file.  It's units are CDATE_FREQ.  See local time.
 
-* Get rid of this msg here.
+* Get rid of this msg here.
 
diff --git a/public/Wb/Doc/CutCorners.DD.HTML b/public/Wb/Doc/CutCorners.DD.HTML index 51d4c3a..f1f9a9e 100755 --- a/public/Wb/Doc/CutCorners.DD.HTML +++ b/public/Wb/Doc/CutCorners.DD.HTML @@ -36,7 +36,7 @@ * I made my type-casting operator post-fix because it makes the compiler way cleaner. -* TempleOS does not figure-out
FAT32 short name alias numbers. FAT32DirNew(). +* TempleOS does not figure-out FAT32 short name alias numbers. FAT32DirNew(). It can cause hard drive corruption, so I might have to do it. It would really take a lot of junky code for this hatefully, detestable, legacy issue. "Please don't make me ruin my beautiful shiny-new TempleOS with that!" I am also not @@ -46,9 +46,9 @@ booted operating systems. * I changed the asm opcodes names to remove the ambiguity between insts with -different numbers of arguments, making my assembler simpler and I did minimal +different numbers of arguments, making my assembler simpler and I did minimal 16-bit asm support, since 64-bit is what you should be using, unless you're -doing a boot loader. +doing a boot loader. * There are no user-controlled file-sharing locks. However, the drive and file system have locks and concurrent operations should be fine. @@ -62,8 +62,8 @@ * Even if a local function variable is declared less than 64 bits, the compiler does calculations with 64-bit. -* Print() uses StrPrintJoin(). You cannot use vastly over-sized fields for %f. +* Print() uses StrPrintJoin(). You cannot use vastly over-sized fields for %f. -* GrEllipse3() is broken on transformations. +* GrEllipse3() is broken on transformations. diff --git a/public/Wb/Doc/DbgOverview.DD.HTML b/public/Wb/Doc/DbgOverview.DD.HTML index 5ad9025..ad8231f 100755 --- a/public/Wb/Doc/DbgOverview.DD.HTML +++ b/public/Wb/Doc/DbgOverview.DD.HTML @@ -29,74 +29,74 @@
                                Debugging Overview
 
-* You can enter the debugger with Dbg() or <CTRL-ALT-d>.  You might enter the 
-debugger through a fault.  Enter G() or G2() to continue execution.  Place a 
-call to Dbg() in your code at fatal error points to enter the debugger.  If you 
-see a stk dump, record the label+offset and unassemble, U(). U(_RIP); 
+* You can enter the debugger with Dbg() or <CTRL-ALT-d>.  You might enter the 
+debugger through a fault.  Enter G() or G2() to continue execution.  Place a 
+call to Dbg() in your code at fatal error points to enter the debugger.  If you 
+see a stk dump, record the label+offset and unassemble, U(). U(_RIP); 
 
-* U(&FunName+offset) to unassemble mem or Uf("FunName") to unassemble a 
-function. U(_RIP-16);
+* U(&FunName+offset) to unassemble mem or Uf("FunName") to unassemble a 
+function. U(_RIP-16);
 
 * While debugging, you specify addresses of assembly routines with just the 
 label, as in _MALLOC+0x20.  You specify HolyC function names with & before 
 functions as in &Print+0x10.
 
-* I use progress1-progress4 for debugging because they show on the wallpaper.  
+* I use progress1-progress4 for debugging because they show on the wallpaper.  
 They're just global int vars.
 
-* You can use AdamLog() to send text to the Adam Task window.  It works like 
-Print().  I never use that.  Instead, I use RawPrint().
+* You can use AdamLog() to send text to the Adam Task window.  It works like 
+Print().  I never use that.  Instead, I use RawPrint().
 
-* D(), DocD(), RawD() to do 16 column hex dump mem with numbering from zero.  
-With DocD the values are updated continually and you can alter mem by editing.
+* D(), DocD(), RawD() to do 16 column hex dump mem with numbering from zero.  
+With DocD the values are updated continually and you can alter mem by editing.
 
-* Dm(), DocDm(), RawDm() to do 16 column hex dump mem with addresses showing.
+* Dm(), DocDm(), RawDm() to do 16 column hex dump mem with addresses showing.
 
-* Da() to do one column address dump (for stk, etc.) with symbolic addresses.
+* Da() to do one column address dump (for stk, etc.) with symbolic addresses.
 
-* Dr() dumps regs.  You can display and modify regs in the debugger with 
+* Dr() dumps regs.  You can display and modify regs in the debugger with 
 var-like labels, _RAX, _RBX, etc.
 
-* ClassRep() and the dynamic version ClassRepD() can be used to dump structures.
+* ClassRep() and the dynamic version ClassRepD() can be used to dump structures.
 
-* Prof() and ProfRep() provide code profiling.  See ::/Demo/InFile/InProfile.IN 
+* Prof() and ProfRep() provide code profiling.  See ::/Demo/InFile/InProfile.IN 
 (This is an InFile.)
 
-* Use RawPrint() to print debug info bypassing the window framework.  You pass 
+* Use RawPrint() to print debug info bypassing the window framework.  You pass 
 these routines a count in milliseconds for how long it should be displayed.  You 
-can use Raw(TRUE) to make all output bypass the window framework.  The WinMgr 
+can use Raw(TRUE) to make all output bypass the window framework.  The WinMgr 
 runs on Core0 and will overwrite raw text from other cores when it updates the 
 scrn.
 
-* Use SysDbg() to set a flag which you can read with IsSysDbg() when you wish to 
+* Use SysDbg() to set a flag which you can read with IsSysDbg() when you wish to 
 trigger some debug activity.  It's just a handy simple flag, nothing fancy.
 
 * There are flags for various trace options that can help debugging when there 
 are compiler bugs.  Often, you place them in #exe{} blocks.
   
-  Echo() turns on or off raw data going into the lexical analyzer.
+  Echo() turns on or off raw data going into the lexical analyzer.
   
-  Trace() unassembles code generated from the HolyC compiler.
+  Trace() unassembles code generated from the HolyC compiler.
   
-  PassTrace() shows intermediate code coming-out after optimization.  The bits 
+  PassTrace() shows intermediate code coming-out after optimization.  The bits 
   ctrl which passes are displayed.
 
 
-* There is a heap check utility which can find leaks.  Use HeapLog(), 
-HeapLogAddrRep() and HeapLogSizeRep().  It's a really simple program which 
-intercepts MAlloc() and Free().  You can customize the code to find other heap 
+* There is a heap check utility which can find leaks.  Use HeapLog(), 
+HeapLogAddrRep() and HeapLogSizeRep().  It's a really simple program which 
+intercepts MAlloc() and Free().  You can customize the code to find other heap 
 issues.
 
-* You can define hndlr functions for <CTRL-ALT-letter> keys with CtrlAltCBSet(). 
+* You can define hndlr functions for <CTRL-ALT-letter> keys with CtrlAltCBSet(). 
  They operate either in a interrupt environment or in the window mgr when it 
-queues kbd msgs.  You can do Raw() output.  <CTRL-ALT-letter> hndlrs take a 
+queues kbd msgs.  You can do Raw() output.  <CTRL-ALT-letter> hndlrs take a 
 scan_code as an arg.
 
-* If you recompile Kernel with BootHDIns(), you can set the MemInit, option to 
+* If you recompile Kernel with BootHDIns(), you can set the MemInit, option to 
 initialize memory to a value at boot, the HeapInit option to cause mem alloced 
 off the heap to be initialized or VarInit option so both global and local vars 
 will be initialized to a value, but global AOT variables are always zero if not 
 initialized.  Pick a non-zero value to discover uninitialized var bugs.  You can 
-set sys_var_init_flag, and sys_heap_init_flag directly after booting.
+set sys_var_init_flag, and sys_heap_init_flag directly after booting.
 
diff --git a/public/Wb/Doc/Define.DD.HTML b/public/Wb/Doc/Define.DD.HTML index a49ee9a..c0e919b 100755 --- a/public/Wb/Doc/Define.DD.HTML +++ b/public/Wb/Doc/Define.DD.HTML @@ -28,9 +28,9 @@
 TempleOS has a string indirection feature implemented with the same hash symbol 
-table entry as #define macros, HTT_DEFINE_STR.  Support for string lists is also 
+table entry as #define macros, HTT_DEFINE_STR.  Support for string lists is also 
 provided, but it's not very efficient, though, you can make a hash table with a 
-list using HashDefineLstAdd().  See ::/Adam/DolDoc/DocInit.HC.
+list using HashDefineLstAdd().  See ::/Adam/DolDoc/DocInit.HC.
 
 If you have an @ as the first char of a define list entry, it is an alias for 
 the prev entry num.
@@ -40,8 +40,8 @@
 
 The DolDoc framework supports text that changes based on entries in the task's 
 symbol table.  Set a text entry with a D= arg, as in $TX,"",D="DD_MYSTRING"$.  
-See ::/Demo/DolDoc/DefineStr.HC, ::/Adam/ADefine.HC and ::/Doc/MemOverview.DD.
+See ::/Demo/DolDoc/DefineStr.HC, ::/Adam/ADefine.HC and ::/Doc/MemOverview.DD.
 
-See ::/Demo/Define.HC.
+See ::/Demo/Define.HC.
 
diff --git a/public/Wb/Doc/Demands.DD.HTML b/public/Wb/Doc/Demands.DD.HTML index dd1ffe2..972c092 100755 --- a/public/Wb/Doc/Demands.DD.HTML +++ b/public/Wb/Doc/Demands.DD.HTML @@ -47,10 +47,10 @@ multiple file systems is bad and imperfect. For this operating system, we want low line count. More than one driver for the same type of device is also bad. -See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC. +See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC. -::/Kernel/BlkDev/FileSysFAT.HC :974 lines for FAT32 gets eliminated. -::/Kernel/BlkDev/DskClus.HC :152 All the clus operations become blk. +::/Kernel/BlkDev/FileSysFAT.HC :974 lines for FAT32 gets eliminated. +::/Kernel/BlkDev/DskClus.HC :152 All the clus operations become blk. * Microsoft must cancel SecureBoot because it makes dual booting impossible. TempleOS is an additional operating system that must be used along-side Windows @@ -83,8 +83,8 @@ secondary master 170/376. Currently, the wicked CIA plays musical chairs with controllers each time you make an install. With tons of ugly code, I do my best. -/Kernel/BlkDev/DskATAId.HC :286 lines to figure-out I/O ports is gone. -/Kernel/PCIBIOS.HC :290 could be eliminated, but maybe we will keep +/Kernel/BlkDev/DskATAId.HC :286 lines to figure-out I/O ports is gone. +/Kernel/PCIBIOS.HC :290 could be eliminated, but maybe we will keep it so people can play with PCI devices. * Until super-simple serial ports are available, PS/2 emulated keyboard and @@ -93,13 +93,13 @@ devices in the same way PS/2 mouse is emulated. All mice will be two button, one wheel. No more HID insanity, no more multi-end point, just simple tx rx fifos with soft/hard flowcontrol that can jump the queue. People with special -needs can buy PCI cards. Our kids deserve code this simple ::/Doc/Comm.HC. The +needs can buy PCI cards. Our kids deserve code this simple ::/Doc/Comm.HC. The right to do your own port banging is what the C64 being our God given ancestral land means. * The x86 IN/OUT port instructions, normally have a delay. Perhaps, VMware & Intel can enable faster x86 IN/OUT instruction timing for ATA/ATAPI PIO, so -bandwidth isn't as bad when doing port I/O. See ATAGetRes(). We don't want to +bandwidth isn't as bad when doing port I/O. See ATAGetRes(). We don't want to do DMA. Perhaps, x86 CPU chips need a new TempleOS mode for fast IN/OUT instructions? I think VMware already does something to speed disk I/O to faster than native speed. @@ -111,7 +111,7 @@ * Since I don't use paging (for anything), Intel should have an option for no-paging long mode, and optimize it! -::/Kernel/Mem/PageTables.HC :135 lines to identity-map gets eliminated. +::/Kernel/Mem/PageTables.HC :135 lines to identity-map gets eliminated. * Desktop computers must have a reset switch and a fast reboot option, skipping diagnostics. I recommend booting TempleOS from a ROM when the reset bttn is @@ -120,10 +120,10 @@ for all desktop x86 CPUs to ensure tamper-proof trust in the oracle and because God deserves the glory. There will be just an English version. A new ROM version is released every seven years. The ROM should boot like the DVD boots, -but with BOOT_SRC_ROM. +but with BOOT_SRC_ROM. * We do not want UTF, just 8-bit characters. <CTRL-ALT-f> toggles between -Cyrillic and Std Fonts. We need the twelve window TextBorder characters added +Cyrillic and Std Fonts. We need the twelve window TextBorder characters added to the VGA font 0x02-0x0D. Japan, China and Korea must switch to alphabets. Maybe, the United States will change to metric, out of good will. I am beginning to plan fresh ASCII replacement, ::/Doc/NewASCII.DD. @@ -132,7 +132,7 @@ blemish free, unlike BMP files. The TOSZ Linux utility can be used to make screencasts from TempleOS exported GR Files and AU Files. -* We must have a nice dictionary. Someone needs to do a Spell Checker, too. +* We must have a nice dictionary. Someone needs to do a Spell Checker, too. * Intel needs to make DolDoc versions of its x86 CPU data sheets documenting all hardware relevant to TempleOS. diff --git a/public/Wb/Doc/Directives.DD.HTML b/public/Wb/Doc/Directives.DD.HTML index 9ec2dfa..cba8fde 100755 --- a/public/Wb/Doc/Directives.DD.HTML +++ b/public/Wb/Doc/Directives.DD.HTML @@ -34,6 +34,6 @@ #define __FILE__ #exe{StreamPrint("\"%s\"",Fs->last_cc->lex_include_stk->full_name);} #define __DIR__ #exe{StreamDir;} -See ::/Demo/Directives.HC. +See ::/Demo/Directives.HC. diff --git a/public/Wb/Doc/DolDoc.DD.HTML b/public/Wb/Doc/DolDoc.DD.HTML index 7ef0bf5..fc095d6 100755 --- a/public/Wb/Doc/DolDoc.DD.HTML +++ b/public/Wb/Doc/DolDoc.DD.HTML @@ -27,8 +27,8 @@
-A DolDoc in memory is a Circular Queue of cmds and graphics.  See CDocEntry for 
-the entry structure.  See TipOfDay() for a nice example.
+A DolDoc in memory is a Circular Queue of cmds and graphics.  See CDocEntry for 
+the entry structure.  See TipOfDay() for a nice example.
 
 DolDoc's are used for the editor, viewer, browser, and cmd line.
 
diff --git a/public/Wb/Doc/DolDocOverview.DD.HTML b/public/Wb/Doc/DolDocOverview.DD.HTML index a605fa8..4059ea2 100755 --- a/public/Wb/Doc/DolDocOverview.DD.HTML +++ b/public/Wb/Doc/DolDocOverview.DD.HTML @@ -36,22 +36,22 @@ Here is the grammar: -<DolDocCmd> := $<TwoLetterCmd>[<FlagList>][,<ArgList>]$ | $ColorName$ +<DolDocCmd> := $<TwoLetterCmd>[<FlagList>][,<ArgList>]$ | $ColorName$ -<FlagList> := +|- <FlagCode>[<FlagList>] +<FlagList> := +|- <FlagCode>[<FlagList>] -<ArgList> := <ArgCode>=<ArgExpression>[,<ArgList>] +<ArgList> := <ArgCode>=<ArgExpression>[,<ArgList>] The format of DolDoc cmds is a two character code, +/-flags, a comma and args separated by commas. Some commands have mandatory args. Optional args are -indicated with <ArgCode>=. A ColorName bracked by dollars, will change the +indicated with <ArgCode>=. A ColorName bracked by dollars, will change the foreground color. See ::/Doc/Widget.DD, ::/Demo/DolDoc/DemoDoc.DD, and -::/Demo/ToHtmlToTXTDemo/ToHtml.HC. +::/Demo/ToHtmlToTXTDemo/ToHtml.HC. -<TwoLetterCmd> See Type Defines and PrsDollarCmd(). +<TwoLetterCmd> See Type Defines and PrsDollarCmd(). +] TX Text +] CR Hard New Line +] SR Soft New Line @@ -92,7 +92,7 @@ +] HC html +] ER Error -<FlagCode> See Flag Defines and Simple Flags. +<FlagCode> See Flag Defines and Simple Flags. +] +H Hold +] +L Link +] +TR Tree @@ -108,7 +108,7 @@ +] +LC Left CallBack +] +RC Right CallBack -<ArgCode> See Arg Defines. +<ArgCode> See Arg Defines. +] T="" Tag Str +] LEN="" Field Length +] A="" Auxilliary Str diff --git a/public/Wb/Doc/Features.DD.HTML b/public/Wb/Doc/Features.DD.HTML index 63f4757..eab7988 100755 --- a/public/Wb/Doc/Features.DD.HTML +++ b/public/Wb/Doc/Features.DD.HTML @@ -54,7 +54,7 @@ * ATAPI PIO CD/DVD support with RedSea file system. Can make bootable ISO files so you can roll-your-own distro's. -* Partitioning tool, installer, boot loaders for CD/DVD and hard disk. +* Partitioning tool, installer, boot loaders for CD/DVD and hard disk. * Editor/Browser for a new Document Format. Source files and the command line window can have graphics, links, icons, trees, colors, super/sub scripts, @@ -84,7 +84,7 @@ * File Manager, <CTRL-d>. -* Code profiler, merge, diff utils. +* Code profiler, merge, diff utils. * PC Speaker support with many hymns. diff --git a/public/Wb/Doc/FileLowLevel.DD.HTML b/public/Wb/Doc/FileLowLevel.DD.HTML index 46c12e0..30cf57c 100755 --- a/public/Wb/Doc/FileLowLevel.DD.HTML +++ b/public/Wb/Doc/FileLowLevel.DD.HTML @@ -38,7 +38,7 @@ - BlkRead() BlkWrite() + BlkRead() BlkWrite() diff --git a/public/Wb/Doc/FileMgr.DD.HTML b/public/Wb/Doc/FileMgr.DD.HTML index 9a713fc..4d3a5f3 100755 --- a/public/Wb/Doc/FileMgr.DD.HTML +++ b/public/Wb/Doc/FileMgr.DD.HTML @@ -80,28 +80,28 @@ 'm' Make CD/DVD ISO.C file. This creates a RedSea ISO file image of the dir the cursor is on. The name of the ISO file is "::/Tmp/CDDVD.ISO.C" - blkdev.dft_iso_c_filename and can be redefined in your start-up scripts. You + blkdev.dft_iso_c_filename and can be redefined in your start-up scripts. You may wish to place it on a different drive. 'B' Burn CD/DVD ISO file. This burns a CD/DVD using the image file, - "::/Tmp/CDDVD.ISO" blkdev.dft_iso_filename to the drive the cursor is on. + "::/Tmp/CDDVD.ISO" blkdev.dft_iso_filename to the drive the cursor is on. Instructions on Using CD/DVD's If you have not recompiled Kernel and defined your CD/DVD drive, exit the - FileMgr and use Mount to define your CD/DVD drive. Place a CD/DVD in the + FileMgr and use Mount to define your CD/DVD drive. Place a CD/DVD in the drive and press 'c' when on top of the CD/DVD drive letter to mount the drive. - It will call DskChg(), the TempleOS cmd to mount removable media. + It will call DskChg(), the TempleOS cmd to mount removable media. Instructions on Burning CD/DVD's Create a temporary dir to hold files and copy files into the holding dir. Make an ISO image of the dir by pressing 'M' when on top of the dir. Press 'B ' when on top of the CD/DVD ROM drive to burn the ISO, "::/Tmp/CDDVD.ISO" - blkdev.dft_iso_filename, to disk. If you have not recompiled Kernel and - defined your CD/DVD drive, exit the FileMgr and use Mount. + blkdev.dft_iso_filename, to disk. If you have not recompiled Kernel and + defined your CD/DVD drive, exit the FileMgr and use Mount. - Making Your Own Distro + Making Your Own Distro diff --git a/public/Wb/Doc/FileUtils.DD.HTML b/public/Wb/Doc/FileUtils.DD.HTML index a4fba8e..11d2571 100755 --- a/public/Wb/Doc/FileUtils.DD.HTML +++ b/public/Wb/Doc/FileUtils.DD.HTML @@ -29,7 +29,7 @@
                                    File Utils
 
-File util FilesFind() wildcard mask consists of a single base dir with multiple 
+File util FilesFind() wildcard mask consists of a single base dir with multiple 
 file masks separated by ';'.  The '*' and '?' wildcard chars are accepted.  The 
 '~' is your home directory and '!' indicates an exclusion mask.
 
@@ -38,23 +38,23 @@
 "/Demo/*.BMP*;*.GR*"    BaseDir: /Demo          Mask: *.BMP* | *.GR*
 "/*.DD*;!*/Bible*"      BaseDir: Root           Mask: *.DD* but not */Bible*
 
-See FilesFindMatch().
+See FilesFindMatch().
 
 Flags are either text or int values.
 
-  FUF_RECURSE           +r Recurse
-  FUF_SINGLE            +s Single File (Optimization for one file in mask.)
-  FUF_FLATTEN_TREE      +f use with '+F'.  Just use +F, probably.
-  FUF_JUST_DIRS         +D just directories
-  FUF_JUST_FILES        +F just files (Flattens trees)
-  FUF_CLUS_ORDER        +O sort by clus (move head one direction)
-  FUF_JUST_TXT          +T just text files      : FILEMASK_TXT
-  FUF_JUST_DD           +$ just DolDoc files    : FILEMASK_DD
-  FUF_JUST_SRC          +S just src files       : FILEMASK_SRC
-  FUF_JUST_AOT          +A just aot files       : FILEMASK_AOT
-  FUF_JUST_JIT          +J just jit files       : FILEMASK_JIT
-  FUF_JUST_GR           +G just graphic files   : FILEMASK_GR
+  FUF_RECURSE           +r Recurse
+  FUF_SINGLE            +s Single File (Optimization for one file in mask.)
+  FUF_FLATTEN_TREE      +f use with '+F'.  Just use +F, probably.
+  FUF_JUST_DIRS         +D just directories
+  FUF_JUST_FILES        +F just files (Flattens trees)
+  FUF_CLUS_ORDER        +O sort by clus (move head one direction)
+  FUF_JUST_TXT          +T just text files      : FILEMASK_TXT
+  FUF_JUST_DD           +$ just DolDoc files    : FILEMASK_DD
+  FUF_JUST_SRC          +S just src files       : FILEMASK_SRC
+  FUF_JUST_AOT          +A just aot files       : FILEMASK_AOT
+  FUF_JUST_JIT          +J just jit files       : FILEMASK_JIT
+  FUF_JUST_GR           +G just graphic files   : FILEMASK_GR
 
-See ST_FILE_UTIL_FLAGS when used in calling program taking text flags.
+See ST_FILE_UTIL_FLAGS when used in calling program taking text flags.
 
diff --git a/public/Wb/Doc/Frame.DD.HTML b/public/Wb/Doc/Frame.DD.HTML index d510c3a..96c3c09 100755 --- a/public/Wb/Doc/Frame.DD.HTML +++ b/public/Wb/Doc/Frame.DD.HTML @@ -28,6 +28,6 @@
 If you require separate global vars for multiple instances of a routine, you can 
-use Frames.  See SpriteMeshEd(), ::/Demo/Graphics/Pick3D.HC or Noise().
+use Frames.  See SpriteMeshEd(), ::/Demo/Graphics/Pick3D.HC or Noise().
 
diff --git a/public/Wb/Doc/GRFiles.DD.HTML b/public/Wb/Doc/GRFiles.DD.HTML index 4315397..a77cefd 100755 --- a/public/Wb/Doc/GRFiles.DD.HTML +++ b/public/Wb/Doc/GRFiles.DD.HTML @@ -68,11 +68,11 @@ I32 width; I32 width_internal; //Rounded-up to multiple of 8. I32 height; - I32 flags; //DCF_COMPRESSED? See ::/Kernel/Compress.HC. + I32 flags; //DCF_COMPRESSED? See ::/Kernel/Compress.HC. CBGR48 palette[16]; //Included if DCF_PALETTE. U8 body[]; }; -See DCSave(), GRWrite(), DCLoad(), and GRRead(). +See DCSave(), GRWrite(), DCLoad(), and GRRead(). diff --git a/public/Wb/Doc/Glossary.DD.HTML b/public/Wb/Doc/Glossary.DD.HTML index 257a83d..2891eac 100755 --- a/public/Wb/Doc/Glossary.DD.HTML +++ b/public/Wb/Doc/Glossary.DD.HTML @@ -44,7 +44,7 @@ Bt, Bts, Btr, Btc, BEqu Define DolDoc -Editor Link Types +Editor Link Types files_find_mask Hash Table InFile diff --git a/public/Wb/Doc/GraphicsOverview.DD.HTML b/public/Wb/Doc/GraphicsOverview.DD.HTML index 54f3385..10e404c 100755 --- a/public/Wb/Doc/GraphicsOverview.DD.HTML +++ b/public/Wb/Doc/GraphicsOverview.DD.HTML @@ -71,78 +71,78 @@ -* See GrUpdateScrn(), GrUpdateTasks() and GrUpdateTaskWin() called by the WinMgr -task 30fps. Notice the task's draw_it() callback being called. Only tasks on C +* See GrUpdateScrn(), GrUpdateTasks() and GrUpdateTaskWin() called by the WinMgr +task 30fps. Notice the task's draw_it() callback being called. Only tasks on C ore0 are allowed to have windows. There is one window per task, no child windows. You can have pop-up child tasks. -* CDCs (device contexts) are a data type for controlling graphics on the scrn or +* CDCs (device contexts) are a data type for controlling graphics on the scrn or graphics in mem. The device context structure has thick and color. You use -DCAlias() to create your own structure, with its own color and thick. Free it -with DCDel() when finished. +DCAlias() to create your own structure, with its own color and thick. Free it +with DCDel() when finished. * gr.dc is a device context for persistent data on the scrn, not needing to be -redrawn. You create an alias for this by using DCAlias() and work with that. -See ::/Demo/Graphics/NetOfDots.HC. +redrawn. You create an alias for this by using DCAlias() and work with that. +See ::/Demo/Graphics/NetOfDots.HC. -* There are various flavors of line and point plotting routines. GrLine() and -GrPlot() are the simplest. The others allow 3D graphics and rotations. +* There are various flavors of line and point plotting routines. GrLine() and +GrPlot() are the simplest. The others allow 3D graphics and rotations. * See ::/Doc/Transform.DD for adding a transformation. * You change the Fs->draw_it var to point to your DrawIt() function which gets called each scrn refresh (30 fps). You draw everything in the window over and -over again. See ::/Demo/Graphics/Box.HC. +over again. See ::/Demo/Graphics/Box.HC. * Use the graphic sprite resource editor, <CTRL-r>, to create a sprite that can -be plotted with Sprite3() or output to the cmd line with Sprite(). Use $IB,"",B +be plotted with Sprite3() or output to the cmd line with Sprite(). Use $IB,"",B I=1$ in a src program to insert the addr of sprite binary data item #1. To learn how the numbers work, after creating a sprite with <CTRL-r>, toggle to plain text with <CTRL-t> and check its num. Make an assignment to a ptr var or -pass to Sprite3() with $IB,"",BI=n$. Use <CTRL-r>'s "Pointer to Sprite" to make -a $IB...$ entry. See ::/Demo/Graphics/SpritePlot.HC and -::/Demo/Graphics/SpritePlot3D.HC. The origin (zero point) for a sprite is +pass to Sprite3() with $IB,"",BI=n$. Use <CTRL-r>'s "Pointer to Sprite" to make +a $IB...$ entry. See ::/Demo/Graphics/SpritePlot.HC and +::/Demo/Graphics/SpritePlot3D.HC. The origin (zero point) for a sprite is defined by the cursor location when you pressed <CTRL-r> to make it. You can edit a sprite by clicking the cursor on it and pressing <CTRL-r> again. -* Set DCF_SYMMETRY in the CDC.flags and call DCSymmetrySet() or DCSymmetry3Set() +* Set DCF_SYMMETRY in the CDC.flags and call DCSymmetrySet() or DCSymmetry3Set() . This will plot a mirror image in addition to the primary image. Set -DCF_JUST_MIRROR to plot just the image, but this required DCF_SYMMETRY to be set +DCF_JUST_MIRROR to plot just the image, but this required DCF_SYMMETRY to be set at the same time. Note: You can only have one symmetry active at a time -including in CSprites. +including in CSprites. -* Use DCNew() to create a mem bitmap which can be used to work off-scrn and -which can be GrBloted onto the scrn. If you set brush member of CDC to another -CDC, all the graphic routines will GrBlot() the brush instead of GrPlot(). See -::/Demo/Graphics/Blot.HC. +* Use DCNew() to create a mem bitmap which can be used to work off-scrn and +which can be GrBloted onto the scrn. If you set brush member of CDC to another +CDC, all the graphic routines will GrBlot() the brush instead of GrPlot(). See +::/Demo/Graphics/Blot.HC. -* There are a few raster operations available. They go in bits 8-11 of the dc-> -color member var which is a CColorROPU32. ROP_COLLISION is special. It counts -the num of pixs drawn on non-background locations. Using ROP_COLLISION with -vector CSprite's is tricky because overlapping pixs from lines in the CSprite +* There are a few raster operations available. They go in bits 8-11 of the dc-> +color member var which is a CColorROPU32. ROP_COLLISION is special. It counts +the num of pixs drawn on non-background locations. Using ROP_COLLISION with +vector CSprite's is tricky because overlapping pixs from lines in the CSprite reg as collisions. You can either work with a nonzero count or convert your -CSprite to a bitmap if your subelements draw on top of each other. Be sure to -set ->bkcolor before using ROP_COLLISION. See ::/Demo/Graphics/Collision.HC and -Titanium. +CSprite to a bitmap if your subelements draw on top of each other. Be sure to +set ->bkcolor before using ROP_COLLISION. See ::/Demo/Graphics/Collision.HC and +Titanium. -* The ->dither_probability_u16 member of CDC is a U16 used to statistically sel +* The ->dither_probability_u16 member of CDC is a U16 used to statistically sel between two colors to get something resembling more shades of color. See -::/Demo/Graphics/SunMoon.HC and ::/Demo/Graphics/Shading.HC. It works with many +::/Demo/Graphics/SunMoon.HC and ::/Demo/Graphics/Shading.HC. It works with many graphic routines, but not those with pens. * There is a mechanism built-in for generating motion based on differential -equations, which allows realistic physics. You create an CMathODE struct with -ODENew(), passing it the num of vars in the state vect. For realistic physics, +equations, which allows realistic physics. You create an CMathODE struct with +ODENew(), passing it the num of vars in the state vect. For realistic physics, you usually have 2 state vars for each dimension (for each mass) because motion is governed by F=mA which is a 2nd order equation. The two states are pos and velocity and to solve these you need to supply the derivative of pos and velocity. The derivative of pos is usually simply the current velocity and the derivative of velocity is the acceleration (the sum of forces on a mass divided by mass). To help provide meaningful names for values in the state vect, you -can create an COrder2D3 ptr and point it to a mass in the state vect. Six +can create an COrder2D3 ptr and point it to a mass in the state vect. Six elements in the state vect are required for each mass. See Math/CMathODE. -See ::/Demo/Games/Rocket.HC. +See ::/Demo/Games/Rocket.HC. diff --git a/public/Wb/Doc/GuideLines.DD.HTML b/public/Wb/Doc/GuideLines.DD.HTML index afc648d..0f72d00 100755 --- a/public/Wb/Doc/GuideLines.DD.HTML +++ b/public/Wb/Doc/GuideLines.DD.HTML @@ -46,11 +46,11 @@ /Kernel The core of the operating system is found here. Since priviledge levels are not used, calling it a kernel is deceptive. It is AOT compiled by -BootHDIns(). It is loaded by the boot loader and must fit in 640K. +BootHDIns(). It is loaded by the boot loader and must fit in 640K. /Compiler The compiler module src code is found here. The compiler is AOT compiled to produce a binary file which is loaded at boot. It, too, is AOT -compiled by BootHDIns(). +compiled by BootHDIns(). /Adam The non-kernel part of the operating system is found here. It is JIT compiled during boot. The Adam Task is the father of all tasks, like Adam and @@ -58,7 +58,7 @@ /0000Boot Boot files go here. Stage 2 of the TempleOS hard drive master boot loader, the old hard drive master boot record which is just blk#0, and the -CD/DVD 0000Kernel.BIN.C file go here. ASCII 0000 is near the top, +CD/DVD 0000Kernel.BIN.C file go here. ASCII 0000 is near the top, alphabetically, in case you use MagicISO. @@ -66,22 +66,22 @@ ::/Home Files The home dir is specified with '~'. The home dir is ::/Home unless you change -it with HomeSet() or compile the kernel with a cfg option. An empty /Home dir +it with HomeSet() or compile the kernel with a cfg option. An empty /Home dir should be valid because it will get default files from the root dir. -~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in +~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in the upper left border area of a window. -~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key. +~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key. -~/MakeHome.HC a file compiled by the Adam Task during StartOS. +~/MakeHome.HC a file compiled by the Adam Task during StartOS. ~/Home* Copy Home* files from the root into ~ and customize them. These files are invoked when the Adam Task starts-up. -~/Once.HC a file invoked at the start-up of the first user. Customize this! +~/Once.HC a file invoked at the start-up of the first user. Customize this! -~/Registry.HC can be edited by hand or deleted to reset to defaults. Takes +~/Registry.HC can be edited by hand or deleted to reset to defaults. Takes affect next boot. @@ -97,7 +97,7 @@ * Place user data in a subdirectory of /Home, preferably naming the subdirectory the same as the /Apps subdirectory. Or, place data in the Registry.HC.Z file. -See ::/Demo/RegistryDemo.HC. +See ::/Demo/RegistryDemo.HC. * If the app needs files in the /Home directory, make an /Apps file called Insta ll.HC.Z or Install.IN.Z to create the /Home subdirectory. @@ -107,10 +107,10 @@ Programming Guidelines * Virtual mem/Paging is not used -- it is identity mapped in x86_64 mode. The -stk does not grow, so alloc enough when the task (process) is Spawned and use -the heap for most things. (The heap refers to MAlloc() and Free().) +stk does not grow, so alloc enough when the task (process) is Spawned and use +the heap for most things. (The heap refers to MAlloc() and Free().) -* You can Free(NULL). +* You can Free(NULL). * See Naming Convention and Abbreviations. @@ -137,7 +137,7 @@ * Avoid boolean expression assignments. Boolean assignments don't have short circuit logic and are not compiled efficiently. The Bool type is just an alias -for a 1 byte signed int -- nothing forces it to 1 or 0. There is a ToBool() +for a 1 byte signed int -- nothing forces it to 1 or 0. There is a ToBool() function that will for to 1 ot 0, however. * Glbl vars in AOT BIN modules are initialized to zero. They occupy space in @@ -148,13 +148,13 @@ locked semaphore. I think semiphores need to be in their own cache line, but I'm not sure. I use lock bits in a lot of places not aligned. -* SysDbg() and IsSysDbg() are really handy when working on the compiler or +* SysDbg() and IsSysDbg() are really handy when working on the compiler or kernel. It's just a bit you can set and test. * I don't use U0 * because the size is zero for ptr arithmetic. -* Use CH_SHIFT_SPACE for spaces in quotes in source code because I run -Spaces-to-Tabs on source code. +* Use CH_SHIFT_SPACE for spaces in quotes in source code because I run +Spaces-to-Tabs on source code. * Do not use #if or #ifdef @@ -162,7 +162,7 @@ Hash Sym Tables -* See ::/Adam/AHash.HC for examples of how the hash tables are set-up. +* See ::/Adam/AHash.HC for examples of how the hash tables are set-up. Basically, syms are placed into hash tables and child process hash tables are chained to parents. This provides scopes for vars and functions. @@ -174,10 +174,10 @@ prompt, make changes and reinclude it. Old syms are overshadowed but they are still there. Periodically, kill the TASK and start fresh when mem is low. If you wish your applications to free themselves instead of staying in mem, spawn -or PopUp() a task to run the application and kill it when it's done. +or PopUp() a task to run the application and kill it when it's done. -* To display the contents of a hash table, use the Who() routine or the -varients. HashDepthRep() gives a histogram of how long the chains are, in case +* To display the contents of a hash table, use the Who() routine or the +varients. HashDepthRep() gives a histogram of how long the chains are, in case you wish to make hash table sizes bigger. @@ -186,18 +186,18 @@ See ::/Doc/Asm.DD. -* FS must always point to the cur CTask. +* FS must always point to the cur CTask. -* GS must always point to the cur CCPU. +* GS must always point to the cur CCPU. * Don't change the segment regs unless interrupts are off. It's hard to do, -anyway. SET_FS_BASE and SET_GS_BASE. +anyway. SET_FS_BASE and SET_GS_BASE. * When interacting with HolyC compiled code, preserve RBP, RSI, RDI, R10-R15 because the compiler uses these for reg vars. You are free to clobber RAX, RBX, -RCX, RDX, R8 and R9. See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS +RCX, RDX, R8 and R9. See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS -* I recommend using the standard stk frame for functions because Caller() is +* I recommend using the standard stk frame for functions because Caller() is used to display the call stk, such as for the wallpaper. PUSH RBP MOV RBP,RSP diff --git a/public/Wb/Doc/Hash.DD.HTML b/public/Wb/Doc/Hash.DD.HTML index 3cad306..ace60b9 100755 --- a/public/Wb/Doc/Hash.DD.HTML +++ b/public/Wb/Doc/Hash.DD.HTML @@ -58,22 +58,22 @@ parent task's sym table is checked. All tasks chain back to the Adam task. TempleOS sym tables are implemented with an array of linked-lists. A num is -generated from a string by HashStr() to index into the array of linked-lists. +generated from a string by HashStr() to index into the array of linked-lists. Multiple strings can generate the same num, so linked-lists are built. Newer entries overshadow older ones. -There are various types of entries. See Hash Entry Types. +There are various types of entries. See Hash Entry Types. -Symbol Look-up (Used many places including the JIT Compiler and Loader.) -1) Symbol name is hashed by adding and shifting the ASCII of all chars. -2) hash table->body[] array is indexed. +Symbol Look-up (Used many places including the JIT Compiler and Loader.) +1) Symbol name is hashed by adding and shifting the ASCII of all chars. +2) hash table->body[] array is indexed. 3) Linked-lst is traversed until match of text and type of entry. -4) If not found, hash table->next table is searched. +4) If not found, hash table->next table is searched. Duplicate entries are allowed -- they overshadow old entries. Address-to-Symbol Look-up (Slow because not important. We could use trees.) -1) FunSeg Cache is scanned. -2) Hash Tables are scanned. +1) FunSeg Cache is scanned. +2) Hash Tables are scanned. diff --git a/public/Wb/Doc/HeapDbg.DD.HTML b/public/Wb/Doc/HeapDbg.DD.HTML index dfb899b..285bb14 100755 --- a/public/Wb/Doc/HeapDbg.DD.HTML +++ b/public/Wb/Doc/HeapDbg.DD.HTML @@ -27,7 +27,7 @@
-Recompile the kernel with _CFG_HEAP_DBG=TRUE if you want more heap debugging.  
+Recompile the kernel with _CFG_HEAP_DBG=TRUE if you want more heap debugging.  
 You are on your own.
 
diff --git a/public/Wb/Doc/HelpIndex.DD.HTML b/public/Wb/Doc/HelpIndex.DD.HTML index 116e623..b913d67 100755 --- a/public/Wb/Doc/HelpIndex.DD.HTML +++ b/public/Wb/Doc/HelpIndex.DD.HTML @@ -89,7 +89,7 @@ Job Key Allocations Keyboard Devices -Link Types +Link Types Math Memory Overview Memory Routines diff --git a/public/Wb/Doc/HelpSystem.DD.HTML b/public/Wb/Doc/HelpSystem.DD.HTML index 49cb9d6..1e9e630 100755 --- a/public/Wb/Doc/HelpSystem.DD.HTML +++ b/public/Wb/Doc/HelpSystem.DD.HTML @@ -30,12 +30,12 @@ #help_index "Topic/SubTopic;OtherTopic" The help index preprocessor compiler directive sets the topics for syms subsequently defined. You specify subtopics with a '/' tree hierarchy and -separate multiple topics with a ';'. The index ctrls HI:index links. +separate multiple topics with a ';'. The index ctrls HI:index links. public causes a sym to appear in help_index reports. #help_file "filename[.DD.Z]" The help file preprocessor directive makes a file into the heading of a -HI:index report for the current help index. +HI:index report for the current help index. diff --git a/public/Wb/Doc/HolyC.DD.HTML b/public/Wb/Doc/HolyC.DD.HTML index 7346260..a2cd37f 100755 --- a/public/Wb/Doc/HolyC.DD.HTML +++ b/public/Wb/Doc/HolyC.DD.HTML @@ -62,8 +62,8 @@ Test(,3); -* A char const all alone is sent to PutChars(). A string with or without args -is sent to Print(). An empty string literal signals a variable fmt_str follows. +* A char const all alone is sent to PutChars(). A string with or without args +is sent to Print(). An empty string literal signals a variable fmt_str follows. void DemoC(char drv,char *fmt,char *name,int age) { @@ -86,8 +86,8 @@ * When dealing with function addresses such as for callbacks, precede the name with "&". -* Type casting is postfix. To typecast int or F64, use ToI64(), ToBool() or -ToF64(). (TempleOS follows normal C float<-->int conversion, but sometimes you +* Type casting is postfix. To typecast int or F64, use ToI64(), ToBool() or +ToF64(). (TempleOS follows normal C float<-->int conversion, but sometimes you want to override. These functions are better than multiplying by "1.0" to convert to float.) @@ -95,7 +95,7 @@ start-up, in order. * There are no bit fields, but there are bit access routines and you can access -bytes or words within any int. See I64 declaration. A class can be accessed as +bytes or words within any int. See I64 declaration. A class can be accessed as a whole are subints, if you put a type in front of the class declaration. public I64i union I64 //"I64i" is intrinsic. We are defining "I64". @@ -128,8 +128,8 @@ public U0 GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...) { - U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);//SPrintF() with MAlloc()ed string. - GrPutS(dc,x,y,buf); //Plot string at x,y pixels. GrPutS is not public. + U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);//SPrintF() with MAlloc()ed string. + GrPutS(dc,x,y,buf); //Plot string at x,y pixels. GrPutS is not public. Free(buf); } @@ -154,7 +154,7 @@ * Allows ranges like "case 4...7:" in switch stmts. * A no case number causes next higher int case in switch stmts. See -::/Demo/NullCase.HC. +::/Demo/NullCase.HC. I64 i; for (i=0;i<20;i++) @@ -170,7 +170,7 @@ * Switch statements can be nestled with a single switch expression! This is known as a "sub_switch" statement. start/end are used to group cases. Don't goto out of, throw an exception out of, or return out of the start front porch -area. See ::/Demo/SubSwitch.HC. +area. See ::/Demo/SubSwitch.HC. I64 i; for (i=0;i<10;i++) @@ -200,7 +200,7 @@ U0 Main() { - //Only use REGG_LOCAL_VARS or REGG_LOCAL_NON_PTR_VARS for reg vars or else + //Only use REGG_LOCAL_VARS or REGG_LOCAL_NON_PTR_VARS for reg vars or else clobbered. I64 reg R15 i=5, noreg j=4; no_warn i; @@ -217,10 +217,10 @@ } * interrupt, haserrcode, public, argpop or noargpop are function flags. See -IRQKbd(). +IRQKbd(). * A single quote can encompass multiple characters. 'ABC' is equ to 0x434241. -PutChars() takes multiple characters. +PutChars() takes multiple characters. asm { HELLO_WORLD:: @@ -241,7 +241,7 @@ * There is no question-colon operator. -* TempleOS operator precedence +* TempleOS operator precedence `,>>,<< *,/,% & @@ -255,15 +255,15 @@ || =,<<=,>>=,*=,/=,&=,|=,^=,+=,-= -* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in +* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in code. -* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find dup local var type stmts. +* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find dup local var type stmts. * With the #exe{} feature in your src code, you can place programs that insert -text into the stream of code being compiled. See #exe {} for an example where +text into the stream of code being compiled. See #exe {} for an example where the date/time and compile-time prompting for cfguration data is placed into a -program. StreamPrint() places text into a src program stream following the +program. StreamPrint() places text into a src program stream following the conclusion of the #exe{} blk. * No #define functions exist (I'm not a fan) @@ -279,23 +279,23 @@ offset in a class definition. * union is more like a class, so you don't reference it with a union label after -you define it. Some common unions are declared in KernelA.HH for 1,2,4 and 8 +you define it. Some common unions are declared in KernelA.HH for 1,2,4 and 8 byte objects. If you place a type in front of a union declaration, that is the -type when used by itself. See ::/Demo/SubIntAccess.HC. +type when used by itself. See ::/Demo/SubIntAccess.HC. * class member vars can have meta data. format and data are two meta data types now used. All compiler structures are saved and you can access the compiler's -info about classes and vars. See ::/Demo/ClassMeta.HC and DocForm(). +info about classes and vars. See ::/Demo/ClassMeta.HC and DocForm(). * There is a keyword lastclass you use as a dft arg. It is set to the class -name of the prev arg. See ::/Demo/LastClass.HC, ClassRep(), DocForm() and -::/Demo/Dsk/BlkDevRep.HC. +name of the prev arg. See ::/Demo/LastClass.HC, ClassRep(), DocForm() and +::/Demo/Dsk/BlkDevRep.HC. -* See ::/Demo/Exceptions.HC. try{} catch{} and throw are different from C++. th +* See ::/Demo/Exceptions.HC. try{} catch{} and throw are different from C++. th row is a function with an 8-byte or less char arg. The char string passed in th row() can be accessed from within a catch{} using the Fs->except_ch. Within a c atch {} blk, set the var Fs->catch_except to TRUE if you want to terminate the -search for a hndlr. Use PutExcept() as a hndlr, if you like. +search for a hndlr. Use PutExcept() as a hndlr, if you like. * A function is available similar to sizeof which provides the offset of a member of a class. It's called offset. You place the class name and member @@ -308,21 +308,21 @@ * lock{} can be used to apply asm LOCK prefixes to code for safe multicore read-modify-write accesses. The code bracked with have LOCK asm prefix's applied to relevant insts within. It's a little shoddy. See -::/Demo/MultiCore/Lock.HC. +::/Demo/MultiCore/Lock.HC. -* There is a function called MSize() which gives the size of an object alloced +* There is a function called MSize() which gives the size of an object alloced off the heap. For larger size allocations, the system rounds-up to a power of two, so MSize() lets you know the real size and you can take full advantage of it. -* You CAN Free() a NULL ptr. Useful variants of MAlloc() can be found Here. +* You CAN Free() a NULL ptr. Useful variants of MAlloc() can be found Here. Each task has a heap and you can MAlloc and Free off-of other task's heaps, or -make an independent heap with HeapCtrlInit(). See HeapLog() for an example. +make an independent heap with HeapCtrlInit(). See HeapLog() for an example. * The stk does not grow because virtual mem is not used. I recommend allocating -large local vars from the heap. You can change MEM_DFT_STK and recompile Kernel -or request more when doing a Spawn(). You can use CallStkGrow(), but it's odd. -See ::/Demo/StkGrow.HC. +large local vars from the heap. You can change MEM_DFT_STK and recompile Kernel +or request more when doing a Spawn(). You can use CallStkGrow(), but it's odd. +See ::/Demo/StkGrow.HC. * Only one base class is allowed. diff --git a/public/Wb/Doc/InFile.DD.HTML b/public/Wb/Doc/InFile.DD.HTML index a4609cc..ef12804 100755 --- a/public/Wb/Doc/InFile.DD.HTML +++ b/public/Wb/Doc/InFile.DD.HTML @@ -31,19 +31,19 @@ tour is done with an InFile. It reminds me of a Unix pipe because StdOut of one gets chained into StdIn of another. -When an InFile runs, a child task is Spawn()ed which intercepts real user input +When an InFile runs, a child task is Spawn()ed which intercepts real user input and generates fake input. InFiles are HolyC programs run by the child whose -stdout goes to the parent's input buffer. Msg() can be included in an InFile to +stdout goes to the parent's input buffer. Msg() can be included in an InFile to send special keys or mouse cmds to the parent. While an InFile is running, the normal input gets diverted to the InFile task and can be filtered and sent back to the parent task. Unless you are driving functions which prompt for data, you can probably use an #include file in place of an InFile. -See ::/Demo/InFile/InDir.IN. +See ::/Demo/InFile/InDir.IN. -Note: In("") can be used if all you need is to send ASCII characters. It -differs from InStr(). You'll probably use In() a lot and not InStr(). With In( +Note: In("") can be used if all you need is to send ASCII characters. It +differs from InStr(). You'll probably use In() a lot and not InStr(). With In( ), for example, you can place answers to the prompts for recompiling the Kernel -module during BootHDIns(). +module during BootHDIns(). diff --git a/public/Wb/Doc/Install.DD.HTML b/public/Wb/Doc/Install.DD.HTML index bce3e0f..3c29a84 100755 --- a/public/Wb/Doc/Install.DD.HTML +++ b/public/Wb/Doc/Install.DD.HTML @@ -39,7 +39,7 @@ connecting a spare additional hard drive and using the BIOS to select which drive to boot. -The ::/Misc/OSInstall.HC script will automate much of this. It runs if you boot +The ::/Misc/OSInstall.HC script will automate much of this. It runs if you boot the CD/DVD-ROM. See Boot.DD for an overview of booting. See Requirements for supported @@ -50,7 +50,7 @@ for your TempleOS partitions. 1) - Mount() use if the drive is partitioned. + Mount() use if the drive is partitioned. This command mounts a drive making it accessible. For simplicity, sel 'C' as the first drive letter for your hard drive. The first partition will be 'C', second, 'D', etc. TempleOS needs 3 numbers to utilize a hard drive -- @@ -58,9 +58,9 @@ C with a 0x prefix. If the probe was successful, you can just enter the number in the probe box instead of base0. - DskPrt('C') use if drive is not partitioned + DskPrt('C') use if drive is not partitioned - This will perform a special Mount() automatically. + This will perform a special Mount() automatically. WARNING: This command erases everything on a hard drive. It repartitions a whole drive and formats the partitions. This command should be skipped if @@ -68,28 +68,28 @@ WARNING: This command doesn't play well with other operating systems. - You'll need to do a BootMHDZero() to restore your drive to a state where + You'll need to do a BootMHDZero() to restore your drive to a state where other operating systems can partition it. -2) Fmt('D',TRUE,FALSE,FSt_FAT32) +2) Fmt('D',TRUE,FALSE,FSt_FAT32) This command formats a drive with FAT32 or the RedSea file system type. Use the drive letter of the partition in place of 'D'. WARNING: If you are upgrading, be sure not to lose the file, /0000Boot/OldMBR .BIN.C. -3) CopyTree("T:/","D:/") +3) CopyTree("T:/","D:/") This command is used to copy files onto a hard drive partition from the CD/DVD. Use the drive letter of the partition in place of 'D'. -4) BootHDIns('D') +4) BootHDIns('D') This command recompiles the source code on a drive and writes to the drive's - boot record. You'll need to reenter the Mount information so it can be stored + boot record. You'll need to reenter the Mount information so it can be stored in the kernel. -5) Use Linux's Grub or TempleOS' BootMHDIns('D') +5) Use Linux's Grub or TempleOS' BootMHDIns('D') - The BootMHDIns() command places a boot loader on a drive. It saves the old + The BootMHDIns() command places a boot loader on a drive. It saves the old master boot record to /0000Boot/OldMBR.BIN.C and replaces it. When you boot, you will have the option of booting the old master boot record. This command can be skipped if you already have a boot loader. Be sure not to lose the diff --git a/public/Wb/Doc/Job.DD.HTML b/public/Wb/Doc/Job.DD.HTML index cad1cff..ecb46f6 100755 --- a/public/Wb/Doc/Job.DD.HTML +++ b/public/Wb/Doc/Job.DD.HTML @@ -28,44 +28,44 @@
 /* Graphics Not Rendered in HTML */
-               PopUpPrint                         User          ExePrint
+               PopUpPrint                         User          ExePrint
 
 
 
-                  PopUp                                          ExePutS
+                  PopUp                                          ExePutS
 
 
 
- Core0 AdamTask  SrvCmdLine   AP SethTask       UserCmdLine
+ Core0 AdamTask  SrvCmdLine   AP SethTask       UserCmdLine
 
 
 
 
 
 
-         SrvTaskCont                          UserTaskCont
+         SrvTaskCont                          UserTaskCont
 
 
 
-        JobsHndlr
+        JobsHndlr
 
 
 
-         JobRunOne           JobRunOne         ExeCmdLine      ExeCmdLine
+         JobRunOne           JobRunOne         ExeCmdLine      ExeCmdLine
 
 
 
 
-CJob nodes are one of five types.  User applications deal with text or msgs.  
-JobRunOne() will call a function, spawn a task or execute some text src code.
+CJob nodes are one of five types.  User applications deal with text or msgs.  
+JobRunOne() will call a function, spawn a task or execute some text src code.
 
-#define JOBT_TEXT_INPUT         0 //TaskText()  Feed StdIn 
-#define JOBT_MSG                1 //TaskMsg()   Post msg 
-#define JOBT_EXE_STR            2 //TaskExe()   Compile & execute src code text
-#define JOBT_CALL               3 //JobQue()    Tell MP to call function
-#define JOBT_SPAWN_TASK         4 //Spawn()     Tell MP to spawn task
+#define JOBT_TEXT_INPUT         0 //TaskText()  Feed StdIn 
+#define JOBT_MSG                1 //TaskMsg()   Post msg 
+#define JOBT_EXE_STR            2 //TaskExe()   Compile & execute src code text
+#define JOBT_CALL               3 //JobQue()    Tell MP to call function
+#define JOBT_SPAWN_TASK         4 //Spawn()     Tell MP to spawn task
 
-Several other routines include a call to JobsHndlr() that gives them powerful 
+Several other routines include a call to JobsHndlr() that gives them powerful 
 ability to execute servant cmds.
 
diff --git a/public/Wb/Doc/KeyAlloc.DD.HTML b/public/Wb/Doc/KeyAlloc.DD.HTML index 36d5049..815eb33 100755 --- a/public/Wb/Doc/KeyAlloc.DD.HTML +++ b/public/Wb/Doc/KeyAlloc.DD.HTML @@ -34,19 +34,19 @@ See
Key Map for a detailed list of key commands. When you are at the cmd line, editing documents, browsing documentation and -help, entering items in forms or in menu's, the DolDoc editor handles keys. It -allows you to define your own key hndlrs in a MyPutKey() function. If you -choose, you can catch keys, overriding the default hndlrs. See DocPutKey(). +help, entering items in forms or in menu's, the DolDoc editor handles keys. It +allows you to define your own key hndlrs in a MyPutKey() function. If you +choose, you can catch keys, overriding the default hndlrs. See DocPutKey(). The following is an overview of key allocations. -<ALT-keys> and <ALT-SHIFT-keys> Free for user configurations in your MyPutKey() +<ALT-keys> and <ALT-SHIFT-keys> Free for user configurations in your MyPutKey() hndlr, except for ALT-BACKSPACE (undo). There are a few examples pre-defined, but you can change them if you wish. <CTRL-ALT-keys> and <CTRL-ALT-SHIFT-keys> Handled at a system level, NOT by the -CDoc editor. I reserve the right to alloc these, but in the mean time, you can -define your own hndlrs with CtrlAltCBSet(). They operate either in a interrupt -environment or in the window mgr when it queues kbd msgs. You can do Raw() +CDoc editor. I reserve the right to alloc these, but in the mean time, you can +define your own hndlrs with CtrlAltCBSet(). They operate either in a interrupt +environment or in the window mgr when it queues kbd msgs. You can do Raw() output. <CTRL-ALT-letter> hndlrs take a scan_code as an arg. <CTRL-function key> Auto-completes local words. diff --git a/public/Wb/Doc/KeyDev.DD.HTML b/public/Wb/Doc/KeyDev.DD.HTML index 97f6be9..f7c40a2 100755 --- a/public/Wb/Doc/KeyDev.DD.HTML +++ b/public/Wb/Doc/KeyDev.DD.HTML @@ -27,26 +27,26 @@
-The editor mostly stays in a GetKey()/PutKey() loop.  The putkey portion is 
+The editor mostly stays in a GetKey()/PutKey() loop.  The putkey portion is 
 where keys are acted-upon.  TempleOS has a chain of putkey hndlrs in a 
 Circular Queue with priorities.  The highest priority hndlrs can choose to 
 terminate handling, otherwise, the keys get sent on down the chain.
 
-KeyDevAdd() defines a putkey device with a priority.  "Device" might be a 
+KeyDevAdd() defines a putkey device with a priority.  "Device" might be a 
 misnomer.  Currently, the following are defined:
 
 Priority    Hndlr
 ---------- ---------
-0x20000000 MyPutKey() user hndlr
-0x40000000 KDInputFilterPutKey() for In(), InStr(), and InFile() handling.
-0x60000000 KDRawPutKey() nonwindowed direct to video mem debug output. 
-0x80000000 KDDocPutKey() standard document cmds
+0x20000000 MyPutKey() user hndlr
+0x40000000 KDInputFilterPutKey() for In(), InStr(), and InFile() handling.
+0x60000000 KDRawPutKey() nonwindowed direct to video mem debug output. 
+0x80000000 KDDocPutKey() standard document cmds
 
 Since handling individual keys is slow, TempleOS supports PutS() as well.  If no 
 puts hndlr is defined, individual keys are sent.
 
-CDoc.user_put_key and CDoc.user_put_s are call back routines which offer some 
-neat tricks.  See ::/Apps/Psalmody/JukeBox.HC.  There is a var CDoc.user_put_dat
+CDoc.user_put_key and CDoc.user_put_s are call back routines which offer some 
+neat tricks.  See ::/Apps/Psalmody/JukeBox.HC.  There is a var CDoc.user_put_dat
 a which gets passed to them.
 
diff --git a/public/Wb/Doc/Lex.DD.HTML b/public/Wb/Doc/Lex.DD.HTML index d8241a5..c5ec281 100755 --- a/public/Wb/Doc/Lex.DD.HTML +++ b/public/Wb/Doc/Lex.DD.HTML @@ -28,8 +28,8 @@
 The compiler's lexical analyzer can be used in your programs to simplify 
-parsing.  See Doc Parsing or Parse Opcode File.
+parsing.  See Doc Parsing or Parse Opcode File.
 
-See Tokens.
+See Tokens.
 
diff --git a/public/Wb/Doc/MemOverview.DD.HTML b/public/Wb/Doc/MemOverview.DD.HTML index f7c0c85..1e27208 100755 --- a/public/Wb/Doc/MemOverview.DD.HTML +++ b/public/Wb/Doc/MemOverview.DD.HTML @@ -41,42 +41,42 @@ 2Gig memory addresses including what would normally be called "the kernel". Two Gig is plenty for code, don't worry. -You can create new, independent heaps using
HeapCtrlInit(). Then, use the -CHeapCtrl as the 2nd arg to MAlloc(). See HeapLog() for an example. +You can create new, independent heaps using HeapCtrlInit(). Then, use the +CHeapCtrl as the 2nd arg to MAlloc(). See HeapLog() for an example. Memory alloced by a task will be freed when the task is killed. The Adam Task is a task that never dies. His memory is like kernel memory in other operating -systems. See ACAlloc(), AMAlloc(), AMAllocIdent() and AStrNew(). +systems. See ACAlloc(), AMAlloc(), AMAllocIdent() and AStrNew(). All of the regular page tables are marked, "cached". When accessing hardware, however, you need uncached page table. The lowest 4Gig addresses have an alias to access hardware located toward the top of mapped space, 0x10000000000. See -dev.uncached_alias. +dev.uncached_alias. During an extended powered-on session of TempleOS, in theory, memory will become fragmented, requiring a reboot. It has never happens to me. -See MemRep() and ::/Demo/MemDemo.HC. +See MemRep() and ::/Demo/MemDemo.HC. Single System-wide Mem Map 0x0000007C00- 0x000003616F - Kernel module, placed here by the boot-loader, BOOT_RAM_BASE. + Kernel module, placed here by the boot-loader, BOOT_RAM_BASE. 0x0000096600- 0x0000096FFF - Boot block relocated here before loading the Kernel module, BootDVD & BootHD. + Boot block relocated here before loading the Kernel module, BootDVD & BootHD. - 0x0000097000- 0x0000097030 Multicore start-up vect code, MPN_VECT. + 0x0000097000- 0x0000097030 Multicore start-up vect code, MPN_VECT. ~0x000009F000- 0x000009FFFF Extended BIOS data area. - 0x00000A0000- 0x00000BFFFF VGA graphics mem with alias at text.vga_alias. - 0x0000100000- 0x0000101FFF CSysFixedArea for misc. + 0x00000A0000- 0x00000BFFFF VGA graphics mem with alias at text.vga_alias. + 0x0000100000- 0x0000101FFF CSysFixedArea for misc. 0x000050A000- 0x001FFDFFFF Code Heap mem. 0x00E0000000- 0x00FFFFFFFF 32-bit devices could alloc memory at 0xF0000000 going up, but this is wrong, since some PCs already have devices at 0xF0000000. No PCI devices are - supported, so Mem32DevAlloc() flaws are not an issue. + supported, so Mem32DevAlloc() flaws are not an issue. 0x0080000000-~0x00DFFFFFFF 0x0100000000-~0xFFFFFFFFFF @@ -86,19 +86,19 @@ Uncached alias of first 4Gig. (For 32-bit device access.) - 0x100FFFFFFFF - 64-bit devices are alloced with Mem64DevAlloc() counting bwd, but no PCI + 64-bit devices are alloced with Mem64DevAlloc() counting bwd, but no PCI devices are actually supported. * Note: There is a break in the data-heap block pool. This has no effect except -the obvious effect that fragmentation has on contiguous requests. I can MAlloc( -) an 8Gig chunk on my 12Gig machine. I can MAlloc() an 32Gig chunk on my 64Gig +the obvious effect that fragmentation has on contiguous requests. I can MAlloc( +) an 8Gig chunk on my 12Gig machine. I can MAlloc() an 32Gig chunk on my 64Gig machine. * Note: For systems with less than 2Gig RAM, the code and data heap block pools are the same. For systems with 2-4Gig of RAM, the code heap is 1/4 of the -total. See BlkPoolsInit(). +total. See BlkPoolsInit(). History @@ -124,20 +124,20 @@ In 2016, I came-up with an alternate idea. I double mapped the lowest memory with an alias that was uncached. Accessing the lowest 2Meg area directly was cached but the alias I created up at the top of address space was uncached. See -UncachedAliasAlloc(). Unfortunately, I could no longer boast of the simplicity +UncachedAliasAlloc(). Unfortunately, I could no longer boast of the simplicity of identity mapping everything. Since many of my users are familiar with A0000-BFFFF, it is actually pretty seriously unfortunate that they cannot use the easy-to-understand numbers of A0000-BFFFF, but must access the relocated -alias location. See text.vga_alias. I also no longer cause a fault when +alias location. See text.vga_alias. I also no longer cause a fault when dereferencing NULL. Then, I switched to 1Gig page sizes. For the lowest 4Gig, I set-up an alias up -at the top of address space. See UncachedAliasAlloc(). Not all computers +at the top of address space. See UncachedAliasAlloc(). Not all computers support 1Gig page tables, however, so I also support 2Meg. My original plan was to allow changing the page tables as needed, so I had code for taking control of 2Meg pages and marking them uncached or whatever. When I did a HDAudio driver, I requested some 32-bit address space as uncached. Today, -all of the first 4Gig can be accessed without caching at the dev.uncached_alias. +all of the first 4Gig can be accessed without caching at the dev.uncached_alias. diff --git a/public/Wb/Doc/Menus.DD.HTML b/public/Wb/Doc/Menus.DD.HTML index 2c02dca..dc8d4b0 100755 --- a/public/Wb/Doc/Menus.DD.HTML +++ b/public/Wb/Doc/Menus.DD.HTML @@ -28,7 +28,7 @@
 A pull-down menu appears when you move the mouse to the top of the scrn.  Menus 
-are created with MenuPush(), MenuFilePush(), MenuNew() or MenuFile() and 
+are created with MenuPush(), MenuFilePush(), MenuNew() or MenuFile() and 
 assigned to Fs->cur_menu.  The format is:
 
 
@@ -53,12 +53,12 @@
 }
 
 The first arg is the msg code and it is optional with the default being 
-MSG_KEY_DOWN_UP.  The second arg is the msg arg1 value which is ASCII of the key 
-in the case of MSG_KEY_DOWN.  The third arg is the msg arg2 value which is the 
-scan_code of the key in the case of MSG_KEY_DOWN.
+MSG_KEY_DOWN_UP.  The second arg is the msg arg1 value which is ASCII of the key 
+in the case of MSG_KEY_DOWN.  The third arg is the msg arg2 value which is the 
+scan_code of the key in the case of MSG_KEY_DOWN.
 
 Press <CTRL-SHIFT-l> and "Insert ASCII/ScanCode".
 
-See ::/Demo/PullDownMenu.HC.
+See ::/Demo/PullDownMenu.HC.
 
diff --git a/public/Wb/Doc/Mouse.DD.HTML b/public/Wb/Doc/Mouse.DD.HTML index a17ed7a..6c36bfb 100755 --- a/public/Wb/Doc/Mouse.DD.HTML +++ b/public/Wb/Doc/Mouse.DD.HTML @@ -27,14 +27,14 @@
-ms.pos.x and ms.pos.y can be used to access the x and y coordinates of the 
+ms.pos.x and ms.pos.y can be used to access the x and y coordinates of the 
 mouse.  They are relative to the scrn, not window.  These can be used if you 
-don't want to use msg passing.  ms.pos.z is the wheel.
+don't want to use msg passing.  ms.pos.z is the wheel.
 
-ms.pos_text.x and ms.pos_text.y are the text column and row.  See 
-::/Demo/Games/Maze.HC.
+ms.pos_text.x and ms.pos_text.y are the text column and row.  See 
+::/Demo/Games/Maze.HC.
 
-See CMsStateGlbls and CMsHardStateGlbls.
+See CMsStateGlbls and CMsHardStateGlbls.
 
 The hard designation, as in ms_hard, represents hardware layer items before the 
 application of an abstraction layer.
diff --git a/public/Wb/Doc/Msgs.DD.HTML b/public/Wb/Doc/Msgs.DD.HTML
index 7a73395..dee3f4b 100755
--- a/public/Wb/Doc/Msgs.DD.HTML
+++ b/public/Wb/Doc/Msgs.DD.HTML
@@ -28,6 +28,6 @@
 
 
 There are a maximum of 63 message types, so a bitmask can be passed.  Messages 
-have two args.  See Message Codes.
+have two args.  See Message Codes.
 
diff --git a/public/Wb/Doc/MultiCore.DD.HTML b/public/Wb/Doc/MultiCore.DD.HTML index 895b9bc..5e9b63c 100755 --- a/public/Wb/Doc/MultiCore.DD.HTML +++ b/public/Wb/Doc/MultiCore.DD.HTML @@ -32,22 +32,22 @@ and the TempleOS scheduler does not move tasks between cores. There are multicore safe locks for file access and heap allocations, however, so -TempleOS is symmetrical in some sense. See
::/Demo/MultiCore/LoadTest.HC. +TempleOS is symmetrical in some sense. See ::/Demo/MultiCore/LoadTest.HC. Only tasks on Core0 can have windows, but other cores can help render them. Each core has an executive Seth Task which is the father of all tasks on that core. Adam is the Seth Task on Core0. -You give a job to a Seth Task with JobQue() and get the result with JobResGet(). - You spawn a task on any core with Spawn(). +You give a job to a Seth Task with JobQue() and get the result with JobResGet(). + You spawn a task on any core with Spawn(). Note: You must use the LOCK asm prefix when changing shared structures in a -multicore environment. The LBts(), LBtr() and LBtc() insts have LOCK prefixes. +multicore environment. The LBts(), LBtr() and LBtc() insts have LOCK prefixes. The compiler has a lock{} feature but it doesn't work well. See -::/Demo/MultiCore/Lock.HC. +::/Demo/MultiCore/Lock.HC. -See ::/Demo/Graphics/Transform.HC. -See ::/Kernel/MultiProc.HC. +See ::/Demo/Graphics/Transform.HC. +See ::/Kernel/MultiProc.HC.
diff --git a/public/Wb/Doc/ODE.DD.HTML b/public/Wb/Doc/ODE.DD.HTML index f195f0c..030966f 100755 --- a/public/Wb/Doc/ODE.DD.HTML +++ b/public/Wb/Doc/ODE.DD.HTML @@ -31,10 +31,10 @@ equations suitable for use in video games. (Not scientific work.) It also has some support for systems of masses and springs, to save you some work. -See CMathODE and ODEsUpdate for an overview. -See ODECallDerivative to see what support there is for masses and springs. +See CMathODE and ODEsUpdate for an overview. +See ODECallDerivative to see what support there is for masses and springs. -See ::/Demo/Games/Whap.HC, ::/Demo/Games/Rocket.HC, ::/Demo/Games/MassSpring.HC, -::/Apps/Span/SpanMain.HC or ::/Apps/X-Caliber/X-Caliber.HC. +See ::/Demo/Games/Whap.HC, ::/Demo/Games/Rocket.HC, ::/Demo/Games/MassSpring.HC, +::/Apps/Span/SpanMain.HC or ::/Apps/X-Caliber/X-Caliber.HC. diff --git a/public/Wb/Doc/Once.DD.HTML b/public/Wb/Doc/Once.DD.HTML index c485ab1..78b2712 100755 --- a/public/Wb/Doc/Once.DD.HTML +++ b/public/Wb/Doc/Once.DD.HTML @@ -27,21 +27,21 @@
-KMain()
-  includes ::/StartOS.HC
-    includes ~/MakeHome.HC
-      includes ~/HomeSys.HC
-        calls StartUpTasks()
-          includes ~/Once.HC
-            calls OnceExe().
+KMain()
+  includes ::/StartOS.HC
+    includes ~/MakeHome.HC
+      includes ~/HomeSys.HC
+        calls StartUpTasks()
+          includes ~/Once.HC
+            calls OnceExe().
 
-AOnce() appends src code to ~/Registry.HC Once/Adam tree, executed at next boot 
+AOnce() appends src code to ~/Registry.HC Once/Adam tree, executed at next boot 
 by Adam.
 
-Once()  appends src code to ~/Registry.HC Once/User tree, executed at next boot 
+Once()  appends src code to ~/Registry.HC Once/User tree, executed at next boot 
 by first User term.
 
-At boot, OnceExe(), executes Once/Adam tree, AOnceFlush()s it,
-executes Once/User tree and OnceFlush()s.
+At boot, OnceExe(), executes Once/Adam tree, AOnceFlush()s it,
+executes Once/User tree and OnceFlush()s.
 
diff --git a/public/Wb/Doc/Options.DD.HTML b/public/Wb/Doc/Options.DD.HTML index 942beda..def5955 100755 --- a/public/Wb/Doc/Options.DD.HTML +++ b/public/Wb/Doc/Options.DD.HTML @@ -29,30 +29,30 @@
                                 Compiler Options
 
-Use Option().  You might need to do #exe {Option();}.
+Use Option().  You might need to do #exe {Option();}.
 
-OPTf_GLBLS_ON_DATA_HEAP without this option, global vars are placed in the code 
+OPTf_GLBLS_ON_DATA_HEAP without this option, global vars are placed in the code 
 heap which is limited to 2Gig.  In AOT modules, global vars take-up room in the 
 .BIN file, so you might want to use this option, instead.  You might wish to 
 turn it on and off around specific vars.  A disadvantage of data heap global 
 vars in AOT modules is they can't be initialized.
 
-OPTf_EXTERNS_TO_IMPORTS and OPTf_KEEP_PRIVATE are strange options, you'll never 
+OPTf_EXTERNS_TO_IMPORTS and OPTf_KEEP_PRIVATE are strange options, you'll never 
 need.  They're to allow the same header file for Kernel to act as externs when 
 compiling itself and imports when compiled by AOT modules.
 
-OPTf_WARN_UNUSED_VAR    warning if unused var.  It is applied to functions.
+OPTf_WARN_UNUSED_VAR    warning if unused var.  It is applied to functions.
 
-OPTf_WARN_PAREN         warning if parenthesis are not needed.
+OPTf_WARN_PAREN         warning if parenthesis are not needed.
 
-OPTf_WARN_DUP_TYPES     warning if dup local var type stmts.
+OPTf_WARN_DUP_TYPES     warning if dup local var type stmts.
 
-OPTf_WARN_HEADER_MISMATCH warning if fun header does not match.
+OPTf_WARN_HEADER_MISMATCH warning if fun header does not match.
 
-OPTf_NO_REG_VAR forces all function local vars to the stk not regs.  Applied to 
+OPTf_NO_REG_VAR forces all function local vars to the stk not regs.  Applied to 
 functions.
 
-OPTf_NO_BUILTIN_CONST Disable 10-byte float consts for pi, log2_10, log10_2, 
+OPTf_NO_BUILTIN_CONST Disable 10-byte float consts for pi, log2_10, log10_2, 
 loge_2.  Applied to functions.
 
diff --git a/public/Wb/Doc/Pags.DD.HTML b/public/Wb/Doc/Pags.DD.HTML index 7101351..bb1cb6a 100755 --- a/public/Wb/Doc/Pags.DD.HTML +++ b/public/Wb/Doc/Pags.DD.HTML @@ -27,9 +27,9 @@
-The word Pag refers to an arbitrilly created MEM_PAG_SIZE unit of heap 
+The word Pag refers to an arbitrilly created MEM_PAG_SIZE unit of heap 
 allocation.  TempleOS does not alter the CPU page tables after setting them up 
-at boot in SYS_INIT_PAGE_TABLES, so the CPU hardware page size is rarely 
+at boot in SYS_INIT_PAGE_TABLES, so the CPU hardware page size is rarely 
 important.
 
diff --git a/public/Wb/Doc/PreProcessor.DD.HTML b/public/Wb/Doc/PreProcessor.DD.HTML index 7e91103..80d5b97 100755 --- a/public/Wb/Doc/PreProcessor.DD.HTML +++ b/public/Wb/Doc/PreProcessor.DD.HTML @@ -29,7 +29,7 @@
                                   PreProcessor
 
-There is no separate preprocessor pass.  The parser front-end calls Lex() which 
+There is no separate preprocessor pass.  The parser front-end calls Lex() which 
 has the preprocessor built-in.  The compiler looks ahead a token, most of the 
 time, so you might throw an extra semicolon after a directive if it's not taking 
 affect right away.
@@ -38,7 +38,7 @@
 
 #include ""     There is no angle bracket <> form of this directive.
 #exe {}         Will execute code at compile-time and can be used to insert code 
-into the stream being compiled using StreamPrint().
+into the stream being compiled using StreamPrint().
 #define         Define string const
 #assert         Print a warning during compilation if an expression is not true. 
 #if             Include code if an expresion is true.
@@ -49,6 +49,6 @@
 defined()       Is a function that can be used in expressions.
 #help_index, #help_file See Help System.
 
-See PreProcessor.
+See PreProcessor.
 
diff --git a/public/Wb/Doc/Print.DD.HTML b/public/Wb/Doc/Print.DD.HTML index e93b1b2..938606d 100755 --- a/public/Wb/Doc/Print.DD.HTML +++ b/public/Wb/Doc/Print.DD.HTML @@ -31,7 +31,7 @@ <fmt_arg> := %[-][0][<width>][.<decimals>][<flags>][h<aux_fmt_num>]<fmt_code> -See StrPrintJoin(). +See StrPrintJoin(). <flags>: @@ -45,7 +45,7 @@ For "%n", "%d" or "%u", the <aux_fmt_num> causes thousands mode. "%h?n" will pick a var exponent multiples of three unit, while "%h-3n" will display milli units or "%h6n" will display mega units. The 'k' flag is always on for "%n". - See ::/Demo/Print.HC. + See ::/Demo/Print.HC. For "%c" or "%C", the <aux_fmt_num> repeats the char that many times. @@ -54,9 +54,9 @@ "%n" floating point in engineering notation, exponents being multiples of three. If it has a <aux_fmt> code, it will display scientific units letters. - "%S" Define() entry. + "%S" Define() entry. - "%C" ToUpper() character. + "%C" ToUpper() character. "%h25c",'\n'; 25 new-lines. @@ -74,14 +74,14 @@ "%,P" link to ptr with no offset. - "%D" date. Pass a CDate. + "%D" date. Pass a CDate. - "%T" time. Pass a CDate. + "%T" time. Pass a CDate. - "%z" sub_entry of an enumerated list of text entries. See LstSub(). Pass + "%z" sub_entry of an enumerated list of text entries. See LstSub(). Pass sub_entry_num first, list second. - "%Z" DefineLstLoad() subentry. Pass sub_entry_num first, define_name second. + "%Z" DefineLstLoad() subentry. Pass sub_entry_num first, define_name second. "%Q" convert "\" to "\\" and quote to backslash quote. (For use in creating strs in strs.) @@ -91,53 +91,53 @@ Print Family -MStrPrint(U8 *fmt,...) is like StrPrint(U8 *dst,U8 *fmt,...) but it returns a -MAllocated str. It is vary handy because you don't have to worry about +MStrPrint(U8 *fmt,...) is like StrPrint(U8 *dst,U8 *fmt,...) but it returns a +MAllocated str. It is vary handy because you don't have to worry about overflow. -CatPrint(U8 *_dst,U8 *fmt,...) concatenates a formated string. +CatPrint(U8 *_dst,U8 *fmt,...) concatenates a formated string. -In(U8 *fmt,...) sends text to the current task's input buffer. -InStr(U8 *fmt,...) sends text of an InFile to the keyboard stream of the current +In(U8 *fmt,...) sends text to the current task's input buffer. +InStr(U8 *fmt,...) sends text of an InFile to the keyboard stream of the current TASK but can also do mouse cmds. -XTalk(CTask *task,U8 *fmt,...) and text to another task's input buffer. -XTalkStr(CTask *task,U8 *fmt,...) sends text of an InFile to the keyboard stream +XTalk(CTask *task,U8 *fmt,...) and text to another task's input buffer. +XTalkStr(CTask *task,U8 *fmt,...) sends text of an InFile to the keyboard stream of another TASK but can also do mouse cmds. -DocPrint(CDoc *doc,U8 *fmt,...) sends text to a document. You can buffer to a +DocPrint(CDoc *doc,U8 *fmt,...) sends text to a document. You can buffer to a Doc and save it, providing the functionality of fprintf. See -::/Demo/Dsk/FPrintF.HC. +::/Demo/Dsk/FPrintF.HC. -Adam(U8 *fmt,...) sends text to the Adam Task to be compiled and run. -AdamLog(U8 *fmt,...) and AdamErr(U8 *fmt,...) send text to the Adam Task to be +Adam(U8 *fmt,...) sends text to the Adam Task to be compiled and run. +AdamLog(U8 *fmt,...) and AdamErr(U8 *fmt,...) send text to the Adam Task to be displayed. -StreamPrint(U8 *fmt,...) sends text to the stream of code being compiled and +StreamPrint(U8 *fmt,...) sends text to the stream of code being compiled and must reside in a #exe{} blk. -GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...) and GrVPrint() plots text in graphics +GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...) and GrVPrint() plots text in graphics mode. -TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...) plots to gr.text_base. +TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...) plots to gr.text_base. -ExePrint(U8 *fmt,...) compiles and execute a string. Note: It returns the res +ExePrint(U8 *fmt,...) compiles and execute a string. Note: It returns the res of the last executed expression. -Once(U8 *fmt,...) Writes User code to Registry to be executed next boot. +Once(U8 *fmt,...) Writes User code to Registry to be executed next boot. -AOnce(U8 *fmt,...) Writes Adam code to Registry to be executed next boot. +AOnce(U8 *fmt,...) Writes Adam code to Registry to be executed next boot. -InPrint(I64 mS,U8 *fmt,...) PutChars()s one at a time with a delay. +InPrint(I64 mS,U8 *fmt,...) PutChars()s one at a time with a delay. -RawPrint(I64 mS,U8 *fmt,...) sends direct to scrn memory, bypassing window +RawPrint(I64 mS,U8 *fmt,...) sends direct to scrn memory, bypassing window manager. -User(U8 *fmt,...) Spawns a user and execute a string on start-up. +User(U8 *fmt,...) Spawns a user and execute a string on start-up. -PopUpPrint(U8 *fmt,...) compiles and execute a string in a pop-up win. Note: It +PopUpPrint(U8 *fmt,...) compiles and execute a string in a pop-up win. Note: It returns the res of the last executed expression. -PopUpViewPrint(U8 *fmt,...) creates a pop-up window and views text. +PopUpViewPrint(U8 *fmt,...) creates a pop-up window and views text. Note: Use Print("%s",src) if you need an unmodified string. diff --git a/public/Wb/Doc/Profiler.DD.HTML b/public/Wb/Doc/Profiler.DD.HTML index cd1f2ca..affc808 100755 --- a/public/Wb/Doc/Profiler.DD.HTML +++ b/public/Wb/Doc/Profiler.DD.HTML @@ -30,11 +30,11 @@ The profiler records where the CPU was executing when the 1000Hz timer interrupt occured, so you can learn where time is spent. -Use the Prof() depth argument to record a hit in the N routines which called the +Use the Prof() depth argument to record a hit in the N routines which called the current routine, as well. -When done collecting statistics, use ProfRep() for a report. You might need a -DocMax() to expand the command line window buffer to fit it all. +When done collecting statistics, use ProfRep() for a report. You might need a +DocMax() to expand the command line window buffer to fit it all. Study the code. The profiler is very simple. You might want to enhance it or modify it to debug something in particular. diff --git a/public/Wb/Doc/Que.DD.HTML b/public/Wb/Doc/Que.DD.HTML index 60f4f19..1b3e289 100755 --- a/public/Wb/Doc/Que.DD.HTML +++ b/public/Wb/Doc/Que.DD.HTML @@ -27,7 +27,7 @@
-A Queue is a bunch of MAlloc()ed chunks of mem linked together in a circle with 
+A Queue is a bunch of MAlloc()ed chunks of mem linked together in a circle with 
 one ptr to the next value and another ptr to the last value.  These ptrs must be 
 stored in the first locations in the structure.
 
diff --git a/public/Wb/Doc/Quirks.DD.HTML b/public/Wb/Doc/Quirks.DD.HTML index 7fe361d..c292cd9 100755 --- a/public/Wb/Doc/Quirks.DD.HTML +++ b/public/Wb/Doc/Quirks.DD.HTML @@ -36,31 +36,31 @@ * When using
FAT32, TempleOS does not generate unique short-entry names, the ones with the ~s. Not all FAT32 filenames are valid TempleOS names and it will complain. Do not access FAT32 drives not dedicated to TempleOS. Disable them -with DrvEnable(OFF), or they will generate error messages. FAT32 involves a +with DrvEnable(OFF), or they will generate error messages. FAT32 involves a long and short name for each file. * The stk does not grow because virtual mem is not used. I recommend allocating -large local vars from the heap. You can change MEM_DFT_STK and recompile Kernel -or request more when doing a Spawn(). +large local vars from the heap. You can change MEM_DFT_STK and recompile Kernel +or request more when doing a Spawn(). * The syntax highlighting occassionally glitches. The compiler doesn't. -* Call DskChg() when you insert a new removable media. +* Call DskChg() when you insert a new removable media. -* Accessing CD/DVD's is flacky. Try Drv() or DskChg() twice. +* Accessing CD/DVD's is flacky. Try Drv() or DskChg() twice. * You can only extern something once. There is a varient called _extern which binds a HolyC definition to a asm sym. This, too, can only be done once. -* A terminal task has a CDoc document structure that remains active even when -you change Fs->draw_it. To prevent links in the CDoc from being activated when +* A terminal task has a CDoc document structure that remains active even when +you change Fs->draw_it. To prevent links in the CDoc from being activated when the user clicks in the window, do one of three things: - A) DocBottom() followed by DocClear() to clear the CDoc so it has no active + A) DocBottom() followed by DocClear() to clear the CDoc so it has no active widgets. B) Disable window mgr bttn click checking with Fs->win_inhibit set to mask - WIF_SELF_MS_L|WIF_FOCUS_TASK_MS_L_D|WIF_SELF_MS_R|WIF_FOCUS_TASK_MS_R_D. This + WIF_SELF_MS_L|WIF_FOCUS_TASK_MS_L_D|WIF_SELF_MS_R|WIF_FOCUS_TASK_MS_R_D. This inhibits window mgr operations but still generates messages from bttn clicks. * switch/case stmts alloc a single jump table--do not use with wide, sparse @@ -71,9 +71,9 @@ * A goto label name must not match a global scope object's name. (It's not worth slowing-down the compiler to handle this case.) -* MemCpy() only goes fwd. +* MemCpy() only goes fwd. -* A Cd() cmd must be followed by two semicolons if a #include is after it. This +* A Cd() cmd must be followed by two semicolons if a #include is after it. This is because the preprocessor processes the next token ahead. * The assembler's error msgs are often off by a line and undefines are cryptic. diff --git a/public/Wb/Doc/RedSea.DD.HTML b/public/Wb/Doc/RedSea.DD.HTML index 15859c4..03bd00d 100755 --- a/public/Wb/Doc/RedSea.DD.HTML +++ b/public/Wb/Doc/RedSea.DD.HTML @@ -45,11 +45,11 @@ public class CDirEntry //64-byte fixed-size { - U16 attr; //See RS_ATTR_DIR. I would like to change these. - U8 name[CDIR_FILENAME_LEN]; //See char_bmp_filename, FileNameChk + U16 attr; //See RS_ATTR_DIR. I would like to change these. + U8 name[CDIR_FILENAME_LEN]; //See char_bmp_filename, FileNameChk I64 clus; (blk) //One sector per clus. I64 size; //In bytes - CDate datetime; //See DateTime, Implementation of DateTime + CDate datetime; //See DateTime, Implementation of DateTime }; public class CRedSeaBoot //RedSea is type FAT32 in partition table to fool BIOS. @@ -65,9 +65,9 @@ U16 signature2; //0xAA55 }; -See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC. +See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC. -Files with names ending in .Z are compressed. See ::/Kernel/Compress.HC. +Files with names ending in .Z are compressed. See ::/Kernel/Compress.HC. To replace ISO9660, make hard-drive partition image of a measured size and copy onto a CD/DVD starting at about sector 20, with EL TORITO booting. 512-byte diff --git a/public/Wb/Doc/Resource.DD.HTML b/public/Wb/Doc/Resource.DD.HTML index a21b54f..e3a9359 100755 --- a/public/Wb/Doc/Resource.DD.HTML +++ b/public/Wb/Doc/Resource.DD.HTML @@ -32,9 +32,9 @@ A sprite is an ordered list of elements such as lines, rectangles, bitmaps and color changes. In a program's source code, you first make a sprite somewhere outside a function. Then, you insert a pointer to the sprite as an "*elems" arg -when calling Sprite() or Sprite3(). See Sprites. +when calling Sprite() or Sprite3(). See Sprites. -You can create a sprite macro on your PersonalMenu with a payload of HolyC +You can create a sprite macro on your PersonalMenu with a payload of HolyC source code to execute when it ESC's back to the cmd line. If you check "Pop-Up", it will spawn a new task and run the payload. A pop-up macro can be placed in any document. diff --git a/public/Wb/Doc/ScopingLinkage.DD.HTML b/public/Wb/Doc/ScopingLinkage.DD.HTML index 761e32c..8102d8a 100755 --- a/public/Wb/Doc/ScopingLinkage.DD.HTML +++ b/public/Wb/Doc/ScopingLinkage.DD.HTML @@ -43,22 +43,22 @@ name, like DrawIt(). This case might occur when the Adam Task is starting-up loading-in many little utilities. -extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym of the same +extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym of the same name if it exists in the sym table (just in just-in-time code). It also can be used to generate a fwd reference. -import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym of the same name -imported from the task's sym table at Load() time. If no sym exists to bind to -at Load() time, the code using this sym will be left incomplete until the sym is +import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym of the same name +imported from the task's sym table at Load() time. If no sym exists to bind to +at Load() time, the code using this sym will be left incomplete until the sym is defined. -_extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym, of a differe +_extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym, of a differe nt name. It must exists in the sym table. Basically, this binds C to asm. -_import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym, of a different name -imported from the task's sym table at Load() time. If no sym exists to bind to -at Load() time, the code using this sym will be left incomplete until the sym is +_import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym, of a different name +imported from the task's sym table at Load() time. If no sym exists to bind to +at Load() time, the code using this sym will be left incomplete until the sym is defined. Basically, this binds C to asm from elsewhere. @@ -170,9 +170,9 @@ * An unused gap on the stk is left for reg vars. * Note: static function vars do not go on the data heap, no matter the setting -of the OPTf_GLBLS_ON_DATA_HEAP. They may in the future. +of the OPTf_GLBLS_ON_DATA_HEAP. They may in the future. -* OPTf_EXTERNS_TO_IMPORTS will treat _extern as _import and extern as import. +* OPTf_EXTERNS_TO_IMPORTS will treat _extern as _import and extern as import. This allows a header to be used either as a JIT compiled or AOT compiled header. diff --git a/public/Wb/Doc/Snd.DD.HTML b/public/Wb/Doc/Snd.DD.HTML index 2374046..9c6f366 100755 --- a/public/Wb/Doc/Snd.DD.HTML +++ b/public/Wb/Doc/Snd.DD.HTML @@ -28,7 +28,7 @@
 Sound is generated with I8 vals called ona's, which are 88 piano key nums, with 
-0 as a rest.  See Note2Ona() and Ona2Freq().  God does not want death screams, 
+0 as a rest.  See Note2Ona() and Ona2Freq().  God does not want death screams, 
 perhaps, because God has PTSD or soldiers have PTSD.  (Imagine wounded on 
 battlefields.)  Ona's will allow elegant wave files for export and will allow 
 the creation of simple hardware over the next centuries.
diff --git a/public/Wb/Doc/Sprite.DD.HTML b/public/Wb/Doc/Sprite.DD.HTML
index 7d000b1..5a41f16 100755
--- a/public/Wb/Doc/Sprite.DD.HTML
+++ b/public/Wb/Doc/Sprite.DD.HTML
@@ -27,17 +27,17 @@
 
 
 
-A CSprite is an ordered list of these elements, created with <CTRL-r>.  
+A CSprite is an ordered list of these elements, created with <CTRL-r>.  
 Normally, they are packed together in a list and the address of the first is 
 passed to routines.
 
-See ::/Demo/Graphics/SpritePlot.HC, ::/Demo/Graphics/SpritePlot3D.HC, 
-::/Demo/Graphics/SpritePut.HC, ::/Demo/Graphics/SpriteRaw.HC and SpriteMeshEd().
+See ::/Demo/Graphics/SpritePlot.HC, ::/Demo/Graphics/SpritePlot3D.HC, 
+::/Demo/Graphics/SpritePut.HC, ::/Demo/Graphics/SpriteRaw.HC and SpriteMeshEd().
 
 Be aware that copying SP, IB, or IS entries with the clip results in duplicate 
 entries with different nums.  You can manually remove dups by editing with <CTRL
 -t> and setting to the original num.
 
-See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
 
diff --git a/public/Wb/Doc/SpriteEd.DD.HTML b/public/Wb/Doc/SpriteEd.DD.HTML index 1fc70db..06b8503 100755 --- a/public/Wb/Doc/SpriteEd.DD.HTML +++ b/public/Wb/Doc/SpriteEd.DD.HTML @@ -38,6 +38,6 @@
Insert Shift Suborigin is an element which shifts subsequent elements. Perhaps, you inserted a sprite's elements from the clip and want to shift it around? -This command is also useful if you call SpriteInterpolate() in programs. +This command is also useful if you call SpriteInterpolate() in programs.
diff --git a/public/Wb/Doc/SpriteEdText.DD.HTML b/public/Wb/Doc/SpriteEdText.DD.HTML index 0a6e068..f60924d 100755 --- a/public/Wb/Doc/SpriteEdText.DD.HTML +++ b/public/Wb/Doc/SpriteEdText.DD.HTML @@ -29,6 +29,6 @@
                             Sprite Edit as Text Help
 
-See the format for CSprites.
+See the format for CSprites.
 
diff --git a/public/Wb/Doc/StdOutTask.DD.HTML b/public/Wb/Doc/StdOutTask.DD.HTML index e5bd9b9..f48f49e 100755 --- a/public/Wb/Doc/StdOutTask.DD.HTML +++ b/public/Wb/Doc/StdOutTask.DD.HTML @@ -27,9 +27,9 @@
-There is one CDoc for the task's border: Fs->border_doc.  There is a pair for 
+There is one CDoc for the task's border: Fs->border_doc.  There is a pair for 
 the task's client area: Fs->put_doc and Fs->display_doc.  You can, optionally, 
 do double buffering, otherwise Fs->put_doc is the same as Fs->display_doc.  See 
-::/Demo/Spy.HC.
+::/Demo/Spy.HC.
 
diff --git a/public/Wb/Doc/StdTempleOSPC.DD.HTML b/public/Wb/Doc/StdTempleOSPC.DD.HTML index ccd155a..16b5418 100755 --- a/public/Wb/Doc/StdTempleOSPC.DD.HTML +++ b/public/Wb/Doc/StdTempleOSPC.DD.HTML @@ -31,7 +31,7 @@ All desktop PCs will have 8-channel OCTART super-simple high speed serial ports to replace USB. They are simpler because the driver is as simple as old school -RS232 Serial, they have no USB end-points and they have no USB human interface +RS232 Serial, they have no USB end-points and they have no USB human interface device reports. Computer mice will all have exactly two bttns and one wheel. Game controllers will all be the standard deluxe game console controllers that are popular today. It will have 8 big TX and 8 big RX fifos that allow flow diff --git a/public/Wb/Doc/Strategy.DD.HTML b/public/Wb/Doc/Strategy.DD.HTML index 65ca4bd..d73c56f 100755 --- a/public/Wb/Doc/Strategy.DD.HTML +++ b/public/Wb/Doc/Strategy.DD.HTML @@ -115,7 +115,7 @@ * No distinction between thread, process or task. -* The Scheduler is for home systems. It is not preemptiove. Disk requests are +* The Scheduler is for home systems. It is not preemptiove. Disk requests are not broken-up, so sharing is bad. It's wonderfully simple. * MultiCore is done master/slave, instead of SMP. Core0 applications explicitly diff --git a/public/Wb/Doc/Streams.DD.HTML b/public/Wb/Doc/Streams.DD.HTML index 030195a..15310a0 100755 --- a/public/Wb/Doc/Streams.DD.HTML +++ b/public/Wb/Doc/Streams.DD.HTML @@ -33,9 +33,9 @@ serialized! Furthermore, the input can come from triggering macro widgets. See Doc Overview and Doc Routines. -If you had a remote term and sent key Scan Codes, the user would press <CTRL-m> +If you had a remote term and sent key Scan Codes, the user would press <CTRL-m> to access his Personal Menu to trigger his macros. However, the local -~/PersonalMenu.DD might differ from the remote, causing loss of sync between +~/PersonalMenu.DD might differ from the remote, causing loss of sync between local and remote sessions. Also, the window size of local and remote might differ, so word-wrapped text would be different. Injecting output text with different windows sizes would cause remote and local documents to not be in @@ -43,6 +43,6 @@ See Char Overview and Char Routines. -You can send characters into StdIn. See In(), XTalk() and InFile. +You can send characters into StdIn. See In(), XTalk() and InFile. diff --git a/public/Wb/Doc/TextBase.DD.HTML b/public/Wb/Doc/TextBase.DD.HTML index ed0424d..818c7d7 100755 --- a/public/Wb/Doc/TextBase.DD.HTML +++ b/public/Wb/Doc/TextBase.DD.HTML @@ -27,24 +27,24 @@
-gr.text_base must be updated 30fps in your Fs->draw_it() callback.  You probably 
-want GrPrint() or just Print().  The DolDoc code takes care of plotting text to 
-gr.text_base.
+gr.text_base must be updated 30fps in your Fs->draw_it() callback.  You probably 
+want GrPrint() or just Print().  The DolDoc code takes care of plotting text to 
+gr.text_base.
 
 Bits 0-7        8-Bit ASCII Scrn Code
-Bits 8-11       Foreground color
-Bits 12-15      Background color
+Bits 8-11       Foreground color
+Bits 12-15      Background color
 Bits 16-20      Signed X pos shift val
 Bits 21-25      Signed Y pos shift val
-Bit  28         Blink
-Bit  29         Inverted (Swap foreground and background)
-Bit  30         Sel (XOR colors with FF)
-Bit  31         Underline
+Bit  28         Blink
+Bit  29         Inverted (Swap foreground and background)
+Bit  30         Sel (XOR colors with FF)
+Bit  31         Underline
 
-GrUpdateTaskWin() calls DocUpdateTaskDocs() which calls DocRecalc() where the 
-document text is plotted into gr.text_base.  Then, GrUpdateTextBG() and 
-GrUpdateTextFG() render the gr.text_base onto gr.dc2, a raw graphic bitmap.
+GrUpdateTaskWin() calls DocUpdateTaskDocs() which calls DocRecalc() where the 
+document text is plotted into gr.text_base.  Then, GrUpdateTextBG() and 
+GrUpdateTextFG() render the gr.text_base onto gr.dc2, a raw graphic bitmap.
 
-See ::/Demo/Games/Maze.HC.
+See ::/Demo/Games/Maze.HC.
 
diff --git a/public/Wb/Doc/TimeCycles.DD.HTML b/public/Wb/Doc/TimeCycles.DD.HTML index e533367..49fcea7 100755 --- a/public/Wb/Doc/TimeCycles.DD.HTML +++ b/public/Wb/Doc/TimeCycles.DD.HTML @@ -29,6 +29,6 @@
 Intel/AMD have an inst that returns the num of CPU cycles since boot.  This is 
 not a steady, calibrated real time value.  TempleOS measures it and you can 
-convert with cnts.time_stamp_freq, a value continuously calibrated from other 
+convert with cnts.time_stamp_freq, a value continuously calibrated from other 
 cnts.
diff --git a/public/Wb/Doc/TimeDate.DD.HTML b/public/Wb/Doc/TimeDate.DD.HTML index 88337de..ef1860e 100755 --- a/public/Wb/Doc/TimeDate.DD.HTML +++ b/public/Wb/Doc/TimeDate.DD.HTML @@ -27,11 +27,11 @@
-TempleOS uses a 64-bit value, CDate, for date/time.  The upper 32-bits are the 
+TempleOS uses a 64-bit value, CDate, for date/time.  The upper 32-bits are the 
 days since Christ.  The lower 32-bits store time of day divided by 4 billion 
-which works out to 49710ths of a second.  You can subtract two CDate's to get a 
+which works out to 49710ths of a second.  You can subtract two CDate's to get a 
 time span.
 
-Use CDATE_FREQ to convert.
+Use CDATE_FREQ to convert.
 
diff --git a/public/Wb/Doc/TimeHPET.DD.HTML b/public/Wb/Doc/TimeHPET.DD.HTML index c730df1..6a20ce3 100755 --- a/public/Wb/Doc/TimeHPET.DD.HTML +++ b/public/Wb/Doc/TimeHPET.DD.HTML @@ -27,8 +27,8 @@
-The HPET, high precision event timer, is read with HPET() and has a frequency of 
-cnts.HPET_freq.  A typical freq value is 14.3 Mhz  It might not be available on 
+The HPET, high precision event timer, is read with HPET() and has a frequency of 
+cnts.HPET_freq.  A typical freq value is 14.3 Mhz  It might not be available on 
 all systems.
 
diff --git a/public/Wb/Doc/TimeJiffy.DD.HTML b/public/Wb/Doc/TimeJiffy.DD.HTML index 285de00..02053c9 100755 --- a/public/Wb/Doc/TimeJiffy.DD.HTML +++ b/public/Wb/Doc/TimeJiffy.DD.HTML @@ -27,12 +27,12 @@
-One jiffy is one time slice.  cnts.jiffies returns time slices since boot.
+One jiffy is one time slice.  cnts.jiffies returns time slices since boot.
 
-SysTimerRead reads the timer ticks since boot.  It's not as fast as GetTSC.
+SysTimerRead reads the timer ticks since boot.  It's not as fast as GetTSC.
 
-Use JIFFY_FREQ to convert cnts.jiffies.
+Use JIFFY_FREQ to convert cnts.jiffies.
 
-Use SYS_TIMER_FREQ to convert SysTimerRead.
+Use SYS_TIMER_FREQ to convert SysTimerRead.
 
diff --git a/public/Wb/Doc/Tips.DD.HTML b/public/Wb/Doc/Tips.DD.HTML index 8ef0b91..2537b90 100755 --- a/public/Wb/Doc/Tips.DD.HTML +++ b/public/Wb/Doc/Tips.DD.HTML @@ -32,32 +32,32 @@ * Turn-off or reboot (<CTRL-ALT-DEL>) at any time, except during disk writes. Writes are not cached. -* Use Seed() and the cmd line to switch Rand() to non-timer mode and replay +* Use Seed() and the cmd line to switch Rand() to non-timer mode and replay games you like. * 64-bit values are most efficient for the compiler. -* See Key Map for a list of defined keys. Define your own keys in MyPutKey(). +* See Key Map for a list of defined keys. Define your own keys in MyPutKey(). See Keyboard Devices. * <ALT-m> maximizes a window. <ALT-SHIFT-w> closes AutoComplete. <ALT-w> brings back AutoComplete. <ALT-v> vertically tiles windows. <ALT-h> -horizontally tiles windows. The ALT keys are defined in ~/HomeKeyPlugIns.HC. +horizontally tiles windows. The ALT keys are defined in ~/HomeKeyPlugIns.HC. You can customize them. * If you make changes to TempleOS files in your /Home directory, generally you reboot to make them take effect. (You don't compile anything.) You should have two TempleOS partitions on your hard drive because a syntax error in a start-up file will make the partition unbootable. Boot to the second partition or boot -to a standard TempleOS CD/DVD and use Mount() to mount your hard drive. +to a standard TempleOS CD/DVD and use Mount() to mount your hard drive. -* I copy my files to a mirrored ident partition, periodically with CopyTree() +* I copy my files to a mirrored ident partition, periodically with CopyTree() commands in scripts. I do merge commands with a menu entry like this: Merge(\"C:/*\",\"D:/*\",\"+r+d\"); to check my changes. * <CTRL-m> at the cmd line to access your PersonalMenu. Place macros there with <CTRL-l>, or icon-like sprites with <CTRL-r>. Use the Pop-Up option on macros -to Spawn() a task to run a file. It dies when it is finished. This returns mem +to Spawn() a task to run a file. It dies when it is finished. This returns mem to the system. Be sure to press <CTRL-s> to save your macro/menu area after making changes. @@ -69,10 +69,10 @@ the keyboard controls to games. * You can adjust the mouse movement rate by setting global vars in your start-up -file. See mouse scale. +file. See mouse scale. -* You can set your local time zone by setting the local_time_offset global var -in a start-up file. It's units are CDATE_FREQ. See local time. +* You can set your local time zone by setting the local_time_offset global var +in a start-up file. It's units are CDATE_FREQ. See local time. * <CTRL-SHIFT-L> in the editor to reindent a HolyC function or renumber an asm routine's local labels. @@ -82,76 +82,76 @@ 5 will display lines within 5 lines of matches. Then, you can do another find to a different string and achieve a AND search. When finished, press <ESC>. -* You can recompile and reinstall the kernel with BootHDIns(). You'll probably -want to make a function for recompiling that uses the In() function to answer -the cfg questions. See my technique Cfg Strs, Update Funs. +* You can recompile and reinstall the kernel with BootHDIns(). You'll probably +want to make a function for recompiling that uses the In() function to answer +the cfg questions. See my technique Cfg Strs, Update Funs. -* Scale2Mem(min,max,limit=2*1024*1024*1024) can be used for cfg questions when -recompiling. The BootHDIns() cfg prompts accept expressions, not just numbers. +* Scale2Mem(min,max,limit=2*1024*1024*1024) can be used for cfg questions when +recompiling. The BootHDIns() cfg prompts accept expressions, not just numbers. The dft disk cache is Scale2Mem(0x80000,0x8000000). -* You can permanently disable AutoComplete commenting-out ACInit() in -~/HomeSys.HC. +* You can permanently disable AutoComplete commenting-out ACInit() in +~/HomeSys.HC. * Boolean expressions not in if stmts don't have short circuit logic and are compiled inefficiently. -* You can use progress1-progress4 in your programs for whatever you like. +* You can use progress1-progress4 in your programs for whatever you like. They're just global vars that are shown on the wallpaper. The original intent was to indicate how far along operations were. There's no coordination, so different apps might interfere. I use them most for debugging--just values -easily viewed. See ::/Demo/Progress.HC. +easily viewed. See ::/Demo/Progress.HC. -* Use DocMax() to adjust the size of the cmd line buf. It counts CDoc entries, +* Use DocMax() to adjust the size of the cmd line buf. It counts CDoc entries, not lines. * Many data structures have a user_data member. Those are available for you to -store a data item, for convenience. CTask, CDocEntry and CDirEntry have them. +store a data item, for convenience. CTask, CDocEntry and CDirEntry have them. You shouldn't encounter conflicts with TempleOS using them. * If, for some strange reason, you wanted to reduce mem usage, make a smaller disk cache when you recompile the kernel; disabling AutoComplete; Specify -smaller stk sizes when doing Spawn(), chang MEM_DFT_STK, and using DocMax() to +smaller stk sizes when doing Spawn(), chang MEM_DFT_STK, and using DocMax() to reduce the cmd line buffer size. * Filenames ending in ".Z" will be automatically compressed and uncompressed when read or written. The compression method is not supported by other -operating systems. You can store files uncompressed by Move()ing them to a +operating systems. You can store files uncompressed by Move()ing them to a filename not ending in ".Z". See ::/Doc/TOSZ.DD if you want to uncompress while in Linux. -* Merge() can be used to see what's changed. The +d flag will show differences +* Merge() can be used to see what's changed. The +d flag will show differences of files which have changed and allow you to merge code. (The +r flag will recurse.) -* There is a utility LinkChk() which will check for broken links in +* There is a utility LinkChk() which will check for broken links in documentation. -* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in +* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in code. -* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find unnecessary local var type +* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find unnecessary local var type stmts. -* Option(OPTf_ECHO,ON) can be placed in StartOS.HC to echo start-up scripts. +* Option(OPTf_ECHO,ON) can be placed in StartOS.HC to echo start-up scripts. -* Use Plain() to edit a plain text file. You'll need this if your file has $'s. - Use the ToDolDoc() utility to convert plain text to DolDoc's by doubling $'s. +* Use Plain() to edit a plain text file. You'll need this if your file has $'s. + Use the ToDolDoc() utility to convert plain text to DolDoc's by doubling $'s. -* Use Silent() to disable scrn text output. +* Use Silent() to disable scrn text output. * Grab-scroll any window at any time with {CTRL-LEFT-MOUSE-DRAG}. Null grab-scrolling with {CTRL-RIGHT-MOUSE}. * Use <CTRL-ALT-z> to zoom-in and <CTRL-ALT-SHIFT-Z> to zoom-out. You can -scroll by moving to the edge of the window. Set gr.continuous_scroll to TRUE if +scroll by moving to the edge of the window. Set gr.continuous_scroll to TRUE if you want. * Use <CTRL-ALT-g> and <CTRL-ALT-SHIFT-G> to display a grid on the scrn. * Use <CTRL-ALT-a> to enter an extended ASCII char. -* Use <CTRL-ALT-f> to toggle between Std Font and Cyrillic Font. +* Use <CTRL-ALT-f> to toggle between Std Font and Cyrillic Font. * Use <CTRL-ALT-s> will capture the scrn as a sprite on the clip. You can save the cmd line doc as text with <CTRL-a>. @@ -162,13 +162,13 @@ Press 't' for transparent. * There are handy functions--F(),R(),FD() and RD() which are defined in -~/HomeWrappers.HC. You are encouraged to change them and add more. They will +~/HomeWrappers.HC. You are encouraged to change them and add more. They will perform find-and-replace operations accross multiple files. The +l flag is particularly useful since it limits to whole labels. The +lb and +la flags limit to whole labels just before or after. You are encouraged to add or modify handy wrapper functions to make cmd line operations easier. -* When using Find() while modifying code, work from the bottom-up so that line +* When using Find() while modifying code, work from the bottom-up so that line numbers are correct. If you work top-down, then inserting or deleting lines causes the lower file links will be incorrect. @@ -183,21 +183,21 @@ * There is a feature of the precompiler that allows code to be executed in the middle of compilation and data inserted into the compilation stream. Click here -for an example: #exe {. +for an example: #exe {. * If you output to the cmd line and wish to allow users to scroll around and -view data, you can use View(). +view data, you can use View(). -* Use View() in Pop-up macros to linger until the user presses <ESC> or <SHIFT-E +* Use View() in Pop-up macros to linger until the user presses <ESC> or <SHIFT-E SC>. -* You can access the word under the cursor at ac.cur_word. +* You can access the word under the cursor at ac.cur_word. * You can reactivate AutoComplete after closing it by pressing <CTRL-Fun Key> or <ALT-w> if you have it defined. -* <CTRL-SHIFT-T> to toggle to/from plain text just the CDoc cmd under the -cursor. See ::/Demo/DolDoc/TextDemo.HC. +* <CTRL-SHIFT-T> to toggle to/from plain text just the CDoc cmd under the +cursor. See ::/Demo/DolDoc/TextDemo.HC. * If you toggle to plain text when you are working with graphics in a document, you can add duplicate entries for sprites by entering a $SP...$ cmd with the @@ -209,7 +209,7 @@ * I use spaces-to-tab operations on all my src files to keep them small. You have to be careful, though, because spaces in strings will be converted. I use -<SHIFT-SPACE> ' ' in such cases. See S2T() for spaces-to-tabs. +<SHIFT-SPACE> ' ' in such cases. See S2T() for spaces-to-tabs. * You can edit an existing sprite by putting the cursor on it and pressing <CTRL -r>. @@ -221,9 +221,9 @@ so you can edit the ctrl points. Then, convert them to bitmaps, so the flood fills work well. If you are doing interpolation, however, they must be vect. -* GrFloodFill() is slow. GrRect() is fast. +* GrFloodFill() is slow. GrRect() is fast. -* You can customize the wallpaper. See ::/Demo/Graphics/WallPaperFish.HC. +* You can customize the wallpaper. See ::/Demo/Graphics/WallPaperFish.HC. * Your RAM disks will not be reformated when you reboot if the memory location has not changed and it finds the disk intacted. @@ -237,41 +237,41 @@ restore defaults. It is a text doc, if you want to edit it. Be careful of tree indentations. -* Study ::/Adam/Opt/Utils/MemRep.HC and WallPaper() to learn how the system +* Study ::/Adam/Opt/Utils/MemRep.HC and WallPaper() to learn how the system resources are put together. * The editor's sel-text mechanism allows for disjoint portions of sel text. This is a feature, not a bug -- you can cut-and-paste disjoint text. -* cnts.time_stamp_freq is continuously calibrated. Be careful because -expressions might decrease. Take a snap-shot, like this: timeout=GetTSC+ -cnts.time_stamp_freq x seconds; and compare against GetTSC(). I recommend just -using tS or cnts.jiffies. +* cnts.time_stamp_freq is continuously calibrated. Be careful because +expressions might decrease. Take a snap-shot, like this: timeout=GetTSC+ +cnts.time_stamp_freq x seconds; and compare against GetTSC(). I recommend just +using tS or cnts.jiffies. -* Use HeapLog(), HeapLogAddrRep() and HeapLogSizeRep() to find leaks. Don't be -confused by CDoc allocations. Those are generated when text is written to the +* Use HeapLog(), HeapLogAddrRep() and HeapLogSizeRep() to find leaks. Don't be +confused by CDoc allocations. Those are generated when text is written to the cmd line buffer. -* For advanced heap debugging, play with _CFG_HEAP_DBG. You're on your own. +* For advanced heap debugging, play with _CFG_HEAP_DBG. You're on your own. -* You can use Type() to display .GR files. +* You can use Type() to display .GR files. -* Use Man() to jump to short sym name src code. +* Use Man() to jump to short sym name src code. -* Use Fix() to edit and fix the last compiler err. +* Use Fix() to edit and fix the last compiler err. * You can use <CTRL-SHIFT-L> to do a check for compile errors. -* You can use DocOpt() to optimize links. (Mostly just removes .Z) +* You can use DocOpt() to optimize links. (Mostly just removes .Z) -* ZipRep() can highlight src files with lots of redundancy. +* ZipRep() can highlight src files with lots of redundancy. * With start/end, common trailing code is fast. Common leading code is slow. * The first line of the Psalmody HolyC song files is a comment with a category -recognized by JukeBox(). The categories are "no nothing", "has words", "has +recognized by JukeBox(). The categories are "no nothing", "has words", "has graphics", or "special". The third character in the song comment is a digit -rating number, shown in JukeBox(). You can set the song rating in JukeBox() by +rating number, shown in JukeBox(). You can set the song rating in JukeBox() by pressing 0-9. You can press <DEL> to delete songs. diff --git a/public/Wb/Doc/Transform.DD.HTML b/public/Wb/Doc/Transform.DD.HTML index eae023b..a030491 100755 --- a/public/Wb/Doc/Transform.DD.HTML +++ b/public/Wb/Doc/Transform.DD.HTML @@ -27,30 +27,30 @@
-CDC's have a 4x4 matrix for rotating, scaling, skewing and shifting in 3 
+CDC's have a 4x4 matrix for rotating, scaling, skewing and shifting in 3 
 dimensions.  To make the graphics routines use the transform, you must set the 
-DCF_TRANSFORMATION flag.
+DCF_TRANSFORMATION flag.
 
-The matrix consists of ints that have been scaled 32 bits (GR_SCALE).  See 
-::/Demo/Lectures/FixedPoint.HC to learn why.
+The matrix consists of ints that have been scaled 32 bits (GR_SCALE).  See 
+::/Demo/Lectures/FixedPoint.HC to learn why.
 
-See Mat4x4IdentEqu(), Mat4x4IdentNew(), Mat4x4Equ() and Mat4x4New().  See 
-Mat4x4RotX(), Mat4x4RotY(), Mat4x4RotZ() and Mat4x4Scale() to rotate about axes 
-and scale.  Combine them with Mat4x4MulMat4x4Equ()/Mat4x4MulMat4x4New() and 
-assign them to the CDC.dc with DCMat4x4Set().  See ::/Demo/Graphics/Box.HC.
+See Mat4x4IdentEqu(), Mat4x4IdentNew(), Mat4x4Equ() and Mat4x4New().  See 
+Mat4x4RotX(), Mat4x4RotY(), Mat4x4RotZ() and Mat4x4Scale() to rotate about axes 
+and scale.  Combine them with Mat4x4MulMat4x4Equ()/Mat4x4MulMat4x4New() and 
+assign them to the CDC.dc with DCMat4x4Set().  See ::/Demo/Graphics/Box.HC.
 
-You can rotate single points using Mat4x4MulXYZ().
+You can rotate single points using Mat4x4MulXYZ().
 
 The 4th dimension allows a neat trick where you can place pos shifts 
-(translations), into the matrix and Mat4x4MulMat4x4Equ/Mat4x4MulMat4x4New them 
+(translations), into the matrix and Mat4x4MulMat4x4Equ/Mat4x4MulMat4x4New them 
 to combine rotation/shift operations.  Normally, you can't combine pos shift 
-operations.  See Mat4x4TranslationEqu() and ::/Demo/Graphics/Transform.HC.
+operations.  See Mat4x4TranslationEqu() and ::/Demo/Graphics/Transform.HC.
 
-Finally, CDC's have an x, y and z which is an additional shift (translation).
+Finally, CDC's have an x, y and z which is an additional shift (translation).
 
-The transformation is implemented as a callback on the CDC's transform() member. 
- The default transform() callback is DCTransform().  See 
-::/Demo/Games/Talons.HC or ::/Demo/Games/CastleFrankenstein.HC to see how to 
+The transformation is implemented as a callback on the CDC's transform() member. 
+ The default transform() callback is DCTransform().  See 
+::/Demo/Games/Talons.HC or ::/Demo/Games/CastleFrankenstein.HC to see how to 
 change the transform() callback for foreshortening.
 
diff --git a/public/Wb/Doc/Welcome.DD.HTML b/public/Wb/Doc/Welcome.DD.HTML index a42390e..404fb6d 100755 --- a/public/Wb/Doc/Welcome.DD.HTML +++ b/public/Wb/Doc/Welcome.DD.HTML @@ -61,41 +61,41 @@ beautiful. The following applications more or less form a basis that spans the range of use that TempleOS is intended for:
-/Demo/Games/BattleLines.HC -/Demo/Games/BigGuns.HC -/Demo/Games/BlackDiamond.HC -/Demo/Games/BomberGolf.HC -/Demo/Games/CastleFrankenstein.HC -/Demo/Games/CharDemo.HC -/Demo/Games/CircleTrace.HC -/Demo/Games/Collision.HC -/Demo/Games/Digits.HC -/Demo/Games/DunGen.HC -/Demo/Games/Talons.HC -/Demo/Games/ElephantWalk.HC -/Demo/Games/FlapBat.HC -/Demo/Games/FlatTops.HC -/Demo/Games/Halogen.HC -/Demo/Games/MassSpring.HC -/Demo/Games/Maze.HC -/Demo/Games/RainDrops.HC -/Demo/Games/RawHide.HC -/Demo/Games/Rocket.HC -/Demo/Games/RocketScience.HC -/Demo/Games/Squirt.HC -/Demo/Games/TheDead.HC -/Demo/Games/TicTacToe.HC -/Demo/Games/TreeCheckers.HC -/Demo/Games/Varoom.HC -/Demo/Games/Wenceslas.HC -/Demo/Games/Whap.HC -/Demo/Games/Zing.HC -/Demo/Games/ZoneOut.HC -/Apps/Psalmody/Examples/childish.HC -/Apps/Psalmody/Examples/night.HC -/Apps/Psalmody/Examples/prosper.HC +/Demo/Games/BattleLines.HC +/Demo/Games/BigGuns.HC +/Demo/Games/BlackDiamond.HC +/Demo/Games/BomberGolf.HC +/Demo/Games/CastleFrankenstein.HC +/Demo/Games/CharDemo.HC +/Demo/Games/CircleTrace.HC +/Demo/Games/Collision.HC +/Demo/Games/Digits.HC +/Demo/Games/DunGen.HC +/Demo/Games/Talons.HC +/Demo/Games/ElephantWalk.HC +/Demo/Games/FlapBat.HC +/Demo/Games/FlatTops.HC +/Demo/Games/Halogen.HC +/Demo/Games/MassSpring.HC +/Demo/Games/Maze.HC +/Demo/Games/RainDrops.HC +/Demo/Games/RawHide.HC +/Demo/Games/Rocket.HC +/Demo/Games/RocketScience.HC +/Demo/Games/Squirt.HC +/Demo/Games/TheDead.HC +/Demo/Games/TicTacToe.HC +/Demo/Games/TreeCheckers.HC +/Demo/Games/Varoom.HC +/Demo/Games/Wenceslas.HC +/Demo/Games/Whap.HC +/Demo/Games/Zing.HC +/Demo/Games/ZoneOut.HC +/Apps/Psalmody/Examples/childish.HC +/Apps/Psalmody/Examples/night.HC +/Apps/Psalmody/Examples/prosper.HC -Two things to know about TempleOS are that tasks have MAlloc/Free heap memory, +Two things to know about TempleOS are that tasks have MAlloc/Free heap memory, not applications, and tasks have compiler symbol tables that persist at a scope like environment variables in other operating systems, and the symbols can include functions. @@ -103,10 +103,10 @@ For other operating systems, I hated learning one language for command line scripts and another for programming. With TempleOS, the command line feeds right into the HolyC compiler, line by line, and it places code into memory it -MAlloc()s. The compiler is paused at the command line, waiting for input. +MAlloc()s. The compiler is paused at the command line, waiting for input. Naturally, you #include a program to load it into memory and, usually, start it. -During the boot process, many files get compiled before you have access to the +During the boot process, many files get compiled before you have access to the command line. (Don't worry, booting takes only two seconds.) All the header declarations for the operating system are compiled and are available for use in your programs without needing to #include them. Everything is truly compiled to @@ -132,7 +132,7 @@ >Dir; The syntax change created an ambiguity when specifying function addresses, like -for calling QSort(). To resolve it, I made a '&' required in front of function +for calling QSort(). To resolve it, I made a '&' required in front of function names when specifying an address of a function, which is better anyway. Once I was no longer using standard C/C++ syntax, I decided to change everything @@ -146,7 +146,7 @@ Tasks have no priority and are never removed from the queue. Instead, they often poll whatever they are waiting on and swap-out. (Swapping tasks takes half a microsecond and does not involve disk activity or memory maps.) See -Scheduler. Polling keeps it simple. It might be a problem if you had lots of +Scheduler. Polling keeps it simple. It might be a problem if you had lots of tasks busy, which rarely happens on a home computer. The order of the tasks in the queue determines front-to-back window order. @@ -158,8 +158,8 @@ TempleOS is geared toward reading and writing whole files. Since whole files are processed, compression is possible. Filenames ending in ".Z" are automatically compressed or uncompressed when stored and fetched. TempleOS does -support direct block random access into files, however -- FBlkRead() and -FBlkWrite(). +support direct block random access into files, however -- FBlkRead() and +FBlkWrite(). If a file is not found, ".Z" is added or removed and a search is done, again. There is no PATH, but parent directories are searched when a file is not found. @@ -182,8 +182,8 @@ not used, so this is possible. See TempleOS MultiCore. There is no distinction between the terms task, process or thread. All have a -task record, CTask, pointed to by the FS segment reg and are accessed with Fs-> -while Gs-> points to a CCPU for the current CPU core. Each task can have just +task record, CTask, pointed to by the FS segment reg and are accessed with Fs-> +while Gs-> points to a CCPU for the current CPU core. Each task can have just one window, but a task can have children with windows. (The segment regs are just used as extra regs -- there is nothing segmented about TempleOS' memory.) It is approximately the case that TempleOS is multi-threading, @@ -196,21 +196,21 @@ mortal task, from Adam's heap. He stays in a server mode, taking requests, so you can ask him to #include something, placing that code system-wide. A funny story is that originally I called it the root task and even had a /Root -directory :-) Adam executes ::/StartOS.HC at boot time. +directory :-) Adam executes ::/StartOS.HC at boot time. For easy back-ups, place everything you author in your /Home directory and -subdirectories. Then, use CopyTree(). That should make upgrading easy, too. +subdirectories. Then, use CopyTree(). That should make upgrading easy, too. Customizable start-up scripts go in your /Home directory. The default start-up scripts are in the root directory. Copy the start-up files you wish to customize into /Home and modify them. See Home Files. You can make your own distro that includes everything and is a bootable live CD with -::/Misc/DoDistro.HC. +::/Misc/DoDistro.HC. Typically, your usage pattern through the day will be repeatedly left or right -clicking on filenames in a cmd line Dir() listing. You left-click files to edit -them and right-click to #include them. To begin a project, type Ed("filename"); +clicking on filenames in a cmd line Dir() listing. You left-click files to edit +them and right-click to #include them. To begin a project, type Ed("filename"); , supplying a filename. You can also run programs with <F5> when in the editor. -<ESC> to save and exit the file. You'll need to do a new Dir() cmd, +<ESC> to save and exit the file. You'll need to do a new Dir() cmd, periodically, so make a macro on your PersonalMenu. Access your PersonalMenu by pressing <CTRL-m>, cursoring until you are on top of it and pressing <SPACE>. @@ -227,16 +227,16 @@ <ALT-a> brings back AutoComplete. <ALT-v> vertically tiles windows. <ALT-h> horizontally tiles windows. -The ALT keys are defined in ~/HomeKeyPlugIns.HC. You can customize them. +The ALT keys are defined in ~/HomeKeyPlugIns.HC. You can customize them. <CTRL-ALT-t> new terminal window. <CTRL-ALT-n> switches to the next window. <CTRL-ALT-x> kills a window. -Find() is your best friend. There's a wrapper function called F() in your ~/Hom +Find() is your best friend. There's a wrapper function called F() in your ~/Hom eWrappers.HC.Z file. Feel free to make wrapper functions for functions you use -often and customize the args. By the way, Find() or R() can be used to replace -strings across multiple files. You can access Find() using <CTRL-SHIFT-f>. +often and customize the args. By the way, Find() or R() can be used to replace +strings across multiple files. You can access Find() using <CTRL-SHIFT-f>. As you browse code, use the AutoComplete window to look-up functions, etc. <CTR L-SHIFT-F1> (or whatever number) to follow a sym to it's source. You can browse @@ -248,12 +248,12 @@ Software is distributed as RedSea ISO files. Burn a CD/DVD, or set your CD/DVD in QEMU, VMware or VirtualBox to the ISO file. Then, access the 'T' drive. Or, -Mount() the ISO.C file and access the 'M' drive in TempleOS. It must be a +Mount() the ISO.C file and access the 'M' drive in TempleOS. It must be a contiguous ISO.C file, so rename it under TempleOS to ISO.C. Ideally, do not install applications such as games onto your hard drive because we wish to keep hard drive usage low, so the whole 'C' drive can be copied -quickly to 'D'. Also, the FileMgr() <CTRL-d> starts too slowly when there are +quickly to 'D'. Also, the FileMgr() <CTRL-d> starts too slowly when there are lots of hard drive files, but that is how we want it. 3rd party libraries are banned, since they circumvent the 100,000 line of code @@ -261,7 +261,7 @@ TempleOS files and whatever they bring along in the ISO. This is similar to how Commodore 64 applications only depended on the ROM. -Create a RedSea ISO file with RedSeaISO(). Send an email to +Create a RedSea ISO file with RedSeaISO(). Send an email to tdavis@templeos.org if you want me to post a link to your TempleOS code in the App Store. diff --git a/public/Wb/Doc/WhyNotMore.DD.HTML b/public/Wb/Doc/WhyNotMore.DD.HTML index 738cfe8..0121162 100755 --- a/public/Wb/Doc/WhyNotMore.DD.HTML +++ b/public/Wb/Doc/WhyNotMore.DD.HTML @@ -39,7 +39,7 @@ plenty remains. The PCI bus interface is what modern hardware uses. Before PCI, life was simple -and devices used I/O ports. After studying PCI Interrupts and attempting to do +and devices used I/O ports. After studying PCI Interrupts and attempting to do a HDAudio driver, I came to realize that modern PCI devices require ten times more code and I cannot even come close to making them work on everyone's machine because with PCI devices there are several models to worry about, unlike with @@ -47,14 +47,14 @@ Currently, I have no PCI drivers. My drivers use I/O ports and operate in ISA bus mode. At this point, I only have one driver for each type of device and it -is delightfully simple that way. I have one keyboard driver, one mouse driver, -one ATA hard drive driver, one ATAPI CD/DVD driver, one VGA 640x480 16 color -video driver and one PC Speaker driver. I use the PIT and HPET timers and -PIC Interrupt Controller. I use IRQ0 for timer, IRQ1 for keyboard, and IRQ12 +is delightfully simple that way. I have one keyboard driver, one mouse driver, +one ATA hard drive driver, one ATAPI CD/DVD driver, one VGA 640x480 16 color +video driver and one PC Speaker driver. I use the PIT and HPET timers and +PIC Interrupt Controller. I use IRQ0 for timer, IRQ1 for keyboard, and IRQ12 for mouse. If IRQ12 is not firing, I am able to poll the mouse. -In the CPU department, I have state of the art 64-bit long mode with multicore -support. I use the APIC and start-up multicore operation. +In the CPU department, I have state of the art 64-bit long mode with multicore +support. I use the APIC and start-up multicore operation. I have made an incredible accomplishment by getting it to work on practically everyone's computer as long as it is 64-bit and they run inside VMware, QEMU or @@ -87,7 +87,7 @@ machine. Therefore, the BIOS companies actually want it difficult to make drivers and purposely make it broken. -The ATA/ATAPI hard drives often can be run with I/O ports if you can find them. +The ATA/ATAPI hard drives often can be run with I/O ports if you can find them. lspci -v on Linux or system information on Windows can help you locate the SATA IO ports the hard drive and CD/DVD have. They no longer are enabled by the BIOS. It's hopeless. I'm stuck with very slow drive performance, but it works diff --git a/public/Wb/Doc/Widget.DD.HTML b/public/Wb/Doc/Widget.DD.HTML index 1703f19..cd751ff 100755 --- a/public/Wb/Doc/Widget.DD.HTML +++ b/public/Wb/Doc/Widget.DD.HTML @@ -62,7 +62,7 @@ Tree The item will behave like a tree widget, with this as the root. Collapsed The tree or hidden widget will begin collapsed. -Define Str will substitute a #define or DefineLoad() string for the tag. +Define Str will substitute a #define or DefineLoad() string for the tag. Quote Make the res suitable for including in a program, in quotes, especially fo rmat entries in class definitions. @@ -79,6 +79,6 @@ Refresh Data updates $DA...$ entry continuously. Html Link stores a link which will be embedded if you generate a html version -of a document with ::/Demo/ToHtmlToTXTDemo/ToHtml.HC. +of a document with ::/Demo/ToHtmlToTXTDemo/ToHtml.HC. diff --git a/public/Wb/Home/Copy.HC b/public/Wb/Home/Copy.HC new file mode 100755 index 0000000..817e742 --- /dev/null +++ b/public/Wb/Home/Copy.HC @@ -0,0 +1,98 @@ +#include "/Demo/ToHtmlToTXTDemo/ToHtml.HC.Z" + +U8 *FilenameToURL(U8 *filename, I64 line) +{ + filename[StrLen(filename) - 2] = NULL; + + return MStrPrint("/Wb%s.HTML#l%d", filename + 2, line); +} + +U8 *LinkCvt(U8 *link_st) +{ + U8 *res = NULL, *filename, *needle; + I64 i, num; + + if (link_st) { + i = EdLinkCvt(link_st, &filename, &needle, &num); + + switch (i) { + case LK_FILE_LINE: + case LK_PLAIN_LINE: + case LK_FILE: + res = FilenameToURL(filename, num); + break; + case LK_DEF: + case LK_HELP_INDEX: + case LK_DOC: + case LK_DOC_ANCHOR: + case LK_DOC_FIND: + case LK_DOC_LINE: + break; + case LK_BIBLE_FIND: + res = TOSLinkCvt1(link_st); + break; + default: + if (DocFileEd(i, filename, needle, &num, EDF_UNCOLLAPSE | EDF_BAIL)) + res = FilenameToURL(filename, num); + } + } + + Free(filename); + Free(needle); + + return res; +} + +CDirEntry *start_entry = FilesFind( + "/*.HC.Z;*.HH.Z;*.DD.Z;!/Home/*", + FUF_RECURSE | FUF_JUST_FILES +); + + +CDirEntry *entry = start_entry; + +U8 *html_header = + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n"; + +U8 *body_header = + "\n" + "
\n";
+
+//Del("C:/Home/Src", FALSE, TRUE);
+
+do {
+  
+  U8 *new_name = MAlloc(2 *StrLen(entry->full_name));
+  StrPrint(new_name, "/Home/Src%s", entry->full_name + 2);
+  
+  new_name[StrLen(new_name) - 2] = NULL;
+  CatPrint(new_name, ".HTML");
+
+  //if (StrMatch(".DD", entry->full_name)) {
+    ToHtml(
+      entry->full_name,
+      new_name,
+      html_header,
+      body_header,
+      NULL,
+      NULL,
+      80,
+      TRUE,
+      &LinkCvt,
+    );
+
+    Print("%s -> %s\n", entry->full_name, new_name);
+  //} else {
+  //  Copy(entry->full_name, new_name);
+  //}
+
+} while (entry = entry->next);
+
+DirTreeDel(start_entry);
\ No newline at end of file
diff --git a/public/Wb/Home/DoDistro.HC.HTML b/public/Wb/Home/DoDistro.HC.HTML
new file mode 100755
index 0000000..be7cb9a
--- /dev/null
+++ b/public/Wb/Home/DoDistro.HC.HTML
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
+
+
+
+
+//Make Your own Distro by #include-ing this file.
+
+#define STD_DISTRO_DVD_CFG      "TB\nScale2Mem(2048,0x40000)\nT \n\n\n\n"
+
+U0 MakeMyISO(U8 *_out_iso_filename)
+{//Does everything with current drive.
+//If you have not recompiled Kernel and defined your CD/DVD drive, use Mount.
+  U8 *out_iso_filename=FileNameAbs(_out_iso_filename);
+  if (!DrvIsWritable) {
+    "Drive must be writable.  Install on Hard drive, first.\n";
+    return;
+  }
+  DelTree("/Distro");
+  Del(out_iso_filename);
+
+  DirMk("/Distro");
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns;
+
+  Copy("/*","/Distro");
+  Del("/Distro/" KERNEL_BIN_C);
+
+  CopyTree(BOOT_DIR,    "/Distro" BOOT_DIR);
+  CopyTree("/Home",     "/Distro/Home");
+  CopyTree("/Adam",     "/Distro/Adam");
+  CopyTree("/Apps",     "/Distro/Apps");
+  CopyTree("/Compiler", "/Distro/Compiler");
+  CopyTree("/Demo",     "/Distro/Demo");
+  CopyTree("/Doc",      "/Distro/Doc");
+  CopyTree("/Kernel",   "/Distro/Kernel");
+  CopyTree("/Misc",     "/Distro/Misc");
+
+  //To save space, optionally delete dictionary.
+  //Del("/Distro/Adam/AutoComplete/ACDefs.DATA");
+  CopyTree("/Downloads","/Distro/Downloads");     //You can leave this out.
+  DirMk("/Distro/Tmp");
+  DirMk("/Distro/Tmp/ScrnShots");
+  RedSeaISO(out_iso_filename,"/Distro","/Distro" BOOT_DIR_KERNEL_BIN_C);
+
+  //If CD-ROM use MT_CD instead of MT_DVD.
+  //DVDImageWrite('T',out_iso_filename,MT_DVD); //Uncomment to burn.
+
+  //DelTree("/Distro");
+  Free(out_iso_filename);
+}
+
+MakeMyISO("/Tmp/MyDistro.ISO.C");
+
+// Study my account examples Cfg Strs, Update Funs.
+
+ diff --git a/public/Wb/Home/Doc/AboutTempleOS.DD.HTML b/public/Wb/Home/Doc/AboutTempleOS.DD.HTML new file mode 100755 index 0000000..4058dba --- /dev/null +++ b/public/Wb/Home/Doc/AboutTempleOS.DD.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+                                    TempleOS
+
+
+Websites:
+www.templeos.org
+
+Owner/President:
+Terry A. Davis
+
+
+ +8144 Sickle Lane +Las Vegas, NV 89128 +(702)254-4223 + +tdavis@templeos.org + + +About Me: + +I was a National Merit Scholar with a 1440 SAT at Arizona State University. I +have a bachelor's in Computer System Engineering from ASU, basically, embedded +systems, and a master's in Electrical Engineering from ASU, control systems. I +worked as a software, hardware and mechanical engineer at Ticketmaster from +1990-1996. + +I designed a 3 axis stepper-motor-driven milling machine 1996-1997 with a +CAD/CAM package for a company I started called Home Automation and Robotic +Equipment. + +
+ +I worked for a company named Xytec Corp. 1997-1999. We made FPGA-based image +processing equipment. I wrote SimStructure from 2000-2001 for H.A.R.E. I +worked as head software/electrical engineer for a company called Graphic +Technologies, 2001-2002, making replacement chips for toner printer cartridges +so they could be refilled. + +Credits: +See ::/Doc/Credits.DD. + +
+ diff --git a/public/Wb/Home/Doc/Asm.DD.HTML b/public/Wb/Home/Doc/Asm.DD.HTML new file mode 100755 index 0000000..7d34c33 --- /dev/null +++ b/public/Wb/Home/Doc/Asm.DD.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+                                   Assembler
+
+See ::/Compiler/OpCodes.DD for opcodes.  They're not standard.  Some invalid 
+insts are not flagged and some valid insts are not implemented. 16-bit asm 
+support is limited.
+
+Here are example inst formats:
+        ADD     RAX,I64 FS:DISP[RSI+RDI*8]
+        ADD     RAX,I64 [DISP]
+
+$ Current compiler output pos (inst ptr).  Even works in HolyC expressions.
+
+$ works in classes.
+  class MyFun
+  {
+    $=-16;
+    I64 local1;
+    I64 local2;
+    $=$+256;
+    I64 crazy;
+  };
+
+LABEL::
+  Defines an exported glbl label.
+
+LABEL:
+  Defines an non-exported glbl label.
+
+@@LABEL:
+  Defines a local label with scope valid between two global labels.
+
+DU8, DU16, DU32, DU64
+  Define BYTE, WORD, DWORD or QWORD. Can be used with DUP() and ASCII strings.  
+For your convenience, the ASCII strings do not have terminating zeros.  Define 
+cmds must end with a semicolon.
+
+USE16, USE32, USE64
+
+IMPORT sym1name, sym2name;
+
+LIST, NOLIST
+
+ALIGN num, fill_byte
+  Align to num boundary and fill with fill_byte.
+
+ORG num
+  Set code addr for JIT or set module Load() addr -- has 16-byte CBinFile header 
+and patch table trailing.
+
+BINFILE "FileName.BIN";
+
+See Assembly Language, ::/Demo/Asm/AsmAndC1.HC, ::/Demo/Asm/AsmAndC2.HC and 
+::/Demo/Asm/AsmAndC3.HC.
+
+ diff --git a/public/Wb/Home/Doc/AutoComplete.DD.HTML b/public/Wb/Home/Doc/AutoComplete.DD.HTML new file mode 100755 index 0000000..c219a94 --- /dev/null +++ b/public/Wb/Home/Doc/AutoComplete.DD.HTML @@ -0,0 +1,55 @@ + + + + + + + + + + + +
+AutoComplete is the LTGRAY window on the right of the scrn.  ACInit() collects 
+words from all text files in subdirectories.  Normally, the call to ACInit() is 
+in HomeSys.HC.  It provides auto-complete for typing, jump-to-code and 
+jump-to-dictionary functionality.
+
+<ALT-SHIFT-A>   Closes the LTGRAY AutoComplete window.
+<ALT-a>         Opens the LTGRAY AutoComplete window.
+
+<CTRL-SHIFT-F1> Jumps to the source code for 1st symbol in the window.
+<CTRL-SHIFT-F2> Jumps to the source code for 2nd symbol in the window.
+<CTRL-SHIFT-Fn> Jumps to the source code for n-th symbol in the window.
+<CTRL-F1>       Autocompletes the 1st symbol in the window.
+<CTRL-F2>       Autocompletes the 2nd symbol in the window.
+<CTRL-Fn>       Autocompletes the n-th symbol in the window.
+<CTRL-SHIFT-1>  Jumps to the dictionary for 1st symbol in the window.
+<CTRL-SHIFT-2>  Jumps to the dictionary for 2nd symbol in the window.
+<CTRL-SHIFT-n>  Jumps to the dictionary for n-th symbol in the window.
+<CTRL-1>        Autocompletes the 1st dictionary word in the window.
+<CTRL-2>        Autocompletes the 2nd dictionary word in the window.
+<CTRL-n>        Autocompletes the n-th dictionary word in the window.
+
+If you have the raw Project Gutenberg dictionary file, you can generate the 
+TempleOS processed dictionary files with the stand-alone program 
+::/Adam/AutoComplete/ACDictGen.HC.
+
+ diff --git a/public/Wb/Home/Doc/Bit.DD.HTML b/public/Wb/Home/Doc/Bit.DD.HTML new file mode 100755 index 0000000..8b95802 --- /dev/null +++ b/public/Wb/Home/Doc/Bit.DD.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+
+These take a pointer to a bit field.
+Bt:     Bit Test
+Bts:    Bit Test and Set to one
+Btr:    Bit Test and Rst to zero
+Btc:    Bit Test and Compliment (toggle)
+BEqu:   Set bit to value.
+
+Bit operations are "atomic", no interrupt between the reading and writing the 
+bit, important when multitasking.  For multicore use "locked" forms.
+
+These don't take a pointer, but the actual field.
+Bsf:    Bit Scan Fwd (Pos of first low one bit or -1)
+Bsr:    Bit Scan Rev (Pos of first high one bit or -1)
+BCnt:   Bit Cnt (Cnt of set bits)
+
+ diff --git a/public/Wb/Home/Doc/BlkChain.DD.HTML b/public/Wb/Home/Doc/BlkChain.DD.HTML new file mode 100755 index 0000000..f56dbae --- /dev/null +++ b/public/Wb/Home/Doc/BlkChain.DD.HTML @@ -0,0 +1,75 @@ + + + + + + + + + + + +
+                                  Block Chain
+
+There was a technique on the Commodore 64 where disk blocks were chained 
+together with a block pointer at the end of each block.  This is far inferior to 
+having a file allocation table, as in FAT32.
+
+The RedSea file system does not allow files to grow because it only has an 
+allocation bitmap and not a FAT table.  This "flaw" is by design.  I am 
+intentionally crippling this operating system, making it a toy with the wisdom 
+that this will prevent commercialization and corruption.  The toy spirit of the 
+operating system will be preserved going into the future.  The vision for this 
+operating system was a modern Commodore 64, which was a fun toy.
+
+Doing whole file operations is the TempleOS way of doing thinks.  It is the 
+simplest and, ironically, the fastest.  It is obnoxious in the characteristic 
+way that TempleOS is obnoxious, flaunting massive modern resources in a way that 
+makes old programmers protest.
+
+Doing whole file operations will sabotage efforts to change the 640x480 
+resolution and violate the ban on multimedia.  When doing large, whole-file 
+operations, immediately memory fragmentation is a serious problem, but not so 
+for allocations in the range under a Meg (with occasional larger ones).
+
+The file compression scheme in TempleOS only works on whole file operations and 
+the DolDoc format cannot have text tacked onto the end, since binary data is at 
+the end.
+
+I don't want to spoil fun, so of course I offer a way to get awesome performance 
+that is, ironically, superior.  FBlkRead() and FBlkWrite() allow you to read a 
+block offset from the start of a file.  Since files are all contiguous, this is 
+incredibly efficient.  You just have to declare the desired file size when you 
+create it with FOpen() and cannot change it.  See ::/Demo/Dsk/DataBase.HC.
+
+If you like, you are encouraged to to do raw BlkRead() and BlkWrite() directly 
+on a drive.  Just get a pointer to a CDrv with Let2Drv() and you are on your 
+way!  Your computer is supposed to be a fun toy!  You can make an entire 
+partition used for a database, or invent a file system.
+
+On the whole, the RedSea file system with its whole-file-only limitation bring 
+beautiful harmony.  It beautifully captures the spirit of TempleOS with 
+simplicity and, ironic speed, since contiguous is fastest.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+
+ diff --git a/public/Wb/Home/Doc/Boot.DD.HTML b/public/Wb/Home/Doc/Boot.DD.HTML new file mode 100755 index 0000000..84569c2 --- /dev/null +++ b/public/Wb/Home/Doc/Boot.DD.HTML @@ -0,0 +1,142 @@ + + + + + + + + + + + +
+                                  Booting A PC
+
+TempleOS only supports traditional BIOS booting, not the newer technique, UEFI.  
+This document describes BIOS booting.
+
+When you turn-on (power-up) a computer or you do a hardware reset, the computer 
+starts executing the BIOS.  Sometimes, you must change the BIOS boot order to 
+boot the device you want.
+
+The BIOS loads a boot sector from CD/DVD, hard disk or whatever.  The boot 
+sector runs in 16-bit real mode and often loads-in a second file that's bigger 
+if it can't be done by just one sector.  It's a safe bet that boot sectors are 
+hand-coded assembly language.  Most boot sectors use the BIOS to load-in the 
+next stage.
+
+Not only do boot sectors have a size limit, 512 bytes or 2048 bytes for CD/DVD, 
+the files they load have to fit within 640K because they run in 16-bit mode.  
+This means they usually can't just load the whole operating system and start it 
+running.  Some boot loaders, like Grub, have a capability of switching modes 
+before handing-off control to the operating system.  The operating system must 
+load the rest of itself.  With TempleOS, the ::/Kernel.BIN.C file is loaded by 
+the boot sector.  I try to put a minimum in the Kernel Module, so that it will 
+always fit in 640K.  When Kernel.BIN runs, it switches to 32-bit mode, then, to 
+64-bit mode allowing access to more memory.  Then, it loads in the rest of 
+TempleOS by executing ::/StartOS.HC.
+
+All the boot related code for TempleOS is in the /Adam/Opt/Boot directory.
+
+BootDVD.HC      CD/DVD boot sector.
+BootDVDIns.HC   Prep for CD/DVD install by creating /0000Boot/0000Kernel.BIN.C.
+If you are curious about CD/DVDs, see DskISORedSea.HC.  To make a custom 
+bootable CD/DVD, look here Bootable CD.
+
+BootMHD.HC      Stage 1 Master HD boot loader.
+BootMHD2.HC     Stage 2 Master HD boot loader.
+BootMHDIns.HC   Installs Master HD boot loader.
+BootMHD goes on block zero.  /0000Boot/BootMHD2.BIN.C is stored as a file in a 
+partition, risky and unusual, since most master boot loaders place stage 2 in a 
+gap that's not in any partition.  BootMHD2 displays a menu and boots a 
+partition.
+
+BootHD.HC       HD partition boot record.
+BootHDIns.HC    Installs HD partition boot record.
+BootHD is the boot record for a TempleOS partition.  Each partition has its own 
+partition boot record, the first block of the partition.
+
+My boot records don't access directories because that would make them too big 
+for one block and would make them depend on a file system layout.  Instead, they 
+get patched with the LBA, logical block addresses, to load files.  To update 
+with a new TempleOS kernel, you must create a ::/Kernel.BIN.C binary file and 
+patch the boot loader so it knows the LBA blocks to load.  Therefore, you 
+usually recompile the kernel and update the boot sector at the same time with  
+BootHDIns().  BootMHDIns() will install a master boot loader.
+
+With TempleOS, ::/Kernel.BIN.C loads ::/Compiler/Compiler.BIN so it can work 
+with source code from then on.  It compiles start-up scripts beginning with 
+::/StartOS.HC into the Adam Task's memory including the code in the /Adam and /H
+ome directories.
+
+It is possible to do a fast reboot without doing a hardware reset.  You might do 
+this when working on ::/Kernel.BIN.C or your start-up scripts when you want to 
+compile them effect.  See BootRAM().
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Home/Doc/CharOverview.DD.HTML b/public/Wb/Home/Doc/CharOverview.DD.HTML new file mode 100755 index 0000000..095a0a9 --- /dev/null +++ b/public/Wb/Home/Doc/CharOverview.DD.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+                                 Char Overview
+
+A Character is a single byte holding an ASCII code for a letter, num or sym.  
+The TempleOS term is a U8.
+
+Standard ASCII values range from 0 to 127.  Values below 32 are ctrl key's.  So, 
+an ASCII #3 is a <CTRL-c>.  TempleOS uses a few nonstandard values below 32.  
+See Char Definitions.
+
+ASCII #5  is the cursor location in a saved file.
+ASCII #28 is <SHIFT-ESC>.
+ASCII #31 is a <SHIFT-SPACE>.
+
+TempleOS ASCII is 8-bit instead of 7-bit, so it also uses the range from 
+128-255.  Press <CTRL-ALT-a> to see shapes for 128-255.  Technically, <CTRL-ALT-
+a> are scrn codes.
+
+A Key is typically specified with a scan code.  TempleOS scan codes contain the 
+key value in the lowest U8, and flags in the upper 3 bytes.  See 
+Scan Code Flags and Scan Codes.
+
+TempleOS stores scan codes in 8 bytes.
+  Byte 0   is the code.  NumPad keys, SHIFT, ALT, CTRL and GUI keys combined.
+  Byte 1-3 are flags
+
+The upper 4-bytes are copied from lower 4-bytes.
+  Byte 4   is the code.  Left, Right and NumPad keys distinct.
+  Byte 5-7 are flags
+
+Run the program ::/Demo/MsgLoop.HC to examine scan code.  Press <CTRL-SHIFT-l> 
+and "Insert ASCII/ScanCode".
+
+See Key Allocations and CKbdStateGlbls.
+
+A String is a bunch of ASCII characters terminated with a zero.
+
+ diff --git a/public/Wb/Home/Doc/Charter.DD.HTML b/public/Wb/Home/Doc/Charter.DD.HTML new file mode 100755 index 0000000..b802d17 --- /dev/null +++ b/public/Wb/Home/Doc/Charter.DD.HTML @@ -0,0 +1,158 @@ + + + + + + + + + + + +
+                                TempleOS Charter
+
+Why did they make Solomon's Temple?  It was a direction to look, to focus on, a 
+special place for meditation, to do offerings, a community center, a home to 
+God's beauty, that encouraged love of God.  People cherished God's temple, 
+beautifying it with gold and all fine things to show love of God, as great 
+cathedrals were decorated with astounding, awe-striking intricate art and 
+gargoyles, incredible devotion to God with hours of effort, toiling and 
+slaving-away for the glory of God, for families with children to see 
+stained-glass windows and tomes with ridiculously elaborate calligraphy to show 
+love of God, from a people who did little else but show love toward God, lived 
+in dire conditions by today's standards, yet with so much difficulty 
+scraping-by, found the time to devote even all free-time to God!
+
+
+1 Kings 6:21 (King James)
+
+     6:21 So Solomon overlaid the house within with pure gold: and he made
+     a partition by the chains of gold before the oracle; and he overlaid
+     it with gold.
+     
+     6:22 And the whole house he overlaid with gold, until he had finished
+     all the house: also the whole altar that was by the oracle he overlaid
+     with gold.
+     
+     6:23 And within the oracle he made two cherubims of olive tree, each
+     ten cubits high.
+
+
+* TempleOS is God's official temple.  Just like Solomon's temple, this is a 
+community focal point where offerings are made and God's oracle is consulted.
+
+* God said 640x480 16 color graphics is a covenant like circumcision.  Children 
+will do offerings.  Think of 16 colors like the Simpson's cartoons.  In the 
+future, even if one GPU were universal, we would still keep 640x480 16 color and 
+not use GPU acceleration.  Graphics operations should be transparent, not hidden 
+in a GPU.
+
+* God said to use a single-voice 8-bit signed MIDI-like sample for sound.  God 
+does not want death screams, perhaps, because God has PTSD or soldiers have 
+PTSD.  (Imagine wounded on battlefields.) 
+
+* God said His temple must be perfect.  We don't think twice about breaking 
+compatibility.  God said we do a seven year release cycle.  I say the PC 
+hardware follows a 49 year, jubilee cycle, like broadcast TV upgrades.
+
+* The vision is the same usage model and niche as the Commodore 64 -- a 
+non-networked, simple machine where programming was the goal, not just a means 
+to an end.  However, it is modern, 64-bit and multi-cored.  It is special 
+purpose, not general purpose, so some things it will not do.  Also, it's a 
+kayak, not a Titanic. The priority is user developers, not 3rd party developers.
+
+* We do not put any hooks for future changes.  "Perfect" means we always act as 
+though it is final, for all time.  Microsoft allowed the Windows BMP file format 
+to adapt to the future and it became grotesque.
+
+* Low line count is the highest good, so it is easy to learn the whole thing.  
+Users should see the light at the end of the tunnel.  One file system, for 
+example, is better than many file systems.
+
+* There is a limit of 100,000 lines of code for all time, not including 
+applications and demos.  Code comments count, however.  Currently, there are 
+80,849 lines of code.  3rd party libraries are banned because they circumvent 
+the intent of this limit.  The vision is a Commodore 64 ROM -- a fixed core API 
+that is the only dependency of applications.  Dependency on components and 
+libraries creates a hell that is no longer blissful.
+
+* The metric for resolving all TempleOS code governance issues is how fast the 
+compiler compiles itself and the kernel with BootHDIns().  The HolyC language 
+should be changed to optimize this metric, as I did when I changed type casting 
+from prefix standard C to postfix HolyC, but we need a rule to prevent 
+degenerating into a brainfuck language.
+ 
+* Minimal abstraction is a goal.  Sheep are fools.  They always respect a design 
+that is more complicated than another.  Any genius can make it complicated.  
+Like in physics, it takes a supra-genius to make it simple.
+
+* It is for one platformc -- x86_64 desktop PC compatibles, more like 
+super-computers than battery efficient wimpy mobiles.
+
+* All hardware access will be done through x86 IN/OUT instructions, not PCI 
+drivers.  A frame buffer for VGA is an exception.
+
+* One driver for each class of device.  Limited exceptions are allowed.  With 
+divergent device capabilities, it is a nightmare for user applications and what 
+is gained?  A three buuton mouse is like a leg you cannot put weight on.
+
+* Ring-0-only.  Everything runs in kernel mode, including user applications.
+
+* Full access to everything.  All memory, I/O ports, instructions, and similar 
+things must never be off limits.  All functions, variables and class members 
+will be accessible.  There are no C++ public/private protections and all 
+functions, even secondary ones in the kernel, can be called.
+
+* Single-address-map as though paging is not used.  Long mode requires paging, 
+however, so the nearest thing is keeping all memory identity-mapped.
+
+* No networking, so malware is not an issue.
+
+* No encryption or passwords.  Files are compressed, not encrypted.
+
+* Free and public domain.
+
+* 100% open source with all source included.
+
+* Documents are not for printing.  They're dynamic, intended for the scrn.
+
+* Just one 8x8 fixed-width font.  No Unicode, just Extended ASCII.  Other 
+countries can make their own versions.  The versions should be just for one 
+language and platform.
+
+* No multimedia.  Sounds and images will be primarily calculated in real-time, 
+not fetched from storage.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+* "The Simpsons" is a trademark owned by Fox.
+* "Windows" is a trademark owned by MicroSoft Corp.
+
+
+
+                              Possible Amendments
+
+The compiler's parser makes RISC code which it optimizes to CISC.  I discovered 
+this does not matter because the CPU converts it back to RISC and schedules it, 
+internally.  A TempleOS zealot with more zeal than I, might say we should save 
+lines-of-code by removing the CISC optimizing.
+
+ diff --git a/public/Wb/Home/Doc/CmdLineOverview.DD.HTML b/public/Wb/Home/Doc/CmdLineOverview.DD.HTML new file mode 100755 index 0000000..05fd4a7 --- /dev/null +++ b/public/Wb/Home/Doc/CmdLineOverview.DD.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+                             Command Line Overview
+
+The cmd line feeds into the HolyC compiler line-by-line as you type.  A stmt 
+outside a function executes immediately.  Remember to add a semicolon.
+
+Look-up the function headers with AutoComplete by hitting <CTRL-SHIFT-F1> after 
+typing the first few letters.
+
+Click Here to see the directory cmd header.  It accepts default args from C++.
+
+>Dir("*.DD.Z");
+
+If you don't have args, you don't need parenthesis.
+
+>Dir;
+
+Directories are referenced with / not \.  There is a current directory, but not 
+a path.  To run a program, you typically #include it.  There are several 
+shortcuts for #includeing files.  Right-click or hit <ENTER> on a directory 
+listing or press <F5> while editing.
+
+>Ed("NewFile.HC.Z");    Invokes the editor. See Doc Link Type.
+
+Most filenames end in .Z because they are stored compressed.
+
+Drives are specified with a letter.  The boot drive is specified with a ':'.  
+The home dir drive is specified with a '~'.
+
+>Drv('B');      B drive
+
+The drive can be specified in a Cd() command as in:
+
+>Cd("B:/Tmp");  B drive
+>Cd("::/Demo"); Boot drive
+
+The home directory is specified with a '~'.
+
+>Cd("~/Psalmody");      See ::/Home dir.
+
+If a file is not found, .Z is added or removed and a search is done, again.  If 
+a file is still not found, all parent directories are searched.
+
+You can place macros in your PersonalMenu for Cd() commands.  <CTRL-m> to access 
+your menu.
+
+>Find("needle","/Demo/*.HC.Z;*.DD.Z;"); See File Utils.
+
+Cmd Line Routines
+
+Take Tour
+
+ diff --git a/public/Wb/Home/Doc/Comm.HC.HTML b/public/Wb/Home/Doc/Comm.HC.HTML new file mode 100755 index 0000000..72312db --- /dev/null +++ b/public/Wb/Home/Doc/Comm.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+/* RS232 serial ports no longer exist.
+Be sure to Adam Include this by placing
+it in your start-up scripts.
+*/
+
+#help_index "Comm"
+
+#define UART_THR                0
+#define UART_RDR                0
+#define UART_BRDL               0
+#define UART_IER                1
+#define UART_BRDH               1
+#define UART_IIR                2
+#define UART_LCR                3
+#define UART_MCR                4
+#define UART_LSR                5
+#define UART_MSR                6
+
+#define COMf_ENABLED    0
+class CComm
+{
+  I64   base,
+        flags;
+  CFifoU8 *RX_fifo;
+  CFifoU8 *TX_fifo;
+} comm_ports[5];
+
+U0 CommHndlr(I64 port)
+{
+  CComm *c=&comm_ports[port];
+  I64 b=0,stat;
+  if (Bt(&c->flags,COMf_ENABLED)) {
+    stat=InU8(c->base+UART_IIR);
+    if (stat & 4)       //RX
+      FifoU8Ins(c->RX_fifo,InU8(c->base+UART_RDR));
+    if (stat & 2) {     //TX
+      if (FifoU8Rem(c->TX_fifo,&b))
+        OutU8(c->base+UART_THR,b);
+      else
+        OutU8(c->base+UART_IER,1); //RX but no THR empty
+    }
+  }
+}
+
+interrupt U0 IRQComm3()
+{
+  CommHndlr(2);
+  CommHndlr(4);
+  OutU8(0x20,0x20);
+}
+
+interrupt U0 IRQComm4()
+{
+  CommHndlr(1);
+  CommHndlr(3);
+  OutU8(0x20,0x20);
+}
+
+U0 CommInit()
+{
+  MemSet(&comm_ports,0,sizeof(comm_ports));
+  comm_ports[1].base=0x3F8;
+  comm_ports[2].base=0x2F8;
+  comm_ports[3].base=0x3E8;
+  comm_ports[4].base=0x2E8;
+  IntEntrySet(0x23,&IRQComm3);
+  IntEntrySet(0x24,&IRQComm4);
+}
+CommInit;
+
+public CComm *CommInit8n1(I64 port,I64 baud)
+{
+  CComm *c=&comm_ports[port];
+
+  PUSHFD
+  CLI
+  if (LBts(&c->flags,COMf_ENABLED)) {
+    FifoU8Del(c->RX_fifo);
+    FifoU8Del(c->TX_fifo);
+  }
+  c->RX_fifo=FifoU8New(256);
+  c->TX_fifo=FifoU8New(256);
+  OutU8(c->base+UART_LCR,0);    //Set for IER
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_LCR,0x80); //Enable baud rate control
+  OutU8(c->base+UART_BRDL,(0x180/(baud/300)) & 0xFF);   //LSB
+  OutU8(c->base+UART_BRDH,(0x180/(baud/300)) / 256);    //MSB
+  OutU8(c->base+UART_LCR,3);    //8-none-1
+
+  InU8(c->base+UART_RDR);       //read garbage
+  InU8(c->base+UART_LSR);
+
+  OutU8(c->base+UART_MCR,4);
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_MCR,0xA);  //out2 and rts
+  OutU8(0x21,InU8(0x21) & (0xFF-0x18)); //Enable 8259 IRQ 3 & 4
+  OutU8(c->base+UART_IER,1);    //RX but no THR empty
+  POPFD
+
+  return c;
+}
+
+public U0 CommPutChar(I64 port,U8 b)
+{
+  CComm *c=&comm_ports[port];
+  PUSHFD
+  CLI
+  FifoU8Ins(c->TX_fifo,b);
+  OutU8(c->base+UART_IER,3);    //RX and THR empty
+  POPFD
+  Sleep(10); //!!! Remove this line!!!  Linux echo_socket is too slow.
+}
+
+U0 CommPutS(I64 port,U8 *st)
+{
+  I64 b;
+  while (b=*st++)
+    CommPutChar(port,b);
+}
+
+public U0 CommPutBlk(I64 port,U8 *buf,I64 cnt)
+{
+  while (cnt--)
+    CommPutChar(port,*buf++);
+}
+
+public U0 CommPrint(I64 port,U8 *fmt,...)
+{
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CommPutS(port,buf);
+  Free(buf);
+}
+
+ diff --git a/public/Wb/Home/Doc/CompilerOverview.DD.HTML b/public/Wb/Home/Doc/CompilerOverview.DD.HTML new file mode 100755 index 0000000..0f4c387 --- /dev/null +++ b/public/Wb/Home/Doc/CompilerOverview.DD.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+                                 Compiler Index
+
+::/Doc/Asm.DD
+
+::/Doc/Directives.DD
+
+::/Doc/Options.DD
+
+::/Doc/PreProcessor.DD
+
+::/Doc/ScopingLinkage.DD
+
+See Hello World.
+
+ diff --git a/public/Wb/Home/Doc/Credits.DD.HTML b/public/Wb/Home/Doc/Credits.DD.HTML new file mode 100755 index 0000000..0ee38aa --- /dev/null +++ b/public/Wb/Home/Doc/Credits.DD.HTML @@ -0,0 +1,113 @@ + + + + + + + + + + + +
+                                    Credits
+
+I, Terry A. Davis, wrote all of TempleOS over the past 20.6 years (full-time).  
+It can run on some bare metal 64-bit PC's from about 2005-2010 with no layering, 
+libraries, tools, modules or anything from other sources.  Otherwise, you run it 
+in a virtual machine, like VMware, QEMU or VirtualBox.  It is independent and 
+stands alone.  It has no networking, so it certainly doesn't call home.  100% of 
+the src code is including on all distro's, from the kernel to the compiler to 
+the boot loaders!  It is public domain, not GPL.
+
+*) ::/Kernel/FontStd.HC, is taken from FreeDOS.  It's public domain.
+
+*) ::/Kernel/FontCyrillic.HC, is taken from OrientDisplay without permission.
+
+*) ATA Reg and Cmd Definitions are originally from Linux.  Later, I got the 
+spec.
+
+*) The heap algorithm, ::/Kernel/Mem/MAllocFree.HC, is adapted from one I saw at 
+Ticketmaster when I worked on their VAX operating system.
+
+*) The LZW compression algorithm, ::/Kernel/Compress.HC, came from a magazine 
+and I implemented it when I worked for Ticketmaster.
+
+*) The adaptive-step-size-Runge-Kutta algorithm, ::/Adam/AMathODE.HC, is adapted 
+from the book, Numeric Recipies in C.
+
+*) The mountain in some games is from http://www.public-domain-photos.com.  The 
+wolf in BlackDiamond is also from there.  I took watermarked photos and 
+converted to 16 color.
+
+*) The FAT32 file system is owned by MicroSoft.
+
+*) A few features were inspired by MATLAB, such as ans in expressions at the 
+command-line.  There is a lot of MSDOS , Windows, VAXTMOS (VAX Ticketmaster 
+O.S.) and Unix inspiration, too, such as drive letters, command names, etc.
+
+*) I included PCIDevice Lst File.
+
+*) Thanks to whoever wrote this CppHtml.HC.Z.  I'm a novice on web stuff and you 
+helped me with html.  See ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+*) I looked at bootable CD boot sects, but didn't learn anything, finding it 
+easier to make my own.
+
+*) I think I got my original PC speaker code from Borland C.
+
+*) I found PS/2 keyboard and mouse code on the net and documentation.  My code 
+is very different.  I found VGA reg info on the net.
+
+*) Thanks to http://www.osdev.org for a couple tips.
+
+*) God told me to stick with 640x480 16 color and single-voice 8-bit signed 
+MIDI-like sample for sound.   He kept me from zombie-walking into making child 
+windows like Windows.  Instead, I made one window per task with no child 
+windows.  He also guided my progress, very obviously.
+
+*) I got Webster's Dictionary and The King James Bible from Project Gutenberg.
+
+*) John Carmack inspired me to use "Clamp" as a name instead of "Limit".  He 
+inspired me to use "needle" and "haystack" as names.  He inspired me to simplify 
+my Frames-Per-Second code.
+
+*) Bill Gates inspired me to add comments to my Help & Index.
+
+*) I hired an artist, Cody Rigby, for $3,000 worth of pixel art.
+
+*) Erik van der Karbargenbok wrote /Downloads shell scripts -- gw.
+
+*) The random number generator is from Donald Knuth in the wikipedia entry for 
+Linear_congruential_generator.
+
+
+* "MSDOS", "Windows", "MovieMaker", "MS Paint" and "FAT32" are trademarks owned 
+by MicroSoft Corp.
+* "SiteBuilder" is a trademark owned by Yahoo! Inc.
+* "MagicISO" is a trademark owned by MagicISO Corp.
+* "MATLAB" is a trademark owned by The Math Works, Inc.
+* "FreeDOS" is a trademark owned by Jim Hall.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VAX" is a trademark owned by Digital Equipment Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "VAXTMOS" is a trademark owned by Ticketmaster.
+
+ diff --git a/public/Wb/Home/Doc/Ctrls.DD.HTML b/public/Wb/Home/Doc/Ctrls.DD.HTML new file mode 100755 index 0000000..a6691b8 --- /dev/null +++ b/public/Wb/Home/Doc/Ctrls.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+To create a TempleOS graphic ctrl, you define callback functions and insert a 
+CCtrl structure in the CTask queue.  See ::/Demo/Graphics/Slider.HC, 
+::/Demo/Graphics/ScrollBars.HC and TermBttnNew.  There is a template-code ctrl 
+generator, if you press <CTRL-SHIFT-L>.
+
+ diff --git a/public/Wb/Home/Doc/Customize.DD.HTML b/public/Wb/Home/Doc/Customize.DD.HTML new file mode 100755 index 0000000..d00bed8 --- /dev/null +++ b/public/Wb/Home/Doc/Customize.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+
+* You can adjust the mouse movement rate by setting global vars in your start-up 
+file.  See mouse scale.
+
+* You can set your local time zone by setting the local_time_offset global var 
+in a start-up file.  It's units are CDATE_FREQ.  See local time.
+
+* Get rid of this msg here.
+
+ diff --git a/public/Wb/Home/Doc/CutCorners.DD.HTML b/public/Wb/Home/Doc/CutCorners.DD.HTML new file mode 100755 index 0000000..f1f9a9e --- /dev/null +++ b/public/Wb/Home/Doc/CutCorners.DD.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+                                  Cut Corners
+
+There are a few places where I cut corners in the interest of not junking-up 
+code.  This is part of the TempleOS mentality.  I try not to let stupid legacy 
+compatibility issues enter and junk-up TempleOS.
+
+* I made my type-casting operator post-fix because it makes the compiler way 
+cleaner.
+
+* TempleOS does not figure-out FAT32 short name alias numbers.  FAT32DirNew().  
+It can cause hard drive corruption, so I might have to do it.  It would really 
+take a lot of junky code for this hatefully, detestable, legacy issue.  "Please 
+don't make me ruin my beautiful shiny-new TempleOS with that!"  I am also not 
+enthused about FAT32 because it is in patent limbo.  FAT32 might get removed 
+from TempleOS.  There is the RedSea  64-bit file system that works perfectly 
+well.  FAT32 is useful, however, because it assists in transferring between dual 
+booted operating systems.
+
+* I changed the asm opcodes names to remove the ambiguity between insts with 
+different numbers of arguments, making my assembler simpler and I did minimal 
+16-bit asm support, since 64-bit is what you should be using, unless you're 
+doing a boot loader.
+
+* There are no user-controlled file-sharing locks.  However, the drive and file 
+system have locks and concurrent operations should be fine. 
+
+* A hidden window is never refreshed.  Certain tasks are never done, therefore.  
+During refresh, the entry count limit of the document buffer is, normally, 
+checked and enforced.  If you print to the command-line in a task whose window 
+is covered, no limit on buffer exists and it will alloc memory for the document 
+buffer until the system runs out of memory and crashes.
+
+* Even if a local function variable is declared less than 64 bits, the compiler 
+does calculations with 64-bit.
+
+* Print() uses StrPrintJoin().  You cannot use vastly over-sized fields for %f.
+
+* GrEllipse3() is broken on transformations.
+ 
+ diff --git a/public/Wb/Home/Doc/D3.DD.HTML b/public/Wb/Home/Doc/D3.DD.HTML new file mode 100755 index 0000000..6016b8b --- /dev/null +++ b/public/Wb/Home/Doc/D3.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+TempleOS has a class for 3 dimensional points consisting of F64s.  HolyC is not 
+C++ -- it does not support passing or returning values from functions which are 
+not 64-bits, therefore, it can't be implemented with operator overloading.  
+Making all function args and returns 64-bit is a core prinicple of TempleOS.
+
+As a courtesy, most of the CD3 functions return the addr of the destination 
+vect, so you can nestle calls.  They do not alloc new space for the destination 
+vect.
+
+ diff --git a/public/Wb/Home/Doc/Date.DD.HTML b/public/Wb/Home/Doc/Date.DD.HTML new file mode 100755 index 0000000..4e1c23d --- /dev/null +++ b/public/Wb/Home/Doc/Date.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Dates are 32-bit signed ints representing the number of days since the birth of 
+Christ.  Negative values represent B.C.E. dates.
+
+ diff --git a/public/Wb/Home/Doc/DbgFunSeg.DD.HTML b/public/Wb/Home/Doc/DbgFunSeg.DD.HTML new file mode 100755 index 0000000..943a43c --- /dev/null +++ b/public/Wb/Home/Doc/DbgFunSeg.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Use %p to print a pointer with FunSeg+Offset or use %P to print a link to a 
+FunSeg+Offset.
+ 
+ diff --git a/public/Wb/Home/Doc/DbgOverview.DD.HTML b/public/Wb/Home/Doc/DbgOverview.DD.HTML new file mode 100755 index 0000000..ad8231f --- /dev/null +++ b/public/Wb/Home/Doc/DbgOverview.DD.HTML @@ -0,0 +1,102 @@ + + + + + + + + + + + +
+                               Debugging Overview
+
+* You can enter the debugger with Dbg() or <CTRL-ALT-d>.  You might enter the 
+debugger through a fault.  Enter G() or G2() to continue execution.  Place a 
+call to Dbg() in your code at fatal error points to enter the debugger.  If you 
+see a stk dump, record the label+offset and unassemble, U(). U(_RIP); 
+
+* U(&FunName+offset) to unassemble mem or Uf("FunName") to unassemble a 
+function. U(_RIP-16);
+
+* While debugging, you specify addresses of assembly routines with just the 
+label, as in _MALLOC+0x20.  You specify HolyC function names with & before 
+functions as in &Print+0x10.
+
+* I use progress1-progress4 for debugging because they show on the wallpaper.  
+They're just global int vars.
+
+* You can use AdamLog() to send text to the Adam Task window.  It works like 
+Print().  I never use that.  Instead, I use RawPrint().
+
+* D(), DocD(), RawD() to do 16 column hex dump mem with numbering from zero.  
+With DocD the values are updated continually and you can alter mem by editing.
+
+* Dm(), DocDm(), RawDm() to do 16 column hex dump mem with addresses showing.
+
+* Da() to do one column address dump (for stk, etc.) with symbolic addresses.
+
+* Dr() dumps regs.  You can display and modify regs in the debugger with 
+var-like labels, _RAX, _RBX, etc.
+
+* ClassRep() and the dynamic version ClassRepD() can be used to dump structures.
+
+* Prof() and ProfRep() provide code profiling.  See ::/Demo/InFile/InProfile.IN 
+(This is an InFile.)
+
+* Use RawPrint() to print debug info bypassing the window framework.  You pass 
+these routines a count in milliseconds for how long it should be displayed.  You 
+can use Raw(TRUE) to make all output bypass the window framework.  The WinMgr 
+runs on Core0 and will overwrite raw text from other cores when it updates the 
+scrn.
+
+* Use SysDbg() to set a flag which you can read with IsSysDbg() when you wish to 
+trigger some debug activity.  It's just a handy simple flag, nothing fancy.
+
+* There are flags for various trace options that can help debugging when there 
+are compiler bugs.  Often, you place them in #exe{} blocks.
+  
+  Echo() turns on or off raw data going into the lexical analyzer.
+  
+  Trace() unassembles code generated from the HolyC compiler.
+  
+  PassTrace() shows intermediate code coming-out after optimization.  The bits 
+  ctrl which passes are displayed.
+
+
+* There is a heap check utility which can find leaks.  Use HeapLog(), 
+HeapLogAddrRep() and HeapLogSizeRep().  It's a really simple program which 
+intercepts MAlloc() and Free().  You can customize the code to find other heap 
+issues.
+
+* You can define hndlr functions for <CTRL-ALT-letter> keys with CtrlAltCBSet(). 
+ They operate either in a interrupt environment or in the window mgr when it 
+queues kbd msgs.  You can do Raw() output.  <CTRL-ALT-letter> hndlrs take a 
+scan_code as an arg.
+
+* If you recompile Kernel with BootHDIns(), you can set the MemInit, option to 
+initialize memory to a value at boot, the HeapInit option to cause mem alloced 
+off the heap to be initialized or VarInit option so both global and local vars 
+will be initialized to a value, but global AOT variables are always zero if not 
+initialized.  Pick a non-zero value to discover uninitialized var bugs.  You can 
+set sys_var_init_flag, and sys_heap_init_flag directly after booting.
+
+ diff --git a/public/Wb/Home/Doc/Define.DD.HTML b/public/Wb/Home/Doc/Define.DD.HTML new file mode 100755 index 0000000..c0e919b --- /dev/null +++ b/public/Wb/Home/Doc/Define.DD.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+TempleOS has a string indirection feature implemented with the same hash symbol 
+table entry as #define macros, HTT_DEFINE_STR.  Support for string lists is also 
+provided, but it's not very efficient, though, you can make a hash table with a 
+list using HashDefineLstAdd().  See ::/Adam/DolDoc/DocInit.HC.
+
+If you have an @ as the first char of a define list entry, it is an alias for 
+the prev entry num.
+
+Each task can load its own Define strings.  Remember, when a Hash table is 
+searched for a string, if it is not found, the parent task's table is searched.
+
+The DolDoc framework supports text that changes based on entries in the task's 
+symbol table.  Set a text entry with a D= arg, as in $TX,"",D="DD_MYSTRING"$.  
+See ::/Demo/DolDoc/DefineStr.HC, ::/Adam/ADefine.HC and ::/Doc/MemOverview.DD.
+
+See ::/Demo/Define.HC.
+
+ diff --git a/public/Wb/Home/Doc/Demands.DD.HTML b/public/Wb/Home/Doc/Demands.DD.HTML new file mode 100755 index 0000000..972c092 --- /dev/null +++ b/public/Wb/Home/Doc/Demands.DD.HTML @@ -0,0 +1,150 @@ + + + + + + + + + + + +
+                                    Demands
+
+I, Terry Davis, am high priest of God's official third temple, TempleOS.  
+TempleOS is an operating system for IBM PC x86_64 desktops that will always dual 
+boot along-side Windows or Linux.  I am in charge of the core 100,000 lines of 
+TempleOS code and I do continual offerings to keep God entertained.  I have 
+divine authority to command any company in the computer industry to do anything 
+that I deem necessary to make God's temple more beautiful, glorious and perfect. 
+I have oversight authority similar to a building inspector or a person enforcing 
+the Americans with Disability Act -- I make commands, God signs-off with a 
+miraculous authentication from an oracle, and Intel, Microsoft or VMware obeys.
+
+
+
+* Windows, Linux and VMware (because of mounted drives) must support RedSea file 
+system when mounting partition, so I can get rid of 1,000 lines of redundant, 
+blemished code -- FAT32.  God's temple must be perfect.  Redundant code for 
+multiple file systems is bad and imperfect.  For this operating system, we want 
+low line count.  More than one driver for the same type of device is also bad.
+
+See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC.
+
+::/Kernel/BlkDev/FileSysFAT.HC  :974 lines for FAT32 gets eliminated.
+::/Kernel/BlkDev/DskClus.HC     :152 All the clus operations become blk.
+
+* Microsoft must cancel SecureBoot because it makes dual booting impossible.  
+TempleOS is an additional operating system that must be used along-side Windows 
+or Linux, not as a replacement.  It must dual boot because it has no networking. 
+Real hardware as opposed to VMware is like the difference between looking in a 
+telescope eye piece vs just looking at an off-line image.  God said the 
+C64/Apple II generation owned ancestral lands.  VMware is like being taken off 
+of our land and moved onto a reservation.  In this case, however, it will not 
+stand.  In fact, God said to replace Windows with Wine, justice.  We can make a 
+100% standard model PC with a standard software for everyone, backed-up in 
+factory ROM.
+
+* VMware needs to support ATAPI CD/DVD/Blu-ray disk burning, directly to real 
+hardware.  Industry needs write-just once media to stop Farenheit 451 non-sense.
+
+* VMware has a bug stretching 640x480 16 color to full screen.
+
+* VMware some PC speaker's distortion is a good idea -- squarewave -- but 
+currently there is too much for hymns.  CIA monkery made fart noises.
+
+* VMware and others must list TempleOS as an official 64-bit operating system 
+and automatically enforce 512 Meg min RAM requirement.
+
+* VMware needs to support more than 16 cores.  I had a 24 core Xeon with 128 Gig 
+of RAM.  I discovered VMware allocates memory too slowly, where QEMU had no 
+problem.
+
+* Until super-simple block devices are available, hard disk should be placed at 
+IDE primary master 1F0/3F6 and CD/DVD/Blu-ray should be placed at the IDE 
+secondary master 170/376.  Currently, the wicked CIA plays musical chairs with 
+controllers each time you make an install.  With tons of ugly code, I do my 
+best.
+/Kernel/BlkDev/DskATAId.HC      :286 lines to figure-out I/O ports is gone.
+/Kernel/PCIBIOS.HC              :290 could be eliminated, but maybe we will keep 
+it so people can play with PCI devices.
+
+* Until super-simple serial ports are available, PS/2 emulated keyboard and 
+mouse must work.  The BIOS must enable these.  The plan is to transition the 
+industry off of USB.  Interum solution is to make virtual RS232 Octart for USB 
+devices in the same way PS/2 mouse is emulated.  All mice will be two button, 
+one wheel.  No more HID insanity, no more multi-end point, just simple tx rx 
+fifos with soft/hard flowcontrol that can jump the queue.  People with special 
+needs can buy PCI cards.  Our kids deserve code this simple ::/Doc/Comm.HC.  The 
+right to do your own port banging is what the C64 being our God given ancestral 
+land means.
+
+* The x86 IN/OUT port instructions, normally have a delay.  Perhaps, VMware & 
+Intel can enable faster x86 IN/OUT instruction timing for ATA/ATAPI PIO, so 
+bandwidth isn't as bad when doing port I/O.  See ATAGetRes().  We don't want to 
+do DMA.  Perhaps, x86 CPU chips need a new TempleOS mode for fast IN/OUT 
+instructions?  I think VMware already does something to speed disk I/O to faster 
+than native speed.
+
+* Perhaps, a new interrupt descriptor table entry type or a new x86 CPU mode can 
+be made that cause fast software interrupts, doing exactly what the CALL REL32 
+does, but with IDT as indirection.  We don't need to change privilege levels or 
+stacks.
+
+* Since I don't use paging (for anything), Intel should have an option for  
+no-paging long mode, and optimize it!
+::/Kernel/Mem/PageTables.HC     :135 lines to identity-map gets eliminated.
+
+* Desktop computers must have a reset switch and a fast reboot option, skipping 
+diagnostics.  I recommend booting TempleOS from a ROM when the reset bttn is 
+pressed and booting UEFI when the power bttn is pressed.  Or, we could build 
+UEFI on a TempleOS layer.  Intel must burn TempleOS into a ROM in the factory 
+for all desktop x86 CPUs to ensure tamper-proof trust in the oracle and because 
+God deserves the glory.  There will be just an English version.  A new ROM 
+version is released every seven years.  The ROM should boot like the DVD boots, 
+but with BOOT_SRC_ROM.
+
+* We do not want UTF, just 8-bit characters.  <CTRL-ALT-f> toggles between 
+Cyrillic and Std Fonts.  We need the twelve window TextBorder characters added 
+to the VGA font 0x02-0x0D.  Japan, China and Korea must switch to alphabets.  
+Maybe, the United States will change to metric, out of good will.  I am 
+beginning to plan fresh ASCII replacement, ::/Doc/NewASCII.DD.
+
+* Microsoft Paint and Linux's Gimp must support TempleOS GR Files.  They are 
+blemish free, unlike BMP files.  The TOSZ Linux utility can be used to make 
+screencasts from TempleOS exported GR Files and AU Files.
+
+* We must have a nice dictionary.  Someone needs to do a Spell Checker, too.
+
+* Intel needs to make DolDoc versions of its x86 CPU data sheets documenting all 
+hardware relevant to TempleOS. 
+
+* We must have the ultimate Bible search engine.  Currently, all we have is     
+filter search.  In the end, it should be a low line-count technique.  Maybe, I 
+allocate 500 lines out of the 20,000 reserve.
+
+* We will make a Standard TempleOS PC.
+
+* "VMware" is a trademark owned by VMware, Inc.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "Windows" and "Paint" are trademarks owned by MicroSoft Corp.
+
+ diff --git a/public/Wb/Home/Doc/DemoIndex.DD.HTML b/public/Wb/Home/Doc/DemoIndex.DD.HTML new file mode 100755 index 0000000..5c47f7a --- /dev/null +++ b/public/Wb/Home/Doc/DemoIndex.DD.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+                              TempleOS Demo Index
+
+These are arranged in increasing order of difficulty, more or less.  This can be 
+used as a tutorial if you start at the beginning and work your way fwd.
+
+<SPACE> to edit a file and <F5> to run it.
+
+::/Doc/HelloWorld.DD
+
++] Games: Beginner
++] Games: Intermediate
++] Games: Advanced
++] Non-Game
++] TempleOS Specific
+
+
+ diff --git a/public/Wb/Home/Doc/Directives.DD.HTML b/public/Wb/Home/Doc/Directives.DD.HTML new file mode 100755 index 0000000..cba8fde --- /dev/null +++ b/public/Wb/Home/Doc/Directives.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#define __DATE__ #exe{StreamPrint("\"%D\"",Now);}
+#define __TIME__ #exe{StreamPrint("\"%T\"",Now);}
+#define __LINE__ #exe{StreamPrint("%d",Fs->last_cc->lex_include_stk->line_num);}
+#define __CMD_LINE__ #exe{StreamPrint("%d",Fs->last_cc->flags&CCF_CMD_LINE && Fs->last_cc->lex_include_stk->depth<1);}
+#define __FILE__ #exe{StreamPrint("\"%s\"",Fs->last_cc->lex_include_stk->full_name);}
+#define __DIR__  #exe{StreamDir;}
+
+See ::/Demo/Directives.HC.
+
+ diff --git a/public/Wb/Home/Doc/DolDoc.DD.HTML b/public/Wb/Home/Doc/DolDoc.DD.HTML new file mode 100755 index 0000000..fc095d6 --- /dev/null +++ b/public/Wb/Home/Doc/DolDoc.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+A DolDoc in memory is a Circular Queue of cmds and graphics.  See CDocEntry for 
+the entry structure.  See TipOfDay() for a nice example.
+
+DolDoc's are used for the editor, viewer, browser, and cmd line.
+
+ diff --git a/public/Wb/Home/Doc/DolDocOverview.DD.HTML b/public/Wb/Home/Doc/DolDocOverview.DD.HTML new file mode 100755 index 0000000..4059ea2 --- /dev/null +++ b/public/Wb/Home/Doc/DolDocOverview.DD.HTML @@ -0,0 +1,151 @@ + + + + + + + + + + + +
+                                DolDoc Overview
+
+DolDoc is a TempleOS document type supported by DolDoc Routines.  In a document, 
+commands are bracketed with '$'s.  Use <CTRL-l> to experiment inserting a 
+command.  Then, use <CTRL-t> to toggle to plain text to see it.
+
+Here is the grammar:
+
+<DolDocCmd> := $<TwoLetterCmd>[<FlagList>][,<ArgList>]$ | $ColorName$
+
+<FlagList> := +|- <FlagCode>[<FlagList>]
+
+<ArgList> := <ArgCode>=<ArgExpression>[,<ArgList>]
+
+
+The format of DolDoc cmds is a two character code, +/-flags, a comma and args 
+separated by commas.  Some commands have mandatory args.  Optional args are 
+indicated with <ArgCode>=.  A ColorName bracked by dollars, will change the 
+foreground color.
+
+See ::/Doc/Widget.DD, ::/Demo/DolDoc/DemoDoc.DD, and 
+::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+<TwoLetterCmd>  See Type Defines and PrsDollarCmd().
++] TX Text
++] CR Hard New Line
++] SR Soft New Line
++] CU Cursor pos
++] TB Tab
++] CL Clear
++] PB Page Break
++] PL Page Length
++] LM Left Margin
++] RM Right Margin
++] HD Header
++] FO Footer
++] ID Indent +/- num
++] Text Colors
++] PT User Prompt
++] WW Word Wrap
++] UL Underline
++] IV Invert
++] BK Blink
++] SX Shift X pos
++] SY Shift Y pos
++] CM Cursor Movement
++] AN Anchor
++] LK Link
++] BT Bttn
++] DA Data
++] CB Check Box
++] LS List Widget
++] MA Macro
++] MU Menu Value
++] HX Hex Edit
++] TR Tree Widget
++] SP Sprite
++] IB Insert Binary
++] IS Insert Binary Size
++] SO Song
++] HL Highlighting
++] HC html
++] ER Error
+
+<FlagCode>  See Flag Defines and Simple Flags.
++] +H Hold
++] +L Link
++] +TR Tree
++] +LS List
++] +PU PopUp
++] +C Collapsed
++] +X <ESC> (Exit)
++] +Q <SHIFT-ESC> (Abort Quit)
++] +Z Zero
++] +RD Refresh Data
++] +UD Update Data
++] +TC Tag CallBack
++] +LC Left CallBack
++] +RC Right CallBack
+
+<ArgCode>  See Arg Defines.
++] T="" Tag Str
++] LEN="" Field Length
++] A="" Auxilliary Str
++] D="" Define Str
++] HTML=""
++] LE=<Exp> Left Expression
++] LM="" Left Macro Str
++] RE=<Exp> Right Expression
++] RM="" Right Macro Str
++] BI=<Exp> Bin Number
++] BP="" Bin Ptr
++] RT=<raw_data_type>
++] SX=<Exp> Shift X
++] SY=<Exp> Shift Y
++] SCX=<Exp> Scroll X
++] U=<Exp> User Data
+
+EXAMPLES:
+
+<CTRL-t> to see how the following were done.
+Underlined Inverted Blinking super sub
+This is a big long scrolling msg.
+
+Cursor Movements:
+
+
+
+   Cursor moved 3 rows down and to 3rd column from left.
+                                                                                
+
+
+                                        Note mandatory comma after flags
+
+The following may be changed to modes instead of attr with flags.
+
+                                This is centered
+
+                                                         This is right justified
+
+ diff --git a/public/Wb/Home/Doc/EdPullDown.DD.HTML b/public/Wb/Home/Doc/EdPullDown.DD.HTML new file mode 100755 index 0000000..0aadddf --- /dev/null +++ b/public/Wb/Home/Doc/EdPullDown.DD.HTML @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+File
+{
+  Save(,CH_CTRLS);
+  SaveAs(,CH_CTRLA);
+  Abort(,CH_SHIFT_ESC);
+  Exit(,CH_ESC);
+}
+
+Edit
+{
+  Undo(,CH_CTRLH,0x80E0000080E);
+  Cut(,CH_CTRLX);
+  Copy(,CH_CTRLC);
+  Paste(,CH_CTRLV);
+  DelLine(,CH_CTRLY);
+  FindReplace(,CH_CTRLF);
+  FindNext(,,0x3D0000003D);
+  FindLast(,,0x23D0000023D);
+  GoLine(,CH_CTRLG,0x42200000422);
+  GoBegin(,,0x4C800000448);
+  GoEnd(,,0x4D000000450);
+  GoLeft(,,0x4CB0000044B);
+  GoRight(,,0x4CD0000044D);
+  GoLBrace(,0x5B,0x61A0000061A);
+  GoRBrace(,0x5D,0x61B0000061B);
+  Macro(,,0x3C0000003C);
+  PlayMacro(,,0x23C0000023C);
+  AutoSaveToggle(,CH_CTRLS,0x61F0000061F);
+}
+
+Insert
+{
+  TextWidgets(,CH_CTRLL,0x42600000426);
+  GraphicResource(,CH_CTRLR,0x41300000413);
+  FileName(,,0x3E0000003E);
+  DirName(,,0x23E0000023E);
+  GodWord(,,0x4100000041);
+  GodBiblePassage(,,0x24100000241);
+  GodSong(,,0x4000000040);
+  GodDoodle(,,0x24000000240);
+  IndentIn(,CH_CTRLI,0x41700000417);
+  IndentOut(,CH_CTRLI,0x61700000617);
+  WordWrapOn(,CH_CTRLW,0x41100000411);
+  WordWrapOff(,CH_CTRLW,0x61100000611);
+  UnderlineOn(,CH_CTRLU,0x41600000416);
+  UnderlineOff(,CH_CTRLU,0x61600000616);
+  BlinkOn(,CH_CTRLK,0x42500000425);
+  BlinkOff(2,CH_CTRLK,0x62500000625);
+  InvertOn(,CH_CTRLZ,0x42C0000042C);
+  InvertOff(,CH_CTRLZ,0x62C0000062C);
+  SuperToggle(,CH_CTRLP,0x41900000419);
+  SubToggle(,CH_CTRLP,0x61900000619);
+  PageBreak(,CH_CTRLJ,0x41C0000041C);
+}
+
+Program
+{
+  CodeTools(,CH_CTRLL,0x62600000626);
+  Include(,0,0x3F0000003F);
+  AdamInclude(,0,0x23F0000023F);
+}
+
+View
+{
+  PlainText(,CH_CTRLT);
+  Collapse(,CH_CTRLO,0x61800000618);
+  Uncollapse(,CH_CTRLO,0x41800000418);
+  Border(,CH_CTRLB);
+  FileMgr(,CH_CTRLD,0x42000000420);
+  Search(,CH_CTRLF,0x62100000621);
+}
+
+Help
+{
+  Menu(,CH_CTRLM,0x43200000432);
+  Help(,,0x3B0000003B);
+  About(,,0x23B0000023B);
+}
+
+ diff --git a/public/Wb/Home/Doc/FAQ.DD.HTML b/public/Wb/Home/Doc/FAQ.DD.HTML new file mode 100755 index 0000000..7ef2750 --- /dev/null +++ b/public/Wb/Home/Doc/FAQ.DD.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+                           Frequently Asked Questions
+
++] How come it is public domain, not GPL?
++] Shouldn't it be GNU/TempleOS?
++] Don't you use GNU's gcc?
++] Why do you dual boot?
++] It has links, so is it a browser?
++] Where are the animated 3D icon GIFs?
++] If the compiler is JIT, isn't it an interpretor?
++] Are you a Creationist?
++] Is 'Bt()' in the code Bit Torrent?
++] Is 'Fs->' in the code file system?
++] Is it Pascal?
++] Why doesn't Sleep() make my laptop hibernate?
++] What is Yield() for in loops?
++] What is JIT Compiled Mode?
++] Why do files end in .Z?  Are they encrypted?
++] Is it open source?  How do I build it?
++] Where are object files?  How do I link?
++] What is the FPS refresh rate?
++] How does a task own the speaker?
++] Why does it leak memory?
++] Why do I get a memory leak when editing big files?
++] Why is it in text mode?
++] Where is the kernel memory?
++] Why does it run code from stack addresses?
++] How does it SYSCALL?
++] How do you fault-in stack?
++] How do I set the PATH?
++] How do I boot it with Grub?
++] How do I get Kernel.BIN to boot?
++] Why is there some 16-Bit code?
++] Why are you pushing 32-bit values on the stack?
++] Why are you using 32-bit insts and not setting high 32-bits?
++] How do you use the FS and GS segment registers.
++] How do I set ORG for position of code?
++] How are symbols loaded?
++] Why doesn't assert work?
++] Why doesn't C++ public work?
++] How does the debugger do source debugging?
++] What are the ASCII 5 and ASCII 31 chars doing in my text files?
++] Why is there garbage at the end of my text files?
++] Why are sprites so small?
++] Why don't I need to recompile /Adam and /Home files?
++] Why does it finds files that aren't there?
+
+
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Doc/Features.DD.HTML b/public/Wb/Home/Doc/Features.DD.HTML new file mode 100755 index 0000000..eab7988 --- /dev/null +++ b/public/Wb/Home/Doc/Features.DD.HTML @@ -0,0 +1,98 @@ + + + + + + + + + + + +
+                               TempleOS' Features
+
+* Oracle in with <F7> for words or <SHIFT-F7> for passages.  See tongues.
+
+* x86_64, ring-0-only, single-address-map (identity), multitasking kernel with 
+multicore support.
+
+* Master/Slave MultiCore 
+
+* Free, public domain, 100% open source.
+
+* 64-bit compiler/assembler for HolyC.  Truly compiles, doesn't interpret.  Just
+-in-Time and Ahead-of-Time compilation.  With JIT, no need for object or exe 
+files.
+
+* No 32-bit krufty code.
+
+* 640x480 16 color VGA graphics.
+
+* Keyboard & Mouse support.
+
+* ATA PIO Hard drives, support for FAT32 and RedSea file systems with file 
+compression.
+
+* ATAPI PIO CD/DVD support with RedSea file system.  Can make bootable ISO files 
+so you can roll-your-own distro's.
+
+* Partitioning tool, installer, boot loaders for CD/DVD and hard disk.
+
+* Editor/Browser for a new Document Format.  Source files and the command line 
+window can have graphics, links, icons, trees, colors, super/sub scripts, 
+margins.  Everything is seamless through-out the tool chain.  No need for 
+separate resource files.
+
+* 8-bit ASCII, not just 7-bit.  Supported in entire tool chain.  <CTRL-ALT-a>
+
+* Graphics in source code, no resource files, graphic sprite editor. <CTRL-r>
+
+* 64-bit pointers.  All memory, even more than 4Gig, can be directly accessed by 
+all tasks on all cores at all times.
+
+* Ring-0-only.  Highest CPU privileged mode at all times.  No off-limits insts.  
+No time lost changing modes or address maps.  Switches tasks in half a 
+microsecond.
+
+* 2D/3D graphics library
+
+* Real-time fancy differential-equation solver for physics engines, to use in 
+games.  (Adaptive step-size Runge-Kutta, interpolated for real-time.)
+
+* Auto-completion, jump-to-source tool called AutoComplete with Dictionary.
+
+* Window Manager.  Pan scrn with <CTRL-LeftDrag>.  Zoom scrn on mouse cursor 
+with <CTRL-ALT-z>/<CTRL-ALT-SHIFT-Z>.
+
+* File Manager, <CTRL-d>.
+
+* Code profiler, merge, diff utils.
+
+* PC Speaker support with many hymns.
+
+* Music composing tool.
+
+* Many games, demos and documentation.
+
+* All source code included.  Only compiles with the included TempleOS compiler 
+and assembler.
+
+ diff --git a/public/Wb/Home/Doc/FileLowLevel.DD.HTML b/public/Wb/Home/Doc/FileLowLevel.DD.HTML new file mode 100755 index 0000000..30cf57c --- /dev/null +++ b/public/Wb/Home/Doc/FileLowLevel.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+                       CFile
+
+
+
+
+
+
+
+    BlkRead()         BlkWrite()
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Home/Doc/FileMgr.DD.HTML b/public/Wb/Home/Doc/FileMgr.DD.HTML new file mode 100755 index 0000000..4d3a5f3 --- /dev/null +++ b/public/Wb/Home/Doc/FileMgr.DD.HTML @@ -0,0 +1,107 @@ + + + + + + + + + + + +
+                                  File Manager
+
+<SHIFT CURSOR>
+  Select files.
+
+<CTRL-y> or <DEL>
+  Delete file or tree.
+
+<CTRL-c> or <CTRL-INS>
+  Copy select files to clip.
+
+<CTRL-v> or <SHIFT-INS>
+  Paste clip.
+
+LEFT-CLICK,drag-drop
+  Move a file or tree to a dir.
+
+LEFT-CLICK,same file or <SPACE>
+  Edit file.
+
+<SHIFT-SPACE>
+  Edit Plain Text File.
+
+RIGHT-CLICK or <ENTER>
+  Bring-up menu.
+
+<F5>
+  #include file.
+
+<SHIFT-F5>
+  Adam #include file.
+
+'r'
+  Rename file.
+
+'d'
+  Make Dir.
+
+'c'
+  DskChg (Remount removable media).  Do not do this on blank disks.
+
+'f'
+  Format drive.
+
+'i'
+  Mount ISO.C file.
+
+'u'
+  Unmount drive(s).
+
+'m'
+  Make CD/DVD ISO.C file.  This creates a RedSea ISO file image of the dir the 
+  cursor is on.  The name of the ISO file is "::/Tmp/CDDVD.ISO.C" 
+  blkdev.dft_iso_c_filename and can be redefined in your start-up scripts.  You 
+  may wish to place it on a different drive.
+
+'B'
+  Burn CD/DVD ISO file.  This burns a CD/DVD using the image file, 
+  "::/Tmp/CDDVD.ISO" blkdev.dft_iso_filename to the drive the cursor is on.
+
+
+Instructions on Using CD/DVD's
+  If you have not recompiled Kernel and defined your CD/DVD drive, exit the 
+  FileMgr and use Mount to define your CD/DVD drive.  Place a CD/DVD in the 
+  drive and press 'c' when on top of the CD/DVD drive letter to mount the drive. 
+   It will call DskChg(), the TempleOS cmd to mount removable media.
+
+
+Instructions on Burning CD/DVD's
+  Create a temporary dir to hold files and copy files into the holding dir.  
+  Make an ISO image of the dir by pressing 'M' when on top of the dir.  Press 'B
+  ' when on top of the CD/DVD ROM drive to burn the ISO, "::/Tmp/CDDVD.ISO" 
+  blkdev.dft_iso_filename, to disk.  If you have not recompiled Kernel and 
+  defined your CD/DVD drive, exit the FileMgr and use Mount.
+  
+  Making Your Own Distro
+  
+ diff --git a/public/Wb/Home/Doc/FileMgrPullDown.DD.HTML b/public/Wb/Home/Doc/FileMgrPullDown.DD.HTML new file mode 100755 index 0000000..da5fefe --- /dev/null +++ b/public/Wb/Home/Doc/FileMgrPullDown.DD.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+File
+{
+  Rename(,'r');
+  DirMk(,'d');
+  FmtDrv(,'f');
+  UnmountDrv(,'u');
+  Abort(,CH_SHIFT_ESC);
+  Exit(,CH_ESC);
+}
+
+Edit
+{
+  Ed(,CH_SPACE);
+  Plain(,CH_SHIFT_SPACE);
+  Copy(,CH_CTRLC);
+  Paste(,CH_CTRLV);
+  DeleteFile(,CH_CTRLY);
+}
+
+CDDVD
+{
+  DskChg(,'c');
+  MountISOC(,'i');
+  MakeRedSeaISOC(,'m');
+  BurnISOFile(,'B');
+}
+
+Program
+{
+  Include(,0,0x3F0000003F);
+  AdamInclude(,0,0x23F0000023F);
+}
+
+ diff --git a/public/Wb/Home/Doc/FileUtils.DD.HTML b/public/Wb/Home/Doc/FileUtils.DD.HTML new file mode 100755 index 0000000..11d2571 --- /dev/null +++ b/public/Wb/Home/Doc/FileUtils.DD.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+                                   File Utils
+
+File util FilesFind() wildcard mask consists of a single base dir with multiple 
+file masks separated by ';'.  The '*' and '?' wildcard chars are accepted.  The 
+'~' is your home directory and '!' indicates an exclusion mask.
+
+ 
+"/Kernel/*"             BaseDir: /Kernel        Mask: *
+"/Demo/*.BMP*;*.GR*"    BaseDir: /Demo          Mask: *.BMP* | *.GR*
+"/*.DD*;!*/Bible*"      BaseDir: Root           Mask: *.DD* but not */Bible*
+
+See FilesFindMatch().
+
+Flags are either text or int values.
+
+  FUF_RECURSE           +r Recurse
+  FUF_SINGLE            +s Single File (Optimization for one file in mask.)
+  FUF_FLATTEN_TREE      +f use with '+F'.  Just use +F, probably.
+  FUF_JUST_DIRS         +D just directories
+  FUF_JUST_FILES        +F just files (Flattens trees)
+  FUF_CLUS_ORDER        +O sort by clus (move head one direction)
+  FUF_JUST_TXT          +T just text files      : FILEMASK_TXT
+  FUF_JUST_DD           +$ just DolDoc files    : FILEMASK_DD
+  FUF_JUST_SRC          +S just src files       : FILEMASK_SRC
+  FUF_JUST_AOT          +A just aot files       : FILEMASK_AOT
+  FUF_JUST_JIT          +J just jit files       : FILEMASK_JIT
+  FUF_JUST_GR           +G just graphic files   : FILEMASK_GR
+
+See ST_FILE_UTIL_FLAGS when used in calling program taking text flags.
+
+ diff --git a/public/Wb/Home/Doc/Frame.DD.HTML b/public/Wb/Home/Doc/Frame.DD.HTML new file mode 100755 index 0000000..96c3c09 --- /dev/null +++ b/public/Wb/Home/Doc/Frame.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+If you require separate global vars for multiple instances of a routine, you can 
+use Frames.  See SpriteMeshEd(), ::/Demo/Graphics/Pick3D.HC or Noise().
+
+ diff --git a/public/Wb/Home/Doc/GRFiles.DD.HTML b/public/Wb/Home/Doc/GRFiles.DD.HTML new file mode 100755 index 0000000..a77cefd --- /dev/null +++ b/public/Wb/Home/Doc/GRFiles.DD.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+GR graphics files are 8-bits-per-pixels but only 4-bits of color, with 
+transparency and no palette.  Compression is the standard TempleOS LZW 
+compression.
+
+#define DCF_COMPRESSED          1 //This is the only saved flag.
+#define DCF_PALETTE             2
+
+#define TRANSPARENT             0xFF
+#define BLACK                   0
+#define BLUE                    1
+#define GREEN                   2
+#define CYAN                    3
+#define RED                     4
+#define PURPLE                  5
+#define BROWN                   6
+#define LTGRAY                  7
+#define DKGRAY                  8
+#define LTBLUE                  9
+#define LTGREEN                 10
+#define LTCYAN                  11
+#define LTRED                   12
+#define LTPURPLE                13
+#define YELLOW                  14
+#define WHITE                   15
+
+class CBGR48
+{
+  U16   r,g,b,pad;
+};
+
+CBGR48 gr_palette_std[16]={
+0x000000000000,0x00000000AAAA,0x0000AAAA0000,0x0000AAAAAAAA,
+0xAAAA00000000,0xAAAA0000AAAA,0xAAAA55550000,0xAAAAAAAAAAAA,
+0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
+0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0xFFFFFFFFFFFF};
+
+class GRFile
+{
+  I32   width;
+  I32   width_internal; //Rounded-up to multiple of 8.
+  I32   height;
+  I32   flags;          //DCF_COMPRESSED? See ::/Kernel/Compress.HC.
+  CBGR48 palette[16];   //Included if DCF_PALETTE.
+  U8    body[];
+};
+
+See DCSave(), GRWrite(), DCLoad(), and GRRead().
+
+ diff --git a/public/Wb/Home/Doc/Glossary.DD.HTML b/public/Wb/Home/Doc/Glossary.DD.HTML new file mode 100755 index 0000000..2891eac --- /dev/null +++ b/public/Wb/Home/Doc/Glossary.DD.HTML @@ -0,0 +1,67 @@ + + + + + + + + + + + +
+                                    Glossery
+
++] Abbreviations
++] Task/Process/Thread
++] Adam Task
++] Seth Tasks
++] Code and Data Heaps
++] Parent, Child and PopUp Tasks
++] HolyC
++] AOT Compile Mode
++] JIT Compile Mode
++] Compiler Intermediate Code
++] Drive/Partition
+
+Bt, Bts, Btr, Btc, BEqu
+Define
+DolDoc
+Editor Link Types
+files_find_mask
+Hash Table
+InFile
+Ona
+Pag
+RedSea File System
+Sprite
+
++] CLI, STI, PUSHFD, POPFD
++] Filename Extention Types
++] Naming Convention
++] Fs
++] Gs
++] Heap
++] Join
++] user_data
++] Multicore Core0/CoreAP
+
+
+ diff --git a/public/Wb/Home/Doc/God.DD.HTML b/public/Wb/Home/Doc/God.DD.HTML new file mode 100755 index 0000000..385eaf6 --- /dev/null +++ b/public/Wb/Home/Doc/God.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+The Holy Spirit can puppet you.
+
+
+ diff --git a/public/Wb/Home/Doc/GraphicsOverview.DD.HTML b/public/Wb/Home/Doc/GraphicsOverview.DD.HTML new file mode 100755 index 0000000..10e404c --- /dev/null +++ b/public/Wb/Home/Doc/GraphicsOverview.DD.HTML @@ -0,0 +1,148 @@ + + + + + + + + + + + +
+                               Graphics Overview
+
+Dive into Demo Index to learn.
+
+The order layers are drawn on top of each other is:
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+* See GrUpdateScrn(), GrUpdateTasks() and GrUpdateTaskWin() called by the WinMgr 
+task 30fps.  Notice the task's draw_it() callback being called.  Only tasks on C
+ore0 are allowed to have windows.  There is one window per task, no child 
+windows.  You can have pop-up child tasks.
+
+* CDCs (device contexts) are a data type for controlling graphics on the scrn or 
+graphics in mem.  The device context structure has thick and color.  You use 
+DCAlias() to create your own structure, with its own color and thick.  Free it 
+with DCDel() when finished.
+
+* gr.dc is a device context for persistent data on the scrn, not needing to be 
+redrawn.  You create an alias for this by using DCAlias() and work with that.  
+See ::/Demo/Graphics/NetOfDots.HC.
+
+* There are various flavors of line and point plotting routines.  GrLine() and 
+GrPlot() are the simplest.  The others allow 3D graphics and rotations.
+
+* See ::/Doc/Transform.DD for adding a transformation.
+
+* You change the Fs->draw_it var to point to your DrawIt() function which gets 
+called each scrn refresh (30 fps).  You draw everything in the window over and 
+over again.  See ::/Demo/Graphics/Box.HC.
+
+* Use the graphic sprite resource editor, <CTRL-r>, to create a sprite that can 
+be plotted with Sprite3() or output to the cmd line with Sprite().  Use $IB,"",B
+I=1$ in a src program to insert the addr of sprite binary data item #1.  To 
+learn how the numbers work, after creating a sprite with <CTRL-r>, toggle to 
+plain text with <CTRL-t> and check its num.  Make an assignment to a ptr var or 
+pass to Sprite3() with $IB,"",BI=n$.  Use <CTRL-r>'s "Pointer to Sprite" to make 
+a $IB...$ entry.  See ::/Demo/Graphics/SpritePlot.HC and 
+::/Demo/Graphics/SpritePlot3D.HC.  The origin (zero point) for a sprite is 
+defined by the cursor location when you pressed <CTRL-r> to make it.  You can 
+edit a sprite by clicking the cursor on it and pressing <CTRL-r> again.
+
+* Set DCF_SYMMETRY in the CDC.flags and call DCSymmetrySet() or DCSymmetry3Set()
+.  This will plot a mirror image in addition to the primary image.  Set 
+DCF_JUST_MIRROR to plot just the image, but this required DCF_SYMMETRY to be set 
+at the same time.  Note: You can only have one symmetry active at a time 
+including in CSprites.
+
+* Use DCNew() to create a mem bitmap which can be used to work off-scrn and 
+which can be GrBloted onto the scrn.  If you set brush member of CDC to another 
+CDC, all the graphic routines will GrBlot() the brush instead of GrPlot().  See 
+::/Demo/Graphics/Blot.HC.
+
+* There are a few raster operations available.  They go in bits 8-11 of the dc->
+color member var which is a CColorROPU32.  ROP_COLLISION is special.  It counts 
+the num of pixs drawn on non-background locations.  Using ROP_COLLISION with 
+vector CSprite's is tricky because overlapping pixs from lines in the CSprite 
+reg as collisions.  You can either work with a nonzero count or convert your 
+CSprite to a bitmap if your subelements draw on top of each other.  Be sure to 
+set ->bkcolor before using ROP_COLLISION.  See ::/Demo/Graphics/Collision.HC and 
+Titanium.
+ 
+* The ->dither_probability_u16 member of CDC is a U16 used to statistically sel 
+between two colors to get something resembling more shades of color.  See 
+::/Demo/Graphics/SunMoon.HC and ::/Demo/Graphics/Shading.HC.  It works with many 
+graphic routines, but not those with pens.
+
+* There is a mechanism built-in for generating motion based on differential 
+equations, which allows realistic physics.  You create an CMathODE struct with 
+ODENew(), passing it the num of vars in the state vect.  For realistic physics, 
+you usually have 2 state vars for each dimension (for each mass) because motion 
+is governed by F=mA which is a 2nd order equation.  The two states are pos and 
+velocity and to solve these you need to supply the derivative of pos and 
+velocity.  The derivative of pos is usually simply the current velocity and the 
+derivative of velocity is the acceleration (the sum of forces on a mass divided 
+by mass).  To help provide meaningful names for values in the state vect, you 
+can create an COrder2D3 ptr and point it to a mass in the state vect.  Six 
+elements in the state vect are required for each mass.
+
+See Math/CMathODE.
+See ::/Demo/Games/Rocket.HC.
+
+ diff --git a/public/Wb/Home/Doc/GuideLines.DD.HTML b/public/Wb/Home/Doc/GuideLines.DD.HTML new file mode 100755 index 0000000..0f72d00 --- /dev/null +++ b/public/Wb/Home/Doc/GuideLines.DD.HTML @@ -0,0 +1,219 @@ + + + + + + + + + + + +
+                              Directory Structure
+
+/Home All your user data should be placed in here to ease backing-up your data.  
+When you install an application it will create a subdirectory of your /Home 
+directory for storage.
+
+/Apps Applications are placed in subdirectories of /Apps.  Applications should 
+have a file called Install.HC.Z which will install the app, possibly making 
+files or directories in /Home.  The file, Load.HC.Z will load the application 
+into mem.  The file, Run.HC.Z, will usually load and execute the app.  To add an 
+app to your PersonalMenu, use <CTRL-l>, insert a macro with the PopUp option 
+checked and invoke the Run.HC.Z file.
+
+/Demo Here you can find lots of sample code to do various things.
+
+/Doc Here you can find documentation.
+
+/Kernel The core of the operating system is found here.  Since priviledge levels 
+are not used, calling it a kernel is deceptive.  It is AOT compiled by 
+BootHDIns().  It is loaded by the boot loader and must fit in 640K.
+
+/Compiler The compiler module src code is found here.  The compiler is AOT 
+compiled to produce a binary file which is loaded at boot.  It, too, is AOT 
+compiled by BootHDIns().
+
+/Adam The non-kernel part of the operating system is found here.  It is JIT 
+compiled during boot.  The Adam Task is the father of all tasks, like Adam and 
+Eve.
+
+/0000Boot Boot files go here.  Stage 2 of the TempleOS hard drive master boot 
+loader, the old hard drive master boot record which is just blk#0, and the 
+CD/DVD 0000Kernel.BIN.C file go here.  ASCII 0000 is near the top, 
+alphabetically, in case you use MagicISO.
+
+
+
+                                 ::/Home Files
+
+The home dir is specified with '~'.  The home dir is ::/Home unless you change 
+it with HomeSet() or compile the kernel with a cfg option.  An empty /Home dir 
+should be valid because it will get default files from the root dir. 
+
+~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in 
+the upper left border area of a window.
+
+~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key.
+
+~/MakeHome.HC a file compiled by the Adam Task during StartOS.
+
+~/Home* Copy Home* files from the root into ~ and customize them.  These files 
+are invoked when the Adam Task starts-up.
+
+~/Once.HC a file invoked at the start-up of the first user.  Customize this!
+
+~/Registry.HC can be edited by hand or deleted to reset to defaults.  Takes 
+affect next boot.
+
+
+
+                              Application Policies
+
+* Place applications in their own /Apps subdirectory.
+
+* Make a file called Load.HC.Z to load the application.
+
+* Make a file called Run.HC.Z to load and run the application, preferable by #in
+cludeing the Load.HC.Z file.
+
+* Place user data in a subdirectory of /Home, preferably naming the subdirectory 
+the same as the /Apps subdirectory.  Or, place data in the Registry.HC.Z file.  
+See ::/Demo/RegistryDemo.HC.
+
+* If the app needs files in the /Home directory, make an /Apps file called Insta
+ll.HC.Z or Install.IN.Z to create the /Home subdirectory.
+
+ 
+
+                             Programming Guidelines
+
+* Virtual mem/Paging is not used -- it is identity mapped in x86_64 mode.  The 
+stk does not grow, so alloc enough when the task (process) is Spawned and use 
+the heap for most things.  (The heap refers to MAlloc() and Free().)
+
+* You can Free(NULL).
+
+* See Naming Convention and Abbreviations.
+
+* There are two modes of compiling, AOT Compile Mode and JIT Compile Mode.  
+Compilation is done in both -- neither is "interpreted".  Use JIT Mode.
+
+* HolyC
+
+* Use I64 instead of smaller int sizes because the compiler converts everything 
+to 64-bit.  Don't use unsigned unless it actually breaks.  A policy of signed 
+keeps it simple so you don't have to agonize over choices.
+
+     U32 DistDist(U16 x1, U16 y1, U16 x2, U16 y2)
+     {//This requires zero-extend when fetching args.
+       return SqrI64(x1-x2)+SqrI64(y1-y2);
+     }
+     
+     I64 DistDist(I64 x1, I64 y1, I64 x2, I64 y2)
+     {
+       return SqrI64(x1-x2)+SqrI64(y1-y2);
+     }
+
+* In-order, short circuit logic is assumed.
+
+* Avoid boolean expression assignments.  Boolean assignments don't have short 
+circuit logic and are not compiled efficiently.  The Bool type is just an alias 
+for a 1 byte signed int -- nothing forces it to 1 or 0.  There is a ToBool() 
+function that will for to 1 ot 0, however.
+
+* Glbl vars in AOT BIN modules are initialized to zero.  They occupy space in 
+BIN files.
+
+* Bracketing code with PUSHFD CLI and POPFD will protect against simultaneous 
+accesses from tasks on one core.  To protect against multiple cores, you need a 
+locked semaphore.  I think semiphores need to be in their own cache line, but 
+I'm not sure.  I use lock bits in a lot of places not aligned.
+
+* SysDbg() and IsSysDbg() are really handy when working on the compiler or 
+kernel.  It's just a bit you can set and test.
+
+* I don't use U0 * because the size is zero for ptr arithmetic.
+
+* Use CH_SHIFT_SPACE for spaces in quotes in source code because I run 
+Spaces-to-Tabs on source code.
+
+* Do not use #if or #ifdef
+
+
+
+                                Hash Sym Tables
+
+* See ::/Adam/AHash.HC for examples of how the hash tables are set-up.  
+Basically, syms are placed into hash tables and child process hash tables are 
+chained to parents.  This provides scopes for vars and functions.
+
+* adam_task->hash_table holds the HolyC syms loaded in on start-up.
+
+* Fs->hash_table holds user HolyC syms and if a sym is not found, it checks 
+parents.  When a duplicate sym is added to the table, it overshadows the prev 
+sym.  When developing software, typically you include the file at the cmd 
+prompt, make changes and reinclude it.  Old syms are overshadowed but they are 
+still there.  Periodically, kill the TASK and start fresh when mem is low.  If 
+you wish your applications to free themselves instead of staying in mem, spawn 
+or PopUp() a task to run the application and kill it when it's done.
+
+* To display the contents of a hash table, use the Who() routine or the 
+varients.  HashDepthRep() gives a histogram  of how long the chains are, in case 
+you wish to make hash table sizes bigger.
+
+
+
+                               Assembly Language
+
+See ::/Doc/Asm.DD.
+
+* FS must always point to the cur CTask.
+
+* GS must always point to the cur CCPU.
+
+* Don't change the segment regs unless interrupts are off.  It's hard to do, 
+anyway.  SET_FS_BASE and SET_GS_BASE.
+
+* When interacting with HolyC compiled code, preserve RBP, RSI, RDI, R10-R15 
+because the compiler uses these for reg vars.  You are free to clobber RAX, RBX, 
+RCX, RDX, R8 and R9.  See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS
+
+* I recommend using the standard stk frame for functions because Caller() is 
+used to display the call stk, such as for the wallpaper.
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,nnnn
+...
+        LEAVE
+        RET
+
+* The args are removed from the stack with RET1 stmts.
+
+        RET1    16      //remove two args
+
+* No args are passed in regs.
+
+* RAX holds function return values, of course.
+
+* "MagicISO" is a trademark owned by MagicISO Corp.
+
+ diff --git a/public/Wb/Home/Doc/Hash.DD.HTML b/public/Wb/Home/Doc/Hash.DD.HTML new file mode 100755 index 0000000..ace60b9 --- /dev/null +++ b/public/Wb/Home/Doc/Hash.DD.HTML @@ -0,0 +1,79 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+There is a symbol (hash) table for each task.  When a sym is not found, the 
+parent task's sym table is checked.  All tasks chain back to the Adam task.
+
+TempleOS sym tables are implemented with an array of linked-lists.  A num is 
+generated from a string by HashStr() to index into the array of linked-lists.  
+Multiple strings can generate the same num, so linked-lists are built.  Newer 
+entries overshadow older ones.
+
+There are various types of entries.  See Hash Entry Types.
+
+Symbol Look-up (Used many places including the JIT Compiler and Loader.)
+1) Symbol name is hashed by adding and shifting the ASCII of all chars.
+2) hash table->body[] array is indexed.
+3) Linked-lst is traversed until match of text and type of entry.
+4) If not found, hash table->next table is searched.
+
+Duplicate entries are allowed -- they overshadow old entries.
+
+Address-to-Symbol Look-up (Slow because not important. We could use trees.)
+1) FunSeg Cache is scanned.
+2) Hash Tables are scanned.
+
+ diff --git a/public/Wb/Home/Doc/HeapDbg.DD.HTML b/public/Wb/Home/Doc/HeapDbg.DD.HTML new file mode 100755 index 0000000..285bb14 --- /dev/null +++ b/public/Wb/Home/Doc/HeapDbg.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Recompile the kernel with _CFG_HEAP_DBG=TRUE if you want more heap debugging.  
+You are on your own.
+
+ diff --git a/public/Wb/Home/Doc/HelloWorld.DD.HTML b/public/Wb/Home/Doc/HelloWorld.DD.HTML new file mode 100755 index 0000000..6d63dd3 --- /dev/null +++ b/public/Wb/Home/Doc/HelloWorld.DD.HTML @@ -0,0 +1,130 @@ + + + + + + + + + + + +
+//Press F5 in the editor to compile and run.
+
+--------Hello.HC.Z---------
+"Hello World\n";
+
+
+--------Hello.HC.Z---------
+U0 Main()
+{
+  "Hello World\n";
+}
+Main;
+
+
+--------Hello.HC.Z---------
+U0 MyPrint(U8 *st)
+{
+  "%s",st;
+}
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+U0 MyPrint2(U8 *st1,U8 *st2) //Any number of args.
+{
+  "%s %s\n",st1,st2; //Any number of args.
+}
+MyPrint2("Hello","World");
+
+
+--------Hello.HC.Z---------
+U0 MyPrint(U8 *st)
+{
+  "" st; //Empty with no comma means first is fmt str.
+}
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+asm {
+MSG:    DU8 "Hello World\n",0;
+
+//The convention is underscore on C callable.
+//Two colons means exported symbol.
+_HELLO_WORLD::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RSI
+        MOV     RSI,MSG
+        CALL    PUT_STR
+        POP     RSI
+        RET
+}
+Call(_HELLO_WORLD);
+
+
+--------Hello.HC.Z---------
+asm {
+_HELLO_WORLD::
+//You can only clobber RAX,RBX,RCX,RDX
+        MOV     RAX,'Hello '
+        CALL    PUT_CHARS //Up to 8 chars packed into one 64-bit int.
+        MOV     RAX,'World\n'
+        CALL    PUT_CHARS
+        RET
+}
+Call(_HELLO_WORLD);
+
+
+--------Hello.HC.Z---------
+asm {
+_MY_PRINT::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        CALL    PUT_STR
+        POP     RSI
+        POP     RBP
+        RET1    8       //Callee pops the stack to clear args.
+}
+_extern _MY_PRINT U0 MyPrint(U8 *st);
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+asm {
+_MY_PRINT::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    U64 SF_ARG1[RBP]
+        CALL    &PutS   //Callee pops the stack to clear args.
+        POP     RBP
+        RET1    8
+}
+_extern _MY_PRINT U0 MyPrint(U8 *st);
+MyPrint("Hello World\n");
+
+
+ diff --git a/public/Wb/Home/Doc/HelpIndex.DD.HTML b/public/Wb/Home/Doc/HelpIndex.DD.HTML new file mode 100755 index 0000000..b913d67 --- /dev/null +++ b/public/Wb/Home/Doc/HelpIndex.DD.HTML @@ -0,0 +1,124 @@ + + + + + + + + + + + +
+                                      Help
+
++] Keyboard Ctrls
++] Mouse Ctrls
++] Keyboard-Mouse Ctrls
+
+Welcome         About TempleOS
+Command Line    Take Tour
+Demo Index      Key Map
+Features        Requirements
+Charter         Strategic Decisions
+F.A.Q.          Glossary
+HolyC           Compiler Index
+Why Not More?   Demands
+The Std TempleOS PC
+        
++] User Help
++] Admin Help
++] Programmer help
++] System Programmer Help
+
+
+                                     Index
+AutoComplete
+Bit
+Boot
+Call
+Char Overview
+Char Routines
+Circular Queue
+Cmd Line Overview
+Cmd Line Routines
+Compiler Overview
+Compiler Routines
+Compression
+Ctrls
+Data Types
+Date
+Debugging Overview
+Debugging Routines
+Define
+Devices
+Disk
+Doc Overview
+Doc Routines
+Exceptions
+File
+File Utils
+Frames
+God
+Graphics Overview
+Graphics Routines
+Hash
+Help System
+HolyC
+InFile
+Info
+Install
+I/O
+Job
+Key Allocations
+Keyboard Devices
+Link Types
+Math
+Memory Overview
+Memory Routines
+Menus
+Messages
+Misc
+Mouse
+MultiCore
+OpCodes
+Operator Precedences
+PCI
+Print("") Fmt Strings
+Processor
+Profiler
+RedSea
+Registry
+Scan Codes
+ScrnCast
+Sound
+Sprites
+StdIn
+StdOut
+String
+Task
+TextBase Layer
+Time
+Training
+TOSZ
+Utils
+Windows
+
+ diff --git a/public/Wb/Home/Doc/HelpSystem.DD.HTML b/public/Wb/Home/Doc/HelpSystem.DD.HTML new file mode 100755 index 0000000..1e9e630 --- /dev/null +++ b/public/Wb/Home/Doc/HelpSystem.DD.HTML @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+#help_index "Topic/SubTopic;OtherTopic"
+The help index preprocessor compiler directive sets the topics for syms 
+subsequently defined.  You specify subtopics with a '/' tree hierarchy and 
+separate multiple topics with a ';'.  The index ctrls HI:index links.
+
+public causes a sym to appear in help_index reports.
+
+#help_file "filename[.DD.Z]"
+The help file preprocessor directive makes a file into the heading of a 
+HI:index report for the current help index.
+
+ diff --git a/public/Wb/Home/Doc/HolyC.DD.HTML b/public/Wb/Home/Doc/HolyC.DD.HTML new file mode 100755 index 0000000..a2cd37f --- /dev/null +++ b/public/Wb/Home/Doc/HolyC.DD.HTML @@ -0,0 +1,354 @@ + + + + + + + + + + + +
+                                     HolyC
+
+* See ::/Doc/CompilerOverview.DD.
+
+* See Scoping and Linkage for details on extern, import, _extern, _import, etc.
+
+* Built-in types include I0,I8,I16,I32,I64 for signed 0-8 byte ints and U0,U8,U1
+6,U32,U64 for unsigned 0-8 byte ints and F64 for 8 byte floats.
+
+        U0      void, but ZERO size!
+        I8      char
+        U8      unsigned char
+        I16     short
+        U16     unsigned short
+        I32     int
+        U32     unsigned int
+        I64     long (64-bit)
+        U64     unsigned long (64-bit)
+        F64     double
+        no F32 float.
+
+* Function with no args, or just default args can be called without parentheses. 
+
+  >Dir("*");
+  >Dir();
+  >Dir;
+
+* Default args don't have to be on the end.  This code is valid:
+  U0 Test(I64 i=4,I64 j,I64 k=5)
+  {
+    Print("%X %X %X\n",i,j,k);
+  }
+  
+  Test(,3);
+
+* A char const all alone is sent to PutChars().  A string with or without args 
+is sent to Print().  An empty string literal signals a variable fmt_str follows.
+
+  void DemoC(char drv,char *fmt,char *name,int age)
+  {
+    printf("Hello World!\n");
+    printf("%s age %d\n",name,age);
+    printf(fmt,name,age);
+    putchar(drv);
+    putchar('*');
+  }
+  
+  U0 DemoHolyC(U8 drv,U8 *fmt,U8 *name,I64 age)
+  {
+    "Hello World!\n";
+    "%s age %d\n",name,age;
+    "" fmt,name,age;
+    '' drv;
+    '*';
+  }
+
+* When dealing with function addresses such as for callbacks, precede the name 
+with "&".
+
+* Type casting is postfix.  To typecast int or F64, use ToI64(), ToBool() or 
+ToF64(). (TempleOS follows normal C float<-->int conversion, but sometimes you 
+want to override.  These functions are better than multiplying by "1.0" to 
+convert to float.) 
+
+* There is no main() function.  Any code outside of functions gets executed upon 
+start-up, in order.
+
+* There are no bit fields, but there are bit access routines and you can access 
+bytes or words within any int.  See I64 declaration.  A class can be accessed as 
+a whole are subints, if you put a type in front of the class declaration.
+  
+  public I64i union I64         //"I64i" is intrinsic.  We are defining "I64".
+  {
+    I8i i8[8];
+    U8i u8[8];
+    I16 i16[4];
+    U16 u16[4];
+    I32 i32[2];
+    U32 u32[2];
+  };
+  
+  I64 i=0x123456780000DEF0;
+  i.u16[1]=0x9ABC;
+
+* Variable arg count functions (...) can access their args with built-in 
+variables similar to 'this' in C++.  They are 'I64 argc' and 'I64 argv[]'.  
+  
+  I64 AddNums(...)
+  {
+    I64 i,res=0;
+    for (i=0;i<argc;i++)
+      res+=argv[i];
+    return res;
+  }
+  
+  >AddNums(1,2,3);
+  ans=6
+  
+  
+  public U0 GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...)
+  {
+    U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);//SPrintF() with MAlloc()ed string.
+    GrPutS(dc,x,y,buf); //Plot string at x,y pixels. GrPutS is not public.
+    Free(buf);
+  }
+  
+    ...
+  
+    GrPrint(gr.dc,(GR_WIDTH-10*FONT_WIDTH)>>1,(GR_HEIGHT-FONT_HEIGHT)>>1,
+        "Score:%4d",score);  //Print score in the center of the scrn.
+    ...
+  
+
+* Allows "5<i<j+1<20" instead of "5<i && i<j+1 && j+1<20".
+  
+  if (13<=age<20)
+    "Teen-ager";
+
+* if you know a switch stmt will not exceed the lowest or highest case values.  
+switch [] is a little faster because it doesn't check.
+
+* switch stmts always use a jump table.  Don't use them with cases with really 
+big, sparse ranges.
+
+* Allows ranges like "case 4...7:" in switch stmts.
+
+* A no case number causes next higher int case in switch stmts.  See 
+::/Demo/NullCase.HC.
+
+  I64 i;
+  for (i=0;i<20;i++) 
+    switch (i) {
+      case: "Zero\n";   break; //Starts at zero
+      case: "One\n";    break; //One plus prev case.
+      case: "Two\n";    break;
+      case: "Three\n";  break;
+      case 10: "Ten\n"; break;
+      case: "Eleven\n"; break; //One plus prev case.
+  }
+
+* Switch statements can be nestled with a single switch expression!  This is 
+known as a "sub_switch" statement.  start/end are used to group cases.  Don't 
+goto out of, throw an exception out of, or return out of the start front porch 
+area.  See ::/Demo/SubSwitch.HC.
+
+  I64 i;
+  for (i=0;i<10;i++)
+    switch (i) {
+      case 0: "Zero ";  break;
+      case 2: "Two ";   break;
+      case 4: "Four ";  break;
+      start:
+        "[";
+        case 1: "One";  break;
+        case 3: "Three";break;
+        case 5: "Five"; break;
+      end:
+        "] ";
+        break;
+    }
+  OutPut:
+  >Zero [One] Two [Three] Four [Five]
+
+* A no_warn stmt will suppress an unused var warning.
+
+* You can have multiple member vars of a class named "pad" or "reserved", and it 
+won't issue warnings. 
+
+* noreg or reg can be placed before a function local var name.  You can, 
+optionally, specify a reg after the reg keyword.
+
+  U0 Main()
+  {
+    //Only use REGG_LOCAL_VARS or REGG_LOCAL_NON_PTR_VARS for reg vars or else 
+  clobbered.
+    I64 reg R15 i=5, noreg j=4;
+    no_warn i;
+    asm {
+        MOV     RAX,R15
+        CALL    &PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    &PUT_CHARS
+        MOV     RAX,U64 &j[RBP]
+        CALL    &PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    &PUT_CHARS
+    }
+  }
+
+* interrupt, haserrcode, public, argpop or noargpop are function flags. See 
+IRQKbd().
+
+* A single quote can encompass multiple characters.  'ABC' is equ to 0x434241.  
+PutChars() takes multiple characters.
+
+  asm {
+  HELLO_WORLD::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,'Hello '
+        CALL    &PUT_CHARS
+        MOV     RAX,'World\n'
+        CALL    &PUT_CHARS
+        LEAVE
+        RET
+  }
+  Call(HELLO_WORLD);
+  PutChars('Hello ');
+  PutChars('World\n');
+
+* The "`" operator raises a base to a power.
+
+* There is no question-colon operator.
+
+* TempleOS operator precedence
+  `,>>,<<
+  *,/,%
+  &
+  ^
+  |
+  +,-
+  <,>,<=,>=
+  ==,!=
+  &&
+  ^^
+  ||
+  =,<<=,>>=,*=,/=,&=,|=,^=,+=,-=
+
+* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in 
+code.
+
+* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find dup local var type stmts.
+
+* With the #exe{} feature in your src code, you can place programs that insert 
+text into the stream of code being compiled.  See #exe {} for an example where 
+the date/time and compile-time prompting for cfguration data is placed into a 
+program.  StreamPrint() places text into a src program stream following the 
+conclusion of the #exe{} blk.
+
+* No #define functions exist (I'm not a fan)
+
+* No typedef, use class.
+
+* No type-checking
+
+* Can't use <> with #include, use "".
+
+* "$" is an escape character.  Two dollar signs signify an ordinary $.  See 
+DolDoc.  In asm or HolyC code, it also refers to the inst's address or the 
+offset in a class definition. 
+
+* union is more like a class, so you don't reference it with a union label after 
+you define it.  Some common unions are declared in KernelA.HH for 1,2,4 and 8 
+byte objects.  If you place a type in front of a union declaration, that is the 
+type when used by itself.  See ::/Demo/SubIntAccess.HC. 
+
+* class member vars can have meta data. format and data are two meta data types 
+now used.  All compiler structures are saved and you can access the compiler's 
+info about classes and vars.  See ::/Demo/ClassMeta.HC and  DocForm().
+
+* There is a keyword lastclass you use as a dft arg.  It is set to the class 
+name of the prev arg.  See ::/Demo/LastClass.HC, ClassRep(), DocForm()  and 
+::/Demo/Dsk/BlkDevRep.HC.
+
+* See ::/Demo/Exceptions.HC.  try{} catch{} and throw are different from C++. th
+row is a function with an 8-byte or less char arg.  The char string passed in th
+row() can be accessed from within a catch{} using the Fs->except_ch.  Within a c
+atch {} blk, set the var Fs->catch_except to TRUE if you want to terminate the 
+search for a hndlr.  Use PutExcept() as a hndlr, if you like.
+
+* A function is available similar to sizeof which provides the offset of a 
+member of a class.  It's called offset.  You place the class name and member 
+inside as in offset(classname.membername).  It has nothing to do with 16-bit 
+code.  Both sizeof and offset only accept one level of member vars.  That is, 
+you can't do sizeof(classname.membername.submembername).
+
+* There is no continue stmt.  Use goto.
+
+* lock{} can be used to apply asm LOCK prefixes to code for safe multicore 
+read-modify-write accesses.  The code bracked with have LOCK asm prefix's 
+applied to relevant insts within.  It's a little shoddy.  See 
+::/Demo/MultiCore/Lock.HC.
+
+* There is a function called MSize() which gives the size of an object alloced 
+off the heap.  For larger size allocations, the system rounds-up to a power of 
+two, so MSize() lets you know the real size and you can take full advantage of 
+it.
+
+* You CAN Free() a NULL ptr.  Useful variants of MAlloc() can be found Here.  
+Each task has a heap and you can MAlloc and Free off-of other task's heaps, or 
+make an independent heap with HeapCtrlInit().  See HeapLog() for an example.
+
+* The stk does not grow because virtual mem is not used.  I recommend allocating 
+large local vars from the heap.  You can change MEM_DFT_STK and recompile Kernel 
+or request more when doing a Spawn().  You can use CallStkGrow(), but it's odd.  
+See ::/Demo/StkGrow.HC. 
+
+* Only one base class is allowed.
+
+* printf() has new codes.  See Print("") Fmt Strings.
+
+* All values are extended to 64-bit when accessed.  Intermediate calculations 
+are done with 64-bit values.
+
+  U0 Main()
+  {
+    I16 i1;
+    I32 j1;
+    j1=i1=0x12345678;           //Resulting i1 is 0x5678 but j1 is 0x12345678
+  
+    I64 i2=0x8000000000000000;
+    Print("%X\n",i2>>1);        //Res is 0xC000000000000000 as expected
+  
+    U64 u3=0x8000000000000000;
+    Print("%X\n",u3>>1);        //Res is 0x4000000000000000 as expected
+  
+    I32 i4=0x80000000;          //const is loaded into a 64-bit reg var.
+    Print("%X\n",i4>>1);        //Res is 0x40000000
+  
+    I32 i5=-0x80000000;
+    Print("%X\n",i5>>1);        //Res is 0xFFFFFFFFC0000000
+  }
+
+
+ diff --git a/public/Wb/Home/Doc/InFile.DD.HTML b/public/Wb/Home/Doc/InFile.DD.HTML new file mode 100755 index 0000000..ef12804 --- /dev/null +++ b/public/Wb/Home/Doc/InFile.DD.HTML @@ -0,0 +1,49 @@ + + + + + + + + + + + +
+InFiles are used to generate user input to automate operations.  The TempleOS 
+tour is done with an InFile.  It reminds me of a Unix pipe because StdOut of one 
+gets chained into StdIn of another.
+
+When an InFile runs, a child task is Spawn()ed which intercepts real user input 
+and generates fake input.  InFiles are HolyC programs run by the child whose 
+stdout goes to the parent's input buffer.  Msg() can be included in an InFile to 
+send special keys or mouse cmds to the parent.  While an InFile is running, the 
+normal input gets diverted to the InFile task and can be filtered and sent back 
+to the parent task.  Unless you are driving functions which prompt for data, you 
+can probably use an #include file in place of an InFile.
+
+See ::/Demo/InFile/InDir.IN.
+
+Note: In("") can be used if all you need is to send ASCII characters.  It 
+differs from InStr().  You'll probably use In() a lot and not InStr().  With In(
+), for example, you can place answers to the prompts for recompiling the Kernel 
+module during BootHDIns().
+
+ diff --git a/public/Wb/Home/Doc/Install.DD.HTML b/public/Wb/Home/Doc/Install.DD.HTML new file mode 100755 index 0000000..3c29a84 --- /dev/null +++ b/public/Wb/Home/Doc/Install.DD.HTML @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+                              Installing TempleOS
+
+Burn a CD with software that supports ISO files.  Then, boot it.  It's a live 
+CD, so you can look around with or without installing.
+
+Dual booting with another operating system is the best way to use TempleOS.  I 
+only use it in a virtual machine because it won't boot natively on my machine, 
+though.  For native dual booting, you need a partition for TempleOS.  Windows 
+often comes with a restore disk that does not allow repartitioning.  I recommend 
+connecting a spare additional hard drive and using the BIOS to select which 
+drive to boot.
+
+The ::/Misc/OSInstall.HC script will automate much of this.  It runs if you boot 
+the CD/DVD-ROM.
+
+See Boot.DD for an overview of booting.  See Requirements for supported 
+hardware.
+
+Two TempleOS partitions are highly recommended, so you can boot to a back-up and 
+fix the primary when you work on it.  Odds are, you only need a couple gigabytes 
+for your TempleOS partitions.
+
+1)
+  Mount() use if the drive is partitioned.
+    This command mounts a drive making it accessible.  For simplicity, sel 'C' 
+    as the first drive letter for your hard drive.  The first partition will be 
+    'C', second, 'D', etc.  TempleOS needs 3 numbers to utilize a hard drive -- 
+    base0, base1, and unit.  When you enter a hexadecimal number, do it like in 
+    C with a 0x prefix.  If the probe was successful, you can just enter the 
+    number in the probe box instead of base0.
+  
+  DskPrt('C') use if drive is not partitioned
+  
+    This will perform a special Mount() automatically.
+    
+    WARNING:  This command erases everything on a hard drive.  It repartitions a 
+    whole drive and formats the partitions.  This command should be skipped if 
+    you already have your hard drive partitioned.
+    
+    
+    WARNING:  This command doesn't play well with other operating systems.  
+    You'll need to do a BootMHDZero() to restore your drive to a state where 
+    other operating systems can partition it.
+  
+2) Fmt('D',TRUE,FALSE,FSt_FAT32)
+  This command formats a drive with FAT32 or the RedSea file system type.  Use 
+  the drive letter of the partition in place of 'D'.
+  
+  WARNING:  If you are upgrading, be sure not to lose the file, /0000Boot/OldMBR
+  .BIN.C.
+  
+3) CopyTree("T:/","D:/")
+  This command is used to copy files onto a hard drive partition from the 
+  CD/DVD.  Use the drive letter of the partition in place of 'D'.
+  
+4) BootHDIns('D')
+  This command recompiles the source code on a drive and writes to the drive's 
+  boot record.  You'll need to reenter the Mount information so it can be stored 
+  in the kernel.
+  
+5) Use Linux's Grub or TempleOS' BootMHDIns('D')
+  
+  The BootMHDIns() command places a boot loader on a drive.  It saves the old 
+  master boot record to /0000Boot/OldMBR.BIN.C and replaces it.  When you boot, 
+  you will have the option of booting the old master boot record.  This command 
+  can be skipped if you already have a boot loader.  Be sure not to lose the 
+  copy of the old boot record, like if you reformat the drive.
+  
+  Delete /0000Boot/OldMBR.BIN.C if you want to get a fresh copy of a mbr, like 
+  if installing from your own custom CD containing it's own /0000Boot/OldMBR.BIN
+  .C onto a system with a non-TempleOS boot loader.
+  
+  If you have anti-virus software, it might object to having a different master 
+  boot record.
+
+
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Doc/Job.DD.HTML b/public/Wb/Home/Doc/Job.DD.HTML new file mode 100755 index 0000000..ecb46f6 --- /dev/null +++ b/public/Wb/Home/Doc/Job.DD.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+               PopUpPrint                         User          ExePrint
+
+
+
+                  PopUp                                          ExePutS
+
+
+
+ Core0 AdamTask  SrvCmdLine   AP SethTask       UserCmdLine
+
+
+
+
+
+
+         SrvTaskCont                          UserTaskCont
+
+
+
+        JobsHndlr
+
+
+
+         JobRunOne           JobRunOne         ExeCmdLine      ExeCmdLine
+
+
+
+
+CJob nodes are one of five types.  User applications deal with text or msgs.  
+JobRunOne() will call a function, spawn a task or execute some text src code.
+
+#define JOBT_TEXT_INPUT         0 //TaskText()  Feed StdIn 
+#define JOBT_MSG                1 //TaskMsg()   Post msg 
+#define JOBT_EXE_STR            2 //TaskExe()   Compile & execute src code text
+#define JOBT_CALL               3 //JobQue()    Tell MP to call function
+#define JOBT_SPAWN_TASK         4 //Spawn()     Tell MP to spawn task
+
+Several other routines include a call to JobsHndlr() that gives them powerful 
+ability to execute servant cmds.
+
+ diff --git a/public/Wb/Home/Doc/KeyAlloc.DD.HTML b/public/Wb/Home/Doc/KeyAlloc.DD.HTML new file mode 100755 index 0000000..815eb33 --- /dev/null +++ b/public/Wb/Home/Doc/KeyAlloc.DD.HTML @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+                                Key Allocations
+
+See Char for definition of scan codes.
+
+See Key Map for a detailed list of key commands.
+
+When you are at the cmd line, editing documents, browsing documentation and 
+help, entering items in forms or in menu's, the DolDoc editor handles keys.  It 
+allows you to define your own key hndlrs in a MyPutKey() function.  If you 
+choose, you can catch keys, overriding the default hndlrs.  See DocPutKey().  
+The following is an overview of key allocations.
+
+<ALT-keys> and <ALT-SHIFT-keys>  Free for user configurations in your MyPutKey() 
+hndlr, except for ALT-BACKSPACE (undo).  There are a few examples pre-defined, 
+but you can change them if you wish.
+
+<CTRL-ALT-keys> and <CTRL-ALT-SHIFT-keys>  Handled at a system level, NOT by the 
+CDoc editor.  I reserve the right to alloc these, but in the mean time, you can 
+define your own hndlrs with CtrlAltCBSet().  They operate either in a interrupt 
+environment or in the window mgr when it queues kbd msgs.  You can do Raw() 
+output.  <CTRL-ALT-letter> hndlrs take a scan_code as an arg.
+
+<CTRL-function key>  Auto-completes local words.
+
+<CTRL-digit key>  Auto-completes dictionary words.
+
+<CTRL-SHIFT-function key>  Jumps to src code.
+
+<CTRL-SHIFT-digit key>  Jumps to dictionary definition.
+
+<function keys> and <SHIFT-function keys>  I reserve the right to alloc these, 
+but there are some free now.
+
+<CTRL-key> and <CTRL-SHIFT-key>  I reserve the right to alloc to these.  There 
+are not many free.
+
+See Keyboard Devices.
+
+ diff --git a/public/Wb/Home/Doc/KeyDev.DD.HTML b/public/Wb/Home/Doc/KeyDev.DD.HTML new file mode 100755 index 0000000..f7c40a2 --- /dev/null +++ b/public/Wb/Home/Doc/KeyDev.DD.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+The editor mostly stays in a GetKey()/PutKey() loop.  The putkey portion is 
+where keys are acted-upon.  TempleOS has a chain of putkey hndlrs in a 
+Circular Queue with priorities.  The highest priority hndlrs can choose to 
+terminate handling, otherwise, the keys get sent on down the chain.
+
+KeyDevAdd() defines a putkey device with a priority.  "Device" might be a 
+misnomer.  Currently, the following are defined:
+
+Priority    Hndlr
+---------- ---------
+0x20000000 MyPutKey() user hndlr
+0x40000000 KDInputFilterPutKey() for In(), InStr(), and InFile() handling.
+0x60000000 KDRawPutKey() nonwindowed direct to video mem debug output. 
+0x80000000 KDDocPutKey() standard document cmds
+
+Since handling individual keys is slow, TempleOS supports PutS() as well.  If no 
+puts hndlr is defined, individual keys are sent.
+
+CDoc.user_put_key and CDoc.user_put_s are call back routines which offer some 
+neat tricks.  See ::/Apps/Psalmody/JukeBox.HC.  There is a var CDoc.user_put_dat
+a which gets passed to them.
+
+ diff --git a/public/Wb/Home/Doc/Lex.DD.HTML b/public/Wb/Home/Doc/Lex.DD.HTML new file mode 100755 index 0000000..c5ec281 --- /dev/null +++ b/public/Wb/Home/Doc/Lex.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+The compiler's lexical analyzer can be used in your programs to simplify 
+parsing.  See Doc Parsing or Parse Opcode File.
+
+See Tokens.
+
+ diff --git a/public/Wb/Home/Doc/MemOverview.DD.HTML b/public/Wb/Home/Doc/MemOverview.DD.HTML new file mode 100755 index 0000000..1e27208 --- /dev/null +++ b/public/Wb/Home/Doc/MemOverview.DD.HTML @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+                                Memory Overview
+
+Paging is practically not used.  64-bit mode requires paging, however, so it is 
+identity-mapped -- virtual identical to physical.  All tasks on all cores use 
+the same page table map, just as though all addresses are physical addresses.  
+2Meg or 1Gig page table entries are used.  Nothing swaps to disk.
+
+In TempleOS, the lowest 2Gig of memory is called the code heap.  TempleOS's 
+compiler always uses 32-bit signed relative JMP & CALL insts because 64-bit 
+CALLs take two insts.  With signed +/- 32-bit values, code can only call a 
+function within 2Gig distance.  Therefore, TempleOS keeps all code in the lowest 
+2Gig memory addresses including what would normally be called "the kernel".  Two 
+Gig is plenty for code, don't worry.
+
+You can create new, independent heaps using HeapCtrlInit().  Then, use the 
+CHeapCtrl as the 2nd arg to MAlloc().  See HeapLog() for an example.
+
+Memory alloced by a task will be freed when the task is killed.  The Adam Task 
+is a task that never dies.  His memory is like kernel memory in other operating 
+systems.  See ACAlloc(), AMAlloc(), AMAllocIdent() and AStrNew().
+
+All of the regular page tables are marked, "cached".  When accessing hardware, 
+however, you need uncached page table.  The lowest 4Gig addresses have an alias 
+to access hardware located toward the top of mapped space, 0x10000000000.  See 
+dev.uncached_alias.
+
+During an extended powered-on session of TempleOS, in theory, memory will become 
+fragmented, requiring a reboot.  It has never happens to me.
+
+See MemRep() and ::/Demo/MemDemo.HC.
+
+
+                           Single System-wide Mem Map
+
+ 0x0000007C00- 0x000003616F
+  Kernel module, placed here by the boot-loader, BOOT_RAM_BASE.
+
+ 0x0000096600- 0x0000096FFF
+  Boot block relocated here before loading the Kernel module, BootDVD & BootHD.
+
+ 0x0000097000- 0x0000097030 Multicore start-up vect code, MPN_VECT.
+~0x000009F000- 0x000009FFFF Extended BIOS data area.
+ 0x00000A0000- 0x00000BFFFF VGA graphics mem with alias at text.vga_alias.
+ 0x0000100000- 0x0000101FFF CSysFixedArea for misc.
+ 0x000050A000- 0x001FFDFFFF Code Heap mem.
+
+ 0x00E0000000- 0x00FFFFFFFF
+  32-bit devices could alloc memory at 0xF0000000 going up, but this is wrong, 
+  since some PCs already have devices at 0xF0000000.  No PCI devices are 
+  supported, so Mem32DevAlloc() flaws are not an issue.
+
+ 0x0080000000-~0x00DFFFFFFF
+ 0x0100000000-~0xFFFFFFFFFF
+  Data Heap mem.  (The physical memory that exists in this range is data heap.)
+
+ 0x10000000000- 0x100FFFFFFFF
+  Uncached alias of first 4Gig.  (For 32-bit device access.)
+
+             - 0x100FFFFFFFF
+  64-bit devices are alloced with Mem64DevAlloc() counting bwd, but no PCI 
+  devices are actually supported.
+
+
+
+* Note: There is a break in the data-heap block pool.  This has no effect except 
+the obvious effect that fragmentation has on contiguous requests.  I can MAlloc(
+) an 8Gig chunk on my 12Gig machine.  I can MAlloc() an 32Gig chunk on my 64Gig 
+machine.  
+
+* Note: For systems with less than 2Gig RAM, the code and data heap block pools 
+are the same.  For systems with 2-4Gig of RAM, the code heap is 1/4 of the 
+total.  See BlkPoolsInit().
+
+
+                                    History
+
+In 2003, I wanted to make a no-paging ring-0-only 64-bit operating system for 
+super speed with simplicity and full access.  With paging, every memory request 
+requires 5 accesses -- it must access the address itself, 4K, 2Meg, 1Gig, and 
+512Gig page tables, but the CPU's translation look-aside buffer mostly removes 
+the penalty for using paging.  So, I did not want to use paging, but long mode 
+requires it.  I did the next best thing -- I identity-mapped everything and 
+achieved the simplicity I was after with subtle performance boosts, not wasting 
+time changing address maps.  And, I look forward to the day I command Intel to 
+make an optimized no-paging long mode.
+
+I needed VGA A0000-BFFFF memory to be write-through and 0xE0000000-0xFFFFFFFF to 
+be uncached for various devices.  All 64-bit computers allow stopping address 
+translation at 2Meg page size, not using 4K.  I wanted to use 2Meg for 
+everything because it's faster, with one less level of page tables.  I had to 
+make A0000-BFFFF write-through, though, so I could not use 2Meg size on the 
+lowest page.  I did the lowest 2Meg area as 4K pages.  I also unmapped the first 
+4K to cause a fault when dereferencing NULL.
+
+In 2016, I came-up with an alternate idea.  I double mapped the lowest memory 
+with an alias that was uncached.  Accessing the lowest 2Meg area directly was 
+cached but the alias I created up at the top of address space was uncached.  See 
+UncachedAliasAlloc().  Unfortunately, I could no longer boast of the simplicity 
+of identity mapping everything.  Since many of my users are familiar with 
+A0000-BFFFF, it is actually pretty seriously unfortunate that they cannot use 
+the easy-to-understand numbers of A0000-BFFFF, but must access the relocated 
+alias location.  See text.vga_alias.  I also no longer cause a fault when 
+dereferencing NULL.
+
+Then, I switched to 1Gig page sizes.  For the lowest 4Gig, I set-up an alias up 
+at the top of address space.  See UncachedAliasAlloc().  Not all computers 
+support 1Gig page tables, however, so I also support 2Meg.
+
+My original plan was to allow changing the page tables as needed, so I had code 
+for taking control of 2Meg pages and marking them uncached or whatever.  When I 
+did a HDAudio driver, I requested some 32-bit address space as uncached.  Today, 
+all of the first 4Gig can be accessed without caching at the dev.uncached_alias.
+
+ diff --git a/public/Wb/Home/Doc/Menus.DD.HTML b/public/Wb/Home/Doc/Menus.DD.HTML new file mode 100755 index 0000000..dc8d4b0 --- /dev/null +++ b/public/Wb/Home/Doc/Menus.DD.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+A pull-down menu appears when you move the mouse to the top of the scrn.  Menus 
+are created with MenuPush(), MenuFilePush(), MenuNew() or MenuFile() and 
+assigned to Fs->cur_menu.  The format is:
+
+
+File 
+{
+  Open(,'O');
+  Save(,'S');
+  Exit(,CH_SHIFT_ESC);
+}
+Edit {
+  Cut(,,SC_DELETE|SCF_SHIFT);
+  Paste(,,SC_INS|SCF_SHIFT);
+}
+Misc {
+  Opt1(MSG_CMD,M_OPTION1);
+  Opt2(MSG_CMD,M_OPTION2);
+}
+Help
+{
+  Help(,'?');
+  About(,'/');
+}
+
+The first arg is the msg code and it is optional with the default being 
+MSG_KEY_DOWN_UP.  The second arg is the msg arg1 value which is ASCII of the key 
+in the case of MSG_KEY_DOWN.  The third arg is the msg arg2 value which is the 
+scan_code of the key in the case of MSG_KEY_DOWN.
+
+Press <CTRL-SHIFT-l> and "Insert ASCII/ScanCode".
+
+See ::/Demo/PullDownMenu.HC.
+
+ diff --git a/public/Wb/Home/Doc/Mouse.DD.HTML b/public/Wb/Home/Doc/Mouse.DD.HTML new file mode 100755 index 0000000..6c36bfb --- /dev/null +++ b/public/Wb/Home/Doc/Mouse.DD.HTML @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+ms.pos.x and ms.pos.y can be used to access the x and y coordinates of the 
+mouse.  They are relative to the scrn, not window.  These can be used if you 
+don't want to use msg passing.  ms.pos.z is the wheel.
+
+ms.pos_text.x and ms.pos_text.y are the text column and row.  See 
+::/Demo/Games/Maze.HC.
+
+See CMsStateGlbls and CMsHardStateGlbls.
+
+The hard designation, as in ms_hard, represents hardware layer items before the 
+application of an abstraction layer.
+
+//****
+ms_hard.pos.x=ms_hard.prescale.x*ms_hard.scale.x*ms_grid.x_speed;
+ms.presnap.x=ToI64(ms.scale.x*ms_hard.pos.x)+ms.offset.x;
+if (ms_grid.snap)
+  ms.pos.x=Trunc(ms.presnap.x/ms_grid.x)*ms_grid.x+ms_grid.x_offset;
+else
+  ms.pos.x=ms.presnap.x;
+//****
+
+ diff --git a/public/Wb/Home/Doc/Msgs.DD.HTML b/public/Wb/Home/Doc/Msgs.DD.HTML new file mode 100755 index 0000000..dee3f4b --- /dev/null +++ b/public/Wb/Home/Doc/Msgs.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+There are a maximum of 63 message types, so a bitmask can be passed.  Messages 
+have two args.  See Message Codes.
+
+ diff --git a/public/Wb/Home/Doc/MultiCore.DD.HTML b/public/Wb/Home/Doc/MultiCore.DD.HTML new file mode 100755 index 0000000..5e9b63c --- /dev/null +++ b/public/Wb/Home/Doc/MultiCore.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+TempleOS does master-slave multicore instead of SMP.  Core0 is the master.  The 
+master core's applications explicitly assign computational jobs to other cores 
+and the TempleOS scheduler does not move tasks between cores.
+
+There are multicore safe locks for file access and heap allocations, however, so 
+TempleOS is symmetrical in some sense.  See ::/Demo/MultiCore/LoadTest.HC.
+
+Only tasks on Core0 can have windows, but other cores can help render them.
+
+Each core has an executive Seth Task which is the father of all tasks on that 
+core.  Adam is the Seth Task on Core0.
+
+You give a job to a Seth Task with JobQue() and get the result with JobResGet(). 
+ You spawn a task on any core with Spawn().
+
+Note: You must use the LOCK asm prefix when changing shared structures in a 
+multicore environment.  The LBts(), LBtr() and LBtc() insts have LOCK prefixes.  
+The compiler has a lock{} feature but it doesn't work well.  See 
+::/Demo/MultiCore/Lock.HC.
+
+See ::/Demo/Graphics/Transform.HC.
+See ::/Kernel/MultiProc.HC.
+
+ diff --git a/public/Wb/Home/Doc/NewASCII.DD.HTML b/public/Wb/Home/Doc/NewASCII.DD.HTML new file mode 100755 index 0000000..769a5ec --- /dev/null +++ b/public/Wb/Home/Doc/NewASCII.DD.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+                                   New ASCII
+
+
+We want to use one set for ASCII, ScanCodes and ScreenCodes.
+
+
+0  -63  :
+64 -127 : SHIFT
+128-191 : CTRL
+192-256 : CTRL+SHIFT
+
+No more ALT key in TempleOS.
+
+CTRL-LEFT/RIGHT is already begin/end line.
+CTRL-UP/DOWN    is already top/bottom of document.
+
+What about function keys?
+We will use reduced keyboard, probably.
+
+
+
+God says...
+clearest bade domine chance none quoth privily subjection possessor abolished
+
+
+
+
+ diff --git a/public/Wb/Home/Doc/ODE.DD.HTML b/public/Wb/Home/Doc/ODE.DD.HTML new file mode 100755 index 0000000..030966f --- /dev/null +++ b/public/Wb/Home/Doc/ODE.DD.HTML @@ -0,0 +1,40 @@ + + + + + + + + + + + +
+TempleOS has an advanced algorithm for integrating ordinary differential 
+equations suitable for use in video games.  (Not scientific work.)  It also has 
+some support for systems of masses and springs, to save you some work.
+
+See CMathODE and ODEsUpdate for an overview.
+See ODECallDerivative to see what support there is for masses and springs.
+
+See ::/Demo/Games/Whap.HC, ::/Demo/Games/Rocket.HC, ::/Demo/Games/MassSpring.HC, 
+::/Apps/Span/SpanMain.HC or ::/Apps/X-Caliber/X-Caliber.HC.
+
+ diff --git a/public/Wb/Home/Doc/Once.DD.HTML b/public/Wb/Home/Doc/Once.DD.HTML new file mode 100755 index 0000000..78b2712 --- /dev/null +++ b/public/Wb/Home/Doc/Once.DD.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+KMain()
+  includes ::/StartOS.HC
+    includes ~/MakeHome.HC
+      includes ~/HomeSys.HC
+        calls StartUpTasks()
+          includes ~/Once.HC
+            calls OnceExe().
+
+AOnce() appends src code to ~/Registry.HC Once/Adam tree, executed at next boot 
+by Adam.
+
+Once()  appends src code to ~/Registry.HC Once/User tree, executed at next boot 
+by first User term.
+
+At boot, OnceExe(), executes Once/Adam tree, AOnceFlush()s it,
+executes Once/User tree and OnceFlush()s.
+
+ diff --git a/public/Wb/Home/Doc/Options.DD.HTML b/public/Wb/Home/Doc/Options.DD.HTML new file mode 100755 index 0000000..def5955 --- /dev/null +++ b/public/Wb/Home/Doc/Options.DD.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+                                Compiler Options
+
+Use Option().  You might need to do #exe {Option();}.
+
+OPTf_GLBLS_ON_DATA_HEAP without this option, global vars are placed in the code 
+heap which is limited to 2Gig.  In AOT modules, global vars take-up room in the 
+.BIN file, so you might want to use this option, instead.  You might wish to 
+turn it on and off around specific vars.  A disadvantage of data heap global 
+vars in AOT modules is they can't be initialized.
+
+OPTf_EXTERNS_TO_IMPORTS and OPTf_KEEP_PRIVATE are strange options, you'll never 
+need.  They're to allow the same header file for Kernel to act as externs when 
+compiling itself and imports when compiled by AOT modules.
+
+OPTf_WARN_UNUSED_VAR    warning if unused var.  It is applied to functions.
+
+OPTf_WARN_PAREN         warning if parenthesis are not needed.
+
+OPTf_WARN_DUP_TYPES     warning if dup local var type stmts.
+
+OPTf_WARN_HEADER_MISMATCH warning if fun header does not match.
+
+OPTf_NO_REG_VAR forces all function local vars to the stk not regs.  Applied to 
+functions.
+
+OPTf_NO_BUILTIN_CONST Disable 10-byte float consts for pi, log2_10, log10_2, 
+loge_2.  Applied to functions.
+
+ diff --git a/public/Wb/Home/Doc/Pags.DD.HTML b/public/Wb/Home/Doc/Pags.DD.HTML new file mode 100755 index 0000000..bb1cb6a --- /dev/null +++ b/public/Wb/Home/Doc/Pags.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+The word Pag refers to an arbitrilly created MEM_PAG_SIZE unit of heap 
+allocation.  TempleOS does not alter the CPU page tables after setting them up 
+at boot in SYS_INIT_PAGE_TABLES, so the CPU hardware page size is rarely 
+important.
+
+ diff --git a/public/Wb/Home/Doc/PreProcessor.DD.HTML b/public/Wb/Home/Doc/PreProcessor.DD.HTML new file mode 100755 index 0000000..80d5b97 --- /dev/null +++ b/public/Wb/Home/Doc/PreProcessor.DD.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+                                  PreProcessor
+
+There is no separate preprocessor pass.  The parser front-end calls Lex() which 
+has the preprocessor built-in.  The compiler looks ahead a token, most of the 
+time, so you might throw an extra semicolon after a directive if it's not taking 
+affect right away.
+
+Put an extra semicolon #exe {Cd("DirName");;} in case a #include follows.
+
+#include ""     There is no angle bracket <> form of this directive.
+#exe {}         Will execute code at compile-time and can be used to insert code 
+into the stream being compiled using StreamPrint().
+#define         Define string const
+#assert         Print a warning during compilation if an expression is not true. 
+#if             Include code if an expresion is true.
+#else
+#endif
+#ifdef,#ifndef  Include code if a sym is defined.
+#ifaot,#ifjit   Include code if in AOT compiler mode.
+defined()       Is a function that can be used in expressions.
+#help_index, #help_file See Help System.
+
+See PreProcessor.
+
+ diff --git a/public/Wb/Home/Doc/Print.DD.HTML b/public/Wb/Home/Doc/Print.DD.HTML new file mode 100755 index 0000000..938606d --- /dev/null +++ b/public/Wb/Home/Doc/Print.DD.HTML @@ -0,0 +1,144 @@ + + + + + + + + + + + +
+                                 Print Fmt Strs
+
+<fmt_arg> := %[-][0][<width>][.<decimals>][<flags>][h<aux_fmt_num>]<fmt_code>
+
+See StrPrintJoin().
+
+<flags>:
+
+  't' truncate to <width>.
+  ',' add commas every three digits or four nibbles.
+  '$' makes %Q convert '$' to "\x24".
+  '/' makes %Q and %q convert '%' to "%%".
+
+<aux_fmt_num>:
+
+  For "%n", "%d" or "%u", the <aux_fmt_num> causes thousands mode.  "%h?n" will 
+  pick a var exponent multiples of three unit, while "%h-3n" will display milli 
+  units or "%h6n" will display mega units.  The 'k' flag is always on for "%n".  
+  See ::/Demo/Print.HC.
+  
+For "%c" or "%C", the <aux_fmt_num> repeats the char that many times.
+
+<fmt_code>:
+
+  "%n" floating point in engineering notation, exponents being multiples of 
+  three.  If it has a <aux_fmt> code, it will display scientific units letters.
+  
+  "%S" Define() entry.
+  
+  "%C" ToUpper() character.
+  
+  "%h25c",'\n'; 25 new-lines.
+  
+  "%h*c",25,'\n'; 25 new-lines.
+  
+  "%F" text file by filename.
+  
+  "%$F" DolDoc file in memory.
+  
+  "%p" ptr. 
+  
+  "%,p" ptr with no offset. 
+  
+  "%P" link to ptr.
+  
+  "%,P" link to ptr with no offset.
+  
+  "%D" date.  Pass a CDate.
+  
+  "%T" time.  Pass a CDate.
+  
+  "%z" sub_entry of an enumerated list of text entries.  See LstSub().  Pass 
+  sub_entry_num first, list second.
+  
+  "%Z" DefineLstLoad() subentry.  Pass sub_entry_num first, define_name second.
+  
+  "%Q" convert "\" to "\\" and quote to backslash quote. (For use in creating 
+  strs in strs.)
+  
+  "%q" rev a "%Q".
+
+
+                                  Print Family
+
+MStrPrint(U8 *fmt,...) is like StrPrint(U8 *dst,U8 *fmt,...) but it returns a 
+MAllocated str.  It is vary handy because you don't have to worry about 
+overflow.
+
+CatPrint(U8 *_dst,U8 *fmt,...) concatenates a formated string.
+
+In(U8 *fmt,...) sends text to the current task's input buffer.
+InStr(U8 *fmt,...) sends text of an InFile to the keyboard stream of the current 
+TASK but can also do mouse cmds.
+
+XTalk(CTask *task,U8 *fmt,...) and text to another task's input buffer.
+XTalkStr(CTask *task,U8 *fmt,...) sends text of an InFile to the keyboard stream 
+of another TASK but can also do mouse cmds.
+
+DocPrint(CDoc *doc,U8 *fmt,...) sends text to a document.  You can buffer to a 
+Doc and save it, providing the functionality of fprintf.  See 
+::/Demo/Dsk/FPrintF.HC.
+
+Adam(U8 *fmt,...) sends text to the Adam Task to be compiled and run.
+AdamLog(U8 *fmt,...) and AdamErr(U8 *fmt,...) send text to the Adam Task to be 
+displayed.
+
+StreamPrint(U8 *fmt,...) sends text to the stream of code being compiled and 
+must reside in a #exe{} blk.
+
+GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...) and GrVPrint() plots text in graphics 
+mode.
+
+TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...) plots to gr.text_base.
+
+ExePrint(U8 *fmt,...) compiles and execute a string.  Note: It returns the res 
+of the last executed expression.
+
+Once(U8 *fmt,...) Writes User code to Registry to be executed next boot.
+
+AOnce(U8 *fmt,...) Writes Adam code to Registry to be executed next boot.
+
+InPrint(I64 mS,U8 *fmt,...) PutChars()s one at a time with a delay.
+
+RawPrint(I64 mS,U8 *fmt,...) sends direct to scrn memory, bypassing window 
+manager.
+
+User(U8 *fmt,...) Spawns a user and execute a string on start-up.
+
+PopUpPrint(U8 *fmt,...) compiles and execute a string in a pop-up win.  Note: It 
+returns the res of the last executed expression.
+PopUpViewPrint(U8 *fmt,...) creates a pop-up window and views text.
+
+Note: Use Print("%s",src) if you need an unmodified string.
+
+ diff --git a/public/Wb/Home/Doc/Profiler.DD.HTML b/public/Wb/Home/Doc/Profiler.DD.HTML new file mode 100755 index 0000000..affc808 --- /dev/null +++ b/public/Wb/Home/Doc/Profiler.DD.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+The profiler records where the CPU was executing when the 1000Hz timer interrupt 
+occured, so you can learn where time is spent.
+
+Use the Prof() depth argument to record a hit in the N routines which called the 
+current routine, as well.
+
+When done collecting statistics, use ProfRep() for a report.  You might need a 
+DocMax() to expand the command line window buffer to fit it all.
+
+Study the code.  The profiler is very simple.  You might want to enhance it or 
+modify it to debug something in particular.
+
+ diff --git a/public/Wb/Home/Doc/Que.DD.HTML b/public/Wb/Home/Doc/Que.DD.HTML new file mode 100755 index 0000000..1b3e289 --- /dev/null +++ b/public/Wb/Home/Doc/Que.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+A Queue is a bunch of MAlloc()ed chunks of mem linked together in a circle with 
+one ptr to the next value and another ptr to the last value.  These ptrs must be 
+stored in the first locations in the structure.
+
+ diff --git a/public/Wb/Home/Doc/Quirks.DD.HTML b/public/Wb/Home/Doc/Quirks.DD.HTML new file mode 100755 index 0000000..c292cd9 --- /dev/null +++ b/public/Wb/Home/Doc/Quirks.DD.HTML @@ -0,0 +1,101 @@ + + + + + + + + + + + +
+                                     Quirks
+
+* You run a risk of problems if you do file operations on the same files 
+simultaneously because there is no file sharing/locking mechanism.  Generally, 
+the last write wins.
+
+* When using FAT32, TempleOS does not generate unique short-entry names, the 
+ones with the ~s.  Not all FAT32 filenames are valid TempleOS names and it will 
+complain.  Do not access FAT32 drives not dedicated to TempleOS.  Disable them 
+with DrvEnable(OFF), or they will generate error messages.  FAT32 involves a 
+long and short name for each file.
+
+* The stk does not grow because virtual mem is not used.  I recommend allocating 
+large local vars from the heap.  You can change MEM_DFT_STK and recompile Kernel 
+or request more when doing a Spawn().
+
+* The syntax highlighting occassionally glitches.  The compiler doesn't.
+
+* Call DskChg() when you insert a new removable media.
+
+* Accessing CD/DVD's is flacky.  Try Drv() or DskChg() twice.
+
+* You can only extern something once.  There is a varient called _extern which 
+binds a HolyC definition to a asm sym.  This, too, can only be done once.
+
+* A terminal task has a CDoc document structure that remains active even when 
+you change Fs->draw_it.  To prevent links in the CDoc from being activated when 
+the user clicks in the window, do one of three things:
+  
+  A) DocBottom() followed by DocClear() to clear the CDoc so it has no active 
+  widgets.
+  
+  B) Disable window mgr bttn click checking with Fs->win_inhibit set to mask 
+  WIF_SELF_MS_L|WIF_FOCUS_TASK_MS_L_D|WIF_SELF_MS_R|WIF_FOCUS_TASK_MS_R_D.  This 
+  inhibits window mgr operations but still generates messages from bttn clicks.
+
+* switch/case stmts alloc a single jump table--do not use with wide, sparse 
+ranges of case values.
+
+* Don't do a goto out of a try{}.
+
+* A goto label name must not match a global scope object's name.  (It's not 
+worth slowing-down the compiler to handle this case.)
+
+* MemCpy() only goes fwd.
+
+* A Cd() cmd must be followed by two semicolons if a #include is after it.  This 
+is because the preprocessor processes the next token ahead.
+
+* The assembler's error msgs are often off by a line and undefines are cryptic.
+
+* The last semicolon on the cmd line is converted to a dbl semicolon because the 
+compiler looks ahead before doing a cmd.  This normally has no negative effect, 
+but when entering if stmts with else clauses it presents problems.
+
+* You can do a class fwd reference by using extern on the first declaration, but 
+you can only do ptr references to the class.
+
+* When doing something like
+    U0 Main()
+    {
+      U16 *_w=0xA0000;
+      *_w|=0x8000;
+    }
+  The |= will be coded as a U32 Bts inst resulting in a U32 access instead of a 
+  U16 access.  This affects some hardware operations.
+
+* Compiler warning or error message line numbers will be off if you have a block 
+of word-wrapped comments.  You might press <CTRL-t> before doing an editor 
+goto-line-number command.
+
+ diff --git a/public/Wb/Home/Doc/RedSea.DD.HTML b/public/Wb/Home/Doc/RedSea.DD.HTML new file mode 100755 index 0000000..03bd00d --- /dev/null +++ b/public/Wb/Home/Doc/RedSea.DD.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+                               RedSea File System
+
+The RedSea file system is a simple, 64-bit, file system which is similar to 
+FAT32, but with absolute block addresses instead of clus, fixed-sized 64-byte 
+directory entries and no FAT table, just an allocation bitmap.  A clus is just 
+one 512 byte sector.  Files are stored in contiguous blocks and cannot grow in 
+size.
+
+#define CDIR_FILENAME_LEN       38 //Must include terminator zero
+
+The following bit field shows valid 8-Bit ASCII filename characters.
+
+U32 char_bmp_filename[8]=
+{0x0000000, 0x03FF73FB, 0xEFFFFFFF, 0x2FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 
+0xFFFFFFFF, 0xFFFFFFFF};
+
+public class CDirEntry //64-byte fixed-size
+{
+  U16 attr;     //See RS_ATTR_DIR.  I would like to change these.
+  U8 name[CDIR_FILENAME_LEN]; //See char_bmp_filename, FileNameChk
+  I64 clus; (blk) //One sector per clus.
+  I64 size;     //In bytes
+  CDate datetime; //See  DateTime, Implementation of DateTime
+};
+
+public class CRedSeaBoot //RedSea is type FAT32 in partition table to fool BIOS.
+{
+  U8 jump_and_nop[3];
+  U8 signature,reserved[4]; //MBR_PT_REDSEA=0x88. Distinguish from real FAT32.
+  I64 drv_offset;       //For CD/DVD image copy.
+  I64 sects;
+  I64 root_clus; (root_blk)
+  I64 bitmap_sects;
+  I64 unique_id;
+  U8 code[462];
+  U16 signature2;       //0xAA55
+};
+
+See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC.
+
+Files with names ending in .Z are compressed.  See ::/Kernel/Compress.HC.
+
+To replace ISO9660, make hard-drive partition image of a measured size and copy 
+onto a CD/DVD starting at about sector 20, with EL TORITO booting.  512-byte 
+sectors will be placed on top of 2048-byte CD/DCD sectors, so there will be four 
+blocks per CD/DVD sector.
+
+RedSea file system has no bad block table and no redundant allocation table.
+
+See Block Chain for RedSea allocation bitmap discussion.
+
+See Reliability for RedSea reliability discussion.
+
+ diff --git a/public/Wb/Home/Doc/Reliability.DD.HTML b/public/Wb/Home/Doc/Reliability.DD.HTML new file mode 100755 index 0000000..01c7ed7 --- /dev/null +++ b/public/Wb/Home/Doc/Reliability.DD.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+                               RedSea Reliability
+
+TempleOS is like the 1040EZ tax form compared to the full 1040 form.  Obviously, 
+it is simpler.  If you allow mission creep, pretty soon the 1040EZ looks just 
+like the 1040 and the messed-up 1040EZ has no purpose.
+
+The Commodore 64 had a file system that was simple enough for peers in my 
+generation to enjoy the thrill of knowing exactly what is going on at the 
+hardware level and writing fun projects to access it.
+
+My primary design criteria is simplicity.  If it is simple enough for only 
+100,000 people to learn, lets try to make it simpler so that 1 million can learn 
+it.
+
+Obviously, we don't do bad block tables, or redundant FATs.
+
+We use the simplest possible technique, a contiguous-file-only allocation 
+bitmap, not Block Chains or FAT tables.
+
+You can be a good toy or you can be a good professional tool, but not both.  
+TempleOS's file manager will start too slowly once a few thousand files exist 
+because the file manager makes a list of all files on start-up.
+
+Do not have more than a few thousand files or the file manager will not 
+function.
+
+You are encouraged to keep your entire drive limited to, maybe, 100 Meg of files 
+because you are suppoosed to operate as a kayak instead of a Titanic.  If you do 
+this, backing-up will be only a minute or so and you should do it at least once 
+a day. 
+
+Third party software should be run from ISO files or CD/DVDs directly, without 
+installing to hard drive.
+
+Multimedia graphics and sound is, basically, forbidden.  If you ignore this, all 
+hell will break loose because memory will fragment with large files and the 
+original vision of kayak hard-drive back-ups won't work.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+
+ diff --git a/public/Wb/Home/Doc/Requirements.DD.HTML b/public/Wb/Home/Doc/Requirements.DD.HTML new file mode 100755 index 0000000..2a8300c --- /dev/null +++ b/public/Wb/Home/Doc/Requirements.DD.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+                           Requirements for TempleOS
+
+User Skills Required
+* Knowledge of the C programming language.
+
+Supported Hardware
+* x86_64 PC compatible computer.  (Obviously, you need 64-bit hardware for a 
+64-bit operating system.)
+
+* 640x480 16 color VGA graphics.
+
+* Most keyboards and mice.
+
+* Minimum 512Meg RAM.
+
+* Internal PC Speakers.
+
+* CD/DVD-ROMs (not SCSI) but only RedSea file system.
+
+* ATA and SATA hard drives.
+
+Unsupported Hardware
+* No graphics acceleration.
+
+* No sound cards.
+
+* No networking.
+
+* No USB devices, except keyboard and mouse in legacy mode.  No, you can't use 
+flash memory cards.
+
+* No printers.
+
+ diff --git a/public/Wb/Home/Doc/Resource.DD.HTML b/public/Wb/Home/Doc/Resource.DD.HTML new file mode 100755 index 0000000..e3a9359 --- /dev/null +++ b/public/Wb/Home/Doc/Resource.DD.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+                          Graphic Sprite Resource Help
+
+A sprite is an ordered list of elements such as lines, rectangles, bitmaps and 
+color changes.  In a program's source code, you first make a sprite somewhere 
+outside a function.  Then, you insert a pointer to the sprite as an "*elems" arg 
+when calling Sprite() or Sprite3().  See Sprites.
+
+You can create a sprite macro on your PersonalMenu with a payload of HolyC 
+source code to execute when it ESC's back to the cmd line.  If you check 
+"Pop-Up", it will spawn a new task and run the payload.  A pop-up macro can be 
+placed in any document.
+
+ diff --git a/public/Wb/Home/Doc/ScopingLinkage.DD.HTML b/public/Wb/Home/Doc/ScopingLinkage.DD.HTML new file mode 100755 index 0000000..8102d8a --- /dev/null +++ b/public/Wb/Home/Doc/ScopingLinkage.DD.HTML @@ -0,0 +1,178 @@ + + + + + + + + + + + +
+                              Scoping and Linkage
+
+JIT Compile Mode makes use of the current task's hash sym table and its parent 
+tasks' tables.  It fetches syms from parent tasks' tables if not found locally 
+in the current task's table and it places new syms in the current task's table.  
+Conceptually, syms are at the scope of environment vars in other operating 
+systems.
+
+When a sym is placed into a table, older syms with ident names will be 
+overshadowed if they exist.  Duplicates are not allowed in many cases, 
+especially in asm blks.  Dupicates are allowed, by design in other cases, so 
+that you can repeatedly #include the same file from the cmd line while 
+developing it.  Or, so you can repeatedly declare a function with a standard 
+name, like DrawIt().  This case might occur when the Adam Task is starting-up 
+loading-in many little utilities.
+
+extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym of the same 
+name if it exists in the sym table (just in just-in-time code).  It also can be 
+used to generate a fwd reference.
+
+import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym of the same name 
+imported from the task's sym table at Load() time.  If no sym exists to bind to 
+at Load() time, the code using this sym will be left incomplete until the sym is 
+defined.
+
+
+_extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym, of a differe
+nt name.  It must exists in the sym table.  Basically, this binds C to asm.
+
+_import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym, of a different name 
+imported from the task's sym table at Load() time.  If no sym exists to bind to 
+at Load() time, the code using this sym will be left incomplete until the sym is 
+defined.  Basically, this binds C to asm from elsewhere.
+
+
+Ahead of Time Compilation
+                    GlobalScope/FunctionScope
+                    | CodeHeap/DataHeap/Stack/Register
+                    | | TaskHashEntry:ExportSysSym/Define/Function/Class
+                    | | | UsageScope: Module/AsmLocal/AsmBlk/TaskAndChildren/Function
+                    | | | |UsageScope: Glbl/AsmLocal/Remainder/glblThisBlkAndRemainder
+                    | | | || StaticVarInit/DynamicVarInitAllowed/NoInitAllowed
+                    | | | || | Are dups allowed within the namespace? A dup overshadows the original.
+                    | | | || | DupsAllowed/NoDups/NoDupsButPad/WarningUnlessClosedOut
+
+asm export label::  G C S MG   N
+asm        label:   G C   MG   N
+asm local  @@label: G C   AL   N
+asm IMPORT label;   G C   MR   N
+asm export label::  F C S BG   N
+asm        label:   F C   BG   N
+asm local  @@label: F C   AL   N
+asm IMPORT label;   F C   BR   N
+C   goto   label:   F C   FG   N
+
+           #define  x     MR   D
+           function G C S MR   D
+           var      F R   FR   N
+           var      F S   FR   N
+static     var      F C   FR D N
+           var      G C S MR D D
+           var      G D   MR N D
+           class    G     MR   D
+class      member   G     MR   P
+extern     class    G     MR   D
+extern     function G C   MR   W
+import     function G C   MR   D
+import     var      G C   MR   D
+_extern    function G C   MR   D
+_extern    var      G C   MR   D
+_import    function G C   MR   D
+_import    var      G C   MR   D
+
+
+Just in Time Compilation
+                    GlobalScope/FunctionScope
+                    | CodeHeap/DataHeap/Stack/Register
+                    | | TaskHashEntry:ExportSysSym/Define/Function/Class
+                    | | | UsageScope: Module/AsmLocal/AsmBlk/TaskAndChildren/Function
+                    | | | |UsageScope: Glbl/AsmLocal/Remainder/glblThisBlkAndRemainder
+                    | | | || StaticVarInit/DynamicVarInitAllowed/NoInitAllowed
+                    | | | || | Are dups allowed within the namespace? A dup overshadows the original.
+                    | | | || | DupsAllowed/NoDups/NoDupsButPad/WarningUnlessClosedOut
+
+asm export label::  G C S Tg   N
+asm        label:   G C   BG   N
+asm local  @@label: G C   AL   N
+asm IMPORT label;   G C   TR   N
+asm export label::  F C   BG   N
+asm        label:   F C   BG   N
+asm local  @@label: F C   AL   N
+asm IMPORT label;   F C   BR   N
+C   goto   label:   F C   FG   N
+
+           #define  x   D TR   D
+           function G C F TR   D
+           var      F R   FR   N
+           var      F S   FR   N
+static     var      F C   FR D N
+           var      G C G TR D D
+           var      G D G TR S D
+           class    G   C TR   D
+class      member   G     TR   P
+extern     class    G   C TR   D
+extern     function G C F TR   W
+extern     var      G C G TR   D
+extern     var      G D G TR   D
+_extern    function G C F TR   D
+_extern    var      G C G TR   D
+
+
+* Goto labels must not have the same name as global scope objects.  GoTo's are 
+rare and I don't want to slow the compiler and add code to fix this.  You will 
+get errors if a collision happens, so it's not very dangerous, but the error 
+message is baffling.
+
+* The member names pad and reserved are special because multiple instances with 
+the same name are allowed in a class.
+
+* Use reg or noreg in front of local var names to override automatic reg var 
+allocation.  You can, optionally, specify a reg after the reg keyword.
+ 
+* Local non-reg function vars can be accessed in asm blks with &i[RBP] for 
+example.
+
+* Glbl vars and functions can be accessed in asm with and & as in
+        MOV     RAX,I64 [&glbl_var]
+        CALL    I32 &Fun
+        CALL    I32 &SYS_SYM
+
+* In JIT asm code, &SYS_SYM and &Fun don't need IMPORT.
+
+* All offspring tasks of a task inherit syms.
+
+* The sizeof() and HolyC structure members can be used in asm blks.
+
+* Using &i in HolyC or i.u8[2] on a local var, i, will force it to noreg.
+
+* Using try/catch in a function will force all local vars to noreg.
+
+* An unused gap on the stk is left for reg vars.
+
+* Note: static function vars do not go on the data heap, no matter the setting 
+of the OPTf_GLBLS_ON_DATA_HEAP.  They may in the future.
+
+* OPTf_EXTERNS_TO_IMPORTS will treat _extern as _import and extern as import.  
+This allows a header to be used either as a JIT compiled or AOT compiled header.
+
+ diff --git a/public/Wb/Home/Doc/Snd.DD.HTML b/public/Wb/Home/Doc/Snd.DD.HTML new file mode 100755 index 0000000..9c6f366 --- /dev/null +++ b/public/Wb/Home/Doc/Snd.DD.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+Sound is generated with I8 vals called ona's, which are 88 piano key nums, with 
+0 as a rest.  See Note2Ona() and Ona2Freq().  God does not want death screams, 
+perhaps, because God has PTSD or soldiers have PTSD.  (Imagine wounded on 
+battlefields.)  Ona's will allow elegant wave files for export and will allow 
+the creation of simple hardware over the next centuries.
+
+ diff --git a/public/Wb/Home/Doc/Sprite.DD.HTML b/public/Wb/Home/Doc/Sprite.DD.HTML new file mode 100755 index 0000000..5a41f16 --- /dev/null +++ b/public/Wb/Home/Doc/Sprite.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+A CSprite is an ordered list of these elements, created with <CTRL-r>.  
+Normally, they are packed together in a list and the address of the first is 
+passed to routines.
+
+See ::/Demo/Graphics/SpritePlot.HC, ::/Demo/Graphics/SpritePlot3D.HC, 
+::/Demo/Graphics/SpritePut.HC, ::/Demo/Graphics/SpriteRaw.HC and SpriteMeshEd().
+
+Be aware that copying SP, IB, or IS entries with the clip results in duplicate 
+entries with different nums.  You can manually remove dups by editing with <CTRL
+-t> and setting to the original num.
+
+See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+
+ diff --git a/public/Wb/Home/Doc/SpriteBitMap.DD.HTML b/public/Wb/Home/Doc/SpriteBitMap.DD.HTML new file mode 100755 index 0000000..0094f37 --- /dev/null +++ b/public/Wb/Home/Doc/SpriteBitMap.DD.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+                            Sprite BitMap Menu Help
+
+BitMaps have a background color.  If you delete to the clip, what's left will be 
+background colored.
+
+While drawing, you can usually press 'c' to eye-dropper the color under the 
+mouse.  Press 't' for transparent.
+
+ diff --git a/public/Wb/Home/Doc/SpriteEd.DD.HTML b/public/Wb/Home/Doc/SpriteEd.DD.HTML new file mode 100755 index 0000000..06b8503 --- /dev/null +++ b/public/Wb/Home/Doc/SpriteEd.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+                             Sprite Edit Menu Help
+
+Order of elements matters.  They are executed in the order they appear in the 
+side-bar.  You can sel or unsel elements graphically, or with text in the 
+sidebar.  Then, cut, copy, paste, shift or transform them.
+
+You can set the current insert point element by clicking the element in the 
+side-bar and making it RED.
+
+Insert Shift Suborigin is an element which shifts subsequent elements.  Perhaps, 
+you inserted a sprite's elements from the clip and want to shift it around?  
+This command is also useful if you call SpriteInterpolate() in programs.
+
+ diff --git a/public/Wb/Home/Doc/SpriteEdText.DD.HTML b/public/Wb/Home/Doc/SpriteEdText.DD.HTML new file mode 100755 index 0000000..f60924d --- /dev/null +++ b/public/Wb/Home/Doc/SpriteEdText.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+                            Sprite Edit as Text Help
+
+See the format for CSprites.
+
+ diff --git a/public/Wb/Home/Doc/SpriteMain.DD.HTML b/public/Wb/Home/Doc/SpriteMain.DD.HTML new file mode 100755 index 0000000..2ac1064 --- /dev/null +++ b/public/Wb/Home/Doc/SpriteMain.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+                             Sprite Main Menu Help
+
+Order of elements matters.  They are executed in the order they appear in the 
+side-bar.  You can set the insert point for new elements by click the element in 
+the side-bar and making it RED.
+
+After you create a 3D Mesh, you can edit it by seling it in the side-bar so it 
+is colored RED.  Then, click EDIT-3D-MESH.  A shiftable 3D mesh has a 2D offset 
+to position the origin.  You can convert between shiftable and non-shiftable by 
+editing it with the other command.
+
+You can convert all elements to a BitMap if END is RED in the side-bar and you 
+CONVERT-TO-BITMAP.  Later, you can edit that bitmap by seling it in the side bar 
+so it is colored RED and clicking EDIT-BITMAP.
+
+If you have a 3D icon, you might want to place a background-colored rectangle 
+under the 3D icon, so it hovers above.  Use TRANSFORM-OFF and TRANSFORM-ON.  You 
+will also need to set the Z offset of the icon.  Go to the Edit menu and sel 
+EDIT-AS-TEXT and change the third INT to Z offset.  Good luck.
+
+While inserting vector elements, you can usually press 'c' to eye-dropper the 
+color under the mouse.  Press 't' for transparent.
+
+ diff --git a/public/Wb/Home/Doc/SpriteSideBar.DD.HTML b/public/Wb/Home/Doc/SpriteSideBar.DD.HTML new file mode 100755 index 0000000..8b0278d --- /dev/null +++ b/public/Wb/Home/Doc/SpriteSideBar.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+                              Sprite SideBar Help
+
+You can cut and paste elements in this side-bar to reorder, delete or 
+duplicating them.  Click an element in the side-bar after you make changes to 
+cause the changes to take-effect.
+
+You can click on an element to make it the insert point for new elements.
+
+The RED element is the current insert point for new elements.
+ diff --git a/public/Wb/Home/Doc/StandBy.DD.HTML b/public/Wb/Home/Doc/StandBy.DD.HTML new file mode 100755 index 0000000..24a4b10 --- /dev/null +++ b/public/Wb/Home/Doc/StandBy.DD.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+                           AutoComplete is in StandBy
+
+                            System Keys Quick Guide
+                               (Works Everywhere)
+  <SPACE>   Left-Click  
+  <ENTER>   Right-Click  
+   <F1>     Help
+ <CTRL-m>   Personal Menu
+   <ESC>    Save  & Exit
+<SHIFT-ESC> Abort & Exit
+ <WINDOWS>  Pull-Down Menu
+
+                                    Tongues
+                               (Works Everywhere)
+   <F7>     God Word
+<SHIFT-F7>  God Passage
+   <F6>     God Song
+<SHIFT-F6>  God Doodle
+ diff --git a/public/Wb/Home/Doc/Start.DD.HTML b/public/Wb/Home/Doc/Start.DD.HTML new file mode 100755 index 0000000..5079921 --- /dev/null +++ b/public/Wb/Home/Doc/Start.DD.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+                                 TempleOS V5.03
+
+                         Public Domain Operating System
+
+Help & Index, Quick Start: Cmd line
+
+ diff --git a/public/Wb/Home/Doc/StdOutTask.DD.HTML b/public/Wb/Home/Doc/StdOutTask.DD.HTML new file mode 100755 index 0000000..f48f49e --- /dev/null +++ b/public/Wb/Home/Doc/StdOutTask.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+There is one CDoc for the task's border: Fs->border_doc.  There is a pair for 
+the task's client area: Fs->put_doc and Fs->display_doc.  You can, optionally, 
+do double buffering, otherwise Fs->put_doc is the same as Fs->display_doc.  See 
+::/Demo/Spy.HC.
+
+ diff --git a/public/Wb/Home/Doc/StdTempleOSPC.DD.HTML b/public/Wb/Home/Doc/StdTempleOSPC.DD.HTML new file mode 100755 index 0000000..16b5418 --- /dev/null +++ b/public/Wb/Home/Doc/StdTempleOSPC.DD.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+                            The Standard TempleOS PC
+
+All desktop PCs will have 8-channel OCTART super-simple high speed serial ports 
+to replace USB.  They are simpler because the driver is as simple as old school 
+RS232 Serial, they have no USB end-points and they have no USB human interface 
+device reports.  Computer mice will all have exactly two bttns and one wheel.  
+Game controllers will all be the standard deluxe game console controllers that 
+are popular today.  It will have 8 big TX and 8 big RX fifos that allow flow 
+control characters to jump the queue.  It should be locked-down to as few 
+options as possible, like 8-1-N only, although hardware may use a USB frame, not 
+an RS232, so stop bits might not be relevant.  Perhaps, just two baud rates -- 
+high and low speed are needed.  Low speed is good for slow microcontrollers and 
+allows longer cable length.  Keyboard, mouse and game controller can be low 
+speed.
+
+The USB creators banned generic devices, requiring a signed, certified driver 
+for everything!  That's no good.  We allow any device and will communicate, 
+generically, using a serial terminal program like the old school HyperTerminal, 
+XTalk or Telnet.
+
+A mouse packet interface should be similar to this:
+
+     TX:        <ENTER>
+     RX:        X:+3 Y:+0 Wheel:+0 LB:OFF RB:OFF
+     TX:        <ENTER>
+     RX:        X:+0 Y:-1 Wheel:+0 LB:ON  RB:OFF
+
+We aspire to be as simple as a Commodore 64 joystick driver:
+
+     VAL=PEEK(56321)
+     if VAL AND 1 THEN y=y-1
+     if VAL AND 2 THEN y=y+1
+     if VAL AND 4 THEN x=x-1
+     if VAL AND 8 THEN x=x+1
+
+The game controller will be more complicated, but much simpler than USB.  It 
+will use a standard text packet of some kind.
+
+On the other end, you might hook-up a thermostat microcontroller and interface 
+as a generic serial device.  The microcontroller in the thermostat would have 
+something simple, not a crazy overkill ethernet connection.
+
+     U8 b;
+     while (TRUE) {
+       b=ReadU8(2); //Read byte from high speed serial channel 2.
+     //(Has been configured for low baud because thermostat should be slow.)
+       if (b==CMD_UP)
+         temperature++;
+       else if (b==CMD_DOWN)
+         temperature--;
+     }
+
+Super-simple block devices will replace ATA/ATAPI hard drives and 
+CD/DVD/BlueRays.  Today, the industry is in flux with nonvolitile memory just 
+invented.  We want a super-simple block device interface for non-volitile memory 
+and for what is currently USB memory sticks, but only if they can be made 
+without bad blocks.  I don't think we want to deal with bad block memory, so 
+maybe we will not do NV-memory.  The standard TempleOS desktop will require a 
+hard disk.
+
+There will be minimal commands:  READ_BLOCK, WRITE_BLOCK, GET_CAPACITY, 
+GET_MODEL, GET_SERIAL_NUM, and EJECT.
+
+We want a CPU mode with virtual IO port addresses similar to how paging creates 
+virtual memory addresses.  We want a 65536 word look-up table that converts 
+virtual IO port numbers to physical IO port numbers.  There will be a standard 
+IO port configuration, so port numbers can be fixed in the code.  We want the 
+primary hard drive on one set of ports and the primary CD/DVD/Blu-ray on another 
+set of ports.  Choose a contiguous set of IO ports.
+
+Meanwhile, a complicated PCI interface can be designed along-side the TempleOS 
+interface for Windows and Linux.  It would almost be possible to carry-on 
+separate lives, however, the super-simple serial requires getting rid of USB 
+since super-simple serial is a new hardware standard.  People can add USB ports 
+with a PCI device card.
+
+God said He wants single-voice 8-bit signed MIDI-like sample for the sound.  God 
+does not want death screams, perhaps, because God has PTSD or soldiers have 
+PTSD.  (Imagine wounded on battlefields.)
+
+The video will be a linear frame buffer 640x480 16 color with one-byte-per-pixel 
+even though it is only 16 color with is 4-bit.  Perhaps, we have a interrupt to 
+sync with the refresh.
+
+I am tmpted to help amateur hardware device designers by making the hardware 
+interface for the PC simple.  I have fond memories of 1993, when I made a 
+wire-wrapped ISA data acquisition card which plugged into my 486 and had some 
+analog-to-digital and digital-to-analog convertors.  I am not designing a bus.  
+Earlier, I said the super-simple high speed serial port replacement could be 
+USB-like in hardware as long as the software driver interface was simple like 
+old school RS232 serial ports.  Requiring a complicated hardware handshake 
+raises the bar, slightly, for the lowest level hardware designers.  Most people 
+will be connecting a microcontroller or something that already has a serial 
+communication design, but if it's not a problem, maybe we should keep it simple 
+at all stages.  It was nice putting an oscilloscope on my serial port wires.
+
+The original PC had general purpose digital IO through the parallel port.  That 
+was fun.  I have enough battles to fight, so I'll leave being a savior to 
+hobbiest hardware engineers to somebody else.
+
+Digital cameras will be super-simple high speed serial, but TempleOS is forever 
+limited to 16 colors and multimedia is banned because large files being loaded 
+into memory fragments memory, so cameras are somewhat unwelcome.  I have enough 
+problems without making the Brits anxious about autonomous gun turrets and 
+killer robots.  The reason I say cameras will be super-simple serial is because 
+we are replacing USB ports with super-simple serial.  PC's will have only 
+super-simple serial ports unless people buy a USB PCI expansion card.  So, the 
+digital cameras will be super-simple serial.
+
+
+                                  Version 1.0
+
+We will make a spec for a $8,000, perfectly standardized, cryogenically-cooled, 
+monster desktop PC.  It will have 16 cores, integrated 4K graphics, and, 
+hopefully, 6 Ghz continuous operation.  Perhaps, 64 Gig of RAM will be standard? 
+God said to help to poor buy them.  It is pointless to have a high powered 
+machine if other people have wimpy machines and cannot run programs you write.  
+Therefore, everybody in the developed world will buy a Standard TempleOS IBM PC 
+over the next ten years, so that will be a quantity of 400 million, perhaps.  
+God said to pay the US national debt with the revenue.  We will standardize 
+everything, not just the TempleOS related items.  The display will be 4K (and of 
+course 640x480 16 color) and no others.  Everybody gets just one monitor, unless 
+you buy special PCI cards.  Everybody gets two speakers, a headphone, a mic, a 
+webcam and touch scrn.  We make the audio one sample rate and one sample size, 
+but TempleOS still gets just a square wave.  (HD Audio is really screwed-up and 
+requires complicated artificial intelligence, just to route output to speakers.)
+
+The Standard Temple IBM PC will be a full-sized tower.  Perhaps, stain-glass 
+will decorate the case because God is sentimentally attached to stained-glass.  
+We should set the size at exactly 2.5 feet by 1.5 feet by 1.5 feet as in the 
+Exodus,25:10-10 for all time.  If there is extra room, make a storage shelf for 
+DVDs.  We do not want a race-to-the-bottom, shrinking the size.  Instead of 
+making it smaller, make it more powerful.  We want to remove all cost pressure 
+from making things small.  It must have a CD/DVD/Blu-ray drive.  The vision is 
+CD/DVDs used for a library of games, not installed on the hard-drive.  We need a 
+network connection, possibly implemented as a super-simple high speed serial 
+device.  What about standard monitor and speakers?  The C64's success was 
+partially due to wide spread, completely standard, hardware.  I think TempleOS 
+will not do bad block devices, so we need a hard drive, not just NV-memory or 
+SSD.
+
+TempleOS will have the priority over Windows or Linux on hardware decisions.  We 
+could make it heterogenious multicore.  I think we want 16 non-hyperthreaded 
+cores.  Core#0 is the only full-featured core needed.  The other cores will have 
+long mode, but not some of these: real mode, protected mode, ring-3, paging, 
+interrupts, in/out port instructions, SSE instructions,  MMX instructions.
+
+God said Intel should do a simulation of heat produced by gates and try 
+spreading-out the heat producing gate circuits on the chip.
+
+God said Linux's Wine should replace Windows.  We will install a standard 
+software set-up on all Standard Temple IBM PC's.
+
+
+                                     Usage
+
+TempleOS is primarily for user developers, like the Commodore 64 was.  I created 
+a total of 50 Meg of content over ten years, so you shouldn't need much room, 
+either.  The installed hard drive space should stay small because the resolution 
+is low, multimedia is banned, 3rd party libraries are banned, and applications 
+can be distributed with ISO files or DVDs.
+
+The ROM will have a command that copies the ROM onto the hard drive, creating 
+identical C and D partitions, so you can have fun modifying TempleOS.  You will 
+have confidence you can fix it easily if you break it.  It should be able to run 
+everything from just the ROM, too.  You will need to specify a /Home directory 
+that is not in the ROM, but on the hard drive. 
+
+The standard set-up will be a C primary drive and a D back-up drive.  Keep the 
+size on each hard drive under 512 Meg and periodically copy all of C to D, so 
+they stay mirrored.  The file manager and other programs read the entire 
+directory structures, so too many files causes problems (unbearably slow).  
+Third party software should be distributed as ISO files or DVDs, like 
+TextAdventure.ISO.  No 3rd party libraries are permitted because they circumvent 
+the intent of the 100,000 line of code limit which is keeping it cognatively 
+small enough to see the light at the end of the tunnel and easily master 
+everything.  Therefore, 3rd party ISO files must bring all required software 
+components with them, except what is found in the TempleOS ROM.
+
+Having all your 3rd party software on separate DVDs or ISO files and TempleOS 
+running from a ROM, keeps it delightfully simple so you have complete 
+understanding of what is going on.  You will have complete confidence and it 
+will be a joy to use.  3rd party applications can store saved data files into 
+your /Home hard drive directory.
+
+The Temple PC will stay unchanged for seven years at a time.  The Bible speaks 
+of a seven year release in Deuteronomy,15:1.  The Commodore stayed unchanged for 
+many years and people became intimately familiar with every aspect.
+
+
+
+I thought 2.5' x 1.5' x 1.5' was ridiculously big, but it looks like it is 
+reasonable for super-cooled refrigeration systems!
+
+
+                                  Version 2.0
+
+
+ +The Standard Temple IBM PC V2.0 will be released seven years after V1.0. Each +unit will have a full, uncut, silicon wafer. V2.0 will be sold, unchanged, for +seven more years, like a Commodore 64. + +* "Commodore 64" is a trademark owned by Polabe Holding NV. +* "Linux" is a trademark owned by Linus Torvalds. +* "Windows" is a trademark owned by MicroSoft Corp. +
+ diff --git a/public/Wb/Home/Doc/Strategy.DD.HTML b/public/Wb/Home/Doc/Strategy.DD.HTML new file mode 100755 index 0000000..d73c56f --- /dev/null +++ b/public/Wb/Home/Doc/Strategy.DD.HTML @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+                        Decisions Making TempleOS Simple
+
+Everybody is obsessed, Jedi mind-tricked, by the notion that when you scale-up, 
+it doesn't get bad, it gets worse.  They automatically think things are going to 
+get bigger.  Guess what happens when you scale down?  It doesn't get good, it 
+gets better!
+
+I limited it to 100,000 lines of code, forever!  I never need a linker or make 
+utility and I can use small labels.
+
+People mock Bill Gates for, "640K should be enough."  I say, "2Gig for code 
+should be enough."  The same people who mock Bill Gates are probably just like 
+the black woman who sued for a trillion dollars.
+
+My Dad worked on converting the Titan missile to the Gemini Mission rocket.  It 
+had to be "man-rated".  You can bet that everything got an order of magnitude 
+more complexity and documentation.  My vision is a souped-up C64, not a 1970's 
+mainframe; a kayak, not a Titanic.
+
+Linux is a semi-tractor -- you need professional drivers for 20 gears.  Linux 
+has file permissions.  Common people are hurt by file permissions.
+
+Windows is a car.
+
+TempleOS is a motorcycle -- if you lean-over too far, a motorcycle will crash.  
+Don't do that!  There are no side air bags on a motorcycle.  DOS and C64 had no 
+memory protections and ran in ring-0, with no security.  This saves an order of 
+magnitude complexity.
+
+Linux and Windows are general purpose operating systems.  They attempt to do any 
+task you want.  TempleOS cherry-picks tasks and is designed to do the same 
+things a C64 did.  This saves and order of magnitude complexity.  For example, 
+the RedSea file system allocates just contiguous files -- you load and save 
+whole files at once.  A benefit is this allows compression.  Also, TempleOS does 
+not do networking or multimedia.  In theory, memory will fragment with lots of 
+big files.  The system would fall to pieces with multimedia, but God said 
+640x480 16 color is a permanent covenant like circumcision.
+
+A three bttn mouse is like a leg you cannot put weight on.  TempleOS just does 
+hardware everybody has, with no divergent code bases for each machine's custom 
+hardware.  There is one graphics driver instead of 50 for different GPUs.  This 
+saves an order of magnitude complexity and makes for a delightful API, so 
+developer's code is not like a frayed rope end.
+
+
+
+* Everything runs in kernel, ring 0, mode.
+
+* One memory map for all tasks on all cores with virtual addresses set equ to 
+physical, just as though paging is not used.
+
+* One platform -- x86_64 PC's, no 32-bit support.
+
+* No security or cryptography.
+
+* No networking.
+
+* Least (greatest) common denominator hardware support.  Mostly, one driver for 
+each device class.  I can't be in the business of different drivers.  
+Compatibility is the greatest challenge for PC operating systems.  Disk code 
+does not use interrupts, avoiding compatibility risks.  PS/2 keyboard/mouse is 
+used instead of USB, also more compatible.
+
+* 640x480 16 colors.  Updates whole scrn at 30 fps, optimized for full scrn 
+games where InvalidRectangles are counter-productive.
+
+* One font, 8x8.  Text and graphic layers done in software with text normally on 
+an 8x8 grid.  It can run in Text mode if graphic initialization fails.
+
+* Compiler extends all values to 64-bit when fetched and does only 64-bit 
+computations intermediately.  Assembler has minimal 16-bit support, good enough 
+for compiling boot loaders.
+
+* No object files.  Use JIT.
+
+* Whole files are processed almost exclusively, allowing compression.
+
+* One language and compiler for command-line, scripts, songs, automations and 
+code.
+
+* One editor/word processor/browser for the command-line window, source code, 
+documentation browser, dialog forms.
+
+* No child windows.  One window per task.  Bttns are widgets, not child windows. 
+ There are child tasks, however.
+
+* No distinction between thread, process or task.
+
+* The Scheduler is for home systems.  It is not preemptiove.  Disk requests are 
+not broken-up, so sharing is bad.  It's wonderfully simple.
+
+* MultiCore is done master/slave, instead of SMP.  Core0 applications explicitly 
+assigns jobs.  Locks are present allowing multicore file, heap, and hardware 
+access, though.
+
+* Sound has single-voice 8-bit signed MIDI-like samples.
+
+* All tasks have a heap and a sym table.  Scope is that of environment vars in 
+other operating systems.  As text is typed at the command line or you run 
+programs by #includeing them, the syms go in the table.  If a sym is not found, 
+the parent task's table is checked.  The father of all tasks has the API syms 
+you'll need waiting in it's table.  No need to #include headers.
+
+* No need for namespaces -- scoping occurs automatically based on task symbol 
+table hierarchy with the Adam Task's symbol system-wide global.
+
+* Sometimes, I cut corners in the interest of keeping the code beautiful.
+
+ diff --git a/public/Wb/Home/Doc/Streams.DD.HTML b/public/Wb/Home/Doc/Streams.DD.HTML new file mode 100755 index 0000000..15310a0 --- /dev/null +++ b/public/Wb/Home/Doc/Streams.DD.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+There are no streams in the traditional sense.  The cmd line output gets sent to 
+the cursor location of a document being edited and by using cursor keys, text 
+can be injected all over the document.  Sprites can be injected and are not 
+serialized!  Furthermore, the input can come from triggering macro widgets.  See 
+Doc Overview and Doc Routines.
+
+If you had a remote term and sent key Scan Codes, the user would press <CTRL-m> 
+to access his Personal Menu to trigger his macros.  However, the local 
+~/PersonalMenu.DD might differ from the remote, causing loss of sync between 
+local and remote sessions.  Also, the window size of local and remote might 
+differ, so word-wrapped text would be different.  Injecting output text with 
+different windows sizes would cause remote and local documents to not be in 
+sync.
+
+See Char Overview and Char Routines.
+
+You can send characters into StdIn.  See In(), XTalk() and InFile.
+
+ diff --git a/public/Wb/Home/Doc/TOSZ.DD.HTML b/public/Wb/Home/Doc/TOSZ.DD.HTML new file mode 100755 index 0000000..03c6dcb --- /dev/null +++ b/public/Wb/Home/Doc/TOSZ.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+                               Linux TOSZ Utility
+
+
+TOSZ [-ascii] filename
+
+Will uncompress a single file from within Linux.  The -ascii flag will convert 
+the irregular TempleOS ASCII 5 and ASCII 31 characters to spaces.  (ASCII 5 is 
+used to mark the cursor pos and ASCII 31 is used for shifted space characters 
+and will cause problems unless you convert them.)
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Doc/TextBase.DD.HTML b/public/Wb/Home/Doc/TextBase.DD.HTML new file mode 100755 index 0000000..818c7d7 --- /dev/null +++ b/public/Wb/Home/Doc/TextBase.DD.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+gr.text_base must be updated 30fps in your Fs->draw_it() callback.  You probably 
+want GrPrint() or just Print().  The DolDoc code takes care of plotting text to 
+gr.text_base.
+
+Bits 0-7        8-Bit ASCII Scrn Code
+Bits 8-11       Foreground color
+Bits 12-15      Background color
+Bits 16-20      Signed X pos shift val
+Bits 21-25      Signed Y pos shift val
+Bit  28         Blink
+Bit  29         Inverted (Swap foreground and background)
+Bit  30         Sel (XOR colors with FF)
+Bit  31         Underline
+
+GrUpdateTaskWin() calls DocUpdateTaskDocs() which calls DocRecalc() where the 
+document text is plotted into gr.text_base.  Then, GrUpdateTextBG() and 
+GrUpdateTextFG() render the gr.text_base onto gr.dc2, a raw graphic bitmap.
+
+See ::/Demo/Games/Maze.HC.
+
+ diff --git a/public/Wb/Home/Doc/TimeCycles.DD.HTML b/public/Wb/Home/Doc/TimeCycles.DD.HTML new file mode 100755 index 0000000..49fcea7 --- /dev/null +++ b/public/Wb/Home/Doc/TimeCycles.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Intel/AMD have an inst that returns the num of CPU cycles since boot.  This is 
+not a steady, calibrated real time value.  TempleOS measures it and you can 
+convert with cnts.time_stamp_freq, a value continuously calibrated from other 
+cnts.
+ diff --git a/public/Wb/Home/Doc/TimeDate.DD.HTML b/public/Wb/Home/Doc/TimeDate.DD.HTML new file mode 100755 index 0000000..ef1860e --- /dev/null +++ b/public/Wb/Home/Doc/TimeDate.DD.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+TempleOS uses a 64-bit value, CDate, for date/time.  The upper 32-bits are the 
+days since Christ.  The lower 32-bits store time of day divided by 4 billion 
+which works out to 49710ths of a second.  You can subtract two CDate's to get a 
+time span.
+
+Use CDATE_FREQ to convert.
+
+ diff --git a/public/Wb/Home/Doc/TimeHPET.DD.HTML b/public/Wb/Home/Doc/TimeHPET.DD.HTML new file mode 100755 index 0000000..6a20ce3 --- /dev/null +++ b/public/Wb/Home/Doc/TimeHPET.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+The HPET, high precision event timer, is read with HPET() and has a frequency of 
+cnts.HPET_freq.  A typical freq value is 14.3 Mhz  It might not be available on 
+all systems.
+
+ diff --git a/public/Wb/Home/Doc/TimeJiffy.DD.HTML b/public/Wb/Home/Doc/TimeJiffy.DD.HTML new file mode 100755 index 0000000..02053c9 --- /dev/null +++ b/public/Wb/Home/Doc/TimeJiffy.DD.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+One jiffy is one time slice.  cnts.jiffies returns time slices since boot.
+
+SysTimerRead reads the timer ticks since boot.  It's not as fast as GetTSC.
+
+Use JIFFY_FREQ to convert cnts.jiffies.
+
+Use SYS_TIMER_FREQ to convert SysTimerRead.
+
+ diff --git a/public/Wb/Home/Doc/Tips.DD.HTML b/public/Wb/Home/Doc/Tips.DD.HTML new file mode 100755 index 0000000..2537b90 --- /dev/null +++ b/public/Wb/Home/Doc/Tips.DD.HTML @@ -0,0 +1,280 @@ + + + + + + + + + + + +
+                                      Tips
+
+* Turn-off or reboot (<CTRL-ALT-DEL>) at any time, except during disk writes.  
+Writes are not cached. 
+
+* Use Seed() and the cmd line to switch Rand() to non-timer mode and replay 
+games you like.
+
+* 64-bit values are most efficient for the compiler.
+
+* See Key Map for a list of defined keys.  Define your own keys in MyPutKey().  
+See Keyboard Devices.
+
+* <ALT-m> maximizes a window.  <ALT-SHIFT-w> closes AutoComplete.  <ALT-w> 
+brings back AutoComplete.  <ALT-v> vertically tiles windows.  <ALT-h> 
+horizontally tiles windows.  The ALT keys are defined in ~/HomeKeyPlugIns.HC.  
+You can customize them.
+
+* If you make changes to TempleOS files in your /Home directory, generally you 
+reboot to make them take effect.  (You don't compile anything.)  You should have 
+two TempleOS partitions on your hard drive because a syntax error in a start-up 
+file will make the partition unbootable.  Boot to the second partition or boot 
+to a standard TempleOS CD/DVD and use Mount() to mount your hard drive.
+
+* I copy my files to a mirrored ident partition, periodically with CopyTree() 
+commands in scripts.  I do merge commands with a menu entry like this:
+Merge(\"C:/*\",\"D:/*\",\"+r+d\"); to check my changes.
+
+* <CTRL-m> at the cmd line to access your PersonalMenu.  Place macros there with 
+<CTRL-l>, or icon-like sprites with <CTRL-r>.  Use the Pop-Up option on macros 
+to Spawn() a task to run a file.  It dies when it is finished.  This returns mem 
+to the system.  Be sure to press <CTRL-s> to save your macro/menu area after 
+making changes.
+
+* You can use ans in cmd line expressions.  It holds the res the last cmd line 
+operation.  You can use the cmd prompt as a calculator by just entering 
+expressions like 1+2*3;.  F64 ress can be accessed with ansf.
+
+* Use the PullDown menu at the top of the scrn to learn commands, or for finding 
+the keyboard controls to games.
+
+* You can adjust the mouse movement rate by setting global vars in your start-up 
+file.  See mouse scale.
+
+* You can set your local time zone by setting the local_time_offset global var 
+in a start-up file.  It's units are CDATE_FREQ.  See local time.
+
+* <CTRL-SHIFT-L> in the editor to reindent a HolyC function or renumber an asm 
+routine's local labels.
+
+* You can use filter_lines in the editor text search form (<CTRL-f>) to 
+temporarily display just lines near each match.  A value of filter lines set to 
+5 will display lines within 5 lines of matches.  Then, you can do another find 
+to a different string and achieve a AND search.  When finished, press <ESC>.
+ 
+* You can recompile and reinstall the kernel with BootHDIns().  You'll probably 
+want to make a function for recompiling that uses the In() function to answer 
+the cfg questions.  See my technique Cfg Strs, Update Funs.
+
+* Scale2Mem(min,max,limit=2*1024*1024*1024) can be used for cfg questions when 
+recompiling.  The BootHDIns() cfg prompts accept expressions, not just numbers.  
+The dft disk cache is Scale2Mem(0x80000,0x8000000).
+
+* You can permanently disable AutoComplete commenting-out ACInit() in 
+~/HomeSys.HC.
+
+* Boolean expressions not in if stmts don't have short circuit logic and are 
+compiled inefficiently.
+
+* You can use progress1-progress4 in your programs for whatever you like.  
+They're just global vars that are shown on the wallpaper.  The original intent 
+was to indicate how far along operations were.  There's no coordination, so 
+different apps might interfere.  I use them most for debugging--just values 
+easily viewed.  See ::/Demo/Progress.HC.
+
+* Use DocMax() to adjust the size of the cmd line buf.  It counts CDoc entries, 
+not lines.
+
+* Many data structures have a user_data member.  Those are available for you to 
+store a data item, for convenience.  CTask, CDocEntry and CDirEntry have them.  
+You shouldn't encounter conflicts with TempleOS using them.
+
+* If, for some strange reason, you wanted to reduce mem usage, make a smaller 
+disk cache when you recompile the kernel; disabling AutoComplete; Specify 
+smaller stk sizes when doing Spawn(), chang MEM_DFT_STK, and using DocMax() to 
+reduce the cmd line buffer size.
+
+* Filenames ending in ".Z" will be automatically compressed and uncompressed 
+when read or written.  The compression method is not supported by other 
+operating systems.  You can store files uncompressed by Move()ing them to a 
+filename not ending in ".Z".  See ::/Doc/TOSZ.DD if you want to uncompress while 
+in Linux.
+
+* Merge() can be used to see what's changed.  The +d flag will show differences 
+of files which have changed and allow you to merge code.  (The +r flag will 
+recurse.)
+
+* There is a utility LinkChk() which will check for broken links in 
+documentation.
+
+* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in 
+code.
+
+* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find unnecessary local var type 
+stmts.
+
+* Option(OPTf_ECHO,ON) can be placed in StartOS.HC to echo start-up scripts.
+
+* Use Plain() to edit a plain text file.  You'll need this if your file has $'s. 
+ Use the ToDolDoc() utility to convert plain text to DolDoc's by doubling $'s.
+
+* Use Silent() to disable scrn text output.
+
+* Grab-scroll any window at any time with {CTRL-LEFT-MOUSE-DRAG}.  Null 
+grab-scrolling with {CTRL-RIGHT-MOUSE}.
+
+* Use <CTRL-ALT-z> to zoom-in and <CTRL-ALT-SHIFT-Z> to zoom-out.  You can 
+scroll by moving to the edge of the window.  Set gr.continuous_scroll to TRUE if 
+you want. 
+
+* Use <CTRL-ALT-g> and <CTRL-ALT-SHIFT-G> to display a grid on the scrn.
+
+* Use <CTRL-ALT-a> to enter an extended ASCII char.
+
+* Use <CTRL-ALT-f> to toggle between Std Font and Cyrillic Font.
+
+* Use <CTRL-ALT-s> will capture the scrn as a sprite on the clip.  You can save 
+the cmd line doc as text with <CTRL-a>.
+
+* You can save a sprite as a .GR file in <CTRL-r> on the Sprite BitMap Menu.
+
+* You can eye-dropper colors in the <CTRL-r> sprite editor by pressing 'c'.  
+Press 't' for transparent.
+
+* There are handy functions--F(),R(),FD() and RD() which are defined in 
+~/HomeWrappers.HC.  You are encouraged to change them and add more.  They will 
+perform find-and-replace operations accross multiple files.  The +l flag is 
+particularly useful since it limits to whole labels.  The +lb and +la flags 
+limit to whole labels just before or after.  You are encouraged to add or modify 
+handy wrapper functions to make cmd line operations easier.
+
+* When using Find() while modifying code, work from the bottom-up so that line 
+numbers are correct.  If you work top-down, then inserting or deleting lines 
+causes the lower file links will be incorrect.
+
+* You can save files after making changes, anytime you are within the editor, 
+like when viewing help/macro files.  <CTRL-a> saves as, <CTRL-s> saves with the 
+same name in the scrolling title bar.  Hitting <ESC> will exit and save.  (<SHIF
+T-ESC> will abort).  You can save the cmd line window to a file, too, since 
+you're actually in the editor when you're at the cmd line.
+
+* When using <CTRL-l> to insert links in documents, you can usually leave the Ta
+g Text blank and it will be filled-in automatically based on other entries.
+
+* There is a feature of the precompiler that allows code to be executed in the 
+middle of compilation and data inserted into the compilation stream.  Click here 
+for an example: #exe {.
+
+* If you output to the cmd line and wish to allow users to scroll around and 
+view data, you can use View().
+
+* Use View() in Pop-up macros to linger until the user presses <ESC> or <SHIFT-E
+SC>.
+
+* You can access the word under the cursor at ac.cur_word.
+
+* You can reactivate AutoComplete after closing it by pressing <CTRL-Fun Key> or 
+<ALT-w> if you have it defined.
+
+* <CTRL-SHIFT-T> to toggle to/from plain text just the CDoc cmd under the 
+cursor.  See ::/Demo/DolDoc/TextDemo.HC.
+ 
+* If you toggle to plain text when you are working with graphics in a document, 
+you can add duplicate entries for sprites by entering a $SP...$ cmd with the 
+same num.
+
+* If you toggle to plain text when working with graphics, you can add a str to 
+the $SP...$ entry to keep track of it.  Try $SP,"<2>",BI=2$ where '2' is the 
+sprite num.
+
+* I use spaces-to-tab operations on all my src files to keep them small.  You 
+have to be careful, though, because spaces in strings will be converted.  I use 
+<SHIFT-SPACE> ' ' in such cases.  See S2T() for spaces-to-tabs.
+
+* You can edit an existing sprite by putting the cursor on it and pressing <CTRL
+-r>.
+
+* When editing a sprite, you can cut and paste the elements in the sidebar text 
+list window.
+
+* I recommend keeping CSprite in vect format until you are done creating them, 
+so you can edit the ctrl points.  Then, convert them to bitmaps, so the flood 
+fills work well.  If you are doing interpolation, however, they must be vect.
+
+* GrFloodFill() is slow.  GrRect() is fast.
+
+* You can customize the wallpaper.  See ::/Demo/Graphics/WallPaperFish.HC.
+
+* Your RAM disks will not be reformated when you reboot if the memory location 
+has not changed and it finds the disk intacted.
+
+* try{} catch{} in a function will cause all vars to be non-reg.
+
+* Using a sub-int array, i.u8[3], for example, will force a local var to 
+non-reg.
+
+* You can delete the ~/Registry.HC.Z file.  The policy is that deleting it will 
+restore defaults.  It is a text doc, if you want to edit it.  Be careful of tree 
+indentations.
+
+* Study ::/Adam/Opt/Utils/MemRep.HC and WallPaper() to learn how the system 
+resources are put together.
+
+* The editor's sel-text mechanism allows for disjoint portions of sel text.  
+This is a feature, not a bug -- you can cut-and-paste disjoint text.
+
+* cnts.time_stamp_freq is continuously calibrated.  Be careful because 
+expressions might decrease.  Take a snap-shot, like this: timeout=GetTSC+
+cnts.time_stamp_freq x seconds; and compare against GetTSC().  I recommend just 
+using tS or cnts.jiffies.
+
+* Use HeapLog(), HeapLogAddrRep() and HeapLogSizeRep() to find leaks.  Don't be 
+confused by CDoc allocations.  Those are generated when text is written to the 
+cmd line buffer.
+
+* For advanced heap debugging, play with _CFG_HEAP_DBG.  You're on your own.
+
+* You can use Type() to display .GR files.
+
+* Use Man() to jump to short sym name src code.
+
+* Use Fix() to edit and fix the last compiler err.
+
+* You can use <CTRL-SHIFT-L> to do a check for compile errors.
+
+* You can use DocOpt() to optimize links. (Mostly just removes .Z)
+
+* ZipRep() can highlight src files with lots of redundancy.
+
+* With start/end, common trailing code is fast.  Common leading code is slow.
+
+* The first line of the Psalmody HolyC song files is a comment with a category 
+recognized by JukeBox().  The categories are "no nothing", "has words", "has 
+graphics", or "special".  The third character in the song comment is a digit 
+rating number, shown in JukeBox().  You can set the song rating in JukeBox() by 
+pressing 0-9.  You can press <DEL> to delete songs.
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Doc/Transform.DD.HTML b/public/Wb/Home/Doc/Transform.DD.HTML new file mode 100755 index 0000000..a030491 --- /dev/null +++ b/public/Wb/Home/Doc/Transform.DD.HTML @@ -0,0 +1,56 @@ + + + + + + + + + + + +
+CDC's have a 4x4 matrix for rotating, scaling, skewing and shifting in 3 
+dimensions.  To make the graphics routines use the transform, you must set the 
+DCF_TRANSFORMATION flag.
+
+The matrix consists of ints that have been scaled 32 bits (GR_SCALE).  See 
+::/Demo/Lectures/FixedPoint.HC to learn why.
+
+See Mat4x4IdentEqu(), Mat4x4IdentNew(), Mat4x4Equ() and Mat4x4New().  See 
+Mat4x4RotX(), Mat4x4RotY(), Mat4x4RotZ() and Mat4x4Scale() to rotate about axes 
+and scale.  Combine them with Mat4x4MulMat4x4Equ()/Mat4x4MulMat4x4New() and 
+assign them to the CDC.dc with DCMat4x4Set().  See ::/Demo/Graphics/Box.HC.
+
+You can rotate single points using Mat4x4MulXYZ().
+
+The 4th dimension allows a neat trick where you can place pos shifts 
+(translations), into the matrix and Mat4x4MulMat4x4Equ/Mat4x4MulMat4x4New them 
+to combine rotation/shift operations.  Normally, you can't combine pos shift 
+operations.  See Mat4x4TranslationEqu() and ::/Demo/Graphics/Transform.HC.
+
+Finally, CDC's have an x, y and z which is an additional shift (translation).
+
+The transformation is implemented as a callback on the CDC's transform() member. 
+ The default transform() callback is DCTransform().  See 
+::/Demo/Games/Talons.HC or ::/Demo/Games/CastleFrankenstein.HC to see how to 
+change the transform() callback for foreshortening.
+
+ diff --git a/public/Wb/Home/Doc/Welcome.DD.HTML b/public/Wb/Home/Doc/Welcome.DD.HTML new file mode 100755 index 0000000..404fb6d --- /dev/null +++ b/public/Wb/Home/Doc/Welcome.DD.HTML @@ -0,0 +1,278 @@ + + + + + + + + + + + +
+                              Welcome to TempleOS
+
+TempleOS is a x86_64, multi-cored, non-preemptive multi-tasking, ring-0-only, 
+single-address_mapped (identity-mapped), operating system for recreational 
+programming.  Paging is almost not used.
+
+The people whom can most benefit are:
+  * Professionals doing hobby projects
+  * Teenagers doing projects
+  * Non-professional, older-persons projects
+
+Simplicity is a goal to keep the line count down, so it's easy to tinker with.  
+As it turns-out, simplicity makes it faster in some ways, too.  It never 
+switches privilege levels, never changes address maps, tends to load whole 
+contiguous files and other, similar things which boost speed.  It's only 80,849 
+lines of code including the kernel, the 64-bit compiler, the graphics library 
+and all the tools.  More importantly, it's designed to keep the user's line 
+count down -- you can do a Hello World application in one line of code and can 
+put graphics on the scrn with a three line program!
+
+It's a kayak, not a Titanic -- it will crash if you do something wrong.  You 
+quickly reboot, however.  DOS and the 8-bit home computers of the 80's worked 
+fine without memory protection and most computers in the world -- the embedded 
+ones -- operate without protection.  The resulting simplicity of no protections 
+is why TempleOS has value.  In facts, that's the point of TempleOS.  See the 
+TempleOS Charter.
+
+Conventional thinking is "failure is not an option" for general purpose 
+operating systems.  Since this OS is used in addition to Windows or Linux, 
+however, failure is an option -- just use Windows or Linux if you can't do 
+something.  I cherry-pick what it will and won't do, to make it maximally 
+beautiful.  The following applications more or less form a basis that spans the 
+range of use that TempleOS is intended for:
+
+/Demo/Games/BattleLines.HC
+/Demo/Games/BigGuns.HC
+/Demo/Games/BlackDiamond.HC
+/Demo/Games/BomberGolf.HC
+/Demo/Games/CastleFrankenstein.HC
+/Demo/Games/CharDemo.HC
+/Demo/Games/CircleTrace.HC
+/Demo/Games/Collision.HC
+/Demo/Games/Digits.HC
+/Demo/Games/DunGen.HC
+/Demo/Games/Talons.HC
+/Demo/Games/ElephantWalk.HC
+/Demo/Games/FlapBat.HC
+/Demo/Games/FlatTops.HC
+/Demo/Games/Halogen.HC
+/Demo/Games/MassSpring.HC
+/Demo/Games/Maze.HC
+/Demo/Games/RainDrops.HC
+/Demo/Games/RawHide.HC
+/Demo/Games/Rocket.HC
+/Demo/Games/RocketScience.HC
+/Demo/Games/Squirt.HC
+/Demo/Games/TheDead.HC
+/Demo/Games/TicTacToe.HC
+/Demo/Games/TreeCheckers.HC
+/Demo/Games/Varoom.HC
+/Demo/Games/Wenceslas.HC
+/Demo/Games/Whap.HC
+/Demo/Games/Zing.HC
+/Demo/Games/ZoneOut.HC
+/Apps/Psalmody/Examples/childish.HC
+/Apps/Psalmody/Examples/night.HC
+/Apps/Psalmody/Examples/prosper.HC
+
+Two things to know about TempleOS are that tasks have MAlloc/Free heap memory, 
+not applications, and tasks have compiler symbol tables that persist at a scope 
+like environment variables in other operating systems, and the symbols can 
+include functions.
+
+For other operating systems, I hated learning one language for command line 
+scripts and another for programming.  With TempleOS, the command line feeds 
+right into the HolyC compiler, line by line, and it places code into memory it 
+MAlloc()s.  The compiler is paused at the command line, waiting for input.  
+Naturally, you #include a program to load it into memory and, usually, start it.
+
+During the boot process, many files get compiled before you have access to the 
+command line.  (Don't worry, booting takes only two seconds.)  All the header 
+declarations for the operating system are compiled and are available for use in 
+your programs without needing to #include them.  Everything is truly compiled to 
+native x86_64 machine code, nothing is interpreted and there is no byte code.
+
+Statements at the global scope -- outside the scope of functions -- execute 
+immediately.  There is no main() function.  Instead, you give meaningful names 
+to what would be main() functions and you invoke them by calling them with a 
+statement in the global scope, usually at the bottom of your file.
+
+I started with C syntax, but didn't like the command line for a directory 
+listing looking like this:
+
+>Dir("*.*",FALSE);
+
+So, I added default args from C++ and it looked like this:
+
+>Dir();
+
+I didn't like that, so I made parentheses optional on calls with no args and it, 
+now, looks like this:
+
+>Dir;
+
+The syntax change created an ambiguity when specifying function addresses, like 
+for calling QSort().  To resolve it, I  made a '&' required in front of function 
+names when specifying an address of a function, which is better anyway.
+
+Once I was no longer using standard C/C++ syntax, I decided to change everything 
+I didn't like and call it HolyC.  Here are the new operator precedence rules.  
+It's Biblical!  See Luke,5:37.
+
+There are no object files in TempleOS and, normally, you don't make executable 
+files either, but you can.  That's known as Ahead-of-Time compilation.  Instead, 
+you Just in Time compile.
+
+Tasks have no priority and are never removed from the queue.  Instead, they 
+often poll whatever they are waiting on and swap-out.  (Swapping tasks takes 
+half a microsecond and does not involve disk activity or memory maps.)  See 
+Scheduler.  Polling keeps it simple.  It might be a problem if you had lots of 
+tasks busy, which rarely happens on a home computer.  The order of the tasks in 
+the queue determines front-to-back window order.
+
+The FAT32 filesystem is supported to makes exchanging files with a dual booted 
+other operating system easy and there is the simple, 64-bit TempleOS RedSea 
+filesystem.  The RedSea has allocation bitmap for clus and all files are stored 
+contiguously.  You can't grow files.
+
+TempleOS is geared toward reading and writing whole files.  Since whole files 
+are processed, compression is possible.  Filenames ending in ".Z" are 
+automatically compressed or uncompressed when stored and fetched.  TempleOS does 
+support direct block random access into files, however -- FBlkRead() and 
+FBlkWrite().
+
+If a file is not found, ".Z" is added or removed and a search is done, again.  
+There is no PATH, but parent directories are searched when a file is not found.  
+This feature is especially useful for default account files.
+
+The graphic resolution is poor, 640x480 16 color, but God said it was a covenant 
+like circumcision.  Also, that's all I feel comfortable with without GPU 
+acceleration supported.  A 1600x1200x24 bit scrn takes 37 times more memory, 
+implying 37 times the CPU power.  Also, a fixed size keeps it simple with 
+everybody machine having the same appearance.  Look on the bright-side -- you 
+won't spend as much time twiddling pixels for your game art and you'll have tons 
+of CPU power available, especially with multicore systems.
+
+TempleOS is for hobbyist programmers on single user (at a time) home computers, 
+not mainframes or servers.  The focus task is all-important so symmetrical 
+multiprocessing is almost pointless.  Why does it matter running two apps at the 
+same time twice as fast when you really want to run one faster?  You could say 
+TempleOS does master/slave multiprocessing.  The anticipated use for multicore 
+is primarily putting graphics on the scrn.  Hardware graphics acceleration is 
+not used, so this is possible.  See TempleOS MultiCore.
+
+There is no distinction between the terms task, process or thread.  All have a 
+task record, CTask, pointed to by the FS segment reg and are accessed with Fs-> 
+while Gs-> points to a CCPU for the current CPU core.  Each task can have just 
+one window, but a task can have children with windows.  (The segment regs are 
+just used as extra regs -- there is nothing segmented about TempleOS' memory.)  
+It is approximately the case that TempleOS is multi-threading, 
+single-processing.
+
+In TempleOS, Adam Task refers to the father of all tasks.  He's never supposed 
+to die.  Since tasks inherit the symbols of parents, system-wide stuff is 
+associated with Adam.  His heap is like kernel memory in other operating 
+systems.  Since Adam is immortal, it's safe to alloc objects, not tied to any 
+mortal task, from Adam's heap.  He stays in a server mode, taking requests, so 
+you can ask him to #include something, placing that code system-wide.  A funny 
+story is that originally I called it the root task and even had a /Root 
+directory :-)  Adam executes ::/StartOS.HC at boot time.
+
+For easy back-ups, place everything you author in your /Home directory and 
+subdirectories.  Then, use CopyTree().  That should make upgrading easy, too.  
+Customizable start-up scripts go in your /Home directory.  The default start-up 
+scripts are in the root directory.  Copy the start-up files you wish to 
+customize into /Home and modify them.  See Home Files.  You can make your own 
+distro that includes everything and is a bootable live CD with 
+::/Misc/DoDistro.HC.
+
+Typically, your usage pattern through the day will be repeatedly left or right 
+clicking on filenames in a cmd line Dir() listing.  You left-click files to edit 
+them and right-click to #include them.  To begin a project, type Ed("filename");
+, supplying a filename.  You can also run programs with <F5> when in the editor. 
+<ESC> to save and exit the file.  You'll need to do a new Dir() cmd, 
+periodically, so make a macro on your PersonalMenu.  Access your PersonalMenu by 
+pressing <CTRL-m>, cursoring until you are on top of it and pressing <SPACE>.
+
+<CTRL-t> toggles plain text mode, showing format commands, a little like viewing 
+html code.
+<CTRL-l> inserts a text widgets.
+<CTRL-r> inserts or edit a graphic sprite resource at cursor location.
+<CTRL-d> brings-up the file manager.  It's pretty crappy.  I find I don't need 
+it very often, believe it or not.
+<CTRL-b> toggles window border.
+
+<ALT-m> maximizes a window.
+<ALT-SHIFT-a> closes AutoComplete.
+<ALT-a> brings back AutoComplete.
+<ALT-v> vertically tiles windows.
+<ALT-h> horizontally tiles windows.
+The ALT keys are defined in ~/HomeKeyPlugIns.HC.  You can customize them.
+
+<CTRL-ALT-t> new terminal window.
+<CTRL-ALT-n> switches to the next window.
+<CTRL-ALT-x> kills a window.
+
+Find() is your best friend.  There's a wrapper function called F() in your ~/Hom
+eWrappers.HC.Z file.  Feel free to make wrapper functions for functions you use 
+often and customize the args.  By the way, Find() or R() can be used to replace 
+strings across multiple files.  You can access Find() using <CTRL-SHIFT-f>.
+
+As you browse code, use the AutoComplete window to look-up functions, etc.  <CTR
+L-SHIFT-F1> (or whatever number) to follow a sym to it's source.  You can browse 
+deeper and deeper.  You go back with <SHIFT-ESC>.
+
+Use the Help & Index or Demo Index to find-out what exists.  Press <F1> for help 
+or use the links on your menu (<CTRL-m>).  Also, look in the /Demo or /Apps 
+directories for inspiration.
+
+Software is distributed as RedSea ISO files.  Burn a CD/DVD, or set your CD/DVD 
+in QEMU, VMware or VirtualBox to the ISO file.  Then, access the 'T' drive.  Or, 
+Mount() the ISO.C file and access the 'M' drive in TempleOS.  It must be a 
+contiguous ISO.C file, so rename it under TempleOS to ISO.C.
+
+Ideally, do not install applications such as games onto your hard drive because 
+we wish to keep hard drive usage low, so the whole 'C' drive can be copied 
+quickly to 'D'.  Also, the FileMgr() <CTRL-d> starts too slowly when there are 
+lots of hard drive files, but that is how we want it.
+
+3rd party libraries are banned, since they circumvent the 100,000 line of code 
+limit in the TempleOS Charter.  All applications must only depend on the core 
+TempleOS files and whatever they bring along in the ISO.  This is similar to how 
+Commodore 64 applications only depended on the ROM.
+
+Create a RedSea ISO file with RedSeaISO().  Send an email to 
+tdavis@templeos.org if you want me to post a link to your TempleOS code in the 
+App Store.
+
+Take Tour
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Doc/WhyNotMore.DD.HTML b/public/Wb/Home/Doc/WhyNotMore.DD.HTML new file mode 100755 index 0000000..0121162 --- /dev/null +++ b/public/Wb/Home/Doc/WhyNotMore.DD.HTML @@ -0,0 +1,118 @@ + + + + + + + + + + + +
+                                 Why Not More?
+
+If a feature cannot be made to work correctly and consistently, professional 
+companies usually remove the feature.  Because PC hardware is so diverse, 
+getting things to work on all people's computers is really difficult.  For one 
+thing, you practically have to own all the different hardware to write drivers 
+for it.  If a company wanted to sell a PC operating system, they would offer a 
+warranty and, therefore, could not get away with amateur behavior.  TempleOS 
+absolutely requires 64-bit computers, so we leave behind much trouble, but 
+plenty remains.
+
+The PCI bus interface is what modern hardware uses.  Before PCI, life was simple 
+and devices used I/O ports.  After studying PCI Interrupts and attempting to do 
+a HDAudio driver, I came to realize that modern PCI devices require ten times 
+more code and I cannot even come close to making them work on everyone's machine 
+because with PCI devices there are several models to worry about, unlike with 
+the older ISA bus devices which can be done with one driver.
+
+Currently, I have no PCI drivers.  My drivers use I/O ports and operate in ISA 
+bus mode.  At this point, I only have one driver for each type of device and it 
+is delightfully simple that way.  I have one keyboard driver, one mouse driver, 
+one ATA hard drive driver, one ATAPI CD/DVD driver, one VGA 640x480 16 color 
+video driver and one PC Speaker driver.  I use the PIT and HPET timers and 
+PIC Interrupt Controller.  I use  IRQ0 for timer, IRQ1 for keyboard, and IRQ12 
+for mouse.  If IRQ12 is not firing, I am able to poll the mouse.
+
+In the CPU department, I have state of the art 64-bit long mode with multicore 
+support.  I use the APIC and start-up multicore operation.
+
+I have made an incredible accomplishment by getting it to work on practically 
+everyone's computer as long as it is 64-bit and they run inside VMware, QEMU or 
+VirtualBox.
+
+Adding a USB driver would be really ugly with UHCI, EHCI, OHCI, USB1, USB2, 
+USB3, ICH6, ICH7, ICH8, ICH9, ICH10, ICH11, ICH12, boot mode and regular mode 
+for keyboard/mouse and a diversity of HID reports.  It's hopeless.  I could 
+never offer anything but crappy, limited support and it would just add a ton of 
+crappy code that mostly didn't work.  What would I gain?  Nothing.  A keyboard 
+or mouse would not be improved.  Solid State USB drives would be really nice, 
+but it's not going to happen.
+
+The same story is basically true for GPUs, audio, networking and AHCI hard drive 
+drivers.  God said 640x480 16 color was a covenant like circumcision, so the 
+video will never change, even if a Standard PC was made.  If you attempt 
+multimedia, everything will break because memory will get fragmented with huge 
+multimedia files.  Some day, if super-simple high speed serial allows 
+networking, there will be no browser within the 100,000 line limit and, with 
+only 16 colors, the world wide web is not tolerable.  FTP and telnet might be 
+possible, in the far distant future, if they could fit within the 100,000 line 
+limit.  Currently, there are 80,849 lines of code.
+
+I don't stand a chance working on native hardware, anymore.  I could install and 
+run natively on hardware from about 2005-2010.  It requires BIOS's being nice 
+enough to write USB mode PS/2 legacy keyboard/mouse support.  As it turns-out, 
+sometimes the BIOS has PS/2 drivers but purposely disables them, just to be 
+mean.  The CIA and whole industry is trying to mess everything up, on purpose.  
+Perhaps, at a point of sale in a store, a thief could hack a credit card 
+machine.  Therefore, the BIOS companies actually want it difficult to make 
+drivers and purposely make it broken.
+
+The ATA/ATAPI hard drives often can be run with I/O ports if you can find them.  
+lspci -v on Linux or system information on Windows can help you locate the SATA 
+IO ports the hard drive and CD/DVD have.  They no longer are enabled by the 
+BIOS.  It's hopeless.  I'm stuck with very slow drive performance, but it works 
+for everybody.
+
+UEFI is pointless.  If I am forced to run in VMware, QEMU or VirtualBox, they 
+will always support non-UEFI mode.  Without working, native hard drive and 
+CD/DVD drivers, you can't get very far with UEFI on a native install, not to 
+mention SecureBoot.  UEFI is, first of all, redundant.  If non-UEFI works in a 
+virtual machine, supporting UEFI would only be redundant, ugly nasty code.  My 
+compiler does not create an ELF or PE format.  I would have to ruin the beauty 
+of my compiler, which would make me cry many tears.
+
+God talks.  It seems reasonable that I will get to make the rules for the whole 
+industry, in the future when God is announced publically to the World.
+
+I made ::/Doc/Demands.DD.
+
+When the PC was created, they wanted flexibility because they did not know the 
+future.  Now, the industry is mature and it is time to make a 100% standard PC 
+that everybody uses.  ::/Doc/StdTempleOSPC.DD
+
+
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Doc/Widget.DD.HTML b/public/Wb/Home/Doc/Widget.DD.HTML new file mode 100755 index 0000000..cd751ff --- /dev/null +++ b/public/Wb/Home/Doc/Widget.DD.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+                               DolDoc Widget Help
+
+DolDoc is a TempleOS document type.
+
+"Expression" a num or HolyC algebraic term with operators and HolyC syms can be 
+entered.
+"Macro" Most entries can behave like macro entries if you assign them macro 
+strs.
+"InStr" Like a macro except it is an InFile.  You can't have both an in_str and 
+macro text defined.  
+
+Tag Text is the text that will be displayed for the item.  For links, you can 
+leave it blank and the details of the link will be shown.
+Hide means display nothing, making an entry invis.
+
+Left X relative to the left margin.
+Center X relative to the horizontal center of the window.
+Right X relative to the right margin.
+Top Y relative to the top of the window.
+Center Y relative to the vertical center of the window.
+Bottom Y relative to the bottom of the window.
+
+Blink make the text blink.
+Invert make the text inverted.
+Underline make the text underlined. 
+
+Scroll X Length Expression if a value is entered, the text will scroll in an 
+area of this width.
+Y Offset Expression if a value is entered, the text will be shifted vertically 
+by this many pixs, so you can make superscripts or subscripts.
+X Offset Expression if a value is entered, the text will be shifted horizontally 
+by this many pixs.
+
+Tree The item will behave like a tree widget, with this as the root.
+Collapsed The tree or hidden widget will begin collapsed.
+Define Str will substitute a #define or DefineLoad() string for the tag.
+
+Quote Make the res suitable for including in a program, in quotes, especially fo
+rmat entries in class definitions.
+
+X Expression For cursor movements, the horizontal value.
+Y Expression For cursor movements, the vertical value.
+
+PopUp For macro's, run the macro in a PopUp window.  Do this when making a macro 
+to run a program, so it doesn't tie-up memory.
+
+Escape For macro's, send an <ESC> char to exit before running the macro.  
+Without this, the macro runs in the wrong window, usually.
+
+Refresh Data  updates $DA...$ entry continuously.
+
+Html Link  stores a link which will be embedded if you generate a html version 
+of a document with ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+ diff --git a/public/Wb/Home/Doc/Windows.DD.HTML b/public/Wb/Home/Doc/Windows.DD.HTML new file mode 100755 index 0000000..ec323a2 --- /dev/null +++ b/public/Wb/Home/Doc/Windows.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Only tasks on Core0 can have a window and there can be only one window per task. 
+ The window Z-buffer, top-to-bottom order is determined by the order in the task 
+queue, with the WinMgr on the bottom.  A task can have child task popup windows.
+
+ diff --git a/public/Wb/Home/MakeHome.HC.HTML b/public/Wb/Home/MakeHome.HC.HTML new file mode 100755 index 0000000..a081be7 --- /dev/null +++ b/public/Wb/Home/MakeHome.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+//If these are not present in /Home, it uses the version in the root dir.  You
+//can make your own, modified, version of these files in your /Home directory.
+#include "~/HomeLocalize"
+#include "/Adam/Opt/Boot/MakeBoot"
+#include "/Adam/Opt/Utils/MakeUtils"
+#include "~/HomeWrappers"
+MapFileLoad("::/Kernel/Kernel");
+MapFileLoad("::/Compiler/Compiler");
+#include "~/HomeKeyPlugIns"
+#include "~/HomeSys"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Registry.HC.HTML b/public/Wb/Home/Registry.HC.HTML new file mode 100755 index 0000000..a1be755 --- /dev/null +++ b/public/Wb/Home/Registry.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
++] Adam
++] Once
+
+ diff --git a/public/Wb/Home/Src/Adam/ABlkDev/ADskA.HC.HTML b/public/Wb/Home/Src/Adam/ABlkDev/ADskA.HC.HTML new file mode 100755 index 0000000..9c2b216 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ABlkDev/ADskA.HC.HTML @@ -0,0 +1,283 @@ + + + + + + + + + + + +
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+public U8 *DBlk(I64 blk,Bool write=FALSE)
+{//Dump disk block. Optionally, write.
+//If you set write to TRUE, the block will
+  //be written when you press <ESC>.
+  //See ::/Demo/Dsk/DskRaw.HC.
+  U8 *buf=MAlloc(BLK_SIZE);
+
+  BlkRead(Fs->cur_dv,buf,blk,1);
+  DocD(buf,BLK_SIZE);
+  if (write) {
+    "Edit and press <ESC> to write or <SHIFT-ESC>\n";
+    if (View) {
+      "Write\n";
+      BlkWrite(Fs->cur_dv,buf,blk,1);
+    }
+  }
+  return buf;
+}
+
+public U8 *DClus(I64 c,Bool write=FALSE,I64 num=0)
+{//Dump disk clus. Optionally, write.
+//If you set write to TRUE, the clus will
+  //be written when you press <ESC>.
+  //See ::/Demo/Dsk/DskRaw.HC.
+  //Do Dir("*",TRUE); to get clus numbers of files.
+  U8 *buf=MAlloc(Fs->cur_dv->spc<<BLK_SIZE_BITS);
+  c=ClusNumNext(Fs->cur_dv,c,num);
+  ClusRead(Fs->cur_dv,buf,c,1);
+  "Clus:%X\n",c;
+  DocD(buf,Fs->cur_dv->spc<<BLK_SIZE_BITS);
+  if (write) {
+    "Edit and press <ESC> to write or <SHIFT-ESC>\n";
+    if (View) {
+      "Write\n";
+      ClusWrite(Fs->cur_dv,buf,c,1);
+    }
+  }
+  return buf;
+}
+
+public U8 *Dump(U8 *filename,Bool write=FALSE)
+{//Dump file. Optionally, write.
+//If you set write to TRUE, the file will
+  //be written when you press <ESC>.
+  U8 *buf;
+  I64 size;
+  if (buf=FileRead(filename,&size)) {
+    DocD(buf,size);
+    if (write) {
+      "Edit and press <ESC> to write or <SHIFT-ESC>\n";
+      if (View) {
+        "Write\n";
+        FileWrite(filename,buf,size);
+      }
+    }
+  }
+  return buf;
+}
+
+public Bool Copy(U8 *src_files_find_mask,U8 *dst_files_find_mask=".")
+{//Copy files.
+//If the name ends in ".Z", it will
+  //be stored compressed.  If not ".Z"
+  //it will be stored uncompressed.
+  Bool res=TRUE;
+  CDirContext *dirc;
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st;
+  if (!(tmpde1=FilesFind(src_files_find_mask,FUF_CLUS_ORDER)))
+    return FALSE;
+  if (IsDir(dst_files_find_mask)) {
+    if (dirc=DirContextNew(dst_files_find_mask,TRUE)) {
+      tmpde=tmpde1;
+      while (tmpde) {
+        if (!(tmpde->attr & RS_ATTR_DIR)) {
+          st=FileNameAbs(tmpde->name);
+          if (!CopySingle(tmpde->full_name,st))
+            res=FALSE;
+          Free(st);
+        }
+        tmpde=tmpde->next;
+      }
+      DirContextDel(dirc);
+    }
+    DirTreeDel(tmpde1);
+    return res;
+  } else {
+    DirTreeDel(tmpde1);
+    return CopySingle(src_files_find_mask,dst_files_find_mask);
+  }
+}
+
+public Bool Move(U8 *f1,U8 *f2)
+{//Move files from one location to another or rename.
+  if (Copy(f1,f2)) {
+    Del(f1);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+I64 CopyTree2(CDirEntry *tmpde,I64 src_dir_len,I64 dst_dir_len,U8 *dst_dir)
+{
+  U8 *st;
+  I64 res=1;
+  while (tmpde) {
+    st=MAlloc(StrLen(tmpde->full_name)+dst_dir_len+2);
+    MemCpy(st,dst_dir,dst_dir_len);
+    StrCpy(st+dst_dir_len,tmpde->full_name+src_dir_len);
+    if (tmpde->attr & RS_ATTR_DIR) {
+      DirMk(st,LinkedLstCnt(tmpde->sub));
+      res+=CopyTree2(tmpde->sub,src_dir_len,dst_dir_len,dst_dir);
+    } else
+      if (CopySingle(tmpde->full_name,st))
+        res++;
+    Free(st);
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+public I64 CopyTree(U8 *src_files_find_mask,U8 *dst_files_find_mask,
+        Bool no_mask=TRUE)
+{//Copy directory tree.
+//Returns the count of copied files (not dirs).
+  CDirContext *dirc;
+  CDirEntry *tmpde=NULL;
+  I64 res=0,i1,i2;
+  U8 *st1,*st2;
+
+  st1=DirNameAbs(src_files_find_mask);
+  st2=DirNameAbs(dst_files_find_mask);
+  i1=StrLen(st1);
+  if (!StrNCmp(st1,st2,i1) && (st2[i1]=='/' || !st2[i1]) ) {
+    Free(st1);
+    Free(st2);
+    return 0;
+  }
+  Free(st1);
+  Free(st2);
+  if (dirc=DirContextNew(src_files_find_mask,TRUE,,no_mask)) {
+    tmpde=FilesFind(dirc->mask,FUF_RECURSE);
+    st1=DirCur;
+    DirContextDel(dirc);
+    i1=StrLen(st1);
+    if (i1==3) i1--;
+    if (dirc=DirContextNew(dst_files_find_mask,TRUE,TRUE)) {
+      st2=DirCur;
+      i2=StrLen(st2);
+      if (i2==3) i2--;
+      res=CopyTree2(tmpde,i1,i2,st2);
+      DirContextDel(dirc);
+      Free(st2);
+    }
+    DirTreeDel(tmpde);
+    Free(st1);
+  }
+  return res;
+}
+
+I64 DelTreeDirs(CDirEntry *tmpde1)
+{
+  I64 res=0;
+  CDirEntry *tmpde2;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR) {
+      if (tmpde1->sub)
+        res+=DelTreeDirs(tmpde1->sub);
+      res+=Del(tmpde1->full_name,TRUE,TRUE);
+    }
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return res;
+}
+I64 DelTreeFiles(CDirEntry *tmpde1)
+{
+  I64 res=0;
+  CDirEntry *tmpde2;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR) {
+      if (tmpde1->sub)
+        res+=DelTreeFiles(tmpde1->sub);
+    } else
+      res+=Del(tmpde1->full_name,FALSE,TRUE);
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return res;
+}
+public I64 DelTree(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Delete directory tree.
+  I64 res=0,fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (IsDir(files_find_mask)) {
+    res=DelTreeDirs(FilesFind(files_find_mask,fuf_flags));
+    res+=Del(files_find_mask,TRUE,TRUE);
+    res+=Del(files_find_mask,FALSE,TRUE);
+  } else
+    res=DelTreeFiles(FilesFind(files_find_mask,fuf_flags));
+  return res;
+}
+
+U0 TouchFile(U8 *filename,U8 *attr,CDate cdt=I64_MIN)
+{
+  CDrv *dv=Let2Drv(*filename);
+  CDirEntry de;
+  U8 *cur_dir=StrNew(filename),buf[STR_LEN];
+  if (FileFind(filename,&de,FUF_JUST_FILES)) {
+    Free(de.full_name);
+    if (!StrCmp(attr,"+?"))
+      "%-48ts %s\n",filename,StrPrintFlags(buf,Define("ST_FILE_ATTRS"),de.attr);
+    else {
+      StrFirstRem(cur_dir,":");
+      StrLastRem(cur_dir,"/");
+      if (!*cur_dir)
+        StrCpy(cur_dir,"/");
+      ScanFlags(&de.attr,Define("ST_FILE_ATTRS"),attr);
+      if (cdt==I64_MIN)
+        de.datetime=Now;
+      else
+        de.datetime=cdt;
+      DirNew(dv,cur_dir,&de,FALSE);
+    }
+  } else
+    PrintErr("File not found: \"%s\".\n",filename);
+  Free(cur_dir);
+}
+public U0 Touch(U8 *files_find_mask="*",U8 *attr="+?",
+        U8 *fu_flags=NULL,CDate cdt=I64_MIN)
+{/*Touch file attributes and DateTime.
+Default lists attributes.
+attr: "+?" =show current
+"+T" =resident
+RS_ATTR_READ_ONLY  ST_FILE_ATTRS
+To Set DateL:
+Touch(filename,"",,datetime);
+*/
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    TouchFile(tmpde->full_name,attr,cdt);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ABlkDev/ADskB.HC.HTML b/public/Wb/Home/Src/Adam/ABlkDev/ADskB.HC.HTML new file mode 100755 index 0000000..41c5b43 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ABlkDev/ADskB.HC.HTML @@ -0,0 +1,222 @@ + + + + + + + + + + + +
+#help_index "File/Internal"
+I64 DirTreeSerializeSize(CDirEntry *tmpde)
+{
+  I64 res=0;
+  while (tmpde) {
+    res+=CDIR_SIZE+1;
+    if (tmpde->attr & RS_ATTR_DIR)
+      res+=DirTreeSerializeSize(tmpde->sub);
+    tmpde=tmpde->next;
+  }
+  return res+1;
+}
+I64 DirTreeSerializeFill(CDirEntry *tmpde,U8 *dst)
+{
+  I64 res=0,i;
+  while (tmpde) {
+    *dst++=1;
+    res++;
+    MemCpy(dst,&tmpde->start,CDIR_SIZE);
+    dst+=CDIR_SIZE;
+    res+=CDIR_SIZE;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      i=DirTreeSerializeFill(tmpde->sub,dst);
+      dst+=i;
+      res+=i;
+    }
+    tmpde=tmpde->next;
+  }
+  *dst=0;
+  return res+1;
+}
+public U8 *DirTreeSerialize(CDirEntry *tmpde,I64 *_size=NULL)
+{//Serialize tree returned from FilesFind() into a one contiguous U8 array.
+  I64 size=DirTreeSerializeSize(tmpde);
+  U8 *buf=MAlloc(size);
+  DirTreeSerializeFill(tmpde,buf);
+  if (_size) *_size=size;
+  return buf;
+}
+
+U8 *DirTreeUnserialize2(U8 *src,CDirEntry **tmpde)
+{
+  CDirEntry *tmpde1;
+  if (*src++) {
+    tmpde1=CAlloc(sizeof(CDirEntry));
+    *tmpde=tmpde1;
+    MemCpy(&tmpde1->start,src,CDIR_SIZE);
+    src+=CDIR_SIZE;
+    if (tmpde1->attr & RS_ATTR_DIR)
+      src=DirTreeUnserialize2(src,&tmpde1->sub);
+    src=DirTreeUnserialize2(src,&tmpde1->next);
+  } else
+    *tmpde=NULL;
+  return src;
+}
+public CDirEntry *DirTreeUnserialize(U8 *src)
+{//Unserialize tree to make it like a tree returned from FilesFind().
+  CDirEntry *tmpde=NULL;
+  DirTreeUnserialize2(src,&tmpde);
+  return tmpde;
+}
+
+#help_index "File/Program Routines"
+U0 FOFlatten(CDirEntry *tmpde,CDirEntry **a,I64 *i)
+{
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr&RS_ATTR_DIR) {
+      FOFlatten(tmpde->sub,a,i);
+      DirEntryDel(tmpde);
+    } else {
+      a[*i]=tmpde;
+      *i=*i+1;
+    }
+    tmpde=tmpde1;
+  }
+}
+
+I64 Size1(CDirEntry *tmpde,I64 *_fuf_flags,I64 round_to)
+{
+  U8 buf[BLK_SIZE];
+  I64 res=0,i;
+  CDrv *dv;
+  while (tmpde) {
+    if ((i=tmpde->size) && Bt(_fuf_flags,FUf_EXPAND) &&
+          !(tmpde->attr&RS_ATTR_DIR) &&
+          FileAttr(tmpde->name)&RS_ATTR_COMPRESSED) {
+      dv=Let2Drv(*tmpde->full_name);
+      BlkRead(dv,buf,Clus2Blk(dv,tmpde->clus),1);
+      i=(&buf)(CArcCompress *)->expanded_size;
+    }
+    if (round_to)
+      i=CeilU64(tmpde->size,round_to);
+    if (tmpde->attr&RS_ATTR_DIR)
+      i+=Size1(tmpde->sub,_fuf_flags,round_to);
+    tmpde->user_data=i;
+    res+=i;
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+public I64 Size(U8 *files_find_mask="/*",U8 *fu_flags=NULL,I64 round_to=0)
+{//Total size of files in mask. "+x" for expanded size.
+//Does not include directory size of base directory, but
+  //does include size of sub directories.
+  I64 fuf_flags=0,res=0;
+  CDirEntry *tmpde1=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND)) {
+    fuf_flags&=FUF_EXPAND;
+    res=Size1(tmpde1,&fuf_flags,round_to);
+    DirTreeDel(tmpde1);
+  }
+  return res;
+}
+
+public I64 FileCnt(CDirEntry *tmpde)
+{//Cnt of files in CDirEntry tree.
+  I64 cnt=0;
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR)
+      cnt+=FileCnt(tmpde->sub);
+    else
+      cnt++;
+    tmpde=tmpde->next;
+  }
+  return cnt;
+}
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+public I64 FF(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Files find. List files matching mask.
+  I64 cnt=0,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    PutFileLink(tmpde->full_name);
+    '\n';
+    cnt++;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return cnt;
+}
+
+public I64 Zip(U8 *files_find_mask="*",U8 *fu_flags=NULL)
+{//Compress files by moving to .Z filename.
+  U8 *st;
+  CDirEntry *tmpde,*tmpde1;
+  I64 res=0,fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (!IsDotZ(tmpde->full_name)) {
+      st=MStrPrint("%s.Z",tmpde->full_name);
+      res+=Move(tmpde->full_name,st);
+      Free(st);
+    }
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return res;
+}
+
+public I64 Unzip(U8 *files_find_mask="*.Z",U8 *fu_flags=NULL)
+{//Uncompress files by moving to not .Z filename.
+//You don't have to do this for normal operation.
+  //It automatically unzips ".Z" files.
+  U8 *st;
+  CDirEntry *tmpde,*tmpde1;
+  I64 res=0,fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (IsDotZ(tmpde->full_name)) {
+      st=StrNew(tmpde->full_name);
+      StrLastRem(st,".");
+      res+=Move(tmpde->full_name,st);
+      Free(st);
+    }
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ABlkDev/DskChk.HC.HTML b/public/Wb/Home/Src/Adam/ABlkDev/DskChk.HC.HTML new file mode 100755 index 0000000..5a57f79 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ABlkDev/DskChk.HC.HTML @@ -0,0 +1,475 @@ + + + + + + + + + + + +
+#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)"
+Bool ChkDskConfirm(Bool *_fix,Bool *_confirm)
+{
+  if (*_fix && *_confirm) {
+    "Fix ";
+    if (!YorN)
+      *_fix=FALSE;
+    *_confirm=FALSE;
+  }
+  return *_fix;
+}
+
+I64 RedSeaChkDskLst(CDrv *dv,CDirEntry *tmpde1,
+        U8 *bits,U8 *bits2,I64 size,I64 bpc)
+{
+  CDirEntry *tmpde2;
+  I64 i,j,errs=0;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)
+      errs+=RedSeaChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);
+    j=(tmpde1->size+bpc-1)/bpc;
+    for (i=0;i<j;i++) {
+      if (i+tmpde1->clus-dv->data_area>size) {
+        PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,
+              i+tmpde1->clus);
+        errs++;
+        break;
+      }
+      if (LBts(bits,i+tmpde1->clus-dv->data_area)) {
+        PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,
+              i+tmpde1->clus);
+        errs++;
+      }
+      if (!LBtr(bits2,i+tmpde1->clus-dv->data_area)) {
+        PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,
+              i+tmpde1->clus);
+        errs++;
+      }
+    }
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return errs;
+}
+
+I64 RedSeaChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
+{
+  I64 i,j,bpc,size,errs=0;
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),
+        *old_dir=StrNew(Fs->cur_dir),
+        *bits,*bits2;
+  CDirEntry *ptr,*ptr2;
+
+  Drv(drv_let);
+  "Scanning...\n";
+  size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;
+  bpc=dv->spc<<BLK_SIZE_BITS;
+  bits=CAlloc((size+7)>>3);
+  bits2=CAlloc((size+7)>>3+BLK_SIZE);
+  BlkRead(dv,bits2,dv->fat1,((size+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS);
+
+  //Get Root Dir size
+  ptr2=MAlloc(bpc);
+  BlkRead(dv,ptr2,dv->root_clus,1);
+  ptr=ptr2(U8 *)-offset(CDirEntry.start);
+  j=(ptr->size+bpc-1)/bpc;
+  Free(ptr2);
+
+  for (i=0;i<j;i++) {
+    if (i+dv->root_clus-dv->data_area>size) {
+      PrintErr("Invalid Clus: RootDir Clus:%X\n",i+dv->root_clus);
+      errs++;
+      break;
+    }
+    if (LBts(bits,i+dv->root_clus-dv->data_area)) {
+      PrintErr("Dbl Alloc: RootDir Clus:%X\n",i+dv->root_clus);
+      errs++;
+    }
+    if (!LBtr(bits2,i+dv->root_clus-dv->data_area)) {
+      PrintErr("UnAlloc: RootDir Clus:%X\n",i+dv->root_clus);
+      errs++;
+    }
+  }
+
+  errs+=RedSeaChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),
+        bits,bits2,size,bpc);
+  for (i=1;i<size;i++)
+    if (Bt(bits2,i)) {
+      PrintWarn("Shouldn't Alloc Clus:%0X\n",i+dv->data_area);
+      errs++;
+      if (ChkDskConfirm(_fix,_confirm))
+        RedSeaFreeClus(dv,i+dv->data_area,1);
+    }
+
+  Free(files_find_mask);
+  Free(bits);
+  Free(bits2);
+  Drv(Drv2Let(old_dv));
+  Cd(old_dir);
+  Free(old_dir);
+  return errs;
+}
+
+I64 FAT32ChkDskLst(CDrv *dv,CDirEntry *tmpde1,
+        U8 *bits,U32 *bits2,I64 size,I64 bpc)
+{
+  CDirEntry *tmpde2;
+  I64 i,c,errs=0;
+  while (tmpde1) {
+    tmpde2=tmpde1->next;
+    if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)
+      errs+=FAT32ChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);
+    i=0;
+    c=tmpde1->clus;
+    while (0<c<0x0FFFFFF8) {
+      if (c>size) {
+        PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,c);
+        errs++;
+        break;
+      }
+      if (LBts(bits,c)) {
+        PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,c);
+        errs++;
+      }
+      if (!bits2[c]) {
+        PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,c);
+        errs++;
+      } else
+        bits2[c]=0;
+      c=ClusNumNext(dv,c);
+      i++;
+    }
+    if (!(tmpde1->attr & RS_ATTR_DIR)) {
+      i*=bpc;
+      if (tmpde1->size>i) {
+        PrintErr("Alloced File Too Short:%s\n",tmpde1->full_name);
+        errs++;
+      }
+      if (i>tmpde1->size+bpc-1) {
+        PrintWarn("Alloced File Too Long:%s\n",tmpde1->full_name);
+        errs++;
+      }
+    }
+    DirEntryDel(tmpde1);
+    tmpde1=tmpde2;
+  }
+  return errs;
+}
+
+I64 FAT32ChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
+{
+  I64 i,bpc,size,c,errs=0;
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),
+        *old_dir=StrNew(Fs->cur_dir),
+        *bits;
+  U32 *bits2;
+  Drv(drv_let);
+  "Scanning...\n";
+  size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;
+  bpc=dv->spc<<BLK_SIZE_BITS;
+  bits=CAlloc((size+7)>>3);
+  bits2=CAlloc(size*4+BLK_SIZE);
+  BlkRead(dv,bits2,dv->fat1,(size*4+BLK_SIZE-1)>>BLK_SIZE_BITS);
+
+  c=dv->root_clus;
+  while (0<c<0x0FFFFFF8) {
+    if (c>size) {
+      PrintErr("Invalid Clus: RootDir Clus:%X\n",c);
+      errs++;
+      break;
+    }
+    if (LBts(bits,c)) {
+      PrintErr("Dbl Alloc: RootDir Clus:%X\n",c);
+      errs++;
+    }
+    if (!bits2[c]) {
+      PrintErr("UnAlloc: RootDir Clus:%X\n",c);
+      errs++;
+    } else
+      bits2[c]=0;
+    c=ClusNumNext(dv,c);
+  }
+
+  errs+=FAT32ChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),
+        bits,bits2,size,bpc);
+
+  bits2[1]=0; //See FAT32Fmt()
+  for (i=1;i<size;i++)
+    if (bits2[i]) {
+      PrintWarn("Shouldn't Alloc Clus:%0X\n",i);
+      errs++;
+      if (ChkDskConfirm(_fix,_confirm))
+        FAT32FreeClus(dv,i);
+    }
+  Free(files_find_mask);
+  Free(bits);
+  Free(bits2);
+  Drv(Drv2Let(old_dv));
+  Cd(old_dir);
+  Free(old_dir);
+  return errs;
+}
+
+public I64 DskChk(U8 drv_let=0,Bool fix=FALSE,Bool confirm=TRUE)
+{//Check disk for allocation errors and, optionally, fix.
+//You probably want to reformat and reinstall.
+  I64 errs=0;
+  CDrv *dv=Let2Drv(drv_let);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      errs=RedSeaChkDsk(drv_let,&fix,&confirm);
+      break;
+    case FSt_FAT32:
+      errs=FAT32ChkDsk(drv_let,&fix,&confirm);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+  if (errs) {
+    if (fix)
+      "It might be a little better.  ";
+    "Copy files to another partition or CD/DVD, "
+          "reformat, and copy back.  "
+          "Or, copy from a back-up.\n";
+  }
+  return errs;
+}
+
+U0 RedSeaDrvView(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
+        s=dv->size+dv->drv_offset-dv->data_area;
+  U8 *bitmap;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  WinMax;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DCFill;
+  try {
+    i=((s+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    i=0;
+    for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {
+      if (ScanKey)
+        break;
+      for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {
+        lohi=i*s;
+        c1=lohi/l;
+        if (Bt(bitmap,c1))
+          dc->color=ROP_XOR+BLUE^TRANSPARENT;
+        else
+          dc->color=ROP_XOR+WHITE^TRANSPARENT;
+        GrPlot(dc,x,y);
+        i++;
+      }
+    }
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  GetChar;
+
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+}
+U0 FAT32DrvView(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
+        s=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);
+  U32 *bitmap;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  WinMax;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DCFill;
+  try {
+    i=(s*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    i=0;
+    for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {
+      if (ScanKey)
+        break;
+      for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {
+        lohi=i*s;
+        c1=lohi/l;
+        if (bitmap[c1])
+          dc->color=ROP_XOR+BLUE^TRANSPARENT;
+        else
+          dc->color=ROP_XOR+WHITE^TRANSPARENT;
+        GrPlot(dc,x,y);
+        i++;
+      }
+    }
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  GetChar;
+
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+}
+public U0 DrvView(U8 drv_let=0)
+{//Drive view. Graph the allocation map's fragmentation.
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  Drv(drv_let);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      RedSeaDrvView(drv_let);
+      break;
+    case FSt_FAT32:
+      FAT32DrvView(drv_let);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+  Drv(Drv2Let(old_dv));
+}
+
+public U0 DskView(U8 drv_let=0)
+{//Disk view. Pie chart of partition sizes.
+  I64 i,j,attr,
+        h=Fs->pix_width,
+        v=Fs->pix_height,
+        radius;
+  CDrv *dv;
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  CDC *dc=DCAlias;
+  F64 sect_start,sect_end;
+
+  SettingsPush; //See SettingsPush
+  DocCursor;
+  DocClear;
+  DCFill;
+  if (h<v)
+    radius=0.4*h;
+  else
+    radius=0.4*v;
+  dc->color=BLACK;
+  GrCircle(dc,h>>1,v>>1,radius);
+
+  j=1;
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (bd==dv->bd && dv->fs_type) {
+      sect_start=-(dv->drv_offset*2*pi/(bd->max_blk+1));
+      sect_end  =-((dv->drv_offset+dv->size)*2*pi/(bd->max_blk+1));
+      dc->color=BLACK;
+      GrLine(dc,h>>1,v>>1,
+            h>>1+radius*Cos(sect_start),
+            v>>1+radius*Sin(sect_start));
+      GrLine(dc,h>>1,v>>1,
+            h>>1+radius*Cos(sect_end),
+            v>>1+radius*Sin(sect_end));
+
+      attr=DrvTextAttrGet(Drv2Let(dv));
+      dc->color=attr&15;
+      GrPrint(dc,0,v-FONT_HEIGHT*j,"%C %-8Z",Drv2Let(dv),
+            dv->fs_type,"ST_DRV_TYPES");
+      dc->color.c1=attr>>4;
+      dc->color|=ROPF_DITHER;
+      GrFloodFill(dc,
+            h>>1+(radius-4)*Cos((sect_start+sect_end)/2),
+            v>>1+(radius-4)*Sin((sect_start+sect_end)/2),FALSE);
+      j++;
+    }
+  }
+
+  GetChar(,FALSE);
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+}
+
+I64 RedSeaUnusedDrvSpace(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 res=0,i,l;
+  U8 *bitmap;
+  try {
+    l=dv->size+dv->drv_offset-dv->data_area;
+    i=((l+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    for (i=0;i<l;i++)
+      if (!Bt(bitmap,i))
+        res++;
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  return res*BLK_SIZE*dv->spc;
+}
+I64 FAT32UnusedDrvSpace(U8 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  I64 res=0,i,l;
+  U32 *bitmap;
+  try {
+    l=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);
+    i=(l*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    bitmap=MAlloc(i<<BLK_SIZE_BITS);
+    BlkRead(dv,bitmap,dv->fat1,i);
+    for (i=0;i<l;i++)
+      if (!bitmap[i])
+        res++;
+    Free(bitmap);
+  } catch
+    DrvUnlock(dv);
+  return res*BLK_SIZE*dv->spc;
+}
+public I64 DrvUnused(U8 drv_let=0)
+{//Returns unused size in bytes.
+  CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
+  U8 *old_dir=StrNew(Fs->cur_dir);
+  I64 res=0;
+  Drv(drv_let);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      res=RedSeaUnusedDrvSpace(drv_let);
+      break;
+    case FSt_FAT32:
+      res=FAT32UnusedDrvSpace(drv_let);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+  Drv(Drv2Let(old_dv));
+  Cd(old_dir);
+  Free(old_dir);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ABlkDev/DskPrt.HC.HTML b/public/Wb/Home/Src/Adam/ABlkDev/DskPrt.HC.HTML new file mode 100755 index 0000000..18154e5 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ABlkDev/DskPrt.HC.HTML @@ -0,0 +1,198 @@ + + + + + + + + + + + +
+#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically)"
+
+#define ROUND_DRV_TO    (63*255)
+#define DRV_HEADER      63
+
+class CPlannedDrv
+{
+  CPlannedDrv *next,*last;
+  I64 size;
+  Bool pri;
+};
+
+public I64 DskPrt(U8 drv_let=0,...)
+{/*Partition the disk containing partition drv_let.
+
+drv_let=0 means add new drive that is not already mounted.
+
+>DskPrt('C',0.5,0.25,0.25); //Make three.  50% C, 25% D, 25% E, round-up to blk.
+
+*/
+  CBlkDev *bd;
+  CPlannedDrv head,*tmppp;
+  CMasterBoot mbr;
+  Bool pri=TRUE;
+  I64 ext_base,drv_let2,pri_cnt=0,i,start_offset,offset,
+        total,remaining,cur_arg=0;
+  "This command does not play well\n"
+        "with other operating systems.\n"
+        "You really should use another\n"
+        "operating system's partitioner.\n"
+        "If you use this, it may, in fact,\n"
+        "make your hard drive impossible\n"
+        "to repartition with other operating\n"
+        "until you set block zero to zero\n"
+        "with $LK,\"BootMHDZero\",\"MN:BootMHDZero\"$()\n\n\n"
+        "Continue";
+  if (argc<=cur_arg && !YorN)
+    return 0;
+  '\n';
+
+  if (drv_let && !Let2BlkDev(drv_let,FALSE))
+    drv_let=0;
+  if (!drv_let && !(drv_let=Mount(TRUE)) ||
+        !(bd=Let2BlkDev(drv_let,FALSE)) || bd->type!=BDT_ATA)
+    return 0;
+
+  total=bd->max_blk+1;
+  QueInit(&head);
+  drv_let2=bd->first_drv_let;
+  remaining=FloorU64(bd->max_blk+1,ROUND_DRV_TO);
+  while (FloorU64(remaining,ROUND_DRV_TO)>=ROUND_DRV_TO) {
+    tmppp=MAlloc(sizeof(CPlannedDrv));
+    do {
+      "$RED$Partition %C$FG$\n",drv_let2;
+      tmppp->pri=FALSE;
+      if (pri) {
+        "Primary Partition";
+        if (argc>cur_arg || YorN) {
+          pri_cnt++;
+          tmppp->pri=TRUE;
+          if (pri_cnt==3)
+            pri=FALSE;
+        } else
+          pri=FALSE;
+      }
+      "\nBlocks Remaining:%d (0x%X)\n",
+            remaining-DRV_HEADER,remaining-DRV_HEADER;
+      if (argc>cur_arg)
+        tmppp->size=MinI64(CeilU64(MaxI64(remaining,DRV_HEADER),ROUND_DRV_TO),
+              CeilU64(argv[cur_arg++](F64)*total,ROUND_DRV_TO));
+      else
+        tmppp->size=CeilU64(GetI64("Size in Blocks  :",
+              remaining-DRV_HEADER)+DRV_HEADER,ROUND_DRV_TO);
+    } while (!(ROUND_DRV_TO<=tmppp->size<=FloorU64(remaining,ROUND_DRV_TO)));
+    QueIns(tmppp,head.last);
+    remaining-=tmppp->size;
+    drv_let2++;
+  }
+
+  "\n\n!!! Repartition Drive !!!\n\n";
+  tmppp=head.next;
+  drv_let2=bd->first_drv_let;
+  while (tmppp!=&head) {
+    "Drive %C:%08X ",drv_let2,tmppp->size;
+    if (tmppp->pri)
+      "Primary\n";
+    else
+      "Logical\n";
+    tmppp=tmppp->next;
+    drv_let2++;
+  }
+  if (!argc && !AreYouSure)
+    goto pd_done;
+
+  remaining=FloorU64(bd->max_blk+1,ROUND_DRV_TO)-ROUND_DRV_TO;
+  tmppp=head.next;
+  MemSet(&mbr,0,BLK_SIZE);
+  mbr.signature=0xAA55;
+  offset=0;
+  for (i=0;i<pri_cnt;i++) {
+    mbr.p[i].active=0x80;
+    mbr.p[i].start_head=0;
+    mbr.p[i].start_cyl=0x101;
+    mbr.p[i].type=1; //Will get set different.
+    mbr.p[i].end_head=0xFE;
+    mbr.p[i].end_cyl=0xFFFF;
+    mbr.p[i].offset=DRV_HEADER+offset;
+    mbr.p[i].size=tmppp->size-DRV_HEADER;
+    offset+=tmppp->size;
+    remaining-=tmppp->size;
+    tmppp=tmppp->next;
+  }
+  if (!i) i++;
+  if (tmppp!=&head) {
+    mbr.p[i].active=0x80;
+    mbr.p[i].start_head=0;
+    mbr.p[i].start_cyl=0x101;
+    mbr.p[i].type=0xF;
+    mbr.p[i].end_head=0xFE;
+    mbr.p[i].end_cyl=0xFFFF;
+    mbr.p[i].offset=offset;
+    mbr.p[i].size=remaining;
+    ext_base=offset;
+  }
+  ATAWriteBlks(bd,&mbr,0,1);
+
+  while (tmppp!=&head) {
+    start_offset=offset;
+    MemSet(&mbr,0,BLK_SIZE);
+    mbr.signature=0xAA55;
+
+    mbr.p[0].active=0x80;
+    mbr.p[0].start_head=1;
+    mbr.p[0].start_cyl=0x101;
+    mbr.p[0].type=1; //Will get set different.
+    mbr.p[0].end_head=0xFE;
+    mbr.p[0].end_cyl=0xFFFF;
+    mbr.p[0].offset=DRV_HEADER;
+    mbr.p[0].size=tmppp->size-DRV_HEADER;
+    offset+=tmppp->size;
+    tmppp=tmppp->next;
+    if (tmppp!=&head) {
+      mbr.p[1].active=0x80;
+      mbr.p[1].start_head=0;
+      mbr.p[1].start_cyl=0x101;
+      mbr.p[1].type=5;
+      mbr.p[1].end_head=0xFE;
+      mbr.p[1].end_cyl=0xFFFF;
+      mbr.p[1].offset=offset-ext_base;
+      mbr.p[1].size=tmppp->size;
+    }
+    ATAWriteBlks(bd,&mbr,start_offset,1);
+  }
+
+  bd->flags&=~(BDF_INITIALIZED | BDF_INIT_IN_PROGRESS);
+  BlkDevAdd(bd,,FALSE,TRUE);
+  for (i=bd->first_drv_let;i<drv_let2;i++)
+    Fmt(i,,FALSE);
+
+    pd_done:
+  while (head.next!=&head) {
+    tmppp=head.next;
+    QueRem(tmppp);
+    Free(tmppp);
+  }
+  return total;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ABlkDev/FileMgr.HC.HTML b/public/Wb/Home/Src/Adam/ABlkDev/FileMgr.HC.HTML new file mode 100755 index 0000000..e760778 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ABlkDev/FileMgr.HC.HTML @@ -0,0 +1,822 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+U0 DirFileDoc(CDoc *doc,CDirEntry *tmpde)
+{
+  while (tmpde) {
+    if (tmpde->attr & RS_ATTR_DIR) {
+      tmpde->user_data=DocPrint(doc,"$TR,\"%s\",U=0x%X$",tmpde->name,tmpde);
+      DocPrint(doc,"\n$ID,+2$");
+      if (tmpde->sub)
+        DirFileDoc(doc,tmpde->sub);
+      DocPrint(doc,"$ID,-2$");
+    } else {
+      tmpde->user_data=DocPrint(doc,"$MU,\"%s\",U=0x%X$",tmpde->name,tmpde);
+      DocPrint(doc,"\n");
+    }
+    tmpde=tmpde->next;
+  }
+}
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+
+#define FM_NORMAL       0
+#define FM_PICK_FILE    1
+#define FM_PICK_DIR     2
+
+class CFMUncollapsedLst
+{
+  CFMUncollapsedLst *next;
+  U8 *name;
+};
+
+CFMUncollapsedLst *FMCollectUncollapsedLst(CDoc *doc)
+{
+  CDocEntry *doc_e=doc->head.next;
+  CFMUncollapsedLst *res=NULL,*tmpc;
+  CDirEntry *tmpde;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TREE) {
+      if (!(doc_e->de_flags&DOCEF_CHECKED_COLLAPSED)) {
+        if (tmpde=doc_e->user_data) {
+          tmpc=MAlloc(sizeof(CFMUncollapsedLst));
+          tmpc->next=res;
+          res=tmpc;
+          tmpc->name=StrNew(tmpde->full_name);
+        }
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  return res;
+}
+
+U0 FMMarkUncollapsed(CDoc *doc,CFMUncollapsedLst *tmpc,
+        U8 *cur_entry,U8 *next_entry)
+{
+  CDocEntry *doc_e=doc->head.next;
+  CFMUncollapsedLst *tmpc1;
+  CDirEntry *tmpde;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TREE) {
+      tmpde=doc_e->user_data;
+      tmpc1=tmpc;
+      while (tmpc1) {
+        if (!StrCmp(tmpc1->name,tmpde->full_name)) {
+          doc_e->de_flags&=~DOCEF_CHECKED_COLLAPSED;
+          break;
+        }
+        tmpc1=tmpc1->next;
+      }
+      if (cur_entry) {
+        if (!StrNCmp(cur_entry,tmpde->full_name,StrLen(tmpde->full_name))) {
+          doc->cur_entry=doc_e;
+          if (StrLen(tmpde->full_name)==StrLen(cur_entry))
+            cur_entry=NULL;
+        } else if (next_entry) {
+          if (!StrNCmp(next_entry,
+                tmpde->full_name,StrLen(tmpde->full_name))) {
+            doc->cur_entry=doc_e;
+            if (StrLen(tmpde->full_name)==StrLen(next_entry))
+              cur_entry=NULL;
+          }
+        }
+      }
+    } else if (doc_e->type_u8==DOCT_MENU_VAL) {
+      tmpde=doc_e->user_data;
+      if (cur_entry) {
+        if (!StrNCmp(cur_entry,tmpde->full_name,StrLen(tmpde->full_name))) {
+          doc->cur_entry=doc_e;
+          if (StrLen(tmpde->full_name)==StrLen(cur_entry))
+            cur_entry=NULL;
+        } else if (next_entry) {
+          if (!StrNCmp(next_entry,
+                tmpde->full_name,StrLen(tmpde->full_name))) {
+            doc->cur_entry=doc_e;
+            if (StrLen(tmpde->full_name)==StrLen(next_entry))
+              cur_entry=NULL;
+          }
+        }
+      }
+    }
+    doc_e=doc_e->next;
+  }
+}
+
+U0 FMDelUncollapsedLst(CFMUncollapsedLst *tmpc)
+{
+  CFMUncollapsedLst *tmpc1;
+  while (tmpc) {
+    tmpc1=tmpc->next;
+    Free(tmpc->name);
+    Free(tmpc);
+    tmpc=tmpc1;
+  }
+}
+
+CDirEntry *FMRebuildDocDrv(U8 drv_let,CDoc *doc,CDirEntry **_head,Bool init)
+{
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st;
+  tmpde=CAlloc(sizeof(CDirEntry));
+  tmpde->full_name=MStrPrint("%C:/",drv_let);
+  tmpde->attr=RS_ATTR_DIR;
+  st=MStrPrint("%c:/*",drv_let);
+  if (init)
+    tmpde->sub=tmpde1=FilesFind(st,FUF_RECURSE);
+  else
+    tmpde1=NULL;
+  Free(st);
+  tmpde->user_data=DocPrint(doc,"$TR,\"%s\",U=0x%X$",tmpde->full_name,tmpde);
+  tmpde->next=*_head;
+  *_head=tmpde;
+  DocPrint(doc,"\n$ID,+2$");
+  DocBottom(doc);
+  if (init) {
+    DirFileDoc(doc,tmpde1);
+    while (tmpde1) {
+      tmpde1->parent=tmpde;
+      tmpde1=tmpde1->next;
+    }
+  }
+  DocPrint(doc,"$ID,-2$");
+  return tmpde;
+}
+
+#define DEF2_PROCESSED          1
+#define DEF2_NOT_INITIALIZED    2
+
+U0 FMRebuildDoc(CDoc **_doc,CDirEntry **_head,I64 mode)
+{
+  CDrv *dv;
+  I64 i;
+  CDoc *doc=*_doc,*doc2=sys_clip_doc,*parent_doc;
+  CFMUncollapsedLst *tmpc=NULL;
+  U8 *cur_entry=NULL,*next_entry=NULL;
+  CDocEntry *doc_ce;
+  CDirEntry *tmpde,*tmpde1,*cur_tree_entry;
+  if (!doc)
+    parent_doc=DocPut;
+  else {
+    parent_doc=doc->parent_doc;
+    Fs->put_doc=Fs->display_doc=NULL;
+    DocUnlock(doc);
+    Refresh;
+    DocLock(doc);
+    cur_tree_entry=NULL;
+    doc_ce=doc->cur_entry;
+    if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+      cur_tree_entry=doc_ce->user_data;
+    if (cur_tree_entry)
+      cur_entry=StrNew(cur_tree_entry->full_name);
+    tmpde=NULL;
+    if (doc_ce!=doc)
+      doc_ce=doc_ce->next;
+    while (doc_ce!=doc) {
+      if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+        tmpde=doc_ce->user_data;
+      else
+        tmpde=NULL;
+      if (tmpde) {
+        tmpde1=tmpde->parent;
+        while (tmpde1) {
+          if (tmpde1==cur_tree_entry) {
+            tmpde=NULL;
+            break;
+          } else
+            tmpde1=tmpde1->parent;
+        }
+        if (tmpde)
+          break;
+      }
+      doc_ce=doc_ce->next;
+    }
+    if (tmpde)
+      next_entry=StrNew(tmpde->full_name);
+
+    tmpc=FMCollectUncollapsedLst(doc);
+    DocDel(doc);
+  }
+  if (*_head) {
+    DirTreeDel(*_head);
+    *_head=NULL;
+  }
+  doc=DocNew;
+  doc->desc='FileMan';
+  doc->parent_doc=parent_doc;
+  doc->flags|=DOCF_FORM;
+  switch (mode) {
+    case FM_NORMAL:
+      DocPrint(doc,"$PURPLE$File Manager\n\n"
+            "$LK,\"Click for Help\",A=\"FI:::/Doc/FileMgr.DD\"$\n\n");
+      break;
+    case FM_PICK_FILE:
+      DocPrint(doc,"$PURPLE$Pick file and press <ESC>\n\n");
+      doc->flags|=DOCF_SIZE_MIN;
+      break;
+    case FM_PICK_DIR:
+      DocPrint(doc,"$PURPLE$Pick directory and press <ESC>\n\n");
+      doc->flags|=DOCF_SIZE_MIN;
+      break;
+  }
+  DocPrint(doc,"$LTBLUE$");
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (dv->bd->type==BDT_ATAPI) {
+      if (dv->bd->flags&BDF_INITIALIZED)
+        tmpde=FMRebuildDocDrv(Drv2Let(dv),doc,_head,TRUE);
+      else {
+        tmpde=FMRebuildDocDrv(Drv2Let(dv),doc,_head,FALSE);
+        tmpde->user_data2|=DEF2_NOT_INITIALIZED;
+      }
+    } else if (dv->fs_type==FSt_REDSEA || dv->fs_type==FSt_FAT32)
+      FMRebuildDocDrv(Drv2Let(dv),doc,_head,TRUE);
+  }
+  DocTop(doc);
+  FMMarkUncollapsed(doc,tmpc,cur_entry,next_entry);
+  DocCenter(doc);
+  DocRst(doc2,TRUE);
+  FMDelUncollapsedLst(tmpc);
+  Free(cur_entry);
+  Free(next_entry);
+  *_doc=doc;
+  DocLock(doc);
+  Fs->put_doc=Fs->display_doc=doc;
+}
+
+U0 FMRename(CDoc *doc)
+{
+  CEdFileName fn;
+  CDocEntry *doc_e=doc->cur_entry;
+  CDirEntry *tmpde=NULL,*parent;
+  if (doc_e->type_u8==DOCT_MENU_VAL) {
+    tmpde=doc_e->user_data;
+    if (parent=tmpde->parent) {
+      Cd(parent->full_name);
+      StrCpy(fn.name,tmpde->name);
+      if (DocForm(&fn)) {
+        Silent;
+        Move(tmpde->name,fn.name);
+        Silent(OFF);
+      }
+    }
+  } else if (doc_e->type_u8==DOCT_TREE) {
+    tmpde=doc_e->user_data;
+    if (parent=tmpde->parent) {
+      Cd(parent->full_name);
+      StrCpy(fn.name,tmpde->name);
+      if (DocForm(&fn)) {
+        if (StrCmp(tmpde->name,fn.name)) {
+          Silent;
+          if (CopyTree(tmpde->name,fn.name))
+            DelTree(tmpde->name);
+          Silent(OFF);
+        }
+      }
+    }
+  }
+}
+
+U0 FMMkDir(CDoc *doc)
+{
+  CEdFileName fn;
+  CDocEntry *doc_e=doc->cur_entry;
+  CDirEntry *tmpde=NULL,*parent;
+  *fn.name=0;
+  if (doc_e->type_u8==DOCT_MENU_VAL) {
+    tmpde=doc_e->user_data;
+    if (parent=tmpde->parent) {
+      Cd(parent->full_name);
+      if (DocForm(&fn)) {
+        Silent;
+        DirMk(fn.name);
+        Silent(OFF);
+      }
+    }
+  } else if (doc_e->type_u8==DOCT_TREE) {
+    tmpde=doc_e->user_data;
+    Cd(tmpde->full_name);
+    if (DocForm(&fn)) {
+      Silent;
+      DirMk(fn.name);
+      Silent(OFF);
+    }
+  }
+}
+
+U0 FMDelete(CDoc *doc)
+{
+  U8 *st;
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_MENU_VAL) {
+    tmpde=doc_ce->user_data;
+    Silent;
+    st=MStrPrint("Delete: %s",tmpde->full_name);
+    if (PopUpCancelOk(st))
+      Del(tmpde->full_name);
+    Free(st);
+    Silent(OFF);
+  } else if (doc_ce->type_u8==DOCT_TREE) {
+    tmpde=doc_ce->user_data;
+    Silent;
+    st=MStrPrint("Delete: %s",tmpde->full_name);
+    if (PopUpCancelOk(st))
+      DelTree(tmpde->full_name);
+    Free(st);
+    Silent(OFF);
+  }
+}
+
+U0 FMChgDsk(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    Silent;
+    DskChg(*tmpde->full_name);
+    Silent(OFF);
+  }
+}
+
+U0 FMMountISO(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_MENU_VAL && (tmpde=doc_ce->user_data))
+    MountFile(tmpde->full_name);
+}
+
+U0 FMUnmount(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  I64 drv_let;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    drv_let=*tmpde->full_name;
+    if (Let2BlkDev(drv_let)!=Let2BlkDev(':'))
+      Unmount(drv_let);
+  }
+}
+
+U0 FMFmtDrv(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  U8 *st=NULL;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    st=MStrPrint("Format Drive '%c'?\nAre You Sure?\n",*tmpde->full_name);
+    if (PopUpCancelOk(st)) {
+      Silent;
+      Fmt(*tmpde->full_name,,FALSE);
+      Silent(OFF);
+    }
+  }
+  Free(st);
+}
+
+U0 FMMakeISO(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    if (doc_ce->type_u8==DOCT_MENU_VAL)
+      tmpde=tmpde->parent;
+    if (tmpde && *tmpde->full_name) {
+      Silent;
+      RedSeaISO(,tmpde->full_name);
+      Silent(OFF);
+    }
+  }
+}
+
+U0 FMBurnISO(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  CDirEntry *tmpde;
+  if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde=doc_ce->user_data;
+  else
+    tmpde=NULL;
+  if (tmpde) {
+    while (tmpde->parent)
+      tmpde=tmpde->parent;
+    Silent;
+    DVDImageWrite(*tmpde->full_name);
+    Silent(OFF);
+  }
+}
+
+U0 FMCopy(CDoc *doc)
+{
+  CDoc *doc2=sys_clip_doc;
+  U8 *st;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e;
+  CDirEntry *tmpde,*tmpde1=NULL,*tmpde2;
+  Bool unlock_doc2=DocLock(doc2);
+  doc_e=doc2->head.next;
+
+  tmpde1=doc_ce->user_data;
+  if (doc_ce->type_u8==DOCT_MENU_VAL)
+    tmpde1=tmpde1->parent;
+  else if (doc_ce->type_u8!=DOCT_TREE)
+    tmpde1=NULL;
+  if (tmpde1) {
+    while (doc_e!=doc2) {
+      if (doc_e->type_u8==DOCT_MENU_VAL) {
+        tmpde=doc_e->user_data;
+        tmpde->user_data2|=DEF2_PROCESSED;
+        tmpde2=tmpde->parent;
+        if (!tmpde2 || !(tmpde2->user_data2&DEF2_PROCESSED)) {
+          Silent;
+          Copy(tmpde->full_name,tmpde1->full_name);
+          Silent(OFF);
+        }
+      } else if (doc_e->type_u8==DOCT_TREE) {
+        tmpde=doc_e->user_data;
+        tmpde->user_data2|=DEF2_PROCESSED;
+        tmpde2=tmpde->parent;
+        if (!tmpde2 || !(tmpde2->user_data2&DEF2_PROCESSED)) {
+          Silent;
+          if (*tmpde1->name)
+            st=MStrPrint("%s/%s",tmpde1->full_name,tmpde->name);
+          else
+            st=MStrPrint("%s%s",tmpde1->full_name,tmpde->name);
+          CopyTree(tmpde->full_name,st);
+          Free(st);
+          Silent(OFF);
+        }
+      }
+      doc_e=doc_e->next;
+    }
+  }
+  if (unlock_doc2)
+    DocUnlock(doc2);
+}
+
+#define FMR_INCLUDE             0
+#define FMR_ADAM_INCLUDE        1
+#define FMR_DELETE              2
+#define FMR_RENAME              3
+#define FMR_MKDIR               4
+#define FMR_PLAIN               5
+#define FMR_PASTE               6
+#define FMR_CHG_DSK             7
+#define FMR_FORMAT              8
+#define FMR_MOUNT_REDSEA_ISO_C  9
+#define FMR_UNMOUNT             10
+#define FMR_MAKE_REDSEA_ISO_C   11
+#define FMR_BURN_ISO            12
+#define FMR_HELP                13
+
+I64 PopUpFMRight(U8 *header=NULL,U8 *footer=NULL)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"$CM+LX,1,1 $$BT,\"INCLUDE                 \",LE=FMR_INCLUDE$"
+        "$CM+LX,29,0$$BT,\"ADAM INCLUDE            \",LE=FMR_ADAM_INCLUDE$"
+        "$CM+LX,1,3 $$BT,\"DELETE                  \",LE=FMR_DELETE$"
+        "$CM+LX,29,0$$BT,\"RENAME                  \",LE=FMR_RENAME$"
+        "$CM+LX,1,3 $$BT,\"MAKE DIRECTORY          \",LE=FMR_MKDIR$"
+        "$CM+LX,29,0$$BT,\"PLAIN-TEXT EDIT         \",LE=FMR_PLAIN$"
+        "$CM+LX,1,3 $$BT,\"PASTE CLIP FILES        \",LE=FMR_PASTE$"
+        "$CM+LX,29,0$$BT,\"CHANGE DISK(MOUNT IT)   \",LE=FMR_CHG_DSK$"
+        "$CM+LX,1,3 $$BT,\"FORMAT                  \",LE=FMR_FORMAT$"
+        "$CM+LX,1,3 $$BT,\"MOUNT ISO.C FILE        \","
+        "LE=FMR_MOUNT_REDSEA_ISO_C$"
+        "$CM+LX,29,0$$BT,\"UNMOUNT                 \",LE=FMR_UNMOUNT$"
+        "$CM+LX,1,3 $$BT,\"MAKE ISO.C (CD/DVD) FILE\",LE=FMR_MAKE_REDSEA_ISO_C$"
+        "$CM+LX,29,0$$BT,\"BURN ISO (CD/DVD) FILE  \",LE=FMR_BURN_ISO$"
+        "$CM+LX,1,3 $$BT,\"HELP                    \",LE=FMR_HELP$"
+        "$CM+LX,29,0$$BT,\"CANCEL                  \",LE=DOCM_CANCEL$\n");
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+U0 FMRightClick()
+{
+  switch (PopUpFMRight) {
+    case FMR_INCLUDE:
+      Msg(MSG_KEY_DOWN,0,0x3F0000003F);
+      break;
+    case FMR_ADAM_INCLUDE:
+      Msg(MSG_KEY_DOWN,0,0x23F0000023F);
+      break;
+    case FMR_DELETE:
+      Msg(MSG_KEY_DOWN,CH_CTRLY,0);
+      break;
+    case FMR_RENAME:
+      Msg(MSG_KEY_DOWN,'r',0);
+      break;
+    case FMR_MKDIR:
+      Msg(MSG_KEY_DOWN,'d',0);
+      break;
+    case FMR_PLAIN:
+      Msg(MSG_KEY_DOWN,CH_SHIFT_SPACE,0);
+      break;
+    case FMR_PASTE:
+      Msg(MSG_KEY_DOWN,0,SC_INS+SCF_SHIFT);
+      break;
+    case FMR_CHG_DSK:
+      Msg(MSG_KEY_DOWN,'c',0);
+      break;
+    case FMR_FORMAT:
+      Msg(MSG_KEY_DOWN,'f',0);
+      break;
+    case FMR_MOUNT_REDSEA_ISO_C:
+      Msg(MSG_KEY_DOWN,'i',0);
+      break;
+    case FMR_UNMOUNT:
+      Msg(MSG_KEY_DOWN,'u',0);
+      break;
+    case FMR_MAKE_REDSEA_ISO_C:
+      Msg(MSG_KEY_DOWN,'m',0);
+      break;
+    case FMR_BURN_ISO:
+      Msg(MSG_KEY_DOWN,'B',0);
+      break;
+    case FMR_HELP:
+      Msg(MSG_KEY_DOWN,CH_CTRLM,0x43200000432);
+      break;
+  }
+}
+
+U8 *fm_ms_str=NULL;
+U0 (*fp_old_final_scrn_update)(CDC *dc);
+
+U0 FMFinalScrnUpdate(CDC *dc)
+{
+  if (fm_ms_str) {
+    dc->color=LTRED;
+    GrPrint(dc,ms.pos.x,ms.pos.y,"%s",fm_ms_str);
+  }
+  (*fp_old_final_scrn_update)(dc);
+}
+
+public U8 *FileMgr(I64 mode=FM_NORMAL,CTask *mem_task=NULL)
+{//File manager. Also, used to choose files and dirs.
+  CDirEntry *head=NULL,*tmpde,*tmpde1,*tmpde2;
+  I64 sc,ch,arg1,arg2,msg_code;
+  CDoc *doc=NULL,*old_put_doc=DocPut,*old_display_doc=DocDisplay;
+  U8 *res=NULL,*st,*st2,*old_cur_dir=DirCur;
+  CDocEntry *doc_ce=NULL,*doc_e;
+  Bool okay;
+
+  SettingsPush; //See SettingsPush
+  fp_old_final_scrn_update=gr.fp_final_scrn_update;
+  MenuFilePush("::/Doc/FileMgrPullDown.DD");
+  FMRebuildDoc(&doc,&head,mode);
+  if (tmpde1=Cd2DirEntry(head,old_cur_dir))
+    doc->cur_entry=tmpde1->user_data;
+  while (tmpde1) {
+    if (tmpde1->attr&RS_ATTR_DIR)
+      tmpde1->user_data(CDocEntry *)->de_flags&=~DOCEF_CHECKED_COLLAPSED;
+    tmpde1=tmpde1->parent;
+  }
+  do {
+    DocUnlock(doc);
+    do msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_UP);
+    while (Fs!=sys_focus_task);
+    DocLock(doc);
+    switch (msg_code) {
+      case MSG_MS_R_UP:
+        DocUnlock(doc);
+        FMRightClick;
+        DocLock(doc);
+        break;
+      case MSG_MS_L_DOWN:
+        doc_ce=doc->cur_entry;
+        fm_ms_str=doc_ce->tag;
+        gr.fp_final_scrn_update=&FMFinalScrnUpdate;
+        break;
+      case MSG_MS_L_UP:
+        if (doc_ce) {
+          gr.fp_final_scrn_update=fp_old_final_scrn_update;
+          if (WinCursorPosSet(Fs,arg1+Fs->pix_left+Fs->scroll_x,
+                arg2+Fs->pix_top+Fs->scroll_y,TRUE)) {
+            doc_e=doc->cur_entry;
+            if (doc_e!=doc_ce) {
+              st2=NULL;
+              if (doc_e->type_u8==DOCT_MENU_VAL) {
+                tmpde1=doc_e->user_data;
+                if (tmpde1=tmpde1->parent)
+                  st2=StrNew(tmpde1->full_name);
+              } else if (doc_e->type_u8==DOCT_TREE) {
+                tmpde1=doc_e->user_data;
+                st2=StrNew(tmpde1->full_name);
+              }
+              if (st2 && doc_ce->type_u8==DOCT_MENU_VAL) {
+                tmpde=doc_ce->user_data;
+                Silent;
+                Move(tmpde->full_name,st2);
+                Silent(OFF);
+                FMRebuildDoc(&doc,&head,mode);
+              } else if (st2 && doc_ce->type_u8==DOCT_TREE) {
+                tmpde=doc_ce->user_data;
+                okay=TRUE;
+                tmpde2=tmpde1;
+                while (tmpde2) {
+                  if (tmpde2!=tmpde)
+                    tmpde2=tmpde2->parent;
+                  else {
+                    okay=FALSE;
+                    break;
+                  }
+                }
+                if (okay) {
+                  if (*tmpde1->name)
+                    st=MStrPrint("%s/%s",tmpde1->full_name,tmpde->name);
+                  else
+                    st=MStrPrint("%s%s",tmpde1->full_name,tmpde->name);
+                  if (StrCmp(tmpde->full_name,st)) {
+                    Silent;
+                    CopyTree(tmpde->full_name,st);
+                    DelTree(tmpde->full_name);
+                    Silent(OFF);
+                    FMRebuildDoc(&doc,&head,mode);
+                  }
+                  Free(st);
+                }
+              }
+              Free(st2);
+              FlushMsgs;
+            } else
+              if (doc_e->type_u8==DOCT_MENU_VAL) {
+                DocUnlock(doc);
+                Ed(doc_e->user_data(CDirEntry *)->full_name);
+                DocLock(doc);
+              }
+            doc_ce=NULL;
+          }
+        }
+        break;
+      case MSG_KEY_DOWN:
+        doc_ce=NULL;
+        ch=arg1; sc=arg2;
+        if (sc.u8[0]==SC_DELETE && !(sc&(SCF_SHIFT|SCF_CTRL)))
+          ch=CH_CTRLY;
+        if (ch && sc&SCF_ALT) goto fm_regular_key;
+        switch (ch) {
+          case '\n':
+            DocUnlock(doc);
+            FMRightClick;
+            DocLock(doc);
+            break;
+          start:
+            DocUnlock(doc);
+            case CH_CTRLV:
+              FMCopy(doc);
+              break;
+            case 'r':
+              FMRename(doc);
+              break;
+            case 'd':
+              FMMkDir(doc);
+              break;
+            case CH_CTRLY:
+              FMDelete(doc);
+              break;
+            case 'c':
+              FMChgDsk(doc);
+              break;
+            case 'i':
+              FMMountISO(doc);
+              break;
+            case 'u':
+              FMUnmount(doc);
+              break;
+            case 'm':
+              FMMakeISO(doc);
+              break;
+            case 'B':
+              FMBurnISO(doc);
+              break;
+            case 'f':
+              FMFmtDrv(doc);
+              break;
+          end:
+            FMRebuildDoc(&doc,&head,mode);
+            break;
+          case CH_SHIFT_ESC:
+            break;
+          case CH_SPACE:
+            if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
+              DocUnlock(doc);
+              Ed(doc->cur_entry->user_data(CDirEntry *)->full_name);
+              DocLock(doc);
+            } else
+              goto fm_regular_key;
+            break;
+          case CH_SHIFT_SPACE:
+            if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
+              DocUnlock(doc);
+              Plain(doc->cur_entry->user_data(CDirEntry *)->full_name);
+              DocLock(doc);
+            } else
+              goto fm_regular_key;
+            break;
+          case CH_ESC:
+            doc_ce=doc->cur_entry;
+            tmpde=doc_ce->user_data;
+            if (mode==FM_PICK_FILE && doc_ce->type_u8==DOCT_MENU_VAL)
+              res=StrNew(tmpde->full_name,mem_task);
+            else if (mode==FM_PICK_DIR) {
+              if (doc_ce->type_u8==DOCT_TREE)
+                res=StrNew(tmpde->full_name,mem_task);
+              else if (doc_ce->type_u8==DOCT_MENU_VAL &&
+                    (tmpde=tmpde->parent))
+                res=StrNew(tmpde->full_name,mem_task);
+            }
+            break;
+          default:
+            if (sc.u8[0]==SC_INS && sc&SCF_SHIFT && !(sc&SCF_CTRL)) {
+              FMCopy(doc);
+              FMRebuildDoc(&doc,&head,mode);
+            } else if (sc.u8[0]==SC_F5) {
+              if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
+                tmpde=doc->cur_entry->user_data;
+                DocUnlock(doc);
+                if (sc&SCF_SHIFT)
+                  AdamFile(tmpde->full_name);
+                else
+                  PopUpFile(tmpde->full_name);
+                DocLock(doc);
+              }
+            } else {
+fm_regular_key:
+              DocUnlock(doc);
+              PutKey(ch,sc);
+              DocLock(doc);
+            }
+        }
+        break;
+    }
+  } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  gr.fp_final_scrn_update=fp_old_final_scrn_update;
+  Fs->put_doc    =old_put_doc;
+  Fs->display_doc=old_display_doc;
+  SettingsPop;
+  DocDel(doc);
+  DirTreeDel(head);
+  Cd(old_cur_dir);
+  Free(old_cur_dir);
+  if (mode!=FM_NORMAL && !res)
+    res=StrNew("",mem_task);
+  MenuPop;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ABlkDev/MakeABlkDev.HC.HTML b/public/Wb/Home/Src/Adam/ABlkDev/MakeABlkDev.HC.HTML new file mode 100755 index 0000000..399fdde --- /dev/null +++ b/public/Wb/Home/Src/Adam/ABlkDev/MakeABlkDev.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "ADskA"
+#include "ADskB"
+#include "DskPrt"
+#include "Mount"
+#include "DskChk"
+#include "FileMgr"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/ABlkDev/Mount.HC.HTML b/public/Wb/Home/Src/Adam/ABlkDev/Mount.HC.HTML new file mode 100755 index 0000000..34d6cb2 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ABlkDev/Mount.HC.HTML @@ -0,0 +1,190 @@ + + + + + + + + + + + +
+#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
+U8 Mount2(U8 boot_drv_let,CDoc *_doc,Bool _caller_is_prtdsk)
+{//If _doc, called by ::/Kernel/KCfg.HC else called by Mount().
+  I64 cnt,total=0,num_hints,drv_let,type,unit,prt_num;
+  U8 blks_buf[STR_LEN],addr_buf[STR_LEN],base0_buf[STR_LEN],base1_buf[STR_LEN],
+        *filename=NULL,*filename2=NULL,res=0;
+  CATARep *head=NULL,*tmpha;
+  Bool whole_drv,make_free;
+  CDoc *doc;
+  if (boot_drv_let)
+    boot_drv_let=Let2Let(boot_drv_let);
+  do {
+    cnt=0;
+    if (!_doc)
+      DrvRep;
+    "\n****** Mount Drives ******\n"
+          "$GREEN$A$FG$-$GREEN$B$FG$ are RAM drives.\n"
+          "$GREEN$C$FG$-$GREEN$L$FG$ are ATA hard drives.\n"
+          "$GREEN$M$FG$-$GREEN$P$FG$ are ISO file read drives.\n"
+          "$GREEN$Q$FG$-$GREEN$S$FG$ are ISO file write drives.\n"
+          "$GREEN$T$FG$-$GREEN$Z$FG$ are ATAPI CD/DVD drives.\n"
+          "\nDrive Letter ($PURPLE$<ENTER>$FG$ to exit):";
+    drv_let=Let2Let(GetChar);
+    '\n';
+    if (type=Let2BlkDevType(drv_let)) {
+      whole_drv=FALSE;
+      if (_doc) { //Called by ::/Kernel/KCfg.HC
+        doc=_doc;
+        make_free=FALSE;
+      } else { //Called by Mount()
+        doc=DocNew;
+        DocPrint(doc,"CBlkDev *bd;\n");
+        make_free=TRUE;
+      }
+      unit=0;
+      prt_num=I64_MIN;
+      switch (type) {
+        case BDT_RAM:
+          "Addr of RAM disk ($PURPLE$<ENTER>$FG$ to MAlloc):";
+          GetS(addr_buf,STR_LEN);
+        case BDT_ISO_FILE_WRITE:
+          "Blks of 512 bytes:";
+          GetS(blks_buf,STR_LEN);
+          break;
+        case BDT_ISO_FILE_READ:
+          filename=GetStr("File Name:");
+          break;
+        case BDT_ATA:
+          prt_num=GetI64("Partition Num (Default=All):",prt_num);
+        case BDT_ATAPI:
+          num_hints=ATARep(,,&head);
+          if (type==BDT_ATAPI && boot_drv_let)
+            "<ENTER> to use booted CD/DVD\n"; //Only ::/Kernel/KCfg.HC
+          do {
+            if (num_hints)
+              "Enter dev number or\nport with $PURPLE$0x$FG$ prefix.\n"
+                    "I/O Port Base0:\n";
+            else
+              "Include $PURPLE$0x$FG$ prefix.\nI/O Port Base0:\n";
+            GetS(base0_buf,STR_LEN);
+          } while (!Str2I64(base0_buf) && (type!=BDT_ATAPI || !boot_drv_let));
+          if (1<=Str2I64(base0_buf)<=num_hints) {
+            tmpha=ATARepFind(head,Str2I64(base0_buf));
+            StrPrint(base0_buf,"0x%X",tmpha->base0);
+            StrPrint(base1_buf,"0x%X",tmpha->base1);
+            unit=tmpha->unit;
+          } else if (type!=BDT_ATAPI || *base0_buf) {
+            if (type==BDT_ATAPI)
+              StrCpy(base1_buf,"0");
+            else
+              do {
+                "I/O Port Base1:\n";
+                GetS(base1_buf,STR_LEN);
+              } while (!Str2I64(base1_buf));
+            do {
+              "\t$PURPLE$0$FG$=Master\n\t$PURPLE$1$FG$=Slave\nUnit:";
+              unit=GetChar-'0';
+            } while (!(0<=unit<=1));
+            '\n';
+          }
+          LinkedLstDel(head);
+          break;
+      }
+      DocPrint(doc,"bd=BlkDevNextFreeSlot(\'%C\',%d);bd->unit=%d;\n",
+            drv_let,type,unit);
+      switch (type) {
+        case BDT_RAM:
+          if (!*addr_buf) StrCpy(addr_buf,"0");
+          DocPrint(doc,"bd->RAM_dsk=%s;\n",addr_buf);
+        case BDT_ISO_FILE_WRITE:
+          if (!*blks_buf) StrCpy(blks_buf,"0");
+          DocPrint(doc,"bd->max_blk=(%s)-1;\n",blks_buf);
+          DocPrint(doc,"bd->drv_offset=19<<2+"
+                "(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
+          break;
+        case BDT_ISO_FILE_READ:
+          filename2=FileNameAbs(filename);
+          DocPrint(doc,"bd->file_dsk_name=AStrNew(\"%s\");\n",filename2);
+          DocPrint(doc,"bd->drv_offset=19<<2+"
+                "(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
+          break;
+        case BDT_ATA:
+        case BDT_ATAPI:
+          if (type==BDT_ATAPI && !*base0_buf) {
+            DocPrint(doc,"GetBaseUnit(bd);\n"); //Only ::/Kernel/KCfg.HC
+            if (drv_let==boot_drv_let)
+              make_free=TRUE;
+          } else
+            DocPrint(doc,"bd->base0=%s;bd->base1=%s;\n",base0_buf,base1_buf);
+          if (type==BDT_ATA && _caller_is_prtdsk) {
+            "\nReformat WHOLE drive!";
+            whole_drv=YorN;
+          }
+          break;
+      }
+      DocPrint(doc,"BlkDevAdd(bd,%d,%d,%d);\n",prt_num,whole_drv,make_free);
+      if (_doc) //Called by ::/Kernel/KCfg.HC
+        cnt++;
+      else { //Called by Mount()
+        if ((cnt=ExeDoc(doc)) && whole_drv) {
+          if (_caller_is_prtdsk) {
+            res=drv_let;
+            DskPrt(drv_let,1.0); //First mount whole drive.
+          } else
+            DskPrt(drv_let);
+        }
+        DocDel(doc);
+      }
+    }
+    total+=cnt;
+  } while (cnt && !_caller_is_prtdsk ||
+        !total && _doc); //At least 1 if Called by ::/Kernel/KCfg.HC
+  Free(filename);
+  Free(filename2);
+  return res;
+}
+
+public U8 Mount(Bool caller_is_prtdsk=FALSE)
+{//Mount drives. Called from DskPrt(Mount).
+  return Mount2(0,NULL,caller_is_prtdsk);
+}
+
+public U0 Unmount(U8 drv_let=0)
+{//Unmount drive(s).
+  BlkDevDel(Let2BlkDev(drv_let));
+}
+
+public U8 MountFile(U8 *filename)
+{//Mount ISO.C file.
+  U8 *filename2=ExtDft(filename,"ISO.C"),*filename3=FileNameAbs(filename2);
+  CDrv *dv=DrvMakeFreeSlot(DrvNextFreeLet('M')); //First BDT_ISO_FILE_READ
+  CBlkDev *bd=BlkDevNextFreeSlot(dv->drv_let,BDT_ISO_FILE_READ);
+  bd->drv_offset=19<<2+(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
+  bd->file_dsk_name=AStrNew(filename3);
+  BlkDevAdd(bd,,TRUE,TRUE);
+  Free(filename3);
+  Free(filename2);
+  return dv->drv_let;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ADbg.HC.HTML b/public/Wb/Home/Src/Adam/ADbg.HC.HTML new file mode 100755 index 0000000..e388230 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ADbg.HC.HTML @@ -0,0 +1,301 @@ + + + + + + + + + + + +
+#help_index "Debugging/Dump"
+Bool ClassRep2(CDoc *doc,U8 *_d,U8 *class_name=lastclass,
+        I64 depth,I64 max_depth,Bool dynamic,I64 types=HTT_CLASS,I64 offset=0)
+{//See ::/Demo/LastClass.HC.
+  I64 i,j,stars,*ptr;
+  CMemberLst *ml;
+  CDocEntry *doc_e;
+  Bool unlock;
+  CHashClass *tmpc,*tmpc2;
+  if (depth>=max_depth) return TRUE;
+  if (!(tmpc=HashFind(class_name,Fs->hash_table,types))) {
+    DocPrint(doc,"Class Not Found.\n");
+    return FALSE;
+  }
+  if (!ChkPtr(_d) || !ChkPtr(_d(U8 *)+tmpc->size)) {
+    DocPrint(doc,"Bad Ptr:%016X\n",_d);
+    return FALSE;
+  }
+  if (tmpc->base_class && !ClassRep2(doc,_d,tmpc->base_class->str,
+        depth,max_depth,dynamic,types,offset))
+    return FALSE;
+  unlock=DocLock(doc);
+  DocPrint(doc,"Class:\"%s\"\n",class_name);
+  ml=tmpc->member_lst_and_root;
+  while (ml) {
+    tmpc2=ml->member_class;
+    ptr=_d(U8 *)+ml->offset;
+    DocPrint(doc,"%08X ",ptr(U8 *)+offset);
+    stars=tmpc2->ptr_stars_cnt;
+    tmpc2=OptClassFwd(tmpc2);
+    tmpc2-=tmpc2->ptr_stars_cnt;
+    if (tmpc2->type & HTT_INTERNAL_TYPE) {
+      DocPrint(doc,"$GREEN$%-20ts:$FG$",ml->str);
+      if (stars==1 && (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8)) {
+        ptr=*ptr;
+        if (ChkPtr(ptr)) {
+          if (dynamic) {
+            doc_e=DocPrint(doc,"$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$\n");
+            doc_e->data=ptr;
+            DocDataFmt(doc,doc_e);
+          } else
+            DocPrint(doc,"%40ts\n",ptr);
+        }
+      } else if (!stars) {
+        j=MinI64(ml->dim.total_cnt,32);
+        if (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8) {
+          if (j==1) {
+            if (dynamic) {
+              doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U8,A=\"%%c\"$\n");
+              doc_e->data=ptr;
+            } else
+              DocPrint(doc,"%c\n",*ptr(U8 *));
+          } else {
+            if (dynamic) {
+              doc_e=DocPrint(doc,"$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$\n");
+              doc_e->data=ptr;
+              DocDataFmt(doc,doc_e);
+            } else
+              DocPrint(doc,"%40ts\n",ptr);
+          }
+        }
+        for (i=0;i<j;i++) {
+          switch (tmpc2->raw_type) {
+            case RT_I0:
+            case RT_U0:
+              break;
+            case RT_I8:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I8,A=\"%%02X\"$ ");
+                doc_e->data=ptr(I8 *)++;
+              } else
+                DocPrint(doc,"%02X ",*ptr(I8 *)++);
+              break;
+            case RT_U8:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U8,A=\"%%02X\"$ ");
+                doc_e->data=ptr(U8 *)++;
+              } else
+                DocPrint(doc,"%02X ",*ptr(U8 *)++);
+              break;
+            case RT_I16:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I16,A=\"%%04X\"$ ");
+                doc_e->data=ptr(I16 *)++;
+              } else
+                DocPrint(doc,"%04X ",*ptr(I16 *)++);
+              break;
+            case RT_U16:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U16,A=\"%%04X\"$ ");
+                doc_e->data=ptr(U16 *)++;
+              } else
+                DocPrint(doc,"%04X ",*ptr(U16 *)++);
+              break;
+            case RT_I32:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I32,A=\"%%08X\"$ ");
+                doc_e->data=ptr(I32 *)++;
+              } else
+                DocPrint(doc,"%08X ",*ptr(I32 *)++);
+              break;
+            case RT_U32:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U32,A=\"%%08X\"$ ");
+                doc_e->data=ptr(U32 *)++;
+              } else
+                DocPrint(doc,"%08X ",*ptr(U32 *)++);
+              break;
+            case RT_U64:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=U64,A=\"%%08X\"$ ");
+                doc_e->data=ptr(U64 *)++;
+              } else
+                DocPrint(doc,"%08X ",*ptr(U64 *)++);
+              break;
+            case RT_F64:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=F64,A=\"%%16g\"$ ");
+                doc_e->data=ptr(F64 *)++;
+              } else
+                DocPrint(doc,"%16g ",*ptr(I64 *)++);
+              break;
+            default:
+              if (dynamic) {
+                doc_e=DocPrint(doc,"$DA-TRM+RD+UD,A=\"%%016X\"$ ");
+                doc_e->data=ptr(I64 *)++;
+              } else
+                DocPrint(doc,"%016X ",*ptr(I64 *)++);
+          }
+          if (dynamic)
+            DocDataFmt(doc,doc_e);
+        }
+        if (j<ml->dim.total_cnt)
+          DocPrint(doc,"...");
+      } else
+        DocPrint(doc,"%016X",*ptr);
+      DocPrint(doc,"\n");
+    } else {
+      if (depth<2) {
+        if (stars==1 && !ChkPtr(*ptr))
+          DocPrint(doc,"%-20ts:%016X\n",ml->str,*ptr);
+        else {
+          DocPrint(doc,"$TR,\"%s\"$\n",ml->str);
+          DocPrint(doc,"$ID,2$");
+          if (!stars)
+            ClassRep2(doc,ptr,tmpc2->str,depth+1,max_depth,dynamic);
+          else if (stars==1)
+            ClassRep2(doc,*ptr,tmpc2->str,depth+1,max_depth,dynamic);
+          DocPrint(doc,"$ID,-2$");
+        }
+      } else
+        DocPrint(doc,"%-20ts\n",ml->str);
+    }
+    ml=ml->next;
+  }
+  if (unlock)
+    DocUnlock(doc);
+  return TRUE;
+}
+
+public U0 ClassRep(U8 *_d,U8 *class_name=lastclass,
+        I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
+{//Displays members of a record by using the compiler's info.
+  CDoc *doc;
+  if (IsRaw)
+    doc=DocNew;
+  else {
+    DocMax;
+    doc=DocPut;
+  }
+  if (fun)
+    ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_FUN,offset);
+  else
+    ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_CLASS,offset);
+  DocPrint(doc,"\n");
+  DocRecalc(doc);
+  if (IsRaw) {
+    DocDump(doc,100000);
+    DocDel(doc);
+  }
+}
+
+public U0 ClassRepD(U8 *_d,U8 *class_name=lastclass,
+        I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
+{//Dynamic ClassRep. Uses hex_ed widgit for live changes.
+  CDoc *doc;
+  if (IsRaw)
+    doc=DocNew;
+  else {
+    DocMax;
+    doc=DocPut;
+  }
+  if (fun)
+    ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_FUN,offset);
+  else
+    ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_CLASS,offset);
+  DocPrint(doc,"\n");
+  DocRecalc(doc);
+  if (IsRaw) {
+    DocDump(doc,100000);
+    DocDel(doc);
+  }
+}
+
+U0 UpdateRegVarImg(CHashFun *tmpf,U8 *_b,CTask *task)
+{
+  CMemberLst *ml;
+  CHashClass *tmpc;
+  ml=tmpf->member_lst_and_root;
+  while (ml) {
+    if (ml->reg!=REG_NONE) {
+      tmpc=OptClassFwd(ml->member_class);
+      MemCpy(_b+ml->offset,TaskRegAddr(task,ml->reg),tmpc->size);
+    }
+    ml=ml->next;
+  }
+}
+
+public U0 FunRep(U8 *st,U8 *rbp=NULL,I64 max_depth=2,CTask *task=NULL)
+{//Shows names and vals of a fun's local vars using compiler's info.
+  I64 size;
+  U8 *img;
+  CHashFun *tmpf=HashFind(st,Fs->hash_table,HTT_FUN);
+  CMemberLst *tmpm;
+  if (tmpf) {
+    if (rbp) {
+      if (task) {
+//tmpf->size is negative.  It's the bottom
+        //of the fun local var space relative to RBP .
+        size=tmpf->arg_cnt*8-tmpf->size+16;
+
+        img=MAlloc(size);
+        MemCpy(img,rbp+tmpf->size,size);
+        UpdateRegVarImg(tmpf,img-tmpf->size,task);
+        ClassRep(img-tmpf->size,st,max_depth,TRUE,rbp-img+tmpf->size);
+        Free(img);
+      } else
+        ClassRep(rbp,st,max_depth,TRUE);
+    } else {
+      tmpm=tmpf->member_lst_and_root;
+      while (tmpm) {
+        if (0<=tmpm->reg<REG_REGS_NUM)
+          "%08Z %s\n",tmpm->reg,"ST_U64_REGS",tmpm->str;
+        else
+          "%08tX %s\n",tmpm->offset,tmpm->str;
+        tmpm=tmpm->next;
+      }
+      "%08tX Stk Size\n",tmpf->size;
+    }
+  }
+}
+
+#help_index "Debugging/Unassemble"
+public U0 Uf(U8 *st)
+{//Unassembles a named fun
+  I64 i;
+  CHashSrcSym *tmpf;
+  CDbgInfo *dbg_info;
+  if (tmpf=HashFind(st,Fs->hash_table,HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+    if (tmpf->type&HTT_FUN)
+      FunRep(st);
+    if (dbg_info=tmpf->dbg_info) {
+      i=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+            -dbg_info->body[0];
+      Un(dbg_info->body[0],i);
+      "Code Size:%04X\n",i;
+    } else
+      U(HashVal(tmpf));
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ADefine.HC.HTML b/public/Wb/Home/Src/Adam/ADefine.HC.HTML new file mode 100755 index 0000000..c108a05 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ADefine.HC.HTML @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+#help_index "Define;Char/Define"
+
+U0 LoadDocDefines()
+{
+  CBinFile *bfh=mem_boot_base-sizeof(CBinFile);
+
+  DefinePrint("DD_OS_NAME_VERSION","TempleOS V%0.2f",sys_os_version);
+  DefinePrint("DD_TEMPLEOS_AGE","%0.1f",
+        (Now-Str2Date("8/1/2003"))/ToF64(1<<32)/CDATE_YEAR_DAYS);
+
+  DefinePrint("DD_KERNEL","%08X",bfh);
+  bfh(I64)+=bfh->file_size-1;
+  DefinePrint("DD_KERNEL_END","%08X",bfh);
+
+  //DD_BOOT_HIGH_LOC_DVD
+
++] LineRep
+
+  DefinePrint("DD_MP_VECT","%08X",MP_VECT_ADDR);
+  DefinePrint("DD_MP_VECT_END","%08X",
+        MP_VECT_ADDR+COREAP_16BIT_INIT_END-COREAP_16BIT_INIT-1);
+
+  DefinePrint("DD_SYS_FIXED_AREA_BASE","%08X",SYS_FIXED_AREA);
+  DefinePrint("DD_SYS_FIXED_AREA_END","%08X",
+        SYS_FIXED_AREA+sizeof(CSysFixedArea)-1);
+  DefinePrint("DD_MEM_HEAP_BASE","%08X",mem_heap_base);
+  DefinePrint("DD_MEM_HEAP_LIMIT","%08X",mem_heap_limit);
+  DefinePrint("DD_MEM_MIN_MEG","%dMeg",MEM_MIN_MEG);
+  DefinePrint("DD_UNCACHED_ALIAS","%010X",dev.uncached_alias);
+  DefinePrint("DD_PHYSICAL_SPACE_END","%010X",
+        mem_physical_space-1);
+  DefinePrint("DD_MAPPED_SPACE_END","%010X",
+        mem_mapped_space-1);
+  DefinePrint("DD_JIFFY_HZ","%dHz",JIFFY_FREQ);
+}
+
+LoadDocDefines;
+
+ diff --git a/public/Wb/Home/Src/Adam/AExts.HC.HTML b/public/Wb/Home/Src/Adam/AExts.HC.HTML new file mode 100755 index 0000000..9e0cbab --- /dev/null +++ b/public/Wb/Home/Src/Adam/AExts.HC.HTML @@ -0,0 +1,126 @@ + + + + + + + + + + + +
+extern U0 ACDDef(I64 n,CTask *parent=NULL);
+extern U0 ACDDefsPut(CDoc *doc=NULL,U8 *st,I64 num=-1);
+extern U0 ACDFillin(I64 n);
+extern U0 ACFillIn(I64 n);
+extern U0 ACMan(I64 n,CTask *parent_task=NULL);
+extern I64 AdamFile(U8 *filename,Bool warn_ext=TRUE);
+extern Bool AutoComplete(Bool val=OFF);
+extern U0 ClipDel();
+extern CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type);
+extern Bool CtrlInside(CCtrl *c,I64 x,I64 y);
+extern U8 *DC2Sprite(CDC *tmpb);
+extern U0 DocBinDel(CDoc *doc,CDocBin *b);
+extern U0 DocBinsValidate(CDoc *doc);
+extern U0 DocBottom(CDoc *doc=NULL);
+extern U0 DocCenter(CDoc *doc=NULL,I64 recalc_flags=RECALCt_NORMAL);
+extern U0 DocClear(CDoc *doc=NULL,Bool clear_holds=FALSE);
+extern Bool DocCursor(Bool show=OFF,CDoc *doc=NULL);
+extern U0 DocD(U8 *buf,I64 cnt=0x80);
+extern U0 DocDataFmt(CDoc *doc,CDocEntry *doc_e,I64 d=DOCM_CANCEL);
+extern U0 DocDel(CDoc *doc);
+extern CDoc *DocDisplay(CTask *task=NULL);
+extern U0 DocDump(CDoc *doc,I64 uS_delay=0);
+extern CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e);
+extern U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e);
+extern Bool DocForm(U8 *_d,U8 *class_name=lastclass,
+        I64 dof_flags=0,U8 *header=NULL,U8 *footer=NULL);
+extern U0 DocHelpIdx(CDoc *doc,U8 *idx);
+extern Bool DocHighlightCursor(Bool show=OFF,CDoc *doc=NULL);
+extern U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2);
+extern U0 DocInsEntry(CDoc *doc,CDocEntry *doc_e);
+extern Bool DocLock(CDoc *doc);
+extern I64 DocMax(I64 i=I64_MAX);
+extern CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL);
+extern CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...);
+extern CDoc *DocPut(CTask *task=NULL);
+extern CDoc *DocRead(U8 *name=NULL,I64 flags=0);
+extern Bool DocRecalc(CDoc *doc,I64 recalc_flags=RECALCt_NORMAL);
+extern U0 DocRst(CDoc *doc,Bool is_old);
+extern CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL);
+extern U0 DocTop(CDoc *doc=NULL);
+extern Bool DocUnlock(CDoc *doc);
+extern U0 DocUpdateTaskDocs(CTask *task);
+extern U0 DrawCtrls(CTask *task);
+extern Bool Ed(U8 *link_st,I64 edf_dof_flags=0);
+extern U0 EdCodeTools(CDoc *doc);
+extern U8 *EdSprite(I64 bin_num);
+extern I64 ExeDoc(CDoc *doc,I64 ccf_flags=0);
+extern I64 FindWiz();
+extern I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX);
+extern Bool GrPlot0(CDC *dc,I64 x,I64 y);
+extern CMenuEntry *MenuEntryFind(CMenu *haystack_menu,U8 *needle_full_name);
+extern CMenu *MenuFilePush(U8 *filename);
+extern U0 MenuPop();
+extern CMenu *MenuPush(U8 *st);
+extern U8 Mount(Bool caller_is_prtdsk=FALSE);
+extern CTask *Noise(I64 mS,F64 min_ona,F64 max_ona);
+extern Bool Plain(U8 *filename,I64 edf_dof_flags=0);
+extern Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL);
+extern I64 PopUpColor(U8 *header=NULL,
+        Bool allow_transparent=TRUE,Bool allow_dft=TRUE);
+extern I64 PopUpColorDither(U8 *header=NULL);
+extern I64 PopUpColorLighting(U8 *header=NULL);
+extern I64 PopUpFile(U8 *filename,
+        Bool warn_ext=TRUE,CTask *parent=NULL,CTask **_pu_task=NULL);
+extern Bool PopUpForm(U8 *_d,U8 *class_name=lastclass,
+        I64 dof_flags=DOF_SIZE_MIN,U8 *header=NULL,U8 *footer=NULL);
+extern I64 PopUpGetI64(U8 *msg,I64 dft,I64 lo=I64_MIN,I64 hi=I64_MAX);
+extern U8 *PopUpGetStr(U8 *header=NULL);
+extern I64 PopUpMenu(CDoc *doc,I64 dof_flags=0);
+extern Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL);
+extern Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL);
+extern I64 PopUpRangeI64(
+        I64 lo,I64 hi,I64 step=1,U8 *header=NULL,U8 *footer=NULL);
+extern Bool PopUpTransform(I64 *r);
+extern I64 RedSeaISO(U8 *_iso_filename=NULL,U8 *_src_dir,
+        U8 *_stage2_filename=NULL);
+extern U0 Refresh(I64 cnt=1,Bool force=FALSE);
+extern U0 RegOneTimePopUp(I64 flag_num,U8 *msg);
+extern Bool RegWrite(U8 *path,U8 *fmt,...);
+extern U0 SettingsPop(CTask *task=NULL,I64 flags=0);
+extern CTaskSettings *SettingsPush(CTask *task=NULL,I64 flags=0);
+extern U0 TemplateCtrlSlider(CDoc *doc);
+extern Bool View();
+extern U0 ViewAnglesDel(CTask *task=NULL);
+extern CCtrl *ViewAnglesNew(CTask *task=NULL);
+extern Bool WinBorder(Bool val=OFF,CTask *task=NULL);
+extern CDoc *WinCursorPosSet(CTask *task,I64 msx,I64 msy,Bool set_cursor=TRUE);
+extern Bool WinHorz(I64 left,I64 right,CTask *task=NULL);
+extern U0 WinMax(CTask *task=NULL);
+extern U0 WinScrollNull(CTask *task,CD3I64 *s);
+extern U0 WinScrollRestore(CTask *task,CD3I64 *s);
+extern U0 WinScrollsInit(CTask *task);
+extern I64 WinToTop(CTask *task=NULL,Bool update_z_buf=TRUE);
+extern Bool WinVert(I64 top,I64 bottom,CTask *task=NULL);
+extern CWinMgrGlbls winmgr;
+
+ diff --git a/public/Wb/Home/Src/Adam/AHash.HC.HTML b/public/Wb/Home/Src/Adam/AHash.HC.HTML new file mode 100755 index 0000000..9d437d2 --- /dev/null +++ b/public/Wb/Home/Src/Adam/AHash.HC.HTML @@ -0,0 +1,462 @@ + + + + + + + + + + + +
+#help_index "Info;Hash/System;Cmd Line (Typically)"
+class CWho
+{
+  CHashGeneric *h;
+  U8 *idx;
+};
+
+I64 HashEntriesCompare(CWho *h1,CWho *h2)
+{
+  I64 i1,i2;
+  if (i1=StrCmp(h1->h->str,h2->h->str))
+    return i1;
+  i1=HashTypeNum(h1->h);
+  i2=HashTypeNum(h2->h);
+  return i1-i2;
+}
+
+I64 HashEntriesCompare2(CWho *h1,CWho *h2)
+{
+  CHashFun *tmpf1=h1->h,*tmpf2=h2->h;
+  I64 i1=HashVal(tmpf1),i2=HashVal(tmpf2);
+  if (i1==i2) {
+    i1=HashTypeNum(tmpf1);
+    i2=HashTypeNum(tmpf2);
+    if (i1==i2)
+      return StrCmp(tmpf1->str,tmpf2->str);
+  }
+  return i1-i2;
+}
+
+I64 HelpIndexCnt(U8 *ptr,U8 *idx)
+{
+  I64 cnt=0,ch,idx_len=StrLen(idx);
+  while (*ptr) {
+    if (!StrNCmp(ptr,idx,idx_len))
+      cnt++;
+    while (ch=*ptr++)
+      if (ch==';')
+        break;
+    if (!ch)
+      ptr--;
+  }
+  return cnt;
+}
+
+U8 *HelpIndexStr(U8 **_ptr,U8 *idx)
+{
+  U8 *ptr=*_ptr,*ptr2,*res;
+  I64 ch,idx_len=StrLen(idx);
+  while (*ptr) {
+    ptr2=ptr;
+    while (ch=*ptr++)
+      if (ch==';')
+        break;
+    if (!ch)
+      ptr--;
+    *_ptr=ptr;
+    if (!StrNCmp(ptr2,idx,idx_len)) {
+      if (ch==';')
+        ptr--;
+      *ptr=0;
+      res=StrNew(ptr2);
+      *ptr=ch;
+      return res;
+    }
+  }
+  return NULL;
+}
+
+U8 *HelpComment(CTask *task,CHash *tmph,U8 *_src_link)
+{
+  CDoc *doc;
+  CDocEntry *doc_e;
+  U8 *res=NULL,*ptr,*ptr2,*src_link=StrNew(_src_link);
+
+  if (*src_link=='F' && src_link[2]==':')
+    *src_link='P';
+  XTalkWait(task,"Ed(0x%X,DOF_DONT_WINMGR_SYNC|DOF_DONT_SHOW);\n",src_link);
+  Free(src_link);
+
+  doc=DocPut(task);
+  doc_e=doc->cur_entry;
+  if (tmph->type&HTT_FUN) {
+    if (Bt(&tmph(CHashFun *)->flags,Ff__EXTERN) ||
+          Bt(&tmph(CHashFun *)->flags,Ff_INTERNAL))
+      while (doc_e!=doc &&
+            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,';')))
+        doc_e=doc_e->next;
+    else
+      while (doc_e!=doc &&
+            (!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,'{')))
+        doc_e=doc_e->next;
+  }
+  if (doc_e!=doc) {
+    if (doc_e->de_flags&DOCEF_TAG) {
+      ptr=doc_e->tag;
+      if (ptr2=StrMatch("//",ptr))
+        ptr=ptr2+2;
+      else if (ptr2=StrMatch("/*",ptr))
+        ptr=ptr2+2;
+      else if (!StrNCmp(ptr,"public",6))
+        ptr+=6;
+      while (*ptr==CH_SPACE)
+        ptr++;
+      res=StrNew(ptr);
+      doc_e=doc_e->next;
+    }
+    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
+      if (doc_e->type_u8==DOCT_TAB) {
+        ptr=MStrPrint("%s ",res);
+        Free(res);
+        res=ptr;
+      } else if (doc_e->de_flags&DOCEF_TAG) {
+        ptr=MStrPrint("%s%s",res,doc_e->tag);
+        Free(res);
+        res=ptr;
+      }
+      doc_e=doc_e->next;
+    }
+  }
+  XTalkWait(task,"%c",CH_SHIFT_ESC);
+  if (res) {
+    ptr=MStrUtil(res,SUF_REM_TRAILING|SUF_REM_LEADING|SUF_SINGLE_SPACE);
+    Free(res);
+    res=ptr;
+  }
+  return res;
+}
+
+I64 HashEntriesCompare3(CWho *h1,CWho *h2)
+{
+  I64 i,i1=0,i2=0;
+  i=StrCmp(h1->idx,h2->idx);
+  if (i)
+    return i;
+  else {
+    if (h1->h->type&HTT_HELP_FILE)
+      i1=1;
+    if (h2->h->type&HTT_HELP_FILE)
+      i2=1;
+    i=i2-i1;
+    if (i)
+      return i;
+    else
+      return StrCmp(h1->h->str,h2->h->str);
+  }
+}
+
+public U0 Who(U8 *fu_flags=NULL,CHashTable *h=NULL,
+U8 *idx=NULL,CDoc *doc=NULL)
+{//Dump hash symbol table.
+// "+p" for only public symbols
+  // "+m" to order by number (normally alphabetical)
+  // "-r" just local hash table
+  CHashTable *table;
+  CHashSrcSym *tmph;
+  CHashGeneric *ptr;
+  CWho *lst;
+  I64 cnt,i,j,k,f=0;
+  U8 buf[512],*last_idx=StrNew(""),*cur_idx,*comment;
+  Bool recurse,publics,map;
+  CTask *task;
+
+  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (f&~(FUF_RECURSE|FUF_PUBLIC|FUF_MAP))
+    throw('FUF');
+  recurse=Bt(&f,FUf_RECURSE);
+  publics=Bt(&f,FUf_PUBLIC);
+  map    =Bt(&f,FUf_MAP);
+
+  if (!h) h=Fs->hash_table;
+
+  if (idx) {
+    task=User;
+    TaskWait(task);
+    LBtr(&task->display_flags,DISPLAYf_SHOW);
+  } else
+    task=NULL;
+
+  cnt=0;
+  table=h;
+  while (table) {
+    for (i=0;i<=table->mask;i++) {
+      tmph=table->body[i];
+      while (tmph) {
+        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
+              (tmph->type & HTF_PUBLIC || !publics)) {
+          if (!idx)
+            cnt++;
+          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx))
+            cnt+=HelpIndexCnt(cur_idx,idx);
+        }
+        tmph=tmph->next;
+      }
+    }
+    if (recurse)
+      table=table->next;
+    else
+      break;
+  }
+  if (!cnt) goto wh_done;
+
+  lst=CAlloc(cnt*sizeof(CWho));
+  j=0;
+  table=h;
+  while (table) {
+    for (i=0;i<=table->mask;i++) {
+      tmph=table->body[i];
+      while (tmph) {
+        if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
+              (tmph->type & HTF_PUBLIC || !publics))
+          if (!idx)
+            lst[j++].h=tmph;
+          else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx) &&
+                (k=HelpIndexCnt(cur_idx,idx)))
+            while (k--) {
+              lst[j].idx=HelpIndexStr(&cur_idx,idx);
+              lst[j++].h=tmph;
+            }
+        tmph=tmph->next;
+      }
+    }
+    if (recurse)
+      table=table->next;
+    else
+      break;
+  }
+
+  if (map)
+    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare2);
+  else if (idx)
+    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare3);
+  else
+    QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare);
+
+  if (idx) {
+    progress1_max=cnt;
+    progress1=0;
+  }
+  for (i=0;i<cnt;i++) {
+    comment=NULL;
+    ptr=lst[i].h;
+    if (idx)
+      if (cur_idx=lst[i].idx) {
+        if (StrCmp(cur_idx,last_idx)) {
+          Free(last_idx);
+          last_idx=StrNew(cur_idx);
+          if (i)
+            DocPrint(doc,"\n\n");
+          DocPrint(doc,"$WW,0$$PURPLE$$TX+CX,\"%$Q\"$$FG$\n",cur_idx);
+        }
+      }
+
+    if (idx && ptr->type & HTT_HELP_FILE) {
+      DocPrint(doc,"$WW,1$");
+      DocType(doc,ptr->str);
+      DocPrint(doc,"$WW,0$");
+    } else {
+      if (ptr->type&HTG_SRC_SYM && ptr(CHashSrcSym *)->src_link) {
+        DocPrint(doc,"$LK,\"%-20s\",A=\"%s\"$",
+              ptr->str,ptr(CHashSrcSym *)->src_link);
+        if (idx)
+          comment=HelpComment(task,ptr,ptr(CHashSrcSym *)->src_link);
+      } else
+        DocPrint(doc,"%-20s",ptr->str);
+
+      if (!idx) {
+        if (ptr->type & HTT_DEFINE_STR) {
+          j=ptr(CHashDefineStr *)->cnt;
+          if (j==-1)
+            StrPrint(buf,"%-10t$Q   ",ptr(CHashDefineStr *)->data);
+          else
+            StrPrint(buf,"%-10t$Q %02X",ptr(CHashDefineStr *)->data,j);
+        } else if (ptr->type & HTT_GLBL_VAR)
+          StrPrint(buf,"%010X   ",ptr(CHashGlblVar *)->data_addr);
+        else
+          StrPrint(buf,"%010X   ",HashVal(ptr));
+        j=HashEntrySize(ptr);
+        if (j==-1)
+          CatPrint(buf," %04X            ",ptr->use_cnt);
+        else
+          CatPrint(buf," %04X %010X ",ptr->use_cnt,j);
+      } else
+        *buf=0;
+
+      k=ptr->type;
+      if (publics)
+        k&=~HTF_PUBLIC;
+      if (!(k&HTG_TYPE_MASK))
+        CatPrint(buf,"NULL ");
+      while (k) {
+        j=Bsf(k);
+        if (j<0)
+          break;
+        Btr(&k,j);
+        CatPrint(buf,"%Z ",j,"ST_HTT_TYPES");
+      }
+      DocPrint(doc,"%s",buf);
+      if (comment) {
+        DocPrint(doc,"$GREEN$%s$FG$",comment);
+        Free(comment);
+      }
+      DocPrint(doc,"\n");
+    }
+    Free(lst[i].idx);
+    if (idx)
+      progress1++;
+  }
+  Free(lst);
+  if (idx)
+    progress1=progress1_max=0;
+
+wh_done:
+  if (doc) {
+    if (doc->head.next==doc)
+      DocPrint(doc,"No Match");
+    else
+      DocRecalc(doc);
+  }
+  Free(last_idx);
+  Kill(task);
+}
+
+#help_index "Info;Hash;Cmd Line (Typically)"
+
+#define HDR_NUM 16
+public I64 HashDepthRep(CHashTable *table=NULL)
+{//Hash table linked-list chain depth report.
+//Histogram of collision count.
+  I64 i,j,longest=0,cnt=0,a[HDR_NUM];
+  CHash *tmph;
+  if (!table) table=Fs->hash_table;
+  MemSet(a,0,sizeof(a));
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    if (tmph) {
+      j=LinkedLstCnt(tmph);
+      if (j<HDR_NUM)
+        a[j]++;
+      cnt+=j;
+      if (j>longest)
+        longest=j;
+    }
+  }
+  "Histogram\n";
+  for (i=0;i<HDR_NUM;i++)
+    if (a[i])
+      "%02d:%d\n",i,a[i];
+  "Size:%d Count:%d Longest:%d\n",
+        table->mask+1,cnt,longest;
+  return longest;
+}
+
+#help_index "Help System"
+#help_file "::/Doc/HelpSystem"
+
+public U0 DocHelpIdx(CDoc *doc,U8 *idx)
+{//Put to doc report for given help idx.
+  Who("+p",,idx,doc);
+}
+
+public U0 PopUpHelpIndex(U8 *idx,CTask *parent=NULL)
+{//PopUp win report for given help idx.
+  U8 *buf;
+  buf=MStrPrint("DocHelpIdx(DocPut,\"%s\");View;",idx);
+  PopUp(buf,parent);
+  Free(buf);
+}
+
+#help_index "Hash/System"
+public U0 MapFileLoad(U8 *filename)
+{//Load map file so we have src line info.
+  U8 *st,*ptr,*name=ExtDft(filename,"MAP.Z"),
+        *absname=FileNameAbs(name);
+  CDoc *doc=DocRead(name);
+  CDocEntry *doc_e;
+  CHashSrcSym *tmph;
+  I64 i,j,base=0;
+  CDbgInfo *dbg_info;
+
+  FileExtRem(absname);
+  if (absname[1]==':' && StrLen(absname)>2 &&
+        (tmph=HashSingleTableFind(absname+2,Fs->hash_table,HTT_MODULE)))
+    base=tmph(CHashGeneric *)->user_data0+sizeof(CBinFile);
+
+  if (!doc) return;
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_LINK) {
+      if (*doc_e->tag)
+        st=MStrUtil(doc_e->tag,SUF_REM_TRAILING);
+      else
+        st=MStrUtil(doc_e->aux_str,SUF_REM_TRAILING);
+      if (tmph=HashSingleTableFind(st,Fs->hash_table,HTG_SRC_SYM)) {
+        if (*doc_e->tag) {
+          Free(tmph->src_link);
+          tmph->src_link=doc_e->aux_str;
+          ptr=tmph->src_link;
+          if (ptr[0] && ptr[1] && ptr[2]==':') {
+            if (ptr[3]==':')
+              ptr[3]=blkdev.boot_drv_let;
+            else if (ptr[3]=='~')
+              ptr[3]=*blkdev.home_dir;
+          }
+          doc_e->aux_str=NULL;
+        }
+        if (tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM) &&
+              !(dbg_info=tmph->dbg_info) && doc_e->bin_data &&
+              (dbg_info=doc_e->bin_data->data)) {
+          if (doc_e->bin_data->size>MSize(dbg_info))
+            "Corrupt Map Entry\n";
+          else {
+            doc_e->bin_data->data=NULL;
+            tmph->dbg_info=dbg_info;
+            for (i=dbg_info->min_line;i<=dbg_info->max_line+1;i++) {
+              j=i-dbg_info->min_line;
+              if (dbg_info->body[j])
+                dbg_info->body[j]=dbg_info->body[j]+base;
+            }
+          }
+        }
+      }
+      Free(st);
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+  Free(name);
+  Free(absname);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AMath.HC.HTML b/public/Wb/Home/Src/Adam/AMath.HC.HTML new file mode 100755 index 0000000..6ed99c7 --- /dev/null +++ b/public/Wb/Home/Src/Adam/AMath.HC.HTML @@ -0,0 +1,166 @@ + + + + + + + + + + + +
+#help_index "Math"
+public U0 R2P(F64 *_mag=NULL,F64 *_arg=NULL,F64 x,F64 y)
+{//Rect to polar
+//Returns angle in range (-pi,pi]
+  if (_arg)
+    *_arg=Arg(x,y);
+  if (_mag)
+    *_mag=Sqrt(x*x+y*y);
+}
+
+public U0 P2R(F64 *_x=NULL,F64 *_y=NULL,F64 mag,F64 arg)
+{//Polar to Rect
+  if (_x)
+    *_x=mag*Cos(arg);
+  if (_y)
+    *_y=mag*Sin(arg);
+}
+
+public F64 Wrap(F64 theta,F64 base=-pi)
+{//Returns angle in range [base,base+2*pi)
+  F64 res=theta%(2*pi);
+  if (res>=base+2*pi)
+    res-=2*pi;
+  else if (res<base)
+    res+=2*pi;
+  return res;
+}
+
+public I64 DistSqrI64(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Distance-squared between 2 points.
+  I64 dx=x1-x2,dy=y1-y2;
+  return dx*dx+dy*dy;
+}
+
+public F64 ASin(F64 s)
+{//Arc Sin (Inverse Sin).
+  F64 c;
+  c=s*s;
+  if (c>=1.0)
+    return pi/2.0;
+  c=Sqrt(1.0-c);
+  return ATan(s/c);
+}
+
+public F64 ACos(F64 c)
+{//Arc Cos (Inverse Cos).
+  F64 s;
+  if (!c)
+    return pi/2.0;
+  s=c*c;
+  if (s>=1.0)
+    return 0.0;
+  s=Sqrt(1.0-s);
+  return ATan(s/c);
+}
+
+public F64 Sinh(F64 x)
+{//Hyperbolic Sine.
+  return 0.5*(Exp(x)-Exp(-x));
+}
+
+public F64 Cosh(F64 x)
+{//Hyperbolic Cosine.
+  return 0.5*(Exp(x)+Exp(-x));
+}
+
+#help_index "Math/Complex;Data Types/Complex"
+public Complex *CAdd(Complex *sum,Complex *n1,Complex *n2)
+{//sum=n1+n2
+  sum->x=n1->x+n2->x;
+  sum->y=n1->y+n2->y;
+  return sum;
+}
+
+public Complex *CSub(Complex *diff,Complex *n1,Complex *n2)
+{//diff=n1-n2
+  diff->x=n1->x-n2->x;
+  diff->y=n1->y-n2->y;
+  return diff;
+}
+
+public Complex *CMul(Complex *prod,Complex *n1,Complex *n2)
+{//prod=n1*n2
+  prod->x=n1->x*n2->x-n1->y*n2->y;
+  prod->y=n1->x*n2->y+n1->y*n2->x;
+  return prod;
+}
+
+public Complex *CDiv(Complex *quot,Complex *n1,Complex *n2)
+{//quot=n1/n2
+  F64 m1,arg1,m2,arg2;
+  R2P(&m1,&arg1,n1->x,n1->y);
+  R2P(&m2,&arg2,n2->x,n2->y);
+  m1/=m2;
+  arg1-=arg2;
+  quot->x=m1*Cos(arg1);
+  quot->y=m1*Sin(arg1);
+  return quot;
+}
+
+public Complex *CScale(Complex *dst,F64 s)
+{//dst*=s
+  dst->x*=s;
+  dst->y*=s;
+  return dst;
+}
+
+public Complex *CCopy(Complex *dst,Complex *src)
+{//dst=src
+  dst->x=src->x;
+  dst->y=src->y;
+  return dst;
+}
+
+public Complex *CEqu(Complex *dst,F64 x,F64 y)
+{//dst=(x,y)
+  dst->x=x;
+  dst->y=y;
+  return dst;
+}
+
+public Complex *CPoly(Complex *dst,I64 n,Complex *zeros,Complex *x)
+{//Eval complex polynomial
+  I64 i;
+  Complex n1,n2;
+  if (n>0) {
+    CSub(dst,x,&zeros[0]);
+    for (i=1;i<n;i++) {
+      CCopy(&n1,dst);
+      CMul(dst,&n1,CSub(&n2,x,&zeros[i]));
+    }
+  } else
+    CEqu(dst,1.0,0.0);
+  return dst;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AMathODE.HC.HTML b/public/Wb/Home/Src/Adam/AMathODE.HC.HTML new file mode 100755 index 0000000..5832989 --- /dev/null +++ b/public/Wb/Home/Src/Adam/AMathODE.HC.HTML @@ -0,0 +1,719 @@ + + + + + + + + + + + +
+#help_index "Math/ODE"
+#help_file "::/Doc/ODE"
+
+//See ::/Doc/Credits.DD.
+
+F64 LowPass1(F64 a,F64 y0,F64 y,F64 dt=1.0)
+{//First order low pass filter
+  dt=Exp(-a*dt);
+  return y0*dt+y*(1.0-dt);
+}
+
+U0 ODERstPtrs(CMathODE *ode)
+{
+  I64 s=ode->n_internal*sizeof(F64);
+  F64 *ptr=ode->array_base;
+  ode->state_internal=ptr;      ptr(I64)+=s;
+  ode->state_scale=ptr;         ptr(I64)+=s;
+  ode->DstateDt=ptr;            ptr(I64)+=s;
+  ode->initial_state=ptr;       ptr(I64)+=s;
+  ode->tmp0=ptr;        ptr(I64)+=s;
+  ode->tmp1=ptr;        ptr(I64)+=s;
+  ode->tmp2=ptr;        ptr(I64)+=s;
+  ode->tmp3=ptr;        ptr(I64)+=s;
+  ode->tmp4=ptr;        ptr(I64)+=s;
+  ode->tmp5=ptr;        ptr(I64)+=s;
+  ode->tmp6=ptr;        ptr(I64)+=s;
+  ode->tmp7=ptr;
+}
+
+public CMathODE *ODENew(I64 n,F64 max_tolerance=1e-6,I64 flags=0)
+{//Make differential equation ctrl struct. See flags.
+  //The tolerance is not precise.
+  //You can min_tolerance and it will
+  //dynamically adjust tolerance to utilize
+  //the CPU.
+  I64 s=n*sizeof(F64);
+  CMathODE *ode=CAlloc(sizeof(CMathODE));
+  ode->t_scale=1.0;
+  ode->flags=flags;
+  ode->n_internal=ode->n=n;
+  ode->h=1e-6;
+  ode->h_min=1e-64;
+  ode->h_max=1e32;
+  ode->max_tolerance=ode->min_tolerance=ode->tolerance_internal=max_tolerance;
+  ode->win_task=ode->mem_task=Fs;
+  QueInit(&ode->next_mass);
+  QueInit(&ode->next_spring);
+  ode->state=CAlloc(s);
+  ode->array_base=MAlloc(12*s);
+  ODERstPtrs(ode);
+  return ode;
+}
+
+
+public Bool ODEPause(CMathODE *ode,Bool val=ON)
+{//Pause ODE.
+  Bool res;
+  if (!ode) return OFF;
+  res=LBEqu(&ode->flags,ODEf_PAUSED,val);
+  if (val)
+    while (Bt(&ode->flags,ODEf_BUSY))
+      Yield;
+  return res;
+}
+
+public U0 ODEDel(CMathODE *ode)
+{//Free ODE node, but not masses or springs.
+  I64 i;
+  if (!ode) return;
+  ODEPause(ode);
+  Free(ode->state);
+  Free(ode->array_base);
+  if (ode->slave_tasks) {
+    for (i=0;i<mp_cnt;i++)
+      Kill(ode->slave_tasks[i]);
+    Free(ode->slave_tasks);
+  }
+  Free(ode);
+}
+
+public I64 ODESize(CMathODE *ode)
+{//Mem size of ode ctrl, but not masses and springs.
+  if (!ode)
+    return 0;
+  else
+    return MSize2(ode->state)+MSize2(ode->array_base)+MSize2(ode);
+}
+
+U0 ODESetMassesPtrs(CMathODE *ode,F64 *state,F64 *DstateDt)
+{
+  COrder2D3 *ptr1=state(F64 *)+ode->n,
+        *ptr2=DstateDt(F64 *)+ode->n;
+  CMass *tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->state=ptr1++;
+    tmpm->DstateDt=ptr2++;
+    tmpm=tmpm->next;
+  }
+}
+
+U0 ODEState2Internal(CMathODE *ode)
+{
+  CMass *tmpm;
+  F64 *old_array_base;
+  I64 mass_cnt;
+
+  if (ode->flags&ODEF_HAS_MASSES) {
+    mass_cnt=0;
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      mass_cnt++;
+      tmpm=tmpm->next;
+    }
+    old_array_base=ode->array_base;
+    ode->n_internal=ode->n+6*mass_cnt;
+    ode->array_base=MAlloc(12*ode->n_internal*sizeof(F64),ode->mem_task);
+    Free(old_array_base);
+    ODERstPtrs(ode);
+
+    ODESetMassesPtrs(ode,ode->state_internal,ode->state_internal);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      MemCpy(tmpm->state,&tmpm->saved_state,sizeof(COrder2D3));
+      tmpm=tmpm->next;
+    }
+  }
+  MemCpy(ode->state_internal,ode->state,ode->n*sizeof(F64));
+}
+
+U0 ODEInternal2State(CMathODE *ode)
+{
+  CMass *tmpm;
+  MemCpy(ode->state,ode->state_internal,ode->n*sizeof(F64));
+  if (ode->flags&ODEF_HAS_MASSES) {
+    ODESetMassesPtrs(ode,ode->state_internal,ode->state_internal);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      MemCpy(&tmpm->saved_state,tmpm->state,sizeof(COrder2D3));
+      tmpm=tmpm->next;
+    }
+  }
+}
+
+public U0 ODERenum(CMathODE *ode)
+{//Renumber masses and springs.
+  I64 i;
+  CSpring *tmps;
+  CMass *tmpm;
+
+  i=0;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->num=i++;
+    tmpm=tmpm->next;
+  }
+
+  i=0;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps->num=i++;
+    tmps->end1_num=tmps->end1->num;
+    tmps->end2_num=tmps->end2->num;
+    tmps=tmps->next;
+  }
+}
+
+public CMass *MassFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
+{//Search for mass nearest to x,y,z.
+  CMass *tmpm,*best_mass=NULL;
+  F64 dd,best_dd=F64_MAX;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    dd=Sqr(tmpm->x-x)+Sqr(tmpm->y-y)+Sqr(tmpm->z-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_mass=tmpm;
+    }
+    tmpm=tmpm->next;
+  }
+  return best_mass;
+}
+
+public CSpring *SpringFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
+{//Find spring midpoint nearest x,y,z.
+  CSpring *tmps,*best_spring=NULL;
+  F64 dd,best_dd=F64_MAX;
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    dd=Sqr((tmps->end1->x+tmps->end2->x)/2-x)+
+          Sqr((tmps->end1->y+tmps->end2->y)/2-y)+
+          Sqr((tmps->end1->z+tmps->end2->z)/2-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_spring=tmps;
+    }
+    tmps=tmps->next;
+  }
+  return best_spring;
+}
+
+public U0 MassOrSpringFind(
+        CMathODE *ode,CMass **res_mass,CSpring **res_spring,
+        F64 x,F64 y,F64 z=0)
+{//Find spring or mass nearest x,y,z.
+  CMass   *tmpm,*best_mass=NULL;
+  CSpring *tmps,*best_spring=NULL;
+  F64 dd,best_dd=F64_MAX;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    dd=Sqr(tmpm->x-x)+Sqr(tmpm->y-y)+Sqr(tmpm->z-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_mass=tmpm;
+    }
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    dd=Sqr((tmps->end1->x+tmps->end2->x)/2-x)+
+          Sqr((tmps->end1->y+tmps->end2->y)/2-y)+
+          Sqr((tmps->end1->z+tmps->end2->z)/2-z);
+    if (dd<best_dd) {
+      best_dd=dd;
+      best_spring=tmps;
+      best_mass=NULL;
+    }
+    tmps=tmps->next;
+  }
+  if (res_mass)   *res_mass  =best_mass;
+  if (res_spring) *res_spring=best_spring;
+}
+
+public CMass *MassFindNum(CMathODE *ode,I64 num)
+{//Return mass number N.
+  CMass *tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->num==num)
+      return tmpm;
+    tmpm=tmpm->next;
+  }
+  return NULL;
+}
+
+public U0 ODERstInactive(CMathODE *ode)
+{//Set all masses and springs to ACTIVE for new trial.
+  CMass *tmpm;
+  CSpring *tmps;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->flags&=~MSF_INACTIVE;
+    tmpm=tmpm->next;
+  }
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps->flags&=~SSF_INACTIVE;
+    tmps=tmps->next;
+  }
+}
+
+U0 ODECalcSprings(CMathODE *ode)
+{
+  CSpring *tmps=ode->next_spring;
+  CMass *e1,*e2;
+  F64 d;
+  CD3 p;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->flags&SSF_INACTIVE) {
+      tmps->displacement=0;
+      tmps->f=0;
+    } else {
+      e1=tmps->end1;
+      e2=tmps->end2;
+      d=D3Norm(D3Sub(&p,&e2->state->x,&e1->state->x));
+      tmps->displacement=d-tmps->rest_len;
+      tmps->f=tmps->displacement*tmps->const;
+      if (tmps->f>0 && tmps->flags&SSF_NO_TENSION)
+        tmps->f=0;
+      else if (tmps->f<0 && tmps->flags&SSF_NO_COMPRESSION)
+        tmps->f=0;
+      if (d>0) {
+        D3MulEqu(&p,tmps->f/d);
+        D3AddEqu(&e1->DstateDt->DxDt,&p);
+        D3SubEqu(&e2->DstateDt->DxDt,&p);
+      }
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 ODECalcDrag(CMathODE *ode)
+{
+  CMass *tmpm;
+  F64 d,dd;
+  CD3 p;
+  if (ode->drag_v || ode->drag_v2 || ode->drag_v3) {
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags & MSF_INACTIVE) &&
+            tmpm->drag_profile_factor &&
+            (dd=D3NormSqr(&tmpm->state->DxDt))) {
+        d=ode->drag_v;
+        if (ode->drag_v2)
+          d+=ode->drag_v2*Sqrt(dd);
+        if (ode->drag_v3)
+          d+=dd*ode->drag_v3;
+        D3SubEqu(&tmpm->DstateDt->DxDt,
+              D3Mul(&p,d*tmpm->drag_profile_factor,&tmpm->state->DxDt));
+      }
+      tmpm=tmpm->next;
+    }
+  }
+}
+
+U0 ODEApplyAccelerationLimit(CMathODE *ode)
+{
+  CMass *tmpm;
+  F64 d;
+  if (ode->acceleration_limit) {
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags & MSF_INACTIVE) &&
+            (d=D3Norm(&tmpm->DstateDt->DxDt))>ode->acceleration_limit)
+        D3MulEqu(&tmpm->DstateDt->DxDt,ode->acceleration_limit/d);
+      tmpm=tmpm->next;
+    }
+  }
+}
+
+U0 ODEMPTask(CMathODE *ode)
+{
+  while (TRUE) {
+    while (!Bt(&ode->mp_not_done_flags,Gs->num))
+      Yield;
+    if (ode->mp_derive)
+      (*ode->mp_derive)(ode,ode->mp_t,
+            Gs->num,ode->mp_state,ode->mp_DstateDt);
+    LBtr(&ode->mp_not_done_flags,Gs->num);
+  }
+}
+
+U0 ODEMPWake(CMathODE *ode)
+{
+  I64 i;
+  if (!ode->slave_tasks) {
+    ode->slave_tasks=CAlloc(mp_cnt*sizeof(CTask *));
+    for (i=0;i<mp_cnt;i++)
+      ode->slave_tasks[i]=Spawn(&ODEMPTask,ode,"ODE Slave",i);
+  }
+  for (i=0;i<mp_cnt;i++) {
+    Suspend(ode->slave_tasks[i],FALSE);
+    MPInt(I_WAKE,i);
+  }
+}
+
+U0 ODEMPSleep(CMathODE *ode)
+{
+  I64 i;
+  if (ode->slave_tasks) {
+    while (ode->mp_not_done_flags)
+      Yield;
+    for (i=0;i<mp_cnt;i++)
+      Suspend(ode->slave_tasks[i]);
+  }
+}
+
+U0 ODECallMPDerivative(CMathODE *ode,F64 t,F64 *state,F64 *DstateDt)
+{
+  ode->mp_t=t;
+  ode->mp_state=state;
+  ode->mp_DstateDt=DstateDt;
+  ode->mp_not_done_flags=1<<mp_cnt-1;
+  do Yield;
+  while (ode->mp_not_done_flags);
+}
+
+U0 ODECallDerivative(CMathODE *ode,F64 t,F64 *state,F64 *DstateDt)
+{
+  CMass *tmpm;
+  if (ode->flags&ODEF_HAS_MASSES) {
+    ODESetMassesPtrs(ode,state,DstateDt);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags&MSF_INACTIVE)) {
+        D3Zero(&tmpm->DstateDt->DxDt);
+        D3Copy(&tmpm->DstateDt->x,&tmpm->state->DxDt);
+      }
+      tmpm=tmpm->next;
+    }
+    ODECalcSprings(ode);
+    ODECalcDrag(ode);
+    if (ode->mp_derive)
+      ODECallMPDerivative(ode,t,state,DstateDt);
+    if (ode->derive)
+      (*ode->derive)(ode,t,state,DstateDt);
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      if (!(tmpm->flags&MSF_INACTIVE)) {
+        if (tmpm->flags&MSF_FIXED) {
+          D3Zero(&tmpm->DstateDt->DxDt);
+          D3Zero(&tmpm->DstateDt->x);
+        } else if (tmpm->mass)
+          D3DivEqu(&tmpm->DstateDt->DxDt,tmpm->mass);
+      }
+      tmpm=tmpm->next;
+    }
+    ODEApplyAccelerationLimit(ode);
+  } else {
+    if (ode->mp_derive)
+      ODECallMPDerivative(ode,t,state,DstateDt);
+    if (ode->derive)
+      (*ode->derive)(ode,t,state,DstateDt);
+  }
+}
+
+U0 ODEOneStep(CMathODE *ode)
+{
+  I64 i;
+  ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+  for (i=0;i<ode->n_internal;i++)
+    ode->state_internal[i]+=ode->h*ode->DstateDt[i];
+  ode->t+=ode->h;
+}
+
+U0 ODERK4OneStep(CMathODE *ode)
+{
+  I64 i,n=ode->n_internal;
+  F64 xh,hh,h6,*dym,*dyt,*yt,*DstateDt;
+
+  dym =ode->tmp0;
+  dyt =ode->tmp1;
+  yt  =ode->tmp2;
+  DstateDt=ode->tmp3;
+  hh  =0.5*ode->h;
+  h6  =ode->h / 6.0;
+  xh  =ode->t + hh;
+
+  ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+  for (i=0;i<n;i++)
+    yt[i]=ode->state_internal[i]+hh*DstateDt[i];
+  ODECallDerivative(ode,xh,yt,dyt);
+  for (i=0;i<n;i++)
+    yt[i]=ode->state_internal[i]+hh*dyt[i];
+  ODECallDerivative(ode,xh,yt,dym);
+  for (i=0;i<n;i++) {
+    yt[i]=ode->state_internal[i]+ode->h*dym[i];
+    dym[i]+=dyt[i];
+  }
+  ode->t+=ode->h;
+  ODECallDerivative(ode,ode->t,yt,dyt);
+  for (i=0;i<n;i++)
+    ode->state_internal[i]+=h6*(DstateDt[i]+dyt[i]+2.0*dym[i]);
+}
+
+#define ODEa2 0.2
+#define ODEa3 0.3
+#define ODEa4 0.6
+#define ODEa5 1.0
+#define ODEa6 0.875
+#define ODEb21 0.2
+#define ODEb31 (3.0/40.0)
+#define ODEb32 (9.0/40.0)
+#define ODEb41 0.3
+#define ODEb42 (-0.9)
+#define ODEb43 1.2
+#define ODEb51 (-11.0/54.0)
+#define ODEb52 2.5
+#define ODEb53 (-70.0/27.0)
+#define ODEb54 (35.0/27.0)
+#define ODEb61 (1631.0/55296.0)
+#define ODEb62 (175.0/512.0)
+#define ODEb63 (575.0/13824.0)
+#define ODEb64 (44275.0/110592.0)
+#define ODEb65 (253.0/4096.0)
+#define ODEc1  (37.0/378.0)
+#define ODEc3  (250.0/621.0)
+#define ODEc4  (125.0/594.0)
+#define ODEc6  (512.0/1771.0)
+#define ODEdc1 (37.0/378.0-2825.0/27648.0)
+#define ODEdc3 (250.0/621.0-18575.0/48384.0)
+#define ODEdc4 (125.0/594.0-13525.0/55296.0)
+#define ODEdc5 (-277.0/14336.0)
+#define ODEdc6 (512.0/1771.0-0.25)
+
+U0 ODECashKarp(CMathODE *ode)
+{
+  I64 i,n=ode->n_internal;
+  F64 h=ode->h,*state=ode->state_internal,
+        *DstateDt=ode->DstateDt,*ak2,*ak3,*ak4,*ak5,*ak6,
+        *tmpstate,*stateerr,*outstate;
+
+  ak2=ode->tmp0;
+  ak3=ode->tmp1;
+  ak4=ode->tmp2;
+  ak5=ode->tmp3;
+  ak6=ode->tmp4;
+  tmpstate=ode->tmp5;
+  outstate=ode->tmp6;
+  stateerr=ode->tmp7;
+
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+ODEb21*h*DstateDt[i];
+  ODECallDerivative(ode,ode->t+ODEa2*h,tmpstate,ak2);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb31*DstateDt[i]+ODEb32*ak2[i]);
+  ODECallDerivative(ode,ode->t+ODEa3*h,tmpstate,ak3);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb41*DstateDt[i]+ODEb42*ak2[i]+ODEb43*ak3[i]);
+  ODECallDerivative(ode,ode->t+ODEa4*h,tmpstate,ak4);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb51*DstateDt[i]+
+          ODEb52*ak2[i]+ODEb53*ak3[i]+ODEb54*ak4[i]);
+  ODECallDerivative(ode,ode->t+ODEa5*h,tmpstate,ak5);
+  for (i=0;i<n;i++)
+    tmpstate[i]=state[i]+h*(ODEb61*DstateDt[i]+
+          ODEb62*ak2[i]+ODEb63*ak3[i]+ODEb64*ak4[i]+ODEb65*ak5[i]);
+  ODECallDerivative(ode,ode->t+ODEa6*h,tmpstate,ak6);
+
+  for (i=0;i<n;i++)
+    outstate[i]=state[i]+h*(ODEc1*DstateDt[i]+
+          ODEc3*ak3[i]+ODEc4*ak4[i]+ODEc6*ak6[i]);
+  for (i=0;i<n;i++)
+    stateerr[i]=h*(ODEdc1*DstateDt[i]+ODEdc3*ak3[i]+
+          ODEdc4*ak4[i]+ODEdc5*ak5[i]+ODEdc6*ak6[i]);
+}
+
+#define SAFETY 0.9
+#define PGROW  (-0.2)
+#define PSHRNK (-0.25)
+#define ERRCON 1.89e-4
+
+U0 ODERK5OneStep(CMathODE *ode)
+{
+  I64 i;
+  F64 errmax,tmp,*tmpstate=ode->tmp6,*stateerr=ode->tmp7;
+  while (TRUE) {
+    ode->h=Clamp(ode->h,ode->h_min,ode->h_max);
+    ODECashKarp(ode);
+    errmax=0.0;
+    for (i=0;i<ode->n_internal;i++) {
+      tmp=Abs(stateerr[i]/ode->state_scale[i]);
+      if (tmp>errmax)
+        errmax=tmp;
+    }
+    errmax/=ode->tolerance_internal;
+    if (errmax<=1.0 || ode->h==ode->h_min) break;
+    tmp=ode->h*SAFETY*errmax`PSHRNK;
+    if (tmp<0.1*ode->h)
+      ode->h*=0.1;
+    else
+      ode->h=tmp;
+  }
+  ode->t+=ode->h;
+  if (errmax>ERRCON)
+    ode->h*=SAFETY*errmax`PGROW;
+  else
+    ode->h*=5.0;
+  ode->h=Clamp(ode->h,ode->h_min,ode->h_max);
+  MemCpy(ode->state_internal,tmpstate,sizeof(F64)*ode->n_internal);
+}
+
+F64 ode_alloced_factor=0.75;
+
+U0 ODEsUpdate(CTask *task)
+{/* This routine is called by the window mgron a continuous
+basis to allow real-time simulation.  It is intended
+to provide ress good enough for games.  It uses a runge-kutta
+integrator which is a better algorithm than doing it with Euler.
+
+It is adaptive step-sized, so it slows down when an important
+event is taking place to improve accuracy, but in my implementation
+it has a timeout.
+*/
+  I64 i;
+  F64 d,start_time,timeout_time,t_desired,t_initial,interpolation;
+  CMathODE *ode;
+
+  if (task->next_ode==&task->next_ode)
+    task->last_ode_time=0;
+  else if (!Bt(&task->win_inhibit,WIf_SELF_ODE)) {
+//See GrUpdateTasks() and GrUpdateTaskODEs().
+    //We will not pick a time limit based on
+    //how busy the CPU is, what percent of the
+    //last refresh cycle was spent on ODE's
+    //and what the refresh cycle rate was.
+    start_time=tS;
+    d=1.0/winmgr.fps;
+    timeout_time=start_time+
+          (task->last_ode_time/d+0.1)/(winmgr.last_ode_time/d+0.1)*
+          ode_alloced_factor*d;
+    ode=task->next_ode;
+    while (ode!=&task->next_ode) {
+      t_initial=ode->t;
+      d=tS;
+      if (!(ode->flags&ODEF_STARTED)) {
+        ode->base_t=d;
+        ode->flags|=ODEF_STARTED;
+      }
+      d-=ode->base_t+t_initial;
+      t_desired=ode->t_scale*d+t_initial;
+      if (ode->flags&ODEF_PAUSED)
+        ode->base_t+=t_desired-ode->t; //Slip
+      else {
+        ode->flags|=ODEF_BUSY;
+        if (ode->flags&ODEF_PAUSED)
+          ode->base_t+=t_desired-ode->t; //Slip
+        else {
+          if (ode->derive || ode->mp_derive) {
+            if (ode->mp_derive)
+              ODEMPWake(ode);
+            ODEState2Internal(ode);
+            MemCpy(ode->initial_state,ode->state_internal,
+                  ode->n_internal*sizeof(F64));
+            while (ode->t<t_desired) {
+              ode->h_max=t_desired-ode->t;
+              ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+              for (i=0;i<ode->n_internal;i++)
+                ode->state_scale[i]=Abs(ode->state_internal[i])+
+                      Abs(ode->DstateDt[i]*ode->h)+ode->tolerance_internal;
+              ODERK5OneStep(ode);
+              if (tS>timeout_time) {
+                ode->base_t+=t_desired-ode->t; //Slip
+                goto ode_done;
+
+              }
+            }
+
+            //Interpolate if end time was not exact.
+            if (ode->t!=t_desired) {
+              if (interpolation=ode->t-t_initial) {
+                interpolation=(t_desired-t_initial)/interpolation;
+                if (interpolation!=1.0)
+                  for (i=0;i<ode->n_internal;i++)
+                    ode->state_internal[i]=(ode->state_internal[i]-
+                          ode->initial_state[i])*interpolation+
+                          ode->initial_state[i];
+              }
+              ode->t=t_desired;
+            }
+ode_done:
+            ODEInternal2State(ode);
+
+            //Convenience call to set vals
+            ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
+
+            if (ode->mp_derive)
+              ODEMPSleep(ode);
+          }
+        }
+        ode->flags&=~ODEF_BUSY;
+      }
+      ode->base_t+=(1.0-ode->t_scale)*d;
+      ode=ode->next;
+    }
+
+    //Now, we will dynamically adjust tolerances.
+
+    //We will regulate the tolerances
+    //to fill the time we decided was
+    //okay to devote to ODE's.
+    //Since we might have multiple ODE's
+    //active we scale them by the same factor.
+
+    //This algorithm is probably not stable or very good, but it's something.
+
+    //Target is 75% of alloced time.
+    d=(tS-start_time)/(timeout_time-start_time)-0.75;
+
+    ode=task->next_ode;
+    while (ode!=&task->next_ode) {
+      if (!(ode->flags&ODEF_PAUSED) && ode->derive) {
+        if (ode->min_tolerance!=ode->max_tolerance) {
+          if (d>0)
+            ode->tolerance_internal*=10.0`d;
+          else
+            ode->tolerance_internal*=2.0`d;
+        }
+        ode->tolerance_internal=Clamp(ode->tolerance_internal,
+              ode->min_tolerance,ode->max_tolerance);
+      }
+      ode=ode->next;
+    }
+    winmgr.ode_time+=task->last_ode_time=tS-start_time;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AMem.HC.HTML b/public/Wb/Home/Src/Adam/AMem.HC.HTML new file mode 100755 index 0000000..64e0d3c --- /dev/null +++ b/public/Wb/Home/Src/Adam/AMem.HC.HTML @@ -0,0 +1,210 @@ + + + + + + + + + + + +
+#help_index "Memory/Task"
+public I64 TaskMemAlloced(CTask *task=NULL,Bool override_validate=FALSE)
+{//Count of bytes alloced to a task, used+unused.
+  I64 res;
+  if (!task) task=Fs;
+  if (override_validate || TaskValidate(task)) {
+    res=task->code_heap->alloced_u8s;
+    if (task->code_heap!=task->data_heap)
+      res+=task->data_heap->alloced_u8s;
+    return res;
+  } else
+    return 0;
+}
+
+public I64 TaskMemUsed(CTask *task=NULL,Bool override_validate=FALSE)
+{//Count of bytes alloced to a task and in use.
+  I64 res;
+  if (!task) task=Fs;
+  if (override_validate || TaskValidate(task)) {
+    res=task->code_heap->used_u8s;
+    if (task->data_heap!=task->code_heap)
+      res+=task->data_heap->used_u8s;
+    return res;
+  } else
+    return 0;
+}
+
+#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
+public Bool HeapRep(CTask *task)
+{//Report status of task's heap.
+  I64 i,cnt;
+  CMemUnused *uum;
+
+  if (!task || task==Fs) {
+    "Task can't HeapRep on self.\n";
+    return FALSE;
+  }
+  if (!TaskValidate(task)) return FALSE;
+
+  PUSHFD
+  CLI
+  while (LBts(&task->code_heap->locked_flags,HClf_LOCKED))
+    PAUSE
+  if (task->data_heap!=task->code_heap)
+    while (LBts(&task->data_heap->locked_flags,HClf_LOCKED))
+      PAUSE
+
+  for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
+    cnt=0;
+    uum=task->code_heap->heap_hash[i];
+    while (uum) {
+      cnt+=uum->size;
+      uum=uum->next;
+    }
+    if (task->data_heap!=task->code_heap) {
+      uum=task->data_heap->heap_hash[i];
+      while (uum) {
+        cnt+=uum->size;
+        uum=uum->next;
+      }
+    }
+    if (cnt)
+      "%03X:%08X\n",i<<3,cnt;
+  }
+  '\n';
+
+  uum=task->code_heap->malloc_free_lst;
+  while (uum) {
+    "%X, ",uum->size;
+    uum=uum->next;
+  }
+  if (task->data_heap!=task->code_heap) {
+    uum=task->data_heap->malloc_free_lst;
+    while (uum) {
+      "%X, ",uum->size;
+      uum=uum->next;
+    }
+  }
+
+  if (task->data_heap!=task->code_heap)
+    LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
+  LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
+  POPFD
+
+  '\n';
+}
+
+#help_index "Memory/HeapCtrl;Debugging/Heap;Memory/Debugging"
+public Bool IsInHeapCtrl(U8 *a,CHeapCtrl *hc,Bool lock=TRUE)
+{//Check addr if in HeapCtrl.
+  CMemBlk *m;
+  PUSHFD
+  CLI
+  if (lock)
+    while (LBts(&hc->locked_flags,HClf_LOCKED))
+      PAUSE
+  m=hc->next_mem_blk;
+  while (m!=&hc->next_mem_blk) {
+    if (a>=m && a<m(U8 *)+m->pags<<MEM_PAG_BITS) {
+      if (lock)
+        LBtr(&hc->locked_flags,HClf_LOCKED);
+      POPFD
+      return TRUE;
+    }
+    m=m->next;
+  }
+  if (lock)
+    LBtr(&hc->locked_flags,HClf_LOCKED);
+  POPFD
+  return FALSE;
+}
+
+public Bool HeapCtrlWalk(CHeapCtrl *hc)
+{//Check integrity of HeapCtrl.
+  I64 i;
+  CMemUnused *uum;
+
+  PUSHFD
+  CLI
+  while (LBts(&hc->locked_flags,HClf_LOCKED))
+    PAUSE
+
+  for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
+    uum=hc->heap_hash[i];
+    while (uum) {
+      if (!IsInHeapCtrl(uum,hc,FALSE))
+        goto hc_false;
+      uum=uum->next;
+    }
+  }
+  uum=hc->malloc_free_lst;
+  while (uum) {
+    if (!IsInHeapCtrl(uum,hc,FALSE))
+      goto hc_false;
+    uum=uum->next;
+  }
+
+  #if _CFG_HEAP_DBG
+  CMemUsed *um,*um1;
+  um1=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
+  um=um1->next;
+  while (um!=um1) {
+    if (!IsInHeapCtrl(um,hc,FALSE))
+      goto hc_false;
+    um=um->next;
+  }
+#endif
+
+  LBtr(&hc->locked_flags,HClf_LOCKED);
+  POPFD
+  return TRUE;
+
+  hc_false:
+  LBtr(&hc->locked_flags,HClf_LOCKED);
+  POPFD
+  return FALSE;
+}
+
+#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
+public Bool IsInHeap(U8 *a,CTask *task=NULL,Bool lock=TRUE)
+{//Check addr if in task's heaps.
+  if (!task) task=Fs;
+  if (TaskValidate(task) && (IsInHeapCtrl(a,task->code_heap,lock)||
+        task->data_heap!=task->code_heap &&
+        IsInHeapCtrl(a,task->data_heap,lock)))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+public Bool HeapWalk(CTask *task=NULL)
+{//Check integrity of task's heaps.
+  if (!task) task=Fs;
+  if (!TaskValidate(task) || !HeapCtrlWalk(task->code_heap) ||
+        task->data_heap!=task->code_heap && !HeapCtrlWalk(task->data_heap))
+    return FALSE;
+  else
+    return TRUE;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AMouse.HC.HTML b/public/Wb/Home/Src/Adam/AMouse.HC.HTML new file mode 100755 index 0000000..17f5253 --- /dev/null +++ b/public/Wb/Home/Src/Adam/AMouse.HC.HTML @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+#help_index "Graphics/Misc;Mouse/Ptr"
+
+<1>/* Graphics Not Rendered in HTML */
+
+gr.empty_sprite=<1>;
+
+<2>/* Graphics Not Rendered in HTML */
+
+<3>/* Graphics Not Rendered in HTML */
+
+public U0 DrawGrabMs(CDC *dc,I64 x,I64 y,Bool closed)
+{//This is a callback. See ::/Demo/Graphics/Grid.HC.
+  dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
+  dc->color=ROP_EQU;
+  if (closed)
+    Sprite3(dc,x,y,0,<2>);
+  else
+    Sprite3(dc,x,y,0,<3>);
+}
+gr.fp_draw_grab_ms=&DrawGrabMs;
+
+ diff --git a/public/Wb/Home/Src/Adam/ARegistry.HC.HTML b/public/Wb/Home/Src/Adam/ARegistry.HC.HTML new file mode 100755 index 0000000..ce02786 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ARegistry.HC.HTML @@ -0,0 +1,234 @@ + + + + + + + + + + + +
+#help_index "Registry"
+#define REGISTRY_FILENAME "~/Registry.HC.Z"
+CDoc *sys_registry_doc=NULL;
+I64 sys_msg_flags[1]={0};
+F64 registry_version;
+
+Bool RegCache()
+{
+  Bool old_silent;
+  if (!sys_registry_doc) {
+    old_silent=Silent;
+    sys_registry_doc=DocRead(REGISTRY_FILENAME);
+    Silent(old_silent);
+    return FALSE;
+  } else
+    return TRUE;
+}
+
+public Bool RegDft(U8 *path,U8 *val,Bool is_adam_entry=FALSE)
+{//Add code doc tree branch to registry.
+  Bool res,unlock_doc;
+  RegCache;
+  unlock_doc=DocLock(sys_registry_doc);
+  if (!DocTreeFind(sys_registry_doc,path)) {
+    DocTreeMake(sys_registry_doc,path);
+    DocPrint(sys_registry_doc,"%s",val);
+    if (is_adam_entry) {
+      if (Fs==adam_task)
+        ExePrint("%s",val);
+      else
+        Adam("%s",val);
+    }
+    if (DrvIsWritable(*sys_registry_doc->filename.name))
+      DocWrite(sys_registry_doc);
+    res=FALSE;
+  } else
+    res=TRUE;
+  if (unlock_doc)
+    DocUnlock(sys_registry_doc);
+  return res;
+}
+
+public I64 RegExe(U8 *path)
+{//Execute doc tree branch in registry.
+  RegCache;
+  return DocTreeExe(sys_registry_doc,path);
+}
+
+public Bool RegWrite(U8 *path,U8 *fmt,...)
+{//Rewrite doc tree branch in registry.
+  Bool res;
+  RegCache;
+  res=DocTreeWriteJoin(sys_registry_doc,path,TRUE,fmt,argc,argv);
+  return res;
+}
+
+public I64 RegCnt(U8 *path)
+{//Tree branch cnt in registry.
+  I64 res=0;
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  Bool unlock_doc=DocLock(sys_registry_doc);
+  if (DocTreeFind(sys_registry_doc,path,
+        &tree_branch,&start_indent,&end_indent)) {
+    end_indent=end_indent->next;
+    while (start_indent!=end_indent) {
+      res++;
+      start_indent=start_indent->next;
+    }
+  }
+  if (unlock_doc)
+    DocUnlock(sys_registry_doc);
+  return res;
+}
+
+public Bool RegAppend(U8 *path,U8 *fmt,...)
+{//Append to doc tree branch in registry.
+  Bool res;
+  RegCache;
+  res=DocTreeAppendJoin(sys_registry_doc,path,TRUE,fmt,argc,argv);
+  return res;
+}
+ 
+public Bool OneTimePopUp(U8 *_flags,I64 flag_num,U8 *msg)
+{//See ::/Apps/X-Caliber/X-Caliber.HC.
+  Bool res=FALSE;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e;
+  if (!Bt(_flags,flag_num)) {
+    if (msg) DocPrint(doc,"%s",msg);
+    doc_e=DocPrint(doc,"\n$CB,\"Do not show this msg again.\",LE=1$");
+    DocPrint(doc,"$CM+CX,0,4$$BT,\"OKAY\",LE=1$\n");
+    if (PopUpMenu(doc)==1 && doc_e->de_flags&DOCEF_CHECKED_COLLAPSED) {
+      LBts(_flags,flag_num);
+      res=TRUE;
+    }
+    DocDel(doc);
+  }
+  return res;
+}
+
+U0 RegOneTimePopUp(I64 flag_num,U8 *msg)
+{//You're not supposed to make system pop-up flags, only me.
+  if (OneTimePopUp(sys_msg_flags,flag_num,msg))
+    RegWrite("Adam/SysMsgFlags","sys_msg_flags[0]=0x%X;\n",
+          sys_msg_flags[0]);
+}
+
+U0 RegInit()
+{
+  U8 buf[STR_LEN];
+  Bool version_present;
+  RegDft("Adam/SysMsgFlags","sys_msg_flags[0]=0;\n",TRUE);
+  StrPrint(buf,"registry_version=%4.3f;\n",sys_os_version);
+  version_present=RegDft("Adam/SysRegVer",buf,TRUE);
+  RegExe("Adam");
+  if (registry_version!=sys_os_version) {
+    RegWrite("Adam/SysRegVer",buf);
+    RegExe("Adam");
+  }
+}
+
+#help_index "Boot/Once;Registry/Once"
+#help_file "::/Doc/Once"
+
+public U0 AOnceFlush()
+{//Flush AOnce() buf.
+  RegWrite("Once/Adam","");
+}
+
+public U0 OnceFlush()
+{//Flush Once() buf.
+  RegWrite("Once/User","");
+}
+
+public U0 AOnce(U8 *fmt,...)
+{//Add Adam code to ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (!Bt(&sys_run_level,RLf_ONCE_ADAM))
+    AOnceFlush;
+  RegAppend("Once/Adam","%s\n",buf);
+  Free(buf);
+}
+
+public U0 Once(U8 *fmt,...)
+{//Add User code to ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (!Bt(&sys_run_level,RLf_ONCE_USER))
+    OnceFlush;
+  RegAppend("Once/User","%s\n",buf);
+  Free(buf);
+}
+
+public U0 AOnceDrv(U8 drv_let=0,U8 *fmt,...)
+{//Add Adam code to drv ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 old_drv_let=*sys_registry_doc->filename.name;
+  if (drv_let)
+    *sys_registry_doc->filename.name=drv_let;
+  if (!Bt(&sys_run_level,RLf_ONCE_ADAM))
+    AOnceFlush;
+  RegAppend("Once/Adam","%s\n",buf);
+  Free(buf);
+  *sys_registry_doc->filename.name=old_drv_let;
+}
+
+public U0 OnceDrv(U8 drv_let=0,U8 *fmt,...)
+{//Add User code to drv ~/Registry.HC, executed next boot.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 old_drv_let=*sys_registry_doc->filename.name;
+  if (drv_let)
+    *sys_registry_doc->filename.name=drv_let;
+  if (!Bt(&sys_run_level,RLf_ONCE_USER))
+    OnceFlush;
+  RegAppend("Once/User","%s\n",buf);
+  Free(buf);
+  *sys_registry_doc->filename.name=old_drv_let;
+}
+
+public U0 OnceExe()
+{//Execute Once code. Call goes in ~/Once.HC.
+  try {
+
+    RegDft("Once/Adam","");
+    if (RegCnt("Once/Adam")>2) {
+      Adam("RegExe(\"Once/Adam\");");
+      AOnceFlush;
+    }
+    LBts(&sys_run_level,RLf_ONCE_ADAM);
+
+    RegDft("Once/User","");
+    if (RegCnt("Once/User")>2) {
+      RegExe("Once/User");
+      OnceFlush;
+    }
+    LBts(&sys_run_level,RLf_ONCE_USER);
+
+  } catch {
+    AOnceFlush;
+    LBts(&sys_run_level,RLf_ONCE_ADAM);
+    OnceFlush;
+    LBts(&sys_run_level,RLf_ONCE_USER);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/ASnd.HC.HTML b/public/Wb/Home/Src/Adam/ASnd.HC.HTML new file mode 100755 index 0000000..90ba6e8 --- /dev/null +++ b/public/Wb/Home/Src/Adam/ASnd.HC.HTML @@ -0,0 +1,440 @@ + + + + + + + + + + + +
+#help_index "Snd"
+public U0 SndTaskEndCB()
+{//Will turn-off snd when a task gets killed.
+  Snd;
+  Exit;
+}
+
+#help_index "Snd/Math;Math"
+public F64 Saw(F64 t,F64 period)
+{//Sawtooth. 0.0 - 1.0 think "(Sin+1)/2"
+  if (period) {
+    if (t>=0.0)
+      return t%period/period;
+    else
+      return 1.0+t%period/period;
+  } else
+    return 0.0;
+}
+
+public F64 FullSaw(F64 t,F64 period)
+{//Plus&Minus Sawtooth. 1.0 - -1.0 think "Sin"
+  if (period) {
+    if (t>=0.0)
+      return 2.0*(t%period/period)-1.0;
+    else
+      return 2.0*(t%period/period)+1.0;
+  } else
+    return 0.0;
+}
+
+public F64 Caw(F64 t,F64 period)
+{//Cawtooth. 1.0 - 0.0 think "(Cos+1)/2"
+  if (period) {
+    if (t>=0.0)
+      return 1.0-t%period/period;
+    else
+      return -(t%period)/period;
+  } else
+    return 1.0;
+}
+
+public F64 FullCaw(F64 t,F64 period)
+{//Plus&Minus Cawtooth. 1.0 - -1.0 think "Cos"
+  if (period) {
+    if (t>=0.0)
+      return -2.0*(t%period/period)+1.0;
+    else
+      return -2.0*(t%period/period)-1.0;
+  } else
+    return 1.0;
+}
+
+public F64 Tri(F64 t,F64 period)
+{//Triangle waveform. 0.0 - 1.0 - 0.0
+  if (period) {
+    t=2.0*(Abs(t)%period)/period;
+    if (t<=1.0)
+      return t;
+    else
+      return 2.0-t;
+  } else
+    return 0.0;
+}
+
+public F64 FullTri(F64 t,F64 period)
+{//Plus&Minus Triangle waveform. 0.0 - 1.0 - 0.0 - -1.0 -0.0
+  if (period) {
+    t=4.0*(t%period)/period;
+    if (t<=-1.0) {
+      if (t<=-3.0)
+        return t+4.0;
+      else
+        return -2.0-t;
+    } else {
+      if (t<=1.0)
+        return t;
+      else if (t<=3.0)
+        return 2.0-t;
+      else
+        return t-4.0;
+    }
+  } else
+    return 0.0;
+}
+
+#help_index "Snd/Music"
+
+public class CMusicGlbls
+{
+  U8    *cur_song;
+  CTask *cur_song_task;
+  I64   octave;
+  F64   note_len;
+  U8    note_map[7];
+  Bool  mute;
+  I64   meter_top,meter_bottom;
+  F64   tempo,stacatto_factor;
+
+  //If you wish to sync with a
+  //note in a Play() string.  0 is the start
+  I64   play_note_num;
+
+  F64   tM_correction,last_Beat,last_tM;
+} music={NULL,NULL,4,1.0,{0,2,3,5,7,8,10},FALSE,4,4,2.5,0.9,0,0,0,0};
+
+#help_index "Snd/Music;Time/Seconds"
+public F64 tM()
+{//Time in seconds synced to music subsystem.
+  return (cnts.jiffies+music.tM_correction)/JIFFY_FREQ;
+}
+
+public F64 Beat()
+{//Time in music beats.
+  F64 res,cur_tM;
+  PUSHFD
+  CLI
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_TMBEAT],0))
+      PAUSE
+  cur_tM=tM;
+  res=music.last_Beat;
+  if (music.tempo)
+    res+=(cur_tM-music.last_tM)*music.tempo;
+  music.last_tM=cur_tM;
+  music.last_Beat=res;
+  LBtr(&sys_semas[SEMA_TMBEAT],0);
+  POPFD
+  return res;
+}
+
+#help_index "Snd/Music"
+U8 *MusicSetOctave(U8 *st)
+{
+  I64 ch;
+  ch=*st++;
+  while ('0'<=ch<='9') {
+    music.octave=ch-'0';
+    ch=*st++;
+  }
+  return --st;
+}
+
+U8 *MusicSetMeter(U8 *st)
+{
+  I64 ch;
+  ch=*st++;
+  while (ch=='M') {
+    ch=*st++;
+    if ('0'<=ch<='9') {
+      music.meter_top=ch-'0';
+      ch=*st++;
+    }
+    if (ch=='/')
+      ch=*st++;
+    if ('0'<=ch<='9') {
+      music.meter_bottom=ch-'0';
+      ch=*st++;
+    }
+  }
+  return --st;
+}
+
+U8 *MusicSetNoteLen(U8 *st)
+{
+  Bool cont=TRUE;
+  do {
+    switch (*st++) {
+      case 'w': music.note_len=4.0;  break;
+      case 'h': music.note_len=2.0;  break;
+      case 'q': music.note_len=1.0;  break;
+      case 'e': music.note_len=0.5;   break;
+      case 's': music.note_len=0.25;   break;
+      case 't': music.note_len=2.0*music.note_len/3.0; break;
+      case '.': music.note_len=1.5*music.note_len; break;
+      default:
+        st--;
+        cont=FALSE;
+    }
+  } while (cont);
+  return st;
+}
+
+public I8 Note2Ona(I64 note,I64 octave=4)
+{//Note to ona. Mid C is ona=51, note=3 and octave=4.
+  if (note<3)
+    return (octave+1)*12+note;
+  else
+    return octave*12+note;
+}
+
+public I8 Ona2Note(I8 ona)
+{//Ona to note in octave. Mid C is ona=51, note=3 and octave=4.
+  return ona%12;
+}
+
+public I8 Ona2Octave(I8 ona)
+{//Ona to octave. Mid C is ona=51, note=3 and octave=4.
+  I64 note=ona%12,octave=ona/12;
+  if (note<3)
+    return octave-1;
+  else
+    return octave;
+}
+
+public U0 Play(U8 *st,U8 *words=NULL)
+{/* Notes are entered with a capital letter.
+
+Octaves are entered with a digit and
+stay set until changed.  Mid C is octave 4.
+
+Durations are entered with
+'w' whole note
+'h' half note
+'q' quarter note
+'e' eighth note
+'t' sets to 2/3rds the current duration
+'.' sets to 1.5 times the current duration
+durations stay set until changed.
+
+'(' tie, placed before the note to be extended
+
+music.meter_top,music.meter_bottom is set with
+"M3/4"
+"M4/4"
+etc.
+
+Sharp and flat are done with '#' or 'b'.
+
+The var music.stacatto_factor can
+be set to a range from 0.0 to 1.0.
+
+The var music.tempo is quarter-notes
+per second.  It defaults to
+2.5 and gets faster when bigger.
+*/
+  U8 *word,*last_st;
+  I64 note,octave,i=0,ona,timeout_val,timeout_val2;
+  Bool tie;
+  F64 d,on_jiffies,off_jiffies;
+  music.play_note_num=0;
+  while (*st) {
+    timeout_val=cnts.jiffies;
+    tie=FALSE;
+
+    do {
+      last_st=st;
+      if (*st=='(') {
+        tie=TRUE;
+        st++;
+      } else {
+        st=MusicSetMeter(st);
+        st=MusicSetOctave(st);
+        st=MusicSetNoteLen(st);
+      }
+    } while (st!=last_st);
+
+    if (!*st) break;
+    note=*st++-'A';
+    if (note<7) {
+      note=music.note_map[note];
+      octave=music.octave;
+      if (*st=='b') {
+        note--;
+        if (note==2)
+          octave--;
+        st++;
+      } else if (*st=='#') {
+        note++;
+        if (note==3)
+          octave++;
+        st++;
+      }
+      ona=Note2Ona(note,octave);
+    } else
+      ona=0;
+    if (words && (word=LstSub(i++,words)) && StrCmp(word," "))
+      "%s",word;
+
+    d=JIFFY_FREQ*music.note_len/music.tempo;
+    on_jiffies  =d*music.stacatto_factor;
+    off_jiffies =d*(1.0-music.stacatto_factor);
+
+    timeout_val+=on_jiffies;
+    timeout_val2=timeout_val+off_jiffies;
+
+    if (!music.mute)
+      Snd(ona);
+    SleepUntil(timeout_val);
+    music.tM_correction+=on_jiffies-ToI64(on_jiffies);
+
+    if (!music.mute && !tie)
+      Snd;
+    SleepUntil(timeout_val2);
+    music.tM_correction+=off_jiffies-ToI64(off_jiffies);
+
+    music.play_note_num++;
+  }
+}
+
+U0 MusicSettingsRst()
+{
+  music.play_note_num=0;
+  music.stacatto_factor=0.9;
+  music.tempo=2.5;
+  music.octave=4;
+  music.note_len=1.0;
+  music.meter_top=4;
+  music.meter_bottom=4;
+  SndRst;
+  PUSHFD
+  CLI
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_TMBEAT],0))
+      PAUSE
+  music.last_tM=tM;
+  music.last_Beat=0.0;
+  LBtr(&sys_semas[SEMA_TMBEAT],0);
+  POPFD
+}
+
+MusicSettingsRst;
+
+U0 CurSongTask()
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  while (TRUE)
+    Play(music.cur_song);
+}
+
+#help_index "Snd"
+
+#define SE_NOISE        0
+#define SE_SWEEP        1
+
+class CSoundEffectFrame
+{
+  I32   type;
+  I8    ona1,ona2;
+  F64   duration;
+};
+
+U0 SoundEffectEndTaskCB()
+{
+  Free(FramePtr("CSoundEffectFrame"));
+  music.mute--;
+  SndTaskEndCB;
+}
+
+U0 SoundEffectTask(CSoundEffectFrame *ns)
+{
+  I64 i,ona;
+  F64 t0=tS,t,timeout=t0+ns->duration;
+  FramePtrAdd("CSoundEffectFrame",ns);
+  Fs->task_end_cb=&SoundEffectEndTaskCB;
+  switch (ns->type) {
+    case SE_NOISE:
+      i=MaxI64(ns->ona2-ns->ona1,1);
+      while (tS<timeout) {
+        ona=RandU16%i+ns->ona1;
+        Snd(ona);
+        t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0);
+        if (t+tS>timeout)
+          t=timeout-tS;
+        Sleep(t);
+      }
+      break;
+    case SE_SWEEP:
+      while (tS<timeout) {
+        t=(tS-t0)/ns->duration;
+        ona=(1.0-t)*ns->ona1+t*ns->ona2;
+        Snd(ona);
+        t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0);
+        if (t+tS>timeout)
+          t=timeout-tS;
+        Sleep(t);
+      }
+      break;
+  }
+}
+
+public CTask *Noise(I64 mS,F64 min_ona,F64 max_ona)
+{//Make white noise for given number of mS.
+  CSoundEffectFrame *ns;
+  if (mS>0) {
+    ns=MAlloc(sizeof(CSoundEffectFrame));
+    ns->type=SE_NOISE;
+    ns->duration=mS/1000.0;
+    ns->ona1=min_ona;
+    ns->ona2=max_ona;
+    music.mute++;
+    return Spawn(&SoundEffectTask,ns,"Noise",,Fs);
+  } else
+    return NULL;
+}
+
+public CTask *Sweep(I64 mS,F64 ona1,F64 ona2)
+{//Sweep through freq range in given number of mS.
+  CSoundEffectFrame *ns;
+  if (mS>0) {
+    ns=MAlloc(sizeof(CSoundEffectFrame));
+    ns->type=SE_SWEEP;
+    ns->duration=mS/1000.0;
+    ns->ona1=ona1;
+    ns->ona2=ona2;
+    music.mute++;
+    return Spawn(&SoundEffectTask,ns,"Noise",,Fs);
+  } else
+    return NULL;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AutoComplete/ACDictGen.HC.HTML b/public/Wb/Home/Src/Adam/AutoComplete/ACDictGen.HC.HTML new file mode 100755 index 0000000..1c787fb --- /dev/null +++ b/public/Wb/Home/Src/Adam/AutoComplete/ACDictGen.HC.HTML @@ -0,0 +1,292 @@ + + + + + + + + + + + +
+/*
+This file is a stand-alone program
+which will regenerate processed dictionary
+files from a raw Project Gutenberg
+dictionary file.
+
+See ::/Doc/Credits.DD.
+*/
+
+U0 ACDPreprocess(U8 *in_name,U8 *out_name)
+{/*
+<cr><nl>--> <nl>
+$       --> $$
+\'89    --> .
+*/
+  I64 ch,i;
+  U8 *src,*dst;
+  CDoc *doc;
+  CDocEntry *doc_e;
+  if (doc=DocRead(in_name,DOCF_PLAIN_TEXT_TABS|DOCF_DBL_DOLLARS)) {
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      if (doc_e->type_u8==DOCT_TEXT) {
+        src=dst=doc_e->tag;
+        while (ch=*src++) {
+          if (ch=='\\' && *src=='\'') {
+            src++;
+            i=0;
+            ch=ToUpper(*src++);
+            if ('0'<=ch<='9')
+              i+=ch-'0';
+            else if ('A'<=ch<='F')
+              i+=ch-'A'+10;
+            i<<=4;
+            ch=ToUpper(*src++);
+            if ('0'<=ch<='9')
+              i+=ch-'0';
+            else if ('A'<=ch<='F')
+              i+=ch-'A'+10;
+            *dst++=i;
+          } else
+            *dst++=ch;
+        }
+        *dst=0;
+      }
+      doc_e=doc_e->next;
+    }
+    StrCpy(doc->filename.name,out_name);
+    DocWrite(doc);
+    DocDel(doc);
+  }
+}
+
+I64 ACDNextCmd(U8 **_ptr)
+{
+  U8 *ptr=*_ptr,*ptr2;
+  I64 ch,res=-1;
+  do {
+    do {
+      if (!(ch=*ptr++)) goto ncmd_done;
+    } while (ch!='<');
+
+    ptr2=ptr;
+    do {
+      if (!(ch=*ptr2++)) goto ncmd_done;
+    } while (ch!='>');
+    *--ptr2=0;
+    res=LstMatch(ptr,"h1\0/h1\0def\0/def\0hw\0/hw\0tt\0/tt\0"
+          "ety\0@fld\0@cd\0@blockquote\0@wordforms\0@note\0@altname\0@chform\0"
+          "@cref\0@syn\0/ety\0@/fld\0@/cd\0@/blockquote\0@/wordforms\0@/note\0"
+          "@/altname\0@/chform\0@/cref\0@/syn\0");
+    *ptr2++='>';
+    ptr=ptr2;
+  } while (res<0);
+
+  ncmd_done:
+  *_ptr=ptr;
+  return res;
+}
+
+U8 *ACDNextEntry(U8 **_ptr)
+{
+  U8 *res,*ignore,*ptr=*_ptr,buf[ACD_BLK_SIZE],*out_ptr=buf;
+  I64 ch,l;
+  while (TRUE) {
+    while (TRUE) {
+      if (!(ch=*ptr++)) goto nentry_done;
+      if (ch!='<') {
+        *out_ptr++=ch;
+        if (ch=='$')
+          *out_ptr++=ch;
+      } else
+        break;
+    }
+    ignore="b>\0i>\0ppp>\0/b>\0/i>\0/p>\0"
+          "ets>\0col>\0spn>\0/ets>\0/col>\0/spn>\0er>\0as>\0cs>\0cd>\0ex>\0"
+          "/er>\0/as>\0/cs>\0/cd>\0/ex>\0"
+          "note>\0/note>\0blockquote>\0/blockquote>\0";
+    while (*ignore) {
+      l=StrLen(ignore);
+      if (!StrNCmp(ptr,ignore,l)) {
+        ptr+=l;
+        break;
+      } else
+        ignore+=l+1;
+    }
+    if (!*ignore)
+      break;
+  }
+nentry_done:
+  *out_ptr++=0;
+  res=StrNew(buf);
+  *_ptr=ptr-1;
+  return res;
+}
+
+I64 ACDCompareWords(U8 *e1,U8 *e2)
+{
+  return StrICmp(e1,e2);
+}
+
+U8 *ACDSortWords(U8 *start,I64 size,I64 word_cnt)
+{
+  U8 **ptr_array=MAlloc(sizeof(U8 *)*word_cnt),
+        *out_start=MAlloc(size),
+        *ptr=start,*ptr2;
+  I64 i=0;
+  while (*ptr) {
+    ptr_array[i++]=ptr;
+    ptr+=StrLen(ptr)+3;
+  }
+  "Sorting...\n"; Sleep(100);
+  QSortI64(ptr_array,word_cnt,&ACDCompareWords);
+  "Done...\n"; Sleep(100);
+
+  ptr=out_start;
+  for (i=0;i<word_cnt;i++) {
+    ptr2=ptr_array[i];
+    while (*ptr2)
+      *ptr++=*ptr2++;
+    *ptr++=*ptr2++; //zero
+    *ptr++=*ptr2++; //blk lo
+    *ptr++=*ptr2++; //blk hi
+  }
+  *ptr++=0;
+  return out_start;
+}
+
+U0 ACDGen(U8 *in_file)
+{
+  I64 cmd,size,word_cnt=0,largest_entry=0;
+  U8 *st,*in_ptr=FileRead(in_file,&size),*in_start=in_ptr,
+        *out_ptr=MAlloc(size),*out_start=out_ptr,
+        *word_ptr=MAlloc(size),*word_start=word_ptr,
+        *last_word="",*def_word_start=out_ptr,
+        *sorted_word_start;
+  U16 *d;
+  if (!in_ptr) return;
+  do {
+    cmd=ACDNextCmd(&in_ptr);
+    if (cmd==ACD_H1) {
+next_word:
+      if (out_ptr-def_word_start>largest_entry)
+        largest_entry=out_ptr-def_word_start;
+      def_word_start=out_ptr;
+      if (st=ACDNextEntry(&in_ptr)) {
+        if (*st) {
+          if (StrICmp(st,last_word)) {
+            word_cnt++;
+
+            *word_ptr++=ACD_WORD_CHAR;
+            last_word=word_ptr;
+            StrCpy(word_ptr,st);
+            word_ptr+=StrLen(st)+1;
+
+            d=word_ptr;
+            *d=(out_ptr-out_start)/ACD_BLK_SIZE;
+            word_ptr+=2;
+
+            *out_ptr++=ACD_WORD_CHAR;
+            StrCpy(out_ptr,st);
+            out_ptr+=StrLen(st)+1;
+          }
+          Free(st);
+
+          do {
+            do {
+              cmd=ACDNextCmd(&in_ptr);
+              if (cmd==ACD_H1)
+                goto next_word;
+            } while (cmd>=0 && !(cmd==ACD_DEF||cmd==ACD_PRONUNCIATION||
+                  cmd==ACD_POS||cmd==ACD_EXTRA));
+            if (cmd==ACD_DEF) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_DEF_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            } else if (cmd==ACD_PRONUNCIATION) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_PRONUNCIATION_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            } else if (cmd==ACD_POS) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_POS_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            } else if (cmd==ACD_EXTRA) {
+              if(st=ACDNextEntry(&in_ptr)) {
+                if (*st) {
+                  *out_ptr++=ACD_EXTRA_CHAR;
+                  StrCpy(out_ptr,st);
+                  out_ptr+=StrLen(st)+1;
+                }
+                Free(st);
+              }
+            }
+          } while (cmd==ACD_DEF||cmd==ACD_PRONUNCIATION||
+                cmd==ACD_POS||cmd==ACD_EXTRA);
+        } else
+          Free(st);
+      }
+    }
+  } while (cmd>=0);
+  *out_ptr++=ACD_END_CHAR;
+  *word_ptr++=ACD_END_CHAR;
+
+  Free(in_start);
+
+  "Blk Size      :%d\n",ACD_BLK_SIZE;
+  "Blk Cnt       :%04X\n",(out_ptr-out_start+ACD_BLK_SIZE-1)/ACD_BLK_SIZE;
+  "Largest Entry :%d\n",largest_entry;
+  "Word Count    :%d\n",word_cnt;
+
+  FileWrite(ACD_DEF_FILENAME,out_start,out_ptr-out_start);
+  "Def File Size :%d\n",out_ptr-out_start;
+
+  sorted_word_start=ACDSortWords(word_start,word_ptr-word_start,word_cnt);
+  FileWrite(ACD_WORD_FILENAME,sorted_word_start,word_ptr-word_start);
+  "Word File Size:%d\n",word_ptr-word_start;
+
+  Free(out_start);
+  Free(word_start);
+  Free(sorted_word_start);
+}
+
+Cd(__DIR__);
+ACDPreprocess("DICTIONARY.DD","DICTIONARY2.DD");
+ACDGen("DICTIONARY2.DD");
+
+ diff --git a/public/Wb/Home/Src/Adam/AutoComplete/ACFill.HC.HTML b/public/Wb/Home/Src/Adam/AutoComplete/ACFill.HC.HTML new file mode 100755 index 0000000..da4a8ad --- /dev/null +++ b/public/Wb/Home/Src/Adam/AutoComplete/ACFill.HC.HTML @@ -0,0 +1,257 @@ + + + + + + + + + + + +
+#help_index "AutoComplete/Dictionary"
+public U8 *ACDDefGet(U8 *st,I64 def_num=1)
+{//MAlloc str holding single dict definition of word.
+  CFile *f;
+  CHashGeneric *tmph;
+  U8 *res=NULL,*buf,*in_ptr,
+        *st2=MStrUtil(st,SUF_TO_UPPER);
+  tmph=HashFind(st2,ac.hash_table,HTT_DICT_WORD);
+  Free(st2);
+  if (tmph) {
+    if (f=FOpen(ACD_DEF_FILENAME,"r")) {
+      buf=MAlloc(ACD_BLK_SIZE*2+1);
+      buf[ACD_BLK_SIZE*2]=0; //terminate
+      FBlkRead(f,buf,tmph->user_data0*ACD_BLK_SIZE/BLK_SIZE,
+            ACD_BLK_SIZE*2/BLK_SIZE);
+      FClose(f);
+      in_ptr=buf;
+      while (in_ptr<buf+ACD_BLK_SIZE*2) {
+        while (*in_ptr!=ACD_WORD_CHAR && in_ptr<buf+ACD_BLK_SIZE*2)
+          in_ptr++;
+        if (*in_ptr++==ACD_WORD_CHAR) {
+          if (!StrICmp(st,in_ptr)) {
+            while (def_num && *in_ptr!=ACD_WORD_CHAR
+                  && in_ptr<buf+ACD_BLK_SIZE*2) {
+              if (*in_ptr==ACD_DEF_CHAR) {
+                if (!--def_num)
+                  break;
+                else
+                  in_ptr++;
+              } else
+                in_ptr++;
+            }
+            if (*in_ptr++==ACD_DEF_CHAR) {
+              res=StrNew(in_ptr);
+              break;
+            }
+          }
+        }
+      }
+      Free(buf);
+    }
+  }
+  return res;
+}
+
+public U8 *ACDDefsGet(U8 *st)
+{//MAlloc str with all dict definitions of word.
+  CFile *f;
+  CHashGeneric *tmph;
+  U8 *res=NULL,*buf,*in_ptr,*in_ptr2,
+        *st2=MStrUtil(st,SUF_TO_UPPER);
+  tmph=HashFind(st2,ac.hash_table,HTT_DICT_WORD);
+  Free(st2);
+  if (tmph) {
+    if (f=FOpen(ACD_DEF_FILENAME,"r")) {
+      buf=MAlloc(ACD_BLK_SIZE*2+1);
+      buf[ACD_BLK_SIZE*2]=0; //terminate
+      FBlkRead(f,buf,tmph->user_data0*ACD_BLK_SIZE/BLK_SIZE,
+            ACD_BLK_SIZE*2/BLK_SIZE);
+      FClose(f);
+      in_ptr=buf;
+      while (in_ptr<buf+ACD_BLK_SIZE*2) {
+        while (*in_ptr!=ACD_WORD_CHAR && in_ptr<buf+ACD_BLK_SIZE*2)
+          in_ptr++;
+        if (*in_ptr++==ACD_WORD_CHAR) {
+          if (!StrICmp(st,in_ptr)) {
+            in_ptr2=in_ptr;
+            in_ptr--;
+            while (*in_ptr2!=ACD_WORD_CHAR
+                  && in_ptr2<buf+ACD_BLK_SIZE*2) {
+              in_ptr2++;
+            }
+            res=MAlloc(in_ptr2+1-in_ptr);
+            MemCpy(res,in_ptr,in_ptr2-in_ptr);
+            res[in_ptr2-in_ptr]=ACD_END_CHAR;
+            break;
+          }
+        }
+      }
+      Free(buf);
+    }
+  }
+  return res;
+}
+
+/*Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block;
+*/
+public U8 *ACDWordPtAt(U8 *st)
+{//Point to word in word list.
+  I64 i;
+  U8 *start=acd.word_lst,*r=start,
+        *end=acd.word_lst+acd.word_lst_size;
+  if (!st || !*st)
+    return acd.word_lst;
+  if (acd.word_lst_size) {
+    while (start+3<end) {
+      r=(start+end)>>1;
+      while (TRUE) {
+        while (*r!=ACD_WORD_CHAR && r>acd.word_lst)
+          r--;
+        if ((r[2]==ACD_WORD_CHAR||r[1]==ACD_WORD_CHAR)&&r-3>acd.word_lst)
+          r--;
+        else
+          break;
+      }
+      if (*r==ACD_WORD_CHAR) {
+        i=StrICmp(st,r+1);
+        if (i<0)
+          end=r-1;
+        else if (i>0)
+          start=r+StrLen(r)+3;
+        else
+          return r;
+      } else
+        break;
+    }
+    r=(start+end)>>1;
+    while (TRUE) {
+      while (*r!=ACD_WORD_CHAR && r>acd.word_lst)
+        r--;
+      if ((r[2]==ACD_WORD_CHAR||r[1]==ACD_WORD_CHAR)&&r-3>acd.word_lst)
+        r--;
+      else
+        break;
+    }
+    if (*r==ACD_WORD_CHAR && StrICmp(st,r+1)>0)
+      r+=StrLen(r)+3;
+  }
+  if (*r==ACD_WORD_CHAR)
+    return r;
+  else
+    return acd.word_lst;
+}
+
+U0 ACDFillin(I64 n)
+{
+  U8 *s;
+  I64 len;
+  if (0<=n<acd.num_fillins) {
+    s=acd.fillins[n]+1;
+    len=StrLen(s);
+    if (len>ac.partial_len)
+      In(s+ac.partial_len);
+  }
+}
+
+public U0 ACDDefsPut(CDoc *doc=NULL,U8 *st,I64 num=-1)
+{//Put to doc a dictionary definition(s) of a word.
+  U8 *st2,*st3;
+  I64 ch,i=0;
+  if (!st) return;
+  if (*st==ACD_WORD_CHAR)
+    st++;
+  DocPrint(doc,"$WW,1$$RED$%s:$FG$\n\n",st);
+  if (num<0) {
+    if (st3=ACDDefsGet(st)) {
+      st2=st3;
+      while (ch=*st2++) {
+        switch (ch) {
+          case ACD_WORD_CHAR:
+            break;
+          case ACD_DEF_CHAR:
+            DocPrint(doc,"$GREEN$(%d)$FG$ %s\n",
+                  ++i,st2);
+            break;
+          case ACD_PRONUNCIATION_CHAR:
+            DocPrint(doc,"$LTGREEN$%s$FG$\n",st2);
+            break;
+          case ACD_POS_CHAR:
+            DocPrint(doc,"$BLACK$%s$FG$\n",st2);
+            break;
+          case ACD_EXTRA_CHAR:
+            DocPrint(doc,"$LTBLUE$%s$FG$\n",st2);
+            break;
+        }
+        st2+=StrLen(st2)+1;
+      }
+      Free(st3);
+    }
+  } else {
+    while (st2=ACDDefGet(st,++i)) {
+      if (i==num)
+        DocPrint(doc,"$GREEN$(%d)$FG$ %s\n",
+              i,st2);
+      Free(st2);
+    }
+  }
+}
+
+U0 ACDPopUpDef(U8 *st,I64 num=-1,CTask *parent=NULL)
+{
+  U8 *buf;
+  buf=MStrPrint("ACDDefsPut(DocPut,\"%s\",%d);View;",st,num);
+  PopUp(buf,parent);
+  Free(buf);
+}
+
+U0 ACDDef(I64 n,CTask *parent=NULL)
+{
+  if (0<=n<acd.num_fillins)
+    ACDPopUpDef(acd.fillins[n],-1,parent);
+}
+
+#help_index "AutoComplete"
+U0 ACFillIn(I64 n)
+{
+  U8 *s;
+  if (0<=--n<ac.num_fillins) {
+    s=ac.fillin_matches[n]->str;
+    if (StrLen(s)>ac.partial_len)
+      In(s+ac.partial_len);
+  }
+}
+
+U0 ACMan(I64 n,CTask *parent_task=NULL)
+{
+  CHashAC *tmpw;
+  CHashSrcSym *tmph;
+  if (0<=--n<ac.num_fillins && (tmpw=ac.fillin_matches[n]) &&
+        (tmph=HashFind(tmpw->str,Fs->hash_table,HTG_SRC_SYM)) &&
+        tmph->src_link)
+    PopUpEd(tmph->src_link,parent_task);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AutoComplete/ACInit.HC.HTML b/public/Wb/Home/Src/Adam/AutoComplete/ACInit.HC.HTML new file mode 100755 index 0000000..e475f96 --- /dev/null +++ b/public/Wb/Home/Src/Adam/AutoComplete/ACInit.HC.HTML @@ -0,0 +1,200 @@ + + + + + + + + + + + +
+#help_index "AutoComplete/Dictionary"
+acd.has_words=FileFind(ACD_WORD_FILENAME);
+acd.has_defs =FileFind(ACD_DEF_FILENAME)||FileFind(ACD_DEF_FILENAME_Z);
+
+public U0 ACDWordsLoad()
+{//Put words from word list into hash table.
+  I64 size;
+  CHashGeneric *tmph;
+  U8 *in_ptr,*in_start,*st2;
+  U16 *d;
+  acd.num_words=0;
+  if (in_ptr=FileRead(ACD_WORD_FILENAME,&size)) {
+    in_start=in_ptr;
+    Free(acd.word_lst);
+    acd.word_lst=AMAlloc(size);
+    MemCpy(acd.word_lst,in_start,size);
+    acd.word_lst_size=size;
+
+    while (in_ptr<in_start+size) {
+      if (*in_ptr==ACD_WORD_CHAR)
+        in_ptr++;
+      if (*in_ptr) {
+        st2=MStrUtil(in_ptr,SUF_TO_UPPER);
+        tmph=ACAlloc(sizeof(CHashGeneric)+StrLen(st2)+1);
+        StrCpy(tmph+1,st2);
+        Free(st2);
+        in_ptr+=StrLen(in_ptr)+1;
+        tmph->str=tmph+1;
+        tmph->use_cnt=1;
+        tmph->type=HTT_DICT_WORD;
+        d=in_ptr;
+        tmph->user_data0=*d;
+        in_ptr+=2;
+        HashAdd(tmph,ac.hash_table);
+        acd.num_words++;
+      } else
+        in_ptr+=3;
+    }
+    Free(in_start);
+  }
+}
+
+#help_index "AutoComplete"
+CHashAC *ACHashAdd(U8 *w)
+{
+  CHashAC *tmpw=HashFind(w,ac.hash_table,HTT_WORD);
+  if (tmpw) {
+    tmpw->hits++;
+    return tmpw;
+  }
+  tmpw=ACAlloc(sizeof(CHashAC));
+  tmpw->str=AStrNew(w);
+  tmpw->type=HTT_WORD;
+  tmpw->use_cnt=1;
+  tmpw->hits=1;
+  HashAdd(tmpw,ac.hash_table);
+  ac.num_words++;
+  return tmpw;
+}
+
+U0 ACSingleFileAdd(U8 *buf)
+{
+  I64 ch;
+  U8 *ptr=buf,*ptr2,*ptr3;
+  while (TRUE) {
+    while (TRUE) {
+      if (ch=*ptr++) {
+        if (Bt(char_bmp_alpha_numeric,ch))
+          break;
+      } else
+        return;
+    }
+    ptr3=ptr;
+    ptr2=ptr;
+    ptr--;
+    while (TRUE) {
+      if (ch=*ptr2++) {
+        if (Bt(char_bmp_alpha_numeric,ch))
+          *ptr3++=ch;
+        else if (ch!=CH_CURSOR)
+          break;
+      } else {
+        ptr2--;
+        break;
+      }
+    }
+    *ptr3=0;
+    ACHashAdd(ptr);
+    ptr=ptr2;
+  }
+}
+
+U0 ACMainFileLstTraverse(U8 *files_find_mask)
+{
+  U8 *buf;
+  CDirEntry *tmpde,*tmpde1;
+  try {
+    tmpde=tmpde1=FilesFind(files_find_mask,
+          FUF_RECURSE|FUF_JUST_TXT|FUF_JUST_FILES|FUF_CLUS_ORDER);
+    while (tmpde) {
+      "%s\n",tmpde->full_name;
+      buf=FileRead(tmpde->full_name);
+      ACSingleFileAdd(buf);
+      Free(buf);
+      tmpde=tmpde->next;
+    }
+  } catch
+    Fs->catch_except=TRUE;
+  DirTreeDel(tmpde1);
+}
+
+U0 ACProgressTask(Bool *_start_flag)
+{
+  I64 start=blkdev.write_cnt;
+  progress1=0;
+  progress1_max=(Size(ACD_DEF_FILENAME_Z,"+x+s")+BLK_SIZE-1)>>BLK_SIZE_BITS;
+  StrCpy(progress1_desc,"Uncompressing Dictionary");
+  start=blkdev.write_cnt;
+  *_start_flag=TRUE;
+  while (progress1<progress1_max) {
+    progress1=blkdev.write_cnt-start;
+    Sleep(10);
+  }
+  *progress1_desc=progress1=progress1_max=0;
+}
+
+public U0 ACInit(U8 *mask=NULL)
+{//Read files and build AutoComplete statistics.
+  Bool start_flag;
+  CBlkDev *bd=Let2BlkDev;
+
+  LBtr(&sys_run_level,RLf_AUTO_COMPLETE);
+  AutoComplete;
+  while (LBts(&ac.flags,ACf_INIT_IN_PROGRESS))
+    Yield;
+  if (DrvIsWritable && FileFind(ACD_DEF_FILENAME_Z) &&
+        !FileFind(ACD_DEF_FILENAME)) {
+    if (bd->type!=BDT_RAM) {
+      start_flag=FALSE;
+      Spawn(&ACProgressTask,&start_flag);
+      while (!start_flag)
+        Yield;
+    }
+    Move(ACD_DEF_FILENAME_Z,ACD_DEF_FILENAME);
+  }
+
+  HashTableDel(ac.hash_table);
+  ac.hash_table=HashTableNew(2048,adam_task);
+
+  ac.num_words=0;
+  Free(ac.cur_word);
+  ac.cur_word=NULL;
+
+  if (mask)
+    ACMainFileLstTraverse(mask);
+
+  ACDWordsLoad;
+  LBtr(&ac.flags,ACf_INIT_IN_PROGRESS);
+  LBts(&sys_run_level,RLf_AUTO_COMPLETE);
+  AutoComplete(ON);
+}
+
+I64 AutoCompleteSize()
+{
+  if (ac.hash_table)
+    return HashTableSize2(ac.hash_table)+MSize2(acd.word_lst);
+  else
+    return 0;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AutoComplete/ACTask.HC.HTML b/public/Wb/Home/Src/Adam/AutoComplete/ACTask.HC.HTML new file mode 100755 index 0000000..ebe2031 --- /dev/null +++ b/public/Wb/Home/Src/Adam/AutoComplete/ACTask.HC.HTML @@ -0,0 +1,314 @@ + + + + + + + + + + + +
+#help_index "AutoComplete/Dictionary"
+U0 ACDDictWordsAdd(U8 *st)
+{
+  I64 i;
+  U8 *ptr;
+  if (st && *st && (ptr=ACDWordPtAt(st))) {
+    for (i=0;i<ACD_FILLINS_NUM;i++) {
+      if (*ptr++!=ACD_WORD_CHAR)
+        break;
+      if (i) '\n';
+      acd.fillins[i]=ptr-1;
+      "$GREEN$'%d'$FG$ %-23ts",i,ptr;
+      ptr+=StrLen(ptr)+3;
+    }
+    acd.num_fillins=i;
+  }
+}
+
+#help_index "AutoComplete"
+U0 ACDocRst(I64 left,I64 top)
+{
+  CDoc *doc=DocPut;
+  DocRst(doc,TRUE);
+  doc->flags|=DOCF_SIZE_MIN;
+  Fs->border_src=BDS_CONST;
+  Fs->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  Fs->text_attr  =LTGRAY<<4+BLUE;
+  LBtr(&Fs->display_flags,DISPLAYf_SHOW);
+  WinHorz(left,Fs->win_right);
+  WinVert(top,Fs->win_bottom);
+  DocCursor;
+}
+
+I64 ACSkipCrap(U8 *src,I64 len)
+{
+  I64 j;
+  j=len-1;
+  while (j>=0) {
+    if (Bt(char_bmp_alpha_numeric,src[j]))
+      break;
+    else
+      j--;
+  }
+  return j+1;
+}
+
+I64 ACPriorWordInStr(U8 *src,U8 *dst,I64 len,I64 buf_size)
+{
+  I64 i,j=0,k;
+  i=len-1;
+  while (i>=0)
+    if (!Bt(char_bmp_alpha_numeric,src[i]))
+      break;
+    else
+      i--;
+  if (i>=-1 && len>0)
+    for (k=i+1;k<len && j<buf_size-1;k++)
+      dst[j++]=src[k];
+  dst[j]=0;
+  return i+1;
+}
+
+U0 ACFillInAdd(CHashAC *tmpw)
+{
+  I64 k;
+  if (ac.num_fillins<AC_FILLINS_NUM ||
+        tmpw->hits>ac.fillin_hits[ac.num_fillins-1]) {
+    for (k=ac.num_fillins-1;k>=0;k--) {
+      if (tmpw->hits<=ac.fillin_hits[k])
+        break;
+      else {
+        ac.fillin_matches[k+1]=ac.fillin_matches[k];
+        ac.fillin_hits[k+1]   =ac.fillin_hits[k];
+      }
+    }
+    ac.fillin_matches[k+1]=tmpw;
+    ac.fillin_hits[k+1]   =tmpw->hits;
+    if (ac.num_fillins<AC_FILLINS_NUM)
+      ac.num_fillins++;
+  }
+}
+
+U0 ACPutChoices(CDoc *focus_l,CDocEntry *doc_e,CTask *focus_task,
+        Bool force_refresh)
+{
+  I64 i,data_col;
+  U8 *buf,*buf1,*src=NULL,*st;
+  CHashAC *tmpw;
+  F64 timeout_time=tS+0.5;
+  CHashSrcSym *tmph;
+
+  src=DocScanLine(focus_l,doc_e,&data_col);
+  DocUnlock(focus_l);
+  i=StrLen(src);
+  buf =MAlloc(MaxI64(i+1,256));
+  buf1=MAlloc(MaxI64(i+1,256));
+  if (data_col==-1)
+    data_col=0;
+  data_col=ACPriorWordInStr(src,buf,data_col,256);
+  ac.partial_len=StrLen(buf);
+  data_col=ACSkipCrap(src,data_col);
+  data_col=ACPriorWordInStr(src,buf1,data_col,256);
+
+  if (!ac.cur_word || StrCmp(ac.cur_word,buf) || force_refresh) {
+    st=ac.cur_word;
+    ac.cur_word=AStrNew(buf);
+    Free(st);
+    ac.num_fillins=0;
+    if (*ac.cur_word)
+      for (i=0;i<=ac.hash_table->mask && tS<timeout_time;i++) {
+        tmpw=ac.hash_table->body[i];
+        while (tmpw) {
+          if (!MemCmp(ac.cur_word,tmpw->str,StrLen(ac.cur_word)))
+            ACFillInAdd(tmpw);
+          tmpw=tmpw->next;
+        }
+      }
+    ACDocRst(51,13);
+    if (ac.cur_word && *ac.cur_word) {
+      "$PURPLE$Word:%s$FG$\n",ac.cur_word;
+      for (i=0;i<ac.num_fillins;i++) {
+        st=ac.fillin_matches[i]->str;
+        "$GREEN$F%02d$FG$ ",i+1;
+        if (TaskValidate(focus_task) &&
+              (tmph=HashFind(st,focus_task->hash_table,HTG_SRC_SYM)) &&
+              tmph->src_link) {
+          if (tmph->type&HTF_PUBLIC)
+            "$RED$";
+          "$TX+UL+L+PU,\"%$Q\",A=\"%s\"$$FG$\n",st,tmph->src_link;
+        } else
+          "%s\n",st;
+      }
+      if (acd.has_words)
+        ACDDictWordsAdd(ac.cur_word);
+    } else if (FileFind("::/Doc/StandBy.DD.Z"))
+      Type("::/Doc/StandBy.DD.Z",0);
+  }
+  Free(src);
+  Free(buf);
+  Free(buf1);
+}
+
+U0 ACTaskNormal(I64 sc,I64 last_sc,
+        CTask *focus_task,CTask *original_focus_task)
+{
+  CDoc *doc;
+  CDocEntry *doc_e;
+  if ((doc=DocPut(focus_task)) &&
+        focus_task!=Fs && Bt(&focus_task->display_flags,DISPLAYf_SHOW)) {
+    DocLock(doc);
+    if (TaskValidate(focus_task) && original_focus_task==sys_focus_task &&
+          doc && doc==DocPut(focus_task) && (doc_e=doc->cur_entry)) {
+      if (doc_e==doc) doc_e=doc_e->last;
+      while (doc_e->last!=doc && (doc_e->type_u8==DOCT_NEW_LINE ||
+            doc_e->type_u8==DOCT_SOFT_NEW_LINE))
+        doc_e=doc_e->last;
+      while (doc_e->last->type_u8!=DOCT_NEW_LINE && doc_e->last!=doc)
+        doc_e=doc_e->last;
+      ACPutChoices(doc,doc_e,focus_task,ToBool(sc!=last_sc));
+    } else
+      DocUnlock(doc);
+  }
+  if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+    WinZBufUpdate;
+}
+
+U0 ACTaskCtrl(I64 sc,I64 last_sc,
+        CTask *focus_task,CTask *original_focus_task)
+{
+  if (TaskValidate(focus_task) &&
+        (focus_task->scroll_x || focus_task->scroll_y)) {
+    if (LBtr(&Fs->display_flags,DISPLAYf_SHOW))
+      WinZBufUpdate;
+  } else {
+    if (sc!=last_sc) {
+      if (sc&SCF_ALT) {
+        ACDocRst(27,3);
+        if (TaskValidate(original_focus_task) &&
+              !Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC))
+          KeyMapFamily(original_focus_task,0,
+                ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+        KeyMapCtrlAltFamily(
+              ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+      } else if (TaskValidate(original_focus_task) &&
+            !Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC)) {
+        ACDocRst(27,3);
+        KeyMapFamily(original_focus_task,SCF_CTRL,
+              ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+      }
+    }
+    if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+      WinZBufUpdate;
+  }
+}
+
+U0 ACTaskAlt(I64 sc,I64 last_sc,
+        CTask *,CTask *original_focus_task)
+{
+  if (sc!=last_sc && TaskValidate(original_focus_task) &&
+        !Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC)) {
+    ACDocRst(27,3);
+    KeyMapFamily(original_focus_task,SCF_ALT,
+          ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
+  }
+  if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+    WinZBufUpdate;
+}
+
+U0 ACTaskEndCB()
+{
+  ac.task=NULL;
+  Exit;
+}
+
+U0 ACTask(I64)
+{
+  CTask *focus_task,*original_focus_task;
+  I64 ch,scan_code=0,last_scan_code=0;
+  CDoc *doc;
+  Fs->task_end_cb=&ACTaskEndCB;
+  DocTermNew;
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinHorz(51,Fs->win_right);
+  LBts(&Fs->display_flags,DISPLAYf_WIN_ON_TOP);
+  Fs->win_inhibit=WIG_NO_FOCUS_TASK_DFT;
+  Free(ac.cur_word);
+  ac.cur_word=NULL;
+  while (TRUE) {
+    if (scan_code&(SCF_CTRL|SCF_ALT) ||
+          GetTSC>KbdMsEvtTime+cnts.time_stamp_freq>>1) {
+      last_scan_code=scan_code;
+      scan_code=kbd.scan_code;
+    }
+    original_focus_task=focus_task=sys_focus_task;
+    while (TaskValidate(focus_task) &&
+          Bt(&focus_task->task_flags,TASKf_INPUT_FILTER_TASK))
+      focus_task=focus_task->parent_task;
+    if (scan_code&SCF_CTRL)
+      ACTaskCtrl(scan_code,last_scan_code,focus_task,original_focus_task);
+     else if (TaskValidate(focus_task)) {
+      if (scan_code&SCF_ALT)
+        ACTaskAlt(scan_code,last_scan_code,focus_task,original_focus_task);
+      else
+        ACTaskNormal(scan_code,last_scan_code,focus_task,original_focus_task);
+    }
+    Sleep(333);
+    if (ScanMsg(&ch,,1<<MSG_KEY_DOWN) && (ch==CH_ESC||ch==CH_SHIFT_ESC))
+      break;
+    doc=DocPut;
+    DocLock(doc);
+    if (doc->cur_entry->de_flags & DOCEF_LINK) {
+      '' CH_SPACE;
+      doc->cur_entry=doc;
+    }
+    DocUnlock(doc);
+  }
+}
+
+public Bool AutoComplete(Bool val=OFF)
+{//Turn AutoComplete OFF or ON.
+  Bool  old_val=FALSE;
+  while (Bt(&ac.flags,ACf_INIT_IN_PROGRESS))
+    Sleep(10);
+  if (val) {
+    if (Bt(&sys_run_level,RLf_AUTO_COMPLETE)) {
+      if (TaskValidate(ac.task))
+        old_val=TRUE;
+      else {
+        ac.task=Spawn(&ACTask,NULL,"AutoComplete");
+        TaskWait(ac.task);
+      }
+      WinToTop(ac.task);
+    }
+  } else {
+    if (TaskValidate(ac.task)) {
+      if (Bt(&sys_run_level,RLf_AUTO_COMPLETE))
+        old_val=TRUE;
+      Kill(ac.task);
+      DeathWait(&ac.task);
+    }
+  }
+  return old_val;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/AutoComplete/MakeAC.HC.HTML b/public/Wb/Home/Src/Adam/AutoComplete/MakeAC.HC.HTML new file mode 100755 index 0000000..6f6c714 --- /dev/null +++ b/public/Wb/Home/Src/Adam/AutoComplete/MakeAC.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+//See ::/Doc/AutoComplete.DD
+Cd(__DIR__);;
+#include "ACFill"
+#include "ACTask"
+#include "ACInit"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/CPURep.HC.HTML b/public/Wb/Home/Src/Adam/CPURep.HC.HTML new file mode 100755 index 0000000..1e54e86 --- /dev/null +++ b/public/Wb/Home/Src/Adam/CPURep.HC.HTML @@ -0,0 +1,103 @@ + + + + + + + + + + + +
+#help_index "Info;Time/CPU Cycles;Processor"
+class CCPURep
+{
+  Bool mp_start,mp_end;
+  I64 mp_not_done_flags,
+      **swaps,
+      **cycles;
+};
+
+U0 MPCPURep(CCPURep *cr)
+{
+  I64 swaps=0,cycles_0,cycles_f;
+  while (!cr->mp_start)
+    Yield;
+  cycles_0=GetTSC;
+  while (!cr->mp_end) {
+    swaps++;
+    Yield;
+  }
+  cycles_f=GetTSC;
+  cr->swaps[Gs->num]=swaps;
+  cr->cycles[Gs->num]=cycles_f-cycles_0;
+  LBtr(&cr->mp_not_done_flags,Gs->num);
+}
+
+public U0 CPURep(Bool full=FALSE)
+{//Report number of cores and clock freq.
+  I64 i,total_swaps,total_cycles;
+  F64 t0,tf;
+  CCPURep cr;
+
+  if (!full)
+    "%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
+  else {
+    cr.swaps=CAlloc(sizeof(I64)*mp_cnt);
+    cr.cycles=CAlloc(sizeof(I64)*mp_cnt);
+    cr.mp_start=cr.mp_end=FALSE;
+    cr.mp_not_done_flags=1<<mp_cnt-1;
+    for (i=0;i<mp_cnt;i++)
+      Spawn(&MPCPURep,&cr,NULL,i);
+
+    t0=tS;
+    cr.mp_start=TRUE;
+    Sleep(2000);
+    cr.mp_end=TRUE;
+    while (cr.mp_not_done_flags)
+      Yield;
+    tf=tS;
+
+    "\n%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
+    "\n         Context\n"
+          "CPU     Swaps/s         Cycles\n"
+          "--- ------------- -----------------\n";
+    total_swaps=0;
+    total_cycles=0;
+    for (i=0;i<mp_cnt;i++) {
+      " %02X %13,d %17,d\n",i,
+            ToI64(cr.swaps[i]/(tf-t0)),ToI64(cr.cycles[i]/(tf-t0));
+      total_swaps+=cr.swaps[i];
+      total_cycles+=cr.cycles[i];
+    }
+    "--- ------------- -----------------\n";
+    "%03X %13,d %17,d\n",i,
+          ToI64(total_swaps/(tf-t0)),ToI64(total_cycles/(tf-t0));
+    "Avg %13,d %17,d\n\n",
+          ToI64(total_swaps/(tf-t0)/i),ToI64(total_cycles/(tf-t0)/i);
+    "Avg Cycles/Swap: %12.6f\n",ToF64(total_cycles)/total_swaps;
+    "Avg Time/Swap  : %12.6fns\n\n",(tf-t0)*1000000000.0*i/total_swaps;
+    Free(cr.swaps);
+    Free(cr.cycles);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Ctrls/CtrlsA.HC.HTML b/public/Wb/Home/Src/Adam/Ctrls/CtrlsA.HC.HTML new file mode 100755 index 0000000..df8516c --- /dev/null +++ b/public/Wb/Home/Src/Adam/Ctrls/CtrlsA.HC.HTML @@ -0,0 +1,419 @@ + + + + + + + + + + + +
+public CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type)
+{//Find task ctrl given ctrl_type.
+  CCtrl *c;
+  c=haystack_task->next_ctrl;
+  while (c!=&haystack_task->next_ctrl) {
+    if (c->type==needle_type)
+      return c;
+    c=c->next;
+  }
+  return NULL;
+}
+
+U0 CtrlsUpdate(CTask *task)
+{
+  CCtrl *c;
+  c=task->next_ctrl;
+  while (c!=&task->next_ctrl) {
+    if (c->update_derived_vals)
+      (*c->update_derived_vals)(c);
+    if (c->flags&CTRLF_BORDER) {
+      c->scrn_left  =gr.pan_text_x+task->pix_left+c->left-FONT_WIDTH;
+      c->scrn_right =gr.pan_text_x+task->pix_left+c->right-FONT_WIDTH;
+      c->scrn_top   =gr.pan_text_y+task->pix_top+c->top-FONT_HEIGHT;
+      c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom-FONT_HEIGHT;
+    } else {
+      c->scrn_left  =gr.pan_text_x+task->pix_left+c->left;
+      c->scrn_right =gr.pan_text_x+task->pix_left+c->right;
+      c->scrn_top   =gr.pan_text_y+task->pix_top+c->top;
+      c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom;
+    }
+    c=c->next;
+  }
+}
+
+fp_update_ctrls=&CtrlsUpdate;
+
+Bool CtrlInsideRect(CCtrl *c,I64 x,I64 y)
+{//scrn coordinates
+  if (c->scrn_left<=x<=c->scrn_right &&
+        c->scrn_top<=y<=c->scrn_bottom)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+public Bool CtrlInside(CCtrl *c,I64 x,I64 y)
+{//Is x,y inside a ctrl?
+  if (c->flags&CTRLF_SHOW) {
+    if (c->inside_ctrl)
+      return (*c->inside_ctrl)(c,x,y);
+    else
+      return CtrlInsideRect(c,x,y);
+  } else
+    return FALSE;
+}
+
+U0 DrawCtrls(CTask *task)
+{
+  CCtrl *c;
+  CDC *dc=DCAlias(gr.dc2,task);
+  c=task->next_ctrl;
+  while (c!=&task->next_ctrl) {
+    if (c->flags&CTRLF_SHOW) {
+      if (c->flags&CTRLF_BORDER) {
+        if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
+          PUSHFD
+          CLI
+          while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+            PAUSE
+
+          task->win_left--; //Allow drawing on border
+          task->win_right++;
+          task->win_top--;
+          task->win_bottom++;
+          WinDerivedValsUpdate(task);
+
+          LBtr(&task->task_flags,TASKf_TASK_LOCK);
+          POPFD
+
+          if (c->draw_it)
+            (*c->draw_it)(dc,c);
+
+          PUSHFD
+          CLI
+          while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+            PAUSE
+
+          task->win_left++;
+          task->win_right--;
+          task->win_top++;
+          task->win_bottom--;
+          WinDerivedValsUpdate(task);
+
+          LBtr(&task->task_flags,TASKf_TASK_LOCK);
+          POPFD
+        }
+      } else
+        if (c->draw_it)
+          (*c->draw_it)(dc,c);
+    }
+    c=c->next;
+  }
+  DCDel(dc);
+}
+
+#define WIN_SCROLL_SIZE         8
+#define WIN_SCROLL_BORDER_BONUS 4
+U0 DrawWinScroll(CDC *dc,CCtrl *c)
+{
+  CWinScroll *s=c->state;
+
+  if (c->flags&CTRLF_CLICKED)
+    dc->color=s->color>>4;
+  else
+    dc->color=s->color&0xF;
+  GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
+
+  if (c->flags&CTRLF_CLICKED)
+    dc->color=s->color&0xF;
+  else
+    dc->color=s->color>>4;
+  GrRect(dc,c->left+2,c->top+2,c->right-c->left+1-4,c->bottom-c->top+1-4);
+}
+
+U0 WinDerivedScrollValsUpdate(CCtrl *c)
+{
+  CWinScroll *s=c->state;
+  I64 range;
+  if (s->max<s->min) s->max=s->min;
+  if (s->pos<s->min) s->pos=s->min;
+  if (s->pos>s->max) s->pos=s->max;
+  s->color=c->win_task->border_attr&0xF^0xF+
+        (c->win_task->border_attr&0xF)<<4;
+  range=s->max-s->min;
+  if (!range) range=1;
+  switch (c->type) {
+    case CTRLT_WIN_HSCROLL:
+      c->left  =gr.pan_text_x+FONT_WIDTH-WIN_SCROLL_BORDER_BONUS+
+            (s->pos-s->min)*(c->win_task->pix_width+2*WIN_SCROLL_BORDER_BONUS
+            -WIN_SCROLL_SIZE)/range;
+      c->right =c->left+WIN_SCROLL_SIZE-1;
+      c->top   =gr.pan_text_y+FONT_HEIGHT+
+            (FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_height;
+      c->bottom=c->top+WIN_SCROLL_SIZE-1;
+      break;
+    case CTRLT_WIN_VSCROLL:
+      c->left  =gr.pan_text_x+FONT_WIDTH+
+            (FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_width;
+      c->right =c->left+WIN_SCROLL_SIZE-1;
+      c->top   =gr.pan_text_y+FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS+
+            (s->pos-s->min)*(c->win_task->pix_height+
+            2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE)/range;
+      c->bottom=c->top+WIN_SCROLL_SIZE-1;
+      break;
+  }
+}
+
+U0 LeftClickHWinScroll(CCtrl *c,I64 x,I64,Bool down)
+{
+  CTask *task=c->win_task;
+  CWinScroll *s=c->state;
+  I64 range=task->pix_width+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
+  LBts(&s->flags,WSSf_SET_TO_POS);
+  s->pos=((x-(FONT_WIDTH-WIN_SCROLL_BORDER_BONUS))
+  *(s->max-s->min+1)+range/2)/range+s->min;
+  if (down)
+    c->flags|=CTRLF_CLICKED;
+  else
+    c->flags&=~CTRLF_CLICKED;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+U0 LeftClickVWinScroll(CCtrl *c,I64,I64 y,Bool down)
+{
+  CTask *task=c->win_task;
+  CWinScroll *s=c->state;
+  I64 range=task->pix_height+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
+  LBts(&s->flags,WSSf_SET_TO_POS);
+  s->pos=((y-(FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS))
+  *(s->max-s->min+1)+range/2)/range+s->min;
+  if (down)
+    c->flags|=CTRLF_CLICKED;
+  else
+    c->flags&=~CTRLF_CLICKED;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+U0 WheelChangeWinScroll(CCtrl *c,I64 delta)
+{
+  CWinScroll *s=c->state;
+  LBts(&s->flags,WSSf_SET_TO_POS);
+  s->pos+=delta;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+U0 WinScrollsInit(CTask *task)
+{
+  CCtrl *c;
+
+  if (!CtrlFindUnique(task,CTRLT_WIN_HSCROLL)) {
+    c=CAlloc(sizeof(CCtrl));
+    c->win_task=task;
+    c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
+    c->type=CTRLT_WIN_HSCROLL;
+    c->state=&task->horz_scroll;
+    c->update_derived_vals=&WinDerivedScrollValsUpdate;
+    c->draw_it=&DrawWinScroll;
+    c->left_click=&LeftClickHWinScroll;
+    QueIns(c,task->last_ctrl);
+  }
+
+  if (!CtrlFindUnique(task,CTRLT_WIN_VSCROLL)) {
+    c=CAlloc(sizeof(CCtrl));
+    c->win_task=task;
+    c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
+    c->type=CTRLT_WIN_VSCROLL;
+    c->state=&task->vert_scroll;
+    c->update_derived_vals=&WinDerivedScrollValsUpdate;
+    c->draw_it=&DrawWinScroll;
+    c->left_click=&LeftClickVWinScroll;
+    c->wheel_chg=&WheelChangeWinScroll;
+    QueIns(c,task->last_ctrl);
+  }
+  TaskDerivedValsUpdate(task);
+}
+#define VIEWANGLES_SPACING      22
+#define VIEWANGLES_RANGE        48
+#define VIEWANGLES_BORDER       2
+#define VIEWANGLES_SNAP         2
+
+U0 DrawViewAnglesCtrl(CDC *dc,CCtrl *c)
+{
+  I64 i,j;
+  CViewAngles *s=c->state;
+
+  dc->color=s->cbd;
+  GrRect(dc, c->left,c->top,VIEWANGLES_SPACING*4+3,
+        VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
+  dc->color=s->cbg;
+  GrRect(dc, c->left+VIEWANGLES_BORDER,c->top+VIEWANGLES_BORDER,
+        VIEWANGLES_SPACING*4+3-2*VIEWANGLES_BORDER,
+        VIEWANGLES_SPACING*2+VIEWANGLES_RANGE-2*VIEWANGLES_BORDER);
+  dc->color=s->cfg;
+  GrLine(dc,c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING,
+        c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING+
+        VIEWANGLES_RANGE-1);
+  GrLine(dc,c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING,
+        c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING+
+        VIEWANGLES_RANGE-1);
+  GrLine(dc,c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING,
+        c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING+
+        VIEWANGLES_RANGE-1);
+  for (i=1;i<VIEWANGLES_RANGE+1;i+=2*VIEWANGLES_SNAP) {
+    j=2-i/3&1;
+    GrLine(dc,c->left+VIEWANGLES_SPACING-j,c->bottom-VIEWANGLES_SPACING-i,
+          c->left+VIEWANGLES_SPACING+j,c->bottom
+          -VIEWANGLES_SPACING-i);
+    GrLine(dc,c->left+2*VIEWANGLES_SPACING+1-j,c->bottom-VIEWANGLES_SPACING-i,
+          c->left+2*VIEWANGLES_SPACING+1+j,c->bottom
+          -VIEWANGLES_SPACING-i);
+    GrLine(dc,c->left+3*VIEWANGLES_SPACING+2-j,c->bottom-VIEWANGLES_SPACING-i,
+          c->left+3*VIEWANGLES_SPACING+2+j,c->bottom
+          -VIEWANGLES_SPACING-i);
+  }
+
+  dc->color=s->cx;
+  GrPrint(dc,c->left+VIEWANGLES_SPACING-FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"X");
+  GrPrint(dc,c->left+VIEWANGLES_SPACING-3*FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
+        "%3d",s->sx*360/VIEWANGLES_RANGE);
+  i=c->left+VIEWANGLES_SPACING;
+  if (s->sx>VIEWANGLES_RANGE/2)
+    j=-VIEWANGLES_RANGE/2+s->sx;
+  else
+    j=s->sx+VIEWANGLES_RANGE/2;
+  j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
+  GrRect(dc,i-3,j-2,7,5);
+  dc->color=s->cx^8;
+  GrRect(dc,i-2,j-1,5,3);
+
+  dc->color=s->cy;
+  GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Y");
+  GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-3*FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
+        "%3d",s->sy*360/VIEWANGLES_RANGE);
+  i=c->left+2*VIEWANGLES_SPACING+1;
+  if (s->sy>VIEWANGLES_RANGE/2)
+    j=-VIEWANGLES_RANGE/2+s->sy;
+  else
+    j=s->sy+VIEWANGLES_RANGE/2;
+  j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
+  GrRect(dc,i-3,j-2,7,5);
+  dc->color=s->cy^8;
+  GrRect(dc,i-2,j-1,5,3);
+
+  dc->color=s->cz;
+  GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Z");
+  GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-3*FONT_WIDTH/2,
+        c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
+        "%3d",s->sz*360/VIEWANGLES_RANGE);
+  i=c->left+3*VIEWANGLES_SPACING+2;
+  if (s->sz>VIEWANGLES_RANGE/2)
+    j=-VIEWANGLES_RANGE/2+s->sz;
+  else
+    j=s->sz+VIEWANGLES_RANGE/2;
+  j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
+  GrRect(dc,i-3,j-2,7,5);
+  dc->color=s->cz^8;
+  GrRect(dc,i-2,j-1,5,3);
+}
+
+U0 UpdateDerivedViewAnglesCtrl(CCtrl *c)
+{
+  CViewAngles *s=c->state;
+  c->left=c->win_task->pix_width-(VIEWANGLES_SPACING*4+3);
+  c->right=c->left+VIEWANGLES_SPACING*4+3;
+  c->top=c->win_task->pix_height-(VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
+  c->bottom=c->top+VIEWANGLES_SPACING*2+VIEWANGLES_RANGE;
+  s->sx=ClampI64(RoundI64(s->sx,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
+  s->sy=ClampI64(RoundI64(s->sy,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
+  s->sz=ClampI64(RoundI64(s->sz,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
+  s->ax=2*pi*s->sx/VIEWANGLES_RANGE;
+  s->ay=2*pi*s->sy/VIEWANGLES_RANGE;
+  s->az=2*pi*s->sz/VIEWANGLES_RANGE;
+}
+
+U0 LeftClickViewAngles(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CViewAngles *s=c->state;
+  I64 i;
+  i=VIEWANGLES_RANGE-1-(y-(c->top+VIEWANGLES_SPACING));
+  if (i>=VIEWANGLES_RANGE/2)
+    i-=VIEWANGLES_RANGE/2;
+  else
+    i+=VIEWANGLES_RANGE/2;
+  if (x<c->left+(c->right-c->left)/3)
+    s->sx=i;
+  else if (x<c->left+2*(c->right-c->left)/3)
+    s->sy=i;
+  else
+    s->sz=i;
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+public CCtrl *ViewAnglesNew(CTask *task=NULL)
+{//Create view angle ctrl. See ::/Demo/Graphics/Shading.HC.
+  CCtrl *c;
+  CViewAngles *s;
+  if (!task) task=Fs;
+  if (!(c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES))) {
+    s=CAlloc(sizeof(CViewAngles),task);
+    c=CAlloc(sizeof(CCtrl));
+    s->cbd=BLUE;
+    s->cbg=LTBLUE;
+    s->cfg=BLACK;
+    s->cx=LTGREEN;
+    s->cy=GREEN;
+    s->cz=LTGREEN;
+    c->win_task=task;
+    c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+    c->type=CTRLT_VIEWING_ANGLES;
+    c->state=s;
+    c->draw_it=&DrawViewAnglesCtrl;
+    c->left_click=&LeftClickViewAngles;
+    c->update_derived_vals=&UpdateDerivedViewAnglesCtrl;
+    QueIns(c,task->last_ctrl);
+    TaskDerivedValsUpdate(task);
+  }
+  return c;
+}
+
+public U0 ViewAnglesDel(CTask *task=NULL)
+{//Free view angle ctrl.
+  CCtrl *c;
+  if (!task) task=Fs;
+  if (c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES)) {
+    QueRem(c);
+    Free(c->state);
+    Free(c);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Ctrls/CtrlsBttn.HC.HTML b/public/Wb/Home/Src/Adam/Ctrls/CtrlsBttn.HC.HTML new file mode 100755 index 0000000..dff6898 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Ctrls/CtrlsBttn.HC.HTML @@ -0,0 +1,122 @@ + + + + + + + + + + + +
+#define BTTN_BORDER     2
+
+#define BTF_DONT_FREE   1
+
+class CCtrlBttnState
+{
+  I64 state,num_states,flags;
+  U8 *state_texts;
+  CColorROPU32 *state_colors;
+};
+
+U0 DrawCtrlBttn(CDC *dc,CCtrl *c)
+{
+  CCtrlBttnState *s=c->state;
+  I64 l;
+  U8 *st;
+
+  dc->color=BLACK;
+  GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
+  if (!(st=LstSub(s->state,s->state_texts)))
+    st=s->state_texts;
+  dc->color=s->state_colors[s->state];
+  l=StrLen(st);
+  GrRect(dc,c->left+BTTN_BORDER,c->top+BTTN_BORDER,
+        c->right-c->left+1-BTTN_BORDER*2,
+        c->bottom-c->top+1-BTTN_BORDER*2);
+  dc->color=s->state_colors[s->state]^(WHITE<<16+WHITE);
+  GrPrint(dc,(c->left+c->right+1-l*FONT_WIDTH)>>1,
+        (c->top+c->bottom+1-FONT_HEIGHT)>>1,"%s",st);
+}
+
+U0 LeftClickCtrlBttn(CCtrl *c,I64,I64,Bool down)
+{
+  CCtrlBttnState *s=c->state;
+  if (down) {
+    s->state++;
+    if (s->state==s->num_states)
+      s->state=0;
+  }
+}
+
+public CCtrl *CtrlBttnNew(I64 x,I64 y,I64 width=-1,I64 height=-1,
+        I64 num_states=1,U8 *state_texts,
+        I32 *state_colors,CCtrlBttnState *_s=NULL)
+{//Create bttn ctrl. See ::/Apps/Strut/Strut.HC.
+  CCtrl *res;
+  CCtrlBttnState *s;
+  I64 i,j,l;
+  U8 *st;
+  if (width<0) {
+    l=1;
+    for (i=0;i<num_states;i++)
+      if (st=LstSub(i,state_texts)) {
+        j=StrLen(st);
+        if (j>l) l=j;
+      }
+    width=BTTN_BORDER*4+l*FONT_WIDTH;
+  }
+  if (height<0) height=BTTN_BORDER*4+FONT_HEIGHT;
+  res=CAlloc(sizeof(CCtrl));
+  if (_s) {
+    s=_s;
+    MemSet(s,0,sizeof(CCtrlBttnState));
+  } else {
+    s=CAlloc(sizeof(CCtrlBttnState));
+    s->flags=BTF_DONT_FREE;
+  }
+  s->num_states=num_states;
+  s->state_texts=state_texts;
+  s->state_colors=state_colors;
+  res->win_task=Fs;
+  res->flags=CTRLF_SHOW;
+  res->type=CTRLT_GENERIC;
+  res->state=s;
+  res->draw_it=&DrawCtrlBttn;
+  res->left_click=&LeftClickCtrlBttn;
+  res->left=x;
+  res->top=y;
+  res->right=res->left+width-1;
+  res->bottom=res->top+height-1;
+  QueIns(res,Fs->last_ctrl);
+  return res;
+}
+
+public U0 CtrlBttnDel(CCtrl *c)
+{//Free bttn ctrl.
+  QueRem(c);
+  if (!(c->flags&BTF_DONT_FREE))
+    Free(c->state);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Ctrls/CtrlsSlider.HC.HTML b/public/Wb/Home/Src/Adam/Ctrls/CtrlsSlider.HC.HTML new file mode 100755 index 0000000..22cad56 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Ctrls/CtrlsSlider.HC.HTML @@ -0,0 +1,245 @@ + + + + + + + + + + + +
+class CTemplateCSSlider
+{
+  CTemplateCSSlider *next,*last;
+  U8 *name;
+  I64 num;
+};
+
+class CTemplateCS
+{
+  CTemplateCSSlider *next_slider,*last_slider;
+  I64 num_sliders,range,spacing,border;
+  U8 *glbl_name;
+};
+
+CTemplateCS *CtrlSliderGet()
+{
+  CTemplateCSSlider *tmps;
+  U8 *st,pmt[STR_LEN];
+  CTemplateCS *res=CAlloc(sizeof(CTemplateCS));
+
+  "$PURPLE$Ctrl Slider$FG$\n\n";
+
+  res->glbl_name=GetStr("Glbl Struct Name (ENTER for No Glbl):");
+  res->range=GetI64     ("Range   (%4d):",30);
+  res->spacing=GetI64("Spacing (%4d):",20);
+  res->border=GetI64 ("Border  (%4d):",2);
+
+  res->next_slider=res->last_slider=&res->next_slider;
+  while (TRUE) {
+    StrPrint(pmt,"Slider #%d Name:",res->num_sliders+1);
+    st=GetStr(pmt);
+    if (!*st) {
+      Free(st);
+      break;
+    }
+    tmps=CAlloc(sizeof(CTemplateCSSlider));
+    tmps->name=st;
+    QueIns(tmps,res->last_slider);
+    tmps->num=res->num_sliders++;
+  }
+  return res;
+}
+
+U0 TemplateCtrlSlider(CDoc *doc)
+{
+  CTask *task;
+  CTemplateCS *m=NULL;
+  CTemplateCSSlider *tmps;
+  I64 i;
+
+  DocUnlock(doc);
+  DocRecalc(doc);
+  DocCaptureUndo(doc,TRUE);
+
+  task=User("CTemplateCS **_m=0x%X;*_m=CtrlSliderGet;\n",&m);
+  while (!m)
+    Yield;
+
+  DocPrint(doc,
+"#define SLIDER_RANGE\t%d
+#define SLIDER_SPACING\t%d
+#define SLIDER_BORDER\t%d
+
+class CSliderState
+{
+",m->range,m->spacing,m->border);
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  I64 %s;\n",tmps->name);
+    tmps=tmps->next;
+  }
+  if (*m->glbl_name)
+    DocPrint(doc,"} %s;\n",m->glbl_name);
+  else
+    DocPrint(doc,"};\n");
+
+  DocPrint(doc,
+"
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,%d*SLIDER_SPACING+%d,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BLUE;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+    %d*SLIDER_SPACING+%d-2*SLIDER_BORDER,SLIDER_SPACING*2
+    +SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+",m->num_sliders+1,m->num_sliders,m->num_sliders+1,m->num_sliders);
+
+  for (i=0;i<m->num_sliders;i++)
+    DocPrint(doc,
+"  GrLine(dc,c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING,
+             c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+",i+1,i,i+1,i);
+
+  DocPrint(doc,"  dc->color=LTRED;\n");
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,
+"  GrPrint(dc,c->left+%d*SLIDER_SPACING+%d-FONT_WIDTH/2,
+    c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+    \"%%d\",s->%s*10/SLIDER_RANGE);\n",
+      tmps->num+1,tmps->num,tmps->name);
+    tmps=tmps->next;
+  }
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,
+        "  GrRect(dc,c->left+%d*SLIDER_SPACING+%d-3,"
+        "c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-2,7,5);\n",
+      tmps->num+1,tmps->num,tmps->name);
+    tmps=tmps->next;
+  }
+  DocPrint(doc,"  dc->color=YELLOW;\n");
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  GrRect(dc,c->left+%d*SLIDER_SPACING+%d-2,"
+        "c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-1,5,3);\n",
+      tmps->num+1,tmps->num,tmps->name);
+    tmps=tmps->next;
+  }
+  DocPrint(doc,
+"}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
+  c->right=c->left+%d*SLIDER_SPACING+%d;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+",m->num_sliders+1,m->num_sliders);
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  s->%s=ClampI64(s->%s,0,SLIDER_RANGE-1);\n",
+        tmps->name,tmps->name);
+    tmps=tmps->next;
+  }
+  DocPrint(doc,
+"}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool down)
+{
+  no_warn down;
+  CSliderState *s=c->state;
+");
+
+  tmps=m->next_slider;
+  while (tmps!=&m->next_slider) {
+    DocPrint(doc,"  ");
+    if (tmps!=m->next_slider)
+      DocPrint(doc,"else ");
+    if (tmps->next==&m->next_slider)
+      DocPrint(doc,"\n");
+    else
+      DocPrint(doc,"if (x<c->left+%d*SLIDER_SPACING+%d+SLIDER_SPACING/2)\n",
+        tmps->num+1,tmps->num);
+    DocPrint(doc,"    s->%s=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));\n",
+       tmps->name);
+    tmps=tmps->next;
+  }
+ 
+  DocPrint(doc,
+"  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+");
+  if (*m->glbl_name)
+    DocPrint(doc,"  c->state=&%s;\n"
+        "  MemSet(&%s,0,sizeof(CSliderState));\n",m->glbl_name,m->glbl_name);
+  else
+    DocPrint(doc,       "  c->state=CAlloc(sizeof(CSliderState));\n");
+  DocPrint(doc,
+"  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+");
+  if (!*m->glbl_name)
+    DocPrint(doc,"  Free(c->state);\n");
+  DocPrint(doc,
+"  Free(c);
+}
+");
+
+  Kill(task);  //This frees memory.
+
+  RegOneTimePopUp(ARf_MANAGE_SLIDER,
+    "Modify the code to your heart's content.\n"
+    "The code is no longer managed.\n");
+
+  DocLock(doc);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Ctrls/MakeCtrls.HC.HTML b/public/Wb/Home/Src/Adam/Ctrls/MakeCtrls.HC.HTML new file mode 100755 index 0000000..128aaf8 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Ctrls/MakeCtrls.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#help_index "Ctrls"
+#help_file "::/Doc/Ctrls"
+#include "CtrlsA"
+#include "CtrlsBttn"
+#include "CtrlsSlider"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/DevInfo.HC.HTML b/public/Wb/Home/Src/Adam/DevInfo.HC.HTML new file mode 100755 index 0000000..1b99a40 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DevInfo.HC.HTML @@ -0,0 +1,251 @@ + + + + + + + + + + + +
+#help_index "PCI;Processor;Devices;Info"
+
+//The file was downloaded from
+//http://www.pcidatabase.com/reports.php?type=tab-delimeted
+
+#define PCI_DEV_FILE "::/Misc/PCIDevices.DD.Z"
+
+/****
+//1) Download http://www.pcidatabase.com/reports.php?type=tab-delimeted
+//2) Rename to ::/Misc/PCIDevices.DD.Z
+//3) ToDolDoc("::/Misc/PCIDevices.DD.Z");
+//4) Edit and remove file header and tail
+//5) Text find-and-replace "=0A=" with "". (Doesn't seem necessary anmore.)
+//6) Run PCIDevFileGen(). (Doesn't seem necessary anmore.)
+
+public U0 PCIDevFileGen()
+{
+  Bool first=TRUE,del=FALSE,del2=FALSE,cont=FALSE;
+  CDoc *doc=DocRead(PCI_DEV_FILE,
+        DOCF_PLAIN_TEXT|DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next,*doc_e2;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (first) {
+      if (doc_e->type_u8==DOCT_TEXT) {
+        if (doc_e->tag[0]==';')
+          del=TRUE;
+      }
+      first=FALSE;
+    }
+    if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[StrLen(doc_e->tag)-1]=='=' &&
+          doc_e2->type_u8==DOCT_NEW_LINE) {
+      doc_e->tag[StrLen(doc_e->tag)-1]=CH_SPACE;
+      cont=TRUE;
+    }
+    del2=del;
+    if (doc_e->type_u8==DOCT_NEW_LINE) {
+      first=TRUE;
+      del2=FALSE;
+      if (cont) {
+        del=TRUE;
+        cont=FALSE;
+      }
+    }
+    if (del)
+      DocEntryDel(doc,doc_e);
+    del=del2;
+    doc_e=doc_e2;
+  }
+  DocWrite(doc);
+}
+****/
+
+//::/Misc/PCIDevices.DD
+U0 PCILookUpSingle(CDoc *doc,I64 m,I64 d,U8 **_vendor,U8 **_dev)
+{
+  Bool first=TRUE;
+  U8 buf[8],*vendor=NULL,*dev=NULL;
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (first) {
+      if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[0]!=';' &&
+            StrLen(doc_e->tag)>=4) {
+        buf[0](U16)='0x';
+        buf[2](U32)=doc_e->tag(U32 *)[0];
+        buf[6]=0;
+        if (Str2I64(buf)==m) {
+          doc_e=doc_e->next->next;
+          if (doc_e->type_u8==DOCT_TEXT) {
+            vendor=AStrNew(doc_e->tag);
+            first=FALSE;
+            break;
+          }
+        }
+      }
+      first=FALSE;
+    }
+    if (doc_e->type_u8==DOCT_NEW_LINE)
+      first=TRUE;
+    doc_e=doc_e->next;
+  }
+
+  if (vendor) {
+    while (doc_e!=doc) {
+      if (first) {
+        if (doc_e->type_u8==DOCT_TAB) {
+          doc_e=doc_e->next;
+          if (doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=4) {
+            buf[0](U16)='0x';
+            buf[2](U32)=doc_e->tag(U32 *)[0];
+            buf[6]=0;
+            if (Str2I64(buf)==d) {
+              doc_e=doc_e->next->next;
+              if (doc_e->type_u8==DOCT_TEXT) {
+                dev=AStrNew(doc_e->tag);
+                break;
+              }
+            }
+          }
+        } else
+          break;
+        first=FALSE;
+      }
+      if (doc_e->type_u8==DOCT_NEW_LINE)
+        first=TRUE;
+      doc_e=doc_e->next;
+    }
+  }
+
+  if (vendor)
+    *_vendor=vendor;
+  else
+    *_vendor=AStrNew("Unknown");
+
+  if (dev)
+    *_dev=dev;
+  else
+    *_dev=AStrNew("Unknown");
+}
+
+U0 PCILookUpDevs()
+{
+  CPCIDev *tmppci;
+  I64 w1,w2,b,d,f,timeout=32*8*2;
+  CDoc *doc;
+  if (dev.pci_head.next!=&dev.pci_head)
+    return;
+  doc=DocRead(PCI_DEV_FILE,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+  for (b=0;b<sys_pci_busses;b++)
+    for (d=0;d<32;d++)
+      for (f=0;f<8;f++) {
+        w1=PCIReadU16(b,d,f,0);
+        if (w1!=0xFFFF) {
+          tmppci=ACAlloc(sizeof(CPCIDev));
+          tmppci->bus=b;
+          tmppci->dev=d;
+          tmppci->fun=f;
+          tmppci->vendor=w1;
+          tmppci->dev_id=w2=PCIReadU16(b,d,f,2);
+          tmppci->sub_code=PCIReadU8(b,d,f,0xA);
+          tmppci->base_code=PCIReadU8(b,d,f,0xB);
+          PCILookUpSingle(doc,w1,w2,&tmppci->vendor_str,&tmppci->dev_id_str);
+          QueIns(tmppci,dev.pci_head.last);
+          timeout=32*8*2;
+        } else if (sys_pci_busses==256 && --timeout<=0)
+          goto lud_done;
+      }
+lud_done:
+  DocDel(doc);
+}
+
+public U0 PCIRep()
+{//Report description of PCI devices.
+  CPCIDev *tmppci;
+  "PCI Busses:%d\n",sys_pci_busses;
+  if (!FileFind(PCI_DEV_FILE)) {
+    "You don't have the PCI device file.\n";
+    return;
+  }
+  PCILookUpDevs;
+  tmppci=dev.pci_head.next;
+  while (tmppci!=&dev.pci_head) {
+    "%02X:%02X:%01X %02X%02X $GREEN$%s $CYAN$%s$FG$\n",
+          tmppci->bus,tmppci->dev,tmppci->fun,
+          tmppci->base_code,tmppci->sub_code,
+          tmppci->vendor_str,tmppci->dev_id_str;
+    tmppci=tmppci->next;
+  }
+}
+
+#help_index "Info;Memory/Info"
+public U0 MemBIOSRep()
+{//Report the memory ranges reported by the BIOS at boot.
+  U16           *m01=MEM_E801;
+  CMemE820      *m20=MEM_E820;
+  CMemRange     *tmpmr;
+  "Standard Addresses\n"
+        "000A0000-000BFFFF VGA\n"
+        "FEE00000-FEE00FFF See $LK,\"APIC\",A=\"MN:LAPIC_BASE\"$\n\n"
+        "32 Bit Device Mem\n";
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  tmpmr=dev.mem32_head.next;
+  while (tmpmr!=&dev.mem32_head) {
+    "%02X:%016X-%016X\n",
+          tmpmr->type,tmpmr->base,tmpmr->base+tmpmr->size-1;
+    tmpmr=tmpmr->next;
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+
+  "\nBIOS Memory Report 15:E801\n"
+        "01:0000000000000000-%016X\n",0x100000+m01[0]<<10-1;
+  "01:0000000001000000-%016X\n",SYS_16MEG_AREA_LIMIT+m01[1]<<16-1;
+
+  if (m20->type) {
+    '\n';
+    "BIOS Memory Report 15:E820\n";
+    while (m20->type) {
+      "%02X:%016X-%016X\n",m20->type,m20->base,m20->base+m20->len-1;
+      m20++;
+    }
+  }
+}
+
+public U0 MemPageRep()
+{//Page Table Report.
+  "MAPPED\t  :%010X with ",mem_mapped_space;
+  if (Bt(&mem_page_size,30))
+    "$RED$1GIG$FG$ pages\n";
+  else
+    "$RED$2MEG$FG$ pages\n";
+  "PML2\t  :%010X 2MEG  :%08X\n",
+        *MEM_PML2(U64 *),*MEM_2MEG_NUM(U64 *);
+  "PML3\t  :%010X 1GIG  :%08X\n",
+        *MEM_PML3(U64 *),*MEM_1GIG_NUM(U64 *);
+  "PML4\t  :%010X 512GIG:%08X\n",
+        *MEM_PML4(U64 *),*MEM_512GIG_NUM(U64 *);
+  "FIXED_AREA:%010X\n",SYS_FIXED_AREA;
+  "HEAP_BASE :%010X\nHEAP_LIMIT:%010X\n",mem_heap_base,mem_heap_limit;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocBin.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocBin.HC.HTML new file mode 100755 index 0000000..dccf733 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocBin.HC.HTML @@ -0,0 +1,173 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Bin"
+
+CDocBin *DocBinFindNum(CDoc *haystack_doc,I64 needle_num)
+{
+  CDocBin *b=haystack_doc->bin_head.next;
+  while (b!=&haystack_doc->bin_head) {
+    if (b->num==needle_num)
+      return b;
+    b=b->next;
+  }
+  return NULL;
+}
+
+CDocBin *DocBinFindTag(CDoc *haystack_doc,U8 *needle_tag)
+{
+  CDocBin *b;
+  if (needle_tag) {
+    b=haystack_doc->bin_head.next;
+    while (b!=&haystack_doc->bin_head) {
+      if (b->tag && !StrCmp(b->tag,needle_tag))
+        return b;
+      b=b->next;
+    }
+  }
+  return NULL;
+}
+
+U0 DocBinsValidate(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocBin *b,*b1;
+  CDocEntry *doc_e,*doc_e2;
+  I64 renum_num=0;
+  b=doc->bin_head.next;
+  while (b!=&doc->bin_head) {
+    b->use_cnt=0;
+    b->tmp_use_cnt=0;
+    b->renum_num=-1;
+    Free(b->tag);
+    b->tag=NULL;
+    b=b->next;
+  }
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (doc_e->de_flags & DOCEF_HAS_BIN) {
+      if (b=doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num)) {
+        if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+          b->tmp_use_cnt=I32_MAX;
+        if (!b->use_cnt++)
+          b->renum_num=++renum_num;
+        doc_e->bin_num=b->renum_num;
+        if (!b->tag && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+          b->tag=StrNew(doc_e->tag,doc->mem_task);
+      } else {
+        RawPrint(3000,"Bin Not Found");
+        doc_e->type=doc_e->de_flags=0;
+        doc_e->type_u8=DOCT_ERROR;
+      }
+    }
+    doc_e=doc_e2;
+  }
+
+  b=doc->bin_head.next;
+  doc->cur_bin_num=1;
+  while (b!=&doc->bin_head) {
+    b1=b->next;
+    if (!b->use_cnt) {
+      QueRem(b);
+      Free(b->data);
+      Free(b);
+    } else {
+      b->num=b->renum_num;
+      if (b->num>=doc->cur_bin_num)
+        doc->cur_bin_num=b->num+1;
+    }
+    b=b1;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 DocBinDel(CDoc *doc,CDocBin *b)
+{
+  if (doc && b && b->use_cnt) {
+    b->use_cnt--;
+    if (!b->use_cnt) {
+      QueRem(b);
+      Free(b->tag);
+      Free(b->data);
+      Free(b);
+    }
+  } else
+    RawPrint(3000,"DocBinDel");
+}
+
+I64 DocBinPtrRst(CDoc *doc,CDocEntry *doc_e)
+{
+  U8 *st,*st2;
+  CDoc *doc2;
+  CDocBin *tmpb,*tmpb2;
+  I64 i,bin_num=0;
+  if (doc_e->de_flags&DOCEF_HAS_BIN &&
+        doc_e->bin_ptr_link && StrLen(doc_e->bin_ptr_link)) {
+    bin_num=doc_e->bin_num;
+    st=StrNew(doc_e->bin_ptr_link);
+    st2=StrNew(st);
+    StrLastRem(st,",",st2);
+    i=Str2I64(st2);
+    if (i>0||*st2) {
+      doc2=DocRead(st);
+      if (i>0  && (tmpb2=DocBinFindNum(doc2,i)) ||
+            i==0 && (tmpb2=DocBinFindTag(doc2,st2))) {
+        i=1;
+        if (bin_num>0) {
+          if (tmpb=DocBinFindNum(doc,bin_num)) {
+            i=tmpb->use_cnt;
+            DocBinDel(doc,tmpb);
+          }
+        } else
+          bin_num=doc->cur_bin_num++;
+        tmpb=MAllocIdent(tmpb2,doc->mem_task);
+        tmpb->use_cnt=i;
+        tmpb->data=MAllocIdent(tmpb2->data,doc->mem_task);
+        tmpb->num=bin_num;
+        doc_e->bin_data=tmpb;
+        if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+          tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
+        else
+          tmpb->tag=NULL;
+        QueIns(tmpb,doc->bin_head.last);
+      } else
+        bin_num=0;
+      DocDel(doc2);
+    } else
+      bin_num=0;
+    Free(st2);
+    Free(st);
+    doc_e->bin_num=bin_num;
+  }
+  return bin_num;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocChar.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocChar.HC.HTML new file mode 100755 index 0000000..c0061aa --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocChar.HC.HTML @@ -0,0 +1,683 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Editor"
+
+public I64 EdCurU8(CDoc *doc)
+{//Return cur U8. See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry;
+  I64 res=-1;
+  if (doc_ce->type_u8==DOCT_TEXT &&
+        doc_ce->min_col<=doc->cur_col<doc_ce->max_col)
+    res=doc_ce->tag[doc->cur_col];
+  else if (doc_ce->type_u8==DOCT_TAB)
+    res='\t';
+  else if (doc_ce->type_u8==DOCT_NEW_LINE ||
+        doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
+    res='\n';
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public U0 EdCursorLeft(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor left. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  U8 *dst;
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
+  I64 cc=doc->cur_col,y=doc_ce->y;
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (sc>=0 && sc&SCF_CTRL) {
+    while (doc_ce->last!=doc && (doc_ce->last->y==y ||
+          doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
+      doc_ce=doc_ce->last;  //TODO: sel? recurse?
+    cc=doc_ce->min_col;
+  } else {
+    if (cc>doc_ce->min_col) {
+      if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+      }
+      cc--;
+      if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+        doc_ce=doc_ne;
+        cc=doc_ce->min_col;
+      }
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+    } else {
+      cc=doc_ce->min_col;
+      while (doc_ce->last!=doc &&
+            (doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
+            doc_ce->last->type_u8==DOCT_INDENT ||
+            doc_ce->last->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+        doc_ce=doc_ce->last;
+        if (sc>=0)
+          BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      }
+      if (doc_ce->last!=doc) {
+        doc_ce=doc_ce->last;
+        if (doc_ce->max_col>doc_ce->min_col) {
+          cc=doc_ce->max_col-1;
+          if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
+            dst=doc_ce->tag+cc;
+            doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+            *dst=0;
+            doc_ce->max_col=cc;
+            QueIns(doc_ne,doc_ce);
+            doc_ce=doc_ne;
+            cc=doc_ce->min_col;
+          }
+        } else
+          cc=doc_ce->max_col;
+        if (sc>=0)
+          BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      }
+    }
+  }
+  doc->cur_col=cc;
+  doc->cur_entry=doc_ce;
+  if (doc_ce!=original_ce)
+    DocFormBwd(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdCursorRight(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor right. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  U8 *dst;
+  CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
+  I64 cc=doc->cur_col,y=doc_ce->y,old_de_flags,old_color;
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (sc>=0 && sc&SCF_CTRL) {
+    while (doc_ce!=doc && doc_ce->next->y==y &&
+          doc_ce->next->type_u8!=DOCT_SOFT_NEW_LINE && doc_ce->next!=doc &&
+          (doc_ce->next->type_u8!=DOCT_NEW_LINE || !(doc->flags & DOCF_FORM)) ||
+          doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))
+      doc_ce=doc_ce->next;
+    if (doc_ce->max_col>doc_ce->min_col)
+      cc=doc_ce->max_col-1;
+    else
+      cc=doc_ce->min_col;
+  } else {
+    if (cc<doc_ce->max_col) {
+      if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+        doc_ce=doc_ne;
+        cc=doc_ce->min_col;
+      }
+      cc++;
+      old_de_flags=doc_ce->de_flags;
+      old_color=doc_ce->type;
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
+        dst=doc_ce->tag+cc;
+        doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+        *dst=0;
+        doc_ne->type=DOCT_TEXT | old_color & -0x100;
+        doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
+        doc_ce->max_col=cc;
+        QueIns(doc_ne,doc_ce);
+        doc_ce=doc_ne;
+        cc=doc_ce->min_col;
+      } else if (cc>=doc_ce->max_col) {
+        doc_ce=doc_ce->next;
+        cc=doc_ce->min_col;
+      }
+    } else {
+      if (doc_ce!=doc) {
+        if (cc<=doc_ce->min_col && sc>=0)
+          BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+        doc_ce=doc_ce->next;
+        while (doc_ce!=doc && doc_ce->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
+          if (sc>=0)
+            BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+          doc_ce=doc_ce->next;
+        }
+        cc=doc_ce->min_col;
+        if (doc_ce->type_u8==DOCT_SOFT_NEW_LINE) {
+          if (sc>=0)
+            BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+          doc_ce=doc_ce->next;
+          cc=doc_ce->min_col;
+        }
+      }
+    }
+  }
+  doc->cur_col=cc;
+  doc->cur_entry=doc_ce;
+  if (doc_ce!=original_ce)
+    DocFormFwd(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdLineUp(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor up. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  U8 *dst;
+  I64 y,x;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
+
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (doc_ce->type_u8==DOCT_HEX_ED) {
+    doc->cur_col=doc->cur_col-doc_ce->hex_ed_width*3;
+    if (doc->cur_col>=0) {
+      if (unlock)
+        DocUnlock(doc);
+      return;
+    } else
+      doc->cur_col=0;
+  }
+  x=doc->x; y=doc->y;
+  if (IsEditableText(doc_ce)) {
+    if (doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      doc_ne->x=doc_ce->x+doc->cur_col;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+    } else if (doc->cur_col==doc_ce->min_col && doc_ce->last!=doc)
+      doc_ce=doc_ce->last;
+  } else if (doc_ce->last!=doc)
+    doc_ce=doc_ce->last;
+  if (sc>=0)
+    BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+  doc->cur_entry=doc_ce;
+  DocFormBwd(doc);
+  doc_ce=doc->cur_entry;
+  while (doc_ce->last!=doc && (doc_ce->y>=y ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+    doc_ce=doc_ce->last;
+    if (sc>=0)
+      BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+  }
+  y=doc_ce->y;
+  doc->y=y;
+  while (doc_ce!=doc && (doc_ce->y>=y && doc_ce->x>=x ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+    if (sc>=0)
+      BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+    doc_ce=doc_ce->last;
+  }
+
+  if (doc_ce==doc || doc_ce->y<y)
+    doc_ce=doc_ce->next;
+  else {
+    if (!IsEditableText(doc_ce)) {
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+    } else {
+      if (doc_ce->next->x==x) {
+        doc_ce=doc_ce->next;
+        if (doc->flags & DOCF_FORM)
+          while (doc_ce->next->x==x &&
+                (!Bt(doldoc.type_flags_form,doc_ce->type_u8) &&
+                !(doc_ce->de_flags&DOCEF_LINK)||
+                doc_ce->de_flags&DOCEF_SKIP_IN_FORM))
+            doc_ce=doc_ce->next;
+      }
+    }
+  }
+  if (doc_ce->de_flags&DOCEF_TAG) {
+    doc->cur_col=x-doc_ce->x;
+    if (IsEditableText(doc_ce)) {
+      if (doc->cur_col>doc_ce->max_col)
+        doc->cur_col=doc_ce->max_col;
+    } else if (doc->cur_col>=doc_ce->max_col)
+      doc->cur_col=doc_ce->max_col-1;
+    if (doc->cur_col<doc_ce->min_col)
+      doc->cur_col=doc_ce->min_col;
+  } else {
+    if (doc_ce->type_u8==DOCT_HEX_ED) {
+      doc->cur_col=RoundI64((doc_ce->len-1)*3,doc_ce->hex_ed_width*3);
+      if (doc->cur_col<0)
+        doc->cur_col=0;
+    } else
+      doc->cur_col=doc_ce->min_col;
+  }
+  if (IsEditableText(doc_ce) && doc_ce->x<x) {
+    if (doc->cur_col<doc_ce->max_col-1) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      if (sc>=0) {
+        if (sc&SCF_SHIFT)
+          doc_ne->type=doc_ce->type | DOCET_SEL;
+        else
+          doc_ne->type=doc_ce->type & ~DOCET_SEL;
+      }
+      doc_ne->x=doc_ce->x+doc->cur_col;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+      doc_ce=doc_ne;
+      doc->cur_col=doc_ce->min_col;
+    }
+  }
+  doc->cur_entry=doc_ce;
+  DocFormFwd(doc);
+  doc->x=doc->cur_entry->x+doc->cur_col;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdLineDown(CDoc *doc,I64 sc=I64_MIN)
+{//Move cursor down. Might need a call to DocRecalc().
+//See EdRenumAsm for an example.
+  Bool unlock=DocLock(doc);
+  U8 *dst;
+  I64 y,x,old_de_flags=0,old_color;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne,*doc_ce2;
+  if (sc!=I64_MIN) sc=sc.u32[0];
+  if (doc_ce->type_u8==DOCT_HEX_ED) {
+    doc->cur_col=doc->cur_col+doc_ce->hex_ed_width*3;
+    if (doc->cur_col>=doc_ce->len*3) {
+      doc->cur_entry=doc_ce=doc_ce->next;
+      doc->cur_col=doc_ce->min_col;
+      doc->x=doc_ce->x+doc->cur_col;
+      doc->y=doc_ce->y;
+    }
+    if (unlock)
+      DocUnlock(doc);
+    return;
+  }
+  x=doc->x; y=doc->y;
+  if (IsEditableText(doc_ce)) {
+    if (doc->cur_col>doc_ce->min_col && doc->cur_col<doc_ce->max_col-1) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      if (sc>=0) {
+        if (sc&SCF_SHIFT)
+          doc_ne->type=doc_ce->type | DOCET_SEL;
+        else
+          doc_ne->type=doc_ce->type & ~DOCET_SEL;
+      }
+      doc_ne->x=doc_ce->x+doc->cur_col;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+      doc_ce=doc_ne;
+      doc->cur_col=doc_ce->min_col;
+    }
+  }
+  doc_ce2=doc_ce;
+  while (doc_ce!=doc && (doc_ce->y<=y ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
+    doc_ce=doc_ce->next;
+  y=doc_ce->y;
+  doc->y=y;
+  while (doc_ce!=doc && (doc_ce->y<=y && doc_ce->x<=x ||
+        doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
+    old_de_flags=doc_ce->de_flags;
+    old_color=doc_ce->type;
+    doc_ce=doc_ce->next;
+  }
+  if (doc_ce->last!=doc && (doc_ce->x>x && doc_ce->last->y>=y || doc_ce->y>y)) {
+    doc_ce=doc_ce->last;
+    doc->cur_entry=doc_ce;
+    if (!((doc_ce->type_u8==DOCT_NEW_LINE ||
+          doc_ce->type_u8==DOCT_SOFT_NEW_LINE ||
+          doc_ce->type_u8==DOCT_INDENT) &&
+          (doc_ce->last->type_u8==DOCT_NEW_LINE ||
+          doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
+          doc_ce->last->type_u8==DOCT_INDENT)))
+      DocFormBwd(doc);
+    doc_ce=doc->cur_entry;
+  }
+  while (doc_ce2!=doc && (doc_ce2!=doc_ce || IsEditableText(doc_ce))) {
+    if ((doc_ce2->y<y || doc_ce2->x<x ||
+          doc_ce2->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP) ||
+          doc_ce2->x==x && !doc_ce2->max_col &&
+          Bt(doldoc.type_flags_nontag_invis,doc_ce2->type_u8)) && sc>=0)
+      BEqu(&doc_ce2->type,DOCEt_SEL,sc&SCF_SHIFT);
+    if (doc_ce2==doc_ce) break;
+    doc_ce2=doc_ce2->next;
+  }
+  if (doc_ce->de_flags&DOCEF_TAG) {
+    doc->cur_col=x-doc_ce->x;
+    if (IsEditableText(doc_ce)) {
+      if (doc->cur_col>doc_ce->max_col)
+        doc->cur_col=doc_ce->max_col;
+    } else if (doc->cur_col>=doc_ce->max_col)
+      doc->cur_col=doc_ce->max_col-1;
+    if (doc->cur_col<doc_ce->min_col)
+      doc->cur_col=doc_ce->min_col;
+  } else
+    doc->cur_col=doc_ce->min_col;
+  if (IsEditableText(doc_ce)&&doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
+    dst=doc_ce->tag+doc->cur_col;
+    doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+    *dst=0;
+    doc_ne->type=DOCT_TEXT | old_color & -0x100;
+    doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
+    doc_ce->max_col=doc->cur_col;
+    doc_ne->x=doc_ce->x+doc->cur_col;
+    QueIns(doc_ne,doc_ce);
+    doc_ce=doc_ne;
+    doc->cur_col=doc_ce->min_col;
+  }
+  doc->cur_entry=doc_ce;
+  DocFormFwd(doc);
+  if (!(doc->flags & DOCF_FORM))
+    while (doc_ce!=doc && doc_ce!=doc->cur_entry) {
+      if (sc>=0)
+        BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+      doc_ce=doc_ce->next;
+    }
+  doc->x=doc->cur_entry->x+doc->cur_col;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 EdCharDel(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry;
+
+  if (doc_ce==doc) {
+    if (unlock)
+      DocUnlock(doc);
+    return;
+  }
+  if (doc_ce->max_col!=0 &&
+        (IsEditableText(doc_ce)||doc_ce->type_u8==DOCT_DATA)) {
+    if (doc_ce->type_u8==DOCT_DATA && doc_ce->de_flags & DOCEF_HAS_TERMINATOR &&
+          doc->cur_col==doc_ce->max_col-1) {
+      if (unlock)
+        DocUnlock(doc);
+      return;
+    }
+    if (doc->cur_col<doc_ce->max_col)
+      StrCpy(doc_ce->tag+doc->cur_col,doc_ce->tag+doc->cur_col+1);
+    if (doc->cur_col>=doc_ce->max_col-1) {
+      doc->cur_entry=doc_ce->next;
+      doc->cur_col=doc->cur_entry->min_col;
+    }
+    DocRemSoftNewLines(doc,doc->cur_entry);
+    if (unlock)
+      DocUnlock(doc);
+    return;
+  }
+  doc->cur_entry=doc_ce->next;
+  doc->cur_col=doc->cur_entry->min_col;
+  if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
+    DocEntryDel(doc,doc_ce);
+  DocRemSoftNewLines(doc,doc->cur_entry);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 ChkDollarBufSize(CDoc *doc)
+{
+  U8 *b;
+  if (doc->dollar_buf_ptr>=doc->dollar_buf_size-2) {
+    doc->dollar_buf_size<<=1;
+    b=MAlloc(doc->dollar_buf_size,doc->mem_task);
+    MemCpy(b,doc->dollar_buf,doc->dollar_buf_ptr);
+    Free(doc->dollar_buf);
+    doc->dollar_buf=b;
+  }
+}
+
+U0 EdCharIns(I64 ch,I64 sc,CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  U8 *st,*src,*dst;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
+  I64 i,j,m,y=doc_ce->y;
+
+  if (doc->flags & DOCF_IN_DOLLAR) {
+    if (!Bt(char_bmp_printable,ch))
+      goto ic_done;
+    ChkDollarBufSize(doc);
+    doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
+    if (ch=='$') {
+      if (doc->dollar_buf_ptr==2) {
+        doc->flags&=~DOCF_IN_DOLLAR;
+        doc->dollar_buf_ptr=0;
+        goto ic_cont;
+      } else {
+        doc->dollar_buf[doc->dollar_buf_ptr]=0;
+        doc->flags&=~DOCF_IN_DOLLAR;
+        DocPrint(doc,"%s",doc->dollar_buf);
+        doc->dollar_buf_ptr=0;
+        goto ic_done;
+      }
+    } else
+      goto ic_done;
+  }
+  if (ch=='$' && !(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
+    doc->flags|=DOCF_IN_DOLLAR;
+    doc->dollar_buf_ptr=0;
+    doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
+    goto ic_done;
+  }
+  if (ch=='\r') goto ic_done;
+
+    ic_cont:
+  if ((ch==CH_SPACE || ch=='\n') &&
+        !(sc & (SCF_CTRL|SCF_SHIFT)) &&
+        doc_ce->de_flags &
+        (DOCEF_LINK|DOCEF_TREE|DOCEF_LST|DOCEF_CHECK_COLLAPSABLE|
+        DOCEF_LEFT_MACRO|DOCEF_LEFT_EXP|DOCEF_LEFT_CB|DOCEF_LEFT_IN_STR |
+        DOCEF_RIGHT_MACRO|DOCEF_RIGHT_EXP|DOCEF_RIGHT_CB|DOCEF_RIGHT_IN_STR)) {
+    doc->cmd_U8=ch;
+    DocEntryRun(doc,doc_ce,FALSE);
+    DocLock(doc);
+    goto ic_done;
+  }
+  if (doc_ce->type_u8==DOCT_HEX_ED) {
+    if (doc_ce->de_flags&DOCEF_DEREF_DATA &&
+          !(doc_ce->de_flags&DOCEF_REMALLOC_DATA))
+      st=doc_ce->data;
+    else
+      st=&doc_ce->data;
+    i=doc->cur_col;
+    j=i%(doc_ce->hex_ed_width*3);
+    m=i/(doc_ce->hex_ed_width*3)*doc_ce->hex_ed_width;
+    if (j>=doc_ce->hex_ed_width<<1)
+      st[j-doc_ce->hex_ed_width<<1+m]=ch;
+    else {
+      ch=ToUpper(ch)-'0';
+      if (ch>9) {
+        ch+='0'-'A'+10;
+        if (!(10<=ch<=15))
+          goto ic_done;
+      }
+      m=j>>1+m;
+      if (j & 1)
+        st[m]=st[m] & 0xF0| ch;
+      else
+        st[m]=st[m] & 0xF | ch<<4;
+    }
+    doc->cur_col++;
+    goto ic_done;
+  }
+  if (doc->flags & DOCF_OVERSTRIKE) {
+    if (Bt(char_bmp_displayable,ch)) {
+ic_overstrike:
+      if (IsEditableText(doc_ce)) {
+        if (doc->cur_col<doc_ce->max_col) {
+          if (doc_ce->tag[doc->cur_col]) {
+            doc_ce->tag[doc->cur_col++]=ch;
+            goto ic_done;
+          }
+        } else {
+          doc_ce=doc_ce->next;
+          doc->cur_entry=doc_ce;
+          doc->cur_col=doc_ce->min_col;
+          goto ic_overstrike;
+        }
+      } else if (doc_ce->type_u8==DOCT_DATA) {
+        if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR) {
+          if (doc_ce->tag[doc->cur_col] &&
+                doc->cur_col<doc_ce->min_col+doc_ce->len) {
+            doc_ce->tag[doc->cur_col++]=ch;
+            if ( ! doc_ce->tag[doc->cur_col]) {
+              doc_ce->tag[doc->cur_col]='_';
+              doc_ce->tag[doc->cur_col+1]=0;
+            }
+          } else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA)
+            goto ic_not_overstrike;
+        } else if (doc_ce->tag[doc->cur_col])
+          doc_ce->tag[doc->cur_col++]=ch;
+        goto ic_done;
+      }
+      doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
+      doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
+      doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
+      QueIns(doc_ne,doc_ce->last);
+    } else if (ch=='\n') {
+      while (doc->cur_entry->next!=doc && doc->cur_entry->y==y)
+        doc->cur_entry=doc->cur_entry->next;
+      doc->cur_col=doc->cur_entry->min_col;
+    } else if (ch=='\t') {
+      if (doc->flags&DOCF_FORM)
+        goto ic_form_tab;
+    }
+    goto ic_done;
+  }
+ic_not_overstrike:
+  if (ch=='\n') {
+    if (sc&SCF_CTRL && !(sc&SCF_SHIFT)) {
+      doc_ne=DocEntryNewBase(doc,
+            DOCT_PAGE_BREAK|doc->settings_head.dft_text_attr<<8);
+    } else {
+      doc_ne=DocEntryNewBase(doc,
+            DOCT_NEW_LINE|doc->settings_head.dft_text_attr<<8);
+    }
+    DocInsEntry(doc,doc_ne);
+  } else if (ch=='\t') {
+    if (doc->flags&DOCF_FORM &&
+          (Bt(doldoc.type_flags_form,doc->cur_entry->type_u8) ||
+          doc->cur_entry->de_flags&DOCEF_LINK) &&
+          !(doc->cur_entry->de_flags&DOCEF_SKIP_IN_FORM)) {
+ic_form_tab:
+      doc->cur_entry=doc->cur_entry->next;
+      doc->cur_col=doc->cur_entry->min_col;
+      DocFormFwd(doc);
+      goto ic_done;
+    } else {
+      doc_ne=DocEntryNewBase(doc,DOCT_TAB|doc->settings_head.dft_text_attr<<8);
+      DocInsEntry(doc,doc_ne);
+    }
+  } else {
+    if (Bt(char_bmp_displayable,ch)) {
+      if (doc_ce->type_u8==DOCT_DATA) {
+        while (TRUE) {
+          i=doc_ce->len+doc_ce->min_col;
+          if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR)
+            i++;
+          if (doc_ce->max_col<i) {
+            st=doc_ce->tag;
+            doc_ce->max_col++;
+            for (i=doc_ce->max_col;i>doc->cur_col;i--)
+              st[i]=st[i-1];
+            st[doc->cur_col++]=ch;
+            break;
+          } else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA) {
+            st=MAlloc(doc_ce->max_col+8,doc->mem_task);
+            MemCpy(st,doc_ce->tag,doc_ce->max_col+1);
+            Free(doc_ce->tag);
+            doc_ce->tag=st;
+            doc_ce->len=MSize(st)-doc_ce->min_col-2; //See DataTagWidth
+            Free(doc_ce->data);
+            doc_ce->data=MAlloc(doc_ce->len+2,doc->mem_task);
+          } else
+            break;
+        }
+      } else if (IsEditableText(doc_ce)) {
+        dst=st=MAlloc(doc_ce->max_col+2,doc->mem_task);
+        src=doc_ce->tag;
+        i=doc->cur_col;
+        while (i-->0)
+          *dst++=*src++;
+        *dst++=ch;
+        while (*dst++=*src++);
+        Free(doc_ce->tag);
+        doc_ce->tag=st;
+        doc_ce->max_col++;
+        doc->cur_col++;
+      } else {
+        doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
+        doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
+        doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
+        doc_ne->x=doc_ce->x+1;
+        QueIns(doc_ne,doc_ce->last);
+      }
+    }
+  }
+ic_done:
+  DocRemSoftNewLines(doc,doc->cur_entry);
+  if (doc->cur_entry->de_flags & DOCEF_UPDATE_DATA &&
+        (doc->cur_entry->type_u8==DOCT_DATA ||
+        doc->cur_entry->type_u8==DOCT_CHECK_BOX))
+    DocDataScan(doc,doc->cur_entry);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 EdLineDel(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ce2;
+  I64 y;
+  y=doc->y;
+  while (doc_ce!=doc && doc_ce->y==y)
+    doc_ce=doc_ce->next;
+  doc->cur_entry=doc_ce;
+  doc->cur_col=doc_ce->min_col;
+  doc_ce=doc_ce->last;
+  while (doc_ce!=doc && doc_ce->y==y) {
+    doc_ce2=doc_ce->last;
+    if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
+      DocEntryDel(doc,doc_ce);
+    doc_ce=doc_ce2;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocClipBoard.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocClipBoard.HC.HTML new file mode 100755 index 0000000..ed6b566 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocClipBoard.HC.HTML @@ -0,0 +1,156 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Clip"
+
+sys_clip_doc=DocNew;
+
+public U0 ClipDel()
+{//Delete everything on clip.
+  DocRst(sys_clip_doc,TRUE);
+}
+
+public U0 ClipCopy(CDoc *doc)
+{//Copy DOCET_SEL flagged entries to clip.
+  CDoc *doc2=sys_clip_doc;
+  Bool unlock_doc=DocLock(doc),
+        unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_e=doc->head.next,*doc_ne;
+  ClipDel;
+  while (doc_e!=doc) {
+    if (doc_e->type & DOCET_SEL) {
+      doc_e->type&=~DOCET_SEL;
+      if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
+        doc_ne=DocEntryCopy(doc2,doc_e);
+        QueIns(doc_ne,doc2->head.last);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public U0 ClipCut(CDoc *doc)
+{//Remove sel entries and place on clip.
+  CDoc *doc2=sys_clip_doc;
+  Bool unlock_doc=DocLock(doc),
+        unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_e=doc->head.next,*doc_e1,*doc_ne,*doc_e2=NULL;
+  ClipDel;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (doc_e->type & DOCET_SEL) {
+      doc_e->type&=~DOCET_SEL;
+      if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
+        doc_ne=DocEntryCopy(doc2,doc_e);
+        QueIns(doc_ne,doc2->head.last);
+      }
+      if (doc_e==doc->cur_entry || doc_e==doc_e2)
+        doc_e2=doc_e->next;
+      DocEntryDel(doc,doc_e);
+    }
+    doc_e=doc_e1;
+  }
+  if (doc_e2) {
+    doc->cur_entry=doc_e2;
+    doc->cur_col=doc_e2->min_col;
+  }
+  DocRemSoftNewLines(doc,NULL);
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public U0 ClipPaste(CDoc *doc)
+{//Insert copy of clip at insert pt, cur_entry.
+  CDoc *doc2=sys_clip_doc;
+  Bool unlock_doc=DocLock(doc),
+        unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e;
+  if (doc_ce->type_u8==DOCT_DATA) {
+    doc_e=doc2->head.next;
+    while (doc_e!=doc2) {
+      if (doc_e->de_flags&DOCEF_TAG)
+        DocPrintPartial(doc,"%s",doc_e->tag);
+      doc_e=doc_e->next;
+    }
+  } else
+    DocInsDoc(doc,doc2);
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public U0 DocCut(CDoc *doc,CDocEntry *start,CDocEntry *end)
+{//Del start to end entry, including end points.
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *doc_e1;
+  if (start!=doc && (start->last!=end || end==doc))
+    do {
+      doc_e1=start->next;
+      if (start==doc->cur_entry) {
+        doc->cur_entry=start->next;
+        doc->cur_col=doc->cur_entry->min_col;
+      }
+      DocEntryDel(doc,start);
+      if (start==end)
+        break;
+      start=doc_e1;
+    } while (start!=doc);
+  DocRemSoftNewLines(doc,NULL);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+public CDoc *DocCopy(CDoc *doc,CDocEntry *start,CDocEntry *end)
+{//Copies start to end entry, including end points.
+  CDoc *doc2=DocNew;
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *doc_ne;
+  if (start!=doc && (start->last!=end || end==doc))
+    do {
+      if (!Bt(doldoc.type_flags_data,start->type_u8)) {
+        doc_ne=DocEntryCopy(doc2,start);
+        QueIns(doc_ne,doc2->head.last);
+      }
+      if (start==end)
+        break;
+      start=start->next;
+    } while (start!=doc);
+  if (unlock_doc)
+    DocUnlock(doc);
+  return doc2;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocCodeTools.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocCodeTools.HC.HTML new file mode 100755 index 0000000..2570272 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocCodeTools.HC.HTML @@ -0,0 +1,689 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+U0 EdReplaceTroubleOne(CDoc *doc,U8 *st_original,U8 *st_safe,I64 num,
+        Bool to_safe,Bool sel)
+{
+  U8 buf[STR_LEN];
+  StrPrint(buf,st_safe,num);
+  if (to_safe)
+    EdReplace(doc,st_original,buf,sel);
+  else
+    EdReplace(doc,buf,st_original,sel);
+}
+
+U0 EdReplaceTroubleAll(CDoc *doc,Bool to_safe,Bool sel)
+{
+  I64 i=0;
+  EdReplaceTroubleOne(doc,"#assert" ,"//<@%d@>"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"#define" ,"//<@%d@>"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"#include","//<@%d@>"  ,i++,to_safe,sel);
+//#if will match #if,#ifdef,#ifndef,#ifaot and #ifjit
+  EdReplaceTroubleOne(doc,"#if"     ,"//<@%d@>"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"#endif"  ,"//<@%d@>"  ,i++,to_safe,sel);
+//Convert #exe to union because we want that indent pattern.
+  EdReplaceTroubleOne(doc,"#exe"    ,"union @%d@",i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"'{'"     ,"'<@%d@>'"  ,i++,to_safe,sel);
+  EdReplaceTroubleOne(doc,"'}'"     ,"'<@%d@>'"  ,i++,to_safe,sel);
+}
+
+#define C_INDENT_SPACES         2
+#define ASM_RENUM_SPACING       5
+
+#define EF_REINDENT     0
+#define EF_CMP_CHK      1
+#define EF_RENUM_ASM    2
+#define EF_CTRL_SLIDER  3
+#define EF_CH_SC        4
+
+I64 PopUpEdFmt()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$LTBLUE$$MU,\"Compile Check\",LE=EF_CMP_CHK$\n"
+        "$MU,\"Reindent HolyC Fun (Beware braces in strings.)\","
+        "LE=EF_REINDENT$\n"
+        "$MU,\"Renum Asm Local @@ Labels for Fun\",LE=EF_RENUM_ASM$\n"
+        "$MU,\"Insert Template Code: Ctrl Slider\",LE=EF_CTRL_SLIDER$\n"
+        "$MU,\"Insert ASCII/Scan Code Hex Codes for key pressed\","
+        "LE=EF_CH_SC$\n\n"
+        "$MU,\"CANCEL\",LE=DOCM_CANCEL$\n\n"
+        "$GREEN$<ALT-BACKSPACE>$FG$ to undo if not happy\n"
+        "with the ress.\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CRILex
+{
+  CCmpCtrl *cc1,*cc2;
+  CQueVectU8 *indent;
+  I64 depth,exp_depth,one_shot;
+  Bool was_new_line,is_not_cont;
+};
+
+I64 EdRILex(CRILex *rx)
+{
+  rx->is_not_cont=FALSE;
+  I64 i;
+  CLexFile *tmpf;
+  do {
+    Lex(rx->cc1);
+    Lex(rx->cc2);
+    i=PrsKeyWord(rx->cc2);
+    if (rx->cc1->token=='\n' && rx->cc2->token==';' || rx->cc2->token=='{' ||
+          rx->cc2->token=='}' || rx->cc2->token==':' || rx->cc2->token==')' &&
+          !rx->exp_depth || i==KW_ELSE || i==KW_CATCH || i==KW_DO)
+      rx->is_not_cont=TRUE;
+    if (rx->was_new_line && (rx->cc1->token!=':' || i==KW_CASE ||
+          i==KW_DFT || i==KW_START || i==KW_END)) {
+      tmpf=rx->cc2->lex_include_stk;
+      while (tmpf->next)
+        tmpf=tmpf->next;
+      QueVectU8Put(rx->indent,tmpf->cur_entry->y,rx->depth+rx->one_shot);
+      rx->one_shot=0;
+    }
+    if (rx->cc2->token=='\n')
+      rx->was_new_line=TRUE;
+    else
+      rx->was_new_line=FALSE;
+  } while (rx->cc1->token=='\n');
+  return rx->cc1->token;
+}
+
+U0 EdRIExp(CRILex *rx)
+{
+  if (rx->cc1->token=='(') {
+    if (!rx->exp_depth++)
+      rx->depth+=3;
+    EdRILex(rx);
+    while (rx->cc1->token && rx->cc1->token!=')')
+      EdRIExp(rx);
+    if (!--rx->exp_depth) {
+      rx->depth-=3;
+      if (rx->depth<0) rx->depth=0;
+    }
+  } else if (rx->cc1->token=='[') {
+    if (!rx->exp_depth++)
+      rx->depth+=3;
+    EdRILex(rx);
+    while (rx->cc1->token && rx->cc1->token!=']')
+      EdRIExp(rx);
+    if (!--rx->exp_depth) {
+      rx->depth-=3;
+      if (rx->depth<0) rx->depth=0;
+    }
+  }
+  EdRILex(rx);
+}
+
+U0 EdRIStmt(CRILex *rx,Bool indent)
+{
+  I64 i;
+  Bool cont;
+  if (rx->cc1->token=='{') {
+    rx->depth++;
+    EdRILex(rx);
+    while (rx->cc1->token && rx->cc1->token!='}')
+      EdRIStmt(rx,FALSE);
+    if (--rx->depth<0) rx->depth=0;
+    EdRILex(rx);
+  } else {
+    if (indent) rx->depth++;
+    do {
+      cont=FALSE;
+      switch (PrsKeyWord(rx->cc1)) {
+        case KW_IF:
+          EdRILex(rx);
+          EdRIExp(rx);
+          EdRIStmt(rx,TRUE);
+          if (PrsKeyWord(rx->cc1)==KW_ELSE) {
+            EdRILex(rx);
+            if (PrsKeyWord(rx->cc1)==KW_IF && rx->cc2->token!='\n')
+              EdRIStmt(rx,FALSE);
+            else
+              EdRIStmt(rx,TRUE);
+          }
+          break;
+        case KW_TRY:
+          EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          if (PrsKeyWord(rx->cc1)==KW_CATCH) {
+            EdRILex(rx);
+            EdRIStmt(rx,TRUE);
+          }
+          break;
+        case KW_LOCK:
+          EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          break;
+        case KW_FOR:
+        case KW_WHILE:
+          EdRILex(rx);
+          EdRIExp(rx);
+          EdRIStmt(rx,TRUE);
+          break;
+        case KW_ASM:
+        case KW_CLASS:
+        case KW_UNION:
+          if (EdRILex(rx)==TK_IDENT)
+            EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          break;
+        case KW_DO:
+          EdRILex(rx);
+          EdRIStmt(rx,TRUE);
+          if (PrsKeyWord(rx->cc1)==KW_WHILE) {
+            EdRILex(rx);
+            EdRIExp(rx);
+          }
+          if (rx->cc1->token==';')
+            EdRILex(rx);
+          break;
+        case KW_SWITCH:
+          EdRILex(rx);
+          EdRIExp(rx);
+          if (rx->cc1->token=='{') {
+            rx->depth++;
+            EdRILex(rx);
+            i=0;
+            while (rx->cc1->token && rx->cc1->token!='}') {
+              switch (PrsKeyWord(rx->cc1)) {
+                case KW_START:
+                  rx->depth+=i; i=0;
+                  while (EdRILex(rx) && rx->cc1->token!=':');
+                  EdRILex(rx);
+                  i++;
+                  break;
+                case KW_END:
+                  rx->depth+=i; i=0;
+                  if (--rx->depth<0) rx->depth=0;
+                  while (EdRILex(rx) && rx->cc1->token!=':');
+                  EdRILex(rx);
+                  break;
+                case KW_CASE:
+                case KW_DFT:
+                  rx->depth+=i; i=0;
+                  while (EdRILex(rx) && rx->cc1->token!=':');
+                  EdRILex(rx);
+                  break;
+                default:
+                  if (rx->cc1->token)
+                    EdRIStmt(rx,TRUE);
+              }
+            }
+            if (--rx->depth<0) rx->depth=0;
+            EdRILex(rx);
+          }
+          break;
+        default:
+          if (rx->cc1->token==TK_IDENT && rx->cc1->hash_entry &&
+                rx->cc1->hash_entry->type&(HTT_OPCODE|HTT_ASM_KEYWORD)) {
+//          rx->one_shot=4-rx->depth;
+            do EdRILex(rx);
+            while (rx->cc2->token && rx->cc2->token!='\n');
+            rx->is_not_cont=TRUE;
+          } else {
+            while (rx->cc1->token && rx->cc1->token!=';' &&
+                  rx->cc1->token!=':') {
+              if (rx->cc2->token=='\n' && !rx->is_not_cont)
+                rx->one_shot=3;
+              EdRILex(rx);
+            }
+            if (rx->cc1->token==':')
+              cont=TRUE;
+            EdRILex(rx);
+          }
+      }
+    } while (cont && rx->cc1->token!='}');
+    if (indent && --rx->depth<0)
+      rx->depth=0;
+  }
+}
+
+CQueVectU8 *EdRICode(CDoc *doc)
+{
+  CQueVectU8 *res;
+  CRILex *rx=CAlloc(sizeof(CRILex));
+
+  rx->cc1=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
+  Free(rx->cc1->lex_include_stk->full_name);
+  LexAttachDoc(rx->cc1,rx->cc1->lex_include_stk,doc,,
+        doc->cur_entry,doc->cur_col);
+
+  rx->cc2=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
+  Free(rx->cc2->lex_include_stk->full_name);
+  LexAttachDoc(rx->cc2,rx->cc2->lex_include_stk,doc,,
+        doc->cur_entry,doc->cur_col);
+
+  rx->indent=QueVectU8New(doc->cur_entry->y);
+
+  Lex(rx->cc1);
+  EdRIStmt(rx,FALSE);
+
+  CmpCtrlDel(rx->cc1);
+  CmpCtrlDel(rx->cc2);
+  res=rx->indent;
+  Free(rx);
+  return res;
+}
+
+U0 EdRemFunLeadingSpace(CDoc *doc)
+{
+  Bool unlock=DocLock(doc),
+        start_of_line=TRUE;
+  U8 *ptr;
+  I64 ch,levels=1;
+  CDocEntry *doc_e,*doc_e2;
+
+  EdGoToFun(doc,FALSE,FALSE);
+  doc_e=doc->cur_entry->next;
+  do {
+    doc_e2=doc_e->next;
+    if (doc_e!=doc && doc_e!=doc->cur_entry &&
+          !(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X)))
+      switch (doc_e->type_u8) {
+        case DOCT_TEXT:
+          ptr=doc_e->tag;
+          if (start_of_line) {
+            while (*ptr==CH_SPACE)
+              ptr++;
+            if (*ptr)
+              start_of_line=FALSE;
+            ptr=StrNew(ptr,doc->mem_task);
+            Free(doc_e->tag);
+            doc_e->tag=ptr;
+          }
+          if (!*ptr)
+            DocEntryDel(doc,doc_e);
+          else {
+            while (ch=*ptr++)
+              if (ch=='{')
+                levels++;
+              else if (ch=='}') {
+                if (!--levels)
+                  break;
+              }
+            if (!levels) goto ls_done;
+          }
+          break;
+        case DOCT_TAB:
+          if (start_of_line)
+            DocEntryDel(doc,doc_e);
+          break;
+        case DOCT_NEW_LINE:
+          start_of_line=TRUE;
+          break;
+        default:
+          start_of_line=FALSE;
+      }
+    doc_e=doc_e2;
+  } while (doc_e!=doc->cur_entry);
+ls_done:
+  DocRecalc(doc);
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+class CRenum
+{
+  CRenum *next,*last;
+  U8 label[sizeof(CEdFindText.find_text)];
+};
+
+I64 EdRAGetU8(CDoc *doc)
+{
+  I64 res=-1;
+  while (doc->cur_entry!=doc &&
+        doc->cur_entry->type&DOCET_SEL && res<0) {
+    res=EdCurU8(doc);
+    EdCursorRight(doc);
+  }
+  return res;
+}
+
+U0 EdRACollect(CDoc *doc,CRenum *head)
+{
+  I64 ch,i;
+  CRenum *tmpr;
+  U8 buf[sizeof(CEdFindText.find_text)];
+  ch=EdRAGetU8(doc);
+  while (ch>=0) {
+    if (ch!='@')
+      ch=EdRAGetU8(doc);
+    else {
+      ch=EdRAGetU8(doc);
+      if (ch=='@') {
+        ch=EdRAGetU8(doc);
+        StrCpy(buf,"@@");
+        i=2;
+        while (ch>=0 && i<sizeof(CEdFindText.find_text)) {
+          if (Bt(char_bmp_alpha_numeric,ch))
+            buf[i++]=ch;
+          else
+            break;
+          ch=EdRAGetU8(doc);
+        }
+        if (i<sizeof(CEdFindText.find_text)) {
+          buf[i++]=0;
+          while (ch>=0 && Bt(char_bmp_white_space,ch))
+            ch=EdRAGetU8(doc);
+          if (ch==':') {
+            ch=EdRAGetU8(doc);
+            tmpr=MAlloc(sizeof(CRenum));
+            StrCpy(tmpr->label,buf);
+            QueIns(tmpr,head->last);
+          }
+        }
+      }
+    }
+  }
+//This is needed because we moved the
+  //cursor and it didn't recalc.
+  DocRecalc(doc);
+}
+
+U0 EdRenumAsm(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  I64 num=0;
+  CRenum head,*tmpr,*tmpr1;
+  U8    buf[sizeof(CEdFindText.find_text)],
+        buf2[sizeof(CEdFindText.find_text)];
+
+  QueInit(&head);
+  EdSelFun(doc,TRUE);
+  EdRACollect(doc,&head);
+
+  tmpr=head.next;
+  while (tmpr!=&head) {
+    tmpr1=tmpr->next;
+    num+=ASM_RENUM_SPACING;
+    StrPrint(buf,"@#%02d",num);
+    EdReplace(doc,tmpr->label,buf,TRUE,TRUE,TRUE);
+    Free(tmpr);
+    tmpr=tmpr1;
+  }
+
+  while (num) {
+    StrPrint(buf, "@#%02d",num);
+    StrPrint(buf2,"@@%02d",num);
+    EdReplace(doc,buf,buf2,TRUE,TRUE,TRUE);
+    num-=ASM_RENUM_SPACING;
+  }
+  EdSelAll(doc,FALSE);
+  DocRecalc(doc);
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 EdCodeTools2(CDoc *doc,I64 tool_action,Bool beep=TRUE)
+{
+  Bool okay,unlock=DocLock(doc),start_of_line=TRUE;
+  CDocEntry *doc_e,*doc_ne;
+  I64 i,start_y,end_y,x,r,goto_line_num;
+  U8 *b,*st,*st2,*prj_file;
+  CTask *task=NULL;
+  CJob *tmpc;
+  CQueVectU8 *indent;
+
+  DocRecalc(doc);
+  goto_line_num=doc->cur_entry->y+1;
+
+  DocCaptureUndo(doc,TRUE);
+  switch (tool_action) {
+    case EF_CMP_CHK:
+      okay=FALSE;
+      if (doc->flags&DOCF_PLAIN_TEXT)
+        DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
+      DocWrite(doc);
+      task=Spawn(&SrvCmdLine,NULL,"Srv",,Fs);
+      st2=DirCur;
+      st=MStrPrint("Cd(\"%s\");",st2);
+      tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+      Free(st2);
+      Free(st);
+      WinHorz(Fs->win_left,Fs->win_right, task);
+      WinVert(Fs->win_top, Fs->win_bottom,task);
+      if (JobResScan(tmpc,&r)) {
+        st=DirFile(doc->filename.name,,"PRJ.Z");
+        prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
+        Free(st);
+        if (FileFind(prj_file)) {
+          st2=DirFile(prj_file),
+                st=MStrPrint("Cd(\"%s\");",st2);
+          Free(st2);
+          tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|
+                1<<JOBf_FOCUS_MASTER|1<<JOBf_FREE_ON_COMPLETE);
+          Free(st);
+          st=MStrPrint("\"$WW,1$\";Cmp(\"%s\",\"SysTmp\",\"SysTmp\");",
+                prj_file);
+          tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+          Free(st);
+          if (JobResScan(tmpc,&r))
+            if (!r) {
+              tmpc=TaskExe(task,Fs,
+                    "Load(\"SysTmp\",LDF_JUST_LOAD);",
+                    1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+              if (JobResScan(tmpc,&r))
+                okay=TRUE;
+            }
+          tmpc=TaskExe(task,Fs,"Del(\"SysTmp.*\");",
+                1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+          JobResScan(tmpc,&r);
+        } else {
+          Free(prj_file);
+          st=DirFile(doc->filename.name,"Load","HC.Z");
+          prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
+          Free(st);
+          if (FileFind(prj_file))
+            st=MStrPrint("\"$WW,1$\";ExeFile(\"%s\",CCF_JUST_LOAD);",prj_file);
+          else
+            st=MStrPrint("\"$WW,1$\";ExeFile(\"%s\",CCF_JUST_LOAD);",
+                  doc->filename.name);
+          tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+          Free(st);
+          if (JobResScan(tmpc,&r) && r)
+            okay=TRUE;
+        }
+        Free(prj_file);
+      }
+      if (!okay) {
+        PopUpOk("Has Errors");
+        while (LBts(&sys_semas[SEMA_FIX],0))
+          Yield;
+        ToFileLine(dbg.fix_file_line,&st,&i);
+        LBtr(&sys_semas[SEMA_FIX],0);
+        if (!StrCmp(st,doc->filename.name))
+          goto_line_num=i;
+        Free(st);
+      }
+      break;
+    case EF_REINDENT:
+      start_y=doc->cur_entry->y;
+      EdReplaceTroubleAll(doc,TRUE,FALSE);
+      DocGoToLine(doc,start_y+1);
+      if (EdGoToFun(doc,FALSE,FALSE)) {
+        start_y=doc->cur_entry->y;
+        indent=EdRICode(doc);
+        DocUnlock(doc);
+        if (beep) {
+          Snd(86); Sleep(150); Snd;
+          Sleep(100);
+          Snd(86); Sleep(150); Snd;
+        }
+        DocLock(doc);
+        EdRemFunLeadingSpace(doc);
+        DocGoToLine(doc,start_y+1);
+        doc_e=doc->cur_entry;
+        end_y=start_y+indent->total_cnt;
+        while (start_y<=doc_e->y<end_y) {
+          if (doc_e!=doc && doc_e!=doc->cur_entry &&
+                !(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X))) {
+            if (doc_e->type_u8==DOCT_NEW_LINE||
+                  doc_e->type_u8==DOCT_SOFT_NEW_LINE)
+              start_of_line=TRUE;
+            else {
+              if (start_of_line) {
+                i=QueVectU8Get(indent,doc_e->y)*C_INDENT_SPACES;
+                x=doc_e->x+1;
+                while (i>8) {
+                  doc_ne=DocEntryNewBase(doc,
+                        DOCT_TAB|doc->settings_head.dft_text_attr<<8,,
+                        x,doc_e->y,doc_e->page_line_num);
+                  MemCpy(&doc_ne->settings,
+                        &doc_e->settings,sizeof(CDocSettings));
+                  QueIns(doc_ne,doc_e->last);
+                  i-=8;
+                  x+=8;
+                }
+                if (i>0) {
+                  b=MAlloc(i+1,doc->mem_task);
+                  MemSet(b,CH_SPACE,i);
+                  b[i]=0;
+                  doc_ne=DocEntryNewBase(doc,
+                        DOCT_TEXT|doc->settings_head.dft_text_attr<<8,,
+                        x,doc_e->y,doc_e->page_line_num);
+                  doc_ne->tag=b;
+                  doc_ne->max_col=1;
+                  MemCpy(&doc_ne->settings,
+                        &doc_e->settings,sizeof(CDocSettings));
+                  QueIns(doc_ne,doc_e->last);
+                }
+              }
+              start_of_line=FALSE;
+            }
+          }
+          doc_e=doc_e->next;
+        }
+        QueVectU8Del(indent);
+      }
+      start_y=doc->cur_entry->y;
+      EdReplaceTroubleAll(doc,FALSE,FALSE);
+      DocGoToLine(doc,start_y+1);
+      break;
+    case EF_RENUM_ASM:
+      if (EdGoToFun(doc,FALSE,TRUE)) {
+        if (EdCurU8(doc)=='{') {
+          EdCursorRight(doc);
+          DocRecalc(doc);
+        } else if (EdCurU8(doc)==':') {
+          EdCursorRight(doc);
+          if (EdCurU8(doc)==':')
+            EdCursorRight(doc);
+          DocRecalc(doc);
+        }
+        DocUnlock(doc);
+        if (beep) {
+          Snd(86); Sleep(150); Snd;
+          Sleep(100);
+          Snd(86); Sleep(150); Snd;
+        }
+        DocLock(doc);
+        EdRenumAsm(doc);
+      }
+      break;
+  }
+
+  DocRecalc(doc);
+  DocGoToLine(doc,goto_line_num);
+
+  DocUnlock(doc);
+  if (!unlock)
+    DocLock(doc);
+  if (task)
+    Kill(task,FALSE);
+}
+
+U0 EdPopUpChSC(I64 *_ch,I64 *_sc)
+{
+  I64 sc;
+  "Press A Key\n";
+  DocPut->flags|=DOCF_SIZE_MIN;
+  do GetMsg(_ch,&sc,1<<MSG_KEY_DOWN);
+  while (sc.u8[0]==SC_SHIFT || sc.u8[0]==SC_CTRL || sc.u8[0]==SC_ALT);
+  *_sc=sc;
+}
+
+U0 EdChSC(CDoc *doc)
+{
+  I64 ch,sc;
+  U8 buf[STR_LEN];
+  StrPrint(buf,"EdPopUpChSC(%d,%d);",&ch,&sc);
+  PopUp(buf,Fs);
+  if (ch==CH_BACKSPACE)
+    DocPrint(doc,"CH_BACKSPACE,0x%X",sc);
+  else if (ch=='\n')
+    DocPrint(doc,"'\n',0x%X",sc);
+  else if (CH_CTRLA<=ch<=CH_CTRLZ)
+    DocPrint(doc,"CH_CTRL%C,0x%X",ch+'@',sc);
+  else if (ch=='$')
+    DocPrint(doc,"'$$',0x%X",sc);
+  else if (ch=='\\')
+    DocPrint(doc,"'\\\\',0x%X",sc);
+  else if (ch=='\'')
+    DocPrint(doc,"'\\\'',0x%X",sc);
+  else if (ch==CH_ESC)
+    DocPrint(doc,"CH_ESC,0x%X",sc);
+  else if (ch==CH_SHIFT_ESC)
+    DocPrint(doc,"CH_SHIFT_ESC,0x%X",sc);
+  else if (ch==CH_SPACE)
+    DocPrint(doc,"CH_SPACE,0x%X",sc);
+  else if (ch==CH_SHIFT_SPACE)
+    DocPrint(doc,"CH_SHIFT_SPACE,0x%X",sc);
+  else if (Bt(char_bmp_displayable,ch))
+    DocPrint(doc,"'%c',0x%X",ch,sc);
+  else
+    DocPrint(doc,"0x%X,0x%X",ch,sc);
+}
+
+U0 EdCodeTools(CDoc *doc)
+{
+  I64 tool_action=PopUpEdFmt;
+  switch (tool_action) {
+    case EF_CMP_CHK:
+    case EF_REINDENT:
+    case EF_RENUM_ASM:
+      EdCodeTools2(doc,tool_action);
+      break;
+    case EF_CTRL_SLIDER:
+      TemplateCtrlSlider(doc);
+      break;
+    case EF_CH_SC:
+      EdChSC(doc);
+      break;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocDblBuf.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocDblBuf.HC.HTML new file mode 100755 index 0000000..f86e075 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocDblBuf.HC.HTML @@ -0,0 +1,141 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Task;StdOut/Task"
+public CDoc *DocPut(CTask *task=NULL)
+{//Current document that StdOut Put() goes to.
+//Basically, StdOut unless double buffering.
+  CDoc *res;
+  if (!task) task=Fs;
+  if (Bt(&task->task_flags,TASKf_INPUT_FILTER_TASK))
+    task=task->parent_task;
+  if ((res=task->put_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
+    return res;
+  else
+    return NULL;
+}
+
+public CDoc *DocDisplay(CTask *task=NULL)
+{//StdOut displayed unless double buffering.
+  CDoc *res;
+  if (!task) task=Fs;
+  if ((res=task->display_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
+    return res;
+  else
+    return NULL;
+}
+
+public CDoc *DocBorder(CTask *task=NULL)
+{//Doc holding border of window text.
+  CDoc *res;
+  if (!task) task=Fs;
+  if ((res=task->border_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
+    return res;
+  else
+    return NULL;
+}
+
+public CDoc *DocDblBufStart(CTask *task=NULL)
+{//See ::/Demo/Spy.HC
+  Bool unlock_ddoc;
+  CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task),*res;
+  if (!pdoc || !ddoc || pdoc!=ddoc)
+    res=NULL; //Already Double buffering
+  else {
+    if (!task) task=Fs;
+    unlock_ddoc=DocLock(ddoc); //dont change during winupdate, so lock DocPut
+    res=DocNew(,task);
+    res->win_task               =ddoc->win_task;
+    res->max_entries            =ddoc->max_entries;
+    MemCpy(res->find_replace,ddoc->find_replace,sizeof(CEdFindText));
+    MemCpy(&res->filename,&ddoc->filename,sizeof(CEdFileName));
+    res->left_click_link        =ddoc->left_click_link;
+    res->right_click_link       =ddoc->right_click_link;
+    res->user_put_data  =ddoc->user_put_data;
+    res->user_put_key   =ddoc->user_put_key;
+    res->user_put_s             =ddoc->user_put_s;
+    res->parent_doc             =ddoc->parent_doc;
+    res->desc           =ddoc->desc;
+    res->user_data              =ddoc->user_data;
+    res->flags|=ddoc->flags&DOCG_DBL_BUF_FLAGS | DOCF_DONT_SHOW;
+    task->put_doc=res;
+    if (unlock_ddoc)
+      DocUnlock(ddoc);
+  }
+  return res;
+}
+
+public Bool DocDblBufEnd(CTask *task=NULL)
+{//See ::/Demo/Spy.HC
+  Bool res=FALSE;
+  CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
+  if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
+    if (!task) task=Fs;
+    ddoc->flags|=DOCF_DONT_SHOW;
+    pdoc->flags&=~DOCF_DONT_SHOW;
+    DocLock(ddoc);
+    task->display_doc=pdoc;
+    DocUnlock(ddoc);
+    DocDel(ddoc);
+    res=TRUE;
+  }
+  return res;
+}
+
+public Bool DocDblBufSwap(CTask *task=NULL)
+{//See ::/Demo/Spy.HC
+  Bool res=FALSE;
+  CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
+  if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
+    if (!task) task=Fs;
+    ddoc->flags|=DOCF_DONT_SHOW;
+    pdoc->flags&=~DOCF_DONT_SHOW;
+    DocLock(ddoc);
+    task->display_doc=pdoc;
+    DocUnlock(ddoc);
+    DocRst(ddoc,TRUE);
+    MemCpy(ddoc->find_replace,pdoc->find_replace,sizeof(CEdFindText));
+    MemCpy(&ddoc->filename,&pdoc->filename,sizeof(CEdFileName));
+    ddoc->max_entries           =pdoc->max_entries;
+    ddoc->flags                 =pdoc->flags&DOCG_DBL_BUF_FLAGS |
+          ddoc->flags&~DOCG_DBL_BUF_FLAGS;
+    ddoc->left_click_link       =pdoc->left_click_link;
+    ddoc->right_click_link      =pdoc->right_click_link;
+    ddoc->user_put_data         =pdoc->user_put_data;
+    ddoc->user_put_key          =pdoc->user_put_key;
+    ddoc->user_put_s            =pdoc->user_put_s;
+    ddoc->desc                  =pdoc->desc;
+    ddoc->user_data             =pdoc->user_data;
+    task->put_doc=ddoc;
+    res=TRUE;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocEd.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocEd.HC.HTML new file mode 100755 index 0000000..f728497 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocEd.HC.HTML @@ -0,0 +1,296 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+
+public Bool View()
+{//Go live for user interaction until <ESC> or <SHIFT-ESC>.
+  I64 ch;
+  do ch=DocGetKey;
+  while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  return ch==CH_ESC;
+}
+
+#help_index "DolDoc"
+U8 *EdOverStrikeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags & DOCF_OVERSTRIKE)
+    *st='O';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdAutoSaveCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags & DOCF_AUTO_SAVE)
+    *st='S';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdFilterCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->find_replace->filter_lines)
+    *st='F';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdDollarCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags & DOCF_IN_DOLLAR)
+    *st='$';
+  else
+    *st='.';
+  st[1]=0;
+  return st;
+}
+
+U8 *EdMoreCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *st=MAlloc(8,mem_task);
+  if (doc->flags&DOCF_MORE)
+    StrCpy(st,"More.");
+  else
+    StrCpy(st,".....");
+  return st;
+}
+
+U8 *EdDollarTypeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
+{
+  CDoc *doc=doc_e->user_data;
+  U8 *src=DefineSub(doc->cur_entry->type_u8,"ST_DOC_CMDS"),
+        *st=CAlloc(8,mem_task);
+  if (doc->cur_entry==doc)
+    src="EOF";
+  else if (!src)
+    src="ERR";
+  StrPrint(st,"%-3ts",src);
+  return st;
+}
+
+public Bool DocEd(CDoc *doc,I64 dof_flags=0)
+{//Live for user interaction. End on <ESC> or <SHIFT-ESC>.
+  CDoc *old_put_doc       =DocPut,
+        *old_display_doc=DocDisplay,
+        *old_border_doc =DocBorder,*bdoc;
+  CDocEntry *doc_e;
+  I64 old_attr=Fs->text_attr,
+        old_top =Fs->win_top, old_bottom=Fs->win_bottom,
+        old_left=Fs->win_left,old_right =Fs->win_right,
+        old_title_src=Fs->title_src;
+  Bool res,unlock;
+  U8 *old_task_title;
+  if (dof_flags&DOF_WIN_MAX)
+    WinMax;
+
+  unlock=DocLock(doc);
+  doc->win_task=Fs;
+  bdoc=DocNew;
+  bdoc->flags|=DOCF_BORDER_DOC;
+  DocPrint(bdoc,"$CM+TY+LX+NC,0,-1$");
+  DocPrint(bdoc,"$TX+RX+BD,\"[X]\"$");
+  DocPrint(bdoc,"$BK,1$$TX+LX+BD,\"MENU\"$$BK,0$");
+
+  old_task_title=StrNew(Fs->task_title);
+  if (Fs->title_src!=TTS_LOCKED_CONST) {
+    Fs->title_src=TTS_ED_FILENAME;
+    MemCpy(Fs->task_title,doc->filename.name,STR_LEN-1);
+  }
+  doc_e=DocPrint(bdoc,"$DA-TRM-P+BD+RD+CX+IV,LEN=STR_LEN-1,"
+        "A=\"%%s...\",SCX=16$");
+  doc_e->data=&Fs->task_title;
+  DocDataFmt(bdoc,doc_e);
+
+  if (doc->flags & DOCF_ALLOW_UNDO) {
+    DocPrint(bdoc,"$CM+BY+LX+NC,1,1$");
+    doc_e=DocPrint(bdoc,"$DA+BD+RD-TRM,RT=U32,A=\"Undo:%%03d\"$\n");
+    doc_e->data=&doc->undo_cnt;
+    DocDataFmt(bdoc,doc_e);
+  }
+
+  DocPrint(bdoc,"$CM+BY+RX+NC,-31,1$");
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\"     \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdMoreCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdDollarTypeCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdFilterCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdOverStrikeCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdAutoSaveCB;
+  doc_e=DocPrint(bdoc,"$TX+BD+TC,\" \"$");
+  doc_e->user_data=doc;
+  doc_e->tag_cb=&EdDollarCB;
+  doc_e=DocPrint(bdoc,"$DA+BD+RD-TRM,A=\"Line:%%04d \"$");
+  doc_e->data=&doc->line;
+  DocDataFmt(bdoc,doc_e);
+  doc_e=DocPrint(bdoc,"$DA+BD+RD-TRM,A=\"Col:%%04d\"$\n");
+  doc_e->data=&doc->col;
+  DocDataFmt(bdoc,doc_e);
+
+  DocRecalc(bdoc);
+  DocRecalc(doc);
+  if (!(dof_flags&DOF_DONT_HOME))
+    DocTop(doc);
+  Fs->border_doc=bdoc;
+  if (doc!=old_display_doc)
+    doc->parent_doc=old_display_doc;
+  Fs->put_doc=Fs->display_doc=doc;
+  if (!(dof_flags&DOF_DONT_TEXT_ATTR))
+    Fs->text_attr=DOC_ATTR_DFT_TEXT;
+  if (!(dof_flags&DOF_DONT_SHOW)) {
+    LBts(&Fs->display_flags,DISPLAYf_SHOW);
+    WinZBufUpdate;
+  }
+  if (dof_flags&DOF_SIZE_MIN)
+    doc->flags|=DOCF_SIZE_MIN;
+
+  DocUnlock(doc);
+  if (!(dof_flags&DOF_DONT_WINMGR_SYNC)) {
+    Refresh(2,TRUE);
+    if (doc->flags&DOCF_SIZE_MIN)
+      Refresh(2,TRUE);
+  }
+  res=View;
+
+  DocLock(doc);
+  if (res) {
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX)
+        DocDataScan(doc,doc_e);
+      doc_e=doc_e->next;
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  Fs->border_doc =old_border_doc;
+  Fs->display_doc=old_display_doc;
+  Fs->put_doc    =old_put_doc;
+  Fs->text_attr  =old_attr;
+  if (Fs->title_src!=TTS_LOCKED_CONST) {
+    Fs->title_src  =old_title_src;
+    StrCpy(Fs->task_title,old_task_title);
+  }
+  Free(old_task_title);
+  DocDel(bdoc);
+  if (dof_flags&DOF_SIZE_MIN) {
+    WinHorz(old_left,old_right);
+    WinVert(old_top,old_bottom);
+  }
+  return res;
+}
+
+#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
+public Bool Ed(U8 *link_st,I64 edf_dof_flags=0)
+{//Invoke document editor.
+  U8 *filename,*needle_str;
+  I64 i,num;
+  Bool cont,res=FALSE;
+  CDoc *doc;
+
+  switch (i=EdLinkCvt(link_st,&filename,&needle_str,&num,edf_dof_flags)) {
+    case -1:
+      break;
+    case LK_DEF:
+      doc=DocNew;
+      doc->desc='DictDef';
+      ACDDefsPut(doc,filename,num);
+      goto ej_doc;
+    case LK_HELP_INDEX:
+      doc=DocNew;
+      doc->desc='HelpIndx';
+      DocHelpIdx(doc,filename);
+ej_doc:
+      if (!(edf_dof_flags&EDF_BAIL)) {
+        DocEd(doc);
+        DocDel(doc);
+      }
+      if (!(edf_dof_flags&EDF_WAS_WRITE))
+        res=TRUE;
+      break;
+    default:
+      if (IsRaw)
+        res=EdLite(filename,num,edf_dof_flags);
+      else {
+        cont=TRUE;
+        if (!(edf_dof_flags&EDF_BAIL) && !(LK_DOC<=i<=LK_DOC_LINE) &&
+              !FilesFindMatch(filename,FILEMASK_TXT) &&
+              !PopUpCancelOk(ST_WARN_ST "Not Text File\n\n"))
+          cont=FALSE;
+        if (cont)
+          res=DocFileEd(i,filename,needle_str,&num,edf_dof_flags);
+      }
+  }
+  Free(filename);
+  Free(needle_str);
+  return res;
+}
+
+public Bool Plain(U8 *filename,I64 edf_dof_flags=0)
+{//Edit document in plain text mode, so dollar signs are not special.
+  Bool res;
+  U8 *st=MStrPrint("PI:%s",filename);
+  res=Ed(st,edf_dof_flags);
+  Free(st);
+  return res;
+}
+
+#help_index "DolDoc;Job/Exe;Task/Job/Exe"
+public I64 PopUpEd(U8 *filename,CTask *parent=NULL,CTask **_pu_task=NULL)
+{//Create PopUp win task and edit a doc.
+  U8 *st=MStrPrint("Ed(\"%Q\");",filename);
+  I64 res=PopUp(st,parent,_pu_task);
+  Free(st);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocExt.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocExt.HC.HTML new file mode 100755 index 0000000..670d919 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocExt.HC.HTML @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+extern Bool DocEd(CDoc *doc,I64 dof_flags=0);
+extern I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,
+        Bool exited,I64 *_has_action=NULL);
+extern U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE);
+extern Bool DocGoToLine(CDoc *doc,I64 line_num);
+extern U0 DocLoad(CDoc *doc,U8 *src2,I64 size);
+extern U0 DocPrintAtomic(CDoc *doc=NULL,U8 *fmt,...);
+extern U0 DocPrintPartial(CDoc *doc=NULL,U8 *fmt,...);
+extern CDocEntry *DocPutS(CDoc *doc,U8 *st);
+extern U8 *DocSave(CDoc *doc,I64 *_size=NULL);
+extern I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e);
+extern I64 PopUpPickLst(U8 *lst);
+extern I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e);
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocFile.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocFile.HC.HTML new file mode 100755 index 0000000..099e603 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocFile.HC.HTML @@ -0,0 +1,388 @@ + + + + + + + + + + + +
+#help_index "DolDoc/File"
+
+public U0 DocLoad(CDoc *doc,U8 *src2,I64 size)
+{//Fetch doc from raw mem buf.
+  I64 i;
+  U8 *src;
+  Bool unlock=DocLock(doc);
+  CDocBin *tmpb;
+  doc->find_replace->filter_lines=0;
+  if (src2) {
+    DocPutS(doc,src2); //Too big DocPrint() is wasteful.
+    src=src2+StrLen(src2)+1;
+    i=size-(offset(CDocBin.end)-offset(CDocBin.start));
+    while (src<=src2+i) {
+      tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
+      MemCpy(&tmpb->start,src,offset(CDocBin.end)-offset(CDocBin.start));
+      src+=offset(CDocBin.end)-offset(CDocBin.start);
+      tmpb->data=MAlloc(tmpb->size,doc->mem_task);
+      if (tmpb->size) {
+        MemCpy(tmpb->data,src,tmpb->size);
+        src+=tmpb->size;
+      }
+      QueIns(tmpb,doc->bin_head.last);
+      if (tmpb->num>=doc->cur_bin_num)
+        doc->cur_bin_num=tmpb->num+1;
+    }
+  }
+  if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
+    DocBinsValidate(doc);
+  DocTop(doc); //Calls DocRecalc().  DOCT_CURSOR will be set.
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public CDoc *DocRead(U8 *name=NULL,I64 flags=0)
+{//Fetch doc from disk. See flags.
+  CDoc *doc=DocNew;
+  U8 *src,*name2;
+  I64 size=0;
+  CDirContext *dirc;
+  if (!name) name=blkdev.tmp_filename;
+  doc->flags|=flags;
+  name2=FileNameAbs(name);
+  StrCpy(doc->filename.name,name2);
+  if (src=FileRead(name2,&size,&doc->file_attr)) {
+    if (dirc=DirContextNew(name2)) {
+      DocLoad(doc,src,size);
+      DirContextDel(dirc);
+    }
+    Free(src);
+  }
+  Free(name2);
+  return doc;
+}
+
+public U8 *DocSave(CDoc *doc,I64 *_size=NULL)
+{//Store doc to raw mem buf.
+  CDocEntry *doc_e,*doc_e1;
+  CDocBin *b;
+  Bool unlock=DocLock(doc);
+  I64 ch,cnt=1;//terminator
+  U8 *st,*res,*dst,*src;
+
+  if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
+    DocBinsValidate(doc);
+  if (doc->flags&DOCF_NO_CURSOR)
+    DocRecalc(doc);
+  else {
+    DocRecalc(doc,RECALCF_ADD_CURSOR);
+    if (doc->head.next->type_u8==DOCT_CURSOR)
+      DocEntryDel(doc,doc->head.next); //If no cursor, DocLoad() puts at top.
+  }
+  for (doc_e=doc->head.next;doc_e!=doc;doc_e=doc_e->next) {
+    if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
+      switch (doc_e->type_u8) {
+        case DOCT_TAB:
+        case DOCT_PAGE_BREAK:
+        case DOCT_CURSOR:
+          cnt++;
+          break;
+        case DOCT_NEW_LINE:
+          if (doc->flags&DOCF_CARRIAGE_RETURN)
+            cnt+=2;
+          else
+            cnt++;
+          break;
+        case DOCT_SOFT_NEW_LINE:
+          break;
+        case DOCT_TEXT:
+          if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
+                DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP))&&
+                !(doc_e->type&DOCG_BL_IV_UL)) {
+            cnt+=StrLen(doc_e->tag);
+            if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)) ||
+                  doc->flags&DOCF_DBL_DOLLARS)
+              cnt+=StrOcc(doc_e->tag,'$');
+            break;
+          }
+        default:
+          st=Doc2PlainText(doc,doc_e);
+          cnt+=StrLen(st)+2;
+          Free(st);
+      }
+    }
+  }
+  for (b=doc->bin_head.next;b!=&doc->bin_head;b=b->next)
+    if (b->use_cnt>b->tmp_use_cnt)
+      cnt+=offset(CDocBin.end)-offset(CDocBin.start)+b->size;
+  res=MAlloc(cnt);
+  dst=res;
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (!Bt(doldoc.type_flags_data,doc_e->type_u8))
+      switch (doc_e->type_u8) {
+        case DOCT_CURSOR:
+          DocEntryDel(doc,doc_e);
+          *dst++=CH_CURSOR;
+          break;
+        case DOCT_TAB:
+          *dst++='\t';
+          break;
+        case DOCT_NEW_LINE:
+          if (doc->flags&DOCF_CARRIAGE_RETURN)
+            *dst++='\r';
+          *dst++='\n';
+          break;
+        case DOCT_SOFT_NEW_LINE:
+          break;
+        case DOCT_TEXT:
+          if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
+                DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
+                !(doc_e->type&DOCG_BL_IV_UL)) {
+            src=doc_e->tag;
+            while (ch=*src++) {
+              *dst++=ch;
+              if (ch=='$' && (!(doc->flags & (DOCF_PLAIN_TEXT|
+                    DOCF_PLAIN_TEXT_TABS)) || doc->flags&DOCF_DBL_DOLLARS))
+                *dst++=ch;
+            }
+            break;
+          }
+        default:
+          *dst++='$';
+          st=Doc2PlainText(doc,doc_e);
+          StrCpy(dst,st);
+          dst+=StrLen(st);
+          *dst++='$';
+          Free(st);
+      }
+    doc_e=doc_e1;
+  }
+  *dst++=0;
+  b=doc->bin_head.next;
+  if (b!=&doc->bin_head) {
+    do {
+      if (b->use_cnt>b->tmp_use_cnt) {
+        MemCpy(dst,&b->start,offset(CDocBin.end)-offset(CDocBin.start));
+        dst+=offset(CDocBin.end)-offset(CDocBin.start);
+        MemCpy(dst,b->data,b->size);
+        dst+=b->size;
+      }
+      b=b->next;
+    } while (b!=&doc->bin_head);
+  } else
+    cnt--; //No terminator
+  if (_size) *_size=cnt;
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public Bool DocWrite(CDoc *doc,Bool prompt=FALSE)
+{//Store doc to disk.
+  I64 size;
+  U8 *buf;
+  if (prompt && !DocForm(&doc->filename) ||
+        doc->filename.name[0]=='A' && doc->filename.name[2]==':')
+    return FALSE;  //CANCEL || LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE?
+  buf=DocSave(doc,&size);
+  FileWrite(doc->filename.name,buf,size,0,doc->file_attr);
+  Free(buf);
+  return TRUE;
+}
+
+#help_index "DolDoc"
+public U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2)
+{//Insert copy of doc2 into doc at insert pt, cur_entry.
+//TODO: DocRst
+  U8 *dst;
+  Bool unlock_doc,unlock_doc2=DocLock(doc2);
+  CDocEntry *doc_ne,*doc_e=doc2->head.next,*doc_ce;
+  if (!doc) doc=DocPut;
+  unlock_doc=DocLock(doc),
+        DocRemSoftNewLines(doc,NULL);
+  doc_ce=doc->cur_entry;
+  if (doc_ce->type_u8==DOCT_TEXT && doc->cur_col>doc_ce->min_col) {
+    if (doc->cur_col<doc_ce->max_col) {
+      dst=doc_ce->tag+doc->cur_col;
+      doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+      *dst=0;
+      doc_ne->type=DOCT_TEXT | doc_ce->type & 0xFFFFFF00;
+      doc_ce->max_col=doc->cur_col;
+      QueIns(doc_ne,doc_ce);
+      doc->cur_entry=doc_ne;
+      doc->cur_col=doc_ne->min_col;
+    } else
+      if (doc_ce!=doc)
+        doc->cur_entry=doc_ce->next;
+  }
+  while (doc_e!=doc2) {
+    if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE) {
+      doc_ne=DocEntryCopy(doc,doc_e);
+      QueIns(doc_ne,doc->cur_entry->last);
+    }
+    doc_e=doc_e->next;
+  }
+  DocRecalc(doc);
+  if (unlock_doc2)
+    DocUnlock(doc2);
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+#help_index "DolDoc/Compiler;Compiler/Directive"
+public U0 StreamDoc(CDoc *doc)
+{//Inject doc into compile stream. Use inside #exe{}.
+//TODO: DocRst
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      StreamPrint("%s",doc_e->tag);
+    else if (doc_e->type_u8==DOCT_NEW_LINE)
+      StreamPrint("\n");
+    else if (doc_e->type_u8==DOCT_TAB)
+      StreamPrint("\t");
+    doc_e=doc_e->next;
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+}
+
+#help_index "DolDoc"
+Bool DocCaptureUndo(CDoc *doc,Bool force=FALSE)
+{
+  Bool res=FALSE,unlock;
+  I64 time_stamp,flags;
+  CDocUndo *u;
+  if (doc->flags&DOCF_ALLOW_UNDO) {
+    unlock=DocLock(doc);
+    time_stamp=GetTSC;
+    if (doc->flags&DOCF_UNDO_DIRTY &&
+          time_stamp>doc->undo_head.last->time_stamp+cnts.time_stamp_freq<<4 ||
+          force) {
+      u=CAlloc(sizeof(CDocUndo),doc->mem_task);
+      u->time_stamp=time_stamp;
+      flags=doc->flags;
+      doc->flags&=~DOCF_NO_CURSOR;
+      u->body=DocSave(doc,&u->size);
+      doc->flags=flags;
+      QueIns(u,doc->undo_head.last);
+      doc->flags&=~DOCF_UNDO_DIRTY;
+      doc->undo_cnt++;
+      u->doc_flags=doc->flags;
+      res=TRUE;
+      if (doc->flags&DOCF_AUTO_SAVE)
+        DocWrite(doc);
+    }
+    if (unlock)
+      DocUnlock(doc);
+  }
+  return res;
+}
+ 
+U0 DocUndoRestore(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocUndo *u=doc->undo_head.last,*u_next,*u_last;
+  if (u!=&doc->undo_head) {
+    QueRem(u);
+    u_next=doc->undo_head.next;
+    u_last=doc->undo_head.last;
+    QueInit(&doc->undo_head);
+    DocRst(doc,TRUE);
+    doc->flags=u->doc_flags&~DOCF_NO_CURSOR;
+    DocLoad(doc,u->body,u->size);
+    doc->flags=u->doc_flags;
+    DocUndoDel(doc,u);
+    doc->undo_head.next=u_next;
+    doc->undo_head.last=u_last;
+  }
+  DocUndoCntSet(doc);
+  doc->flags&=~DOCF_UNDO_DIRTY;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+#help_index "Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
+public Bool DocType(CDoc *doc=NULL,U8 *filename,I64 trailing_new_lines=1)
+{//Output txt or graphic file to document.
+  Bool res=FALSE;
+  CDoc *doc2;
+  if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return FALSE;
+  if (FilesFindMatch(filename,FILEMASK_TXT)) {
+    doc2=DocRead(filename);
+    DocInsDoc(doc,doc2);
+    if (IsRaw)
+      DocDump(doc2,100000);
+    DocDel(doc2);
+    res=TRUE;
+  } else if (FilesFindMatch(filename,"*.GR*")) {
+    DocGR(doc,filename);
+    res=TRUE;
+  }
+  if (res)
+    DocPrint(doc,"%h*c",trailing_new_lines,'\n');
+  return res;
+}
+
+#help_index "Graphics/GR Files;"\
+        "File/Cmd Line (Typically);DolDoc/Cmd Line (Typically);"\
+        "StdOut;Cmd Line (Typically)"
+public Bool Type(U8 *filename,I64 trailing_new_lines=1)
+{//Output txt or graphic file to command line.
+  return DocType(,filename,trailing_new_lines);
+}
+
+#help_index "DolDoc/File"
+
+public U8 *DocLineRead(U8 *filename,I64 line,CTask *mem_task=NULL)
+{//Extract line from stored doc file. (Slow.)
+  U8 *res=NULL;
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  if (DocGoToLine(doc,line) && doc->cur_entry->type_u8==DOCT_TEXT)
+    res=StrNew(doc->cur_entry->tag,mem_task);
+  DocDel(doc);
+  return res;
+}
+
+public U8 *DocLineWrite(U8 *filename,I64 line,U8 *st)
+{//Write line to stored doc file. (Slow.)
+  U8 *res=NULL;
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  if (DocGoToLine(doc,line)) {
+    if (doc->cur_entry->type_u8==DOCT_TEXT) {
+      Free(doc->cur_entry->tag);
+      doc->cur_entry->tag=StrNew(st);
+    } else
+      DocPrint(doc,"%s",st);
+    DocTop(doc);
+    DocWrite(doc);
+  }
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocFind.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocFind.HC.HTML new file mode 100755 index 0000000..e7de5ed --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocFind.HC.HTML @@ -0,0 +1,615 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Editor"
+
+public Bool DocGoToLine(CDoc *doc,I64 line_num) //one based
+{//Nearest to specified line num.  Move cur_entry & center.
+  Bool res=FALSE,unlock;
+  if (doc) {
+    unlock=DocLock(doc);
+    doc->x=0;
+    doc->y=line_num-1;
+    DocRecalc(doc,RECALCt_FIND_CURSOR);
+    DocCenter(doc);
+    if (doc->cur_entry->y==line_num-1)
+      res=TRUE;
+    if (unlock)
+      DocUnlock(doc);
+  }
+  return res;
+}
+
+public Bool DocFind(CDoc *haystack_doc,I64 start_line_num=I64_MIN,
+U8 *needle,I64 match=1)
+{//Find str by searching tags. Move cur_entry & center.
+  Bool res=FALSE,unlock;
+  CDocEntry *doc_e;
+  U8 *ptr;
+  I64 i;
+  if (haystack_doc) {
+    unlock=DocLock(haystack_doc);
+    if (start_line_num==I64_MIN) {
+      res=TRUE;
+      doc_e=haystack_doc->head.next;
+    } else {
+      res=DocGoToLine(haystack_doc,start_line_num);
+      doc_e=haystack_doc->cur_entry;
+    }
+    if (res) {
+      if (needle) {
+        res=FALSE;
+        while (doc_e!=haystack_doc) {
+          if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
+//TODO: handle multi-DocEntry strs
+                (ptr=StrIMatch(needle,doc_e->tag))) {
+            i=ptr-doc_e->tag;
+            if (!--match) {
+              haystack_doc->cur_entry=doc_e;
+              if (i<doc_e->min_col) i=doc_e->min_col;
+              if (i>doc_e->max_col) i=doc_e->max_col;
+              haystack_doc->cur_col=i;
+              res=TRUE;
+              break;
+            }
+          }
+          doc_e=doc_e->next;
+        }
+      } else
+        res=FALSE;
+    }
+    if (!res) DocBottom(haystack_doc);
+    DocCenter(haystack_doc);
+    if (unlock)
+      DocUnlock(haystack_doc);
+  }
+  return res;
+}
+
+public Bool DocAnchorFind(CDoc *haystack_doc,U8 *needle_str)
+{//Find named anchor. Move cur_entry & center.
+  Bool res=FALSE,unlock;
+  CDocEntry *doc_e;
+  if (haystack_doc) {
+    unlock=DocLock(haystack_doc);
+    doc_e=haystack_doc->head.next;
+    if (needle_str)
+      while (doc_e!=haystack_doc) {
+        if (doc_e->type_u8==DOCT_ANCHOR && doc_e->de_flags & DOCEF_AUX_STR) {
+          if (!StrCmp(needle_str,doc_e->aux_str)) {
+            haystack_doc->cur_entry=doc_e;
+            haystack_doc->cur_col=doc_e->min_col;
+            res=TRUE;
+            break;
+          }
+        }
+        doc_e=doc_e->next;
+      }
+    if (!res) DocBottom(haystack_doc);
+    DocCenter(haystack_doc);
+    if (unlock)
+      DocUnlock(haystack_doc);
+  }
+  return res;
+}
+
+public U0 EdFindNext(CDoc *doc)
+{//Editor F3 find next, possibly doing replaces.
+  Bool unlock=DocLock(doc);
+  U8 *ptr,*ptr2,*ptr3;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce;
+  I64 sf_flags;
+  if (doc->find_replace->match_case)
+    sf_flags=0;
+  else
+    sf_flags=SFF_IGNORE_CASE;
+  if (doc->find_replace->whole_labels)
+    sf_flags|=SFG_WHOLE_LABELS;
+  do {
+    if (doc_e!=doc) {
+      if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
+            !(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP))) {
+        if (doc_e->type & DOCET_SEL ||
+              !doc->find_replace->scan_sel_text) {
+          if (doc->find_replace->scan_fwd) {
+            if (doc_e==doc_ce) {
+              ptr=doc_ce->tag+doc->cur_col+1;
+              if (ptr-doc_ce->tag>=doc_ce->max_col)
+                goto fn_skip;
+              if (ptr-doc_ce->tag<doc_ce->min_col)
+                ptr=doc_ce->tag+doc_ce->min_col;
+            } else
+              ptr=doc_e->tag;
+            if (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
+              doc->cur_entry=doc_e;
+              doc->cur_col=ptr-doc_e->tag;
+              if (doc->cur_col>=doc_e->max_col)
+                doc->cur_col=doc_e->max_col-1;
+              if (doc->cur_col<doc_e->min_col)
+                doc->cur_col=doc_e->min_col;
+              DocCenter(doc);
+              if (unlock)
+                DocUnlock(doc);
+              return;
+            }
+          } else {
+            ptr2=NULL;
+            ptr=doc_e->tag+doc_e->min_col;
+            if (doc_e==doc_ce)
+              ptr3=doc_ce->tag+doc->cur_col;
+            else
+              ptr3=doc_e->tag+doc_e->max_col;
+            while (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
+              if (ptr>=ptr3)
+                break;
+              ptr2=ptr++;
+            }
+            if (ptr2 && ptr2<ptr3) {
+              doc->cur_entry=doc_e;
+              doc->cur_col=ptr2-doc_e->tag;
+              if (doc->cur_col>=doc_e->max_col)
+                doc->cur_col=doc_e->max_col-1;
+              if (doc->cur_col<doc_e->min_col)
+                doc->cur_col=doc_e->min_col;
+              DocCenter(doc);
+              if (unlock)
+                DocUnlock(doc);
+              return;
+            }
+          }
+        }
+      }
+    }
+fn_skip:
+    if (doc->find_replace->scan_fwd)
+      doc_e=doc_e->next;
+    else
+      doc_e=doc_e->last;
+  } while (doc_e!=doc_ce);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 EdSelAll(CDoc *doc,Bool sel)
+{//Set state of DOCET_SEL on all entries.
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    BEqu(&doc_e->type,DOCEt_SEL,sel);
+    doc_e=doc_e->next;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public Bool EdFindPaired(CDoc *doc,U8 plus,U8 minus,
+Bool fwd,Bool abort_on_dbl_colon=FALSE)
+{//Find { } or ( ) pair. Move cur_entry & center.
+  Bool unlock=DocLock(doc),res=FALSE;
+  U8 *ptr;
+  I64 ch,levels=0,colons=0,original_col=doc->cur_col;
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce,*original_ce=doc_ce;
+  if (abort_on_dbl_colon && EdCurU8(doc)==':')
+    colons=1;
+  else
+    colons=0;
+  do {
+    if (doc_e!=doc) {
+      if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
+            !(doc_e->de_flags&DOCEF_FILTER_SKIP)) {
+        if (fwd) {
+          if (doc_e==doc_ce)
+            ptr=doc_e->tag+doc->cur_col+1;
+          else
+            ptr=doc_e->tag;
+          if (ptr-doc_e->tag<doc_e->min_col)
+            ptr=doc_e->tag+doc_e->min_col;
+          if (ptr-doc_e->tag>=doc_e->max_col)
+            goto pa_skip;
+          while (ch=*ptr++)
+            if (abort_on_dbl_colon && ch==':') {
+              if (++colons==2) {
+                doc->cur_entry=doc_e;
+                doc->cur_col=ptr-doc_e->tag-1;
+                EdCursorLeft(doc);
+                res=FALSE;
+                goto pa_done;
+              }
+            } else {
+              colons=0;
+              if (ch==plus)
+                levels++;
+              else if (ch==minus) {
+                if (!levels--) {
+                  doc->cur_entry=doc_e;
+                  doc->cur_col=ptr-doc_e->tag-1;
+                  res=doc->cur_entry!=original_ce ||
+                        doc->cur_col!=original_col;
+                  goto pa_done;
+                }
+              }
+            }
+        } else {
+          if (doc_e==doc_ce) {
+            ptr=doc_e->tag+doc->cur_col-1;
+            if (ptr-doc_e->tag>=doc_e->max_col)
+              ptr=doc_e->tag+doc_e->max_col-1;
+          } else
+            ptr=doc_e->tag+doc_e->max_col-1;
+          if (ptr-doc_e->tag<doc_e->min_col)
+            goto pa_skip;
+          while (ptr>=doc_e->tag+doc_e->min_col) {
+            ch=*ptr--;
+            if (abort_on_dbl_colon && ch==':') {
+              if (++colons==2) {
+                doc->cur_entry=doc_e;
+                doc->cur_col=ptr-doc_e->tag+1;
+                res=FALSE;
+                goto pa_done;
+              }
+            } else {
+              colons=0;
+              if (ch==plus)
+                levels++;
+              else if (ch==minus) {
+                if (!levels--) {
+                  doc->cur_entry=doc_e;
+                  doc->cur_col=ptr-doc_e->tag+1;
+                  res=doc->cur_entry!=original_ce ||
+                        doc->cur_col!=original_col;
+                  goto pa_done;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+pa_skip:
+    if (fwd)
+      doc_e=doc_e->next;
+    else
+      doc_e=doc_e->last;
+  } while (doc_e!=doc_ce);
+pa_done:
+  DocRecalc(doc);
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public Bool EdGoToFun(CDoc *doc,Bool fwd,Bool abort_on_dbl_colon)
+{//Move cur_entry to start of cur fun and center.(Shoddy)
+  Bool unlock=DocLock(doc),res=FALSE;
+  I64 ch,levels,colons;
+  if (fwd) {
+    levels=0;
+    colons=0;
+    while (doc->cur_entry!=doc) {
+      ch=EdCurU8(doc);
+      if (abort_on_dbl_colon && ch==':') {
+        if (++colons==2) {
+          EdCursorLeft(doc);
+          break;
+        }
+      } else {
+        colons=0;
+        if (ch=='{')
+          levels++;
+        else if (ch=='}' && !levels--)
+          break;
+      }
+      EdCursorRight(doc);
+    }
+    DocRecalc(doc);
+    if (doc->cur_entry!=doc)
+      res=TRUE;
+  } else {
+    while (EdFindPaired(doc,'}','{',FALSE,abort_on_dbl_colon));
+    if (doc->cur_entry!=doc) {
+      ch=EdCurU8(doc);
+      if (abort_on_dbl_colon && ch==':')
+        res=TRUE;
+      else {
+        if (ch=='{')
+          res=TRUE;
+      }
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public U0 EdSelFun(CDoc *doc,Bool abort_on_dbl_colon=FALSE)
+{//Set DOCET_SEL on all entries in cur fun.
+  Bool unlock=DocLock(doc);
+  U8 *ptr;
+  I64 ch,levels=0,colons=0;
+  CDocEntry *doc_e;
+  EdSelAll(doc,FALSE);
+  EdGoToFun(doc,FALSE,abort_on_dbl_colon);
+  if (EdCurU8(doc)=='{')
+    levels--;
+  else if (abort_on_dbl_colon && EdCurU8(doc)==':') {
+    EdCursorRight(doc);
+    if (EdCurU8(doc)==':')
+      EdCursorRight(doc);
+  }
+  doc_e=doc->cur_entry;
+  while (doc_e!=doc) {
+    doc_e->type|=DOCET_SEL;
+    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
+      ptr=doc_e->tag;
+      if (doc_e==doc->cur_entry)
+        ptr+=doc->cur_col;
+      while (ch=*ptr++)
+        if (abort_on_dbl_colon && ch==':') {
+          if (++colons==2)
+            goto sf_done;
+        } else {
+          colons=0;
+          if (ch=='{')
+            levels++;
+          else if (ch=='}' && !levels--)
+            goto sf_done;
+        }
+    }
+    doc_e=doc_e->next;
+  }
+sf_done:
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+#define RSAC_REPLACE    0
+#define RSAC_SKIP       1
+#define RSAC_ALL        2
+
+I64 PopUpReplaceSkipAllCancel(U8 *header=NULL,U8 *footer=NULL)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"$CM+LX,1,4$$BT,\"REPLACE\",LE=RSAC_REPLACE$"
+        "$CM+LX,17,0$$BT,\"SKIP\",LE=RSAC_SKIP$"
+        "$CM+LX,1,3$$BT,\"ALL\",LE=RSAC_ALL$"
+        "$CM+LX,17,0$$BT,\"CANCEL\",LE=DOCM_CANCEL$\n");
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 EdFindReplace(CDoc *doc)
+{
+  Bool found,unlock;
+  I64 cmd,i,j,plen,rlen,dlen,res=-1,sf_flags;
+  U8 *src,*dst,*dst2;
+  CDocEntry *doc_ce,*doc_e,*doc_marker=NULL;
+  if (doc->find_replace->pmt)
+    cmd=RSAC_REPLACE;
+  else
+    cmd=RSAC_ALL;
+  if (!doc->find_replace->pmt || DocForm(doc->find_replace)) {
+    res=0;
+    unlock=DocLock(doc);
+    if (doc->find_replace->match_case || doc->find_replace->local_var)
+      sf_flags=0;
+    else
+      sf_flags=SFF_IGNORE_CASE;
+    if (doc->find_replace->whole_labels || doc->find_replace->local_var)
+      sf_flags|=SFG_WHOLE_LABELS;
+
+    if (i=doc->find_replace->filter_lines) {
+      doc_ce=doc->head.next;
+      while (doc_ce!=doc) {
+        if (doc_ce->de_flags&DOCEF_TAG && doc_ce->tag &&
+              !(doc_ce->de_flags&DOCEF_FILTER_SKIP) &&
+              StrFind(doc->find_replace->find_text,doc_ce->tag,sf_flags)) {
+          doc_ce->type|=DOCET_SEL;
+          res++;
+        } else
+          doc_ce->type&=~DOCET_SEL;
+        doc_ce=doc_ce->next;
+      }
+
+      doc_ce=doc->head.next;
+      while (doc_ce!=doc) {
+        if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP)) {
+          found=FALSE;
+
+          doc_e=doc_ce;
+          while (doc_e!=doc && doc_e->y>doc_ce->y-i) {
+            if (doc_e->type&DOCET_SEL) {
+              found=TRUE;
+              break;
+            } else
+              doc_e=doc_e->last;
+          }
+
+          if (!found) {
+            doc_e=doc_ce;
+            while (doc_e!=doc && doc_e->y<doc_ce->y+i) {
+              if (doc_e->type&DOCET_SEL) {
+                found=TRUE;
+                break;
+              } else
+                doc_e=doc_e->next;
+            }
+          }
+
+          if (!found)
+            doc_ce->de_flags|=DOCEF_FILTER_SKIP;
+        }
+
+        doc_ce=doc_ce->next;
+      }
+      EdSelAll(doc,FALSE);
+      goto fr_unlock_done;
+    }
+
+    if (doc->find_replace->local_var)
+      EdSelFun(doc);
+
+    if (!doc->find_replace->replace && !doc->find_replace->local_var) {
+      EdFindNext(doc);
+      goto fr_unlock_done;
+    }
+    plen=StrLen(doc->find_replace->find_text);
+    if (!plen)
+      goto fr_unlock_done;
+    rlen=StrLen(doc->find_replace->replace_text);
+    if (doc->head.next!=doc) {
+      doc_e=doc_marker=DocSplitTag(doc,doc->cur_entry,doc->cur_col,
+            doc->cur_entry->x+doc->cur_col,doc->cur_entry->y,DOCT_MARKER);
+      do {
+        if (doc_e==doc) {
+          if (doc->find_replace->scan_fwd)
+            doc_e=doc_e->next;
+          else
+            doc_e=doc_e->last;
+          if (doc_e==doc_marker)
+            break;
+        }
+        if (doc_e->type_u8==DOCT_TEXT &&
+              !(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP)) &&
+              (doc_e->type & DOCET_SEL ||
+              !doc->find_replace->scan_sel_text&&
+              !doc->find_replace->local_var)) {
+          src=doc_e->tag;
+          while (src) {
+            src=StrFind(doc->find_replace->find_text,src,sf_flags);
+            if (src) {
+              doc->cur_col=src-doc_e->tag;
+              doc->cur_entry=doc_e;
+              if (cmd!=RSAC_ALL)
+                DocCenter(doc);
+              if (cmd!=RSAC_ALL) {
+                DocUnlock(doc);
+                cmd=PopUpReplaceSkipAllCancel("");
+                DocLock(doc);
+                if (cmd<0)
+                  goto fr_unlock_done;
+              }
+              doc_e=doc->cur_entry;
+              src=doc->cur_col+doc_e->tag;
+              if (cmd==RSAC_REPLACE || cmd==RSAC_ALL) {
+                dlen=StrLen(doc_e->tag);
+                doc_e->max_col=dlen+rlen-plen;
+                dst=MAlloc(doc_e->max_col+1,doc->mem_task);
+                dst2=dst;
+                j=src-doc_e->tag;
+                for (i=0;i<j;i++)
+                  *dst++=doc_e->tag[i];
+                for (i=0;i<rlen;i++)
+                  *dst++=doc->find_replace->replace_text[i];
+                src=dst;
+                for (i=j+plen;i<=dlen;i++)
+                  *dst++=doc_e->tag[i];
+                Free(doc_e->tag);
+                doc_e->tag=dst2;
+                doc->cur_col=src-doc_e->tag;
+                doc->cur_entry=doc_e;
+                if (cmd!=RSAC_ALL) {
+                  DocRemSoftNewLines(doc,doc->cur_entry);
+                  DocRecalc(doc);
+                }
+                doc_e=doc->cur_entry;
+                src=doc->cur_col+doc_e->tag;
+                res++;
+              } else
+                src++;
+            }
+          }
+        }
+        if (doc->find_replace->scan_fwd)
+          doc_e=doc_e->next;
+        else
+          doc_e=doc_e->last;
+      } while (doc_e!=doc_marker);
+    }
+fr_unlock_done:
+    if (doc_marker)
+      DocEntryDel(doc,doc_marker);
+    DocRemSoftNewLines(doc,NULL);
+    DocRecalc(doc);
+    DocCenter(doc);
+    if (unlock)
+      DocUnlock(doc);
+  }
+  return res;
+}
+
+public I64 EdReplace(CDoc *doc,U8 *find,U8 *replace,
+Bool sel=TRUE,Bool match_case=TRUE,Bool whole_labels=FALSE)
+{//Find & replace using editor's cmd.
+  CEdFindText old_find_replace;
+  Bool unlock;
+  I64 i,res=-1;
+  if (!doc) return -1;
+  unlock=DocLock(doc);
+  MemCpy(&old_find_replace,doc->find_replace,sizeof(CEdFindText));
+  MemSet(doc->find_replace,0,sizeof(CEdFindText));
+  i=StrLen(find);
+  if (i<sizeof(CEdFindText.find_text)) {
+    MemCpy(doc->find_replace->find_text,find,i+1);
+    i=StrLen(replace);
+    if (i<sizeof(CEdFindText.replace_text)) {
+      MemCpy(doc->find_replace->replace_text,replace,i+1);
+      doc->find_replace->replace=TRUE;
+      doc->find_replace->scan_sel_text=sel;
+      doc->find_replace->match_case=match_case;
+      doc->find_replace->whole_labels=whole_labels;
+      doc->find_replace->pmt=FALSE;
+      res=EdFindReplace(doc);
+    }
+  }
+  MemCpy(doc->find_replace,&old_find_replace,sizeof(CEdFindText));
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+class CEdLineGoTo
+{
+  I64 line format "$DA,A=\"Go to Line:%d\"$";
+};
+
+U0 EdGoToLine(CDoc *doc)
+{//Prompt with form and go to line num.
+  CEdLineGoTo gtl;
+  gtl.line=1;
+  if (DocForm(&gtl))
+    DocGoToLine(doc,gtl.line);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocForm.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocForm.HC.HTML new file mode 100755 index 0000000..4833647 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocForm.HC.HTML @@ -0,0 +1,375 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Form"
+
+U0 DocFormFwd(CDoc *doc,Bool giveup=FALSE)
+{
+  CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
+  if (doc->flags & DOCF_FORM) {
+    if (doc_e==doc) goto ff_recover;
+    while (!Bt(doldoc.type_flags_form,doc_e->type_u8) &&
+          !(doc_e->de_flags&DOCEF_LINK) ||
+          doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
+      doc_e=doc_e->next;
+      if (doc_e==doc) {
+ff_recover:
+        doc->cur_col=0;
+        if (!giveup) {
+          doc->cur_entry=doc_e->last;
+          DocFormBwd(doc,TRUE);
+        } else
+          doc->cur_entry=doc;
+        return;
+      }
+    }
+  }
+  while (doc_e->type_u8==DOCT_INDENT)
+    doc_e=doc_e->next;
+  if (doc_e!=doc_e2) {
+    doc->cur_col=doc_e->min_col;
+    doc->cur_entry=doc_e;
+  }
+}
+
+U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE)
+{
+  CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
+  if (doc->flags & DOCF_FORM) {
+    while (!Bt(doldoc.type_flags_form,doc_e->type_u8) &&
+          !(doc_e->de_flags&DOCEF_LINK) ||
+          doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
+      doc_e=doc_e->last;
+      if (doc_e==doc) {
+        doc->cur_col=0;
+        if (!giveup) {
+          doc->cur_entry=doc_e->next;
+          DocFormFwd(doc,TRUE);
+        } else
+          doc->cur_entry=doc;
+        return;
+      }
+    }
+  }
+  while (doc_e->type_u8==DOCT_INDENT)
+    doc_e=doc_e->next;
+  if (doc_e!=doc_e2) {
+    doc->cur_col=doc_e->min_col;
+    doc->cur_entry=doc_e;
+  }
+}
+
+U0 DocDataFmt(CDoc *doc,CDocEntry *doc_e,I64 d=DOCM_CANCEL)
+{
+  I64 i;
+  U8 *ptr,*ptr2;
+  CHashDefineStr *tmph;
+  if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
+        doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
+    if (d==DOCM_CANCEL) {
+      if (doc_e->de_flags&DOCEF_DEREF_DATA &&
+            !(doc_e->de_flags&DOCEF_REMALLOC_DATA)) {
+        if (!(ptr=doc_e->data)) return;
+      } else
+        ptr=&doc_e->data;
+      switch (doc_e->raw_type) {
+        case RT_I0:
+        case RT_U0:     d=0;            break;
+        case RT_I8:     d=*ptr(I8 *);   break;
+        case RT_U8:     d=*ptr(U8 *);   break;
+        case RT_I16:    d=*ptr(I16 *);  break;
+        case RT_U16:    d=*ptr(U16 *);  break;
+        case RT_I32:    d=*ptr(I32 *);  break;
+        case RT_U32:    d=*ptr(U32 *);  break;
+        default:        d=*ptr(I64 *);
+      }
+    }
+    if (doc_e->type_u8==DOCT_DATA) {
+      if (doc_e->de_flags & DOCEF_REMALLOC_DATA) {
+        ptr=MStrPrint(doc_e->aux_str,d,doc_e->my_fmt_data);
+        i=StrLen(ptr);
+        if (!doc_e->data) {
+          doc_e->data=CAlloc(2,doc->mem_task);
+          doc_e->len=MSize(doc_e->data)-2;
+        }
+        if (doc_e->len+doc_e->min_col>i)
+          MemCpy(doc_e->tag,ptr,i+1);
+        else {
+          ptr2=MAlloc(i+8,doc->mem_task);
+          doc_e->len=MSize(ptr2)-doc_e->min_col-2;       //See DataTagWidth
+          MemCpy(ptr2,ptr,i+1);
+          Free(doc_e->tag);
+          doc_e->tag=ptr2;
+        }
+        Free(ptr);
+      } else {
+        StrPrint(doc_e->tag,doc_e->aux_str,d,doc_e->my_fmt_data);
+        i=StrLen(doc_e->tag);
+      }
+      if (doc_e->de_flags & DOCEF_HAS_TERMINATOR) {
+        doc_e->tag[i++]='_';
+        doc_e->tag[i]=0;
+      }
+      doc_e->max_col=i;
+    } else if (doc_e->de_flags & DOCEF_LST) {
+      if (doc_e->de_flags & DOCEF_DEFINE && (tmph=HashFind(doc_e->define_str,
+            doc->win_task->hash_table,HTT_DEFINE_STR)) && 0<=d<tmph->cnt) {
+        ptr=MStrPrint("[%s]",tmph->sub_idx[d]);
+        Free(doc_e->tag);
+        doc_e->tag=StrNew(ptr,doc->mem_task);
+        Free(ptr);
+      } else {
+        Free(doc_e->tag);
+        doc_e->tag=StrNew("[]",doc->mem_task);
+      }
+    } else {
+      if (d)
+        doc_e->de_flags|=DOCEF_CHECKED_COLLAPSED;
+      else
+        doc_e->de_flags&=~DOCEF_CHECKED_COLLAPSED;
+    }
+  }
+}
+
+U0 DocDataScan(CDoc *doc,CDocEntry *doc_e)
+{
+  I64 i,d;
+  U8 *ptr,*ptr1,*ptr2;
+  CHashDefineStr *tmph;
+  if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
+        doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
+    if (doc_e->de_flags&DOCEF_DEREF_DATA &&
+          !(doc_e->de_flags&DOCEF_REMALLOC_DATA)) {
+      if (!(ptr=doc_e->data)) return;
+    } else
+      ptr=&doc_e->data;
+    if (doc_e->type_u8==DOCT_DATA) {
+      i=StrLen(doc_e->tag);
+      if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
+        doc_e->tag[--i]=0;
+      if (i>doc_e->len+doc_e->min_col)
+        doc_e->tag[doc_e->len+doc_e->min_col]=0;
+      if (RT_I8<=doc_e->raw_type<=RT_U32) {
+        StrScan(doc_e->tag,doc_e->aux_str,&d,doc_e->my_fmt_data);
+        if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
+          doc_e->tag[i]='_';
+      } else if (RT_I64<=doc_e->raw_type<=RT_UF64) {
+        if (doc_e->de_flags & DOCEF_REMALLOC_DATA) {
+          ptr=MAlloc(i-doc_e->min_col+8,doc->mem_task);
+          MemCpy(ptr,doc_e->tag+doc_e->min_col,i-doc_e->min_col+1);
+          Free(doc_e->data);
+          doc_e->data=ptr;
+          doc_e->len=MSize(ptr)-1;
+        } else
+          StrScan(doc_e->tag,doc_e->aux_str,ptr,doc_e->my_fmt_data);
+        if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
+          doc_e->tag[i]='_';
+        return;
+      }
+    } else if (doc_e->de_flags & DOCEF_LST) {
+      d=0;
+      if (doc_e->tag && doc_e->de_flags & DOCEF_DEFINE &&
+            (tmph=HashFind(doc_e->define_str,
+            doc->win_task->hash_table,HTT_DEFINE_STR))) {
+        ptr1=ptr2=StrNew(doc_e->tag);
+        if (*ptr2=='[') {
+          ptr2++;
+          i=StrLen(ptr2);
+          if (ptr2[i-1]==']')
+            ptr2[i-1]=0;
+        }
+        d=LstMatch(ptr2,tmph->data);
+        Free(ptr1);
+      }
+    } else {
+      if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+        d=TRUE;
+      else
+        d=FALSE;
+    }
+    switch (doc_e->raw_type) {
+      case RT_I8:
+      case RT_U8:
+        *ptr(U8 *)=d;
+      case RT_I0:
+      case RT_U0:
+        break;
+      case RT_I16:
+      case RT_U16:
+        *ptr(U16 *)=d;
+        break;
+      case RT_I32:
+      case RT_U32:
+        *ptr(U32 *)=d;
+        break;
+      default:
+        *ptr(I64 *)=d;
+    }
+  }
+}
+
+#help_index "DolDoc/Input;StdIn/DolDoc"
+public Bool DocForm(U8 *_d,U8 *class_name=lastclass,
+    I64 dof_flags=0,U8 *header=NULL,U8 *footer=NULL)
+{//User input. Supply a class name that has format definitions.
+//See ::/Demo/DolDoc/Form.HC and ::/Demo/LastClass.HC.
+  CMemberLst *ml;
+  CDocEntry *doc_e;
+  U8 *format;
+  CHashClass *tmpc,*tmpc2;
+  CDoc *doc;
+  Bool res=FALSE;
+  I64 old_border_src=Fs->border_src,has_action;
+  if (!(tmpc=HashFind(class_name,Fs->hash_table,HTT_CLASS)))
+    return FALSE;
+  doc=DocNew;
+  doc->desc='Form';
+  if (header) DocPrint(doc,"%s",header);
+  doc->flags|=DOCF_OVERSTRIKE|DOCF_FORM;
+  if (dof_flags&DOF_SIZE_MIN)
+    doc->flags|=DOCF_SIZE_MIN;
+  ml=tmpc->member_lst_and_root;
+  while (ml) {
+    if ((format=MemberMetaData("format",ml)) &&
+          (doc_e=DocPrint(doc,"%s",format))) {
+      tmpc2=ml->member_class;
+      if ((doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_LST ||
+            doc_e->type_u8==DOCT_CHECK_BOX) && !tmpc2->ptr_stars_cnt) {
+        tmpc2=OptClassFwd(tmpc2);
+        tmpc2-=tmpc2->ptr_stars_cnt;
+        if (tmpc2->type & HTT_INTERNAL_TYPE) {
+          if (ml->dim.next) { //Array
+            if (tmpc2->raw_type==RT_U8 &&
+                  LBtr(&doc_e->de_flags,&DOCEf_DFT_LEN)) {
+              doc_e->len=ml->dim.total_cnt;
+              if (doc_e->de_flags&DOCEF_HAS_TERMINATOR)
+                doc_e->len--;
+              Free(doc_e->tag);  //See DataTagWidth
+              doc_e->tag=MAlloc(doc_e->len+doc_e->min_col+2,
+                    doc->mem_task); //+2 because "_\0"
+            }
+          } else if (LBtr(&doc_e->de_flags,DOCEf_DFT_RAW_TYPE))
+            doc_e->raw_type=tmpc2->raw_type;
+        }
+      }
+      if (doc_e->de_flags&DOCEF_REMALLOC_DATA) {
+        doc_e->user_data=_d+ml->offset;
+        doc_e->data=*doc_e->user_data(U8 **);
+      } else
+        doc_e->data=_d+ml->offset;
+      doc_e->my_fmt_data=MemberMetaData("data",ml);
+      DocDataFmt(doc,doc_e);
+    }
+    ml=ml->next;
+  }
+  if (footer) DocPrint(doc,"%s",footer);
+  if (doc->head.next!=doc)      {
+    Fs->border_src=BDS_CONST;
+    DocRecalc(doc);
+    if (DocEd(doc,dof_flags)) {
+      doc_e=doc->cur_entry;
+      res=TRUE;
+      if (doc_e!=doc) {
+        if (DocEntryRun(doc,doc_e,TRUE,&has_action)==DOCM_CANCEL && has_action)
+          res=FALSE;
+        DocUnlock(doc);
+      }
+    }
+  }
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->de_flags&DOCEF_REMALLOC_DATA) {
+      *doc_e->user_data(U8 **)=doc_e->data;
+      doc_e->data=NULL;
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+  Fs->border_src=old_border_src;
+  return res;
+}
+
+U0 DocMenuEndTaskCB()
+{
+  WinToTop;
+  throw;
+}
+
+public I64 DocMenu(CDoc *m,I64 dof_flags=0)
+{//Run menu chooser doc. Returns menu doc unlocked.
+  U8 *old_end_cb=Fs->task_end_cb;
+  Bool old_break_shift_esc=LBts(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC);
+  CDocEntry *doc_e;
+  I64 old_border_src=Fs->border_src,res=DOCM_CANCEL,has_action;
+  Fs->task_end_cb=&DocMenuEndTaskCB;
+  try {
+    if (m) {
+      m->desc='Menu';
+      Fs->border_src=BDS_CONST;
+dm_restart:
+      if (DocEd(m,dof_flags)) {
+        doc_e=m->cur_entry;
+        if (doc_e!=m) {
+          res=DocEntryRun(m,doc_e,TRUE,&has_action);
+          DocUnlock(m);
+          if (!has_action) {
+            res=DOCM_CANCEL;
+            dof_flags|=DOF_DONT_HOME;
+            goto dm_restart;
+          }
+        }
+      }
+    }
+  } catch {
+    if (!Fs->except_ch) {
+      if (!(dof_flags & DOF_INTERCEPT_TASK_END))
+        Exit;
+      Fs->catch_except=TRUE;
+    }
+  }
+  LBEqu(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC,old_break_shift_esc);
+  Fs->border_src=old_border_src;
+  Fs->task_end_cb=old_end_cb;
+  return res;
+}
+
+public I64 PopUpMenu(CDoc *doc,I64 dof_flags=0)
+{//Run menu chooser doc in PopUp win task.
+  doc->flags|=DOCF_SIZE_MIN | DOCF_FORM;
+  return PopUpPrint("DocMenu(0x%X,0x%X);",doc,dof_flags);
+}
+
+public Bool PopUpForm(U8 *_d,U8 *class_name=lastclass,
+        I64 dof_flags=DOF_SIZE_MIN,U8 *header=NULL,U8 *footer=NULL)
+{//See ::/Demo/DolDoc/Form.HC and ::/Demo/LastClass.HC.
+  return PopUpPrint("DocForm(0x%X,0x%X,0x%X,0x%X,0x%X);",_d,class_name,
+        dof_flags,header,footer);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocGet.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocGet.HC.HTML new file mode 100755 index 0000000..0ed7ea4 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocGet.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+U0 EdUndoFilter(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->head.next;
+  while (doc_ce!=doc) {
+    doc_ce->de_flags&=~DOCEF_FILTER_SKIP;
+    doc_ce=doc_ce->next;
+  }
+  doc->find_replace->filter_lines=0;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public I64 DocGetKey(I64 *_sc=NULL)
+{//Called by View. You probably don't need this.
+  I64 ch,sc;
+  Bool cont,old_key_desc;
+  do {
+    old_key_desc=LBtr(&Fs->win_inhibit,WIf_SELF_KEY_DESC);
+    do ch=GetKey(&sc,TRUE);
+    while (sc&SCF_KEY_DESC);
+    LBEqu(&Fs->win_inhibit,WIf_SELF_KEY_DESC,old_key_desc);
+
+    DocRecalc(DocPut);
+    cont=FALSE;
+    if ((ch==CH_ESC || ch==CH_SHIFT_ESC) && //Check for exit filter mode
+          DocPut && DocPut->find_replace->filter_lines) {
+      EdUndoFilter(DocPut);
+      cont=TRUE;
+    }
+  } while (cont);
+  if (_sc) *_sc=sc;
+  return ch;
+}
+
+#help_index "DolDoc/Input;StdIn/DolDoc"
+public U8 *DocScanLine(CDoc *doc,CDocEntry *doc_e,
+        I64 *cur_col=NULL,CDocEntry **_do_e_end=NULL)
+{//Start at entry in doc,make and return one line as str.
+  CDocEntry *doc_e2=doc_e;
+  Bool unlock=DocLock(doc);
+  U8 *dst,*src,*start,*res;
+  I64 i=0;
+  if (cur_col)
+    *cur_col=-1;
+  while (doc_e2!=doc && doc_e2->type_u8!=DOCT_NEW_LINE) {
+    if (doc_e2->de_flags&DOCEF_TAG && doc_e2->tag) {
+      src=doc_e2->tag;
+      i+=StrLen(src);
+    } else if (doc_e2->type_u8==DOCT_TAB)
+      i++;
+    else if (doc_e2->type_u8==DOCT_SHIFTED_X ||
+          doc_e2->type_u8==DOCT_SHIFTED_Y) {
+      if (doc_e2->attr<0)
+        i++;
+      i+=6; //$SY,3$
+    }
+    doc_e2=doc_e2->next;
+  }
+  res=MAlloc(i+1);
+  dst=res;
+  while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
+    start=dst;
+    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
+      src=doc_e->tag;
+      while (*src)
+        *dst++=*src++;
+    } else if (doc_e->type_u8==DOCT_TAB)
+      *dst++='\t';
+    else if (doc_e->type_u8==DOCT_SHIFTED_Y) {
+      *dst(U32 *)++='$SY,';
+      if (doc_e->attr<0)
+        *dst++='-';
+      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
+      *dst++='$';
+    } else if (doc_e->type_u8==DOCT_SHIFTED_X) {
+      *dst(U32 *)++='$SX,';
+      if (doc_e->attr<0)
+        *dst++='-';
+      *dst++='0'+AbsI64(doc_e->attr); //Supposedly -7 to 7 (single digit)
+      *dst++='$';
+    }
+    if (doc_e==doc->cur_entry && cur_col)
+      *cur_col=start-res+doc->cur_col;
+    doc_e=doc_e->next;
+  }
+  if (_do_e_end) *_do_e_end=doc_e;
+  *dst=0;
+  if (doc_e==doc->cur_entry && cur_col && !doc->cur_col)
+    *cur_col=dst-res;
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+U8 *DocGetStr2(I64 flags=0)
+{//Flags
+  CDoc *doc;
+  CDocEntry *doc_e,*doc_e_end;
+  U8 *st,*st2,*res;
+  I64 ch,sc;
+  "$PT$";
+  do {
+    ch=DocGetKey(&sc);
+    if (ch==CH_ESC) {
+      if (doc=DocPut) {
+        DocLock(doc);
+        if (doc->doc_signature==DOC_SIGNATURE_VAL && doc->cur_entry!=doc) {
+          doc_e=DocEntryCopy(doc,doc->cur_entry);
+          DocBottom(doc);
+          DocEntryRun(doc,doc_e,TRUE);
+          DocEntryDel(doc,doc_e);
+        }
+        DocUnlock(doc);
+      }
+      if (flags&GSF_WITH_NEW_LINE)
+        break;
+    } if (ch==CH_SHIFT_ESC) {
+      if (flags&GSF_SHIFT_ESC_EXIT)
+        Exit;
+      else {
+        res=StrNew("");
+        goto gs_done;
+      }
+    }
+//<CTRL-SHIFT-ENTER> is a blank line without entry
+  } while (flags&GSF_WITH_NEW_LINE || ch!='\n' ||
+        sc&SCF_CTRL && sc&SCF_SHIFT);
+
+  doc=DocPut;
+  DocLock(doc);
+  if (flags&GSF_WITH_NEW_LINE) {
+    doc_e=doc->cur_entry;
+    do doc_e=doc_e->last;
+    while (doc_e!=doc && doc_e->type_u8!=DOCT_PMT);
+    doc_e=doc_e->next;
+    if (res=DocScanLine(doc,doc_e,NULL,&doc_e_end)) {
+      while (doc_e_end!=doc && doc_e_end->type_u8==DOCT_NEW_LINE) {
+        st2=MStrPrint("%s\n",res);
+        Free(res);
+        res=st2;
+        if (st=DocScanLine(doc,doc_e_end->next,NULL,&doc_e_end)) {
+          st2=MStrPrint("%s%s",res,st);
+          Free(st);
+          Free(res);
+          res=st2;
+        }
+      }
+    }
+  } else {
+    doc_e=doc->cur_entry;
+    do doc_e=doc_e->last;
+    while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
+          doc_e->type_u8!=DOCT_PMT);
+    if (doc_e!=doc && doc_e->type_u8!=DOCT_PMT) {
+      do doc_e=doc_e->last;
+      while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
+            doc_e->type_u8!=DOCT_PMT);
+    }
+    doc_e=doc_e->next;
+    res=DocScanLine(doc,doc_e,NULL);
+  }
+  DocUnlock(doc);
+gs_done:
+  "$PT$$FG$$BG$";
+  return res;
+}
+
+#help_index "Keyboard Devices;Char/Input;StdIn"
+public I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX)
+{//Prompt user for I64 expression.
+  Bool okay;
+  U8 *st;
+  I64 res;
+  while (TRUE) {
+    if (msg)
+      "" msg,dft;
+    st=GetStr;
+    if (!*st) {
+      Free(st);
+      return dft;
+    }
+    try {
+      res=ExePrint2("ToI64(%s);",st);
+      okay=TRUE;
+    } catch {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+    }
+    Free(st);
+    if (okay && lo<=res<=hi)
+      return res;
+  }
+}
+
+public F64 GetF64(U8 *msg=NULL,F64 dft=0,F64 lo=F64_MIN,F64 hi=F64_MAX)
+{//Prompt user for F64 expression.
+  Bool okay;
+  U8 *st;
+  F64 res;
+  while (TRUE) {
+    if (msg)
+      "" msg,dft;
+    st=GetStr;
+    if (!*st) {
+      Free(st);
+      return dft;
+    }
+    try {
+      res=ExePrint2("ToF64(%s);",st)(F64);
+      okay=TRUE;
+    } catch {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+    }
+    Free(st);
+    if (okay && lo<=res<=hi)
+      return res;
+  }
+}
+
+public CDate GetDate(U8 *msg=NULL,CDate dft=I64_MIN,
+        CDate lo=I64_MIN,CDate hi=I64_MAX)
+{//Prompt user for date expression. (Use Now() if you want current time.)
+  U8 *st;
+  CDate res;
+  if (dft==I64_MIN) dft=Now;
+  while (TRUE) {
+    if (msg)
+      "" msg,dft,dft;
+    st=GetStr;
+    if (!*st) {
+      Free(st);
+      return dft;
+    }
+    res=Str2Date(st);
+    Free(st);
+    if (res>=lo && res<=hi)
+      return res;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocGr.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocGr.HC.HTML new file mode 100755 index 0000000..d1f1744 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocGr.HC.HTML @@ -0,0 +1,194 @@ + + + + + + + + + + + +
+#help_index "Graphics/Input"
+
+public I64 PopUpColor(U8 *header=NULL,
+        Bool allow_transparent=TRUE,Bool allow_dft=TRUE)
+{//Chooser for 16-color, default or transparent.
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  if (allow_transparent)
+    DocPrint(doc,"$MU,\"TRANSPARENT\",LE=TRANSPARENT$\n");
+  for (i=0;i<COLORS_NUM;i++)
+    DocPrint(doc,"$BG,%d$$MU,\"__%-8Z__\",LE=%d$$BG$\n",i,i,"ST_COLORS",i);
+  if (allow_dft)
+    DocPrint(doc,"$BG,WHITE$$MU,\"DEFAULT\",LE=DOC_DFT$$BG$");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public I64 PopUpColorLighting(U8 *header=NULL)
+{//Chooser for std TempleOS DCLighting() color.
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"\nSingle-Sided means front and back different."
+        "\nDouble-Sided means front and back same."
+        "\n"
+        "\nHalf-Range means 0 to [0,7]"
+        "\n                 [8,15]-8 to [8,15]"
+        "\nFull-Range means 0 to [0,7] to [0,7]+8"
+        "\n");
+  DocPrint(doc,
+        "\n$LTPURPLE$Single-Sided Full-Range Double-Sided Full-Range\n$BLACK$");
+  for (i=0;i<COLORS_NUM/2;i++) {
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$ ",i,i,"ST_COLORS",i);
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$\n",i,i,"ST_COLORS",
+          ROPF_TWO_SIDED+i);
+  }
+  DocPrint(doc,
+        "\n$LTPURPLE$Single-Sided Half-Range Double-Sided Half-Range\n$BLACK$");
+  for (i=0;i<COLORS_NUM;i++) {
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$ ",
+          i,i,"ST_COLORS",ROPF_HALF_RANGE_COLOR+i);
+    DocPrint(doc,"$BG,%d$$MU,\"__%-19Z__\",LE=%d$$BG$\n",
+          i,i,"ST_COLORS",ROPF_TWO_SIDED+ROPF_HALF_RANGE_COLOR+i);
+  }
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CTransformForm
+{
+  F64 x_scale   format "$DA-TRM,A=\"X Scale :%12.6f\"$\n";
+  F64 y_scale   format "$DA-TRM,A=\"Y Scale :%12.6f\"$\n";
+  F64 z_scale   format "$DA-TRM,A=\"Z Scale :%12.6f\"$\n";
+  F64 theta_z   format "\nAngles are in degrees\n"
+                       "$DA-TRM,A=\"Z-Axis  :%12.6f\"$\n";
+  F64 theta_y   format "$DA-TRM,A=\"Y-Axis  :%12.6f\"$\n";
+  F64 theta_x   format "$DA-TRM,A=\"X-Axis  :%12.6f\"$\n";
+  F64 x_offset  format "\n$DA-TRM,A=\"X Offset:%12.6f\"$\n";
+  F64 y_offset  format "$DA-TRM,A=\"Y Offset:%12.6f\"$\n";
+  F64 z_offset  format "$DA-TRM,A=\"Z Offset:%12.6f\"$\n";
+};
+
+#help_index "Graphics/Input;Graphics/Math/3D Transformation"
+public Bool PopUpTransform(I64 *r)
+{//Prompt for Mat4x4 transform.
+  CTransformForm *tf=MAlloc(sizeof(CTransformForm));
+  tf->x_scale=1.0;
+  tf->y_scale=1.0;
+  tf->z_scale=1.0;
+  tf->theta_x=0.0;
+  tf->theta_y=0.0;
+  tf->theta_z=0.0;
+  tf->x_offset=0.0;
+  tf->y_offset=0.0;
+  tf->z_offset=0.0;
+  if (PopUpForm(tf)) {
+    MemSet(r,0,16*sizeof(I64));
+    r[0] =tf->x_scale*GR_SCALE;
+    r[5] =tf->y_scale*GR_SCALE;
+    r[10]=tf->z_scale*GR_SCALE;
+    r[15]=GR_SCALE;
+
+    Mat4x4RotZ(r,tf->theta_z*pi/180.0);
+    Mat4x4RotY(r,tf->theta_y*pi/180.0);
+    Mat4x4RotX(r,tf->theta_x*pi/180.0);
+
+    r[3] =tf->x_offset*GR_SCALE;
+    r[7] =tf->y_offset*GR_SCALE;
+    r[11]=tf->z_offset*GR_SCALE;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+#help_index "Graphics/Input"
+#define PU_SPACING      10
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,i1,j1;
+  CDoc *doc=DocPut(task);
+  for (j=0;j<17;j++)
+    for (i=0;i<17;i++) {
+      if (j<16)
+        j1=j;
+      else
+        j1=TRANSPARENT;
+      if (i<16)
+        i1=i;
+      else
+        i1=TRANSPARENT;
+      dc->color=j1+i1<<16+ROPF_DITHER;
+      GrRect(dc,i*PU_SPACING,j*PU_SPACING+FramePtr("DitherFrame",task),
+            PU_SPACING,PU_SPACING);
+    }
+  i=(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH;
+  if (doc->max_x>i) i=doc->max_x;
+  WinHorz(task->win_left,task->win_left+i,task);
+  WinVert(task->win_top,task->win_top+doc->max_y+
+        (17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH,task);
+}
+
+I64 DitherColor2(U8 *header=NULL)
+{
+  I64 msg_code,arg1,arg2,res=-1,i,j;
+  DocClear;
+  "%s",header;
+  DocRecalc(DocPut);
+  FramePtrAdd("DitherFrame",(DocPut->max_y+1)*FONT_HEIGHT);
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_KEY_DOWN);
+    if (msg_code==MSG_MS_L_DOWN) {
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP);
+      i=arg1/PU_SPACING;
+      j=(arg2-FramePtr("DitherFrame"))/PU_SPACING;
+      if (arg1>=0 && arg2>=0 && 0<=j<17 && 0<=i<17) {
+        if (j==16) j=TRANSPARENT;
+        if (i==16) i=TRANSPARENT;
+        res=j+i<<16+ROPF_DITHER;
+        goto dc_done;
+      }
+    }
+  } while (!(msg_code==MSG_KEY_DOWN && (arg1==CH_ESC || arg1==CH_SHIFT_ESC)));
+  do GetMsg(&arg1,&arg2,1<<MSG_KEY_UP);
+  while (!arg1);
+dc_done:
+  SettingsPop;
+  FramePtrDel("DitherFrame");
+  return res;
+}
+
+public I64 PopUpColorDither(U8 *header=NULL)
+{//Chooser for 2 x 16 colors or transparent.
+  U8 buf[STR_LEN];
+  StrPrint(buf,"DitherColor2(0x%X);",header);
+  return PopUp(buf,Fs);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocHighlight.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocHighlight.HC.HTML new file mode 100755 index 0000000..08e5714 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocHighlight.HC.HTML @@ -0,0 +1,191 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+CColorROPU32 highlight_hash_type_colors[HTt_TYPES_NUM]=
+        DOC_COLOR_EXPORT_SYS_SYM,0,DOC_COLOR_DEFINE_STR,DOC_COLOR_GLBL_VAR,
+        DOC_COLOR_CLASS,DOC_COLOR_KEYWORD,DOC_COLOR_FUN,0,0,DOC_COLOR_KEYWORD,
+        DOC_COLOR_KEYWORD,DOC_COLOR_KEYWORD,DOC_COLOR_REG,0,0,0,0};
+
+U32 *DocHighlight(CDocEntry *doc_e,U8 *src,I64 len,I64 _tmp_u32_attr)
+{//Be aware of ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+  U32 *res=MAlloc((len+1)*sizeof(U32)),*dst=res;
+  U8 *ptr;
+  CDocSettings *s=&doc_e->settings;
+  I64 ch,ch1,last_ch,tmp_u32_attr,mask_tmp_u32_attr=_tmp_u32_attr&0xFFFFF000,
+        comment_depth,brace_depth=s->brace_depth,paren_depth=s->paren_depth;
+  CHash *tmph;
+  switch [s->state] {
+    case DOCSS_NORMAL:
+hl_normal:
+      while (len) {
+        while (len && !Bt(char_bmp_alpha_numeric,*src)) {
+          tmp_u32_attr=_tmp_u32_attr;
+          ch1=*src++;
+          switch (ch1) {
+            case '/':
+              if (len>=2) {
+                if (*src=='/') {
+                  tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+                  *dst++=ch1+tmp_u32_attr;
+                  *dst++=*src++ +tmp_u32_attr;
+                  len-=2;
+                  goto hl_cpp_comment;
+                } else if (*src=='*') {
+                  tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+                  *dst++=ch1+tmp_u32_attr;
+                  *dst++=*src++ +tmp_u32_attr;
+                  len-=2;
+                  comment_depth=1;
+                  goto hl_comment;
+                }
+              }
+              break;
+            case '\'':
+              tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
+              *dst++=ch1+tmp_u32_attr;
+              len--;
+              goto hl_single_quote;
+            case '\"':
+              tmp_u32_attr=DOC_COLOR_STR<<8|mask_tmp_u32_attr;
+              *dst++=ch1+tmp_u32_attr;
+              len--;
+              goto hl_dbl_quote;
+            case '(':
+              if (paren_depth++&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+            case ')':
+              if (--paren_depth&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+            case '{':
+              if (brace_depth++&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+            case '}':
+              if (--brace_depth&1)
+                tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
+              break;
+          }
+          *dst++=ch1+tmp_u32_attr;
+          if (!--len) goto hl_normal_done;
+        }
+        ptr=src;
+        while (len && Bt(char_bmp_alpha_numeric,*src)) {
+          src++;
+          len--;
+        }
+        ch=*src;
+        *src=0;
+        if (tmph=HashFind(ptr,adam_task->hash_table,
+              HTT_EXPORT_SYS_SYM|HTT_DEFINE_STR|HTT_GLBL_VAR|HTT_CLASS|
+              HTT_INTERNAL_TYPE|HTT_FUN|HTT_KEYWORD|HTT_ASM_KEYWORD|
+              HTT_OPCODE|HTT_REG))
+          tmp_u32_attr=highlight_hash_type_colors[HashTypeNum(tmph)]<<8|
+                mask_tmp_u32_attr;
+        else
+          tmp_u32_attr=_tmp_u32_attr;
+        while (ch1=*ptr++)
+          *dst++=ch1+tmp_u32_attr;
+        *src=ch;
+      }
+hl_normal_done:
+      s->state=DOCSS_NORMAL;
+      s->comment_depth=0;
+      break;
+    case DOCSS_SINGLE_QUOTE:
+      tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
+hl_single_quote:
+      last_ch=0;
+      while (len--) {
+        ch1=*src++;
+        *dst++=ch1+tmp_u32_attr;
+        if (last_ch!='\\' && ch1=='\'')
+          goto hl_normal;
+        if (last_ch=='\\' && ch1=='\\')
+          last_ch=0;
+        else
+          last_ch=ch1;
+      }
+      s->state=DOCSS_SINGLE_QUOTE;
+      s->comment_depth=0;
+      break;
+    case DOCSS_DBL_QUOTE:
+      tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
+hl_dbl_quote:
+      last_ch=0;
+      while (len--) {
+        ch1=*src++;
+        *dst++=ch1+tmp_u32_attr;
+        if (last_ch!='\\' && ch1=='\"')
+          goto hl_normal;
+        if (last_ch=='\\' && ch1=='\\')
+          last_ch=0;
+        else
+          last_ch=ch1;
+      }
+      s->state=DOCSS_DBL_QUOTE;
+      s->comment_depth=0;
+      break;
+    case DOCSS_COMMENT:
+      tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+      comment_depth=s->comment_depth;
+hl_comment:
+      last_ch=0;
+      while (len--) {
+        ch1=*src++;
+        *dst++=ch1+tmp_u32_attr;
+        if (last_ch=='*' && ch1=='/') {
+          if (!--comment_depth)
+            goto hl_normal;
+        } else if (last_ch=='/' && ch1=='*')
+          comment_depth++;
+        last_ch=ch1;
+      }
+      s->state=DOCSS_COMMENT;
+      s->comment_depth=comment_depth;
+      break;
+    case DOCSS_CPP_Z_COMMENT:
+      tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
+hl_cpp_comment:
+      while (len--)
+        *dst++=*src++ +tmp_u32_attr;
+      s->state=DOCSS_CPP_Z_COMMENT;
+      s->comment_depth=0;
+      break;
+  }
+  s->paren_depth=paren_depth;
+  s->brace_depth=brace_depth;
+  *dst=0;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocInit.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocInit.HC.HTML new file mode 100755 index 0000000..3e23b4a --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocInit.HC.HTML @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+U0 DocInit()
+{//CMD Defines
+  CCmpCtrl *cc;
+  I64 i;
+  CHashGeneric *tmph;
+
+  DefineLstLoad("ST_DOC_CMDS",
+        "TX\0CR\0SR\0TB\0PB\0CU\0MK\0PT\0CL\0PL\0LM\0RM\0HD\0FO\0ID\0FG\0"
+        "BG\0FD\0BD\0WW\0HL\0BK\0IV\0UL\0SX\0SY\0CM\0AN\0LK\0BT\0"
+        "DA\0CB\0LS\0MA\0MU\0HX\0TR\0SP\0IB\0IS\0SO\0HC\0ER\0");
+  DefineLstLoad("ST_DOC_FLAGS",
+        "T\0LEN\0A\0D\0HTML\0LE\0LM\0RE\0RM\0BI\0BP\0RT\0SX\0SY\0SCX\0U\0"
+        "LC\0LIS\0RC\0RIS\0LX\0CX\0RX\0TY\0CY\0BY\0"
+        "HL\0WW\0BK\0IV\0SEL\0UL\0"
+        "TC\0PRY\0MRX\0WR\0L\0X\0Q\0FST\0B\0S\0BD\0C\0CA\0RD\0UD\0P\0M\0"
+        "TRM\0Z\0H\0TR\0LS\0SK\0PU\0SIF\0FS\0NC\0DD\0DL\0DRT\0");
+  DefineLstLoad("ST_LINK_TYPES",
+        "FI\0FA\0FF\0FL\0MN\0PI\0PF\0PL\0BF\0DN\0HI\0AD\0AI\0AA\0AF\0AL\0");
+
+  doldoc.hash=HashTableNew(512);
+  HashDefineLstAdd("ST_DOC_CMDS",DHT_DOC_CMD,doldoc.hash);
+  HashDefineLstAdd("ST_DOC_FLAGS",DHT_DOC_FLAG,doldoc.hash);
+  HashDefineLstAdd("ST_COLORS",DHT_COLOR,doldoc.hash);
+
+  MemSet(doldoc.dft_de_flags,   0,sizeof(doldoc.dft_de_flags));
+  MemSet(doldoc.dft_type_flags, 0,sizeof(doldoc.dft_type_flags));
+  cc=CmpCtrlNew("TX+T;DA+P+TRM+T+DL+DRT;CM+LE+RE;AN+T;LK+L+UL+T;MA+X+UL+T;"
+        "MU+X+UL+T;BT+X+B+T;CB+CA+P+T+DRT;LS+LS+P+T+DRT;HX+P+Z;TR+TR+C+CA+UL+T;"
+        "SP+T;IB+T;IS+T;SO+T;HC+T;",CCF_DONT_FREE_BUF);
+  cc->htc.hash_table_lst=NULL;
+  Lex(cc);
+  while (cc->token==TK_IDENT) {
+    if (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_CMD)) {
+      i=tmph->user_data0;
+      Lex(cc);
+      PrsDocFlags(cc,&doldoc.dft_de_flags[i],&doldoc.dft_type_flags[i]);
+    }
+    if (cc->token==';')
+      Lex(cc);
+  }
+  CmpCtrlDel(cc);
+
+  for (i=0;i<DOCT_TYPES_NUM;i++)
+    doldoc.dft_de_flags[i]&=~DOCG_BL_IV_UL;
+
+  doldoc.type_flags_form[0]=0;
+  for (i=0;i<DOCT_TYPES_NUM;i++)
+    if (Bt(&doldoc.dft_de_flags[i],DOCEf_TAG) && i!=DOCT_TEXT || i==DOCT_HEX_ED)
+      Bts(doldoc.type_flags_form,i);
+
+      //Don't forget cmp_type_flags_src_code.
+  doldoc.type_flags_nontag_invis[0]=
+        1<<DOCT_PMT|
+        1<<DOCT_PAGE_LEN|
+        1<<DOCT_LEFT_MARGIN|
+        1<<DOCT_RIGHT_MARGIN|
+        1<<DOCT_HEADER|
+        1<<DOCT_FOOTER|
+        1<<DOCT_INDENT|
+        1<<DOCT_FOREGROUND|
+        1<<DOCT_BACKGROUND|
+        1<<DOCT_DFT_FOREGROUND|
+        1<<DOCT_DFT_BACKGROUND|
+        1<<DOCT_WORD_WRAP|
+        1<<DOCT_HIGHLIGHT|
+        1<<DOCT_BLINK|
+        1<<DOCT_INVERT|
+        1<<DOCT_UNDERLINE|
+        1<<DOCT_SHIFTED_X|
+        1<<DOCT_SHIFTED_Y|
+        1<<DOCT_SPRITE;
+
+  doldoc.type_flags_data[0]=1<<DOCT_DATA|1<<DOCT_HEX_ED|1<<DOCT_CHECK_BOX;
+
+  doldoc.type_flags_chk_dup[0]=
+        1<<DOCT_LEFT_MARGIN|
+        1<<DOCT_RIGHT_MARGIN|
+        1<<DOCT_HEADER|
+        1<<DOCT_FOOTER|
+        1<<DOCT_FOREGROUND|
+        1<<DOCT_BACKGROUND|
+        1<<DOCT_DFT_FOREGROUND|
+        1<<DOCT_DFT_BACKGROUND|
+        1<<DOCT_WORD_WRAP|
+        1<<DOCT_HIGHLIGHT|
+        1<<DOCT_BLINK|
+        1<<DOCT_INVERT|
+        1<<DOCT_UNDERLINE|
+        1<<DOCT_SHIFTED_X|
+        1<<DOCT_SHIFTED_Y;
+
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_RIGHT);
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_LEFT);
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_UP);
+  Bts(doldoc.clean_scan_codes,SC_CURSOR_DOWN);
+  Bts(doldoc.clean_scan_codes,SC_PAGE_UP);
+  Bts(doldoc.clean_scan_codes,SC_PAGE_DOWN);
+  Bts(doldoc.clean_scan_codes,SC_ALT);
+  Bts(doldoc.clean_scan_codes,SC_CTRL);
+  Bts(doldoc.clean_scan_codes,SC_SHIFT);
+  Bts(doldoc.clean_scan_codes,SC_CAPS);
+  Bts(doldoc.clean_scan_codes,SC_NUM);
+  Bts(doldoc.clean_scan_codes,SC_SCROLL);
+  Bts(doldoc.clean_scan_codes,SC_HOME);
+  Bts(doldoc.clean_scan_codes,SC_END);
+  Bts(doldoc.clean_scan_codes,SC_GUI);
+  Bts(doldoc.clean_scan_codes,SC_BACKSPACE); //Handled specially
+}
+
+DocInit;
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocLink.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocLink.HC.HTML new file mode 100755 index 0000000..14a9ee1 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocLink.HC.HTML @@ -0,0 +1,389 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Link"
+
+/* See TempleOS Link Types.
+"filename"
+"FI:filename"
+"FA:haystack_filename,needle_anchor_str"
+"FF:haystack_filename,needle_str"
+"FF:haystack_filename,needle_str:occurnum"
+"FL:filename,linenum"
+"MN:SymName"
+"PI:filename"
+"PF:haystack_filename,needle_str"
+"PF:haystack_filename,needle_str:occurnum"
+"PL:filename,linenum"
+"BF:haystack_bible_book,needle_str"
+"DN:word"
+"DN:word,defnum"
+"HI:index"
+"AD:code_address_number"
+
+To edit a doc structure already in memory. See SpriteEdText().
+"AI:doc_address"
+"AA:haystack_doc_address,needle_anchor_str"
+"AF:haystack_doc_address,needle_str"
+"AF:haystack_doc_address,needle_str:occurnum"
+"AL:doc_address,linenum"
+*/
+
+#define LK_FILE         0
+#define LK_FILE_ANCHOR  1
+#define LK_FILE_FIND    2
+#define LK_FILE_LINE    3
+#define LK_MAN_PAGE     4
+#define LK_PLAIN        5
+#define LK_PLAIN_FIND   6
+#define LK_PLAIN_LINE   7
+#define LK_BIBLE_FIND   8
+#define LK_DEF          9
+#define LK_HELP_INDEX   10
+#define LK_ADDR         11
+#define LK_DOC          12 //See SpriteEdText()
+#define LK_DOC_ANCHOR   13
+#define LK_DOC_FIND     14
+#define LK_DOC_LINE     15
+#define LK_PLACE_ANCHOR 16
+
+public U8 *DocEntryLink(CDoc *doc,CDocEntry *doc_e)
+{//MAlloc new str, either tag or aux_str if link.
+  if (doc_e->de_flags&DOCEF_LINK) {
+    if (doc_e->de_flags & DOCEF_AUX_STR)
+      return StrNew(doc_e->aux_str,doc->mem_task);
+    else if (doc_e->de_flags & DOCEF_TAG)
+      return StrNew(doc_e->tag,doc->mem_task);
+  }
+  return NULL;
+}
+
+Bool DocFileEd(I64 _type,U8 *filename,
+        U8 *needle_str,I64 *_num,I64 edf_dof_flags)
+{
+  I64 type=_type,flags=0,old_border_src=Fs->border_src;
+  CDocEntry *doc_e;
+  CDoc *doc;
+  Bool old_silent=Bt(&Fs->display_flags,DISPLAYf_SILENT),
+        res=FALSE,other_found=FALSE;
+  U8 *st1,*st2;
+  try {
+    switch (type) {
+      case LK_PLAIN:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+      case LK_DOC:
+        type=LK_FILE;
+        break;
+      case LK_DOC_ANCHOR:
+        type=LK_FILE_ANCHOR;
+        break;
+      case LK_PLAIN_FIND:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+      case LK_DOC_FIND:
+        type=LK_FILE_FIND;
+        break;
+      case LK_PLAIN_LINE:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+      case LK_DOC_LINE:
+        type=LK_FILE_LINE;
+        break;
+      case LK_BIBLE_FIND:
+        flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+        break;
+    }
+
+    flags|=DOCF_ALLOW_UNDO;
+
+    if (LK_DOC<=_type<=LK_DOC_LINE) {
+      doc=Str2I64(filename);//See SpriteEdText()
+      res=TRUE;
+    } else {
+      st1=StrNew(filename);
+      st2=StrNew(filename);
+      StrLastRem(st1,"/",st2); //st2 is name without dir
+      if (!FileNameChk(st2))
+        doc=NULL;
+      else {
+        Silent;
+        if (Bt(&edf_dof_flags,EDf_BAIL)) //if bail, scan parents
+          res=FileFind(filename,,
+                FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        else if (!(res=FileFind(filename,,FUF_JUST_FILES)))
+          other_found=FileFind(filename,,
+                FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        doc=DocRead(filename,flags);
+        doc->desc='Edit';
+        Silent(old_silent);
+        Fs->border_src=BDS_ED_FILENAME_DRV;
+      }
+      Free(st1);
+      Free(st2);
+    }
+    if (!doc||doc->doc_signature!=DOC_SIGNATURE_VAL)
+      res=FALSE;
+    else {
+      if (Bt(&edf_dof_flags,EDf_COLLAPSE))
+        DocCollapse(TRUE,doc);
+      else if (Bt(&edf_dof_flags,EDf_UNCOLLAPSE))
+        DocCollapse(FALSE,doc);
+
+      if (res || other_found)
+        switch (type) {
+          case LK_FILE_LINE:
+            res=DocGoToLine(doc,*_num);
+            break;
+          case LK_FILE_ANCHOR:
+            res=DocAnchorFind(doc,needle_str);
+            break;
+          case LK_FILE_FIND:
+            res=DocFind(doc,,needle_str,*_num);
+            break;
+          case LK_BIBLE_FIND:
+            res=DocFind(doc,*_num,needle_str);
+            break;
+          default:
+            DocCenter(doc);
+        }
+      *_num=doc->cur_entry->y+1;
+
+      if (edf_dof_flags&EDF_WAS_WRITE)
+        res=FALSE;
+      if (!(edf_dof_flags&EDF_BAIL)) {
+        if (*doc->filename.name)
+          doc->filename.dirc=DirContextNew(doc->filename.name);
+        else
+          doc->filename.dirc=NULL;
+        if (DocEd(doc,edf_dof_flags|DOF_DONT_HOME)) {
+          DocLock(doc);
+          doc_e=doc->cur_entry;
+          if (doc_e!=doc)
+            DocEntryRun(doc,doc_e,TRUE);
+          DocUnlock(doc);
+          if (!(LK_DOC<=_type<=LK_DOC_LINE)) {
+            DocWrite(doc);
+            if (edf_dof_flags&EDF_WAS_WRITE)
+              res=TRUE;
+          }
+        }
+        DirContextDel(doc->filename.dirc);
+      }
+      if (!(LK_DOC<=_type<=LK_DOC_LINE))
+        DocDel(doc);
+    }
+  } catch {
+    Silent(old_silent);
+    res=FALSE;
+  }
+  Fs->border_src=old_border_src;
+  return res;
+}
+
+#define DFT_ADDR_LINK_BIN_SIZE  64
+
+public I64 EdLinkCvt(U8 *link_st,U8 **_filename=NULL,U8 **_needle_str=NULL,
+        I64 *_num=NULL,I64 edf_dof_flags=0)
+{//Editor Link--> filename, needle_str and line number.
+  U8 *st,*ptr,*src,*filename=NULL,*needle_str=NULL,*filename2;
+  I64 res,i,num=1;
+  CHashSrcSym *tmph;
+  if (!link_st||!*link_st) {
+    if (edf_dof_flags&EDF_BAIL)
+      return -1;
+    link_st=blkdev.tmp_filename;
+  }
+  st=StrNew(link_st);
+  res=LK_FILE;
+  if (StrLen(st)>3 && st[2]==':') {
+    st[2]=0;
+    filename2=st+3;
+    switch (res=DefineMatch(st,"ST_LINK_TYPES",LMF_IGNORE_CASE)) {
+      case LK_MAN_PAGE:
+        if (tmph=HashFind(filename2,Fs->hash_table,HTG_SRC_SYM))
+          res=EdLinkCvt(tmph->src_link,&filename,
+                &needle_str,&num,edf_dof_flags);
+        else
+          res=-1;
+        goto lc_done;
+      case LK_ADDR:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          i=Str2I64(ptr+1);
+        } else
+          i=DFT_ADDR_LINK_BIN_SIZE;
+        if (ptr=SrcEdLink(ExePrint("%s;",filename2),i)) {
+          res=EdLinkCvt(ptr,&filename,&needle_str,&num,edf_dof_flags);
+          Free(ptr);
+        } else
+          res=-1;
+        goto lc_done;
+      case LK_DEF:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          i=Str2I64(ptr+1);
+        } else
+          i=-1;
+        filename=StrNew(filename2);
+        num=i;
+        goto lc_done;
+      case LK_HELP_INDEX:
+        filename=StrNew(filename2);
+        goto lc_done;
+      case LK_BIBLE_FIND:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          src=ptr+1;
+          while (*src) { //We do not allow ending verse
+            if (*src=='-')
+              *src=0;
+            src++;
+          }
+          needle_str=StrNew(ptr+1);
+        }
+        i=DefineMatch(filename2,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE);
+        if (i<0)
+          res=-1;
+        else {
+          num=Str2I64(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
+          filename2=BIBLE_FILENAME;
+        }
+        break;
+      case LK_FILE_LINE:
+      case LK_PLAIN_LINE:
+      case LK_DOC_LINE:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          num=Str2I64(ptr+1);
+        }
+        break;
+      case LK_FILE_ANCHOR:
+      case LK_DOC_ANCHOR:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          needle_str=StrNew(ptr+1);
+        }
+        break;
+      case LK_FILE_FIND:
+      case LK_PLAIN_FIND:
+      case LK_DOC_FIND:
+        if (ptr=StrLastOcc(filename2,",")) {
+          *ptr=0;
+          needle_str=StrNew(ptr+1);
+          if (ptr=StrLastOcc(needle_str,":")) {
+            *ptr=0;
+            num=Str2I64(ptr+1);
+          }
+        }
+        break;
+    }
+  } else
+    filename2=st;
+  if (res>=0) {
+    if (LK_DOC<=res<=LK_DOC_LINE)
+      filename=StrNew(filename2); //Holds document address as number.
+    else
+      filename=FileNameAbs(filename2,FUF_Z_OR_NOT_Z);
+  }
+lc_done:
+  Free(st);
+  if (_filename)
+    *_filename=filename;
+  else
+    Free(filename);
+  if (_needle_str)
+    *_needle_str=needle_str;
+  else
+    Free(needle_str);
+  if (_num)
+    *_num=num;
+  return res;
+}
+
+public Bool DocLinkChk(CDoc *doc,U8 *link_st)
+{//Check for bad Editor Link.
+  U8 *filename,*st;
+  Bool res=FALSE;
+  CDirContext *dirc;
+  if (link_st) {
+    st=FileNameAbs(doc->filename.name);
+    dirc=DirContextNew(st);
+    Free(st);
+    switch (EdLinkCvt(link_st,&filename)) {
+      case -1:
+        break;
+      case LK_FILE_LINE:
+      case LK_PLAIN_LINE:
+      case LK_FILE:
+//We don't check line number
+        res=FileFind(filename,,
+              FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        break;
+      case LK_BIBLE_FIND:
+        st=StrNew(link_st+3);
+        if (StrOcc(st,','))
+          StrLastRem(st,",");
+        if (DefineMatch(st,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE)>=0)
+          res=TRUE;
+        Free(st);
+        break;
+      default://TODO: Need to validate HI: and DN:
+        if (Ed(link_st,EDF_BAIL))
+          res=TRUE;
+    }
+    Free(filename);
+    DirContextDel(dirc);
+  }
+  return res;
+}
+
+public U8 *DocLinkFile(U8 *link_st,CTask *mem_task=NULL)
+{//Return the file for an Editor Link Types.
+  U8 *filename=NULL,*st,*res=NULL;
+  if (link_st) {
+    switch (EdLinkCvt(link_st,&filename)) {
+      case LK_FILE:
+      case LK_FILE_ANCHOR:
+      case LK_FILE_FIND:
+      case LK_FILE_LINE:
+      case LK_PLAIN:
+      case LK_PLAIN_FIND:
+      case LK_PLAIN_LINE:
+        st=FileNameAbs(filename,FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
+        res=StrNew(st);
+        Free(st);
+        break;
+      case LK_BIBLE_FIND:
+        res=StrNew(BIBLE_FILENAME,mem_task);
+        break;
+    }
+    Free(filename);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocMacro.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocMacro.HC.HTML new file mode 100755 index 0000000..3af88d9 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocMacro.HC.HTML @@ -0,0 +1,242 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+U8 captured_macro_name[STR_LEN];
+StrCpy(captured_macro_name,"Test");
+
+I64 sys_macro_repeat_n=1;
+
+U0 SysMacroStripKey(CJob *macro_head,I64 arg1,I64 arg2)
+{
+  CJob *tmpc,*tmpc1;
+  tmpc=macro_head->next;
+  while (tmpc!=macro_head) {
+    tmpc1=tmpc->next;
+    if (tmpc->job_code==JOBT_MSG &&
+          (tmpc->msg_code==MSG_KEY_DOWN || tmpc->msg_code==MSG_KEY_UP ||
+          tmpc->msg_code==MSG_KEY_DOWN_UP) &&
+          arg1 && tmpc->aux1==arg1 || !arg1 && tmpc->aux2==arg2) {
+      QueRem(tmpc);
+      JobDel(tmpc);
+    }
+    tmpc=tmpc1;
+  }
+}
+
+#define MT_NULL 0
+#define MT_MSG  1
+#define MT_CHAR 2
+
+class CMacroTmp
+{
+  CMacroTmp *next,*last;
+  I64 type;
+  U8 buf[STR_LEN];
+};
+
+CMacroTmp *Cmd2MT(CJob *tmpc)
+{
+  U8 buf[8];
+  CMacroTmp *tmpmt=CAlloc(sizeof(CMacroTmp));
+  if (Bt(char_bmp_macro,tmpc->aux1) && tmpc->msg_code==MSG_KEY_DOWN) {
+    tmpmt->type=MT_CHAR;
+    buf[0]=tmpc->aux1;
+    buf[1]=0;
+    StrPrint(tmpmt->buf,"%Q",buf);
+  } else {
+    tmpmt->type=MT_MSG;
+    StrPrint(tmpmt->buf,"Msg(0x%X,0x%X,0x%X);",
+          tmpc->msg_code,tmpc->aux1,tmpc->aux2);
+  }
+  return tmpmt;
+}
+
+U8 *SysMacro2Str(CJob *macro_head)
+{
+  CJob *tmpc;
+  I64 cnt=1; //terminating zero
+  U8 *ptr,*m;
+  CMacroTmp *tmpmt,*tmpmt1,head;
+  LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+
+  QueInit(&head);
+  head.type=MT_NULL;
+  tmpc=macro_head->next;
+  while (tmpc!=macro_head) {
+    tmpmt=Cmd2MT(tmpc);
+    QueIns(tmpmt,head.last);
+    cnt+=StrLen(tmpmt->buf);
+    if (tmpmt->type==MT_CHAR) {
+      if (tmpmt->last->type!=MT_CHAR)
+        cnt+=StrLen("\"");
+      if (tmpmt->next->type!=MT_CHAR)
+        cnt+=StrLen("\";");
+    }
+    tmpc=tmpc->next;
+  }
+
+  m=MAlloc(cnt);
+  ptr=m;
+
+  tmpmt=head.next;
+  while (tmpmt!=&head) {
+    tmpmt1=tmpmt->next;
+    if (tmpmt->type==MT_MSG) {
+      StrCpy(ptr, tmpmt->buf);
+      ptr+=StrLen(tmpmt->buf);
+    } else {
+      if (tmpmt->last->type!=MT_CHAR) {
+        StrCpy(ptr, "\"");
+        ptr+=StrLen("\"");
+      }
+      StrCpy(ptr,tmpmt->buf);
+      ptr+=StrLen(tmpmt->buf);
+      if (tmpmt->next->type!=MT_CHAR) {
+        StrCpy(ptr, "\";");
+        ptr+=StrLen("\";");
+      }
+    }
+    Free(tmpmt);
+    tmpmt=tmpmt1;
+  }
+  *ptr=0;
+  return m;
+}
+
+U0 PlaySysMacro(I64 n=1)
+{
+  CTask *task=sys_focus_task;
+  U8 *m;
+  if (TaskValidate(task)) {
+    LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+    m=SysMacro2Str(&sys_macro_head);
+    while (n-- && TaskValidate(task)) {
+      if (task==Fs)
+        InStr("%s",m);
+      else
+        XTalkStrWait(task,"%s",m);
+    }
+    Free(m);
+  }
+}
+
+U0 EdInsCapturedMacro()
+{
+  U8 *st=SysMacro2Str(&sys_macro_head);
+  if (sys_focus_task) {
+    XTalk(sys_focus_task,"$MA+LIS,T=\"%s\",LM=\"%$Q\"$",
+          captured_macro_name,st);
+    Free(st);
+  }
+}
+
+#define SM_RECORD       0
+#define SM_INS          1
+#define SM_PLAY         2
+#define SM_REPEAT_N     3
+#define SM_STOP         4
+
+I64 PopUpMacroMenu()
+{
+  I64 res=0;
+  U8 buf[STR_LEN];
+  CJob *tmpc;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e=DocPrint(doc,"$DA-P,LEN=STR_LEN-1,A=\"Name:%%s\"$");
+  doc_e->data=captured_macro_name;
+  DocDataFmt(doc,doc_e);
+
+  doc_e=DocPrint(doc,"\n$DA,A=\"Repeat N:%%d\"$");
+  doc_e->data=&sys_macro_repeat_n;
+  DocDataFmt(doc,doc_e);
+
+  DocPrint(doc,"\n"
+        "$CM+LX,1,3$$BT,\"RECORD\",LE=SM_RECORD$"
+        "$CM+LX,17,0$$BT,\"INSERT\",LE=SM_INS$"
+        "$CM+LX,1,3$$BT,\"PLAY\",LE=SM_PLAY$"
+        "$CM+LX,17,0$$BT,\"REPEAT N\",LE=SM_REPEAT_N$"
+        "$CM+LX,1,3$$BT,\"STOP\",LE=SM_STOP$"
+        "$CM+LX,17,0$$BT,\"CANCEL\",LE=DOCM_CANCEL$"
+        "\n\n\n$GREEN$SHIFT-F2$FG$ will play macro.\n");
+  doc->flags|=DOCF_SIZE_MIN | DOCF_FORM;
+  StrPrint(buf,"DocMenu(%d);",doc);
+  sys_macro_task=Spawn(&SrvCmdLine,NULL,"Macro Popup",,Fs);
+  Fs->popup_task=sys_macro_task;
+  LBts(&sys_macro_task->display_flags,DISPLAYf_WIN_ON_TOP);
+  tmpc=TaskExe(sys_macro_task,Fs,buf,
+        1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+  JobResScan(tmpc,&res);
+  Fs->popup_task=NULL;
+  Kill(sys_macro_task);
+  sys_macro_task=NULL;
+  DocDataScan(doc,doc_e);
+  DocDel(doc);
+  return res;
+}
+
+U0 MacroTask(I64)
+{
+  I64 i;
+  StrCpy(captured_macro_name,"Click Here");
+  sys_macro_repeat_n=1;
+  do {
+    i=PopUpMacroMenu;
+    WinRefocus(sys_focus_task);
+    switch (i) {
+      case SM_RECORD:
+        LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+        QueDel(&sys_macro_head,TRUE);
+        LBts(&sys_semas[SEMA_RECORD_MACRO],0);
+        break;
+      case SM_PLAY:
+        PlaySysMacro;
+        break;
+      case SM_REPEAT_N:
+        PlaySysMacro(sys_macro_repeat_n);
+        break;
+      case SM_STOP:
+        LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+        break;
+      case SM_INS:
+        LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
+        EdInsCapturedMacro;
+        break;
+    }
+  } while (i>=0);
+}
+
+U0 EdMacroUtil()
+{
+  if (!sys_macro_task)
+    Spawn(&MacroTask,NULL,"Macro");
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocNew.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocNew.HC.HTML new file mode 100755 index 0000000..e23b1b9 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocNew.HC.HTML @@ -0,0 +1,416 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+public Bool DocLock(CDoc *doc)
+{//Make this task have exclusive access to this doc.
+  if (!Bt(&doc->locked_flags,DOClf_LOCKED) || doc->owning_task!=Fs) {
+    while (LBts(&doc->locked_flags,DOClf_LOCKED))
+      Yield;
+    if (doc->owning_task!=Fs)
+      LBEqu(&doc->flags,DOCf_BREAK_UNLOCKED,BreakLock(Fs));
+    doc->owning_task=Fs;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+public Bool DocUnlock(CDoc *doc)
+{//Release exclusive lock on access to doc.
+  Bool unlock_break;
+  if (Bt(&doc->locked_flags,DOClf_LOCKED) && doc->owning_task==Fs) {
+    doc->owning_task=0;
+    unlock_break=Bt(&doc->flags,DOCf_BREAK_UNLOCKED);
+    LBtr(&doc->locked_flags,DOClf_LOCKED);
+    if (unlock_break)
+      BreakUnlock(Fs);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool IsEditableText(CDocEntry *doc_e)
+{
+  if (doc_e->type_u8==DOCT_TEXT&&!(doc_e->de_flags&DOCEG_DONT_EDIT))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+CDocEntry *DocEntryNewBase(CDoc *doc,I64 type,I64 de_flags=0,
+        I64 x=0,I64 y=0,I64 page_line_num=0)
+{//See also MAllocIdent and CDocEntry.
+  CDocEntry *res=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
+  res->type=type;
+  res->de_flags=de_flags|doldoc.dft_de_flags[type.u8[0]];
+  res->x=x;
+  res->y=y;
+  res->page_line_num=page_line_num;
+  return res;
+}
+
+CDocEntry *DocEntryNewTag(CDoc *doc,CDocEntry *doc_ce,U8 *tag)
+{
+  I64 l=StrLen(tag);
+  CDocEntry *res=DocEntryNewBase(doc,doc_ce->type,doc_ce->de_flags,
+        doc_ce->x,doc_ce->y,doc_ce->page_line_num);
+  res->de_flags=doc_ce->de_flags; //Override
+  res->max_col=l;
+  res->tag=MAlloc(l+1,doc->mem_task);
+  MemCpy(res->tag,tag,l+1);
+  MemCpy(&res->settings,&doc_ce->settings,sizeof(CDocSettings));
+  return res;
+}
+
+public U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e)
+{//Free entry and all parts of entry.
+  if (!doc || doc==doc_e)
+    RawPrint(3000,"DocEntryDel");
+  else {
+    if (doc->cur_entry==doc_e)
+      doc->cur_entry=doc_e->next;
+    QueRem(doc_e);
+    if (doc_e->de_flags & DOCEF_TAG)
+      Free(doc_e->tag);
+    if (doc_e->de_flags & DOCEF_AUX_STR)
+      Free(doc_e->aux_str);
+    if (doc_e->de_flags & DOCEF_DEFINE)
+      Free(doc_e->define_str);
+    if (doc_e->de_flags & DOCEF_HTML_LINK)
+      Free(doc_e->html_link);
+    if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+      Free(doc_e->left_macro);
+    if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
+      Free(doc_e->right_macro);
+    if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+      Free(doc_e->bin_ptr_link);
+    if (doc_e->de_flags & DOCEF_HAS_BIN)
+      DocBinDel(doc,doc_e->bin_data);
+    if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
+      Free(doc_e->data);
+    Free(doc_e);
+  }
+}
+
+public I64 DocEntrySize(CDoc *,CDocEntry *doc_e)
+{//Mem size of entry and all parts.
+  I64 res;
+  if (!doc_e) return 0;
+  res=MSize2(doc_e);
+  if (doc_e->de_flags & DOCEF_TAG)
+    res+=MSize2(doc_e->tag);
+  if (doc_e->de_flags & DOCEF_AUX_STR)
+    res+=MSize2(doc_e->aux_str);
+  if (doc_e->de_flags & DOCEF_DEFINE)
+    res+=MSize2(doc_e->define_str);
+  if (doc_e->de_flags & DOCEF_HTML_LINK)
+    res+=MSize2(doc_e->html_link);
+  if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+    res+=MSize2(doc_e->left_macro);
+  if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
+    res+=MSize2(doc_e->right_macro);
+  if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+    res+=MSize2(doc_e->bin_ptr_link);
+  if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
+    res+=MSize2(doc_e->data);
+  return res;
+}
+
+U0 DocUndoDel(CDoc *,CDocUndo *u)
+{
+  Free(u->body);
+  Free(u);
+}
+
+U0 DocUndoCntSet(CDoc *doc)
+{
+  Bool unlock=DocLock(doc);
+  CDocUndo *u=doc->undo_head.next;
+  doc->undo_cnt=0;
+  while (u!=&doc->undo_head) {
+    doc->undo_cnt++;
+    u=u->next;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e)
+{//Make copy of entry and all parts of entry.
+  CDocEntry *doc_ne;
+  CDocBin *tmpb;
+  CTask *task=doc->mem_task;
+  doc_ne=MAllocIdent(doc_e,task);
+  doc_ne->next=doc_ne;
+  doc_ne->last=doc_ne;
+  if (doc_e->de_flags & DOCEF_TAG)
+    doc_ne->tag=MAllocIdent(doc_e->tag,task);
+  if (doc_e->de_flags & DOCEF_AUX_STR)
+    doc_ne->aux_str=MAllocIdent(doc_e->aux_str,task);
+  if (doc_e->de_flags & DOCEF_DEFINE)
+    doc_ne->define_str=MAllocIdent(doc_e->define_str,task);
+  if (doc_e->de_flags & DOCEF_HTML_LINK)
+    doc_ne->html_link=MAllocIdent(doc_e->html_link,task);
+  if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+    doc_ne->left_macro=MAllocIdent(doc_e->left_macro,task);
+  if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
+    doc_ne->right_macro=MAllocIdent(doc_e->right_macro,task);
+  if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
+    doc_ne->bin_ptr_link=MAllocIdent(doc_e->bin_ptr_link,task);
+  if (doc_e->de_flags & DOCEF_HAS_BIN) {
+    tmpb=MAllocIdent(doc_e->bin_data,task);
+    tmpb->data=MAllocIdent(doc_e->bin_data->data,task);
+    doc_ne->bin_num=doc->cur_bin_num;
+    tmpb->num=doc->cur_bin_num++;
+    doc_ne->bin_data=tmpb;
+    if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+      tmpb->tag=StrNew(doc_e->tag,task);
+    else
+      tmpb->tag=NULL;
+    QueIns(tmpb,doc->bin_head.last);
+  }
+  if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
+    doc_ne->data=MAllocIdent(doc_e->data,task);
+  return doc_ne;
+}
+
+U0 DocRemSoftNewLines(CDoc *doc=NULL,CDocEntry *doc_e=NULL)
+{
+  CDocEntry *doc_e2,*saved_ll=doc_e;
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  if (!doc_e) doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (doc_e->type_u8==DOCT_SOFT_NEW_LINE) {
+      if (doc->cur_entry==doc_e) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc->cur_entry->min_col;
+      }
+      DocEntryDel(doc,doc_e);
+    } else if (saved_ll && doc_e->type_u8==DOCT_NEW_LINE)
+      break;
+    doc_e=doc_e2;
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocInsEntry(CDoc *doc,CDocEntry *doc_e)
+{//Insert entry into doc, updating its vals.
+  U8 *dst;
+  Bool unlock=DocLock(doc);
+  CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
+
+  doc_e->x=doc_ce->x;
+  doc_e->y=doc_ce->y;
+  doc_e->page_line_num=doc_ce->page_line_num;
+  MemCpy(&doc_e->settings,&doc_ce->settings,sizeof(CDocSettings));
+  if (doc->cur_col>0 &&
+        doc_ce->type_u8==DOCT_TEXT &&
+        !(doc_ce->de_flags&(DOCEF_TAG_CB|DOCEF_DEFINE|DOCEF_AUX_STR|
+        DOCEF_HTML_LINK|DOCEF_BIN_PTR_LINK)) &&
+        doc->cur_col<doc_ce->max_col) {
+    dst=doc_ce->tag+doc->cur_col;
+    doc_ne=DocEntryNewTag(doc,doc_ce,dst);
+    *dst=0;
+    doc_ne->type=DOCT_TEXT|doc_ce->type&0xFFFFFF00;
+    doc_ce->max_col=doc->cur_col;
+    QueIns(doc_ne,doc_ce);
+    doc->cur_col=0;
+    doc_ce=doc_ne;
+  }
+  if (doc_ce->type_u8==DOCT_TEXT && doc->cur_col>=doc_ce->max_col) {
+    QueIns(doc_e,doc_ce);
+    doc->cur_entry=doc_e->next;
+  } else {
+    QueIns(doc_e,doc_ce->last);
+    doc->cur_entry=doc_ce;
+  }
+  doc->cur_col=doc->cur_entry->min_col;
+  DocRemSoftNewLines(doc,doc->cur_entry);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocRst(CDoc *doc,Bool is_old)
+{//Del all entries and set doc to dfts.
+  Bool unlock;
+  CDocEntry *doc_e,*doc_e2;
+  CDocUndo *u,*u8;
+  CDocSettings *s;
+  CDocBin *b,*b1;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  if (is_old) {
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      doc_e2=doc_e->next;
+      DocEntryDel(doc,doc_e);
+      doc_e=doc_e2;
+    }
+    u=doc->undo_head.next;
+    while (u!=&doc->undo_head) {
+      u8=u->next;
+      DocUndoDel(doc,u);
+      u=u8;
+    }
+    b=doc->bin_head.next;
+    while (b!=&doc->bin_head) {
+      b1=b->next;
+      QueRem(b);
+      Free(b->data);
+      Free(b);
+      b=b1;
+    }
+  }
+//Check DocInsDoc
+  doc->flags&=DOCF_BREAK_UNLOCKED;
+  doc->head.next=doc->head.last=doc;
+  QueInit(&doc->bin_head);
+  QueInit(&doc->undo_head);
+  doc->undo_head.time_stamp=0;
+  doc->undo_cnt=0;
+  doc->cur_bin_num=1;
+  doc->dollar_buf_ptr=0;
+  doc->cmd_U8=CH_SPACE;
+  doc->page_line_num=0;
+  doc->best_d=I64_MAX;
+
+  s=&doc->settings_head;
+  s->left_margin=DOC_DFT;
+  s->right_margin=DOC_DFT;
+  s->indent=0;
+  s->page_len=66;
+  s->header=DOC_DFT;
+  s->footer=DOC_DFT;
+  s->state=DOCSS_NORMAL;
+  s->comment_depth=0;
+  s->paren_depth=0;
+  s->brace_depth=0;
+  s->shifted_x=0;
+  s->shifted_y=0;
+  s->cur_text_attr=s->dft_text_attr=DOC_ATTR_DFT_TEXT;
+
+  doc_e=&doc->head;
+  doc_e->type=DOCT_ERROR;
+  doc_e->de_flags=0;
+  doc_e->x=0;
+  doc_e->y=0;
+  doc_e->min_col=0;
+  doc_e->max_col=0;
+  doc_e->page_line_num=doc->page_line_num;
+  MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
+
+  DocTop(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocDel(CDoc *doc)
+{//Free entire doc and entries.
+  if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return;
+  DocLock(doc);
+  doc->doc_signature=0;
+  DocRst(doc,TRUE);
+  Free(doc->find_replace);
+  Free(doc->dollar_buf);
+  DocUnlock(doc);
+  Free(doc);
+}
+
+public I64 DocSize(CDoc *doc)
+{//Mem size of doc and all its entries.
+  Bool unlock;
+  CDocEntry *doc_e;
+  CDocUndo *u;
+  CDocBin *b;
+  I64 res=0;
+
+  if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return 0;
+  unlock=DocLock(doc);
+
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    res+=DocEntrySize(doc,doc_e);
+    doc_e=doc_e->next;
+  }
+
+  u=doc->undo_head.next;
+  while (u!=&doc->undo_head) {
+    res+=MSize2(u->body);
+    res+=MSize2(u);
+    u=u->next;
+  }
+
+  b=doc->bin_head.next;
+  while (b!=&doc->bin_head) {
+    res+=MSize2(b->data);
+    res+=MSize2(b);
+    b=b->next;
+  }
+
+  res+=MSize2(doc->find_replace);
+  res+=MSize2(doc->dollar_buf);
+  res+=MSize2(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+#help_index "DolDoc"
+public CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL)
+{//MAlloc new DolDoc. (Begin a new doc.)
+  CDoc *doc;
+  if (!task) task=Fs;
+  doc=CAlloc(sizeof(CDoc),task);
+  if (filename)
+    StrCpy(doc->filename.name,filename);
+  else
+    StrCpy(doc->filename.name,blkdev.tmp_filename);
+  doc->find_replace=CAlloc(sizeof(CEdFindText),task);
+  doc->find_replace->scan_fwd=TRUE;
+  doc->find_replace->match_case=TRUE;
+  doc->find_replace->pmt=TRUE;
+  doc->left_click_link=&EdLeftClickLink;
+  doc->dollar_buf_size=84;
+  doc->dollar_buf=MAlloc(doc->dollar_buf_size,task);
+  doc->max_entries=I64_MAX;
+  doc->win_task=task;
+  doc->mem_task=task;
+  DocRst(doc,FALSE);
+  doc->doc_signature=DOC_SIGNATURE_VAL;
+  return doc;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocPlain.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocPlain.HC.HTML new file mode 100755 index 0000000..e1c78f1 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocPlain.HC.HTML @@ -0,0 +1,642 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+I64 PrsDocFlagSingle(CCmpCtrl *cc,I64 *_de_flags,U32 *_type,Bool turn_on)
+{
+  I64 res=-1;
+  CHashGeneric *tmph;
+  if (cc->token==TK_IDENT &&
+        (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_FLAG))) {
+    res=tmph->user_data0;
+    if (res<64) {
+      BEqu(_de_flags,res,turn_on);
+      switch (res) {
+        case DOCEf_BLINK:
+        case DOCEf_INVERT:
+        case DOCEf_UNDERLINE:
+        case DOCEf_SEL:
+          BEqu(_type,res,turn_on);
+          break;
+      }
+    }
+    Lex(cc);    //skip flag
+  }
+  return res;
+}
+
+I64 PrsDocFlags(CCmpCtrl *cc,I64 *_de_flags,U32 *_type)
+{
+  I64 res=-1;
+  Bool turn_on;
+  while (TRUE) {
+    if (cc->token=='+')
+      turn_on=TRUE;
+    else if (cc->token=='-')
+      turn_on=FALSE;
+    else
+      break;
+    Lex(cc);
+    res=PrsDocFlagSingle(cc,_de_flags,_type,turn_on);
+  }
+  return res;
+}
+
+U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e)
+{//TODO: break strs
+  I64 i,j,attr=doc_e->attr,
+        t1,f1,de_flags,type;
+  U8 *buf,*buf2;
+
+  if (doc_e->type_u8==DOCT_FOREGROUND &&
+        doc->flags&DOCF_COLOR_NAMES && 0<=attr<COLORS_NUM) {
+    buf=StrNew(DefineSub(attr,"ST_COLORS"));
+    attr=DOC_DFT;
+  } else
+    buf=StrNew(DefineSub(doc_e->type_u8,"ST_DOC_CMDS"));
+  if (doc_e->type_u8!=DOCT_ERROR) {
+    f1=doldoc.dft_de_flags[doc_e->type_u8];
+    t1=doc_e->type_u8|doldoc.dft_type_flags[doc_e->type_u8];
+
+    de_flags=doc_e->de_flags&~(DOCG_BL_IV_UL|DOCEF_SEL|
+          DOCEF_HIGHLIGHT|DOCEF_WORD_WRAP|DOCEF_SKIP|DOCEF_FILTER_SKIP);
+    for (i=0;i<DOCEf_FLAGS_NUM;i++)
+      if (Bt(&f1,i)!=Bt(&de_flags,i)) {
+        if (Bt(&de_flags,i)) {
+          if (!(1<<i&DOCEG_HAS_ARG)) {
+            buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
+            Free(buf); buf=buf2;
+          }
+        } else {
+          buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
+          Free(buf); buf=buf2;
+        }
+      }
+    type=doc_e->type&~DOCET_SEL;
+    for (i=DOCEt_BLINK;i<=DOCEt_UNDERLINE;i++)
+      if (Bt(&t1,i)!=Bt(&type,i)) {
+        if (Bt(&type,i))
+          buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
+        else
+          buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
+        Free(buf); buf=buf2;
+      }
+    buf2=MStrPrint("%s,",buf);
+    Free(buf); buf=buf2;
+    switch [doc_e->type_u8] {
+      case DOCT_HEX_ED:
+        buf2=MStrPrint("%s%d,",buf,doc_e->len);
+        Free(buf); buf=buf2;
+        buf2=MStrPrint("%s%d,",buf,doc_e->hex_ed_width);
+        Free(buf); buf=buf2;
+        break;
+      case DOCT_FOREGROUND:
+      case DOCT_BACKGROUND:
+      case DOCT_DFT_FOREGROUND:
+      case DOCT_DFT_BACKGROUND:
+        if (doc->flags&DOCF_COLOR_NAMES && 0<=attr<COLORS_NUM) {
+          buf2=MStrPrint("%s%Z,",buf,doc_e->attr,"ST_COLORS");
+          Free(buf); buf=buf2;
+          break;
+        }
+      case DOCT_PAGE_LEN:
+      case DOCT_LEFT_MARGIN:
+      case DOCT_RIGHT_MARGIN:
+      case DOCT_HEADER:
+      case DOCT_FOOTER:
+      case DOCT_INDENT:
+      case DOCT_WORD_WRAP:
+      case DOCT_HIGHLIGHT:
+      case DOCT_BLINK:
+      case DOCT_INVERT:
+      case DOCT_UNDERLINE:
+      case DOCT_SHIFTED_X:
+      case DOCT_SHIFTED_Y:
+        if (attr!=DOC_DFT) {
+          buf2=MStrPrint("%s%d,",buf,doc_e->attr);
+          Free(buf); buf=buf2;
+        }
+      case DOCT_TYPES_NUM-1: //nobound switch
+        break;
+    }
+    de_flags=doc_e->de_flags & DOCEG_HAS_ARG;
+    while (de_flags) {
+      j=Bsf(de_flags);
+      Btr(&de_flags,j);
+      switch [j] {
+        case DOCEf_TAG:
+          if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_MACRO &&
+                (doc_e->de_flags&DOCEF_LEFT_MACRO &&
+                !StrCmp(doc_e->tag,doc_e->left_macro) ||
+                doc_e->de_flags&DOCEF_RIGHT_MACRO &&
+                !StrCmp(doc_e->tag,doc_e->right_macro)) ||
+                doc_e->de_flags&DOCEF_LST && !StrCmp(doc_e->tag,"[]") &&
+                doc_e->de_flags&DOCEF_DEFINE) {
+            buf2=buf;
+            buf=NULL;
+          } else {
+            if (doc_e->type_u8==DOCT_CHECK_BOX) {
+              if (StrLen(doc_e->tag)>=4)
+                buf2=doc_e->tag+4;
+              else
+                buf2="";
+            } else if (doc_e->de_flags & DOCEF_TREE) {
+              if (StrLen(doc_e->tag)>=3)
+                buf2=doc_e->tag+3;
+              else
+                buf2="";
+            } else
+              buf2=doc_e->tag;
+            if (Bt(&doldoc.dft_de_flags[doc_e->type_u8],DOCEf_TAG))
+              buf2=MStrPrint("%s\"%$Q\",",buf,buf2);
+            else
+              buf2=MStrPrint("%sT=\"%$Q\",",buf,buf2);
+          }
+          break;
+        case DOCEf_LEN:
+          buf2=MStrPrint("%sLEN=%d,",buf,doc_e->len);
+          break;
+        case DOCEf_AUX_STR:
+          buf2=MStrPrint("%sA=\"%$Q\",",buf,doc_e->aux_str);
+          break;
+        case DOCEf_DEFINE:
+          buf2=MStrPrint("%sD=\"%$Q\",",buf,doc_e->define_str);
+          break;
+        case DOCEf_HTML_LINK:
+          buf2=MStrPrint("%sHTML=\"%$Q\",",buf,doc_e->html_link);
+          break;
+        case DOCEf_LEFT_EXP:
+          buf2=MStrPrint("%sLE=%d,",buf,doc_e->left_exp);
+          break;
+        case DOCEf_LEFT_MACRO:
+          buf2=MStrPrint("%sLM=\"%$Q\",",buf,doc_e->left_macro);
+          break;
+        case DOCEf_RIGHT_EXP:
+          buf2=MStrPrint("%sRE=%d,",buf,doc_e->right_exp);
+          break;
+        case DOCEf_RIGHT_MACRO:
+          buf2=MStrPrint("%sRM=\"%$Q\",",buf,doc_e->right_macro);
+          break;
+        case DOCEf_HAS_BIN:
+          buf2=MStrPrint("%sBI=%d,",buf,doc_e->bin_num);
+          break;
+        case DOCEf_BIN_PTR_LINK:
+          buf2=MStrPrint("%sBP=\"%$Q\",",buf,doc_e->bin_ptr_link);
+          break;
+        case DOCEf_RAW_TYPE:
+          if (doc_e->type_u8==DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I8 ||
+                doc_e->type_u8!=DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I64)
+            buf2=MStrPrint("%sRT=%Z,",buf,doc_e->raw_type,"ST_RAW_TYPES");
+          break;
+        case DOCEf_SHIFTED_X:
+          j=doc_e->type.u16[1]&0x1F;
+          if (j&0x10) j|=0xFFFFFFF0;
+          buf2=MStrPrint("%sSX=%d,",buf,j);
+          break;
+        case DOCEf_SHIFTED_Y:
+          j=doc_e->type>>21 &0x1F;
+          if (j&0x10) j|=0xFFFFFFF0;
+          buf2=MStrPrint("%sSY=%d,",buf,j);
+          break;
+        case DOCEf_SCROLLING_X:
+          buf2=MStrPrint("%sSCX=%d,",buf,doc_e->scroll_len);
+          break;
+        case DOCEf_USER_DATA:
+          buf2=MStrPrint("%sU=0x%X,",buf,doc_e->user_data);
+          break;
+        case DOCEf_FLAGS_NUM-1: //nobound switch
+          break;
+      }
+      Free(buf); buf=buf2;
+    }
+    buf[StrLen(buf)-1]=0;  //Kill last comma
+  }
+  buf2=StrNew(buf,doc->mem_task); //exact allocation
+  Free(buf);
+  return buf2;
+}
+
+CDocEntry *PrsDollarCmd(CDoc *doc,U8 *st)
+{//Uses Lex() to parse a string and make Doc entries.
+  I64 i,j,de_flags,processed_flags,attr=DOC_DFT;
+  U8 *ptr,*st2;
+  CDocEntry *doc_e=NULL;
+  CHashGeneric *tmph;
+  CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
+  CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;
+  try {
+    cc->htc.hash_table_lst=NULL;
+    if (Lex(cc)==TK_IDENT) {
+      if (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_CMD|DHT_COLOR)) {
+        if (tmph->type&DHT_DOC_CMD)
+          i=tmph->user_data0;
+        else {//DHT_COLOR
+          i=DOCT_FOREGROUND;
+          attr=tmph->user_data0;
+        }
+      } else
+        goto pd_err;
+      Lex(cc); //skip cmd code
+      doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
+      doc_e->type=i;
+      doc_e->de_flags=doldoc.dft_de_flags[i];
+      doc_e->type|=doldoc.dft_type_flags[i];
+      doc_e->raw_type=RT_I64;
+      doc_e->len=DOCE_LEN_DFT;
+      j=PrsDocFlags(cc,&doc_e->de_flags,&doc_e->type);
+      cc->htc.hash_table_lst=old_hash_table_lst;
+      switch [i] {
+        case DOCT_CHECK_BOX:
+          doc_e->raw_type=RT_I8;
+          break;
+        case DOCT_HEX_ED:
+          while (cc->token==',')
+            Lex(cc);
+          if (cc->token)
+            doc_e->len=LexExpressionI64(cc);
+          else
+            goto pd_err;
+          while (cc->token==',')
+            Lex(cc);
+          if (cc->token)
+            doc_e->hex_ed_width=LexExpressionI64(cc);
+          else
+            goto pd_err;
+          break;
+        case DOCT_PAGE_LEN:
+        case DOCT_LEFT_MARGIN:
+        case DOCT_RIGHT_MARGIN:
+        case DOCT_HEADER:
+        case DOCT_FOOTER:
+        case DOCT_INDENT:
+        case DOCT_FOREGROUND:
+        case DOCT_BACKGROUND:
+        case DOCT_DFT_FOREGROUND:
+        case DOCT_DFT_BACKGROUND:
+        case DOCT_WORD_WRAP:
+        case DOCT_HIGHLIGHT:
+        case DOCT_BLINK:
+        case DOCT_INVERT:
+        case DOCT_UNDERLINE:
+        case DOCT_SHIFTED_X:
+        case DOCT_SHIFTED_Y:
+          while (cc->token==',')
+            Lex(cc);
+          if (cc->token)
+            doc_e->attr=LexExpressionI64(cc);
+          else
+            doc_e->attr=attr;
+          break;
+#assert DOCT_ERROR==DOCT_TYPES_NUM-1
+        case DOCT_ERROR:
+          goto pd_err;
+      }
+
+      processed_flags=0;
+      while (TRUE) {
+        cc->htc.hash_table_lst=NULL;
+        while (cc->token==',')
+          Lex(cc);
+        cc->htc.hash_table_lst=old_hash_table_lst;
+        j=PrsDocFlagSingle(cc,&doc_e->de_flags,&doc_e->type,TRUE);
+        if (!(de_flags=~processed_flags & doc_e->de_flags & DOCEG_HAS_ARG))
+          break;
+        if (cc->token=='=')
+          Lex(cc);
+        else
+          j=Bsf(de_flags);
+        if (j<0 || Bts(&processed_flags,j))
+          goto pd_err;
+        switch [j] {//TODO: Might check for expression errors
+          case DOCEf_TAG:
+            if (!doc_e->tag) {
+//If a $MA,LM=""$, Tag is filled when the LM is processed.
+              //if doc_e->df_flags&DOCEF_LST,
+              // Tag is filled when the Define is processed.
+              //(The dft_flag1.tag calls this after.)
+              if (cc->token==TK_STR) {
+                st2=LexExtStr(cc);
+                if (i==DOCT_CHECK_BOX) {
+                  st=MStrPrint("[X] %s",st2);
+                  Free(st2);
+                  doc_e->min_col=1;
+                } else if (doc_e->de_flags & DOCEF_LST) {
+                  if (*st2!='[') {
+                    st=MStrPrint("[%s]",st2);
+                    Free(st2);
+                  } else
+                    st=st2;
+                  doc_e->min_col=1;
+                } else if (doc_e->de_flags & DOCEF_TREE) {
+                  st=MStrPrint("+] %s",st2);
+                  Free(st2);
+                  doc_e->min_col=1;
+                } else
+                  st=st2;
+                doc_e->tag=StrNew(st,doc->mem_task);
+                Free(st);
+              } else
+                goto pd_err;
+            }
+            break;
+          case DOCEf_LEN:
+            if (cc->token) {
+              doc_e->len=LexExpression(cc);
+              doc_e->de_flags&=~DOCEF_DFT_LEN;
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_AUX_STR:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->aux_str=StrNew(st2,doc->mem_task);
+              Free(st2);
+//Anchor
+              if (i==DOCT_DATA) { //See DocForm()
+                if (ptr=StrMatch(":",doc_e->aux_str))
+                  doc_e->min_col=ptr-doc_e->aux_str+1;
+                doc_e->tag=MAlloc(doc_e->len+doc_e->min_col+2,
+                      doc->mem_task); //+2 because "_\0"
+              }
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_DEFINE:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->define_str=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (doc_e->de_flags&DOCEF_LST && !doc_e->tag)
+                doc_e->tag=StrNew("[]",doc->mem_task);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_HTML_LINK:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->html_link=StrNew(st2,doc->mem_task);
+              Free(st2);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_LEFT_EXP:
+            if (cc->token)
+              doc_e->left_exp=LexExpression(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_LEFT_MACRO:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->left_macro=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (i==DOCT_MACRO && !doc_e->tag)
+                doc_e->tag=StrNew(doc_e->left_macro,doc->mem_task);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_RIGHT_EXP:
+            if (cc->token)
+              doc_e->right_exp=LexExpression(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_RIGHT_MACRO:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->right_macro=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (i==DOCT_MACRO && !doc_e->tag)
+                doc_e->tag=StrNew(doc_e->right_macro,doc->mem_task);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_HAS_BIN:
+            if (cc->token)
+              doc_e->bin_num=LexExpressionI64(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_BIN_PTR_LINK:
+            if (cc->token==TK_STR) {
+              st2=LexExtStr(cc);
+              doc_e->bin_ptr_link=StrNew(st2,doc->mem_task);
+              Free(st2);
+              if (!DocBinPtrRst(doc,doc_e))
+                doc_e->type=DOCT_ERROR;
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_RAW_TYPE:
+            if (cc->token==TK_IDENT) {
+              j=DefineMatch(cc->cur_str,"ST_RAW_TYPES");
+              if (j<0)
+                goto pd_err;
+              doc_e->raw_type=j;
+              doc_e->de_flags&=~DOCEF_DFT_RAW_TYPE;
+              Lex(cc);
+            } else
+              goto pd_err;
+            break;
+          case DOCEf_SHIFTED_X:
+            if (cc->token)
+              doc_e->type|=(LexExpressionI64(cc) & 0x1F)<<16;
+            else
+              goto pd_err;
+            break;
+          case DOCEf_SHIFTED_Y:
+            if (cc->token)
+              doc_e->type|=(LexExpressionI64(cc) & 0x1F)<<21;
+            else
+              goto pd_err;
+            break;
+          case DOCEf_SCROLLING_X:
+            if (cc->token)
+              doc_e->scroll_len=LexExpressionI64(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_USER_DATA:
+            if (cc->token)
+              doc_e->user_data=LexExpression(cc);
+            else
+              goto pd_err;
+            break;
+          case DOCEf_FLAGS_NUM-1: //nobound switch
+            break;
+        }
+      }
+    } else {
+pd_err:
+      if (!doc_e)
+        doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
+      doc_e->type=DOCT_ERROR;
+      doc_e->de_flags=0;
+    }
+    if (doc_e->de_flags&DOCEF_LST && (doc_e->de_flags&DOCEF_REMALLOC_DATA ||
+          !(doc_e->de_flags&DOCEF_DEREF_DATA))) {
+      DocDataScan(doc,doc_e);
+      DocDataFmt(doc,doc_e);
+    }
+    CmpCtrlDel(cc);
+  } catch {
+    Fs->catch_except=TRUE;
+    if (!doc_e)
+      doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
+    doc_e->type=DOCT_ERROR;
+    doc_e->de_flags=0;
+  }
+  return doc_e;
+}
+
+U0 DocEntryToggle(CDoc *doc)
+{
+  Bool unlock=DocLock(doc),old_color_names;
+  CDocEntry *doc_ce=doc->cur_entry,*cl1,*doc_ce2;
+  U8 ch,*st,*st2;
+  I64 i,j,k;
+  if (doc_ce!=doc &&
+        !(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
+    if (doc_ce->type_u8==DOCT_TEXT && !(doc_ce->de_flags &
+          ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|
+          DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
+          !(doc_ce->type&DOCG_BL_IV_UL)) {
+      doc_ce2=doc_ce->last;
+      for (k=0;k<20;k++) {
+        if (doc_ce2!=doc) {
+          cl1=doc_ce2->last;
+          if (doc_ce2->type_u8==DOCT_TEXT &&
+                doc_ce->de_flags==doc_ce2->de_flags &&
+                doc_ce->type==doc_ce2->type) {
+            i=StrLen(doc_ce2->tag);
+            j=StrLen(doc_ce->tag);
+            st=MAlloc(i+j+1,doc->mem_task);
+            MemCpy(st,doc_ce2->tag,i);
+            MemCpy(st+i,doc_ce->tag,j+1);
+            Free(doc_ce->tag);
+            doc_ce->tag=st;
+            doc_ce->max_col=i+j;
+            doc->cur_col+=i;
+            DocEntryDel(doc,doc_ce2);
+          } else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
+            DocEntryDel(doc,doc_ce2);
+          else
+            break;
+          doc_ce2=cl1;
+        } else
+          break;
+      }
+      doc_ce2=doc_ce->next;
+      for (k=0;k<20;k++) {
+        if (doc_ce2!=doc) {
+          cl1=doc_ce2->next;
+          if (doc_ce2->type_u8==DOCT_TEXT &&
+                doc_ce->de_flags==doc_ce2->de_flags &&
+                doc_ce->type==doc_ce2->type) {
+            i=StrLen(doc_ce->tag);
+            j=StrLen(doc_ce2->tag);
+            st=MAlloc(i+j+1,doc->mem_task);
+            MemCpy(st,doc_ce->tag,i);
+            MemCpy(st+i,doc_ce2->tag,j+1);
+            Free(doc_ce->tag);
+            doc_ce->tag=st;
+            doc_ce->max_col=i+j;
+            DocEntryDel(doc,doc_ce2);
+          } else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
+            DocEntryDel(doc,doc_ce2);
+          else
+            break;
+          doc_ce2=cl1;
+        } else
+          break;
+      }
+      i=doc->cur_col;
+      while (i>doc_ce->min_col && doc_ce->tag[i]!='$')
+        i--;
+      j=doc->cur_col+1;
+      while (j<doc_ce->max_col && doc_ce->tag[j]!='$')
+        j++;
+      if (i<j-1 && doc_ce->min_col<=i<j<doc_ce->max_col &&
+            doc_ce->tag[i]=='$' && doc_ce->tag[j]=='$') {
+        ch=doc_ce->tag[j+1];
+        doc_ce->tag[j+1]=0;
+        st=StrNew(doc_ce->tag+i);
+        doc_ce->tag[j+1]=ch;
+        StrCpy(doc_ce->tag+i,doc_ce->tag+j+1);
+        doc->cur_col=i;
+        st2=MStrPrint("%q",st);
+        if (doc_ce=DocPrint(doc,st2)) {
+          doc->cur_entry=doc_ce;
+          doc->cur_col=doc_ce->min_col;
+        }
+        Free(st);
+        Free(st2);
+      }
+    } else {
+      old_color_names=LBts(&doc->flags,DOCf_COLOR_NAMES);
+      st=Doc2PlainText(doc,doc_ce);
+      LBEqu(&doc->flags,DOCf_COLOR_NAMES,old_color_names);
+      DocEntryDel(doc,doc_ce);
+      DocPrint(doc,"$$%$Q$$",st);
+    }
+    DocRecalc(doc);
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 DocFlagsToggle(CDoc *doc,I64 tog_flags)
+{
+  Bool  unlock=DocLock(doc);
+  I64 size,flags=doc->flags^tog_flags;
+  U8 *st;
+  CDocUndo *u_next,*u_last;
+
+  doc->flags=doc->flags&~DOCF_NO_CURSOR|DOCF_COLOR_NAMES;
+  st=DocSave(doc,&size);
+
+  u_next=doc->undo_head.next;
+  u_last=doc->undo_head.last;
+  doc->undo_head.next=doc->undo_head.last=&doc->undo_head;
+
+  DocRst(doc,TRUE);
+  doc->undo_head.next=u_next;
+  doc->undo_head.last=u_last;
+  DocUndoCntSet(doc);
+  doc->flags=flags&~(DOCF_NO_CURSOR|DOCG_BL_IV_UL|DOCF_WORD_WRAP);
+  DocLoad(doc,st,size);
+  doc->flags|=flags&DOCF_NO_CURSOR;
+  DocCenter(doc);
+  if (unlock)
+    DocUnlock(doc);
+  Free(st);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocPopUp.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocPopUp.HC.HTML new file mode 100755 index 0000000..26e734f --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocPopUp.HC.HTML @@ -0,0 +1,348 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+public CTask *PopUpViewDoc(CDoc *doc,I64 dof_flags=0)
+{//Pass doc to PopUp win task for viewing.
+  U8 *buf=MStrPrint("DocEd(0x%X,0x%X);",doc,dof_flags);
+  CTask *task=Spawn(&SrvCmdLine,NULL,"View",,Fs);
+  TaskExe(task,NULL,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  Free(buf);
+  return task;
+}
+
+public CTask *PopUpViewPrint(U8 *fmt,...)
+{//View Print stmt in PopUp win task.
+  CTask *task=Spawn(&SrvCmdLine,NULL,"View",,Fs);
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CDoc *doc=DocNew(,task);
+  DocPrint(doc,buf);
+  Free(buf);
+  buf=MStrPrint("DocEd(0x%X);",doc);
+  TaskExe(task,NULL,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  Free(buf);
+  return task;
+}
+
+#help_index "DolDoc/Input;File/FileNames;StdIn/DolDoc"
+public U8 *PopUpPickFile(U8 *dir=NULL)
+{//Filename chooser.  Uses FileMgr().
+  U8 *res,*st,*st2;
+  if (dir)
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",dir);
+  else {
+    st2=DirCur;
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",st2);
+    Free(st2);
+  }
+  res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public U8 *PopUpPickDir(U8 *dir=NULL)
+{//File dir name chooser.  Uses FileMgr().
+  U8 *res,*st,*st2;
+  if (dir)
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",dir);
+  else {
+    st2=DirCur;
+    st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",st2);
+    Free(st2);
+  }
+  res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public U8 *FileNameForm(U8 *dft=NULL,I64 dof_flags=0,CTask *mem_task=NULL)
+{//Text filename form in cur win, not PopUp.
+  CEdFileName fn;
+  if (dft)
+    StrCpy(fn.name,dft);
+  else
+    *fn.name=0;
+  if (DocForm(&fn,,dof_flags))
+    return StrNew(fn.name,mem_task);
+  else
+    return NULL;
+}
+
+public U8 *PopUpFileName(U8 *dft=NULL,I64 dof_flags=0)
+{//Filename chooser. Uses form, not FileMgr().
+  U8 *st=MStrPrint("FileNameForm(\"%Q\",0x%X,Fs->parent_task);",
+        dft,dof_flags|DOF_SIZE_MIN),*res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+#help_index "DolDoc"
+Bool PopUpCd()
+{
+  Bool res;
+  U8 *st=PopUpPickDir;
+  if (st) {
+    res=Cd(st);
+    Free(st);
+  } else
+    res=FALSE;
+  return res;
+}
+
+#help_index "DolDoc/Input;Char/Lists;StdIn/DolDoc"
+public I64 PopUpPickLst(U8 *lst)
+{//Prompt for lst entry in PopUp win task.
+  I64 res,i=0;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$LTBLUE$");
+  while (*lst) {
+    if (*lst=='@') {//Check for '@' alias lst entry
+      i--;
+      lst++;
+    }
+    DocPrint(doc,"$MU,\"%s\",LE=%d$\n",lst,i++);
+    lst+=StrLen(lst)+1;
+  }
+  DocPrint(doc,"\n$MU,\"CANCEL\",LE=DOCM_CANCEL$\n");
+  res=PopUpMenu(doc);
+  DocDel(doc);
+  return res;
+}
+
+#help_index "DolDoc/Input;Char/Lists;Char/Define;StdIn/DolDoc"
+public U8 *PopUpPickDefineSub(U8 *dname)
+{//Prompt for Define lst entry in PopUp win task.
+  return PopUpPickLst(Define(dname));
+}
+
+#help_index "DolDoc/Input;StdIn/DolDoc"
+public I64 PopUp1(U8 *b1,I64 n1,U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with one bttn.
+  I64 i,l1=StrLen(b1);
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"$CM+CX,%d,4$$BT,\"%s\",LE=%d$\n",-l1/2,b1,n1);
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public I64 PopUp2(U8 *b1,I64 n1,U8 *b2,I64 n2,U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with two bttns.
+  I64 i,l1=StrLen(b1),l2=StrLen(b2),y;
+  CDoc *doc=DocNew;
+  if (header) {
+    DocPrint(doc,"%s",header);
+    y=4;
+  } else {
+    DocPrint(doc,"%*s\n",l1+l2+10,"");
+    y=3;
+  }
+  DocPrint(doc,"$CM+CX,%d,%d$$BT,\"%s\",LE=%d$",-(l1+l2+3)>>1,y,b1,n1);
+  DocPrint(doc,"$CM+CX,%d,0$$BT,\"%s\",LE=%d$\n" ,-(l1+l2+3)>>1+l1+6,b2,n2);
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with OKAY bttn.
+  return PopUp1("OKAY",1,header,footer)>0;
+}
+
+public Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task with NO/YES bttns.
+  return PopUp2("YES",1,"NO",0,header,footer)>0;
+}
+
+public Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL)
+{//Make PopUp win task CANCEL/OKAY bttns.
+  return PopUp2("OKAY",1,"CANCEL",0,header,footer)>0;
+}
+
+U8 *PopUpGetStr2(U8 *header,CTask *mem_task)
+{
+  U8 *res,*st;
+  if (header)
+    "%s",header;
+  st=GetStr(,,GSF_WITH_NEW_LINE);
+  res=StrNew(st,mem_task);
+  Free(st);
+  return res;
+}
+
+public U8 *PopUpGetStr(U8 *header=NULL)
+{//Prompt for text str in PopUp win task.
+  U8 *st=MStrPrint("PopUpGetStr2(0x%X,0x%X);",header,Fs),
+        *res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public I64 PopUpGetI64(U8 *msg,I64 dft,I64 lo=I64_MIN,I64 hi=I64_MAX)
+{//Prompt for I64 text expression in PopUp win task.
+  U8 *st=MStrPrint("GetI64(0x%X,0x%X,0x%X,0x%X);",msg,dft,lo,hi);
+  I64 res=PopUp(st,Fs);
+  Free(st);
+  return res;
+}
+
+public F64 PopUpGetF64(U8 *msg,F64 dft,F64 lo=F64_MIN,F64 hi=F64_MAX)
+{//Prompt for F64 text expression in PopUp win task.
+  U8 *st=MStrPrint("GetF64(0x%X,0x%X(F64),0x%X(F64),0x%X(F64));",msg,dft,lo,hi);
+  F64 res=PopUp(st,Fs)(F64);
+  Free(st);
+  return res;
+}
+
+public I64 PopUpRangeI64(I64 lo,I64 hi,I64 step=1,
+        U8 *header=NULL,U8 *footer=NULL)
+{//Evenly-spaced I64 range chooser in PopUp win task.
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"$LTBLUE$");
+  for (i=lo;i<=hi;i+=step)
+    DocPrint(doc,"$MU,\"%d\",LE=%d$\n",i,i);
+  if (footer)
+    DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+public F64 PopUpRangeF64(F64 lo,F64 hi,F64 step,
+    U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
+{//Evenly-spaced F64 range chooser in PopUp win task.
+  F64 d;
+  I64 i;
+  U8 buf[STR_LEN];
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"$LTBLUE$");
+  for (d=lo;d<=hi;d+=step) {
+    StrPrint(buf,fmt,d);
+    DocPrint(doc,"$MU,\"%s\",LE=0x%X$\n",buf,d);
+  }
+  if (footer)
+    DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i(F64);
+}
+
+public F64 PopUpRangeF64Exp(F64 lo,F64 hi,F64 factor,
+    U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
+{//Exp-spaced F64 range chooser in PopUp win task.
+  F64 d;
+  I64 i;
+  U8 buf[STR_LEN];
+  CDoc *doc=DocNew;
+  if (header)
+    DocPrint(doc,"%s",header);
+  DocPrint(doc,"$LTBLUE$");
+  for (d=lo;d<=hi;d*=factor) {
+    StrPrint(buf,fmt,d);
+    DocPrint(doc,"$MU,\"%s\",LE=0x%X$\n",buf,d);
+  }
+  if (footer)
+    DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i(F64);
+}
+
+public F64 PopUpRangeF64Log(F64 lo,F64 hi,I64 steps,
+    U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
+{//Log-spaced F64 range chooser in PopUp win task.
+  return PopUpRangeF64Exp(lo,hi,Exp(Ln(hi/lo)/(steps-1)),fmt,header,footer);
+}
+
+#help_index "Job/Exe;Task/Job/Exe;Compiler"
+public I64 AdamFile(U8 *filename,Bool warn_ext=TRUE)
+{//Make adam_task execute file.
+  Bool okay=TRUE;
+  U8 *name=FileNameAbs(filename),
+        *name2=ExtDft(name,"HC.Z");
+  I64 res=0;
+  if (warn_ext &&
+        !FilesFindMatch(name2,FILEMASK_JIT) &&
+        !PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n"))
+    okay=FALSE;
+  if (okay)
+    res=Adam("#include \"%s\";",name2);
+  Free(name2);
+  Free(name);
+  return res;
+}
+
+public I64 PopUpFile(U8 *filename,Bool warn_ext=TRUE,
+        CTask *parent=NULL,CTask **_pu_task=NULL)
+{//ExeFile2() in PopUp task. Cont as User.
+  Bool okay=TRUE;
+  U8 *st,*name=FileNameAbs(filename),
+        *name2=ExtDft(name,"HC.Z");
+  I64 res=0;
+  if (warn_ext &&
+        !FilesFindMatch(name2,FILEMASK_JIT) &&
+        !PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n"))
+    okay=FALSE;
+  if (okay) {
+    st=MStrPrint(
+          "\"$$WW+H,1$$\";In(\"ExeFile2(\\\"%s\\\",CCF_CMD_LINE);\\n\");"
+          "UserTaskCont;",
+          name2);
+    res=PopUp(st,parent,_pu_task);
+    Free(st);
+  }
+  Free(name2);
+  Free(name);
+  return res;
+}
+
+public I64 PopUpRunFile(U8 *filename,I64 ccf_flags=0,...)
+{//ExeFile() with args using LastFun() in PopUp task.
+  U8 *st,*name=FileNameAbs(filename),
+        *name2=ExtDft(name,"HC.Z");
+  I64 res=0;
+  st=MStrPrint(
+        "\"$$WW+H,1$$\";ExeFile2(\"%s\",0x%X);LastFun(0x%X,0x%X);",
+        name2,ccf_flags,argc,argv);
+  res=PopUp(st,Fs);
+  Free(st);
+  Free(name2);
+  Free(name);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocPutKey.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocPutKey.HC.HTML new file mode 100755 index 0000000..24b2d8f --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocPutKey.HC.HTML @@ -0,0 +1,760 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+
+public U0 DocPutKey(CDoc *doc,I64 ch=0,I64 sc=0)
+{//PutKey(ch,sc) at doc insert pt, cur_entry.
+  I64 i,x,y;
+  CDoc *m;
+  CDocEntry *doc_ce;
+  U8 *st,*st2;
+  Bool unlock;
+
+  if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return;
+  if (doc->user_put_key && (*doc->user_put_key)(doc,doc->user_put_data,ch,sc))
+    return;
+  unlock=DocLock(doc);
+  if (!Bt(doldoc.clean_scan_codes,sc.u8[0]))
+    doc->flags|=DOCF_UNDO_DIRTY;
+  DocCaptureUndo(doc);
+  if (Bt(char_bmp_printable,ch) && !(sc&(SCF_CTRL|SCF_ALT))) {
+    if (sc&SCF_KEY_DESC) {
+      st=Char2KeyName(ch,FALSE);
+      KeyDescSet("Char  /'%s'",st);
+      Free(st);
+    } else
+      EdCharIns(ch,sc,doc);
+  } else {
+    doc_ce=doc->cur_entry;
+    x=doc->x; y=doc->y;
+    if (sc&SCF_ALT)
+      switch (ch) {
+        case CH_BACKSPACE: //<CTRL-H>
+          if (!(sc&(SCF_SHIFT|SCF_CTRL))) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Undo");
+            else
+              DocUndoRestore(doc);
+          }
+          break;
+      }
+    else
+      switch (ch) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_DOWN:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Down, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Down");
+                } else
+                  EdLineDown(doc,sc);
+                break;
+              } else
+                sc&=~SCF_CTRL;
+//Fall Through to SC_END
+            case SC_END:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/GoTo Doc End, Sel");
+                  else
+                    KeyDescSet("Edit/GoTo Doc End");
+                } else {
+                  while (doc_ce!=doc) {
+                    BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+                    doc_ce=doc->cur_entry=doc_ce->next;
+                  }
+                  doc->cur_col=doc_ce->min_col;
+                  DocFormBwd(doc);
+                }
+              }
+              break;
+            case SC_CURSOR_UP:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Up, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Up");
+                } else
+                  EdLineUp(doc,sc);
+                break;
+              } else
+                sc&=~SCF_CTRL;
+//Fall Through to SC_HOME
+            case SC_HOME:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/GoTo Top of Doc, Sel");
+                  else
+                    KeyDescSet("Edit/GoTo Top of Doc");
+                } else {
+                  if (doc_ce==doc) doc_ce=doc_ce->last;
+                  while (doc_ce!=doc) {
+                    BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
+                    doc_ce=doc->cur_entry=doc_ce->last;
+                  }
+                  doc_ce=doc->cur_entry=doc->head.next;
+                  doc->cur_col=doc_ce->min_col;
+                  DocFormFwd(doc);
+                }
+              }
+              break;
+            case SC_PAGE_DOWN:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Page Down, Sel");
+                  else
+                    KeyDescSet("Edit/Page Down");
+                } else {
+                  i=doc_ce->y+doc->win_task->win_height-1;
+                  if (doc_ce->type_u8==DOCT_HEX_ED)
+                    i+=doc->cur_col/3/doc_ce->hex_ed_width;
+                  while (doc_ce!=doc &&
+                        (doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y<i ||
+                        doc_ce->type_u8==DOCT_HEX_ED &&
+                        doc_ce->y+doc->cur_col/3/doc_ce->hex_ed_width<i)) {
+                    EdLineDown(doc,sc);
+//paranoid check for stuck on same node
+                    if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
+                      break;
+                    doc_ce=doc->cur_entry;
+                  }
+                }
+              }
+              break;
+            case SC_PAGE_UP:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Page Up, Sel");
+                  else
+                    KeyDescSet("Edit/Page Up");
+                }else {
+                  i=doc_ce->y-(doc->win_task->win_height-1);
+                  if (doc_ce->type_u8==DOCT_HEX_ED)
+                    i+=doc->cur_col/3/doc_ce->hex_ed_width;
+                  while (doc_ce->last!=doc &&
+                        (doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y>i ||
+                        doc_ce->type_u8==DOCT_HEX_ED &&
+                        doc_ce->y+doc->cur_col/3/doc_ce->hex_ed_width>i) &&
+                        doc_ce->y!=doc->head.next->y) {
+                    EdLineUp(doc,sc);
+//paranoid check for stuck on same node
+                    if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
+                      break;
+                    doc_ce=doc->cur_entry;
+                  }
+                }
+              }
+              break;
+            case SC_CURSOR_LEFT:
+              if (sc&SCF_KEY_DESC) {
+                if (sc&SCF_CTRL)
+                  KeyDescSet("Edit/GoTo Start of Line");
+                else {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Left, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Left");
+                }
+              } else
+                EdCursorLeft(doc,sc);
+              break;
+            case SC_CURSOR_RIGHT:
+              if (sc&SCF_KEY_DESC) {
+                if (sc&SCF_CTRL)
+                  KeyDescSet("Edit/GoTo End of Line");
+                else {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cursor Right, Sel");
+                  else
+                    KeyDescSet("Edit/Cursor Right");
+                }
+              } else
+                EdCursorRight(doc,sc);
+              break;
+            case SC_DELETE:
+              if (!(sc&SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Cut To Clip");
+                  else
+                    KeyDescSet("Char  /Delete");
+                } else {
+                  if (sc&SCF_SHIFT)
+                    ClipCut(doc);
+                  else
+                    EdCharDel(doc);
+                }
+              }
+              break;
+            case SC_INS:
+              if (sc&(SCF_SHIFT|SCF_CTRL)!=(SCF_SHIFT|SCF_CTRL)) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Edit/Paste Clip");
+                  else if (sc&SCF_CTRL)
+                    KeyDescSet("Edit/Copy to Clip");
+                  else
+                    KeyDescSet("Edit/Toggle Overstrike");
+                } else {
+                  if (sc&SCF_SHIFT)
+                    ClipPaste(doc);
+                  else if (sc&SCF_CTRL)
+                    ClipCopy(doc);
+                  else
+                    doc->flags^=DOCF_OVERSTRIKE;
+                }
+              }
+              break;
+            case SC_F1...SC_F10:
+              if (sc&SCF_CTRL) {
+                if (sc&SCF_KEY_DESC) {
+                  if (sc&SCF_SHIFT)
+                    KeyDescSet("Cmd /Src Code of Sym");
+                  else
+                    KeyDescSet("Edit/Autocomplete Sym");
+                } else {
+                  DocUnlock(doc);
+                  if (AutoComplete(ON)) {
+                    if (sc&SCF_SHIFT)
+                      ACMan(sc.u8[0]-SC_F1+1,Fs);
+                    else
+                      ACFillIn(sc.u8[0]-SC_F1+1);
+                  }
+                  DocLock(doc);
+                }
+              } else {
+                switch (sc.u8[0]) {
+                  case SC_F1:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /About");
+                      else
+                        KeyDescSet("Cmd /Help");
+                    } else {
+                      if (sc&SCF_SHIFT)
+                        Ed("::/Doc/AboutTempleOS.DD.Z");
+                      else
+                        Ed("::/Doc/HelpIndex.DD.Z");
+                    }
+                    break;
+                  case SC_F2:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Edit/Play Macro");
+                      else
+                        KeyDescSet("Edit/Macro");
+                    } else {
+                      DocUnlock(doc);
+                      if (sc&SCF_SHIFT) {
+                        if (TaskValidate(sys_macro_task))
+                          PostMsgWait(sys_macro_task,
+                                MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+                        SysMacroStripKey(&sys_macro_head,ch,sc);
+                        PlaySysMacro;
+                      } else
+                        EdMacroUtil;
+                      DocLock(doc);
+                    }
+                    break;
+                  case SC_F3:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Edit/Find Last");
+                      else
+                        KeyDescSet("Edit/Find Next");
+                    }else {
+                      doc->find_replace->scan_fwd=!(sc&SCF_SHIFT);
+                      EdFindNext(doc);
+                    }
+                    break;
+                  case SC_F4:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /Insert Directory Name");
+                      else
+                        KeyDescSet("Cmd /Insert FileName");
+                    } else {
+                      DocUnlock(doc);
+                      if (sc&SCF_SHIFT)
+                        st=PopUpPickDir;
+                      else
+                        st=PopUpPickFile;
+                      DocLock(doc);
+                      if (st) {
+                        DocPrintPartial(doc,"%s",st);
+                        Free(st);
+                      }
+                    }
+                    break;
+                  case SC_F5:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /Adam Include");
+                      else
+                        KeyDescSet("Cmd /Run (Execute)");
+                    } else {
+                      if (st2=DocEntryLink(doc,doc_ce)) {
+                        st=DocLinkFile(st2);
+                        Free(st2);
+                      } else {
+                        DocWrite(doc);
+                        st=StrNew(doc->filename.name);
+                      }
+                      if (st2=DirFile(st,"Run","HC.Z")) {
+                        if (FileFind(st2)) {
+                          Free(st);
+                          st=st2;
+                        } else
+                          Free(st2);
+                      }
+                      if (st) {
+                        if (sc&SCF_SHIFT)
+                          AdamFile(st);
+                        else
+                          PopUpFile(st);
+                        Free(st);
+                      }
+                    }
+                    break;
+                  case SC_F6:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /God Doodle");
+                      else
+                        KeyDescSet("Cmd /God Song");
+                    } else {
+//::/Adam/God/HSNotes.DD
+                      if (sc&SCF_SHIFT) {
+                        DocUnlock(doc);
+                        GodDoodle;
+                        DocLock(doc);
+                      } else
+                        GodSong;
+                    }
+                    break;
+                  case SC_F7:
+                    if (sc&SCF_KEY_DESC) {
+                      if (sc&SCF_SHIFT)
+                        KeyDescSet("Cmd /God Passage");
+                      else
+                        KeyDescSet("Cmd /God Word");
+                    } else {
+//::/Adam/God/HSNotes.DD
+                      FifoU8Flush(god.fifo);
+                      GodBitsIns(GOD_GOOD_BITS,KbdMsEvtTime>>GOD_BAD_BITS);
+                      if (sc&SCF_SHIFT)
+                        GodBiblePassage;
+                      else
+                        GodWord;
+                    }
+                    break;
+                }
+              }
+              break;
+          }
+          break;
+        case CH_CTRLA:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Save As");
+            else if (DocWrite(doc,TRUE)&&(st=FileNameAbs(doc->filename.name))) {
+              DirContextDel(doc->filename.dirc);
+              doc->filename.dirc=DirContextNew(st);
+              Free(st);
+            }
+          }
+          break;
+        case CH_CTRLB:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Toggle Border");
+            else
+              WinBorder(Bt(&doc->win_task->display_flags,
+                    DISPLAYf_NO_BORDER),doc->win_task);
+          }
+          break;
+        case CH_CTRLC:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Copy to Clip");
+            else
+              ClipCopy(doc);
+          }
+          break;
+        case CH_CTRLD:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /File Manager");
+            else {
+              DocUnlock(doc);
+              FileMgr;
+              DocLock(doc);
+            }
+          }
+          break;
+        case CH_CTRLF:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Search Files");
+            else
+              FindWiz;
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Find & Replace");
+            else
+              EdFindReplace(doc);
+          }
+          break;
+        case CH_CTRLG:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/GoTo Line Num");
+            else
+              EdGoToLine(doc);
+          }
+          break;
+        case CH_BACKSPACE: //<CTRL-H>
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Char  /Back Space");
+            else {
+              DocCaptureUndo(doc);
+              doc_ce=doc->cur_entry;
+              if (doc->cur_col<=doc_ce->min_col) {
+                doc_ce=doc->cur_entry=doc_ce->last;
+                if (doc_ce!=doc && doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
+                  doc_ce=doc->cur_entry=doc_ce->last;
+                if (doc_ce==doc || doc_ce->type_u8==DOCT_PMT) {
+                  doc_ce=doc->cur_entry=doc_ce->next;
+                  doc->cur_col=doc_ce->min_col;
+                } else {
+                  doc->cur_col=doc_ce->max_col;
+                  if (doc->cur_col>doc_ce->min_col)
+                    doc->cur_col--;
+                  EdCharDel(doc);
+                }
+              } else {
+                doc->cur_col--;
+                EdCharDel(doc);
+              }
+            }
+          }
+          break;
+        case CH_CTRLI:
+          if (sc.u8[0]!=SC_TAB) {
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Unindent 2");
+              else
+                DocPrint(doc,"$ID,-2$");
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Indent 2");
+              else
+                DocPrint(doc,"$ID,2$");
+            }
+          }
+          break;
+        case '\n':
+          if (sc&SCF_KEY_DESC) {
+            if (sc&SCF_SHIFT)
+              KeyDescSet("Char  /Return");
+            else
+              KeyDescSet("Char  /Page Break");
+          } else
+            EdCharIns(ch,sc,doc);
+          break;
+        case CH_CTRLK:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Blinking Text Off");
+            else
+              DocPrint(doc,"$BK,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Blinking Text On");
+            else
+              DocPrint(doc,"$BK,1$");
+          }
+          break;
+        case CH_CTRLL:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Code Tools");
+            else {
+              DocUnlock(doc);
+              EdCodeTools(doc);
+              DocLock(doc);
+            }
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Insert Text Widgets Wizard");
+            else {
+              DocUnlock(doc);
+              EdInsWidgetWiz;
+              DocLock(doc);
+            }
+          }
+          break;
+        case CH_CTRLM:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Personal Notes");
+            else
+              Ed("~/PersonalNotes.DD.Z");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Personal Menu");
+            else {
+              m=DocRead("~/PersonalMenu.DD.Z");
+              DocMenu(m);
+              DocDel(m);
+            }
+          }
+          break;
+        case CH_CTRLO:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Collapse");
+            else
+              DocCollapse(TRUE,doc);
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Uncolapse");
+            else
+              DocCollapse(FALSE,doc);
+          }
+          break;
+        case CH_CTRLP:
+          if (doc->flags & (DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Toggle Super or Sub script");
+            else {
+              DocPrint(doc,"$SY,0$");
+              doc->flags&=~(DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE);
+            }
+          } else if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Toggle Subscript");
+            else {
+              DocPrint(doc,"$SY,3$");
+              doc->flags|=DOCF_SUBSCRIPT_MODE;
+            }
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Toggle Superscript");
+            else {
+              DocPrint(doc,"$SY,-3$");
+              doc->flags|=DOCF_SUPERSCRIPT_MODE;
+            }
+          }
+          break;
+        case CH_CTRLQ:
+          break;
+        case CH_CTRLR:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Cmd /Sprite Graphic Resource");
+            else
+              if (!(doc->flags&DOCF_FORM) &&
+                    !(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
+                DocUnlock(doc);
+                if (doc_ce->type_u8==DOCT_SPRITE)
+                  EdSpriteEd(doc);
+                else
+                  EdSpriteIns(doc);
+                DocLock(doc);
+              }
+          }
+          break;
+        case CH_CTRLS:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Toggle AutoSave");
+            else
+              LBtc(&doc->flags,DOCf_AUTO_SAVE);
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Save");
+            else
+              DocWrite(doc);
+          }
+          break;
+        case CH_CTRLT:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Single Entry Toggle Plain Text");
+            else if (!(doc->flags&DOCF_FORM))
+              DocEntryToggle(doc);
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Toggle Plain Text Display");
+            else if (!(doc->flags&DOCF_FORM))
+              DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
+          }
+          break;
+        case CH_CTRLU:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Underline Off");
+            else
+              DocPrint(doc,"$UL,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Underline On");
+            else
+              DocPrint(doc,"$UL,1$");
+          }
+          break;
+        case CH_CTRLV:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Paste Clip");
+            else
+              ClipPaste(doc);
+          }
+          break;
+        case CH_CTRLW:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Word Wrap Off");
+            else
+              DocPrint(doc,"$WW,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Word Wrap On");
+            else
+              DocPrint(doc,"$WW,1$");
+          }
+          break;
+        case CH_CTRLX:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Cut To Clip");
+            else
+              ClipCut(doc);
+          }
+          break;
+        case CH_CTRLY:
+          if (!(sc&SCF_SHIFT)) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Edit/Delete Line");
+            else
+              EdLineDel(doc);
+          }
+          break;
+        case CH_CTRLZ:
+          if (sc&SCF_SHIFT) {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Inverted Text Off");
+            else
+              DocPrint(doc,"$IV,0$");
+          } else {
+            if (sc&SCF_KEY_DESC)
+              KeyDescSet("Dol /Inverted Text On");
+            else
+              DocPrint(doc,"$IV,1$");
+          }
+          break;
+        case '0'...'9':
+          if (sc&SCF_CTRL) {
+            if (sc&SCF_KEY_DESC) {
+              if (sc&SCF_SHIFT)
+                KeyDescSet("Cmd /Word Definition");
+              else
+                KeyDescSet("Edit/Autocomplete Word");
+            } else {
+              if (AutoComplete(ON)) {
+                DocUnlock(doc);
+                if (sc&SCF_SHIFT)
+                  ACDDef(ch-'0',Fs);
+                else
+                  ACDFillin(ch-'0');
+                DocLock(doc);
+              }
+            }
+          }
+          break;
+        case '[':
+          if (sc&SCF_CTRL) {
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching brace");
+              else
+                EdFindPaired(doc,'}','{',FALSE);
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching bracket");
+              else
+                EdFindPaired(doc,']','[',FALSE);
+            }
+          }
+          break;
+        case ']':
+          if (sc&SCF_CTRL) {
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching brace");
+              else
+                EdFindPaired(doc,'{','}',TRUE);
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Edit/GoTo matching bracket");
+              else
+                EdFindPaired(doc,'[',']',TRUE);
+            }
+          }
+          break;
+      }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  if (!(doc->flags&DOCF_DONT_SWAP_OUT))
+    Yield;
+}
+
+Bool KDDocPutKey(I64 ch,I64 scan_code)
+{
+  CDoc *doc;
+  if (doc=DocPut)
+    DocPutKey(doc,ch,scan_code);
+  return FALSE;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocPutS.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocPutS.HC.HTML new file mode 100755 index 0000000..42903a3 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocPutS.HC.HTML @@ -0,0 +1,367 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Output;StdOut/DolDoc"
+
+CDocEntry *DocPutS(CDoc *doc,U8 *st)
+{//Don't use this.  Use DocPrint().
+//Does not handle partial Doc entries.
+  //Returns last newly created dollar-sign CDocEntry or NULL.
+  U8 *ptr=st,*ptr2,*st2,*ptr3,*ptr4,*src,
+        *char_bmp;
+  Bool unlock;
+  I64 ch,j;
+  CDocEntry *doc_e=NULL,*res=NULL,*doc_ce;
+  if (!st || !doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return NULL;
+  unlock=DocLock(doc);
+  if (doc->flags & DOCF_PLAIN_TEXT_TABS)
+    char_bmp=char_bmp_zero_cr_nl_cursor;
+  else if (doc->flags & DOCF_PLAIN_TEXT)
+    char_bmp=char_bmp_zero_tab_cr_nl_cursor;
+  else
+    char_bmp=char_bmp_zero_tab_cr_nl_cursor_dollar;
+  doc_ce=doc->cur_entry;
+  while (*ptr) {
+    ptr2=ptr;
+    do ch=*ptr++;
+    while (!Bt(char_bmp,ch) || ch==CH_CURSOR && doc->flags&DOCF_NO_CURSOR);
+    ptr--;
+    if (!ch) {
+      if (j=ptr-ptr2) {
+        doc_e=DocEntryNewBase(doc,
+              DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
+        if (doc->flags & DOCF_NO_CURSOR) {
+          src=MAlloc(j+1);
+          MemCpy(src,ptr2,j+1);
+          StrUtil(src,SUF_REM_CTRL_CHARS);
+          j=StrLen(src);
+        } else
+          src=ptr2;
+        doc_e->tag=MAlloc(j+1,doc->mem_task);
+        MemCpy(doc_e->tag,src,j+1);
+        doc_e->max_col=j;
+        DocInsEntry(doc,doc_e);
+        if (doc->flags & DOCF_NO_CURSOR)
+          Free(src);
+      }
+    } else {
+      if (j=ptr-ptr2) {
+        *ptr=0;
+        doc_e=DocEntryNewBase(doc,
+              DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
+        if (doc->flags & DOCF_NO_CURSOR) {
+          src=MAlloc(j+1);
+          MemCpy(src,ptr2,j+1);
+          ptr3=src;
+          ptr4=src;
+          while (*ptr3)
+            if (*ptr3!=CH_CURSOR)
+              *ptr4++=*ptr3++;
+            else
+              ptr3++;
+          *ptr4=0;
+          j=ptr4-src;
+        } else
+          src=ptr2;
+        doc_e->tag=MAlloc(j+1,doc->mem_task);
+        MemCpy(doc_e->tag,src,j+1);
+        doc_e->max_col=j;
+        DocInsEntry(doc,doc_e);
+        if (doc->flags & DOCF_NO_CURSOR)
+          Free(src);
+        *ptr=ch;
+      }
+      switch (ch) {
+        case CH_CURSOR:
+          doc_e=DocEntryNewBase(doc,
+                DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
+          DocInsEntry(doc,doc_e);
+          ptr++;
+          break;
+        case '\t':
+          doc_e=DocEntryNewBase(doc,
+                DOCT_TAB|doc->settings_head.dft_text_attr<<8);
+          DocInsEntry(doc,doc_e);
+          ptr++;
+          break;
+        case '$':
+          ptr++; //skip first dollar
+          ptr2=ptr;
+          while (*ptr && *ptr!='$')
+            ptr++;
+          if (*ptr) {
+            *ptr=0; //zero second dollar
+            if (ptr-1==ptr2 && *ptr2==CH_CURSOR) {
+              doc_e=DocEntryNewBase(doc,
+                    DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
+              DocInsEntry(doc,doc_e);
+              ptr2++;
+            }
+            if (ptr==ptr2) {
+              doc_e=DocEntryNewBase(doc,
+                    DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
+              doc_e->max_col=1;
+              if (doc->flags & DOCF_DBL_DOLLARS)
+                doc_e->tag=StrNew("$$",doc->mem_task);
+              else
+                doc_e->tag=StrNew("$",doc->mem_task);
+              DocInsEntry(doc,doc_e);
+            } else {
+              st2=MAlloc(ptr-ptr2+1);
+              ptr3=ptr2;
+              ptr4=st2;
+              while (ch=*ptr3++) {
+                if (ch==CH_CURSOR) {
+                  doc_e=DocEntryNewBase(doc,
+                        DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
+                  DocInsEntry(doc,doc_e);
+                } else
+                  *ptr4++=ch;
+              }
+              *ptr4=0;
+              if (doc_e=PrsDollarCmd(doc,st2)) {
+                res=doc_e;
+                DocInsEntry(doc,doc_e);
+              }
+              Free(st2);
+            }
+            *ptr++='$';
+          }
+          break;
+        default:
+          doc_e=DocEntryNewBase(doc,
+                DOCT_NEW_LINE|doc->settings_head.dft_text_attr<<8);
+          DocInsEntry(doc,doc_e);
+          if (ch=='\r')
+            while (*ptr=='\r')
+              ptr++;
+          if (*ptr=='\n')
+            ptr++;
+          while (*ptr=='\r')
+            ptr++;
+      }
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+public CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...)
+{//You must not print partial doc cmds.
+//Returns last newly created dollar-sign CDocEntry or NULL.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CDocEntry *res=DocPutS(doc,buf);
+  Free(buf);
+  return res;
+}
+
+public U0 DocPrintPartial(CDoc *doc=NULL,U8 *fmt,...)
+{//Lets you print half a doc cmd, if you like.
+  U8 *buf,*st,*src,*dst,*ptr,*ptr2;
+  Bool unlock;
+  CDocEntry *doc_ce,*doc_ne;
+  I64 ch,i,j;
+  if (!doc && !(doc=DocPut))
+    return;
+  buf=StrPrintJoin(NULL,fmt,argc,argv);
+  ptr=buf;
+  if (doc->user_put_s && (*doc->user_put_s)(doc,doc->user_put_data,buf)) {
+    Free(buf);
+    return;
+  }
+  unlock=DocLock(doc);
+  if (doc->cur_entry->type_u8==DOCT_DATA)
+    while (ch=*ptr++)
+      DocPutKey(doc,ch,0);
+  else
+    while (ch=*ptr) {
+      if (!Bt(char_bmp_safe_dollar,ch) ||
+            doc->flags & (DOCF_OVERSTRIKE|DOCF_IN_DOLLAR)) {
+        DocPutKey(doc,ch,0);
+        ptr++;
+      } else {
+        ptr2=ptr++;
+        while (TRUE) {
+          ch=*ptr++;
+          if (!Bt(char_bmp_safe_dollar,ch))
+            break;
+        }
+        ptr--;
+        *ptr=0;
+        doc_ce=doc->cur_entry;
+        j=ptr-ptr2;
+        if (IsEditableText(doc_ce)) {
+          dst=st=MAlloc(doc_ce->max_col+j+1,doc->mem_task);
+          src=doc_ce->tag;
+          i=doc->cur_col;
+          doc->cur_col+=j;
+          doc_ce->max_col+=j;
+          while (i-->0)
+            *dst++=*src++;
+          while (j-->0)
+            *dst++=*ptr2++;
+          while (*dst++=*src++);
+          Free(doc_ce->tag);
+          doc_ce->tag=st;
+        } else {
+          doc_ne=DocEntryNewTag(doc,doc_ce,ptr2);
+          doc_ne->type=DOCT_TEXT|doc->settings_head.dft_text_attr<<8;
+          doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
+          QueIns(doc_ne,doc_ce->last);
+          doc->cur_entry=doc_ne;
+          doc->cur_col=StrLen(ptr2);
+        }
+        *ptr=ch;
+        DocRemSoftNewLines(doc,doc->cur_entry);
+      }
+    }
+  if (unlock)
+    DocUnlock(doc);
+  if (!(doc->flags&DOCF_DONT_SWAP_OUT))
+    Yield;
+  Free(buf);
+}
+
+Bool KDDocPutS(U8 *st)
+{
+  CDoc *doc;
+  if (doc=DocPut)
+    DocPrintPartial(doc,"%s",st);
+  return FALSE;
+}
+
+public U0 DocPrintAtomic(CDoc *doc=NULL,U8 *fmt,...)
+{//Prints multiple whole cmds all-at-once. Might need this when printing trees.
+  U8 *buf;
+  Bool unlock;
+  I64 old_flags;
+  if (!doc && !(doc=DocPut))
+    return;
+  buf=StrPrintJoin(NULL,fmt,argc,argv);
+  unlock=DocLock(doc);
+  old_flags=doc->flags;
+  doc->flags|=DOCF_NO_CURSOR;
+  DocPrint(doc,"%s",buf);
+  DocRecalc(doc);
+  doc->flags=old_flags;
+  if (unlock)
+    DocUnlock(doc);
+  Free(buf);
+}
+
+U0 DocDump(CDoc *doc,I64 uS_delay=0)
+{
+  U8 *st;
+  CDocEntry *doc_e,*doc_e2;
+  Bool unlock=DocLock(doc);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    st=DocScanLine(doc,doc_e,NULL,&doc_e2);
+    "%s",st;
+    Free(st);
+    doc_e=doc_e2;
+    if (doc_e->type_u8==DOCT_NEW_LINE) {
+      '\n';
+      Busy(uS_delay);
+      doc_e=doc_e->next;
+    }
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public CDocEntry *DocPutLine(CDoc *doc=NULL,CDocEntry *doc_e)
+{//Send line from other doc to StdOut DocPut.
+  I64 ch;
+  U8 *ptr,*ptr2;
+  Bool unlock;
+  if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
+    return NULL;
+  unlock=DocLock(doc);
+  while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
+    if (doc_e->de_flags&DOCEF_TAG) {
+      ptr=doc_e->tag;
+      do {
+        ptr2=ptr;
+        while (ch=*ptr)
+          if (ch=='$')
+            break;
+          else
+            ptr++;
+        *ptr=0;
+        "%s",ptr2;
+        *ptr=ch;
+        if (ch=='$') {
+          "$$";
+          ptr++;
+        }
+      } while (ch);
+    } else if (doc_e->type_u8==DOCT_TAB)
+      '\t';
+    doc_e=doc_e->next;
+  }
+  '\n';
+  if (doc_e!=doc)
+    doc_e=doc_e->next;
+  if (unlock)
+    DocUnlock(doc);
+  return doc_e;
+}
+
+#help_index "Debugging/Dump;DolDoc/Cmd Line (Typically);"\
+        "Cmd Line (Typically);DolDoc/Output;StdOut/DolDoc"
+public U0 DocDm(U8 *buf,I64 cnt=0x80)
+{//Dump live chunk of mem showing addresses. Can be edited.
+  CDocEntry *doc_e;
+  CDoc *doc=DocPut;
+  Bool unlock=DocLock(doc);
+  doc_e=DocPrint(doc,"$HX-Z,%d,16$",cnt);
+  doc_e->data=buf;
+  doc->cur_entry=doc_e->next;
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocD(U8 *buf,I64 cnt=0x80)
+{//Dump live chunk of mem showing offsets. Can be edited.
+  CDocEntry *doc_e;
+  CDoc *doc=DocPut;
+  Bool unlock=DocLock(doc);
+  doc_e=DocPrint(doc,"$HX,%d,16$",cnt);
+  doc_e->data=buf;
+  doc->cur_entry=doc_e->next;
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocRecalc.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocRecalc.HC.HTML new file mode 100755 index 0000000..8208557 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocRecalc.HC.HTML @@ -0,0 +1,1355 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+I64 DocWordWrapDel(CDoc *doc,CDocEntry *doc_e,
+        Bool full_refresh,Bool same_win,I64 left_margin,I64 right_margin,
+        CDocEntry **_best_doc_e,I64 *_best_col)
+{
+  CDocEntry *doc_e2;
+  U8 *ptr;
+  I64 j,k;
+  if (doc_e->de_flags&DOCEF_TAG && doc_e->tag)
+    k=StrLen(doc_e->tag);
+  else
+    k=0;
+  if (full_refresh)
+    while (TRUE) {
+      doc_e2=doc_e->next;
+      if (doc_e2->type_u8==DOCT_SOFT_NEW_LINE && !same_win) {
+        if (doc->cur_entry==doc_e2) {
+          doc->cur_entry=doc_e2->next;
+          doc->cur_col=doc->cur_entry->min_col;
+        }
+        if (*_best_doc_e==doc_e2) {
+          *_best_doc_e=doc_e2->next;
+          *_best_col=0;
+        }
+        DocEntryDel(doc,doc_e2);
+      } else if (IsEditableText(doc_e) &&
+            doc_e->de_flags==doc_e2->de_flags && doc_e->type==doc_e2->type) {
+        j=StrLen(doc_e2->tag);
+        ptr=MAlloc(k+j+1,doc->mem_task);
+        MemCpy(ptr,doc_e->tag,k);
+        MemCpy(ptr+k,doc_e2->tag,j+1);
+        Free(doc_e->tag);
+        doc_e->tag=ptr;
+        if (doc->cur_entry==doc_e2) {
+          doc->cur_entry=doc_e;
+          doc->cur_col+=k;
+        }
+        if (*_best_doc_e==doc_e2) {
+          *_best_doc_e=doc_e;
+          *_best_col=0;
+        }
+        DocEntryDel(doc,doc_e2);
+        k+=j;
+        if (k>(right_margin-left_margin+1)<<1)
+          break;
+      } else
+        break;
+    }
+  if (doc_e->de_flags & DOCEF_SCROLLING_X)
+    k=doc_e->scroll_len;
+  return k;
+}
+
+U0 DocRecalcXY(CDoc *doc,CDocEntry *doc_e,
+        I64 k,I64 left,I64 width,I64 height,I64 left_margin,I64 right_margin,
+        I64 x0,I64 y0,I64 *_x,I64 *_y)
+{
+  I64 i,x=*_x,y=*_y;
+  if (doc_e->de_flags & DOCEF_MARGIN_REL_X) {
+    if (doc_e->de_flags & DOCEF_LEFT_X)
+      x=left_margin-left;
+    else if (doc_e->de_flags & DOCEF_RIGHT_X)
+      x=right_margin-(k-1)-left;
+    else if (doc_e->de_flags & DOCEF_CENTER_X)
+      x=(right_margin+left_margin)>>1-k>>1-left;
+  } else {
+    if (doc_e->de_flags & DOCEF_LEFT_X)
+      x=x0;
+    else if (doc_e->de_flags & DOCEF_RIGHT_X)
+      x=width+x0-k;
+    else if (doc_e->de_flags & DOCEF_CENTER_X)
+      x=(width+x0-k)>>1;
+  }
+  i=y;
+  if (doc_e->de_flags & DOCEF_PAGE_REL_Y) {
+    doc->flags|=DOCF_BWD_MOVEMENT;
+    if (doc_e->de_flags & DOCEF_TOP_Y)
+      y-=doc_e->page_line_num;
+    else if (doc_e->de_flags & DOCEF_BOTTOM_Y)
+      y+=doc_e->settings.page_len-doc_e->page_line_num;
+    else if (doc_e->de_flags & DOCEF_CENTER_Y)
+      y+=doc_e->settings.page_len>>1-doc_e->page_line_num;
+  } else {
+    doc->flags|=DOCF_BWD_MOVEMENT;
+    if (doc_e->de_flags & DOCEF_TOP_Y)
+      y=y0;
+    else if (doc_e->de_flags & DOCEF_BOTTOM_Y)
+      y=height-1+y0;
+    else if (doc_e->de_flags & DOCEF_CENTER_Y)
+      y=height>>1+y0;
+  }
+  if (y!=i) {
+    doc->page_line_num+=y-i;
+    if (doc->page_line_num<0)
+      doc->page_line_num=doc_e->settings.page_len+
+            doc->page_line_num%doc_e->settings.page_len;
+    else
+      doc->page_line_num=doc->page_line_num%doc_e->settings.page_len;
+    if (doc_e->settings.header!=DOC_DFT &&
+          doc->page_line_num<doc_e->settings.header) {
+      y+=doc_e->settings.header-doc->page_line_num;
+      doc->page_line_num=doc_e->settings.header;
+    }
+    if (doc_e->settings.footer==DOC_DFT) {
+      if (doc->page_line_num>=doc_e->settings.page_len) {
+        if (doc_e->settings.header==DOC_DFT)
+          doc->page_line_num=0;
+        else {
+          doc->page_line_num=doc_e->settings.header;
+          y+=doc_e->settings.header;
+        }
+      }
+    } else {
+      if (doc->page_line_num>=
+            doc_e->settings.page_len-doc_e->settings.footer) {
+        y+=doc_e->settings.footer;
+        if (doc_e->settings.header==DOC_DFT)
+          doc->page_line_num=0;
+        else {
+          doc->page_line_num=doc_e->settings.header;
+          y+=doc_e->settings.header;
+        }
+      }
+    }
+  }
+  *_x=x;
+  *_y=y;
+}
+
+CDocEntry *DocSplitTag(CDoc *doc,CDocEntry *doc_e,I64 i,I64 x,I64 y,I64 type_u8)
+{//Split tag at i, insert DOCT_SOFT_NEW_LINE, DOCT_MARKER or DOCT_CURSOR
+  U8 *ptr;
+  CDocEntry *doc_e2;
+  if (doc_e->type_u8==DOCT_TEXT && i) {
+    if (i<StrLen(doc_e->tag)) {
+      doc_e2=MAllocIdent(doc_e,doc->mem_task);
+      doc_e2->tag=StrNew(doc_e->tag+i,doc->mem_task);
+      doc_e2->de_flags=doc_e->de_flags&~DOCEG_HAS_ALLOC|DOCEF_TAG;
+      QueIns(doc_e2,doc_e);
+      if (doc->cur_entry==doc_e && doc->cur_col>=i) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc->cur_col-i;
+      }
+      doc_e->tag[i]=0;
+      ptr=StrNew(doc_e->tag,doc->mem_task);
+      Free(doc_e->tag);
+      doc_e->tag=ptr;
+    }
+  } else
+    doc_e=doc_e->last;
+  doc_e2=DocEntryNewBase(doc,type_u8|doc_e->type & 0xFFFFFF00,
+        doc_e->de_flags&~DOCEG_HAS_ARG,x,y,doc_e->page_line_num);
+  MemCpy(&doc_e2->settings,&doc_e->settings,sizeof(CDocSettings));
+  QueIns(doc_e2,doc_e);
+  return doc_e2;
+}
+
+CDocEntry *DocWordWrapAdd(CDoc *doc,CDocEntry *doc_e,
+        I64 *_k,I64 left,I64 right_margin,I64 x,I64 y)
+{
+  CDocEntry *doc_e2;
+  I64 j,i=right_margin+1-(x+left),  //Space left on line
+        ii=x+1-doc_e->settings.left_margin;
+  if (IsEditableText(doc_e)) {
+    if (doc->cur_entry==doc_e->next) {
+      if (doc->cur_col==doc_e->next->min_col)
+        i--;
+    } else {
+      if (doc->cur_entry==doc_e && doc->cur_col==i)
+        i--;
+    }
+    if (*_k>i) {
+      for (j=i;j>8-ii && j>=0;j--)
+        if (doc_e->tag[j]==CH_SPACE || doc_e->tag[j]==CH_SHIFT_SPACE) {
+          i=j+1;
+          break;
+        }
+      if (0<i<*_k) {
+        DocSplitTag(doc,doc_e,i,x,y,DOCT_SOFT_NEW_LINE);
+        *_k=StrLen(doc_e->tag);
+        return NULL;
+      }
+    }
+    if (*_k==i)
+      return NULL;
+  }
+  if (*_k>=i) {
+    doc_e2=doc_e->last;
+    if (doc_e2->type_u8!=DOCT_SOFT_NEW_LINE &&
+          doc_e2->type_u8!=DOCT_NEW_LINE &&
+          doc_e2->type_u8!=DOCT_CURSOR_MOVEMENT) {
+      doc_e2=DocEntryNewBase(doc,DOCT_SOFT_NEW_LINE|doc_e->type&0xFFFFFF00,
+            DOCEF_WORD_WRAP|doc_e->de_flags&(DOCEF_HIGHLIGHT|DOCG_BL_IV_UL|
+            DOCEF_SKIP|DOCEF_FILTER_SKIP),x,y,doc_e->last->page_line_num);
+      MemCpy(&doc_e2->settings,&doc_e->settings,sizeof(CDocSettings));
+      QueIns(doc_e2,doc_e->last);
+      return doc_e2;
+    }
+  }
+  return NULL;
+}
+
+I64 DocTmpAttr(CDoc *doc,CDocEntry *doc_e,I64 cur_u8_attr)
+{
+  I64 tmp_u32_attr;
+  doc_e->de_flags=doc->flags& (DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT) |
+        doc_e->de_flags&~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT);
+  tmp_u32_attr=(cur_u8_attr&0xF0)<<8|
+        doc->flags&DOCG_BL_IV_UL|(doc_e->settings.shifted_x&0x1F)<<16|
+        (doc_e->settings.shifted_y&0x1F)<<21;
+  if (doc_e->de_flags & DOCEF_HAS_BIN && *doc_e->tag=='<')
+    tmp_u32_attr.u8[1]|=DOC_COLOR_BIN;
+  else
+    switch (doc_e->type_u8) {
+      case DOCT_SPRITE:
+        if (doc_e->de_flags & DOCEF_LEFT_EXP)
+          tmp_u32_attr.u8[1]|=cur_u8_attr&15;
+        else if (doc_e->de_flags & DOCEF_LINK)
+          tmp_u32_attr.u8[1]|=DOC_COLOR_LINK;
+        else if (doc_e->de_flags & DOCEF_LEFT_MACRO)
+          tmp_u32_attr.u8[1]|=DOC_COLOR_MACRO;
+        else if (doc_e->de_flags & (DOCEF_TREE|DOCEF_LST))
+          tmp_u32_attr.u8[1]|=DOC_COLOR_TREE;
+        else
+          tmp_u32_attr.u8[1]|=DOC_COLOR_BIN;
+        break;
+      case DOCT_HTML_CODE:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_BIN;
+        break;
+      case DOCT_LINK:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_LINK;
+        break;
+      case DOCT_MACRO:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_MACRO;
+        break;
+      case DOCT_ANCHOR:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_ANCHOR;
+        break;
+      case DOCT_TREE:
+      case DOCT_LST:
+        tmp_u32_attr.u8[1]|=DOC_COLOR_TREE;
+        break;
+      default:
+        tmp_u32_attr.u8[1]|=cur_u8_attr&15;
+    }
+  doc_e->type.u8[1]=tmp_u32_attr.u8[1];
+  tmp_u32_attr|=doc_e->type&0xFFFF0000;
+  if (doc_e==doc->cur_entry && !(doc->flags&DOCF_DONT_HIGHLIGHT_CURSOR) &&
+        doc_e->type_u8!=DOCT_TEXT)
+    tmp_u32_attr^=0xFF00;
+  doc_e->settings.final_u32_attr=tmp_u32_attr;
+  return tmp_u32_attr;
+}
+
+public Bool DocRecalc(CDoc *doc,I64 recalc_flags=RECALCt_NORMAL)
+{//Recalc and fmt.  Also used by WinMgr to draw on scrn.
+  I64 i,ii,j,k,x,x0,y,y0,D,d2,col,col2,best_col=0,best_d=I64_MAX,xx,yy,zz,
+        num_entries=0,i_jif,cur_u8_attr,tmp_u32_attr,
+        cursor_y=I64_MIN,left_margin,right_margin,y_plot_top,y_plot_bottom,
+        top,left,bottom,right,width,height,scroll_x,scroll_y,pix_top,pix_left;
+  CDocEntry reg *doc_e,reg *doc_e2,*best_doc_e,*next_clear_found=NULL,
+        *added_cursor=NULL;
+  CDocBin *tmpb;
+  CDocSettings *s;
+  Bool del_doc_e,skipped_update,tree_collapsed,same_win,more=FALSE,
+        find_cursor=FALSE,blink_flag,full_refresh=TRUE,unlock,clear_holds;
+  CTask *win_task,*mem_task;
+  CDC *dc;
+  U8 *bptr,*ptr,buf[STR_LEN],ch;
+  U32 *u32_ptr,*hl;
+  I32 *depth_buf=NULL;
+  F64 cur_time=tS;
+  CWinScroll *vss,*hss;
+  CHashDefineStr *tmph;
+
+  if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return FALSE;
+
+    //WinMgr updates all wins (30000.0/1001), 33.33333mS
+  if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN && doc->owning_task!=Fs) {
+    i_jif=cnts.jiffies+JIFFY_FREQ/250; //4 ms
+    while (Bt(&doc->locked_flags,DOClf_LOCKED)) {
+      if (cnts.jiffies>=i_jif)
+        return FALSE; //Bail-out if doc locked.
+      Yield;
+    }
+  }
+
+  unlock=DocLock(doc);
+  if (doc->doc_signature!=DOC_SIGNATURE_VAL) {
+    DocUnlock(doc);
+    return FALSE;
+  }
+
+  win_task=doc->win_task;
+  mem_task=doc->mem_task;
+  blink_flag=Blink;
+  dc=NULL;
+  switch [recalc_flags&RECALCG_MASK] {
+    case RECALCt_FIND_CURSOR:
+      find_cursor=TRUE;
+      if (win_task)
+        dc=DCAlias(gr.dc2,win_task); //Necessary for sprites
+      break;
+    case RECALCt_TO_SCRN:
+      if (doc->updates_cnt++%(ToI64(winmgr.fps/10)+1) &&
+            !Bt(&doc->flags,DOCf_DO_FULL_REFRESH) &&
+            !(doc->flags&DOCF_BWD_MOVEMENT))
+        full_refresh=FALSE;
+      if (win_task)
+        dc=DCAlias(gr.dc2,win_task);
+      break;
+  }
+
+  PUSHFD
+  CLI
+  left  =win_task->win_left;
+  right =win_task->win_right;
+  width =win_task->win_width;
+  scroll_x=win_task->scroll_x;
+  scroll_y=win_task->scroll_y;
+  top   =win_task->win_top;
+  bottom=win_task->win_bottom;
+  height=win_task->win_height;
+  pix_left  =win_task->pix_left;
+  pix_top   =win_task->pix_top;
+  left_margin=left;
+  right_margin=right;
+  POPFD
+  if (doc->flags&DOCF_BORDER_DOC) {
+    scroll_x=0;
+    scroll_y=0;
+  }
+  best_doc_e=doc->cur_entry;
+
+  if (!(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)) &&
+        FilesFindMatch(doc->filename.name,FILEMASK_SRC))
+    doc->flags|=DOCF_HIGHLIGHT;
+  else
+    doc->flags&=~DOCF_HIGHLIGHT;
+
+  x=y=0;
+  doc->page_line_num=0;
+  if (full_refresh && !find_cursor) {
+    doc->x=x;
+    doc->y=y;
+  }
+
+  hss=&win_task->horz_scroll;
+  vss=&win_task->vert_scroll;
+  if (doc->flags&DOCF_BORDER_DOC) {
+    doc->top_line_num=0;
+    doc->line_start_col=0;
+    recalc_flags&=~RECALCF_HAS_CURSOR;
+    if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN)
+      doc->settings_head.cur_text_attr=
+            doc->settings_head.dft_text_attr=win_task->border_attr;
+  } else {
+    if (recalc_flags&RECALCF_HAS_CURSOR && full_refresh) {
+      if (Bt(&hss->flags,WSSf_SET_TO_POS)||Bt(&vss->flags,WSSf_SET_TO_POS)) {
+        if (!(doc->flags&DOCF_NO_SCROLL_BARS)) {
+          if (Bt(&hss->flags,WSSf_SET_TO_POS)) {
+            doc->line_start_col=hss->pos;
+            LBtr(&hss->flags,WSSf_SET_TO_POS);
+          }
+          if (Bt(&vss->flags,WSSf_SET_TO_POS)) {
+            doc->top_line_num=vss->pos;
+            LBtr(&vss->flags,WSSf_SET_TO_POS);
+          }
+        }
+        doc->x=doc->line_start_col+width/2;
+        doc->y=doc->top_line_num+height/2;
+        find_cursor=TRUE;
+      }
+    }
+    if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN)
+      doc->settings_head.cur_text_attr=
+            doc->settings_head.dft_text_attr=win_task->text_attr;
+  }
+  x0=doc->line_start_col;
+  y0=doc->top_line_num;
+  same_win=top   ==doc->old_win_top &&
+        bottom==doc->old_win_bottom &&
+        left  ==doc->old_win_left &&
+        right ==doc->old_win_right &&
+        doc->cur_entry==doc->old_cur_entry &&
+        doc->cur_col==doc->old_cur_col;
+  if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN) {
+    y_plot_top=y0-scroll_y/FONT_HEIGHT;
+    y_plot_bottom=y0+height-1-scroll_y/FONT_HEIGHT;
+    if (!(doc->flags&DOCF_BORDER_DOC) &&
+          !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+      DocBorderLstDraw(doc);
+  }
+
+  if (doc->cur_col<=doc->cur_entry->min_col)
+    doc->cur_col=doc->cur_entry->min_col;
+  doc_e=doc->head.next;
+  doc_e->de_flags&=~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT);
+  if (doc_e==doc->head.next)
+    s=&doc->settings_head;
+  else
+    s=&doc_e->last->settings;
+  doc->flags=doc_e->de_flags& (DOCG_BL_IV_UL|DOCEF_WORD_WRAP) |
+        doc->flags&~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP);
+  cur_u8_attr=s->cur_text_attr;
+  if (doc_e==doc->head.next) {
+    doc->flags&=~DOCF_BWD_MOVEMENT;
+    if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN && full_refresh)
+      doc->flags&=~DOCF_HAS_SONG;
+  } else
+    doc->flags=doc_e->de_flags& DOCEF_HIGHLIGHT |
+          doc->flags&~DOCEF_HIGHLIGHT;
+
+  if (doc->head.next==doc) {
+    best_doc_e=doc;
+    best_col=0;
+    doc->cur_entry=doc;
+    doc->cur_col=0;
+    doc_e=doc;
+  }
+  skipped_update= doc_e==doc && doc->head.next!=doc;
+
+  if (full_refresh) {
+    doc->min_x=I32_MAX; doc->min_y=I32_MAX;
+    doc->max_x=I32_MIN; doc->max_y=I32_MIN;
+  }
+  while (doc_e!=doc) {
+    while (TRUE) {
+      del_doc_e=FALSE;
+      if (doc_e->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
+        doc_e2=doc_e;
+        goto rc_skip;
+      }
+      MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
+      s=&doc_e->settings;
+      if (doc_e->de_flags & (DOCEF_TAG_CB|DOCEF_DEFINE) &&
+            !(doc_e->de_flags & DOCEF_LST)) {
+        Free(doc_e->tag);
+        if (doc_e->de_flags & DOCEF_TAG_CB) {
+          if (doc_e->tag_cb)
+            doc_e->tag=(*doc_e->tag_cb)(doc,doc_e,mem_task);
+          else
+            doc_e->tag=StrNew("",mem_task);
+        } else {
+          if (tmph=HashFind(doc_e->define_str,
+                win_task->hash_table,HTT_DEFINE_STR))
+            doc_e->tag=StrNew(tmph->data,mem_task);
+          else
+            doc_e->tag=CAlloc(1,mem_task);
+        }
+        doc_e->max_col=StrLen(doc_e->tag);
+        if (doc->cur_entry==doc_e && doc->cur_col>=doc_e->max_col) {
+          if (doc_e->max_col)
+            doc->cur_col=doc_e->max_col-1;
+          else
+            doc->cur_col=0;
+        }
+      }
+      k=DocWordWrapDel(doc,doc_e,full_refresh,same_win,
+            left_margin,right_margin,&best_doc_e,&best_col);
+      if (doc_e->de_flags & (DOCEF_LEFT_X|DOCEF_RIGHT_X|DOCEF_CENTER_X|
+            DOCEF_TOP_Y|DOCEF_BOTTOM_Y|DOCEF_CENTER_Y))
+        DocRecalcXY(doc,doc_e,k,
+              left,width,height,left_margin,right_margin,x0,y0,&x,&y);
+      if (full_refresh && k>0 && doc->flags & DOCF_WORD_WRAP &&
+            (doc_e2=DocWordWrapAdd(doc,doc_e,&k,left,right_margin,x,y)))
+        doc_e=doc_e2;
+      else
+        break;
+    }
+
+    if (full_refresh) {
+      doc_e->x=x;
+      doc_e->y=y;
+      doc_e->page_line_num=doc->page_line_num;
+      if (x<doc->min_x) doc->min_x=x;
+      if (y<doc->min_y) doc->min_y=y;
+      if (find_cursor) {
+        D=DocCharDist(doc,x,y);
+        col=0;
+      }
+    }
+    col2=0;
+
+    tmp_u32_attr=DocTmpAttr(doc,doc_e,cur_u8_attr);
+    if (doc_e==doc->cur_entry) {
+      cursor_y=doc_e->y;
+      if (recalc_flags&RECALCF_ADD_CURSOR && !added_cursor) {
+        if (doc_e->type_u8==DOCT_TEXT && 0<doc->cur_col<k &&
+              !(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
+              DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
+              !(doc_e->type&DOCG_BL_IV_UL)) {
+          added_cursor=DocSplitTag(doc,doc_e,doc->cur_col,x,y,DOCT_CURSOR);
+          k=StrLen(doc_e->tag);
+        } else {
+          added_cursor=doc_e2=DocEntryNewBase(doc,
+                DOCT_CURSOR|doc_e->type&0xFFFFFF00,
+                doc_e->de_flags&~DOCEG_HAS_ARG,x,y,doc->page_line_num);
+          MemCpy(&doc_e2->settings,&doc_e->settings,sizeof(CDocSettings));
+          if (doc_e->type_u8==DOCT_TEXT && doc->cur_col>=k)
+            QueIns(doc_e2,doc_e);
+          else
+            QueInsRev(doc_e2,doc_e);
+        }
+      }
+    }
+
+    if (doc_e->de_flags & DOCEF_REFRESH_DATA &&
+          (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX ||
+          doc_e->de_flags & DOCEF_LST)) {
+      DocDataFmt(doc,doc_e);
+      k=StrLen(doc_e->tag);
+    }
+    if (doc_e->de_flags&DOCEF_TAG) {
+      ptr=doc_e->tag;
+      if (doc_e->de_flags & DOCEF_TREE) {
+        if (k>=2) {
+          if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+            *ptr++='+';
+          else
+            *ptr++='-';
+          *ptr++=']';
+          ptr=doc_e->tag;
+        }
+      } else if (doc_e->de_flags & DOCEF_HAS_BIN) {
+        if (*ptr=='<' && full_refresh && '0'<=ptr[1]<='9') {
+          ptr=MStrPrint("<%d>",doc_e->bin_num);
+          Free(doc_e->tag);
+          doc_e->tag=StrNew(ptr,mem_task);
+          Free(ptr);
+          ptr=doc_e->tag;
+          k=StrLen(ptr);
+        }
+      } else if (doc_e->type_u8==DOCT_CHECK_BOX) {
+        if (k>=3) {
+          *ptr++='[';
+          if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+            *ptr++='X';
+          else
+            *ptr++=CH_SPACE;
+          *ptr++=']';
+          ptr=doc_e->tag;
+        }
+      }
+      if (doc_e->de_flags & DOCEF_SCROLLING_X) {
+        j=StrLen(doc_e->tag);
+        if (j && doc_e->scroll_len) {
+          i_jif=ToI64(cur_time*FONT_WIDTH*DOC_SCROLL_SPEED)%(j*FONT_WIDTH);
+          tmp_u32_attr=tmp_u32_attr & 0xFFE0FF00|
+                (FONT_WIDTH-1-i_jif&(FONT_WIDTH-1))<<16;
+#assert FONT_WIDTH==8
+          i_jif>>=3;
+          for (k=0;k<doc_e->scroll_len;k++) {
+            ch=ptr[(i_jif+k)%j];
+            if (!Bt(char_bmp_displayable,ch)) ch='.';
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+              if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                    !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+              else
+                TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+            }
+            x++;
+          }
+        }
+        if (find_cursor)  {
+          D=DocCharDist(doc,doc_e->x,doc_e->y);
+          col=doc_e->min_col;
+        }
+        col2=doc_e->scroll_len; //TODO This is flawed
+      } else {
+        if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+              !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER)) {
+          while (ch=*ptr++) {
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW))
+              TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+            else
+              if (find_cursor) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D) {
+                  D=d2;
+                  col=col2;
+                }
+              }
+            col2++;
+            x++;
+          }
+        } else {
+          if (doc_e->type_u8==DOCT_TEXT && doc_e->de_flags&DOCEF_HIGHLIGHT)
+            hl=DocHighlight(doc_e,ptr,k,tmp_u32_attr);
+          else
+            hl=NULL;
+          if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+//Technically we should do this for scrolling_x, too.
+            if (y>y_plot_bottom)
+              more=TRUE;
+            else if (y>=y_plot_top) {
+              if (hl)
+                TextLenAttrStr(win_task,x-x0,y-y0,k,hl);
+              else
+                TextLenStr(win_task,x-x0,y-y0,k,tmp_u32_attr,ptr);
+            }
+            col2+=k;
+            x+=k;
+          } else {
+            if (find_cursor) {
+              while (k--) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D) {
+                  D=d2;
+                  col=col2;
+                }
+                col2++;
+                x++;
+              }
+            } else {
+              col2+=k;
+              x+=k;
+            }
+          }
+          Free(hl);
+        }
+      }
+    }
+    switch [doc_e->type_u8] {
+      case DOCT_TEXT:
+        if (!col2 && !(doc_e->de_flags
+              &(DOCEF_TREE|DOCEF_LST|DOCEF_TAG_CB|DOCEF_DEFINE|
+              DOCEF_AUX_STR|DOCEF_HTML_LINK|DOCEF_BIN_PTR_LINK)))
+          del_doc_e=TRUE;
+        break;
+      case DOCT_HEX_ED:
+        if (doc_e->de_flags&DOCEF_DEREF_DATA &&
+              !(doc_e->de_flags&DOCEF_REMALLOC_DATA))
+          bptr=doc_e->data;
+        else
+          bptr=&doc_e->data;
+        k=doc_e->hex_ed_width; //columns
+        for (i=0;i<doc_e->len;i+=k) {
+          if (doc_e->de_flags & DOCEF_ZERO_BASED)
+            StrPrint(buf,"%08tX ",i);
+          else
+            StrPrint(buf,"%08tX ",bptr);
+          ptr=buf;
+          while (ch=*ptr++) {
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+              if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                    !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+              else
+                TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+            }
+            if (find_cursor) {
+              d2=DocCharDist(doc,x,y);
+              if (d2<D) {
+                D=d2;
+                col=i*3;
+              }
+            }
+            x++;
+          }
+          if (i+k>doc_e->len) k=doc_e->len-i;
+          for (j=0;j<k;j++) {
+            StrPrint(buf,"%02tX",*bptr++);
+            ptr=buf;
+            while (ch=*ptr++) {
+              if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                    !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+                if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                      !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                  TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+                else
+                  TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+              }
+              if (find_cursor) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D) {
+                  D=d2;
+                  col=col2;
+                }
+              }
+              col2++;
+              x++;
+            }
+            x++;
+          }
+          bptr-=j;
+          x+=(doc_e->hex_ed_width-k)*3;
+          for (j=0;j<k;j++) {
+            ch=*bptr++;
+            if (!Bt(char_bmp_displayable,ch)) ch='.';
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+              if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+                    !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER))
+                TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+ch);
+              else
+                TextChar(win_task,FALSE,x-x0,y-y0,tmp_u32_attr+ch);
+            }
+            if (find_cursor) {
+              d2=DocCharDist(doc,x,y);
+              if (d2<D) {
+                D=d2;
+                col=col2;
+              }
+            }
+            col2++;
+            x++;
+          }
+          y++;
+          x-=doc_e->hex_ed_width*3+k+9;
+        }
+        break;
+      case DOCT_NEW_LINE:
+      case DOCT_SOFT_NEW_LINE:
+        if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+              !(doc_e->de_flags&DOCEF_DONT_DRAW)&&
+              y_plot_top<=y<=y_plot_bottom)
+          TextLenAttr(win_task,x-x0,y-y0,width-(x-x0),cur_u8_attr<<8);
+        if (doc_e->de_flags&DOCEF_HIGHLIGHT && s->state==DOCSS_CPP_Z_COMMENT)
+          s->state=DOCSS_NORMAL;
+        y++;
+        doc->page_line_num++;
+rc_start_of_line:
+        if (s->left_margin==DOC_DFT)
+          x=s->indent;
+        else
+          x=s->indent+s->left_margin;
+rc_adjust_xy:
+        i=s->indent+s->left_margin;
+        if (x<i)
+          x=i;
+        if (doc->page_line_num<0)
+          doc->page_line_num=s->page_len+doc->page_line_num%s->page_len;
+        else {
+          if (doc->page_line_num>=s->page_len) {
+            doc->page_line_num-=s->page_len;
+            if (doc->page_line_num>=s->page_len) //avoid extra divide
+              doc->page_line_num=doc->page_line_num%s->page_len;
+          }
+        }
+        if (s->header!=DOC_DFT) {
+          if (doc->page_line_num<s->header) {
+            y+=s->header-doc->page_line_num;
+            doc->page_line_num=s->header;
+            goto rc_start_of_line;
+          }
+        }
+        if (s->footer==DOC_DFT) {
+          if (doc->page_line_num>=s->page_len) {
+            if (s->header==DOC_DFT)
+              doc->page_line_num=0;
+            else {
+              doc->page_line_num=s->header;
+              y+=s->header;
+            }
+            goto rc_start_of_line;
+          }
+        } else {
+          if (doc->page_line_num>=s->page_len-s->footer) {
+            y+=s->footer;
+            if (s->header==DOC_DFT)
+              doc->page_line_num=0;
+            else {
+              doc->page_line_num=s->header;
+              y+=s->header;
+            }
+            goto rc_start_of_line;
+          }
+        }
+        break;
+      case DOCT_TAB:
+        k=(x+8) & ~7;
+        if (doc_e->de_flags & DOCEF_BORDER_PLOT &&
+              !Bt(&win_task->display_flags,DISPLAYf_NO_BORDER)) {
+          while (x<k) {
+            if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                  !(doc_e->de_flags&DOCEF_DONT_DRAW))
+              TextChar(win_task,TRUE,x-x0,y-y0,tmp_u32_attr+CH_SPACE);
+            if (find_cursor) {
+              d2=DocCharDist(doc,x,y);
+              if (d2<D)
+                D=d2;
+            }
+            x++;
+          }
+        } else {
+          k-=x;
+          if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+                !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+            if (y_plot_top<=y<=y_plot_bottom)
+              TextLenStr(win_task,x-x0,y-y0,k,tmp_u32_attr,"        ");
+            x+=k;
+          } else {
+            if (find_cursor) {
+              while (k--) {
+                d2=DocCharDist(doc,x,y);
+                if (d2<D)
+                  D=d2;
+                x++;
+              }
+            } else
+              x+=k;
+          }
+        }
+        break;
+      case DOCT_PAGE_BREAK:
+        doc->flags|=DOCF_BWD_MOVEMENT;
+        y+=s->page_len-doc_e->page_line_num;
+        doc->page_line_num=0;
+        goto rc_start_of_line;
+      case DOCT_CURSOR:
+        if (!find_cursor && !(doc->flags & DOCF_NO_CURSOR)) {
+          doc->cur_entry=doc_e->next;
+          doc->cur_col=doc->cur_entry->min_col;
+        }
+        if (doc_e!=added_cursor)
+          del_doc_e=TRUE;
+        break;
+      case DOCT_PMT:
+        cur_u8_attr=cur_u8_attr&0xF0|DOC_COLOR_PMT;
+        if (y==cursor_y) {
+          doc->cur_entry=doc_e->next;
+          doc->cur_col=doc->cur_entry->min_col;
+        }
+        break;
+      case DOCT_CLEAR:
+        next_clear_found=doc_e;
+        if (doc_e->de_flags&DOCEF_HOLD)
+          clear_holds=TRUE;
+        else
+          clear_holds=FALSE;
+        break;
+      case DOCT_PAGE_LEN:
+        s->page_len=doc_e->attr;
+        if (doc_e->de_flags & DOCEF_WIN_REL)
+          s->page_len+=height;
+        goto rc_adjust_xy;
+      case DOCT_LEFT_MARGIN:
+        i=doc_e->attr;
+        left_margin=left+i;
+        s->left_margin=i;
+        goto rc_start_of_line;
+      case DOCT_RIGHT_MARGIN:
+        if (doc_e->de_flags & DOCEF_WIN_REL)
+          i=width-1-doc_e->attr;
+        else
+          i=doc_e->attr;
+        right_margin=left+i;
+        s->right_margin=i;
+        goto rc_adjust_xy;
+      case DOCT_HEADER:
+        s->header=doc_e->attr;
+        goto rc_adjust_xy;
+      case DOCT_FOOTER:
+        s->footer=doc_e->attr;
+        goto rc_adjust_xy;
+      case DOCT_INDENT:
+        if (doc_e->de_flags & DOCEF_LEFT_X)
+          i=doc_e->attr;
+        else
+          i=s->indent+doc_e->attr;
+        s->indent=i;
+        goto rc_start_of_line;
+      case DOCT_FOREGROUND:
+        cur_u8_attr&=0xF0;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0x0F;
+        else
+          cur_u8_attr|=doc_e->attr;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_BACKGROUND:
+        cur_u8_attr&=0x0F;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0xF0;
+        else
+          cur_u8_attr|=doc_e->attr<<4;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_DFT_FOREGROUND:
+        cur_u8_attr&=0xF0;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0xF;
+        else
+          cur_u8_attr|=doc_e->attr;
+        s->dft_text_attr=s->dft_text_attr&0xF0|cur_u8_attr&0x0F;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_DFT_BACKGROUND:
+        cur_u8_attr&=0x0F;
+        if (doc_e->attr==DOC_DFT)
+          cur_u8_attr|=s->dft_text_attr&0xF0;
+        else
+          cur_u8_attr|=doc_e->attr<<4;
+        s->dft_text_attr=s->dft_text_attr&0x0F|cur_u8_attr&0xF0;
+        s->cur_text_attr=cur_u8_attr;
+        break;
+      case DOCT_WORD_WRAP:
+        if (doc_e->attr)
+          doc->flags|=DOCF_WORD_WRAP;
+        else
+          doc->flags&=~DOCF_WORD_WRAP;
+        break;
+      case DOCT_HIGHLIGHT:
+        if (doc_e->attr)
+          doc->flags|=DOCF_HIGHLIGHT;
+        else
+          doc->flags&=~DOCF_HIGHLIGHT;
+        break;
+      case DOCT_BLINK:
+        if (doc_e->attr)
+          doc->flags|=DOCF_BLINK;
+        else
+          doc->flags&=~DOCF_BLINK;
+        break;
+      case DOCT_INVERT:
+        if (doc_e->attr)
+          doc->flags|=DOCF_INVERT;
+        else
+          doc->flags&=~DOCF_INVERT;
+        break;
+      case DOCT_UNDERLINE:
+        if (doc_e->attr)
+          doc->flags|=DOCF_UNDERLINE;
+        else
+          doc->flags&=~DOCF_UNDERLINE;
+        break;
+      case DOCT_SHIFTED_X:
+        s->shifted_x=doc_e->attr;
+        break;
+      case DOCT_SHIFTED_Y:
+        s->shifted_y=doc_e->attr;
+        break;
+      case DOCT_CURSOR_MOVEMENT:
+        doc->flags|=DOCF_BWD_MOVEMENT;
+        x+=doc_e->cursor_x_offset;
+        if (doc_e->de_flags & DOCEF_PAGE_REL_Y) {
+          i=doc->page_line_num;
+          if (doc_e->de_flags & DOCEF_TOP_Y)
+            doc->page_line_num=0;
+          else if (doc_e->de_flags & DOCEF_BOTTOM_Y)
+            doc->page_line_num=s->page_len-1;
+          else if (doc_e->de_flags & DOCEF_CENTER_Y)
+            doc->page_line_num=s->page_len>>1;
+          y+=doc->page_line_num-i;
+        }
+        y+=doc_e->cursor_y_offset;
+        doc->page_line_num+=doc_e->cursor_y_offset;
+        goto rc_adjust_xy;
+      case DOCT_SPRITE:
+        if (!doc_e->bin_data && doc->flags&DOCEF_HAS_BIN)
+          doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num);
+        if ((tmpb=doc_e->bin_data) &&
+              !tmpb->tag && doc_e->tag && *doc_e->tag)
+          tmpb->tag=StrNew(doc_e->tag,mem_task);
+        if (tmpb && dc) {
+          DCRst(dc);
+          dc->flags&=~(DCF_DONT_DRAW|DCF_LOCATE_NEAREST);
+          if (recalc_flags&RECALCG_MASK!=RECALCt_TO_SCRN ||
+                doc_e->de_flags&DOCEF_DONT_DRAW)
+            dc->flags|=DCF_DONT_DRAW;
+          bptr=tmpb->data;
+          ii=SpriteTypeMask(bptr);
+          if (ii&1<<SPT_TYPES_NUM) {
+            bptr=gr.empty_sprite;
+            ii=SpriteTypeMask(bptr);
+          }
+          if (ii&(1<<SPT_FLOOD_FILL|1<<SPT_FLOOD_FILL_NOT))
+            i=cur_u8_attr>>4 &0xF ^ win_task->text_attr>>4 & 0xF;
+          else {
+            i=tmp_u32_attr>>12&0xF ^ win_task->text_attr>>4 & 0xF;
+            if (tmp_u32_attr & DOCET_SEL)
+              i^=0xF;
+            if (tmp_u32_attr & DOCET_INVERT)
+              i^=0xF;
+            if (blink_flag &&
+                  (doc_e==doc->cur_entry || tmp_u32_attr&DOCET_BLINK))
+              i^=0xF;
+          }
+          dc->color=i;
+          if (find_cursor)
+            dc->flags|=DCF_LOCATE_NEAREST;
+          dc->cur_x=(doc->x-x0)*FONT_WIDTH+pix_left+scroll_x;
+          dc->cur_y=(doc->y-y0)*FONT_HEIGHT+pix_top+scroll_y;
+          dc->cur_z=0;
+          dc->bkcolor=i;
+          if (doc_e->de_flags & DOCEF_FROM_START) {
+            xx=(x-k-x0)*FONT_WIDTH; //TODO: scrolling text is not length k
+            yy=(y-y0)*FONT_HEIGHT;
+            zz=0;
+          } else {
+            xx=(x-x0)*FONT_WIDTH;
+            yy=(y-y0)*FONT_HEIGHT;
+            zz=0;
+          }
+          if (ii&(1<<SPT_MESH|1<<SPT_SHIFTABLE_MESH)) {
+            if (!depth_buf) {
+              DCDepthBufAlloc(dc);
+              depth_buf=dc->depth_buf;
+            } else
+              dc->depth_buf=depth_buf;
+            Mat4x4IdentEqu(dc->r);
+            Mat4x4RotZ(dc->r,cur_time*3.1);
+            Mat4x4RotY(dc->r,cur_time*1.9);
+            Mat4x4RotX(dc->r,cur_time);
+            dc->flags|=DCF_TRANSFORMATION;
+            dc->x=xx;
+            dc->y=yy;
+            dc->z=GR_Z_ALL;
+            xx=0; yy=0; zz=0;
+          }
+          Sprite3(dc,xx,yy,zz,bptr);
+          dc->depth_buf=NULL;
+          dc->flags&=~(DCF_LOCATE_NEAREST|DCF_DONT_DRAW|DCF_TRANSFORMATION);
+          if (dc->nearest_dist<=D) {
+            D=dc->nearest_dist;
+            col=doc_e->min_col;
+          }
+        }
+        break;
+      case DOCT_SONG:
+        if (sys_focus_task==win_task &&
+              recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+              !(doc_e->de_flags&DOCEF_DONT_DRAW)) {
+          if (doc_e->aux_str &&
+                (!music.cur_song || StrCmp(music.cur_song,doc_e->aux_str))) {
+            Free(music.cur_song);
+            MusicSettingsRst;
+            music.cur_song=AStrNew(doc_e->aux_str);
+          }
+        }
+        doc->flags|=DOCF_HAS_SONG;
+        break;
+      case DOCT_HTML_CODE:
+        if (recalc_flags&RECALCF_TO_HTML &&
+              doc_e->de_flags&DOCEF_TAG && doc_e->tag)
+          x-=StrLen(doc_e->tag);
+        break;
+      case DOCT_TYPES_NUM-1: //nobound switch
+      default:
+        break;
+    }
+
+    if (doc_e->de_flags & DOCEF_HAS_BORDER)
+      TextBorder(win_task,doc_e->x-x0,x-x0-1,doc_e->y-y0,y-y0,
+            tmp_u32_attr.u8[1],ToBool(doc_e->de_flags & DOCEF_SOLID_BORDER));
+    if (full_refresh) {
+      switch (doc_e->type_u8) {
+        case DOCT_CHECK_BOX:
+          doc_e->max_col=2;
+          break;
+        case DOCT_LST:
+        case DOCT_TREE:
+        case DOCT_BTTN:
+        case DOCT_LINK:
+        case DOCT_MENU_VAL:
+        case DOCT_MACRO:
+          doc_e->max_col=1;
+          break;
+        default:
+          if (doc_e->de_flags & (DOCEF_TREE|DOCEF_LST))
+            doc_e->max_col=1;
+          else
+            doc_e->max_col=col2;
+      }
+
+      if (x>doc->max_x) doc->max_x=x;
+      if (y>doc->max_y) doc->max_y=y;
+      if (D<=best_d && !(doc_e->de_flags&DOCEF_NO_CLICK_ON)) {
+        best_d=D;
+        best_doc_e=doc_e;
+        best_col=col;
+      }
+      if (doc_e->de_flags & DOCEF_TREE) {
+        if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
+          tree_collapsed=TRUE;
+        else
+          tree_collapsed=FALSE;
+        doc_e2=doc_e->next;
+        while (doc_e2!=doc && doc_e2->type_u8!=DOCT_INDENT &&
+              !(doc_e2->de_flags & DOCEF_TREE))
+          doc_e2=doc_e2->next;
+        if (doc_e2->type_u8==DOCT_INDENT) {
+          j=i=s->indent;
+          do {
+            if (tree_collapsed)
+              doc_e2->de_flags|=DOCEF_SKIP;
+            else
+              doc_e2->de_flags&=~DOCEF_SKIP;
+            if (doc_e2->type_u8==DOCT_INDENT) {
+              if (doc_e2->de_flags & DOCEF_LEFT_X)
+                j=doc_e2->attr;
+              else
+                j+=doc_e2->attr;
+            }
+            doc_e2=doc_e2->next;
+          } while (doc_e2!=doc && j>i);
+        }
+      }
+    }
+
+    doc_e2=doc_e->next;
+rc_skip:
+    while (doc_e2!=doc && doc_e2->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
+      if (doc_e2==doc->cur_entry) {
+        doc->cur_entry=doc_e2->next;
+        doc->cur_col=doc->cur_entry->min_col;
+      }
+      if (full_refresh) {
+        doc_e2->x=x;
+        doc_e2->y=y;
+        doc_e2->page_line_num=doc->page_line_num;
+        MemCpy(&doc_e2->settings,s,sizeof(CDocSettings));
+        doc_e2->type.u8[1]=cur_u8_attr;
+        doc_e2->de_flags=doc->flags
+              &(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT) |
+              doc_e2->de_flags&~(DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT);
+      }
+      doc_e2=doc_e2->next;
+    }
+
+    if (full_refresh) {
+      if (del_doc_e) {
+        if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))) {
+          if (doc_e==doc->cur_entry) {
+            doc->cur_entry=doc_e2;
+            doc->cur_col=doc_e2->min_col;
+          }
+          if (best_doc_e==doc_e) {
+            best_doc_e=doc_e2;
+            best_col=doc_e2->min_col;  //TODO: might be bug
+          }
+          DocEntryDel(doc,doc_e);
+        }
+      }
+    }
+    num_entries++;
+    if (!full_refresh && doc_e->y>y_plot_bottom)
+      break;
+    doc_e=doc_e2;
+  }
+
+  if (full_refresh) {
+    if (doc->cur_entry==doc && recalc_flags&RECALCF_ADD_CURSOR) {
+      doc_e2=DocEntryNewBase(doc,DOCT_CURSOR,,x,y,doc->page_line_num);
+      MemCpy(&doc_e2->settings,s,sizeof(CDocSettings));
+      QueInsRev(doc_e2,doc);
+    }
+
+    if (doc->min_x>doc->max_x) {
+      doc->max_x=0;
+      doc->min_x=0;
+    }
+    if (doc->min_y>doc->max_y) {
+      doc->max_y=0;
+      doc->min_y=0;
+    }
+
+    //Update header
+    if (!skipped_update) {
+      doc_e->x=x;
+      doc_e->y=y;
+      doc_e->page_line_num=doc->page_line_num;
+      MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
+      doc_e->type.u8[1]=cur_u8_attr;
+      if (find_cursor) {
+        D=DocCharDist(doc,x,y);
+        if (D<best_d && !(doc_e->de_flags&DOCEF_NO_CLICK_ON)) {
+          best_d=D;
+          best_doc_e=doc_e;
+          best_col=0;
+        }
+      }
+    }
+    if (doc->flags & DOCF_SIZE_MIN) {
+      if (Bt(&win_task->display_flags,DISPLAYf_NO_BORDER)) {
+        if (left<0)
+          left=0;
+        i=left+doc->max_x-doc->min_x;
+        if (i>TEXT_COLS-1)
+          i=TEXT_COLS-1;
+        WinHorz(left,i,win_task);
+        if (top<0)
+          top=0;
+        i=top+doc->max_y-doc->min_y;
+        if (i>TEXT_ROWS-1)
+          i=TEXT_ROWS-1;
+        WinVert(top,i,win_task);
+      } else {
+        if (left<1)
+          left=1;
+        i=left+doc->max_x-doc->min_x;
+        if (i>TEXT_COLS-2)
+          i=TEXT_COLS-2;
+        WinHorz(left,i,win_task);
+        if (top<1)
+          top=1;
+        i=top+doc->max_y-doc->min_y;
+        if (i>TEXT_ROWS-2)
+          i=TEXT_ROWS-2;
+        WinVert(top,i,win_task);
+      }
+    }
+    if (find_cursor) {
+      doc->cur_entry=best_doc_e;
+      doc->cur_col=best_col;
+      DocFormBwd(doc);
+//We need this because text coordinates are used
+      if (best_d<FONT_WIDTH)
+        best_d=0;
+      doc->best_d=best_d;
+    }
+
+    if (doc->cur_entry->type_u8!=DOCT_HEX_ED) {
+      doc->y=doc->cur_entry->y;
+      doc->x=doc->cur_entry->x+doc->cur_col;
+    } else {
+      doc->y=doc->cur_entry->y+doc->cur_col/3/doc->cur_entry->hex_ed_width;
+      x=doc->cur_col%(doc->cur_entry->hex_ed_width*3);
+      i=x/doc->cur_entry->hex_ed_width;
+      doc->x=doc->cur_entry->x+9;
+      if (i<2)
+        doc->x+=x>>1*3+x&1;
+      else
+        doc->x+=doc->cur_entry->hex_ed_width*3+
+              (x-doc->cur_entry->hex_ed_width<<1);
+    }
+    doc->line=doc->y+1;
+    doc->col=doc->x+1;
+
+    if (recalc_flags&RECALCF_HAS_CURSOR) {
+      if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN) {
+        x=0;
+        y=0;
+      } else {
+        x=scroll_x/FONT_WIDTH;
+        y=scroll_y/FONT_HEIGHT;
+      }
+      if (doc->top_line_num-y+height-1>doc->max_y)
+        doc->top_line_num=doc->max_y-(height-1)+y;
+      if (doc->top_line_num-y<doc->min_y)
+        doc->top_line_num=doc->min_y+y;
+
+      if (doc->y-doc->top_line_num+y>height-1)
+        doc->top_line_num=doc->y-(height-1)+y;
+      if (doc->y-doc->top_line_num+y<0)
+        doc->top_line_num=doc->y+y;
+
+      if (doc->line_start_col-x+width-1>doc->max_x)
+        doc->line_start_col=doc->max_x-(width-1)+x;
+      if (doc->line_start_col-x<doc->min_x)
+        doc->line_start_col=doc->min_x+x;
+
+      if (doc->x-doc->line_start_col+x>width-1)
+        doc->line_start_col=doc->x-(width-1)+x;
+      if (doc->x-doc->line_start_col+x<0)
+        doc->line_start_col=doc->x+x;
+    }
+  }
+  if (recalc_flags&RECALCG_MASK==RECALCt_TO_SCRN &&
+        recalc_flags&RECALCF_HAS_CURSOR) {
+    x=doc->x-doc->line_start_col+left +scroll_x/FONT_WIDTH;
+    y=doc->y-doc->top_line_num+top+scroll_y/FONT_HEIGHT;
+    if (0<=x<=right && 0<=y<=bottom &&
+          x<TEXT_COLS && y<TEXT_ROWS &&
+          !(doc->flags&DOCF_HIDE_CURSOR)) {
+      u32_ptr=gr.text_base+y*TEXT_COLS+x;
+      *u32_ptr|=DOCET_BLINK;
+      *u32_ptr^=0xFF00;
+    }
+    if (full_refresh) {
+      if (!(doc->flags&DOCF_NO_SCROLL_BARS)) {
+        if (!Bt(&hss->flags,WSSf_SET_TO_POS)) {
+          hss->min=doc->min_x;
+          if (doc->max_x-width+1<hss->min)
+            hss->max=hss->min;
+          else
+            hss->max=doc->max_x-width+1;
+          hss->pos=doc->line_start_col;
+        }
+        if (!Bt(&vss->flags,WSSf_SET_TO_POS)) {
+          vss->min=doc->min_y;
+          if (doc->max_y-height+1<vss->min)
+            vss->max=vss->min;
+          else
+            vss->max=doc->max_y-height+1;
+          vss->pos=doc->top_line_num;
+        }
+      }
+      LBEqu(&doc->flags,DOCf_MORE,more);
+    }
+  }
+  if (!same_win) {
+    doc->old_win_top=top;
+    doc->old_win_bottom=bottom;
+    doc->old_win_left=left;
+    doc->old_win_right=right;
+    doc->old_cur_entry=doc->cur_entry;
+    doc->old_cur_col=doc->old_cur_col;
+  }
+  if (doc->flags & DOCF_HAS_SONG)
+    LBts(&win_task->task_flags,TASKf_HAS_SONG);
+  if (full_refresh) {
+    i=num_entries-doc->max_entries;
+    if (next_clear_found) {
+      DocDelToEntry(doc,next_clear_found,clear_holds);
+      DocRecalc(doc,recalc_flags);
+    } else if (i>1024) {
+      DocDelToNum(doc,i);
+      DocRecalc(doc,recalc_flags);
+    }
+  }
+  DCDel(dc);
+  Free(depth_buf);
+  if (unlock)
+    DocUnlock(doc);
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocRecalcLib.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocRecalcLib.HC.HTML new file mode 100755 index 0000000..8531126 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocRecalcLib.HC.HTML @@ -0,0 +1,244 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+I64 DocCharDist(CDoc *doc,I64 x,I64 y)
+{
+#assert FONT_WIDTH==FONT_HEIGHT
+  return (SqrI64(doc->x-x)+SqrI64(doc->y-y))*FONT_WIDTH*FONT_WIDTH;
+}
+
+U0 DocDelToNum(CDoc *doc,I64 num)
+{
+  CDocEntry *doc_e=doc->head.next,*doc_e2;
+  while (num-->0 && doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))) {
+      if (doc_e==doc->cur_entry) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc_e2->min_col;
+      }
+      DocEntryDel(doc,doc_e);
+    }
+    doc_e=doc_e2;
+  }
+}
+
+U0 DocDelToEntry(CDoc *doc,CDocEntry *clear_entry,Bool clear_holds)
+{
+  CDocEntry *doc_e=doc->head.next,*doc_e2;
+  while (doc_e!=doc) {
+    doc_e2=doc_e->next;
+    if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))||clear_holds) {
+      if (doc_e==doc->cur_entry) {
+        doc->cur_entry=doc_e2;
+        doc->cur_col=doc_e2->min_col;
+      }
+      DocEntryDel(doc,doc_e);
+    }
+    if (doc_e==clear_entry)
+      break;
+    doc_e=doc_e2;
+  }
+}
+
+U0 DocBorderLstDraw(CDoc *doc)
+{
+  CTask *win_task=doc->win_task;
+  I64 i,y=-1,attr=win_task->border_attr<<8;
+  U64 ch;
+  CDoc *tmpl=doc;
+  CD3I64 saved_scroll;
+  while (tmpl && tmpl->doc_signature==DOC_SIGNATURE_VAL) {
+    y+=(Bsr(tmpl->desc)+7)>>3+1; //StrLen+1
+    tmpl=tmpl->parent_doc;
+  }
+  tmpl=doc;
+  if (y>win_task->win_height)
+    y=win_task->win_height;
+  WinScrollNull(win_task,&saved_scroll);
+  while (tmpl && tmpl->doc_signature==DOC_SIGNATURE_VAL) {
+    ch=tmpl->desc;
+    i=(Bsr(ch)+7)>>3;   //StrLen
+    ch=EndianI64(ch<<((8-i)<<3));
+    attr=win_task->border_attr<<8;
+    while (i-- && y>0) {
+      TextChar(win_task,TRUE,-1,--y,attr+ch&0xFF);
+      ch>>=8;
+    }
+    y--;
+    tmpl=tmpl->parent_doc;
+  }
+  WinScrollRestore(win_task,&saved_scroll);
+}
+
+public U0 DocTop(CDoc *doc=NULL)
+{//Move cursor, cur_entry, to top.
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  doc->cur_entry=doc->head.next;
+  doc->cur_col=doc->cur_entry->min_col;
+  doc->x=0;
+  doc->y=0;
+  doc->line_start_col=0;
+  doc->top_line_num=0;
+
+  DocFormFwd(doc);
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocCenter(CDoc *doc=NULL,I64 recalc_flags=RECALCt_NORMAL)
+{//Center win on doc cursor, cur_entry.
+  Bool unlock;
+  CTask *task;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  task=doc->win_task;
+  DocRecalc(doc,recalc_flags);
+  if (!(doc->flags&DOCF_BORDER_DOC))
+    doc->top_line_num=doc->y-(task->win_height+1)>>1;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocBottom(CDoc *doc=NULL)
+{//Move cursor, cur_entry, to bottom.
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  doc->cur_entry=doc;
+  doc->cur_col=0;
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public U0 DocClear(CDoc *doc=NULL,Bool clear_holds=FALSE)
+{//Clear all doc entries, except +H, hold entries.
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  DocBottom(doc);
+  if (clear_holds)
+    DocPrint(doc,"$CL+H$");
+  else
+    DocPrint(doc,"$CL$");
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+public Bool DocCursor(Bool show=OFF,CDoc *doc=NULL)
+{//Show or hide cursor.
+  if (!doc && !(doc=DocPut))
+    return FALSE;
+  return !LBEqu(&doc->flags,DOCf_HIDE_CURSOR,!show);
+}
+
+public Bool DocHighlightCursor(Bool show=OFF,CDoc *doc=NULL)
+{//Highlight or Don't highlight cursor.
+  if (!doc && !(doc=DocPut))
+    return FALSE;
+  return !LBEqu(&doc->flags,DOCf_DONT_HIGHLIGHT_CURSOR,!show);
+}
+
+public Bool DocScroll(Bool val=OFF,CDoc *doc=NULL)
+{//Turn scroll bars OFF/ON.
+  if (!doc && !(doc=DocPut))
+    return FALSE;
+  return !LBEqu(&doc->flags,DOCf_NO_SCROLL_BARS,!val);
+}
+
+public U0 DocCollapse(Bool collapse=TRUE,CDoc *doc=NULL)
+{//Collapse or uncollapse all tree widgets.
+  CDocEntry *doc_e;
+  Bool unlock;
+  if (!doc && !(doc=DocPut))
+    return;
+  unlock=DocLock(doc);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->de_flags&DOCEF_TREE)
+      BEqu(&doc_e->de_flags,DOCEf_CHECKED_COLLAPSED,collapse);
+    doc_e=doc_e->next;
+  }
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+}
+
+#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
+public I64 DocMax(I64 i=I64_MAX)
+{//Set max document entries. (Cmd line buffer size.)
+//Adjusts the size of the cmd line buf.
+  //Normally, the cmd line deletes entries
+  //when more are added and the old scroll up.
+  //See max_entries.
+  I64 res;
+  CDoc *doc;
+  if (doc=DocPut) {
+    res=doc->max_entries;
+    doc->max_entries=i;
+    return res;
+  } else
+    return 0;
+}
+
+#help_index "DolDoc/Task;StdOut/Task"
+U0 DocUpdateTaskDocs(CTask *task)
+{//This is called from GrUpdateTaskWin() by the winmgr at 30fps.
+  CDoc *doc;
+  CD3I64 saved_scroll;
+  if (task->border_src==BDS_CUR_DRV && task->cur_dv)
+    task->border_attr=DrvTextAttrGet(Drv2Let(task->cur_dv));
+  if (task->title_src==TTS_TASK_NAME)
+    StrCpy(task->task_title,task->task_name);
+  if ((doc=DocDisplay(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
+    if (task->border_src==BDS_ED_FILENAME_DRV)
+      task->border_attr=DrvTextAttrGet(*doc->filename.name);
+    if (task->title_src==TTS_ED_FILENAME)
+      MemCpy(task->task_title,doc->filename.name,STR_LEN-1);
+    DocRecalc(doc,RECALCt_TO_SCRN|RECALCF_HAS_CURSOR);
+  }
+  if ((doc=DocBorder(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
+    WinScrollNull(task,&saved_scroll);
+    DocRecalc(doc,RECALCt_TO_SCRN);
+    WinScrollRestore(task,&saved_scroll);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocRun.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocRun.HC.HTML new file mode 100755 index 0000000..54fffcc --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocRun.HC.HTML @@ -0,0 +1,134 @@ + + + + + + + + + + + +
+#help_index "DolDoc"
+
+public I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,
+        Bool exited,I64 *_has_action=NULL)
+{//Do action on final entry sel by user.
+//Sometimes returns locked, sometimes unlocked
+  U8 ch=doc->cmd_U8,*st;
+  I64 res=DOCM_CANCEL,has_action=FALSE;
+  CHashDefineStr *tmph;
+  DocLock(doc);
+  if (!exited) {
+    if (doc_e->de_flags & DOCEF_ESC) {
+      Msg(MSG_KEY_DOWN,CH_ESC,0,1<<JOBf_DONT_FILTER);
+      has_action=TRUE;
+      goto er_done;
+    } if (doc_e->de_flags & DOCEF_QUIT) {
+      Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0,1<<JOBf_DONT_FILTER);
+      has_action=TRUE;
+      goto er_done;
+    } else if (doc_e->de_flags & DOCEF_CHECK_COLLAPSABLE) {
+      doc_e->de_flags^=DOCEF_CHECKED_COLLAPSED;
+      has_action=TRUE;
+    }
+  }
+  try {
+    if (ch==CH_SPACE) {
+      if (doc_e->de_flags & DOCEF_LINK && doc->left_click_link) {
+        res=(*doc->left_click_link)(doc,doc_e);
+        has_action=TRUE;
+      }
+      if (doc_e->de_flags & DOCEF_LEFT_EXP) {
+        res=doc_e->left_exp;
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_LEFT_CB && doc_e->left_cb) {
+        DocUnlock(doc);
+        res=(*doc_e->left_cb)(doc,doc_e);
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_LEFT_MACRO) {
+        if (doc_e->de_flags & DOCEF_POPUP) {
+          st=StrNew(doc_e->left_macro);
+          DocUnlock(doc);
+          PopUp(st,Fs);
+          Free(st);
+        } else {
+          if (doc_e->de_flags & DOCEF_LEFT_IN_STR)
+            InStr("%s",doc_e->left_macro);
+          else
+            In("%s",doc_e->left_macro);
+        }
+        has_action=TRUE;
+      }
+      if (!exited && doc_e->de_flags & DOCEF_LST &&
+            doc_e->de_flags & DOCEF_DEFINE &&
+            (tmph=HashFind(doc_e->define_str,
+            doc->win_task->hash_table,HTT_DEFINE_STR)) &&
+            (res=PopUpPickLst(tmph->data))!=DOCM_CANCEL) {
+        DocDataFmt(doc,doc_e,res);
+        DocDataScan(doc,doc_e);
+        has_action=TRUE;
+      }
+    } else if (ch=='\n') {
+      if (doc_e->de_flags & DOCEF_LINK && doc->right_click_link) {
+        res=(*doc->right_click_link)(doc,doc_e);
+        has_action=TRUE;
+      }
+      if (doc_e->de_flags & DOCEF_RIGHT_EXP) {
+        res=doc_e->right_exp;
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_RIGHT_CB && doc_e->right_cb) {
+        DocUnlock(doc);
+        res=(*doc_e->right_cb)(doc,doc_e);
+        has_action=TRUE;
+        Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
+      }
+      if (doc_e->de_flags & DOCEF_RIGHT_MACRO) {
+        if (doc_e->de_flags & DOCEF_POPUP) {
+          st=StrNew(doc_e->right_macro);
+          DocUnlock(doc);
+          PopUp(st,Fs);
+          Free(st);
+        } else {
+          if (doc_e->de_flags & DOCEF_RIGHT_IN_STR)
+            InStr("%s",doc_e->right_macro);
+          else
+            In("%s",doc_e->right_macro);
+        }
+        has_action=TRUE;
+      }
+    }
+  }
+  catch
+    DocBottom(doc);
+  doc->cmd_U8=CH_SPACE;
+er_done:
+  if (_has_action) *_has_action=has_action;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocTerm.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocTerm.HC.HTML new file mode 100755 index 0000000..9084bc5 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocTerm.HC.HTML @@ -0,0 +1,244 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Task;StdOut/Task"
+public CDoc *DocBorderNew(CDoc *pdoc)
+{//Make new std border doc.
+  CDocEntry *doc_e;
+  CDoc *bdoc;
+
+  bdoc=DocNew;
+  bdoc->flags|=DOCF_BORDER_DOC;
+  if (pdoc) {
+    DocPrint(bdoc,"$CM+H+BY+RX+NC,-7,1$");
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdFilterCB;
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdOverStrikeCB;
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdDollarCB;
+    DocPrint(bdoc,"$CM+H+BY+RX+NC,-18,1$");
+    doc_e=DocPrint(bdoc,"$TX+BD+TC,\"     \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdMoreCB;
+    doc_e=DocPrint(bdoc,"$TX+H+BD+TC,\" \"$");
+    doc_e->user_data=pdoc;
+    doc_e->tag_cb=&EdDollarTypeCB;
+  }
+  DocPrint(bdoc,"$CM+H+TY+NC,0,-1$");
+  doc_e=DocPrint(bdoc,"$DA+H-TRM-P+BD+RD+CX+IV,LEN=STR_LEN-1,"
+        "A=\"%%s...\",SCX=15$");
+  doc_e->data=&Fs->task_title;
+  DocDataFmt(bdoc,doc_e);
+  DocPrint(bdoc,"$CM+H+NC,1,0$$TX+H+BD+IV,\"%X\"$",Fs);
+  DocPrint(bdoc,"$TX+H+RX+BD,\"[X]\"$");
+  DocPrint(bdoc,"$BK,1$$TX+H+LX+BD,\"MENU\"$$BK,0$");
+  return bdoc;
+}
+
+public U0 DocTermNew()
+{//Make into term win task with Put/Display/Border docs.
+  CDoc *pdoc=DocNew;
+  pdoc->right_click_link=&TermRightClickLink;
+  pdoc->max_entries=4096;
+  Fs->border_src=BDS_CUR_DRV;
+  pdoc->desc='Term';
+  Fs->put_doc=Fs->display_doc=pdoc;
+  Fs->border_doc=DocBorderNew(pdoc);
+  Fs->cur_menu=MenuFile("::/Doc/EdPullDown.DD");
+  WinScrollsInit(Fs);
+  Raw(OFF);
+}
+
+#help_index "DolDoc"
+
+#define RIGHT_INCLUDE   0
+#define RIGHT_AINCLUDE  1
+#define RIGHT_COPY      2
+#define RIGHT_MOVE      3
+#define RIGHT_DELETE    4
+#define RIGHT_TYPE      5
+#define RIGHT_ED        6
+#define RIGHT_MOUNT     7
+#define RIGHT_PLAIN     8
+#define RIGHT_INFILE    9
+
+I64 PopUpTermRight(U8 *header)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  DocPrint(doc,"\n\n"
+        "TXT=%s\nDD =%s\nJIT=%s\nGR =%s"
+        "$CM+LX,1,3 $$BT,\"Include           JIT\",LE=RIGHT_INCLUDE$"
+        "$CM+LX,25,0$$BT,\"Adam Include      JIT\",LE=RIGHT_AINCLUDE$"
+        "$CM+LX,1,3 $$BT,\"Copy                 \",LE=RIGHT_COPY$"
+        "$CM+LX,25,0$$BT,\"Move or Rename       \",LE=RIGHT_MOVE$"
+        "$CM+LX,1,3 $$BT,\"Delete               \",LE=RIGHT_DELETE$"
+        "$CM+LX,25,0$$BT,\"Type           TXT;GR\",LE=RIGHT_TYPE$"
+        "$CM+LX,1,3 $$BT,\"DolDoc Edit        DD\",LE=RIGHT_ED$"
+        "$CM+LX,25,0$$BT,\"Mount           ISO.C\",LE=RIGHT_MOUNT$"
+        "$CM+LX,1,3 $$BT,\"Plain Text Edit   TXT\",LE=RIGHT_PLAIN$"
+        "$CM+LX,25,0$$BT,\"Infile             IN\",LE=RIGHT_INFILE$"
+        "$CM+LX,1,3 $$BT,\"Cancel               \",LE=DOCM_CANCEL$\n",
+        FILEMASK_TXT,FILEMASK_DD,FILEMASK_JIT,FILEMASK_GR);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e)
+{//Called with doc locked, exit unlocked
+  Bool res;
+  U8 *st;
+  if (st=DocEntryLink(doc,doc_e)) {
+    DocUnlock(doc);
+    if (doc_e->de_flags & DOCEF_POPUP)
+      res=PopUpEd(st);
+    else
+      res=Ed(st);
+    Free(st);
+    return res;
+  }
+}
+
+I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e)
+{//Called with doc locked, exit unlocked
+  Bool send_new_line=FALSE,res=FALSE;
+  U8 *st,*st2;
+  I64 i;
+  CEdFileName fn;
+  if (st2=DocEntryLink(doc,doc_e)) {
+    if (st=DocLinkFile(st2)) {
+      DocUnlock(doc);
+      if ((i=PopUpTermRight(st))>=0) {
+        DocBottom(doc);
+        switch (i) {
+          case RIGHT_INCLUDE:
+            if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "#include \"%s\";\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            ExeFile(st,CCF_CMD_LINE);
+            res=TRUE;
+            break;
+          case RIGHT_AINCLUDE:
+            if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "Adam(\"#include \\\"%s\\\"\" );\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            AdamFile(st,FALSE);
+            res=TRUE;
+            break;
+          case RIGHT_COPY:
+            StrCpy(fn.name,st);
+            if (DocForm(&fn)) {
+              res=ToBool(Copy(st,fn.name));
+            } else
+              send_new_line=TRUE;
+            break;
+          case RIGHT_MOVE:
+            StrCpy(fn.name,st);
+            if (DocForm(&fn))
+              res=Move(st,fn.name);
+            else
+              send_new_line=TRUE;
+            break;
+          case RIGHT_DELETE:
+            res=ToBool(Del(st));
+            break;
+          case RIGHT_TYPE:
+            res=Type(st);
+            break;
+          case RIGHT_ED:
+            if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_DD)) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not DolDoc File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "Ed(\"%s\");\n$PT$$FG$$BG$",st;
+            res=Ed(st);
+            break;
+          case RIGHT_MOUNT:
+            if (FileExtDot(st) && !FilesFindMatch(st,"*.ISO.C")) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .ISO.C File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "MountFile(\"%s\");\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            MountFile(st);
+            res=TRUE;
+            break;
+          case RIGHT_PLAIN:
+            "Plain(\"%s\");\n$PT$$FG$$BG$",st;
+            res=Plain(st);
+            break;
+          case RIGHT_INFILE:
+            if (FileExtDot(st) && !FilesFindMatch(st,"*.IN*")) {
+              if (!PopUpCancelOk(ST_WARN_ST "Not .IN File\n\n")) {
+                send_new_line=TRUE;
+                break;
+              }
+            }
+            "InFile(\"%s\");\n$PT$$FG$$BG$",st;
+            WinZBufUpdate;
+            InFile(st);
+            res=TRUE;
+            break;
+        }
+      } else
+        send_new_line=TRUE;
+      Free(st);
+    } else
+      send_new_line=TRUE;
+    Free(st2);
+  } else
+    send_new_line=TRUE;
+  DocBottom(doc);
+  "$PT$$FG$$BG$";
+  if (send_new_line)
+    '\n';
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocTree.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocTree.HC.HTML new file mode 100755 index 0000000..513de88 --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocTree.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Tree"
+
+public Bool DocTreeFind(CDoc *haystack_doc,U8 *needle_path,
+  CDocEntry **_tree_entry=NULL,
+  CDocEntry **_start_indent=NULL, CDocEntry **_end_indent=NULL)
+{//Find tree widget start and end.
+  I64 i=0,k=0;
+  U8 *st1=StrNew(needle_path),*st2=MAlloc(StrLen(needle_path)+1);
+  Bool res=FALSE,unlock_doc=DocLock(haystack_doc);
+  CDocEntry *doc_e=haystack_doc->head.next;
+  if (_tree_entry) *_tree_entry=haystack_doc;
+  if (_start_indent) *_start_indent=haystack_doc;
+  if (_end_indent) *_end_indent=haystack_doc;
+  while (*st1 && doc_e!=haystack_doc) {
+    StrFirstRem(st1,"/",st2);
+    if (*st2) {
+      while (doc_e!=haystack_doc) {
+        if (doc_e->type_u8==DOCT_INDENT)
+          i+=doc_e->attr;
+        else if (i==k && doc_e->de_flags&DOCEF_TREE &&
+              !StrCmp(doc_e->tag+3,st2)) {
+          if (*st1)
+            break;
+          else {
+            if (_tree_entry) *_tree_entry=doc_e;
+            i=0;
+            while (doc_e!=haystack_doc && doc_e->type_u8!=DOCT_INDENT)
+              doc_e=doc_e->next;
+            if (doc_e!=haystack_doc) {
+              i=doc_e->attr;
+              if (_start_indent) *_start_indent=doc_e;
+              doc_e=doc_e->next;
+              while (doc_e!=haystack_doc && i>0) {
+                if (doc_e->type_u8==DOCT_INDENT) {
+                  i+=doc_e->attr;
+                  if (i<=0) {
+                    if (_end_indent) *_end_indent=doc_e;
+                    res=TRUE;
+                    break;
+                  }
+                }
+                doc_e=doc_e->next;
+              }
+            }
+            goto ft_done;
+          }
+        }
+        doc_e=doc_e->next;
+      }
+      k+=2;
+    }
+  }
+ft_done:
+  if (unlock_doc)
+    DocUnlock(haystack_doc);
+  Free(st1);
+  Free(st2);
+  return res;
+}
+
+public Bool DocTreeFFind(U8 *name,U8 *path)
+{//Find tree widget in file.
+  CDoc *doc=DocRead(name);
+  Bool res=DocTreeFind(doc,path);
+  DocDel(doc);
+  return res;
+}
+
+public Bool DocTreeMake(CDoc *doc,U8 *path)
+{//Make tree widget.
+  I64 i=0,j=I64_MIN,k=0;
+  U8 *st1=StrNew(path),
+        *st2=MAlloc(StrLen(path)+1),
+        *st3=StrNew(path);
+  Bool res=TRUE,unlock_doc=DocLock(doc);
+  CDocEntry *doc_e=doc->head.next;
+  doc->cur_entry=doc;
+  doc->cur_col=0;
+  while (*st1 && doc_e!=doc) {
+    StrFirstRem(st1,"/",st2);
+    if (*st2) {
+      while (doc_e!=doc) {
+        if (doc_e->type_u8==DOCT_INDENT) {
+          i+=doc_e->attr;
+          if (i==j) {
+            doc->cur_entry=doc_e;
+            doc->cur_col=0;
+            goto mt_done;
+          }
+        } else if (i==k && doc_e->de_flags&DOCEF_TREE &&
+              !StrCmp(doc_e->tag+3,st2)) {
+          Free(st3);
+          st3=StrNew(st1);
+          j=i;
+          if (!*st1)
+            res=FALSE;
+          else
+            break;
+        }
+        doc_e=doc_e->next;
+      }
+      k+=2;
+    }
+  }
+mt_done:
+  if (res) {
+    while (*st3) {
+      StrFirstRem(st3,"/",st2);
+      if (*st2) {
+        DocPrint(doc,"$TR+C,\"%s\"$\n$ID,2$",st2);
+        doc->cur_entry=DocPrint(doc,"$ID,-2$");
+        doc->cur_col=0;
+      }
+    }
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+  Free(st1);
+  Free(st2);
+  Free(st3);
+  return res;
+}
+
+Bool DocTreeWriteJoin(CDoc *doc,U8 *path,Bool write,U8 *fmt,I64 argc,I64 *argv)
+{//Rewrite doc tree branch.
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  Bool res,unlock_doc=DocLock(doc);
+  if (res=DocTreeFind(doc,path,
+        &tree_branch,&start_indent,&end_indent)) {
+    DocCut(doc,start_indent->next,end_indent->last);
+    doc->cur_entry=start_indent->next;
+    doc->cur_col=doc->cur_entry->min_col;
+  } else
+    DocTreeMake(doc,path);
+  DocPrint(doc,"%s",buf);
+  if (write && DrvIsWritable(*doc->filename.name))
+    DocWrite(doc);
+  if (unlock_doc)
+    DocUnlock(doc);
+  Free(buf);
+  return res;
+}
+
+Bool DocTreeAppendJoin(CDoc *doc,U8 *path,Bool write,U8 *fmt,I64 argc,I64 *argv)
+{//Append to doc tree branch.
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  Bool res,unlock_doc=DocLock(doc);
+  if (res=DocTreeFind(doc,path,
+        &tree_branch,&start_indent,&end_indent)) {
+    doc->cur_entry=end_indent;
+    doc->cur_col=doc->cur_entry->min_col;
+  } else
+    DocTreeMake(doc,path);
+  DocPrint(doc,"%s",buf);
+  if (write && DrvIsWritable(*doc->filename.name))
+    DocWrite(doc);
+  if (unlock_doc)
+    DocUnlock(doc);
+  Free(buf);
+  return res;
+}
+
+public Bool DocTreeWrite(CDoc *doc,U8 *path,Bool write=TRUE,U8 *fmt,...)
+{//Rewrite doc tree branch.
+  return DocTreeWriteJoin(doc,path,write,fmt,argc,argv);
+}
+
+public Bool DocTreeAppend(CDoc *doc,U8 *path,Bool write=TRUE,U8 *fmt,...)
+{//Append to doc tree branch.
+  return DocTreeAppendJoin(doc,path,write,fmt,argc,argv);
+}
+
+public Bool DocTreeFWrite(U8 *name,U8 *path,U8 *fmt,...)
+{//Rewrite doc tree branch in file.
+  CDoc *doc=DocRead(name);
+  Bool res=DocTreeWriteJoin(doc,path,TRUE,fmt,argc,argv);
+  DocDel(doc);
+  return res;
+}
+
+public Bool DocTreeFAppend(U8 *name,U8 *path,U8 *fmt,...)
+{//Append to doc tree branch in file.
+  CDoc *doc=DocRead(name);
+  Bool res=DocTreeAppendJoin(doc,path,TRUE,fmt,argc,argv);
+  DocDel(doc);
+  return res;
+}
+
+#help_index "DolDoc/Compiler;Compiler"
+public I64 ExeDoc(CDoc *doc,I64 ccf_flags=0)
+{//JIT Compile and execute a document.
+  I64 res;
+  Bool okay=TRUE,unlock_doc=DocLock(doc);
+  CCmpCtrl *cc=CmpCtrlNew(,ccf_flags|CCF_DONT_FREE_BUF);
+  if (Fs->last_cc!=&Fs->next_cc)
+    cc->opts=Fs->last_cc->opts;
+  QueIns(cc,Fs->last_cc);
+  LexAttachDoc(cc,,doc);
+  try {
+    Lex(cc);
+    res=ExeCmdLine(cc);
+  } catch {
+    if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+      res=0;
+    }
+  }
+  QueRem(cc);
+  if (okay)
+    CmpCtrlDel(cc); //TODO: can crash
+  if (unlock_doc)
+    DocUnlock(doc);
+  return res;
+}
+
+#help_index "DolDoc/Tree;DolDoc/Compiler;Compiler"
+public I64 DocTreeExe(CDoc *doc,U8 *path)
+{//Execute doc tree branch.
+  CDoc *doc2;
+  Bool unlock_doc=DocLock(doc);
+  CDocEntry *tree_branch,*start_indent,*end_indent;
+  I64 res=0;
+  if (DocTreeFind(doc,path,&tree_branch,&start_indent,&end_indent)) {
+    doc2=DocCopy(doc,tree_branch,end_indent);
+    res=ExeDoc(doc2);
+    DocDel(doc2);
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+  return res;
+}
+
+public I64 DocTreeFExe(U8 *name,U8 *path)
+{//Execute doc tree branch in file.
+  I64 res;
+  CDoc *doc=DocRead(name);
+  res=DocTreeExe(doc,path);
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/DocWidgetWiz.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/DocWidgetWiz.HC.HTML new file mode 100755 index 0000000..7187f8c --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/DocWidgetWiz.HC.HTML @@ -0,0 +1,1194 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Misc"
+
+U8 *ctrl_L_footer=
+        "\n$MU-X+Q,\"Abort\",LE=DOCM_CANCEL$\n"
+        "\n\n$LK+PU,\"Click for Help\",A=\"FI:::/Doc/Widget.DD\"$\n";
+
+I64 PopUpLinkType(Bool include_anchor)
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Link Type Menu\"$\n"
+        "\n$LTBLUE$$MU,\"To file\",LE=LK_FILE$\n"
+        "$MU,\"To anchor in file\",LE=LK_FILE_ANCHOR$\n"
+        "$MU,\"To str in file\",LE=LK_FILE_FIND$\n"
+        "$MU,\"To line in file\",LE=LK_FILE_LINE$\n"
+        "$MU,\"To man page\",LE=LK_MAN_PAGE$\n"
+        "$MU,\"To plain-text file\",LE=LK_PLAIN$\n"
+        "$MU,\"To str in plain-text file\",LE=LK_PLAIN_FIND$\n"
+        "$MU,\"To line in plain-text file\",LE=LK_PLAIN_LINE$\n"
+        "$MU,\"To Bible chapter line and verse\",LE=LK_BIBLE_FIND$\n"
+        "$MU,\"To Dictionary Definition\",LE=LK_DEF$\n"
+        "$MU,\"To Help Index\",LE=LK_HELP_INDEX$\n"
+        "$MU,\"To Addr\",LE=LK_ADDR$\n");
+  if (include_anchor)
+    DocPrint(doc,"$MU,\"Place Anchor\",LE=LK_PLACE_ANCHOR$\n");
+  DocPrint(doc,"%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CEdFileLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512];
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdFileAnchorLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Anchor Label  :%s\"$\n";
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdFileFindLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Str        :%s\"$\n";
+  I64   num             format "$DA-TRM,A=\"Occurrence Num:%04d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdFileLineLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512];
+  I64   num             format "$DA-TRM,A=\"Line Num      :%04d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdManPageLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Label         :%s\"$\n";
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdAddrLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Addr Exp   :%s\"$\n";
+  I64   num             format "$DA-TRM,A=\"Bin Size      :%04d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdPlaceAnchor
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Anchor Label  :%s\"$\n";
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up,
+        quote           format "$CB,\"Quote\"$\n",
+        hide            format "$CB,\"Hide\"$\n";
+};
+
+class CEdBibleLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book            format "$LS,D=\"ST_BIBLE_BOOKS\"$\n";
+  U8    aux[512]        format "$DA-P,A=\"Chapter Verse :%s\"$\n";
+  I64   num;
+
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdDefLink
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512];
+  I64   book;
+  U8    aux[512]        format "$DA-P,A=\"Word          :%s\"$\n";
+  I64   num             format "$DA-TRM,A=\"Def Num       :%4d\"$\n";
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+class CEdProject
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        file[512]       format "$DA-P,A=\"File          :%s\"$\n";
+  I64   book;
+  U8    aux[512];
+  I64   num;
+  U8    html_link[512]  format "$DA-P,A=\"Html Link     :%s\"$\n";
+  Bool  pop_up          format "$CB,\"PopUp\"$\n",
+        quote           format "$CB,\"Quote\"$\n",
+        hide;
+};
+
+Bool GetLink(I64 type,U8 **_tag,U8 **_link,Bool *_pop_up,
+        Bool *_quote,U8 **_html_link)
+{
+  CEdFileLink *e=CAlloc(sizeof(CEdFileLink));
+  Bool res=FALSE;
+  if (type>=0) {
+    e->num=1;
+    switch (type) {
+      case LK_FILE:
+        if (DocForm(e,,,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("FI:%s",e->file);
+        }
+        break;
+      case LK_PLAIN:
+        if (DocForm(e,,,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("PI:%s",e->file);
+        }
+        break;
+      case LK_FILE_ANCHOR:
+        if (DocForm(e,"CEdFileAnchorLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("FA:%s,%s",e->file,e->aux);
+        }
+        break;
+      case LK_FILE_FIND:
+        if (DocForm(e,"CEdFileFindLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (e->num==1) {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("FF:%s,%s",e->file,e->aux);
+          } else {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("FF:%s,%s:%d",e->file,e->aux,e->num);
+          }
+        }
+        break;
+      case LK_PLAIN_FIND:
+        if (DocForm(e,"CEdFileFindLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (e->num==1) {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("PF:%s,%s",e->file,e->aux);
+          } else {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("PF:%s,%s:%d",e->file,e->aux,e->num);
+          }
+        }
+        break;
+      case LK_FILE_LINE:
+        if (DocForm(e,"CEdFileLineLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("FL:%s,%d",e->file,e->num);
+        }
+        break;
+      case LK_PLAIN_LINE:
+        if (DocForm(e,"CEdFileLineLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->file);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("PL:%s,%d",e->file,e->num);
+        }
+        break;
+      case LK_MAN_PAGE:
+        if (DocForm(e,"CEdManPageLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("MN:%s",e->aux);
+        }
+        break;
+      case LK_PLACE_ANCHOR:
+        if (DocForm(e,"CEdPlaceAnchor",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag) {
+            if (e->hide)
+              *_tag=StrNew("");
+            else
+              *_tag=StrNew(e->aux);
+          } else
+            *_tag=StrNew(e->tag);
+          *_link=StrNew(e->aux);
+        }
+        break;
+      case LK_BIBLE_FIND:
+        if (DocForm(e,"CEdBibleLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=MStrPrint("%Z,%s",e->book,"ST_BIBLE_BOOKS",e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("BF:%Z,%s",e->book,"ST_BIBLE_BOOKS",e->aux);
+        }
+        break;
+      case LK_DEF:
+        e->num=-1;
+        if (DocForm(e,"CEdDefLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          if (e->num<0)
+            *_link=MStrPrint("DN:%s",e->aux);
+          else
+            *_link=MStrPrint("DN:%s,%d",e->aux,e->num);
+
+        }
+        break;
+      case LK_HELP_INDEX:
+        if (DocForm(e,"CEdManPageLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (!*e->tag)
+            *_tag=StrNew(e->aux);
+          else
+            *_tag=StrNew(e->tag);
+          *_link=MStrPrint("HI:%s",e->aux);
+        }
+        break;
+      case LK_ADDR:
+        e->num=DFT_ADDR_LINK_BIN_SIZE;
+        if (DocForm(e,"CEdAddrLink",,,ctrl_L_footer)) {
+          res=TRUE;
+          if (e->num==DFT_ADDR_LINK_BIN_SIZE) {
+            if (!*e->tag)
+              *_tag=StrNew(e->aux);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("AD:%s",e->aux);
+          } else {
+            if (!*e->tag)
+              *_tag=MStrPrint("%s,%d",e->aux,e->num);
+            else
+              *_tag=StrNew(e->tag);
+            *_link=MStrPrint("AD:%s,%d",e->aux,e->num);
+          }
+        }
+        break;
+    }
+  }
+  if (*e->html_link)
+    *_html_link=StrNew(e->html_link);
+  else
+    *_html_link=NULL;
+  if (e->pop_up)
+    *_pop_up=TRUE;
+  else
+    *_pop_up=FALSE;
+  if (e->quote)
+    *_quote=TRUE;
+  else
+    *_quote=FALSE;
+  Free(e);
+  return res;
+}
+
+U0 EdInsLink()
+{
+  U8 *tag=NULL,*link=NULL,*st=NULL,*html_link=NULL,*pop_up_st;
+  Bool pop_up=FALSE,quote=FALSE;
+  I64 type=PopUpLinkType(TRUE);
+  if (type>=0) {
+    if (GetLink(type,&tag,&link,&pop_up,&quote,&html_link)) {
+      if (pop_up)
+        pop_up_st="+PU";
+      else
+        pop_up_st="";
+      switch (type) {
+        case LK_PLACE_ANCHOR:
+          if (html_link)
+            st=MStrPrint("$AN,\"%$Q\",A=\"%$Q\",HTML=\"%$Q\"$",
+                  tag,link,html_link);
+          else
+            st=MStrPrint("$AN,\"%$Q\",A=\"%$Q\"$",tag,link);
+          break;
+        default:
+          if (html_link)
+            st=MStrPrint("$LK%s,\"%$Q\",A=\"%$Q\",HTML=\"%$Q\"$",
+                  pop_up_st,tag,link,html_link);
+          else
+            st=MStrPrint("$LK%s,\"%$Q\",A=\"%$Q\"$",pop_up_st,tag,link);
+      }
+    }
+  }
+  if (st) {
+    if (quote)
+      "%$Q",st;
+    else
+      "%s",st;
+  }
+  Free(tag);
+  Free(link);
+  Free(html_link);
+  Free(st);
+}
+
+I64 PopUpColorType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Color Type Menu\"$\n"
+        "\n$LTBLUE$$MU,\"Foreground\",LE=DOCT_FOREGROUND$\n"
+        "$MU,\"Background\",LE=DOCT_BACKGROUND$\n"
+        "$MU,\"Default Foreground\",LE=DOCT_DFT_FOREGROUND$\n"
+        "$MU,\"Default Background\",LE=DOCT_DFT_BACKGROUND$\n"
+        "%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 PopUpPageSettingType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Page Setting Menu\"$\n"
+        "\n$LTBLUE$$MU,\"Page Length\",LE=DOCT_PAGE_LEN$\n"
+        "$MU,\"Page Header\",LE=DOCT_HEADER$\n"
+        "$MU,\"Page Footer\",LE=DOCT_FOOTER$\n"
+        "$MU,\"Left Margin\",LE=DOCT_LEFT_MARGIN$\n"
+        "$MU,\"Right Margin\",LE=DOCT_RIGHT_MARGIN$\n"
+        "%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+U0 EdInsColor()
+{
+  I64 type=PopUpColorType,col=DOC_DFT;
+  if (type>=0) {
+    col=PopUpColor(,FALSE);
+    if (col==DOC_DFT)
+      "$%Z$",type,"ST_DOC_CMDS";
+    else if (col>=0)
+      "$%Z,%d$",type,"ST_DOC_CMDS",col;
+  }
+}
+
+class CEdPageSetting1
+{
+  U8    val[512]        format "$DA-P,A=\"Setting Val:%s\"$\n";
+  Bool  winrel;
+};
+
+class CEdPageSetting2
+{
+  U8    val[512]        format "$DA-P,A=\"Setting Val:%s\"$\n";
+  Bool  winrel          format "$CB,\"Win Relative\"$\n";
+};
+
+U0 EdInsPageSetting()
+{
+  I64 type=PopUpPageSettingType;
+  CEdPageSetting1 *e=CAlloc(sizeof(CEdPageSetting1));
+  if (type>=0) {
+    if (type==DOCT_RIGHT_MARGIN||type==DOCT_PAGE_LEN) {
+      if (DocForm(e(CEdPageSetting2 *))) {
+        if (e->winrel) {
+          if (*e->val)
+            "$%Z+WR,%s$",type,"ST_DOC_CMDS",e->val;
+          else
+            "$%Z+WR,0$",type,"ST_DOC_CMDS";
+        } else {
+          if (*e->val)
+            "$%Z,%s$",type,"ST_DOC_CMDS",e->val;
+          else
+            "$%Z$",type,"ST_DOC_CMDS";
+        }
+      }
+    } else {
+      if (DocForm(e)) {
+        if (*e->val)
+          "$%Z,%s$",type,"ST_DOC_CMDS",e->val;
+        else
+          "$%Z$",type,"ST_DOC_CMDS";
+      }
+    }
+  }
+  Free(e);
+}
+
+#define WIZ_HIGHLIGHT_ON        (DOCT_ERROR+1)
+#define WIZ_HIGHLIGHT_OFF       (DOCT_ERROR+2)
+
+I64 PopUpWidgetType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Text Widgets Menu\"$\n"
+        "\n$LTBLUE$$MU,\"Link\",LE=DOCT_LINK$\n"
+        "$MU,\"Text\",LE=DOCT_TEXT$\n"
+        "$MU,\"Tree Branch\",LE=DOCT_TREE$\n"
+        "$MU,\"Color\",LE=DOCT_FOREGROUND$\n"
+        "$MU,\"Page Settings\",LE=DOCT_PAGE_LEN$\n"
+        "$MU,\"Cursor Movement\",LE=DOCT_CURSOR_MOVEMENT$\n"
+        "$MU,\"Macro\",LE=DOCT_MACRO$\n"
+        "$MU,\"Bttn\",LE=DOCT_BTTN$\n"
+        "$MU,\"Check Box\",LE=DOCT_CHECK_BOX$\n"
+        "$MU,\"List\",LE=DOCT_LST$\n"
+        "$MU,\"Menu Val\",LE=DOCT_MENU_VAL$\n"
+        "$MU,\"Data\",LE=DOCT_DATA$\n"
+        "$MU,\"Hex Edit\",LE=DOCT_HEX_ED$\n"
+        "$MU,\"Syntax Highlight ON\",LE=WIZ_HIGHLIGHT_ON$\n"
+        "$MU,\"Syntax Highlight OFF\",LE=WIZ_HIGHLIGHT_OFF$\n"
+        "$MU,\"HTML\",LE=DOCT_HTML_CODE$\n"
+        "$MU,\"Song\",LE=DOCT_SONG$\n"
+        "%s",ctrl_L_footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CEdText
+{
+  U8    tag[512]  format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  Bool  left_x    format "$CB,\"Left X\"$\n",
+        center_x  format "$CB,\"Center X\"$\n",
+        right_x   format "$CB,\"Right X\"$\n",
+        margin_rel format "$CB,\"Margin Rel X\"$\n",
+        blink     format "$CB,\"Blink\"$\n",
+        invert    format "$CB,\"Invert\"$\n",
+        underline format "$CB,\"Underline\"$\n",
+        tree      format "$CB,\"Tree\"$\n",
+        collapsed format "$CB,\"Collapsed\"$\n";
+  U8    scroll_x [512]  format "$DA-P,A=\"Scroll X Length Expression:%s\"$\n",
+        shift_x  [512]  format "$DA-P,A=\"X Offset Expression       :%s\"$\n",
+        shift_y  [512]  format "$DA-P,A=\"Y Offset Expression       :%s\"$\n",
+        define_str[512] format "$DA-P,A=\"Define Str                :%s\"$\n",
+        html_link[512]  format "$DA-P,A=\"Html Link                 :%s\"$\n";
+};
+
+U0 EdInsText()
+{
+  U8 *st,buf[512];
+  CEdText *e=CAlloc(sizeof(CEdText));
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->left_x  )  CatPrint(buf,"+LX");
+    if (e->center_x)  CatPrint(buf,"+CX");
+    if (e->right_x )  CatPrint(buf,"+RX");
+    if (e->margin_rel) CatPrint(buf,"+MRX");
+    if (e->blink)     CatPrint(buf,"+BK");
+    if (e->invert)    CatPrint(buf,"+IV");
+    if (e->underline) CatPrint(buf,"+UL");
+    if (e->tree)      CatPrint(buf,"+TR");
+    if (e->collapsed) CatPrint(buf,"+C");
+    st=MStrPrint("%q",e->tag);
+    "$TX%s,\"%$Q\"",buf,st;
+    Free(st);
+    if (*e->shift_x)
+      ",SX=%s",e->shift_x;
+    if (*e->shift_y)
+      ",SY=%s",e->shift_y;
+    if (*e->scroll_x)
+      ",SCX=%s",e->scroll_x;
+    if (*e->define_str) {
+      st=MStrPrint("%q",e->define_str);
+      ",D=\"%$Q\"",st;
+      Free(st);
+    }
+    if (*e->html_link) {
+      st=MStrPrint("%q",e->html_link);
+      ",HTML=\"%$Q\"",st;
+      Free(st);
+    }
+    "$";
+  }
+  Free(e);
+}
+
+class CEdSong
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n",
+        song[512]       format "$DA-P,A=\"Song          :%s\"$\n";
+};
+
+U0 EdInsSong()
+{
+  CEdSong *e=CAlloc(sizeof(CEdSong));
+  if (DocForm(e,,,,ctrl_L_footer))
+    "$SO,\"%$Q\",A=\"%s\"$",e->tag,e->song;
+  Free(e);
+}
+
+class CEdHtmlCode
+{
+  U8    tag[512]        format "$DA-P,A=\"Html Code:%s\"$\n";
+};
+
+U0 EdInsHtml()
+{
+  CEdHtmlCode *e=CAlloc(sizeof(CEdHtmlCode));
+  if (DocForm(e,,,,ctrl_L_footer))
+    "$HC,\"%$Q\"$",e->tag;
+  Free(e);
+}
+
+class CEdMacroMenu
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text                  :%s\"$\n",
+        left_macro[512] format "$DA-P,A=\"Left Click Macro          :%s\"$\n",
+        left_exp[512]   format "$DA-P,A=\"Left Click Expression     :%s\"$\n";
+  Bool  popup           format "$CB,\"PopUp\"$\n",
+        left_is_in_str  format "$CB,\"Left is InStr\"$\n",
+        left_x          format "$CB,\"Left X \"$\n",
+        center_x        format "$CB,\"Center X \"$\n",
+        right_x         format "$CB,\"Right X \"$\n",
+        margin_rel      format "$CB,\"Margin Rel X\"$\n",
+        blink           format "$CB,\"Blink\"$\n",
+        invert          format "$CB,\"Invert\"$\n",
+        underline       format "$CB,\"Underline\"$\n",
+        escape          format "$CB,\"Escape\"$\n";
+  U8    scroll_x[512]   format "$DA-P,A=\"Scroll X Length Expression:%s\"$\n",
+        shift_x[512]    format "$DA-P,A=\"X Offset Expression       :%s\"$\n",
+        shift_y[512]    format "$DA-P,A=\"Y Offset Expression       :%s\"$\n";
+};
+
+U0 EdInsMacroMenu(Bool is_macro)
+{
+  U8 *st,buf[512];
+  CEdMacroMenu *e=CAlloc(sizeof(CEdMacroMenu));
+  e->underline=TRUE;
+  e->escape=TRUE;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->popup)       CatPrint(buf,"+PU-X");
+    if (e->left_x  )    CatPrint(buf,"+LX");
+    if (e->center_x)    CatPrint(buf,"+CX");
+    if (e->right_x )    CatPrint(buf,"+RX");
+    if (e->margin_rel)  CatPrint(buf,"+MRX");
+    if (e->blink)       CatPrint(buf,"+BK");
+    if (e->invert)      CatPrint(buf,"+IV");
+    if (!e->underline)  CatPrint(buf,"-UL");
+    if (!e->escape)     CatPrint(buf,"-X");
+    if (e->left_is_in_str) CatPrint(buf,"+LIS");
+    if (*e->tag || is_macro) {
+      if (is_macro) {
+        if (*e->tag) {
+          st=MStrPrint("%q",e->tag);
+          "$MA%s,\"%$Q\"",buf,st;
+          Free(st);
+        } else
+          "$MA%s",buf;
+      } else {
+        st=MStrPrint("%q",e->tag);
+        "$MU%s,\"%$Q\"",buf,st;
+        Free(st);
+      }
+      if (*e->left_exp)
+        ",LE=%s",e->left_exp;
+      if (*e->left_macro) {
+        st=MStrPrint("%q",e->left_macro);
+        ",LM=\"%$Q\"",st;
+        Free(st);
+      }
+      if (*e->shift_x)
+        ",SX=%s",e->shift_x;
+      if (*e->shift_y)
+        ",SY=%s",e->shift_y;
+      if (*e->scroll_x)
+        ",SCX=%s",e->scroll_x;
+      "$";
+    }
+  }
+  Free(e);
+}
+
+class CEdBttn
+{
+  U8    tag[512]   format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  Bool  popup      format "$CB,\"PopUp\"$\n",
+        left_x     format "$CB,\"Left X \"$\n",
+        center_x   format "$CB,\"Center X \"$\n",
+        right_x    format "$CB,\"Right X \"$\n",
+        margin_rel format "$CB,\"Margin Rel X\"$\n",
+        escape     format "$CB,\"Escape\"$\n";
+  U8    left_macro[512] format "$DA-P,A=\"Left Click Macro:%s\"$\n";
+  Bool  left_is_in_str  format "$CB,\"Left is InStr\"$\n";
+  U8    left_exp[512]   format "$DA-P,A=\"Left Click Expression:%s\"$\n";
+  Bool  quote           format "$CB,\"Quote\"$\n";
+};
+
+U0 EdInsBttn()
+{
+  U8 *st,buf[512];
+  CEdBttn *e=CAlloc(sizeof(CEdBttn));
+  e->escape=TRUE;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->popup)    CatPrint(buf,"+PU-X");
+    if (e->left_x  ) CatPrint(buf,"+LX");
+    if (e->center_x) CatPrint(buf,"+CX");
+    if (e->right_x ) CatPrint(buf,"+RX");
+    if (e->margin_rel) CatPrint(buf,"+MRX");
+    if (!e->escape)     CatPrint(buf,"-X");
+    if (e->left_is_in_str) CatPrint(buf,"+LIS");
+    if (*e->tag) {
+      if (e->quote) {
+        st=MStrPrint("%q",e->tag);
+        "$$BT%s,\\\"%$Q\\\"",buf,st;
+        Free(st);
+        if (*e->left_exp)
+          ",LE=%s",e->left_exp;
+        if (*e->left_macro) {
+          st=MStrPrint("%q",e->left_macro);
+          ",LM=\\\"%$Q\\\"",st;
+          Free(st);
+        }
+        "$$";
+      } else {
+        st=MStrPrint("%q",e->tag);
+        "$BT%s,\"%$Q\"",buf,st;
+        Free(st);
+        if (*e->left_exp)
+          ",LE=%s",e->left_exp;
+        if (*e->left_macro) {
+          st=MStrPrint("%q",e->left_macro);
+          ",LM=\"%$Q\"",st;
+          Free(st);
+        }
+        "$";
+      }
+    }
+  }
+  Free(e);
+}
+
+class CEdCursorMovement
+{
+  U8    left_exp[512]    format "$DA-P,A=\"X Expression (LE):%s\"$\n",
+        right_exp[512]   format "$DA-P,A=\"Y Expression (RE):%s\"$\n";
+  Bool  left_x   format "$CB,\"Left   X \"$\n",
+        center_x format "$CB,\"Center X \"$\n",
+        right_x  format "$CB,\"Right  X \"$\n",
+        margin_rel format "$CB,\"Margin Rel X\"$\n",
+        top_y    format "$CB,\"Top    Y \"$\n",
+        center_y format "$CB,\"Center Y \"$\n",
+        bottom_y format "$CB,\"Bottom Y \"$\n",
+        page_rel format "$CB,\"Page Rel Y\"$\n",
+        quote    format "$CB,\"Quote\"$\n";
+};
+
+U0 EdInsCursorMovement()
+{
+  U8 buf[512];
+  CEdCursorMovement *e=CAlloc(sizeof(CEdCursorMovement));
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (e->left_x  )    CatPrint(buf,"+LX");
+    if (e->center_x)    CatPrint(buf,"+CX");
+    if (e->right_x )    CatPrint(buf,"+RX");
+    if (e->margin_rel)  CatPrint(buf,"+MRX");
+    if (e->top_y   )    CatPrint(buf,"+TY");
+    if (e->center_y)    CatPrint(buf,"+CY");
+    if (e->bottom_y)    CatPrint(buf,"+BY");
+    if (e->page_rel)    CatPrint(buf,"+PRY");
+    if (!*e->left_exp)  CatPrint(buf,"-LE");
+    if (!*e->right_exp) CatPrint(buf,"-RE");
+    if (e->quote)
+      "$";
+    "$CM%s",buf;
+    if (*e->left_exp)
+      ",LE=%s",e->left_exp;
+    if (*e->right_exp)
+      ",RE=%s",e->right_exp;
+    "$";
+    if (e->quote)
+      "$";
+  }
+  Free(e);
+}
+
+class CEdDataNum
+{
+  U8    fmt_str[512]    format "$DA-P,A=\"Format Str:%s\"$\n";
+  I64   len;
+  Bool  term            format "$CB,\"Form Field Terminator\"$\n",
+        remalloc,
+        refresh         format "$CB,\"Refresh Data\"$\n",
+        update          format "$CB,\"Update Data\"$\n";
+};
+
+class CEdDataStr
+{
+  U8    fmt_str[512]    format "$DA-P,A=\"Format Str:%s\"$\n";
+  I64   len             format "$DA,A=\"Length:%d\"$\n";
+  Bool  term            format "$CB,\"Zero Terminator\"$\n",
+        remalloc        format "$CB,\"Remalloc for Unlimited Length\"$\n",
+        refresh         format "$CB,\"Refresh Data\"$\n",
+        update          format "$CB,\"Update Data\"$\n";
+};
+
+U0 EdInsData()
+{
+  I64 i,type=RT_I64;
+  U8 *st,buf[512],raw_type[16];
+  CEdDataNum *e=CAlloc(sizeof(CEdDataNum));
+  e->term=TRUE;
+  e->len=DOCE_LEN_DFT;
+  if ((i=PopUpPickDefineSub("ST_NATURAL_TYPES"))>=0) {
+    *buf=0;
+    i+=RT_I8;
+    if (i==RT_F32)
+      i=RT_F64;
+    if (i==RT_UF32) {//U8 *
+      i=DocForm(e(CEdDataStr *),,,,ctrl_L_footer);
+      if (e->remalloc) {
+        CatPrint(buf,"+M");
+        e->term=TRUE;
+      } else
+        CatPrint(buf,"-P");
+    } else {
+      type=i;
+      i=DocForm(e,,,,ctrl_L_footer);
+    }
+    if (i) {
+      if (type==RT_I64)
+        *raw_type=0;
+      else
+        StrPrint(raw_type,",RT=%Z",type,"ST_RAW_TYPES");
+
+      if (!e->term)     CatPrint(buf,"-TRM");
+      if (e->refresh)   CatPrint(buf,"+RD");
+      if (e->update)    CatPrint(buf,"+UD");
+
+      st=MStrPrint("%q",e->fmt_str);
+      if (e->remalloc)
+        "$$DA%s,A=\\\"%$Q\\\"$$",buf,st;
+      else if (e->len==DOCE_LEN_DFT)
+        "$$DA%s%s,A=\\\"%$Q\\\"$$",buf,raw_type,st;
+      else
+        "$$DA%s,LEN=%d%s,A=\\\"%$Q\\\"$$",buf,e->len,raw_type,st;
+      Free(st);
+    }
+  }
+  Free(e);
+}
+
+class CEdCheckBox
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  Bool  refresh         format "$CB,\"Refresh Data\"$\n";
+  I64   type            format "$LS,D=\"ST_INT_SIZE_TYPES\"$\n";
+};
+
+U0 EdInsCheckBox()
+{
+  U8 *st,buf[512],raw_type[16];
+  CEdCheckBox *e=CAlloc(sizeof(CEdCheckBox));
+  e->type=RT_I8-RT_I8;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    e->type+=RT_I8;
+    if (e->type==RT_I8)
+      *raw_type=0;
+    else
+      StrPrint(raw_type,",RT=%Z",e->type,"ST_RAW_TYPES");
+    if (e->refresh)  CatPrint(buf,"+RD");
+    st=MStrPrint("%q",e->tag);
+    "$$CB%s%s,\\\"%$Q\\\"$$",buf,raw_type,st;
+    Free(st);
+  }
+  Free(e);
+}
+
+class CEdLst
+{
+  U8    tag[512]        format "$DA-P,A=\"Dft Sel    :%s\"$\n",
+        define_str[512] format "$DA-P,A=\"Define Str    :%s\"$\n";
+  Bool  refresh         format "$CB,\"Refresh Data\"$\n";
+  I64   type            format "$LS,D=\"ST_INT_SIZE_TYPES\"$\n";
+};
+
+U0 EdInsLst()
+{
+  U8 *st1,*st2,buf[512],raw_type[16];
+  CEdLst *e=CAlloc(sizeof(CEdLst));
+  e->type=RT_I64-RT_I8;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    e->type+=RT_I8;
+    if (e->type==RT_I64)
+      *raw_type=0;
+    else
+      StrPrint(raw_type,",RT=%Z",e->type,"ST_RAW_TYPES");
+    if (e->refresh)  CatPrint(buf,"+RD");
+    if (!*e->tag)
+      st1=NULL;
+    else
+      st1=MStrPrint("%q",e->tag);
+    st2=MStrPrint("%q",e->define_str);
+    if (st1)
+      "$$LS%s%s,\\\"%$Q\\\",D=\\\"%$Q\\\"$$",buf,raw_type,st1,st2;
+    else
+      "$$LS%s%s,D=\\\"%$Q\\\"$$",buf,raw_type,st2;
+    Free(st1);
+    Free(st2);
+  }
+  Free(e);
+}
+
+class CEdHexEd
+{
+  I64   cnt     format "$DA,A=\"Count:%d\"$\n",
+        cols    format "$DA,A=\"Columns:%d\"$\n";
+  Bool  zero    format "$CB,\"Zero Based\"$\n",
+        refresh format "$CB,\"Refresh Data\"$\n";
+};
+
+U0 EdInsHexEd()
+{
+  U8 buf[512];
+  CEdHexEd *e=CAlloc(sizeof(CEdHexEd));
+  e->cnt=128;
+  e->cols=4;
+  e->zero=TRUE;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (!e->zero)  CatPrint(buf,"-Z");
+    if (e->refresh)  CatPrint(buf,"+RD");
+    "$$HX%s,%d,%d$$",buf,e->cnt,e->cols;
+  }
+  Free(e);
+}
+
+class CEdBin
+{
+  U8    tag[512]                format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  I64   bin_num                 format "$DA,A=\"Bin Num:%d\"$\n";
+  U8    bin_ptr_link_file[512]  format "$DA-P,A=\"File:%s\"$\n";
+  I64   bin_ptr_link_bin_num    format "$DA,A=\"File Bin Num:%d\"$\n";
+  U8    bin_ptr_link_tag[512]   format "$DA-P,A=\"File Bin Tag:%s\"$\n";
+};
+
+U0 EdInsBin(I64 bin_num,I64 type)
+{
+  CEdBin *e=CAlloc(sizeof(CEdBin));
+  StrPrint(e->tag,"<%d>",bin_num);
+  e->bin_num=bin_num;
+  e->bin_ptr_link_bin_num=1;
+  if (DocForm(e,,,
+        "Note: Normally, you enter no file,\n"
+        "just a bin num.  If You enter a\n"
+        "file, enter a file bin num or a file\n"
+        "bin tag.\n\n",ctrl_L_footer)) {
+    if (*e->bin_ptr_link_file) {
+      if (*e->bin_ptr_link_tag)
+        "$%Z,\"%$Q\",BI=%d,BP=\"%s,%s\"$",type,"ST_DOC_CMDS",e->tag,e->bin_num,
+              e->bin_ptr_link_file,e->bin_ptr_link_tag;
+      else
+        "$%Z,\"%$Q\",BI=%d,BP=\"%s,%d\"$",type,"ST_DOC_CMDS",e->tag,e->bin_num,
+              e->bin_ptr_link_file,e->bin_ptr_link_bin_num;
+    } else {
+      if (DocBinFindNum(DocPut,e->bin_num))
+        "$%Z,\"%$Q\",BI=%d$",type,"ST_DOC_CMDS",e->tag,e->bin_num;
+      else
+        PopUpOk("Invalid Binary Num");
+    }
+  }
+  Free(e);
+}
+
+class CEdTree
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text      :%s\"$\n";
+  I64   indent          format "$DA,A=\"Indention:%d\"$\n";
+  Bool  collapsed       format "$CB,\"Collapsed\"$\n";
+};
+
+U0 EdInsTree()
+{
+  U8 *st1,*st2,buf[512];
+  CEdTree *e=CAlloc(sizeof(CEdTree));
+  e->collapsed=TRUE;
+  e->indent=2;
+  if (DocForm(e,,,,ctrl_L_footer)) {
+    *buf=0;
+    if (!e->collapsed)  CatPrint(buf,"-C");
+    st1=MStrPrint("%q",e->tag);
+    st2=MStrPrint("$TR%s,\"%$Q\"$\n$ID,%d$*\n$ID,%d$",
+          buf,st1,e->indent,-e->indent);
+    DocPrintAtomic(DocPut,"%s",st2);
+    Free(st1);
+    Free(st2);
+  }
+  Free(e);
+}
+
+U0 EdInsWidgetWiz()
+{
+  I64 type=PopUpWidgetType;
+  switch (type) {
+    case DOCT_FOREGROUND:
+      EdInsColor;
+      break;
+    case DOCT_PAGE_LEN:
+      EdInsPageSetting;
+      break;
+    case DOCT_LINK:
+      EdInsLink;
+      break;
+    case DOCT_TEXT:
+      EdInsText;
+      break;
+    case DOCT_TREE:
+      EdInsTree;
+      break;
+    case DOCT_MACRO:
+      EdInsMacroMenu(TRUE);
+      break;
+    case DOCT_MENU_VAL:
+      EdInsMacroMenu(FALSE);
+      break;
+    case DOCT_CURSOR_MOVEMENT:
+      EdInsCursorMovement;
+      break;
+    case DOCT_BTTN:
+      EdInsBttn;
+      break;
+    case DOCT_DATA:
+      EdInsData;
+      break;
+    case DOCT_CHECK_BOX:
+      EdInsCheckBox;
+      break;
+    case DOCT_LST:
+      EdInsLst;
+      break;
+    case DOCT_HEX_ED:
+      EdInsHexEd;
+      break;
+    case DOCT_SONG:
+      EdInsSong;
+      break;
+    case WIZ_HIGHLIGHT_ON:
+      "$HL,1$";
+      break;
+    case WIZ_HIGHLIGHT_OFF:
+      "$HL,0$";
+      break;
+    case DOCT_HTML_CODE:
+      EdInsHtml;
+  }
+}
+
+#define EST_SPRITE              0
+#define EST_SPRITE_PTR          1
+#define EST_DUP_SPRITE          2
+#define EST_SPRITE_SIZE         3
+#define EST_SPRITE_MACRO        4
+#define EST_SPRITE_MENU         5
+#define EST_SPRITE_LINK         6
+
+I64 PopUpSpriteType()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Graphic Sprite Resource Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/Resource.DD.Z\"$\n\n"
+        "$LTBLUE$$MU,\"Make Sprite\",LE=EST_SPRITE$$FG$\t "
+        "Start by making a sprite.\n"
+        "$LTBLUE$$MU,\"Ptr to Sprite\",LE=EST_SPRITE_PTR$$FG$\t "
+        "Insert pointer into src code.\n"
+        "$LTBLUE$$MU,\"Duplicate Sprite\",LE=EST_DUP_SPRITE$$FG$ "
+        "Make dup image for in a doc.\n"
+        "$LTBLUE$$MU,\"Sprite Size\",LE=EST_SPRITE_SIZE$$FG$\t "
+        "Insert size of a sprite into src code.\n"
+        "$LTBLUE$$MU,\"Sprite Macro\",LE=EST_SPRITE_MACRO$$FG$\t "
+        "Create icon with auto-text payload.\n"
+        "$LTBLUE$$MU,\"Sprite Menu Item\",LE=EST_SPRITE_MENU$$FG$ "
+        "Create icon with numeric payload.\n"
+        "$LTBLUE$$MU,\"Sprite Link\",LE=EST_SPRITE_LINK$$FG$\t "
+        "Create icon with link payload.\n\n"
+        "$LTBLUE$$MU,\"Abort\",LE=DOCM_CANCEL$\n\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+class CEdMacroSprite
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text       :%s\"$\n",
+        exp[512]        format "$DA-P,A=\"Macro          :%s\"$\n";
+  Bool  escape          format "$CB,\"Escape\"$\n",
+        popup           format "$CB,\"PopUp\"$\n",
+        is_in_str               format "$CB,\"InStr\"$\n";
+};
+
+class CEdMenuSprite
+{
+  U8    tag[512]        format "$DA-P,A=\"Tag Text       :%s\"$\n",
+        exp[512]        format "$DA-P,A=\"Expression     :%s\"$\n";
+  Bool  escape          format "$CB,\"Escape\"$\n",
+        popup,
+        is_in_str;
+};
+
+U8 *EdSpriteLink(Bool *_pop_up,U8 **_html_link)
+{
+  U8 *res=NULL,*tag=NULL,*link=NULL;
+  Bool quote=FALSE;
+  I64 type=PopUpLinkType(FALSE);
+  *_html_link=NULL;
+  if (type>=0 && GetLink(type,&tag,&link,_pop_up,&quote,_html_link))
+    res=MStrPrint("\"%$Q\",A=\"%$Q\"",tag,link);
+  Free(tag);
+  Free(link);
+  return res;
+}
+
+U8 *EdSprite(I64 bin_num)
+{
+  I64 type=PopUpSpriteType;
+  Bool pop_up;
+  U8 *st,*st1=NULL,*st2=NULL,buf[1024],*html_link=NULL;
+  CEdMacroSprite *e=CAlloc(sizeof(CEdMacroSprite));
+  *buf=0;
+  switch (type) {
+    case EST_SPRITE:
+      st1=MStrPrint("\"<%d>\"",bin_num);
+      break;
+    case EST_SPRITE_MACRO:
+      e->escape=TRUE;
+      if (DocForm(e,,,,ctrl_L_footer)) {
+        CatPrint(buf,"+UL");
+        if (e->is_in_str) CatPrint(buf,"+LIS");
+        if (e->popup)   CatPrint(buf,"+PU");
+        if (e->escape)  CatPrint(buf,"+X");
+        st=MStrPrint("%q",e->exp);
+        st1=MStrPrint("\"%$Q\",LM=\"%$Q\"",e->tag,st);
+        Free(st);
+      }
+      break;
+    case EST_SPRITE_MENU:
+      e->escape=TRUE;
+      if (DocForm(e,"CEdMenuSprite",,,ctrl_L_footer)) {
+        if (e->escape)  CatPrint(buf,"+X");
+        st1=MStrPrint("\"%$Q\",LE=%s",e->tag,e->exp);
+      }
+      break;
+    case EST_SPRITE_LINK:
+      CatPrint(buf,"+L");
+      st1=EdSpriteLink(&pop_up,&html_link);
+      if (pop_up)
+        CatPrint(buf,"+PU");
+      break;
+    case EST_SPRITE_PTR:
+      EdInsBin(--bin_num,DOCT_INS_BIN);
+      break;
+    case EST_SPRITE_SIZE:
+      EdInsBin(--bin_num,DOCT_INS_BIN_SIZE);
+      break;
+    case EST_DUP_SPRITE:
+      EdInsBin(--bin_num,DOCT_SPRITE);
+      break;
+  }
+  if (st1) {
+    if (html_link)
+      st2=MStrPrint("$SP%s,%s,HTML=\"%$Q\",BI=%d$",buf,st1,html_link,bin_num);
+    else
+      st2=MStrPrint("$SP%s,%s,BI=%d$",buf,st1,bin_num);
+    Free(st1);
+  }
+  Free(e);
+  Free(html_link);
+  return st2;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/DolDoc/MakeDoc.HC.HTML b/public/Wb/Home/Src/Adam/DolDoc/MakeDoc.HC.HTML new file mode 100755 index 0000000..1aabc1e --- /dev/null +++ b/public/Wb/Home/Src/Adam/DolDoc/MakeDoc.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#help_index "DolDoc"
+#help_file "::/Doc/DolDoc"
+
+/*
+TempleOS DolDoc's can have "cursor movement" cmds which can move the cursor up
+the scrn and layer on existing text.  It can also have callback funs which
+supply live, changing text.  For these reasons, you can't assume you know
+where the vis portion of the document is and must process much
+of the document each time it is placed on the scrn, becoming CPU
+intensive on big documents.
+See ::/Doc/DolDocOverview.DD
+*/
+
+//Hash Types
+#define DHT_DOC_CMD     1
+#define DHT_DOC_FLAG    2
+#define DHT_COLOR       4
+
+public class CDolDocGlbls
+{
+  CHashTable *hash;
+  I64   dft_de_flags            [DOCT_TYPES_NUM],
+        type_flags_nontag_invis [(DOCT_TYPES_NUM+63)/64],
+        type_flags_form         [(DOCT_TYPES_NUM+63)/64],
+        type_flags_data         [(DOCT_TYPES_NUM+63)/64],
+        type_flags_chk_dup      [(DOCT_TYPES_NUM+63)/64],
+        clean_scan_codes        [4];
+  I32   dft_type_flags          [DOCT_TYPES_NUM];
+} doldoc;
+MemSet(&doldoc,0,sizeof(CDolDocGlbls));
+
+#help_index "God"
+#define BIBLE_FILENAME  "::/Misc/Bible.TXT.Z"
+
+#include "DocExt"
+#include "DocBin"
+#include "DocNew"
+#include "DocForm"
+#include "DocDblBuf"
+#include "DocPlain"
+#include "DocInit"
+#include "DocHighlight"
+#include "DocRecalcLib"
+#include "DocRecalc"
+#include "DocFile"
+#include "DocClipBoard"
+#include "DocRun"
+#include "DocGet"
+#include "DocChar"
+#include "DocFind"
+#include "DocLink"
+#include "DocEd"
+#include "DocPopUp"
+#include "DocGr"
+#include "DocMacro"
+#include "DocWidgetWiz"
+#include "DocPutKey"
+#include "DocPutS"
+#include "DocCodeTools"
+#include "DocTree"
+#include "DocTerm"
+
+KeyDevAdd(&KDDocPutKey,&KDDocPutS,0x80000000,TRUE);
+fp_getstr2=&DocGetStr2;
+fp_doc_put=&DocPut;
+
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/God/GodBible.HC.HTML b/public/Wb/Home/Src/Adam/God/GodBible.HC.HTML new file mode 100755 index 0000000..ec06683 --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/GodBible.HC.HTML @@ -0,0 +1,379 @@ + + + + + + + + + + + +
+#help_index "God"
+U0 BibleInit()
+{
+  DefineLstLoad("ST_BIBLE_BOOKS",
+        "Genesis\0"
+        "Exodus\0"
+        "Leviticus\0"
+        "Numbers\0"
+        "Deuteronomy\0"
+        "Joshua\0"
+        "Judges\0"
+        "Ruth\0"
+        "1 Samuel\0"
+        "2 Samuel\0"
+        "1 Kings\0"
+        "2 Kings\0"
+        "1 Chronicles\0"
+        "2 Chronicles\0"
+        "Ezra\0"
+        "Nehemiah\0"
+        "Esther\0"
+        "Job\0"
+        "Psalms\0"
+        "Proverbs\0"
+        "Ecclesiastes\0"
+        "Song of Songs\0"
+        "Isaiah\0"
+        "Jeremiah\0"
+        "Lamentations\0"
+        "Ezekiel\0"
+        "Daniel\0"
+        "Hosea\0"
+        "Joel\0"
+        "Amos\0"
+        "Obadiah\0"
+        "Jonah\0"
+        "Micah\0"
+        "Nahum\0"
+        "Habakkuk\0"
+        "Zephaniah\0"
+        "Haggai\0"
+        "Zechariah\0"
+        "Malachi\0"
+        "Matthew\0"
+        "Mark\0"
+        "Luke\0"
+        "John\0"
+        "Acts\0"
+        "Romans\0"
+        "1 Corinthians\0"
+        "2 Corinthians\0"
+        "Galatians\0"
+        "Ephesians\0"
+        "Philippians\0"
+        "Colossians\0"
+        "1 Thessalonians\0"
+        "2 Thessalonians\0"
+        "1 Timothy\0"
+        "2 Timothy\0"
+        "Titus\0"
+        "Philemon\0"
+        "Hebrews\0"
+        "James\0"
+        "1 Peter\0"
+        "2 Peter\0"
+        "1 John\0"
+        "2 John\0"
+        "3 John\0"
+        "Jude\0"
+        "Revelation\0");
+  DefineLstLoad("ST_BIBLE_BOOK_LINES",
+        "297\0"
+        "5068\0"
+        "9123\0"
+        "12005\0"
+        "15977\0"
+        "19168\0"
+        "21329\0"
+        "23598\0"
+        "23902\0"
+        "26892\0"
+        "29345\0"
+        "32241\0"
+        "34961\0"
+        "37633\0"
+        "40756\0"
+        "41671\0"
+        "42963\0"
+        "43605\0"
+        "46190\0"
+        "53793\0"
+        "56267\0"
+        "56966\0"
+        "57332\0"
+        "61806\0"
+        "66736\0"
+        "67217\0"
+        "71804\0"
+        "73189\0"
+        "73876\0"
+        "74130\0"
+        "74615\0"
+        "74697\0"
+        "74860\0"
+        "75241\0"
+        "75416\0"
+        "75604\0"
+        "75806\0"
+        "75932\0"
+        "76684\0"
+        "76908\0"
+        "79970\0"
+        "81941\0"
+        "85266\0"
+        "87803\0"
+        "90914\0"
+        "92110\0"
+        "93323\0"
+        "94088\0"
+        "94514\0"
+        "94869\0"
+        "95153\0"
+        "95402\0"
+        "95647\0"
+        "95772\0"
+        "96090\0"
+        "96320\0"
+        "96440\0"
+        "96500\0"
+        "97370\0"
+        "97687\0"
+        "97976\0"
+        "98163\0"
+        "98506\0"
+        "98552\0"
+        "98597\0"
+        "98684\0"
+        "100111\0");
+  DefinePrint("ST_BIBLE_LINES","%d",
+        Str2I64(DefineSub(DefineCnt("ST_BIBLE_BOOK_LINES")-1,
+        "ST_BIBLE_BOOK_LINES"))-1);
+} BibleInit;
+
+public U8 *BibleLine2Verse(I64 line,I64 separate_ch=CH_SPACE)
+{//Line number to verse str, Malloc()ed.
+//Separate with <SPACE> or ','.  If you pass '%', it uses "%20".
+  CDoc *doc;
+  CDocEntry *doc_e;
+  I64 i=0,cnt=DefineCnt("ST_BIBLE_BOOKS"),start=0,last_start=0;
+  U8 *ptr=DefineSub(0,"ST_BIBLE_BOOK_LINES"),*ptr2;
+  while (i<=cnt) {
+    last_start=start;
+    start=Str2I64(ptr);
+    if (line<start)
+      break;
+    i++;
+    ptr+=StrLen(ptr)+1;
+  }
+  if (0<=--i<cnt) {
+    doc=DocRead(BIBLE_FILENAME,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+    DocGoToLine(doc,line); //one based
+    doc_e=doc->cur_entry;
+    while (doc_e!=doc && (doc_e->type_u8!=DOCT_TEXT || !*doc_e->tag))
+      doc_e=doc_e->next;
+    if (doc_e->type_u8==DOCT_TEXT && '0'<=*doc_e->tag<='9') {
+      ptr=ptr2=doc_e->tag;
+      while ('0'<=*ptr2<='9' || *ptr2==':')
+        ptr2++;
+      *ptr2=0;
+      if (separate_ch=='%')
+        ptr=MStrPrint("%Z%%20%s",i,"ST_BIBLE_BOOKS",ptr);
+      else
+        ptr=MStrPrint("%Z%c%s",i,"ST_BIBLE_BOOKS",separate_ch,ptr);
+    } else {
+      while (TRUE) {
+        doc_e=doc_e->last;
+        if (doc_e==doc) {
+          ptr=NULL;
+          break;
+        }
+        if (doc_e->y+1<last_start) {
+          ptr=MStrPrint("%Z",i,"ST_BIBLE_BOOKS");
+          break;
+        }
+        if (doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=3) {
+          ptr=doc_e->tag+StrLen(doc_e->tag)-1;
+          while (ptr>doc_e->tag && (!('0'<=*(ptr-1)<='9') || *ptr!=':' ||
+                !('0'<=*(ptr+1)<='9')))
+            ptr--;
+          ptr--;
+          while (ptr>=doc_e->tag && '0'<=*ptr<='9')
+            ptr--;
+          ptr2=++ptr;
+          if ('0'<=*ptr2++<='9') {
+            while ('0'<=*ptr2<='9')
+              ptr2++;
+            if (*ptr2++==':' && '0'<=*ptr2++<='9') {
+              while ('0'<=*ptr2<='9')
+                ptr2++;
+              *ptr2=0;
+              if (separate_ch=='%')
+                ptr=MStrPrint("%Z%%20%s",i,"ST_BIBLE_BOOKS",ptr);
+              else
+                ptr=MStrPrint("%Z%c%s",i,"ST_BIBLE_BOOKS",separate_ch,ptr);
+              break;
+            }
+          }
+        }
+      }
+    }
+    DocDel(doc);
+    return ptr;
+  } else
+    return NULL;
+}
+
+public U0 BookLines(CDoc *doc_out=NULL,I64 start,I64 lines,
+        U8 *book_filename=BIBLE_FILENAME)
+{//Put N line starting at line M into doc.
+  CDoc *doc_in;
+  CDocEntry *doc_e;
+  if (!doc_out) doc_out=DocPut;
+  if (doc_out && FileFind(book_filename)) {
+    doc_in=DocRead(book_filename,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+    DocGoToLine(doc_in,start); //one based
+    doc_e=doc_in->cur_entry;
+    while (lines>0 && doc_e!=doc_in) {
+      if (doc_e->type_u8==DOCT_TEXT)
+        DocPrint(doc_out,"%s",doc_e->tag);
+      else if (doc_e->type_u8==DOCT_NEW_LINE) {
+        DocPutKey(doc_out,'\n');
+        lines--;
+      }
+      doc_e=doc_e->next;
+    }
+    DocDel(doc_in);
+  }
+}
+
+public U0 BibleVerse(CDoc *doc_out=NULL,U8 *verse,I64 lines)
+{//Put N lines starting at verse str into doc.
+  I64 i;
+  CDoc *doc_in;
+  CDocEntry *doc_e;
+  U8 *st,*st2;
+  if (!doc_out) doc_out=DocPut;
+  if (doc_out && FileFind(BIBLE_FILENAME)) {
+    st=StrNew(verse);
+    st2=StrNew(verse);
+    if (StrOcc(st,','))
+      StrLastRem(st,",",st2);
+    else
+      *st2=0;
+    i=DefineMatch(st,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE);
+    if (i>=0) {
+      i=Str2I64(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
+      doc_in=DocRead(BIBLE_FILENAME,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+      DocGoToLine(doc_in,i); //one based
+      if (*st2) {
+        StrCpy(doc_in->find_replace->find_text,st2);
+        EdFindNext(doc_in);
+      }
+      doc_e=doc_in->cur_entry;
+      while (lines>0 && doc_e!=doc_in) {
+        if (doc_e->type_u8==DOCT_TEXT)
+          DocPrint(doc_out,"%s",doc_e->tag);
+        else if (doc_e->type_u8==DOCT_NEW_LINE) {
+          DocPutKey(doc_out,'\n');
+          lines--;
+        }
+        doc_e=doc_e->next;
+      }
+      DocDel(doc_in);
+    }
+    Free(st);
+    Free(st2);
+  }
+}
+
+public CDoc *BibleDoc()
+{//Return Bible as DolDoc with trees.
+  CDoc  *res=DocRead(BIBLE_FILENAME);
+  CDocEntry *doc_e=res->head.next,*doc_e1;
+  Bool open_chapter=FALSE;
+  U8    *ptr=Define("ST_BIBLE_BOOK_LINES");
+  I64   book,book_cnt=DefineCnt("ST_BIBLE_BOOK_LINES")-1,
+        chapter,
+        line=Str2I64(ptr,,&ptr);
+  ptr++;
+  for (book=0;book<book_cnt;book++) {
+    while (doc_e->y+1<line) {
+      doc_e1=doc_e->next;
+      DocEntryDel(res,doc_e);
+      doc_e=doc_e1;
+    }
+    res->cur_entry=doc_e;
+    res->cur_col=0;
+    DocPrint(res,"$TR,\"%Z\"$\n$ID,2$",book,"ST_BIBLE_BOOKS");
+    line=Str2I64(ptr,,&ptr);
+    ptr++;
+    chapter=1;
+    while (doc_e->y+1<line) {
+      doc_e1=doc_e->next;
+      if (doc_e->type_u8==DOCT_TEXT && StrMatch(":1 ",doc_e->tag)) {
+        res->cur_entry=doc_e;
+        res->cur_col=0;
+        if (open_chapter) {
+          DocPrint(res,"$ID,-2$");
+          open_chapter=FALSE;
+        }
+        DocPrint(res,"$TR,\"%d\"$\n$ID,2$",chapter++);
+        open_chapter=TRUE;
+      } else if (chapter==1) {
+        doc_e1=doc_e->next;
+        DocEntryDel(res,doc_e);
+        doc_e=doc_e1;
+      }
+      doc_e=doc_e1;
+    }
+    res->cur_entry=doc_e;
+    res->cur_col=0;
+    if (open_chapter) {
+      DocPrint(res,"$ID,-2$");
+      open_chapter=FALSE;
+    }
+    DocPrint(res,"$ID,-2$");
+  }
+  while (doc_e!=res) {
+    doc_e1=doc_e->next;
+    DocEntryDel(res,doc_e);
+    doc_e=doc_e1;
+  }
+  return res;
+}
+
+public U0 BibleView()
+{//View Bible as DolDoc with trees.
+  U8 buf[STR_LEN];
+  CDoc *doc=BibleDoc;
+  StrPrint(buf,"AL:%d,1",doc);
+  Ed(buf);
+  DocDel(doc);
+}
+U0 CtrlAltB(I64)
+{
+  PopUp("BibleView;");
+}
+CtrlAltCBSet('B',&CtrlAltB,"Cmd /Bible");
+
+ diff --git a/public/Wb/Home/Src/Adam/God/GodDoodle.HC.HTML b/public/Wb/Home/Src/Adam/God/GodDoodle.HC.HTML new file mode 100755 index 0000000..0d5881e --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/GodDoodle.HC.HTML @@ -0,0 +1,223 @@ + + + + + + + + + + + +
+#help_index "God;Graphics/Sprite;Sprites"
+
+U0 GodDoodleDraw(CTask *task,CDC *dc)
+{
+  GrBlot(dc,0,0,god.doodle_dc);
+  if (Blink) {
+    if (god.doodle_done) {
+      dc->color=RED;
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*29)>>1,
+            (task->pix_height-3*FONT_HEIGHT)>>1,
+            "Press <ESC> to insert sprite.");
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*39)>>1,
+            (task->pix_height-3*FONT_HEIGHT)>>1+2*FONT_HEIGHT,
+            "Press <SHIFT-ESC> to throw-away sprite.");
+    } else {
+      dc->color=GREEN;
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*25)>>1,
+            (task->pix_height-FONT_HEIGHT)>>1,
+            "Press <SPACE> repeatedly.");
+    }
+  }
+}
+
+U0 GodDoodleSmooth(I64 num)
+{
+  CDC *dc=DCExt(god.doodle_dc,0,0,
+        god.doodle_dc->width-1,god.doodle_dc->height-1);
+  I64 i,x,y,x1,y1,c,histogram[16],best,best_cnt,c_old=god.doodle_dc->color;
+  for (y=0;y<god.doodle_dc->height;y++)
+    for (x=0;x<god.doodle_dc->width;x++) {
+      MemSet(histogram,0,sizeof(histogram));
+      for (y1=y-num;y1<=y+num;y1++)
+        for (x1=x-num;x1<=x+num;x1++) {
+          c=GrPeek(dc,x1,y1);
+          if (0<=c<=15)
+            histogram[c]++;
+        }
+      best=BLACK;
+      best_cnt=-1;
+      for (i=0;i<16;i++)
+        if (histogram[i]>best_cnt) {
+          best=i;
+          best_cnt=histogram[i];
+        }
+      god.doodle_dc->color=best;
+      GrPlot(god.doodle_dc,x,y);
+    }
+  god.doodle_dc->color=c_old;
+  DCDel(dc);
+}
+
+U0 GodDoodleBitsIns(I64 num_bits,I64 n)
+{//Insert bits into God doodle bit fifo.
+  I64 i;
+  for (i=0;i<num_bits;i++) {
+    FifoU8Ins(god.doodle_fifo,n&1);
+    n>>=1;
+  }
+}
+
+U0 GodDoodleHexIns(U8 *st)
+{//Insert hex record into God doodle bit fifo.
+  U8 buf[2];
+  if (st) {
+    buf[1]=0;
+    while (*buf=*st++)
+      if (Bt(char_bmp_hex_numeric,*buf))
+        GodDoodleBitsIns(4,rev_bits_table[Str2I64(buf,16)]>>4);
+  }
+}
+
+I64 GodDoodleBits(I64 num_bits)
+{
+  U8 b;
+  I64 res=0;
+  while (num_bits) {
+    if (FifoU8Rem(god.doodle_fifo,&b)) {
+      res=res<<1+b;
+      num_bits--;
+    } else {
+      god.doodle_ch=GetChar(,FALSE);
+      if (god.doodle_ch==CH_ESC||god.doodle_ch==CH_SHIFT_ESC)
+        throw;
+      else if (god.doodle_ch=='\n') {
+        DCFill(god.doodle_dc,WHITE);
+        FifoU8Flush(god.doodle_fifo);
+      } else if ('0'<=god.doodle_ch<='9')
+        GodDoodleSmooth(god.doodle_ch-'0');
+      else
+        GodDoodleBitsIns(GOD_GOOD_BITS,KbdMsEvtTime>>GOD_BAD_BITS);
+    }
+  }
+  return res;
+}
+
+public U8 *GodDoodleSprite(U8 *hex=NULL)
+{//Make God draw sprite. Holy Spirit Instructions
+  I64 i,j,w,h,x,y,ch;
+  U8 *elems;
+
+  if (god.doodle_dc) return NULL;
+  god.doodle_done=FALSE;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+
+  if (!hex)
+    PopUpOk("The Holy Spirit can puppet you.\n\n"
+          "Press $GREEN$<SPACE>$FG$ until it finishes.");
+
+  god.doodle_ch=0;
+  god.doodle_dc=DCNew(Fs->pix_width,Fs->pix_height);
+  DCFill(god.doodle_dc,WHITE);
+  w=god.doodle_dc->width;
+  h=god.doodle_dc->height;
+
+  Fs->draw_it=&GodDoodleDraw;
+  FifoU8Flush(god.doodle_fifo);
+  GodDoodleHexIns(hex);
+  try {
+    for (i=0;i<3;i++) {
+      god.doodle_dc->color=RED;
+      for (j=0;j<29;j++)
+        switch [GodDoodleBits(3)] {
+          case 0:
+            GrEllipse3(god.doodle_dc,
+                  (w-1)*GodDoodleBits(5)/15.5-w/2,
+                  (h-1)*GodDoodleBits(5)/15.5-h/2,0,
+                  (w-1)*GodDoodleBits(5)/15.5,(h-1)*GodDoodleBits(5)/15.5);
+            break;
+          case 1:
+            GrCircle3(god.doodle_dc,
+                  (w-1)*GodDoodleBits(5)/15.5-w/2,
+                  (h-1)*GodDoodleBits(5)/15.5-h/2,0,
+                  (w-1)*GodDoodleBits(5)/15.5);
+            break;
+          case 2:
+            GrBorder(god.doodle_dc,
+                  (w-1)*GodDoodleBits(5)/15.5-w/2,
+                  (h-1)*GodDoodleBits(5)/15.5-h/2,
+                  (w-1)*GodDoodleBits(5)/15.5,(h-1)*GodDoodleBits(5)/15.5);
+            break;
+          case 3...7:
+            GrLine3(god.doodle_dc,
+                  (w-1)*GodDoodleBits(4)/15,(h-1)*GodDoodleBits(4)/15,0,
+                  (w-1)*GodDoodleBits(4)/15,(h-1)*GodDoodleBits(4)/15,0);
+            break;
+        }
+      for (j=0;j<6;j++) {
+        x=(w-1)*GodDoodleBits(5)/31+w/64;
+        y=(h-1)*GodDoodleBits(5)/31+h/64;
+        switch [GodDoodleBits(2)] {
+          case 0: god.doodle_dc->color=BLACK;   break;
+          case 1: god.doodle_dc->color=DKGRAY;  break;
+          case 2: god.doodle_dc->color=LTGRAY;  break;
+          case 3: god.doodle_dc->color=WHITE;   break;
+        }
+        GrFloodFill3(god.doodle_dc,x,y,0);
+      }
+      GodDoodleSmooth(3);
+    }
+    god.doodle_done=TRUE;
+    if (!hex) {
+      do ch=GetChar(,FALSE);
+      while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+    } else
+      ch=CH_ESC;
+  } catch {
+    Fs->catch_except=TRUE;
+    ch=CH_SHIFT_ESC;
+  }
+  DCFill;
+  SettingsPop;
+  if (ch==CH_ESC)
+    elems=DC2Sprite(god.doodle_dc);
+  else
+    elems=NULL;
+  DCDel(god.doodle_dc);
+  god.doodle_dc=NULL;
+  return elems;
+}
+
+#help_index "God"
+public U0 GodDoodle(U8 *hex=NULL)
+{//Make God draw sprite, insert in doc. Holy Spirit Instructions
+  U8 *elems;
+  if (elems=GodDoodleSprite(hex)) {
+    Sprite(elems);
+    Free(elems);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/God/GodExt.HC.HTML b/public/Wb/Home/Src/Adam/God/GodExt.HC.HTML new file mode 100755 index 0000000..0443d6e --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/GodExt.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+#help_index "God"
+
+#define GOD_BAD_BITS    4
+#define GOD_GOOD_BITS   24
+
+public class CGodGlbls
+{
+  U8    **words,
+        *word_file_mask;
+  I64   word_fuf_flags,
+        num_words;
+  CFifoU8 *fifo;
+  CDC   *doodle_dc;
+  I64   doodle_ch;
+  CFifoU8 *doodle_fifo;
+  Bool  doodle_done;
+} god;
+MemSet(&god,0,sizeof(CGodGlbls));
+god.doodle_fifo =FifoU8New(2048*8);
+god.fifo        =FifoU8New(2048*8);
+
+extern U0 GodBiblePassage(I64 num_lines=20);
+extern U0 GodBitsIns(I64 num_bits,I64 n);
+extern U0 GodDoodle(U8 *hex=NULL);
+extern U0 GodSong();
+extern U0 GodWord(I64 bits=17);
+
+ diff --git a/public/Wb/Home/Src/Adam/God/GodSong.HC.HTML b/public/Wb/Home/Src/Adam/God/GodSong.HC.HTML new file mode 100755 index 0000000..31cd652 --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/GodSong.HC.HTML @@ -0,0 +1,202 @@ + + + + + + + + + + + +
+#help_index "God"
+
+DefineLstLoad("ST_RHYTHM_COMPLEXITY","Simple\0Normal\0Complex\0");
+
+class CMakeSongSettings
+{
+  I64  complexity               format "$LS,D=\"ST_RHYTHM_COMPLEXITY\"$\n";
+  Bool rests                    format "$CB,\"Rests\"$\n";
+  Bool six_eight                format "$CB,\"Six Eight\"$\n";
+  I64  octave                   format "$DA-TRM,A=\"Octave:%d\"$\n";
+  I64  octave_state;
+};
+
+U0 InsNote(CMakeSongSettings *mss,U8 *buf,I64 k,I64 *j)
+{//k is a random note nibble
+  if (!k && mss->rests) {
+    buf[*j]='R';
+    *j+=1;
+  } else {
+    k/=2;
+    if (k<3) {
+      if (mss->octave_state!=mss->octave) {
+        mss->octave_state=mss->octave;
+        buf[*j]=mss->octave_state+'0';
+        *j+=1;
+      }
+      if (!k)
+        buf[*j]='G';
+      else
+        buf[*j]=k-1+'A';
+      *j+=1;
+    } else {
+      if (mss->octave_state!=mss->octave+1) {
+        mss->octave_state=mss->octave+1;
+        buf[*j]=mss->octave_state+'0';
+        *j+=1;
+      }
+      buf[*j]=k-1+'A';
+      *j+=1;
+    }
+  }
+}
+
+#define DUR_4           0
+#define DUR_8_8         1
+#define DUR_3_3_3       2
+#define DUR_16_16_16_16 3
+#define DUR_8DOT_16     4
+#define DUR_8_16_16     5
+#define DUR_16_16_8     6
+
+U8 god_simple_songs [5]={DUR_4,DUR_4,DUR_4,DUR_4,DUR_8_8};
+U8 god_normal_songs [5]={DUR_4,DUR_4,DUR_8_8,DUR_3_3_3,DUR_16_16_16_16};
+U8 god_complex_songs[9]={DUR_4,DUR_4,DUR_8_8,DUR_8_8,DUR_8DOT_16,DUR_3_3_3,
+DUR_8_16_16,DUR_16_16_8,DUR_16_16_16_16};
+
+public U8 *GodSongStr()
+{//Make God generate 2 measures of a song. Holy Spirit Instructions
+  CMakeSongSettings mss;
+  U8 *buf;
+  I64 i,j=0,k,n,k2,duration,last_duration=-1,len;
+
+  MemSet(&mss,0,sizeof(mss));
+  mss.complexity=1;
+  mss.rests=FALSE;
+  mss.octave=music.octave;
+
+  if (!PopUpForm(&mss))
+    return NULL;
+
+  buf=CAlloc(256);
+  music.octave=mss.octave=ClampI64(mss.octave,1,7);
+  progress4=0;
+  if (mss.six_eight)
+    progress4_max=6;
+  else
+    progress4_max=8;
+
+  mss.octave_state=mss.octave+1;
+  buf[j++]='0'+mss.octave_state;
+  if (mss.six_eight) {
+    len=6;
+    buf[j++]='M';
+    buf[j++]='6';
+    buf[j++]='/';
+    buf[j++]='8';
+  } else
+    len=8;
+  FifoU8Flush(god.fifo);
+  for (i=0;i<len;i++) {
+    n=GodBits(8);
+    if (mss.complexity==2)
+      duration=god_complex_songs[n%9];
+    else if (mss.complexity==1)
+      duration=god_normal_songs[n%5];
+    else
+      duration=god_simple_songs[n%5];
+
+    switch (duration) {
+      case DUR_8_8:
+        if (last_duration!=DUR_8_8)
+          buf[j++]='e';
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        break;
+      case DUR_8DOT_16:
+        buf[j++]='e';
+        buf[j++]='.';
+        InsNote(&mss,buf,GodBits(4),&j);
+        buf[j++]='s';
+        InsNote(&mss,buf,GodBits(4),&j);
+        duration=DUR_16_16_16_16;
+        break;
+      case DUR_3_3_3:
+        if (last_duration!=DUR_3_3_3) {
+          buf[j++]='e';
+          buf[j++]='t';
+        }
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        break;
+      case DUR_8_16_16:
+        if (last_duration!=DUR_8_8)
+          buf[j++]='e';
+        InsNote(&mss,buf,GodBits(4),&j);
+        buf[j++]='s';
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        duration=DUR_16_16_16_16;
+        break;
+      case DUR_16_16_8:
+        if (last_duration!=DUR_16_16_16_16)
+          buf[j++]='s';
+        InsNote(&mss,buf,GodBits(4),&j);
+        InsNote(&mss,buf,GodBits(4),&j);
+        buf[j++]='e';
+        InsNote(&mss,buf,GodBits(4),&j);
+        duration=DUR_8_8;
+        break;
+      case DUR_16_16_16_16:
+        if (last_duration!=DUR_16_16_16_16)
+          buf[j++]='s';
+        k =GodBits(4);
+        k2=GodBits(4);
+        InsNote(&mss,buf,k,&j);
+        InsNote(&mss,buf,k2,&j);
+        InsNote(&mss,buf,k,&j);
+        InsNote(&mss,buf,k2,&j);
+        break;
+      default:
+        if (last_duration!=DUR_4)
+          buf[j++]='q';
+        InsNote(&mss,buf,GodBits(4),&j);
+    }
+    last_duration=duration;
+    progress4++;
+  }
+  buf[j++]=0;
+  progress4=progress4_max=0;
+  return buf;
+}
+
+public U0 GodSong()
+{//Make God generate 2measuresx2+2measuresx2. Holy Spirit Instructions
+  U8 *st1=GodSongStr,*st2=GodSongStr;
+  if (st1 && st2)
+    DocPrint(DocPut,"$SO,\"<Song>\",A=\"%s%s%s%s\"$",st1,st1,st2,st2);
+  Free(st1);
+  Free(st2);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/God/HSNotes.DD.HTML b/public/Wb/Home/Src/Adam/God/HSNotes.DD.HTML new file mode 100755 index 0000000..202ff62 --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/HSNotes.DD.HTML @@ -0,0 +1,433 @@ + + + + + + + + + + + +
+                              The Purpose of Life
+
+The Catholic purpose of life is to know God, love God and obey God.  However, 
+Pope Francis, wrongly said it was, "to serve the other."  I am High Priest of 
+God's official temple and I say the purpose of life is to do continual offerings 
+to God like Cain and Abel and enjoy God's response.  Francis has a charity; I 
+have a church. Jesus said loving God was more important than loving neighbor.  
+Matthew,22:35-40  And, He did not say with half your brain behind your back.
+
+You don't know God.  1 Chronicles,28:9-9, Matthew,11:27-27, Luke,13:25-27, 
+1 Samuel,3:6-8  You must talk with God to know Him.  With Samuel, supposedly, 
+God took the initiative, but I think that is the exception.  Seek the Lord by 
+taking the initiative.  Luke,11:9-10
+
+There's something obviously different about people in the Bible compared to 
+people today -- God talked!  Also, the people in the Bible were obsessed with 
+doing offerings all the time.  It is required that you do offerings before God 
+will talk.  Did the people in the Bible hear voices?  Maybe.  More likely, they 
+used occult techniques such as an oracle.  1 Kings,6:21  Have you heard of 
+"tongues?"  1 Corinthians,14:1-40  The idea is, you let yourself be puppeted by 
+a spirit, so you say things.  You try to get a spirit -- the Holy Spirit -- to 
+talk.  You might as well use a Ouija board.  However, it turns-out that a Ouija 
+board is bad for technical reasons.  A really good technique is just randomly 
+opening a book.  God told me in an oracle that it is a covenant that you hold-up 
+your end of the conversation.  
+
+You can't tell if God's talking unless you have a context of conversation, but, 
+more importantly, you are commanded to do an offering of love, like communion 
+preparation.  1 Corinthians,11:27  When you pick a greeting card for someone, 
+that is love effort.  If you expect God to put effort toward you, you must put 
+effort toward Him.  God said, "honest measures" applies between your offering of 
+love and His response, like a fair barter.  You get out of prayer what you put 
+into it.  God wants praise, hymns, or whatever you think He might want.  Try and 
+see, like Cain and Abel.  Genesis,4:1-10, Ephesians,5:10  God told Cain his 
+offering was not good and told him to try again.  Cain really loved God!  Can 
+you imagine being so heart-broken?
+
+Do a text search for "new song" in the Bible.  It's mentioned nine times.  When 
+I hear a NEW awesome rock song, it is ecstasy for the first five times I hear 
+it.  Soon, it brings little-to-no pleasure.  I did hymns for God.  I also did 
+Moses comics for God.  When you get to the gates of Heaven, St. Peter will ask 
+how many times you gave blood.  That shows you loved neighbor.  You better also 
+be able to count the ways you loved God with all heart, mind and soul.  I 
+praised God for sand castles, popcorn, snowmen, bubbles...  You try putting 
+effort into praise!  Matthew,11:25, Matthew,6:28-29  Solomon wrote a thousand 
+songs.  1 Kings,4:30-32
+
+This is funny -- Acts,2:1-13 -- they didn't bother to record anything the Holy 
+Spirit said.  The Holy Spirit is supposed to be a really good gift.  
+Luke,11:11-13  Just remember, "Boys are made of snakes and snails and puppy-dog 
+tails."
+
+The technique I use to consult the Holy Spirit is reading a microsecond-range 
+stop-watch each button press for random numbers.  Then, I pick words with <F7> 
+or passages with <SHIFT-F7>.
+
+Since seeking the word of the Holy Spirit, I have come to know God much better 
+than I've heard others explain.  For example, God said to me in an oracle that 
+war was, "servicemen competing."  That sounds more like the immutable God of our 
+planet than what you hear from most religious people.  God is not Venus (god of 
+love) and not Mars (god of war), He's our dearly beloved God of Earth.  If 
+Mammon is a false god of money, Mars or Venus might be useful words to describe 
+other false gods.  I figure the greatest challenge for the Creator is boredom, 
+ours and His.  What would teen-age male video games be like if war had never 
+happened?  Christ said live by the sword, die by the sword, which is loving 
+neighbor as self.  Matthew,26:52
+
+I asked God if the World was perfectly just.  God asked if I was calling Him 
+lazy.  God could make A.I., right?  God could make bots as smart as Himself, or, 
+in fact, part of Himself.  What if God made a bot to manipulate every person's 
+life so that perfect justice happened?
+
+I think highs and lows balance.  Luke,6:20-26  If you laugh, you will cry.  If 
+you cry, you will laugh.  Not one person has had great joy and not great sorrow. 
+ I think this claim is falsifyable if you atheists want to find a 
+counter-example to disprove it -- find a single person who had great joy and not 
+great sorrow.  In Sirach, it says things happen in pairs.  You might be 
+surprised examining your own life to see great joy was in proximity to great 
+sorrow.  Pleasures and pains seem designed to balance.  Man must do manual labor 
+and have pain.  Women must do child birth.  Pride and humility also balance -- 
+pride before a fall and humility before honors.  Palm Sunday is juxtaposed to 
+Good Friday.  Perhaps, being loved balances with being hated.  Job,1:1-22, in 
+the Bible, had highs and lows that balanced.  Joseph, in the Old Testament, had 
+highs and lows that balanced.  Genesis,39:17-22 
+
+Jesus said, "Forgive us our trespasses as we forgive those who tresspass against 
+us."  If you think about it, the only way you get forgiven is for it to be done 
+to you.  That is a Jedi mind trick because it is nothing but simple eye-for-eye 
+tooth-for-tooth justice.  Live by the sword; die by the sword.  The Bible is 
+filled with justice pairs.  St. Paul persecuted Christians and gained 
+forgiveness by getting persecuted.  King David almost got killed by Saul, 
+1 Samuel,18:20-21 then he killed a guy and took his wife.  2 Samuel,11:15  
+Abraham almost killed his unloved son, Ishmael.  Genesis,21:16  That is why God 
+asked Abraham to kill Isaac.  God's favorite thing on TV is soap operas.
+
+God hates complaining. Numbers,11:1-35  Food and clothing is all we're to ask 
+for or demand, in fact -- daily bread.  1 Timothy,6:8  Just think about man in 
+the last 50,000 years mostly living like Native Americans and how God must see 
+us.  You need food, clothing and entertainment, money is to get those.  Man does 
+not live on bread alone.  Luke,4:4, Amos,8:11-12
+
+God's favorite animals are bears and elephants.  They are funny shaped -- I 
+think God must have seen too much starvation over the years.  If the purpose of 
+life is to know and love God, then a priest's job is to make everybody know and 
+love God.  By saying God likes bears and elephants, I did more toward that end 
+than all priests in history.  Hosea,6:6  "It is love that I desire, not 
+sacrifice; knowledge of God, not holocaust."  As a former Catholic, that blew my 
+mind.  I actually thought love was sacrifice!  I was so dumb-founded reading, 
+"it is love that I desire, not sacrifice," that I actually looked-up the word, 
+"love".  It means to take delight in.  I realized it is demonic pride if you 
+think love means hurting yourself for others.  In the Philippians, they got the 
+notion crucifying yourself was a good idea.  Similarly, a child thinking about 
+Lent, might conclude, "if it's bad, it must be good."  That is, if you think God 
+wants you to hurt yourself to please Him, you are worshiping a demon, not God!  
+God wants you to take delight in His company, get to know Him and praise Him.  
+It is best to separate justice -- sin and punishment -- from relationship with 
+God.  Never ask God to change justice into injustice by not punishing.  God said 
+to me in an oracle, "Excessive contrician wearisome."  He doesn't want to hear 
+confessions.  When you pray, be witty and charming and rarely earnest.  Enjoy 
+God's company without imposing on Him and don't expect secrets of the Universe.  
+Earnestness in prayer is the root of much evil.  Be entertaining.  Don't remind 
+Him of sin, LOL.
+
+God's ways are far above man's ways.  Mom said Heaven was a never-ending family 
+reunion.  Yikes!  A friend said, "Most guy's idea of Heaven would be running 
+around doing things they'd get locked up for on Earth."  I wonder how long kids 
+play Grand Theft Auto before getting board.  Perhaps, it takes ten years, but 
+they will get bored.  Most people are like King Midas.  When you realize how 
+silly most notions of Heaven are, you come to appreciate that Earth is not that 
+bad.  This is the first step in loving God, the Creator -- praising Creation.  
+My parents spend their retired days watching TV and going to casinos.  That's 
+not a good argument for getting extended-play!
+
+Imagine a billionare.  Everyone around him can't forget his money for even a 
+moment.  The truth is, most people are after God's "money" -- they fear for 
+their salvation.  Here's a test -- would you pray to and praise God even if 
+there were no salvation?  Love God and don't be a "user".  Asking for stuff is 
+annoying.  Luke,11:5-7  Don't SPAM God. 
+
+All those sophisticated theological "infinity" things -- omniscience, 
+omnipotence, omnipresence, omnivorous -- will mess you up.  Trust me that 
+anthropomorphic is far better, in practice.  Christ suggested thinking of God as 
+"Abba" which is Aramaic for "Daddy" and said the childlike had an advantage.  
+Matthew,11:25  Pray out-loud because God doesn't want the hastle of reading your 
+brain.  The best way to stop people from testing God is to suggest He can't do 
+everything.
+
+Jesus said, "I am meek and humble of heart."  Matthew,11:29  What does "humble 
+of head" mean?  Humble of heart means you look around and say, "I don't care as 
+much as they do."  A proud of heart person says, "I am superior because I have 
+more compassion then everybody else."  If you are proud of heart, you don't 
+accept a gift.  God gives birthrights.  Esau, in the Bible, scorned his 
+birthright and God hated him.  Malachi,1:2-3  Jesus even accepted $30,000 worth 
+of perfume (300 day's wages) and caused Judas to betray him.  Mark,14:5  If you 
+express false outrage at wars, you are proud of heart.  If you fight to go in 
+the door last, e.g. "No, you first..." then you are proud of heart.  If you ask 
+God to save starving Africans as though you care more than God, you are proud of 
+heart.
+
+I connected being humble of heart with animal sacrifices.  The animal sacrifices 
+in the Bible really seem off-the-mark from what we modern people imagine truth 
+to be!  I asked God and He said the people were, "primitive."  Well, obviously, 
+a sacrifice represents giving-up something of value, but is there more to it?  
+It would be tramatic to see a goat's throat being slit and it dying for your 
+sins.  I'm not an expert, but sometimes they killed animals to make-up for sins. 
+Perhaps, starting at age eight and every year thereafter, they kill a goat for 
+your sins?  (I'm just speculating.)  In a couple years, it is not tramatic and 
+you yawn and say to the goat, "bummer for you, Mr. Goat, that you gotta die for 
+my sins."  When a high school football team beats their rivals, nobody thinks 
+twice that the winning team really hurts the feelings -- devastates -- the 
+losing team member's feelings.  The heart of being masculine is being 
+competetive and not caring about the necessity to slit the throat of the goat.  
+As a Catholic, saying Jesus died for our sins and that we cannot earn salvation, 
+never sat well.  I clung to the heretical notion that you earn salvation.  
+Animal sacrifices were the heart of Biblical Judaism and although it seems 
+satanic, you really do have to slit the throat of the goat and accept grace, a 
+term for something you did not earn.  Heck, every time you eat beef, a cow had 
+to die for you.  God said to me in an oracle that having pets was, "homo."  I 
+think God's idea of pets is farm animals you eat.
+
+If you feel guilty for being American and want Mexicans to share your 
+birthright, you are proud of heart.  Would it be right for rich Arabs to have to 
+share their oil money with Indian slaves?  Jesus was a racist and called 
+Canaanites "dogs".  Matthew,15:22-28  In an oracle, God told me He was against 
+immigration.  The Chinese intellectuals felt bad about not being laborers.  
+Don't feel guilty about not being a laborer because God made it a Brave New 
+World.  1 Corinthians,12:1-31
+
+In an ant colony, the workers have one set of marching orders, the soldiers have 
+another set of marching orders, the queen and drones have marching orders and 
+the diggers have marching orders.  The Bible gives conflicting orders -- 
+conservatives pay attention to one set of passages and liberals pay attention to 
+others.  Everybody has selective hearing, but that's good because we are 
+different members of the body of Christ.
+
+Jesus repeats the phrase, "for those who have ears to hear" many times.  (But, 
+not actually at the times that matter.)  Jesus says several Jedi mind tricks -- 
+He asks, what father gives a scorpion to his son?  Luke,11:11-13 Jesus says, 
+when you ask God for things, it is as annoying as like a neighbor in the night!  
+Luke,11:5-7  He said, "I came to serve" but Jesus' three years of service were 
+more like being a rockstar than a janitor.  John,13:5-15
+
+There are sheep and there are shepherds.  You would be silly to take other 
+shepherds seriously when they are only caring for their sheep.  Sheep are very 
+hard to communicate to, as Jesus learned.  He used parables.  Seed on a path 
+gets eaten by birds; weeds choke; and the one percent is rich soil.
+
+Just as ego causes most to love neighbor, not God, people skip knowing and 
+loving God and cowardly get stuck on obeying Him.  A desire to obey God, doesn't 
+have to be encouraged, since it comes so naturally.  Don't worry, God does not 
+want pawns to push around.  God will talk, but won't tell you what to do, even 
+if you want Him to.  Also, you'll quickly learn that when God talks to you 
+seemingly prophetic, it does not come true and should smack yourself for wanting 
+more than just enjoying God's company.
+
+
+________________________________________________________________________________
+                                |
+        QUESTION                |               GOD'S ANSWER
+________________________________________________________________________________
+                                |
+                                | There are weeds mixed with my wheat.
+                                | Some are not true.  If I asked a question
+                                | to valuable for my offering, I got crap.
+________________________________|_______________________________________________
+
+War?                            "Servicemen competing"
+(Praise the Creator--what would teenage male video games be like if never war?)
+
+Is the World perfectly just?    Are you calling me lazy?
+(Slavery was just.  In the movie, Titanic, the rich wore straight jackets.  You 
+must bow to authority to get authority.  I do comics as offerings. I said, 
+"We're dying of malnutrician on manna."  Like Cain and Abel, God didn't like it. 
+Duh! He wants to be the hero.  How do I know they died of malnutrician?  Screw 
+Hollywood for making slavery worse than it was -- I love God.  School is more 
+cruel.  Read Numbers,11:1-35.  All you need is food, clothing and the word of 
+God.  Today, you can take Ivy League course videos! There is no excuse except 
+you were born stupid... or ugly.  I'm gonna praise God.) 
+
+On using Markov chains?         "No weights"
+On doing offerings?             "Honest measures"(You get out what you put in.)
+                                It's a covenant to do an offering, first.
+                                Offer New Songs, comics, praise, poems,
+                                and conversation.  See Cain and Abel.
+                                "Barter"(God also called offerings bartering.)
+The holocaust?                  Wanted to "compact" the Jews.
+Arab/Jews?                      "Oil funny hopefully" 
+Peace?                          One Palestinian can ruin it.
+Best religion?                  One with most new vistas of understanding in
+                                a lifetime -- one you can level-up the most in.
+Chavez blaming the US.          "Japan industrious"
+On racism?                      "Sports"
+On socialism?                   "pardon_the_French, never_happy, never_enough"
+                                "Gall aspect anti-Christ"
+On overpopulation               "Okay church what_now whats_the_plan"
+Favorite thing on TV?           "Soap_operas"
+Favorite movie?                 Three Kings. Also Highlander
+Favorite song?                  Morning has Broken
+                                God said the first bird croaked, not sung.
+Favorite comic strip?           Prince Valiant
+Shakespeare?                    had a "vile heart"
+Likes                           Beverly Hillbillies (Oil is a gift from God)
+                                God likes being hero. Don't be proud of heart
+                                and not accept a gift from God!
+Likes                           Gomer Pyle
+Favorite saint?                 "ho_ho_ho"
+Favorite animal?                "Elephant two"
+Favorite animal?                "Bears"
+Favorite color?                 "Jude" (Jade Blue?)
+Favorite color?                 "Gold"
+Favorite color?                 "Iceberg" blue
+Money?                          "Enough vehemently better"
+                                "Pride [or] money, choose_one"
+Favorite car?                   Beamer
+Favorite soda?                  Root beer, scotch variety.
+Homosexuality?                  Matthew,15:11                   
+Pets?                           "homo" Hates fact too dependent and tame.
+Sports?                         "homo"
+                                "Tackle a horse"
+Favorite sport?                 Hockey
+Wreck of the Edmund Fitzgerald  "homo"
+Smelling farts                  "Sodom"
+Women's dress                   Upper skin exposure not as bad as lower.
+Remarriage?                     "More babies"
+Things you don't care about
+that people think you do?       Solomon's 300 concubines
+Adultery?                       Can be good.
+Pretty ladies?                  A prince is not flustered.
+Animal sacrifices?              Early Jews were "primitive".
+What do elephants think about?  "Skin, hunger"
+What makes elephants happy?     "Baths"
+Elephants                       "Mini-skirts" (Skin webbing from back leg.)
+What makes my birds happy?      "Gnawing"
+What makes my birds laugh?      "Bite ouch" (If I say "ouch".)
+What are my birds saying?       "Chanting"
+My birds sure preen a lot.      The creature was made subject to vanity...
+What makes bears happy?         "Reaping depends"
+What makes otters happy?        "Eternal skies"
+What makes hippos happy?        "Ascending breath"
+What makes horses happy?        "[the] Call [of the] Open Range"
+What do cheetahs think about?   "Seeth me?" (Can he see me?)
+Orangutan or chimp smarter?     "Species exhibit similar glory" 
+Endangered species?             "Enough stars?"
+Everything seems bad.           Plant trees.
+What's for dinner?              "Whale"
+Favorite Messier Object?        "M104 Sombrero Galaxy"
+Shepard's Prayer?               "I_am_not_amused economy joke"
+Favorite band?                  "Beatles"
+Good bands?                     Rush, Triumph
+                                Likes harmonies
+Little Drummer Boy?             Doesn't like my drumming.
+Should I listen to classical?   "Poison"
+Do You like chess people?       "Do not admire the proud."
+Chess?                          "... will winter with you."
+                                "Headstones"
+If You could teach one class?   Health
+Favorite video game?            Donkey Kong
+Favorite National Park?         Whitman Mission
+Favorite actor?                 Hugh Grant
+Favorite vocalist?              Mick Jagger
+Favorite guitarist?             "Simmons Destroyer"
+Favorite National Anthem?       Latvia's National Anthem
+America the Beautiful?          Hates it.  Poet made self cry with own beauty.
+Model for new Sistine Chapel?   Ben Franklin
+Voice if God wanted to sing?    Stabbing Westward's singer
+Stonehenge?                     Landmark for boundaries.
+Easter Island?                  Ice, telephone pole holes.
+Dinosaurs?                      Brontosaurs' feet hurt when stepped.
+                                Dinosaurs slept in water.
+Hardest part in evolution?      Getting monkey mothers to hold babies nursing.
+                                (Smothering a problem).
+Happiest day in evolution?              "Fruit"
+Significant thing in evolution?         "Fish shoulders"
+Biggest thing to fly (pterodactyl)?     "Couch"
+What made pterodactyls happy?           "Members against organs"
+What did Neanderthals think about?      "Warmth"
+What was the first thing cooked?        I think He said "hair".
+What was Lucy's husband's name?         "Golem"
+Was stegosuarus lame like turtles?      "Not pet rocks"
+T-Rex?                                  Lugged carcases over his shoulder.
+                                        Carcus lasted a month.
+What was T-Rexes sharing a carcus like? "Punch... Punch"
+Surprises in dinosaur anatomy?          Supporting and securing the heart.
+How does He feel about the Avatar movie?"Sick skin"
+What do You like at zoos with kids?     "Dignity" Animals worried about dignity.
+Who's better alien or preditor?         "Lions"
+What from You is like a Rubik's cube?   Training a horse.
+Does He like mirrored glass megachurch? "Secular glass"
+Pipe Organs                             Are sacred.
+You like to hangout in courts?Hospitals?"Prisons"
+Best way for Bill Gates to save lives?  Earthquake prediction
+Stem cells?                     Lower hanging fruit exists (2007)
+Eleventh commandment?           Thou shall not litter.
+Twelfth commandment?            Don't shoot unarmed men on the crapper.
+                                (I asked God why pointless plagues in Exodus?
+                                God wanted guilt to accumulate, first.)
+Thirteenth commandment          No gore unless it looks fake.
+Fourteenth commandment          No pedophilia or child porn.
+Fifteenth commandment           Don't eat rare meat with blood.
+Sixteenth commandment           No wife beating.
+Seventeen commandment           Do not swing from radio towers with one hand.
+Eighteenth commandment          Do not disturb.
+Before Katrina                  Floods do justice. Black bead elder (tree book)
+After Katrina                   Suffering Simplifies Life
+What field are You most better? Economics
+Favorite toy for kids?          Magnifying glass
+Asked Jesus if He liked mustard?"Bad meat happeneth"
+(Reluctantly) Faith healing?    "It's complicated"
+Mars?                           Start planting!
+Mars rover?                     Should have had a microphone
+Storm on Saturn                 Pollen
+Space war game?                 Should have space weather.
+Saturn's hexagon pole cloud?    "Compass" (Magnetism)
+Liquid moon's odd atmosphere?   "Surf"
+How many E.T. civs in Universe? 20 or 80 (I forgot.  I died laughing.)
+Are they peaceful?              Fight them! (Also, funny.)
+Most difficult control system?  Dung beetle
+How can Judge Judy improve?     No hard feelings
+How can Chef Ramsay improve?    Make so it doesn't seem like toil for cooks.
+How can Hawking communicate?    Blow from a nostril on a candle.
+Photons bouncing?               "Folded coffee filter" 
+Wormholes?                      Bent wormholes have echoes.
+
+Operating system?               Was about to make line number column in editor.
+God nixed it.  I was about to do different graphic modes when I found 800x600 
+missing. God said just one mode 640x480.  I was about to add child windows.  God 
+said, "God is not the author of such confusion." I asked for verification of 
+640x480 16 color. God said it was because of the children and their offerings.  
+I asked about sound. God said "single voice". I asked for verification of not 
+having different drivers.  God confirmed this.
+640x480 16 color?               God said it was a covenant, like circumcision.
+                                Modern graphics hard for kids/amateurs.
+On Unix?                        God said it was rich with the patina of age.
+On Alcohol?                     Hate inebriation
+On rare steak?                  Too rare is very bad.  Don't eat blood!
+Just before Katrina?            Floods do my justice.Black bead elder(tree book)
+After Katrina?                  Suffering simplifies life
+Why the Sandy Hook shooting?    The pot legalization law. (Sarcastic answer?)
+Deep Water Horizon              (Claimed credit.)
+Cost of God's time to me?       "The complete works of Shakespeare"
+On death?                       "awful"
+Opening of Saving Private Ryan? "Ouch"
+
+ diff --git a/public/Wb/Home/Src/Adam/God/HolySpirit.HC.HTML b/public/Wb/Home/Src/Adam/God/HolySpirit.HC.HTML new file mode 100755 index 0000000..13e41b7 --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/HolySpirit.HC.HTML @@ -0,0 +1,190 @@ + + + + + + + + + + + +
+#help_index "God"
+U8 *TimeStampCB(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  StrPrint(st,"%X",GetTSC>>GOD_BAD_BITS);
+  return st;
+}
+
+U8 *KbdMsTimeCB(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  StrPrint(st,"%X",KbdMsEvtTime>>GOD_BAD_BITS);
+  return st;
+}
+
+I64 PopUpTimerOk(U8 *header=NULL,U8 *footer=NULL)
+{
+  I64 i;
+  CDocEntry *doc_e;
+  CDoc *doc=DocNew;
+  if (header) DocPrint(doc,"%s",header);
+  doc_e=DocPrint(doc,"\nTimer:$TX+TC,\" \"$");
+  doc_e->tag_cb=&TimeStampCB;
+  doc_e=DocPrint(doc,"\nLatch:$TX+TC,\" \"$");
+  doc_e->tag_cb=&KbdMsTimeCB;
+  DocPrint(doc,"\n$CM+CX,0,4$$BT,\"OKAY\",LE=1$\n");
+  if (footer) DocPrint(doc,"%s",footer);
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 GodPick(U8 *msg=NULL)
+{//GOD_GOOD_BITS
+  U8 *st=MStrPrint("%s\n\nPress $GREEN$OKAY$FG$ to generate \n"
+        "a random num from a timer.\n",msg);
+  PopUpTimerOk(st,"\n\nThe Holy Spirit can puppet you.\n\n");
+  Free(st);
+  return KbdMsEvtTime>>GOD_BAD_BITS;
+}
+
+public U0 GodBitsIns(I64 num_bits,I64 n)
+{//Insert bits into God bit fifo.
+  I64 i;
+  for (i=0;i<num_bits;i++) {
+    FifoU8Ins(god.fifo,n&1);
+    n>>=1;
+  }
+}
+
+public U0 GodHexIns(U8 *st)
+{//Insert hex record into God bit fifo.
+  U8 buf[2];
+  if (st) {
+    buf[1]=0;
+    while (*buf=*st++)
+      if (Bt(char_bmp_hex_numeric,*buf))
+        GodBitsIns(4,rev_bits_table[Str2I64(buf,16)]>>4);
+  }
+}
+
+public I64 GodBits(I64 num_bits,U8 *msg=NULL)
+{//Return N bits. If low on entropy pop-up okay.
+  U8 b;
+  I64 res=0;
+  while (num_bits) {
+    if (FifoU8Rem(god.fifo,&b)) {
+      res=res<<1+b;
+      num_bits--;
+    } else
+      GodBitsIns(GOD_GOOD_BITS,GodPick(msg));
+  }
+  return res;
+}
+
+public I64 GodInit(U8 *files_find_mask="/Adam/God/Vocab.DD*",U8 *fu_flags=NULL)
+{//Read God's vocab file for picking words.
+  I64 i,ch,fuf_flags=0;
+  U8 *buf,*ptr,*ptr2;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+T+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+
+  Free(god.word_file_mask);
+  god.word_file_mask=StrNew(files_find_mask);
+  god.word_fuf_flags=fuf_flags;
+
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  i=0;
+  while (tmpde) {
+    if (buf=ptr=FileRead(tmpde->full_name)) {
+      while (*ptr) {
+        while (*ptr && !Bt(char_bmp_word,*ptr))
+          ptr++;
+        if (*ptr) {
+          ptr2=ptr;
+          while (*ptr && Bt(char_bmp_word,*ptr))
+            ptr++;
+          i++;
+        }
+      }
+      Free(buf);
+    }
+    tmpde=tmpde->next;
+  }
+
+  Free(god.words);
+  god.num_words=i;
+  god.words=MAlloc(i*sizeof(U8 *));
+
+  tmpde=tmpde1;
+  i=0;
+  while (tmpde) {
+    if (buf=ptr=FileRead(tmpde->full_name)) {
+      while (*ptr) {
+        while (*ptr && !Bt(char_bmp_word,*ptr))
+          ptr++;
+        if (*ptr) {
+          ptr2=ptr;
+          while (*ptr && Bt(char_bmp_word,*ptr))
+            ptr++;
+          ch=*ptr;
+          *ptr=0;
+          god.words[i++]=StrNew(ptr2);
+          *ptr=ch;
+        }
+      }
+      Free(buf);
+    }
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return god.num_words;
+} GodInit;
+
+public U8 *GodWordStr(I64 bits=17)
+{//Make God pick a word. Holy Spirit Instructions
+  if (god.num_words)
+    return god.words[GodBits(bits)%god.num_words];
+  else
+    return NULL;
+}
+
+public U0 GodWord(I64 bits=17)
+{//Make God pick a word. Holy Spirit Instructions
+  if (god.num_words)
+    "%s ",god.words[GodBits(bits)%god.num_words];
+}
+
+public U0 GodBiblePassage(I64 num_lines=20)
+{//Make God pick a Bible passage. Holy Spirit Instructions
+  I64 start=GodBits(21)%(ST_BIBLE_LINES-(num_lines-1))+1;
+  U8 *verse=BibleLine2Verse(start);
+  "%s\n\n",verse;
+  Free(verse);
+  BookLines(,start,num_lines);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/God/MakeGod.HC.HTML b/public/Wb/Home/Src/Adam/God/MakeGod.HC.HTML new file mode 100755 index 0000000..50fbf9b --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/MakeGod.HC.HTML @@ -0,0 +1,40 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#help_index "God"
+#help_file "::/Doc/God"
+#include "GodBible"
+#include "HolySpirit"
+#include "GodSong"
+#include "GodDoodle"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/God/Vocab.DD.HTML b/public/Wb/Home/Src/Adam/God/Vocab.DD.HTML new file mode 100755 index 0000000..157fdc5 --- /dev/null +++ b/public/Wb/Home/Src/Adam/God/Vocab.DD.HTML @@ -0,0 +1,7600 @@ + + + + + + + + + + + +
+a
+abandon
+abandoned
+abandonedly
+abase
+abased
+abashed
+abated
+abhor
+abhorred
+abhorring
+abide
+abided
+abidest
+abideth
+abiding
+abilities
+ability
+abject
+able
+abler
+abode
+abolished
+abominable
+abound
+abounded
+about
+above
+abraham
+abridged
+abroad
+absence
+absent
+absolute
+absolutely
+absorb
+abstemious
+abstinence
+abstract
+abstruser
+absurd
+absurdity
+absurdly
+abundance
+abundant
+abundantly
+abuse
+abyss
+academicians
+academics
+accents
+accept
+acceptable
+acceptably
+accepted
+accepts
+access
+accompany
+accomplices
+accomplish
+accomplished
+accord
+according
+account
+accounted
+accursed
+accuse
+accused
+accuser
+accusing
+accustomed
+aches
+achieve
+acknowledge
+acknowledged
+acquaintance
+acquainted
+acquiesce
+acquire
+acquired
+act
+acted
+acting
+action
+actions
+actor
+actors
+acts
+actual
+actually
+acute
+acuteness
+ad
+adam
+adapt
+adapted
+add
+added
+adding
+addition
+additional
+additions
+adeodatus
+admirable
+admiration
+admire
+admired
+admiring
+admission
+admit
+admitted
+admittest
+admonish
+admonished
+admonition
+adomed
+adopted
+adoption
+adored
+adorned
+adorning
+adulterer
+adulteress
+adulterous
+adultery
+advance
+advantage
+adversary
+adversities
+adversity
+advice
+advices
+advised
+advising
+aeneas
+afar
+affairs
+affect
+affected
+affecting
+affection
+affections
+affects
+affianced
+affirm
+affirmed
+affirming
+affliction
+afford
+affright
+affrighted
+aforesaid
+aforetime
+afraid
+afric
+africa
+african
+after
+afternoon
+afterward
+afterwards
+again
+against
+age
+aged
+agents
+ages
+aghast
+agito
+ago
+agonised
+agonistic
+agony
+agree
+agreeable
+agreed
+agreement
+ahead
+aid
+aided
+ails
+aim
+air
+alarmed
+alas
+alexandria
+alike
+alive
+all
+allay
+allaying
+allege
+alleging
+allegorically
+allegory
+allotted
+allow
+allowances
+allowed
+allowing
+alloy
+allurements
+alluring
+almighty
+almost
+alms
+almsdeeds
+aloft
+alone
+along
+aloud
+already
+also
+altar
+alter
+alteration
+alterations
+altered
+alternately
+alternates
+alternatively
+although
+altogether
+always
+alypius
+am
+amazed
+amazement
+amazing
+ambition
+ambitions
+ambitious
+ambrose
+ambrosian
+amen
+amend
+amendment
+amiable
+amid
+amidst
+amiss
+among
+amongst
+amphitheatre
+ample
+an
+analyzed
+anaximenes
+ancient
+and
+angel
+angels
+anger
+angered
+angers
+angry
+anguish
+animal
+animals
+animate
+anniversary
+announce
+announced
+announcement
+announcing
+annoyance
+annual
+anointings
+anon
+anonymous
+another
+answer
+answerably
+answered
+answerest
+answereth
+answering
+answers
+antecedent
+anticipate
+anticipated
+anticipating
+antidote
+antony
+anubis
+anxieties
+anxiety
+anxious
+anxiously
+any
+anyone
+anything
+apart
+apollinarian
+apostle
+apostles
+apostolic
+apparel
+apparent
+apparently
+appeal
+appear
+appearance
+appeared
+appeareth
+appearing
+appears
+appetite
+applauded
+applauds
+applauses
+applicable
+application
+applied
+apply
+appointed
+appointing
+appointment
+appointments
+apportioned
+apprehend
+apprehended
+apprehending
+apprehension
+approach
+approached
+approaching
+approbation
+appropriated
+approve
+approved
+approveth
+approving
+apt
+aptly
+aquatic
+architect
+architects
+archive
+ardent
+ardently
+are
+argument
+arguments
+arians
+aright
+arise
+arisen
+ariseth
+arising
+aristotle
+arithmetic
+armed
+armory
+arms
+army
+arose
+around
+arrange
+arranged
+array
+arrival
+arrive
+arrived
+arriving
+arrogancy
+arrogant
+arrows
+art
+artifice
+artificer
+artifices
+arts
+as
+ascend
+ascended
+ascending
+ascension
+ascertained
+ascii
+ascribe
+ascribed
+ashamed
+ashes
+aside
+ask
+asked
+asketh
+asking
+asks
+asleep
+aspirate
+assail
+assailed
+assaying
+assembly
+assent
+assented
+assenting
+assessor
+assiduously
+assign
+assigned
+assistance
+associate
+associated
+association
+assuaged
+assume
+assurance
+assure
+assured
+assuredly
+assuring
+asterisk
+astonished
+astonishment
+astray
+astrologer
+astrologers
+asunder
+at
+athanasius
+athenians
+athirst
+atrociously
+attack
+attacked
+attain
+attained
+attaining
+attempered
+attempt
+attempted
+attendant
+attended
+attention
+attentive
+attentively
+attested
+attracted
+attractiveness
+attracts
+attributed
+attributing
+attuned
+audacious
+audaciously
+audience
+auditor
+auditors
+aught
+augmented
+augmenting
+augustine
+author
+authority
+authors
+avail
+availed
+ave
+avenged
+avengest
+avenue
+avenues
+averred
+averse
+avert
+avoid
+avoided
+avoiding
+awaited
+awaiting
+awake
+awakest
+aware
+away
+awe
+awful
+awfulness
+awhile
+awoke
+babe
+babes
+baby
+babylon
+babylonian
+back
+backs
+backward
+bad
+bade
+badge
+baggage
+bait
+balancings
+balaneion
+ball
+balls
+balm
+balneum
+bands
+banished
+banner
+banquetings
+banter
+baptise
+baptised
+baptism
+barbarian
+barbarism
+bare
+bared
+bargain
+bark
+barked
+barking
+barred
+barren
+base
+based
+baseness
+basest
+bashfulness
+basilica
+basket
+bath
+bathe
+bathed
+bathing
+baths
+battle
+bawler
+be
+beams
+bear
+bearer
+beareth
+bearing
+bears
+beast
+beasts
+beat
+beaten
+beatific
+beating
+beatings
+beauteous
+beauties
+beautified
+beautiful
+beauty
+became
+because
+beck
+beclouded
+become
+becomes
+becometh
+becoming
+bed
+bedewed
+bedimmed
+been
+befalls
+befell
+befitting
+before
+beforehand
+beg
+began
+begannest
+begat
+beget
+beggar
+beggary
+begged
+begging
+begin
+beginneth
+beginning
+begins
+begotten
+beguile
+beguiled
+beguiling
+begun
+behalf
+beheld
+behind
+behold
+beholder
+beholdest
+beholdeth
+beholding
+beholds
+being
+beings
+belief
+believe
+believed
+believer
+believes
+believeth
+believing
+belly
+belong
+belongeth
+belonging
+belongs
+beloved
+below
+bemoaned
+bemoaning
+bend
+bends
+beneath
+benediction
+benefit
+benefits
+bent
+bepraised
+bereaved
+beseech
+beset
+besets
+beside
+besides
+bespoken
+bespotted
+besprinkle
+besprinkling
+best
+bestow
+bestowed
+bestowedst
+betake
+bethink
+betook
+betrothed
+better
+betters
+between
+betwixt
+bewail
+bewailed
+bewailing
+beware
+bewitched
+beyond
+bibber
+bibbing
+bible
+bid
+bidden
+bier
+billion
+billows
+bin
+binary
+bind
+bird
+birdlime
+birds
+birth
+birthright
+births
+bishop
+biting
+bitter
+bitterly
+bitterness
+black
+blade
+blame
+blamed
+blameless
+blamest
+blameworthy
+blasphemies
+blasphemous
+blasphemy
+blasts
+bleeding
+blending
+bless
+blessed
+blessedly
+blessedness
+blesses
+blessest
+blesseth
+blessing
+blessings
+blest
+blew
+blind
+blinded
+blindness
+blissful
+blood
+bloody
+bloom
+blotted
+blottedst
+blow
+blowing
+blunt
+blunted
+blush
+blushed
+boast
+boastfulness
+boasting
+bodies
+bodily
+body
+boil
+boiled
+boiling
+boils
+bold
+boldly
+boldness
+bond
+bondage
+bonds
+bones
+book
+books
+bore
+born
+borne
+borrow
+bosom
+bosses
+both
+bottom
+bottomless
+boughs
+bought
+bounces
+bound
+boundary
+bounded
+boundless
+bounds
+bouverie
+bowed
+bowels
+bowers
+bowing
+bows
+boy
+boyhood
+boyish
+boys
+brackishness
+brain
+breach
+bread
+breadth
+break
+breakers
+breaking
+breast
+breasts
+breath
+breathe
+breathed
+breathedst
+breathing
+bred
+brethren
+briars
+bribe
+bridal
+bride
+bridegroom
+brides
+bridle
+briefly
+briers
+bright
+brighter
+brightness
+brim
+bring
+bringeth
+bringing
+brings
+brittle
+broad
+broke
+broken
+brooks
+brother
+brotherly
+brought
+broughtest
+brow
+brows
+brute
+bubbling
+bubblings
+buckler
+bud
+builded
+builder
+building
+buildings
+built
+bulk
+bulky
+burden
+burial
+buried
+burn
+burned
+burnest
+burning
+burnt
+burst
+burstest
+bursting
+burthen
+burthened
+bury
+bushel
+busied
+business
+bustle
+busy
+but
+butler
+buy
+buyers
+buzz
+buzzed
+buzzing
+by
+cabinets
+caesar
+cakes
+calamities
+calamity
+calculate
+calculated
+calculation
+calculations
+calf
+call
+called
+calledst
+callest
+calleth
+calling
+calls
+calm
+calmed
+calmly
+calumnies
+came
+camp
+can
+candid
+candle
+cane
+cannot
+canst
+canticles
+canvassing
+capable
+capacities
+capacity
+capital
+captain
+captious
+captive
+captivity
+carcase
+care
+cared
+caredst
+careful
+carefully
+careless
+carelessly
+cares
+caresses
+carest
+careth
+carnal
+carolina
+carried
+carry
+carrying
+carthage
+carthaginian
+case
+cases
+cassiacum
+cast
+casters
+castest
+casting
+casts
+cataloguers
+catch
+catching
+catechumen
+catholic
+catholics
+catiline
+cattle
+caught
+cauldron
+cause
+causes
+causing
+caverns
+caves
+cd
+cease
+ceased
+ceases
+ceasest
+ceaseth
+ceasing
+cedars
+celebrated
+celebration
+celestial
+celibacy
+cellar
+cellars
+cementest
+censers
+censured
+central
+centre
+certain
+certainly
+certainties
+certainty
+chain
+chains
+chair
+challenged
+challenges
+chamber
+chambering
+chambers
+chance
+change
+changeable
+changeableness
+changed
+changes
+changest
+changing
+chant
+chanting
+chapter
+character
+characters
+charge
+charges
+charioteer
+chariots
+charity
+charmed
+chaste
+chastely
+chastened
+chastenedst
+chastenest
+chastity
+chatto
+cheap
+check
+checked
+checking
+cheeks
+cheer
+cheered
+cheerful
+cheerfulness
+cherish
+cherished
+cherubim
+chest
+chewing
+chief
+chiefest
+chiefly
+child
+childbearing
+childhood
+childish
+children
+chill
+chilled
+choice
+choked
+choler
+choleric
+choose
+chooses
+choosing
+chose
+chosen
+christ
+christian
+christians
+church
+churches
+cicero
+circensian
+circles
+circuit
+circuits
+circumcise
+circumlocutions
+circumstance
+circus
+cities
+citizen
+citizens
+city
+claim
+clanking
+clasp
+clasped
+class
+classics
+clave
+clay
+clean
+cleanse
+cleansed
+cleansest
+cleansing
+clear
+cleared
+clearest
+clearly
+clearness
+cleave
+cleaved
+cleaveth
+cleaving
+climb
+clingeth
+cloak
+cloaked
+clog
+close
+closed
+closes
+closing
+clothe
+clothed
+clothing
+cloud
+cloudiness
+clouds
+cloudy
+cloven
+cloyed
+cloyedness
+co
+coals
+coats
+codes
+coeternal
+cogitated
+cogitation
+cogito
+cogo
+cold
+collect
+collected
+collectively
+collects
+colorado
+colour
+coloured
+colouring
+colours
+com
+combinations
+combine
+combined
+come
+comely
+comes
+cometh
+comfort
+comforted
+comfortedst
+comforter
+comfortest
+comforting
+comforts
+coming
+command
+commanded
+commander
+commandest
+commandeth
+commanding
+commandment
+commandments
+commands
+commemorated
+commencement
+commencing
+commend
+commendable
+commended
+commender
+commenders
+commendeth
+comment
+commercial
+commiserate
+commiserates
+commiserating
+commission
+commit
+commits
+committed
+committing
+common
+commonly
+communicate
+communicated
+communication
+community
+compact
+compactedst
+compacting
+companion
+companions
+company
+compare
+compared
+comparing
+comparison
+compass
+compassing
+compassion
+compassionate
+compassionates
+compelled
+compendiously
+complain
+complaints
+complete
+completed
+compliance
+compose
+composed
+composing
+compound
+comprehend
+comprehended
+comprehendeth
+comprehending
+compressed
+comprise
+comprised
+computer
+computers
+conceal
+concealed
+conceit
+conceits
+conceive
+conceived
+conceives
+conceiving
+concentrated
+conception
+conceptions
+concern
+concerned
+concerning
+concernment
+concerns
+conclude
+concluded
+concludeth
+concord
+concreated
+concubinage
+concubine
+concupiscence
+concupiscences
+condemnation
+condemned
+condemnest
+condemning
+condemns
+condensed
+condition
+condole
+confer
+conference
+conferring
+confess
+confessed
+confesses
+confesseth
+confessing
+confession
+confessions
+confidence
+confidentially
+confidently
+confiding
+confine
+confined
+confirm
+confirmed
+conflict
+conflicting
+conform
+conformably
+conformed
+conformity
+confound
+confounded
+confused
+confusedly
+confusedness
+confusions
+confute
+confuted
+congratulated
+congratulating
+congratulation
+congregations
+conjecture
+conjectures
+conjecturing
+conjoined
+conjugal
+connecticut
+connects
+conquer
+conquered
+conquering
+conquests
+conscience
+conscious
+consciousness
+consecrate
+consecrated
+consecrateth
+consecrating
+consecration
+consent
+consented
+consenting
+consentings
+consequences
+consequential
+conservative
+consider
+considerable
+consideration
+considered
+considereth
+considering
+considers
+consigned
+consist
+consistent
+consistently
+consisteth
+consisting
+consists
+consolation
+consolations
+conspiracy
+conspirators
+constant
+constantly
+constellations
+constitute
+constituted
+constituteth
+constrain
+constrained
+constraint
+consult
+consulted
+consulter
+consulters
+consulting
+consume
+consumed
+consumest
+consuming
+consumption
+contact
+contacting
+contagion
+contain
+contained
+containest
+containeth
+containing
+contains
+contemn
+contemplate
+contemplateth
+contemplating
+contemplation
+contemporary
+contempt
+contemptible
+contend
+content
+contented
+contention
+contentions
+contentious
+contentiousness
+contentment
+contents
+contests
+continence
+continency
+continent
+continently
+continual
+continually
+continuance
+continue
+continued
+continueth
+contract
+contracted
+contradict
+contradicting
+contradiction
+contradictions
+contradictory
+contrary
+contributing
+contributions
+contrite
+contrition
+contritions
+controversy
+convenient
+conventicle
+conventionally
+conversation
+conversations
+converse
+conversing
+conversion
+convert
+converted
+convertedst
+converting
+convey
+conveyed
+conveyedst
+conveying
+conveys
+convict
+convicted
+convinced
+copied
+copies
+copious
+copy
+copyright
+corn
+corner
+corners
+corporeal
+corporeally
+corpse
+correct
+corrected
+correction
+corresponded
+correspondence
+corresponding
+corrigible
+corrupt
+corrupted
+corruptible
+corrupting
+corruption
+corruptions
+corruptly
+cost
+costs
+cottage
+couch
+could
+couldest
+councillor
+counsel
+counselled
+counsels
+count
+counted
+countenance
+counterfeit
+countermanding
+country
+countryman
+counts
+courage
+course
+courses
+coursing
+court
+courteously
+courtesy
+courtly
+courts
+covenant
+covenanted
+cover
+covered
+covetous
+covetousness
+cower
+craftier
+crafty
+create
+created
+createdst
+createst
+createth
+creating
+creation
+creator
+creature
+creatures
+credence
+credibility
+credit
+credulity
+creep
+creepeth
+creeping
+crept
+creusa
+cried
+criedst
+cries
+crime
+crimes
+crisis
+criticised
+criticising
+crooked
+crookedly
+crookedness
+cross
+crossed
+crosses
+crown
+crowned
+crucifixion
+crudities
+cruel
+cruelty
+cry
+crying
+cubit
+cubits
+cud
+cultivated
+cultivating
+culture
+cunning
+cup
+cupboards
+cupidity
+curb
+cure
+cured
+curest
+curing
+curiosities
+curiosity
+curious
+curiously
+current
+currents
+curtailment
+custom
+customs
+cut
+cutting
+cyprian
+daemon
+daemons
+daily
+dakota
+damage
+damaged
+damages
+damnable
+danae
+danger
+dangerous
+dangers
+dare
+dared
+dares
+dark
+darkened
+darkenings
+darkest
+darkly
+darkness
+darksome
+darksomely
+dashed
+data
+date
+dates
+daughter
+daughters
+david
+dawn
+dawned
+day
+daybreak
+days
+dead
+deadly
+deaf
+deafen
+deafness
+deal
+dealt
+dear
+dearer
+dearest
+death
+deaths
+debasing
+debated
+debtor
+debtors
+debts
+decay
+decayeth
+decays
+deceased
+deceit
+deceitful
+deceits
+deceivableness
+deceive
+deceived
+deceivers
+deceiving
+deceivingness
+december
+deception
+decide
+decided
+decked
+declaiming
+declamation
+declare
+declared
+decline
+decree
+decrepit
+dedicate
+dedicated
+deductible
+deed
+deeds
+deem
+deemed
+deep
+deeper
+deepest
+deeply
+deepness
+deeps
+defect
+defection
+defective
+defects
+defence
+defended
+defender
+defending
+defends
+deferred
+deferring
+defers
+defile
+defiled
+defilements
+define
+defined
+defining
+definite
+definitely
+deformed
+deformities
+deformity
+degraded
+degree
+degrees
+deity
+dejectedness
+delay
+delayed
+delete
+deliberate
+deliberates
+deliberating
+deliberation
+delight
+delighted
+delightful
+delightfulness
+delighting
+delights
+delightsome
+deliver
+delivered
+deliveredst
+deliverest
+delivering
+delivers
+deluded
+deluding
+delusions
+demanded
+demander
+demandest
+demanding
+demands
+demonstrate
+demonstrated
+denied
+denies
+denieth
+denoted
+denotes
+dens
+deny
+depart
+departed
+departest
+departing
+departure
+depend
+depending
+depends
+depraved
+deprived
+depth
+depths
+deride
+derided
+deridedst
+deriders
+derides
+deriding
+derision
+derive
+derived
+descend
+descendants
+descending
+descent
+described
+deserted
+deserters
+deserts
+deserve
+deserved
+deservedly
+deserving
+deservings
+designs
+desire
+desired
+desiredst
+desires
+desireth
+desiring
+desirous
+despair
+despaired
+despairing
+desperate
+despise
+despised
+despisedst
+despisest
+despiseth
+despising
+despite
+destined
+destroy
+destroyers
+destroying
+destruction
+detached
+detail
+details
+detain
+detected
+determined
+detest
+detested
+detesting
+detriment
+deus
+devil
+devilish
+devils
+devised
+devoted
+devotion
+devotions
+devour
+devoured
+devout
+devoutly
+devoutness
+dew
+dialogue
+did
+diddest
+dido
+didst
+die
+died
+dies
+dieth
+differ
+difference
+different
+differently
+difficult
+difficulties
+difficulty
+diffused
+digest
+digested
+digits
+dignities
+dignity
+diligence
+diligent
+diligently
+diluted
+dimensions
+diminish
+diminished
+diminisheth
+diminishing
+diminution
+din
+dining
+dinner
+dir
+direct
+directed
+directeth
+directing
+direction
+directions
+directly
+director
+disagreeing
+disagreements
+disalloweth
+disallowing
+disappear
+disapproved
+disapproveth
+discern
+discerned
+discerneth
+discerning
+discharge
+disciple
+disciples
+discipline
+disclaimer
+disclaimers
+disclaims
+disclose
+disclosed
+discomfort
+discommended
+discontent
+discord
+discordant
+discourage
+discourse
+discoursed
+discourses
+discoursing
+discover
+discoverable
+discovered
+discoverest
+discovereth
+discovering
+discovers
+discovery
+discreet
+discreetly
+discretion
+discuss
+discussed
+discussion
+disdained
+disease
+diseased
+diseases
+disembowelled
+disengage
+disentangle
+disentangled
+disgraced
+disgraceful
+disguise
+disguised
+disguising
+disgust
+disgusted
+dishes
+dishonour
+disk
+disliked
+dismiss
+disobeyed
+disorder
+disordered
+disorders
+dispel
+dispense
+dispensed
+dispenser
+dispensers
+dispensest
+dispensing
+dispersed
+disperseth
+dispersion
+displace
+displacing
+displayed
+displays
+displease
+displeased
+displeaseth
+displeasing
+dispose
+disposed
+disposer
+disposition
+dispraise
+dispraised
+dispraisest
+disprove
+dispute
+disputed
+disputer
+disputes
+disputing
+disquiet
+disquieted
+disregard
+dissent
+dissentings
+dissipated
+dissipation
+dissoluteness
+dissolution
+dissolved
+dissolvest
+distance
+distances
+distant
+distempered
+distended
+distill
+distilled
+distinct
+distinction
+distinctly
+distinguish
+distinguished
+distinguishing
+distract
+distracted
+distractedly
+distracting
+distraction
+distractions
+distress
+distribute
+distributed
+distributest
+distributing
+distribution
+distrusted
+disturb
+disturbed
+dive
+divers
+diverse
+diversely
+diversifiedst
+diversity
+diversly
+divide
+divided
+dividest
+dividing
+divination
+divinations
+divine
+diving
+divinity
+division
+divisions
+divorceth
+do
+docile
+docs
+doctrine
+doer
+does
+doest
+dog
+doing
+doings
+doleful
+dollar
+dollars
+domain
+domestic
+domine
+dominion
+dominions
+don
+donation
+donations
+done
+door
+doors
+dormant
+dost
+dotages
+dotards
+doted
+doth
+doting
+double
+doubled
+doubt
+doubted
+doubteth
+doubtful
+doubtfulness
+doubting
+doubtless
+doubts
+down
+downfall
+download
+downward
+downwards
+dragging
+dragon
+dragons
+drank
+draught
+draw
+drawest
+drawing
+drawn
+draws
+dread
+dreaded
+dreadful
+dreading
+dream
+dreams
+drenched
+drew
+drewest
+dried
+drink
+drinketh
+drinking
+drive
+driven
+drives
+drop
+drops
+drove
+drowsiness
+drowsy
+drudgery
+drunk
+drunkard
+drunkards
+drunken
+drunkenness
+dry
+dryness
+duad
+duck
+dudley
+due
+dug
+dull
+duller
+dully
+dumb
+during
+durst
+dust
+duties
+dutiful
+duty
+dwell
+dwellers
+dwellest
+dwelleth
+dwelling
+dwelt
+dying
+each
+eager
+eagerly
+eagerness
+eagle
+ear
+earliest
+early
+earnest
+earnestly
+earnestness
+ears
+earth
+earthly
+ease
+eased
+easeful
+easier
+easily
+east
+eastern
+easy
+eat
+eaten
+eateth
+eating
+ebb
+ebbing
+ebbs
+ebcdic
+ecclesiastical
+echo
+echoed
+echoes
+eclipsed
+eclipses
+edged
+edification
+edify
+edit
+edited
+editing
+edition
+editions
+educate
+educated
+education
+edward
+effaced
+effaces
+effect
+effected
+effectedst
+effort
+efforts
+egypt
+egyptian
+eight
+eighth
+ein
+either
+elder
+elders
+elect
+electronic
+electronically
+element
+elements
+elephant
+elevated
+elevation
+eligible
+elijah
+eloquence
+eloquent
+eloquently
+else
+elsewhere
+eluding
+email
+embalmed
+embarrassments
+embittered
+emblem
+embrace
+embraced
+embracement
+embracements
+embraces
+embryo
+emerge
+emerging
+eminence
+eminent
+eminently
+emotion
+emotions
+emperor
+empire
+employ
+employed
+employee
+employest
+empress
+emptied
+emptiness
+emptinesses
+empty
+enabled
+enact
+enacted
+enacteth
+enamoured
+enchantment
+encompass
+encompasseth
+encourage
+encouraged
+encouraging
+encumbered
+encumbrances
+end
+endangers
+endeared
+endearments
+endeavour
+endeavoured
+endeavouring
+endeavours
+ended
+ending
+endlessly
+ends
+endued
+endurance
+endure
+endured
+endures
+endureth
+enduring
+enemies
+enemy
+energy
+enervated
+enforced
+enforcement
+engage
+engaged
+engages
+engine
+english
+engraff
+enigma
+enjoin
+enjoined
+enjoinest
+enjoy
+enjoyed
+enjoying
+enlarge
+enlarged
+enlargedst
+enlarging
+enlighten
+enlightened
+enlightener
+enlighteneth
+enlightening
+enlightens
+enlisted
+enmities
+enmity
+enough
+enounce
+enquire
+enquired
+enquirers
+enquiries
+enquiring
+enquiringly
+enquiry
+enricher
+ensample
+enslaved
+ensnared
+ensnaring
+ensues
+ensuing
+entangle
+entangled
+entangling
+enter
+entered
+enteredst
+entering
+enters
+enthralled
+enticed
+enticements
+enticing
+entire
+entirely
+entireness
+entitled
+entrails
+entrance
+entreat
+entreated
+entreaties
+entrust
+entrusted
+entwine
+enumeration
+envenomed
+envious
+environeth
+environing
+envy
+envying
+epaphroditus
+epicurus
+episcopal
+epistles
+equably
+equal
+equalled
+equally
+equals
+equinoxes
+equipment
+equity
+equivalent
+ere
+ergo
+err
+erred
+error
+errors
+erst
+esau
+escape
+escaped
+especially
+espoused
+essay
+essayed
+essence
+establish
+established
+estate
+esteem
+esteemed
+esteeming
+estimate
+estimated
+estimation
+estranged
+etc
+eternal
+eternally
+eternity
+etext
+etext00
+etext01
+etext02
+etext90
+etext99
+etexts
+eunuchs
+euodius
+evangelists
+evaporates
+eve
+even
+evened
+evening
+evenly
+events
+ever
+everfixed
+everlasting
+everlastingly
+evermore
+every
+everything
+everywhere
+evidence
+evident
+evidently
+evil
+evils
+evincing
+exact
+exacted
+exacting
+exalted
+exaltedness
+examine
+examined
+examiner
+examining
+example
+examples
+exceeded
+exceedeth
+exceeding
+exceedingly
+excel
+excelled
+excellence
+excellencies
+excellency
+excellent
+excellently
+excelling
+excels
+except
+excepted
+exceptions
+excess
+excessive
+exchanged
+excited
+excitement
+excites
+exclaim
+exclude
+excluded
+exclusion
+exclusions
+excursive
+excuse
+excused
+excuses
+execrable
+execrate
+execute
+exercise
+exercised
+exhalation
+exhausted
+exhibit
+exhibited
+exhort
+exhortation
+exhortations
+exhorted
+exhorting
+exigency
+exiled
+exist
+existence
+existeth
+existing
+exists
+exodus
+expansive
+expect
+expectation
+expected
+expecteth
+expects
+expends
+expense
+expenses
+experience
+experienced
+experiments
+explain
+explained
+explaining
+explanatory
+expose
+exposed
+expound
+expounded
+expounding
+express
+expressed
+expression
+expressions
+exquisitely
+extended
+extension
+extent
+exterior
+external
+extinguish
+extinguished
+extol
+extolled
+extollers
+extracted
+extreme
+extremely
+extremest
+extricate
+extricated
+exuberance
+exuberant
+exude
+exult
+exultation
+eye
+eyes
+eyesight
+fable
+fables
+fabric
+fabulous
+face
+faced
+faces
+facio
+factito
+facts
+faculties
+faculty
+fail
+faileth
+failing
+failure
+fain
+faint
+fainting
+faintly
+fair
+fairer
+fairest
+fairly
+fairness
+faith
+faithful
+faithfully
+faithfulness
+fall
+fallacies
+fallen
+falling
+falls
+false
+falsehood
+falsehoods
+falsely
+falsified
+fame
+familiar
+familiarised
+familiarly
+family
+famine
+famished
+famous
+fancies
+fancy
+fanned
+fantasies
+fantastic
+far
+fared
+farness
+farther
+fashion
+fashioned
+fast
+faster
+fastidiousness
+fasting
+fastings
+fat
+father
+fatherless
+fatherly
+fathers
+fatigues
+fatness
+fault
+faultfinders
+faults
+faulty
+faustus
+favour
+favoured
+favourites
+favours
+fear
+feared
+feareth
+fearful
+fearfully
+fearing
+fearlessly
+fears
+feast
+fed
+fee
+feed
+feedest
+feedeth
+feeding
+feeds
+feel
+feeling
+feelings
+feels
+fees
+feet
+feigned
+felicity
+fell
+fellow
+fellows
+felt
+female
+females
+fence
+fervent
+fervently
+fervid
+festival
+fetched
+fettered
+fetters
+fever
+feverishness
+few
+fiction
+fictions
+field
+fields
+fiercely
+fiercest
+fifteen
+fifth
+fifty
+fig
+fight
+fighter
+fighting
+figurative
+figuratively
+figure
+figured
+figures
+file
+filename
+files
+fill
+filled
+fillest
+filleth
+filling
+filth
+filths
+filthy
+final
+finally
+find
+findest
+findeth
+finding
+finds
+fine
+finest
+finger
+fingers
+finish
+finished
+finite
+fire
+fired
+fires
+firm
+firmament
+firminus
+firmly
+firmness
+first
+fish
+fishes
+fit
+fitness
+fitted
+fitter
+fittest
+fitting
+five
+fix
+fixed
+fixedly
+fixing
+flagitiousness
+flagitiousnesses
+flagon
+flame
+flash
+flashedst
+flashes
+flashing
+flattering
+fled
+fledged
+flee
+fleeing
+fleeting
+flesh
+fleshly
+fleshy
+flew
+flies
+flights
+fling
+floating
+flock
+flocks
+flood
+floods
+flour
+flourished
+flow
+flowed
+flower
+flowers
+flowing
+flown
+flows
+fluctuate
+fluctuates
+fluctuating
+fluctuations
+fluently
+fluidness
+flung
+fluttereth
+flux
+fly
+flying
+foamed
+fog
+folded
+folk
+folks
+follies
+follow
+followed
+followers
+followest
+followeth
+following
+follows
+folly
+food
+fool
+foolish
+foolishly
+foolishness
+fools
+foot
+footed
+footsteps
+for
+forasmuch
+forbade
+forbadest
+forbare
+forbear
+forbid
+forbidden
+force
+forced
+forceth
+forcibly
+fore
+foreconceived
+forefathers
+forego
+foregoing
+forehead
+foreign
+foreigner
+foreknowledge
+forementioned
+forenamed
+forenoon
+forenoons
+forepassed
+foresaw
+foresee
+foreshow
+foreshowed
+foreshower
+foresignified
+foresignify
+forests
+foretell
+foretelling
+forethink
+forethinking
+forethought
+foretold
+forgave
+forge
+forget
+forgetful
+forgetfulness
+forgetteth
+forgetting
+forging
+forgive
+forgiven
+forgivest
+forgiving
+forgot
+forgotten
+forgottest
+form
+formation
+formed
+formedst
+former
+formerly
+formest
+forming
+formless
+formlessness
+forms
+fornicating
+fornication
+fornications
+forsake
+forsaken
+forsakest
+forsaketh
+forsaking
+forsook
+forsooth
+forth
+forthcoming
+forthwith
+fortunate
+fortunes
+forum
+forward
+forwards
+foster
+fostering
+fought
+foul
+foully
+foulness
+fouls
+found
+foundation
+foundations
+founded
+fountain
+four
+fourth
+fourthly
+fowl
+fowls
+fragment
+fragments
+fragrance
+fragrant
+frailness
+frame
+framed
+framers
+frantic
+fraud
+fraught
+freaks
+free
+freed
+freedom
+freely
+freeman
+frenzied
+frenzies
+frenzy
+frequent
+frequently
+fresh
+freshness
+fretted
+friend
+friends
+friendship
+frightful
+fro
+from
+front
+frozen
+fruit
+fruitful
+fruitfully
+fruitfulness
+fruitless
+fruitlessly
+fruits
+ftp
+fuel
+fugitives
+fulfil
+fulfilled
+fulfils
+full
+fuller
+fully
+fulness
+fumed
+fumes
+functions
+fund
+funding
+funeral
+furious
+furnace
+furnish
+furnished
+furnishing
+further
+furtherance
+furthermore
+fury
+future
+gain
+gained
+gainful
+gaining
+gains
+gainsay
+gainsayer
+gainsayers
+gainst
+galatians
+gales
+gall
+gallantry
+game
+games
+garb
+garden
+gardens
+garland
+garlands
+garment
+garner
+gasped
+gate
+gates
+gather
+gathered
+gatheredst
+gatherest
+gathering
+gathers
+gave
+gavest
+gay
+gaze
+gazers
+gazing
+general
+generally
+generate
+generation
+generations
+genesis
+genius
+gentiles
+gentle
+gentleness
+gently
+genuinely
+geometry
+gervasius
+gestures
+get
+getting
+ghastly
+ghost
+ghosts
+giant
+gift
+gifted
+gifts
+gilded
+girded
+girl
+girls
+give
+given
+giver
+givers
+gives
+givest
+giveth
+giving
+glad
+gladdened
+gladdens
+gladiators
+gladly
+gladness
+gladsome
+glance
+glances
+glass
+gleam
+gleameth
+gleams
+glide
+glided
+gliding
+glittering
+gloried
+glories
+glorieth
+glorified
+glorifies
+glorify
+glorious
+glory
+glorying
+glow
+glowed
+gloweth
+glowing
+glows
+glue
+gnashed
+gnawed
+gnawing
+go
+goad
+goaded
+goading
+goads
+goal
+god
+godhead
+godless
+godly
+gods
+goes
+goest
+goeth
+going
+gold
+golden
+gone
+good
+goodliness
+goodly
+goodness
+goods
+gorgeous
+gospel
+got
+gotten
+govemed
+government
+governor
+governors
+gowned
+grace
+graceful
+gracefulness
+gracious
+gradation
+gradually
+grammar
+grammarian
+grammarians
+grandchildren
+grant
+granted
+grantest
+grasp
+grasps
+grass
+grassy
+gratefully
+gratias
+gratification
+gratings
+gratuitous
+gratuitously
+grave
+gravity
+great
+greater
+greatest
+greatly
+greatness
+greaves
+grecian
+greedily
+greediness
+greedy
+greek
+greeks
+green
+greet
+greeted
+grew
+grief
+griefs
+grieve
+grieved
+grieves
+grievest
+grieving
+grievous
+grievously
+groan
+groaned
+groaneth
+groaning
+groanings
+groans
+groat
+gross
+grossness
+ground
+grounded
+grounds
+groves
+grow
+growing
+grown
+growth
+guarded
+guardian
+guardianship
+guess
+guessed
+guidance
+guidances
+guide
+guidest
+guilt
+guiltless
+guilty
+gulf
+gushed
+gutenberg
+gutindex
+habit
+habitation
+habits
+had
+hadst
+hail
+hair
+hairs
+hale
+haled
+half
+hallow
+hallowed
+hallowing
+halved
+hand
+handkerchief
+handle
+handled
+handling
+handmaid
+hands
+handwriting
+hang
+hanging
+hap
+haphazard
+hapless
+haply
+happen
+happened
+happeneth
+happens
+happier
+happily
+happiness
+happy
+harass
+harbour
+harbouring
+hard
+harder
+hardheartedness
+hardship
+hare
+hark
+harlotries
+harm
+harmed
+harmless
+harmonious
+harmoniously
+harmonise
+harmoniseth
+harmonising
+harmonized
+harmonizing
+harmony
+harsh
+hart
+harts
+harvest
+has
+hast
+haste
+hasten
+hastened
+hastening
+hasting
+hatchet
+hate
+hated
+hateful
+hath
+hatred
+haughtiness
+haunt
+have
+having
+hay
+he
+head
+header
+headlong
+heads
+heal
+healed
+healedst
+healeth
+healing
+health
+healthful
+healthfully
+healthy
+heaped
+heaps
+hear
+heard
+heardest
+hearer
+hearers
+hearest
+heareth
+hearing
+hearken
+hears
+hearsay
+heart
+hearted
+heartedness
+hearts
+heat
+heated
+heathen
+heaven
+heavenly
+heavens
+heavier
+heavily
+heavy
+hebrew
+hedged
+heed
+heeded
+height
+heightening
+heights
+heinous
+held
+heldest
+hell
+hellish
+helmet
+help
+helped
+helper
+helpful
+helpidius
+helping
+hence
+henceforth
+her
+herb
+herbs
+here
+hereafter
+hereat
+hereby
+hereditary
+herein
+hereof
+hereon
+heresies
+heresy
+heretics
+heretofore
+hereunto
+hereupon
+hers
+herself
+hesitate
+hesitated
+hesitating
+hesitation
+hid
+hidden
+hiddest
+hide
+hideous
+hidest
+hierius
+high
+higher
+highest
+highly
+highness
+hills
+him
+himself
+hinder
+hindered
+hindereth
+hindrance
+hint
+hippocrates
+his
+history
+hither
+hitherto
+hoar
+hogs
+hogshed
+hold
+holden
+holdest
+holding
+holds
+holies
+holily
+holiness
+holy
+home
+homer
+honest
+honestly
+honesty
+honey
+honied
+honor
+honour
+honourable
+honoured
+honouring
+honours
+hook
+hooks
+hope
+hoped
+hopeful
+hopes
+hoping
+horns
+horrible
+horror
+horse
+horses
+hortensius
+host
+hosts
+hot
+hotly
+hour
+hours
+house
+household
+houseless
+houses
+hovered
+how
+however
+howsoever
+html
+http
+huge
+hugging
+human
+humane
+humanity
+humans
+humble
+humbled
+humbledst
+humility
+hundred
+hundreds
+hung
+hunger
+hungered
+hungering
+hungry
+hunting
+hurried
+hurriedly
+hurrying
+hurt
+hurtful
+hurting
+husband
+husbands
+hushed
+husks
+hymn
+hymns
+hypertext
+i
+ibiblio
+ice
+idaho
+ideas
+identification
+identify
+idle
+idleness
+idly
+idol
+idols
+if
+ignoble
+ignorance
+ignorant
+ii
+iii
+ill
+ills
+illuminate
+illuminating
+illumined
+illusion
+image
+images
+imaginary
+imagination
+imaginations
+imagine
+imagined
+imagining
+imbibe
+imbibed
+imbue
+imitate
+imitated
+imitating
+imitation
+immediately
+immense
+immersed
+immoderate
+immortal
+immortality
+immortally
+immovably
+immutable
+impair
+impaired
+impart
+imparted
+imparts
+impatience
+impatient
+impatiently
+imperfect
+imperfection
+imperfections
+imperishable
+imperturbable
+impiety
+impious
+implanted
+implanting
+implied
+imply
+important
+importunity
+imposed
+impostors
+impostumes
+impotent
+impregnable
+impress
+impressed
+impressing
+impression
+impressions
+imprinted
+improperly
+impudently
+impulses
+impunity
+impure
+impurity
+impute
+in
+inaccessible
+inaccurate
+inactive
+inanimate
+inappropriately
+inasmuch
+incarnation
+incense
+incensed
+inchoate
+incidental
+inclination
+incline
+inclined
+included
+including
+incommutable
+incomparably
+incomplete
+incomprehensible
+incongruously
+incorporeal
+incorrect
+incorruptible
+incorruptibly
+incorruption
+increase
+increased
+increasing
+incredible
+incredibly
+incumbrances
+incurable
+incurred
+indebted
+indeed
+indefinitely
+indemnify
+indemnity
+indentures
+indexes
+indiana
+indicate
+indicated
+indicating
+indications
+indigent
+indigested
+indignant
+indirect
+indirectly
+indite
+indited
+indued
+indulgent
+inebriate
+inebriated
+inebriation
+inevitable
+inevitably
+inexperienced
+inexpressible
+infancy
+infant
+infantine
+infants
+infected
+infection
+infer
+inferior
+infidelity
+infidels
+infinite
+infinitely
+infinitude
+infirmities
+infirmity
+inflame
+inflamed
+inflammation
+inflection
+inflicted
+influence
+influenced
+influences
+information
+informed
+informing
+infringement
+infuse
+infused
+ingrated
+inhabitant
+inhabitants
+inhabited
+inharmonious
+inheritance
+iniquities
+iniquity
+initiated
+initiating
+initiation
+initiatory
+injurable
+injure
+injured
+injures
+injurious
+injury
+injustice
+inmost
+innate
+inner
+innocence
+innocency
+innocent
+innumerable
+innumerably
+inordinate
+insatiable
+insatiate
+insensibly
+inseparable
+inserted
+insight
+insolently
+insomuch
+inspect
+inspecting
+inspiration
+inspire
+inspired
+inspirest
+inspiring
+instability
+instance
+instances
+instant
+instantly
+instead
+instillest
+instinct
+instinctive
+instituted
+institution
+instruct
+instructed
+instructest
+instruction
+instructor
+insult
+insultingly
+intellectual
+intelligence
+intelligences
+intelligent
+intelligible
+intemperance
+intend
+intended
+intense
+intensely
+intenseness
+intensest
+intent
+intention
+intently
+intercede
+intercedeth
+intercepting
+intercession
+intercourse
+interest
+interested
+interior
+intermission
+intermit
+intermitted
+intermitting
+internal
+international
+interpose
+interposed
+interposing
+interpret
+interpretation
+interpreted
+interpreter
+interpreting
+interrupt
+interrupted
+interruption
+interval
+intervals
+intimacy
+intimate
+intimated
+intimately
+into
+intolerable
+intoxicated
+intricate
+introduced
+intrude
+inured
+inveigler
+invest
+invests
+invisible
+invite
+invited
+inviting
+involved
+inward
+inwardly
+iowa
+iron
+irons
+irrational
+irresoluteness
+irrevocable
+irritate
+is
+isaac
+isaiah
+israel
+issue
+issued
+it
+italian
+italy
+itch
+itching
+items
+its
+itself
+jacob
+jarring
+jealous
+jealousy
+jeer
+jeering
+jerusalem
+jest
+jests
+jesus
+jew
+jews
+join
+joined
+joineth
+joining
+joint
+jointly
+joking
+jordan
+joseph
+journey
+journeyed
+jove
+joy
+joyed
+joyful
+joyfulness
+joying
+joyous
+joyously
+joyousness
+joys
+judge
+judged
+judgements
+judges
+judgest
+judgeth
+judging
+judgment
+judgments
+julian
+juncture
+june
+juno
+jupiter
+just
+justice
+justification
+justifieth
+justify
+justina
+justly
+keen
+keep
+keeper
+keepest
+keeping
+keeps
+ken
+kentucky
+kept
+kicking
+kill
+killed
+killest
+killeth
+kind
+kindle
+kindled
+kindly
+kindness
+kindred
+kinds
+king
+kingdom
+kingdoms
+kings
+knee
+knees
+knew
+knewest
+knit
+knitting
+knock
+knocked
+knocketh
+knocking
+knocks
+knots
+knottiness
+knotty
+know
+knowest
+knoweth
+knowing
+knowingly
+knowledge
+known
+knows
+labour
+laboured
+labourers
+labours
+lack
+lacketh
+lacking
+laden
+laid
+lament
+lamentable
+lamented
+lancet
+land
+lands
+language
+languages
+languishing
+lanthorn
+lap
+large
+largely
+largeness
+larger
+lashed
+lashes
+lashest
+last
+lastly
+late
+later
+lathe
+latin
+latins
+latinum
+latter
+lattice
+laugh
+laughed
+laughter
+launched
+law
+lawful
+lawfully
+lawless
+laws
+lawyer
+lawyers
+laxly
+lay
+layeth
+laying
+lays
+lead
+leaden
+leadeth
+leading
+leads
+leaning
+leaps
+learn
+learned
+learner
+learning
+learnt
+leasing
+least
+leave
+leaven
+leaves
+leaveth
+leaving
+lecture
+lectured
+led
+left
+legal
+legally
+leisure
+lends
+length
+lengthened
+lentiles
+less
+lessen
+lesser
+lesson
+lessons
+lest
+let
+lethargy
+letter
+letters
+lettest
+lewd
+liability
+liar
+libanus
+liberal
+liberality
+liberty
+licence
+license
+licensed
+licenses
+lick
+lie
+lied
+lies
+lieth
+life
+lift
+lifted
+liftedst
+lifter
+liftest
+lifts
+light
+lighted
+lighten
+lightened
+lighteth
+lightly
+lights
+lightsome
+like
+liked
+likedst
+likely
+likeness
+likenesses
+liker
+likes
+likest
+likewise
+lilies
+limbs
+limed
+limitation
+limited
+limits
+line
+lineage
+lineaments
+lined
+lines
+linger
+lingered
+lingering
+links
+lion
+lip
+lips
+list
+listened
+listening
+listing
+lists
+literally
+literary
+literature
+litigation
+little
+littles
+live
+lived
+livelihood
+lively
+lives
+livest
+liveth
+living
+lizard
+lo
+load
+loads
+loathed
+loathing
+loathsome
+locking
+locusts
+lodging
+lofty
+logic
+login
+long
+longed
+longer
+longing
+longings
+longs
+look
+looked
+looker
+looketh
+looking
+looks
+loose
+loosed
+loosen
+loosest
+loquacity
+lord
+lords
+lose
+loses
+loseth
+losing
+loss
+lost
+lot
+loth
+lottery
+loud
+loudly
+louisiana
+love
+loved
+loveliness
+lovely
+lover
+lovers
+loves
+lovest
+loveth
+loving
+lovingly
+low
+lower
+lowering
+lowest
+lowlily
+lowliness
+lowly
+lucid
+lucre
+ludicrous
+lulled
+luminaries
+lump
+lungs
+lure
+lures
+lust
+lusted
+lusteth
+lustful
+lustfulness
+lusting
+lusts
+luxuriousness
+luxury
+lying
+macedonia
+machine
+mad
+madaura
+made
+madest
+madly
+madness
+magical
+magistrates
+magnified
+magnify
+magnitudes
+maid
+maiden
+maidens
+mail
+maimed
+main
+mainly
+maintain
+maintained
+maintainers
+maintaining
+majesty
+make
+maker
+makers
+makes
+makest
+maketh
+making
+male
+malice
+malicious
+maliciously
+malignant
+mammon
+man
+manage
+manfully
+mangled
+manhood
+manichaean
+manichaeus
+manichee
+manichees
+manifest
+manifestation
+manifested
+manifestly
+manifold
+manifoldly
+manifoldness
+mankind
+manna
+manner
+manners
+manors
+mansion
+mantles
+manufactures
+many
+mariners
+mark
+marked
+market
+marketplace
+marking
+marks
+marriage
+marriageable
+married
+marrow
+marry
+marrying
+mars
+marts
+martyr
+martyrs
+marvel
+marvelled
+mary
+masculine
+mass
+massachusetts
+masses
+master
+mastered
+masters
+mastery
+material
+materials
+mathematicians
+matrons
+matter
+matters
+maturing
+may
+mayest
+mazes
+me
+mean
+meanest
+meaning
+meanings
+meanly
+means
+meant
+meantime
+meanwhile
+measurable
+measure
+measured
+measures
+measuring
+meat
+meats
+meddle
+meddling
+medea
+mediator
+medicine
+medicines
+medicining
+meditate
+meditated
+meditating
+meditations
+medium
+meek
+meekness
+meet
+meeting
+meets
+melodies
+melodious
+melody
+melt
+melted
+member
+members
+memory
+men
+mentally
+mention
+mentioned
+mentioning
+merchantability
+mercies
+merciful
+mercifully
+mercy
+mere
+merely
+merged
+merits
+merrily
+merry
+message
+messages
+messengers
+met
+method
+metre
+metres
+mget
+michael
+mid
+middle
+midnight
+might
+mightest
+mightier
+mightily
+mightiness
+mighty
+milan
+milanese
+milder
+mildly
+milk
+milky
+millennium
+million
+mimic
+mind
+minded
+mindful
+minds
+mine
+minerva
+mingle
+mingled
+mingling
+minister
+ministers
+ministry
+minute
+minutest
+miracles
+mire
+mirth
+mirthful
+mischief
+misdeeds
+miserable
+miserably
+miseries
+misery
+mislike
+misliked
+miss
+missed
+missing
+mist
+mistaken
+mistress
+mistresses
+mists
+mixture
+moan
+mock
+mocked
+mockeries
+mockers
+mockery
+mocking
+mode
+models
+moderate
+moderation
+modes
+modestly
+modesty
+modification
+modify
+modulation
+moist
+molest
+molten
+moment
+momentary
+momentous
+moments
+monad
+monasteries
+monastery
+money
+monk
+monnica
+monster
+monstrous
+monstrousness
+montana
+month
+months
+monument
+moon
+moral
+more
+moreover
+morning
+morrow
+morsel
+mortal
+mortality
+mortals
+mortified
+moses
+most
+mostly
+mother
+motherly
+mothers
+motion
+motions
+motive
+mould
+moulded
+mount
+mountain
+mountains
+mounting
+mourn
+mourned
+mourners
+mournful
+mourning
+mouth
+mouthed
+mouths
+move
+moved
+moveth
+moving
+much
+muddy
+mule
+multiple
+multiplicity
+multiplied
+multipliedst
+multiply
+multiplying
+multitude
+multitudes
+munday
+murder
+murdered
+murdering
+murmur
+murmured
+museth
+music
+musical
+musing
+must
+mutability
+mutable
+mute
+muttering
+mutual
+mutually
+my
+myself
+mysteries
+mysterious
+mysteriously
+mystery
+mystic
+mystically
+nails
+naked
+name
+named
+namely
+names
+narrow
+narrower
+narrowly
+narrowness
+nation
+nations
+native
+nativity
+natural
+naturally
+nature
+natures
+nay
+near
+nearer
+neatly
+neatness
+nebridius
+necessaries
+necessarily
+necessary
+necessities
+necessity
+neck
+need
+needed
+needeth
+needful
+needing
+needs
+needy
+neglect
+neglected
+neglecteth
+neglecting
+negligence
+negligent
+neighbour
+neighbouring
+neighbours
+neither
+neptune
+nest
+nests
+net
+nets
+nevada
+never
+nevertheless
+new
+newsletter
+newsletters
+next
+nigh
+night
+nights
+nill
+nilled
+nimble
+nine
+nineteenth
+ninety
+ninth
+no
+noah
+nobility
+noble
+nod
+noise
+nominally
+none
+noon
+nor
+north
+nostrils
+not
+note
+noted
+notes
+nothing
+notice
+notices
+notion
+notions
+notorious
+notwithstanding
+nought
+nourish
+nourished
+nourishing
+nourishment
+nourishments
+novelty
+novice
+now
+nowhere
+null
+number
+numbered
+numberest
+numbering
+numberless
+numbers
+numerous
+nurse
+nursery
+nurses
+nuts
+obedience
+obedient
+obediently
+obey
+obeyed
+obeying
+obeys
+object
+objected
+objections
+objects
+oblation
+obscure
+obscurely
+observance
+observation
+observe
+observed
+observes
+observeth
+observing
+obstinacy
+obtain
+obtained
+obtaining
+obtains
+obviously
+occasion
+occasioned
+occupy
+occupying
+occur
+occurred
+occurs
+ocean
+odour
+odours
+of
+off
+offence
+offences
+offend
+offended
+offensive
+offer
+offered
+offerings
+office
+officer
+officers
+offices
+official
+offspring
+oft
+often
+oftentimes
+ofthe
+ofttimes
+oh
+oil
+ointments
+oklahoma
+old
+omened
+omit
+omitted
+omnipotency
+omnipotent
+omnium
+on
+once
+one
+ones
+onesiphorus
+only
+open
+opened
+openest
+openeth
+opening
+openly
+opens
+operations
+opinion
+opinionative
+opinions
+opportunity
+oppose
+opposed
+opposing
+oppressed
+oppresseth
+oppression
+or
+oracle
+oracles
+orally
+orations
+orator
+oratory
+orbs
+ordained
+ordainer
+order
+ordered
+orderer
+orderest
+ordering
+ordinance
+ordinarily
+ordinary
+orestes
+org
+organization
+organs
+origin
+original
+ornamentedst
+ornamenting
+ostentation
+ostia
+other
+others
+otherwhere
+otherwhiles
+otherwise
+ought
+oughtest
+our
+ours
+ourself
+ourselves
+out
+outer
+outrages
+outset
+outward
+outwardly
+over
+overboldness
+overcame
+overcast
+overcharged
+overclouded
+overcome
+overcoming
+overflow
+overflowed
+overflowing
+overhastily
+overjoyed
+overpass
+overpast
+overspread
+overspreading
+overtake
+overthrew
+overthrow
+overturned
+overwhelmed
+owe
+owed
+owes
+owing
+own
+owns
+oxford
+page
+pages
+paid
+pain
+painful
+pains
+pair
+pairs
+palace
+palaces
+palate
+pale
+palm
+pamperedness
+pander
+panegyric
+pangs
+pant
+panted
+panting
+paper
+par
+paraclete
+paradise
+parched
+pardoned
+pared
+parent
+parental
+parents
+parity
+parley
+part
+partake
+partaker
+partaketh
+parted
+participation
+particle
+particles
+particular
+parties
+parting
+partly
+partners
+parts
+party
+pass
+passage
+passages
+passed
+passengers
+passes
+passeth
+passible
+passing
+passion
+passionately
+passions
+password
+past
+pastime
+pastimes
+patched
+path
+paths
+patience
+patiently
+patricius
+pattern
+patterns
+paul
+paulus
+pause
+pauses
+pay
+payable
+payest
+paying
+payments
+peace
+peaceful
+peacefully
+peacemaker
+pear
+pearl
+pears
+peculiar
+peculiarly
+pen
+penal
+penally
+penalties
+penalty
+pence
+penetrating
+penitent
+people
+per
+peradventure
+perceivable
+perceive
+perceived
+perceivedst
+perceives
+perceiveth
+perceiving
+perchance
+perdition
+perfect
+perfected
+perfecting
+perfection
+perfectly
+performed
+performing
+perhaps
+peril
+perilous
+perils
+period
+periodic
+periods
+perish
+perishable
+perished
+perisheth
+permission
+permit
+permitted
+pernicious
+perpetual
+perplexed
+perplexities
+persecuted
+persecutes
+persecuting
+persevering
+person
+personages
+personally
+personated
+persons
+perspicuous
+persuade
+persuaded
+persuasions
+persuasive
+pertain
+pertained
+pertaining
+perturbations
+perused
+perverse
+perverseness
+perversion
+perversity
+pervert
+perverted
+pervertedly
+perverting
+pervious
+pestilent
+petitions
+petty
+petulantly
+pg
+phantasm
+phantasms
+phantom
+phantoms
+philippians
+philosophers
+philosophy
+photinus
+phrase
+phrases
+physic
+physical
+physician
+physicians
+picture
+pictures
+piece
+piecemeal
+pieces
+pierce
+pierced
+piercing
+piety
+pile
+piled
+pilgrim
+pilgrimage
+pilgrims
+pinching
+pines
+pious
+piously
+pit
+pitch
+pitiable
+pitied
+pitiest
+pitiful
+pity
+pitying
+place
+placed
+placedst
+places
+placest
+placing
+plague
+plain
+plainer
+plainly
+plainness
+plains
+plan
+planets
+plans
+plant
+plants
+platonists
+plausibility
+play
+playing
+plays
+plea
+plead
+pleasant
+pleasanter
+pleasantly
+pleasantness
+please
+pleased
+pleasest
+pleasing
+pleasurable
+pleasure
+pleasureableness
+pleasures
+plenary
+plenteous
+plenteousness
+plentiful
+plentifully
+plenty
+pliant
+plot
+plots
+plotting
+pluck
+plucked
+pluckest
+plucking
+plunged
+plunging
+plural
+pmb
+poems
+poesy
+poet
+poetic
+poets
+point
+pointed
+points
+poise
+poison
+pole
+polished
+polluted
+pollution
+pontitianus
+poor
+popular
+popularity
+population
+portion
+portions
+position
+possess
+possessed
+possesses
+possessest
+possesseth
+possession
+possessor
+possibility
+possible
+posted
+potent
+potter
+pour
+poured
+pourest
+poverty
+power
+powerful
+powers
+practice
+practise
+practised
+praetorian
+prairienet
+praise
+praised
+praises
+praiseth
+prated
+praters
+prating
+pray
+prayed
+prayer
+prayers
+praying
+preach
+preached
+preacher
+preachers
+preaching
+preachings
+precede
+preceded
+precedes
+precedest
+precedeth
+precepts
+precious
+precipice
+precipitated
+precisely
+predestinated
+predestination
+predicament
+predicaments
+predicated
+predict
+predicted
+preeminence
+preeminent
+prefect
+prefer
+preferable
+preference
+preferred
+preferring
+prejudice
+prelate
+preliminary
+prepare
+prepared
+preparedst
+prepares
+preparest
+preparing
+prerogative
+presbyters
+prescribed
+prescribes
+prescripts
+presence
+present
+presented
+presently
+presents
+preserve
+preserved
+preserving
+presidentship
+presides
+presidest
+presideth
+presiding
+press
+pressed
+pressedst
+presseth
+pressure
+presume
+presumed
+presuming
+presumption
+pretend
+prevail
+prevailed
+prevailing
+prevails
+prevented
+preventedst
+preventing
+previous
+prey
+price
+prices
+pricked
+pricks
+pride
+priest
+primary
+primitive
+prince
+princes
+principalities
+principally
+principles
+print
+prior
+prison
+prisoner
+privacy
+private
+privately
+privation
+privily
+prize
+prizes
+probable
+problem
+proceed
+proceeded
+proceedeth
+proceeding
+processing
+processors
+proclaim
+proclaiming
+proconsul
+proconsular
+procure
+procured
+procuredst
+prodigality
+produce
+produced
+production
+products
+prof
+profane
+profess
+professed
+professing
+profession
+professor
+professorship
+proffer
+proffering
+proficiency
+profit
+profitable
+profited
+profits
+profligate
+profound
+profounder
+profoundly
+program
+progress
+prohibition
+project
+projected
+prolix
+prolonged
+promise
+promised
+promises
+promiseth
+promising
+promo
+pronounce
+pronounced
+pronounces
+pronouncing
+pronunciation
+proof
+proofread
+prop
+proper
+properly
+property
+prophecy
+prophet
+prophets
+proportion
+proportions
+proposed
+propound
+propoundest
+proprietary
+prose
+prosper
+prosperities
+prosperity
+protasius
+protect
+protection
+protest
+protesting
+protracted
+protraction
+proud
+prouder
+proudly
+prove
+proved
+provest
+proveth
+provide
+provided
+providedst
+providence
+province
+provincial
+provision
+provisions
+provoke
+prudent
+prunes
+pryers
+psalm
+psalmody
+psalms
+psalter
+psaltery
+pub
+public
+publication
+publicly
+puffed
+pulse
+punctuation
+punish
+punishable
+punished
+punishment
+punishments
+punitive
+pupils
+puppies
+purchase
+purchased
+purchasing
+pure
+purely
+purer
+purest
+purged
+purified
+purity
+purpose
+purposed
+purposes
+purposing
+pursue
+pursued
+pursues
+pursuing
+pursuits
+pusey
+put
+putrefied
+putting
+pylades
+qualified
+qualities
+quarrel
+quarrels
+quarter
+queen
+quench
+quest
+question
+questioned
+questioning
+questionings
+questions
+quick
+quicken
+quickened
+quickenest
+quicker
+quickly
+quickness
+quiet
+quieter
+quit
+quite
+quitting
+quoth
+race
+races
+racked
+racks
+rage
+raged
+raging
+rais
+raise
+raised
+raisedst
+raises
+raisest
+raising
+ran
+random
+range
+ranged
+rank
+ranked
+ransom
+rapture
+rare
+rash
+rashly
+rashness
+rates
+rather
+rational
+raven
+ravish
+reach
+reached
+reacheth
+reaching
+read
+readable
+reader
+readers
+readest
+readier
+readily
+readiness
+reading
+reads
+ready
+real
+realised
+realisest
+realities
+reality
+really
+reap
+reason
+reasonable
+reasoning
+reasonings
+reasons
+reawakened
+rebel
+rebelled
+rebellious
+rebuke
+rebuked
+recall
+recalled
+recallest
+recalling
+recalls
+receive
+received
+receives
+receivest
+receiveth
+receiving
+recent
+recently
+receptacle
+recess
+recesses
+recite
+recited
+reckon
+reckoned
+reckoning
+reckons
+reclaim
+reclaiming
+recognise
+recognised
+recognises
+recognising
+recollect
+recollected
+recollecting
+recollection
+recommend
+recommended
+recommending
+reconcile
+reconciled
+reconcilement
+reconciliation
+recondite
+record
+recorded
+recount
+recounts
+recourse
+recover
+recovered
+recoveredst
+recovering
+recovery
+recruiting
+rectify
+recur
+recurring
+redeem
+redeemed
+redeemer
+redemption
+redistributing
+redoubling
+refer
+reference
+references
+referred
+reflect
+reform
+reformed
+refrain
+refrained
+refraining
+refresh
+refreshed
+refreshing
+refreshment
+refuge
+refund
+refuse
+refused
+refusing
+refute
+regard
+regarded
+regardest
+regarding
+regardless
+regenerated
+regeneratedst
+regeneration
+region
+regions
+regular
+regulate
+rehearse
+reigning
+reigns
+rein
+reins
+reinvolved
+reject
+rejected
+rejection
+rejects
+rejoice
+rejoiced
+rejoices
+rejoicest
+rejoiceth
+rejoicing
+relapse
+relapseth
+relate
+related
+relater
+relating
+relation
+relations
+relationship
+relative
+relators
+relaxation
+relaxedly
+relaxing
+release
+released
+relics
+relied
+relief
+relieve
+religion
+religious
+religiously
+remain
+remainder
+remained
+remainest
+remaineth
+remaining
+remains
+remarkable
+remedies
+remember
+remembered
+remembereth
+remembering
+remembers
+remembrance
+remembrances
+reminded
+remindeth
+remission
+remitted
+remittest
+remnants
+remorse
+removal
+remove
+removed
+rend
+render
+renderest
+renew
+renewed
+reneweth
+renewing
+renounce
+renowned
+rent
+repair
+repay
+repeat
+repeated
+repeating
+repel
+repelled
+repent
+repentance
+repentest
+replace
+replacement
+replacing
+replenish
+replenished
+replenishing
+replied
+replies
+reply
+report
+reported
+reporters
+reports
+repose
+reposed
+reposes
+reposeth
+reposing
+represent
+repress
+reproach
+reproachful
+reproof
+reproved
+reproves
+reptiles
+reputation
+repute
+reputed
+request
+require
+required
+requirements
+requires
+requiring
+requital
+requited
+requitest
+rescue
+rescued
+rescuing
+resemble
+resembling
+resend
+resent
+reserved
+reside
+residest
+resigned
+resist
+resistance
+resisted
+resistedst
+resistest
+resisteth
+resisting
+resolute
+resolutely
+resolution
+resolved
+respect
+respected
+respective
+respects
+respite
+rest
+rested
+restest
+resting
+restless
+restlessly
+restlessness
+restoration
+restore
+restored
+restoring
+restrain
+restrained
+restrainest
+restraining
+restrains
+restraint
+restricted
+result
+resulting
+results
+resumed
+resumes
+resurrection
+retain
+retained
+retaineth
+retard
+retire
+retired
+retiring
+retreat
+return
+returned
+returning
+returns
+reveal
+revealed
+revealedst
+revealing
+revelation
+revelations
+revenge
+revenged
+revenges
+revenue
+reverence
+reverential
+reverently
+review
+reviewing
+reviled
+revised
+revive
+revolt
+revolting
+revolved
+revolving
+reward
+rewards
+rhetoric
+rich
+richer
+riches
+riddle
+ridiculous
+right
+righteous
+righteousness
+rightful
+rightly
+rights
+rigidly
+rigorous
+rioting
+riotous
+ripened
+riper
+rise
+risen
+riseth
+rising
+risk
+rites
+rivers
+riveted
+roared
+roarest
+rob
+robber
+robbery
+robert
+robing
+rocks
+rods
+roll
+rolled
+rolling
+roman
+romanianus
+rome
+rood
+room
+root
+rose
+rottenness
+rough
+round
+rounds
+rouse
+roused
+rove
+roving
+rovings
+royalties
+royalty
+rude
+rudely
+rudiments
+rugged
+ruggedness
+ruinous
+rule
+ruled
+ruler
+rules
+rulest
+ruleth
+ruminate
+ruminating
+run
+running
+runs
+rush
+rushing
+s
+sabbath
+sacrament
+sacraments
+sacrifice
+sacrificed
+sacrifices
+sacrificing
+sacrilegious
+sad
+saddeneth
+sadness
+safe
+safer
+safety
+said
+saidst
+sail
+sailors
+sails
+saint
+saints
+saith
+sake
+sakes
+salary
+sale
+salt
+salted
+salvation
+same
+sanctification
+sanctified
+sanctity
+sanctuary
+sand
+sang
+sangest
+sank
+sat
+sate
+sated
+satiate
+satiated
+satiety
+satisfaction
+satisfactorily
+satisfied
+satisfy
+satisfying
+saturn
+saul
+savage
+savageness
+save
+saved
+saving
+saviour
+savour
+savoured
+savoury
+saw
+sawest
+say
+sayest
+saying
+sayings
+says
+scanning
+scantling
+scarce
+scarcely
+scatter
+scattered
+scatteredst
+scenical
+sceptre
+schedule
+scholar
+scholars
+school
+schools
+science
+sciences
+scoffed
+scoffing
+scorn
+scorned
+scornful
+scornfully
+scourge
+scourged
+scourgedst
+scourges
+scraped
+scratch
+scratching
+scripture
+scriptures
+scroll
+scruple
+sea
+seal
+sealed
+search
+searched
+searcher
+searches
+searching
+seas
+season
+seasonably
+seasoned
+seasoneth
+seasons
+seat
+seated
+seats
+second
+secondary
+secrecies
+secret
+secretly
+secrets
+sect
+section
+secular
+secure
+securely
+seduce
+seduced
+seducers
+seducing
+seduction
+seductions
+seductive
+see
+seed
+seeing
+seek
+seekest
+seeketh
+seeking
+seeks
+seem
+seemed
+seemeth
+seemly
+seems
+seen
+sees
+seest
+seeth
+seize
+seized
+seizes
+seldomness
+selected
+self
+sell
+sellers
+selling
+selves
+semblance
+senator
+senators
+send
+sending
+seneca
+sensation
+sensations
+sense
+senseless
+senses
+sensible
+sensibly
+sensitive
+sent
+sentence
+sentences
+sentest
+sentiment
+separate
+separated
+separateth
+separating
+seraphim
+serene
+serenity
+sermons
+serpent
+serpents
+servant
+servants
+serve
+served
+serves
+service
+serviceable
+services
+serving
+servitude
+session
+set
+sets
+settest
+setting
+settle
+settled
+settling
+seven
+seventh
+sever
+several
+severally
+severe
+severed
+severely
+severer
+severing
+severity
+sex
+shade
+shadow
+shadowed
+shadows
+shadowy
+shady
+shaggy
+shake
+shaken
+shakes
+shall
+shalt
+shame
+shameful
+shamefulness
+shameless
+shamelessness
+shape
+shapen
+shapes
+share
+shared
+sharers
+shares
+sharp
+sharpen
+sharper
+sharply
+sharpness
+sharpsighted
+shatter
+shattered
+she
+shed
+sheep
+shelter
+shepherd
+shield
+shifted
+shifting
+shine
+shines
+shinest
+shineth
+shining
+ship
+ships
+shipwreck
+shod
+shoe
+shoes
+shone
+shonest
+shook
+shoot
+shop
+shops
+shore
+short
+shortened
+shorter
+shortly
+should
+shoulder
+shoulders
+shouldest
+shouted
+shoutedst
+show
+showed
+showedst
+shower
+showeth
+showing
+shown
+shows
+shrink
+shrinking
+shrunk
+shudder
+shunning
+shuns
+shut
+sick
+sickly
+sickness
+sicknesses
+side
+sides
+siege
+sigh
+sighed
+sigheth
+sighing
+sighs
+sight
+sights
+sign
+significations
+signified
+signifies
+signify
+signs
+silence
+silenced
+silent
+silently
+silly
+silver
+silversmiths
+similitude
+simple
+simplicianus
+simplicity
+simply
+sin
+since
+sincerely
+sinful
+sing
+singeth
+singing
+single
+singly
+sings
+singsong
+singular
+singularly
+sink
+sinking
+sinks
+sinned
+sinner
+sinners
+sins
+sipped
+sips
+sit
+sites
+sits
+sittest
+sitteth
+sitting
+six
+sixteenth
+sixth
+size
+skies
+skilful
+skill
+skilled
+skin
+skins
+skirmishes
+skirts
+sky
+slackened
+slackness
+slain
+slave
+slavery
+slaves
+slavish
+slay
+slaying
+sleep
+sleeper
+sleepest
+sleeping
+slept
+slew
+slight
+slighting
+slightly
+slipped
+slippery
+sloth
+slothful
+slow
+slower
+slowly
+sluggish
+slumber
+slumbers
+small
+smaller
+smallest
+smarting
+smell
+smelleth
+smelling
+smells
+smile
+smiled
+smiling
+smiting
+smoke
+smooth
+smoothed
+smoothing
+snare
+snares
+snow
+so
+soaring
+sober
+soberly
+sobriety
+socalled
+society
+sodom
+soever
+soft
+softened
+softening
+softly
+software
+soil
+solaces
+sold
+soldier
+sole
+solecism
+solemn
+solemnise
+solemnities
+solemnity
+solicited
+solicits
+solid
+solidity
+solitude
+solomon
+solstices
+solve
+solving
+some
+someone
+something
+sometime
+sometimes
+somewhat
+somewhere
+son
+song
+songs
+sons
+soon
+sooner
+soothed
+soothes
+sore
+sorely
+sores
+sorrow
+sorrowed
+sorrowful
+sorrowfulness
+sorrows
+sorry
+sort
+sorts
+sought
+soughtest
+soul
+souls
+sound
+sounded
+soundedst
+sounder
+soundeth
+sounding
+soundly
+soundness
+sounds
+sour
+source
+sources
+south
+sovereign
+sovereignly
+sowing
+space
+spaces
+spacious
+spake
+spare
+sparedst
+sparks
+sparrow
+sparrows
+speak
+speakers
+speakest
+speaketh
+speaking
+speaks
+special
+species
+specimens
+spectacle
+spectacles
+spectator
+spectators
+speech
+speeches
+speechless
+speed
+speedily
+spend
+spent
+spices
+spider
+spirit
+spirits
+spiritual
+spiritually
+spoil
+spoke
+spoken
+spokest
+sponge
+sport
+sportively
+sports
+spot
+spots
+spouts
+sprang
+spread
+spreadest
+spreading
+spreads
+spring
+springeth
+springs
+sprung
+spurn
+stable
+stablished
+staff
+stage
+stages
+staggered
+stand
+standest
+standeth
+standing
+stands
+stank
+stanza
+stanzas
+star
+starry
+stars
+start
+starting
+startled
+startles
+state
+stated
+stateliness
+statement
+states
+station
+statue
+stature
+status
+stay
+stayed
+stays
+stead
+steadfast
+steal
+stealing
+steals
+stealth
+steep
+steeping
+steer
+steered
+step
+steps
+stick
+sticking
+stiff
+stiffly
+stiffneckedness
+stiffness
+still
+stilled
+stimulus
+stipend
+stir
+stirred
+stirrest
+stirring
+stole
+stolen
+stolidity
+stomach
+stomachs
+stone
+stones
+stood
+stoop
+stooping
+stop
+stopped
+store
+stored
+stores
+stories
+storing
+storm
+stormed
+stormy
+story
+stowed
+straightening
+strained
+strait
+straitly
+straitness
+strange
+strangely
+stranger
+strangers
+strayed
+straying
+stream
+streaming
+streams
+streets
+strength
+strengthen
+strengthened
+strengthenedst
+strengthenest
+strengtheneth
+strengthless
+stretch
+stretched
+stretching
+stricken
+strict
+strictness
+strife
+strifes
+strike
+strikes
+striking
+strings
+stripes
+stripped
+strive
+strives
+striving
+stroke
+strong
+strongholds
+strongly
+struck
+structure
+struggle
+struggled
+struggles
+struggling
+stuck
+student
+students
+studied
+studies
+studious
+studiously
+study
+studying
+stuff
+stumble
+stumbled
+stumbling
+stung
+stupidity
+style
+styled
+subdu
+subdued
+subduedst
+subduing
+subject
+subjected
+subjection
+subjects
+subjoined
+subjoinedst
+subjoins
+sublime
+sublimely
+sublimer
+sublimities
+sublimity
+submit
+submitted
+submitting
+subordinate
+subsequently
+subsist
+subsists
+substance
+substances
+substantial
+subtile
+subtilty
+subtle
+subversion
+subverted
+subverters
+subvertings
+succeed
+succeeded
+succeeding
+succession
+successive
+successively
+succour
+succouredst
+such
+suck
+sucking
+sucklings
+sudden
+suddenly
+sue
+suffer
+suffered
+sufferedst
+sufferest
+suffering
+suffers
+suffice
+sufficed
+sufficest
+sufficeth
+sufficient
+sufficiently
+suffocated
+suffrages
+suggest
+suggested
+suggestion
+suggestions
+suggests
+suitable
+suitably
+summer
+summing
+summit
+sumptuously
+sun
+sunder
+sung
+sunk
+supercelestial
+supereminence
+supereminent
+superfluously
+superior
+superstition
+superstitious
+suppliant
+supplied
+supplies
+support
+supported
+supporting
+suppose
+supposed
+supposing
+suppress
+suppressed
+supreme
+supremely
+sure
+surely
+surf
+surface
+surfeiting
+surmount
+surmounted
+surpassed
+surpasses
+surpassest
+surpassingly
+surprises
+surrounded
+surveyed
+suspect
+suspected
+suspense
+suspicions
+suspicious
+sustenance
+swallowed
+swaying
+sweat
+sweet
+sweeten
+sweetened
+sweeter
+sweetly
+sweetlyvain
+sweetness
+sweetnesses
+swelled
+swelling
+swept
+swerving
+swift
+swiftness
+swine
+swollen
+swoon
+sword
+syllable
+syllables
+symmachus
+sympathy
+syrian
+tabernacle
+table
+take
+taken
+takes
+taketh
+taking
+tale
+talent
+talented
+talents
+tales
+talk
+talked
+talkers
+talketh
+talking
+tame
+tamed
+tamedst
+tamer
+taming
+tardy
+task
+taste
+tasted
+tastes
+tasteth
+tasting
+tattlings
+taught
+taughtest
+taunt
+taunted
+tax
+taxes
+tcosa10
+tcosa10a
+tcosa11
+teach
+teacher
+teachers
+teaches
+teachest
+teacheth
+teaching
+teachings
+tear
+tearful
+tears
+tediousness
+teeming
+teeth
+tell
+tellest
+telleth
+telling
+tells
+temper
+temperament
+temperance
+tempered
+tempers
+tempestuously
+temple
+temples
+temporal
+temporary
+temporately
+tempt
+temptation
+temptations
+tempted
+tempting
+tempts
+ten
+tend
+tender
+tenderly
+tenderness
+tendernesses
+tending
+tends
+tenet
+tenets
+tenor
+terence
+termed
+terms
+terrestrial
+terrible
+terribly
+terrors
+testament
+testified
+testimonies
+testimony
+texas
+text
+texts
+thagaste
+than
+thank
+thankful
+thanks
+thanksgiving
+thanksgivings
+that
+the
+theatre
+theatres
+theatrical
+thee
+theft
+thefts
+their
+theirs
+them
+themselves
+then
+thence
+thenceforth
+there
+thereby
+therefore
+therefrom
+therein
+thereof
+thereon
+thereto
+thereupon
+therewith
+these
+thessalonica
+they
+thick
+thickeneth
+thickets
+thief
+thieve
+thin
+thine
+thing
+things
+think
+thinkest
+thinketh
+thinking
+thinks
+third
+thirdly
+thirst
+thirsted
+thirsteth
+thirsts
+thirtieth
+this
+thither
+thorns
+thoroughly
+those
+thou
+though
+thought
+thoughts
+thousand
+thraldom
+thread
+threatenest
+threatens
+threats
+three
+threefold
+thrice
+thriven
+throat
+throne
+thrones
+throng
+throngs
+through
+throughout
+thrown
+thrust
+thrustedst
+thunder
+thundered
+thunderer
+thunderest
+thundering
+thus
+thwart
+thy
+thyself
+tibi
+tickled
+tide
+tides
+tie
+tilde
+till
+time
+times
+tip
+tire
+tired
+title
+titles
+tm
+to
+tobias
+together
+toil
+toiled
+toiling
+toilsome
+token
+told
+tolerated
+tolerating
+toment
+tomenting
+tomorrow
+tone
+tones
+tongue
+tongues
+too
+took
+tookest
+top
+tore
+torment
+tormented
+torments
+torn
+torpor
+torrent
+torture
+toss
+tossed
+tosses
+total
+touch
+touched
+touchedst
+touching
+toward
+towardliness
+towards
+tower
+town
+townsman
+toys
+trace
+traced
+tracedst
+traces
+track
+trade
+trademark
+tradition
+tragical
+trailed
+trample
+trampled
+tranquil
+tranquillity
+transcribe
+transcription
+transferred
+transferring
+transformed
+transforming
+transgressing
+transgression
+transgressions
+transgressors
+transition
+transitory
+translated
+transmitted
+transparent
+transported
+travail
+travailed
+travailing
+travails
+traveller
+treacherous
+treachery
+tread
+treasure
+treasured
+treasures
+treasury
+treat
+treble
+tree
+trees
+tremble
+trembled
+trembling
+trial
+trials
+tribulation
+tribute
+tried
+triers
+trifles
+trifling
+trillion
+trine
+trinity
+triple
+triumph
+triumphed
+triumpheth
+trod
+trojan
+troop
+troops
+trouble
+troubled
+troubles
+troublesome
+troy
+true
+truer
+truly
+trust
+trustees
+trusting
+truth
+truths
+try
+trying
+tully
+tumbling
+tumult
+tumults
+tumultuous
+tumultuously
+tumultuousness
+tune
+turbulence
+turbulent
+turmoiling
+turmoils
+turn
+turned
+turnest
+turning
+turns
+tutor
+tutors
+twelve
+twentieth
+twenty
+twice
+twinkling
+twins
+twisted
+two
+txt
+ulcerous
+uman
+unabiding
+unable
+unacquainted
+unadorned
+unaided
+unallowed
+unalterable
+unanxious
+unarranged
+unassuming
+unawares
+unbecoming
+unbelievers
+unbelieving
+unbending
+unbeseemingly
+unbounded
+unbroken
+uncase
+unceasing
+uncertain
+uncertainties
+uncertainty
+unchain
+unchangeable
+unchangeableness
+unchangeably
+unchanged
+unclean
+uncleanness
+unconscious
+unconsciously
+uncorrupted
+uncorruptible
+uncorruptness
+uncultivated
+undefilable
+under
+undergo
+underline
+understand
+understandeth
+understanding
+understands
+understood
+undertake
+undertook
+underwent
+undid
+undistracted
+undisturbed
+undo
+unemployed
+unexpected
+unexpectedly
+unexplained
+unfailing
+unfailingly
+unfair
+unfeigned
+unfledged
+unforgotten
+unformed
+unfriendly
+ungodlily
+ungodliness
+ungodly
+ungoverned
+unhappily
+unhappiness
+unhappy
+unharmonising
+unhealthiness
+unhesitatingly
+unholy
+uninjurable
+uninjuriousness
+unintelligible
+unintermitting
+union
+united
+unity
+universal
+universally
+universe
+university
+unjust
+unjustly
+unkindled
+unkindness
+unknowing
+unknowingly
+unknown
+unlawful
+unlearned
+unless
+unlicensed
+unlike
+unlikeliness
+unlikeness
+unliker
+unlimited
+unlocked
+unlooked
+unmarried
+unmeasurable
+unmeasured
+unnatural
+unpassable
+unperceived
+unpermitted
+unpleasantly
+unpraised
+unpunished
+unquiet
+unravelied
+unravelled
+unreal
+unreasoning
+unresolved
+unrighteous
+unrulily
+unruly
+unsating
+unsearchable
+unseemly
+unseen
+unsettled
+unshaken
+unshakenly
+unskilful
+unskilfulness
+unsought
+unsound
+unspeakable
+unstable
+unstayed
+unsuitably
+unsure
+untainted
+unteach
+unteachable
+unthankful
+unthought
+until
+unto
+untruly
+untruth
+unused
+unusual
+unutterable
+unutterably
+unveiled
+unwarmed
+unwearied
+unwholesome
+unwilling
+unwonted
+unworthy
+unyielding
+up
+upborne
+upbraid
+upbraided
+upheld
+upheldest
+uphold
+upliftest
+upon
+upper
+upright
+uprightness
+uproar
+upward
+upwards
+urge
+urged
+urgedst
+urgently
+us
+usa
+usage
+use
+used
+useful
+usefully
+users
+uses
+useth
+ushered
+using
+usual
+usually
+usury
+utensils
+utmost
+utter
+utterance
+uttered
+uttereth
+utterly
+vacation
+vagrant
+vail
+vain
+vainglorious
+vainly
+valentinian
+valiant
+valley
+valuable
+value
+valued
+vanilla
+vanished
+vanities
+vanity
+vanquished
+vapours
+variable
+variableness
+variance
+variation
+variations
+varied
+varies
+varieties
+variety
+various
+variously
+vary
+varying
+vast
+vaster
+vaunt
+vehemence
+vehement
+vehemently
+veil
+veiled
+vein
+venerable
+vengeance
+vent
+venture
+ventures
+venturing
+venus
+ver
+verecundus
+verily
+verity
+vermont
+verse
+verses
+version
+versions
+very
+vessel
+vessels
+vestige
+vex
+vexed
+vi
+vice
+vices
+viciousness
+vicissitude
+vicissitudes
+victim
+victor
+victorinus
+victorious
+victory
+view
+viewing
+vigorous
+vigour
+vii
+viii
+vile
+vileness
+villa
+villainies
+vindicating
+vindicianus
+vineyard
+vintage
+violated
+violence
+violent
+violets
+viper
+virgil
+virgin
+virginity
+virgins
+virtue
+virtuous
+virus
+visible
+vision
+visions
+vital
+vivid
+vocal
+vocally
+voice
+voices
+void
+volume
+volumes
+voluntarily
+volunteers
+voluptuous
+voluptuousness
+vomited
+vouchsafe
+vouchsafed
+vouchsafedst
+vouchsafest
+vow
+vowed
+vowing
+vows
+voyage
+vulgar
+waft
+waged
+wages
+wail
+wait
+waited
+waiting
+waking
+walk
+walked
+walking
+walks
+wallow
+wallowed
+walls
+wander
+wandered
+wanderer
+wandering
+wanderings
+want
+wanted
+wanting
+wanton
+wantonly
+wantonness
+wants
+war
+warfare
+warmth
+warned
+warning
+warped
+warranted
+warranties
+warranty
+warreth
+warring
+wars
+was
+wash
+washing
+wast
+waste
+wasted
+wasting
+watch
+watched
+watchfully
+watchings
+water
+watered
+waterest
+waters
+watery
+waver
+wavered
+wavering
+waves
+wavy
+wax
+way
+wayfaring
+ways
+wayward
+we
+weak
+weaken
+weakened
+weaker
+weakest
+weakly
+weakness
+weaknesses
+weal
+wealth
+wealthy
+weapon
+wear
+wearied
+weariness
+wearing
+wearisome
+weary
+weaving
+wedlock
+weep
+weeping
+weeps
+weigh
+weighed
+weigheth
+weighing
+weight
+weights
+weighty
+welcome
+well
+weltering
+went
+wept
+were
+wert
+whales
+what
+whatever
+whatsoever
+wheat
+wheel
+when
+whence
+whencesoever
+whenever
+where
+whereas
+whereat
+whereby
+wherefore
+wherefrom
+wherein
+whereof
+whereon
+wheresoever
+whereto
+whereupon
+wherever
+wherewith
+whether
+which
+whichsoever
+while
+whilst
+whirling
+whirlings
+whirlpool
+whirlpools
+whispered
+whisperings
+whispers
+whit
+white
+whither
+whithersoever
+whitherto
+whitherward
+who
+whoever
+whole
+wholesome
+wholesomely
+wholesomeness
+wholly
+whom
+whomever
+whoring
+whose
+whoso
+whosoever
+why
+wicked
+wickedly
+wickedness
+wide
+widow
+widows
+wife
+wild
+wilderness
+wildness
+wilfully
+wilfulness
+will
+willed
+willedst
+willest
+willeth
+willing
+willingly
+wills
+wilt
+win
+wind
+winding
+windings
+window
+winds
+windus
+windy
+wine
+wings
+winked
+winning
+wins
+wipe
+wisdom
+wise
+wisely
+wiser
+wish
+wished
+wishes
+wishing
+wit
+with
+withal
+withdraw
+withdrawing
+withdrawn
+withdrew
+wither
+withered
+withering
+within
+without
+withstood
+witness
+witnesses
+witting
+wittingly
+wives
+wizard
+woe
+woes
+woke
+woman
+womanish
+womb
+women
+won
+wonder
+wondered
+wonderful
+wonderfully
+wonderfulness
+wondering
+wonders
+wondrous
+wondrously
+wont
+wonted
+wood
+wooden
+wooed
+word
+wordly
+words
+wordy
+work
+workest
+worketh
+workhouse
+working
+workings
+workmanship
+workmaster
+works
+world
+worldly
+worlds
+worm
+worn
+worse
+worship
+worshipped
+worshipper
+worshippers
+worshipping
+worsted
+worthless
+worthy
+would
+wouldest
+wound
+wounded
+woundest
+wounds
+wove
+wrap
+wrath
+wrench
+wrested
+wretch
+wretched
+wretchedness
+wring
+wrinkle
+writ
+write
+writer
+writing
+writings
+written
+wrong
+wronged
+wronging
+wrote
+wroth
+wrought
+wyoming
+ye
+yea
+year
+years
+yes
+yesterday
+yet
+yield
+yielded
+yieldeth
+yielding
+yields
+yoke
+you
+young
+younger
+your
+yourselves
+youth
+youthful
+youthfulness
+youths
+zeal
+zealous
+zealously
+zip
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/Gr.HH.HTML b/public/Wb/Home/Src/Adam/Gr/Gr.HH.HTML new file mode 100755 index 0000000..ff8d3f2 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/Gr.HH.HTML @@ -0,0 +1,211 @@ + + + + + + + + + + + +
+#help_index "Sprites/Binary"
+
+class CMeshTri
+{
+  I32 color;    //Give one of 0-7 colors.
+//Colors 8-15 are 0-7 with intensity bit set.
+  I32 nums[3];  //Vertex number
+};
+
+class CQueMeshTri
+{
+  CQueMeshTri *next,*last;
+  U0 start;
+  I32 color;
+  I32 nums[3];
+};
+
+public class CSpriteBase
+{
+  U8 type;
+};
+
+public class CSpriteColor : CSpriteBase
+{
+  U8 color;
+};
+
+public class CSpriteDitherColor : CSpriteBase
+{
+  U16 dither_color;
+};
+
+public class CSpriteT : CSpriteBase
+{
+  I32 thick;
+};
+
+public class CSpritePt : CSpriteBase
+{
+  I32 x1;
+  I32 y1;
+};
+
+public class CSpritePtRad : CSpritePt
+{
+  I32 radius;
+};
+
+public class CSpritePtPt : CSpritePt
+{
+  I32 x2;
+  I32 y2;
+};
+
+public class CSpritePtPtAng : CSpritePtPt
+{
+  F64 angle;
+};
+
+public class CSpritePtWH : CSpritePt
+{
+  I32 width;
+  I32 height;
+};
+
+public class CSpritePtWHU8s : CSpritePtWH
+{
+  U8 u[0];
+};
+
+public class CSpritePtWHAng : CSpritePtWH
+{
+  F64 angle;
+};
+
+public class CSpritePtWHAngSides : CSpritePtWHAng
+{
+  I32 sides;
+};
+
+public class CSpriteNumU8s : CSpriteBase
+{
+  I32 num;
+  U8  u[0];
+};
+
+public class CSpriteNumPtU8s : CSpriteBase
+{
+  I32 num;
+  I32 x;
+  I32 y;
+  U8  u[0];
+};
+
+public class CSpritePtStr : CSpritePt
+{
+  U8  st[0];
+};
+
+public class CSpriteMeshU8s : CSpriteBase
+{
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  U8  u[0];
+};
+
+public class CSpritePtMeshU8s : CSpriteBase
+{
+  I32 x;
+  I32 y;
+  I32 z;
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  U8  u[0];
+};
+
+#define SPF_SEL                 128
+#define SPf_SEL                 7
+
+#define SPT_END                 0       //CSpriteBase
+#define SPT_COLOR               1       //CSpriteColor
+#define SPT_DITHER_COLOR        2       //CSpriteDitherColor
+#define SPT_THICK               3       //CSpriteT
+#define SPT_PLANAR_SYMMETRY     4       //CSpritePtPt
+#define SPT_TRANSFORM_ON        5       //CSpriteBase
+#define SPT_TRANSFORM_OFF       6       //CSpriteBase
+#define SPT_SHIFT               7       //CSpritePt
+#define SPT_PT                  8       //CSpritePt
+#define SPT_POLYPT              9       //CSpriteNumPtU8s
+#define SPT_LINE                10      //CSpritePtPt
+#define SPT_POLYLINE            11      //CSpriteNumU8s
+#define SPT_RECT                12      //CSpritePtPt
+#define SPT_ROTATED_RECT        13      //CSpritePtPtAng
+#define SPT_CIRCLE              14      //CSpritePtRad
+#define SPT_ELLIPSE             15      //CSpritePtWHAng
+#define SPT_POLYGON             16      //CSpritePtWHAngSides
+#define SPT_BSPLINE2            17      //CSpriteNumU8s
+#define SPT_BSPLINE2_CLOSED     18      //CSpriteNumU8s
+#define SPT_BSPLINE3            19      //CSpriteNumU8s
+#define SPT_BSPLINE3_CLOSED     20      //CSpriteNumU8s
+#define SPT_FLOOD_FILL          21      //CSpritePt
+#define SPT_FLOOD_FILL_NOT      22      //CSpritePt
+#define SPT_BITMAP              23      //CSpritePtWHU8s
+#define SPT_MESH                24      //CSpriteMeshU8s See ::/Apps/GrModels.
+#define SPT_SHIFTABLE_MESH      25      //CSpritePtMeshU8s See ::/Apps/GrModels.
+#define SPT_ARROW               26      //CSpritePtPt
+#define SPT_TEXT                27      //CSpritePtStr
+#define SPT_TEXT_BOX            28      //CSpritePtStr
+#define SPT_TEXT_DIAMOND        29      //CSpritePtStr
+#define SPT_TYPES_NUM           30
+#define SPG_TYPE_MASK           0x7F
+
+#help_index "Graphics/Sprite;Sprites;Sprites/Binary"
+
+//See Sprites.  See ::/Adam/Gr/GrSpritePlot.HC and
+//::/Demo/Graphics/SpriteRaw.HC for how CSprite are stored.
+public class CSprite
+{
+  CSprite *next,*last;
+  U0 start;
+  union {
+    U8 type;
+    CSpriteBase         b;
+    CSpriteColor        c;
+    CSpriteDitherColor  d;
+    CSpriteT            t;
+    CSpritePt           p;
+    CSpritePtPt         pp;
+    CSpritePtPtAng      ppa;
+    CSpritePtRad        pr;
+    CSpritePtWHU8s      pwhu;
+    CSpritePtWHAng      pwha;
+    CSpritePtWHAngSides pwhas;
+    CSpriteNumU8s       nu;
+    CSpriteNumPtU8s     npu;
+    CSpriteMeshU8s      mu;
+    CSpritePtMeshU8s    pmu;
+    CSpritePtStr        ps;
+  }
+};
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrAsm.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrAsm.HC.HTML new file mode 100755 index 0000000..64840f8 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrAsm.HC.HTML @@ -0,0 +1,441 @@ + + + + + + + + + + + +
+#help_index "Graphics/Misc"
+asm {
+//************************************
+_GR_UPDATE_LINE64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RSI,U64 [RAX]           //rsi=src
+        MOV     RBX,U64 [&rev_bits_table]
+        MOV     RCX,U64 SF_ARG3[RBP]    //rcx=d
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     RDI,U64 [RAX]           //rdi=image
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     R8,U64 [RAX]            //rbp=vga dst
+
+@@05:   LODSQ
+        CMP     U64 [RDI],RAX
+        JE      @@10
+        MOV     U64 [RDI],RAX
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        MOV     U64 [R8],RAX
+@@10:   ADD     RDI,8
+        ADD     R8,8
+        DEC     RCX
+        JNZ     @@05
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     U64 [RAX],R8
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     U64 [RAX],RDI
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     U64 [RAX],RSI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+//************************************
+_GR_UPDATE_LINE64_FLUSH_CACHE::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RSI,U64 [RAX]           //rsi=src
+        MOV     RBX,U64 [&rev_bits_table]
+        MOV     RCX,U64 SF_ARG3[RBP]    //rcx=d
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     RDI,U64 [RAX]           //rdi=image
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     R8,U64 [RAX]            //rbp=vga dst
+
+@@05:   LODSQ
+        MOV     U64 [RDI],RAX
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        XLATB
+        ROR     RAX,8
+        MOV     U64 [R8],RAX
+        ADD     RDI,8
+        ADD     R8,8
+        DEC     RCX
+        JNZ     @@05
+
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     U64 [RAX],R8
+        MOV     RAX,U64 SF_ARG4[RBP]
+        MOV     U64 [RAX],RDI
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     U64 [RAX],RSI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+//************************************
+_DC_BLOT_COLOR4::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        PUSH    R10
+
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        MOV     R8,RDI
+        ADD     R8,RCX
+        MOV     R9,R8
+        ADD     R9,RCX
+        MOV     R10,R9
+        ADD     R10,RCX
+
+@@5:    LODSQ
+        MOV     RDX,U64 [RBX]
+        CMP     RAX,RDX
+        JE      I32 @@10
+        MOV     U64 [RBX],RAX
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+0
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+0
+        ADC     RDX,0
+        MOV     U8 [RDI],DL
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+1
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+1
+        ADC     RDX,0
+        MOV     U8 [R8],DL
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+2
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+2
+        ADC     RDX,0
+        MOV     U8 [R9],DL
+
+        XOR     RDX,RDX
+        BT      RAX,7*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,6*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,5*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,4*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,3*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,2*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,1*8+3
+        ADC     RDX,0
+        SHL1    RDX
+        BT      RAX,0*8+3
+        ADC     RDX,0
+        MOV     U8 [R10],DL
+
+@@10:   ADD     RBX,8
+
+        INC     RDI
+        INC     R8
+        INC     R9
+        INC     R10
+
+        DEC     RCX
+        JNZ     I32 @@5
+
+        POP     R10
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+//************************************
+_IS_PIX_COVERED0::
+        PUSH    RBP
+        MOV     RBP,RSP
+#assert FONT_WIDTH==FONT_HEIGHT==8
+        MOV     RCX,U64 SF_ARG3[RBP]
+        SAR     RCX,3
+        MOV     RAX,U64 SF_ARG2[RBP]
+        SAR     RAX,3
+        MOV     RDX,U64 SF_ARG1[RBP]
+        IMUL2   RCX,TEXT_COLS
+        MOV     RBX,U64 [&gr.win_z_buf]
+        MOV     DX,U16 CTask.win_z_num[RDX]
+        ADD     RCX,RAX
+        XOR     RAX,RAX
+        CMP     DX,U16 [RBX+RCX*2]
+        JAE     @@05    //Jump not covered
+        INC     RAX
+@@05:   POP     RBP
+        RET1    24
+//************************************
+_GR_ROP_EQU_U8_NO_CLIPPING::
+//Puts foreground char shape onto gr.dc2.
+//ch.u8[1] is color as a whole byte
+//ch ATTRf_UNDERLINE attr flag is used.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOVZX   RAX,U8 SF_ARG1[RBP]
+        MOV     RDX,U64 [&text.font]
+        MOV     RAX,U64 [RDX+RAX*8]     //RAX is 8x8 char font data, 64-bits
+        BT      U64 SF_ARG1[RBP],ATTRf_UNDERLINE
+        JNC     @@05
+        MOV     RBX,0xFF00000000000000
+        OR      RAX,RBX
+@@05:   TEST    RAX,RAX
+        JZ      I32 @@10
+
+        PUSH    RSI
+        PUSH    RDI
+        MOVZX   RBX,U8 SF_ARG1+1[RBP]   //Warning color is 8-bit
+        MOV     RDX,U64 [&gr.to_8_colors]
+        MOV     R8,U64 [RDX+RBX*8]      //R8 is color repeated 8 times.
+        MOV     R9,U64 SF_ARG3[RBP]     //R9 is width_internal
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RSI,U64 [&gr.to_8_bits] //RSI is gr.to_8_bits
+
+//      m=my_1_to_8_bits[ch&255];ch>>=8;
+//      *dst=*dst&~m|c&m;
+//      dst(U8 *)+=w1;
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOVZX   RBX,AL
+        MOV     RDX,U64 [RSI+RBX*8]
+        SHR     RAX,8
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+        ADD     RDI,R9
+
+        MOV     RDX,U64 [RSI+RAX*8]
+        MOV     RBX,U64 [RDI]
+        MOV     RCX,RDX
+        NOT     RCX
+        AND     RDX,R8
+        AND     RCX,RBX
+        OR      RCX,RDX
+        MOV     U64 [RDI],RCX
+
+        POP     RDI
+        POP     RSI
+@@10:   POP     RBP
+        RET1    24
+}
+_extern _GR_ROP_EQU_U8_NO_CLIPPING U0 GrRopEquU8NoClipping(I64 ch,
+        U8 *dst,I64 width_internal);
+public _extern _IS_PIX_COVERED0 Bool IsPixCovered0(
+        CTask *task,I64 x,I64 y);//No clipping
+
+_extern _GR_UPDATE_LINE64 U0 GrUpdateLine64(
+  U64 **_vga,U64 **_src,I64 d,U8 **_dst);
+_extern _GR_UPDATE_LINE64_FLUSH_CACHE U0 GrUpdateLine64FlushCache(
+  U64 **_vga,U64 **_src,I64 d,U8 **_dst);
+_extern _DC_BLOT_COLOR4 U0 DCBlotColor4(
+  U8 *dst,I64 *img,I64 *img_cache,I64 cnt);
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrBitMap.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrBitMap.HC.HTML new file mode 100755 index 0000000..94abc58 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrBitMap.HC.HTML @@ -0,0 +1,2085 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+Option(OPTf_WARN_HEADER_MISMATCH,OFF);
+public Bool GrPlot0(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. No clipping or transformation or thick.
+  U8 *dst;
+  I32 *db;
+  I64 d,dist;
+  CColorROPU32 c,color=dc->color,bkcolor=dc->bkcolor;
+
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    dist=DistSqrI64(x,y,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_RECORD_EXTENTS) {
+    if (x<dc->min_x) dc->min_x=x;
+    if (x>dc->max_x) dc->max_x=x;
+    if (y<dc->min_y) dc->min_y=y;
+    if (y>dc->max_y) dc->max_y=y;
+  }
+  if (dc->flags & DCF_DONT_DRAW)
+    return TRUE;
+  d=dc->width_internal*y+x;
+  if (db=dc->depth_buf) {
+    db+=d;
+    if (0<=dc->db_z<=*db)
+      *db=dc->db_z;
+    else
+      return TRUE;
+  }
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      if (RandU16<dc->dither_probability_u16) {
+        color.c1.rop=color.c0.rop;
+        color.c0=color.c1;
+      }
+    } else {
+      if ((x^y)&1) {
+        color.c1.rop=color.c0.rop;
+        color.c0=color.c1;
+      }
+    }
+  }
+  dst=dc->body+d;
+  switch [color.c0.rop] {
+    case ROPB_EQU:
+    case ROPB_MONO:
+      *dst=color.c0.color;
+      break;
+    case ROPB_COLLISION:
+      c=*dst;
+      if (c!=TRANSPARENT && c!=bkcolor.c0.color)
+        dc->collision_cnt++;
+      break;
+    case ROPB_XOR:
+      *dst^=color.c0.color;
+      break;
+  }
+  return TRUE;
+}
+Option(OPTf_WARN_HEADER_MISMATCH,ON);
+
+public I64 GrPeek0(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. No clipping or transformation.
+  return dc->body[dc->width_internal*y+x];
+}
+
+#help_index "Graphics;Graphics/Device Contexts"
+
+public I64 GrBlot(CDC *dc=gr.dc,I64 x,I64 y,CDC *img)
+{//2D. Clipping but not transformation..
+  I64 i,j,k,k1,kk,kk1,w1,h1,w2,h2,dist,
+        leading_pixels,leading_pixel_mask,whole_I64s,
+        trailing_pixels,trailing_pixel_mask,
+        reg bit_shift,win_z_buf_line_inc,win_z_buf_line_dec,win_z_num,
+        color_mask;
+  U8 reg *dst,*src;
+  I32 *db;
+  U16 reg *win_z_buf_ptr;
+  CColorROPU32 color,c,old_color;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+  if (x<0)
+    w1=-x;
+  else
+    w1=0;
+  if (y<0)
+    h1=-y;
+  else
+    h1=0;
+  w2=img->width;
+  h2=img->height;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x+=win_task->pix_left;
+    y+=win_task->pix_top;
+  }
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    dist=DistSqrI64(x+img->width>>1,y+img->height>>1,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    if (x+w1<0) w1=-x;
+    if (x+w2>win_task->pix_right+1)
+      w2=win_task->pix_right+1-x;
+
+    if (y+h1<0) h1=-y;
+    if (y+h2>win_task->pix_bottom+1)
+      h2=win_task->pix_bottom+1-y;
+  }
+  if (x+w2>dc->width)
+    w2=dc->width-x;
+  if (y+h2>dc->height)
+    h2=dc->height-y;
+  if (w1<w2<=img->width && h1<h2<=img->height) {
+    if (dc->flags & DCF_RECORD_EXTENTS) {
+      if (x+w1<dc->min_x) dc->min_x=x+w1;
+      if (x+w2-1>dc->max_x) dc->max_x=x+w2-1;
+      if (y+h1<dc->min_y) dc->min_y=y+h1;
+      if (y+h2-1>dc->max_y) dc->max_y=y+h2-1;
+    }
+    if (dc->flags & DCF_DONT_DRAW)
+      return 1;
+    old_color=dc->color;
+    db=dc->depth_buf;
+    dc->depth_buf=NULL;
+    dc->color&=~ROPF_DITHER;
+    color=dc->color;
+    leading_pixels=-(w1+x)&7;
+    leading_pixel_mask=gr.to_8_bits[0xFF>>leading_pixels];
+    bit_shift=-x&7;
+    whole_I64s=(w2-w1-leading_pixels)>>3;
+    if (whole_I64s<0) whole_I64s=0;
+    trailing_pixels=(x+w2)&7;
+    trailing_pixel_mask=gr.to_8_bits[0xFF<<trailing_pixels&0xFF];
+    if (leading_pixels+trailing_pixels>w2-w1) {
+      leading_pixel_mask|=trailing_pixel_mask;
+      trailing_pixels=0;
+    }
+    switch (color.c0.rop) {
+      case ROPB_COLLISION: //TODO: Might want to check win_z_buf
+        color =dc->bkcolor.c0.color;
+        k=h1*img->width_internal;
+        k1=(h1+y)*dc->width_internal+x;
+        for (j=h2-h1;j;j--) {
+          for (i=w1;i<w2;i++) {
+            c=dc->body[k1+i];
+            if (c!=TRANSPARENT&&c!=color&&img->body[k+i]!=TRANSPARENT)
+              dc->collision_cnt++;
+          }
+          k+=img->width_internal;
+          k1+=dc->width_internal;
+        }
+        break;
+      case ROPB_MONO:
+        color_mask=gr.to_8_colors[color.c0.color];
+        if (img->flags&DCF_NO_TRANSPARENTS) {
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+            win_z_buf_ptr=NULL;
+          else {
+            win_z_num=win_task->win_z_num;
+            win_z_buf_ptr=gr.win_z_buf(U8 *)+((h1+y)/FONT_HEIGHT*TEXT_COLS+
+                  (w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+          }
+          kk = h1   *img ->width_internal+w1;
+          kk1=(h1+y)*dc->width_internal+x+w1;
+          kk =(kk-bit_shift)&~7+bit_shift;
+          bit_shift*=8;
+          if (win_z_buf_ptr)
+            for (j=h1;j<h2;j++) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (win_z_num>=*win_z_buf_ptr++) {
+                  if (bit_shift)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift))&
+                          ~leading_pixel_mask&color_mask;
+                  else
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *src(I64 *)++&~leading_pixel_mask&color_mask;
+                } else {
+                  src(I64 *)++;
+                  dst(I64 *)++;
+                }
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=(*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift))&color_mask;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              else
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=*src(I64 *)++&color_mask;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&
+                        ~trailing_pixel_mask&color_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask&color_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+            }
+          else
+            for (j=h2-h1;j;j--) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&
+                        ~leading_pixel_mask&color_mask;
+                else
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        *src(I64 *)++&~leading_pixel_mask&color_mask;
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&color_mask;
+              else
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=*src(I64 *)++&color_mask;
+
+              if (trailing_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&
+                        ~trailing_pixel_mask&color_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask&color_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+            }
+        } else {
+          k=h1*img->width_internal;
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP) {
+            for (j=h1;j<h2;j++) {
+              for (i=w1;i<w2;i++)
+                if (img->body[k+i])
+                  GrPlot0(dc,x+i,y+j);
+              k+=img->width_internal;
+            }
+          } else {
+            win_z_num           =win_task->win_z_num;
+            win_z_buf_ptr       =gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+            for (j=h1;j<h2;j++) {
+              if (win_z_num>=*win_z_buf_ptr++)
+                color_mask=TRUE;
+              else
+                color_mask=FALSE;
+              for (i=w1;i<w2;) {
+                if (color_mask)
+                  if (img->body[k+i])
+                    GrPlot0(dc,x+i,y+j);
+                if (!((++i+x) &7) && i<w2) {
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    color_mask=TRUE;
+                  else
+                    color_mask=FALSE;
+                }
+              }
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+              k+=img->width_internal;
+            }
+          }
+        }
+        break;
+      case ROPB_EQU:
+        if (img->flags&DCF_NO_TRANSPARENTS) {
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+            win_z_buf_ptr=NULL;
+          else {
+            win_z_num=win_task->win_z_num;
+            win_z_buf_ptr=gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+          }
+          kk = h1   *img ->width_internal+w1;
+          kk1=(h1+y)*dc->width_internal+x+w1;
+          kk =(kk-bit_shift)&~7+bit_shift;
+          bit_shift*=8;
+          if (win_z_buf_ptr)
+            for (j=h1;j<h2;j++) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (win_z_num>=*win_z_buf_ptr++) {
+                  if (bit_shift)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift))&~leading_pixel_mask;
+                  else
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *src(I64 *)++&~leading_pixel_mask;
+                } else {
+                  src(I64 *)++;
+                  dst(I64 *)++;
+                }
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift);
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              else
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++=*src(I64 *)++;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+            }
+          else
+            for (j=h2-h1;j;j--) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&~leading_pixel_mask;
+                else
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        *src(I64 *)++&~leading_pixel_mask;
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift);
+              else
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++=*src(I64 *)++;
+
+              if (trailing_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *src(I64 *)++&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+            }
+        } else {
+here1a:
+          k=h1*img->width_internal;
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP) {
+            for (j=h1;j<h2;j++) {
+              for (i=w1;i<w2;i++) {
+                c=img->body[k+i];
+                if (c!=TRANSPARENT) {
+                  dc->color.c0.color=c;
+                  GrPlot0(dc,x+i,y+j);
+                }
+              }
+              k+=img->width_internal;
+            }
+          } else {
+            win_z_num           =win_task->win_z_num;
+            win_z_buf_ptr       =gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+            for (j=h1;j<h2;j++) {
+              if (win_z_num>=*win_z_buf_ptr++)
+                color_mask=TRUE;
+              else
+                color_mask=FALSE;
+              for (i=w1;i<w2;) {
+                if (color_mask) {
+                  c=img->body[k+i];
+                  if (c!=TRANSPARENT) {
+                    dc->color.c0.color=c;
+                    GrPlot0(dc,x+i,y+j);
+                  }
+                }
+                if (!((++i+x) &7) && i<w2) {
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    color_mask=TRUE;
+                  else
+                    color_mask=FALSE;
+                }
+              }
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+              k+=img->width_internal;
+            }
+          }
+          dc->color=color;
+        }
+        break;
+      case ROPB_XOR:
+        if (img->flags&DCF_NO_TRANSPARENTS) {
+          if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+            win_z_buf_ptr=NULL;
+          else {
+            win_z_num=win_task->win_z_num;
+            win_z_buf_ptr=gr.win_z_buf(U8 *)+
+                  ((h1+y)/FONT_HEIGHT*TEXT_COLS+(w1+x)/FONT_WIDTH)*sizeof(U16);
+            win_z_buf_line_dec=whole_I64s;
+            if (leading_pixels)
+              win_z_buf_line_dec++;
+            if (trailing_pixels)
+              win_z_buf_line_dec++;
+            win_z_buf_line_dec*=sizeof(U16);
+            win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+          }
+          kk = h1   *img ->width_internal  +w1;
+          kk1=(h1+y)*dc->width_internal+x+w1;
+          kk =(kk-bit_shift)&~7+bit_shift;
+          bit_shift*=8;
+          if (win_z_buf_ptr)
+            for (j=h1;j<h2;j++) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (win_z_num>=*win_z_buf_ptr++) {
+                  if (bit_shift)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift)))&~leading_pixel_mask;
+                  else
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          (*dst(I64 *)^*src(I64 *)++)&~leading_pixel_mask;
+                } else {
+                  src(I64 *)++;
+                  dst(I64 *)++;
+                }
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++^=*src(U64 *)++>>bit_shift|
+                          *src(I64 *)<<(64-bit_shift);
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              else
+                for (i=0;i<whole_I64s;i++)
+                  if (win_z_num>=*win_z_buf_ptr++)
+                    *dst(I64 *)++^=*src(I64 *)++;
+                  else {
+                    src(I64 *)++;
+                    dst(I64 *)++;
+                  }
+              if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift)))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^*src(I64 *)++)&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+              if ((j+y)&7==7)
+                win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+              else
+                win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+            }
+          else
+            for (j=h2-h1;j;j--) {
+              src=img->body+kk&~7;
+              dst=dc->body+kk1&~7;
+              if (leading_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift)))&~leading_pixel_mask;
+                else
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        (*dst(I64 *)^*src(I64 *)++)&~leading_pixel_mask;
+              }
+              if (bit_shift)
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++^=*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift);
+              else
+                for (i=0;i<whole_I64s;i++)
+                  *dst(I64 *)++^=*src(I64 *)++;
+              if (trailing_pixels) {
+                if (bit_shift)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^(*src(U64 *)++>>bit_shift|
+                        *src(I64 *)<<(64-bit_shift)))&~trailing_pixel_mask;
+                else
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^*src(I64 *)++)&~trailing_pixel_mask;
+              }
+              kk +=img->width_internal;
+              kk1+=dc->width_internal;
+            }
+        } else
+          goto here1a;
+        break;
+    }
+    dc->depth_buf=db;
+    dc->color=old_color;
+    return 1;
+  } else
+    return 0;
+}
+
+#help_index "Graphics/Device Contexts"
+
+U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor)
+{
+  I64 c,k,i=src_size*2,i1=i>>3;
+  for (k=0;k<i;k++) {
+    c=0;
+    if (Bt(src     ,k)) c|=1;
+    if (Bt(src+i1  ,k)) c|=2;
+    if (Bt(src+i1*2,k)) c|=4;
+    if (Bt(src+i1*3,k)) c|=8;
+    if (c==bkcolor) c=TRANSPARENT;
+    *dst++=c;
+  }
+  return dst;
+}
+
+U8 *GrBitMap1ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor)
+{
+  I64 c,k,i=src_size*8;
+  for (k=0;k<i;k++) {
+    c=0;
+    if (Bt(src,k))  c=COLOR_MONO;
+    if (c==bkcolor) c=TRANSPARENT;
+    *dst++=c;
+  }
+  return dst;
+}
+
+public CDC *DCExt(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
+        CTask *task=NULL)
+{//Extract new device context rect from device context.
+  CDC *res;
+  CTask *win_task;
+  if (x1>x2) SwapI64(&x1,&x2);
+  if (y1>y2) SwapI64(&y1,&y2);
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x1+=win_task->pix_left+win_task->scroll_x;
+    y1+=win_task->pix_top +win_task->scroll_y;
+    x2+=win_task->pix_left+win_task->scroll_x;
+    y2+=win_task->pix_top +win_task->scroll_y;
+  }
+  res=DCNew(x2-x1+1,y2-y1+1,task);
+  DCFill(res);
+  GrBlot(res,-x1,-y1,dc);
+  return res;
+}
+
+public CDC *DCDiff(CDC *base,CDC *update)
+{//Trim to win of what has chged.
+  I64 i,x1=0,y1=0,x2=update->width-1,y2=update->height-1; //inclusive
+  U32 *ptr_base,*ptr_update;
+  CDC *res;
+  ptr_base  =base->body;
+  ptr_update=update->body;
+  while (y1<=y2) {
+    i=update->width>>2;
+    while (i--)
+      if (*ptr_base++!=*ptr_update++)
+        goto df_y2;
+    i=update->width&3;
+    while (i--)
+      if (*ptr_base(U8 *)++!=*ptr_update(U8 *)++)
+        goto df_y2;
+    y1++;
+  }
+  return NULL;
+df_y2:
+  ptr_base  =base->body  +base->width_internal  *base->height;
+  ptr_update=update->body+update->width_internal*update->height;
+  while (y1<y2) {
+    i=update->width>>2;
+    while (i--)
+      if (*--ptr_base!=*--ptr_update)
+        goto df_x1;
+    i=update->width&3;
+    while (i--)
+      if (*--ptr_base(U8 *)!=*--ptr_update(U8 *))
+        goto df_x1;
+    y2--;
+  }
+df_x1:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++)
+      if (GrPeek0(base,x1,i)!=GrPeek0(update,x1,i))
+         goto df_x2;
+    x1++;
+  }
+df_x2:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++)
+      if (GrPeek0(base,x2,i)!=GrPeek0(update,x2,i))
+         goto df_done;
+    x2--;
+  }
+df_done:
+  res=DCExt(update,x1,y1,x2,y2);
+  res->x0=x1;
+  res->y0=y1;
+  return res;
+}
+
+#help_index "Graphics/Char;Char/Graphics"
+
+public I64 GrPutChar(CDC *dc=gr.dc,I64 x,I64 y,U8 ch)
+{//2D. Clipping but not transformation.
+  U8 reg *src,reg *dst,*font_ptr;
+  I64 i,m,leading_pixels,trailing_pixels,leading_pixel_mask,trailing_pixel_mask,
+        j,k1,kk1,w1,h1,w2,h2,reg bit_shift,reg color_mask,dist;
+  CColorROPU32 color,c;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+
+  if (x<0)
+    w1=-x;
+  else
+    w1=0;
+  if (y<0)
+    h1=-y;
+  else
+    h1=0;
+  w2=FONT_WIDTH;
+  h2=FONT_HEIGHT;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x+=win_task->pix_left;
+    y+=win_task->pix_top;
+  }
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    dist=DistSqrI64(x+w2>>1,y+h2>>1,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    if (x+w1<0) w1=-x;
+    if (x+w2>win_task->pix_right+1)
+      w2=win_task->pix_right+1-x;
+
+    if (y+h1<0) h1=-y;
+    if (y+h2>win_task->pix_bottom+1)
+      h2=win_task->pix_bottom+1-y;
+  }
+  if (x+w2>dc->width)
+    w2=dc->width-x;
+  if (y+h2>dc->height)
+    h2=dc->height-y;
+  if (w1<w2<=FONT_WIDTH && h1<h2<=FONT_HEIGHT) {
+    if (dc->flags & DCF_RECORD_EXTENTS) {
+      if (x+w1  <dc->min_x) dc->min_x=x+w1;
+      if (x+w2-1>dc->max_x) dc->max_x=x+w2-1;
+      if (y+h1  <dc->min_y) dc->min_y=y+h1;
+      if (y+h2-1>dc->max_y) dc->max_y=y+h2-1;
+    }
+    if (dc->flags & DCF_DONT_DRAW)
+      return 1;
+    color=dc->color;
+    leading_pixels=-(w1+x)&7;
+    if (!leading_pixels) leading_pixels=8;
+    leading_pixel_mask=gr.to_8_bits[0xFF>>leading_pixels];
+    bit_shift=-x&7;
+    trailing_pixels=(x+w2)&7;
+    trailing_pixel_mask=gr.to_8_bits[0xFF<<trailing_pixels&0xFF];
+    if (leading_pixels+trailing_pixels>w2-w1) {
+      leading_pixel_mask|=trailing_pixel_mask;
+      trailing_pixels=0;
+    }
+    font_ptr=&text.font(U8 *)[FONT_HEIGHT*ch+h1];
+    if (color.c0.rop==ROPB_COLLISION) {
+      m=w1&(FONT_WIDTH-1);
+#assert FONT_WIDTH==8
+      color =dc->bkcolor.c0.color;
+      for (i=w1;i<w2;i++,m++) {
+        k1=(h1+y)*dc->width_internal+x;
+        src=font_ptr;
+        for (j=h2-h1;j;j--) {
+          c=dc->body[k1+i];
+          if (c!=TRANSPARENT && c!=color && Bt(src,m))
+            dc->collision_cnt++;
+          k1+=dc->width_internal;
+          src++;
+        }
+      }
+    } else {
+      color_mask=gr.to_8_colors[color.c0.color];
+      k1=x+w1;
+      kk1=(h1+y)*dc->width_internal+k1;
+      if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP) {
+        if (leading_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h2-h1;j;j--) {
+                m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                      (color_mask&m|*dst(I64 *)&~m)&~leading_pixel_mask;
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask) {
+                for (j=h2-h1;j;j--) {
+                  *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                        (*dst(I64 *)^gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF])&
+                        ~leading_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              }
+              break;
+          }
+          kk1+=8;
+        }
+        if (trailing_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr+1;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h2-h1;j;j--) {
+                m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                      (color_mask&m|*dst(I64 *)&~m)&~trailing_pixel_mask;
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask)
+                for (j=h2-h1;j;j--) {
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (*dst(I64 *)^gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF])&
+                        ~trailing_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              break;
+          }
+        }
+      } else {
+        if (leading_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h1;j<h2;j++) {
+                if (!IsPixCovered0(win_task,k1,y+j)) {
+                  m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                  *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                        (color_mask&m|*dst(I64 *)&~m)&~leading_pixel_mask;
+                }
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask)
+                for (j=h1;j<h2;j++) {
+                  if (!IsPixCovered0(win_task,k1,y+j))
+                    *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                          (*dst(I64 *)^gr.to_8_bits
+                          [*src(U16 *)>>bit_shift&0xFF])&
+                          ~leading_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              break;
+          }
+          k1+=8;
+          kk1+=8;
+        }
+        if (trailing_pixels) {
+          dst=dc->body+kk1&~7;
+          src=font_ptr+1;
+          if (bit_shift)
+            src--;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              for (j=h1;j<h2;j++) {
+                if (!IsPixCovered0(win_task,k1,y+j)) {
+                  m=gr.to_8_bits[*src(U16 *)>>bit_shift&0xFF];
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        (color_mask&m|*dst(I64 *)&~m)&~trailing_pixel_mask;
+                }
+                src++;
+                dst+=dc->width_internal;
+              }
+              break;
+            case ROPB_XOR:
+              if (color_mask)
+                for (j=h1;j<h2;j++) {
+                  if (!IsPixCovered0(win_task,k1,y+j))
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          (*dst(I64 *)^gr.to_8_bits
+                          [*src(U16 *)>>bit_shift&0xFF])&
+                          ~trailing_pixel_mask;
+                  src++;
+                  dst+=dc->width_internal;
+                }
+              break;
+          }
+        }
+      }
+    }
+    return 1;
+  } else
+    return 0;
+}
+
+I64 GrPutS(CDC *dc=gr.dc,I64 x,I64 y,U8 *_s)
+{//Use GrPrint()
+  I64 x0,sx=0,sy=0,res;
+  if (!_s) return 0;
+  x0=x;
+  res=0;
+  while (*_s) {
+    if (*_s=='\n') {
+      x=x0;
+      y+=FONT_HEIGHT;
+      _s++;
+    } else if (*_s=='\t') {
+      x=x0+CeilU64(x-x0+FONT_WIDTH,8*FONT_WIDTH);
+      _s++;
+    } else if (*_s(U32 *)=='$SY,') {
+      if (_s[4]=='-') {
+        _s++;
+        sy='0'-_s[4];
+      } else
+        sy=_s[4]-'0';
+      _s+=6;
+    } else if (*_s(U32 *)=='$SX,') {
+      if (_s[4]=='-') {
+        _s++;
+        sx='0'-_s[4];
+      } else
+        sx=_s[4]-'0';
+      _s+=6;
+    } else {
+      res+=GrPutChar(dc,x+sx,y+sy,*_s);
+      x+=FONT_WIDTH;
+      _s++;
+    }
+  }
+  return res;
+}
+
+I64 GrVPutS(CDC *dc=gr.dc,I64 x,I64 y,U8 *_s)
+{//Vertical Text.  Use GrVPrint()
+  I64 y0,sx=0,sy=0,res;
+  U8 buf[2];
+  if (!_s) return 0;
+  y0=y;
+  res=0;
+  buf[1]=0;
+  while (*_s) {
+    if (*_s=='\n') {
+      y=y0;
+      x+=FONT_WIDTH;
+      _s++;
+    } else if (*_s=='\t') {
+      y=y0+CeilU64(y-y0+FONT_HEIGHT,8*FONT_HEIGHT);
+      _s++;
+    } else if (*_s(U32 *)=='$SY,') {
+      if (_s[4]=='-') {
+        _s++;
+        sx='0'-_s[4];
+      } else
+        sx=_s[4]-'0';
+      _s+=6;
+    } else if (*_s(U32 *)=='$SX,') {
+      if (_s[4]=='-') {
+        _s++;
+        sy='0'-_s[4];
+      } else
+        sy=_s[4]-'0';
+      _s+=6;
+    } else {
+      *buf=*_s++;
+      res+=GrPutS(dc,x,y,buf);
+      y+=FONT_HEIGHT;
+    }
+  }
+  return res;
+}
+
+public I64 GrPrint(CDC *dc=gr.dc,I64 x,I64 y,U8 *fmt,...)
+{//2D. Clipping but not transformation.
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=GrPutS(dc,x,y,buf);
+  Free(buf);
+  return res;
+}
+
+public I64 GrVPrint(CDC *dc=gr.dc,I64 x,I64 y,U8 *fmt,...)
+{//2D. Vertical text. Clipping but not transformation.
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=GrVPutS(dc,x,y,buf);
+  Free(buf);
+  return res;
+}
+
+#help_index "Graphics"
+public I64 GrRect(CDC *dc=gr.dc,I64 x,I64 y,I64 w,I64 h)
+{//2D. Width Height. Clipping but not transformation.
+//Returns cnt of pixs changed.
+  I64 i,res=0,j,k1,kk1,w1,h1,w2,h2,dist,
+        leading_pixels,original_leading_pixels,whole_I64s,
+        trailing_pixels,leading_pixel_mask,trailing_pixel_mask,
+        win_z_buf_line_inc,win_z_buf_line_dec,win_z_num,color_mask;
+  U8 reg *dst;
+  U16 reg *win_z_buf_ptr;
+  CColorROPU32 color,c,dither_colors;
+  Bool dither,probability_dither;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+
+  if (x<0)
+    w1=-x;
+  else
+    w1=0;
+  if (y<0)
+    h1=-y;
+  else
+    h1=0;
+  w2=w;
+  h2=h;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x+=win_task->pix_left;
+    y+=win_task->pix_top;
+  }
+  if (dc->flags & DCF_LOCATE_NEAREST) {//TODO:Untested
+    if (x<=dc->cur_x<=x+w && y<=dc->cur_y<=y+h)
+      dist=0;
+    else
+      dist=DistSqrI64(x+w>>1,y+h>>1,dc->cur_x,dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    if (x+w1<0) w1=-x;
+    if (x+w2>win_task->pix_right+1)
+      w2=win_task->pix_right+1-x;
+
+    if (y+h1<0) h1=-y;
+    if (y+h2>win_task->pix_bottom+1)
+      h2=win_task->pix_bottom+1-y;
+  }
+  if (x+w2>dc->width)
+    w2=dc->width-x;
+  if (y+h2>dc->height)
+    h2=dc->height-y;
+  if (w1<w2<=w && h1<h2<=h) {
+    if (dc->flags & DCF_RECORD_EXTENTS) {
+      if (x+w1  <dc->min_x) dc->min_x=x+w1;
+      if (x+w2-1>dc->max_x) dc->max_x=x+w2-1;
+      if (y+h1  <dc->min_y) dc->min_y=y+h1;
+      if (y+h2-1>dc->max_y) dc->max_y=y+h2-1;
+    }
+    if (dc->flags & DCF_DONT_DRAW)
+      return TRUE;
+    color=dc->color;
+    if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+      dither=TRUE;
+      if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+        probability_dither=TRUE;
+        color.c1.rop=color.c0.rop;
+        dither_colors=color;
+      } else {
+        probability_dither=FALSE;
+        color.c1.rop=color.c0.rop;
+      }
+    } else
+      dither=FALSE;
+    original_leading_pixels=leading_pixels=-(w1+x)&7;
+    leading_pixel_mask=gr.to_8_bits[0xFF>>leading_pixels];
+    whole_I64s=(w2-w1-leading_pixels)>>3;
+    if (whole_I64s<0) whole_I64s=0;
+    trailing_pixels=(x+w2)&7;
+    trailing_pixel_mask=gr.to_8_bits[0xFF<<trailing_pixels&0xFF];
+    if (leading_pixels+trailing_pixels>w2-w1) {
+      leading_pixel_mask|=trailing_pixel_mask;
+      leading_pixels=w2-w1; //Correct so it's right for res.
+      trailing_pixels=0;
+    }
+    if (color.c0.rop==ROPB_COLLISION) {//TODO: Might want to check win_z_buf
+      color =dc->bkcolor.c0.color;
+      k1=(h1+y)*dc->width_internal+x;
+      res=-dc->collision_cnt;
+      for (j=h2-h1;j;j--) {
+        for (i=w1;i<w2;i++) {
+          c=dc->body[k1+i];
+          if (c!=TRANSPARENT && c!=color)
+            dc->collision_cnt++;
+        }
+        k1+=dc->width_internal;
+      }
+      res+=dc->collision_cnt;
+    } else {
+      if (!(dc->flags & DCF_SCRN_BITMAP) || dc->flags&DCF_ON_TOP)
+        win_z_buf_ptr=NULL;
+      else {
+        win_z_num=win_task->win_z_num;
+        win_z_buf_ptr=gr.win_z_buf(U8 *)+((h1+y)/FONT_HEIGHT*TEXT_COLS+
+              (w1+x)/FONT_WIDTH)*sizeof(U16);
+        win_z_buf_line_dec=whole_I64s;
+        if (leading_pixels)
+          win_z_buf_line_dec++;
+        if (trailing_pixels)
+          win_z_buf_line_dec++;
+        win_z_buf_line_dec*=sizeof(U16);
+        win_z_buf_line_inc=TEXT_COLS*sizeof(U16)-win_z_buf_line_dec;
+      }
+      kk1=(h1+y)*dc->width_internal+x+w1;
+      if (dither) {
+        if (probability_dither) {
+          if (RandU16<dc->dither_probability_u16)
+            color.c0=dither_colors.c1;
+          else
+            color.c0=dither_colors.c0;
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+            case ROPB_XOR:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            *dst(I64 *)^color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)^=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_colors[color.c0.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *dst(I64 *)^color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)^=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  if (RandU16<dc->dither_probability_u16)
+                    color.c0=dither_colors.c1;
+                  else
+                    color.c0=dither_colors.c0;
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+          }
+        } else {
+          if (((x+w1-original_leading_pixels)^(y+h1))&1)
+            SwapU16(&color.c0,&color.c1);
+          switch [color.c0.rop] {
+            case ROPB_EQU:
+            case ROPB_MONO:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+            case ROPB_XOR:
+              if (win_z_buf_ptr) {
+                res=0;
+                for (j=h1;j<h2;j++) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels) {
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                            *dst(I64 *)^color_mask&~leading_pixel_mask;
+                      res+=leading_pixels;
+                    }
+                    dst(I64 *)++;
+                  }
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    if (win_z_num>=*win_z_buf_ptr++) {
+                      *dst(I64 *)^=color_mask;
+                      res+=8;
+                    }
+                  if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                    res+=trailing_pixels;
+                  }
+                  if ((j+y)&7==7)
+                    win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                  else
+                    win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+              } else {
+                for (j=h2-h1;j;j--) {
+                  color_mask=gr.to_8_bits[0x55]&gr.to_8_colors[color.c0.color]|
+                        gr.to_8_bits[0xAA]&gr.to_8_colors[color.c1.color];
+                  dst=dc->body+kk1&~7;
+                  if (leading_pixels)
+                    *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                          *dst(I64 *)^color_mask&~leading_pixel_mask;
+                  for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                    *dst(I64 *)^=color_mask;
+                  if (trailing_pixels)
+                    *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                          *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                  kk1+=dc->width_internal;
+                  SwapU16(&color.c0,&color.c1);
+                }
+                res=(h2-h1)*(w2-w1);
+              }
+              break;
+          }
+        }
+      } else {
+        color_mask=gr.to_8_colors[color.c0.color];
+        switch [color.c0.rop] {
+          case ROPB_EQU:
+          case ROPB_MONO:
+            if (win_z_buf_ptr) {
+              res=0;
+              for (j=h1;j<h2;j++) {
+                dst=dc->body+kk1&~7;
+                if (leading_pixels) {
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                          color_mask&~leading_pixel_mask;
+                    res+=leading_pixels;
+                  }
+                  dst(I64 *)++;
+                }
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=color_mask;
+                    res+=8;
+                  }
+                if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        color_mask&~trailing_pixel_mask;
+                  res+=trailing_pixels;
+                }
+                if ((j+y)&7==7)
+                  win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                else
+                  win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                kk1+=dc->width_internal;
+              }
+            } else {
+              for (j=h2-h1;j;j--) {
+                dst(I64 *)=dc->body+kk1&~7;
+                if (leading_pixels)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        color_mask&~leading_pixel_mask;
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  *dst(I64 *)=color_mask;
+                if (trailing_pixels)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        color_mask&~trailing_pixel_mask;
+                kk1+=dc->width_internal;
+              }
+              res=(h2-h1)*(w2-w1);
+            }
+            break;
+          case ROPB_XOR:
+            if (win_z_buf_ptr) {
+              res=0;
+              for (j=h1;j<h2;j++) {
+                dst=dc->body+kk1&~7;
+                if (leading_pixels) {
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)=*dst(I64 *)&leading_pixel_mask|
+                          *dst(I64 *)^color_mask&~leading_pixel_mask;
+                    res+=leading_pixels;
+                  }
+                  dst(I64 *)++;
+                }
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  if (win_z_num>=*win_z_buf_ptr++) {
+                    *dst(I64 *)^=color_mask;
+                    res+=8;
+                  }
+                if (trailing_pixels && win_z_num>=*win_z_buf_ptr++) {
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                  res+=trailing_pixels;
+                }
+                if ((j+y)&7==7)
+                  win_z_buf_ptr(U8 *)+=win_z_buf_line_inc;
+                else
+                  win_z_buf_ptr(U8 *)-=win_z_buf_line_dec;
+                kk1+=dc->width_internal;
+              }
+            } else {
+              for (j=h2-h1;j;j--) {
+                dst=dc->body+kk1&~7;
+                if (leading_pixels)
+                  *dst(I64 *)++=*dst(I64 *)&leading_pixel_mask|
+                        *dst(I64 *)^color_mask&~leading_pixel_mask;
+                for (i=0;i<whole_I64s;i++,dst(I64 *)++)
+                  *dst(I64 *)^=color_mask;
+                if (trailing_pixels)
+                  *dst(I64 *)=*dst(I64 *)&trailing_pixel_mask|
+                        *dst(I64 *)^color_mask&~trailing_pixel_mask;
+                kk1+=dc->width_internal;
+              }
+              res=(h2-h1)*(w2-w1);
+            }
+            break;
+        }
+      }
+    }
+  }
+  return res;
+}
+
+I64 GrRayLenMinus(CDC *dc,I64 x,I64 y)
+{
+//Returns cnt of pixs changed
+  I64 res=0,c,x3,y3,d;
+  U8 *dst,*dst2;
+  Bool not_color=ToBool(dc->flags&DCF_FILL_NOT_COLOR);
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+  }
+  x3=x;
+  y3=y;
+  if (x3<0 || y3<0)
+    goto gr_done;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x3+=win_task->pix_left;
+    y3+=win_task->pix_top;
+    if (!(0<=x3<=win_task->pix_right) || !(0<=y3<=win_task->pix_bottom) ||
+          !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+      goto gr_done;
+  }
+  if (x3>=dc->width || y3>=dc->height)
+    goto gr_done;
+
+  d=y3*dc->width_internal;
+  dst2=dc->body+d;
+  while (TRUE) {
+    x3=x;
+    if (x3&(FONT_WIDTH-1)==FONT_WIDTH-1) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        if (x3<0) break;
+        x3+=win_task->pix_left;
+        if (!(0<=x3<=win_task->pix_right) || x3>=dc->width ||
+              !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+          break;
+      } else
+        if (!(0<=x3<dc->width))
+          break;
+    } else if (dc->flags & DCF_SCRN_BITMAP)
+      x3+=win_task->pix_left;
+    dst=dst2+x3;
+    c=*dst;
+    if (not_color) {
+      if (c!=dc->color2) {
+        res++;
+        x--;
+      } else
+        break;
+    } else {
+      if (c==dc->color2) {
+        res++;
+        x--;
+      } else
+        break;
+    }
+  }
+  return res;
+gr_done:
+  return 0;
+}
+
+I64 GrRayLen(CDC *dc,I64 *x1,I64 y,I64 z=0,I32 *db=NULL)
+{
+//Returns cnt of pixs changed
+  I64 res=0,d,x=*x1,x2,x3,y3,dist;
+  Bool plot,dither,probability_dither,
+        not_color=ToBool(dc->flags&DCF_FILL_NOT_COLOR);
+  U8 *dst,*dst2;
+  CColorROPU32 c,c2,color=dc->color,bkcolor=dc->bkcolor;
+  I32 *db2;
+  CTask *win_task;
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->scroll_x;
+    y+=win_task->scroll_y;
+    z+=win_task->scroll_z;
+  }
+  x2=x;
+  x3=x;
+  y3=y;
+  if (x3<0 || y3<0)
+    goto gr_done;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x3+=win_task->pix_left;
+    y3+=win_task->pix_top;
+    if (!(0<=x3<=win_task->pix_right) || !(0<=y3<=win_task->pix_bottom) ||
+          !(dc->flags&DCF_ON_TOP) &&  IsPixCovered0(win_task,x3,y3))
+      goto gr_done;
+  }
+  if (x3>=dc->width || y3>=dc->height)
+    goto gr_done;
+
+  d=dc->width_internal*y3;
+  if (db) db+=d;
+
+  color=dc->color;
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    dither=TRUE;
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      probability_dither=TRUE;
+      color.c1.rop=color.c0.rop;
+    } else {
+      probability_dither=FALSE;
+      color.c1.rop=color.c0.rop;
+    }
+  } else
+    dither=FALSE;
+  dst2=dc->body+d;
+  while (TRUE) {
+    x3=x;
+    if (!(x3&(FONT_WIDTH-1))) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        if (x3<0) break;
+        x3+=win_task->pix_left;
+        if (!(0<=x3<=win_task->pix_right) || x3>=dc->width ||
+              !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+          break;
+      } else {
+        if (!(0<=x3<dc->width))
+          break;
+      }
+    } else if (dc->flags & DCF_SCRN_BITMAP)
+      x3+=win_task->pix_left;
+
+    dst=dst2+x3;
+
+    c=*dst;
+    if (db) {
+      db2=db+x3;
+      if (0<=z<=*db2) {
+        *db2=z;
+        plot=TRUE;
+      } else
+        plot=FALSE;
+    } else
+      plot=TRUE;
+
+    if ((not_color && c!=dc->color2 ||
+          !not_color && c==dc->color2) && plot) {
+      if (dc->flags & DCF_LOCATE_NEAREST) {
+        dist=DistSqrI64(x3,y3,dc->cur_x,dc->cur_y);
+        if (dist<=dc->nearest_dist)
+          dc->nearest_dist=dist;
+      }
+      if (dc->flags & DCF_RECORD_EXTENTS) {
+        if (x3<dc->min_x) dc->min_x=x3;
+        if (x3>dc->max_x) dc->max_x=x3;
+        if (y3<dc->min_y) dc->min_y=y3;
+        if (y3>dc->max_y) dc->max_y=y3;
+      }
+      dst=dst2+x3;
+
+      c=color.c0.color;
+      if (dither) {
+        if (probability_dither) {
+          if (RandU16<dc->dither_probability_u16)
+            c=color.c1.color;
+        } else
+          if ((x3^y3)&1)
+            c=color.c1.color;
+      }
+      switch [color.c0.rop] {
+        case ROPB_EQU:
+        case ROPB_MONO:
+          *dst=c;
+          break;
+        case ROPB_COLLISION:
+          c2=*dst;
+          if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+            dc->collision_cnt++;
+          break;
+        case ROPB_XOR:
+          *dst^=c;
+          break;
+      }
+      res++;
+      x++;
+    } else
+      break;
+  }
+  if (dc->flags & DCF_SCRN_BITMAP)
+    *x1=x-1-win_task->scroll_x;
+  else
+    *x1=x-1;
+  x=x2-1;
+  while (TRUE) {
+    x3=x;
+    if (x3&(FONT_WIDTH-1)==FONT_WIDTH-1) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        if (x3<0) break;
+        x3+=win_task->pix_left;
+        if (!(0<=x3<=win_task->pix_right) || x3>=dc->width ||
+              !(dc->flags&DCF_ON_TOP) && IsPixCovered0(win_task,x3,y3))
+          break;
+      } else
+        if (!(0<=x3<dc->width))
+          break;
+    } else if (dc->flags & DCF_SCRN_BITMAP)
+      x3+=win_task->pix_left;
+
+    dst=dst2+x3;
+    c=*dst;
+    if (db) {
+      db2=db+x3;
+      if (0<=z<=*db2) {
+        *db2=z;
+        plot=TRUE;
+      } else
+        plot=FALSE;
+    } else
+      plot=TRUE;
+
+    if ((not_color && c!=dc->color2 ||
+          !not_color && c==dc->color2) && plot) {
+      if (dc->flags & DCF_LOCATE_NEAREST) {
+        dist=DistSqrI64(x3,y3,dc->cur_x,dc->cur_y);
+        if (dist<=dc->nearest_dist)
+          dc->nearest_dist=dist;
+      }
+      if (dc->flags & DCF_RECORD_EXTENTS) {
+        if (x3<dc->min_x) dc->min_x=x3;
+        if (x3>dc->max_x) dc->max_x=x3;
+        if (y3<dc->min_y) dc->min_y=y3;
+        if (y3>dc->max_y) dc->max_y=y3;
+      }
+      dst=dst2+x3;
+
+      c=color.c0.color;
+      if (dither) {
+        if (probability_dither) {
+          if (RandU16<dc->dither_probability_u16)
+            c=color.c1.color;
+        } else
+          if ((x3^y3)&1)
+            c=color.c1.color;
+      }
+      switch [color.c0.rop] {
+        case ROPB_EQU:
+        case ROPB_MONO:
+          *dst=c;
+          break;
+        case ROPB_COLLISION:
+          c2=*dst;
+          if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+            dc->collision_cnt++;
+          break;
+        case ROPB_XOR:
+          *dst^=c;
+          break;
+      }
+      res++;
+      x--;
+    } else
+      break;
+  }
+  return res;
+gr_done:
+  return 0;
+}
+
+public I64 GrHLine(CDC *dc=gr.dc,I64 x1,I64 x2,I64 y,I64 z1=0,I64 z2=0)
+{//3D. No transformation or thick.
+//Returns cnt of pixs changed
+  //Uses fixed-point.
+  I64 dist,dx,dz,z,res=0,i,j,d;
+  U8 *dst;
+  CColorROPU32 c,c2,color=dc->color,bkcolor=dc->bkcolor,dither_colors;
+  I32 *db;
+  Bool plot=TRUE,char_clear,dither,probability_dither;
+  CTask *win_task;
+
+  if (!dc->depth_buf) {
+    if (x2<x1) SwapI64(&x1,&x2);
+    return GrRect(dc,x1,y,x2-x1+1,1);
+  }
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x1+=win_task->scroll_x;
+    x2+=win_task->scroll_x;
+    y +=win_task->scroll_y;
+    z1+=win_task->scroll_z;
+    z2+=win_task->scroll_z;
+  }
+  if (dc->flags & DCF_RECORD_EXTENTS) {
+    if (x1<dc->min_x) dc->min_x=x1;
+    if (x1>dc->max_x) dc->max_x=x1;
+    if (x2<dc->min_x) dc->min_x=x2;
+    if (x2>dc->max_x) dc->max_x=x2;
+    if (y<dc->min_y) dc->min_y=y;
+    if (y>dc->max_y) dc->max_y=y;
+  }
+  if (y<0) goto gr_done;
+  if (x2<x1) {
+    SwapI64(&x1,&x2);
+    SwapI64(&z1,&z2);
+  }
+  if (x2<0)
+    goto gr_done;
+  if (x1<0) {
+    i=-x1;
+    x1=0;
+  } else
+    i=0;
+  j=0;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    x1+=win_task->pix_left;
+    x2+=win_task->pix_left;
+    if (x1>win_task->pix_right)
+      goto gr_done;
+    if (x2>win_task->pix_right) {
+      j=x2-win_task->pix_right;
+      x2=win_task->pix_right;
+    }
+    y+=win_task->pix_top;
+    if (!(0<=y<=win_task->pix_bottom) || x2<0)
+      goto gr_done;
+  }
+  if (x1>=dc->width || y>=dc->height)
+    goto gr_done;
+  dx=x2+j-(x1-i);
+  d=dc->width_internal*y+x1;
+  if (db=dc->depth_buf) {
+    db+=d;
+    if (dx)
+      dz=(z2-z1)<<32/dx;
+    else
+      dz=0;
+    z=z1<<32;
+  }
+  if (i)
+    z+=i*dz;
+  if (x2>=dc->width)
+    x2=dc->width-1;
+
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    if (x1<=dc->cur_x<=x2)
+      dist=0;
+    else if (dc->cur_x<x1)
+      dist=SqrI64(x1-dc->cur_x);
+    else
+      dist=SqrI64(dc->cur_x-x2);
+    dist+=SqrI64(y-dc->cur_y);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_DONT_DRAW)
+    goto gr_done;
+
+  if (!(dc->flags & DCF_SCRN_BITMAP) ||
+        win_task->next_task==sys_winmgr_task ||
+        dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x1,y))
+    char_clear=TRUE;
+  else
+    char_clear=FALSE;
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    dither=TRUE;
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      probability_dither=TRUE;
+      color.c1.rop=color.c0.rop;
+      dither_colors=color;
+      if (RandU16<dc->dither_probability_u16)
+        color.c0=dither_colors.c1;
+      else
+        color.c0=dither_colors.c0;
+    } else {
+      probability_dither=FALSE;
+      color.c1.rop=color.c0.rop;
+      if ((x1^y)&1)
+        SwapU16(&color.c0,&color.c1);
+    }
+  } else
+    dither=FALSE;
+  while (x1<=x2) {
+    if (char_clear) {
+      if (db) {
+        if (0<=z.i32[1]<=*db) {
+          *db=z.i32[1];
+          plot=TRUE;
+        } else
+          plot=FALSE;
+      }
+      if (plot) {
+        dst=dc->body+d;
+        c=color.c0.color;
+        switch [color.c0.rop] {
+          case ROPB_EQU:
+          case ROPB_MONO:
+            *dst=c;
+            break;
+          case ROPB_COLLISION:
+            c2=*dst;
+            if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+              dc->collision_cnt++;
+            break;
+          case ROPB_XOR:
+            *dst^=c;
+            break;
+        }
+        res++;
+      }
+    }
+    if (dither) {
+      if (probability_dither) {
+        if (RandU16<dc->dither_probability_u16)
+          color.c0=dither_colors.c1;
+        else
+          color.c0=dither_colors.c0;
+      } else
+        SwapU16(&color.c0,&color.c1);
+    }
+    d++;
+    x1++;
+    if (db)
+      db++;
+    z+=dz;
+    if (!(x1&(FONT_WIDTH-1)) && x1<=x2) {
+      if (!(dc->flags & DCF_SCRN_BITMAP)||
+            win_task->next_task==sys_winmgr_task ||
+            dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x1,y))
+        char_clear=TRUE;
+      else
+        char_clear=FALSE;
+    }
+  }
+gr_done:
+  return res;
+}
+
+public I64 GrVLine(CDC *dc=gr.dc,I64 x,I64 y1,I64 y2,I64 z1=0,I64 z2=0)
+{//3D. No transformation or thick.
+//Returns cnt of pixs changed
+  //Uses fixed-point.
+  I64 dist,dy,dz,z,res=0,i,j,d;
+  U8 *dst;
+  CColorROPU32 c,c2,color=dc->color,bkcolor=dc->bkcolor,dither_colors;
+  I32 *db;
+  Bool plot=TRUE,char_clear,dither,probability_dither;
+  CTask *win_task;
+
+  if (!dc->depth_buf) {
+    if (y2<y1) SwapI64(&y1,&y2);
+    return GrRect(dc,x,y1,1,y2-y1+1);
+  }
+
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x +=win_task->scroll_x;
+    y1+=win_task->scroll_y;
+    y2+=win_task->scroll_y;
+    z1+=win_task->scroll_z;
+    z2+=win_task->scroll_z;
+  }
+  if (dc->flags & DCF_RECORD_EXTENTS) {
+    if (x<dc->min_x) dc->min_x=x;
+    if (x>dc->max_x) dc->max_x=x;
+    if (y1<dc->min_y) dc->min_y=y1;
+    if (y1>dc->max_y) dc->max_y=y1;
+    if (y2<dc->min_y) dc->min_y=y2;
+    if (y2>dc->max_y) dc->max_y=y2;
+  }
+  if (x<0) goto gr_done;
+  if (y2<y1) {
+    SwapI64(&y1,&y2);
+    SwapI64(&z1,&z2);
+  }
+  if (y2<0)
+    goto gr_done;
+  if (y1<0) {
+    i=-y1;
+    y1=0;
+  } else
+    i=0;
+  j=0;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    y1+=win_task->pix_top;
+    y2+=win_task->pix_top;
+    if (y1>win_task->pix_bottom)
+      goto gr_done;
+    if (y2>win_task->pix_bottom) {
+      j=y2-win_task->pix_bottom;
+      y2=win_task->pix_bottom;
+    }
+    x+=win_task->pix_left;
+    if (!(0<=x<=win_task->pix_right) || y2<0)
+      goto gr_done;
+  }
+  if (y1>=dc->height || x>=dc->width)
+    goto gr_done;
+  dy=y2+j-(y1-i);
+  d=dc->width_internal*y1+x;
+  if (db=dc->depth_buf) {
+    db+=d;
+    if (dy)
+      dz=(z2-z1)<<32/dy;
+    else
+      dz=0;
+    z=z1<<32;
+  }
+  if (i)
+    z+=i*dz;
+  if (y2>=dc->height)
+    y2=dc->height-1;
+
+  if (dc->flags & DCF_LOCATE_NEAREST) {
+    if (y1<=dc->cur_y<=y2)
+      dist=0;
+    else if (dc->cur_y<y1)
+      dist=SqrI64(y1-dc->cur_y);
+    else
+      dist=SqrI64(dc->cur_y-y2);
+    dist+=SqrI64(x-dc->cur_x);
+    if (dist<=dc->nearest_dist)
+      dc->nearest_dist=dist;
+  }
+  if (dc->flags & DCF_DONT_DRAW)
+    goto gr_done;
+
+  if (!(dc->flags & DCF_SCRN_BITMAP) ||
+        win_task->next_task==sys_winmgr_task ||
+        dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x,y1))
+    char_clear=TRUE;
+  else
+    char_clear=FALSE;
+  if (color.c1.rop&(ROPBF_DITHER|ROPBF_PROBABILITY_DITHER)) {
+    dither=TRUE;
+    if (color.c1.rop&ROPBF_PROBABILITY_DITHER) {
+      probability_dither=TRUE;
+      color.c1.rop=color.c0.rop;
+      dither_colors=color;
+      if (RandU16<dc->dither_probability_u16)
+        color.c0=dither_colors.c1;
+      else
+        color.c0=dither_colors.c0;
+    } else {
+      probability_dither=FALSE;
+      color.c1.rop=color.c0.rop;
+      if ((x^y1)&1)
+        SwapU16(&color.c0,&color.c1);
+    }
+  } else
+    dither=FALSE;
+  while (y1<=y2) {
+    if (char_clear) {
+      if (db) {
+        if (0<=z.i32[1]<=*db) {
+          *db=z.i32[1];
+          plot=TRUE;
+        } else
+          plot=FALSE;
+      }
+      if (plot) {
+        dst=dc->body+d;
+        c=color.c0.color;
+        switch [color.c0.rop] {
+          case ROPB_EQU:
+          case ROPB_MONO:
+            *dst=c;
+            break;
+          case ROPB_COLLISION:
+            c2=*dst;
+            if (c2!=TRANSPARENT && c2!=bkcolor.c0.color)
+              dc->collision_cnt++;
+            break;
+          case ROPB_XOR:
+            *dst^=c;
+            break;
+        }
+        res++;
+      }
+    }
+    if (dither) {
+      if (probability_dither) {
+        if (RandU16<dc->dither_probability_u16)
+          color.c0=dither_colors.c1;
+        else
+          color.c0=dither_colors.c0;
+      } else
+        SwapU16(&color.c0,&color.c1);
+    }
+    d+=dc->width_internal;
+    y1++;
+    if (db)
+      db+=dc->width_internal;
+    z+=dz;
+    if (!(y1&(FONT_HEIGHT-1)) && y1<=y2) {
+      if (!(dc->flags & DCF_SCRN_BITMAP)||
+            win_task->next_task==sys_winmgr_task ||
+            dc->flags&DCF_ON_TOP || !IsPixCovered0(win_task,x,y1))
+        char_clear=TRUE;
+      else
+        char_clear=FALSE;
+    }
+  }
+gr_done:
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrComposites.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrComposites.HC.HTML new file mode 100755 index 0000000..1e53d5b --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrComposites.HC.HTML @@ -0,0 +1,375 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+public I64 GrFillPoly3(CDC *dc=gr.dc,I64 n,CD3I32 *poly)
+{//3D. Must be convex.
+//Returns cnt of pixs changed
+  CD3I32 tri[3];
+  I64 i,j,x,y,z,res=0;
+  if (n<3) return 0;
+  if (dc->flags & DCF_SYMMETRY) {
+    for (i=1;i<n-1;i++) {
+      j=i-1;
+      if (i==1) {
+        x=poly[j].x; y=poly[j].y; z=poly[j].z;
+        if (dc->flags&DCF_TRANSFORMATION)
+          (*dc->transform)(dc,&x,&y,&z);
+        DCReflect(dc,&x,&y,&z);
+        tri[0].x=x; tri[0].y=y; tri[0].z=z;
+      }
+
+      j++;
+      if (i==1) {
+        x=poly[j].x; y=poly[j].y; z=poly[j].z;
+        if (dc->flags&DCF_TRANSFORMATION)
+          (*dc->transform)(dc,&x,&y,&z);
+        DCReflect(dc,&x,&y,&z);
+      }
+      tri[1].x=x; tri[1].y=y; tri[1].z=z;
+
+      j++;
+      x=poly[j].x; y=poly[j].y; z=poly[j].z;
+      if (dc->flags&DCF_TRANSFORMATION)
+        (*dc->transform)(dc,&x,&y,&z);
+      DCReflect(dc,&x,&y,&z);
+      tri[2].x=x; tri[2].y=y; tri[2].z=z;
+
+      res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
+    }
+  }
+  if (dc->flags&DCF_JUST_MIRROR)
+    return res;
+  for (i=1;i<n-1;i++) {
+    j=i-1;
+    if (i==1) {
+      x=poly[j].x; y=poly[j].y; z=poly[j].z;
+      if (dc->flags&DCF_TRANSFORMATION)
+        (*dc->transform)(dc,&x,&y,&z);
+      tri[0].x=x; tri[0].y=y; tri[0].z=z;
+    }
+
+    j++;
+    if (i==1) {
+      x=poly[j].x; y=poly[j].y; z=poly[j].z;
+      if (dc->flags&DCF_TRANSFORMATION)
+        (*dc->transform)(dc,&x,&y,&z);
+    }
+    tri[1].x=x; tri[1].y=y; tri[1].z=z;
+
+    j++;
+    x=poly[j].x; y=poly[j].y; z=poly[j].z;
+    if (dc->flags&DCF_TRANSFORMATION)
+      (*dc->transform)(dc,&x,&y,&z);
+    tri[2].x=x; tri[2].y=y; tri[2].z=z;
+
+    res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
+  }
+  return res;
+}
+
+public I64 GrRectB(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
+{//2D. Two point. Clipping but not transformation.
+  if (x2<x1) SwapI64(&x1,&x2);
+  if (y2<y1) SwapI64(&y1,&y2);
+  return GrRect(dc,x1,y1,x2-x1+1,y2-y1+1);
+}
+
+public I64 GrRect3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,I64 w,I64 h)
+{//3D. Width Height. Clipping and transformation.
+  CD3I32 poly[4];
+  poly[0].x=x;
+  poly[0].y=y;
+  poly[0].z=z;
+  poly[1].x=x+w;
+  poly[1].y=y;
+  poly[1].z=z;
+  poly[2].x=x+w;
+  poly[2].y=y+h;
+  poly[2].z=z;
+  poly[3].x=x;
+  poly[3].y=y+h;
+  poly[3].z=z;
+  return GrFillPoly3(dc,4,poly);
+}
+
+public U0 GrBorder(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
+        I64 step=1,I64 start=0)
+{//2D. Transformation with thick.
+//Can be used with ROPF_DITHER+WHITE<<16+BLACK for dotted rect.
+  GrLine3(dc,x1,y1,0,x2,y1,0,step,start);
+  GrLine3(dc,x2,y1,0,x2,y2,0,step,start);
+  GrLine3(dc,x2,y2,0,x1,y2,0,step,start);
+  GrLine3(dc,x1,y2,0,x1,y1,0,step,start);
+}
+
+public Bool GrArrow3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
+        I64 x2,I64 y2,I64 z2,F64 w=2.75,I64 step=1,I64 start=0)
+{//3D. Transformation with thick.
+  I64 _x1,_y1,_z1,_x2,_y2,_z2,dx,dy;
+  F64 d;
+  Bool res=FALSE,was_transform=FALSE,was_symmetry=FALSE;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    (*dc->transform)(dc,&x2,&y2,&z2);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x1=x1; _y1=y1; _z1=z1;
+    DCReflect(dc,&_x1,&_y1,&_z1);
+    _x2=x2; _y2=y2; _z2=z2;
+    DCReflect(dc,&_x2,&_y2,&_z2);
+    dc->flags&=~DCF_SYMMETRY;
+    res=Line(dc,_x1,_y1,_z1,_x2,_y2,_z2,&GrPlot3,step,start);
+    dx=_x2-_x1; dy=_y2-_y1;
+    if (d=Sqrt(dx*dx+dy*dy)) {
+      d=w*dc->thick/d;
+      res|=Line(dc,_x2-dx*d+dy*d+0.5,_y2-dy*d-dx*d+0.5,_z2,
+            _x2,_y2,_z2,&GrPlot3,step);
+      res|=Line(dc,_x2-dx*d-dy*d+0.5,_y2-dy*d+dx*d+0.5,_z2,
+            _x2,_y2,_z2,&GrPlot3,step);
+    }
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  res|=Line(dc,x1,y1,z1,x2,y2,z2,&GrPlot3,step,start);
+  dx=x2-x1; dy=y2-y1;
+  if (d=Sqrt(dx*dx+dy*dy)) {
+    d=w*dc->thick/d;
+    res|=Line(dc,x2-dx*d+dy*d+0.5,y2-dy*d-dx*d+0.5,z2,
+          x2,y2,z2,&GrPlot3,step);
+    res|=Line(dc,x2-dx*d-dy*d+0.5,y2-dy*d+dx*d+0.5,z2,
+          x2,y2,z2,&GrPlot3,step);
+  }
+gr_done:
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return res;
+}
+
+#help_index "Graphics/Char;Char/Graphics"
+public Bool GrTextBox3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,U8 *s,I64 border=2)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  U8 *ptr;
+  I64 ch,res,w,w_max,h;
+  if (!s) return FALSE;
+  ptr=s;
+  w=0;  w_max=0; h=FONT_HEIGHT;
+
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x1,&y1,&z1);
+  while (ch=*ptr++) {
+    if (ch=='\t')
+      w=CeilU64(w+FONT_WIDTH,FONT_WIDTH*8);
+    else if (ch=='\n') {
+      if (w>w_max) w_max=w;
+      w=0;
+      h+=FONT_HEIGHT;
+    } else
+      w+=FONT_WIDTH;
+  }
+  if (w>w_max) w_max=w;
+  res=GrPrint(dc,x1,y1,"%s",s);
+  res|=GrLine(dc,x1-border         ,y1-border  ,x1+w_max+border,y1-border);
+  res|=GrLine(dc,x1-border         ,y1+h+border,x1+w_max+border,y1+h+border);
+  res|=GrLine(dc,x1-border         ,y1-border  ,x1-border,y1+h+border);
+  res|=GrLine(dc,x1+w_max+border,y1-border  ,x1+w_max+border,y1+h+border);
+  return ToBool(res);
+}
+
+#define DIAMOND_SLOPE_MAX       2.75
+
+public Bool GrTextDiamond3(CDC *dc=gr.dc,
+        I64 x1,I64 y1,I64 z1,U8 *_s,I64 border=2)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  Bool first=TRUE;
+  U8 ch,*ptr,*ptr_end,*st,*s;
+  I64 res=0,y,dx,dy,dx_old,dy_old,w,h=FONT_HEIGHT;
+  F64 m;
+  if (!_s) return FALSE;
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x1,&y1,&z1);
+
+  ptr=s=StrNew(_s);
+  while (ch=*ptr) {
+    if (ch=='\r'||ch=='\t')
+      *ptr=CH_SPACE;
+    if (ch=='\n') {
+      *ptr=0;
+      h+=FONT_HEIGHT;
+    }
+    ptr++;
+  }
+  ptr_end=ptr+1;
+
+  y=y1-h>>1;
+  dx=FONT_WIDTH +border;      //Minimum
+  dy=FONT_HEIGHT+border+h>>1; //Minimum
+  ptr=s;
+  while (ptr!=ptr_end) {
+    st=ptr;
+    while (*ptr++);
+    StrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
+
+    w=(StrLen(st)*FONT_WIDTH)>>1;
+    if (first) {
+      res|=GrPrint(dc,x1-w,y,"%s",st);
+      first=FALSE;
+    } else
+      res|=GrPrint(dc,x1-w,y,"%s",st);
+    if (w) {
+      w+=border;
+      do {
+        dx_old=dx; dy_old=dy;
+        m=ToF64(dx)/dy;
+        if (m<1/DIAMOND_SLOPE_MAX) {
+          dy=MaxI64(dy,Ceil(DIAMOND_SLOPE_MAX*dx));
+          m=1/DIAMOND_SLOPE_MAX;
+        } else if (m>DIAMOND_SLOPE_MAX) {
+          dy=MaxI64(dy,Ceil(dx/DIAMOND_SLOPE_MAX));
+          m=DIAMOND_SLOPE_MAX;
+        }
+        dx=MaxI64(dx,w+Ceil(m*AbsI64(y-y1)));
+        dx=MaxI64(dx,w+Ceil(m*AbsI64(y+FONT_HEIGHT-y1)));
+      } while (dx!=dx_old || dy!=dy_old);
+    }
+    y+=FONT_HEIGHT;
+  }
+  Free(s);
+
+  res|=GrLine(dc,x1,y1-dy,x1+dx,y1);
+  res|=GrLine(dc,x1+dx,y1,x1,y1+dy);
+  res|=GrLine(dc,x1,y1+dy,x1-dx,y1);
+  res|=GrLine(dc,x1-dx,y1,x1,y1-dy);
+  return ToBool(res);
+}
+
+#help_index "Graphics/Mesh"
+public I64 Gr3Mesh(CDC *dc=gr.dc,I64 vertex_cnt,CD3I32 *p,
+        I64 tri_cnt,CMeshTri *tri)
+{//Returns cnt of pixs changed.
+  CColorROPU32 old_color=dc->color;
+  I64 i,x,y,z,res=0;
+  CD3I32 *pt,*pt_sym,*p_sym,*dst;
+  CMeshTri *tri_sym=tri;
+  if (dc->flags&DCF_TRANSFORMATION) {
+    dst=pt=MAlloc(sizeof(CD3I32)*vertex_cnt);
+    for (i=0;i<vertex_cnt;i++,p++,dst++) {
+      x=p->x; y=p->y; z=p->z;
+      (*dc->transform)(dc,&x,&y,&z);
+      dst->x=x; dst->y=y; dst->z=z;
+    }
+    p=pt;
+  } else
+    pt=NULL;
+
+  if (dc->flags & DCF_SYMMETRY) {
+    dst=pt_sym=MAlloc(sizeof(CD3I32)*vertex_cnt);
+    p_sym=p;
+    for (i=0;i<vertex_cnt;i++,p_sym++,dst++) {
+      x=p_sym->x; y=p_sym->y; z=p_sym->z;
+      DCReflect(dc,&x,&y,&z);
+      dst->x=x; dst->y=y; dst->z=z;
+    }
+    p_sym=pt_sym;
+    for (i=0;i<tri_cnt;i++,tri_sym++) {
+      (*dc->lighting)(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
+            &p_sym[tri_sym->nums[1]],tri_sym->color);
+      res+=GrFillTri0(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
+            &p_sym[tri_sym->nums[1]]);
+    }
+    Free(pt_sym);
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto mesh_done;
+  }
+  for (i=0;i<tri_cnt;i++,tri++) {
+    (*dc->lighting)(dc,&p[tri->nums[0]],&p[tri->nums[1]],
+          &p[tri->nums[2]],tri->color);
+    res+=GrFillTri0(dc,&p[tri->nums[0]],&p[tri->nums[1]],&p[tri->nums[2]]);
+  }
+mesh_done:
+  dc->color=old_color;
+  Free(pt);
+  return res;
+}
+
+#help_index "Graphics/Misc;Mouse/Ptr"
+public U0 DrawStdMs(CDC *dc,I64 x,I64 y)
+{//This is a callback. See ::/Demo/Graphics/Grid.HC.
+//Called by DrawMs() which is
+  //called by WinFinalUpdate().
+  dc->thick=1;
+  dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
+  GrArrow3(dc,x+8,y+8,0,x,y,0);
+}
+
+gr.fp_draw_ms=&DrawStdMs;
+
+public U0 DrawWaitMs(CDC *dc,I64 x,I64 y)
+{//This is a callback. See ::/Demo/Graphics/Grid.HC.
+  I64 old_pen_width=dc->thick;
+  CColorROPU32 old_color=dc->color;
+  dc->thick=3;
+  dc->color=LTRED;
+  GrCircle3(dc,x,y,0,7);
+  GrLine3(dc,x-6,y+6,0,x+6,y-6,0);
+  dc->color=RED;
+  GrCircle(dc,x,y,7);
+  GrLine(dc,x-6,y+6,x+6,y-6);
+  dc->thick=old_pen_width;
+  dc->color=old_color;
+}
+
+#help_index "Graphics/GR Files;Graphics/Scrn"
+public Bool GRScrnCaptureRead(U8 *filename,CDC *dc=gr.dc,I64 x=0,I64 y=0)
+{//GrBlot TempleOS GR File to dc,x,y.
+  CDC *dc2;
+  if (dc2=GRRead(filename)) {
+    dc->color=ROP_EQU;
+    GrBlot(dc,x,y,dc2);
+    DCDel(dc2);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+public I64 GRScrnCaptureWrite(U8 *filename,Bool include_zoom=TRUE)
+{//Capture scrn to a TempleOS GR File.
+  I64 size;
+  CDC *dc=DCScrnCapture(include_zoom);
+  size=GRWrite(filename,dc,DCSF_COMPRESSED|DCSF_PALETTE_GET);
+  DCDel(dc);
+  return size;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrDC.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrDC.HC.HTML new file mode 100755 index 0000000..12edb5e --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrDC.HC.HTML @@ -0,0 +1,465 @@ + + + + + + + + + + + +
+#help_index "Graphics/Math/3D Transformation"
+#help_file "::/Doc/Transform"
+
+#define GR_SCALE        (1<<32)
+
+public U0 Mat4x4MulXYZ(I64 *r,I64 *_x,I64 *_y,I64 *_z)
+{//Rotate 3D point using 4x4 matrix. Uses fixed-point.
+  I64 x1,y1,z1,xx=*_x,yy=*_y,zz=*_z;
+  x1=(r[0*4+0]*xx+r[0*4+1]*yy+r[0*4+2]*zz+r[0*4+3])>>32;
+  y1=(r[1*4+0]*xx+r[1*4+1]*yy+r[1*4+2]*zz+r[1*4+3])>>32;
+  z1=(r[2*4+0]*xx+r[2*4+1]*yy+r[2*4+2]*zz+r[2*4+3])>>32;
+  *_x=x1;*_y=y1;*_z=z1;
+}
+
+public U0 DCTransform(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
+{//This is the dft dc->transform() callback.
+//Uses fixed-point.
+  Mat4x4MulXYZ(dc->r,_x,_y,_z);
+  *_x+=dc->x;
+  *_y+=dc->y;
+  *_z+=dc->z;
+}
+
+public I64 *Mat4x4IdentEqu(I64 *r)
+{//Set matrix to identity. Uses fixed-point.
+  MemSet(r,0,sizeof(I64)*16);
+  r[0*4+0].i32[1]=1;
+  r[1*4+1].i32[1]=1;
+  r[2*4+2].i32[1]=1;
+  r[3*4+3].i32[1]=1;
+  return r;
+}
+
+public I64 *Mat4x4IdentNew(CTask *mem_task=NULL)
+{//MAlloc an identity matrix. Uses fixed-point.
+  return Mat4x4IdentEqu(MAlloc(sizeof(I64)*16,mem_task));
+}
+
+public I64 Mat4x4NormSqr65536(I64 *r)
+{//Norm Squared of r.
+//(1.0/Sqrt(3))*65536=37837.22
+  return SqrI64((r[0*4+0]*37838+r[0*4+1]*37838+r[0*4+2]*37838)>>32)+
+        SqrI64((r[1*4+0]*37837+r[1*4+1]*37837+r[1*4+2]*37837)>>32)+
+        SqrI64((r[2*4+0]*37837+r[2*4+1]*37837+r[2*4+2]*37837)>>32);
+}
+
+public U0 DCMat4x4Set(CDC *dc=NULL,I64 *r)
+{//Set device context's rot matrix. Will be Freed() in DCDel().Uses fixed-point.
+//The main purpose is to set matrix norm for thick scaling.
+  //NULL as dc means gr.dc
+  if (!dc)   dc=gr.dc;
+  dc->r=r;
+  dc->r_norm=Sqrt(Mat4x4NormSqr65536(r))*65536; //scaled 32 bits
+}
+
+#help_index "Graphics/Mesh"
+public U0 DCLighting(CDC *dc,
+        CD3I32 *p1,CD3I32 *p2,CD3I32 *p3,CColorROPU32 color)
+{//This is the dft dc->lighting() callback.
+  CD3I32 v1,v2;
+  I64 i,vn_x,vn_y,vn_z;
+  F64 d;
+
+  v1.x=p1->x-p2->x;
+  v1.y=p1->y-p2->y;
+  v1.z=p1->z-p2->z;
+
+  v2.x=p3->x-p2->x;
+  v2.y=p3->y-p2->y;
+  v2.z=p3->z-p2->z;
+
+  //V1 and V2 are vects along two sides
+  //of the tri joined at p2.
+
+  vn_x=v1.y*v2.z-v1.z*v2.y;
+  vn_y=v1.z*v2.x-v1.x*v2.z;
+  vn_z=v1.x*v2.y-v1.y*v2.x;
+  if (d=Sqrt(SqrI64(vn_x)+SqrI64(vn_y)+SqrI64(vn_z)))
+    d=1<<16/d;
+  vn_x*=d;
+  vn_y*=d;
+  vn_z*=d;
+//Vn is the cross product of V1 and V3
+  //which means it is perpendicular.  It
+  //is the normal vect to the surface.
+  //It has been scaled to length 65536.
+
+  //Light source has been scaled to length 65536.
+  i=(vn_x*dc->ls.x+vn_y*dc->ls.y+vn_z*dc->ls.z)>>16;
+//The dot product of the light source
+  //vect and the surface normal
+  //gives an illumination number.
+  //65536*65536>>16=65536
+
+  //TempleOS will generate a random U16
+  //and compare to dither_probability_u16 and
+  //will pick from two colors.
+  //Probability dithering does not work with thick>1 at this time.
+  if (color.c0.rop&ROPBF_TWO_SIDED) {
+    color.c0.rop&=~ROPBF_TWO_SIDED;
+    i=AbsI64(i)<<1;
+  } else
+    i+=65536;
+  if (color.c0.rop&ROPBF_HALF_RANGE_COLOR) {
+    color.c0.rop&=~ROPBF_HALF_RANGE_COLOR;
+    i>>=1;
+    if (color>=8) {
+      color-=8;
+      i+=65536;
+    }
+  }
+  if (i<65536) {
+    dc->color=ROPF_PROBABILITY_DITHER+color<<16+BLACK;
+    dc->dither_probability_u16=i;
+  } else {
+    dc->color=ROPF_PROBABILITY_DITHER+(color^8)<<16+color;
+    dc->dither_probability_u16=i-65536;
+  }
+}
+
+#help_index "Graphics/Device Contexts"
+public U0 DCFill(CDC *dc=NULL,CColorROPU32 val=TRANSPARENT)
+{//Fill entire device context with color.
+  if (!dc) dc=gr.dc;
+  MemSet(dc->body,val,dc->width_internal*dc->height);
+}
+
+public U0 DCClear(CDC *dc=NULL)
+{//Set entire device context image body to 0 (BLACK).
+  if (!dc) dc=gr.dc;
+  DCFill(dc,0);
+}
+
+public U0 DCRst(CDC *dc)
+{//Reset CDC structure members but not image body, itself.
+  dc->color=BLACK;
+  dc->color2=BLACK;
+  dc->bkcolor=BLACK;
+  dc->collision_cnt=0;
+  dc->thick=1;
+  dc->ls.x=37837; //1<<16/Sqrt(3)
+  dc->ls.y=37837;
+  dc->ls.z=37837;
+  dc->x=0;
+  dc->y=0;
+  dc->z=0;
+  dc->transform=&DCTransform;
+  dc->lighting =&DCLighting;
+  Mat4x4IdentEqu(dc->r);
+  dc->r_norm=GR_SCALE;
+  dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);
+  MemCpy(dc->palette,gr_palette_std,sizeof(CBGR48)*COLORS_NUM);
+}
+
+public U0 DCExtentsInit(CDC *dc=NULL)
+{//Init markers for extent of next newly drawn graphics.
+//NULL means gr.dc
+  //See ::/Demo/Graphics/Extents.HC
+  //You should clear the record flag yourself
+  if (!dc)   dc=gr.dc;
+  dc->flags|=DCF_RECORD_EXTENTS;
+  dc->min_x=I64_MAX;
+  dc->max_x=I64_MIN;
+  dc->min_y=I64_MAX;
+  dc->max_y=I64_MIN;
+}
+
+public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)
+{//Create alias of dc, so can change pen, color, etc.
+//NULL means gr.dc
+  CDC *res;
+  if (!dc)   dc=gr.dc;
+  if (!task) task=Fs;
+  if (dc->dc_signature!=DCS_SIGNATURE_VAL)
+    throw('Graphics');
+  res=MAlloc(sizeof(CDC),task);
+  MemCpy(res,dc,sizeof(CDC));
+  res->win_task=res->mem_task=task;
+  res->r=MAlloc(16*sizeof(I64),task);
+  DCRst(res);
+  res->flags|=DCF_ALIAS;
+  res->alias=dc;
+  return res;
+}
+
+public CDC *DCNew(I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)
+{//Create new width x height device context.
+//Internally only allows widths which are divisible by 8.
+  //Don't forget these sizeof(CDC).
+  CDC *res;
+  if (!task) task=Fs;
+  res=CAlloc(sizeof(CDC),task);
+  res->win_task=task;
+  res->mem_task=task;
+  res->width=width;
+  res->width_internal=(width+7)&~7;
+  res->height=height;
+  if (null_bitmap)
+    res->flags|=DCF_DONT_DRAW;
+  else
+    res->body=CAlloc(res->width_internal*res->height,task);
+  res->r=MAlloc(16*sizeof(I64),task);
+  DCRst(res);
+  res->dc_signature=DCS_SIGNATURE_VAL;
+  return res;
+}
+
+public U0 DCDel(CDC *dc)
+{//Free dc, image body, rot mat and depth buf.
+  if (!dc) return;
+  if (dc->dc_signature!=DCS_SIGNATURE_VAL)
+    throw('Graphics');
+  dc->dc_signature=0;
+  Free(dc->r);
+  if (!(dc->flags & DCF_ALIAS))
+    Free(dc->body);
+  Free(dc->depth_buf);
+  Free(dc);
+}
+
+public I64 DCSize(CDC *dc)
+{//Mem size of header, image body and depth buffer.
+  if (dc)
+    return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);
+  else
+    return 0;
+}
+
+public I32 *DCDepthBufRst(CDC *dc)
+{//Reset device context depth buf to far away.
+  if (dc->depth_buf)
+    MemSetU32(dc->depth_buf,I32_MAX,dc->width_internal*dc->height);
+  return dc->depth_buf;
+}
+
+public I32 *DCDepthBufAlloc(CDC *dc)
+{//Alloc a 32-bit depth buffer for device context.
+  Free(dc->depth_buf);
+  dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);
+  return DCDepthBufRst(dc);
+}
+
+public CDC *DCCopy(CDC *dc,CTask *task=NULL)
+{//Alloc copy of dc, including image body, rot mat and depth buf.
+  CDC *res;
+  if (!dc) return NULL;
+  if (dc->dc_signature!=DCS_SIGNATURE_VAL)
+    throw('Graphics');
+  res=MAllocIdent(dc,task);
+  DCMat4x4Set(res,Mat4x4New(dc->r,task));
+  res->mem_task=task;
+  res->body=MAllocIdent(dc->body,task);
+  res->depth_buf=MAllocIdent(dc->depth_buf,task);
+  return res;
+}
+
+public U0 DCMono(CDC *dc,
+  I64 quest=TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)
+{//Set entire device context to one of two colors.
+  I64 i;
+  U8 *dst;
+  dst=dc->body;
+  i=dc->width_internal*dc->height;
+  while (i--)
+    if (*dst==quest)
+      *dst++=true_color;
+    else
+      *dst++=false_color;
+}
+
+public I64 DCColorChg(CDC *dc,I64 src_color,I64 dst_color=TRANSPARENT)
+{//Find and replace src color with dst in device context.
+  I64 i,res=0;
+  U8 *dst;
+  dst=dc->body;
+  i=dc->width_internal*dc->height;
+  while (i--)
+    if (*dst==src_color) {
+      *dst++=dst_color;
+      res++;
+    } else
+      dst++;
+  return res;
+}
+
+public U8 *DCSave(CDC *dc,I64 *_size=NULL,I64 dcsf_flags=DCSF_COMPRESSED)
+{//Stores device context to mem, perhaps, with compression.
+  U8 *res,*ptr,*body;
+  CArcCompress *arc;
+  I64 body_size=dc->width_internal*dc->height,total_size,flags;
+  CBGR48 palette[COLORS_NUM];
+
+  if (dcsf_flags&DCSF_COMPRESSED) {
+    arc=CompressBuf(dc->body,body_size);
+    body_size=arc->compressed_size;
+    body=arc;
+  } else {
+    arc=NULL;
+    body=dc->body;
+  }
+
+  total_size=offset(CDC.end)-offset(CDC.start)+body_size;
+  if (dcsf_flags&DCSF_COMPRESSED)
+    flags=DCF_COMPRESSED;
+  else
+    flags=0;
+
+  if (dcsf_flags&DCSF_PALETTE_GET)
+    GrPaletteGet(palette);
+  else
+    MemCpy(palette,&dc->palette,COLORS_NUM*sizeof(CBGR48));
+  if (MemCmp(palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48))) {
+    flags|=DCF_PALETTE;
+    total_size+=COLORS_NUM*sizeof(CBGR48);
+  }
+
+  ptr=res=MAlloc(total_size);
+
+#assert !offset(CDC.start)
+  MemCpy(ptr,&dc->start,offset(CDC.end)-offset(CDC.start));
+  ptr(CDC *)->flags=flags;
+  ptr+=offset(CDC.end)-offset(CDC.start);
+
+#assert offset(CDC.end)==offset(CDC.palette)
+  if (flags&DCF_PALETTE) {
+    MemCpy(ptr,palette,COLORS_NUM*sizeof(CBGR48));
+    ptr+=COLORS_NUM*sizeof(CBGR48);
+  }
+
+  MemCpy(ptr,body,body_size);
+  ptr+=body_size;
+
+  Free(arc);
+  if (_size) *_size=total_size;
+  return res;
+}
+
+public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)
+{//Loads device context from mem.
+  CDC *res;
+  U8 *ptr=src;
+  CArcCompress *arc;
+  I64 body_size;
+  if (!task) task=Fs;
+  res=CAlloc(sizeof(CDC),task);
+  res->win_task=task;
+  res->mem_task=task;
+  MemCpy(&res->start,ptr,offset(CDC.end)-offset(CDC.start));
+  ptr+=offset(CDC.end)-offset(CDC.start);
+
+  if (res->flags&DCF_PALETTE) {
+    MemCpy(&res->palette,ptr,COLORS_NUM*sizeof(CBGR48));
+    ptr+=COLORS_NUM*sizeof(CBGR48);
+  } else
+    MemCpy(&res->palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48));
+
+  body_size=res->width_internal*res->height;
+  if (res->flags&DCF_COMPRESSED) {
+    res->flags&=~DCF_COMPRESSED;
+    arc=ptr;
+    res->body=ExpandBuf(arc,task);
+    ptr+=arc->compressed_size;
+  } else {
+    res->body=MAlloc(body_size,task);
+    MemCpy(res->body,ptr,body_size);
+    ptr+=body_size;
+  }
+  res->thick=1;
+  res->r=Mat4x4IdentNew(task);
+  res->r_norm.u32[1]=1;
+  res->dc_signature=DCS_SIGNATURE_VAL;
+  if (_size) *_size=ptr-src;
+  return res;
+}
+
+#help_index "Graphics/GR Files"
+#help_file "::/Doc/GRFiles"
+#help_index "Graphics/Device Contexts;Graphics/GR Files"
+
+#define GR_FILE_MAX     (offset(CDC.end)-offset(CDC.start)+\
+        COLORS_NUM*sizeof(CBGR48)+sizeof(CArcCtrl)+GR_WIDTH*GR_HEIGHT)
+
+public I64 GRWrite(U8 *filename,CDC *dc,I64 dcsf_flags=DCSF_COMPRESSED)
+{//TempleOS GR File.
+  I64   size;
+  U8    *st=ExtDft(filename,"GR.Z"),
+        *src=DCSave(dc,&size,dcsf_flags);
+  FileWrite(st,src,size);
+  Free(st);
+  Free(src);
+  return size;
+}
+
+public CDC *GRRead(U8 *filename,CTask *task=NULL)
+{//TempleOS GR File.
+  CDC   *dc=NULL;
+  U8    *st=ExtDft(filename,"GR.Z"),
+        *src=FileRead(st);
+  if (src)
+    dc=DCLoad(src,,task);
+  Free(src);
+  Free(st);
+  return dc;
+}
+
+#help_index "Graphics/Sprite;Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
+public U0 DocGR(CDoc *doc=NULL,U8 *filename)
+{//Put a GR file into a document as asprite.
+  CDC *dc=GRRead(filename);
+  CSprite *elems=DC2Sprite(dc);
+  DocSprite(doc,elems);
+  Free(elems);
+  DCDel(dc);
+}
+
+#help_index "Graphics/Device Contexts;Graphics/Scrn"
+public CDC *DCScrnCapture(Bool include_zoom=TRUE,CTask *task=NULL)
+{//Capture scrn to a device context.
+  CDC *dc;
+  U8 *dst;
+  Refresh(0,FALSE);
+  if (include_zoom)
+    dc=DCCopy(gr.scrn_image,task);
+  else
+    dc=DCCopy(gr.dc1,task);
+  dc->flags&=~DCF_SCRN_BITMAP;
+  dst=MAlloc(dc->width_internal*dc->height,task);
+//Pick background color that never occurs. COLOR_INVALID
+  GrBitMap4ToBitMap8(dst,dc->body,
+        (dc->width_internal*dc->height)>>1,COLOR_INVALID);
+  Free(dc->body);
+  dc->body=dst;
+  return dc;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrEnd.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrEnd.HC.HTML new file mode 100755 index 0000000..351ed8b --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrEnd.HC.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+#help_index "Graphics/Scrn"
+
+U0 CtrlAltZ(I64 sc)
+{
+  if (sc&SCF_SHIFT)
+    GrScaleZoom(0.5);
+  else
+    GrScaleZoom(2.0);
+}
+CtrlAltCBSet('Z',&CtrlAltZ,"Cmd /Zoom In",
+        "Cmd /Zoom Out");
+
+U0 Scrn2Clip(I64)
+{
+  CDC *dc=DCScrnCapture;
+  U8 *elems=DC2Sprite(dc);
+  Bool unlock_doc=DocLock(sys_clip_doc);
+  ClipDel;
+  DocSprite(sys_clip_doc,elems);
+  if (unlock_doc)
+    DocUnlock(sys_clip_doc);
+  Free(elems);
+  DCDel(dc);
+}
+U0 CtrlAltS(I64)
+{
+  Spawn(&Scrn2Clip);
+}
+CtrlAltCBSet('S',&CtrlAltS,"Cmd /Scrn Shot to Clip");
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrExt.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrExt.HC.HTML new file mode 100755 index 0000000..f6873f3 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrExt.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+extern U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor);
+extern I64 GrBlot3(CDC *dc,I64 x1,I64 y1,I64 z1,CDC *img);
+extern I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL);
+extern U8 *SpriteQue2Sprite(CSprite *head,I64 *_size=NULL);
+extern CSprite *SpriteSetSettings(CDC *dc=NULL,CSprite *head,I64 elem_num,
+        I64 x=0,I64 y=0,CColorROPU32 *_color=NULL,I64 *_thick=NULL,
+        I64 *_xx=NULL,I64 *_yy=NULL);
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrGlbls.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrGlbls.HC.HTML new file mode 100755 index 0000000..1128344 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrGlbls.HC.HTML @@ -0,0 +1,86 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+public class CGrGlbls
+{
+  I64   *to_8_bits,*to_8_colors;
+  CDC   *scrn_image,    //Read only.
+        *dc,            //Persistent
+        *dc1,
+        *dc2,           //Updated every refresh
+        *dc_cache,
+        *zoomed_dc;
+  U32   *text_base;     //See TextBase Layer. (Similar to 0xB8000 but 32 bits)
+  U16   *win_z_buf;
+
+  #define SPHT_ELEM_CODE        1
+  CHashTable *sprite_hash;
+
+  U16   *win_uncovered_bitmap;
+  I64   highest_uncovered;
+  U16   *vga_text_cache;
+  I64   pan_text_x,pan_text_y;  //[-7,7]
+  U0    (*fp_final_scrn_update)(CDC *dc);//Mouse cursor is handled here.
+  U0    (*fp_wall_paper)(CTask *task);
+  U0    (*fp_draw_ms)(CDC *dc,I64 x,I64 y);
+  U0    (*fp_draw_grab_ms)(CDC *dc,I64 x,I64 y,Bool closed);
+  U8    *empty_sprite; //Gets assigned gr.empty_sprite
+
+  #define GR_PEN_BRUSHES_NUM 64
+  CDC   *pen_brushes[GR_PEN_BRUSHES_NUM],
+        *collision_pen_brushes[GR_PEN_BRUSHES_NUM],
+        *even_pen_brushes[GR_PEN_BRUSHES_NUM],
+        *odd_pen_brushes[GR_PEN_BRUSHES_NUM];
+  I8    circle_lo[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM],
+        circle_hi[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM];
+
+  #define GR_SCRN_ZOOM_MAX      8
+  U8    *scrn_zoom_tables[GR_SCRN_ZOOM_MAX+1];
+  I64   scrn_zoom,sx,sy;
+
+  //When zoomed, this keeps the mouse centered.
+  Bool  continuous_scroll,
+        hide_row,hide_col;
+} gr;
+
+//See RLf_VGA
+//See SysGrInit()
+//Allows consts to be used instead of vars.
+HashPublic("GR_WIDTH",HTT_DEFINE_STR);;
+HashPublic("GR_HEIGHT",HTT_DEFINE_STR);;
+
+#help_index "Char;TextBase Layer/Char"
+DefinePrint("TEXT_ROWS","%d",text.rows);;;
+HashPublic("TEXT_ROWS",HTT_DEFINE_STR);;;
+DefinePrint("TEXT_COLS","%d",text.cols);;;
+HashPublic("TEXT_COLS",HTT_DEFINE_STR);;;
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrInitA.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrInitA.HC.HTML new file mode 100755 index 0000000..88c5c38 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrInitA.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+U0 GrInit1()
+{
+  DefineLstLoad("ST_SPRITE_ELEM_TYPES",
+        "End\0Color\0Dither Color\0"
+        "Thick\0Planar Symmetry\0Transform On\0Transform Off\0Shift\0"
+        "Point\0PolyPoint\0Line\0PolyLine\0Rect\0Rotated Rect\0"
+        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2 Closed\0"
+        "BSpline3\0BSpline3 Closed\0"
+        "Flood Fill\0Flood Fill Not Color\0BitMap\0Mesh\0Shiftable Mesh\0"
+        "Arrow\0Text\0Text Box\0Text Diamond\0");
+  DefineLstLoad("ST_SPRITE_ELEM_CODES",
+        "End\0Color\0Color\0"
+        "Thick\0PlanarSymmetry\0Transform\0Transform\0Shift\0"
+        "Pt\0PolyPt\0Line\0PolyLine\0Rect\0Rect\0"
+        "Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2\0BSpline3\0BSpline3\0"
+        "FloodFill\0FloodFill\0BitMap\0Mesh\0Mesh\0"
+        "Arrow\0Text\0TextBox\0TextDiamond\0");
+}
+GrInit1;
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrInitB.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrInitB.HC.HTML new file mode 100755 index 0000000..0bb9e8f --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrInitB.HC.HTML @@ -0,0 +1,240 @@ + + + + + + + + + + + +
+#help_index "Graphics/Scrn"
+
+U0 GrSetUpTables()
+{
+  CDC *dc;
+  I64 i,j,k,l,m,x,y,rr;
+  U8 *dst;
+
+  k=0;
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++)
+      if (Bt(&i,j))
+        gr.to_8_bits(U8 *)[k++]=0xFF;
+      else
+        gr.to_8_bits(U8 *)[k++]=0x00;
+  k=0;
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++)
+      gr.to_8_colors(U8 *)[k++]=i;
+
+  for (i=0;i<GR_PEN_BRUSHES_NUM;i++) {
+    k=i+1;
+
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr) {
+          if (x-1-i>>1<gr.circle_lo[i][i-y])
+            gr.circle_lo[i][i-y]=x-1-i>>1;
+          if (x-1-i>>1>gr.circle_hi[i][i-y])
+            gr.circle_hi[i][i-y]=x-1-i>>1;
+        }
+
+    dc=DCNew(i,i);
+    gr.pen_brushes[i]=dc;
+    dc->color=COLOR_MONO;
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+
+    dc=DCNew(i,i);
+    gr.collision_pen_brushes[i]=dc;
+    dc->color=COLOR_INVALID;//Want color that never occurs.
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+
+    dc=DCNew(i,i);
+    gr.even_pen_brushes[i]=dc;
+    dc->color=COLOR_MONO;
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (!(((x-1)^(y-1))&1) && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+
+    dc=DCNew(i,i);
+    gr.odd_pen_brushes[i]=dc;
+    dc->color=COLOR_MONO;
+    rr=k*k;
+    for (y=1;y<k;y++)
+      for (x=1;x<k;x++)
+        if (((x-1)^(y-1))&1 && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
+          GrPlot0(dc,x-1,y-1);
+  }
+  if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
+    MemSet(text.vga_text_alias,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
+    MemSet(gr.vga_text_cache,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
+  } else {
+    OutU8(VGAP_IDX,VGAR_MAP_MASK);
+    OutU8(VGAP_DATA,0x0F);
+//Virtual Box crashes on the following for some reason.
+    //    MemSet(text.vga_alias,0,GR_HEIGHT*GR_WIDTH>>3);
+    MemSet(gr.scrn_image->body,0,GR_WIDTH*GR_HEIGHT>>1);
+  }
+  for (i=1;i<=GR_SCRN_ZOOM_MAX;i++) {
+    dst=gr.scrn_zoom_tables[i]=MAlloc(256*i);
+    for (j=0;j<256;j++) {
+      m=0;
+      for (k=0;k<8;k++) {
+        if (Bt(&j,k)) {
+          for (l=0;l<i;l++)
+            Bts(&m,l+k*i);
+        }
+      }
+      for (l=0;l<i;l++)
+        dst[j+l*256]=m.u8[l];
+    }
+  }
+}
+
+#help_index "Graphics/Scrn;Windows"
+
+U0 WinZBufFill(CTask *task)
+{//Not public
+  I64 y,t,b,l,r,w;
+  if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
+    if (task->win_top-1>0)
+      t=task->win_top-1;
+    else
+      t=0;
+    if (task->win_bottom+1<TEXT_ROWS)
+      b=task->win_bottom+1;
+    else
+      b=TEXT_ROWS-1;
+    if (task->win_left-1>0)
+      l=task->win_left-1;
+    else
+      l=0;
+    if (task->win_right+1<TEXT_COLS)
+      r=task->win_right+1;
+    else
+      r=TEXT_COLS-1;
+  } else {
+    if (task->win_top>0)
+      t=task->win_top;
+    else
+      t=0;
+    if (task->win_bottom<TEXT_ROWS)
+      b=task->win_bottom;
+    else
+      b=TEXT_ROWS-1;
+    if (task->win_left>0)
+      l=task->win_left;
+    else
+      l=0;
+    if (task->win_right<TEXT_COLS)
+      r=task->win_right;
+    else
+      r=TEXT_COLS-1;
+  }
+  t=ClampI64(t,0,TEXT_ROWS-1);
+  b=ClampI64(b,t,TEXT_ROWS-1);
+  l=ClampI64(l,0,TEXT_COLS-1);
+  r=ClampI64(r,l,TEXT_COLS-1);
+  if (w=r-l+1)
+    for (y=t;y<=b;y++)
+      MemSetU16(gr.win_z_buf(U8 *)+(y*TEXT_COLS+l)*sizeof(U16),
+            task->win_z_num,w);
+}
+
+public U0 WinZBufUpdate()
+{//Might have to call if doing graphics outside winmgr callback routines.
+//Call it if, for example, when a pop-up window closes and you need to refresh
+  //before graphics.
+  I64 i,z=1;
+  U16 *ptr;
+  CTask *task,*task1;
+  if (gr.win_z_buf) {
+    LBtr(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);
+    task1=task=sys_winmgr_task;
+    do {
+      if (!TaskValidate(task)) break;
+      if (Bt(&task->display_flags,DISPLAYf_SHOW)) {
+        task->win_z_num=z++;
+        WinZBufFill(task);
+      }
+      task=task->next_task;
+    } while (task!=task1 && z<0x10000);
+
+    MemSet(gr.win_uncovered_bitmap,0,(gr.highest_uncovered+7)>>3+1);
+    gr.highest_uncovered=z-1;
+    for (ptr=gr.win_z_buf,i=TEXT_ROWS*TEXT_COLS;i;i--)
+      Bts(gr.win_uncovered_bitmap,*ptr++);
+  }
+}
+
+#help_index "Graphics"
+U0 GrInit2()
+{
+  MemSet(&gr,0,sizeof(CGrGlbls));
+  gr.sprite_hash=HashTableNew(512);
+  HashDefineLstAdd("ST_SPRITE_ELEM_CODES",SPHT_ELEM_CODE,gr.sprite_hash);
+  gr.scrn_zoom=1;
+
+  PaletteSetStd;
+  fp_set_std_palette=&PaletteSetStd;
+  GrPaletteIndicesSet;
+
+  gr.to_8_bits  =MAlloc(256*sizeof(I64));
+  gr.to_8_colors=MAlloc(256*sizeof(I64));
+
+  gr.text_base=CAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U32));
+  gr.vga_text_cache=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
+  gr.win_uncovered_bitmap=CAlloc(65536/8);
+  gr.highest_uncovered=0;
+  gr.win_z_buf=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
+
+  gr.dc2=DCNew(GR_WIDTH,GR_HEIGHT);
+  gr.dc2->flags|=DCF_SCRN_BITMAP;
+  gr.dc_cache=DCNew(GR_WIDTH,GR_HEIGHT);
+
+  gr.dc=DCNew(GR_WIDTH,GR_HEIGHT);
+  gr.dc->flags|=DCF_SCRN_BITMAP|DCF_ON_TOP;
+  DCFill;
+
+  gr.dc1=DCNew(GR_WIDTH,GR_HEIGHT);
+  gr.dc1->flags|=DCF_SCRN_BITMAP;
+
+  gr.scrn_image=DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
+  gr.zoomed_dc   =DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
+  gr.zoomed_dc->flags|=DCF_SCRN_BITMAP;
+}
+
+GrInit2;
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrMath.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrMath.HC.HTML new file mode 100755 index 0000000..b1df487 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrMath.HC.HTML @@ -0,0 +1,836 @@ + + + + + + + + + + + +
+#help_index "Graphics/Math"
+
+public I64 gr_x_offsets[8]={-1, 0, 1,-1,1,-1,0,1},
+           gr_y_offsets[8]={-1,-1,-1, 0,0, 1,1,1},
+          gr_x_offsets2[4]={ 0,-1, 1, 0},
+          gr_y_offsets2[4]={-1, 0, 0, 1};
+
+public Bool Line(U8 *aux_data,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),I64 step=1,I64 start=0)
+{//Step through line segment calling callback.
+//Uses fixed-point.
+  I64 i,j,d,dx=x2-x1,dy=y2-y1,dz=z2-z1,_x,_y,_z,
+        adx=AbsI64(dx),ady=AbsI64(dy),adz=AbsI64(dz);
+  Bool first=TRUE;
+  if (adx>=ady) {
+    if (adx>=adz) {
+      if (d=adx) {
+        if (dx>=0)
+          dx=0x100000000;
+        else
+          dx=-0x100000000;
+        dy=dy<<32/d;
+        dz=dz<<32/d;
+      }
+    } else {
+      if (d=adz) {
+        dx=dx<<32/d;
+        dy=dy<<32/d;
+        if (dz>=0)
+          dz=0x100000000;
+        else
+          dz=-0x100000000;
+      }
+    }
+  } else {
+    if (ady>=adz) {
+      if (d=ady) {
+        dx=dx<<32/d;
+        if (dy>=0)
+          dy=0x100000000;
+        else
+          dy=-0x100000000;
+        dz=dz<<32/d;
+      }
+    } else {
+      if (d=adz) {
+        dx=dx<<32/d;
+        dy=dy<<32/d;
+        if (dz>=0)
+          dz=0x100000000;
+        else
+          dz=-0x100000000;
+      }
+    }
+  }
+  x1<<=32; y1<<=32; z1<<=32;
+  for (j=0;j<start;j++) {
+    x1+=dx; y1+=dy; z1+=dz;
+  }
+  if (step!=1 && step!=0) {
+    dx*=step;
+    dy*=step;
+    dz*=step;
+    d/=step;
+  }
+  for (i=start;i<=d;i++) {
+    if ((_x!=x1.i32[1] || _y!=y1.i32[1] || _z!=z1.i32[1] || first) &&
+          !(*fp_plot)(aux_data,x1.i32[1],y1.i32[1],z1.i32[1]))
+      return FALSE;
+    first=FALSE;
+    _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+    x1+=dx; y1+=dy; z1+=dz;
+  }
+  if (step==1 && (_x!=x2||_y!=y2||_z!=z2) && !(*fp_plot)(aux_data,x2,y2,z2))
+    return FALSE;
+  return TRUE;
+}
+
+#help_index "Graphics/Math/3D Transformation"
+public I64 *Mat4x4MulMat4x4Equ(I64 *dst,I64 *m1,I64 *m2)
+{//Multiply 4x4 matrices and store in dst. Uses fixed-point.
+//Conceptually, the transform m1 is applied after m2
+  I64 i,j,k;
+  F64 sum;
+  for (i=0;i<4;i++) {
+    for (j=0;j<4;j++) {
+      sum=0;
+      for (k=0;k<4;k++)
+        sum+=ToF64(m1[k+4*j])*ToF64(m2[i+4*k]);
+      dst[i+4*j]=sum/GR_SCALE;
+    }
+  }
+  return dst;
+}
+
+public I64 *Mat4x4MulMat4x4New(I64 *m1,I64 *m2,CTask *mem_task=NULL)
+{//Multiply 4x4 matrices. Return MAlloced matrix. Uses fixed-point.
+//Conceptually, the transform m1 is applied after m2
+  return Mat4x4MulMat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),m1,m2);
+}
+
+public I64 *Mat4x4Equ(I64 *dst,I64 *src)
+{//Copy 4x4 Rot matrix.
+  MemCpy(dst,src,sizeof(I64)*16);
+  return dst;
+}
+
+public I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL)
+{//Return MAlloced copy of 4x4 Rot matrix.
+  return Mat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),src);
+}
+
+public I64 *Mat4x4RotX(I64 *m,F64 phi)
+{//Rot matrix about X axis. Uses fixed-point.
+  F64 my_cos=Cos(phi)*GR_SCALE,my_sin=Sin(phi)*GR_SCALE;
+  I64 r[16],r2[16];
+  MemSet(r,0,sizeof(r));
+  r[5]=my_cos;
+  r[10]=my_cos;
+  r[9]=my_sin;
+  r[6]=-my_sin;
+  r[0]=GR_SCALE;
+  r[15]=GR_SCALE;
+  return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
+}
+
+public I64 *Mat4x4RotY(I64 *m,F64 omega)
+{//Rot matrix about Y axis. Uses fixed-point.
+  F64 my_cos=Cos(omega)*GR_SCALE,my_sin=Sin(omega)*GR_SCALE;
+  I64 r[16],r2[16];
+  MemSet(r,0,sizeof(r));
+  r[0]=my_cos;
+  r[10]=my_cos;
+  r[8]=-my_sin;
+  r[2]=my_sin;
+  r[5]=GR_SCALE;
+  r[15]=GR_SCALE;
+  return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
+}
+
+public I64 *Mat4x4RotZ(I64 *m,F64 theta)
+{//Rot matrix about Z axis. Uses fixed-point.
+  F64 my_cos=Cos(theta)*GR_SCALE,my_sin=Sin(theta)*GR_SCALE;
+  I64 r[16],r2[16];
+  MemSet(r,0,sizeof(r));
+  r[0]=my_cos;
+  r[5]=my_cos;
+  r[4]=my_sin;
+  r[1]=-my_sin;
+  r[10]=GR_SCALE;
+  r[15]=GR_SCALE;
+  return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
+}
+
+public I64 *Mat4x4Scale(I64 *m,F64 s)
+{//Scale 4x4 matrix by value.
+  I64 i;
+  for (i=0;i<16;i++)
+    m[i]*=s;
+  return m;
+}
+
+public U0 DCThickScale(CDC *dc=gr.dc)
+{//Scale device context's thick by norm of transformation.
+  I64 d;
+  if (dc->flags&DCF_TRANSFORMATION) {
+    if (dc->thick) {
+      d=dc->thick*dc->r_norm+0x80000000; //Round
+      dc->thick=d.i32[1];
+      if (dc->thick<1)
+        dc->thick=1;
+    }
+  }
+}
+
+public I64 *Mat4x4TranslationEqu(I64 *r,I64 x,I64 y,I64 z)
+{//Set translation values in 4x4 matrix. Uses fixed-point.
+  r[0*4+3]=x<<32;
+  r[1*4+3]=y<<32;
+  r[2*4+3]=z<<32;
+  r[3*4+3]=GR_SCALE;
+  return r;
+}
+
+public I64 *Mat4x4TranslationAdd(I64 *r,I64 x,I64 y,I64 z)
+{//Add translation to 4x4 matrix. Uses fixed-point.
+  r[0*4+3]+=x<<32;
+  r[1*4+3]+=y<<32;
+  r[2*4+3]+=z<<32;
+  r[3*4+3]=GR_SCALE;
+  return r;
+}
+
+public Bool DCSymmetrySet(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
+{//2D. Set device context's symmetry.
+  F64 d;
+  if (y1==y2 && x1==x2)
+    return FALSE;
+  dc->sym.snx=y2-y1;
+  dc->sym.sny=x1-x2;
+  dc->sym.snz=0;
+  if (d=Sqrt(SqrI64(dc->sym.snx)+
+        SqrI64(dc->sym.sny)+
+        SqrI64(dc->sym.snz))) {
+    d=GR_SCALE/d;
+    dc->sym.snx *= d;
+    dc->sym.sny *= d;
+    dc->sym.snz *= d;
+  }
+  dc->sym.sx=x1;
+  dc->sym.sy=y1;
+  dc->sym.sz=0;
+  return TRUE;
+}
+
+public Bool DCSymmetry3Set(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
+        I64 x2,I64 y2,I64 z2,I64 x3,I64 y3,I64 z3)
+{//3D. Set device context's symmetry.
+  F64 d,x,y,z,xx,yy,zz;
+  I64 xx1,yy1,zz1,xx2,yy2,zz2,*r;
+  xx1=x1-x2; yy1=y1-y2; zz1=z1-z2;
+  xx2=x3-x2; yy2=y3-y2; zz2=z3-z2;
+  if (!xx1 && !yy1 && !zz1 ||
+        !xx2 && !yy2 && !zz2 ||
+        xx1==xx2 && yy1==yy2 && zz1==zz2)
+    return FALSE;
+
+  x=yy1*zz2-zz1*yy2;
+  y=-xx1*zz2+zz1*xx2;
+  z=xx1*yy2-yy1*xx2;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    r=dc->r;
+    xx=x*r[0]+y*r[1]+z*r[2];
+    yy=x*r[4]+y*r[5]+z*r[6];
+    zz=x*r[8]+y*r[9]+z*r[10];
+    x=xx; y=yy; z=zz;
+  }
+  if (d=Sqrt(Sqr(x)+Sqr(y)+Sqr(z))) {
+    d=GR_SCALE/d;
+    dc->sym.snx = d*x;
+    dc->sym.sny = d*y;
+    dc->sym.snz = d*z;
+  }
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x1,&y1,&z1);
+  dc->sym.sx=x1;
+  dc->sym.sy=y1;
+  dc->sym.sz=z1;
+  return TRUE;
+}
+
+public U0 DCReflect(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
+{//Reflect 3D point about device context's symmetry. Uses fixed-point.
+  I64 x=*_x<<32,y=*_y<<32,z=*_z<<32,
+        xx=*_x-dc->sym.sx,yy=*_y-dc->sym.sy,zz=*_z-dc->sym.sz,
+        d=(xx*dc->sym.snx+yy*dc->sym.sny+zz*dc->sym.snz)>>16,
+        xn,yn,zn,xx2,yy2,zz2;
+  xn=d*dc->sym.snx>>15;
+  yn=d*dc->sym.sny>>15;
+  zn=d*dc->sym.snz>>15;
+  xx=x-xn;
+  yy=y-yn;
+  zz=z-zn;
+  xx2=x+xn;
+  yy2=y+yn;
+  zz2=z+zn;
+  if (SqrI64(xx>>16 -dc->sym.sx<<16)+
+        SqrI64(yy>>16 -dc->sym.sy<<16)+
+        SqrI64(zz>>16 -dc->sym.sz<<16)<
+        SqrI64(xx2>>16-dc->sym.sx<<16)+
+        SqrI64(yy2>>16-dc->sym.sy<<16)+
+        SqrI64(zz2>>16-dc->sym.sz<<16)) {
+    *_x=xx.i32[1]; *_y=yy.i32[1]; *_z=zz.i32[1];
+  } else {
+    *_x=xx2.i32[1]; *_y=yy2.i32[1]; *_z=zz2.i32[1];
+  }
+}
+
+#help_index "Graphics/Math"
+#define GR_SCALE1_BITS  24
+#define GR_SCALE2_BITS  8
+public Bool Circle(U8 *aux_data,I64 cx,I64 cy,I64 cz,I64 radius,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
+        I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//Step through circle arc calling callback.
+  I64 i,j,len=Ceil(len_radians*radius),
+        x,y,x1,y1,s1,s2,c;
+  F64 t;
+  if (radius<=0||!step) return TRUE;
+  t=1.0/radius;
+  c=1<<GR_SCALE1_BITS*Cos(t);
+  if (step<0) {
+    step=-step;
+    s2=1<<GR_SCALE1_BITS*Sin(t);
+    s1=-s2;
+  } else {
+    s1=1<<GR_SCALE1_BITS*Sin(t);
+    s2=-s1;
+  }
+  if (start_radians) {
+    x=radius*Cos(start_radians);
+    y=-radius*Sin(start_radians);
+  } else {
+    x=radius;
+    y=0;
+  }
+  x<<=GR_SCALE2_BITS;
+  y<<=GR_SCALE2_BITS;
+  for (i=0;i<=len;i+=step) {
+    if (!(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
+      return FALSE;
+    for (j=0;j<step;j++) {
+      x1=(c*x+s1*y)>>GR_SCALE1_BITS;
+      y1=(s2*x+c*y)>>GR_SCALE1_BITS;
+      x=x1; y=y1;
+    }
+  }
+  return TRUE;
+}
+
+public Bool Ellipse(U8 *aux_data,I64 cx,I64 cy,I64 cz,
+        I64 x_radius,I64 y_radius,Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
+        F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//Step through ellipse arc calling callback.
+  I64 i,j,len,
+        x,y,_x,_y,x1,y1,x2,y2, s1,s2,c, s12,s22,c2;
+  F64 t;
+  Bool first=TRUE;
+  if (x_radius<=0 || y_radius<=0 || !step)
+    return TRUE;
+  if (x_radius>=y_radius) {
+    t=1.0/x_radius;
+    len=Ceil(len_radians*x_radius);
+  } else {
+    t=1.0/y_radius;
+    len=Ceil(len_radians*y_radius);
+  }
+
+  c=1<<GR_SCALE1_BITS*Cos(t);
+  if (step<0) {
+    step=-step;
+    s2=1<<GR_SCALE1_BITS*Sin(t);
+    s1=-s2;
+  } else {
+    s1=1<<GR_SCALE1_BITS*Sin(t);
+    s2=-s1;
+  }
+
+  c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
+  s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
+  s22=-s12;
+
+  if (start_radians) {
+    x=x_radius*Cos(start_radians);
+    y=-x_radius*Sin(start_radians);
+  } else {
+    x=x_radius;
+    y=0;
+  }
+  x<<=GR_SCALE2_BITS;
+  y<<=GR_SCALE2_BITS;
+  x2=x;
+  y2=y;
+
+  y1=y2*y_radius/x_radius;
+  x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
+  y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
+
+  for (i=0;i<=len;i+=step) {
+    if ((x>>GR_SCALE2_BITS!=_x || y>>GR_SCALE2_BITS!=_y || first) &&
+          !(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
+      return FALSE;
+
+    _x=x>>GR_SCALE2_BITS; _y=y>>GR_SCALE2_BITS; first=FALSE;
+    for (j=0;j<step;j++) {
+      x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
+      y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
+      x2=x1;
+      y2=y1;
+      y1=y1*y_radius/x_radius;
+      x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
+      y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
+    }
+  }
+  return TRUE;
+}
+
+public Bool RegPoly(U8 *aux_data,I64 cx,I64 cy,I64 cz,
+        I64 x_radius,I64 y_radius,I64 sides,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
+        F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//Step through regular polygon calling callback.
+  I64 i,n,x,y,x1,y1,x2,y2,
+        xx1,yy1,xx2,yy2,
+        s1,s2,c, s12,s22,c2;
+  F64 angle_step;
+
+  if (sides<=0 || x_radius<=0 || y_radius<=0)
+    return TRUE;
+
+  angle_step=2*pi/sides;
+  n=len_radians*sides/(2*pi);
+
+  s1=1<<GR_SCALE1_BITS*Sin(angle_step);
+  s2=-s1;
+  c=1<<GR_SCALE1_BITS*Cos(angle_step);
+
+  s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
+  s22=-s12;
+  c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
+
+  if (start_radians) {
+    x=x_radius*Cos(start_radians);
+    y=-x_radius*Sin(start_radians);
+  } else {
+    x=x_radius;
+    y=0;
+  }
+  x<<=GR_SCALE2_BITS;
+  y<<=GR_SCALE2_BITS;
+  x2=x;
+  y2=y;
+
+  y1=y2*y_radius/x_radius;
+  x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
+  y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
+
+  xx1=cx+x>>GR_SCALE2_BITS;
+  yy1=cy+y>>GR_SCALE2_BITS;
+  for (i=0;i<n;i++) {
+    x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
+    y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
+    x2=x1;
+    y2=y1;
+    y1=y1*y_radius/x_radius;
+    x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
+    y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
+    xx2=cx+x>>GR_SCALE2_BITS;
+    yy2=cy+y>>GR_SCALE2_BITS;
+    if (!Line(aux_data,xx1,yy1,cz,xx2,yy2,cz,fp_plot,step))
+      return FALSE;
+    xx1=xx2; yy1=yy2;
+  }
+  return TRUE;
+}
+
+#help_index "Graphics/Data Types/D3I32;Math/Data Types/D3I32;Data Types/D3I32"
+public F64 D3I32Dist(CD3I32 *p1,CD3I32 *p2)
+{//Distance
+  return Sqrt(SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z));
+}
+
+public I64 D3I32DistSqr(CD3I32 *p1,CD3I32 *p2)
+{//Distance Squared
+  return SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z);
+}
+
+public F64 D3I32Norm(CD3I32 *p)
+{//Norm
+  return Sqrt(SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z));
+}
+
+public I64 D3I32NormSqr(CD3I32 *p)
+{//Norm Squared
+  return SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z);
+}
+
+#help_index "Graphics/Math"
+public Bool Bezier2(U8 *aux_data,CD3I32 *ctrl,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
+{//Go in 2nd order bezier calling callback.
+  I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
+  F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
+        x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
+        x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
+        t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
+        D3I32Dist(&ctrl[1],&ctrl[2])+
+        D3I32Dist(&ctrl[2],&ctrl[0]),
+        s=0.5/d,t1,t2;
+  xx=x0; yy=y0; zz=z0;
+  if (first && !(*fp_plot)(aux_data,xx,yy,zz))
+    return FALSE;
+  for (t=0.0;t<=1.0;t+=s) {
+    t1=t*(1.0-t);
+    t2=t*t;
+    x=x0+x1*t1+x2*t2;
+    y=y0+y1*t1+y2*t2;
+    z=z0+z1*t1+z2*t2;
+    dx=AbsI64(x-xx);
+    dy=AbsI64(y-yy);
+    dz=AbsI64(z-zz);
+    if (dx>dy)
+      d_max=dx;
+    else
+      d_max=dy;
+    if (dz>d_max)
+      d_max=dz;
+    if (!d_max)
+      s*=1.1;
+    else {
+      s*=0.9;
+      if (!(*fp_plot)(aux_data,x,y,z))
+        return FALSE;
+      xx=x;yy=y;zz=z;
+    }
+  }
+  x=ctrl[2].x; y=ctrl[2].y; z=ctrl[2].z;
+  if ((xx!=x || yy!=y || zz!=z) &&
+        !(*fp_plot)(aux_data,x,y,z))
+    return FALSE;
+  return TRUE;
+}
+
+public Bool Bezier3(U8 *aux_data,CD3I32 *ctrl,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
+{//Go in 3rd order bezier calling callback.
+  I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
+  F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
+        x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
+        x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
+        x3=ctrl[3].x-x0,y3=ctrl[3].y-y0,z3=ctrl[3].z-z0,
+        t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
+        D3I32Dist(&ctrl[1],&ctrl[2])+
+        D3I32Dist(&ctrl[2],&ctrl[3])+
+        D3I32Dist(&ctrl[3],&ctrl[0]),
+        s=0.5/d,nt,t1,t2,t3;
+  xx=x0; yy=y0; zz=z0;
+  if (first && !(*fp_plot)(aux_data,xx,yy,zz))
+    return FALSE;
+  for (t=0.0;t<=1.0;t+=s) {
+    nt=1.0-t;
+    t1=t*nt*nt;
+    t2=t*t*nt;
+    t3=t*t*t;
+    x=x0+x1*t1+x2*t2+x3*t3;
+    y=y0+y1*t1+y2*t2+y3*t3;
+    z=z0+z1*t1+z2*t2+z3*t3;
+    dx=AbsI64(x-xx);
+    dy=AbsI64(y-yy);
+    dz=AbsI64(z-zz);
+    if (dx>dy)
+      d_max=dx;
+    else
+      d_max=dy;
+    if (dz>d_max)
+      d_max=dz;
+    if (!d_max)
+      s*=1.1;
+    else {
+      s*=0.9;
+      if (!(*fp_plot)(aux_data,x,y,z))
+        return FALSE;
+      xx=x;yy=y;zz=z;
+    }
+  }
+  x=ctrl[3].x; y=ctrl[3].y; z=ctrl[3].z;
+  if ((xx!=x || yy!=y || zz!=z) &&
+        !(*fp_plot)(aux_data,x,y,z))
+    return FALSE;
+  return TRUE;
+}
+
+public Bool BSpline2(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
+{//Go in 2nd order spline calling callback.
+  I64 i,j;
+  CD3I32 *c;
+  Bool first;
+  if (cnt<3) return FALSE;
+  first=TRUE;
+  if (closed) {
+    cnt++;
+    c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
+    j=1;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
+      c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
+      c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
+      j+=2;
+    }
+    c[j].x=(ctrl[0].x+ctrl[cnt-2].x)/2.0;
+    c[j].y=(ctrl[0].y+ctrl[cnt-2].y)/2.0;
+    c[j].z=(ctrl[0].z+ctrl[cnt-2].z)/2.0;
+
+    c[0].x=(c[1].x+c[j].x)/2.0;
+    c[0].y=(c[1].y+c[j].y)/2.0;
+    c[0].z=(c[1].z+c[j].z)/2.0;
+    j=2;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=2;
+    }
+    c[j].x=c[0].x;
+    c[j].y=c[0].y;
+    c[j].z=c[0].z;
+  } else {
+    c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
+    c[0].x=ctrl[0].x;
+    c[0].y=ctrl[0].y;
+    c[0].z=ctrl[0].z;
+    c[cnt*2-2].x=ctrl[cnt-1].x;
+    c[cnt*2-2].y=ctrl[cnt-1].y;
+    c[cnt*2-2].z=ctrl[cnt-1].z;
+    j=1;
+    for (i=0;i<cnt-1;i++) {
+      c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
+      c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
+      c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
+      j+=2;
+    }
+    j=2;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=2;
+    }
+  }
+  for (i=0;i<cnt*2-2;i+=2) {
+    if (!Bezier2(aux_data,&c[i],fp_plot,first))
+      return FALSE;
+    first=FALSE;
+  }
+  Free(c);
+  return TRUE;
+}
+
+public Bool BSpline3(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
+        Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
+{//Go in 3rd order spline calling callback.
+  I64 i,j;
+  F64 x,y,z;
+  CD3I32 *c;
+  Bool first;
+  if (cnt<3) return FALSE;
+  first=TRUE;
+  if (closed) {
+    cnt++;
+    c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
+    j=1;
+    for (i=0;i<cnt-2;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      c[j].x=(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=(ctrl[i+1].z-z)/3.0+z;
+      j++;
+      c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
+      j+=2;
+    }
+    x=ctrl[cnt-2].x;
+    y=ctrl[cnt-2].y;
+    z=ctrl[cnt-2].z;
+    c[j].x=(ctrl[0].x-x)/3.0+x;
+    c[j].y=(ctrl[0].y-y)/3.0+y;
+    c[j].z=(ctrl[0].z-z)/3.0+z;
+    j++;
+    c[j].x=2.0*(ctrl[0].x-x)/3.0+x;
+    c[j].y=2.0*(ctrl[0].y-y)/3.0+y;
+    c[j].z=2.0*(ctrl[0].z-z)/3.0+z;
+
+    c[0].x=(c[1].x+c[j].x)/2.0;
+    c[0].y=(c[1].y+c[j].y)/2.0;
+    c[0].z=(c[1].z+c[j].z)/2.0;
+
+    j=3;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=3;
+    }
+    c[j].x=c[0].x;
+    c[j].y=c[0].y;
+    c[j].z=c[0].z;
+  } else {
+    c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
+    c[0].x=ctrl[0].x;
+    c[0].y=ctrl[0].y;
+    c[0].z=ctrl[0].z;
+    c[cnt*3-3].x=ctrl[cnt-1].x;
+    c[cnt*3-3].y=ctrl[cnt-1].y;
+    c[cnt*3-3].z=ctrl[cnt-1].z;
+    j=1;
+    for (i=0;i<cnt-1;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      c[j].x=(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=(ctrl[i+1].z-z)/3.0+z;
+      j++;
+      c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
+      c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
+      c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
+      j+=2;
+    }
+    j=3;
+    for (i=0;i<cnt-2;i++) {
+      c[j].x=(c[j-1].x+c[j+1].x)/2.0;
+      c[j].y=(c[j-1].y+c[j+1].y)/2.0;
+      c[j].z=(c[j-1].z+c[j+1].z)/2.0;
+      j+=3;
+    }
+  }
+  for (i=0;i<cnt*3-3;i+=3) {
+    if (!Bezier3(aux_data,&c[i],fp_plot,first))
+      return FALSE;
+    first=FALSE;
+  }
+  Free(c);
+  return TRUE;
+}
+
+#define CC_LEFT         1
+#define CC_RIGHT        2
+#define CC_TOP          4
+#define CC_BOTTOM       8
+
+public Bool ClipLine(I64 *_x1,I64 *_y1,I64 *_x2,I64 *_y2,
+        I64 left,I64 top,I64 right,I64 bottom)
+{//Clip x1,y1 x2,y2 with left,top,right,bottom.
+  I64 x,y,x1=*_x1,y1=*_y1,x2=*_x2,y2=*_y2,
+        cc,cc1,cc2;
+  if (y1>bottom)
+    cc1=CC_BOTTOM;
+  else if (y1<top)
+    cc1=CC_TOP;
+  else
+    cc1=0;
+  if (x1>right)
+    cc1|=CC_RIGHT;
+  else if (x1<left)
+    cc1|=CC_LEFT;
+
+  if (y2>bottom)
+    cc2=CC_BOTTOM;
+  else if (y2<top)
+    cc2=CC_TOP;
+  else
+    cc2=0;
+  if (x2>right)
+    cc2|=CC_RIGHT;
+  else if (x2<left)
+    cc2|=CC_LEFT;
+
+  while (TRUE) {
+    if (!(cc1|cc2))
+      return TRUE;
+    if (cc1&cc2)
+      return FALSE;
+
+    if (cc1)
+      cc=cc1;
+    else
+      cc=cc2;
+
+    if (cc&CC_BOTTOM) {
+      x=x1+(x2-x1)*(bottom-y1)/(y2-y1);
+      y=bottom;
+    } else if (cc&CC_TOP) {
+      x=x1+(x2-x1)*(top-y1)/(y2-y1);
+      y=top;
+    } else if (cc&CC_RIGHT) {
+      y=y1+(y2-y1)*(right-x1)/(x2-x1);
+      x=right;
+    } else {
+      y=y1+(y2-y1)*(left-x1)/(x2-x1);
+      x=left;
+    }
+
+    if (cc==cc1) {
+      *_x1=x1=x;
+      *_y1=y1=y;
+      if (y1>bottom)
+        cc1=CC_BOTTOM;
+      else if (y1<top)
+        cc1=CC_TOP;
+      else
+        cc1=0;
+      if (x1>right)
+        cc1|=CC_RIGHT;
+      else if (x1<left)
+        cc1|=CC_LEFT;
+    } else {
+      *_x2=x2=x;
+      *_y2=y2=y;
+      if (y2>bottom)
+        cc2=CC_BOTTOM;
+      else if (y2<top)
+        cc2=CC_TOP;
+      else
+        cc2=0;
+      if (x2>right)
+        cc2|=CC_RIGHT;
+      else if (x2<left)
+        cc2|=CC_LEFT;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrPalette.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrPalette.HC.HTML new file mode 100755 index 0000000..67331c3 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrPalette.HC.HTML @@ -0,0 +1,124 @@ + + + + + + + + + + + +
+#help_index "Graphics/Color"
+public U8 gr_rainbow_10[10]={
+  BLACK,BROWN,RED,LTRED,YELLOW,GREEN,BLUE,PURPLE,LTGRAY,WHITE};
+
+DefineLstLoad("ST_RAINBOW_10",
+  "BLACK\0BROWN\0RED\0LTRED\0YELLOW\0GREEN\0BLUE\0PURPLE\0LTGRAY\0WHITE\0");
+
+U0 GrPaletteIndicesSet()
+{//There is a level of indirection that we identity map.
+// Set 16-colors to use first 16 DAC BGR entries, so we
+// never need to worry about indexes, just DAC palette settings.
+  I64 i;
+  if (!Bt(&sys_run_level,RLf_VGA)) return;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_VGA],0))
+    Yield;
+  InU8(VGAP_INPUT_STAT); //Rsts attr index/data
+  for (i=0;i<COLORS_NUM;i++) {
+    OutU8(VGAP_ATTR_INDEX,i);
+    OutU8(VGAP_ATTR_DATA_WRITE,i);
+  }
+  OutU8(VGAP_ATTR_INDEX,0x20);
+  OutU8(VGAP_ATTR_DATA_WRITE,0); //Dummy write
+  InU8(VGAP_INPUT_STAT); //Rsts attr index/data
+  LBtr(&sys_semas[SEMA_VGA],0);
+  POPFD
+}
+
+public U0 GrPaletteColorSet(I64 color_num,CBGR48 bgr48)
+{//VGA has 6-bits for blue, for green, and for red.
+  if (!Bt(&sys_run_level,RLf_VGA)) return;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_VGA],0))
+    Yield;
+  OutU8(VGAP_PALETTE_MASK,0xFF);
+  OutU8(VGAP_REG_WRITE,color_num);
+  OutU8(VGAP_PALETTE_DATA,bgr48.r>>10);
+  OutU8(VGAP_PALETTE_DATA,bgr48.g>>10);
+  OutU8(VGAP_PALETTE_DATA,bgr48.b>>10);
+  LBtr(&sys_semas[SEMA_VGA],0);
+  POPFD
+}
+
+public CBGR48 GrPaletteColorGet(I64 color_num)
+{//VGA has 6-bits for blue, for green, and for red.
+  CBGR48 res=0;
+  if (!Bt(&sys_run_level,RLf_VGA)) return 0;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_VGA],0))
+    Yield;
+  OutU8(VGAP_PALETTE_MASK,0xFF);
+  OutU8(VGAP_REG_READ,color_num);
+  res.r=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
+  res.g=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
+  res.b=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
+  LBtr(&sys_semas[SEMA_VGA],0);
+  POPFD
+  return res;
+}
+
+public CBGR48 gr_palette_std[COLORS_NUM]={
+0x000000000000,0x00000000AAAA,0x0000AAAA0000,0x0000AAAAAAAA,
+0xAAAA00000000,0xAAAA0000AAAA,0xAAAA55550000,0xAAAAAAAAAAAA,
+0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
+0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0xFFFFFFFFFFFF};
+
+public CBGR48 gr_palette_gray[COLORS_NUM]={
+0x000000000000,0x111111111111,0x222222222222,0x333333333333,
+0x444444444444,0x555555555555,0x666666666666,0x777777777777,
+0x888888888888,0x999999999999,0xAAAAAAAAAAAA,0xBBBBBBBBBBBB,
+0xCCCCCCCCCCCC,0xDDDDDDDDDDDD,0xEEEEEEEEEEEE,0xFFFFFFFFFFFF};
+
+public U0 GrPaletteGet(CBGR48 *bgr48)
+{//16 colors
+  I64 i;
+  for (i=0;i<COLORS_NUM;i++)
+    bgr48[i]=GrPaletteColorGet(i);
+}
+
+public U0 GrPaletteSet(CBGR48 *bgr48)
+{//16 colors
+  I64 i;
+  for (i=0;i<COLORS_NUM;i++)
+    GrPaletteColorSet(i,bgr48[i]);
+}
+
+public U0 PaletteSetStd()
+{//Activate std palette.
+  GrPaletteSet(gr_palette_std);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrPrimatives.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrPrimatives.HC.HTML new file mode 100755 index 0000000..f652252 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrPrimatives.HC.HTML @@ -0,0 +1,1853 @@ + + + + + + + + + + + +
+#help_index "Graphics"
+
+public Bool GrClamp(CDC *dc=gr.dc,I64 *left,I64 *top,I64 *right,I64 *bottom,
+        I64 width=0,I64 height=0)
+{//Returns scrn, not window coordinates.
+  CTask *win_task;
+  *left=0;
+  *top=0;
+  *right=dc->width-1;
+  *bottom=dc->height-1;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    if (GR_WIDTH-1<*right)
+      *right=GR_WIDTH-1;
+    if (GR_HEIGHT-1<*bottom)
+      *bottom=GR_HEIGHT-1;
+    if (win_task->pix_left>*left)
+      *left=win_task->pix_left;
+    if (win_task->pix_top>*top)
+      *top=win_task->pix_top;
+    if (win_task->pix_right<*right)
+      *right=win_task->pix_right;
+    if (win_task->pix_bottom<*bottom)
+      *bottom=win_task->pix_bottom;
+  }
+  *left-=width;
+  *right+=width;
+  *top-=height;
+  *bottom+=height;
+  return *left<=*right && *top<=*bottom;
+}
+
+Bool DCClipLine(CDC *dc=gr.dc,I64 *x1,I64 *y1,I64 *x2,I64 *y2,
+        I64 width=0,I64 height=0)
+{//Also converts window to scrn coordinates
+  I64 left,top,right,bottom;
+  CTask *win_task;
+  if (GrClamp(dc,&left,&top,&right,&bottom,width,height)) {
+    if (dc->flags & DCF_SCRN_BITMAP) {
+      win_task=dc->win_task;
+      *x1+=win_task->pix_left+win_task->scroll_x;
+      *y1+=win_task->pix_top+win_task->scroll_y;
+      *x2+=win_task->pix_left+win_task->scroll_x;
+      *y2+=win_task->pix_top+win_task->scroll_y;
+    }
+    return ClipLine(x1,y1,x2,y2,left,top,right,bottom);
+  } else
+    return FALSE;
+}
+
+public Bool GrPlot(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. Clipping but No transformation or thick.
+  I32 *db=dc->depth_buf;
+  CTask *win_task;
+  CColorROPU32 old_color;
+  dc->depth_buf=NULL;
+  if (dc->brush) {
+    old_color=dc->color;
+    if (dc->color.c0.rop!=ROPB_COLLISION)
+      dc->color.c0.rop=ROPB_MONO;
+    GrBlot(dc,x,y,dc->brush);
+    dc->color=old_color;
+  } else if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->pix_left+win_task->scroll_x;
+    y+=win_task->pix_top+win_task->scroll_y;
+    if (win_task->pix_left<=x<=win_task->pix_right &&
+          win_task->pix_top<=y<=win_task->pix_bottom &&
+          0<=x<dc->width && 0<=y<dc->height &&
+          (win_task->next_task==sys_winmgr_task ||
+          dc->flags&DCF_ON_TOP ||
+          !IsPixCovered0(win_task,x,y)))
+      GrPlot0(dc,x,y);
+  } else
+    if (0<=x<dc->width && 0<=y<dc->height)
+      GrPlot0(dc,x,y);
+  dc->depth_buf=db;
+  return TRUE;
+}
+
+Bool GrPlot1(CDC *dc=gr.dc,I64 x,I64 y)
+{//Clipping but No transformation or thick, called with db_z set
+  CTask *win_task;
+  CColorROPU32 old_color;
+  if (dc->brush) {
+    old_color=dc->color;
+    if (dc->color.c0.rop!=ROPB_COLLISION)
+      dc->color.c0.rop=ROPB_MONO;
+    if (dc->depth_buf)
+      GrBlot3(dc,x,y,dc->db_z,dc->brush);
+    else
+      GrBlot(dc,x,y,dc->brush);
+    dc->color=old_color;
+  } else if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->pix_left+win_task->scroll_x;
+    y+=win_task->pix_top+win_task->scroll_y;
+    if (win_task->pix_left<=x<=win_task->pix_right &&
+          win_task->pix_top <=y<=win_task->pix_bottom &&
+          0<=x<dc->width && 0<=y<dc->height &&
+          (win_task->next_task==sys_winmgr_task ||
+          dc->flags&DCF_ON_TOP ||
+          !IsPixCovered0(win_task,x,y)))
+      GrPlot0(dc,x,y);
+  } else
+    if (0<=x<dc->width && 0<=y<dc->height)
+      GrPlot0(dc,x,y);
+  return TRUE;
+}
+
+public I64 GrPeek(CDC *dc=gr.dc,I64 x,I64 y)
+{//2D. Clipping but no transformation.
+//Returns pix color or -1 if off-scrn or covered.
+  CTask *win_task;
+  if (dc->flags & DCF_SCRN_BITMAP) {
+    win_task=dc->win_task;
+    x+=win_task->pix_left+win_task->scroll_x;
+    y+=win_task->pix_top+win_task->scroll_y;
+    if (!(win_task->pix_left<=x<=win_task->pix_right)  ||
+          !(win_task->pix_top <=y<=win_task->pix_bottom) ||
+          !(0<=x<dc->width) || !(0<=y<dc->height) ||
+          win_task->next_task!=sys_winmgr_task &&
+          !(dc->flags&DCF_ON_TOP) &&
+          IsPixCovered0(win_task,x,y))
+      return -1;
+  } else
+    if (!(0<=x<dc->width) || !(0<=y<dc->height))
+      return -1;
+  return GrPeek0(dc,x,y);
+}
+
+/*
+
+This is an easier to understand
+version of the nonrecursive routine below.
+I64 GrFloodFillRay(CDC *dc,I64 x,I64 y,I64 z,I32 *db)
+{
+  I64 res,j,x1,ray_len,ray_len2;
+
+  if (UnusedStk<0x80)
+    Panic("Stk Overflow",Fs);
+
+  res=ray_len=GrRayLen(dc,&x,y,z,db);
+  y--;
+  j=ray_len;
+  x1=x;
+  while (j>0) {
+    if (ray_len2=GrRayLenMinus(dc,x1,y))
+      res+=GrFloodFillRay(dc,x1,y,z,db);
+    j-=ray_len2+1;
+    x1-=ray_len2+1;
+  }
+  y+=2;
+  j=ray_len;
+  x1=x;
+  while (j>0) {
+    if (ray_len2=GrRayLenMinus(dc,x1,y))
+      res+=GrFloodFillRay(dc,x1,y,z,db);
+    j-=ray_len2+1;
+    x1-=ray_len2+1;
+  }
+  return res;
+}
+*/
+
+class CFFRay
+{
+  I64 state,x,y,j,x1,ray_len,ray_len2;
+};
+
+I64 GrFloodFillRay(CDC *dc,I64 x,I64 y,I64 z,I32 *db)
+{//See the above commented-out routine for an easier to understand version.
+//Returns cnt of pixs changed
+  I64 res=0;
+//We don't dynamically calculate the size to avoid
+  //fragmentation of memory.
+  CFFRay *f_dc=MAlloc(sizeof(CFFRay)*0x80000),*f=f_dc;
+  f->x=x;
+  f->y=y;
+  f->state=0;
+  do {
+    switch [f->state] {
+      case 0:
+        f->state++;
+        res+=f->ray_len=GrRayLen(dc,&f->x,f->y,z,db);
+        f->y--;
+        f->j=f->ray_len;
+        f->x1=f->x;
+        break;
+      case 1:
+        if (f->j>0) {
+          f->state++;
+          if (f->ray_len2=GrRayLenMinus(dc,f->x1,f->y)) {
+            f[1].x=f->x1;
+            f[1].y=f->y;
+            f[1].state=0;
+            f++;
+          }
+        } else
+          f->state+=2;
+        break;
+      case 2:
+        f->state--;
+        f->j-=f->ray_len2+1;
+        f->x1-=f->ray_len2+1;
+        break;
+      case 3:
+        f->state++;
+        f->y+=2;
+        f->j=f->ray_len;
+        f->x1=f->x;
+        break;
+      case 4:
+        if (f->j>0) {
+          f->state++;
+          if (f->ray_len2=GrRayLenMinus(dc,f->x1,f->y)) {
+            f[1].x=f->x1;
+            f[1].y=f->y;
+            f[1].state=0;
+            f++;
+          }
+        } else
+          f->state+=2;
+        break;
+      case 5:
+        f->state--;
+        f->j-=f->ray_len2+1;
+        f->x1-=f->ray_len2+1;
+        break;
+      case 6:
+        f--;
+        break;
+    }
+  } while (f>=f_dc);
+  Free(f_dc);
+  return res;
+}
+
+public I64 GrFloodFill(CDC *dc=gr.dc,I64 x,I64 y,
+        Bool not_color=FALSE,I64 z=0,I32 *db=NULL)
+{//2D. Ignore z and db.
+//not_color=TRUE means fill up to everything which is not the current color.
+  //not_color=FALSE means fill all parts equ to the color under the point.
+  //Returns cnt of pixs changed
+  I64 res=0,j,old_flags=dc->flags;
+  CColorROPU32 old_color2=dc->color2;
+  CDC *old_brush;
+  if (dc->flags & DCF_DONT_DRAW) //TODO
+    return 0;
+  old_brush=dc->brush;
+  dc->brush=NULL;
+  if ((j=GrPeek(dc,x,y))>=0) {
+    if (not_color) {
+      dc->color2=dc->color.c0.color;
+      dc->flags|=DCF_FILL_NOT_COLOR;
+    } else {
+      dc->color2=j;
+      if (dc->color.c1.rop&ROPBF_DITHER) {
+        if (dc->color2.c0.color==dc->color.c0.color &&
+              dc->color.c0.color==dc->color.c1.color)
+          goto ff_done;
+      } else if (dc->color2.c0.color==dc->color.c0.color)
+        goto ff_done;
+      dc->flags&=~DCF_FILL_NOT_COLOR;
+    }
+    if (not_color && j!=dc->color2 ||
+          !not_color)
+      res=GrFloodFillRay(dc,x,y,z,db);
+  }
+ff_done:
+  dc->brush=old_brush;
+  dc->flags=old_flags;
+  dc->color2=old_color2;
+  return res;
+}
+
+I64 GrFillSemiCircle(CDC *dc=gr.dc,I64 cx,I64 cy,I64 z=0,I64 diameter,I64 n)
+{//2D. Clipping but not transformation.
+  I64 res=0,i,k,r=diameter>>1,rr;
+  if (diameter>=1)
+    switch (n) {
+      case 0:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(r-i))+cx,
+                  Sqrt(rr-SqrI64(r-i))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 1:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(i-r))+cx,
+                  Sqrt(rr-SqrI64(i-r))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 2:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(r-i))+cy,
+                  Sqrt(rr-SqrI64(r-i))+cy,z,z);
+        }
+        break;
+      case 3:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(i-r))+cy,
+                  Sqrt(rr-SqrI64(i-r))+cy,z,z);
+        }
+        break;
+      case 4:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(r-i))+cx,
+                  Sqrt(rr-SqrI64(r-i))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 5:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+                  gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrHLine(dc,-Sqrt(rr-SqrI64(i-r))+cx,
+                  Sqrt(rr-SqrI64(i-r))+cx,cy+i-r,z,z);
+        }
+        break;
+      case 6:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=0;i<r;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(r-i))+cy,
+                  Sqrt(rr-SqrI64(r-i))+cy,z,z);
+        }
+        break;
+      case 7:
+        if (diameter<GR_PEN_BRUSHES_NUM)
+          for (i=r+1;i<diameter;i++)
+            res+=GrVLine(dc,cx+i-r,gr.circle_lo[diameter][i]+cy,
+                  gr.circle_hi[diameter][i]+cy,z,z);
+        else {
+          k=diameter+1;
+          rr=SqrI64((k+1)>>1);
+          for (i=r+1;i<k;i++)
+            res+=GrVLine(dc,cx+i-r,-Sqrt(rr-SqrI64(i-r))+cy,
+                  Sqrt(rr-SqrI64(i-r))+cy,z,z);
+        }
+        break;
+    }
+  return res;
+}
+
+public I64 GrFillCircle(CDC *dc=gr.dc,I64 cx,I64 cy,I64 z=0,I64 diameter)
+{//2D. Clipping but not transformation.
+  I64 res=0,i,k,r=diameter>>1,rr;
+  if (diameter>=1) {
+    if (diameter<GR_PEN_BRUSHES_NUM)
+      for (i=0;i<diameter;i++)
+        res+=GrHLine(dc,gr.circle_lo[diameter][i]+cx,
+              gr.circle_hi[diameter][i]+cx,cy+i-r,z,z);
+    else {
+      k=diameter+1;
+      rr=SqrI64((k+1)>>1);
+      for (i=0;i<=r;i++)
+        res+=GrHLine(dc,-Sqrt(rr-SqrI64(r-i))+cx,
+              Sqrt(rr-SqrI64(r-i))+cx,cy+i-r,z,z);
+      for (;i<k;i++)
+        res+=GrHLine(dc,-Sqrt(rr-SqrI64(i-r))+cx,
+              Sqrt(rr-SqrI64(i-r))+cx,cy+i-r,z,z);
+    }
+  }
+  return res;
+}
+
+public Bool GrPlot3B(CDC *dc=gr.dc,I64 x,I64 y,I64 z)
+{//3D. Clipping and transformation but no thick.
+  I64 _x,_y,_z;
+  Bool was_transform=FALSE,was_symmetry=FALSE;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x,&y,&z);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x=x; _y=y; _z=z;
+    DCReflect(dc,&_x,&_y,&_z);
+    dc->flags&=~DCF_SYMMETRY;
+    dc->db_z=_z;
+    GrPlot1(dc,_x,_y);
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  dc->db_z=z;
+  GrPlot1(dc,x,y);
+gr_done:
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return TRUE;
+}
+
+public Bool GrPlot3(CDC *dc=gr.dc,I64 x,I64 y,I64 z)
+{//3D. Clipping and transformation and thick.
+  I64 _x,_y,_z,w,dist;
+  CColorROPU32 old_color=dc->color;
+  Bool record,was_transform=FALSE,was_symmetry=FALSE;
+  CTask *win_task;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x,&y,&z);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x=x; _y=y; _z=z;
+    DCReflect(dc,&_x,&_y,&_z);
+    dc->flags&=~DCF_SYMMETRY;
+    GrPlot3(dc,_x,_y,_z);
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  w=dc->thick>>1;
+  dc->db_z=z;
+  if (dc->brush || w<=0)
+    GrPlot1(dc,x,y);
+  else if (dc->thick<GR_PEN_BRUSHES_NUM) {
+    if (dc->color.c0.rop!=ROPB_COLLISION)
+      dc->color.c0.rop=ROPB_MONO;
+    if (dc->depth_buf) {
+      if (dc->color.c1.rop&ROPBF_DITHER) {
+        dc->color.c1.rop=dc->color.c0.rop;
+        if (((x-w)^(y-w))&1) {
+          record=GrBlot3(dc,x-w,y-w,z,gr.odd_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot3(dc,x-w,y-w,z,gr.even_pen_brushes[dc->thick]);
+        } else {
+          record=GrBlot3(dc,x-w,y-w,z,gr.even_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot3(dc,x-w,y-w,z,gr.odd_pen_brushes[dc->thick]);
+        }
+      } else {
+        if (dc->color.c0.rop==ROPB_COLLISION) {
+          if (dc->color.c0.color!=dc->bkcolor.c0.color &&
+                dc->color.c0.color!=TRANSPARENT)
+            record=GrBlot3(dc,x-w,y-w,z,
+                  gr.collision_pen_brushes[dc->thick]);
+          else
+            record=FALSE;
+        } else
+          record=GrBlot3(dc,x-w,y-w,z,gr.pen_brushes[dc->thick]);
+      }
+    } else {
+      if (dc->color.c1.rop&ROPBF_DITHER) {
+        dc->color.c1.rop=dc->color.c0.rop;
+        if (((x-w)^(y-w))&1) {
+          record=GrBlot(dc,x-w,y-w,gr.odd_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot(dc,x-w,y-w,gr.even_pen_brushes[dc->thick]);
+        } else {
+          record=GrBlot(dc,x-w,y-w,gr.even_pen_brushes[dc->thick]);
+          dc->color.c0=dc->color.c1;
+          record=GrBlot(dc,x-w,y-w,gr.odd_pen_brushes[dc->thick]);
+        }
+      } else {
+        if (dc->color.c0.rop==ROPB_COLLISION) {
+          if (dc->color.c0.color!=dc->bkcolor.c0.color &&
+                dc->color.c0.color!=TRANSPARENT)
+            record=GrBlot(dc,x-w,y-w,gr.collision_pen_brushes[dc->thick]);
+          else
+            record=FALSE;
+        } else
+          record=GrBlot(dc,x-w,y-w,gr.pen_brushes[dc->thick]);
+      }
+    }
+    if (record) {
+      if (dc->flags & DCF_SCRN_BITMAP) {
+        win_task=dc->win_task;
+        x+=win_task->pix_left+win_task->scroll_x;
+        y+=win_task->pix_top+win_task->scroll_y;
+      }
+      if (dc->flags & DCF_LOCATE_NEAREST) {
+        dist=DistSqrI64(x,y,dc->cur_x,dc->cur_y);
+        if (dist<=dc->nearest_dist)
+          dc->nearest_dist=dist;
+      }
+      if (dc->flags & DCF_RECORD_EXTENTS) {
+        if (x-w<dc->min_x) dc->min_x=x-w;
+        if (y-w<dc->min_y) dc->min_y=y-w;
+        if (dc->thick & 1) {
+          if (x+w>dc->max_x) dc->max_x=x+w;
+          if (y+w>dc->max_y) dc->max_y=y+w;
+        } else {
+          if (x+w-1>dc->max_x) dc->max_x=x+w-1;
+          if (y+w-1>dc->max_y) dc->max_y=y+w-1;
+        }
+      }
+    }
+  } else
+    GrFillCircle(dc,x,y,dc->db_z,dc->thick);
+gr_done:
+  dc->color=old_color;
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return TRUE;
+}
+
+Bool GrLinePlot0(CDC *dc,I64 x,I64 y,I64 z)
+{//This is a callback.
+  CTask *win_task=dc->win_task;
+  if (!(dc->flags & DCF_SCRN_BITMAP) ||
+        win_task->next_task==sys_winmgr_task ||
+        dc->flags&DCF_ON_TOP ||
+        !IsPixCovered0(win_task,x,y)) {
+    dc->db_z=z;
+    GrPlot0(dc,x,y);
+  }
+  return TRUE;
+}
+
+Bool GrLinePlot(CDC *dc,I64 x,I64 y,I64 z)
+{//This is a callback.
+  dc->db_z=z;
+  GrPlot1(dc,x,y);
+  return TRUE;
+}
+
+public Bool GrLine(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
+        I64 step=1,I64 start=0)
+{//2D. Clipping but not transformation.
+  Bool res=FALSE;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  if (step==1 && !start && !dc->brush && !dc->depth_buf) {
+    if (DCClipLine(dc,&x1,&y1,&x2,&y2))
+      res=Line(dc,x1,y1,0,x2,y2,0,&GrLinePlot0,step,start);
+  } else
+    res=Line(dc,x1,y1,0,x2,y2,0,&GrLinePlot,step,start);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool GrCircle(CDC *dc=gr.dc,I64 cx,I64 cy,I64 radius,
+  I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//2D. Clipping but not transformation.
+  Bool res;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  res=Circle(dc,cx,cy,0,radius,&GrLinePlot,step,start_radians,len_radians);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool GrEllipse(CDC *dc=gr.dc,
+                I64 cx,I64 cy,
+                I64 x_radius,I64 y_radius,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//2D. Clipping but not transformation.
+  Bool res;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  res=Ellipse(dc,cx,cy,0,x_radius,y_radius,&GrLinePlot,
+        rot_angle,step,start_radians,len_radians);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool GrRegPoly(CDC *dc=gr.dc,
+                I64 cx,I64 cy,
+                I64 x_radius,I64 y_radius,I64 sides,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//2D. Clipping but no transform or thick.
+  Bool res;
+  I32 *db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  res=RegPoly(dc,cx,cy,0,x_radius,y_radius,sides,
+        &GrLinePlot,rot_angle,step,start_radians,len_radians);
+  dc->depth_buf=db;
+  return res;
+}
+
+public Bool Gr2Bezier(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//2nd order. Clipping but no transform or thick.
+  return Bezier2(dc,ctrl,&GrLinePlot);
+}
+
+public Bool Gr3Bezier(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//3rd order. Clipping but no transform or thick.
+  return Bezier3(dc,ctrl,&GrLinePlot);
+}
+
+public Bool Gr2BSpline(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//2nd order. Clipping but no transform or thick.
+  return BSpline2(dc,ctrl,cnt,&GrLinePlot,closed);
+}
+
+public Bool Gr3BSpline(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//3rd order. Clipping but no transform or thick.
+  return BSpline3(dc,ctrl,cnt,&GrLinePlot,closed);
+}
+
+I64 GrLineFat3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
+        I64 width,I64 start=0)
+{//Step through line segment calling callback.
+//Uses fixed-point.
+  I64 res=0,i,j,d,dx=x2-x1,dy=y2-y1,dz=z2-z1,_x,_y,_z,d_lo,d_hi,
+        adx=AbsI64(dx),ady=AbsI64(dy),adz=AbsI64(dz);
+  if (width>0) {
+    if (adx>=ady) {
+      if (adx>=adz) {
+        if (d=adx) {
+          if (dx>=0)
+            dx=0x100000000;
+          else
+            dx=-0x100000000;
+          dy=dy<<32/d;
+          dz=dz<<32/d;
+        }
+      } else {
+        if (d=adz) {
+          dx=dx<<32/d;
+          dy=dy<<32/d;
+          if (dz>=0)
+            dz=0x100000000;
+          else
+            dz=-0x100000000;
+        }
+      }
+      x1<<=32; y1<<=32; z1<<=32;
+      for (j=0;j<start;j++) {
+        x1+=dx; y1+=dy; z1+=dz;
+      }
+      if (start>=d)
+        res+=GrFillCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width);
+      else {
+        if (width==1)
+          for (i=start;i<=d;i++) {
+            dc->db_z=z1.i32[1];
+            res+=GrPlot1(dc,x1.i32[1],y1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+        else {
+          i=width*Sqrt(SqrI64(adx)+SqrI64(ady))/adx;
+          d_lo=i>>1; d_hi=(i-1)>>1;
+
+          if (dx>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,2);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,7);
+          for (i=start;i<=d;i++) {
+            res+=GrVLine(dc,x1.i32[1],y1.i32[1]-d_lo,y1.i32[1]+d_hi,
+                  z1.i32[1],z1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+          x1-=dx; y1-=dy; z1-=dz;
+          if (dx>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,3);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,6);
+        }
+      }
+    } else {
+      if (ady>=adz) {
+        if (d=ady) {
+          dx=dx<<32/d;
+          if (dy>=0)
+            dy=0x100000000;
+          else
+            dy=-0x100000000;
+          dz=dz<<32/d;
+        }
+      } else {
+        if (d=adz) {
+          dx=dx<<32/d;
+          dy=dy<<32/d;
+          if (dz>=0)
+            dz=0x100000000;
+          else
+            dz=-0x100000000;
+        }
+      }
+      x1<<=32; y1<<=32; z1<<=32;
+      for (j=0;j<start;j++) {
+        x1+=dx; y1+=dy; z1+=dz;
+      }
+      if (start>=d)
+        res+=GrFillCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width);
+      else {
+        if (width==1)
+          for (i=start;i<=d;i++) {
+            dc->db_z=z1.i32[1];
+            res+=GrPlot1(dc,x1.i32[1],y1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+        else {
+          i=width*Sqrt(SqrI64(ady)+SqrI64(adx))/ady;
+          d_lo=i>>1; d_hi=(i-1)>>1;
+
+          if (dy>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,0);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,5);
+          for (i=start;i<=d;i++) {
+            res+=GrHLine(dc,x1.i32[1]-d_lo,x1.i32[1]+d_hi,y1.i32[1],
+                  z1.i32[1],z1.i32[1]);
+            _x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
+            x1+=dx; y1+=dy; z1+=dz;
+          }
+          x1-=dx; y1-=dy; z1-=dz;
+          if (dy>=0)
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,1);
+          else
+            res+=GrFillSemiCircle(dc,x1.i32[1],y1.i32[1],z1.i32[1],width,4);
+        }
+      }
+    }
+  }
+  return res;
+}
+
+public Bool GrLine3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
+        I64 step=1,I64 start=0)
+{//3D. Transformation with thick.
+  I64 _x1,_y1,_z1,_x2,_y2,_z2;
+  Bool res=FALSE,was_transform=FALSE,was_symmetry=FALSE;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    (*dc->transform)(dc,&x2,&y2,&z2);
+    dc->flags&=~DCF_TRANSFORMATION;
+    was_transform=TRUE;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x1=x1; _y1=y1; _z1=z1;
+    DCReflect(dc,&_x1,&_y1,&_z1);
+    _x2=x2; _y2=y2; _z2=z2;
+    DCReflect(dc,&_x2,&_y2,&_z2);
+    dc->flags&=~DCF_SYMMETRY;
+    if (step==1 && !dc->brush) {
+      if (!start && dc->thick<2 && !dc->depth_buf) {//TODO: clip z depbuf
+        if (DCClipLine(dc,&_x1,&_y1,&_x2,&_y2))
+          res=Line(dc,_x1,_y1,0,_x2,_y2,0,&GrLinePlot0,step,start);
+      } else {
+        if (GrLineFat3(dc,_x1,_y1,_z1,_x2,_y2,_z2,dc->thick,start))
+          res=TRUE;
+      }
+    } else
+      res=Line(dc,_x1,_y1,_z1,_x2,_y2,_z2,&GrPlot3,step,start);
+    was_symmetry=TRUE;
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  if (step==1 && !dc->brush) {
+    if (!start && dc->thick<2 && !dc->depth_buf) {//TODO: clip z depbuf
+      if (DCClipLine(dc,&x1,&y1,&x2,&y2))
+        res|=Line(dc,x1,y1,0,x2,y2,0,&GrLinePlot0,step,start);
+    } else {
+      if (GrLineFat3(dc,x1,y1,z1,x2,y2,z2,dc->thick,start))
+        res=TRUE;
+    }
+  } else
+    res|=Line(dc,x1,y1,z1,x2,y2,z2,&GrPlot3,step,start);
+gr_done:
+  if (was_transform)
+    dc->flags|=DCF_TRANSFORMATION;
+  if (was_symmetry)
+    dc->flags|=DCF_SYMMETRY;
+  return res;
+}
+
+#help_index "Graphics/Char;Char/Graphics"
+
+public Bool GrPutChar3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 ch)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x,&y,&z);
+  return GrPutChar(dc,x,y,ch);
+}
+
+public I64 GrPrint3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *fmt,...)
+{//3D. Transformation. DCF_SYMMETRY is silly.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res;
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x,&y,&z);
+  res=GrPrint(dc,x,y,"%s",buf);
+  Free(buf);
+  return res;
+}
+
+public I64 GrVPrint3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *fmt,...)
+{//3D. Vertical text. Transformation. DCF_SYMMETRY is silly.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res;
+  if (dc->flags & DCF_TRANSFORMATION)
+    (*dc->transform)(dc,&x,&y,&z);
+  res=GrVPrint(dc,x,y,"%s",buf);
+  Free(buf);
+  return res;
+}
+
+#help_index "Graphics"
+
+public Bool GrEllipse3(CDC *dc=gr.dc,
+                I64 cx,I64 cy,I64 cz,
+                I64 x_radius,I64 y_radius,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//3D. Transformation with thick.
+  Bool res;
+  I64 x,y,z,xx,yy,zz;
+  F64 m1,arg1,m2,arg2,s,c;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    dc->flags&=~DCF_TRANSFORMATION;
+    (*dc->transform)(dc,&cx,&cy,&cz);
+
+    c=Cos(rot_angle);
+    s=Sin(rot_angle);
+
+    x_radius<<=16;
+    y_radius<<=16;
+
+    xx=0;
+    yy=0;
+    zz=0;
+    (*dc->transform)(dc,&xx,&yy,&zz);
+
+    x=x_radius*c;
+    y=x_radius*s;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m1,&arg1,x,y);
+
+    x=-y_radius*s;
+    y=y_radius*c;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m2,&arg2,x,y);
+    m2*=Abs(Sin(arg2-arg1));
+
+    res=Ellipse(dc,cx,cy,cz,
+          m1/0x10000,m2/0x10000,&GrPlot3,-arg1,step,start_radians,len_radians);
+    dc->flags|=DCF_TRANSFORMATION;
+  } else
+    res=Ellipse(dc,cx,cy,cz,x_radius,y_radius,&GrPlot3,
+          rot_angle,step,start_radians,len_radians);
+  return res;
+}
+
+public Bool GrCircle3(CDC *dc=gr.dc,I64 cx,I64 cy,I64 cz,I64 radius,
+  I64 step=1,F64 start_radians=0,F64 len_radians=2*pi)
+{//3D. Transformation with thick.
+  if (dc->flags & DCF_TRANSFORMATION)
+    return GrEllipse3(dc,cx,cy,cz,radius,radius,0,step,
+          start_radians,len_radians);
+  else
+    return Circle(dc,cx,cy,cz,radius,&GrPlot3,step,
+          start_radians,len_radians);
+}
+
+public Bool GrRegPoly3(CDC *dc=gr.dc,
+                I64 cx,I64 cy,I64 cz,
+                I64 x_radius,I64 y_radius,I64 sides,
+                F64 rot_angle=0,
+                I64 step=1,
+                F64 start_radians=0,
+                F64 len_radians=2*pi)
+{//3D. Clipping and transform and thick.
+  Bool res;
+  I64 x,y,z,xx,yy,zz;
+  F64 m1,arg1,m2,arg2,s,c;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    dc->flags&=~DCF_TRANSFORMATION;
+    (*dc->transform)(dc,&cx,&cy,&cz);
+
+    c=Cos(rot_angle);
+    s=Sin(rot_angle);
+
+    x_radius<<=16;
+    y_radius<<=16;
+
+    xx=0;
+    yy=0;
+    zz=0;
+    (*dc->transform)(dc,&xx,&yy,&zz);
+
+    x=x_radius*c;
+    y=x_radius*s;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m1,&arg1,x,y);
+
+    x=-y_radius*s;
+    y=y_radius*c;
+    z=0;
+    (*dc->transform)(dc,&x,&y,&z);
+    x-=xx;
+    y-=yy;
+    z-=zz;
+    R2P(&m2,&arg2,x,y);
+    m2*=Abs(Sin(arg2-arg1));
+
+    res=RegPoly(dc,cx,cy,cz,
+          m1/0x10000,m2/0x10000,sides,&GrPlot3,-arg1,
+          step,start_radians,len_radians);
+    dc->flags|=DCF_TRANSFORMATION;
+  } else
+    res=RegPoly(dc,cx,cy,cz,x_radius,y_radius,sides,&GrPlot3,
+          rot_angle,step,start_radians,len_radians);
+  return res;
+}
+
+public I64 GrFloodFill3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,Bool not_color=FALSE)
+{//3D. Transformation.
+//not_color=TRUE means fill up to everything which is not the current color.
+  //not_color=FALSE means fill all parts equ to the color under the point.
+  //Returns cnt of pixs changed
+  I64 res,old_flags=dc->flags,
+        _x,_y,_z;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    dc->flags&=~DCF_TRANSFORMATION;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    _x=x1; _y=y1; _z=z1;
+    DCReflect(dc,&_x,&_y,&_z);
+    dc->flags&=~DCF_SYMMETRY;
+    res=GrFloodFill(dc,_x,_y,not_color,_z,dc->depth_buf);
+    if (dc->flags&DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+  res=GrFloodFill(dc,x1,y1,not_color,z1,dc->depth_buf);
+gr_done:
+  dc->flags=old_flags;
+  return res;
+}
+
+#help_index "Graphics;Graphics/Device Contexts"
+
+Option(OPTf_WARN_HEADER_MISMATCH,OFF);
+public I64 GrBlot3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,CDC *img)
+{//3D. Clipping and transformation.
+  CColorROPU32 old_color=dc->color;
+  I64  color,reg i,j,w=img->width,h=img->height,
+        d1,dx1,dy1,dz1,
+        reg d2,dx2,dy2,dz2,
+        adx1,ady1,adz1,
+        adx2,ady2,adz2,
+        x2,y2,z2,x3,y3,z3,
+        dw,reg dh,x,y,_x1,_y1,_z1,_x2,_y2,_z2,_x3,_y3,_z3,
+        last_x,last_y,res=0;
+  Bool first;
+  CDC *old_brush=dc->brush;
+
+  if (dc->depth_buf || dc->flags & (DCF_TRANSFORMATION | DCF_SYMMETRY)) {
+    x2=x1+w; y2=y1; z2=z1;
+    x3=x1; y3=y1+h; z3=z1;
+    if (dc->flags & DCF_TRANSFORMATION) {
+      (*dc->transform)(dc,&x1,&y1,&z1);
+      (*dc->transform)(dc,&x2,&y2,&z2);
+      (*dc->transform)(dc,&x3,&y3,&z3);
+    }
+    if (dc->flags & DCF_SYMMETRY) {
+      _x1=x1; _y1=y1; _z1=z1;
+      DCReflect(dc,&_x1,&_y1,&_z1);
+      _x2=x2; _y2=y2; _z2=z2;
+      DCReflect(dc,&_x2,&_y2,&_z2);
+      _x3=x3; _y3=y3; _z3=z3;
+      DCReflect(dc,&_x3,&_y3,&_z3);
+      dx1=_x2-_x1; dy1=_y2-_y1; dz1=_z2-_z1;
+      dx2=_x3-_x1; dy2=_y3-_y1; dz2=_z3-_z1;
+      adx1=AbsI64(dx1); ady1=AbsI64(dy1); adz1=AbsI64(dz1);
+      adx2=AbsI64(dx2); ady2=AbsI64(dy2); adz2=AbsI64(dz2);
+
+      if (adx1>=ady1) {
+        if (adx1>=adz1)
+          d1=adx1;
+        else
+          d1=adz1;
+      } else {
+        if (ady1>=adz1)
+          d1=ady1;
+        else
+          d1=adz1;
+      }
+      if (adx2>=ady2) {
+        if (adx2>=adz2)
+          d2=adx2;
+        else
+          d2=adz2;
+      } else {
+        if (ady2>=adz2)
+          d2=ady2;
+        else
+          d2=adz2;
+      }
+
+      if (AbsI64(d1)!=w ||AbsI64(d2)!=h) {
+        d1<<=1;
+        d2<<=1;
+      }
+      if (d1) {
+        dx1=dx1<<32/d1;
+        dy1=dy1<<32/d1;
+        dz1=dz1<<32/d1;
+      } else
+        goto normal_image;
+      if (d2) {
+        dx2=dx2<<32/d2;
+        dy2=dy2<<32/d2;
+        dz2=dz2<<32/d2;
+      } else
+        goto normal_image;
+      dc->brush=NULL;
+      x=0;y=0;
+      dw=w<<32/d1;
+      dh=h<<32/d2;
+
+      first=TRUE;
+      _x1<<=32; _y1<<=32; _z1<<=32;
+      for (j=0;j<=d1;j++) {
+        _x2=_x1; _y2=_y1; _z2=_z1;
+        y=0;
+        for (i=0;i<=d2;i++) {
+          if (_x2.i32[1]!=last_x || _y2.i32[1]!=last_y ||first) {
+            if ((color=GrPeek(img,x.i32[1],y.i32[1]))>=0) {
+              if (dc->color.c0.rop==ROPB_MONO) {
+                if (color) {
+                  dc->color=old_color&~ROPF_DITHER;
+                  if (dc->depth_buf) {
+                    dc->db_z=_z2.i32[1];
+                    GrPlot1(dc,_x2.i32[1],_y2.i32[1]);
+                  } else
+                    GrPlot(dc,_x2.i32[1],_y2.i32[1]);
+                }
+              } else {
+                if (color!=TRANSPARENT) {
+                  dc->color=old_color&~COLORROP_NO_ROP0_MASK|color;
+                  if (dc->depth_buf) {
+                    dc->db_z=_z2.i32[1];
+                    GrPlot1(dc,_x2.i32[1],_y2.i32[1]);
+                  } else
+                    GrPlot(dc,_x2.i32[1],_y2.i32[1]);
+                }
+              }
+            }
+          }
+          first=FALSE;
+          last_x=_x2.i32[1]; last_y=_y2.i32[1];
+          _x2+=dx2; _y2+=dy2; _z2+=dz2;
+          y+=dh;
+        }
+        _x1+=dx1; _y1+=dy1; _z1+=dz1;
+        x+=dw;
+      }
+      res=1;
+normal_image:
+      if (dc->flags&DCF_JUST_MIRROR)
+        goto gr_done;
+    }
+    dx1=x2-x1; dy1=y2-y1; dz1=z2-z1;
+    dx2=x3-x1; dy2=y3-y1; dz2=z3-z1;
+    adx1=AbsI64(dx1); ady1=AbsI64(dy1); adz1=AbsI64(dz1);
+    adx2=AbsI64(dx2); ady2=AbsI64(dy2); adz2=AbsI64(dz2);
+
+    if (adx1>=ady1) {
+      if (adx1>=adz1)
+        d1=adx1;
+      else
+        d1=adz1;
+    } else {
+      if (ady1>=adz1)
+        d1=ady1;
+      else
+        d1=adz1;
+    }
+    if (adx2>=ady2) {
+      if (adx2>=adz2)
+        d2=adx2;
+      else
+        d2=adz2;
+    } else {
+      if (ady2>=adz2)
+        d2=ady2;
+      else
+        d2=adz2;
+    }
+    if (AbsI64(d1)!=w ||AbsI64(d2)!=h) {
+      d1<<=1;
+      d2<<=1;
+    }
+    if (d1) {
+      dx1=dx1<<32/d1;
+      dy1=dy1<<32/d1;
+      dz1=dz1<<32/d1;
+    } else
+      goto gr_done;
+    if (d2) {
+      dx2=dx2<<32/d2;
+      dy2=dy2<<32/d2;
+      dz2=dz2<<32/d2;
+    } else
+      goto gr_done;
+    dc->brush=NULL;
+    x=0;y=0;
+    dw=w<<32/d1;
+    dh=h<<32/d2;
+
+    first=TRUE;
+    x1<<=32; y1<<=32; z1<<=32;
+    for (j=0;j<=d1;j++) {
+      x2=x1; y2=y1; z2=z1;
+      y=0;
+      for (i=0;i<=d2;i++) {
+        if (x2.i32[1]!=last_x || y2.i32[1]!=last_y || first) {
+          if ((color=GrPeek(img,x.i32[1],y.i32[1]))>=0) {
+            if (dc->color.c0.rop==ROPB_MONO) {
+              if (color) {
+                dc->color=old_color&~ROPF_DITHER;
+                if (dc->depth_buf) {
+                  dc->db_z=z2.i32[1];
+                  GrPlot1(dc,x2.i32[1],y2.i32[1]);
+                } else
+                  GrPlot(dc,x2.i32[1],y2.i32[1]);
+              }
+            } else {
+              if (color!=TRANSPARENT) {
+                dc->color=old_color&~COLORROP_NO_ROP0_MASK|color;//COLOR
+                if (dc->depth_buf) {
+                  dc->db_z=z2.i32[1];
+                  GrPlot1(dc,x2.i32[1],y2.i32[1]);
+                } else
+                  GrPlot(dc,x2.i32[1],y2.i32[1]);
+              }
+            }
+          }
+        }
+        first=FALSE;
+        last_x=x2.i32[1]; last_y=y2.i32[1];
+        x2+=dx2; y2+=dy2; z2+=dz2;
+        y+=dh;
+      }
+      x1+=dx1; y1+=dy1; z1+=dz1;
+      x+=dw;
+    }
+    res=1;  //TODO: check off scrn
+  } else
+    res=GrBlot(dc,x1,y1,img);
+gr_done:
+  dc->color=old_color;
+  dc->brush=old_brush;
+  return res;
+}
+Option(OPTf_WARN_HEADER_MISMATCH,ON);
+
+#help_index "Graphics"
+
+public Bool Gr2Bezier3(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//2nd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*3);
+    for (i=0;i<3;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*3);
+    for (i=0;i<3;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=Bezier2(dc,ctrl3,&GrPlot3);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=Bezier2(dc,ctrl,&GrPlot3);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public Bool Gr3Bezier3(CDC *dc=gr.dc,CD3I32 *ctrl)
+{//3rd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*4);
+    for (i=0;i<4;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*4);
+    for (i=0;i<4;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=Bezier3(dc,ctrl3,&GrPlot3);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=Bezier3(dc,ctrl,&GrPlot3);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public I64 Gr2BSpline3(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//2nd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=BSpline2(dc,ctrl3,cnt,&GrPlot3,closed);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=BSpline2(dc,ctrl,cnt,&GrPlot3,closed);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public Bool Gr3BSpline3(CDC *dc=gr.dc,CD3I32 *ctrl,I64 cnt,Bool closed=FALSE)
+{//3rd order. Clipping and transform and thick.
+  Bool res=FALSE;
+  I64 i,x,y,z,
+        old_flags=dc->flags;
+  CD3I32 *ctrl2=NULL,*ctrl3=NULL;
+  if (dc->flags & DCF_TRANSFORMATION) {
+    ctrl2=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      (*dc->transform)(dc,&x,&y,&z);
+      ctrl2[i].x=x;
+      ctrl2[i].y=y;
+      ctrl2[i].z=z;
+    }
+    dc->flags&=~DCF_TRANSFORMATION;
+    ctrl=ctrl2;
+  }
+  if (dc->flags & DCF_SYMMETRY) {
+    ctrl3=MAlloc(sizeof(CD3I32)*cnt);
+    for (i=0;i<cnt;i++) {
+      x=ctrl[i].x;
+      y=ctrl[i].y;
+      z=ctrl[i].z;
+      DCReflect(dc,&x,&y,&z);
+      ctrl3[i].x=x;
+      ctrl3[i].y=y;
+      ctrl3[i].z=z;
+    }
+    dc->flags&=~DCF_SYMMETRY;
+    res=BSpline3(dc,ctrl3,cnt,&GrPlot3,closed);
+    if (dc->flags & DCF_JUST_MIRROR)
+      goto gr_done;
+  }
+
+  res|=BSpline3(dc,ctrl,cnt,&GrPlot3,closed);
+gr_done:
+  Free(ctrl2);
+  Free(ctrl3);
+  dc->flags=old_flags;
+  return res;
+}
+
+public I64 GrFillTri0(CDC *dc=gr.dc,CD3I32 *p1,CD3I32 *p2,CD3I32 *p4)
+{//3D. Returns cnt of pixs changed
+  I64 x1,x2,y1,y2,z1,z2,dx1,dy1,dz1,dx2,dy2,dz2,res=0,i,min,max;
+  CTask *win_task;
+
+  if (AbsI64(p1->y-p2->y)+AbsI64(p1->y-p4->y)<=
+        AbsI64(p1->x-p2->x)+AbsI64(p1->x-p4->x)) {
+//p1 is min x
+    if (p4->x<p2->x)
+      SwapI64(&p4,&p2);
+    if (p2->x<p1->x)
+      SwapI64(&p2,&p1);
+
+      //p2y<=p4y
+    if (p4->y<p2->y)
+      SwapI64(&p4,&p2);
+
+    min=0;
+    max=dc->height;
+    if (dc->flags & DCF_SCRN_BITMAP) {
+      win_task=dc->win_task;
+      min-=win_task->scroll_y+win_task->pix_top;
+      max-=win_task->scroll_y+win_task->pix_top;
+      if (max>win_task->pix_bottom-(win_task->scroll_y+win_task->pix_top))
+        max=win_task->pix_bottom-(win_task->scroll_y+win_task->pix_top);
+    }
+
+    if ((dy2=p4->y-p1->y)<0) {
+      dy1=p2->y-p1->y;
+      dx1=(p1->x-p2->x)<<32/dy1;
+      dz1=(p1->z-p2->z)<<32/dy1;
+
+      dx2=(p1->x-p4->x)<<32/dy2;
+      dz2=(p1->z-p4->z)<<32/dy2;
+      x1=x2=p1->x<<32; y1=p1->y; z1=z2=p1->z<<32;
+      if (y1+dy2<min) {
+        i=min-(y1+dy2);
+        if (i>-dy2) goto ft_done;
+        dy2+=i;
+      }
+      if (y1>=max) {
+        i=y1-max+1;
+        if (i>-dy2)
+          i=-dy2;
+        dy2+=i;
+        y1-=i;
+        x1+=dx1*i;
+        x2+=dx2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dy2++) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1--;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dy2=p2->y-p4->y) {
+        dx2=(p4->x-p2->x)<<32/dy2;
+        dz2=(p4->z-p2->z)<<32/dy2;
+        if (y1+dy2<min) {
+          i=min-(y1+dy2);
+          if (i>-dy2) goto ft_done;
+          dy2+=i;
+        }
+        if (y1>=max) {
+          i=y1-max+1;
+          if (i>-dy2) goto ft_done;
+          dy2+=i;
+          y1-=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dy2++<=0) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1--;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else if ((dy2=p2->y-p1->y)>0) {
+      dy1=p4->y-p1->y;
+      dx1=(p4->x-p1->x)<<32/dy1;
+      dz1=(p4->z-p1->z)<<32/dy1;
+
+      dx2=(p2->x-p1->x)<<32/dy2;
+      dz2=(p2->z-p1->z)<<32/dy2;
+      x1=x2=p1->x<<32; y1=p1->y; z1=z2=p1->z<<32;
+      if (y1+dy2>=max) {
+        i=y1+dy2-max+1;
+        if (i>dy2) goto ft_done;
+        dy2-=i;
+      }
+      if (y1<min) {
+        i=min-y1;
+        if (i>dy2)
+          i=dy2;
+        dy2-=i;
+        y1+=i;
+        x1+=dx1*i;
+        x2+=dx2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dy2--) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1++;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dy2=p4->y-p2->y) {
+        dx2=(p4->x-p2->x)<<32/dy2;
+        dz2=(p4->z-p2->z)<<32/dy2;
+        if (y1+dy2>=max) {
+          i=y1+dy2-max+1;
+          if (i>dy2) goto ft_done;
+          dy2-=i;
+        }
+        if (y1<min) {
+          i=min-y1;
+          if (i>dy2) goto ft_done;
+          dy2-=i;
+          y1+=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dy2-->=0) {
+        res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+        y1++;
+        x1+=dx1;
+        x2+=dx2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else {
+      if (dy1=p2->y-p1->y) {
+        dx1=(p2->x-p1->x)<<32/dy1;
+        dz1=(p2->z-p1->z)<<32/dy1;
+        if (dy2=p2->y-p4->y) {
+          dx2=(p2->x-p4->x)<<32/dy2;
+          dz2=(p2->z-p4->z)<<32/dy2;
+        } else {
+          dx2=0;
+          dz2=0;
+        }
+        x1=x2=p2->x<<32; y1=p2->y; z1=z2=p2->z<<32;
+        if (y1<min) {
+          i=min-y1;
+          if (i>-dy1)
+            i=-dy1;
+          dy1+=i;
+          y1+=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dy1++<=0) {
+          if (y1<max)
+            res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+          y1++;
+          x1+=dx1;
+          x2+=dx2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+      if (dy1=p4->y-p1->y) {
+        dx1=(p1->x-p4->x)<<32/dy1;
+        dz1=(p1->z-p4->z)<<32/dy1;
+        if (dy2=p4->y-p2->y) {
+          dx2=(p2->x-p4->x)<<32/dy2;
+          dz2=(p2->z-p4->z)<<32/dy2;
+        } else {
+          dx2=0;
+          dz2=0;
+        }
+        x1=x2=p4->x<<32; y1=p4->y; z1=z2=p4->z<<32;
+        if (y1-dy1<min) {
+          i=min-(y1-dy1);
+          if (i>dy1) goto ft_done;
+          dy1-=i;
+        }
+        if (y1>=max) {
+          i=y1-max+1;
+          if (i>dy1) goto ft_done;
+          dy1-=i;
+          y1-=i;
+          x1+=dx1*i;
+          x2+=dx2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dy1-->=0) {
+          res+=GrHLine(dc,x1.i32[1],x2.i32[1],y1,z1.i32[1],z2.i32[1]);
+          y1--;
+          x1+=dx1;
+          x2+=dx2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+    }
+  } else {
+//p1 is min y
+    if (p4->y<p2->y)
+      SwapI64(&p4,&p2);
+    if (p2->y<p1->y)
+      SwapI64(&p2,&p1);
+
+      //p2x<=p4x
+    if (p4->x<p2->x)
+      SwapI64(&p4,&p2);
+
+    min=0;
+    max=dc->width;
+    if (dc->flags & DCF_SCRN_BITMAP) {
+      win_task=dc->win_task;
+      min-=win_task->scroll_x+win_task->pix_left;
+      max-=win_task->scroll_x+win_task->pix_left;
+      if (max>win_task->pix_right-(win_task->scroll_x+win_task->pix_left))
+        max=win_task->pix_right-(win_task->scroll_x+win_task->pix_left);
+    }
+
+    if ((dx2=p4->x-p1->x)<0) {
+      dx1=p2->x-p1->x;
+      dy1=(p1->y-p2->y)<<32/dx1;
+      dz1=(p1->z-p2->z)<<32/dx1;
+
+      dy2=(p1->y-p4->y)<<32/dx2;
+      dz2=(p1->z-p4->z)<<32/dx2;
+      y1=y2=p1->y<<32; x1=p1->x; z1=z2=p1->z<<32;
+      if (x1+dx2<min) {
+        i=min-(x1+dx2);
+        if (i>-dx2) goto ft_done;
+        dx2+=i;
+      }
+      if (x1>=max) {
+        i=x1-max+1;
+        if (i>-dx2)
+          i=-dx2;
+        dx2+=i;
+        x1-=i;
+        y1+=dy1*i;
+        y2+=dy2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dx2++) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1--;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dx2=p2->x-p4->x) {
+        dy2=(p4->y-p2->y)<<32/dx2;
+        dz2=(p4->z-p2->z)<<32/dx2;
+        if (x1+dx2<min) {
+          i=min-(x1+dx2);
+          if (i>-dx2) goto ft_done;
+          dx2+=i;
+        }
+        if (x1>=max) {
+          i=x1-max+1;
+          if (i>-dx2) goto ft_done;
+          dx2+=i;
+          x1-=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dx2++<=0) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1--;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else if ((dx2=p2->x-p1->x)>0) {
+      dx1=p4->x-p1->x;
+      dy1=(p4->y-p1->y)<<32/dx1;
+      dz1=(p4->z-p1->z)<<32/dx1;
+
+      dy2=(p2->y-p1->y)<<32/dx2;
+      dz2=(p2->z-p1->z)<<32/dx2;
+      y1=y2=p1->y<<32; x1=p1->x; z1=z2=p1->z<<32;
+      if (x1+dx2>=max) {
+        i=x1+dx2-max+1;
+        if (i>dx2) goto ft_done;
+        dx2-=i;
+      }
+      if (x1<min) {
+        i=min-x1;
+        if (i>dx2)
+          i=dx2;
+        dx2-=i;
+        x1+=i;
+        y1+=dy1*i;
+        y2+=dy2*i;
+        z1+=dz1*i;
+        z2+=dz2*i;
+      }
+      while (dx2--) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1++;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+      if (dx2=p4->x-p2->x) {
+        dy2=(p4->y-p2->y)<<32/dx2;
+        dz2=(p4->z-p2->z)<<32/dx2;
+        if (x1+dx2>=max) {
+          i=x1+dx2-max+1;
+          if (i>dx2) goto ft_done;
+          dx2-=i;
+        }
+        if (x1<min) {
+          i=min-x1;
+          if (i>dx2) goto ft_done;
+          dx2-=i;
+          x1+=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+      }
+      while (dx2-->=0) {
+        res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+        x1++;
+        y1+=dy1;
+        y2+=dy2;
+        z1+=dz1;
+        z2+=dz2;
+      }
+    } else {
+      if (dx1=p2->x-p1->x) {
+        dy1=(p2->y-p1->y)<<32/dx1;
+        dz1=(p2->z-p1->z)<<32/dx1;
+        if (dx2=p2->x-p4->x) {
+          dy2=(p2->y-p4->y)<<32/dx2;
+          dz2=(p2->z-p4->z)<<32/dx2;
+        } else {
+          dy2=0;
+          dz2=0;
+        }
+        y1=y2=p2->y<<32; x1=p2->x; z1=z2=p2->z<<32;
+        if (x1<min) {
+          i=min-x1;
+          if (i>-dx1)
+            i=-dx1;
+          dx1+=i;
+          x1+=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dx1++<=0) {
+          if (x1<max)
+            res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+          x1++;
+          y1+=dy1;
+          y2+=dy2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+      if (dx1=p4->x-p1->x) {
+        dy1=(p1->y-p4->y)<<32/dx1;
+        dz1=(p1->z-p4->z)<<32/dx1;
+        if (dx2=p4->x-p2->x) {
+          dy2=(p2->y-p4->y)<<32/dx2;
+          dz2=(p2->z-p4->z)<<32/dx2;
+        } else {
+          dy2=0;
+          dz2=0;
+        }
+        y1=y2=p4->y<<32; x1=p4->x; z1=z2=p4->z<<32;
+        if (x1-dx1<min) {
+          i=min-(x1-dx1);
+          if (i>dx1) goto ft_done;
+          dx1-=i;
+        }
+        if (x1>=max) {
+          i=x1-max+1;
+          if (i>dx1) goto ft_done;
+          dx1-=i;
+          x1-=i;
+          y1+=dy1*i;
+          y2+=dy2*i;
+          z1+=dz1*i;
+          z2+=dz2*i;
+        }
+        while (dx1-->=0) {
+          res+=GrVLine(dc,x1,y1.i32[1],y2.i32[1],z1.i32[1],z2.i32[1]);
+          x1--;
+          y1+=dy1;
+          y2+=dy2;
+          z1+=dz1;
+          z2+=dz2;
+        }
+      }
+    }
+  }
+ft_done:
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrScrn.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrScrn.HC.HTML new file mode 100755 index 0000000..2eba4fb --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrScrn.HC.HTML @@ -0,0 +1,454 @@ + + + + + + + + + + + +
+#help_index "Graphics/Scrn"
+
+U0 GrUpdateTaskODEs(CTask *task)
+{
+  sys_task_being_scrn_updated=task;
+  try
+    ODEsUpdate(task);
+  catch {
+    LBts(&task->win_inhibit,WIf_SELF_ODE);
+    "Exception in WinMgr: Update Task ODEs\n";
+    PutExcept;
+    Sleep(3000);
+    VGAFlush;
+  }
+  sys_task_being_scrn_updated=NULL;
+}
+
+U0 GrUpdateTaskWin(CTask *task)
+{ //Draw a win.  Only Core0 tasks have a win.
+  CDC *dc;
+  CD3I64 saved_scroll;
+  sys_task_being_scrn_updated=task;
+  try {
+    if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER))
+      TextBorder(Fs,task->win_left,task->win_right,task->win_top,
+            task->win_bottom,task->border_attr,task==sys_focus_task);
+    TextRect(task->win_left,task->win_right,
+          task->win_top,task->win_bottom,task->text_attr<<8);
+    if (task==sys_winmgr_task) {
+      if (gr.fp_wall_paper)
+        (*gr.fp_wall_paper)(task);
+    } else if (!(task->win_inhibit&WIF_SELF_DOC))
+      DocUpdateTaskDocs(task);
+    if (TaskValidate(task)) {
+      if (task->draw_it) {
+        dc=DCAlias(gr.dc2,task);
+        (*task->draw_it)(task,dc);
+        DCDel(dc);
+      }
+      if (TaskValidate(task)) {
+        WinScrollNull(task,&saved_scroll);
+        DrawCtrls(task);
+        WinScrollRestore(task,&saved_scroll);
+      }
+    }
+  } catch {
+    if (task!=Fs && TaskValidate(task)) {
+      LBtr(&task->display_flags,DISPLAYf_SHOW);
+      "Exception in WinMgr: Update Task Win\n";
+      PutExcept;
+      Sleep(3000);
+      VGAFlush;
+    }
+  }
+  sys_task_being_scrn_updated=NULL;
+}
+
+U0 GrUpdateTasks()
+{//Only called by WinMgr
+  I64 i;
+  CTask *task,*task1;
+  try {
+    winmgr.ode_time=0;
+    if (Bt(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0))
+      WinZBufUpdate;
+    task1=task=sys_winmgr_task;
+    do { //Loop through Core0 tasks.
+      if (!TaskValidate(task)) break;
+      if (Bt(&task->display_flags,DISPLAYf_SHOW) &&
+            Bt(gr.win_uncovered_bitmap,task->win_z_num))
+        GrUpdateTaskWin(task);
+      if (!TaskValidate(task)) break;
+      task=task->next_task;
+    } while (task!=task1);
+
+    for (i=0;i<mp_cnt;i++) { //Loop through all cores.
+      task1=task=cpu_structs[i].seth_task;
+      do {
+        if (!TaskValidate(task)) break;
+        GrUpdateTaskODEs(task);
+        if (!TaskValidate(task)) break;
+        task=task->next_task;
+      } while (task!=task1);
+    }
+  } catch {
+    PutExcept(FALSE);
+    Dbg("Exception in WinMgr");
+  }
+  winmgr.last_ode_time=winmgr.ode_time;
+  ode_alloced_factor=LowPass1(0.1,ode_alloced_factor,
+        Clamp(Gs->idle_factor-0.1,0.2,0.8),1/winmgr.fps);
+  sys_task_being_scrn_updated=NULL;
+}
+
+U0 GrFixZoomScale()
+{
+  gr.scrn_zoom=ClampI64(gr.scrn_zoom,1,GR_SCRN_ZOOM_MAX);
+  if (gr.scrn_zoom==1) {
+    gr.sx=0;
+    gr.sy=0;
+  } else {
+    gr.sx=ClampI64(gr.sx,0,GR_WIDTH-GR_WIDTH/gr.scrn_zoom)&~7;
+    gr.sy=ClampI64(gr.sy,0,GR_HEIGHT-GR_HEIGHT/gr.scrn_zoom);
+  }
+}
+
+public U0 GrScaleZoom(F64 scale)
+{//Multiply zoom factor larger or smaller.
+  F64 s=gr.scrn_zoom;
+  gr.scrn_zoom=gr.scrn_zoom*scale;
+  GrFixZoomScale;
+  s/=gr.scrn_zoom;
+  ms.scale.x*=s;
+  ms.scale.y*=s;
+  ms.scale.z*=s;
+  ms.offset.x=ms.pos.x-(ms.pos.x-ms.offset.x)*s;
+  ms.offset.y=ms.pos.y-(ms.pos.y-ms.offset.y)*s;
+  ms.offset.z=ms.pos.z-(ms.pos.z-ms.offset.z)*s;
+  gr.sx=ms.pos.x-gr.zoomed_dc->width >>1/gr.scrn_zoom;
+  gr.sy=ms.pos.y-gr.zoomed_dc->height>>1/gr.scrn_zoom;
+  GrFixZoomScale;
+}
+
+U0 GrZoomInScrn()
+{
+  GrFixZoomScale;
+  I64 plane,row,col,k,l,
+        d2=gr.zoomed_dc->width>>3/gr.scrn_zoom,
+        d4=gr.zoomed_dc->width_internal>>3,
+        d5=d4-d2*gr.scrn_zoom,
+        d3=gr.zoomed_dc->height/gr.scrn_zoom,
+        d6=(gr.zoomed_dc->height-d3)*gr.dc1->width_internal>>3,
+        d7=gr.zoomed_dc->height%gr.scrn_zoom*d4;
+  U8 *src,*src2,*dst,*src3,*map=gr.scrn_zoom_tables[gr.scrn_zoom];
+
+  src=gr.dc1->body+gr.sx>>3+gr.sy*gr.dc1->width_internal>>3;
+  dst=gr.zoomed_dc->body;
+  for (plane=1;plane<0x10;plane<<=1) {
+    row=d3;
+    while (row--) {
+      k=gr.scrn_zoom;
+      while (k--) {
+        src2=src;
+        col=d2;
+        while (col--) {
+          src3=&map[*src2++];
+          l=gr.scrn_zoom;
+          while (l--) {
+            *dst++=*src3;
+            src3+=256;
+          }
+        }
+        l=d5;
+        while (l--)
+          *dst++=0;
+      }
+      src+=d4;
+    }
+    l=d7;
+    while (l--)
+      *dst++=0;
+    src+=d6;
+  }
+}
+
+U0 GrUpdateTextBG()
+{
+  I64 reg RSI *dst=gr.dc2->body,reg R13 c,row,col,
+        num_rows=TEXT_ROWS,num_cols=TEXT_COLS,i,j,cur_ch,
+        reg R12 w1=gr.dc2->width_internal,w2=-7*w1+8,w3=7*w1,w4=0;
+  U32 *src=gr.text_base;
+  Bool blink_flag=Blink;
+  U8 *dst2=dst;
+
+  if (gr.pan_text_x||gr.hide_col) {
+    gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
+    j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
+    num_cols-=j;
+    if (gr.pan_text_x<0) {
+      src+=j;
+      i=FONT_WIDTH*j+gr.pan_text_x;
+    } else
+      i=gr.pan_text_x;
+    dst2=dst(U8 *)+i;
+    w4=j;
+    w3+=j*FONT_WIDTH;
+
+    j*=FONT_WIDTH;
+    dst(U8 *)=gr.dc2->body;
+    for (row=num_rows*FONT_HEIGHT;row--;) {
+      for (col=i;col--;)
+        *dst(U8 *)++=0;
+      dst(U8 *)+=w1-i-j;
+      for (col=j;col--;)
+        *dst(U8 *)++=0;
+    }
+  }
+  dst=dst2;
+
+  if (gr.pan_text_y||gr.hide_row) {
+    gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
+    j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
+    num_rows-=j;
+    if (gr.pan_text_y<0) {
+      src+=w1/FONT_WIDTH*j;
+      i=w1*(FONT_HEIGHT*j+gr.pan_text_y);
+    } else
+      i=w1*gr.pan_text_y;
+    dst2=dst(U8 *)+i;
+
+    j*=w1*FONT_HEIGHT;
+    dst(U8 *)=gr.dc2->body;
+    for (row=i;row--;)
+      *dst(U8 *)++=0;
+    dst(U8 *)=gr.dc2->body+TEXT_ROWS*TEXT_COLS*FONT_HEIGHT*FONT_WIDTH-j;
+    for (row=j;row--;)
+      *dst(U8 *)++=0;
+  }
+  dst=dst2;
+
+  for (row=num_rows;row--;) {
+    for (col=num_cols;col--;) {
+      cur_ch=*src++;
+      if (cur_ch & (ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
+        if (cur_ch & ATTRF_SEL)
+          cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+        if (cur_ch & ATTRF_INVERT)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+        if (cur_ch & ATTRF_BLINK && blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      }
+      c=gr.to_8_colors[cur_ch.u8[1]>>4];
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      ADD       RSI,R12
+      MOV       U64 [RSI],R13
+      dst(U8 *)+=w2;
+    }
+    src+=w4;
+    dst(U8 *)+=w3;
+  }
+}
+
+U0 GrUpdateTextFG()
+{//See TextBase Layer.
+  U32 *src=gr.text_base;
+  I64 i,j,cur_ch,*dst=gr.dc2->body,
+        w1=gr.dc2->width_internal,w2=7*w1,w4=0,
+        num_rows=TEXT_ROWS,num_cols=TEXT_COLS,row,col;
+  U8 *dst_start=gr.dc2->body,*dst_end=dst_start+w1*gr.dc2->height-7*w1-8;
+  Bool blink_flag=Blink;
+
+  if (gr.pan_text_x||gr.hide_col) {
+    gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
+    j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
+    num_cols-=j;
+    if (gr.pan_text_x<0) {
+      src+=j;
+      dst(U8 *)+=FONT_WIDTH*j;
+    }
+    w4=j;
+    w2+=j*FONT_WIDTH;
+  }
+
+  if (gr.pan_text_y||gr.hide_row) {
+    gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
+    j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
+    num_rows-=j;
+    if (gr.pan_text_y<0) {
+      src+=w1/FONT_WIDTH*j;
+      dst(U8 *)+=w1*FONT_HEIGHT*j;
+    }
+  }
+
+  for (row=num_rows;row--;) {
+    for (col=num_cols;col--;) {
+      cur_ch=*src++;
+      if (cur_ch & (ATTRF_UNDERLINE|ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
+        if (cur_ch & ATTRF_SEL)
+          cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+        if (cur_ch & ATTRF_INVERT)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+        if (cur_ch & ATTRF_BLINK && blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      }
+      if (i=cur_ch.u16[1]&0x3FF+gr.pan_text_x+gr.pan_text_y<<5) {
+        j=i&0x1F;
+        if (j&0x10) j|=~0x1F;
+        i>>=5;
+        if (i&0x10) i|=~0x1F;
+        i=w1*i+j;
+        if (dst_start<=dst(U8 *)+i<dst_end)
+          GrRopEquU8NoClipping(cur_ch&(ATTRF_UNDERLINE+0xFFF),dst(U8 *)+i,w1);
+      } else
+        GrRopEquU8NoClipping(cur_ch&(ATTRF_UNDERLINE+0xFFF),dst,w1);
+      dst(U8 *)+=8;
+    }
+    src+=w4;
+    dst(U8 *)+=w2;
+  }
+}
+
+U0 DCBlotColor8(CDC *dc,CDC *img)
+{
+  U8  *src=img->body,*b0=dc->body;
+  I64 j,k,d0=img->width_internal*img->height;
+  for (k=0;k<d0;k++) {
+    j=*src++;
+    if (j!=TRANSPARENT)
+      *b0++=j;
+    else
+      b0++;
+  }
+}
+
+U0 GrUpdateTextModeText()
+{
+  U32 *src=gr.text_base;
+  I64 cur_ch,i=TEXT_COLS*TEXT_ROWS;
+  U16 *dst=text.vga_text_alias,*dst2=gr.vga_text_cache;
+  Bool blink_flag=Blink;
+  if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
+    while (i--) {
+      cur_ch=*src++;
+      if (cur_ch & ATTRF_SEL)
+        cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+      if (cur_ch & ATTRF_INVERT)
+        cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      if (cur_ch & ATTRF_BLINK)
+        if (blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      *dst++=*dst2++=cur_ch&0x7FFF;
+    }
+  } else {
+    while (i--) {
+      cur_ch=*src++;
+      if (cur_ch & ATTRF_SEL)
+        cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
+      if (cur_ch & ATTRF_INVERT)
+        cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      if (cur_ch & ATTRF_BLINK)
+        if (blink_flag)
+          cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
+      cur_ch&=0x7FFF;
+      if (*dst2!=cur_ch)
+        *dst++=*dst2++=cur_ch;
+      else {
+        dst++;
+        dst2++;
+      }
+    }
+  }
+}
+
+U0 GrUpdateVGAGraphics()
+{//Update Graphic Card
+  I64 row,plane,d=gr.zoomed_dc->width_internal>>6;
+  U32 *src,*vga,*dst;
+  if (gr.scrn_zoom==1)
+    src=gr.dc1->body;
+  else {
+    GrZoomInScrn;
+    src=gr.zoomed_dc->body;
+  }
+  dst=gr.scrn_image->body;
+  if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
+    for (plane=1;plane<0x10;plane<<=1) {
+      OutU8(VGAP_IDX,VGAR_MAP_MASK);
+      OutU8(VGAP_DATA,plane);
+      vga=text.vga_alias;
+      row=gr.zoomed_dc->height;
+      while (row--)
+        GrUpdateLine64FlushCache(&vga,&src,d,&dst);
+    }
+  } else {
+    for (plane=1;plane<0x10;plane<<=1) {
+      OutU8(VGAP_IDX,VGAR_MAP_MASK);
+      OutU8(VGAP_DATA,plane);
+      vga=text.vga_alias;
+      row=gr.zoomed_dc->height;
+      while (row--)
+        GrUpdateLine64(&vga,&src,d,&dst);
+    }
+  }
+}
+
+U0 GrUpdateScrn()
+{//Called by the Window Manager HERE, 30 times a second.
+  CDC *dc;
+  if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
+    GrUpdateTasks;
+  else {
+    GrUpdateTextBG;
+    GrUpdateTextFG;
+    GrUpdateTasks;
+    DCBlotColor8(gr.dc2,gr.dc);
+  }
+
+  dc=DCAlias(gr.dc2,Fs);
+  dc->flags|=DCF_ON_TOP;
+  if (gr.fp_final_scrn_update)
+    (*gr.fp_final_scrn_update)(dc);
+  DCDel(dc);
+
+  if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
+    GrUpdateTextModeText;
+  else {
+    DCBlotColor4(gr.dc1->body,gr.dc2->body,gr.dc_cache->body,
+          gr.dc2->height*gr.dc2->width_internal>>3);
+    GrUpdateVGAGraphics;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrSpritePlot.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrSpritePlot.HC.HTML new file mode 100755 index 0000000..376a839 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrSpritePlot.HC.HTML @@ -0,0 +1,506 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+/*
+CSprites are stored as a sequence of var
+length operations with a 1-byte type leading
+each operation.  They are stored, one after another,
+in a chunk of memory terminated by a zero.
+Sprite3() shows how the CSprite unions are used.
+
+SpriteElemSize() will return the size of a single
+element, while SpriteSize() will return the size
+of an entire list.  Look at sprite_elem_base_sizes.
+
+See ::/Apps/GrModels for an example of
+making CSprite by hand.  It uses SPT_MESH,
+one of the most complicated.
+*/
+
+public U0 Sprite3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,
+        Bool just_one_elem=FALSE)
+{//Plot a sprite into a CDC.
+  CSprite *tmpg=elems-offset(CSprite.start);
+  I64 i,j,k,x1,y1,z1,x2,y2,
+        *old_r,*r2,old_flags=dc->flags,old_pen_width=dc->thick;
+  I32 *ptr;
+  CColorROPU32 old_color=dc->color;
+  CDC *img;
+  CD3I32 *p,*p2;
+  CGrSym old_sym;
+  MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));
+  if (dc->flags & DCF_LOCATE_NEAREST)
+    dc->nearest_dist=I64_MAX;
+  while (tmpg->type&SPG_TYPE_MASK) {
+    switch (tmpg->type&SPG_TYPE_MASK) {
+      case SPT_COLOR:
+        dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tmpg->c.color;
+        break;
+      case SPT_DITHER_COLOR:
+        dc->color=dc->color&~COLORROP_COLORS_MASK|
+              tmpg->d.dither_color.u8[0]|
+              tmpg->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER;
+        break;
+      case SPT_THICK:
+        dc->thick=tmpg->t.thick;
+        DCThickScale(dc);
+        break;
+      case SPT_TRANSFORM_ON:
+        if (!(dc->flags&DCF_TRANSFORMATION)) {
+          x-=dc->x;
+          y-=dc->y;
+          z-=dc->z;
+        }
+        dc->flags|=DCF_TRANSFORMATION;
+        break;
+      case SPT_TRANSFORM_OFF:
+        if (dc->flags&DCF_TRANSFORMATION) {
+          x+=dc->x;
+          y+=dc->y;
+          z+=dc->z;
+        }
+        dc->flags&=~DCF_TRANSFORMATION;
+        break;
+      case SPT_PT:
+        GrPlot3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z);
+        break;
+      case SPT_TEXT:
+        GrPrint3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,"%s",tmpg->ps.st);
+        break;
+      case SPT_TEXT_BOX:
+        GrTextBox3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
+        break;
+      case SPT_TEXT_DIAMOND:
+        GrTextDiamond3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
+        break;
+      case SPT_FLOOD_FILL:
+        GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,FALSE);
+        break;
+      case SPT_FLOOD_FILL_NOT:
+        i=dc->color;
+        dc->color=dc->color.c0;
+        GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,TRUE);
+        dc->color=i;
+        break;
+      case SPT_SHIFT:
+        x+=tmpg->p.x1;
+        y+=tmpg->p.y1;
+        break;
+      case SPT_LINE:
+        GrLine3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z);
+        break;
+      case SPT_ARROW:
+        GrArrow3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z);
+        break;
+      case SPT_PLANAR_SYMMETRY:
+        if (DCSymmetry3Set(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z,
+              tmpg->pp.x2+x,tmpg->pp.y2+y,z+1))
+          dc->flags|=DCF_SYMMETRY;
+        else
+          dc->flags&=~DCF_SYMMETRY;
+        break;
+      case SPT_BITMAP:
+        img=CAlloc(sizeof(CDC));
+        img->width=tmpg->pwhu.width;
+        img->width_internal=(tmpg->pwhu.width+7)&~7;
+        img->height=tmpg->pwhu.height;
+        img->body=&tmpg->pwhu.u;
+        img->dc_signature=DCS_SIGNATURE_VAL;
+        GrBlot3(dc,tmpg->pwhu.x1+x,tmpg->pwhu.y1+y,z,img);
+        Free(img);
+        break;
+      case SPT_RECT:
+        GrRect3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
+              tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
+        break;
+      case SPT_ROTATED_RECT:
+        x1=tmpg->ppa.x1+x;
+        y1=tmpg->ppa.y1+y;
+        z1=z;
+        Mat4x4MulXYZ(dc->r,&x1,&y1,&z1);
+        old_r=dc->r;
+        dc->flags|=DCF_TRANSFORMATION;
+        r2=Mat4x4IdentNew;
+        Mat4x4RotZ(r2,-tmpg->ppa.angle);
+        Mat4x4TranslationEqu(r2,x1,y1,z1);
+        DCMat4x4Set(dc,Mat4x4MulMat4x4New(old_r,r2));
+        GrRect3(dc,0,0,0,
+              tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1);
+        Free(dc->r);
+        Free(r2);
+        DCMat4x4Set(dc,old_r);
+        dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
+        break;
+      case SPT_CIRCLE:
+        GrCircle3(dc,tmpg->pr.x1+x,tmpg->pr.y1+y,z,tmpg->pr.radius);
+        break;
+      case SPT_ELLIPSE:
+        GrEllipse3(dc,tmpg->pwha.x1+x,tmpg->pwha.y1+y,z,tmpg->pwha.width,
+              tmpg->pwha.height,tmpg->pwha.angle);
+        break;
+      case SPT_POLYGON:
+        GrRegPoly3(dc,tmpg->pwhas.x1+x,tmpg->pwhas.y1+y,z,tmpg->pwhas.width,
+              tmpg->pwhas.height,tmpg->pwhas.sides,tmpg->pwhas.angle);
+        break;
+      case SPT_POLYLINE:
+        ptr=&tmpg->nu.u;
+        x1=ptr[0];
+        y1=ptr[1];
+        for (i=1;i<tmpg->nu.num;i++) {
+          x2=ptr[i<<1];
+          y2=ptr[i<<1+1];
+          GrLine3(dc,x1+x,y1+y,z,x2+x,y2+y,z);
+          x1=x2;y1=y2;
+        }
+        break;
+      case SPT_POLYPT:
+        x1=tmpg->npu.x;
+        y1=tmpg->npu.y;
+        ptr=&tmpg->npu.u;
+        k=tmpg->npu.num*3;
+        GrPlot3(dc,x1+x,y1+y,z);
+        for (i=0;i<k;i+=3) {
+          j=BFieldExtU32(ptr,i,3);
+          x1+=gr_x_offsets[j];
+          y1+=gr_y_offsets[j];
+          GrPlot3(dc,x1+x,y1+y,z);
+        }
+        break;
+      start:
+        p2=p=MAlloc(tmpg->nu.num*sizeof(CD3I32));
+        MemCpy(p,&tmpg->nu.u,tmpg->nu.num*sizeof(CD3I32));
+        for (i=0;i<tmpg->nu.num;i++,p2++) {
+          p2->x+=x;
+          p2->y+=y;
+          p2->z+=z;
+        }
+        case SPT_BSPLINE2:
+          Gr2BSpline3(dc,p,tmpg->nu.num,FALSE);
+          break;
+        case SPT_BSPLINE3:
+          Gr3BSpline3(dc,p,tmpg->nu.num,FALSE);
+          break;
+        case SPT_BSPLINE2_CLOSED:
+          Gr2BSpline3(dc,p,tmpg->nu.num,TRUE);
+          break;
+        case SPT_BSPLINE3_CLOSED:
+          Gr3BSpline3(dc,p,tmpg->nu.num,TRUE);
+          break;
+      end:
+        Free(p);
+        break;
+      case SPT_MESH:
+        p2=p=MAlloc(tmpg->mu.vertex_cnt*sizeof(CD3I32));
+        MemCpy(p,&tmpg->mu.u,tmpg->mu.vertex_cnt*sizeof(CD3I32));
+        for (i=0;i<tmpg->mu.vertex_cnt;i++,p2++) {
+          p2->x+=x;
+          p2->y+=y;
+          p2->z+=z;
+        }
+        Gr3Mesh(dc,tmpg->mu.vertex_cnt,p,tmpg->mu.tri_cnt,
+              (&tmpg->mu.u)(U8 *)+sizeof(CD3I32)*tmpg->mu.vertex_cnt);
+        Free(p);
+        break;
+      case SPT_SHIFTABLE_MESH:
+        if (dc->flags&DCF_TRANSFORMATION) {
+          dc->x+=tmpg->pmu.x;
+          dc->y+=tmpg->pmu.y;
+          dc->z+=tmpg->pmu.z;
+          x1=x;
+          y1=y;
+          z1=z;
+        } else {
+          x1=tmpg->pmu.x+x;
+          y1=tmpg->pmu.y+y;
+          z1=tmpg->pmu.z+z;
+        }
+        p2=p=MAlloc(tmpg->pmu.vertex_cnt*sizeof(CD3I32));
+        MemCpy(p,&tmpg->pmu.u,tmpg->pmu.vertex_cnt*sizeof(CD3I32));
+        for (i=0;i<tmpg->pmu.vertex_cnt;i++,p2++) {
+          p2->x+=x1;
+          p2->y+=y1;
+          p2->z+=z1;
+        }
+        Gr3Mesh(dc,tmpg->pmu.vertex_cnt,p,tmpg->pmu.tri_cnt,
+              (&tmpg->pmu.u)(U8 *)+sizeof(CD3I32)*tmpg->pmu.vertex_cnt);
+        Free(p);
+        if (dc->flags&DCF_TRANSFORMATION) {
+          dc->x-=tmpg->pmu.x;
+          dc->y-=tmpg->pmu.y;
+          dc->z-=tmpg->pmu.z;
+        }
+        break;
+    }
+    if (just_one_elem) break;
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+  MemCpy(&dc->sym,&old_sym,sizeof(CGrSym));
+  dc->color=old_color;
+  dc->thick=old_pen_width;
+  dc->flags=dc->flags&~(DCF_SYMMETRY|DCF_TRANSFORMATION) |
+        old_flags&(DCF_SYMMETRY|DCF_TRANSFORMATION);
+}
+
+public U0 Sprite3B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems)
+{//Plot a sprite into a CDC, post transform xyz translation.
+  I64 old_x=dc->x,old_y=dc->y,old_z=dc->z,
+        old_flags=dc->flags&DCF_TRANSFORMATION;
+  dc->x=x; dc->y=y; dc->z=z;
+  dc->flags|=DCF_TRANSFORMATION;
+  Sprite3(dc,0,0,0,elems);
+  dc->x=old_x; dc->y=old_y; dc->z=old_z;
+  dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
+}
+
+public U0 Sprite3Mat4x4B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)
+{//Plot rotated by matrix.
+  I64 r[16],*old_r=dc->r,new_m[16],
+        old_flags=dc->flags&DCF_TRANSFORMATION;
+  MemCpy(new_m,m,16*sizeof(I64));
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4TranslationAdd(new_m,x,y,z);
+  dc->r=Mat4x4MulMat4x4Equ(r,old_r,new_m);
+  Sprite3(dc,0,0,0,elems);
+  dc->r=old_r;
+  dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
+}
+
+public U0 Sprite3XB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 phi=0)
+{//Plot rotated around X axis.
+  I64 r[16];
+  Mat4x4IdentEqu(r);
+  Mat4x4RotX(r,phi);
+  Sprite3Mat4x4B(dc,x,y,z,elems,r);
+}
+
+public U0 Sprite3YB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 omega=0)
+{//Plot rotated around Y axis.
+  I64 r[16];
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,omega);
+  Sprite3Mat4x4B(dc,x,y,z,elems,r);
+}
+
+public U0 Sprite3ZB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 theta=0)
+{//Plot rotated around Z axis.
+  I64 r[16];
+  Mat4x4IdentEqu(r);
+  Mat4x4RotZ(r,theta);
+  Sprite3Mat4x4B(dc,x,y,z,elems,r);
+}
+
+public U0 SpriteExtents(U8 *elems,I64 *min_x=NULL,I64 *max_x=NULL,
+                                   I64 *min_y=NULL,I64 *max_y=NULL)
+{//Ignores flood fills.
+  CDC *dc=DCNew(I32_MAX,I32_MAX,Fs,TRUE);
+  DCExtentsInit(dc);
+  Sprite3(dc,I32_MAX/2,I32_MAX/2,I32_MAX/2,elems);
+  if (dc->min_x<=dc->max_x) {
+    dc->min_x-=I32_MAX/2;
+    dc->max_x-=I32_MAX/2;
+  }
+  if (dc->min_y<=dc->max_y) {
+    dc->min_y-=I32_MAX/2;
+    dc->max_y-=I32_MAX/2;
+  }
+  if (min_x) *min_x=dc->min_x;
+  if (max_x) *max_x=dc->max_x;
+  if (min_y) *min_y=dc->min_y;
+  if (max_y) *max_y=dc->max_y;
+  DCDel(dc);
+}
+
+public CDC *Sprite2DC(U8 *elems)
+{//Convert sprite to device context.
+  CDC *res;
+  I64 min_x,max_x,min_y,max_y;
+  SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);
+  res=DCNew(max_x-min_x+1,max_y-min_y+1);
+  Sprite3(res,-min_x,-min_y,0,elems);
+  return res;
+}
+
+public U8 *SpriteInterpolate(F64 t,U8 *elems0,U8 *elems1)
+{//The two CSprite should be ident except for points shifted around.
+//t ranges from 0.0 to 1.0.
+  I64 i,t1=GR_SCALE*t,t0=GR_SCALE-t1;
+  I32 *ptr0,*ptr1,*ptrr;
+  CD3I32 *p0,*p1,*pr;
+  U8 *res;
+  CSprite *tmpg0=elems0-offset(CSprite.start),
+        *tmpg1=elems1-offset(CSprite.start),*tmpgr;
+  if (t<0.5) {
+    i=SpriteSize(elems0),
+          res=MAlloc(i);
+    MemCpy(res,elems0,i);
+  } else {
+    i=SpriteSize(elems1),
+          res=MAlloc(i);
+    MemCpy(res,elems1,i);
+  }
+  tmpgr=res-offset(CSprite.start);
+  while (tmpg0->type&SPG_TYPE_MASK) {
+    if (tmpg0->type&SPG_TYPE_MASK!=tmpg1->type&SPG_TYPE_MASK)
+      throw('Graphics');
+    switch (tmpg0->type&SPG_TYPE_MASK) {
+      case SPT_ROTATED_RECT:
+        tmpgr->ppa.angle=(tmpg0->ppa.angle*t0+tmpg1->ppa.angle*t1)/GR_SCALE;
+      case SPT_RECT:
+      case SPT_LINE:
+      case SPT_ARROW:
+      case SPT_PLANAR_SYMMETRY:
+        tmpgr->pp.x2=(tmpg0->pp.x2*t0+tmpg1->pp.x2*t1)>>32;
+        tmpgr->pp.y2=(tmpg0->pp.y2*t0+tmpg1->pp.y2*t1)>>32;
+      case SPT_TEXT:
+      case SPT_TEXT_BOX:
+      case SPT_TEXT_DIAMOND:
+      case SPT_PT:
+      case SPT_FLOOD_FILL:
+      case SPT_FLOOD_FILL_NOT:
+      case SPT_SHIFT:
+        tmpgr->p.x1=(tmpg0->p.x1*t0+tmpg1->p.x1*t1)>>32;
+        tmpgr->p.y1=(tmpg0->p.y1*t0+tmpg1->p.y1*t1)>>32;
+        break;
+      case SPT_CIRCLE:
+        tmpgr->pr.radius=(tmpg0->pr.radius*t0+tmpg1->pr.radius*t1)>>32;
+        tmpgr->pr.x1=(tmpg0->pr.x1*t0+tmpg1->pr.x1*t1)>>32;
+        tmpgr->pr.y1=(tmpg0->pr.y1*t0+tmpg1->pr.y1*t1)>>32;
+        break;
+      case SPT_ELLIPSE:
+      case SPT_POLYGON:
+        tmpgr->pwha.x1=(tmpg0->pwha.x1*t0+tmpg1->pwha.x1*t1)>>32;
+        tmpgr->pwha.y1=(tmpg0->pwha.y1*t0+tmpg1->pwha.y1*t1)>>32;
+        tmpgr->pwha.width =(tmpg0->pwha.width *t0+tmpg1->pwha.width*t1)>>32;
+        tmpgr->pwha.height=(tmpg0->pwha.height*t0+tmpg1->pwha.height*t1)>>32;
+        break;
+      case SPT_BITMAP:
+        tmpgr->pwhu.x1=(tmpg0->pwhu.x1*t0+tmpg1->pwhu.x1*t1)>>32;
+        tmpgr->pwhu.y1=(tmpg0->pwhu.y1*t0+tmpg1->pwhu.y1*t1)>>32;
+        break;
+      case SPT_POLYLINE:
+        ptr0=&tmpg0->nu.u;
+        ptr1=&tmpg1->nu.u;
+        ptrr=&tmpgr->nu.u;
+        for (i=0;i<tmpg0->nu.num;i++) {
+          ptrr[i<<1]=(ptr0[i<<1]*t0+ptr1[i<<1]*t1)>>32;
+          ptrr[i<<1+1]=(ptr0[i<<1+1]*t0+ptr1[i<<1+1]*t1)>>32;
+        }
+        break;
+      case SPT_POLYPT:
+        tmpgr->npu.x=(tmpg0->npu.x*t0+tmpg1->npu.x*t1)>>32;
+        tmpgr->npu.y=(tmpg0->npu.y*t0+tmpg1->npu.y*t1)>>32;
+        break;
+      case SPT_BSPLINE2:
+      case SPT_BSPLINE3:
+      case SPT_BSPLINE2_CLOSED:
+      case SPT_BSPLINE3_CLOSED:
+        p0=&tmpg0->nu.u;
+        p1=&tmpg1->nu.u;
+        pr=&tmpgr->nu.u;
+        for (i=0;i<tmpg0->nu.num;i++) {
+          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
+          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
+          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
+        }
+        break;
+      case SPT_MESH:
+        p0=&tmpg0->mu.u;
+        p1=&tmpg1->mu.u;
+        pr=&tmpgr->mu.u;
+        for (i=0;i<tmpg0->mu.vertex_cnt;i++) {
+          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
+          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
+          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
+        }
+        break;
+      case SPT_SHIFTABLE_MESH:
+        p0=&tmpg0->pmu.u;
+        p1=&tmpg1->pmu.u;
+        pr=&tmpgr->pmu.u;
+        for (i=0;i<tmpg0->pmu.vertex_cnt;i++) {
+          pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
+          pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
+          pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
+        }
+        break;
+    }
+    tmpg0(U8 *)+=SpriteElemSize(tmpg0);
+    tmpg1(U8 *)+=SpriteElemSize(tmpg1);
+    tmpgr(U8 *)+=SpriteElemSize(tmpgr);
+  }
+  return res;
+}
+
+#help_index "Graphics/Sprite;DolDoc/Output;StdOut/DolDoc"
+public CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL)
+{//Put a sprite into a document.  You can, optionally, supply a fmt string
+//for DolDoc cmd with a %d for the bin_num.
+  I64 size;
+  U8 *st;
+  Bool unlock;
+  CDocEntry *doc_e;
+  CDocBin *tmpb;
+  if (!doc && !(doc=DocPut)) return NULL;
+  unlock=DocLock(doc);
+  size=SpriteSize(elems);
+  tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
+  tmpb->size=size;
+  tmpb->data=MAlloc(size,doc->mem_task);
+  MemCpy(tmpb->data,elems,size);
+  tmpb->num=doc->cur_bin_num;
+  tmpb->use_cnt=1;
+  QueIns(tmpb,doc->bin_head.last);
+  if (fmt)
+    st=MStrPrint(fmt,doc->cur_bin_num++);
+  else
+    st=MStrPrint("$SP,\"\",BI=%d$",doc->cur_bin_num++);
+  doc_e=DocPrint(doc,"%s",st);
+  Free(st);
+  doc_e->bin_data=tmpb;
+  if (doc_e && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+    tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
+  if (unlock)
+    DocUnlock(doc);
+  return doc_e;
+}
+
+public CDocEntry *Sprite(U8 *elems,U8 *fmt=NULL)
+{//Put sprite to the command-line, DocPut.
+//If you set fmt, then include dollars ("$SP ...$") and leave %d for num.
+  CDoc *doc;
+  if (doc=DocPut)
+    return DocSprite(doc,elems,fmt);
+  return NULL;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/GrTextBase.HC.HTML b/public/Wb/Home/Src/Adam/Gr/GrTextBase.HC.HTML new file mode 100755 index 0000000..862ffad --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/GrTextBase.HC.HTML @@ -0,0 +1,394 @@ + + + + + + + + + + + +
+#help_index "TextBase Layer;Char/TextBase Layer"
+#help_file "::/Doc/TextBase"
+
+asm {
+//************************************
+_TEXT_CHAR::
+//Bool TextChar(CTask *task,Bool allow_border=FALSE,I64 x,I64 y,I64 d);
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RCX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 CTask.scroll_x[RCX]
+        SAR     RBX,3
+        ADD     RBX,U64 SF_ARG3[RBP]
+        MOV     RAX,U64 CTask.scroll_y[RCX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG4[RBP]
+
+        TEST    U8 SF_ARG2[RBP],0xFF
+        JNZ     @@10
+
+//Border not allowed
+        TEST    RBX,RBX         //Check X
+        JS      @@05
+        ADD     RBX,U64 CTask.win_left[RCX]
+        CMP     RBX,U64 CTask.win_right[RCX]
+        JG      @@05
+        TEST    RBX,RBX
+        JS      @@05
+        CMP     RBX,TEXT_COLS
+        JGE     @@05
+        TEST    RAX,RAX         //Check Y
+        JS      @@05
+        ADD     RAX,U64 CTask.win_top[RCX]
+        CMP     RAX,U64 CTask.win_bottom[RCX]
+        JG      @@05
+        TEST    RAX,RAX
+        JS      @@05
+        CMP     RAX,TEXT_ROWS
+        JGE     @@05
+        JMP     @@15
+
+@@05:   XOR     RAX,RAX         //return FALSE
+        POP     RBP
+        RET1    40
+
+//Border allowed
+@@10:   MOV     RDX,-1          //Check X
+        CMP     RBX,RDX
+        JL      @@05
+        ADD     RBX,U64 CTask.win_left[RCX]
+        MOV     RDX,U64 CTask.win_right[RCX]
+        INC     RDX
+        CMP     RBX,RDX
+        JG      @@05
+        TEST    RBX,RBX
+        JS      @@05
+        CMP     RBX,TEXT_COLS
+        JGE     @@05
+        MOV     RDX,-1          //Check Y
+        CMP     RAX,RDX
+        JL      @@05
+        ADD     RAX,U64 CTask.win_top[RCX]
+        MOV     RDX,U64 CTask.win_bottom[RCX]
+        INC     RDX
+        CMP     RAX,RDX
+        JG      @@05
+        TEST    RAX,RAX
+        JS      @@05
+        CMP     RAX,TEXT_ROWS
+        JGE     @@05
+
+@@15:   IMUL2   RAX,TEXT_COLS
+        ADD     RBX,RAX
+        SHL     RBX,2
+        ADD     RBX,U64 [&gr.text_base]
+        MOV     RAX,U64 SF_ARG5[RBP]
+        MOV     U32 [RBX],EAX
+
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    40
+//************************************
+_TEXT_LEN_STR::
+//Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,I64 attr,U8 *s)
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG6[RBP]
+        MOV     RDI,U64 CTask.scroll_x[RBX]
+        SAR     RDI,3
+        ADD     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        TEST    RDI,RDI
+        JNS     @@05
+        ADD     RCX,RDI
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@05:   ADD     RDI,U64 CTask.win_left[RBX]
+        MOV     RDX,RCX
+        ADD     RDX,RDI
+        DEC     RDX
+        CMP     RDX,U64 CTask.win_right[RBX]
+        JLE     @@10
+        MOV     RAX,RDX
+        SUB     RAX,U64 CTask.win_right[RBX]
+        SUB     RDX,RAX
+        SUB     RCX,RAX
+@@10:   TEST    RDI,RDI
+        JNS     @@15
+        ADD     RCX,RDI
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@15:   INC     RDX
+        SUB     RDX,TEXT_COLS
+        JLE     @@20
+        SUB     RCX,RDX
+@@20:   CMP     RCX,1
+        JL      @@30
+
+        MOV     RAX,U64 CTask.scroll_y[RBX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG3[RBP]
+        TEST    RAX,RAX
+        JS      @@30
+        ADD     RAX,U64 CTask.win_top[RBX]
+        CMP     RAX,U64 CTask.win_bottom[RBX]
+        JG      @@30
+        TEST    RAX,RAX
+        JS      @@30
+        CMP     RAX,TEXT_ROWS
+        JGE     @@30
+
+        IMUL2   RAX,TEXT_COLS
+        ADD     RDI,RAX
+        SHL     RDI,2
+        ADD     RDI,U64 [&gr.text_base]
+        MOV     RAX,U64 SF_ARG5[RBP]
+@@25:   LODSB
+        STOSD
+        DEC     RCX
+        JNZ     @@25
+
+        POP     RDI
+        POP     RSI
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    48
+
+@@30:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    48
+//************************************
+_TEXT_LEN_ATTR_STR::
+//Bool TextLenAttrStr(CTask *task,I64 x,I64 y,I64 len,U32 *_attr)
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG5[RBP]
+        MOV     RDI,U64 CTask.scroll_x[RBX]
+        SAR     RDI,3
+        ADD     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        TEST    RDI,RDI
+        JNS     @@05
+        ADD     RCX,RDI
+        SHL     RDI,2
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@05:   ADD     RDI,U64 CTask.win_left[RBX]
+        MOV     RDX,RCX
+        ADD     RDX,RDI
+        DEC     RDX
+        CMP     RDX,U64 CTask.win_right[RBX]
+        JLE     @@10
+        MOV     RAX,RDX
+        SUB     RAX,U64 CTask.win_right[RBX]
+        SUB     RDX,RAX
+        SUB     RCX,RAX
+@@10:   TEST    RDI,RDI
+        JNS     @@15
+        ADD     RCX,RDI
+        SHL     RDI,2
+        SUB     RSI,RDI
+        XOR     RDI,RDI
+@@15:   INC     RDX
+        SUB     RDX,TEXT_COLS
+        JLE     @@20
+        SUB     RCX,RDX
+@@20:   CMP     RCX,1
+        JL      @@30
+
+        MOV     RAX,U64 CTask.scroll_y[RBX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG3[RBP]
+        TEST    RAX,RAX
+        JS      @@30
+        ADD     RAX,U64 CTask.win_top[RBX]
+        CMP     RAX,U64 CTask.win_bottom[RBX]
+        JG      @@30
+        TEST    RAX,RAX
+        JS      @@30
+        CMP     RAX,TEXT_ROWS
+        JGE     @@30
+
+        IMUL2   RAX,TEXT_COLS
+        ADD     RDI,RAX
+        SHL     RDI,2
+        ADD     RDI,U64 [&gr.text_base]
+@@25:   MOVSD
+        DEC     RCX
+        JNZ     @@25
+
+        POP     RDI
+        POP     RSI
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    40
+
+@@30:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    40
+//************************************
+_TEXT_LEN_ATTR:://Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,I64 attr)
+//Must be called 30fps in Fs->draw_it() callback.
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 CTask.scroll_x[RBX]
+        SAR     RDI,3
+        ADD     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+
+        TEST    RDI,RDI
+        JNS     @@05
+        ADD     RCX,RDI
+        XOR     RDI,RDI
+@@05:   ADD     RDI,U64 CTask.win_left[RBX]
+        MOV     RDX,RCX
+        ADD     RDX,RDI
+        DEC     RDX
+        CMP     RDX,U64 CTask.win_right[RBX]
+        JLE     @@10
+        MOV     RAX,RDX
+        SUB     RAX,U64 CTask.win_right[RBX]
+        SUB     RDX,RAX
+        SUB     RCX,RAX
+@@10:   TEST    RDI,RDI
+        JNS     @@15
+        ADD     RCX,RDI
+        XOR     RDI,RDI
+@@15:   INC     RDX
+        SUB     RDX,TEXT_COLS
+        JLE     @@20
+        SUB     RCX,RDX
+@@20:   CMP     RCX,1
+        JL      @@35
+
+        MOV     RAX,U64 CTask.scroll_y[RBX]
+        SAR     RAX,3
+        ADD     RAX,U64 SF_ARG3[RBP]
+        TEST    RAX,RAX
+        JS      @@35
+        ADD     RAX,U64 CTask.win_top[RBX]
+        CMP     RAX,U64 CTask.win_bottom[RBX]
+        JG      @@35
+        TEST    RAX,RAX
+        JS      @@35
+        CMP     RAX,TEXT_ROWS
+        JGE     @@35
+
+        IMUL2   RAX,TEXT_COLS
+        ADD     RDI,RAX
+        SHL     RDI,2
+        ADD     RDI,U64 [&gr.text_base]
+        MOV     RBX,U64 SF_ARG5[RBP]
+        MOV     RSI,RDI
+@@25:   LODSD
+        TEST    AL,AL
+        JNZ     @@30
+        MOV     RAX,RBX
+        STOSD
+        DEC     RCX
+        JNZ     @@25
+
+@@30:   POP     RDI
+        POP     RSI
+        MOV     RAX,TRUE
+        POP     RBP
+        RET1    40
+
+@@35:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    40
+}
+public _extern _TEXT_CHAR Bool TextChar(CTask *task,Bool allow_border=FALSE,
+I64 x,I64 y,I64 d); //Plot char. 30fps in Fs->draw_it() callback.
+public _extern _TEXT_LEN_STR Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,
+I64 attr,U8 *s); //Plot str with len.  30fps in Fs->draw_it() callback.
+public _extern _TEXT_LEN_ATTR_STR Bool TextLenAttrStr(CTask *task,I64 x,I64 y,
+I64 len,U32 *_attr); //Plot attr str with len.  30fps in Fs->draw_it() callback.
+public _extern _TEXT_LEN_ATTR Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,
+I64 attr); //Plot attrs with len.  30fps in Fs->draw_it() callback.
+
+public U0 TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...)
+{//Plot chars. 30fps in Fs->draw_it() callback.
+//You probably want GrPrint() or just Print().
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  TextLenStr(task,x,y,StrLen(buf),attr<<8,buf);
+  Free(buf);
+}
+
+public U0 TextBorder(CTask *task=NULL,
+        I64 l,I64 r,I64 t,I64 b,I64 attr,Bool solid)
+{//Plot border square. 30fps in Fs->draw_it() callback.
+//Draws window borders or DolDoc text bttn borders.
+  //Set task=sys_winmgr_task for no clipping.
+  I64 i;
+  if (!task) task=Fs;
+  attr<<=8;
+  TextChar(task,,l-1,t-1,text.border_chars[6+solid]+attr);
+  TextChar(task,,r+1,t-1,text.border_chars[8+solid]+attr);
+  TextChar(task,,l-1,b+1,text.border_chars[10+solid]+attr);
+  TextChar(task,,r+1,b+1,text.border_chars[12+solid]+attr);
+  for (i=l;i<=r;i++) {
+    TextChar(task,,i,t-1,text.border_chars[2+solid]+attr);
+    TextChar(task,,i,b+1,text.border_chars[2+solid]+attr);
+  }
+  for (i=t;i<=b;i++) {
+    TextChar(task,,l-1,i,text.border_chars[4+solid]+attr);
+    TextChar(task,,r+1,i,text.border_chars[4+solid]+attr);
+  }
+}
+
+public U0 TextRect(I64 l,I64 r,I64 t,I64 b,I64 d)
+{//Fill text rect. 30fps in Fs->draw_it() callback.
+  I64 y,w;
+  if (l>r || t>b) return;
+  if (t<0) t=0;
+  if (b>=TEXT_ROWS) b=TEXT_ROWS-1;
+  if (l<0) l=0;
+  if (r>=TEXT_COLS) r=TEXT_COLS-1;
+  if (w=r-l+1)
+    for (y=t;y<=b;y++)
+      MemSetU32(gr.text_base(U8 *)+(y*TEXT_COLS+l)*sizeof(U32),d,w);
+}
+
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/MakeGr.HC.HTML b/public/Wb/Home/Src/Adam/Gr/MakeGr.HC.HTML new file mode 100755 index 0000000..7914c17 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/MakeGr.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#include "GrInitA"
+#include "Gr.HH"
+#include "GrExt"
+#include "GrGlbls"
+#include "GrTextBase"
+#include "GrAsm"
+#include "GrPalette"
+#include "GrDC"
+#include "GrInitB"
+#include "GrMath"
+#include "GrScrn"
+#include "GrBitMap"
+#include "GrPrimatives"
+#include "GrComposites"
+#include "ScrnCast"
+
+#define SPE_ABORT       (-1)
+#define SPE_EXIT        0
+#define SPE_CONT        1
+#include "SpriteNew"
+#include "GrSpritePlot"
+#include "SpriteMesh"
+#include "SpriteBitMap"
+#include "SpriteCode"
+#include "SpriteSideBar"
+#include "SpriteEd"
+#include "SpriteMain"
+
+#include "GrEnd"
+
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/ScrnCast.HC.HTML b/public/Wb/Home/Src/Adam/Gr/ScrnCast.HC.HTML new file mode 100755 index 0000000..83affc4 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/ScrnCast.HC.HTML @@ -0,0 +1,127 @@ + + + + + + + + + + + +
+#help_index "ScrnCast;Graphics/Device Contexts;Graphics/GR Files"
+
+#define MV_FILE_MAX     0x007FF000
+
+public I64 GR2MV(U8 *print_fmt="VID%03d.MV",
+        U8 *files_find_mask,U8 *fu_flags=NULL)
+{/*Merge GR lst to MV file.
+"+d" will delete GR list files.
+*/
+  I64 fuf_flags=0,file_num=0,size;
+  CDirEntry *tmpde,*tmpde1;
+  U8 *base,*dst,*src,*st;
+  CDC *dc,*dc_base=DCNew(GR_WIDTH,GR_HEIGHT);
+  CDate cdt;
+  Bool old_silent;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND);
+  if (progress1_max=LinkedLstCnt(tmpde1)) {
+    dst=base=MAlloc(MV_FILE_MAX);
+    while (tmpde) {
+      dc=GRRead(tmpde->full_name);
+      GrBlot(dc_base,dc->x0,dc->y0,dc);
+      if (dst+GR_FILE_MAX>base+MV_FILE_MAX) {
+        st=MStrPrint(print_fmt,file_num++);
+        FileWrite(st,base,dst-base);
+        Free(st);
+        dst=base;
+
+        cdt=dc->cdt;
+        dc=DCCopy(dc_base);
+        dc->cdt=cdt;
+      }
+      src=DCSave(dc,&size);
+      DCDel(dc);
+      MemCpy(dst,src,size);
+      dst+=size;
+      Free(src);
+      if (fuf_flags&FUF_DEL) {
+        old_silent=Silent;
+        Del(tmpde->full_name);
+        Silent(old_silent);
+      }
+      progress1++;
+      tmpde=tmpde->next;
+    }
+    if (dst>base) {
+      st=MStrPrint(print_fmt,file_num++);
+      FileWrite(st,base,dst-base);
+      Free(st);
+    }
+    Free(base);
+  }
+  progress1=progress1_max=0;
+  DirTreeDel(tmpde1);
+  DCDel(dc_base);
+  return file_num;
+}
+
+#help_index "ScrnCast;Snd/AU Files"
+public U0 SndShift(CSndData *head,F64 dt=0)
+{//Shift CSndData in time.
+  CSndData *tmpsd,*tmpsd1;
+  if (dt) {
+    tmpsd=head->next;
+    while (tmpsd!=head) {
+      tmpsd1=tmpsd->next;
+      tmpsd->tS-=dt;
+      if (tmpsd->tS<tmpsd->last->tS) {
+        QueRem(tmpsd);
+        Free(tmpsd);
+      }
+      tmpsd=tmpsd1;
+    }
+  }
+}
+
+public I64 AUWrite(U8 *filename,CSndData *head,CDate *t0_now,F64 t0_tS)
+{//Write AU file.
+  CSndData *tmpsd;
+  CAUData *base,*dst;
+  I64 size=(1+QueCnt(head))*sizeof(CAUData);
+  U8 *st=ExtDft(filename,"AU");
+  base=dst=MAlloc(size);
+  tmpsd=head;
+  do {
+    dst->cdt=t0_now(I64)+ToI64(CDATE_FREQ*(tmpsd->tS-t0_tS));
+    dst->ona=tmpsd->ona;
+    dst++;
+    tmpsd=tmpsd->next;
+  } while (tmpsd!=head);
+  FileWrite(st,base,dst(U8 *)-base(U8 *));
+  Free(base);
+  Free(st);
+  return size;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/SpriteBitMap.HC.HTML b/public/Wb/Home/Src/Adam/Gr/SpriteBitMap.HC.HTML new file mode 100755 index 0000000..46cb9ac --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/SpriteBitMap.HC.HTML @@ -0,0 +1,701 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+#define SPBM_EXIT               0
+#define SPBM_MAIN_MENU          1
+#define SPBM_COLOR              2
+#define SPBM_DITHER_COLOR       3
+#define SPBM_WIDTH              4
+#define SPBM_PT                 5
+#define SPBM_LINE               6
+#define SPBM_ARROW              7
+#define SPBM_RECT               8
+#define SPBM_CIRCLE             9
+#define SPBM_TEXT               10
+#define SPBM_TEXT_BOX           11
+#define SPBM_TEXT_DIAMOND       12
+#define SPBM_FLOOD_FILL         13
+#define SPBM_FLOOD_FILL_NOT     14
+#define SPBM_POLYLINE           15
+#define SPBM_POLYPT             16
+#define SPBM_COPY               17
+#define SPBM_DELETE             18
+#define SPBM_PASTE              19
+#define SPBM_PASTE_TRANSPARENT  20
+#define SPBM_FIND_AND_REPLACE   21
+#define SPBM_TRIM_TO_EXTENTS    22
+#define SPBM_ADD_OUTLINE        23
+#define SPBM_ETCH               24
+#define SPBM_UNDO               25
+#define SPBM_SAVE_GR            26
+
+U0 GrInit4()
+{
+  DefineLstLoad("ST_SPRITE_BITMAP_MENU",
+        "Exit\0Main Menu\0Color\0Dither Color\0Width\0Point\0Line\0Arrow\0"
+        "Rect\0Circle\0Text\0Text Box\0Text Diamond\0Flood Fill\0"
+        "Flood Fill Not Color\0PolyLine\0PolyPoint\0Copy\0Delete\0Paste\0"
+        "Paste Transparent\0Find and Replace\0Trim to Extents\0Add Outline\0"
+        "Etch\0Undo\0Save GR\0");
+}
+GrInit4;
+
+I64 PopUpSpriteBitMap(CColorROPU32 color,I64 width)
+{
+  I64 res;
+  U8 *st1,*st2,buf[STR_LEN];
+  CDoc *doc=DocNew;
+
+  Color2Str(buf,color);
+  if (color&ROPF_DITHER) {
+    st1="";
+    st2=buf;
+  } else {
+    st1=buf;
+    st2="";
+  }
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite BitMap Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteBitMap.DD.Z\"$\n"
+        "\n$LTBLUE$$MU-UL,\"Color        %s\",LE=SPBM_COLOR$\n"
+        "$MU-UL,\"Dither Color %s\",LE=SPBM_DITHER_COLOR$\n"
+        "$MU-UL,\"Width        %d\",LE=SPBM_WIDTH$\n"
+        "$MU-UL,\"Find & Replace Color\",LE=SPBM_FIND_AND_REPLACE$\n"
+        "$MU-UL,\"Trim to Extents\",LE=SPBM_TRIM_TO_EXTENTS$\n"
+        "$MU-UL,\"Add Outline\",LE=SPBM_ADD_OUTLINE$\n"
+        "$MU-UL,\"Etch\",LE=SPBM_ETCH$\n"
+        "\n$MU-UL,\"Point\",LE=SPBM_PT$\n"
+        "$MU-UL,\"Line\",LE=SPBM_LINE$\n"
+        "$MU-UL,\"Arrow\",LE=SPBM_ARROW$\n"
+        "$MU-UL,\"Rect\",LE=SPBM_RECT$\n"
+        "$MU-UL,\"Circle\",LE=SPBM_CIRCLE$\n"
+        "$MU-UL,\"Text\",LE=SPBM_TEXT$\n"
+        "$MU-UL,\"Text Box\",LE=SPBM_TEXT_BOX$\n"
+        "$MU-UL,\"Text Diamond\",LE=SPBM_TEXT_DIAMOND$\n"
+        "$MU-UL,\"Flood Fill\",LE=SPBM_FLOOD_FILL$\n"
+        "$MU-UL,\"Flood Fill Not Color\",LE=SPBM_FLOOD_FILL_NOT$\n"
+        "$MU-UL,\"PolyLine\",LE=SPBM_POLYLINE$\n"
+        "$MU-UL,\"PolyPoint\",LE=SPBM_POLYPT$\n"
+        "\n$MU-UL,\"Copy to Clip\",LE=SPBM_COPY$\n"
+        "$MU-UL,\"Delete to Clip\",LE=SPBM_DELETE$\n"
+        "$MU-UL,\"Paste Clip\",LE=SPBM_PASTE$\n"
+        "$MU-UL,\"Paste Transparent Clip\",LE=SPBM_PASTE_TRANSPARENT$\n"
+        "\n$MU-UL,\"Save GR File\",LE=SPBM_SAVE_GR$\n"
+        "\n$MU-UL,\"Undo\",LE=SPBM_UNDO$\n"
+        "\n$PURPLE$$MU-UL,\"+] Sprite Main Menu\",LE=SPBM_MAIN_MENU$$LTBLUE$\n"
+        "$MU-UL,\"Exit  Sprite\",LE=SPBM_EXIT$\n"
+        "$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$\n"
+        "\nRight-Click to get back to this menu.",st1,st2,width);
+  res=PopUpMenu(doc);
+  DocDel(doc);
+  return res;
+}
+
+U0 GrBitMapEdPrepPersistentDC(CDC *dc,I64 xx1,I64 yy1,CDC *img)
+{
+  DCFill(dc);
+  GrBlot(dc,xx1,yy1,img);
+}
+
+U0 GrBitMapEdTrimToExtents(CDC **_img,I64 *_xx1,I64 *_yy1,
+        I64 *_xx2,I64 *_yy2,CColorROPU32 bkcolor)
+{
+  CDC *img=*_img;
+  I64 i,c,
+        x1=0,y1=0,x2=img->width-1,y2=img->height-1; //inclusive
+  while (y1<y2) {
+    for (i=x1;i<=x2;i++) {
+      c=GrPeek(img,i,y1);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_y2;
+    }
+    y1++;
+  }
+
+  tr_y2:
+  while (y1<y2) {
+    for (i=x1;i<=x2;i++) {
+      c=GrPeek(img,i,y2);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_x1;
+    }
+    y2--;
+  }
+
+  tr_x1:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++) {
+      c=GrPeek(img,x1,i);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_x2;
+    }
+    x1++;
+  }
+
+  tr_x2:
+  while (x1<x2) {
+    for (i=y1;i<=y2;i++) {
+      c=GrPeek(img,x2,i);
+      if (c!=bkcolor&&c!=TRANSPARENT) goto tr_done;
+    }
+    x2--;
+  }
+
+  tr_done:
+  *_img=DCExt(img,x1,y1,x2,y2);
+  *_xx1+=x1;                *_yy1+=y1;
+  *_xx2+=x2-(img->width-1); *_yy2+=y2-(img->height-1); //not inclusive
+  DCDel(img);
+}
+
+U0 GrBitMapEdAddOutline(CDC *img,I64 width,
+        CColorROPU32 color,CColorROPU32 bkcolor)
+{
+  I64 i,j,k,c;
+  CColorROPU32 old_color;
+  CDC *src;
+  if (img->width && img->height) {
+    old_color=img->color;
+    img->color=color;
+    while (width-->0) {
+      src=DCExt(img,0,0,img->width-1,img->height-1);
+      for (i=0;i<img->height;i++)
+        for (j=0;j<img->width;j++)
+          if (GrPeek(src,j,i)==bkcolor)
+            for (k=0;k<8;k++) {
+              c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
+              if (c>=0 && c!=bkcolor) {
+                GrPlot(img,j,i);
+                break;
+              }
+            }
+      DCDel(src);
+    }
+    img->color=old_color;
+  }
+}
+
+U0 GrBitMapEdEtch(CDC *img,I64 width,CColorROPU32 bkcolor)
+{
+  I64 i,j,k,c;
+  CColorROPU32 old_color;
+  CDC *src;
+  if (img->width && img->height) {
+    old_color=img->color;
+    img->color=bkcolor;
+    while (width-->0) {
+      src=DCExt(img,0,0,img->width-1,img->height-1);
+      for (i=0;i<img->height;i++)
+        for (j=0;j<img->width;j++)
+          if (GrPeek(src,j,i)!=bkcolor)
+            for (k=0;k<8;k++) {
+              c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
+              if (c<0 || c==bkcolor) {
+                GrPlot(img,j,i);
+                break;
+              }
+            }
+      DCDel(src);
+    }
+    img->color=old_color;
+  }
+}
+
+I64 SpriteBitMapEd(CDoc *,CDocEntry *doc_e,CDC *dc,I64 *_xx1,I64 *_yy1,
+        I64 *_xx2,I64 *_yy2,CDC **_img,CColorROPU32 bkcolor)
+{
+  I64 i,j,mode=SPBM_LINE,color=BLACK,width=1,msg_code,arg1,arg2,x1,y1,x11,y11,
+        x22,y22,res,xx1=*_xx1,yy1=*_yy1,xx2=*_xx2,yy2=*_yy2,
+        old_de_flags=doc_e->de_flags;
+  Bool down=FALSE;
+  U8 *st=NULL;
+  CEdFileName filename;
+  CDC *img=*_img,
+        *clip=NULL,*undo=NULL,*dc2;
+  SettingsPush; //See SettingsPush
+
+  doc_e->de_flags|=DOCEF_DONT_DRAW;
+  goto bm_menu;
+
+  while (TRUE) {
+    if (kbd.scan_code&SCF_CTRL)//grab scroll update?
+      GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+
+    dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+    dc->thick=1;
+    GrBorder(dc,xx1-1,yy1-1,xx2,yy2);//This is done little bit too often.
+
+    while (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_DOWN|1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN)) {
+      switch (msg_code) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case CH_SHIFT_ESC:
+              res=SPE_ABORT;
+              goto bm_key_up_done;
+            case CH_ESC:
+              res=SPE_CONT;
+              goto bm_key_up_done;
+            case 'c': //eye-dropper
+              dc2=DCScrnCapture(FALSE);
+              color=GrPeek(dc2,ms.pos.x,ms.pos.y)^15;//Mouse cursor is XORed.
+              DCDel(dc2);
+              break;
+            case 't': //Set to transparent color
+              color=TRANSPARENT;
+              break;
+          }
+          break;
+
+        case MSG_MS_R_DOWN:
+bm_menu:
+          DCFill(dc);
+          StrCpy(Fs->task_title,"Sprite BitMap Menu");
+          i=PopUpSpriteBitMap(color,width);
+          if (i>=0)
+            StrCpy(Fs->task_title,DefineSub(i,"ST_SPRITE_BITMAP_MENU"));
+          switch (i) {
+            case DOCM_CANCEL:
+              res=SPE_ABORT;
+              goto bm_done;
+            case SPBM_EXIT:
+              res=SPE_EXIT;
+              goto bm_done;
+            case SPBM_MAIN_MENU:
+              res=SPE_CONT;
+              goto bm_done;
+            case SPBM_COLOR:
+              i=PopUpColor(,,FALSE);
+              if (i>=0) color=i;
+              goto bm_menu;
+            case SPBM_FIND_AND_REPLACE:
+              i=PopUpColor("Find Color\n",,FALSE);
+              if (i>=0) {
+                j=PopUpColor("Replace Color\n",,FALSE);
+                if (j>=0) {
+                  DCColorChg(img,i,j);
+                  GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                }
+              }
+              goto bm_menu;
+            case SPBM_TRIM_TO_EXTENTS:
+              GrBitMapEdTrimToExtents(&img,&xx1,&yy1,&xx2,&yy2,bkcolor);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              goto bm_menu;
+            case SPBM_ADD_OUTLINE:
+              i=PopUpRangeI64(1,16,1,"Outline Width\n");
+              if (i>=0) {
+                GrBitMapEdAddOutline(img,i,color,bkcolor);
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              }
+              goto bm_menu;
+            case SPBM_ETCH:
+              i=PopUpRangeI64(1,16,1,"Etch Width\n");
+              if (i>=0) {
+                GrBitMapEdEtch(img,i,bkcolor);
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              }
+              goto bm_menu;
+            case SPBM_SAVE_GR:
+              *filename.name=0;
+              if (DocForm(&filename) && *filename.name)
+                GRWrite(filename.name,img,DCSF_COMPRESSED|DCSF_PALETTE_GET);
+              goto bm_menu;
+            case SPBM_DITHER_COLOR:
+              i=PopUpColorDither;
+              if (i>=0) color=i;
+              goto bm_menu;
+            case SPBM_WIDTH:
+              i=PopUpRangeI64(1,16,1,"Thick\n");
+              if (i>=0) width=i;
+              goto bm_menu;
+            case SPBM_UNDO:
+              if (undo) {
+                DCFill(img,bkcolor);
+                img->color=ROP_EQU;
+                GrBlot(img,0,0,undo);
+                DCDel(undo);
+                undo=NULL;
+              }
+              goto bm_menu;
+            case SPBM_PT:
+            case SPBM_LINE:
+            case SPBM_ARROW:
+            case SPBM_RECT:
+            case SPBM_CIRCLE:
+            case SPBM_FLOOD_FILL:
+            case SPBM_FLOOD_FILL_NOT:
+            case SPBM_POLYPT:
+            case SPBM_POLYLINE:
+            case SPBM_COPY:
+            case SPBM_DELETE:
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              mode=i;
+              break;
+            case SPBM_TEXT:
+            case SPBM_TEXT_BOX:
+            case SPBM_TEXT_DIAMOND:
+              Free(st);
+              st=PopUpGetStr("Enter text and press <ESC>.\n");
+              if (st && *st)
+                mode=i;
+              else
+                goto bm_menu;
+              break;
+          }
+          DCDel(undo);
+          undo=DCExt(img,0,0,img->width-1,img->height-1);
+          undo->bkcolor=bkcolor;
+          Refresh(2,TRUE);      //Let popup close
+          GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+          down=FALSE;
+          break;
+        case MSG_MS_L_DOWN:
+          switch (mode) {
+            case SPBM_PT:
+              img->color=color;
+              img->thick=width;
+              GrPlot3(img,arg1-xx1,arg2-yy1,0);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            start:
+              if (down)
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              x1=arg1; y1=arg2;
+              down=TRUE;
+              dc->color=color;
+              dc->thick=width;
+              case SPBM_LINE:
+                GrLine3(dc,x1,y1,0,arg1,arg2,0);
+                break;
+              case SPBM_ARROW:
+                GrArrow3(dc,x1,y1,0,arg1,arg2,0);
+                break;
+              case SPBM_RECT:
+                GrRect(dc,x1,y1,1,1);
+                break;
+              case SPBM_CIRCLE:
+                GrCircle3(dc,x1,y1,0,1);
+                break;
+              case SPBM_COPY:
+              case SPBM_DELETE:
+                dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+                dc->thick=1;
+                GrBorder(dc,x1,y1,x1,y1);
+                break;
+            end:
+              break;
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              if (clip) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (mode==SPBM_PASTE) {
+                  clip->flags|=DCF_NO_TRANSPARENTS;
+                  GrBlot(dc,arg1,arg2,clip);
+                  clip->flags&=~DCF_NO_TRANSPARENTS;
+                } else {
+                  dc2=DCCopy(clip);
+                  DCColorChg(dc2,bkcolor);
+                  GrBlot(dc,arg1,arg2,dc2);
+                  DCDel(dc2);
+                }
+              }
+              break;
+            case SPBM_TEXT:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrPrint(dc,arg1,arg2,"%s",st);
+              break;
+            case SPBM_TEXT_BOX:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextBox3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_TEXT_DIAMOND:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextDiamond3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_FLOOD_FILL:
+              img->color=color;
+              GrFloodFill(img,arg1-xx1,arg2-yy1);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_FLOOD_FILL_NOT:
+              img->color=color;
+              GrFloodFill(img,arg1-xx1,arg2-yy1,TRUE);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_POLYLINE:
+              if (!down) {
+                x1=arg1; y1=arg2;
+                down=TRUE;
+                dc->color=color;
+                dc->thick=width;
+                GrLine3(dc,x1,y1,0,arg1,arg2,0);
+              }
+              break;
+            case SPBM_POLYPT:
+              x1=arg1; y1=arg2;
+              down=TRUE;
+              img->color=color;
+              img->thick=width;
+              GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+          }
+          break;
+        case MSG_MS_MOVE:
+          switch (mode) {
+            case SPBM_LINE:
+            case SPBM_ARROW:
+            case SPBM_POLYLINE:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                dc->color=color;
+                dc->thick=width;
+                if (mode==SPBM_ARROW)
+                  GrArrow3(dc,x1,y1,0,arg1,arg2,0);
+                else
+                  GrLine3(dc,x1,y1,0,arg1,arg2,0);
+              }
+              break;
+            case SPBM_RECT:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (x1<arg1) {
+                  x11=x1;
+                  x22=arg1;
+                } else {
+                  x11=arg1;
+                  x22=x1;
+                }
+                if (y1<arg2) {
+                  y11=y1;
+                  y22=arg2;
+                } else {
+                  y11=arg2;
+                  y22=y1;
+                }
+                dc->color=color;
+                GrRect(dc,x11,y11,x22-x11+1,y22-y11+1);
+              }
+              break;
+            case SPBM_COPY:
+            case SPBM_DELETE:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (x1<arg1) {
+                  x11=x1;
+                  x22=arg1;
+                } else {
+                  x11=arg1;
+                  x22=x1;
+                }
+                if (y1<arg2) {
+                  y11=y1;
+                  y22=arg2;
+                } else {
+                  y11=arg2;
+                  y22=y1;
+                }
+                dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+                dc->thick=1;
+                GrBorder(dc,x11,y11,x22,y22);
+              }
+              break;
+            case SPBM_CIRCLE:
+              if (down) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                dc->color=color;
+                dc->thick=width;
+                GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
+              }
+              break;
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              if (clip) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (mode==SPBM_PASTE) {
+                  clip->flags|=DCF_NO_TRANSPARENTS;
+                  GrBlot(dc,arg1,arg2,clip);
+                  clip->flags&=~DCF_NO_TRANSPARENTS;
+                } else {
+                  dc2=DCCopy(clip);
+                  DCColorChg(dc2,bkcolor);
+                  GrBlot(dc,arg1,arg2,dc2);
+                  DCDel(dc2);
+                }
+              }
+              break;
+            case SPBM_TEXT:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrPrint(dc,arg1,arg2,"%s",st);
+              break;
+            case SPBM_TEXT_BOX:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextBox3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_TEXT_DIAMOND:
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              dc->color=color;
+              GrTextDiamond3(dc,arg1,arg2,0,st);
+              break;
+            case SPBM_POLYPT:
+              if (down) {
+                img->color=color;
+                img->thick=width;
+                GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                x1=arg1; y1=arg2;
+              }
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (mode) {
+            case SPBM_LINE:
+            case SPBM_ARROW:
+            case SPBM_POLYPT:
+            case SPBM_POLYLINE:
+              img->color=color;
+              img->thick=width;
+              if (mode==SPBM_ARROW)
+                GrArrow3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+              else
+                GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              if (mode==SPBM_POLYLINE) {
+                x1=arg1; y1=arg2;
+              } else
+                down=FALSE;
+              break;
+            case SPBM_RECT:
+              img->color=color;
+              if (x1<arg1) {
+                x11=x1;
+                x22=arg1;
+              } else {
+                x11=arg1;
+                x22=x1;
+              }
+              if (y1<arg2) {
+                y11=y1;
+                y22=arg2;
+              } else {
+                y11=arg2;
+                y22=y1;
+              }
+              GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
+              down=FALSE;
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_COPY:
+            case SPBM_DELETE:
+              if (x1<arg1) {
+                x11=x1;
+                x22=arg1;
+              } else {
+                x11=arg1;
+                x22=x1;
+              }
+              if (y1<arg2) {
+                y11=y1;
+                y22=arg2;
+              } else {
+                y11=arg2;
+                y22=y1;
+              }
+              DCDel(clip);
+              clip=DCExt(img,x11-xx1,y11-yy1,x22-xx1,y22-yy1);
+              clip->bkcolor=bkcolor;
+              if (mode==SPBM_DELETE) {
+                img->color=bkcolor;
+                GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
+              }
+              goto bm_menu;
+            case SPBM_CIRCLE:
+              img->color=color;
+              img->thick=width;
+              GrCircle3(img,x1-xx1,y1-yy1,0,
+                    Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
+              down=FALSE;
+              GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              break;
+            case SPBM_PASTE:
+            case SPBM_PASTE_TRANSPARENT:
+              if (clip) {
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+                if (mode==SPBM_PASTE) {
+                  clip->flags|=DCF_NO_TRANSPARENTS;
+                  GrBlot(img,arg1-xx1,arg2-yy1,clip);
+                  clip->flags&=~DCF_NO_TRANSPARENTS;
+                } else {
+                  dc2=DCCopy(clip);
+                  DCColorChg(dc2,bkcolor);
+                  GrBlot(img,arg1-xx1,arg2-yy1,dc2);
+                  DCDel(dc2);
+                }
+                GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
+              }
+              break;
+            case SPBM_TEXT:
+              img->color=color;
+              GrPrint(img,arg1-xx1,arg2-yy1,"%s",st);
+              goto bm_menu;
+            case SPBM_TEXT_BOX:
+              img->color=color;
+              GrTextBox3(img,arg1-xx1,arg2-yy1,0,st);
+              goto bm_menu;
+            case SPBM_TEXT_DIAMOND:
+              img->color=color;
+              GrTextDiamond3(img,arg1-xx1,arg2-yy1,0,st);
+              goto bm_menu;
+          }
+          break;
+      }
+    }
+    Refresh;
+  }
+bm_key_up_done:
+  GetMsg(,,1<<MSG_KEY_UP);
+bm_done:
+  DCDel(clip);
+  DCDel(undo);
+  Free(st);
+  DCFill(dc);
+  SettingsPop;
+  doc_e->de_flags=old_de_flags;
+  *_img=img;
+  *_xx1=xx1,*_yy1=yy1,*_xx2=xx2,*_yy2=yy2;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/SpriteCode.HC.HTML b/public/Wb/Home/Src/Adam/Gr/SpriteCode.HC.HTML new file mode 100755 index 0000000..e43a4cf --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/SpriteCode.HC.HTML @@ -0,0 +1,634 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+U0 SpriteElem2Code(CDoc *doc,CSprite *tmpg)
+{
+  U8 buf1[STR_LEN],buf2[STR_LEN];
+  I32 *ptr;
+  I64 i,j,k,col,width_internal;
+  CD3I32 *p;
+  CMeshTri *tri;
+  if (!doc) doc=DocPut;
+  DocPrint(doc,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_CODES");
+  switch (tmpg->type&SPG_TYPE_MASK) {
+    case SPT_COLOR:
+      DocPrint(doc,"{%s}",
+            Color2Str(buf1,tmpg->c.color));
+      break;
+    case SPT_DITHER_COLOR:
+      DocPrint(doc,"{%s}",
+            Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
+            tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
+      break;
+    case SPT_TRANSFORM_ON:
+      DocPrint(doc,"{ON}");
+      break;
+    case SPT_TRANSFORM_OFF:
+      DocPrint(doc,"{OFF}");
+      break;
+    case SPT_LINE:
+    case SPT_ARROW:
+    case SPT_PLANAR_SYMMETRY:
+      DocPrint(doc,"{(%d,%d),(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
+            tmpg->pp.x2,tmpg->pp.y2);
+      break;
+    case SPT_RECT:
+      DocPrint(doc,"{(%d,%d):(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
+            tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
+      break;
+    case SPT_ROTATED_RECT:
+      DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->ppa.x1,tmpg->ppa.y1,
+            tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1,
+            180/pi*Wrap(tmpg->ppa.angle));
+      break;
+    case SPT_PT:
+    case SPT_FLOOD_FILL:
+    case SPT_SHIFT:
+      DocPrint(doc,"{(%d,%d)}",tmpg->p.x1,tmpg->p.y1);
+      break;
+    case SPT_FLOOD_FILL_NOT:
+      DocPrint(doc,"{(%d,%d),TRUE}",tmpg->p.x1,tmpg->p.y1);
+      break;
+    case SPT_CIRCLE:
+      DocPrint(doc,"{(%d,%d):%d}",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
+      break;
+    case SPT_THICK:
+      DocPrint(doc,"{%d}",tmpg->t.thick);
+      break;
+    case SPT_ELLIPSE:
+      DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->pwha.x1,tmpg->pwha.y1,
+            tmpg->pwha.width,tmpg->pwha.height,180/pi*Wrap(tmpg->pwha.angle));
+      break;
+    case SPT_POLYGON:
+      DocPrint(doc,"{%d,(%d,%d):(%d,%d),%0.4f}",tmpg->pwhas.sides,
+            tmpg->pwhas.x1,tmpg->pwhas.y1,
+            tmpg->pwhas.width,tmpg->pwhas.height,
+            180/pi*Wrap(tmpg->pwhas.angle));
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      DocPrint(doc,"{(%d,%d),\"%Q\"}",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
+      break;
+    case SPT_POLYLINE:
+      ptr=&tmpg->nu.u;
+      DocPrint(doc,"{");
+      for (i=0;i<tmpg->nu.num;i++,ptr+=2) {
+        DocPrint(doc,"(%d,%d)",ptr[0],ptr[1]);
+        if (i+1<tmpg->nu.num) DocPrint(doc,",");
+        if (i&3==3 && i+1<tmpg->nu.num)
+          DocPrint(doc,"\n");
+      }
+      DocPrint(doc,"}");
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      ptr=&tmpg->nu.u;
+      DocPrint(doc,"{");
+      for (i=0;i<tmpg->nu.num;i++,ptr+=3) {
+        DocPrint(doc,"(%d,%d,%d)",ptr[0],ptr[1],ptr[2]);
+        if (i+1<tmpg->nu.num) DocPrint(doc,",");
+        if (i&3==3 && i+1<tmpg->nu.num)
+          DocPrint(doc,"\n");
+      }
+      if (tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE2||
+            tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE3)
+        DocPrint(doc,",FALSE}");
+      else
+        DocPrint(doc,",TRUE}");
+      break;
+    case SPT_POLYPT:
+      DocPrint(doc,"{(%d,%d),",tmpg->npu.x,tmpg->npu.y);
+      ptr=&tmpg->npu.u;
+      col=16;
+      for (i=0;i<tmpg->npu.num;i++) {
+        DocPrint(doc,"%d",BFieldExtU32(ptr,i*3,3));
+        if (++col>=64 && i+1<tmpg->npu.num) {
+          DocPrint(doc,"\n");
+          col=0;
+        }
+      }
+      DocPrint(doc,"}");
+      break;
+    case SPT_BITMAP:
+      DocPrint(doc,"{(%d,%d):(%d,%d),\n",tmpg->pwhu.x1,tmpg->pwhu.y1,
+            tmpg->pwhu.width,tmpg->pwhu.height);
+      width_internal=(tmpg->pwhu.width+7)&~7;
+      if (width_internal<80)
+        k=width_internal;
+      else
+        k=64;
+      ptr=&tmpg->pwhu.u;
+      col=0;
+      for (j=0;j<tmpg->pwhu.height;j++)
+        for (i=0;i<width_internal;i++,ptr(U8 *)++) {
+          if (i>=tmpg->pwhu.width)
+            DocPrint(doc,"_");
+          else if (*ptr(U8 *)<16)
+            DocPrint(doc,"%X",*ptr(U8 *));
+          else
+            DocPrint(doc,"%c",CH_SHIFT_SPACE);
+          if (++col>=k && (i+1<width_internal||j+1<tmpg->pwhu.height)) {
+            DocPrint(doc,"\n");
+            col=0;
+          }
+        }
+      DocPrint(doc,"}");
+      break;
+    case SPT_MESH:
+      DocPrint(doc,"{FALSE,");
+      p=&tmpg->mu.u;
+      col=0;
+      for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
+        DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
+        if (i+1<tmpg->mu.vertex_cnt) DocPrint(doc,",");
+        if (++col==4) {
+          DocPrint(doc,"\t//%d\n",i);
+          col=0;
+        }
+      }
+      DocPrint(doc,":");
+      tri=p;
+      for (i=0;i<tmpg->mu.tri_cnt;i++,tri++) {
+        DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
+              tri->nums[0],tri->nums[1],tri->nums[2]);
+        if (i+1<tmpg->mu.tri_cnt) DocPrint(doc,",");
+        if (++col>=3 && i+1<tmpg->mu.tri_cnt) {
+          DocPrint(doc,"\n");
+          col=0;
+        }
+      }
+      DocPrint(doc,"}");
+      break;
+    case SPT_SHIFTABLE_MESH:
+      DocPrint(doc,"{TRUE,(%d,%d,%d):",tmpg->pmu.x,tmpg->pmu.y,tmpg->pmu.z);
+      p=&tmpg->pmu.u;
+      col=1;
+      for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) {
+        DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
+        if (i+1<tmpg->pmu.vertex_cnt) DocPrint(doc,",");
+        if (++col==4) {
+          DocPrint(doc,"\t//%d\n",i);
+          col=0;
+        }
+      }
+      DocPrint(doc,":");
+      tri=p;
+      for (i=0;i<tmpg->pmu.tri_cnt;i++,tri++) {
+        DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
+              tri->nums[0],tri->nums[1],tri->nums[2]);
+        if (i+1<tmpg->pmu.tri_cnt) DocPrint(doc,",");
+        if (++col>=3 && i+1<tmpg->pmu.tri_cnt) {
+          DocPrint(doc,"\n");
+          col=0;
+        }
+      }
+      DocPrint(doc,"}");
+      break;
+  }
+    DocPrint(doc,";\n");
+}
+
+public U0 Sprite2Code(CDoc *doc=NULL,U8 *elems)
+{//Sprite to text.
+  CSprite *tmpg=elems-offset(CSprite.start);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    SpriteElem2Code(doc,tmpg);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+}
+
+CSprite *Code2SpriteElem(CCmpCtrl *cc,I64 type)
+{
+  I64 i,num1,num2,size;
+  CSprite *res,g;
+  CColorROPU32 color;
+  U8 *st,*ptr;
+  CQueD3I32 headp,*tmpp,*tmpa1;
+  CQueMeshTri headt,*tmpt,*tmpt1;
+  CQueVectU8 *tmpv;
+  MemSet(&g,0,sizeof(CSprite));
+  switch (type) {
+    start:
+      case SPT_COLOR:
+      case SPT_DITHER_COLOR:
+        st=LexFirstRem(cc,"}");
+        color=Str2ColorU32(st);
+        Free(st);
+        Lex(cc); //Skip color
+        g.c.color=color.c0.color;
+        if (color&ROPF_DITHER) {
+          g.d.dither_color.u8[1]=color.c1.color;
+          g.type=SPT_DITHER_COLOR;
+        } else
+          g.type=SPT_COLOR;
+        break;
+      case SPT_TRANSFORM_ON:
+      case SPT_TRANSFORM_OFF:
+        Lex(cc); //Skip {
+        if (LexExpressionI64(cc))
+          g.type=SPT_TRANSFORM_ON;
+        else
+          g.type=SPT_TRANSFORM_OFF;
+        break;
+      case SPT_LINE:
+      case SPT_ARROW:
+      case SPT_PLANAR_SYMMETRY:
+        Lex(cc); //Skip {
+        g.type=type;
+        LexD2I32(cc,&g.pp.x1);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        LexD2I32(cc,&g.pp.x2);
+        break;
+      case SPT_RECT:
+      case SPT_ROTATED_RECT:
+        Lex(cc); //Skip {
+        LexD2I32(cc,&g.pp.x1);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+        LexD2I32(cc,&g.pp.x2);
+        g.ppa.x2+=g.pp.x1;
+        g.ppa.y2+=g.pp.y1;
+        if (cc->token==',') {
+          Lex(cc); //Skip ,
+          g.ppa.angle=pi/180*LexExpressionF64(cc);
+          g.type=SPT_ROTATED_RECT;
+        } else
+          g.type=SPT_RECT;
+        break;
+      case SPT_PT:
+      case SPT_SHIFT:
+        Lex(cc); //Skip {
+        g.type=type;
+        LexD2I32(cc,&g.p.x1);
+        break;
+      case SPT_FLOOD_FILL:
+      case SPT_FLOOD_FILL_NOT:
+        Lex(cc); //Skip {
+        LexD2I32(cc,&g.p.x1);
+        if (cc->token==',') {
+          Lex(cc); //Skip ,
+          i=LexExpressionI64(cc);
+        } else
+          i=0;
+        if (i)
+          g.type=SPT_FLOOD_FILL_NOT;
+        else
+          g.type=SPT_FLOOD_FILL;
+        break;
+      case SPT_THICK:
+        Lex(cc); //Skip {
+        g.t.thick=LexExpressionI64(cc);
+        g.type=SPT_THICK;
+        break;
+      case SPT_CIRCLE:
+        Lex(cc); //Skip {
+        g.type=SPT_CIRCLE;
+        LexD2I32(cc,&g.pr.x1);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+        g.pr.radius=LexExpressionI64(cc);
+        break;
+      case SPT_POLYGON:
+        Lex(cc); //Skip {
+        g.pwhas.sides=LexExpressionI64(cc);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+      case SPT_ELLIPSE:
+        Lex(cc); //Skip {
+        g.type=type;
+        LexD2I32(cc,&g.pwha.x1);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+        LexD2I32(cc,&g.pwha.width);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        g.pwha.angle=pi/180*LexExpressionF64(cc);
+        break;
+    end:
+      size=SpriteElemSize(&g)+offset(CSprite.start);
+      res=MAlloc(size);
+      MemCpy(res,&g,size);
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      Lex(cc); //Skip {
+      g.type=type;
+      LexD2I32(cc,&g.ps.x1);
+      if (cc->token!=',')
+        LexExcept(cc,"Expecting ',' at ");
+      if (Lex(cc)==TK_STR)  //Skip ,
+        st=LexExtStr(cc);
+      else
+        LexExcept(cc,"Expecting string at ");
+      size=SpriteElemQuedBaseSize(type);
+      i=StrLen(st)+1;
+      res=MAlloc(size+i);
+      MemCpy(res,&g,size);
+      MemCpy(res(U8 *)+size,st,i);
+      Free(st);
+      break;
+    case SPT_POLYLINE:
+      Lex(cc); //Skip {
+      g.type=SPT_POLYLINE;
+      QueInit(&headp);
+      while (cc->token=='(') {
+        tmpp=CAlloc(sizeof(CQueD3I32));
+        LexD2I32(cc,&tmpp->p);
+        QueIns(tmpp,headp.last);
+        g.nu.num++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (g.nu.num<2)
+        LexExcept(cc,"Expecting point at ");
+      size=SpriteElemQuedBaseSize(SPT_POLYLINE);
+      res=MAlloc(size+g.nu.num*sizeof(CD2I32));
+      MemCpy(res,&g,size);
+      ptr=&res->nu.u;
+      tmpp=headp.next;
+      while (tmpp!=&headp) {
+        tmpa1=tmpp->next;
+        MemCpy(ptr,&tmpp->p,sizeof(CD2I32));
+        ptr+=sizeof(CD2I32);
+        Free(tmpp);
+        tmpp=tmpa1;
+      }
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      Lex(cc); //Skip {
+      QueInit(&headp);
+      while (cc->token=='(') {
+        tmpp=CAlloc(sizeof(CQueD3I32));
+        LexD3I32(cc,&tmpp->p);
+        QueIns(tmpp,headp.last);
+        g.nu.num++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (g.nu.num<2)
+        LexExcept(cc,"Expecting point at ");
+      size=SpriteElemQuedBaseSize(type);
+      res=MAlloc(size+g.nu.num*sizeof(CD3I32));
+      if (LexExpressionI64(cc)) {
+        if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
+          g.type=SPT_BSPLINE2_CLOSED;
+        else
+          g.type=SPT_BSPLINE3_CLOSED;
+      } else {
+        if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
+          g.type=SPT_BSPLINE2;
+        else
+          g.type=SPT_BSPLINE3;
+      }
+      MemCpy(res,&g,size);
+      ptr=&res->nu.u;
+      tmpp=headp.next;
+      while (tmpp!=&headp) {
+        tmpa1=tmpp->next;
+        MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
+        ptr+=sizeof(CD3I32);
+        Free(tmpp);
+        tmpp=tmpa1;
+      }
+      break;
+    case SPT_POLYPT:
+      Lex(cc); //Skip {
+      LexD2I32(cc,&g.npu.x);
+      if (cc->token!=',')
+        LexExcept(cc,"Expecting ',' at ");
+      tmpv=QueVectU8New;
+      while (TRUE) {
+        if (!(i=LexGetChar(cc)))
+          LexExcept(cc,"Expecting '}' at ");
+        if (i=='}')
+          break;
+        if ('0'<=i<='7')
+          QueVectU8Put(tmpv,g.npu.num++,i-'0');
+      }
+      Bts(&cc->flags,CCf_USE_LAST_U16);
+      Lex(cc); //Load '}'
+      g.type=SPT_POLYPT;
+      size=SpriteElemQuedBaseSize(SPT_POLYPT);
+      res=CAlloc(size+(g.npu.num*3+7)>>3);
+      MemCpy(res,&g,size);
+      ptr=&res->npu.u;
+      for (i=0;i<g.npu.num;i++)
+        BFieldOrU32(ptr,i*3,QueVectU8Get(tmpv,i));
+      QueVectU8Del(tmpv);
+      break;
+    case SPT_BITMAP:
+      Lex(cc); //Skip {
+      LexD2I32(cc,&g.pwhu.x1);
+      if (cc->token!=':')
+        LexExcept(cc,"Expecting ':' at ");
+      Lex(cc); //Skip :
+      LexD2I32(cc,&g.pwhu.width);
+      if (cc->token!=',')
+        LexExcept(cc,"Expecting ',' at ");
+      tmpv=QueVectU8New;
+      num1=0;
+      while (TRUE) {
+        if (!(i=ToUpper(LexGetChar(cc))))
+          LexExcept(cc,"Expecting '}' at ");
+        if (i=='}')
+          break;
+        if ('0'<=i<='9')
+          QueVectU8Put(tmpv,num1++,i-'0');
+        else if ('A'<=i<='F')
+          QueVectU8Put(tmpv,num1++,i-'A'+10);
+        else if (i==CH_SPACE||i==CH_SHIFT_SPACE)
+          QueVectU8Put(tmpv,num1++,TRANSPARENT);
+        else if (i=='_')
+          QueVectU8Put(tmpv,num1++,0);
+      }
+      Bts(&cc->flags,CCf_USE_LAST_U16);
+      Lex(cc); //Load '}'
+      g.type=SPT_BITMAP;
+      size=SpriteElemQuedBaseSize(SPT_BITMAP);
+      res=CAlloc(size+num1);
+      MemCpy(res,&g,size);
+      ptr=&res->pwhu.u;
+      for (i=0;i<num1;i++)
+        *ptr++=QueVectU8Get(tmpv,i);
+      QueVectU8Del(tmpv);
+      break;
+    case SPT_MESH:
+    case SPT_SHIFTABLE_MESH:
+      Lex(cc); //Skip {
+      if (LexExpressionI64(cc)) {
+        g.type=SPT_SHIFTABLE_MESH;
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        LexD3I32(cc,&g.pmu.x);
+        if (cc->token!=':')
+          LexExcept(cc,"Expecting ':' at ");
+        Lex(cc); //Skip :
+      } else {
+        g.type=SPT_MESH;
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+      }
+      num1=0;
+      QueInit(&headp);
+      while (cc->token=='(') {
+        tmpp=CAlloc(sizeof(CQueD3I32));
+        LexD3I32(cc,&tmpp->p);
+        QueIns(tmpp,headp.last);
+        num1++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (cc->token!=':')
+        LexExcept(cc,"Expecting ':' at ");
+      Lex(cc); //Skip :
+      num2=0;
+      QueInit(&headt);
+      while (cc->token=='(') {
+        tmpt=CAlloc(sizeof(CQueMeshTri));
+        st=LexFirstRem(cc,",");
+        tmpt->color=Str2ColorU32(st);
+        Free(st);
+        Lex(cc); //Skip color
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        tmpt->nums[0]=LexExpressionI64(cc);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        tmpt->nums[1]=LexExpressionI64(cc);
+        if (cc->token!=',')
+          LexExcept(cc,"Expecting ',' at ");
+        Lex(cc); //Skip ,
+        tmpt->nums[2]=LexExpressionI64(cc);
+        if (cc->token!=')')
+          LexExcept(cc,"Expecting ')' at ");
+        Lex(cc); //Skip )
+        QueIns(tmpt,headt.last);
+        num2++;
+        if (cc->token==',')
+          Lex(cc); //Skip ,
+      }
+      if (g.type==SPT_MESH) {
+        g.mu.vertex_cnt=num1;
+        g.mu.tri_cnt=num2;
+        size=SpriteElemQuedBaseSize(SPT_MESH);
+      } else {
+        g.pmu.vertex_cnt=num1;
+        g.pmu.tri_cnt=num2;
+      }
+      size=SpriteElemQuedBaseSize(g.type);
+      res=MAlloc(size+num1*sizeof(CD3I32)+num2*sizeof(CMeshTri));
+      MemCpy(res,&g,size);
+      ptr=res(U8 *)+size;
+      tmpp=headp.next;
+      while (tmpp!=&headp) {
+        tmpa1=tmpp->next;
+        MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
+        ptr+=sizeof(CD3I32);
+        Free(tmpp);
+        tmpp=tmpa1;
+      }
+      tmpt=headt.next;
+      while (tmpt!=&headt) {
+        tmpt1=tmpt->next;
+        MemCpy(ptr,&tmpt->start,sizeof(CMeshTri));
+        ptr+=sizeof(CMeshTri);
+        Free(tmpt);
+        tmpt=tmpt1;
+      }
+      break;
+  }
+  if (cc->token!='}')
+    LexExcept(cc,"Expecting '}' at ");
+  if (Lex(cc)!=';')
+    LexExcept(cc,"Expecting ';' at ");
+  return res;
+}
+
+public U8 *Code2Sprite(CDoc *doc,I64 *_size=NULL)
+{//Text to sprite.
+  CSprite head;
+  U8 *res;
+  Bool okay=TRUE,unlock_doc=DocLock(doc);
+  CCmpCtrl *cc=CmpCtrlNew(,CCF_DONT_FREE_BUF);
+  CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;
+  CHashGeneric *tmph;
+  I64 i,size=0;
+  QueInit(&head);
+  LexAttachDoc(cc,,doc);
+  try {
+    do {
+      cc->htc.hash_table_lst=NULL;
+      if (Lex(cc)==TK_IDENT && //Skip ;
+            (tmph=HashFind(cc->cur_str,gr.sprite_hash,SPHT_ELEM_CODE))) {
+        i=tmph->user_data0;
+        cc->htc.hash_table_lst=old_hash_table_lst;
+        if (Lex(cc)=='{') //Skip ident
+          QueIns(Code2SpriteElem(cc,i),head.last);
+      } else if (cc->token)
+        LexExcept(cc,"Expecting sprite element type name at ");
+    } while (cc->token);
+    okay=TRUE;
+  } catch {
+    Fs->catch_except=TRUE;
+    okay=FALSE;
+  }
+  if (unlock_doc)
+    DocUnlock(doc);
+  if (okay) {
+    CmpCtrlDel(cc); //TODO: can crash
+    res=SpriteQue2Sprite(&head,&size);
+  } else {
+    res=NULL;
+    size=0;
+  }
+  if (_size) *_size=size;
+  QueDel(&head);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/SpriteEd.HC.HTML b/public/Wb/Home/Src/Adam/Gr/SpriteEd.HC.HTML new file mode 100755 index 0000000..8117f52 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/SpriteEd.HC.HTML @@ -0,0 +1,1209 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+CSprite *SpriteSetSettings(CDC *dc=NULL,CSprite *head,I64 elem_num,
+        I64 x=0,I64 y=0,CColorROPU32 *_color=NULL,I64 *_thick=NULL,
+        I64 *_xx=NULL,I64 *_yy=NULL)
+{
+  CSprite *res=head->next;
+  I64 thick=1,xx=0,yy=0;
+  CColorROPU32 color=BLACK;
+  if (dc) DCRst(dc);
+  while (elem_num-->0 && res!=head) {
+    switch (res->type&SPG_TYPE_MASK) {
+      case SPT_COLOR:
+        color=res->c.color;
+        if (dc) dc->color=color;
+        break;
+      case SPT_DITHER_COLOR:
+        color=res->d.dither_color.u8[0]|
+              res->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER;
+        if (dc) dc->color=color;
+        break;
+      case SPT_THICK:
+        thick=res->t.thick;
+        if (dc) dc->thick=thick;
+        break;
+      case SPT_SHIFT:
+        xx+=res->p.x1;
+        yy+=res->p.y1;
+        x+=res->p.x1;
+        y+=res->p.y1;
+        break;
+      case SPT_PLANAR_SYMMETRY:
+        if (dc) {
+          if (DCSymmetry3Set(dc,res->pp.x1+x,res->pp.y1+y,0,
+                res->pp.x2+x,res->pp.y2+y,0,
+                res->pp.x2+x,res->pp.y2+y,1))
+            dc->flags|=DCF_SYMMETRY;
+          else
+            dc->flags&=~DCF_SYMMETRY;
+        }
+        break;
+    }
+    res=res->next;
+  }
+  if (_color) *_color=color;
+  if (_thick) *_thick=thick;
+  if (_xx) *_xx=xx;
+  if (_yy) *_yy=yy;
+  return res;
+}
+
+Bool SpritePolyPtPlot(CSprite *head,I64 x,I64 y,I64)
+{
+  CSprite *tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_PT));
+  tmpg->type=SPT_PT;
+  tmpg->p.x1=x;
+  tmpg->p.y1=y;
+  QueIns(tmpg,head->last);
+  return TRUE;
+}
+
+CSprite *Sprite2SpriteQue(U8 *elems)
+{
+  I64 s;
+  CSprite *res=CAlloc(sizeof(CSprite)),
+        *tmpg=elems-offset(CSprite.start),*tmpg1;
+  QueInit(res);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    tmpg1=MAlloc(SpriteElemSize(tmpg)+offset(CSprite.start));
+    s=SpriteElemSize(tmpg);
+    MemCpy(&tmpg1->start,&tmpg->start,s);
+    QueIns(tmpg1,res->last);
+    tmpg(U8 *)+=s;
+  }
+  return res;
+}
+
+U8 *SpriteQue2Sprite(CSprite *head,I64 *_size=NULL)
+{
+  I64 i,size=sprite_elem_base_sizes[SPT_END];
+  CSprite *tmpg=head->next;
+  U8 *res,*dst;
+  while (tmpg!=head) {
+    size+=SpriteElemSize(tmpg);
+    tmpg=tmpg->next;
+  }
+  if (_size) *_size=size;
+  res=dst=MAlloc(size);
+  tmpg=head->next;
+  while (tmpg!=head) {
+    i=SpriteElemSize(tmpg);
+    MemCpy(dst,&tmpg->start,i);
+    dst+=i;
+    tmpg=tmpg->next;
+  }
+  *dst=SPT_END;
+  return res;
+}
+
+U0 SpriteEdUpdate(CDoc *doc,CDocEntry *doc_ce,CSprite *head)
+{
+  CDocBin *tmpb=doc_ce->bin_data;
+  I64 size;
+  Bool unlock=DocLock(doc);
+  Free(tmpb->data);
+  tmpb->data=SpriteQue2Sprite(head,&size);
+  tmpb->size=size;
+  if (unlock)
+    DocUnlock(doc);
+}
+
+U0 SpriteSetOrigin(CSprite *head,I64 dx,I64 dy,I64 dz)
+{
+  I64 i;
+  I32 *ptr;
+  CD3I32 *p;
+  CSprite *tmpg=head->next;
+  while (tmpg!=head) {
+    if (Bt(&tmpg->type,SPf_SEL))
+      switch (tmpg->type&SPG_TYPE_MASK) {
+        case SPT_ARROW:
+        case SPT_LINE:
+        case SPT_PLANAR_SYMMETRY:
+        case SPT_RECT:
+        case SPT_ROTATED_RECT:
+          tmpg->pp.x2+=dx;
+          tmpg->pp.y2+=dy;
+        case SPT_PT:
+        case SPT_FLOOD_FILL:
+        case SPT_FLOOD_FILL_NOT:
+        case SPT_TEXT:
+        case SPT_TEXT_BOX:
+        case SPT_TEXT_DIAMOND:
+        case SPT_CIRCLE:
+        case SPT_BITMAP:
+        case SPT_ELLIPSE:
+        case SPT_POLYGON:
+          tmpg->p.x1+=dx;
+          tmpg->p.y1+=dy;
+          break;
+        case SPT_POLYLINE:
+          ptr=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++) {
+            ptr[i<<1]+=dx;
+            ptr[i<<1+1]+=dy;
+          }
+          break;
+        case SPT_POLYPT:
+          tmpg->npu.x+=dx;
+          tmpg->npu.y+=dy;
+          break;
+        case SPT_BSPLINE2:
+        case SPT_BSPLINE3:
+        case SPT_BSPLINE2_CLOSED:
+        case SPT_BSPLINE3_CLOSED:
+          p=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++,p++) {
+            p->x+=dx;
+            p->y+=dy;
+            p->z+=dz;
+          }
+          break;
+        case SPT_MESH:
+          p=&tmpg->mu.u;
+          for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
+            p->x+=dx;
+            p->y+=dy;
+            p->z+=dz;
+          }
+          break;
+        case SPT_SHIFTABLE_MESH:
+          tmpg->pmu.x+=dx;
+          tmpg->pmu.y+=dy;
+          tmpg->pmu.z+=dz;
+          break;
+      }
+    tmpg=tmpg->next;
+  }
+}
+
+CSprite *SpriteTransformCircle(I64 *r,CSprite *tmpg)
+{
+  I64 x,y,z;
+  F64 m1,arg1,m2,radius=tmpg->pr.radius<<16;
+  CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(SPT_ELLIPSE));
+  tmpg1->type=SPT_ELLIPSE;
+
+  x=tmpg->pr.x1; y=tmpg->pr.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->pwha.x1=x;
+  tmpg1->pwha.y1=y;
+
+  x=radius; y=0; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m1,&arg1,x,y);
+
+  x=0; y=radius; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  m2=Sqrt(x*x+y*y);
+
+  tmpg1->pwha.width =ToI64(m1)/0x10000;
+  tmpg1->pwha.height=ToI64(m2)/0x10000;
+  tmpg1->pwha.angle=-arg1;
+
+  tmpg1->type|=tmpg->type&SPF_SEL;
+  return tmpg1;
+}
+
+CSprite *SpriteTransformEllipse(I64 *r,CSprite *tmpg)
+{
+  I64 x,y,z;
+  F64 m1,arg1,m2,arg2,s,c,x_radius=tmpg->pwha.width<<16,
+        y_radius=tmpg->pwha.height<<16;
+  CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(tmpg->type&SPG_TYPE_MASK));
+  tmpg1->type=tmpg->type;
+  if (tmpg->type&SPG_TYPE_MASK==SPT_POLYGON)
+    tmpg1->pwhas.sides=tmpg->pwhas.sides;
+
+  x=tmpg->pwha.x1; y=tmpg->pwha.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->pwha.x1=x;
+  tmpg1->pwha.y1=y;
+
+  c=Cos(-tmpg->pwha.angle);
+  s=Sin(-tmpg->pwha.angle);
+
+  x=x_radius*c;
+  y=x_radius*s;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m1,&arg1,x,y);
+
+  x=-y_radius*s;
+  y=y_radius*c;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m2,&arg2,x,y);
+  m2*=Abs(Sin(arg2-arg1));
+
+  tmpg1->pwha.width=ToI64(m1)/0x10000;
+  if (tmpg1->pwha.width<1) tmpg1->pwha.width=1;
+  tmpg1->pwha.height=ToI64(m2)/0x10000;
+  if (tmpg1->pwha.height<1) tmpg1->pwha.height=1;
+  tmpg1->pwha.angle=-arg1;
+
+  tmpg1->type|=tmpg->type&SPF_SEL;
+  return tmpg1;
+}
+
+CSprite *SpriteTransformRect(I64 *r,CSprite *tmpg,F64 theta)
+{
+  I64 x,y,z,w,h;
+  F64 m1,arg1,m2,arg2,s,c,
+        x_radius=(tmpg->pp.x2-tmpg->pp.x1)<<16,
+        y_radius=(tmpg->pp.y2-tmpg->pp.y1)<<16;
+  CSprite *tmpg1=CAlloc(SpriteElemQuedBaseSize(SPT_ROTATED_RECT));
+  tmpg1->type=SPT_ROTATED_RECT;
+
+  x=tmpg->pp.x1; y=tmpg->pp.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->ppa.x1=x;
+  tmpg1->ppa.y1=y;
+
+  c=Cos(-theta);
+  s=Sin(-theta);
+
+  x=x_radius*c;
+  y=x_radius*s;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m1,&arg1,x,y);
+
+  x=-y_radius*s;
+  y=y_radius*c;
+  z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  R2P(&m2,&arg2,x,y);
+  m2*=Abs(Sin(arg2-arg1));
+
+  w=ToI64(m1)/0x10000;
+  if (w<1) w=1;
+  h=ToI64(m2)/0x10000;
+  if (h<1) h=1;
+  tmpg1->ppa.x2=tmpg1->ppa.x1+w;
+  tmpg1->ppa.y2=tmpg1->ppa.y1+h;
+  tmpg1->ppa.angle=-arg1;
+
+  tmpg1->type|=tmpg->type&SPF_SEL;
+  return tmpg1;
+}
+
+CSprite *SpriteTransformBitMap(I64 *r,CSprite *tmpg)
+{
+  CDC *img,*dc3;
+  U8 *elems;
+  I64 x,y,z,minx,maxx,miny,maxy,minz,maxz;
+  CSprite *tmpg1;
+
+  x=tmpg->pwhu.x1; y=tmpg->pwhu.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  minx=maxx=x;
+  miny=maxy=y;
+  minz=maxz=z;
+
+  x=tmpg->pwhu.x1; y=tmpg->pwhu.y1+tmpg->pwhu.height; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  if (x<minx) minx=x;
+  if (x>maxx) maxx=x;
+  if (y<miny) miny=y;
+  if (y>maxy) maxy=y;
+  if (z<minz) minz=z;
+  if (z>maxz) maxz=z;
+
+  x=tmpg->pwhu.x1+tmpg->pwhu.width; y=tmpg->pwhu.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  if (x<minx) minx=x;
+  if (x>maxx) maxx=x;
+  if (y<miny) miny=y;
+  if (y>maxy) maxy=y;
+  if (z<minz) minz=z;
+  if (z>maxz) maxz=z;
+
+  x=tmpg->pwhu.x1+tmpg->pwhu.width; y=tmpg->pwhu.y1+tmpg->pwhu.height; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  if (x<minx) minx=x;
+  if (x>maxx) maxx=x;
+  if (y<miny) miny=y;
+  if (y>maxy) maxy=y;
+  if (z<minz) minz=z;
+  if (z>maxz) maxz=z;
+
+  dc3=DCNew(maxx-minx+1,maxy-miny+1);
+
+  img=CAlloc(sizeof(CDC));
+  img->width=tmpg->pwhu.width;
+  img->width_internal=(tmpg->pwhu.width+7)&~7;
+  img->height=tmpg->pwhu.height;
+  img->body=&tmpg->pwhu.u;
+  img->dc_signature=DCS_SIGNATURE_VAL;
+
+  dc3->color=TRANSPARENT;
+  GrRect(dc3,0,0,maxx-minx+1,maxy-miny+1);
+
+  Free(dc3->r);
+  DCMat4x4Set(dc3,r);
+  dc3->flags|=DCF_TRANSFORMATION;
+
+  dc3->x=tmpg->pwhu.x1-minx;
+  dc3->y=tmpg->pwhu.y1-miny;
+  dc3->z=-minz;
+  GrBlot3(dc3,0,0,0,img);
+  Free(img);
+
+  elems=DC2Sprite(dc3);
+  dc3->r=NULL;
+  DCDel(dc3);
+  tmpg1=CAlloc(offset(CSprite.start)+MSize(elems));
+  MemCpy(tmpg1(U8 *)+offset(CSprite.start),elems,MSize(elems));
+  tmpg1->type=tmpg->type;
+
+  x=tmpg->pwhu.x1; y=tmpg->pwhu.y1; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  tmpg1->pwhu.x1=x;
+  tmpg1->pwhu.y1=y;
+
+  return tmpg1;
+}
+
+U0 SpriteTransformQue(CSprite *head,I64 *r)
+{
+  I64 i,j,k,num,x,y,z,x1,y1,z1,x2,y2,z2,x3,y3,z3;
+  I32 *ptr;
+  CD3I32 *p;
+  CSprite *tmpg=head->next,head2,*tmpg1,*tmpg2,*tmpg3;
+  while (tmpg!=head) {
+    if (Bt(&tmpg->type,SPf_SEL))
+      switch (tmpg->type&SPG_TYPE_MASK) {
+        case SPT_THICK:
+          tmpg->t.thick*=Sqrt(Mat4x4NormSqr65536(r))/65536;
+          if (tmpg->t.thick<0) tmpg->t.thick=0;
+          break;
+        case SPT_PLANAR_SYMMETRY:
+        case SPT_ARROW:
+        case SPT_LINE:
+          x=tmpg->pp.x2; y=tmpg->pp.y2; z=0;
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          tmpg->pp.x2=x;
+          tmpg->pp.y2=y;
+        case SPT_PT:
+        case SPT_FLOOD_FILL:
+        case SPT_FLOOD_FILL_NOT:
+        case SPT_TEXT:
+        case SPT_TEXT_BOX:
+        case SPT_TEXT_DIAMOND:
+          x=tmpg->p.x1; y=tmpg->p.y1; z=0;
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          tmpg->p.x1=x;
+          tmpg->p.y1=y;
+          break;
+        case SPT_BITMAP:
+          tmpg1=SpriteTransformBitMap(r,tmpg);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_ROTATED_RECT:
+          tmpg1=SpriteTransformRect(r,tmpg,tmpg->ppa.angle);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_RECT:
+          tmpg1=SpriteTransformRect(r,tmpg,0);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_CIRCLE:
+          tmpg1=SpriteTransformCircle(r,tmpg);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_ELLIPSE:
+        case SPT_POLYGON:
+          tmpg1=SpriteTransformEllipse(r,tmpg);
+          QueIns(tmpg1,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg1;
+          break;
+        case SPT_POLYLINE:
+          ptr=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++) {
+            x=ptr[i<<1]; y=ptr[i<<1+1]; z=0;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            ptr[i<<1]=x;
+            ptr[i<<1+1]=y;
+          }
+          break;
+        case SPT_POLYPT:
+          QueInit(&head2);
+          x=tmpg->npu.x; y=tmpg->npu.y; z=0;
+          x1=x; y1=y; z1=z;  //unrotated cur coordinates
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          ptr=&tmpg->npu.u;
+          k=tmpg->npu.num*3;
+          x2=x; y2=y; z2=z;  //rotated start coordinates
+          x3=x; y3=y; z3=z;  //lag 1 rotated coordinates
+          for (i=0;i<k;i+=3) {
+            j=BFieldExtU32(ptr,i,3);
+            x1+=gr_x_offsets[j];
+            y1+=gr_y_offsets[j];
+            x=x1; y=y1; z=z1;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            Line(&head2,x3-x2,y3-y2,0,x-x2,y-y2,0,&SpritePolyPtPlot);
+            x3=x; y3=y; z3=z;
+          }
+
+          num=0;
+          tmpg1=head2.next;
+          x3=0; y3=0; z3=0;
+          while (tmpg1!=&head2) {
+            tmpg2=tmpg1->next;
+            if (tmpg1->p.x1==x3 && tmpg1->p.y1==y3) {
+              QueRem(tmpg1);
+              Free(tmpg1);
+            } else {
+              num++;
+              x3=tmpg1->p.x1;
+              y3=tmpg1->p.y1;
+            }
+            tmpg1=tmpg2;
+          }
+
+          tmpg3=CAlloc(SpriteElemQuedBaseSize(SPT_POLYPT)+(num*3+7)>>3);
+          tmpg3->npu.x=x2;
+          tmpg3->npu.y=y2;
+          ptr=&tmpg3->npu.u;
+          x3=0;y3=0; z3=0;
+          i=0;
+          tmpg1=head2.next;
+          while (tmpg1!=&head2) {
+            tmpg2=tmpg1->next;
+            BFieldOrU32(ptr,i,
+                  polypt_map[SignI64(tmpg1->p.x1-x3)+1+
+                  3*(SignI64(tmpg1->p.y1-y3)+1)]);
+            i+=3;
+            x3=tmpg1->p.x1;y3=tmpg1->p.y1;
+            QueRem(tmpg1);
+            Free(tmpg1);
+            tmpg1=tmpg2;
+          }
+          tmpg3->type=SPT_POLYPT|tmpg->type&SPF_SEL;
+          tmpg3->npu.num=num;
+          QueIns(tmpg3,tmpg);
+          QueRem(tmpg);
+          Free(tmpg);
+          tmpg=tmpg3;
+          break;
+        case SPT_BSPLINE2:
+        case SPT_BSPLINE3:
+        case SPT_BSPLINE2_CLOSED:
+        case SPT_BSPLINE3_CLOSED:
+          p=&tmpg->nu.u;
+          for (i=0;i<tmpg->nu.num;i++,p++) {
+            x=p->x; y=p->y; z=p->z;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            p->x=x;
+            p->y=y;
+            p->z=z;
+          }
+          break;
+        case SPT_SHIFTABLE_MESH:
+          x=tmpg->pmu.x; y=tmpg->pmu.y; z=tmpg->pmu.z;
+          Mat4x4MulXYZ(r,&x,&y,&z);
+          tmpg->pmu.x=x;
+          tmpg->pmu.y=y;
+          tmpg->pmu.z=z;
+          p=&tmpg->pmu.u;
+          for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) {
+            x=p->x; y=p->y; z=p->z;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            p->x=x;
+            p->y=y;
+            p->z=z;
+          }
+          break;
+        case SPT_MESH:
+          p=&tmpg->mu.u;
+          for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
+            x=p->x; y=p->y; z=p->z;
+            Mat4x4MulXYZ(r,&x,&y,&z);
+            p->x=x;
+            p->y=y;
+            p->z=z;
+          }
+          break;
+      }
+    tmpg=tmpg->next;
+  }
+}
+
+I64 SpriteQueSelCnt(CSprite *head,Bool val=TRUE)
+{
+  I64 res=0;
+  CSprite *tmpg=head->next;
+  val=ToBool(val);
+  while (tmpg!=head) {
+    if (Bt(&tmpg->type,SPf_SEL)==val)
+      res++;
+    tmpg=tmpg->next;
+  }
+  return res;
+}
+
+I64 SpriteQueSelAll(CSprite *head,Bool val=TRUE)
+{
+  I64 res=0;
+  CSprite *tmpg=head->next;
+  while (tmpg!=head) {
+    BEqu(&tmpg->type,SPf_SEL,val);
+    res++;
+    tmpg=tmpg->next;
+  }
+  return res;
+}
+
+Bool SpriteEdText(CSprite **_head,I64 *_cur_elem_num)
+{
+  Bool res;
+  CSprite *head=*_head;
+  U8 *elems=SpriteQue2Sprite(head);
+  CDoc *doc=DocNew,*doc2,*old_put=DocPut;
+  StrPrint(doc->filename.name,"AI:0x%X",doc);
+  DocPrint(doc,"//$PURPLE$$TX+CX,\"Sprite Edit as Text\"$$FG$\n"
+        "//$LK+PU+CX,\"Click for Help\","
+        "A=\"FI:::/Doc/SpriteEdText.DD.Z\"$\n\n");
+  Sprite2Code(doc,elems);
+  Free(elems);
+  while (TRUE) {
+    if (res=PopUpPrint("DocEd(0x%X,0x%X);",doc,0)) {
+      Fs->put_doc=doc2=DocNew;
+      "$WW,1$";
+      if (elems=Code2Sprite(doc)) {
+        DocDel(doc2);
+        Fs->put_doc=old_put;
+        QueDel(head);
+        Free(head);
+        head=Sprite2SpriteQue(elems);
+        Free(elems);
+        *_cur_elem_num=QueCnt(head); //TODO: Might want to improve this.
+        break;
+      } else {
+        PopUpPrint("DocEd(0x%X,0x%X);",doc2,0);
+        DocDel(doc2);
+        Fs->put_doc=old_put;
+      }
+    } else
+      break;
+  }
+  DocDel(doc);
+  if (_head) *_head=head;
+  return res;
+}
+
+#define SPED_SEL_UNSEL_ALL      0
+#define SPED_SEL                2
+#define SPED_SEL_RECTS          3
+#define SPED_UNSEL              4
+#define SPED_UNSEL_RECTS        5
+#define SPED_SHIFT_PTS          6
+#define SPED_SHIFT_RECTS        7
+#define SPED_SHIFT_SEL          8
+#define SPED_TRANSFORM_SEL      9
+#define SPED_SET_ORIGIN         10
+#define SPED_SHIFT_SUB_ORIGIN   11
+#define SPED_TEXT_ED            12
+#define SPED_INS_CLIP           13
+#define SPED_MAIN_MENU          14
+#define SPED_EXIT               15
+
+U0 GrInit3()
+{
+  DefineLstLoad("ST_SPRITE_ED_MENU","Select/Unselect All\0 \0Select\0"
+        "Select Rects\0Unselect\0Unselect Rects\0Shift Points\0Shift Rects\0"
+        "Shift Selected\0Transform Selected\0Set Origin\0"
+        "Insert Shift SubOrigin\0Edit as Text\0Insert Clip\0Main Menu\0");
+}
+GrInit3;
+
+I64 PopUpSpriteEd(CSprite **_head,I64 *_cur_elem_num)
+{
+  U8 *st;
+  CTask *pu_task;
+  I64 res;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite Edit Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteEd.DD.Z\"$\n\n"
+        "$LTBLUE$$MU-UL,\"Select/Unselect All\",LE=SPED_SEL_UNSEL_ALL$\n"
+        "$MU-UL,\"Select Elems\",LE=SPED_SEL$\n"
+        "$MU-UL,\"Select Elems with Rects\",LE=SPED_SEL_RECTS$\n"
+        "$MU-UL,\"Unsel Elems\",LE=SPED_UNSEL$\n"
+        "$MU-UL,\"Unsel Elems with Rects\",LE=SPED_UNSEL_RECTS$\n\n"
+        "$MU-UL,\"Shift Points\",LE=SPED_SHIFT_PTS$\n"
+        "$MU-UL,\"Shift Points with Rects\",LE=SPED_SHIFT_RECTS$\n"
+        "$MU-UL,\"Shift Selected Elems\",LE=SPED_SHIFT_SEL$\n"
+        "$MU-UL,\"Transform Selected Elems\",LE=SPED_TRANSFORM_SEL$\n\n"
+        "$MU-UL,\"Set Origin\",LE=SPED_SET_ORIGIN$\n"
+        "$MU-UL,\"Insert Shift SubOrigin\",LE=SPED_SHIFT_SUB_ORIGIN$\n\n"
+        "$MU-UL,\"Edit as Text\",LE=SPED_TEXT_ED$\n"
+        "$MU-UL,\"Insert Clip Sprite's\",LE=SPED_INS_CLIP$\n\n"
+        "$PURPLE$$MU-UL,\"+] Sprite Main Menu\",LE=SPED_MAIN_MENU$$LTBLUE$\n"
+        "$MU-UL,\"Exit  Sprite\",LE=SPED_EXIT$\n"
+        "$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$");
+  st=MStrPrint("SpriteSideBarTask(0x%X,0x%X,0x%X);",Fs,_head,_cur_elem_num);
+  PopUp(st,NULL,&pu_task);
+  Free(st);
+  res=PopUpMenu(doc);
+  if (TaskValidate(pu_task)) {
+    *_head=SpriteSideBar2SpriteQue(DocPut(pu_task),*_head,_cur_elem_num);
+    Kill(pu_task);
+  }
+  DocDel(doc);
+  return res;
+}
+
+#define SPEDT_SIMPLE_PT         0
+#define SPEDT_WIDTH_HEIGHT      1
+
+#define SPEDF_SEL               1
+
+class CEdSprite
+{
+  CEdSprite *next,*last;
+  CSprite *g;
+  I32 type,num,flags,xx,yy,zz;
+  I32 *x,*y,*z,*w,*h;
+};
+
+CEdSprite *EdSpriteNew(I64 type,CSprite *tmpg)
+{
+  CEdSprite *res=CAlloc(sizeof(CEdSprite));
+  res->g=tmpg;
+  if (tmpg->type&SPF_SEL)
+    res->flags|=SPEDF_SEL;
+  res->type=type;
+  return res;
+}
+
+U0 SpritePtQueNew(U8 *elems,I64 x,I64 y,CEdSprite *head)
+{
+  I64 i,num=0;
+  I32 *ptr;
+  CD3I32 *p;
+  CEdSprite *tmpes;
+  CSprite *tmpg=elems-offset(CSprite.start);
+  QueInit(head);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    switch (tmpg->type&SPG_TYPE_MASK) {
+      case SPT_ELLIPSE:
+      case SPT_POLYGON:
+        tmpes=EdSpriteNew(SPEDT_WIDTH_HEIGHT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->pwha.x1;
+        tmpes->y=&tmpg->pwha.y1;
+        tmpes->w=&tmpg->pwha.width;
+        tmpes->h=&tmpg->pwha.height;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        goto pq_x1_y1;
+      case SPT_RECT:
+      case SPT_ROTATED_RECT:
+      case SPT_LINE:
+      case SPT_ARROW:
+      case SPT_PLANAR_SYMMETRY:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->pp.x2;
+        tmpes->y=&tmpg->pp.y2;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+      case SPT_TEXT:
+      case SPT_TEXT_BOX:
+      case SPT_TEXT_DIAMOND:
+      case SPT_PT:
+      case SPT_BITMAP:
+      case SPT_FLOOD_FILL:
+      case SPT_FLOOD_FILL_NOT:
+      case SPT_CIRCLE:
+pq_x1_y1:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->p.x1;
+        tmpes->y=&tmpg->p.y1;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        break;
+      case SPT_SHIFT:
+        x+=tmpg->p.x1;
+        y+=tmpg->p.y1;
+        break;
+      case SPT_POLYLINE:
+        ptr=&tmpg->nu.u;
+        for (i=0;i<tmpg->nu.num;i++) {
+          tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+          tmpes->xx=x;
+          tmpes->yy=y;
+          tmpes->x=&ptr[i<<1];
+          tmpes->y=&ptr[i<<1+1];
+          tmpes->num=num;
+          QueIns(tmpes,head->last);
+        }
+        break;
+      case SPT_POLYPT:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->npu.x;
+        tmpes->y=&tmpg->npu.y;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        break;
+      case SPT_BSPLINE2:
+      case SPT_BSPLINE3:
+      case SPT_BSPLINE2_CLOSED:
+      case SPT_BSPLINE3_CLOSED:
+        p=&tmpg->nu.u;
+        for (i=0;i<tmpg->nu.num;i++) {
+          tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+          tmpes->xx=x;
+          tmpes->yy=y;
+          tmpes->x=&p[i].x;
+          tmpes->y=&p[i].y;
+          tmpes->z=&p[i].z;
+          tmpes->num=num;
+          QueIns(tmpes,head->last);
+        }
+        break;
+      case SPT_MESH:
+        break;
+      case SPT_SHIFTABLE_MESH:
+        tmpes=EdSpriteNew(SPEDT_SIMPLE_PT,tmpg);
+        tmpes->xx=x;
+        tmpes->yy=y;
+        tmpes->x=&tmpg->pmu.x;
+        tmpes->y=&tmpg->pmu.y;
+        tmpes->z=&tmpg->pmu.z;
+        tmpes->num=num;
+        QueIns(tmpes,head->last);
+        break;
+    }
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+    num++;
+  }
+}
+
+U0 SpriteCtrlPtsDraw(CDC *dc,CEdSprite *head)
+{
+  I64 x,y;
+  CEdSprite *tmpes;
+  Refresh;
+  DCFill(dc);
+  if (Blink(20)) {
+    tmpes=head->next;
+    while (tmpes!=head) {
+      switch (tmpes->type) {
+        case SPEDT_SIMPLE_PT:
+          x=*tmpes->x+tmpes->xx;
+          y=*tmpes->y+tmpes->yy;
+          break;
+        case SPEDT_WIDTH_HEIGHT:
+          x=*tmpes->w+*tmpes->x+tmpes->xx;
+          y=*tmpes->h+*tmpes->y+tmpes->yy;
+          break;
+      }
+      if (tmpes->flags&SPEDF_SEL)
+        dc->color=RED;
+      else
+        dc->color=BLACK;
+      GrRect(dc,x-2,y-2,4,4);
+      dc->color=WHITE;
+      GrRect(dc,x-1,y-1,2,2);
+      tmpes=tmpes->next;
+    }
+  }
+}
+
+U0 SpriteCtrlPtsMove(CEdSprite *head,I64 dx,I64 dy)
+{
+  CEdSprite *tmpes;
+  tmpes=head->next;
+  while (tmpes!=head) {
+    if (tmpes->flags&SPEDF_SEL)
+      switch (tmpes->type) {
+        case SPEDT_SIMPLE_PT:
+          if (tmpes->x) *tmpes->x+=dx;
+          if (tmpes->y) *tmpes->y+=dy;
+          break;
+        case SPEDT_WIDTH_HEIGHT:
+          if (tmpes->w) *tmpes->w+=dx;
+          if (tmpes->h) *tmpes->h+=dy;
+          break;
+      }
+    tmpes=tmpes->next;
+  }
+}
+
+Bool SpriteSelUnselShiftPts(U8 *elems,I64 x,I64 y,I64 *_cur_elem_num,I64 mode)
+{
+  I64 msg_code,arg1,arg2,xx,yy,xx2,yy2,dd,best_dd,cur_elem_num;
+  Bool res=TRUE;
+  CDC *dc=DCAlias;
+  CEdSprite head,*tmpes,*best_es;
+
+  SpritePtQueNew(elems,x,y,&head);
+  cur_elem_num=0;
+  if (head.next!=&head) {
+    while (TRUE) {
+      SpriteCtrlPtsDraw(dc,&head); //has Refresh
+      switch (msg_code=ScanMsg(&arg1,&arg2,
+            1<<MSG_MS_R_UP|1<<MSG_MS_L_DOWN|1<<MSG_KEY_DOWN)) {
+        case MSG_MS_L_DOWN:
+          switch (mode) {
+            case SPED_SEL:
+            case SPED_UNSEL:
+            case SPED_SHIFT_PTS:
+              xx=arg1; yy=arg2;
+              best_dd=I64_MAX;
+              tmpes=head.next;
+              while (tmpes!=&head) {
+                switch (tmpes->type) {
+                  case SPEDT_SIMPLE_PT:
+                    dd=SqrI64(*tmpes->x+tmpes->xx-xx)+
+                          SqrI64(*tmpes->y+tmpes->yy-yy);
+                    break;
+                  case SPEDT_WIDTH_HEIGHT:
+                    dd=SqrI64(*tmpes->x+*tmpes->w+tmpes->xx-xx)+
+                          SqrI64(*tmpes->y+*tmpes->h+tmpes->yy-yy);
+                    break;
+                }
+                if (dd<best_dd) {
+                  best_dd=dd;
+                  best_es=tmpes;
+                }
+                tmpes=tmpes->next;
+              }
+              cur_elem_num=best_es->num;
+              if (mode!=SPED_UNSEL) {
+                best_es->flags|=SPEDF_SEL;
+                best_es->g->type|=SPF_SEL;
+              } else {
+                best_es->flags&=~SPEDF_SEL;
+                best_es->g->type&=~SPF_SEL;
+              }
+              break;
+            start:
+              xx2=xx=arg1; yy2=yy=arg2;
+              while (TRUE) {
+                SpriteCtrlPtsDraw(dc,&head);
+                dc->color=ROPF_DITHER+WHITE<<16+RED;
+                GrBorder(dc,xx,yy,xx2,yy2);
+                if (msg_code=ScanMsg(&arg1,&arg2,
+                      1<<MSG_MS_MOVE|1<<MSG_MS_L_UP)) {
+                  if (msg_code==MSG_MS_MOVE) {
+                    xx2=arg1; yy2=arg2;
+                  } else
+                    break;
+                }
+              }
+              if (xx2<xx) SwapI64(&xx,&xx2);
+              if (yy2<yy) SwapI64(&yy,&yy2);
+              tmpes=head.next;
+              while (tmpes!=&head) {
+                switch (tmpes->type) {
+                  case SPEDT_SIMPLE_PT:
+                    if (xx<=*tmpes->x+tmpes->xx<=xx2 &&
+                          yy<=*tmpes->y+tmpes->yy<=yy2) {
+                      if (mode!=SPED_UNSEL_RECTS) {
+                        tmpes->flags|=SPEDF_SEL;
+                        tmpes->g->type|=SPF_SEL;
+                      } else {
+                        tmpes->flags&=~SPEDF_SEL;
+                        tmpes->g->type&=~SPF_SEL;
+                      }
+                    }
+                    break;
+                  case SPEDT_WIDTH_HEIGHT:
+                    if (xx<=*tmpes->x+*tmpes->w+tmpes->xx<=xx2 &&
+                          yy<=*tmpes->y+*tmpes->h+tmpes->yy<=yy2) {
+                      if (mode!=SPED_UNSEL_RECTS) {
+                        tmpes->flags|=SPEDF_SEL;
+                        tmpes->g->type|=SPF_SEL;
+                      } else {
+                        tmpes->flags&=~SPEDF_SEL;
+                        tmpes->g->type&=~SPF_SEL;
+                      }
+                    }
+                    break;
+                }
+                tmpes=tmpes->next;
+              }
+              case SPED_SEL_RECTS:
+              case SPED_UNSEL_RECTS:
+                break;
+              case SPED_SHIFT_RECTS:
+                do {
+                  SpriteCtrlPtsDraw(dc,&head);
+                  msg_code=ScanMsg(&arg1,&arg2,
+                        1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN);
+                  if (msg_code==MSG_KEY_DOWN) goto gs_key;
+                } while (msg_code!=MSG_MS_L_DOWN);
+                xx=arg1;yy=arg2;
+                break;
+            end:
+          }
+          switch (mode) {
+            case SPED_SHIFT_PTS:
+            case SPED_SHIFT_RECTS:
+              do {
+                SpriteCtrlPtsDraw(dc,&head);
+                if (msg_code=ScanMsg(&arg1,&arg2,
+                      1<<MSG_MS_MOVE|1<<MSG_MS_L_UP)) {
+                  SpriteCtrlPtsMove(&head,arg1-xx,arg2-yy);
+                  xx=arg1;yy=arg2;
+                }
+              } while (msg_code!=MSG_MS_L_UP);
+              tmpes=head.next;
+              while (tmpes!=&head) {
+                tmpes->flags&=~SPEDF_SEL;
+                tmpes->g->type&=~SPF_SEL;
+                tmpes=tmpes->next;
+              }
+              break;
+          }
+          break;
+        case MSG_KEY_DOWN:
+gs_key:
+          switch (arg1.u8[0]) {
+            case CH_SHIFT_ESC:
+              res=FALSE;
+            case CH_ESC:
+              GetMsg(&arg1,&arg2,1<<MSG_KEY_UP);
+              goto gs_done;
+            case 'p':
+            case 'P':
+              mode&=~1;
+              break;
+            case 'r':
+            case 'R':
+              mode|=1;
+              break;
+          }
+          break;
+        case MSG_MS_R_UP:
+          goto gs_done;
+      }
+    }
+gs_done:
+    QueDel(&head,TRUE);
+  }
+  DCFill(dc);
+  DCDel(dc);
+  if (_cur_elem_num && res)
+    *_cur_elem_num=cur_elem_num;
+  return res;
+}
+
+I64 SpriteEd(CDoc *doc,CDocEntry *doc_ce,I64 x,I64 y,
+        CSprite **_head,I64 *_cur_elem_num)
+{
+  CDocEntry *doc_e2;
+  CDocBin *tmpb;
+  Bool unlock;
+  I64 i,r[16],msg_code,arg1,arg2,xx,yy,
+        old_de_flags;
+  CSprite *head2,*next,*last,*tmpg,*insert_pt;
+
+  old_de_flags=doc_ce->de_flags;
+  tmpb=doc_ce->bin_data;
+  DocUnlock(doc);
+  SpriteQueSelAll(*_head,FALSE);
+  do {
+    if (winmgr.fps<10)
+      doc_ce->de_flags|=DOCEF_DONT_DRAW;
+    StrCpy(Fs->task_title,"Sprite Edit Menu");
+    i=PopUpSpriteEd(_head,_cur_elem_num);
+    SpriteEdUpdate(doc,doc_ce,*_head);
+    if (0<=i<SPED_EXIT) {
+      StrCpy(Fs->task_title,DefineSub(i,"ST_SPRITE_ED_MENU"));
+      switch (i) {
+        case SPED_SEL_UNSEL_ALL:
+          if (!SpriteQueSelCnt(*_head))
+            SpriteQueSelAll(*_head);
+          else
+            SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SET_ORIGIN:
+          SpriteQueSelAll(*_head);
+          doc_ce->de_flags=old_de_flags;
+          GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP);
+          SpriteSetOrigin(*_head,x-arg1,y-arg2,0);
+          SpriteEdUpdate(doc,doc_ce,*_head);
+          SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SHIFT_SEL:
+          if (!SpriteQueSelCnt(*_head))
+            SpriteQueSelAll(*_head);
+          doc_ce->de_flags=old_de_flags;
+          GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN);
+          xx=arg1; yy=arg2;
+          do {
+            msg_code=GetMsg(&arg1,&arg2,
+                  1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+            SpriteSetOrigin(*_head,arg1-xx,arg2-yy,0);
+            xx=arg1; yy=arg2;
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          } while (msg_code!=MSG_MS_L_UP);
+          if (!SpriteQueSelCnt(*_head,FALSE))
+            SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SEL:
+        case SPED_SEL_RECTS:
+        case SPED_UNSEL:
+        case SPED_UNSEL_RECTS:
+        case SPED_SHIFT_PTS:
+        case SPED_SHIFT_RECTS:
+          RegOneTimePopUp(ARf_CSPRITE_PTS_RECTANGLES,
+                "You can switch between points\n"
+                "and rectangles with '$GREEN$p$FG$' and '$GREEN$r$FG$'.\n"
+                "Press '$GREEN$r$FG$' after one rectangle\n"
+                "to OR another rectangle.\n");
+          doc_ce->de_flags=old_de_flags;
+          if (SpriteSelUnselShiftPts(tmpb->data,x,y,_cur_elem_num,i)) {
+            QueDel(*_head);
+            Free(*_head);
+            *_head=Sprite2SpriteQue(tmpb->data);
+          } else
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          break;
+        case SPED_TRANSFORM_SEL:
+          if (!SpriteQueSelCnt(*_head))
+            SpriteQueSelAll(*_head);
+          if (PopUpTransform(r)) {
+            SpriteTransformQue(*_head,r);
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          }
+          if (!SpriteQueSelCnt(*_head,FALSE))
+            SpriteQueSelAll(*_head,FALSE);
+          break;
+        case SPED_SHIFT_SUB_ORIGIN:
+          doc_ce->de_flags=old_de_flags;
+          insert_pt=SpriteSetSettings(,*_head,*_cur_elem_num);
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_SHIFT));
+          tmpg->type=SPT_SHIFT;
+          tmpg->p.x1=0;
+          tmpg->p.y1=0;
+          QueIns(tmpg,insert_pt->last);
+          GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN);
+          xx=arg1; yy=arg2;
+          do {
+            msg_code=GetMsg(&arg1,&arg2,
+                  1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+            tmpg->p.x1=arg1-xx;
+            tmpg->p.y1=arg2-yy;
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          } while (msg_code!=MSG_MS_L_UP);
+          *_cur_elem_num+=1;
+          break;
+        case SPED_INS_CLIP:
+          RegOneTimePopUp(ARf_CSPRITE_INS_CLIP,
+                "You will probably want to shift around\n"
+                "the location of element groups.  Use\n"
+                "'Insert shift sub-origin' after picking the\n"
+                "element to insert before.  Or,\n"
+                "use 'shift points'.\n");
+          insert_pt=SpriteSetSettings(,*_head,*_cur_elem_num);
+          unlock=DocLock(sys_clip_doc);
+          doc_e2=sys_clip_doc->head.next;
+          while (doc_e2!=sys_clip_doc) {
+            if (doc_e2->type_u8==DOCT_SPRITE) {
+              head2=Sprite2SpriteQue(doc_e2->bin_data->data);
+              if (head2->next!=head2) {
+                tmpg=head2->next;
+                while (tmpg!=head2) {
+                  *_cur_elem_num+=1;
+                  tmpg=tmpg->next;
+                }
+                next=head2->next;
+                last=head2->last;
+                insert_pt->last->next=next;
+                next->last=insert_pt->last;
+                insert_pt->last=last;
+                last->next=insert_pt;
+              }
+              Free(head2);
+            }
+            doc_e2=doc_e2->next;
+          }
+          if (unlock)
+            DocUnlock(sys_clip_doc);
+          SpriteEdUpdate(doc,doc_ce,*_head);
+          break;
+        case SPED_TEXT_ED:
+          if (SpriteEdText(_head,_cur_elem_num))
+            SpriteEdUpdate(doc,doc_ce,*_head);
+          break;
+      }
+    }
+  } while (i!=DOCM_CANCEL && i!=SPED_EXIT && i!=SPED_MAIN_MENU);
+  doc_ce->de_flags=old_de_flags;
+
+  switch (i) {
+    case DOCM_CANCEL:   return SPE_ABORT;
+    case SPED_EXIT:     return SPE_EXIT;
+    case SPED_MAIN_MENU:        return SPE_CONT;
+  }
+}
+
+#help_index "Graphics/Sprite;Sprites;Graphics/Math/3D Transformation"
+public U8 *SpriteTransform(U8 *elems,I64 *r)
+{//Rotate Sprite using 4x4 matrix. Uses fixed-point.
+  U8 *res;
+  CSprite *head=Sprite2SpriteQue(elems);
+  SpriteQueSelAll(head);
+  SpriteTransformQue(head,r);
+  res=SpriteQue2Sprite(head);
+  QueDel(head);
+  Free(head);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/SpriteMain.HC.HTML b/public/Wb/Home/Src/Adam/Gr/SpriteMain.HC.HTML new file mode 100755 index 0000000..808abdd --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/SpriteMain.HC.HTML @@ -0,0 +1,1269 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+#define SPT_MENU        -2
+#define SPT_INS_SCRN_BITMAP             -3
+#define SPT_INS_TRANSPARENT_SCRN_BITMAP -4
+#define SPT_ED_MENU     -5
+#define SPT_EXIT        -6
+
+I64 PopUpSpriteMain(CSprite **_head,I64 *_cur_elem_num,
+        CDoc *_doc,CDocEntry *_doc_e)
+{
+  CTask *pu_task;
+  I64   res;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_de;
+  U8    *st;
+
+  doc_de=DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite Main Menu\"$\n"
+        "$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteMain.DD.Z\"$\n"
+        "\n$LTBLUE$$DA+M,A=\"Tag Text:%%s\"$\n\n");
+  doc_de->data=StrNew(_doc_e->tag,doc->mem_task);
+  DocDataFmt(doc,doc_de);
+
+  DocPrint(doc,"$MU-UL,\"Color (4-bit)\",LE=SPT_COLOR$\n"
+        "$MU-UL,\"Dither Color (4-bit)\",LE=SPT_DITHER_COLOR$\n"
+        "$MU-UL,\"Thick\",LE=SPT_THICK$\n"
+        "$MU-UL,\"Planar Symmetry\",LE=SPT_PLANAR_SYMMETRY$\n"
+        "\n$MU-UL,\"Point\",LE=SPT_PT$\n"
+        "$MU-UL,\"Line\",LE=SPT_LINE$\n"
+        "$MU-UL,\"Arrow\",LE=SPT_ARROW$\n"
+        "$MU-UL,\"Rect\",LE=SPT_RECT$\n"
+        "$MU-UL,\"Circle\",LE=SPT_CIRCLE$\n"
+        "$MU-UL,\"Ellipse\",LE=SPT_ELLIPSE$\n"
+        "$MU-UL,\"Polygon\",LE=SPT_POLYGON$\n"
+        "$MU-UL,\"Text\",LE=SPT_TEXT$\n"
+        "$MU-UL,\"Text Box\",LE=SPT_TEXT_BOX$\n"
+        "$MU-UL,\"Text Diamond\",LE=SPT_TEXT_DIAMOND$\n"
+        "$MU-UL,\"Flood Fill\",LE=SPT_FLOOD_FILL$\n"
+        "$MU-UL,\"Flood Fill Not Color\",LE=SPT_FLOOD_FILL_NOT$\n"
+        "$MU-UL,\"PolyLine\",LE=SPT_POLYLINE$\n"
+        "$MU-UL,\"PolyPoint\",LE=SPT_POLYPT$\n"
+        "$MU-UL,\"BSpline2\",LE=SPT_BSPLINE2$\n"
+        "$MU-UL,\"BSpline3\",LE=SPT_BSPLINE3$\n"
+        "$MU-UL,\"BSpline2 Closed\",LE=SPT_BSPLINE2_CLOSED$\n"
+        "$MU-UL,\"BSpline3 Closed\",LE=SPT_BSPLINE3_CLOSED$\n"
+        "$MU-UL,\"Insert Scrn-Captured BitMap\",LE=SPT_INS_SCRN_BITMAP$\n"
+        "$MU-UL,\"Insert Transparent Scrn-Captured BitMap\","
+        "LE=SPT_INS_TRANSPARENT_SCRN_BITMAP$\n"
+        "$PURPLE$$MU-UL,\"+] Create or Edit 3D Mesh\",LE=SPT_MESH$\n"
+        "$MU-UL,\"+] Create or Edit Shiftable 3D Mesh\","
+        "LE=SPT_SHIFTABLE_MESH$\n"
+        "$MU-UL,\"+] Convert to BitMap or Edit BitMap\","
+        "LE=SPT_BITMAP$$LTBLUE$\n"
+        "\n$MU-UL,\"Transform On  (for use with 3D icons)\","
+        "LE=SPT_TRANSFORM_ON$\n"
+        "$MU-UL,\"Transform Off (for use with 3D icons)\","
+        "LE=SPT_TRANSFORM_OFF$\n"
+        "\n"
+        "$PURPLE$$MU-UL,\"+] Sprite Edit Menu\",LE=SPT_ED_MENU$$LTBLUE$\n"
+        "$MU-UL,\"Exit  Sprite\",LE=SPT_EXIT$\n"
+        "$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$\n"
+        "\nRight-Click to get back to this menu.");
+  st=MStrPrint("SpriteSideBarTask(0x%X,0x%X,0x%X);",Fs,_head,_cur_elem_num);
+  PopUp(st,NULL,&pu_task);
+  Free(st);
+  res=PopUpMenu(doc);
+  if (TaskValidate(pu_task)) {
+    *_head=SpriteSideBar2SpriteQue(DocPut(pu_task),*_head,_cur_elem_num);
+    Kill(pu_task);
+  }
+  Free(_doc_e->tag);
+  _doc_e->tag=StrNew(doc_de->data,_doc->mem_task);
+  _doc->cur_col=0;
+  DocDel(doc);
+  return res;
+}
+
+Bool PopUpExtents(I64 *_x1,I64 *_x2,I64 *_y1,I64 *_y2)
+{
+  I64 res;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e;
+  doc_e=DocPrint(doc,"  $DA,A=\"x1:%%d\"$\n");
+  doc_e->data=_x1;
+  DocDataFmt(doc,doc_e);
+  doc_e=DocPrint(doc,"  $DA,A=\"x2:%%d\"$\n");
+  doc_e->data=_x2;
+  DocDataFmt(doc,doc_e);
+  doc_e=DocPrint(doc,"  $DA,A=\"y1:%%d\"$\n");
+  doc_e->data=_y1;
+  DocDataFmt(doc,doc_e);
+  doc_e=DocPrint(doc,"  $DA,A=\"y2:%%d\"$\n\n");
+  doc_e->data=_y2;
+  DocDataFmt(doc,doc_e);
+
+  DocPrint(doc," $BT,\"Use These Extents\",LE=TRUE$");
+  DocPrint(doc,"$CM,3,0$$BT,\"Drag-Out New Extents\",LE=FALSE$\n\n");
+  do res=PopUpMenu(doc);
+  while (res!=FALSE && res!=TRUE);
+  DocDel(doc);
+  return res;
+}
+
+U0 SpriteScrnInit(CDC *dc,I64,I64)
+{
+//Uses fixed-point.
+  I64 xx,yy,old_pen_width=dc->thick;
+  CColorROPU32 old_color=dc->color;
+  Refresh;
+  DCFill(dc);
+  if (dc->flags&DCF_SYMMETRY) {
+    dc->flags&=~DCF_SYMMETRY;
+    dc->thick=1;
+    xx=dc->sym.sny*8192;
+    yy=-dc->sym.snx*8192;
+    dc->color=RED;
+    GrLine3(dc,dc->sym.sx-xx.i32[1],dc->sym.sy-yy.i32[1],0,
+          dc->sym.sx+xx.i32[1],dc->sym.sy+yy.i32[1],0,3,0);
+    dc->color=WHITE;
+    GrLine3(dc,dc->sym.sx-xx.i32[1],dc->sym.sy-yy.i32[1],0,
+          dc->sym.sx+xx.i32[1],dc->sym.sy+yy.i32[1],0,3,1);
+    dc->color=BLACK;
+    GrLine3(dc,dc->sym.sx-xx.i32[1],dc->sym.sy-yy.i32[1],0,
+          dc->sym.sx+xx.i32[1],dc->sym.sy+yy.i32[1],0,3,2);
+    dc->flags|=DCF_SYMMETRY;
+  }
+  dc->color=old_color;
+  dc->thick=old_pen_width;
+}
+
+CSprite *SMLine(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrLine3(dc,x1,y1,0,x2,y2,0);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrLine3(dc,x1,y1,0,x2,y2,0);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_LINE));
+  res->type=SPT_LINE;
+  res->pp.x1=x1-x;
+  res->pp.y1=y1-y;
+  res->pp.x2=x2-x;
+  res->pp.y2=y2-y;
+  return res;
+}
+
+CSprite *SMArrow(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrArrow3(dc,x1,y1,0,x2,y2,0);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrArrow3(dc,x1,y1,0,x2,y2,0);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_ARROW));
+  res->type=SPT_ARROW;
+  res->pp.x1=x1-x;
+  res->pp.y1=y1-y;
+  res->pp.x2=x2-x;
+  res->pp.y2=y2-y;
+  return res;
+}
+
+CSprite *SMPlanarSymmetry(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,old_width,old_flags;
+  CSprite *res;
+  old_width=dc->thick;
+  old_flags=dc->flags;
+  dc->flags&=~DCF_SYMMETRY;
+  dc->thick=1;
+  do {
+    dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+    GrLine3(dc,x1,y1,0,x2,y2,0);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->flags=old_flags&DCF_SYMMETRY|dc->flags&~DCF_SYMMETRY;
+  dc->thick=old_width;
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_PLANAR_SYMMETRY));
+  res->type=SPT_PLANAR_SYMMETRY;
+  res->pp.x1=x1-x;
+  res->pp.y1=y1-y;
+  res->pp.x2=x2-x;
+  res->pp.y2=y2-y;
+  return res;
+}
+
+CSprite *SMRect(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,
+        xx1=arg1,yy1=arg2,xx2=arg1,yy2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrRect3(dc,xx1,yy1,0,xx2-xx1,yy2-yy1);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+    if (x2<x1) {
+      xx1=x2; xx2=x1;
+    } else {
+      xx1=x1; xx2=x2;
+    }
+    if (y2<y1) {
+      yy1=y2; yy2=y1;
+    } else {
+      yy1=y1; yy2=y2;
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrRect3(dc,xx1,yy1,0,xx2-xx1,yy2-yy1);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_RECT));
+  res->type=SPT_RECT;
+  res->pp.x1=xx1-x;
+  res->pp.y1=yy1-y;
+  res->pp.x2=xx2-x;
+  res->pp.y2=yy2-y;
+  return res;
+}
+
+CSprite *SMScrnBitMap(I64 eletype,CDC *dc,CDC *dc2,I64 x,I64 y,
+        I64 arg1,I64 arg2,CColorROPU32 bm_bkcolor)
+{
+  I64 i,msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,
+        xx1=arg1,yy1=arg2,xx2=arg1,yy2=arg2,old_width;
+  CDC *dc3,*img;
+  CSprite *res;
+  old_width=dc2->thick;
+  dc2->thick=1;
+  do {
+    dc2->color=ROPF_DITHER+WHITE<<16+BLACK;
+    GrBorder(dc2,xx1+Fs->pix_left+Fs->scroll_x,yy1+Fs->pix_top+Fs->scroll_y,
+          xx2+Fs->pix_left+Fs->scroll_x,yy2+Fs->pix_top+Fs->scroll_y);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+    if (x2<x1) {
+      xx1=x2; xx2=x1;
+    } else {
+      xx1=x1; xx2=x2;
+    }
+    if (y2<y1) {
+      yy1=y2; yy2=y1;
+    } else {
+      yy1=y1; yy2=y2;
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  xx2++; yy2++;
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_BITMAP)+((xx2-xx1+7)&~7)*(yy2-yy1));
+  res->type=SPT_BITMAP;
+  res->pwhu.width=xx2-xx1;
+  res->pwhu.height=yy2-yy1;
+  res->pwhu.x1=0;
+  res->pwhu.y1=0;
+  SpriteScrnInit(dc,x,y);
+  i=gr.scrn_zoom;
+  GrScaleZoom(1.0/i);
+  Refresh(2,TRUE);
+
+  dc3=DCScrnCapture;
+  img=DCExt(dc3,Fs->pix_left+Fs->scroll_x+xx1,Fs->pix_top+Fs->scroll_y+yy1,
+        Fs->pix_left+Fs->scroll_x+xx2-1,Fs->pix_top+Fs->scroll_y+yy2-1);
+  if (eletype==SPT_INS_TRANSPARENT_SCRN_BITMAP)
+    DCColorChg(img,bm_bkcolor);
+  GrScaleZoom(i);
+  MemCpy(&res->pwhu.u,img->body,((xx2-xx1+7)&~7)*(yy2-yy1));
+  DCDel(img);
+  DCDel(dc3);
+  dc2->thick=old_width;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_SELF_GRAB_SCROLL;
+  return res;
+}
+
+CSprite *SMCircle(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2)));
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2)));
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_CIRCLE));
+  res->type=SPT_CIRCLE;
+  res->pr.x1=x1-x;
+  res->pr.y1=y1-y;
+  res->pr.radius=Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2));
+  return res;
+}
+
+CSprite *SMEllipse(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  F64 angle1,angle2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrEllipse3(dc,(x1+x2)>>1,(y1+y2)>>1,0,AbsI64(x1-x2)>>1,AbsI64(y1-y2)>>1);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_ELLIPSE));
+  res->type=SPT_ELLIPSE;
+  res->pwha.x1=(x1+x2)>>1-x;
+  res->pwha.y1=(y1+y2)>>1-y;
+  res->pwha.width =AbsI64(x1-x2)>>1;
+  res->pwha.height=AbsI64(y1-y2)>>1;
+  angle2=Arg(x2-(res->pwha.x1+x),y2-(res->pwha.y1+y));
+  if (res->pwha.width<res->pwha.height)
+    angle2-=pi/2.0;
+  do {
+    angle1=Arg(x2-(res->pwha.x1+x),y2-(res->pwha.y1+y));
+    if (res->pwha.width>=res->pwha.height)
+      res->pwha.angle=-(angle1-angle2);
+    else
+      res->pwha.angle=-(angle1-angle2)+pi/2.0;
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrEllipse3(dc,res->pwha.x1+x,res->pwha.y1+y,0,
+          res->pwha.width,res->pwha.height,res->pwha.angle);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  angle1=Arg(x2-(res->pwha.x1+x),y2-(res->pwha.y1+y));
+  if (res->pwha.width>=res->pwha.height)
+    res->pwha.angle=-(angle1-angle2);
+  else
+    res->pwha.angle=-(angle1-angle2)+pi/2.0;
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrEllipse3(dc,res->pwha.x1+x,res->pwha.y1+y,0,
+        res->pwha.width,res->pwha.height,res->pwha.angle);
+  return res;
+}
+
+CSprite *SMPolygon(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,I64 sides,
+        CColorROPU32 color)
+{
+  I64 msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  F64 angle1,angle2;
+  CSprite *res;
+  do {
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrRegPoly3(dc,(x1+x2)>>1,(y1+y2)>>1,0,
+          AbsI64(x1-x2)>>1,AbsI64(y1-y2)>>1,sides);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_POLYGON));
+  res->type=SPT_POLYGON;
+  res->pwhas.x1=(x1+x2)>>1-x;
+  res->pwhas.y1=(y1+y2)>>1-y;
+  res->pwhas.width =AbsI64(x1-x2)>>1;
+  res->pwhas.height=AbsI64(y1-y2)>>1;
+  res->pwhas.sides=sides;
+  angle2=Arg(x2-(res->pwhas.x1+x),y2-(res->pwhas.y1+y));
+  if (res->pwhas.width<res->pwhas.height)
+    angle2-=pi/2.0;
+  do {
+    angle1=Arg(x2-(res->pwhas.x1+x),y2-(res->pwhas.y1+y));
+    if (res->pwhas.width>=res->pwhas.height)
+      res->pwhas.angle=-(angle1-angle2);
+    else
+      res->pwhas.angle=-(angle1-angle2)+pi/2.0;
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    GrRegPoly3(dc,res->pwhas.x1+x,res->pwhas.y1+y,0,
+          res->pwhas.width,res->pwhas.height,
+          res->pwhas.sides,res->pwhas.angle);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    SpriteScrnInit(dc,x,y);
+    x2=arg1; y2=arg2;
+  } while (msg_code!=MSG_MS_L_UP);
+  angle1=Arg(x2-(res->pwhas.x1+x),y2-(res->pwhas.y1+y));
+  if (res->pwhas.width>=res->pwhas.height)
+    res->pwhas.angle=-(angle1-angle2);
+  else
+    res->pwhas.angle=-(angle1-angle2)+pi/2.0;
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  GrRegPoly3(dc,res->pwhas.x1+x,res->pwhas.y1+y,0,
+        res->pwhas.width,res->pwhas.height,res->pwhas.sides,
+        res->pwhas.angle);
+  return res;
+}
+
+CSprite *SMPolyLineFamily(I64 eletype,CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,
+        CColorROPU32 color)
+{
+  I64 i,num=0,msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2;
+  I32 *ptr;
+  CD3I32 *p;
+  CSprite *res,*tmpg,*tmpg1,head2;
+
+  QueInit(&head2);
+  do {
+    do {
+      dc->color=color&COLORROP_NO_ROP0_MASK;
+      if (num)
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_L_UP+1<<MSG_MS_MOVE+1<<MSG_MS_R_UP);
+      dc->color=TRANSPARENT;
+      if (num)
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+      x2=arg1; y2=arg2;
+    } while (msg_code!=MSG_MS_L_UP && msg_code!=MSG_MS_R_UP);
+    dc->color=color&COLORROP_NO_ROP0_MASK;
+    if (msg_code==MSG_MS_L_UP) {
+      if (num)
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+      res=CAlloc(SpriteElemQuedBaseSize(SPT_PT));
+      res->type=SPT_PT;
+      res->p.x1=x2-x;
+      res->p.y1=y2-y;
+      QueIns(res,head2.last);
+      x1=x2;y1=y2;
+      num++;
+    }
+  } while (msg_code!=MSG_MS_R_UP);
+
+  switch (eletype) {
+    case SPT_POLYLINE:
+      if (num>1) {
+        res=CAlloc(SpriteElemQuedBaseSize(SPT_POLYLINE)+num*sizeof(CD2I32));
+        ptr=&res->nu.u;
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          ptr[i<<1]=tmpg1->p.x1;
+          ptr[i<<1+1]=tmpg1->p.y1;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res->type=SPT_POLYLINE;
+        res->nu.num=num;
+      } else {
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res=NULL;
+      }
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      if (num>2) {
+        res=CAlloc(SpriteElemQuedBaseSize(eletype)+num*sizeof(CD3I32));
+        p=&res->nu.u;
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          p[i].x=tmpg1->p.x1;
+          p[i].y=tmpg1->p.y1;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res->type=eletype;
+        res->nu.num=num;
+      } else {
+        tmpg1=head2.next;
+        for (i=0;i<num;i++) {
+          tmpg=tmpg1->next;
+          Free(tmpg1);
+          tmpg1=tmpg;
+        }
+        res=NULL;
+      }
+      break;
+  }
+  return res;
+}
+
+CSprite *SMPolyPoint(CDC *dc,I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color)
+{
+  I64 i,num=0,msg_code,x1=arg1,y1=arg2,x2=arg1,y2=arg2,x3,y3;
+  I32 *ptr;
+  CSprite *res,*tmpg,*tmpg1,head2;
+
+  QueInit(&head2);
+  x3=arg1-x; y3=arg2-y;
+  dc->color=color&COLORROP_NO_ROP0_MASK;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+    x2=arg1; y2=arg2;
+    GrLine3(dc,x1,y1,0,x2,y2,0);
+    Line(&head2,x1-x,y1-y,0,x2-x,y2-y,0,&SpritePolyPtPlot);
+    x1=x2;y1=y2;
+  } while (msg_code!=MSG_MS_L_UP);
+
+  num=0;
+  res=head2.next;
+  x1=x3; y1=y3;
+  while (res!=&head2) {
+    tmpg=res->next;
+    if (res->p.x1==x1 && res->p.y1==y1) {
+      QueRem(res);
+      Free(res);
+    } else {
+      num++;
+      x1=res->p.x1;
+      y1=res->p.y1;
+    }
+    res=tmpg;
+  }
+
+  res=CAlloc(SpriteElemQuedBaseSize(SPT_POLYPT)+(num*3+7)>>3);
+  res->npu.x=x3;
+  res->npu.y=y3;
+  ptr=&res->npu.u;
+  x1=x3; y1=y3;
+  i=0;
+  tmpg1=head2.next;
+  while (tmpg1!=&head2) {
+    tmpg=tmpg1->next;
+    BFieldOrU32(ptr,i,polypt_map[SignI64(tmpg1->p.x1-x1)+1+
+          3*(SignI64(tmpg1->p.y1-y1)+1)]);
+    i+=3;
+    x1=tmpg1->p.x1;y1=tmpg1->p.y1;
+    QueRem(tmpg1);
+    Free(tmpg1);
+    tmpg1=tmpg;
+  }
+  res->type=SPT_POLYPT;
+  res->npu.num=num;
+  return res;
+}
+
+U0 SMTextFamily(I64 eletype,CDoc *doc,CDocEntry *doc_ce,CSprite *head,CDC *dc,
+        I64 x,I64 y,I64 arg1,I64 arg2,CColorROPU32 color,I64 *_cur_elem_num,
+        I64 old_de_flags)
+{
+  CSprite *tmpg,*insert_pt=SpriteSetSettings(,head,*_cur_elem_num);
+  I64 msg_code,x1,y1;
+  U8 *st;
+  doc_ce->de_flags|=DOCEF_DONT_DRAW;
+  st=PopUpGetStr("Enter text and press <ESC>.\n");
+  doc_ce->de_flags=old_de_flags;
+  if (st && *st) {
+    x1=0; y1=0;
+    do {
+      dc->color=color&COLORROP_NO_ROP0_MASK;
+      switch (eletype) {
+        case SPT_TEXT:          GrPrint3(dc,x1,y1,0,"%s",st);   break;
+        case SPT_TEXT_BOX:      GrTextBox3(dc,x1,y1,0,st);      break;
+        case SPT_TEXT_DIAMOND:  GrTextDiamond3(dc,x1,y1,0,st);  break;
+      }
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+      SpriteScrnInit(dc,x,y);
+      x1=arg1; y1=arg2;
+    } while (msg_code!=MSG_MS_L_UP);
+    tmpg=CAlloc(SpriteElemQuedBaseSize(eletype)+StrLen(st)+1);
+    tmpg->type=eletype;
+    tmpg->ps.x1=x1-x;
+    tmpg->ps.y1=y1-y;
+    StrCpy(tmpg->ps.st,st);
+    QueIns(tmpg,insert_pt->last);
+    SpriteEdUpdate(doc,doc_ce,head);
+    *_cur_elem_num+=1;
+  }
+  Free(st);
+}
+
+I64 SMBitMap(I64 eletype,CDoc *doc,CDocEntry *doc_ce,CSprite *head,
+        CDC *dc,I64 xx,I64 yy,I64 arg1,I64 arg2,CColorROPU32 bm_bkcolor,
+        Bool sel,I64 xx1=0,I64 yy1=0,I64 xx2=0,I64 yy2=0,I64 *_cur_elem_num)
+{
+  I64 i,msg_code,x=xx,y=yy,x1=arg1,y1=arg2,x2=arg1,y2=arg2,old_width;
+  CSprite *tmpg,*tmpg1,*insert_pt;
+  CDC *img;
+
+  insert_pt=SpriteSetSettings(,head,*_cur_elem_num,xx,yy,,,&x,&y);
+  x+=xx; y+=yy;
+
+  if (sel) {
+    xx1=arg1; yy1=arg2;
+    xx2=arg1; yy2=arg2;
+    old_width=dc->thick;
+    dc->thick=1;
+    do {
+      dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+      GrBorder(dc,xx1,yy1,xx2,yy2);
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+      SpriteScrnInit(dc,x,y);
+      x2=arg1; y2=arg2;
+      if (x2<x1) {
+        xx1=x2; xx2=x1;
+      } else {
+        xx1=x1; xx2=x2;
+      }
+      if (y2<y1) {
+        yy1=y2; yy2=y1;
+      } else {
+        yy1=y1; yy2=y2;
+      }
+    } while (msg_code!=MSG_MS_L_UP);
+    dc->thick=old_width;
+  }
+
+  xx2++; yy2++;
+  tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_BITMAP)+
+        ((xx2-xx1+7)&~7)*(yy2-yy1));
+  tmpg->type=SPT_BITMAP;
+  tmpg->pwhu.width=xx2-xx1;
+  tmpg->pwhu.height=yy2-yy1;
+  tmpg->pwhu.x1=xx1-x;
+  tmpg->pwhu.y1=yy1-y;
+  img=DCNew(tmpg->pwhu.width,tmpg->pwhu.height,Fs);
+  img->color=bm_bkcolor;
+  GrRect(img,0,0,tmpg->pwhu.width,tmpg->pwhu.height);
+  tmpg1=insert_pt;
+  if (tmpg1==head || tmpg1->type&SPG_TYPE_MASK!=SPT_BITMAP) {
+    SpriteSetSettings(img,head,0,-(xx1-x),-(yy1-y));
+    x=xx; y=yy;
+    Sprite3(img,-(xx1-x),-(yy1-y),0,doc_ce->bin_data->data);
+    QueDel(head);
+    insert_pt=head->next=head->last=head;
+    *_cur_elem_num=1;
+  } else {
+    SpriteSetSettings(img,head,*_cur_elem_num,-(xx1-x),-(yy1-y));
+    Sprite3(img,-(xx1-x),-(yy1-y),0,&tmpg1->start,TRUE);
+    insert_pt=tmpg1->next;
+    QueRem(tmpg1);
+    Free(tmpg1);
+  }
+  MemCpy(&tmpg->pwhu.u,img->body,((xx2-xx1+7)&~7)*(yy2-yy1));
+
+  switch (i=SpriteBitMapEd(doc,doc_ce,dc,&xx1,&yy1,
+        &xx2,&yy2,&img,bm_bkcolor)) {
+    case SPE_EXIT:
+    case SPE_CONT:
+      Free(tmpg);
+      tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_BITMAP)+
+            ((xx2-xx1+7)&~7)*(yy2-yy1));
+      tmpg->type=eletype;
+      tmpg->pwhu.width=xx2-xx1;
+      tmpg->pwhu.height=yy2-yy1;
+      tmpg->pwhu.x1=xx1-x;
+      tmpg->pwhu.y1=yy1-y;
+      MemCpy(&tmpg->pwhu.u,img->body,((xx2-xx1+7)&~7)*(yy2-yy1));
+      break;
+  }
+  QueIns(tmpg,insert_pt->last);
+  DCDel(img);
+  SpriteEdUpdate(doc,doc_ce,head);
+  return i;
+}
+
+U0 SMMesh(CDoc *doc,CDocEntry *doc_ce,CSprite *head,I64 *_cur_elem_num)
+{
+  CSprite *tmpg,*insert_pt=SpriteSetSettings(,head,*_cur_elem_num),
+        *tmpg1=insert_pt;
+  CD3I32 *p;
+  I64 i,size,x1,y1,z1;
+  I32 *mesh,*old_mesh;
+  if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_MESH)
+    old_mesh=&tmpg1->mu.vertex_cnt;
+  else if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    x1=tmpg1->pmu.x;
+    y1=tmpg1->pmu.y;
+    z1=tmpg1->pmu.z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x+=x1;
+      p->y+=y1;
+      p->z+=z1;
+    }
+    old_mesh=&tmpg1->pmu.vertex_cnt;
+  } else
+    old_mesh=NULL;
+  if (mesh=SpriteMeshEd(old_mesh,&size,TRUE)) {
+    tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_MESH)-sizeof(I32)*2+size);
+    tmpg->type=SPT_MESH;
+    MemCpy(&tmpg->mu.vertex_cnt,mesh,size);
+    Free(mesh);
+    QueIns(tmpg,insert_pt->last);
+    SpriteEdUpdate(doc,doc_ce,head);
+    if (old_mesh) {
+      insert_pt=tmpg;
+      QueRem(tmpg1);
+      Free(tmpg1);
+      SpriteEdUpdate(doc,doc_ce,head);
+    } else
+      *_cur_elem_num+=1;
+  } else if (old_mesh && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    x1=tmpg1->pmu.x;
+    y1=tmpg1->pmu.y;
+    z1=tmpg1->pmu.z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x-=x1;
+      p->y-=y1;
+      p->z-=z1;
+    }
+  }
+}
+
+U0 SMShiftableMesh(CDoc *doc,CDocEntry *doc_ce,CSprite *head,
+        I64 x,I64 y,I64 arg1,I64 arg2,I64 *_cur_elem_num)
+{
+  CSprite *tmpg,*insert_pt=SpriteSetSettings(,head,*_cur_elem_num),
+        *tmpg1=insert_pt;
+  CD3I32 *p;
+  I64 i,size,z,x1,y1,z1;
+  I32 *mesh,*old_mesh;
+  if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_MESH) {
+    z=0;
+    x1=-(arg1-x);
+    y1=-(arg2-y);
+    z1=z;
+    p=&tmpg1->mu.u;
+    for (i=0;i<tmpg1->mu.vertex_cnt;i++,p++) {
+      p->x+=x1;
+      p->y+=y1;
+      p->z+=z1;
+    }
+    old_mesh=&tmpg1->mu.vertex_cnt;
+  } else if (tmpg1!=head && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    z=-tmpg1->pmu.z;
+    x1=tmpg1->pmu.x-(arg1-x);
+    y1=tmpg1->pmu.y-(arg2-y);
+    z1=tmpg1->pmu.z+z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x+=x1;
+      p->y+=y1;
+      p->z+=z1;
+    }
+    old_mesh=&tmpg1->pmu.vertex_cnt;
+  } else {
+    z=0;
+    old_mesh=NULL;
+  }
+  if (mesh=SpriteMeshEd(old_mesh,&size,TRUE)) {
+    tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_SHIFTABLE_MESH)-sizeof(I32)*2+size);
+    tmpg->type=SPT_SHIFTABLE_MESH;
+    MemCpy(&tmpg->pmu.vertex_cnt,mesh,size);
+    Free(mesh);
+    tmpg->pmu.x=arg1-x;
+    tmpg->pmu.y=arg2-y;
+    tmpg->pmu.z=-z;
+    QueIns(tmpg,insert_pt->last);
+    SpriteEdUpdate(doc,doc_ce,head);
+    if (old_mesh) {
+      insert_pt=tmpg;
+      QueRem(tmpg1);
+      Free(tmpg1);
+      SpriteEdUpdate(doc,doc_ce,head);
+    } else
+      *_cur_elem_num+=1;
+  } else if (old_mesh && tmpg1->type&SPG_TYPE_MASK==SPT_SHIFTABLE_MESH) {
+    x1=tmpg1->pmu.x-(arg1-x);
+    y1=tmpg1->pmu.y-(arg2-y);
+    z1=tmpg1->pmu.z+z;
+    p=&tmpg1->pmu.u;
+    for (i=0;i<tmpg1->pmu.vertex_cnt;i++,p++) {
+      p->x-=x1;
+      p->y-=y1;
+      p->z-=z1;
+    }
+  } else if (old_mesh && tmpg1->type&SPG_TYPE_MASK==SPT_MESH) {
+    x1=-(arg1-x);
+    y1=-(arg2-y);
+    z1= z;
+    p=&tmpg1->mu.u;
+    for (i=0;i<tmpg1->mu.vertex_cnt;i++,p++) {
+      p->x-=x1;
+      p->y-=y1;
+      p->z-=z1;
+    }
+  }
+}
+
+U0 SMTaskTitleSet(I64 eletype)
+{
+  Fs->title_src=TTS_CONST; //Violates TTS_LOCKED_CONST
+  switch (eletype) {
+    case SPT_INS_SCRN_BITMAP:
+      StrCpy(Fs->task_title,"Insert Scrn BitMap");
+      break;
+    case SPT_INS_TRANSPARENT_SCRN_BITMAP:
+      StrCpy(Fs->task_title,"Insert Transparent Scrn BitMap");
+      break;
+    default:
+      if (eletype>=0)
+        StrCpy(Fs->task_title,DefineSub(eletype,"ST_SPRITE_ELEM_TYPES"));
+  }
+  Fs->border_src=BDS_CONST;
+}
+
+I64 SpriteMainEd(CDoc *doc)
+{
+  CDocEntry *doc_ce=doc->cur_entry;
+  I64 res,i,x,y,arg1,arg2,xx,yy,xx1,yy1,xx2,yy2,thick,eletype=SPT_MENU,
+        cur_elem_num,old_border_src=Fs->border_src,old_title_src=Fs->title_src,
+        old_de_flags=doc_ce->de_flags;
+  CColorROPU32 bm_bkcolor,color;
+  CSprite *head,*tmpg,*insert_pt;
+  CDC *dc=DCAlias(,Fs),*dc2=DCAlias(,sys_winmgr_task),*dc3;
+  U8 *old_task_title=StrNew(Fs->task_title);
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  Refresh(2,TRUE);
+  dc2->flags|=DCF_ON_TOP;
+  head=Sprite2SpriteQue(doc_ce->bin_data->data);
+  cur_elem_num=QueCnt(head);
+  xx=(doc_ce->x+doc_ce->max_col-doc->line_start_col)*FONT_WIDTH;
+  yy=(doc_ce->y-doc->top_line_num)*FONT_HEIGHT;
+
+  while (TRUE) {
+    insert_pt=SpriteSetSettings(dc,head,cur_elem_num,xx,yy,
+          &color,&thick,&x,&y);
+    x+=xx; y+=yy;
+    DCFill;
+    if (eletype==SPT_MENU) {
+      Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+            -WIF_SELF_BORDER-WIF_SELF_GRAB_SCROLL;
+      if (winmgr.fps<10)
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+      StrCpy(Fs->task_title,old_task_title);
+      Fs->border_src=old_border_src;
+      Fs->title_src =old_title_src;
+
+      xx-=StrLen(doc_ce->tag)*FONT_WIDTH;
+      eletype=PopUpSpriteMain(&head,&cur_elem_num,doc,doc_ce);
+      xx+=StrLen(doc_ce->tag)*FONT_WIDTH;
+      insert_pt=SpriteSetSettings(dc,head,cur_elem_num,x,y,
+            &color,&thick,&x,&y);
+      x+=xx; y+=yy;
+
+      SpriteEdUpdate(doc,doc_ce,head);
+      switch (eletype) {
+        case SPT_FLOOD_FILL:
+        case SPT_FLOOD_FILL_NOT:
+          RegOneTimePopUp(ARf_FLOODFILL,
+                ST_WARN_ST "This is affected by what's underneath\n"
+                "when it is drawn.  You will probably want to\n"
+                "convert it to a bitmap.\n\n"
+                "A tip on artistry you might consider\n"
+                "is using lines to fill regions because\n"
+                "brush strokes look cool.\n");
+          break;
+        case SPT_PLANAR_SYMMETRY:
+          RegOneTimePopUp(ARf_PLANAR_SYMMETRY,
+                "Right-click to turn-off symmetry.\n");
+          break;
+      }
+      doc_ce->de_flags=old_de_flags;
+    }
+    SMTaskTitleSet(eletype);
+    switch (eletype) {
+      case SPT_COLOR:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColor(,,FALSE);
+        if (i>=0) {
+          color=i;
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_COLOR));
+          tmpg->type=SPT_COLOR;
+          tmpg->c.color=color;
+          QueIns(tmpg,insert_pt->last);
+          SpriteEdUpdate(doc,doc_ce,head);
+          cur_elem_num++;
+        }
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_DITHER_COLOR:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColorDither;
+        if (i>=0) {
+          color=i;
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_DITHER_COLOR));
+          tmpg->type=SPT_DITHER_COLOR;
+          tmpg->d.dither_color=color.c0.color|color.c1.color<<8;
+          QueIns(tmpg,insert_pt->last);
+          SpriteEdUpdate(doc,doc_ce,head);
+          cur_elem_num++;
+        }
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_ED_MENU:
+        switch (SpriteEd(doc,doc_ce,x,y,&head,&cur_elem_num)) {
+          case SPE_ABORT:       eletype=DOCM_CANCEL;    break;
+          case SPE_EXIT:        eletype=SPT_EXIT;       break;
+          case SPE_CONT:        eletype=SPT_MENU;       break;
+        }
+        break;
+      case SPT_MESH:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        SMMesh(doc,doc_ce,head,&cur_elem_num);
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_SHIFTABLE_MESH:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        if (PopUpNoYes("Study the $LK,\"X-Caliber\","
+              "A=\"FF:::/PersonalMenu.DD.Z,X-Caliber\"$ icon.\n\n"
+              "It has black rectangle background with stars.  The\n"
+              "mesh is in front and rotates.  To keep the background\n"
+              "rectangle from rotating, "
+              "$GREEN$TRANSFORM OFF$FG$ has been used.\n\n"
+              "The X-Caliber mesh has a different origin for rotation.\n"
+              "To avoid clipping, it also has also been moved in the\n"
+              "negative Z direction by editing the sprite as text\n"
+              "and changing the first vector.\n\n"
+              "For the mesh you are creating, use same origin as\n"
+              "the rest of the sprite?  If $GREEN$YES$FG$, you can always\n"
+              "shift the mesh origin point in the sprite edit menu.\n")) {
+          doc_ce->de_flags=old_de_flags;
+          arg1=x; arg2=y;
+          SMShiftableMesh(doc,doc_ce,head,x,y,arg1,arg2,&cur_elem_num);
+          eletype=SPT_MENU;
+        } else
+          PopUpOk("Select Origin.\n");
+        doc_ce->de_flags=old_de_flags;
+        break;
+      case SPT_INS_SCRN_BITMAP:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        PopUpOk("Drag-out a rect for the extents of the\nbitmap.\n");
+        doc_ce->de_flags=old_de_flags;
+        Fs->win_inhibit=WIG_TASK_DFT|WIF_FOCUS_TASK_MS_L|WIF_FOCUS_TASK_MS_R|
+              WIF_FOCUS_TASK_BORDER-WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+        break;
+      case SPT_BITMAP:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColor("Background Color\n\n",,FALSE);
+        if (i<0)
+          eletype=SPT_MENU;
+        else {
+          bm_bkcolor=i;
+          SpriteEdUpdate(doc,doc_ce,head);
+          SpriteExtents(doc_ce->bin_data->data,&xx1,&xx2,&yy1,&yy2);
+          if (!(xx1<=xx2 && yy1<=yy2))
+            xx1=xx2=yy1=yy2=0;
+          if (PopUpExtents(&xx1,&xx2,&yy1,&yy2)) {
+            doc_ce->de_flags=old_de_flags;
+            xx1+=xx; yy1+=yy;
+            xx2+=xx; yy2+=yy;
+            if (SMBitMap(eletype,doc,doc_ce,head,dc,xx,yy,arg1,arg2,bm_bkcolor,
+                  FALSE,xx1,yy1,xx2,yy2,&cur_elem_num)==SPE_EXIT) {
+              res=SPE_EXIT;
+              goto ei_done;
+            }
+            eletype=SPT_MENU;
+          }
+        }
+        doc_ce->de_flags=old_de_flags;
+        break;
+      case SPT_INS_TRANSPARENT_SCRN_BITMAP:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpColor("Color to Become Transparent\n\n",,FALSE);
+        if (i<0)
+          eletype=SPT_MENU;
+        else {
+          bm_bkcolor=i;
+          PopUpOk("Drag-out a rect for the extents of the\nbitmap.\n");
+        }
+        doc_ce->de_flags=old_de_flags;
+        Fs->win_inhibit=WIG_TASK_DFT|WIF_FOCUS_TASK_MS_L|WIF_FOCUS_TASK_MS_R|
+              WIF_FOCUS_TASK_BORDER-WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+        break;
+      case SPT_THICK:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpRangeI64(1,16,1,"Thick\n");
+        if (i>=1) {
+          thick=i;
+          tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_THICK));
+          tmpg->type=SPT_THICK;
+          tmpg->t.thick=thick;
+          QueIns(tmpg,insert_pt->last);
+          SpriteEdUpdate(doc,doc_ce,head);
+          cur_elem_num++;
+        }
+        doc_ce->de_flags=old_de_flags;
+        eletype=SPT_MENU;
+        break;
+      case SPT_TRANSFORM_ON:
+      case SPT_TRANSFORM_OFF:
+        tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_TRANSFORM_ON));
+        if (eletype==SPT_TRANSFORM_ON)
+          tmpg->type=SPT_TRANSFORM_ON;
+        else
+          tmpg->type=SPT_TRANSFORM_OFF;
+        QueIns(tmpg,insert_pt->last);
+        SpriteEdUpdate(doc,doc_ce,head);
+        cur_elem_num++;
+        eletype=SPT_MENU;
+        break;
+      case SPT_POLYGON:
+        doc_ce->de_flags|=DOCEF_DONT_DRAW;
+        i=PopUpRangeI64(3,16,1,"Num of Sides\n");
+        doc_ce->de_flags=old_de_flags;
+        if (i<3)
+          eletype=SPT_MENU;
+        break;
+      case SPT_TEXT:
+      case SPT_TEXT_BOX:
+      case SPT_TEXT_DIAMOND:
+        SMTextFamily(eletype,doc,doc_ce,head,dc,xx,yy,arg1,arg2,
+              color,&cur_elem_num,old_de_flags);
+        eletype=SPT_MENU;
+        break;
+    }
+
+    if (eletype!=SPT_MENU) {
+      insert_pt=SpriteSetSettings(dc,head,cur_elem_num,xx,yy,
+            &color,&thick,&x,&y);
+      x+=xx; y+=yy;
+      SpriteScrnInit(dc,x,y);
+      if (eletype==SPT_EXIT) {
+        res=SPE_EXIT;
+        goto ei_done;
+      } else if (eletype==DOCM_CANCEL) {
+        res=SPE_ABORT;
+        goto ei_done;
+      }
+      switch (GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_R_UP|1<<MSG_MS_L_DOWN)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case CH_ESC:
+              res=SPE_EXIT;
+              goto ei_done;
+            case CH_SHIFT_ESC:
+              res=SPE_ABORT;
+              goto ei_done;
+            case 'c': //eye-dropper
+              dc3=DCScrnCapture(FALSE);
+              color=GrPeek(dc3,ms.pos.x,ms.pos.y)^15;//Mouse cursor is XORed.
+              DCDel(dc3);
+              tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_COLOR));
+              tmpg->type=SPT_COLOR;
+              tmpg->c.color=color;
+              QueIns(tmpg,insert_pt->last);
+              SpriteEdUpdate(doc,doc_ce,head);
+              cur_elem_num++;
+              break;
+            case 't': //Set to transparent color
+              tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_COLOR));
+              tmpg->type=SPT_COLOR;
+              tmpg->c.color=TRANSPARENT;
+              QueIns(tmpg,insert_pt->last);
+              SpriteEdUpdate(doc,doc_ce,head);
+              cur_elem_num++;
+              break;
+          }
+          break;
+        case MSG_MS_R_UP:
+          if (eletype==SPT_PLANAR_SYMMETRY) {
+            tmpg=CAlloc(SpriteElemQuedBaseSize(SPT_PLANAR_SYMMETRY));
+            tmpg->type=SPT_PLANAR_SYMMETRY;
+            QueIns(tmpg,insert_pt->last);
+            SpriteEdUpdate(doc,doc_ce,head);
+            cur_elem_num++;
+            eletype=SPT_MENU;
+          } else
+            eletype=SPT_MENU;
+          break;
+        case MSG_MS_L_DOWN:
+          switch (eletype) {
+            start:
+              case SPT_LINE:
+                tmpg=SMLine(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_ARROW:
+                tmpg=SMArrow(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_PLANAR_SYMMETRY:
+                tmpg=SMPlanarSymmetry(dc,x,y,arg1,arg2);
+                eletype=SPT_MENU;
+                break;
+              case SPT_RECT:
+                tmpg=SMRect(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_INS_SCRN_BITMAP:
+              case SPT_INS_TRANSPARENT_SCRN_BITMAP:
+                tmpg=SMScrnBitMap(eletype,dc,dc2,x,y,arg1,arg2,bm_bkcolor);
+                eletype=SPT_MENU;
+                break;
+              case SPT_CIRCLE:
+                tmpg=SMCircle(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_ELLIPSE:
+                tmpg=SMEllipse(dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_POLYGON:
+                tmpg=SMPolygon(dc,x,y,arg1,arg2,i,color);
+                eletype=SPT_MENU;
+                break;
+              case SPT_PT:
+              case SPT_FLOOD_FILL:
+              case SPT_FLOOD_FILL_NOT:
+                tmpg=CAlloc(SpriteElemQuedBaseSize(eletype));
+                tmpg->type=eletype;
+                tmpg->p.x1=arg1-x;
+                tmpg->p.y1=arg2-y;
+                break;
+              case SPT_POLYLINE:
+              case SPT_BSPLINE2:
+              case SPT_BSPLINE3:
+              case SPT_BSPLINE2_CLOSED:
+              case SPT_BSPLINE3_CLOSED:
+                tmpg=SMPolyLineFamily(eletype,dc,x,y,arg1,arg2,color);
+                break;
+              case SPT_POLYPT:
+                tmpg=SMPolyPoint(dc,x,y,arg1,arg2,color);
+                break;
+            end:
+              if (tmpg) {
+                QueIns(tmpg,insert_pt->last);
+                SpriteEdUpdate(doc,doc_ce,head);
+                cur_elem_num++;
+              }
+              break;
+            case SPT_BITMAP:
+              if (SMBitMap(eletype,doc,doc_ce,head,dc,xx,yy,
+                    arg1,arg2,bm_bkcolor,TRUE,,,,,&cur_elem_num)==SPE_EXIT) {
+                res=SPE_EXIT;
+                goto ei_done;
+              }
+              doc_ce->de_flags=old_de_flags;
+              eletype=SPT_MENU;
+              break;
+            case SPT_SHIFTABLE_MESH:
+              GetMsg(NULL,NULL,1<<MSG_MS_L_UP);
+              doc_ce->de_flags|=DOCEF_DONT_DRAW;
+              SMShiftableMesh(doc,doc_ce,head,x,y,arg1,arg2,&cur_elem_num);
+              doc_ce->de_flags=old_de_flags;
+              eletype=SPT_MENU;
+              break;
+          }
+          break;
+      }
+    }
+  }
+ei_done:
+  DCFill;
+  SettingsPop;
+  doc_ce->de_flags=old_de_flags;
+  DCDel(dc);
+  DCDel(dc2);
+  StrCpy(Fs->task_title,old_task_title);
+  Free(old_task_title);
+  Fs->border_src=old_border_src;
+  Fs->title_src =old_title_src;
+  QueDel(head);
+  Free(head);
+  return res;
+}
+
+U0 EdSpriteIns(CDoc *doc)
+{
+  Bool unlock;
+  U8 *st;
+  CDocEntry *doc_e;
+  CDocBin *tmpb;
+  if (Fs!=doc->mem_task)
+    throw('Graphics');
+  if (st=EdSprite(doc->cur_bin_num)) {
+    unlock=DocLock(doc);
+    tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
+    tmpb->size=sprite_elem_base_sizes[SPT_END];
+    tmpb->data=CAlloc(tmpb->size,doc->mem_task);
+    tmpb->num=doc->cur_bin_num++;
+    tmpb->use_cnt=1;
+    QueIns(tmpb,doc->bin_head.last);
+    doc_e=DocPrint(doc,"%s",st);
+    doc_e->bin_data=tmpb;
+    Free(st);
+    if (doc_e) {
+      if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
+        tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
+      doc->cur_entry=doc_e;
+      doc->cur_col=0;
+      DocUnlock(doc);
+      DocRecalc(doc);
+      if (SpriteMainEd(doc)==SPE_ABORT) {
+        DocLock(doc);
+        DocEntryDel(doc,doc_e);
+      } else
+        SpriteSelAll(tmpb->data,FALSE);
+    } else
+      DocBinDel(doc,tmpb);
+    if (unlock)
+      DocUnlock(doc);
+  }
+  if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
+    DocBinsValidate(doc);
+}
+
+U0 EdSpriteEd(CDoc *doc)
+{
+  CDocEntry *doc_ce;
+  CDocBin *tmpb;
+  CSprite *old_csprite;
+  I64   old_size;
+  Bool unlock=DocLock(doc);
+  doc_ce=doc->cur_entry;
+  tmpb=doc_ce->bin_data;
+  old_size=tmpb->size;
+  old_csprite=tmpb->data;
+  tmpb->data=MAllocIdent(old_csprite,doc->mem_task);
+  DocUnlock(doc);
+  if (SpriteMainEd(doc)==SPE_ABORT) {
+    DocLock(doc);
+    Free(tmpb->data);
+    tmpb->data=old_csprite;
+    tmpb->size=old_size;
+  } else {
+    SpriteSelAll(tmpb->data,FALSE);
+    Free(old_csprite);
+  }
+  if (unlock)
+    DocUnlock(doc);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/SpriteMesh.HC.HTML b/public/Wb/Home/Src/Adam/Gr/SpriteMesh.HC.HTML new file mode 100755 index 0000000..5d52a61 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/SpriteMesh.HC.HTML @@ -0,0 +1,1539 @@ + + + + + + + + + + + +
+#help_index "Graphics/Mesh"
+#define MESH_WORKSPACE_SIZE     4000
+
+#define VF_SEL          1
+#define VF_COPIED       2
+#define VF_IGNORE       4
+
+class CMeshEdVertex
+{
+  CMeshEdVertex *next,*last,*copy;
+
+  U0 start;
+  CD3I32 p; //World coordinates of the point.
+  U0 end;
+  CD3I32 p0,
+        pt; //Transformed coordinates.  (Scrn)
+  I32 num,flags;
+};
+
+#define TF_SEL  1
+#define TF_COPIED       2
+
+class CMeshEdTri
+{
+  CMeshEdTri *next,*last;
+
+  U0 start;
+  CMeshTri mt;
+  U0 end;
+
+  I32 cpu_num,flags; //Draw different tris with different cores.
+  CMeshEdVertex *t[3];
+};
+
+class CMeshFrame
+{
+  I64 ms_z,thickness; //Mouse Z-coordinate
+  I64 ed_mode,cx,cy;
+  CColorROPU32 cur_color;
+  Bool grid_on,flip_y,sel_rect,vertex_on,closed,pad[3];
+  I64 mp_not_done_flags; //Used for multiprocessing signaling.
+  F64 view_scale;
+  CDC *dc;
+  I32 *depth_buf;
+  I64 *w2s,*s2w; //Scrn-to-world and world-to-scrn transform matrices.
+  I64 vertex_cnt,tri_cnt; //Set by MeshSize
+  CMeshEdVertex vertex_head,*cur_vertex,*chain_pred;
+  CMeshEdTri    tri_head,*cur_tri;
+  I64 x1,y1,x2,y2,cur_snap;
+};
+
+CMeshEdVertex *MeshVertexNew(CMeshFrame *e,I64 x,I64 y,I64 z)
+{
+  CMeshEdVertex *tmpv=CAlloc(sizeof(CMeshEdVertex));
+  tmpv->p.x=x;
+  tmpv->p.y=y;
+  tmpv->p.z=z;
+  QueIns(tmpv,e->vertex_head.last);
+  return tmpv;
+}
+
+CMeshEdTri *MeshTriNew(CMeshFrame *e,CColorROPU32 color,
+        CMeshEdVertex *v1,CMeshEdVertex *v2,CMeshEdVertex *v3)
+{
+  static I64 cpu_num=0;
+  CMeshEdTri *tmpt=CAlloc(sizeof(CMeshEdTri));
+  tmpt->cpu_num=cpu_num++%mp_cnt;
+  tmpt->mt.color=color;
+  tmpt->t[0]=v1;
+  tmpt->t[1]=v2;
+  tmpt->t[2]=v3;
+  QueIns(tmpt,e->tri_head.last);
+  return tmpt;
+}
+
+CMeshEdVertex *MeshVertexFindScrPt(CMeshFrame *e,I64 x,I64 y)
+{//Scrn coordinates
+  CMeshEdVertex *res=NULL,*tmpv=e->vertex_head.next;
+  I64 dd,dz,best_dd=I64_MAX,best_dz=I64_MAX;
+  while (tmpv!=&e->vertex_head) {
+    if (!(tmpv->flags&VF_IGNORE)) {
+      dd=SqrI64(x-tmpv->pt.x)+SqrI64(y-tmpv->pt.y);
+      dz=AbsI64(e->ms_z-tmpv->p.z);
+      if (dd<best_dd || dd==best_dd && dz<best_dz) {
+        res=tmpv;
+        best_dd=dd;
+        best_dz=dz;
+      }
+    }
+    tmpv=tmpv->next;
+  }
+  return res;
+}
+
+CMeshEdVertex *MeshVertexFindNum(CMeshFrame *haystack_e,I64 needle_num)
+{
+  CMeshEdVertex *tmpv=haystack_e->vertex_head.next;
+  while (tmpv!=&haystack_e->vertex_head) {
+    if (tmpv->num==needle_num)
+      return tmpv;
+    tmpv=tmpv->next;
+  }
+  return NULL;
+}
+
+U0 MeshTriDel(CMeshFrame *e,CMeshEdTri *tmpt)
+{
+  if (tmpt) {
+    if (tmpt==e->cur_tri)
+      e->cur_tri=NULL;
+    QueRem(tmpt);
+    Free(tmpt);
+  }
+}
+
+U0 MeshVertexDel(CMeshFrame *e,CMeshEdVertex *tmpv)
+{
+  I64 i;
+  CMeshEdTri *tmpt,*tmpt1;
+  if (tmpv) {
+    tmpt=e->tri_head.next;
+    while (tmpt!=&e->tri_head) {
+      tmpt1=tmpt->next;
+      for (i=0;i<3;i++)
+        if (tmpt->t[i]==tmpv)
+          break;
+      if (i<3)
+        MeshTriDel(e,tmpt);
+      tmpt=tmpt1;
+    }
+    if (tmpv==e->cur_vertex)
+      e->cur_vertex=NULL;
+    if (tmpv==e->chain_pred)
+      e->chain_pred=NULL;
+    QueRem(tmpv);
+    Free(tmpv);
+  }
+}
+
+U0 MeshFence(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv,*tmpv1,*tmpv_last=NULL,*tmpv1_last=NULL,
+        *start=e->chain_pred->next,*end=e->vertex_head.last;
+  tmpv=start;
+  while (TRUE) {
+    tmpv1=MeshVertexNew(e,tmpv->p.x,tmpv->p.y,tmpv->p.z+e->thickness);
+    if (tmpv_last) {
+      MeshTriNew(e,e->cur_color,tmpv_last,tmpv,tmpv1);
+      MeshTriNew(e,e->cur_color,tmpv1,tmpv1_last,tmpv_last);
+    }
+    tmpv_last=tmpv;
+    tmpv1_last=tmpv1;
+    if (tmpv==end)
+      break;
+    tmpv=tmpv->next;
+  }
+  if (e->closed && tmpv_last) {
+    MeshTriNew(e,e->cur_color,tmpv_last,start,end->next);
+    MeshTriNew(e,e->cur_color,end->next,tmpv1_last,tmpv_last);
+  }
+}
+
+U0 MeshPolygon(CMeshFrame *e,CMeshEdVertex *start,CMeshEdVertex *end,Bool rev)
+{
+  CMeshEdVertex *tmpv,*tmpv1;
+  if (start!=end) {
+    tmpv=start;
+    tmpv1=tmpv->next;
+    while (tmpv1!=end) {
+      if (rev)
+        MeshTriNew(e,e->cur_color,tmpv1,tmpv,end);
+      else
+        MeshTriNew(e,e->cur_color,tmpv,tmpv1,end);
+      tmpv=tmpv->next;
+      tmpv1=tmpv1->next;
+    }
+  }
+}
+
+U0 MeshPrism(CMeshFrame *e)
+{
+  CMeshEdVertex *start=e->chain_pred->next,*end=e->vertex_head.last;
+  MeshFence(e);
+  MeshPolygon(e,start,end,FALSE);
+  MeshPolygon(e,end->next,e->vertex_head.last,TRUE);
+}
+
+U0 MeshVertexSelAll(CMeshFrame *e,Bool val)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    if (val)
+      tmpv->flags|=VF_SEL;
+    else
+      tmpv->flags&=~VF_SEL;
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshTriSelAll(CMeshFrame *e,Bool val)
+{
+  CMeshEdTri *tmpt=e->tri_head.next;
+  while (tmpt!=&e->tri_head) {
+    if (val)
+      tmpt->flags|=TF_SEL;
+    else
+      tmpt->flags&=~TF_SEL;
+    tmpt=tmpt->next;
+  }
+}
+
+U0 MeshVertexIgnoreSet(CMeshFrame *e,Bool val)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    tmpv->flags&=~VF_IGNORE;
+    if (tmpv->flags&VF_SEL && val)
+      tmpv->flags|=VF_IGNORE;
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshP0Capture(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    MemCpy(&tmpv->p0,&tmpv->p,sizeof(CD3I32));
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshP0Offset(CMeshFrame *e,I64 dx,I64 dy,I64 dz)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL) {
+      tmpv->p.x=tmpv->p0.x+dx;
+      tmpv->p.y=tmpv->p0.y+dy;
+      tmpv->p.z=tmpv->p0.z+dz;
+    }
+    tmpv=tmpv->next;
+  }
+}
+
+#define SEL_MESH_EQU    0
+#define SEL_MESH_OR     1
+#define SEL_MESH_AND    2
+
+U0 MeshVertexSelRect(CMeshFrame *e,I64 sel_mode,I64 x1,I64 x2,I64 y1,I64 y2)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (x1>x2) SwapI64(&x1,&x2);
+  if (y1>y2) SwapI64(&y1,&y2);
+  while (tmpv!=&e->vertex_head) {
+    if (x1<=tmpv->pt.x<=x2 &&
+          y1<=tmpv->pt.y<=y2) {
+      if (sel_mode==SEL_MESH_AND)
+        tmpv->flags&=~VF_SEL;
+      else
+        tmpv->flags|=VF_SEL;
+    } else if (sel_mode==SEL_MESH_EQU)
+      tmpv->flags&=~VF_SEL;
+    tmpv=tmpv->next;
+  }
+}
+
+U0 MeshTriSelRect(CMeshFrame *e,I64 sel_mode,I64 x1,I64 x2,I64 y1,I64 y2)
+{
+  CMeshEdTri *tmpt=e->tri_head.next;
+  if (x1>x2) SwapI64(&x1,&x2);
+  if (y1>y2) SwapI64(&y1,&y2);
+  while (tmpt!=&e->tri_head) {
+    if (x1<=tmpt->t[0]->pt.x<=x2 &&
+          y1<=tmpt->t[0]->pt.y<=y2 &&
+          x1<=tmpt->t[1]->pt.x<=x2 &&
+          y1<=tmpt->t[1]->pt.y<=y2 &&
+          x1<=tmpt->t[2]->pt.x<=x2 &&
+          y1<=tmpt->t[2]->pt.y<=y2) {
+      if (sel_mode==SEL_MESH_AND)
+        tmpt->flags&=~TF_SEL;
+      else
+        tmpt->flags|=TF_SEL;
+    } else {
+      if (sel_mode==SEL_MESH_EQU)
+        tmpt->flags&=~TF_SEL;
+      else if (sel_mode==SEL_MESH_AND) {
+        if (x1<=tmpt->t[0]->pt.x<=x2 &&
+              y1<=tmpt->t[0]->pt.y<=y2 ||
+              x1<=tmpt->t[1]->pt.x<=x2 &&
+              y1<=tmpt->t[1]->pt.y<=y2 ||
+              x1<=tmpt->t[2]->pt.x<=x2 &&
+              y1<=tmpt->t[2]->pt.y<=y2)
+          tmpt->flags&=~TF_SEL;
+      }
+    }
+    tmpt=tmpt->next;
+  }
+}
+
+I64 MeshSelCnt(CMeshFrame *e)
+{
+  I64 res=0;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  CMeshEdTri *tmpt=e->tri_head.next;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL)
+      res++;
+    tmpv=tmpv->next;
+  }
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags&TF_SEL)
+      res++;
+    tmpt=tmpt->next;
+  }
+  return res;
+}
+
+U0 MeshSwapAxes(CMeshFrame *e,I64 o1,I64 o2)
+{
+  Bool unsel;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshVertexSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL)
+      SwapU32((&tmpv->p)(U8 *)+o1,(&tmpv->p)(U8 *)+o2);
+    tmpv=tmpv->next;
+  }
+  if (unsel)
+    MeshVertexSelAll(e,FALSE);
+}
+
+U0 MeshInvertAxis(CMeshFrame *e,I64 o)
+{
+  Bool unsel;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshVertexSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL)
+      *((&tmpv->p)(U8 *)+o)(I32 *)=-*((&tmpv->p)(U8 *)+o)(I32 *);
+    tmpv=tmpv->next;
+  }
+  if (unsel)
+    MeshVertexSelAll(e,FALSE);
+}
+
+U0 MeshTransformSel(CMeshFrame *e)
+{
+  Bool unsel;
+  I64 r[16],x,y,z;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  if (PopUpTransform(r)) {
+    if (!MeshSelCnt(e)) {
+      MeshVertexSelAll(e,TRUE);
+      unsel=TRUE;
+    } else
+      unsel=FALSE;
+    while (tmpv!=&e->vertex_head) {
+      if (tmpv->flags&VF_SEL) {
+        x=tmpv->p.x; y=tmpv->p.y; z=tmpv->p.z;
+        Mat4x4MulXYZ(r,&x,&y,&z);
+        tmpv->p.x=x; tmpv->p.y=y; tmpv->p.z=z;
+      }
+      tmpv=tmpv->next;
+    }
+    if (unsel)
+      MeshVertexSelAll(e,FALSE);
+  }
+}
+
+U0 MeshColorTris(CMeshFrame *e)
+{
+  Bool unsel;
+  CMeshEdTri *tmpt=e->tri_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshTriSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags & TF_SEL)
+      tmpt->mt.color=e->cur_color;
+    tmpt=tmpt->next;
+  }
+  if (unsel)
+    MeshTriSelAll(e,FALSE);
+}
+
+U0 MeshRevTris(CMeshFrame *e)
+{
+  Bool unsel;
+  CMeshEdTri *tmpt=e->tri_head.next;
+  if (!MeshSelCnt(e)) {
+    MeshTriSelAll(e,TRUE);
+    unsel=TRUE;
+  } else
+    unsel=FALSE;
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags & TF_SEL)
+      SwapI64(&tmpt->t[1],&tmpt->t[2]);
+    tmpt=tmpt->next;
+  }
+  if (unsel)
+    MeshTriSelAll(e,FALSE);
+}
+
+U0 MeshRecalcCxCy(CTask *task,CMeshFrame *e)
+{
+  e->cx=RoundI64(task->pix_width/2 -task->horz_scroll.pos,e->cur_snap);
+  e->cy=RoundI64(task->pix_height/2-task->vert_scroll.pos,e->cur_snap);
+}
+
+U0 MeshCurSnap(CMeshFrame *e)
+{
+  I64 x1,y1,z1,x2,y2,z2;
+  if (e->w2s) {
+    x1=e->cur_snap<<16; y1=0; z1=0;
+    Mat4x4MulXYZ(e->w2s,&x1,&y1,&z1);
+    x2=0; y2=e->cur_snap<<16; z2=0;
+    Mat4x4MulXYZ(e->w2s,&x2,&y2,&z2);
+    ms_grid.x=Max(1,MaxI64(x1,x2)>>16);
+    ms_grid.y=Max(1,MaxI64(y1,y2)>>16);
+    ms_grid.z=Min(ms_grid.x,ms_grid.y);
+  }
+}
+
+U0 MeshScaleZoom(CMeshFrame *e,F64 scale)
+{
+  CTask *task=Fs;
+  I64   x=ms.pos.x-task->pix_left-task->scroll_x-task->pix_width/2,
+        y=ms.pos.y-task->pix_top-task->scroll_y-task->pix_height/2;
+  task->horz_scroll.pos*=scale;
+  task->vert_scroll.pos*=scale;
+  task->horz_scroll.pos+=scale*x-x;
+  task->vert_scroll.pos+=scale*y-y;
+  e->view_scale*=scale;
+  MeshRecalcCxCy(task,e);
+  MeshCurSnap(e);
+}
+
+U0 MPDrawIt(CMeshFrame *e)
+{//Multiprocessing draw it, called by each core.
+
+  //Makes a copy of e->dc so we can change dc->color member and stuff.
+  CDC *dc=DCAlias(e->dc,e->dc->win_task);
+
+  CMeshEdTri *tmpt=e->tri_head.next;
+  I64 i,*old_r=dc->r;
+
+  //DCAlias() allocs a new identity rotation matrix.
+  //We want e->dc's rotation matrix.
+  dc->r=e->dc->r;
+  dc->depth_buf=e->depth_buf;
+  MemCpy(&dc->ls,&e->dc->ls,sizeof(CD3I32));
+
+  //... and translation (shift) vals.
+  dc->x=e->dc->x;
+  dc->y=e->dc->y;
+  dc->z=e->dc->z;
+  dc->flags|=DCF_TRANSFORMATION;
+
+  if (e->grid_on)
+//Draw grid with different cores.
+    for (i=-500+25*Gs->num;i<=500;i+=25*mp_cnt) {
+      if (i) {
+        dc->color=DKGRAY;
+        GrLine3(dc,i,-500,0,i,500,0);
+        dc->color=LTGRAY;
+        GrLine3(dc,-500,i,0,500,i,0);
+      }
+    }
+  if (!Gs->num) {
+    dc->color=RED;      //Y-Axis red
+    GrLine3(dc,0,0,0,0,500,0);
+    dc->color=ROPF_DITHER+RED;   //Y-Axis red
+    GrLine3(dc,0,-500,0,0,0,0);
+
+    dc->color=YELLOW;   //X-Axis yellow
+    GrLine3(dc,0,0,0,500,0,0);
+    dc->color=ROPF_DITHER+YELLOW;        //X-Axis yellow
+    GrLine3(dc,-500,0,0,0,0,0);
+
+    dc->color=GREEN;    //Z-Axis green
+    GrLine3(dc,0,0,0,0,0,500);
+    dc->color=ROPF_DITHER+GREEN;         //Z-Axis green
+    GrLine3(dc,0,0,-500,0,0,0);
+  }
+
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->cpu_num==Gs->num) {
+      if (tmpt->flags & TF_SEL) {
+        if (Blink)
+          dc->color=ROPF_DITHER+WHITE<<16+RED;
+        else
+          dc->color=ROPF_DITHER+RED<<16+WHITE;
+        GrFillTri0(dc,&tmpt->t[0]->pt,&tmpt->t[1]->pt,&tmpt->t[2]->pt);
+      } else {
+        (*dc->lighting)(dc,&tmpt->t[0]->pt,&tmpt->t[1]->pt,
+              &tmpt->t[2]->pt,tmpt->mt.color);
+        GrFillTri0(dc,&tmpt->t[0]->pt,&tmpt->t[1]->pt,&tmpt->t[2]->pt);
+      }
+    }
+    tmpt=tmpt->next;
+  }
+  dc->r=old_r;
+
+  //e->dc's depth buf was copied but we don't want it freed during DCDel().
+  dc->depth_buf=NULL;
+
+  DCDel(dc);
+  LBtr(&e->mp_not_done_flags,Gs->num);
+}
+
+I64 *MeshW2S(CMeshFrame *e,CTask *task)
+{//World to scrn coordinate transform matrix.
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s=c->state;
+  I64 *r=Mat4x4IdentNew(task);
+  Mat4x4Scale(r,e->view_scale);
+  Mat4x4RotZ(r,s->az);
+  Mat4x4RotY(r,s->ay);
+  if (e->flip_y)
+    Mat4x4RotX(r,s->ax);
+  else
+    Mat4x4RotX(r,s->ax+pi);
+  return r;
+}
+
+I64 *MeshS2W(CMeshFrame *e,CTask *task)
+{//Scrn to world coordinate transform matrix.
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s=c->state;
+  I64 *r=Mat4x4IdentNew(task);
+  if (e->flip_y)
+    Mat4x4RotX(r,-s->ax);
+  else
+    Mat4x4RotX(r,-(s->ax+pi));
+  Mat4x4RotY(r,-s->ay);
+  Mat4x4RotZ(r,-s->az);
+  Mat4x4Scale(r,1/e->view_scale);
+  return r;
+}
+
+I64 *MeshSetW2S(CMeshFrame *e,CTask *task)
+{
+  Free(e->w2s);
+  e->w2s=MeshW2S(e,task);
+  Free(e->s2w);
+  e->s2w=MeshS2W(e,task);
+//returned matrix is assigned to dc->r and will be freed by DCDel().
+  return Mat4x4New(e->w2s,task);
+}
+
+U0 MeshCursorW(CMeshFrame *e,CTask *task,I64 *_x,I64 *_y,I64 *_z)
+{
+  I64   x_shadow,y_shadow,z_shadow,
+        xc=ms.pos.x-task->pix_left-task->scroll_x-e->cx,
+        yc=ms.pos.y-task->pix_top-task->scroll_y-e->cy,zc=0,
+        x=0,y=0,z=e->ms_z,
+        i,x2,y2,z2;
+  Mat4x4MulXYZ(e->w2s,&x,&y,&z); //scrn of Z vect
+
+  //Converges onto a solution for zc, an unknown.
+  for (i=0;i<128;i++) {
+    x_shadow=xc-x; //Shadow of mouse cursor on xy plane
+    y_shadow=yc-y;
+    z_shadow=zc-z;
+    Mat4x4MulXYZ(e->s2w,&x_shadow,&y_shadow,&z_shadow);
+    x2=0; y2=0; z2=-z_shadow;
+    Mat4x4MulXYZ(e->w2s,&x2,&y2,&z2);
+    zc+=Round(Sqrt(x2*x2+y2*y2+z2*z2))*SignI64(z2);
+  }
+
+  x=xc-x;
+  y=yc-y;
+  z=zc-z;
+  Mat4x4MulXYZ(e->s2w,&x,&y,&z);
+  x=RoundI64(x,e->cur_snap);
+  y=RoundI64(y,e->cur_snap);
+  z=RoundI64(e->ms_z,e->cur_snap);
+  *_x=x; *_y=y; *_z=z;
+}
+
+CMeshEdVertex   sys_clip_vertex_head;
+CMeshEdTri      sys_clip_tri_head;
+
+U0 MeshClipInit()
+{
+  QueInit(&sys_clip_vertex_head);
+  QueInit(&sys_clip_tri_head);
+}
+
+U0 MeshClipRst()
+{
+  QueDel(&sys_clip_vertex_head,TRUE);
+  QueDel(&sys_clip_tri_head,TRUE);
+  MeshClipInit;
+}
+
+U0 MeshClipCopy(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next,*tmpv2;
+  CMeshEdTri    *tmpt=e->tri_head.next,*tmpt2;
+
+  MeshClipRst;
+  while (tmpv!=&e->vertex_head) {
+    if (tmpv->flags&VF_SEL) {
+      tmpv->copy=tmpv2=ACAlloc(sizeof(CMeshEdVertex));
+      MemCpy(&tmpv2->p,&tmpv->p,sizeof(CD3I32));
+      QueIns(tmpv2,sys_clip_vertex_head.last);
+      tmpv->flags|=VF_COPIED;
+      tmpv->flags&=~VF_SEL;
+    } else {
+      tmpv->copy=NULL;
+      tmpv->flags&=~(VF_COPIED|VF_SEL);
+    }
+    tmpv=tmpv->next;
+  }
+  while (tmpt!=&e->tri_head) {
+    if (tmpt->flags&TF_SEL &&
+          tmpt->t[0]->copy && tmpt->t[1]->copy && tmpt->t[2]->copy) {
+      tmpt2=ACAlloc(sizeof(CMeshEdTri));
+      tmpt2->t[0]=tmpt->t[0]->copy;
+      tmpt2->t[1]=tmpt->t[1]->copy;
+      tmpt2->t[2]=tmpt->t[2]->copy;
+      tmpt2->mt.color=tmpt->mt.color;
+      QueIns(tmpt2,sys_clip_tri_head.last);
+      tmpt->flags|=TF_COPIED;
+      tmpt->flags&=~TF_SEL;
+    } else
+      tmpt->flags&=~(TF_COPIED|TF_SEL);
+    tmpt=tmpt->next;
+  }
+}
+
+U0 MeshClipCut(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv=e->vertex_head.next,*tmpv1;
+  CMeshEdTri    *tmpt=e->tri_head.next,*tmpt1;
+  MeshClipCopy(e);
+  while (tmpt!=&e->tri_head) {
+    tmpt1=tmpt->next;
+    if (tmpt->flags&TF_COPIED)
+      MeshTriDel(e,tmpt);
+    tmpt=tmpt1;
+  }
+  while (tmpv!=&e->vertex_head) {
+    tmpv1=tmpv->next;
+    if (tmpv->flags&VF_COPIED)
+      MeshVertexDel(e,tmpv);
+    tmpv=tmpv1;
+  }
+}
+
+U0 MeshClipDel(CMeshFrame *e)
+{//Technically not clip
+  CMeshEdVertex *tmpv=e->vertex_head.next,*tmpv1;
+  CMeshEdTri    *tmpt=e->tri_head.next,*tmpt1;
+  while (tmpt!=&e->tri_head) {
+    tmpt1=tmpt->next;
+    if (tmpt->flags&TF_SEL)
+      MeshTriDel(e,tmpt);
+    tmpt=tmpt1;
+  }
+  while (tmpv!=&e->vertex_head) {
+    tmpv1=tmpv->next;
+    if (tmpv->flags&VF_SEL)
+      MeshVertexDel(e,tmpv);
+    tmpv=tmpv1;
+  }
+}
+
+U0 MeshClipPaste(CMeshFrame *e)
+{
+  CMeshEdVertex *tmpv2=sys_clip_vertex_head.next,*tmpv;
+  CMeshEdTri    *tmpt2=sys_clip_tri_head.next,*tmpt;
+
+  MeshVertexSelAll(e,FALSE);
+  MeshTriSelAll(e,FALSE);
+  while (tmpv2!=&sys_clip_vertex_head) {
+    tmpv2->copy=tmpv=CAlloc(sizeof(CMeshEdVertex));
+    MemCpy(&tmpv->p,&tmpv2->p,sizeof(CD3I32));
+    QueIns(tmpv,e->vertex_head.last);
+    tmpv->flags|=VF_SEL;
+    tmpv2=tmpv2->next;
+  }
+
+  while (tmpt2!=&sys_clip_tri_head) {
+    tmpt=MeshTriNew(e,tmpt2->mt.color,tmpt2->t[0]->copy,
+          tmpt2->t[1]->copy,tmpt2->t[2]->copy);
+    tmpt->flags|=TF_SEL;
+    tmpt2=tmpt2->next;
+  }
+}
+
+MeshClipInit;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CMeshFrame *e=FramePtr("CMeshFrame",task);
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  F64 d;
+  I64 i,x,y,z;
+  CMeshEdVertex *tmpv;
+
+  task->horz_scroll.min=-(MESH_WORKSPACE_SIZE-task->pix_width)/2;
+  task->horz_scroll.max= (MESH_WORKSPACE_SIZE-task->pix_width)/2;
+  task->vert_scroll.min=-(MESH_WORKSPACE_SIZE-task->pix_height)/2;
+  task->vert_scroll.max= (MESH_WORKSPACE_SIZE-task->pix_height)/2;
+  TaskDerivedValsUpdate(task);
+  MeshRecalcCxCy(task,e);
+
+  dc->flags|=DCF_TRANSFORMATION;
+
+  Free(dc->r); //Set rotmat doesn't free old dc->r matrix.
+  DCMat4x4Set(dc,MeshSetW2S(e,task));
+
+  dc->x=e->cx;
+  dc->y=e->cy;
+//z-vals less than zero are in front of scrn and not drawn.
+  //we want to shift all Z-vals into a drawable range.
+  //GR_Z_ALL is set to half of the Z-range which is an I32.
+  dc->z=GR_Z_ALL;
+
+  //Light source set to mouse.
+  MeshCursorW(e,task,&x,&y,&z);
+  dc->ls.x=x;
+  dc->ls.y=y;
+  dc->ls.z=z;
+  d=1<<16/D3I32Norm(&dc->ls); //Light source normalized to 65536.
+  dc->ls.x*=d;
+  dc->ls.y*=d;
+  dc->ls.z*=d;
+
+  DCDepthBufAlloc(dc);
+
+  tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    x=tmpv->p.x; y=tmpv->p.y; z=tmpv->p.z;
+    (*dc->transform)(dc,&x,&y,&z);
+    tmpv->pt.x=x; tmpv->pt.y=y; tmpv->pt.z=z;
+    tmpv=tmpv->next;
+  }
+
+  e->mp_not_done_flags=1<<mp_cnt-1; //Issue jobs to all cores.
+  e->dc=dc;
+  e->depth_buf=dc->depth_buf;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPDrawIt,e,i);
+
+  tmpv=e->vertex_head.next;
+  while (tmpv!=&e->vertex_head) {
+    x=tmpv->pt.x; y=tmpv->pt.y; z=tmpv->pt.z;
+    if (e->vertex_on) {
+      if (Blink(10)) //This blinks at 10 Hz.
+        dc->color=ROPF_DITHER+BLACK<<16+WHITE;
+      else
+        dc->color=ROPF_DITHER+WHITE<<16+BLACK;
+      GrLine(dc,x-3,y-3,x+3,y+3);
+      GrLine(dc,x-3,y+3,x+3,y-3);
+    }
+    if (tmpv->flags&VF_SEL) {
+      if (e->ed_mode=='t') {
+        if (Blink(10)) //This blinks at 10 Hz.
+          dc->color=ROPF_DITHER+e->cur_color.c0.color<<16+
+                e->cur_color.c0.color^8;
+        else
+          dc->color=ROPF_DITHER+(e->cur_color.c0.color^8)<<16+
+                e->cur_color.c0.color;
+      } else {
+        if (Blink)
+          dc->color=ROPF_DITHER+RED<<16+WHITE;
+        else
+          dc->color=ROPF_DITHER+WHITE<<16+RED;
+      }
+      GrCircle(dc,x,y,3);
+    }
+    tmpv=tmpv->next;
+  }
+
+  if (CtrlInside(c,ms.presnap.x,ms.presnap.y)||winmgr.show_menu) {
+    GridInit;
+    task->win_inhibit=WIF_SELF_DOC;
+  } else {
+    MeshCurSnap(e);
+    task->win_inhibit=WIG_TASK_DFT|WIF_SELF_DOC-WIF_SELF_FOCUS-WIF_SELF_BORDER
+          -WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU-WIF_SELF_GRAB_SCROLL;
+  }
+
+  MeshCursorW(e,task,&x,&y,&z);
+  if (z<0)
+    dc->color=ROP_XOR+RED^TRANSPARENT;
+  else
+    dc->color=ROP_XOR+TRANSPARENT;
+  GrPrint(dc,0,0,"%6.3f%% (%d,%d,%d)",e->view_scale*100,x,y,z);
+  dc->thick=1;
+  dc->color&=0xF;
+  if (Blink(10))
+    dc->color^=0xF;
+  GrLine3(dc,x,y,z,x,y,0);
+
+  if (e->sel_rect) {
+    dc->flags&=~DCF_TRANSFORMATION;
+    dc->thick=1;
+    if (Blink)
+      dc->color=ROPF_DITHER+RED<<16+WHITE;
+    else
+      dc->color=ROPF_DITHER+WHITE<<16+RED;
+    GrBorder(dc,e->x1,e->y1,e->x2,e->y2);
+  }
+//Wait for all cores to complete.
+  while (e->mp_not_done_flags)
+    Yield;
+}
+
+U0 MeshInit(CMeshFrame *e,Bool flip_y)
+{
+  MemSet(e,0,sizeof(CMeshFrame));
+  QueInit(&e->vertex_head);
+  QueInit(&e->tri_head);
+  e->ed_mode='v';
+  e->grid_on=TRUE;
+  e->vertex_on=TRUE;
+  e->ms_z=0;
+  e->thickness=25;
+  e->closed=TRUE;
+  e->view_scale=1.0;
+  e->w2s=NULL;
+  e->s2w=NULL;
+  e->cur_color=RED;
+  e->cur_snap=5;
+  e->flip_y=flip_y;
+  e->sel_rect=FALSE;
+  e->cur_tri=NULL;
+  e->cur_vertex=NULL;
+  e->chain_pred=NULL;
+}
+
+U0 MeshLoad(CMeshFrame *e,U8 *src)
+{
+  I64 i,j,x,y,z;
+  CColorROPU32 color;
+  CMeshEdVertex *tmpv,*va[3];
+
+  QueInit(&e->vertex_head);
+  QueInit(&e->tri_head);
+
+  e->vertex_cnt  =*src(I32 *)++;
+  e->tri_cnt=*src(I32 *)++;
+  for (i=0;i<e->vertex_cnt;i++) {
+    x=*src(I32 *)++;
+    y=*src(I32 *)++;
+    z=*src(I32 *)++;
+    tmpv=MeshVertexNew(e,x,y,z);
+    tmpv->num=i;
+  }
+  for (i=0;i<e->tri_cnt;i++) {
+    color=*src(I32 *)++;
+    for (j=0;j<3;j++)
+      va[j]=MeshVertexFindNum(e,*src(I32 *)++);
+    MeshTriNew(e,color,va[0],va[1],va[2]);
+  }
+}
+
+I64 MeshSize(CMeshFrame *e)
+{
+  I64 i;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  CMeshEdTri    *tmpt=e->tri_head.next;
+
+  e->vertex_cnt=0;
+  while (tmpv!=&e->vertex_head) {
+    tmpv->num=e->vertex_cnt++;
+    tmpv=tmpv->next;
+  }
+
+  e->tri_cnt=0;
+  while (tmpt!=&e->tri_head) {
+    e->tri_cnt++;
+    for (i=0;i<3;i++)
+      tmpt->mt.nums[i]=tmpt->t[i]->num;
+    tmpt=tmpt->next;
+  }
+  return sizeof(I32)*2+
+        (offset(CMeshEdVertex.end)-offset(CMeshEdVertex.start))*e->vertex_cnt+
+        (offset(CMeshEdTri.end)-offset(CMeshEdTri.start))*e->tri_cnt;
+}
+
+I32 *MeshSave(CMeshFrame *e,I64 *_size=NULL)
+{
+  I64 size=MeshSize(e);
+  U8 *res=MAlloc(size),*dst=res;
+  CMeshEdVertex *tmpv=e->vertex_head.next;
+  CMeshEdTri    *tmpt=e->tri_head.next;
+
+  *dst(I32 *)++=e->vertex_cnt;
+  *dst(I32 *)++=e->tri_cnt;
+
+  e->vertex_cnt=0;
+  while (tmpv!=&e->vertex_head) {
+    MemCpy(dst,&tmpv->start,offset(CMeshEdVertex.end)
+    -offset(CMeshEdVertex.start));
+    dst+=offset(CMeshEdVertex.end)-offset(CMeshEdVertex.start);
+    tmpv=tmpv->next;
+  }
+
+  e->tri_cnt=0;
+  while (tmpt!=&e->tri_head) {
+    MemCpy(dst,&tmpt->start,offset(CMeshEdTri.end)-offset(CMeshEdTri.start));
+    dst+=offset(CMeshEdTri.end)-offset(CMeshEdTri.start);
+    tmpt=tmpt->next;
+  }
+  if (_size) *_size=size;
+  return res;
+}
+
+U0 MeshCleanUp(CMeshFrame *e)
+{
+  QueDel(&e->vertex_head,TRUE);
+  QueDel(&e->tri_head,TRUE);
+  Free(e->w2s);
+  Free(e->s2w);
+}
+
+U0 MeshUpdateMenu(CMeshFrame *e)
+{
+  CMenuEntry *tmpse;
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Grid"))
+    tmpse->checked=ToBool(e->grid_on);
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Vertex"))
+    tmpse->checked=ToBool(e->vertex_on);
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/PlaceVertex"))
+    tmpse->checked=ToBool(e->ed_mode=='v');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/MoveVertex"))
+    tmpse->checked=ToBool(e->ed_mode=='m');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/MoveVertexZ"))
+    tmpse->checked=ToBool(e->ed_mode=='M');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Triangle"))
+    tmpse->checked=ToBool(e->ed_mode=='t');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Polygon"))
+    tmpse->checked=ToBool(e->ed_mode=='n');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Fence"))
+    tmpse->checked=ToBool(e->ed_mode=='f');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Mode/Prism"))
+    tmpse->checked=ToBool(e->ed_mode=='p');
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/FlipY"))
+    tmpse->checked=ToBool(e->flip_y);
+}
+
+I32 *SpriteMeshEd(I32 *head=NULL,I64 *_size=NULL,Bool flip_y=FALSE)
+{/*Fmt for mesh:
+{
+I32 vertex_cnt;
+I32 tri_cnt;
+CD3I32 vertices[];
+CMeshTri tris[];
+}
+
+If head points to a mesh, it will load it.
+
+Returns a newly malloced mesh or NULL.
+
+See ::/Demo/Graphics/SpritePlot3D.HC.
+*/
+  CCtrl *c=CtrlFindUnique(Fs,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s,*old_s;
+  I64 i,msg_code,sel_mode,arg1,arg2,make_tri_vertex_num=0,x,y,z;
+  CD3I32 p0a,p0b;
+  CMeshEdVertex *va[3],*tmpv;
+  Bool adjusting_z=FALSE,moving,save_and_exit;
+  CMeshFrame e;
+
+  if (c) {
+    old_s=MAlloc(sizeof(CViewAngles));
+    MemCpy(old_s,c->state,sizeof(CViewAngles));
+  } else {
+    c=ViewAnglesNew;
+    old_s=NULL;
+  }
+
+  s=c->state;
+  s->sx=0;
+  s->sy=0;
+  s->sz=0;
+  s->cx=YELLOW;
+  s->cy=RED;
+  s->cz=GREEN;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  Delete(,,SC_DELETE);"
+        "  DelLast(,CH_BACKSPACE);"
+        "  Cut(,CH_CTRLX);"
+        "  Copy(,CH_CTRLC);"
+        "  Paste(,CH_CTRLV);"
+        "  SelectAll(,'A');"
+        "  UnSelectAll(,'U');"
+        "  SelectRect(,'a');"
+        "  UnSelectRect(,'u');"
+        "  OrSelectRect(,'o');"
+        "  JumpToZ(,'j');"
+        "  ResetColor(,'C');"
+        "  ReverseTri(,'r');"
+        "}"
+        "Mode {"
+        "  PlaceVertex(,'v');"
+        "  MoveVertex(,'m');"
+        "  MoveVertexZ(,'M');"
+        "  Triangle(,'t');"
+        "  Polygon(,'n');"
+        "  Fence(,'f');"
+        "  Prism(,'p');"
+        "}"
+        "Settings {"
+        "  Color(,'c');"
+        "  Snap(,'s');"
+        "}"
+        "View {"
+        "  ZoomIn(,'z');"
+        "  ZoomOut(,'Z');"
+        "  NullAngles(,'N');"
+        "  FlipY(,'y');"
+        "  Grid(,'g');"
+        "  Vertex(,'V');"
+        "  ToggleBorder(,CH_CTRLB);"
+        "}"
+        "Transforms {"
+        "  Transform(,'T');"
+        "  SwapXY(,'1');"
+        "  SwapXZ(,'2');"
+        "  SwapYZ(,'3');"
+        "  InvertX(,'4');"
+        "  InvertY(,'5');"
+        "  InvertZ(,'6');"
+        "  ReverseTri(,'R');"
+        "}");
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  RegOneTimePopUp(ARf_MESH_ED,
+        "$GREEN$Right Mouse$FG$: Hold and move to shift cursor z\n"
+        "$GREEN$'j'$FG$: Jump cursor Z to nearest vertex's Z\n"
+        "$GREEN$'v'$FG$: Place Vertex Mode\n"
+        "$GREEN$'m'$FG$: Move Vertex Mode\n"
+        "$GREEN$'M'$FG$: Move Vertex Z\n"
+        "$GREEN$'t'$FG$: Form Triangle Mode\n"
+        "$GREEN$'n'$FG$: Polygon Mode\n"
+        "$GREEN$'f'$FG$: Fence Mode\n"
+        "$GREEN$'p'$FG$: Prism Mode\n"
+        "$GREEN$'c'$FG$: Set color\n"
+        "$GREEN$'s'$FG$: Set snap\n"
+        "\nSee menu at top of scrn for more.\n");
+
+  Fs->win_inhibit=WIG_TASK_DFT|WIF_SELF_DOC-WIF_SELF_FOCUS-WIF_SELF_BORDER
+        -WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU-WIF_SELF_GRAB_SCROLL;
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+  MeshInit(&e,flip_y);
+  if (head)
+    MeshLoad(&e,head);
+  FramePtrAdd("CMeshFrame",&e);
+  Fs->draw_it=&DrawIt;
+  MeshCurSnap(&e);
+  MeshRecalcCxCy(Fs,&e);
+
+  try {//In case of <CTRL-ALT-c>
+    while (TRUE) {
+      MeshUpdateMenu(&e);
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|
+            1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP);
+me_restart:
+      switch (msg_code) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case 0:
+              switch (arg2.u8[0]) {
+                case SC_DELETE:
+                  if (arg2&SCF_SHIFT)
+                    goto me_clip_cut;
+                  else {
+                    if (MeshSelCnt(&e))
+                      MeshClipDel(&e);
+                    else if (e.ed_mode!='t')
+                      MeshVertexDel(&e,MeshVertexFindScrPt(&e,
+                            ms.presnap.x-Fs->pix_left-Fs->scroll_x,
+                            ms.presnap.y-Fs->pix_top-Fs->scroll_y));
+                    MeshVertexSelAll(&e,FALSE);
+                    MeshTriSelAll(&e,FALSE);
+                    make_tri_vertex_num=0;
+                  }
+                  break;
+                case SC_INS:
+                  if (arg2&SCF_CTRL)
+                    goto me_clip_copy;
+                  else if (arg2&SCF_SHIFT)
+                    goto me_clip_paste;
+              }
+              break;
+            case CH_BACKSPACE:
+              switch (e.ed_mode) {
+                case 'n':
+                case 'f':
+                case 'p':
+                case 'v':
+                  MeshVertexDel(&e,e.cur_vertex);
+                  break;
+                case 't':
+                  if (make_tri_vertex_num) {
+                    MeshVertexSelAll(&e,FALSE);
+                    MeshTriSelAll(&e,FALSE);
+                    make_tri_vertex_num=0;
+                  } else
+                    MeshTriDel(&e,e.cur_tri);
+                  break;
+              }
+              break;
+            case 'f':
+            case 'p':
+              e.thickness=PopUpGetI64("Thickness (%d):",e.thickness);
+            case 'n':
+              if (arg1=='n' || arg1=='p')
+                e.closed=TRUE;
+              else
+                e.closed=PopUpNoYes("Closed?\n");
+me_chain:
+              e.chain_pred=e.vertex_head.last;
+            case 't':
+              MeshVertexSelAll(&e,FALSE);
+              MeshTriSelAll(&e,FALSE);
+            case 'v':
+            case 'm':
+            case 'M':
+              adjusting_z=FALSE;
+              moving=FALSE;
+              e.ed_mode=arg1;
+              make_tri_vertex_num=0;
+              Snd;
+              break;
+            case 'T':
+              MeshTransformSel(&e);
+              break;
+            case 'A':
+              MeshTriSelAll(&e,TRUE);
+              if (e.ed_mode!='t')
+                MeshVertexSelAll(&e,TRUE);
+              else
+                MeshVertexSelAll(&e,FALSE);
+              make_tri_vertex_num=0;
+              break;
+            case 'U':
+              MeshTriSelAll(&e,FALSE);
+              MeshVertexSelAll(&e,FALSE);
+              make_tri_vertex_num=0;
+              break;
+            case 'a':
+            case 'u':
+            case 'o':
+              if (arg1=='a')
+                sel_mode=SEL_MESH_EQU;
+              else if (arg1=='u')
+                sel_mode=SEL_MESH_AND;
+              else
+                sel_mode=SEL_MESH_OR;
+              if ((msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|
+                    1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP))
+                    !=MSG_MS_L_DOWN) {
+                Beep; Beep;
+                goto me_restart;
+              }
+              e.x1=arg1; e.y1=arg2;
+              e.x2=arg1; e.y2=arg2;
+              e.sel_rect=TRUE;
+              while (TRUE) {
+                msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN|
+                      1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|
+                      1<<MSG_MS_R_UP);
+                if (msg_code==MSG_MS_MOVE) {
+                  e.x2=arg1; e.y2=arg2;
+                } else if (msg_code==MSG_MS_L_UP) {
+                  e.x2=arg1; e.y2=arg2;
+                  break;
+                } else {
+                  e.sel_rect=FALSE;
+                  Beep; Beep;
+                  goto me_restart;
+                }
+              }
+              e.sel_rect=FALSE;
+              MeshTriSelRect(&e,sel_mode,e.x1,e.x2,e.y1,e.y2);
+              if (e.ed_mode!='t')
+                MeshVertexSelRect(&e,sel_mode,e.x1,e.x2,e.y1,e.y2);
+              else
+                MeshVertexSelAll(&e,FALSE);
+              make_tri_vertex_num=0;
+              break;
+            case CH_CTRLB:
+              WinBorder(Bt(&Fs->display_flags,DISPLAYf_NO_BORDER));
+              break;
+            case CH_CTRLC:
+me_clip_copy:
+              if (e.ed_mode=='t') {
+                Beep;Beep;
+              } else
+                MeshClipCopy(&e);
+              break;
+            case CH_CTRLV:
+me_clip_paste:
+              if (e.ed_mode=='t') {
+                Beep;Beep;
+              } else {
+                MeshClipPaste(&e);
+                e.ed_mode='m';
+              }
+              break;
+            case CH_CTRLX:
+me_clip_cut:
+              if (e.ed_mode=='t') {
+                Beep;Beep;
+              } else
+                MeshClipCut(&e);
+              break;
+            case CH_SHIFT_ESC:
+              save_and_exit=FALSE;
+              goto me_done;
+            case CH_ESC:
+              save_and_exit=TRUE;
+              goto me_done;
+            case 'z':
+              MeshScaleZoom(&e,1.5);
+              break;
+            case 'Z':
+              MeshScaleZoom(&e,1/1.5);
+              break;
+            case 'c':
+              e.cur_color=PopUpColorLighting;
+              break;
+            case 's':
+              i=PopUpRangeI64(1,25,1,"New Snap\n");
+              if (i>=1)
+                e.cur_snap=i;
+              MeshCurSnap(&e);
+              MeshRecalcCxCy(Fs,&e);
+              break;
+            case 'g':
+              e.grid_on=!e.grid_on;
+              break;
+            case 'V':
+              e.vertex_on=!e.vertex_on;
+              break;
+            case 'N':
+              s->sx=s->sy=s->sz=0;
+              break;
+            case 'y':
+              e.flip_y=!e.flip_y;
+              break;
+            case 'j':
+              if (moving)
+                MeshVertexIgnoreSet(&e,TRUE);
+              if (tmpv=MeshVertexFindScrPt(&e,
+                    ms.pos.x-Fs->pix_left-Fs->scroll_x,
+                    ms.pos.y-Fs->pix_top-Fs->scroll_y)) {
+                Noise(25,86,110);
+                e.ms_z=RoundI64(tmpv->p.z,e.cur_snap);
+              } else {
+                Beep; Beep;
+                e.ms_z=0;
+              }
+              MeshVertexIgnoreSet(&e,FALSE);
+              if (moving) {
+                MeshCursorW(&e,Fs,&x,&y,&z);
+                if (adjusting_z)
+                  MeshP0Offset(&e,0,0,z-p0a.z);
+                else
+                  MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+                p0a.x=x;
+                p0a.y=y;
+                p0a.z=z;
+                MeshP0Capture(&e);
+              }
+              break;
+            case '1':
+              MeshSwapAxes(&e,offset(CD3I32.x),offset(CD3I32.y));
+              break;
+            case '2':
+              MeshSwapAxes(&e,offset(CD3I32.x),offset(CD3I32.z));
+              break;
+            case '3':
+              MeshSwapAxes(&e,offset(CD3I32.y),offset(CD3I32.z));
+              break;
+            case '4':
+              MeshInvertAxis(&e,offset(CD3I32.x));
+              break;
+            case '5':
+              MeshInvertAxis(&e,offset(CD3I32.y));
+              break;
+            case '6':
+              MeshInvertAxis(&e,offset(CD3I32.z));
+              break;
+            case 'r':
+              if (e.cur_tri)
+                SwapI64(&e.cur_tri->t[1],&e.cur_tri->t[2]);
+              break;
+            case 'C':
+              MeshColorTris(&e);
+              break;
+            case 'R':
+              MeshRevTris(&e);
+              break;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          switch (e.ed_mode) {
+            case 'm':
+              if (!moving) {
+                if (!MeshSelCnt(&e) &&
+                      (tmpv=MeshVertexFindScrPt(&e,arg1,arg2))) {
+                  tmpv->flags|=VF_SEL;
+                  e.ms_z=RoundI64(tmpv->p.z,e.cur_snap);
+                }
+                if (MeshSelCnt(&e)) {
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  p0a.x=x;
+                  p0a.y=y;
+                  p0a.z=z;
+                  MeshP0Capture(&e);
+                  moving=TRUE;
+                }
+              }
+              break;
+            case 'M':
+              if (!adjusting_z && !moving) {
+                if (!MeshSelCnt(&e) &&
+                      (tmpv=MeshVertexFindScrPt(&e,arg1,arg2))) {
+                  tmpv->flags|=VF_SEL;
+                  e.ms_z=RoundI64(tmpv->p.z,e.cur_snap);
+                }
+                if (MeshSelCnt(&e)) {
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  p0a.x=x;
+                  p0a.y=y;
+                  p0a.z=z;
+                  MeshP0Capture(&e);
+                  moving=TRUE;
+
+                  p0b.x=ms.presnap.x;
+                  p0b.y=ms.presnap.y;
+                  p0b.z=e.ms_z;
+                  adjusting_z=TRUE;
+                  Snd(ClampI64(Freq2Ona(3*e.ms_z+1500),0,I8_MAX));
+                }
+              }
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (e.ed_mode) {
+            case 'n':
+            case 'f':
+            case 'p':
+            case 'v':
+              Noise(25,86,110);
+              MeshCursorW(&e,Fs,&x,&y,&z);
+              e.cur_vertex=MeshVertexNew(&e,x,y,z);
+              break;
+            case 'm':
+            case 'M':
+              if (moving) {
+                if (adjusting_z) {
+                  e.ms_z=RoundI64(Sign(p0b.y-ms.presnap.y)
+                  *Sqrt(Sqr(p0b.x-ms.presnap.x)+Sqr(p0b.y-ms.presnap.y))
+                  +p0b.z,e.cur_snap);
+                  Snd;
+                  adjusting_z=FALSE;
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  MeshP0Offset(&e,0,0,z-p0a.z);
+                } else {
+                  MeshCursorW(&e,Fs,&x,&y,&z);
+                  MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+                }
+                MeshTriSelAll(&e,FALSE);
+                MeshVertexSelAll(&e,FALSE);
+                moving=FALSE;
+              }
+              break;
+            case 't':
+              if (tmpv=MeshVertexFindScrPt(&e,arg1,arg2)) {
+                for (i=0;i<make_tri_vertex_num;i++)
+                  if (va[i]==tmpv) {
+                    Beep; Beep;
+                    break;
+                  }
+                if (i==make_tri_vertex_num) {
+                  Noise(25,86,110);
+                  va[make_tri_vertex_num++]=tmpv;
+                  tmpv->flags|=VF_SEL;
+                  if (make_tri_vertex_num==3) {
+                    e.cur_tri=MeshTriNew(&e,e.cur_color,va[0],va[1],va[2]);
+                    for (i=0;i<make_tri_vertex_num;i++)
+                      va[i]->flags&=~VF_SEL;
+                    make_tri_vertex_num=0;
+                  }
+                }
+              }
+              break;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+          if (!adjusting_z && e.ed_mode!='M' &&
+                (e.chain_pred==e.vertex_head.last ||
+                e.ed_mode!='n' && e.ed_mode!='f' && e.ed_mode!='p')) {
+            if (moving) {
+              MeshCursorW(&e,Fs,&x,&y,&z);
+              MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+              p0a.x=x;
+              p0a.y=y;
+              p0a.z=z;
+              MeshP0Capture(&e);
+            }
+            p0b.x=ms.presnap.x;
+            p0b.y=ms.presnap.y;
+            p0b.z=e.ms_z;
+            adjusting_z=TRUE;
+            Snd(ClampI64(Freq2Ona(3*e.ms_z+1500),0,I8_MAX));
+          }
+          break;
+        case MSG_MS_R_UP:
+          if (adjusting_z) {
+            e.ms_z=RoundI64(Sign(p0b.y-ms.presnap.y)
+            *Sqrt(Sqr(p0b.x-ms.presnap.x)+Sqr(p0b.y-ms.presnap.y))
+            +p0b.z,e.cur_snap);
+            Snd;
+            adjusting_z=FALSE;
+            if (moving) {
+              MeshCursorW(&e,Fs,&x,&y,&z);
+              MeshP0Offset(&e,0,0,z-p0a.z);
+              p0a.x=x;
+              p0a.y=y;
+              p0a.z=z;
+              MeshP0Capture(&e);
+            }
+          } else  if (e.ed_mode=='n') {
+            if (e.chain_pred && e.chain_pred!=e.vertex_head.last)
+              MeshPolygon(&e,e.chain_pred->next,e.vertex_head.last,FALSE);
+            arg1=e.ed_mode;
+            goto me_chain;
+          } else if (e.ed_mode=='f') {
+            if (e.chain_pred && e.chain_pred!=e.vertex_head.last)
+              MeshFence(&e);
+            arg1=e.ed_mode;
+            goto me_chain;
+          } else if (e.ed_mode=='p') {
+            if (e.chain_pred && e.chain_pred!=e.vertex_head.last)
+              MeshPrism(&e);
+            arg1=e.ed_mode;
+            goto me_chain;
+          }
+          break;
+        case MSG_MS_MOVE:
+          if (adjusting_z) {
+            e.ms_z=RoundI64(Sign(p0b.y-ms.presnap.y)
+            *Sqrt(Sqr(p0b.x-ms.presnap.x)+Sqr(p0b.y-ms.presnap.y))
+            +p0b.z,e.cur_snap);
+            Snd(ClampI64(Freq2Ona(3*e.ms_z+1500),0,I8_MAX));
+          }
+          if (moving) {
+            MeshCursorW(&e,Fs,&x,&y,&z);
+            if (adjusting_z)
+              MeshP0Offset(&e,0,0,z-p0a.z);
+            else
+              MeshP0Offset(&e,x-p0a.x,y-p0a.y,z-p0a.z);
+            p0a.x=x;
+            p0a.y=y;
+            p0a.z=z;
+            MeshP0Capture(&e);
+          }
+          break;
+      }
+    }
+me_done:
+  } catch
+    Fs->catch_except=TRUE;
+  SettingsPop;
+  MenuPop;
+  if (save_and_exit)
+    head=MeshSave(&e,_size);
+  else
+    head=NULL;
+  MeshCleanUp(&e);
+  FramePtrDel("CMeshFrame");
+  if (old_s) {
+    MemCpy(c->state,old_s,sizeof(CViewAngles));
+    Free(old_s);
+  } else
+    ViewAnglesDel;
+  return head;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/SpriteNew.HC.HTML b/public/Wb/Home/Src/Adam/Gr/SpriteNew.HC.HTML new file mode 100755 index 0000000..c75aad5 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/SpriteNew.HC.HTML @@ -0,0 +1,220 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+#help_file "::/Doc/Sprite"
+
+U8 polypt_map[9]={0,1,2,3,0,4,5,6,7};
+
+I64 sprite_elem_base_sizes[SPT_TYPES_NUM]={
+  sizeof(CSpriteBase),          //SPT_END
+  sizeof(CSpriteColor),         //SPT_COLOR
+  sizeof(CSpriteDitherColor),   //SPT_DITHER_COLOR
+  sizeof(CSpriteT),             //SPT_THICK
+  sizeof(CSpritePtPt),          //SPT_PLANAR_SYMMETRY
+  sizeof(CSpriteBase),          //SPT_TRANSFORM_ON
+  sizeof(CSpriteBase),          //SPT_TRANSFORM_OFF
+  sizeof(CSpritePt),            //SPT_SHIFT
+  sizeof(CSpritePt),            //SPT_PT
+  sizeof(CSpriteNumPtU8s),      //SPT_POLYPT
+  sizeof(CSpritePtPt),          //SPT_LINE
+  sizeof(CSpriteNumU8s),        //SPT_POLYLINE
+  sizeof(CSpritePtPt),          //SPT_RECT
+  sizeof(CSpritePtPtAng),       //SPT_ROTATED_RECT
+  sizeof(CSpritePtRad),         //SPT_CIRCLE
+  sizeof(CSpritePtWHAng),       //SPT_ELLIPSE
+  sizeof(CSpritePtWHAngSides),  //SPT_POLYGON
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE2
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE2_CLOSED
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE3
+  sizeof(CSpriteNumU8s),        //SPT_BSPLINE3_CLOSED
+  sizeof(CSpritePt),            //SPT_FLOOD_FILL
+  sizeof(CSpritePt),            //SPT_FLOOD_FILL_NOT
+  sizeof(CSpritePtWHU8s),       //SPT_BITMAP
+  sizeof(CSpriteMeshU8s),       //SPT_MESH
+  sizeof(CSpritePtMeshU8s),     //SPT_SHIFTABLE_MESH
+  sizeof(CSpritePtPt),          //SPT_ARROW
+  sizeof(CSpritePtStr),         //SPT_TEXT
+  sizeof(CSpritePtStr),         //SPT_TEXT_BOX
+  sizeof(CSpritePtStr),         //SPT_TEXT_DIAMOND
+};
+
+I64 SpriteElemQuedBaseSize(I64 type)
+{
+  return sprite_elem_base_sizes[type&SPG_TYPE_MASK]+offset(CSprite.start);
+}
+
+I64 SpriteElemSize(CSprite *tmpg)
+{
+  I64 i=sprite_elem_base_sizes[tmpg->type&SPG_TYPE_MASK];
+  switch (tmpg->type&SPG_TYPE_MASK) {
+    case SPT_POLYLINE:
+      i+=tmpg->nu.num*sizeof(CD2I32);
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      i+=StrLen(tmpg->ps.st)+1;
+      break;
+    case SPT_BITMAP:
+      i+=((tmpg->pwhu.width+7)&~7)*tmpg->pwhu.height;
+      break;
+    case SPT_POLYPT:
+      i+=(tmpg->npu.num*3+7)>>3;
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      i+=tmpg->nu.num*sizeof(CD3I32);
+      break;
+    case SPT_MESH:
+      i+=tmpg->mu.vertex_cnt*sizeof(CD3I32)+
+            tmpg->mu.tri_cnt*sizeof(CMeshTri);
+      break;
+    case SPT_SHIFTABLE_MESH:
+      i+=tmpg->pmu.vertex_cnt*sizeof(CD3I32)+
+            tmpg->pmu.tri_cnt*sizeof(CMeshTri);
+      break;
+  }
+  return i;
+}
+
+public I64 SpriteSize(U8 *elems)
+{//Walk sprite elements and return size of sprite as binary data.
+  CSprite *tmpg=elems-offset(CSprite.start),*tmpg1=tmpg;
+  while (tmpg->type&SPG_TYPE_MASK)
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  return tmpg(U8 *)-tmpg1(U8 *)+sprite_elem_base_sizes[SPT_END];
+}
+
+I64 SpriteTypeMask(U8 *elems)
+{
+  I64 res=0;
+  CSprite *tmpg=elems-offset(CSprite.start);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    if (tmpg->type&SPG_TYPE_MASK>=SPT_TYPES_NUM)
+      return 1<<SPT_TYPES_NUM;
+    Bts(&res,tmpg->type&SPG_TYPE_MASK);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+  return res;
+}
+
+U0 SpriteSelAll(U8 *elems,Bool val)
+{
+  CSprite *tmpg=elems-offset(CSprite.start);
+  while (tmpg->type&SPG_TYPE_MASK) {
+    BEqu(&tmpg->type,SPf_SEL,val);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+}
+
+public U8 *DC2Sprite(CDC *tmpb)
+{//Convert device context to sprite.
+  CSprite *tmpg;
+  tmpg=CAlloc(sprite_elem_base_sizes[SPT_BITMAP]+
+        tmpb->width_internal*tmpb->height+
+        sprite_elem_base_sizes[SPT_END])
+  (U8 *)-offset(CSprite.start);
+  tmpg->type=SPT_BITMAP;
+  tmpg->pwhu.width=tmpb->width;
+  tmpg->pwhu.height=tmpb->height;
+  tmpg->pwhu.x1=0;
+  tmpg->pwhu.y1=0;
+  MemCpy(&tmpg->pwhu.u,tmpb->body,tmpb->width_internal*tmpb->height);
+  return tmpg(U8 *)+offset(CSprite.start);
+}
+
+public U8 *SpriteElem2Summary(CSprite *tmpg)
+{//Study ::/Demo/Graphics/SpriteText.HC.
+  U8 buf[STR_LEN],buf2[STR_LEN];
+  I32 *ptr;
+  StrPrint(buf,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_TYPES");
+  switch (tmpg->type&SPG_TYPE_MASK) {
+    case SPT_COLOR:
+      CatPrint(buf," %s",Color2Str(buf2,tmpg->c.color));
+      break;
+    case SPT_DITHER_COLOR:
+      CatPrint(buf," %s",Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
+            tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
+      break;
+    case SPT_PT:
+    case SPT_FLOOD_FILL:
+    case SPT_FLOOD_FILL_NOT:
+    case SPT_SHIFT:
+      CatPrint(buf," (%d,%d)",tmpg->p.x1,tmpg->p.y1);
+      break;
+    case SPT_LINE:
+    case SPT_ARROW:
+    case SPT_PLANAR_SYMMETRY:
+    case SPT_RECT:
+    case SPT_ROTATED_RECT:
+      CatPrint(buf," (%d,%d),(%d,%d)",tmpg->pp.x1,tmpg->pp.y1,
+            tmpg->pp.x2,tmpg->pp.y2);
+      break;
+    case SPT_CIRCLE:
+      CatPrint(buf," (%d,%d):%dR",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
+      break;
+    case SPT_THICK:
+      CatPrint(buf," %d",tmpg->t.thick);
+      break;
+    case SPT_TEXT:
+    case SPT_TEXT_BOX:
+    case SPT_TEXT_DIAMOND:
+      CatPrint(buf," %d,%d:%-16t$Q",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
+      break;
+    case SPT_POLYLINE:
+    case SPT_POLYPT:
+      ptr=&tmpg->npu.x;
+      CatPrint(buf," %d (%d,%d)",tmpg->npu.num,ptr[0],ptr[1]);
+      break;
+    case SPT_ELLIPSE:
+    case SPT_POLYGON:
+    case SPT_BITMAP:
+      CatPrint(buf," (%d,%d):%dW,%dH",tmpg->pwhu.x1,tmpg->pwhu.y1,
+            tmpg->pwhu.width,tmpg->pwhu.height);
+      break;
+    case SPT_BSPLINE2:
+    case SPT_BSPLINE3:
+    case SPT_BSPLINE2_CLOSED:
+    case SPT_BSPLINE3_CLOSED:
+      CatPrint(buf," %d",tmpg->nu.num);
+      break;
+    case SPT_MESH:
+      CatPrint(buf," %dV,%dT",tmpg->mu.vertex_cnt,tmpg->mu.tri_cnt);
+      break;
+    case SPT_SHIFTABLE_MESH:
+      CatPrint(buf," %dV,%dT",tmpg->pmu.vertex_cnt,tmpg->pmu.tri_cnt);
+      break;
+  }
+  return StrNew(buf);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Gr/SpriteSideBar.HC.HTML b/public/Wb/Home/Src/Adam/Gr/SpriteSideBar.HC.HTML new file mode 100755 index 0000000..e2b8da3 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Gr/SpriteSideBar.HC.HTML @@ -0,0 +1,126 @@ + + + + + + + + + + + +
+#help_index "Graphics/Sprite;Sprites"
+
+CSprite *SpriteSideBar2SpriteQue(CDoc *doc,CSprite *head,I64 *_cur_elem_num)
+{//For the side-bar
+  CSprite *res=CAlloc(sizeof(CSprite)),*tmpg;
+  CDocEntry *doc_e=doc->head.next;
+  Bool found=FALSE;
+  I64 num=0;
+  QueInit(res);
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_MENU_VAL && doc_e->left_exp>=0) {
+      tmpg=SpriteSetSettings(,head,doc_e->left_exp);
+      if (tmpg!=head) {
+        tmpg=MAllocIdent(tmpg);
+        BEqu(&tmpg->type,SPf_SEL,Bt(&doc_e->type,DOCEt_SEL));
+        if (*_cur_elem_num==doc_e->left_exp) {
+          *_cur_elem_num=num;
+          found=TRUE;
+        }
+        QueIns(tmpg,res->last);
+        num++;
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  if (!found)
+    *_cur_elem_num=num;
+  QueDel(head);
+  Free(head);
+  return res;
+}
+
+U0 SpriteSideBarPickNew(CDoc *doc,CSprite *head,I64 old_num)
+{
+  CSprite *tmpg;
+  CDocEntry *doc_cur_e=NULL,*doc_e;
+  I64 cur_elem_num=0;
+  U8 *st;
+  DocPrint(doc,"$PURPLE$$TX+CX,\"Sprite SideBar\"$\n"
+        "$LK+PU+CX,\"Click for Help\","
+        "A=\"FI:::/Doc/SpriteSideBar.DD.Z\"$\n\n");
+  tmpg=head->next;
+  while (tmpg!=head) {
+    st=SpriteElem2Summary(tmpg);
+    if (cur_elem_num==old_num)
+      doc_cur_e=doc_e=
+            DocPrint(doc,"$LTRED$$MU-UL,\"%$Q\",LE=%d$\n",st,cur_elem_num++);
+    else
+      doc_e=DocPrint(doc,"$LTBLUE$$MU-UL,\"%$Q\",LE=%d$\n",st,cur_elem_num++);
+    BEqu(&doc_e->de_flags,DOCEf_SEL,Bt(&tmpg->type,&SPf_SEL));
+    BEqu(&doc_e->type,DOCEt_SEL,Bt(&tmpg->type,SPf_SEL));
+    Free(st);
+    tmpg=tmpg->next;
+  }
+  if (cur_elem_num==old_num)
+    doc_cur_e=DocPrint(doc,"$LTRED$$MU-UL,\"END\",LE=%d$\n",cur_elem_num);
+  else
+    DocPrint(doc,"$LTBLUE$$MU-UL,\"END\",LE=%d$\n",cur_elem_num);
+  if (doc_cur_e)
+    doc->cur_entry=doc_cur_e;
+}
+
+U0 SpriteSideBarTask2(CTask *grand_parent)
+{
+  I64 w,h;
+  CTask *parent=Fs->parent_task,*pu_task;
+  while (TRUE) {
+    pu_task=grand_parent->popup_task;
+    if (TaskValidate(pu_task)) {
+      w=parent->win_right-parent->win_left;
+      WinHorz(pu_task->win_right+2,pu_task->win_right+2+w,parent);
+      h=parent->win_bottom-parent->win_top;
+      WinVert(pu_task->win_top,pu_task->win_top+h,parent);
+    }
+    Refresh;
+  }
+}
+
+U0 SpriteSideBarTask(CTask *parent,CSprite **_head,I64 *_cur_elem_num)
+{
+  CDocEntry *doc_e;
+  CDoc *doc=DocPut;
+  Spawn(&SpriteSideBarTask2,parent,"CSpriteTask",,Fs);
+  doc->flags|=DOCF_SIZE_MIN|DOCF_FORM;
+  while (TRUE) {
+    SpriteSideBarPickNew(doc,*_head,*_cur_elem_num);
+    DocHighlightCursor(,doc);
+    View;
+    doc_e=doc->cur_entry;
+    if (doc_e->type_u8==DOCT_MENU_VAL)
+      *_cur_elem_num=doc_e->left_exp;
+    *_head=SpriteSideBar2SpriteQue(doc,*_head,_cur_elem_num);
+    DocClear(doc);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Host.HC.HTML b/public/Wb/Home/Src/Adam/Host.HC.HTML new file mode 100755 index 0000000..f3a7e15 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Host.HC.HTML @@ -0,0 +1,101 @@ + + + + + + + + + + + +
+#help_index "Misc/Host"
+
+public Bool HostChgDsk(U8 *iso_filename)
+{//Help user change CD/DVD or ISO_file.
+  Bool res=FALSE;
+  SettingsPush; //See SettingsPush
+  try {
+    AutoComplete;
+    WinBorder;
+    WinMax;
+    DocClear;
+    "$PURPLE$$TX+CX,\"Set to %s\"$$FG$\n\n\n\n",iso_filename;
+    switch (ins_reg.host_vm) {
+      case VM_VMWARE:
+        if (IsDotC(iso_filename))
+"
+Click CDROM Icon in bottom-right border of VMware window.
+
+Click \"Settings\".
+
+Set ISO image to \"%s\".
+When browsing, change the file mask from \"*.iso\" to \"All Files\".
+
+",iso_filename;
+          else
+"
+Click CDROM Icon in bottom-right border of VMware window.
+
+Click \"Settings\".
+
+Set ISO image to \"%s\".
+
+",iso_filename;
+        break;
+      case VM_QEMU:
+"
+Change to QEMU monitor using <CTRL-ALT-2>
+
+Get the CDROM designation.
+
+        >info block
+
+Use the designation.
+
+        >eject ide1-cd0
+
+Use the designation.
+
+        >change ide1-cd0 %s
+
+Change back to QEMU using <CTRL-ALT-1>
+
+",iso_filename;
+        break;
+      default:
+"
+Place the CDDVD %s in the drive.
+
+",iso_filename;
+    }
+    if (PressAKey!=CH_SHIFT_ESC) {
+      ">DskChg('T');\n\n";
+      DskChg('T');
+      res=TRUE;
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/InFile.HC.HTML b/public/Wb/Home/Src/Adam/InFile.HC.HTML new file mode 100755 index 0000000..c27c559 --- /dev/null +++ b/public/Wb/Home/Src/Adam/InFile.HC.HTML @@ -0,0 +1,171 @@ + + + + + + + + + + + +
+#help_index "InFile;Help System/Training"
+#help_file "::/Doc/InFile"
+
+public U0 InGetStr(U8 *st)
+{//Wait for user to type certain str.
+  I64 ch,sc;
+  U8 buf[256],*st2;
+  while (*st) {
+    ch=GetKey(&sc,FALSE);
+    if (sc.u8[0]!=SC_SHIFT &&
+          sc.u8[0]!=SC_ALT &&
+          sc.u8[0]!=SC_CTRL) {
+      if (ch==*st) {
+        '' ch;
+        st++;
+      } else {
+        st2=Char2KeyName(*st);
+        StrPrint(buf,"Press the $GREEN$<%s>$FG$ key.",st2);
+        Free(st2);
+        PopUpOk(buf);
+      }
+    }
+  }
+}
+
+public U0 InPrint(I64 mS=100,U8 *fmt,...)
+{//Print message with delay after each char.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=buf;
+  I64 ch;
+  while (ch=*st++) {
+    '' ch;
+    Sleep(mS);
+  }
+  Free(buf);
+}
+
+public U0 InGetKey(I64 scan_code,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
+{//Wait for user to press certain key.
+  I64 sc,ch;
+  U8 buf[STR_LEN],*st;
+  do {
+    ch=GetKey(&sc);
+    if (sc.u8[0]!=SC_PRTSCRN1 &&
+          !(sc.u8[0]==SC_SHIFT && scan_code&SCF_SHIFT) &&
+          !(sc.u8[0]==SC_CTRL && scan_code&SCF_CTRL) &&
+          !(sc.u8[0]==SC_ALT && scan_code&SCF_ALT) ) {
+      if (sc&sc_mask!=scan_code&sc_mask) {
+        st=ScanCode2KeyName(scan_code);
+        StrPrint(buf,"Press the $GREEN$<%s>$FG$ key",st);
+        Free(st);
+        PopUpOk(buf);
+      }
+    }
+  } while (sc&sc_mask!=scan_code&sc_mask);
+  Msg(MSG_KEY_DOWN,ch,sc);
+}
+
+public I64 InGetChar(...)
+{//Wait for user to press one of set of chars.
+  I64 i,sc,ch;
+  U8 buf[512],*st;
+  while (TRUE) {
+    ch=GetKey(&sc);
+    if (sc.u8[0]!=SC_SHIFT && sc.u8[0]!=SC_ALT && sc.u8[0]!=SC_CTRL) {
+      for (i=0;i<argc;i++)
+        if (ch==argv[i]) {
+          Msg(MSG_KEY_DOWN,ch,sc);
+          return ch;
+        }
+      StrPrint(buf,"Press ");
+      for (i=0;i<argc;i++) {
+        st=Char2KeyName(argv[i]);
+        CatPrint(buf,"$GREEN$<%s>$FG$",st);
+        Free(st);
+        if (argc==i+1)
+          CatPrint(buf,".");
+        else if (argc==i+2)
+          CatPrint(buf," or ");
+        else
+          CatPrint(buf,", ");
+      }
+      PopUpOk(buf);
+    }
+  }
+}
+
+public U0 InUntilKey(I64 scan_code,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
+{//Let user type until he presses certain key.
+  I64 sc,ch;
+  do {
+    ch=GetKey(&sc);
+    Msg(MSG_KEY_DOWN,ch,sc);
+  } while (sc&sc_mask!=scan_code&sc_mask);
+}
+
+public I64 InUntilChar(...)
+{//Let user type until he presses one of set of chars.
+  I64 i,sc,ch;
+  while (TRUE) {
+    ch=GetKey(&sc);
+    Msg(MSG_KEY_DOWN,ch,sc);
+    for (i=0;i<argc;i++)
+      if (ch==argv[i])
+        return ch;
+  }
+}
+
+public Bool InView()
+{//Let user type until <ESC> or <SHIFT-ESC>.
+  Bool res=View;
+  DocBottom;
+  return res;
+}
+
+#help_index "InFile;Help System/Training;Mouse"
+I64 in_plot_l,in_plot_r;
+
+Bool InSetMsPlot(I64 mS,I64 x,I64 y,I64 z)
+{
+  MsSet(x,y,z,in_plot_l,in_plot_r);
+  Sleep(mS);
+  return TRUE;
+}
+
+public U0 InSetMs(I64 mS=7,I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,
+                I64 l=I64_MAX,I64 r=I64_MAX)
+{//Move mouse to spot at certain speed.
+  if (!(0<=x<GR_WIDTH))
+    x=ms.pos.x;
+  if (!(0<=y<GR_HEIGHT))
+    y=ms.pos.y;
+  if (z==I64_MAX)
+    z=ms.pos.z;
+  if (!(FALSE<=l<=TRUE))
+    l=ms.lb;
+  if (!(FALSE<=r<=TRUE))
+    r=ms.rb;
+  in_plot_l=l; in_plot_r=r;
+  Line(mS,ms.pos.x,ms.pos.y,ms.pos.z,x,y,z,&InSetMsPlot);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/InsReg.HC.HTML b/public/Wb/Home/Src/Adam/InsReg.HC.HTML new file mode 100755 index 0000000..68c6212 --- /dev/null +++ b/public/Wb/Home/Src/Adam/InsReg.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+#help_index "Registry/Install Registration"
+
+public CInsReg ins_reg;
+MemSet(&ins_reg,0,sizeof(CInsReg));
+
+DefineLstLoad("ST_HOST_OSES","Other\0Native\0Linux\0Windows\0");
+DefineLstLoad("ST_HOST_VMS","Other\0Native\0VMware\0QEMU\0VirtualBox\0");
+
+#define RR_UNREGISTER   -1
+#define RR_REGISTER     0
+#define RR_REREGISTER   1
+
+public Bool InsReg(U8 drv_let=0,I64 action=RR_REGISTER)
+{//Register this install in local Registry.HC file.
+  CInsReg r;
+  I64 old_drv_let;
+  Bool res=FALSE;
+
+  if (action==RR_UNREGISTER) {
+    MemSet(&r,0,sizeof(CInsReg));
+    res=TRUE;
+  } else if (action==RR_REREGISTER || !ins_reg.registered) {
+    MemCpy(&r,&ins_reg,sizeof(CInsReg));
+    r.registered=TRUE;
+    if (PopUpForm(&r))
+      res=TRUE;
+  }
+
+  if (res) {
+    old_drv_let=*sys_registry_doc->filename.name;
+    if (drv_let)
+      *sys_registry_doc->filename.name=drv_let;
+    RegWrite("Adam/InsReg",
+        "#help_index \"Registry/Install Registration\"\n"
+        "MemSet(&ins_reg,0,sizeof(CInsReg));\n"
+        "ins_reg.registered=%d;\n"
+        "ins_reg.host_os=%d;\n"
+        "ins_reg.host_vm=%d;\n"
+        "\n#define INS_REG_PERSONAL_INITIALS \"%s\"\n"
+        "StrCpy(ins_reg.initials,\"%s\");\n"
+        "HashPublic(\"INS_REG_PERSONAL_INITIALS\",HTT_DEFINE_STR);\n"
+        "\n#define INS_REG_MACHINE_NUM %d\n"
+        "ins_reg.machine_num=%d;\n"
+        "HashPublic(\"INS_REG_MACHINE_NUM\",HTT_DEFINE_STR);\n"
+        "\n\"InsReg:%%s:%%d\\n\","
+        "INS_REG_PERSONAL_INITIALS,INS_REG_MACHINE_NUM;\n"
+        "\n#help_index \"\"\n"
+        ,r.registered,r.host_os,r.host_vm,
+        r.initials,r.initials,r.machine_num,r.machine_num);
+    *sys_registry_doc->filename.name=old_drv_let;
+    RegExe("Adam/InsReg");
+  }
+  return res;
+}
+
+public Bool InsRereg(U8 drv_let=0)
+{//Reregister this install in local Registry.HC file.
+  return InsReg(drv_let,RR_REREGISTER);
+}
+
+public Bool InsUnreg(U8 drv_let=0)
+{//Unregister this install in local Registry.HC file.
+  return InsReg(drv_let,RR_UNREGISTER);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/MakeAdam.HC.HTML b/public/Wb/Home/Src/Adam/MakeAdam.HC.HTML new file mode 100755 index 0000000..4f723a5 --- /dev/null +++ b/public/Wb/Home/Src/Adam/MakeAdam.HC.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "AExts"
+#include "AMath"
+#include "Training"
+#include "AMem"
+#include "TaskRep"
+#include "AMathODE"
+#include "Gr/MakeGr"
+#include "ASnd"
+#include "ABlkDev/MakeABlkDev"
+#include "Menu"
+#include "Win"
+#include "WinMgr"
+#include "ADbg"
+#include "::/Adam/God/GodExt"
+#include "DolDoc/MakeDoc"
+LBts(&sys_run_level,RLf_DOC);
+#include "Ctrls/MakeCtrls"
+#include "InFile"
+#include "ARegistry"
+#include "InsReg"
+#include "AutoComplete/MakeAC"
+#include "God/MakeGod"
+#include "AHash"
+#include "TaskSettings"
+#include "CPURep"
+#include "DevInfo"
+#include "ADefine"
+#include "WallPaper"
+#include "AMouse"
+#include "Host"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/Menu.HC.HTML b/public/Wb/Home/Src/Adam/Menu.HC.HTML new file mode 100755 index 0000000..678b30b --- /dev/null +++ b/public/Wb/Home/Src/Adam/Menu.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+#help_index "Menus"
+#help_file "::/Doc/Menus"
+
+CTask *MenuTask()
+{
+  CTask *res=sys_focus_task;
+  while (res && !res->cur_menu)
+    res=res->parent_task;
+  return res;
+}
+
+CMenuEntry *sys_cur_submenu_entry=NULL;
+
+public CMenuEntry *MenuSubEntryFind(
+        CMenuEntry *haystack_first,U8 *needle_entry_name)
+{//You probably don't need this. Use dir / and MenuEntryFind().
+  while (haystack_first) {
+    if (!StrCmp(haystack_first->name,needle_entry_name))
+      return haystack_first;
+    haystack_first=haystack_first->next;
+  }
+  return NULL;
+}
+
+public CMenuEntry *MenuEntryFind(CMenu *haystack_menu,U8 *needle_full_name)
+{//Find pulldown entry. Fs->cur_menu is probably the menu you want.
+//Just 2 levels -- across top and down are valid, currently.
+  U8 *st,*st2;
+  CMenuEntry *tmpse;
+  if (!haystack_menu || !needle_full_name)
+    return NULL;
+  st=StrNew(needle_full_name);
+  st2=StrNew(needle_full_name);
+  tmpse=(&haystack_menu->sub)(U8 *)-offset(CMenuEntry.sub);
+  while (*st && tmpse) {
+    StrFirstRem(st,"/",st2);
+    tmpse=MenuSubEntryFind(tmpse->sub,st2);
+  }
+  Free(st);
+  Free(st2);
+  return tmpse;
+}
+
+CMenuEntry *MenuNewSub(CCmpCtrl *cc,CTask *task)
+{
+  CMenuEntry *tmpme=NULL,*tmpse;
+  if (cc->token==TK_IDENT) {
+    tmpme=CAlloc(sizeof(CMenuEntry),task);
+    if (StrLen(cc->cur_str)>31)
+      cc->cur_str[31]=0;
+    StrCpy(tmpme->name,cc->cur_str);
+    if (Lex(cc)=='(') {
+      tmpme->msg_code=MSG_KEY_DOWN_UP;
+      if (Lex(cc)!=',' && cc->token!=')')
+        tmpme->msg_code=LexExpressionI64(cc);
+      if (cc->token==',')
+        Lex(cc);
+      if (cc->token!=',' && cc->token!=')')
+        tmpme->arg1=LexExpressionI64(cc);
+      if (cc->token==',')
+        Lex(cc);
+      if (cc->token!=',' && cc->token!=')')
+        tmpme->arg2=LexExpressionI64(cc);
+      if (cc->token!=')')
+        LexExcept(cc,"Missing ')' at ");
+      if (Lex(cc)!=';')
+        LexExcept(cc,"Missing ';' at");
+      Lex(cc); //Skip ;
+    } else if (cc->token=='{') {
+      Lex(cc); //Skip {
+      tmpme->dir=TRUE;
+      tmpse=&tmpme->sub;
+      while (tmpse && cc->token!='}')
+        tmpse=tmpse->next=MenuNewSub(cc,task);
+      if (cc->token!='}')
+        LexExcept(cc,"Missing '}' at ");
+      else
+        Lex(cc); //Skip }
+    } else
+      LexExcept(cc,"Expecting '{' at ");
+  }
+  return tmpme;
+}
+
+public CMenu *MenuNew(U8 *st,I64 flags=0,CTask *task=NULL)
+{//Parse a menu. You probably don't need this.
+  CMenu *m;
+  CMenuEntry *tmpse;
+  CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
+  if (!task) task=Fs;
+  Lex(cc);
+  m=CAlloc(sizeof(CMenu),task);
+  m->task=task;
+  m->flags=flags;
+  m->attr =BLUE<<4+YELLOW;
+  tmpse=&m->sub;
+  while (tmpse)
+    tmpse=tmpse->next=MenuNewSub(cc,task);
+  CmpCtrlDel(cc);
+  return m;
+}
+
+public CMenu *MenuFile(U8 *filename,I64 flags=0,CTask *task=NULL)
+{//Parse a pulldown menu file. You probably don't need this.
+  CMenu *m;
+  U8 *st=MStrPrint("#include \"%s\"",filename);
+  m=MenuNew(st,flags,task);
+  Free(st);
+  return m;
+}
+
+U0 MenuDelSub(CMenuEntry *tmpme)
+{
+  CMenuEntry *tmpse,*tmpse1;
+  if (tmpme) {
+    tmpse=tmpme->sub;
+    while (tmpse) {
+      tmpse1=tmpse->next;
+      MenuDelSub(tmpse);
+      tmpse=tmpse1;
+    }
+    Free(tmpme);
+  }
+}
+
+public U0 MenuDel(CMenu *m)
+{//Delete a manu. You probably don't need this.
+  CMenuEntry *tmpme,*tmpme1;
+  if (!m) return;
+  tmpme=m->sub;
+  while (tmpme) {
+    tmpme1=tmpme->next;
+    MenuDelSub(tmpme);
+    tmpme=tmpme1;
+  }
+  Free(m);
+}
+
+I64 MenuEntryWidth(CMenuEntry *tmpme)
+{
+  I64 res=StrLen(tmpme->name);
+  CMenuEntry *tmpse=tmpme->sub;
+  while (tmpse) {
+    res=MaxI64(res,StrLen(tmpse->name));
+    tmpse=tmpse->next;
+  }
+  return res+1;
+}
+
+public CMenu *MenuPush(U8 *st)
+{//Save old pulldown menu and replace with new from str.
+  CMenu *m=MenuNew(st);
+  m->next=Fs->cur_menu;
+  Fs->cur_menu=m;
+  return m;
+}
+
+public CMenu *MenuFilePush(U8 *filename)
+{//Save old pulldown menu and replace with new from file.
+  CMenu *m=MenuFile(filename);
+  m->next=Fs->cur_menu;
+  Fs->cur_menu=m;
+  return m;
+}
+
+public U0 MenuPop()
+{//Restore old pulldown menu. Delete just-deactivated menu.
+  CMenu *m=Fs->cur_menu;
+  if (!m) return;
+  Fs->cur_menu=m->next;
+  MenuDel(m);
+}
+
+U0 DrawMenu(CDC *dc)
+{
+  CMenu *m;
+  CMenuEntry *tmpme,*tmpse,*cur_submenu=NULL;
+  U8 *st=NULL;
+  CTask *task=MenuTask;
+  I64 i,w,x0,y0,x1=ms.pos.x,y1=ms.pos.y;
+  if (!TaskValidate(task) || !(m=task->cur_menu)) {
+    sys_cur_submenu_entry=NULL;
+    return;
+  }
+  dc->color=m->attr>>4;
+  GrRect(dc,0,0,GR_WIDTH,FONT_HEIGHT);
+  x0=0;
+  tmpme=m->sub;
+  while (tmpme) {
+    w=MenuEntryWidth(tmpme)*FONT_WIDTH;
+    if (x0<=x1<x0+w) {
+      if (0<=y1<FONT_HEIGHT) {
+        dc->color=m->attr&15;
+        GrRect(dc,x0,0,w,FONT_HEIGHT);
+        dc->color=m->attr>>4;
+      } else
+        dc->color=m->attr&15;
+      GrPrint(dc,x0,0,"%s",tmpme->name);
+      y0=FONT_HEIGHT;
+      tmpse=tmpme->sub;
+      while (tmpse) {
+        if (tmpse->checked)
+          i=m->attr^0xFF;
+        else
+          i=m->attr;
+        if (y0<=y1<y0+FONT_HEIGHT) {
+          if (tmpse->msg_code==MSG_KEY_DOWN||
+                tmpse->msg_code==MSG_KEY_DOWN_UP) {
+            if (!tmpse->arg2)
+              tmpse->arg2=Char2ScanCode(tmpse->arg1);
+            st=ScanCode2KeyName(tmpse->arg2);
+          }
+          sys_cur_submenu_entry=cur_submenu=tmpse;
+          dc->color=i&15;
+          GrRect(dc,x0,y0,w,FONT_HEIGHT);
+          dc->color=i>>4;
+          GrPrint(dc,x0,y0,"%s",tmpse->name);
+          if (st) {
+            dc->color=i>>4;
+            GrRect(dc,x0+w,y0-FONT_HEIGHT,
+                  (StrLen(st)+1)*FONT_WIDTH,FONT_HEIGHT*3);
+            dc->color=i&15;
+            GrPrint(dc,x0+w,y0,"%s",st);
+            Free(st);
+          }
+        } else {
+          dc->color=i>>4;
+          GrRect(dc,x0,y0,w,FONT_HEIGHT);
+          dc->color=i&15;
+          GrPrint(dc,x0,y0,"%s",tmpse->name);
+        }
+        y0+=FONT_HEIGHT;
+        tmpse=tmpse->next;
+      }
+    } else {
+      dc->color=m->attr&15;
+      GrPrint(dc,x0,0,"%s",tmpme->name);
+    }
+    x0+=w;
+    tmpme=tmpme->next;
+  }
+  sys_cur_submenu_entry=cur_submenu;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootDVD.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootDVD.HC.HTML new file mode 100755 index 0000000..f002b4e --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootDVD.HC.HTML @@ -0,0 +1,219 @@ + + + + + + + + + + + +
+#define BOOT_HIGH_LOC_DVD       ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_DVD","%08X",BOOT_HIGH_LOC_DVD<<4);
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_DVD_END","%08X",BOOT_RAM_LIMIT-1);
+
+asm {
+USE16
+BDVD_START::
+//DL is supposed to have the BIOS drive number
+        CLD
+        MOV     AX,BOOT_HIGH_LOC_DVD
+        MOV     ES,AX
+
+        CLI
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE
+        STI
+
+        CALL    BDVD_GET_RIP
+BDVD_GET_RIP:
+        POP     BX
+        SUB     BX,BDVD_GET_RIP-BDVD_START
+        SHR     BX,4
+//This copies this bootloader's code to 0x00096600
+        MOV     AX,CS
+        ADD     AX,BX
+        MOV     DS,AX
+        MOV     CX,DVD_BOOT_LOADER_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_DVD
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_DVD:BDVD_MAIN
+        DU16    BDVD_MAIN-BDVD_START,BOOT_HIGH_LOC_DVD;
+
+BDVD_BIOS_DRV_NUM:      DU8     0;
+BDVD_PAGE:              DU8     0;
+
+BDVD_DAP:               DU8     16,0,1,0; //One blk at a time
+BDVD_DAP_BUF:           DU16    0,0;
+BDVD_DAP_BLK:           DU64    0;
+        
+BDVD_TEMPLEOS_MSG:
+        DU8     "Loading TempleOS",0;
+
+BDVD_NOT64_MSG:
+        DU8     "TempleOS requires a 64-bit capable processor.\n\r",0;
+
+//These get patched.
+BDVD_BLK_LO::           DU16    0;
+BDVD_BLK_HI::           DU16    0;
+BDVD_BLK_CNT::          DU16    0;
+BDVD_SHIFT_BLKS::       DU16    0;
+BDVD_PROGRESS_STEP::    DU32    0;
+BDVD_PROGRESS_VAL::     DU32    0;
+
+BDVD_PUT_CHAR::
+        MOV     AH,0xE
+        MOV     BL,7 //Might be foreground color on some BIOS's
+        MOV     BH,U8 [BDVD_PAGE-BDVD_START]
+        INT     0x10
+BDVD_RET::
+        RET
+BDVD_PUTS::
+@@1:    LODSB
+        TEST    AL,AL
+        JZ      BDVD_RET
+        CALL    BDVD_PUT_CHAR
+        JMP     @@1
+
+BDVD_MAIN::
+        MOV     U8 [BDVD_BIOS_DRV_NUM-BDVD_START],DL //Passed in by BIOS
+
+        MOV     AH,0xF
+        INT     0x10
+        MOV     U8 [BDVD_PAGE-BDVD_START],BH //Video page
+
+        MOV     EAX,0x80000000
+        CPUID
+        CMP     EAX,0x80000001
+        JB      @@05
+
+        MOV     EAX,0x80000001
+        CPUID
+        BT      EDX,29
+        JC      @@15
+@@05:   MOV     SI,BDVD_NOT64_MSG-BDVD_START
+        CALL    BDVD_PUTS
+@@10:   JMP     @@10
+
+@@15:   MOV     SI,BDVD_TEMPLEOS_MSG-BDVD_START
+        CALL    BDVD_PUTS
+
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        XOR     ECX,ECX
+        MOV     CX,U16 [BDVD_BLK_CNT-BDVD_START]
+
+        MOV     EAX,(80-7-9)*65536      //80 columns
+        XOR     EDX,EDX
+        DIV     ECX
+        MOV     U32 [BDVD_PROGRESS_STEP-BDVD_START],EAX
+        MOV     U32 [BDVD_PROGRESS_VAL-BDVD_START],0
+
+        MOV     AX,U16 [BDVD_BLK_LO-BDVD_START]
+        MOV     DX,U16 [BDVD_BLK_HI-BDVD_START]
+
+@@20:   PUSH    CX      //Blk cnt
+
+//READ BLK
+        PUSH    AX      //Blk lo
+        PUSH    DX      //Blk hi
+        PUSH    ES      //Buf seg
+        MOV     U16 [BDVD_DAP_BLK-BDVD_START],AX
+        MOV     U16 [BDVD_DAP_BLK+2-BDVD_START],DX
+        MOV     AX,ES
+        MOV     U16 [BDVD_DAP_BUF+2-BDVD_START],AX //ES:0000
+        MOV     SI,BDVD_DAP-BDVD_START //DS:SI=DAP
+        MOV     AH,0x42
+        MOV     DL,U8 [BDVD_BIOS_DRV_NUM-BDVD_START]
+        INT     0x13
+
+        POP     AX      //ES
+        ADD     AX,DVD_BLK_SIZE/16
+        MOV     ES,AX
+        POP     DX
+        POP     AX
+        INC     AX
+        JNZ     @@25
+        INC     DX
+
+@@25:   PUSH    AX
+        MOV     BX,U16 [BDVD_PROGRESS_VAL+2-BDVD_START]
+        MOV     EAX,U32 [BDVD_PROGRESS_STEP-BDVD_START]
+        ADD     U32 [BDVD_PROGRESS_VAL-BDVD_START],EAX
+        CMP     U16 [BDVD_PROGRESS_VAL+2-BDVD_START],BX
+        JE      @@30
+        MOV     AL,'.'
+        CALL    BDVD_PUT_CHAR
+@@30:   POP     AX
+
+        POP     CX
+        LOOP    @@20
+
+//Shift backward to align
+        PUSH    DS
+        MOV     BX,U16 [BDVD_SHIFT_BLKS-BDVD_START]
+        SHL     BX,BLK_SIZE_BITS-4
+        MOV     CX,U16 [BDVD_BLK_CNT-BDVD_START]
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        ADD     AX,BX
+        MOV     DS,AX
+@@35:   PUSH    CX
+        XOR     SI,SI
+        XOR     DI,DI
+        MOV     CX,DVD_BLK_SIZE/4
+        REP_MOVSD
+        MOV     AX,DS
+        ADD     AX,DVD_BLK_SIZE/16
+        MOV     DS,AX
+        MOV     AX,ES
+        ADD     AX,DVD_BLK_SIZE/16
+        MOV     ES,AX
+        POP     CX
+        LOOP    @@35
+        POP     DS
+
+//See BootDVDProbe().
+        MOV     EBX,U32 [BDVD_BLK_LO-BDVD_START]
+        MOV     AX,U16 [BDVD_SHIFT_BLKS-BDVD_START]
+        SHL     EAX,16
+        MOV     AX,BOOT_SRC_DVD  //See sys_boot_src
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_RAM_BASE:0000
+        DU16    0,BOOT_RAM_BASE/16;
+//Continues here ::/Kernel/KStart16.HC
+BDVD_END::
+#assert BDVD_END-BDVD_START<DVD_BOOT_LOADER_SIZE
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootDVDIns.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootDVDIns.HC.HTML new file mode 100755 index 0000000..6d3592b --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootDVDIns.HC.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+//See Install Documentation.
+//Study my account examples: Cfg Strs, Update Funs
+
+#include "BootDVD"
+#include "DskISORedSea"
+
+#help_index "Install"
+
+#define KERNEL_BIN_C    "Kernel.BIN.C"
+#define BOOT_DIR        "/0000Boot"
+#define BOOT_DIR_KERNEL_BIN_C   BOOT_DIR "/0000" KERNEL_BIN_C
+
+U0 MakeAll()
+{
+  if (Cmp("/Compiler/Compiler","Compiler",,':'))
+    throw;
+  if (Cmp("/Kernel/Kernel","Kernel",,':'))
+    throw;
+}
+
+public U0 BootDVDIns(U8 drv_let=0)
+{//See ::/Misc/DoDistro.HC.
+  try {
+    if (!Drv(drv_let))
+      throw;
+    MakeAll;
+    Move("/Kernel/Kernel.BIN.Z",BOOT_DIR_KERNEL_BIN_C);
+  } catch {
+    PutExcept;
+    Beep;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootHD.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootHD.HC.HTML new file mode 100755 index 0000000..58706ba --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootHD.HC.HTML @@ -0,0 +1,124 @@ + + + + + + + + + + + +
+#define MODULE_SIZE             1*BLK_SIZE
+#define BOOT_HIGH_LOC_HD        ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+MODULE_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_HD","%08X",BOOT_HIGH_LOC_HD<<4);
+
+asm {
+USE16
+BHD_CODE::
+
+#define BHD_START (BHD_CODE-offset(CFAT32Boot.code))
+
+        CLD
+
+        MOV     AX,BOOT_HIGH_LOC_HD
+        MOV     ES,AX
+
+        CLI
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE+MODULE_SIZE
+        STI
+
+        CALL    BHD_GET_RIP
+BHD_GET_RIP:
+        POP     BX
+        SUB     BX,BHD_GET_RIP-BHD_START
+        SHR     BX,4
+//This copies this bootloader's code to 0x00096C00
+        MOV     AX,CS
+        ADD     AX,BX
+        MOV     DS,AX
+        MOV     CX,MODULE_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_HD
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_HD:BHD_HISTART
+        DU16    BHD_HISTART-BHD_START,BOOT_HIGH_LOC_HD;
+
+BHD_BIOS_DRV_NUM: DU8   0;
+
+//Gets patched by BootHDIns().
+BHD_BLK_CNT::   DU16    0;
+
+BHD_DAP:        DU8     16,0,1,0; //One blk at a time
+BHD_DAP_BUF:    DU16    0,0;
+//Gets patched by BootHDIns().
+BHD_DAP_BLK::   //64-bit
+BHD_DAP_BLK_LO: DU32    0;
+BHD_DAP_BLK_HI: DU32    0;
+
+BHD_HISTART:
+        MOV     U8 [BHD_BIOS_DRV_NUM-BHD_START],DL //Passed in by BIOS
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        XOR     ECX,ECX
+        MOV     CX,U16 [BHD_BLK_CNT-BHD_START]
+
+@@05:   PUSH    CX      //Blk cnt
+
+//READ BLK
+        PUSH    ES      //Buf seg
+        MOV     AX,ES
+        MOV     U16 [BHD_DAP_BUF+2-BHD_START],AX //ES:0000
+        MOV     SI,BHD_DAP-BHD_START //DS:SI=DAP
+        MOV     AH,0x42
+        MOV     DL,U8 [BHD_BIOS_DRV_NUM-BHD_START]
+        INT     0x13
+
+        POP     AX      //ES
+        ADD     AX,BLK_SIZE/16
+        MOV     ES,AX
+        INC     U32 [BHD_DAP_BLK_LO-BHD_START]
+        JNZ     @@10
+        INC     U32 [BHD_DAP_BLK_HI-BHD_START]
+
+@@10:   POP     CX
+        LOOP    @@05
+
+        XOR     EBX,EBX
+        MOV     EAX,BOOT_SRC_HARDDRV //See sys_boot_src
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_RAM_BASE:0000
+        DU16    0,BOOT_RAM_BASE/16;
+//Continues here ::/Kernel/KStart16.HC
+BHD_END::
+#assert BHD_END-BHD_START<MODULE_SIZE-2
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootHDIns.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootHDIns.HC.HTML new file mode 100755 index 0000000..d1ad294 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootHDIns.HC.HTML @@ -0,0 +1,91 @@ + + + + + + + + + + + +
+//See Install Documentation.
+//Study my account examples: Cfg Strs, Update Funs
+
+#include "BootHD"
+
+#help_index "Install"
+
+#define KERNEL_BIN_C    "Kernel.BIN.C"
+
+U0 MakeAll()
+{
+  if (Cmp("/Compiler/Compiler","Compiler",,':'))
+    throw;
+  if (Cmp("/Kernel/Kernel","Kernel",,':'))
+    throw;
+}
+
+public U0 BootHDIns(U8 drv_let=0)
+{//MakeAll and install new boot-loader.
+  CDrv *dv;
+  CFAT32Boot br;
+  CDirEntry de;
+  I64 i;
+  try {
+    if (!Drv(drv_let))
+      throw;
+    dv=Fs->cur_dv;
+    MakeAll;
+    switch (Let2BlkDevType(dv->drv_let)) {
+      case BDT_RAM:
+      case BDT_ATA:
+        Move("/Kernel/Kernel.BIN.Z","/" KERNEL_BIN_C);
+        if (!FileFind("/" KERNEL_BIN_C,&de,FUF_JUST_FILES))
+          "No Kernel.BIN.C\n";
+        else {
+          Free(de.full_name);
+          "Modifying partition boot record.\n";
+          BlkRead(dv,&br,dv->drv_offset,1);
+          br.jump_and_nop[0]=OC_JMP_REL8;
+          br.jump_and_nop[1]=offset(CFAT32Boot.code)-2;
+#assert offset(CFAT32Boot.code)>=offset(CRedSeaBoot.code)
+          br.jump_and_nop[2]=OC_NOP;
+          *BHD_BLK_CNT(U16 *)=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+          *BHD_DAP_BLK(I64 *)=Clus2Blk(dv,de.clus);
+          for (i=0;i<BHD_END-BHD_CODE;i++)
+            br.code[i]=BHD_CODE(U8 *)[i];
+#assert sizeof(CFAT32Boot.code)>=BHD_END-BHD_CODE
+          for (;i<sizeof(CFAT32Boot.code);i++)
+            br.code[i]=0;
+          BlkWrite(dv,&br,dv->drv_offset,1);
+        }
+        break;
+      default:
+        throw;
+    }
+  } catch {
+    PutExcept;
+    Beep;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootMHD.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootMHD.HC.HTML new file mode 100755 index 0000000..edbad66 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootMHD.HC.HTML @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+#define MODULE_SIZE             1*BLK_SIZE
+#define BOOT_HIGH_LOC_MHD       ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+MODULE_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_MHD","%08X",BOOT_HIGH_LOC_MHD<<4);
+
+asm {
+USE16
+BMHD_START::
+BMHD_CODE::
+        CLD
+
+        MOV     AX,BOOT_HIGH_LOC_MHD
+
+        CLI
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE+MODULE_SIZE
+        STI
+
+        PUSHFW
+        PUSH    DS
+        PUSH    ES
+        PUSH    FS
+        PUSH    GS
+        PUSH    ECX
+        PUSH    EBX
+        PUSH    EDX
+        PUSH    EBP
+
+        MOV     ES,AX
+
+        CALL    BMHD_GET_RIP
+BMHD_GET_RIP:
+        POP     BX
+        SUB     BX,BMHD_GET_RIP-BMHD_START
+        MOV     CX,BX
+        SHR     BX,4
+//This copies this bootloader's code to 0x00096C00
+        MOV     AX,CS
+        PUSH    AX
+        ADD     AX,BX
+        MOV     DS,AX
+        MOV     U16 [BMHD_OLD_CS_RIP-BMHD_START],CX
+        POP     U16 [BMHD_OLD_CS_RIP+2-BMHD_START]
+
+        MOV     CX,MODULE_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_MHD
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_MHD:BMHD_HISTART
+        DU16    BMHD_HISTART-BMHD_START,BOOT_HIGH_LOC_MHD;
+
+BMHD_BIOS_DRV_NUM:      DU8     0;
+BMHD_OLD_CS_RIP:                DU16    0,0;
+//Gets patched by BootHDIns().
+BMHD_BLK_CNT::          DU16    0;
+
+BMHD_DAP:               DU8     16,0,1,0; //One blk at a time
+BMHD_DAP_BUF:           DU16    0,0;
+//Gets patched by BootHDIns().
+BMHD_DAP_BLK::  //64-bit
+BMHD_DAP_BLK_LO:        DU32    0;
+BMHD_DAP_BLK_HI:        DU32    0;
+
+BMHD_HISTART:
+        MOV     U8 [BMHD_BIOS_DRV_NUM-BMHD_START],DL //Passed in by BIOS
+        MOV     AX,BOOT_RAM_BASE/16
+        MOV     ES,AX
+        XOR     ECX,ECX
+        MOV     CX,U16 [BMHD_BLK_CNT-BMHD_START]
+
+@@05:   PUSH    CX      //Blk cnt
+
+//READ BLK
+        PUSH    ES      //Buf seg
+        MOV     AX,ES
+        MOV     U16 [BMHD_DAP_BUF+2-BMHD_START],AX //ES:0000
+        MOV     SI,BMHD_DAP-BMHD_START //DS:SI=DAP
+        MOV     AH,0x42
+        MOV     DL,U8 [BMHD_BIOS_DRV_NUM-BMHD_START]
+        INT     0x13
+
+        POP     AX      //ES
+        ADD     AX,BLK_SIZE/16
+        MOV     ES,AX
+        INC     U32 [BMHD_DAP_BLK_LO-BMHD_START]
+        JNZ     @@10
+        INC     U32 [BMHD_DAP_BLK_HI-BMHD_START]
+
+@@10:   POP     CX
+        LOOP    @@05
+
+        MOV     DL,U8 [BMHD_BIOS_DRV_NUM-BMHD_START]
+        MOV     EBX,U32 [BMHD_OLD_CS_RIP-BMHD_START]
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_RAM_BASE:0000
+        DU16    0,BOOT_RAM_BASE/16;
+//Continues here BMHD2_START
+BMHD_END::
+#assert BMHD_END-BMHD_START<=440
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootMHD2.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootMHD2.HC.HTML new file mode 100755 index 0000000..fde5e41 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootMHD2.HC.HTML @@ -0,0 +1,154 @@ + + + + + + + + + + + +
+#define MODULE_SIZE             2*BLK_SIZE
+#define BOOT_HIGH_LOC_MHD2      ((BOOT_RAM_LIMIT-\
+                                (BOOT_STK_SIZE+MODULE_SIZE))>>4)
+
+DefinePrint(
+  "DD_BOOT_HIGH_LOC_MHD2","%08X",BOOT_HIGH_LOC_MHD2<<4);
+
+asm {
+USE16
+BMHD2_START::
+        MOV     U32 FS:[0],'B'+0x2000+('2'+0x2000)<<16
+
+        MOV     AX,BOOT_HIGH_LOC_MHD2
+        MOV     ES,AX
+//This copies this bootloader's code to 0x00096A00
+        MOV     AX,CS
+        MOV     DS,AX
+        MOV     U32 [BMHD2_OLD_CS_RIP-BMHD2_START],EBX
+        MOV     U8 [BMHD2_BIOS_DRV_NUM-BMHD2_START],DL
+
+        MOV     CX,MODULE_SIZE
+        XOR     SI,SI
+        XOR     DI,DI
+        REP_MOVSB
+
+        MOV     AX,BOOT_HIGH_LOC_MHD2
+        MOV     DS,AX
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP BOOT_HIGH_LOC_MHD2:BMHD2_HISTART
+        DU16    BMHD2_HISTART-BMHD2_START,BOOT_HIGH_LOC_MHD2;
+
+BMHD2_BOOT_MSG::
+        DU8     256 DUP(0);
+
+BMHD2_BIOS_DRV_NUM:     DU8     0;
+BMHD2_PAGE:             DU8     0;
+BMHD2_BLK_ARRAY::       DU64 8 DUP(0);
+
+BMHD2_DAP:              DU8     16,0,1,0; //One blk at a time
+BMHD2_DAP_BUF:          DU16    0,0;
+BMHD2_DAP_BLK:: //64-bit
+BMHD2_DAP_BLK_LO:       DU32    0;
+BMHD2_DAP_BLK_HI:       DU32    0;
+
+BMHD2_PUT_CHAR::
+        MOV     AH,0xE
+        MOV     BL,7 //Might be foreground color on some BIOS's
+        MOV     BH,U8 [BMHD2_PAGE-BMHD2_START]
+        INT     0x10
+BMHD2_RET::
+        RET
+BMHD2_PUTS::
+@@1:    LODSB
+        TEST    AL,AL
+        JZ      BMHD2_RET
+        CALL    BMHD2_PUT_CHAR
+        JMP     @@1
+
+BMHD2_GETCHAR:
+        XOR     AH,AH
+        INT     0x16
+        PUSH    AX
+        MOV     AH,0x0E
+        MOV     BX,0x07
+        INT     0x10
+        POP     AX
+        RET
+
+BMHD2_HISTART:
+        MOV     AH,0xF
+        INT     0x10
+        MOV     U8 [BMHD2_PAGE-BMHD2_START],BH //Video page
+
+        MOV     U32 FS:[0],0
+@@5:    MOV     SI,BMHD2_BOOT_MSG-BMHD2_START
+        CALL    BMHD2_PUTS
+        CALL    BMHD2_GETCHAR
+        CMP     AL,'0'
+        JB      @@5
+        CMP     AL,'8'
+        JAE     @@5
+        AND     EAX,7
+
+        MOV     EBX,U32 BMHD2_BLK_ARRAY-BMHD2_START[EAX*8]
+        MOV     EAX,U32 BMHD2_BLK_ARRAY+4-BMHD2_START[EAX*8]
+
+        TEST    EBX,EBX
+        JNZ     @@10
+        TEST    EAX,EAX
+        JZ      @@5
+
+@@10:   MOV     U32 [BMHD2_DAP_BLK_LO-BMHD2_START],EBX
+        MOV     U32 [BMHD2_DAP_BLK_HI-BMHD2_START],EAX
+
+        MOV     AX,U16 [BMHD2_OLD_CS_RIP-BMHD2_START]
+        SHR     AX,4
+        ADD     AX,U16 [BMHD2_OLD_CS_RIP+2-BMHD2_START]
+        MOV     U16 [BMHD2_DAP_BUF+2-BMHD2_START],AX //ES:0000
+        MOV     SI,BMHD2_DAP-BMHD2_START //DS:SI=DAP
+        MOV     DL,U8 [BMHD2_BIOS_DRV_NUM-BMHD2_START]
+        MOV     AH,0x42
+        INT     0x13
+
+        POP     EBP
+        POP     EDX
+        POP     EBX
+        POP     ECX
+        XOR     EAX,EAX
+        POP     GS
+        POP     FS
+        POP     ES
+        POP     DS
+        POPFW
+
+//My assembler doesn't support 16-bit very well.
+        DU8     0xEA;   //JMP xxxx:yyyy
+BMHD2_OLD_CS_RIP:
+        DU16    0,0;
+BMHD2_END::
+//Continues here ::/Adam/Opt/Boot/BootHD.HC
+#assert BMHD2_END-BMHD2_START<MODULE_SIZE
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootMHDIns.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootMHDIns.HC.HTML new file mode 100755 index 0000000..9f2bd46 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootMHDIns.HC.HTML @@ -0,0 +1,183 @@ + + + + + + + + + + + +
+//See Install Documentation.
+//Study my account examples: Cfg Strs, Update Funs
+
+#include "BootMHD"
+#include "BootMHD2"
+
+#help_index "Install"
+
+#define BOOT_DIR        "/0000Boot"
+//Stage 2 of master boot loader
+#define BOOT_DIR_BOOTMHD2_BIN_C BOOT_DIR "/BootMHD2.BIN.C"
+//Old master boot record
+#define BOOT_DIR_OLDMBR_BIN_C   BOOT_DIR "/OldMBR.BIN.C"
+
+public U0 BootMHDOldRead(U8 src_drv,U8 dst_drv)
+{//Reads MBR from disk drive containing src partition.
+//Writes a single blk file to dst BOOT_DIR.
+  CBlkDev *bd=Let2BlkDev(src_drv);
+  CDrv *dv;
+  CMasterBoot mbr;
+  Drv(dst_drv);
+  dv=Fs->cur_dv;
+  if (dv->fs_type!=FSt_REDSEA && dv->fs_type!=FSt_FAT32)
+    PrintErr("File System Not Supported\n");
+  else {
+//Bypass partition bounds-checking
+    BlkDevLock(bd);
+    ATAReadBlks(bd,&mbr,0,1);
+    BlkDevUnlock(bd);
+
+    Drv(dst_drv);
+    DirMk(BOOT_DIR);
+    FileWrite(BOOT_DIR_OLDMBR_BIN_C,&mbr,BLK_SIZE);
+  }
+}
+
+public U0 BootMHDOldWrite(U8 src_drv,U8 dst_drv)
+{//Reads OldMBR from src drive BOOT_DIR.
+//writes it to the MBR of the drive with dst partition.
+  CBlkDev *bd=Let2BlkDev(dst_drv);
+  CMasterBoot *mbr;
+  Drv(src_drv);
+  if (mbr=FileRead(BOOT_DIR_OLDMBR_BIN_C)) {
+//Bypass partition bounds-checking
+    BlkDevLock(bd);
+    ATAWriteBlks(bd,mbr,0,1);
+    BlkDevUnlock(bd);
+  }
+  Free(mbr);
+}
+
+public U0 BootMHDZero(U8 dst_drv)
+{//Set MBR of disk with dst partition to zero.
+
+  //This is dangerous!!
+  //The TempleOS partitioner doesn't play well
+  //with other operating systems at this time and you need
+  //to do this on a drive partitioned by TempleOS
+  //if you wish to partition with another operating system.
+  CBlkDev *bd=Let2BlkDev(dst_drv);
+  CMasterBoot mbr;
+  MemSet(&mbr,0,BLK_SIZE);
+//Bypass partition bounds-checking
+  BlkDevLock(bd);
+  ATAWriteBlks(bd,&mbr,0,1);
+  BlkDevUnlock(bd);
+}
+
+public Bool BootMHDIns(U8 drv_let,U8 *drv_lst=NULL)
+{//Create new MBR on the disk that has drv_let as a partition.
+//Puts stage 2 in BOOT_DIR of drv_let.
+  CBlkDev *bd,*bd1;
+  CDrv *dv,*p1;
+  CMasterBoot mbr;
+  CDirEntry de;
+  I64 i,j,size,*_q;
+  U8 *menu_ptr,*ptr,ch,buf[STR_LEN];
+  Bool res=FALSE;
+
+  try {
+    if (drv_lst) {
+      StrCpy(buf,drv_lst);
+      StrUtil(buf,SUF_TO_UPPER);
+    } else {
+      j=0;
+      for (i='A';i<='Z';i++)
+        buf[j++]=i;
+      buf[j++]=0;
+    }
+    Drv(drv_let);
+    dv=Fs->cur_dv;
+    if (dv->fs_type!=FSt_REDSEA && dv->fs_type!=FSt_FAT32)
+      PrintErr("File System Not Supported\n");
+    else {
+      bd=dv->bd;
+      if (!FileFind(BOOT_DIR_OLDMBR_BIN_C,,FUF_JUST_FILES))
+        BootMHDOldRead(drv_let,drv_let);
+
+      _q=BMHD2_BLK_ARRAY;
+      MemSet(_q,0,sizeof(I64)*8);
+      menu_ptr=BMHD2_BOOT_MSG;
+      StrPrint(menu_ptr,"\n\r\n\rTempleOS Boot Loader\n\r\n\r");
+      j=0;
+      if (FileFind(BOOT_DIR_OLDMBR_BIN_C,&de,FUF_JUST_FILES)) {
+        Free(de.full_name);
+        *_q++=Clus2Blk(dv,de.clus);
+        CatPrint(menu_ptr,"0. Old Boot Record\n\r");
+        j++;
+      }
+
+      ptr=buf;
+      while (ch=*ptr++) {
+        if ((p1=Let2Drv(ch,FALSE)) && (bd1=p1->bd) && bd1==bd) {
+          *_q=p1->drv_offset;
+          "Drive %C:%16X\n",Drv2Let(p1),*_q;
+          CatPrint(menu_ptr,"%d. Drive %C\n\r",j++,Drv2Let(p1));
+          _q++;
+        }
+      }
+      CatPrint(menu_ptr,"\n\rSelection:");
+
+      size=BMHD2_END-BMHD2_START;
+      FileWrite(BOOT_DIR_BOOTMHD2_BIN_C,BMHD2_START,size);
+
+      if (!FileFind(BOOT_DIR_BOOTMHD2_BIN_C,&de,FUF_JUST_FILES))
+        "No Boot Loader Image\n";
+      else {
+        Free(de.full_name);
+        *BMHD_BLK_CNT(U16 *)=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+        *BMHD_DAP_BLK(I64 *)=Clus2Blk(dv,de.clus);
+//Bypass partition bounds-checking
+        BlkDevLock(bd);
+        ATAReadBlks(bd,&mbr,0,1);
+        for (i=0;i<BMHD_END-BMHD_CODE;i++)
+          mbr.code[i]=BMHD_CODE(U8 *)[i];
+#assert sizeof(CMasterBoot.code)>=BMHD_END-BMHD_CODE
+        for (;i<sizeof(CMasterBoot.code);i++)
+          mbr.code[i]=0;
+        if (!mbr.media_id)
+          mbr.media_id=RandU32;
+        mbr.zero=0;
+        mbr.signature=0xAA55;
+
+        ATAWriteBlks(bd,&mbr,0,1);
+        BlkDevUnlock(bd);
+        res=TRUE;
+      }
+    }
+  } catch
+    PutExcept;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/BootRAM.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/BootRAM.HC.HTML new file mode 100755 index 0000000..9a05223 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/BootRAM.HC.HTML @@ -0,0 +1,91 @@ + + + + + + + + + + + +
+#help_index "Call"
+asm {
+_HI_CALL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 16[RBP]
+        TEST    RAX,RAX
+        JZ      @@05
+        CALL    RAX
+@@05:   POP     RBP
+        RET1    8
+//************************************
+_HI_MEMCPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_MOVSB
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+}
+_extern _HI_CALL I64 HiCall(U8 *machine_code);
+_extern _HI_MEMCPY U8 *HiMemCpy(U8 *dst,U8 *src,I64 cnt);
+
+#help_index "Boot"
+public U0 BootRAM(U8 *filename=NULL)
+{//Softboot Kernel.BIN file. No hardware reset.
+  I64 size;
+  CKernel *hi_image,*lo_image=mem_boot_base-sizeof(CBinFile),
+        reg *sys_ram_reboot;
+  if (!filename)
+    filename="::/" KERNEL_BIN_C;
+  do if (!(hi_image=FileRead(filename,&size))) return;
+  while (hi_image<0x100000); //If alloc from low 640K, just get another copy.
+
+  do sys_ram_reboot=MAlloc(SYS_RAM_REBOOT_END-SYS_RAM_REBOOT,Fs->code_heap);
+  while (sys_ram_reboot<0x100000);
+
+  hi_image->boot_src=BOOT_SRC_RAM;
+  hi_image->boot_blk=0;
+  hi_image->boot_patch_table_base=lo_image(U8 *)+hi_image->h.patch_table_offset;
+  hi_image->sys_run_level =lo_image->sys_run_level&(RLF_VGA|RLF_16BIT);
+  MemCpy(&hi_image->start,&lo_image->start,
+        sizeof(CKernel)-offset(CKernel.start));
+
+  CLI
+  if (mp_cnt>1)
+    MPHalt;
+
+  HiMemCpy(sys_ram_reboot,SYS_RAM_REBOOT,SYS_RAM_REBOOT_END-SYS_RAM_REBOOT);
+  HiMemCpy(lo_image,hi_image,size);
+  HiCall(sys_ram_reboot);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/DskISORedSea.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/DskISORedSea.HC.HTML new file mode 100755 index 0000000..1f7490e --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/DskISORedSea.HC.HTML @@ -0,0 +1,219 @@ + + + + + + + + + + + +
+#help_index "File/CD DVD"
+
+U0 FillU16Palindrome(CPalindromeU16 *dst,U16 w)
+{
+  dst->big=EndianU16(w);
+  dst->little=w;
+}
+
+U0 FillU32Palindrome(CPalindromeU32 *dst,I64 d)
+{
+  dst->big=EndianU32(d);
+  dst->little=d;
+}
+
+class CElTorito
+{
+  U16 w[16];
+  U8 bootable; //88=bootable 00=not bootable
+  U8 media_type; //0=no emulation 4=hard disk
+  U16 load_seg; //0000->07C0
+  U8 sys_type;
+  U8 zero;
+  U16 sect_cnt;
+  U32 load_rba; //start addr of virtual disk
+  U8 zero2[20];
+};
+
+U0 RedSeaISO9660Stage1(U8 *iso_filename,U8 *stage2_filename)
+{
+  CDirEntry de;
+  CFile *out_file=NULL;
+  U8    *stage1_buf=CAlloc(DVD_BOOT_LOADER_SIZE);
+  if (FileFind(stage2_filename,&de) && (out_file=FOpen(iso_filename,"wc+"))) {
+    MemCpy(stage1_buf,BDVD_START,BDVD_END-BDVD_START);
+    *(BDVD_BLK_LO       -BDVD_START+stage1_buf)(U32 *)=de.clus>>2;
+    *(BDVD_BLK_CNT      -BDVD_START+stage1_buf)(U16 *)=
+          (de.size+DVD_BLK_SIZE-1)>>(BLK_SIZE_BITS+2);
+    *(BDVD_SHIFT_BLKS   -BDVD_START+stage1_buf)(U16 *)=de.clus&3;
+    if (de.clus&3)
+      *(BDVD_BLK_CNT    -BDVD_START+stage1_buf)(U16 *)+=1;
+    FBlkWrite(out_file,stage1_buf,
+          20<<2+1<<2,DVD_BOOT_LOADER_SIZE/BLK_SIZE);
+    FClose(out_file);
+  }
+  Free(stage1_buf);
+}
+
+U0 RedSeaISO9660(U8 *iso_filename,U8 drv_let)
+{
+  CDrv  *dv=Let2Drv(drv_let);
+  CISOPriDesc *iso_pri=CAlloc(DVD_BLK_SIZE),
+        *iso_boot=CAlloc(DVD_BLK_SIZE),
+        *iso_sup=CAlloc(DVD_BLK_SIZE),
+        *iso_term=CAlloc(DVD_BLK_SIZE);
+  I64 iso_size=0,i,j;
+  U32 *d;
+  CElTorito *et=CAlloc(DVD_BLK_SIZE);
+  U8    *zero_buf=CAlloc(DVD_BLK_SIZE);
+  CFile *out_file=NULL;
+
+  if (out_file=FOpen(iso_filename,"wc+")) {
+    iso_size=FSize(out_file)/DVD_BLK_SIZE;
+    for (i=0;i<dv->bd->drv_offset;i+=4)
+      FBlkWrite(out_file,zero_buf,i,4);
+
+    iso_pri->type=ISOT_PRI_VOL_DESC;
+    StrCpy(iso_pri->id,"CD001");
+    iso_pri->version=1;
+    FillU16Palindrome(&iso_pri->vol_set_size,1);
+    FillU16Palindrome(&iso_pri->vol_seq_num,1);
+    FillU16Palindrome(&iso_pri->log_block_size,DVD_BLK_SIZE);
+    FillU32Palindrome(&iso_pri->vol_space_size,iso_size);
+    FillU32Palindrome(&iso_pri->root_dir_record,dv->root_clus);
+    iso_pri->file_structure_version=1;
+    StrCpy(iso_pri->publisher_id,"TempleOS RedSea");
+
+    MemCpy(iso_sup,iso_pri,DVD_BLK_SIZE);
+    iso_sup->type=ISOT_SUPPLEMENTARY_DESC;
+
+    iso_boot->type=ISOT_BOOT_RECORD;
+    StrCpy(iso_boot->id,"CD001");
+    iso_boot->version=1;
+    StrCpy(iso_boot(U8 *)+7,"EL TORITO SPECIFICATION");
+
+    FBlkWrite(out_file,iso_pri,16<<2,4);
+    iso_term->type=ISOT_TERMINATOR;
+    StrCpy(iso_term->id,"CD001");
+    iso_term->version=1;
+
+    d=iso_boot(U8 *)+0x47;
+    *d=20<<2>>2;
+    FBlkWrite(out_file,iso_boot,17<<2,4);
+
+    FBlkWrite(out_file,iso_sup,18<<2,4);
+    FBlkWrite(out_file,iso_term,19<<2,4);
+
+    et->w[0]=1;
+    StrCpy(&et->w[2],"TempleOS");
+    et->w[15]=0xAA55;
+    j=0;
+    for (i=0;i<16;i++) //Checksum
+      j+=et->w[i];
+    et->w[14]=-j;
+    et->bootable=0x88;
+    et->media_type=0;//0=no emu 2=1.44meg 4=hard drive
+    et->sect_cnt=4;  //5 seems like the limit, 4 is safer
+    et->load_rba=20<<2>>2+1;
+    FBlkWrite(out_file,et,20<<2,4);
+    FClose(out_file);
+  }
+  Free(zero_buf);
+  Free(et);
+  Free(iso_pri);
+  Free(iso_boot);
+  Free(iso_sup);
+  Free(iso_term);
+}
+
+I64 RedSeaISOPass1(CDirEntry *tmpde)
+{
+  I64 dir_entry_cnt=3+LinkedLstCnt(tmpde),res=0;
+  while (tmpde) {
+    if (tmpde->attr & RS_ATTR_DIR) {
+      if (tmpde->sub)
+        res+=RedSeaISOPass1(tmpde->sub);
+      else
+        res+=BLK_SIZE; //Empty dir
+    } else
+      res+=CeilU64(tmpde->size,BLK_SIZE);
+    tmpde=tmpde->next;
+  }
+  res+=CeilU64(dir_entry_cnt<<6,BLK_SIZE); //Size in bytes
+#assert CDIR_SIZE==64
+  return res;
+}
+public I64 RedSeaISO(U8 *_iso_filename=NULL,U8 *_src_dir,
+        U8 *_stage2_filename=NULL)
+{//See ::/Misc/DoDistro.HC. Must be ISO.C
+  I64 i,res,root_cnt,root_dir_blks,bitmap_blks,bitmap_blks1;
+  CDirEntry *tmpde;
+  U8 buf[STR_LEN],*iso_filename,*src_dir,*stage2_filename;
+  CDrv *dv=DrvMakeFreeSlot(DrvNextFreeLet('Q')); //First BDT_ISO_FILE_WRITE
+  CBlkDev *bd=BlkDevNextFreeSlot(dv->drv_let,BDT_ISO_FILE_WRITE);
+
+  if (!IsDir(_src_dir))
+    PrintErr("'%s' is not a dir.\n",_src_dir);
+  else {
+    if (!_iso_filename)
+      _iso_filename=blkdev.dft_iso_c_filename;
+    iso_filename=ExtChg(_iso_filename,"ISO.C");
+    src_dir=DirNameAbs(_src_dir);
+    if (_stage2_filename) {
+      stage2_filename=FileNameAbs(_stage2_filename);
+      *stage2_filename=dv->drv_let;
+      i=StrLen(src_dir);
+      if (i!=3) //If not root
+        i++;    //Skip slash
+      StrCpy(stage2_filename+3,stage2_filename+i);
+    } else
+      stage2_filename=NULL;
+    tmpde=FilesFind(src_dir,FUF_RECURSE);
+    root_cnt=LinkedLstCnt(tmpde)+3;
+    root_dir_blks=CeilU64(root_cnt<<6,BLK_SIZE)>>BLK_SIZE_BITS;
+    if (res=RedSeaISOPass1(tmpde)>>BLK_SIZE_BITS) {
+      bd->drv_offset=19<<2+(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
+      bitmap_blks=1;
+      do {
+        bitmap_blks1=bitmap_blks;
+        bitmap_blks=(res+bitmap_blks+BLK_SIZE<<3-1)/BLK_SIZE<<3;
+      } while (bitmap_blks!=bitmap_blks1);
+
+      bd->max_blk=CeilI64(bd->drv_offset+1+bitmap_blks+res,4);
+      bd->max_blk--; //Inclusive.
+      bd->file_dsk_name=AStrNew(iso_filename);
+      bd->init_root_dir_blks=root_dir_blks;
+      BlkDevAdd(bd,,TRUE,TRUE);
+      StrPrint(buf,"%C:/",dv->drv_let);
+      CopyTree(src_dir,buf,TRUE);
+      RedSeaISO9660Stage1(iso_filename,stage2_filename);
+      DrvDel(dv);
+      BlkDevDel(bd);
+    }
+    Free(stage2_filename);
+    Free(src_dir);
+    Free(iso_filename);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Boot/MakeBoot.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Boot/MakeBoot.HC.HTML new file mode 100755 index 0000000..181a93f --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Boot/MakeBoot.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "BootDVDIns"
+#include "BootHDIns"
+#include "BootMHDIns"
+#include "BootRAM"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/Diff.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/Diff.HC.HTML new file mode 100755 index 0000000..5a18dbd --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/Diff.HC.HTML @@ -0,0 +1,384 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+#define DS_USE_FILE1    0
+#define DS_USE_FILE2    1
+#define DS_REMAINDER_1  2
+#define DS_REMAINDER_2  3
+#define DS_ABORT_FILE   4
+
+I64 PopUpDiffMenu()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$CM+LX,2,4$$FG$$BT,\"USE FILE1\",LE=DS_USE_FILE1$"
+        "$CM+LX,24,0$$CYAN$$BT,\"USE FILE2\",LE=DS_USE_FILE2$"
+        "$CM+LX,2,4$$FG$$BT,\"REMAINDER ALL FILE1\",LE=DS_REMAINDER_1$"
+        "$CM+LX,24,0$$CYAN$$BT,\"REMAINDER ALL FILE2\",LE=DS_REMAINDER_2$"
+        "$CM+LX,2,4$$FG$$BT,\"ABORT FILE\",LE=DS_ABORT_FILE$"
+        "$CM+LX,24,0$$FG$$BT,\"ABORT ALL FILES\",LE=DOCM_CANCEL$\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 DiffEntriesCompare(CDocEntry *doc_e1,CDocEntry *doc_e2)
+{
+  return StrCmp(doc_e1->tag,doc_e2->tag);
+}
+
+#define DF_MODIFIED                     0x01
+#define DF_DONT_MODIFIED                0x02
+#define DF_REMAINDER_ALL_FILE1          0x04
+#define DF_REMAINDER_ALL_FILE2          0x08
+#define DF_ABORT_FILE                   0x10
+#define DF_ABORT_ALL_FILES              0x20
+#define DF_NO_MORE_PMTS_THIS_FILE       0x40
+
+U0 DiffSel(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,
+        I64 j2_lo,I64 j2_hi,I64 cnt1,I64 cnt2,
+        CDocEntry **doc_unsorted1,CDocEntry **doc_unsorted2)
+{
+  CDocEntry *doc_e,*doc_e1,*doc_e2;
+  Bool use_file1;
+  I64 i,old_flags;
+  CDoc *cur_l;
+  if (!(*_df_flags & (DF_ABORT_FILE|DF_ABORT_ALL_FILES))) {
+    "$RED$";
+    if (0<=j1_lo<cnt1)
+      "%d,",doc_unsorted1[j1_lo]->y+1;
+    else if (0<=j1_hi-1<cnt1)
+      "%d,",doc_unsorted1[j1_hi-1]->y+1;
+    else
+      "***,";
+    if (0<=j2_lo<cnt2)
+      "%d",doc_unsorted2[j2_lo]->y+1;
+    else if (0<=j2_hi-1<cnt2)
+      "%d",doc_unsorted2[j2_hi-1]->y+1;
+    else
+      "***";
+    "---------------------$FG$\n";
+    if (j1_lo<=0)
+      i=0;
+    else
+      i=j1_lo-1;
+    while (i<j1_hi) {
+      if (cur_l=DocPut) {
+        old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+        cur_l->flags|=DOCF_PLAIN_TEXT;
+      }
+      "%s",doc_unsorted1[i++]->tag;
+      if (cur_l)
+        cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+      '\n';
+    }
+    "$CYAN$";
+    if (j2_lo<=0)
+      i=0;
+    else
+      i=j2_lo-1;
+    while (i<j2_hi) {
+      if (cur_l=DocPut) {
+        old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+        cur_l->flags|=DOCF_PLAIN_TEXT;
+      }
+      "%s",doc_unsorted2[i++]->tag;
+      if (cur_l)
+        cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+      '\n';
+    }
+    "$FG$";
+
+    use_file1=TRUE;
+    if (!(*_df_flags & DF_NO_MORE_PMTS_THIS_FILE)) {
+      switch (PopUpDiffMenu) {
+        case DS_USE_FILE1:
+          break;
+        case DS_USE_FILE2:
+          use_file1=FALSE;
+          break;
+        case DS_REMAINDER_1:
+          *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE2|
+                DF_REMAINDER_ALL_FILE1|DF_NO_MORE_PMTS_THIS_FILE;
+          break;
+        case DS_REMAINDER_2:
+          *_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE1|
+                DF_REMAINDER_ALL_FILE2|DF_NO_MORE_PMTS_THIS_FILE;
+          break;
+        case DS_ABORT_FILE:
+          *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_FILE|
+                DF_NO_MORE_PMTS_THIS_FILE;
+          break;
+        default:
+          *_df_flags|=DF_DONT_MODIFIED|DF_ABORT_ALL_FILES|
+                DF_NO_MORE_PMTS_THIS_FILE;
+      }
+    }
+    if (*_df_flags & DF_REMAINDER_ALL_FILE2 &&
+          !(*_df_flags & (DF_DONT_MODIFIED|DF_REMAINDER_ALL_FILE1)))
+      use_file1=FALSE;
+    if (!use_file1) {
+      *_df_flags|=DF_MODIFIED;
+      doc_e1=doc_unsorted1[j1_lo]->last;
+      if (j1_lo<j1_hi) {
+        doc_e=doc_unsorted1[j1_lo];
+        while (doc_e!=doc_unsorted1[j1_hi]) {
+          doc_e2=doc_e->next;
+          DocEntryDel(doc,doc_e);
+          doc_e=doc_e2;
+        }
+      }
+      if (j2_lo<j2_hi) {
+        doc_e=doc_unsorted2[j2_lo];
+        while (doc_e!=doc_unsorted2[j2_hi]) {
+          doc_e2=DocEntryCopy(doc,doc_e);
+          QueIns(doc_e2,doc_e1);
+          doc_e1=doc_e2;
+          doc_e=doc_e->next;
+        }
+      }
+    }
+  }
+}
+
+Bool DiffSub(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,I64 j2_lo,I64 j2_hi,
+        I64 cnt1,I64 cnt2,CDocEntry **doc_sorted1,CDocEntry **doc_sorted2,
+        CDocEntry **doc_unsorted1,CDocEntry **doc_unsorted2)
+{
+  I64 i,i1=0,i2=0,i2b,j1,j2,n,
+        best_j1,best_j2,best_score=0,score;
+  Bool res=FALSE;
+
+  if (j1_lo>=j1_hi || j2_lo>=j2_hi) {
+    if (j1_lo<j1_hi || j2_lo<j2_hi) {
+      DiffSel(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,
+            doc_unsorted1,doc_unsorted2);
+      return TRUE;
+    } else
+      return FALSE;
+  }
+
+  //Locate longest matching str in intervals
+  while (i1<cnt1 && i2<cnt2) {
+    if (!(j1_lo<=doc_sorted1[i1]->user_data<j1_hi)) //user_data is the new y
+      i1++;
+    else if (!(j2_lo<=doc_sorted2[i2]->user_data<j2_hi)) //user_data is new y
+      i2++;
+    else {
+      i=StrCmp(doc_sorted1[i1]->tag,doc_sorted2[i2]->tag);
+      if (i>0)
+        i2++;
+      else if (i<0)
+        i1++;
+      else {
+        i2b=i2;
+        while (!StrCmp(doc_sorted1[i1]->tag,doc_sorted2[i2]->tag)) {
+          if (j2_lo<=doc_sorted2[i2]->user_data<j2_hi) {//user_data is the new y
+            score=0;
+            j1=doc_sorted1[i1]->user_data; //user_data is the new y
+            j2=doc_sorted2[i2]->user_data; //user_data is the new y
+            n=j1_hi-j1;
+            if (j2_hi-j2<n)
+              n=j2_hi-j2;
+            while (score<n) {
+              if (!StrCmp(doc_unsorted1[j1+score]->tag,
+                    doc_unsorted2[j2+score]->tag))
+                score++;
+              else
+                break;
+            }
+            if (score>best_score) {
+              best_score=score;
+              best_j1=j1;
+              best_j2=j2;
+            }
+          }
+          i2++;
+          if (i2>=cnt2)
+            break;
+        }
+        i2=i2b;
+        i1++;
+      }
+    }
+  }
+  if (!best_score) {
+    DiffSel(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,
+          doc_unsorted1,doc_unsorted2);
+    return TRUE;
+  } else {
+    if (DiffSub(doc,_df_flags,j1_lo,best_j1,j2_lo,best_j2,cnt1,cnt2,
+          doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2))
+      res=TRUE;
+    if (DiffSub(doc,_df_flags,best_j1+best_score,j1_hi,best_j2+best_score,
+          j2_hi,cnt1,cnt2,
+          doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2))
+      res=TRUE;
+    return res;
+  }
+}
+
+Bool DiffBins(CDoc *doc1,CDoc *doc2)
+{
+  CDocBin *tmpb1=doc1->bin_head.next,
+        *tmpb2=doc2->bin_head.next;
+
+  if (tmpb1->last->last->num!=tmpb2->last->last->num)
+    return TRUE;
+  while (tmpb1!=&doc1->bin_head) {
+    if (tmpb1->size!=tmpb2->size ||
+          MemCmp(tmpb1->data,tmpb2->data,tmpb1->size))
+      return TRUE;
+    tmpb1=tmpb1->next;
+    tmpb2=tmpb2->next;
+  }
+  return FALSE;
+}
+
+public Bool Diff(U8 *dst_file,U8 *src_file,I64 *_df_flags=NULL)
+{//Report differences between two files and merge differences
+//from src_file to dst_file.  Don't use _df_flags arg. (Used by Merge().)
+  CDoc *doc1=DocRead(dst_file,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR),
+        *doc2=DocRead(src_file,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e,**doc_sorted1,**doc_sorted2,**doc_unsorted1,**doc_unsorted2;
+  I64 i,cnt1=0,cnt2=0,df_flags;
+  Bool res=FALSE;
+
+  if (_df_flags)
+    df_flags=*_df_flags;
+  else
+    df_flags=0;
+  df_flags&=DF_ABORT_ALL_FILES;
+
+  doc_e=doc1->head.next;
+  while (doc_e!=doc1) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      doc_e->user_data=cnt1++; //user_data is the new y
+    doc_e=doc_e->next;
+  }
+
+  doc_e=doc2->head.next;
+  while (doc_e!=doc2) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      doc_e->user_data=cnt2++; //user_data is the new y
+    doc_e=doc_e->next;
+  }
+
+  doc_sorted1=MAlloc(cnt1*sizeof(CDocEntry *));
+  doc_unsorted1=MAlloc((cnt1+1)*sizeof(CDocEntry *));
+  i=0;
+  doc_e=doc1->head.next;
+  while (doc_e!=doc1) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      doc_sorted1[i]=doc_e;
+      doc_unsorted1[i++]=doc_e;
+    }
+    doc_e=doc_e->next;
+  }
+  doc_unsorted1[i]=doc1;
+  QSortI64(doc_sorted1,cnt1,&DiffEntriesCompare);
+
+  doc_sorted2=MAlloc(cnt2*sizeof(CDocEntry *));
+  doc_unsorted2=MAlloc((cnt2+1)*sizeof(CDocEntry *));
+  i=0;
+  doc_e=doc2->head.next;
+  while (doc_e!=doc2) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      doc_sorted2[i]=doc_e;
+      doc_unsorted2[i++]=doc_e;
+    }
+    doc_e=doc_e->next;
+  }
+  doc_unsorted2[i]=doc2;
+  QSortI64(doc_sorted2,cnt2,&DiffEntriesCompare);
+
+  res=DiffSub(doc1,&df_flags,0,cnt1,0,cnt2,cnt1,cnt2,
+        doc_sorted1,doc_sorted2,doc_unsorted1,doc_unsorted2);
+  if (df_flags&DF_MODIFIED && !(df_flags&DF_DONT_MODIFIED))
+    DocWrite(doc1);
+
+  if (DiffBins(doc1,doc2)) {
+    "$RED$Bin Data is Different$FG$\n";
+    res=TRUE;
+  }
+
+  DocDel(doc1);
+  DocDel(doc2);
+  Free(doc_sorted1);
+  Free(doc_sorted2);
+  Free(doc_unsorted1);
+  Free(doc_unsorted2);
+  if (_df_flags)
+    *_df_flags=df_flags;
+  return res;
+}
+
+#help_index "Cmd Line (Typically);Info"
+I64 ZRepCompare(CDirEntry *e1,CDirEntry *e2)
+{
+  return SignI64(e2->user_data(F64)-e1->user_data(F64));
+}
+public U0 ZipRep(U8 *files_find_mask="/*",U8 *fu_flags=NULL,
+  Bool just_text_not_graphics=TRUE)
+{//Report file compressibility.
+//Dft is just src files.  (Used to spot
+  //src files with redundancy in them.)
+  I64 i=0,cnt,size,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1,**sort_buf;
+  U8 *buf;
+  CArcCompress *arc;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+F+S");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  cnt=FileCnt(tmpde);
+  sort_buf=MAlloc(sizeof(CDirEntry *)*cnt);
+  while (tmpde) {
+    sort_buf[i++]=tmpde;
+    buf=FileRead(tmpde->full_name,&size);
+    if (just_text_not_graphics)
+      size=StrLen(buf);
+    arc=CompressBuf(buf,size);
+    Free(buf);
+    tmpde->user_data(F64)=100.0*arc->compressed_size/arc->expanded_size;
+    Free(arc);
+    tmpde=tmpde->next;
+  }
+  QSortI64(sort_buf,cnt,&ZRepCompare);
+  for (i=0;i<cnt;i++) {
+    "%4.1f%% %04X ",sort_buf[i]->user_data,sort_buf[i]->size;
+    PutFileLink(sort_buf[i]->full_name);
+    '\n';
+  }
+  Free(sort_buf);
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/DocUtils.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/DocUtils.HC.HTML new file mode 100755 index 0000000..1a9e676 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/DocUtils.HC.HTML @@ -0,0 +1,187 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Cmd Line (Typically)"
+
+U0 CursorRemFile(U8 *filename)
+{//Rem ASCII 5 cursor from one file.
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+  DocWrite(doc);
+  DocDel(doc);
+}
+public U0 CursorRem(U8 *files_find_mask="*")
+{//Rem ASCII 5 cursor.
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+T+f+F+O");
+  CDirEntry *tmpde=FilesFind(files_find_mask,fuf_flags),*tmpde1=tmpde;
+  while (tmpde) {
+    CursorRemFile(tmpde->full_name);
+    Touch(tmpde->full_name,"",,tmpde->datetime);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+U0 CollapseFile(U8 *filename,Bool collapse=TRUE)
+{//Collapse DolDoc trees in one file.
+  CDoc *doc=DocRead(filename,DOCF_NO_CURSOR);
+  DocCollapse(collapse,doc);
+  DocWrite(doc);
+  DocDel(doc);
+}
+public U0 Collapse(U8 *files_find_mask="*",
+        Bool collapse=TRUE,U8 *fu_flags=NULL)
+{//Collapse DolDoc trees.
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+$+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  CDirEntry *tmpde=FilesFind(files_find_mask,fuf_flags),*tmpde1=tmpde;
+  while (tmpde && !Bt(&fuf_flags,FUf_CANCEL)) {
+    CollapseFile(tmpde->full_name,collapse);
+    Touch(tmpde->full_name,"",,tmpde->datetime);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+I64 DocOptEntry(CDoc *,CDocEntry *doc_e,I64 fuf_flags)
+{
+  U8 *st,*st2,**_dst;
+  I64 i,res=0;
+
+  if (doc_e->de_flags&DOCEF_LINK && doc_e->de_flags&(DOCEF_AUX_STR|DOCEF_TAG)) {
+    if (doc_e->de_flags & DOCEF_AUX_STR && doc_e->de_flags & DOCEF_TAG &&
+          !MemCmp(doc_e->aux_str,"FI:",3) &&
+          !StrCmp(doc_e->aux_str+3,doc_e->tag)) {
+      Free(doc_e->aux_str);
+      doc_e->aux_str=NULL;
+      doc_e->de_flags&=~DOCEF_AUX_STR;
+      res++;
+    }
+    if (doc_e->de_flags & DOCEF_AUX_STR)
+      _dst=&doc_e->aux_str;
+    else
+      _dst=&doc_e->tag;
+    if (StrMatch(".Z",*_dst)) {
+      st=DocLinkFile(*_dst);
+      if (FileFind(st)) {
+        if (IsDotZ(st))
+          st[StrLen(st)-2]=0;
+        i=StrLen(st);
+        if ((st2=StrMatch(st,*_dst)) && st2[i]=='.' && st2[i+1]=='Z') {
+          StrCpy(st2+i,st2+i+2);
+          res++;
+        }
+      }
+      Free(st);
+    }
+    if (fuf_flags&FUF_RISKY) {
+      if (doc_e->de_flags & DOCEF_AUX_STR) {
+        if (st=StrMatch(".Z",doc_e->aux_str)) {
+          StrCpy(st,st+2);
+          res++;
+        }
+      }
+      if (doc_e->de_flags&DOCEF_TAG) {
+        if (st=StrMatch(".Z",doc_e->tag)) {
+          StrCpy(st,st+2);
+          res++;
+        }
+      }
+    }
+  }
+  return res;
+}
+I64 DocOptDoc(CDoc *doc,I64 fuf_flags)
+{//Optimize Doc.
+  Bool unlock=DocLock(doc);
+  I64 res=0;
+  CDocEntry *doc_e,*doc_e1,*doc_e_last;
+  DocRecalc(doc);
+  doc_e_last=NULL;
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (res+=DocOptEntry(doc,doc_e,fuf_flags))
+      res+=DocOptEntry(doc,doc_e,fuf_flags);
+    if (doc_e_last && doc_e_last->type&~0xFF00==doc_e->type&~0xFF00 &&
+       doc_e_last->de_flags==doc_e->de_flags &&
+       Bt(doldoc.type_flags_chk_dup,doc_e->type_u8) &&
+       doc_e_last->attr==doc_e->attr) {
+      DocEntryDel(doc,doc_e);
+      res++;
+    } else
+      doc_e_last=doc_e;
+    doc_e=doc_e1;
+  }
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+I64 DocOptFile(U8 *filename,I64 fuf_flags)
+{//Optimize file.
+  I64 res;
+  CDoc *doc=DocRead(filename);
+  if (res=DocOptDoc(doc,fuf_flags)) {
+    "-%d:%s\n",res,doc->filename.name;
+    DocWrite(doc);
+  }
+  DocDel(doc);
+  return res;
+}
+I64 DocOptLst(CDirEntry *tmpde,I64 fuf_flags)
+{
+  I64 res=0;
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      if (tmpde->sub) {
+        "Scanning Directory: %s\n",tmpde->full_name;
+        res+=DocOptLst(tmpde->sub,fuf_flags);
+      }
+    } else
+      res+=DocOptFile(tmpde->full_name,fuf_flags);
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+  return res;
+}
+public I64 DocOpt(U8 *files_find_mask="*",U8 *fu_flags=NULL)
+{//Optimize DolDoc files, eliminating aux_str's and .Z's.
+//+R flag for aggressively risky.
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+$");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  return DocOptLst(FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND),
+        fuf_flags&~FUG_FILES_FIND);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/Find.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/Find.HC.HTML new file mode 100755 index 0000000..0f97350 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/Find.HC.HTML @@ -0,0 +1,288 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+#define FND_REPLACE     0
+#define FND_SKIP        1
+#define FND_ALL         2
+#define FND_ED          3
+#define FND_ABORT_FILE  4
+#define FND_SKIP_FILE   5
+
+I64 PopUpFindMenu()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$CM+LX,2,4$$BT,\"REPLACE\",LE=FND_REPLACE$"
+        "$CM+LX,22,0$$BT,\"SKIP\",LE=FND_SKIP$"
+        "$CM+LX,2,4$$BT,\"ALL\",LE=FND_ALL$"
+        "$CM+LX,22,0$$BT,\"ABORT ALL\",LE=DOCM_CANCEL$"
+        "$CM+LX,2,4$$BT,\"EDIT\",LE=FND_ED$"
+        "$CM+LX,22,0$$BT,\"ABORT FILE\",LE=FND_ABORT_FILE$"
+        "$CM+LX,2,4$$BT,\"SKIP FILE\",LE=FND_SKIP_FILE$\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+I64 FindFile(U8 *needle_str,U8 *haystack_filename,
+        I64 *_fuf_flags,U8 *replace_text)
+{//Have you confused with FileFind()?
+  Bool first_on_line,write_this_file=FALSE,cont=!Bt(_fuf_flags,FUf_CANCEL);
+  U8 *src,*dst,*dst2,*name_buf=NULL;
+  I64 i,j,plen,rlen,dlen,cnt=0,old_flags,ss_flags;
+  CDoc *cur_l,*doc=DocRead(haystack_filename,
+        DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e;
+
+  if (Bt(_fuf_flags,FUf_IGNORE))
+    ss_flags=SFF_IGNORE_CASE;
+  else
+    ss_flags=0;
+  if (Bt(_fuf_flags,FUf_WHOLE_LABELS))
+    ss_flags|=SFG_WHOLE_LABELS;
+  if (Bt(_fuf_flags,FUf_WHOLE_LABELS_BEFORE))
+    ss_flags|=SFF_WHOLE_LABELS_BEFORE;
+  if (Bt(_fuf_flags,FUf_WHOLE_LABELS_AFTER))
+    ss_flags|=SFF_WHOLE_LABELS_AFTER;
+
+  plen=StrLen(needle_str);
+  if (replace_text)
+    rlen=StrLen(replace_text);
+  doc_e=doc->head.next;
+  while (doc_e!=doc && cont) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      src=doc_e->tag;
+      first_on_line=TRUE;
+      while (src && cont) {
+        if (src=StrFind(needle_str,src,ss_flags)) {
+          cnt++;
+          if (first_on_line || Bt(_fuf_flags,FUf_REPLACE)) {
+            first_on_line=FALSE;
+            PutFileLink(haystack_filename,,doc_e->y+1,TRUE);
+            name_buf=MStrPrint("%s,%d",haystack_filename,doc_e->y+1);
+            if (cur_l=DocPut) {
+              old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+              cur_l->flags|=DOCF_PLAIN_TEXT;
+            }
+            " %s\n",doc_e->tag;
+            if (cur_l)
+              cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+          }
+          if (Bt(_fuf_flags,FUf_REPLACE)) {
+            if (Bt(_fuf_flags,FUf_ALL))
+              i=FND_ALL;
+            else {
+              i=PopUpFindMenu;
+              if (i<0) {
+                LBts(_fuf_flags,FUf_CANCEL);
+                cont=FALSE;
+                write_this_file=FALSE;
+              } else if (i==FND_ALL)
+                LBts(_fuf_flags,FUf_ALL);
+              else if (i==FND_ABORT_FILE) {
+                cont=FALSE;
+                write_this_file=FALSE;
+              } else if (i==FND_SKIP_FILE)
+                cont=FALSE;
+            }
+            if (i==FND_REPLACE || i==FND_ALL) {
+              dlen=StrLen(doc_e->tag);
+              dst=MAlloc(dlen+1+rlen-plen);
+              dst2=dst;
+              j=src-doc_e->tag;
+              for (i=0;i<j;i++)
+                *dst++=doc_e->tag[i];
+              for (i=0;i<rlen;i++)
+                *dst++=replace_text[i];
+              src=dst;
+              for (i=j+plen;i<=dlen;i++)
+                *dst++=doc_e->tag[i];
+              Free(doc_e->tag);
+              doc_e->tag=dst2;
+              if (cur_l=DocPut) {
+                old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
+                cur_l->flags|=DOCF_PLAIN_TEXT;
+              }
+              "%12s,%04d*%s\n",haystack_filename,doc_e->y+1,dst2;
+              if (cur_l)
+                cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
+              write_this_file=TRUE;
+            } else {
+              src++;
+              if (i==FND_ED) {
+                Free(name_buf);
+                name_buf=StrNew(doc->filename.name);
+                doc->flags&=~DOCF_NO_CURSOR;
+                doc->cur_entry=doc_e;
+                doc->cur_col=doc_e->min_col;
+                DocWrite(doc);
+                DocDel(doc);
+                "Wrote:%s\n",name_buf;
+                Ed(name_buf);
+                doc=DocRead(name_buf, DOCF_PLAIN_TEXT_TABS);
+                doc_e=doc->cur_entry;
+                if (doc_e->last!=doc) doc_e=doc_e->last;
+                src=NULL;
+                write_this_file=FALSE;
+              }
+            }
+          } else
+            src++;
+          Free(name_buf);
+          name_buf=NULL;
+        }
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  if (write_this_file) {
+    DocWrite(doc);
+    "Wrote:%s\n",doc->filename.name;
+  }
+  DocDel(doc);
+  return cnt;
+}
+
+public I64 Find(U8 *needle_str,U8 *files_find_mask="*",
+        U8 *fu_flags=NULL,U8 *replace_text=NULL)
+{/*Find occurrences of a string in files.
+This does not do regular expressions.
+Anyway, it's good for searching and replacing.
+Let's say it stands for global replace ;-)
+
+"+r" =recurse
+"+i" =ignore case
+"+l" =whole labels only.
+This will check for a nonlabel character before
+and after.  If you have a var, "dd" and don't
+want to match words like "Add", you
+set this flag and it will see that the characters
+before or after "dd" are label characters.
+"+lb"=only checks for label chars before.
+"+la"=only checks for label chars after.
+*/
+  I64 cnt=0,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+i+f+F+T");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (fuf_flags&~(FUG_FILES_FIND|FUF_IGNORE|FUF_ALL|
+        FUF_WHOLE_LABELS|FUF_WHOLE_LABELS_BEFORE|FUF_WHOLE_LABELS_AFTER))
+    throw('FUF');
+  LBEqu(&fuf_flags,FUf_REPLACE,replace_text);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND);
+  fuf_flags&=FUF_ALL|FUF_REPLACE|FUF_IGNORE|FUF_WHOLE_LABELS|
+        FUF_WHOLE_LABELS_BEFORE|FUF_WHOLE_LABELS_AFTER;
+  while (tmpde && !Bt(&fuf_flags,FUf_CANCEL)) {
+    cnt+=FindFile(needle_str,tmpde->full_name,&fuf_flags,replace_text);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return cnt;
+}
+
+public I64 FileOcc(U8 *needle_str,
+        U8 *files_find_mask="*",U8 *fu_flags="+r+i+l")
+{/*Silently return occurrences of a string in files.
+"+r"=recurse
+"+i"=ignore case
+"+l"=whole labels only.
+"+lb"=only checks for label chars before.
+"+la"=only checks for label chars after.
+*/
+  I64 cnt=0;
+  Bool old_silent=Silent(TRUE);
+  cnt=Find(needle_str,files_find_mask,fu_flags);
+  Silent(old_silent);
+  return cnt;
+}
+
+class CFind
+{
+  U8    find_text[STR_LEN] format "$DA-P,"
+        "A=\"FIND        :%s\"$\n";
+  U8    replace_text[STR_LEN] format "$DA-P,"
+        "A=\"REPLACE     :%s\"$\n";
+  Bool  replace         format "$CB,\"REPLACE\"$\n";
+  Bool  match_case      format "$CB,\"MATCH CASE\"$\n";
+  Bool  whole_labels    format "$CB,\"WHOLE LABELS\"$\n";
+  U8    filemask[STR_LEN] format "$DA-P,A=\"FILE MASK   :%s\"$\n";
+  Bool  recurse         format "$CB,\"RECURSE\"$\n";
+};
+
+I64 FindWiz()
+{
+  CDoc *doc;
+  U8 buf[32],*dir,*st;
+  CFind *g=CAlloc(sizeof(CFind));
+  I64 res=0;
+  g->recurse=TRUE;
+  StrCpy(g->filemask,FILEMASK_TXT);
+  if (doc=DocPut) {
+    StrCpy(g->find_text,doc->find_replace->find_text);
+    StrCpy(g->replace_text,doc->find_replace->replace_text);
+    g->replace=doc->find_replace->replace;
+    g->match_case=doc->find_replace->match_case;
+    g->whole_labels=doc->find_replace->whole_labels;
+  }
+  if (DocForm(g,,0,"$PURPLE$$TX+CX,\"Find\"$\n$FG$")) {
+    if (doc) {
+      StrCpy(doc->find_replace->find_text,g->find_text);
+      StrCpy(doc->find_replace->replace_text,g->replace_text);
+      doc->find_replace->replace=g->replace;
+      doc->find_replace->match_case=g->match_case;
+      doc->find_replace->whole_labels=g->whole_labels;
+    }
+    dir=PopUpPickDir;
+    if (*dir) {
+      *buf=0;
+      if (g->match_case)
+        CatPrint(buf,"-i");
+      if (!g->recurse)
+        CatPrint(buf,"-r");
+      if (g->whole_labels)
+        CatPrint(buf,"+l");
+      if (g->replace)
+        st=MStrPrint("\"$$WW+H,1$$\";Cd(\"%s\");"
+              "Find(\"%Q\",\"%Q\",\"%Q\",\"%Q\");UserTaskCont;",
+              dir,g->find_text,g->filemask,buf,g->replace_text);
+      else
+        st=MStrPrint("\"$$WW+H,1$$\";Cd(\"%s\");"
+              "Find(\"%Q\",\"%Q\",\"%Q\");UserTaskCont;",
+              dir,g->find_text,g->filemask,buf);
+      res=PopUp(st);
+    }
+    Free(dir);
+  }
+  Free(g);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/HeapLog.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/HeapLog.HC.HTML new file mode 100755 index 0000000..9f1e398 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/HeapLog.HC.HTML @@ -0,0 +1,242 @@ + + + + + + + + + + + +
+#help_index "Debugging/Heap;Memory/Debugging"
+#help_file "::/Doc/HeapDbg"
+
+#define HL_CALLER_DEPTH 5 //Feel free to change this.
+#define HL_HASH_SIZE    0x1000
+
+class CHeapLog
+{
+  CHeapLog *next,*last;
+  union {
+    U8 *addr;
+    I64 size;
+  }
+  I64 cnt;
+  U8 *caller[HL_CALLER_DEPTH];
+};
+
+class CHeapLogHash
+{
+  CHeapLog *next,*last;
+};
+
+CHeapCtrl *heaplog_hc_watched,*heaplog_hc=NULL;
+CHeapLogHash *heaplog_head=NULL;
+
+U0 HeapLogMAlloc(U8 *addr)
+{
+  CHeapLog *tmphl;
+  I64 i;
+  if (MHeapCtrl(addr)==heaplog_hc_watched) {
+    tmphl=MAlloc(sizeof(CHeapLog),heaplog_hc);
+    tmphl->addr=addr;
+    for (i=0;i<HL_CALLER_DEPTH;i++)
+      tmphl->caller[i]=Caller(i+2);
+    i=addr>>3 &(HL_HASH_SIZE-1);
+    PUSHFD
+    CLI
+    while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+      PAUSE
+    QueIns(tmphl,heaplog_head[i].last);
+    LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+    POPFD
+  }
+}
+
+U0 HeapLogFree(U8 *addr)
+{
+  I64 i;
+  CHeapLog *tmphl;
+  if (!addr) return;
+  if (MHeapCtrl(addr)==heaplog_hc_watched) {
+    i=addr>>3 &(HL_HASH_SIZE-1);
+    PUSHFD
+    CLI
+    while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+      PAUSE
+    tmphl=heaplog_head[i].next;
+    while (tmphl!=&heaplog_head[i]) {
+      if (addr==tmphl->addr) {
+        QueRem(tmphl);
+        LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+        POPFD
+        Free(tmphl);
+        return;
+      }
+      tmphl=tmphl->next;
+    }
+    LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+    POPFD
+  }
+}
+
+public Bool HeapLog(Bool val=ON,CTask *task=NULL)
+{//Turn on.  Collect data.  Call HeapLogAddrRep() or  HeapLogSizeRep().
+  I64 i;
+  if (val) {
+    if (Bt(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+      "HeapLog Already Active\n";
+      return TRUE;
+    } else {
+      if (!task) task=Fs;
+      if (TaskValidate(task))
+        heaplog_hc_watched=task->data_heap;
+      else
+        heaplog_hc_watched=task;//Actually, not a task, must be a HeapCtrl.
+      PUSHFD
+      CLI
+      while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+        PAUSE
+      heaplog_hc=HeapCtrlInit(,,sys_data_bp);
+      ext[EXT_HEAPLOG_MALLOC]=&HeapLogMAlloc;
+      ext[EXT_HEAPLOG_FREE]=&HeapLogFree;
+      heaplog_head=MAlloc(sizeof(CHeapLogHash)*HL_HASH_SIZE,heaplog_hc);
+      for (i=0;i<HL_HASH_SIZE;i++)
+        QueInit(&heaplog_head[i]);
+      LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+      POPFD
+      LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);
+      return FALSE;
+    }
+  } else {
+    if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+      "HeapLog Not Active\n";
+      return FALSE;
+    } else {
+      HeapCtrlDel(heaplog_hc);
+      heaplog_head=heaplog_hc=NULL;
+      ext[EXT_HEAPLOG_MALLOC]=NULL;
+      ext[EXT_HEAPLOG_FREE]=NULL;
+      return TRUE;
+    }
+  }
+}
+
+public U0 HeapLogAddrRep(Bool leave_it=OFF)
+{//Call HeapLog() first and collect data.
+  I64 i,j,total=0;
+  CHeapLog *tmphl,hl;
+  if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+    "HeapLog Not Active\n";
+    return;
+  }
+  "$WW,0$";
+  while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+    PAUSE
+  for (i=0;i<HL_HASH_SIZE;i++) {
+    tmphl=heaplog_head[i].next;
+    while (tmphl!=&heaplog_head[i]) {
+//Take snapshot in case modified. (while we work)
+      MemCpy(&hl,tmphl,sizeof(CHeapLog));
+      "$PURPLE$%08X$FG$ %08X",MSize(hl.addr),hl.addr;
+      for (j=0;j<HL_CALLER_DEPTH;j++)
+        " %P",hl.caller[j];
+      '\n';
+      total+=MSize(hl.addr);
+      tmphl=hl.next;
+    }
+  }
+  LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+  "\n$LTRED$Total:%08X$FG$\n",total;
+  LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);
+  if (!leave_it)
+    HeapLog(OFF);
+}
+
+public U0 HeapLogSizeRep(Bool leave_it=OFF)
+{//Call HeapLog() first and collect data.
+  I64 i,j,k,total=0;
+  CHeapLog *tmphla,hla,*tmphls,*tmphls1;
+  CHeapLogHash *size_head;
+  if (!LBtr(&sys_semas[SEMA_HEAPLOG_ACTIVE],0)) {
+    "HeapLog Not Active\n";
+    return;
+  }
+
+  size_head=MAlloc(sizeof(CHeapLogHash)*HL_HASH_SIZE,heaplog_hc);
+  for (i=0;i<HL_HASH_SIZE;i++)
+    QueInit(&size_head[i]);
+
+  "$WW,0$";
+  while (LBts(&sys_semas[SEMA_HEAPLOG_LOCK],0))
+    PAUSE
+  for (i=0;i<HL_HASH_SIZE;i++) {
+    tmphla=heaplog_head[i].next;
+    while (tmphla!=&heaplog_head[i]) {
+//Take snapshot in case modified. (while we work)
+      MemCpy(&hla,tmphla,sizeof(CHeapLog));
+      k=(MSize(hla.addr)>>3+hla.caller[0])&(HL_HASH_SIZE-1);
+      tmphls=size_head[k].next;
+      while (tmphls!=&size_head[k]) {
+        if (MSize(hla.addr)==tmphls->size) {
+          for (j=0;j<HL_CALLER_DEPTH;j++)
+            if (hla.caller[j]!=tmphls->caller[j])
+              goto hl_next;
+          tmphls->cnt++;
+          goto hl_found;
+        }
+hl_next:
+        tmphls=tmphls->next;
+      }
+      tmphls=MAlloc(sizeof(CHeapLog),heaplog_hc);
+      MemCpy(tmphls,&hla,sizeof(CHeapLog));
+      tmphls->cnt=1;
+      tmphls->size=MSize(hla.addr);
+      QueIns(tmphls,size_head[k].last);
+hl_found:
+      tmphla=hla.next;
+    }
+  }
+  LBtr(&sys_semas[SEMA_HEAPLOG_LOCK],0);
+
+  for (i=0;i<HL_HASH_SIZE;i++) {
+    tmphls=size_head[i].next;
+    while (tmphls!=&size_head[i]) {
+      tmphls1=tmphls->next;
+      "%08X*%08X=%08X",tmphls->size,tmphls->cnt,tmphls->size*tmphls->cnt;
+      for (j=0;j<HL_CALLER_DEPTH;j++)
+        " %P",tmphls->caller[j];
+      '\n';
+      total+=tmphls->size*tmphls->cnt;
+      Free(tmphls);
+      tmphls=tmphls1;
+    }
+  }
+  Free(size_head);
+
+  "\n$LTRED$Total:%08X$FG$\n",total;
+  LBts(&sys_semas[SEMA_HEAPLOG_ACTIVE],0);
+  if (!leave_it)
+    HeapLog(OFF);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/LineRep.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/LineRep.HC.HTML new file mode 100755 index 0000000..ac646b8 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/LineRep.HC.HTML @@ -0,0 +1,140 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+I64 LineRep1(CDirEntry *tmpde)
+{
+  CDoc *doc;
+  I64 res=0,i;
+  while (tmpde) {
+    i=0;
+    if (tmpde->attr&RS_ATTR_DIR)
+      i=LineRep1(tmpde->sub);
+    else {
+      doc=DocRead(tmpde->full_name);
+      if (doc->head.next!=doc)
+        i=doc->head.last->y+2;
+      DocDel(doc);
+    }
+    tmpde->user_data=i;
+    res+=i;
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+U0 LineRep2(CDoc *doc,CDirEntry *tmpde)
+{
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR) {
+      DocPrint(doc,"%8,d $TR+C,\"%s\"$\n$ID,2$",tmpde->user_data,tmpde->name);
+      LineRep2(doc,tmpde->sub);
+      DocPrint(doc,"$ID,-2$");
+    } else
+      DocPrint(doc,"%8,d $LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->user_data,tmpde->name,tmpde->full_name);
+    tmpde=tmpde->next;
+  }
+}
+public I64 LineRep(U8 *files_find_mask="/*",U8 *fu_flags=NULL)
+{//Source line-of-code count report.
+  I64 fuf_flags=0,res=0;
+  CDoc *doc=DocNew;
+  CDirEntry *tmpde1=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+S");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (tmpde1=FilesFind(files_find_mask,fuf_flags)) {
+    res=LineRep1(tmpde1);
+    DocPrint(doc,"%8,d $TR+C,\"%s\"$\n$ID,2$",res,files_find_mask);
+    LineRep2(doc,tmpde1);
+    DocPrint(doc,"$ID,-2$");
+    DirTreeDel(tmpde1);
+  }
+  DocInsDoc(DocPut,doc);
+  DocDel(doc);
+  return res;
+}
+
+I64 SizeRep1(CDirEntry *tmpde,I64 *_fuf_flags)
+{
+  I64 res=0,i;
+  U8 buf[BLK_SIZE];
+  CDrv *dv;
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR)
+      i=SizeRep1(tmpde->sub,_fuf_flags);
+    else if ((i=tmpde->size) && Bt(_fuf_flags,FUf_EXPAND) &&
+          FileAttr(tmpde->name)&RS_ATTR_COMPRESSED) {
+      dv=Let2Drv(*tmpde->full_name);
+      BlkRead(dv,buf,Clus2Blk(dv,tmpde->clus),1);
+      i=(&buf)(CArcCompress *)->expanded_size;
+    }
+    tmpde->user_data=i;
+    res+=i;
+    tmpde=tmpde->next;
+  }
+  return res;
+}
+U0 SizeRep2(CDoc *doc,CDirEntry *tmpde)
+{
+  while (tmpde) {
+    if (tmpde->attr&RS_ATTR_DIR) {
+      DocPrint(doc,"%10,d $TR+C,\"%s\"$\n$ID,2$",
+            tmpde->user_data,tmpde->name);
+      SizeRep2(doc,tmpde->sub);
+      DocPrint(doc,"$ID,-2$");
+    } else {
+      DocPrint(doc,"%10,d ",tmpde->user_data);
+      DocPrint(doc,"$LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->name,tmpde->full_name);
+    }
+    tmpde=tmpde->next;
+  }
+}
+public I64 SizeRep(U8 *files_find_mask="/*",U8 *fu_flags=NULL)
+{//Report file sizes. "+x" for expanded size of compressed files.
+  I64 fuf_flags=0,res=0;
+  CDoc *doc=DocNew;
+  CDirEntry *tmpde1=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND)) {
+    fuf_flags&=FUF_EXPAND;
+    res=SizeRep1(tmpde1,&fuf_flags);
+    DocPrint(doc,"%10,d $TR+C,\"%s\"$\n$ID,2$",res,files_find_mask);
+    SizeRep2(doc,tmpde1);
+    DocPrint(doc,"$ID,-2$");
+    DirTreeDel(tmpde1);
+  }
+  DocInsDoc(DocPut,doc);
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/LinkChk.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/LinkChk.HC.HTML new file mode 100755 index 0000000..e36417e --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/LinkChk.HC.HTML @@ -0,0 +1,110 @@ + + + + + + + + + + + +
+#help_index "Debugging;Cmd Line (Typically)"
+
+I64 LinkChkDoc(CDoc *doc,I64 *_fuf_flags)
+{
+  U8 *st;
+  Bool found,unlock=DocLock(doc);
+  CDoc *old_doc;
+  CDocEntry *doc_e=doc->head.next;
+  I64 res=0;
+  while (doc_e!=doc) {
+    if (ScanKey) {
+      LBts(_fuf_flags,FUf_CANCEL);
+      break;
+    }
+    if (st=DocEntryLink(doc,doc_e)) {
+      old_doc=DocPut;
+      DocLock(old_doc);
+      Fs->put_doc=doc;
+      found=DocLinkChk(doc,st);
+      Fs->put_doc=old_doc;
+      DocUnlock(old_doc);
+      if (!found) {
+        PutFileLink(doc->filename.name,,doc_e->y);
+        "$RED$ %04d:%s\n$FG$",doc_e->y,st;
+        res++;
+      }
+      Free(st);
+    } else if (doc_e->type_u8==DOCT_ERROR) {
+      PutFileLink(doc->filename.name,,doc_e->y);
+      "$RED$ Doc Error\n$FG$";
+      res++;
+    }
+    doc_e=doc_e->next;
+  }
+  if (unlock) DocUnlock(doc);
+  return res;
+}
+
+I64 LinkChkFile(U8 *filename,I64 *_fuf_flags)
+{
+  I64 res;
+  CDoc *doc=DocRead(filename,DOCF_NO_CURSOR);
+  res=LinkChkDoc(doc,_fuf_flags);
+  DocDel(doc);
+  return res;
+}
+public I64 LinkChk(U8 *files_find_mask="/*",U8 *fu_flags=NULL)
+{//Check documents for broken file links.
+  I64 fuf_flags=0,res=0;
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st;
+  progress2_max=1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+$+f+F+O");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde && !Bt(&fuf_flags,FUf_CANCEL)) {
+
+    st=MStrPrint("Before %s Broke:%d",tmpde->full_name,res);
+    if (StrLen(st)>PROGRESS_DESC_LEN-1)
+      st[PROGRESS_DESC_LEN-1]=0;
+    StrCpy(progress2_desc,st);
+    Free(st);
+    Yield;
+
+    res+=LinkChkFile(tmpde->full_name,&fuf_flags);
+
+    st=MStrPrint("After %s Broke:%d",tmpde->full_name,res);
+    if (StrLen(st)>PROGRESS_DESC_LEN-1)
+      st[PROGRESS_DESC_LEN-1]=0;
+    StrCpy(progress2_desc,st);
+    Free(st);
+    Yield;
+
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  progress2_max=0;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/MakeUtils.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/MakeUtils.HC.HTML new file mode 100755 index 0000000..c570100 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/MakeUtils.HC.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Diff"
+#include "Find"
+#include "HeapLog"
+#include "LineRep"
+#include "LinkChk"
+#include "MemRep"
+#include "Merge"
+#include "Profiler"
+#include "StrUtils"
+#include "DocUtils"
+#include "ToDolDoc"
+#include "ToTXT"
+#include "TOS"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/MemRep.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/MemRep.HC.HTML new file mode 100755 index 0000000..a48593e --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/MemRep.HC.HTML @@ -0,0 +1,262 @@ + + + + + + + + + + + +
+#help_index "Info;Memory/Info;Cmd Line (Typically)"
+
+I64 TSSSize(CTSS *tss)
+{
+  return MSize2(tss)+MSize2(tss->st0)+MSize2(tss->st1)+MSize2(tss->st2);
+}
+
+I64 PenBrushesSize()
+{
+  I64 res=0,i;
+  for (i=0;i<GR_PEN_BRUSHES_NUM;i++)
+    res+=DCSize(gr.pen_brushes[i])+DCSize(gr.collision_pen_brushes[i])+
+          DCSize(gr.even_pen_brushes[i])+DCSize(gr.odd_pen_brushes[i]);
+  return res;
+}
+
+I64 ScrnZoomTablesSize()
+{
+  I64 res=0,i;
+  for (i=1;i<=GR_SCRN_ZOOM_MAX;i++)
+    res+=MSize2(gr.scrn_zoom_tables[i]);
+  return res;
+}
+
+I64 TaskStkSize(CTask *task)
+{
+  CTaskStk *tmps=task->stk;
+  I64 res=0;
+  while (tmps) {
+    res+=MSize2(tmps);
+    tmps=tmps->next_stk;
+  }
+  return res;
+}
+
+I64 TaskQueSize(CTask *task)
+{
+  CJob *tmpc,*tmpc1;
+  I64 res=0;
+  PUSHFD
+  CLI
+  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+
+  tmpc1=&task->srv_ctrl.next_waiting;
+  tmpc=tmpc1->next;
+  while (tmpc!=tmpc1) {
+    res+=MSize2(tmpc)+MSize2(tmpc->aux_str);
+    tmpc=tmpc->next;
+  }
+
+  tmpc1=&task->srv_ctrl.next_done;
+  tmpc=tmpc1->next;
+  while (tmpc!=tmpc1) {
+    res+=MSize2(tmpc)+MSize2(tmpc->aux_str);
+    tmpc=tmpc->next;
+  }
+
+  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  POPFD
+  return res;
+}
+
+I64 BlkDevsSize()
+{
+  I64 i,j,res=MSize2(blkdev.blkdevs);
+  CBlkDev *bd;
+  for (i=0;i<BLKDEVS_NUM;i++) {
+    bd=&blkdev.blkdevs[i];
+    if (bd->bd_signature==BD_SIGNATURE_VAL) {
+      j=(bd->max_blk+1)<<BLK_SIZE_BITS;
+      if (bd->type==BDT_RAM)
+        "RAMDsk %C\t:%010X/%010X\n",
+              bd->first_drv_let,j-DrvUnused(bd->first_drv_let),j;
+      res+=MSize2(bd->dev_id_record);
+    }
+  }
+  return res;
+}
+
+I64 DrvsSize()
+{
+  I64 i,res=MSize2(blkdev.drvs);
+  for (i=0;i<DRVS_NUM;i++)
+    res+=MSize2(blkdev.drvs[i].cur_fat_blk)+MSize2(blkdev.drvs[i].fis);
+  return res;
+}
+
+Bool MemRepTask(CTask *task,Bool override_validate=FALSE)
+{
+  I64 i,j,k,m,n;
+  CDoc *pdoc,*ddoc,*bdoc;
+  CCmpCtrl *cc;
+  CMathODE *o;
+  CCPU *c;
+  CTask *task1;
+
+  if (!override_validate && !TaskValidate(task))
+    return FALSE;
+  if (task==Fs)
+    task->rsp=GetRSP;
+  "$BLACK$%-27t$Q#%08X$FG$\n",task->task_title,task;
+  "$ID,2$Heap\t:%010X/%010X\n",TaskMemUsed(task,override_validate),
+        TaskMemAlloced(task,override_validate);
+
+  i=UnusedStk(task);
+  j=TaskStkSize(task);
+  if (0<=i<=task->stk->stk_size)
+    "Stk\t\t:%010X/%010X\n",j-i,j;
+  else
+    "Stk\t\t:$RED$$BK,1$Overflow$BK,0$$FG$/%010X\n",j;
+
+  "HashTable\t:%010X\n",HashTableSize2(task->hash_table);
+  "FPU\t\t:%010X\n",MSize2(task->fpu_mmx);
+  "DirCur\t:%010X\n",MSize2(task->cur_dir);
+
+  if (pdoc=DocPut(task))
+    "PutDoc\t:%010X\n",DocSize(pdoc);
+  if ((ddoc=DocDisplay(task)) && pdoc!=ddoc)
+    "DisplayDoc\t:%010X\n",DocSize(ddoc);
+  if (bdoc=DocBorder(task))
+    "BorderDoc\t:%010X\n",DocSize(bdoc);
+
+  cc=task->next_cc;
+  while (cc!=&task->next_cc) {
+    "CmpCtrl\t:%010X\n",CmpCtrlSize(cc);
+    cc=cc->next;
+  }
+
+  o=task->next_ode;
+  while (o!=&task->next_ode) {
+    "CMathODE\t:%010X\n",ODESize(o);
+    o=o->next;
+  }
+
+  if (task==sys_winmgr_task) {
+    "gr.pen_brushes\t:%010X\n",PenBrushesSize;
+    "gr.scrn_zoom_tbles\t:%010X\n",ScrnZoomTablesSize;
+    "scrncast.dc\t:%010X\n",DCSize(scrncast.dc);
+    "scrncast.dc2_alias\t:%010X\n",DCSize(scrncast.dc2_alias);
+  } else if (task==adam_task) {
+    j=0;k=0;m=0;n=0;
+    for (i=0;i<mp_cnt;i++) {
+      c=&cpu_structs[i];
+      k+=TSSSize(c->tss);
+      task1=c->seth_task;
+      do {
+        if (task1!=adam_task) {//adam task located in Kernel mem
+          j+=MSize2(task1);
+          m+=MSize2(task1->code_heap);
+          if (task1->data_heap!=task1->code_heap)
+            m+=MSize2(task1->code_heap);
+        }
+        n+=TaskQueSize(task1);
+        task1=task1->next_task;
+      } while (task1!=c->seth_task);
+      task1=c->idle_task;
+      j+=MSize2(task1);
+      m+=MSize2(task1->code_heap);
+      if (task1->data_heap!=task1->code_heap)
+        m+=MSize2(task1->code_heap);
+    }
+    "TaskStructs\t:%010X\n",j;
+    "TSSes\t:%010X\n",k;
+    "HeapCtrls\t:%010X\n",m;
+    if (n)
+      "TaskQues\t:%010X\n",n;
+    "BlkDevs\t:%010X\n",BlkDevsSize;
+    "Drvs\t:%010X\n",DrvsSize;
+    if (blkdev.cache_base)
+      "DskCache\t:%010X\n",
+            MSize2(blkdev.cache_base)+MSize2(blkdev.cache_hash_table)+
+            MSize2(blkdev.cache_ctrl);
+    "Clip\t:%010X\n",DocSize(sys_clip_doc);
+    "AutoComplete:%010X\n",CallExtStr("AutoCompleteSize");
+    "gr.to_8_bits\t:%010X\n",MSize2(gr.to_8_bits);
+    "gr.to_8_colors\t:%010X\n",MSize2(gr.to_8_colors);
+    "gr.text_base\t:%010X\n",MSize2(gr.text_base);
+    "gr.vga_text_cache\t:%010X\n",MSize2(gr.vga_text_cache);
+    "gr.win_z_buf\t:%010X\n",MSize2(gr.win_z_buf)+
+          MSize2(gr.win_uncovered_bitmap);
+    "gr.dc\t\t:%010X\n",DCSize(gr.dc);
+    "gr.dc1\t\t:%010X\n",DCSize(gr.dc1);
+    "gr.dc2\t\t:%010X\n",DCSize(gr.dc2);
+    "gr.dc_cache\t\t:%010X\n",DCSize(gr.dc_cache);
+    "gr.scrn_image\t:%010X\n",DCSize(gr.scrn_image);
+    "gr.zoomed_dc\t:%010X\n",DCSize(gr.zoomed_dc);
+  }
+  "$ID,-2$";
+  return TRUE;
+}
+
+public U0 MemRep()
+{//Memory usage report.
+  I64 i;
+  CTask *task;
+  CCPU *c;
+  CBinFile *bfh=mem_boot_base-sizeof(CBinFile);
+  bfh(I64)+=bfh->file_size-1;
+
+  "$BLACK$Low Memory\t:0000100000$FG$\n$ID,2$";
+  "Kernel\t:%010X-%010X\n",mem_boot_base-sizeof(CBinFile),bfh;
+
+  "VGA\t\t:00000A0000-00000BFFFF\n";
+  "$ID,-2$$BLACK$High Memory\t:0000100000-%010X$FG$\n",
+        mem_heap_limit;
+  "SYS_FIXED_AREA\t:%010X-%010X\n",
+        SYS_FIXED_AREA,SYS_FIXED_AREA+sizeof(CSysFixedArea)-1;
+
+  if (sys_data_bp) {
+    "$BLACK$Code Heap\t:%010X/%010X$FG$\n",
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s;
+    "$BLACK$Data Heap\t:%010X/%010X$FG$\n",
+          sys_data_bp->used_u8s,sys_data_bp->alloced_u8s;
+  } else
+    "$BLACK$Code/Data Heap\t:%010X/%010X$FG$\n",
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s;
+
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    "$PURPLE$CPU%d$FG$\n$ID,2$",i;
+    task=c->seth_task;
+    do {
+      if (!MemRepTask(task))
+        break;
+      task=task->next_task;
+    } while (task!=c->seth_task);
+    MemRepTask(c->idle_task,TRUE);
+    "$ID,-2$";
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/Merge.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/Merge.HC.HTML new file mode 100755 index 0000000..a4b2059 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/Merge.HC.HTML @@ -0,0 +1,108 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+CDirEntry MGFind(CDirEntry *needle_entry,CDirEntry *haystack_lst)
+{
+  while (haystack_lst) {
+    if (!StrCmp(needle_entry->name,haystack_lst->name))
+      return haystack_lst;
+    haystack_lst=haystack_lst->next;
+  }
+  return NULL;
+}
+
+U0 Merge2(CDirEntry *tmpde1,CDirEntry *tmpde2,I64 *_fuf_flags,I64 *_df_flags)
+{
+  CDirEntry *tmpde;
+  while (tmpde1 && !(*_df_flags & DF_ABORT_ALL_FILES)) {
+    tmpde=MGFind(tmpde1,tmpde2);
+    if (!tmpde)
+      "$BROWN$Does Not Exist:%s$FG$\n",tmpde1->full_name;
+    else {
+      if (tmpde1->attr & RS_ATTR_DIR)
+        Merge2(tmpde1->sub,tmpde->sub,_fuf_flags,_df_flags);
+      else {
+        if (AbsI64(tmpde1->datetime-tmpde->datetime)>CDATE_FREQ*2) {//slop
+          "%s",tmpde1->full_name;
+          '\n';
+          if (Bt(_fuf_flags,FUf_DIFF)) {
+            if (FilesFindMatch(tmpde1->full_name,FILEMASK_TXT))
+              Diff(tmpde->full_name,tmpde1->full_name,_df_flags);
+          }
+        }
+      }
+    }
+    tmpde1=tmpde1->next;
+  }
+}
+public U0 Merge(U8 *dst_files_find_mask="/*",U8 *src_files_find_mask="/*",
+  U8 *fu_flags=NULL)
+{/*Merge text files from one list into another.
+Report files whos date/time is different.
+
+"+d" will do Diff() on files and prompt to
+merge changes from source files into
+destination files.
+*/
+  I64 df_flags=0,fuf_flags=0;
+  CDirEntry *tmpde1=NULL,*tmpde2=NULL;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  if (fuf_flags&~(FUG_FILES_FIND|FUF_DIFF))
+    throw('FUF');
+  PrintWarn("This is based strictly on file dates.\n");
+  tmpde1=FilesFind(src_files_find_mask,fuf_flags&FUG_FILES_FIND);
+  tmpde2=FilesFind(dst_files_find_mask,fuf_flags&FUG_FILES_FIND);
+  fuf_flags&=FUF_DIFF;
+  Merge2(tmpde1,tmpde2,&fuf_flags,&df_flags);
+  DirTreeDel(tmpde1);
+  DirTreeDel(tmpde2);
+}
+
+#help_index "Utils;Cmd Line (Typically)"
+
+public U0 NewFiles(U8 *files_find_mask="/*",CDate cdt=0,U8 *fu_flags=NULL)
+{//Report files newer than a certain date.
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  if (!cdt) cdt=sys_compile_time;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (tmpde->datetime>cdt)
+      "%s\n",tmpde->full_name;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/Profiler.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/Profiler.HC.HTML new file mode 100755 index 0000000..33a7b46 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/Profiler.HC.HTML @@ -0,0 +1,133 @@ + + + + + + + + + + + +
+#help_index "Debugging/Profiler;Profiler;Cmd Line (Typically)/Profiler"
+#help_file "::/Doc/Profiler"
+
+#define PF_ARRAY_CNT 0x100000
+I64 pf_jiffy_start,pf_jiffy_end;
+I64 *pf_array=NULL;
+I64 pf_cpu=0;
+I64 pf_buf_in_ptr=0,pf_depth;
+I64 pf_prof_active=0;
+
+U0 ProfTimerInt(CTask *task)
+{//See profiler_timer_irq.
+  I64 i,k;
+  if (Bt(&pf_prof_active,0))
+    for (k=0;k<=pf_depth;k++) {
+      if (task==Gs->idle_task)
+        i=SYS_IDLE_PT;
+      else
+        i=TaskCaller(task,k,TRUE);
+      if (pf_buf_in_ptr<PF_ARRAY_CNT) {
+        pf_array[pf_buf_in_ptr++]=i;
+        pf_jiffy_end=cnts.jiffies;
+      }
+    }
+}
+
+public U0 Prof(I64 depth=0,I64 cpu_num=0)
+{/*Start collecting profiler statistics.
+Profilers report where time is spent
+by sampling RIP during the 1000Hz
+timer interrupt.
+
+Do a ProfRep(), (profiler report)
+after you have collected data.
+*/
+  if (!(0<=cpu_num<mp_cnt))
+    ST_ERR_ST "Invalid CPU\n";
+  else {
+    cpu_structs[pf_cpu].profiler_timer_irq=NULL;
+    pf_cpu=cpu_num;
+
+    pf_depth=depth;
+    pf_buf_in_ptr=0;
+    if (!pf_array)
+      pf_array=AMAlloc(sizeof(I64)*PF_ARRAY_CNT);
+    pf_jiffy_end=pf_jiffy_start=cnts.jiffies;
+    LBts(&pf_prof_active,0);
+    cpu_structs[pf_cpu].profiler_timer_irq=&ProfTimerInt;
+  }
+}
+
+I64 ProfCompare(U8 *i1,U8 *i2)
+{
+  return i1-i2;
+}
+
+public U0 ProfRep(I64 filter_cnt=1,Bool leave_it=OFF)
+{//Profiler report. Call Prof() first and collect data.
+  I64 i,hits,rip,last_rip=0,routine_total=0;
+  F64 total_time;
+  U8 buf[256],buf2[256],last_buf[256];
+  if (!LBtr(&pf_prof_active,0))
+    "Profiler Not Active\n";
+  if (!pf_buf_in_ptr)
+    "No Profiler Statistic\n";
+  else {
+    if (!(total_time=pf_jiffy_end-pf_jiffy_start))
+      total_time=1;
+    QSortI64(pf_array,pf_buf_in_ptr,&ProfCompare);
+    *last_buf=0;
+    for (i=0;i<pf_buf_in_ptr;i+=hits) {
+      rip=pf_array[i];
+      hits=0;
+      do hits++;
+      while (i+hits<pf_buf_in_ptr && pf_array[i+hits]==rip);
+
+      StrPrint(buf,"%p",rip);
+      StrFirstRem(buf,"+",buf2);
+      if (StrCmp(buf2,last_buf)) {
+        if (*last_buf && routine_total>=filter_cnt)
+          "$GREEN$%6.2f %08X:%s\n$FG$",100*routine_total/total_time,
+                routine_total,last_buf;
+        StrCpy(last_buf,buf2);
+        routine_total=0;
+      }
+      routine_total+=hits;
+      if (hits>=filter_cnt) {
+        "%6.2f %08X:%P\n",100*hits/total_time,hits,rip;
+        last_rip=rip;
+      }
+    }
+    if (*last_buf && routine_total>=filter_cnt)
+      "$GREEN$%6.2f %08X:%s\n$FG$",100*routine_total/total_time,
+            routine_total,last_buf;
+    "Total Time:%0.6fs\n",total_time/JIFFY_FREQ;
+    if (leave_it) {
+      cpu_structs[pf_cpu].profiler_timer_irq=&ProfTimerInt;
+      LBts(&pf_prof_active,0);
+    } else
+      cpu_structs[pf_cpu].profiler_timer_irq=NULL;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/StrUtils.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/StrUtils.HC.HTML new file mode 100755 index 0000000..07755d0 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/StrUtils.HC.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+I64 DEPtrCompare(CDocEntry **e1,CDocEntry **e2)
+{
+  return StrCmp((*e1)->tag,(*e2)->tag);
+}
+
+public I64 Sort(U8 *_in_name,U8 *_out_name=NULL,
+        I64 entry_lines=1,Bool unique=FALSE)
+{//Sort lines of a text file. Removes blank lines.
+  U8 *in_name,*out_name,*st;
+  CDoc *doc;
+  CDocEntry *doc_e,*doc_e1,**a;
+  I64 i,j,cnt=0,res;
+
+  if (!_in_name) return 0;
+  in_name=ExtDft(_in_name,"DD.Z");
+  if (_out_name)
+    out_name=ExtDft(_out_name,"DD.Z");
+  else
+    out_name=StrNew(in_name);
+
+  doc=DocRead(in_name,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT)
+      cnt++;
+    doc_e=doc_e->next;
+  }
+  a=MAlloc(cnt*sizeof(CDocEntry *));
+  doc_e=doc->head.next;
+  i=0;
+  while (doc_e!=doc) {
+    doc_e1=doc_e->next;
+    if (doc_e->type_u8==DOCT_TEXT) {
+      QueRem(doc_e);
+      a[i++]=doc_e;
+    } else
+      DocEntryDel(doc,doc_e);
+    doc_e=doc_e1;
+  }
+  QSort(a,cnt/entry_lines,entry_lines*sizeof(CDocEntry *),&DEPtrCompare);
+
+  res=0;
+  st=NULL;
+  for (i=0;i<cnt;) {
+    if (!unique || !st || StrCmp(a[i]->tag,st)) {
+      st=a[i]->tag;
+      for (j=0;j<entry_lines && i<cnt;j++,i++) {
+        QueIns(a[i],doc->head.last);
+        doc->cur_entry=&doc->head;
+        doc->cur_col=0;
+        DocPrint(doc,"\n");
+      }
+      res++;
+    } else
+      for (j=0;j<entry_lines && i<cnt;j++,i++) {
+        QueIns(a[i],doc->head.last);
+        DocEntryDel(doc,a[i]);
+      }
+  }
+  StrCpy(doc->filename.name,out_name);
+  DocWrite(doc);
+
+  Free(a);
+  DocDel(doc);
+  Free(in_name);
+  Free(out_name);
+  return res; //Num Entries
+}
+
+I64 DocWordsFile(CDoc *doc_out=NULL,U8 *filename,U32 *char_bmp)
+{
+  U8 *ptr,*ptr2;
+  I64 res=0,ch;
+  CDoc *doc_in=DocRead(filename);
+  CDocEntry *doc_e=doc_in->head.next;
+  while (doc_e!=doc_in) {
+    if (doc_e->de_flags & DOCEF_TAG) {
+      ptr=doc_e->tag;
+      while (*ptr) {
+        while (*ptr && !Bt(char_bmp,*ptr))
+          ptr++;
+
+        ptr2=ptr;
+        while (*ptr && Bt(char_bmp,*ptr))
+          ptr++;
+
+        ch=*ptr;
+        *ptr=0;
+        if (*ptr2) {
+          DocPrint(doc_out,"%s\n",ptr2);
+          res++;
+        }
+        *ptr=ch;
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc_in);
+  return res;
+}
+public I64 Words(U8 *files_find_mask="*",U32 *char_bmp=char_bmp_alpha,
+        U8 *fu_flags=NULL)
+{//Break file into list of not-unique words.
+  I64 fuf_flags=0,res=0;
+  CDoc *doc_out=DocNew;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+T");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    res+=DocWordsFile(doc_out,tmpde->full_name,char_bmp);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  DocInsDoc(NULL,doc_out);
+  DocDel(doc_out);
+  return res;
+}
+
+I64 LongLinesFile(U8 *filename,I64 cols)
+{
+  I64 res=0;
+  CDoc *doc=DocRead(filename);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_NEW_LINE && doc_e->x>=cols+1)
+      res++;
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+  if (res) {
+    "%04d ",res;
+    PutFileLink(filename);
+    '\n';
+  }
+  return res;
+}
+public I64 LongLines(U8 *files_find_mask="*",I64 cols=80,U8 *fu_flags=NULL)
+{//Report files with lines of too many cols.
+  I64 res=0,fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+S");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    if (LongLinesFile(tmpde->full_name,cols))
+      res++;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return res;
+}
+
+U0 SUFile(U8 *filename,I64 suf_flags,F64 indent_scale_factor)
+{//String utility on a single file
+//See SU Flags
+  U8 *dst;
+  Bool chged=FALSE;
+  I64 reduced=0;
+  CDoc *doc=DocRead(filename,DOCF_PLAIN_TEXT_TABS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      dst=MStrUtil(doc_e->tag,suf_flags,indent_scale_factor);
+      if (StrCmp(dst,doc_e->tag)) {
+        reduced+=StrLen(doc_e->tag)-StrLen(dst);
+        chged=TRUE;
+        Free(doc_e->tag);
+        doc_e->tag=dst;
+      } else
+        Free(dst);
+    }
+    doc_e=doc_e->next;
+  }
+  if (chged) {
+    "Reduced %s by %d chars\n",filename,reduced;
+    DocWrite(doc);
+  }
+  DocDel(doc);
+}
+public U0 SU(U8 *files_find_mask,I64 suf_flags,U8 *fu_flags=NULL,
+        F64 indent_scale_factor=0)
+{//Apply StrUtil() on files.
+//You can convert spaces to tabs, for example,
+  //or removing trailing spaces on lines.
+  //See SUF Flags.
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F+T");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    SUFile(tmpde->full_name,suf_flags,indent_scale_factor);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+public U0 S2T(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Spaces to tabs.
+//Use "Hard Space" (SHIFT-SPACE) for spaces
+  //in string consts in your code.
+  SU(files_find_mask,SUF_S2T|SUF_REM_TRAILING,fu_flags);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/TOS.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/TOS.HC.HTML new file mode 100755 index 0000000..67cdb2d --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/TOS.HC.HTML @@ -0,0 +1,107 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS"
+
+U0 TOSStaffIns()
+{//Completes TOS install from TOS_Staff.ISO
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  "$PURPLE$$TX+CX,\"Complete TOS install from TOS_Staff.ISO\"$$FG$\n\n\n\n";
+  InsRereg;
+
+  "\nDownload TOS_Supplemental1.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental2.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental3.ISO.C\tfrom http://www.templeos.org\n";
+
+  if (PressAKey!=CH_SHIFT_ESC) {
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental1.ISO.C"))
+      CopyTree("T:/","~/Sup1");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental2.ISO.C"))
+      CopyTree("T:/","~/Sup2");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental3.ISO.C"))
+      CopyTree("T:/","~/Sup3");
+
+    Once("TOSBootHDIns;");
+    "\nDo you wish to run >TOSRegen; to generate\n the "
+          "distro ISO's ";
+    if (YorN) {
+      Once("TOSRegen;");
+      BootRAM("C:/" KERNEL_BIN_C); //Boot so TOSRegen cmd is available.
+    } else {
+      "\nReboot ";
+      if (YorN)
+        Reboot;
+    }
+  }
+  SettingsPop;
+}
+
+public U0 TOSStdIns()
+{//Completes TOS install from TOS_Distro.ISO
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  "$PURPLE$$TX+CX,\"Complete TOS install from TOS_Distro.ISO\"$$FG$\n\n\n\n";
+  InsRereg;
+
+  "\nDownload TOS_Supplemental1.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental2.ISO.C\tfrom http://www.templeos.org\n"
+  "Download TOS_Supplemental3.ISO.C\tfrom http://www.templeos.org\n";
+
+  if (PressAKey!=CH_SHIFT_ESC) {
+    if (FileFind("/Demo/AcctExample"))
+      CopyTree("::/Demo/AcctExample","~");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental1.ISO.C"))
+      CopyTree("T:/","~/Sup1");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental2.ISO.C"))
+      CopyTree("T:/","~/Sup2");
+    if (HostChgDsk("/home/tad/Downloads/TOS_Supplemental3.ISO.C"))
+      CopyTree("T:/","~/Sup3");
+
+    Once("TOSBootHDIns;");
+    "\nDo you wish to run >TOSRegen; to generate\n the distro ISO's ";
+    if (YorN) {
+      Once("TOSRegen;");
+      BootRAM("C:/" KERNEL_BIN_C); //Boot so TOSRegen cmd is available.
+    } else {
+      "\nReboot ";
+      if (YorN)
+        Reboot;
+    }
+  }
+  SettingsPop;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/ToDolDoc.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/ToDolDoc.HC.HTML new file mode 100755 index 0000000..83dafd9 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/ToDolDoc.HC.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically);DolDoc/Conversion;DolDoc/Cmd Line (Typically)"
+
+public U0 ToDolDoc(U8 *files_find_mask,U8 *fu_flags=NULL)
+{//Convert text file to DolDoc by making double $'s.
+  CDoc *doc;
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    "%s\n",tmpde->full_name;
+    doc=DocRead(tmpde->full_name,DOCF_PLAIN_TEXT|DOCF_DBL_DOLLARS);
+    DocWrite(doc);
+    DocDel(doc);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Opt/Utils/ToTXT.HC.HTML b/public/Wb/Home/Src/Adam/Opt/Utils/ToTXT.HC.HTML new file mode 100755 index 0000000..bf8c4fe --- /dev/null +++ b/public/Wb/Home/Src/Adam/Opt/Utils/ToTXT.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Conversion"
+
+U0 TXTPutS(CDoc *doc,U8 *st,I64 *_col)
+{
+  U8 *ch,*ptr;
+  while (ch=*st++) {
+    switch (ch) {
+      case '\t':
+        do {
+          DocPutKey(doc,CH_SPACE,0);
+          *_col=*_col+1;
+        } while (*_col&7);
+        break;
+
+      start:
+        case 'pi':      ptr="pi";       break;
+        case 'theta':   ptr="theta";    break;
+        case 'phi':     ptr="phi";      break;
+        case 'omega':   ptr="omega";    break;
+        case 'inf':     ptr="inf";      break;
+        case 'u':       ptr="u";        break;
+        case CH_SHIFT_SPACE: ptr=" ";   break;
+      end:
+        DocPrint(doc,ptr);
+        *_col=*_col+StrLen(ptr);
+        break;
+
+      default:
+        if (CH_SPACE<=ch<0x7F || ch=='\n')
+          DocPutKey(doc,ch,0);
+        else
+          DocPrint(doc,".");
+        *_col=*_col+1;
+    }
+  }
+}
+
+public CDoc *Doc2TXT(CDoc *doc_in)
+{//Cvt DolDoc doc to plain text.
+  CDocEntry *doc_e,*doc_e2;
+  I64 y,col;
+  CDoc *doc_out=DocNew;
+  Bool unlock_doc_in=DocLock(doc_in),no_bwd,line_has_html_code=FALSE;
+  DocRecalc(doc_in);
+
+  doc_out->flags|=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+
+  doc_e=doc_in->head.next;
+  col=doc_e->x;
+  y=doc_e->y;
+  while (doc_e!=doc_in) {
+    if (!(doc_e->de_flags&DOCEF_SKIP)) {
+      while (y<doc_e->y) {
+        TXTPutS(doc_out,"\n",&col);
+        y++;
+        col=0;
+        line_has_html_code=FALSE;
+      }
+      if (doc_e->type_u8==DOCT_HTML_CODE)
+        line_has_html_code=TRUE;
+
+      no_bwd=TRUE;
+      doc_e2=doc_e->next;
+      while (doc_e2!=doc_in && doc_e2->y==doc_e->y) {
+        if (doc_e2->x<doc_e->x) {
+          no_bwd=FALSE;
+          break;
+        }
+        doc_e2=doc_e2->next;
+      }
+      if (no_bwd && !(doc_e->type_u8==DOCT_NEW_LINE && line_has_html_code))
+        while (col<doc_e->x)
+          TXTPutS(doc_out," ",&col);
+
+      switch (doc_e->type_u8) {
+        case DOCT_TEXT:
+          TXTPutS(doc_out,doc_e->tag,&col);
+          break;
+        case DOCT_TAB:
+          TXTPutS(doc_out,"\t",&col);
+          break;
+        case DOCT_HTML_CODE:
+          break;
+        case DOCT_SPRITE:
+          break;
+        default:
+          if (doc_e->de_flags&DOCEF_TAG)
+            TXTPutS(doc_out,doc_e->tag,&col);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  while (y<doc_e->y) {
+    TXTPutS(doc_out,"\n",&col);
+    y++;
+    col=0;
+  }
+  doc_out->cur_entry=&doc_out->head;
+  DocRecalc(doc_out);
+
+  if (unlock_doc_in)
+    DocUnlock(doc_in);
+  return doc_out;
+}
+
+#help_index "Cmd Line (Typically);DolDoc/Conversion;DolDoc/Cmd Line (Typically)"
+public U0 ToTXT(U8 *_in_name,U8 *_out_name=NULL,I64 width=70)
+{//Convert DolDocfile to plain text.
+  U8 *in_name,*out_name;
+  CDoc *doc_in,*doc_out;
+
+  SettingsPush; //See SettingsPush
+  WinHorz(0,width-1); //Sets doc width for word wrap.
+
+  in_name=ExtDft(_in_name,"DD.Z");
+  if (_out_name)
+    out_name=ExtDft(_out_name,"TXT");
+  else
+    out_name=ExtChg(_in_name,"TXT");
+
+  doc_in=DocRead(in_name);
+  doc_out=Doc2TXT(doc_in);
+  StrCpy(&doc_out->filename.name,out_name);
+
+  SettingsPop;
+
+  DocWrite(doc_out);
+  DocDel(doc_in);
+  DocDel(doc_out);
+  Free(in_name);
+  Free(out_name);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/TaskRep.HC.HTML b/public/Wb/Home/Src/Adam/TaskRep.HC.HTML new file mode 100755 index 0000000..d0e386e --- /dev/null +++ b/public/Wb/Home/Src/Adam/TaskRep.HC.HTML @@ -0,0 +1,61 @@ + + + + + + + + + + + +
+#help_index "Info;Task"
+U0 TaskRepTask(CTask *task,I64 indent)
+{
+  CTask *task1;
+  "%h*c$MA,T=\"%08X\",LM=\"Kill(0x%X);\n\",$ $BLACK$#%d$FG$ "
+        "$TX,\"%$Q...\",SCX=16$\n",indent,CH_SPACE,task,task,task->task_num,
+        task->task_title;
+  "%h*c%08X %04X:%04X:%08X\n",indent+2,CH_SPACE,TaskMemAlloced(task),
+        task->task_flags,task->display_flags,task->win_inhibit;
+  task1=task->next_child_task;
+  while (task1!=(&task->next_child_task)(U8 *)
+        -offset(CTask.next_sibling_task)) {
+    TaskRepTask(task1,indent+2);
+    task1=task1->next_sibling_task;
+  }
+}
+
+public U0 TaskRep()
+{//Report current tasks on all cores.
+  I64 i;
+  CCPU *c;
+  PUSHFD
+  CLI
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    "$PURPLE$CPU%02X$FG$\n",i;
+    TaskRepTask(c->seth_task,2);
+  }
+  POPFD
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/TaskSettings.HC.HTML b/public/Wb/Home/Src/Adam/TaskSettings.HC.HTML new file mode 100755 index 0000000..8b58bcf --- /dev/null +++ b/public/Wb/Home/Src/Adam/TaskSettings.HC.HTML @@ -0,0 +1,151 @@ + + + + + + + + + + + +
+#help_index "Task/Settings"
+
+public CTaskSettings *SettingsPush(CTask *task=NULL,I64 flags=0)
+{//Typically, called at start of an application.
+//It saves many settings so they can be restored
+  //at the end of the application with SettingsPop().
+
+  CTaskSettings *tmpse;
+  CDoc *doc;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return NULL;
+  tmpse=CAlloc(sizeof(CTaskSettings),task);
+  tmpse->cur_dir=DirCur(task,task);
+  tmpse->draw_it=task->draw_it;
+  GrPaletteGet(tmpse->palette);
+  tmpse->task_end_cb=task->task_end_cb;
+
+  if (!(flags&TSF_SAME_SONG)) {
+    if (tmpse->song_task=task->song_task) {
+      Suspend(task->song_task);
+      Snd;
+    }
+    task->song_task=NULL;
+  }
+
+  if (tmpse->animate_task=task->animate_task)
+    Suspend(task->animate_task);
+  task->animate_task=NULL;
+
+  if (doc=DocPut(task)) {
+    tmpse->hide_cursor=!Bt(&doc->flags,DOCf_HIDE_CURSOR);
+    tmpse->highlight_cursor=!Bt(&doc->flags,DOCf_DONT_HIGHLIGHT_CURSOR);
+    tmpse->scroll=!Bt(&doc->flags,DOCf_NO_SCROLL_BARS);
+  }
+
+  tmpse->left=task->win_left;
+  tmpse->right=task->win_right;
+  tmpse->top=task->win_top;
+  tmpse->bottom=task->win_bottom;
+
+  tmpse->scroll_x=task->scroll_x;
+  tmpse->scroll_y=task->scroll_y;
+  tmpse->scroll_z=task->scroll_z;
+
+  tmpse->win_inhibit=task->win_inhibit;
+  tmpse->text_attr=task->text_attr;
+  StrCpy(tmpse->task_title,task->task_title);
+  tmpse->title_src  =task->title_src;
+  tmpse->border_attr=task->border_attr;
+  tmpse->border_src =task->border_src;
+  tmpse->border=!Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+  if (TaskValidate(ac.task))
+    tmpse->autocomplete=TRUE;
+  else
+    tmpse->autocomplete=FALSE;
+
+  tmpse->next=task->next_settings;
+  task->next_settings=tmpse;
+  return tmpse;
+}
+
+U0 SettingsPop2(CTask *task,CTaskSettings *tmpse)
+{
+  CDoc *doc;
+
+  if (doc=DocPut(task)) {
+    LBEqu(&doc->flags,DOCf_HIDE_CURSOR,!tmpse->hide_cursor);
+    LBEqu(&doc->flags,DOCf_DONT_HIGHLIGHT_CURSOR,!tmpse->highlight_cursor);
+    LBEqu(&doc->flags,DOCf_NO_SCROLL_BARS,!tmpse->scroll);
+  }
+
+  WinBorder(tmpse->border,task);
+  WinHorz(tmpse->left,tmpse->right,task);
+  WinVert(tmpse->top,tmpse->bottom,task);
+  task->scroll_x=tmpse->scroll_x;
+  task->scroll_y=tmpse->scroll_y;
+  task->scroll_z=tmpse->scroll_z;
+  task->win_inhibit=tmpse->win_inhibit;
+  task->text_attr=tmpse->text_attr;
+  task->border_attr=tmpse->border_attr;
+  task->border_src =tmpse->border_src;
+  task->title_src  =tmpse->title_src;
+  StrCpy(task->task_title,tmpse->task_title);
+  AutoComplete(tmpse->autocomplete);
+  GrPaletteSet(tmpse->palette);
+  Snd;
+}
+
+public U0 SettingsPop(CTask *task=NULL,I64 flags=0)
+{//Typically, called at end of an application.
+  CTaskSettings *tmpse;
+  if (!task) task=Fs;
+  if (!TaskValidate(task))
+    return;
+  if (tmpse=task->next_settings) {
+    task->next_settings=tmpse->next;
+    Cd(tmpse->cur_dir);
+    Free(tmpse->cur_dir);
+    task->draw_it=tmpse->draw_it;
+    task->task_end_cb=tmpse->task_end_cb;
+
+    if (task->animate_task)
+      Kill(task->animate_task);
+    if (task->animate_task=tmpse->animate_task)
+      Suspend(task->animate_task,FALSE);
+
+    if (!(flags&TSF_SAME_SONG)) {
+      if (task->song_task)
+        Kill(task->song_task);
+      if (task->song_task=tmpse->song_task)
+        Suspend(task->song_task,FALSE);
+    }
+
+    SettingsPop2(task,tmpse); //Do it to get ress fast
+    Refresh(,TRUE);
+    SettingsPop2(task,tmpse); //Redo in case was lost by old update
+
+    Free(tmpse);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Training.HC.HTML b/public/Wb/Home/Src/Adam/Training.HC.HTML new file mode 100755 index 0000000..d8db1f5 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Training.HC.HTML @@ -0,0 +1,215 @@ + + + + + + + + + + + +
+#help_index "Help System"
+
+U8 *KeyMapKeyMStrPrint(I64 sc,U0 (*fp_hndlr)(I64 sc),
+        U8 *desc,CTask *task=NULL)
+{
+  I64 i=9,k,c;
+  U8 *st,*st2,*res,*ptr;
+  CHashTable *old_hash=Fs->hash_table;
+  st=ScanCode2KeyName(sc);
+  if (sc&SCF_CTRL)      i+=5;
+  if (sc&SCF_ALT)       i+=4;
+  if (sc&(SCF_SHIFT|SCF_NO_SHIFT)) i+=6;
+  if (TaskValidate(task))
+    Fs->hash_table=task->hash_table;
+  st2=SrcEdLink(fp_hndlr,256);
+  Fs->hash_table=old_hash;
+
+  k=*desc(U32 *);
+  if (k=='Edit')        c=BLUE;
+  else if (k=='Dol ')   c=GREEN;
+  else if (k=='Cmd ')   c=RED;
+  else                  c=BLACK;
+
+  res=MStrPrint("%-*s $FG,%d$$TX+UL+L+PU,\"%$Q\",A=\"%s\"$$FG$\n",
+        i,st,c,desc,st2);
+  Free(st);
+  Free(st2);
+
+  ptr=res;
+  while (*ptr) {
+    if (*ptr==CH_SPACE)
+      *ptr=CH_SHIFT_SPACE;
+    ptr++;
+  }
+
+  return res;
+}
+
+U0 KeyMapKeyPrint(I64 sc,U0 (*fp_hndlr)(I64 sc),U8 *desc,CTask *task=NULL)
+{
+  U8 *st=KeyMapKeyMStrPrint(sc,fp_hndlr,desc,task);
+  "%s",st;
+  Free(st);
+}
+
+U0 KeyMapCtrlAltFamily(Bool no_shift,Bool shift)
+{
+  I64 i,no_shift_f;
+  if (no_shift && shift)
+    no_shift_f=SCF_NO_SHIFT;
+  else
+    no_shift_f=0;
+  if (no_shift) KeyMapKeyPrint(SC_DELETE+SCF_CTRL+SCF_ALT+no_shift_f,
+          &Reboot,"Cmd /Reboot");
+  if (no_shift) KeyMapKeyPrint(SC_ESC+SCF_CTRL+SCF_ALT+no_shift_f,
+          &User,"Cmd /Terminal Window");
+  if (no_shift) KeyMapKeyPrint(SC_TAB+SCF_CTRL+SCF_ALT+no_shift_f,
+          &WinToTop,"Cmd /Next Focus Task");
+
+  for (i=0;i<26;i++)
+    if (keydev.fp_ctrl_alt_cbs[i]) {
+      if (no_shift && keydev.ctrl_alt_no_shift_descs[i])
+        KeyMapKeyPrint(Char2ScanCode(i+'a')+SCF_CTRL+SCF_ALT+no_shift_f,
+              keydev.fp_ctrl_alt_cbs[i],keydev.ctrl_alt_no_shift_descs[i]);
+      if (shift && keydev.ctrl_alt_shift_descs[i])
+        KeyMapKeyPrint(Char2ScanCode(i+'a')+SCF_CTRL+SCF_ALT+SCF_SHIFT,
+              keydev.fp_ctrl_alt_cbs[i],keydev.ctrl_alt_shift_descs[i]);
+    }
+}
+
+U0 KMComparePrepare(U8 *buf,I64 *src)
+{
+  I64 i,*dst=buf;
+  U8 *ptr;
+  if (src) {
+    *dst++=*src++;
+    *dst++=*src++;
+    *dst++=*src++;
+    *dst++=*src++;
+    *dst(U8 *)=0;
+    if (ptr=StrMatch("SHIFT",buf)) {
+      for (i=0;i<5;i++)
+        ptr[i]=CH_SHIFT_SPACE;
+      if (ptr=StrMatch("$",buf))
+        *ptr=255;
+    }
+  } else
+    *buf=0;
+}
+
+I64 KMCompare(U8 *e1,U8 *e2)
+{
+  U8 buf1[STR_LEN],buf2[STR_LEN];
+  KMComparePrepare(buf1,e1);
+  KMComparePrepare(buf2,e2);
+  return StrCmp(buf1,buf2);
+}
+
+U0 KeyMapFamily2(U8 **entries,CTask *task,I64 scf)
+{
+  I64 i,arg1,arg2;
+  for (i=0;i<256;i++) {
+    arg2=scf|i|SCF_KEY_DESC;
+    arg1=ScanCode2Char(arg2);
+    *keydev.desc=0;
+    keydev.hndlr=NULL;
+    if (TaskValidate(task) && !Bt(&task->win_inhibit,WIf_SELF_KEY_DESC)) {
+      if (task==Fs)
+        PutKey(arg1,arg2);
+      else
+        PostMsg(task,MSG_KEY_DOWN,arg1,arg2);
+      Refresh(0,TRUE);
+      Sleep(1); //Open loop because might be no response.  TODO: Drops msgs.
+    }
+    if (*keydev.desc && StrNCmp(keydev.desc,"Char  /",7))
+      entries[i]=KeyMapKeyMStrPrint(arg2,keydev.hndlr,keydev.desc,task);
+  }
+}
+
+U0 KeyMapFamily(CTask *task,I64 scf,Bool no_shift,Bool shift)
+{
+  I64 i,cnt=0;
+  U8 **entries=CAlloc(2*256*sizeof(U8 *)),**ptr=entries;
+  if (no_shift) {
+    if (shift)
+      KeyMapFamily2(ptr,task,scf+SCF_NO_SHIFT);
+    else
+      KeyMapFamily2(ptr,task,scf);
+    ptr+=256;
+    cnt+=256;
+  }
+  if (shift) {
+    KeyMapFamily2(ptr,task,scf+SCF_SHIFT);
+    ptr+=256;
+    cnt+=256;
+  }
+  QSortI64(entries,cnt,&KMCompare);
+  for (i=0;i<cnt;i++)
+    if (entries[i]) {
+      "%s",entries[i];
+      Free(entries[i]);
+    }
+  Free(entries);
+}
+
+public U0 KeyMap(CTask *task=NULL)
+{//Report desc of all keys.
+  Bool old_key_desc;
+  if (!task) task=Fs;
+  old_key_desc=LBtr(&task->win_inhibit,WIf_SELF_KEY_DESC);
+  DocMax;
+  KeyMapFamily(task,0,TRUE,TRUE);
+  KeyMapFamily(task,SCF_CTRL,TRUE,TRUE);
+  KeyMapFamily(task,SCF_ALT,TRUE,TRUE);
+  KeyMapCtrlAltFamily(TRUE,TRUE);
+  LBEqu(&task->win_inhibit,WIf_SELF_KEY_DESC,old_key_desc);
+  "\nKeyMap Completed.\n";
+}
+
+#help_index "Help System/Training"
+public U0 TipOfDay(U8 *tip_file="::/Doc/Tips.DD")
+{//Print random tip-of-day from ::/Doc/Tips.DD.
+  I64 i=RandU16;
+  CDoc *doc=DocRead(tip_file),*doc2=DocNew;
+  CDocEntry *doc_e=doc->head.next;
+  "$WW,1$\n";
+  while (TRUE) {
+    if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*')
+      if (!i--) break;
+    doc_e=doc_e->next;
+  }
+  if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*') {
+    while (doc_e!=doc) {
+      if (doc_e->type_u8!=DOCT_ERROR)
+        DocInsEntry(doc2,DocEntryCopy(doc2,doc_e));
+      doc_e=doc_e->next;
+      if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*')
+        break;
+    }
+  }
+  DocInsDoc(DocPut,doc2);
+  DocDel(doc2);
+  DocDel(doc);
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/WallPaper.HC.HTML b/public/Wb/Home/Src/Adam/WallPaper.HC.HTML new file mode 100755 index 0000000..7a7e7d1 --- /dev/null +++ b/public/Wb/Home/Src/Adam/WallPaper.HC.HTML @@ -0,0 +1,196 @@ + + + + + + + + + + + +
+#help_index "Windows"
+
+class CWallPaperGlbls
+{
+  I64   last_calc_idle_cnt,last_swap_cnter[MP_PROCESSORS_NUM];
+  F64   last_calc_idle_delta_time;
+  U8    top_line[STR_LEN];
+} *wall=CAlloc(sizeof(CWallPaperGlbls));
+wall->last_calc_idle_delta_time=1.0;
+
+class CTaskWallPaperData
+{
+  I64   alloced_u8s,used_u8s;
+  U8    caller_stk[STR_LEN-$];
+};
+
+U0 WallPaper(CTask *_task)
+{
+  I64 i,j,l=TEXT_ROWS-1;
+  CTask *task;
+  CTaskWallPaperData *wpd;
+  CHashTable *old_hash=Fs->hash_table;
+  CCPU *c;
+  CDateStruct ds;
+  U8 *st;
+  _task->text_attr=BLUE<<4+WHITE;
+  if (sys_data_bp) {
+    TextPrint(Fs,0,l--,BLUE<<4+YELLOW,
+          "%010X/%010X %010X/%010X%12td%12td%12td",
+          sys_data_bp->used_u8s,sys_data_bp->alloced_u8s,
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s,
+          cmp.compiled_lines,blkdev.read_cnt,blkdev.write_cnt);
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+          "______Data_Heap______ ______Code_Heap______ "
+          "___Lines___ ___Reads___ __Writes___");
+  } else {
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+          "%010X/%010X%12td%12td%12td",
+          sys_code_bp->used_u8s,sys_code_bp->alloced_u8s,
+          cmp.compiled_lines,blkdev.read_cnt,blkdev.write_cnt);
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+          "____CodeData_Heap____ "
+          "___Lines___ ___Reads___ ___Writes__");
+  }
+  TextPrint(Fs,0,l--,BLUE<<4+WHITE,"ProgressBars:%016X %016X %016X %016X",
+        progress1,progress2,progress3,progress4);
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    if (winmgr.t->calc_idle_cnt!=wall->last_calc_idle_cnt) {
+      wall->last_calc_idle_delta_time=winmgr.t->calc_idle_delta_time;
+      wall->last_swap_cnter[i]=winmgr.t->last_swap_cnter[i];
+      winmgr.t->last_swap_cnter[i]=c->swap_cnter;
+    }
+
+    task=c->seth_task;
+    do {
+      wpd=&task->wallpaper_data;
+      if (!TaskValidate(task)) break;
+      if (!(winmgr.updates&31)) {
+        if (c==Gs)
+          Fs->hash_table=task->hash_table;
+        else //precaution
+          Fs->hash_table=old_hash;
+        StrPrint(wpd->caller_stk,"    %-18tp %-18tp %-18tp %-18tp",
+              TaskCaller(task,0),TaskCaller(task,1),
+              TaskCaller(task,2),TaskCaller(task,3));
+      }
+      TextPrint(Fs,0,l--,BLUE<<4+YELLOW,wpd->caller_stk);
+      j=UnusedStk(task);
+      if (j<0)
+        Panic("Stk Overflow",task);
+      if (!(winmgr.updates&31)) {
+        wpd->alloced_u8s=TaskMemAlloced(task);
+        wpd->used_u8s   =TaskMemUsed(task);
+      }
+      TextPrint(Fs,0,l--,BLUE<<4+BROWN,
+            "  %-18ts #%08X %010X %010X/%010X %04X:%02tX:%08X",
+            task->task_title,task,j,wpd->used_u8s,wpd->alloced_u8s,
+            task->task_flags,task->display_flags,task->win_inhibit);
+      if (!TaskValidate(task)) break;
+      task=task->next_task;
+    } while (task!=c->seth_task);
+    TextPrint(Fs,0,l--,BLUE<<4+WHITE,"CPU%02X %2tf%% ContextSwaps/s:%9,d",i,
+          100.0*(1.0-c->idle_factor),ToI64((winmgr.t->last_swap_cnter[i]
+          -wall->last_swap_cnter[i])/wall->last_calc_idle_delta_time));
+  }
+  TextPrint(Fs,0,l--,BLUE<<4+WHITE,
+        "  ___Description____ #__Task__ UnusedStk_ _UsedMem__/_AllocMem_ "
+        "______Flags_____");
+
+  if (!(winmgr.updates&31) || !*wall->top_line) {
+    Date2Struct(&ds,Now+local_time_offset);
+    i=sys_code_bp->alloced_u8s-sys_code_bp->used_u8s;
+    if (sys_data_bp)
+      i+=sys_data_bp->alloced_u8s-sys_data_bp->used_u8s;
+    StrPrint(wall->top_line,
+          "%3tZ %02d/%02d %02d:%02d:%02d FPS:%2tf Mem:%010X CPU",
+          ds.day_of_week,"ST_DAYS_OF_WEEK",ds.mon,ds.day_of_mon,
+          ds.hour,ds.min,ds.sec,winmgr.fps,i);
+  }
+  TextPrint(Fs,0,0,BLUE<<4+WHITE,wall->top_line);
+
+  if (scrncast.record)
+    TextPrint(Fs,44-4,0,BLUE<<4+RED,"*");
+  for (i=0;i<mp_cnt;i++) {
+    c=&cpu_structs[i];
+    if (i&1)
+      TextPrint(Fs,44+i*2,0,BLUE<<4+WHITE,"%2tf",100.0*(1.0-c->idle_factor));
+    else
+      TextPrint(Fs,44+i*2,0,BLUE<<4+YELLOW,"%2tf",100.0*(1.0-c->idle_factor));
+  }
+
+  st=ScanCode2KeyName(kbd.last_down_scan_code);
+  TextPrint(Fs,80-18,0,BLUE<<4+YELLOW,"%18ts",st);
+  Free(st);
+
+  Fs->hash_table=old_hash;
+  wall->last_calc_idle_cnt=winmgr.t->calc_idle_cnt;
+}
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+U0 DrawTermBttn(CDC *dc,CCtrl *c)
+{
+  if (Blink)
+    Sprite3(dc,c->left,c->top,0,<1>);
+}
+
+U0 LeftClickTermBttn(CCtrl *,I64,I64,Bool down)
+{
+  if (down)
+    User;
+}
+
+CCtrl *TermBttnNew()
+{
+  I64 min_x,max_x,min_y,max_y;
+  CCtrl *c=ACAlloc(sizeof(CCtrl));
+
+  c->win_task=sys_winmgr_task;
+  c->flags=CTRLF_SHOW;
+  c->type=CTRLT_GENERIC;
+  c->draw_it=&DrawTermBttn;
+  c->left_click=&LeftClickTermBttn;
+
+  SpriteExtents(<1>,&min_x,&max_x,&min_y,&max_y);
+//min must be zero
+  c->left=sys_winmgr_task->pix_width-(max_x-min_x+1);
+  c->right=c->left+(max_x-min_x+1)-1;
+  c->top=sys_winmgr_task->pix_height-(max_y-min_y+1);
+  c->bottom=c->top+(max_y-min_y+1)-1;
+
+  QueIns(c,sys_winmgr_task->last_ctrl);
+  TaskDerivedValsUpdate(sys_winmgr_task);
+
+  return c;
+}
+
+U0 WallPaperInit()
+{
+  TermBttnNew;
+  gr.fp_wall_paper=&WallPaper;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/Win.HC.HTML b/public/Wb/Home/Src/Adam/Win.HC.HTML new file mode 100755 index 0000000..95548e8 --- /dev/null +++ b/public/Wb/Home/Src/Adam/Win.HC.HTML @@ -0,0 +1,573 @@ + + + + + + + + + + + +
+#help_index "Windows"
+#help_file "::/Doc/Windows"
+
+CMsStateGlbls old_ms={{-1000,-1000,0},{-1000,-1000,0},{-1000,-1000,0},
+  {0,0,0},{1.0,1.0,1.0},0.0,GetTSC,0.350,0,0,
+  FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE
+};
+
+public CWinMgrGlbls winmgr={0,0,0,WINMGR_FPS,tS,tS,NULL,FALSE,FALSE,FALSE};
+winmgr.t=CAlloc(sizeof(CWinMgrTimingGlbls));
+winmgr.t->last_calc_idle_time=tS;
+
+U0 ProgressBarsRegTf(U8 *path=NULL)
+{
+  F64 t,p1,p2,p3,p4;
+  if (path) {
+    t=tS;
+    if (progress1_t0) p1=t-progress1_t0; else p1=0;
+    if (progress2_t0) p2=t-progress2_t0; else p2=0;
+    if (progress3_t0) p3=t-progress3_t0; else p3=0;
+    if (progress4_t0) p4=t-progress4_t0; else p4=0;
+    RegWrite(path,"progress1_tf=%0.3f;progress2_tf=%0.3f;\n"
+          "progress3_tf=%0.3f;progress4_tf=%0.3f;\n",p1,p2,p3,p4);
+  }
+}
+
+#define PROGRESS_BAR_HEIGHT     20
+#define PROGRESS_BAR_WIDTH      (3*GR_WIDTH/4)
+U0 DrawProgressBars(CDC *dc)
+{
+  I64 i,j,k,n,m;
+  U8 *st,*st2;
+  for (i=0;i<PROGRESS_BARS_NUM;i++) {
+    if (m=sys_progresses[i].max) {
+      dc->color=BLACK;
+      GrRect(dc,
+            (GR_WIDTH-PROGRESS_BAR_WIDTH)/2,
+            (GR_HEIGHT-(PROGRESS_BARS_NUM*2-1-i*4)*PROGRESS_BAR_HEIGHT)/2,
+            PROGRESS_BAR_WIDTH,PROGRESS_BAR_HEIGHT);
+
+      dc->color=LTGREEN;
+      n=sys_progresses[i].val;
+      if (n>m)
+        n=m;
+      GrRect(dc,
+            (GR_WIDTH-PROGRESS_BAR_WIDTH)/2+2,
+            (GR_HEIGHT-(PROGRESS_BARS_NUM*2-1-i*4)*PROGRESS_BAR_HEIGHT)/2+2,
+            n*(PROGRESS_BAR_WIDTH-4)/m,
+            PROGRESS_BAR_HEIGHT-4);
+
+      if (m>1) {
+        dc->color=BLACK;
+        k=m-1;
+        if (k>19) k=19;
+        for (j=0;j<=k;j++)
+          GrLine(dc,
+                (GR_WIDTH-PROGRESS_BAR_WIDTH)/2+1+j*
+                (PROGRESS_BAR_WIDTH-4)/ToF64(k+1),
+                (GR_HEIGHT-(PROGRESS_BARS_NUM*2-1-i*4)*
+                PROGRESS_BAR_HEIGHT)/2+4,
+                (GR_WIDTH-PROGRESS_BAR_WIDTH)/2+1+j*
+                (PROGRESS_BAR_WIDTH-4)/ToF64(k+1),
+                (GR_HEIGHT-(PROGRESS_BARS_NUM*2-3-i*4)*
+                PROGRESS_BAR_HEIGHT)/2-4);
+      }
+
+      dc->color=GREEN;
+      if (*sys_progresses[i].desc)
+        st=StrNew(sys_progresses[i].desc);
+      else
+        st=MStrPrint("%d/%d",n,m);
+      if (sys_progresses[i].t0) {
+        st2=MStrPrint("%s %fs",st,tS-sys_progresses[i].t0);
+        Free(st);
+      } else
+        st2=st;
+      if (sys_progresses[i].tf) {
+        st=MStrPrint("%s/%fs",st2,sys_progresses[i].tf);
+        Free(st2);
+      } else
+        st=st2;
+      GrPrint(dc,(GR_WIDTH-FONT_WIDTH*StrLen(st))/2,(GR_HEIGHT-FONT_HEIGHT-
+            (PROGRESS_BARS_NUM*2-2-i*4)*PROGRESS_BAR_HEIGHT)/2,"%s",st);
+      Free(st);
+    }
+  }
+}
+
+U0 DrawWinGrid(CDC *dc)
+{
+  F64 d;
+  dc->color=BLACK;
+  dc->thick=1;
+  for (d=ms_grid.x_offset;d<GR_WIDTH; d+=ms_grid.x)
+    GrLine(dc,d,0,d,GR_HEIGHT-1);
+  for (d=ms_grid.y_offset;d<GR_HEIGHT;d+=ms_grid.y)
+    GrLine(dc,0,d,GR_WIDTH-1,d);
+}
+
+U0 WinGrid(Bool val)
+{
+  CGridGlbls last_grid;
+  MemCpy(&last_grid,&ms_grid,sizeof(CGridGlbls));
+  if (!val || PopUpForm(&ms_grid)) {
+    if (!val)
+      GridInit;
+    ms_hard.prescale.x*=last_grid.x_speed/ms_grid.x_speed;
+    ms_hard.prescale.y*=last_grid.y_speed/ms_grid.y_speed;
+    ms_hard.prescale.z*=last_grid.z_speed/ms_grid.z_speed;
+  } else
+    MemCpy(&ms_grid,&last_grid,sizeof(CGridGlbls));
+}
+U0 CtrlAltG(I64 sc)
+{
+  if (sc&SCF_SHIFT)
+    PopUp("WinGrid(OFF);");
+  else
+    PopUp("WinGrid(ON);");
+}
+CtrlAltCBSet('G',&CtrlAltG,"Cmd /Grid On",
+        "Cmd /Grid Off");
+
+CTask *ext_ASCII_task;
+U0 ExtendedASCII()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"Sel Char and Press <ESC>\n$LTBLUE$");
+  for (i=0;i<256;i++) {
+    if (i>=CH_SHIFT_SPACE && i!=0x7F) {
+      if (i==CH_SHIFT_SPACE)
+        DocPrint(doc,"$MU-UL,\"\\x1F\",LE=%d$",i);
+      else if (i=='$')
+        DocPrint(doc,"$MU-UL,\"\\x24\",LE=%d$",i);
+      else if (i=='\"'||i=='\\')
+        DocPrint(doc,"$MU-UL,\"\\%c\",LE=%d$",i,i);
+      else
+        DocPrint(doc,"$MU-UL,\"%c\",LE=%d$",i,i);
+    } else
+      DocPrint(doc," ");
+    if (i&15==15)
+      DocPrint(doc,"\n");
+  }
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  if (i>=0)
+    PostMsg(ext_ASCII_task,MSG_KEY_DOWN_UP,i,Char2ScanCode(i));
+}
+
+U0 CtrlAltA(I64)
+{
+  if (ext_ASCII_task=sys_focus_task)
+    Spawn(&ExtendedASCII);
+}
+CtrlAltCBSet('A',&CtrlAltA,"Cmd /Extended ASCII");
+
+public U0 WinScrollNull(CTask *task,CD3I64 *s)
+{//If panning a window has been done, restore to zero.
+  s->x=task->scroll_x;
+  s->y=task->scroll_y;
+  s->z=task->scroll_z;
+  task->scroll_x=0;
+  task->scroll_y=0;
+  task->scroll_z=0;
+}
+
+public U0 WinScrollRestore(CTask *task,CD3I64 *s)
+{//Set window pan value to stored value.
+  task->scroll_x=s->x;
+  task->scroll_y=s->y;
+  task->scroll_z=s->z;
+}
+
+U0 DrawMs(CDC *dc)
+{
+  I64 x,y;
+  PUSHFD
+  CLI
+  x=ms.pos.x;
+  y=ms.pos.y;
+  POPFD
+  if (ms.show && ms_hard.installed) {
+    if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
+      gr.text_base[ms.pos_text.x+ms.pos_text.y*TEXT_COLS]^=0x7F00;
+    else {
+      if (gr.fp_draw_ms) {
+        if (ms.lb)
+          dc->color=ROP_XOR+LTPURPLE^TRANSPARENT;
+        else if (ms.rb)
+          dc->color=ROP_XOR+LTCYAN^TRANSPARENT;
+        else
+          dc->color=ROP_XOR+BLACK^TRANSPARENT;
+        if (winmgr.grab_scroll && gr.fp_draw_grab_ms)
+          (*gr.fp_draw_grab_ms)(dc,x,y,winmgr.grab_scroll_closed);
+        else
+          (*gr.fp_draw_ms)(dc,x,y);
+      }
+    }
+  }
+}
+
+U0 WinFinalUpdate(CDC *dc)
+{
+  if (ms_grid.show)
+    DrawWinGrid(dc);
+  if (ms_grid.coord)
+    GrPrint(dc,GR_WIDTH-FONT_WIDTH*10,FONT_HEIGHT*3,
+          "(%03d,%03d)",ms.pos.x,ms.pos.y);
+  DrawProgressBars(dc);
+  if (winmgr.show_menu)
+    DrawMenu(dc);
+  else
+    sys_cur_submenu_entry=NULL;
+  DrawMs(dc);
+}
+
+gr.fp_final_scrn_update=&WinFinalUpdate;
+
+U0 WinMsUpdate()
+{
+  I64 dd;
+  Bool set=FALSE;
+  if (ms_hard.installed) {
+    ms.has_wheel=ms_hard.has_wheel;
+    if (ms_hard.evt) {
+      MsUpdate(ms_hard.pos.x,ms_hard.pos.y,ms_hard.pos.z,
+            ms_hard.bttns[0],ms_hard.bttns[1]);
+      ms_hard.evt=FALSE;
+      set=TRUE;
+    }
+  }
+
+  if (set) {
+    if (ms_hard.installed) {
+      ms.speed=ms_hard.speed;
+      ms.timestamp=ms_hard.timestamp;
+    }
+  } else
+    ms.speed*=0.95;
+  if (gr.scrn_zoom!=1) {
+    if (gr.continuous_scroll)
+      GrScaleZoom(1.0);
+    else {
+      dd=(ms.pos.x-gr.sx)*gr.scrn_zoom;
+      if (!(8<=dd<GR_WIDTH-8))
+        GrScaleZoom(1.0);
+      else {
+        dd=(ms.pos.y-gr.sy)*gr.scrn_zoom;
+        if (!(8<=dd<GR_HEIGHT-8))
+          GrScaleZoom(1.0);
+      }
+    }
+  }
+}
+
+public CTask *WinRefocus(CTask *task=NULL)
+{//Reset the focus task if NULL.
+  PUSHFD
+  CLI
+  if (!task) {
+    task=sys_winmgr_task->last_task;
+    while (TaskValidate(task) && task!=sys_winmgr_task) {
+      if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+        sys_focus_task=task;
+        break;
+      }
+      task=task->last_task;
+    }
+  }
+  POPFD
+  return sys_focus_task;
+}
+
+I64 WinOnTopWindows()
+{
+  CTask *task,*task1,*first_moved_fwd=NULL;
+  I64 res=0;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  task=sys_winmgr_task->next_task;
+  while (task!=sys_winmgr_task && task!=first_moved_fwd) {
+    task1=task->next_task;
+    if (!TaskValidate(task)) {
+      POPFD
+      return res;
+    }
+    if (Bt(&task->display_flags,DISPLAYf_WIN_ON_TOP) &&
+          task!=sys_winmgr_task->last_task) {
+      TaskQueRem(task);
+      TaskQueIns(task,sys_winmgr_task);
+      res++;
+      if (!first_moved_fwd)
+        first_moved_fwd=task;
+    }
+    task=task1;
+  }
+  POPFD
+  return res;
+}
+
+public I64 WinToTop(CTask *task=NULL,Bool update_z_buf=TRUE)
+{//Put task's win on top of window stack.
+  CTask *task1;
+  I64 res=0;
+  if (!task) task=Fs;
+  if (!TaskValidate(task) || task->gs->num)
+    return 0;
+  TaskDerivedValsUpdate(task,FALSE);
+  if (!sys_winmgr_task || task==sys_winmgr_task)
+    return 0;
+  PUSHFD
+  CLI
+  if (!TaskValidate(task)) {
+    POPFD
+    return 0;
+  }
+  if (task!=sys_winmgr_task->last_task) {
+    TaskQueRem(task);
+    TaskQueIns(task,sys_winmgr_task);
+    res++;
+  }
+  if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+    sys_focus_task=task;
+  if (res && !Bt(&task->display_flags,DISPLAYf_CHILDREN_NOT_ON_TOP)) {
+    task1=task->next_child_task;
+    while (task1!=&task->next_child_task) {
+      if (!TaskValidate(task1))
+        break;
+      res+=WinToTop(task1,FALSE);
+      task1=task1->next_sibling_task;
+    }
+    if (task->popup_task &&
+          task->popup_task->parent_task==task)
+      res+=WinToTop(task->popup_task,FALSE);
+  }
+  POPFD
+  res+=WinOnTopWindows;
+  if (res && update_z_buf)
+    WinZBufUpdate;
+  return res;
+}
+ext[EXT_WIN_TO_TOP]=&WinToTop;
+
+public CTask *WinFocus(CTask *task=NULL)
+{//Set task as focus task.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (!TaskValidate(task)||Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+    task=WinRefocus(sys_focus_task);
+  WinToTop(sys_focus_task=task);
+  POPFD
+  return sys_focus_task;
+}
+ext[EXT_WIN_FOCUS]=&WinFocus;
+
+public Bool WinHorz(I64 left,I64 right,CTask *task=NULL)
+{//Set task's win left and right columns.
+  I64 d=right-left;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return FALSE;
+  if (d<0) d=0;
+  if (left>=TEXT_COLS) {
+    left=TEXT_COLS-1;
+    right=left+d;
+  }
+  if (right<0) {
+    right=0;
+    left=right-d;
+  }
+  if (left>right) {
+    if (left>0)
+      right=left;
+    else
+      left=right;
+  }
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  if (task->win_left!=left || task->win_right!=right) {
+    task->win_left=left;
+    task->win_right=right;
+    TaskDerivedValsUpdate(task);
+    POPFD
+    return TRUE;
+  } else {
+    POPFD
+    return FALSE;
+  }
+}
+
+public Bool WinVert(I64 top,I64 bottom,CTask *task=NULL)
+{//Set task's win top and bottom rows.
+  I64 d=bottom-top;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return FALSE;
+  if (d<0) d=0;
+  if (top>=TEXT_ROWS) {
+    top=TEXT_ROWS-1;
+    bottom=top+d;
+  }
+  if (bottom<=0) {
+    bottom=1;
+    top=bottom-d;
+  }
+  if (top>bottom) {
+    if (top>=0)
+      bottom=top;
+    else
+      top=bottom;
+  }
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  if (task->win_top!=top || task->win_bottom!=bottom) {
+    task->win_top=top;
+    task->win_bottom=bottom;
+    TaskDerivedValsUpdate(task);
+    POPFD
+    return TRUE;
+  } else {
+    POPFD
+    return FALSE;
+  }
+}
+
+public U0 WinTileHorz()
+{//Tile windows horizontally top-to-bottom.
+  CTask *task,*last_task=Fs;
+  I64 cnt,c,i,vert_size,no_border;
+
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  task=sys_winmgr_task;
+  cnt=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+      cnt++;
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+
+  task=sys_winmgr_task;
+  i=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+      no_border=Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+      c=cnt- i&~3;
+      if (!c)
+        c=1;
+      else if (c>4)
+        c=4;
+      vert_size=(TEXT_ROWS-1)/c;
+
+      WinHorz(1-no_border,TEXT_COLS-2+no_border,task);
+      WinVert((i&3)*vert_size+2-no_border,(i&3+1)*vert_size+no_border,task);
+      last_task=task;
+      if (i&3==3)
+        WinVert(task->win_top,TEXT_ROWS-2,task);
+      i++;
+    }
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+  WinVert(last_task->win_top,TEXT_ROWS-2,last_task);
+  POPFD
+}
+
+public U0 WinTileVert()
+{//Tile windows vertically side-by-side.
+  CTask *task,*last_task=Fs;
+  I64 cnt,c,i,horz_size,no_border;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  task=sys_winmgr_task;
+  cnt=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS))
+      cnt++;
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+
+  task=sys_winmgr_task;
+  i=0;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+      no_border=Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+      c=cnt- i&~3;
+      if (!c)
+        c=1;
+      else if (c>4)
+        c=4;
+      horz_size=TEXT_COLS/c;
+      WinHorz((i&3)*horz_size+1-no_border,(i&3+1)*horz_size-1+no_border,task);
+      WinVert(2-no_border,TEXT_ROWS-2+no_border,task);
+      last_task=task;
+      if (i&3==3)
+        WinHorz(task->win_left,TEXT_COLS-2,task);
+      i++;
+    }
+    task=task->last_task;
+  } while (task!=sys_winmgr_task);
+  WinHorz(last_task->win_left,TEXT_COLS-2,last_task);
+  POPFD
+}
+
+public U0 WinMax(CTask *task=NULL)
+{//Maximize task's window
+  I64 no_border;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  no_border=Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+  WinHorz(1-no_border,TEXT_COLS-2+no_border,task);
+  WinVert(2-no_border,TEXT_ROWS-2+no_border,task);
+  WinToTop(task);
+  POPFD
+}
+
+public Bool WinBorder(Bool val=OFF,CTask *task=NULL)
+{//Turn off (or on) window border.
+  Bool old_has_border;
+  if (!task) task=Fs;
+  if (!TaskValidate(task)) return FALSE;
+  PUSHFD
+  CLI //TODO Multiprocessor safe
+  old_has_border=!Bt(&task->display_flags,DISPLAYf_NO_BORDER);
+  if (val) {
+    if (!old_has_border) {
+      LBtr(&task->display_flags,DISPLAYf_NO_BORDER);
+      task->win_left++; task->win_right--;
+      task->win_top++;  task->win_bottom--;
+      TaskDerivedValsUpdate(task,FALSE);
+    }
+  } else {
+    if (old_has_border) {
+      LBts(&task->display_flags,DISPLAYf_NO_BORDER);
+      task->win_left--; task->win_right++;
+      task->win_top--;  task->win_bottom++;
+      TaskDerivedValsUpdate(task,FALSE);
+    }
+  }
+  POPFD
+  return old_has_border;
+}
+
+ diff --git a/public/Wb/Home/Src/Adam/WinMgr.HC.HTML b/public/Wb/Home/Src/Adam/WinMgr.HC.HTML new file mode 100755 index 0000000..6fb4f67 --- /dev/null +++ b/public/Wb/Home/Src/Adam/WinMgr.HC.HTML @@ -0,0 +1,894 @@ + + + + + + + + + + + +
+#help_index "Windows;Task/Delay"
+
+public U0 Refresh(I64 cnt=1,Bool force=FALSE)
+{//Wait for 30fps WinMgr to start & finish scrn refresh.
+  //0,FALSE Cnt Sync to WinMgr.
+  //0,TRUE  Pump Msgs.
+  //1 Cnt Wait and Pump Msgs.
+  //2 Cnt Make Sure to do a Full Refresh
+  //and Set Cur Pos.
+  Bool  old_full_refresh,
+        old_idle=LBts(&Fs->task_flags,TASKf_IDLE);
+  CDoc *old_doc=DocPut;
+  I64 update_cnt;
+  if (!cnt&&force)
+    LBts(&sys_semas[SEMA_JUST_PUMP_MSGS],0);
+  while (Bt(&sys_semas[SEMA_REFRESH_IN_PROGRESS],0)) {
+    if (force && sys_winmgr_task)
+      sys_winmgr_task->wake_jiffy=cnts.jiffies;
+    Yield;
+  }
+  if (cnt>1 && old_doc)
+    old_full_refresh=LBts(&old_doc->flags,DOCf_DO_FULL_REFRESH);
+  update_cnt=winmgr.updates+cnt;
+  while (winmgr.updates<update_cnt) {
+    if (force && sys_winmgr_task)
+      sys_winmgr_task->wake_jiffy=cnts.jiffies;
+    Sleep(1);
+  }
+  if (old_doc)
+    LBEqu(&old_doc->flags,DOCf_DO_FULL_REFRESH,old_full_refresh);
+  LBEqu(&Fs->task_flags,TASKf_IDLE,old_idle);
+}
+
+#help_index "Windows"
+
+I64 WinQueIPMsgs(Bool que)
+{
+  static CD3I64 single_ms={0,0,0};
+  F64 time=tS;
+  I64 msg_code=0,arg1,arg2,single_arg1,single_arg2;
+  CTask *task_focus=sys_focus_task;
+
+  if (task_focus && !winmgr.grab_scroll) {
+    arg1=ms.pos.x-task_focus->pix_left-task_focus->scroll_x;
+    arg2=ms.pos.y-task_focus->pix_top-task_focus->scroll_y;
+    single_arg1=single_ms.x-task_focus->pix_left-task_focus->scroll_x;
+    single_arg2=single_ms.y-task_focus->pix_top-task_focus->scroll_y;
+    if (old_ms.presnap.x!=ms.presnap.x || old_ms.presnap.y!=ms.presnap.y) {
+      if (que)
+        TaskMsg(task_focus,0,
+              MSG_MS_MOVE,arg1,arg2,0);
+      msg_code=MSG_MS_MOVE;
+    }
+//TODO que msg for ms.pos.z?
+    if (ms.left_dbl_time) {
+      if (time>ms.left_dbl_time) {
+        if (ms.left_dbl) {
+          if (!ms.left_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_D_DOWN,arg1,arg2,0);
+            ms.left_down_sent=TRUE;
+            msg_code=MSG_MS_L_D_DOWN;
+          }
+          if (!ms.lb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_D_UP,arg1,arg2,0);
+            ms.left_dbl_time=0;
+            msg_code=MSG_MS_L_D_UP;
+          }
+        } else {
+          if (!ms.left_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_DOWN,single_arg1,single_arg2,0);
+            ms.left_down_sent=TRUE;
+            msg_code=MSG_MS_L_DOWN;
+          }
+          if (!ms.lb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_L_UP,arg1,arg2,0);
+            ms.left_dbl_time=0;
+            msg_code=MSG_MS_L_UP;
+          }
+        }
+      } else {
+        if (ms.lb && !ms_last.lb) {
+          ms.left_dbl_time=time;
+          ms.left_dbl=TRUE;
+        }
+      }
+    } else {
+      if (TaskValidate(task_focus) &&
+            Bt(&task_focus->win_inhibit,WIf_FOCUS_TASK_MS_L_D)) {
+        if (ms.lb  && !ms_last.lb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_L_DOWN,arg1,arg2,0);
+          msg_code=MSG_MS_L_DOWN;
+        } else if (!ms.lb && ms_last.lb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_L_UP,arg1,arg2,0);
+          msg_code=MSG_MS_L_UP;
+        }
+      } else {
+        if (ms.lb  && !ms_last.lb) {
+          ms.left_dbl=FALSE;
+          ms.left_down_sent=FALSE;
+          ms.left_dbl_time=time+ms.dbl_time;
+          single_ms.x=ms.pos.x;
+          single_ms.y=ms.pos.y;
+        }
+      }
+    }
+
+    if (ms.right_dbl_time) {
+      if (time>ms.right_dbl_time) {
+        if (ms.right_dbl) {
+          if (!ms.right_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_D_DOWN,arg1,arg2,0);
+            ms.right_down_sent=TRUE;
+            msg_code=MSG_MS_R_D_DOWN;
+          }
+          if (!ms.rb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_D_UP,arg1,arg2,0);
+            ms.right_dbl_time=0;
+            msg_code=MSG_MS_R_D_UP;
+          }
+        } else {
+          if (!ms.right_down_sent) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_DOWN,single_arg1,single_arg2,0);
+            ms.right_down_sent=TRUE;
+            msg_code=MSG_MS_R_DOWN;
+          }
+          if (!ms.rb) {
+            if (que)
+              TaskMsg(task_focus,0,
+                    MSG_MS_R_UP,arg1,arg2,0);
+            ms.right_dbl_time=0;
+            msg_code=MSG_MS_R_UP;
+          }
+        }
+      } else {
+        if (ms.rb && !ms_last.rb) {
+          ms.right_dbl_time=time;
+          ms.right_dbl=TRUE;
+        }
+      }
+    } else {
+      if (TaskValidate(task_focus) &&
+            Bt(&task_focus->win_inhibit,WIf_FOCUS_TASK_MS_R_D)) {
+        if (ms.rb  && !ms_last.rb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_R_DOWN,arg1,arg2,0);
+          msg_code=MSG_MS_R_DOWN;
+        } else if (!ms.rb && ms_last.rb) {
+          if (que)
+            TaskMsg(task_focus,0,
+                  MSG_MS_R_UP,arg1,arg2,0);
+          msg_code=MSG_MS_R_UP;
+        }
+      } else {
+        if (ms.rb  && !ms_last.rb) {
+          ms.right_dbl=FALSE;
+          ms.right_down_sent=FALSE;
+          ms.right_dbl_time=time+ms.dbl_time;
+          single_ms.x=ms.pos.x;
+          single_ms.y=ms.pos.y;
+        }
+      }
+    }
+
+    MemCpy(&ms_last,&ms,sizeof(CMsStateGlbls));
+    MemCpy(&old_ms,&ms,sizeof(CMsStateGlbls));
+  }
+  return msg_code;
+}
+
+U0 WinCalcIdles()
+{
+  F64 calc_idle_time;
+  I64 i,k,total_jiffies,total_jiffies_delta,idle_pt_hits[MP_PROCESSORS_NUM];
+  CCPU *c;
+  CWinMgrTimingGlbls *t=winmgr.t;
+
+  if ((t->calc_idle_delta_time=
+        (calc_idle_time=tS)-t->last_calc_idle_time)>.25) {
+    PUSHFD
+    CLI
+    total_jiffies=cpu_structs[0].total_jiffies;
+    for (i=0;i<mp_cnt;i++)
+      idle_pt_hits[i]=cpu_structs[i].idle_pt_hits;
+    POPFD
+
+    total_jiffies_delta=total_jiffies-t->last_total_jiffies;
+    for (i=0;i<mp_cnt;i++) {
+      c=&cpu_structs[i];
+      if (total_jiffies_delta && (k=idle_pt_hits[i]-t->last_idle_pt_hits[i])>=0)
+        c->idle_factor=Clamp(ToF64(k)/total_jiffies_delta,0.01,0.99);
+      else
+        c->idle_factor=0.01;
+      t->last_idle_pt_hits[i]=idle_pt_hits[i];
+    }
+    t->last_total_jiffies=total_jiffies;
+    t->last_calc_idle_time=calc_idle_time;
+    t->calc_idle_cnt++;
+  }
+}
+
+I64 WinMgrSleep(Bool flush_msgs=FALSE)
+{
+  I64 timeout_val,msg_code=0;
+  CCtrl *c;
+  Bool que;
+  F64 t,t_delta;
+  U8 *st;
+  CDC *diff;
+  CDate cdt;
+
+  TimeCal;
+  if ((t_delta=(t=tS)-winmgr.last_refresh_tS)>0.01)
+    winmgr.fps=Max(1.0/t_delta,1);
+  else
+    winmgr.fps=99;
+  winmgr.last_refresh_tS=t;
+  WinCalcIdles;
+
+  if (flush_msgs)
+    FifoI64Flush(kbd.scan_code_fifo);
+  else if (TaskValidate(sys_focus_task)) {
+    KbdMsgsQue;
+
+    que=TRUE;
+    if (TaskValidate(sys_focus_task) &&
+          !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_CTRLS)) {
+      c=sys_focus_task->next_ctrl;
+      while (c!=&sys_focus_task->next_ctrl) {
+        if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+          que=FALSE;
+          break;
+        }
+        c=c->next;
+      }
+    }
+    msg_code=WinQueIPMsgs(que);
+  } else {
+    WinRefocus(sys_focus_task);
+    if (!TaskValidate(sys_focus_task))
+      FifoI64Flush(kbd.scan_code_fifo);
+  }
+  if (sys_focus_task)
+    LBtr(&sys_focus_task->task_flags,TASKf_HAS_SONG);
+  WinMsUpdate;
+
+  if (!LBtr(&sys_semas[SEMA_JUST_PUMP_MSGS],0)) {
+    t=tS+WINMGR_PERIOD/8;
+    while (winmgr.ideal_refresh_tS<t)
+      winmgr.ideal_refresh_tS+=WINMGR_PERIOD;
+    timeout_val=cnts.jiffies+(winmgr.ideal_refresh_tS-tS)*JIFFY_FREQ;
+    LBts(&sys_semas[SEMA_REFRESH_IN_PROGRESS],0);
+    GrUpdateScrn;
+    LBtr(&sys_semas[SEMA_REFRESH_IN_PROGRESS],0);
+    if (scrncast.record  && !scrncast.just_audio) {
+      cdt=scrncast.t0_now(I64)+ToI64(CDATE_FREQ*(tS-scrncast.t0_tS));
+      if (!scrncast.dc) {
+        scrncast.dc=DCCopy(scrncast.dc2_alias);
+        scrncast.dc->cdt=cdt;
+        st=MStrPrint(scrncast.print_fmt,cdt);
+        GRWrite(st,scrncast.dc);
+        Free(st);
+      } else if (MemCmp(scrncast.dc->body,
+            scrncast.dc2_alias->body,MSize(scrncast.dc2_alias->body))) {
+        diff=DCDiff(scrncast.dc,scrncast.dc2_alias);
+        diff->cdt=cdt;
+        st=MStrPrint(scrncast.print_fmt,cdt);
+        GRWrite(st,diff);
+        Free(st);
+        DCDel(diff);
+        Free(scrncast.dc->body);
+        scrncast.dc->body=MAllocIdent(scrncast.dc2_alias->body);
+      }
+    } else if (scrncast.dc) {
+      DCDel(scrncast.dc); //TODO: MemRep can crash.
+      scrncast.dc=NULL;
+    }
+    if (sys_focus_task && !Bt(&sys_focus_task->task_flags,TASKf_HAS_SONG)) {
+      Free(music.cur_song);
+      music.cur_song=NULL;
+    }
+    if (music.cur_song) {
+      if (!music.cur_song_task)
+        music.cur_song_task=Spawn(&CurSongTask,NULL,"Song");
+    } else if (music.cur_song_task) {
+      Kill(music.cur_song_task);
+      music.cur_song_task=NULL;
+    }
+    winmgr.updates++;
+    if (ms_hard.install_attempts) //Don't call before boot mouse install attempt
+      KbdMsHndlr(FALSE,TRUE);
+    SleepUntil(timeout_val);
+  }
+  return msg_code;
+}
+
+CDoc *WinCursorPosSet(CTask *task,I64 msx,I64 msy,Bool set_cursor=TRUE)
+{
+  CDoc *res=NULL;
+  Bool unlock;
+  I64 x0,y0;
+  if (!task) task=Fs;
+  if (WinInside(msx,msy,task)) {
+    if ((res=DocDisplay(task)) && res->flags&DOCF_DONT_SHOW)
+      res=NULL;
+    else if (set_cursor) {
+      unlock=DocLock(res);
+      if (res->doc_signature!=DOC_SIGNATURE_VAL)
+        res=NULL;
+      else {
+        x0=res->line_start_col;
+        y0=res->top_line_num;
+        DocRecalc(res,RECALCF_HAS_CURSOR);
+        res->x=(msx-task->pix_left-task->scroll_x)/FONT_WIDTH +x0;
+        res->y=(msy-task->pix_top -task->scroll_y)/FONT_HEIGHT+y0;
+        DocRecalc(res,RECALCt_FIND_CURSOR);
+        task->scroll_x=0;
+        task->scroll_y=0;
+        task->scroll_z=0;
+        if (unlock)
+          DocUnlock(res);
+      }
+    }
+    WinToTop(task);
+  }
+  return res;
+}
+
+Bool WinKeyNavMenu()
+{
+  I64 i,old_key_cnt;
+  CD3I64 old_pos,new_pos;
+  CMenu *m;
+  CMenuEntry *tmpme;
+  CTask *focus=MenuTask;
+  if (Bt(kbd.down_bitmap,SC_GUI) && focus && (m=focus->cur_menu)) {
+    winmgr.show_menu=TRUE;
+    sys_cur_submenu_entry=NULL;
+    old_pos.x=ms.pos.x; old_pos.y=ms.pos.y;
+    ms.pos.x=new_pos.x=ms.pos.y=new_pos.y=0;
+    while (Bt(kbd.down_bitmap,SC_GUI)) {
+      old_key_cnt=kbd.cnt;
+      if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_LEFT) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        if (new_pos.x) {
+          i=0;
+          tmpme=m->sub;
+          while (tmpme) {
+            if (i+MenuEntryWidth(tmpme)*FONT_WIDTH==new_pos.x) {
+              new_pos.x=i;
+              break;
+            }
+            i+=MenuEntryWidth(tmpme)*FONT_WIDTH;
+            tmpme=tmpme->next;
+          }
+        }
+        new_pos.y=0;
+      } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        i=0;
+        tmpme=m->sub;
+        while (tmpme) {
+          if (i==new_pos.x) {
+            if (tmpme->next)
+              new_pos.x=i+MenuEntryWidth(tmpme)*FONT_WIDTH;
+            break;
+          }
+          i+=MenuEntryWidth(tmpme)*FONT_WIDTH;
+          tmpme=tmpme->next;
+        }
+        new_pos.y=0;
+      } else if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_UP) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        new_pos.y-=FONT_HEIGHT;
+      } else if (Bt(kbd.down_bitmap,SC_CURSOR_DOWN)) {
+        while (Bt(kbd.down_bitmap,SC_CURSOR_DOWN) && kbd.cnt==old_key_cnt)
+          WinMgrSleep(TRUE);
+        new_pos.y+=FONT_HEIGHT;
+      }
+      new_pos.x=ClampI64(new_pos.x,0,GR_WIDTH-1);
+      new_pos.y=ClampI64(new_pos.y,0,GR_HEIGHT-1);
+      ms.pos.x=new_pos.x; ms.pos.y=new_pos.y;
+      WinMgrSleep(TRUE);
+      if (!sys_cur_submenu_entry)
+        ms.pos.y=new_pos.y=0;
+    }
+    if (sys_cur_submenu_entry)
+      TaskMsg(sys_focus_task,0,sys_cur_submenu_entry->msg_code,
+            sys_cur_submenu_entry->arg1,sys_cur_submenu_entry->arg2,0);
+    winmgr.show_menu=FALSE;
+    ms.pos.x=old_pos.x; ms.pos.y=old_pos.y;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+U0 WinMgrTask(I64)
+{
+  CTask *task=Fs;
+  CDoc *doc;
+  CDocEntry *doc_e;
+  I64 x,y,z,msg_code,
+        my_ms_z=0,left,top,
+        old_flags=GetRFlags;
+  Bool has_border;
+  CCtrl *c;
+  WinHorz(0,TEXT_COLS-1);
+  WinVert(0,TEXT_ROWS-1);
+  LBts(&Fs->display_flags,DISPLAYf_NO_BORDER);
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  gr.dc->win_task=Fs;
+  Fs->win_inhibit&=~WIF_SELF_CTRLS;
+  GrSetUpTables;
+  scrncast.dc2_alias=DCAlias(gr.dc2);
+  WinZBufUpdate;
+  LBts(&sys_run_level,RLf_WINMGR);
+  while (TRUE) {
+    try {
+wmt_start:
+      if (Bt(&sys_run_level,RLf_ADAM_SERVER))
+        TaskKillDying;
+      WinMgrSleep;
+
+      task=Fs->last_task;
+      while (TRUE) {
+        CLI
+        if (!TaskValidate(task)) {
+          SetRFlags(old_flags);
+          goto wmt_start;
+        }
+        TaskDerivedValsUpdate(task,FALSE);
+        task=task->last_task;
+        SetRFlags(old_flags);
+        if (task==Fs)
+          break;
+      }
+      TaskDerivedValsUpdate(Fs,FALSE);
+
+      task=Fs->last_task;
+      while (TRUE) {
+        CLI
+        if (!TaskValidate(task)) {
+          SetRFlags(old_flags);
+          goto wmt_start;
+        }
+        if (WinInside(ms.pos.x,ms.pos.y,task,FONT_WIDTH)) {
+          SetRFlags(old_flags);
+          break;
+        }
+        if (task==Fs) { //Shouldn't happen
+          SetRFlags(old_flags);
+          goto wmt_start;
+        }
+        task=task->last_task;
+        SetRFlags(old_flags);
+      }
+
+      if (Bt(&task->display_flags,DISPLAYf_NO_BORDER))
+        has_border=FALSE;
+      else
+        has_border=TRUE;
+
+      winmgr.show_menu=FALSE;
+      sys_cur_submenu_entry=NULL;
+      if (TaskValidate(sys_focus_task) &&
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MENU)) {
+        if (WinKeyNavMenu)
+          goto wmt_start;
+        if (task==Fs && 0<=ms.pos.y<FONT_HEIGHT && ms_hard.installed) {
+          winmgr.show_menu=TRUE;
+          if (ms.lb && !old_ms.lb) {
+            winmgr.show_menu=TRUE;
+            while (ms.lb)
+              WinMgrSleep(TRUE);
+            if (sys_cur_submenu_entry)
+              TaskMsg(sys_focus_task,0,
+                    sys_cur_submenu_entry->msg_code,
+                    sys_cur_submenu_entry->arg1,
+                    sys_cur_submenu_entry->arg2,0);
+            winmgr.show_menu=FALSE;
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+
+      //grab scroll
+      if (!Bt(&task->win_inhibit,WIf_SELF_GRAB_SCROLL) &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_GRAB_SCROLL)) &&
+            kbd.scan_code&SCF_CTRL && TaskValidate(task)) {
+        winmgr.grab_scroll_closed=FALSE;
+        winmgr.grab_scroll=TRUE;
+        while (kbd.scan_code&SCF_CTRL && TaskValidate(task) && (!ac.task ||
+              !WinInside(ms.pos.x,ms.pos.y,ac.task,FONT_WIDTH))) {
+          if (ms.lb) {
+            winmgr.grab_scroll_closed=TRUE;
+            x=ms.pos.x-task->scroll_x;
+            y=ms.pos.y-task->scroll_y;
+            z=ms.pos.z-task->scroll_z;
+            while (ms.lb && kbd.scan_code&SCF_CTRL && TaskValidate(task)) {
+              task->scroll_x=(ms.pos.x-x)&~7;
+              task->scroll_y=(ms.pos.y-y)&~7;
+              task->scroll_z=ms.pos.z-z;
+              WinMgrSleep(TRUE);
+            }
+            winmgr.grab_scroll_closed=FALSE;
+          } else if (ms.rb)  {
+            task->scroll_x=0;
+            task->scroll_y=0;
+            task->scroll_z=0;
+            WinMgrSleep(TRUE);
+          } else
+            WinMgrSleep;
+        }
+        winmgr.grab_scroll=FALSE;
+        goto wmt_start;
+      } else
+        winmgr.grab_scroll=FALSE;
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_CTRLS) &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_CTRLS))) {
+        if (ms.lb && !old_ms.lb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->flags&CTRLF_CAPTURE_LEFT_MS) {
+                while (ms.lb && TaskValidate(task)) {
+                  if (c->left_click)
+                    (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                  WinMgrSleep;
+                }
+                if (c->left_click)
+                  (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+                old_ms.lb=FALSE;
+                goto wmt_start;
+              } else {
+                if (c->left_click)
+                  (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                old_ms.lb=TRUE;
+                goto wmt_start;
+              }
+            }
+            c=c->next;
+          }
+        }
+        if (old_ms.lb && !ms.lb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->left_click)
+                (*c->left_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+              old_ms.lb=FALSE;
+              goto wmt_start;
+            }
+            c=c->next;
+          }
+        }
+        if (ms.rb && !old_ms.rb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->flags&CTRLF_CAPTURE_RIGHT_MS) {
+                while (ms.rb && TaskValidate(task)) {
+                  if (c->right_click)
+                    (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                  WinMgrSleep;
+                }
+                if (c->right_click)
+                  (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+                old_ms.rb=FALSE;
+                goto wmt_start;
+              } else {
+                if (c->right_click)
+                  (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,TRUE);
+                old_ms.rb=TRUE;
+                goto wmt_start;
+              }
+            }
+            c=c->next;
+          }
+        }
+        if (old_ms.rb && !ms.rb) {
+          c=task->next_ctrl;
+          while (c!=&task->next_ctrl) {
+            if (CtrlInside(c,ms.pos.x,ms.pos.y)) {
+              left=task->pix_left;
+              top =task->pix_top;
+              if (c->flags&CTRLF_BORDER) {
+                left-=FONT_WIDTH;
+                top -=FONT_HEIGHT;
+              }
+              if (c->right_click)
+                (*c->right_click)(c,ms.pos.x-left,ms.pos.y-top,FALSE);
+              old_ms.rb=FALSE;
+              goto wmt_start;
+            }
+            c=c->next;
+          }
+        }
+        if (ms.has_wheel && my_ms_z!=ms.pos.z) {
+          if (task==sys_focus_task) {
+            c=task->next_ctrl;
+            while (c!=&task->next_ctrl) {
+              if (c->wheel_chg) {
+                (*c->wheel_chg)(c,ms.pos.z-my_ms_z);
+                my_ms_z=ms.pos.z;
+                goto wmt_start;
+              }
+              c=c->next;
+            }
+            my_ms_z=ms.pos.z;
+          } else if (!sys_focus_task)
+            my_ms_z=ms.pos.z;
+        }
+      }
+
+      if (task==Fs)
+        goto wmt_start;
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_L)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_L))) {
+        if (!old_ms.lb && ms.lb) {
+          if (doc=WinCursorPosSet(task,ms.pos.x,ms.pos.y)) {
+            DocLock(doc);
+            if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+              doc_e=doc->cur_entry;
+              if (doc_e!=doc) {
+                if (doc_e->de_flags & DOCEF_HAS_BORDER)
+                  doc_e->de_flags|=DOCEF_SOLID_BORDER;
+              }
+            }
+            DocUnlock(doc);
+            old_ms.lb=TRUE;
+            goto wmt_start;
+          }
+        }
+      }
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_R)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_R))) {
+        if (!old_ms.rb && ms.rb) {
+          if (WinCursorPosSet(task,ms.pos.x,ms.pos.y)) {
+            old_ms.rb=TRUE;
+            goto wmt_start;
+          }
+        }
+      }
+      if (!Bt(&task->win_inhibit,WIf_SELF_BORDER) && has_border &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_BORDER))) {
+        if (old_ms.lb && !ms.lb) {
+          if (ms.pos_text.y==task->win_top-1) {
+            if (task->win_left<=ms.pos_text.x<task->win_left+4) {
+              TaskMsg(task,0,MSG_KEY_DOWN,CH_CTRLM,0x43200000432,0);
+              old_ms.lb=FALSE;
+              goto wmt_start;
+            } else if (task->win_right-2<=ms.pos_text.x<=task->win_right) {
+              if (DocPut(task))
+                TaskMsg(task,0,MSG_KEY_DOWN,CH_SHIFT_ESC,0,0);
+              else
+                Kill(task,FALSE);
+              old_ms.lb=FALSE;
+              goto wmt_start;
+            }
+          }
+        }
+      }
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_L)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_L))) {
+        if (old_ms.lb && !ms.lb) {
+          if (doc=WinCursorPosSet(task,ms.pos.x,ms.pos.y,FALSE)) {
+            do msg_code=WinMgrSleep;
+            while (TaskValidate(task) && (ms.lb || ms.left_dbl_time));
+            if (TaskValidate(task)) {
+              if (msg_code==MSG_MS_L_UP) {
+                if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                  DocLock(doc);
+                  if (TaskValidate(task)) {
+                    if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                      doc_e=doc->cur_entry;
+                      if (doc_e!=doc) {
+                        if (doc_e->de_flags & DOCEF_HAS_BORDER)
+                          doc_e->de_flags&=~DOCEF_SOLID_BORDER;
+                        if (doc_e->de_flags & (DOCEF_TREE|DOCEF_LST|
+                              DOCEF_LINK|DOCEF_CHECK_COLLAPSABLE|
+                              DOCEF_LEFT_CB|DOCEF_LEFT_MACRO|DOCEF_LEFT_EXP))
+                          TaskMsg(task,0,MSG_KEY_DOWN,CH_SPACE,0,0);
+                      }
+                    }
+                    DocUnlock(doc);
+                  }
+                }
+              } else if (msg_code==MSG_MS_L_D_UP)
+                TaskMsg(task,0,MSG_KEY_DOWN,CH_ESC,0,0);
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_MS_R)&&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_MS_R))) {
+        if (old_ms.rb && !ms.rb) {
+          if (doc=WinCursorPosSet(task,ms.pos.x,ms.pos.y,FALSE)) {
+            do msg_code=WinMgrSleep;
+            while (TaskValidate(task) && (ms.rb || ms.right_dbl_time));
+            if (TaskValidate(task)) {
+              if (msg_code==MSG_MS_R_UP) {
+                if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                  DocLock(doc);
+                  if (TaskValidate(task)) {
+                    if (doc->doc_signature==DOC_SIGNATURE_VAL) {
+                      doc_e=doc->cur_entry;
+                      if (doc_e!=doc) {
+                        if (doc_e->de_flags&(DOCEF_LINK|
+                              DOCEF_RIGHT_CB|DOCEF_RIGHT_MACRO|DOCEF_RIGHT_EXP))
+                          TaskMsg(task,0,MSG_KEY_DOWN,'\n',0,0);
+                      }
+                    }
+                    DocUnlock(doc);
+                  }
+                }
+              } else if (msg_code==MSG_MS_R_D_UP)
+                TaskMsg(task,0,MSG_KEY_DOWN,CH_SHIFT_ESC,0,0);
+            }
+            old_ms.rb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+
+      if (!Bt(&task->win_inhibit,WIf_SELF_BORDER) && has_border &&
+            (!TaskValidate(sys_focus_task)||
+            !Bt(&sys_focus_task->win_inhibit,WIf_FOCUS_TASK_BORDER))) {
+        if (ms.lb && !old_ms.lb) {
+          if (task->win_top==ms.pos_text.y+1 &&
+                task->win_left-1<=ms.pos_text.x<=task->win_right+1) {
+            if (task->win_left<=ms.pos_text.x<task->win_left+4) {
+              old_ms.lb=TRUE;
+              goto wmt_start;
+            }
+            if (task->win_right-2<=ms.pos_text.x<=task->win_right) {
+              old_ms.lb=TRUE;
+              goto wmt_start;
+            }
+            x=ms.pos_text.x-task->win_left;
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(ms.pos_text.x-x,task->win_width-1+ms.pos_text.x-x,task);
+                WinVert(ms.pos_text.y+1,task->win_height+ms.pos_text.y,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_left==ms.pos_text.x+1 &&
+                task->win_top-1<=ms.pos_text.y<=task->win_bottom+1) {
+            y=ms.pos_text.y-task->win_top;
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(ms.pos_text.x+1,task->win_width+ms.pos_text.x,task);
+                WinVert(ms.pos_text.y-y,
+                      task->win_height-1+ms.pos_text.y-y,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_right+1==ms.pos_text.x &&
+                task->win_bottom+1==ms.pos_text.y) {
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(task->win_left,ms.pos_text.x-1,task);
+                WinVert(task->win_top,ms.pos_text.y-1,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_bottom==ms.pos_text.y-1 &&
+                task->win_left<=ms.pos_text.x<=task->win_right) {
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinVert(task->win_top,ms.pos_text.y-1,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+          if (task->win_right==ms.pos_text.x-1 &&
+                task->win_top<=ms.pos_text.y<=task->win_bottom) {
+            if (ms.lb) {
+              WinToTop(task);
+              while (ms.lb && TaskValidate(task)) {
+                WinHorz(task->win_left,ms.pos_text.x-1,task);
+                WinMgrSleep;
+              }
+            }
+            old_ms.lb=FALSE;
+            goto wmt_start;
+          }
+        }
+      }
+    } catch {
+      Beep;
+      Fs->catch_except=TRUE;
+      task=Fs;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/Accts.DD.HTML b/public/Wb/Home/Src/Apps/Budget/Accts.DD.HTML new file mode 100755 index 0000000..24298ee --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/Accts.DD.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+JOB
+BANK
+CREDIT
+CASH
+RENT
+CAR
+UTILITIES
+MISC
+CLOTHS
+HEALTH
+CHARITY
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/BgtAccts.HC.HTML b/public/Wb/Home/Src/Apps/Budget/BgtAccts.HC.HTML new file mode 100755 index 0000000..55a5316 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/BgtAccts.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+U0 BgtAcctsUpdate()
+{
+  CBgtEntry     *tmpb;
+  CBgtTemplate  *tmpt;
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    if (tmpb->type!=BE_TEMPLATE_COPY) {
+      tmpb->credit_idx=StrFileAdd(tmpb->credit,
+            &accts_table_strs,accts_table);
+      tmpb->debit_idx =StrFileAdd(tmpb->debit,
+            &accts_table_strs,accts_table);
+    }
+    tmpb=tmpb->next;
+  }
+  tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    tmpt->b.credit_idx=StrFileAdd(tmpt->b.credit,
+          &accts_table_strs,accts_table);
+    tmpt->b.debit_idx =StrFileAdd(tmpt->b.debit,
+          &accts_table_strs,accts_table);
+    tmpt=tmpt->next;
+  }
+}
+
+U0 BgtAcctsWrite()
+{
+  BgtAcctsUpdate;
+  StrFileWrite(bgt_accts_file,accts_table,TRUE);
+}
+
+U0 BgtAcctsRead()
+{
+  I64   i,max_num;
+  U8    *colors,**s=StrFileRead(bgt_accts_file,&max_num,&colors,TRUE);
+  StrFileDel(accts_table);
+  accts_table=HashTableNew(512);
+  accts_table_strs=0;
+  for (i=0;i<=max_num;i++)
+    if (s[i])
+      StrFileAdd(s[i],&accts_table_strs,accts_table,colors[i]);
+  StrFileArrDel(s,max_num);
+  Free(colors);
+}
+
+I64 BgtAcctColor(U8 *st)
+{
+  CHashGeneric *tmph;
+  if (tmph=HashFind(st,accts_table,SFT_GENERIC))
+    return tmph->user_data1;
+  else
+    return BLACK;
+}
+
+U8 *BgtPopUpAcct(U8 *header=NULL,U8 *dft=NULL)
+{
+  I64 i;
+  U8 *res;
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e,*doc_dft=NULL;
+  CHashGeneric *tmph;
+
+  if (header)
+    DocPrint(doc,"%s",header);
+
+  for (i=0;i<=accts_table->mask;i++) {
+    tmph=accts_table->body[i];
+    while (tmph) {
+      doc_e=DocPrint(doc,"$FG,%d$$MU-UL,\"%s\",LE=0x%X$\n",
+            tmph->user_data1,tmph->str,tmph->str);
+      if (dft && !StrCmp(dft,tmph->str))
+        doc_dft=doc_e;
+      tmph=tmph->next;
+    }
+  }
+
+  if (doc_dft) {
+    doc->cur_entry=doc_dft;
+    doc->cur_col=0;
+  }
+  res=PopUpMenu(doc,DOF_DONT_HOME);
+  DocDel(doc);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/BgtEntry.HC.HTML b/public/Wb/Home/Src/Apps/Budget/BgtEntry.HC.HTML new file mode 100755 index 0000000..063c4cc --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/BgtEntry.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+U0 BgtEntryDel2(CBgtEntry *tmpb)
+{
+  if (tmpb->type!=BE_TEMPLATE_COPY) {
+    Free(tmpb->credit);
+    Free(tmpb->debit);
+    Free(tmpb->desc);
+  }
+}
+
+CBgtEntry *BgtEntryCopy(CBgtEntry *tmpb,Bool periodic_copy)
+{
+  CBgtEntry *res=MAlloc(sizeof(CBgtEntry));
+  MemCpy(res,tmpb,sizeof(CBgtEntry));
+  if (periodic_copy) {
+    res->credit=StrNew(tmpb->credit);
+    res->debit =StrNew(tmpb->debit);
+    res->desc  =StrNew(tmpb->desc);
+  }
+  return res;
+}
+
+U0 BgtEntryDel(CBgtEntry *tmpb)
+{
+  BgtEntryDel2(tmpb);
+  Free(tmpb);
+}
+
+U0 BgtIns(CBgtEntry *tmpb)
+{
+  CBgtEntry     *tmpb1=b_head.next;
+  while (tmpb1!=&b_head && tmpb1->date<tmpb->date)
+    tmpb1=tmpb1->next;
+  QueIns(tmpb,tmpb1->last);
+}
+
+class CBgtEntryForm
+{
+  U8    date[512]       format "$DA-P,A=\"Date              :%s\"$\n";
+  F64   amount          format "Amount            $$$DA,A=\"%10.2f\"$\n";
+  U8    credit[512]     format "$DA-P,A=\"Credit (from) Acct:%s\"$\n";
+  U8    debit [512]     format "$DA-P,A=\"Debit  (to)   Acct:%s\"$\n";
+  U8    desc  [512]     format "$DA-P,A=\"Desc              :%s\"$\n";
+};
+
+CBgtEntry *BgtEntryPmt(CBgtEntry *dft=NULL)
+{
+  CBgtEntryForm b;
+  CBgtEntry *tmpb;
+  U8 *st;
+  MemSet(&b,0,sizeof(CBgtEntryForm));
+  StrCpy(&b.date,"*");
+  if (dft) {
+    StrPrint(b.date,"%D",dft->date);
+    b.amount=dft->amount;
+    StrCpy(b.credit,dft->credit);
+    StrCpy(b.debit ,dft->debit);
+    StrCpy(b.desc  ,dft->desc);
+  }
+  while (TRUE)
+    if (PopUpForm(&b)) {
+      if (!*b.credit) {
+        st=BgtPopUpAcct("Credit Acct\n\n");
+        if (st!=DOCM_CANCEL)
+          StrCpy(b.credit,st);
+      } else if (!*b.debit) {
+        st=BgtPopUpAcct("Debit Acct\n\n");
+        if (st!=DOCM_CANCEL)
+          StrCpy(b.debit,st);
+      } else {
+        tmpb=CAlloc(sizeof(CBgtEntry));
+        tmpb->date  =Str2Date(b.date);
+        tmpb->amount=b.amount;
+        tmpb->credit=StrNew(b.credit);
+        tmpb->debit =StrNew(b.debit);
+        tmpb->desc  =StrNew(b.desc);
+        tmpb->type  =BE_NORMAL;
+        StrFileAdd(tmpb->credit,&accts_table_strs,accts_table);
+        StrFileAdd(tmpb->debit,&accts_table_strs,accts_table);
+        return tmpb;
+      }
+    } else
+      return NULL;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/BgtFile.HC.HTML b/public/Wb/Home/Src/Apps/Budget/BgtFile.HC.HTML new file mode 100755 index 0000000..660e642 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/BgtFile.HC.HTML @@ -0,0 +1,171 @@ + + + + + + + + + + + +
+U0 BgtDataRead()
+{
+  CBgtEntry     *tmpb;
+  CBgtTemplate  *tmpt;
+  I64           i,cnt,size;
+  U8            *b,*ptr;
+  I64           max_num;
+  U8            **s=StrFileRead(bgt_string_file,&max_num);
+
+  MemSet(&b_head,0,sizeof(CBgtEntry));
+  QueInit(&b_head);
+  b_head.date=Now;
+  MemSet(&t_head,0,sizeof(CBgtTemplate));
+  QueInit(&t_head);
+  t_head.b.date=Now;
+
+  if (ptr=b=FileRead(bgt_data_file,&size)) {
+    cnt=*ptr(I64 *)++;
+    for (i=0;i<cnt;i++) {
+      tmpb=CAlloc(sizeof(CBgtEntry));
+      MemCpy(&tmpb->start,ptr,BE_SIZE);
+      tmpb->credit=StrNew(s[tmpb->credit_idx]);
+      tmpb->debit =StrNew(s[tmpb->debit_idx]);
+      tmpb->desc  =StrNew(s[tmpb->desc_idx]);
+      QueIns(tmpb,b_head.last);
+      ptr+=BE_SIZE;
+    }
+
+    cnt=*ptr(I64 *)++;
+    for (i=0;i<cnt;i++) {
+      tmpt=CAlloc(sizeof(CBgtTemplate));
+      MemCpy(&tmpt->start,ptr,BT_SIZE);
+      ptr+=BT_SIZE;
+      MemCpy(&tmpt->b.start,ptr,BE_SIZE);
+      ptr+=BE_SIZE;
+      tmpt->b.credit=StrNew(s[tmpt->b.credit_idx]);
+      tmpt->b.debit =StrNew(s[tmpt->b.debit_idx]);
+      tmpt->b.desc  =StrNew(s[tmpt->b.desc_idx]);
+      QueIns(tmpt,t_head.last);
+    }
+  }
+
+  StrFileArrDel(s,max_num);
+  Free(b);
+
+  BgtAcctsUpdate;
+}
+
+U0 BgtDataWrite()
+{
+  I64 i,num=0,size,cnt1,cnt2;
+  CHashTable    *table=HashTableNew(1024);
+  CBgtEntry     *tmpb;
+  CBgtTemplate  *tmpt;
+  CHashGeneric *tmph;
+  U8 *buf,*ptr;
+
+  for (i=0;i<=accts_table->mask;i++) {
+    tmph=accts_table->body[i];
+    while (tmph) {
+      StrFileAdd(tmph->str,&num,table); //Cosmetics -- make accts appear first.
+      tmph=tmph->next;
+    }
+  }
+
+  tmpb=b_head.next;
+  cnt1=0;
+  while (tmpb!=&b_head) {
+    if (tmpb->type!=BE_TEMPLATE_COPY) {
+      tmpb->credit_idx  =StrFileAdd(tmpb->credit,&num,table);
+      tmpb->debit_idx   =StrFileAdd(tmpb->debit,&num,table);
+      tmpb->desc_idx            =StrFileAdd(tmpb->desc,&num,table);
+      cnt1++;
+    }
+    tmpb=tmpb->next;
+  }
+
+  tmpt=t_head.next;
+  cnt2=0;
+  while (tmpt!=&t_head) {
+    tmpt->b.credit_idx  =StrFileAdd(tmpt->b.credit,&num,table);
+    tmpt->b.debit_idx   =StrFileAdd(tmpt->b.debit,&num,table);
+    tmpt->b.desc_idx            =StrFileAdd(tmpt->b.desc,&num,table);
+    cnt2++;
+    tmpt=tmpt->next;
+  }
+  StrFileWrite(bgt_string_file,table);
+  StrFileDel(table);
+
+  size=sizeof(I64)*2+cnt1*BE_SIZE+cnt2*(BT_SIZE+BE_SIZE);
+  buf=ptr=MAlloc(size);
+
+  MemCpy(ptr,&cnt1,sizeof(I64));
+  ptr+=sizeof(I64);
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    if (tmpb->type!=BE_TEMPLATE_COPY) {
+      MemCpy(ptr,&tmpb->start,BE_SIZE);
+      ptr+=BE_SIZE;
+    }
+    tmpb=tmpb->next;
+  }
+
+  MemCpy(ptr,&cnt2,sizeof(I64));
+  ptr+=sizeof(I64);
+  tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    MemCpy(ptr,&tmpt->start,BT_SIZE);
+    ptr+=BT_SIZE;
+    MemCpy(ptr,&tmpt->b.start,BE_SIZE);
+    ptr+=BE_SIZE;
+    tmpt=tmpt->next;
+  }
+
+  FileWrite(bgt_data_file,buf,size);
+  Free(buf);
+}
+
+U0 BgtDel()
+{
+  CBgtEntry     *tmpb,*tmpb1;
+  CBgtTemplate  *tmpt,*tmpt1;
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    tmpb1=tmpb->next;
+    BgtEntryDel2(tmpb);
+    Free(tmpb);
+    tmpb=tmpb1;
+  }
+  tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    tmpt1=tmpt->next;
+    BgtEntryDel2(&tmpt->b);
+    Free(tmpt);
+    tmpt=tmpt1;
+  }
+  StrFileDel(accts_table);
+  accts_table=NULL;
+  accts_table_strs=0;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/BgtMain.HC.HTML b/public/Wb/Home/Src/Apps/Budget/BgtMain.HC.HTML new file mode 100755 index 0000000..ce86b2d --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/BgtMain.HC.HTML @@ -0,0 +1,261 @@ + + + + + + + + + + + +
+extern U0 BgtRegen();
+
+Bool BgtPutKey(CDoc *doc,U8 *,I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+  no_warn sc;
+  CBgtEntry *tmpb,*tmpb1;
+  CBgtTemplate *tmpt,*tmpt1;
+  CDocEntry *doc_ce;
+  U8 *st;
+  switch (ch) {
+    case '\n':
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL) {
+        tmpb=doc_ce->user_data;
+        if (tmpt=tmpb->template) {
+          if (tmpt1=BgtTemplatePmt(tmpt)) {
+            QueRem(tmpt);
+            BgtTemplatePurge(tmpt);
+            BgtEntryDel2(&tmpt->b);
+            Free(tmpt);
+            QueIns(tmpt1,t_head.last);
+            BgtTemplateExpand(tmpt1);
+            BgtRegen;
+          }
+        } else {
+          if (tmpb1=BgtEntryPmt(tmpb)) {
+            QueRem(tmpb);
+            BgtEntryDel(tmpb);
+            BgtIns(tmpb1);
+            BgtRegen;
+          }
+        }
+      }
+      return TRUE;
+    case CH_CTRLY:
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL) {
+        tmpb=doc_ce->user_data;
+        if (tmpt=tmpb->template) {
+          QueRem(tmpt);
+          BgtTemplateDel(tmpt);
+        } else {
+          QueRem(tmpb);
+          BgtEntryDel(tmpb);
+        }
+        BgtRegen;
+      }
+      return TRUE;
+    case 'a':
+      PopUpOk(  "Set the name and color of your accounts.\n"
+            "To delete accounts, manually edit\n"
+            "$GREEN$~/Budget/Accts.DD.Z$FG$.");
+      if (PopUpEd(bgt_accts_file,Fs)) {
+        BgtAcctsRead;
+        BgtRegen;
+      }
+      return TRUE;
+    case 'v':
+      if ((st=BgtPopUpAcct("View Acct\n\n",view_acct))>=0) {
+        StrCpy(view_acct,st);
+        BgtRegen;
+      }
+      return TRUE;
+    case 'n':
+      if (tmpb1=BgtEntryPmt) {
+        BgtIns(tmpb1);
+        BgtRegen;
+      }
+      return TRUE;
+    case 't':
+      if (tmpt1=BgtTemplatePmt) {
+        QueIns(tmpt1,t_head.last);
+        BgtTemplateExpand(tmpt1);
+        BgtRegen;
+      }
+      return TRUE;
+    case 'c':
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL)
+        tmpb=doc_ce->user_data;
+      else
+        tmpb=NULL;
+      if (tmpb1=BgtEntryPmt(tmpb)) {
+        BgtIns(tmpb1);
+        BgtRegen;
+      }
+      return TRUE;
+    case 'p':
+      if ((doc_ce=doc->cur_entry) && doc_ce!=doc &&
+            doc_ce->type_u8==DOCT_MENU_VAL) {
+        tmpb=doc_ce->user_data;
+        if (tmpt1=BgtTemplatePmt(,tmpb)) {
+          BgtTemplateExpand(tmpt1,TRUE);
+          BgtTemplateDel(tmpt1);
+          BgtRegen;
+        }
+      }
+      return TRUE;
+  }
+  return FALSE;
+}
+
+U0 BgtRegen()
+{
+  I64 timeout_jiffy,c,color=COLOR_INVALID;
+  F64 balance=0;
+  CDoc *doc,*pdoc,*ddoc;
+  CDocEntry *doc_ce;
+  CBgtEntry *tmpb=b_head.next,*tmpb_ce;
+  doc=DocNew;
+  doc->flags|=DOCF_FORM;
+  while (tmpb!=&b_head) {
+    if (!StrCmp(view_acct,tmpb->credit))
+      balance-=tmpb->amount;
+    if (!StrCmp(view_acct,tmpb->debit))
+      balance+=tmpb->amount;
+    c=BgtAcctColor(tmpb->credit);
+    if (c!=color) {
+      color=c;
+      DocPrint(doc,"$FG,%d$",color);
+    }
+    tmpb->doc_e=DocPrint(doc,
+          "$MU-UL,\"%D %8ts %8ts:%8.2f %8.2f:%$Q\",U=0x%X$\n",
+          tmpb->date,tmpb->credit,tmpb->debit,balance,
+          tmpb->amount,tmpb->desc,tmpb);
+    tmpb=tmpb->next;
+  }
+  DocRecalc(doc);
+
+  if (pdoc=Fs->put_doc) {
+    DocLock(pdoc);
+//Now, we want to preserve old position in doc, using ugly brute force.
+    //It's tricky -- can't use old line num because of editor filters.
+
+    //The price we pay for using the standard document editor is this kludge.
+    //When I originally wrote my budget program, I did not have separate budget
+    //and line entries, so we never had to resync.
+
+    doc_ce=pdoc->cur_entry;
+    timeout_jiffy=cnts.jiffies+JIFFY_FREQ; //Max one second.
+    while (doc_ce!=pdoc && cnts.jiffies<timeout_jiffy) {
+      while (doc_ce->type_u8!=DOCT_MENU_VAL || !(tmpb_ce=doc_ce->user_data)) {
+        doc_ce=doc_ce->next;
+        if (doc_ce==pdoc) goto br_cont;
+      }
+      tmpb=b_head.next;
+      while (tmpb!=&b_head) {
+        if (tmpb==tmpb_ce) {
+          doc->cur_entry=tmpb->doc_e;
+          doc->cur_col=0;
+          DocCenter(doc);
+          goto br_cont;
+        }
+        tmpb=tmpb->next;
+      }
+      doc_ce=doc_ce->next;
+    }
+  }
+
+  br_cont:
+  ddoc=Fs->display_doc;
+  Fs->put_doc    =doc;
+  Fs->display_doc=doc;
+  DocDel(pdoc);
+  if (pdoc!=ddoc)
+    DocDel(ddoc);
+  doc->user_put_key=&BgtPutKey;
+}
+
+U0 Budget(U8 *dirname="~/Budget")
+{
+  CDoc *pdoc,*ddoc,*old_put,*old_display;
+
+  Cd(dirname);
+  bgt_string_file       =FileNameAbs("Strs.DD.Z");
+  bgt_accts_file        =FileNameAbs("Accts.DD.Z");
+  bgt_data_file         =FileNameAbs("Bgt.DATA.Z");
+
+  BgtAcctsRead;
+  BgtDataRead;
+  CBgtTemplatesExpand;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  NewEntry(,'n');"
+        "  CopyEntry(,'c');"
+        "  PeriodicEntry(,'p');"
+        "  EditEntry(,'\n');"
+        "  DeleteEntry(,CH_CTRLY);"
+        "  NewTemplate(,'t');"
+        "  AcctsFile(,'a');"
+        "}"
+        "View {"
+        "  ViewAcct(,'v');"
+        "}"
+        );
+  StrCpy(view_acct,"BANK");
+  DocMax;
+  old_put        =Fs->put_doc;
+  old_display    =Fs->display_doc;
+  Fs->put_doc    =NULL;
+  Fs->display_doc=NULL;
+  BgtRegen;
+  try
+    if (View) {
+      BgtDataWrite;
+      BgtAcctsWrite;
+    }
+  catch
+    PutExcept;
+
+  pdoc=Fs->put_doc;
+  ddoc=Fs->display_doc;
+  Fs->put_doc    =old_put;
+  Fs->display_doc=old_display;
+  DocDel(pdoc);
+  if (pdoc!=ddoc)
+    DocDel(ddoc);
+
+  SettingsPop;
+  BgtDel;
+  MenuPop;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/BgtStrs.HC.HTML b/public/Wb/Home/Src/Apps/Budget/BgtStrs.HC.HTML new file mode 100755 index 0000000..7eee491 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/BgtStrs.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+#define SFT_GENERIC     1
+
+public U8 **StrFileRead(U8 *name,I64 *_max_num=NULL,
+        U8 **_colors=NULL,Bool no_nums=FALSE)
+{
+  CDoc          *doc=DocRead(name,DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
+  CDocEntry     *doc_e=doc->head.next;
+  I64           i,max_num=0;
+  U8            *ptr,**res,*colors;
+
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      if (no_nums)
+        i=++max_num;
+      else {
+        i=Str2I64(doc_e->tag,,&ptr);
+        if (i>max_num) max_num=i;
+        if (*ptr==',') ptr++;
+        ptr=StrNew(ptr);
+        Free(doc_e->tag);
+        doc_e->tag=ptr;
+      }
+      doc_e->user_data=i;
+    }
+    doc_e=doc_e->next;
+  }
+
+  res=CAlloc(sizeof(U8 *)*(max_num+1));
+  colors=CAlloc(sizeof(U8)*(max_num+1));
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT && 0<=doc_e->user_data<=max_num) {
+      res[doc_e->user_data]=doc_e->tag;
+      doc_e->tag=NULL;
+      colors[doc_e->user_data]=doc_e->type.u8[1]&15;
+    }
+    doc_e=doc_e->next;
+  }
+
+  DocDel(doc);
+  if (_max_num) *_max_num=max_num;
+  if (_colors)
+    *_colors=colors;
+  else
+    Free(colors);
+  return res;
+}
+
+public U0 StrFileArrDel(U8 **a,I64 max_num)
+{
+  I64 i;
+  for (i=0;i<=max_num;i++)
+    Free(a[i]);
+  Free(a);
+}
+
+public I64 StrFileAdd(U8 *st,I64 *_num,
+        CHashTable *table,I64 color=COLOR_INVALID)
+{
+  CHashGeneric *tmph;
+  if (!st) return 0;
+  if (!(tmph=HashFind(st,table,SFT_GENERIC))) {
+    tmph=CAlloc(sizeof(CHashGeneric));
+    tmph->type=SFT_GENERIC;
+    tmph->str=StrNew(st);
+    tmph->user_data0=(*_num)++;
+    HashAdd(tmph,table);
+  }
+  if (color!=COLOR_INVALID)
+    tmph->user_data1=color;
+  return tmph->user_data0;
+}
+
+I64 StrEntriesCompare(CHashGeneric *h1,CHashGeneric *h2)
+{
+  return h1->user_data0-h2->user_data0;
+}
+
+public U0 StrFileWrite(U8 *name,CHashTable *table,Bool no_nums=FALSE)
+{
+  I64 i,j,cnt,color=BLACK;
+  CDoc *doc=DocNew(name);
+  CHashGeneric *tmph,**a;
+  if (table) {
+    cnt=0;      //Count Strings
+    for (i=0;i<=table->mask;i++)
+      cnt+=LinkedLstCnt(table->body[i]);
+    a=MAlloc(cnt*sizeof(CHashGeneric *));
+    j=0;        //Load Strings
+    for (i=0;i<=table->mask;i++) {
+      tmph=table->body[i];
+      while (tmph) {
+        a[j++]=tmph;
+        tmph=tmph->next;
+      }
+    }
+    QSortI64(a,cnt,&StrEntriesCompare);
+    for (i=0;i<cnt;i++) {
+      tmph=a[i];
+      if (tmph->user_data1&15!=color) {
+        DocPrint(doc,"$FG,%d$",tmph->user_data1&15);
+        color=tmph->user_data1&15;
+      }
+      if (no_nums)
+        DocPrint(doc,"%s\n",tmph->str);
+      else
+        DocPrint(doc,"%d,%s\n",tmph->user_data0,tmph->str);
+    }
+    Free(a);
+  }
+  doc->flags|=DOCF_NO_CURSOR;
+  DocWrite(doc);
+  DocDel(doc);
+}
+
+public U0 StrFileDel(CHashTable *table)
+{
+  I64 i;
+  CHashGeneric *tmph,*tmph1;
+  if (!table) return;
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      tmph1=tmph->next;
+      Free(tmph->str);
+      Free(tmph);
+      tmph=tmph1;
+    }
+  }
+  Free(table->body);
+  Free(table);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/BgtTemplate.HC.HTML b/public/Wb/Home/Src/Apps/Budget/BgtTemplate.HC.HTML new file mode 100755 index 0000000..354c5f3 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/BgtTemplate.HC.HTML @@ -0,0 +1,213 @@ + + + + + + + + + + + +
+U0 BgtTemplatePurge(CBgtTemplate *tmpt)
+{
+  CBgtEntry     *tmpb,*tmpb1;
+  tmpb=b_head.next;
+  while (tmpb!=&b_head) {
+    tmpb1=tmpb->next;
+    if (tmpb->template==tmpt) {
+      QueRem(tmpb);
+      BgtEntryDel2(tmpb);
+      Free(tmpb);
+    }
+    tmpb=tmpb1;
+  }
+}
+
+U0 BgtTemplateDel(CBgtTemplate *tmpt)
+{
+  BgtTemplatePurge(tmpt);
+  BgtEntryDel2(&tmpt->b);
+  Free(tmpt);
+}
+
+U0 BgtTemplateExpand(CBgtTemplate *tmpt,Bool periodic_copy=FALSE)
+{
+  CDate         d,start,end;
+  CDateStruct   ds;
+  CBgtEntry     *tmpb;
+  Bool          first=TRUE;
+
+  start=MyStr2Date(tmpt->start_date);
+  end  =MyStr2Date(tmpt->end_date);
+  tmpt->b.template=tmpt;
+  switch (tmpt->type) {
+    case BT_INTERVAL:
+      d=start;
+      while (d<=end) {
+        if (!first || !periodic_copy) {
+          tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+          tmpb->date=d;
+          if (periodic_copy)
+            tmpb->template=NULL;
+          else
+            tmpb->type=BE_TEMPLATE_COPY;
+          BgtIns(tmpb);
+        }
+        d+=tmpt->period*0x100000000;
+        first=FALSE;
+      }
+      break;
+    case BT_MONTHLY:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        if (++ds.mon>12) {
+          ds.mon=1;
+          ds.year++;
+        }
+        first=FALSE;
+      }
+      break;
+    case BT_BIMONTHLY:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        ds.mon+=2;
+        if (ds.mon>12) {
+          ds.mon-=12;
+          ds.year++;
+        }
+        first=FALSE;
+      }
+      break;
+    case BT_SEMIANNUAL:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        ds.mon+=6;
+        if (ds.mon>12) {
+          ds.mon-=12;
+          ds.year++;
+        }
+        first=FALSE;
+      }
+      break;
+    case BT_ANNUAL:
+      Date2Struct(&ds,start);
+      while (TRUE) {
+        d=Struct2Date(&ds);
+        if (d<=end) {
+          if (!first || !periodic_copy) {
+            tmpb=BgtEntryCopy(&tmpt->b,periodic_copy);
+            tmpb->date=d;
+            if (periodic_copy)
+              tmpb->template=NULL;
+            else
+              tmpb->type=BE_TEMPLATE_COPY;
+            BgtIns(tmpb);
+          }
+        } else
+          break;
+        ds.year++;
+        first=FALSE;
+      }
+      break;
+  }
+}
+
+U0 CBgtTemplatesExpand()
+{
+  CBgtTemplate  *tmpt=t_head.next;
+  while (tmpt!=&t_head) {
+    BgtTemplateExpand(tmpt);
+    tmpt=tmpt->next;
+  }
+}
+
+CBgtTemplate *BgtTemplatePmt(CBgtTemplate *dft_t=NULL,CBgtEntry *dft_b=NULL)
+{
+  CBgtTemplate  t,*tmpt;
+  CBgtEntry     *tmpb;
+  MemSet(&t,0,sizeof(CBgtTemplate));
+  if (dft_t) {
+    MemCpy(&t.start,&dft_t->start,BT_SIZE);
+    dft_b=&dft_t->b;
+  } else {
+    t.type=BT_INTERVAL;
+    if (dft_b)
+      StrPrint(&t.start_date,"%D",dft_b->date);
+    else
+      StrCpy(&t.start_date,"[");
+    StrCpy(&t.end_date,"]");
+  }
+  while (TRUE)
+    if (PopUpForm(&t) && ((t.type==BT_INTERVAL && t.period>0) ||
+          t.type>BT_INTERVAL)) {
+      if (tmpb=BgtEntryPmt(dft_b)) {
+        tmpt=CAlloc(sizeof(CBgtTemplate));
+        MemCpy(&tmpt->start,&t.start,BT_SIZE);
+        MemCpy(&tmpt->b,tmpb,sizeof(CBgtEntry));
+        Free(tmpb);
+        return tmpt;
+      }
+    } else
+      break;
+  return NULL;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/Budget.HC.HTML b/public/Wb/Home/Src/Apps/Budget/Budget.HC.HTML new file mode 100755 index 0000000..c6f7a47 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/Budget.HC.HTML @@ -0,0 +1,108 @@ + + + + + + + + + + + +
+U8 *bgt_string_file;
+U8 *bgt_accts_file;
+U8 *bgt_data_file;
+
+#define BE_NORMAL               0
+#define BE_GAS                  1
+#define BE_ANNIVERSARY          2
+#define BE_PRICE                3
+#define BE_TEMPLATE_COPY        4
+
+extern class CBgtTemplate;
+
+class CBgtEntry
+{
+  CBgtEntry *next,*last;
+
+  U0 start;
+  CDate date;
+  U16 type,flags;
+  U32 credit_idx,debit_idx,desc_idx;
+  F64 amount;
+  U0 end;
+
+  U8 *credit,*debit,*desc;
+  CBgtTemplate *template;
+  CDocEntry *doc_e;
+} b_head;
+#define BE_SIZE (offset(CBgtEntry.end)-offset(CBgtEntry.start))
+
+#define BT_NULL         0
+#define BT_INTERVAL     1
+#define BT_MONTHLY      2
+#define BT_BIMONTHLY    3
+#define BT_SEMIANNUAL   4
+#define BT_ANNUAL       5
+
+DefineLstLoad("ST_BGT_TEMPLATE_TYPES",
+        "Null\0Interval\0Monthly\0Bimonthly\0Semiannual\0Annual\0");
+
+class CBgtTemplate
+{
+  CBgtTemplate *next,*last;
+
+  U0 start;
+  U16 type              format "$LS,D=\"ST_BGT_TEMPLATE_TYPES\"$\n";
+  U16 flags;
+  U8 start_date[16]     format "$DA-P,A=\"Start Date:%s\"$\n";
+  U8 end_date[16]       format "$DA-P,A=\"End Date  :%s\"$\n";
+  F64 period            format "$DA,A=\"Period    :%8.2f\"$\n";
+  U0 end;
+
+  CBgtEntry b;
+} t_head;
+#define BT_SIZE (offset(CBgtTemplate.end)-offset(CBgtTemplate.start))
+
+U8 view_acct[512];
+CHashTable *accts_table=NULL;
+I64 accts_table_strs=0;
+
+CDate MyStr2Date(U8 *st)
+{
+  CDateStruct   ds;
+  CDate         res;
+  if (st&&*st) {
+    if (StrOcc(st,'['))
+      res=b_head.next->date;
+    else if (StrOcc(st,']'))
+      res=b_head.last->date;
+    else
+      res=Str2Date(st);
+  } else
+    res=Now;
+  Date2Struct(&ds,res);
+  if (ds.year>2050)
+    ds.year-=100;
+  return Struct2Date(&ds);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/Install.HC.HTML b/public/Wb/Home/Src/Apps/Budget/Install.HC.HTML new file mode 100755 index 0000000..03cd450 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/Install.HC.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+if (!FileFind("~/Budget",,FUF_JUST_DIRS)) {
+  DirMk("~/Budget");
+  Copy("Accts.DD.Z","~/Budget");
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/Load.HC.HTML b/public/Wb/Home/Src/Apps/Budget/Load.HC.HTML new file mode 100755 index 0000000..feea5f3 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/Load.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+#help_index "Finance"
+
+Cd(__DIR__);;
+#include "BgtStrs"
+#include "Budget"
+#include "BgtAccts"
+#include "BgtEntry"
+#include "BgtTemplate"
+#include "BgtFile"
+#include "BgtMain"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/Budget/Run.HC.HTML b/public/Wb/Home/Src/Apps/Budget/Run.HC.HTML new file mode 100755 index 0000000..9a7a9a4 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Budget/Run.HC.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+#include "Install" //Might as well always install
+Budget;
+
+ diff --git a/public/Wb/Home/Src/Apps/GrModels/BallGen.HC.HTML b/public/Wb/Home/Src/Apps/GrModels/BallGen.HC.HTML new file mode 100755 index 0000000..c917f0c --- /dev/null +++ b/public/Wb/Home/Src/Apps/GrModels/BallGen.HC.HTML @@ -0,0 +1,159 @@ + + + + + + + + + + + +
+//Makes a mesh ball.
+
+#define VERTICES_NUM    1024
+#define TRIS_NUM        1024
+
+class Ball
+{
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  CD3I32            v[VERTICES_NUM];
+  CMeshTri t[TRIS_NUM];
+} *b;
+
+class BallDefineStruct
+{
+  F64 radius    format   "$DA-TRM,A=\"Radius         :%8.3f\"$\n";
+  I64 n_longitude format "$DA-TRM,A=\"Longitude Faces:%5d\"$\n";
+  I64 n_lattitude format "$DA-TRM,A=\"Lattitude Rings:%5d\"$\n";
+};
+
+U0 BDInit(BallDefineStruct *bd)
+{
+  MemSet(bd,0,sizeof(BallDefineStruct));
+  bd->n_longitude=16;
+  bd->n_lattitude=8;
+  bd->radius     =20.0;
+}
+
+U0 BDCorrect(BallDefineStruct *bd)
+{
+  bd->n_longitude=(bd->n_longitude+1)/2;
+  bd->n_lattitude=(bd->n_lattitude+1)/2;
+}
+
+I64 AddVertex(BallDefineStruct *,I64 x,I64 y,I64 z)
+{
+  I64 i;
+  for (i=0;i<b->vertex_cnt;i++)
+    if (b->v[i].x==x && b->v[i].y==y && b->v[i].z==z)
+      return i;
+  i=b->vertex_cnt++;
+  b->v[i].x=x;
+  b->v[i].y=y;
+  b->v[i].z=z;
+  return i;
+}
+
+I64 AddTri(BallDefineStruct *,I64 c,I64 n0,I64 n1,I64 n2)
+{
+  I64 res=b->tri_cnt++;
+  b->t[res].color=c;
+  b->t[res].nums[0]=n0;
+  b->t[res].nums[1]=n1;
+  b->t[res].nums[2]=n2;
+  return res;
+}
+
+U8 *Ball2CSprite()
+{
+//See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+  U8 *res=MAlloc(sizeof(CSpriteMeshU8s)+
+        b->vertex_cnt*sizeof(CD3I32)+b->tri_cnt*sizeof(CMeshTri)
+  +sprite_elem_base_sizes[SPT_END]),
+        *dst=res;
+  *dst++ =SPT_MESH;
+  *dst(I32 *)++ =b->vertex_cnt;
+  *dst(I32 *)++ =b->tri_cnt;
+  MemCpy(dst,&b->v,b->vertex_cnt*sizeof(CD3I32));
+  dst+=b->vertex_cnt*sizeof(CD3I32);
+  MemCpy(dst,&b->t,b->tri_cnt*sizeof(CMeshTri));
+  dst+=b->tri_cnt*sizeof(CMeshTri);
+  *dst++ =SPT_END;
+  return res;
+}
+
+public U8 *BallGen()
+{
+  U8 *res;
+  I64 i,j,n,m,c,p1,p2,p3,p4;
+  BallDefineStruct bd1,bd2;
+  F64 r,r1,r2,z1,z2,d_a1,d_a2;
+
+  BDInit(&bd1);
+
+  while (TRUE) {
+    if (!DocForm(&bd1))
+      return NULL;
+    MemCpy(&bd2,&bd1,sizeof(BallDefineStruct));
+    BDCorrect(&bd2);
+
+    c=PopUpColorLighting;
+    if (c<0)  return NULL;
+
+    b=CAlloc(sizeof(Ball));
+    r=bd2.radius;
+    n=bd2.n_lattitude;
+    m=bd2.n_longitude;
+    d_a1=2*pi/n/4;
+    d_a2=2*pi/m/2;
+    for (j=-n;j<n;j++) {
+      r1=r*Cos( j   *d_a1);
+      r2=r*Cos((j+1)*d_a1);
+      z1=r*Sin( j   *d_a1);
+      z2=r*Sin((j+1)*d_a1);
+      for (i=0;i<m;i++) {
+        p1=AddVertex(&bd2,r1*Cos((2*i  +j)*d_a2),r1*Sin((2*i  +j)*d_a2),z1);
+        p2=AddVertex(&bd2,r1*Cos((2*i+2+j)*d_a2),r1*Sin((2*i+2+j)*d_a2),z1);
+        p3=AddVertex(&bd2,r2*Cos((2*i+1+j)*d_a2),r2*Sin((2*i+1+j)*d_a2),z2);
+        p4=AddVertex(&bd2,r2*Cos((2*i+3+j)*d_a2),r2*Sin((2*i+3+j)*d_a2),z2);
+        AddTri(&bd2,c,p1,p2,p3);
+        AddTri(&bd2,c,p3,p2,p4);
+      }
+    }
+
+    res=Ball2CSprite;
+    "%h7c",'\n';
+    Sprite(res,"\t\t$SP,\"<1>\",BI=%d$");
+    "%h7c",'\n';
+    "Vertices:%d\n",b->vertex_cnt;
+    Free(b);
+    "Do another";
+    if (YorN)
+      Free(res);
+    else
+      break;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/GrModels/Load.HC.HTML b/public/Wb/Home/Src/Apps/GrModels/Load.HC.HTML new file mode 100755 index 0000000..ca13d9b --- /dev/null +++ b/public/Wb/Home/Src/Apps/GrModels/Load.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#help_index "Misc"
+
+Cd(__DIR__);;
+#include "ManGen"
+#include "BallGen"
+#include "Models"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/GrModels/ManGen.HC.HTML b/public/Wb/Home/Src/Apps/GrModels/ManGen.HC.HTML new file mode 100755 index 0000000..bacff26 --- /dev/null +++ b/public/Wb/Home/Src/Apps/GrModels/ManGen.HC.HTML @@ -0,0 +1,351 @@ + + + + + + + + + + + +
+//Makes a mesh man.
+
+#define VERTICES_NUM    1024
+#define TRIS_NUM        1024
+
+class Man
+{
+  I32 vertex_cnt;
+  I32 tri_cnt;
+  CD3I32   v[VERTICES_NUM];
+  CMeshTri t[TRIS_NUM];
+} *m;
+
+class ManDefineStruct
+{
+  F64 head_rad   format
+        "$DA-TRM,A=\"Head Radius                :%8.3f\"$\n";
+
+  F64 torso_len  format
+        "$DA-TRM,A=\"Torso Length               :%8.3f\"$\n";
+  F64 arm_len    format
+        "$DA-TRM,A=\"Arm Length                 :%8.3f\"$\n";
+  F64 hand_len   format
+        "$DA-TRM,A=\"Hand Length                :%8.3f\"$\n";
+  F64 leg_len    format
+        "$DA-TRM,A=\"Leg Length                 :%8.3f\"$\n";
+  F64 foot_len   format
+        "$DA-TRM,A=\"Foot Length                :%8.3f\"$\n";
+  F64 torso_width format
+        "$DA-TRM,A=\"Torso Width                :%8.3f\"$\n";
+  F64 torso_depth format
+        "$DA-TRM,A=\"Torso Depth                :%8.3f\"$\n";
+  F64 arm_rad    format
+        "$DA-TRM,A=\"Arm Radius                 :%8.3f\"$\n";
+  F64 hand_rad   format
+        "$DA-TRM,A=\"Hand Radius                :%8.3f\"$\n";
+  F64 leg_rad    format
+        "$DA-TRM,A=\"Leg Radius                 :%8.3f\"$\n";
+  F64 foot_rad   format
+        "$DA-TRM,A=\"Foot Radius                :%8.3f\"$\n\n";
+
+  F64 r_shoulder_a1      format
+        "$DA-TRM,A=\"R.Shoulder Front/Back Angle:%8.3f\"$\n";
+  F64 l_shoulder_a1      format
+        "$DA-TRM,A=\"L.Shoulder Front/Back Angle:%8.3f\"$\n";
+  F64 r_hip_a1   format
+        "$DA-TRM,A=\"R.Hip Front/Back Angle     :%8.3f\"$\n";
+  F64 l_hip_a1   format
+        "$DA-TRM,A=\"L.Hip Front/Back Angle     :%8.3f\"$\n";
+
+  F64 r_shoulder_a2      format
+        "$DA-TRM,A=\"R.Shoulder Side Angle      :%8.3f\"$\n";
+  F64 l_shoulder_a2      format
+        "$DA-TRM,A=\"L.Shoulder Side Angle      :%8.3f\"$\n";
+  F64 r_hip_a2   format
+        "$DA-TRM,A=\"R.Hip Side Angle           :%8.3f\"$\n";
+  F64 l_hip_a2   format
+        "$DA-TRM,A=\"L.Hip Side Angle           :%8.3f\"$\n";
+
+  F64 r_elbow_a  format
+        "$DA-TRM,A=\"R.Elbow Angle              :%8.3f\"$\n";
+  F64 l_elbow_a  format
+        "$DA-TRM,A=\"L.Elbow Angle              :%8.3f\"$\n";
+  F64 r_knee_a   format
+        "$DA-TRM,A=\"R.Knee Angle               :%8.3f\"$\n";
+  F64 l_knee_a   format
+        "$DA-TRM,A=\"L.Knee Angle               :%8.3f\"$\n";
+
+  F64 r_wrist_a  format
+        "$DA-TRM,A=\"R.Wrist Angle              :%8.3f\"$\n";
+  F64 l_wrist_a  format
+        "$DA-TRM,A=\"L.Wrist Angle              :%8.3f\"$\n";
+  F64 r_ankle_a  format
+        "$DA-TRM,A=\"R.Ankle Angle              :%8.3f\"$\n";
+  F64 l_ankle_a  format
+        "$DA-TRM,A=\"L.Ankle Angle              :%8.3f\"$\n";
+
+};
+
+U0 MDInit(ManDefineStruct *md)
+{
+  MemSet(md,0,sizeof(ManDefineStruct));
+
+  md->head_rad  =5.0;
+
+  md->torso_len =35.0;
+  md->arm_len   =30.0;
+  md->hand_len  =8.0;
+  md->leg_len   =32.0;
+  md->foot_len  =16.0;
+  md->torso_width=20.0;
+  md->torso_depth=10.0;
+  md->arm_rad   =3.5;
+  md->hand_rad  =2.0;
+  md->leg_rad   =4.0;
+  md->foot_rad  =3.0;
+
+  md->r_shoulder_a1     =30;
+  md->l_shoulder_a1     =-30;
+  md->r_hip_a1  =-45;
+  md->l_hip_a1  =45;
+
+  md->r_shoulder_a2     =10;
+  md->l_shoulder_a2     =10;
+  md->r_hip_a2  =-5;
+  md->l_hip_a2  =-5;
+
+  md->r_elbow_a =30;
+  md->l_elbow_a =0;
+  md->r_knee_a  =0;
+  md->l_knee_a  =30;
+
+  md->r_wrist_a =0;
+  md->l_wrist_a =0;
+  md->r_ankle_a =0;
+  md->l_ankle_a =0;
+}
+
+U0 MDCorrect(ManDefineStruct *md)
+{
+  md->r_ankle_a    =-md->r_ankle_a;
+  md->l_ankle_a    =-md->l_ankle_a;
+  md->r_knee_a    =-md->r_knee_a;
+  md->l_knee_a    =-md->l_knee_a;
+  md->r_hip_a2     =-md->r_hip_a2;
+  md->r_shoulder_a2=-md->r_shoulder_a2;
+  md->r_ankle_a+=90;
+  md->l_ankle_a+=90;
+
+  md->foot_len-=md->leg_rad;
+
+  md->r_elbow_a+=md->r_shoulder_a1;
+  md->l_elbow_a+=md->l_shoulder_a1;
+  md->r_knee_a+=md->r_hip_a1;
+  md->l_knee_a+=md->l_hip_a1;
+
+  md->r_wrist_a+=md->r_elbow_a;
+  md->l_wrist_a+=md->l_elbow_a;
+  md->r_ankle_a+=md->r_knee_a;
+  md->l_ankle_a+=md->l_knee_a;
+}
+
+I64 AddVertex(ManDefineStruct *md,I64 x,I64 y,I64 z)
+{
+  I64 res=m->vertex_cnt++;
+  m->v[res].x=-x;
+  m->v[res].y=-y-md->leg_len-md->foot_rad*2;
+  m->v[res].z=-z;
+  return res;
+}
+
+I64 AddTri(ManDefineStruct *,I64 c,I64 n0,I64 n1,I64 n2)
+{
+  I64 res=m->tri_cnt++;
+  m->t[res].color=c;
+  m->t[res].nums[0]=n1;
+  m->t[res].nums[1]=n0;
+  m->t[res].nums[2]=n2;
+  return res;
+}
+
+U0 AddBox(ManDefineStruct *md,I64 c,I64 x1,I64 y1,I64 z1,
+        F64 w,F64 h,F64 d,F64 h2,F64 h3,F64 az,F64 ay,F64 ax,
+        I64 *ox,I64 *oy,I64 *oz)
+{
+  I64 *r;
+  I64 p1a,p2a,p3a,p4a;
+  I64 p1b,p2b,p3b,p4b;
+  I64 wx=w/2,wy=0,wz=0,hx=0,hy=h,hz=0,h2x=0,h2y=h2,h2z=0,
+        h3x=0,h3y=h3,h3z=0,dx=0,dy=0,dz=d/2;
+
+  r=Mat4x4IdentNew;
+  Mat4x4RotZ(r,az*pi/180.0);
+  Mat4x4RotY(r,ay*pi/180.0);
+  Mat4x4RotX(r,ax*pi/180.0);
+  Mat4x4MulXYZ(r,&wx,&wy,&wz);
+  Mat4x4MulXYZ(r,&hx,&hy,&hz);
+  Mat4x4MulXYZ(r,&h2x,&h2y,&h2z);
+  Mat4x4MulXYZ(r,&h3x,&h3y,&h3z);
+  Mat4x4MulXYZ(r,&dx,&dy,&dz);
+
+  p1a=AddVertex(md,x1+dx        -wx+h2x,y1+dy   -wy+h2y,z1+dz   -wz+h2z);
+  p2a=AddVertex(md,x1+dx        +wx+h2x,y1+dy   +wy+h2y,z1+dz   +wz+h2z);
+  p3a=AddVertex(md,x1+dx+hx-wx    ,y1+dy+hy-wy    ,z1+dz+hz-wz);
+  p4a=AddVertex(md,x1+dx+hx+wx    ,y1+dy+hy+wy    ,z1+dz+hz+wz);
+  AddTri(md,c,p1a,p2a,p3a);
+  AddTri(md,c,p4a,p3a,p2a);
+
+  p1b=AddVertex(md,x1-dx        -wx+h2x,y1-dy   -wy+h2y,z1-dz   -wz+h2z);
+  p2b=AddVertex(md,x1-dx        +wx+h2x,y1-dy   +wy+h2y,z1-dz   +wz+h2z);
+  p3b=AddVertex(md,x1-dx+hx-wx    ,y1-dy+hy-wy    ,z1-dz+hz-wz);
+  p4b=AddVertex(md,x1-dx+hx+wx    ,y1-dy+hy+wy    ,z1-dz+hz+wz);
+  AddTri(md,c,p1b,p2b,p3b);
+  AddTri(md,c,p4b,p3b,p2b);
+
+  AddTri(md,c,p1a,p2a,p1b);
+  AddTri(md,c,p2b,p1b,p2a);
+  AddTri(md,c,p3a,p4a,p3b);
+  AddTri(md,c,p4b,p3b,p4a);
+  AddTri(md,c,p1a,p3a,p1b);
+  AddTri(md,c,p3b,p1b,p3a);
+  AddTri(md,c,p2a,p4a,p2b);
+  AddTri(md,c,p4b,p2b,p4a);
+
+  *ox=x1+hx-h3x;
+  *oy=y1+hy-h3y;
+  *oz=z1+hz-h3z;
+
+  Free(r);
+}
+
+U8 *Man2CSprite()
+{
+//See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+  U8 *res=MAlloc(sizeof(CSpriteMeshU8s)+
+        m->vertex_cnt*sizeof(CD3I32)+m->tri_cnt*sizeof(CMeshTri)+
+        sprite_elem_base_sizes[SPT_END]),
+        *dst=res;
+  *dst++ =SPT_MESH;
+  *dst(I32 *)++ =m->vertex_cnt;
+  *dst(I32 *)++ =m->tri_cnt;
+  MemCpy(dst,&m->v,m->vertex_cnt*sizeof(CD3I32));
+  dst+=m->vertex_cnt*sizeof(CD3I32);
+  MemCpy(dst,&m->t,m->tri_cnt*sizeof(CMeshTri));
+  dst+=m->tri_cnt*sizeof(CMeshTri);
+  *dst++ =SPT_END;
+  return res;
+}
+
+public U8 *ManGen()
+{
+  U8 *res;
+  I64 x,y,z,c1,c2,c3,c4;
+  ManDefineStruct md1,md2;
+  MDInit(&md1);
+
+  while (TRUE) {
+    if (!DocForm(&md1))
+      return NULL;
+    MemCpy(&md2,&md1,sizeof(ManDefineStruct));
+    MDCorrect(&md2);
+
+    c1=PopUpColorLighting("$BK,1$Shirt$BK,0$\n");
+    if (c1<0) return NULL;
+    c2=PopUpColorLighting("$BK,1$Pants$BK,0$\n");
+    if (c2<0) return NULL;
+    c3=PopUpColorLighting("$BK,1$Skin$BK,0$\n");
+    if (c3<0) return NULL;
+    c4=PopUpColorLighting("$BK,1$Shoes$BK,0$\n");
+    if (c4<0) return NULL;
+
+    m=CAlloc(sizeof(Man));
+
+    //Head
+    AddBox(&md2,c3,0,md2.torso_len+md2.head_rad*2,0,
+          md2.head_rad*2,-md2.head_rad*2,md2.head_rad*2,0,0, 0,0,0,
+          &x,&y,&z);
+
+    //Torso
+    AddBox(&md2,c1,0,md2.torso_len,0,
+          md2.torso_width,-md2.torso_len,md2.torso_depth,0,0, 0,0,0,
+          &x,&y,&z);
+
+    //Right Arm
+    AddBox(&md2,c1,-md2.torso_width/2-md2.arm_rad,md2.torso_len-md2.arm_rad,0,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,md2.arm_rad,0,
+          md2.r_shoulder_a2,0,md2.r_shoulder_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,0,0,
+          md2.r_shoulder_a2,0,md2.r_elbow_a,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.hand_len,md2.hand_rad*2,0,0,
+          md2.r_shoulder_a2,0,md2.r_wrist_a,&x,&y,&z);
+
+    //Left Arm
+    AddBox(&md2,c1,md2.torso_width/2+md2.arm_rad,md2.torso_len-md2.arm_rad,0,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,md2.arm_rad,0,
+          md2.l_shoulder_a2,0,md2.l_shoulder_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.arm_len/2,md2.arm_rad*2,0,0,
+          md2.l_shoulder_a2,0,md2.l_elbow_a,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.arm_rad*2,-md2.hand_len,md2.hand_rad*2,0,0,
+          md2.l_shoulder_a2,0,md2.l_wrist_a,&x,&y,&z);
+
+    //Right Leg
+    AddBox(&md2,c2,-md2.torso_width/2+md2.leg_rad,0,0,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,0,
+          md2.r_hip_a2,0,md2.r_hip_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,md2.foot_rad,
+          md2.r_hip_a2,0,md2.r_knee_a,&x,&y,&z);
+    AddBox(&md2,c4,x,y,z,
+          md2.leg_rad*2,-md2.foot_len,md2.foot_rad*2,md2.leg_rad,0,
+          md2.r_hip_a2,0,md2.r_ankle_a,&x,&y,&z);
+
+    //Left Leg
+    AddBox(&md2,c2,md2.torso_width/2-md2.leg_rad,0,0,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,0,
+          md2.l_hip_a2,0,md2.l_hip_a1,&x,&y,&z);
+    AddBox(&md2,c3,x,y,z,
+          md2.leg_rad*2,-md2.leg_len/2,md2.leg_rad*2,0,md2.foot_rad,
+          md2.l_hip_a2,0,md2.l_knee_a,&x,&y,&z);
+    AddBox(&md2,c4,x,y,z,
+          md2.leg_rad*2,-md2.foot_len,md2.foot_rad*2,md2.leg_rad,0,
+          md2.l_hip_a2,0,md2.l_ankle_a,&x,&y,&z);
+
+    res=Man2CSprite;
+    "%h7c",'\n';
+    Sprite(res,"\t\t$SP,\"<1>\",BI=%d$");
+    "%h7c",'\n';
+    Free(m);
+    "Do another";
+    if (YorN)
+      Free(res);
+    else
+      break;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/GrModels/Models.HC.HTML b/public/Wb/Home/Src/Apps/GrModels/Models.HC.HTML new file mode 100755 index 0000000..11d031d --- /dev/null +++ b/public/Wb/Home/Src/Apps/GrModels/Models.HC.HTML @@ -0,0 +1,56 @@ + + + + + + + + + + + +
+#define T_MAN   0
+#define T_BALL  1
+
+U0 Models()
+{
+  I64 i;
+  Bool old_form=LBts(&(DocPut)->flags,DOCf_FORM);
+  DocClear;
+  "Make a CSprite model.  Then, cut-and-Paste it.\n\n";
+  "$LM,4$";
+  "\n\n$BT,\"Man\",LE=T_MAN$\n\n";
+  "\n\n$BT,\"Ball\",LE=T_BALL$\n\n";
+  "$LM,0$";
+  i=DocMenu(DocPut);
+  LBEqu(&(DocPut)->flags,DOCf_FORM,old_form);
+  DocBottom;
+  switch (i) {
+    case T_MAN:
+      ManGen;
+      break;
+    case T_BALL:
+      BallGen;
+      break;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/GrModels/Run.HC.HTML b/public/Wb/Home/Src/Apps/GrModels/Run.HC.HTML new file mode 100755 index 0000000..93bac8d --- /dev/null +++ b/public/Wb/Home/Src/Apps/GrModels/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Models;
+ diff --git a/public/Wb/Home/Src/Apps/KeepAway/KeepAway.HC.HTML b/public/Wb/Home/Src/Apps/KeepAway/KeepAway.HC.HTML new file mode 100755 index 0000000..2fb39de --- /dev/null +++ b/public/Wb/Home/Src/Apps/KeepAway/KeepAway.HC.HTML @@ -0,0 +1,740 @@ + + + + + + + + + + + +
+//The ball and men were generated
+//with ::/Apps/GrModels/Run.HC.
+//They were cut-and-pasted here.
+
+
+                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <9>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <11>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <12>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <13>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <14>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <15>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+                <16>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <17>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <18>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <19>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <20>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <21>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <22>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <23>/* Graphics Not Rendered in HTML */
+
+
+
+class Frame
+{
+  U8 *img[2];
+  F64 dt;
+};
+
+#define COURT_BORDER            10
+#define COLLISION_DAMP          0.8
+#define AIR_VISCOSITY           0.1
+
+#define GRAVITY_ACCELERATION    500
+#define SHOT_VELOCITY           400
+#define DRIBBLE_T               0.25
+#define MAN_VELOCITY            150
+#define MAN_SQR_RADIUS          (20*20)
+#define FOUL_VELOCITY_THRESHOLD 50
+#define JUMP_VELOCITY           250
+#define ROLL_VELOCITY_THRESHOLD 100
+#define RANDOM_MAN_ACCELERATION 30
+
+#define HEAD_Z_OFFSET   200
+#define HAND_X_OFFSET   30
+#define HAND_Y_OFFSET   20
+#define HAND_SQR_OFFSET \
+        (HAND_X_OFFSET*HAND_X_OFFSET+HAND_Y_OFFSET*HAND_Y_OFFSET)
+#define HAND_Z_OFFSET   110
+
+#define FIRST_STANDING          0
+
+#define RUNNING_IMGS_NUM        4
+#define FIRST_RUNNING   0
+#define LAST_RUNNING    (FIRST_RUNNING+RUNNING_IMGS_NUM-1)
+
+#define SHOOTING_IMGS_NUM       5
+#define FIRST_SHOOTING  (LAST_RUNNING+1)
+#define LAST_SHOOTING   (FIRST_SHOOTING+SHOOTING_IMGS_NUM-1)
+
+#define DRIBBLING_IMGS_NUM      4
+#define FIRST_DRIBBLING (LAST_SHOOTING+1)
+#define LAST_DRIBBLING  (FIRST_DRIBBLING+DRIBBLING_IMGS_NUM-1)
+
+#define STOPPED_DRIBBLING_IMGS_NUM      2
+#define FIRST_STOPPED_DRIBBLING (LAST_DRIBBLING+1)
+#define LAST_STOPPED_DRIBBLING  \
+        (FIRST_STOPPED_DRIBBLING+STOPPED_DRIBBLING_IMGS_NUM-1)
+
+Frame imgs[LAST_STOPPED_DRIBBLING+1]={
+  {{<6>,<7>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<2>,<3>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<6>,<7>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<4>,<5>},2*DRIBBLE_T/RUNNING_IMGS_NUM},
+  {{<8>,<9>},0.1},{{<10>,<11>},0.2},
+  {{<12>,<13>},0.2},{{<12>,<13>},0.1},{{<14>,<15>},0.1},
+  {{<20>,<21>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<16>,<17>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<20>,<21>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<18>,<19>},2*DRIBBLE_T/DRIBBLING_IMGS_NUM},
+  {{<20>,<21>},DRIBBLE_T/STOPPED_DRIBBLING_IMGS_NUM},
+  {{<22>,<23>},DRIBBLE_T/STOPPED_DRIBBLING_IMGS_NUM},
+};
+
+RegDft("TempleOS/KeepAway","I64 best_score0=0,best_score1=9999;\n");
+RegExe("TempleOS/KeepAway");
+
+F64 game_t_end,foul_t_end;
+I64 score0,score1;
+
+#define PER_SIDE_NUM    3
+#define OBJS_NUM        (PER_SIDE_NUM*2+1)
+Bool someone_shooting,someone_has_ball;
+F64 shot_land_t;
+        
+class Obj
+{
+  I64 team; //-1 is ball
+  F64 x,y,z,DxDt,DyDt,DzDt,theta,radius,stolen_t0;
+  F64 get_ball_dt,get_ball_theta,nearest_man_dd,last_t0,next_t0,foul_t0;
+  I64 last_img,next_img;
+  Bool stopped,shooting,has_ball,nearest_ball,pad[4];
+} objs[OBJS_NUM],*ball,*human,*last_owner;
+
+/*Just to be different, I didn't use the built-in
+DCF_TRANSFORMATION flag in this game.
+Instead, I chose a 45 degree angle
+between Y and Z as the view point.
+If I had used the transform, I would
+have to make all my men taller.
+This is a little simpler, and faster,
+but adds lots of factor 2 vals.
+
+I also didn't use the CMathODE feat,
+just to be different.
+*/
+
+U0 DrawObj(CDC *dc,Obj *o,F64 tt)
+{
+  U8 *tmps;
+  F64 r1=Max(9-0.1*o->z,1),r2=Max(r1/4,1);
+
+  if (o==human)
+    dc->color=LTRED;
+  else
+    dc->color=BLACK;
+  GrEllipse(dc,o->x,o->y/2,r1,r2);
+  GrFloodFill(dc,o->x,o->y/2);
+
+  if (o==ball)
+    Sprite3(dc,o->x,(o->y-o->z)/2,GR_Z_ALL-o->y,<1>);
+  else {
+    tmps=SpriteInterpolate((tt-o->last_t0)/(o->next_t0-o->last_t0),
+          imgs[o->last_img].img[o->team],
+          imgs[o->next_img].img[o->team]);
+    Sprite3YB(dc,o->x,(o->y-o->z)/2,GR_Z_ALL-o->y,tmps,o->theta);
+    Free(tmps);
+  }
+}
+
+I64 ObjCompare(Obj *o1,Obj *o2)
+{
+  return o1->y-o2->y;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 tt=tS,d,d_down,d_up;
+  I64 i;
+  Obj *o_sort[OBJS_NUM],*o;
+
+  DCDepthBufAlloc(dc);
+  dc->ls.x=10000;
+  dc->ls.y=60000;
+  dc->ls.z=10000;
+  d=65535/D3I32Norm(&dc->ls);
+  dc->ls.x*=d;
+  dc->ls.y*=d;
+  dc->ls.z*=d;
+
+  dc->thick=2;
+  dc->color=RED;
+  GrBorder(dc,COURT_BORDER,COURT_BORDER,
+        task->pix_width -1-COURT_BORDER,
+        task->pix_height-1-COURT_BORDER);
+  for (i=0;i<OBJS_NUM;i++) {
+    o=o_sort[i]=&objs[i];
+    if (o!=ball) {
+      if (o->has_ball) {
+        ball->x=o->x+HAND_X_OFFSET*Cos(o->theta-pi/2)+HAND_Y_OFFSET*Cos(o->theta);
+//The factor 2 is because the man is not transformed.
+        ball->y=o->y+HAND_X_OFFSET*Sin(o->theta-pi/2)/2+HAND_Y_OFFSET*Sin(o->theta)/2;
+        if (ball->z+ball->radius*2>o->z+HAND_Z_OFFSET)
+          ball->z=o->z+HAND_Z_OFFSET-ball->radius*2;
+      } else if (o->shooting) {
+        ball->x=o->x;
+        ball->y=o->y;
+        ball->z=o->z+HEAD_Z_OFFSET;
+      }
+      if (tt>o->next_t0) {
+        if (o->has_ball && (ball->z+ball->radius*2>=o->z+HAND_Z_OFFSET ||
+              Abs(ball->DzDt)<30)) {
+//This is an approximation.  My instinct tells me the viscosity term
+          //needs an Exp().  However, we should be syncronized to img frames,
+          //so we don't have to be perfect.
+          d_down=1.0;
+          d_up  =1.0/COLLISION_DAMP;
+//Up bounce takes higher % because speed lost in collision.
+          ball->DzDt=-((d_down+d_up)*
+                (o->z+HAND_Z_OFFSET-ball->radius*4)/(1.0-AIR_VISCOSITY)+
+                0.5*GRAVITY_ACCELERATION*(
+                Sqr(DRIBBLE_T*d_up/(d_down+d_up))-
+                Sqr(DRIBBLE_T*d_down/(d_down+d_up)) ))/DRIBBLE_T;
+        }
+        o->last_t0=tt;
+        o->last_img=o->next_img++;
+        if (o->stopped) {
+          if (o->has_ball) {
+            if (!(FIRST_STOPPED_DRIBBLING<=o->next_img<=LAST_STOPPED_DRIBBLING))
+              o->next_img=FIRST_STOPPED_DRIBBLING;
+          } else
+            o->next_img=FIRST_STANDING;
+          o->stopped=FALSE;
+        } else if (o->shooting) {
+          if (!(FIRST_SHOOTING<=o->last_img<=LAST_SHOOTING))
+            o->next_img=FIRST_SHOOTING;
+          if (o->next_img>LAST_SHOOTING) {
+            o->next_img=FIRST_STANDING;
+            someone_has_ball=someone_shooting=o->has_ball=o->shooting=FALSE;
+            ball->DxDt=o->DxDt+SHOT_VELOCITY/sqrt2*Cos(o->theta-pi/2);
+            ball->DyDt=o->DyDt+SHOT_VELOCITY/sqrt2*Sin(o->theta-pi/2);
+            ball->DzDt=o->DzDt+SHOT_VELOCITY/sqrt2;
+            shot_land_t=tt+(ball->DzDt+Sqrt(Sqr(ball->DzDt)+
+                2*GRAVITY_ACCELERATION*ball->z))/GRAVITY_ACCELERATION;
+          } else {
+            ball->DxDt=0;
+            ball->DyDt=0;
+            ball->DzDt=0;
+          }
+        } else if (o->has_ball) {
+          if (FIRST_RUNNING<=o->next_img<=LAST_RUNNING)
+            o->next_img+=FIRST_DRIBBLING-FIRST_RUNNING;
+          if (!(FIRST_DRIBBLING<=o->next_img<=LAST_DRIBBLING))
+            o->next_img=FIRST_DRIBBLING;
+        } else {
+          if (FIRST_DRIBBLING<=o->next_img<=LAST_DRIBBLING)
+            o->next_img+=FIRST_RUNNING-FIRST_DRIBBLING;
+          if (!(FIRST_RUNNING<=o->next_img<=LAST_RUNNING))
+            o->next_img=FIRST_RUNNING;
+        }
+        o->next_t0+=imgs[o->last_img].dt;
+        if (o->next_t0<=tt)
+          o->next_t0=tt+imgs[o->last_img].dt;
+      }
+    }
+  }
+
+  QSortI64(o_sort,OBJS_NUM,&ObjCompare);
+  for (i=0;i<OBJS_NUM;i++)
+    DrawObj(dc,o_sort[i],tt);
+  tt=(game_t_end-tS)/60;
+  if (tt<=0) {
+    dc->color=RED;
+    tt=0;
+    if (Blink)
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*9)>>1,
+            (task->pix_height-FONT_HEIGHT)>>1,"Game Over");
+  } else {
+    if (tS<foul_t_end) {
+      dc->color=LTRED;
+      if (Blink)
+        GrPrint(dc,(task->pix_width-FONT_WIDTH*4)>>1,
+              (task->pix_height-FONT_HEIGHT)>>1,"Foul");
+    }
+    dc->color=BLACK;
+  }
+  GrPrint(dc,0,0,"Time:%d:%04.1f  Score:",ToI64(tt),(tt-ToI64(tt))*60);
+  GrPrint  (dc,FONT_WIDTH*27,0,"Best Score:");
+
+  dc->color=LTCYAN;
+  GrPrint(dc,FONT_WIDTH*20,0,"%02d",score0);
+  dc->color=LTPURPLE;
+  GrPrint(dc,FONT_WIDTH*23,0,"%02d",score1);
+
+  dc->color=LTCYAN;
+  GrPrint(dc,FONT_WIDTH*39,0,"%02d",best_score0);
+  dc->color=LTPURPLE;
+  GrPrint(dc,FONT_WIDTH*42,0,"%02d",best_score1);
+}
+
+U0 Shoot(Obj *o)
+{
+  if (!someone_shooting && o->has_ball) {
+    someone_shooting=o->stopped=o->shooting=TRUE;
+    o->has_ball=FALSE;
+  }
+}
+
+U0 AnimateTask(CTask *parent_task)
+{
+  F64 d,dx,dy,dt,dx2,dy2,t0=tS;
+  I64 i,j;
+  Bool gets_ball;
+  Obj *o,*nearest_ball[2];
+  while (TRUE) {
+    dt=tS-t0;
+    t0=tS;
+
+    if (game_t_end && game_t_end<t0) {
+      game_t_end=0;
+      Beep;
+      if (score0-score1>best_score0-best_score1) {
+        best_score0=score0;
+        best_score1=score1;
+        Snd(86);Sleep(100); Snd;Sleep(100);
+        Snd(86);Sleep(100); Snd;Sleep(100);
+      }
+    }
+
+    if (game_t_end) {
+      MemSet(&nearest_ball,0,sizeof(nearest_ball));
+      for (i=0;i<OBJS_NUM;i++) {
+        o=&objs[i];
+        o->nearest_ball=FALSE;
+        if (o!=ball) {
+          d=0;
+          for (j=0;j<5;j++) //Iterative estimate of how long to get ball.
+            d=Sqrt(Sqr(ball->DxDt*d+ball->x-o->x)+
+                  Sqr(ball->DyDt*d+ball->y-o->y))/MAN_VELOCITY;
+          o->get_ball_dt=d;
+          o->get_ball_theta=Arg(ball->DxDt*d+ball->x-o->x,
+                ball->DyDt*d+ball->y-o->y);
+          if (o!=last_owner && !nearest_ball[o->team] ||
+                o->get_ball_dt<nearest_ball[o->team]->get_ball_dt)
+            nearest_ball[o->team]=o;
+        }
+      }
+      nearest_ball[0]->nearest_ball=TRUE;
+      nearest_ball[1]->nearest_ball=TRUE;
+
+      for (i=0;i<OBJS_NUM;i++) {
+        o=&objs[i];
+        if (o==ball) {
+          o->x+=dt*o->DxDt;
+          o->y+=dt*o->DyDt;
+          if (!someone_shooting)
+            o->z+=dt*(o->DzDt-0.5*GRAVITY_ACCELERATION*dt);
+        } else {
+          if (!o->has_ball) {
+            if (t0-o->stolen_t0>2.0 && !someone_shooting) {
+              dx=ball->x-o->x;
+              dy=ball->y-o->y;
+              if (dx*dx+dy*dy<HAND_SQR_OFFSET && ball->z<o->z+HAND_Z_OFFSET) {
+                gets_ball=TRUE;
+                for (j=0;j<PER_SIDE_NUM*2;j++)
+                  if (j!=i && objs[j].has_ball) {
+                    if (Rand<2.0*dt) {
+                      objs[j].stolen_t0=t0;
+                      objs[j].has_ball=FALSE;
+                    } else
+                      gets_ball=FALSE;
+                  }
+                if (gets_ball) {
+                  someone_has_ball=o->has_ball=TRUE;
+                  if (o!=last_owner) {
+                    if (o->team) {
+                      if (t0<shot_land_t+0.1)
+                        score1+=6;
+                      else
+                        score1+=2;
+                      Noise(250,74,74);
+                    } else {
+                      if (t0<shot_land_t+0.1)
+                        score0+=6;
+                      else
+                        score0+=2;
+                      Noise(250,86,86);
+                    }
+                    last_owner=o;
+                  }
+                }
+              }
+            }
+          } else if (o!=human && Rand<0.25*dt)
+            Shoot(o);
+          if (!o->shooting) {
+            if (o==human) {
+              dx=(ms.pos.x-parent_task->pix_left-parent_task->scroll_x)-o->x;
+              dy=(ms.pos.y-parent_task->pix_top-parent_task->scroll_y)*2-o->y;
+            } else {
+              if (!someone_has_ball && o->nearest_man_dd>4*MAN_SQR_RADIUS &&
+                    o->nearest_ball) {
+                dx=o->DxDt=MAN_VELOCITY*Cos(o->get_ball_theta);
+                dy=o->DyDt=MAN_VELOCITY*Sin(o->get_ball_theta);
+              } else {
+                dx=o->DxDt+=RANDOM_MAN_ACCELERATION/sqrt2*RandI16/I16_MAX*dt;
+                dy=o->DyDt+=RANDOM_MAN_ACCELERATION/sqrt2*RandI16/I16_MAX*dt;
+              }
+            }
+            d=Sqrt(dx*dx+dy*dy);
+            if (d>=1.0) {
+              o->theta=Arg(dx,dy)+pi/2;
+              dx*=MAN_VELOCITY/sqrt2*dt/d;
+              dy*=MAN_VELOCITY/sqrt2*dt/d;
+              o->nearest_man_dd=F64_MAX;
+              for (j=0;j<PER_SIDE_NUM*2;j++)
+                if (j!=i) {
+                  dx2=objs[j].x-o->x;
+                  dy2=objs[j].y-o->y;
+                  d=Sqr(dx2)+Sqr(dy2);
+                  if (d<o->nearest_man_dd)
+                    o->nearest_man_dd=d;
+                  if (d<MAN_SQR_RADIUS) {
+                    if (d) {
+                      d=Sqrt(d);
+                      dx2/=d;
+                      dy2/=d;
+                    }
+                    if (t0>o->foul_t0+0.15) {
+                      d=(dx-objs[j].DxDt)*dx2+(dy-objs[j].DyDt)*dy2;
+                      if (o==human && t0>o->foul_t0+1.0 &&
+                            dt && d/dt>FOUL_VELOCITY_THRESHOLD &&
+                            objs[j].team) {
+                        Noise(250,62,62);
+                        score1+=1;
+                        foul_t_end=t0+1.0;
+                      }
+                      o->foul_t0=t0;
+                    }
+                  }
+                }
+              if (t0<o->foul_t0+0.15) {
+                dx=-dx;
+                dy=-dy;
+              }
+              o->x+=dx;
+              o->y+=dy;
+              o->stopped=FALSE;
+            } else
+              o->stopped=TRUE;
+          }
+          if (o->DzDt)
+            o->z+=dt*(o->DzDt-0.5*GRAVITY_ACCELERATION*dt);
+        }
+
+        if (o->x+o->radius>=parent_task->pix_width-COURT_BORDER) {
+          o->x=parent_task->pix_width-COURT_BORDER-1-o->radius;
+          o->DxDt=-COLLISION_DAMP*o->DxDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+        if (o->x-o->radius<COURT_BORDER) {
+          o->x=COURT_BORDER+o->radius;
+          o->DxDt=-COLLISION_DAMP*o->DxDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+
+        if (o->y+o->radius*2>=(parent_task->pix_height-COURT_BORDER)*2) {
+          o->y=(parent_task->pix_height-COURT_BORDER)*2-1-o->radius*2;
+          o->DyDt=-COLLISION_DAMP*o->DyDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+        if (o->y-o->radius*2<2*COURT_BORDER) {
+          o->y=COURT_BORDER*2+o->radius*2;
+          o->DyDt=-COLLISION_DAMP*o->DyDt;
+          if (o==ball)
+            Noise(10,74,86);
+        }
+
+        if (o->z-o->radius*2<0) {
+          o->z=o->radius*2;
+          o->DzDt=-COLLISION_DAMP*o->DzDt;
+          if (o->DzDt>ROLL_VELOCITY_THRESHOLD)
+            Noise(10,74,86);
+          if (o!=ball)
+            o->DzDt=0;
+        } else if (o->z-o->radius*2>0)
+          o->DzDt-=GRAVITY_ACCELERATION*dt;
+        if (o==ball) {
+          d=Exp(-AIR_VISCOSITY*dt);
+          o->DxDt*=d;
+          o->DyDt*=d;
+          o->DzDt*=d;
+        }
+      }
+    }
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  someone_shooting=FALSE;
+  shot_land_t=0;
+  MemSet(&objs,0,sizeof(objs));
+  for (i=0;i<PER_SIDE_NUM*2;i++) {
+    objs[i].team=i&1;
+    objs[i].x=Fs->pix_width/2;
+    objs[i].y=2*Fs->pix_height/2;
+    objs[i].next_img=objs[i].last_img=FIRST_RUNNING;
+  }
+  last_owner=NULL;
+  human=&objs[0];
+  ball =&objs[i];
+  ball->team=-1;
+  ball->x=0.5*Fs->pix_width/2;
+  ball->y=0.5*2*Fs->pix_height/2;
+  ball->radius=11;
+  ball->z=ball->radius;
+  score0=score1=0;
+  game_t_end=tS+3*60;
+  foul_t_end=0;
+}
+
+U0 KeepAway()
+{
+  I64 msg_code,arg1,arg2;
+
+  PopUpOk(
+        "Pass or hand-off to your team to score points.$FG$\n\n"
+        "\t2 points for successful hand-off.\n"
+        "\t6 points for successful pass.\n"
+        "\t1 point penalty for foul.\n\n"
+        "Left-Click\tto pass.\n\n"
+        "Right-Click\tto jump.\n");
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK+YELLOW<<4;
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Shoot(,CH_SPACE);"
+        "  Jump(,'j');"
+        "}"
+        );
+
+  Init;
+  Fs->draw_it=&DrawIt;
+  Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
+
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|1<<MSG_KEY_DOWN);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+ka_shoot:
+          Shoot(human);
+          break;
+        case MSG_MS_R_DOWN:
+ka_jump:
+          human->DzDt=JUMP_VELOCITY;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              Init;
+              break;
+            case 'j':
+              goto ka_jump;
+            case CH_SPACE:
+              goto ka_shoot;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto ka_done;
+          }
+          break;
+      }
+    }
+ka_done: //Don't goto out of try
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/KeepAway","I64 best_score0=%d,best_score1=%d;\n",
+        best_score0,best_score1);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/KeepAway/Load.HC.HTML b/public/Wb/Home/Src/Apps/KeepAway/Load.HC.HTML new file mode 100755 index 0000000..08328e4 --- /dev/null +++ b/public/Wb/Home/Src/Apps/KeepAway/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "KeepAway"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/KeepAway/Run.HC.HTML b/public/Wb/Home/Src/Apps/KeepAway/Run.HC.HTML new file mode 100755 index 0000000..e1f6751 --- /dev/null +++ b/public/Wb/Home/Src/Apps/KeepAway/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+KeepAway;
+ diff --git a/public/Wb/Home/Src/Apps/Logic/Load.HC.HTML b/public/Wb/Home/Src/Apps/Logic/Load.HC.HTML new file mode 100755 index 0000000..d72082d --- /dev/null +++ b/public/Wb/Home/Src/Apps/Logic/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Misc"
+
+Cd(__DIR__);;
+#include "Logic"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/Logic/Logic.HC.HTML b/public/Wb/Home/Src/Apps/Logic/Logic.HC.HTML new file mode 100755 index 0000000..8c1a190 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Logic/Logic.HC.HTML @@ -0,0 +1,621 @@ + + + + + + + + + + + +
+#define TABLE_SIZE_MAX 0x10000
+
+I64 output_found,passes,table_size;
+
+U8 *gate_type_table =NULL,
+   *displayed_design=NULL,
+   *added_this_pass =NULL;
+
+U16 *input1_table=NULL,
+    *input2_table=NULL,
+    *input3_table=NULL;
+
+#define CONNECT_WIDTH   16
+#define GATE_WIDTH      37
+
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+      
+      
+      /* Graphics Not Rendered in HTML */
+      
+
+U8 *gate_type_lst="NULL\0OUTPUT\0INPUT\0"
+     "NOT\0AND\0OR\0NAND\0NOR\0XOR\0AND3\0OR3\0NAND3\0NOR3\0";
+
+#define GT_NULL   0  //Specifies that table entry has not been filled-in
+#define GT_OUTPUT 1  //Specifies the table entry is a desired output
+#define GT_INPUT  2  //Specifies that table entry comes from an input signal
+
+#define GT_FIRST_REAL_GATE 3
+#define GT_NOT          3
+#define GT_AND          4
+#define GT_OR           5
+#define GT_NAND         6
+#define GT_NOR          7
+#define GT_XOR          8
+#define GT_AND3         9
+#define GT_OR3          10
+#define GT_NAND3        11
+#define GT_NOR3         12
+#define GT_ENTRIES_NUM  13
+
+#define SEL_GATES_NUM   128
+
+U8 *imgs[GT_ENTRIES_NUM]={NULL,NULL,NULL,
+<NOT>,<AND>,<OR>,<NAND>,<NOR>,<XOR>,<AND3>,<OR3>,<NAND3>,<NOR3>};
+
+I64 num_inputs_entered,num_outputs_entered;
+I64 num_sel_gates,
+    sel_gates[SEL_GATES_NUM];
+
+U0 GetGates()
+{
+  I64 i;
+  U8 *st;
+
+  "\nEnter the available gate types in the order you prefer them to be used.\n"
+        "Your choices are:\n";
+  for (i=GT_FIRST_REAL_GATE;i<GT_ENTRIES_NUM;i++)
+    "%z ",i,gate_type_lst;
+  '\n';
+
+  num_sel_gates=0;
+  while (num_sel_gates<GT_ENTRIES_NUM) {
+    "%d",num_sel_gates;
+    st=GetStr(" Gate: ");
+    if (!*st) {
+      Free(st);
+      return;
+    }
+    i=LstMatch(st,gate_type_lst,LMF_IGNORE_CASE);
+    Free(st);
+    if (i<GT_FIRST_REAL_GATE)
+      "Invalid response\n";
+    else
+      sel_gates[num_sel_gates++]=i;
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+
+  do {
+    table_size=GetI64("\nTable size in hex (3 input=0x100,4=0x10000): ",0);
+    if (table_size>TABLE_SIZE_MAX)
+      "Too large\n";
+    else if (table_size<1) {
+      "No table specified, aborting.\n";
+      throw;
+    }
+  } while (table_size>TABLE_SIZE_MAX);
+
+  gate_type_table =CAlloc(table_size*sizeof(U8));
+  displayed_design=MAlloc((table_size+7)/8);
+  added_this_pass =MAlloc((table_size+7)/8);
+  input1_table    =MAlloc(table_size*sizeof(U16));
+  input2_table    =MAlloc(table_size*sizeof(U16));
+  input3_table    =MAlloc(table_size*sizeof(U16));
+
+  "\nEnter the hex truth table column values of inputs.\n";
+  if (table_size<=0x100)
+    "For example, enter A=0xF0, B=0xCC and C=0xAA.\n";
+  else
+    "For example, enter A=0xFF00, B=0xF0F0, C=0xCCCC and D=0xAAAA.\n";
+  num_inputs_entered=0;
+  while (TRUE) {
+    "Input %C: ",'A'+num_inputs_entered;
+    i=GetI64("",-1);
+    if (i<0) break;
+    if (i>table_size)
+      "Too large\n";
+    else {
+      if (gate_type_table[i])
+        "Duplicate\n";
+      else {
+        gate_type_table[i]=GT_INPUT;
+        input1_table[i]=num_inputs_entered++;
+      }
+    }
+  }
+  if (!num_inputs_entered) {
+    "No inputs specified, aborting.\n";
+    throw;
+  }
+
+  "\nEnter the hex truth table columns values of the outputs.\n";
+  num_outputs_entered=0;
+  while (TRUE) {
+    "Output %C: ",'A'+num_outputs_entered;
+    i=GetI64("",-1);
+    if (i<0) break;
+    if (i>table_size)
+      "Too large\n";
+    else {
+      if (gate_type_table[i]==GT_INPUT)
+        "To produce this output, connect to input %C\n",
+              'A'+input1_table[i];
+      else if (gate_type_table[i]==GT_OUTPUT)
+        "Duplicate\n";
+      else {
+        gate_type_table[i]=GT_OUTPUT;
+        input1_table[i]=num_outputs_entered++;
+      }
+    }
+  }
+
+  if (!num_outputs_entered) {
+    "No output specified, aborting.\n";
+    throw;
+  }
+}
+
+U0 DrawDesign(CDC *dc,I64 *_y,I64 output,I64 depth,I64 *_x_out,I64 *_y_out)
+{
+  I64 y=*_y,type=gate_type_table[output],
+        xx=(passes-depth)*(GATE_WIDTH+CONNECT_WIDTH),yy=y,
+        x1,y1,x2,y2,x3,y3;
+  if (_x_out) *_x_out=xx;
+  if (_y_out) *_y_out=yy;
+  if (Bt(displayed_design,output) && type!=GT_INPUT) {
+    dc->color=GREEN;
+    GrPrint(dc,xx-FONT_WIDTH*3,y-4,"Dup");
+    y+=10;
+  } else
+    switch (type) {
+      case GT_INPUT:
+        dc->color=GREEN;
+        GrPrint(dc,xx-FONT_WIDTH-4,y-4,"%C",'A'+input1_table[output]);
+        y+=10;
+        break;
+      case GT_NOT:
+        if (!Bt(displayed_design,output)) {
+          y+=16;
+          DrawDesign(dc,&y,input1_table[output],depth+1,&x1,&y1);
+          yy=y1;
+
+          dc->color=BLUE;
+          Sprite3(dc,xx,yy,0,imgs[type]);
+
+          dc->color=RED;
+          GrLine(dc,xx-GATE_WIDTH,yy,x1,y1);
+          if (_y_out) *_y_out=yy;
+        }
+        break;
+      case GT_AND:
+      case GT_OR:
+      case GT_NAND:
+      case GT_NOR:
+      case GT_XOR:
+        if (!Bt(displayed_design,output)) {
+          y+=24;
+          DrawDesign(dc,&y,input1_table[output],depth+1,&x1,&y1);
+          DrawDesign(dc,&y,input2_table[output],depth+1,&x2,&y2);
+          yy=(y1+y2)/2;
+
+          dc->color=BLUE;
+          Sprite3(dc,xx,yy,0,imgs[type]);
+
+          dc->color=RED;
+          GrLine(dc,xx-GATE_WIDTH,yy-4,x1,y1);
+          GrLine(dc,xx-GATE_WIDTH,yy+4,x2,y2);
+          if (_y_out) *_y_out=yy;
+        }
+        break;
+      case GT_AND3:
+      case GT_OR3:
+      case GT_NAND3:
+      case GT_NOR3:
+        if (!Bt(displayed_design,output)) {
+          y+=32;
+          DrawDesign(dc,&y,input1_table[output],depth+1,&x1,&y1);
+          DrawDesign(dc,&y,input2_table[output],depth+1,&x2,&y2);
+          DrawDesign(dc,&y,input3_table[output],depth+1,&x3,&y3);
+          yy=(y1+y2+y3)/3;
+
+          dc->color=BLUE;
+          Sprite3(dc,xx,yy,0,imgs[type]);
+
+          dc->color=RED;
+          GrLine(dc,xx-GATE_WIDTH,yy-8,x1,y1);
+          GrLine(dc,xx-GATE_WIDTH,yy  ,x2,y2);
+          GrLine(dc,xx-GATE_WIDTH,yy+8,x3,y3);
+          if (_y_out) *_y_out=yy;
+        }
+        break;
+    }
+  dc->color=BLACK;
+  GrPrint(dc,xx,yy+3,"%04X",output);
+  Bts(displayed_design,output);
+  if (_y) *_y=y;
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 y=0;
+  MemSet(displayed_design,0,(table_size+7)/8*sizeof(Bool));
+  DrawDesign(dc,&y,output_found,0,NULL,NULL);
+}
+
+U0 FillNot(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i)) {
+      progress1=i;
+      j= (~i) & (table_size-1);
+      old_type=gate_type_table[j];
+      if (old_type<GT_INPUT) {
+        gate_type_table[j]=GT_NOT;
+        input1_table[j]=i;
+        Bts(added_this_pass,j);
+        *chged=TRUE;
+        if (old_type==GT_OUTPUT) {
+          if (output_found<0) output_found=j;
+          *num_outputs_found=*num_outputs_found+1;
+        }
+      }
+    }
+}
+
+U0 FillAnd(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (i & k) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_AND;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillOr(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (i | k) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_OR;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillNAnd(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (~ (i & k)) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_NAND;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillNOr(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (~ (i | k)) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_NOR;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillXor(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k)) {
+          progress1=i;
+          j= (i ^ k) & (table_size-1);
+          old_type=gate_type_table[j];
+          if (old_type<GT_INPUT) {
+            gate_type_table[j]=GT_XOR;
+            input1_table[j]=i;
+            input2_table[j]=k;
+            Bts(added_this_pass,j);
+            *chged=TRUE;
+            if (old_type==GT_OUTPUT) {
+              if (output_found<0) output_found=j;
+              *num_outputs_found=*num_outputs_found+1;
+            }
+          }
+        }
+}
+
+U0 FillAnd3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (i & k & l) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_AND3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+U0 FillOr3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (i | k | l) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_OR3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+U0 FillNAnd3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (~(i & k & l)) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_NAND3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+U0 FillNOr3(Bool *chged,I64 *num_outputs_found)
+{
+  I64 i,j,k,l,old_type;
+  for (i=0;i<table_size;i++)
+    if (gate_type_table[i]>GT_OUTPUT && !Bt(added_this_pass,i))
+      for (k=0;k<table_size;k++)
+        if (gate_type_table[k]>GT_OUTPUT && !Bt(added_this_pass,k))
+          for (l=0;l<table_size;l++)
+            if (gate_type_table[l]>GT_OUTPUT && !Bt(added_this_pass,l)) {
+              progress1=i;
+              j= (~(i | k | l)) & (table_size-1);
+              old_type=gate_type_table[j];
+              if (old_type<GT_INPUT) {
+                gate_type_table[j]=GT_NOR3;
+                input1_table[j]=i;
+                input2_table[j]=k;
+                input3_table[j]=l;
+                Bts(added_this_pass,j);
+                *chged=TRUE;
+                if (old_type==GT_OUTPUT) {
+                  if (output_found<0) output_found=j;
+                  *num_outputs_found=*num_outputs_found+1;
+                }
+              }
+            }
+}
+
+I64 FillGateTable()
+{
+  I64 current_gate,num_outputs_found=0;
+  Bool chged=TRUE;
+  passes=1;
+  output_found=-1;
+  ProgressBarsRst;
+  progress1_max=table_size;
+  '\n';
+  while (num_outputs_found<num_outputs_entered && chged) {
+    "Pass : %d\n",passes++;
+    chged=FALSE;
+    MemSet(added_this_pass,0,(table_size+7)/8);
+    for (current_gate=0;current_gate<num_sel_gates &&
+          num_outputs_found<num_outputs_entered;current_gate++) {
+      switch (sel_gates[current_gate]) {
+        case GT_NOT:   FillNot  (&chged,&num_outputs_found); break;
+        case GT_AND:   FillAnd  (&chged,&num_outputs_found); break;
+        case GT_OR:    FillOr   (&chged,&num_outputs_found); break;
+        case GT_NAND:  FillNAnd (&chged,&num_outputs_found); break;
+        case GT_NOR:   FillNOr  (&chged,&num_outputs_found); break;
+        case GT_XOR:   FillXor  (&chged,&num_outputs_found); break;
+        case GT_AND3:  FillAnd3 (&chged,&num_outputs_found); break;
+        case GT_OR3:   FillOr3  (&chged,&num_outputs_found); break;
+        case GT_NAND3: FillNAnd3(&chged,&num_outputs_found); break;
+        case GT_NOR3:  FillNOr3 (&chged,&num_outputs_found); break;
+      }
+    }
+  }
+  ProgressBarsRst;
+  return num_outputs_found;
+}
+
+U0 CleanUp()
+{
+  Free(gate_type_table);
+  Free(displayed_design);
+  Free(added_this_pass);
+  Free(input1_table);
+  Free(input2_table);
+  Free(input3_table);
+}
+
+U0 DigitalLogic()
+{
+  gate_type_table =NULL;
+  displayed_design=NULL;
+  added_this_pass =NULL;
+  input1_table    =NULL;
+  input2_table    =NULL;
+  input3_table    =NULL;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder(ON);
+  WinMax;
+  DocClear;
+  GetGates;
+  try {
+    Init;
+    if (FillGateTable) {
+      DocCursor;
+      DocClear;
+      Fs->draw_it=&DrawIt;
+      GetChar;
+      DocClear;
+      Refresh(2,TRUE);
+      DocBottom;
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Logic/Run.HC.HTML b/public/Wb/Home/Src/Apps/Logic/Run.HC.HTML new file mode 100755 index 0000000..23a5137 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Logic/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+DigitalLogic;
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Examples/childish.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/Examples/childish.HC.HTML new file mode 100755 index 0000000..9815331 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Examples/childish.HC.HTML @@ -0,0 +1,55 @@ + + + + + + + + + + + +
+//9 has words
+U0 Song()
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 2.480;
+  music.stacatto_factor= 0.902;
+  try {
+    while (!ScanKey) {
+      Play("5qEsCDCDqCDeEGsE4B5E4B5eC4B5sD4A5D4A",
+            "Be \0like \0 \0a \0 \0child \0 \0 \0 \0"
+            "some \0 \0re\0 \0spect.\n\0 \0 \0 \0 \0 \0");
+      Play("5qEsCDCDqCDeEGsE4B5E4B5eC4B5sD4A5D4A",
+            "Ma\0tur\0 \0i\0 \0ty \0 \0 \0 \0don't \0 \0"
+            "ne\0 \0glect.\n\0 \0 \0 \0 \0 \0");
+      Play("4eB5DqF4sGAGAqAAA5etD4AA5sD4B5D4B");
+      Play("4eB5DqF4sGAGAqAAA5etD4AA5sD4B5D4B");
+    }
+  } catch
+    PutExcept;
+  Snd;
+}
+
+Song;
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Examples/night.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/Examples/night.HC.HTML new file mode 100755 index 0000000..d8b8087 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Examples/night.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+//9 has graphics
+
+         <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+#define X       330
+#define Y       35
+
+F64 t0=Beat;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  F64 x,y,dt=Beat-t0;
+  Sprite3(dc,X,Y,0,<1>);
+  if (Beat-t0<24) {
+    if (Rand<0.7) {
+      dc->color=YELLOW;
+      GrPlot(dc,X-12,Y+1);
+      GrPlot(dc,X-12,Y+2);
+      GrPlot(dc,X-11,Y+4);
+      GrPlot(dc,X+10,Y+4);
+      GrPlot(dc,X+4,Y+4);
+      GrPlot(dc,X+5,Y+4);
+      GrPlot(dc,X+6,Y+4);
+      GrPlot(dc,X+7,Y+5);
+      GrPlot(dc,X+8,Y+5);
+    }
+    for (i=0;i<512;i++) {
+      x=1.0-Rand`3.0;
+      y=Rand;
+      x=5.0*Sin(pi*Sqrt(y))*x;
+      y=25.0*y;
+      if (Rand*(x*x+2.0)*Sqrt(y)<4.0) {
+        if (Rand<0.5)
+          dc->color=BLUE;
+        else
+          dc->color=LTBLUE;
+      } else
+        dc->color=YELLOW;
+      if (RandI16<0)
+        x=-x;
+      x+=150.0*Sin(pi*dt)/(35-y)`1.5;
+      GrPlot(dc,X+x,Y-y);
+    }
+  }
+}
+
+U0 Song()
+{
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+LTGRAY;
+  Fs->draw_it=&DrawIt;
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo=2.0;
+  try {
+    "$BG+H,BLACK$$FD+H,LTGRAY$";
+    while (TRUE) {
+      t0=Beat;
+      "$WHITE$God said this was a dirge.\n$FG$";
+      Play("5FqDqD4eA5CqEqEqDqDq",
+            "Gone \0to \0sleep \0for \0the \0fi\0nal \0time.\n\0");
+      Play("5FqDqD4eA5CqEqEqDqDq",
+            "Gone \0to \0sleep \0for \0the \0fi\0nal \0time.\n\0");
+      Play("5DqGqFeGFqFqEqE4qBq",
+            " \0Ash \0to... \0and \0 \0dust \0to \0dust.\n\0");
+      Play("5DqGqFeGFqFqEqE4qBq",
+            " \0Ash \0to... \0and \0 \0dust \0to \0dust.\n\0");
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+Song;
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Examples/prosper.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/Examples/prosper.HC.HTML new file mode 100755 index 0000000..e26b2c5 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Examples/prosper.HC.HTML @@ -0,0 +1,87 @@ + + + + + + + + + + + +
+//9 has graphics
+
+//When using flood-fill in a graphic
+//element, you probably want to
+//convert it to a bitmap using the
+//feature in the <CTRL-r> menu.
+
+   <1>/* Graphics Not Rendered in HTML */
+
+
+   <2>/* Graphics Not Rendered in HTML */
+
+
+F64 t0=Beat;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 dt=Beat-t0;
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4RotZ(dc->r,0.25*Sin(2*dt));
+  Mat4x4Scale(dc->r,1.5+0.5*Sin(dt/3));
+  DCMat4x4Set(dc,dc->r);
+  if (ToI64(dt)&1)
+    Sprite3B(dc,12.0*dt%task->pix_width,20,0,<1>);
+  else
+    Sprite3B(dc,12.0*dt%task->pix_width,20,0,<2>);
+}
+
+U0 Song()
+{
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=GREEN<<4+YELLOW;
+  Fs->draw_it=&DrawIt;
+  Fs->task_end_cb=&SndTaskEndCB;
+
+  MusicSettingsRst;
+  music.tempo=3.5;
+  try {
+    while (!ScanKey) {
+      t0=Beat;
+      Play("5qG4G5D4B5sDCDCqRCG",
+            "$CL$$BG,9$\n\n$BG,2$$CM-LE,3$$FG,14$Baa, \0"
+            "the \0grass \0is \0green.\n\0 \0 \0 \0 \0 \0 \0");
+      Play("5G4G5D4B5sDCDCqRCG",
+            "This \0must \0be \0a \0dream.\n\0 \0 \0 \0 \0 \0 \0");
+      Play("5EeGF4qBB5D4AeGGqR",
+            "Thanks, \0my \0 \0shep\0herd.  \0You \0are \0good.\n\0 \0 \0");
+      Play("5EeGF4qBB5D4AeGGqR",
+            "Thanks, \0my \0 \0shep\0herd.  \0You \0are \0good.\n\0 \0 \0");
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+Song;
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Help.DD.HTML b/public/Wb/Home/Src/Apps/Psalmody/Help.DD.HTML new file mode 100755 index 0000000..d7f30c2 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Help.DD.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+                                 Psalmody Help
+
+* The keyboard can be used as an organ by typing letter keys or clicking the 
+mouse on the keyboard diagram.  You can "record" notes by pressing the red bttn 
+and typing letters.  They will appear on the musical staff.  You can edit and 
+save them.
+
+* The clip can be used to cut and paste.
+
+* Psalmody uses HolyC files as the song format!  See 
+::/Apps/Psalmody/Examples/prosper.HC.  The Psalmody program does not fully parse 
+the songs when loading them back in, so changes made outside Psalmody will be 
+lost, like if you add graphics.
+
+* The first line of the HolyC song files is a comment with a category recognized 
+by JukeBox().  The categories are "no nothing", "has words", "has graphics", or 
+"special".  The third character in the song comment is a digit rating number, 
+shown in JukeBox().  You can set the song rating in JukeBox() by pressing 0-9.  
+You can request your reward from God by pressing r.  You can press <DEL> to 
+delete songs.
+
+* You can take the Play() stmts out of a song file and place them in your 
+programs.  You can also add a song to a document with <CTRL-l>, but you should 
+do it after pressing <CTRL-t> because the clip-insert in <CTRL-l> is screwy.  
+See this <Song> after pressing <CTRL-t>, now.
+
+* You can call JukeBox("~/Psalmody"); to play your songs.
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Install.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/Install.HC.HTML new file mode 100755 index 0000000..2dce866 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Install.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+if (!FileFind("~/Psalmody",,FUF_JUST_DIRS))
+  DirMk("~/Psalmody");
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/JukeBox.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/JukeBox.HC.HTML new file mode 100755 index 0000000..ffa2e52 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/JukeBox.HC.HTML @@ -0,0 +1,231 @@ + + + + + + + + + + + +
+CTask *JukeReward(U8 *msg)
+{
+  U8 *buf;
+  CDoc *doc;
+  CTask *res=Spawn(&SrvCmdLine,NULL,"Reward",,Fs);
+  StrCpy(res->task_title,"Reward");
+  res->title_src=TTS_LOCKED_CONST;
+
+  doc=DocNew(,res);
+  DocPrint(doc,"$WW+H,1$$RED$%s",msg);
+
+  buf=MStrPrint("DocEd(0x%X);",doc);
+  TaskExe(res,NULL,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  Free(buf);
+  TaskWait(res);
+
+  res->border_src =BDS_CONST;
+  res->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  res->text_attr  =LTGRAY<<4+BLUE;
+  res->win_inhibit=WIG_NO_FOCUS_TASK_DFT;
+  WinHorz(Fs->win_right+2,TEXT_COLS-2,res);
+  WinVert(2,TEXT_ROWS-2,res);
+
+  WinFocus(Fs->parent_task);
+  return res;
+}
+
+CTask *SingleSong(U8 *msg,U8 *name)
+{
+  CTask *task=Spawn(&SrvCmdLine,NULL,name,,Fs);
+  StrCpy(task->task_title,name);
+  task->title_src=TTS_LOCKED_CONST;
+  TaskExe(task,Fs,";",1<<JOBf_WAKE_MASTER|1<<JOBf_FREE_ON_COMPLETE);
+  WinHorz(task->win_left,task->win_left+50,task);
+  WinVert(2,2+8,task);
+  task->win_inhibit=WIG_NO_FOCUS_TASK_DFT;
+  TaskExe(task,NULL,msg,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+  DocPut(task)->max_entries=100;
+  return task;
+}
+
+#define JB_RUN_LEVEL_NULL       0
+#define JB_RUN_LEVEL_ONE        1
+#define JB_RUN_LEVEL_TWO        2
+
+Bool JBPutKey(CDoc *doc,U8 *,I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+  CDocEntry *doc_ce=doc->cur_entry,*doc_e;
+  CDirEntry *tmpde;
+  I64 i;
+  U8 *st;
+  CDoc *doc2;
+  if (!(sc&(SCF_ALT|SCF_CTRL|SCF_SHIFT))
+        && doc_ce->type_u8==DOCT_MENU_VAL && doc_ce->left_exp>=0) {
+    tmpde=doc_ce->left_exp;
+    if (sc.u8[0]==SC_DELETE ) {
+      Beep;
+      Silent;
+      Del(tmpde->full_name);
+      Silent(OFF);
+    } else if ('0'<=ch<='9') {
+      if (StrLen(doc_ce->tag)>1)
+        doc_ce->tag[0]=ch;
+      doc2=DocRead(tmpde->full_name);
+      DocGoToLine(doc2,1);
+      doc_e=doc2->cur_entry;
+      if (doc_e!=doc2 && doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=3) {
+        doc_e->tag[2]=ch;
+        DocWrite(doc2);
+      }
+      DocDel(doc2);
+      return TRUE;
+    } else if (ch=='r') {
+      if (!DocTreeFFind(tmpde->full_name,"Reward1")) {
+        doc2=DocRead(tmpde->full_name);
+        DocGoToLine(doc2,2);
+        DocPrint(doc2,
+              "\n$TR,\"Reward1\"$\n"
+              "$ID,2$CallExtStr(\"JukeReward\",\"\"\n"
+              "$TR,\"Reward2\"$\n"
+              "$ID,2$\n"
+              "$ID,-2$\n"
+              ");\n$ID,-2$\n"
+              );
+        DocWrite(doc2);
+        DocDel(doc2);
+      }
+      if (DocTreeFFind(tmpde->full_name,"Reward1/Reward2")) {
+        for (i=0;i<5;i++) {
+          st=MStrPrint("%s %s %s %s ",
+                GodWordStr,GodWordStr,GodWordStr,GodWordStr);
+          DocTreeFAppend(tmpde->full_name,"Reward1/Reward2",
+                "\"%s\"\n",st);
+          Free(st);
+        }
+        In(" ");
+      }
+      return TRUE;
+    } else if (ch==CH_SPACE||ch==CH_ESC)
+      tmpde->user_data++; //JB_RUN_LEVEL++
+//<SPACE> is followed by <ESC> --> JB_RUN_LEVEL_TWO
+      //Actual <ESC> just exits      --> JB_RUN_LEVEL_ONE
+  }
+  return FALSE;
+}
+
+public U0 JukeBox(U8 *dirname="~/Psalmody",U8 **_filename=NULL)
+{//_filename is for using this as a song-chooser program.
+  I64 i=0,rating;
+  U8 *st,*st2;
+  CDirEntry *tmpde,*tmpde1;
+  CDoc *doc=DocNew,*s;
+  CDocEntry *doc_e;
+  CTask *task=NULL;
+  if (_filename)
+    *_filename=NULL;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  try {
+    dirname=StrNew(dirname);
+    st=MStrPrint("%s/*.HC.Z",dirname);
+    tmpde=tmpde1=FilesFind(st);
+    Free(st);
+    Free(dirname);
+    doc->user_put_key=&JBPutKey;
+    DocPrint(doc,
+          "Key: $GREEN$Graphics $BLUE$Words $RED$No Nothing "
+          "$BLACK$Incomplete $CYAN$Special$FG$\n\n"
+          "$GREEN$<DEL>$FG$\tto delete a song.\n"
+          "'$GREEN$0$FG$'-'$GREEN$9$FG$'\tto rate a song.\n"
+          "'$GREEN$r$FG$'\tto get your reward from God.\n");
+    while (tmpde) {
+      if (!(i++%5))
+        DocPrint(doc,"\n");
+      if (FileOcc("Play(",tmpde->full_name,"")) {
+        st=StrNew(tmpde->name);
+        FileExtRem(st);
+        s=DocRead(tmpde->full_name);
+        doc_e=s->head.next;
+        while (doc_e!=s && doc_e->type_u8!=DOCT_TEXT)
+          doc_e=doc_e->next;
+        rating='0';
+        if (doc_e!=s && doc_e->type_u8==DOCT_TEXT) {
+          if ('0'<=doc_e->tag[2]<='9')
+            rating=doc_e->tag[2];
+          if (StrMatch("incomplete",doc_e->tag))
+            DocPrint(doc,"$BLACK$");
+          else if (StrMatch("has graphics",doc_e->tag))
+            DocPrint(doc,"$GREEN$");
+          else if (StrMatch("has words",doc_e->tag))
+            DocPrint(doc,"$BLUE$");
+          else if (StrMatch("special",doc_e->tag))
+            DocPrint(doc,"$CYAN$");
+          else if (StrMatch("no nothing",doc_e->tag)) {
+            DocPrint(doc,"$RED$");
+            if (FileOcc("\\0",tmpde->full_name,"")) {
+              s->cur_entry=doc_e->next;
+              s->cur_col=0;
+              DocEntryDel(s,doc_e);
+              DocPrint(s,"//0 has words\n");
+              DocWrite(s);
+            }
+          }
+          DocPrint(doc,"$MU-UL,\"%c%-8ts\",LE=%d$ ",rating,st,tmpde);
+          tmpde->user_data=JB_RUN_LEVEL_NULL;
+        }
+        DocDel(s);
+        Free(st);
+      }
+      tmpde=tmpde->next;
+    }
+    DocPrint(doc,"\n$CYAN$$MU-UL,\"DONE\",LE=%d$\n",DOCM_CANCEL);
+    while (TRUE) {
+      if (_filename)
+        tmpde=PopUpMenu(doc,DOF_INTERCEPT_TASK_END);
+      else
+        tmpde=PopUpMenu(doc);
+      if (task)
+        Kill(task);
+      if (tmpde<=0) break;
+      st2=StrNew(tmpde->name);
+      if (_filename) {
+        Free(*_filename);
+        *_filename=StrNew(tmpde->full_name);
+      }
+      if (tmpde->user_data==JB_RUN_LEVEL_ONE) break; //<ESC>
+      tmpde->user_data=JB_RUN_LEVEL_NULL; //Rst from <SPACE>
+      FileExtRem(st2);
+      st=MStrPrint("ExeFile(\"%s\");",tmpde->full_name);
+      MusicSettingsRst;
+      task=SingleSong(st,st2);
+      Free(st2);
+      Free(st);
+    }
+    DocDel(doc);
+    DirTreeDel(tmpde1);
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/JukePuppet.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/JukePuppet.HC.HTML new file mode 100755 index 0000000..3199670 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/JukePuppet.HC.HTML @@ -0,0 +1,126 @@ + + + + + + + + + + + +
+U0 SongPuppet(CTask *task,I64 passes)
+{
+  CDbgInfo *dbg_info;
+  I64 i,start,end,rip,last_rip;
+  CHashFun *tmpf=NULL;
+  for (i=0;i<250 && TaskValidate(task);i++) {
+    if (tmpf=HashFind("Song",task->hash_table,HTT_FUN))
+      break;
+    Sleep(1);
+  }
+  if (tmpf && (dbg_info=tmpf->dbg_info)) {
+    start=dbg_info->body[0];
+    end  =dbg_info->body[dbg_info->max_line+1-dbg_info->min_line];
+    last_rip=0;
+    while (TRUE) {
+      i=0;
+      while (TaskValidate(task) && (rip=TaskCaller(task,i++))) {
+        if (start<=rip<end) {
+          if (rip<last_rip && --passes<=0)
+            return;
+          last_rip=rip;
+        }
+      }
+      Sleep(1);
+    }
+  }
+}
+
+U0 JukeSongPuppet(CTask *juke_task,I64 passes,I64 song_num,U8 *name)
+{
+  Bool found;
+  CTask *task;
+  I64 i;
+
+  if (FileExtDot(name))
+    FileExtRem(name);
+  BirthWait(&juke_task->popup_task);
+  TaskWait(juke_task->popup_task);
+  PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP+SCF_CTRL);
+  TaskWait(juke_task->popup_task);
+  for (i=0;i<song_num;i++) {
+    PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    TaskWait(juke_task->popup_task);
+  }
+
+  PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  TaskWait(juke_task->popup_task);
+  Sleep(500);
+
+  found=FALSE;
+  task=Fs->next_task;
+  while (task!=Fs) {
+    if (!StrCmp(task->task_title,name)) {
+      found=TRUE;
+      break;
+    }
+    task=task->next_task;
+  }
+
+  if (found) {//Position cursor on song title during song
+    TaskWait(juke_task->popup_task);
+    PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP+SCF_CTRL);
+    TaskWait(juke_task->popup_task);
+    for (i=0;i<song_num;i++) {
+      PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+      TaskWait(juke_task->popup_task);
+    }
+    SongPuppet(task,passes);
+  }
+  Kill(task);
+}
+
+public U0 JukeSongsPuppet(U8 *dirname="~/Psalmody",I64 passes=2,
+        I64 start_song=0,I64 end_song=I64_MAX)
+{//Help make music video by puppeting JukeBox task.
+  I64 i;
+  CDirEntry *tmpde,*tmpde1;
+  CTask *juke_task=User("JukeBox(0x%X);\n",dirname);
+  F64 t0;
+  Cd(dirname);
+  tmpde1=FilesFind("*",FUF_RECURSE|FUF_JUST_TXT|FUF_JUST_FILES);
+  for (tmpde=tmpde1,i=0;tmpde && i<start_song;i++)
+    tmpde=tmpde->next;
+  if (scrncast.record)
+    t0=scrncast.t0_tS;
+  else
+    t0=tS;
+  for (i=start_song;tmpde && i<end_song;i++) {
+    "%12.6fs %s\n",tS-t0,tmpde->full_name;
+    JukeSongPuppet(juke_task,passes,i,tmpde->name);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  Kill(juke_task);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Load.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/Load.HC.HTML new file mode 100755 index 0000000..acad725 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Load.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+#help_index "Snd/Music/Apps"
+
+Cd(__DIR__);;
+#include "JukeBox"
+#include "JukePuppet"
+#include "Psalmody"
+#include "PsalmodyCtrls"
+#include "PsalmodyDraw"
+#include "PsalmodyFile"
+#include "PsalmodyMain"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Psalmody.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/Psalmody.HC.HTML new file mode 100755 index 0000000..cc0e05d --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Psalmody.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+/*
+This uses four types of ctrls
+
+  1) The pull-down menu.
+
+  2) The CCtrl type for the tempo/stacatto sliders.
+
+  3) The active CDoc sprite bttns with macros for left/record/play/right.
+
+  4) Hand-made ctrls for the kbdgraphic, notes and staff.
+
+This uses four types of output
+
+  1) The CDoc for the text and bttns and kbdgraphic.
+
+  2) The Fs->draw_it() for the staff region, drawn every refresh.
+
+  3) The gr.dc persistent layer for the note chooser, meter chooser.  The 
+persistent layer is used during drag-and-drop.
+
+  4) The Fs->next_ctrl for the tempo/stacatto sliders.
+
+See GrUpdateTaskWin(), GrUpdateTasks() and GrUpdateScrn().
+*/
+
+#define PSMT_HEAD       0
+#define PSMT_NOTE       1
+#define PSMT_METER      2
+
+#define PSMf_SEL        0
+#define PSMF_SEL        1
+#define PSMf_SHARP      1
+#define PSMf_FLAT       2
+#define PSMf_TIE        3
+
+class PsmNote
+{
+  PsmNote *next,*last;
+  I64 x,y;
+  U8 *word;
+  I64 type,flags;
+  I64 ona,meter_top,meter_bottom;
+  I64 duration,width;
+  U8 ascii[32];
+};
+
+//Tool types
+#define PSMTT_PTR_TOOL  0
+#define PSMTT_BOX_TOOL  1
+
+class PsmCtrl
+{
+  PsmNote head;
+  PsmNote clip;
+  CMenuEntry *incomplete_entry,*record_entry;
+  I64 scrn_x,tool;
+  PsmNote *cur_note;
+  CDC *dc2;
+  Bool playing;
+} psm;
+
+U8 *psm_note_lst="A\0A#\0B\0C\0C#\0D\0D#\0E\0F\0F#\0G\0G#\0";
+U8 psm_note_map[12]={6,6,5,4,4,3,3,2,1,1,0,0};
+U8 psm_note_inverse_map[7]={10,8,7,5,3,2,0};
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/PsalmodyCtrls.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyCtrls.HC.HTML new file mode 100755 index 0000000..e81049e --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyCtrls.HC.HTML @@ -0,0 +1,120 @@ + + + + + + + + + + + +
+#define TEMPO_SPACING 15
+#define TEMPO_RANGE   80
+#define TEMPO_BORDER  2
+
+class TempoState
+{
+  I64 tempo,stacatto;
+} tempo_state;
+
+U0 DrawTempoCtrl(CDC *dc,CCtrl *c)
+{
+  TempoState *s=c->state;
+
+  dc->color=LTGREEN;
+  GrRect(dc, c->left,c->top,TEMPO_SPACING*3+2,TEMPO_SPACING*2+TEMPO_RANGE);
+  dc->color=BLACK;
+  GrRect(dc, c->left+TEMPO_BORDER,c->top+TEMPO_BORDER,
+        TEMPO_SPACING*3+2-2*TEMPO_BORDER,
+        TEMPO_SPACING*2+TEMPO_RANGE-2*TEMPO_BORDER);
+  dc->color=WHITE;
+  GrLine(dc,c->left+TEMPO_SPACING,c->top+TEMPO_SPACING,
+        c->left+TEMPO_SPACING,c->top+TEMPO_SPACING+TEMPO_RANGE-1);
+  GrLine(dc,c->left+2*TEMPO_SPACING+1,c->top+TEMPO_SPACING,
+        c->left+2*TEMPO_SPACING+1,c->top+TEMPO_SPACING+TEMPO_RANGE-1);
+
+  dc->color=LTGREEN;
+  GrPrint(dc,c->left+TEMPO_SPACING-FONT_WIDTH/2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE+3,"%d",s->tempo*10/TEMPO_RANGE);
+  GrPrint(dc,c->left+2*TEMPO_SPACING+1-FONT_WIDTH/2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE+3,"%d",
+        s->stacatto*10/TEMPO_RANGE);
+  GrRect(dc,c->left+TEMPO_SPACING-3,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->tempo-2 ,7,5);
+  GrRect(dc,c->left+2*TEMPO_SPACING+1-3,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->stacatto-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+TEMPO_SPACING-2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->tempo-1 ,5,3);
+  GrRect(dc,c->left+2*TEMPO_SPACING+1-2,
+        c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->stacatto-1,5,3);
+
+  dc->color=GREEN;
+  GrVPrint(dc,c->left+TEMPO_BORDER+2,c->top+TEMPO_SPACING+2,"Tempo");
+  GrVPrint(dc,c->right-TEMPO_BORDER-2-FONT_WIDTH,
+        c->top+TEMPO_SPACING+2,"Stacatto");
+}
+
+U0 UpdateDerivedTempoCtrl(CCtrl *c)
+{
+  TempoState *s=c->state;
+  c->right=c->left+TEMPO_SPACING*3+2;
+  c->bottom=c->top+TEMPO_SPACING*2+TEMPO_RANGE;
+  s->tempo =ClampI64(s->tempo,0,TEMPO_RANGE-1);
+  s->stacatto=ClampI64(s->stacatto,0,TEMPO_RANGE-1);
+}
+
+U0 LeftClickTempo(CCtrl *c,I64 x,I64 y,Bool)
+{
+  TempoState *s=c->state;
+  if (x<(c->right+c->left)/2)
+    s->tempo=TEMPO_RANGE-1-(y-(c->top+TEMPO_SPACING));
+  else
+    s->stacatto=TEMPO_RANGE-1-(y-(c->top+TEMPO_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *TempoNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&tempo_state;
+  c->draw_it=&DrawTempoCtrl;
+  c->left_click=&LeftClickTempo;
+  c->update_derived_vals=&UpdateDerivedTempoCtrl;
+  c->left=396;
+  c->top=96;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 TempoDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/PsalmodyDraw.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyDraw.HC.HTML new file mode 100755 index 0000000..580ff22 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyDraw.HC.HTML @@ -0,0 +1,440 @@ + + + + + + + + + + + +
+
+        
+        <1>/* Graphics Not Rendered in HTML */
+        
+        <2>/* Graphics Not Rendered in HTML */
+        
+        <3>/* Graphics Not Rendered in HTML */
+        
+        <4>/* Graphics Not Rendered in HTML */
+        
+        <5>/* Graphics Not Rendered in HTML */
+        
+        <6>/* Graphics Not Rendered in HTML */
+        
+        
+        <7>/* Graphics Not Rendered in HTML */
+        
+                
+        <8>/* Graphics Not Rendered in HTML */
+        
+        
+        <9>/* Graphics Not Rendered in HTML */
+        
+        
+        <10>/* Graphics Not Rendered in HTML */
+        
+        
+        <11>/* Graphics Not Rendered in HTML */
+        
+        
+        
+        
+        
+        
+        
+        <12>/* Graphics Not Rendered in HTML */
+        
+        
+                
+        
+        <13>/* Graphics Not Rendered in HTML */
+        
+        <14>/* Graphics Not Rendered in HTML */
+        
+        <15>/* Graphics Not Rendered in HTML */
+        
+        
+        <16>/* Graphics Not Rendered in HTML */
+
+#define PSM_NOTE_SPACING        9
+#define PSM_DURATIONS_NUM       12
+
+F64 psm_durations[PSM_DURATIONS_NUM+1]={
+2*.25/3,.25,2*.5/3,.5,2.0/3.0,0.5*1.5,1.0,1.5,2.0,3.0,4.0,6.0,1000000.0};
+U8 *psm_duration_lst="st\0s\0et\0e\0qt\0e.\0q\0q.\0h\0h.\0w\0w.\0";
+U8 *psm_duration_imgs[PSM_DURATIONS_NUM]={
+        <1>,<1>,<2>,<2>,<3>,<2>,<3>,<3>,<4>,<4>,<5>,<5>};
+Bool psm_triplet_durations[PSM_DURATIONS_NUM]={TRUE,FALSE,TRUE,
+        FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
+
+Bool PsmBlink()
+{
+  if (Blink || psm.playing)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool PsmHasWords(U8 *st)
+{
+  if (st && *st && (StrLen(st)>1 || *st!=CH_SPACE && *st!=CH_SHIFT_SPACE))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool PsmIsDotted(I64 duration)
+{
+  U8 *st=LstSub(duration,psm_duration_lst);
+  if (st[1]=='.')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 PsmMarkSel(I64 x1,I64 x2,Bool sel)
+{
+  PsmNote *tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    if (sel) {
+      if (x1<=tmpn->x<=x2)
+        tmpn->flags|=PSMF_SEL;
+    } else
+      tmpn->flags&=~PSMF_SEL;
+    tmpn=tmpn->next;
+  }
+}
+
+U0 PsmSetWidth(PsmNote *tmpn)
+{
+  if (tmpn->type==PSMT_METER)
+    tmpn->width=12;
+  else {
+    tmpn->width=PSM_NOTE_SPACING;
+    if (PsmIsDotted(tmpn->duration))
+      tmpn->width+=PSM_NOTE_SPACING/2;
+    if (Bt(&tmpn->flags,PSMf_SHARP) || Bt(&tmpn->flags,PSMf_FLAT))
+      tmpn->width+=PSM_NOTE_SPACING;
+  }
+}
+
+U0 PsmSetOctave(I64 octave)
+{
+  I64 i;
+  U8 buf[STR_LEN];
+  CMenuEntry *tmpse;
+  for (i=1;i<=7;i++) {
+    StrPrint(buf,"Snd/Octave%d",i);
+    if (tmpse=MenuEntryFind(Fs->cur_menu,buf)) {
+      if (i==octave)
+        tmpse->checked=TRUE;
+      else
+        tmpse->checked=FALSE;
+    }
+  }
+}
+
+U0 DrawNote(CDC *dc,I64 x,I64 y,I64 duration)
+{
+  if (0<=duration<=PSM_DURATIONS_NUM) {
+    Sprite3(dc,x,y,0,psm_duration_imgs[duration]);
+    if (psm_triplet_durations[duration])
+      Sprite3(dc,x,y,0,<16>);
+    if (PsmIsDotted(duration))
+      Sprite3(dc,x,y,0,<15>);
+  }
+}
+
+U0 DrawTimeSignature(CDC *dc,I64 x,I64 y,I64 top,I64 bottom)
+{
+  GrPrint(dc,x,y,"%d",top);
+  GrPrint(dc,x,y+FONT_HEIGHT,"%d",bottom);
+}
+
+U0 PsmRecalcNoteXY()
+{
+  F64 measure_len=4,measure_left=measure_len;
+  PsmNote *tmpn=psm.head.next;
+  I64 x=8-psm.scrn_x,ona,note,octave;
+  while (TRUE) {
+    tmpn->x=x;
+    tmpn->y=50;
+    if (tmpn==&psm.head)
+      break;
+    else {
+      if (tmpn->type!=PSMT_METER) {
+        if (tmpn->ona) {
+          ona=tmpn->ona;
+          if (Bt(&tmpn->flags,PSMf_SHARP))
+            ona--;
+          if (Bt(&tmpn->flags,PSMf_FLAT))
+            ona++;
+          octave=Ona2Octave(ona);
+          note  =Ona2Note  (ona);
+          note=music.note_map[*LstSub(note,psm_note_lst)-'A'];
+          if (note<3)
+            octave++;
+          tmpn->y=(15+(psm_note_map[note]-7*(octave-4)))*4;
+        }
+      }
+      x+=tmpn->width;
+      if (tmpn->type==PSMT_METER) {
+        measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
+        measure_left=0;
+      } else
+        measure_left-=psm_durations[tmpn->duration];
+      if (measure_left<0.001) {
+        x+=PSM_NOTE_SPACING;
+        measure_left=measure_len;
+      }
+    }
+    tmpn=tmpn->next;
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  PsmNote *tmpn;
+  I64 i,x,y,
+        w=task->pix_width;
+  F64 measure_len=4,measure_left=measure_len;
+
+  dc->color=BLACK;
+  for (i=1;i<6;i++)
+    GrLine(dc,0,i*8,w,i*8);
+  for (i=7;i<12;i++)
+    GrLine(dc,0,i*8,w,i*8);
+
+  PsmRecalcNoteXY;
+  if (psm.cur_note->x<64) {
+    psm.scrn_x-=128;
+    PsmRecalcNoteXY;
+  }
+  if (psm.cur_note->x>=GR_WIDTH-64) {
+    psm.scrn_x+=128;
+    PsmRecalcNoteXY;
+  }
+
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    x=tmpn->x;
+    y=tmpn->y;
+    if (measure_left<0.001) {
+      dc->color=BLACK;
+      GrLine(dc,x-PSM_NOTE_SPACING,8,x-PSM_NOTE_SPACING,11*8);
+      measure_left=measure_len;
+    }
+    if (tmpn->type==PSMT_METER) {
+      if (tmpn==psm.cur_note && PsmBlink)
+        dc->color=BROWN;
+      else
+        dc->color=BLACK;
+      DrawTimeSignature(dc,x,5*8,tmpn->meter_top,tmpn->meter_bottom);
+      measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
+      measure_left=0;
+    } else {
+      if (tmpn==psm.cur_note && PsmBlink) {
+        dc->color=BROWN;
+        GrPrint(dc,x+8,y,"%s",tmpn->word);
+      } else if (tmpn->flags&PSMF_SEL)
+        dc->color=RED;
+      else {
+        if (tmpn->ona)
+          dc->color=BLACK;
+        else
+          dc->color=LTGRAY;
+        if (PsmHasWords(tmpn->word))
+          dc->color=GREEN;
+      }
+      DrawNote(dc,x,y,tmpn->duration);
+      if (PsmIsDotted(tmpn->duration))
+        x+=PSM_NOTE_SPACING/2;
+      if (Bt(&tmpn->flags,PSMf_SHARP))
+        Sprite3(dc,x,y,0,<13>);
+      else if (Bt(&tmpn->flags,PSMf_FLAT))
+        Sprite3(dc,x,y,0,<14>);
+      measure_left-=psm_durations[tmpn->duration];
+    }
+    tmpn=tmpn->next;
+  }
+
+  if (psm.cur_note==&psm.head && PsmBlink)
+    dc->color=BROWN;
+  else
+    dc->color=BLACK;
+  Sprite3(dc,psm.head.x,50,0,<12>);
+}
+
+#define PSM_NOTE_BOX_X  220
+#define PSM_NOTE_BOX_Y  (13*FONT_HEIGHT+14)
+U0 PsmSetPickNoteBoxX(I64 duration,I64 *x)
+{
+  I64 i;
+  *x=PSM_NOTE_BOX_X;
+  for (i=0;i<duration;i++) {
+    if (PsmIsDotted(i))
+      *x+=PSM_NOTE_SPACING/2;
+    *x+=PSM_NOTE_SPACING+4;
+  }
+}
+
+I64 PsmGetPickNoteBoxDuration(I64 xx,I64 yy)
+{
+  I64 i,x1,x2;
+  if (PSM_NOTE_BOX_Y-14<=yy<PSM_NOTE_BOX_Y+6) {
+    for (i=0;i<PSM_DURATIONS_NUM;i++) {
+      PsmSetPickNoteBoxX(i,&x1);
+      PsmSetPickNoteBoxX(i+1,&x2);
+      if (x1<=xx+PSM_NOTE_SPACING/2<x2)
+        return i;
+    }
+  }
+  return -1;
+}
+
+U0 DrawPickNoteBox()
+{
+  I64 i,x;
+  for (i=0;i<PSM_DURATIONS_NUM;i++) {
+    PsmSetPickNoteBoxX(i,&x);
+    if (PsmIsDotted(i))
+      psm.dc2->color=RED;
+    else if (psm_triplet_durations[i])
+      psm.dc2->color=LTRED;
+    else
+      psm.dc2->color=BLACK;
+    DrawNote(psm.dc2,x,PSM_NOTE_BOX_Y,i);
+  }
+}
+
+#define PSM_TOOLS_X     450
+#define PSM_TOOLS_Y     13*FONT_HEIGHT
+
+U0 DrawPickTools()
+{
+  if (psm.tool==PSMTT_BOX_TOOL)
+    psm.dc2->color=ROPF_DITHER+WHITE<<16+RED;
+  else
+    psm.dc2->color=ROPF_DITHER+WHITE<<16+BLACK;
+  GrBorder(psm.dc2,PSM_TOOLS_X,PSM_TOOLS_Y,PSM_TOOLS_X+10,PSM_TOOLS_Y+10);
+
+  if (psm.tool==PSMTT_PTR_TOOL)
+    psm.dc2->color=RED;
+  else
+    psm.dc2->color=BLACK;
+  (*gr.fp_draw_ms)(psm.dc2,PSM_TOOLS_X+15,PSM_TOOLS_Y);
+  psm.dc2->color=BLACK;
+}
+
+Bool PsmGetPickToolBox(I64 xx,I64 yy)
+{
+  if (PSM_TOOLS_X<=xx<PSM_TOOLS_X+27 && PSM_TOOLS_Y<=yy<PSM_TOOLS_Y+15) {
+    PsmMarkSel(0,0,FALSE);
+    if (xx<PSM_TOOLS_X+13)
+      psm.tool=PSMTT_BOX_TOOL;
+    else
+      psm.tool=PSMTT_PTR_TOOL;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+#define PSM_METERS_NUM  7
+I64 meter_tops[PSM_METERS_NUM]  ={2,3,4,5,6,7,9},
+   meter_bottoms[PSM_METERS_NUM]={4,4,4,4,8,8,8};
+
+#define PSM_METER_X     485
+#define PSM_METER_Y     13*FONT_HEIGHT
+#define PSM_METER_W     12
+Bool PsmGetPickMeterBox(I64 xx,I64 yy,I64 *top,I64 *bottom)
+{
+  I64 i;
+  if (PSM_METER_X<=xx<PSM_METER_X+PSM_METER_W*PSM_METERS_NUM &&
+        PSM_METER_Y<=yy<PSM_METER_Y+2*FONT_HEIGHT) {
+    i=(xx-PSM_METER_X)/PSM_METER_W;
+    *top=meter_tops[i];
+    *bottom=meter_bottoms[i];
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 DrawPickMeterBox()
+{
+  I64 i;
+  psm.dc2->color=BLACK;
+  for (i=0;i<PSM_METERS_NUM;i++)
+    DrawTimeSignature(psm.dc2,PSM_METER_X+i*PSM_METER_W,PSM_METER_Y,
+          meter_tops[i],meter_bottoms[i]);
+}
+
+U0 DrawDC2()
+{
+  DCFill;
+  DrawPickNoteBox;
+  DrawPickMeterBox;
+  DrawPickTools;
+}
+
+
+<17>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+U0 PsmMenu(I64 psm_octave)
+{
+  DocClear;
+  "$BG,WHITE$$FD,GREEN$$CM,0,12$\n";
+  Sprite(<17>);
+  '\n\n\n\n\n';
+
+  DrawDC2;
+
+  "$LTGREEN$<SPACE>$FG$\t\tRest\n"
+        "$LTGREEN$<BACKSPACE>$FG$\tDeletes Last Note\n"
+        "$LTGREEN$Left Mouse$FG$\tDrag note or shift word\n"
+        "$LTGREEN$Right Mouse$FG$\tChange duration or set word\n";
+  Sprite(<6>,"$SP+LIS,\"\","
+        "LM=\"Msg(MSG_KEY_DOWN,0,SCF_CTRL|SC_CURSOR_LEFT);\",BI=%d$");
+  "   ";
+  if (psm.playing)
+    Sprite(<9>,"$SP,\"\",LM=\"x\",BI=%d$");
+  else
+    Sprite(<8>,"$SP,\"\",LM=\"x\",BI=%d$");
+  "   ";
+  if (psm.record_entry->checked) {
+    psm.record_entry->checked=TRUE;
+    Sprite(<10>,"$SP,\"\",LM=\"z\",BI=%d$");
+  } else
+    Sprite(<11>,"$SP,\"\",LM=\"z\",BI=%d$");
+  "   ";
+  Sprite(<7>,"$SP+LIS,\"\","
+        "LM=\"Msg(MSG_KEY_DOWN,0,SCF_CTRL|SC_CURSOR_RIGHT);\",BI=%d$");
+  "$CM+LX,0,6$";
+  PsmSetOctave(psm_octave);
+  Refresh(2);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/PsalmodyFile.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyFile.HC.HTML new file mode 100755 index 0000000..36f5d5e --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyFile.HC.HTML @@ -0,0 +1,458 @@ + + + + + + + + + + + +
+U0 PsmNoteDel(PsmNote *tmpn)
+{
+  Free(tmpn->word);
+  Free(tmpn);
+}
+
+PsmNote *PsmNoteCopy(PsmNote *tmpn)
+{
+  PsmNote *tmpn1=MAllocIdent(tmpn);
+  if (tmpn->word)
+    tmpn1->word=StrNew(tmpn->word);
+  else
+    tmpn1->word=NULL;
+  return tmpn1;
+}
+
+U0 PsmSongDel(PsmNote *head)
+{
+  PsmNote *tmpn,*tmpn1;
+  tmpn=head->next;
+  while (tmpn!=head) {
+    tmpn1=tmpn->next;
+    PsmNoteDel(tmpn);
+    tmpn=tmpn1;
+  }
+  QueInit(head);
+}
+
+U0 PsmCutToClip()
+{
+  PsmNote *tmpn,*tmpn1;
+  PsmSongDel(&psm.clip);
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    tmpn1=tmpn->next;
+    if (tmpn->flags&PSMF_SEL) {
+      if (psm.cur_note==tmpn)
+        psm.cur_note=tmpn->next;
+      QueRem(tmpn);
+      tmpn->flags&=~PSMF_SEL;
+      QueIns(tmpn,psm.clip.last);
+    }
+    tmpn=tmpn1;
+  }
+}
+
+U0 PsmPasteClip()
+{
+  PsmNote *tmpn,*tmpn1;
+  tmpn=psm.clip.next;
+  while (tmpn!=&psm.clip) {
+    tmpn1=PsmNoteCopy(tmpn);
+    QueIns(tmpn1,psm.cur_note->last);
+    tmpn=tmpn->next;
+  }
+}
+
+U0 PsmCopyToClip()
+{
+  PsmNote *tmpn,*tmpn1;
+  PsmSongDel(&psm.clip);
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    if (tmpn->flags&PSMF_SEL) {
+      tmpn->flags&=~PSMF_SEL;
+      tmpn1=PsmNoteCopy(tmpn);
+      QueIns(tmpn1,psm.clip.last);
+    }
+    tmpn=tmpn->next;
+  }
+}
+
+PsmNote *PsmFindNote(I64 x,I64)
+{
+  PsmNote *tmpn=psm.head.next;
+  PsmRecalcNoteXY;
+  x+=PSM_NOTE_SPACING/2;
+  while (x>tmpn->next->x && tmpn!=&psm.head)
+    tmpn=tmpn->next;
+  return tmpn;
+}
+
+U8 *PsmMusicSetOctave(U8 *st,I64 *psm_octave)
+{
+  while ('0'<=*st<='9')
+    *psm_octave=*st++ -'0';
+  return st;
+}
+
+U8 *PsmMusicSetNoteLen(U8 *st,F64 *psm_duration)
+{
+  Bool cont=TRUE;
+  do {
+    switch (*st++) {
+      case 'w': *psm_duration=4.0;  break;
+      case 'h': *psm_duration=2.0;  break;
+      case 'q': *psm_duration=1.0;  break;
+      case 'e': *psm_duration=0.5;  break;
+      case 's': *psm_duration=0.25; break;
+      case 't': *psm_duration=2.0* *psm_duration/3.0;   break;
+      case '.': *psm_duration=1.5* *psm_duration;       break;
+      default:
+        st--;
+        cont=FALSE;
+    }
+  } while (cont);
+  return st;
+}
+
+U0 PsmLoadSongStr(U8 *st,I64 *psm_octave,F64 *psm_duration)
+{
+  PsmNote *tmpn,*tmpn1;
+  I64 note,i=0;
+  while (*st) {
+    tmpn=CAlloc(sizeof(PsmNote));
+    while (*st && !('A'<=*st<='G') && *st!='R') {
+      if (*st=='M') {
+        tmpn1=CAlloc(sizeof(PsmNote));
+        tmpn1->type=PSMT_METER;
+        st++;
+        if ('1'<=*st<='9')
+          tmpn1->meter_top=*st++-'0';
+        else
+          tmpn1->meter_top=4;
+        if (*st=='/')
+          st++;
+        if ('1'<=*st<='9')
+          tmpn1->meter_bottom=*st++-'0';
+        else
+          tmpn1->meter_bottom=4;
+        PsmSetWidth(tmpn1);
+        QueIns(tmpn1,psm.head.last);
+      }
+      while (*st=='(') {
+        Bts(&tmpn->flags,PSMf_TIE);
+        st++;
+      }
+      st=PsmMusicSetOctave(st,psm_octave);
+      st=PsmMusicSetNoteLen(st,psm_duration);
+    }
+    if (!*st) {
+      PsmNoteDel(tmpn);
+      break;
+    }
+    note=*st++-'A';
+    if (note<7) {
+      note=music.note_map[note];
+      if (*st=='b') {
+        Bts(&tmpn->flags,PSMf_FLAT);
+        note--;
+        st++;
+        if (note<0) //Ab
+          note=11;
+        else if (note==2) //Cb
+          *psm_octave-=1;
+      } else if (*st=='#') {
+        Bts(&tmpn->flags,PSMf_SHARP);
+        note++;
+        st++;
+        if (note>11) //G#
+          note=0;
+        else if (note==3) //B#
+          *psm_octave+=1;
+      }
+      tmpn->ona=Note2Ona(note,*psm_octave);
+    } else
+      tmpn->ona=0;
+    if (*psm_duration<=2*.25/3)
+      i=0;
+    else if (*psm_duration<=.25)
+      i=1;
+    else if (*psm_duration<=2*.5/3)
+      i=2;
+    else if (*psm_duration<=.5)
+      i=3;
+    else if (*psm_duration<=2.0/3)
+      i=4;
+    else if (*psm_duration<=.5*1.5)
+      i=5;
+    else if (*psm_duration<=1.0)
+      i=6;
+    else if (*psm_duration<=1.5)
+      i=7;
+    else if (*psm_duration<=2.0)
+      i=8;
+    else if (*psm_duration<=3.0)
+      i=9;
+    else if (*psm_duration<=4.0)
+      i=10;
+    else
+      i=11;
+    tmpn->duration=i;
+    tmpn->type=PSMT_NOTE;
+    PsmSetWidth(tmpn);
+    QueIns(tmpn,psm.cur_note->last);
+  }
+}
+
+U0 PsmLoadSong(U8 *filename,I64 *psm_octave,F64 *psm_duration)
+{
+  U8 *st;
+  PsmNote *tmpn;
+  CCmpCtrl *cc=CmpCtrlNew(MStrPrint("#include \"%s\"",filename));
+  if (FileOcc("incomplete",filename,""))
+    psm.incomplete_entry->checked=TRUE;
+  else
+    psm.incomplete_entry->checked=FALSE;
+  while (Lex(cc)) {
+    if (cc->token==TK_IDENT)
+      if (!StrCmp(cc->cur_str,"Play")) {
+        if (Lex(cc)=='(')
+          if (Lex(cc)==TK_STR) {
+            tmpn=psm.head.last;
+            st=LexExtStr(cc);
+            PsmLoadSongStr(st,psm_octave,psm_duration);
+            if (cc->token==',') {
+              if (Lex(cc)==TK_STR) {
+                st=LexExtStr(cc);
+                do {
+                  do tmpn=tmpn->next;
+                  while (tmpn!=&psm.head && tmpn->type==PSMT_METER);
+                  if (tmpn!=&psm.head)
+                    tmpn->word=StrNew(st);
+                  st+=StrLen(st)+1;
+                } while (*st);
+              }
+            }
+          }
+      } else if (!StrCmp(cc->cur_str,"music") &&
+            Lex(cc)=='.' && Lex(cc)==TK_IDENT) {
+        if (!StrCmp(cc->cur_str,"tempo")) {
+          if (Lex(cc)=='=' && Lex(cc)==TK_F64) {
+            music.tempo=cc->cur_f64-0.0005;
+            tempo_state.tempo=Round(TEMPO_RANGE*(music.tempo-0.5)/4.4);
+          }
+        } else if (!StrCmp(cc->cur_str,"stacatto_factor")) {
+          if (Lex(cc)=='=' && Lex(cc)==TK_F64) {
+            music.stacatto_factor=cc->cur_f64-0.0005;
+            tempo_state.stacatto=
+                  Round(TEMPO_RANGE*(music.stacatto_factor-0.12)/0.88);
+          }
+        }
+      }
+  }
+  CmpCtrlDel(cc);
+}
+
+U8 *PsmCvtSong()
+{
+  PsmNote *tmpn;
+  U8 *st,*src,*dst;
+  I64 i,ona,note,octave,last_octave,last_duration;
+
+  i=0;
+  tmpn=psm.head.next;
+  last_octave=I64_MIN;
+  last_duration=-1;
+  while (tmpn!=&psm.head) {
+    dst=&tmpn->ascii;
+    if (tmpn->type==PSMT_METER) {
+      *dst++='M';
+      *dst++=tmpn->meter_top+'0';
+      *dst++='/';
+      *dst++=tmpn->meter_bottom+'0';
+    } else {
+      if (tmpn->ona) {
+        ona=tmpn->ona;
+        if (Bt(&tmpn->flags,PSMf_SHARP))
+          ona--;
+        if (Bt(&tmpn->flags,PSMf_FLAT))
+          ona++;
+        octave=Ona2Octave(ona);
+        note  =Ona2Note  (ona);
+        note=music.note_map[*LstSub(note,psm_note_lst)-'A'];
+      }
+      if (Bt(&tmpn->flags,PSMf_TIE))
+        *dst++='(';
+      if (octave!=last_octave && tmpn->ona) {
+        *dst++=octave+'0';
+        last_octave=octave;
+      }
+      if (tmpn->duration!=last_duration) {
+        src=LstSub(tmpn->duration,psm_duration_lst);
+        *dst++=src[0];
+        if (src[1])
+          *dst++=src[1];
+        last_duration=tmpn->duration;
+      }
+      if (tmpn->ona) {
+        src=LstSub(note,psm_note_lst);
+        *dst++=src[0];
+        if (src[1])
+          *dst++=src[1];
+        else if (Bt(&tmpn->flags,PSMf_FLAT))
+          *dst++='b';
+        else if (Bt(&tmpn->flags,PSMf_SHARP))
+          *dst++='#';
+      } else
+        *dst++='R';
+    }
+    *dst++=0;
+    i+=StrLen(tmpn->ascii);
+    tmpn=tmpn->next;
+  }
+
+  st=MAlloc(i+1);
+  dst=st;
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    StrCpy(dst,tmpn->ascii);
+    dst+=StrLen(tmpn->ascii);
+    tmpn=tmpn->next;
+  }
+  *dst++=0;
+  return st;
+}
+
+U8 *PsmSaveSong(U8 *dirname,U8 *full_filename)
+{
+  CDoc *doc=DocNew(full_filename);
+  Bool has_words;
+  PsmNote *tmpn,*tmpn1;
+  F64 measure_len=4,two_measure_left=2*measure_len;
+  I64 ch;
+  U8 *ptr;
+
+  Free(PsmCvtSong); //set tmpn->ascii;
+
+  music.tempo=4.4*tempo_state.tempo/TEMPO_RANGE+0.5;
+  music.stacatto_factor=0.88*tempo_state.stacatto/TEMPO_RANGE+0.12;
+
+  has_words=FALSE;
+  tmpn=psm.head.next;
+  while (tmpn!=&psm.head) {
+    if (PsmHasWords(tmpn->word)) has_words=TRUE;
+    tmpn=tmpn->next;
+  }
+  if (psm.incomplete_entry->checked)
+    DocPrint(doc,"//0 incomplete\n");
+  else if (has_words)
+    DocPrint(doc,"//0 has words\n");
+  else
+    DocPrint(doc,"//0 no nothing\n");
+
+  DocPrint(doc,
+        "U0 Song()\n"
+        "{\n"
+        "  Fs->task_end_cb=&SndTaskEndCB;\n"
+        "  MusicSettingsRst;\n"
+        "  music.tempo=%6.3f;\n"
+        "  music.stacatto_factor=%6.3f;\n"
+        "  try {\n"
+        "    while (!ScanKey) {\n"
+        "\tPlay(\"",music.tempo+0.0005,music.stacatto_factor+0.0005);
+
+  tmpn=psm.head.next;
+  tmpn1=tmpn;
+  has_words=FALSE;
+  while (tmpn!=&psm.head) {
+    DocPrint(doc,"%s",tmpn->ascii);
+    if (PsmHasWords(tmpn->word)) has_words=TRUE;
+    if (tmpn->type==PSMT_METER) {
+      measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
+      two_measure_left=0;
+    } else
+      two_measure_left-=psm_durations[tmpn->duration];
+    tmpn=tmpn->next;
+    if (two_measure_left<0.001 && tmpn!=&psm.head) {
+      if (has_words) {
+        DocPrint(doc,"\",\n\t\t\"");
+        while (tmpn1!=tmpn) {
+          if (tmpn1->type!=PSMT_METER) {
+            if (ptr=tmpn1->word) {
+              while (ch=*ptr) {
+                if (ch==CH_SPACE)
+                  *ptr=CH_SHIFT_SPACE;
+                ptr++;
+              }
+              DocPrint(doc,"%Q\\0",tmpn1->word);
+            } else
+              DocPrint(doc,"%c\\0",CH_SHIFT_SPACE);
+          }
+          tmpn1=tmpn1->next;
+        }
+      }
+      DocPrint(doc,"\");\n"
+            "\tPlay(\"");
+      two_measure_left=2*measure_len;
+      tmpn1=tmpn;
+      has_words=FALSE;
+    }
+  }
+  if (has_words) {
+    DocPrint(doc,"\",\n\t\t\"");
+    while (tmpn1!=tmpn) {
+      if (tmpn1->type!=PSMT_METER) {
+        if (ptr=tmpn1->word) {
+          while (ch=*ptr) {
+            if (ch==CH_SPACE)
+              *ptr=CH_SHIFT_SPACE;
+            ptr++;
+          }
+          DocPrint(doc,"%Q\\0",tmpn1->word);
+        } else
+          DocPrint(doc,"%c\\0",CH_SHIFT_SPACE);
+      }
+      tmpn1=tmpn1->next;
+    }
+  }
+  DocPrint(doc,"\");\n"
+        "    }\n"
+        "  } catch\n"
+        "    PutExcept;\n"
+        "  Snd;\n"
+        "}\n"
+        "\n"
+        "Song;\n");
+  DocRecalc(doc);
+  if (full_filename)
+    Free(full_filename);
+  else
+    StrPrint(doc->filename.name,"%s/Tmp.HC.Z",dirname);
+  DocWrite(doc,TRUE);
+  full_filename=StrNew(doc->filename.name);
+  DocDel(doc);
+  return full_filename;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/PsalmodyMain.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyMain.HC.HTML new file mode 100755 index 0000000..f17184f --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/PsalmodyMain.HC.HTML @@ -0,0 +1,829 @@ + + + + + + + + + + + +
+#define PSMR_FLAT               -8
+#define PSMR_SHARP              -7
+#define PSMR_TIE                -6
+#define PSMR_REST               -5
+#define PSMR_INS_NOTE           -4
+#define PSMR_DELETE_NOTE        -3
+#define PSMR_SET_WORD           -2
+
+F64 PopUpDuration()
+{
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$GREEN$$MU,\"Set Word\",LE=PSMR_SET_WORD$\n"
+        "$MU,\"Toggle Sharp\",LE=PSMR_SHARP$\n"
+        "$MU,\"Toggle Flat\",LE=PSMR_FLAT$\n"
+        "$MU,\"Toggle Tie\",LE=PSMR_TIE$\n"
+        "$MU,\"Make Rest\",LE=PSMR_REST$\n"
+        "$MU,\"Insert Note\",LE=PSMR_INS_NOTE$\n"
+        "$MU,\"Delete Note\",LE=PSMR_DELETE_NOTE$\n\n");
+  for (i=0;i<PSM_DURATIONS_NUM;i++)
+    DocPrint(doc,"$MU,\"%7.5f\",LE=%d$\n",psm_durations[i],i);
+  DocPrint(doc,"\n$MU,\"CANCEL\",LE=DOCM_CANCEL$\n");
+  i=PopUpMenu(doc);
+  DocDel(doc);
+  return i;
+}
+
+U0 PsmRightClick(I64 x,I64 y)
+{
+  U8 *st,*st2;
+  PsmNote *tmpn,*tmpn1;
+  I64 i,old_doc_flags;
+  if (DocPut) old_doc_flags=DocPut->flags;
+  psm.cur_note=tmpn=PsmFindNote(x,y);
+  if (tmpn!=&psm.head) {
+    Fs->win_inhibit=WIG_USER_TASK_DFT;
+    i=PopUpDuration;
+    if (0<=i<PSM_DURATIONS_NUM) {
+      if (tmpn->type==PSMT_NOTE)
+        tmpn->duration=i;
+    } else {
+      switch (i) {
+        case PSMR_REST:
+          if (tmpn->type==PSMT_NOTE)
+            tmpn->ona=0;
+          break;
+        case PSMR_SHARP:
+          if (tmpn->type==PSMT_NOTE && tmpn->ona) {
+            if (Btr(&tmpn->flags,PSMf_FLAT))
+              tmpn->ona++;
+            if (Btc(&tmpn->flags,PSMf_SHARP))
+              tmpn->ona--;
+            else
+              tmpn->ona++;
+          }
+          break;
+        case PSMR_FLAT:
+          if (tmpn->type==PSMT_NOTE && tmpn->ona) {
+            if (Btr(&tmpn->flags,PSMf_SHARP))
+              tmpn->ona--;
+            if (Btc(&tmpn->flags,PSMf_FLAT))
+              tmpn->ona++;
+            else
+              tmpn->ona--;
+          }
+          break;
+        case PSMR_TIE:
+          if (tmpn->type==PSMT_NOTE)
+            Btc(&tmpn->flags,PSMf_TIE);
+          break;
+        case PSMR_SET_WORD:
+          if (tmpn->type==PSMT_NOTE) {
+            if (DocPut) DocPut->flags&=~DOCF_FORM;
+            if (PsmHasWords(tmpn->word))
+              st2=MStrPrint("\nWord(\"%Q\"):",tmpn->word);
+            else
+              st2=MStrPrint("\nWord(\"\"):");
+            DocBottom;
+            st=GetStr(st2);
+            Free(st2);
+            Free(tmpn->word);
+            if (*st) {
+              tmpn->word=MStrPrint("%q",st);
+              Free(st);
+            } else
+              tmpn->word=StrNew(" ");
+            if (DocPut) DocPut->flags=DocPut->flags&
+                    ~DOCF_FORM|old_doc_flags&DOCF_FORM;
+          }
+          break;
+        case PSMR_INS_NOTE:
+          tmpn1=PsmNoteCopy(tmpn);
+          QueIns(tmpn1,tmpn);
+          break;
+        case PSMR_DELETE_NOTE:
+          psm.cur_note=tmpn->next;
+          QueRem(tmpn);
+          PsmNoteDel(tmpn);
+          break;
+      }
+    }
+    PsmSetWidth(psm.cur_note);
+    Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+          -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  }
+}
+
+U0 PsmLeftClickPickNoteBox(I64 duration)
+{
+  I64 o,n,msg_code,arg1,arg2;
+  PsmNote *tmpn,*tmpn1;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+    if (msg_code==MSG_MS_MOVE) {
+      DrawDC2;
+      DrawNote(psm.dc2,arg1,arg2,duration);
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  if (arg2<13*FONT_HEIGHT) {
+    if (arg1>psm.head.last->x)
+      tmpn1=psm.head.last;
+    else if (arg1<psm.head.next->x)
+      tmpn1=&psm.head;
+    else
+      tmpn1=PsmFindNote(arg1-PSM_NOTE_SPACING/2,arg2);
+    tmpn=CAlloc(sizeof(PsmNote));
+    tmpn->type=PSMT_NOTE;
+    arg2=arg2/4-15;
+    n=arg2%7;
+    o=4+arg2/-7;
+    if (n<0) {
+      n+=7;
+      o++;
+    }
+    n=psm_note_inverse_map[n];
+    if (n<3)
+      o--;
+    tmpn->ona=Note2Ona(n,o);
+    tmpn->duration=duration;
+    PsmSetWidth(tmpn);
+    QueIns(tmpn,tmpn1);
+    psm.cur_note=tmpn->next;
+  }
+  DrawDC2;
+}
+
+U0 PsmLeftClickPickMeterBox(I64 top,I64 bottom)
+{
+  I64 msg_code,arg1,arg2;
+  PsmNote *tmpn,*tmpn1;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+    if (msg_code==MSG_MS_MOVE) {
+      DrawDC2;
+      DrawTimeSignature(psm.dc2,arg1,arg2,top,bottom);
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  if (arg2<13*FONT_HEIGHT) {
+    if (arg1>=psm.head.x)
+      tmpn1=psm.head.last;
+    else if (arg1<psm.head.next->x)
+      tmpn1=&psm.head;
+    else
+      tmpn1=PsmFindNote(arg1-PSM_NOTE_SPACING/2,arg2);
+    tmpn=CAlloc(sizeof(PsmNote));
+    tmpn->type=PSMT_METER;
+    tmpn->meter_top=top;
+    tmpn->meter_bottom=bottom;
+    PsmSetWidth(tmpn);
+    QueIns(tmpn,tmpn1);
+    psm.cur_note=tmpn->next;
+  }
+  DrawDC2;
+}
+
+U0 PsmLeftClickStaffPtr(I64 x,I64 y)
+{
+  PsmNote *tmpn,*tmpn1;
+  I64 o,n,msg_code,arg1,arg2,n_original,o_original;
+  psm.cur_note=tmpn=PsmFindNote(x,y);
+  if (tmpn!=&psm.head) {
+    if (tmpn->type==PSMT_NOTE) {
+      o_original=Ona2Octave(tmpn->ona);
+      n_original=Ona2Note  (tmpn->ona);
+      do {
+        msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+        if (msg_code==MSG_MS_L_UP) {
+          tmpn1=PsmFindNote(arg1,arg2);
+          if (tmpn1==&psm.head || tmpn1==tmpn)
+            goto move_note;
+          else {
+            Free(tmpn1->word);
+            tmpn1->word=tmpn->word;
+            tmpn->word=NULL;
+            tmpn->ona=Note2Ona(n_original,o_original);
+          }
+        } else {
+move_note:
+          arg2=arg2/4-15;
+          n=arg2%7;
+          o=4+arg2/-7;
+          if (n<0) {
+            n+=7;
+            o++;
+          }
+          n=psm_note_inverse_map[n];
+          if (n<3)
+            o--;
+          tmpn->ona=Note2Ona(n,o);
+        }
+      } while (msg_code!=MSG_MS_L_UP);
+      PsmSetWidth(tmpn);
+    }
+  }
+}
+
+U0 PsmLeftClickStaffBox(I64 x,I64 y)
+{
+  I64 msg_code,arg1,arg2;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP|1<<MSG_MS_MOVE);
+    DrawDC2;
+    psm.dc2->color=ROPF_DITHER+WHITE<<16+BLACK;
+    GrBorder(psm.dc2,x,y,arg1,arg2);
+    if (msg_code==MSG_MS_L_UP) {
+      if (x>arg1) SwapI64(&x,&arg1);
+      PsmMarkSel(x,arg1,TRUE);
+    }
+  } while (msg_code!=MSG_MS_L_UP);
+  DrawDC2;
+}
+
+U0 PsmLeftClick(I64 x,I64 y)
+{
+  I64 duration,top,bottom;
+  if (y<13*FONT_HEIGHT) {
+    if (psm.tool==PSMTT_PTR_TOOL)
+      PsmLeftClickStaffPtr(x,y);
+    else
+      PsmLeftClickStaffBox(x,y);
+  } else {
+    duration=PsmGetPickNoteBoxDuration(x,y);
+    if (0<=duration<PSM_DURATIONS_NUM)
+      PsmLeftClickPickNoteBox(duration);
+    else if (PsmGetPickMeterBox(x,y,&top,&bottom))
+      PsmLeftClickPickMeterBox(top,bottom);
+    else if (PsmGetPickToolBox(x,y))
+      DrawDC2;
+  }
+}
+
+U8 PsmCvtDuration(F64 d)
+{
+  F64 d1,d2;
+  I64 j;
+  for (j=0;j<PSM_DURATIONS_NUM;j++) {
+    d1=psm_durations[j];
+    d2=psm_durations[j+1];
+    if (d<d1*d2/(d1+d2))
+      return j;
+  }
+  return 0;
+}
+
+#define PSM_KEYS_NUM    20
+class PsmKey
+{
+  U8 x,w,h,ascii;
+};
+
+#define PSM_W_W 16
+#define PSM_W_H 36
+#define PSM_B_W 8
+#define PSM_B_H 20
+
+PsmKey psm_kbd[PSM_KEYS_NUM]={
+  { 2*PSM_W_W-4,PSM_B_W,PSM_B_H,'e' },
+  { 3*PSM_W_W-4,PSM_B_W,PSM_B_H,'r' },
+  { 4*PSM_W_W-4,PSM_B_W,PSM_B_H,'t' },
+  { 6*PSM_W_W-4,PSM_B_W,PSM_B_H,'u' },
+  { 7*PSM_W_W-4,PSM_B_W,PSM_B_H,'i' },
+  { 9*PSM_W_W-4,PSM_B_W,PSM_B_H,'p' },
+  {10*PSM_W_W-4,PSM_B_W,PSM_B_H,'[' },
+  {11*PSM_W_W-4,PSM_B_W,PSM_B_H,']' },
+
+  { 0*PSM_W_W,PSM_W_W,PSM_W_H,'a' },
+  { 1*PSM_W_W,PSM_W_W,PSM_W_H,'s' },
+  { 2*PSM_W_W,PSM_W_W,PSM_W_H,'d' },
+  { 3*PSM_W_W,PSM_W_W,PSM_W_H,'f' },
+  { 4*PSM_W_W,PSM_W_W,PSM_W_H,'g' },
+  { 5*PSM_W_W,PSM_W_W,PSM_W_H,'h' },
+  { 6*PSM_W_W,PSM_W_W,PSM_W_H,'j' },
+  { 7*PSM_W_W,PSM_W_W,PSM_W_H,'k' },
+  { 8*PSM_W_W,PSM_W_W,PSM_W_H,'l' },
+  { 9*PSM_W_W,PSM_W_W,PSM_W_H,';' },
+  {10*PSM_W_W,PSM_W_W,PSM_W_H,'\'' },
+  {11*PSM_W_W,PSM_W_W,PSM_W_H,'\n'},
+};
+
+U0 PsmDownKey(I64 x,I64 y)
+{
+  I64 i;
+  PsmKey *o;
+  y-=FONT_HEIGHT*13;
+  if (0<=y<PSM_W_H) {
+    x-=16;
+    for (i=0;i<PSM_KEYS_NUM;i++) {
+      o=&psm_kbd[i];
+      if (o->x<=x<o->x+o->w && y<o->h) {
+        Msg(MSG_KEY_DOWN,o->ascii,0);
+        return;
+      }
+    }
+  }
+}
+
+U0 PsmUpKey(I64 x,I64 y)
+{
+  I64 i;
+  PsmKey *o;
+  y-=FONT_HEIGHT*13;
+  if (0<=y<PSM_W_H) {
+    x-=16;
+    for (i=0;i<PSM_KEYS_NUM;i++) {
+      o=&psm_kbd[i];
+      if (o->x<=x<o->x+o->w && y<o->h) {
+        Msg(MSG_KEY_UP,o->ascii,0);
+        return;
+      }
+    }
+  }
+}
+
+U0 PsmPushMode(I64 psm_octave)
+{
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  PsmMenu(psm_octave);
+}
+
+U0 PsmPopMode()
+{
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  DCFill;
+}
+
+#define PSMF_CD         1
+#define PSMF_INCOMPLETE 2
+
+U0 Psalmody(U8 *dirname="~/Psalmody")
+{
+  Bool was_playing,is_null=TRUE,was_null=TRUE;
+  I64 arg1,arg2,msg_code=0,col,ona=0,last_ona=0,
+        psm_octave=4,timeout_val,timeout_val2,old_doc_flags;
+  U8 *filename=NULL,*st,*st2;
+  PsmNote *tmpn;
+  F64 psm_duration=1.0,d,evt_time=tS,note_down_time=tS;
+  CCtrl *c=TempoNew;
+
+  if (DocPut) old_doc_flags=DocPut->flags;
+  SettingsPush; //See SettingsPush
+
+  MusicSettingsRst;
+  tempo_state.tempo=Round(TEMPO_RANGE*(music.tempo-0.5)/4.4);
+  tempo_state.stacatto=Round(TEMPO_RANGE*(music.stacatto_factor-0.12)/0.88);
+
+  if (DocPut) DocPut->flags|=DOCF_FORM;
+
+  MemSet(&psm,0,sizeof(PsmCtrl));
+  psm.scrn_x=0;
+  psm.head.next=psm.head.last=&psm.head;
+  psm.clip.next=psm.clip.last=&psm.clip;
+  psm.cur_note=&psm.head;
+  psm.dc2=DCAlias;
+
+  MenuPush(
+        "File {"
+        "  New(,'.');"
+        "  ChgDir(MSG_CMD,PSMF_CD);"
+        "  Open(,CH_CTRLO);"
+        "  SaveAs(,CH_CTRLA);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  Cut(,CH_CTRLX);"
+        "  Copy(,CH_CTRLC);"
+        "  Paste(,CH_CTRLV);"
+        "  RightMenu(,'\n');"
+        "  BackSpace(,CH_BACKSPACE);"
+        "  DeleteNote(,,SC_DELETE);"
+        "  ClearSong(,'.');"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  GoBegin(,,0x4CB0000044B);"
+        "  GoEnd(,,0x4CD0000044D);"
+        "}"
+        "Song {"
+        "  Play(,'x');"
+        "  Record(,'z');"
+        "  Random(,',');"
+        "  MarkIncomplete(MSG_CMD,PSMF_INCOMPLETE);"
+        "}"
+        "Snd {"
+        "  Octave1(,'1');"
+        "  Octave2(,'2');"
+        "  Octave3(,'3');"
+        "  Octave4(,'4');"
+        "  Octave5(,'5');"
+        "  Octave6(,'6');"
+        "  Octave7(,'7');"
+        "}"
+        "Help {"
+        "  Help(,,SC_F1);"
+        "}"
+        );
+  psm.incomplete_entry=MenuEntryFind(Fs->cur_menu,"Song/MarkIncomplete");
+  psm.record_entry=MenuEntryFind(Fs->cur_menu,"Song/Record");
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+
+  dirname=StrNew(dirname);
+  PsmPushMode(psm_octave);
+  col=0;
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      was_playing=FALSE;
+mo_start:
+      if (ms.pos_text.y-Fs->win_top<18)
+        msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP|
+              1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_UP|
+              1<<MSG_MS_MOVE|1<<MSG_CMD);
+      else
+        msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP|
+              1<<MSG_MS_MOVE|1<<MSG_CMD);
+mo_got_msg:
+      if (msg_code==MSG_KEY_DOWN && arg1==CH_SPACE && !arg2) {
+//The Window Mgr sets the Doc cur_entry to a bttn
+        //and generates a <SPACE> when the Doc Bttns are clicked.
+        //This is so that kbd and mouse are the same for Doc's.
+        //We must now pass the <SPACE> onto the Doc hndlr.
+        PutKey(arg1,arg2);
+        goto mo_start;
+      }
+      if (msg_code!=MSG_MS_MOVE) {
+        DocBottom;
+        if (was_playing || DocPut->cur_entry->y>=Fs->win_height-2) {
+          PsmMenu(psm_octave);
+          col=0;
+        }
+      }
+
+      ona=Note2Ona(3,psm_octave+1); //C
+      is_null=TRUE;
+      switch (msg_code) {
+        case MSG_CMD:
+          PsmPopMode;
+          switch (arg1) {
+            case PSMF_CD:
+              st2=dirname;
+              if (dirname=PopUpPickDir) {
+                Free(st2);
+                Free(filename);
+                filename=NULL;
+              } else
+                dirname=st2;
+              break;
+            case PSMF_INCOMPLETE:
+              psm.incomplete_entry->checked=!psm.incomplete_entry->checked;
+              break;
+          }
+          PsmPushMode(psm_octave);
+          col=0;
+          break;
+        case MSG_KEY_DOWN:
+          evt_time=tS;
+          if ('0'<=arg1<='9') {
+            psm_octave=arg1-'0';
+            PsmMenu(psm_octave);
+            col=0;
+          } else {
+            switch (arg1) {
+              start:
+                case 'a':       ona-=8;         break;
+                case 's':       ona-=7;         break;
+                case 'e':       ona-=6;         break;
+                case 'd':       ona-=5;         break;
+                case 'r':       ona-=4;         break;
+                case 'f':       ona-=3;         break;
+                case 't':       ona-=2;         break;
+                case 'g':       ona--;          break;
+                case 'h':                       break;
+                case 'u':       ona++;          break;
+                case 'j':       ona+=2;         break;
+                case 'i':       ona+=3;         break;
+                case 'k':       ona+=4;         break;
+                case 'l':       ona+=5;         break;
+                case 'p':       ona+=6;         break;
+                case ';':       ona+=7;         break;
+                case '[':       ona+=8;         break;
+                case '\'':      ona+=9;         break;
+                case ']':       ona+=10;        break;
+                case CH_SPACE:  ona=0;          break;
+              end:
+                is_null=FALSE;
+                break;
+
+              case 0:
+                switch (arg2.u8[0]) {
+                  case SC_CURSOR_LEFT:
+                    if (arg2&SCF_CTRL) {
+                      while (psm.cur_note->last!=&psm.head) {
+                        psm.cur_note=psm.cur_note->last;
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                      }
+                    } else {
+                      if (psm.cur_note->last!=&psm.head) {
+                        psm.cur_note=psm.cur_note->last;
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                      }
+                    }
+                    break;
+                  case SC_CURSOR_RIGHT:
+                    if (arg2&SCF_CTRL) {
+                      while (psm.cur_note!=&psm.head) {
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                        psm.cur_note=psm.cur_note->next;
+                      }
+                    } else {
+                      if (psm.cur_note!=&psm.head) {
+                        if (psm.cur_note!=&psm.head)
+                          LBEqu(&psm.cur_note->flags,PSMf_SEL,arg2&SCF_SHIFT);
+                        psm.cur_note=psm.cur_note->next;
+                      }
+                    }
+                    break;
+                  case SC_DELETE:
+                    if (arg2&SCF_SHIFT)
+                      PsmCutToClip;
+                    else {
+                      tmpn=psm.cur_note;
+                      psm.cur_note=tmpn->next;
+                      if (tmpn!=&psm.head) {
+                        QueRem(tmpn);
+                        PsmNoteDel(tmpn);
+                      }
+                    }
+                    break;
+                  case SC_INS:
+                    if (arg2&SCF_SHIFT)
+                      PsmPasteClip;
+                    else if (arg2&SCF_CTRL)
+                      PsmCopyToClip;
+                    break;
+                  case SC_F1:
+                    PsmPopMode;
+                    PopUpEd("::/Apps/Psalmody/Help.DD.Z",Fs);
+                    PsmPushMode(psm_octave);
+                    col=0;
+                    break;
+                }
+                break;
+              case ',':
+                Free(filename);
+                filename=NULL;
+                PsmPopMode;
+                music.octave=psm_octave;
+                if (st2=GodSongStr) {
+                  PsmLoadSongStr(st2,&psm_octave,&psm_duration);
+                  Free(st2);
+                }
+                PsmPushMode(psm_octave);
+                col=0;
+                break;
+              case CH_CTRLO:
+                PsmPopMode;
+                RegOneTimePopUp(ARf_PSALMODY_JUKEBOX,
+                      "Sel a song and preview it.\n"
+                      "$GREEN$<SHIFT-ESC>$FG$ to load it into Psalmody.\n\n"
+                      ST_WARN_ST " Graphics and other embelishments\n"
+                      "will be lost because Psalmody can't\n"
+                      "parse HolyC programs completely.\n");
+                Free(filename);
+                filename=NULL;
+                JukeBox(dirname,&filename);
+                if (filename) {
+                  psm.scrn_x=0;
+                  psm_duration=1.0;
+                  psm_octave=4;
+                  PsmSongDel(&psm.head);
+                  psm.cur_note=&psm.head;
+                  PsmLoadSong(filename,&psm_octave,&psm_duration);
+                  psm.record_entry->checked=FALSE;
+                  psm.cur_note=psm.head.next;
+                }
+                PsmPushMode(psm_octave);
+                col=0;
+                break;
+              case CH_CTRLA:
+                PsmPopMode;
+                filename=PsmSaveSong(dirname,filename);
+                PsmPushMode(psm_octave);
+                break;
+              case CH_CTRLC:
+                PsmCopyToClip;
+                break;
+              case CH_CTRLV:
+                PsmPasteClip;
+                break;
+              case CH_CTRLX:
+                PsmCutToClip;
+                break;
+              case '.':
+                PsmMenu(psm_octave);
+                col=0;
+                Free(filename);
+                filename=NULL;
+                psm_duration=1.0;
+                psm_octave=4;
+                PsmSongDel(&psm.head);
+                psm.cur_note=&psm.head;
+                psm.scrn_x=0;
+                break;
+              case '\n':
+                if (psm.cur_note!=&psm.head)
+                  PsmRightClick(psm.cur_note->x,psm.cur_note->y);
+                break;
+              case 'x':
+                if (was_playing)
+                  break;
+                col=0;
+                psm.playing=TRUE;
+                PsmMenu(psm_octave);
+                tmpn=psm.cur_note;
+                while (tmpn!=&psm.head) {
+                  if (tmpn->type!=PSMT_METER) {
+                    timeout_val=cnts.jiffies;
+                    if (ms.pos_text.y-Fs->win_top<18)
+                      msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|
+                            1<<MSG_MS_L_DOWN|1<<MSG_MS_R_UP|1<<MSG_CMD);
+                    else
+                      msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|
+                            1<<MSG_MS_L_DOWN|1<<MSG_CMD);
+                    if (msg_code) {
+                      Snd;
+                      psm.playing=FALSE;
+                      was_playing=TRUE;
+                      if (ms.pos_text.y-Fs->win_top>=18 &&
+                            msg_code==MSG_MS_L_DOWN)
+                        goto mo_start;
+                      else
+                        goto mo_got_msg;
+                    }
+                    psm.cur_note=tmpn;
+                    psm.scrn_x+=tmpn->x-0.33*GR_WIDTH;
+                    if (PsmHasWords(tmpn->word))
+                      "%s",tmpn->word;
+                    Snd(tmpn->ona);
+
+                    music.tempo=4.4*tempo_state.tempo/TEMPO_RANGE+0.5;
+                    music.stacatto_factor=
+                          0.88*tempo_state.stacatto/TEMPO_RANGE+0.12;
+                    d=JIFFY_FREQ*psm_durations[tmpn->duration]/music.tempo;
+                    if (Bt(&tmpn->flags,PSMf_TIE)) {
+                      timeout_val+=d;
+                      timeout_val2=timeout_val;
+                    } else {
+                      timeout_val+=d*music.stacatto_factor;
+                      timeout_val2=timeout_val+
+                            d*(1.0-music.stacatto_factor);
+                    }
+                    SleepUntil(timeout_val);
+                    Snd;
+                    SleepUntil(timeout_val2);
+                  }
+                  tmpn=tmpn->next;
+                }
+                psm.cur_note=&psm.head;
+                psm.scrn_x+=psm.cur_note->x-GR_WIDTH/2;
+                psm.playing=FALSE;
+                PsmMenu(psm_octave);
+                col=0;
+                Snd;
+                break;
+              case CH_BACKSPACE:
+                tmpn=psm.cur_note->last;
+                if (tmpn!=&psm.head) {
+                  QueRem(tmpn);
+                  PsmNoteDel(tmpn);
+                }
+                if (col) {
+                  '' CH_BACKSPACE;
+                  col--;
+                }
+                break;
+              case 'z':
+                if (psm.record_entry->checked)
+                  psm.record_entry->checked=FALSE;
+                else {
+                  psm.record_entry->checked=TRUE;
+                  psm_duration=1.0;
+                  psm_octave=4;
+                  psm.scrn_x=0;
+                }
+                PsmMenu(psm_octave);
+                col=0;
+                break;
+              case CH_ESC:
+                PsmPopMode;
+                filename=PsmSaveSong(dirname,filename);
+                PsmPushMode(psm_octave);
+              case CH_SHIFT_ESC:
+                goto mo_done;
+            }
+          }
+          break;
+        case MSG_KEY_UP:
+          evt_time=tS;
+          break;
+        case MSG_MS_MOVE:
+          if (arg2>18*FONT_HEIGHT)
+            Fs->win_inhibit=WIG_USER_TASK_DFT;
+          else
+            Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER
+                  -WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+          break;
+        case MSG_MS_L_DOWN:
+          PsmDownKey(arg1,arg2);
+          PsmLeftClick(arg1,arg2);
+          break;
+        case MSG_MS_L_UP:
+          PsmUpKey(arg1,arg2);
+          break;
+        default:
+          PsmRightClick(arg1,arg2);
+      }
+      if (is_null)
+        ona=0;
+      if (ona!=last_ona || is_null!=was_null) {
+        if (!ona) {
+          if (is_null)
+            st="";
+          else
+            st="R";
+        } else
+          st=LstSub(Ona2Note(ona),psm_note_lst);
+        Snd(ona);
+        if (psm.record_entry->checked) {
+          if (!was_null) {
+            music.tempo=4.4*tempo_state.tempo/TEMPO_RANGE+0.5;
+            music.stacatto_factor=0.88*tempo_state.stacatto/TEMPO_RANGE+0.12;
+            tmpn->duration=PsmCvtDuration(
+                  music.tempo*(evt_time-note_down_time));
+            PsmSetWidth(tmpn);
+            QueIns(tmpn,psm.cur_note->last);
+          }
+          if (!is_null) {
+            note_down_time=tS;
+            tmpn=CAlloc(sizeof(PsmNote));
+            tmpn->type=PSMT_NOTE;
+            tmpn->ona=ona;
+            if (st[1]=='#')
+              Bts(&tmpn->flags,PSMf_SHARP);
+          }
+        }
+        last_ona=ona;
+        was_null=is_null;
+        "%s",st;
+        col+=StrLen(st);
+        if (col>=Fs->win_width-1) {
+          '\n';
+          col=0;
+        }
+      }
+    }
+mo_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  PsmPopMode;
+  PsmSongDel(&psm.head);
+  PsmSongDel(&psm.clip);
+  TempoDel(c);
+  DCFill;
+  DCDel(psm.dc2);
+  DocClear;
+  SettingsPop;
+  if (DocPut) DocPut->flags=DocPut->flags&~DOCF_FORM|old_doc_flags&DOCF_FORM;
+  Free(dirname);
+  MenuPop;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Psalmody/Run.HC.HTML b/public/Wb/Home/Src/Apps/Psalmody/Run.HC.HTML new file mode 100755 index 0000000..02995c8 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Psalmody/Run.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Psalmody;
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/Install.HC.HTML b/public/Wb/Home/Src/Apps/Span/Install.HC.HTML new file mode 100755 index 0000000..bf52ff2 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/Install.HC.HTML @@ -0,0 +1,32 @@ + + + + + + + + + + + +
+DirMk("~/Span");
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/Load.HC.HTML b/public/Wb/Home/Src/Apps/Span/Load.HC.HTML new file mode 100755 index 0000000..0cb1671 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/Load.HC.HTML @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "Span.HH"
+#include "SpanDerive"
+#include "SpanBridge"
+#include "SpanNew"
+#include "SpanMain"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/Run.HC.HTML b/public/Wb/Home/Src/Apps/Span/Run.HC.HTML new file mode 100755 index 0000000..afca3d0 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/Run.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Span;
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/Span.HH.HTML b/public/Wb/Home/Src/Apps/Span/Span.HH.HTML new file mode 100755 index 0000000..1df594a --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/Span.HH.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+#define SPAN_VERSION    1.0
+
+class SpanHeader
+{
+F64 version;
+I32 num_masses,num_springs;
+};
+
+class MyMass:CMass
+{
+F64 radius,cost,load_t;
+CColorROPU32 color;
+} *cursor_mass;
+
+class MySpring:CSpring
+{
+F64 compression_strength,tensile_strength,cost;
+F64 base_compression_strength,base_tensile_strength,
+base_const,base_cost;
+
+CColorROPU32 color;
+I32 thick;
+};
+
+CMathODE *ode=NULL;
+
+CCtrlBttnState run_bttn,mode_bttn;
+
+CColorROPU32 run_colors[2]={RED,GREEN};
+
+#define MD_MASS         0
+#define MD_CONCRETE     1
+#define MD_STEEL        2
+#define MD_WIRE         3
+#define MD_MOVE         4
+#define MD_DELETE       5
+#define MD_MODES_NUM    6
+CColorROPU32 mode_colors[MD_MODES_NUM]=
+{BROWN,LTGRAY,DKGRAY,RED,PURPLE,RED};
+  DefineLstLoad("ST_SPAN_MODES","Mass\0Concrete\0Steel\0Wire\0Move\0Delete\0");
+
+  class SpanAnimateStruct
+          {
+    U8 *saved_ode;
+  F64 elapsed_t,start_wall_t;
+} a;
+
+extern MyMass *PlaceMass(I64 x, I64 y);
+extern F64 SpanTime();
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/SpanBridge.HC.HTML b/public/Wb/Home/Src/Apps/Span/SpanBridge.HC.HTML new file mode 100755 index 0000000..48b6640 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/SpanBridge.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+#define STRENGTH_SCALE  1.5e7
+#define SPRING_SCALE    6.0e6
+#define COST_SCALE      375.0
+#define MASS_RADIUS     3.0
+#define MASS_MASS       10.0
+#define WIRE_PERCENT    0.99
+
+#define RIVER_BANK_COLS 5
+#define SKY_LINES       40
+
+#define FIXED_X1        ((RIVER_BANK_COLS-1)*FONT_WIDTH)
+#define FIXED_X2        ((RIVER_BANK_COLS-4)*FONT_WIDTH)
+#define FIXED_X3        (TEXT_COLS*FONT_WIDTH>>1)
+#define FIXED_Y1        ((SKY_LINES+1)*FONT_HEIGHT)
+#define FIXED_Y2        ((SKY_LINES+5)*FONT_HEIGHT)
+#define FIXED_Y3        ((TEXT_ROWS-8)*FONT_HEIGHT)
+
+#define LOAD_WEIGHTS    8
+
+U0 SpanBridge1Init(CMathODE *)
+{
+  I64 i;
+
+  MyMass *tmpm;
+  tmpm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(GR_WIDTH-FIXED_X2,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(GR_WIDTH-FIXED_X1,FIXED_Y2);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X1,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X2,FIXED_Y1);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X1,FIXED_Y2);
+  tmpm->flags|=MSF_FIXED;
+  tmpm=PlaceMass(FIXED_X3,FIXED_Y3);
+  tmpm->flags|=MSF_FIXED;
+
+  for (i=0;i<LOAD_WEIGHTS;i++) {
+    tmpm=PlaceMass(FIXED_X1+(i+1)*(GR_WIDTH-2*FIXED_X1)/(LOAD_WEIGHTS+1),
+          FIXED_Y1);
+    tmpm->load_t=(i+1.0)/LOAD_WEIGHTS;
+    tmpm->color=RED;
+  }
+
+  DocClear;
+  "$BG,LTCYAN$%h*c",SKY_LINES,'\n';
+  for (i=0;i<10;i++) {
+    "$BG,BROWN$%h*c",RIVER_BANK_COLS,CH_SPACE;
+    "$BG,LTCYAN$%h*c",TEXT_COLS-2*RIVER_BANK_COLS,CH_SPACE;
+    "$BG,BROWN$%h*c\n",RIVER_BANK_COLS,CH_SPACE;
+  }
+  for (i=0;i<5;i++)  {
+    "$BG,BROWN$%h*c",RIVER_BANK_COLS+i,CH_SPACE;
+    "$BG,BLUE$%h*c",TEXT_COLS/2-RIVER_BANK_COLS-2*i,CH_SPACE;
+    "$BG,BROWN$%h*c",2*i,CH_SPACE;
+    "$BG,BLUE$%h*c",TEXT_COLS/2-RIVER_BANK_COLS-2*i,CH_SPACE;
+    "$BG,BROWN$%h*c\n",RIVER_BANK_COLS+i,CH_SPACE;
+  }
+}
+
+U0 AdjustLoads(CMathODE *ode)
+{
+  MyMass *tmpm=ode->next_mass;
+  F64 d,tt=SpanTime/10.0;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->load_t) {
+      if (tt) {
+        d=Abs(Sin(tmpm->load_t*pi+tt)); //0.0<=d<=1.0
+        tmpm->mass=100.0*Sqr(Sqr(d+1.0));
+        tmpm->radius=7.0*d+2.0;
+      } else {
+        tmpm->mass=MASS_MASS;
+        tmpm->radius=MASS_RADIUS;
+      }
+    }
+    tmpm=tmpm->next;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/SpanDerive.HC.HTML b/public/Wb/Home/Src/Apps/Span/SpanDerive.HC.HTML new file mode 100755 index 0000000..1a6563c --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/SpanDerive.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+//The forces due to springs and drag are
+  //automatically handled by the
+  //ode code.  We can add new forces
+  //here.
+  CTask *task=ode->win_task;
+  F64 d,dd;
+  CD3 p,p2;
+  MyMass *tmpm1,*tmpm2;
+
+  //Collisions
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      D3Sub(&p,&tmpm2->state->x,&tmpm1->state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=Sqr(tmpm1->radius+tmpm2->radius)) {
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr(Sqr(tmpm1->radius+tmpm2->radius)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&tmpm2->DstateDt->DxDt,&p);
+        D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+      }
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    if (!(tmpm1->flags&MSF_FIXED))
+      tmpm1->DstateDt->DyDt+=10.0*tmpm1->mass; //Gravity
+    tmpm1=tmpm1->next;
+  }
+
+  if (cursor_mass) {
+    p2.x=ms.pos.x-task->pix_left-task->scroll_x;
+    p2.y=ms.pos.y-task->pix_top-task->scroll_y;
+    p2.z=0;
+    D3Sub(&p,&p2,&cursor_mass->state->x);
+    d=10.0*D3NormSqr(&p);
+    D3MulEqu(&p,d);
+    D3AddEqu(&cursor_mass->DstateDt->DxDt,&p);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/SpanMain.HC.HTML b/public/Wb/Home/Src/Apps/Span/SpanMain.HC.HTML new file mode 100755 index 0000000..69b7f25 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/SpanMain.HC.HTML @@ -0,0 +1,499 @@ + + + + + + + + + + + +
+F64 SpanTime()
+{
+  if (run_bttn.state)
+    return a.elapsed_t+tS-a.start_wall_t;
+  else
+    return a.elapsed_t;
+}
+
+F64 Cost(CMathODE *ode)
+{
+  MyMass   *tmpm;
+  MySpring *tmps;
+  F64 res=0;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    res+=tmpm->cost;
+    tmpm=tmpm->next;
+  }
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    res+=tmps->cost;
+    tmps=tmps->next;
+  }
+  return res;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  MyMass   *tmpm;
+  MySpring *tmps;
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (!(tmps->flags&SSF_INACTIVE)) {
+      dc->color=tmps->color;
+      dc->thick=tmps->thick;
+      GrLine3(dc,tmps->end1->x,tmps->end1->y,0,
+            tmps->end2->x,tmps->end2->y,0);
+    }
+    tmps=tmps->next;
+  }
+
+  if (cursor_mass) {
+    dc->color=RED;
+    dc->thick=2;
+    GrLine3(dc,ms.pos.x-task->pix_left-task->scroll_x,
+          ms.pos.y-task->pix_top-task->scroll_y,0,
+          cursor_mass->x,cursor_mass->y,0);
+  }
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (!(tmpm->flags&MSF_INACTIVE)) {
+      dc->color=BLACK;
+      GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+      GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);
+      dc->color=tmpm->color;
+      GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+      GrFloodFill(dc,tmpm->x,tmpm->y,TRUE);
+      dc->color=BLACK;
+      GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+    }
+    tmpm=tmpm->next;
+  }
+
+  dc->color=BLACK;
+  GrPrint(dc,90,0,"Cost:%12.2,f",Cost(ode));
+  GrPrint(dc,90,FONT_HEIGHT,"Time:%12.2f",SpanTime);
+}
+
+MyMass *PlaceMass(I64 x, I64 y)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass));
+  tmpm->drag_profile_factor=1.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->mass=MASS_MASS;
+  tmpm->radius=MASS_RADIUS;
+  tmpm->cost=25.0*COST_SCALE;
+  tmpm->color=YELLOW;
+  QueIns(tmpm,ode->last_mass);
+  return tmpm;
+}
+
+U0 NullSpring(MySpring *tmps,F64 scale)
+{
+  F64 d=D3Dist(&tmps->end1->x,&tmps->end2->x);
+  tmps->rest_len=d*scale;
+  tmps->compression_strength=
+        tmps->base_compression_strength/(tmps->rest_len+1.0);
+  tmps->tensile_strength=tmps->base_tensile_strength/(tmps->rest_len+1.0);
+  tmps->const=tmps->base_const/(tmps->rest_len+1.0);
+  tmps->cost=tmps->base_cost*tmps->rest_len;
+}
+
+U0 MoveMass(MyMass *tmpm,I64 x, I64 y)
+{
+  MySpring *tmps;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->DxDt=0;
+  tmpm->DyDt=0;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->end1==tmpm || tmps->end2==tmpm) {
+      if (tmps->flags&SSF_NO_COMPRESSION)
+        NullSpring(tmps,WIRE_PERCENT);
+      else
+        NullSpring(tmps,1.0);
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 DelSpring(MySpring *tmps)
+{
+  QueRem(tmps);
+  Free(tmps);
+}
+
+U0 DelMass(MyMass *tmpm)
+{
+  MySpring *tmps,*tmps1;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps1=tmps->next;
+    if (tmps->end1==tmpm || tmps->end2==tmpm)
+      DelSpring(tmps);
+    tmps=tmps1;
+  }
+  QueRem(tmpm);
+  Free(tmpm);
+}
+
+U0 DrawSpring(CDC *dc,MyMass *tmpm,I64 x,I64 y)
+{
+  switch (mode_bttn.state) {
+    case MD_CONCRETE:
+      dc->color=LTGRAY;
+      dc->thick=2;
+      break;
+    case MD_STEEL:
+      dc->color=DKGRAY;
+      dc->thick=2;
+      break;
+    case MD_WIRE:
+      dc->color=RED;
+      dc->thick=1;
+      break;
+  }
+  GrLine3(dc,tmpm->x,tmpm->y,0,x,y,0);
+}
+
+U0 PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  switch (mode_bttn.state) {
+    case MD_CONCRETE:
+      tmps->base_const        = 3.00*SPRING_SCALE;
+      tmps->base_compression_strength=10.00*STRENGTH_SCALE;
+      tmps->base_tensile_strength    = 0.35*STRENGTH_SCALE;
+      tmps->base_cost                 = 0.30*COST_SCALE;
+      NullSpring(tmps,1.0);
+      tmps->color=LTGRAY;
+      tmps->thick=2;
+      break;
+    case MD_STEEL:
+      tmps->base_const        = 1.00*SPRING_SCALE;
+      tmps->base_compression_strength= 1.00*STRENGTH_SCALE;
+      tmps->base_tensile_strength    = 1.00*STRENGTH_SCALE;
+      tmps->base_cost                 = 1.00*COST_SCALE;
+      NullSpring(tmps,1.0);
+      tmps->color=DKGRAY;
+      tmps->thick=2;
+      break;
+    case MD_WIRE:
+      tmps->base_const        = 0.25*SPRING_SCALE;
+      tmps->base_compression_strength= 0.00;
+      tmps->base_tensile_strength    = 0.50*STRENGTH_SCALE;
+      tmps->base_cost                 = 0.10*COST_SCALE;
+      NullSpring(tmps,WIRE_PERCENT);
+      tmps->color=RED;
+      tmps->thick=1;
+      tmps->flags|=SSF_NO_COMPRESSION;
+      break;
+  }
+  QueIns(tmps,ode->last_spring);
+}
+
+U0 AnimateTask(SpanAnimateStruct *a)
+{
+  MySpring *tmps,*tmps1;
+  Bool old_run=FALSE;
+  F64 f;
+  while (TRUE) {
+    tmps=ode->next_spring;
+    while (tmps!=&ode->next_spring) {
+      tmps1=tmps->next;
+      f=tmps->f;
+      if (f>0 &&  f>tmps->compression_strength &&
+            !(tmps->flags&SSF_NO_COMPRESSION)||
+            f<0 && -f>tmps->tensile_strength &&
+            !(tmps->flags&SSF_NO_TENSION))
+        tmps->flags|=SSF_INACTIVE;
+      tmps=tmps1;
+    }
+    AdjustLoads(ode);
+    Refresh; //CMathODE updated once per refresh.
+    if (old_run!=run_bttn.state) {
+      if (run_bttn.state) {
+        if (!a->elapsed_t || !a->saved_ode) {
+          Free(a->saved_ode);
+          a->saved_ode=SpanSave(ode);
+        }
+        a->start_wall_t=tS;
+        ODEPause(ode,OFF);
+      } else {
+        ODEPause(ode);
+        a->elapsed_t+=tS-a->start_wall_t;
+      }
+      old_run=run_bttn.state;
+    }
+  }
+}
+
+U0 Init(SpanAnimateStruct *a)
+{
+  SpanDel(ode);
+  ode=SpanNew;
+
+  run_bttn.state=0;
+  Refresh(2); //Allow stop to reg in animate task.
+
+  if (a->saved_ode)
+    SpanLoad(ode,a->saved_ode);
+  else
+    SpanBridge1Init(ode);
+  a->elapsed_t=0;
+  cursor_mass=NULL;
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 3.636;
+  music.stacatto_factor= 0.902;
+  while (TRUE) {
+    Play("5q.EeDqED4G5DhE");
+    Play("5q.EeDqED4G5DhE");
+    Play("5q.FeEFEqF4G5EhF");
+    Play("5q.FeEFEqF4G5EhF");
+  }
+}
+
+U0 Span()
+{
+  I64 msg_code,arg1,arg2;
+  MyMass   *tmpm1=NULL,*tmpm2=NULL;
+  MySpring *tmps;
+  CCtrl *bt_run,*bt_mode;
+  U8 *src;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BROWN<<4+BLACK;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+
+  bt_run =CtrlBttnNew(0,0,                80,,
+        2,"Stopped\0Running\0",run_colors,&run_bttn);
+  bt_mode=CtrlBttnNew(0,3.0*FONT_HEIGHT,80,,
+        MD_MODES_NUM,Define("ST_SPAN_MODES"),mode_colors,&mode_bttn);
+  a.saved_ode=NULL;
+
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  New(,CH_CTRLN);"
+        "  Open(,CH_CTRLO);"
+        "  SaveAs(,CH_CTRLA);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  RunStop(,CH_SPACE);"
+        "  Mass(,'m');"
+        "  Concrete(,'c');"
+        "  Steel(,'s');"
+        "  Wire(,'w');"
+        "  Move(,'v');"
+        "  Delete(,'d');"
+        "}"
+        );
+
+  ode=NULL;
+  Init(&a);
+  Fs->animate_task=Spawn(&AnimateTask,&a,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  PopUpOk(
+        "Build a bridge to hold-up the\n"
+        "red masses.  Test your design\n"
+        "by pressing run/stop.\n\n"
+        "The lowest cost bridge that\n"
+        "stays standing wins.\n\n"
+        "For a variation, try without\n"
+        "using the center base point.\n"
+        "\n"
+        "Use\n"
+        "\t$GREEN$'m'$FG$ass\n"
+        "\t$GREEN$'c'$FG$oncrete\n"
+        "\t$GREEN$'s'$FG$teel\n"
+        "\t$GREEN$'w'$FG$ire\n"
+        "\nto sel materials.\n");
+
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|
+            1<<MSG_MS_L_UP|1<<MSG_KEY_DOWN|1<<MSG_MS_MOVE);
+      DCFill(dc);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+          cursor_mass=tmpm1=tmpm2=NULL;
+          switch (mode_bttn.state) {
+            case MD_MASS:
+              PlaceMass(arg1,arg2);
+              break;
+            case MD_CONCRETE:
+            case MD_STEEL:
+            case MD_WIRE:
+              tmpm1=MassFind(ode,arg1,arg2);
+              break;
+            case MD_MOVE:
+              if (run_bttn.state)
+                cursor_mass=MassFind(ode,arg1,arg2);
+              else
+                if (tmpm1=MassFind(ode,arg1,arg2))
+                  MoveMass(tmpm1,arg1,arg2);
+              break;
+            case MD_DELETE:
+              MassOrSpringFind(ode,&tmpm1,&tmps,arg1,arg2);
+              if (tmpm1)
+                DelMass(tmpm1);
+              if (tmps)
+                DelSpring(tmps);
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (mode_bttn.state) {
+            case MD_CONCRETE:
+            case MD_STEEL:
+            case MD_WIRE:
+              if (tmpm1 && (tmpm2=MassFind(ode,arg1,arg2)) && tmpm1!=tmpm2)
+                PlaceSpring(tmpm1,tmpm2);
+              break;
+            case MD_MOVE:
+              if (!run_bttn.state && tmpm1)
+                MoveMass(tmpm1,arg1,arg2);
+              break;
+          }
+          cursor_mass=tmpm1=tmpm2=NULL;
+          break;
+        case MSG_MS_MOVE:
+          switch (mode_bttn.state) {
+            case MD_MOVE:
+              if (!run_bttn.state && tmpm1)
+                MoveMass(tmpm1,arg1,arg2);
+              break;
+            case MD_CONCRETE:
+            case MD_STEEL:
+            case MD_WIRE:
+              if (tmpm1) {
+                DrawSpring(dc,tmpm1,arg1,arg2);
+              }
+              break;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+          mode_bttn.state++;
+          if (mode_bttn.state>=MD_MODES_NUM)
+            mode_bttn.state=0;
+          cursor_mass=tmpm1=tmpm2=NULL;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              if (!SpanTime || !a.saved_ode) {
+                Free(a.saved_ode);
+                a.saved_ode=SpanSave(ode);
+              }
+              Init(&a);
+              break;
+            case CH_CTRLN:
+              Free(a.saved_ode);
+              a.saved_ode=NULL;
+              Init(&a);
+              break;
+            case CH_CTRLO:
+              if (src=SpanRead) {
+                Free(a.saved_ode);
+                a.saved_ode=src;
+                Init(&a);
+              }
+              break;
+            case CH_CTRLA:
+              if (!SpanTime || !a.saved_ode) {
+                Free(a.saved_ode);
+                a.saved_ode=SpanSave(ode);
+              }
+              Init(&a);
+              SpanWrite(ode);
+              break;
+            case CH_SPACE:
+              run_bttn.state=!run_bttn.state;
+              break;
+            case 'c':
+              mode_bttn.state=MD_CONCRETE;
+              break;
+            case 's':
+              mode_bttn.state=MD_STEEL;
+              break;
+            case 'w':
+              mode_bttn.state=MD_WIRE;
+              break;
+            case 'm':
+              mode_bttn.state=MD_MASS;
+              break;
+            case 'v':
+              mode_bttn.state=MD_MOVE;
+              break;
+            case 'd':
+              mode_bttn.state=MD_DELETE;
+              break;
+            case CH_ESC:
+              if (!SpanTime || !a.saved_ode) {
+                Free(a.saved_ode);
+                a.saved_ode=SpanSave(ode);
+              }
+              Init(&a);
+              SpanWrite(ode);
+            case CH_SHIFT_ESC:
+              goto span_done;
+          }
+          break;
+      }
+    }
+span_done: //Don't goto out of try
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+  CtrlBttnDel(bt_run);
+  CtrlBttnDel(bt_mode);
+  SpanDel(ode);
+  DCFill(dc);
+  DCDel(dc);
+  MenuPop;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Span/SpanNew.HC.HTML b/public/Wb/Home/Src/Apps/Span/SpanNew.HC.HTML new file mode 100755 index 0000000..992f4a1 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Span/SpanNew.HC.HTML @@ -0,0 +1,157 @@ + + + + + + + + + + + +
+CMathODE *SpanNew()
+{
+  CMathODE *ode=ODENew(0,1e-4,ODEF_HAS_MASSES|ODEF_PAUSED);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+  QueIns(ode,Fs->last_ode);
+  return ode;
+}
+
+U0 SpanDel(CMathODE *ode)
+{
+  if (ode) {
+    QueRem(ode);
+    QueDel(&ode->next_mass,TRUE);
+    QueDel(&ode->next_spring,TRUE);
+    ODEDel(ode);
+  }
+}
+
+#define M_SIZE (sizeof(MyMass)  -offset(CMass.start))
+#define S_SIZE (sizeof(MySpring)-offset(CSpring.start))
+
+U8 *SpanSave(CMathODE *ode,I64 *_size=NULL)
+{
+  I64 cnt;
+  U8 *res,*ptr;
+  MyMass   *tmpm;
+  MySpring *tmps;
+  SpanHeader h;
+
+  ODERenum(ode);
+  h.version=SPAN_VERSION;
+  if (ode->next_mass!=&ode->next_mass)
+    h.num_masses=ode->last_mass->num+1;
+  else
+    h.num_masses=0;
+  if (ode->next_spring!=&ode->next_spring)
+    h.num_springs=ode->last_spring->num+1;
+  else
+    h.num_springs=0;
+
+  cnt=sizeof(SpanHeader)+h.num_masses*M_SIZE+h.num_springs*S_SIZE;
+
+  ptr=res=MAlloc(cnt);
+  MemCpy(ptr,&h,sizeof(SpanHeader));
+  ptr+=sizeof(SpanHeader);
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    MemCpy(ptr,&tmpm->start,M_SIZE);
+    ptr+=M_SIZE;
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    MemCpy(ptr,&tmps->start,S_SIZE);
+    ptr+=S_SIZE;
+    tmps=tmps->next;
+  }
+  if (_size) *_size=cnt;
+  return res;
+}
+
+Bool SpanWrite(CMathODE *ode)
+{
+  U8 *name,*buf;
+  I64 size;
+  Bool res=FALSE,old_silent=Silent;
+  DirMk("~/Span");
+  Silent(old_silent);
+  if (name=PopUpFileName("~/Span/Game.DATA")) {
+    if (buf=SpanSave(ode,&size)) {
+      FileWrite(name,buf,size);
+      Free(buf);
+      res=TRUE;
+    }
+    Free(name);
+  }
+  return res;
+}
+
+U0 SpanLoad(CMathODE *ode,U8 *src)
+{
+  I64 i;
+  MyMass   *tmpm;
+  MySpring *tmps;
+  SpanHeader h;
+
+  if (!src) return;
+
+  MemCpy(&h,src,sizeof(SpanHeader));
+  src+=sizeof(SpanHeader);
+
+  for (i=0;i<h.num_masses;i++) {
+    tmpm=CAlloc(sizeof(MyMass));
+    MemCpy(&tmpm->start,src,M_SIZE);
+    src+=M_SIZE;
+    QueIns(tmpm,ode->last_mass);
+  }
+
+  for (i=0;i<h.num_springs;i++) {
+    tmps=CAlloc(sizeof(MySpring));
+    MemCpy(&tmps->start,src,S_SIZE);
+    src+=S_SIZE;
+    QueIns(tmps,ode->last_spring);
+    tmps->end1=MassFindNum(ode,tmps->end1_num);
+    tmps->end2=MassFindNum(ode,tmps->end2_num);
+  }
+}
+
+U8 *SpanRead()
+{
+  U8 *src=NULL,*name;
+  Bool old_silent=Silent;
+  DirMk("~/Span");
+  Silent(old_silent);
+  if (name=PopUpPickFile("~/Span")) {
+    src=FileRead(name);
+    Free(name);
+  }
+  return src;
+}
+
+
+ diff --git a/public/Wb/Home/Src/Apps/Strut/Load.HC.HTML b/public/Wb/Home/Src/Apps/Strut/Load.HC.HTML new file mode 100755 index 0000000..b739757 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Strut/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "Strut"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/Strut/Run.HC.HTML b/public/Wb/Home/Src/Apps/Strut/Run.HC.HTML new file mode 100755 index 0000000..828cc1b --- /dev/null +++ b/public/Wb/Home/Src/Apps/Strut/Run.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Strut;
+
+ diff --git a/public/Wb/Home/Src/Apps/Strut/Strut.HC.HTML b/public/Wb/Home/Src/Apps/Strut/Strut.HC.HTML new file mode 100755 index 0000000..7a5ec6c --- /dev/null +++ b/public/Wb/Home/Src/Apps/Strut/Strut.HC.HTML @@ -0,0 +1,667 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+#define STARS_NUM       8192
+I64 stars_x[STARS_NUM],stars_y[STARS_NUM];
+
+#define RADIUS  7
+
+class MyMass:CMass
+{
+  U8 *img;
+};
+
+class MySpring:CSpring
+{
+  I64 type,action_key;
+};
+
+//Main Modses
+#define MMD_EDIT        0
+#define MMD_PLAY        1
+#define MMD_MODES_NUM   2
+CColorROPU32 main_mode_colors[MMD_MODES_NUM]={LTRED,LTGREEN};
+DefineLstLoad("ST_MAIN_MODES","Edit\0Play\0");
+CCtrlBttnState main_mode_bttn;
+
+//Edit Modes
+#define EMD_MASS        0
+#define EMD_SPRING      1
+#define EMD_CONNECTOR   2
+#define EMD_THRUSTER    3
+#define EMD_MOVE        4
+#define EMD_MODES_NUM   5
+CColorROPU32 edit_mode_colors[EMD_MODES_NUM]={LTGRAY,LTCYAN,CYAN,YELLOW,LTBLUE};
+DefineLstLoad("ST_EDIT_MODES","Mass\0Spring\0Connector\0Thruster\0Move\0");
+CCtrlBttnState edit_mode_bttn;
+
+CTask *task;
+F64 zoom;
+I64 next_action_key,action_scan_codes[10];
+CMathODE *ode=NULL;
+
+U0 S2W(F64 sx,F64 sy,F64 *_wx,F64 *_wy)
+{
+  sx-=task->pix_left+task->scroll_x;
+  sy-=task->pix_top +task->scroll_y;
+  *_wx=sx/zoom;
+  *_wy=sy/zoom;
+}
+
+U0 W2S(F64 wx,F64 wy,F64 *_sx,F64 *_sy)
+{
+  *_sx=wx*zoom; *_sy=wy*zoom;
+}
+
+#define ZOOM_STEPS      20
+
+U0 Zoom(F64 d)
+{
+  F64 sx,sy,wx,wy;
+  I64 i,x=ms.pos.x,y=ms.pos.y;
+  d=Exp(Ln(d)/ZOOM_STEPS);
+  for (i=0;i<ZOOM_STEPS;i++) {
+    S2W(x,y,&wx,&wy);
+    zoom=Clamp(zoom*d,0.02,50);
+    W2S(wx,wy,&sx,&sy);
+    task->scroll_x=ms.pos.x-sx-task->pix_left;
+    task->scroll_y=ms.pos.y-sy-task->pix_top;
+    Sleep(10);
+  }
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  F64 theta,d,x1,y1,x2,y2;
+  MyMass   *tmpm;
+  MySpring *tmps;
+
+  tmpm=ode->next_mass;
+  if (tmpm!=&ode->next_mass) {
+    task->scroll_x=-tmpm->x*zoom+task->pix_width >>1;
+    task->scroll_y=-tmpm->y*zoom+task->pix_height>>1;
+  }
+
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4Scale(dc->r,zoom);
+
+  switch (main_mode_bttn.state) {
+    case MMD_EDIT:
+      task->text_attr=DKGRAY<<4+WHITE;
+      dc->color=BLACK;
+      break;
+    case MMD_PLAY:
+      task->text_attr=BLACK<<4+WHITE;
+      dc->color=WHITE;
+      for (i=0;i<STARS_NUM;i++)
+        GrPlot3(dc,stars_x[i],stars_y[i],0);
+      break;
+  }
+
+  if (main_mode_bttn.state==MMD_EDIT) {
+    if (edit_mode_bttn.state==EMD_CONNECTOR) {
+      dc->color=CYAN;
+      S2W(FONT_WIDTH*11,FONT_HEIGHT*7,&x1,&y1);
+      GrPutChar3(dc,x1,y1,0,next_action_key);
+    } else if (edit_mode_bttn.state==EMD_THRUSTER) {
+      dc->color=YELLOW;
+      S2W(FONT_WIDTH*11,FONT_HEIGHT*7,&x1,&y1);
+      GrPutChar3(dc,x1,y1,0,next_action_key);
+    }
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->type==EMD_SPRING) {
+      dc->color=LTCYAN;
+      GrLine3(dc,tmps->end1->x,tmps->end1->y,0,
+            tmps->end2->x,tmps->end2->y,0);
+    } else if (tmps->type==EMD_CONNECTOR) {
+      dc->color=CYAN;
+      GrLine3(dc,tmps->end1->x,tmps->end1->y,0,
+            tmps->end2->x,tmps->end2->y,0);
+    }
+    tmps=tmps->next;
+  }
+
+  dc->color=LTGRAY;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    Sprite3(dc,tmpm->x,tmpm->y,0,tmpm->img);
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    x1=tmps->end1->x; y1=tmps->end1->y;
+    x2=tmps->end2->x; y2=tmps->end2->y;
+    if (tmps->type==EMD_THRUSTER) {
+      theta=Arg(x2-x1,y2-y1);
+      if (Bt(kbd.down_bitmap,action_scan_codes[tmps->action_key-'0'])) {
+        dc->flags|=DCF_SYMMETRY;
+        DCSymmetry3Set(dc,x1,y1,256,x1,y1,0,x1-256*Cos(theta),y1-256*Sin(theta),0);
+        for (i=0;i<8;i++) {
+          d=20*Rand+6;
+          if (d<10)
+            dc->color=BLUE;
+          else if (d<16)
+            dc->color=LTBLUE;
+          else
+            dc->color=YELLOW;
+          GrLine3(dc,x1-3*Cos(theta),y1-3*Sin(theta),0,
+                x1-d*Cos(theta)+0.5*d*Sin(theta),
+                y1-d*Sin(theta)-0.5*d*Cos(theta),0);
+          GrLine3(dc,x1-2*d*Cos(theta),y1-2*d*Sin(theta),0,
+                x1-d*Cos(theta)+0.5*d*Sin(theta),
+                y1-d*Sin(theta)-0.5*d*Cos(theta),0);
+        }
+        dc->flags&=~DCF_SYMMETRY;
+      }
+      Sprite3ZB(dc,x1,y1,0,<3>,theta);
+      if (zoom>0.5) {
+        dc->color=YELLOW;
+        GrPutChar3(dc,(x1*7+x2)/8,(y1*7+y2)/8,0,tmps->action_key);
+      }
+    } else if (tmps->type==EMD_CONNECTOR) {
+      if (zoom>0.5) {
+        dc->color=CYAN;
+        GrPutChar3(dc,(x1*7+x2)/8,(y1*7+y2)/8,0,tmps->action_key);
+      }
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+//The forces due to springs and drag are
+  //automatically handled by the
+  //ode code.  We can add new forces
+  //here.
+  F64 d,dd;
+  CD3 p;
+  MyMass *tmpm1,*tmpm2;
+  MySpring *tmps;
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      D3Sub(&p,&tmpm2->state->x,&tmpm1->state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=Sqr(2*RADIUS)) {
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr(Sqr(2*RADIUS)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&tmpm2->DstateDt->DxDt,&p);
+        D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+      }
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (main_mode_bttn.state==MMD_PLAY && tmps->type==EMD_THRUSTER &&
+          Bt(kbd.down_bitmap,action_scan_codes[tmps->action_key-'0'])) {
+      D3Sub(&p,&tmps->end2->state->x,&tmps->end1->state->x);
+      D3Unit(&p);
+      D3MulEqu(&p,2000);
+      D3AddEqu(&tmps->end1->DstateDt->DxDt,&p);
+    }
+    tmps=tmps->next;
+  }
+}
+
+MyMass *PlaceMass(I64 x, I64 y)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass));
+  tmpm->mass=1.0;
+  tmpm->drag_profile_factor=100.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  QueIns(tmpm,ode->last_mass);
+  return tmpm;
+}
+
+MySpring *PlaceSpring(MyMass *tmpm1,MyMass *tmpm2,I64 type)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  F64 d=D3Dist(&tmpm1->x,&tmpm2->x);
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  tmps->rest_len=d;
+  tmps->type=type;
+  if (type==EMD_THRUSTER)
+    tmps->const=0;
+  else
+    tmps->const=2500000/Sqr(d);
+  tmps->action_key=next_action_key;
+  QueIns(tmps,ode->last_spring);
+  return tmps;
+}
+
+U0 CenterMasses()
+{
+  CD3 p;
+  MyMass *tmpm1,*tmpm2;
+  tmpm1=ode->next_mass;
+  if (tmpm1!=&ode->next_mass) {
+    D3Copy(&p,&tmpm1->x);
+    tmpm2=ode->next_mass;
+    while (tmpm2!=&ode->next_mass) {
+      D3SubEqu(&tmpm2->x,&p);
+      tmpm2=tmpm2->next;
+    }
+  }
+}
+
+U0 NullSprings()
+{
+  MySpring *tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    tmps->rest_len=D3Dist(&tmps->end1->x,&tmps->end2->x);
+    tmps=tmps->next;
+  }
+}
+
+U0 BreakConnectors()
+{
+  MySpring *tmps=ode->next_spring,*tmps1;
+  while (tmps!=&ode->next_spring) {
+    tmps1=tmps->next;
+    if (tmps->type==EMD_CONNECTOR &&
+          Bt(kbd.down_bitmap,action_scan_codes[tmps->action_key-'0'])) {
+      QueRem(tmps);
+      Free(tmps);
+    }
+    tmps=tmps1;
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  task=Fs;
+  for (i=0;i<=9;i++)
+    action_scan_codes[i]=Char2ScanCode('0'+i);
+  for (i=0;i<STARS_NUM;i++) {
+    stars_x[i]=RandU32%8192-4096;
+    stars_y[i]=RandU32%8192-4096;
+  }
+  next_action_key='1';
+  zoom=1.0;
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->acceleration_limit=5e3;
+  ode->drag_v2=0.000002;
+  ode->drag_v3=0.0000001;
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  if (ode) {
+    QueRem(ode);
+    QueDel(&ode->next_mass,TRUE);
+    QueDel(&ode->next_spring,TRUE);
+    ODEDel(ode);
+    ode=NULL;
+  }
+}
+
+U0 PlayShip()
+{
+  I64 arg1,arg2;
+  F64 last_noise=0;
+  Bool okay;
+  ODEPause(ode,OFF);
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Edit {"
+        "  EditShip(,CH_SPACE);"
+        "}"
+        "Play {"
+        "  Center(,'c');"
+        "  Damp(,'d');"
+        "  Action0(,'0');"
+        "  Action1(,'1');"
+        "  Action2(,'2');"
+        "  Action3(,'3');"
+        "  Action4(,'4');"
+        "  Action5(,'5');"
+        "  Action6(,'6');"
+        "  Action7(,'7');"
+        "  Action8(,'8');"
+        "  Action9(,'9');"
+        "}"
+        "View {"
+        "  ZoomIn(,'z');"
+        "  ZoomOut(,'Z');"
+        "}"
+        );
+  DocClear;
+  try {
+    while (main_mode_bttn.state==MMD_PLAY) {
+      BreakConnectors;
+      switch (ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '0'...'9':
+              if (tS>last_noise+0.25) {
+                Noise(250,18,46);
+                last_noise=tS;
+              }
+              break;
+            case 'z':
+              Spawn(&Zoom,2.0(I64));
+              break;
+            case 'Z':
+              Spawn(&Zoom,0.5(I64));
+              break;
+            case 'c':
+              CenterMasses;
+              break;
+            case 'd':
+              ode->drag_v2=0.002;
+              ode->drag_v3=0.0001;
+              break;
+            case CH_SPACE:
+              if (++main_mode_bttn.state==MMD_MODES_NUM)
+                main_mode_bttn.state=0;
+              GetMsg(,,1<<MSG_KEY_UP);
+              goto ps_done;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              throw;
+          }
+          break;
+        case MSG_KEY_UP:
+          switch (arg1) {
+            case 'd':
+              ode->drag_v2=0.000002;
+              ode->drag_v3=0.0000001;
+              break;
+          }
+          break;
+      }
+      Refresh;
+    }
+ps_done: //Don't goto out of try
+    okay=TRUE;
+  } catch {
+    Fs->catch_except=TRUE;
+    okay=FALSE;
+  }
+  MenuPop;
+  if (!okay)
+    throw;
+}
+
+U0 EditShip()
+{
+  I64 arg1,arg2;
+  F64 wx,wy;
+  Bool okay;
+  MyMass *tmpm1=NULL,*tmpm2=NULL;
+  CCtrl *bt_edit_mode=CtrlBttnNew(0,5*FONT_HEIGHT+4,80,,EMD_MODES_NUM,
+        Define("ST_EDIT_MODES"),edit_mode_colors,&edit_mode_bttn);
+  ODEPause(ode);
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  PlayShip(,CH_SPACE);"
+        "  Center(,'c');"
+        "  Damp(,'d');"
+        "}"
+        "Edit {"
+        "  Move(,'v');"
+        "  Mass(,'m');"
+        "  Spring(,'s');"
+        "  Connector(,'n');"
+        "  Thruster(,'t');"
+        "  Restart(,'\n');"
+        "  Action0(,'0');"
+        "  Action1(,'1');"
+        "  Action2(,'2');"
+        "  Action3(,'3');"
+        "  Action4(,'4');"
+        "  Action5(,'5');"
+        "  Action6(,'6');"
+        "  Action7(,'7');"
+        "  Action8(,'8');"
+        "  Action9(,'9');"
+        "}"
+        "View {"
+        "  ZoomIn(,'z');"
+        "  ZoomOut(,'Z');"
+        "}"
+        );
+  DocClear;
+  try {
+    while (main_mode_bttn.state==MMD_EDIT) {
+      switch (ScanMsg(&arg1,&arg2,
+            1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_DOWN|
+            1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_MS_L_DOWN:
+          switch (edit_mode_bttn.state) {
+            case EMD_MASS:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              tmpm1=PlaceMass(wx,wy);
+              if (ode->next_mass==tmpm1)
+                tmpm1->img=<1>;
+              else
+                tmpm1->img=<2>;
+              tmpm1=NULL;
+              break;
+            case EMD_SPRING:
+            case EMD_CONNECTOR:
+            case EMD_THRUSTER:
+            case EMD_MOVE:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              tmpm1=MassFind(ode,wx,wy);
+              tmpm2=NULL;
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          switch (edit_mode_bttn.state) {
+            case EMD_MASS:
+              break;
+            case EMD_SPRING:
+            case EMD_CONNECTOR:
+            case EMD_THRUSTER:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              if (tmpm1 && (tmpm2=MassFind(ode,wx,wy)) && tmpm1!=tmpm2)
+                PlaceSpring(tmpm1,tmpm2,edit_mode_bttn.state);
+              tmpm1=tmpm2=NULL;
+              break;
+            case EMD_MOVE:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              if (tmpm1) {
+                tmpm1->x=wx;
+                tmpm1->y=wy;
+                tmpm1->z=0;
+                NullSprings;
+              }
+              tmpm1=tmpm2=NULL;
+              break;
+          }
+          break;
+        case MSG_MS_MOVE:
+          switch (edit_mode_bttn.state) {
+            case EMD_MOVE:
+              S2W(ms.pos.x,ms.pos.y,&wx,&wy);
+              if (tmpm1) {
+                tmpm1->x=wx;
+                tmpm1->y=wy;
+                tmpm1->z=0;
+                NullSprings;
+              }
+              break;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+          if (++edit_mode_bttn.state==EMD_MODES_NUM)
+            edit_mode_bttn.state=0;
+          break;
+        case MSG_MS_R_UP:
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case '0'...'9':
+              next_action_key=arg1;
+              break;
+            case 'c':
+              CenterMasses;
+              break;
+            case 'd':
+              ODEPause(ode,OFF);
+              ode->drag_v2=0.002;
+              ode->drag_v3=0.0001;
+              break;
+            case 'v':
+              edit_mode_bttn.state=EMD_MOVE;
+              break;
+            case 'm':
+              edit_mode_bttn.state=EMD_MASS;
+              break;
+            case 'n':
+              edit_mode_bttn.state=EMD_CONNECTOR;
+              break;
+            case 's':
+              edit_mode_bttn.state=EMD_SPRING;
+              break;
+            case 't':
+              edit_mode_bttn.state=EMD_THRUSTER;
+              break;
+            case 'z':
+              Spawn(&Zoom,2.0(I64));
+              break;
+            case 'Z':
+              Spawn(&Zoom,0.5(I64));
+              break;
+            case CH_SPACE:
+              if (++main_mode_bttn.state==MMD_MODES_NUM)
+                main_mode_bttn.state=0;
+              GetMsg(,,1<<MSG_KEY_UP);
+              goto es_done;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              throw;
+          }
+          break;
+        case MSG_KEY_UP:
+          switch (arg1) {
+            case 'd':
+              ODEPause(ode);
+              ode->drag_v2=0.000002;
+              ode->drag_v3=0.0000001;
+              break;
+          }
+          break;
+      }
+      Refresh;
+    }
+es_done: //Don't goto out of try
+    okay=TRUE;
+  } catch {
+    Fs->catch_except=TRUE;
+    okay=FALSE;
+  }
+  MenuPop;
+  CtrlBttnDel(bt_edit_mode);
+  if (!okay)
+    throw;
+}
+
+U0 Strut()
+{
+  CCtrl *bt_main_mode;
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit|=WIF_SELF_MS_L|WIF_SELF_MS_R|WIG_DBL_CLICK;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  "\n$WW,1$$PURPLE$$TX+CX,\"Build a ship.\"$$FG$\n\n"
+        "Sel mass mode.\tLeft-click to place masses.\n"
+        "Sel spring mode.\tLeft-drag to make members.\n"
+        "Sel thruster mode.\tPress a digit, 0-9.  Drag to make thruster.\n"
+        "Sel connector mode.\tPress a digit, 0-9.  "
+        "Drag to make breakable connector.\n\n"
+        "Press $GREEN$<SPACE>$FG$ to run the game.  Press digits to operate "
+        "thrusters and break connectors.\n\n"
+        "Press $GREEN$<z>$FG$ or $GREEN$<SHIFT-Z>$FG$ to zoom in/out.\n\n";
+
+  PressAKey;
+  bt_main_mode=CtrlBttnNew(
+        (GR_WIDTH-4*FONT_WIDTH-16)>>1,1*FONT_HEIGHT+4,80,,MMD_MODES_NUM,
+        Define("ST_MAIN_MODES"),main_mode_colors,&main_mode_bttn);
+  DocClear;
+  Init;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      EditShip;
+      PlayShip;
+    }
+  } catch {
+    CleanUp;
+    Fs->catch_except=TRUE;
+  }
+  SettingsPop;
+  CtrlBttnDel(bt_main_mode);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/TimeClock/Install.HC.HTML b/public/Wb/Home/Src/Apps/TimeClock/Install.HC.HTML new file mode 100755 index 0000000..5600040 --- /dev/null +++ b/public/Wb/Home/Src/Apps/TimeClock/Install.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+if (!FileFind("~/TimeClock",,FUF_JUST_DIRS)) {
+  DirMk("~/TimeClock");
+  DocClear;
+  "After Loading, type $GREEN$PunchIn;$FG$, "
+  "$GREEN$PunchOut;$FG$ or $GREEN$TimeRep;$FG$\n"
+  "You might want to make PLUGINS for hot keys.\n\n\n";
+}
+
+
+ diff --git a/public/Wb/Home/Src/Apps/TimeClock/Load.HC.HTML b/public/Wb/Home/Src/Apps/TimeClock/Load.HC.HTML new file mode 100755 index 0000000..81a242f --- /dev/null +++ b/public/Wb/Home/Src/Apps/TimeClock/Load.HC.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+#help_index "Misc"
+
+Cd(__DIR__);;
+#include "TimeClk"
+#include "Install" //Might as well always install
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/TimeClock/TimeClk.HC.HTML b/public/Wb/Home/Src/Apps/TimeClock/TimeClk.HC.HTML new file mode 100755 index 0000000..e0d3d0f --- /dev/null +++ b/public/Wb/Home/Src/Apps/TimeClock/TimeClk.HC.HTML @@ -0,0 +1,182 @@ + + + + + + + + + + + +
+#define TIME_FILENAME   "~/TimeClock/TimeFile.DATA.Z"
+
+#define TET_EOF         0
+#define TET_PUNCH_IN    1
+#define TET_PUNCH_OUT   2
+
+class TimeEntry
+{
+  TimeEntry *next,*last;
+  U8 type;
+  CDate datetime;
+  U8 *desc;
+};
+
+U0 TimeFileRead(TimeEntry *header)
+{
+  U8 *buf,*ptr;
+  I64 type;
+  TimeEntry *tmpt;
+  buf=FileRead(TIME_FILENAME);
+  if (!buf)
+    buf=CAlloc(1);
+  QueInit(header);
+  ptr=buf;
+  while (type=*ptr++) {
+    tmpt=CAlloc(sizeof(TimeEntry));
+    tmpt->type=type;
+    tmpt->datetime=*ptr(CDate *)++;
+    tmpt->desc=StrNew(ptr);
+    ptr+=StrLen(ptr)+1;
+    QueIns(tmpt,header->last);
+  }
+  Free(buf);
+}
+
+U0 TimeFileWrite(TimeEntry *header)
+{
+  U8 *buf,*ptr;
+  TimeEntry *tmpt;
+  I64 size=1; //for EOF
+
+  tmpt=header->next;
+  while (tmpt!=header) {
+    size+=sizeof(U8)+sizeof(CDate)+StrLen(tmpt->desc)+1;
+    tmpt=tmpt->next;
+  }
+  buf=MAlloc(size);
+
+  ptr=buf;
+  tmpt=header->next;
+  while (tmpt!=header) {
+    *ptr++=tmpt->type;
+    *ptr(CDate *)++=tmpt->datetime;
+    StrCpy(ptr,tmpt->desc);
+    ptr+=StrLen(tmpt->desc)+1;
+    tmpt=tmpt->next;
+  }
+  *ptr=TET_EOF;
+  FileWrite(TIME_FILENAME,buf,size);
+  Free(buf);
+}
+
+U0 TimeEntriesDel(TimeEntry *header)
+{
+  TimeEntry *tmpt=header->next,*tmpt1;
+  while (tmpt!=header) {
+    tmpt1=tmpt->next;
+    Free(tmpt->desc);
+    Free(tmpt);
+    tmpt=tmpt1;
+  }
+  Free(header);
+}
+
+public Bool TimeRep(TimeEntry **_header=NULL)
+{
+  Bool is_in=FALSE,first=TRUE;
+  I64 week,cur_week=-1,week_total;
+  TimeEntry *tmpt,*header=MAlloc(sizeof(TimeEntry));
+  if (_header) *_header=header;
+  TimeFileRead(header);
+  tmpt=header->next;
+  while (tmpt!=header) {
+    week=tmpt->datetime.date/7;  //TODO
+    if (week!=cur_week) {
+      if (!first) {
+        if (is_in)
+          week_total+=Now;
+        "Week Total:%T\n",week_total-local_time_offset;
+      } else
+        first=FALSE;
+      cur_week=week;
+      week_total=0;
+    }
+    if (tmpt->type==TET_PUNCH_IN) {
+      "$RED$IN ";
+      if (!is_in)
+        week_total-=tmpt->datetime;
+      is_in=TRUE;
+    } else {
+      "$RED$OUT";
+      if (is_in)
+        week_total+=tmpt->datetime;
+      is_in=FALSE;
+    }
+    " %D %T:$FG$\n%s\n",tmpt->datetime,tmpt->datetime,tmpt->desc;
+    tmpt=tmpt->next;
+  }
+  if (is_in)
+    week_total+=Now;
+  "$RED$Week Total:%T$FG$\n",week_total-local_time_offset;
+  if (!_header)
+    TimeEntriesDel(header);
+  return is_in;
+}
+
+public U0 PunchOut()
+{
+  TimeEntry *tmpt,*header;
+  if (!TimeRep(&header))
+    "$BK,1$Already Punched-Out$BK,0$\n";
+  else {
+    tmpt=MAlloc(sizeof(TimeEntry));
+    tmpt->type=TET_PUNCH_OUT;
+    tmpt->datetime=Now;
+    "\nEnter Description.\nPress <ESC> when done.\n";
+    if (!(tmpt->desc=GetStr(,,GSF_WITH_NEW_LINE)))
+      tmpt->desc=CAlloc(1);
+    QueIns(tmpt,header->last);
+    TimeFileWrite(header);
+  }
+  TimeEntriesDel(header);
+}
+
+public U0 PunchIn()
+{
+  TimeEntry *tmpt,*header;
+  if (TimeRep(&header))
+    "$BK,1$Already Punched-In$BK,0$\n";
+  else {
+    tmpt=MAlloc(sizeof(TimeEntry));
+    tmpt->type=TET_PUNCH_IN;
+    tmpt->datetime=Now;
+    "\nEnter Description.\nPress <ESC> when done.\n";
+    if (!(tmpt->desc=GetStr(,,GSF_WITH_NEW_LINE)))
+      tmpt->desc=CAlloc(1);
+    QueIns(tmpt,header->last);
+    TimeFileWrite(header);
+  }
+  TimeEntriesDel(header);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Titanium/Load.HC.HTML b/public/Wb/Home/Src/Apps/Titanium/Load.HC.HTML new file mode 100755 index 0000000..49f3987 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Titanium/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "Titanium"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/Titanium/Run.HC.HTML b/public/Wb/Home/Src/Apps/Titanium/Run.HC.HTML new file mode 100755 index 0000000..8f59b4d --- /dev/null +++ b/public/Wb/Home/Src/Apps/Titanium/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+Titanium;
+ diff --git a/public/Wb/Home/Src/Apps/Titanium/Titanium.HC.HTML b/public/Wb/Home/Src/Apps/Titanium/Titanium.HC.HTML new file mode 100755 index 0000000..461e0e9 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Titanium/Titanium.HC.HTML @@ -0,0 +1,996 @@ + + + + + + + + + + + +
+RegDft("TempleOS/Titanium","I64 best_score=0;\n");
+RegExe("TempleOS/Titanium");
+
+#define MAP_HEIGHT      4096
+
+#define B_LEN   10
+#define B_SPEED 5
+#define B_NUM   128
+class Bullet
+{
+  I64 x,y,dx,dy,dx2,dy2;
+  Bool dead,missile,pad[6];
+} b[B_NUM];
+I64 bullets_fired,missile_bmp;
+
+I64 x,y,dx,dy,finish_line;
+F64 theta,t0,tf,snd_timeout;
+
+#define PHASES_GROUPS   8
+#define HACK_DIST       5
+
+#define U_ENEMY_NUM     (PHASES_GROUPS*64)
+#define U_FRIENDLY_NUM  (PHASES_GROUPS*16)
+#define U_NUM   (U_FRIENDLY_NUM+U_ENEMY_NUM)
+class Unit
+{
+  I64 x,y,best_dd;
+  F64 theta,phase;
+  Bool friendly,dead,tank,CIA,pad[4];
+} u[U_NUM];
+
+#define ET_MAN          0
+#define ET_TANK         1
+#define ET_MISSILE      2
+#define ET_BUILDING     3
+#define E_NUM           512
+class Explosion
+{
+  I64 x,y,num,type;
+  F64 t0,tf;
+  Bool dead,pad[7];
+} e[E_NUM];
+
+I64 total_score,friendly_fire,enemy_by_friendly,friendly_left,enemy_left,
+    main_loop_pass;
+Bool game_over;
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+
+
+U8 *friendly_imgs[4]={<5>,<4>,<5>,<6>};
+
+
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+        <8>/* Graphics Not Rendered in HTML */
+
+
+
+        <9>/* Graphics Not Rendered in HTML */
+
+
+
+U8 *CIA_neeger_imgs[4]={<8>,<7>,<8>,<9>};
+
+
+
+
+        <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <11>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <12>/* Graphics Not Rendered in HTML */
+
+
+
+
+U8 *friendly_hacking_imgs[4]={<10>,<11>,<10>,<12>};
+
+
+
+
+        <13>/* Graphics Not Rendered in HTML */
+
+
+
+        <14>/* Graphics Not Rendered in HTML */
+
+
+
+        <15>/* Graphics Not Rendered in HTML */
+
+
+
+U8 *enemy_imgs[4]={<14>,<13>,<14>,<15>};
+
+
+
+
+        <16>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <17>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <18>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+        <19>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+U8 *enemy_hacking_imgs[4]={<17>,<16>,<17>,<18>};
+
+
+
+
+
+
+
+        <20>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <21>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+        <22>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <23>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+#define LS_APTS_NUM             20
+#define LS_MOUNTAINS_NUM        3
+#define LS_NUM                  128
+class LandScapeItem
+{
+  I64 x,y;
+  U8 *img;
+} ls[LS_NUM];
+
+#define LS_TYPES        4
+U8 *landscape_imgs[LS_TYPES]=
+  {<20>,<21>,<22>,<23>};
+
+U0 ExplosionDraw(CDC *dc,Explosion *tmpe,I64 y)
+{
+  I64 i,n1,n2,n3,n4,n5;
+  F64 t=(tS-tmpe->t0)/(tmpe->tf-tmpe->t0);
+  Seed(tmpe->num+1);
+
+  switch (tmpe->type) {
+    case ET_MAN:        n1=8;   n2=0;  n3=0;  n4=18;  n5=28;    break;
+    case ET_TANK:       n1=64;  n2=14; n3=24; n4=60;  n5=90;    break;
+    case ET_MISSILE:    n1=128; n2=30; n3=60; n4=100; n5=200;   break;
+    case ET_BUILDING:   n1=128; n2=80; n3=80; n4=200; n5=300;   break;
+  }
+  for (i=0;i<n1;i++) {
+    if (i&2)
+      switch (tmpe->type) {
+        case ET_MAN:
+          if (i&1)
+            dc->color=WHITE;
+          else
+            dc->color=LTGRAY;
+          break;
+        case ET_MISSILE:
+          if (i&1) {
+            if (i&4)
+              dc->color=RED;
+            else
+              dc->color=DKGRAY;
+          } else
+            dc->color=YELLOW;
+          break;
+        case ET_TANK:
+          if (i&1) {
+            if (i&4)
+              dc->color=RED;
+            else
+              dc->color=DKGRAY;
+          } else
+            dc->color=LTRED;
+          break;
+        case ET_BUILDING:
+          if (i&1) {
+            if (i&4)
+              dc->color=BLACK;
+            else
+              dc->color=DKGRAY;
+          } else
+            dc->color=LTGRAY;
+          break;
+      }
+    else if (i&1)
+      dc->color=WHITE;
+    else
+      dc->color=LTGRAY;
+    GrLine(dc,tmpe->x+n2*(Rand-.5),y+n3/2*Rand,
+          tmpe->x+n4*t*(Rand-.5),y-n5/2*t*Rand);
+  }
+}
+
+I64 mp_not_done_flags;
+U0 MPMenDraw(CDC *dc2)
+{
+  CTask *task=dc2->win_task;
+  CDC *dc=DCAlias(dc2,task);
+  I64 i,r[16],lo=Gs->num*U_NUM/mp_cnt,hi=(Gs->num+1)*U_NUM/mp_cnt,
+        yy,phase,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
+  Unit *tmpu;
+  Explosion *tmpe;
+  U8 *tmps,**_tmps;
+  F64 tt,ts=tS;
+
+  for (i=Gs->num;i<E_NUM;i+=mp_cnt) {
+    tmpe=&e[i];
+    yy=(tmpe->y-scroll_y)&(MAP_HEIGHT-1);
+    if (-32<=yy<=task->pix_bottom+32 && !tmpe->dead) {
+      ExplosionDraw(dc,tmpe,yy);
+      if (tS>tmpe->tf)
+        tmpe->dead=TRUE;
+    }
+  }
+  for (i=lo;i<hi;i++) {
+    tmpu=&u[i];
+    yy=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
+    if (-32<=yy<=task->pix_bottom+32) {
+      if (!tmpu->dead) {
+        Mat4x4IdentEqu(r);
+        Mat4x4RotY(r,tmpu->theta);
+        Mat4x4RotX(r,pi/6);
+        Mat4x4Scale(r,0.3);
+        if (tmpu->tank)
+          Sprite3Mat4x4B(dc,tmpu->x,yy,GR_Z_ALL,<19>,r);
+        else {
+          if (tmpu->best_dd<(2*HACK_DIST)*(2*HACK_DIST)) {//It's neat so times 2
+            if (tmpu->friendly)
+              _tmps=friendly_hacking_imgs;
+            else
+              _tmps=enemy_hacking_imgs;
+            tt=4*Wrap(tmpu->phase+20*ts,0)/(2*pi);
+          } else {
+            if (tmpu->friendly) {
+              if (tmpu->CIA && Blink)
+                _tmps=CIA_neeger_imgs;
+              else
+                _tmps=friendly_imgs;
+            } else
+              _tmps=enemy_imgs;
+            tt=4*Wrap(tmpu->phase+5*ts,0)/(2*pi);
+          }
+          phase=tt; tt%=1.0;
+          tmps=SpriteInterpolate(tt,_tmps[phase&3],_tmps[(phase+1)&3]);
+          Sprite3Mat4x4B(dc,tmpu->x,yy,GR_Z_ALL,tmps,r);
+          Free(tmps);
+        }
+      }
+    }
+  }
+
+  dc->depth_buf=NULL;
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+  Seed; //Return Seth task to timer-based.
+}
+
+U0 MissilePos(I64 m,F64 theta,I64 *_x,I64 *_y)
+{
+  I64 n;
+  if (m<2)
+    n=-1;
+  else
+    n=1;
+  *_x=x+3.0*Cos(theta)-(15.0-(m&1)<<3)*Cos(theta-n*pi/2);
+  *_y=y+3.0*Sin(theta)-(15.0-(m&1)<<3)*Sin(theta-n*pi/2);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,m,xx,yy,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
+  F64 tt,ts=tS;
+  Bullet *tmpb;
+
+  dc->color=ROPF_DITHER|BROWN<<16|YELLOW;
+  GrRect3(dc,0,0,0,dc->width,dc->height);
+
+  for (i=0;i<LS_NUM;i++) {
+    yy=(ls[i].y-scroll_y)&(MAP_HEIGHT-1);
+    if (-32<=yy<=task->pix_bottom+32)
+      Sprite3(dc,ls[i].x,yy,0,ls[i].img);
+  }
+
+  dc->thick=3;
+  dc->color=BROWN;
+  GrLine3(dc,0,  (finish_line-scroll_y)&(MAP_HEIGHT-1),0,
+        GR_WIDTH,(finish_line-scroll_y)&(MAP_HEIGHT-1),0);
+
+  dc->color=LTGRAY;
+  for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
+    if (!tmpb->dead) {
+      if (tmpb->missile)
+        Sprite3ZB(dc,tmpb->x>>32,tmpb->y>>32,0,<2>,pi/2+Arg(tmpb->dx,tmpb->dy));
+      else
+        GrLine(dc,tmpb->x>>32,tmpb->y>>32,
+              (tmpb->x+tmpb->dy*B_LEN)>>32,
+              (tmpb->y+tmpb->dx*B_LEN)>>32);
+    }
+
+  DCDepthBufAlloc(dc);
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPMenDraw,dc,i);
+  while (mp_not_done_flags)
+    Yield;
+  Free(dc->depth_buf);
+  dc->depth_buf=NULL;
+
+  for (m=0;m<4;m++)
+    if (Bt(&missile_bmp,m)) {
+      MissilePos(m,theta,&xx,&yy);
+      Sprite3ZB(dc,xx,yy,0,<3>,theta);
+    }
+  Sprite3ZB(dc,x,y,0,<1>,theta);
+
+  if (tf) {
+    tt=tf;
+    dc->color=RED;
+    if (game_over && Blink)
+      GrPrint(dc,task->pix_width/2-9*FONT_WIDTH/2,task->pix_height/2,
+            "Game Over");
+  } else {
+    tt=ts;
+    if (!enemy_left || !friendly_left)
+      game_over=TRUE;
+  }
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Enemy:%d Friends:%d Friendly Fire:%d Time:%6.2f Bullets:%d",
+        enemy_left,friendly_left,friendly_fire,tt-t0,bullets_fired);
+  GrPrint(dc,0,8,"Total Score:%,d High Score:%,d",
+        total_score,best_score);
+}
+
+Explosion *ExplosionNew(I64 x,I64 y)
+{
+  I64 i;
+  for (i=0;i<E_NUM;i++)
+    if (e[i].dead) {
+      e[i].x=x;
+      e[i].y=y;
+      e[i].dead=FALSE;
+      return &e[i];
+    }
+  return NULL;
+}
+
+U0 ManDie(Unit *tmpu,Bool by_human)
+{
+  Explosion *tmpe;
+
+  tmpu->dead=TRUE;
+  if (by_human) {
+    if (tmpe=ExplosionNew(tmpu->x,tmpu->y)) {
+      tmpe->t0=tS;
+      if (tmpu->tank) {
+        tmpe->type=ET_TANK;
+        tmpe->tf=tmpe->t0+0.40;
+      } else {
+        tmpe->type=ET_MAN;
+        tmpe->tf=tmpe->t0+0.20;
+      }
+    }
+  }
+
+  if (tmpu->friendly) {
+    friendly_left--;
+    if (by_human)
+      friendly_fire++;
+  } else {
+    enemy_left--;
+    if (!by_human)
+      enemy_by_friendly++;
+  }
+  if (by_human && !snd_timeout) {
+    snd_timeout=tS+0.01;
+    if (tmpu->friendly)
+      Snd(46);
+    else
+      Snd(22);
+  }
+}
+
+U0 ExplosionDo(I64 x,I64 y,I64 scroll_y)
+{
+  I64 i,x2,y2;
+  Explosion *tmpe;
+  Unit *tmpu;
+  if (tmpe=ExplosionNew(x,y+scroll_y)) {
+    tmpe->t0=tS;
+    tmpe->type=ET_MISSILE;
+    tmpe->tf=tmpe->t0+1.0;
+  }
+  for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+    if (!tmpu->dead) {
+      x2=tmpu->x;
+      y2=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
+      if (SqrI64(x-x2)+SqrI64(y-y2)<100*100)
+        ManDie(tmpu,TRUE);
+    }
+  }
+  for (i=0;i<LS_APTS_NUM;i++) {
+    x2=ls[i].x;
+    y2=(ls[i].y-scroll_y)&(MAP_HEIGHT-1);
+    if (SqrI64(x-x2)+SqrI64(y-y2)<100*100) {
+      if (tmpe=ExplosionNew(x2,y2+scroll_y)) {
+        tmpe->t0=tS;
+        tmpe->type=ET_BUILDING;
+        tmpe->tf=tmpe->t0+2.0;
+      }
+    }
+  }
+}
+
+U0 CheckCollisions()
+{
+  I64 i,n1,x,y,scroll_y=MAP_HEIGHT-100-100*(tS-t0);
+  Unit *tmpu;
+  Bullet *tmpb;
+  CDC   *dc2=DCNew(GR_WIDTH,GR_HEIGHT);
+  dc2->color=LTRED;
+  for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
+    if (!tmpb->dead && !tmpb->missile)  //Bullets not missiles
+      GrLine(dc2,tmpb->x>>32,tmpb->y>>32,
+            (tmpb->x+tmpb->dx*B_LEN)>>32,
+            (tmpb->y+tmpb->dy*B_LEN)>>32);
+
+  dc2->color  =ROP_COLLISION;
+  dc2->bkcolor=BLACK;
+  for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+    if (!tmpu->dead) {
+      x=tmpu->x;
+      y=(tmpu->y-scroll_y)&(MAP_HEIGHT-1);
+      if (0<=x<GR_WIDTH && 0<=y<GR_HEIGHT) {
+        dc2->collision_cnt=0;
+        GrRect(dc2,x-3,y-9,6,8);
+        if (dc2->collision_cnt)
+          ManDie(tmpu,TRUE);
+      }
+    }
+  }
+  DCDel(dc2);
+
+  for (i=0,tmpb=b;i<B_NUM;i++,tmpb++)
+    if (!tmpb->dead && tmpb->missile)  { //Missiles not bullets
+      x=tmpb->x>>32;
+      y=tmpb->y>>32;
+      for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+        if (tmpu->tank)
+          n1=16;
+        else
+          n1=6;
+        if (!tmpu->dead && AbsI64(x-tmpu->x-n1)+
+              AbsI64(y-(tmpu->y-scroll_y)&(MAP_HEIGHT-1)+n1)<n1<<1) {
+          tmpb->dead=TRUE;
+          ExplosionDo(x,y,scroll_y);
+        }
+      }
+      if (!tmpb->dead)
+        for (i=0;i<LS_APTS_NUM;i++)
+          if (2*SqrI64(x-ls[i].x)+
+                3*SqrI64(y+35-(ls[i].y-scroll_y)&(MAP_HEIGHT-1))<2*60*60) {
+            tmpb->dead=TRUE;
+            ExplosionDo(x,y,scroll_y);
+          }
+    }
+}
+
+U0 Init()
+{
+  I64 i,xx,yy,scroll_y=MAP_HEIGHT-100;
+  Unit *tmpu;
+
+  snd_timeout=0;
+  Snd;
+
+  total_score=0;
+  game_over=FALSE;
+  main_loop_pass=0;
+
+  x=Fs->pix_width>>1;
+  y=0.9*Fs->pix_height;
+  finish_line=scroll_y+y;
+  dx=0;
+  dy=0;
+  theta=-pi/2;
+
+  for (i=0;i<LS_NUM;i++) {
+    ls[i].x=(Fs->pix_width-100)*RandU32/U32_MAX+50;
+    ls[i].y=(MAP_HEIGHT-100)*RandU32/U32_MAX+50;
+    ls[i].img=landscape_imgs[RandU16%(LS_TYPES-2)];
+  }
+
+  for (i=0;i<LS_APTS_NUM;i++)
+    ls[i].img=landscape_imgs[LS_TYPES-1]; //Apartment
+
+  for (;i<LS_APTS_NUM+LS_MOUNTAINS_NUM;i++)
+    ls[i].img=landscape_imgs[LS_TYPES-2]; //mountain
+
+  MemSet(u,0,sizeof(u));
+  for (i=0,tmpu=u;i<U_NUM;i++,tmpu++) {
+    if (i<U_FRIENDLY_NUM) {
+      tmpu->friendly=TRUE;
+      if (!(i&7)) {
+        xx=(Fs->pix_width-200)*RandU32/U32_MAX;
+        yy=(MAP_HEIGHT-200)*RandU32/U32_MAX;
+      }
+      if (!(i&63))
+        tmpu->CIA=TRUE;
+      else
+        tmpu->CIA
+
+
+
+
+
+
+=FALSE;
+    } else {
+      tmpu->friendly=FALSE;
+      if (!(i&31)) {
+        xx=(Fs->pix_width-200)*RandU32/U32_MAX;
+        yy=(MAP_HEIGHT-200)*RandU32/U32_MAX;
+      }
+      if (!(i&15))
+        tmpu->tank=TRUE;
+    }
+    tmpu->dead=FALSE;
+    tmpu->x=xx+64*RandI32/I32_MAX+100;
+    tmpu->y=yy+64*RandU32/I32_MAX-64+100;
+    tmpu->best_dd=I64_MAX;
+    tmpu->theta=pi/2;
+    tmpu->phase=2*pi*Rand;
+  }
+  for (i=0;i<B_NUM;i++)
+    b[i].dead=TRUE;
+  for (i=0;i<E_NUM;i++) {
+    e[i].dead=TRUE;
+    e[i].num=i;
+  }
+  friendly_left=U_FRIENDLY_NUM;
+  enemy_left   =U_ENEMY_NUM;
+  enemy_by_friendly=0;
+  bullets_fired=0;
+  missile_bmp =15;
+  friendly_fire=0;
+  t0=tS;
+  tf=0;
+}
+
+U0 FireBullet()
+{
+  I64 i,j;
+  F64 a;
+  Bullet *tmpb;
+  for (i=0;i<B_NUM-1;i++)
+    if (b[i].dead)
+      break;
+  tmpb=&b[i];
+
+  j=x+28.0*Cos(theta);
+  tmpb->x=j<<32;
+  j=y+28.0*Sin(theta);
+  tmpb->y=j<<32;
+
+  tmpb->dx2=(B_SPEED*Cos(theta)+dx)*0x100000000;
+  tmpb->dy2= B_SPEED*Sin(theta)*0x100000000;
+  a=Arg(tmpb->dx2,tmpb->dy2);
+  tmpb->dx=Sin(a)*0x100000000;
+  tmpb->dy=Cos(a)*0x100000000;
+  bullets_fired++;
+  tmpb->dead=FALSE;
+  tmpb->missile=FALSE;
+  if (!snd_timeout) {
+    snd_timeout=tS+0.0005;
+    Snd(74);
+  }
+}
+
+Bool FireMissile(I64 n)
+{
+  I64 i,m;
+  F64 a;
+  Bullet *tmpb;
+  Bool res=FALSE;
+
+  m=n;
+  if (Btr(&missile_bmp,++m) || Btr(&missile_bmp,++m))
+    res=TRUE;
+
+  if (res) {
+    for (i=0;i<B_NUM-1;i++)
+      if (b[i].dead)
+        break;
+    tmpb=&b[i];
+
+    MissilePos(m,theta,&tmpb->x,&tmpb->y);
+    tmpb->x<<=32;
+    tmpb->y<<=32;
+
+    tmpb->dx2=(B_SPEED*Cos(theta)+dx)*0x100000000;
+    tmpb->dy2= B_SPEED*Sin(theta)*0x100000000;
+    a=Arg(tmpb->dx2,tmpb->dy2);
+    tmpb->dx=Sin(a)*0x100000000;
+    tmpb->dy=Cos(a)*0x100000000;
+    tmpb->dead=FALSE;
+    tmpb->missile=TRUE;
+    if (!snd_timeout) {
+      snd_timeout=tS+0.0005;
+      Snd(74);
+    }
+  }
+}
+
+U0 MenMove(I64 phase_group)
+{
+  I64 i,j,dd,best,best_dd;
+  for (i=phase_group;i<U_FRIENDLY_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=U_FRIENDLY_NUM;
+      best_dd=I64_MAX;
+      for (j=U_FRIENDLY_NUM;j<U_NUM;j++) {
+        if (!u[j].dead) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd!=I64_MAX) {
+        u[i].x+=4*SignI64(u[best].x-u[i].x);
+        u[i].y+=4*SignI64(u[best].y-u[i].y);
+        u[i].theta=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
+      }
+    }
+  }
+  for (i=U_FRIENDLY_NUM+phase_group;i<U_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=0;
+      best_dd=I64_MAX;
+      for (j=0;j<U_FRIENDLY_NUM;j++) {
+        if (!u[j].dead) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd!=I64_MAX) {
+        u[i].x+=4*SignI64(u[best].x-u[i].x);
+        u[i].y+=4*SignI64(u[best].y-u[i].y);
+        u[i].theta=Arg(u[best].x-u[i].x,u[best].y-u[i].y);
+      }
+    }
+  }
+}
+
+U0 MenFight(I64 phase_group)
+{
+  I64 i,j,dd,best,best_dd;
+  for (i=phase_group;i<U_FRIENDLY_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=U_FRIENDLY_NUM;
+      best_dd=I64_MAX;
+      for (j=U_FRIENDLY_NUM;j<U_NUM;j++) {
+        if (!u[j].dead && u[i].y-u[j].y<8) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
+        ManDie(&u[best],FALSE);
+    }
+  }
+  for (i=U_FRIENDLY_NUM+phase_group;i<U_NUM;i+=PHASES_GROUPS) {
+    if (!u[i].dead) {
+      best=0;
+      best_dd=I64_MAX;
+      for (j=0;j<U_FRIENDLY_NUM;j++) {
+        if (!u[j].dead&& u[i].y-u[j].y<8) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if (dd<best_dd) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].best_dd=best_dd;
+      if (best_dd<HACK_DIST*HACK_DIST && !(RandU16&1))
+        ManDie(&u[best],FALSE);
+    }
+  }
+}
+
+U0 Titanium()
+{
+  I64 i,msg_code,ch,sc;
+  Bool gun_on;
+
+  I64 next_update_jiffy;
+  SettingsPush; //See SettingsPush
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fire(,CH_SPACE);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  LeftMissile(,,SC_CURSOR_LEFT|SCF_CTRL);"
+        "  RightMissile(,,SC_CURSOR_RIGHT|SCF_CTRL);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  "\nScoring:\n"
+        "\tEnemy Killed\t\t+3\n"
+        "\tEnemy by Friendly\t+5\n"
+        "\tFriendly Fire\t\t-100\n"
+        "\tBullets Fired\t\t-1\n"
+        "\tGame Time\t\t-10 per second\n"
+        "\tSurviving Friendlies\t+250\n\n"
+        "Sweep side-to-side while shooting, "
+        "holding down $GREEN$<SPACE>$FG$.\n\n";
+  PressAKey;
+
+  Init;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+
+  gun_on=FALSE;
+
+  try {
+    while (TRUE) {
+      next_update_jiffy=cnts.jiffies+JIFFY_FREQ/100;
+      while (msg_code=ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN+1<<MSG_KEY_UP)) {
+        switch (msg_code) {
+          case MSG_KEY_DOWN:
+            switch (ch) {
+              case 0:
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    if (sc&SCF_CTRL)
+                      FireMissile(1);
+                    break;
+                  case SC_CURSOR_LEFT:
+                    if (sc&SCF_CTRL)
+                      FireMissile(-1);
+                    break;
+                }
+                break;
+              case CH_SHIFT_ESC:
+              case CH_ESC:
+                goto to_done;
+              case '\n':
+                Init;
+                break;
+              case CH_SPACE:
+                gun_on=TRUE;
+                break;
+            }
+            break;
+          case MSG_KEY_UP:
+            if (ch==CH_SPACE)
+              gun_on=FALSE;
+            else if (sc.u8[0]==SC_CURSOR_RIGHT||sc.u8[0]==SC_CURSOR_LEFT)
+              theta=-pi/2;
+            break;
+        }
+      }
+
+      for (i=0;i<B_NUM;i++) {
+        if (!b[i].dead) {
+          b[i].x+=b[i].dx2;
+          b[i].y+=b[i].dy2;
+          if (b[i].y<0||b[i].x<0||
+                b[i].x>>32>=Fs->pix_width||
+                b[i].y>>32>=Fs->pix_height)
+            b[i].dead=TRUE;
+        }
+      }
+
+      dx=0;
+      if (!Bt(kbd.down_bitmap,SC_CTRL)) {
+        if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+          theta=-pi/2-15.0*pi/180.0;
+          dx=-2;
+        } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+          theta=-pi/2+15.0*pi/180.0;
+          dx=2;
+        }
+      }
+      x+=dx;
+      while (x>=Fs->pix_width)
+        x-=Fs->pix_width;
+      while (x<0)
+        x+=Fs->pix_width;
+
+        //It takes too much CPU do do all these all the time.
+      switch [main_loop_pass&7] {
+        case 0:
+          switch [main_loop_pass>>3&7] {
+            case 0:
+              if (--y<20)
+                game_over=TRUE;
+            case 2:
+            case 4:
+            case 6:
+              MenFight(main_loop_pass>>4%PHASES_GROUPS);
+              break;
+            case 1:
+            case 3:
+            case 5:
+            case 7:
+              MenMove (main_loop_pass>>4%PHASES_GROUPS);
+              break;
+          }
+        case 4:
+          break;
+        case 2:
+        case 6:
+          if (gun_on)
+            FireBullet;
+          break;
+        case 1:
+        case 3:
+        case 5:
+        case 7:
+          CheckCollisions;
+          break;
+      }
+      main_loop_pass++;
+
+      if (snd_timeout && tS>snd_timeout) {
+        snd_timeout=0;
+        Snd;
+      }
+      SleepUntil(next_update_jiffy);
+
+      total_score=3*(U_ENEMY_NUM-enemy_left)+5*enemy_by_friendly
+            -100*friendly_fire-10*(tS-t0)-bullets_fired;
+      if (game_over) {
+        tf=tS;
+        Sleep(750);
+        FlushMsgs;
+        while (!ScanKey(&ch)&&friendly_left||tS-tf<1.5) {
+          total_score+=250;
+          Snd(86); Sleep(150);
+          Snd;    Sleep(50);
+          friendly_left--;
+        }
+        total_score+=250*friendly_left;
+        if (total_score>best_score)
+          best_score=total_score;
+        if (!ch) ch=GetChar(,FALSE);
+        if (ch==CH_ESC||ch==CH_SHIFT_ESC)
+          goto to_done;
+        gun_on=FALSE;
+        Init;
+      }
+    }
+to_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  }
+  catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/Titanium","I64 best_score=%d;\n",best_score);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/AIs/Human.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/AIs/Human.HC.HTML new file mode 100755 index 0000000..de9d1cb --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/AIs/Human.HC.HTML @@ -0,0 +1,197 @@ + + + + + + + + + + + +
+U0 PlayerIndirect()
+{
+  Unit *tmpu=NULL;
+  I64 i,remaining=0,msg_code,arg1,arg2;
+  F64 target_x,target_y;
+  ViewPlayerSet(cur_player);
+  for (i=0;i<UNITS_NUM;i++) {
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0 && tmpu->indirect_fire)
+      remaining++;
+  }
+  while (remaining) {
+    if (!alive_cnt[0] || !alive_cnt[1])
+      throw('GameOver',TRUE);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        CharDo(arg1);
+        break;
+      case MSG_MS_L_DOWN:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (tmpu=UnitFind(cursor_row,cursor_col)) {
+            if (tmpu->player==enemy_player || tmpu->fired ||
+                  !tmpu->indirect_fire)
+              tmpu=NULL;
+            else {
+              RowCol2XY(&fire_radius_x,&fire_radius_y,tmpu->row,tmpu->col);
+              fire_radius=tmpu->range*2*HEX_RADIUS;
+            }
+          }
+        }
+        break;
+      case MSG_MS_L_UP:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          RowCol2XY(&target_x,&target_y,cursor_row,cursor_col);
+          if (!tmpu)
+            Beep;
+          else {
+            if (Sqrt(Sqr(fire_radius_x-target_x)+Sqr(fire_radius_y-target_y))>
+                  fire_radius)
+              Beep;
+            else {
+              IndirectAdd(tmpu,cursor_row,cursor_col);
+              remaining--;
+            }
+          }
+        }
+        tmpu=NULL;
+        fire_radius=0;
+        break;
+      case MSG_MS_R_UP:
+        if (CursorInWin(Fs,arg1,arg2))
+          throw('PhaseOvr',TRUE);
+        break;
+    }
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+U0 PlayerMove()
+{
+  Unit *tmpu=NULL;
+  I64 msg_code,arg1,arg2;
+  ViewPlayerSet(cur_player);
+  while (TRUE) {
+    if (!alive_cnt[0] || !alive_cnt[1])
+      throw('GameOver',TRUE);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        CharDo(arg1);
+        break;
+      case MSG_MS_L_DOWN:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (tmpu=UnitFind(cursor_row,cursor_col)) {
+            if (tmpu->player==enemy_player || !tmpu->remaining_movement)
+              tmpu=NULL;
+          }
+        }
+        break;
+      case MSG_MS_L_UP:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (!tmpu)
+            Beep;
+          else {
+            UnitMove(tmpu,arg1,arg2);
+            break;
+          }
+        }
+        tmpu=NULL;
+        break;
+      case MSG_MS_R_UP:
+        if (CursorInWin(Fs,arg1,arg2))
+          throw('PhaseOvr',TRUE);
+        break;
+    }
+  }
+}
+
+U0 PlayerDirect()
+{
+  Unit *tmpu=NULL,*target;
+  I64 msg_code,arg1,arg2;
+  ViewPlayerSet(cur_player);
+  while (TRUE) {
+    if (!alive_cnt[0] || !alive_cnt[1])
+      throw('GameOver',TRUE);
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
+          1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        CharDo(arg1);
+        break;
+      case MSG_MS_L_DOWN:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          if (tmpu=UnitFind(cursor_row,cursor_col)) {
+            if (tmpu->player==enemy_player || tmpu->fired ||
+                  tmpu->indirect_fire)
+              tmpu=NULL;
+            else {
+              VRSetUp(cur_player);
+              RowCol2XY(&fire_radius_x,&fire_radius_y,tmpu->row,tmpu->col);
+              fire_radius=tmpu->range*2*HEX_RADIUS;
+              VisRecalc(VR_ONE_FRIENDLY_UNIT,tmpu);
+            }
+          }
+        }
+        break;
+      case MSG_MS_L_UP:
+        if (CursorInWin(Fs,arg1,arg2)) {
+          arg1-=x0; arg2-=y0;
+          CursorUpdate(Fs,arg1,arg2);
+          target=UnitFind(cursor_row,cursor_col);
+          if (!tmpu)
+            Beep;
+          else {
+            if (!target || target->player!=enemy_player ||
+                  !Bt(&target->vis,0))
+              Beep;
+            else
+              UnitDirectFire(tmpu,target);
+            VisRecalc(VR_UPDATE_FRIENDLY_UNIT,tmpu);
+          }
+        }
+        tmpu=NULL;
+        fire_radius=0;
+        break;
+      case MSG_MS_R_UP:
+        if (CursorInWin(Fs,arg1,arg2))
+          throw('PhaseOvr',TRUE);
+        break;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/AIs/SimpleAI.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/AIs/SimpleAI.HC.HTML new file mode 100755 index 0000000..fad3384 --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/AIs/SimpleAI.HC.HTML @@ -0,0 +1,110 @@ + + + + + + + + + + + +
+Unit *UnitNearestFind(I64 row,I64 col,I64 player,Bool in_LOS,F64 range=-1)
+{
+  I64 i;
+  F64 dd,best_dd=F64_MAX,x1,y1,x2,y2;
+  Unit *best=NULL;
+//Sqrt() is slow, so work with squared distances.
+  if (range<0)
+    range=F64_MAX;
+  else
+    range*=range;
+  RowCol2XY(&x1,&y1,row,col);
+  for (i=0;i<UNITS_NUM;i++)
+    if (units[player][i].life>0) {
+      if (!in_LOS || LOS(row,col,units[player][i].row,units[player][i].col)) {
+        RowCol2XY(&x2,&y2,units[player][i].row,units[player][i].col);
+        dd=Sqr(x2-x1)+Sqr(y2-y1);
+        if (dd<=range && dd<best_dd) {
+          best=&units[player][i];
+          best_dd=dd;
+        }
+      }
+    }
+  return best;
+}
+
+U0 PlayerIndirect()
+{
+  Unit *target,*tmpu;
+  I64 i;
+  for (i=0;i<UNITS_NUM;i++) {
+    UserChk;
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0 && tmpu->indirect_fire &&
+          (target=UnitNearestFind(tmpu->row,tmpu->col,enemy_player,TRUE,
+          tmpu->range*2*HEX_RADIUS)))
+      IndirectAdd(tmpu,target->row,target->col);
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+U0 PlayerMove()
+{
+  Unit *target,*tmpu;
+  I64 i;
+  F64 x,y;
+  for (i=0;i<UNITS_NUM;i++) {
+    UserChk;
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0) {
+//Cheats because it violates Line-of-Sight
+      if (target=UnitNearestFind(tmpu->row,tmpu->col,enemy_player,FALSE)) {
+        RowCol2XY(&x,&y,target->row,target->col);
+        if (!UnitMove(tmpu,x,y)) {
+          RowCol2XY(&x,&y,tmpu->row,tmpu->col);
+          UnitMove(tmpu,x+RandI16,y+RandI16);
+        }
+      }
+    }
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+U0 PlayerDirect()
+{
+  Unit *target,*tmpu;
+  I64 i;
+  for (i=0;i<UNITS_NUM;i++) {
+    UserChk;
+    tmpu=&units[cur_player][i];
+    if (tmpu->life>0 && !tmpu->indirect_fire &&
+          (target=UnitNearestFind(tmpu->row,tmpu->col,enemy_player,TRUE,
+          tmpu->range*2*HEX_RADIUS))) {
+      UnitDirectFire(tmpu,target);
+      Sleep(250*animation_delay);
+    }
+  }
+  throw('PhaseOvr',TRUE);
+}
+
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/Install.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/Install.HC.HTML new file mode 100755 index 0000000..061d29a --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/Install.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+DirMk("~/ToTheFront");
+
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/Load.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/Load.HC.HTML new file mode 100755 index 0000000..4f61c33 --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/Load.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "TTFGlbls"
+#include "TTFLib"
+#include "TTFInit"
+#include "TTFVis"
+#include "TTFFire"
+#include "TTFMove"
+#include "TTFDraw"
+#include "ToTheFront"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/Run.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/Run.HC.HTML new file mode 100755 index 0000000..d5240cf --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+ToTheFront;
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/TTFDraw.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/TTFDraw.HC.HTML new file mode 100755 index 0000000..ce35e29 --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/TTFDraw.HC.HTML @@ -0,0 +1,243 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+U0 UnitDraw(CDC *dc,Unit *tmpu,I64 x,I64 y,F64 f)
+{
+  x+=x0; y+=y0;
+  if (tmpu->infantry)
+    Sprite3(dc,x,y,0,tmpu->img);
+  else
+    Sprite3ZB(dc,x,y,0,tmpu->img,f);
+  if (phase&~1==PHASE_INDIRECT && tmpu->indirect_fire &&
+        !tmpu->fired && tmpu->player==cur_player) {
+    dc->thick=2;
+    if (cur_player)
+      dc->color=PURPLE;
+    else
+      dc->color=CYAN;
+    GrCircle3(dc,x,y,0,20*Saw(4*tS,2.0));
+    GrCircle3(dc,x,y,0,20*Saw(4*tS+1.0,2.0));
+    dc->thick=1;
+  }
+}
+
+U0 UnitsDraw(CDC *dc)
+{
+  I64 i,j;
+  F64 x,y;
+  Unit *tmpu;
+  for (j=0;j<2;j++) {
+    for (i=0;i<UNITS_NUM;i++) {
+      tmpu=&units[j][i];
+      if (tmpu==target_unit) {
+        if (target_hit)
+          dc->color=RED;
+        else
+          dc->color=GREEN;
+      } else {
+        if (j)
+          dc->color=LTPURPLE;
+        else
+          dc->color=LTCYAN;
+      }
+      if (tmpu->life>0 && Bt(&tmpu->vis[view_player],0) &&
+            tmpu!=moving_unit) {
+        RowCol2XY(&x,&y,tmpu->row,tmpu->col);
+        if (phase&~1==PHASE_MOVE && tmpu->remaining_movement ||
+              (phase&~1==PHASE_INDIRECT&& tmpu->indirect_fire||
+              phase&~1==PHASE_DIRECT&&!tmpu->indirect_fire) && !tmpu->fired ||
+              Blink(5))
+          UnitDraw(dc,tmpu,x,y,tmpu->facing*60.0*pi/180.0);
+      }
+    }
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 x,y;
+  I64 i,j,r,c;
+  U8 buf[STR_LEN];
+  IndirectOrders *tmpi;
+
+  //Erase text beneath.
+  dc->color=WHITE;
+  GrRect(dc,-task->scroll_x,-task->scroll_y,dc->width,dc->height);
+
+  map_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,x0,y0,map_dc);
+
+  i=ms.pos.x-task->pix_left-task->scroll_x;
+  j=ms.pos.y-task->pix_top -task->scroll_y;
+  if (CursorInWin(task,i,j)) {
+    i-=x0; j-=y0;
+    CursorUpdate(task,i,j);
+  }
+  RowCol2XY(&x,&y,cursor_row,cursor_col);
+
+  //Roads require multiple cursor fills
+  dc->color=YELLOW;
+  c=terrain[cursor_row][cursor_col];
+  for (i=-(HEX_SIDE+DCOS)/2;i<=(HEX_SIDE+DCOS)/2;i++) {
+    if (GrPeek(dc,x+i+x0,y+y0)==c)
+      GrFloodFill(dc,x+i+x0,y+y0);
+    for (j=-HEX_SIDE/2;j<=HEX_SIDE/2;j++)
+      if (GrPeek(dc,x+j+x0,y+i+y0)==c)
+        GrFloodFill(dc,x+j+x0,y+i+y0);
+  }
+
+  UnitsDraw(dc);
+  if (firing) {
+    dc->color=BLACK;
+    GrCircle(dc,fire_x+x0,fire_y+y0,2);
+  }
+  if (indirect_explosion) {
+    for (i=0;i<7;i++) {
+      if (indirect_row&1)
+        c=indirect_col+col_offsets_odd[i];
+      else
+        c=indirect_col+col_offsets_even[i];
+      r=indirect_row+row_offsets[i];
+      if (0<=r<map_rows && 0<=c<map_cols) {
+        RowCol2XY(&x,&y,r,c);
+        for (j=0;j<10;j++)  {
+          if (j&1)
+            dc->color=LTRED;
+          else
+            dc->color=YELLOW;
+          GrCircle(dc,x+RandU16%HEX_SIDE-HEX_SIDE/2+x0,
+                y+RandU16%HEX_SIDE-HEX_SIDE/2+y0,2);
+        }
+      }
+    }
+  }
+  if (moving_unit && moving_unit->vis[view_player]) {
+    dc->color=YELLOW;
+    UnitDraw(dc,moving_unit,move_x,move_y,move_facing);
+  }
+  ProgressBarsRst;
+  if (moving_unit) {
+    if (ms.pos.y<GR_HEIGHT/2) {
+      progress4_max=moving_unit->movement;
+      progress4=moving_unit->remaining_movement;
+    } else {
+      progress1_max=moving_unit->movement;
+      progress1=moving_unit->remaining_movement;
+    }
+  }
+  if (fire_radius) {
+    dc->color=YELLOW;
+    GrCircle(dc,fire_radius_x+x0,fire_radius_y+y0,fire_radius-1);
+    GrCircle(dc,fire_radius_x+x0,fire_radius_y+y0,fire_radius+1);
+    dc->color=RED;
+    GrCircle(dc,fire_radius_x+x0,fire_radius_y+y0,fire_radius);
+  }
+  if (Blink(10)) {
+    tmpi=indirect_head.next;
+    while (tmpi!=&indirect_head) {
+      if (tmpi->attacker->player==view_player) {
+        RowCol2XY(&x,&y,tmpi->row,tmpi->col);
+        Sprite3(dc,x+x0,y+y0,0,<1>);
+      }
+      tmpi=tmpi->next;
+    }
+  }
+  if (Bt(kbd.down_bitmap,SC_SHIFT)) {
+    if (show_vis_row!=cursor_row || show_vis_col!=cursor_col) {
+      show_vis_row=cursor_row;
+      show_vis_col=cursor_col;
+      VisRecalcMap(show_vis_row,show_vis_col);
+    }
+
+    dc->color=LTGRAY;
+    for (j=0;j<map_rows;j++)
+      for (i=0;i<map_cols;i++)
+        if (!vis_map[j][i]) {
+          RowCol2XY(&x,&y,j,i);
+          GrLine(dc,x-6+x0,y-6+y0,x+6+x0,y+6+y0);
+          GrLine(dc,x+6+x0,y-6+y0,x-6+x0,y+6+y0);
+          GrLine(dc,x+x0,y-6+y0,x+x0,y+6+y0);
+          GrLine(dc,x+6+x0,y+y0,x-6+x0,y+y0);
+        }
+  }
+  if (i=StrLen(msg_buf)*FONT_WIDTH) {
+    dc->color=BLACK;
+    GrRect(dc,(task->pix_width-i)>>1-10-task->scroll_x,
+          (task->pix_height-FONT_HEIGHT)>>1-10-task->scroll_y,
+          i+20,FONT_HEIGHT+20);
+
+    dc->color=YELLOW;
+    GrRect(dc,(task->pix_width-i)>>1-7-task->scroll_x,
+          (task->pix_height-FONT_HEIGHT)>>1-7-task->scroll_y,
+          i+14,FONT_HEIGHT+14);
+
+    dc->color=RED;
+    GrPrint(dc,(task->pix_width-i)>>1-task->scroll_x,
+          (task->pix_height-FONT_HEIGHT)>>1-task->scroll_y,
+          msg_buf);
+    if (msg_off_timeout) {
+      if (msg_off_timeout-cnts.jiffies<3*JIFFY_FREQ/2*animation_delay)
+        Snd;
+      if (cnts.jiffies>msg_off_timeout)
+        *msg_buf=0;
+    }
+  }
+
+  dc->color=WHITE;
+  GrRect(dc,-task->scroll_x,-task->scroll_y,
+        (13+7+10+10)*FONT_WIDTH,FONT_HEIGHT);
+
+  if (phase&~1==PHASE_INDIRECT)
+    StrPrint(buf,"Turn:%2d Artillery",turn);
+  else if (phase&~1==PHASE_MOVE)
+    StrPrint(buf,"Turn:%2d Move",turn);
+  else
+    StrPrint(buf,"Turn:%2d Fire",turn);
+  dc->color=BLACK;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y,buf);
+
+  StrPrint(buf,"%3d Units",alive_cnt[0]);
+  if (cur_player || Blink)
+    dc->color=CYAN;
+  else
+    dc->color=LTCYAN;
+  GrPrint(dc,-task->scroll_x+(13+7)*FONT_WIDTH,-task->scroll_y,buf);
+
+  StrPrint(buf,"%3d Units",alive_cnt[1]);
+  if (!cur_player || Blink)
+    dc->color=PURPLE;
+  else
+    dc->color=LTPURPLE;
+  GrPrint(dc,-task->scroll_x+(13+7+10)*FONT_WIDTH,-task->scroll_y,buf);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/TTFFire.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/TTFFire.HC.HTML new file mode 100755 index 0000000..34dd67d --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/TTFFire.HC.HTML @@ -0,0 +1,309 @@ + + + + + + + + + + + +
+U0 AttackHeader(Unit *tmpu,U8 *st,Unit *target)
+{
+  I64 i=9+StrLen(st);
+  if (target) {
+    i+=9;
+    if (target->armor)
+      i+=8;
+    else
+      i+=10;
+  }
+  '\n\n';
+  "$BLACK$%h*c$FG$\n",i,'-';
+  if (tmpu->player)
+    "$PURPLE$Player 2$FG$ ";
+  else
+    "$CYAN$Player 1$FG$ ";
+  "%s",st;
+  if (target) {
+    if (target->player)
+      " $PURPLE$Player 2";
+    else
+      " $CYAN$Player 1";
+    if (target->armor)
+      " Armored";
+    else
+      " Unarmored";
+    '$FG$';
+  }
+  '\n';
+  "$BLACK$%h*c$FG$\n",i,'-';
+}
+
+F64 HitDamage(Unit *tmpu,Unit *target,I64 facing=1,F64 range_factor=0)
+{
+  F64 d,res=200.0*Rand;
+  "\nRoll Out of 200\t\t:%6.2f Damage\n",res;
+  if (target->armor) {
+    d=target->armor/100.0*(5-facing)/5.0;
+    if (d>=0) {
+      "Armor Attack\t\t:%6.2f\n",ToF64(tmpu->armored_attack);
+      res*=(tmpu->armored_attack/100.0)/d;
+    } else
+      res=0;
+    "Armor(%z) Defense\t:%6.2f\n",facing,
+          "Front\0FrontSide\0RearSide\0Rear\0",100*d;
+  } else {
+    d=1.0-range_factor;
+    if (d>0) {
+      "Unarmored Attack\t:%6.2f\n",ToF64(tmpu->unarmored_attack);
+      "Range Adjust\t\t:%6.2f%%\n",100*d;
+      res*=(tmpu->unarmored_attack/100.0)*d;
+    } else
+      res=0;
+  }
+  "Attack/Defense Adjusted\t:%6.2f Damage\n",res;
+  return Round(res);
+}
+
+Bool DamageDo(Unit *target,F64 damage)
+{
+  if (damage>0) {
+    if (target->armor)
+      "Armor Hit Score %6.2f\t:",damage;
+    else
+      "%3d Life - %3f Damage\t=",target->life,damage;
+    if (damage>=target->life) {
+      "$RED$Killed$FG$\n";
+      Noise(1000*animation_delay,74,98);
+      Sleep(1000*animation_delay);
+      target->life=0;
+      VisRecalc(VR_FRIENDLY_UNIT_DIED,target);
+      alive_cnt[target->player]--;
+      return TRUE;
+    } else {
+      if (target->armor) {
+        if (damage>0.6*target->life) {
+          target->movement=0;
+          "$RED$Immobilized$FG$\n";
+        } else
+          "$GREEN$No Penetration$FG$\n";
+      } else {
+        target->life-=damage;
+        "$RED$%6.2f Life$FG$\n",ToF64(target->life);
+      }
+      return FALSE;
+    }
+  } else
+    return FALSE;
+}
+
+U0 IndirectAdd(Unit *tmpu,I64 row,I64 col)
+{
+  IndirectOrders *tmpi;
+  if (tmpu->life<=0 || tmpu->range<=0)
+    return;
+  tmpu->fired=TRUE;
+  tmpi=CAlloc(sizeof(IndirectOrders));
+  tmpi->attacker=tmpu;
+  tmpi->row=row;
+  tmpi->col=col;
+  QueIns(tmpi,indirect_head.last);
+}
+
+Bool BulletPlot(U0,I64 x,I64 y,I64)
+{
+  fire_x=x; fire_y=y;
+  firing=TRUE;
+  Sleep(3*animation_delay);
+  return TRUE;
+}
+
+U0 UnitDirectFire(Unit *tmpu,Unit *target)
+{
+  I64 r,c,facing,
+        t1=terrain[tmpu->row][tmpu->col],t2=terrain[target->row][target->col];
+  F64 x1,y1,x2,y2,d,a,range_factor;
+  if (tmpu->life<=0 || target->life<=0 || tmpu->range<=0)
+    return;
+  AttackHeader(tmpu,"DirectFire",target);
+  RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
+  RowCol2XY(&x2,&y2,target->row,target->col);
+  d=100*Rand;
+  "+%5.2f  Roll\n",d;
+  d+=tmpu->accuracy;
+  "+%2d.00  Accuracy\n",tmpu->accuracy;
+
+  range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);
+  "-%5.2f%% of Range\n",100*range_factor;
+  d-=100*range_factor;
+  if (t2==TREES) {
+    "-30.00  Target in Trees Penalty\n";
+    d-=30;
+  }
+  if (t1==MOUNTAINS && t2!=MOUNTAINS) {
+    "+30.00  High Ground Bonus\n";
+    d+=30;
+  }
+  "_______\n";
+  target_unit=target;
+  if (d>=0) {
+    "+%5.2f  Hit\n",d;
+    target_hit=TRUE;
+    Noise(500*animation_delay,34,41);
+    Sleep(500*animation_delay);
+    Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);
+  } else {
+    "-%5.2f  Miss\n",-d;
+    target_hit=FALSE;
+    Noise(1000*animation_delay,69,74);
+    Sleep(1000*animation_delay);
+    a=pi*2*Rand;
+    d=(0.5-d/100)*HEX_SIDE;
+    Line(NULL,x1,y1,0,x2+d*Cos(a),y2+d*Sin(a),0,&BulletPlot);
+  }
+  firing=FALSE;
+  tmpu->fired=TRUE;
+  if (target_hit) {
+    r=target->row;c=target->col;
+    if ((facing=HexMoveOne(&r,&c,x1,y1))>=0)
+      facing=FacingChg(facing,target->facing);
+    else
+      facing=0;
+    DamageDo(target,HitDamage(tmpu,target,facing,range_factor));
+  }
+  while (scrncast.ona) //see Snd()
+    Yield;
+  target_unit=NULL;
+}
+
+Bool HexOccupy(Bool overrun,Unit *tmpu,Unit *target)
+{
+  I64 t2=terrain[target->row][target->col];
+  F64 damage;
+  if (tmpu->life<=0 || target->life<=0)
+    return FALSE;
+  if (overrun)
+    AttackHeader(tmpu,"OverRun",target);
+  else
+    AttackHeader(tmpu,"CloseAssault",target);
+  Noise(500*animation_delay,34,41);
+  Sleep(500*animation_delay);
+  tmpu->fired=TRUE;
+  target->fired=TRUE;
+  damage=HitDamage(tmpu,target);
+  if (overrun) {
+    damage*=2.0;
+    "x2 OverRun Bonus\t=%6.2f Damage\n",damage;
+    if (t2!=PLAINS) {
+      damage/=2.0;
+      "/2 Terrain Penalty\t=%6.2f Damage\n",damage;
+    }
+  } else {
+    damage*=3.0;
+    "x3 CloseAssault Bonus\t=%6.2f Damage\n",damage;
+  }
+  if (DamageDo(target,Round(damage))) {
+    "$RED$Success$FG$\n";
+    while (scrncast.ona) //see Snd()
+      Yield;
+    return TRUE;
+  } else {
+    tmpu->life=0;
+    VisRecalc(VR_FRIENDLY_UNIT_DIED,tmpu);
+    alive_cnt[tmpu->player]--;
+    "$RED$Failure$FG$\n";
+    while (scrncast.ona) //see Snd()
+      Yield;
+    return FALSE;
+  }
+}
+
+U0 IndirectResolveAll()
+{
+  I64 i,r,c;
+  F64 x1,y1,x2,y2,d,range_factor;
+  Unit *tmpu,*target;
+  IndirectOrders *tmpi=indirect_head.next,*tmpi1;
+  while (tmpi!=*indirect_head) {
+    tmpi1=tmpi->next;
+    tmpu=tmpi->attacker;
+    AttackHeader(tmpu,"IndirectFire",NULL);
+    RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
+    RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);
+    d=100*Rand;
+    "+%5.2f  Roll\n",d;
+    d+=tmpu->accuracy;
+    "+%2d.00  Accuracy\n",tmpu->accuracy;
+    range_factor=Sqrt(Sqr(x2-x1)+Sqr(y2-y1))/(tmpu->range*2*DSIN);
+    "-%5.2f%% of Range\n",100*range_factor;
+    d-=100*range_factor;
+    '_______\n';
+
+
+    if (d>=0) {
+      "+%5.2f  Hit\n",d;
+      Noise(500*animation_delay,34,41);
+      Sleep(500*animation_delay);
+    } else {
+      "-%5.2f  Miss\n",-d;
+      Noise(1000*animation_delay,69,74);
+      Sleep(1000*animation_delay);
+      i=RandU16%6;
+      if (tmpi->row&1)
+        tmpi->col+=col_offsets_odd[i];
+      else
+        tmpi->col+=col_offsets_even[i];
+      tmpi->row+=row_offsets[i];
+      RowCol2XY(&x2,&y2,tmpi->row,tmpi->col);
+    }
+
+    Line(NULL,x1,y1,0,x2,y2,0,&BulletPlot);
+    firing=FALSE;
+    tmpu->fired=TRUE;
+    indirect_row=tmpi->row;
+    indirect_col=tmpi->col;
+    indirect_explosion=TRUE;
+    for (i=0;i<7;i++) {
+      if (tmpi->row&1)
+        c=tmpi->col+col_offsets_odd[i];
+      else
+        c=tmpi->col+col_offsets_even[i];
+      r=tmpi->row+row_offsets[i];
+      if (0<=r<map_rows && 0<=c<map_cols && (target=UnitFind(r,c))) {
+        AttackHeader(tmpu,"IndirectFire",target);
+        DamageDo(target,HitDamage(tmpu,target));
+      }
+    }
+    Noise(2000*animation_delay,70,74);
+    Sleep(2000*animation_delay);
+    while (scrncast.ona) //see Snd()
+      Yield;
+    indirect_explosion=FALSE;
+
+    QueRem(tmpi);
+    Free(tmpi);
+    tmpi=tmpi1;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/TTFGlbls.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/TTFGlbls.HC.HTML new file mode 100755 index 0000000..dfaf2b7 --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/TTFGlbls.HC.HTML @@ -0,0 +1,139 @@ + + + + + + + + + + + +
+#define MAP_WIDTH               640     //Change this, if you like.
+#define UNITS_NUM               32      //Change this, if you like.
+#define HEX_SIDE                11
+
+U0 InitDefines()
+{
+  DefinePrint("MAP_HEIGHT","%d",(GR_HEIGHT-FONT_HEIGHT*2)*MAP_WIDTH/GR_WIDTH);
+  DefinePrint("DCOS",      "%12.9f",    HEX_SIDE*Cos(60.0/180*pi));
+  DefinePrint("DSIN",      "%12.9f",    HEX_SIDE*Sin(60.0/180*pi));
+  DefinePrint("HEX_RADIUS","%12.9f",    HEX_SIDE*Sin(60.0/180*pi)+0.01); //Slop
+} InitDefines;
+
+I64     map_cols=(MAP_WIDTH-DCOS)/(2*HEX_SIDE+2*DCOS),
+        map_rows=ToI64((MAP_HEIGHT-DSIN)/DSIN)&~1,
+        map_width=map_cols*(2*HEX_SIDE+2*DCOS)+DCOS,
+        map_height=map_rows*DSIN+DSIN+1,
+        x0,y0;
+
+CDC     *map_dc;
+U8      terrain[map_rows][map_cols];
+
+//Centers of hexes
+class Pt
+{
+  F64 x,y;
+};
+Pt      hex_centers[map_rows][map_cols];
+
+I64     show_vis_row,show_vis_col;
+Bool    roads[map_rows][map_cols],
+        rivers[map_rows][map_cols],
+        vis_map[map_rows][map_cols];
+
+//Other options for PLAINS are WHITE or YELLOW
+#define PLAINS          LTGREEN
+#define TREES           GREEN
+#define MOUNTAINS       DKGRAY
+
+//These are used to display a range circle when they player
+//is firing.
+F64     fire_radius,fire_radius_x,fire_radius_y;
+
+//These display "phase", "turn" and "game over".
+U8      msg_buf[STR_LEN];
+I64     msg_off_timeout; //Jiffies. Goes away after a time.
+
+//Unit types
+#define UT_INFANTRY     0
+#define UT_ARTILLERY    1
+#define UT_LT_TANK      2
+#define UT_MD_TANK      3
+
+class Unit
+{
+  U8    *img;
+  I64   num,row,col,
+        armored_attack,unarmored_attack,armor;
+  I8    type,player,facing,movement,life,
+        range,remaining_movement,accuracy;
+  Bool  vis[2],fired,infantry,indirect_fire,pad[3];
+};
+
+Unit    units[2][UNITS_NUM];
+
+// Bt(vis_unit_bitmap,player1+player0*((UNITS_NUM+7)&~7))
+U8      vis_unit_bitmap[2][(((UNITS_NUM+7)&~7)*UNITS_NUM)>>3];
+
+#define PHASE_START     0
+#define PHASE_INDIRECT  0
+#define PHASE_INDIRECT0 0
+#define PHASE_INDIRECT1 1
+#define PHASE_MOVE      2
+#define PHASE_MOVE0     2
+#define PHASE_MOVE1     3
+#define PHASE_DIRECT    4
+#define PHASE_DIRECT0   4
+#define PHASE_DIRECT1   5
+#define PHASE_END       6
+
+I64     phase,cur_player,enemy_player,view_player,turn,
+        cursor_row,cursor_col,alive_cnt[2],
+        player_indirect[2],player_move[2],player_direct[2];
+F64     animation_delay=0.5;
+
+Bool    moving=FALSE;
+I64     move_x,move_y;
+F64     move_facing;
+Unit    *moving_unit;
+extern I64 HexMoveOne(I64 *_row,I64 *_col,F64 x,F64 y);
+
+class IndirectOrders
+{
+  IndirectOrders *next,*last;
+  Unit  *attacker;
+  I64   row,col;
+} indirect_head;
+
+Bool    firing=FALSE;
+I64     fire_x,fire_y;
+Unit    *target_unit;
+Bool    target_hit;
+
+Bool    indirect_explosion=FALSE;
+I64     indirect_row,indirect_col;
+
+I64     row_offsets[7]={-1,-2,-1,1,2,1,0};
+I64     col_offsets_even[7]={-1, 0, 0,0,0,-1,0};
+I64     col_offsets_odd [7]={ 0, 0, 1,1,0, 0,0};
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/TTFInit.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/TTFInit.HC.HTML new file mode 100755 index 0000000..14a171c --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/TTFInit.HC.HTML @@ -0,0 +1,445 @@ + + + + + + + + + + + +
+/*I got tricky by not defining a color
+right away in these CSprites so they can
+work for both players by setting dc->color
+before drawing them.  I actually made these
+graphics by defining a color in the <CTRL-r>
+menu, drawing the unit and deleting the color.
+
+I had to leave a gap between the tank tread
+and body because of how it is rendered when rotated.
+*/
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+//This is an infantry.
+
+<3>/* Graphics Not Rendered in HTML */
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+U0 DrawHexes()
+{
+  F64 dx=2*HEX_SIDE+2*DCOS,dy=2*DSIN,
+        x,y,x1,y1,x2,y2;
+  I64 i,j;
+  map_dc->color=WHITE;
+  GrRect(map_dc,0,0,map_dc->width,map_dc->height);
+  map_dc->color=BLACK;
+  y=0;
+  for (j=0;j<map_rows;j+=2) {
+    x=DCOS;
+    GrLine(map_dc,x,y,x-DCOS,y+DSIN);
+    GrLine(map_dc,x-DCOS,y+DSIN,x,y+2*DSIN);
+    for (i=0;i<map_cols;i++) {
+      x1=x; y1=y;
+      x2=x1+HEX_SIDE; y2=y1;
+      GrLine(map_dc,x1,y1,x2,y2);
+      x1=x2; y1=y2;
+      x2+=DCOS; y2+=DSIN;
+      GrLine(map_dc,x1,y1,x2,y2);
+      GrLine(map_dc,x2,y2,x2-DCOS,y2+DSIN);
+      x1=x2; y1=y2;
+      x2+=HEX_SIDE;
+      GrLine(map_dc,x1,y1,x2,y2);
+      GrLine(map_dc,x2,y2,x2+DCOS,y2+DSIN);
+      x1=x2; y1=y2;
+      x2+=DCOS; y2-=DSIN;
+      if (j || i<map_cols-1)
+        GrLine(map_dc,x1,y1,x2,y2);
+      x+=dx;
+    }
+    y+=dy;
+  }
+  x=DCOS;
+  for (i=0;i<map_cols;i++) {
+    x1=x; y1=y;
+    x2=x1+HEX_SIDE; y2=y1;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x1=x2; y1=y2;
+    x2+=DCOS; y2+=DSIN;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x1=x2; y1=y2;
+    x2+=HEX_SIDE;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x1=x2; y1=y2;
+    x2+=DCOS; y2-=DSIN;
+    GrLine(map_dc,x1,y1,x2,y2);
+    x+=dx;
+  }
+}
+
+U0 MakeTerrain(U8 color,I64 cnt,I64 clus_lo,I64 clus_hi)
+{
+  I64 i,j,l,row,col;
+  for (i=0;i<cnt;i++) {
+    col=RandU32%map_cols;
+    row=RandU32%map_rows;
+    l=clus_lo+RandU16%(clus_hi-clus_lo+1);
+    for (j=0;j<l;j++) {
+      terrain[row][col]=color;
+      Toward(&row,&col,RandU16%6);
+      col=ClampI64(col,0,map_cols-1);
+      row=ClampI64(row,0,map_rows-1);
+    }
+  }
+}
+
+U0 MakeRivers()
+{
+  I64 i,row,col,direction;
+  for (i=0;i<4;i++) {
+    row=RandU32%map_rows;
+    col=RandU32%map_cols;
+    direction=RandU16%6;
+    while (TRUE) {
+      rivers[row][col]=TRUE;
+      Toward(&row,&col,direction);
+      if (!(0<=row<map_rows && 0<=col<map_cols))
+        break;
+      if (!(RandU16&3))
+        direction=(direction+(7-RandU16%3))%6;
+    }
+  }
+}
+
+U0 MakeRoads()
+{
+  I64 i,row,col,direction;
+  for (i=0;i<5;i++) {
+    row=RandU32%map_rows;
+    col=RandU32%map_cols;
+    direction=RandU16%6;
+    while (TRUE) {
+      roads[row][col]=TRUE;
+      Toward(&row,&col,direction);
+      if (!(0<=row<map_rows && 0<=col<map_cols))
+        break;
+      if (!(RandU16%3))
+        direction=(direction+(7-RandU16%3))%6;
+    }
+  }
+}
+
+U0 DrawTerrain()
+{
+  I64 i,j;
+  F64 x,y;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      map_dc->color=terrain[j][i];
+      RowCol2XY(&x,&y,j,i);
+      GrFloodFill(map_dc,x,y);
+    }
+}
+
+U0 DrawRivers()
+{
+  I64 i,j,k,r,c;
+  F64 x1,y1,x2,y2;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      if (rivers[j][i]) {
+        RowCol2XY(&x1,&y1,j,i);
+        for (k=0;k<6;k++) {
+          r=j;c=i;
+          Toward(&r,&c,k);
+          if (0<=r<map_rows && 0<=c<map_cols &&
+                rivers[r][c]) {
+            RowCol2XY(&x2,&y2,r,c);
+            map_dc->color=LTBLUE;
+            map_dc->thick=4;
+            GrLine3(map_dc,x1,y1,0,x2,y2,0);
+            map_dc->color=BLUE;
+            map_dc->thick=2;
+            GrLine3(map_dc,x1,y1,0,x2,y2,0);
+          }
+        }
+      }
+    }
+}
+
+U0 DrawRoads()
+{
+  I64 i,j,k,r,c;
+  F64 x1,y1,x2,y2;
+  map_dc->color=RED;
+  map_dc->thick=3;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      if (roads[j][i]) {
+        RowCol2XY(&x1,&y1,j,i);
+        for (k=0;k<6;k++) {
+          r=j;c=i;
+          Toward(&r,&c,k);
+          if (0<=r<map_rows && 0<=c<map_cols &&
+                roads[r][c]) {
+            RowCol2XY(&x2,&y2,r,c);
+            GrLine3(map_dc,x1,y1,0,x2,y2,0);
+          }
+        }
+      }
+    }
+}
+
+U0 DrawDots()
+{
+  I64 i,j;
+  F64 x,y;
+  map_dc->color=BLACK;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      RowCol2XY(&x,&y,j,i);
+      GrPlot(map_dc,x,y);
+    }
+}
+
+U0 HexCentersCalc()
+{
+  I64 i,j;
+  F64 x,y;
+  for (j=0;j<map_rows;j++)
+    for (i=0;i<map_cols;i++) {
+      x=(2*HEX_SIDE+2*DCOS)*i+HEX_SIDE/2+DCOS;
+      if (j&1)
+        x+=HEX_SIDE+DCOS;
+      y=DSIN*(j+1);
+      hex_centers[j][i].x=x;
+      hex_centers[j][i].y=y;
+    }
+}
+
+U0 InitMap()
+{
+  HexCentersCalc;
+  DrawHexes;
+  MemSet(terrain,PLAINS,sizeof(terrain));
+  MemSet(roads,FALSE,sizeof(roads));
+  MemSet(rivers,FALSE,sizeof(rivers));
+  MemSet(vis_map,FALSE,sizeof(vis_map));
+  MakeTerrain(MOUNTAINS,0.03*map_cols*map_cols,5,35);
+  MakeTerrain(TREES,0.03*map_cols*map_cols,5,35);
+  DrawTerrain;
+  MakeRivers;
+  DrawRivers;
+  MakeRoads;
+  DrawRoads;
+  DrawDots;
+}
+
+U0 InitUnits()
+{
+  I64 i,j,row,col,type;
+  Unit *tmpu;
+  MemSet(units,0,sizeof(units));
+  alive_cnt[0]=alive_cnt[1]=UNITS_NUM;
+  for (j=0;j<2;j++)
+    for (i=0;i<alive_cnt[j];i++) {
+      tmpu=&units[j][i];
+      tmpu->player=j;
+      tmpu->num=i;
+      tmpu->life=100;
+      tmpu->facing=RandU16%6;
+      if (!j) {
+        if (i>=UNITS_NUM/2) {
+          if (i>=15*UNITS_NUM/16)
+            type=UT_ARTILLERY;
+          else
+            type=UT_INFANTRY;
+        } else {
+          if (i>=UNITS_NUM/4)
+            type=UT_MD_TANK;
+          else
+            type=UT_LT_TANK;
+        }
+      } else {
+        if (i>=UNITS_NUM/2) {
+          if (i>=15*UNITS_NUM/16)
+            type=UT_ARTILLERY;
+          else
+            type=UT_INFANTRY;
+        } else {
+          if (i>=UNITS_NUM/4)
+            type=UT_MD_TANK;
+          else
+            type=UT_LT_TANK;
+        }
+      }
+      tmpu->type=type;
+      switch (type) {
+        case UT_INFANTRY:
+          tmpu->infantry=TRUE;
+          tmpu->indirect_fire=FALSE;
+          tmpu->armor    =0;
+          tmpu->armored_attack  =15;
+          tmpu->unarmored_attack=180;
+          tmpu->accuracy=45;
+          tmpu->range    =5;
+          tmpu->movement=4;
+          tmpu->img      =<1>;
+          break;
+        case UT_ARTILLERY:
+          tmpu->infantry=TRUE;
+          tmpu->indirect_fire=TRUE;
+          tmpu->armor    =0;
+          tmpu->armored_attack  =60;
+          tmpu->unarmored_attack=180;
+          tmpu->accuracy=25;
+          tmpu->range    =20;
+          tmpu->movement=2;
+          tmpu->img      =<2>;
+          break;
+        case UT_LT_TANK:
+          tmpu->infantry=FALSE;
+          tmpu->indirect_fire=FALSE;
+          tmpu->armor    =30;
+          tmpu->armored_attack  =40;
+          tmpu->unarmored_attack=60;
+          tmpu->accuracy=25;
+          tmpu->range    =8;
+          tmpu->movement=24;
+          tmpu->img      =<3>;
+          break;
+        case UT_MD_TANK:
+          tmpu->infantry=FALSE;
+          tmpu->indirect_fire=FALSE;
+          tmpu->armor    =60;
+          tmpu->armored_attack  =60;
+          tmpu->unarmored_attack=80;
+          tmpu->accuracy=25;
+          tmpu->range    =12;
+          tmpu->movement=16;
+          tmpu->img      =<4>;
+          break;
+      }
+      do {
+        row=RandU32%map_rows;
+        col=RandU32%(map_cols/3);
+        if (j)
+          col+=2*map_cols/3;
+      } while (UnitFind(row,col));
+      tmpu->row=row;
+      tmpu->col=col;
+      LBts(&tmpu->vis[cur_player],0);
+    }
+}
+
+U0 ViewPlayerSet(I8 p)
+{
+  CMenuEntry *tmpse;
+  view_player=p;
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Player1"))
+    tmpse->checked= view_player==0;
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"View/Player2"))
+    tmpse->checked= view_player==1;
+}
+
+U0 Init()
+{
+  DocClear;
+  "GameSeed(0x%X)\n",Seed(PopUpGetI64("GameSeed(0x%X):",Seed));
+  moving_unit=NULL;
+  InitMap;
+  ViewPlayerSet(cur_player=0);
+  enemy_player=1;
+  if (map_width<GR_WIDTH) {
+    x0=(MAP_WIDTH-map_width)>>1;
+    y0=(MAP_HEIGHT-map_height)>>1+FONT_HEIGHT;
+  } else {
+    x0=0;
+    y0=FONT_HEIGHT;
+  }
+  InitUnits;
+  QueInit(&indirect_head);
+  turn=0;
+  fire_radius=0;
+  show_vis_row=-1;
+  show_vis_col=-1;
+  *msg_buf=0;
+  msg_off_timeout=0;
+  phase=PHASE_END;
+}
+
+U0 CleanUp()
+{
+  QueDel(&indirect_head,TRUE);
+}
+
+U0 PlayerPick(U8 *dirname,I64 player)
+{
+  I64 i=0;
+  U8 *st;
+  CDirEntry *tmpde,*tmpde1,*tmpde2;
+  CDoc *doc=DocNew;
+  Bool *old_silent=Silent;
+  st=MStrPrint("%s/*.HC*",dirname);
+  tmpde=FilesFind(st);
+  Free(st);
+  tmpde2=FilesFind("~/ToTheFront/*.HC*");
+  tmpde1=tmpde;
+  Silent(old_silent);
+
+  DocPrint(doc,"Player %d Type\n\n$LTBLUE$",player+1);
+  while (tmpde1) {
+    if (!(i++&3))
+      DocPrint(doc,"\n");
+    st=StrNew(tmpde1->name);
+    FileExtRem(st);
+    tmpde1->user_data=DocPrint(doc,"$MU-UL,\"%-10ts\",LE=%d$ ",st,tmpde1);
+    Free(st);
+    tmpde1=tmpde1->next;
+  }
+  tmpde1=tmpde2;
+  while (tmpde1) {
+    if (!(i++&3))
+      DocPrint(doc,"\n");
+    st=StrNew(tmpde1->name);
+    FileExtRem(st);
+    tmpde1->user_data=DocPrint(doc,"$MU-UL,\"%-10ts\",LE=%d$ ",st,tmpde1);
+    Free(st);
+    tmpde1=tmpde1->next;
+  }
+  DocPrint(doc,"\n\n\n$FG$Create your own AI in ~/ToTheFront.");
+  while ((tmpde1=PopUpMenu(doc))<=0);
+  ExeFile(tmpde1->full_name);
+  DocDel(doc);
+  DirTreeDel(tmpde);
+  DirTreeDel(tmpde2);
+  ExePrint("player_indirect[%d]=&PlayerIndirect;"
+        "player_move[%d]=&PlayerMove;"
+        "player_direct[%d]=&PlayerDirect;",
+        player,player,player);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/TTFLib.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/TTFLib.HC.HTML new file mode 100755 index 0000000..7b93698 --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/TTFLib.HC.HTML @@ -0,0 +1,152 @@ + + + + + + + + + + + +
+U0 Toward(I64 *_row,I64 *_col,I64 direction)
+{
+  switch (direction) {
+    case 0:
+      *_row-=2;
+      break;
+    case 1:
+      if (*_row&1) *_col+=1;
+      *_row-=1;
+      break;
+    case 2:
+      if (*_row&1) *_col+=1;
+      *_row+=1;
+      break;
+    case 3:
+      *_row+=2;
+      break;
+    case 4:
+      if (!(*_row&1)) *_col-=1;
+      *_row+=1;
+      break;
+    case 5:
+      if (!(*_row&1)) *_col-=1;
+      *_row-=1;
+      break;
+  }
+}
+
+I64 FacingChg(I64 f1,I64 f2)
+{
+  I64 res=(f1+6-f2)%6;
+  if (res>=3)
+    return 6-res;
+  else
+    return res;
+}
+
+U0 RowCol2XY(F64 *_x,F64 *_y,I64 row,I64 col)
+{
+  Pt *c;
+  row=ClampI64(row,0,map_rows);
+  col=ClampI64(col,0,map_cols);
+  c=&hex_centers[row][col];
+  *_x=c->x;
+  *_y=c->y;
+}
+
+U0 XY2RowCol(I64 *_row,I64 *_col,F64 x,F64 y)
+{
+  *_col=(x-DCOS/2)/(HEX_SIDE+DCOS);
+  if (*_col&1)
+    *_row=ToI64((y-DSIN)/(2*DSIN))*2+1;
+  else
+    *_row=ToI64(y/(2*DSIN))*2;
+  *_col>>=1;
+  *_row=ClampI64(*_row,0,map_rows-1);
+  *_col=ClampI64(*_col,0,map_cols-1);
+}
+
+Unit *UnitFind(I64 row,I64 col)
+{//Finds unit in a hexagon.
+  I64 i,j;
+  for (j=0;j<2;j++)
+    for (i=0;i<UNITS_NUM;i++)
+      if (units[j][i].life>0 &&
+            units[j][i].row==row &&
+            units[j][i].col==col)
+        return &units[j][i];
+  return NULL;
+}
+
+Bool CursorInWin(CTask *task,I64 x,I64 y)
+{
+  if (0<=x+task->scroll_x<task->pix_width &&
+        0<=y+task->scroll_y<task->pix_height)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 CursorUpdate(CTask *task,I64 x,I64 y)
+{
+  if (CursorInWin(task,x,y))
+    XY2RowCol(&cursor_row,&cursor_col,x,y);
+}
+
+class LOSCtrl
+{
+  I64 r1,c1,r2,c2,distance;
+};
+
+Bool LOSPlot(LOSCtrl *l,I64 x,I64 y,I64 z)
+{//We got tricky and used z as the distance from the start of the line.
+  I64 row,col;
+  XY2RowCol(&row,&col,x,y);
+  if ((row!=l->r1 || col!=l->c1) &&
+        (row!=l->r2 || col!=l->c2) &&
+        terrain[row][col]!=PLAINS) {
+    if (terrain[l->r1][l->c1]==MOUNTAINS) {
+      if (terrain[row][col]==MOUNTAINS || z>l->distance>>1)
+        return FALSE;
+    } else if (terrain[l->r2][l->c2]==MOUNTAINS) {
+      if (terrain[row][col]==MOUNTAINS || z<=l->distance>>1)
+        return FALSE;
+    } else
+      return FALSE;
+  }
+  return TRUE;
+}
+
+Bool LOS(I64 r1,I64 c1,I64 r2,I64 c2)
+{
+  F64 x1,y1,x2,y2;
+  LOSCtrl l;
+  RowCol2XY(&x1,&y1,r1,c1);
+  RowCol2XY(&x2,&y2,r2,c2);
+  l.r1=r1; l.c1=c1;
+  l.r2=r2; l.c2=c2;
+  l.distance=Sqrt(SqrI64(x1-x2)+SqrI64(y1-y2));
+  return Line(&l,x1,y1,0,x2,y2,l.distance,&LOSPlot);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/TTFMove.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/TTFMove.HC.HTML new file mode 100755 index 0000000..e7cc87b --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/TTFMove.HC.HTML @@ -0,0 +1,160 @@ + + + + + + + + + + + +
+U8 movement_costs[16];
+movement_costs[PLAINS]=2;
+movement_costs[TREES]=6;
+movement_costs[MOUNTAINS]=10;
+
+I64 HexMoveOneCost(Unit *tmpu,I64 r,I64 c,I64 facing)
+{
+  I64 res;
+  if (tmpu->infantry)
+    res=0;
+  else {
+    res=FacingChg(facing,tmpu->facing);
+    if (res>0) res--;
+  }
+  if (roads[r][c] && roads[tmpu->row][tmpu->col])
+    res+=1;
+  else {
+    if (tmpu->infantry)
+      res+=2;
+    else {
+      res+=movement_costs[terrain[r][c]];
+      if (rivers[r][c])
+        res=tmpu->movement;
+    }
+  }
+  return res;
+}
+
+I64 HexMoveOne(I64 *_row,I64 *_col,F64 x,F64 y)
+{
+  I64 direction,best_direction=-1,r,c;
+  F64 dd,best_dd,x1,y1;
+  RowCol2XY(&x1,&y1,*_row,*_col);
+  best_dd=Sqr(x1-x)+Sqr(y1-y);
+  for (direction=0;direction<6;direction++) {
+    r=*_row; c=*_col;
+    Toward(&r,&c,direction);
+    RowCol2XY(&x1,&y1,r,c);
+    dd=Sqr(x1-x)+Sqr(y1-y);
+    if (0<=r<map_rows && 0<=c<map_cols && dd<best_dd) {
+      best_dd=dd;
+      best_direction=direction;
+    }
+  }
+  if (best_direction>=0) {
+    Toward(_row,_col,best_direction);
+    return best_direction;
+  } else
+    return -1;
+}
+
+Bool UnitMovePlot(U0,I64 x,I64 y,I64)
+{
+  move_x=x; move_y=y;
+  Sleep(5*animation_delay);
+  return TRUE;
+}
+
+U0 UnitMoveAnimation(Unit *tmpu,I64 r,I64 c,I64 facing)
+{
+  F64 x1,y1,x2,y2,f=facing*60.0*pi/180.0;
+  moving_unit=tmpu;
+  RowCol2XY(&x1,&y1,tmpu->row,tmpu->col);
+  move_x=x1; move_y=y1;
+  moving=TRUE;
+  if (tmpu->infantry)
+    Snd(53);
+  else {
+    move_facing=tmpu->facing*60.0*pi/180.0;
+    Snd(41);
+    while (Wrap(f-move_facing,-pi)<=0) {
+      move_facing-=0.03;
+      Sleep(5*animation_delay);
+    }
+    while (Wrap(f-move_facing,-pi)>0) {
+      move_facing+=0.03;
+      Sleep(5*animation_delay);
+    }
+    Snd(34);
+  }
+  move_facing=f;
+  RowCol2XY(&x2,&y2,r,c);
+  Line(NULL,x1,y1,0,x2,y2,0,&UnitMovePlot);
+  Snd;
+  moving_unit=NULL;
+  moving=FALSE;
+}
+ 
+Bool UnitMove(Unit *tmpu,I64 x,I64 y)
+{
+  Unit *target;
+  I64 r,c,r0=tmpu->row,c0=tmpu->col,i,facing;
+  while (tmpu->remaining_movement>0) {
+    r=tmpu->row;
+    c=tmpu->col;
+    if ((facing=HexMoveOne(&r,&c,x,y))<0)
+      break;
+    else {
+      i=HexMoveOneCost(tmpu,r,c,facing);
+      if (i>tmpu->movement)
+        i=tmpu->movement;
+      if (!tmpu->fired && tmpu->remaining_movement>=i &&
+            tmpu->remaining_movement>=tmpu->movement>>1 &&
+            (target=UnitFind(r,c)) && target->player!=tmpu->player &&
+            tmpu->infantry!=target->infantry) {
+        if (!HexOccupy(ToBool(target->infantry),tmpu,target)) {
+          tmpu=NULL;
+          break;
+        }
+        i=tmpu->remaining_movement;
+      }
+      if (tmpu->remaining_movement>=i && !UnitFind(r,c)) {
+        UnitMoveAnimation(tmpu,r,c,facing);
+        tmpu->facing=facing;
+        tmpu->remaining_movement-=i;
+        tmpu->row=r;
+        tmpu->col=c;
+        VisRecalc(VR_UPDATE_FRIENDLY_UNIT,tmpu);
+        LBEqu(&tmpu->vis[enemy_player],0,
+              VisRecalc(VR_ONE_ENEMY_UNIT,tmpu));
+      } else
+        break;
+    }
+  }
+  if (!tmpu || tmpu->row!=r0 || tmpu->col!=c0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/TTFVis.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/TTFVis.HC.HTML new file mode 100755 index 0000000..8fc4e7c --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/TTFVis.HC.HTML @@ -0,0 +1,254 @@ + + + + + + + + + + + +
+#define VR_ONE_FRIENDLY_UNIT    0
+#define VR_UPDATE_FRIENDLY_UNIT 1
+#define VR_FRIENDLY_UNIT_DIED   3
+#define VR_ONE_ENEMY_UNIT       4
+#define VR_ALL_UNITS            5
+
+class MPCtrl1
+{
+  I64 mode,lo,hi;
+  Unit *tmpu;
+};
+
+class MPCtrl2
+{
+  I64 lo,hi,row,col;
+};
+
+
+U0 VRSetUp(I64 player)
+{
+  I64 i;
+  Unit *ut0,*ut1;
+  ut0=&units[player][0];
+  ut1=&units[player^1][0];
+  for (i=0;i<UNITS_NUM;i++,ut0++,ut1++) {
+    LBtr(&ut1->vis[player],0);
+    LBEqu(&ut0->vis[player],0,ut0->life>0);
+  }
+}
+
+U0 VRMerge(I64 player)
+{
+  I64 i,j;
+  Unit *ut1;
+  U8 *dst,*src,*mask=CAlloc((UNITS_NUM+7)>>3);
+  for (j=0;j<UNITS_NUM;j++) {//p0
+    src=&vis_unit_bitmap[player][(((UNITS_NUM+7)&~7)*j)>>3];
+    dst=mask;
+    for (i=0;i<(UNITS_NUM+7)>>3;i++) //player1
+      *dst++|=*src++;
+  }
+  ut1=&units[player^1][0];
+  for (j=0;j<UNITS_NUM;j++,ut1++)
+    LBEqu(&ut1->vis[player],0,Bt(mask,j) && ut1->life>0);
+  Free(mask);
+}
+
+Bool MPVisRecalc(MPCtrl1 *job)
+{
+  Bool res=FALSE,seen;
+  I64 i,j,row,col;
+  F64 x1,y1,x2,y2,dd,range;
+  Unit *ut0,*ut1;
+  ut0=&units[cur_player][job->lo];
+  ut1=&units[enemy_player][job->lo];
+  if (job->tmpu) {
+    row=job->tmpu->row;
+    col=job->tmpu->col;
+    range=job->tmpu->range*2*HEX_RADIUS;
+    range*=range;
+  }
+  switch (job->mode) {
+    case VR_UPDATE_FRIENDLY_UNIT:
+    case VR_ONE_FRIENDLY_UNIT:
+      if (job->mode==VR_UPDATE_FRIENDLY_UNIT)
+        range=F64_MAX;
+      RowCol2XY(&x1,&y1,row,col);
+      for (i=job->lo;i<job->hi;i++,ut1++) {
+        seen=FALSE;
+        if (ut1->life>0 &&
+              LOS(row,col,ut1->row,ut1->col)) {
+          RowCol2XY(&x2,&y2,ut1->row,ut1->col);
+          dd=Sqr(x2-x1)+Sqr(y2-y1);
+          if (dd<range) {
+            seen=TRUE;
+            LBts(&ut1->vis[cur_player],0);
+          }
+        }
+        if (job->mode==VR_UPDATE_FRIENDLY_UNIT)
+          LBEqu(&vis_unit_bitmap[cur_player],
+                i+job->tmpu->num*((UNITS_NUM+7)&~7),seen);
+      }
+      break;
+    case VR_ONE_ENEMY_UNIT:
+      RowCol2XY(&x1,&y1,row,col);
+      for (i=job->lo;i<job->hi;i++,ut1++)
+        if (ut1->life>0 &&
+              LOS(row,col,ut1->row,ut1->col)) {
+          LBts(&vis_unit_bitmap[enemy_player],
+                job->tmpu->num+i*((UNITS_NUM+7)&~7));
+          res=TRUE;
+        } else
+          LBtr(&vis_unit_bitmap[enemy_player],
+                job->tmpu->num+i*((UNITS_NUM+7)&~7));
+      break;
+    case VR_ALL_UNITS:
+      ut0=&units[cur_player][0];
+      for (i=0;i<UNITS_NUM;i++,ut0++)
+        if (ut0->life>0) {
+          RowCol2XY(&x1,&y1,ut0->row,ut0->col);
+          ut1=&units[enemy_player][job->lo];
+          for (j=job->lo;j<job->hi;j++,ut1++) {
+            if (ut1->life>0 &&
+                  LOS(ut0->row,ut0->col,ut1->row,ut1->col)) {
+              LBts(&ut1->vis[cur_player],0);
+              LBts(&vis_unit_bitmap[cur_player],j+i*((UNITS_NUM+7)&~7));
+            } else
+              LBtr(&vis_unit_bitmap[cur_player],j+i*((UNITS_NUM+7)&~7));
+          }
+        } else
+          for (j=job->lo;j<job->hi;j++)
+            LBtr(&vis_unit_bitmap[cur_player],j+i*((UNITS_NUM+7)&~7));
+      ut0=&units[enemy_player][0];
+      for (i=0;i<UNITS_NUM;i++,ut0++)
+        if (ut0->life>0) {
+          RowCol2XY(&x1,&y1,ut0->row,ut0->col);
+          ut1=&units[cur_player][job->lo];
+          for (j=job->lo;j<job->hi;j++,ut1++) {
+            if (ut1->life>0 &&
+                  LOS(ut0->row,ut0->col,ut1->row,ut1->col)) {
+              LBts(&ut1->vis[enemy_player],0);
+              LBts(&vis_unit_bitmap[enemy_player],j+i*((UNITS_NUM+7)&~7));
+            } else
+              LBtr(&vis_unit_bitmap[enemy_player],j+i*((UNITS_NUM+7)&~7));
+          }
+        } else
+          for (j=job->lo;j<job->hi;j++)
+            LBtr(&vis_unit_bitmap[enemy_player],j+i*((UNITS_NUM+7)&~7));
+      break;
+  }
+  return res;
+}
+
+Bool VisRecalc(I64 mode,Unit *tmpu=NULL)
+{
+  I64 i,hi,k,cnt;
+  Bool res;
+/*The compiler doesn't go out of it's way
+to know if something is const.;-)  This
+just compiles with the val at compile
+time, an advantage of just-in-time over
+AOT binaries.  TempleOS has a limited
+stk size, so don't get in the habit.
+MAlloc() would probably be the better choice.
+*/
+  MPCtrl1 job[mp_cnt];
+  CJob *cmd[mp_cnt];
+
+  if (mode==VR_FRIENDLY_UNIT_DIED) {
+    MemSet((&vis_unit_bitmap[enemy_player])(U8 *)+
+          (tmpu->num*((UNITS_NUM+7)&~7))>>3,0,(UNITS_NUM+7)>>3);
+    VRMerge(enemy_player);
+    return 0; //Return any value--don't care
+  }
+
+  cnt=mp_cnt; //Cores
+  hi=UNITS_NUM;
+  if (mode==VR_ONE_ENEMY_UNIT) {
+    for (hi--;hi>=0;hi--)
+      if (units[enemy_player][hi].life>0)
+        break;
+    hi++;
+  }
+  k=hi;
+  if (hi/mp_cnt<2)
+    cnt=1;
+  for (i=0;i<cnt;i++) {
+    job[i].mode=mode;
+    job[i].tmpu=tmpu;
+    job[i].hi=k;
+    k-=hi/cnt;
+    if (k<0) k=0;
+    if (i==cnt-1) k=0;
+    job[i].lo=k;
+  }
+
+  res=FALSE;
+  for (i=0;i<cnt;i++)
+    cmd[i]=JobQue(&MPVisRecalc,&job[i],i,0);
+  for (i=0;i<cnt;i++)
+    if (JobResGet(cmd[i]))
+      res=TRUE;
+  if (mode==VR_UPDATE_FRIENDLY_UNIT)
+    VRMerge(cur_player);
+  return res;
+}
+
+U0 MPVisRecalcMap(MPCtrl2 *job)
+{
+  I64 i,j;
+  for (j=job->lo;j<job->hi;j++)
+    for (i=0;i<map_cols;i++)
+      if (LOS(job->row,job->col,j,i))
+        vis_map[j][i]=TRUE;
+      else
+        vis_map[j][i]=FALSE;
+}
+
+U0 VisRecalcMap(I64 row,I64 col)
+{
+  I64 i,hi,k,cnt;
+  MPCtrl2 job[mp_cnt];
+  CJob *cmd[mp_cnt];
+
+  cnt=mp_cnt; //Cores
+  hi=map_rows;
+  k=hi;
+  if (hi/mp_cnt<2)
+    cnt=1;
+  for (i=0;i<cnt;i++) {
+    job[i].row=row;
+    job[i].col=col;
+    job[i].hi=k;
+    k-=hi/cnt;
+    if (k<0) k=0;
+    if (i==cnt-1) k=0;
+    job[i].lo=k;
+  }
+  for (i=0;i<cnt;i++)
+    cmd[i]=JobQue(&MPVisRecalcMap,&job[i],i,0);
+  for (i=0;i<cnt;i++)
+    JobResGet(cmd[i]);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/ToTheFront/ToTheFront.HC.HTML b/public/Wb/Home/Src/Apps/ToTheFront/ToTheFront.HC.HTML new file mode 100755 index 0000000..2a8b75f --- /dev/null +++ b/public/Wb/Home/Src/Apps/ToTheFront/ToTheFront.HC.HTML @@ -0,0 +1,245 @@ + + + + + + + + + + + +
+U0 AnimationDelaySet()
+{
+  animation_delay=PopUpRangeF64(0,100,25,"%3f% %%","Animation Delay\n")/100;
+}
+
+U0 TurnNew()
+{
+  I64 i,j;
+  for (j=0;j<2;j++)
+    for (i=0;i<UNITS_NUM;i++) {
+      units[j][i].remaining_movement=units[j][i].movement;
+      units[j][i].fired=FALSE;
+    }
+  phase=PHASE_START;
+  moving_unit=NULL;
+
+  SleepUntil(msg_off_timeout);
+  msg_off_timeout=cnts.jiffies+JIFFY_FREQ*2*animation_delay+1;
+  Snd(74);
+  StrPrint(msg_buf,"Turn %d",++turn);
+  VRSetUp(0);
+  VRSetUp(1);
+  VisRecalc(VR_ALL_UNITS);
+  cur_player=(turn&1)^1;
+  enemy_player=cur_player^1;
+}
+
+U0 PhaseNew()
+{
+  cur_player^=1;
+  enemy_player=cur_player^1;
+  if (++phase>=PHASE_END) {
+    IndirectResolveAll;
+    TurnNew;
+  }
+
+  SleepUntil(msg_off_timeout);
+  msg_off_timeout=cnts.jiffies+JIFFY_FREQ*2*animation_delay+1;
+  Snd(74);
+  switch (phase) {
+    case PHASE_INDIRECT0:
+    case PHASE_INDIRECT1:
+      StrPrint(msg_buf,"Player %d Artillery Plot",cur_player+1);
+      break;
+    case PHASE_MOVE0:
+    case PHASE_MOVE1:
+      StrPrint(msg_buf,"Player %d Move",cur_player+1);
+      break;
+    case PHASE_DIRECT0:
+    case PHASE_DIRECT1:
+      StrPrint(msg_buf,"Player %d Fire",cur_player+1);
+      break;
+  }
+}
+
+U0 CharDo(U8 ch)
+{
+  I64 old_inhibit,old_draw_it;
+  Bool old_cursor;
+  switch (ch) {
+    case CH_ESC:
+    case CH_SHIFT_ESC:
+      throw('ExitGame',TRUE);
+    case CH_SPACE:
+      throw('PhaseOvr',TRUE);
+    case '\n':
+      throw('NewGame',TRUE);
+    case '1':
+      ViewPlayerSet(0);
+      break;
+    case '2':
+      ViewPlayerSet(1);
+      break;
+    case 'c':
+      old_draw_it=Fs->draw_it;
+      old_inhibit=Fs->win_inhibit;
+      Fs->draw_it=Fs->next_settings->draw_it;
+      Fs->win_inhibit=WIG_USER_TASK_DFT;
+      old_cursor=DocCursor(ON);
+      DocBottom;
+      "\n$GREEN$<SHIFT-ESC>$FG$ to return to game.\n";
+      View;
+      DocBottom;
+      DocCursor(old_cursor);
+      Fs->win_inhibit=old_inhibit;
+      Fs->draw_it=old_draw_it;
+      break;
+    case 'd':
+      AnimationDelaySet;
+      break;
+  }
+}
+
+U0 UserChk()
+{
+  I64 ch;
+  if (!alive_cnt[0] || !alive_cnt[1])
+    throw('GameOver',TRUE);
+  if (ch=ScanChar)
+    CharDo(ch);
+}
+
+U0 TaskEndCB()
+{
+  Snd;
+  progress4=progress4_max=progress1=progress1_max=0;
+  Exit;
+}
+
+I64 PhaseDo()
+{
+  I64 res='ExitGame';
+  PhaseNew;
+  try {
+    if (phase&~1==PHASE_INDIRECT)
+      Call(player_indirect[cur_player]);
+    else if (phase&~1==PHASE_MOVE)
+      Call(player_move[cur_player]);
+    else
+      Call(player_direct[cur_player]);
+  } catch {
+    res=Fs->except_ch;
+    Fs->catch_except=TRUE;
+  }
+  return res;
+}
+
+U0 ToTheFront()
+{
+  I64 res,ch;
+  map_dc=DCNew(MAP_WIDTH,MAP_HEIGHT);
+
+  SettingsPush; //See SettingsPush
+  Cd(__DIR__);
+  Fs->win_inhibit|=WIF_SELF_MS_L|WIF_SELF_MS_R|WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  EndPhase(,CH_SPACE);"
+        "  Restart(,'\n');"
+        "}"
+        "View {"
+        "  Player1(,'1');"
+        "  Player2(,'2');"
+        "  OddsCalculations(,'c');"
+        "  LOS(,0,SCF_SHIFT);"
+        "}"
+        "Settings {"
+        "  AnimationDelay(,'d');"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocMax;
+  Init;
+  PlayerPick("AIs",0);
+  PlayerPick("AIs",1);
+
+  PopUpOk("$PURPLE$$TX+CX,\"ToTheFront\"$$FG$\n\n"
+        "$GREEN${Left-click}$FG$ to move or fire units.\n"
+        "$GREEN$<SPACE>$FG$\tor $GREEN${Right-click}$FG$ to end phase.\n"
+        "$GREEN$<SHIFT>$FG$\tto show line-of-sight.\n"
+        "$GREEN$<ENTER>$FG$\tto start new game.\n"
+        "$GREEN$  1$FG$\tPlayer 1 view.\n"
+        "$GREEN$  2$FG$\tPlayer 2 view.\n"
+        "$GREEN$  c$FG$\tView odds calculations.\n"
+        "$GREEN$  d$FG$\tSet animation delay.");
+  Fs->task_end_cb=&TaskEndCB; //<CTRL-ALT-x>
+  Fs->draw_it=&DrawIt;
+  try {
+    do {
+      res=PhaseDo;
+      if (res=='GameOver') {
+        while (TRUE) {
+          msg_off_timeout=0;
+          StrCpy(msg_buf,"Game Over");
+          Snd;
+          ch=GetChar(,FALSE);
+          if (ch=='\n') {
+            CleanUp;
+            Init;
+            break;
+          } else if (ch==CH_ESC || ch==CH_SHIFT_ESC) {
+            res='ExitGame';
+            break;
+          } else if (ch=='1')
+            ViewPlayerSet(0);
+          else if (ch=='2')
+            ViewPlayerSet(1);
+          else if (ch=='d')
+            AnimationDelaySet;
+        }
+      } else if (res=='NewGame') {
+        CleanUp;
+        Init;
+      }
+    } while (res!='ExitGame');
+  } catch
+    PutExcept;
+  ProgressBarsRst;
+
+  SettingsPop;
+  DCDel(map_dc);
+  CleanUp;
+  MenuPop;
+  Seed;
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/Vocabulary/Load.HC.HTML b/public/Wb/Home/Src/Apps/Vocabulary/Load.HC.HTML new file mode 100755 index 0000000..6875d95 --- /dev/null +++ b/public/Wb/Home/Src/Apps/Vocabulary/Load.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "VocabQuiz"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/Vocabulary/Run.HC.HTML b/public/Wb/Home/Src/Apps/Vocabulary/Run.HC.HTML new file mode 100755 index 0000000..03b504a --- /dev/null +++ b/public/Wb/Home/Src/Apps/Vocabulary/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+VocabQuiz;
+ diff --git a/public/Wb/Home/Src/Apps/Vocabulary/VocabQuiz.HC.HTML b/public/Wb/Home/Src/Apps/Vocabulary/VocabQuiz.HC.HTML new file mode 100755 index 0000000..2abad5f --- /dev/null +++ b/public/Wb/Home/Src/Apps/Vocabulary/VocabQuiz.HC.HTML @@ -0,0 +1,88 @@ + + + + + + + + + + + +
+U8 *RandVocabWord()
+{
+  I64 i;
+  U8 *ptr;
+  if (!acd.num_words)
+    return NULL;
+  i=RandU32%acd.num_words;
+  ptr=acd.word_lst;
+  while (i-- && *ptr==ACD_WORD_CHAR)
+    ptr+=StrLen(ptr)+3;
+  if (*ptr++!=ACD_WORD_CHAR)
+    return NULL;
+  else
+    return ptr;
+}
+
+U0 VocabQuiz()
+{
+  I64 ch,i,num;
+  U8 *right_word,*words[4];
+  if (!FileFind(ACD_DEF_FILENAME)) {
+    "Uncompressed dictionary not present.\n";
+    return;
+  }
+  do {
+    right_word=RandVocabWord;
+    for (i=0;i<4;i++)
+      words[i]=RandVocabWord;
+    num=RandU32&3;
+    words[num]=right_word;
+
+    "$WW,1$$CM-LE,5$$RED$$BK,1$%s$BK,0$:$FG$$LM,4$\n",right_word;
+    for (i=0;i<4;i++)
+      "\n\n$GREEN$$BT-X,\"%d\",LM=\"%d\"$$FG$"
+            "$LM,7$%s\n$LM,4$",i+1,i+1,ACDDefGet(words[i]);
+    "\n\n$LTBLUE$Answer:$FG$";
+    do {
+      ch=GetKey(,TRUE);
+      DocBottom;
+      if ('1'<=ch<='4') {
+        '\n';
+        if (ch-'1'==num) {
+          "$LTGREEN$Correct\n$FG$";
+          Snd(74);
+        } else {
+          "$LTRED$Incorrect\n$FG$";
+          Snd(46);
+        }
+        Sleep(500);
+        Snd;
+        ACDPopUpDef(right_word);
+        break;
+      }
+    } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+    "$LM,0$\n";
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/X-Caliber/Load.HC.HTML b/public/Wb/Home/Src/Apps/X-Caliber/Load.HC.HTML new file mode 100755 index 0000000..ce3951b --- /dev/null +++ b/public/Wb/Home/Src/Apps/X-Caliber/Load.HC.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+#help_index "Games"
+
+Cd(__DIR__);;
+#include "XCCtrls"
+#include "X-Caliber"
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Apps/X-Caliber/Run.HC.HTML b/public/Wb/Home/Src/Apps/X-Caliber/Run.HC.HTML new file mode 100755 index 0000000..11a3b88 --- /dev/null +++ b/public/Wb/Home/Src/Apps/X-Caliber/Run.HC.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+#include "Load"
+XCaliber;
+ diff --git a/public/Wb/Home/Src/Apps/X-Caliber/X-Caliber.HC.HTML b/public/Wb/Home/Src/Apps/X-Caliber/X-Caliber.HC.HTML new file mode 100755 index 0000000..6f59533 --- /dev/null +++ b/public/Wb/Home/Src/Apps/X-Caliber/X-Caliber.HC.HTML @@ -0,0 +1,1549 @@ + + + + + + + + + + + +
+#define  XMSGF_ANTISPIN         0
+#define  XMSGF_SOLAR_STORM      1
+RegDft("TempleOS/XCaliber",
+        "I64 best_score=0;\n"
+        "I64 msg_flags=0;\n"
+        );
+RegExe("TempleOS/XCaliber");
+
+#define MT_HUMAN_SHIP           0
+#define MT_ENEMY_SHIP           1
+#define MT_SOLAR_FLARE          2
+#define MT_ION                  3
+#define MT_ANTIMATTER_BALL      4
+#define MT_ANTIMATTER_SPLAT     5
+#define MT_MISSILE              6
+
+class MyMass:CMass
+{
+  F64 temperature,radius,die_timeout;
+  I64 type;
+  Bool no_overlap;
+};
+
+class MySpring:CSpring
+{
+  F64 strength;
+  I64 color;
+};
+
+#define SPIN_GAIN               0.25
+#define MASSES_NUM              8
+#define SPRINGS_NUM             16
+#define MISSILES_NUM            2
+#define ST_HUMAN1               0
+#define ST_ENEMY1               1
+#define ST_ENEMY2               2
+extern class Ship;
+
+#define MISSILE_LEN             5
+class Missile
+{
+  Missile *next,*last;
+  F64 tons,fuse_time,die_timeout;
+  MyMass p_front,p_back;
+  MySpring s[5];
+  U8 *img;
+  Ship *owner,*target;
+  Bool active,launched,exploding;
+  U8 label[5];
+} missile_head;
+
+class Ship
+{
+  Ship *next,*last;
+  I64 type,masses,springs;
+  MyMass   p[MASSES_NUM];
+  MySpring s[SPRINGS_NUM];
+  F64 fire_rate;
+  F64 reload_timeout,spacewalk_timeout;
+  F64 die_time,die_timeout;
+  I64 spacewalk_side;
+  F64 laser_temperature;
+  Missile missiles[MISSILES_NUM];
+  Bool lasering,exploding,laser_overheat;
+} ship_head,*human;
+
+F64 human_t_left,human_t_right,human_antispin;
+
+class Shot
+{
+  Shot *next,*last;
+  F64 radius,fuse_time;
+  I64 splats;
+  MyMass p;
+} shot_head;
+
+F64 t_solar_storm;
+Bool alarm;
+
+#define THRUST_MAX      200.0
+#define ANTISPIN_MAX    25.0
+#define SPACEWALK_TIME  7.5
+
+#define CMD_NULL        0
+#define CMD_SPIN_LEFT   1
+#define CMD_SPIN_RIGHT  2
+#define CMD_THRUST      3
+#define CMD_FIRE        4
+#define CMD_EXIT        5
+Bool game_over,show_level_msg;
+
+#define STARS_NUM       100
+I64 stars_x[STARS_NUM],stars_y[STARS_NUM];
+
+CMathODE *ode=NULL;
+I64 level,score,remaining;
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+<3>/* Graphics Not Rendered in HTML */
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+<6>/* Graphics Not Rendered in HTML */
+
+<7>/* Graphics Not Rendered in HTML */
+
+<8>/* Graphics Not Rendered in HTML */
+
+
+//********************************** Ship
+Bool CheckOverlap()
+{
+  CD3 p;
+  MyMass *tmpm,*tmpm1;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=ode->next_mass;
+    while (tmpm1!=&ode->next_mass) {
+      if (tmpm!=tmpm1 && !tmpm->no_overlap && !tmpm1->no_overlap) {
+        D3Sub(&p,&tmpm->x,&tmpm1->x);
+        if (D3NormSqr(&p)<=Sqr(tmpm->radius+tmpm1->radius))
+          return TRUE;
+      }
+      tmpm1=tmpm1->next;
+    }
+    tmpm=tmpm->next;
+  }
+  return FALSE;
+}
+
+U0 MissileNew(Ship *tmpsp,I64 n)
+{
+  I64 i;
+  CD3 p,p1,p2;
+  Missile *tmpmi=&tmpsp->missiles[n];
+  MemSet(tmpmi,0,sizeof(Missile));
+
+  D3Equ(&tmpmi->p_front.x,
+        (tmpsp->p[n+1].x+tmpsp->p[n+3].x)/2,
+        (tmpsp->p[n+1].y+tmpsp->p[n+3].y)/2,0);
+  D3Copy(&tmpmi->p_back.x,&tmpmi->p_front.x);
+
+  if (n&1)
+    StrCpy(tmpmi->label,"L");
+  else
+    StrCpy(tmpmi->label,"R");
+  tmpmi->owner=tmpsp;
+  tmpmi->tons=0.5;
+  tmpmi->p_front.mass=0.1;
+  tmpmi->p_front.type=MT_MISSILE;
+  tmpmi->p_back.mass =0.1;
+  tmpmi->p_back.type =MT_MISSILE;
+  tmpmi->p_front.radius=2;
+  tmpmi->p_back.radius =2;
+  tmpmi->p_front.no_overlap=TRUE;
+  tmpmi->p_back.no_overlap =TRUE;
+  D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x);
+  D3Sub(&p2,&tmpsp->p[0].x,&tmpsp->p[2].x);
+  D3Unit(D3Add(&p,&p1,&p2));
+  D3AddEqu(&tmpmi->p_front.x,D3MulEqu(D3Copy(&p1,&p),MISSILE_LEN/2+1));
+  D3SubEqu(&tmpmi->p_back.x ,D3MulEqu(D3Copy(&p1,&p),MISSILE_LEN/2-1));
+  D3Copy(&tmpmi->p_front.DxDt,&tmpsp->p[n].DxDt);
+  D3Copy(&tmpmi->p_back.DxDt,&tmpsp->p[n].DxDt);
+  QueIns(&tmpmi->p_front,ode->last_mass);
+  QueIns(&tmpmi->p_back, ode->last_mass);
+
+  tmpmi->s[0].end1=&tmpmi->p_front;
+  tmpmi->s[0].end2=&tmpmi->p_back;
+  tmpmi->s[1].end1=&tmpmi->p_front;
+  tmpmi->s[1].end2=&tmpsp->p[n+1];
+  tmpmi->s[2].end1=&tmpmi->p_back;
+  tmpmi->s[2].end2=&tmpsp->p[n+1];
+  tmpmi->s[3].end1=&tmpmi->p_front;
+  tmpmi->s[3].end2=&tmpsp->p[n+3];
+  tmpmi->s[4].end1=&tmpmi->p_back;
+  tmpmi->s[4].end2=&tmpsp->p[n+3];
+ 
+  for (i=0;i<5;i++) {
+    tmpmi->s[i].const=10000;
+    tmpmi->s[i].strength  =20000;
+    tmpmi->s[i].color=BLACK;
+    tmpmi->s[i].rest_len=D3Dist(&tmpmi->s[i].end1->x,&tmpmi->s[i].end2->x);
+    QueIns(&tmpmi->s[i],ode->last_spring);
+  }
+  tmpmi->img=<7>;
+  tmpmi->active=TRUE;
+  QueIns(tmpmi,missile_head.last);
+}
+
+Ship *ShipNew(I64 x,I64 y,I64 type)
+{
+  I64 i;
+  Ship *tmpsp=CAlloc(sizeof(Ship));
+
+  switch (tmpsp->type=type) {
+    case ST_HUMAN1:
+      tmpsp->fire_rate=25;
+      tmpsp->masses=5;
+      tmpsp->p[0].x=x;
+      tmpsp->p[0].y=y;
+      tmpsp->p[1].x=x+3;
+      tmpsp->p[1].y=y+10;
+      tmpsp->p[2].x=x-3;
+      tmpsp->p[2].y=y+10;
+      tmpsp->p[3].x=x+20;
+      tmpsp->p[3].y=y+20;
+      tmpsp->p[4].x=x-20;
+      tmpsp->p[4].y=y+20;
+
+      for (i=0;i<tmpsp->masses;i++) {
+        tmpsp->p[i].mass=1;
+        tmpsp->p[i].type=MT_HUMAN_SHIP;
+        if (i<3)
+          tmpsp->p[i].radius=2.5;
+        else
+          tmpsp->p[i].radius=4;
+        tmpsp->p[i].drag_profile_factor=3;
+        QueIns(&tmpsp->p[i],ode->last_mass);
+      }
+      tmpsp->p[3].mass/=10.0;
+      tmpsp->p[4].mass/=10.0;
+
+      tmpsp->springs=7;
+      tmpsp->s[0].end1=&tmpsp->p[0];
+      tmpsp->s[0].end2=&tmpsp->p[1];
+      tmpsp->s[1].end1=&tmpsp->p[2];
+      tmpsp->s[1].end2=&tmpsp->p[0];
+      tmpsp->s[2].end1=&tmpsp->p[1];
+      tmpsp->s[2].end2=&tmpsp->p[2];
+      tmpsp->s[3].end1=&tmpsp->p[1];
+      tmpsp->s[3].end2=&tmpsp->p[3];
+      tmpsp->s[4].end1=&tmpsp->p[0];
+      tmpsp->s[4].end2=&tmpsp->p[3];
+      tmpsp->s[5].end1=&tmpsp->p[2];
+      tmpsp->s[5].end2=&tmpsp->p[4];
+      tmpsp->s[6].end1=&tmpsp->p[0];
+      tmpsp->s[6].end2=&tmpsp->p[4];
+
+      for (i=0;i<tmpsp->springs;i++) {
+        tmpsp->s[i].rest_len=
+              D3Dist(&tmpsp->s[i].end1->x,&tmpsp->s[i].end2->x);
+        tmpsp->s[i].const=10000;
+        tmpsp->s[i].strength  =30000;
+        if (i<=2)
+          tmpsp->s[i].color=LTCYAN;
+        else
+          tmpsp->s[i].color=LTGRAY;
+        QueIns(&tmpsp->s[i],ode->last_spring);
+      }
+      MissileNew(tmpsp,0);
+      MissileNew(tmpsp,1);
+      remaining=0;
+
+      break;
+    case ST_ENEMY1:
+      tmpsp->fire_rate=2.5;
+      tmpsp->masses=3;
+      tmpsp->p[0].x=x;
+      tmpsp->p[0].y=y;
+      tmpsp->p[1].x=x+15;
+      tmpsp->p[1].y=y;
+      tmpsp->p[2].x=x;
+      tmpsp->p[2].y=y+15;
+
+      for (i=0;i<tmpsp->masses;i++) {
+        tmpsp->p[i].mass=1;
+        tmpsp->p[i].type=MT_ENEMY_SHIP;
+        tmpsp->p[i].radius=7;
+        tmpsp->p[i].drag_profile_factor=3;
+        QueIns(&tmpsp->p[i],ode->last_mass);
+      }
+
+      tmpsp->springs=3;
+      tmpsp->s[0].end1=&tmpsp->p[0];
+      tmpsp->s[0].end2=&tmpsp->p[1];
+      tmpsp->s[1].end1=&tmpsp->p[1];
+      tmpsp->s[1].end2=&tmpsp->p[2];
+      tmpsp->s[2].end1=&tmpsp->p[2];
+      tmpsp->s[2].end2=&tmpsp->p[0];
+
+      for (i=0;i<tmpsp->springs;i++) {
+        tmpsp->s[i].rest_len=
+              D3Dist(&tmpsp->s[i].end1->x,&tmpsp->s[i].end2->x);
+        tmpsp->s[i].const=10000;
+        tmpsp->s[i].strength  =20000;
+        tmpsp->s[i].color=BLACK;
+        QueIns(&tmpsp->s[i],ode->last_spring);
+      }
+      remaining++;
+      break;
+    case ST_ENEMY2:
+      tmpsp->fire_rate=5.0;
+      tmpsp->masses=5;
+      tmpsp->p[0].x=x;
+      tmpsp->p[0].y=y;
+      tmpsp->p[1].x=x-7;
+      tmpsp->p[1].y=y+10;
+      tmpsp->p[2].x=x+7;
+      tmpsp->p[2].y=y+10;
+      tmpsp->p[3].x=x-14;
+      tmpsp->p[3].y=y+20;
+      tmpsp->p[4].x=x+14;
+      tmpsp->p[4].y=y+20;
+
+      for (i=0;i<tmpsp->masses;i++) {
+        tmpsp->p[i].mass=1;
+        tmpsp->p[i].type=MT_ENEMY_SHIP;
+        tmpsp->p[i].radius=6;
+        tmpsp->p[i].drag_profile_factor=5;
+        QueIns(&tmpsp->p[i],ode->last_mass);
+      }
+
+      tmpsp->springs=7;
+      tmpsp->s[0].end1=&tmpsp->p[0];
+      tmpsp->s[0].end2=&tmpsp->p[1];
+      tmpsp->s[1].end1=&tmpsp->p[0];
+      tmpsp->s[1].end2=&tmpsp->p[2];
+      tmpsp->s[2].end1=&tmpsp->p[1];
+      tmpsp->s[2].end2=&tmpsp->p[2];
+      tmpsp->s[3].end1=&tmpsp->p[1];
+      tmpsp->s[3].end2=&tmpsp->p[3];
+      tmpsp->s[4].end1=&tmpsp->p[2];
+      tmpsp->s[4].end2=&tmpsp->p[4];
+      tmpsp->s[5].end1=&tmpsp->p[2];
+      tmpsp->s[5].end2=&tmpsp->p[3];
+      tmpsp->s[6].end1=&tmpsp->p[1];
+      tmpsp->s[6].end2=&tmpsp->p[4];
+
+      for (i=0;i<tmpsp->springs;i++) {
+        tmpsp->s[i].rest_len=
+              D3Dist(&tmpsp->s[i].end1->x,&tmpsp->s[i].end2->x);
+        tmpsp->s[i].const= 40000;
+        tmpsp->s[i].strength  =75000;
+        if (i>=3)
+          tmpsp->s[i].color=LTPURPLE;
+        else
+          tmpsp->s[i].color=BLACK;
+        QueIns(&tmpsp->s[i],ode->last_spring);
+      }
+      remaining++;
+      break;
+  }
+  QueIns(tmpsp,ship_head.last);
+  return tmpsp;
+}
+
+U0 MissileDel(Missile *tmpmi)
+{
+  I64 i;
+  if (tmpmi->active) {
+    QueRem(tmpmi);
+    for(i=0;i<5;i++)
+      QueRem(&tmpmi->s[i]);
+    QueRem(&tmpmi->p_front);
+    QueRem(&tmpmi->p_back);
+    tmpmi->active=FALSE;
+  }
+}
+
+U0 ShipDel(Ship *tmpsp)
+{
+  I64 i;
+  if (!tmpsp) return;
+  for (i=0;i<tmpsp->masses;i++)
+    QueRem(&tmpsp->p[i]);
+  for (i=0;i<tmpsp->springs;i++)
+    QueRem(&tmpsp->s[i]);
+  for (i=0;i<2;i++)
+    MissileDel(&tmpsp->missiles[i]);
+  QueRem(tmpsp);
+  Free(tmpsp);
+  remaining--;
+}
+
+U0 PlaceShip(I64 type)
+{
+  Ship *tmpsp;
+  if (CheckOverlap)
+    return;
+  while (TRUE) {
+    tmpsp=ShipNew(RandU16%(Fs->pix_width-20)+10,
+          RandU16%(Fs->pix_height-20)+10,type);
+    if (CheckOverlap)
+      ShipDel(tmpsp);
+    else
+      break;
+  }
+}
+
+//********************************** Human Ship
+
+I64 Tweaked()
+{
+  CD3 p,p1,p2;
+  if (human) {
+    D3Sub(&p1,&human->p[0].x,&human->p[1].x);
+    D3Sub(&p2,&human->p[0].x,&human->p[2].x);
+    D3Unit(D3Add(&p,&p1,&p2));
+    D3Sub(&p1,&human->p[0].x,&human->p[3].x);
+    D3Sub(&p2,&human->p[0].x,&human->p[4].x);
+    D3Unit(&p1);
+    D3Unit(&p2);
+    if (!(human->s[3].flags&SSF_INACTIVE) && D3Dot(&p,&p1)>Cos(20*pi/180))
+      return 3;
+    if (!(human->s[5].flags&SSF_INACTIVE) && D3Dot(&p,&p2)>Cos(20*pi/180))
+      return 4;
+    return 0;
+  }
+}
+
+U0 AllDel(CMathODE *ode)
+{
+  Ship *tmpsp,*tmpsp1;
+  QueRem(ode);
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    tmpsp1=tmpsp->next;
+    ShipDel(tmpsp);
+    tmpsp=tmpsp1;
+  }
+  human=NULL;
+  QueDel(&shot_head,TRUE);
+  ODEDel(ode);
+}
+
+Bool LaserPlot(CDC *dc,I64 x,I64 y,I64)
+{
+  I64 c;
+  c=GrPeek(dc,x,y);
+  if (c!=BLACK && c!=WHITE)
+    return FALSE;
+  else {
+    GrPlot(dc,x,y);
+    return TRUE;
+  }
+}
+
+//**********************************
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j;
+  F64 arg;
+  Ship *tmpsp;
+  Shot *tmps;
+  Missile *tmpmi;
+  CD3 p,p1,p2;
+  F64 t_left,t_right,spin,d,x,y;
+  MySpring *tmpsps;
+  MyMass *tmpm;
+  U8 *img;
+  Bool draw_laser_line=FALSE;
+
+  if (ode!=task->last_ode) return;
+
+  dc->color=WHITE;
+  GrPrint(dc,0,0,"Level:%d Score:%d High Score:%d",level,score,best_score);
+  if (game_over) {
+    if (Blink)
+      GrPrint(dc,(task->pix_width-9*FONT_WIDTH)/2,
+            (task->pix_height-FONT_HEIGHT)/2,"Game Over");
+  } else if (show_level_msg) {
+    if (Blink)
+      GrPrint(dc,(task->pix_width-8*FONT_WIDTH)/2,
+            (task->pix_height-FONT_HEIGHT)/2+50,"Level %d",level);
+  }
+
+  for (i=0;i<STARS_NUM;i++)
+    GrPlot(dc,stars_x[i],stars_y[i]);
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type==MT_ANTIMATTER_SPLAT) {
+      dc->color=LTGREEN;
+      GrPlot(dc,tmpm->x,tmpm->y);
+    } else if (tmpm->type==MT_ION) {
+      dc->color=YELLOW;
+      GrPlot(dc,tmpm->x,tmpm->y);
+    }
+    tmpm=tmpm->next;
+  }
+
+  tmpsps=ode->next_spring;
+  while (tmpsps!=&ode->next_spring) {
+    if (!(tmpsps->flags&SSF_INACTIVE) && tmpsps->color) {
+      dc->color=tmpsps->color;
+      GrLine(dc,tmpsps->end1->x,tmpsps->end1->y,
+            tmpsps->end2->x,tmpsps->end2->y);
+    }
+    tmpsps=tmpsps->next;
+  }
+
+  tmpmi=missile_head.next;
+  while (tmpmi!=&missile_head) {
+    if (tmpmi->active) {
+      if (tmpmi->launched && tmpmi->exploding) {
+        d=(tS-tmpmi->fuse_time)/(tmpmi->die_timeout-tmpmi->fuse_time);
+        d=70*Sin(pi*d)*tmpmi->tons+1;
+        for (i=1;i<d;i++) {
+          if (i&1)
+            dc->color=YELLOW;
+          else
+            dc->color=LTRED;
+          GrCircle(dc,tmpmi->p_front.x,tmpmi->p_front.y,i);
+        }
+      } else
+        Sprite3ZB(dc,(tmpmi->p_front.x+tmpmi->p_back.x)/2,
+              (tmpmi->p_front.y+tmpmi->p_back.y)/2,0,tmpmi->img,
+              Arg(tmpmi->p_front.x-tmpmi->p_back.x,
+              tmpmi->p_front.y-tmpmi->p_back.y));
+    }
+    tmpmi=tmpmi->next;
+  }
+
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    if (!tmpsp->exploding) {
+      switch (tmpsp->type) {
+        case ST_HUMAN1:
+          if (tmpsp->spacewalk_side) {
+            t_left=0;
+            t_right=0;
+          } else {
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x))) {
+              D3Sub(&p2,&tmpsp->p[0].DxDt,&tmpsp->p[1].DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_left =Clamp(human_t_left+SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[2].x))) {
+              D3Sub(&p2,&tmpsp->p[0].DxDt,&tmpsp->p[2].DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_right=Clamp(human_t_right-SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+          }
+
+          D3Sub(&p1,&tmpsp->p[1].x,&tmpsp->p[0].x);
+          D3Sub(&p2,&tmpsp->p[2].x,&tmpsp->p[0].x);
+          D3Unit(D3Add(&p,&p1,&p2));
+
+          if (!(tmpsp->s[3].flags&SSF_INACTIVE)) {
+            dc->color=YELLOW;
+            D3AddEqu(D3Mul(&p1,t_left/25,&p),&tmpsp->p[3].x);
+            GrLine(dc,tmpsp->p[1].x,tmpsp->p[1].y,p1.x,p1.y);
+            arg=Arg(p.x,p.y);
+            Sprite3ZB(dc,tmpsp->p[3].x,tmpsp->p[3].y,0,<thruster>,arg);
+          }
+
+          if (!(tmpsp->s[5].flags&SSF_INACTIVE)) {
+            dc->color=YELLOW;
+            D3AddEqu(D3Mul(&p2,t_right/25,&p),&tmpsp->p[4].x);
+            GrLine(dc,tmpsp->p[2].x,tmpsp->p[2].y,p2.x,p2.y);
+            arg=Arg(p.x,p.y);
+            Sprite3ZB(dc,tmpsp->p[4].x,tmpsp->p[4].y,0,<thruster>,arg);
+          }
+
+          if (tS>tmpsp->reload_timeout)
+            img=<gun_ready>;
+          else
+            img=<gun_busy>;
+          arg=Arg(p.x,p.y);
+          switch (level) {
+            case 3:
+              if (!(tmpsp->s[3].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[3].x,tmpsp->p[3].y,0,img,arg);
+              if (!(tmpsp->s[5].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[4].x,tmpsp->p[4].y,0,img,arg);
+            case 2:
+              if (!(tmpsp->s[1].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[1].x,tmpsp->p[1].y,0,img,arg);
+              if (!(tmpsp->s[2].flags&SSF_INACTIVE))
+                Sprite3ZB(dc,tmpsp->p[2].x,tmpsp->p[2].y,0,img,arg);
+            case 1:
+              Sprite3ZB(dc,tmpsp->p[0].x,tmpsp->p[0].y,0,img,arg);
+              break;
+            default:
+              Sprite3ZB(dc,tmpsp->p[0].x,tmpsp->p[0].y,0,<Laser>,arg);
+              if (tmpsp->lasering && !tmpsp->laser_overheat) {
+                draw_laser_line=TRUE;
+                Snd(74);
+              }
+          }
+
+          ctrl_panel.laser_temperature=tmpsp->laser_temperature;
+
+          if (tmpsp->spacewalk_side) {
+            d=1.0-(tmpsp->spacewalk_timeout-tS)/SPACEWALK_TIME;
+            if (d>1.0) {
+              tmpsp->spacewalk_side=0;
+              ctrl_panel.spacewalk=FALSE;
+            } else {
+              if (d<0.5) {
+                d=d*2;
+                x=tmpsp->p[0].x*(1.0-d)+
+                      tmpsp->p[tmpsp->spacewalk_side].x*(d);
+                y=tmpsp->p[0].y*(1.0-d)+
+                      tmpsp->p[tmpsp->spacewalk_side].y*(d);
+              } else {
+                d=(d-0.5)*2;
+                x=tmpsp->p[tmpsp->spacewalk_side].x*(1.0-d)+
+                      tmpsp->p[0].x*(d);
+                y=tmpsp->p[tmpsp->spacewalk_side].y*(1.0-d)+
+                      tmpsp->p[0].y*(d);
+              }
+              Sprite3ZB(dc,x,y,0,<spacewalk>,arg+0.75*Sin(tS*2));
+            }
+          } else {
+            if (ctrl_panel.spacewalk) {
+              if (tmpsp->spacewalk_side=Tweaked)
+                tmpsp->spacewalk_timeout=tS+SPACEWALK_TIME;
+              else
+                ctrl_panel.spacewalk=FALSE;
+            }
+          }
+          break;
+        case ST_ENEMY2:
+          for (i=3;i<tmpsp->masses;i++) {
+            dc->color=PURPLE;
+            GrCircle(dc,tmpsp->p[i].x,tmpsp->p[i].y,tmpsp->p[i].radius);
+            GrFloodFill(dc,tmpsp->p[i].x,tmpsp->p[i].y+2,TRUE);
+            dc->color=WHITE;
+            GrCircle(dc,tmpsp->p[i].x,tmpsp->p[i].y,tmpsp->p[i].radius);
+          }
+        case ST_ENEMY1:
+          D3DivEqu(D3Sub(&p1,&tmpsp->p[1].x,&tmpsp->p[0].x),2.0);
+          D3DivEqu(D3Sub(&p2,&tmpsp->p[2].x,&tmpsp->p[0].x),2.0);
+          D3Unit(D3Add(&p,&p1,&p2));
+          if (tS>tmpsp->reload_timeout)
+            img=<gun_ready>;
+          else
+            img=<gun_busy>;
+          arg=Arg(p.x,p.y);
+          Sprite3ZB(dc,tmpsp->p[0].x,tmpsp->p[0].y,0,img,arg);
+          arg=Arg(p1.x,p1.y);
+          Sprite3ZB(dc,tmpsp->p[0].x+p1.x,tmpsp->p[0].y+p1.y,0,
+                <EnemySide>,arg);
+          arg=Arg(p2.x,p2.y);
+          Sprite3ZB(dc,tmpsp->p[0].x+p2.x,tmpsp->p[0].y+p2.y,0,
+                <EnemySide>,arg);
+          break;
+      }
+      for (i=0;i<tmpsp->masses;i++) {
+        dc->color=YELLOW;
+        if (tmpsp->p[i].temperature>=1.0)
+          GrCircle(dc,tmpsp->p[i].x,tmpsp->p[i].y,
+                tmpsp->p[i].temperature);
+      }
+    }
+    else if (tmpsp->die_time<=tS<=tmpsp->die_timeout)
+      for (j=0;j<tmpsp->masses;j++) {
+        d=(tS-tmpsp->die_time)/(tmpsp->die_timeout-tmpsp->die_time);
+        d=7*Sin(pi*d)*(6+j)+1;
+        for (i=1;i<d;i++) {
+          if (i&1)
+            dc->color=YELLOW;
+          else
+            dc->color=LTRED;
+          GrCircle(dc,tmpsp->p[j].x,tmpsp->p[j].y,i);
+        }
+      }
+    tmpsp=tmpsp->next;
+  }
+
+  tmps=shot_head.next;
+  while (tmps!=&shot_head) {
+    if (tmps->radius<1.0) {
+      dc->color=LTGREEN;
+      GrPlot(dc,tmps->p.x,tmps->p.y);
+    } else {
+      dc->color=YELLOW;
+      GrCircle(dc,tmps->p.x,tmps->p.y,tmps->radius);
+      if (tmps->radius>=2.0)
+        GrFloodFill(dc,tmps->p.x,tmps->p.y,TRUE);
+      dc->color=LTGREEN;
+      GrCircle(dc,tmps->p.x,tmps->p.y,tmps->radius);
+    }
+    tmps=tmps->next;
+  }
+
+  if (human && draw_laser_line) {
+    D3Sub(&p1,&human->p[1].x,&human->p[0].x);
+    D3Sub(&p2,&human->p[2].x,&human->p[0].x);
+    D3Unit(D3Add(&p,&p1,&p2));
+    dc->color=LTBLUE;
+    Line(dc,human->p[0].x-10*p.x,human->p[0].y-10*p.y,0,
+          human->p[0].x-800*p.x,human->p[0].y-800*p.y,0,&LaserPlot);
+  }
+
+  tmpmi=missile_head.next;
+  while (tmpmi!=&missile_head) {
+    if (tmpsp=tmpmi->target) {
+      dc->color=LTRED;
+      GrCircle(dc,tmpsp->p[0].x,tmpsp->p[0].y,10);
+      GrPrint(dc,tmpsp->p[0].x+12,tmpsp->p[0].y-4,tmpmi->label);
+    }
+    tmpmi=tmpmi->next;
+  }
+}
+
+U0 Explosion(MyMass *tmpm1,MyMass *tmpm2,F64 tons)
+{
+  MyMass *tmpm;
+  CD3 p1;
+  F64 d;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm!=tmpm1 && tmpm!=tmpm2) {
+      D3Sub(&p1,&tmpm->state->x,&tmpm1->state->x);
+      d=D3NormSqr(&p1)-tmpm->radius*tmpm->radius;
+      if (d<100.0*100.0) {
+        if (d<1)
+          d=1;
+        else
+          d=Sqrt(d);
+        d=250000*tons/d`2;
+        D3MulEqu(&p1,d);
+        D3AddEqu(&tmpm->DstateDt->DxDt,&p1);
+      }
+    }
+    tmpm=tmpm->next;
+  }
+}
+
+Ship TargetGet(Missile *tmpmi)
+{
+  Ship *tmpsp,*res=NULL;
+  F64 dd,best_dd=F64_MAX;
+  I64 i;
+  CD3 p,p1,p2;
+  D3Unit(D3Sub(&p,&tmpmi->p_front.state->x,&tmpmi->p_back.state->x));
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    if (!tmpsp->exploding && tmpsp!=tmpmi->owner)
+      for (i=0;i<tmpsp->masses;i++) {
+        D3Sub(&p1,&tmpsp->p[i].state->x,&tmpmi->p_front.state->x);
+        D3Unit(D3Copy(&p2,&p1));
+        D3Cross(&p1,&p,&p2);
+        if (D3Dot(&p,&p2)>0 && D3Norm(&p1)<=pi/16) {
+          dd=D3NormSqr(&p1);
+          if (dd<best_dd) {
+            best_dd=dd;
+            res=tmpsp;
+          }
+        }
+      }
+    tmpsp=tmpsp->next;
+  }
+  return res;
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+  I64 i;
+  F64 d,dd,dd2,spin,t_left,t_right,theta_err,theta_thrust,DthetaDt;
+  CTask *task=ode->win_task;
+  CD3 p,p1,p2;
+  Ship *tmpsp;
+  Missile *tmpmi;
+  MyMass *tmpm,*tmpm1;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type!=MT_SOLAR_FLARE && tmpm->type!=MT_ION) {
+      d=tmpm->state->x;
+      if (d-tmpm->radius<0)
+        tmpm->DstateDt->DxDt+=Sqr(Sqr(Sqr(d-tmpm->radius)));
+      if (d+tmpm->radius>task->pix_width)
+        tmpm->DstateDt->DxDt-=Sqr(Sqr(Sqr((d+tmpm->radius)-task->pix_width)));
+      d=tmpm->state->y;
+      if (d-tmpm->radius<0)
+        tmpm->DstateDt->DyDt+=Sqr(Sqr(Sqr(d-tmpm->radius)));
+      if (d+tmpm->radius>task->pix_height)
+        tmpm->DstateDt->DyDt-=Sqr(Sqr(Sqr((d+tmpm->radius)-task->pix_height)));
+    }
+    if (tmpm->type!=MT_ION && tmpm->type!=MT_ANTIMATTER_SPLAT) {
+      tmpm1=ode->next_mass;
+      while (tmpm1!=&ode->next_mass) {
+        if (tmpm!=tmpm1) {
+          if (tmpm1->type==MT_ANTIMATTER_SPLAT) {
+            if (tmpm->type==MT_HUMAN_SHIP || tmpm->type==MT_ENEMY_SHIP) {
+              D3Sub(&p,&tmpm->state->x,&tmpm1->state->x);
+              dd=D3NormSqr(&p)+1;
+              if (dd<100000) {
+                D3MulEqu(&p,100000/dd);
+                D3AddEqu(&tmpm1->DstateDt->DxDt,&p);
+              }
+            }
+          } else if (tmpm1->type!=MT_ION) {
+            D3Sub(&p,&tmpm->state->x,&tmpm1->state->x);
+            dd=D3NormSqr(&p);
+            dd2=Sqr(tmpm->radius+tmpm1->radius);
+            if (dd<=dd2) {
+              d=Sqrt(dd)+0.0001;
+              D3MulEqu(&p,Sqr(Sqr(dd2-dd))/d);
+              D3AddEqu(&tmpm ->DstateDt->DxDt,&p);
+              D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+            }
+          }
+        }
+        tmpm1=tmpm1->next;
+      }
+    }
+    tmpm=tmpm->next;
+  }
+
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    if (tmpsp->exploding && tmpsp->die_time<=tS<=tmpsp->die_timeout)
+      for (i=0;i<tmpsp->masses;i++)
+        Explosion(&tmpsp->p[i],NULL,tmpsp->p[i].radius/250.0);
+    switch (tmpsp->type) {
+      case ST_HUMAN1:
+        if (!tmpsp->exploding) {
+          if (tmpsp->spacewalk_side) {
+            t_left=0;
+            t_right=0;
+            d=1.0-(tmpsp->spacewalk_timeout-tS)/SPACEWALK_TIME;
+            if (0.485<d<0.515) {
+              D3Unit(D3Sub(&p,&tmpsp->p[2].state->x,&tmpsp->p[1].state->x));
+              if (tmpsp->spacewalk_side==3) {
+                tmpsp->p[3].DstateDt->DxDt-=10*THRUST_MAX*p.x;
+                tmpsp->p[3].DstateDt->DyDt-=10*THRUST_MAX*p.y;
+                tmpsp->p[1].DstateDt->DxDt+=10*THRUST_MAX*p.x;
+                tmpsp->p[1].DstateDt->DyDt+=10*THRUST_MAX*p.y;
+              } else {
+                tmpsp->p[4].DstateDt->DxDt+=10*THRUST_MAX*p.x;
+                tmpsp->p[4].DstateDt->DyDt+=10*THRUST_MAX*p.y;
+                tmpsp->p[2].DstateDt->DxDt-=10*THRUST_MAX*p.x;
+                tmpsp->p[2].DstateDt->DyDt-=10*THRUST_MAX*p.y;
+              }
+            }
+          } else {
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].state->x,
+                  &tmpsp->p[1].state->x))) {
+              D3Sub(&p2,&tmpsp->p[0].state->DxDt,&tmpsp->p[1].state->DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_left =Clamp(human_t_left+SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+
+            if (d=D3Norm(D3Sub(&p1,&tmpsp->p[0].state->x,
+                  &tmpsp->p[2].state->x))) {
+              D3Sub(&p2,&tmpsp->p[0].state->DxDt,&tmpsp->p[2].state->DxDt);
+              D3Cross(&p,&p1,&p2);
+              spin=p.z/d;
+            } else
+              spin=0;
+            t_right=Clamp(human_t_right-SPIN_GAIN*spin*human_antispin,
+                  0,THRUST_MAX);
+
+            D3Sub(&p1,&tmpsp->p[0].state->x,&tmpsp->p[1].state->x);
+            D3Sub(&p2,&tmpsp->p[0].state->x,&tmpsp->p[2].state->x);
+            D3Unit(D3Add(&p,&p1,&p2));
+            if (!(tmpsp->s[3].flags&SSF_INACTIVE)) {
+              D3Mul(&p1,t_left,&p);
+              D3AddEqu(&tmpsp->p[3].DstateDt->DxDt,&p1);
+            }
+            if (!(tmpsp->s[5].flags&SSF_INACTIVE)) {
+              D3Mul(&p2,t_right,&p);
+              D3AddEqu(&tmpsp->p[4].DstateDt->DxDt,&p2);
+            }
+          }
+        }
+        break;
+    }
+    tmpsp=tmpsp->next;
+  }
+
+  tmpmi=missile_head.next;
+  while (tmpmi!=&missile_head) {
+    if (tmpmi->active) {
+      if (tmpmi->launched) {
+        if (tmpmi->exploding)
+          Explosion(&tmpmi->p_front,&tmpmi->p_back,tmpmi->tons);
+        else {
+//Guide missile
+          if (tmpsp=tmpmi->target) {
+            D3Unit(D3Sub(&p,&tmpmi->p_front.state->x,
+                  &tmpmi->p_back.state->x));
+            D3Sub(&p1,&tmpsp->p[0].state->x,&tmpmi->p_front.state->x);
+            d=D3Norm(&p1);
+            D3Unit(&p1);
+            theta_err=D3Dot(&p,&p1);
+            D3Sub(&p1,&tmpmi->p_front.state->DxDt,&tmpmi->p_back.state->DxDt);
+            D3Cross(&p2,&p,&p1);
+            DthetaDt=D3Norm(&p2);
+            if (p2.z<0)
+              DthetaDt=-DthetaDt;
+            theta_thrust=Clamp(200*(theta_err+2*DthetaDt)/(d+200),-pi/8,pi/8);
+            p2.x=p.x*Cos(theta_thrust)-p.y*Sin(theta_thrust);
+            p2.y=p.y*Cos(theta_thrust)+p.x*Sin(theta_thrust);
+            p2.z=0;
+            D3AddEqu(&tmpmi->p_back.DstateDt->DxDt,D3MulEqu(&p2,THRUST_MAX));
+          }
+        }
+      } else
+        tmpmi->target=TargetGet(tmpmi);
+    } else
+      tmpmi->target=NULL;
+    tmpmi=tmpmi->next;
+  }
+}
+
+U0 CheckDamage()
+{
+  I64 i,j,death_score;
+  Ship *tmpsp,*tmpsp1;
+  MyMass *tmpm,*tmpm1,*best_mass;
+  CD3 p,p1,p2;
+  F64 d,best_distance;
+  Bool facing_sun=FALSE;
+
+  if (human) {
+    D3Sub(&p1,&human->p[1].x,&human->p[0].x);
+    D3Sub(&p2,&human->p[2].x,&human->p[0].x);
+    D3Add(&p,&p1,&p2);
+    if (p.x>0)
+      facing_sun=TRUE;
+  }
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type==MT_ION) {
+      if (facing_sun) {
+        tmpm1=ode->next_mass;
+        while (tmpm1!=&ode->next_mass) {
+          if (tmpm1->type==MT_HUMAN_SHIP) {
+            D3Sub(&p,&tmpm1->x,&tmpm->x);
+            if (D3NormSqr(&p)<Sqr(tmpm1->radius))
+              tmpm1->temperature+=3.0;
+          }
+          tmpm1=tmpm1->next;
+        }
+      }
+    } else if (tmpm->type==MT_ANTIMATTER_SPLAT) {
+      tmpm1=ode->next_mass;
+      while (tmpm1!=&ode->next_mass) {
+        if (tmpm1->type!=MT_ION && tmpm1->type!=MT_ANTIMATTER_SPLAT) {
+          D3Sub(&p,&tmpm1->x,&tmpm->x);
+          if (D3NormSqr(&p)<Sqr(tmpm1->radius))
+            tmpm1->temperature+=0.4;
+        }
+        tmpm1=tmpm1->next;
+      }
+    } else
+      tmpm->temperature*=0.9;
+    tmpm=tmpm->next;
+  }
+
+  if (human) {
+    human->laser_temperature*=0.975;
+
+    if (human->laser_overheat) {
+      if (human->laser_temperature<LASER_THRESHOLD_TEMP)
+        human->laser_overheat=FALSE;
+    }
+    if (!human->laser_overheat && human->lasering) {
+      if (human->laser_temperature>=LASER_TEMP_MAX) {
+        human->laser_overheat=TRUE;
+        Snd;
+      } else {
+        human->laser_temperature+=1.0;
+        D3Sub(&p1,&human->p[0].x,&human->p[1].x);
+        D3Sub(&p2,&human->p[0].x,&human->p[2].x);
+        D3Unit(D3Add(&p,&p1,&p2));
+        p2.x=p.y;
+        p2.y=-p.x;
+        p2.z=0;
+        best_mass=NULL;
+        best_distance=F64_MAX;
+        tmpm=ode->next_mass;
+        while (tmpm!=&ode->next_mass) {
+          D3Sub(&p1,&human->p[0].x,&tmpm->x);
+          if (Abs(D3Dot(&p1,&p2))<tmpm->radius &&
+                D3Dot(&p1,&p)<0.0) {
+            d=D3NormSqr(&p1);
+            if (d<best_distance) {
+              best_distance=d;
+              best_mass=tmpm;
+            }
+          }
+          tmpm=tmpm->next;
+        }
+        if (best_mass)
+          best_mass->temperature+=1.0;
+      }
+    }
+  }
+
+  tmpsp=ship_head.next;
+  while (tmpsp!=&ship_head) {
+    tmpsp1=tmpsp->next;
+    death_score=0;
+    switch (tmpsp->type) {
+      case ST_HUMAN1:
+        if (tmpsp->exploding) {
+          if (tS>tmpsp->die_timeout)  {
+            ShipDel(tmpsp);
+            human=NULL;
+          }
+        } else
+          for (i=0;i<tmpsp->springs;i++) {
+            if (Abs(tmpsp->s[i].f)>tmpsp->s[i].strength) {
+              tmpsp->s[i].flags|=SSF_INACTIVE;
+              if (i==4)
+                MissileDel(&tmpsp->missiles[0]);
+              else if (i==5)
+                MissileDel(&tmpsp->missiles[1]);
+            }
+            if (tmpsp->s[i].flags&SSF_INACTIVE && i<3)
+              death_score++;
+          }
+        break;
+      default:
+        if (tmpsp->exploding) {
+          if (tS>tmpsp->die_timeout) {
+            ShipDel(tmpsp);
+            score+=level;
+            if (score>best_score)
+              best_score=score;
+          }
+        } else {
+          j=0;
+          for (i=0;i<tmpsp->springs;i++) {
+            if (tmpsp->s[i].flags&SSF_INACTIVE)
+              j++;
+            else if (Abs(tmpsp->s[i].f)>tmpsp->s[i].strength) {
+              tmpsp->s[i].flags|=SSF_INACTIVE;
+              j++;
+            }
+          }
+          if (j>1)
+            death_score++;
+        }
+    }
+    if (!tmpsp->exploding) {
+      for (i=0;i<tmpsp->masses;i++)
+        if (tmpsp->p[i].temperature>MASS_TEMP_MAX)
+          death_score++;
+      if (death_score) {
+        tmpsp->exploding=TRUE;
+        tmpsp->die_time=tS;
+        tmpsp->die_timeout=tS+0.75;
+        Noise(750,74,93);
+        if (tmpsp->type==ST_HUMAN1)
+          game_over=TRUE;
+      }
+    }
+    tmpsp=tmpsp1;
+  }
+}
+
+//********************************** Shots
+
+Shot *ShotNew(I64 type,CD3 *_p,CD3 *_v,F64 r,F64 fuse_time,
+        CD3 *_p_gun_offset=NULL)
+{
+  Shot *tmps=CAlloc(sizeof(Shot));
+  D3Copy(&tmps->p.x,_p);
+  tmps->radius=r;
+  tmps->splats=20*r;
+  tmps->fuse_time=tS+fuse_time;
+  tmps->p.mass=0.3*r*r*r;
+  tmps->p.type=type;
+  if (_p_gun_offset)
+    D3AddEqu(&tmps->p.x,_p_gun_offset);
+  D3Copy(&tmps->p.DxDt,_v);
+  QueIns(&tmps->p,ode->last_mass);
+  QueIns(tmps,shot_head.last);
+}
+
+U0 SolarFlares()
+{
+  CD3 p,v,p1,p2;
+  CTask *task=ode->win_task;
+  if (!alarm && t_solar_storm-2.0<tS<t_solar_storm+1.0) {
+    Sweep(2000,74,93);
+    alarm=TRUE;
+  }
+  if (t_solar_storm<tS) {  //If solar storm has arrived
+    if (tS<t_solar_storm+5.0) { //If solar storm not over
+      if (Rand<.1) {
+        D3Equ(&p,-300,Rand*task->pix_height,0);
+        D3Equ(&v,200.0,0,0);
+        ShotNew(MT_SOLAR_FLARE,&p,&v,25,0.1);
+      }
+    } else {
+      t_solar_storm=tS+25*Rand;  //Schedule next solar storm
+      alarm=FALSE;
+    }
+  }
+}
+
+U0 FireOneGun(Ship *tmpsp,I64 n,F64 r,F64 fuse_time)
+{
+  I64 ona;
+  CD3 p,v,p1,p2;
+  Shot *tmps;
+  D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x);
+  D3Sub(&p2,&tmpsp->p[0].x,&tmpsp->p[2].x);
+  D3Unit(D3Add(&p,&p1,&p2));
+  D3MulEqu(D3Copy(&p1,&p),r+tmpsp->p[0].radius+5);
+  D3AddEqu(D3MulEqu(D3Copy(&v,&p),1000/(r+1)),&tmpsp->p[n].DxDt);
+  tmps=ShotNew(MT_ANTIMATTER_BALL,&tmpsp->p[n].x,&v,r,fuse_time,&p1);
+  D3MulEqu(&p,tmps->p.mass/tmpsp->p[n].mass/100.0);
+  D3SubEqu(&tmpsp->p[n].DxDt,&p);
+  tmpsp->reload_timeout=tS+r/tmpsp->fire_rate;
+  ona=Freq2Ona(500/r);
+  Noise(100,ona,ona+12);
+}
+
+U0 FireOneMissile(Ship *tmpsp,I64 n)
+{
+  I64 i;
+  Missile *tmpmi=&tmpsp->missiles[n];
+  if (!tmpmi->launched && tmpmi->target) {
+    tmpmi->fuse_time=tS+1.0;
+    tmpmi->die_timeout=tmpmi->fuse_time+0.125;
+    tmpmi->img=<8>;
+    for (i=1;i<5;i++)
+      tmpmi->s[i].flags|=SSF_INACTIVE;
+    tmpmi->launched=TRUE;
+    Sweep(250,53,56);
+  }
+}
+
+U0 HumanFireGunBegin()
+{
+  F64 r=3.0*ctrl_panel.shot_radius/CTRL_PANEL_RANGE+0.5,
+        fuse_time=ToF64(ctrl_panel.fuse_time+1)/CTRL_PANEL_RANGE;
+  if (human) {
+    if (!human->exploding && !human->spacewalk_side && tS>human->reload_timeout)
+      switch (level) {
+        case 3:
+          if (!(human->s[3].flags&SSF_INACTIVE))
+            FireOneGun(human,3,r,fuse_time);
+          if (!(human->s[5].flags&SSF_INACTIVE))
+            FireOneGun(human,4,r,fuse_time);
+        case 2:
+          if (!(human->s[1].flags&SSF_INACTIVE))
+            FireOneGun(human,1,r,fuse_time);
+          if (!(human->s[2].flags&SSF_INACTIVE))
+            FireOneGun(human,2,r,fuse_time);
+        case 1:
+          FireOneGun(human,0,r,fuse_time);
+          break;
+      }
+  }
+}
+
+U0 HumanFireMissileBegin(I64 n)
+{
+  if (human && !human->exploding &&
+        !human->spacewalk_side && tS>human->reload_timeout)
+    FireOneMissile(human,n);
+}
+
+U0 HumanFireLaserBegin()
+{
+  if (human && !human->exploding &&
+        !human->spacewalk_side && tS>human->reload_timeout)
+    human->lasering=TRUE;
+}
+U0 HumanFireLaserEnd()
+{
+  if (human && !human->exploding) {
+    human->lasering=FALSE;
+    Snd;
+  }
+}
+
+U0 SplatNew(Shot *tmps,F64 die_time,F64 start,F64 end)
+{
+  MyMass *tmpm;
+  F64 theta=Arg(tmps->p.DxDt,tmps->p.DyDt);
+  I64 i;
+  for (i=0;i<tmps->splats;i++) {
+    tmpm=CAlloc(sizeof(MyMass));
+    D3Copy(&tmpm->x,&tmps->p.x);
+    tmpm->radius=1;
+    tmpm->mass=1;
+    tmpm->die_timeout=tS+die_time;
+    if (tmps->p.type==MT_SOLAR_FLARE)
+      tmpm->type=MT_ION;
+    else
+      tmpm->type=MT_ANTIMATTER_SPLAT;
+    D3Copy(&tmpm->DxDt,&tmps->p.DxDt);
+    tmpm->DxDt+=50*Sqr(tmps->radius)*Rand*
+          Sin(start+theta+(end-start)*i/tmps->splats);
+    tmpm->DyDt+=50*Sqr(tmps->radius)*Rand*
+          Cos(start+theta+(end-start)*i/tmps->splats);
+    QueIns(tmpm,ode->last_mass);
+  }
+}
+
+U0 ExpireShots()
+{
+  Shot *tmps=shot_head.next,*tmps1;
+  while (tmps!=&shot_head) {
+    tmps1=tmps->next;
+    if (tS>tmps->fuse_time) {
+      if (tmps->p.type==MT_SOLAR_FLARE)
+        SplatNew(tmps,1.0,3*pi/8,5*pi/8);
+      else
+        SplatNew(tmps,.2,0,2*pi);
+      QueRem(tmps);
+      QueRem(&tmps->p);
+      Free(tmps);
+    }
+    tmps=tmps1;
+  }
+}
+
+U0 ExpireSplats()
+{
+  MyMass *tmpm,*tmpm1;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=tmpm->next;
+    if ((tmpm->type==MT_ION || tmpm->type==MT_ANTIMATTER_SPLAT) &&
+          tS>tmpm->die_timeout) {
+      QueRem(tmpm);
+      Free(tmpm);
+    }
+    tmpm=tmpm1;
+  }
+}
+
+U0 ExpireMissiles()
+{
+  I64 i;
+  F64 dd,best_dd;
+  Missile *tmpmi=missile_head.next,*tmpm1;
+  while (tmpmi!=&missile_head) {
+    tmpm1=tmpmi->next;
+    if (tmpmi->launched) {
+      best_dd=F64_MAX;
+      if (tmpmi->target)
+        for (i=0;i<tmpmi->target->masses;i++) {
+          dd=D3DistSqr(&tmpmi->p_front.x,&tmpmi->target->p[i].x);
+          if (dd<best_dd)
+            best_dd=dd;
+        }
+      if (!tmpmi->exploding && (best_dd<30*30 || tS>tmpmi->fuse_time)) {
+        tmpmi->p_front.mass=10.0; //They go flying, if too light.
+        tmpmi->p_back.mass =10.0;
+        tmpmi->exploding=TRUE;
+        Noise(50,93,105);
+      } else if (tS>tmpmi->die_timeout)
+        MissileDel(tmpmi);
+    }
+    tmpmi=tmpm1;
+  }
+}
+
+//********************************** AI
+
+U0 AI()
+{
+  CD3 p,p1,p2;
+  Ship *tmpsp=ship_head.next;
+  if (human && !human->exploding) {
+    while (tmpsp!=&ship_head) {
+      D3Sub(&p1,&tmpsp->p[0].x,&tmpsp->p[1].x);
+      D3Sub(&p2,&tmpsp->p[0].x,&tmpsp->p[2].x);
+      D3Add(&p,&p1,&p2);
+      D3Sub(&p1,&human->p[0].x,&tmpsp->p[0].x);
+      if (D3Dot(D3Unit(&p),D3Unit(&p1))>0.995 &&
+            tS>tmpsp->reload_timeout) {
+        FireOneGun(tmpsp,0,1.5+.5,.4);
+      }
+      tmpsp=tmpsp->next;
+    }
+  }
+}
+
+//********************************** Init
+U0 InitLevel()
+{
+  I64 i;
+  MyMass *tmpm,*tmpm1;
+
+  t_solar_storm=0;
+
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=tmpm->next;
+    if (tmpm->type==MT_ION || tmpm->type==MT_ANTIMATTER_SPLAT) {
+      QueRem(tmpm);
+      Free(tmpm);
+    }
+    tmpm=tmpm1;
+  }
+  if (level==1)
+    OneTimePopUp(&msg_flags,XMSGF_SOLAR_STORM,
+          "Face away from Sun in solar storm.\n");
+  if (level==4)
+    OneTimePopUp(&msg_flags,XMSGF_ANTISPIN,
+          "Press $GREEN$<CURSOR-DOWN>$FG$ for anti-spin stabilizer.\n");
+  human=ShipNew(Fs->pix_width/2,Fs->pix_height/2,ST_HUMAN1);
+  for (i=0;i<level+2;i++)
+    PlaceShip(ST_ENEMY1);
+  PlaceShip(ST_ENEMY2);
+  show_level_msg=TRUE;
+  ODEPause(ode);
+}
+
+U0 Init()
+{
+  I64 i;
+  game_over=FALSE;
+  score=0;
+  level=1;
+
+  QueInit(&ship_head);
+  QueInit(&shot_head);
+  QueInit(&missile_head);
+
+  for (i=0;i<STARS_NUM;i++) {
+    stars_x[i]=RandU16%GR_WIDTH;
+    stars_y[i]=RandU16%GR_HEIGHT;
+  }
+
+  human_t_left=0;
+  human_t_right=0;
+  human_antispin=0;
+
+  InitLevel;
+}
+
+//********************************** Main
+U0 XCaliber()
+{
+  I64 ch,msg_code,arg1,arg2,sc;
+  CCtrl *cp=CtrlPanelNew;
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+WHITE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Game {"
+        "  Restart(,'\n');"
+        "  LevelUp(,'+');"
+        "  LevelDown(,'-');"
+        "}"
+        "Play {"
+        "  Fire(,CH_SPACE);"
+        "  Thrust(,,SC_CURSOR_UP);"
+        "  StopSpin(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  LeftMissile(,,SC_CURSOR_LEFT|SCF_CTRL);"
+        "  RightMissile(,,SC_CURSOR_RIGHT|SCF_CTRL);"
+        "  Spackwalk(,'w');"
+        "  LongerFuse(,,SC_CURSOR_RIGHT|SCF_SHIFT);"
+        "  ShorterFuse(,,SC_CURSOR_LEFT|SCF_SHIFT);"
+        "  LargerShot(,,SC_CURSOR_UP|SCF_SHIFT);"
+        "  SmallerShot(,,SC_CURSOR_DOWN|SCF_SHIFT);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  Fs->draw_it=&DrawIt;
+  do {
+    ode=ODENew(0,0.01,ODEF_HAS_MASSES);
+    ode->derive=&MyDerivative;
+    ode->min_tolerance=1e-9;
+    ode->drag_v3=0.00001;
+    Init;
+    QueIns(ode,Fs->last_ode);
+    ch=0;
+    do {
+      while (!game_over && !show_level_msg &&
+            (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP))) {
+        switch (msg_code) {
+          case MSG_KEY_DOWN:
+            ch=arg1; sc=arg2;
+            switch (ch) {
+              case 0:
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    if (sc&SCF_CTRL)
+                      HumanFireMissileBegin(0);
+                    else if (sc&SCF_SHIFT)
+                      ctrl_panel.fuse_time+=2;
+                    else
+                      human_t_right=THRUST_MAX;
+                    break;
+                  case SC_CURSOR_LEFT:
+                    if (sc&SCF_CTRL)
+                      HumanFireMissileBegin(1);
+                    else if (sc&SCF_SHIFT)
+                      ctrl_panel.fuse_time-=2;
+                    else
+                      human_t_left =THRUST_MAX;
+                    break;
+                  case SC_CURSOR_UP:
+                    if (sc&SCF_SHIFT)
+                      ctrl_panel.shot_radius+=2;
+                    else {
+                      human_t_right=THRUST_MAX;
+                      human_t_left =THRUST_MAX;
+                    }
+                    break;
+                  case SC_CURSOR_DOWN:
+                    if (sc&SCF_SHIFT)
+                      ctrl_panel.shot_radius-=2;
+                    else
+                      human_antispin=ANTISPIN_MAX;
+                    break;
+                }
+                break;
+              case CH_SPACE:
+                if (level<4)
+                  HumanFireGunBegin;
+                else
+                  HumanFireLaserBegin;
+                break;
+              case 'w':
+                ctrl_panel.spacewalk=TRUE;
+                break;
+              case '+':
+                level++;
+                break;
+              case '-':
+                level--;
+                break;
+            }
+            break;
+          case MSG_KEY_UP:
+            ch=arg1; sc=arg2;
+            switch (ch) {
+              case 0:
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    human_t_right=0;
+                    break;
+                  case SC_CURSOR_LEFT:
+                    human_t_left =0;
+                    break;
+                  case SC_CURSOR_UP:
+                    human_t_right=0;
+                    human_t_left =0;
+                    break;
+                  case SC_CURSOR_DOWN:
+                    human_antispin=0;
+                    break;
+                }
+                break;
+              case '\n':
+                ch=0;
+                break;
+              case CH_SPACE:
+                if (level>=4)
+                  HumanFireLaserEnd;
+                break;
+            }
+            break;
+        }
+      }
+      AI;
+      SolarFlares;
+      ExpireShots;
+      ExpireSplats;
+      ExpireMissiles;
+      CheckDamage;
+      Refresh; //msgs are only qued by winmgr
+      if (show_level_msg) {
+        ch=GetKey(&sc);
+        if (ch=='\n')
+          ch=0;
+        ODEPause(ode,OFF);
+        show_level_msg=FALSE;
+      } else if (game_over) {
+        ch=ScanChar;
+      } else {
+        if (!remaining) {
+          level++;
+          ShipDel(human);
+          human=NULL;
+          InitLevel;
+        }
+      }
+    } while (ch!=CH_ESC && ch!='\n' && ch!=CH_SHIFT_ESC);
+    AllDel(ode);
+  } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  SettingsPop;
+  CtrlPanelDel(cp);
+  MenuPop;
+  RegWrite("TempleOS/XCaliber",
+        "I64 best_score=%d;\n"
+        "I64 msg_flags=%d;\n",best_score,msg_flags);
+}
+
+ diff --git a/public/Wb/Home/Src/Apps/X-Caliber/XCCtrls.HC.HTML b/public/Wb/Home/Src/Apps/X-Caliber/XCCtrls.HC.HTML new file mode 100755 index 0000000..d669b5e --- /dev/null +++ b/public/Wb/Home/Src/Apps/X-Caliber/XCCtrls.HC.HTML @@ -0,0 +1,185 @@ + + + + + + + + + + + +
+#define LASER_TEMP_MAX          30.0
+#define LASER_THRESHOLD_TEMP    10.0
+#define MASS_TEMP_MAX           5.0
+
+class CtrlPanelState
+{
+  I64 shot_radius,fuse_time;
+  F64 laser_temperature;
+  Bool spacewalk;
+} ctrl_panel;
+
+#define CTRL_PANEL_SPACING 33
+#define CTRL_PANEL_RANGE   30
+#define CTRL_PANEL_BORDER  2
+#define CTRL_PANEL_BTTN_SIZE    12
+
+#define TMP_Y   (+2)
+
+U0 DrawCtrlPanelCtrl(CDC *dc,CCtrl *c)
+{
+  CtrlPanelState *s=c->state;
+  F64 d,d_range;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,CTRL_PANEL_SPACING*3+2,
+        CTRL_PANEL_SPACING*2+CTRL_PANEL_RANGE+CTRL_PANEL_BTTN_SIZE);
+  dc->color=DKGRAY;
+  GrRect(dc, c->left+CTRL_PANEL_BORDER,c->top+CTRL_PANEL_BORDER,
+        CTRL_PANEL_SPACING*3+2-2*CTRL_PANEL_BORDER,
+        CTRL_PANEL_SPACING*2+CTRL_PANEL_RANGE+CTRL_PANEL_BTTN_SIZE
+        -2*CTRL_PANEL_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+CTRL_PANEL_SPACING,(c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING,c->left+CTRL_PANEL_SPACING,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE-1);
+  GrLine(dc,c->left+2*CTRL_PANEL_SPACING+1,(c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING,c->left+2*CTRL_PANEL_SPACING+1,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE-1);
+
+  dc->color=BLACK;
+  GrRect(dc,(c->left+c->right+1)/2-9*FONT_WIDTH/2-3,
+        c->top+CTRL_PANEL_BORDER+(CTRL_PANEL_SPACING-FONT_HEIGHT)/2,
+        9*FONT_WIDTH+6,FONT_HEIGHT+6);
+
+  if (s->spacewalk)
+    dc->color=YELLOW;
+  else
+    dc->color=DKGRAY;
+  GrRect(dc,(c->left+c->right+1)/2-9*FONT_WIDTH/2-2,
+        c->top+CTRL_PANEL_BORDER+1+(CTRL_PANEL_SPACING-FONT_HEIGHT)/2,
+        9*FONT_WIDTH+4,FONT_HEIGHT+4);
+
+  dc->color=RED;
+  GrPrint(dc,(c->left+c->right+1)/2-9*FONT_WIDTH/2,
+        c->top+CTRL_PANEL_BORDER+3+
+        (CTRL_PANEL_SPACING-FONT_HEIGHT)/2,"SpaceWalk");
+  GrPrint(dc,c->left+CTRL_PANEL_SPACING-4*FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING-FONT_HEIGHT-2,"Size");
+  GrPrint(dc,c->left+2*CTRL_PANEL_SPACING+1-4*FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+
+        CTRL_PANEL_SPACING-FONT_HEIGHT-2,"Fuse");
+  dc->color=LTRED;
+  GrPrint(dc,c->left+CTRL_PANEL_SPACING-FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE+3,
+        "%d",s->shot_radius*10/CTRL_PANEL_RANGE);
+  GrPrint(dc,c->left+2*CTRL_PANEL_SPACING+1-FONT_WIDTH/2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+CTRL_PANEL_RANGE+3,
+        "%d",s->fuse_time*10/CTRL_PANEL_RANGE);
+  GrRect(dc,c->left+CTRL_PANEL_SPACING-3,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->shot_radius-2 ,7,5);
+  GrRect(dc,c->left+2*CTRL_PANEL_SPACING+1-3,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->fuse_time-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+CTRL_PANEL_SPACING-2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->shot_radius-1 ,5,3);
+  GrRect(dc,c->left+2*CTRL_PANEL_SPACING+1-2,
+        (c->top+CTRL_PANEL_BTTN_SIZE)+CTRL_PANEL_SPACING+
+        CTRL_PANEL_RANGE-1-s->fuse_time-1,5,3);
+
+  d_range=c->right-c->left-5-5;
+  d=s->laser_temperature*d_range/LASER_TEMP_MAX;
+  dc->color=BLACK;
+  GrRect(dc,c->left+5-1,c->bottom+TMP_Y-2,d_range+2,2+1+1);
+  if (d>1.0) {
+    dc->color=GREEN;
+    GrRect(dc,c->left+5,c->bottom+TMP_Y-1,Min(d,d_range/3),2);
+    if (d>=d_range/3) {
+      dc->color=YELLOW;
+      GrRect(dc,c->left+5+d_range/3,c->bottom+TMP_Y-1,
+            Min(d,2*d_range/3)-d_range/3,2);
+      if (d>=2*d_range/3) {
+        dc->color=RED;
+        GrRect(dc,c->left+5+2*d_range/3,c->bottom+TMP_Y-1,d-2*d_range/3,2);
+      }
+    }
+  }
+}
+
+U0 UpdateDerivedCtrlPanelCtrl(CCtrl *c)
+{
+  CtrlPanelState *s=c->state;
+  c->left=c->win_task->pix_width-(CTRL_PANEL_SPACING*3+2);
+  c->right=c->left+CTRL_PANEL_SPACING*3+2;
+  c->top=c->win_task->pix_height-(CTRL_PANEL_SPACING*2+
+        CTRL_PANEL_RANGE+CTRL_PANEL_BTTN_SIZE);
+  c->bottom=c->top+CTRL_PANEL_SPACING*2+CTRL_PANEL_RANGE;
+
+  s->shot_radius=ClampI64(s->shot_radius,0,CTRL_PANEL_RANGE-1);
+  s->fuse_time=ClampI64(s->fuse_time,0,CTRL_PANEL_RANGE-1);
+}
+
+U0 LeftClickCtrlPanel(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CtrlPanelState *s=c->state;
+  if (y<c->top+CTRL_PANEL_BORDER+(CTRL_PANEL_SPACING-FONT_HEIGHT)/2+
+        FONT_HEIGHT+6)
+    s->spacewalk=TRUE;
+  else {
+    if (x<(c->right+c->left)/2)
+      s->shot_radius=CTRL_PANEL_RANGE-1
+            -(y-(c->top+CTRL_PANEL_SPACING+CTRL_PANEL_BTTN_SIZE));
+    else
+      s->fuse_time=CTRL_PANEL_RANGE-1
+            -(y-(c->top+CTRL_PANEL_SPACING+CTRL_PANEL_BTTN_SIZE));
+  }
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *CtrlPanelNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  MemSet(&ctrl_panel,0,sizeof(ctrl_panel));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&ctrl_panel;
+  c->draw_it=&DrawCtrlPanelCtrl;
+  c->left_click=&LeftClickCtrlPanel;
+  c->update_derived_vals=&UpdateDerivedCtrlPanelCtrl;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 CtrlPanelDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/Asm.HC.HTML b/public/Wb/Home/Src/Compiler/Asm.HC.HTML new file mode 100755 index 0000000..851864f --- /dev/null +++ b/public/Wb/Home/Src/Compiler/Asm.HC.HTML @@ -0,0 +1,1145 @@ + + + + + + + + + + + +
+Bool PrsAsmImm(CCmpCtrl *cc,CAsmArg *arg)
+{
+  if (arg->imm_or_off_present)
+    LexExcept(cc,"Already one immediate at ");
+  arg->imm_or_off_present=TRUE;
+  arg->num.local_asm_undef_hash=NULL;
+  arg->num.glbl_asm_undef_hash=NULL;
+  cc->asm_undef_hash=NULL;
+  cc->abs_cnts=0;
+  cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);
+  if (!IsLexExpression2Bin(cc,&arg->num.machine_code))
+    LexSkipEol(cc);
+  else {
+    if (cc->abs_cnts.externs)
+      LexExcept(cc,"Extern Not Allowed at ");
+    if (cc->flags & CCF_UNRESOLVED) {
+      if (cc->flags & CCF_LOCAL) {
+        arg->num.local_asm_undef_hash=cc->asm_undef_hash;
+        cc->asm_undef_hash=NULL;
+      } else {
+        arg->num.glbl_asm_undef_hash=cc->asm_undef_hash;
+        cc->asm_undef_hash=NULL;
+      }
+    } else {
+      arg->num.i=Call(arg->num.machine_code);
+      arg->num.glbl_asm_undef_hash=cc->asm_undef_hash;
+      cc->asm_undef_hash=NULL;
+      Free(arg->num.machine_code);
+      arg->num.machine_code=NULL;
+    }
+  }
+  return TRUE;
+}
+
+U0 PrsAsmArg(CCmpCtrl *cc,CAsmArg *arg,Bool rel)
+{
+  CHashGeneric *tmph,*tmph1;
+  CHashReg *tmpr;
+  MemSet(arg,0,sizeof(CAsmArg));
+  arg->seg =REG_NONE;
+  arg->reg1=REG_NONE;
+  arg->reg2=REG_NONE;
+  arg->scale=1;
+  while (TRUE) {
+    if (cc->token==TK_IDENT) {
+      if (tmph=cc->hash_entry) {
+        if (tmph->type&HTG_TYPE_MASK==HTT_REG) {
+          tmpr=tmph;
+          arg->reg1_type=tmpr->reg_type;
+          switch (tmpr->reg_type) {
+            start:
+              case REGT_R8:
+                arg->size=1;
+                break;
+              case REGT_R16:
+                arg->size=2;
+                break;
+              case REGT_R32:
+                arg->size=4;
+                break;
+              case REGT_R64:
+                arg->size=8;
+                break;
+            end:
+              arg->reg1=tmpr->reg_num;
+              Lex(cc);
+              return;
+            case REGT_SEG:
+              arg->seg=tmpr->reg_num;
+              if (Lex(cc)!=':') {
+                arg->just_seg=TRUE;
+                return;
+              } else
+                Lex(cc); //skip ":"
+              break;
+            case REGT_FSTK:
+            case REGT_MM:
+            case REGT_XMM:
+              arg->size=8;
+              arg->reg1=tmpr->reg_num;
+              Lex(cc);
+              return;
+          }
+        } else {
+          if ((tmph->type&HTG_TYPE_MASK==HTT_CLASS||
+                tmph->type&HTG_TYPE_MASK==HTT_INTERNAL_TYPE) &&
+                (tmph1=HashFind(cc->cur_str,cmp.asm_hash,HTT_ASM_KEYWORD)))
+            tmph=tmph1;
+          if (tmph->type&HTG_TYPE_MASK==HTT_ASM_KEYWORD) {
+            switch (tmph->user_data0) {
+              case AKW_I8:
+              case AKW_U8:
+                arg->size=1;
+                break;
+              case AKW_I16:
+              case AKW_U16:
+                arg->size=2;
+                break;
+              case AKW_I32:
+              case AKW_U32:
+                arg->size=4;
+                break;
+              case AKW_I64:
+              case AKW_U64:
+                arg->size=8;
+                break;
+              default:
+                LexExcept(cc,"syntax error at ");
+            }
+            Lex(cc); //skip keyword
+          } else
+            goto pa_asm_direct_imm;
+        }
+      } else {
+pa_asm_direct_imm:
+        PrsAsmImm(cc,arg);
+        arg->num.abs_cnts=cc->abs_cnts;
+        if (arg->size<=1 && !rel && arg->num.abs_cnts&1) {
+          if (cc->aotc->seg_size==16)
+            arg->size=2;
+          else
+            arg->size=4;
+        }
+        if (cc->token!='[')
+          return;
+      }
+    } else if (cc->token=='[') {
+      arg->indirect=TRUE;
+      Lex(cc); // skip [
+      while (cc->token && cc->token!=']') {
+        if (cc->token==TK_IDENT) {
+          if (tmph=cc->hash_entry) {
+            if (tmph->type&HTG_TYPE_MASK==HTT_REG &&
+                  REGT_R16<=tmph(CHashReg *)->reg_type<=REGT_R64) {
+              tmpr=tmph;
+              arg->reg2_type=tmpr->reg_type;
+              if (arg->reg1==REG_NONE) {
+                if (tmpr->reg_num&7==REG_RSP) {
+                  arg->reg1=4;
+                  arg->reg2=tmpr->reg_num;
+                } else
+                  arg->reg1=tmpr->reg_num;
+              } else
+                arg->reg2=tmpr->reg_num;
+              Lex(cc);
+            } else
+              goto pa_asm_indirect_imm;
+          } else
+            goto pa_asm_indirect_imm;
+        } else if (cc->token=='*') {
+          Lex(cc);
+          if (cc->token!=TK_I64)
+            LexExcept(cc,"Expecting scale factor at ");
+          arg->scale=cc->cur_i64;
+          Lex(cc); //skip scale
+          if (arg->reg2!=REG_NONE) {
+            SwapI64(&arg->reg1,&arg->reg2);
+            SwapI64(&arg->reg1_type,&arg->reg2_type);
+          }
+        } else if (cc->token=='+') {
+          Lex(cc); //skip '+'
+        } else {
+pa_asm_indirect_imm:
+          PrsAsmImm(cc,arg);
+          arg->num.abs_cnts=cc->abs_cnts;
+        }
+      }
+      if (cc->token!=']')
+        LexExcept(cc,"Missing ']' at ");
+      Lex(cc); //skip ]
+      return;
+    } else
+      goto pa_asm_direct_imm;
+  }
+}
+
+I64 AsmMakeArgMask(CCmpCtrl *cc,CAsmArg *arg)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 res;
+  if (arg->just_seg) {
+    switch (arg->seg) {
+      case 0: res=1<<ARGT_ES|1<<ARGT_SREG; break;
+      case 1: res=1<<ARGT_CS|1<<ARGT_SREG; break;
+      case 2: res=1<<ARGT_SS|1<<ARGT_SREG; break;
+      case 3: res=1<<ARGT_DS|1<<ARGT_SREG; break;
+      case 4: res=1<<ARGT_FS|1<<ARGT_SREG; break;
+      case 5: res=1<<ARGT_GS|1<<ARGT_SREG; break;
+    }
+    goto mm_done;
+  }
+  if (arg->reg1_type==REGT_FSTK) {
+    if (arg->reg1)
+      res=1<<ARGT_STI;
+    else
+      res=1<<ARGT_ST0|1<<ARGT_STI;
+    goto mm_done;
+  }
+  res=cmp.size_arg_mask[arg->size];
+  if (aotc->seg_size==64)
+    res&=0xFF0FFFFFFF;
+
+  if (arg->reg1!=REG_NONE && arg->imm_or_off_present && !arg->num.i &&
+        !arg->num.glbl_asm_undef_hash && !arg->num.local_asm_undef_hash)
+    arg->imm_or_off_present=FALSE;  //Zero displacement
+
+  if (arg->reg2!=REG_NONE || arg->scale!=1) {
+    res&=0x0000FF0000;
+    goto mm_done;
+  }
+
+  if (arg->indirect) {
+    if (arg->imm_or_off_present)
+      res&=0x00FFFF0000;
+    else
+      res&=0x000FFF0000;
+  } else {
+    if (arg->imm_or_off_present)
+      res&=0x000F000FFE;
+    else
+      res&=0x3F0FFFF000;
+  }
+  if (arg->seg!=REG_NONE)
+    res&=0x00FFFF0000;
+  if (arg->reg1==REG_NONE) {
+    if (arg->indirect)
+      res&=0x00FFFF0000;
+    else if (arg->num.i<0) {
+      if (arg->num.i>=I8_MIN)
+        res&=0x8FE;
+      else if (arg->num.i>=I16_MIN)
+        res&=0x8EE;
+      else if (arg->num.i>=I32_MIN)
+        res&=0x8CE;
+      else
+        res&=0x88E;
+    } else {
+      if (arg->num.i<=I8_MAX)
+        res&=0xFFE;
+      else if (arg->num.i<=U8_MAX)
+        res&=0xFEE;
+      else if (arg->num.i<=I16_MAX)
+        res&=0xEEE;
+      else if (arg->num.i<=U16_MAX)
+        res&=0xECE;
+      else if (arg->num.i<=I32_MAX)
+        res&=0xCCE;
+      else if (arg->num.i<=U32_MAX)
+        res&=0xC8E;
+      else
+        res&=0x88E;
+    }
+  } else {
+    res&=  0x3F00FFF000;
+    if (!arg->indirect) //M8-M64
+      res&=0xFFFF0FFFFF;
+  }
+  switch (arg->reg1) {
+    case REG_RAX: res&=~0x3000000000; break;
+    case REG_RCX: res&=~0x2F00000000; break;
+    case REG_RDX: res&=~0x1F00000000; break;
+    default:      res&=~0x3F00000000;
+  }
+mm_done:
+  return res;
+}
+
+Bool AsmStoreNum(CCmpCtrl *cc,CAsmNum2 *num2,I64 cnt,Bool U8_avail)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i;
+  CAOTAbsAddr *tmpa;
+
+  if (!num2->imm_flag)
+    num2->num.i-=num2->rel;
+  for (i=0;i<cnt;i++) {
+    if (num2->U8_cnt==1) {
+      if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+        AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I8+num2->imm_flag,
+              aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+              num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+              U8_avail);
+      else if (!num2->imm_flag && !(I8_MIN<=num2->num.i<=I8_MAX))
+        LexExcept(cc,"Branch out of range at ");
+      if (num2->imm_flag) {
+        if (num2->num.abs_cnts.abs_addres&1) {
+          tmpa=CAlloc(sizeof(CAOTAbsAddr));
+          tmpa->next=aotc->abss;
+          aotc->abss=tmpa;
+          tmpa->rip=aotc->rip;
+          tmpa->type=AAT_ADD_U8;
+        }
+      } else {
+        if (num2->num.abs_cnts.c_addres&1) {
+          tmpa=CAlloc(sizeof(CAOTAbsAddr));
+          tmpa->next=aotc->abss;
+          aotc->abss=tmpa;
+          tmpa->rip=aotc->rip;
+          tmpa->type=AAT_SUB_U8;
+        }
+      }
+      AOTStoreCodeU8(cc,num2->num.i);
+    } else {
+      if (num2->U8_cnt==2) {
+        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I16+num2->imm_flag,
+                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+                U8_avail);
+        else if (!num2->imm_flag && !(I16_MIN<=num2->num.i<=I16_MAX))
+          LexExcept(cc,"Branch out of range at ");
+        if (num2->imm_flag) {
+          if (num2->num.abs_cnts.abs_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_ADD_U16;
+          }
+        } else {
+          if (num2->num.abs_cnts.c_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_SUB_U16;
+          }
+        }
+        AOTStoreCodeU8(cc,num2->num.i.u8[0]);
+        AOTStoreCodeU8(cc,num2->num.i.u8[1]);
+      } else if (num2->U8_cnt==4) {
+        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I32+num2->imm_flag,
+                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+                U8_avail);
+        else if (!num2->imm_flag && !(I32_MIN<=num2->num.i<=I32_MAX))
+          LexExcept(cc,"Branch out of range at ");
+        if (num2->imm_flag) {
+          if (num2->num.abs_cnts.abs_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_ADD_U32;
+          }
+        } else {
+          if (num2->num.abs_cnts.c_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_SUB_U32;
+          }
+        }
+        AOTStoreCodeU32(cc,num2->num.i);
+      } else if (num2->U8_cnt==8) {
+        if (num2->num.local_asm_undef_hash||num2->num.glbl_asm_undef_hash)
+          AsmUnresolvedAdd(cc,num2->num.machine_code,IET_REL_I64+num2->imm_flag,
+                aotc->rip,num2->rel,num2->num.local_asm_undef_hash,
+                num2->num.glbl_asm_undef_hash,cc->lex_include_stk->line_num,
+                U8_avail);
+        if (num2->imm_flag) {
+          if (num2->num.abs_cnts.abs_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_ADD_U64;
+          }
+        } else {
+          if (num2->num.abs_cnts.c_addres&1) {
+            tmpa=CAlloc(sizeof(CAOTAbsAddr));
+            tmpa->next=aotc->abss;
+            aotc->abss=tmpa;
+            tmpa->rip=aotc->rip;
+            tmpa->type=AAT_SUB_U64;
+          }
+        }
+        AOTStoreCodeU64(cc,num2->num.i);
+      }
+      if (U8_avail && !num2->num.local_asm_undef_hash &&
+            !num2->num.glbl_asm_undef_hash &&
+            !num2->imm_flag && -124<=num2->num.i<=123) {
+        LexWarn(cc,"could use I8 displacement at ");
+        return FALSE;
+      }
+    }
+  }
+  return TRUE;
+}
+
+U8 asm_seg_prefixes[6]={0x26,0x2E,0x36,0x3E,0x64,0x65};
+
+Bool PrsAsmInst(CCmpCtrl *cc,CHashOpcode *tmpo,I64 argcnt)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i,j,arg1,arg2,om,seg,arg1mask,arg2mask;
+  CAsmArg *tmpa1,*tmpa2;
+  Bool ModrM_complete,U8_avail=FALSE,found_second_possible=FALSE;
+  CInst *tmpins;
+  CAsmIns cur,best;
+
+  best.U8_cnt=255;
+  if (argcnt>0)
+    arg1mask=AsmMakeArgMask(cc,&aotc->arg1);
+  else
+    arg1mask=1;
+  if (argcnt>1)
+    arg2mask=AsmMakeArgMask(cc,&aotc->arg2);
+  else
+    arg2mask=1;
+  for (i=0;i<tmpo->inst_entry_cnt;i++) {
+    tmpins=&tmpo->ins[i];
+    if (tmpins->arg1==ARGT_REL8 || tmpins->arg2==ARGT_REL8)
+      U8_avail=TRUE;
+    if (Bt(&arg1mask,tmpins->arg1) && Bt(&arg2mask,tmpins->arg2) &&
+          (!(tmpins->flags&IEF_NOT_IN_64_BIT) || aotc->seg_size!=64)) {
+      MemSet(&cur,0,sizeof(CAsmIns));
+      cur.tmpins=tmpins;
+      ModrM_complete=FALSE;
+      cur.is_dft=ToBool(tmpins->flags & IEF_DFT);
+      if (aotc->seg_size==64) {
+        if (tmpins->flags & IEF_48_REX)
+          cur.REX=0x48;
+        else
+          cur.REX=0x40;
+      }
+      cur.disp.imm_flag=TRUE;
+      cur.imm.imm_flag=TRUE;
+      om=tmpins->opcode_modifier;
+      arg1=tmpins->arg1;
+      arg2=tmpins->arg2;
+      tmpa1=&aotc->arg1;
+      tmpa2=&aotc->arg2;
+      cur.last_opcode_U8=tmpins->opcode[tmpins->opcode_cnt-1];
+
+      if (tmpins->slash_val<8) {
+        cur.ModrM|=tmpins->slash_val<<3;
+        cur.has_ModrM=TRUE;
+      }
+
+      if (aotc->seg_size==16 && tmpins->flags & IEF_OP_SIZE32 ||
+            aotc->seg_size!=16 && tmpins->flags & IEF_OP_SIZE16)
+        cur.has_operand_prefix=TRUE;
+
+      if (om==OM_IB)      cur.imm.U8_cnt=1;
+      else if (om==OM_IW) cur.imm.U8_cnt=2;
+      else if (om==OM_ID) cur.imm.U8_cnt=4;
+
+      if (om==OM_CB) {
+        cur.imm.U8_cnt=1;
+        cur.imm.imm_flag=FALSE;
+      } else if (om==OM_CW) {
+        cur.imm.U8_cnt=2;
+        cur.imm.imm_flag=FALSE;
+      } else if (om==OM_CD) {
+        cur.imm.U8_cnt=4;
+        cur.imm.imm_flag=FALSE;
+      }
+
+      if (argcnt==1) {
+        if (best.U8_cnt!=255 && !found_second_possible && !best.is_dft) {
+          found_second_possible=TRUE;
+          if (!aotc->arg1.size)
+            PrintWarn("no size specified at %s,%04d\n",
+                  cc->lex_include_stk->full_name,
+                  cc->lex_include_stk->line_num-1);
+        }
+        if (tmpins->flags & IEF_PLUS_OPCODE) {
+          if (tmpins->slash_val==SV_R_REG) {
+            cur.last_opcode_U8|=tmpa1->reg1&7;
+            if (tmpa1->reg1&15>7)
+              cur.REX|=1;
+            if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+              cur.has_REX=TRUE;
+          } else {//SV_I_REG
+            if (tmpa1->reg1_type==REGT_FSTK)
+              cur.last_opcode_U8+=tmpa1->reg1;
+          }
+        }
+        if (arg1==ARGT_R64 || arg1==ARGT_RM64 || arg1==ARGT_M64)
+          cur.REX|=8;
+        if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_M8<=arg1<=ARGT_M64) {
+          if (aotc->seg_size==16)
+            cur.has_addr_prefix=TRUE;
+
+          cur.has_ModrM=TRUE;
+          if (tmpa1->imm_or_off_present && tmpa1->indirect &&
+                tmpa1->reg1==REG_NONE) {
+            cur.ModrM=cur.ModrM+5;
+            MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+            cur.disp.U8_cnt=4;
+            if (aotc->seg_size==64)
+              cur.disp.imm_flag=FALSE;
+          } else {
+            if (tmpa1->reg2==REG_NONE && tmpa1->scale==1) {
+              cur.ModrM|=tmpa1->reg1&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            } else {
+              cur.ModrM|=4;
+              cur.has_SIB=TRUE;
+              if (tmpa1->scale==1)
+                cur.SIB=0;
+              else if (tmpa1->scale==2)
+                cur.SIB=0x40;
+              else if (tmpa1->scale==4)
+                cur.SIB=0x80;
+              else if (tmpa1->scale==8)
+                cur.SIB=0xC0;
+              if (tmpa1->reg2==REG_NONE) {
+                ModrM_complete=TRUE;
+                cur.SIB|=(tmpa1->reg1&7)<<3+REG_RBP;
+                if (tmpa1->reg1&15>7)
+                  cur.REX|=2;
+                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+                cur.disp.U8_cnt=4;
+              } else {
+                cur.SIB|=(tmpa1->reg1&7)<<3+tmpa1->reg2&7;
+                if (tmpa1->reg1&15>7)
+                  cur.REX|=2;
+                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+                if (tmpa1->reg2&15>7)
+                  cur.REX|=1;
+                if (tmpa1->reg2>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+                if (tmpa1->reg2&7==REG_RBP &&
+                      !tmpa1->imm_or_off_present && tmpa1->indirect) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                  ModrM_complete=TRUE;
+                }
+              }
+            }
+            if (!ModrM_complete) {
+              if (tmpa1->imm_or_off_present) {
+                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+                if (!cur.disp.num.machine_code &&
+                      I8_MIN<=cur.disp.num.i<=I8_MAX) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                } else if (aotc->seg_size==16) {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=2;
+                } else {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=4;
+                }
+              } else if (!tmpa1->indirect) {
+                cur.has_addr_prefix=FALSE;
+                cur.ModrM|=0xC0;
+              } else {
+                if (tmpa1->reg1&7==REG_RBP) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                }
+              }
+            }
+          }
+        } else if (ARGT_REL8<=arg1<=ARGT_REL32 || ARGT_IMM8<=arg1<=ARGT_IMM64 ||
+              ARGT_UIMM8<=arg1<=ARGT_UIMM64) {
+          if (arg1==ARGT_IMM64 || arg2==ARGT_UIMM64)
+            cur.REX|=8;
+          MemCpy(&cur.imm.num,&tmpa1->num,sizeof(CAsmNum));
+        }
+      } else if (argcnt==2) {
+        if (best.U8_cnt!=255 && !found_second_possible && !best.is_dft) {
+          found_second_possible=TRUE;
+          if (!aotc->arg1.size && !aotc->arg2.size)
+            PrintWarn("no size specified at %s,%04d\n",
+                  cc->lex_include_stk->full_name,
+                  cc->lex_include_stk->line_num-1);
+        }
+        if (tmpins->flags & IEF_PLUS_OPCODE) {
+          if (tmpins->slash_val==SV_R_REG) {
+            if (ARGT_AL<=arg1<=ARGT_RAX) {
+              cur.last_opcode_U8|=tmpa2->reg1&7;
+              if (tmpa2->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa2->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            } else {
+              cur.last_opcode_U8|=tmpa1->reg1&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            }
+          } else {//SV_I_REG
+            if (tmpa1->reg1_type==REGT_FSTK)
+              cur.last_opcode_U8|=tmpa1->reg1;
+            if (tmpa2->reg1_type==REGT_FSTK)
+              cur.last_opcode_U8|=tmpa2->reg1;
+          }
+        }
+        if (arg1==ARGT_RM64 || arg2==ARGT_RM64 ||
+              arg1==ARGT_M64 || arg2==ARGT_M64 ||
+              arg1==ARGT_R64 || arg2==ARGT_R64)
+          cur.REX|=8;
+        if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_RM8<=arg2<=ARGT_RM64 ||
+              ARGT_M8<=arg1<=ARGT_M64  || ARGT_M8<=arg2<=ARGT_M64) {
+          if (aotc->seg_size==16)
+            cur.has_addr_prefix=TRUE;
+          cur.has_ModrM=TRUE;
+          if (ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
+            tmpa1=&aotc->arg2;
+            tmpa2=&aotc->arg1;
+          }
+          if (tmpins->slash_val==SV_R_REG) {
+            if (tmpa2->just_seg)
+              cur.ModrM|=tmpa2->seg<<3;
+            else {
+              if (tmpa2->reg1==REG_NONE) {
+                cur.ModrM|=(tmpa1->reg1&7)<<3;
+                if (tmpa1->reg1&15>7)
+                  cur.REX|=4;
+                if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+              } else {
+                cur.ModrM|=(tmpa2->reg1&7)<<3;
+                if (tmpa2->reg1&15>7)
+                  cur.REX|=4;
+                if (tmpa2->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                  cur.has_REX=TRUE;
+              }
+            }
+          }
+          if (tmpa1->reg2==REG_NONE && tmpa1->scale==1) {
+            if (tmpa1->reg1!=REG_NONE) {
+              cur.ModrM|=tmpa1->reg1&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+            }
+          } else {
+            cur.ModrM|=4;
+            cur.has_SIB=TRUE;
+            if (tmpa1->scale==1)
+              cur.SIB=0;
+            else if (tmpa1->scale==2)
+              cur.SIB=0x40;
+            else if (tmpa1->scale==4)
+              cur.SIB=0x80;
+            else if (tmpa1->scale==8)
+              cur.SIB=0xC0;
+            if (tmpa1->reg2==REG_NONE) {
+              ModrM_complete=TRUE;
+              cur.SIB|=(tmpa1->reg1&7)<<3+5;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=2;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+              MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+              cur.disp.U8_cnt=4;
+            } else {
+              cur.SIB|=(tmpa1->reg1&7)<<3+tmpa1->reg2&7;
+              if (tmpa1->reg1&15>7)
+                cur.REX|=2;
+              if (tmpa1->reg1>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+              if (tmpa1->reg2&15>7)
+                cur.REX|=1;
+              if (tmpa1->reg2>=20) //RBPu8,RSPu8,RSIu8,RDIu8?
+                cur.has_REX=TRUE;
+              if (tmpa1->reg2&7==REG_RBP &&
+                    !tmpa1->imm_or_off_present && tmpa1->indirect) {
+                cur.ModrM|=0x40;
+                cur.disp.U8_cnt=1;
+                ModrM_complete=TRUE;
+              }
+            }
+          }
+          if (!ModrM_complete) {
+            if (tmpa1->imm_or_off_present &&
+                  tmpa1->indirect && tmpa1->reg1==REG_NONE) {
+              cur.ModrM=cur.ModrM&0xF8+5;
+              MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+              cur.disp.U8_cnt=4;
+              if (aotc->seg_size==64)
+                cur.disp.imm_flag=FALSE;
+            } else {
+              if (tmpa1->imm_or_off_present) {
+                MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+                if (!cur.disp.num.machine_code &&
+                      I8_MIN<=cur.disp.num.i<=I8_MAX) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                } else if (aotc->seg_size==16) {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=2;
+                } else {
+                  cur.ModrM|=0x80;
+                  cur.disp.U8_cnt=4;
+                }
+              } else if (!tmpa1->indirect) {
+                cur.has_addr_prefix=FALSE;
+                cur.ModrM|=0xC0;
+              } else {
+                if (tmpa1->reg1&7==REG_RBP) {
+                  cur.ModrM|=0x40;
+                  cur.disp.U8_cnt=1;
+                }
+              }
+            }
+          }
+        } else if (ARGT_MOFFS8<=arg1<=ARGT_MOFFS64) {
+          MemCpy(&cur.disp.num,&tmpa1->num,sizeof(CAsmNum));
+          if (aotc->seg_size==16)
+            cur.disp.U8_cnt=2;
+          else
+            cur.disp.U8_cnt=4;
+          cur.has_addr_prefix=FALSE;
+        } else if (ARGT_MOFFS8<=arg2<=ARGT_MOFFS64) {
+          MemCpy(&cur.disp.num,&tmpa2->num,sizeof(CAsmNum));
+          if (aotc->seg_size==16)
+            cur.disp.U8_cnt=2;
+          else
+            cur.disp.U8_cnt=4;
+          cur.has_addr_prefix=FALSE;
+        } else if (ARGT_IMM8<=arg1<=ARGT_IMM64 ||
+              ARGT_UIMM8<=arg1<=ARGT_UIMM64) {
+          MemCpy(&cur.imm.num,&tmpa1->num,sizeof(CAsmNum));
+          if (arg1==ARGT_IMM8 || arg1==ARGT_UIMM8) cur.imm.U8_cnt=1;
+          else if (arg1==ARGT_IMM16 || arg1==ARGT_UIMM16) cur.imm.U8_cnt=2;
+          else if (arg1==ARGT_IMM32 || arg1==ARGT_UIMM32) cur.imm.U8_cnt=4;
+          else {
+            cur.imm.U8_cnt=8;
+            cur.REX|=8;
+          }
+        }
+        if (ARGT_IMM8<=arg2<=ARGT_IMM64 ||
+              ARGT_UIMM8<=arg2<=ARGT_UIMM64) {
+          MemCpy(&cur.imm.num,&tmpa2->num,sizeof(CAsmNum));
+          if (arg2==ARGT_IMM8 || arg2==ARGT_UIMM8) cur.imm.U8_cnt=1;
+          else if (arg2==ARGT_IMM16 || arg2==ARGT_UIMM16) cur.imm.U8_cnt=2;
+          else if (arg2==ARGT_IMM32 || arg2==ARGT_UIMM32) {
+            cur.imm.U8_cnt=4;
+            if (tmpins->flags&IEF_REX_ONLY_R8_R15 && arg2==ARGT_UIMM32)
+              cur.REX&=~8;
+          } else {
+            cur.imm.U8_cnt=8;
+            cur.REX|=8;
+          }
+        }
+      }
+      cur.U8_cnt=tmpins->opcode_cnt+cur.disp.U8_cnt+cur.imm.U8_cnt;
+      if (cur.has_ModrM) cur.U8_cnt++;
+      if (cur.has_SIB) cur.U8_cnt++;
+      if (aotc->seg_size==64 && cur.REX&0x40==0x40 &&
+            (cur.REX!=0x40 || cur.has_REX) &&
+            (cur.REX&7 || !(tmpins->flags&IEF_REX_ONLY_R8_R15 ||
+            tmpins->flags&IEF_REX_XOR_LIKE && tmpa1->reg1==tmpa2->reg1 &&
+            cur.ModrM&0xC0==0xC0)))
+        cur.U8_cnt++;
+      if (cur.U8_cnt<best.U8_cnt &&
+            !(tmpins->flags & IEF_DONT_SWITCH_MODES &&
+            (cur.has_addr_prefix || cur.has_operand_prefix)))
+        MemCpy(&best,&cur,sizeof(CAsmIns));
+    }
+  }
+  if (best.U8_cnt<255) {
+    tmpins=best.tmpins;
+    seg=REG_NONE;
+    if (argcnt>1 && aotc->arg2.seg!=REG_NONE && !aotc->arg2.just_seg)
+      seg=aotc->arg2.seg;
+    else if (argcnt>0 && aotc->arg1.seg!=REG_NONE && !aotc->arg1.just_seg)
+      seg=aotc->arg1.seg;
+    if (seg!=REG_NONE)
+      AOTStoreCodeU8(cc,asm_seg_prefixes[seg]);
+    if (best.has_operand_prefix)
+      AOTStoreCodeU8(cc,OC_OP_SIZE_PREFIX); //Operand size override
+    if (best.has_addr_prefix  || aotc->seg_size==16 && cur.has_SIB)
+      AOTStoreCodeU8(cc,OC_ADDR_SIZE_PREFIX); //Operand size override
+    if (aotc->seg_size==64 && best.REX&0x40==0x40 &&
+          (best.REX!=0x40 || best.has_REX) &&
+          (best.REX&7||!(tmpins->flags&IEF_REX_ONLY_R8_R15 ||
+          tmpins->flags&IEF_REX_XOR_LIKE && tmpa1->reg1==tmpa2->reg1 &&
+          best.ModrM&0xC0==0xC0)))
+      AOTStoreCodeU8(cc,best.REX);
+    for (j=0;j<tmpins->opcode_cnt-1;j++)
+      AOTStoreCodeU8(cc,tmpins->opcode[j]);
+    AOTStoreCodeU8(cc,best.last_opcode_U8);
+
+    if (best.has_ModrM)
+      AOTStoreCodeU8(cc,best.ModrM);
+    if (best.has_SIB)
+      AOTStoreCodeU8(cc,best.SIB);
+
+    if (best.disp.U8_cnt) {
+      best.disp.rel=aotc->rip+best.disp.U8_cnt+best.imm.U8_cnt;
+      if (!AsmStoreNum(cc,&best.disp,1,U8_avail))
+        return FALSE;
+    }
+
+    if (best.imm.U8_cnt) {
+      best.imm.rel=aotc->rip+best.imm.U8_cnt;
+      if (!AsmStoreNum(cc,&best.imm,1,U8_avail))
+        return FALSE;
+    }
+    if (tmpins->flags&IEF_ENDING_ZERO) //ENTER inst
+      AOTStoreCodeU8(cc,0);
+    return TRUE;
+  }
+  LexExcept(cc,"Invalid inst at ");
+}
+
+U0 PrsAsmDefine(CCmpCtrl *cc,I64 U8_cnt)
+{
+  Bool is_dup;
+  I64 i,dup_val;
+  U8 *ptr;
+  CAsmNum2 num2;
+  num2.U8_cnt=U8_cnt;
+
+  while (cc->token && cc->token!=';') {
+    num2.num.local_asm_undef_hash=NULL;
+    num2.num.glbl_asm_undef_hash=NULL;
+    if (cc->token==TK_STR) {
+      ptr=cc->cur_str;
+      i=cc->cur_str_len-1;
+      while (i--)
+        AOTStoreCodeU8(cc,*ptr++);
+      Lex(cc);  //Skip Str
+    } else {
+      is_dup=FALSE;
+      cc->abs_cnts=0;
+      cc->asm_undef_hash=NULL;
+      cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);
+      if (!IsLexExpression2Bin(cc,&num2.num.machine_code))
+        LexSkipEol(cc);
+      else {
+        if (cc->abs_cnts.externs)
+          LexExcept(cc,"Extern Not Allowed at ");
+        if (cc->flags & CCF_UNRESOLVED) {
+          if (cc->flags & CCF_LOCAL) {
+            num2.num.local_asm_undef_hash=cc->asm_undef_hash;
+            cc->asm_undef_hash=NULL;
+          } else {
+            num2.num.glbl_asm_undef_hash=cc->asm_undef_hash;
+            cc->asm_undef_hash=NULL;
+          }
+        } else {
+          i=Call(num2.num.machine_code);
+          Free(num2.num.machine_code);
+        }
+      }
+      if (cc->token==TK_IDENT && cc->hash_entry) {
+        if (cc->hash_entry->type & HTT_ASM_KEYWORD &&
+              cc->hash_entry->user_data0==AKW_DUP) {
+          is_dup=TRUE;
+          if (Lex(cc)!='(')
+            LexExcept(cc,"Expecting '(' at ");
+          Lex(cc); //skip (
+          dup_val=AsmLexExpression(cc);
+          if (cc->token!=')')
+            LexExcept(cc,"Expecting ')' at ");
+          Lex(cc); //SKIP )
+        }
+      }
+      num2.rel=0;
+      num2.imm_flag=TRUE;
+      num2.num.abs_cnts=cc->abs_cnts;
+      if (is_dup) {
+        if (num2.num.local_asm_undef_hash || num2.num.glbl_asm_undef_hash)
+          LexExcept(cc,"Undefined DUP cnt at ");
+        num2.num.i=dup_val;
+        AsmStoreNum(cc,&num2,i,FALSE);
+      } else {
+        num2.num.i=i;
+        AsmStoreNum(cc,&num2,1,FALSE);
+      }
+    }
+    if (cc->token==',')
+      Lex(cc);
+  }
+  if (cc->token!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+}
+
+U0 PrsBinFile(CCmpCtrl *cc)
+{
+  I64 i,size;
+  U8 *buf,*st;
+  if (cc->token!=TK_STR)
+    LexExcept(cc,"Expecting string at ");
+  st=ExtDft(cc->cur_str,"BIN");
+  buf=FileRead(st,&size);
+  Free(st);
+  for (i=0;i<size;i++)
+    AOTStoreCodeU8(cc,buf[i]);
+  if (Lex(cc)!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+}
+
+U0 PrsAsmBlk(CCmpCtrl *cc,I64 cmp_flags)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i,j,k,argcnt,
+        old_flags=cc->flags & CCF_ASM_EXPRESSIONS;
+  CHashOpcode *tmpo;
+  CHashExport *tmpex;
+  U8 *next_last_label;
+  CCodeMisc *g_lb;
+
+  aotc->seg_size=64;
+  cc->flags|=CCF_ASM_EXPRESSIONS;
+  if (!(cmp_flags&CMPF_ONE_ASM_INS)) {
+    if (cc->token!='{')
+      LexExcept(cc,"Expecting '{' at ");
+    Lex(cc);
+  }
+  while (cc->token && cc->token!='}') {
+    AsmLineLst(cc);
+    if (cc->token==TK_IDENT && cc->hash_entry) {
+      if (cc->hash_entry->type&HTT_ASM_KEYWORD) {
+        i=cc->hash_entry->user_data0;
+        Lex(cc); //skip keyword
+        switch (i) {
+          case AKW_IMPORT:
+            while (cc->token && cc->token!=';') {
+              if (cc->token!=TK_IDENT)
+                LexExcept(cc,"Expecting identifier at ");
+              else {
+                tmpex=NULL;
+                tmpex=CAlloc(sizeof(CHashExport));
+                tmpex->str=cc->cur_str;
+                cc->cur_str=0;
+                tmpex->type=HTT_EXPORT_SYS_SYM|HTF_UNRESOLVED;
+                HashAdd(tmpex,cc->htc.glbl_hash_table);
+                tmpex->type|=HTF_IMPORT;
+                if (Lex(cc)==',')
+                  Lex(cc); //skip ','
+              }
+            }
+            if (cc->token!=';')
+              LexExcept(cc,"Missing ';' at");
+            Lex(cc); //skip ';';
+            break;
+          case AKW_ORG:
+            if (cc->htc.local_var_lst)
+              LexExcept(cc,"ORG not allowed in fun asm blk ");
+            if (aotc->org!=INVALID_PTR)
+              LexExcept(cc,"Just one org allowed ");
+            if (aotc->rip)
+              LexExcept(cc,"ORG must be at beginning ");
+            aotc->org=AsmLexExpression(cc);
+            break;
+          case AKW_ALIGN:
+            if (cc->htc.local_var_lst)
+              LexExcept(cc,"ALIGN not allowed in fun asm blk ");
+            i=AsmLexExpression(cc);
+            j=Bsf(i);
+            if (!i || j!=Bsr(i))
+              LexExcept(cc,"ALIGN must be power of two at ");
+            if (!(cc->flags&CCF_AOT_COMPILE) && i>8)
+              LexExcept(cc,"In JIT mode, max ALIGN is 8 ");
+            if (j>aotc->max_align_bits) aotc->max_align_bits=j;
+            i=CeilU64(aotc->rip,i);
+            if (cc->token!=',')
+              LexExcept(cc,"Expecting ',' at ");
+            Lex(cc);
+            k=AsmLexExpression(cc);
+            for (j=aotc->rip;j<i;j++)
+              AOTStoreCodeU8(cc,k);
+            break;
+          case AKW_DU8:
+            PrsAsmDefine(cc,1);
+            break;
+          case AKW_DU16:
+            PrsAsmDefine(cc,2);
+            break;
+          case AKW_DU32:
+            PrsAsmDefine(cc,4);
+            break;
+          case AKW_DU64:
+            PrsAsmDefine(cc,8);
+            break;
+          case AKW_BINFILE:
+            PrsBinFile(cc);
+            break;
+          case AKW_LIST:
+            aotc->lst=TRUE;
+            break;
+          case AKW_NOLIST:
+            aotc->lst=FALSE;
+            break;
+          case AKW_USE16:
+            aotc->seg_size=16;
+            break;
+          case AKW_USE32:
+            aotc->seg_size=32;
+            break;
+          case AKW_USE64:
+            aotc->seg_size=64;
+            break;
+          default:
+            LexExcept(cc,"Syntax error at ");
+        }
+      } else if (cc->hash_entry->type & HTT_OPCODE) {
+        tmpo=cc->hash_entry;
+        Lex(cc); //skip opcode
+        argcnt=0;
+        if (tmpo->ins[0].arg1) {
+          argcnt++;
+          if (ARGT_REL8<=tmpo->ins[0].arg1<=ARGT_REL32)
+            PrsAsmArg(cc,&aotc->arg1,TRUE);
+          else
+            PrsAsmArg(cc,&aotc->arg1,FALSE);
+          if (tmpo->ins[0].arg2) {
+            argcnt++;
+            if (cc->token!=',')
+              LexExcept(cc,"Expecting ',' at ");
+            else {
+              Lex(cc); //skip ','
+              if (ARGT_REL8<=tmpo->ins[0].arg2<=ARGT_REL32)
+                PrsAsmArg(cc,&aotc->arg2,TRUE);
+              else
+                PrsAsmArg(cc,&aotc->arg2,FALSE);
+            }
+          }
+        }
+        PrsAsmInst(cc,tmpo,argcnt);
+      } else if (cc->hash_entry->type & HTT_EXPORT_SYS_SYM) {
+        if (Btr(&cc->hash_entry->type,HTf_UNRESOLVED)) {
+          if (cc->hash_entry->type & HTF_LOCAL) {
+            cc->hash_entry(CHashExport *)->val=aotc->rip;
+            if (Lex(cc)!=':')
+              LexExcept(cc,"Expecting ':' at ");
+            Lex(cc);
+          } else {
+            if (cc->hash_entry->type & HTF_IMPORT)
+              LexExcept(cc,"attempt to define import at ");
+            cc->hash_entry(CHashExport *)->val=aotc->rip;
+            next_last_label=cc->hash_entry->str;
+            Lex(cc); //Skip cur_str
+            if (cc->token!=':' && cc->token!=TK_DBL_COLON)
+              LexExcept(cc,"Expecting ':' at ");
+            if (cc->token==TK_DBL_COLON) {
+              cc->hash_entry->type|=HTF_EXPORT;
+              HashSrcFileSet(cc,cc->hash_entry);
+
+              AOTLocalsResolve(cc);
+              aotc->last_label=next_last_label;
+            }
+            Lex(cc);
+          }
+        } else if (cc->hash_entry(CHashExport *)->val==aotc->rip) {
+          Lex(cc); //Skip cur_str
+          if (cc->token!=':' && cc->token!=TK_DBL_COLON)
+            LexExcept(cc,"Expecting ':' at ");
+          Lex(cc);
+        } else
+          LexExcept(cc,"Redefinition at ");
+      } else
+        LexExcept(cc,"Syntax error at ");
+    } else if (cc->token==TK_IDENT) {
+      tmpex=CAlloc(sizeof(CHashExport));
+      tmpex->str=cc->cur_str;
+      cc->cur_str=0;
+      tmpex->type=HTT_EXPORT_SYS_SYM;
+      tmpex->val=aotc->rip;
+      Lex(cc);  //Skip cur_str
+      if (cc->token!=':' && cc->token!=TK_DBL_COLON)
+        LexExcept(cc,"Expecting ':' at ");
+      else {
+        if (*tmpex->str=='@' && tmpex->str[1]=='@') {
+          if (cc->token==TK_DBL_COLON)
+            LexExcept(cc,"No local glbl exports at ");
+          HashAdd(tmpex,cc->htc.local_hash_table);
+        } else
+          HashAdd(tmpex,cc->htc.glbl_hash_table);
+        if (cc->htc.local_var_lst) {//AsmBlk in fun? Also add goto-like label.
+          if (!(g_lb=COCGoToLabelFind(cc,tmpex->str))) {
+            g_lb=COCMiscNew(cc,CMT_ASM_LABEL);
+            g_lb->str=StrNew(tmpex->str);
+          } else if (g_lb->flags&CMF_DEFINED)
+            LexExcept(cc,"Duplicate goto label at ");
+          g_lb->type=CMT_ASM_LABEL;
+          g_lb->flags|=CMF_DEFINED;
+          g_lb->rip=aotc->rip;
+          g_lb->use_cnt++; //Disable warning on unused labels.
+          ICAdd(cc,IC_LABEL,g_lb,0);
+        }
+        if (cc->token==TK_DBL_COLON) {
+          tmpex->type|=HTF_EXPORT;
+          HashSrcFileSet(cc,tmpex);
+
+          AOTLocalsResolve(cc);
+          aotc->last_label=tmpex->str;
+        }
+        Lex(cc);
+      }
+    } else if (cc->token==';')
+      Lex(cc);
+    else
+      LexExcept(cc,"Syntax error at ");
+    if (cmp_flags&CMPF_ONE_ASM_INS && (cc->token!=TK_IDENT ||
+          !(tmpo=cc->hash_entry) ||
+          !(tmpo->type&(HTT_OPCODE|HTT_ASM_KEYWORD))))
+      break;
+  }
+  AOTLocalsResolve(cc);
+  aotc->lst=FALSE;
+  cc->flags&=cc->flags&~CCF_ASM_EXPRESSIONS|old_flags;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/AsmInit.HC.HTML b/public/Wb/Home/Src/Compiler/AsmInit.HC.HTML new file mode 100755 index 0000000..a822b58 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/AsmInit.HC.HTML @@ -0,0 +1,240 @@ + + + + + + + + + + + +
+U0 AsmPrsInsFlags(CCmpCtrl *cc,CInst *tmpins)
+{
+  I64 i;
+  while (TRUE) {
+    switch (cc->token) {
+      case TK_IDENT:
+        if ((i=LstMatch(cc->cur_str,"NO\0CB\0CW\0CD\0CP\0IB\0IW\0ID\0"))>=0) {
+          tmpins->opcode_modifier=i;
+          break;
+        } else
+          return;
+      case TK_I64:
+        if (cc->cur_i64==16)
+          tmpins->flags|=IEF_OP_SIZE16;
+        else if (cc->cur_i64==32)
+          tmpins->flags|=IEF_OP_SIZE32;
+        else
+          return;
+        break;
+      case '+':
+        tmpins->flags|=IEF_PLUS_OPCODE;
+      case '/':
+        if (Lex(cc)==TK_I64 && cc->cur_i64<8)
+          tmpins->slash_val=cc->cur_i64;
+        else if (cc->token==TK_IDENT) {
+          if (!StrCmp(cc->cur_str,"R"))
+            tmpins->slash_val=SV_R_REG;
+          else if (!StrCmp(cc->cur_str,"I"))
+            tmpins->slash_val=SV_I_REG;
+          else
+            return;
+        } else
+          return;
+        break;
+      case '!': tmpins->flags|=IEF_DONT_SWITCH_MODES;   break;
+      case '&': tmpins->flags|=IEF_DFT;                 break;
+      case '%': tmpins->flags|=IEF_NOT_IN_64_BIT;       break;
+      case '=': tmpins->flags|=IEF_48_REX;              break;
+      case '`': tmpins->flags|=IEF_REX_ONLY_R8_R15;     break;
+      case '^': tmpins->flags|=IEF_REX_XOR_LIKE;                break;
+      case '*': tmpins->flags|=IEF_STI_LIKE;            break;
+      case '$': tmpins->flags|=IEF_ENDING_ZERO;         break;
+      default:
+        return;
+    }
+    Lex(cc);
+  }
+}
+
+U0 AsmHashLoad()
+{//See ::/Compiler/OpCodes.DD.
+  I64 i,j,size,size_max;
+  CInternalType *tmpit;
+  CCmpCtrl *cc;
+  CHashGeneric *tmph;
+  CHashReg *tmpr;
+  CHashOpcode *tmpo,*tmpo2,*tmpo_max;
+  CInst *tmpins;
+  CHashClass *tmpc;
+
+  cmp.size_arg_mask[0]=0x3FF0FFFFFE;
+  cmp.size_arg_mask[1]=0x1110111112;
+  cmp.size_arg_mask[2]=0x2220222224;
+  cmp.size_arg_mask[4]=0x0440444448;
+  cmp.size_arg_mask[8]=0x0880888880;
+
+  cmp.asm_hash=HashTableNew(1024);
+  size_max=offset(CHashOpcode.ins)+sizeof(CInst)<<5;
+  tmpo_max=MAlloc(size_max);
+
+  cc=CmpCtrlNew(FileRead("OpCodes.DD"),,"OpCodes.DD.Z");
+  cc->htc.hash_table_lst=NULL;
+  Lex(cc);
+  while (cc->token) {
+    if (cc->token!=TK_IDENT)
+      LexExcept(cc,"Expecting identifier at ");
+    i=LstMatch(cc->cur_str,"NONE\0R8\0R16\0R32\0R64\0SEG\0FSTK\0"
+          "MM\0XMM\0OPCODE\0KEYWORD\0ASM_KEYWORD\0");
+    if (i<=0)
+      LexExcept(cc,"Unknown Stmt");
+    Lex(cc); //skip keyword
+    if (cc->token!=TK_IDENT)
+      LexExcept(cc,"Expecting identifier at ");
+    switch (i) {
+      case REGT_R8...REGT_XMM:
+        tmpr=CAlloc(sizeof(CHashReg));
+        tmpr->str=cc->cur_str;
+        cc->cur_str=NULL;
+        Lex(cc); //skip keyword name
+        if (cc->token!=TK_I64)
+          LexExcept(cc,"Expecting int at ");
+        tmpr->type=HTT_REG;
+        tmpr->reg_type=i;
+        tmpr->reg_num=cc->cur_i64;
+        HashAdd(tmpr,cmp.asm_hash);
+        Lex(cc); //Skip INT
+        break;
+      case: //OPCODE
+        if (cc->token!=TK_IDENT)
+          LexExcept(cc,"Expecting opcode at ");
+        MemSet(tmpo_max,0,size_max);
+        tmpo_max->type=HTT_OPCODE;
+        tmpo_max->inst_entry_cnt=0;
+        tmpo_max->str=cc->cur_str;
+        cc->cur_str=0;
+        Lex(cc);        //Skip OPCODE
+        while (cc->token && cc->token!=';' && cc->token!=':') {
+          tmpins=&tmpo_max->ins[tmpo_max->inst_entry_cnt];
+          tmpins->ins_entry_num=tmpo_max->inst_entry_cnt++;
+          tmpins->slash_val=SV_NONE; //Not zero!!
+          while (cc->token==TK_I64) {
+            tmpins->opcode[tmpins->opcode_cnt++]=cc->cur_i64;
+            Lex(cc);
+          }
+          if (cc->token==',')
+            Lex(cc);
+          else if (cc->token!=';')
+            LexExcept(cc,"Expecting ',' at ");
+
+          AsmPrsInsFlags(cc,tmpins);
+
+          tmpins->uasm_slash_val=tmpins->slash_val;
+          if (tmpins->flags&IEF_STI_LIKE && tmpins->slash_val!=SV_I_REG)
+            tmpins->uasm_slash_val=SV_STI_LIKE;
+
+          tmpins->arg1=tmpins->arg2=tmpins->size1=tmpins->size2=0;
+          if (cc->token==TK_IDENT) {
+            j=DefineMatch(cc->cur_str,"ST_ARG_TYPES");
+            tmpins->arg1=j;
+            if (Bt(&cmp.size_arg_mask[1],j))
+              tmpins->size1=8;
+            else if (Bt(&cmp.size_arg_mask[2],j))
+              tmpins->size1=16;
+            else if (Bt(&cmp.size_arg_mask[4],j))
+              tmpins->size1=32;
+            else if (Bt(&cmp.size_arg_mask[8],j))
+              tmpins->size1=64;
+
+            if (Lex(cc)==TK_IDENT) {
+              j=DefineMatch(cc->cur_str,"ST_ARG_TYPES");
+              Lex(cc);
+              tmpins->arg2=j;
+              if (Bt(&cmp.size_arg_mask[1],j))
+                tmpins->size2=8;
+              else if (Bt(&cmp.size_arg_mask[2],j))
+                tmpins->size2=16;
+              else if (Bt(&cmp.size_arg_mask[4],j))
+                tmpins->size2=32;
+              else if (Bt(&cmp.size_arg_mask[8],j))
+                tmpins->size2=64;
+            }
+          }
+        }
+        size=offset(CHashOpcode.ins)+sizeof(CInst)*tmpo_max->inst_entry_cnt;
+        tmpo=MAlloc(size);
+        MemCpy(tmpo,tmpo_max,size);
+        tmpo->use_cnt=0;
+        if (HashFind(tmpo->str,cmp.asm_hash,HTT_OPCODE))
+          LexExcept(cc,"Duplicate OPCODE entry ");
+        HashAdd(tmpo,cmp.asm_hash);
+        //Parse aliases.
+        if (cc->token==':') {
+          while (Lex(cc)==TK_IDENT) {
+            tmpo2=MAllocIdent(tmpo);
+            tmpo2->str=cc->cur_str;
+            cc->cur_str=0;
+            tmpo2->oc_flags|=OCF_ALIAS;
+            if (HashFind(tmpo2->str,cmp.asm_hash,HTT_OPCODE))
+              LexExcept(cc,"Duplicate OPCODE ALIAS entry ");
+            HashAdd(tmpo2,cmp.asm_hash);
+          }
+        }
+        break;
+      case: //KEYWORD
+      case: //ASM_KEYWORD
+        tmph=CAlloc(sizeof(CHashGeneric));
+        tmph->str=cc->cur_str;
+        cc->cur_str=NULL;
+        Lex(cc); //skip keyword name
+        if (cc->token!=TK_I64)
+          LexExcept(cc,"Expecting int at ");
+        tmph->user_data0=cc->cur_i64;
+        if (i==10)
+          tmph->type=HTT_KEYWORD;
+        else
+          tmph->type=HTT_ASM_KEYWORD;
+        HashAdd(tmph,cmp.asm_hash);
+        Lex(cc); //Skip INT
+        break;
+    }
+    if (cc->token!=';')
+      LexExcept(cc,"Missing ';' at");
+    Lex(cc); //Skip ';'
+  }
+  Free(tmpo_max);
+  CmpCtrlDel(cc);
+  for (i=0;i<INTERNAL_TYPES_NUM;i++) {
+    tmpit=&internal_types_table[i];
+    tmpc=PrsClassNew;
+    tmpc->type=HTT_INTERNAL_TYPE;
+    tmpc->raw_type=tmpit->type;
+    Bts(&tmpc->flags,Cf_INTERNAL_TYPE);
+    tmpc->size=tmpit->size;
+    tmpc->str=AStrNew(tmpit->name);
+    HashAdd(tmpc,cmp.asm_hash);
+    cmp.internal_types[tmpc->raw_type]=tmpc;
+  }
+  adam_task->hash_table->next=cmp.asm_hash;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/AsmLib.HC.HTML b/public/Wb/Home/Src/Compiler/AsmLib.HC.HTML new file mode 100755 index 0000000..84dc385 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/AsmLib.HC.HTML @@ -0,0 +1,206 @@ + + + + + + + + + + + +
+U0 AOTStoreCodeU8(CCmpCtrl *cc,U8 b)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i=aotc->rip>>AOT_BIN_BLK_BITS;
+  CAOTBinBlk *tmpbin=aotc->bin;
+  while (i--)
+    if (!(tmpbin=tmpbin->next)) {
+      i=aotc->rip>>AOT_BIN_BLK_BITS+1;
+      tmpbin=&aotc->bin;
+      while (i--) {
+        if (!tmpbin->next)
+          tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+        tmpbin=tmpbin->next;
+      }
+      break;
+    }
+  tmpbin->body[aotc->rip++ & (AOT_BIN_BLK_SIZE-1)]=b;
+  if (aotc->lst) {
+    if (aotc->lst_col>=24) {
+      '\n';
+      aotc->lst_col=0;
+    }
+    "%02X ",b;
+    aotc->lst_col+=3;
+  }
+  if (aotc->rip>aotc->num_bin_U8s)
+    aotc->num_bin_U8s=aotc->rip;
+}
+
+U0 AOTStoreCodeU32(CCmpCtrl *cc,U32 d)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i=aotc->rip>>AOT_BIN_BLK_BITS,j=(aotc->rip+sizeof(U32))>>AOT_BIN_BLK_BITS;
+  U32 *_d;
+  CAOTBinBlk *tmpbin;
+  if (i!=j)
+    for (i=0;i<sizeof(U32);i++)
+      AOTStoreCodeU8(cc,d.u8[i]);
+  else {
+    tmpbin=aotc->bin;
+    while (i--)
+      if (!(tmpbin=tmpbin->next)) {
+        i=aotc->rip>>AOT_BIN_BLK_BITS+1;
+        tmpbin=&aotc->bin;
+        while (i--) {
+          if (!tmpbin->next)
+            tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+          tmpbin=tmpbin->next;
+        }
+        break;
+      }
+    _d=tmpbin->body+ aotc->rip&(AOT_BIN_BLK_SIZE-1);
+    *_d=d;
+    aotc->rip+=sizeof(U32);
+    if (aotc->lst) {
+      if (aotc->lst_col>=24) {
+        '\n';
+        aotc->lst_col=0;
+      }
+      "%08X ",d;
+      aotc->lst_col+=9;
+    }
+    if (aotc->rip>aotc->num_bin_U8s)
+      aotc->num_bin_U8s=aotc->rip;
+  }
+}
+
+U0 AOTStoreCodeU64(CCmpCtrl *cc,U64 q)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64   i=aotc->rip>>AOT_BIN_BLK_BITS,
+        j=(aotc->rip+sizeof(I64))>>AOT_BIN_BLK_BITS, *_q;
+  CAOTBinBlk *tmpbin;
+  if (i!=j)
+    for (i=0;i<sizeof(I64);i++)
+      AOTStoreCodeU8(cc,q.u8[i]);
+  else {
+    tmpbin=aotc->bin;
+    while (i--)
+      if (!(tmpbin=tmpbin->next)) {
+        i=aotc->rip>>AOT_BIN_BLK_BITS+1;
+        tmpbin=&aotc->bin;
+        while (i--) {
+          if (!tmpbin->next)
+            tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+          tmpbin=tmpbin->next;
+        }
+        break;
+      }
+    _q=tmpbin->body+ aotc->rip&(AOT_BIN_BLK_SIZE-1);
+    *_q=q;
+    aotc->rip+=sizeof(I64);
+    if (aotc->lst) {
+      if (aotc->lst_col>=24) {
+        '\n';
+        aotc->lst_col=0;
+      }
+      "%016X ",q;
+      aotc->lst_col+=17;
+    }
+    if (aotc->rip>aotc->num_bin_U8s)
+      aotc->num_bin_U8s=aotc->rip;
+  }
+}
+
+U0 AOTStoreCodeU8At(CCmpCtrl *cc,I64 rip,...)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CAOTBinBlk *tmpbin;
+  I64 i,j;
+  for (j=0;j<argc;j++) {
+    i=rip>>AOT_BIN_BLK_BITS+1;
+    tmpbin=&aotc->bin;
+    while (i--) {
+      if (!tmpbin->next) {
+        tmpbin->next=CAlloc(sizeof(CAOTBinBlk));
+        tmpbin->next->next=NULL;
+      }
+      tmpbin=tmpbin->next;
+    }
+    tmpbin->body[rip++ & (AOT_BIN_BLK_SIZE-1)]=argv[j];
+  }
+  if (rip>aotc->num_bin_U8s)
+    aotc->num_bin_U8s=rip;
+}
+
+I64 AsmLexExpression(CCmpCtrl *cc)
+{
+  U8 *machine_code;
+  I64 res=0;
+  cc->asm_undef_hash=NULL;
+  cc->flags&=~(CCF_UNRESOLVED+CCF_LOCAL);
+  cc->abs_cnts=0;
+  if (!IsLexExpression2Bin(cc,&machine_code))
+    LexSkipEol(cc);
+  else {
+    if (cc->abs_cnts.externs)
+      LexExcept(cc,"Extern Not Allowed at ");
+    if (cc->flags & CCF_UNRESOLVED)
+      LexExcept(cc,"Undefined sym at ");
+    res=Call(machine_code);
+    Free(machine_code);
+  }
+  return res;
+}
+
+U0 AsmLineLst(CCmpCtrl *cc)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CLexFile *tmpf=cc->lex_include_stk;
+  CDocEntry *doc_e=tmpf->line_start,*doc_e2;
+  if (aotc->lst && aotc->lst_last_lfn==tmpf && doc_e) {
+    if (doc_e2=aotc->lst_last_line) {
+      if (tmpf->flags& LFSF_DOC) {
+        while (doc_e2->y<doc_e->y) {
+          "%h*c%08X ",24-aotc->lst_col,CH_SPACE,aotc->lst_last_rip;
+          aotc->lst_col=0;
+          doc_e2=LexPutLine(cc,doc_e2);
+        }
+      } else {
+        while (*doc_e2(U8 *) && doc_e2!=doc_e) {
+          "%h*c%08X ",24-aotc->lst_col,CH_SPACE,aotc->lst_last_rip;
+          aotc->lst_col=0;
+          doc_e2=LexPutLine(cc,doc_e2);
+        }
+      }
+      aotc->lst_last_line=doc_e2;
+    } else
+      aotc->lst_last_line=doc_e;
+  } else {
+    aotc->lst_last_line=NULL;
+    aotc->lst_last_lfn=tmpf;
+  }
+  aotc->lst_last_rip=aotc->rip;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/AsmResolve.HC.HTML b/public/Wb/Home/Src/Compiler/AsmResolve.HC.HTML new file mode 100755 index 0000000..e5ca283 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/AsmResolve.HC.HTML @@ -0,0 +1,248 @@ + + + + + + + + + + + +
+U0 AsmResolve(CCmpCtrl *cc,CAsmUnresolvedRef *tmpu,U8 *label,Bool undefined)
+{
+  CAOTImportExport *tmpie;
+  CAsmUndefHash *tmpauh;
+  I64 res=Call(tmpu->machine_code);
+  if (undefined) {
+    tmpauh=tmpu->asm_undef_hash;
+    while (tmpauh) {
+      if (tmpauh->hash->type & HTF_UNRESOLVED) {
+        tmpie=CAlloc(sizeof(CAOTImportExport));
+        tmpie->next=tmpauh->hash->ie_lst;
+        tmpauh->hash->ie_lst=tmpie;
+        tmpie->rip=tmpu->rip;
+        tmpie->aot=cc->aot;
+        tmpie->type=tmpu->type;
+      }
+      tmpauh=tmpauh->next; //Technically, more than one won't work.
+    }
+  } else if (!(tmpu->type&IEF_IMM_NOT_REL)) {
+    res-=tmpu->rel_rip;
+    if (tmpu->type==IET_REL_I8 && !(I8_MIN<=res<=I8_MAX) ||
+          tmpu->type==IET_REL_I16 && !(I16_MIN<=res<=I16_MAX)) {
+      PrintErr("Branch out of range at line:%04d %s\n",
+            tmpu->line_num,label);
+      LexExcept(cc);
+    }
+    if (tmpu->U8_avail && tmpu->type>IET_IMM_U8 && -124<=res<=123)
+      PrintWarn("could use I8 displacement at line:%04d %s %s\n",
+            tmpu->line_num,cc->aotc->last_label,label);
+  }
+  AOTStoreCodeU8At(cc,tmpu->rip,res.u8[0]);
+  if (tmpu->type>=IET_REL_I16) {
+    AOTStoreCodeU8At(cc,tmpu->rip+1,res.u8[1]);
+    if (tmpu->type>=IET_REL_I32) {
+      AOTStoreCodeU8At(cc,tmpu->rip+2,res.u8[2],res.u8[3]);
+      if (tmpu->type>=IET_REL_I64)
+        AOTStoreCodeU8At(cc,tmpu->rip+4,res.u8[4],res.u8[5],
+              res.u8[6],res.u8[7]);
+    }
+  }
+}
+
+U0 AOTLocalsResolve(CCmpCtrl *cc)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CAsmUnresolvedRef *tmpu=aotc->local_unresolved,*tmpu1;
+  CAsmUndefHash *tmpauh;
+  Bool undefined;
+  U8 *label=NULL;
+
+  while (tmpu) {
+    undefined=FALSE;
+    tmpu1=tmpu->next;
+    tmpauh=tmpu->asm_undef_hash;
+    while (tmpauh) {
+      if (tmpauh->hash->type & HTF_UNRESOLVED) {
+        PrintErr("Undefined sym at line:%04d %s %s\n",
+              tmpu->line_num,aotc->last_label,tmpauh->hash->str);
+        LexExcept(cc);
+      }
+      label=tmpauh->hash->str;
+      tmpauh=tmpauh->next;
+    }
+    if (!undefined)
+      AsmResolve(cc,tmpu,label,FALSE);
+    Free(tmpu->machine_code);
+    LinkedLstDel(tmpu->asm_undef_hash);
+    Free(tmpu);
+    tmpu=tmpu1;
+  }
+  HashTableDel(cc->htc.local_hash_table);
+  cc->htc.hash_table_lst=cc->htc.local_hash_table=HashTableNew(16);
+  cc->htc.local_hash_table->next=cc->htc.glbl_hash_table;
+  aotc->local_unresolved=NULL;
+}
+
+U0 AOTGlblsResolve(CCmpCtrl *cc,CAOT *tmpaot)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  CHashFun *tmpf;
+  CAsmUnresolvedRef *tmpu=aotc->glbl_unresolved,*tmpu1;
+  I64 i,j;
+  CAOTImportExport *tmpie,*tmpie1;
+  CAsmUndefHash *tmpauh;
+  CHashExport *tmpex;
+  U8 *label;
+  Bool undefined;
+  CExternUsage *tmpeu,*tmpeu8;
+
+  while (tmpu) {
+    label=NULL;
+    undefined=FALSE;
+    tmpu1=tmpu->next;
+    tmpauh=tmpu->asm_undef_hash;
+    while (tmpauh) {
+      if (tmpauh->hash->type & HTF_UNRESOLVED) {
+        tmpex=tmpauh->hash;
+        if (tmpex->type & HTT_EXPORT_SYS_SYM&& tmpex->type & HTF_UNRESOLVED &&
+              !(tmpex->type & HTF_IMPORT) &&
+              (tmpf=HashFind(tmpex->str,cc->htc.hash_table_lst,HTT_FUN)) &&
+              !Bt(&tmpf->flags,Cf_EXTERN)) {
+          tmpex->val=tmpf->exe_addr;
+          tmpex->type&=~HTF_UNRESOLVED;
+          label=tmpauh->hash->str;
+        } else {
+          if (!(tmpex->type & HTF_IMPORT)) {
+            if (cc->htc.local_var_lst) {
+              tmpex->type|=HTF_GOTO_LABEL;
+              tmpex->use_cnt++;
+            } else {
+              PrintErr("Undefined sym at line:%04d %s\n",
+                    tmpu->line_num,tmpex->str);
+              LexExcept(cc);
+            }
+          } else if (undefined) {
+            PrintErr("Two imports in same expression "
+                  "not allowed at line:%04d %s\n",
+                  tmpu->line_num,tmpex->str);
+            LexExcept(cc);
+          }
+          undefined=TRUE;
+        }
+      } else
+        label=tmpauh->hash->str;
+      tmpauh=tmpauh->next;
+    }
+    AsmResolve(cc,tmpu,label,undefined);
+    Free(tmpu->machine_code);
+    LinkedLstDel(tmpu->asm_undef_hash);
+    Free(tmpu);
+    tmpu=tmpu1;
+  }
+
+  for (i=0;i<=cc->htc.glbl_hash_table->mask;i++) {
+    tmpex=cc->htc.glbl_hash_table->body[i];
+    while (tmpex) {
+      if (tmpex->type & (HTF_IMPORT|HTF_GOTO_LABEL)) {
+        if (tmpex->use_cnt && (tmpie=tmpex->ie_lst)) {
+          if (tmpex->type&HTF_GOTO_LABEL)
+            tmpie->flags|=IEF_GOTO_LABEL;
+          if (tmpex->import_name)
+            tmpie->str=StrNew(tmpex->import_name);
+          else
+            tmpie->str=StrNew(tmpex->str);
+          do {
+            tmpie1=tmpie->next;
+            QueIns(tmpie,tmpaot->last_ie);
+          } while (tmpie=tmpie1);
+          tmpex->ie_lst=NULL;
+        }
+      } else if (tmpex->type & (HTF_EXPORT|HTF_RESOLVE)) {
+        if (tmpex->type & HTF_UNRESOLVED) {
+          PrintErr("Undefined sym at %s\n",tmpex->str);
+          LexExcept(cc);
+        }
+        if (tmpex->type & HTF_RESOLVE) {
+          tmpf=tmpex;
+          tmpeu=tmpf->ext_lst;
+          while (tmpeu) {
+            tmpeu8=tmpeu->next;
+            j=tmpf->exe_addr-(tmpeu->rip+4);
+            AOTStoreCodeU8At(cc,tmpeu->rip,j.u8[0],j.u8[1],j.u8[2],j.u8[3]);
+            Free(tmpeu);
+            tmpeu=tmpeu8;
+          }
+        }
+        if (tmpex->type & HTF_EXPORT) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_REL32_EXPORT;
+          if (tmpex->type & HTT_FUN)
+            tmpie->rip=tmpf->exe_addr;
+          else if (tmpex->type & HTT_GLBL_VAR)
+            tmpie->rip=tmpex(CHashGlblVar *)->data_addr_rip;
+          else
+            tmpie->rip=tmpex->val;
+          tmpie->aot=cc->aot;
+          if (tmpex->type & HTF_IMM)
+            tmpie->type++;
+          tmpie->str=StrNew(tmpex->str);
+          tmpie->src_link=StrNew(tmpex->src_link);
+          QueIns(tmpie,tmpaot->last_ie);
+        }
+      }
+      tmpex=tmpex->next;
+    }
+  }
+}
+
+U0 AsmUnresolvedAdd(CCmpCtrl *cc,U8 *machine_code,I64 type,I64 rip,I64 rel_rip,
+        CAsmUndefHash *local_asm_undef_hash,CAsmUndefHash *glbl_asm_undef_hash,
+        I64 line_num,Bool U8_avail)
+{
+  CAsmUnresolvedRef *tmpu=MAlloc(sizeof(CAsmUnresolvedRef));
+  tmpu->machine_code=machine_code;
+  tmpu->type=type;
+  tmpu->rip=rip;
+  tmpu->rel_rip=rel_rip;
+  tmpu->aot=cc->aot;
+  tmpu->imm_flag=FALSE;
+  tmpu->line_num=line_num;
+  tmpu->U8_avail=U8_avail;
+  tmpu->str=NULL;
+  if (local_asm_undef_hash) {
+    tmpu->asm_undef_hash=local_asm_undef_hash;
+    tmpu->next=cc->aotc->local_unresolved;
+    cc->aotc->local_unresolved=tmpu;
+  } else {
+    tmpu->asm_undef_hash=glbl_asm_undef_hash;
+    tmpu->next=cc->aotc->glbl_unresolved;
+    cc->aotc->glbl_unresolved=tmpu;
+    if (glbl_asm_undef_hash->hash->type & HTF_IMPORT) {
+      tmpu->str=StrNew(glbl_asm_undef_hash->hash->str);
+      if (glbl_asm_undef_hash->hash->type & HTF_IMM)
+        tmpu->imm_flag=TRUE;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/BackA.HC.HTML b/public/Wb/Home/Src/Compiler/BackA.HC.HTML new file mode 100755 index 0000000..f742abd --- /dev/null +++ b/public/Wb/Home/Src/Compiler/BackA.HC.HTML @@ -0,0 +1,689 @@ + + + + + + + + + + + +
+U0 ICAddEct(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,I64 op,I64 rip)
+{
+  I64 i,tmp,res_reg=REG_RAX;
+  Bool swap=FALSE;
+  if (r3!=res_reg) {
+    swap^=TRUE;
+    SwapI64(&t2,&t3);
+    SwapI64(&r2,&r3);
+    SwapI64(&d2,&d3);
+  }
+  if (t2.raw_type>=RT_I64 && r2!=res_reg && t2&MDG_REG_DISP_SIB_RIP) {
+    if (t1&MDF_REG && !(r2==r1 && t2&MDG_REG_DISP_SIB))
+      res_reg=r1;
+    ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
+    i=ICModr1(res_reg,t2,r2,d2);
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICRex(tmpi,i.u8[1]);
+    ICU16(tmpi,i.u8[2]<<8+op);
+    ICModr2(tmpi,i,,d2,rip);
+  } else {
+    if (t2&MDF_REG)
+      tmp=r2;
+    else
+      tmp=REG_RCX;
+
+    if (t1&MDF_REG)
+      res_reg=r1;
+
+    if (tmp==res_reg)
+      res_reg=REG_RDX;
+    if (swap) {
+      if (r3==tmp && t3&MDG_REG_DISP_SIB)
+        tmp=REG_RCX;
+      ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t2,r2,d2,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
+    } else {
+      if (r2==res_reg && t2&MDG_REG_DISP_SIB)
+        res_reg=REG_RDX;
+      ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t3,r3,d3,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t2,r2,d2,rip);
+    }
+    i=0x48;
+    if (res_reg>7)
+      i+=4;
+    if (tmp>7)
+      i++;
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICU24(tmpi,0xC00000+i+(tmp&7)<<16+(res_reg&7)<<19+op<<8);
+  }
+  ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+U0 ICAddSubEctImm(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,I64 d,I64 op,I64 rip)
+{
+  I64 i;
+  if (op.u8[0]==0x2B) {
+    op=0x0003;
+    d=-d;
+  }
+  if (t1&MDF_REG) {
+    if (!(t2&MDF_REG)) {
+      ICMov(tmpi,t1,r1,d1,t2,r2,d2,rip);
+      t2=t1;
+      r2=r1;
+      d2=d1;
+    }
+    if (r1==r2) {
+      if (r1>7)
+        i=0x49;
+      else
+        i=0x48;
+      if (!d &&
+            (op.u8[0]==0x03||op.u8[0]==0x2B||op.u8[0]==0x33||op.u8[0]==0x0B))
+        return;
+      else if (d==1 && op.u8[0]==0x03) {
+        ICU24(tmpi,0xC0FF00+op.u8[1]<<19+i+(r1&7)<<16);
+        return;
+      } else if (d==-1 && op.u8[0]==0x03) {
+        ICU24(tmpi,0xC8FF00+i+(r1&7)<<16);
+        return;
+      } else if (I8_MIN<=d<=I8_MAX) {
+        ICU24(tmpi,0xC08300+op.u8[1]<<19+i+(r1&7)<<16);
+        ICU8(tmpi,d);
+        return;
+      } else if (I32_MIN<=d<=I32_MAX) {
+        ICU24(tmpi,0xC08100+op.u8[1]<<19+i+(r1&7)<<16);
+        ICU32(tmpi,d);
+        return;
+      }
+    }
+    if (op.u8[0]==0x03 && I32_MIN<=d<=I32_MAX &&
+          !Bt(&cmp.non_ptr_vars_mask,r2)) {
+      i=ICModr1(r1,MDF_DISP+RT_I64,r2,d);
+      i.u8[1]|=0x48;
+      ICU24(tmpi,i.u8[2]<<16+0x8D00+i.u8[1]);
+      ICModr2(tmpi,i,,d,rip);
+      return;
+    }
+  }
+  switch (Bsr(t1)) {
+    case MDf_REG:
+    case MDf_DISP:
+    case MDf_SIB:
+    case MDf_RIP_DISP32:
+      if (t1!=t2 || r1!=r2 || d1!=d2) {
+        ICMov(tmpi,t1,r1,d1,t2,r2,d2,rip);
+        t2=t1;
+        r2=r1;
+        d2=d1;
+      }
+
+      if (!d &&(op.u8[0]==0x03||op.u8[0]==0x2B||op.u8[0]==0x33||op.u8[0]==0x0B))
+        return;
+
+      if (op.u8[0]==0x03 && d==-1) //add -1
+        op.u8[1]=1; //Decrement slash val
+
+      if (op.u8[0]==0x03 && (d==1 || d==-1)) {  //Add
+        i=ICModr1(op.u8[1],t1,r1,d1);
+        if (!(t1&MDF_REG) && tmpi->ic_flags&ICF_LOCK)
+          ICU8(tmpi,OC_LOCK_PREFIX);
+        switch (t1.raw_type) {
+          case RT_I8:
+          case RT_U8:
+            ICRex(tmpi,i.u8[1]);
+            ICU16(tmpi,i.u8[2]<<8+0xFE);
+            break;
+          case RT_I16:
+          case RT_U16:
+            ICOpSizeRex(tmpi,i.u8[1]);
+            ICU16(tmpi,i.u8[2]<<8+0xFF);
+            break;
+          default:
+            ICRex(tmpi,i.u8[1]);
+            ICU16(tmpi,i.u8[2]<<8+0xFF);
+        }
+        ICModr2(tmpi,i,,d1,rip);
+        return;
+      }
+      if (I8_MIN<=d<=I8_MAX || t1&(RTG_MASK-RTF_UNSIGNED)==RT_I8) {
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_IMM_U8+op.u8[1],rip+1);
+        ICU8(tmpi,d);
+        return;
+      }
+      if (I32_MIN<=d<=I32_MAX || t1.raw_type<RT_I64) {
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_IMM_U32+op.u8[1],rip);
+        if (t1&(RTG_MASK-RTF_UNSIGNED)==RT_I16)
+          ICU16(tmpi,d);
+        else
+          ICU32(tmpi,d);
+        return;
+      }
+      break;
+    case MDf_STK:
+      ICAddSubEctImm(tmpi,MDF_REG+RT_I64,REG_RAX,0,t2,r2,d2,d,op,rip);
+      ICPushRegs(tmpi,1<<REG_RAX);
+      return;
+  }
+  ICAddEct(tmpi,t1,r1,d1,MDF_IMM+RT_I64,0,d,t2,r2,d2,op.u8[0],rip);
+}
+
+U0 ICSub(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,I64 rip)
+{
+  I64 i=0x48,op=0x2B;
+  Bool swap=FALSE;
+  if (r3!=REG_RAX) {
+    swap=TRUE;
+    SwapI64(&t2,&t3);
+    SwapI64(&r2,&r3);
+    SwapI64(&d2,&d3);
+  }
+  if (t2.raw_type>=RT_I64 && r2.u8[0]!=REG_RAX &&
+        (!(t2&MDF_SIB) || r2.u8[1]&15!=REG_RAX) && t2&MDG_REG_DISP_SIB_RIP) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+    if (!swap) {
+      op=0x03;
+      ICU24(tmpi,0xD8F748);
+    }
+    i=ICModr1(REG_RAX,t2,r2,d2);
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICRex(tmpi,i.u8[1]);
+    ICU16(tmpi,i.u8[2]<<8+op);
+    ICModr2(tmpi,i,,d2,rip);
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    if (!(t3&MDF_REG) || t3.raw_type<RT_I64) {
+      if (swap) {
+        swap=FALSE;
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+        r2=REG_RAX;
+        r3=REG_RCX;
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+        r3=REG_RAX;
+        r2=REG_RCX;
+      }
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+      r2=REG_RCX;
+    }
+    if (swap) {
+      op=0x03;
+      ICU24(tmpi,0xD9F748);
+    }
+    if (r3>7)
+      i++;
+    if (r2>7)
+      i+=4;
+    if (tmpi->ic_flags&ICF_LOCK)
+      ICU8(tmpi,OC_LOCK_PREFIX);
+    ICU24(tmpi,0xC00000+i+(r3&7)<<16+(r2&7)<<19+op<<8);
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,r2,0,rip);
+  }
+}
+
+U0 ICMul(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i,r2,r=REG_RAX,j;
+  CICArg *arg1,*arg2;
+  Bool alt;
+  if (tmpi->arg1.type&MDF_IMM) {
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+    alt=TRUE;
+  } else {
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+    alt=FALSE;
+  }
+  i=arg2->disp;
+  if (!(tmpi->ic_class->raw_type&RTF_UNSIGNED) &&
+        arg2->type&MDF_IMM && I32_MIN<=i<=I32_MAX) {
+    if (tmpi->res.type==MDF_REG+RT_I64) {
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            arg1->type,arg1->reg,arg1->disp,rip);
+      r=tmpi->res.reg;
+    } else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,arg1->reg,arg1->disp,rip);
+    if (r>7)
+      j=0xC0004D;
+    else
+      j=0xC00048;
+    if (I8_MIN<=i<=I8_MAX)
+      ICU32(tmpi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
+    else {
+      ICU24(tmpi,0x6900+j+(r&7)<<16+(r&7)<<19);
+      ICU32(tmpi,i);
+    }
+  } else {
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED)
+      i=0xE0F748;
+    else
+      i=0xE8F748;
+    if (alt) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      r2=REG_RCX;
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,arg2->reg,arg2->disp,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,arg2->reg,arg2->disp,rip);
+      if (!(arg1->type&MDF_REG) || arg1->type.raw_type<RT_I64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+              arg1->type,arg1->reg,arg1->disp,rip);
+        r2=REG_RCX;
+      } else
+        r2=arg1->reg;
+    }
+    if (r2>7) {
+      i++;
+      r2&=7;
+    }
+    ICU24(tmpi,i+r2<<16);
+  }
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,r,0,rip);
+}
+
+U0 ICMulEqu(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i=tmpi->arg2.disp,r=REG_RAX,j;
+  if (!(tmpi->ic_class->raw_type&RTF_UNSIGNED) &&
+        tmpi->arg2.type&MDF_IMM && I32_MIN<=i<=I32_MAX) {
+    if (tmpi->ic_flags & ICF_BY_VAL) {
+      if (tmpi->arg1.type==MDF_REG+RT_I64)
+        r=tmpi->arg1.reg;
+      else
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      if (r>7)
+        j=0xC0004D;
+      else
+        j=0xC00048;
+      if (I8_MIN<=i<=I8_MAX)
+        ICU32(tmpi,i<<24+0x6B00+j+(r&7)<<16+(r&7)<<19);
+      else {
+        ICU24(tmpi,0x6900+j+(r&7)<<16+(r&7)<<19);
+        ICU32(tmpi,i);
+      }
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,r,0,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      r=REG_RBX;
+      if (I8_MIN<=i<=I8_MAX)
+        ICU32(tmpi,i<<24+0xDB6B48);
+      else {
+        ICU24(tmpi,0xDB6948);
+        ICU32(tmpi,i);
+      }
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,REG_RBX,0,rip);
+    }
+  } else {
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED)
+      i=0xE3F748;
+    else
+      i=0xEBF748;
+    if (tmpi->ic_flags & ICF_BY_VAL) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICU24(tmpi,i);
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      ICU24(tmpi,i);
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    }
+  }
+  if (tmpi->res.type.mode)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,r,0,rip);
+}
+
+U0 ICDiv(CIntermediateCode *tmpi,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+    ICZero(tmpi,REG_RDX);
+    ICU24(tmpi,0xF1F748);
+  } else {
+    ICU16(tmpi,0x9948);
+    ICU24(tmpi,0xF9F748);
+  }
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICDivEqu(CIntermediateCode *tmpi,Bool is_mod,I64 rip)
+{
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+          tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+      ICZero(tmpi,REG_RDX);
+      ICU24(tmpi,0xF1F748);
+    } else {
+      ICU16(tmpi,0x9948);
+      ICU24(tmpi,0xF9F748);
+    }
+    if (is_mod)
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RDX,0,rip);
+    else
+      ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+//dangerous might clobber RBX in Mov, but it doesn't
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+tmpi->arg1_type_pointed_to,
+          REG_RBX,0,rip);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+      ICZero(tmpi,REG_RDX);
+      ICU24(tmpi,0xF1F748);
+    } else {
+      ICU16(tmpi,0x9948);
+      ICU24(tmpi,0xF9F748);
+    }
+    if (is_mod)
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RBX,0,
+            MDF_REG+RT_I64,REG_RDX,0,rip);
+    else
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RBX,0,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+  if (tmpi->res.type.mode) {
+    if (is_mod)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RDX,0,rip);
+    else
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+U0 ICMod(CIntermediateCode *tmpi,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED) {
+    ICZero(tmpi,REG_RDX);
+    ICU24(tmpi,0xF1F748);
+  } else {
+    ICU16(tmpi,0x9948);
+    ICU24(tmpi,0xF9F748);
+  }
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RDX,0,rip);
+}
+
+U0 ICAddSubEctEqu(CIntermediateCode *tmpi,U8 type_pointed_to,
+        CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,
+        CICType t3,I64 r3,I64 d3,I64 op,I64 rip)
+{
+  Bool done;
+  I64 res_reg,tmp,i;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (t3&MDF_IMM) {
+      ICAddSubEctImm(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,t2&MDG_MASK+
+            type_pointed_to,r2,d2,d3,op,rip);
+      if (t1.mode)
+        ICMov(tmpi,t1,r1,d1,t2&MDG_MASK+type_pointed_to,r2,d2,rip);
+      return;
+    } else {
+      done=FALSE;
+      if (type_pointed_to>=RT_I64) {
+        if (!t1.mode && t2&MDG_REG_DISP_SIB_RIP) {
+          if (t3&MDF_REG)
+            tmp=r3;
+          else {
+            tmp=REG_RCX;
+            ICMov(tmpi,MDF_REG+RT_I64,tmp,0,t3,r3,d3,rip);
+          }
+          i=ICModr1(tmp,t2&MDG_MASK+type_pointed_to,r2,d2);
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          ICRex(tmpi,i.u8[1]);
+          ICU16(tmpi,i.u8[2]<<8+op.u8[5]);
+          ICModr2(tmpi,i,,d2,rip);
+          return;
+        }
+        if (t3.raw_type>=RT_I64 && t3&MDG_REG_DISP_SIB_RIP) {
+          if (t2&MDF_REG)
+            res_reg=r2;
+          else {
+            res_reg=REG_RCX;
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+          }
+          i=ICModr1(res_reg,t3&MDG_MASK+type_pointed_to,r3,d3);
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          ICRex(tmpi,i.u8[1]);
+          ICU16(tmpi,i.u8[2]<<8+op.u8[0]);
+          ICModr2(tmpi,i,,d3,rip);
+          ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
+                MDF_REG+RT_I64,res_reg,0,rip);
+          done=TRUE;
+        }
+      }
+      if (!done) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+        if (t2&MDF_REG && r2!=REG_RAX)
+          res_reg=r2;
+        else {
+          res_reg=REG_RCX;
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+                t2&MDG_MASK+type_pointed_to,r2,d2,rip);
+        }
+        if (tmpi->ic_flags&ICF_LOCK)
+          ICU8(tmpi,OC_LOCK_PREFIX);
+        if (res_reg>7)
+          ICU8(tmpi,0x4C);
+        else
+          ICU8(tmpi,0x48);
+        ICU16(tmpi,0xC000+op.u8[0]+(res_reg&7)<<11);
+        ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
+              MDF_REG+RT_I64,res_reg,0,rip);
+      }
+    }
+  } else {
+    done=FALSE;
+    if (t3&MDF_IMM && op.u8[2]) {
+      if (!d3.u32[1]) {
+        if (tmpi->ic_flags&ICF_RES_NOT_USED &&
+              t2&MDF_REG && d3(U64)<=I8_MAX) {
+          ICSlashOp(tmpi,MDF_DISP+type_pointed_to,r2,0,0x838000+op.u8[4],rip);
+          ICU8(tmpi,d3);
+          done=TRUE;
+        } else if (op.u8[2]==0x24) {//AND
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_DISP+type_pointed_to,REG_RCX,0,rip);
+          res_reg=REG_RAX;
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          ICU16(tmpi,op.u8[3]<<8+0x40);
+          ICU32(tmpi,d3);
+          ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
+                MDF_REG+RT_I64,res_reg,0,rip);
+          done=TRUE;
+        } else if (type_pointed_to<RT_I64) {//OR/XOR
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_DISP+type_pointed_to,REG_RCX,0,rip);
+          res_reg=REG_RAX;
+          if (tmpi->ic_flags&ICF_LOCK)
+            ICU8(tmpi,OC_LOCK_PREFIX);
+          if (d3.u16[1]) {
+            ICU16(tmpi,op.u8[3]<<8+0x40);
+            ICU32(tmpi,d3);
+          } else if (d3.u8[1]) {
+            ICU24(tmpi,op.u8[3]<<16+0x4000+OC_OP_SIZE_PREFIX);
+            ICU16(tmpi,d3);
+          } else {
+            ICU16(tmpi,op.u8[2]<<8+0x40);
+            ICU8(tmpi,d3);
+          }
+          ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
+                MDF_REG+RT_I64,res_reg,0,rip);
+          done=TRUE;
+        }
+      }
+    }
+    if (!done) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,t3,r3,d3,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+            MDF_DISP+type_pointed_to,REG_RCX,0,rip);
+      res_reg=REG_RBX;
+      if (tmpi->ic_flags&ICF_LOCK)
+        ICU8(tmpi,OC_LOCK_PREFIX);
+      ICU8(tmpi,0x48);
+      ICU16(tmpi,0xC000+op.u8[0]+(res_reg&7)<<11);
+      ICMov(tmpi,MDF_DISP+type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,res_reg,0,rip);
+    }
+  }
+  if (t1.mode)
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+U0 ICShift(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CICType t3,I64 r3,I64 d3,
+        I64 us,I64 is,I64 rip)
+{
+  I64 i=0x48,res_reg;
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+        tmpi->ic_flags & ICF_USE_UNSIGNED)
+    is=us;
+  if (t1&MDF_REG) {
+    res_reg=r1;
+    if (res_reg>7)
+      i++;
+  } else
+    res_reg=REG_RAX;
+  if (t3&MDF_IMM) {
+    ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t2,r2,d2,rip);
+    if (d3==1)
+      ICU24(tmpi,i+is.u16[2]<<8+(res_reg&7)<<16);
+    else {
+      ICU24(tmpi,i+is.u16[0]<<8+(res_reg&7)<<16);
+      ICU8(tmpi,d3);
+    }
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,res_reg,0,t2,r2,d2,rip);
+    ICU24(tmpi,i+is.u16[1]<<8+(res_reg&7)<<16);
+  }
+  ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+U0 ICShiftEqu(CIntermediateCode *tmpi,U8 type_pointed_to,
+        CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,
+        CICType t3,I64 r3,I64 d3,I64 us,I64 is,I64 rip)
+{
+  I64 res_reg;
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+        tmpi->ic_flags & ICF_USE_UNSIGNED)
+    is=us;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (!(t3&MDF_IMM))
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
+    if (t2&MDF_REG)
+      res_reg=r2;
+    else {
+      res_reg=REG_RAX;
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            t2&MDG_MASK+type_pointed_to,r2,d2,rip);
+    }
+    if (res_reg>7)
+      ICU8(tmpi,0x49);
+    else
+      ICU8(tmpi,0x48);
+    if (t3&MDF_IMM) {
+      if (d3==1)
+        ICU16(tmpi,is.u16[2]+(res_reg&7)<<8);
+      else {
+        ICU16(tmpi,is.u16[0]+(res_reg&7)<<8);
+        ICU8(tmpi,d3);
+      }
+    } else
+      ICU16(tmpi,is.u16[1]+(res_reg&7)<<8);
+    ICMov(tmpi,t2&MDG_MASK+type_pointed_to,r2,d2,
+          MDF_REG+RT_I64,res_reg,0,rip);
+  } else {
+    if (!(t3&MDF_IMM))
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t3,r3,d3,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,t2,r2,d2,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+type_pointed_to,REG_RDX,0,rip);
+    res_reg=REG_RAX;
+    ICU8(tmpi,0x48);
+    if (t3&MDF_IMM) {
+      if (d3==1)
+        ICU16(tmpi,is.u16[2]+(res_reg&7)<<8);
+      else {
+        ICU16(tmpi,is.u16[0]+(res_reg&7)<<8);
+        ICU8(tmpi,d3);
+      }
+    } else
+      ICU16(tmpi,is.u16[1]+(res_reg&7)<<8);
+    ICMov(tmpi,
+          MDF_DISP+type_pointed_to,REG_RDX,0,MDF_REG+RT_I64,res_reg,0,rip);
+  }
+  if (t1.mode)
+    ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,res_reg,0,rip);
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/BackB.HC.HTML b/public/Wb/Home/Src/Compiler/BackB.HC.HTML new file mode 100755 index 0000000..f4143a1 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/BackB.HC.HTML @@ -0,0 +1,750 @@ + + + + + + + + + + + +
+U0 ICUnaries(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICNot(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i;
+  if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {
+    i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);
+    ICRex(tmpi,i.u8[1]);
+    ICU16(tmpi,i.u8[2]<<8+0xF6); //TEST ?,0xFF
+    ICModr2(tmpi,i,,tmpi->arg1.disp,rip+1);
+    ICU8(tmpi,0xFF);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICTest(tmpi,REG_RAX);
+  }
+  ICU24(tmpi,0xC0940F);   //SETZ AL
+  ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_U64,REG_RAX,0,rip);
+}
+
+U0 ICAndAnd(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 r2;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r2=REG_RDX;
+  } else
+    r2=tmpi->arg1.reg;
+  ICZero(tmpi,REG_RAX);
+  ICTest(tmpi,r2);
+  ICU16(tmpi,0x0874);
+  ICTest(tmpi,REG_RCX);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC0FF48);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICOrOr(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 i=0x48,r2;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg==REG_RAX) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r2=REG_RDX;
+  } else
+    r2=tmpi->arg1.reg;
+
+  if (r2>7) {
+    i++;
+    r2&=7;
+  }
+  ICZero(tmpi,REG_RAX);
+  ICU24(tmpi,0xC80B00+i+r2<<16);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC0FF48);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICXorXor(CIntermediateCode *tmpi,I64 rip)
+{
+  I64 r2;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  if (!(tmpi->arg1.type&MDF_REG)) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r2=REG_RDX;
+  } else
+    r2=tmpi->arg1.reg;
+  ICZero(tmpi,REG_RBX);
+  ICTest(tmpi,r2);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC3FF48);
+
+  ICZero(tmpi,REG_RAX);
+  ICTest(tmpi,REG_RCX);
+  ICU16(tmpi,0x0374);
+  ICU24(tmpi,0xC0FF48);
+
+  ICU24(tmpi,0xC33348);
+
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICCmp(CIntermediateCode *tmpi,I64 us,I64 is,I64 rip)
+{
+  I64 r1,d1,r2,i=0x48,j=tmpi->arg2.disp;
+  if (tmpi->arg2.type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
+    if (!(tmpi->ic_flags&(ICF_POP_CMP|ICF_PUSH_CMP)) &&
+          tmpi->arg1.type&MDF_DISP && //TODO
+          tmpi->arg1.type.raw_type>=RT_I64 && tmpi->arg1.reg!=REG_RAX) {
+      r1=tmpi->arg1.reg;
+      d1=tmpi->arg1.disp;
+      ICZero(tmpi,REG_RAX);
+      if (r1>7)
+        i++;
+      if (I8_MIN<=j<=I8_MAX)
+        i+=0x388300;
+      else
+        i+=0x388100;
+      if (!d1) {
+        ICU24(tmpi,0x000000+i+(r1&7)<<16);
+      } else if (I8_MIN<=d1<=I8_MAX) {
+        ICU24(tmpi,0x400000+i+(r1&7)<<16);
+        ICU8(tmpi,d1);
+      } else {
+        ICU24(tmpi,0x800000+i+(r1&7)<<16);
+        ICU32(tmpi,d1);
+      }
+      if (I8_MIN<=j<=I8_MAX)
+        ICU8(tmpi,j);
+      else
+        ICU32(tmpi,j);
+    } else {
+      if (tmpi->ic_flags & ICF_POP_CMP) {
+        ICPopRegs(tmpi,1<<REG_RCX);
+        r1=REG_RCX;
+      } else {
+        if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)
+          r1=tmpi->arg1.reg;
+        else {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+          r1=REG_RCX;
+        }
+      }
+      ICZero(tmpi,REG_RAX);
+      if (r1>7)
+        i++;
+      if (I8_MIN<=j<=I8_MAX) {
+        ICU24(tmpi,0xF88300+i+(r1&7)<<16);
+        ICU8(tmpi,j);
+      } else {
+        ICU24(tmpi,0xF88100+i+(r1&7)<<16);
+        ICU32(tmpi,j);
+      }
+    }
+    if (tmpi->ic_flags & ICF_PUSH_CMP)
+      ICPush(tmpi,MDF_IMM+RT_I64,0,j,rip);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+          tmpi->ic_flags & ICF_USE_UNSIGNED)
+      is=us;
+    ICU16(tmpi,0x300+is);
+    ICU24(tmpi,0xC0FF48);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    if (tmpi->arg2.type&MDF_REG && tmpi->arg2.reg!=REG_RAX)
+      r2=tmpi->arg2.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      r2=REG_RCX;
+    }
+    if (tmpi->ic_flags & ICF_POP_CMP) {
+      ICPopRegs(tmpi,1<<REG_RDX);
+      r1=REG_RDX;
+    } else {
+      if (tmpi->arg1.type&MDF_REG && tmpi->arg1.reg!=REG_RAX)
+        r1=tmpi->arg1.reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+        r1=REG_RDX;
+      }
+    }
+    ICZero(tmpi,REG_RAX);
+    if (r2>7)
+      i++;
+    if (r1>7)
+      i+=4;
+    if (tmpi->ic_flags & ICF_PUSH_CMP)
+      ICPushRegs(tmpi,1<<r2);
+    ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
+    if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+          tmpi->ic_flags & ICF_USE_UNSIGNED)
+      is=us;
+    ICU16(tmpi,0x300+is);
+    ICU24(tmpi,0xC0FF48);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+U0 ICBitOps(CIntermediateCode *tmpi,CICArg *arg1,CICArg *arg2,
+        CIntermediateCode *tmpi2,I64 op,I64 op_imm,I64 rip)
+{//TODO:not fully utilizing Modr
+  Bool res_not_used=ToBool(tmpi2->ic_flags&ICF_RES_NOT_USED);
+  I64 r1,t2,r2,d2,i=0x48;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    t2=arg2->type&MDG_MASK+RT_I64; //TODO: check overflow
+    r2=arg2->reg;
+    d2=arg2->disp;
+    if (!(t2&MDG_REG_DISP_SIB_RIP) || !(r2.u8[0]!=REG_RAX&&(!(t2&MDF_SIB) ||
+        r2.u8[1]&15!=REG_RAX) || res_not_used)) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,rip);
+      t2=MDF_REG+RT_I64;
+      r2=REG_RCX;
+      d2=0;
+    }
+    if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))
+      r1=arg1->reg;
+    else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      r1=REG_RDX;
+    } else
+      r1=0;
+  } else {
+    t2=MDF_DISP+RT_I64;
+    d2=0;
+    if (arg2->type&MDF_REG && (arg2->reg!=REG_RAX||res_not_used))
+      r2=arg2->reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip);
+      r2=REG_RCX;
+    }
+    if (arg1->type&MDF_REG && (arg1->reg!=REG_RAX||res_not_used))
+      r1=arg1->reg;
+    else if (!(arg1->type&MDF_IMM) || arg1->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      r1=REG_RDX;
+    } else
+      r1=0;
+  }
+  if (!res_not_used)
+    ICZero(tmpi,REG_RAX);
+  if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)
+    ICU8(tmpi,OC_LOCK_PREFIX);
+  if (arg1->type&MDF_IMM && arg1->disp<32)
+    t2=t2&MDG_MASK+RT_U32;
+  i=ICModr1(r1,t2,r2,d2);
+  ICRex(tmpi,i.u8[1]);
+  if (arg1->type&MDF_IMM && arg1->disp<64) {
+    ICU24(tmpi,i.u8[2]<<16+op_imm);
+    ICModr2(tmpi,i,,d2,rip+1);
+    ICU8(tmpi,arg1->disp);
+  } else {
+    ICU24(tmpi,i.u8[2]<<16+op);
+    ICModr2(tmpi,i,,d2,rip);
+  }
+  if (!res_not_used) {
+    ICU24(tmpi,0xC0920F); //SETC AL
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+U0 ICToUpper(CIntermediateCode *tmpi,I64 rip)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  ICU32(tmpi,0x61F88348);
+  ICU16(tmpi,0x0A7C);
+  ICU32(tmpi,0x7AF88348);
+  ICU16(tmpi,0x047F);
+  ICU32(tmpi,0xE0C08348);
+}
+
+U0 ICToI64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{
+  ICFCvt(cc,tmpi,REG_RAX,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,TRUE,CN_INST,rip);
+}
+
+U0 ICToF64(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{
+  ICFCvt(cc,tmpi,REG_RAX,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,FALSE,CN_INST,rip);
+}
+
+U0 ICToBool(CCmpCtrl *,CIntermediateCode *tmpi,I64 rip)
+{
+  I64 r;
+  if (tmpi->arg1.type&MDF_REG)
+    r=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    r=REG_RAX;
+  }
+  ICTest(tmpi,r);
+  ICU24(tmpi,0xC0950F);   //SETNZ AL
+  ICU32(tmpi,0xC0B60F48); //MOVZX RAX,AL
+}
+
+U0 ICPreIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  I64 r;
+  CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpc->ptr_stars_cnt && tmpc1->size!=1) {
+      ICAddSubEctImm(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);
+    } else
+      ICSlashOp(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RCX;
+    }
+    if (tmpc->ptr_stars_cnt &&
+          tmpc1->size!=1) {
+      ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+            tmpc1->size,op.u16[3],rip);
+    } else
+      ICSlashOp(tmpi,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);
+  }
+}
+
+U0 ICPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  I64 r;
+  CHashClass *tmpc=tmpi->ic_class,*tmpc1=tmpc-1;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    if (tmpc->ptr_stars_cnt &&  tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG &&
+          !(tmpi->res.type&MDF_REG && tmpi->res.reg==tmpi->arg1.reg))
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RCX;
+    }
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,rip);
+    if (tmpc->ptr_stars_cnt &&  tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,r,0,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,op,rip);
+  }
+}
+
+U0 ICDerefPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  CICType t;
+  I64 r;
+  CHashClass *tmpc1=tmpi->ic_class;
+  t=tmpi->res.type.raw_type;
+  if (t>tmpi->arg1_type_pointed_to)
+    t=tmpi->arg1_type_pointed_to;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RDX;
+    }
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,r,0,rip);
+    if (tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,
+            tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,tmpi->arg1.type&MDG_MASK+RT_I64,
+            tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RCX;
+    }
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r,0,rip);
+    if (tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,r,0,MDF_DISP+RT_I64,r,0,
+            tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,MDF_DISP+RT_I64,r,0,op,rip);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,REG_RDX,0,rip);
+  }
+}
+
+U0 ICAssignPostIncDec(CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  CHashClass *tmpc1=tmpi->ic_class2-1;
+  I64 r;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->arg1.type&MDF_REG)
+      r=tmpi->arg1.reg;
+    else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      r=REG_RDX;
+    }
+    ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,r,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpc1->size!=1 || tmpi->arg1.type&MDF_STK)
+      ICAddSubEctImm(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+            MDF_REG+RT_I64,r,0,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,op,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_I64,REG_RDX,0,rip);
+    ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpc1->size!=1)
+      ICAddSubEctImm(tmpi,MDF_DISP+RT_I64,REG_RDX,0,
+            MDF_REG+RT_I64,REG_RCX,0,tmpc1->size,op.u16[3],rip);
+    else
+      ICSlashOp(tmpi,MDF_DISP+RT_I64,REG_RDX,0,op,rip);
+  }
+}
+
+U0 ICCmpAndBranch(CIntermediateCode *tmpi,Bool has_res,I64 rip,
+   I64 us,I64 is,I64 not_us,I64 not_is,U8 *buf,I64 rip2)
+{
+  I64 r1,r2,i=0x48,j,res_reg;
+  CICType t1,t2;
+  Bool short_jmp,swap,done;
+  CCodeMisc *lb;
+  CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;
+
+  j=arg1->disp;
+  if (arg1->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
+    SwapI64(&arg1,&arg2);
+    swap=TRUE;
+    us=not_us;
+    is=not_is;
+  } else
+    swap=FALSE;
+  if (tmpi->ic_class->raw_type&RTF_UNSIGNED ||
+        tmpi->ic_flags & ICF_USE_UNSIGNED)
+    is=us;
+
+  j=arg2->disp;
+  if (arg2->type&MDF_IMM && I32_MIN<=j<=I32_MAX) {
+    if (!has_res && arg1->type&MDG_REG_DISP_SIB_RIP)
+      ICAddSubEctImm(tmpi,arg1->type,arg1->reg,arg1->disp,
+            arg1->type,arg1->reg,arg1->disp,j,0x073B,rip2);
+    else {
+      if (arg1->type&MDF_REG)
+        r1=arg1->reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+              arg1->reg,arg1->disp,rip2);
+        r1=REG_RDX;
+      }
+      if (!j) {
+        if (is.u8[2]==0x7C) {
+          ICTest(tmpi,r1);
+          is=0x78880F;
+        } else if (is.u8[2]==0x7D) {
+          ICTest(tmpi,r1);
+          is=0x79890F;
+        } else if (is.u8[2]==0x74 || is.u8[2]==0x75)
+          ICTest(tmpi,r1);
+        else {
+          if (r1>7)
+            i++;
+          ICU24(tmpi,0xF88300+i+(r1&7)<<16);
+          ICU8(tmpi,j);
+        }
+      } else {
+        if (r1>7)
+          i++;
+        if (I8_MIN<=j<=I8_MAX) {
+          ICU24(tmpi,0xF88300+i+(r1&7)<<16);
+          ICU8(tmpi,j);
+        } else {
+          ICU24(tmpi,0xF88100+i+(r1&7)<<16);
+          ICU32(tmpi,j);
+        }
+      }
+    }
+    if (has_res) {
+      if (!swap) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_IMM+RT_I64,0,j,rip2);
+        res_reg=REG_RCX;
+      } else
+        res_reg=r1;
+    }
+  } else {
+    done=FALSE;
+    t1=arg1->type;
+    r1=arg1->reg;
+    r2=arg2->reg;
+    t2=arg2->type;
+    if (t2.raw_type>=RT_I64 && !has_res && t2&MDG_DISP_SIB_RIP) {
+      if (!(t1&MDF_REG) || t1.raw_type<RT_I64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,
+              arg1->reg,arg1->disp,rip2);
+        r1=REG_RAX;
+      }
+      i=ICModr1(r1,t2,r2,arg2->disp);
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+0x3B);
+      ICModr2(tmpi,i,,arg2->disp,rip2);
+      done=TRUE;
+    } else if (t1.raw_type>=RT_I64 && t1&MDG_REG_DISP_SIB_RIP) {
+      if (!(t2&MDF_REG) || t2.raw_type<RT_I64) {
+        if (t1&MDF_REG && r1==REG_RAX) {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,
+                arg2->reg,arg2->disp,rip2);
+          r2=REG_RCX;
+        } else {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+                arg2->reg,arg2->disp,rip2);
+          r2=REG_RAX;
+        }
+      }
+      i=ICModr1(r2,t1,r1,arg1->disp);
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+0x39);
+      ICModr2(tmpi,i,,arg1->disp,rip2);
+      if (has_res)
+        res_reg=r2;
+      done=TRUE;
+    }
+    if (!done) {
+      if (arg2->type&MDF_REG)
+        r2=arg2->reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip2);
+        r2=REG_RAX;
+      }
+      if (arg1->type&MDF_REG)
+        r1=arg1->reg;
+      else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
+              arg1->reg,arg1->disp,rip2);
+        r1=REG_RCX;
+      }
+      if (r2>7)
+        i++;
+      if (r1>7)
+        i+=4;
+      ICU24(tmpi,0xC03B00+i+(r2&7)<<16+(r1&7)<<19);
+      if (has_res)
+        res_reg=r2;
+    }
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+  if (has_res)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,res_reg,0,rip2);
+}
+
+U0 ICTestAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)
+{
+  I64 i;
+  Bool short_jmp;
+  CCodeMisc *lb;
+
+  if (!(tmpi->arg1.type&MDF_REG)) {
+    if (tmpi->arg1.type.raw_type<=RT_U8 && tmpi->arg1.type&MDG_DISP_SIB_RIP) {
+      i=ICModr1(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp);
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+0xF6);
+      ICModr2(tmpi,i,,tmpi->arg1.disp,rip2+1);
+      ICU8(tmpi,0xFF);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      ICTest(tmpi,REG_RAX);
+    }
+  } else
+    ICTest(tmpi,tmpi->arg1.reg);
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICFlagBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf)
+{
+  I64 i;
+  Bool short_jmp;
+  CCodeMisc *lb;
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/BackC.HC.HTML b/public/Wb/Home/Src/Compiler/BackC.HC.HTML new file mode 100755 index 0000000..46abb8d --- /dev/null +++ b/public/Wb/Home/Src/Compiler/BackC.HC.HTML @@ -0,0 +1,802 @@ + + + + + + + + + + + +
+U0 ICAndBranch(CIntermediateCode *tmpi,I64 rip,I64 is,U8 *buf,I64 rip2)
+{
+  U64 i;
+  I64 it,t1,r1,d1,r2;
+  Bool short_jmp,swap,override;
+  CCodeMisc *lb;
+  CICArg *arg1,*arg2;
+
+  if (tmpi->arg1.type&MDF_IMM) {
+    swap=TRUE;
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+  } else {
+    swap=FALSE;
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+  }
+
+  if (arg2->type&MDF_IMM && arg2->disp>U32_MAX)
+    override=TRUE;
+  else
+    override=FALSE;
+
+  if (arg1->type.raw_type<arg2->type.raw_type)
+    it=arg1->type.raw_type;
+  else
+    it=arg2->type.raw_type;
+
+  i=arg2->disp;
+  if (arg2->type&MDF_IMM && i<=U32_MAX) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg1->type,arg1->reg,arg1->disp,rip2);
+    if (i<=U8_MAX)
+      ICU16(tmpi,i<<8+0xA8);
+    else if (i<=U16_MAX)
+      ICU32(tmpi,i<<16+0xA900+OC_OP_SIZE_PREFIX);
+    else {
+      ICU8(tmpi,0xA9);
+      ICU32(tmpi,i);
+    }
+  } else {
+    t1=MDF_REG+it;
+    d1=0;
+    if (swap && !override) {
+      if (arg1->type&MDF_REG) {
+        r1=arg1->reg;
+        swap=TRUE;
+      } else {
+        r1=REG_RCX;
+        swap=FALSE;
+      }
+      if (arg2->type&MDF_REG) {
+        r2=arg2->reg;
+        swap=FALSE;
+      } else
+        r2=REG_RDX;
+      if (swap) {
+        if (!(arg1->type&MDF_REG) || r1!=arg1->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        if (arg2->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg2->type&MDG_MASK+it;
+          r2=arg2->reg;
+          d1=arg2->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        i=ICModr1(r1,t1,r2,d1);
+      } else {
+        if (arg1->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+it;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        if (!(arg2->type&MDF_REG) || r2!=arg2->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        i=ICModr1(r2,t1,r1,d1);
+      }
+    } else {
+      if (arg2->type&MDF_REG) {
+        r2=arg2->reg;
+        swap=FALSE;
+      } else {
+        r2=REG_RDX;
+        swap=TRUE;
+      }
+      if (arg1->type&MDF_REG) {
+        r1=arg1->reg;
+        swap=TRUE;
+      } else
+        r1=REG_RCX;
+      if (override)
+        swap=FALSE;
+      if (swap) {
+        if (arg2->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg2->type&MDG_MASK+it;
+          r2=arg2->reg;
+          d1=arg2->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        if (!(arg1->type&MDF_REG) || r1!=arg1->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        i=ICModr1(r1,t1,r2,d1);
+      } else {
+        if (!(arg2->type&MDF_REG) || r2!=arg2->reg)
+          ICMov(tmpi,MDF_REG+RT_I64,r2,0,arg2->type,arg2->reg,arg2->disp,rip2);
+        if (arg1->type&MDG_REG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+it;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else
+          ICMov(tmpi,MDF_REG+RT_I64,r1,0,arg1->type,arg1->reg,arg1->disp,rip2);
+        i=ICModr1(r2,t1,r1,d1);
+      }
+    }
+    switch (it) {
+      case RT_I8:
+      case RT_U8:
+        ICRex(tmpi,i.u8[1]);
+        ICU16(tmpi,i.u8[2]<<8+0x84);
+        break;
+      case RT_U16:
+      case RT_I16:
+        ICOpSizeRex(tmpi,i.u8[1]);
+        ICU16(tmpi,i.u8[2]<<8+0x85);
+        break;
+      default:
+        ICRex(tmpi,i.u8[1]);
+        ICU16(tmpi,i.u8[2]<<8+0x85);
+    }
+    ICModr2(tmpi,i,,d1,rip2);
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICAssign(CIntermediateCode *tmpi,I64 rip)
+{
+  CIntermediateCode *tmpi1;
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+          tmpi->arg1.reg,tmpi->arg1.disp,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else {
+    if (tmpi->arg1.type&MDF_REG) {
+      if (!(tmpi1=OptLag1(tmpi)) || tmpi1->ic_code!=IC_ADD_CONST ||
+            tmpi1->res.type!=MDF_REG+RT_I64 || tmpi1->res.reg!=tmpi->arg1.reg ||
+            tmpi1->arg1.type!=MDF_REG+RT_I64 ||
+            tmpi1->arg1.reg!=tmpi->arg1.reg ||
+            (tmpi->arg2.type&MDF_REG || tmpi->arg2.type&MDF_DISP) &&
+            tmpi->arg2.reg==tmpi->arg1.reg ||
+            tmpi->res.type.mode || tmpi1->ic_flags&~ICG_NO_CVT_MASK) {
+        ICMov(tmpi,
+              MDF_DISP+tmpi->arg1_type_pointed_to,
+              tmpi->arg1.reg,tmpi->arg1.disp,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+        if (tmpi->res.type.mode)
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      } else {
+        tmpi->ic_flags=(tmpi->ic_flags|tmpi1->ic_flags)&
+              ~ICF_CODE_FINAL|ICF_DONT_RESTORE;
+        tmpi->arg1.disp=tmpi1->ic_data;
+        OptSetNOP1(tmpi1); //This better not be last pass!
+        ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,
+              tmpi->arg1.reg,tmpi->arg1.disp,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      }
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      if (tmpi->res.type.mode)
+        ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    }
+  }
+}
+
+U0 ICBrBitOps(CIntermediateCode *tmpi,I64 rip,
+        I64 op,I64 op_imm,I64 is,U8 *buf,I64 rip2)
+{
+  I64 i,t,r1,r2,d1,d2,t1,t2;
+  CICArg *arg1=&tmpi->arg1,*arg2=&tmpi->arg2;
+  Bool short_jmp;
+  CCodeMisc *lb;
+
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (tmpi->ic_flags&ICF_SWAP && !(arg2->type&MDF_REG) &&
+          (!(arg2->type&MDF_IMM) ||arg2->disp>63)||
+          !(tmpi->ic_flags&ICF_SWAP) && arg2->type&MDF_IMM &&
+          arg2->disp<64 || arg2->type&MDF_STK) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);
+      t2=MDF_REG+RT_I64;
+      r2=REG_RCX;
+      d2=0;
+    } else {
+      t2=arg2->type;
+      if (t2&MDF_IMM && arg2->disp<64)
+        r2=0;
+      else
+        r2=arg2->reg;
+      d2=arg2->disp;
+    }
+    if (!(tmpi->ic_flags&ICF_SWAP) && !(arg1->type&MDF_REG) &&
+          (!(arg1->type&MDF_IMM) || arg1->disp>63) ||
+          tmpi->ic_flags&ICF_SWAP && arg1->type&MDF_IMM &&
+          arg1->disp<64 || arg1->type&MDF_STK) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);
+      t1=MDF_REG+RT_I64;
+      r1=REG_RDX;
+      d1=0;
+    } else {
+      t1=arg1->type;
+      if (t1&MDF_IMM && arg1->disp<64)
+        r1=0;
+      else
+        r1=arg1->reg;
+      d1=arg1->disp;
+    }
+  } else {
+    t1=MDF_DISP+RT_I64;
+    t2=MDF_DISP+RT_I64;
+    d1=0;
+    d2=0;
+    if (arg2->type&MDF_REG)
+      r2=arg2->reg;
+    else if (!(tmpi->ic_flags&ICF_SWAP) || !(arg2->type&MDF_IMM) ||
+          arg2->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg2->type,arg2->reg,arg2->disp,rip2);
+      r2=REG_RCX;
+    } else
+      r2=0;
+    if (arg1->type&MDF_REG)
+      r1=arg1->reg;
+    else if (tmpi->ic_flags&ICF_SWAP ||
+          !(arg1->type&MDF_IMM) || arg1->disp>63) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,arg1->reg,arg1->disp,rip2);
+      r1=REG_RDX;
+    } else
+      r1=0;
+  }
+  if (tmpi->ic_flags&ICF_LOCK && op!=0xA30F)
+    ICU8(tmpi,OC_LOCK_PREFIX);
+  if (tmpi->ic_flags&ICF_SWAP) {
+    if (arg2->type&MDF_IMM && arg2->disp<32) {
+      if (op==0xA30F && arg2->disp<8) {
+        t=t1&MDG_MASK+RT_U8;
+        op_imm=0xF6; //TEST
+      } else
+        t=t1&MDG_MASK+RT_U32;
+    } else
+      t=t1;
+    i=ICModr1(r2,t,r1,d1);
+    SwapI64(&arg1,&arg2);
+  } else {
+    if (arg1->type&MDF_IMM && arg1->disp<32) {
+      if (op==0xA30F && arg1->disp<8) {
+        t=t2&MDG_MASK+RT_U8;
+        op_imm=0xF6; //TEST
+      } else
+        t=t2&MDG_MASK+RT_U32;
+    } else
+      t=t2;
+    i=ICModr1(r1,t,r2,d2);
+  }
+  ICRex(tmpi,i.u8[1]);
+  if (op_imm==0xF6) {//TEST
+    ICU16(tmpi,i.u8[2]<<8+op_imm);
+    ICModr2(tmpi,i,,arg2->disp,rip2+1);
+    ICU8(tmpi,1<<arg1->disp);
+    if (is==0x72820F)
+      is=0x75850F;
+    else
+      is=0x74840F;
+  } else if (arg1->type&MDF_IMM && arg1->disp<64) {
+    ICU24(tmpi,i.u8[2]<<16+op_imm);
+    ICModr2(tmpi,i,,arg2->disp,rip2+1);
+    ICU8(tmpi,arg1->disp);
+  } else {
+    ICU24(tmpi,i.u8[2]<<16+op);
+    ICModr2(tmpi,i,,arg2->disp,rip2);
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,i<<8+is.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP)
+      i+=8;
+    ICU16(tmpi,is.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICQueInit(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1;
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RAX;
+  }
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);
+}
+
+U0 ICQueIns(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1,r2;
+  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)
+    r2=tmpi->arg2.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+    r2=REG_RAX;
+  }
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RDX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,0,MDF_REG+RT_I64,r2,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,REG_RBX,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);
+}
+
+U0 ICQueInsRev(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1,r2;
+  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RDX)
+    r2=tmpi->arg2.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+    r2=REG_RAX;
+  }
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RDX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,REG_RBX,0,MDF_REG+RT_I64,r2,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,0,MDF_REG+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r2,sizeof(U8 *),MDF_REG+RT_I64,REG_RBX,0,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,r1,sizeof(U8 *),MDF_REG+RT_I64,r2,0,rip2);
+}
+
+U0 ICQueRem(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1;
+  if (tmpi->arg1.type==MDF_REG+RT_I64)
+    r1=tmpi->arg1.reg;
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    r1=REG_RAX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,MDF_DISP+RT_I64,r1,0,rip2);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_I64,r1,sizeof(U8 *),rip2);
+  ICU24(tmpi,0x1A8948);
+  ICU32(tmpi,sizeof(U8 *)<<24+0x538948);
+}
+
+U0 ICMinMax(CIntermediateCode *tmpi,I64 op,I64 rip2)
+{
+  I64 r1,i1=0x48;
+  if (tmpi->arg2.type==MDF_REG+RT_I64 && tmpi->arg2.reg!=REG_RAX) {
+    r1=tmpi->arg2.reg;
+    if (r1>7) {
+      i1++;
+      r1&=7;
+    }
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  } else {
+    if (tmpi->arg1.reg==REG_RAX && tmpi->arg1.type&MDG_REG_DISP_SIB) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+      r1=REG_RDX;
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+      if (tmpi->arg1.type==MDF_REG+RT_I64) {
+        r1=tmpi->arg1.reg;
+        if (r1>7) {
+          i1++;
+          r1&=7;
+        }
+      } else {
+        r1=REG_RDX;
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      }
+    }
+  }
+  ICU24(tmpi,0xC03B00+r1<<16+i1);
+  ICU32(tmpi,0xC0000F00+op<<16+r1<<24+i1);
+}
+
+U0 ICSqr(CIntermediateCode *tmpi,I64 op,I64 rip2)
+{
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  ICSlashOp(tmpi,MDF_REG+RT_I64,REG_RAX,0,op,rip2);
+}
+
+U0 ICModU64(CIntermediateCode *tmpi,I64 rip2)
+{
+  CICType t1;
+  I64 r1,d1;
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+  if (tmpi->arg1.reg!=REG_RAX && tmpi->arg1.reg!=REG_RDX &&
+        tmpi->arg1.type&MDG_REG_DISP_SIB &&
+        tmpi->arg1.type.raw_type>=RT_I64) {
+    t1=tmpi->arg1.type;
+    r1=tmpi->arg1.reg;
+    d1=tmpi->arg1.disp;
+  } else {
+    t1=MDF_REG+RT_I64;
+    r1=REG_RBX;
+    d1=0;
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip2);
+  ICZero(tmpi,REG_RDX);
+  ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_DIV,rip2);
+  ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip2);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        MDF_REG+RT_I64,REG_RDX,0,rip2);
+}
+
+U0 ICSwap(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 r1,r2;
+  if (tmpi->arg1.type&MDF_REG)
+    r1=tmpi->arg1.reg;
+  else
+    r1=REG_RAX;
+  if (tmpi->arg2.type&MDF_REG)
+    r2=tmpi->arg2.reg;
+  else
+    r2=REG_RAX;
+  if (r1==r2) {
+    if (r1==REG_RAX)
+      r1=REG_RBX;
+    else
+      r2=REG_RAX;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,r2,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+  ICMov(tmpi,MDF_REG+RT_I64,r1,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  switch (tmpi->ic_code) {
+    case IC_SWAP_U8:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U8,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U8,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U8,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U8,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+    case IC_SWAP_U16:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U16,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U16,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U16,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U16,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+    case IC_SWAP_U32:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U32,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U32,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U32,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U32,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+    case IC_SWAP_I64:
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,MDF_DISP+RT_U64,r1,0,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_DISP+RT_U64,r2,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U64,r2,0,MDF_REG+RT_I64,REG_RCX,0,rip2);
+      ICMov(tmpi,MDF_DISP+RT_U64,r1,0,MDF_REG+RT_I64,REG_RDX,0,rip2);
+      break;
+  }
+}
+
+U0 ICAndEqu(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 i,bit;
+  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
+        tmpi->ic_flags&ICF_RES_NOT_USED) {
+    i=~tmpi->arg2.disp;
+    bit=Bsf(i);
+    if (0<=bit==Bsr(i)) {
+      tmpi->arg2.disp=bit;
+      tmpi->arg2.reg=0;
+      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
+      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xB30F,0x30BA0F,rip2);
+      return;
+    }
+  }
+  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x210425240423,rip2);
+}
+
+U0 ICOrEqu(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 i,bit;
+  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
+        tmpi->ic_flags&ICF_RES_NOT_USED) {
+    i=tmpi->arg2.disp;
+    bit=Bsf(i);
+    if (0<=bit==Bsr(i) && i>I8_MAX) {
+      tmpi->arg2.disp=bit;
+      tmpi->arg2.reg=0;
+      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
+      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xAB0F,0x28BA0F,rip2);
+      return;
+    }
+  }
+  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x09010D0C010B,rip2);
+}
+
+U0 ICXorEqu(CIntermediateCode *tmpi,I64 rip2)
+{
+  I64 i,bit;
+  if (tmpi->arg2.type&MDF_IMM && !(tmpi->arg1.type&MDF_STK) &&
+        tmpi->ic_flags&ICF_RES_NOT_USED) {
+    i=tmpi->arg2.disp;
+    bit=Bsf(i);
+    if (0<=bit==Bsr(i)) {
+      tmpi->arg2.disp=bit;
+      tmpi->arg2.reg=0;
+      tmpi->arg1.type=tmpi->arg1.type&MDG_MASK+RT_I64;
+      ICBitOps(tmpi,&tmpi->arg2,&tmpi->arg1,tmpi,0xBB0F,0x38BA0F,rip2);
+      return;
+    }
+  }
+  ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+        tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x310635340633,rip2);
+}
+
+U0 ICSwitch(CIntermediateCode *tmpi,I64 rip,
+        Bool nobound,CCmpCtrl *cc,U8 *buf,I64 rip2)
+{
+  I64 i,j,cnt,min,max,begin,r;
+  CCodeMisc *lb;
+  Bool short_jmp;
+  CAOTAbsAddr *tmpa;
+  if (!(tmpi->arg1.type&MDF_REG) || tmpi->arg1.reg&7==REG_RSP)
+    r=REG_RDX;
+  else
+    r=tmpi->arg1.reg;
+  if (nobound)
+    ICMov(tmpi,MDF_REG+RT_I64,r,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+  else {
+    if (tmpi->arg2.type&MDF_IMM) {
+      j=tmpi->arg2.disp;
+      ICMov(tmpi,MDF_REG+RT_I64,r,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      if (I8_MIN<=j<=I8_MAX) {
+        i=0xF88348+(r&7)<<16;
+        if (r>7) i++;
+        ICU24(tmpi,i);
+        ICU8(tmpi,j);
+      } else if (I32_MIN<=j<=I32_MAX) {
+        i=0xF88148+(r&7)<<16;
+        if (r>7) i++;
+        ICU24(tmpi,i);
+        ICU32(tmpi,j);
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+              tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+        i=0xC13B48+(r&7)<<19;
+        if (r>7) i+=4;
+        ICU24(tmpi,i);
+      }
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+      ICMov(tmpi,MDF_REG+RT_I64,r,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+      i=0xC13B48+(r&7)<<19;
+      if (r>7) i+=4;
+      ICU24(tmpi,i);
+    }
+
+    rip+=tmpi->ic_cnt;
+    lb=tmpi->ic_data(CCodeMisc *)->dft;
+    short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+    if (!buf && lb->addr!=INVALID_PTR) {
+      i=lb->addr-(rip+2);
+      if (I8_MIN<=i<=I8_MAX)
+        short_jmp=TRUE;
+    }
+    if (short_jmp) {
+      tmpi->ic_flags|=ICF_SHORT_JMP;
+      ICU16(tmpi,(lb->addr-(rip+2))<<8+0x73);
+    } else {
+      tmpi->ic_flags&=~ICF_SHORT_JMP;
+      ICU16(tmpi,0x830F);
+      ICU32(tmpi,lb->addr-(rip+6));
+    }
+  }
+
+  lb=tmpi->ic_data;
+  begin=lb->begin->addr;
+  if (!buf && begin!=INVALID_PTR) {
+    min=I64_MAX;
+    max=I64_MIN;
+    for (i=0;i<lb->range;i++) {
+      if (lb->jmp_table[i]->addr==INVALID_PTR) {
+        min=I64_MIN;
+        max=I64_MAX;
+        break;
+      } else {
+        j=lb->jmp_table[i]->addr-begin;
+        min=MinI64(min,j);
+        max=MaxI64(max,j);
+      }
+    }
+    if (I8_MIN<=min<=max<=I8_MAX)
+      lb->flags|=CMF_I8_JMP_TABLE;
+    else if (U8_MIN<=min<=max<=U8_MAX)
+      lb->flags|=CMF_U8_JMP_TABLE;
+    else if (I16_MIN<=min<=max<=I16_MAX)
+      lb->flags|=CMF_I16_JMP_TABLE;
+    else if (U16_MIN<=min<=max<=U16_MAX)
+      lb->flags|=CMF_U16_JMP_TABLE;
+  }
+
+  if (lb->flags&CMF_I8_JMP_TABLE) {
+    if (r<8)
+      ICU8(tmpi,0x48);
+    else
+      ICU8(tmpi,0x49);
+    ICU24(tmpi,0x98BE0F+(r&7)<<16);
+    cnt=1;
+  } else if (lb->flags&CMF_U8_JMP_TABLE) {
+    if (r<8)
+      cnt=2;
+    else {
+      ICU8(tmpi,0x49);
+      cnt=1;
+    }
+    ICU24(tmpi,0x98B60F+(r&7)<<16);
+  } else if (lb->flags&CMF_I16_JMP_TABLE) {
+    if (r<8)
+      ICU8(tmpi,0x48);
+    else
+      ICU8(tmpi,0x4A);
+    ICU32(tmpi,0x451CBF0F+(r&7)<<27);
+    cnt=0;
+  } else if (lb->flags&CMF_U16_JMP_TABLE) {
+    if (r<8)
+      cnt=1;
+    else {
+      ICU8(tmpi,0x4A);
+      cnt=0;
+    }
+    ICU32(tmpi,0x451CB70F+(r&7)<<27);
+  } else {
+    if (r<8)
+      cnt=2;
+    else {
+      ICU8(tmpi,0x42);
+      cnt=1;
+    }
+    ICU24(tmpi,0x851C8B+(r&7)<<19);
+  }
+  if (buf && cc->flags&CCF_AOT_COMPILE) {
+    tmpa=CAlloc(sizeof(CAOTAbsAddr));
+    tmpa->next=cc->aotc->abss;
+    tmpa->type=AAT_ADD_U32;
+    cc->aotc->abss=tmpa;
+    tmpa->rip=rip2+tmpi->ic_cnt;
+    ICU32(tmpi,lb->addr+cc->aotc->rip);
+  } else
+    ICU32(tmpi,lb->addr+buf);
+
+  if (lb->flags&(CMF_I8_JMP_TABLE|CMF_U8_JMP_TABLE|
+        CMF_I16_JMP_TABLE|CMF_U16_JMP_TABLE)) {
+    ICU16(tmpi,0xC381); //ADD EBX,0x12345678
+    if (buf && cc->flags&CCF_AOT_COMPILE) {
+      tmpa=CAlloc(sizeof(CAOTAbsAddr));
+      tmpa->next=cc->aotc->abss;
+      tmpa->type=AAT_ADD_U32;
+      cc->aotc->abss=tmpa;
+      tmpa->rip=rip2+tmpi->ic_cnt;
+      ICU32(tmpi,begin+cc->aotc->rip);
+    } else
+      ICU32(tmpi,begin+buf);
+  } else
+    cnt+=6;
+  ICU16(tmpi,0xE3FF); //JMP EBX
+  for (i=0;i<cnt;i++) //Code must always shrink, not expand
+    ICU8(tmpi,OC_NOP);
+  tmpi->ic_flags&=~ICF_CODE_FINAL;
+}
+
+U0 ICLocalVarInit(CIntermediateCode *tmpi)
+{
+  ICU24(tmpi,0xC48B48);
+  ICU16(tmpi,0x5748);
+  ICU24(tmpi,0xF88B48);
+  ICU24(tmpi,0xC1C748);
+  ICU32(tmpi,tmpi->ic_data);
+  ICU16(tmpi,sys_var_init_val<<8+0xB0);
+  ICU24(tmpi,0xAA48F3);
+  ICU16(tmpi,0x5F48);
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/BackFA.HC.HTML b/public/Wb/Home/Src/Compiler/BackFA.HC.HTML new file mode 100755 index 0000000..399d0c2 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/BackFA.HC.HTML @@ -0,0 +1,638 @@ + + + + + + + + + + + +
+#define CN_A2   0
+#define CN_A1   1
+#define CN_INST 2
+#define CN_RES  3
+
+U0 CmpNoteFloatOp(CCmpCtrl *cc,CIntermediateCode *tmpi,
+        Bool dont_pushable,Bool dont_popable,I64 pos)
+{
+  Bool link=FALSE;
+  if (cc->pass==7 && cc->last_float_op_ic &&
+        cc->last_dont_popable && dont_pushable) {
+    switch [pos] {
+      case CN_A2:
+        if (cc->last_float_op_ic!=tmpi && cc->dont_push_float)
+          link=TRUE;
+        break;
+      case CN_A1:
+        if (cc->last_float_op_ic!=tmpi && cc->dont_push_float)
+          link=TRUE;
+        break;
+      case CN_INST:
+        if (cc->last_float_op_ic!=tmpi) {
+          if (cc->dont_push_float) {
+            if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG &&
+                  cc->last_float_op_ic->res.reg!=REG_R8)
+              tmpi->ic_flags|=ICF_ALT_TEMPLATE;
+            else
+              tmpi->ic_flags&=~ICF_ALT_TEMPLATE;
+            link=TRUE;
+          }
+        } else {
+          if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG &&
+                cc->last_float_op_pos!=CN_A1)
+            tmpi->ic_flags|=ICF_ALT_TEMPLATE;
+          else
+            tmpi->ic_flags&=~ICF_ALT_TEMPLATE;
+          link=TRUE;
+        }
+        break;
+      case CN_RES:
+        if (cc->last_float_op_ic==tmpi && cc->last_float_op_pos==CN_INST)
+          link=TRUE;
+        break;
+    }
+    if (link) {
+      if (!Bts(&cc->last_float_op_ic->ic_flags,
+            ICf_DONT_POP_FLOAT0+cc->last_ic_float_op_num))
+        cc->last_float_op_ic->ic_flags&=~ICF_CODE_FINAL;
+      if (!Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0+cc->cur_ic_float_op_num))
+        tmpi->ic_flags&=~ICF_CODE_FINAL;
+    }
+  }
+  cc->last_float_op_ic=tmpi;
+  cc->last_dont_pushable=dont_pushable;
+  cc->last_dont_popable=dont_popable;
+  cc->last_ic_float_op_num=cc->cur_ic_float_op_num++;
+  cc->last_float_op_pos=pos;
+  if (cc->cur_ic_float_op_num>4)
+    throw('Compiler');
+}
+
+U0 CmpSetFloatOpPushPop(CCmpCtrl *cc,CIntermediateCode *tmpi,
+        Bool *dont_push_float,Bool *dont_pop_float)
+{
+  if (cc->pass==7) {
+    *dont_push_float=FALSE;
+    *dont_pop_float =FALSE;
+    tmpi->ic_flags&=~ICF_CODE_FINAL;
+  } else {
+    *dont_push_float=Bt(&tmpi->ic_flags,
+          ICf_DONT_PUSH_FLOAT0+cc->cur_ic_float_op_num);
+    *dont_pop_float=Bt(&tmpi->ic_flags,
+          ICf_DONT_POP_FLOAT0+cc->cur_ic_float_op_num);
+  }
+}
+
+U0 ICCopyTemplate(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,
+  Bool off_the_record,Bool dont_pushable,Bool dont_popable,I64 pos)
+{
+  Bool dont_push_float,dont_pop_float,alt;
+  U8 *ptr;
+  I64 i=0;
+  if (!off_the_record) {
+    if (tmpi->ic_flags&ICF_ALT_TEMPLATE)
+      alt=TRUE;
+    else
+      alt=FALSE;
+    CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  } else {
+    dont_push_float=FALSE;
+    dont_pop_float=FALSE;
+    alt=FALSE;
+  }
+  if (alt && dont_push_float && !dont_pop_float) {
+    ptr=cmp_templates_dont_push2[op];
+    i=cmp_templates_dont_push2[op+1]-ptr;
+  }
+  if (!i) {
+    if (dont_push_float) {
+      if (dont_pop_float) {
+        ptr=cmp_templates_dont_push_pop[op];
+        i=cmp_templates_dont_push_pop[op+1]-ptr;
+      } else {
+        ptr=cmp_templates_dont_push[op];
+        i=cmp_templates_dont_push[op+1]-ptr;
+      }
+    } else {
+      if (dont_pop_float) {
+        ptr=cmp_templates_dont_pop[op];
+        i=cmp_templates_dont_pop[op+1]-ptr;
+      } else {
+        ptr=cmp_templates[op];
+        i=cmp_templates[op+1]-ptr;
+      }
+    }
+  }
+  MemCpy(&tmpi->ic_body[tmpi->ic_cnt],ptr,i);
+  if (!off_the_record)
+    CmpNoteFloatOp(cc,tmpi,dont_pushable,dont_popable,pos);
+  tmpi->ic_cnt+=i;
+}
+
+U0 ICFCvt(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 r1,
+        CICType t2,I64 r2,I64 d2,Bool to_int,I64 pos,I64 rip)
+{
+  I64 rsp_size=0,op1,op2;
+  Bool dont_push_float,dont_pop_float;
+
+  if (to_int) {
+    op1=SLASH_OP_FLD;
+    op2=SLASH_OP_FISTTP;
+  } else {
+    op1=SLASH_OP_FILD;
+    op2=SLASH_OP_FSTP;
+  }
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (!dont_push_float) {
+    if (!(t2.raw_type>=RT_I64 && t2&MDG_DISP_SIB_RIP)) {
+      ICPush(tmpi,t2,r2,d2,rip);
+      t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      rsp_size=8;
+    } else {
+      if (!dont_pop_float) {
+        rsp_size=8;
+        ICAddRSP(tmpi,-8);
+      }
+    }
+    ICSlashOp(tmpi,t2,r2,d2,op1,rip);
+  } else {
+    if (!dont_pop_float) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    }
+  }
+  if (to_int)
+    CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,pos);
+  else
+    CmpNoteFloatOp(cc,tmpi,FALSE,TRUE,pos);
+  if (dont_pop_float) {
+    if (rsp_size)
+      ICAddRSP(tmpi,rsp_size);
+  } else {
+    ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,rip);
+    ICPop(tmpi,MDF_REG+RT_I64,r1,0,rip);
+  }
+}
+
+U0 ICFCvt2(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 r1,
+        CICType t2,I64 r2,I64 d2,Bool to_int,I64 rip)
+{
+  I64 rsp_size=0,op1,op2;
+  if (to_int) {
+    op1=SLASH_OP_FLD;
+    op2=SLASH_OP_FISTTP;
+  } else {
+    op1=SLASH_OP_FILD;
+    op2=SLASH_OP_FSTP;
+  }
+  if (!(t2.raw_type>=RT_I64 && t2&MDG_DISP_SIB_RIP)) {
+    ICPush(tmpi,t2,r2,d2,rip);
+    t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+    rsp_size=8;
+  } else {
+    rsp_size=8;
+    ICAddRSP(tmpi,-8);
+  }
+  ICSlashOp(tmpi,t2,r2,d2,op1,rip);
+  ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,op2,rip);
+  ICPop(tmpi,MDF_REG+RT_I64,r1,0,rip);
+  cc->last_dont_pushable=cc->last_dont_popable=FALSE; //TODO: improve this
+}
+
+U0 ICFUnaryMinus(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf2,I64 rip)
+{
+  CICArg *arg1=&tmpi->arg1;
+  I64 rsp_size=0,builtin1=0,t1,r1,d1;
+  Bool dont_push_float,dont_pop_float;
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (!dont_push_float) {
+    if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+      t1=arg1->type;
+      r1=arg1->reg;
+      d1=arg1->disp;
+    } else {
+      if (arg1->type&MDF_IMM) {
+        if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+          t1=MDF_RIP_DISP32+RT_I64;
+          r1=REG_RIP;
+          d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+        }
+      } else {
+        ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+        rsp_size+=8;
+      }
+    }
+    if (builtin1)
+      ICU16(tmpi,builtin1);
+    else
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip);
+  }
+  if (!dont_pop_float && !rsp_size) {
+    rsp_size=8;
+    ICAddRSP(tmpi,-8);
+  }
+  ICU16(tmpi,0xE0D9); //FCHS
+  CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+  if (dont_pop_float) {
+    if (rsp_size)
+      ICAddRSP(tmpi,rsp_size);
+  } else {
+    ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+    ICPop(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,rip);
+  }
+}
+
+U0 ICFMod(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{//for MOD
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (tmpi->ic_flags&ICF_ALT_TEMPLATE)
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  }
+//TODO: unpushable,unpop?  Not sure
+  ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
+  if (!dont_pop_float)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFPow(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{//for POW
+  I64 i;
+  CAOTImportExport *tmpie;
+  CHashExport *tmpex=HashFind("SYS_POW",
+        cc->htc.hash_table_lst,HTT_EXPORT_SYS_SYM);
+
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+        tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+        tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  if (cc->flags&CCF_AOT_COMPILE) {
+    if (!tmpex) {
+      tmpex=CAlloc(sizeof(CHashExport));
+      tmpex->str=StrNew("SYS_POW");
+      tmpex->type=HTT_EXPORT_SYS_SYM|HTF_UNRESOLVED|HTF_IMPORT;
+      HashAdd(tmpex,cc->htc.glbl_hash_table);
+    }
+    if (tmpex->type&HTF_IMPORT) {
+      if (GetOption(OPTf_USE_IMM64)) {
+        ICU16(tmpi,0xBB48);
+        ICU64(tmpi,0);
+        if (buf) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_IMM_I64;
+          tmpie->rip=rip+tmpi->ic_cnt-8;
+          tmpie->next=tmpex->ie_lst;
+          tmpex->ie_lst=tmpie;
+        }
+        ICU16(tmpi,0xD3FF);
+      } else {
+        ICU8(tmpi,0xE8);
+        ICU32(tmpi,-(rip+tmpi->ic_cnt+4));
+        if (buf) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_REL_I32;
+          tmpie->rip=rip+tmpi->ic_cnt-4;
+          tmpie->next=tmpex->ie_lst;
+          tmpex->ie_lst=tmpie;
+        }
+      }
+    } else {//Kernel
+      if (tmpex->type&HTF_UNRESOLVED)
+        throw('Compiler');
+      else {
+        i=tmpex->val-(rip+tmpi->ic_cnt+5);
+        if (!(I32_MIN<=i<=I32_MAX)) {
+          throw('Compiler');
+//          ICU16(tmpi,0xBB48);
+          //        ICU64(tmpi,tmpex->val);
+          //        ICU16(tmpi,0xD3FF);
+        } else {
+          ICU8(tmpi,0xE8);
+          ICU32(tmpi,i);
+        }
+      }
+    }
+  } else {
+    i=tmpex->val-(rip+tmpi->ic_cnt+5);
+    if (!(I32_MIN<=i<=I32_MAX)) {
+      ICU16(tmpi,0xBB48);
+      ICU64(tmpi,tmpex->val);
+      ICU16(tmpi,0xD3FF);
+    } else {
+      ICU8(tmpi,0xE8);
+      ICU32(tmpi,i);
+    }
+  }
+  tmpi->ic_flags&=~ICF_CODE_FINAL;
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFOp(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,U8 *buf2,I64 rip)
+{//for ADD,SUB,DIV,MUL
+  CICArg *arg1,*arg2;
+  Bool dont_push_float,dont_pop_float,alt;
+  I64 rsp_size=0,builtin1=0,builtin2=0,t1,r1,d1,t2,r2,d2;
+
+  if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+    alt=TRUE;
+  } else {
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+    alt=FALSE;
+  }
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+      t2=arg2->type;
+      r2=arg2->reg;
+      d2=arg2->disp;
+    } else {
+      if (arg2->type&MDF_IMM) {
+        if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+          t2=MDF_RIP_DISP32+RT_I64;
+          r2=REG_RIP;
+          d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+        }
+      } else {
+        ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+        rsp_size+=8;
+      }
+    }
+  } else {
+    if (alt) {
+      if (!(arg2->type&MDF_STK)) {
+        if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else {
+          if (arg1->type&MDF_IMM) {
+            if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+              t1=MDF_RIP_DISP32+RT_I64;
+              r1=REG_RIP;
+              d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
+            t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+            rsp_size+=8;
+          }
+        }
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+            if (r1==REG_RSP+REG_RSP<<8)
+              d1+=8;
+          }
+        }
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    } else {
+      if (!(arg1->type&MDF_STK)) {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type;
+          r1=arg1->reg;
+          d1=arg1->disp;
+        } else {
+          if (arg1->type&MDF_IMM) {
+            if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+              t1=MDF_RIP_DISP32+RT_I64;
+              r1=REG_RIP;
+              d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip);
+            t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+            rsp_size+=8;
+            if (r2==REG_RSP+REG_RSP<<8)
+              d2+=8;
+          }
+        }
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    }
+  }
+  if (!dont_pop_float && !rsp_size) {
+    rsp_size=8;
+    ICAddRSP(tmpi,-8);
+  }
+  if (!dont_push_float) {
+    if (builtin2 && !builtin1) {
+      alt=!alt;
+      SwapI64(&t1,&t2);
+      SwapI64(&r1,&r2);
+      SwapI64(&d1,&d2);
+      SwapI64(&builtin1,&builtin2);
+    }
+    if (builtin1)
+      ICU16(tmpi,builtin1);
+    else
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip);
+  }
+  if (alt)
+    switch (op.u8[0]) {
+      case 4: op=SLASH_OP_FSUBR; break;
+      case 6: op=SLASH_OP_FDIVR; break;
+    }
+  if (builtin2) {
+    ICU16(tmpi,builtin2);
+    ICU16(tmpi,op.u16[2]);
+  } else
+    ICSlashOp(tmpi,t2,r2,d2,op,rip);
+  CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+  if (dont_pop_float) {
+    if (rsp_size)
+      ICAddRSP(tmpi,rsp_size);
+  } else {
+    if (rsp_size==8)
+      ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+    else if (rsp_size>8) {
+      ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
+            SLASH_OP_FSTP,rip);
+      ICAddRSP(tmpi,rsp_size-8);
+    }
+    ICPop(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,rip);
+  }
+}
+
+U0 ICFCmp(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
+      if (tmpi->ic_flags&ICF_POP_CMP)
+        ICPopRegs(tmpi,1<<REG_RAX);
+      else
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    } else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    if (tmpi->ic_flags&ICF_POP_CMP)
+      ICPopRegs(tmpi,1<<REG_RDX);
+    else
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  }
+  if (tmpi->ic_flags&ICF_PUSH_CMP)
+    ICPushRegs(tmpi,1<<REG_RAX);
+  ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,FALSE,CN_INST);
+  ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+        MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFModEqu(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    if (dont_push_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+    }
+//TODO: unpushable,unpop?  Not sure
+    ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
+    if (tmpi->arg1_type_pointed_to!=RT_F64)
+      ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+    ICMov(tmpi,tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+          tmpi->arg1.reg,tmpi->arg1.disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else {
+    if (dont_push_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,tmpi->arg1.type,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+    } else {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,tmpi->arg1.type,
+            tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+            MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+    }
+//TODO: unpushable,unpop?  Not sure
+    ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_MOD,FALSE,FALSE,FALSE,CN_INST);
+    if (tmpi->arg1_type_pointed_to!=RT_F64)
+      ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+    ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/BackFB.HC.HTML b/public/Wb/Home/Src/Compiler/BackFB.HC.HTML new file mode 100755 index 0000000..342f976 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/BackFB.HC.HTML @@ -0,0 +1,662 @@ + + + + + + + + + + + +
+U0 ICFOpEqu(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,U8 *buf2,I64 rip)
+{//for ADD,SUB,DIV,MUL
+  CICArg *arg1=&tmpi->arg1,
+        *arg2=&tmpi->arg2;
+  Bool dont_push_float,dont_pop_float,p1_mem;
+  I64 rsp_size=0,builtin2=0,
+        t1,r1,d1,t2,r2,d2;
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_pop_float)
+    throw('Compiler');
+
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    p1_mem=FALSE;
+    if (dont_push_float) {
+      if (tmpi->arg1_type_pointed_to!=RT_F64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              arg1->reg,arg1->disp,rip);
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+        ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+        rsp_size+=8;
+      } else {
+        if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;
+          r1=arg1->reg;
+          d1=arg1->disp;
+          p1_mem=TRUE;
+        } else {
+          ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+                arg1->reg,arg1->disp,rip);
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+        }
+      }
+    } else {
+      if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              arg1->reg,arg1->disp,rip);
+        if (tmpi->arg1_type_pointed_to!=RT_F64)
+          ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      } else {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        if (tmpi->arg1_type_pointed_to>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+          t1=arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to;
+          r1=arg1->reg;
+          d1=arg1->disp;
+          p1_mem=TRUE;
+        } else {
+          ICPush(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+                arg1->reg,arg1->disp,rip);
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+          if (r2==REG_RSP+REG_RSP<<8)
+            d2+=8;
+        }
+      }
+    }
+    if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to==RT_F64)) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    }
+    if (!dont_push_float) {
+      if (builtin2)
+        ICU16(tmpi,builtin2);
+      else
+        ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);
+    }
+    switch (op.u8[0]) {
+      case 4: op=SLASH_OP_FSUBR; break;
+      case 6: op=SLASH_OP_FDIVR; break;
+    }
+    ICSlashOp(tmpi,t1,r1,d1,op,rip);
+    CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
+    if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FSTP,rip);
+      if (rsp_size)
+        ICAddRSP(tmpi,rsp_size);
+    } else {
+      if (rsp_size==8)
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+      else if (rsp_size>8) {
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
+              SLASH_OP_FSTP,rip);
+        ICAddRSP(tmpi,rsp_size-8);
+      }
+      if (tmpi->arg1_type_pointed_to!=RT_F64) {
+        ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+        ICMov(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,arg1->reg,
+              arg1->disp,MDF_REG+RT_I64,REG_RAX,0,rip);
+      } else
+        ICPop(tmpi,arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+              arg1->reg,arg1->disp,rip);
+    }
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            arg1->type&MDG_MASK+tmpi->arg1_type_pointed_to,
+            arg1->reg,arg1->disp,rip);
+  } else {
+    if (tmpi->arg1_type_pointed_to>=RT_I64)
+      p1_mem=TRUE;
+    else
+      p1_mem=FALSE;
+    if (dont_push_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,arg1->reg,arg1->disp,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+              MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,FALSE,rip);
+        ICPush(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+      } else
+        ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+      t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+      rsp_size+=8;
+    } else {
+      if (tmpi->arg1_type_pointed_to!=RT_F64 || arg1->type&MDF_STK) {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+              MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+        if (tmpi->arg1_type_pointed_to!=RT_F64)
+          ICFCvt2(cc,tmpi,REG_RDX,MDF_REG+RT_I64,REG_RDX,0,FALSE,rip);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      } else {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64)))) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,arg1->type,
+              arg1->reg,arg1->disp,rip);
+        ICPush(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,rip);
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+        rsp_size+=8;
+        if (r2==REG_RSP+REG_RSP<<8)
+          d2+=8;
+      }
+    }
+    if (!rsp_size && !(p1_mem && tmpi->arg1_type_pointed_to==RT_F64)) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    }
+    if (!dont_push_float) {
+      if (builtin2)
+        ICU16(tmpi,builtin2);
+      else
+        ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip);
+    }
+
+    switch (op.u8[0]) {
+      case 4: op=SLASH_OP_FSUBR; break;
+      case 6: op=SLASH_OP_FDIVR; break;
+    }
+    ICSlashOp(tmpi,t1,r1,d1,op,rip);
+    CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
+    if (p1_mem && tmpi->arg1_type_pointed_to==RT_F64) {
+      ICSlashOp(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,
+            REG_RCX,0,SLASH_OP_FSTP,rip);
+      if (rsp_size)
+        ICAddRSP(tmpi,rsp_size);
+    } else {
+      if (rsp_size==8)
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,0,SLASH_OP_FSTP,rip);
+      else if (rsp_size>8) {
+        ICSlashOp(tmpi,MDF_SIB+RT_I64,REG_RSP+REG_RSP<<8,rsp_size-8,
+              SLASH_OP_FSTP,rip);
+        ICAddRSP(tmpi,rsp_size-8);
+      }
+      ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip);
+      if (tmpi->arg1_type_pointed_to!=RT_F64)
+        ICFCvt2(cc,tmpi,REG_RAX,MDF_REG+RT_I64,REG_RAX,0,TRUE,rip);
+      ICMov(tmpi,MDF_DISP+tmpi->arg1_type_pointed_to,REG_RCX,0,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    }
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+}
+ 
+U0 ICFCmpAndBranch(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 rip,
+   I64 us,I64 not_us,U8 *buf,I64 rip2)
+{
+  CICArg *arg1,*arg2;
+  Bool dont_push_float,dont_pop_float,alt,short_jmp;
+  I64 i,rsp_size=0,builtin1=0,builtin2=0,t1,r1,d1,t2,r2,d2;
+  CCodeMisc *lb;
+  U8 *buf2;
+
+  if (tmpi->ic_flags&ICF_ALT_TEMPLATE) {
+    arg1=&tmpi->arg2;
+    arg2=&tmpi->arg1;
+    alt=TRUE;
+  } else {
+    arg1=&tmpi->arg1;
+    arg2=&tmpi->arg2;
+    alt=FALSE;
+  }
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    buf2=cc->aotc->rip;
+  else
+    buf2=buf;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (dont_push_float) {
+    if (tmpi->ic_flags&ICF_POP_CMP && alt) {
+      t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      rsp_size+=8;
+    } else {
+      if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+        t2=arg2->type;
+        r2=arg2->reg;
+        d2=arg2->disp;
+      } else {
+        if (arg2->type&MDF_IMM) {
+          if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
+                tmpi->ic_flags&ICF_PUSH_CMP) {
+            t2=MDF_RIP_DISP32+RT_I64;
+            r2=REG_RIP;
+            d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+          }
+        } else {
+          ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
+          t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+          rsp_size+=8;
+        }
+      }
+    }
+  } else {
+    if (alt) {
+      if (!(arg2->type&MDF_STK)) {
+        if (tmpi->ic_flags&ICF_POP_CMP) {
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+        } else {
+          if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+            t1=arg1->type;
+            r1=arg1->reg;
+            d1=arg1->disp;
+          } else {
+            if (arg1->type&MDF_IMM) {
+              if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+                t1=MDF_RIP_DISP32+RT_I64;
+                r1=REG_RIP;
+                d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+              }
+            } else {
+              ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);
+              t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+              rsp_size+=8;
+            }
+          }
+        }
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
+                  tmpi->ic_flags&ICF_PUSH_CMP) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+            if (r1==REG_RSP+REG_RSP<<8)
+              d1+=8;
+          }
+        }
+      } else {
+        if (tmpi->ic_flags&ICF_POP_CMP)
+          ICPopRegs(tmpi,1<<REG_RDX);
+        else
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+                arg1->reg,arg1->disp,rip2);
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip2);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    } else {
+      if (!(arg1->type&MDF_STK)) {
+        if (arg2->type.raw_type>=RT_I64 && arg2->type&MDG_DISP_SIB_RIP) {
+          t2=arg2->type;
+          r2=arg2->reg;
+          d2=arg2->disp;
+        } else {
+          if (arg2->type&MDF_IMM) {
+            if (!(builtin2=ICBuiltInFloatConst(arg2->disp(F64))) ||
+                  tmpi->ic_flags&ICF_PUSH_CMP) {
+              t2=MDF_RIP_DISP32+RT_I64;
+              r2=REG_RIP;
+              d2=COCFloatConstFind(cc,arg2->disp(F64))+buf2;
+            }
+          } else {
+            ICPush(tmpi,arg2->type,arg2->reg,arg2->disp,rip2);
+            t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+            rsp_size+=8;
+          }
+        }
+        if (tmpi->ic_flags&ICF_POP_CMP) {
+          t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+          rsp_size+=8;
+          if (r2==REG_RSP+REG_RSP<<8)
+            d1+=8;
+        } else {
+          if (arg1->type.raw_type>=RT_I64 && arg1->type&MDG_DISP_SIB_RIP) {
+            t1=arg1->type;
+            r1=arg1->reg;
+            d1=arg1->disp;
+          } else {
+            if (arg1->type&MDF_IMM) {
+              if (!(builtin1=ICBuiltInFloatConst(arg1->disp(F64)))) {
+                t1=MDF_RIP_DISP32+RT_I64;
+                r1=REG_RIP;
+                d1=COCFloatConstFind(cc,arg1->disp(F64))+buf2;
+              }
+            } else {
+              ICPush(tmpi,arg1->type,arg1->reg,arg1->disp,rip2);
+              t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=0;
+              rsp_size+=8;
+              if (r2==REG_RSP+REG_RSP<<8)
+                d2+=8;
+            }
+          }
+        }
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,arg2->type,
+              arg2->reg,arg2->disp,rip2);
+        if (tmpi->ic_flags&ICF_POP_CMP)
+          ICPopRegs(tmpi,1<<REG_RDX);
+        else
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,arg1->type,
+                arg1->reg,arg1->disp,rip2);
+        ICU16(tmpi,0x5052);     //PUSH EDX PUSH EAX
+        rsp_size=16;
+        t1=MDF_SIB+RT_I64; r1=REG_RSP+REG_RSP<<8; d1=8;
+        t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+      }
+    }
+  }
+  if (!dont_push_float) {
+    if (builtin1)
+      ICU16(tmpi,builtin1);
+    else
+      ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_FLD,rip2);
+  }
+  if (!alt)
+    us=not_us;
+  if (builtin2)
+    ICU16(tmpi,builtin2);
+  else
+    ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FLD,rip2);
+  if (tmpi->ic_flags&ICF_PUSH_CMP) {
+    t2=MDF_SIB+RT_I64; r2=REG_RSP+REG_RSP<<8; d2=0;
+    if (!rsp_size) {
+      rsp_size=8;
+      ICAddRSP(tmpi,-8);
+    } else if (rsp_size==16)
+      d2=8;
+
+    if (alt) {
+      ICU16(tmpi,0xF1DF);         //FCOMIP
+      ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);
+    } else {
+      ICU16(tmpi,0xF1DB);         //FCOMI
+      ICSlashOp(tmpi,t2,r2,d2,SLASH_OP_FSTP,rip2);
+      ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP
+    }
+  } else {
+    ICU16(tmpi,0xF1DF);   //FCOMIP
+    ICU32(tmpi,0xF7D9C0DD); //FFREE,FINCSTP
+  }
+  CmpNoteFloatOp(cc,tmpi,TRUE,FALSE,CN_INST);
+
+  if (tmpi->ic_flags&ICF_PUSH_CMP) {
+    if (r2.u8[0]==REG_RSP) {
+      while (d2 && rsp_size) {
+        ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
+        rsp_size-=8;
+        d2-=8;
+      }
+    } else {
+      while (rsp_size) {
+        ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
+        rsp_size-=8;
+      }
+      ICPush(tmpi,t2,r2,d2,rip2);
+    }
+  } else {
+    while (rsp_size) {
+      ICU8(tmpi,0x5B); //POP RBX (Dont change flags)
+      rsp_size-=8;
+    }
+  }
+
+  rip+=tmpi->ic_cnt;
+  lb=OptLabelFwd(tmpi->ic_data);
+  short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+  if (!buf && lb->addr!=INVALID_PTR) {
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    if (I8_MIN<=i<=I8_MAX)
+      short_jmp=TRUE;
+  }
+
+  if (short_jmp) {
+    tmpi->ic_flags|=ICF_SHORT_JMP;
+    i=lb->addr-(rip+2);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,i<<8+us.u8[2]);
+  } else {
+    tmpi->ic_flags&=~ICF_SHORT_JMP;
+    i=lb->addr-(rip+6);
+    if (lb->flags&CMF_POP_CMP) {
+      if(tmpi->ic_flags&ICF_PUSH_CMP)
+        i+=4;
+      else
+        i+=8;
+    }
+    ICU16(tmpi,us.u16[0]);
+    ICU32(tmpi,i);
+  }
+}
+
+U0 ICFMul(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  if (tmpi->arg1.type&MDF_IMM && tmpi->arg1.type&RTG_MASK==RT_F64 &&
+        tmpi->arg1.disp(F64)==1.0) {
+    CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+  } else if (tmpi->arg2.type&MDF_IMM &&
+        tmpi->arg2.type&RTG_MASK==RT_F64&& tmpi->arg2.disp(F64)==1.0) {
+    CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FMUL,buf,rip);
+}
+
+U0 ICFDiv(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  if (tmpi->arg2.type&MDF_IMM && tmpi->arg2.type&RTG_MASK==RT_F64 &&
+        tmpi->arg2.disp(F64)==1.0) {
+    CmpNoteFloatOp(cc,tmpi,FALSE,FALSE,CN_INST);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FDIV,buf,rip);
+}
+
+U0 ICFAdd(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (tmpi->arg1.type&MDF_IMM && !tmpi->arg1.disp) {
+    if (dont_push_float) {
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else if (dont_pop_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
+    } else {
+      CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip);
+    }
+  } else if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {
+    if (dont_push_float) {
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else if (dont_pop_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
+    } else {
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+    }
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FADD,buf,rip);
+}
+
+U0 ICFSub(CCmpCtrl *cc,CIntermediateCode *tmpi,U8 *buf,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+  if (tmpi->arg2.type&MDF_IMM && !tmpi->arg2.disp) {
+    CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+    if (dont_push_float) {
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FSTP,FALSE,TRUE,TRUE,CN_INST);
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            MDF_REG+RT_I64,REG_RAX,0,rip);
+    } else if (dont_pop_float) {
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_FLD,FALSE,TRUE,TRUE,CN_INST);
+    } else {
+      ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+            tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+      CmpNoteFloatOp(cc,tmpi,TRUE,TRUE,CN_INST);
+    }
+  } else
+    ICFOp(cc,tmpi,SLASH_OP_FSUB,buf,rip);
+}
+
+U0 ICFPreIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+  if (tmpi->res.type.mode)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+U0 ICFPostIncDec(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  if (tmpi->ic_flags & ICF_BY_VAL) {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type&MDG_MASK+RT_I64,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+  } else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,MDF_DISP+RT_I64,REG_RCX,0,rip);
+    if (tmpi->res.type.mode)
+      ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+    ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+    ICMov(tmpi,MDF_DISP+RT_I64,REG_RCX,0,MDF_REG+RT_I64,REG_RAX,0,rip);
+  }
+  if (tmpi->res.type.mode)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RDX,0,rip);
+}
+
+U0 ICFTemplateFun(CCmpCtrl *cc,CIntermediateCode *tmpi,I64 op,I64 rip)
+{
+  Bool dont_push_float,dont_pop_float;
+
+  CmpSetFloatOpPushPop(cc,tmpi,&dont_push_float,&dont_pop_float);
+  if (!dont_push_float)
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+
+  ICCopyTemplate(cc,tmpi,op,FALSE,TRUE,TRUE,CN_INST);
+  if (tmpi->res.type.mode && !(tmpi->ic_flags & ICF_RES_TO_F64) &&
+        !(tmpi->ic_flags & ICF_RES_TO_INT))
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_REG+RT_I64,REG_RAX,0,rip);
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/BackLib.HC.HTML b/public/Wb/Home/Src/Compiler/BackLib.HC.HTML new file mode 100755 index 0000000..a58f72a --- /dev/null +++ b/public/Wb/Home/Src/Compiler/BackLib.HC.HTML @@ -0,0 +1,739 @@ + + + + + + + + + + + +
+/*Intermediate Code to Machine Code
+
+RAX,RBX,RCX and RDX can be clobbered by
+each intermediate code's output code.
+However, intermediate codes must be
+coupled together based on the arg and
+res type specifications in the
+CICArg.  RAX is the most common reg
+for coupling intermediate codes.
+
+Internal calculations take place on
+64-bit vals, so anything which has
+found it's way into a reg has been
+sign or zero extended to 64-bits.
+*/
+
+U0 ICU8(CIntermediateCode *tmpi,U8 b)
+{
+  tmpi->ic_body[tmpi->ic_cnt++]=b;
+}
+
+U0 ICRex(CIntermediateCode *tmpi,U8 b)
+{
+  if (b)
+    tmpi->ic_body[tmpi->ic_cnt++]=b;
+}
+
+U0 ICOpSizeRex(CIntermediateCode *tmpi,U8 b)
+{
+  tmpi->ic_body[tmpi->ic_cnt++]=OC_OP_SIZE_PREFIX;
+  if (b)
+    tmpi->ic_body[tmpi->ic_cnt++]=b;
+}
+
+U0 ICU16(CIntermediateCode *tmpi,U16 w)
+{
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U16)=w;
+  tmpi->ic_cnt+=2;
+}
+
+U0 ICU24(CIntermediateCode *tmpi,U32 d)
+{//Writes extra harmless overhanging byte.
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;
+  tmpi->ic_cnt+=3;
+}
+
+U0 ICU32(CIntermediateCode *tmpi,U32 d)
+{
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U32)=d;
+  tmpi->ic_cnt+=4;
+}
+
+U0 ICU64(CIntermediateCode *tmpi,U64 q)
+{
+  *(&tmpi->ic_body[tmpi->ic_cnt])(U64)=q;
+  tmpi->ic_cnt+=8;
+}
+
+U0 ICAddRSP(CIntermediateCode *tmpi,I64 i,Bool optimize=TRUE)
+{
+  I64 j,last_start;
+  CIntermediateCode *tmpil1;
+  if (optimize) {
+    tmpil1=tmpi;
+    if (tmpi->ic_last_start<0 && !tmpi->ic_cnt &&
+          (tmpil1=OptLag1(tmpi)) && tmpil1->ic_last_start<0)
+      tmpil1=NULL;
+    if (tmpil1) {
+      j=tmpil1->ic_cnt;
+      if (tmpil1->ic_last_start==j-4 && tmpil1->ic_body[j-3]==0x83 &&
+            tmpil1->ic_body[j-4]==0x48) {
+        if (tmpil1->ic_body[j-2]==0xEC)
+          j=-tmpil1->ic_body[j-1](I8);
+        else if (tmpil1->ic_body[j-2]==0xC4)
+          j=tmpil1->ic_body[j-1](I8);
+        else
+          j=0;
+      } else if (tmpil1->ic_last_start==j-7 && tmpil1->ic_body[j-6]==0x81 &&
+            tmpil1->ic_body[j-7]==0x48) {
+        if (tmpil1->ic_body[j-5]==0xEC)
+          j=-tmpil1->ic_body[j-4](I32);
+        else if (tmpil1->ic_body[j-5]==0xC4)
+          j=tmpil1->ic_body[j-4](I32);
+        else
+          j=0;
+      } else
+        j=0;
+      if (j) {
+        if (tmpi==tmpil1) {
+          tmpi->ic_cnt=tmpi->ic_last_start;
+          i+=j;
+        } else if (!(tmpi->ic_flags&ICF_PREV_DELETED)) {
+          tmpil1->ic_flags|=ICF_DEL_PREV_INS;
+          tmpi->ic_flags=tmpi->ic_flags&~ICF_CODE_FINAL|ICF_PREV_DELETED;
+          i+=j;
+        }
+      }
+    }
+  }
+  last_start=tmpi->ic_cnt;
+  if (i>0) {
+    if (i<=I8_MAX)
+      ICU32(tmpi,0xC48348+i<<24);
+    else if (i<=I32_MAX) {
+      ICU24(tmpi,0xC48148);
+      ICU32(tmpi,i);
+    } else
+      throw('Compiler');
+  } else if (i<0) {
+    i=-i;
+    if (i<=I8_MAX)
+      ICU32(tmpi,0xEC8348+i<<24);
+    else if (i<=I32_MAX) {
+      ICU24(tmpi,0xEC8148);
+      ICU32(tmpi,i);
+    } else
+      throw('Compiler');
+  }
+  if (optimize && tmpi->ic_cnt>last_start)
+    tmpi->ic_last_start=last_start;
+}
+
+extern U0 ICMov(CIntermediateCode *tmpi,
+        CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip);
+
+#define MODR_REG                        0
+#define MODR_INDIRECT_REG               1
+#define MODR_D8_INDIRECT_REG            2
+#define MODR_D32_INDIRECT_REG           3
+#define MODR_SIB_INDIRECT_REG           4
+#define MODR_SIB_D8_INDIRECT_REG        5
+#define MODR_SIB_D32_INDIRECT_REG       6
+#define MODR_RIP_REL                    7
+#define MODR_RIP_REL_IMM_U32            8
+
+I64 ICModr1(I64 r,CICType t2,I64 r2,I64 d2)
+{//res.u8[0] is type
+//res.u8[1] is REX
+  //res.u8[2] is ModR
+  //res.u8[3] is SIB
+  I64 res=0;
+  if (t2.raw_type<RT_I64)
+    res.u8[1]=0x40;
+  else
+    res.u8[1]=0x48;
+  if (r>7) {
+    res.u8[1]+=4;
+    r&=7;
+  }
+  switch (Bsr(t2)) {
+    case MDf_REG:
+      if (r2>7) {
+        res.u8[1]++;
+        r2&=7;
+      }
+      res.u8[2]=0xC0+r<<3+r2;
+      res.u8[0]=MODR_REG;
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4 && r2<4))
+        res.u8[1]=0;
+      break;
+    case MDf_DISP:
+      if (r2>7) {
+        res.u8[1]++;
+        r2&=7;
+      }
+      if (!d2 && r2!=REG_RBP) {
+        res.u8[2]=r<<3+r2;
+        res.u8[0]=MODR_INDIRECT_REG;
+      } else if (I8_MIN<=d2<=I8_MAX) {
+        res.u8[2]=0x40+r<<3+r2;
+        res.u8[0]=MODR_D8_INDIRECT_REG;
+      } else {
+        res.u8[2]=0x80+r<<3+r2;
+        res.u8[0]=MODR_D32_INDIRECT_REG;
+      }
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
+        res.u8[1]=0;
+      break;
+    case MDf_SIB:
+      if (7<r2.u8[0]<REG_NONE)
+        res.u8[1]++;
+      if (r2.u8[1]&15>7)
+        res.u8[1]+=2;
+      if (r2.u8[0]==REG_NONE) {
+        res.u8[3]=5+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
+        res.u8[2]=4+r<<3;
+        res.u8[0]=MODR_SIB_D32_INDIRECT_REG;
+      } else {
+        res.u8[3]=r2.u8[0]&7+(r2.u8[1]&7)<<3+r2.u8[1]&0xC0;
+        if (!d2 && r2.u8[0]&7!=REG_RBP) {
+          res.u8[2]=4+r<<3;
+          res.u8[0]=MODR_SIB_INDIRECT_REG;
+        } else if (I8_MIN<=d2<=I8_MAX) {
+          res.u8[2]=0x44+r<<3;
+          res.u8[0]=MODR_SIB_D8_INDIRECT_REG;
+        } else {
+          res.u8[2]=0x84+r<<3;
+          res.u8[0]=MODR_SIB_D32_INDIRECT_REG;
+        }
+      }
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
+        res.u8[1]=0;
+      break;
+    case MDf_RIP_DISP32:
+      res.u8[2]=0x05+r<<3;
+      res.u8[0]=MODR_RIP_REL;
+      if (res.u8[1]==0x40 && (t2.raw_type>=RT_I16 || r<4))
+        res.u8[1]=0;
+      break;
+  }
+  return res;
+}
+
+U0 ICModr2(CIntermediateCode *tmpi,I64 i,CICType t=0,I64 d,I64 rip=0)
+{
+  switch [i.u8[0]] {
+    case MODR_REG:
+      break;
+    case MODR_INDIRECT_REG:
+      break;
+    case MODR_D8_INDIRECT_REG:
+      ICU8(tmpi,d);
+      break;
+    case MODR_D32_INDIRECT_REG:
+      ICU32(tmpi,d);
+      break;
+    case MODR_SIB_INDIRECT_REG:
+      ICU8(tmpi,i.u8[3]);
+      break;
+    case MODR_SIB_D8_INDIRECT_REG:
+      ICU8(tmpi,i.u8[3]);
+      ICU8(tmpi,d);
+      break;
+    case MODR_SIB_D32_INDIRECT_REG:
+      ICU8(tmpi,i.u8[3]);
+      ICU32(tmpi,d);
+      break;
+    case MODR_RIP_REL_IMM_U32:
+      switch (t.raw_type) {
+        case RT_I8:
+        case RT_U8:
+          d--;
+          break;
+        case RT_I16:
+        case RT_U16:
+          d-=2;
+          break;
+        default:
+          d-=4;
+      }
+    case MODR_RIP_REL:
+      ICU32(tmpi,d-(rip+4+tmpi->ic_cnt));
+      tmpi->ic_flags&=~ICF_CODE_FINAL;
+      break;
+  }
+}
+
+#define SLASH_OP_INC            0x0003000000FFFE00
+#define SLASH_OP_DEC            0x052B000000FFFE01
+#define SLASH_OP_NOT            0x0000000000F7F602
+#define SLASH_OP_NEG            0x0000000000F7F603
+#define SLASH_OP_IMM_U8         0x0000000000838000
+#define SLASH_OP_IMM_U32        0x0000000000818300
+#define SLASH_OP_MUL            0x0000000000F7F604
+#define SLASH_OP_IMUL           0x0000000000F7F605
+#define SLASH_OP_DIV            0x0000000000F7F606
+#define SLASH_OP_MOV            0x0000000000898800
+#define SLASH_OP_MOV_IMM        0x0000000000C7C600
+#define SLASH_OP_PUSH           0x0000000000FFFF06
+#define SLASH_OP_POP            0x00000000008F8F00
+#define SLASH_OP_FADD           0x0000C1DE01DCDC00
+#define SLASH_OP_FSUB           0x0000E9DE01DCDC04
+#define SLASH_OP_FSUBR          0x0000E1DE01DCDC05
+#define SLASH_OP_FMUL           0x0000C9DE01DCDC01
+#define SLASH_OP_FDIV           0x0000F9DE01DCDC06
+#define SLASH_OP_FDIVR          0x0000F1DE01DCDC07
+#define SLASH_OP_FLD            0x0000000001DDDD00
+#define SLASH_OP_FSTP           0x0000000001DDDD03
+#define SLASH_OP_FISTTP         0x0000000001DDDD01
+#define SLASH_OP_FILD           0x0000000001DFDF05
+
+U0 ICSlashOp(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 op,I64 rip)
+{
+  I64 i;
+  if (t1&MDF_REG && !op.u8[3])
+    t1=t1&(MDG_MASK|RTF_UNSIGNED)+RT_I64; //Set to 64 bit,preserving unsigned
+  i=ICModr1(op.u8[0],t1,r1,d1);
+  if (tmpi->ic_flags&ICF_LOCK && !(t1&MDF_REG) &&
+        op&~7!=SLASH_OP_MOV && op!=SLASH_OP_MOV_IMM)
+    ICU8(tmpi,OC_LOCK_PREFIX);
+  switch (t1.raw_type) {
+    case RT_I8:
+    case RT_U8:
+      ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+op.u8[1]);
+      break;
+    case RT_I16:
+    case RT_U16:
+      ICOpSizeRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+op.u8[2]);
+      break;
+    default:
+      if (i.u8[1]!=0x48 || !op.u8[3])
+        ICRex(tmpi,i.u8[1]);
+      ICU16(tmpi,i.u8[2]<<8+op.u8[2]);
+  }
+  if (i.u8[0]==MODR_RIP_REL&& (op==SLASH_OP_MOV_IMM || op&~7==SLASH_OP_IMM_U32))
+    i.u8[0]=MODR_RIP_REL_IMM_U32;
+  ICModr2(tmpi,i,t1,d1,rip);
+}
+
+U0 ICPush(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)
+{
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      if (r1>7)
+        ICU16(tmpi,0x5049+(r1&7)<<8);
+      else
+        ICU8(tmpi,0x50+r1);
+      return;
+    case MDf_IMM:
+      if (I8_MIN<=d1<=I8_MAX)
+        ICU16(tmpi,0x6A+d1<<8);
+      else if (I32_MIN<=d1<=I32_MAX) {
+        ICU8(tmpi,0x68);
+        ICU32(tmpi,d1);
+      } else {
+        ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);
+        ICU8(tmpi,0x50+REG_RBX);
+      }
+      return;
+    case MDf_STK:
+      return;
+    case MDf_DISP:
+    case MDf_SIB:
+    case MDf_RIP_DISP32:
+      switch (t1.raw_type) {
+        case RT_I64:
+        case RT_U64:
+        case RT_F64:
+          ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_PUSH,rip);
+          return;
+      }
+      break;
+  }
+  ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t1,r1,d1,rip);
+  ICU16(tmpi,0x5048+REG_RBX<<8);
+}
+
+U0 ICPushRegs(CIntermediateCode *tmpi,I64 mask)
+{
+  I64 i;
+  for (i=0;i<REG_REGS_NUM;i++) {
+    if (Bt(&mask,i)) {
+      if (i>7)
+        ICU16(tmpi,0x5049+(i&7)<<8);
+      else
+        ICU8(tmpi,0x50+i);
+    }
+  }
+}
+
+U0 ICPop(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,I64 rip)
+{
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      if (r1>7)
+        ICU16(tmpi,0x5849+(r1&7)<<8);
+      else
+        ICU8(tmpi,0x58+r1);
+      break;
+    case MDf_DISP:
+    case MDf_RIP_DISP32:
+    case MDf_SIB:
+      if (t1.raw_type<RT_I64) {
+        ICU8(tmpi,0x58+REG_RBX);
+        ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
+      } else
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_POP,rip);
+      break;
+    case MDf_STK:
+    case MDf_IMM:
+      ICU8(tmpi,0x58+REG_RBX);
+      ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
+      break;
+    default:
+      ICAddRSP(tmpi,8);
+  }
+}
+
+U0 ICPopRegs(CIntermediateCode *tmpi,I64 mask)
+{
+  I64 i;
+  for (i=REG_REGS_NUM-1;i>=0;i--) {
+    if (Bt(&mask,i)) {
+      if (i>7)
+        ICU16(tmpi,0x5849+(i&7)<<8);
+      else
+        ICU8(tmpi,0x58+i);
+    }
+  }
+}
+
+U0 ICZero(CIntermediateCode *tmpi,I64 r)
+{
+  if (r>7) {
+    r&=7;
+    ICU24(tmpi,0xC0334D+r<<16+r<<19);
+  } else
+    ICU16(tmpi,0xC033+r<<8+r<<11);
+}
+
+U0 ICTest(CIntermediateCode *tmpi,I64 r)
+{
+  I64 i=0xC08548; //TEST R,R
+  if (r>7) {
+    i+=5;
+    r&=7;
+  }
+  ICU24(tmpi,i+r<<16+r<<19);
+}
+
+I64 ICBuiltInFloatConst(F64 d)
+{//Returns 2-byte opcode for FLD const or zero
+  if (!d)
+    return 0xEED9;
+  else if (d==1.0)
+    return 0xE8D9;
+  else if (GetOption(OPTf_NO_BUILTIN_CONST))
+    return 0;
+  else if (d==pi)
+    return 0xEBD9;
+  else if (d==log2_10)
+    return 0xE9D9;
+  else if (d==log2_e)
+    return 0xEAD9;
+  else if (d==log10_2)
+    return 0xECD9;
+  else if (d==loge_2)
+    return 0xEDD9;
+  else
+    return 0;
+}
+
+U0 ICMov(CIntermediateCode *tmpi,
+        CICType t1,I64 r1,I64 d1,CICType t2,I64 r2,I64 d2,I64 rip)
+{
+  I64 i,cnt1,cnt2,b1_rex,b2_rex,b1,b2,b1_modr,b2_modr,
+        b1_r1,b1_r2,b2_r1,b2_r2,last_start=tmpi->ic_cnt;
+  CIntermediateCode *tmpil1;
+  Bool old_lock=Btr(&tmpi->ic_flags,ICf_LOCK);
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      if (t2&MDF_IMM) {
+        if (!d2)
+          ICZero(tmpi,r1);
+        else if (0<=d2<=U8_MAX) {
+          ICZero(tmpi,r1);
+          if (r1>7)
+            ICU24(tmpi,d2<<16+(0xB0+r1&7)<<8+0x41);
+          else if (r1>3)
+            ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);
+          else
+            ICU16(tmpi,d2<<8+0xB0+r1);
+        } else if (I8_MIN<=d2<0) {
+          if (r1>7) {
+            r1&=7;
+            ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x41);
+            ICU32(tmpi,0xC0BE0F4D+r1<<24+r1<<27);
+          } else {
+            if (r1>3)
+              ICU24(tmpi,d2<<16+(0xB0+r1)<<8+0x40);
+            else
+              ICU16(tmpi,d2<<8+0xB0+r1);
+            ICU32(tmpi,0xC0BE0F48+r1<<24+r1<<27);
+          }
+        } else if (0<=d2<=U32_MAX) {
+          if (r1>7) {
+            r1&=7;
+            ICU16(tmpi,(0xB8+r1)<<8+0x41);
+            ICU32(tmpi,d2);
+          } else {
+            ICU8(tmpi,0xB8+r1);
+            ICU32(tmpi,d2);
+          }
+        } else if (I32_MIN<=d2<0) {
+          if (r1>7) {
+            r1&=7;
+            ICU16(tmpi,(0xB8+r1)<<8+0x41);
+            ICU32(tmpi,d2);
+            ICU24(tmpi,0xC0634D+r1<<16+r1<<19);
+          } else {
+            ICU8(tmpi,0xB8+r1);
+            ICU32(tmpi,d2);
+            ICU24(tmpi,0xC06348+r1<<16+r1<<19);
+          }
+        } else {
+          i=0xB848;
+          if (r1>7) {
+            i++;
+            r1&=7;
+          }
+          ICU16(tmpi,i+r1<<8);
+          ICU64(tmpi,d2);
+        }
+      } else if (t2&MDF_STK)
+        ICPop(tmpi,t1,r1,d1,rip);
+      else {
+        if (r1==r2 && t2&MDF_REG)
+          goto move_done;
+        if (t2&MDF_REG)
+          t2=MDF_REG+RT_I64;
+        i=ICModr1(r1,t2,r2,d2);
+        if (t2.raw_type!=RT_U32)
+          i|=0x4800;
+        ICRex(tmpi,i.u8[1]);
+        switch (t2.raw_type) {
+          case RT_I8:
+            ICU24(tmpi,i.u8[2]<<16+0xBE0F);
+            break;
+          case RT_I16:
+            ICU24(tmpi,i.u8[2]<<16+0xBF0F);
+            break;
+          case RT_I32:
+            ICU16(tmpi,i.u8[2]<<8+0x63);
+            break;
+
+          case RT_U8:
+            ICU24(tmpi,i.u8[2]<<16+0xB60F);
+            break;
+          case RT_U16:
+            ICU24(tmpi,i.u8[2]<<16+0xB70F);
+            break;
+          default:
+            ICU16(tmpi,i.u8[2]<<8+0x8B);
+        }
+        ICModr2(tmpi,i,,d2,rip);
+      }
+      break;
+    case MDf_STK:
+      if (tmpi->ic_flags&ICF_PUSH_CMP)
+        ICPopRegs(tmpi,1<<REG_RBX);
+      if (t1.raw_type<t2.raw_type)
+        ICPush(tmpi,t2&MDG_MASK+t1.raw_type,r2,d2,rip);
+      else
+        ICPush(tmpi,t2,r2,d2,rip);
+      if (tmpi->ic_flags&ICF_PUSH_CMP)
+        ICPushRegs(tmpi,1<<REG_RBX);
+      break;
+    case MDf_DISP:
+    case MDf_RIP_DISP32:
+    case MDf_SIB:
+      if (t2&MDF_IMM && (t1.raw_type<RT_I64 || (I32_MIN<=d2<=I32_MAX))) {
+        ICSlashOp(tmpi,t1,r1,d1,SLASH_OP_MOV_IMM,rip);
+        switch (t1.raw_type) {
+          case RT_I8:
+          case RT_U8:
+            ICU8(tmpi,d2);
+            break;
+          case RT_I16:
+          case RT_U16:
+            ICU16(tmpi,d2);
+            break;
+          default:
+            ICU32(tmpi,d2);
+        }
+      } else {
+        if (t2&MDF_REG)
+          ICSlashOp(tmpi,t1,r1,d1,r2+SLASH_OP_MOV,rip);
+        else {
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RBX,0,t2,r2,d2,rip);
+          ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RBX,0,rip);
+        }
+      }
+      break;
+  }
+move_done:
+  if (!((t1|t2)&(MDF_STK|MDF_RIP_DISP32))) {
+    tmpil1=tmpi;
+    if (tmpi->ic_last_start<0 && (tmpil1=OptLag1(tmpi)) &&
+          tmpil1->ic_last_start<0)
+      tmpil1=NULL;
+    if (tmpil1) {
+      if (tmpil1==tmpi)
+        cnt1=last_start-tmpil1->ic_last_start;
+      else {
+        if (!(tmpil1->ic_flags&ICF_CODE_FINAL))
+          tmpi->ic_flags&=~ICF_CODE_FINAL;
+        if (last_start)
+          cnt1=0;
+        else
+          cnt1=tmpil1->ic_cnt-tmpil1->ic_last_start;
+      }
+      cnt2=tmpi->ic_cnt-last_start;
+      if (cnt1 && cnt1==cnt2) {
+        b1_rex=tmpil1->ic_body[tmpil1->ic_last_start];
+        b2_rex=tmpi->ic_body[last_start];
+        if (b1_rex&0x48==0x48 && b2_rex&0x48==0x48) {
+          for (i=1;i<cnt1;i++)
+            if ((b1=tmpil1->ic_body[tmpil1->ic_last_start+i])==
+                  (b2=tmpi->ic_body[last_start+i])) {
+              if (i==1 && (b2==0x89 || b2==0x8B)) {
+                b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];
+                b1_r1=b1_modr&7 +Bt(&b1_rex,0)<<3;
+                b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;
+                b2_modr=tmpi->ic_body[last_start+2];
+                b2_r1=b2_modr&7   +Bt(&b2_rex,0)<<3;
+                b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;
+                if (cnt1==3 && b2_modr&0xC0==0xC0) {
+                  if (b2_r1==b2_r2)
+                    goto move_redundant;
+                  if (b1_modr&0xC0==0xC0) {
+                    if (b1_r1==b2_r2 && b2_r1==b1_r2)
+                      goto move_redundant;
+                  }
+                } else if (b1_rex!=b2_rex || b1_r1==b1_r2 || (t1|t2)&MDF_SIB)
+                  break;
+              } else if (b1_rex!=b2_rex)
+                break;
+            } else if (i!=1)
+              break;
+            else if (b2!=0x89 && b2!=0x8B)
+              break;
+            else {
+              b1_modr=tmpil1->ic_body[tmpil1->ic_last_start+2];
+              b1_r1=b1_modr&7   +Bt(&b1_rex,0)<<3;
+              b1_r2=b1_modr>>3&7+Bt(&b1_rex,2)<<3;
+              b2_modr=tmpi->ic_body[last_start+2];
+              b2_r1=b2_modr&7   +Bt(&b2_rex,0)<<3;
+              b2_r2=b2_modr>>3&7+Bt(&b2_rex,2)<<3;
+              if (cnt1==3 && b2_modr&0xC0==0xC0) {
+                if (b2_r1==b2_r2)
+                  goto move_redundant;
+                if (b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89) {
+                  if (b1_modr&0xC0==0xC0) {
+                    if (b1_r1==b2_r1 && b1_r2==b2_r2 ||
+                          b1_r1==b2_r2 && b2_r1==b1_r2)
+                      goto move_redundant;
+                  }
+                  if (b1_rex!=b2_rex)
+                    break;
+                } else
+                  break;
+              } else if (b1_r1==b1_r2 || (t1|t2)&MDF_SIB || b1_rex!=b2_rex ||
+                    !(b1==0x89 && b2==0x8B || b1==0x8B && b2==0x89))
+                break;
+            }
+          if (i==cnt1) {
+move_redundant:
+            tmpi->ic_cnt=last_start;
+          }
+        }
+      }
+    }
+  }
+  if (tmpi->ic_cnt>last_start>tmpi->ic_last_start)
+    tmpi->ic_last_start=last_start;
+  BEqu(&tmpi->ic_flags,ICf_LOCK,old_lock);
+}
+
+U0 ICLea(CIntermediateCode *tmpi,CICType t1,I64 r1,I64 d1,
+        CICType t2,I64 r2,I64 d2,CCmpCtrl *cc,U8 *buf,I64 rip)
+{
+  I64 i;
+  CAOTAbsAddr *tmpa;
+  switch (Bsr(t1)) {
+    case MDf_REG:
+      i=ICModr1(r1,t2,r2,d2);
+      i.u8[1]|=0x48;
+      ICU24(tmpi,i.u8[2]<<16+0x8D00+i.u8[1]);
+      ICModr2(tmpi,i,,d2,rip);
+      break;
+    case MDf_STK:
+      if (t2&MDF_RIP_DISP32) {
+        ICU8(tmpi,0x68);
+        ICU32(tmpi,d2);
+        if (cc->flags&CCF_AOT_COMPILE && buf && !(cc->flags&CCF_NO_ABSS)) {
+          tmpa=CAlloc(sizeof(CAOTAbsAddr));
+          tmpa->next=cc->aotc->abss;
+          tmpa->type=AAT_ADD_U32;
+          cc->aotc->abss=tmpa;
+          tmpa->rip=rip+tmpi->ic_cnt-4;
+        }
+        tmpi->ic_flags&=~ICF_CODE_FINAL;
+        break;
+      } // Fall thru
+    default:
+      ICLea(tmpi,MDF_REG+RT_I64,REG_RCX,0,t2,r2,d2,cc,buf,rip);
+      ICMov(tmpi,t1,r1,d1,MDF_REG+RT_I64,REG_RCX,0,rip);
+  }
+}
+
+U0 ICDeref(CIntermediateCode *tmpi,I64 rip)
+{
+  CICType t;
+  t=tmpi->res.type.raw_type;
+  if (t>tmpi->arg1_type_pointed_to)
+    t=tmpi->arg1_type_pointed_to;
+  if (tmpi->arg1.type&MDF_REG)
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+  else {
+    ICMov(tmpi,MDF_REG+RT_I64,REG_RCX,0,
+          tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip);
+    ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+          MDF_DISP+t,REG_RCX,0,rip);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/CExcept.HC.HTML b/public/Wb/Home/Src/Compiler/CExcept.HC.HTML new file mode 100755 index 0000000..0c1c54a --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CExcept.HC.HTML @@ -0,0 +1,284 @@ + + + + + + + + + + + +
+U0 LexPutToken(CCmpCtrl *cc)
+{//Print cur token to StdOut. (Crude)
+  '"';
+  if (cc->token==TK_IDENT || cc->token==TK_STR)
+    "%s",cc->cur_str;
+  else if (cc->token==TK_I64)
+    "INT:%X",cc->cur_i64;
+  else if (cc->token==TK_CHAR_CONST)
+    "U8:%X",cc->cur_i64;
+  else if (cc->token==TK_F64)
+    "FLOAT:%e",cc->cur_f64;
+  else if (cc->token=='\n')
+    "<NEW_LINE>";
+  else if (Bt(char_bmp_displayable,cc->token))
+    '' cc->token;
+  else {
+    "T:%X",cc->token;
+  }
+  "\" ";
+}
+
+U8 *LexPutLine(CCmpCtrl *cc,U8 *start)
+{//Print cur pos to end of line to StdOut.
+  I64 ch;
+  U8 *ptr;
+  if (!start) return NULL;
+  if (cc->lex_include_stk->flags&LFSF_DOC)
+    return DocPutLine(cc->lex_include_stk->doc,start);
+  else {
+    ptr=start;
+    while (ch=*ptr++) {
+      if (ch=='\n') {
+        if (*ptr=='\r')
+          ptr++;
+        break;
+      } else if (ch=='\r') {
+        if (*ptr=='\n')
+          ptr++;
+        break;
+      }
+      '' ch;
+    }
+    if (!ch) ptr--;
+    '\n';
+    return ptr;
+  }
+  return NULL;
+}
+
+U0 LexPutPos(CCmpCtrl *cc)
+{//Print token, line link and, then, LexPutLine().
+  LexPutToken(cc);
+  FixSet(cc->lex_include_stk->full_name,cc->lex_include_stk->line_num);
+  if (IsRaw)
+    "%s,%d ",cc->lex_include_stk->full_name,cc->lex_include_stk->line_num;
+  else {
+    PutFileLink(cc->lex_include_stk->full_name,,cc->lex_include_stk->line_num);
+    AdamErr("%s,%d\n",
+          cc->lex_include_stk->full_name,cc->lex_include_stk->line_num);
+    '' CH_SPACE;
+  }
+  LexPutLine(cc,cc->lex_include_stk->line_start);
+}
+
+U0 LexWarn(CCmpCtrl *cc,U8 *str=NULL)
+{//Print warn msg, then, LexPutPos().
+  if (str) PrintWarn(str);
+  if (cc->htc.fun) {
+    "in fun '%s'.\n",cc->htc.fun->str;
+    if (IsRaw)
+      "%s\n",cc->htc.fun->src_link;
+    else {
+      "$LK,\"%s\"$\n",cc->htc.fun->src_link;
+      AdamErr("%s\n",cc->htc.fun->src_link);
+    }
+  } else
+    LexPutPos(cc);
+  cc->warning_cnt++;
+}
+
+U0 LexExcept(CCmpCtrl *cc,U8 *str=NULL)
+{//Print err msg, LexPutPos() and throw exception.
+  if (!Bt(&sys_run_level,RLf_ADAM_SERVER)) {
+    Raw(ON);
+    "Note: Still in boot phase.\n";
+  }
+  if (str) PrintErr(str);
+  if (!IsRaw)
+    AdamErr("Task:%08X %s\n",Fs,str);
+  LexPutPos(cc);
+  cc->error_cnt++;
+  FlushMsgs;
+  if (!Bt(&sys_run_level,RLf_ADAM_SERVER))
+    Dbg("Type \"Fix;\"");
+  throw('Compiler');
+}
+
+U0 UndefinedExtern()
+{
+  PrintErr("Undefined Extern\nat %P\n",Caller);
+  throw('UndefExt');
+}
+
+U0 UnusedExternWarning(CCmpCtrl *cc,CHashClass *tmpc)
+{
+  PrintWarn("Unused extern '%s'\n",tmpc->str);
+  cc->warning_cnt++;
+}
+
+U0 ParenWarning(CCmpCtrl *cc)
+{
+  if (Bt(&cc->opts,OPTf_WARN_PAREN) &&
+        !(cc->lex_include_stk->flags&LFSF_DEFINE))
+    LexWarn(cc,"Unnecessary parenthesis ");
+}
+
+U0 ICClassPut(CHashClass *c)
+{
+  I64 i;
+  if (!c) return;
+  if (c->ptr_stars_cnt>4) {
+    PrintErr("put_class ptrcnt=%d\n",c->ptr_stars_cnt);
+    while (TRUE)
+//TODO:
+      Yield;
+  }
+  for (i=0;i<c->ptr_stars_cnt;i++)
+    '*';
+  c-=c->ptr_stars_cnt;
+  if (c->str)
+    "%s",c->str;
+  else {
+    PrintErr("put_class str=NULL\n");
+    while (TRUE)
+//TODO:
+      Yield;
+  }
+  '' CH_SPACE;
+}
+
+U0 ICArgPut(CICArg *a,I64 type_pointed_to)
+{
+  if (type_pointed_to)
+    "[%Z](%Z) %Z ",a->type.raw_type,"ST_RAW_TYPES",
+          type_pointed_to,"ST_RAW_TYPES",Bsr(a->type>>8)+1,"ST_TY_TYPES";
+  else
+    "%Z %Z ",a->type.raw_type,"ST_RAW_TYPES",
+          Bsr(a->type>>8)+1,"ST_TY_TYPES";
+  switch (Bsr(a->type)) {
+    case MDf_STK:
+      "STK";
+      break;
+    case MDf_IMM:
+      "#%X",a->disp;
+      break;
+    case MDf_REG:
+      "%Z",a->reg,"ST_U64_REGS";
+      break;
+    case MDf_DISP:
+      "%X[%Z]",a->disp,a->reg,"ST_U64_REGS";
+      break;
+    case MDf_RIP_DISP32:
+      "[%X]",a->disp;
+      break;
+    case MDf_SIB:
+      if (a->disp)
+        "%X",a->disp;
+      if (a->reg==REG_RIP)
+        '[';
+      else
+        "[%Z+",a->reg&15,"ST_U64_REGS";
+      "%Z",a->reg>>8&15,"ST_U64_REGS";
+      switch (a->reg>>14) {
+        case 0: "]";   break;
+        case 1: "*2]"; break;
+        case 2: "*4]"; break;
+        case 3: "*8]"; break;
+      }
+      break;
+  }
+  '' CH_SPACE;
+}
+
+U0 ICPut(CCmpCtrl *cc,CIntermediateCode *tmpi)
+{
+  I64 opcode=tmpi->ic_code,i;
+  if (opcode>=IC_END_EXP && opcode!=IC_NOP2) {
+    "%15ts %016X ",intermediate_code_table[opcode].name,tmpi->ic_data;
+    if (cc->pass) {
+      if (tmpi->res.type.mode) {
+        "$PURPLE$RES:$FG$";
+        ICArgPut(&tmpi->res,0);
+      }
+      if (tmpi->arg1.type.mode) {
+        "$PURPLE$ARG1:$FG$";
+        if (intermediate_code_table[tmpi->ic_code].type==IST_DEREF ||
+              intermediate_code_table[tmpi->ic_code].type==IST_ASSIGN)
+          ICArgPut(&tmpi->arg1,tmpi->arg1_type_pointed_to);
+        else
+          ICArgPut(&tmpi->arg1,0);
+      }
+      if (tmpi->arg2.type.mode) {
+        "$PURPLE$ARG2:$FG$";
+        ICArgPut(&tmpi->arg2,0);
+      }
+      "$PURPLE$:$FG$";
+    }
+    ICClassPut(tmpi->ic_class);
+    if (tmpi->ic_flags & ICF_LOCK)
+      "$BROWN$lock$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG2_TO_F64)
+      "$LTBLUE$a2d$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG2_TO_INT)
+      "$GREEN$a2i$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG1_TO_F64)
+      "$LTBLUE$a1d$FG$ ";
+    if (tmpi->ic_flags & ICF_ARG1_TO_INT)
+      "$GREEN$a1i$FG$ ";
+    if (tmpi->ic_flags & ICF_RES_TO_F64)
+      "$LTBLUE$rd$FG$ ";
+    if (tmpi->ic_flags & ICF_RES_TO_INT)
+      "$GREEN$ri$FG$ ";
+    if (tmpi->ic_flags & ICF_USE_F64)
+      "[F64] ";
+    if (tmpi->ic_flags & ICF_USE_UNSIGNED)
+      "[unsigned] ";
+    if (tmpi->ic_flags & ICF_USE_INT)
+      "[int] ";
+    if (tmpi->ic_flags & ICF_RES_NOT_USED)
+      "NO_RES ";
+    if (tmpi->ic_flags & ICF_BY_VAL)
+      "BY_VAL ";
+    if (tmpi->ic_flags & ICF_PUSH_RES)
+      "PUSH ";
+    if (tmpi->ic_flags & ICF_PUSH_CMP)
+      "PUSH_CMP ";
+    if (tmpi->ic_flags & ICF_POP_CMP)
+      "POP_CMP ";
+    if (tmpi->ic_flags & ICF_DEL_PREV_INS)
+      "DEL_PREV ";
+    if (tmpi->ic_flags & ICF_PREV_DELETED)
+      "PREV_DEL ";
+    for (i=0;i<3;i++) {
+      if (Bt(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0+i))
+        "DONT_PUSH#%d ",i;
+      if (Bt(&tmpi->ic_flags,ICf_DONT_POP_FLOAT0+i))
+        "DONT_POP#%d ",i;
+    }
+    if (tmpi->ic_flags & ICF_ALT_TEMPLATE)
+      "ALT_TMP ";
+    '\n';
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/CExts.HC.HTML b/public/Wb/Home/Src/Compiler/CExts.HC.HTML new file mode 100755 index 0000000..a46fe69 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CExts.HC.HTML @@ -0,0 +1,77 @@ + + + + + + + + + + + +
+import U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e);
+import U0 DocBinsValidate(CDoc *doc);
+import U0 DocDel(CDoc *doc);
+import U0 DocLoad(CDoc *doc,U8 *src2,I64 size);
+import CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL);
+import CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...);
+import CDocEntry *DocPutLine(CDoc *doc,CDocEntry *doc_e);
+import I64 DocSize(CDoc *doc);
+import Bool DocWrite(CDoc *doc,Bool prompt=FALSE);
+extern U8 *CmdLinePmt();
+extern I64 HashEntrySize2(CHashSrcSym *tmph);
+extern Bool IsLexExpression2Bin(CCmpCtrl *cc,U8 **_machine_code);
+extern I64 Lex(CCmpCtrl *cc);
+extern I64 LexExpression(CCmpCtrl *cc);
+extern I64 LexGetChar(CCmpCtrl *cc);
+extern CCodeMisc *OptLabelFwd(CCodeMisc *lb);
+extern CIntermediateCode *OptPass012(CCmpCtrl *cc);
+extern U0 OptPass3(CCmpCtrl *cc,COptReg *reg_offsets);
+extern U0 OptPass4(CCmpCtrl *cc,COptReg *reg_offsets,I64 *_type);
+extern U0 OptPass5(CCmpCtrl *cc);
+extern U0 OptPass6(CCmpCtrl *cc);
+extern I64 OptPass789A(
+        CCmpCtrl *cc,COptReg *reg_offsets,U8 *buf,CDbgInfo **_dbg);
+extern CHashClass *PrsClass(
+        CCmpCtrl *cc,I64 keyword,I64 fsp_flags,Bool is_extern);
+extern CHashFun *PrsFunJoin(
+        CCmpCtrl *cc,CHashClass *tmp_return,U8 *name,I64 fsp_flags);
+extern I64 PrsKeyWord(CCmpCtrl *cc);
+extern Bool PrsStmt(CCmpCtrl *cc,I64 try_cnt=0,
+        CCodeMisc *lb_break=NULL,I64 cmp_flags=CMPF_PRS_SEMICOLON);
+extern U0 PrsStreamBlk(CCmpCtrl *cc);
+extern CHashClass *PrsType(CCmpCtrl *cc,CHashClass **_tmpc1,
+        I64 *_mode,CMemberLst *tmpm,U8 **_ident,CHashFun **_fun_ptr,
+        CHashExport **_tmpex,CArrayDim *tmpad,I64 fsp_flags);
+extern I64 PrsUnaryModifier(CCmpCtrl *cc,CPrsStk *ps,
+        CMemberLst **_local_var,CArrayDim **_tmpad,I64 *unary_post_prec);
+extern I64 PrsUnaryTerm(
+        CCmpCtrl *cc,CPrsStk *ps,CMemberLst **_local_var,CArrayDim **_tmpad,
+        I64 *max_prec,I64 *unary_pre_prec,I64 *paren_prec);
+extern U0 PrsVarInit2(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,
+        CArrayDim *tmpad,U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass);
+_extern CMP_TEMPLATES                   U32 cmp_templates[1];
+_extern CMP_TEMPLATES_DONT_POP          U32 cmp_templates_dont_pop[1];
+_extern CMP_TEMPLATES_DONT_PUSH2        U32 cmp_templates_dont_push2[1];
+_extern CMP_TEMPLATES_DONT_PUSH         U32 cmp_templates_dont_push[1];
+_extern CMP_TEMPLATES_DONT_PUSH_POP     U32 cmp_templates_dont_push_pop[1];
+
+ diff --git a/public/Wb/Home/Src/Compiler/CHash.HC.HTML b/public/Wb/Home/Src/Compiler/CHash.HC.HTML new file mode 100755 index 0000000..aeaaaa8 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CHash.HC.HTML @@ -0,0 +1,172 @@ + + + + + + + + + + + +
+I64 HashEntrySize(CHashSrcSym *tmph)
+{//Logical size of a std system hash entry.
+  CDbgInfo *dbg_info;
+  CBinFile *bfh;
+  switch (HashTypeNum(tmph)) {
+    case HTt_DEFINE_STR:
+      return MSize(tmph(CHashDefineStr *)->data);
+    case HTt_GLBL_VAR:
+    case HTt_CLASS:
+    case HTt_INTERNAL_TYPE:
+      return tmph(CHashClass *)->size;
+    case HTt_FUN:
+      if (dbg_info=tmph->dbg_info)
+        return dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+              -dbg_info->body[0];
+      else
+        return -1;
+    case HTt_FILE:
+      return MSize(tmph(CHashGeneric *)->user_data0);
+    case HTt_MODULE:
+      if (StrCmp(tmph->str,KERNEL_MODULE_NAME))
+        return MSize(tmph(CHashGeneric *)->user_data0);
+      else {
+        bfh=mem_boot_base-sizeof(CBinFile);
+        return bfh->file_size;
+      }
+    case HTt_WORD:
+      return StrLen(tmph->str);
+  }
+  return -1;
+}
+
+I64 HashEntrySize2(CHashSrcSym *tmph)
+{//Memory size of a std system hash entry.
+  CDbgInfo *dbg_info;
+  I64 res=MSize2(tmph);
+  if (!(tmph->type&HTT_DICT_WORD))
+    res+=MSize2(tmph->str);
+  if (tmph->type & HTG_SRC_SYM) {
+    res+=MSize2(tmph->src_link);
+    res+=MSize2(tmph->idx);
+    res+=MSize2(tmph->import_name);
+    res+=LinkedLstSize(tmph->ie_lst);
+    if (tmph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM))
+      res+=MSize2(tmph->dbg_info);
+    if (tmph->type & HTT_CLASS)
+      res+=MemberLstSize(tmph);
+    else if (tmph->type & HTT_FUN) {
+      res+=MemberLstSize(tmph);
+      if (dbg_info=tmph->dbg_info)
+//This should be MSize() but it would crash on AOT .BIN.Z file funs.
+        res+=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+              -dbg_info->body[0];
+    } else if (tmph->type&HTT_DEFINE_STR)
+      res+=MSize2(tmph(CHashDefineStr *)->data);
+    else if (tmph->type & HTT_GLBL_VAR) {
+      res+=LinkedLstSize(tmph(CHashGlblVar *)->dim.next);
+      if (!(tmph(CHashGlblVar *)->flags&GVF_ALIAS))
+        res+=MSize2(tmph(CHashGlblVar *)->data_addr);
+      if (tmph(CHashGlblVar *)->fun_ptr)
+        res+=HashEntrySize2(tmph(CHashGlblVar *)->fun_ptr
+              -tmph(CHashGlblVar *)->fun_ptr->ptr_stars_cnt);
+    }
+  } else if (tmph->type & HTT_FILE)
+    res+=MSize2(tmph(CHashGeneric *)->user_data0);
+  else if (tmph->type & HTT_MODULE &&
+        StrCmp(tmph->str,KERNEL_MODULE_NAME))
+    res+=MSize2(tmph(CHashGeneric *)->user_data0);
+  return res;
+}
+
+I64 HashTableSize2(CHashTable *table)
+{//Memory size of std system hash table and all entries.
+  I64 i,res=0;
+  CHashSrcSym *tmph;
+  if (!table)
+    return 0;
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      res+=HashEntrySize2(tmph);
+      tmph=tmph->next;
+    }
+  }
+  res+=MSize2(table->body);
+  res+=MSize2(table);
+  return res;
+}
+
+U0 MapFileWrite(CHashTable *h,U8 *map_name,U8 drv_let)
+{
+  CHashSrcSym *tmph;
+  I64 i,size;
+  U8 *src_link;
+  CDoc *doc;
+  CDocBin *tmpb;
+  CDbgInfo *dbg_info;
+
+  doc=DocNew(map_name);
+  doc->flags|=DOCF_NO_CURSOR;
+  for (i=0;i<=h->mask;i++) {
+    tmph=h->body[i];
+    while (tmph) {
+      if (tmph->src_link && !(tmph->type & (HTF_IMPORT | HTF_PRIVATE))) {
+        src_link=StrNew(tmph->src_link);
+        if (drv_let && StrLen(src_link)>=4)
+          src_link[3]=drv_let;
+        if (dbg_info=tmph->dbg_info) {
+          size=offset(CDbgInfo.body)+
+                sizeof(U32)*(dbg_info->max_line+2-dbg_info->min_line);
+          if (size>MSize(dbg_info)) {
+            "Corrupt Map Entry\n";
+            dbg_info=NULL;
+          } else {
+            if (dbg_info->min_line<=dbg_info->max_line) {
+              tmpb=CAlloc(sizeof(CDocBin));
+              tmpb->size=size;
+              tmpb->data=MAlloc(size);
+              MemCpy(tmpb->data,dbg_info,size);
+              tmpb->num=doc->cur_bin_num++;
+              tmpb->use_cnt=1;
+              QueIns(tmpb,doc->bin_head.last);
+            } else
+              dbg_info=NULL;
+          }
+        }
+        if (dbg_info)
+          DocPrint(doc,"$LK,\"%s\",A=\"%s\",BI=%d$\n",
+                tmph->str,src_link,tmpb->num);
+        else
+          DocPrint(doc,"$LK,\"%s\",A=\"%s\"$\n",tmph->str,src_link);
+
+        Free(src_link);
+      }
+      tmph=tmph->next;
+    }
+  }
+  DocBinsValidate(doc);
+  DocWrite(doc);
+  DocDel(doc);
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/CInit.HC.HTML b/public/Wb/Home/Src/Compiler/CInit.HC.HTML new file mode 100755 index 0000000..0c8b5fd --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CInit.HC.HTML @@ -0,0 +1,361 @@ + + + + + + + + + + + +
+#define INTERNAL_TYPES_NUM      17
+
+class CInternalType
+{
+  U8 type,size,name[8];
+} internal_types_table[INTERNAL_TYPES_NUM]={
+  {RT_I0,0,"I0i"},{RT_I0,0,"I0"},{RT_U0,0,"U0i"},{RT_U0,0,"U0"},
+  {RT_I8,1,"I8i"},{RT_I8,1,"I8"},{RT_I8,1,"Bool"},
+  {RT_U8,1,"U8i"},{RT_U8,1,"U8"},
+  {RT_I16,2,"I16i"},{RT_U16,2,"U16i"},
+  {RT_I32,4,"I32i"},{RT_U32,4,"U32i"},
+  {RT_I64,8,"I64i"},{RT_U64,8,"U64i"},
+  {RT_F64,8,"F64i"},{RT_F64,8,"F64"},
+};
+
+CIntermediateStruct intermediate_code_table[IC_ICS_NUM]={
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"END"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOP1"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"END_EXP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOP2"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"LABEL"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"CALL_START"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"CALL_END"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"CALL_END2"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RETURN_VAL"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RETURN_VAL2"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"IMM_I64"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"IMM_F64"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"STR_CONST"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ABS_ADDR"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ADDR_IMPORT"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"HEAP_GLBL"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SIZEOF"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"TYPE"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"GET_LABEL"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"RBP"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"REG"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"FS"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV_FS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GS"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV_GS"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"LEA"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"MOV"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_I64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_F64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TO_BOOL"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"TOUPPER"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"HOLYC_TYPECAST"},
+  {IS_1_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"ADDR"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"COM"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"NOT"},
+  {IS_1_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"UNARY_MINUS"},
+  {IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF"},
+  {IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF_PP"},
+  {IS_1_ARG,1,IST_DEREF,FALSE,TRUE,0,0,0,"DEREF_MM"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"_PP"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"_MM"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"PP_"},
+  {IS_1_ARG,1,IST_DEREF,TRUE,TRUE,0,0,0,"MM_"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SHL"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"SHR"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SHL_CONST"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SHR_CONST"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"POWER"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"MUL"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"DIV"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"MOD"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"AND"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"OR"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"XOR"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ADD"},
+  {IS_2_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SUB"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"ADD_CONST"},
+  {IS_1_ARG,1,IST_ASSIGN,FALSE,FALSE,0,0,0,"SUB_CONST"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"EQU_EQU"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"NOT_EQU"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"LESS"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"GREATER_EQU"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"GREATER"},
+  {IS_2_ARG,1,IST_CMP,FALSE,FALSE,0,0,0,"LESS_EQU"},
+  {IS_0_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"PUSH_CMP"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"AND_AND"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"OR_OR"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"XOR_XOR"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN_PP"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ASSIGN_MM"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SHL_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SHR_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"MUL_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"DIV_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"MOD_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"AND_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"OR_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"XOR_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"ADD_EQU"},
+  {IS_2_ARG,1,IST_ASSIGN,FALSE,TRUE,0,0,0,"SUB_EQU"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"JMP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SUB_CALL"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SWITCH"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"NOBOUND_SWITCH"},
+  {IS_V_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ADD_RSP"},
+  {IS_V_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ADD_RSP1"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ENTER"},
+  {IS_0_ARG,0,IST_ASSIGN,FALSE,FALSE,0,0,0,"PUSH_REGS"},
+  {IS_0_ARG,0,IST_ASSIGN,FALSE,FALSE,0,0,0,"POP_REGS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"LEAVE"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"RET"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_INDIRECT"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_INDIRECT2"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_IMPORT"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CALL_EXTERN"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"ASM"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"PUSH"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"POP"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CLFLUSH"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"INVLPG"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U8"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U16"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"IN_U32"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U8"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U16"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"OUT_U32"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RFLAGS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"CARRY"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RFLAGS"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RAX"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RAX"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RBP"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RBP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"GET_RSP"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SET_RSP"},
+  {IS_0_ARG,1,IST_NULL,FALSE,TRUE,0,0,0,"RIP"},
+  {IS_0_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"RDTSC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BTC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"LBTC"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BSF"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BSR"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INIT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_INS_REV"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"QUE_REM"},
+  {IS_1_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"STRLEN"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_ZERO"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_ZERO"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_CARRY"},
+  {IS_0_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_CARRY"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_EQU_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_NOT_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_LESS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_GREATER_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_GREATER"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_LESS_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2EQU_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2NOT_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2LESS"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2GREATER_EQU"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2GREATER"},
+  {IS_2_ARG,1,IST_NULL,FALSE,FALSE,0,0,0,"BR_2LESS_EQU"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_NOT_ZERO"},
+  {IS_1_ARG,0,IST_DEREF,FALSE,TRUE,0,0,0,"BR_MM_ZERO"},
+  {IS_1_ARG,0,IST_DEREF,FALSE,TRUE,0,0,0,"BR_MM_NOT_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_AND_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_AND_AND_NOT_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_OR_OR_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"BR_OR_OR_NOT_ZERO"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_BTC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BT"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTS"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTR"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"BR_NOT_BTC"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U8"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U16"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U32"},
+  {IS_2_ARG,0,IST_NULL,FALSE,TRUE,0,0,0,"SWAP_U64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"ABS_I64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SIGN_I64"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"I64_MIN"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"U64_MIN"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"I64_MAX"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"U64_MAX"},
+  {IS_2_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"MOD_U64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SQRI64"},
+  {IS_1_ARG,0,IST_NULL,FALSE,FALSE,0,0,0,"SQRU64"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SQR"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ABS"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SQRT"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"SIN"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"COS"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"TAN"},
+  {IS_1_ARG,1,IST_NULL,TRUE,FALSE,0,0,0,"ATAN"},
+};
+
+U0 CmpLoadDefines()
+{
+  DefineLstLoad("ST_RAW_TYPES",
+        " \0 \0I0\0U0\0I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0"
+        "F32\0UF32\0F64\0UF64\0");
+  DefineLstLoad("ST_NATURAL_TYPES",
+        "I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0F64\0String\0");
+  DefineLstLoad("ST_INT_SIZE_TYPES",
+        "I8\0U8\0I16\0U16\0I32\0U32\0I64\0U64\0");
+  DefineLstLoad("ST_TY_TYPES","NULL\0STK\0IMM\0REG\0DISP\0SIB\0RIP\0");
+  DefineLstLoad("ST_U8_REGS","AL\0CL\0DL\0BL\0AH\0CH\0DH\0BH\0"
+        "R8u8\0R9u8\0R10u8\0R11u8\0R12u8\0R13u8\0R14u8\0R15u8\0");
+  DefineLstLoad("ST_U8_REX_REGS","AL\0CL\0DL\0BL\0RSPu8\0RBPu8\0RSIu8\0RDIu8\0"
+        "R8u8\0R9u8\0R10u8\0R11u8\0R12u8\0R13u8\0R14u8\0R15u8\0");
+  DefineLstLoad("ST_U16_REGS","AX\0CX\0DX\0BX\0SP\0BP\0SI\0DI\0"
+        "R8u16\0R9u16\0R10u16\0R11u16\0R12u16\0R13u16\0R14u16\0R15u16\0");
+  DefineLstLoad("ST_U32_REGS","EAX\0ECX\0EDX\0EBX\0ESP\0EBP\0ESI\0EDI\0"
+        "R8u32\0R9u32\0R10u32\0R11u32\0R12u32\0R13u32\0R14u32\0R15u32\0");
+  DefineLstLoad("ST_U64_REGS","RAX\0RCX\0RDX\0RBX\0RSP\0RBP\0RSI\0RDI\0"
+        "R8\0R9\0R10\0R11\0R12\0R13\0R14\0R15\0");
+  DefineLstLoad("ST_MM_REGS","MM0\0MM1\0MM2\0MM3\0MM4\0MM5\0MM6\0MM7\0");
+  DefineLstLoad("ST_XMM_REGS",
+        "XMM0\0XMM1\0XMM2\0XMM3\0XMM4\0XMM5\0XMM6\0XMM7\0");
+  DefineLstLoad("ST_ARG_TYPES","NONE\0REL8\0REL16\0REL32\0"
+        "IMM8\0IMM16\0IMM32\0IMM64\0UIMM8\0UIMM16\0UIMM32\0UIMM64\0"
+        "R8\0R16\0R32\0R64\0RM8\0RM16\0RM32\0RM64\0"
+        "M8\0M16\0M32\0M64\0M1632\0M16N32\0M16N16\0M32N32\0"
+        "MOFFS8\0MOFFS16\0MOFFS32\0MOFFS64\0"
+        "AL\0AX\0EAX\0RAX\0CL\0DX\0 \0SREG\0"
+        "SS\0DS\0ES\0FS\0GS\0CS\0ST0\0STI\0"
+        "MM\0MM32\0MM64\0XMM\0XMM32\0XMM64\0XMM128\0XMM0\0");
+  DefineLstLoad("ST_SEG_REGS","ES\0CS\0SS\0DS\0FS\0GS\0");
+  DefineLstLoad("ST_FSTK_REGS","ST0\0ST1\0ST2\0ST3\0ST4\0ST5\0ST6\0ST7\0");
+}
+
+U0 CmpFillTables()
+{
+  I64 i;
+  U32 *d;
+
+  cmp.to_reg_vars_map=CAlloc(REG_REGS_NUM*sizeof(U8));
+  cmp.num_reg_vars=0;
+  cmp.reg_vars_mask=REGG_LOCAL_VARS;
+  for (i=0;i<REG_REGS_NUM;i++)
+    if (Bt(&cmp.reg_vars_mask,i))
+      cmp.to_reg_vars_map[cmp.num_reg_vars++]=i;
+
+  cmp.non_ptr_vars_map=CAlloc(REG_REGS_NUM*sizeof(U8));
+  cmp.num_non_ptr_vars=0;
+  cmp.non_ptr_vars_mask=REGG_LOCAL_NON_PTR_VARS;
+  for (i=0;i<REG_REGS_NUM;i++)
+    if (Bt(&cmp.non_ptr_vars_mask,i))
+      cmp.non_ptr_vars_map[cmp.num_non_ptr_vars++]=i;
+
+  cmp.dual_U16_tokens1=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['!']=TK_NOT_EQU<<16+'=';
+  d['&']=TK_AND_AND<<16+'&';
+  d['*']=TK_MUL_EQU<<16+'=';
+  d['+']=TK_PLUS_PLUS<<16+'+';
+  d['-']=TK_DEREFERENCE<<16+'>';
+  d['/']='*';
+  d[':']=TK_DBL_COLON<<16+':';
+  d['<']=TK_LESS_EQU<<16+'=';
+  d['=']=TK_EQU_EQU<<16+'=';
+  d['>']=TK_GREATER_EQU<<16+'=';
+  d['^']=TK_XOR_EQU<<16+'=';
+  d['|']=TK_OR_OR<<16+'|';
+  d['%']=TK_MOD_EQU<<16+'=';
+
+  cmp.dual_U16_tokens2=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['&']=TK_AND_EQU<<16+'=';
+  d['+']=TK_ADD_EQU<<16+'=';
+  d['-']=TK_MINUS_MINUS<<16+'-';
+  d['/']='/';
+  d['<']=TK_SHL<<16+'<';
+  d['>']=TK_SHR<<16+'>';
+  d['^']=TK_XOR_XOR<<16+'^';
+  d['|']=TK_OR_EQU<<16+'=';
+
+  cmp.dual_U16_tokens3=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['-']=TK_SUB_EQU<<16+'=';
+  d['/']=TK_DIV_EQU<<16+'=';
+
+  cmp.binary_ops=d=CAlloc(sizeof(U32)*TK_TKS_NUM);
+  d['`']   =(PREC_EXP+ASSOCF_RIGHT)<<16+IC_POWER;
+  d[TK_SHL]=(PREC_EXP+ASSOCF_LEFT)<<16+IC_SHL;
+  d[TK_SHR]=(PREC_EXP+ASSOCF_LEFT)<<16+IC_SHR;
+
+  d['*']=PREC_MUL<<16+IC_MUL;
+  d['/']=(PREC_MUL+ASSOCF_LEFT)<<16+IC_DIV;
+  d['%']=(PREC_MUL+ASSOCF_LEFT)<<16+IC_MOD;
+
+  d['&']=PREC_AND<<16+IC_AND;
+
+  d['^']=PREC_XOR<<16+IC_XOR;
+
+  d['|']=PREC_OR<<16+IC_OR;
+
+  d['+']=PREC_ADD<<16+IC_ADD;
+  d['-']=(PREC_ADD+ASSOCF_LEFT)<<16+IC_SUB;
+
+  d['<']                =PREC_CMP<<16+IC_LESS;
+  d['>']                =PREC_CMP<<16+IC_GREATER;
+  d[TK_LESS_EQU]        =PREC_CMP<<16+IC_LESS_EQU;
+  d[TK_GREATER_EQU]     =PREC_CMP<<16+IC_GREATER_EQU;
+
+  d[TK_EQU_EQU] =PREC_CMP2<<16+IC_EQU_EQU;
+  d[TK_NOT_EQU] =PREC_CMP2<<16+IC_NOT_EQU;
+
+  d[TK_AND_AND] =PREC_AND_AND<<16+IC_AND_AND;
+
+  d[TK_XOR_XOR] =PREC_XOR_XOR<<16+IC_XOR_XOR;
+
+  d[TK_OR_OR]   =PREC_OR_OR<<16+IC_OR_OR;
+
+  d['=']         =(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_ASSIGN;
+  d[TK_SHL_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHL_EQU;
+  d[TK_SHR_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SHR_EQU;
+  d[TK_MUL_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MUL_EQU;
+  d[TK_DIV_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_DIV_EQU;
+  d[TK_MOD_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_MOD_EQU;
+  d[TK_AND_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_AND_EQU;
+  d[TK_OR_EQU] =(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_OR_EQU;
+  d[TK_XOR_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_XOR_EQU;
+  d[TK_ADD_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_ADD_EQU;
+  d[TK_SUB_EQU]=(PREC_ASSIGN+ASSOCF_RIGHT)<<16+IC_SUB_EQU;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/CMain.HC.HTML b/public/Wb/Home/Src/Compiler/CMain.HC.HTML new file mode 100755 index 0000000..e3b69f3 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CMain.HC.HTML @@ -0,0 +1,733 @@ + + + + + + + + + + + +
+U8 *LexStmt2Bin(CCmpCtrl *cc,I64 *_type,I64 cmp_flags=0)
+{//Compile one cc stmt to bin code.
+  I64 size,i,j,k,*res=INVALID_PTR;
+  CCodeCtrl *tmpcbh;
+  if (_type) *_type=RT_I64;
+  Btr(&cc->flags,CCf_PASS_TRACE_PRESENT);
+  if (cc->aot_depth==2)
+    COCPush(cc);
+  COCInit(cc);
+  if (!PrsStmt(cc,,,cmp_flags)) {
+    if (cc->coc.coc_head.next!=&cc->coc.coc_head) {
+      cc->coc.coc_head.last->ic_flags&=~ICF_RES_NOT_USED;
+      ICAdd(cc,IC_RETURN_VAL2,0,0);
+      ICAdd(cc,IC_RET,0,0);
+      if (res=COCCompile(cc,&size,NULL,_type)) {
+        if (cc->flags&CCF_AOT_COMPILE) {
+          j=cc->aotc->rip;
+          k=(size+7)>>3;
+          for (i=0;i<k;i++)
+            AOTStoreCodeU64(cc,res[i]);
+          Free(res);
+          res=j;
+        }
+      }
+    } //TODO: else del misc?
+  } else //TODO: too dangerous to del Misc?
+    QueDel(&cc->coc.coc_head.next);
+  if (cc->aot_depth==2) {
+    tmpcbh=COCPopNoFree(cc);
+    COCAppend(cc,tmpcbh);
+  }
+  return res;
+}
+
+CAOT *CmpJoin(CCmpCtrl *cc,I64 cmp_flags,U8 *map_name=NULL,U8 mapfile_drv_let=0)
+{
+  CAOTCtrl *aotc,*old_aot=cc->aotc;
+  I64 i,j,l;
+  U8 *buf;
+  CAOTBinBlk *tmpbin;
+  CAOTImportExport *tmpie;
+  Bool okay=TRUE;
+  CLexHashTableContext *htc=MAlloc(sizeof(CLexHashTableContext));
+  CAOT *res=CAlloc(sizeof(CAOT)),*parent;
+  if (parent=cc->aot) {
+    res->parent_aot=parent;
+    QueIns(res,parent->last);
+  } else
+    QueInit(res);
+  cc->aot=res;
+
+  res->next_ie=res->last_ie=&res->next_ie;
+  cc->aotc=aotc=CAlloc(sizeof(CAOTCtrl));
+  cc->aot_depth++;
+
+  aotc->bin=CAlloc(sizeof(CAOTBinBlk));
+  aotc->max_align_bits=0;
+  aotc->org=INVALID_PTR;
+
+  MemCpy(htc,&cc->htc,sizeof(CLexHashTableContext));
+  if (cc->htc.fun)
+    cc->htc.glbl_hash_table=HashTableNew(128);
+  else
+    cc->htc.glbl_hash_table=HashTableNew(1024);
+  if (cc->flags&CCF_AOT_COMPILE) {
+    cc->htc.define_hash_table=cc->htc.glbl_hash_table;
+    if (cc->aot_depth<=1)
+      cc->htc.glbl_hash_table->next=cmp.asm_hash;
+    else
+      cc->htc.glbl_hash_table->next=htc->glbl_hash_table;
+  } else
+    cc->htc.glbl_hash_table->next=Fs->hash_table;
+  cc->htc.hash_table_lst=cc->htc.local_hash_table=HashTableNew(16);
+  cc->htc.local_hash_table->next=cc->htc.glbl_hash_table;
+  cc->htc.local_var_lst=cc->htc.fun; //HolyC local vars
+  cc->htc.fun=NULL;
+  try {
+    if (cmp_flags&CMPF_LEX_FIRST)
+      Lex(cc);
+    if (!(cmp_flags&CMPF_ONE_ASM_INS))
+      cmp_flags|=CMPF_PRS_SEMICOLON;
+    if (cc->flags&CCF_AOT_COMPILE) {
+      while (cc->token!=TK_EOF) {
+        buf=LexStmt2Bin(cc,NULL,cmp_flags);
+        if (buf!=INVALID_PTR) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_MAIN;
+          tmpie->rip=buf;
+          QueIns(tmpie,res->last_ie);
+        }
+        if (cmp_flags&CMPF_ASM_BLK)
+          break;
+      }
+    } else
+      PrsStmt(cc,,,cmp_flags);
+    AOTGlblsResolve(cc,res);
+  } catch {
+    if (Fs->except_ch=='Compiler' && !(cmp_flags&CMPF_ASM_BLK)) {
+      LexPutPos(cc);
+      Fs->catch_except=TRUE;
+    }
+    okay=FALSE;
+  }
+  if (!okay) {
+    if (cc->error_cnt<1)
+      cc->error_cnt=1;
+    cc->aot=res->parent_aot;
+    Free(res);
+    LinkedLstDel(aotc->bin);
+    res=NULL;
+  } else {
+    if (map_name)
+      MapFileWrite(cc->htc.glbl_hash_table,map_name,mapfile_drv_let);
+    HashTableDel(cc->htc.local_hash_table);
+    HashTableDel(cc->htc.glbl_hash_table);
+
+    if (!aotc->num_bin_U8s)
+      res->buf=NULL;
+    else {
+      if (cc->flags&CCF_AOT_COMPILE)
+        res->buf=MAlloc(aotc->num_bin_U8s);
+      else {
+        if (aotc->org==INVALID_PTR)
+          res->buf=MAlloc(aotc->num_bin_U8s,Fs->code_heap);
+        else
+          res->buf=aotc->org;
+      }
+      res->aot_U8s=aotc->num_bin_U8s;
+      tmpbin=aotc->bin;
+      j=0;
+      l=aotc->num_bin_U8s;
+      while (tmpbin) {
+        i=l;
+        if (i>AOT_BIN_BLK_SIZE)
+          i=AOT_BIN_BLK_SIZE;
+        MemCpy(res->buf+j,tmpbin->body,i);
+        j+=i;
+        l-=i;
+        tmpbin=tmpbin->next;
+      }
+    }
+    LinkedLstDel(aotc->bin);
+    res->abss=aotc->abss;
+    res->heap_glbls=aotc->heap_glbls;
+    res->max_align_bits=aotc->max_align_bits;
+    res->org=aotc->org;
+  }
+  cc->aot=parent;
+  MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
+  Free(htc);
+  Free(aotc);
+  cc->aotc=old_aot;
+  cc->aot_depth--;
+  return res;
+}
+
+CAOT *CmpBuf(U8 *buf,U8 *map_name=NULL,
+  I64 *error_cnt=NULL, I64 *warning_cnt=NULL,U8 mapfile_drv_let=0)
+{
+  CCmpCtrl *cc;
+  CAOT *res=NULL;
+  cc=CmpCtrlNew(buf,CCF_DONT_FREE_BUF);
+  cc->flags|=CCF_AOT_COMPILE;
+  QueIns(cc,Fs->last_cc);
+  res=CmpJoin(cc,CMPF_LEX_FIRST,map_name,mapfile_drv_let);
+  if (error_cnt)   *error_cnt=cc->error_cnt;
+  if (warning_cnt) *warning_cnt=cc->warning_cnt;
+  QueRem(cc);
+  if (res)
+    CmpCtrlDel(cc);
+  return res;
+}
+
+U0 CmpFixUpJITAsm(CCmpCtrl *cc,CAOT *tmpaot)
+{
+  I64 i,rip2=tmpaot->buf+tmpaot->rip,*str=NULL;
+  U8 *ptr;
+  CCodeMisc *g_lb;
+  CAOTAbsAddr *tmpa,*tmpa1;
+  CAOTImportExport *tmpie,*tmpie1;
+  CHashExport *tmpex;
+
+  tmpa=tmpaot->abss;
+  while (tmpa) {
+    tmpa1=tmpa->next;
+    ptr=rip2+tmpa->rip;
+    switch [tmpa->type] {
+      case AAT_ADD_U8:  *ptr(U8 *) +=rip2; break;
+      case AAT_SUB_U8:  *ptr(U8 *) -=rip2; break;
+      case AAT_ADD_U16: *ptr(U16 *)+=rip2; break;
+      case AAT_SUB_U16: *ptr(U16 *)-=rip2; break;
+      case AAT_ADD_U32: *ptr(U32 *)+=rip2; break;
+      case AAT_SUB_U32: *ptr(U32 *)-=rip2; break;
+      case AAT_ADD_U64: *ptr(I64 *)+=rip2; break;
+      case AAT_SUB_U64: *ptr(I64 *)-=rip2; break;
+    }
+    Free(tmpa);
+    tmpa=tmpa1;
+  }
+  tmpie=tmpaot->next_ie;
+  while (tmpie!=&tmpaot->next_ie) {
+    tmpie1=tmpie->next;
+    if (tmpie->str) {
+      Free(str);
+      str=tmpie->str;
+    }
+    switch (tmpie->type) {
+      case IET_REL32_EXPORT:
+      case IET_IMM32_EXPORT:
+      case IET_REL64_EXPORT:
+      case IET_IMM64_EXPORT:
+        tmpex=CAlloc(sizeof(CHashExport));
+        tmpex->str=str;
+        str=NULL;
+        tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+        if (tmpie->type==IET_IMM32_EXPORT||tmpie->type==IET_IMM64_EXPORT)
+          tmpex->val=tmpie->rip;
+        else
+          tmpex->val=tmpie->rip+rip2;
+        tmpex->src_link=tmpie->src_link;
+        tmpie->src_link=NULL;
+        HashAdd(tmpex,Fs->hash_table);
+        SysSymImportsResolve(tmpex->str);
+        break;
+      case IET_REL_I0...IET_IMM_I64:
+        if (tmpie->str) {
+          if (tmpie->flags&IEF_GOTO_LABEL) {
+            if(!(g_lb=COCGoToLabelFind(cc,str)))
+              "Unresolved Reference:%s\n",str;
+            else {
+              g_lb->use_cnt++;
+              g_lb=OptLabelFwd(g_lb);
+              i=g_lb->addr+tmpaot->buf;
+            }
+            tmpex=NULL;
+          } else {
+            if (!(tmpex=HashFind(str,Fs->hash_table,
+                  HTG_ALL-HTT_IMPORT_SYS_SYM)))
+              "Unresolved Reference:%s\n",str;
+            else {
+              if (tmpex->type & HTT_FUN)
+                i=tmpex(CHashFun *)->exe_addr;
+              else if (tmpex->type & HTT_GLBL_VAR)
+                i=tmpex(CHashGlblVar *)->data_addr;
+              else
+                i=tmpex->val;
+            }
+            g_lb=NULL;
+          }
+        }
+        if (tmpex || g_lb) {
+          ptr=tmpie->rip+rip2;
+          switch [tmpie->type] {
+            case IET_REL_I0:
+            case IET_IMM_U0:
+              break;
+            case IET_REL_I8:
+              if (!(I8_MIN<=i-ptr-1<=I8_MAX))
+                LexExcept(cc,"Branch out of range at ");
+              *ptr(U8 *) =i-ptr-1;
+              break;
+            case IET_IMM_U8:
+              *ptr(U8 *) =i;
+              break;
+            case IET_REL_I16:
+              if (!(I16_MIN<=i-ptr-2<=I16_MAX))
+                LexExcept(cc,"Branch out of range at ");
+              *ptr(U16 *)=i-ptr-2;
+              break;
+            case IET_IMM_U16:
+              *ptr(U16 *)=i;
+              break;
+            case IET_REL_I32:
+              if (!(I32_MIN<=i-ptr-4<=I32_MAX))
+                LexExcept(cc,"Branch out of range at ");
+              *ptr(U32 *)=i-ptr-4;
+              break;
+            case IET_IMM_U32:
+              *ptr(U32 *)=i;
+              break;
+            case IET_REL_I64:
+              *ptr(I64 *)=i-ptr-8;
+              break;
+            case IET_IMM_I64:
+              *ptr(I64 *)=i;
+              break;
+          }
+        }
+        break;
+    }
+    Free(tmpie->src_link);
+    Free(tmpie);
+    tmpie=tmpie1;
+  }
+  Free(str);
+  if (!cc->aot_depth && Bt(&cc->opts,OPTf_TRACE))
+    Un(rip2,tmpaot->aot_U8s,64);
+  QueRem(tmpaot);
+  Free(tmpaot);
+}
+
+U0 CmpFixUpAOTAsm(CCmpCtrl *cc,CAOT *tmpaot)
+{
+  CAOTCtrl *aotc=cc->aotc;
+  I64 i,rip2=tmpaot->rip+cc->aotc->rip;
+  U8 *ptr;
+  CCodeMisc *g_lb=NULL;
+  CAOTAbsAddr *tmpa,*tmpa1;
+  CAOTImportExport *tmpie,*tmpie1;
+
+  tmpa=tmpaot->abss;
+  while (tmpa) {
+    tmpa1=tmpa->next;
+    tmpa->next=aotc->abss;
+    ptr=tmpaot->buf+tmpaot->rip+tmpa->rip;
+    switch [tmpa->type] {
+      case AAT_ADD_U8:  *ptr(U8 *)+=rip2;       break;
+      case AAT_SUB_U8:  *ptr(U8 *)-=rip2;       break;
+      case AAT_ADD_U16: *ptr(U16 *)+=rip2;      break;
+      case AAT_SUB_U16: *ptr(U16 *)-=rip2;      break;
+      case AAT_ADD_U32: *ptr(U32 *)+=rip2;      break;
+      case AAT_SUB_U32: *ptr(U32 *)-=rip2;      break;
+      case AAT_ADD_U64: *ptr(I64 *)+=rip2;      break;
+      case AAT_SUB_U64: *ptr(I64 *)-=rip2;      break;
+    }
+    aotc->abss=tmpa;
+    tmpa->rip+=rip2;
+    tmpa=tmpa1;
+  }
+
+  tmpie=tmpaot->next_ie;
+  while (tmpie!=&tmpaot->next_ie) {
+    tmpie1=tmpie->next;
+    QueRem(tmpie);
+    if (IET_REL_I0<=tmpie->type<=IET_IMM_I64) {
+      if (tmpie->str) {
+        if (tmpie->flags&IEF_GOTO_LABEL) {
+          if(!(g_lb=COCGoToLabelFind(cc,tmpie->str)))
+            "Unresolved Reference:%s\n",tmpie->str;
+          else {
+            g_lb->use_cnt++;
+            g_lb=OptLabelFwd(g_lb);
+          }
+        } else
+          g_lb=NULL;
+      }
+    } else
+      g_lb=NULL;
+
+    ptr=tmpaot->buf+tmpaot->rip+tmpie->rip;
+    if (g_lb) {
+      i=g_lb->addr+tmpaot->buf;
+      switch [tmpie->type] {
+        case IET_REL_I0:
+        case IET_IMM_U0:
+          break;
+        case IET_REL_I8:
+          if (!(I8_MIN<=i-ptr-1<=I8_MAX))
+            LexExcept(cc,"Branch out of range at ");
+          *ptr(U8 *) =i-ptr-1;
+          break;
+        case IET_IMM_U8:
+          *ptr(U8 *) =i;
+          break;
+        case IET_REL_I16:
+          if (!(I16_MIN<=i-ptr-2<=I16_MAX))
+            LexExcept(cc,"Branch out of range at ");
+          *ptr(U16 *)=i-ptr-2;
+          break;
+        case IET_IMM_U16:
+          *ptr(U16 *)=i;
+          break;
+        case IET_REL_I32:
+          if (!(I32_MIN<=i-ptr-4<=I32_MAX))
+            LexExcept(cc,"Branch out of range at ");
+          *ptr(U32 *)=i-ptr-4;
+          break;
+        case IET_IMM_U32:
+          *ptr(U32 *)=i;
+          break;
+        case IET_REL_I64:
+          *ptr(I64 *)=i-ptr-8;
+          break;
+        case IET_IMM_I64:
+          *ptr(I64 *)=i;
+          break;
+      }
+      Free(tmpie->src_link);
+      Free(tmpie);
+    } else {
+      switch (tmpie->type) {
+        start:
+          case IET_REL32_EXPORT:
+          case IET_IMM32_EXPORT:
+          case IET_REL64_EXPORT:
+          case IET_IMM64_EXPORT:
+          case IET_IMM_U0:
+          case IET_IMM_U8:
+          case IET_IMM_U16:
+          case IET_IMM_U32:
+          case IET_IMM_I64:
+          case IET_REL_I0:
+            break;
+          case IET_REL_I8:          *ptr(U8 *) -=rip2;      break;
+          case IET_REL_I16:         *ptr(U16 *)-=rip2;      break;
+          case IET_REL_I32:         *ptr(U32 *)-=rip2;      break;
+          case IET_REL_I64:         *ptr(I64 *)-=rip2;      break;
+        end:
+          tmpie->rip+=rip2;
+          break;
+      }
+      tmpie->aot=NULL;
+      QueIns(tmpie,tmpaot->parent_aot->last_ie);
+    }
+    tmpie=tmpie1;
+  }
+}
+
+I64 Cmp(U8 *filename,U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv_let=0)
+{//AOT Compile HC or PRJ file a and output BIN file. Returns err_cnt.
+  U8 *ptr,*fbuf=NULL,*fbuf2=NULL,*fbuf3=NULL,
+        *patch_table=MAlloc(0x20000);
+  CAOT *tmpaot;
+  I64 i,cnt,size=0,error_cnt=0,warning_cnt=0,aot_U8s=0;
+  CBinFile *bfh;
+  CAOTImportExport *tmpie,*tmpie1;
+  CAOTAbsAddr *tmpa,*tmpa1;
+  CAOTHeapGlblRef *tmphgr,*tmphgr1;
+  CAOTHeapGlbl *tmphg,*tmphg1;
+
+  fbuf=ExtDft(filename,"PRJ.Z");
+  fbuf2=MStrPrint("#include \"%s\"",fbuf);
+  if (map_name)
+    fbuf3=ExtDft(map_name,"MAP.Z");
+
+  if (tmpaot=CmpBuf(fbuf2,fbuf3,&error_cnt,&warning_cnt,mapfile_drv_let)) {
+    aot_U8s=tmpaot->aot_U8s;
+    ptr=patch_table;
+//See Load()
+    cnt=0;
+    tmpa=tmpaot->abss;
+    while (tmpa) {
+      if (!(tmpa->type&IEF_IMM_NOT_REL))
+        cnt++;
+      tmpa=tmpa->next;
+    }
+    if (cnt) {
+      *ptr++=IET_ABS_ADDR;
+      *ptr(U32 *)++=cnt;
+      *ptr++=0;
+      tmpa=tmpaot->abss;
+      while (tmpa) {
+        tmpa1=tmpa->next;
+        if (!(tmpa->type&IEF_IMM_NOT_REL))
+          *ptr(U32 *)++ =tmpa->rip;
+        Free(tmpa);
+        tmpa=tmpa1;
+      }
+    }
+    tmphg=tmpaot->heap_glbls;
+    while (tmphg) {
+      tmphg1=tmphg->next;
+      cnt=0;
+      tmphgr=tmphg->references;
+      while (tmphgr) {
+        cnt++;
+        tmphgr=tmphgr->next;
+      }
+      if (cnt) {
+        *ptr++=IET_DATA_HEAP;
+        *ptr(U32 *)++=cnt;
+        if (tmphg->str) {
+          i=StrLen(tmphg->str);
+          MemCpy(ptr,tmphg->str,i+1);
+          Free(tmphg->str);
+          ptr+=i+1;
+        } else
+          *ptr++=0;
+        *ptr(I64 *)++=tmphg->size;
+        tmphgr=tmphg->references;
+        while (tmphgr) {
+          tmphgr1=tmphgr->next;
+          *ptr(U32 *)++=tmphgr->rip;
+          Free(tmphgr);
+          tmphgr=tmphgr1;
+        }
+      }
+      Free(tmphg);
+      tmphg=tmphg1;
+    }
+
+    //Do exports first
+    tmpie=tmpaot->next_ie;
+    while (tmpie!=&tmpaot->next_ie) {
+      tmpie1=tmpie->next;
+      if (!tmpie->type || IET_REL32_EXPORT<=tmpie->type<=IET_IMM64_EXPORT) {
+        QueRem(tmpie);
+        *ptr++=tmpie->type;
+        *ptr(U32 *)++=tmpie->rip;
+        if (tmpie->str) {
+          i=StrLen(tmpie->str);
+          MemCpy(ptr,tmpie->str,i+1);
+          Free(tmpie->str);
+          ptr+=i+1;
+        } else
+          *ptr++=0;
+        Free(tmpie->src_link);
+        Free(tmpie);
+      }
+      tmpie=tmpie1;
+    }
+
+    //Do imports second
+    tmpie=tmpaot->next_ie;
+    while (tmpie!=&tmpaot->next_ie) {
+      tmpie1=tmpie->next;
+      QueRem(tmpie);
+      *ptr++=tmpie->type;
+      if (tmpie->aot)
+        tmpie->rip+=tmpie->aot->rip2;
+      *ptr(U32 *)++=tmpie->rip;
+      if (tmpie->str) {
+        i=StrLen(tmpie->str);
+        MemCpy(ptr,tmpie->str,i+1);
+        Free(tmpie->str);
+        ptr+=i+1;
+      } else
+        *ptr++=0;
+      Free(tmpie->src_link);
+      Free(tmpie);
+      tmpie=tmpie1;
+    }
+
+    *ptr++=IET_END;
+    MemSet(ptr,0,16);
+    i=ptr-patch_table;
+//Needs 16 ALIGN
+    size=(sizeof(CBinFile)+aot_U8s+i+15)&-16;
+    bfh=MAlloc(size);
+    bfh->jmp=0xEB+256*(sizeof(CBinFile)-2);
+#assert sizeof(CBinFile)-2<=I8_MAX
+    bfh->reserved=0;
+    bfh->bin_signature=BIN_SIGNATURE_VAL;
+    bfh->org=tmpaot->org;
+    bfh->module_align_bits=tmpaot->max_align_bits;
+    bfh->patch_table_offset=sizeof(CBinFile)+aot_U8s;
+    bfh->file_size=size;
+    MemCpy(bfh(U8 *)+sizeof(CBinFile),tmpaot->buf,aot_U8s);
+    MemCpy(bfh(U8 *)+sizeof(CBinFile)+aot_U8s,patch_table,
+          size-aot_U8s-sizeof(CBinFile));
+    Free(fbuf2);
+    if (out_name)
+      fbuf2=ExtDft(out_name,"BIN.Z");
+    else
+      fbuf2=ExtChg(fbuf,"BIN.Z");
+    FileWrite(fbuf2,bfh,size);
+    Free(bfh);
+    Free(tmpaot->buf);
+    QueDel(tmpaot);
+    Free(tmpaot);
+  }
+  Free(patch_table);
+  Free(fbuf);
+  Free(fbuf2);
+  Free(fbuf3);
+  Print("Errs:%d Warns:%d Code:%X Size:%X\n",
+        error_cnt,warning_cnt,aot_U8s,size);
+  return error_cnt;
+}
+
+I64 ExePutS(U8 *buf,U8 *filename=NULL,
+        I64 ccf_flags=0,CLexHashTableContext *htc=NULL)
+{//JIT Compile and execute text from a puts("").
+  I64 res;
+  Bool okay=TRUE;
+  CCmpCtrl *cc;
+  if (!filename)
+    filename=blkdev.tmp_filename;
+  cc=CmpCtrlNew(buf,ccf_flags|CCF_DONT_FREE_BUF,filename);
+  if (Fs->last_cc!=&Fs->next_cc) {
+    cc->opts=Fs->last_cc->opts;
+    if (htc) {
+      cc->flags=cc->flags &~CCF_ASM_EXPRESSIONS |
+            htc->old_flags&CCF_ASM_EXPRESSIONS;
+      MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
+    }
+  }
+  QueIns(cc,Fs->last_cc);
+  try {
+    Lex(cc);
+    res=ExeCmdLine(cc);
+  } catch {
+    if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
+      Fs->catch_except=TRUE;
+      okay=FALSE;
+      res=0;
+    }
+  }
+  QueRem(cc);
+  if (okay)
+    CmpCtrlDel(cc); //TODO: can crash
+  return res;
+}
+
+I64 ExePrint(U8 *fmt,...)
+{//JIT Compile and execute text from a printf().
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=ExePutS(buf);
+  Free(buf);
+  return res;
+}
+
+I64 ExeFile(U8 *name,I64 ccf_flags=0)
+{//JIT Compile and execute a file.
+  I64 res;
+  U8 *name2=ExtDft(name,"HC.Z"),
+        *st=MStrPrint("#include \"%s\";",name2);
+  res=ExePutS(st,name,ccf_flags);
+  Free(st);
+  Free(name2);
+  return res;
+}
+
+I64 RunFile(U8 *name,I64 ccf_flags=0,...)
+{//ExeFile() with args using LastFun().
+  ExeFile(name,ccf_flags);
+  return LastFun(argc,argv);
+}
+
+I64 ExePutS2(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0)
+{//throws exceptions
+  I64 res;
+  CCmpCtrl *cc;
+  if (!filename)
+    filename=blkdev.tmp_filename;
+  cc=CmpCtrlNew(buf,ccf_flags|CCF_DONT_FREE_BUF,filename);
+  if (Fs->last_cc!=&Fs->next_cc)
+    cc->opts=Fs->last_cc->opts;
+  QueIns(cc,Fs->last_cc);
+  Lex(cc);
+  res=ExeCmdLine(cc);
+  QueRem(cc);
+  CmpCtrlDel(cc);
+  return res;
+}
+
+I64 ExePrint2(U8 *fmt,...)
+{//throws exceptions
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=ExePutS2(buf);
+  Free(buf);
+  return res;
+}
+
+I64 ExeFile2(U8 *name,I64 ccf_flags=0)
+{//throws exceptions
+  I64 res;
+  U8 *name2=ExtDft(name,"HC.Z"),*st=MStrPrint("#include \"%s\";",name2);
+  res=ExePutS2(st,name,ccf_flags);
+  Free(st);
+  Free(name2);
+  return res;
+}
+
+I64 RunFile2(U8 *name,I64 ccf_flags=0,...)
+{//ExeFile2() with args using LastFun(). throws exceptions.
+  ExeFile2(name,ccf_flags);
+  return LastFun(argc,argv);
+}
+
+I64 StreamExePrint(U8 *fmt,...)
+{//Causes value from stream to be used in an #exe{} block.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res=0;
+  CLexHashTableContext *htc;
+  CCmpCtrl *cc=Fs->last_cc;
+  if (cc==&Fs->next_cc)
+    PrintErr("Not Compiling\n");
+  else {
+    if (!(cc->flags&CCF_EXE_BLK))
+      LexExcept(cc,"StreamExePrint only allowed in AOT compiled #exe{} mode.");
+    if (htc=cc->htc.next)
+      res=ExePutS(buf,,,htc);
+  }
+  Free(buf);
+  return res;
+}
+
+U0 CInit()
+{
+  CmpLoadDefines;
+  CmpFillTables;
+  QueInit(&cmp.ic_nop);
+  cmp.ic_nop.ic_class=cmp.internal_types[RT_I64];
+  cmp.ic_nop.ic_code=IC_NOP1;
+  AsmHashLoad;
+  UAsmHashLoad;
+}
+
+CInit;
+
+ diff --git a/public/Wb/Home/Src/Compiler/CMisc.HC.HTML b/public/Wb/Home/Src/Compiler/CMisc.HC.HTML new file mode 100755 index 0000000..807e037 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CMisc.HC.HTML @@ -0,0 +1,200 @@ + + + + + + + + + + + +
+Bool Option(I64 num,Bool val)
+{//Set compiler Option to val.
+  return BEqu(&Fs->last_cc->opts,num,val);
+}
+
+Bool GetOption(I64 num)
+{//Get state of compiler option.
+  return Bt(&Fs->last_cc->opts,num);
+}
+
+asm {
+_LAST_FUN::     //See _CALL_IND
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        XOR     RAX,RAX
+        MOV     RAX,FS:CTask.last_fun[RAX]
+        TEST    RAX,RAX
+        JZ      @@10
+        MOV     RDX,U64 CHashFun.exe_addr[RAX]
+
+        MOV     RCX,U64 SF_ARG1[RBP]    //argc
+        MOV     RSI,U64 SF_ARG2[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        TEST    RDX,RDX
+        JZ      @@05
+
+        CALL    RDX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+
+@@05:   MOV     RCX,U64 SF_ARG1[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        XOR     RAX,RAX
+@@10:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+}
+_extern _LAST_FUN I64 LastFun(I64 argc,I64 *argv); //Execute last fun with args.
+
+I64 PassTrace(I64 i=0b10001111101)
+{//Ctrls which optimizer passes are displayed.
+  I64 old=Fs->last_cc->pass_trace;
+  if (i) Fs->last_cc->saved_pass_trace=i;
+  Fs->last_cc->pass_trace=i;
+  return old;
+}
+
+Bool Trace(Bool val=ON)
+{//Displays assembly code output from compiler.
+  return Option(OPTf_TRACE,val);
+}
+
+Bool Echo(Bool val)
+{//Displays text as it is being compiled.
+  return Option(OPTf_ECHO,val);
+}
+
+U0 StreamPrint(U8 *fmt,...)
+{//Injects text into the compile stream. Used in #exe{} blocks.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st;
+  CCmpCtrl *cc=Fs->last_cc;
+  CStreamBlk *tmpe=cc->last_stream_blk;
+  if (tmpe!=&cc->next_stream_blk) {
+    st=MStrPrint("%s%s",tmpe->body,buf);
+    Free(tmpe->body);
+    tmpe->body=st;
+  } else
+    PrintErr("No exe{} blk\n");
+  Free(buf);
+}
+
+U0 StreamDir()
+{
+  U8 *dirname;
+  if (dirname=DirFile(Fs->last_cc->lex_include_stk->full_name)) {
+    StreamPrint("\"%s\"",dirname);
+    Free(dirname);
+  }
+}
+
+CD2I32 *LexD2I32(CCmpCtrl *cc,CD2I32 *p)
+{//Not HolyC. Sprite-like lex 2D point.
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc); //Skip (
+  p->x=LexExpressionI64(cc);
+  if (cc->token!=',')
+    LexExcept(cc,"Expecting ',' at ");
+  Lex(cc); //Skip ,
+  p->y=LexExpressionI64(cc);
+  if (cc->token!=')')
+    LexExcept(cc,"Expecting ')' at ");
+  Lex(cc); //Skip )
+  return p;
+}
+
+CD3I32 *LexD3I32(CCmpCtrl *cc,CD3I32 *p)
+{//Not HolyC. Sprite-like lex 3D point.
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc); //Skip (
+  p->x=LexExpressionI64(cc);
+  if (cc->token!=',')
+    LexExcept(cc,"Expecting ',' at ");
+  Lex(cc); //Skip ,
+  p->y=LexExpressionI64(cc);
+  if (cc->token!=',')
+    LexExcept(cc,"Expecting ',' at ");
+  Lex(cc); //Skip ,
+  p->z=LexExpressionI64(cc);
+  if (cc->token!=')')
+    LexExcept(cc,"Expecting ')' at ");
+  Lex(cc); //Skip )
+  return p;
+}
+
+U8 *CmdLinePmt()
+{
+  I64 i;
+  U8 *res,*st;
+  if (Fs->new_answer) {
+    if (Fs->answer_type&~1!=RT_I0) {
+      if (Fs->answer_type==RT_F64)
+        "%8.6fs ansf=%15.7g\n",Fs->answer_time,Fs->answer;
+      else
+        "%8.6fs ans=0x%08X=%d\n",Fs->answer_time,Fs->answer,Fs->answer;
+    } else {
+      "%8.6fs\n",Fs->answer_time;
+      Fs->answer=0;
+    }
+    Fs->new_answer=FALSE;
+  }
+  if (st=DirCur) {
+    "%s",st;
+    Free(st);
+  }
+  '>';
+  if (IsDbgMode&&IsRaw)
+    RawDr;
+
+  LBts(&Fs->task_flags,TASKf_CMD_LINE_PMT);
+  st=GetStr(,,GSF_SHIFT_ESC_EXIT);
+  LBtr(&Fs->task_flags,TASKf_CMD_LINE_PMT);
+
+  i=StrLen(st);
+  res=MAlloc(i+1+2);
+  MemCpy(res,st,i+1);
+  i--;
+  while (i>=0 && Bt(char_bmp_white_space,res[i]))
+    i--;
+  i++;
+  if (i>0 && res[i-1]==';')
+    res[i++]=';'; //The Lex goes one beyond
+  res[i++]='\n';//#define goes to '\n'
+  res[i]=0;
+
+  Free(st);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/CompilerA.HH.HTML b/public/Wb/Home/Src/Compiler/CompilerA.HH.HTML new file mode 100755 index 0000000..a120f35 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CompilerA.HH.HTML @@ -0,0 +1,437 @@ + + + + + + + + + + + +
+#help_index "Compiler/Internal"
+//Intermediate compiler codes
+#define IS_0_ARG        0
+#define IS_1_ARG        1
+#define IS_2_ARG        2
+#define IS_V_ARG        3 //Variable Arg Cnt
+
+#define IST_NULL        0
+#define IST_DEREF       1
+#define IST_ASSIGN      2
+#define IST_CMP         3
+        
+class CIntermediateStruct
+{
+  U8 arg_cnt,res_cnt,type;
+  Bool fpop,not_const,pad[3];
+  U8 *name;
+};
+
+#define IC_END                  0x00
+#define IC_NOP1                 0x01
+#define IC_END_EXP              0x02
+#define IC_NOP2                 0x03
+#define IC_LABEL                0x04
+#define IC_CALL_START           0x05
+#define IC_CALL_END             0x06
+#define IC_CALL_END2            0x07
+#define IC_RETURN_VAL           0x08
+#define IC_RETURN_VAL2          0x09
+#define IC_IMM_I64              0x0A
+#define IC_IMM_F64              0x0B
+#define IC_STR_CONST            0x0C
+#define IC_ABS_ADDR             0x0D
+#define IC_ADDR_IMPORT          0x0E
+#define IC_HEAP_GLBL            0x0F
+#define IC_SIZEOF               0x10
+#define IC_TYPE                 0x11
+#define IC_GET_LABEL            0x12
+#define IC_RBP                  0x13
+#define IC_REG                  0x14
+#define IC_FS                   0x15
+#define IC_MOV_FS               0x16
+#define IC_GS                   0x17
+#define IC_MOV_GS               0x18
+
+#define IC_LEA                  0x19
+#define IC_MOV                  0x1A
+
+#define IC_TO_I64               0x1B
+#define IC_TO_F64               0x1C
+#define IC_TO_BOOL              0x1D
+#define IC_TOUPPER              0x1E
+#define IC_HOLYC_TYPECAST       0x1F
+
+#define IC_ADDR                 0x20
+#define IC_COM                  0x21
+#define IC_NOT                  0x22
+#define IC_UNARY_MINUS          0x23
+
+#define IC_DEREF                0x24
+#define IC_DEREF_PP             0x25
+#define IC_DEREF_MM             0x26
+#define IC__PP                  0x27
+#define IC__MM                  0x28
+#define IC_PP_                  0x29
+#define IC_MM_                  0x2A
+
+#define IC_SHL                  0x2B
+#define IC_SHR                  0x2C
+#define IC_SHL_CONST            0x2D
+#define IC_SHR_CONST            0x2E
+#define IC_POWER                0x2F
+
+#define IC_MUL                  0x30
+#define IC_DIV                  0x31
+#define IC_MOD                  0x32
+
+#define IC_AND                  0x33
+
+#define IC_OR                   0x34
+#define IC_XOR                  0x35
+
+#define IC_ADD                  0x36
+#define IC_SUB                  0x37
+#define IC_ADD_CONST            0x38
+#define IC_SUB_CONST            0x39
+
+#define IC_EQU_EQU              0x3A
+#define IC_NOT_EQU              0x3B
+#define IC_LESS                 0x3C
+#define IC_GREATER_EQU          0x3D
+#define IC_GREATER              0x3E
+#define IC_LESS_EQU             0x3F
+#define IC_PUSH_CMP             0x40
+
+#define IC_AND_AND              0x41
+
+#define IC_OR_OR                0x42
+#define IC_XOR_XOR              0x43
+
+#define IC_ASSIGN               0x44
+#define IC_ASSIGN_PP            0x45
+#define IC_ASSIGN_MM            0x46
+
+#define IC_SHL_EQU              0x47
+#define IC_SHR_EQU              0x48
+#define IC_MUL_EQU              0x49
+#define IC_DIV_EQU              0x4A
+#define IC_MOD_EQU              0x4B
+#define IC_AND_EQU              0x4C
+#define IC_OR_EQU               0x4D
+#define IC_XOR_EQU              0x4E
+#define IC_ADD_EQU              0x4F
+#define IC_SUB_EQU              0x50
+
+#define IC_JMP                  0x51
+#define IC_SUB_CALL             0x52
+#define IC_SWITCH               0x53
+#define IC_NOBOUND_SWITCH               0x54
+
+#define IC_ADD_RSP              0x55
+#define IC_ADD_RSP1             0x56
+#define IC_ENTER                0x57
+#define IC_PUSH_REGS            0x58
+#define IC_POP_REGS             0x59
+#define IC_LEAVE                0x5A
+#define IC_RET                  0x5B
+
+#define IC_CALL                 0x5C
+#define IC_CALL_INDIRECT        0x5D
+#define IC_CALL_INDIRECT2       0x5E
+#define IC_CALL_IMPORT          0x5F
+#define IC_CALL_EXTERN          0x60
+
+#define IC_ASM                  0x61
+#define IC_PUSH                 0x62
+#define IC_POP                  0x63
+
+#define IC_CLFLUSH              0x64
+#define IC_INVLPG               0x65
+
+#define IC_IN_U8                0x66
+#define IC_IN_U16               0x67
+#define IC_IN_U32               0x68
+#define IC_OUT_U8               0x69
+#define IC_OUT_U16              0x6A
+#define IC_OUT_U32              0x6B
+
+#define IC_GET_RFLAGS           0x6C
+#define IC_CARRY                0x6D
+#define IC_SET_RFLAGS           0x6E
+#define IC_GET_RAX              0x6F
+#define IC_SET_RAX              0x70
+#define IC_GET_RBP              0x71
+#define IC_SET_RBP              0x72
+#define IC_GET_RSP              0x73
+#define IC_SET_RSP              0x74
+#define IC_RIP                  0x75
+
+#define IC_RDTSC                0x76
+
+#define IC_BT                   0x77
+#define IC_BTS                  0x78
+#define IC_BTR                  0x79
+#define IC_BTC                  0x7A
+#define IC_LBTS                 0x7B
+#define IC_LBTR                 0x7C
+#define IC_LBTC                 0x7D
+#define IC_BSF                  0x7E
+#define IC_BSR                  0x7F
+
+#define IC_QUE_INIT             0x80
+#define IC_QUE_INS              0x81
+#define IC_QUE_INS_REV          0x82
+#define IC_QUE_REM              0x83
+
+#define IC_STRLEN               0x84
+
+#define IC_BR_ZERO              0x85
+#define IC_BR_NOT_ZERO          0x86
+#define IC_BR_CARRY             0x87
+#define IC_BR_NOT_CARRY         0x88
+
+#define IC_BR_EQU_EQU           0x89
+#define IC_BR_NOT_EQU           0x8A
+#define IC_BR_LESS              0x8B
+#define IC_BR_GREATER_EQU       0x8C
+#define IC_BR_GREATER           0x8D
+#define IC_BR_LESS_EQU          0x8E
+
+#define IC_BR_EQU_EQU2          0x8F
+#define IC_BR_NOT_EQU2          0x90
+#define IC_BR_LESS2             0x91
+#define IC_BR_GREATER_EQU2      0x92
+#define IC_BR_GREATER2          0x93
+#define IC_BR_LESS_EQU2         0x94
+
+#define IC_BR_AND_ZERO          0x95
+#define IC_BR_AND_NOT_ZERO      0x96
+#define IC_BR_MM_ZERO           0x97
+#define IC_BR_MM_NOT_ZERO       0x98
+#define IC_BR_AND_AND_ZERO      0x99
+#define IC_BR_AND_AND_NOT_ZERO  0x9A
+#define IC_BR_OR_OR_ZERO        0x9B
+#define IC_BR_OR_OR_NOT_ZERO    0x9C
+
+#define IC_BR_BT                0x9D
+#define IC_BR_BTS               0x9E
+#define IC_BR_BTR               0x9F
+#define IC_BR_BTC               0xA0
+#define IC_BR_NOT_BT            0xA1
+#define IC_BR_NOT_BTS           0xA2
+#define IC_BR_NOT_BTR           0xA3
+#define IC_BR_NOT_BTC           0xA4
+
+#define IC_SWAP_U8              0xA5
+#define IC_SWAP_U16             0xA6
+#define IC_SWAP_U32             0xA7
+#define IC_SWAP_I64             0xA8
+
+#define IC_ABS_I64              0xA9
+#define IC_SIGN_I64             0xAA
+#define IC_MIN_I64              0xAB
+#define IC_MIN_U64              0xAC
+#define IC_MAX_I64              0xAD
+#define IC_MAX_U64              0xAE
+#define IC_MOD_U64              0xAF
+#define IC_SQR_I64              0xB0
+#define IC_SQR_U64              0xB1
+#define IC_SQR                  0xB2
+#define IC_ABS                  0xB3
+#define IC_SQRT                 0xB4
+#define IC_SIN                  0xB5
+#define IC_COS                  0xB6
+#define IC_TAN                  0xB7
+#define IC_ATAN                 0xB8
+#define IC_ICS_NUM              0xB9
+
+#define KW_INCLUDE      0
+#define KW_DEFINE       1
+#define KW_UNION        2
+#define KW_CATCH        3
+#define KW_CLASS        4
+#define KW_TRY          5
+#define KW_IF           6
+#define KW_ELSE         7
+#define KW_FOR          8
+#define KW_WHILE        9
+#define KW_EXTERN       10
+#define KW__EXTERN      11
+#define KW_RETURN       12
+#define KW_SIZEOF       13
+#define KW__INTERN      14
+#define KW_DO           15
+#define KW_ASM          16
+#define KW_GOTO         17
+#define KW_EXE          18
+#define KW_BREAK        19
+#define KW_SWITCH       20
+#define KW_START        21
+#define KW_END          22
+#define KW_CASE         23
+#define KW_DFT          24
+#define KW_PUBLIC       25
+#define KW_OFFSET       26
+#define KW_IMPORT       27
+#define KW__IMPORT      28
+#define KW_IFDEF        29
+#define KW_IFNDEF       30
+#define KW_IFAOT        31
+#define KW_IFJIT        32
+#define KW_ENDIF        33
+#define KW_ASSERT       34
+#define KW_REG          35
+#define KW_NOREG        36
+#define KW_LASTCLASS    37
+#define KW_NO_WARN      38
+#define KW_HELP_INDEX   39
+#define KW_HELP_FILE    40
+#define KW_STATIC       41
+#define KW_LOCK         42
+#define KW_DEFINED      43
+#define KW_INTERRUPT    44
+#define KW_HASERRCODE   45
+#define KW_ARGPOP       46
+#define KW_NOARGPOP     47
+
+#define AKW_ALIGN       64
+#define AKW_ORG         65
+#define AKW_I0          66
+#define AKW_I8          67
+#define AKW_I16         68
+#define AKW_I32         69
+#define AKW_I64         70
+#define AKW_U0          71
+#define AKW_U8          72
+#define AKW_U16         73
+#define AKW_U32         74
+#define AKW_U64         75
+#define AKW_F64         76
+#define AKW_DU8         77
+#define AKW_DU16        78
+#define AKW_DU32        79
+#define AKW_DU64        80
+#define AKW_DUP         81
+#define AKW_USE16       82
+#define AKW_USE32       83
+#define AKW_USE64       84
+#define AKW_IMPORT      85
+#define AKW_LIST        86
+#define AKW_NOLIST      87
+#define AKW_BINFILE     88
+#define KW_KWS_NUM      89
+
+#define CMP_TEMPLATE_INC        0x00
+#define CMP_TEMPLATE_DEC        0x01
+#define CMP_TEMPLATE_MOD        0x02
+#define CMP_TEMPLATE_LESS       0x03
+#define CMP_TEMPLATE_GREATER    0x04
+#define CMP_TEMPLATE_LESS_EQU   0x05
+#define CMP_TEMPLATE_GREATER_EQU 0x06
+#define CMP_TEMPLATE_STRLEN     0x07
+#define CMP_TEMPLATE_RDTSC      0x08
+#define CMP_TEMPLATE_SIGN_I64   0x09
+#define CMP_TEMPLATE_FSTP       0x0A
+#define CMP_TEMPLATE_FLD        0x0B
+#define CMP_TEMPLATE_SQR        0x0C
+#define CMP_TEMPLATE_ABS        0x0D
+#define CMP_TEMPLATE_SQRT       0x0E
+#define CMP_TEMPLATE_SIN        0x0F
+#define CMP_TEMPLATE_COS        0x10
+#define CMP_TEMPLATE_TAN        0x11
+#define CMP_TEMPLATE_ATAN       0x12
+
+#define ASSOCF_LEFT     1
+#define ASSOCF_RIGHT    2
+#define ASSOC_MASK      3
+
+#define PREC_NULL               0x00
+#define PREC_TERM               0x04
+#define PREC_UNARY_POST         0x08
+#define PREC_UNARY_PRE          0x0C
+#define PREC_EXP                0x10
+#define PREC_MUL                0x14
+#define PREC_AND                0x18
+#define PREC_XOR                0x1C
+#define PREC_OR                 0x20
+#define PREC_ADD                0x24
+#define PREC_CMP                0x28
+#define PREC_CMP2               0x2C
+#define PREC_AND_AND            0x30
+#define PREC_XOR_XOR            0x34
+#define PREC_OR_OR              0x38
+#define PREC_ASSIGN             0x3C
+
+#define PREC_MAX                0x40
+
+//Function/static/public flags
+#define FSF_PUBLIC              0x01
+#define FSF_ASM                 0x02
+#define FSF_STATIC              0x04
+#define FSF__                   0x08
+#define FSF_INTERRUPT           (1<<Ff_INTERRUPT)
+#define FSF_HASERRCODE          (1<<Ff_HASERRCODE)
+#define FSF_ARGPOP              (1<<Ff_ARGPOP)
+#define FSF_NOARGPOP            (1<<Ff_NOARGPOP)
+#define FSG_FUN_FLAGS1 (FSF_INTERRUPT|FSF_HASERRCODE|FSF_ARGPOP|FSF_NOARGPOP)
+#define FSG_FUN_FLAGS2 (FSG_FUN_FLAGS1|FSF_PUBLIC)
+
+//Byte 0
+#define PRS0_NULL               0x000000
+#define PRS0__EXTERN            0x000001
+#define PRS0__INTERN            0x000002
+#define PRS0__IMPORT            0x000003
+#define PRS0_EXTERN             0x000004
+#define PRS0_IMPORT             0x000005
+#define PRS0_TYPECAST           0x000006
+
+//Byte 1
+#define PRS1B_NULL              0
+#define PRS1_NULL               0x000000
+#define PRS1B_LOCAL_VAR         1
+#define PRS1_LOCAL_VAR          0x000100
+#define PRS1B_FUN_ARG           2
+#define PRS1_FUN_ARG            0x000200
+#define PRS1B_CLASS             3
+#define PRS1_CLASS              0x000300
+#define PRS1B_STATIC_LOCAL_VAR  4
+#define PRS1_STATIC_LOCAL_VAR   0x000400
+#define PRS1B__EXTERN_IMPORT    5
+#define PRS1_NOT_REALLY__EXTERN 0x000500
+
+#define PRSF_UNION              0x010000
+
+class COptReg
+{
+  I64   offset;
+  CMemberLst *m;
+};
+
+#define CMPF_ASM_BLK            1
+#define CMPF_ONE_ASM_INS        2
+#define CMPF_LEX_FIRST          4
+#define CMPF_PRS_SEMICOLON      8
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Compiler/CompilerB.HH.HTML b/public/Wb/Home/Src/Compiler/CompilerB.HH.HTML new file mode 100755 index 0000000..3182ff0 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/CompilerB.HH.HTML @@ -0,0 +1,110 @@ + + + + + + + + + + + +
+#help_index "Compiler"
+extern U0 CInit(Bool first);
+public extern I64 ExeFile(U8 *name,I64 ccf_flags=0);
+public extern I64 ExeFile2(U8 *name,I64 ccf_flags=0);
+public extern I64 ExePrint(U8 *fmt,...);
+public extern I64 ExePrint2(U8 *fmt,...);
+public extern I64 ExePutS(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0,
+        CLexHashTableContext *htc=NULL);
+public extern I64 ExePutS2(U8 *buf,U8 *filename=NULL,I64 ccf_flags=0);
+public _extern _LAST_FUN I64 LastFun(I64 argc,I64 *argv);
+public extern I64 RunFile(U8 *name,I64 ccf_flags=0,...);
+public extern I64 RunFile2(U8 *name,I64 ccf_flags=0,...);
+public extern CCmpGlbls cmp;
+
+#help_index "Compiler/Directive"
+#help_file "::/Doc/Directives"
+public extern Bool Echo(Bool val);
+public extern Bool GetOption(I64 num);
+public extern I64 PassTrace(I64 i=0b1001111101);
+extern U0 StreamDir();
+public extern I64 StreamExePrint(U8 *fmt,...);
+public extern U0 StreamPrint(U8 *fmt,...);
+public extern Bool Trace(Bool val=ON);
+
+#help_index "Compiler/Lex"
+#help_file "::/Doc/Lex"
+extern U0 ClassMemberLstDel(CHashClass *c);
+public extern U0 CmpCtrlDel(CCmpCtrl *cc);
+public extern CCmpCtrl *CmpCtrlNew(U8 *buf=NULL,I64 flags=0,U8 *filename=NULL);
+public extern I64 CmpCtrlSize(CCmpCtrl *cc);
+public extern I64 IsLexExpression2Bin(
+        CCmpCtrl *cc,U8 **machine_code); //FALSE=no err
+public extern I64 Lex(CCmpCtrl *cc);
+public extern U0 LexAttachDoc(CCmpCtrl *cc,CLexFile *tmpf=NULL,
+        CDoc *doc=NULL,U8 *abs_filename=NULL,CDocEntry *doc_e=NULL,I64 col=0);
+public extern CD2I32 *LexD2I32(CCmpCtrl *cc,CD2I32 *p);
+public extern CD3I32 *LexD3I32(CCmpCtrl *cc,CD3I32 *p);
+public extern U0 LexExcept(CCmpCtrl *cc,U8 *str=NULL);
+public extern I64 LexExpression(CCmpCtrl *cc);
+public extern U8 *LexExpression2Bin(CCmpCtrl *cc,I64 *_type=NULL);
+public extern F64 LexExpressionF64(CCmpCtrl *cc);
+public extern I64 LexExpressionI64(CCmpCtrl *cc);
+public extern U8 *LexExtStr(CCmpCtrl *cc,I64 *_size=NULL,Bool lex_next=TRUE);
+public extern U8 *LexFirstRem(CCmpCtrl *cc,U8 *marker,I64 _len=NULL);
+public extern I64 LexGetChar(CCmpCtrl *cc);
+public extern U0 LexPopNoRestore(CCmpCtrl *cc);
+public extern U0 LexPopRestore(CCmpCtrl *cc);
+public extern U0 LexPush(CCmpCtrl *cc);
+public extern U0 LexPutLine(CCmpCtrl *cc,U8 *start);
+public extern U0 LexPutPos(CCmpCtrl *cc);
+public extern U0 LexPutToken(CCmpCtrl *cc);
+public extern U0 LexSkipEol(CCmpCtrl *cc);
+public extern U8 *LexStmt2Bin(
+        CCmpCtrl *cc,I64 *_type,I64 cmp_flags=CMPF_PRS_SEMICOLON);
+public extern U0 LexWarn(CCmpCtrl *cc,U8 *str=NULL);
+extern CMemberLst *MemberClassBaseFind(
+        CHashClass *needle_class,CHashClass *haystack_class);
+public extern CMemberLst *MemberFind(U8 *needle_str,CHashClass *haystack_class);
+extern U0 MemberLstDel(CMemberLst *tmpm);
+public extern I64 MemberMetaData(U8 *st,CMemberLst *ml);
+public extern CMemberLstMeta *MemberMetaFind(U8 *st,CMemberLst *ml);
+public extern CHashClass *OptClassFwd(CHashClass *tmpc);
+public extern I64 PrsKeyWord(CCmpCtrl *cc);
+
+#help_index "Compiler;Cmd Line (Typically)"
+extern I64 Cmp(U8 *filename,
+        U8 *map_name=NULL,U8 *out_name=NULL,U8 mapfile_drv_let=0);
+
+#help_index "Debugging/Unassemble"
+public extern U8 *U(U8 *rip,I64 cnt=20,I64 seg_size=64);
+public extern U0 Ui(U8 *buf,U8 **_rip,I64 seg_size=64,
+        I64 *_jmp_dst=NULL,Bool just_ins=FALSE);
+public extern I64 Un(U8 *rip,I64 cnt=0x80,I64 seg_size=64);
+extern CUAsmGlbls uasm;
+
+#help_index "Hash/System"
+public extern I64 HashEntrySize(CHashSrcSym *tmph);
+public extern I64 HashEntrySize2(CHashSrcSym *tmph);
+public extern I64 HashTableSize2(CHashTable *table);
+
+ diff --git a/public/Wb/Home/Src/Compiler/Lex.HC.HTML b/public/Wb/Home/Src/Compiler/Lex.HC.HTML new file mode 100755 index 0000000..0e8b96d --- /dev/null +++ b/public/Wb/Home/Src/Compiler/Lex.HC.HTML @@ -0,0 +1,1226 @@ + + + + + + + + + + + +
+CLexFile *LexFilePush(CCmpCtrl *cc)
+{//#include file push.
+  CLexFile *res=CAlloc(sizeof(CLexFile));
+  if (res->next=cc->lex_include_stk)
+    res->depth=res->next->depth+1;
+  else
+    res->depth=-1; //Include depth starts with -1.
+  return cc->lex_include_stk=res;
+}
+
+CLexFile *LexFilePop(CCmpCtrl *cc)
+{//#include file pop.
+  CLexFile *tmpf;
+  if (tmpf=cc->lex_include_stk) {
+    if ((cc->lex_include_stk=tmpf->next) || !(cc->flags & CCF_DONT_FREE_BUF)) {
+      if (tmpf->flags & LFSF_DOC) {
+        if (tmpf->doc)
+          DocDel(tmpf->doc);
+      } else
+        Free(tmpf->buf);;
+    }
+    Free(tmpf->full_name);
+    Free(tmpf);
+  }
+  return cc->lex_include_stk;
+}
+
+CCmpCtrl *CmpCtrlNew(U8 *buf=NULL,I64 flags=0,U8 *filename=NULL)
+{//MAlloc and Init CCmpCtrl.
+//Frees buf in CmpCtrlDel unless CCF_DONT_FREE_BUF flag is set.
+  //FileName is for error reporting.  If files are #included,
+  //new names are used.  See Psalmody CmpCtrlNew.
+  CCmpCtrl *cc=CAlloc(sizeof(CCmpCtrl));
+  CLexFile *tmpf;
+  QueInit(cc);
+  cc->flags=flags;
+  cc->opts=1<<OPTf_WARN_UNUSED_VAR|1<<OPTf_WARN_HEADER_MISMATCH;
+  cc->htc.hash_mask=HTG_TYPE_MASK-HTT_IMPORT_SYS_SYM;
+  cc->htc.define_hash_table=cc->htc.hash_table_lst=
+        cc->htc.glbl_hash_table=cc->htc.local_hash_table=Fs->hash_table;
+  if (flags&CCF_KEEP_AT_SIGN)
+    cc->char_bmp_alpha_numeric=char_bmp_alpha_numeric_no_at;
+  else
+    cc->char_bmp_alpha_numeric=char_bmp_alpha_numeric;
+  tmpf=LexFilePush(cc);
+  QueInit(&cc->next_stream_blk);
+  if (filename)
+    tmpf->full_name=FileNameAbs(filename);
+  else
+    tmpf->full_name=StrNew(blkdev.tmp_filename);
+  if (flags & CCF_PMT)
+    buf=CAlloc(8);
+  tmpf->buf=tmpf->buf_ptr=tmpf->line_start=cc->cur_buf_ptr=buf;
+  tmpf->line_num=1;
+  return cc;
+}
+
+U0 CmpCtrlDel(CCmpCtrl *cc)
+{//Free CCmpCtrl.
+  while (LexFilePop(cc));
+  LinkedLstDel(cc->lex_prs_stk);
+  LinkedLstDel(cc->htc.next);
+  Free(cc->ps);
+  Free(cc->cur_str);
+  Free(cc->cur_help_idx);
+  Free(cc->dollar_buf);
+  Free(cc);
+}
+
+I64 CmpCtrlSize(CCmpCtrl *cc)
+{//Mem size of CCmpCtrl and its members.
+  CLexFile *tmpf=cc->lex_include_stk;
+  I64 res=0;
+  while (tmpf) {
+    if (tmpf->next || !(cc->flags & CCF_DONT_FREE_BUF)) {
+      if (tmpf->flags & LFSF_DOC) {
+        if (tmpf->doc)
+          res+=DocSize(tmpf->doc);
+      } else
+        res+=MSize2(tmpf->buf);
+    }
+    res+=MSize2(tmpf->full_name);
+    res+=MSize2(tmpf);
+    tmpf=tmpf->next;
+  }
+  res+=MSize2(cc->cur_str);
+  res+=MSize2(cc);
+  return res;
+}
+
+U32 lex_zeros=0;
+
+Bool LexDollar(CCmpCtrl *cc,CDoc *doc,CDocEntry *doc_e)
+{
+  U8 *st;
+  if (cc->flags&CCF_IN_QUOTES) {
+    Free(cc->dollar_buf);
+    st=Doc2PlainText(doc,doc_e);
+    cc->dollar_buf=MStrPrint("$%$Q$",st);
+    cc->dollar_cnt=2;
+    Free(st);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+I64 LexGetChar(CCmpCtrl *cc)
+{//Get one char from stream. Allow put-back one.
+  U8 *ptr,*src;
+  CLexFile *tmpf;
+  CDoc *doc;
+  CDocEntry *doc_e;
+  if (!Btr(&cc->flags,CCf_USE_LAST_U16)) {
+lgc_start1:
+    if (!(src=cc->cur_buf_ptr++)) {
+      cc->cur_buf_ptr=NULL;
+      goto lgc_here;
+    }
+    switch [cc->last_U16=*src++] {
+      case 0:
+lgc_here:
+        tmpf=cc->lex_include_stk;
+        if (tmpf->flags & LFSF_DOC) {
+          doc=tmpf->doc;
+          doc_e=tmpf->cur_entry;
+          doc_e=doc_e->next;
+lgc_start2:
+          if (doc_e!=doc) {
+            tmpf->cur_entry=doc_e;
+            switch [doc_e->type_u8] {
+              case DOCT_TEXT:
+                if (doc_e->de_flags & ~(DOCEF_TAG|DOCEF_DEFINE|DOCEF_TAG_CB|
+                      DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|
+                      DOCEF_SKIP|DOCEF_FILTER_SKIP) &&
+                      LexDollar(cc,doc,doc_e) && *(src=cc->dollar_buf)) {
+                  tmpf->line_num=doc_e->y+1;
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                } else if (*(src=doc_e->tag))
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                else {
+                  doc_e=doc_e->next;
+                  goto lgc_start2;
+                }
+                break;
+              case DOCT_NEW_LINE:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                tmpf->line_start=doc_e->next;
+                tmpf->line_num=doc_e->y+2;//+1 because NEW_LINE is on prev line
+//+1 because doc y starts at zero
+                cmp.compiled_lines++;
+                cc->last_U16='\n';
+                goto lgc_done;
+              case DOCT_TAB:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                tmpf->line_num=doc_e->y+1;
+                cc->last_U16='\t';
+                goto lgc_done;
+              case DOCT_INS_BIN:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                tmpf->line_num=doc_e->y+1;
+                Free(cc->cur_str);
+                cc->cur_str=NULL;
+                cc->cur_str_len=0;
+                if (doc_e->bin_data) {
+                  ptr=MAlloc(doc_e->bin_data->size);
+                  if (doc_e->bin_data->data)
+                    MemCpy(ptr,doc_e->bin_data->data,doc_e->bin_data->size);
+                  cc->cur_str=ptr;
+                  cc->cur_str_len=doc_e->bin_data->size;
+                }
+                cc->last_U16=TK_INS_BIN;
+                goto lgc_done;
+              case DOCT_INS_BIN_SIZE:
+                tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                if (doc_e->bin_data)
+                  cc->cur_i64=doc_e->bin_data->size;
+                else
+                  cc->cur_i64=0;
+                tmpf->line_num=doc_e->y+1;
+                cc->last_U16=TK_INS_BIN_SIZE;
+                goto lgc_done;
+              case DOCT_SHIFTED_Y:
+                if (LexDollar(cc,doc,doc_e) && *(src=cc->dollar_buf)) {
+                  tmpf->line_num=doc_e->y+1;
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                } else {
+                  tmpf->buf_ptr=cc->cur_buf_ptr=&lex_zeros;
+                  tmpf->line_num=doc_e->y+1;
+                  if (doc_e->attr<0)
+                    cc->last_U16=TK_SUPERSCRIPT;
+                  else if (doc_e->attr>0)
+                    cc->last_U16=TK_SUBSCRIPT;
+                  else
+                    cc->last_U16=TK_NORMALSCRIPT;
+                  goto lgc_done;
+                }
+                break;
+              case DOCT_MARKER:
+              case DOCT_CURSOR:
+                doc_e=doc_e->next;
+                goto lgc_start2;
+              case 0xFF: //nobound switch
+              default:
+                if (LexDollar(cc,doc,doc_e) && *(src=cc->dollar_buf)) {
+                  tmpf->line_num=doc_e->y+1;
+                  tmpf->buf_ptr=cc->cur_buf_ptr=src;
+                } else {
+                  doc_e=doc_e->next;
+                  goto lgc_start2;
+                }
+            }
+          }
+          if (doc_e!=doc)
+            goto lgc_start1;
+          tmpf->cur_entry=doc->head.last; //When take next, will still be end.
+        }
+        tmpf=cc->lex_include_stk;
+        if (tmpf->next) {
+          tmpf=LexFilePop(cc);
+          cc->cur_buf_ptr=tmpf->buf_ptr;
+          cc->flags&=~CCF_USE_LAST_U16;
+          if (!(cc->last_U16=tmpf->last_U16))
+            goto lgc_start1;
+        } else {
+          if (cc->flags & CCF_PMT) {
+            Free(tmpf->buf);
+            ptr=CmdLinePmt;
+            if (StrCmp(ptr,"\n") && !cc->pmt_line++ && !StrCmp(ptr,"?\n") &&
+                cc->flags & CCF_QUESTION_HELP) {
+              Free(ptr);
+              ptr=StrNew("Help;;\n");
+            }
+            tmpf->buf=tmpf->buf_ptr=tmpf->line_start=cc->cur_buf_ptr=ptr;
+            goto lgc_start1;
+          } else {
+            if (src)
+              cc->cur_buf_ptr=src-1;
+            cc->last_U16=TK_EOF;
+          }
+        }
+        break;
+      case CH_CURSOR:
+        goto lgc_start1;
+      case '\n':
+        tmpf=cc->lex_include_stk;
+        if (!(tmpf->flags & LFSF_DOC)) {
+          tmpf->line_num++;
+          cmp.compiled_lines++;
+          tmpf->line_start=src;
+        }
+        break;
+      case 0xFF: //nobound switch
+    }
+lgc_done:
+    if (cc->last_U16==CH_SHIFT_SPACE)
+      cc->last_U16=CH_SPACE;
+    if (cc->opts & OPTF_ECHO &&
+          cc->last_U16<256 && Bt(char_bmp_printable,cc->last_U16))
+      '' cc->last_U16;
+  }
+  return cc->last_U16;
+}
+
+U0 LexSkipEol(CCmpCtrl *cc)
+{//LexGetChar to NULL until end-of-line.
+  I64 ch;
+  do ch=LexGetChar(cc);
+  while (Bt(char_bmp_non_eol,ch));
+}
+
+U8 *LexFirstRem(CCmpCtrl *cc,U8 *marker,I64 _len=NULL)
+{//LexGetChar() chars making str until marker.
+  U8 *res,*ptr;
+  CQueVectU8 *tmpv=QueVectU8New;
+  I64 i,len=0;
+  while (TRUE) {
+    i=LexGetChar(cc);
+    if (!i||StrOcc(marker,i))
+      break;
+    QueVectU8Put(tmpv,len++,i);
+  }
+  if (i)
+    Bts(&cc->flags,CCf_USE_LAST_U16);
+  res=ptr=MAlloc(len+1);
+  for (i=0;i<len;i++)
+    *ptr++=QueVectU8Get(tmpv,i);
+  *ptr=0;
+  QueVectU8Del(tmpv);
+  if (_len) *_len=len;
+  return res;
+}
+
+U0 LexIncludeStr(CCmpCtrl *cc,U8 *abs_filename,U8 *src,Bool actual_file)
+{
+  LexBackupLastChar(cc);
+  CLexFile *tmpf=LexFilePush(cc);
+  if (actual_file)
+    tmpf->full_name=StrNew(abs_filename);
+  else
+    tmpf->full_name=StrNew(blkdev.tmp_filename);
+  tmpf->line_num=1;
+  tmpf->buf=tmpf->buf_ptr=tmpf->line_start=cc->cur_buf_ptr=src;
+}
+
+CDoc *LexDocRead(U8 *abs_filename,I64 flags)
+{
+  CDoc *doc=DocNew(abs_filename);
+  U8 *src;
+  I64 size=0;
+  doc->flags|=flags;
+  src=FileRead(abs_filename,&size);
+  if (!src || !size) {
+    Free(src);
+    src=CAlloc(1);
+    size=0;
+  }
+  DocLoad(doc,src,size);
+  Free(src);
+  return doc;
+}
+
+I64 cmp_type_flags_src_code[(DOCT_TYPES_NUM+63)/64]={
+  1<<DOCT_TEXT|1<<DOCT_TAB|1<<DOCT_INS_BIN|1<<DOCT_INS_BIN_SIZE};
+
+U0 LexAttachDoc(CCmpCtrl *cc,CLexFile *tmpf=NULL,
+        CDoc *doc=NULL,U8 *abs_filename=NULL,CDocEntry *doc_e=NULL,I64 col=0)
+{//Start lexing doc. Give either doc or abs_filename.
+  if (!doc)
+    doc=LexDocRead(abs_filename,DOCF_DBL_DOLLARS);
+  if (!tmpf) {
+    LexBackupLastChar(cc);
+    tmpf=LexFilePush(cc);
+  }
+  if (!doc_e)
+    doc_e=doc->head.next;
+  tmpf->full_name=StrNew(doc->filename.name);
+  tmpf->doc=doc;
+  while (doc_e!=doc) {
+    if (Bt(cmp_type_flags_src_code,doc_e->type_u8))
+      break;
+    doc_e=doc_e->next;
+    col=doc_e->min_col;
+  }
+  if (doc_e!=doc) {
+    col=ClampI64(col,doc_e->min_col,doc_e->max_col);
+    tmpf->line_start=doc_e;
+    tmpf->buf=NULL;
+    tmpf->line_num=doc_e->y+1;
+    if (doc_e->type_u8==DOCT_TEXT) {
+      tmpf->cur_entry=doc_e;
+      tmpf->buf_ptr=doc_e->tag;
+    } else {
+      tmpf->cur_entry=doc_e->last; //TODO: might be problem at begin of file
+      tmpf->buf_ptr=&lex_zeros;
+    }
+    tmpf->flags=LFSF_DOC;
+  } else {//TODO: DocDel(doc)?
+    col=0;
+    tmpf->buf=tmpf->buf_ptr=tmpf->line_start=CAlloc(1);
+    tmpf->line_num=1;
+    tmpf->flags=0;
+  }
+  cc->cur_buf_ptr=tmpf->buf_ptr+col;
+  tmpf->last_U16=0;
+}
+
+I64 LexInStr(CCmpCtrl *cc,U8 *buf,I64 size,Bool *done)
+{
+  I64 i=0,j,k,ch;
+  *done=TRUE;
+  while (i<size-1) {
+    ch=LexGetChar(cc);
+    if (!ch || ch=='"') {
+      buf[i++]=0;
+      return i;
+    } else if (ch=='\\') {
+      switch (ch=LexGetChar(cc)) {
+        case '0':
+          buf[i++]=0;
+          break;
+        case '\'':
+          buf[i++]='\'';
+          break;
+        case '\`':
+          buf[i++]='\`';
+          break;
+        case '\\':
+          buf[i++]='\\';
+          break;
+        case '"':
+          buf[i++]='"';
+          break;
+        case 'd':
+          buf[i++]='$';
+          break;
+        case 'n':
+          buf[i++]='\n';
+          break;
+        case 'r':
+          buf[i++]='\r';
+          break;
+        case 't':
+          buf[i++]='\t';
+          break;
+        case 'x':
+        case 'X':
+          j=0;
+          for (k=0;k<2;k++) {
+            ch=ToUpper(LexGetChar(cc));
+            if (Bt(char_bmp_hex_numeric,ch)) {
+              if (ch<='9')
+                j=j<<4+ch-'0';
+              else
+                j=j<<4+ch-'A'+10;
+            } else {
+              cc->flags|=CCF_USE_LAST_U16;
+              break;
+            }
+          }
+          buf[i++]=j;
+          break;
+        default:
+          cc->flags|=CCF_USE_LAST_U16;
+          buf[i++]='\\';
+      }
+    } else if (ch=='$') {
+      buf[i++]='$';
+      if (cc->dollar_cnt)
+        cc->dollar_cnt--;
+      else if (LexGetChar(cc)!='$') {
+        cc->dollar_cnt=1;
+        cc->flags|=CCF_USE_LAST_U16;
+      }
+    } else
+      buf[i++]=ch;
+  }
+  *done=FALSE;
+  return i;
+}
+
+I64 Lex(CCmpCtrl *cc)
+{//Fetch next token.
+  I64 i,j,k,l,ch;
+  CHash *tmph;
+  Bool str_done,in_str,neg_e;
+  U8 *fbuf,*buf2,*buf3,buf[STR_LEN];
+  cc->last_line_num=cc->lex_include_stk->line_num;
+  while (TRUE) {
+lex_cont:
+    switch [ch=LexGetChar(cc)] {
+      case 0:
+        return cc->token=TK_EOF;
+      case TK_SUPERSCRIPT:
+        ch='>';
+        goto lex_ident;
+      case TK_SUBSCRIPT:
+        ch='<';
+        goto lex_ident;
+      case TK_NORMALSCRIPT:
+        ch='=';
+        goto lex_ident;
+      case '@':
+        if (cc->flags&CCF_KEEP_AT_SIGN) {
+          cc->token=ch;
+          goto lex_end;
+        }
+      case 'A'...'Z':
+      case 'a'...'z':
+      case '_':
+      case 128...255:
+lex_ident:
+        i=0;
+        buf[i++]=ch;
+        while (TRUE) {
+          if (i>=STR_LEN)
+            LexExcept(cc,"Ident limited to STR_LEN chars at ");
+          else if (!(ch=LexGetChar(cc)))
+            break;
+          else if (Bt(cc->char_bmp_alpha_numeric,ch))
+            buf[i++]=ch;
+          else if (ch==TK_SUPERSCRIPT)
+            buf[i++]='>';
+          else if (ch==TK_SUBSCRIPT)
+            buf[i++]='<';
+          else if (ch==TK_NORMALSCRIPT)
+            buf[i++]='=';
+          else {
+            cc->flags|=CCF_USE_LAST_U16;
+            break;
+          }
+        }
+        buf[i++]=0;
+        tmph=NULL;
+        if (cc->htc.local_var_lst)
+          cc->local_var_entry=MemberFind(buf,cc->htc.local_var_lst);
+        else
+          cc->local_var_entry=NULL;
+        if (!cc->local_var_entry && cc->htc.hash_table_lst)
+          tmph=HashFind(buf,cc->htc.hash_table_lst,cc->htc.hash_mask);
+        if (tmph)
+          j=tmph->type;
+        else
+          j=0;
+        if (j & HTT_DEFINE_STR && !(cc->flags & CCF_NO_DEFINES)) {
+          LexIncludeStr(cc,
+                tmph->str,StrNew(tmph(CHashDefineStr *)->data),FALSE);
+          cc->lex_include_stk->flags|=LFSF_DEFINE;
+        } else {
+          cc->hash_entry=tmph;
+          Free(cc->cur_str);
+          cc->cur_str=StrNew(buf);
+          cc->cur_str_len=i;
+          cc->token=TK_IDENT;
+          goto lex_end;
+        }
+        break;
+      case '0'...'9':
+        i=ch-'0';
+        ch=ToUpper(LexGetChar(cc));
+        if (ch=='X') {
+          while (TRUE) {
+            ch=ToUpper(LexGetChar(cc));
+            if (Bt(char_bmp_hex_numeric,ch)) {
+              if (ch<='9')
+                i=i<<4+ch-'0';
+              else
+                i=i<<4+ch-'A'+10;
+            } else {
+              cc->cur_i64=i;
+              cc->flags|=CCF_USE_LAST_U16;
+              cc->token=TK_I64;
+              goto lex_end;
+            }
+          }
+        } else if (ch=='B') {
+          while (TRUE) {
+            ch=LexGetChar(cc);
+            if (ch=='0')
+              i=i<<1;
+            else if (ch=='1')
+              i=i<<1+1;
+            else {
+              cc->cur_i64=i;
+              cc->flags|=CCF_USE_LAST_U16;
+              cc->token=TK_I64;
+              goto lex_end;
+            }
+          }
+        }
+        while (TRUE) {
+          if (Bt(char_bmp_dec_numeric,ch))
+            i=i*10+ch-'0';
+          else {
+            if (ch=='.' || ch=='e' || ch=='E') break;
+lex_is_int:
+            cc->cur_i64=i;
+            cc->flags|=CCF_USE_LAST_U16;
+            cc->token=TK_I64;
+            goto lex_end;
+          }
+          ch=LexGetChar(cc);
+        }
+        if (ch=='.') {
+          ch=LexGetChar(cc);
+          if (ch=='.') {
+            cc->flags|=CCF_LAST_WAS_DOT;
+            goto lex_is_int;
+          }
+        }
+lex_float_start:
+        k=0;
+        while (TRUE) {
+          if (Bt(char_bmp_dec_numeric,ch)) {
+            i=i*10+ch-'0';
+            k++;
+          } else {
+            if (ch=='e' || ch=='E')
+              break;
+            cc->cur_f64=i*Pow10I64(-k);
+            cc->flags|=CCF_USE_LAST_U16;
+            cc->token=TK_F64;
+            goto lex_end;
+          }
+          ch=LexGetChar(cc);
+        }
+        ch=LexGetChar(cc);
+        neg_e=FALSE;
+        if (ch=='-') {
+          neg_e=TRUE;
+          ch=LexGetChar(cc);
+        }
+        j=0;
+        while (TRUE) {
+          if (Bt(char_bmp_dec_numeric,ch))
+            j=j*10+ch-'0';
+          else {
+            if (neg_e)
+              cc->cur_f64=i*Pow10I64(-j-k);
+            else
+              cc->cur_f64=i*Pow10I64(j-k);
+            cc->flags|=CCF_USE_LAST_U16;
+            cc->token=TK_F64;
+            goto lex_end;
+          }
+          ch=LexGetChar(cc);
+        }
+        break;
+      case '"':
+        cc->flags|=CCF_IN_QUOTES;
+        buf2=NULL;
+        i=0;
+        do {
+          j=LexInStr(cc,buf,STR_LEN,&str_done);
+          buf3=MAlloc(i+j);
+          if (buf2) {
+            MemCpy(buf3,buf2,i);
+            Free(buf2);
+            buf2=buf3;
+            MemCpy(buf2+i,buf,j);
+          } else {
+            buf2=buf3;
+            MemCpy(buf2,buf,j);
+          }
+          i+=j;
+        } while (!str_done);
+        Free(cc->cur_str);
+        cc->cur_str=MAlloc(i);
+        MemCpy(cc->cur_str,buf2,i);
+        Free(buf2);
+        cc->cur_str_len=i;
+        cc->flags&=~CCF_IN_QUOTES;
+        cc->token=TK_STR;
+        goto lex_end;
+      case '\'':
+        if (cc->flags&CCF_NO_CHAR_CONST)
+          break;
+        k=0;
+        for (j=0;j<8;j++) {
+          if (!(ch=LexGetChar(cc)) || ch=='\'')
+            break;
+          if (ch=='\\') {
+            switch (ch=LexGetChar(cc)) {
+              case '0':         k.u8[j]=0;      break;
+              case '\'':        k.u8[j]='\'';   break;
+              case '\`':        k.u8[j]='\`';   break;
+              case '"':         k.u8[j]='"';    break;
+              case '\\':        k.u8[j]='\\';   break;
+              case 'd':         k.u8[j]='$';    break;
+              case 'n':         k.u8[j]='\n';   break;
+              case 'r':         k.u8[j]='\r';   break;
+              case 't':         k.u8[j]='\t';   break;
+              case 'x':
+              case 'X':
+                i=0;
+                for (l=0;l<2;l++) {
+                  ch=ToUpper(LexGetChar(cc));
+                  if (Bt(char_bmp_hex_numeric,ch)) {
+                    if (ch<='9')
+                      i=i<<4+ch-'0';
+                    else
+                      i=i<<4+ch-'A'+10;
+                  } else {
+                    cc->flags|=CCF_USE_LAST_U16;
+                    break;
+                  }
+                }
+                k.u8[j]=i;
+                break;
+              default:
+                k.u8[j]='\\';
+                cc->flags|=CCF_USE_LAST_U16;
+            }
+          } else if (ch=='$') {
+            ch=LexGetChar(cc);
+            k.u8[j]='$';
+            if (ch!='$')
+              cc->flags|=CCF_USE_LAST_U16;
+          } else
+            k.u8[j]=ch;
+        }
+        if (ch!='\'' && (ch=LexGetChar(cc)) && ch!='\'')
+          LexExcept(cc,"Char const limited to 8 chars at ");
+        cc->cur_i64=k;
+        cc->token=TK_CHAR_CONST;
+        goto lex_end;
+      case '#':
+        if (cc->flags&CCF_KEEP_SIGN_NUM) {
+          cc->token=ch;
+          goto lex_end;
+        }
+        if (Lex(cc)!=TK_IDENT)  //skip '#'
+          goto lex_end;
+        if (!(tmph=cc->hash_entry))
+          goto lex_end;
+        if (!(tmph->type & HTT_KEYWORD))
+          goto lex_end;
+        switch (i=tmph(CHashGeneric *)->user_data0) {
+          case KW_INCLUDE:
+            if (Lex(cc)!=TK_STR)
+              goto lex_end;
+            fbuf=ExtDft(cc->cur_str,"HC.Z");
+            buf2=FileNameAbs(fbuf);
+            Free(fbuf);
+            if (Bt(&sys_run_level,RLf_DOC))
+              LexAttachDoc(cc,,,buf2);
+            else
+              LexIncludeStr(cc,buf2,FileRead(buf2),TRUE);
+            Free(buf2);
+            break;
+          case KW_DEFINE:
+            cc->flags|=CCF_NO_DEFINES;
+            if (Lex(cc)==TK_IDENT) {
+              tmph=CAlloc(sizeof(CHashDefineStr));
+              tmph->str=cc->cur_str;
+              cc->cur_str=0;
+              tmph->type=HTT_DEFINE_STR;
+              HashSrcFileSet(cc,tmph);
+
+              do ch=LexGetChar(cc); //skip space between define name and start
+              while (Bt(char_bmp_non_eol_white_space,ch));
+
+              i=j=0;
+              buf2=NULL;
+              if (ch) {
+                in_str=FALSE;
+                do {
+                  if (ch=='\\') {
+                    if (ch=LexGetChar(cc)) {
+                      if (ch!='\r' && ch!='\n') {
+                        buf[j++]='\\';
+                        buf[j++]=ch;
+                      } else if (ch=='\r' && LexGetChar(cc)!='\n')
+                        cc->flags|=CCF_USE_LAST_U16;
+                    } else {
+                      buf[j++]='\\';
+                      break;
+                    }
+                  } else if (ch!='\n') {
+                    if (ch=='\"')
+                      in_str=!in_str;
+                    buf[j++]=ch;
+                  } else
+                    break;
+                  while (ch=LexGetChar(cc)) {
+                    if (ch=='/') {
+                      ch=LexGetChar(cc);
+                      if (ch=='/' && !in_str) {
+                        do ch=LexGetChar(cc);
+                        while (Bt(char_bmp_non_eol,ch));
+                        break;
+                      } else {
+                        buf[j++]='/';
+                        cc->flags|=CCF_USE_LAST_U16;
+                      }
+                    } else if (ch=='\\') {
+                      if (ch=LexGetChar(cc)) {
+                        if (ch=='\"') {
+                          buf[j++]='\\';
+                          buf[j++]=ch;
+                        } else {
+                          cc->flags|=CCF_USE_LAST_U16;
+                          ch='\\';
+                          break;
+                        }
+                      }
+                    } else if (Bt(char_bmp_non_eol,ch)) {
+                      if (ch=='\"')
+                        in_str=!in_str;
+                      buf[j++]=ch;
+                    } else
+                      break;
+                    if (j>=STR_LEN-4) {//Spot for ['\'][ch],[ch],[0]
+                      buf[j++]=0;
+                      buf3=MAlloc(i+j);
+                      if (buf2) {
+                        MemCpy(buf3,buf2,i);
+                        Free(buf2);
+                        buf2=buf3;
+                        MemCpy(buf2+i,buf,j);
+                      } else {
+                        buf2=buf3;
+                        MemCpy(buf2,buf,j);
+                      }
+                      i+=j-1;
+                      j=0;
+                    }
+                  }
+                } while (ch=='\\');
+              }
+              buf[j++]=0;
+              buf3=MAlloc(i+j);
+              if (buf2) {
+                MemCpy(buf3,buf2,i);
+                Free(buf2);
+                buf2=buf3;
+                MemCpy(buf2+i,buf,j);
+              } else {
+                buf2=buf3;
+                MemCpy(buf2,buf,j);
+              }
+              tmph(CHashDefineStr *)->data=buf2;
+              tmph(CHashDefineStr *)->cnt=-1;
+              HashAdd(tmph,cc->htc.define_hash_table);
+            }
+            cc->flags&=~CCF_NO_DEFINES;
+            break;
+          case KW_ELSE:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_ELSE;
+              goto lex_end;
+            }
+lex_else:
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+
+          case KW_IF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IF;
+              goto lex_end;
+            }
+lex_if:
+            cc->flags|=CCF_IN_IF;
+            if (!Lex(cc)) {
+              cc->flags&=~CCF_IN_IF;
+              goto lex_end;
+            }
+            if (LexExpression(cc)) {
+              cc->flags&=~CCF_IN_IF;
+              switch (cc->token) {
+                case TK_IF:     goto lex_if;
+                case TK_IFDEF:  goto lex_ifdef;
+                case TK_IFNDEF: goto lex_ifndef;
+                case TK_IFAOT:  goto lex_ifaot;
+                case TK_IFJIT:  goto lex_ifjit;
+                case TK_ELSE:   goto lex_else;
+                case TK_ENDIF:  goto lex_cont;
+                default:        goto lex_end;
+              }
+            } else {
+              cc->flags&=~CCF_IN_IF;
+              if (cc->token!=TK_ENDIF && cc->token!=TK_ELSE) {
+                if (cc->token==TK_IF || cc->token==TK_IFDEF ||
+                      cc->token==TK_IFNDEF || cc->token==TK_IFAOT ||
+                      cc->token==TK_IFJIT)
+                  j=2;
+                else
+                  j=1;
+                do {
+                  if (ch=LexGetChar(cc)) {
+                    if (ch=='#') {
+                      if (!Lex(cc))
+                        goto lex_end;
+                      i=PrsKeyWord(cc);
+                      if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                            i==KW_IFAOT || i==KW_IFJIT)
+                        j++;
+                      else if (i==KW_ENDIF)
+                        j--;
+                      else if (i==KW_ELSE && j==1)
+                        break;
+                    }
+                  } else {
+                    cc->token=TK_EOF;
+                    goto lex_end;
+                  }
+                } while (j);
+              }
+            }
+            break;
+          case KW_IFDEF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFDEF;
+              goto lex_end;
+            }
+lex_ifdef:
+            cc->flags|=CCF_NO_DEFINES;
+            if (!Lex(cc)) {
+              cc->flags&=~CCF_NO_DEFINES;
+              goto lex_end;
+            }
+            cc->flags&=~CCF_NO_DEFINES;
+            if (cc->token!=TK_IDENT)
+              goto lex_end;
+            if (cc->hash_entry)
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_IFNDEF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFNDEF;
+              goto lex_end;
+            }
+lex_ifndef:
+            cc->flags|=CCF_NO_DEFINES;
+            if (!Lex(cc)) {
+              cc->flags&=~CCF_NO_DEFINES;
+              goto lex_end;
+            }
+            cc->flags&=~CCF_NO_DEFINES;
+            if (cc->token!=TK_IDENT)
+              goto lex_end;
+            if (!cc->hash_entry)
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_IFAOT:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFAOT;
+              goto lex_end;
+            }
+lex_ifaot:
+            if (cc->flags & CCF_AOT_COMPILE)
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_IFJIT:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_IFAOT;
+              goto lex_end;
+            }
+lex_ifjit:
+            if (!(cc->flags & CCF_AOT_COMPILE))
+              goto lex_cont;
+            j=1;
+            do {
+              if (ch=LexGetChar(cc)) {
+                if (ch=='#') {
+                  if (!Lex(cc))
+                    goto lex_end;
+                  i=PrsKeyWord(cc);
+                  if (i==KW_IF || i==KW_IFDEF || i==KW_IFNDEF ||
+                        i==KW_IFAOT || i==KW_IFJIT)
+                    j++;
+                  else if (i==KW_ENDIF)
+                    j--;
+                  else if (i==KW_ELSE && j==1)
+                    break;
+                }
+              } else {
+                cc->token=TK_EOF;
+                goto lex_end;
+              }
+            } while (j);
+            break;
+          case KW_ENDIF:
+            if (cc->flags & CCF_IN_IF) {
+              cc->token=TK_ENDIF;
+              goto lex_end;
+            }
+            break;
+          case KW_ASSERT:
+            if (!Lex(cc))
+              goto lex_end;
+            if (!LexExpression(cc))
+              LexWarn(cc,"Assert Failed ");
+            goto lex_end;
+          case KW_EXE:
+            if (!Lex(cc))
+              goto lex_end;
+            PrsStreamBlk(cc);
+            goto lex_end;
+          case KW_HELP_INDEX:
+            if (Lex(cc)!=TK_STR)
+              goto lex_end;
+            Free(cc->cur_help_idx);
+            cc->cur_help_idx=LexExtStr(cc,,FALSE);
+            break;
+          case KW_HELP_FILE:
+            if (Lex(cc)!=TK_STR)
+              goto lex_end;
+            tmph=CAlloc(sizeof(CHashSrcSym));
+            fbuf=ExtDft(cc->cur_str,"DD.Z");
+            tmph->str=FileNameAbs(fbuf);
+            Free(fbuf);
+            tmph->type=HTT_HELP_FILE|HTF_PUBLIC;
+            HashSrcFileSet(cc,tmph);
+            HashAdd(tmph,cc->htc.glbl_hash_table);
+            break;
+        }
+        break;
+      case '\n':
+        if (!(cc->flags&CCF_KEEP_NEW_LINES))
+          break; //else fall through
+      case TK_INS_BIN:
+      case TK_INS_BIN_SIZE:
+        cc->token=ch;
+        goto lex_end;
+      case '.':
+        if (cc->flags&CCF_KEEP_DOT) {
+          cc->token=ch;
+          goto lex_end;
+        }
+        if (cc->flags&CCF_LAST_WAS_DOT) {
+          cc->flags&=~CCF_LAST_WAS_DOT;
+          goto lex_dot_dot;
+        }
+        ch=LexGetChar(cc);
+        if ('0'<=ch<='9') {
+          i=0;
+          goto lex_float_start;
+        } else if (ch=='.') {
+lex_dot_dot:
+          cc->token=TK_DOT_DOT;
+          if (LexGetChar(cc)=='.')
+            cc->token=TK_ELLIPSIS;
+          else
+            cc->flags|=CCF_USE_LAST_U16;
+          goto lex_end;
+        }
+        cc->flags|=CCF_USE_LAST_U16;
+        cc->token='.';
+        goto lex_end;
+      case '!':
+      case '$'...'&':
+      case '('...'-':
+      case '/':
+      case ':'...'?':
+      case '[':
+      case ']'...'^':
+      case '{'...'~':
+      case '`':
+        if (!(i=cmp.dual_U16_tokens1[ch])) {
+          if (ch=='$') {
+            ch=LexGetChar(cc);
+            if (ch=='$') {
+              cc->token='$';
+              goto lex_end;
+            } else if (ch) {
+              do ch=LexGetChar(cc);
+              while (ch && ch!='$');
+              if (!ch) {
+                cc->token=TK_EOF;
+                goto lex_end;
+              } else
+                goto lex_cont;
+            } else {
+              cc->flags|=CCF_USE_LAST_U16;
+              cc->token='$';
+              goto lex_end;
+            }
+          } else {
+            cc->token=ch;
+            goto lex_end;
+          }
+        } else {
+          j=LexGetChar(cc);
+          if (i.u16[0]==j) {
+            i>>=16;
+            if (!i) {// "/*"
+              j=1;
+              do {
+                if (!(ch=LexGetChar(cc)))
+                  return cc->token=TK_EOF;
+lex_check_comment:
+                if (ch=='*') {
+                  if (!(ch=LexGetChar(cc)))
+                    return cc->token=TK_EOF;
+                  if (ch=='/')
+                    j--;
+                  else
+                    goto lex_check_comment;
+                } else if (ch=='/') {
+                  if (!(ch=LexGetChar(cc)))
+                    return cc->token=TK_EOF;
+                  if (ch=='*')
+                    j++;
+                  else
+                    goto lex_check_comment;
+                }
+              } while (j);
+              goto lex_cont;
+            } else {
+              cc->token=i;
+              goto lex_end;
+            }
+          }
+          if (i=cmp.dual_U16_tokens2[ch]) {
+            if (i.u16[0]==j) {
+              i>>=16;
+              if (!i) {// "//"
+                LexSkipEol(cc);
+                if (cc->flags&CCF_KEEP_NEW_LINES) {
+                  cc->token='\n';
+                  goto lex_end;
+                } else
+                  goto lex_cont;
+              } else {
+                if (i==TK_SHL || i==TK_SHR) {
+                  j=LexGetChar(cc);
+                  if (j=='=') {
+                    if (i==TK_SHL)
+                      i=TK_SHL_EQU;
+                    else
+                      i=TK_SHR_EQU;
+                  } else
+                    cc->flags|=CCF_USE_LAST_U16;
+                }
+                cc->token=i;
+                goto lex_end;
+              }
+            }
+            if (i=cmp.dual_U16_tokens3[ch]) {
+              if (i.u16[0]==j) {
+                cc->token=i.u16[1];
+                goto lex_end;
+              }
+            }
+          }
+          cc->flags|=CCF_USE_LAST_U16;
+          cc->token=ch;
+          goto lex_end;
+        }
+      case TK_TKS_NUM:
+        break;
+    }
+  }
+lex_end:
+  LexGetChar(cc); //Do this so WAS_NEW_LINE is right
+  cc->flags|=CCF_USE_LAST_U16;
+  return cc->token;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/LexLib.HC.HTML b/public/Wb/Home/Src/Compiler/LexLib.HC.HTML new file mode 100755 index 0000000..d641269 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/LexLib.HC.HTML @@ -0,0 +1,306 @@ + + + + + + + + + + + +
+U0 LexBackupLastChar(CCmpCtrl *cc)
+{
+  CLexFile *tmpf=cc->lex_include_stk;
+  tmpf->buf_ptr=cc->cur_buf_ptr;
+  if (cc->flags & CCF_USE_LAST_U16) {
+    tmpf->last_U16=cc->last_U16;
+    cc->flags&=~CCF_USE_LAST_U16;
+  } else
+    tmpf->last_U16=0;
+}
+
+U0 LexPush(CCmpCtrl *cc)
+{//Create token-stream save point.
+  CLexFile *tmpf;
+  LexBackupLastChar(cc);
+  if (cc->lex_include_stk->last_U16)
+    cc->flags|=CCF_USE_LAST_U16;
+  tmpf=MAllocIdent(cc->lex_include_stk);
+  tmpf->next=cc->lex_prs_stk;
+  cc->lex_prs_stk=tmpf;
+}
+
+U0 LexPopRestore(CCmpCtrl *cc)
+{//Restore token-stream saved-point.
+//Bad things can happen if you cross an #include file boundary.
+  CLexFile *tmpf=cc->lex_prs_stk;
+  cc->cur_buf_ptr=tmpf->buf_ptr;
+  if (cc->last_U16=tmpf->last_U16)
+    cc->flags|=CCF_USE_LAST_U16;
+  else
+    cc->flags&=~CCF_USE_LAST_U16;
+  MemCpy(cc->lex_include_stk(U8 *)+sizeof(U8 *),tmpf(U8 *)+sizeof(U8 *),
+        sizeof(CLexFile)-sizeof(U8 *));
+  cc->lex_prs_stk=tmpf->next;
+  Free(tmpf);
+}
+
+U0 LexPopNoRestore(CCmpCtrl *cc)
+{//Don't restore token-stream saved-point.
+  CLexFile *tmpf=cc->lex_prs_stk;
+  cc->lex_prs_stk=tmpf->next;
+  Free(tmpf);
+}
+
+I64 MemberMetaData(U8 *needle_str,CMemberLst *haystack_member_lst)
+{//Find meta data name, return meta data val. See ::/Demo/ClassMeta.HC.
+  CMemberLstMeta *meta=haystack_member_lst->meta;
+  while (meta) {
+    if (!StrCmp(meta->str,needle_str))
+      return meta->user_data;
+    meta=meta->next;
+  }
+  return 0;
+}
+
+CMemberLstMeta *MemberMetaFind(U8 *needle_str,CMemberLst *haystack_member_lst)
+{//Find meta data name, return meta data struct. See ::/Demo/ClassMeta.HC.
+  CMemberLstMeta *meta=haystack_member_lst->meta;
+  while (meta) {
+    if (!StrCmp(meta->str,needle_str))
+      return meta;
+    meta=meta->next;
+  }
+  return NULL;
+}
+
+CMemberLst *MemberFind(U8 *needle_str,CHashClass *haystack_class)
+{//Find class member. See ClassRep() and DocForm().
+  I64 i;
+  CMemberLst *tmpm;
+  do {
+    tmpm=haystack_class->member_lst_and_root;
+    while (tmpm) {
+      if (!(i=StrCmp(tmpm->str,needle_str))) {
+        tmpm->use_cnt++;
+        return tmpm;
+      }
+      if (i<=0)
+        tmpm=tmpm->left;
+      else
+        tmpm=tmpm->right;
+    }
+  } while (haystack_class=haystack_class->base_class);
+  return NULL;
+}
+
+CMemberLst *MemberClassBaseFind(CHashClass *needle_class,
+        CHashClass *haystack_class)
+{//Find class member class base. For finding dup class local vars.
+  CMemberLst *tmpm;
+  tmpm=haystack_class->member_class_base_root;
+  while (tmpm) {
+    if (needle_class==tmpm->member_class_base)
+      return tmpm;
+    if (needle_class<tmpm->member_class_base)
+      tmpm=tmpm->left_class_base;
+    else
+      tmpm=tmpm->right_class_base;
+  }
+  return NULL;
+}
+
+U0 MemberAdd(CCmpCtrl *cc,CMemberLst *tmpm,CHashClass *tmpc,I64 mode)
+{
+  U8 *st=tmpm->str;
+  CMemberLst **tmpm1,*tmpm2;
+
+  if (MemberFind(st,tmpc) && StrCmp(st,"pad") &&
+        StrCmp(st,"reserved") && StrCmp(st,"_anon_"))
+    LexExcept(cc,"Duplicate member at ");
+  tmpm1=&tmpc->member_lst_and_root;
+  while (tmpm2=*tmpm1) {
+    if (StrCmp(tmpm2->str,st)<=0)
+      tmpm1=&tmpm2->left;
+    else
+      tmpm1=&tmpm2->right;
+  }
+  *tmpm1=tmpm;
+
+  if (mode==PRS1B_LOCAL_VAR) {
+    tmpm->member_class_base=
+        tmpm->member_class-tmpm->member_class->ptr_stars_cnt;
+    if (Bt(&cc->opts,OPTf_WARN_DUP_TYPES) &&
+         MemberClassBaseFind(tmpm->member_class_base,tmpc))
+      LexWarn(cc,"Duplicate type at ");
+    tmpm1=&tmpc->member_class_base_root;
+    while (tmpm2=*tmpm1) {
+      if (tmpm->member_class_base<tmpm2->member_class_base)
+        tmpm1=&tmpm2->left_class_base;
+      else if (tmpm->member_class_base>tmpm2->member_class_base)
+        tmpm1=&tmpm2->right_class_base;
+      else {
+        tmpm1=NULL;
+        break;
+      }
+    }
+    if (tmpm1)
+      *tmpm1=tmpm;
+  } else
+    tmpm->member_class_base=NULL;
+
+  tmpm->left=NULL;
+  tmpm->right=NULL;
+  tmpm->left_class_base=NULL;
+  tmpm->right_class_base=NULL;
+  tmpm2=tmpc->last_in_member_lst;
+  tmpm2->next=tmpc->last_in_member_lst=tmpm;
+}
+
+CMemberLst *MemberLstNew(I64 _reg)
+{
+  CMemberLst *res=CAlloc(sizeof(CMemberLst));
+  res->reg=_reg;
+  return res;
+}
+
+Bool  MemberLstCmp(CMemberLst *tmpm1,CMemberLst *tmpm2,I64 cnt=I64_MAX)
+{
+  while (tmpm1 && tmpm2 && cnt--) {
+    if (StrCmp(tmpm1->str,tmpm2->str) ||
+          tmpm1->member_class!=tmpm2->member_class ||
+          tmpm1->member_class_base!=tmpm2->member_class_base)
+      return FALSE;
+    if (tmpm1->flags&MLF_DFT_AVAILABLE || tmpm2->flags&MLF_DFT_AVAILABLE) {
+      if (tmpm1->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE)!=
+            tmpm2->flags&(MLF_DFT_AVAILABLE|MLF_STR_DFT_AVAILABLE))
+        return FALSE;
+      if (tmpm1->flags&MLF_STR_DFT_AVAILABLE) {
+        if (StrCmp(tmpm1->dft_val,tmpm2->dft_val))
+          return FALSE;
+      } else if (tmpm1->dft_val!=tmpm2->dft_val)
+        return FALSE;
+    }
+    tmpm1=tmpm1->next;
+    tmpm2=tmpm2->next;
+  }
+  if (cnt<0 || !tmpm1 && !tmpm2)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 MemberLstDel(CMemberLst *tmpm)
+{
+  CMemberLst *tmpm1;
+  CMemberLstMeta *tmp_meta,*tmp_meta1;
+  while (tmpm) {
+    tmpm1=tmpm->next;
+    Free(tmpm->str);
+    LinkedLstDel(tmpm->dim.next);
+    if (tmpm->flags & MLF_STR_DFT_AVAILABLE)
+      Free(tmpm->dft_val);
+    if (tmpm->flags & MLF_FUN)
+      HashDel(tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+    tmp_meta=tmpm->meta;
+    while (tmp_meta) {
+      tmp_meta1=tmp_meta->next;
+      Free(tmp_meta->str);
+      if (tmp_meta->flags&MLMF_IS_STR)
+        Free(tmp_meta->user_data);
+      Free(tmp_meta);
+      tmp_meta=tmp_meta1;
+    }
+    Free(tmpm);
+    tmpm=tmpm1;
+  }
+}
+
+U0 ClassMemberLstDel(CHashClass *tmpc)
+{
+  MemberLstDel(tmpc->member_lst_and_root);
+  tmpc->size=0;
+  tmpc->last_in_member_lst=&tmpc->member_lst_and_root;
+  tmpc->member_lst_and_root=NULL;
+  tmpc->member_class_base_root=NULL;
+  tmpc->member_cnt=0;
+  if (tmpc->type&HTT_FUN)
+    tmpc(CHashFun *)->arg_cnt=0;
+}
+
+I64 MemberLstSize(CHashClass *tmpc)
+{
+  CMemberLst *tmpm;
+  CMemberLstMeta *tmp_meta;
+  I64 res=0;
+  tmpm=tmpc->member_lst_and_root;
+  while (tmpm) {
+    res+=MSize2(tmpm->str);
+    res+=LinkedLstSize(tmpm->dim.next);
+    if (tmpm->flags & MLF_STR_DFT_AVAILABLE)
+      res+=MSize2(tmpm->dft_val);
+    if (tmpm->flags & MLF_FUN)
+      res+=HashEntrySize2(tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+    tmp_meta=tmpm->meta;
+    while (tmp_meta) {
+      res+=MSize2(tmp_meta->str);
+      if (tmp_meta->flags&MLMF_IS_STR)
+        res+=MSize2(tmp_meta->user_data);
+      res+=MSize2(tmp_meta);
+      tmp_meta=tmp_meta->next;
+    }
+    res+=MSize2(tmpm);
+    tmpm=tmpm->next;
+  }
+  return res;
+}
+
+U8 *LexExtStr(CCmpCtrl *cc,I64 *_size=NULL,Bool lex_next=TRUE)
+{//Lex TK_STR's to one combined str. _size includes terminator.
+  I64 len=cc->cur_str_len,len1,len2;
+  U8 *st=cc->cur_str,*st1,*st2;
+  cc->cur_str=NULL;
+  while (cc->token==TK_STR) {
+    st1=st;
+    len1=len;
+    if (!lex_next && LexGetChar(cc)!='\\') {
+      cc->flags|=CCF_USE_LAST_U16;
+      break;
+    }
+    if (Lex(cc)==TK_STR) {
+      len2=cc->cur_str_len;
+      st2=cc->cur_str;
+      cc->cur_str=NULL;
+      len=len1+len2-1;
+      st=MAlloc(len);
+      if (len1>1)
+        MemCpy(st,st1,len1-1);
+      MemCpy(st+len1-1,st2,len2);
+      Free(st1);
+      Free(st2);
+    }
+  }
+  if (_size) *_size=len;
+  return st;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/OpCodes.DD.HTML b/public/Wb/Home/Src/Compiler/OpCodes.DD.HTML new file mode 100755 index 0000000..cb17b3e --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OpCodes.DD.HTML @@ -0,0 +1,1328 @@ + + + + + + + + + + + +
+/* See AsmHashLoad().
+
+'!'= IEF_DONT_SWITCH_MODES
+'&'= IEF_DFT
+'%'= IEF_NOT_IN_64_BIT  Not Allowed in 64-bit.
+'='= IEF_48_REX         Rex 0x48 only if in 64-bit mode.
+'`'= IEF_REX_ONLY_R8_R15
+'^'= IEF_REX_XOR_LIKE
+'*'= IEF_STI_LIKE       Floating STI-like for UAsm.
+'$'= IEF_ENDING_ZERO    Ending zero for ENTER.
+
+Note: TempleOS uses nonstandard opcodes.
+Asm is kind-of a bonus and I made changes
+to make the assembler simpler. For opcodes
+which can have different numbers of
+args, I separated them out -- Like IMUL and IMUL2.
+The assembler will not report certain invalid
+forms. Get an Intel datasheet and learn
+which forms are valid.
+
+{Lock|Rep}{Seg|2E=NotBr|3E=Br}{OP}{ADD}{REX}
+
+':' is start of alias list.     Marked with OCF_ALIAS.
+*/
+
+R8 AL 0;
+R8 CL 1;
+R8 DL 2;
+R8 BL 3;
+R8 AH 4;
+R8 CH 5;
+R8 DH 6;
+R8 BH 7;
+R8 R8u8 8;
+R8 R9u8 9;
+R8 R10u8 10;
+R8 R11u8 11;
+R8 R12u8 12;
+R8 R13u8 13;
+R8 R14u8 14;
+R8 R15u8 15;
+R8 RSPu8 20;
+R8 RBPu8 21;
+R8 RSIu8 22;
+R8 RDIu8 23;
+
+R16 AX 0;
+R16 CX 1;
+R16 DX 2;
+R16 BX 3;
+R16 SP 4;
+R16 BP 5;
+R16 SI 6;
+R16 DI 7;
+R16 R8u16 8;
+R16 R9u16 9;
+R16 R10u16 10;
+R16 R11u16 11;
+R16 R12u16 12;
+R16 R13u16 13;
+R16 R14u16 14;
+R16 R15u16 15;
+
+R32 EAX 0;
+R32 ECX 1;
+R32 EDX 2;
+R32 EBX 3;
+R32 ESP 4;
+R32 EBP 5;
+R32 ESI 6;
+R32 EDI 7;
+R32 R8u32 8;
+R32 R9u32 9;
+R32 R10u32 10;
+R32 R11u32 11;
+R32 R12u32 12;
+R32 R13u32 13;
+R32 R14u32 14;
+R32 R15u32 15;
+
+R64 RAX 0;
+R64 RCX 1;
+R64 RDX 2;
+R64 RBX 3;
+R64 RSP 4;
+R64 RBP 5;
+R64 RSI 6;
+R64 RDI 7;
+R64 R8 8;
+R64 R9 9;
+R64 R10 10;
+R64 R11 11;
+R64 R12 12;
+R64 R13 13;
+R64 R14 14;
+R64 R15 15;
+R64 R8u64 8;
+R64 R9u64 9;
+R64 R10u64 10;
+R64 R11u64 11;
+R64 R12u64 12;
+R64 R13u64 13;
+R64 R14u64 14;
+R64 R15u64 15;
+
+SEG ES 0;
+SEG CS 1;
+SEG SS 2;
+SEG DS 3;
+SEG FS 4;
+SEG GS 5;
+
+FSTK ST0 0;
+FSTK ST1 1;
+FSTK ST2 2;
+FSTK ST3 3;
+FSTK ST4 4;
+FSTK ST5 5;
+FSTK ST6 6;
+FSTK ST7 7;
+
+MM MM0 0;
+MM MM1 1;
+MM MM2 2;
+MM MM3 3;
+MM MM4 4;
+MM MM5 5;
+MM MM6 6;
+MM MM7 7;
+
+XMM XMM0 0;
+XMM XMM1 1;
+XMM XMM2 2;
+XMM XMM3 3;
+XMM XMM4 4;
+XMM XMM5 5;
+XMM XMM6 6;
+XMM XMM7 7;
+
+KEYWORD include         0;
+KEYWORD define          1;
+KEYWORD union           2;
+KEYWORD catch           3;
+KEYWORD class           4;
+KEYWORD try             5;
+KEYWORD if              6;
+KEYWORD else            7;
+KEYWORD for             8;
+KEYWORD while           9;
+KEYWORD extern          10;
+KEYWORD _extern         11;
+KEYWORD return          12;
+KEYWORD sizeof          13;
+KEYWORD _intern         14;
+KEYWORD do              15;
+KEYWORD asm             16;
+KEYWORD goto            17;
+KEYWORD exe             18;
+KEYWORD break           19;
+KEYWORD switch          20;
+KEYWORD start           21;
+KEYWORD end             22;
+KEYWORD case            23;
+KEYWORD default         24;
+KEYWORD public          25;
+KEYWORD offset          26;
+KEYWORD import          27;
+KEYWORD _import         28;
+KEYWORD ifdef           29;
+KEYWORD ifndef          30;
+KEYWORD ifaot           31;
+KEYWORD ifjit           32;
+KEYWORD endif           33;
+KEYWORD assert          34;
+KEYWORD reg             35;
+KEYWORD noreg           36;
+KEYWORD lastclass       37;
+KEYWORD no_warn 38;
+KEYWORD help_index      39;
+KEYWORD help_file       40;
+KEYWORD static          41;
+KEYWORD lock            42;
+KEYWORD defined         43;
+KEYWORD interrupt       44;
+KEYWORD haserrcode      45;
+KEYWORD argpop          46;
+KEYWORD noargpop        47;
+
+ASM_KEYWORD ALIGN       64;
+ASM_KEYWORD ORG         65;
+ASM_KEYWORD I0          66;
+ASM_KEYWORD I8          67;
+ASM_KEYWORD I16         68;
+ASM_KEYWORD I32         69;
+ASM_KEYWORD I64         70;
+ASM_KEYWORD U0          71;
+ASM_KEYWORD U8          72;
+ASM_KEYWORD U16         73;
+ASM_KEYWORD U32         74;
+ASM_KEYWORD U64         75;
+ASM_KEYWORD F64         76;
+ASM_KEYWORD DU8         77;
+ASM_KEYWORD DU16        78;
+ASM_KEYWORD DU32        79;
+ASM_KEYWORD DU64        80;
+ASM_KEYWORD DUP         81;
+ASM_KEYWORD USE16       82;
+ASM_KEYWORD USE32       83;
+ASM_KEYWORD USE64       84;
+ASM_KEYWORD IMPORT      85;
+ASM_KEYWORD LIST        86;
+ASM_KEYWORD NOLIST      87;
+ASM_KEYWORD BINFILE     88;
+
+OPCODE PUSH
+ 0x0E, CS
+ 0x16, SS
+ 0x1E, DS
+ 0x06, ES
+ 0x0F 0xA0, FS
+ 0x0F 0xA8, GS
+ 0x6A, &IB IMM8
+ 0x68, 16 !IW IMM16
+ 0x68, 32 !ID IMM32
+ 0x50,+R 16 % R16
+ 0x50,+R 32 R32
+ 0x50,+R 32 `R64
+ 0xFF,/6 16 % RM16
+ 0xFF,/6 32 RM32
+ 0xFF,/6 32 RM64;
+OPCODE PUSHAW 0x60, 16;
+OPCODE PUSHAD 0x60, 32;
+OPCODE PUSHFW 0x9C, 16;
+OPCODE PUSHFD 0x9C, 32;
+OPCODE POP
+ 0x1F, DS
+ 0x07, ES
+ 0x17, SS
+ 0x0F 0xA1, FS
+ 0x0F 0xA9, GS
+ 0x58,+R 16 R16
+ 0x58,+R 32 R32
+ 0x58,+R 32 `R64
+ 0x8F,/0 16 RM16
+ 0x8F,/0 32 RM32
+ 0x8F,/0 32 RM64;
+OPCODE POPAW 0x61, 16;
+OPCODE POPAD 0x61, 32;
+OPCODE POPFW 0x9D, 16;
+OPCODE POPFD 0x9D, 32;
+OPCODE MOV
+// 0xA0, AL MOFFS8
+ 0xA1, 16 AX MOFFS16
+ 0xA1, 32 EAX MOFFS32
+// 0xA2, MOFFS8 AL
+ 0xA3, 16 MOFFS16 AX
+ 0xA3, 32 MOFFS32 EAX
+ 0x8A,/R R8 RM8
+ 0x8B,/R 16 R16 RM16
+ 0x8B,/R 32 R32 RM32
+ 0x8B,/R 32 R64 RM64
+ 0x88,/R RM8 R8
+ 0x89,/R 16 RM16 R16
+ 0x89,/R 32 RM32 R32
+ 0x89,/R 32 RM64 R64
+ 0x8C,/R 32 RM16 SREG
+ 0x8E,/R 32 SREG RM16
+ 0xB0,+R &R8 UIMM8
+ 0xB0,+R R8 IMM8
+ 0xB8,+R 16 &R16 UIMM16
+ 0xB8,+R 16 R16 IMM16
+ 0xB8,+R 32 &R32 UIMM32
+ 0xB8,+R 32 R32 IMM32
+ 0xB8,+R 32 `R64 UIMM32
+ 0xB8,+R 32 &R64 UIMM64
+ 0xB8,+R 32 R64 IMM64
+ 0xC6, &RM8 UIMM8
+ 0xC6, RM8 IMM8
+ 0xC7, 16 &RM16 UIMM16
+ 0xC7, 16 RM16 IMM16
+ 0xC7, 32 &RM32 UIMM32
+ 0xC7, 32 RM32 IMM32
+ 0xC7, 32 `RM64 UIMM32
+ 0xC7, 32 RM64 IMM32;
+
+OPCODE ADC
+ 0x14, IB &AL UIMM8
+ 0x14, IB AL IMM8
+ 0x15, 16 IW &AX UIMM16
+ 0x15, 16 IW AX IMM16
+ 0x15, 32 ID &EAX UIMM32
+ 0x15, 32 ID EAX IMM32
+ 0x80,/2 IB RM8 IMM8
+ 0x83,/2 16 IB RM16 IMM8
+ 0x83,/2 32 IB RM32 IMM8
+ 0x83,/2 32 IB RM64 IMM8
+ 0x81,/2 16 IW RM16 IMM16
+ 0x81,/2 32 ID RM32 IMM32
+ 0x81,/2 32 ID RM64 IMM32
+ 0x12,/R R8 RM8
+ 0x13,/R 16 R16 RM16
+ 0x13,/R 32 R32 RM32
+ 0x13,/R 32 R64 RM64
+ 0x10,/R RM8 R8
+ 0x11,/R 16 RM16 R16
+ 0x11,/R 32 RM32 R32
+ 0x11,/R 32 RM64 R64;
+OPCODE ADD
+ 0x04, IB &AL UIMM8
+ 0x04, IB AL IMM8
+ 0x05, 16 IW &AX UIMM16
+ 0x05, 16 IW AX IMM16
+ 0x05, 32 ID &EAX UIMM32
+ 0x05, 32 ID EAX IMM32
+ 0x80,/0 IB &RM8 UIMM8
+ 0x80,/0 IB RM8 IMM8
+ 0x83,/0 16 IB RM16 IMM8
+ 0x83,/0 32 IB RM32 IMM8
+ 0x83,/0 32 IB RM64 IMM8
+ 0x81,/0 16 IW RM16 IMM16
+ 0x81,/0 32 ID RM32 IMM32
+ 0x81,/0 32 ID RM64 IMM32
+ 0x02,/R R8 RM8
+ 0x03,/R 16 R16 RM16
+ 0x03,/R 32 R32 RM32
+ 0x03,/R 32 R64 RM64
+ 0x00,/R RM8 R8
+ 0x01,/R 16 RM16 R16
+ 0x01,/R 32 RM32 R32
+ 0x01,/R 32 RM64 R64;
+OPCODE AND
+ 0x24, IB &AL UIMM8
+ 0x24, IB AL IMM8
+ 0x25, 16 IW &AX UIMM16
+ 0x25, 16 IW AX IMM16
+ 0x25, 32 ID &EAX UIMM32
+ 0x25, 32 ID EAX IMM32
+ 0x80,/4 IB &RM8 UIMM8
+ 0x80,/4 IB RM8 IMM8
+ 0x83,/4 16 IB RM16 IMM8
+ 0x83,/4 32 IB RM32 IMM8
+ 0x83,/4 32 IB RM64 IMM8
+ 0x81,/4 16 IW RM16 IMM16
+ 0x81,/4 32 ID RM32 IMM32
+ 0x81,/4 32 ID RM64 IMM32
+ 0x22,/R R8 RM8
+ 0x23,/R 16 R16 RM16
+ 0x23,/R 32 R32 RM32
+ 0x23,/R 32 R64 RM64
+ 0x20,/R RM8 R8
+ 0x21,/R 16 RM16 R16
+ 0x21,/R 32 RM32 R32
+ 0x21,/R 32 RM64 R64;
+OPCODE CMP
+ 0x3C, IB &AL UIMM8
+ 0x3C, IB AL IMM8
+ 0x3D, 16 IW &AX UIMM16
+ 0x3D, 16 IW AX IMM16
+ 0x3D, 32 ID &EAX UIMM32
+ 0x3D, 32 ID EAX IMM32
+ 0x80,/7 IB &RM8 UIMM8
+ 0x80,/7 IB RM8 IMM8
+ 0x83,/7 16 IB RM16 IMM8
+ 0x83,/7 32 IB RM32 IMM8
+ 0x83,/7 32 IB RM64 IMM8
+ 0x81,/7 16 IW RM16 IMM16
+ 0x81,/7 32 ID RM32 IMM32
+ 0x81,/7 32 ID RM64 IMM32
+ 0x3A,/R R8 RM8
+ 0x3B,/R 16 R16 RM16 //ERROR?
+ 0x3B,/R 32 R32 RM32
+ 0x3B,/R 32 R64 RM64
+ 0x38,/R RM8 R8
+ 0x39,/R 16 RM16 R16
+ 0x39,/R 32 RM32 R32
+ 0x39,/R 32 RM64 R64;
+OPCODE OR
+ 0x0C, IB &AL UIMM8
+ 0x0C, IB AL IMM8
+ 0x0D, 16 IW &AX UIMM16
+ 0x0D, 16 IW AX IMM16
+ 0x0D, 32 ID &EAX UIMM32
+ 0x0D, 32 ID EAX IMM32
+ 0x80,/1 IB &RM8 UIMM8
+ 0x80,/1 IB RM8 IMM8
+ 0x83,/1 16 IB RM16 IMM8
+ 0x83,/1 32 IB RM32 IMM8
+ 0x83,/1 32 IB RM64 IMM8
+ 0x81,/1 16 IW RM16 IMM16
+ 0x81,/1 32 ID RM32 IMM32
+ 0x81,/1 32 ID RM64 IMM32
+ 0x0A,/R R8 RM8
+ 0x0B,/R 16 R16 RM16
+ 0x0B,/R 32 R32 RM32
+ 0x0B,/R 32 R64 RM64
+ 0x08,/R RM8 R8
+ 0x09,/R 16 RM16 R16
+ 0x09,/R 32 RM32 R32
+ 0x09,/R 32 RM64 R64;
+OPCODE SBB
+ 0x1C, IB &AL UIMM8
+ 0x1C, IB AL IMM8
+ 0x1D, 16 IW &AX UIMM16
+ 0x1D, 16 IW AX IMM16
+ 0x1D, 32 ID &EAX UIMM32
+ 0x1D, 32 ID EAX IMM32
+ 0x80,/3 IB &RM8 UIMM8
+ 0x80,/3 IB RM8 IMM8
+ 0x83,/3 16 IB RM16 IMM8
+ 0x83,/3 32 IB RM32 IMM8
+ 0x83,/3 32 IB RM64 IMM8
+ 0x81,/3 16 IW RM16 IMM16
+ 0x81,/3 32 ID RM32 IMM32
+ 0x81,/3 32 ID RM64 IMM32
+ 0x1A,/R R8 RM8
+ 0x1B,/R 16 R16 RM16
+ 0x1B,/R 32 R32 RM32
+ 0x1B,/R 32 R64 RM64
+ 0x18,/R RM8 R8
+ 0x19,/R 16 RM16 R16
+ 0x19,/R 32 RM32 R32
+ 0x19,/R 32 RM64 R64;
+OPCODE SUB
+ 0x2C, IB &AL UIMM8
+ 0x2C, IB AL IMM8
+ 0x2D, 16 IW &AX UIMM16
+ 0x2D, 16 IW AX IMM16
+ 0x2D, 32 ID &EAX UIMM32
+ 0x2D, 32 ID EAX IMM32
+ 0x80,/5 IB &RM8 UIMM8
+ 0x80,/5 IB RM8 IMM8
+ 0x83,/5 16 IB RM16 IMM8
+ 0x83,/5 32 IB RM32 IMM8
+ 0x83,/5 32 IB RM64 IMM8
+ 0x81,/5 16 IW RM16 IMM16
+ 0x81,/5 32 ID RM32 IMM32
+ 0x81,/5 32 ID RM64 IMM32
+ 0x2A,/R R8 RM8
+ 0x2B,/R 16 R16 RM16
+ 0x2B,/R 32 R32 RM32
+ 0x2B,/R 32 R64 RM64
+ 0x28,/R RM8 R8
+ 0x29,/R 16 RM16 R16
+ 0x29,/R 32 RM32 R32
+ 0x29,/R 32 RM64 R64;
+OPCODE TEST
+ 0xA8, IB &AL UIMM8
+ 0xA8, IB AL IMM8
+ 0xA9, 16 IW &AX UIMM16
+ 0xA9, 16 IW AX IMM16
+ 0xA9, 32 ID &EAX UIMM32
+ 0xA9, 32 ID EAX IMM32
+ 0xF6,/0 IB &RM8 UIMM8
+ 0xF6,/0 IB RM8 IMM8
+ 0xF7,/0 16 IW RM16 IMM16
+ 0xF7,/0 32 ID RM32 IMM32
+ 0xF7,/0 32 ID RM64 IMM32
+ 0x84,/R RM8 R8
+ 0x85,/R 16 RM16 R16
+ 0x85,/R 32 RM32 R32
+ 0x85,/R 32 RM64 R64;
+OPCODE NOP 0x90;
+OPCODE NOP2 0x66 0x90;
+OPCODE XCHG
+ 0x90,+R 16 R16 AX
+ 0x90,+R 16 AX R16
+ 0x90,+R 32 R32 EAX
+ 0x90,+R 32 EAX R32
+ 0x90,+R 32 R64 RAX
+ 0x90,+R 32 RAX R64
+ 0x86,/R R8 RM8
+ 0x87,/R 16 R16 RM16
+ 0x87,/R 32 R32 RM32
+ 0x87,/R 32 R64 RM64
+ 0x86,/R RM8 R8
+ 0x87,/R 16 RM16 R16
+ 0x87,/R 32 RM32 R32
+ 0x87,/R 32 RM64 R64;
+OPCODE XOR
+ 0x34, IB &AL UIMM8
+ 0x34, IB AL IMM8
+ 0x35, 16 IW &AX UIMM16
+ 0x35, 16 IW AX IMM16
+ 0x35, 32 ID &EAX UIMM32
+ 0x35, 32 ID EAX IMM32
+ 0x80,/6 IB &RM8 UIMM8
+ 0x80,/6 IB RM8 IMM8
+ 0x83,/6 16 IB RM16 IMM8
+ 0x83,/6 32 IB RM32 IMM8
+ 0x83,/6 32 IB RM64 IMM8
+ 0x81,/6 16 IW RM16 IMM16
+ 0x81,/6 32 ID RM32 IMM32
+ 0x81,/6 32 ID RM64 IMM32
+ 0x32,/R R8 RM8
+ 0x33,/R 16 R16 RM16
+ 0x33,/R 32 R32 RM32
+ 0x33,/R 32 ^ R64 RM64
+ 0x30,/R RM8 R8
+ 0x31,/R 16 RM16 R16
+ 0x31,/R 32 RM32 R32
+ 0x31,/R 32 ^ RM64 R64;
+
+OPCODE CMOVO
+ 0x0F 0x40,/R 16 R16 RM16
+ 0x0F 0x40,/R 32 R32 RM32
+ 0x0F 0x40,/R 32 R64 RM64;
+OPCODE CMOVNO
+ 0x0F 0x41,/R 16 R16 RM16
+ 0x0F 0x41,/R 32 R32 RM32
+ 0x0F 0x41,/R 32 R64 RM64;
+OPCODE CMOVB
+ 0x0F 0x42,/R 16 R16 RM16
+ 0x0F 0x42,/R 32 R32 RM32
+ 0x0F 0x42,/R 32 R64 RM64       :CMOVC CMOVNAE;
+OPCODE CMOVAE
+ 0x0F 0x43,/R 16 R16 RM16
+ 0x0F 0x43,/R 32 R32 RM32
+ 0x0F 0x43,/R 32 R64 RM64       :CMOVNB CMOVNC;
+OPCODE CMOVE
+ 0x0F 0x44,/R 16 R16 RM16
+ 0x0F 0x44,/R 32 R32 RM32
+ 0x0F 0x44,/R 32 R64 RM64       :CMOVZ;
+OPCODE CMOVNE
+ 0x0F 0x45,/R 16 R16 RM16
+ 0x0F 0x45,/R 32 R32 RM32
+ 0x0F 0x45,/R 32 R64 RM64       :CMOVNZ;
+OPCODE CMOVBE
+ 0x0F 0x46,/R 16 R16 RM16
+ 0x0F 0x46,/R 32 R32 RM32
+ 0x0F 0x46,/R 32 R64 RM64       :CMOVNA;
+OPCODE CMOVA
+ 0x0F 0x47,/R 16 R16 RM16
+ 0x0F 0x47,/R 32 R32 RM32
+ 0x0F 0x47,/R 32 R64 RM64       :CMOVNBE;
+OPCODE CMOVS
+ 0x0F 0x48,/R 16 R16 RM16
+ 0x0F 0x48,/R 32 R32 RM32
+ 0x0F 0x48,/R 32 R64 RM64;
+OPCODE CMOVNS
+ 0x0F 0x49,/R 16 R16 RM16
+ 0x0F 0x49,/R 32 R32 RM32
+ 0x0F 0x49,/R 32 R64 RM64;
+OPCODE CMOVP
+ 0x0F 0x4A,/R 16 R16 RM16
+ 0x0F 0x4A,/R 32 R32 RM32
+ 0x0F 0x4A,/R 32 R64 RM64       :CMOVPE;
+OPCODE CMOVNP
+ 0x0F 0x4B,/R 16 R16 RM16
+ 0x0F 0x4B,/R 32 R32 RM32
+ 0x0F 0x4B,/R 32 R64 RM64       :CMOVPO;
+OPCODE CMOVL
+ 0x0F 0x4C,/R 16 R16 RM16
+ 0x0F 0x4C,/R 32 R32 RM32
+ 0x0F 0x4C,/R 32 R64 RM64       :CMOVNGE;
+OPCODE CMOVGE
+ 0x0F 0x4D,/R 16 R16 RM16
+ 0x0F 0x4D,/R 32 R32 RM32
+ 0x0F 0x4D,/R 32 R64 RM64       :CMOVNL;
+OPCODE CMOVLE
+ 0x0F 0x4E,/R 16 R16 RM16
+ 0x0F 0x4E,/R 32 R32 RM32
+ 0x0F 0x4E,/R 32 R64 RM64       :CMOVNG;
+OPCODE CMOVG
+ 0x0F 0x4F,/R 16 R16 RM16
+ 0x0F 0x4F,/R 32 R32 RM32
+ 0x0F 0x4F,/R 32 R64 RM64       :CMOVNLE;
+
+OPCODE CALL
+ 0xE8, 16 !&CW REL16
+ 0xFF,/2 16 ! RM16
+ 0xE8, 32 !&CD REL32
+ 0xFF,/2 32 ! RM32
+ 0xFF,/2 32 !`RM64
+// 0x9A, CD PTR1616
+// 0xFF,/3 16 M1616
+// 0x9A, 16 CP PTR1632
+// 0x9A, 32 CP PTR3232
+// 0xFF,/3 32 M1632
+;
+
+OPCODE JMP
+ 0xEB, &CB REL8
+ 0xE9, 16 !CW REL16
+ 0xE9, 32 !CD REL32
+ 0xFF,/4 16 ! RM16
+ 0xFF,/4 32 ! RM32
+ 0xFF,/4 32 ! RM64;
+
+OPCODE JO
+ 0x70, &CB REL8
+ 0x0F 0x80, 16 !CW REL16
+ 0x0F 0x80, 32 !CD REL32;
+OPCODE JNO
+ 0x71, &CB REL8
+ 0x0F 0x81, 16 !CW REL16
+ 0x0F 0x81, 32 !CD REL32;
+OPCODE JB
+ 0x72, &CB REL8
+ 0x0F 0x82, 16 !CW REL16
+ 0x0F 0x82, 32 !CD REL32        :JC JNAE;
+OPCODE JAE
+ 0x73, &CB REL8
+ 0x0F 0x83, 16 !CW REL16
+ 0x0F 0x83, 32 !CD REL32        :JNB JNC;
+OPCODE JE
+ 0x74, &CB REL8
+ 0x0F 0x84, 16 !CW REL16
+ 0x0F 0x84, 32 !CD REL32        :JZ;
+OPCODE JNE
+ 0x75, &CB REL8
+ 0x0F 0x85, 16 !CW REL16
+ 0x0F 0x85, 32 !CD REL32        :JNZ;
+OPCODE JBE
+ 0x76, &CB REL8
+ 0x0F 0x86, 16 !CW REL16
+ 0x0F 0x86, 32 !CD REL32        :JNA;
+OPCODE JA
+ 0x77, &CB REL8
+ 0x0F 0x87, 16 !CW REL16
+ 0x0F 0x87, 32 !CD REL32        :JNBE;
+OPCODE JS
+ 0x78, &CB REL8
+ 0x0F 0x88, 16 !CW REL16
+ 0x0F 0x88, 32 !CD REL32;
+OPCODE JNS
+ 0x79, &CB REL8
+ 0x0F 0x89, 16 !CW REL16
+ 0x0F 0x89, 32 !CD REL32;
+OPCODE JP
+ 0x7A, &CB REL8
+ 0x0F 0x8A, 16 !CW REL16
+ 0x0F 0x8A, 32 !CD REL32        :JPE;
+OPCODE JNP
+ 0x7B, &CB REL8
+ 0x0F 0x8B, 16 !CW REL16
+ 0x0F 0x8B, 32 !CD REL32        :JPO;
+OPCODE JL
+ 0x7C, &CB REL8
+ 0x0F 0x8C, 16 !CW REL16
+ 0x0F 0x8C, 32 !CD REL32        :JNGE;
+OPCODE JGE
+ 0x7D, &CB REL8
+ 0x0F 0x8D, 16 !CW REL16
+ 0x0F 0x8D, 32 !CD REL32        :JNL;
+OPCODE JLE
+ 0x7E, &CB REL8
+ 0x0F 0x8E, 16 !CW REL16
+ 0x0F 0x8E, 32 !CD REL32        :JNG;
+OPCODE JG
+ 0x7F, &CB REL8
+ 0x0F 0x8F, 16 !CW REL16
+ 0x0F 0x8F, 32 !CD REL32        :JNLE;
+
+OPCODE JCXZ
+ 0xE3, CB REL8                  :JECXZ JRCXZ;
+
+OPCODE INC
+ 0x40,+R 16 % R16
+ 0x40,+R 32 % R32
+ 0xFE,/0 RM8
+ 0xFF,/0 16 RM16
+ 0xFF,/0 32 RM32
+ 0xFF,/0 32 RM64;
+OPCODE DEC
+ 0x48,+R 16 % R16
+ 0x48,+R 32 % R32
+ 0xFE,/1 RM8
+ 0xFF,/1 16 RM16
+ 0xFF,/1 32 RM32
+ 0xFF,/1 32 RM64;
+OPCODE NOT
+ 0xF6,/2 RM8
+ 0xF7,/2 16 RM16
+ 0xF7,/2 32 RM32
+ 0xF7,/2 32 RM64;
+OPCODE NEG
+ 0xF6,/3 RM8
+ 0xF7,/3 16 RM16
+ 0xF7,/3 32 RM32
+ 0xF7,/3 32 RM64;
+OPCODE MUL
+ 0xF6,/4 RM8
+ 0xF7,/4 16 RM16
+ 0xF7,/4 32 RM32
+ 0xF7,/4 32 RM64;
+OPCODE IMUL
+ 0xF6,/5 RM8
+ 0xF7,/5 16 RM16
+ 0xF7,/5 32 RM32
+ 0xF7,/5 32 RM64;
+OPCODE IMUL2
+ 0x0F 0xAF,/R 16 R16 RM16
+ 0x0F 0xAF,/R 32 R32 RM32
+ 0x0F 0xAF,/R 32 R64 RM64
+ 0x6B,/R 16 IB RM16 IMM8
+ 0x6B,/R 32 IB RM32 IMM8
+ 0x6B,/R 32 IB RM64 IMM8
+ 0x69,/R 16 IW &RM16 UIMM16
+ 0x69,/R 16 IW RM16 IMM16
+ 0x69,/R 32 ID &RM32 UIMM32
+ 0x69,/R 32 ID RM32 IMM32
+ 0x69,/R 32 ID &RM64 UIMM32
+ 0x69,/R 32 ID RM64 IMM32;
+OPCODE DIV
+ 0xF6,/6 RM8
+ 0xF7,/6 16 RM16
+ 0xF7,/6 32 RM32
+ 0xF7,/6 32 RM64;
+OPCODE IDIV
+ 0xF6,/7 RM8
+ 0xF7,/7 16 RM16
+ 0xF7,/7 32 RM32
+ 0xF7,/7 32 RM64;
+
+OPCODE AAA 0x37;
+OPCODE AAD 0xD5 0x0A;
+OPCODE AAM 0xD4 0x0A;
+OPCODE AAS 0x3F;
+OPCODE ARPL 0x63,/R RM16 R16;
+OPCODE BOUND
+ 0x62,/R 16 RM16 R16
+ 0x62,/R 32 RM32 R32
+ 0x62,/R 32 RM64 R64;
+OPCODE BSF
+ 0x0F 0xBC,/R 16 R16 RM16
+ 0x0F 0xBC,/R 32 R32 RM32
+ 0x0F 0xBC,/R 32 R64 RM64;
+OPCODE BSR
+ 0x0F 0xBD,/R 16 R16 RM16
+ 0x0F 0xBD,/R 32 R32 RM32
+ 0x0F 0xBD,/R 32 R64 RM64;
+OPCODE BSWAP
+ 0x0F 0xC8,/R 32 R32
+ 0x0F 0xC8,/R 32 R64;
+OPCODE BT
+ 0x0F 0xA3,/R 16 RM16 R16
+ 0x0F 0xA3,/R 32 RM32 R32
+ 0x0F 0xA3,/R 32 RM64 R64
+ 0x0F 0xBA,/4 16 IB &RM16 UIMM8
+ 0x0F 0xBA,/4 16 IB RM16 IMM8
+ 0x0F 0xBA,/4 32 IB &RM32 UIMM8
+ 0x0F 0xBA,/4 32 IB RM32 IMM8
+ 0x0F 0xBA,/4 32 IB &RM64 UIMM8
+ 0x0F 0xBA,/4 32 IB RM64 IMM8;
+OPCODE BTC
+ 0x0F 0xBB,/R 16 RM16 R16
+ 0x0F 0xBB,/R 32 RM32 R32
+ 0x0F 0xBB,/R 32 RM64 R64
+ 0x0F 0xBA,/7 16 IB &RM16 UIMM8
+ 0x0F 0xBA,/7 16 IB RM16 IMM8
+ 0x0F 0xBA,/7 32 IB &RM32 UIMM8
+ 0x0F 0xBA,/7 32 IB RM32 IMM8
+ 0x0F 0xBA,/7 32 IB &RM64 UIMM8
+ 0x0F 0xBA,/7 32 IB RM64 IMM8;
+OPCODE BTR
+ 0x0F 0xB3,/R 16 RM16 R16
+ 0x0F 0xB3,/R 32 RM32 R32
+ 0x0F 0xB3,/R 32 RM64 R64
+ 0x0F 0xBA,/6 16 IB &RM16 UIMM8
+ 0x0F 0xBA,/6 16 IB RM16 IMM8
+ 0x0F 0xBA,/6 32 IB &RM32 UIMM8
+ 0x0F 0xBA,/6 32 IB RM32 IMM8
+ 0x0F 0xBA,/6 32 IB &RM64 UIMM8
+ 0x0F 0xBA,/6 32 IB RM64 IMM8;
+OPCODE BTS
+ 0x0F 0xAB,/R 16 RM16 R16
+ 0x0F 0xAB,/R 32 RM32 R32
+ 0x0F 0xAB,/R 32 RM64 R64
+ 0x0F 0xBA,/5 16 IB &RM16 UIMM8
+ 0x0F 0xBA,/5 16 IB RM16 IMM8
+ 0x0F 0xBA,/5 32 IB &RM32 UIMM8
+ 0x0F 0xBA,/5 32 IB RM32 IMM8
+ 0x0F 0xBA,/5 32 IB &RM64 UIMM8
+ 0x0F 0xBA,/5 32 IB RM64 IMM8;
+OPCODE CBW 0x98, 16;
+OPCODE CWDE 0x98, 32;
+OPCODE CDQE 0x98, 32=;
+OPCODE CWD 0x99, 16;
+OPCODE CDQ 0x99, 32;
+OPCODE CQO 0x99, 32=;
+OPCODE CLC 0xF8;
+OPCODE CLD 0xFC;
+OPCODE CLI 0xFA;
+OPCODE CLTS 0x0F 0x06;
+OPCODE CMC 0xF5;
+OPCODE CMPSB 0xA6;
+OPCODE CMPSW 0xA7, 16;
+OPCODE CMPSD 0xA7, 32;
+OPCODE CMPSQ 0xA7, 32=;
+OPCODE CMPXCHG
+ 0x0F 0xB0,/R RM8 R8
+ 0x0F 0xB1,/R 16 RM16 R16
+ 0x0F 0xB1,/R 32 RM32 R32
+ 0x0F 0xB1,/R 32 RM64 R64;
+OPCODE CHPXCHG8B 0x0F 0xC7, RM64;
+OPCODE DAA 0x27;
+OPCODE DAS 0x2F;
+OPCODE ENTER
+ 0xC8, $IW IMM16;
+OPCODE HLT 0xF4;
+OPCODE IN
+ 0xE4, IB &AL UIMM8
+ 0xE4, IB AL IMM8
+ 0xE5, 16 IB &AX UIMM8
+ 0xE5, 16 IB AX IMM8
+ 0xE5, 32 IB &EAX UIMM8
+ 0xE5, 32 IB EAX IMM8
+ 0xEC, AL DX
+ 0xED, 16 AX DX
+ 0xED, 32 EAX DX;
+OPCODE INS
+ 0x6C, RM8 DX
+ 0x6D, 16 RM16 DX
+ 0x6D, 32 RM32 DX;
+OPCODE INSB 0x6C;
+OPCODE INSW 0x6D, 16;
+OPCODE INSD 0x6D, 32;
+OPCODE INTO 0xCE;
+OPCODE INT3 0xCC,               :BPT;
+OPCODE INT 
+ 0xCD, IB &UIMM8
+ 0xCD, IB IMM8;
+OPCODE INVD 0x0F 0x08;
+OPCODE IRET 0xCF, 32=;
+OPCODE LAHF 0x9F;
+OPCODE LAR
+ 0x0F 0x02,/R 16 R16 RM16
+ 0x0F 0x02,/R 32 R32 RM32
+ 0x0F 0x02,/R 32 R64 RM64;
+OPCODE LEA
+ 0x8D,/R 16 R16 RM16
+ 0x8D,/R 32 R32 RM32
+ 0x8D,/R 32 R64 RM64;
+OPCODE LEAVE 0xC9;
+OPCODE LGDT
+ 0x0F 0x01,/2 16 M16
+ 0x0F 0x01,/2 32 M32
+ 0x0F 0x01,/2 32 M64;
+OPCODE SGDT
+ 0x0F 0x01,/0 16 M16
+ 0x0F 0x01,/0 32 M32
+ 0x0F 0x01,/0 32 M64;
+OPCODE LIDT
+ 0x0F 0x01,/3 16 M16
+ 0x0F 0x01,/3 32 M32
+ 0x0F 0x01,/3 32 M64;
+OPCODE SIDT 
+ 0x0F 0x01,/1 16 M16
+ 0x0F 0x01,/1 32 M32
+ 0x0F 0x01,/1 32 M64;
+OPCODE LLDT
+ 0x0F 0x00,/2 RM16;
+OPCODE SLDT
+ 0x0F 0x00,/0 16 RM16
+ 0x0F 0x00,/0 32 RM32
+ 0x0F 0x00,/0 32 RM64;
+OPCODE LMSW
+ 0x0F 0x01,/6 RM16;
+OPCODE SMSW
+ 0x0F 0x01,/4 16 RM16
+ 0x0F 0x01,/4 32 RM32
+ 0x0F 0x01,/4 32 RM64;
+//OPCODE LGS LSS LFS LDS LES
+OPCODE LOCK 0xF0;
+OPCODE LODSB 0xAC;
+OPCODE LODSW 0xAD, 16;
+OPCODE LODSD 0xAD, 32;
+OPCODE LODSQ 0xAD, 32=;
+OPCODE LOOP 0xE2, CB REL8;
+OPCODE LOOPE 0xE1, CB REL8      :LOOPZ;
+OPCODE LOOPNE 0xE0, CB REL8     :LOOPNZ;
+OPCODE LSL
+ 0x0F 0x03,/R 16 R16 RM16
+ 0x0F 0x03,/R 32 R32 RM32
+ 0x0F 0x03,/R 32 R64 RM64;
+OPCODE LTR
+ 0x0F 0x00,/3 RM16;
+OPCODE MOVSB 0xA4;
+OPCODE MOVSW 0xA5, 16;
+OPCODE MOVSD 0xA5, 32;
+OPCODE MOVSQ 0xA5, 32=;
+OPCODE MOVSX
+ 0x0F 0xBE,/R 16 R16 RM8
+ 0x0F 0xBE,/R 32 R32 RM8
+ 0x0F 0xBE,/R 32 R64 RM8
+ 0x0F 0xBF,/R 32 R32 RM16
+ 0x0F 0xBF,/R 32 R64 RM16;
+OPCODE MOVSXD
+ 0x63,/R 32 R64 RM32;
+OPCODE MOVZX
+ 0x0F 0xB6,/R 16 R16 RM8
+ 0x0F 0xB6,/R 32 R32 RM8
+ 0x0F 0xB6,/R 32 R64 RM8
+ 0x0F 0xB7,/R 32 R32 RM16
+ 0x0F 0xB7,/R 32 R64 RM16;
+OPCODE OUT
+ 0xE6, IB &UIMM8 AL
+ 0xE6, IB IMM8 AL
+ 0xE7, 16 IB &UIMM8 AX
+ 0xE7, 16 IB IMM8 AX
+ 0xE7, 32 IB &UIMM8 EAX
+ 0xE7, 32 IB IMM8 EAX
+ 0xEE, DX AL
+ 0xEF, 16 DX AX
+ 0xEF, 32 DX EAX;
+OPCODE OUTSB 0x6E;
+OPCODE OUTSW 0x6F, 16;
+OPCODE OUTSD 0x6F, 32;
+OPCODE REP_INSB
+ 0xF3 0x6C, %
+ 0xF3 0x48 0x6C;
+OPCODE REP_INSW 0xF3 0x6D, 16;
+OPCODE REP_INSD 0xF3 0x6D, 32;
+OPCODE REP_MOVSB
+ 0xF3 0xA4, %
+ 0xF3 0x48 0xA4;
+OPCODE REP_MOVSW 0xF3 0xA5, 16;
+OPCODE REP_MOVSD 0xF3 0xA5, 32;
+OPCODE REP_MOVSQ 0xF3 0x48 0xA5, 32;
+OPCODE REP_OUTSB,
+ 0xF3 0x6E, %
+ 0xF3 0x48 0x6E;
+OPCODE REP_OUTSW 0xF3 0x6F, 16;
+OPCODE REP_OUTSD 0xF3 0x6F, 32;
+OPCODE REP_LODSB
+ 0xF2 0xAC, %
+ 0xF2 0x48 0xAC;
+OPCODE REP_LODSW 0xF2 0xAD, 16;
+OPCODE REP_LODSD 0xF2 0xAD, 32;
+OPCODE REP_LODSQ 0xF2 0x48 0xAD, 32;
+OPCODE REP_STOSB
+ 0xF3 0xAA, %
+ 0xF3 0x48 0xAA;
+OPCODE REP_STOSW 0xF3 0xAB, 16;
+OPCODE REP_STOSD 0xF3 0xAB, 32;
+OPCODE REP_STOSQ 0xF3 0x48 0xAB, 32;
+OPCODE REPE_CMPSB
+ 0xF3 0xA6, %
+ 0xF3 0x48 0xA6;
+OPCODE REPE_CMPSW 0xF3 0xA7, 16;
+OPCODE REPE_CMPSD 0xF3 0xA7, 32;
+OPCODE REPE_CMPSQ 0xF3 0x48 0xA7, 32;
+OPCODE REPE_SCASB
+ 0xF3 0xAE, %
+ 0xF3 0x48 0xAE;
+OPCODE REPE_SCASW 0xF3 0xAF, 16;
+OPCODE REPE_SCASD 0xF3 0xAF, 32;
+OPCODE REPE_SCASQ 0xF3 0x48 0xAF, 32;
+OPCODE REPNE_CMPSB
+ 0xF2 0xA6, %
+ 0xF2 0x48 0xA6;
+OPCODE REPNE_CMPSW 0xF2 0xA7, 16;
+OPCODE REPNE_CMPSD 0xF2 0xA7, 32;
+OPCODE REPNE_CMPSQ 0xF2 0x48 0xA7, 32;
+OPCODE REPNE_SCASB
+ 0xF2 0xAE, %
+ 0xF2 0x48 0xAE;
+OPCODE REPNE_SCASW 0xF2 0xAF, 16;
+OPCODE REPNE_SCASD 0xF2 0xAF, 32;
+OPCODE REPNE_SCASQ 0xF2 0x48 0xAF, 32;
+OPCODE RET 0xC3;
+OPCODE RET1 0xC2, IW IMM16;
+OPCODE RETF 0xCB;
+OPCODE RETF1 0xCA, IW IMM16;
+OPCODE REX 0x48;
+OPCODE REX2 0x40;
+OPCODE RSM 0x0F 0xAA;
+OPCODE SAHF 0x9E;
+OPCODE SCASB 0xAE;
+OPCODE SCASW 0xAF, 16;
+OPCODE SCASD 0xAF, 32;
+OPCODE SCASQ 0xAF, 32=;
+OPCODE SEGCS 0x2E;
+OPCODE SEGSS 0x36;
+OPCODE SEGDS 0x3E;
+OPCODE SEGES 0x26;
+OPCODE SEGFS 0x64;
+OPCODE SEGGS 0x65;
+OPCODE SETO  0x0F 0x90, RM8;
+OPCODE SETNO 0x0F 0x91, RM8;
+OPCODE SETB  0x0F 0x92, RM8     :SETC SETNAE;
+OPCODE SETAE 0x0F 0x93, RM8     :SETNC SETNB;
+OPCODE SETE  0x0F 0x94, RM8     :SETZ;
+OPCODE SETNE 0x0F 0x95, RM8     :SETNZ;
+OPCODE SETBE 0x0F 0x96, RM8     :SETNA;
+OPCODE SETA  0x0F 0x97, RM8     :SETNBE;
+OPCODE SETS  0x0F 0x98, RM8;
+OPCODE SETNS 0x0F 0x99, RM8;
+OPCODE SETP  0x0F 0x9A, RM8     :SETPE;
+OPCODE SETNP 0x0F 0x9B, RM8     :SETPO;
+OPCODE SETL  0x0F 0x9C, RM8     :SETNGE;
+OPCODE SETGE 0x0F 0x9D, RM8     :SETNL;
+OPCODE SETLE 0x0F 0x9E, RM8     :SETNG;
+OPCODE SETG  0x0F 0x9F, RM8     :SETNLE;
+OPCODE SHLD
+ 0x0F 0xA5,/R 16 RM16 R16
+ 0x0F 0xA5,/R 32 RM32 R32
+ 0x0F 0xA5,/R 32 RM64 R64;
+OPCODE SHRD
+ 0x0F 0xAD,/R 16 RM16 R16
+ 0x0F 0xAD,/R 32 RM32 R32
+ 0x0F 0xAD,/R 32 RM64 R64;
+OPCODE STC 0xF9;
+OPCODE STD 0xFD;
+OPCODE STI 0xFB;
+OPCODE STOSB 0xAA;
+OPCODE STOSW 0xAB, 16;
+OPCODE STOSD 0xAB, 32;
+OPCODE STOSQ 0xAB, 32=;
+OPCODE STR
+ 0x0F 0x00,/1 16 RM16
+ 0x0F 0x00,/1 32 RM32
+ 0x0F 0x00,/1 32 RM64;
+OPCODE VERR
+ 0x0F 0x00,/4 16 RM16
+ 0x0F 0x00,/4 32 RM32
+ 0x0F 0x00,/4 32 RM64;
+OPCODE VERW
+ 0x0F 0x00,/5 16 RM16
+ 0x0F 0x00,/5 32 RM32
+ 0x0F 0x00,/5 32 RM64;
+OPCODE WAIT 0x9B;
+OPCODE FWAIT 0x9B;
+OPCODE XADD
+ 0x0F 0xC0,/R RM8 R8
+ 0x0F 0xC1,/R 16 RM16 R16
+ 0x0F 0xC1,/R 32 RM32 R32
+ 0x0F 0xC1,/R 32 RM64 R64;
+OPCODE XLATB 0xD7;
+
+OPCODE ROL
+ 0xD2,/0 RM8 CL
+ 0xD3,/0 16 RM16 CL
+ 0xD3,/0 32 RM32 CL
+ 0xD3,/0 32 RM64 CL
+ 0xC0,/0 IB &RM8 UIMM8
+ 0xC0,/0 IB RM8 IMM8
+ 0xC1,/0 16 IB &RM16 UIMM8
+ 0xC1,/0 16 IB RM16 IMM8
+ 0xC1,/0 32 IB &RM32 UIMM8
+ 0xC1,/0 32 IB RM32 IMM8
+ 0xC1,/0 32 IB &RM64 UIMM8
+ 0xC1,/0 32 IB RM64 IMM8;
+OPCODE ROL1
+ 0xD0,/0 RM8
+ 0xD1,/0 16 RM16
+ 0xD1,/0 32 RM32
+ 0xD1,/0 32 RM64;
+OPCODE ROR
+ 0xD2,/1 RM8 CL
+ 0xD3,/1 16 RM16 CL
+ 0xD3,/1 32 RM32 CL
+ 0xD3,/1 32 RM64 CL
+ 0xC0,/1 IB &RM8 UIMM8
+ 0xC0,/1 IB RM8 IMM8
+ 0xC1,/1 16 IB &RM16 UIMM8
+ 0xC1,/1 16 IB RM16 IMM8
+ 0xC1,/1 32 IB &RM32 UIMM8
+ 0xC1,/1 32 IB RM32 IMM8
+ 0xC1,/1 32 IB &RM64 UIMM8
+ 0xC1,/1 32 IB RM64 IMM8;
+OPCODE ROR1
+ 0xD0,/1 RM8
+ 0xD1,/1 16 RM16
+ 0xD1,/1 32 RM32
+ 0xD1,/1 32 RM64;
+OPCODE RCL
+ 0xD2,/2 RM8 CL
+ 0xD3,/2 16 RM16 CL
+ 0xD3,/2 32 RM32 CL
+ 0xD3,/2 32 RM64 CL
+ 0xC0,/2 IB &RM8 UIMM8
+ 0xC0,/2 IB RM8 IMM8
+ 0xC1,/2 16 IB &RM16 UIMM8
+ 0xC1,/2 16 IB RM16 IMM8
+ 0xC1,/2 32 IB &RM32 UIMM8
+ 0xC1,/2 32 IB RM32 IMM8
+ 0xC1,/2 32 IB &RM64 UIMM8
+ 0xC1,/2 32 IB RM64 IMM8;
+OPCODE RCL1
+ 0xD0,/2 RM8
+ 0xD1,/2 16 RM16
+ 0xD1,/2 32 RM32
+ 0xD1,/2 32 RM64;
+OPCODE RCR
+ 0xD2,/3 RM8 CL
+ 0xD3,/3 16 RM16 CL
+ 0xD3,/3 32 RM32 CL
+ 0xD3,/3 32 RM64 CL
+ 0xC0,/3 IB &RM8 UIMM8
+ 0xC0,/3 IB RM8 IMM8
+ 0xC1,/3 16 IB &RM16 UIMM8
+ 0xC1,/3 16 IB RM16 IMM8
+ 0xC1,/3 32 IB &RM32 UIMM8
+ 0xC1,/3 32 IB RM32 IMM8
+ 0xC1,/3 32 IB &RM64 UIMM8
+ 0xC1,/3 32 IB RM64 IMM8;
+OPCODE RCR1
+ 0xD0,/3 RM8
+ 0xD1,/3 16 RM16
+ 0xD1,/3 32 RM32
+ 0xD1,/3 32 RM64;
+OPCODE SHL
+ 0xD2,/4 RM8 CL
+ 0xD3,/4 16 RM16 CL
+ 0xD3,/4 32 RM32 CL
+ 0xD3,/4 32 RM64 CL
+ 0xC0,/4 IB &RM8 UIMM8
+ 0xC0,/4 IB RM8 IMM8
+ 0xC1,/4 16 IB &RM16 UIMM8
+ 0xC1,/4 16 IB RM16 IMM8
+ 0xC1,/4 32 IB &RM32 UIMM8
+ 0xC1,/4 32 IB RM32 IMM8
+ 0xC1,/4 32 IB &RM64 UIMM8
+ 0xC1,/4 32 IB RM64 IMM8        :SAL;
+OPCODE SHL1
+ 0xD0,/4 RM8
+ 0xD1,/4 16 RM16
+ 0xD1,/4 32 RM32
+ 0xD1,/4 32 RM64                :SAL1;
+OPCODE SHR
+ 0xD2,/5 RM8 CL
+ 0xD3,/5 16 RM16 CL
+ 0xD3,/5 32 RM32 CL
+ 0xD3,/5 32 RM64 CL
+ 0xC0,/5 IB &RM8 UIMM8
+ 0xC0,/5 IB RM8 IMM8
+ 0xC1,/5 16 IB &RM16 UIMM8
+ 0xC1,/5 16 IB RM16 IMM8
+ 0xC1,/5 32 IB &RM32 UIMM8
+ 0xC1,/5 32 IB RM32 IMM8
+ 0xC1,/5 32 IB &RM64 UIMM8
+ 0xC1,/5 32 IB RM64 IMM8;
+OPCODE SHR1
+ 0xD0,/5 RM8
+ 0xD1,/5 16 RM16
+ 0xD1,/5 32 RM32
+ 0xD1,/5 32 RM64;
+OPCODE SAR
+ 0xD2,/7 RM8 CL
+ 0xD3,/7 16 RM16 CL
+ 0xD3,/7 32 RM32 CL
+ 0xD3,/7 32 RM64 CL
+ 0xC0,/7 IB &RM8 UIMM8
+ 0xC0,/7 IB RM8 IMM8
+ 0xC1,/7 16 IB &RM16 UIMM8
+ 0xC1,/7 16 IB RM16 IMM8
+ 0xC1,/7 32 IB &RM32 UIMM8
+ 0xC1,/7 32 IB RM32 IMM8
+ 0xC1,/7 32 IB &RM64 UIMM8
+ 0xC1,/7 32 IB RM64 IMM8;
+OPCODE SAR1
+ 0xD0,/7 RM8
+ 0xD1,/7 16 RM16
+ 0xD1,/7 32 RM32
+ 0xD1,/7 32 RM64;
+
+OPCODE FILD
+ 0xDF,/0 M16    //Load I16
+ 0xDB,/0 M32    //Load I32
+ 0xDF,/5 `M64;  //Load I64
+OPCODE FISTP
+ 0xDF,/7 `M64;  //Store I64
+OPCODE FISTTP
+ 0xDD,/1 `M64;  //Store I64
+OPCODE FLD
+ 0xD9,/0 M32    //Load F32
+ 0xDD,/0 `M64   //Load F64
+ 0xD9 0xC0,+I* STI;
+OPCODE FSTP
+ 0xD9,/3 M32    //Store F32
+ 0xDD,/3 `M64   //Store F64
+ 0xDD 0xD8,+I* STI;
+OPCODE FST
+ 0xD9,/2 M32    //Store F32
+ 0xDD,/2 `M64   //Store F64
+ 0xDD 0xD0,+I* STI;
+OPCODE FRSTOR
+ 0xDD,/4 M32
+ 0xDD,/4 M64;
+OPCODE FSAVE
+ 0xDD,/6 M32
+ 0xDD,/6 M64;
+
+OPCODE FYL2X 0xD9 0xF1,*;
+OPCODE FYL2XP1 0xD9 0xF9,*;
+OPCODE F2XM1 0xD9 0xF0,*;
+OPCODE FABS 0xD9 0xE1,*;
+OPCODE FCHS 0xD9 0xE0,*;
+OPCODE FSIN 0xD9 0xFE,*;
+OPCODE FCOS 0xD9 0xFF,*;
+OPCODE FPTAN 0xD9 0xF2,*;
+OPCODE FPATAN 0xD9 0xF3,*;
+OPCODE FSQRT 0xD9 0xFA,*;
+OPCODE FMULP 0xDE 0xC8,+I* STI ST0;
+OPCODE FMUL 
+ 0xD8,/1 ST0 M32
+ 0xDC,/1 `ST0 M64
+ 0xD8 0xC8,+I* ST0 STI
+ 0xDC 0xC8,+I* STI ST0;
+OPCODE FIMUL 
+ 0xDA,/1 ST0 M32
+ 0xDE,/1 ST0 M16;
+OPCODE FDIVP 0xDE 0xF8,+I* STI ST0;
+OPCODE FDIV 
+ 0xD8,/6 ST0 M32
+ 0xDC,/6 `ST0 M64
+ 0xD8 0xF0,+I* ST0 STI
+ 0xDC 0xF8,+I* STI ST0;
+OPCODE FDIVRP 0xDE 0xF0,+I* STI ST0;
+OPCODE FDIVR 
+ 0xD8,/7 ST0 M32
+ 0xDC,/7 `ST0 M64
+ 0xD8 0xF8,+I* ST0 STI
+ 0xDC 0xF0,+I* STI ST0;
+OPCODE FPREM 0xD9 0xF8,*;
+OPCODE FADDP 0xDE 0xC0,+I* STI ST0;
+OPCODE FADD 
+ 0xD8,/0 ST0 M32
+ 0xDC,/0 `ST0 M64
+ 0xD8 0xC0,+I* ST0 STI
+ 0xDC 0xC0,+I* STI ST0;
+OPCODE FSUBP 0xDE 0xE8,+I* STI ST0;
+OPCODE FSUB 
+ 0xD8,/4 ST0 M32
+ 0xDC,/4 `ST0 M64
+ 0xD8 0xE0,+I* ST0 STI
+ 0xDC 0xE8,+I* STI ST0;
+OPCODE FSUBRP 0xDE 0xE0,+I* STI ST0;
+OPCODE FSUBR 
+ 0xD8,/5 ST0 M32
+ 0xDC,/5 `ST0 M64
+ 0xD8 0xE8,+I* ST0 STI
+ 0xDC 0xE0,+I* STI ST0;
+OPCODE FCOMIP 0xDF 0xF0,+I* ST0 STI;
+OPCODE FCOMI 0xDB 0xF0,+I* ST0 STI;
+OPCODE FCLEX 0x9B 0xDB 0xE2,*;
+OPCODE FNCLEX 0xDB 0xE2,*;
+OPCODE FSTSW 0xDF 0xE0,*;
+OPCODE FDECSTP 0xD9 0xF6,*;
+OPCODE FINCSTP 0xD9 0xF7,*;
+OPCODE FFREE 0xDD 0xC0,+I* STI;
+OPCODE FRNDINT 0xD9 0xFC,*;
+OPCODE FSCALE 0xD9 0xFD,*;
+OPCODE FXTRACT 0xD9 0xF4,*;
+
+OPCODE FLD1 0xD9 0xE8,*;
+OPCODE FLDL2T 0xD9 0xE9,*;
+OPCODE FLDL2E 0xD9 0xEA,*;
+OPCODE FLDPI 0xD9 0xEB,*;
+OPCODE FLDLG2 0xD9 0xEC,*;
+OPCODE FLDLN2 0xD9 0xED,*;
+OPCODE FLDZ 0xD9 0xEE,*;
+
+OPCODE FXCH 0xD9 0xC8,+I* STI;
+OPCODE FTST 0xD9 0xE4,*;
+OPCODE FXAM 0xD9 0xE5,*;
+OPCODE FINIT 0x9B 0xDB 0xE3;
+OPCODE FNINIT 0xDB 0xE3;
+
+OPCODE FSTCW 
+ 0xD9,/7 M16;
+OPCODE FLDCW 
+ 0xD9,/5 M16;
+OPCODE FXSAVE   //512 byte
+ 0x0F 0xAE,/0 32 M32
+ 0x0F 0xAE,/0 32 M64;
+OPCODE FXRSTOR  //512 byte
+ 0x0F 0xAE,/1 32 M32
+ 0x0F 0xAE,/1 32 M64;
+
+OPCODE WBINVD 0x0F 0x09;
+OPCODE CLFLUSH 0x0F 0xAE,/7 RM8;
+OPCODE INVLPG 0x0F 0x01,/7 RM8;
+OPCODE CPUID 0x0F 0xA2, 32=;
+OPCODE WRMSR 0x0F 0x30, 32=;
+OPCODE RDTSC 0x0F 0x31;
+OPCODE RDMSR 0x0F 0x32, 32=;
+OPCODE PAUSE 0xF3 0x90;
+
+OPCODE MOV_CR0_EAX 0x0F 0x22 0xC0;
+OPCODE MOV_EAX_CR0 0x0F 0x20 0xC0;
+OPCODE MOV_CR2_EAX 0x0F 0x22 0xD0;
+OPCODE MOV_EAX_CR2 0x0F 0x20 0xD0;
+OPCODE MOV_CR3_EAX 0x0F 0x22 0xD8;
+OPCODE MOV_EAX_CR3 0x0F 0x20 0xD8;
+OPCODE MOV_CR4_EAX 0x0F 0x22 0xE0;
+OPCODE MOV_EAX_CR4 0x0F 0x20 0xE0;
+
+OPCODE MOV_CR0_RAX 0x0F 0x22 0xC0, 32=;
+OPCODE MOV_RAX_CR0 0x0F 0x20 0xC0, 32=;
+OPCODE MOV_CR2_RAX 0x0F 0x22 0xD0, 32=;
+OPCODE MOV_RAX_CR2 0x0F 0x20 0xD0, 32=;
+OPCODE MOV_CR3_RAX 0x0F 0x22 0xD8, 32=;
+OPCODE MOV_RAX_CR3 0x0F 0x20 0xD8, 32=;
+OPCODE MOV_CR4_RAX 0x0F 0x22 0xE0, 32=;
+OPCODE MOV_RAX_CR4 0x0F 0x20 0xE0, 32=;
+
+ diff --git a/public/Wb/Home/Src/Compiler/OptLib.HC.HTML b/public/Wb/Home/Src/Compiler/OptLib.HC.HTML new file mode 100755 index 0000000..02795dc --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OptLib.HC.HTML @@ -0,0 +1,596 @@ + + + + + + + + + + + +
+CCodeMisc *OptLabelFwd(CCodeMisc *lb)
+{
+  CCodeMisc *lb1;
+  while (lb1=lb->fwd)
+    lb=lb1;
+  return lb;
+}
+
+CHashClass *OptClassFwd(CHashClass *tmpc)
+{//Class forwarding for unions and subclasses.
+  CHashClass *tmpc1;
+  while (tmpc1=tmpc->fwd_class)
+    tmpc=tmpc1;
+  return tmpc;
+}
+
+U0 OptSetNOP1(CIntermediateCode *tmpi)
+{
+  tmpi->ic_code=IC_NOP1;
+  tmpi->ic_flags=0;
+  tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;
+  tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;
+}
+
+U0 OptSetNOP2(CIntermediateCode *tmpi,I64 stk_delta=1)
+{
+  tmpi->ic_code=IC_NOP2;
+  tmpi->ic_data=stk_delta;
+  tmpi->arg1.type=MDF_NULL+tmpi->arg1.type.raw_type;
+  tmpi->res.type =MDF_NULL+tmpi->res.type.raw_type;
+}
+
+CIntermediateCode *OptFree(CIntermediateCode *tmpi)
+{//We might access freed entries in CICTreeLinks
+  QueRem(tmpi);
+  Free(tmpi);
+  return NULL;
+}
+
+CIntermediateCode *OptLag(CIntermediateCode *tmpi)
+{
+  do {
+    if (!tmpi->ic_code)
+      return NULL;
+    else
+      tmpi=tmpi->last;
+  } while (tmpi->ic_code<=IC_END_EXP);
+  return tmpi;
+}
+
+CIntermediateCode *OptLag1(CIntermediateCode *tmpi)
+{
+  do {
+    if (!tmpi->ic_code)
+      return NULL;
+    else
+      tmpi=tmpi->last;
+  } while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);
+  return tmpi;
+}
+
+CIntermediateCode *OptLag2(CIntermediateCode *tmpi)
+{
+  do {
+    if (!tmpi->ic_code)
+      return NULL;
+    else
+      tmpi=tmpi->last;
+  } while (tmpi->ic_code<IC_END_EXP);
+  return tmpi;
+}
+
+CIntermediateCode *OptLead1(CIntermediateCode *tmpi)
+{
+  do {
+    tmpi=tmpi->next;
+    if (!tmpi->ic_code)
+      return NULL;
+  } while (tmpi->ic_code==IC_NOP1||tmpi->ic_code==IC_NOP2);
+  return tmpi;
+}
+
+I64 CmpOffset2Reg(I64 offset,COptReg *reg_offsets)
+{
+  I64 i;
+  for (i=0;i<REG_REGS_NUM;i++)
+    if (offset==reg_offsets[i].offset)
+      return i;
+  return -1;
+}
+
+#define FBO1_NOT_CONST  0
+#define FBO1_INT        1
+#define FBO1_F64        2
+
+Bool OptFixupBinaryOp1(CIntermediateCode *tmpi,
+     CIntermediateCode *tmpi1,CIntermediateCode *tmpi2,
+     Bool *is_unsigned)
+{
+  CIntermediateCode *tmpii;
+  CHashClass *tmpc=tmpi->ic_class,*tmpc1,*tmpc2;
+
+  if (tmpi1->ic_flags&ICF_RES_TO_INT)
+    tmpc1=cmp.internal_types[RT_I64];
+  else if (tmpi1->ic_flags&ICF_RES_TO_F64)
+    tmpc1=cmp.internal_types[RT_F64];
+  else {
+    tmpc1=OptClassFwd(tmpi1->ic_class);
+  }
+
+  if (tmpi2->ic_flags&ICF_RES_TO_INT)
+    tmpc2=cmp.internal_types[RT_I64];
+  else if (tmpi2->ic_flags&ICF_RES_TO_F64)
+    tmpc2=cmp.internal_types[RT_F64];
+  else {
+    tmpc2=OptClassFwd(tmpi2->ic_class);
+  }
+
+  if (tmpc1->raw_type>tmpc2->raw_type)
+    tmpc=tmpi->ic_class=tmpc1;
+  else
+    tmpc=tmpi->ic_class=tmpc2;
+
+  if (tmpc->raw_type==RT_F64) {
+    if (tmpi1->ic_code==IC_IMM_I64) {
+      tmpi1->ic_data(F64)=tmpi1->ic_data;
+      tmpi1->ic_class=cmp.internal_types[RT_F64];
+      tmpi1->ic_code=IC_IMM_F64;
+      tmpi1->ic_flags&=~ICF_RES_TO_F64;
+    } else
+      if (tmpc1->raw_type!=RT_F64)
+        tmpi1->ic_flags|=ICF_RES_TO_F64;
+    if (tmpi2->ic_code==IC_IMM_I64) {
+      tmpi2->ic_data(F64)=tmpi2->ic_data;
+      tmpi2->ic_class=cmp.internal_types[RT_F64];
+      tmpi2->ic_code=IC_IMM_F64;
+      tmpi2->ic_flags&=~ICF_RES_TO_F64;
+    } else
+      if (tmpc2->raw_type!=RT_F64)
+        tmpi2->ic_flags|=ICF_RES_TO_F64;
+    if (IC_LESS<=tmpi->ic_code<=IC_GREATER_EQU && (tmpii=OptLead1(tmpi)) &&
+          tmpii->ic_code!=IC_PUSH_CMP && tmpii->ic_code!=IC_AND_AND) {
+//We are looking for float comparisons to zero to convert to int.
+      if (tmpi1->ic_code==IC_IMM_F64 && !tmpi1->ic_data &&
+            tmpi2->ic_code==IC_DEREF && tmpc2==cmp.internal_types[RT_F64]) {
+        tmpi1->ic_code==IC_IMM_I64;
+        goto fb_here1;
+      } else if (tmpi2->ic_code==IC_IMM_F64 && !tmpi2->ic_data &&
+            tmpi1->ic_code==IC_DEREF && tmpc1==cmp.internal_types[RT_F64]) {
+        tmpi2->ic_code==IC_IMM_I64;
+fb_here1:
+        tmpi1->ic_flags&=~ICF_RES_TO_F64;
+        tmpi->ic_class=tmpi1->ic_class=tmpi2->ic_class=
+              cmp.internal_types[RT_I64];
+        *is_unsigned=FALSE;
+        return FBO1_NOT_CONST;
+      }
+      goto fb_here2;
+    } else {
+fb_here2:
+      if (tmpi1->ic_code==IC_IMM_F64 && tmpi2->ic_code==IC_IMM_F64 &&
+            !(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
+        tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+        OptSetNOP1(tmpi1);
+        OptSetNOP1(tmpi2);
+        return FBO1_F64;
+      } else
+        return FBO1_NOT_CONST;
+    }
+  }
+  *is_unsigned=tmpc1->raw_type&RTF_UNSIGNED || tmpc2->raw_type&RTF_UNSIGNED;
+  if (tmpi1->ic_code==IC_IMM_I64 && tmpi2->ic_code==IC_IMM_I64 &&
+        !(tmpi->ic_flags&(ICF_PUSH_CMP|ICF_POP_CMP))) {
+    tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+    OptSetNOP1(tmpi1);
+    OptSetNOP1(tmpi2);
+    return FBO1_INT;
+  } else
+    return FBO1_NOT_CONST;
+}
+
+Bool OptFixupBinaryOp2(CIntermediateCode **tmpi1,CIntermediateCode **tmpi2)
+{
+  CIntermediateCode *tmpii1=*tmpi1,
+        *tmpii2=*tmpi2;
+  if (tmpii1->ic_code==IC_IMM_I64 && !(tmpii1->ic_flags & ICF_RES_TO_F64))
+    return TRUE;
+  if (tmpii2->ic_code==IC_IMM_I64 && !(tmpii2->ic_flags & ICF_RES_TO_F64)) {
+    *tmpi1=tmpii2;
+    *tmpi2=tmpii1;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+Bool OptFixupUnaryOp(CIntermediateCode *tmpi, CIntermediateCode *tmpi1,
+     Bool *is_unsigned)
+{
+  CHashClass *tmpc,*tmpc1;
+  tmpc1=OptClassFwd(tmpi1->ic_class);
+  tmpi->ic_class=tmpc1;
+  tmpc=tmpi->ic_class;
+  if (tmpc->raw_type==RT_F64) {
+    if (tmpi1->ic_code==IC_IMM_I64) {
+      tmpi1->ic_data(F64)=tmpi1->ic_data;
+      tmpi1->ic_class=cmp.internal_types[RT_F64];
+      tmpi1->ic_code=IC_IMM_F64;
+      tmpi1->ic_flags&=~ICF_RES_TO_F64;
+    } else
+      if (tmpc1->raw_type!=RT_F64)
+        tmpi1->ic_flags|=ICF_RES_TO_F64;
+    if (tmpi1->ic_code==IC_IMM_F64) {
+      tmpi->ic_flags|=tmpi1->ic_flags;
+      OptSetNOP1(tmpi1);
+      return FBO1_F64;
+    } else
+      return FBO1_NOT_CONST;
+  }
+  *is_unsigned=tmpc1->raw_type&RTF_UNSIGNED;
+  if (tmpi1->ic_code==IC_IMM_I64) {
+    tmpi->ic_flags|=tmpi1->ic_flags;
+    OptSetNOP1(tmpi1);
+    return FBO1_INT;
+  } else
+    return FBO1_NOT_CONST;
+}
+
+extern CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi);
+
+CIntermediateCode *OptBrZero(CCmpCtrl *cc,CIntermediateCode *tmpi)
+{
+  CCodeMisc *lb_true,*lb_false;
+  CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;
+  switch (tmpii->ic_code) {
+    case IC_NOT:
+      tmpi->ic_code=IC_BR_NOT_ZERO;
+      tmpi->ic_class=tmpii->ic_class;
+      tmpi->ic_flags|=tmpii->ic_flags;
+      tmpi->t.arg1_class=tmpii->t.arg1_class;
+      tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+      OptFree(tmpii);
+      return OptBrNotZero(cc,tmpi);
+    case IC_EQU_EQU...IC_LESS_EQU:
+      tmpi->ic_code=(tmpii->ic_code-IC_EQU_EQU)^1+IC_BR_EQU_EQU;
+      break;
+    case IC_OR_OR:
+      tmpi->ic_code=IC_BR_OR_OR_ZERO;
+      break;
+    case IC_AND_AND:
+      tmpi->ic_code=IC_BR_AND_AND_ZERO;
+      break;
+    case IC_AND:
+      tmpi->ic_code=IC_BR_AND_ZERO;
+      break;
+    case IC_MM_:
+      if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&
+            tmpii->ic_class->raw_type!=RT_F64)
+        tmpi->ic_code=IC_BR_MM_ZERO;
+      break;
+    case IC_CALL_END:
+      tmpii2=OptLag(tmpii);
+      switch (tmpii2->ic_code) {
+        start:
+          case IC_CARRY:
+            tmpii2->ic_code=IC_BR_NOT_CARRY;
+            break;
+          case IC_BT:
+            tmpii2->ic_code=IC_BR_NOT_BT;
+            break;
+          case IC_LBTS:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTS:
+            tmpii2->ic_code=IC_BR_NOT_BTS;
+            break;
+          case IC_LBTR:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTR:
+            tmpii2->ic_code=IC_BR_NOT_BTR;
+            break;
+          case IC_LBTC:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTC:
+            tmpii2->ic_code=IC_BR_NOT_BTC;
+            break;
+        end:
+          tmpii2->ic_data=tmpi->ic_data;
+          tmpii->ic_code=IC_CALL_END2;
+          OptSetNOP1(tmpi);
+          return tmpii;
+      }
+      break;
+  }
+  if (tmpi->ic_code!=IC_BR_ZERO) {
+    tmpi->ic_class=tmpii->ic_class;
+    tmpi->ic_flags|=tmpii->ic_flags;
+    tmpi->t.arg1_class=tmpii->t.arg1_class;
+    tmpi->t.arg2_class=tmpii->t.arg2_class;
+    tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+    tmpi->t.arg2_tree=tmpii->t.arg2_tree;
+    OptFree(tmpii);
+
+    if (tmpi->ic_flags&ICF_PUSH_CMP &&
+          IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&
+          !(tmpi->ic_flags&ICF_USE_F64)) {
+      tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;
+      tmpi->ic_flags&=~ICF_PUSH_CMP;
+      tmpii=tmpi->next; //IC_PUSH_CMP inst
+      while (tmpii->ic_code!=IC_PUSH_CMP)
+        tmpii=tmpii->next;
+      tmpii->t.arg1_tree=tmpi;
+      OptSetNOP1(tmpii);
+    }
+
+    lb_true=tmpi->ic_data;
+    if (tmpi->ic_code==IC_BR_AND_AND_ZERO) {
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->ic_data=lb_true;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_code=IC_BR_ZERO;
+      OptBrZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_ZERO;
+      tmpii=OptBrZero(cc,tmpii);
+      OptSetNOP1(tmpi);
+    } else if (tmpi->ic_code==IC_BR_OR_OR_ZERO) {
+      lb_false=COCMiscNew(cc,CMT_LABEL);
+      tmpi->ic_code=IC_LABEL;
+      tmpi->ic_flags=0;
+      tmpi->ic_data=lb_false;
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_data=lb_false;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      OptBrNotZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_ZERO;
+      tmpii=OptBrZero(cc,tmpii);
+    } else
+      tmpii=tmpi;
+    if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {
+      tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;
+      tmpi->ic_flags&=~ICF_POP_CMP;
+    }
+    return tmpii;
+  }
+  return tmpi;
+}
+
+CIntermediateCode *OptBrNotZero(CCmpCtrl *cc,CIntermediateCode *tmpi)
+{
+  CCodeMisc *lb_true,*lb_false;
+  CIntermediateCode *tmpii=OptLag(tmpi),*tmpii2;
+  switch (tmpii->ic_code) {
+    case IC_NOT:
+      tmpi->ic_code=IC_BR_ZERO;
+      tmpi->ic_class=tmpii->ic_class;
+      tmpi->ic_flags|=tmpii->ic_flags;
+      tmpi->t.arg1_class=tmpii->t.arg1_class;
+      tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+      OptFree(tmpii);
+      return OptBrZero(cc,tmpi);
+    case IC_EQU_EQU...IC_LESS_EQU:
+      tmpi->ic_code=tmpii->ic_code+IC_BR_EQU_EQU-IC_EQU_EQU;
+      break;
+    case IC_OR_OR:
+      tmpi->ic_code=IC_BR_OR_OR_NOT_ZERO;
+      break;
+    case IC_AND_AND:
+      tmpi->ic_code=IC_BR_AND_AND_NOT_ZERO;
+      break;
+    case IC_AND:
+      tmpi->ic_code=IC_BR_AND_NOT_ZERO;
+      break;
+    case IC_MM_:
+      if (cc->pass==2 && !(tmpii->ic_flags&ICF_RES_TO_F64) &&
+            tmpii->ic_class->raw_type!=RT_F64)
+        tmpi->ic_code=IC_BR_MM_NOT_ZERO;
+      break;
+    case IC_CALL_END:
+      tmpii2=OptLag(tmpii);
+      switch (tmpii2->ic_code) {
+        start:
+          case IC_CARRY:
+            tmpii2->ic_code=IC_BR_CARRY;
+            break;
+          case IC_BT:
+            tmpii2->ic_code=IC_BR_BT;
+            break;
+          case IC_LBTS:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTS:
+            tmpii2->ic_code=IC_BR_BTS;
+            break;
+          case IC_LBTR:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTR:
+            tmpii2->ic_code=IC_BR_BTR;
+            break;
+          case IC_LBTC:
+            tmpii2->ic_flags|=ICF_LOCK;
+          case IC_BTC:
+            tmpii2->ic_code=IC_BR_BTC;
+            break;
+        end:
+          tmpii2->ic_data=tmpi->ic_data;
+          tmpii->ic_code=IC_CALL_END2;
+          OptSetNOP1(tmpi);
+          return tmpii;
+      }
+      break;
+  }
+  if (tmpi->ic_code!=IC_BR_NOT_ZERO) {
+    tmpi->ic_class=tmpii->ic_class;
+    tmpi->ic_flags|=tmpii->ic_flags;
+    tmpi->t.arg1_class=tmpii->t.arg1_class;
+    tmpi->t.arg2_class=tmpii->t.arg2_class;
+    tmpi->t.arg1_tree=tmpii->t.arg1_tree;
+    tmpi->t.arg2_tree=tmpii->t.arg2_tree;
+    OptFree(tmpii);
+
+    if (tmpi->ic_flags&ICF_PUSH_CMP &&
+          IC_BR_NOT_EQU<=tmpi->ic_code<=IC_BR_LESS_EQU &&
+          !(tmpi->ic_flags&ICF_USE_F64)) {
+      tmpi->ic_code+=IC_BR_EQU_EQU2-IC_BR_EQU_EQU;
+      tmpi->ic_flags&=~ICF_PUSH_CMP;
+      tmpii=tmpi->next; //IC_PUSH_CMP inst
+      while (tmpii->ic_code!=IC_PUSH_CMP)
+        tmpii=tmpii->next;
+      tmpii->t.arg1_tree=tmpi;
+      OptSetNOP1(tmpii);
+    }
+
+    lb_true=tmpi->ic_data;
+    if (tmpi->ic_code==IC_BR_OR_OR_NOT_ZERO) {
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      OptBrNotZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      tmpii=OptBrNotZero(cc,tmpii);
+      OptSetNOP1(tmpi);
+    } else if (tmpi->ic_code==IC_BR_AND_AND_NOT_ZERO) {
+      lb_false=COCMiscNew(cc,CMT_LABEL);
+      tmpi->ic_code=IC_LABEL;
+      tmpi->ic_flags=0;
+      tmpi->ic_data=lb_false;
+      tmpii=tmpi->t.arg1_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg1_tree;
+      tmpii->t.arg1_class=tmpi->t.arg1_class;
+      tmpii->ic_data=lb_false;
+      tmpii->ic_code=IC_BR_ZERO;
+      OptBrZero(cc,tmpii);
+      tmpii=tmpi->t.arg2_tree->next;
+      tmpii->t.arg1_tree=tmpi->t.arg2_tree;
+      tmpii->t.arg1_class=tmpi->t.arg2_class;
+      tmpii->ic_data=lb_true;
+      tmpii->ic_code=IC_BR_NOT_ZERO;
+      tmpii=OptBrNotZero(cc,tmpii);
+    } else
+      tmpii=tmpi;
+    if (tmpi->ic_flags&ICF_POP_CMP && tmpi->t.arg1_tree->ic_code==IC_NOP1) {
+      tmpi->t.arg1_tree=tmpi->t.arg1_tree->t.arg1_tree;
+      tmpi->ic_flags&=~ICF_POP_CMP;
+    }
+    return tmpii;
+  }
+  return tmpi;
+}
+
+U0 OptFixSizeOf(CIntermediateCode *tmpi1,
+        CIntermediateCode *tmpi_push,CHashClass *tmpcc)
+{
+  if (tmpi1->ic_code==IC_MUL && tmpi1->t.arg2_tree->ic_code==IC_SIZEOF) {
+    tmpi1->t.arg2_tree->ic_code=IC_IMM_I64;
+    tmpi1->t.arg2_tree->ic_class=tmpcc;
+    tmpi_push->ic_class=tmpcc;
+    if (tmpcc->ptr_stars_cnt) {
+      tmpcc--;
+      if (tmpcc->size==1)
+        goto here;
+      tmpi1->t.arg2_tree->ic_data=tmpcc->size;
+    } else {
+here:
+      if (tmpi_push==tmpi1)
+        tmpi1->t.arg2_tree->ic_data=1;
+      else {
+        OptSetNOP1(tmpi1->t.arg2_tree);
+        OptSetNOP1(tmpi1);
+      }
+    }
+  }
+}
+
+I64 CmpRawType(CHashClass *tmpc)
+{
+  if (tmpc) {
+    tmpc=OptClassFwd(tmpc);
+    return tmpc->raw_type;
+  }
+  return 0;
+}
+
+I64 CmpRawTypePointed(CHashClass *tmpc)
+{
+  if (tmpc) {
+    if (tmpc->ptr_stars_cnt)
+      tmpc--;
+    tmpc=OptClassFwd(tmpc);
+    return tmpc->raw_type;
+  }
+  return 0;
+}
+
+U0 CmpMinTypePointed(CIntermediateCode *tmpi,I64 pt1)
+{
+  I64 pt;
+  if ((pt=tmpi->arg1_type_pointed_to) && pt!=RT_F64 && 0<pt1<pt)
+    tmpi->arg1_type_pointed_to=pt;
+}
+
+U0 CmpF1PushPop(CIntermediateCode *tmpi,CIntermediateCode *tmpi2)
+{
+  if (intermediate_code_table[tmpi2->ic_code].fpop||
+        tmpi2->ic_flags&ICF_RES_TO_F64)
+    Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+}
+
+U0 CmpF2PushPop(CIntermediateCode *tmpi,
+        CIntermediateCode *tmpi1,CIntermediateCode *tmpi2)
+{
+  if ((tmpi2->ic_code==IC_MOV || tmpi2->ic_code==IC_IMM_F64) &&
+        !(tmpi2->ic_flags&ICF_RES_TO_F64) &&
+        (intermediate_code_table[tmpi1->ic_code].fpop ||
+        tmpi1->ic_flags&ICF_RES_TO_F64))
+    Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+  else if ((intermediate_code_table[tmpi2->ic_code].fpop ||
+        tmpi2->ic_flags&ICF_RES_TO_F64)&&
+        !(tmpi1->ic_flags&ICF_RES_TO_F64))
+    Bts(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+}
+
+class COptMemberVar
+{
+  I64 score,offset_start,offset_end,lea_balance;
+  CMemberLst *m;
+};
+
+I64 OptMVCompare(COptMemberVar *mv1,COptMemberVar *mv2)
+{
+  return mv2->score-mv1->score;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/OptPass012.HC.HTML b/public/Wb/Home/Src/Compiler/OptPass012.HC.HTML new file mode 100755 index 0000000..3c79339 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OptPass012.HC.HTML @@ -0,0 +1,1319 @@ + + + + + + + + + + + +
+/*OptPass012
+
+Pass#0
+When parsing the arg expressions to a function
+call, there is a call to OptPass012 to determine
+the type of the expression. OptPass012
+
+Pass#1&2
+Constant expressions are simplified.
+Eliminated opcodes are set to NOP.
+Types are determined by reconstructing an
+expression tree for operators
+CIntermediateCode.CICTreeLinks.
+
+Pointer arithmetic size is set, once
+the type is determined.
+
+Branches are expressed with short-circuit
+logic. 3-Arg comparisons are established.
+
+*/
+
+CIntermediateCode *OptPass012(CCmpCtrl *cc)
+{/*Simplify CONST arithmetic.
+Sets the class throughout Expression trees.
+Returns the type of an Expression for use
+in int<-->F64 conversions of fun
+args.
+*/
+  I64 code,i;
+  Bool is_unsigned;
+  CHashClass *tmpc,*tmpc1,*tmpc2;
+  CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpi3,*tmpi_push,
+        *last_with_class=NULL;
+  CCodeMisc *lb,*lb1,*lb2;
+  CPrsStk *ps;
+  if (!(ps=cc->ps))
+    ps=cc->ps=MAlloc(sizeof(CPrsStk));
+  ps->ptr=0;
+  ps->ptr2=0;
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    tmpc=tmpi->ic_class;
+    tmpi->ic_class2=tmpc;
+    tmpi_push=tmpi;
+    MemSet(&tmpi->arg1,0,3*sizeof(CICArg));
+    tmpi->arg1_type_pointed_to=0;
+    switch [intermediate_code_table[code].arg_cnt] {
+      case IS_V_ARG:
+        ps->ptr-=tmpi->ic_data>>2;
+        break;
+      case IS_2_ARG:
+        tmpi2=PrsPop(ps);
+        tmpc2=tmpi2->ic_class;
+        tmpi->t.arg2_tree=tmpi2;
+        tmpi->t.arg2_class=PrsPop(ps);
+      case IS_1_ARG:
+        tmpi1=PrsPop(ps);
+        tmpc1=tmpi1->ic_class;
+        tmpi->t.arg1_tree=tmpi1;
+        tmpi->t.arg1_class=PrsPop(ps);
+        break;
+      case IS_0_ARG: //nobound switch
+        break;
+    }
+    if (intermediate_code_table[code].not_const)
+      cc->flags|=CCF_NOT_CONST;
+    switch [code] {
+      case IC_IMM_F64:
+        tmpi->ic_flags&=~ICF_RES_TO_F64;
+        if (cc->pass==2 && tmpi->ic_flags&ICF_RES_TO_INT) {
+          tmpi->ic_data=ToI64(tmpi->ic_data(F64));
+          tmpi->ic_flags&=~ICF_RES_TO_INT;
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+        }
+        break;
+      case IC_IMM_I64:
+        tmpi->ic_flags&=~ICF_RES_TO_INT;
+        if (cc->pass==2 && tmpi->ic_flags&ICF_RES_TO_F64) {
+          tmpi->ic_data(F64)=ToF64(tmpi->ic_data);
+          tmpi->ic_flags&=~ICF_RES_TO_F64;
+          tmpi->ic_code=IC_IMM_F64;
+          tmpi->ic_class=cmp.internal_types[RT_F64];
+        }
+        break;
+      case IC_HOLYC_TYPECAST:
+        if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) {
+          if (tmpi->ic_class->raw_type==RT_F64)
+            tmpi1->ic_code=IC_IMM_F64;
+          else
+            tmpi1->ic_code=IC_IMM_I64;
+          tmpi1->ic_class=tmpi->ic_class;
+          tmpi1->ic_flags|=tmpi->ic_flags;
+          tmpi_push=tmpi1;
+          OptSetNOP1(tmpi);
+        } else {
+          if (tmpi->ic_data) {//was paren
+            if (!tmpi_push->ic_class->ptr_stars_cnt) {
+              if (tmpi_push->ic_class->raw_type==RT_F64)
+                tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+              else
+                tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+            }
+          } else {
+            tmpi1->ic_class=tmpi->ic_class;
+            tmpi1->ic_flags|=tmpi->ic_flags;
+            tmpi_push=tmpi1;
+            OptSetNOP1(tmpi);
+          }
+        }
+        break;
+      case IC_FS:
+      case IC_GS:
+//CALL,FS/GS,CALL_END,IMM,ADD,DEREF-->MOV_FS/GS
+        tmpi1=tmpi->next->next; //IMM
+        tmpi2=tmpi1->next; //ADD
+        tmpi3=tmpi2->next; //DEREF
+        if (tmpi1->ic_code==IC_IMM_I64 && tmpi2->ic_code==IC_ADD &&
+              tmpi3->ic_code==IC_DEREF &&
+              !(tmpi3->ic_flags&~ICG_NO_CVT_MASK)) {
+          tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags|tmpi3->ic_flags;
+          if (tmpi->ic_code==IC_FS)
+            tmpi->ic_code=IC_MOV_FS;
+          else
+            tmpi->ic_code=IC_MOV_GS;
+          tmpi->ic_data=tmpi1->ic_data;
+          tmpi->ic_class =tmpi3->ic_class;
+          tmpi->ic_class2=tmpi3->ic_class2;
+          OptSetNOP1(tmpi1);
+          OptSetNOP1(tmpi2);
+          OptSetNOP1(tmpi3);
+
+          tmpi1=tmpi->last; //CALL
+          tmpi2=tmpi->next; //CALL_END
+          tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+          OptSetNOP1(tmpi1);
+          OptSetNOP1(tmpi2);
+        }
+        break;
+      case IC_PUSH_CMP:
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_AND_AND)
+            tmpi1=OptLag(tmpi1);
+          if (tmpi1)
+            tmpi->ic_class=tmpi1->ic_class;
+        }
+        tmpi->ic_class2=tmpi->ic_class;
+        tmpi->ic_data=0;
+        if (tmpi->ic_class->raw_type==RT_F64)
+          tmpi->ic_flags|=ICF_USE_F64;
+        break;
+      case IC_COM:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi->ic_data=~tmpi1->ic_data;
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_flags|=tmpi1->ic_flags;
+          OptSetNOP1(tmpi1);
+        }
+        tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        break;
+      start:
+        case IC_NOT:
+          if (tmpc->raw_type==RT_F64) {
+            if (tmpi1->ic_code==IC_IMM_F64) {
+              tmpi->ic_data(F64)=!tmpi1->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            }
+            break;
+          }
+          if (tmpi1->ic_code==IC_IMM_I64) {
+            tmpi->ic_data=!tmpi1->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            OptSetNOP1(tmpi1);
+          }
+          break;
+        case IC_UNARY_MINUS:
+          if (i=OptFixupUnaryOp(tmpi,tmpi1,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              tmpi->ic_data=-tmpi1->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=-tmpi1->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          }
+          if (tmpc1->type&HTT_INTERNAL_TYPE && tmpc1->raw_type&RTF_UNSIGNED)
+            tmpi->ic_class=cmp.internal_types[tmpc1->raw_type-1];
+          break;
+        case IC_SHL_CONST:
+          if (i=OptFixupUnaryOp(tmpi,tmpi1,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<<tmpi->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<<tmpi->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)<<tmpi->ic_data;
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi1->ic_code==IC_SHL_CONST) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->ic_data+=tmpi1->ic_data;
+            OptSetNOP1(tmpi1);
+          }
+          break;
+        case IC_SHR_CONST:
+          if (i=OptFixupUnaryOp(tmpi,tmpi1,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>>tmpi->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>>tmpi->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)>>tmpi->ic_data;
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi1->ic_code==IC_SHR_CONST) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->ic_data+=tmpi1->ic_data;
+            OptSetNOP1(tmpi1);
+          }
+          break;
+        case IC_SHL:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<<tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<<tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64) << tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi2->ic_code==IC_IMM_I64) {
+            tmpi->ic_flags|=tmpi2->ic_flags;
+            tmpi->ic_data=tmpi2->ic_data;
+            tmpi->ic_code=IC_SHL_CONST;
+            OptSetNOP1(tmpi2);
+          }
+          break;
+        case IC_SHR:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>>tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>>tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64) >> tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (tmpi2->ic_code==IC_IMM_I64) {
+            tmpi->ic_flags|=tmpi2->ic_flags;
+            tmpi->ic_data=tmpi2->ic_data;
+            tmpi->ic_code=IC_SHR_CONST;
+            OptSetNOP1(tmpi2);
+          }
+          break;
+      end:
+        if (!tmpi_push->ic_class->ptr_stars_cnt) {
+          if (tmpi_push->ic_class->raw_type==RT_F64)
+            tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+          else
+            tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        }
+        break;
+      case IC_DEREF:
+        if (cc->pass==2) {
+          if (!tmpc->size)
+            LexWarn(cc,"Dereference U0 ");
+          if (tmpi1->ic_class->raw_type!=RT_F64) {
+            if (tmpi1->ic_code==IC__PP) {
+              tmpi->ic_code=IC_DEREF_PP;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            } else if (tmpi1->ic_code==IC__MM) {
+              tmpi->ic_code=IC_DEREF_MM;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            }
+          }
+        }
+        break;
+      case IC__PP:
+      case IC__MM:
+      case IC_PP_:
+      case IC_MM_:
+        if (cc->pass==2 && !tmpc->size)
+          LexWarn(cc,"Dereference U0 ");
+        break;
+      case IC_POWER:
+        tmpc=tmpi->ic_class=cmp.internal_types[RT_F64];
+        if (tmpc1->raw_type!=RT_F64)
+          tmpi1->ic_flags|=ICF_RES_TO_F64;
+        if (tmpc2->raw_type!=RT_F64)
+          tmpi2->ic_flags|=ICF_RES_TO_F64;
+        tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+        break;
+      start:
+        case IC_MUL:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)*tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)*tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)*tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (tmpi1->ic_code==IC_IMM_I64 && cc->pass==2) {
+              switch (i=tmpi1->ic_data) {
+                case 0:
+                  break;
+                case 1:
+                  tmpi2->ic_flags|=tmpi->ic_flags|tmpi1->ic_flags;
+                  tmpi2->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi2;
+                  OptSetNOP1(tmpi1);
+                  OptSetNOP1(tmpi);
+                  break;
+                default:
+                  if (Bsf(i)==Bsr(i)) {
+                    tmpi->ic_flags|=tmpi1->ic_flags;
+                    tmpi->t.arg1_class=tmpi->t.arg2_class;
+                    tmpi->ic_data=Bsf(i);
+                    tmpi->ic_code=IC_SHL_CONST;
+                    OptSetNOP1(tmpi1);
+                  }
+              }
+            } else if (tmpi2->ic_code==IC_IMM_I64) {
+              switch (i=tmpi2->ic_data) {
+                case 0:
+                  break;
+                case 1:
+                  tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                  break;
+                default:
+                  if (Bsf(i)==Bsr(i)) {
+                    tmpi->ic_flags|=tmpi2->ic_flags;
+                    tmpi->ic_data=Bsf(i);
+                    tmpi->ic_code=IC_SHL_CONST;
+                    OptSetNOP1(tmpi2);
+                  } else if (tmpi1->ic_code==IC_MUL && cc->pass==2) {
+                    if (tmpi1->t.arg1_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      tmpi1->t.arg1_tree->ic_data*=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      tmpi1->t.arg2_tree->ic_data*=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    }
+                  }
+              }
+            } else if (tmpi2->ic_code==IC_IMM_F64 && cc->pass==2) {
+              if (tmpi2->ic_data(F64)==1.0) {
+                tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                tmpi1->ic_class2=tmpi->ic_class2;
+                tmpi_push=tmpi1;
+                OptSetNOP1(tmpi2);
+                OptSetNOP1(tmpi);
+              } else if (tmpi1->ic_code==IC_MUL) {
+                if (tmpi1->t.arg1_tree->ic_code==IC_IMM_F64) {
+                  tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                  tmpi1->t.arg1_tree->ic_data(F64)*=tmpi2->ic_data(F64);
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_F64) {
+                  tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                  tmpi1->t.arg2_tree->ic_data(F64)*=tmpi2->ic_data(F64);
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                }
+              }
+            }
+          }
+          break;
+        case IC_DIV:
+          if ((tmpi2->ic_data || tmpi2->ic_code!=IC_IMM_I64 &&
+                tmpi2->ic_code!=IC_IMM_F64) &&
+                (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned))) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)/tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)/tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)/
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (tmpi2->ic_code==IC_IMM_I64 && (i=tmpi2->ic_data)) {
+              if (i==1) {
+                tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                tmpi1->ic_class2=tmpi->ic_class2;
+                tmpi_push=tmpi1;
+                OptSetNOP1(tmpi2);
+                OptSetNOP1(tmpi);
+              } else if (Bsf(i)==Bsr(i)) {
+                tmpi->ic_flags|=tmpi2->ic_flags;
+                tmpi->ic_data=Bsf(i);
+                tmpi->ic_code=IC_SHR_CONST;
+                OptSetNOP1(tmpi2);
+              }
+            }
+          }
+          break;
+        case IC_MOD:
+          if ((tmpi2->ic_data || tmpi2->ic_code!=IC_IMM_I64 &&
+                tmpi2->ic_code!=IC_IMM_F64) &&
+                (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned))) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)%tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)%tmpi2->ic_data(I64);
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)%
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else if (cc->pass==2 && tmpi2->ic_code==IC_IMM_I64 &&
+                (i=tmpi2->ic_data) && Bsf(i)==Bsr(i) &&
+                tmpi_push->ic_class->raw_type!=RT_F64 &&
+                tmpi_push->ic_class->raw_type&RTF_UNSIGNED) {//do only unsigned
+            tmpi2->ic_data=i-1;
+            tmpi->ic_code=IC_AND;
+          }
+          break;
+        case IC_AND:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data&tmpi2->ic_data;
+            if (i==FBO1_INT)
+              tmpi->ic_code=IC_IMM_I64;
+            else
+              tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_OR:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data|tmpi2->ic_data;
+            if (i==FBO1_INT)
+              tmpi->ic_code=IC_IMM_I64;
+            else
+              tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_XOR:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data^tmpi2->ic_data;
+            if (i==FBO1_INT)
+              tmpi->ic_code=IC_IMM_I64;
+            else
+              tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_ADD:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              tmpi->ic_data=tmpi1->ic_data+tmpi2->ic_data;
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)+
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (tmpi1->ic_code==IC_ABS_ADDR&&tmpi2->ic_code==IC_IMM_I64) {
+              tmpi->ic_flags|=tmpi1->ic_flags|tmpi2->ic_flags;
+              tmpi->ic_data=tmpi1->ic_data+tmpi2->ic_data;
+              tmpi->ic_code=IC_ABS_ADDR;
+              OptSetNOP1(tmpi1);
+              OptSetNOP1(tmpi2);
+            } else if (cc->pass==2) {
+              if (tmpi1->ic_code==IC_IMM_I64) {
+                if (!tmpi1->ic_data) {
+                  tmpi2->ic_flags|=tmpi1->ic_flags|tmpi->ic_flags;
+                  tmpi2->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi2;
+                  OptSetNOP1(tmpi1);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi2->ic_code==IC_ADD||
+                      tmpi2->ic_code==IC_SUB) {
+                  if (tmpi2->t.arg1_tree->ic_code==IC_IMM_I64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    tmpi2->t.arg1_tree->ic_data+=tmpi1->ic_data;
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi2->t.arg2_tree->ic_code==IC_IMM_I64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    if (tmpi2->ic_code==IC_ADD)
+                      tmpi2->t.arg2_tree->ic_data+=tmpi1->ic_data;
+                    else
+                      tmpi2->t.arg2_tree->ic_data-=tmpi1->ic_data;
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              } else if (tmpi2->ic_code==IC_IMM_I64) {
+                if (!tmpi2->ic_data) {
+                  tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi1->ic_code==IC_ADD ||
+                      tmpi1->ic_code==IC_SUB) {
+                  if (tmpi1->t.arg1_tree->ic_code==IC_IMM_I64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    tmpi1->t.arg1_tree->ic_data+=tmpi2->ic_data;
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_I64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    if (tmpi1->ic_code==IC_ADD)
+                      tmpi1->t.arg2_tree->ic_data+=tmpi2->ic_data;
+                    else
+                      tmpi1->t.arg2_tree->ic_data-=tmpi2->ic_data;
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              } else if (tmpi1->ic_code==IC_IMM_F64) {
+                if (!tmpi1->ic_data) {
+                  tmpi2->ic_flags|=tmpi1->ic_flags|tmpi->ic_flags;
+                  tmpi2->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi2;
+                  OptSetNOP1(tmpi1);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi2->ic_code==IC_ADD||
+                      tmpi2->ic_code==IC_SUB) {
+                  if (tmpi2->t.arg1_tree->ic_code==IC_IMM_F64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    tmpi2->t.arg1_tree->ic_data(F64)+=tmpi1->ic_data(F64);
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi2->t.arg2_tree->ic_code==IC_IMM_F64) {
+                    tmpi2->ic_flags|=tmpi->ic_flags;
+                    if (tmpi2->ic_code==IC_ADD)
+                      tmpi2->t.arg2_tree->ic_data(F64)+=tmpi1->ic_data(F64);
+                    else
+                      tmpi2->t.arg2_tree->ic_data(F64)-=tmpi1->ic_data(F64);
+                    tmpi2->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi2;
+                    OptSetNOP1(tmpi1);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              } else if (tmpi2->ic_code==IC_IMM_F64) {
+                if (!tmpi2->ic_data) {
+                  tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else if (tmpi1->ic_code==IC_ADD ||
+                      tmpi1->ic_code==IC_SUB) {
+                  if (tmpi1->t.arg1_tree->ic_code==IC_IMM_F64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    tmpi1->t.arg1_tree->ic_data(F64)+=tmpi2->ic_data(F64);
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_F64) {
+                    tmpi1->ic_flags|=tmpi->ic_flags;
+                    if (tmpi1->ic_code==IC_ADD)
+                      tmpi1->t.arg2_tree->ic_data(F64)+=tmpi2->ic_data(F64);
+                    else
+                      tmpi1->t.arg2_tree->ic_data(F64)-=tmpi2->ic_data(F64);
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  }
+                }
+              }
+            }
+          }
+          break;
+        case IC_SUB:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              tmpi->ic_data=tmpi1->ic_data-tmpi2->ic_data;
+              tmpi->ic_code=IC_IMM_I64;
+            } else {
+              tmpi->ic_data(F64)=tmpi1->ic_data(F64)-
+                    tmpi2->ic_data(F64);
+              tmpi->ic_code=IC_IMM_F64;
+            }
+          } else {
+            if (cc->pass==2) {
+              if (tmpi2->ic_code==IC_IMM_I64) {
+                if (!tmpi2->ic_data) {
+                  tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                  tmpi1->ic_class2=tmpi->ic_class2;
+                  tmpi_push=tmpi1;
+                  OptSetNOP1(tmpi2);
+                  OptSetNOP1(tmpi);
+                } else
+                  if (tmpi1->ic_code==IC_ADD ||
+                        tmpi1->ic_code==IC_SUB) {
+                    if (tmpi1->t.arg1_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      tmpi1->t.arg1_tree->ic_data-=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_I64) {
+                      tmpi1->ic_flags|=tmpi->ic_flags;
+                      if (tmpi1->ic_code==IC_ADD)
+                        tmpi1->t.arg2_tree->ic_data-=tmpi2->ic_data;
+                      else
+                        tmpi1->t.arg2_tree->ic_data+=tmpi2->ic_data;
+                      tmpi1->ic_class2=tmpi->ic_class2;
+                      tmpi_push=tmpi1;
+                      OptSetNOP1(tmpi2);
+                      OptSetNOP1(tmpi);
+                    }
+                  }
+              } else
+                if (tmpi2->ic_code==IC_IMM_F64) {
+                  if (!tmpi2->ic_data) {
+                    tmpi1->ic_flags|=tmpi2->ic_flags|tmpi->ic_flags;
+                    tmpi1->ic_class2=tmpi->ic_class2;
+                    tmpi_push=tmpi1;
+                    OptSetNOP1(tmpi2);
+                    OptSetNOP1(tmpi);
+                  } else
+                    if (tmpi1->ic_code==IC_ADD || tmpi1->ic_code==IC_SUB) {
+                      if (tmpi1->t.arg1_tree->ic_code==IC_IMM_F64) {
+                        tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                        tmpi1->t.arg1_tree->ic_data(F64)-=tmpi2->ic_data(F64);
+                        tmpi1->ic_class2=tmpi->ic_class2;
+                        tmpi_push=tmpi1;
+                        OptSetNOP1(tmpi2);
+                        OptSetNOP1(tmpi);
+                      } else if (tmpi1->t.arg2_tree->ic_code==IC_IMM_F64) {
+                        tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+                        if (tmpi1->ic_code==IC_ADD)
+                          tmpi1->t.arg2_tree->ic_data(F64)-=tmpi2->ic_data(F64);
+                        else
+                          tmpi1->t.arg2_tree->ic_data(F64)+=tmpi2->ic_data(F64);
+                        tmpi1->ic_class2=tmpi->ic_class2;
+                        tmpi_push=tmpi1;
+                        OptSetNOP1(tmpi2);
+                        OptSetNOP1(tmpi);
+                      }
+                    }
+                }
+            }
+          }
+          break;
+        case IC_AND_AND:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data&&tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          break;
+        case IC_OR_OR:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data||tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          break;
+        case IC_XOR_XOR:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data^^tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          break;
+      end:
+        if (!tmpi_push->ic_class->ptr_stars_cnt) {
+          if (tmpi_push->ic_class->raw_type==RT_F64)
+            tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+          else if (is_unsigned)
+            tmpi_push->ic_class2=cmp.internal_types[RT_U64];
+          else
+            tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        }
+        break;
+      start:
+        case IC_EQU_EQU:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data==tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          } else
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          break;
+        case IC_NOT_EQU:
+          if (OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            tmpi->ic_data=tmpi1->ic_data!=tmpi2->ic_data;
+            tmpi->ic_code=IC_IMM_I64;
+          } else
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          break;
+        case IC_LESS:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)<tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+        case IC_GREATER_EQU:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>=tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>=tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)>=tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+        case IC_GREATER:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)>tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)>tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)>tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+        case IC_LESS_EQU:
+          if (i=OptFixupBinaryOp1(tmpi,tmpi1,tmpi2,&is_unsigned)) {
+            if (i==FBO1_INT) {
+              if (is_unsigned)
+                tmpi->ic_data=tmpi1->ic_data(U64)<=tmpi2->ic_data(U64);
+              else
+                tmpi->ic_data=tmpi1->ic_data(I64)<=tmpi2->ic_data(I64);
+            } else
+              tmpi->ic_data=tmpi1->ic_data(F64)<=tmpi2->ic_data(F64);
+            tmpi->ic_code=IC_IMM_I64;
+          } else {
+            if (is_unsigned)
+              tmpi->ic_flags|=ICF_USE_UNSIGNED;
+            if (tmpi->ic_class->raw_type==RT_F64)
+              tmpi->ic_flags|=ICF_USE_F64;
+          }
+          break;
+      end:
+        tmpi->ic_flags&=~ICF_RES_TO_INT;
+        if (!tmpi_push->ic_class->ptr_stars_cnt) {
+          if (tmpi_push->ic_class->raw_type==RT_F64)
+            tmpi_push->ic_class2=cmp.internal_types[RT_F64];
+          else if (is_unsigned)
+            tmpi_push->ic_class2=cmp.internal_types[RT_U64];
+          else
+            tmpi_push->ic_class2=cmp.internal_types[RT_I64];
+        }
+        if (tmpi_push->ic_flags & ICF_PUSH_CMP)
+          tmpi->ic_class=tmpi->ic_class2;
+        else
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+        break;
+      start:
+        if (cc->pass==2 && (!tmpc->size||!tmpc2->size))
+          LexWarn(cc,"Assign U0 ");
+        start:
+          case IC_MUL_EQU:
+            if (tmpi2->ic_code==IC_IMM_I64 && tmpc->raw_type!=RT_F64 &&
+                  tmpc2->raw_type!=RT_F64) {
+              if (i=tmpi2->ic_data) {
+                if (Bsf(i)==Bsr(i)) {
+                  tmpi2->ic_data=Bsf(i);
+                  tmpi->ic_code=IC_SHL_EQU;
+                }
+              }
+            }
+            break;
+          case IC_DIV_EQU:
+            if (tmpi2->ic_code==IC_IMM_I64 && tmpc->raw_type!=RT_F64 &&
+                  tmpc2->raw_type!=RT_F64 &&
+                  (i=tmpi2->ic_data) && Bsf(i)==Bsr(i)) {
+              tmpi2->ic_data=Bsf(i);
+              tmpi->ic_code=IC_SHR_EQU;
+            }
+            break;
+          case IC_MOD_EQU:
+            if (tmpi2->ic_code==IC_IMM_I64 && tmpc->raw_type!=RT_F64 &&
+                  tmpc2->raw_type!=RT_F64 &&
+                  (i=tmpi2->ic_data) && Bsf(i)==Bsr(i)) {
+              tmpi2->ic_data=i-1;
+              tmpi->ic_code=IC_AND_EQU;
+            }
+            break;
+          case IC_ADD_EQU:
+          case IC_SUB_EQU:
+            break;
+        end:
+          if (tmpi2->ic_class->raw_type==RT_F64)
+            tmpi->ic_flags=tmpi->ic_flags|ICF_USE_F64;
+          if (tmpc->raw_type==RT_F64) {
+            if (tmpc2->raw_type!=RT_F64)
+              tmpi2->ic_flags|=ICF_RES_TO_F64;
+          }
+          break;
+        case IC_ASSIGN:
+          if (tmpc->raw_type==RT_F64) {
+            if (tmpc2->raw_type!=RT_F64)
+              tmpi2->ic_flags|=ICF_RES_TO_F64;
+          } else {
+            if (tmpc2->raw_type==RT_F64)
+              tmpi2->ic_flags|=ICF_RES_TO_INT;
+          }
+          if (cc->pass==2 && tmpi1->ic_class->raw_type!=RT_F64) {
+            if (tmpi1->ic_code==IC__PP) {
+              tmpi->ic_code=IC_ASSIGN_PP;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              tmpi->t.class2=tmpi1->ic_class;
+              OptSetNOP1(tmpi1);
+            } else if (tmpi1->ic_code==IC__MM) {
+              tmpi->ic_code=IC_ASSIGN_MM;
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              tmpi->t.class2=tmpi1->ic_class;
+              OptSetNOP1(tmpi1);
+            }
+          }
+          break;
+        case IC_SHL_EQU:
+        case IC_SHR_EQU:
+        case IC_AND_EQU:
+        case IC_OR_EQU:
+        case IC_XOR_EQU:
+          if (tmpc2->raw_type==RT_F64)
+            tmpi2->ic_flags|=ICF_RES_TO_INT;
+          break;
+      end:
+        break;
+      case IC_ENTER:
+      case IC_LEAVE:
+        tmpi->ic_data=-cc->htc.fun->size;
+        break;
+      case IC_ADD_RSP:
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_ADD_RSP) {
+            tmpi->ic_data+=tmpi1->ic_data;
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            OptSetNOP1(tmpi1);
+          }
+        }
+      case IC_ADD_RSP1:
+        break;
+      case IC_BSF:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi1->ic_data=Bsf(tmpi1->ic_data);
+          tmpi_push=tmpi1;
+          OptSetNOP1(OptLag(tmpi1));    //CALL_START
+          tmpi2=OptLead1(tmpi);
+          tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);            //CALL_END
+          OptSetNOP1(tmpi);             //BSF
+        }
+        break;
+      case IC_BSR:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi1->ic_data=Bsr(tmpi1->ic_data);
+          tmpi_push=tmpi1;
+          OptSetNOP1(OptLag(tmpi1));    //CALL_START
+          tmpi2=OptLead1(tmpi);
+          tmpi1->ic_flags|=tmpi->ic_flags|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);            //CALL_END
+          OptSetNOP1(tmpi);             //BSR
+        }
+        break;
+      case IC_LBTS:
+      case IC_LBTR:
+      case IC_LBTC:
+        tmpi->ic_flags|=ICF_LOCK;
+        break;
+      case IC_TO_I64:
+        if (tmpi1->ic_code==IC_IMM_F64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_INT|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_data=ToI64(tmpi1->ic_data(F64));
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          tmpi->ic_class2=cmp.internal_types[RT_I64];
+          OptSetNOP1(tmpi1);
+        } else if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_F64|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_data=tmpi1->ic_data;
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          tmpi->ic_class2=cmp.internal_types[RT_I64];
+          OptSetNOP1(tmpi1);
+        }
+        if (tmpi1->ic_flags&ICF_RES_TO_F64) {
+          i=0;
+          tmpi2=tmpi1->last;
+          while (TRUE) {
+            if (tmpi2->ic_code==IC_CALL_START) {
+              if (!i) break;
+              i--;
+            } else if (tmpi2->ic_code==IC_CALL_END)
+              i++;
+            tmpi2=tmpi2->last;
+          }
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi1->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi1->ic_flags=tmpi->ic_flags|tmpi1->ic_flags&
+                ~(ICF_RES_TO_F64|ICF_PUSH_RES)|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi1->ic_class=cmp.internal_types[RT_I64];
+          tmpi1->ic_class2=cmp.internal_types[RT_I64];
+          tmpi_push=tmpi1;
+          OptSetNOP1(tmpi);
+        }
+        break;
+      case IC_TO_F64:
+        if (tmpi1->ic_code==IC_IMM_I64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_F64|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_F64;
+          tmpi->ic_data(F64)=ToF64(tmpi1->ic_data);
+          tmpi->ic_class=cmp.internal_types[RT_F64];
+          tmpi->ic_class2=cmp.internal_types[RT_F64];
+          OptSetNOP1(tmpi1);
+        } else if (tmpi1->ic_code==IC_IMM_F64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_INT|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_F64;
+          tmpi->ic_data=tmpi1->ic_data;
+          tmpi->ic_class=cmp.internal_types[RT_F64];
+          tmpi->ic_class2=cmp.internal_types[RT_F64];
+          OptSetNOP1(tmpi1);
+        }
+        if (tmpi1->ic_flags&ICF_RES_TO_INT) {
+          i=0;
+          tmpi2=tmpi1->last;
+          while (TRUE) {
+            if (tmpi2->ic_code==IC_CALL_START) {
+              if (!i) break;
+              i--;
+            } else if (tmpi2->ic_code==IC_CALL_END)
+              i++;
+            tmpi2=tmpi2->last;
+          }
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi1->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi1->ic_flags=tmpi->ic_flags|tmpi1->ic_flags&
+                ~(ICF_RES_TO_INT|ICF_PUSH_RES)|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi1->ic_class=cmp.internal_types[RT_F64];
+          tmpi1->ic_class2=cmp.internal_types[RT_F64];
+          tmpi_push=tmpi1;
+          OptSetNOP1(tmpi);
+        }
+        break;
+      case IC_TO_BOOL:
+        if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) {
+          tmpi2=tmpi1->last;
+          while (tmpi2->ic_code!=IC_CALL_START)
+            tmpi2=tmpi2->last;
+          OptSetNOP1(tmpi2);
+
+          tmpi2=tmpi->next;
+          while (tmpi2->ic_code!=IC_CALL_END)
+            tmpi2=tmpi2->next;
+
+          tmpi->ic_flags|=tmpi1->ic_flags&~ICF_RES_TO_F64|tmpi2->ic_flags;
+          OptSetNOP1(tmpi2);
+
+          tmpi->ic_code=IC_IMM_I64;
+          tmpi->ic_data=ToBool(tmpi1->ic_data);
+          tmpi->ic_class=cmp.internal_types[RT_I64];
+          tmpi->ic_class2=cmp.internal_types[RT_I64];
+          OptSetNOP1(tmpi1);
+        }
+        break;
+      case IC_BR_ZERO:
+        tmpi_push=OptBrZero(cc,tmpi);
+        break;
+      case IC_BR_NOT_ZERO:
+        tmpi_push=OptBrNotZero(cc,tmpi);
+        break;
+      case IC_NOP1:
+        if (tmpi->ic_flags&ICF_PUSH_RES) {
+          tmpi1=tmpi;
+          do tmpi1=tmpi1->last;
+          while (tmpi1->ic_code==IC_NOP1);
+          tmpi1->ic_flags|=ICF_PUSH_RES;
+          tmpi->ic_flags&=~ICF_PUSH_RES;
+        }
+        break;
+      case IC_NOP2:
+        ps->ptr+=tmpi->ic_data<<1;
+        break;
+      case IC_LABEL:
+        lb=OptLabelFwd(tmpi->ic_data);
+        lb1=tmpi->ic_data;
+        while (lb2=lb1->fwd) {
+          lb1->fwd=lb;
+          lb1=lb2;
+        }
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_JMP) {
+            lb1=tmpi1->ic_data;
+            while (lb1->fwd)
+              lb1=lb1->fwd;
+            if (lb1==lb) {
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              OptSetNOP1(tmpi1);
+            }
+          } else if (tmpi1->ic_code==IC_LABEL) {
+            lb1=tmpi1->ic_data;
+            if (!lb1->fwd)
+              lb1->fwd=lb;
+            if (tmpi1=OptLag(tmpi1)) {
+              if (tmpi1->ic_code==IC_JMP) {
+                lb1=tmpi1->ic_data;
+                while (lb1->fwd)
+                  lb1=lb1->fwd;
+                if (lb1==lb) {
+                  tmpi->ic_flags|=tmpi1->ic_flags;
+                  OptSetNOP1(tmpi1);
+                }
+              }
+            }
+          }
+        }
+        break;
+      case IC_JMP:
+        if (tmpi1=OptLag(tmpi)) {
+          if (tmpi1->ic_code==IC_LABEL) {
+            lb=OptLabelFwd(tmpi->ic_data);
+            lb1=OptLabelFwd(tmpi1->ic_data);
+            if (lb!=lb1)
+              lb1->fwd=lb;
+          }
+        }
+        break;
+      case IC_STR_CONST:
+      case IC_RBP:
+      case IC_MOV_FS:
+      case IC_MOV_GS:
+      case IC_RIP:
+      case IC_SIZEOF:
+      case IC_SQR:
+      case IC_ABS:
+      case IC_SQRT:
+      case IC_SIN:
+      case IC_COS:
+      case IC_TAN:
+      case IC_ATAN:
+      case IC_BR_CARRY:
+      case IC_BR_NOT_CARRY:
+      case IC_BR_EQU_EQU ...IC_BR_LESS_EQU:
+      case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
+      case IC_BR_OR_OR_NOT_ZERO:
+      case IC_BR_OR_OR_ZERO:
+      case IC_BR_AND_AND_NOT_ZERO:
+      case IC_BR_AND_AND_ZERO:
+      case IC_BR_AND_NOT_ZERO:
+      case IC_BR_AND_ZERO:
+      case IC_BR_MM_NOT_ZERO:
+      case IC_BR_MM_ZERO:
+      case IC_BR_BT:
+      case IC_BR_BTS:
+      case IC_BR_BTR:
+      case IC_BR_BTC:
+      case IC_BR_NOT_BT:
+      case IC_BR_NOT_BTS:
+      case IC_BR_NOT_BTR:
+      case IC_BR_NOT_BTC:
+      case IC_END:
+      case IC_ADDR:
+      case IC_RET:
+      case IC_END_EXP:
+      case IC_CALL_START:
+      case IC_CALL_END:
+      case IC_CALL_END2:
+      case IC_PUSH_REGS:
+      case IC_POP_REGS:
+      case IC_SUB_CALL:
+      case IC_CALL:
+      case IC_CALL_INDIRECT:
+      case IC_CALL_INDIRECT2:
+      case IC_CALL_EXTERN:
+      case IC_CALL_IMPORT:
+      case IC_PUSH:
+      case IC_POP:
+      case IC_INVLPG:
+      case IC_CLFLUSH:
+      case IC_GET_RFLAGS:
+      case IC_CARRY:
+      case IC_GET_RBP:
+      case IC_GET_RSP:
+      case IC_GET_RAX:
+      case IC_RETURN_VAL:
+      case IC_RETURN_VAL2:
+      case IC_ABS_ADDR:
+      case IC_HEAP_GLBL:
+      case IC_ADDR_IMPORT:
+      case IC_GET_LABEL:
+      case IC_TYPE:
+      case IC_RDTSC:
+      case IC_SET_RFLAGS:
+      case IC_SET_RBP:
+      case IC_SET_RSP:
+      case IC_SET_RAX:
+      case IC_SIGN_I64:
+      case IC_TOUPPER:
+      case IC_ABS_I64:
+      case IC_MIN_I64:
+      case IC_MAX_I64:
+      case IC_MIN_U64:
+      case IC_MAX_U64:
+      case IC_MOD_U64:
+      case IC_SQR_I64:
+      case IC_SQR_U64:
+      case IC_SWAP_U8:
+      case IC_SWAP_U16:
+      case IC_SWAP_U32:
+      case IC_SWAP_I64:
+      case IC_IN_U32:
+      case IC_IN_U16:
+      case IC_IN_U8:
+      case IC_STRLEN:
+      case IC_BT:
+      case IC_BTS:
+      case IC_BTR:
+      case IC_BTC:
+      case IC_QUE_INIT:
+      case IC_QUE_REM:
+      case IC_QUE_INS:
+      case IC_QUE_INS_REV:
+      case IC_OUT_U32:
+      case IC_OUT_U16:
+      case IC_OUT_U8:
+      case IC_NOBOUND_SWITCH:
+      case IC_SWITCH:
+      case IC_ASM:
+        break;
+      default:
+        "Pass:%d Missing IC hndlr\n",cc->pass;
+        ICPut(cc,tmpi);
+        LexExcept(cc,"Compiler Optimization Error at ");
+    }
+    if (intermediate_code_table[code].arg_cnt==IS_2_ARG) {
+      if (tmpi_push->ic_precedence&~ASSOC_MASK==PREC_ASSIGN)
+        OptFixSizeOf(tmpi2,tmpi_push,tmpi1->ic_class-1);
+      else {
+        OptFixSizeOf(tmpi1,tmpi_push,tmpi2->ic_class);
+        OptFixSizeOf(tmpi2,tmpi_push,tmpi1->ic_class);
+      }
+    }
+    if (intermediate_code_table[tmpi_push->ic_code].res_cnt) {
+      PrsPush(ps,tmpi->ic_class2);
+      PrsPush(ps,tmpi_push);
+    }
+    if (tmpi->ic_class) {
+      if (tmpi->ic_class->raw_type==RT_F64)
+        tmpi->ic_flags&=~ICF_RES_TO_F64;
+      else
+        tmpi->ic_flags&=~ICF_RES_TO_INT;
+      if (code>IC_END_EXP)
+        last_with_class=tmpi;
+    }
+    tmpi=tmpi->next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+//This is for determining type conversions for passing args to funs.
+  return last_with_class;
+}
+
+
+ diff --git a/public/Wb/Home/Src/Compiler/OptPass3.HC.HTML b/public/Wb/Home/Src/Compiler/OptPass3.HC.HTML new file mode 100755 index 0000000..8fedba1 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OptPass3.HC.HTML @@ -0,0 +1,653 @@ + + + + + + + + + + + +
+U0 OptPass3(CCmpCtrl *cc,COptReg *reg_offsets)
+{
+  CHashClass *tmpc,*tmpc1,*tmpc2;
+  CCodeMisc *lb;
+  CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpi_next,
+        *tmpil1,*tmpil2;
+  I64 code,i,j,l,member_cnt,used_reg_mask=0;
+  CMemberLst *tmpm;
+  COptMemberVar *mv=NULL;
+  CAOT *tmpaot;
+  CAOTImportExport *tmpie;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+
+  for (i=0;i<REG_REGS_NUM;i++) {
+    reg_offsets[i].offset=I64_MAX;
+    reg_offsets[i].m=NULL;
+  }
+  if (cc->htc.fun) {
+    member_cnt=cc->htc.fun->member_cnt;
+    if (Bt(&cc->htc.fun->flags,Ff_DOT_DOT_DOT))
+      member_cnt+=2;
+    mv=CAlloc(member_cnt*sizeof(COptMemberVar));
+    member_cnt=0;
+    tmpm=cc->htc.fun->member_lst_and_root;
+    while (tmpm) {
+      tmpc=OptClassFwd(tmpm->member_class);
+      if (0<=tmpm->reg<REG_REGS_NUM) {
+        if (Bts(&used_reg_mask,tmpm->reg))
+          PrintWarn("Reg in use\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                cc->lex_include_stk->full_name,
+                cc->lex_include_stk->line_num,tmpm->str,cc->htc.fun->str);
+        reg_offsets[tmpm->reg].offset=tmpm->offset;
+        reg_offsets[tmpm->reg].m=tmpm;
+      } else if (tmpc->raw_type!=RT_F64 && tmpm->reg!=REG_NONE ||
+            tmpm->reg==REG_ALLOC) {
+        if (tmpm->reg==REG_ALLOC)
+          mv[member_cnt].score=I64_MAX/2; //big but not too big
+        mv[member_cnt].offset_start=tmpm->offset;
+        mv[member_cnt].offset_end=tmpm->offset+MaxI64(1,tmpm->size);
+        mv[member_cnt++].m=tmpm;
+      } else if (tmpm->reg==REG_ALLOC)
+        PrintWarn("Can't reg var\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+              cc->lex_include_stk->full_name,
+              cc->lex_include_stk->line_num,tmpm->str,cc->htc.fun->str);
+      tmpm=tmpm->next;
+    }
+  } else
+    member_cnt=0;
+
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    tmpi_next=tmpi->next;
+    if (code==IC_NOP1)
+      OptFree(tmpi);
+    else {
+      if (tmpil1=OptLag(tmpi)) {
+        if (!(tmpil2=OptLag(tmpil1)))
+          tmpil2=&cmp.ic_nop;
+      } else
+        tmpil1=tmpil2=&cmp.ic_nop;
+      tmpc=tmpi->ic_class;
+      switch [intermediate_code_table[code].arg_cnt] {
+        case IS_V_ARG:
+          ps->ptr-=tmpi->ic_data>>3;
+          break;
+        case IS_2_ARG:
+          tmpi2=PrsPop(ps);
+          if (tmpi2->ic_flags&ICF_RES_TO_F64)
+            tmpc2=cmp.internal_types[RT_F64];
+          else if (tmpi2->ic_flags & ICF_RES_TO_INT)
+            tmpc2=cmp.internal_types[RT_I64];
+          else
+            tmpc2=tmpi->t.arg2_class;
+          tmpi->arg2.type=MDF_STK+CmpRawType(tmpc2);
+          tmpi->ic_flags|=ICF_ARG2_WAS_STK;
+        case IS_1_ARG:
+          tmpi1=PrsPop(ps);
+          if (tmpi1->ic_flags&ICF_RES_TO_F64)
+            tmpc1=cmp.internal_types[RT_F64];
+          else if (tmpi1->ic_flags & ICF_RES_TO_INT)
+            tmpc1=cmp.internal_types[RT_I64];
+          else
+            tmpc1=tmpi->t.arg1_class;
+          tmpi->arg1.type=MDF_STK+CmpRawType(tmpc1);
+          tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc1);
+          tmpi->ic_flags|=ICF_ARG1_WAS_STK;
+          break;
+        case IS_0_ARG: //nobound switch
+          break;
+      }
+      if (intermediate_code_table[code].res_cnt) {
+        tmpi->res.type=MDF_STK+CmpRawType(tmpc);
+        tmpi->ic_flags|=ICF_RES_WAS_STK;
+        PrsPush(ps,tmpi);
+      }
+      switch [code] {
+        case IC_IMM_F64:
+          tmpi->ic_flags&=~ICF_RES_TO_F64;
+          if (tmpi->ic_flags&ICF_RES_TO_INT) {
+            tmpi->ic_data=ToI64(tmpi->ic_data(F64));
+            tmpi->ic_flags&=~ICF_RES_TO_INT;
+            tmpi->ic_code=IC_IMM_I64;
+          }
+          break;
+        case IC_IMM_I64:
+          tmpi->ic_flags&=~ICF_RES_TO_INT;
+          if (tmpi->ic_flags&ICF_RES_TO_F64) {
+            tmpi->ic_data(F64)=ToF64(tmpi->ic_data);
+            tmpi->ic_flags&=~ICF_RES_TO_F64;
+            tmpi->ic_code=IC_IMM_F64;
+          }
+          break;
+        case IC_RBP:
+          tmpi->ic_code=IC_REG;
+          tmpi->arg1.reg=REG_RBP;
+          break;
+        case IC_DEREF:
+          tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+          if (tmpi1->ic_code==IC_LEA) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->arg1.reg=tmpi1->arg1.reg;
+            tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type;
+            tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc);
+            tmpi->ic_code=IC_MOV;
+            OptFree(tmpi1);
+            if (tmpi->arg1.reg==REG_RBP)
+              for (i=0;i<member_cnt;i++)
+                if (mv[i].offset_start==tmpi->arg1.disp) {
+                  mv[i].lea_balance--;
+                  mv[i].score++;
+                  break;
+                }
+          } else if (tmpil1->ic_code==IC_ADD_CONST) {
+            if (tmpil2->ic_code==IC_REG) {
+              tmpi->ic_flags|=tmpil2->ic_flags|tmpil1->ic_flags;
+              tmpi->arg1.reg=tmpil2->arg1.reg;
+              tmpi->arg1.disp=tmpi->ic_data;
+              tmpi->arg1.type=MDF_DISP+tmpi->res.type.raw_type;
+              tmpi->arg1_type_pointed_to=CmpRawTypePointed(tmpc);
+              tmpi->ic_code=IC_MOV;
+              OptFree(tmpil2);
+              OptFree(tmpil1);
+            }
+          }
+          break;
+        case IC__PP:
+        case IC__MM:
+        case IC_PP_:
+        case IC_MM_:
+          CmpMinTypePointed(tmpi,CmpRawTypePointed(tmpi->t.arg1_class));
+        case IC_DEREF_PP:
+        case IC_DEREF_MM:
+          if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
+                tmpi1->arg1.reg==REG_RBP)
+            for (i=0;i<member_cnt;i++)
+              if (mv[i].offset_start==tmpi1->arg1.disp) {
+                mv[i].lea_balance--;
+                mv[i].score++;
+                break;
+              }
+          tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+          break;
+        case IC_MUL:
+        case IC_DIV:
+          if (tmpc->raw_type==RT_F64) {
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+            break;
+          }
+          break;
+        case IC_ADD:
+          if (tmpc->raw_type==RT_F64) {
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+            break;
+          }
+          if (OptFixupBinaryOp2(&tmpi1,&tmpi2)) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            if (tmpi->t.arg1_tree!=tmpi2)
+              tmpi->t.arg1_class=tmpi->t.arg2_class;
+            tmpi->ic_data=tmpi1->ic_data;
+            tmpi->ic_code=IC_ADD_CONST;
+            tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+            tmpi->arg2.type=MDF_NULL;
+            OptFree(tmpi1);
+            if (tmpil2->ic_code==IC_REG && tmpil2->arg1.reg==REG_RBP) {
+              tmpi->ic_flags|=tmpil2->ic_flags;
+              tmpi->ic_code=IC_LEA;
+              tmpi->arg1.reg=REG_RBP;
+              tmpi->arg1.type=MDF_DISP+tmpi->arg1.type.raw_type;
+              tmpi->arg1.disp=tmpi->ic_data;
+              for (i=0;i<member_cnt;i++)
+                if (mv[i].offset_start<=tmpi->ic_data<mv[i].offset_end) {
+                  mv[i].lea_balance++;
+                  mv[i].score++;
+                  break;
+                }
+              OptFree(tmpil2);
+            }
+          }
+          break;
+        case IC_SUB:
+          if (tmpc->raw_type==RT_F64) {
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+            break;
+          }
+          if (tmpi2->ic_code==IC_IMM_I64) {
+            tmpi->ic_flags|=tmpi2->ic_flags;
+            tmpi->ic_data=tmpi2->ic_data;
+            tmpi->ic_code=IC_SUB_CONST;
+            tmpi->arg2.type=MDF_NULL;
+            OptFree(tmpi2);
+          }
+          break;
+        case IC_LESS:
+        case IC_GREATER_EQU:
+        case IC_GREATER:
+        case IC_LESS_EQU:
+          if (tmpi->ic_flags&ICF_USE_F64)
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+          break;
+        case IC_MUL_EQU:
+        case IC_DIV_EQU:
+        case IC_ADD_EQU:
+        case IC_SUB_EQU:
+          if (tmpc->raw_type==RT_F64)
+            CmpF1PushPop(tmpi,tmpi2);
+        case IC_ASSIGN_PP:
+        case IC_ASSIGN_MM:
+        case IC_ASSIGN:
+        case IC_SHL_EQU:
+        case IC_SHR_EQU:
+        case IC_MOD_EQU:
+        case IC_AND_EQU:
+        case IC_OR_EQU:
+        case IC_XOR_EQU:
+          if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
+                tmpi1->arg1.reg==REG_RBP)
+            for (i=0;i<member_cnt;i++)
+              if (mv[i].offset_start==tmpi1->arg1.disp) {
+                mv[i].lea_balance--;
+                mv[i].score++;
+                break;
+              }
+          tmpi->arg1_type_pointed_to=tmpi->res.type.raw_type;
+          CmpMinTypePointed(tmpi,CmpRawTypePointed(tmpi->t.arg1_class));
+          break;
+        case IC_RETURN_VAL:
+        case IC_RETURN_VAL2:
+          if (tmpc) {
+            if (tmpc->raw_type==RT_F64 && tmpil1->ic_class->raw_type!=RT_F64)
+              tmpil1->ic_flags|=ICF_RES_TO_F64;
+            else if (tmpc->raw_type!=RT_F64 &&
+                  tmpil1->ic_class->raw_type==RT_F64)
+              tmpil1->ic_flags|=ICF_RES_TO_INT;
+          }
+          break;
+        case IC_SQR:
+        case IC_ABS:
+        case IC_SQRT:
+        case IC_SIN:
+        case IC_COS:
+        case IC_TAN:
+        case IC_ATAN:
+          if (tmpc->raw_type==RT_F64)
+            CmpF1PushPop(tmpi,tmpi1);
+          break;
+        case IC_NOBOUND_SWITCH:
+        case IC_SWITCH:
+          lb=OptLabelFwd(tmpi->ic_data(CCodeMisc *)->dft);
+          lb->use_cnt++;
+          break;
+        case IC_ASM:
+          tmpaot=tmpi->ic_data;
+          tmpie=tmpaot->next_ie;
+          while (tmpie!=&tmpaot->next_ie) {
+            if (IET_REL_I0<=tmpie->type<=IET_IMM_I64 &&
+                  tmpie->str && tmpie->flags&IEF_GOTO_LABEL &&
+                  (lb=COCGoToLabelFind(cc,tmpie->str)))
+              lb->use_cnt++; //Prevent deadcode elimination.
+            tmpie=tmpie->next;
+          }
+          break;
+        case IC_BR_NOT_EQU:
+        case IC_BR_EQU_EQU:
+          if ((tmpi1->ic_code==IC_IMM_I64 ||
+                tmpi1->ic_code==IC_IMM_F64) && !tmpi1->ic_data) {
+            OptFree(tmpi1);
+            MemCpy(&tmpi->arg1,&tmpi->arg2,sizeof(CICArg));
+            tmpi->arg2.type=MDF_NULL;
+            if (code==IC_BR_EQU_EQU)
+              code=tmpi->ic_code=IC_BR_ZERO;
+            else
+              code=tmpi->ic_code=IC_BR_NOT_ZERO;
+            tmpi1=tmpi2;
+            tmpc1=tmpc2;
+          } else if ((tmpi2->ic_code==IC_IMM_I64 ||
+                tmpi2->ic_code==IC_IMM_F64) && !tmpi2->ic_data) {
+            OptFree(tmpi2);
+            tmpi->arg2.type=MDF_NULL;
+            if (code==IC_BR_EQU_EQU)
+              code=tmpi->ic_code=IC_BR_ZERO;
+            else
+              code=tmpi->ic_code=IC_BR_NOT_ZERO;
+          } else
+            goto here1;
+        case IC_BR_ZERO:
+        case IC_BR_NOT_ZERO:
+          if (tmpi1->ic_code==IC_IMM_I64 || tmpi1->ic_code==IC_IMM_F64) {
+            if (code==IC_BR_ZERO ^^ tmpi1->ic_data) {
+              OptFree(tmpi1);
+              tmpi->arg1.type=MDF_NULL;
+              tmpi->ic_code=IC_JMP;
+            } else {
+              OptFree(tmpi1);
+              tmpi=OptFree(tmpi);
+              break;
+            }
+          }
+          goto here1;
+        case IC_BR_AND_ZERO:
+          if (tmpi1->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi1->ic_data);
+            if (0<=i==Bsf(tmpi1->ic_data)) {
+              tmpi1->ic_data=i;
+              tmpi->ic_flags|=ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_NOT_BT;
+              goto here1;
+            }
+          }
+          if (tmpi2->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi2->ic_data);
+            if (0<=i==Bsf(tmpi2->ic_data)) {
+              tmpi2->ic_data=i;
+              tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_NOT_BT;
+            }
+          }
+          goto here1;
+        case IC_BR_AND_NOT_ZERO:
+          if (tmpi1->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi1->ic_data);
+            if (0<=i==Bsf(tmpi1->ic_data)) {
+              tmpi1->ic_data=i;
+              tmpi->ic_flags|=ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_BT;
+              goto here1;
+            }
+          }
+          if (tmpi2->ic_code==IC_IMM_I64) {
+            i=Bsr(tmpi2->ic_data);
+            if (0<=i==Bsf(tmpi2->ic_data)) {
+              tmpi2->ic_data=i;
+              tmpi->ic_flags|=ICF_SWAP|ICF_BY_VAL;
+              tmpi->ic_code=IC_BR_BT;
+            }
+          }
+          goto here1;
+        case IC_BR_MM_ZERO:
+        case IC_BR_MM_NOT_ZERO:
+          if (tmpi1->ic_code==IC_LEA && tmpi1->arg1.type&MDF_DISP &&
+                tmpi1->arg1.reg==REG_RBP)
+            for (i=0;i<member_cnt;i++)
+              if (mv[i].offset_start==tmpi1->arg1.disp) {
+                mv[i].lea_balance--;
+                mv[i].score++;
+                break;
+              }
+          tmpi->arg1_type_pointed_to=CmpRawType(tmpc);
+          goto here1;
+        case IC_BR_LESS:
+        case IC_BR_GREATER_EQU:
+        case IC_BR_GREATER:
+        case IC_BR_LESS_EQU:
+          if (tmpi->ic_flags&ICF_USE_F64)
+            CmpF2PushPop(tmpi,tmpi1,tmpi2);
+        case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
+        case IC_BR_CARRY:
+        case IC_BR_NOT_CARRY:
+        case IC_GET_LABEL:
+        case IC_BR_BT:
+        case IC_BR_BTS:
+        case IC_BR_BTR:
+        case IC_BR_BTC:
+        case IC_BR_NOT_BT:
+        case IC_BR_NOT_BTS:
+        case IC_BR_NOT_BTR:
+        case IC_BR_NOT_BTC:
+        case IC_JMP:
+        case IC_SUB_CALL:
+here1:
+          if (tmpi->ic_flags&ICF_PUSH_CMP)
+            lb=tmpi->ic_data;
+          else
+            lb=OptLabelFwd(tmpi->ic_data);
+          lb->use_cnt++;
+          break;
+        case IC_NOP1:
+          tmpi=OptFree(tmpi);
+          break;
+        case IC_NOP2:
+          ps->ptr+=tmpi->ic_data;
+          break;
+        case IC_SHL_CONST:
+        case IC_SHR_CONST:
+        case IC_ENTER:
+        case IC_ADD_RSP:
+        case IC_ADD_RSP1:
+        case IC_CALL:
+        case IC_CALL_INDIRECT:
+        case IC_CALL_INDIRECT2:
+        case IC_CALL_EXTERN:
+        case IC_CALL_IMPORT:
+        case IC_PUSH:
+        case IC_POP:
+        case IC_INVLPG:
+        case IC_CLFLUSH:
+        case IC_GET_RFLAGS:
+        case IC_CARRY:
+        case IC_RDTSC:
+        case IC_SET_RFLAGS:
+        case IC_GET_RBP:
+        case IC_SET_RBP:
+        case IC_GET_RSP:
+        case IC_GET_RAX:
+        case IC_SET_RSP:
+        case IC_SET_RAX:
+        case IC_ABS_ADDR:
+        case IC_HEAP_GLBL:
+        case IC_ADDR_IMPORT:
+        case IC_TYPE:
+        case IC_BT:
+        case IC_BTS:
+        case IC_BTR:
+        case IC_BTC:
+        case IC_LBTS:
+        case IC_LBTR:
+        case IC_LBTC:
+        case IC_BSF:
+        case IC_BSR:
+        case IC_SIGN_I64:
+        case IC_TOUPPER:
+        case IC_TO_I64:
+        case IC_TO_F64:
+        case IC_TO_BOOL:
+        case IC_ABS_I64:
+        case IC_MIN_I64:
+        case IC_MAX_I64:
+        case IC_MIN_U64:
+        case IC_MAX_U64:
+        case IC_MOD_U64:
+        case IC_SQR_I64:
+        case IC_SQR_U64:
+        case IC_SWAP_U8:
+        case IC_SWAP_U16:
+        case IC_SWAP_U32:
+        case IC_SWAP_I64:
+        case IC_QUE_INIT:
+        case IC_QUE_INS:
+        case IC_QUE_INS_REV:
+        case IC_QUE_REM:
+        case IC_IN_U32:
+        case IC_IN_U16:
+        case IC_IN_U8:
+        case IC_STRLEN:
+        case IC_OUT_U32:
+        case IC_OUT_U16:
+        case IC_OUT_U8:
+        case IC_STR_CONST:
+        case IC_FS:
+        case IC_GS:
+        case IC_MOV_FS:
+        case IC_MOV_GS:
+        case IC_RIP:
+        case IC_PUSH_CMP:
+        case IC_REG:
+        case IC_COM:
+        case IC_HOLYC_TYPECAST:
+        case IC_NOT:
+        case IC_UNARY_MINUS:
+        case IC_POWER:
+        case IC_SHL:
+        case IC_SHR:
+        case IC_MOD:
+        case IC_AND:
+        case IC_OR:
+        case IC_XOR:
+        case IC_EQU_EQU:
+        case IC_NOT_EQU:
+        case IC_AND_AND:
+        case IC_OR_OR:
+        case IC_XOR_XOR:
+        case IC_LEAVE:
+        case IC_RET:
+        case IC_ADDR:
+        case IC_END:
+        case IC_END_EXP:
+        case IC_CALL_END:
+        case IC_CALL_END2:
+        case IC_CALL_START:
+        case IC_PUSH_REGS:
+        case IC_POP_REGS:
+        case IC_LABEL:
+          break;
+        default:
+          "Pass:%d Missing IC hndlr\n",cc->pass;
+          ICPut(cc,tmpi);
+          LexExcept(cc,"Compiler Optimization Error at ");
+      }
+    }
+    tmpi=tmpi_next;
+  }
+/* REGISTER VARIABLE ASSIGNMENT
+
+We just scored num occurrences of each [RBP] offset in the code to help decide
+which variables should be assigned to register variables.
+
+We counted the times each offset was added to RBP as a plus LEA and we subtract
+the times the offset is dereferenced.  If the address was calculated more times
+than the offset was dereferenced, the variable's address was passed or assigned
+and we cannot use a register because you can't take address of a reg var.
+
+RAX,RBX,RCX,RDX, R8 are free to be clobbered by each intermediate code.
+RAX and R8 links intermediate codes together.  R9 is used for stack machine
+temporaries.  RBP is used as stack frame.
+
+RSI,RDI,R10,R11,R12,R13,R14,R15 are used for reg vars.  R12 and R13, however,
+have a unusual ModR addressing mode in the x86_64 architecture, so I only use
+R12 and R13 as non-pointer register variables, such as index variables i,j,k.
+
+*/
+  if (cc->htc.fun) {
+    cc->htc.fun->used_reg_mask=cc->htc.fun->used_reg_mask&
+          ~(REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS)|used_reg_mask;
+    if (!Bt(&cc->opts,OPTf_NO_REG_VAR) &&
+          !(cc->flags & CCF_NO_REG_OPT)) {
+      QSort(mv,member_cnt,sizeof(COptMemberVar),&OptMVCompare);
+      while (member_cnt && !mv[member_cnt-1].score)
+        member_cnt--;
+      j=0;
+      for (i=0;i<member_cnt;i++) {
+        if (!mv[i].lea_balance && mv[i].offset_start) {//addr operator cancels
+          mv[j].m=mv[i].m;
+          mv[j].offset_start=mv[i].offset_start;
+          mv[j++].offset_end=mv[i].offset_end;
+        } else {
+          if (mv[i].m->reg==REG_ALLOC)
+            PrintWarn("Can't reg var\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                  cc->lex_include_stk->full_name,
+                  cc->lex_include_stk->line_num,mv[i].m->str,cc->htc.fun->str);
+        }
+      }
+      if (j>0) {
+        if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
+          "Fun:%s\n",cc->htc.fun->str;
+        if (j>cmp.num_reg_vars) {
+          l=0;
+          for (i=0;i<j && l<cmp.num_non_ptr_vars;i++) {
+            tmpm=mv[i].m;
+            tmpc=OptClassFwd(tmpm->member_class);
+            if (!tmpc->ptr_stars_cnt && !tmpm->dim.next) {
+              while (l<cmp.num_non_ptr_vars &&
+                    Bts(&cc->htc.fun->used_reg_mask,cmp.non_ptr_vars_map[l]))
+                l++;
+              if (l<cmp.num_non_ptr_vars) {
+                tmpm->reg=cmp.non_ptr_vars_map[l++];
+                reg_offsets[tmpm->reg].offset=mv[i].offset_start;
+                reg_offsets[tmpm->reg].m=tmpm;
+                if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
+                  "Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS",
+                        tmpm->str,reg_offsets[tmpm->reg].offset;
+                mv[i].offset_start=0; //flag as reg var
+                if (tmpm->size<8 &&
+                      !StrIMatch("Bool",tmpm->member_class->str) &&
+                      tmpm->member_class->type&HTT_INTERNAL_TYPE)
+                  PrintWarn("Using 64-bit reg var.\n "
+                        "$LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                        cc->lex_include_stk->full_name,
+                        cc->lex_include_stk->line_num,
+                        tmpm->str,cc->htc.fun->str);
+              }
+            }
+          }
+        }
+        l=0;
+        for (i=0;i<j && l<cmp.num_reg_vars;i++) {
+          tmpm=mv[i].m;
+//if not just flagged as reg var
+          if (mv[i].offset_start && (!mv[i].m->dim.next||
+                tmpm->offset>0 && StrCmp(tmpm->str,"argv"))) {
+            while (l<cmp.num_reg_vars &&
+                  Bts(&cc->htc.fun->used_reg_mask,cmp.to_reg_vars_map[l]))
+              l++;
+            if (l<cmp.num_reg_vars) {
+              tmpm->reg=cmp.to_reg_vars_map[l++];
+              reg_offsets[tmpm->reg].offset=mv[i].offset_start;
+              reg_offsets[tmpm->reg].m=tmpm;
+              if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT))
+                "Reg %Z Var \"%-15ts\" %016X[RBP]\n",tmpm->reg,"ST_U64_REGS",
+                      tmpm->str,reg_offsets[tmpm->reg].offset;
+              if (tmpm->size<8 &&
+                    !StrIMatch("Bool",tmpm->member_class->str) &&
+                    tmpm->member_class->type&HTT_INTERNAL_TYPE)
+                PrintWarn("Using 64-bit reg var.\n "
+                      "$LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+                      cc->lex_include_stk->full_name,
+                      cc->lex_include_stk->line_num,
+                      tmpm->str,cc->htc.fun->str);
+            }
+          }
+        }
+      }
+    }
+    Free(mv);
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+}
+
+
+ diff --git a/public/Wb/Home/Src/Compiler/OptPass4.HC.HTML b/public/Wb/Home/Src/Compiler/OptPass4.HC.HTML new file mode 100755 index 0000000..de8c4e2 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OptPass4.HC.HTML @@ -0,0 +1,720 @@ + + + + + + + + + + + +
+Bool OptIC4(CIntermediateCode *tmpi)
+{
+  I64 i;
+  CIntermediateCode *tmpil1,*tmpil2;
+
+  if (tmpi->ic_code<IC_IMM_I64) return FALSE;
+
+  tmpil1=tmpi;
+  if (!(tmpil2=OptLag1(tmpil1)))
+    return FALSE;
+
+  if (tmpil2->res.type&MDF_STK && !(tmpil2->ic_flags&ICF_PUSH_RES)) {
+    if (tmpil1->ic_code==IC_ADD_CONST && tmpil1->arg1.type&MDF_STK) {
+      if ((tmpil2->ic_code==IC_REG || tmpil2->ic_code==IC_MOV) &&
+            tmpil2->arg1.type&MDF_REG) {
+        i=tmpil1->ic_data;
+        if (I32_MIN<=i<=I32_MAX &&
+              !Bt(&cmp.non_ptr_vars_mask,tmpil2->arg1.reg)) {
+          tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+          tmpil1->ic_code=IC_LEA;
+          tmpil1->arg1.type=MDF_DISP+tmpil1->arg1.type.raw_type;
+          tmpil1->arg1.reg=tmpil2->arg1.reg;
+          tmpil1->arg1.disp=i;
+          OptFree(tmpil2);
+          return TRUE;
+        }
+      } else if (tmpil2->ic_code==IC_SHL_CONST && tmpil2->arg1.type&MDF_REG) {
+        i=tmpil1->ic_data;
+        if (I32_MIN<=i<=I32_MAX && tmpil2->arg1.reg!=REG_RSP &&
+              1<=tmpil2->ic_data<=3) {
+          tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+          tmpil1->ic_code=IC_LEA;
+          tmpil1->arg1.type=MDF_SIB+tmpil1->arg1.type.raw_type;
+          tmpil1->arg1.reg=tmpil2->arg1.reg<<8+REG_NONE;
+          if (tmpil2->ic_data==1)
+            tmpil1->arg1.reg|=0x4000;
+          else if (tmpil2->ic_data==2)
+            tmpil1->arg1.reg|=0x8000;
+          else
+            tmpil1->arg1.reg|=0xC000;
+          tmpil1->arg1.disp=i;
+          OptFree(tmpil2);
+          return TRUE;
+        }
+      }
+    }
+    if (tmpil2->ic_code==IC_MOV || tmpil2->ic_code==IC_REG) {
+      if (tmpil1->arg2.type&MDF_STK) {
+        if (tmpil2->ic_flags & ICF_RES_TO_INT) {
+          if (tmpil2->arg1.type&MDF_IMM)
+            tmpil2->arg1.disp=tmpil2->arg1.disp(F64);
+          else
+            tmpil1->ic_flags|=ICF_ARG2_TO_INT;
+        } else if (tmpil2->ic_flags&ICF_RES_TO_F64) {
+          if (tmpil2->arg1.type&MDF_IMM)
+            tmpil2->arg1.disp(F64)=tmpil2->arg1.disp;
+          else
+            tmpil1->ic_flags|=ICF_ARG2_TO_F64;
+        }
+        tmpil1->arg2.type=tmpil2->arg1.type&MDG_MASK+
+              MinI64(tmpil1->arg2.type.raw_type,
+              MinI64(tmpil2->res.type.raw_type,tmpil2->arg1.type.raw_type));
+        tmpil1->arg2.reg=tmpil2->arg1.reg;
+        tmpil1->arg2.disp=tmpil2->arg1.disp;
+        tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+        OptSetNOP2(tmpil2);
+        return TRUE;
+      }
+      if (tmpil1->arg1.type&MDF_STK) {
+        if (tmpil2->ic_flags & ICF_RES_TO_INT) {
+          if (tmpil2->arg1.type&MDF_IMM)
+            tmpil2->arg1.disp=tmpil2->arg1.disp(F64);
+          else
+            tmpil1->ic_flags|=ICF_ARG1_TO_INT;
+        } else if (tmpil2->ic_flags&ICF_RES_TO_F64) {
+          if (tmpil2->arg1.type&MDF_IMM) {
+            if (tmpil2->arg1.type&RTF_UNSIGNED)
+              tmpil2->arg1.disp(F64)=tmpil2->arg1.disp(U64);
+            else
+              tmpil2->arg1.disp(F64)=tmpil2->arg1.disp(I64);
+          } else
+            tmpil1->ic_flags|=ICF_ARG1_TO_F64;
+        }
+        tmpil1->arg1.type=tmpil2->arg1.type&MDG_MASK+
+              MinI64(tmpil1->arg1.type.raw_type,
+              MinI64(tmpil2->res.type.raw_type,tmpil2->arg1.type.raw_type));
+        CmpMinTypePointed(tmpil1,tmpil2->arg1_type_pointed_to);
+        tmpil1->arg1.reg=tmpil2->arg1.reg;
+        tmpil1->arg1.disp=tmpil2->arg1.disp;
+        tmpil1->ic_flags|=tmpil2->ic_flags&ICG_NO_CVT_MASK;
+        OptSetNOP2(tmpil2);
+        return TRUE;
+      }
+    }
+    if (tmpil1->ic_code==IC_DEREF) {
+      if (tmpil2->ic_code==IC_ADD_CONST && tmpil2->arg1.type&MDF_REG &&
+            tmpil1->arg1.type&MDF_STK) {
+        i=tmpil2->ic_data;
+        if (I32_MIN<=i<=I32_MAX &&
+              !Bt(&cmp.non_ptr_vars_mask,tmpil2->arg1.reg)) {
+          tmpil1->ic_flags|=tmpil2->ic_flags;
+          tmpil1->ic_code=IC_MOV;
+          tmpil1->arg1.type=MDF_DISP+tmpil1->arg1_type_pointed_to;
+          tmpil1->arg1.reg=tmpil2->arg1.reg;
+          tmpil1->arg1.disp=i;
+          OptSetNOP2(tmpil2,-1);
+          return TRUE;
+        }
+      }
+      if (tmpil2->ic_code==IC_LEA && tmpil1->arg1.type&MDF_STK) {
+        tmpil1->ic_flags|=tmpil2->ic_flags;
+        tmpil1->ic_code=IC_MOV;
+        tmpil1->arg1.type=tmpil2->arg1.type&MDG_MASK+
+              tmpil1->arg1_type_pointed_to;
+        tmpil1->arg1.reg=tmpil2->arg1.reg;
+        tmpil1->arg1.disp=tmpil2->arg1.disp;
+        OptFree(tmpil2);
+        return TRUE;
+      }
+    }
+  }
+  if (tmpil1->ic_code==IC_DEREF) {
+    if (tmpil1->arg1.type&MDF_REG) {
+      tmpil1->arg1.type=MDF_DISP+tmpil1->arg1_type_pointed_to;
+      tmpil1->arg1.disp=0;
+      tmpil1->ic_code=IC_MOV;
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+U0 OptPass4(CCmpCtrl *cc,COptReg *reg_offsets,I64 *_type)
+{
+  CHashClass *tmpc,*tmpc1,*tmpc2;
+  CIntermediateCode *tmpi,*tmpi1,*tmpi2,*tmpil1,*tmpil2,*tmpil3,
+        *tmpi_next;
+  I64 code,i;
+  Bool dead_code=FALSE;
+  CCodeMisc *lb;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+
+  if (_type)
+    *_type=RT_I64;
+
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    tmpi_next=tmpi->next;
+    if (dead_code&&code!=IC_LABEL) {
+      if (code==IC_JMP||code==IC_SUB_CALL) {
+        lb=OptLabelFwd(tmpi->ic_data);
+        if (lb->use_cnt>0)
+          lb->use_cnt--;
+      }
+      tmpi=OptFree(tmpi);
+    } else {
+      tmpc=tmpi->ic_class;
+      tmpi1=tmpi2=&cmp.ic_nop;
+      if (tmpil1=OptLag2(tmpi)) {
+        if (tmpil2=OptLag2(tmpil1)) {
+          if (!(tmpil3=OptLag2(tmpil2)))
+            tmpil3=&cmp.ic_nop;
+        } else
+          tmpil2=tmpil3=&cmp.ic_nop;
+      } else
+        tmpil1=tmpil2=tmpil3=&cmp.ic_nop;
+      switch [intermediate_code_table[code].arg_cnt] {
+        case IS_V_ARG:
+          ps->ptr-=tmpi->ic_data>>3;
+          break;
+        case IS_2_ARG:
+          tmpi2=PrsPop(ps);
+          tmpc2=tmpi2->ic_class;
+        case IS_1_ARG:
+          tmpi1=PrsPop(ps);
+          tmpc1=tmpi1->ic_class;
+          break;
+        case IS_0_ARG: //nobound switch
+          break;
+      }
+      switch [code] {
+        case IC_IMM_I64:
+        case IC_TYPE:
+          tmpi->arg1.type=MDF_IMM+RT_I64;
+          tmpi->arg1.disp=tmpi->ic_data;
+          tmpi->ic_code=IC_MOV;
+          break;
+        case IC_IMM_F64:
+          tmpi->arg1.type=MDF_IMM+RT_I64;
+          tmpi->arg1.disp=tmpi->ic_data;
+          tmpi->arg1_type_pointed_to=RT_F64;
+          tmpi->ic_code=IC_MOV;
+          break;
+        case IC_MOV:
+          if (tmpi->arg1.type&MDF_DISP && tmpi->arg1.reg==REG_RBP) {
+            i=CmpOffset2Reg(tmpi->arg1.disp,reg_offsets);
+            if (i>=0) {
+              tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+              tmpi->arg1.reg=i;
+              tmpi->arg1.disp=0;
+            }
+          }
+          break;
+        case IC_DEREF:
+          if (tmpi1->ic_code==IC_LEA) {
+            if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
+              i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
+              if (i>=0) {
+                tmpi->ic_flags|=tmpi1->ic_flags;
+                tmpi->ic_code=IC_REG;
+                tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+                tmpi->arg1.reg=i;
+                tmpi->arg1.disp=0;
+                OptFree(tmpi1);
+              }
+            }
+          } else if ((tmpi1->ic_code==IC_ABS_ADDR ||
+                tmpi1->ic_code==IC_MOV &&
+                tmpi1->arg1.type==MDF_IMM+RT_I64 &&
+                0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
+            if (tmpi1->ic_code==IC_ABS_ADDR)
+              tmpi->arg1.disp=tmpi1->ic_data;
+            else
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            tmpi->ic_code=IC_MOV;
+            tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1_type_pointed_to;
+            tmpi->arg1.reg=REG_RIP;
+            OptFree(tmpi1);
+          }
+          break;
+        case IC_BR_MM_ZERO:
+        case IC_BR_MM_NOT_ZERO:
+//(branch ++ to zero is unlikely)
+        case IC_DEREF_PP:
+        case IC_DEREF_MM:
+        case IC__PP:
+        case IC__MM:
+        case IC_PP_:
+        case IC_MM_:
+          if (tmpi1->ic_code==IC_LEA) {
+            if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
+              i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
+              if (i>=0) {
+                tmpi->ic_flags|=tmpi1->ic_flags;
+                tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+                tmpi->arg1.reg=i;
+                tmpi->arg1.disp=0;
+                tmpi->ic_flags|=ICF_BY_VAL;
+                OptSetNOP2(tmpi1);
+              } else
+                goto p4_lea_gone;
+            } else {
+p4_lea_gone:
+              tmpi->ic_flags|=tmpi1->ic_flags;
+              tmpi->arg1.type=tmpi1->arg1.type;
+              tmpi->arg1.reg=tmpi1->arg1.reg;
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+              tmpi->ic_flags|=ICF_BY_VAL;
+              OptSetNOP2(tmpi1);
+            }
+          } else if ((tmpi1->ic_code==IC_ABS_ADDR || tmpi1->ic_code==IC_MOV &&
+                tmpi1->arg1.type==MDF_IMM+RT_I64 &&
+                0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            if (tmpi1->ic_code==IC_ABS_ADDR)
+              tmpi->arg1.disp=tmpi1->ic_data;
+            else
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1_type_pointed_to;
+            tmpi->arg1.reg=REG_RIP;
+            tmpi->ic_flags|=ICF_BY_VAL;
+            OptFree(tmpi1);
+          }
+          break;
+        case IC_ADD:
+          if (tmpi1->ic_code==IC_MOV && tmpi1->arg1.type==MDF_REG+RT_I64 ||
+                tmpi1->ic_code==IC_REG) {
+            if (tmpi2->ic_code==IC_MOV && tmpi2->arg1.type==MDF_REG+RT_I64 ||
+                  tmpi2->ic_code==IC_REG) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=0;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                goto p4_sib;
+              } else if (tmpi1->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=0;
+                tmpi->arg1.reg=tmpi2->arg1.reg+tmpi1->arg1.reg<<8;
+p4_sib:
+                tmpi->ic_flags|=(tmpi1->ic_flags|tmpi2->ic_flags)
+                &ICG_NO_CVT_MASK;
+                OptSetNOP2(tmpi1);
+                OptFree(tmpi2);
+
+                tmpi->ic_code=IC_LEA;
+                tmpi->arg1.type=MDF_SIB+RT_I64;
+                tmpi->arg1_type_pointed_to=RT_I64;
+
+                tmpi->arg2.type=MDF_NULL+tmpi->arg2.type.raw_type;
+              }
+            } else if (tmpi2->ic_code==IC_SHL_CONST &&
+                  tmpi2->arg1.type==MDF_REG+RT_I64 && tmpi2->ic_data<=3) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=0;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                if (tmpi2->ic_data==1)
+                  tmpi->arg1.reg|=0x4000;
+                else if (tmpi2->ic_data==2)
+                  tmpi->arg1.reg|=0x8000;
+                else
+                  tmpi->arg1.reg|=0xC000;
+                goto p4_sib;
+              }
+            }
+          } else if (tmpi1->ic_code==IC_LEA &&
+                tmpi1->arg1.type&MDF_DISP) {
+            if (tmpi1->arg1.reg==REG_RBP &&
+                  CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets)>=0)
+              break;
+            if (tmpi2->ic_code==IC_MOV && tmpi2->arg1.type==MDF_REG+RT_I64 ||
+                  tmpi2->ic_code==IC_REG) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                goto p4_sib;
+              } else if (tmpi1->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                tmpi->arg1.reg=tmpi2->arg1.reg+tmpi1->arg1.reg<<8;
+                goto p4_sib;
+              }
+            } else if (tmpi2->ic_code==IC_SHL_CONST &&
+                  tmpi2->arg1.type==MDF_REG+RT_I64 && tmpi2->ic_data<=3) {
+              if (tmpi2->arg1.reg!=REG_RSP) {
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                tmpi->arg1.reg=tmpi1->arg1.reg+tmpi2->arg1.reg<<8;
+                if (tmpi2->ic_data==1)
+                  tmpi->arg1.reg|=0x4000;
+                else if (tmpi2->ic_data==2)
+                  tmpi->arg1.reg|=0x8000;
+                else
+                  tmpi->arg1.reg|=0xC000;
+                goto p4_sib;
+              }
+            }
+          }
+          break;
+        case IC_ASSIGN_PP:
+        case IC_ASSIGN_MM:
+//this val was stashed during pass012 for pointer arithmetic
+          tmpi->ic_class2=tmpi->t.class2; //See ic_class2
+        case IC_ASSIGN:
+        case IC_SHL_EQU:
+        case IC_SHR_EQU:
+        case IC_MUL_EQU:
+        case IC_DIV_EQU:
+        case IC_MOD_EQU:
+        case IC_AND_EQU:
+        case IC_OR_EQU:
+        case IC_XOR_EQU:
+        case IC_ADD_EQU:
+        case IC_SUB_EQU:
+          if (tmpi1->ic_code==IC_LEA) {
+            if (tmpi1->arg1.type&(MDF_DISP|MDF_SIB)) {
+              tmpi2=tmpi->next;
+              if (tmpi1->arg1.type&MDF_DISP && tmpi1->arg1.reg==REG_RBP) {
+                i=CmpOffset2Reg(tmpi1->arg1.disp,reg_offsets);
+                if (i>=0) {
+                  tmpi->ic_flags|=tmpi1->ic_flags;
+                  tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+                  tmpi->arg1.reg=i;
+                  tmpi->arg1.disp=0;
+                  OptSetNOP2(tmpi1);
+                } else {
+                  tmpi->ic_flags|=tmpi1->ic_flags;
+                  tmpi->arg1.type=MDF_DISP+tmpi->arg1.type.raw_type;
+                  tmpi->arg1.reg=REG_RBP;
+                  tmpi->arg1.disp=tmpi1->arg1.disp;
+                  OptSetNOP2(tmpi1);
+                }
+              } else {
+                tmpi->ic_flags|=tmpi1->ic_flags;
+                tmpi->arg1.type=tmpi1->arg1.type&MDG_MASK+
+                      tmpi->arg1.type.raw_type;
+                tmpi->arg1.reg=tmpi1->arg1.reg;
+                tmpi->arg1.disp=tmpi1->arg1.disp;
+                OptSetNOP2(tmpi1);
+              }
+              if (tmpi->res.type&MDF_STK && tmpi2->arg2.type&MDF_STK &&
+                    code!=IC_ASSIGN_PP && code!=IC_ASSIGN_MM) {
+                tmpi->res.type=tmpi->arg1.type;
+                tmpi->res.reg=tmpi->arg1.reg;
+                tmpi->res.disp=tmpi->arg1.disp;
+                tmpi2->arg2.type=tmpi->arg1.type;
+                tmpi2->arg2.reg=tmpi->arg1.reg;
+                tmpi2->arg2.disp=tmpi->arg1.disp;
+                CmpMinTypePointed(tmpi2,tmpi->arg1_type_pointed_to);
+              }
+              tmpi->ic_flags|=ICF_BY_VAL;
+            }
+          } else if ((tmpi1->ic_code==IC_ABS_ADDR ||
+                tmpi1->ic_code==IC_MOV && tmpi1->arg1.type==MDF_IMM+RT_I64 &&
+                0<=tmpi1->arg1.disp<=I32_MAX)&& !(tmpi1->ic_flags&ICF_NO_RIP)) {
+            tmpi->ic_flags|=tmpi1->ic_flags;
+            if (tmpi1->ic_code==IC_ABS_ADDR)
+              tmpi->arg1.disp=tmpi1->ic_data;
+            else
+              tmpi->arg1.disp=tmpi1->arg1.disp;
+            tmpi->arg1.type=MDF_RIP_DISP32+tmpi->arg1.type.raw_type;
+            tmpi->arg1.reg=REG_RIP;
+            tmpi->ic_flags|=ICF_BY_VAL;
+            OptSetNOP2(tmpi1);
+          }
+          break;
+        case IC_RETURN_VAL:
+        case IC_RETURN_VAL2:
+          if (!tmpi->ic_class) {
+            if (_type) {
+              tmpil1=tmpi;
+              while (tmpil1=OptLag1(tmpil1))
+                if (tmpil1->ic_class) {
+                  if (tmpil1->ic_flags & ICF_RES_TO_F64)
+                    *_type=RT_F64;
+                  else if (tmpil1->ic_flags & ICF_RES_TO_INT)
+                    *_type=RT_I64;
+                  else
+                    *_type=tmpil1->ic_class->raw_type;
+                  break;
+                }
+            }
+            tmpi->ic_class=cmp.internal_types[RT_I64];
+          } else if (_type)
+            *_type=tmpi->ic_class->raw_type;
+          break;
+        case IC_NOP1:
+          tmpi=OptFree(tmpi);
+          break;
+        case IC_BR_BT:
+        case IC_BR_BTS:
+        case IC_BR_BTR:
+        case IC_BR_BTC:
+        case IC_BR_NOT_BT:
+        case IC_BR_NOT_BTS:
+        case IC_BR_NOT_BTR:
+        case IC_BR_NOT_BTC:
+        case IC_BT:
+        case IC_BTS:
+        case IC_BTR:
+        case IC_BTC:
+        case IC_LBTS:
+        case IC_LBTR:
+        case IC_LBTC:
+          if (!(tmpi->ic_flags&ICF_BY_VAL)) {
+            if (tmpi2->ic_code==IC_ADDR) {
+              if (tmpi2->arg1.type&MDF_STK &&
+                    tmpi2->res.type&MDF_STK) {
+                if (tmpil2=OptLag1(tmpi2)) {
+                  if (tmpil2->ic_code==IC_LEA) {
+                    if (tmpil2->arg1.type&(MDF_IMM|MDG_REG_DISP_SIB_RIP)) {
+                      if (tmpi2) {
+                        tmpi->ic_flags|=tmpi2->ic_flags;
+                        OptFree(tmpi2);
+                      }
+                      tmpi->ic_flags|=tmpil2->ic_flags|ICF_BY_VAL;
+                      tmpi->arg2.type=tmpil2->arg1.type;
+                      tmpi->arg2.reg =tmpil2->arg1.reg;
+                      tmpi->arg2.disp=tmpil2->arg1.disp;
+                      OptFree(tmpil2);
+                    }
+                    break;
+                  } else if (tmpil2->ic_code!=IC_ABS_ADDR &&
+                        !(tmpil2->ic_code==IC_MOV &&
+                        tmpil2->arg1.type==MDF_IMM+RT_I64 &&
+                        0<=tmpil2->arg1.disp<=I32_MAX) ||
+                        tmpil2->ic_flags&ICF_NO_RIP)
+                    tmpil2=NULL;
+                  else {
+                    if (tmpil2->ic_code==IC_ABS_ADDR)
+                      tmpi->arg2.disp=tmpil2->ic_data;
+                    else
+                      tmpi->arg2.disp=tmpil2->arg1.disp;
+                  }
+                }
+              } else {
+                if (tmpi2->arg1.type==MDF_IMM+RT_I64 &&
+                      0<=tmpi2->arg1.disp<=I32_MAX &&
+                      !(tmpi2->ic_flags&ICF_NO_RIP)) {
+                  tmpil2=tmpi2;
+                  tmpi2=NULL;
+                  tmpi->arg2.disp=tmpil2->arg1.disp;
+                } else
+                  tmpil2=NULL;
+              }
+              if (tmpil2) {
+                if (tmpi2) {
+                  tmpi->ic_flags|=tmpi2->ic_flags;
+                  OptFree(tmpi2);
+                }
+                tmpi->ic_flags|=tmpil2->ic_flags|ICF_BY_VAL;
+                tmpi->arg2.type=MDF_RIP_DISP32+tmpi->arg2.type.raw_type;
+                tmpi->arg2.reg=REG_RIP;
+                OptFree(tmpil2);
+              }
+            } else if (tmpi2->ic_code==IC_MOV && tmpi2->res.type&MDF_STK &&
+                  tmpi2->arg1.type==MDF_IMM+RT_I64 &&
+                  0<=tmpi2->arg1.disp<=I32_MAX &&
+                  !(tmpi2->ic_flags&ICF_NO_RIP)) {
+              tmpi->arg2.disp=tmpi2->arg1.disp;
+              tmpi->ic_flags|=tmpi2->ic_flags|ICF_BY_VAL;
+              tmpi->arg2.type=MDF_RIP_DISP32+tmpi->arg2.type.raw_type;
+              tmpi->arg2.reg=REG_RIP;
+              OptFree(tmpi2);
+            }
+          }
+          break;
+        case IC_BR_EQU_EQU ...IC_BR_LESS_EQU:
+        case IC_BR_EQU_EQU2...IC_BR_LESS_EQU2:
+        case IC_BR_CARRY:
+        case IC_BR_NOT_CARRY:
+        case IC_BR_ZERO:
+        case IC_BR_NOT_ZERO:
+          lb=tmpi->ic_data;
+          if (tmpi->ic_flags&ICF_PUSH_CMP) {
+            lb->flags|=CMF_POP_CMP;
+            lb->fwd=NULL;
+          }
+          break;
+        case IC_LABEL:
+          lb=tmpi->ic_data;
+          if (lb->use_cnt)
+            dead_code=FALSE;
+          break;
+        case IC_JMP:
+        case IC_RET:
+          dead_code=TRUE;
+          break;
+        case IC_NOP2:
+          ps->ptr+=tmpi->ic_data;
+          break;
+        case IC_CALL_END:
+        case IC_END_EXP:
+          if (!(tmpil1->ic_flags&ICF_PUSH_RES)) {
+            if (tmpi->ic_flags&ICF_RES_NOT_USED) {
+              tmpil1->ic_flags|=ICF_RES_NOT_USED;
+              tmpil1->res.type=MDF_NULL+tmpil1->res.type.raw_type;
+            } else if (tmpi->arg1.type&MDF_STK &&
+                  tmpil1->res.type&MDF_STK) {
+              tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+              tmpi->arg1.disp=0;
+              tmpil1->res.type=MDF_REG+tmpil1->res.type.raw_type;
+              tmpil1->res.disp=0;
+              if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG) {
+                tmpi->arg1.reg=REG_R8;
+                tmpil1->res.reg=REG_R8;
+              } else {
+                tmpi->arg1.reg=REG_RAX;
+                tmpil1->res.reg=REG_RAX;
+              }
+            }
+          }
+          break;
+        case IC_STR_CONST:
+        case IC_FS:
+        case IC_GS:
+        case IC_MOV_FS:
+        case IC_MOV_GS:
+        case IC_RIP:
+        case IC_RBP:
+        case IC_REG:
+        case IC_COM:
+        case IC_HOLYC_TYPECAST:
+        case IC_NOT:
+        case IC_UNARY_MINUS:
+        case IC_PUSH_CMP:
+        case IC_ADD_CONST:
+        case IC_SUB_CONST:
+        case IC_ENTER:
+        case IC_ADD_RSP:
+        case IC_ADD_RSP1:
+        case IC_CALL:
+        case IC_CALL_INDIRECT:
+        case IC_CALL_INDIRECT2:
+        case IC_CALL_EXTERN:
+        case IC_CALL_IMPORT:
+        case IC_PUSH:
+        case IC_POP:
+        case IC_INVLPG:
+        case IC_CLFLUSH:
+        case IC_GET_RFLAGS:
+        case IC_CARRY:
+        case IC_RDTSC:
+        case IC_SET_RFLAGS:
+        case IC_GET_RBP:
+        case IC_SET_RBP:
+        case IC_GET_RSP:
+        case IC_GET_RAX:
+        case IC_SET_RSP:
+        case IC_SET_RAX:
+        case IC_SHL_CONST:
+        case IC_LEA:
+        case IC_SHR_CONST:
+        case IC_POWER:
+        case IC_SHL:
+        case IC_SHR:
+        case IC_MUL:
+        case IC_DIV:
+        case IC_MOD:
+        case IC_AND:
+        case IC_OR:
+        case IC_XOR:
+        case IC_SUB:
+        case IC_EQU_EQU...IC_LESS_EQU:
+        case IC_AND_AND:
+        case IC_OR_OR:
+        case IC_XOR_XOR:
+        case IC_GET_LABEL:
+        case IC_ABS_ADDR:
+        case IC_HEAP_GLBL:
+        case IC_ADDR_IMPORT:
+        case IC_BSF:
+        case IC_BSR:
+        case IC_SIGN_I64:
+        case IC_TOUPPER:
+        case IC_TO_I64:
+        case IC_TO_F64:
+        case IC_TO_BOOL:
+        case IC_SQR:
+        case IC_ABS:
+        case IC_SQRT:
+        case IC_SIN:
+        case IC_COS:
+        case IC_TAN:
+        case IC_ATAN:
+        case IC_ABS_I64:
+        case IC_MIN_I64:
+        case IC_MAX_I64:
+        case IC_MIN_U64:
+        case IC_MAX_U64:
+        case IC_MOD_U64:
+        case IC_SQR_I64:
+        case IC_SQR_U64:
+        case IC_SWAP_U8:
+        case IC_SWAP_U16:
+        case IC_SWAP_U32:
+        case IC_SWAP_I64:
+        case IC_QUE_INIT:
+        case IC_QUE_INS:
+        case IC_QUE_INS_REV:
+        case IC_QUE_REM:
+        case IC_IN_U32:
+        case IC_IN_U16:
+        case IC_IN_U8:
+        case IC_STRLEN:
+        case IC_OUT_U32:
+        case IC_OUT_U16:
+        case IC_OUT_U8:
+        case IC_NOBOUND_SWITCH:
+        case IC_SWITCH:
+        case IC_END:
+        case IC_ADDR:
+        case IC_CALL_START:
+        case IC_LEAVE:
+        case IC_PUSH_REGS:
+        case IC_POP_REGS:
+        case IC_ASM:
+        case IC_BR_AND_NOT_ZERO:
+        case IC_BR_AND_ZERO:
+        case IC_SUB_CALL:
+        case IC_CALL_END2:
+          break;
+        default:
+          "Pass:%d Missing IC hndlr\n",cc->pass;
+          ICPut(cc,tmpi);
+          LexExcept(cc,"Compiler Optimization Error at ");
+      }
+      if (tmpi) {
+        while (OptIC4(tmpi));
+        code=tmpi->ic_code;
+        if (intermediate_code_table[code].res_cnt)
+          PrsPush(ps,tmpi);
+      }
+    }
+    tmpi=tmpi_next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/OptPass5.HC.HTML b/public/Wb/Home/Src/Compiler/OptPass5.HC.HTML new file mode 100755 index 0000000..b5e794c --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OptPass5.HC.HTML @@ -0,0 +1,121 @@ + + + + + + + + + + + +
+U0 OptPass5(CCmpCtrl *cc)
+{
+  CIntermediateCode *tmpi,*tmpi1;
+  I64 code,i;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+
+  tmpi=cc->coc.coc_head.next;
+  while (code=tmpi->ic_code) {
+    if (code>IC_NOP2) {
+      if (tmpi->ic_flags&ICF_PASS_TRACE) {
+        if (Bt(&cc->saved_pass_trace,5)) {
+          "%2d:",ps->ptr;
+          ICPut(cc,tmpi);
+        }
+      }
+      if (intermediate_code_table[code].arg_cnt==IS_V_ARG)
+        ps->ptr-=tmpi->ic_data>>3;
+      if (code==IC_PUSH_REGS) {
+        for (i=0;i<REG_REGS_NUM;i++)
+          if (Bt(&tmpi->ic_data,i))
+            ps->ptr++;
+      } else if (code==IC_POP_REGS) {
+        for (i=0;i<REG_REGS_NUM;i++)
+          if (Bt(&tmpi->ic_data,i))
+            ps->ptr--;
+      }
+      if (tmpi->arg2.type&MDF_STK) {
+        tmpi1=PrsPop(ps);
+        if (tmpi1->ic_code==IC_MOV || tmpi1->ic_code==IC_REG) {
+          if (tmpi1->ic_flags & ICF_RES_TO_INT) {
+            if (tmpi1->arg1.type&MDF_IMM)
+              tmpi1->arg1.disp=tmpi1->arg1.disp(F64);
+            else
+              tmpi->ic_flags|=ICF_ARG2_TO_INT;
+          } else if (tmpi1->ic_flags&ICF_RES_TO_F64) {
+            if (tmpi1->arg1.type&MDF_IMM)
+              tmpi1->arg1.disp(F64)=tmpi1->arg1.disp;
+            else
+              tmpi->ic_flags|=ICF_ARG2_TO_F64;
+          }
+          tmpi->arg2.type=tmpi1->arg1.type&MDG_MASK+
+                MinI64(tmpi->arg2.type.raw_type,
+                MinI64(tmpi1->res.type.raw_type,tmpi1->arg1.type.raw_type));
+          tmpi->arg2.reg=tmpi1->arg1.reg;
+          tmpi->arg2.disp=tmpi1->arg1.disp;
+          tmpi->ic_flags|=tmpi1->ic_flags&ICG_NO_CVT_MASK;
+          OptSetNOP2(tmpi1);
+        }
+      }
+
+      if (tmpi->arg1.type&MDF_STK) {
+        tmpi1=PrsPop(ps);
+        if (tmpi1->ic_code==IC_MOV || tmpi1->ic_code==IC_REG) {
+          if (tmpi1->ic_flags & ICF_RES_TO_INT) {
+            if (tmpi1->arg1.type&MDF_IMM)
+              tmpi1->arg1.disp=tmpi1->arg1.disp(F64);
+            else
+              tmpi->ic_flags|=ICF_ARG1_TO_INT;
+          } else if (tmpi1->ic_flags&ICF_RES_TO_F64) {
+            if (tmpi1->arg1.type&MDF_IMM) {
+              if (tmpi1->arg1.type&RTF_UNSIGNED)
+                tmpi1->arg1.disp(F64)=tmpi1->arg1.disp(U64);
+              else
+                tmpi1->arg1.disp(F64)=tmpi1->arg1.disp(I64);
+            } else
+              tmpi->ic_flags|=ICF_ARG1_TO_F64;
+          }
+          tmpi->arg1.type=tmpi1->arg1.type&MDG_MASK+
+                MinI64(tmpi->arg1.type.raw_type,
+                MinI64(tmpi1->res.type.raw_type,tmpi1->arg1.type.raw_type));
+          CmpMinTypePointed(tmpi,tmpi1->arg1_type_pointed_to);
+          tmpi->arg1.reg=tmpi1->arg1.reg;
+          tmpi->arg1.disp=tmpi1->arg1.disp;
+          tmpi->ic_flags|=tmpi1->ic_flags&ICG_NO_CVT_MASK;
+          OptSetNOP2(tmpi1);
+        }
+      }
+      if (tmpi->res.type&MDF_STK &&
+            !(tmpi->ic_flags&ICF_RES_NOT_USED))
+        PrsPush(ps,tmpi);
+    }
+    tmpi=tmpi->next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/OptPass6.HC.HTML b/public/Wb/Home/Src/Compiler/OptPass6.HC.HTML new file mode 100755 index 0000000..43a0e1b --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OptPass6.HC.HTML @@ -0,0 +1,216 @@ + + + + + + + + + + + +
+Bool OptIC6(CIntermediateCode *tmpi)
+{
+  CIntermediateCode *tmpil1;
+  if (tmpi->ic_code<IC_IMM_I64 || !(tmpil1=OptLag1(tmpi)))
+    return FALSE;
+  if (tmpil1->ic_code==IC_ADD_CONST && tmpi->ic_code==IC_DEREF &&
+        tmpi->ic_flags&ICF_ARG1_WAS_STK &&  tmpi->arg1.type&MDF_REG &&
+        tmpil1->res.type&MDF_REG && I32_MIN<=tmpil1->ic_data<=I32_MAX &&
+        !Bt(&cmp.non_ptr_vars_mask,tmpil1->arg1.reg)) {
+    if (tmpil1->arg1.type&MDF_REG) {
+      tmpi->ic_flags=tmpi->ic_flags&~ICF_ARG1_WAS_STK | tmpil1->ic_flags;
+      tmpi->ic_code=IC_MOV;
+      tmpi->arg1.type=MDF_DISP+tmpi->arg1_type_pointed_to;
+      tmpi->arg1.reg=tmpil1->arg1.reg;
+      tmpi->arg1.disp=tmpil1->ic_data;
+      OptSetNOP2(tmpil1,-1);
+    } else {
+      tmpil1->ic_code=IC_MOV;
+      tmpi->ic_code=IC_MOV;
+      tmpi->arg1.type=MDF_DISP+tmpi->arg1_type_pointed_to;
+      tmpi->arg1.disp=tmpil1->ic_data;
+    }
+    return TRUE;
+  }
+  return FALSE;
+}
+
+U0 OptPass6Lag(CCmpCtrl *cc,CPrsStk *ps,CIntermediateCode *tmpi,
+        I64 *_stk_ptr,I64 reg_stk_size,I64 *_clobbered_reg_mask)
+{
+  I64 stk_ptr=*_stk_ptr,code,
+        clobbered_stk_tmp_mask,clobbered_reg_mask=*_clobbered_reg_mask;
+  CHashFun *tmpf;
+  code=tmpi->ic_code;
+  if (tmpi->ic_flags&ICF_PASS_TRACE && Bt(&cc->saved_pass_trace,6)) {
+    "%2d:",stk_ptr;
+    ICPut(cc,tmpi);
+  }
+  if (code==IC_CALL_START) {
+    if (reg_stk_size==1 && stk_ptr>0)
+      clobbered_stk_tmp_mask=REGG_STK_TMP;
+    else
+      clobbered_stk_tmp_mask=0;
+    if (tmpf=tmpi->ic_data) {
+      if (Bt(&tmpf->flags,Ff_INTERNAL))
+        clobbered_stk_tmp_mask=0;
+      else {
+        clobbered_stk_tmp_mask&=tmpf->clobbered_reg_mask;
+        clobbered_reg_mask|=tmpf->clobbered_reg_mask;
+      }
+    }
+    tmpi->ic_data=clobbered_stk_tmp_mask;
+    PrsPush(ps,stk_ptr);
+    PrsPush(ps,clobbered_stk_tmp_mask);
+  } else if (code==IC_CALL_END) {
+    tmpi->ic_data=PrsPop(ps);
+    stk_ptr=PrsPop(ps);
+  } else if (code==IC_CALL_END2) {
+    ps->ptr--;
+    stk_ptr=PrsPop(ps);
+  }
+  if (intermediate_code_table[code].arg_cnt==IS_V_ARG)
+    stk_ptr-=tmpi->ic_data>>3;
+  if (tmpi->arg2.type&MDF_STK) {
+    stk_ptr--;
+    if (stk_ptr<reg_stk_size) {
+      tmpi->arg2.type=MDF_REG+tmpi->arg2.type.raw_type;
+      tmpi->arg2.reg=Bsf(REGG_STK_TMP);
+      tmpi->arg2.disp=0;
+    }
+  }
+  if (tmpi->arg1.type&MDF_STK) {
+    stk_ptr--;
+    if (stk_ptr<reg_stk_size) {
+      tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+      tmpi->arg1.reg=Bsf(REGG_STK_TMP);
+      tmpi->arg1.disp=0;
+    }
+  }
+  if (tmpi->res.type&MDF_STK && !(tmpi->ic_flags & ICF_PUSH_RES)) {
+    stk_ptr++;
+    if (stk_ptr<=reg_stk_size) {
+      tmpi->res.type=MDF_REG+tmpi->res.type.raw_type;
+      tmpi->res.reg=Bsf(REGG_STK_TMP);
+      clobbered_reg_mask|=REGG_STK_TMP;
+      tmpi->res.disp=0;
+    }
+  }
+  while (OptIC6(tmpi));
+  if (tmpi->res.type.raw_type!=RT_F64 && !(tmpi->ic_flags&ICF_USE_F64))
+    tmpi->ic_flags|=ICF_USE_INT;
+  *_stk_ptr=stk_ptr;
+  *_clobbered_reg_mask=clobbered_reg_mask;
+}
+
+U0 OptPass6(CCmpCtrl *cc)
+{
+  CIntermediateCode *tmpi,*tmpi_next,*tmpil1,*tmpil2,*old_tmpil2;
+  I64 stk_ptr=0,reg_stk_size,clobbered_reg_mask=REGG_CLOBBERED;
+  CPrsStk *ps=cc->ps;
+  ps->ptr=0;
+  ps->ptr2=0;
+  if (Bt(&cc->opts,OPTf_NO_REG_VAR) || cc->flags&CCF_NO_REG_OPT)
+    reg_stk_size=0;
+  else
+    reg_stk_size=1;
+#assert REGG_STK_TMP==1<<9
+  tmpi=cc->coc.coc_head.next;
+  old_tmpil2=NULL;
+  tmpil1=tmpil2=&cmp.ic_nop;
+  while (tmpi->ic_code) {
+    if (tmpi->ic_code>IC_NOP2) {
+      if (tmpil1->ic_code>IC_NOP2)
+        tmpil2=tmpil1;
+      tmpil1=tmpi;
+      if (tmpi->arg2.type&MDF_STK) {
+        if (tmpil2->res.type&MDF_STK &&
+              !(tmpil2->ic_flags&ICF_PUSH_RES)) {
+          if (tmpi->ic_code==IC_ASSIGN && tmpi->ic_flags&ICF_BY_VAL &&
+                tmpi->ic_flags&ICF_RES_NOT_USED &&
+                tmpil2->ic_code!=IC_CALL_END &&
+                tmpil2->ic_code!=IC_CALL_END2 &&
+                tmpil2->ic_code!=IC_SET_RAX &&
+                !(tmpi->ic_flags&(ICF_ARG2_TO_F64|ICF_ARG2_TO_INT)) &&
+                !(tmpil2->ic_flags&(ICF_RES_TO_F64|ICF_RES_TO_INT))) {
+            tmpil2->res.type =tmpi->arg1.type&MDG_MASK+
+                  tmpi->arg1_type_pointed_to;
+            tmpil2->res.reg  =tmpi->arg1.reg;
+            tmpil2->res.disp =tmpi->arg1.disp;
+            tmpil2->ic_flags=tmpil2->ic_flags
+                  &~(ICF_RES_NOT_USED|ICF_RES_WAS_STK)
+            |tmpi->ic_flags&~(ICF_BY_VAL|ICF_ARG1_WAS_STK|ICF_ARG2_WAS_STK);
+            old_tmpil2=NULL;
+            OptSetNOP1(tmpi);
+          } else {
+            tmpi->arg2.type=MDF_REG+tmpi->arg2.type.raw_type;
+            tmpi->arg2.reg=REG_RAX;
+            tmpi->arg2.disp=0;
+            tmpil2->res.type=MDF_REG+tmpil2->res.type.raw_type;
+            tmpil2->res.reg=REG_RAX;
+            tmpil2->res.disp=0;
+          }
+        }
+      } else if (tmpi->arg1.type&MDF_STK && tmpil2->res.type&MDF_STK &&
+            !(tmpil2->ic_flags&ICF_PUSH_RES)) {
+        tmpi->arg1.type=MDF_REG+tmpi->arg1.type.raw_type;
+        tmpi->arg1.disp=0;
+        tmpil2->res.type=MDF_REG+tmpil2->res.type.raw_type;
+        tmpil2->res.disp=0;
+        if (intermediate_code_table[tmpi->ic_code].arg_cnt==IS_2_ARG) {
+          tmpi->arg1.reg=REG_R8;
+          tmpil2->res.reg=REG_R8;
+        } else {
+          tmpi->arg1.reg=REG_RAX;
+          tmpil2->res.reg=REG_RAX;
+        }
+      }
+      if (tmpi->ic_flags & ICF_PUSH_RES)
+        tmpi->res.type==MDF_STK+tmpi->res.type.raw_type;
+      if (old_tmpil2!=tmpil2) {
+        if (tmpil2->ic_code>IC_NOP2)
+          OptPass6Lag(cc,ps,tmpil2,&stk_ptr,reg_stk_size,&clobbered_reg_mask);
+        old_tmpil2=tmpil2;
+      }
+    }
+    tmpi_next=tmpi->next;
+    if (tmpi->ic_code<=IC_NOP2)
+      OptFree(tmpi);
+    tmpi=tmpi_next;
+  }
+  if (ps->ptr>2) {
+    "Pass:%d Stk:%08X\n",cc->pass,ps->ptr;
+    LexExcept(cc,"Compiler Optimization Error at ");
+  }
+  if (cc->htc.fun) {
+    cc->htc.fun->used_reg_mask&=~REGG_STK_TMP;
+    cc->htc.fun->used_reg_mask|=clobbered_reg_mask;
+    cc->htc.fun->clobbered_reg_mask=clobbered_reg_mask;
+    if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT) &&
+          Bt(&cc->saved_pass_trace,6)) {
+      "Used      Reg Mask:%04X\n",cc->htc.fun->used_reg_mask;
+      "Clobbered Reg Mask:%04X\n",clobbered_reg_mask;
+    }
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/OptPass789A.HC.HTML b/public/Wb/Home/Src/Compiler/OptPass789A.HC.HTML new file mode 100755 index 0000000..cddf502 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/OptPass789A.HC.HTML @@ -0,0 +1,1183 @@ + + + + + + + + + + + +
+I64 OptPass789A(CCmpCtrl *cc,COptReg *reg_offsets,U8 *buf,CDbgInfo **_dbg)
+{/*cc->pass==7 is first time
+cc->pass==8 is second time
+cc->pass==9 is third time
+cc->pass==9 is fourth time and repeated until size stops shrinking
+size is now known
+cc->pass==10 is final pass, code is placed into buf.
+*/
+  CIntermediateCode *tmpi,*tmpi_next;
+  I64 i,cnt,num_lines=cc->max_line+1-cc->min_line,rip=0,rip2;
+  U8  *ptr,saved_arg1_arg2_r[3*sizeof(CICArg)];
+  CCodeMisc *lb;
+  CAOT *tmpaot;
+  CAOTAbsAddr *tmpa;
+  CAOTImportExport *tmpie;
+  CAOTHeapGlbl *tmphg;
+  CAOTHeapGlblRef *tmphgr;
+  CDbgInfo *dbg_info;
+  CAOTCtrl *aotc=cc->aotc;
+  Bool short_jmp;
+  CHashClass *tmpc;
+  CHashFun *tmpf;
+  CHashGlblVar *tmpg;
+  CExternUsage *tmpeu;
+
+  if (_dbg) {
+    *_dbg=dbg_info=CAlloc(offset(CDbgInfo.body)+sizeof(U32)*(num_lines+1));
+    dbg_info->min_line=cc->min_line;
+    dbg_info->max_line=cc->max_line;
+    if (cc->flags&CCF_AOT_COMPILE)
+      dbg_info->body[0]=aotc->rip;
+    else
+      dbg_info->body[0]=buf;
+  } else
+    dbg_info=NULL;
+
+  if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT) &&
+        Bt(&cc->saved_pass_trace,cc->pass))
+    "$BK,1$$LTRED$$IV,1$This code gets merged together and patched.\n"
+          "$FG$$IV,0$$BK,0$";
+
+  cc->last_float_op_ic=NULL;
+  tmpi=&cc->coc.coc_head;
+  tmpi->ic_last_start=-1;
+  tmpi->ic_cnt=0;
+  tmpi=tmpi->next;
+  while (tmpi->ic_code) {
+    tmpi_next=tmpi->next;
+    if (tmpi->ic_flags&ICF_PASS_TRACE && Bt(&cc->saved_pass_trace,cc->pass))
+      ICPut(cc,tmpi);
+    rip2=rip;
+    if (cc->flags&CCF_AOT_COMPILE)
+      rip2+=aotc->rip;
+    else
+      rip2+=buf;
+    cc->cur_ic_float_op_num=0;
+    if (!(tmpi->ic_flags &ICF_CODE_FINAL)) {
+      tmpi->ic_flags=tmpi->ic_flags&
+            ~(ICF_PREV_DELETED|ICF_DONT_RESTORE)|ICF_CODE_FINAL;
+      if (cc->pass==7)
+        cc->dont_push_float=Btr(&tmpi->ic_flags,ICf_DONT_PUSH_FLOAT0);
+      MemCpy(saved_arg1_arg2_r,&tmpi->arg1,3*sizeof(CICArg));
+      tmpi->ic_cnt=0;
+      tmpi->ic_last_start=-1;
+      if (tmpi->arg2.type.mode) {
+        if (tmpi->ic_flags & ICF_ARG2_TO_F64) {
+          ICFCvt(cc,tmpi,REG_RAX,tmpi->arg2.type,
+                tmpi->arg2.reg,tmpi->arg2.disp,FALSE,CN_A2,rip2);
+          tmpi->arg2.type=MDF_REG+RT_I64;
+          tmpi->arg2.reg=REG_RAX;
+          tmpi->arg2.disp=0;
+        } else if (tmpi->ic_flags & ICF_ARG2_TO_INT) {
+          ICFCvt(cc,tmpi,REG_RAX,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,TRUE,CN_A2,rip2);
+          tmpi->arg2.type=MDF_REG+RT_I64;
+          tmpi->arg2.reg=REG_RAX;
+          tmpi->arg2.disp=0;
+        }
+      }
+      if (tmpi->arg1.type.mode) {
+        if (tmpi->ic_flags & ICF_ARG1_TO_F64) {
+          ICFCvt(cc,tmpi,REG_RDX,tmpi->arg1.type,
+                tmpi->arg1.reg,tmpi->arg1.disp,FALSE,CN_A1,rip2);
+          tmpi->arg1.type=MDF_REG+RT_I64;
+          tmpi->arg1.reg=REG_RDX;
+          tmpi->arg1.disp=0;
+        } else if (tmpi->ic_flags & ICF_ARG1_TO_INT) {
+          ICFCvt(cc,tmpi,REG_RDX,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,TRUE,CN_A1,rip2);
+          tmpi->arg1.type=MDF_REG+RT_I64;
+          tmpi->arg1.reg=REG_RDX;
+          tmpi->arg1.disp=0;
+        }
+      }
+
+      switch [tmpi->ic_code] {
+        start:
+          start:
+            case IC_ABS_ADDR:
+              ICU16(tmpi,0xB848);
+              ICU64(tmpi,tmpi->ic_data);
+              if (buf && cc->flags&CCF_AOT_COMPILE &&
+                    !(cc->flags&(CCF_NO_ABSS|CCF_ASM_EXPRESSIONS))) {
+                tmpa=CAlloc(sizeof(CAOTAbsAddr));
+                tmpa->next=aotc->abss;
+                tmpa->type=AAT_ADD_U64;
+                aotc->abss=tmpa;
+                tmpa->rip=rip2+tmpi->ic_cnt-8;
+              }
+              break;
+            case IC_HEAP_GLBL:
+              ICU16(tmpi,0xB848);
+              ICU64(tmpi,0);
+              tmphg=tmpi->ic_data;
+              if (buf && cc->flags&CCF_AOT_COMPILE &&
+//TODO:is this necessary--flags?
+                    !(cc->flags&(CCF_NO_ABSS|CCF_ASM_EXPRESSIONS))) {
+                tmphgr=CAlloc(sizeof(CAOTHeapGlblRef));
+                tmphgr->next=tmphg->references;
+                tmphg->references=tmphgr;
+                tmphgr->rip=rip2+tmpi->ic_cnt-8;
+              }
+              break;
+            case IC_ADDR_IMPORT:
+              ICU8(tmpi,0xB8);
+              ICU32(tmpi,0);
+              if (buf && !(cc->flags&CCF_NO_ABSS)) {
+                tmpg=tmpi->ic_data;
+                tmpie=CAlloc(sizeof(CAOTImportExport));
+                tmpie->type=IET_IMM_U32;
+                tmpie->rip=rip2+tmpi->ic_cnt-4;
+                tmpie->next=tmpg->ie_lst;
+                tmpg->ie_lst=tmpie;
+              }
+              ICU24(tmpi,0xC06348);
+              break;
+            case IC_RIP:
+              ICU16(tmpi,0xB848);
+              ICU64(tmpi,rip2+tmpi->ic_cnt-2);
+              if (cc->flags&CCF_AOT_COMPILE && buf &&!(cc->flags&CCF_NO_ABSS)) {
+                tmpa=CAlloc(sizeof(CAOTAbsAddr));
+                tmpa->next=aotc->abss;
+                tmpa->type=AAT_ADD_U64;
+                aotc->abss=tmpa;
+                tmpa->rip=rip2+tmpi->ic_cnt-8;
+              }
+              break;
+          end:
+            ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  MDF_REG+RT_I64,REG_RAX,0,rip2);
+            break;
+          case IC_BR_CARRY:
+            ICFlagBranch(tmpi,rip,0x72820F,buf);
+            break;
+          case IC_BR_NOT_CARRY:
+            ICFlagBranch(tmpi,rip,0x73830F,buf);
+            break;
+          case IC_BR_ZERO:
+            ICTestAndBranch(tmpi,rip,0x74840F,buf,rip2);
+            break;
+          case IC_BR_NOT_ZERO:
+            ICTestAndBranch(tmpi,rip,0x75850F,buf,rip2);
+            break;
+          case IC_BR_MM_ZERO:
+            ICPreIncDec(tmpi,SLASH_OP_DEC,rip2);
+            ICFlagBranch(tmpi,rip,0x74840F,buf);
+            break;
+          case IC_BR_MM_NOT_ZERO:
+            ICPreIncDec(tmpi,SLASH_OP_DEC,rip2);
+            ICFlagBranch(tmpi,rip,0x75850F,buf);
+            break;
+          case IC_BR_EQU_EQU:
+            ICCmpAndBranch(tmpi,FALSE,rip,0x74840F,0x74840F,
+                  0x74840F,0x74840F,buf,rip2);
+            break;
+          case IC_BR_EQU_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x74840F,0x74840F,
+                  0x74840F,0x74840F,buf,rip2);
+            break;
+          case IC_BR_NOT_EQU:
+            ICCmpAndBranch(tmpi,FALSE,rip,0x75850F,0x75850F,
+                  0x75850F,0x75850F,buf,rip2);
+            break;
+          case IC_BR_NOT_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x75850F,0x75850F,
+                  0x75850F,0x75850F,buf,rip2);
+            break;
+          case IC_BR_LESS:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x72820F,0x77870F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x72820F,0x7C8C0F,
+                    0x77870F,0x7F8F0F,buf,rip2);
+            break;
+          case IC_BR_LESS2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x72820F,0x7C8C0F,
+                  0x77870F,0x7F8F0F,buf,rip2);
+            break;
+          case IC_BR_GREATER_EQU:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x73830F,0x76860F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x73830F,0x7D8D0F,
+                    0x76860F,0x7E8E0F,buf,rip2);
+            break;
+          case IC_BR_GREATER_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x73830F,0x7D8D0F,
+                  0x76860F,0x7E8E0F,buf,rip2);
+            break;
+          case IC_BR_GREATER:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x77870F,0x72820F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x77870F,0x7F8F0F,
+                    0x72820F,0x7C8C0F,buf,rip2);
+            break;
+          case IC_BR_GREATER2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x77870F,0x7F8F0F,
+                  0x72820F,0x7C8C0F,buf,rip2);
+            break;
+          case IC_BR_LESS_EQU:
+            if (tmpi->ic_flags&ICF_USE_F64)
+              ICFCmpAndBranch(cc,tmpi,  rip,0x76860F,0x73830F,buf,rip2);
+            else
+              ICCmpAndBranch(tmpi,FALSE,rip,0x76860F,0x7E8E0F,
+                    0x73830F,0x7D8D0F,buf,rip2);
+            break;
+          case IC_BR_LESS_EQU2:
+            ICCmpAndBranch(tmpi,TRUE,rip,0x76860F,0x7E8E0F,
+                  0x73830F,0x7D8D0F,buf,rip2);
+            break;
+          case IC_BR_BT:
+            ICBrBitOps(tmpi,rip,0xA30F,0x20BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_BTS:
+            ICBrBitOps(tmpi,rip,0xAB0F,0x28BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_BTR:
+            ICBrBitOps(tmpi,rip,0xB30F,0x30BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_BTC:
+            ICBrBitOps(tmpi,rip,0xBB0F,0x38BA0F,0x72820F,buf,rip2);
+            break;
+          case IC_BR_NOT_BT:
+            ICBrBitOps(tmpi,rip,0xA30F,0x20BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_NOT_BTS:
+            ICBrBitOps(tmpi,rip,0xAB0F,0x28BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_NOT_BTR:
+            ICBrBitOps(tmpi,rip,0xB30F,0x30BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_NOT_BTC:
+            ICBrBitOps(tmpi,rip,0xBB0F,0x38BA0F,0x73830F,buf,rip2);
+            break;
+          case IC_BR_AND_ZERO:
+            ICAndBranch(tmpi,rip,0x74840F,buf,rip2);
+            break;
+          case IC_BR_AND_NOT_ZERO:
+            ICAndBranch(tmpi,rip,0x75850F,buf,rip2);
+            break;
+          case IC_SUB_CALL:
+            lb=OptLabelFwd(tmpi->ic_data);
+            ICU8(tmpi,0xE8);
+            ICU32(tmpi,lb->addr-(rip+5));
+            break;
+          case IC_JMP:
+            lb=OptLabelFwd(tmpi->ic_data);
+            short_jmp=ToBool(tmpi->ic_flags&ICF_SHORT_JMP);
+            if (!buf && lb->addr!=INVALID_PTR &&
+                  I8_MIN+5<lb->addr-rip<I8_MAX-5)
+              short_jmp=TRUE;
+            if (short_jmp) {
+              tmpi->ic_flags|=ICF_SHORT_JMP;
+              i=lb->addr-(rip+2);
+              if (buf || i)
+                ICU16(tmpi,i<<8+0xEB);
+              else
+                tmpi->ic_code=IC_NOP1;
+            } else {
+              i=lb->addr-(rip+5);
+              ICU8(tmpi,0xE9);
+              ICU32(tmpi,i);
+            }
+            break;
+          case IC_LABEL:
+            lb=tmpi->ic_data;
+            lb->addr=rip;
+            if (lb->flags&CMF_POP_CMP) {
+              ICAddRSP(tmpi,-8,FALSE);
+              ICAddRSP(tmpi,8,FALSE);
+            }
+            if (lb->type==CMT_ASM_LABEL)
+              lb->addr+=lb->rip;
+            break;
+          case IC_STR_CONST:
+          case IC_GET_LABEL:
+            lb=tmpi->ic_data;
+            if (cc->flags&CCF_AOT_COMPILE)
+              i=lb->addr+aotc->rip;
+            else
+              i=lb->addr+buf;
+            ICLea(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  MDF_RIP_DISP32+RT_PTR,0,i,cc,buf,rip2);
+            break;
+          case IC_ASM:
+            tmpaot=tmpi->ic_data;
+            tmpi->ic_cnt+=tmpaot->aot_U8s;
+            if (buf) {
+              MemCpy(buf+rip,tmpaot->buf,tmpaot->aot_U8s);
+              Free(tmpaot->buf);
+              tmpaot->buf=buf;
+              tmpaot->rip=rip;
+              tmpaot->rip2=rip2;
+              if (cc->flags&CCF_AOT_COMPILE)
+                CmpFixUpAOTAsm(cc,tmpaot);
+              else
+                CmpFixUpJITAsm(cc,tmpaot);
+              cnt=tmpi->ic_cnt;
+              goto op789A_skip_copy;
+            }
+            break;
+          case IC_CALL:
+            i=tmpi->ic_data-(rip2+5);
+            if (!(I32_MIN<=i<=I32_MAX) && !(cc->flags&CCF_AOT_COMPILE)) {
+              ICU16(tmpi,0xBB48);
+              ICU64(tmpi,tmpi->ic_data);
+              ICU16(tmpi,0xD3FF);
+            } else {
+              ICU8(tmpi,0xE8);
+              ICU32(tmpi,i);
+            }
+            break;
+          case IC_CALL_EXTERN: //Only for static modules
+            ICU8(tmpi,0xE8);
+            ICU32(tmpi,0);
+            if (buf) {
+              tmpf=tmpi->ic_data;
+              tmpeu=CAlloc(sizeof(CExternUsage));
+              tmpeu->next=tmpf->ext_lst;
+              tmpf->ext_lst=tmpeu;
+              tmpeu->rip=rip2+1;
+            }
+            break;
+          case IC_CALL_INDIRECT2:
+            ICU16(tmpi,0xBB48);
+            if (cc->flags&CCF_AOT_COMPILE) i=rip2+tmpi->ic_cnt;
+            ICU64(tmpi,tmpi->ic_data);
+            ICU16(tmpi,0x13FF);
+            if (buf && cc->flags&CCF_AOT_COMPILE&& !(cc->flags&CCF_NO_ABSS)) {
+              tmpa=CAlloc(sizeof(CAOTAbsAddr));
+              tmpa->next=aotc->abss;
+              tmpa->type=AAT_ADD_U64;
+              aotc->abss=tmpa;
+              tmpa->rip=i;
+            }
+            break;
+          case IC_CALL_IMPORT:
+            if (GetOption(OPTf_USE_IMM64)) {
+              ICU16(tmpi,0xBB48);
+              ICU64(tmpi,0);
+              if (buf) {
+                tmpf=tmpi->ic_data;
+                tmpie=CAlloc(sizeof(CAOTImportExport));
+                tmpie->type=IET_IMM_I64;
+                tmpie->rip=rip2+tmpi->ic_cnt-8;
+                tmpie->next=tmpf->ie_lst;
+                tmpf->ie_lst=tmpie;
+              }
+              ICU16(tmpi,0xD3FF);
+            } else {
+              ICU8(tmpi,0xE8);
+              ICU32(tmpi,0);
+              if (buf) {
+                tmpf=tmpi->ic_data;
+                tmpie=CAlloc(sizeof(CAOTImportExport));
+                tmpie->type=IET_REL_I32;
+                tmpie->rip=rip2+tmpi->ic_cnt-4;
+                tmpie->next=tmpf->ie_lst;
+                tmpf->ie_lst=tmpie;
+              }
+            }
+            break;
+        end:
+          tmpi->ic_flags&=~ICF_CODE_FINAL;
+          break;
+        case IC_LEAVE:
+          if (cc->htc.fun) {
+            if (Bt(&cc->htc.fun->flags,Ff_INTERRUPT))
+              ICPopRegs(tmpi,REGG_CLOBBERED|cc->htc.fun->used_reg_mask&
+                    (REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS|REGG_STK_TMP));
+            else
+              ICPopRegs(tmpi,cc->htc.fun->used_reg_mask&
+                    (REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS));
+          }
+          if (tmpi->ic_data<=I16_MAX) {
+            if (tmpi->ic_data)
+              ICU8(tmpi,0xC9); //LEAVE
+            else
+              ICU8(tmpi,0x5D); //POP RBP
+          } else {
+            ICAddRSP(tmpi,tmpi->ic_data);
+            ICU8(tmpi,0x5D); //POP RBP
+          }
+          if (cc->htc.fun && Bt(&cc->htc.fun->flags,Ff_INTERRUPT)) {
+            if (Bt(&cc->htc.fun->flags,Ff_HASERRCODE))
+              ICAddRSP(tmpi,8);
+            ICU16(tmpi,0xCF48);
+          } else if (cc->htc.fun && cc->htc.fun->arg_cnt &&
+                (Bt(&cc->htc.fun->flags,Ff_RET1) ||
+                Bt(&cc->htc.fun->flags,Ff_ARGPOP)) &&
+                !Bt(&cc->htc.fun->flags,Ff_NOARGPOP)) {
+            ICU8(tmpi,0xC2);
+            ICU16(tmpi,cc->htc.fun->arg_cnt<<3);
+          } else
+            ICU8(tmpi,0xC3);
+          break;
+        case IC_RET:
+          ICU8(tmpi,0xC3);
+          break;
+        case IC_FS:
+          ICZero(tmpi,REG_RAX);
+          ICU32(tmpi,0x8B4864);
+          break;
+        case IC_GS:
+          ICZero(tmpi,REG_RAX);
+          ICU32(tmpi,0x8B4865);
+          break;
+        case IC_MOV_FS:
+          ICZero(tmpi,REG_RAX);
+          ICU8(tmpi,0x64);
+//It's ugly to use ic_class here
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                MDF_DISP+CmpRawType(tmpi->ic_class),REG_RAX,tmpi->ic_data,
+                rip2);
+          break;
+        case IC_MOV_GS:
+          ICZero(tmpi,REG_RAX);
+          ICU8(tmpi,0x65);
+//It's ugly to use ic_class here
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                MDF_DISP+CmpRawType(tmpi->ic_class),REG_RAX,tmpi->ic_data,
+                rip2);
+          break;
+        case IC_HOLYC_TYPECAST:
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_COM:
+          ICUnaries(tmpi,SLASH_OP_NOT,rip2);
+          break;
+        case IC_NOT:
+          ICNot(tmpi,rip2);
+          break;
+        case IC_UNARY_MINUS:
+          if (tmpi->res.type.raw_type==RT_F64)
+            ICFUnaryMinus(cc,tmpi,buf,rip2);
+          else
+            ICUnaries(tmpi,SLASH_OP_NEG,rip2);
+          break;
+        case IC_ADDR:
+        case IC_MOV:
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_DEREF:
+          ICDeref(tmpi,rip2);
+          break;
+        case IC_DEREF_PP:
+          ICDerefPostIncDec(tmpi,SLASH_OP_INC,rip2);
+          break;
+        case IC_DEREF_MM:
+          ICDerefPostIncDec(tmpi,SLASH_OP_DEC,rip2);
+          break;
+        case IC__PP:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPostIncDec(tmpi,SLASH_OP_INC,rip2);
+          else
+            ICFPostIncDec(cc,tmpi,CMP_TEMPLATE_INC,rip2);
+          break;
+        case IC__MM:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPostIncDec(tmpi,SLASH_OP_DEC,rip2);
+          else
+            ICFPostIncDec(cc,tmpi,CMP_TEMPLATE_DEC,rip2);
+          break;
+        case IC_PP_:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPreIncDec(tmpi,SLASH_OP_INC,rip2);
+          else
+            ICFPreIncDec(cc,tmpi,CMP_TEMPLATE_INC,rip2);
+          break;
+        case IC_MM_:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICPreIncDec(tmpi,SLASH_OP_DEC,rip2);
+          else
+            ICFPreIncDec(cc,tmpi,CMP_TEMPLATE_DEC,rip2);
+          break;
+        case IC_LEA:
+          ICLea(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,cc,buf,rip2);
+          break;
+        case IC_POWER:
+          ICFPow(cc,tmpi,buf,rip2);
+          break;
+        case IC_SHL:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE0D1E0D3E0C1,0xE0D1E0D3E0C1,rip2);
+          break;
+        case IC_SHR:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE8D1E8D3E8C1,0xF8D1F8D3F8C1,rip2);
+          break;
+        case IC_MUL:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICMul(tmpi,rip2);
+          else
+            ICFMul(cc,tmpi,buf,rip2);
+          break;
+        case IC_DIV:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICDiv(tmpi,rip2);
+          else
+            ICFDiv(cc,tmpi,buf,rip2);
+          break;
+        case IC_MOD:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICMod(tmpi,rip2);
+          else
+            ICFMod(cc,tmpi,rip2);
+          break;
+        case IC_AND:
+          ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x23,rip2);
+          break;
+        case IC_OR:
+          ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x0B,rip2);
+          break;
+        case IC_XOR:
+          ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x33,rip2);
+          break;
+        case IC_ADD:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICAddEct(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,0x03,rip2);
+          else
+            ICFAdd(cc,tmpi,buf,rip2);
+          break;
+        case IC_SUB:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICSub(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+          else
+            ICFSub(cc,tmpi,buf,rip2);
+          break;
+        case IC_EQU_EQU:
+          ICCmp(tmpi,0x75,0x75,rip2);
+          break;
+        case IC_NOT_EQU:
+          ICCmp(tmpi,0x74,0x74,rip2);
+          break;
+        case IC_LESS:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x73,0x7D,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_LESS,rip2);
+          break;
+        case IC_GREATER_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x72,0x7C,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_GREATER_EQU,rip2);
+          break;
+        case IC_GREATER:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x76,0x7E,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_GREATER,rip2);
+          break;
+        case IC_LESS_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICCmp(tmpi,0x77,0x7F,rip2);
+          else
+            ICFCmp(cc,tmpi,CMP_TEMPLATE_LESS_EQU,rip2);
+          break;
+        case IC_AND_AND:
+          ICAndAnd(tmpi,rip2);
+          break;
+        case IC_OR_OR:
+          ICOrOr(tmpi,rip2);
+          break;
+        case IC_XOR_XOR:
+          ICXorXor(tmpi,rip2);
+          break;
+        case IC_ASSIGN:
+          ICAssign(tmpi,rip2);
+          break;
+        case IC_ASSIGN_PP:
+          ICAssignPostIncDec(tmpi,SLASH_OP_INC,rip2);
+          break;
+        case IC_ASSIGN_MM:
+          ICAssignPostIncDec(tmpi,SLASH_OP_DEC,rip2);
+          break;
+        case IC_SHL_EQU:
+          ICShiftEqu(tmpi,tmpi->arg1_type_pointed_to,
+                tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE0D1E0D3E0C1,0xE0D1E0D3E0C1,rip2);
+          break;
+        case IC_SHR_EQU:
+          ICShiftEqu(tmpi,tmpi->arg1_type_pointed_to,
+                tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                0xE8D1E8D3E8C1,0xF8D1F8D3F8C1,rip2);
+          break;
+        case IC_MUL_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICMulEqu(tmpi,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FMUL,buf,rip2);
+          break;
+        case IC_DIV_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICDivEqu(tmpi,FALSE,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FDIV,buf,rip2);
+          break;
+        case IC_MOD_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICDivEqu(tmpi,TRUE,rip2);
+          else
+            ICFModEqu(cc,tmpi,rip2);
+          break;
+        case IC_AND_EQU:
+          ICAndEqu(tmpi,rip2);
+          break;
+        case IC_OR_EQU:
+          ICOrEqu(tmpi,rip2);
+          break;
+        case IC_XOR_EQU:
+          ICXorEqu(tmpi,rip2);
+          break;
+        case IC_ADD_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+                  tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                  0x010000000003,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FADD,buf,rip2);
+          break;
+        case IC_SUB_EQU:
+          if (tmpi->ic_flags&ICF_USE_INT)
+            ICAddSubEctEqu(tmpi,tmpi->arg1_type_pointed_to,
+                  tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,
+                  0x29000000052B,rip2);
+          else
+            ICFOpEqu(cc,tmpi,SLASH_OP_FSUB,buf,rip2);
+          break;
+        case IC_SHL_CONST:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                MDF_IMM+RT_I64,0,tmpi->ic_data,
+                0xE0D1E0D3E0C1,0xE0D1E0D3E0C1,rip2);
+          break;
+        case IC_SHR_CONST:
+          ICShift(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,
+                MDF_IMM+RT_I64,0,tmpi->ic_data,
+                0xE8D1E8D3E8C1,0xF8D1F8D3F8C1,rip2);
+          break;
+        case IC_ADD_CONST:
+          ICAddSubEctImm(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,tmpi->ic_data,
+                0x0003,rip2);
+          break;
+        case IC_SUB_CONST:
+          ICAddSubEctImm(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,tmpi->ic_data,
+                0x052B,rip2);
+          break;
+        case IC_ENTER:
+          ICU32(tmpi,0xEC8B4855);
+          if (tmpi->ic_data)
+            ICAddRSP(tmpi,-tmpi->ic_data,FALSE);
+          if (cc->htc.fun) {
+            if (Bt(&cc->htc.fun->flags,Ff_INTERRUPT))
+              ICPushRegs(tmpi,REGG_CLOBBERED|cc->htc.fun->used_reg_mask&
+                    (REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS|REGG_STK_TMP));
+            else {
+              if (sys_var_init_flag && i)
+                ICLocalVarInit(tmpi);
+              ICPushRegs(tmpi,cc->htc.fun->used_reg_mask
+                    &(REGG_LOCAL_VARS|REGG_LOCAL_NON_PTR_VARS));
+            }
+            for (i=0;i<REG_REGS_NUM;i++)
+              if (reg_offsets[i]>0 && reg_offsets[i].offset!=I64_MAX) {
+                tmpc=OptClassFwd(reg_offsets[i].m->member_class);
+                ICMov(tmpi,MDF_REG+RT_I64,i,0,MDF_DISP+tmpc->raw_type,
+                      REG_RBP,reg_offsets[i].offset,rip2);
+              }
+          }
+          break;
+        case IC_ADD_RSP:
+          ICAddRSP(tmpi,tmpi->ic_data);
+          break;
+        case IC_CALL_INDIRECT:
+          if (I8_MIN<=tmpi->ic_data<=I8_MAX) {
+            ICU24(tmpi,0x2454FF);  //CALL disp[RSP]
+            ICU8(tmpi,tmpi->ic_data);
+          } else {
+            ICU24(tmpi,0x2494FF);  //CALL disp[RSP]
+            ICU32(tmpi,tmpi->ic_data);
+          }
+          break;
+        case IC_PUSH:
+          ICPush(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_POP:
+          ICU8(tmpi,0x58);
+          break;
+        case IC_INVLPG:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU24(tmpi,0x38010F);
+          break;
+        case IC_CLFLUSH:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU24(tmpi,0x38AE0F);
+          break;
+        case IC_GET_RFLAGS:
+          ICU8(tmpi,0x9C);
+          ICPop(tmpi,MDF_REG+RT_I64,REG_RAX,0,rip2);
+          break;
+        case IC_CARRY:
+          ICU24(tmpi,0xC0920F); //SETC AL
+          ICU24(tmpi,0x01E083); //AND EAX,1
+          break;
+        case IC_RDTSC:
+          ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_RDTSC,TRUE,FALSE,FALSE,CN_INST);
+          break;
+        case IC_SET_RFLAGS:
+          ICPush(tmpi,tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU8(tmpi,0x9D);
+          break;
+        case IC_GET_RBP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_REG+RT_I64,REG_RBP,0,rip2);
+          break;
+        case IC_SET_RBP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RBP,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_GET_RSP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                MDF_REG+RT_I64,REG_RSP,0,rip2);
+          break;
+        case IC_SET_RSP:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RSP,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_RETURN_VAL:
+        case IC_SET_RAX:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          break;
+        case IC_RETURN_VAL2:
+        case IC_GET_RAX:
+          break;
+        case IC_BT:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xA30F,0x20BA0F,rip2);
+          break;
+        case IC_BTS:
+        case IC_LBTS:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xAB0F,0x28BA0F,rip2);
+          break;
+        case IC_BTR:
+        case IC_LBTR:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xB30F,0x30BA0F,rip2);
+          break;
+        case IC_BTC:
+        case IC_LBTC:
+          ICBitOps(tmpi,&tmpi->arg1,&tmpi->arg2,tmpi->next,
+                0xBB0F,0x38BA0F,rip2);
+          break;
+        case IC_BSF:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU32(tmpi,0xC0BC0F48);
+          ICU16(tmpi,0x0375);
+          ICU24(tmpi,0xD0F748);
+          break;
+        case IC_BSR:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU32(tmpi,0xC0BD0F48);
+          ICU16(tmpi,0x0375);
+          ICU24(tmpi,0xD0F748);
+          break;
+        case IC_SIGN_I64:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_SIGN_I64,
+                TRUE,FALSE,FALSE,CN_INST);
+          break;
+        case IC_TOUPPER:
+          ICToUpper(tmpi,rip2);
+          break;
+        case IC_TO_I64:
+          ICToI64(cc,tmpi,rip2);
+          break;
+        case IC_TO_F64:
+          ICToF64(cc,tmpi,rip2);
+          break;
+        case IC_TO_BOOL:
+          ICToBool(cc,tmpi,rip2);
+          break;
+        case IC_SQR:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_SQR,rip2);
+          break;
+        case IC_ABS:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_ABS,rip2);
+          break;
+        case IC_SQRT:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_SQRT,rip2);
+          break;
+        case IC_SIN:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_SIN,rip2);
+          break;
+        case IC_COS:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_COS,rip2);
+          break;
+        case IC_TAN:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_TAN,rip2);
+          break;
+        case IC_ATAN:
+          ICFTemplateFun(cc,tmpi,CMP_TEMPLATE_ATAN,rip2);
+          break;
+        case IC_ABS_I64:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICU24(tmpi,0xC08548);
+          ICU16(tmpi,0x0379);
+          ICU24(tmpi,0xD8F748);
+          break;
+        case IC_MIN_I64:
+          ICMinMax(tmpi,0x4F,rip2);
+          break;
+        case IC_MAX_I64:
+          ICMinMax(tmpi,0x4C,rip2);
+          break;
+        case IC_MIN_U64:
+          ICMinMax(tmpi,0x47,rip2);
+          break;
+        case IC_MAX_U64:
+          ICMinMax(tmpi,0x42,rip2);
+          break;
+        case IC_MOD_U64:
+          ICModU64(tmpi,rip2);
+          break;
+        case IC_SQR_I64:
+          ICSqr(tmpi,SLASH_OP_IMUL,rip2);
+          break;
+        case IC_SQR_U64:
+          ICSqr(tmpi,SLASH_OP_MUL,rip2);
+          break;
+        case IC_SWAP_U8:
+        case IC_SWAP_U16:
+        case IC_SWAP_U32:
+        case IC_SWAP_I64:
+          ICSwap(tmpi,rip2);
+          break;
+        case IC_QUE_INIT:
+          ICQueInit(tmpi,rip2);
+          break;
+        case IC_QUE_INS:
+          ICQueIns(tmpi,rip2);
+          break;
+        case IC_QUE_INS_REV:
+          ICQueInsRev(tmpi,rip2);
+          break;
+        case IC_QUE_REM:
+          ICQueRem(tmpi,rip2);
+          break;
+        case IC_STRLEN:
+          ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+          ICCopyTemplate(cc,tmpi,CMP_TEMPLATE_STRLEN,TRUE,FALSE,FALSE,CN_INST);
+          break;
+        case IC_IN_U32:
+          if (tmpi->arg1.type&MDF_IMM) {
+            ICU16(tmpi,0xC033);
+            if (tmpi->arg1.disp<=U8_MAX)
+              ICU16(tmpi,0xE5+tmpi->arg1.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+              ICU8(tmpi,0xED);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xC033);
+            ICU8(tmpi,0xED);
+          }
+          break;
+        case IC_IN_U16:
+          if (tmpi->arg1.type&MDF_IMM) {
+            ICU16(tmpi,0xC033);
+            if (tmpi->arg1.disp<=U8_MAX)
+              ICU24(tmpi,0xE500+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+              ICU16(tmpi,0xED00+OC_OP_SIZE_PREFIX);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xC033);
+            ICU16(tmpi,0xED00+OC_OP_SIZE_PREFIX);
+          }
+          break;
+        case IC_IN_U8:
+          if (tmpi->arg1.type&MDF_IMM) {
+            ICU16(tmpi,0xC033);
+            if (tmpi->arg1.disp<=U8_MAX)
+              ICU16(tmpi,0xE4+tmpi->arg1.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg1.disp<<16);
+              ICU8(tmpi,0xEC);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xC033);
+            ICU8(tmpi,0xEC);
+          }
+          break;
+        case IC_OUT_U32:
+          if (tmpi->arg2.type&MDF_IMM) {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            if (tmpi->arg2.disp<=U8_MAX)
+              ICU16(tmpi,0xE7+tmpi->arg2.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+              ICU8(tmpi,0xEF);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU8(tmpi,0xEF);
+          }
+          break;
+        case IC_OUT_U16:
+          if (tmpi->arg2.type&MDF_IMM) {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            if (tmpi->arg2.disp<=U8_MAX)
+              ICU24(tmpi,0xE700+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+              ICU16(tmpi,0xEF00+OC_OP_SIZE_PREFIX);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU16(tmpi,0xEF00+OC_OP_SIZE_PREFIX);
+          }
+          break;
+        case IC_OUT_U8:
+          if (tmpi->arg2.type&MDF_IMM) {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            if (tmpi->arg2.disp<=U8_MAX)
+              ICU16(tmpi,0xE6+tmpi->arg2.disp<<8);
+            else {
+              ICU32(tmpi,0xBA00+OC_OP_SIZE_PREFIX+tmpi->arg2.disp<<16);
+              ICU8(tmpi,0xEE);
+            }
+          } else {
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RDX,0,
+                  tmpi->arg2.type,tmpi->arg2.reg,tmpi->arg2.disp,rip2);
+            ICMov(tmpi,MDF_REG+RT_I64,REG_RAX,0,
+                  tmpi->arg1.type,tmpi->arg1.reg,tmpi->arg1.disp,rip2);
+            ICU8(tmpi,0xEE);
+          }
+          break;
+        case IC_NOBOUND_SWITCH:
+          ICSwitch(tmpi,rip,TRUE,cc,buf,rip2);
+          break;
+        case IC_SWITCH:
+          ICSwitch(tmpi,rip,FALSE,cc,buf,rip2);
+          break;
+        case IC_NOP1:
+        case IC_NOP2:
+          OptFree(tmpi);
+          goto op789A_next;
+        case IC_CALL_START:
+        case IC_PUSH_REGS:
+          ICPushRegs(tmpi,tmpi->ic_data);
+          break;
+        case IC_CALL_END:
+          ICPopRegs(tmpi,tmpi->ic_data);
+          if (tmpi->res.type.mode)
+            ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  MDF_REG+RT_I64,REG_RAX,0,rip2);
+          break;
+        case IC_POP_REGS:
+          ICPopRegs(tmpi,tmpi->ic_data);
+          break;
+        case IC_PUSH_CMP:
+        case IC_CALL_END2:
+        case IC_END:
+        case IC_ADD_RSP1:
+          break;
+        default:
+          "Pass:%d Missing IC hndlr\n",cc->pass;
+          ICPut(cc,tmpi);
+          LexExcept(cc,"Compiler Optimization Error at ");
+      }
+      if (tmpi->res.type.mode) {
+        if (tmpi->ic_flags & ICF_RES_TO_F64) {
+          if (tmpi->ic_code==IC_PUSH_CMP) {
+            ICU24(tmpi,0x242CDF); //FILD U64 [RSP]
+            ICU24(tmpi,0x241CDD); //FSTP U64 [RSP]
+          } else {
+            ICFCvt(cc,tmpi,REG_RAX,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                  FALSE,CN_RES,rip2);
+            if (!Bt(&tmpi->ic_flags,ICf_DONT_POP_FLOAT0+
+                  cc->cur_ic_float_op_num-1))
+              ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                    MDF_REG+RT_I64,REG_RAX,0,rip2);
+          }
+        } else if (tmpi->ic_flags & ICF_RES_TO_INT) {
+          ICFCvt(cc,tmpi,REG_RAX,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                TRUE,CN_RES,rip2);
+          ICMov(tmpi,tmpi->res.type,tmpi->res.reg,tmpi->res.disp,
+                MDF_REG+RT_I64,REG_RAX,0,rip2);
+        }
+      }
+    }
+    cnt=tmpi->ic_cnt;
+    if (tmpi->ic_flags&ICF_DEL_PREV_INS) {
+      if (cc->pass>8)
+        cnt=tmpi->ic_last_start;
+      tmpi->ic_flags&=~ICF_DEL_PREV_INS;
+    }
+    if (cnt && buf)
+      MemCpy(buf+rip,tmpi->ic_body,cnt);
+op789A_skip_copy:
+    if (dbg_info && cc->min_line<=tmpi->ic_line<=cc->max_line) {
+      i=tmpi->ic_line-cc->min_line;
+      if (!dbg_info->body[i])
+        dbg_info->body[i]=rip2;
+    }
+    if (tmpi->ic_flags&ICF_PASS_TRACE &&
+          Bt(&cc->saved_pass_trace,cc->pass) && cnt) {
+      "$RED$";
+      if (buf)
+        Un(buf+rip,cnt,64);
+      else
+        Un(tmpi->ic_body,cnt,64);
+      "$FG$";
+    }
+    if (!(tmpi->ic_flags&(ICF_CODE_FINAL|ICF_DONT_RESTORE)))
+      MemCpy(&tmpi->arg1,saved_arg1_arg2_r,3*sizeof(CICArg));
+    rip+=cnt;
+    if (tmpi->ic_cnt>=IC_BODY_SIZE && tmpi->ic_code!=IC_ASM)
+      throw('Compiler');
+op789A_next:
+    tmpi=tmpi_next;
+  }
+
+  lb=cc->coc.coc_next_misc;
+  while (lb!=&cc->coc.coc_next_misc) {
+    switch (lb->type) {
+      case CMT_STR_CONST:
+        lb->addr=rip;
+        if (buf)
+          MemCpy(buf+rip,lb->str,lb->st_len);
+        rip+=lb->st_len;
+        break;
+      case CMT_JMP_TABLE:
+        lb->addr=rip;
+        ptr=buf+lb->addr;
+        if (lb->flags&(CMF_I8_JMP_TABLE|CMF_U8_JMP_TABLE)) {
+          if (buf)
+            for (i=0;i<lb->range;i++)
+              *ptr++=lb->jmp_table[i]->addr-lb->begin->addr;
+          rip+=lb->range;
+        } else if (lb->flags&(CMF_I16_JMP_TABLE|CMF_U16_JMP_TABLE)) {
+          if (buf)
+            for (i=0;i<lb->range;i++)
+              *ptr(U16 *)++=lb->jmp_table[i]->addr-lb->begin->addr;
+          rip+=lb->range<<1;
+        } else {
+          if (buf)
+            for (i=0;i<lb->range;i++) {
+              if (cc->flags&CCF_AOT_COMPILE && !(cc->flags&CCF_NO_ABSS)) {
+                tmpa=CAlloc(sizeof(CAOTAbsAddr));
+                tmpa->next=aotc->abss;
+                tmpa->type=AAT_ADD_U32;
+                aotc->abss=tmpa;
+                tmpa->rip=aotc->rip+lb->addr+i<<2;
+                *ptr(U32 *)++=lb->jmp_table[i]->addr+aotc->rip;
+              } else
+                *ptr(U32 *)++=lb->jmp_table[i]->addr+buf;
+            }
+          rip+=lb->range<<2;
+        }
+        break;
+      case CMT_FLOAT_CONSTS:
+        lb->addr=rip;
+        if (buf)
+          MemCpy(buf+lb->addr,lb->float_consts,lb->num_consts*sizeof(F64));
+        rip+=lb->num_consts*sizeof(F64);
+        break;
+    }
+    lb=lb->next;
+  }
+  if (dbg_info) {
+    if (cc->flags&CCF_AOT_COMPILE)
+      dbg_info->body[num_lines]=rip+aotc->rip;
+    else
+      dbg_info->body[num_lines]=rip+buf;
+  }
+  return rip;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/PrsExp.HC.HTML b/public/Wb/Home/Src/Compiler/PrsExp.HC.HTML new file mode 100755 index 0000000..b953d83 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/PrsExp.HC.HTML @@ -0,0 +1,1209 @@ + + + + + + + + + + + +
+#define PE_UNARY_TERM1          0
+#define PE_UNARY_TERM2          1
+#define PE_MAYBE_MODIFIERS      2
+#define PE_UNARY_MODIFIERS      3
+#define PE_DEREFERENCE          4
+#define PE_CHECK_BINARY_OPS1    5
+#define PE_CHECK_BINARY_OPS2    6
+#define PE_DO_UNARY_OP          7
+#define PE_DO_BINARY_OP         8
+#define PE_POP_HIGHER           9
+#define PE_PUSH_LOWER           10
+#define PE_POP_ALL1             11
+#define PE_POP_ALL2             12
+
+CIntermediateCode *PrsAddOp(CCmpCtrl *cc,I64 stk_op,CHashClass *tmpc)
+{
+  CIntermediateCode *tmpi=cc->coc.coc_head.last;
+  Bool div_sizeof=FALSE;
+  switch (stk_op.u16[0]) {
+    case IC_ADD:
+      if (tmpc->ptr_stars_cnt && !tmpi->ic_class->ptr_stars_cnt &&
+            tmpi->ic_class->raw_type!=RT_F64) {
+        ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+        ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+      }
+      break;
+    case IC_SUB:
+      if (tmpc->ptr_stars_cnt && tmpi->ic_class->raw_type!=RT_F64) {
+        if (!tmpi->ic_class->ptr_stars_cnt) {
+          ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+          ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+        } else
+          div_sizeof=TRUE;
+      }
+      break;
+    case IC_AND_AND:
+    case IC_OR_OR:
+      ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+      break;
+    case IC_ADD_EQU:
+    case IC_SUB_EQU:
+      if (tmpc->ptr_stars_cnt) {
+        ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+        ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+      }
+      break;
+  }
+  tmpi=ICAdd(cc,stk_op,0,tmpc);
+  if (stk_op.u8[3]&ECF_HAS_PUSH_CMP) {
+    tmpi->ic_flags|=ICF_POP_CMP;
+    ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+    ICAdd(cc,IC_AND_AND,0,cmp.internal_types[RT_I64],ICF_POP_CMP);
+  }
+  if (div_sizeof) {
+    tmpc--;
+    if (tmpc->size!=1) {
+      ICAdd(cc,IC_IMM_I64,tmpc->size,cmp.internal_types[RT_I64]);
+      ICAdd(cc,IC_DIV,0,cmp.internal_types[RT_I64]);
+      tmpc=cmp.internal_types[RT_I64];
+    }
+  }
+  return tmpi;
+}
+
+U0 PrsExpression2(CCmpCtrl *cc,I64 *_max_prec,CPrsStk *ps)
+{
+  I64 i,cur_op,stk_op,state,max_prec=PREC_NULL,unary_pre_prec,paren_prec,
+        unary_post_prec,left_prec=PREC_MAX;
+  CIntermediateCode *tmpi;
+  CHashClass *tmpc;
+  CMemberLst *local_var;
+  CArrayDim *tmpad=NULL;
+
+  goto pe_unary_term1;
+  while (TRUE) {
+    switch [state] {
+      case PE_UNARY_TERM1:
+pe_unary_term1:
+        unary_pre_prec=PREC_NULL;
+        unary_post_prec=PREC_NULL;
+        cc->flags&=~(CCF_PAREN+CCF_PREINC+CCF_PREDEC+CCF_POSTINC+
+              CCF_POSTDEC+CCF_FUN_EXP);
+      case PE_UNARY_TERM2:
+        state=PrsUnaryTerm(cc,ps,&local_var,&tmpad,
+              &max_prec,&unary_pre_prec,&paren_prec);
+        break;
+      case PE_UNARY_MODIFIERS:
+        state=PrsUnaryModifier(cc,ps,&local_var,&tmpad,&unary_post_prec);
+        break;
+      case PE_MAYBE_MODIFIERS:
+        if (cc->token=='(') { //Typecast or fun_ptr
+          cc->flags|=CCF_RAX;
+          state=PrsUnaryModifier(cc,ps,&local_var,&tmpad,&unary_post_prec);
+        } else
+          goto pe_check_binary_ops1;
+        break;
+      case PE_DEREFERENCE:
+        if (!(cc->flags&(CCF_PREINC|CCF_PREDEC|CCF_POSTINC|CCF_POSTDEC)))
+          i=IC_DEREF+PREC_UNARY_PRE<<16;
+        else {
+          if (cc->flags & CCF_POSTINC)
+            i=IC__PP+PREC_UNARY_POST<<16;
+          else if (cc->flags & CCF_POSTDEC)
+            i=IC__MM+PREC_UNARY_POST<<16;
+          else if (cc->flags & CCF_PREDEC)
+            i=IC_MM_+PREC_UNARY_PRE<<16;
+          else
+            i=IC_PP_+PREC_UNARY_PRE<<16;
+          cc->flags&=~(CCF_PREINC|CCF_PREDEC|CCF_POSTINC|CCF_POSTDEC);
+        }
+        tmpi=cc->coc.coc_head.last;
+        if (cc->flags & (CCF_RAX|CCF_ARRAY)) {
+          if (tmpi->ic_code==IC_DEREF)
+            tmpi->ic_code=i;
+        } else {
+          tmpc=OptClassFwd(tmpi->ic_class-1);
+          ICAdd(cc,i,0,tmpc);
+        }
+      case PE_CHECK_BINARY_OPS1:
+pe_check_binary_ops1:
+        if (paren_prec) {
+          if (unary_pre_prec || unary_post_prec) {
+            if (paren_prec<=unary_pre_prec && !unary_post_prec)
+              ParenWarning(cc);
+            paren_prec=PREC_NULL;
+          } else if (paren_prec<=PREC_UNARY_PRE+ASSOC_MASK)
+            ParenWarning(cc);
+        }
+        cur_op=cmp.binary_ops[cc->token];
+
+      case PE_CHECK_BINARY_OPS2:
+pe_check_binary_ops2:
+        stk_op=PrsPop(ps);
+        tmpc=PrsPop(ps);
+        if (!(0<stk_op.u8[2]<=PREC_UNARY_PRE+ASSOC_MASK))
+          goto pe_do_binary_op;
+
+      case PE_DO_UNARY_OP:
+        if (cur_op.u16[0]==IC_POWER &&
+              stk_op.u16[0]==IC_UNARY_MINUS) {
+          Lex(cc); //skip ` op
+          left_prec=cur_op.i8[2];
+          PrsPush(ps,tmpc);
+          PrsPush(ps,stk_op);
+          PrsPush(ps,cc->coc.coc_head.last->ic_class);
+          PrsPush(ps,cur_op);
+          goto pe_unary_term1;
+        } else {
+          tmpi=cc->coc.coc_head.last;
+          tmpc=tmpi->ic_class;
+          if (stk_op.u16[0]==IC_DEREF && tmpc->ptr_stars_cnt)
+            tmpc--;
+          else if (stk_op.u16[0]==IC_ADDR) {
+            cc->abs_cnts.c_addres++;
+            if (intermediate_code_table[tmpi->ic_code].type==IST_DEREF)
+              OptFree(tmpi);
+            tmpc++;
+          }
+          tmpc=OptClassFwd(tmpc);
+          if (stk_op)
+            ICAdd(cc,stk_op,0,tmpc);
+          goto pe_check_binary_ops2;
+        }
+
+      case PE_DO_BINARY_OP:
+pe_do_binary_op:
+        PrsPush(ps,tmpc);
+        PrsPush(ps,stk_op);
+        if (!cur_op)
+          goto pe_pop_all1;
+
+        switch (cur_op.u16[0]) {
+          case IC_ADD:
+          case IC_SUB:
+            tmpi=cc->coc.coc_head.last;
+            if (!tmpi->ic_class->ptr_stars_cnt &&
+                  tmpi->ic_class->raw_type!=RT_F64) {
+              ICAdd(cc,IC_SIZEOF,1,cmp.internal_types[RT_I64]);
+              ICAdd(cc,IC_MUL,0,cmp.internal_types[RT_I64]);
+            }
+            break;
+          case IC_AND_AND:
+          case IC_OR_OR:
+            ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+            break;
+        }
+        if (cc->flags & CCF_FUN_EXP) {
+          ps->ptr2--;
+          cc->flags&=~CCF_FUN_EXP;
+        }
+        Lex(cc); //skip op
+        if (paren_prec>PREC_UNARY_PRE+ASSOC_MASK &&
+              paren_prec&~ASSOC_MASK<left_prec&~ASSOC_MASK+
+              paren_prec&ASSOCF_RIGHT &&
+              paren_prec&~ASSOC_MASK<cur_op.u8[2]&~ASSOC_MASK+
+              !(paren_prec&ASSOCF_RIGHT))
+          ParenWarning(cc);
+        if (cur_op.u8[2]>max_prec)
+          max_prec=cur_op.u8[2];
+        left_prec=cur_op.u8[2];
+        if (intermediate_code_table[cur_op.u16[0]].type==IST_ASSIGN) {
+          tmpi=cc->coc.coc_head.last;
+          tmpc=OptClassFwd(tmpi->ic_class);
+          if (intermediate_code_table[tmpi->ic_code].type!=IST_DEREF ||
+                !tmpc->ptr_stars_cnt && !Bt(&tmpc->flags,Cf_INTERNAL_TYPE))
+            LexExcept(cc,"Invalid lval at ");
+          tmpi->ic_code=IC_NOP1; //Important for setting class (pretty sure)
+          cur_op.u8[2]=PREC_ASSIGN|ASSOCF_RIGHT;
+        }
+
+      case PE_POP_HIGHER:
+pe_pop_higher:
+        stk_op=PrsPop(ps); //pop ops of higher prec
+        tmpc=PrsPop(ps);
+        if (!stk_op)
+          goto pe_push_lower;
+        else if (cur_op.u8[2]&~ASSOC_MASK==stk_op.u8[2]&~ASSOC_MASK) {
+          if (cur_op.u8[2]&ASSOCF_RIGHT)
+            goto pe_push_lower;
+        } else if (cur_op.u8[2]&~ASSOC_MASK<=stk_op.u8[2]&~ASSOC_MASK)
+          goto pe_push_lower;
+
+        tmpi=PrsAddOp(cc,stk_op,tmpc);
+
+        if (intermediate_code_table[cur_op.u16[0]].type==IST_CMP &&
+              intermediate_code_table[stk_op.u16[0]].type==IST_CMP) {
+          tmpi->ic_flags|=ICF_PUSH_CMP;
+          ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+          ICAdd(cc,IC_PUSH_CMP,0,tmpc);
+          cur_op.u8[3]|=ECF_HAS_PUSH_CMP;
+        } else if (cur_op.u16[0]==IC_AND_AND || cur_op.u16[0]==IC_OR_OR)
+          ICAdd(cc,IC_NOP1,0,cmp.internal_types[RT_I64]);
+        goto pe_pop_higher;
+
+      case PE_PUSH_LOWER:
+pe_push_lower:
+        PrsPush(ps,tmpc);
+        PrsPush(ps,stk_op);
+        PrsPush(ps,cc->coc.coc_head.last->ic_class);
+        PrsPush(ps,cur_op);
+        goto pe_unary_term1;
+
+      case PE_POP_ALL1:
+pe_pop_all1:
+        if (paren_prec>PREC_UNARY_PRE+ASSOC_MASK &&
+              paren_prec&~ASSOC_MASK<=left_prec&~ASSOC_MASK-
+              paren_prec&ASSOCF_LEFT-left_prec&ASSOCF_LEFT)
+          ParenWarning(cc);
+      case PE_POP_ALL2:
+pe_pop_all2:
+        stk_op=PrsPop(ps);
+        tmpc=PrsPop(ps);
+        if (!stk_op.u16[0])
+          goto pe_done;
+        PrsAddOp(cc,stk_op,tmpc);
+        goto pe_pop_all2;
+    }
+  }
+pe_done:
+  if (_max_prec)
+    *_max_prec=max_prec;
+}
+
+Bool PrsExpression(CCmpCtrl *cc,I64 *_max_prec,Bool end_exp,CPrsStk *_ps=NULL)
+{
+  Bool res=TRUE;
+  I64 old_flags=cc->flags;
+  CPrsStk *ps;
+  if (_ps)
+    ps=_ps;
+  else {
+    ps=MAlloc(sizeof(CPrsStk));
+    ps->ptr=0;
+    ps->ptr2=0;
+  }
+  PrsPush(ps,0); //terminate
+  PrsPush(ps,0); //terminate
+  try
+//try catch causes noreg vars in function
+          PrsExpression2(cc,_max_prec,ps);
+  catch {
+    if (Fs->except_ch=='Compiler') {
+      res=FALSE;
+      Fs->catch_except=TRUE;
+    }
+  }
+  if (!_ps) {
+    if (ps->ptr)
+      LexExcept(cc,"Compiler Parse Error at ");
+    Free(ps);
+  }
+  if (res) {
+    if (end_exp)
+      ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+    if (cc->coc.coc_head.last->ic_class==
+          cmp.internal_types[RT_U0])
+      LexWarn(cc,"U0 Expression ");
+  }
+  cc->flags|=old_flags&(CCF_PREINC|CCF_PREDEC);
+  return res;
+}
+
+U0 PrsSizeOf(CCmpCtrl *cc)
+{
+  CHashClass *tmpc;
+  CMemberLst *tmpm;
+  CDbgInfo *dbg_info;
+  I64 i;
+  if (cc->token!=TK_IDENT)
+    LexExcept(cc,"Invalid class at ");
+  if (tmpm=cc->local_var_entry) {
+    tmpc=tmpm->member_class;
+    i=tmpc->size*tmpm->dim.total_cnt;
+    if (Lex(cc)=='.')
+      goto pu_sizeof_member;
+  } else {
+    if (!(tmpc=cc->hash_entry) || !(tmpc->type &
+          (HTT_CLASS|HTT_INTERNAL_TYPE|HTT_GLBL_VAR|
+          HTT_FUN|HTT_EXPORT_SYS_SYM)))
+      LexExcept(cc,"Invalid class at ");
+    if (tmpc->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+      if (!(dbg_info=tmpc(CHashFun *)->dbg_info))
+        LexExcept(cc,"Size not defined at ");
+      i=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
+            -dbg_info->body[0];
+      Lex(cc);
+    } else {
+      i=tmpc->size;
+      while (Lex(cc)=='.') {
+pu_sizeof_member:
+        if (!(tmpc->type & (HTT_CLASS|HTT_GLBL_VAR)))
+          LexExcept(cc,"Invalid class at ");
+        else if (tmpc->type & HTT_GLBL_VAR)
+          tmpc=tmpc(CHashGlblVar *)->var_class;
+        if (Lex(cc)!=TK_IDENT || !(tmpm=MemberFind(cc->cur_str,tmpc)))
+          LexExcept(cc,"Invalid member at ");
+        else if (cc->local_var_entry)
+          cc->local_var_entry->use_cnt--;
+        tmpc=tmpm->member_class;
+//Probably others like this:
+        #assert offset(CHashClass.size)==offset(CHashGlblVar.size)
+        i=tmpc->size*tmpm->dim.total_cnt;
+      }
+    }
+  }
+  if (cc->token=='*') {
+    while (Lex(cc)=='*');
+    i=sizeof(U8 *);
+  }
+  ICAdd(cc,IC_IMM_I64,i,cmp.internal_types[RT_I64]);
+}
+
+U0 PrsOffsetOf(CCmpCtrl *cc)
+{
+  CHashClass *tmpc;
+  CMemberLst *tmpm;
+  I64 i;
+  if (cc->token!=TK_IDENT)
+    LexExcept(cc,"Invalid class at ");
+  if (tmpm=cc->local_var_entry)
+    tmpc=tmpm->member_class;
+  else {
+    tmpc=cc->hash_entry;
+    if (!tmpc || !(tmpc->type & (HTT_CLASS|HTT_GLBL_VAR)))
+      LexExcept(cc,"Invalid class at ");
+    else if (tmpc->type & HTT_GLBL_VAR)
+      tmpc=tmpc(CHashGlblVar *)->var_class;
+  }
+  if (Lex(cc)!='.')
+    LexExcept(cc,"Expecting '.' at ");
+  i=0;
+  do {
+    if (Lex(cc)!=TK_IDENT || !(tmpm=MemberFind(cc->cur_str,tmpc)))
+      LexExcept(cc,"Invalid member at ");
+    else if (cc->local_var_entry)
+      cc->local_var_entry->use_cnt--;
+    i+=tmpm->offset;
+    tmpc=tmpm->member_class;
+  } while (Lex(cc)=='.');
+  ICAdd(cc,IC_IMM_I64,i,cmp.internal_types[RT_I64]);
+}
+
+I64 PrsFunCall(CCmpCtrl *cc,CPrsStk *ps,Bool indirect,CHashFun *tmpf)
+{
+  I64 i,argc_cnt,dft_val;
+  Bool is_first_arg=TRUE,needs_right_paren,is_print,is_putchars,
+        is_template_fun;
+  CHashClass *tmpc2,*last_class=NULL;
+  CMemberLst *tmpm;
+  CCodeCtrl *tmpcbh,*tmpcbh1;
+  CCodeMisc *cm;
+  CIntermediateCode *tmpi;
+
+  if (!tmpf) {
+    if (cc->token==TK_CHAR_CONST) {
+      if (!(tmpf=HashFind("PutChars",cc->htc.hash_table_lst,HTT_FUN)))
+        LexExcept(cc,"Missing header for Print() and PutChars() at ");
+      if (!cc->cur_i64) //empty char signals PutChars with variable
+        Lex(cc);
+      is_print=FALSE;
+      is_putchars=TRUE;
+    } else {
+      if (!(tmpf=HashFind("Print",cc->htc.hash_table_lst,HTT_FUN)))
+        LexExcept(cc,"Missing header for Print() and PutChars() at ");
+      if (!*cc->cur_str) //empty string signals Print with variable fmt_str
+        Lex(cc);
+      is_putchars=FALSE;
+      is_print=TRUE;
+    }
+  } else {
+    is_print=FALSE;
+    is_putchars=FALSE;
+  }
+
+  if (Bt(&tmpf->flags,Ff_INTERNAL)&& IC_SQR<=tmpf->exe_addr<=IC_ATAN)
+    is_template_fun=TRUE;
+  else
+    is_template_fun=FALSE;
+
+  if (indirect) {
+    if (!(cc->flags & (CCF_RAX | CCF_ARRAY)))
+      ICAdd(cc,IC_DEREF,0,cmp.internal_types[RT_PTR]);
+    cc->coc.coc_head.last->ic_class=cmp.internal_types[RT_PTR];
+    ICAdd(cc,IC_SET_RAX,0,cmp.internal_types[RT_PTR]);
+    ICAdd(cc,IC_NOP2,1,cmp.internal_types[RT_PTR]); //balance the books
+  }
+  COCPush(cc);
+  tmpcbh=cc->coc.coc_next;
+  cc->coc.coc_next=NULL;
+  i=tmpf->arg_cnt;
+  tmpm=tmpf->member_lst_and_root;
+  argc_cnt=0;
+  if (cc->token=='(') {
+    Lex(cc);
+    needs_right_paren=TRUE;
+  } else
+    needs_right_paren=FALSE;
+  while (i--) {
+    COCInit(cc);
+    if (!is_first_arg) {
+      if (is_print) {
+        if (cc->token==',')
+          Lex(cc);
+        else if (cc->token!=';')
+          LexExcept(cc,"Expecting ',' at ");
+      } else {
+        if (needs_right_paren) {
+          if (cc->token==',')
+            Lex(cc);
+          else if (cc->token!=')')
+            LexExcept(cc,"Expecting ',' at ");
+        }
+      }
+    }
+    if (tmpm->flags & MLF_DFT_AVAILABLE &&
+          (cc->token==')' || cc->token==',' || !needs_right_paren)) {
+      dft_val=tmpm->dft_val;
+      if (tmpm->flags & MLF_LASTCLASS && last_class)
+        dft_val=(last_class-last_class->ptr_stars_cnt)->str;
+      if (tmpm->flags & (MLF_STR_DFT_AVAILABLE|MLF_LASTCLASS) &&
+            cc->flags&CCF_AOT_COMPILE) {
+        cm=COCMiscNew(cc,CMT_STR_CONST);
+        ICAdd(cc,IC_STR_CONST,cm,cmp.internal_types[RT_U8]+1);
+        cm->st_len=StrLen(dft_val)+1;
+        cm->str=StrNew(dft_val);
+        cc->flags|=CCF_HAS_MISC_DATA;
+      } else
+        ICAdd(cc,IC_IMM_I64,dft_val,tmpm->member_class);
+    } else {
+      if (!PrsExpression(cc,NULL,FALSE,ps))
+        throw('Compiler');
+      else {
+        COCPush(cc);
+        cc->pass=0;      OptPass012(cc);
+        cc->pass=1; tmpi=OptPass012(cc);
+        COCPop(cc);
+        last_class=OptClassFwd(tmpi->ic_class);
+        tmpc2=OptClassFwd(tmpm->member_class);
+        if (tmpc2->raw_type==RT_F64 && !tmpm->dim.next &&
+              last_class->raw_type!=RT_F64)
+          tmpi->ic_flags|=ICF_RES_TO_F64;
+        else
+          if (tmpc2->raw_type!=RT_F64 && last_class->raw_type==RT_F64)
+            tmpi->ic_flags|=ICF_RES_TO_INT;
+      }
+    }
+    COCPush(cc);
+    is_first_arg=FALSE;
+    tmpm=tmpm->next;
+  }
+  if (tmpm && tmpm->flags & MLF_DOT_DOT_DOT) {
+    COCInit(cc);
+    tmpi=ICAdd(cc,IC_IMM_I64,0,tmpm->member_class);
+    COCPush(cc);
+    if (is_print) {
+      if (cc->token!=';') {
+        do {
+          if (!is_first_arg) {
+            if (cc->token==',')
+              Lex(cc);
+            else
+              LexExcept(cc,"Expecting ',' at ");
+          }
+          COCInit(cc);
+          if (!PrsExpression(cc,NULL,FALSE,ps))
+            throw('Compiler');
+          COCPush(cc);
+          is_first_arg=FALSE;
+          argc_cnt++;
+        } while (cc->token==',');
+      }
+    } else if (needs_right_paren) {
+      if (cc->token!=')') {
+        do {
+          if (!is_first_arg) {
+            if (cc->token==',')
+              Lex(cc);
+            else
+              LexExcept(cc,"Expecting ',' at ");
+          }
+          COCInit(cc);
+          if (!PrsExpression(cc,NULL,FALSE,ps))
+            throw('Compiler');
+          COCPush(cc);
+          is_first_arg=FALSE;
+          argc_cnt++;
+        } while (cc->token==',');
+      }
+    }
+    tmpi->ic_data=argc_cnt++; //++ so add_esp latter works
+  }
+  if (needs_right_paren) {
+    if (cc->token==')')
+      Lex(cc);
+    else
+      LexExcept(cc,"Missing ')' at ");
+  }
+  tmpcbh1=tmpcbh->coc_next;
+  tmpcbh->coc_next=cc->coc.coc_next;
+  cc->coc.coc_next=tmpcbh;
+  COCPop(cc);
+  tmpcbh=cc->coc.coc_next;
+  cc->coc.coc_next=tmpcbh1;
+  if (!is_template_fun)
+    ICAdd(cc,IC_CALL_START,tmpf,0);
+  if (indirect)
+    ICAdd(cc,IC_PUSH_REGS,1<<REG_RAX,tmpf->return_class);
+  while (tmpcbh) {
+    tmpcbh1=tmpcbh->coc_next;
+    COCAppend(cc,tmpcbh);
+    if (!Bt(&tmpf->flags,Ff_INTERNAL))
+      cc->coc.coc_head.last->ic_flags|=ICF_PUSH_RES;
+    tmpcbh=tmpcbh1;
+  }
+  if (Bt(&tmpf->flags,Ff_INTERNAL))
+    ICAdd(cc,tmpf->exe_addr,0,tmpf->return_class);
+  else {
+    if (indirect)
+      ICAdd(cc,IC_CALL_INDIRECT,
+            (argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+    else if (Bt(&tmpf->flags,Cf_EXTERN)) {
+      cc->abs_cnts.externs++;
+      if (cc->flags&CCF_AOT_COMPILE) {
+        if (tmpf->type&HTF_IMPORT)
+          ICAdd(cc,IC_CALL_IMPORT,tmpf,tmpf->return_class);
+        else
+          ICAdd(cc,IC_CALL_EXTERN,tmpf,tmpf->return_class);
+      } else
+        ICAdd(cc,IC_CALL_INDIRECT2,&tmpf->exe_addr,tmpf->return_class);
+    } else
+      ICAdd(cc,IC_CALL,tmpf->exe_addr,tmpf->return_class);
+    if ((Bt(&tmpf->flags,Ff_RET1) || Bt(&tmpf->flags,Ff_ARGPOP)) &&
+          !Bt(&tmpf->flags,Ff_NOARGPOP)) {
+      if (indirect) {
+        ICAdd(cc,IC_ADD_RSP1,(argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+        ICAdd(cc,IC_ADD_RSP,8,tmpf->return_class);
+      } else
+        ICAdd(cc,IC_ADD_RSP1,(argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+    } else {
+      if (indirect)
+        argc_cnt++;
+      ICAdd(cc,IC_ADD_RSP,(argc_cnt+tmpf->arg_cnt)<<3,tmpf->return_class);
+    }
+  }
+  if (!is_template_fun)
+    ICAdd(cc,IC_CALL_END,tmpf,tmpf->return_class);
+  if (is_print||is_putchars)
+    ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+  cc->flags=(cc->flags|CCF_RAX) & ~(CCF_ARRAY|CCF_FUN_EXP);
+  return PE_UNARY_MODIFIERS;
+}
+
+I64 PrsUnaryTerm(CCmpCtrl *cc,CPrsStk *ps,CMemberLst **_local_var,
+        CArrayDim **_tmpad,I64 *max_prec,I64 *unary_pre_prec,I64 *paren_prec)
+{
+  I64 i,j;
+  CHashExport *tmpex;
+  CHashClass *tmpc;
+  CHashFun *tmpf;
+  CHashGlblVar *tmpg;
+  CMemberLst *tmpm;
+  CAsmUndefHash *tmpauh;
+  CCodeMisc *cm;
+  Bool paren_warn;
+
+  *_local_var=NULL;
+  *paren_prec=PREC_NULL;
+  switch (cc->token) {
+    start:
+      if (PREC_UNARY_PRE>*max_prec)
+        *max_prec=PREC_UNARY_PRE;
+      *unary_pre_prec=PREC_UNARY_PRE;
+      start:
+        case '~': i=IC_COM;             break;
+        case '!': i=IC_NOT;             break;
+        case '-': i=IC_UNARY_MINUS;     break;
+        case '*': i=IC_DEREF;           break;
+      end:
+        Lex(cc); //Skip op
+        break;
+      case '&':
+        if (Lex(cc)==TK_IDENT) {
+          if (tmpc=cc->hash_entry) {
+            if (tmpc->type & HTT_FUN) {
+              tmpf=tmpc;
+              if (!Bt(&tmpf->flags,Ff_INTERNAL)) {
+                if (Bt(&tmpf->flags,Cf_EXTERN)) {
+                  if (cc->flags&CCF_AOT_COMPILE) {
+                    if (cc->flags&CCF_ASM_EXPRESSIONS) {
+                      if (tmpex=HashFind(tmpf->str,cc->htc.hash_table_lst,
+                            HTT_EXPORT_SYS_SYM))
+                        goto pu_export_sys_sym;
+                      else
+                        goto pu_new_sys_sym;
+                    }
+                    LexExcept(cc,"Can't take addr of extern fun");
+                  }
+                  cc->abs_cnts.externs++;
+                  ICAdd(cc,IC_IMM_I64,
+                        &tmpf->exe_addr,cmp.internal_types[RT_PTR]);
+                  ICAdd(cc,IC_DEREF,0,cmp.internal_types[RT_PTR]);
+                } else {
+                  if (cc->flags&CCF_AOT_COMPILE) {
+                    ICAdd(cc,IC_ABS_ADDR,
+                          tmpf->exe_addr,cmp.internal_types[RT_PTR]);
+                    if (cc->flags&CCF_ASM_EXPRESSIONS)
+                      cc->abs_cnts.abs_addres++;
+                  } else
+                    ICAdd(cc,IC_IMM_I64,
+                          tmpf->exe_addr,cmp.internal_types[RT_PTR]);
+                }
+                cc->abs_cnts.c_addres++;
+                Lex(cc);
+                return PE_MAYBE_MODIFIERS;
+              }
+            } else if (tmpc->type & HTT_EXPORT_SYS_SYM) {
+              tmpex=tmpc;
+              if (cc->flags&CCF_ASM_EXPRESSIONS &&
+                    !(cc->flags&CCF_AOT_COMPILE) && tmpex->type&HTF_IMM) {
+                cc->abs_cnts.c_addres++;
+                ICAdd(cc,IC_IMM_I64,
+                      tmpex->val,cmp.internal_types[RT_PTR]);
+                Lex(cc);
+                return PE_MAYBE_MODIFIERS;
+              } else
+                goto pu_export_sys_sym;
+            }
+          } else if (cc->flags&CCF_ASM_EXPRESSIONS && !cc->local_var_entry)
+            goto pu_ident_but_not_local_var;
+        }
+        i=IC_ADDR;
+        break;
+    end:
+      PrsPush(ps,tmpc);
+      PrsPush(ps,PREC_UNARY_PRE<<16+i);
+      return PE_UNARY_TERM2;
+
+    start:
+      case TK_I64:
+      case TK_CHAR_CONST:
+      case TK_INS_BIN_SIZE:
+        if (cc->cur_i64<0)
+          ICAdd(cc,IC_IMM_I64,cc->cur_i64,cmp.internal_types[RT_U64]);
+        else
+          ICAdd(cc,IC_IMM_I64,cc->cur_i64,cmp.internal_types[RT_I64]);
+        Lex(cc);
+        break;
+      case TK_F64:
+        ICAdd(cc,IC_IMM_F64,cc->cur_f64(I64),cmp.internal_types[RT_F64]);
+        Lex(cc);
+        break;
+      case TK_STR:
+        cm=COCMiscNew(cc,CMT_STR_CONST);
+        ICAdd(cc,IC_STR_CONST,cm,cmp.internal_types[RT_U8]+1);
+        cm->str=LexExtStr(cc,&cm->st_len);
+        cc->flags|=CCF_HAS_MISC_DATA;
+        break;
+      case TK_INS_BIN:
+        cm=COCMiscNew(cc,CMT_STR_CONST);
+        ICAdd(cc,IC_STR_CONST,cm,cmp.internal_types[RT_U8]+1);
+        cm->str=cc->cur_str;
+        cm->st_len=cc->cur_str_len;
+        cc->cur_str=NULL;
+        cc->flags|=CCF_HAS_MISC_DATA;
+        Lex(cc);
+        break;
+      case '$':
+        if (cc->flags & CCF_ASM_EXPRESSIONS) {
+          cc->abs_cnts.abs_addres++;
+          if (cc->flags&CCF_AOT_COMPILE)
+            ICAdd(cc,IC_ABS_ADDR,cc->aotc->rip,cmp.internal_types[RT_PTR]);
+          else
+            ICAdd(cc,IC_IMM_I64,cc->aotc->rip,cmp.internal_types[RT_PTR]);
+        } else {
+          if (cc->flags&CCF_CLASS_DOL_OFFSET)
+            ICAdd(cc,IC_IMM_I64,cc->class_dol_offset,
+                  cmp.internal_types[RT_I64]);
+          else
+            ICAdd(cc,IC_RIP,0,cmp.internal_types[RT_PTR]);
+        }
+        Lex(cc);
+        break;
+    end:
+      if (PREC_TERM>*max_prec)
+        *max_prec=PREC_TERM;
+      return PE_MAYBE_MODIFIERS;
+
+    case '(':
+      if (Lex(cc)==TK_IDENT && cc->hash_entry &&
+            cc->hash_entry->type & (HTT_CLASS|HTT_INTERNAL_TYPE))
+        LexExcept(cc,"Use TempleOS postfix typecasting at ");
+      else {
+        if (PREC_TERM>*max_prec)
+          *max_prec=PREC_TERM;
+        if (cc->lex_include_stk->flags&LFSF_DEFINE)
+          paren_warn=FALSE;
+        else
+          paren_warn=TRUE;
+        if (!PrsExpression(cc,paren_prec,FALSE,ps))
+          throw('Compiler');
+        if (!paren_warn)
+          *paren_prec=PREC_NULL;
+        if (cc->token!=')')
+          LexExcept(cc,"Missing ')' at ");
+        Lex(cc); //skip )
+        cc->flags= cc->flags & ~CCF_ARRAY | CCF_RAX | CCF_PAREN;
+        return PE_UNARY_MODIFIERS;
+      }
+
+    start:
+      case '+':                                   break;
+      case TK_PLUS_PLUS:   cc->flags|=CCF_PREINC; break;
+      case TK_MINUS_MINUS: cc->flags|=CCF_PREDEC; break;
+    end:
+      if (PREC_UNARY_PRE>*max_prec)
+        *max_prec=PREC_UNARY_PRE;
+      *unary_pre_prec=PREC_UNARY_PRE;
+      Lex(cc);
+      return PE_UNARY_TERM2;
+
+    case TK_IDENT:
+      if (tmpm=cc->local_var_entry) {
+        if (PREC_TERM>*max_prec)
+          *max_prec=PREC_TERM;
+        cc->flags&=~(CCF_RAX|CCF_ARRAY|CCF_FUN_EXP);
+        tmpc=tmpm->member_class+1;
+        if (tmpm->flags & MLF_FUN && !(cc->flags&CCF_ASM_EXPRESSIONS)) {
+          PrsPopDeref(ps);
+          cc->flags|=CCF_FUN_EXP;
+          PrsPush2(ps,tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+        }
+        if (tmpm->dim.next) {
+          *_tmpad=tmpm->dim.next;
+          cc->flags|=CCF_ARRAY;
+        }
+        if (tmpm->flags&MLF_STATIC) {
+          if (cc->flags&CCF_AOT_COMPILE) {
+//      if (tmpg->flags&GVF_DATA_HEAP) //TODO
+            //    ICAdd(cc,IC_HEAP_GLBL,tmpm->static_data,tmpc);
+            //  else
+            ICAdd(cc,IC_ABS_ADDR,tmpm->static_data_rip,tmpc);
+          } else
+            ICAdd(cc,IC_IMM_I64,tmpm->static_data,tmpc);
+        } else {
+          if (cc->flags&CCF_ASM_EXPRESSIONS) {
+            i=PrsPop(ps);
+            ps->ptr--;
+            if (i.u16[0]!=IC_ADDR)
+              LexExcept(cc,"Expecting '&' at ");
+            ICAdd(cc,IC_IMM_I64,tmpm->offset,cmp.internal_types[RT_PTR]);
+            *_local_var=tmpm;
+            Lex(cc);
+            return PE_MAYBE_MODIFIERS;
+          } else {
+            if (tmpm->dim.next && tmpm->offset>0 &&
+                  StrCmp(tmpm->str,"argv")) {
+              tmpc++;
+              cc->flags&=~CCF_ARRAY;
+            }
+            ICAdd(cc,IC_RBP,0,tmpc);
+            ICAdd(cc,IC_IMM_I64,tmpm->offset,tmpc);
+            ICAdd(cc,IC_ADD,0,tmpc);
+          }
+        }
+        Lex(cc); //skip var name
+        *_local_var=tmpm;
+        return PE_UNARY_MODIFIERS;
+      }
+pu_ident_but_not_local_var:
+      if (!(tmpex=cc->hash_entry)) {
+        if (!(cc->flags & CCF_ASM_EXPRESSIONS))
+          LexExcept(cc,"Invalid lval at ");
+        tmpc=NULL;
+pu_new_sys_sym:
+        tmpex=CAlloc(sizeof(CHashExport),Fs->code_heap);
+        tmpex->str=cc->cur_str;
+        cc->cur_str=NULL;
+        if (!cc->htc.local_var_lst &&
+              *tmpex->str=='@' && tmpex->str[1]=='@') {
+          tmpex->type=HTT_EXPORT_SYS_SYM | HTF_UNRESOLVED | HTF_LOCAL;
+          HashAdd(tmpex,cc->htc.local_hash_table);
+        } else {
+          tmpex->type=HTT_EXPORT_SYS_SYM | HTF_UNRESOLVED;
+          if (tmpc)
+            HashAddAfter(tmpex,tmpc,cc->htc.glbl_hash_table);
+          else
+            HashAdd(tmpex,cc->htc.glbl_hash_table);
+        }
+      }
+      switch (Bsf(tmpex->type)) {
+        case HTt_EXPORT_SYS_SYM:
+pu_export_sys_sym:
+          if (PREC_TERM>*max_prec)
+            *max_prec=PREC_TERM;
+          if (!(tmpex->type & (HTF_IMM|HTF_IMPORT)))
+            cc->abs_cnts.abs_addres++;
+          if (tmpex->type & HTF_UNRESOLVED) {
+            if (!(cc->flags&CCF_ASM_EXPRESSIONS))
+              LexExcept(cc,"Illegal fwd ref at ");
+            tmpauh=MAlloc(sizeof(CAsmUndefHash));
+            tmpauh->hash=tmpex;
+            tmpauh->next=cc->asm_undef_hash;
+            cc->asm_undef_hash=tmpauh;
+            if (tmpex->type & HTF_LOCAL)
+              cc->flags|=CCF_UNRESOLVED|CCF_LOCAL;
+            else
+              cc->flags|=CCF_UNRESOLVED;
+            ICAdd(cc,IC_IMM_I64,
+                  &tmpex->val,cmp.internal_types[RT_PTR],ICF_NO_RIP);
+            ICAdd(cc,IC_DEREF,0,cmp.internal_types[RT_PTR]);
+          } else {
+            if (cc->flags&CCF_AOT_COMPILE && !(tmpex->type & HTF_IMM))
+              ICAdd(cc,IC_ABS_ADDR,tmpex->val,cmp.internal_types[RT_PTR]);
+            else {
+              if (tmpex->type&HTF_IMM)
+                cc->abs_cnts.c_addres++;
+              ICAdd(cc,IC_IMM_I64,tmpex->val,cmp.internal_types[RT_PTR]);
+            }
+          }
+          Lex(cc);
+          return PE_MAYBE_MODIFIERS;
+        case HTt_FUN:
+          if (PREC_TERM>*max_prec)
+            *max_prec=PREC_TERM;
+          Lex(cc);  //skip fun name
+          return PrsFunCall(cc,ps,FALSE,tmpex);
+        case HTt_GLBL_VAR:
+          if (PREC_TERM>*max_prec)
+            *max_prec=PREC_TERM;
+          tmpg=tmpex;
+          tmpc=tmpg->var_class+1;
+          cc->flags&=~(CCF_RAX|CCF_ARRAY|CCF_FUN_EXP);
+          if (tmpg->flags&GVF_ARRAY) {
+            *_tmpad=tmpg->dim.next;
+            cc->flags|=CCF_ARRAY;
+          }
+          if (cc->flags&CCF_AOT_COMPILE) {
+            if (tmpg->flags & GVF_EXTERN) //TODO
+              LexExcept(cc,"Feature not implemented ");
+            else {
+              if (tmpg->flags & GVF_IMPORT)
+                ICAdd(cc,IC_ADDR_IMPORT,tmpg,tmpc);
+              else {
+                if (tmpg->flags&GVF_DATA_HEAP)
+                  ICAdd(cc,IC_HEAP_GLBL,tmpg->heap_glbl,tmpc);
+                else
+                  ICAdd(cc,IC_ABS_ADDR,tmpg->data_addr_rip,tmpc);
+              }
+            }
+          } else {
+            if (tmpg->flags & GVF_EXTERN) {
+              cc->abs_cnts.externs++;
+              ICAdd(cc,IC_IMM_I64,&tmpg->data_addr,tmpc);
+              ICAdd(cc,IC_DEREF,0,tmpc);
+            } else
+              ICAdd(cc,IC_IMM_I64,tmpg->data_addr,tmpc);
+          }
+          Lex(cc);
+          if (tmpg->flags & GVF_FUN) {
+            PrsPopDeref(ps);
+            cc->flags|=CCF_FUN_EXP;
+            PrsPush2(ps,tmpg->fun_ptr-tmpg->fun_ptr->ptr_stars_cnt);
+          }
+          return PE_UNARY_MODIFIERS;
+        case HTt_CLASS:
+          PrsOffsetOf(cc);
+          return PE_MAYBE_MODIFIERS;
+        case HTt_KEYWORD:
+          switch (tmpex(CHashGeneric *)->user_data0) {
+            case KW_SIZEOF:
+              if (PREC_TERM>*max_prec)
+                *max_prec=PREC_TERM;
+              j=0;
+              while (Lex(cc)=='(')
+                j++;
+              PrsSizeOf(cc);
+              while (j--) {
+                if (cc->token!=')')
+                  LexExcept(cc,"Missing ')' at ");
+                Lex(cc);
+              }
+              return PE_MAYBE_MODIFIERS;
+            case KW_OFFSET:
+              if (PREC_TERM>*max_prec)
+                *max_prec=PREC_TERM;
+              j=0;
+              while (Lex(cc)=='(')
+                j++;
+              PrsOffsetOf(cc);
+              while (j--) {
+                if (cc->token!=')')
+                  LexExcept(cc,"Missing ')' at ");
+                Lex(cc);
+              }
+              return PE_MAYBE_MODIFIERS;
+            case KW_DEFINED:
+              if (PREC_TERM>*max_prec)
+                *max_prec=PREC_TERM;
+              j=0;
+              while (Lex(cc)=='(')
+                j++;
+              if (cc->token==TK_IDENT &&
+                    (cc->hash_entry || cc->local_var_entry))
+                ICAdd(cc,IC_IMM_I64,TRUE,cmp.internal_types[RT_I64]);
+              else
+                ICAdd(cc,IC_IMM_I64,FALSE,cmp.internal_types[RT_I64]);
+              Lex(cc);
+              while (j--) {
+                if (cc->token!=')')
+                  LexExcept(cc,"Missing ')' at ");
+                Lex(cc);
+              }
+              return PE_MAYBE_MODIFIERS;
+          }
+      }
+  }
+  LexExcept(cc,"Missing expression at ");
+}
+
+I64 PrsUnaryModifier(CCmpCtrl *cc,CPrsStk *ps,CMemberLst **_local_var,
+        CArrayDim **_tmpad,I64 *unary_post_prec)
+{
+  CHashClass *tmpc,*tmpc1;
+  CHashFun *fun_ptr;
+  CMemberLst *tmpm=*_local_var;
+  CIntermediateCode *tmpi,*tmpi1;
+  CArrayDim *tmpad1,tmpad2;
+  CCodeMisc *cm;
+  I64 mode,old_flags;
+  Bool was_paren=Btr(&cc->flags,CCf_PAREN);
+
+  *_local_var=NULL;
+  switch (cc->token) {
+    case '.':
+      if (tmpm)
+        tmpm->reg=REG_NONE;
+      goto um_join;
+
+    case TK_DEREFERENCE:
+      tmpi=cc->coc.coc_head.last;
+      if (!(cc->flags & (CCF_RAX | CCF_ARRAY)))
+        ICAdd(cc,IC_DEREF+PREC_UNARY_PRE<<16,0,tmpi->ic_class-1);
+      else
+        tmpi->ic_class--;
+
+        um_join:
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_TERM;
+      tmpc=cc->coc.coc_head.last->ic_class;
+      if ((!tmpc->ptr_stars_cnt || cc->flags & CCF_ARRAY) && cc->token=='.')
+        LexExcept(cc,"Must be address, not value ");
+      if (!(cc->flags & CCF_RAX))
+        tmpc--;
+      if (!(tmpc->type & HTT_CLASS))
+        LexExcept(cc,"Invalid class at ");
+      if (Lex(cc)!=TK_IDENT ||
+            !(tmpm=MemberFind(cc->cur_str,tmpc)))
+        LexExcept(cc,"Invalid member at ");
+      else if (cc->local_var_entry)
+        cc->local_var_entry->use_cnt--;
+      Lex(cc);  //skip member name
+      tmpc1=tmpm->member_class+1;
+      ICAdd(cc,IC_IMM_I64,tmpm->offset,tmpc1);
+      cc->flags&=~(CCF_RAX|CCF_ARRAY|CCF_FUN_EXP);
+      if (tmpm->dim.next) {
+        *_tmpad=tmpm->dim.next;
+        cc->flags|=CCF_ARRAY;
+      }
+      if(tmpm->flags & MLF_FUN) {
+        PrsPopDeref(ps);
+        PrsPush2(ps,tmpm->fun_ptr-tmpm->fun_ptr->ptr_stars_cnt);
+        cc->flags|=CCF_FUN_EXP;
+      }
+      ICAdd(cc,IC_ADD,0,tmpc1);
+      return PE_UNARY_MODIFIERS;
+    case '(':
+      if (cc->flags & CCF_FUN_EXP) {
+        if (!*unary_post_prec)
+          *unary_post_prec=PREC_TERM;
+        return PrsFunCall(cc,ps,TRUE,PrsPop2(ps));
+      }
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_TERM;
+      if (Lex(cc)!=TK_IDENT)
+        LexExcept(cc,"Invalid class at ");
+      if (Btr(&cc->flags,CCf_FUN_EXP))
+        ps->ptr2--;
+      cc->flags&=~CCF_ARRAY;
+      tmpc=cc->hash_entry;
+      Lex(cc);
+      mode=PRS0_TYPECAST|PRS1_NULL;
+      tmpc=PrsType(cc,&tmpc,&mode,NULL,NULL,&fun_ptr,NULL,&tmpad2,0);
+      if (fun_ptr) {
+        PrsPopDeref(ps);
+        Bts(&cc->flags,CCf_FUN_EXP);
+        PrsPush2(ps,fun_ptr);
+        cm=COCMiscNew(cc,CMT_HASH_ENTRY);
+        cm->h=fun_ptr;
+      }
+      if (*_tmpad=tmpad2.next) {
+        cc->flags|=CCF_ARRAY;
+        tmpc++;
+        cm=COCMiscNew(cc,CMT_ARRAY_DIM);
+        cm->dim=*_tmpad;
+      }
+      if (!(cc->flags&(CCF_RAX|CCF_ARRAY)))
+        tmpc++;
+      tmpi=cc->coc.coc_head.last;
+      tmpi->ic_class=tmpc;
+      ICAdd(cc,IC_HOLYC_TYPECAST,was_paren,tmpc);
+      if (cc->token!=')')
+        LexExcept(cc,"Missing ')' at ");
+      Lex(cc);
+      return PE_UNARY_MODIFIERS;
+    case '[':
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_TERM;
+      Lex(cc);
+      tmpc=OptClassFwd(cc->coc.coc_head.last->ic_class);
+      if (!tmpc->ptr_stars_cnt)
+        LexExcept(cc,"Not array or ptr ");
+      if (!(cc->flags & (CCF_ARRAY | CCF_RAX))) {
+        tmpc=OptClassFwd(tmpc-1);
+        if (!tmpc->ptr_stars_cnt)
+          LexExcept(cc,"Not array or ptr ");
+        ICAdd(cc,IC_DEREF+PREC_UNARY_PRE<<16,0,tmpc);
+      }
+      tmpc1=tmpc-1;
+      if (tmpad1=*_tmpad) {
+        ICAdd(cc,IC_IMM_I64,tmpad1->total_cnt*tmpc1->size,tmpc);
+        if (*_tmpad=tmpad1->next) {
+          old_flags=cc->flags;
+          if (!PrsExpression(cc,NULL,FALSE,ps))
+            throw('Compiler');
+          cc->flags=cc->flags&~CCF_FUN_EXP|old_flags&CCF_FUN_EXP;
+          if (cc->token!=']')
+            LexExcept(cc,"Missing ']' at ");
+          Lex(cc); //skip ]
+          tmpi1=cc->coc.coc_head.last;
+          tmpi1->ic_flags|=ICF_RES_TO_INT;
+          ICAdd(cc,IC_MUL,0,tmpc);
+          ICAdd(cc,IC_ADD,0,tmpc);
+          cc->flags|=CCF_RAX;
+          return PE_UNARY_MODIFIERS;
+        }
+      } else
+        ICAdd(cc,IC_IMM_I64,tmpc1->size,tmpc);
+      old_flags=cc->flags;
+      if (!PrsExpression(cc,NULL,FALSE,ps))
+        throw('Compiler');
+      cc->flags=cc->flags&~CCF_FUN_EXP|old_flags&CCF_FUN_EXP;
+      if (cc->token!=']')
+        LexExcept(cc,"Missing ']' at ");
+      Lex(cc); //skip ]
+      tmpi1=cc->coc.coc_head.last;
+      tmpi1->ic_flags|=ICF_RES_TO_INT;
+      ICAdd(cc,IC_MUL,0,tmpc);
+      ICAdd(cc,IC_ADD,0,tmpc);
+      cc->flags&=~(CCF_RAX|CCF_ARRAY);
+      return PE_UNARY_MODIFIERS;
+    start:
+      case TK_PLUS_PLUS:
+        cc->flags|=CCF_POSTINC;
+        break;
+      case TK_MINUS_MINUS:
+        cc->flags|=CCF_POSTDEC;
+        break;
+    end:
+      if (!*unary_post_prec)
+        *unary_post_prec=PREC_UNARY_POST;
+      Lex(cc);
+      return PE_DEREFERENCE;
+  }
+  return PE_DEREFERENCE;
+}
+
+U8 *LexExpression2Bin(CCmpCtrl *cc,I64 *_type=NULL)
+{//Compile cc expression. You call the code.
+  U8 *res;
+  I64 size;
+  Bool old_trace=Btr(&cc->flags,CCf_PASS_TRACE_PRESENT);
+  COCPush(cc);
+  COCInit(cc);
+  if (PrsExpression(cc,NULL,FALSE)) {
+    ICAdd(cc,IC_RETURN_VAL,0,0);
+    ICAdd(cc,IC_RET,0,0);
+    res=COCCompile(cc,&size,NULL,_type);
+  } else
+    res=NULL;
+  COCPop(cc);
+  BEqu(&cc->flags,CCf_PASS_TRACE_PRESENT,old_trace);
+  return res;
+}
+
+Bool IsLexExpression2Bin(CCmpCtrl *cc,U8 **_machine_code)
+{//Compile cc expression to bin. Return err status.
+  return ToBool(*_machine_code=LexExpression2Bin(cc));
+}
+
+I64 LexExpressionI64(CCmpCtrl *cc)
+{//Compile cc expression, forcing to I64 and eval.
+  U8 *machine_code;
+  I64 res,type;
+  if (machine_code=LexExpression2Bin(cc,&type)) {
+    res=Call(machine_code);
+    Free(machine_code);
+    if (type==RT_F64)
+      res=ToI64(res(F64));
+  } else
+    res=0;
+  return res;
+}
+
+F64 LexExpressionF64(CCmpCtrl *cc)
+{//Compile cc expression, forcing to F64 and eval.
+  U8 *machine_code;
+  I64 res,type;
+  if (machine_code=LexExpression2Bin(cc,&type)) {
+    res=Call(machine_code);
+    Free(machine_code);
+    if (type!=RT_F64)
+      res(F64)=ToF64(res);
+  } else
+    res=0;
+  return res(F64);
+}
+
+I64 LexExpression(CCmpCtrl *cc)
+{//Compile cc expression and eval.  Might be I64 or F64.
+  U8 *machine_code;
+  I64 res;
+  if (machine_code=LexExpression2Bin(cc)) {
+    res=Call(machine_code);
+    Free(machine_code);
+  } else
+    res=0;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/PrsLib.HC.HTML b/public/Wb/Home/Src/Compiler/PrsLib.HC.HTML new file mode 100755 index 0000000..4a220ad --- /dev/null +++ b/public/Wb/Home/Src/Compiler/PrsLib.HC.HTML @@ -0,0 +1,354 @@ + + + + + + + + + + + +
+U0 PrsPush(CPrsStk *ps,I64 val)
+{
+  ps->stk[++ps->ptr]=val;
+}
+
+I64 PrsPop(CPrsStk *ps)
+{
+  return ps->stk[ps->ptr--];
+}
+
+U0 PrsPush2(CPrsStk *ps,I64 val)
+{
+  ps->stk2[++ps->ptr2]=val;
+}
+
+I64 PrsPop2(CPrsStk *ps)
+{
+  return ps->stk2[ps->ptr2--];
+}
+
+U0 PrsPopDeref(CPrsStk *ps)
+{
+  I64 i=PrsPop(ps);
+  CHashClass *tmpc=PrsPop(ps);
+  if (i.u16[0]!=IC_DEREF) {
+    PrsPush(ps,tmpc);
+    PrsPush(ps,i);
+  }
+}
+
+I64 PrsKeyWord(CCmpCtrl *cc)
+{//Cvt cur token to KEYWORD or -1.
+  CHashGeneric *tmph;
+  if (cc->token==TK_IDENT &&(tmph=cc->hash_entry) && tmph->type&HTT_KEYWORD)
+    return tmph->user_data0;
+  else
+    return -1;
+}
+
+CHashClass *PrsClassNew()
+{/*Ptrs to classes are handled by
+allocating 5 structures for each
+new class and representing a pointer
+to a class by advancing 1 struct fwd
+for one * and two fwd for two **.
+*/
+  I64 i;
+  CHashClass *res=CAlloc(sizeof(CHashClass)*(PTR_STARS_NUM+1),Fs->code_heap),
+        *tmpc=res;
+  for (i=0;i<=PTR_STARS_NUM;i++) {
+    tmpc->type=HTT_CLASS;
+    tmpc->raw_type=RT_PTR;
+    tmpc->size=sizeof(U8 *);
+    tmpc->ptr_stars_cnt=i;
+    tmpc++;
+  }
+  res->last_in_member_lst=&res->member_lst_and_root;
+  res->size=0;
+  return res;
+}
+
+CHashFun *PrsFunNew()
+{
+  I64 i;
+  CHashFun *res=CAlloc(sizeof(CHashFun)*(PTR_STARS_NUM+1),Fs->code_heap),
+        *tmpf=res;
+  for (i=0;i<=PTR_STARS_NUM;i++) {
+    tmpf->type=HTT_FUN;
+    tmpf->raw_type=RT_PTR;
+    tmpf->size=sizeof(U8 *);
+    tmpf->ptr_stars_cnt=i;
+    tmpf++;
+  }
+  res->last_in_member_lst=&res->member_lst_and_root;
+  res->size=0;
+  return res;
+}
+
+CIntermediateCode *ICAdd(CCmpCtrl *cc,
+   I64 opcode_and_precedence,I64 arg, CHashClass *c,I64 flags=0)
+{
+  CIntermediateCode *tmpi=MAlloc(sizeof(CIntermediateCode));
+  tmpi->ic_code=opcode_and_precedence.u16[0];
+  tmpi->ic_precedence=opcode_and_precedence.u16[1];
+  tmpi->ic_data=arg;
+  tmpi->ic_class=c;
+  if (cc->pass_trace) {
+    Bts(&cc->flags,CCf_PASS_TRACE_PRESENT);
+    flags|=ICF_PASS_TRACE;
+  }
+  if (cc->lock_cnt)
+    flags|=ICF_LOCK;
+  tmpi->ic_flags=flags;
+  tmpi->ic_line=cc->last_line_num;
+  QueIns(tmpi,cc->coc.coc_head.last);
+  return tmpi;
+}
+
+U0 COCInit(CCmpCtrl *cc)
+{
+  CCodeCtrl *tmpcbh=&cc->coc;
+  QueInit(&tmpcbh->coc_head.next);
+  QueInit(&tmpcbh->coc_next_misc);
+  tmpcbh->coc_head.ic_code=IC_END;
+}
+
+U0 COCPush(CCmpCtrl *cc)
+{
+  CCodeCtrl *tmpcbh=MAlloc(sizeof(CCodeCtrl));
+  MemCpy(tmpcbh,&cc->coc,sizeof(CCodeCtrl));
+  cc->coc.coc_next=tmpcbh;
+}
+
+CCmpCtrl *COCPopNoFree(CCmpCtrl *cc)
+{
+  CCodeCtrl *tmpcbh=cc->coc.coc_next;
+  MemCpy(&cc->coc,tmpcbh,sizeof(CCodeCtrl));
+  return tmpcbh;
+}
+
+U0 COCPop(CCmpCtrl *cc)
+{
+  Free(COCPopNoFree(cc));
+}
+
+U0 COCAppend(CCmpCtrl *cc, CCodeCtrl *tmpcbh)
+{
+  if (tmpcbh->coc_head.next!=&cc->coc.coc_head.next) {
+    cc->coc.coc_head.last->next=tmpcbh->coc_head.next;
+    tmpcbh->coc_head.next->last=cc->coc.coc_head.last;
+    cc->coc.coc_head.last=tmpcbh->coc_head.last;
+    tmpcbh->coc_head.last->next=&cc->coc.coc_head.next;
+  }
+  if (tmpcbh->coc_next_misc!=&cc->coc.coc_next_misc) {
+    cc->coc.coc_last_misc->next=tmpcbh->coc_next_misc;
+    tmpcbh->coc_next_misc->last=cc->coc.coc_last_misc;
+    cc->coc.coc_last_misc=tmpcbh->coc_last_misc;
+    tmpcbh->coc_last_misc->next=&cc->coc.coc_next_misc;
+  }
+  Free(tmpcbh);
+}
+
+CCodeMisc *COCMiscNew(CCmpCtrl *cc,I64 ty)
+{
+  CCodeMisc *res=CAlloc(sizeof(CCodeMisc));
+  res->addr=INVALID_PTR;
+  res->type=ty;
+  QueIns(res,cc->coc.coc_last_misc);
+  return res;
+}
+
+CCodeMisc *COCGoToLabelFind(CCmpCtrl *cc,U8 *name)
+{
+  CCodeMisc *cm=cc->coc.coc_next_misc;
+  while (cm!=&cc->coc.coc_next_misc) {
+    if ((cm->type==CMT_GOTO_LABEL||cm->type==CMT_ASM_LABEL) &&
+          !StrCmp(cm->str,name))
+      return cm;
+    cm=cm->next;
+  }
+  return NULL;
+}
+
+I64 COCFloatConstFind(CCmpCtrl *cc,F64 d)
+{
+  I64 i;
+  CCodeMisc *cm=cc->coc.coc_next_misc;
+  while (cm!=&cc->coc.coc_next_misc) {
+    if (cm->type==CMT_FLOAT_CONSTS) {
+      for (i=0;i<cm->num_consts;i++)
+        if (cm->float_consts[i]==d)
+          return cm->addr+i*sizeof(F64);
+      if (cm->num_consts<CM_CONSTS_NUM)  {
+        cm->float_consts[cm->num_consts++]=d;
+        return cm->addr+i*sizeof(F64);
+      }
+    }
+    cm=cm->next;
+  }
+  cm=COCMiscNew(cc,CMT_FLOAT_CONSTS);
+  cm->float_consts=MAlloc(CM_CONSTS_NUM*sizeof(F64));
+  cm->float_consts[cm->num_consts++]=d;
+  return cm->addr;
+}
+
+U0 COCDel(CCmpCtrl *cc,CCodeCtrl *coc)
+{
+  CCodeMisc *cm,*cm1;
+  U8 *undef=NULL;
+  QueDel(&coc->coc_head.next);
+  cm=coc->coc_next_misc;
+  while (cm!=&coc->coc_next_misc) {
+    cm1=cm->next;
+    switch (cm->type) {
+      case CMT_GOTO_LABEL:
+      case CMT_ASM_LABEL:
+        if (!(cm->flags&CMF_DEFINED)) {
+          undef=cm->str;
+          cm->str=NULL;
+        } else if (!cm->use_cnt) {
+          PrintWarn("Unused label %s\n",cm->str);
+          LexWarn(cc,"Unused label at ");
+        }
+        break;
+      case CMT_JMP_TABLE:
+        Free(cm->jmp_table);
+        break;
+      case CMT_FLOAT_CONSTS:
+        Free(cm->float_consts);
+        break;
+      case CMT_ARRAY_DIM:
+        LinkedLstDel(cm->dim);
+        break;
+      case CMT_HASH_ENTRY:
+        HashDel(cm->h);
+        break;
+    }
+    Free(cm->str);
+    Free(cm);
+    cm=cm1;
+  }
+  if (undef) {
+    PrintErr("Undefined goto label %s\n",undef);
+    Free(undef);
+    LexExcept(cc,"Undefined goto label at ");
+  }
+}
+
+U0 COCHeaderPut(CCmpCtrl *cc,I64 pass,Bool put)
+{
+  CIntermediateCode *tmpi;
+  if (Bt(&cc->flags,CCf_PASS_TRACE_PRESENT)) {
+    if (put) {
+      if (Bt(&cc->saved_pass_trace,pass-1)) {
+        "$IV,1$Pass %d:$IV,0$\n",pass-1;
+        tmpi=cc->coc.coc_head.next;
+        while (tmpi->ic_code) {
+          if (tmpi->ic_flags&ICF_PASS_TRACE)
+            ICPut(cc,tmpi);
+          tmpi=tmpi->next;
+        }
+      }
+    } else if (Bt(&cc->saved_pass_trace,pass))
+      "$IV,1$Pass %d:$IV,0$\n",pass;
+  }
+  cc->pass=pass;
+}
+
+U8 *COCCompile(CCmpCtrl *cc,I64 *_code_size,CDbgInfo **_dbg,I64 *_type)
+{
+  U8 *res;
+  CCodeMisc *lb;
+  I64 i,code_size,last_code_size;
+
+  COptReg reg_offsets[REG_REGS_NUM];
+  if (_dbg) *_dbg=NULL;
+  cc->pass=0;
+  COCHeaderPut(cc,1,TRUE);
+  OptPass012(cc);
+  COCHeaderPut(cc,2,TRUE);
+  OptPass012(cc);
+  COCHeaderPut(cc,3,TRUE);
+  OptPass3(cc,reg_offsets);
+  COCHeaderPut(cc,4,TRUE);
+  OptPass4(cc,reg_offsets,_type);
+  COCHeaderPut(cc,5,TRUE);
+  OptPass5(cc);
+  COCHeaderPut(cc,6,TRUE);
+  OptPass6(cc);
+  COCHeaderPut(cc,7,TRUE);
+
+  lb=cc->coc.coc_next_misc;
+  while (lb!=&cc->coc.coc_next_misc) {
+    if (lb->type==CMT_JMP_TABLE) {
+      for (i=0;i<lb->range;i++)
+        lb->jmp_table[i]=OptLabelFwd(lb->jmp_table[i]);
+      lb->dft=OptLabelFwd(lb->dft);
+    }
+    lb=lb->next;
+  }
+
+  COCHeaderPut(cc,7,FALSE);
+  OptPass789A(cc,reg_offsets,NULL,NULL);
+  COCHeaderPut(cc,8,FALSE);
+  OptPass789A(cc,reg_offsets,NULL,NULL);
+  COCHeaderPut(cc,9,FALSE);
+  code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
+  do {
+    last_code_size=code_size;
+    COCHeaderPut(cc,9,FALSE);
+    code_size=OptPass789A(cc,reg_offsets,NULL,NULL);
+    if (code_size>last_code_size) {
+      "Pass:9 Code Size\n";
+      LexExcept(cc,"Compiler Optimization Error at ");
+    }
+  } while (code_size<last_code_size);
+
+  if (cc->flags&CCF_AOT_COMPILE)
+    res=MAlloc(code_size);
+  else {
+    res=MAlloc(code_size,Fs->code_heap);
+    if (cc->htc.fun)
+      Fs->last_fun=cc->htc.fun;
+  }
+  COCHeaderPut(cc,10,FALSE);
+  code_size=OptPass789A(cc,reg_offsets,res,_dbg);
+
+  COCDel(cc,&cc->coc);
+  if (Bt(&cc->opts,OPTf_TRACE)) {
+    if (cc->flags&CCF_AOT_COMPILE) {
+      if (cc->aotc->seg_size==16)
+        Un(res,code_size,16);
+      else if (cc->aotc->seg_size==64)
+        Un(res,code_size,64);
+      else
+        Un(res,code_size,32);
+    } else
+      Un(res,code_size,64);
+  }
+  if (_code_size) *_code_size=code_size;
+  cc->saved_pass_trace=cc->pass_trace;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/PrsStmt.HC.HTML b/public/Wb/Home/Src/Compiler/PrsStmt.HC.HTML new file mode 100755 index 0000000..f8c3012 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/PrsStmt.HC.HTML @@ -0,0 +1,1253 @@ + + + + + + + + + + + +
+CHashClass *PrsClass(CCmpCtrl *cc,I64 keyword,I64 fsp_flags,Bool is_extern)
+{
+  CHashClass *tmpc,*base_class;
+  if (cc->token!=TK_IDENT)
+    LexExcept(cc,"Expecting identifier at ");
+  if (is_extern) {
+    tmpc=PrsClassNew;
+    tmpc->str=cc->cur_str;
+    cc->cur_str=NULL;
+    HashAdd(tmpc,cc->htc.glbl_hash_table);
+    LBts(&tmpc->flags,Cf_EXTERN);
+    HashSrcFileSet(cc,tmpc);
+    Lex(cc);
+  } else {
+    if (cc->flags&CCF_AOT_COMPILE)
+      tmpc=HashFind(cc->cur_str,cc->htc.glbl_hash_table,HTT_CLASS);
+    else
+      tmpc=HashSingleTableFind(cc->cur_str,cc->htc.glbl_hash_table,HTT_CLASS);
+    if (tmpc) {
+      if (!Bt(&tmpc->flags,Cf_EXTERN))
+        tmpc=NULL;
+      else if (tmpc->use_cnt<3)
+        UnusedExternWarning(cc,tmpc);
+    }
+    if (tmpc) {
+      Free(tmpc->src_link);
+      tmpc->src_link=NULL;
+      Free(tmpc->idx);
+      tmpc->idx=NULL;
+    } else {
+      tmpc=PrsClassNew;
+      tmpc->str=cc->cur_str;
+      cc->cur_str=NULL;
+      HashAdd(tmpc,cc->htc.glbl_hash_table);
+    }
+    LBtr(&tmpc->flags,Cf_EXTERN);
+    if (fsp_flags&FSF_PUBLIC)
+      tmpc->type|=HTF_PUBLIC;
+    tmpc->use_cnt=0;
+    if (cc->last_U16=='\n')
+      HashSrcFileSet(cc,tmpc,-1);
+    else
+      HashSrcFileSet(cc,tmpc,0);
+    if (Lex(cc)==':') {
+      if (Lex(cc)!=TK_IDENT || !(base_class=cc->hash_entry) ||
+            !(base_class->type&HTT_CLASS))
+        LexExcept(cc,"Invalid class at ");
+      if (Lex(cc)==',')
+        LexExcept(cc,"Only one base class allowed at this time at ");
+      tmpc->base_class=base_class;
+      tmpc->size+=base_class->size;
+    }
+    if (keyword==KW_UNION)
+      PrsVarLst(cc,tmpc,PRS0_NULL|PRS1_CLASS|PRSF_UNION);
+    else
+      PrsVarLst(cc,tmpc,PRS0_NULL|PRS1_CLASS);
+    tmpc->size+=tmpc->neg_offset;
+  }
+  return tmpc;
+}
+
+CHashFun *PrsFunJoin(CCmpCtrl *cc,CHashClass *tmp_return,
+        U8 *name,I64 fsp_flags)
+{
+  CMemberLst *tmpm,*header_lst;
+  CAOTCtrl *aotc=cc->aotc;
+  CHashClass *header_return;
+  CHashFun *tmpf;
+  I64 header_arg_cnt;
+  if (name) {//if not fun_ptr
+    if (cc->flags&CCF_AOT_COMPILE) {
+      if ((tmpf=HashFind(name,cc->htc.glbl_hash_table,HTT_FUN)) &&
+            tmpf->type & HTF_IMPORT)
+        tmpf=NULL;
+    } else
+      if ((tmpf=HashSingleTableFind(name,cc->htc.glbl_hash_table,HTT_FUN)) &&
+            !Bt(&tmpf->flags,Cf_EXTERN))
+        tmpf=NULL;
+    if (tmpf && tmpf->use_cnt<3)
+      UnusedExternWarning(cc,tmpf);
+  } else
+    tmpf=NULL;
+  if (tmpf) {
+    tmpf->used_reg_mask=REGG_CLOBBERED+REGG_SAVED+REGG_STK_TMP;
+    Free(tmpf->src_link);
+    tmpf->src_link=NULL;
+    Free(tmpf->idx);
+    tmpf->idx=NULL;
+    Free(name);
+    header_arg_cnt=tmpf->arg_cnt;
+    header_lst=tmpf->member_lst_and_root;
+    header_return=tmpf->return_class;
+    tmpf->member_lst_and_root=NULL;
+    ClassMemberLstDel(tmpf);
+  } else {
+    tmpf=PrsFunNew;
+    header_return=NULL;
+    tmpf->used_reg_mask=REGG_CLOBBERED+REGG_SAVED+REGG_STK_TMP;
+    tmpf->clobbered_reg_mask=REGG_CLOBBERED+REGG_STK_TMP;
+    tmpf->str=name;
+    if (cc->flags&CCF_AOT_COMPILE)
+      tmpf->exe_addr=aotc->rip;
+    else
+      tmpf->exe_addr=&UndefinedExtern;
+    LBts(&tmpf->flags,Cf_EXTERN);
+    tmpf->flags|=fsp_flags&FSG_FUN_FLAGS1;
+    if (name) //if not fun_ptr
+      HashAdd(tmpf,cc->htc.glbl_hash_table);
+  }
+  BEqu(&tmpf->type,HTf_PUBLIC,fsp_flags&FSF_PUBLIC);
+  tmpf->return_class=tmp_return;
+  tmpf->use_cnt=0;
+  HashSrcFileSet(cc,tmpf);
+  PrsVarLst(cc,tmpf,PRS0_NULL|PRS1_FUN_ARG);
+  tmpf->arg_cnt=tmpf->member_cnt;
+  if (0<tmpf->arg_cnt<<3<=I16_MAX && !Bt(&tmpf->flags,Ff_DOT_DOT_DOT))
+    LBts(&tmpf->flags,Ff_RET1);
+  tmpm=tmpf->member_lst_and_root;
+  while (tmpm) {
+    tmpm->offset+=16; //RBP+RETURN
+    tmpm=tmpm->next;
+  }
+  tmpf->size=0;
+  if (header_return) {
+    if (GetOption(OPTf_WARN_HEADER_MISMATCH)) {
+      if (tmpf->return_class!=header_return) {
+        PrintWarn("Fun Header return mismatch '%s'\n",tmpf->str);
+        cc->warning_cnt++;
+      }
+      if (!MemberLstCmp(tmpf->member_lst_and_root,header_lst,header_arg_cnt)) {
+        PrintWarn("Fun header args mismatch '%s'\n",tmpf->str);
+        cc->warning_cnt++;
+      }
+    }
+    MemberLstDel(header_lst);
+  }
+  return tmpf;
+}
+
+U0 PrsFun(CCmpCtrl *cc,CHashClass *tmp_return,U8 *name,I64 fsp_flags)
+{
+  CMemberLst *tmpm;
+  CCodeMisc *saved_leave_label;
+  I64 i,j,size,*r;
+  Bool old_trace;
+
+  cc->fun_lex_file=cc->lex_include_stk;
+  cc->min_line=cc->max_line=cc->lex_include_stk->line_num;
+
+  cc->flags&=~CCF_NO_REG_OPT;
+  cc->htc.local_var_lst=cc->htc.fun=PrsFunJoin(cc,tmp_return,name,fsp_flags);
+
+  COCPush(cc);
+  Btr(&cc->flags,CCf_PASS_TRACE_PRESENT);
+  COCInit(cc);
+  ICAdd(cc,IC_ENTER,0,0);
+  saved_leave_label=cc->lb_leave;
+  cc->lb_leave=COCMiscNew(cc,CMT_LABEL);
+  cc->flags&=~CCF_HAS_RETURN;
+  PrsStmt(cc,,,0);
+
+  if (cc->max_line<cc->min_line)
+    cc->max_line=cc->min_line;
+
+  if (cc->htc.fun->return_class->size && !(cc->flags&CCF_HAS_RETURN))
+    LexWarn(cc,"Function should return val ");
+  ICAdd(cc,IC_LABEL,cc->lb_leave,0);
+  cc->lb_leave=saved_leave_label;
+  ICAdd(cc,IC_LEAVE,0,cc->htc.fun->return_class);
+  cc->htc.fun->size&=~7;
+  if (cc->flags&CCF_AOT_COMPILE) {
+    cc->htc.fun->exe_addr=cc->aotc->rip;
+    cc->htc.fun->type|=HTF_EXPORT|HTF_RESOLVE;
+    r=COCCompile(cc,&size,&cc->htc.fun->dbg_info,NULL);
+    if (r) {
+      j=(size+7)>>3;
+      for (i=0;i<j;i++)
+        AOTStoreCodeU64(cc,r[i]);
+      Free(r);
+    }
+  } else {
+    old_trace=Btr(&cc->opts,OPTf_TRACE);
+    cc->htc.fun->exe_addr=COCCompile(
+          cc,&size,&cc->htc.fun->dbg_info,NULL);
+    if (old_trace) {
+      Bts(&cc->opts,OPTf_TRACE);
+      Un(cc->htc.fun->exe_addr,size,64);
+    }
+    SysSymImportsResolve(cc->htc.fun->str);
+  }
+  LBtr(&cc->htc.fun->flags,Cf_EXTERN);
+  COCPop(cc);
+  tmpm=cc->htc.fun->member_lst_and_root;
+  while (tmpm) {
+    if (tmpm->flags & MLF_NO_UNUSED_WARN) {
+      if (tmpm->use_cnt>1&&StrCmp(tmpm->str,"_anon_"))
+        PrintWarn("Unneeded no_warn\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+              cc->lex_include_stk->full_name,cc->lex_include_stk->line_num,
+              tmpm->str,cc->htc.fun->str);
+    } else if (!tmpm->use_cnt && GetOption(OPTf_WARN_UNUSED_VAR))
+      PrintWarn("Unused var\n $LK,\"FL:%s,%d\"$ '%s' in '%s'\n",
+            cc->lex_include_stk->full_name,cc->lex_include_stk->line_num,
+            tmpm->str,cc->htc.fun->str);
+    tmpm=tmpm->next;
+  }
+  cc->htc.local_var_lst=cc->htc.fun=cc->fun_lex_file=NULL;
+}
+
+U0 PrsGlblVarLst(CCmpCtrl *cc,I64 saved_mode,CHashClass *saved_tmpc,
+  I64 saved_val,I64 fsp_flags)
+{
+  I64 i,j,mode,k,val;
+  U8 *st;
+  CHashExport *tmpex;
+  CHashGlblVar *tmpg;
+  CAOTCtrl *aotc=cc->aotc;
+  CAOTHeapGlbl *tmphg;
+  CHashClass *tmpc;
+  CHashFun *tmpf,*tmpf_fun_ptr;
+  CArrayDim tmpad;
+  Bool has_alias,undef_array_size,is_array;
+  while (TRUE) {
+    tmpc=PrsType(cc,&saved_tmpc,&saved_mode,NULL,&st,
+          &tmpf_fun_ptr,&tmpex,&tmpad,fsp_flags);
+
+    if (!st) return;
+    if (tmpad.next)
+      is_array=TRUE;
+    else if (tmpad.total_cnt<0) {
+      is_array=TRUE;
+      tmpc--;
+    } else
+      is_array=FALSE;
+
+    val=saved_val;
+    mode=saved_mode;
+    if (tmpex && mode&255==PRS0_EXTERN && !(cc->flags&CCF_AOT_COMPILE) &&
+          tmpex->type&HTT_EXPORT_SYS_SYM) {
+      val=tmpex->val;
+      mode=PRS0__EXTERN|PRS1_NOT_REALLY__EXTERN;
+    }
+    if (cc->token=='(') {
+      switch (mode&255) {
+        case PRS0__INTERN:
+          tmpf=PrsFunJoin(cc,tmpc,st,fsp_flags);
+          tmpf->exe_addr=val;
+          Bts(&tmpf->flags,Ff_INTERNAL);
+          LBtr(&tmpf->flags,Cf_EXTERN);
+          return;
+        case PRS0__EXTERN:
+          if (!(fsp_flags&FSF__) && !(mode&PRS1_NOT_REALLY__EXTERN))
+            LexExcept(cc,"Expecting label with underscore at ");
+          tmpf=PrsFunJoin(cc,tmpc,st,fsp_flags);
+          tmpf->exe_addr=val;
+          SysSymImportsResolve(tmpf->str);
+          LBtr(&tmpf->flags,Cf_EXTERN);
+          if (saved_mode&255==PRS0__EXTERN)
+            LBts(&tmpf->flags,Ff__EXTERN);
+          if (cc->flags&CCF_AOT_COMPILE)
+            tmpf->type|=HTF_RESOLVE;
+          return;
+        case PRS0_EXTERN:
+          PrsFunJoin(cc,tmpc,st,fsp_flags);
+          return;
+        case PRS0__IMPORT:
+          if (!(fsp_flags&FSF__))
+            LexExcept(cc,"Expecting label with underscore at ");
+        case PRS0_IMPORT:
+          if (!(cc->flags&CCF_AOT_COMPILE))
+            LexExcept(cc,"import not needed at ");
+          else {
+            tmpf=PrsFunJoin(cc,tmpc,st,fsp_flags);
+            tmpf->type|=HTF_IMPORT;
+            if (mode&255==PRS0__IMPORT)
+              tmpf->import_name=StrNew(val);
+            else
+              tmpf->import_name=StrNew(st);
+          }
+          return;
+        default:
+          PrsFun(cc,tmpc,st,fsp_flags);
+          return;
+      }
+    } else {
+      if (tmpad.total_cnt<0) {
+        i=0;
+        undef_array_size=TRUE;
+      } else {
+        i=tmpad.total_cnt;
+        undef_array_size=FALSE;
+      }
+      if (tmpf_fun_ptr)
+        j=sizeof(U8 *);
+      else
+        j=tmpc->size;
+      j*=i;
+      has_alias=FALSE;
+      tmphg=NULL;
+      switch (mode&255) {
+        case PRS0__EXTERN:
+          if (cc->flags&CCF_AOT_COMPILE) {
+            tmpg=CAlloc(sizeof(CHashGlblVar));
+            tmpg->data_addr_rip=val;
+            tmpg->type=HTT_GLBL_VAR | HTF_EXPORT;
+          } else {
+            tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+            tmpg->data_addr=val;
+            tmpg->type=HTT_GLBL_VAR;
+          }
+          tmpg->flags|=GVF_ALIAS;
+          break;
+        case PRS0__IMPORT:
+        case PRS0_IMPORT:
+          if (!(cc->flags&CCF_AOT_COMPILE))
+            LexExcept(cc,"import not needed at ");
+          else {
+            tmpg=CAlloc(sizeof(CHashGlblVar));
+            tmpg->type=HTT_GLBL_VAR | HTF_IMPORT;
+            if (mode&255==PRS0__IMPORT)
+              tmpg->import_name=StrNew(val);
+            else
+              tmpg->import_name=StrNew(st);
+          }
+          break;
+        case PRS0_EXTERN:
+          if (cc->flags&CCF_AOT_COMPILE) {
+            tmpg=CAlloc(sizeof(CHashGlblVar));
+            tmpg->type=HTT_GLBL_VAR;
+          } else {
+            tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+            tmpg->type=HTT_GLBL_VAR|HTF_UNRESOLVED;
+          }
+          break;
+        default:
+          if (cc->flags&CCF_AOT_COMPILE) {
+            if (Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)) {
+              if (cc->token=='=')
+                LexExcept(cc,"Can't init glbl var on data heap in AOT module ");
+              tmpg=CAlloc(sizeof(CHashGlblVar));
+              tmphg=tmpg->heap_glbl=CAlloc(sizeof(CAOTHeapGlbl));
+              tmphg->size=j;
+              tmphg->str=StrNew(st);
+              tmphg->next=aotc->heap_glbls;
+              aotc->heap_glbls=tmphg;
+              tmpg->flags=GVF_DATA_HEAP;
+              tmpg->type=HTT_GLBL_VAR; //TODO: HTF_EXPORT
+              if (tmpex && tmpex->type & HTT_GLBL_VAR) //TODO!! extern
+                LexExcept(cc,"Feature not implemented ");
+            } else {
+              tmpg=CAlloc(sizeof(CHashGlblVar));
+              if (cc->token=='=')
+                tmpg->data_addr=CAlloc(j);
+              if (tmpc->size>=8) //align
+                while (aotc->rip&7)
+                  AOTStoreCodeU8(cc,0);
+              else if (tmpc->size==4)
+                while (aotc->rip&3)
+                  AOTStoreCodeU8(cc,0);
+              else if (tmpc->size==2)
+                while (aotc->rip&1)
+                  AOTStoreCodeU8(cc,0);
+              tmpg->data_addr_rip=aotc->rip;
+              tmpg->type=HTT_GLBL_VAR | HTF_EXPORT;
+              if (tmpex && tmpex->type & HTT_GLBL_VAR)
+                has_alias=TRUE;
+              for (k=0;k<j;k++)
+                AOTStoreCodeU8(cc,0); //Init AOT glbl to zero.
+            }
+          } else {
+            if (Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)) {
+              tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+              tmpg->data_addr=MAlloc(j);
+              tmpg->flags=GVF_DATA_HEAP;
+            } else {
+              tmpg=CAlloc(sizeof(CHashGlblVar),Fs->code_heap);
+              tmpg->data_addr=MAlloc(j,Fs->code_heap);
+            }
+            tmpg->type=HTT_GLBL_VAR;
+            if (tmpex && tmpex->type&HTT_GLBL_VAR &&
+                  tmpex->type&HTF_UNRESOLVED &&
+                  MHeapCtrl(tmpex)==MHeapCtrl(tmpg))
+              has_alias=TRUE;
+            if (sys_var_init_flag)
+              MemSet(tmpg->data_addr,sys_var_init_val,j);
+          }
+      }
+      tmpg->dim.next=tmpad.next;
+      if (fsp_flags&FSF_PUBLIC)
+        tmpg->type|=HTF_PUBLIC;
+      tmpg->var_class=tmpc;
+      tmpg->str=st;
+      tmpg->size=j;
+      tmpg->dim.total_cnt=i;
+      tmpg->use_cnt=0;
+      if (cc->last_U16=='\n')
+        HashSrcFileSet(cc,tmpg,-1);
+      else
+        HashSrcFileSet(cc,tmpg,0);
+      if (mode&255==PRS0_IMPORT || mode&255==PRS0__IMPORT)
+        tmpg->flags|=GVF_IMPORT;
+      if (mode&255==PRS0_EXTERN)
+        tmpg->flags|=GVF_EXTERN;
+      if (tmpf_fun_ptr) {
+        tmpg->fun_ptr=tmpf_fun_ptr;
+        tmpg->flags|=GVF_FUN;
+      }
+      if (is_array)
+        tmpg->flags|=GVF_ARRAY;
+      HashAdd(tmpg,cc->htc.glbl_hash_table);
+      if (!(cc->flags&CCF_AOT_COMPILE) && !(tmpg->flags&GVF_EXTERN))
+        SysSymImportsResolve(tmpg->str);
+      if (cc->token=='=') {
+        if (undef_array_size) {
+          LexPush(cc);
+          LexPush(cc);
+          Lex(cc);
+          PrsGlblInit(cc,tmpg,1);
+          LexPopNoRestore(cc);
+          tmpg->size=tmpg->dim.total_cnt*tmpc->size;
+          if (tmphg)
+            tmphg->size=tmpg->size;
+          if (cc->flags&CCF_AOT_COMPILE)
+            for (k=0;k<tmpg->size;k++)
+              AOTStoreCodeU8(cc,0);
+          else
+            if (sys_var_init_flag)
+              MemSet(tmpg->data_addr,sys_var_init_val,k);
+          LexPopRestore(cc);
+        }
+        LexPush(cc);
+        Lex(cc);
+        PrsGlblInit(cc,tmpg,2);
+        if (cc->flags&CCF_AOT_COMPILE)
+          for (k=0;k<tmpg->size;k++)
+            AOTStoreCodeU8At(cc,tmpg->data_addr_rip+k,tmpg->data_addr[k]);
+        LexPopNoRestore(cc);
+      }
+      if (has_alias) {
+        if (tmpex(CHashGlblVar *)->use_cnt<2) {
+          PrintWarn("Unused extern '%s'\n",tmpex(CHashGlblVar *)->str);
+          cc->warning_cnt++;
+        }
+        tmpex(CHashGlblVar *)->flags|=GVF_ALIAS;
+        tmpex(CHashGlblVar *)->data_addr=tmpg->data_addr;
+        tmpex(CHashGlblVar *)->data_addr_rip=tmpg->data_addr_rip;
+      }
+      if (cc->token==',')
+        Lex(cc);
+      else {
+        if (cc->token!=';')
+          LexExcept(cc,"Missing ';' at");
+        Lex(cc);
+        return;
+      }
+    }
+  }
+}
+
+U0 PrsIf(CCmpCtrl *cc,I64 try_cnt,CCodeMisc *lb_break)
+{
+  CCodeMisc *lb,*lb1;
+  I64 k;
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  Lex(cc);
+  lb=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_BR_ZERO,lb,0);
+  PrsStmt(cc,try_cnt,lb_break);
+  k=PrsKeyWord(cc);
+  if (k==KW_ELSE) {
+    Lex(cc);
+    lb1=COCMiscNew(cc,CMT_LABEL);
+    ICAdd(cc,IC_JMP,lb1,0);
+    ICAdd(cc,IC_LABEL,lb,0);
+    PrsStmt(cc,try_cnt,lb_break);
+    ICAdd(cc,IC_LABEL,lb1,0);
+  } else
+    ICAdd(cc,IC_LABEL,lb,0);
+}
+
+U0 PrsWhile(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeMisc *lb,*lb_done;
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  lb=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_LABEL,lb,0);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  Lex(cc);
+  lb_done=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_BR_ZERO,lb_done,0);
+  PrsStmt(cc,try_cnt,lb_done);
+  ICAdd(cc,IC_JMP,lb,0);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+}
+
+U0 PrsDoWhile(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeMisc *lb,*lb_done;
+  lb=COCMiscNew(cc,CMT_LABEL);
+  lb_done=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_LABEL,lb,0);
+  PrsStmt(cc,try_cnt,lb_done);
+  if (PrsKeyWord(cc)!=KW_WHILE)
+    LexExcept(cc,"Missing 'while' at");
+  if (Lex(cc)!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  ICAdd(cc,IC_BR_NOT_ZERO,lb,0);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+  if (Lex(cc)!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+}
+
+U0 PrsFor(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeCtrl *tmpcbh;
+  CCodeMisc *lb,*lb_done;
+
+  if (cc->token!='(')
+    LexExcept(cc,"Expecting '(' at ");
+  Lex(cc);
+  PrsStmt(cc,try_cnt);
+
+  lb=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_LABEL,lb,0);
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  lb_done=COCMiscNew(cc,CMT_LABEL);
+  ICAdd(cc,IC_BR_ZERO,lb_done,0);
+  if (cc->token!=';')
+    LexExcept(cc,"Missing ';' at");
+  Lex(cc);
+
+  COCPush(cc);
+  COCInit(cc);
+  if (cc->token!=')')
+    PrsStmt(cc,try_cnt,NULL,0);
+  COCPush(cc);
+  tmpcbh=COCPopNoFree(cc);
+  COCPop(cc);
+  if (cc->token!=')')
+    LexExcept(cc,"Missing ')' at ");
+  Lex(cc);
+
+  PrsStmt(cc,try_cnt,lb_done);
+  COCAppend(cc,tmpcbh);
+  ICAdd(cc,IC_JMP,lb,0);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+}
+
+class CSubSwitch {
+  CSubSwitch *next,*last;
+  CCodeMisc *lb_start,*lb_break;
+};
+
+class CSwitchCase {
+  CSwitchCase *next;
+  CCodeMisc *label;
+  I64 val;
+  CSubSwitch *ss;
+};
+
+U0 PrsSwitch(CCmpCtrl *cc,I64 try_cnt)
+{
+  CSwitchCase *header=NULL,*tmps,*tmps1;        //Leaks on except
+  CSubSwitch head,*tmpss;                       //Leaks on except
+  CCodeMisc *lb_dft,*lb_fwd_case,*mc_jt,*lb_entry,**jmp_table;
+  CIntermediateCode *tmpi_sub,*tmpi_cmp,*tmpi_jmp,*tmpi_start;
+  Bool dft_found=FALSE,nobound;
+  I64 i,k_start=I64_MIN,k_end,lo=I64_MAX,hi=I64_MIN,range;
+
+  if (cc->token=='(')
+    nobound=FALSE;
+  else if (cc->token=='[')
+    nobound=TRUE;
+  else
+    LexExcept(cc,"Expecting '(' or '[' at ");
+  Lex(cc);
+  QueInit(&head);
+
+  head.last->lb_break=COCMiscNew(cc,CMT_LABEL);
+  head.last->lb_break->use_cnt++;
+  lb_dft=COCMiscNew(cc,CMT_LABEL);
+  lb_dft->use_cnt++;
+  mc_jt=COCMiscNew(cc,CMT_JMP_TABLE);
+  mc_jt->begin=COCMiscNew(cc,CMT_LABEL);
+  mc_jt->begin->use_cnt++;
+  if (!PrsExpression(cc,NULL,FALSE))
+    throw('Compiler');
+  tmpi_sub=ICAdd(cc,IC_IMM_I64,0,cmp.internal_types[RT_I64]);
+  ICAdd(cc,IC_SUB,0,cmp.internal_types[RT_I64]);
+  tmpi_cmp=ICAdd(cc,IC_IMM_I64,0,cmp.internal_types[RT_I64]);
+  if (nobound) {
+    ICAdd(cc,IC_NOBOUND_SWITCH,mc_jt,0);
+    if (cc->token!=']')
+      LexExcept(cc,"Missing ']' at ");
+  } else {
+    ICAdd(cc,IC_SWITCH,mc_jt,0);
+    if (cc->token!=')')
+      LexExcept(cc,"Missing ')' at ");
+  }
+  if (Lex(cc)!='{')
+    LexExcept(cc,"Expecting '{' at ");
+  Lex(cc);
+  ICAdd(cc,IC_LABEL,mc_jt->begin,0);
+  while (TRUE) {
+    while (cc->token && cc->token!='}') {
+sw_cont:
+      switch (PrsKeyWord(cc)) {
+        case KW_END:
+          goto sw_sub_end;
+        case KW_START:
+          if (Lex(cc)==':')
+            Lex(cc);
+          else
+            LexExcept(cc,"Expecting ':' at ");
+          tmpss=MAlloc(sizeof(CSubSwitch));
+          QueIns(tmpss,head.last);
+          head.last->lb_break=COCMiscNew(cc,CMT_LABEL);
+          head.last->lb_break->use_cnt++;
+          lb_fwd_case=COCMiscNew(cc,CMT_LABEL);
+          tmpi_jmp=ICAdd(cc,IC_JMP,lb_fwd_case,0);
+
+          tmpss->lb_start=COCMiscNew(cc,CMT_LABEL);
+          tmpi_start=ICAdd(cc,IC_LABEL,tmpss->lb_start,0);
+          while (cc->token && cc->token!='}') {
+            switch (PrsKeyWord(cc)) {
+              case KW_END:
+                OptFree(tmpi_jmp);
+                goto sw_sub_end;
+              case KW_START:
+              case KW_CASE:
+              case KW_DFT:
+                if (cc->coc.coc_head.last==tmpi_start) {
+                  OptFree(tmpi_jmp);
+                  tmpss->lb_start=NULL;
+                } else {
+                  ICAdd(cc,IC_RET,0,0);
+                  ICAdd(cc,IC_LABEL,lb_fwd_case,0);
+                  ICAdd(cc,IC_SUB_CALL,tmpss->lb_start,0);//In case fall-thru
+                }
+                goto sw_cont;
+              default:
+                PrsStmt(cc,try_cnt);
+            }
+          }
+          break;
+        case KW_CASE:
+          if (head.next!=&head) {
+            lb_fwd_case=COCMiscNew(cc,CMT_LABEL);
+            tmpi_jmp=ICAdd(cc,IC_JMP,lb_fwd_case,0);//In case fall-thru
+          }
+          Lex(cc);
+          lb_entry=COCMiscNew(cc,CMT_LABEL);
+          ICAdd(cc,IC_LABEL,lb_entry,0);
+          lb_entry->use_cnt++;
+          if (head.next!=&head) {
+            tmpss=head.next;
+            while (tmpss!=&head) {
+              if (tmpss->lb_start)
+                ICAdd(cc,IC_SUB_CALL,tmpss->lb_start,0);
+              tmpss=tmpss->next;
+            }
+            ICAdd(cc,IC_LABEL,lb_fwd_case,0);
+          }
+          if (cc->token==':') {
+            if (k_start==I64_MIN)
+              k_start=0;
+            else
+              k_start++;
+          } else
+            k_start=LexExpressionI64(cc);
+          if (k_start<lo) lo=k_start;
+          if (k_start>hi) hi=k_start;
+          if (cc->token==':') {
+            Lex(cc);
+            tmps=MAlloc(sizeof(CSwitchCase));
+            tmps->label=lb_entry;
+            tmps->val=k_start;
+            tmps->next=header;
+            header=tmps;
+          } else if (cc->token==TK_ELLIPSIS) {
+            Lex(cc);
+            k_end=LexExpressionI64(cc);
+            if (cc->token==':') {
+              Lex(cc);
+              if (k_end<lo) lo=k_end;
+              if (k_end>hi) hi=k_end;
+              if (k_start>k_end)
+                SwapI64(&k_start,&k_end);
+              for (i=k_start;i<=k_end;i++) {
+                tmps=MAlloc(sizeof(CSwitchCase));
+                tmps->label=lb_entry;
+                tmps->val=i;
+                tmps->next=header;
+                header=tmps;
+              }
+              k_start=k_end;
+            } else
+              LexExcept(cc,"Expecting ':' at ");
+          } else
+            LexExcept(cc,"Expecting ':' at ");
+          break;
+        case KW_DFT:
+          if (head.next!=&head) {
+            lb_fwd_case=COCMiscNew(cc,CMT_LABEL);
+            tmpi_jmp=ICAdd(cc,IC_JMP,lb_fwd_case,0);//In case fall-thru
+          }
+          Lex(cc);
+          ICAdd(cc,IC_LABEL,lb_dft,0);
+          if (cc->token==':')
+            Lex(cc);
+          else
+            LexExcept(cc,"Expecting ':' at ");
+          if (head.next!=&head) {
+            tmpss=head.next;
+            while (tmpss!=&head) {
+              if (tmpss->lb_start)
+                ICAdd(cc,IC_SUB_CALL,tmpss->lb_start,0);
+              tmpss=tmpss->next;
+            }
+            ICAdd(cc,IC_LABEL,lb_fwd_case,0);
+          }
+          dft_found=TRUE;
+          break;
+        default:
+          PrsStmt(cc,try_cnt,head.last->lb_break);
+      }
+    }
+sw_sub_end:
+    tmpss=head.last;
+    ICAdd(cc,IC_LABEL,tmpss->lb_break,0);
+    if (tmpss==&head) {
+      if (cc->token!='}')
+        LexExcept(cc,"Missing '}' at ");
+      Lex(cc);
+      break;
+    } else {
+      QueRem(tmpss);
+      Free(tmpss);
+      if (PrsKeyWord(cc)!=KW_END)
+        LexExcept(cc,"Missing 'end' at ");
+      if (Lex(cc)==':')
+        Lex(cc);
+      else
+        LexExcept(cc,"Expecting ':' at ");
+    }
+  }
+  if (!dft_found)
+    ICAdd(cc,IC_LABEL,lb_dft,0);
+
+  if (0<lo<=16)
+    lo=0;
+  range=hi-lo+1;
+  if (lo>hi || !(0<range<=0xFFFF))
+    LexExcept(cc,"switch range error at ");
+  jmp_table=MAlloc((sizeof(CCodeMisc *)*range+0x1FF)&~0x1FF);
+  MemSetI64(jmp_table,lb_dft,range);
+  tmpi_sub->ic_data=lo;
+  tmpi_cmp->ic_data=range;
+  tmps=header;
+  while (tmps) {
+    tmps1=tmps->next;
+    if (jmp_table[tmps->val-lo]!=lb_dft)
+      LexExcept(cc,"Duplicate case at ");
+    else
+      jmp_table[tmps->val-lo]=tmps->label;
+    Free(tmps);
+    tmps=tmps1;
+  }
+  mc_jt->dft=lb_dft;
+  mc_jt->jmp_table=jmp_table;
+  mc_jt->range=range;
+}
+
+U0 PrsNoWarn(CCmpCtrl *cc)
+{
+  CMemberLst *tmpm;
+  while (cc->token==TK_IDENT) {
+    if (!(tmpm=cc->local_var_entry))
+      LexExcept(cc,"Expecting local var at ");
+    tmpm->flags|=MLF_NO_UNUSED_WARN;
+    if (Lex(cc)==',')
+      Lex(cc);
+    else if (cc->token!=';')
+      LexExcept(cc,"Expecting ',' at ");
+  }
+}
+
+U0 PrsStreamBlk(CCmpCtrl *cc)
+{
+  CLexHashTableContext *htc=MAlloc(sizeof(CLexHashTableContext));
+  CStreamBlk *tmpe=MAlloc(sizeof(CStreamBlk));
+  tmpe->body=StrNew("");
+  QueIns(tmpe,cc->last_stream_blk);
+  COCPush(cc);
+  QueInit(&cc->coc.coc_next_misc);
+
+  MemCpy(htc,&cc->htc,sizeof(CLexHashTableContext));
+  htc->old_flags=cc->flags;
+  cc->htc.next=htc;
+  cc->htc.fun=cc->htc.local_var_lst=NULL;
+  cc->htc.define_hash_table=cc->htc.hash_table_lst=
+        cc->htc.glbl_hash_table=cc->htc.local_hash_table=Fs->hash_table;
+  cc->flags=cc->flags & ~(CCF_ASM_EXPRESSIONS|CCF_AOT_COMPILE) | CCF_EXE_BLK;
+  if (cc->token=='{')
+    Lex(cc);
+  else
+    LexExcept(cc,"Missing '}' at ");
+  while (cc->token && cc->token!='}')
+    ExeCmdLine(cc);
+
+  MemCpy(&cc->htc,htc,sizeof(CLexHashTableContext));
+  cc->flags=cc->flags&~CCF_EXE_BLK |
+        htc->old_flags & (CCF_ASM_EXPRESSIONS|CCF_EXE_BLK|CCF_AOT_COMPILE);
+  Free(htc);
+  COCPop(cc);
+  QueRem(tmpe);
+  if (*tmpe->body)
+    LexIncludeStr(cc,"StreamBlk",tmpe->body,FALSE);
+  else
+    Free(tmpe->body);
+  Free(tmpe);
+  Lex(cc); //Skip '}'
+}
+
+U0 PrsTryBlk(CCmpCtrl *cc,I64 try_cnt)
+{
+  CCodeMisc     *lb_catch,*lb_done,*lb_untry;
+  CHashClass    *tmpc=cmp.internal_types[RT_PTR];
+  CHashFun      *tmp_try=HashFind("SysTry",cc->htc.hash_table_lst,HTT_FUN),
+        *tmp_untry=HashFind("SysUntry",cc->htc.hash_table_lst,HTT_FUN);
+
+  if (!tmp_try || !tmp_untry)
+    LexExcept(cc,"Missing header for SysTry() and SysUntry() at ");
+
+  cc->flags|=CCF_NO_REG_OPT; //TODO:Currently no reg vars in funs with try/catch
+
+  lb_catch=COCMiscNew(cc,CMT_LABEL);
+  lb_done =COCMiscNew(cc,CMT_LABEL);
+  lb_untry=COCMiscNew(cc,CMT_LABEL);
+
+  ICAdd(cc,IC_CALL_START,0,0);
+  ICAdd(cc,IC_GET_LABEL,lb_untry,tmpc,ICF_PUSH_RES);
+  ICAdd(cc,IC_GET_LABEL,lb_catch,tmpc,ICF_PUSH_RES);
+  if (Bt(&tmp_try->flags,Cf_EXTERN)) {
+    cc->abs_cnts.externs++;
+    if (cc->flags&CCF_AOT_COMPILE)
+      ICAdd(cc,IC_CALL_IMPORT,tmp_try,tmpc);
+    else
+      ICAdd(cc,IC_CALL_INDIRECT2,&tmp_try->exe_addr,tmpc);
+  } else
+    ICAdd(cc,IC_CALL,tmp_try->exe_addr,tmpc);
+  if ((Bt(&tmp_try->flags,Ff_RET1) ||
+        Bt(&tmp_try->flags,Ff_ARGPOP)) && !Bt(&tmp_try->flags,Ff_NOARGPOP))
+    ICAdd(cc,IC_ADD_RSP1,16,tmpc);
+  else
+    ICAdd(cc,IC_ADD_RSP,16,tmpc);
+  ICAdd(cc,IC_CALL_END,0,tmpc);
+  ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+
+  PrsStmt(cc,try_cnt+1);
+
+  ICAdd(cc,IC_LABEL,lb_untry,0);
+  ICAdd(cc,IC_CALL_START,0,0);
+  if (Bt(&tmp_untry->flags,Cf_EXTERN)) {
+    cc->abs_cnts.externs++;
+    if (cc->flags&CCF_AOT_COMPILE)
+      ICAdd(cc,IC_CALL_IMPORT,tmp_untry,tmpc);
+    else
+      ICAdd(cc,IC_CALL_INDIRECT2,&tmp_untry->exe_addr,tmpc);
+  } else
+    ICAdd(cc,IC_CALL,tmp_untry->exe_addr,tmpc);
+  ICAdd(cc,IC_CALL_END,0,tmpc);
+  ICAdd(cc,IC_END_EXP,0,0,ICF_RES_NOT_USED);
+
+  ICAdd(cc,IC_JMP,lb_done,0);
+
+  if (PrsKeyWord(cc)!=KW_CATCH)
+    LexExcept(cc,"Missing 'catch' at");
+
+  Lex(cc);
+  ICAdd(cc,IC_LABEL,lb_catch,0);
+  PrsStmt(cc,try_cnt+1);
+  ICAdd(cc,IC_RET,0,tmpc);
+  ICAdd(cc,IC_LABEL,lb_done,0);
+}
+
+Bool PrsStmt(CCmpCtrl *cc,I64 try_cnt=0,
+  CCodeMisc *lb_break=NULL,I64 cmp_flags=CMPF_PRS_SEMICOLON)
+{
+  I64 i,fsp_flags=0;
+  CHashExport *tmpex;
+  CCodeMisc *g_lb;
+  U8 *import_name;
+  CHashFun *tmp_untry;
+  CAOT *tmpaot;
+  if (cmp_flags&CMPF_ONE_ASM_INS) {
+    if (cc->flags&CCF_AOT_COMPILE || cc->aot_depth)
+      PrsAsmBlk(cc,CMPF_ONE_ASM_INS);
+    else if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK|CMPF_ONE_ASM_INS))
+      CmpFixUpJITAsm(cc,tmpaot);
+    fsp_flags=FSF_ASM;
+  } else
+    while (TRUE) {
+      while (cc->token==',')
+        Lex(cc);
+      if (cc->token=='{') {
+        Lex(cc);
+        while (cc->token!='}' && cc->token!=TK_EOF)
+          PrsStmt(cc,try_cnt,lb_break);
+        if (cc->lex_include_stk==cc->fun_lex_file)
+          cc->max_line=cc->lex_include_stk->line_num;
+        if (Lex(cc)!=',') goto sm_done;
+      } else if (cc->token==';') {
+        if (cmp_flags&CMPF_PRS_SEMICOLON)
+          Lex(cc);
+        if (cc->token!=',') goto sm_done;
+      } else {
+        if (cc->token==TK_IDENT) {
+          if (tmpex=cc->hash_entry) {
+            if (tmpex->type & HTT_KEYWORD) {
+              i=tmpex(CHashGeneric *)->user_data0;
+              switch [i] {
+                case KW_KWS_NUM-1: //nobound switch
+                default: //A keyword that is not valid here is just a symbol.
+                  goto sm_not_keyword_afterall;
+                start:
+                  case KW_ASM:
+                    if (cc->htc.fun) {
+                      if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK))
+                        ICAdd(cc,IC_ASM,tmpaot,0);
+                      Lex(cc); //Skip '}' of asm{}
+                    } else {
+                      if (cc->flags&CCF_AOT_COMPILE || cc->aot_depth) {
+                        Lex(cc);
+                        PrsAsmBlk(cc,0);
+                        if (cc->flags&CCF_AOT_COMPILE && cc->aot_depth==1)
+                          Lex(cc); //Skip '}' of asm{}
+                      } else {
+                        if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK))
+                          CmpFixUpJITAsm(cc,tmpaot);
+                        Lex(cc); //Skip '}' of asm{}
+                      }
+                      fsp_flags=FSF_ASM;
+                    }
+                    break;
+                  start:
+                    Lex(cc);
+                    case KW_LOCK:
+                      cc->lock_cnt++;
+                      PrsStmt(cc,try_cnt);
+                      cc->lock_cnt--;
+                      break;
+                    case KW_TRY:
+                      PrsTryBlk(cc,try_cnt);
+                      break;
+                    case KW_IF:
+                      PrsIf(cc,try_cnt,lb_break);
+                      break;
+                    case KW_FOR:
+                      PrsFor(cc,try_cnt);
+                      break;
+                    case KW_WHILE:
+                      PrsWhile(cc,try_cnt);
+                      break;
+                    case KW_DO:
+                      PrsDoWhile(cc,try_cnt);
+                      break;
+                    case KW_SWITCH:
+                      PrsSwitch(cc,try_cnt);
+                      break;
+                  end:
+                end:
+                  if (cc->token!=',') goto sm_done;
+                  break;
+                start:
+                  if (cc->htc.fun)
+                    LexExcept(cc,"Not allowed in fun");
+                  Lex(cc);
+                  case KW__EXTERN:
+                    if (Bt(&cc->opts,OPTf_EXTERNS_TO_IMPORTS))
+                      goto sm_underscore_import;
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & HTT_EXPORT_SYS_SYM))
+                      LexExcept(cc,"Expecting system sym at ");
+                    if (*cc->cur_str=='_')
+                      fsp_flags|=FSF__;
+                    i=tmpex->val;
+                    Lex(cc);
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0__EXTERN|PRS1_NULL,tmpex,i,fsp_flags);
+                    break;
+                  case KW__IMPORT:
+sm_underscore_import:
+                    if (cc->token!=TK_IDENT)
+                      LexExcept(cc,"Expecting system sym at ");
+                    if (*cc->cur_str=='_')
+                      fsp_flags|=FSF__;
+                    import_name=cc->cur_str;
+                    cc->cur_str=0;
+                    if (Lex(cc)!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0__IMPORT|PRS1_NULL,tmpex,
+                          import_name,fsp_flags);
+                    Free(import_name);
+                    break;
+                  case KW_EXTERN:
+                    if (cc->token!=TK_IDENT)
+                      LexExcept(cc,"Expecting type at ");
+                    tmpex=cc->hash_entry;
+                    i=PrsKeyWord(cc);
+                    if (i==KW_CLASS||i==KW_UNION) {
+                      Lex(cc);
+                      PrsClass(cc,i,fsp_flags,TRUE);
+                      fsp_flags&=FSF_ASM;
+                      goto sm_semicolon;
+                    }
+                    if (!tmpex ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    if (Bt(&cc->opts,OPTf_EXTERNS_TO_IMPORTS))
+                      goto sm_import;
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0_EXTERN|PRS1_NULL,tmpex,0,fsp_flags);
+                    break;
+                  case KW_IMPORT:
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+sm_import:
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0_IMPORT|PRS1_NULL,tmpex,0,fsp_flags);
+                    break;
+                  case KW__INTERN:
+                    i=LexExpressionI64(cc);
+                    if (cc->token!=TK_IDENT || !(tmpex=cc->hash_entry) ||
+                          !(tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+                      LexExcept(cc,"Expecting type at ");
+                    Lex(cc);
+                    PrsGlblVarLst(cc,PRS0__INTERN|PRS1_NULL,tmpex,i,fsp_flags);
+                    break;
+                end:
+                  fsp_flags&=FSF_ASM;
+                  break;
+                start:
+                  case KW_STATIC:
+                    fsp_flags=FSF_STATIC|fsp_flags&FSF_ASM;
+                    break;
+                  case KW_INTERRUPT:
+                    fsp_flags=FSF_INTERRUPT|FSF_NOARGPOP|
+                          fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_HASERRCODE:
+                    fsp_flags=FSF_HASERRCODE|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_ARGPOP:
+                    fsp_flags=FSF_ARGPOP|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_NOARGPOP:
+                    fsp_flags=FSF_NOARGPOP|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                  case KW_PUBLIC:
+                    fsp_flags=FSF_PUBLIC|fsp_flags&(FSG_FUN_FLAGS2|FSF_ASM);
+                    break;
+                end:
+                  Lex(cc);
+                  break;
+                case KW_RETURN:
+                  if (!cc->htc.fun)
+                    LexExcept(cc,"Not in fun.  Can't return a val ");
+                  if (try_cnt) {
+                    tmp_untry=HashFind("SysUntry",
+                          cc->htc.hash_table_lst,HTT_FUN);
+                    for (i=0;i<try_cnt;i++) {
+                      if (Bt(&tmp_untry->flags,Cf_EXTERN)) {
+                        cc->abs_cnts.externs++;
+                        if (cc->flags&CCF_AOT_COMPILE)
+                          ICAdd(cc,IC_CALL_IMPORT,
+                                tmp_untry,cmp.internal_types[RT_PTR]);
+                        else
+                          ICAdd(cc,IC_CALL_INDIRECT2,
+                                &tmp_untry->exe_addr,
+                                cmp.internal_types[RT_PTR]);
+                      } else
+                        ICAdd(cc,IC_CALL,tmp_untry->exe_addr,
+                              cmp.internal_types[RT_PTR]);
+                    }
+                  }
+                  if (Lex(cc)!=';') {
+                    if (!cc->htc.fun->return_class->size)
+                      LexWarn(cc,"Function should NOT return val ");
+                    if (!PrsExpression(cc,NULL,FALSE))
+                      throw('Compiler');
+                    ICAdd(cc,IC_RETURN_VAL,0,cc->htc.fun->return_class);
+                    cc->flags|=CCF_HAS_RETURN;
+                  } else if (cc->htc.fun->return_class->size)
+                    LexWarn(cc,"Function should return val ");
+                  ICAdd(cc,IC_JMP,cc->lb_leave,0);
+                  goto sm_semicolon;
+                case KW_GOTO:
+                  if (Lex(cc)!=TK_IDENT)
+                    LexExcept(cc,"Expecting identifier at ");
+                  if (!(g_lb=COCGoToLabelFind(cc,cc->cur_str))) {
+                    g_lb=COCMiscNew(cc,CMT_GOTO_LABEL);
+                    g_lb->str=cc->cur_str;
+                    cc->cur_str=NULL;
+                  }
+                  g_lb->use_cnt++;
+                  ICAdd(cc,IC_JMP,g_lb,0);
+                  Lex(cc);
+                  goto sm_semicolon;
+                case KW_BREAK:
+                  Lex(cc);
+                  if (!lb_break)
+                    LexExcept(cc,"'break' not allowed\n");
+                  ICAdd(cc,IC_JMP,lb_break,0);
+                  goto sm_semicolon;
+                case KW_NO_WARN:
+                  Lex(cc);
+                  PrsNoWarn(cc);
+                  goto sm_semicolon;
+                case KW_UNION:
+                case KW_CLASS:
+                  Lex(cc);
+                  tmpex=PrsClass(cc,i,fsp_flags,FALSE);
+                  if (!cc->htc.fun && cc->token!=';') {
+                    PrsGlblVarLst(cc,PRS0_NULL|PRS1_NULL,tmpex,0,fsp_flags);
+                    fsp_flags&=FSF_ASM;
+                    break;
+                  } else {
+                    fsp_flags&=FSF_ASM;
+                    goto sm_semicolon;
+                  }
+              }
+            } else {//Ident, found in hash table, not keyword
+sm_not_keyword_afterall:
+              if (tmpex->type & (HTT_CLASS|HTT_INTERNAL_TYPE)) {
+                if (cc->htc.fun) {
+                  if (fsp_flags&FSF_STATIC)
+                    PrsVarLst(cc,cc->htc.fun,PRS0_NULL|PRS1_STATIC_LOCAL_VAR);
+                  else
+                    PrsVarLst(cc,cc->htc.fun,PRS0_NULL|PRS1_LOCAL_VAR);
+                  if (cc->token=='}') goto sm_done;
+                } else {
+                  Lex(cc);
+                  PrsGlblVarLst(cc,PRS0_NULL|PRS1_NULL,tmpex,0,fsp_flags);
+                }
+              } else {
+                if (tmpex->type & (HTT_OPCODE|HTT_ASM_KEYWORD)) {
+                  if (cc->htc.fun) {
+                    if (tmpaot=CmpJoin(cc,CMPF_ASM_BLK|CMPF_ONE_ASM_INS))
+                      ICAdd(cc,IC_ASM,tmpaot,0);
+                  } else
+                    LexExcept(cc,"Use Asm Blk at ");
+                  if (cc->token!=',') goto sm_done;
+                } else
+                  goto sm_prs_exp;
+              }
+              fsp_flags&=FSF_ASM;
+            }
+          } else {//Ident, not in hash table
+            if (cc->local_var_entry)
+              goto sm_prs_exp;
+            if (!(g_lb=COCGoToLabelFind(cc,cc->cur_str))) {
+              g_lb=COCMiscNew(cc,CMT_GOTO_LABEL);
+              g_lb->str=cc->cur_str;
+              cc->cur_str=NULL;
+            } else if (g_lb->flags&CMF_DEFINED)
+              LexExcept(cc,"Duplicate goto label at ");
+            g_lb->flags|=CMF_DEFINED;
+            ICAdd(cc,IC_LABEL,g_lb,0);
+            if (Lex(cc)==':') //skip cur_str
+              Lex(cc); //skip colon
+            else
+              LexExcept(cc,"Undefined identifier at ");
+            if (!cc->htc.fun)
+              LexExcept(cc,"No global labels at ");
+            if (cc->token!=',') goto sm_done;
+          }
+        } else if (cc->token==TK_STR||cc->token==TK_CHAR_CONST) {
+          PrsFunCall(cc,NULL,FALSE,NULL);
+          goto sm_semicolon;
+        } else if (cc->token!=TK_EOF) {//Non-cur_str symbol, num or something
+sm_prs_exp:
+          if (!PrsExpression(cc,NULL,TRUE))
+            throw('Compiler');
+sm_semicolon:
+          if (cmp_flags&CMPF_PRS_SEMICOLON) {
+            if (cc->token==';')
+              Lex(cc);
+            else if (cc->token!=',')
+              LexExcept(cc,"Missing ';' at");
+          }
+          if (cc->token!=',') goto sm_done;
+        } else
+          goto sm_done; //TK_EOF
+      }
+    }
+sm_done:
+  return fsp_flags&FSF_ASM;
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/PrsVar.HC.HTML b/public/Wb/Home/Src/Compiler/PrsVar.HC.HTML new file mode 100755 index 0000000..4581aa5 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/PrsVar.HC.HTML @@ -0,0 +1,752 @@ + + + + + + + + + + + +
+U0 PrsVarInit(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,CArrayDim *tmpad,
+        U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass)
+{
+  U8 *dst=*_dst,*machine_code;
+  I64 i,j,r,old_flags,type,size;
+  CMemberLst *tmpm;
+  CIntermediateCode *tmpi;
+  CAOTCtrl *aotc=cc->aotc;
+  CAOTAbsAddr *tmpa;
+  CAOTImportExport *tmpie;
+  Bool is_str;
+
+  tmpc=OptClassFwd(tmpc);
+  if (tmpm=tmpc->member_lst_and_root) {
+    if (cc->token!='{')
+      LexExcept(cc,"Expecting '{' at ");
+    LexPopNoRestore(cc);
+    LexPush(cc);
+    Lex(cc);
+    while (tmpm) {
+      PrsVarInit2(cc,&dst,tmpm->member_class,&tmpm->dim,
+            data_addr_rip,_base,data_heap,pass);
+      if (cc->token==',')
+        Lex(cc);
+      tmpm=tmpm->next;
+    }
+    LexPopNoRestore(cc);
+    if (cc->token!='}')
+      LexExcept(cc,"Missing '}' at ");
+    Lex(cc);
+  } else {
+    if (tmpc->ptr_stars_cnt==1 &&
+          ((tmpc-1)->raw_type==RT_I8 || (tmpc-1)->raw_type==RT_U8) &&
+          !tmpad && cc->token==TK_STR)
+      is_str=TRUE;
+    else
+      is_str=FALSE;
+    if (cc->flags&CCF_AOT_COMPILE && is_str) {
+      LexPopNoRestore(cc);
+      machine_code=LexExtStr(cc,&i);
+      if (pass==2) {
+        tmpa=CAlloc(sizeof(CAOTAbsAddr));
+        tmpa->next=aotc->abss;
+        tmpa->type=AAT_ADD_U64;
+        aotc->abss=tmpa;
+        tmpa->rip=data_addr_rip+dst-*_base;
+        *dst(I64 *)=aotc->rip;
+        for (j=0;j<i;j++)
+          AOTStoreCodeU8(cc,machine_code[j]);
+      }
+      Free(machine_code);
+    } else {
+      old_flags=cc->flags;
+      cc->flags=CCF_NO_ABSS | cc->flags &
+            ~(CCF_AOT_COMPILE|CCF_HAS_MISC_DATA|CCF_NOT_CONST);
+      machine_code=LexExpression2Bin(cc,&type);
+      if (old_flags&CCF_AOT_COMPILE &&
+            cc->flags&CCF_NOT_CONST &&
+            !Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)) {
+        cc->flags=cc->flags&~CCF_NO_ABSS|CCF_AOT_COMPILE;
+        Free(machine_code);
+        if (pass==2) {
+          MemSet(dst,0,tmpc->size);
+          LexPopRestore(cc);
+          Lex(cc);
+          COCPush(cc);
+          COCInit(cc);
+          ICAdd(cc,IC_ABS_ADDR,data_addr_rip,tmpc+1);
+          ICAdd(cc,IC_IMM_I64,dst-*_base,tmpc+1);
+          ICAdd(cc,IC_ADD,0,tmpc+1);
+          if (!PrsExpression(cc,NULL,TRUE))
+            throw('Compiler');
+          tmpi=cc->coc.coc_head.last;
+          if (tmpi->ic_code==IC_END_EXP) {
+            tmpi->ic_code=IC_NOP1;
+            tmpi->ic_flags=0;
+          }
+          ICAdd(cc,IC_ASSIGN,0,tmpc);
+          ICAdd(cc,IC_END_EXP,0,tmpc,ICF_RES_NOT_USED);
+          ICAdd(cc,IC_RET,0,0);
+          if (machine_code=COCCompile(cc,&size,NULL,NULL)) {
+            tmpie=CAlloc(sizeof(CAOTImportExport));
+            tmpie->type=IET_MAIN;
+            tmpie->rip=cc->aotc->rip;
+            QueIns(tmpie,cc->aot->last_ie);
+            for (i=0;i<size;i++)
+              AOTStoreCodeU8(cc,machine_code[i]);
+            Free(machine_code);
+          }
+          COCPop(cc);
+        } else
+          LexPopNoRestore(cc);
+      } else {
+        LexPopNoRestore(cc);
+        if (!machine_code)
+          throw('Compiler');
+        r=Call(machine_code);
+        if (!(cc->flags & CCF_HAS_MISC_DATA)||pass==1)
+          Free(machine_code);
+
+        if (type==RT_F64 &&
+              tmpc->raw_type!=RT_F64)
+          r=r(F64);
+        else if (type!=RT_F64 &&
+              tmpc->raw_type==RT_F64)
+          r(F64)=r;
+        MemCpy(dst,&r,tmpc->size);
+      }
+    }
+    dst+=tmpc->size;
+    cc->flags=cc->flags&
+          ~CCF_NO_ABSS|old_flags&(CCF_HAS_MISC_DATA|CCF_AOT_COMPILE);
+  }
+  *_dst=dst;
+}
+
+class CVI2
+{
+  CVI2 *next,*last;
+  U0 base;
+};
+
+U0 PrsVarInit2(CCmpCtrl *cc,U8 **_dst,CHashClass *tmpc,
+        CArrayDim *tmpad,U8 *data_addr_rip,U8 **_base,Bool data_heap,I64 pass)
+{
+  I64 i,j,cnt;
+  U8 *st,*_b;
+  CVI2 head,*tmpvi,*tmpvi1;
+  CArrayDim *tmpad1;
+  tmpc=OptClassFwd(tmpc);
+  if (tmpad1=tmpad->next) {
+    if (!tmpc->ptr_stars_cnt &&
+          (tmpc->raw_type==RT_I8 || tmpc->raw_type==RT_U8) &&
+          cc->token==TK_STR) {
+      LexPopNoRestore(cc);
+      st=LexExtStr(cc,&i);
+      if (tmpad1->cnt<0) {//[]
+        tmpad1->cnt=i;
+        tmpad->total_cnt=i*tmpad1->total_cnt;
+        Free(*_base);
+        if (data_heap)
+          *_base=MAlloc(i);
+        else
+          *_base=MAlloc(i,Fs->code_heap);
+        MemCpy(*_base,st,i);
+        *_dst=*_base+i;
+      } else {
+        MemCpy(*_dst,st,tmpad1->cnt);
+        *_dst+=tmpad1->cnt;
+      }
+      Free(st);
+      LexPush(cc);
+    } else {
+      if (cc->token=='{') {
+        LexPopNoRestore(cc);
+        LexPush(cc);
+        Lex(cc);
+      }
+      if (tmpad1->cnt<0) {//[]
+        QueInit(&head);
+        cnt=0;
+        while (cc->token!='}') {
+          tmpvi=MAlloc(offset(CVI2.base)+tmpad1->total_cnt*tmpc->size);
+          _b=&tmpvi->base;
+          PrsVarInit2(cc,&_b,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
+          QueIns(tmpvi,head.last);
+          if (cc->token==',')
+            Lex(cc);
+          cnt++;
+        }
+        Lex(cc); //skip '}'
+        tmpad1->cnt=cnt;
+        tmpad->total_cnt=cnt*tmpad1->total_cnt;
+        j=tmpad1->total_cnt*tmpc->size;
+        i=cnt*j;
+        Free(*_base);
+        if (data_heap)
+          *_base=_b=MAlloc(i);
+        else
+          *_base=_b=MAlloc(i,Fs->code_heap);
+        tmpvi=head.next;
+        while (tmpvi!=&head) {
+          tmpvi1=tmpvi->next;
+          MemCpy(_b,&tmpvi->base,j);
+          _b+=j;
+          Free(tmpvi);
+          tmpvi=tmpvi1;
+        }
+        *_dst=_b;
+      } else {
+        for (i=0;i<tmpad1->cnt;i++) {
+          PrsVarInit2(cc,_dst,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
+          if (tmpad1->cnt>1 && cc->token==',')
+            Lex(cc);
+        }
+        if (cc->token=='}')
+          Lex(cc);
+      }
+    }
+  } else {
+    PrsVarInit(cc,_dst,tmpc,tmpad1,data_addr_rip,_base,data_heap,pass);
+    LexPush(cc);
+  }
+}
+
+U0 PrsGlblInit(CCmpCtrl *cc,CHashGlblVar *tmpg,I64 pass)
+{
+  U8 *dst=tmpg->data_addr;
+  PrsVarInit2(cc,&dst,tmpg->var_class,&tmpg->dim,
+        tmpg->data_addr_rip,&tmpg->data_addr,
+        Bt(&cc->opts,OPTf_GLBLS_ON_DATA_HEAP)||
+        Bt(&cc->flags,CCf_AOT_COMPILE),pass);
+}
+
+U0 PrsStaticInit(CCmpCtrl *cc,CMemberLst *tmpm,I64 pass)
+{
+  U8 *machine_code,*dst=tmpm->static_data;
+  CHashClass *tmpc=tmpm->member_class;
+  I64 i,size;
+  CAOTImportExport *tmpie;
+
+  if (cc->flags&CCF_AOT_COMPILE && pass==2) {
+    COCPush(cc);
+    COCInit(cc);
+  }
+  PrsVarInit2(cc,&dst,tmpc,&tmpm->dim,tmpm->static_data_rip,
+        &tmpm->static_data,Bt(&cc->flags,CCf_AOT_COMPILE),pass);
+  if (cc->flags&CCF_AOT_COMPILE && pass==2) {
+    if (cc->coc.coc_head.next!=&cc->coc.coc_head) {
+      ICAdd(cc,IC_RET,0,0);
+      if (machine_code=COCCompile(cc,&size,NULL,NULL)) {
+        if (pass==2) {
+          tmpie=CAlloc(sizeof(CAOTImportExport));
+          tmpie->type=IET_MAIN;
+          tmpie->rip=cc->aotc->rip;
+          QueIns(tmpie,cc->aot->last_ie);
+          for (i=0;i<size;i++)
+            AOTStoreCodeU8(cc,machine_code[i]);
+        }
+        Free(machine_code);
+      }
+    } //TODO: else del misc?
+    COCPop(cc);
+  }
+}
+
+U0 PrsArrayDims(CCmpCtrl *cc,I64 mode,CArrayDim *dim)
+{//dim->next!=0 for array
+  CArrayDim *tmpad,*tmpad1;
+  I64 j;
+  dim->next=NULL;
+  dim->cnt=0;
+  dim->total_cnt=1;
+  tmpad1=&dim->next;
+  if (cc->token=='[') {
+    if (mode.u8[1]==PRS1B_FUN_ARG)
+      LexExcept(cc,"No arrays in fun args at ");
+    do {
+      if (Lex(cc)==']' && !dim->next)
+        j=0;
+      else {
+        if ((j=LexExpressionI64(cc))<0)
+          LexExcept(cc,"Invalid array size at ");
+      }
+      tmpad=MAlloc(sizeof(CArrayDim));
+      tmpad->next=NULL;
+      tmpad1=&dim;
+      do {
+        tmpad1->total_cnt*=j;
+        if (!tmpad1->next) {
+          tmpad1->next=tmpad;
+          break;
+        }
+        tmpad1=tmpad1->next;
+      } while (tmpad1);
+      tmpad1=tmpad;
+      tmpad->cnt=j;
+      tmpad->total_cnt=1;
+      if (cc->token!=']')
+        LexExcept(cc,"Missing ']' at ");
+    } while (Lex(cc)=='[');
+  }
+}
+
+CHashClass *PrsType(CCmpCtrl *cc,CHashClass **_tmpc1,
+  I64 *_mode,CMemberLst *tmpm,U8 **_ident,CHashFun **_fun_ptr,
+  CHashExport **_tmpex,CArrayDim *tmpad,I64 fsp_flags)
+{
+  I64 k,ptr_stars_cnt,mode=*_mode;
+  CHashClass *tmpc1=*_tmpc1,*tmpc2;
+  CHashFun *fun_ptr=NULL;
+  CHashExport *tmpex=NULL;
+
+  pt_start:
+  if (!tmpc1 || !(tmpc1->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+    LexExcept(cc,"Invalid class at ");
+
+  ptr_stars_cnt=0;
+  while (cc->token=='*') {
+    if (mode.u8[1]) {
+      LexPopNoRestore(cc);
+      LexPush(cc);
+    }
+    Lex(cc);
+    tmpc1++;
+    if (++ptr_stars_cnt>PTR_STARS_NUM)
+      LexExcept(cc,"Too many *'s at ");
+  }
+
+  k=PrsKeyWord(cc);
+  if (k==KW_UNION || k==KW_CLASS) {
+    Lex(cc);
+    tmpc2=PrsClass(cc,k,fsp_flags,mode&255==PRS0_EXTERN);
+    tmpc2->fwd_class=tmpc1;
+    tmpc1=tmpc2;
+    if (_tmpc1) *_tmpc1=tmpc1;
+    mode=PRS0_NULL|PRS1_NULL;
+    goto pt_start;
+  }
+
+  if (cc->token=='(') {
+    if (Lex(cc)!='*')
+      LexExcept(cc,"Expecting '*' at ");
+    ptr_stars_cnt=1; //fun_ptr
+    while (Lex(cc)=='*')
+      ptr_stars_cnt++; //fun_ptr
+    if (ptr_stars_cnt>PTR_STARS_NUM)
+      LexExcept(cc,"Too many *'s at ");
+  } else
+    ptr_stars_cnt=-1; //fun_ptr
+
+  if (_ident) {
+    if (cc->token==TK_IDENT) {
+      tmpex=cc->hash_entry;
+      *_ident=cc->cur_str;
+      cc->cur_str=NULL;
+      Lex(cc);
+    } else {
+      if (!mode.u8[1])
+        *_ident=NULL;
+      else if (cc->token==',' || cc->token==';' || cc->token==')') {
+        tmpex=NULL;
+        *_ident=StrNew("_anon_");
+        tmpm->flags|=MLF_NO_UNUSED_WARN;
+      } else
+        LexExcept(cc,"Expecting identifier at ");
+    }
+  }
+
+  if (ptr_stars_cnt>=0) { //fun_ptr
+    if (cc->token!=')')
+      LexExcept(cc,"Missing ')' at ");
+    if (Lex(cc)!='(')
+      LexExcept(cc,"Expecting '(' at ");
+    fun_ptr=PrsFunJoin(cc,tmpc1,NULL,fsp_flags)+ptr_stars_cnt;
+    tmpc1=cmp.internal_types[RT_PTR]+ptr_stars_cnt;
+  }
+  PrsArrayDims(cc,mode,tmpad);
+
+  tmpc2=OptClassFwd(tmpc1);
+  if (tmpc2->ptr_stars_cnt) {
+    tmpc2-=tmpc2->ptr_stars_cnt;
+    if (tmpc2->type&HTT_INTERNAL_TYPE && !tmpc2->size)
+      LexWarn(cc,"use \"U8 *\" instead of \"U0 *\" at ");
+  }
+
+  if (_mode)    *_mode=mode;
+  if (_fun_ptr) *_fun_ptr=fun_ptr;
+  if (_tmpex)   *_tmpex=tmpex;
+  return tmpc1;
+}
+
+U0 PrsDotDotDot(CCmpCtrl *cc,CHashFun *tmpf,I64 _reg)
+{
+  CMemberLst *tmpm;
+  CArrayDim *tmpad;
+
+  Bts(&tmpf->flags,Ff_DOT_DOT_DOT);
+
+  Lex(cc);
+  tmpm=MemberLstNew(_reg);
+  tmpm->flags=MLF_DOT_DOT_DOT;
+  tmpm->member_class=cmp.internal_types[RT_I64];
+  tmpm->str=StrNew("argc");
+  tmpm->offset=tmpf->size;
+  tmpm->size=8;
+  tmpf->size+=8;
+  MemberAdd(cc,tmpm,tmpf,PRS1B_FUN_ARG);
+
+  tmpm=MemberLstNew(_reg);
+  tmpm->flags=MLF_DOT_DOT_DOT;
+  tmpm->member_class=cmp.internal_types[RT_I64];
+  tmpm->str=StrNew("argv");
+  tmpm->dim.total_cnt=127; //arbitrary
+  tmpm->dim.next=tmpad=MAlloc(sizeof(CArrayDim));
+  tmpad->next=NULL;
+  tmpad->cnt=127; //arbitrary
+  tmpad->total_cnt=1;
+  tmpm->offset=tmpf->size;
+  tmpm->size=8; //Close enough
+  tmpf->size+=8;//Close enough
+  MemberAdd(cc,tmpm,tmpf,PRS1B_FUN_ARG);
+
+  if (cc->token==')')
+    Lex(cc);
+}
+
+U0 PrsVarLst(CCmpCtrl *cc,CHashClass *tmpc,I64 mode,I64 union_base=0)
+{
+  I64 i,k,old_flags=cc->flags,old_flags2,type,_reg;
+  CHashClass *tmpc1,*tmpc2;
+  CHash *tmph;
+  CMemberLst *tmpm;
+  CMemberLstMeta *tmp_meta;
+  U8 *machine_code;
+  Bool undef_array_size,first;
+  cc->flags|=CCF_DONT_MAKE_RES;
+  if (mode.u8[1]==PRS1B_CLASS)
+    cc->flags|=CCF_CLASS_DOL_OFFSET;
+  if ((mode.u8[1]!=PRS1B_LOCAL_VAR && mode.u8[1]!=PRS1B_STATIC_LOCAL_VAR ||
+        mode&PRSF_UNION) && (cc->token=='(' || cc->token=='{'))
+    Lex(cc);
+  while (TRUE) {
+    if (mode&PRSF_UNION)
+      cc->class_dol_offset=union_base;
+    else
+      cc->class_dol_offset=tmpc->size;
+    while (cc->token==';')
+      Lex(cc);
+    while (cc->token=='$') {
+      if (Lex(cc)!='=') //skip $
+        LexExcept(cc,"Expecting '=' at ");
+      Lex(cc); //skip =
+      cc->class_dol_offset=LexExpression(cc);
+      if (-cc->class_dol_offset>tmpc->neg_offset)
+        tmpc->neg_offset=-cc->class_dol_offset;
+      if (mode&PRSF_UNION)
+        union_base=cc->class_dol_offset;
+      else
+        tmpc->size=cc->class_dol_offset;
+      if (cc->token!=';')
+        LexExcept(cc,"Missing ';' at");
+      Lex(cc); //skip ;
+    }
+    if (cc->token==')' || cc->token=='}') {
+      Lex(cc);
+      goto pvl_done;
+    }
+    _reg=REG_UNDEF;
+pvl_restart1:
+    switch (PrsKeyWord(cc)) {
+      case KW_REG:
+        _reg=REG_ALLOC;
+        if (Lex(cc)==TK_IDENT) {
+          k=DefineMatch(cc->cur_str,"ST_U64_REGS");
+          if (k>=0) {
+            _reg=k;
+            Lex(cc);
+          }
+        }
+        goto pvl_restart1;
+      case KW_NOREG:
+        _reg=REG_NONE;
+        Lex(cc);
+        goto pvl_restart1;
+    }
+
+    if (cc->token==TK_ELLIPSIS && mode.u8[1]==PRS1B_FUN_ARG) {
+      PrsDotDotDot(cc,tmpc,_reg);
+      goto pvl_done;
+    }
+    if (cc->token==TK_IDENT)
+      tmph=cc->hash_entry;
+    else
+      tmph=NULL;
+    if (!tmph)
+      LexExcept(cc,"Expecting type at ");
+    k=PrsKeyWord(cc);
+    if (k==KW_UNION) {
+      Lex(cc);
+      PrsVarLst(cc,tmpc,mode|PRSF_UNION,tmpc->size);
+    } else {
+      if (!(tmph->type & (HTT_CLASS|HTT_INTERNAL_TYPE)))
+        LexExcept(cc,"Expecting type at ");
+      first=TRUE;
+pvl_restart2:
+      tmpc1=tmph;
+      LexPush(cc);
+      Lex(cc); //skip type or ','
+      tmpm=MemberLstNew(_reg);
+      _reg=REG_UNDEF;
+      if (mode.u8[1]==PRS1B_STATIC_LOCAL_VAR) {
+        tmpm->flags|=MLF_STATIC;
+        tmpm->reg=REG_NONE;
+      }
+      if (mode.u8[1]==PRS1B_FUN_ARG || mode.u8[1]==PRS1B_LOCAL_VAR) {
+pvl_restart3:
+        switch (PrsKeyWord(cc)) {
+          case KW_REG:
+            tmpm->reg=REG_ALLOC;
+            LexPopNoRestore(cc);
+            LexPush(cc);
+            if (Lex(cc)==TK_IDENT) {
+              k=DefineMatch(cc->cur_str,"ST_U64_REGS");
+              if (k>=0) {
+                tmpm->reg=k;
+                LexPopNoRestore(cc);
+                LexPush(cc);
+                Lex(cc);
+              }
+            }
+            goto pvl_restart3;
+          case KW_NOREG:
+            tmpm->reg=REG_NONE;
+            LexPopNoRestore(cc);
+            LexPush(cc);
+            Lex(cc);
+            goto pvl_restart3;
+        }
+      }
+      tmpm->member_class=PrsType(cc,&tmpc1,&mode,tmpm,&tmpm->str,
+            &tmpm->fun_ptr,NULL,&tmpm->dim,0);
+      if (tmpm->fun_ptr)
+        tmpm->flags|=MLF_FUN;
+      if (first)
+        MemberAdd(cc,tmpm,tmpc,mode.u8[1]);
+      else
+        MemberAdd(cc,tmpm,tmpc,PRS1B_NULL);
+      tmpc->member_cnt++;
+
+      tmpc2=tmpm->member_class;
+      i=tmpc2->size*tmpm->dim.total_cnt;
+      switch (mode.u8[1]) {
+        case PRS1B_STATIC_LOCAL_VAR:
+          if (i<0) {
+            i=0;
+            undef_array_size=TRUE;
+          } else
+            undef_array_size=FALSE;
+          if (mode&PRSF_UNION)
+            LexExcept(cc,"Static unions are not implemented ");
+          k=(i+7)&~7;
+          if (cc->flags&CCF_AOT_COMPILE)
+            tmpm->static_data=MAlloc(k);
+          else
+            tmpm->static_data=MAlloc(k,Fs->code_heap);
+          if (cc->flags&CCF_AOT_COMPILE)        {
+            tmpm->static_data_rip=cc->aotc->rip;
+            k>>=3;
+            while (k--)
+              AOTStoreCodeU64(cc,0);
+          } else
+            if (sys_var_init_flag)
+              MemSet(tmpm->static_data,sys_var_init_val,k);
+          LexPopNoRestore(cc);
+          if (cc->token=='=') {
+            cc->flags=cc->flags&
+                  ~CCF_DONT_MAKE_RES|old_flags&CCF_DONT_MAKE_RES;
+            if (undef_array_size) {
+              LexPush(cc);
+              LexPush(cc);
+              Lex(cc); //skip =
+              PrsStaticInit(cc,tmpm,1);
+              LexPopNoRestore(cc);
+              i=tmpc2->size*tmpm->dim.total_cnt;
+              k=(i+7)&~7;
+              if (cc->flags&CCF_AOT_COMPILE)    {
+                k>>=3;
+                while (k--)
+                  AOTStoreCodeU64(cc,0);
+              } else
+                if (sys_var_init_flag)
+                  MemSet(tmpm->static_data,sys_var_init_val,k);
+              LexPopRestore(cc);
+            }
+            LexPush(cc);
+            Lex(cc); //skip =
+            PrsStaticInit(cc,tmpm,2);
+            LexPopNoRestore(cc);
+            if (cc->flags&CCF_AOT_COMPILE)
+              for (k=0;k<i;k++)
+                AOTStoreCodeU8At(cc,tmpm->static_data_rip+k,
+                      tmpm->static_data[k]);
+            tmpm->use_cnt=0;
+            cc->flags|=CCF_DONT_MAKE_RES;
+          }
+          if (cc->flags&CCF_AOT_COMPILE)
+            Free(tmpm->static_data);
+          break;
+        case PRS1B_LOCAL_VAR:
+          if (mode&PRSF_UNION) {
+            if (union_base-tmpc->size<i)
+              i=union_base-i-tmpc->size;
+            else
+              i=0;
+          }
+          if (i>=8)
+            tmpc->size=(tmpc->size-i)&~7;
+          else if (i>=4)
+            tmpc->size=(tmpc->size-i)&~3;
+          else if (i>=2)
+            tmpc->size=(tmpc->size-i)&~1;
+          else
+            tmpc->size-=i;
+          tmpm->offset=tmpc->size;
+          tmpm->size=i;
+          if (cc->token=='=') {
+            cc->flags=cc->flags&~CCF_DONT_MAKE_RES|
+                  old_flags&CCF_DONT_MAKE_RES;
+            LexPopRestore(cc);
+            Lex(cc);
+            if (!PrsExpression(cc,NULL,TRUE))
+              throw('Compiler');
+            tmpm->use_cnt=0;
+            cc->flags|=CCF_DONT_MAKE_RES;
+          } else
+            LexPopNoRestore(cc);
+          break;
+        case PRS1B_FUN_ARG:
+          if (mode&PRSF_UNION) {
+            tmpm->offset=union_base;
+            if (tmpc->size-union_base<8)
+              tmpc->size=8+union_base;
+          } else {
+            tmpm->offset=tmpc->size;
+            tmpc->size+=8;
+          }
+          tmpm->size=8;
+          if (cc->token=='=') {
+            Lex(cc);
+            if (PrsKeyWord(cc)==KW_LASTCLASS) {
+              tmpm->flags|=MLF_LASTCLASS;
+              Lex(cc);
+            } else {
+              old_flags2=cc->flags;
+              cc->flags&=~CCF_HAS_MISC_DATA;
+              machine_code=LexExpression2Bin(cc,&type);
+              if (!machine_code)
+                throw('Compiler');
+              tmpm->dft_val=Call(machine_code);
+              tmpc2=OptClassFwd(tmpc2);
+              if (tmpc2->raw_type==RT_F64) {
+                if (type!=RT_F64)
+                  tmpm->dft_val(F64)=tmpm->dft_val;
+              } else {
+                if (type==RT_F64)
+                  tmpm->dft_val=tmpm->dft_val(F64);
+              }
+              if (cc->flags & CCF_HAS_MISC_DATA) {
+                tmpm->dft_val=StrNew(tmpm->dft_val);
+                tmpm->flags|=MLF_STR_DFT_AVAILABLE;
+              }
+              Free(machine_code);
+              cc->flags|=old_flags2&CCF_HAS_MISC_DATA;
+            }
+            tmpm->flags|=MLF_DFT_AVAILABLE;
+          }
+          LexPopNoRestore(cc);
+          break;
+        case PRS1B_CLASS:
+          if (mode&PRSF_UNION) {
+            tmpm->offset=union_base;
+            if (tmpc->size-union_base<i)
+              tmpc->size=i+union_base;
+          } else {
+            tmpm->offset=tmpc->size;
+            tmpc->size+=i;
+          }
+          tmpm->size=i;
+          if (mode&PRSF_UNION)
+            cc->class_dol_offset=union_base;
+          else
+            cc->class_dol_offset=tmpc->size;
+
+          while (cc->token==TK_IDENT) {
+            tmp_meta=MAlloc(sizeof(CMemberLstMeta));
+            tmp_meta->next=tmpm->meta;
+            tmpm->meta=tmp_meta;
+            tmp_meta->str=cc->cur_str;
+            tmp_meta->flags=0;
+            cc->cur_str=NULL;
+            if (Lex(cc)==TK_STR) {
+              tmp_meta->user_data=LexExtStr(cc);
+              tmp_meta->flags|=MLMF_IS_STR;
+            } else
+              tmp_meta->user_data=LexExpression(cc);
+          }
+          LexPopNoRestore(cc);
+          break;
+      }
+      switch (cc->token) {
+        case ',':
+          if (mode.u8[1]==PRS1B_FUN_ARG && !(mode&PRSF_UNION))
+            Lex(cc);
+          else {
+            first=FALSE;
+            goto pvl_restart2;
+          }
+          break;
+        case ')':
+        case '}':
+          Lex(cc);
+          goto pvl_done;
+        case ';':
+          cc->flags=cc->flags&~CCF_DONT_MAKE_RES|
+                old_flags&CCF_DONT_MAKE_RES;
+          Lex(cc);
+          cc->flags|=CCF_DONT_MAKE_RES;
+          if ((mode.u8[1]==PRS1B_LOCAL_VAR||mode.u8[1]==
+                PRS1B_STATIC_LOCAL_VAR) && !(mode&PRSF_UNION))
+            goto pvl_done;
+          break;
+        default:
+          LexExcept(cc,"Missing ';' at");
+      }
+    }
+  }
+pvl_done:
+  cc->flags=cc->flags&~(CCF_CLASS_DOL_OFFSET|CCF_DONT_MAKE_RES)|
+        old_flags&(CCF_CLASS_DOL_OFFSET|CCF_DONT_MAKE_RES);
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/Templates.HC.HTML b/public/Wb/Home/Src/Compiler/Templates.HC.HTML new file mode 100755 index 0000000..4afeb40 --- /dev/null +++ b/public/Wb/Home/Src/Compiler/Templates.HC.HTML @@ -0,0 +1,543 @@ + + + + + + + + + + + +
+asm {
+//************************************
+CMP_TEMPLATES::
+        DU32    @@05,@@10,@@15,@@25,@@30,
+                @@35,@@40,@@45,@@55,@@60,
+                @@75,@@80,@@85,@@90,@@95,
+                @@100,@@105,@@110,@@120,@@130;
+
+@@05:   //INC
+        PUSH    RAX
+        FLD1
+        FADD    ST0,U64 [RSP]
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        PUSH    RAX
+        FLD1
+        FSUBR   ST0,U64 [RSP]
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@15:   //MOD
+        PUSH    RDX
+        PUSH    RAX
+        MOV     RBX,RSP
+        FLD     U64 [RBX]
+        FLD     U64 8[RBX]
+@@20:   FPREM
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@20
+        FSTP    U64 [RBX]
+        FFREE   ST0
+        FINCSTP
+        POP     RAX
+        ADD     RSP,8
+
+@@25:   //LESS
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD     U64 8[RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@30:   //GREATER
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 8[RSP]
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@35:   //LESS_EQU
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 8[RSP]
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@40:   //GREATER_EQU
+        PUSH    RDX
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD     U64 8[RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,16
+
+@@45: //StrLen
+        MOV     RDX,RAX
+@@50:   MOV     BL,U8 [RAX]
+        INC     RAX
+        TEST    BL,BL
+        JNZ     @@50
+        SUB     RAX,RDX
+        DEC     RAX
+
+@@55: //RDTSC
+        RDTSC
+        SHL     RDX,32
+        ADD     RAX,RDX
+
+@@60: //SignI64
+        TEST    RAX,RAX
+        JZ      @@70
+        JS      @@65
+        MOV     RAX,1
+        JMP     @@70
+@@65:   MOV     RAX,-1
+@@70:
+@@75:
+@@80:
+@@85: //Sqr
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FMUL    ST0,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@90: //Abs
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FABS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@95: //Sqrt
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSQRT
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@100: //Sin
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSIN
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@105: //Cos
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@110: //Tan
+        PUSH    RAX
+        FLD     U64 [RSP]
+@@115:  FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@115
+        FFREE   ST0
+        FINCSTP
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@120: //Atan
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD1
+@@125:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@125
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@130:
+
+//************************************
+CMP_TEMPLATES_DONT_POP::
+        DU32    @@05,@@10,@@15,@@20,@@25,
+                @@30,@@35,@@40,@@45,@@50,
+                @@55,@@60,@@65,@@70,@@75,
+                @@80,@@85,@@90,@@100,@@110;
+
+@@05:   //INC
+        PUSH    RAX
+        FLD1
+        FADD    ST0,U64 [RSP]
+        FST     U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        PUSH    RAX
+        FLD1
+        FSUBR   ST0,U64 [RSP]
+        FST     U64 [RSP]
+        POP     RAX
+
+@@15:
+@@20:
+@@25:
+@@30:
+@@35:
+@@40:
+@@45:
+@@50:
+@@55:
+@@60:
+        PUSH    RAX
+        FLD     U64 [RSP]
+        ADD     RSP,8
+
+@@65: //Sqr
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FMUL    ST0,ST0
+        ADD     RSP,8
+
+@@70: //Abs
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FABS
+        ADD     RSP,8
+
+@@75: //Sqrt
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSQRT
+        ADD     RSP,8
+
+@@80: //Sin
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FSIN
+        ADD     RSP,8
+
+@@85: //Cos
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOS
+        ADD     RSP,8
+
+@@90: //Tan
+        PUSH    RAX
+        FLD     U64 [RSP]
+@@95:   FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@95
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@100: //Atan
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FLD1
+@@105:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@105
+        ADD     RSP,8
+@@110:
+
+//************************************
+CMP_TEMPLATES_DONT_PUSH::
+        DU32    @@05,@@10,@@15,@@20,@@30,
+                @@35,@@40,@@50,@@55,@@60,
+                @@65,@@70,@@75,@@80,@@85,
+                @@90,@@95,@@100,@@110,@@120;
+
+@@05:   //INC
+        SUB     RSP,8
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        SUB     RSP,8
+        FLD1
+        FSUBP   ST1,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@15:
+@@20:   //LESS
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        JZ      @@25
+        MOV     RAX,1
+        SBB     RAX,0
+@@25:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@30:   //GREATER
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@35:   //LESS_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@40:   //GREATER_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        JZ      @@45
+        MOV     RAX,0
+        ADC     RAX,0
+@@45:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+@@50:
+@@55:
+@@60:
+@@65: //FSTP
+        SUB     RSP,8
+        FSTP    U64 [RSP]
+        POP     RAX
+@@70:
+@@75: //Sqr
+        SUB     RSP,8
+        FMUL    ST0,ST0
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@80: //Abs
+        SUB     RSP,8
+        FABS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@85: //Sqrt
+        SUB     RSP,8
+        FSQRT
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@90: //Sin
+        SUB     RSP,8
+        FSIN
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@95: //Cos
+        SUB     RSP,8
+        FCOS
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@100: //Tan
+        SUB     RSP,8
+@@105:  FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@105
+        FFREE   ST0
+        FINCSTP
+        FSTP    U64 [RSP]
+        POP     RAX
+
+@@110: //Atan
+        SUB     RSP,8
+        FLD1
+@@115:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@115
+        FSTP    U64 [RSP]
+        POP     RAX
+@@120:
+
+//************************************
+CMP_TEMPLATES_DONT_PUSH_POP::
+        DU32    @@05,@@10,@@15,@@20,@@25,
+                @@30,@@35,@@40,@@45,@@50,
+                @@55,@@60,@@65,@@70,@@75,
+                @@80,@@85,@@90,@@95,@@105;
+
+@@05:   //INC
+        SUB     RSP,8
+        FLD1
+        FADDP   ST1,ST0
+        FST     U64 [RSP]
+        POP     RAX
+
+@@10:   //DEC
+        SUB     RSP,8
+        FLD1
+        FSUBP   ST1,ST0
+        FST     U64 [RSP]
+        POP     RAX
+
+@@15:
+@@20:
+@@25:
+@@30:
+@@35:
+@@40:
+@@45:
+@@50:
+@@55:
+@@60:
+@@65: //Sqr
+        FMUL    ST0,ST0
+
+@@70: //Abs
+        FABS
+
+@@75: //Sqrt
+        FSQRT
+
+@@80: //Sin
+        FSIN
+
+@@85: //Cos
+        FCOS
+
+@@90: //Tan
+        FPTAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@90
+        FFREE   ST0
+        FINCSTP
+
+@@95: //Atan
+        FLD1
+@@100:  FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@100
+@@105:
+
+//************************************
+CMP_TEMPLATES_DONT_PUSH2::
+        DU32    @@05,@@10,@@15,@@20,@@25,
+                @@35,@@45,@@50,@@55,@@60,
+                @@65,@@70,@@75,@@80,@@85,
+                @@90,@@95,@@100,@@105,@@110;
+
+@@05:
+@@10:
+
+@@15:
+@@20:   //LESS
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        ADC     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@25:   //GREATER
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,0
+        JZ      @@30
+        MOV     RAX,1
+        SBB     RAX,0
+@@30:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@35:   //LESS_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        JZ      @@40
+        MOV     RAX,0
+        ADC     RAX,0
+@@40:   FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+
+@@45:   //GREATER_EQU
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCOMIP  ST0,ST1
+        MOV     RAX,1
+        SBB     RAX,0
+        FFREE   ST0
+        FINCSTP
+        ADD     RSP,8
+@@50:
+@@55:
+@@60:
+@@65:
+@@70:
+@@75:
+@@80:
+@@85:
+@@90:
+@@95:
+@@100:
+@@105:
+@@110:
+}
+
+ diff --git a/public/Wb/Home/Src/Compiler/UAsm.HC.HTML b/public/Wb/Home/Src/Compiler/UAsm.HC.HTML new file mode 100755 index 0000000..563dd4d --- /dev/null +++ b/public/Wb/Home/Src/Compiler/UAsm.HC.HTML @@ -0,0 +1,713 @@ + + + + + + + + + + + +
+I64 InstEntriesCompare(CInst *tmpins1,CInst *tmpins2)
+{
+  I64 i1,i2,j=0,res=0,oc_cnt1=tmpins1->opcode_cnt,oc_cnt2=tmpins2->opcode_cnt;
+  if (tmpins1->flags&IEF_STI_LIKE)
+    oc_cnt1--;
+  if (tmpins2->flags&IEF_STI_LIKE)
+    oc_cnt2--;
+  while (TRUE) {
+    if (j<oc_cnt1 && j<oc_cnt2) {
+      if (res=tmpins1->opcode[j]-tmpins2->opcode[j])
+        return res;
+      j++;
+    } else {
+      if (res=oc_cnt1-oc_cnt2)
+        return res;
+
+      if (tmpins1->flags&IEF_STI_LIKE && tmpins2->flags&IEF_STI_LIKE)
+        return tmpins1->opcode[j]-tmpins2->opcode[j];
+
+      if (res=tmpins1->flags&IEF_STI_LIKE - tmpins2->flags&IEF_STI_LIKE)
+        return res;
+
+      if (res=tmpins1->slash_val-tmpins2->slash_val)
+        return res;
+
+      if (res=tmpins1->flags&IEF_OP_SIZE32 - tmpins2->flags&IEF_OP_SIZE32)
+        return res;
+
+      i1=Bt(&uasm.ins64_arg_mask,tmpins1->arg1) ||
+            Bt(&uasm.ins64_arg_mask,tmpins1->arg2);
+      i2=Bt(&uasm.ins64_arg_mask,tmpins2->arg1) ||
+            Bt(&uasm.ins64_arg_mask,tmpins2->arg2);
+      if (res=i1-i2)
+        return res;
+
+      if (res=tmpins1->flags&IEF_48_REX - tmpins2->flags&IEF_48_REX)
+        return res;
+
+      i1=tmpins1->arg2==ARGT_IMM64 || tmpins1->arg2==ARGT_UIMM64;
+      i2=tmpins2->arg2==ARGT_IMM64 || tmpins2->arg2==ARGT_UIMM64;
+      return i1-i2;
+    }
+  }
+}
+
+/*
+U0 DumpUAsmIns(CInst *tmpins)
+{
+  CHashOpcode *tmpo=tmpins(U8 *)-tmpins->ins_entry_num*sizeof(CInst)
+  -offset(CHashOpcode.ins);
+  "%10s:%02d,%02d SV:%02d\n",tmpo->str,
+        tmpins->arg1,tmpins->arg2,tmpins->slash_val;
+}
+U0 DumpUAsmTables()
+{
+  I64 k;
+  "16/32 Bit Table\n";
+  for (k=0;k<uasm.table_16_32_entries;k++)
+    DumpUAsmIns(uasm.table_16_32[k]);
+  "\n\n\n\n64 Bit Table\n";
+  for (k=0;k<uasm.table_64_entries;k++)
+    DumpUAsmIns(uasm.table_64[k]);
+}
+*/
+
+CInst *InstEntryFind(U8 *rip,I64 opsize,I64 seg_size)
+{//Binary Search
+  I64 i,j,n,m,k,arg1,arg2,o1,o2,oc_cnt;
+  CInst *tmpins,**table;
+  i=0;
+  if (seg_size==64) {
+    table=uasm.table_64;
+    j=uasm.table_64_entries-1;
+  } else {
+    table=uasm.table_16_32;
+    j=uasm.table_16_32_entries-1;
+  }
+  while (TRUE) {
+    k=(i+j)>>1;  //binary search
+    tmpins=table[k];
+//DumpUAsmIns(tmpins);
+    m=0;
+    n=0;
+    while (TRUE) { //ief_compare_start
+      arg1=tmpins->arg1;
+      arg2=tmpins->arg2;
+      oc_cnt=tmpins->opcode_cnt;
+      if (tmpins->flags&IEF_STI_LIKE)
+        oc_cnt--;
+      if (n<oc_cnt) {
+        o1=rip[n];
+        if (n==tmpins->opcode_cnt-1 && tmpins->flags & IEF_PLUS_OPCODE)
+          o1&=-8;
+        o2=tmpins->opcode[n++];
+        if (m=o1-o2)
+          goto ief_compare_done;
+      } else
+        switch [tmpins->uasm_slash_val] {
+          case 0...7:
+            if (!(m=rip[n]>>3&7-tmpins->slash_val)) {
+              if ((Bt(&uasm.mem_arg_mask,arg1) ||
+                    Bt(&uasm.mem_arg_mask,arg2)) &&
+                    rip[n]&0xC0==0xC0) {
+                m=1;
+                goto ief_compare_done;
+              }
+              if (opsize==16) {
+                if (tmpins->flags & IEF_OP_SIZE32) {
+                  m=-1;
+                  goto ief_compare_done;
+                }
+              } else {
+                if (tmpins->flags & IEF_OP_SIZE16) {
+                  m=1;
+                  goto ief_compare_done;
+                }
+              }
+              if (opsize==64||arg1==ARGT_M64||arg2==ARGT_M64) {
+                if (!Bt(&uasm.ins64_arg_mask,arg1)&&
+                      !Bt(&uasm.ins64_arg_mask,arg2)&&
+                      !(tmpins->flags&IEF_48_REX))
+                  m=1;
+              } else {
+                if (Bt(&uasm.ins64_arg_mask,arg1)||
+                      Bt(&uasm.ins64_arg_mask,arg2) ||
+                      tmpins->flags&IEF_48_REX)
+                  m=-1;
+              }
+            } else if ((Bt(&uasm.mem_arg_mask,arg1)||
+                  Bt(&uasm.mem_arg_mask,arg2)) &&
+                  rip[n]&0xC0==0xC0)
+              m=1;
+            goto ief_compare_done;
+          case SV_I_REG:
+            m=rip[n]>>3-tmpins->opcode[tmpins->opcode_cnt-1]>>3;
+            goto ief_compare_done;
+          case SV_STI_LIKE:
+            if (!(m=rip[n]>>3-tmpins->opcode[tmpins->opcode_cnt-1]>>3))
+              m=rip[n]-tmpins->opcode[tmpins->opcode_cnt-1];
+            goto ief_compare_done;
+          case SV_R_REG:
+          case SV_NONE:
+            m=0;
+            if (opsize==16) {
+              if (tmpins->flags & IEF_OP_SIZE32) {
+                m=-1;
+                goto ief_compare_done;
+              }
+            } else {
+              if (tmpins->flags & IEF_OP_SIZE16) {
+                m=1;
+                goto ief_compare_done;
+              }
+            }
+            if (opsize==64 || arg1==ARGT_M64 || arg2==ARGT_M64) {
+              if (!Bt(&uasm.ins64_arg_mask,arg1) &&
+                    !Bt(&uasm.ins64_arg_mask,arg2) &&
+                    !(tmpins->flags&IEF_48_REX)&& !(arg2==ARGT_NONE &&
+                    (ARGT_UIMM8<=arg1<=ARGT_UIMM64 ||
+                    ARGT_IMM8<=arg1<=ARGT_IMM64)))
+                m=1;
+              else if (tmpins->arg2==ARGT_IMM64 || tmpins->arg2==ARGT_UIMM64) {
+                if (arg2!=ARGT_IMM64&&arg2!=ARGT_UIMM64)
+                  m=1;
+              } else if (arg2==ARGT_IMM64||arg2==ARGT_UIMM64)
+                m=-1;
+            } else {
+              if (Bt(&uasm.ins64_arg_mask,arg1) ||
+                    Bt(&uasm.ins64_arg_mask,arg2) ||
+                    tmpins->flags&IEF_48_REX)
+                m=-1;
+            }
+            goto ief_compare_done;
+        }
+    }
+ief_compare_done:
+    if (m>0) {
+      if (k==i) {
+        k=j;
+        break;
+      } else
+        i=k;
+    } else if (m<0) {
+      if (k-i<=1) {
+        k=i;
+        break;
+      } else
+        j=k;
+    } else
+      break;
+  }
+  return table[k];
+}
+
+U0 UAsmHashLoad()
+{
+  CHashOpcode *tmph;
+  CInst *tmpins;
+  I64 i,j1,j2,k;
+
+  uasm.ins64_arg_mask=0x0880888880+1<<ARGT_ST0+1<<ARGT_STI;
+  uasm.signed_arg_mask=1<<ARGT_REL8+1<<ARGT_REL16+1<<ARGT_REL32+
+        1<<ARGT_IMM8+1<<ARGT_IMM16+1<<ARGT_IMM32+1<<ARGT_IMM64;
+  uasm.mem_arg_mask=1<<ARGT_M8+1<<ARGT_M16+1<<ARGT_M32+1<<ARGT_M64;
+
+  uasm.table_16_32_entries=uasm.table_64_entries=0;
+  for (i=0;i<=cmp.asm_hash->mask;i++) {
+    tmph=cmp.asm_hash->body[i];
+    while (tmph) {
+      if (tmph->type==HTT_OPCODE && !(tmph->oc_flags&OCF_ALIAS)) {
+        tmpins=&tmph->ins;
+        for (k=0;k<tmph->inst_entry_cnt;k++) {
+          uasm.table_16_32_entries++;
+          if (!(tmpins->flags&IEF_NOT_IN_64_BIT))
+            uasm.table_64_entries++;
+          tmpins++;
+        }
+      }
+      tmph=tmph->next;
+    }
+  }
+
+  j1=j2=0;
+  uasm.table_16_32=MAlloc(uasm.table_16_32_entries*sizeof(U8 *));
+  uasm.table_64   =MAlloc(uasm.table_64_entries   *sizeof(U8 *));
+  for (i=0;i<=cmp.asm_hash->mask;i++) {
+    tmph=cmp.asm_hash->body[i];
+    while (tmph) {
+      if (tmph->type==HTT_OPCODE && !(tmph->oc_flags&OCF_ALIAS)) {
+        tmpins=&tmph->ins;
+        for (k=0;k<tmph->inst_entry_cnt;k++) {
+          uasm.table_16_32[j1++]=tmpins;
+          if (!(tmpins->flags&IEF_NOT_IN_64_BIT))
+            uasm.table_64[j2++]=tmpins;
+          tmpins++;
+        }
+      }
+      tmph=tmph->next;
+    }
+  }
+  QSortI64(uasm.table_16_32,uasm.table_16_32_entries,&InstEntriesCompare);
+  QSortI64(uasm.table_64   ,uasm.table_64_entries   ,&InstEntriesCompare);
+}
+
+U0 Ui(U8 *buf,U8 **_rip,I64 seg_size=64,I64 *_jmp_dst=NULL,Bool just_ins=FALSE)
+{//Unassembles one inst
+  I64 i,disp,imm,opsize,opadd,
+        arg1,arg2,reloced_arg1,reloced_arg2,
+        arg1_size=0,arg2_size=0,reloced_arg1_size,reloced_arg2_size,
+        ModrM=-1,SIB=-1,scale,r1,r2,
+        Mod=-1,RM1=-1,RM2=-1,REX=-1,REX_r=0,REX_x=0,REX_b=0;
+  Bool cont;
+  CInst *tmpins,*tmpins2;
+  CHashOpcode *tmpo;
+  U8 *rip=*_rip,*ptr,*reloced_arg1_st,*reloced_arg2_st,
+        *bin_data_area1,*bin_data_area2,
+        line1[512],line2[512],buf2[512],arg1_st[512],
+        arg2_st[512],seg_overrides[32];
+
+  if (_jmp_dst) *_jmp_dst=-1;
+  if (seg_size==16) {
+    opsize=16;
+    opadd=16;
+  } else if (seg_size==32) {
+    opsize=32;
+    opadd=32;
+  } else {
+    opsize=32;
+    opadd=64;
+  }
+  *arg1_st=0;
+  *arg2_st=0;
+  if (!IsRaw && PutSrcLink(rip,1,line1))
+    CatPrint(line1,"\n");
+  else
+    *line1=0;
+
+  StrPrint(line1+StrLen(line1),"%24tp ",rip);
+  bin_data_area1=line1+StrLen(line1);
+  for (i=0;i<6;i++)
+    CatPrint(line1,"%02X",rip[i]);
+  CatPrint(line1," ");
+
+  StrPrint(line2,"%24tp ",rip+6);
+  bin_data_area2=line2+StrLen(line2);
+  for (i=6;i<12;i++)
+    CatPrint(line2,"%02X",rip[i]);
+
+  *seg_overrides=0;
+  cont=TRUE;
+  while (TRUE) {
+    switch (*rip) {
+      case 0x2E: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"CS:"); break;
+      case 0x36: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"SS:"); break;
+      case 0x3E: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"DS:"); break;
+      case 0x26: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"ES:"); break;
+      case 0x64: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"FS:"); break;
+      case 0x65: if (StrLen(seg_overrides)<24)
+          CatPrint(seg_overrides,"GS:"); break;
+      case OC_OP_SIZE_PREFIX:
+        if (opsize==16)
+          opsize=32;
+        else
+          opsize=16;
+        break;
+      case OC_ADDR_SIZE_PREFIX:
+        if (opadd==16)
+          opadd=32;
+        else
+          opadd=16;
+        break;
+      case 0x40...0x4F:
+        if (seg_size==64) {
+          REX=*rip;
+          if (REX>=0x48)
+            opsize=64;
+          REX_b=Bt(&REX,0)<<3;
+          REX_x=Bt(&REX,1)<<3;
+          REX_r=Bt(&REX,2)<<3;
+          break;
+        } //Fall thru if !64
+      default:
+        cont=FALSE;
+    }
+    if (cont)
+      rip++;
+    else
+      break;
+  }
+
+  tmpins=InstEntryFind(rip,opsize,seg_size);
+  if (opsize==32 && seg_size==64) {
+    tmpins2=InstEntryFind(rip,64,seg_size);
+    if (tmpins2!=tmpins && tmpins2->flags&IEF_REX_ONLY_R8_R15 ||
+          tmpins2->flags&IEF_REX_XOR_LIKE&& rip[1]>>3&7==rip[1]&7)
+      tmpins=tmpins2;
+  }
+
+  rip+=tmpins->opcode_cnt;
+  tmpo=tmpins(U8 *)-tmpins->ins_entry_num*sizeof(CInst)
+  -offset(CHashOpcode.ins);
+  if (just_ins)
+    *line1=0;
+  CatPrint(line1,tmpo->str);
+
+  arg1=tmpins->arg1;
+  arg2=tmpins->arg2;
+
+  if (arg1_size=tmpins->size1) {
+    if (Bt(&uasm.signed_arg_mask,arg1))
+      CatPrint(arg1_st,"I%d ",arg1_size);
+    else
+      CatPrint(arg1_st,"U%d ",arg1_size);
+  }
+
+  if (arg2_size=tmpins->size2) {
+    if (Bt(&uasm.signed_arg_mask,arg2))
+      CatPrint(arg2_st,"I%d ",arg2_size);
+    else
+      CatPrint(arg2_st,"U%d ",arg2_size);
+  }
+
+  if (tmpins->flags & IEF_PLUS_OPCODE) {
+    rip--;
+    RM1=*rip++ - tmpins->opcode[tmpins->opcode_cnt-1]+REX_b;
+    ptr=NULL;
+    if (ARGT_R8<=arg1<=ARGT_R64) {
+      if (arg1_size==8) {
+        if (REX!=-1)
+          ptr="ST_U8_REX_REGS";
+        else
+          ptr="ST_U8_REGS";
+      } else if (arg1_size==16)
+        ptr="ST_U16_REGS";
+      else if (arg1_size==32)
+        ptr="ST_U32_REGS";
+      else if (arg1_size==64)
+        ptr="ST_U64_REGS";
+      if (ptr)
+        CatPrint(arg1_st,"%Z",RM1,ptr);
+    } else {
+      if (arg2_size==8) {
+        if (REX!=-1)
+          ptr="ST_U8_REX_REGS";
+        else
+          ptr="ST_U8_REGS";
+      } else if (arg2_size==16)
+        ptr="ST_U16_REGS";
+      else if (arg2_size==32)
+        ptr="ST_U32_REGS";
+      else if (arg2_size==64)
+        ptr="ST_U64_REGS";
+      if (ptr)
+        CatPrint(arg2_st,"%Z",RM1,ptr);
+    }
+  }
+
+  if (ARGT_RM8<=arg1<=ARGT_RM64 || ARGT_M8<=arg1<=ARGT_M64 ||
+        ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
+    if (ARGT_RM8<=arg2<=ARGT_RM64 || ARGT_M8<=arg2<=ARGT_M64) {
+      reloced_arg1=arg2;
+      reloced_arg2=arg1;
+      reloced_arg1_size=arg2_size;
+      reloced_arg2_size=arg1_size;
+      reloced_arg1_st=arg2_st;
+      reloced_arg2_st=arg1_st;
+    } else {
+      reloced_arg1=arg1;
+      reloced_arg2=arg2;
+      reloced_arg1_size=arg1_size;
+      reloced_arg2_size=arg2_size;
+      reloced_arg1_st=arg1_st;
+      reloced_arg2_st=arg2_st;
+    }
+
+    CatPrint(reloced_arg1_st,seg_overrides);
+    ModrM=*rip++;
+    Mod=ModrM>>6 & 3;
+    RM1=ModrM & 7+REX_b;
+    RM2=ModrM>>3 & 7+REX_r;
+    if (Mod<3 && RM1&7==4)
+      SIB=*rip++;
+    if (Mod==1) {
+      disp=*rip(U8 *)++;
+      CatPrint(reloced_arg1_st,"%02X",disp);
+    } else if (Mod==2) {
+      disp=*rip(U32 *)++;
+      CatPrint(reloced_arg1_st,"%08X",disp);
+    }
+    if (tmpins->slash_val<8)
+      RM2=-1;
+    else {
+      ptr=NULL;
+      if (reloced_arg2==ARGT_SREG) {
+        if (RM2<=5)
+          ptr="ST_SEG_REGS";
+      } else if (!(ARGT_IMM8<=reloced_arg2<=ARGT_IMM64) &&
+            !(ARGT_UIMM8<=reloced_arg2<=ARGT_UIMM64)) {
+        if (reloced_arg2_size==8) {
+          if (REX!=-1)
+            ptr="ST_U8_REX_REGS";
+          else
+            ptr="ST_U8_REGS";
+        } else if (reloced_arg2_size==16)
+          ptr="ST_U16_REGS";
+        else if (reloced_arg2_size==32)
+          ptr="ST_U32_REGS";
+        else if (reloced_arg2_size==64)
+          ptr="ST_U64_REGS";
+      }
+      if (ptr)
+        CatPrint(reloced_arg2_st,"%Z",RM2,ptr);
+    }
+    if (RM1&7==5 && !Mod) {
+      disp=*rip(I32 *)++;
+      if (seg_size==64) {
+        disp+=rip;
+        if (reloced_arg2==ARGT_IMM8 || reloced_arg2==ARGT_UIMM8)
+          disp++;
+        else if (reloced_arg2==ARGT_IMM16 || reloced_arg2==ARGT_UIMM16)
+          disp+=2;
+        else if (reloced_arg2==ARGT_IMM32 || reloced_arg2==ARGT_UIMM32)
+          disp+=4;
+        else if (reloced_arg2==ARGT_IMM64 || reloced_arg2==ARGT_UIMM64)
+          disp+=8;
+      }
+      CatPrint(reloced_arg1_st,"[%X]",disp);
+      RM1=-1;
+    } else {
+      if (Mod<3) {
+        if (RM1&7==4) {
+          RM1=-1;
+          r1=SIB & 7+REX_b;
+          r2=SIB>>3 & 7+REX_x;
+          scale=SIB>>6 &3;
+          if (scale==3)
+            scale=8;
+          else if (scale==2)
+            scale=4;
+          else if (scale==1)
+            scale=2;
+          else
+            scale=1;
+          if (seg_size==64)
+            ptr="ST_U64_REGS";
+          else
+            ptr="ST_U32_REGS";
+          if (r1==REG_RBP && !Mod) {
+            disp=*rip(U32 *)++;
+            CatPrint(reloced_arg1_st,"%08X[%Z*%d]",disp,r2,ptr,scale);
+          } else if (r2==4)
+            CatPrint(reloced_arg1_st,"[%Z]",r1,ptr);
+          else
+            CatPrint(reloced_arg1_st,"[%Z+%Z*%d]",r1,ptr,r2,ptr,scale);
+        } else {
+          if (opadd==16)
+            ptr="ST_U16_REGS";
+          else if (opadd==32)
+            ptr="ST_U32_REGS";
+          else
+            ptr="ST_U64_REGS";
+          CatPrint(reloced_arg1_st,"[%Z]",RM1,ptr);
+        }
+      } else {
+        ptr=NULL;
+        if (reloced_arg1_size==8) {
+          if (REX!=-1)
+            ptr="ST_U8_REX_REGS";
+          else
+            ptr="ST_U8_REGS";
+        } else if (reloced_arg1_size==16)
+          ptr="ST_U16_REGS";
+        else if (reloced_arg1_size==32)
+          ptr="ST_U32_REGS";
+        else if (reloced_arg1_size==64)
+          ptr="ST_U64_REGS";
+        if (ptr)
+          CatPrint(reloced_arg1_st,DefineSub(RM1,ptr));
+      }
+    }
+  }
+
+  switch (arg1) {
+    case ARGT_IMM8:
+    case ARGT_UIMM8:
+      imm=*rip(U8 *)++;
+      CatPrint(arg1_st,"%02X",imm);
+      if (tmpins->opcode[0]==0xCD && (ptr=DefineSub(imm,"ST_INT_NAMES")))
+        CatPrint(arg1_st," %s",ptr);
+      break;
+    case ARGT_IMM16:
+    case ARGT_UIMM16:
+      CatPrint(arg1_st,"%04X",*rip(U16 *)++);
+      break;
+    case ARGT_IMM32:
+    case ARGT_UIMM32:
+      CatPrint(arg1_st,"%08X",*rip(U32 *)++);
+      break;
+    case ARGT_IMM64:
+    case ARGT_UIMM64:
+      CatPrint(arg1_st,"%016X",*rip(I64 *)++);
+      break;
+    start:
+      case ARGT_REL8:
+        disp=*rip(I8 *)++;
+        break;
+      case ARGT_REL16:
+        disp=*rip(I16 *)++;
+        break;
+      case ARGT_REL32:
+        disp=*rip(I32 *)++;
+        break;
+    end:
+      disp+=rip;
+      if (IsDbgMode)
+        CatPrint(arg1_st,"%p ",disp);
+      else if (PutSrcLink(disp,512,buf2))
+        CatPrint(arg1_st,"%s ",buf2);
+      else
+        CatPrint(arg1_st,"%P ",disp);
+      if (_jmp_dst) *_jmp_dst=disp;
+      break;
+    case ARGT_MOFFS8...ARGT_MOFFS64:
+      CatPrint(arg1_st,seg_overrides);
+      if (arg1_size==8)
+        disp=*rip(U8 *)++;
+      else if (opadd==16)
+        disp=*rip(U16 *)++;
+      else
+        disp=*rip(U32 *)++;
+      CatPrint(arg1_st,"[%X]",disp);
+      break;
+    case ARGT_AL ... ARGT_DX:
+    case ARGT_SS ... ARGT_ST0:
+      CatPrint(arg1_st,"%z",arg1-ARGT_AL,
+            "AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
+      break;
+    case ARGT_STI:
+      rip--;
+      CatPrint(arg1_st,"%Z",*rip++ - tmpins->opcode[tmpins->opcode_cnt-1],
+            "ST_FSTK_REGS");
+      break;
+  }
+
+  switch (arg2) {
+    case ARGT_IMM8:
+    case ARGT_UIMM8:
+      CatPrint(arg2_st,"%02X",*rip(U8 *)++);
+      break;
+    case ARGT_IMM16:
+    case ARGT_UIMM16:
+      CatPrint(arg2_st,"%04X",*rip(U16 *)++);
+      break;
+    case ARGT_IMM32:
+    case ARGT_UIMM32:
+      CatPrint(arg2_st,"%08X",*rip(U32 *)++);
+      break;
+    case ARGT_IMM64:
+    case ARGT_UIMM64:
+      CatPrint(arg2_st,"%016X",*rip(I64 *)++);
+      break;
+    case ARGT_MOFFS8...ARGT_MOFFS64:
+      CatPrint(arg2_st,seg_overrides);
+      if (arg2_size==8)
+        disp=*rip(U8 *)++;
+      else if (opadd==16)
+        disp=*rip(U16 *)++;
+      else
+        disp=*rip(U32 *)++;
+      CatPrint(arg2_st,"[%X]",disp);
+      break;
+    case ARGT_AL ... ARGT_DX:
+    case ARGT_SS ... ARGT_ST0:
+      CatPrint(arg2_st,"%z",arg2-ARGT_AL,
+            "AL\0AX\0EAX\0RAX\0CL\0DX\0 \0 \0SS\0DS\0ES\0FS\0GS\0CS\0ST0\0");
+      break;
+    case ARGT_STI:
+      rip--;
+      CatPrint(arg2_st,"%Z",*rip++ -tmpins->opcode[tmpins->opcode_cnt-1],
+            "ST_FSTK_REGS");
+      break;
+  }
+  if (tmpins->flags&IEF_ENDING_ZERO)
+    rip++;
+
+  if (*arg1_st)
+    CatPrint(line1,"\t%s",arg1_st);
+  if (*arg2_st)
+    CatPrint(line1,",%s",arg2_st);
+  CatPrint(line1,"\n");
+  CatPrint(line2,"\n");
+  if (!just_ins) {
+    for (i=rip-(*_rip)(I64);i<6;i++) {
+      bin_data_area1[i<<1]=CH_SPACE;
+      bin_data_area1[i<<1+1]=CH_SPACE;
+    }
+    for (i=rip-(*_rip)(I64);i<12;i++) {
+      bin_data_area2[(i-6)<<1]=CH_SPACE;
+      bin_data_area2[(i-6)<<1+1]=CH_SPACE;
+    }
+  }
+  StrCpy(buf,line1);
+  if (!just_ins && rip-(*_rip)(I64)>6)
+    CatPrint(buf,line2);
+  *_rip=rip;
+}
+
+U8 *U(U8 *rip,I64 cnt=20,I64 seg_size=64)
+{//Unassembles a num of insts.
+  I64 i;
+  U8 buf[1024];
+  if (seg_size==16)
+    PrintWarn("16-bit unassembly is not well supported.\n");
+  "$HL,1$";
+  for (i=0;i<cnt;i++) {
+    Ui(buf,&rip,seg_size);
+    "%s",buf;
+  }
+  "$HL,0$";
+  return rip;
+}
+
+I64 Un(U8 *rip,I64 cnt=0x80,I64 seg_size=64)
+{//Unassembles a num of bytes
+  I64 i=0;
+  U8 buf[1024],*end_rip=rip(I64)+cnt;
+  if (seg_size==16)
+    PrintWarn("16-bit unassembly is not well supported.\n");
+  "$HL,1$";
+  while (rip<end_rip) {
+    Ui(buf,&rip,seg_size);
+    "%s",buf;
+    i++;
+  }
+  "$HL,0$";
+  return i;
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/HomeKeyPlugIns.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/HomeKeyPlugIns.HC.HTML new file mode 100755 index 0000000..53214cd --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/HomeKeyPlugIns.HC.HTML @@ -0,0 +1,320 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 TimeIns()
+{
+  CDate cdt;
+  cdt=Now;
+  "$IV,1$----%D %T----$IV,0$\n",cdt,cdt;
+}
+
+U0 FileLinkIns()
+{
+  U8 *st=PopUpPickFile;
+  st[0]=':';  //This is my personal code, not production. LOL
+  "$LK,\"%s\",A=\"FI:%s\"$",st+2,st;
+  Free(st);
+}
+
+U0 DirLinksIns()
+{
+  CDirEntry *tmpde,*tmpde1;
+  U8 *st=PopUpPickDir,*st2;
+  st[0]=':';  //This is my personal code, not production. LOL
+  st2=MStrPrint("%s/*",st);
+  tmpde=tmpde1=FilesFind(st2,FUF_JUST_FILES);
+  while (tmpde) {
+    tmpde->full_name[0]=':';
+    "$LK,\"%s\",A=\"FI:%s\"$\n",tmpde->full_name+2,tmpde->full_name;
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  Free(st);
+  Free(st2);
+}
+
+U0 DocHiddenDel(CDoc *doc=NULL)
+{
+  Bool unlock;
+  CDocEntry *doc_e,*doc_e1;
+  if (!doc) doc=DocPut;
+  if (doc) {
+    unlock=DocLock(doc);
+    DocRecalc(doc);
+    doc_e=doc->head.next;
+    while (doc_e!=doc) {
+      doc_e1=doc_e->next;
+      if (doc_e->de_flags&(DOCEF_FILTER_SKIP|DOCEF_SKIP))
+        DocEntryDel(doc,doc_e);
+      doc_e=doc_e1;
+    }
+    DocRecalc(doc);
+    if (unlock)
+      DocUnlock(doc);
+  }
+}
+
+Bool MyPutKey(I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+
+  //See Char for definition of scan codes.
+  //See Key Allocations.
+  //See Keyboard Devices.
+
+  //You can customize keys.  This routine
+  //is called before the main editor
+  //key hndlr DocPutKey().
+  //You can intercept any key.
+
+  //Return TRUE if you completely
+  //handled the key.
+  I64 i;
+  U8 *st1,*st2;
+  if (sc&SCF_ALT && !(sc&SCF_CTRL)) {
+    switch (ch) {
+      case 0:
+        switch (sc.u8[0]) {
+          case SC_F1:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTPURPLE");
+              else
+                "$LTPURPLE$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /PURPLE");
+              else
+                "$PURPLE$";
+            }
+            return TRUE;
+          case SC_F2:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTRED");
+              else
+                "$LTRED$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /RED");
+              else
+                "$RED$";
+            }
+            return TRUE;
+          case SC_F3:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTGREEN");
+              else
+                "$LTGREEN$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /GREEN");
+              else
+                "$GREEN$";
+            }
+            return TRUE;
+          case SC_F4:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Default Color");
+              else
+                "$FG$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /BLUE");
+              else
+                "$BLUE$";
+            }
+            return TRUE;
+          case SC_F8:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Cmd /DirLinksIns");
+              else
+                DirLinksIns;
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Cmd /FileLinkIns");
+              else
+                FileLinkIns;
+            }
+            return TRUE;
+        }
+        break;
+      case 'a':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete On");
+        else
+          AutoComplete(ON);
+        return TRUE;
+      case 'A':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete Off");
+        else
+          AutoComplete;
+        return TRUE;
+      case 'f': //With sync
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /FrameGrabber Sync");
+        else if (fg_on)
+          FrameGrabberToggle(FALSE,FALSE);
+        else
+          FrameGrabberToggle(TRUE,FALSE);
+        return TRUE;
+      case 'F': //With sync and intro TOS theme
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /FrameGrabber Intro");
+        else if (fg_on)
+          FrameGrabberToggle(FALSE,FALSE);
+        else
+          FrameGrabberToggle(TRUE,TRUE);
+        return TRUE;
+      case 'h':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileHorz");
+        else
+          WinTileHorz;
+        return TRUE;
+      case 'H':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Del Hidden Doc Entries");
+        else
+          DocHiddenDel;
+        return TRUE;
+      case 'm':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinMax");
+        else {
+          WinBorder;
+          WinMax;
+        }
+        return TRUE;
+      case 'v':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileVert");
+        else
+          WinTileVert;
+        return TRUE;
+      case 'l':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Put Link to Cur Pos on Clip");
+        else {
+          ClipDel;
+          st1=FileNameAbs(BIBLE_FILENAME);
+          st2=FileNameAbs(DocPut->filename.name);
+          if (!StrCmp(st1,st2)) {
+            Free(st1);
+            st1=BibleLine2Verse(DocPut->cur_entry->y+1,',');
+            DocPrint(sys_clip_doc,"$LK,\"BF:%s\"$",st1);
+          } else
+            DocPrint(sys_clip_doc,"$LK,\"FL:%s,%d\"$",
+                  st2,DocPut->cur_entry->y+1);
+          Free(st1);
+          Free(st2);
+        }
+        return TRUE;
+      case 'L':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Place Anchor, Put Link to Clip");
+        else {
+          i=RandU32;
+          ClipDel;
+          DocPrint(sys_clip_doc,"$LK,\"<TODO>\",A=\"FA:%s,ANC%d\"$",
+                DocPut->filename.name,i);
+          "$AN,\"<TODO>\",A=\"ANC%d\"$",i;
+        }
+        return TRUE;
+      case 'p':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /JukeBox");
+        else
+          PopUp("#include \"::/Apps/Psalmody/Load\";"
+                "JukeBox(\"::/Home/Sup3/Sup3Hymns\");");
+        return TRUE;
+      case 'P':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /Psalmody");
+        else
+          PopUp("#include \"::/Apps/Psalmody/Load\";"
+                "Psalmody(\"~/Sup3/Sup3Hymns\");");
+        return TRUE;
+
+        //Ins your own ALT-key plug-ins
+      case '1':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /pi");
+        else
+          'pi';
+        return TRUE;
+      case '2':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /theta");
+        else
+          'theta';
+        return TRUE;
+      case '3':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /phi");
+        else
+          'phi';
+        return TRUE;
+      case '4':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /omega");
+        else
+          'omega';
+        return TRUE;
+      case '9':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Indent 5");
+        else
+          "$ID,5$";
+        return TRUE;
+      case '0':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Unindent 5");
+        else
+          "$ID,-5$";
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+Bool MyPutS(U8 *)
+{
+  return FALSE;
+}
+
+KeyDevAdd(&MyPutKey,&MyPutS,0x20000000,TRUE);
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/HomeLocalize.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/HomeLocalize.HC.HTML new file mode 100755 index 0000000..a5fb469 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/HomeLocalize.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+Option(OPTf_WARN_PAREN,ON);
+Option(OPTf_WARN_DUP_TYPES,ON);
+
+KbdTypeMatic(0);
+
+// Las Vegas is -7 during summer, -8 during winter
+local_time_offset=-7*60*60*CDATE_FREQ; //Pacific
+// Remember you can set the time in the BIOS.
+
+//adjust these to set mouse move scale
+ms_hard.scale.x=0.5;
+ms_hard.scale.y=0.5;
+ms_hard.scale.z=5.0; //wheel
+
+//don't change these
+ms_hard.prescale.x=ms_hard.pos.x/ms_hard.scale.x;
+ms_hard.prescale.y=ms_hard.pos.y/ms_hard.scale.y;
+ms_hard.prescale.z=ms_hard.pos.z/ms_hard.scale.z;
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/HomeSys.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/HomeSys.HC.HTML new file mode 100755 index 0000000..e9f3e8d --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/HomeSys.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 UserStartUp()
+{//Run each time a user a spawned
+  DocTermNew;
+  Type("::/Doc/Start.DD");
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+  Dir;
+  "80,849LOC:";
+  CPURep;
+}
+
+U0 SrvStartUp()
+{//Run each time a srv task is spawned.
+  DocTermNew;
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+}
+
+CTask *user1,*user2;
+
+U0 StartUpTasks()
+{
+  user1=User;
+  user2=User;
+  WinToTop(user1);
+  WinTileVert;
+  "Boot     Time:%7.3fs\n",tS;
+  XTalk(user1,"Cd;#include \"Once\";\n");
+  Silent;
+  ACInit("/*;!*/Bible.TXT*;!*.TXT"); //No Bible, no uncompressed DD.
+  Silent(OFF);
+  "AutoComplete Time:%7.3fs\n",tS;
+}
+
+if (DrvIsWritable(':')) {
+  DelTree("::/Tmp/ScrnShots");
+  DirMk("::/Tmp/ScrnShots");
+}
+
+StartUpTasks;
+
+"\nTempleOS V%5.3f\t%D %T\n\n",sys_os_version,sys_compile_time,sys_compile_time;
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/HomeWrappers.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/HomeWrappers.HC.HTML new file mode 100755 index 0000000..8ec70d8 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/HomeWrappers.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+#help_index "Cmd Line (Typically)"
+
+#define FILEMASK_OFF_LIMITS "!*/Misc/PCIDevices.DD*;!*/Misc/Bible.TXT*;"\
+        "!*/Books?/*;!*/Sup1/Sup1Words/*;!*/Sup1/Sup1Bin/*;"\
+        "!*/God/Vocab.DD*"
+
+public I64 F(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in all text files.
+  return Find(needle_str,"/*",fu_flags);
+}
+
+public I64 F2(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in most text files.
+  return Find(needle_str,"/*;" FILEMASK_OFF_LIMITS,fu_flags);
+}
+
+public I64 R(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in most text files.
+  return Find(needle_str,"/*;" FILEMASK_OFF_LIMITS,fu_flags,replace_text);
+}
+
+public I64 FD(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in cur dir text files.
+  return Find(needle_str,"*",fu_flags);
+}
+
+public I64 FD2(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in most cur dir text files.
+  return Find(needle_str,"*;" FILEMASK_OFF_LIMITS,fu_flags);
+}
+
+public I64 RD(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in most cur dir text files.
+  return Find(needle_str,"*;" FILEMASK_OFF_LIMITS,fu_flags,replace_text);
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/MakeHome.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/MakeHome.HC.HTML new file mode 100755 index 0000000..00ffaf0 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/MakeHome.HC.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+//If these are not present in /Home, it uses the version in the root dir.  You
+//can make your own, modified, version of these files in your /Home directory.
+#include "~/HomeLocalize"
+#include "/Adam/Opt/Boot/MakeBoot"
+#include "/Adam/Opt/Utils/MakeUtils"
+#include "~/HomeWrappers"
+MapFileLoad("::/Kernel/Kernel");
+MapFileLoad("::/Compiler/Compiler");
+
+#include "::/Apps/Psalmody/Load"
+#include "~/TOS/MakeTOS"
+#include "~/HomeKeyPlugIns"
+#include "~/HomeSys"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/Once.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/Once.HC.HTML new file mode 100755 index 0000000..25b97eb --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/Once.HC.HTML @@ -0,0 +1,70 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+//This file is executed by the
+//first terminal window upon start-up.
+//See Once and Home Files.
+
+//  Type("::/Doc/Customize.DD");
+
+U0 Tmp()
+{
+  OnceExe;
+  switch (sys_boot_src.u16[0]) {
+    case BOOT_SRC_DVD:
+      "\nIf you answer 'No' you can play with\n"
+            "the live CD without installing.\n\n"
+            "Install onto hard drive ";
+      if (YorN) {
+        DocBottom;
+        if (RunFile("::/Misc/OSInstall",,FALSE)) {
+          Del("C:/Home/DoDistro.HC.Z");
+          Del("D:/Home/DoDistro.HC.Z");
+          OnceDrv('C',"\"\n\nRun TOSStaffIns;\n\n\n\";");
+          OnceDrv('D',""); //This command uses cached Registry file.
+          if (PressAKey!=CH_SHIFT_ESC)
+            Reboot; //Too dangerous for amateurs until reboot.
+        }
+      }
+      break;
+  }
+  if (FileFind("D:/Tmp/Logs/access.log")) {
+    In("\n\n%C",CH_ESC);
+    RunFile("::/Demo/WebLogDemo/WebLogRep",,
+          "D:/Tmp/Logs/*.log","D:/Home/WebLogRep.DD");
+    Del("D:/Tmp/Logs/*.log");
+  }
+}
+
+Tmp;
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/PersonalMenu.DD.HTML b/public/Wb/Home/Src/Demo/AcctExample/PersonalMenu.DD.HTML new file mode 100755 index 0000000..6f99a72 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/PersonalMenu.DD.HTML @@ -0,0 +1,128 @@ + + + + + + + + + + + +
+Cd      DrvC    DrvD    /       Home    TOS     ChgDskT MergeD  MergeT  
+MakeC   BootC   Regen   PreRegenMakeD   BootD   CopyDrv 
+Adam    Kernel  CompilerBlkDev  Mem     Serial  
+DolDoc  Gr      AutoCompGod     Ctrls   Boot    Utils   ABlkDev Snd     
+Apps    Budget  GrModelsKeepAwayLogic   PsalmodySpan    Strut   
+Hymns3  Hymns2  Hymns1  Sup1    Titan   ToTheFrtXCaliber
+Games   GraphicsDemo    AcctEmplAsm     DocDoc  Dsk     InFile  LecturesMultCore
+RevFile Snd     SortFileTemplateHtmlTXT WebLog  Stadium 
+Doc     Misc    Tour    Tmp     DelScrSt0000Boot
+DownloadLinxDictHappy   August  Words   
+
+
+          Fun Games
+
+
+
+
+
+
+
+
+Titanium/* Graphics Not Rendered in HTML */ Diamond/* Graphics Not Rendered in HTML */  Bat/* Graphics Not Rendered in HTML */   Varoom/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+FlatTops/* Graphics Not Rendered in HTML */  Golf /* Graphics Not Rendered in HTML */ KeepAway/* Graphics Not Rendered in HTML */ RawHide/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+X-Caliber/* Graphics Not Rendered in HTML */ Wenceslas/* Graphics Not Rendered in HTML */  Lines/* Graphics Not Rendered in HTML */
+
+
+
+
+         Unfun Games
+
+
+
+
+
+
+
+
+
+ Talons/* Graphics Not Rendered in HTML */  Frankenstein/* Graphics Not Rendered in HTML */ ZoneOut/* Graphics Not Rendered in HTML */ 
+
+
+
+
+
+
+
+
+
+ToTheFront/* Graphics Not Rendered in HTML */  Span /* Graphics Not Rendered in HTML */ Checkers/* Graphics Not Rendered in HTML */ Digits/* Graphics Not Rendered in HTML */
+
+
+
+
+             Code Scraps
+
+
+
+
+
+
+ Strut/* Graphics Not Rendered in HTML */ BigGuns/* Graphics Not Rendered in HTML */ TheDead/* Graphics Not Rendered in HTML */ DunGen/* Graphics Not Rendered in HTML */ Models/* Graphics Not Rendered in HTML */
+
+
+
+
+              Nongames
+
+
+
+
+
+
+
+JukeBox/* Graphics Not Rendered in HTML */ Psalmody/* Graphics Not Rendered in HTML */ Budget/* Graphics Not Rendered in HTML */ Logic/* Graphics Not Rendered in HTML */ Vocab/* Graphics Not Rendered in HTML */ 
+
+Sup1Hym Sup2Hym Sup3Hym
+
+Budget  TestSuitTakeTourSymAlphaSymNum  
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/PersonalNotes.DD.HTML b/public/Wb/Home/Src/Demo/AcctExample/PersonalNotes.DD.HTML new file mode 100755 index 0000000..e6b1729 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/PersonalNotes.DD.HTML @@ -0,0 +1,532 @@ + + + + + + + + + + + +
+                                      TODO
+
+* Get rid of niggerlicious name "binary".
+
+* Change mouse Z to wheel.
+
+* 10/28/17 Editor froze when filter search 3, in bible, "hour".
+
+* 10/28/17 Titanium froze, easy repeatable
+
+* Corrupt ISO.C, might be fix--no longer dependent on direntry ISO filesize
+
+* DskChk CDROM
+
+* Compiler Bug: AUWrite() dst->cdt=t0_now+ToI64(CDATE_FREQ*(tmpsd->tS-t0_tS));
+
+* Make MV files combine disjoint rects for same frame.
+
+* God said to reconsider switch start/end, perhaps preface portion?
+
+* 170605 Alec Murphy said MountFile() of a red sea supplemental1 ISO failed.
+
+* Does entire tool chain support super/sub script?
+
+* 170624 DskChk() showed extra alloced clus for FAT32, Sup1Hymns.  ClusNum was 
+'.'+1 and clus was zero.
+
+* ::/Apps/X-Caliber/X-Caliber.HC
+* Add asteroid harbor defense.
+* Afterburner thruster.
+
+* ::/Apps/Titanium/Titanium.HC
+* Lead-in at start of game with no enemy.
+* Have highway of death.
+* Fix straight shooting.
+* Helicopters.
+* Anti-Aircraft.
+
+* 64-Bit Device Memory is not implemented.
+
+* Investigate why packet loss Training Sleep(1).
+
+* Add AVL or red/black binary tree library support.  We have fixed-size stack.  
+Auto-balancing binary tree is very needed.  I've done everything myself.  I 
+don't want to ruin a perfect record.  I'm in no hurry.
+
+* SpriteEd shift pts, Ctrl pt for ellipse/polygon w,h is off when rotated.
+
+* God said this is bad.  FL:::/Adam/DolDoc/DocFind.HC,41
+* Backward <SHIFT-F3> is broken?
+
+* Find() search sprite text?
+
+* Cannot include ':' in Document Links search string.
+* $DA fixed width string: <Del> or <BACKSPACE> permanently shortens.
+
+* 11/19/16 editor took long time after copying old testament onto clip and 
+exiting.
+
+* Nestled switch() start/end?
+
+* Editor filter froze.
+
+* Editor overstrike mode at cmd line with menu macro?  Probably, many other 
+overstrike issues.
+
+* DOCT_HEX_ED with odd size, ASCII cannot be edited.
+
+* FL:::/Adam/Gr/SpriteEd.HC,789 Resize bitmap?
+
+* DOCEF_REMALLOC_DATA HexEdit Remalloc.
+
+* DOCF_DBL_DOLLARS in Reindention.
+
+* Compiler Optimization: Local array vars --> reg.  Might exist.
+
+* Make function as a better word processor.  Justify text.  Page numbers.  
+Header and footer templates?
+
+* Compiler Optimization: heap_glbls with added offset.  Might exist.
+
+* Bug: Find-and-replace text on $PT$ line before it.
+* 12/25/2015 Copy-Paste index.html glitch if source window 40 columns.
+* 01/06/2016 Editor filter "str" applied to output from LineRep looks broken.
+
+* Document, perhaps with video, GetStr() all the way down into PutKey() code.
+
+* Better dictionary.
+* Good spell checker.
+* Good Bible search.
+
+* Can MEM_EXTRA_HASH2_PAGS be just one?
+
+* Bible ranges in BibleVerse(). 
+
+* ::/Demo/Games/FlatTops.HC is torpedo, not bombs.
+
+* Reset MPs with Core0StartMP() after boot.  Free old task memory?
+
+* Use thick and pen_height when clipping with thick>1.
+
+* ~/Sup1/Sup1Games/Rocks.HC.
+
+* Asm LIST NOLIST bugs.
+
+* Review writing to same cache-line from multicore.  Do CTask->task_flags and 
+others need to be in separate cache lines?
+
+* Fix KbdLEDsSet().
+* NumLock comes on with break key.
+
+* Hymns: mightest, finger
+
+* Get rid of JIFFY and HPET and just use tS.
+
+* Use "Rosetta Stone" in documentaion pointing to this: 
+::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+* Change %h*c so the character is not a arg?
+
+* GrLineFat3() needs a little work.
+
+* GrFillTri0() with both GrHLine() and GrVLine() don't match in 
+::/Demo/Games/CastleFrankenstein.HC causing wall spot pixels.
+
+
+                                   TODO? Meh
+* Compiler: lock{} needs warn on invalid modes or something.
+
+* Compiler: Warn recurse class define?
+
+* Asm could support R4u8 by adding 0x40 byte.
+
+* Mem32DevAlloc() is broken.  Devices should be in free spot of E820 report.
+
+* SpriteEd: Strip SPT_SHIFT origin cmds?
+
+* Clean-up ASCII #127 delete char?  (No. Maybe, we want a new usage for 127 in 
+future centuries.)
+
+* Compiler: Exceptions don't free CCmpCtrl stuff.
+
+* ::/Adam/DolDoc/DocHighlight.HC for code comments at top of documents.
+
+* Unhandled exception msgs from MP's get overwritten by WinMgr.
+
+* Diff("C:/Misc/Bible.TXT","D:/Misc/Bible.TXT"); Takes too long.
+
+* Finish Pilgrim game.
+
+* Compiler: PtrArith MUL SIZE -->QueIns(MUL)?
+* Compiler: QueRem(IC_NOP)?
+
+* Fix Chess game so not isometric view.
+
+
+                      TODO: Too Hard, or Not Worth Doing.
+* AutoComplete/Man() Jmp for user code.
+
+* Bible sized nodes
+
+* FileMgr() is bad with lots of files.  
+
+* Would be nice to have a routine telling how much free memory, so apps can plan 
+a big alloc.  This is doable, depending on how.
+
+* Log-to-file is inefficient because we load and save whole file.
+
+* ICMov() PUSH_CMP and MDf_STK?  Perhaps, it's okay.
+
+* Short FAT32 ~ names.
+
+* Find() search text in sprites.
+
+* Links in text in sprites. 
+
+* Compiler: Inline functions?
+
+* Compiler: FunPtr local vars?  I forgot if this was hard or not.
+     U0 Main()
+     {
+       U0 (*fp_old_draw_ms)(CDC *dc,I64 x,I64 y)=gr.fp_draw_ms;
+     }
+
+* Compiler: Get rid of 0x20000 limit.
+
+* GrFloodFillRay: Get rid of 0x80000 limit.
+
+
+                                      Bugs
+* 1/28/16 ::/Demo/Graphics/Pick3D.HC crashed in TestSuite.
+
+* 1/12/16 make RAM drive 2288 blks, CopyTree("C:/Home","B:/Home");   Disk 
+runs-out of space and hangs instead of reporting errors.
+
+* Bug introduced around 11/1/15.  Changed ::/Kernel/Sched.HC and now WinToTop is 
+called on Adam task at start-up, sometimes.  Might be user's fault because of 
+bad keys pressed during VMware power-on init.  Might be fixed by 
+ACf_INIT_IN_PROGRESS.
+
+* 1/12/16 ATARepEntry shows corrupted bttns.  Weird.  Perhaps, my imagination.
+
+
+                                 3rd Party Bugs
+* VMware: Stretch to full scrn
+* VMware: PC speaker sound distorted.
+* VMware: 8/2/2015 start-up. Probably multicore.
+* VMware: CtrlAltDel on <CTRL-ALT-INS>
+* VMware: Size zero files don't copy out of mounted disk?  (Might be fixed.)
+
+
+                             Bugs? Not really sure.
+* Mount() crashes on bad drive.
+
+* Graphics clipping: scrn y+top<0 for top<0?
+
+* 1/1/2015 Bug messing-up keyboard, like no CTRL key.  Was working on Sprites.
+
+* 4/13/14 Strut or RawHide crashed when sys_var_init_flag was set during 
+testsuite.  Perhaps, floodfill?
+
+* DskChk alloc unalloced.  I don't know if I fixed this.
+
+* 1/?/2015,8/10/2015 Macro sel in Menu did not go to shell?  No, I think just 
+<CTRL-m> twice.  Not a bug.
+
+* 5/7/14:Something like InSetMs caused hang, then reboot in TestSuite.
+* 5/7/14:#63 Maybe, ::/Demo/Graphics/Pick3D.HC crashed in TestSuite.
+
+* StrPrintJoin(,st); With st="\n\\"; (Forgot what this is talking about.)
+
+
+                         TODO? Not really, just angst.
+* Should these be moved into CHashClass from CMemberLst and CHashGlblVar?
+     CArrayDim dim;
+     CHashFun *fun_ptr;
+
+* extern of fun with dft arg of str?
+
+* ISO.C on FAT32 created by Windows or Linux are not contiguous.
+
+* Might want to warn switch[] dup case numbers.
+
+* Make Clamp(), Min(), Max() into asm routines?
+
+* Add local vars to sym table in Dbg()?
+
+* Compiler: Prints two error messages for expressions in stmts.
+
+* U() negative byte displacement, neg 32-bit disp.
+
+* Race condition in ::/Demo/Games/FlatTops.HC torpedo.
+
+* Links to self document if empty file name? Document Links
+
+* FUF_RECURSE would be nice if capital "+R".
+
+* Sprites in cmd line code.
+
+* 16-Bit Assembly and Unassembly and is bad.
+
+* Compiler: Cmd to enable/disable warnings.
+
+* Compiler: Type for either F64 or I64, like Print -- no conversion.
+* Compiler: Arg type ... that did do conversion, if we have one that doesn't.
+
+* R("char_bmp_","set_");
+
+* Clean-up code FileNameAbs(), does it need so many local var names?  I guess no 
+choice.
+
+
+                                Committee Needed
+* Make binary tree look-up using FUN_SEG symbol addresses, so we can eliminate 
+fun_seg cache and wall-paper kludge?  All HolyC functions and glbl vars would 
+have left-right for address search.
+
+* Should we get rid of drive mapping.  It's ugly.
+
+* Can we get rid of MSG_CMD?
+
+* Make so just CdRom; command to copy entire disk to ::/CdRom directory? 
+
+* MP DepthBuf is a kludge because of dc->depth_buf=NULL in various graphics 
+routines.
+
+* Improve editor undo, add redo.
+
+* Compiler: F32?
+
+* International Date output: MPrintDate().  Every country make own version?
+* International Date input: Str2Date().
+
+* DCF_SYMMETRY before transformation? (Currently, it's after.) 
+
+* TRANSPARENT does not work with ROPF_DITHER.
+
+* ROP_XOR with thick>1 is broken.
+
+* GrPutChar3() with depth buf?
+
+* Eliminate?  ::/Adam/Ctrls/CtrlsA.HC?
+* Eliminate?  ::/Adam/AMathODE.HC?
+* Eliminate?  Complex?
+* Eliminate?  CDC.brush?
+* Eliminate?  Mat4x4MulXYZ() change to 3x3?
+* Eliminate?  ROP_XOR?
+
+* WinMgrTask needs to do doc operations on PostMsg() msgs for ms_hard.  Already 
+works for MsSet()?
+
+* Should Msgs in PopUp queue get fwded to parent when task dies?
+
+* Import Intel datasheets so we can use links in Code for documentation.  I 
+tried a PDF-to-text convertor and it wasn't acceptible.
+
+* Switch stmt with sparse cases?  Maybe, ban sparse switch stmts.
+
+* Compiler Optimization: Postpone LocalVar init until last possible moment in 
+case of return.
+
+* Compiler: Local var array/struct initialization.
+
+* Compiler Optimization: Bools use r,rm in ICCmp() like in ICCmpAndBranch()?
+
+* Compiler: !F64 ~F64
+
+* Compiler: &=, |= can overflow with Bts Btr on small data types?
+
+* Implement RS_ATTR_FIXED fixed pos files?
+
+* SIMD in Mat4x4MulXYZ?
+
+* I use fixed-point in Circle(), Ellipse(), Mat4x4MulXYZ(), Mat4x4MulMat4x4New() 
+and others.  God says I might want to change to float.  
+::/Demo/Lectures/FixedPoint.HC ::/Demo/Lectures/FixedPointAdvanced.HC.
+
+* Note: We will never put multiple Keyboard Tables.  Each country must make 
+their own version of TempleOS.  The Intel Factory ROM will have just English.  
+Our Charter bans multiple country or architectures in the same version.
+
+* 12 border chars in scrn font codes 0x02-0x0D.  TextBorder() RawDr() 
+::/Demo/Games/CharDemo.HC. LineFeed shows-up in <CTRL-m> PersonalMenu.
+
+* Super-simple high speed serial needs flow control.  <CTRL-s> and <CTRL-q>?
+
+
+                              Inspirational Ideas
+* Redo videos, make more professional.
+
+* Add icons.
+
+* Use standard terminology from "the literature".
+
+* Striped and other dither patterns.  Brushes?
+
+* Get rid of BYTE, WORD, DWORD in opcode and replace with U8, U16, U32.
+
+* Get rid of "Char".
+
+* Get rid of having two terms and pick one, "Disk" and "BlkDev"?  (Probably, not 
+that one.)
+
+* Could switch to having just C and D drives and RAMDrive and CD/DVD? 
+
+* New editor widgets.
+
+* Make use of flag potential in FilesFind() and possibly DirContextNew().
+* Sort options for FilesFind()?
+
+* New HolyC language features?
+
+* Better Debugging?
+
+* Look for mem leaks?
+
+* Std local var names.
+
+* Ticketmaster format stmts? Overflow "t='*'" and padding character?
+
+* Move stuff out of Kernel module.
+
+* $LK,L="FL:D:/Kernel/File.HC"$ instead of A=
+* $SP,B=1$ instead of $SP,BI=1$
+* $CM+LE+RE is nasty
+
+* DCF_TRANSFORMATION|DCF_SYMMETRY|DCF_JUST_MIRROR -- maybe not both needed at 
+once.
+
+* More Controls?
+
+* Compiler: More use of more floating-point stk?
+
+* Compiler: More aggressive in CmpF2PushPop() with types besides MOV and F64. 
+
+* Playing with ::/Demo/Lectures/NegDisp.HC on CTask?
+     $=-CTASK_NEG_OFFSET
+     offset(CTask.addr)==0
+     Spawn(): CAlloc()
+     TaskDel(): Free()
+     CSysFixedArea.adam
+     Looks like task_flags,locked_flags cause problems with neg offset.
+
+* Make a game, S.E.T.I., with radio telescope array.  Put God on air.
+
+
+                                      Test
+* SpriteBitMap: Grabscroll? 
+
+* DrvMap() in MountFile().
+
+* Return ress for GrBlot, GrRect, GrPutChar?
+* Collision cnts for GrBlot, GrRect, GrPutChar?
+
+* GetStr() or GetChar() in OSInstall didn't like focus change.
+
+* Test on Dad's computer or other people's?
+
+* ICDivEqu() assumes RBX.  Is it okay?
+
+* InFile PopUp of PopUp?
+
+* FileMgr() help link scrolls out of window.
+
+* MsHardDrvrInstall() throws exceptions?  Doesn't work?  Why mouse 0x9FC30?
+
+* VirtualBox MP reboot?
+
+* Compiler: Err/Warn line nums?
+* Asm branch-out-of-range warn by one line?
+
+* Make sure queue links safe in one direction.  Task QueIns and QueRem for 
+multicore cycling fwd through tasks.
+
+* Test removable media id and RS_ATTR_RESIDENT.  Touch("","+T");
+
+
+                                 Uncategorized
+* DiskCache during FileRead. <CTRL-ALT-c>, Kill().  
+
+* MOV U8 [RSP+RCX],DL
+
+* gr.scrn_image
+  >Might want to do ZOOM in U8 graphics and convert scrn capture to U8
+  >Might want to rev bit order
+
+* This Fs->catch_except=TRUE causes problems because it
+catches divide and out-of-mem.  Not sure what to do, yet.
+
+* Release semaphores or break lock sema,usb_td
+
+* Might make CSprite flood fill operate on a separate bitmap
+and blotted at the end.
+* <CTRL-r> delete subsprite in menu near others
+* make better heapwalk, do something with _CFG_HEAP_DBG.
+
+* static var off of data heap.
+* could add "const" to not set CCF_NOT_CONST flag for trig, etc.
+* could make glblvar imports use MDF_RIP_DISP32.
+* PUSH_CMP allocs reg R9 or whatever
+* Might be problem with NOP in OPT pass1 for NO_PUSH in expressions besides
+assignments.  Is ShiftNoPush fully implemented?
+
+
+                                 Bible Passages
+It is love I desire                     Hosea 6:6
+Males appear three times, not empty     Deuteronomy 16:16
+Offer a sacrifice of praise             Hebrews 13:15
+Do I drink blood of goats? Offer praise Psalms 50:14
+When a servant becomes king...          Proverb 30:22
+Runner's stride                         Psalms 147:10
+Buckling armor                          1 Kings 20:11
+Lot cast in the lap                     Proverbs 16:33
+Lord does not repeat                    Job 33:14
+Offer only in approved place            Deuteronomy 12:13-18
+Jesus' zeal for the Temple              John 2:14-19
+Famine not for bread                    Amos 8:11-12
+To the honest, you are honest           Psalm 18:26
+Meek and humble of heart                Matthew 11:29
+Moses gets Aaron                        Exodus 4:10-16
+There is no council against the Lord    Proverbs 21:30
+Human help is worthless                 Psalm 108:12
+Do not seek your own wealth             1 Corinthians 10:24
+Abundance of Spirits                    1 Corinthians 14:12
+The stone rejected is cornerstone       Matthew 21:42
+Egypt rise like flood                   Jeremiah 46:7-8
+New wineskins                           Mark 2:22
+Thousand songs of Solomon               1 Kings 4:32
+Not rich, nor poor, but my portion      Proverbs 30:8
+Be hot or cold. Lukewarm I spit you out Revelation 3:16
+
+Linus Torvalds (Dec 28, 1969)
+John Carmack   (Aug 20, 1970)
+Terry A. Davis (Dec 15, 1969)
+Dr. David Pheanis
+Dr. Konstantinos S. Tsakalis
+Dr. Walter Higgins
+Peter Gadwa
+Ticketmaster
+Tom Foley
+Graphic Technologies
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/Registry.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/Registry.HC.HTML new file mode 100755 index 0000000..3baaec9 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/Registry.HC.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
++] Adam
++] TempleOS
++] Once
++] DemoCompany
++] WalnutZone
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/TOS/MakeTOS.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/TOS/MakeTOS.HC.HTML new file mode 100755 index 0000000..ef633a4 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/TOS/MakeTOS.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+#include "TOSExt"
+#include "TOSCfg"
+#include "TOSMisc"
+#include "TOSDistro"
+
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSCfg.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSCfg.HC.HTML new file mode 100755 index 0000000..0845fe0 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSCfg.HC.HTML @@ -0,0 +1,92 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS/Cfg"
+
+#define SLOP    BLK_SIZE
+
+U0 TOSDbgDistro1()
+{
+  CBinFile *bfh=mem_boot_base-sizeof(CBinFile);
+  bfh(I64)+=bfh->file_size-1;
+  DefinePrint("TOS_DBG_DISTRO","0x%X",
+        CeilI64(SYS_KERNEL_END+SLOP,BLK_SIZE));
+  DefinePrint("TOS_DBG_DISTRO_END",  "0x%X",FloorI64(
+        (BOOT_RAM_LIMIT-(BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE))>>4<<4-
+        (bfh(I64)-SYS_KERNEL_END)-SLOP,BLK_SIZE));
+  DefinePrint("CFG_DBG_DISTRO_FILE","\"/Tmp/DbgDistro.BIN.Z\"");
+} TOSDbgDistro1;
+
+U0 TOSDbgDistro2()
+{
+  DefinePrint("CFG_DBG_DISTRO","\"a0x%X\n0x%X\n\"",TOS_DBG_DISTRO,
+        (TOS_DBG_DISTRO_END-TOS_DBG_DISTRO)/BLK_SIZE);
+  DefinePrint("CFG_DBG_DISTRO_START","\"0x%X\"",TOS_DBG_DISTRO);
+} TOSDbgDistro2;
+
+U0 TOSInit()
+{
+  switch (INS_REG_MACHINE_NUM) {
+    case 1: //TAD Native Machine
+      DefinePrint("CFG_RAM_DRVS",
+            "\"B\nScale2Mem(2048,0x100000,4*1024*1024*1024)\n\"");
+      DefinePrint("CFG_HARD_DRVS","\"C\ns0xFE00\n0xFE10\n0\"");
+      DefinePrint("CFG_DVD_DRVS","\"Ts0x1F0\n1\"");
+      DefinePrint("CFG_DSK_CACHE","\"Scale2Mem(0x80000,0x8000000)\n\"");
+      DefinePrint("TOS_HDS","\"CD\"");
+      DefinePrint("TOS_MASTER_BOOT_DRVS","\"C\"");
+      break;
+    default:
+      DefinePrint("CFG_RAM_DRVS",
+            "\"B\nScale2Mem(2048,0x100000,4*1024*1024*1024)\n\"");
+      DefinePrint("CFG_HARD_DRVS","\"\"");
+      DefinePrint("CFG_DVD_DRVS","\"\"");
+      DefinePrint("CFG_DSK_CACHE","\"Scale2Mem(0x80000,0x8000000)\n\"");
+      DefinePrint("TOS_HDS","\"CD\"");
+      DefinePrint("TOS_MASTER_BOOT_DRVS","\"C\"");
+  }
+} TOSInit;
+
+#define TOS_ISO_NAME    "B:/TOS_Distro.ISO.C"
+#define TOS_DISTRO_DIR  "B:/Distro"
+#define CFG_OPTS        "StaffMode\nMountIDEAuto\nCT\n"
+#define CFG_DBG_OPTS    "StaffMode\nMountIDEAuto\nCT"\
+                        "HeapInit\n130\nMemInit\n131\nVarInit\n132\n\n"
+#define CFG_DBGZ_OPTS   "StaffMode\nMountIDEAuto\nCT"\
+                        "HeapInit\n0\nMemInit\n0\nVarInit\n0\n\n"
+#define TOS_CFG         "\n" CFG_RAM_DRVS CFG_DVD_DRVS CFG_HARD_DRVS "\n"\
+                        CFG_DSK_CACHE CFG_OPTS
+#define TOS_DVD_CFG     "TB\n0x20000\nT \n\n\nStaffMode\nMountIDEAuto\nCT\n"
+#define TOS_DVD_DBG_CFG "A" CFG_DBG_DISTRO\
+                        "B\nScale2Mem(2048,0x40000)\n\n\n"\
+                        "NoMP\nTextMode\nDontProbe\nDbgDistro\n"\
+                        "C:" CFG_DBG_DISTRO_FILE "\n"\
+                        CFG_DBG_DISTRO_START "\n\n"
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSDistro.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSDistro.HC.HTML new file mode 100755 index 0000000..5995360 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSDistro.HC.HTML @@ -0,0 +1,418 @@ + + + + + + + + + + + +
+//The CFG defines are ~/TOS/TOSCfg.HC.
+
+#help_index "Misc/TOS/Distro"
+
+#define MAKE_LITE       1
+#define MAKE_DBG        0
+#define MAKE_STAFF      1
+
+public U8 TOSGetDrv()
+{//Pmt for drv let.
+  I64 res;
+  "Drive (%s):",TOS_HDS;
+  res=Let2Let(GetChar);
+  '\n';
+  return res;
+}
+
+public U0 TOSBootHDIns(U8 drv_let=0)
+{//Make Compiler and Kernel. Reinstall Kernel.
+  drv_let=Let2Let(drv_let);
+  In(TOS_CFG);
+  BootHDIns(drv_let);
+  if (StrOcc(TOS_MASTER_BOOT_DRVS,drv_let))
+    BootMHDIns(drv_let);
+}
+
+public U0 TOSCopyDrv(U8 src,U8 dst)
+{//Fmt dst and copy entire drv.
+  U8 buf_s[STR_LEN],buf_d[STR_LEN];
+  src=Let2Let(src);
+  dst=Let2Let(dst);
+
+  if (dst=='D')
+    Fmt(dst,,FALSE,FSt_FAT32);
+  else
+    Fmt(dst,,FALSE,FSt_REDSEA);
+
+  StrPrint(buf_s,"%c:/",src);
+  StrPrint(buf_d,"%c:/",dst);
+  CopyTree(buf_s,buf_d);
+
+  DocClear;
+  Drv(dst);
+  TOSBootHDIns(dst);
+}
+
+public U0 TOSPmtAndCopyDrv()
+{//Pmt for drv lets. Then, Fmt dst and copy entire drv.
+   I64 src,dst;
+  "$RED$\nCopy Src Drive:\n$FG$";
+  src=TOSGetDrv;
+  "$RED$\nCopy Dst Drive:\n$FG$";
+  dst=TOSGetDrv;
+  TOSCopyDrv(src,dst);
+}
+
+U0 DistroPrep()
+{
+  AOnceFlush; //Don't want in Registry
+  OnceFlush;
+
+  Del("/Home/Demo*");
+  DelTree("/Home/*Tmp.DD.Z");
+
+  DelTree("/Tmp");
+  DirMk("/Tmp");
+  DirMk("/Tmp/ScrnShots");
+
+  Touch("/PersonalMenu.DD.Z","+T");
+  Touch("/Home/PersonalMenu.DD.Z","+T");
+
+  DelTree("/Demo/AcctExample");
+  CopyTree("/Home","/Demo/AcctExample");
+  DelTree("/Demo/AcctExample/TAD");
+  DelTree("/Demo/AcctExample/Sup1");
+  DelTree("/Demo/AcctExample/Sup2");
+  DelTree("/Demo/AcctExample/Sup3");
+  Del("/Demo/AcctExample/Test*");
+  if (FileFind("~/Sup1/Sup1Utils/SortHeaders.HC.Z"))
+    ExeFile("~/Sup1/Sup1Utils/SortHeaders.HC.Z");
+
+  CursorRem("/*");
+  DelTree("/Demo/*.BI*");
+  S2T("/*","+r+S");
+  DocOpt("/*","+R");
+  Move(ACD_DEF_FILENAME,ACD_DEF_FILENAME_Z);
+}
+
+U0 DbgDistroFilePrep()
+{
+  CBlkDev *bd;
+  if (!Let2Drv('A',FALSE)) {
+    In(CFG_DBG_DISTRO "\n");
+    Mount;
+  }
+  bd=Let2BlkDev('A');
+  Fmt('A',,FALSE,FSt_REDSEA);
+
+  DirMk("A:/Compiler");
+  Copy("C:/Compiler/Compiler.BIN.Z",    "A:/Compiler");
+  Copy("C:/Compiler/OpCodes.DD.Z",      "A:/Compiler");
+  Copy("C:/Compiler/CompilerA.HH.Z",    "A:/Compiler");
+  Copy("C:/Compiler/CompilerB.HH.Z",    "A:/Compiler");
+
+  DirMk("A:/Kernel");
+  Copy("C:/Kernel/*.HH*",               "A:/Kernel");
+  CopyTree("C:/Kernel/BlkDev",          "A:/Kernel/BlkDev");
+
+  Copy("C:/Home/Sup1/Sup1Distro/DbgStartOS.HC.Z","A:/StartOS.HC.Z");
+
+  DirMk("A:/Adam");
+  Copy("C:/Home/Sup1/Sup1Distro/DbgMakeAdam.HC.Z","A:/Adam/MakeAdam.HC.Z");
+  Copy("C:/Home/Sup1/Sup1Distro/DbgMount.HC.Z","A:/Adam");
+  Copy("C:/Adam/AExts.HC.Z",    "A:/Adam");
+  Copy("C:/Adam/AMath.HC.Z",    "A:/Adam");
+  Copy("C:/Adam/Training.HC.Z","A:/Adam");
+  Copy("C:/Adam/AMem.HC.Z",     "A:/Adam");
+  Copy("C:/Adam/TaskRep.HC.Z",  "A:/Adam");
+
+  FileWrite("C:" CFG_DBG_DISTRO_FILE,
+        bd->RAM_dsk,(bd->max_blk+1)<<BLK_SIZE_BITS);
+}
+
+
+U0 StdDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home");
+  DirMk(TOS_DISTRO_DIR "/Home");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+  Del(TOS_DISTRO_DIR BOOT_DIR "/OldMBR.BIN.C");
+  Del(TOS_DISTRO_DIR BOOT_DIR "/BootMHD2.BIN.C");
+}
+U0 MakeStdDistro()
+{
+  StdDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOSCD_SIZE",
+        "Download TempleOS V5.03 - Standard Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+U0 LiteDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home");
+  DirMk(TOS_DISTRO_DIR "/Home");
+  DelTree(TOS_DISTRO_DIR "/Apps");
+  DelTree(TOS_DISTRO_DIR "/Demo");
+  Copy(TOS_DISTRO_DIR "/Demo/Games/Talons.HC.Z",TOS_DISTRO_DIR "/Home");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+  Del(TOS_DISTRO_DIR BOOT_DIR "/OldMBR.BIN.C");
+  Del(TOS_DISTRO_DIR BOOT_DIR "/BootMHD2.BIN.C");
+  Del(TOS_DISTRO_DIR "/Adam/AutoComplete/ACDefs.DATA.Z");
+  Del(TOS_DISTRO_DIR "/Adam/AutoComplete/ACWords.DATA.Z");
+  Del(TOS_DISTRO_DIR "/Misc/Bible.TXT.Z");
+}
+U0 MakeLiteDistro()
+{
+  LiteDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOSCD_SIZE",
+        "Download TempleOS V5.03 - Standard Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+U0 DbgDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  DbgDistroFilePrep;
+  In(TOS_DVD_DBG_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home");
+  DirMk(TOS_DISTRO_DIR "/Home");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+  Del(TOS_DISTRO_DIR BOOT_DIR "/OldMBR.BIN.C");
+  Del(TOS_DISTRO_DIR BOOT_DIR "/BootMHD2.BIN.C");
+}
+U0 MakeDbgDistro()
+{
+  DbgDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOS_DBG_SIZE",
+        "Download TempleOS V5.03 - Debug Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+U0 StaffDistroPrep()
+{
+  Drv('C');
+  DistroPrep;
+  In(TOS_DVD_CFG);
+  BootDVDIns('C');
+  Fmt('B',,FALSE,FSt_REDSEA);
+  DelTree(TOS_DISTRO_DIR);
+  CopyTree("C:/",TOS_DISTRO_DIR "/");
+  DelTree(TOS_DISTRO_DIR "/Home/Sup1");
+  DelTree(TOS_DISTRO_DIR "/Home/Sup2");
+  DelTree(TOS_DISTRO_DIR "/Home/Sup3");
+  Del(TOS_DISTRO_DIR "/" KERNEL_BIN_C);
+}
+U0 MakeStaffDistro()
+{
+  StaffDistroPrep;
+  RedSeaISO(TOS_ISO_NAME,TOS_DISTRO_DIR,TOS_DISTRO_DIR BOOT_DIR_KERNEL_BIN_C);
+  DefinePrint("DD_TEMPLEOS_STAFF_SIZE",
+        "Download TempleOS V5.03 - T.S. Company Internal Distro (%0.1fMB)",
+        0.1*(10*Size(TOS_ISO_NAME,"+s")/1024/1024));
+  Drv('C');
+}
+
+I64 UpdateLineCnts()
+{
+  I64 res;
+
+  DocClear;
+  Drv('C');
+  DistroPrep;
+
+  Cd("C:/");
+  DelTree("B:/TOS/TOS");
+  CopyTree("C:/Home","B:/TOS/TOS");
+  DelTree("C:/Home");
+
+  DocMax;
+  DocClear;
+  res=LineRep("C:/*","-r")+LineRep("C:/Adam/*")+
+        LineRep("C:/Compiler/*","-S+$")+LineRep("C:/Kernel/*");
+  CopyTree("B:/TOS/TOS","C:/Home");
+  DelTree("B:/TOS/TOS");
+
+  DocTreeFWrite("C:/Adam/ADefine.HC.Z","LineRep",
+        "DefinePrint(\"DD_TEMPLEOS_LOC\",\"%,d\");\n",res);
+  DefinePrint("DD_TEMPLEOS_LOC","%,d",res);
+
+  "Total LOC:%12,d\n\n",res;
+  return res;
+}
+
+U0 UpdateISODocDefines()
+{
+  try {
+    DefinePrint("DD_TEMPLEOSCD_SIZE",
+          "Download TempleOS V5.03 - Standard Distro (%0.1fMB)",
+          0.1*(10*Size("D:/Downloads/TOS_Distro.ISO","+s")/1024/1024));
+    DefinePrint("DD_TEMPLEOSCD_K_SIZE",
+          "%dKB",Size("D:/Downloads/TOS_Distro.ISO","+s")/1024);
+  } catch
+    Fs->catch_except=TRUE;
+}
+UpdateISODocDefines;
+
+
+I64 tos_progress;
+F64 tos_progress_t0;
+
+U0 TOSProgress(U8 *st)
+{
+  U8 buf[STR_LEN];
+  progress4=tos_progress;
+  progress3_max=1;
+  *progress4_desc=0;
+  progress4_max=9+MAKE_LITE+MAKE_DBG+MAKE_STAFF;
+  progress4_t0=tos_progress_t0;
+  StrPrint(buf,"%d. %s",++progress4,st);
+  "$PURPLE$$TX+CX,\"%s\"$$FG$\n",buf;
+  StrCpy(progress3_desc,buf);
+  tos_progress=progress4;
+}
+
+U0 TOSRegen2()
+{
+  I64 slash_home=0;
+  SettingsPush; //See SettingsPush
+  tos_progress=-1;
+  tos_progress_t0=tS;
+  RegExe("TempleOS/TOSRegen");
+
+  TOSProgress("DskChk All");
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DskChkAll;
+
+  TOSProgress("Update Line Cnts");
+  UpdateLineCnts;
+
+  TOSProgress("Copy C to D");
+  TOSCopyDrv('C','D');
+
+  TOSProgress("Make Standard Distro ISO");
+  MakeStdDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Distro.ISO");
+
+  TOSProgress("Make Supplemental1 ISO");
+  RedSeaISO("D:/Downloads/TOS_Supplemental1","C:/Home/Sup1");
+
+  TOSProgress("Make Supplemental2 ISO");
+  RedSeaISO("D:/Downloads/TOS_Supplemental2","C:/Home/Sup2");
+
+  TOSProgress("Make Supplemental3 ISO");
+  RedSeaISO("D:/Downloads/TOS_Supplemental3","C:/Home/Sup3");
+
+#if MAKE_LITE
+  TOSProgress("Make Lite Distro ISO");
+  MakeLiteDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Lite.ISO");
+#endif
+#if MAKE_DBG
+  TOSProgress("Make Dbg Distro ISO");
+  MakeDbgDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Dbg.ISO");
+#endif
+#if MAKE_STAFF
+  TOSProgress("Make Staff Distro ISO");
+  MakeStaffDistro;
+  DocClear;
+  Move(TOS_ISO_NAME,"D:/Downloads/TOS_Staff.ISO");
+#endif
+
+  UpdateISODocDefines;
+  Cd("C:/");
+  DocClear;
+
+  TOSProgress("Check for Long Lines");
+  if (LongLines)
+    throw;
+
+  DocClear;
+  TOSProgress("Check for Broken DolDoc Links");
+  if (LinkChk)
+    throw;
+
+  TOSProgress("Find /Home");
+  slash_home=F2("/Home","-i+la");
+
+  TOSProgress("DskChk All");
+  Drv('C');
+  DskChkAll;
+
+  TOSProgress("Done");
+  SettingsPop;
+  "F2(\"/Home\") Cnt\t:%d\n",slash_home;
+  "Elapsed Time\t:%5.3fs\n",tS-progress4_t0;
+  ProgressBarsRst("TempleOS/TOSRegen");
+}
+
+public U0 TOSPreRegen()
+{//Copy bins from D:/Home/Sup1 to C:/Home/Sup1
+  Copy("D:/Home/" INS_REG_PERSONAL_INITIALS "/*",
+        "C:/Home/" INS_REG_PERSONAL_INITIALS);
+  DelTree("C:/Home/Sup1/Sup1Bin");
+  CopyTree("D:/Home/Sup1/Sup1Bin","C:/Home/Sup1/Sup1Bin");
+  Copy("D:/Home/Sup1/Sup1CodeScraps/Comm/TOSSocket*",
+        "C:/Home/Sup1/Sup1CodeScraps/Comm");
+  DelTree("C:/Downloads/Linux");
+  CopyTree("D:/Downloads/Linux","C:/Downloads/Linux");
+}
+
+public U0 TOSRegen()
+{//Generate distro ISO's
+  TOSBootHDIns('C');
+  Once("TOSRegen2;");
+  BootRAM("C:/Kernel/" KERNEL_BIN_C); //Boot to load TOS_CFG.
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSExt.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSExt.HC.HTML new file mode 100755 index 0000000..340f4bf --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSExt.HC.HTML @@ -0,0 +1,341 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS/God;God/TOS"
+
+#define NIST_TIME_OFFSET        (tos_nist_offset-local_time_offset/CDATE_FREQ)
+#define NIST_TIME_TO_SWITCH     3
+
+#define GSRC_NIST_BEACON        0
+#define GSRC_HOTBITS            1
+#define GSRC_ANU_NIST           2
+#define GSRC_GOOGLE             3
+#define GSRC_RANDOM_ORG         4
+#define GSRC_RANDOM_NUMBERS_INFO 5
+#define GSRC_PASSWORD           6
+#define GSRC_GENERATE_DATA      7
+#define GSRC_VIRTUAL_NOTARY     8
+#define GSRC_TIMER              9
+
+#define GBP_SHORT       0
+#define GBP_MEDIUM      1
+#define GBP_LONG        2
+
+class CRandExtDec5Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,A=\"5 Decimal Digits from Hex:%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CHexWordForm
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,A=\"Hex Word Indices#0:%s\"$\n";
+  U8    rnd1[512]       format "$DA-P,A=\"Hex Word Indices#1:%s\"$\n";
+  U8    rnd2[512]       format "$DA-P,A=\"Hex Word Indices#2:%s\"$\n";
+  U8    rnd3[512]       format "$DA-P,A=\"Hex Word Indices#3:%s\"$\n";
+  U8    rnd4[512]       format "$DA-P,A=\"Hex Word Indices#4:%s\"$\n";
+  U8    rnd5[512]       format "$DA-P,A=\"Hex Word Indices#5:%s\"$\n";
+  U8    rnd6[512]       format "$DA-P,A=\"Hex Word Indices#6:%s\"$\n";
+  U8    rnd7[512]       format "$DA-P,A=\"Hex Word Indices#7:%s\"$\n";
+  U8    rnd8[512]       format "$DA-P,A=\"Hex Word Indices#8:%s\"$\n";
+  U8    rnd9[512]       format "$DA-P,A=\"Hex Word Indices#9:%s\"$\n";
+  U8    rndA[512]       format "$DA-P,A=\"Hex Word Indices#A:%s\"$\n";
+  U8    rndB[512]       format "$DA-P,A=\"Hex Word Indices#B:%s\"$\n";
+  I64   cert;
+};
+
+class CNISTBeaconHexWordForm
+{
+  I64   timestamp       format "$DA,A=\"TimeStamp:%d\"$\n";
+  U8    rnd0[512]       format "$DA-P,A=\"Hex Word Indices#0:%s\"$\n";
+  U8    rnd1[512]       format "$DA-P,A=\"Hex Word Indices#1:%s\"$\n";
+  U8    rnd2[512]       format "$DA-P,A=\"Hex Word Indices#2:%s\"$\n";
+  U8    rnd3[512]       format "$DA-P,A=\"Hex Word Indices#3:%s\"$\n";
+  U8    rnd4[512]       format "$DA-P,A=\"Hex Word Indices#4:%s\"$\n";
+  U8    rnd5[512]       format "$DA-P,A=\"Hex Word Indices#5:%s\"$\n";
+  U8    rnd6[512]       format "$DA-P,A=\"Hex Word Indices#6:%s\"$\n";
+  U8    rnd7[512]       format "$DA-P,A=\"Hex Word Indices#7:%s\"$\n";
+  U8    rnd8[512]       format "$DA-P,A=\"Hex Word Indices#8:%s\"$\n";
+  U8    rnd9[512]       format "$DA-P,A=\"Hex Word Indices#9:%s\"$\n";
+  U8    rndA[512]       format "$DA-P,A=\"Hex Word Indices#A:%s\"$\n";
+  U8    rndB[512]       format "$DA-P,A=\"Hex Word Indices#B:%s\"$\n";
+  I64   cert;
+};
+
+class CRandHex5Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P-TRM,LEN=5,"
+        "A=\"Line (5-Digit Hex):%5s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CRandHex8Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P-TRM,LEN=8,"
+        "A=\"Line (8-Digit Hex):%8s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CMoviesForm
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Movie #1-100 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CPaintings100Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Painting #00-99 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CPaintings1000Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Painting #000-999 (3 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CPoems100Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Poems #00-99 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CMetallicaForm
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,"
+        "A=\"Song #1-99 (2 Decimal Digits from Hex):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert;
+};
+
+class CCertRandDec5Form
+{
+  I64   timestamp;
+  U8    rnd0[512]       format "$DA-P,A=\"Line (Dec):%s\"$\n";
+  U8    rnd1[512];
+  U8    rnd2[512];
+  U8    rnd3[512];
+  U8    rnd4[512];
+  U8    rnd5[512];
+  U8    rnd6[512];
+  U8    rnd7[512];
+  U8    rnd8[512];
+  U8    rnd9[512];
+  U8    rndA[512];
+  U8    rndB[512];
+  I64   cert            format "$DA,A=\"Certificate:%d\"$\n";
+};
+
+class CGodVideoForm
+{
+  U8    title[STR_LEN]  format "$DA-P,A=\"Title:%s\"$\n";
+  U8    serial[STR_LEN] format "$DA-P-TRM,LEN=11,A=\"SerialNum:%11s\"$\n";
+  I64   min             format "$DA,A=\"Minutes:%d\"$\n";
+  I64   sec             format "$DA,A=\"Seconds:%d\"$\n";
+};
+
+class CWebBibleForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Tag Text:%s\"$\n";
+  U8    special[STR_LEN] format "$DA-P,A=\"Bible Passage:%s\"$\n";
+  I64   min;
+  I64   sec;
+};
+
+class CYouTubeForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Title:%s\"$\n";
+  U8    special[STR_LEN] format "$DA-P-TRM,LEN=11,A=\"SerialNum:%11s\"$\n";
+  I64   min             format "$DA,A=\"Minutes:%d\"$\n";
+  I64   sec             format "$DA,A=\"Seconds:%d\"$\n";
+};
+
+class CImgurForm
+{
+  U8    tag[STR_LEN];
+  U8    special[STR_LEN] format "$DA-P,A=\"SerialNum:%s\"$\n";
+  I64   min             format "$DA,A=\"Width    :%d\"$\n";
+  I64   sec             format "$DA,A=\"Height   :%d\"$\n";
+};
+
+class CWikipediaForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Tag Text:%s\"$\n";
+  U8    special[STR_LEN] format "$DA-P,A=\"Index   :%s\"$\n";
+  I64   min;
+  I64   sec;
+};
+
+class CWebBookMarkForm
+{
+  U8    tag[STR_LEN]    format "$DA-P,A=\"Tag Text:%s\"$\n";
+  U8    special[STR_LEN];
+  I64   min;
+  I64   sec;
+};
+
+DefineLstLoad("ST_FAMLY_PHOTOS","Family1_58-78\0Family2_78-86\0"
+        "Family3_86-99\0Family4_99\0");
+
+class CFamilyPhotoForm
+{
+  I64   volume          format  "$LS,D=\"ST_FAMLY_PHOTOS\"$\n";
+  I64   part            format  "$DA,A=\"Part   :%d\"$\n";
+  U8    picture[STR_LEN] format "$DA-P,A=\"Picture:%s\"$\n";
+  I64   width           format  "$GREEN$640x427 or 640x960$FG$\n"
+                                "$DA,A=\"Width  :%d\"$\n";
+  I64   height          format  "$DA,A=\"Height :%d\"$\n";
+};
+
+class CBlogImgForm
+{
+  U8    picture[STR_LEN] format "$DA-P,A=\"Picture:%s\"$\n";
+  I64   width           format "$DA,A=\"Width  :%d\"$\n";
+  I64   height          format "$DA,A=\"Height :%d\"$\n";
+};
+
+class CBlogVideoForm
+{
+  U8    video[STR_LEN]  format "$DA-P,A=\"Video:%s\"$\n";
+  Bool  big             format "$CB,\"Big\"$\n";
+};
+
+extern U0 FreshenBlog();
+extern U0 GodBooksPassageU32(U32 rand_u32,U8 *files_find_mask,
+        U8 *file_mask="*",I64 len=512,I64 verbosity=GBP_MEDIUM);
+extern I64 GodHeaderIns(U8 *type=NULL);
+extern U0 GodVideoDigits(U8 *title,U8 *webpage,U8 *rnd,I64 digits,U8 *filename);
+extern U0 GodVideoU32(U32 rand_u32,U8 *filename);
+extern U0 GodWebIdx(U8 *title,U8 *webpage,U8 *rnd,I64 digits,U8 *filename)
+extern U0 GodWordBatch(CHexWordForm *gm,I64 radix,I64 digits);
+extern U0 TOSBookLines(U8 *book_filename,I64 book_lines,U8 *st,I64 num_lines,
+        I64 radix,Bool modulo,Bool plus_one);
+extern U0 TOSGodDoodle(I64 god_src,CNISTBeaconHexWordForm *gm=NULL);
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSMisc.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSMisc.HC.HTML new file mode 100755 index 0000000..d67c0fa --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSMisc.HC.HTML @@ -0,0 +1,194 @@ + + + + + + + + + + + +
+#help_index "Misc/TOS"
+
+Bool    fg_on =FALSE;
+
+I64 CopyVideo()
+{
+  I64 res=0;
+  Bool old_silent=Silent;
+  Del("D:/Tmp/*.AU");
+  Del("D:/Tmp/*.MV");
+  Silent(old_silent);
+  SndShift(&scrncast.snd_head,0.185);
+  AUWrite("D:/Tmp/AUDIO",&scrncast.snd_head,scrncast.t0_now,scrncast.t0_tS);
+  QueDel(&scrncast.snd_head,TRUE);
+  GR2MV("D:/Tmp/VID%03d.MV","B:/Tmp","+d");
+  return res;
+}
+
+#help_index "ScrnCast/TOS"
+U0 DelScrnShots()
+{
+  Bool old_silent=Silent;
+  DelTree("B:/Tmp");
+  DirMk("B:/Tmp");
+  Del("D:/Tmp/*.AU");
+  Del("D:/Tmp/*.MV");
+  Del("C:/Tmp/*.AU");
+  Del("C:/Tmp/*.MV");
+  Silent(old_silent);
+}
+
+public U0 FrameGrabberToggle(Bool sync_tone,Bool tos_theme,
+        Bool just_audio=FALSE)
+{//The frame grabber saves GR files to B:/Tmp.
+  static F64 last_time=0;
+  if (tS-last_time>3.0) {
+    last_time=tS;
+    if (fg_on) {
+      fg_on=FALSE;
+      ScrnCast(OFF);
+      User("CopyVideo;Exit;\n");
+    } else {
+      DelScrnShots;
+      fg_on=TRUE;
+      ScrnCast(ON,just_audio);
+      if (sync_tone) {Beep;}
+      if (tos_theme) {User("ExeFile(\"~/TOS/TOSTheme\");Exit;\n");}
+    }
+  }
+}
+
+public U0 JukeSongTAD(I64 num,I64 passes=2)
+{//Make movie of one song.
+  if (!fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  Sleep(200);
+  JukeSongsPuppet("~/TAD/Songs",passes,num,num+1);
+  if (fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+}
+
+public U0 JukeSongSup(I64 vol,I64 num,I64 passes=2)
+{//Make movie of one song.
+  U8 *st=MStrPrint("~/Sup%d/Sup%dHymns",vol,vol);
+  if (!fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  JukeSongsPuppet(st,passes,num,num+1);
+  if (fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  Free(st);
+}
+
+public U0 JukeLines(I64 vol,I64 start_line,I64 end_line)
+{//Make movie of many lines of songs, starting at 0.
+  U8 *st=MStrPrint("~/Sup%d/Sup%dHymns",vol,vol);
+  if (!fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  JukeSongsPuppet(st,,start_line*5,end_line*5);
+  if (fg_on)
+    FrameGrabberToggle(FALSE,FALSE);
+  Free(st);
+}
+
+public U0 TADHymns(I64 vol,I64 let)
+{//Make 2-lines of songs movie
+  I64 line=2*(ToUpper(let)-'A');
+  JukeLines(vol,line,line+2);
+}
+
+#help_index "Misc/TOS"
+public U0 DskChkAll()
+{//DskChk on C & D.
+  U8 *ptr=TOS_HDS;
+  while (*ptr) {
+    "DskChk('%c')\n",*ptr;
+    DskChk(*ptr++,TRUE);
+  }
+}
+
+public CDoc *DC2Doc(CDC *dc,I64 dx=0,I64 dy=0,I64 *_total_score=NULL)
+{//Use OCR to make a text DolDoc from CDC.
+  U8 byte_bit_cnts[256];
+  I64 i,j,*ptr,row,col,ch,best_ch,score,best_score,
+        cur_char_image,diff_image,total_score=0;
+  CDoc *doc=DocNew;
+
+  MemSet(byte_bit_cnts,0,sizeof(byte_bit_cnts));
+  for (i=0;i<256;i++)
+    for (j=0;j<7;j++)
+      if (Bt(&i,j))
+        byte_bit_cnts[i]++;
+
+  for (row=0;row<dc->height/FONT_HEIGHT;row++) {
+    for (col=0;col<dc->width/FONT_WIDTH;col++) {
+
+      cur_char_image=0;
+      for (i=0;i<FONT_HEIGHT;i++)
+        for (j=0;j<FONT_WIDTH;j++)
+          if (GrPeek(dc,col*FONT_WIDTH+j+dx,row*FONT_HEIGHT+i+dy)!=WHITE)
+            LBts(&cur_char_image,i*8+j);
+
+      best_score=I64_MAX;
+      best_ch=0;
+      ptr=&text.font[32];
+      for (ch=32;ch<127;ch++) {
+        diff_image=*ptr++ ^ cur_char_image;
+        score=0;
+        for (i=0;i<8;i++)
+          score+=byte_bit_cnts[diff_image.u8[i]];
+        if (score<best_score) {
+          best_score=score;
+          best_ch=ch;
+        }
+      }
+      if (best_ch=='$')
+        DocPrint(doc,"$$");
+      else
+        DocPrint(doc,"%c",best_ch);
+      total_score+=best_score;
+    }
+    DocPrint(doc,"\n");
+  }
+  if (_total_score) *_total_score=total_score;
+  return doc;
+}
+
+#define MEM_TEST_SIZE   1024*1024
+U0 MemTest()
+{
+  U8 *b;
+  while (sys_data_bp->alloced_u8s-sys_data_bp->used_u8s>0x1000000) {
+    b=MAlloc(MEM_TEST_SIZE,Fs->data_heap);
+    MemSet(b,0x88,MSize(b));
+    "Data:%X\n",sys_data_bp->alloced_u8s-sys_data_bp->used_u8s;
+    Yield;
+  }
+  while (sys_code_bp->alloced_u8s-sys_code_bp->used_u8s>0x1000000) {
+    b=MAlloc(MEM_TEST_SIZE,Fs->code_heap);
+    MemSet(b,0x88,MSize(b));
+    "Code:%X\n",sys_code_bp->alloced_u8s-sys_code_bp->used_u8s;
+    Yield;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSTheme.HC.HTML b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSTheme.HC.HTML new file mode 100755 index 0000000..97d02f5 --- /dev/null +++ b/public/Wb/Home/Src/Demo/AcctExample/TOS/TOSTheme.HC.HTML @@ -0,0 +1,233 @@ + + + + + + + + + + + +
+/*
+This is one of the oldest songs.  I picked
+the random name "risen" and said to God
+"Oh, you're ambitious," thinking it was
+an epic name.  He laughed and gave an
+epic song!
+*/
+
+
+
+
+                                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                                <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                                <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                                <4>/* Graphics Not Rendered in HTML */
+
+
+
+F64 t0=Beat;
+
+#define WING    24
+#define BODY    8
+
+U0 Bird(CDC *dc,F64 wing_theta)
+{
+  CD3I32 p[3];
+  dc->color=WHITE;
+
+  p[0].x=0; p[0].y=0; p[0].z=-BODY;
+  p[1].x=0; p[1].y=0; p[1].z=BODY;
+  p[2].x=-WING*Cos(wing_theta); p[2].y=-WING*Sin(wing_theta); p[2].z=0;
+  GrFillPoly3(dc,3,p);
+
+  p[0].x=0; p[0].y=0; p[0].z=-BODY;
+  p[1].x=0; p[1].y=0; p[1].z=BODY;
+  p[2].x=WING*Cos(wing_theta); p[2].y=-WING*Sin(wing_theta); p[2].z=0;
+  GrFillPoly3(dc,3,p);
+
+  dc->color=ROPF_DITHER+WHITE<<16+LTGRAY;
+  dc->thick=3;
+  GrLine3(dc,0,0,-BODY,0,0,BODY);
+}
+
+#define SCALE           115
+#define ARM             112
+#define CHAIN           100
+#define CUP             28
+#define TILT            -.25
+#define ARM_Y           -(0.93*CHAIN)
+#define ARM_Z           -45
+
+#define BIRDS_NUM       7
+#define RANGE           40
+F64 bx[BIRDS_NUM],by[BIRDS_NUM];
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i;
+  F64 theta,dt=Beat-t0,d_chain=Sin(pi/64*Sin(pi*dt/4))*CHAIN;
+  if (t0) {
+    DCDepthBufAlloc(dc);
+    dc->flags|=DCF_TRANSFORMATION;
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1;
+    dc->y=task->pix_height>>1-SCALE;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotX(dc->r,TILT);
+    Mat4x4RotZ(dc->r,pi/64*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<3>);
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1-ARM;
+    dc->y=task->pix_height>>1-SCALE+CHAIN-d_chain;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotX(dc->r,TILT+pi/32*Sin(pi*dt/4));
+    Mat4x4RotY(dc->r,pi/32*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<2>);
+
+    Mat4x4IdentEqu(dc->r);
+    Mat4x4RotX(dc->r,TILT);
+    dc->color=BLACK;
+    GrLine3(dc,0,ARM_Y,ARM_Z,0,0,0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,CUP,0,-0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,-CUP,0,-0.707*CUP);
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1+ARM;
+    dc->y=task->pix_height>>1-SCALE+CHAIN+d_chain;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotX(dc->r,TILT-pi/32*Sin(pi*dt/4));
+    Mat4x4RotY(dc->r,-pi/32*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<2>);
+
+    Mat4x4IdentEqu(dc->r);
+    Mat4x4RotX(dc->r,TILT);
+    dc->color=BLACK;
+    GrLine3(dc,0,ARM_Y,ARM_Z,0,0,0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,CUP,0,-0.707*CUP);
+    GrLine3(dc,0,ARM_Y,ARM_Z,-CUP,0,-0.707*CUP);
+
+    Mat4x4IdentEqu(dc->r);
+    dc->x=task->pix_width>>1;
+    dc->y=task->pix_height>>1;
+    dc->z=3*GR_Z_ALL>>1;
+    Mat4x4RotZ(dc->r,0.6-pi/32*Sin(pi*dt/4));
+    Mat4x4RotX(dc->r,TILT-pi/32*Sin(pi*dt/4));
+    Mat4x4RotY(dc->r,-pi/32*Sin(pi*dt/4));
+    Sprite3(dc,0,0,0,<4>);
+
+    if (dt>=12.0) {
+      Mat4x4IdentEqu(dc->r);
+      dc->x=task->pix_width>>1;
+      dc->y=task->pix_height>>1;
+      dc->z=GR_Z_ALL;
+      Mat4x4Scale(dc->r,.5+.04*dt);
+      Sprite3(dc,0,0,0,<1>);
+    }
+
+    dc->y=task->pix_height+60;
+    for (i=0;i<BIRDS_NUM;i++) {
+      bx[i]=Clamp(bx[i]+0.35*SignI64(RandI16),-RANGE,RANGE);
+      by[i]=Clamp(by[i]+0.35*SignI64(RandI16),-RANGE,RANGE);
+      theta=pi/2*i/BIRDS_NUM+0.2*pi*dt+pi/2;
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4RotX(dc->r,pi/2);
+      Mat4x4RotZ(dc->r,theta);
+      Mat4x4TranslationEqu(dc->r,230*Cos(theta)+bx[i],230*Sin(theta)+by[i],
+            -(120*i/BIRDS_NUM+16*dt));
+      Mat4x4RotX(dc->r,0.45*pi+pi);
+      Bird(dc,Sin(2*pi*dt+i*2*pi/BIRDS_NUM));
+    }
+  }
+}
+
+U0 TOSTheme()
+{
+  I64 i,old_update=gr.fp_final_scrn_update;
+  gr.fp_final_scrn_update=NULL;
+  t0=0;
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  WinVert(0,TEXT_ROWS-1,Fs);
+  DocCursor;
+  DocClear;
+  Fs->text_attr=LTCYAN<<4+BLACK;
+  Fs->draw_it=&DrawIt;
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 2.85;
+  music.stacatto_factor= 0.902;
+  for (i=0;i<BIRDS_NUM;i++) {
+    bx[i]=RANGE*RandI16/RANGE;
+    by[i]=RANGE*RandI16/RANGE;
+  }
+  try {
+    "$BG+H,LTCYAN$";
+    Refresh(2);
+    for (i=0;i<1;i++) {
+      t0=Beat;
+      Play("5eDEqFFetEEFqDeCDDEetCGF");
+      Play("5eDEqFFetEEFqDeCDDEetCGF");
+      Play("5eDCqDE4eAA5etEEFEDG4B5DCqF");
+      Play("5eDCqDE4eAA5etEEFEDG4B5DCqF");
+    }
+    Refresh(2);
+  } catch
+    PutExcept;
+  SettingsPop;
+  gr.fp_final_scrn_update=old_update;
+}
+
+TOSTheme;
+
+ diff --git a/public/Wb/Home/Src/Demo/Asm/AsmAndC1.HC.HTML b/public/Wb/Home/Src/Demo/Asm/AsmAndC1.HC.HTML new file mode 100755 index 0000000..620c052 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/AsmAndC1.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+*/
+
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+        IMPORT  Beep;
+
+_BEEPS::
+//You can always clobber RAX,RBX,RCX,RDX,R8,R9.  The compiler expects that.
+//See REGG_CLOBBERED and REGG_STK_TMP.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RCX,U64 SF_ARG1[RBP]  //SF_ARG1
+
+@@05:   PUSH    RCX
+//U0 Beep(I8 ona=62,Bool busy=FALSE)
+        PUSH    FALSE   //Do not busy (spin) wait
+        PUSH    62      //500 Hz
+        CALL    Beep
+        POP     RCX
+        LOOP    @@05
+
+        POP     RBP
+        RET1    8       //Use special return. Pop one arg off of stack.
+
+//HolyC return vals are in RAX.  This function has no return value.
+}
+
+//_extern binds a asm sym to a function.
+//My convention is to put an underscore
+//on C callable asm routines.
+_extern _BEEPS U0 Beeps(I64 cnt);
+
+I64 AsmAndC1()
+{
+  I64 noreg i;  //Normally this would be stored in a reg
+//Check by unassembling with Uf("AsmAndC1").
+
+  i=GetI64("Num of beeps 1-5 (%d):",3,1,5);
+  Beeps(i);
+
+  asm {
+//You can clobber RAX,RBX,RCX,RDX.  The compiler expects that.
+
+    IMPORT      Snd; //Import an not use & or don't import and use &Snd.
+    MOV         RCX,&i[RBP] //You can clobber RAX,RBX,RCX,RDX.
+                //You better preserve the rest.
+@@05:   PUSH    RCX
+
+                //U0 Snd(I8 ona);
+    MOV         RAX,RCX //ona=loop*10+50
+    IMUL2       RAX,10 //TempleOS uses nonstandard opcodes
+                //to avoid multiple form of the same one.
+                //See ::/Compiler/OpCodes.DD.
+    ADD         RAX,40
+    PUSH        RAX
+    CALL        Snd
+
+    MOV         RCX,cnts.time_stamp_freq>>3 //JIT Const.  Simple delay loop
+@@10:   LOOP    @@10
+
+    POP         RCX
+    LOOP        @@05
+  }
+  Snd;
+  return i;
+}
+
+"Beeps:%d\n",AsmAndC1;
+
+ diff --git a/public/Wb/Home/Src/Demo/Asm/AsmAndC2.HC.HTML b/public/Wb/Home/Src/Demo/Asm/AsmAndC2.HC.HTML new file mode 100755 index 0000000..71ebcc3 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/AsmAndC2.HC.HTML @@ -0,0 +1,116 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+*/
+
+//This is to demo glbl var access.
+//Glbs defined elsewhere can accessed too, like cnts.jiffies.
+I64 glbl_ona=Freq2Ona(400),glbl_ona_step=10,glbl_ona_base=Freq2Ona(100);
+
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+JIFFIES_MSG:    DU8 "Jiffies:",0;
+
+//See ::/Kernel/StrA.HC and ::/Kernel/KUtils.HC.
+
+_BEEPS2::
+//You can clobber RAX,RBX,RCX,RDX,R8,R9.  The compiler expects that.
+//See REGG_CLOBBERED and REGG_STK_TMP.
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RCX,U64 SF_ARG1[RBP] //SF_ARG1
+
+        PUSH    U64 [&cnts.jiffies]
+
+@@05:   PUSH    RCX
+//U0 Beep(I8 ona=62,Bool busy=FALSE)
+        PUSH    FALSE   //Do not busy (spin) wait
+        PUSH    U64 [&glbl_ona] //evaluated at run time
+        CALL    &Beep
+        POP     RCX
+        LOOP    @@05
+
+        PUSH    RSI     //See REGG_LOCAL_VARS & REGG_LOCAL_NON_PTR_VARS
+        MOV     RSI,JIFFIES_MSG
+        CALL    PUT_STR
+        POP     RSI
+
+        POP     RAX
+        SUB     RAX,U64 [&cnts.jiffies]
+        NEG     RAX
+        CALL    PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    PUT_CHARS
+
+        POP     RBP
+        RET1    8
+}
+
+//My convention is to put an underscore
+//on C callable asm routines.
+_extern _BEEPS2 U0 Beeps2(I64 cnt);
+
+U0 AsmAndC2()
+{
+  I64 reg R15 i;
+
+  i=GetI64("$PURPLE$\n\nNum of beeps 1-5 (%d):$FG$",3,1,5);
+  Beeps2(i);
+
+  asm {
+    LIST
+//You can clobber RAX,RBX,RCX,RDX, but preserve the rest.
+    MOV RCX,R15 //You can clobber RAX,RBX,RCX,RDX. Preserve the rest.
+    @@05:       PUSH    RCX
+
+//U0 Snd(I8 ona);
+    MOV RAX,RCX //ona=loop*10+100.0Hz
+    IMUL2       RAX,glbl_ona_step //Intentionally evaluated at compile time
+    ADD RAX,U64 [&glbl_ona_base]  //Intentionally evaluated at run time
+    PUSH        RAX
+    CALL        &Snd    //We can skip IMPORT with & if JIT compiling.
+    MOV RCX,cnts.time_stamp_freq>>3 //JIT Const.  Simple delay loop.
+@@10:   LOOP    @@10
+
+    POP RCX
+    LOOP        @@05
+  }
+  Snd;
+}
+
+AsmAndC2;
+
+ diff --git a/public/Wb/Home/Src/Demo/Asm/AsmAndC3.HC.HTML b/public/Wb/Home/Src/Demo/Asm/AsmAndC3.HC.HTML new file mode 100755 index 0000000..16fc983 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/AsmAndC3.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+*/
+
+U0 AsmAndC3()
+{
+  I64 i;
+  for (i=0;i<3;i++) {
+    "Meaning of life:";
+    MOV AL,0x41
+    STC
+    ADC AL,0 //Round-about way to make the not-special constant, 0x42.
+    CALL        PUT_HEX_U8
+    MOV RCX,cnts.time_stamp_freq>>5 //JIT Const.  Simple delay loop.
+@@1:    LOOP    @@1
+    '\n';
+  }
+}
+
+AsmAndC3;
+
+ diff --git a/public/Wb/Home/Src/Demo/Asm/AsmHelloWorld.HC.HTML b/public/Wb/Home/Src/Demo/Asm/AsmHelloWorld.HC.HTML new file mode 100755 index 0000000..41f9b5f --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/AsmHelloWorld.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+/*Asm labels can only be defined once
+in a task.  <F5> will spawn a new task
+each time, so you don't get redefine
+error, like when repeatedly #including
+it from the cmd line.
+
+These are many useful kernel
+routines ::/Kernel/StrA.HC
+intended to be called from
+asm.  Generally, they preserve
+regs.
+
+You can call any routine you
+like, C or asm, if you import it.
+Be aware that C routines do not
+preserve RAX,RBX,RCX,RDX,R8,R9.
+When calling from the shell or
+from C, preserve all other regs.
+
+*/
+
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+MY_WORLD_MSG:
+//Define U8 does not put terminating zeros
+//on strings.
+        DU8     "World\n",0;
+
+//My convention is to put an underscore
+//on C callable asm routines.
+_HELLO_WORLD::
+        PUSH    RSI     //See REGG_LOCAL_VARS & REGG_LOCAL_NON_PTR_VARS
+        MOV     RCX,10
+@@05:   MOV     RAX,RCX
+        CALL    PUT_HEX_U8
+        MOV     RAX,CH_SPACE
+        CALL    PUT_CHARS
+        MOV     RAX,'Hello ' //Supports multi-byte char consts
+        CALL    PUT_CHARS
+//We broke it in two pieces to show different ways.
+        MOV     RSI,MY_WORLD_MSG
+        CALL    PUT_STR
+        LOOP    @@05
+        POP     RSI
+        RET
+};
+
+Call(_HELLO_WORLD);
+
+ diff --git a/public/Wb/Home/Src/Demo/Asm/BuzzFizz.HC.HTML b/public/Wb/Home/Src/Demo/Asm/BuzzFizz.HC.HTML new file mode 100755 index 0000000..23b2b67 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/BuzzFizz.HC.HTML @@ -0,0 +1,215 @@ + + + + + + + + + + + +
+#define RANGE_START     1
+#define RANGE_END       100
+ 
+#define FIZZ_SPAN       6
+#define BUZZ_SPAN       7
+ 
+asm {
+_BUZZ_FIZZ::
+        PUSH    RBP
+        MOV     RBP,RSP //Always set-up stk frame.  (Stack Gets Traced)
+        PUSH    RSI     //See REGG_LOCAL_VARS & REGG_LOCAL_NON_PTR_VARS
+        PUSH    RDI
+        MOV     RSI,FIZZ_SPAN-RANGE_START%FIZZ_SPAN+1
+        MOV     RDI,BUZZ_SPAN-RANGE_START%BUZZ_SPAN+1
+        MOV     RAX,RANGE_START
+ 
+@@05:   CALL    PUT_HEX_U64
+        PUSH    RAX
+        MOV     RAX,CH_SPACE
+        CALL    PUT_CHARS
+
+        DEC     RSI
+        JNZ     @@10
+        MOV     RAX,'FIZZ '
+        CALL    PUT_CHARS
+        MOV     RSI,FIZZ_SPAN
+
+@@10:   DEC     RDI
+        JNZ     @@15
+        MOV     RAX,'BUZZ '
+        CALL    PUT_CHARS
+        MOV     RDI,BUZZ_SPAN
+ 
+@@15:   MOV     RAX,'\n'
+        CALL    PUT_CHARS
+        POP     RAX
+        INC     RAX
+        CMP     RAX,RANGE_END   //Actually only a 32-bit inst.
+        JBE     @@05
+
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+}
+ 
+Call(_BUZZ_FIZZ);
+
+/*
+       _BUZZ_FIZZ+0x0000 55           PUSH      U64 RBP
+       _BUZZ_FIZZ+0x0001 488BEC       MOV       U64 RBP,U64 RSP
+       _BUZZ_FIZZ+0x0004 56           PUSH      U64 RSI
+       _BUZZ_FIZZ+0x0005 57           PUSH      U64 RDI
+       _BUZZ_FIZZ+0x0006 BE06000000   MOV       U32 ESI,U32 00000006
+       _BUZZ_FIZZ+0x000B BF07000000   MOV       U32 EDI,U32 00000007
+       _BUZZ_FIZZ+0x0010 B801000000   MOV       U32 EAX,U32 00000001
+       _BUZZ_FIZZ+0x0015 E8C51F2BC0   CALL      I32 PUT_HEX_U64+0x0000
+       _BUZZ_FIZZ+0x001A 50           PUSH      U64 RAX
+       _BUZZ_FIZZ+0x001B B820000000   MOV       U32 EAX,U32 00000020
+       _BUZZ_FIZZ+0x0020 E81E202BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0025 48FFCE       DEC       U64 RSI
+       _BUZZ_FIZZ+0x0028 7514         JNZ       I8 _BUZZ_FIZZ+0x003E
+       _BUZZ_FIZZ+0x002A 48B846495A5A MOV       U64 RAX,I64 000000205A5A4946
+       _BUZZ_FIZZ+0x0030 20000000
+       _BUZZ_FIZZ+0x0034 E80A202BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0039 BE06000000   MOV       U32 ESI,U32 00000006
+       _BUZZ_FIZZ+0x003E 48FFCF       DEC       U64 RDI
+       _BUZZ_FIZZ+0x0041 7514         JNZ       I8 _BUZZ_FIZZ+0x0057
+       _BUZZ_FIZZ+0x0043 48B842555A5A MOV       U64 RAX,I64 000000205A5A5542
+       _BUZZ_FIZZ+0x0049 20000000
+       _BUZZ_FIZZ+0x004D E8F11F2BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0052 BF07000000   MOV       U32 EDI,U32 00000007
+       _BUZZ_FIZZ+0x0057 B80A000000   MOV       U32 EAX,U32 0000000A
+       _BUZZ_FIZZ+0x005C E8E21F2BC0   CALL      I32 PUT_CHARS+0x0000
+       _BUZZ_FIZZ+0x0061 58           POP       U64 RAX
+       _BUZZ_FIZZ+0x0062 48FFC0       INC       U64 RAX
+       _BUZZ_FIZZ+0x0065 4883F864     CMP       U64 RAX,I8 64
+       _BUZZ_FIZZ+0x0069 76AA         JNA       I8 _BUZZ_FIZZ+0x0015
+       _BUZZ_FIZZ+0x006B 5F           POP       U64 RDI
+       _BUZZ_FIZZ+0x006C 5E           POP       U64 RSI
+       _BUZZ_FIZZ+0x006D 5D           POP       U64 RBP
+       _BUZZ_FIZZ+0x006E C3           RET
+
+0000000000000001
+0000000000000002
+0000000000000003
+0000000000000004
+0000000000000005
+0000000000000006 FIZZ
+0000000000000007 BUZZ
+0000000000000008
+0000000000000009
+000000000000000A
+000000000000000B
+000000000000000C FIZZ
+000000000000000D
+000000000000000E BUZZ
+000000000000000F
+0000000000000010
+0000000000000011
+0000000000000012 FIZZ
+0000000000000013
+0000000000000014
+0000000000000015 BUZZ
+0000000000000016
+0000000000000017
+0000000000000018 FIZZ
+0000000000000019
+000000000000001A
+000000000000001B
+000000000000001C BUZZ
+000000000000001D
+000000000000001E FIZZ
+000000000000001F
+0000000000000020
+0000000000000021
+0000000000000022
+0000000000000023 BUZZ
+0000000000000024 FIZZ
+0000000000000025
+0000000000000026
+0000000000000027
+0000000000000028
+0000000000000029
+000000000000002A FIZZ BUZZ
+000000000000002B
+000000000000002C
+000000000000002D
+000000000000002E
+000000000000002F
+0000000000000030 FIZZ
+0000000000000031 BUZZ
+0000000000000032
+0000000000000033
+0000000000000034
+0000000000000035
+0000000000000036 FIZZ
+0000000000000037
+0000000000000038 BUZZ
+0000000000000039
+000000000000003A
+000000000000003B
+000000000000003C FIZZ
+000000000000003D
+000000000000003E
+000000000000003F BUZZ
+0000000000000040
+0000000000000041
+0000000000000042 FIZZ
+0000000000000043
+0000000000000044
+0000000000000045
+0000000000000046 BUZZ
+0000000000000047
+0000000000000048 FIZZ
+0000000000000049
+000000000000004A
+000000000000004B
+000000000000004C
+000000000000004D BUZZ
+000000000000004E FIZZ
+000000000000004F
+0000000000000050
+0000000000000051
+0000000000000052
+0000000000000053
+0000000000000054 FIZZ BUZZ
+0000000000000055
+0000000000000056
+0000000000000057
+0000000000000058
+0000000000000059
+000000000000005A FIZZ
+000000000000005B BUZZ
+000000000000005C
+000000000000005D
+000000000000005E
+000000000000005F
+0000000000000060 FIZZ
+0000000000000061
+0000000000000062 BUZZ
+0000000000000063
+0000000000000064
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/Asm/DivByHand.HC.HTML b/public/Wb/Home/Src/Demo/Asm/DivByHand.HC.HTML new file mode 100755 index 0000000..3c1a013 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/DivByHand.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+asm {
+_DIV_U64_BY_U64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        XOR     RDX,RDX
+        MOV     RCX,64
+        MOV     RAX,SF_ARG1[RBP]
+        MOV     RBX,SF_ARG2[RBP]
+@@1:    SHL1    RAX
+        RCL1    RDX
+        CMP     RBX,RDX
+        JA      @@2
+        INC     RAX
+        SUB     RDX,RBX
+@@2:    LOOP    @@1
+        POP     RBP
+        RET1    16
+}
+
+_extern _DIV_U64_BY_U64 I64 DivU64ByU64(I64 dividend,I64 divisor);
+
+"123456/10=%d\n",DivU64ByU64(123456,10);
+ diff --git a/public/Wb/Home/Src/Demo/Asm/MulByHand.HC.HTML b/public/Wb/Home/Src/Demo/Asm/MulByHand.HC.HTML new file mode 100755 index 0000000..62fc12e --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/MulByHand.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+/*When I was a kid with a Commodore 64,
+the 6502 chip had no multiply inst
+and this is how we had to do it, except,
+I used more regs in this example.
+*/
+asm {
+//Opcodes are slightly different to make writing my x86_64 assembler easier.
+//See ::/Compiler/OpCodes.DD.
+
+//You can clobber RAX,RBX,RCX,RDX,R8,R9.  The compiler expects that.
+
+MUL_BY_HAND_U8_U8_TO_U16: //This is only for fun.
+//8bit * 8bit-->16bit
+//AL*BL-->AX
+        MOV     CL,8
+        SHL     AX,8
+@@05:   SHL1    AX
+        JNC     @@10
+        ADD     AL,BL
+@@10:   DEC     CL
+        JNZ     @@05
+        RET
+
+_MUL_BY_HAND_U8_U8_TO_U16::     //C callable
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     AL,U8 SF_ARG1[RBP] //SF_ARG1
+        MOV     BL,U8 SF_ARG2[RBP]
+        CALL    MUL_BY_HAND_U8_U8_TO_U16
+        MOVZX   RAX,AX
+        POP     RBP
+        RET1    16
+
+_MUL_U64_U64_TO_U128::
+//64bit * 64bit-->128bit
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP] //SF_ARG1
+        MUL     U64 SF_ARG2[RBP]        //Res RDX:RAX 128bit
+        MOV     U64 [RBX],RAX
+        MOV     U64 8[RBX],RDX
+        POP     RBP
+        RET1    24
+};
+
+//My convention is to put an underscore
+//on C callable asm routines.
+_extern _MUL_BY_HAND_U8_U8_TO_U16 U16 MulU8(U8 n1,U8 n2);
+
+class U128
+{
+  U64 lo,hi;
+};
+
+_extern _MUL_U64_U64_TO_U128 U0 MulU64(I64 n1,I64 n2,U128 *_prod);
+
+U0 MulByHand()
+{
+  U128 p;
+  "2*7   =0x%X\n",MulU8(2,7);
+  "100*10=0x%X\n",MulU8(100,10);
+
+  MulU64(0x0123456789ABCDEF,0x1000001,&p);
+  "0x0123466789ABCDEF*0x1000001=0x%016X%016X\n",p.hi,p.lo;
+}
+
+MulByHand;
+
+
+ diff --git a/public/Wb/Home/Src/Demo/Asm/PutDec.HC.HTML b/public/Wb/Home/Src/Demo/Asm/PutDec.HC.HTML new file mode 100755 index 0000000..5d7748d --- /dev/null +++ b/public/Wb/Home/Src/Demo/Asm/PutDec.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+asm {
+PUT_DEC_U64::
+//RAX is number to print in decimal.
+//Preserves all regs.
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,24          //24 char buffer on stack
+
+//Save regs which C code is free to clobber.  We don't have to for C callers,
+//but this function will be nice for ASM callers if it saves all regs.
+        PUSH_C_REGS
+
+        PUSH    RSI           //See REGG_LOCAL_VARS&REGG_LOCAL_NON_PTR_VARS
+        LEA     RSI,-1[RBP]     //Load addr of end of buffer.
+                                //We picked RSI because of PUT_STR
+                                //We'll move bwd
+        MOV     U8 [RSI],0      //Terminator
+
+        TEST    RAX,RAX         //Special case -- zero
+        JNZ     @@05
+        DEC     RSI
+        MOV     U8 [RSI],'0'
+        JMP     @@15
+
+@@05:   MOV     RBX,10          //Divides by 10
+
+@@10:   XOR     RDX,RDX
+        DIV     RBX             //RAX=(RDX:RAX)/RBX with remainder in RDX
+        ADD     RDX,'0'
+        DEC     RSI
+        MOV     U8 [RSI],DL
+        TEST    RAX,RAX
+        JNZ     @@10
+
+@@15:   CALL    PUT_STR
+        POP     RSI
+        POP_C_REGS
+        LEAVE
+        RET
+
+_DO_IT::        //The convention is C-callable routines have underscores.
+        MOV     RAX,122333221
+        CALL    PUT_DEC_U64
+        MOV     RAX,'\n'
+        CALL    PUT_CHARS
+        RET
+}
+
+Call(_DO_IT);
+
+ diff --git a/public/Wb/Home/Src/Demo/Carry.HC.HTML b/public/Wb/Home/Src/Demo/Carry.HC.HTML new file mode 100755 index 0000000..a3bacd9 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Carry.HC.HTML @@ -0,0 +1,76 @@ + + + + + + + + + + + +
+//Shows the Carry function.  It holds the CPU carry flag.
+//U() Unassemble to make sure it is right.
+
+U0 BigCnt()
+{
+  U64 lo=0,hi=0;
+  "BigCnt\n";
+  while (hi<0x10) {
+    lo+=1<<58;
+    hi+=Carry;
+    "%016X %016X\n",hi,lo;
+  }
+}
+
+BigCnt;
+
+U0 BigShift()
+{
+  U64 lo=1,hi=0;
+  "Big Shift\n";
+  while (lo||hi) {
+    hi<<=1;
+    lo<<=1;
+    hi+=Carry;
+    "%016X %016X\n",hi,lo;
+  }
+}
+
+BigShift;
+
+U0 Branch()
+{
+  U64 i=0xFFCC3311,j;
+  'Branch\n';
+  for (j=0;j<64;j++) {
+    i<<=1;
+    if (Carry)
+      '1';
+    else
+      '0';
+  }
+  '\n';
+}
+
+Branch;
+
+ diff --git a/public/Wb/Home/Src/Demo/ClassMeta.HC.HTML b/public/Wb/Home/Src/Demo/ClassMeta.HC.HTML new file mode 100755 index 0000000..236bd4d --- /dev/null +++ b/public/Wb/Home/Src/Demo/ClassMeta.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+/*Demonstrates class meta data.
+Basically, we make use of the compiler's
+data about a class.  We can add to the
+compilers data arbitrary items, either string or
+or int or F64 (if you typecast).
+
+This stuff is not high performance.
+Don't get carried away -- it might be slow.
+*/
+
+U0 RankOut(I64 i)
+{
+  " %z",i,"Cadet\0Ensign\0Captain\0Admiral\0President\0";
+}
+
+class Test1Struct
+{
+  I64 age       print_str "%2d" dft_val 38;
+  I64 color     dft_val RED; //Accepts expressions
+  I64 rank      print_str "%1d" dft_val 6/2 output_fun &RankOut;
+};
+
+class Test2Struct
+{
+  I64 age        print_str "%2d" dft_val 38 percentile 54.20;
+  I64 rank       print_str "%1d" dft_val 5;
+  I64 serial_num print_str "%6d" dft_val 123456;
+};
+
+U0 DumpStruct(U8 *_d,U8 *class_name=lastclass)
+{//lastclass is keyword.  See ::/Demo/LastClass.HC.
+  CHashClass *tmpc=HashFind(class_name,Fs->hash_table,HTT_CLASS);
+  U8 *print_str;
+  I64 *q,dft_val;
+  U0 (* fp_output_fun)(I64 i);
+  F64 percentile;
+  if (!tmpc) return;
+  CMemberLst *ml;
+  ml=tmpc->member_lst_and_root;
+  while (ml) {
+    "%s:",ml->str;
+
+    //All our items are I64's.  If you want, you can check
+    //the data type of the member var.  See ClassRep().
+    q=_d+ml->offset;
+
+    if (print_str=MemberMetaData("print_str",ml))
+      "" print_str,*q;
+
+      //This is slightly ambiguous -- if no meta is present it will return zero.
+    if (dft_val=MemberMetaData("dft_val",ml))
+      " default:%d",dft_val;
+
+      //This corrects for the ambiguity, allowing zero percentile.
+    if (MemberMetaFind("percentile",ml)) {//check if it exists
+//We could use the CMemberLstMeta structure returned by
+      //MemberMetaFind() and save a search.
+      percentile=MemberMetaData("percentile",ml)(F64);
+      " percentile: %5.2f",percentile;
+    }
+
+    if (fp_output_fun=MemberMetaData("output_fun",ml))
+      (*fp_output_fun)(*q);
+    '\n';
+    ml=ml->next;
+  }
+}
+
+Test1Struct t1;
+t1.age=44;
+t1.rank=3;
+
+DumpStruct(&t1);
+
+Test2Struct t2;
+t2.age=22;
+t2.rank=2;
+t2.serial_num=55555;
+
+DumpStruct(&t2);
+
+ diff --git a/public/Wb/Home/Src/Demo/CompileDemo.HC.HTML b/public/Wb/Home/Src/Demo/CompileDemo.HC.HTML new file mode 100755 index 0000000..66e44a5 --- /dev/null +++ b/public/Wb/Home/Src/Demo/CompileDemo.HC.HTML @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+F64 glbl;
+
+F64 CompileDemo(U8 *st)
+{
+  I64 type;
+  U8 *machine_code;
+  CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
+  F64 res=0;
+  Lex(cc);  //Gotta get it started
+  "Compile \"%s\"\n",st;
+  do {
+    if (machine_code=LexExpression2Bin(cc,&type)) {
+      if (type!=RT_F64)
+        res=ToF64(Call(machine_code));
+      else
+        res=Call(machine_code)(F64);
+      Free(machine_code);
+    }
+    "res=%9.4f\n",res;
+    if (cc->token==';')
+      Lex(cc);
+  } while (cc->token!=TK_EOF);  //end of file?
+  CmpCtrlDel(cc);
+  return res;
+}
+
+CompileDemo("2+Cos(pi)");
+CompileDemo("1;2+4");
+CompileDemo("glbl=1;glbl*2;glbl/3;Sin(glbl)");
+
+//This is just like you typed-it on
+//the cmd line.
+ExePrint(
+"I64 i;"
+"for (i=0;i<10;i++) "
+"  \"%%d\n\",i;"
+);
+
+ diff --git a/public/Wb/Home/Src/Demo/DateTime.HC.HTML b/public/Wb/Home/Src/Demo/DateTime.HC.HTML new file mode 100755 index 0000000..1a802ad --- /dev/null +++ b/public/Wb/Home/Src/Demo/DateTime.HC.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+
+"\n\n%D %T\n\n\n",Now,Now;
+
+CDateStruct ds;
+Date2Struct(&ds,Now+local_time_offset);
+
+"Hour:%02d Minute:%02d Second:%02d\n\n\n",ds.hour,ds.min,ds.sec;
+
+"Day Name:%03tZ\n\n\n",ds.day_of_week,"ST_DAYS_OF_WEEK";
+
+"Month Name:%03tZ\n\n\n",ds.mon-1,"ST_MONTHS";
+
+ diff --git a/public/Wb/Home/Src/Demo/DbgDemo.HC.HTML b/public/Wb/Home/Src/Demo/DbgDemo.HC.HTML new file mode 100755 index 0000000..87d0fd7 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DbgDemo.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+/*
+Press <CTRL-ALT-c> to break.
+
+Rerun Program
+
+Press <CTRL-ALT-d> to enter Dbg.
+> Dr;   //Dump Regs
+> G2;   //Cont program
+
+Press <CTRL-ALT-d> to enter Dbg.
+> Uf("DbgDemo");
+> U(_RIP);
+
+See Debugging
+*/
+
+U0 DbgDemo()
+{
+  I64 i=0;
+  while (TRUE)
+    if (!(i++%2000000))
+      ".";
+}
+
+DbgDemo;
+
+
+ diff --git a/public/Wb/Home/Src/Demo/Define.HC.HTML b/public/Wb/Home/Src/Demo/Define.HC.HTML new file mode 100755 index 0000000..d2354ad --- /dev/null +++ b/public/Wb/Home/Src/Demo/Define.HC.HTML @@ -0,0 +1,67 @@ + + + + + + + + + + + +
+//See Define.
+
+//These might be in the Adam task.
+DefineLoad("ST_YES_NO","(Yes or No)");
+DefineLoad("ST_EXIT","Exit");
+DefineLstLoad("ST_NO_YES_LST","No\0Yes\0");
+
+//New strings might be loaded for each user
+//to override.
+
+"Spanish";
+if (YorN) {
+  DefineLoad("ST_YES_NO","(Si or No)");
+  DefineLoad("ST_EXIT","Salida");
+  DefineLstLoad("ST_NO_YES_LST","No\0Si\0");
+}
+
+Bool Quit()
+{
+  Bool res;
+  U8 *st;
+  I64 i;
+  while (TRUE) {
+    "%S %S?","ST_EXIT","ST_YES_NO";
+    st=GetStr;
+    i=DefineMatch(st,"ST_NO_YES_LST",LMF_IGNORE_CASE);
+    if (i>=0) {
+      res=i;
+      break;
+    }
+    Free(st);
+  }
+  return res;
+}
+
+Quit;
+
+ diff --git a/public/Wb/Home/Src/Demo/Directives.HC.HTML b/public/Wb/Home/Src/Demo/Directives.HC.HTML new file mode 100755 index 0000000..d6ebfb5 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Directives.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+U0 Directives()
+{
+  "Date\t:%s\n",__DATE__;
+  "Time\t:%s\n",__TIME__;
+  "File\t:%s\n",__FILE__;
+  "Dir\t:%s\n",__DIR__;
+  "Line\t:%d\n",__LINE__;
+  "CmdLine\t:%d\n",__CMD_LINE__;
+  "Inst1\t:%P:%08X\n",$,$;
+  "Inst2\t:%P:%08X\n",$,$;
+}
+
+Directives;
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/CallBack.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/CallBack.HC.HTML new file mode 100755 index 0000000..815f1b2 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/CallBack.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+U8 *tSCB(CDoc *,CDocEntry *,CTask *mem_task)
+{//This is called by the window mgr.
+//Things would get corrupted
+  //if the window mgr used it's own
+  //heap, so we use the owning task's heap.
+  U8 *st=MAlloc(64,mem_task);
+  CDate cdt=tS*CDATE_FREQ;
+//Doesn't have to be fixed width!!
+  StrPrint(st,"%d=%T",cdt,cdt);
+  return st;
+}
+
+U8 *CurTimeCB(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  CDate cdt=Now;
+  StrPrint(st,"%D %T",cdt,cdt);
+  return st;
+}
+
+U0 DoIt()
+{
+  CDoc *bdoc=DocBorder,*pdoc=DocPut;
+  CDocEntry *doc_e;
+
+  DocLock(bdoc);
+  DocBottom(bdoc);  //Ins at the bottom
+  DocPrint(bdoc,"$RED$$CM+BY+LX,5,-3$");
+//The DocPrint() routine returns the addr of the last entry.
+  doc_e=DocPrint(bdoc,"$TX+TC,\" \"$");
+//The TC flag is "has tag callback".
+
+  //Flags are explained here:
+  //::/Doc/DolDocOverview.DD    ::/Doc/Widget.DD
+  //Dollar Flags                ST_DOC_FLAGS
+  doc_e->tag_cb=&tSCB;
+  DocPrint(bdoc,"$FG$");
+  DocUnlock(bdoc);
+
+  //WARNING: If you use the put_doc you
+  //run the risk of the user pressing
+  //<CTRL-t> or using the clip, both
+  //of which will crash.        So, you might want
+  //to use the border_doc.
+
+  DocLock(pdoc);
+  DocPrint(pdoc,"$LTRED$");
+  doc_e=DocPrint(pdoc,"$TX+TC,\" \"$");
+  doc_e->tag_cb=&CurTimeCB;
+  DocPrint(pdoc,"$FG$");
+  DocUnlock(pdoc);
+
+  //Send carriage return, new line, so
+  //that the timer string is not part
+  //of the next cmd on the cmd line.
+  '\n';
+}
+
+U0 UndoIt()
+{//Clear-out entries without a +H hold flag.
+  DocClear(Fs->border_doc);
+}
+
+DoIt;
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/ClickCallBack.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/ClickCallBack.HC.HTML new file mode 100755 index 0000000..3959bbb --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/ClickCallBack.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+I64 MyLeftCB1(CDoc *,CDocEntry *)
+{
+  I64 i;
+  for (i=500;i<1000;i+=25) {
+    Snd(Freq2Ona(i));
+    Sleep(10);
+  }
+  Snd;
+  return 0;
+}
+
+U0 ClickCallBack()
+{
+  CDocEntry *doc_e;
+  DocLock(DocPut);
+//The DocPrint() routine returns the addr of the last entry.
+  doc_e=DocPrint(DocPut,"\n$MA+LC,\"Click Me\"$ ");
+//The LC flag is "has left callback".
+
+  //Flags are explained here:
+  //::/Doc/DolDocOverview.DD    ::/Doc/Widget.DD
+  //Dollar Flags                ST_DOC_FLAGS
+  "(Not preserved if you press <CTRL-t>.)\n\n";
+  doc_e->left_cb=&MyLeftCB1;
+  DocUnlock(DocPut);
+}
+
+ClickCallBack;
+
+I64 MyLeftCB2(CDoc *,CDocEntry *)
+{
+  return cnts.jiffies;
+}
+
+U0 PopUpJiffiesCallBack(I64 i)
+{
+  CDoc *doc=DocNew;
+  CDocEntry *doc_e=DocPrint(doc,
+        "Click %d more times\n\n\n$BT+LC,\"Jiffies\"$\n\n\n",i);
+  doc_e->left_cb=&MyLeftCB2;
+  "Current Jiffies:%d\n",PopUpMenu(doc);
+  DocDel(doc);
+}
+
+PopUpJiffiesCallBack(3);
+PopUpJiffiesCallBack(2);
+PopUpJiffiesCallBack(1);
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/CursorMove.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/CursorMove.HC.HTML new file mode 100755 index 0000000..bd72ef0 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/CursorMove.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+U0 CursorMovementDemo()
+{
+  I64 i;
+  for (i=0;i<100;i++) {
+    "%03d ",i;
+    "$CM,-4,1$";
+    if (i%10==9)
+      "$CM,4,-10$";
+  }
+
+  //+LX is relative to left side.
+  //See <CTRL-l> with cursor-movement for all the flags.
+  //Check "Quote" to set-up a cmd for in quotes.
+  "$CM+LX,0,+10$\n";
+}
+
+CursorMovementDemo;
+
+/*The word-wrap Off and On cmds are
+$WW,0$ and $WW,1$.
+
+You might need DocMax() to adjust
+the cmd line window buf size.
+It counts cmds, not lines.
+
+The +H flag will hold-onto an entry
+so it doesn't get pushed-out of the document.
+This is useful for a $WW+H,1$ cmd.
+
+See ::/Doc/DolDocOverview.DD for documentation on
+all flags and cmds.
+
+Note: the default page length is 66 lines
+and branching back more than the page length
+will rst the column to 1.  So, set page
+length to a large number if you want to
+branch back a long distance.
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/Data.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/Data.HC.HTML new file mode 100755 index 0000000..891811e --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/Data.HC.HTML @@ -0,0 +1,94 @@ + + + + + + + + + + + +
+/*$DA   is the data widget.
+   -TRM flag is for var
+        width fields with a terminator
+        character.
+   +RD  refreshes the data.
+   +UD  updates the val when you edit it.
+
+   -P   Means it is a string var, basically.
+
+   ,32  sets the tag string width.
+        See Data Tag Width.
+
+   ,RT=I16 means the val is 2 bytes.
+        See DocDataFmt() and DocDataScan().
+*/
+
+I16 i=0;
+U8 buf[8];
+
+U0 UpdateGlblTask(I64)
+{
+  while (TRUE) {
+    i++;
+    Sleep(1);
+  }
+}
+
+U0 DataDemo()
+{
+  CDocEntry *doc_e;
+
+  //This is the command line document.
+  CDoc *doc=DocPut;
+
+  //We do this to prevent access to
+  //doc_e->data before it is set.
+  Bool unlock=DocLock(doc);
+
+  //You might set the DOCF_FORM flag.
+  //  doc->flags|=DOCF_FORM
+  //if you wish.
+
+  Spawn(&UpdateGlblTask,NULL,"Update Glbl",,Fs);
+
+  "Enter editor overstrike mode\n"
+        "and you can modify the val.\n"
+        "However, changes happen immediately,\n"
+        "so it's tricky.\n\n";
+//Use <CTRL-l> for the $DA...$ format.
+  doc_e=DocPrint(doc,"$DA-TRM+RD+UD,RT=I16,A=\"%%7d\"$\n");
+  doc_e->data=&i;
+
+  StrCpy(buf,"Terry");
+  doc_e=DocPrint(doc,"$DA-P+RD+UD,LEN=7,A=\"Str:%%s\"$\n");
+  doc_e->data=buf;
+
+  if (unlock)
+    DocUnlock(doc);
+}
+
+DataDemo;
+
+//See PopUpExtents().
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/DefineStr.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/DefineStr.HC.HTML new file mode 100755 index 0000000..44a7680 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/DefineStr.HC.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+/*The +D flag causes a define-string
+look-up and substitution.
+
+It is available in the <CTRL-l> text-widget
+menu under text entries for use in
+documentation.
+
+*/
+
+DefineLoad("COMPANY","Acme Inc");
+"Company: $TX,\"\",D=\"COMPANY\"$\n";
+
+DefinePrint("COMPANY_TIME","%T",Now);
+
+#exe {
+  StreamPrint(
+    "#define COMPANY_AGE %0.1f\n",
+    (Now-Str2Date("8/1/2003"))/ToF64(1<<32)/CDATE_YEAR_DAYS);
+};
+
+"Age : $TX,\"\",D=\"COMPANY_AGE\"$ years\n";
+"Time: $TX,\"\",D=\"COMPANY_TIME\"$\n";
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/DemoDoc.DD.HTML b/public/Wb/Home/Src/Demo/DolDoc/DemoDoc.DD.HTML new file mode 100755 index 0000000..f19213c --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/DemoDoc.DD.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+
+
+
+
+
+This is page 1.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+This is page 2.
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  
+            /* Graphics Not Rendered in HTML */This is a demo 
+            doc.  This is a 
+            demo doc.  This 
+            is a demo doc.  
+            This is a demo 
+            doc.  This is a 
+            demo doc.  This 
+            is a demo doc.  
+            This is a demo 
+            doc.  This is a 
+            demo doc.  This 
+            is a demo doc.  
+            This is a demo 
+            doc.
+            
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.  
+This is a demo doc.  This is 
+a demo doc.  This is a demo 
+doc.  This is a demo doc.         This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.      This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.  This is a demo doc.
+
+
+
+
+
+
+
+
+
+
+
+  This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  MyLittleAnchor  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.  
+This is a demo doc.  This is a demo doc.  This is a demo 
+doc.  This is a demo doc.  This is a demo doc.  This is a 
+demo doc.  This is a demo doc.  This is a demo doc.  This 
+is a demo doc.  This is a demo doc.  This is a demo doc.
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/FileRead.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/FileRead.HC.HTML new file mode 100755 index 0000000..444f861 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/FileRead.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+public U0 DocProfile(U8 *filename,I64 flags)
+{
+  I64 i,*cmd_stats=CAlloc(sizeof(I64)*DOCT_TYPES_NUM),
+        *flags_stats=CAlloc(sizeof(I64)*64),
+        *type_flags_stats=CAlloc(sizeof(I64)*64);
+//Note: word wrap is determined by
+  //doc->win_task when a CDoc is recalculated
+  //use DocRecalc().
+  CDoc *doc=DocRead(filename,flags);
+
+  //doc->head which is equ to doc is the
+  //header of the CQue and represents the end-of-file marker.
+  CDocEntry *doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    cmd_stats[doc_e->type_u8]++;
+    for (i=0;i<64;i++)
+      if (Bt(&doc_e->de_flags,i))
+        flags_stats[i]++;
+    for (i=16;i<32;i++)
+      if (Bt(&doc_e->type,i))
+        type_flags_stats[i]++;
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+
+  "$PURPLE$-------%s-------\n",filename;
+  "$GREEN$The lowest byte of the 32-bit 'doc_e->type', "
+        "'$PURPLE$doc_e->type.u8[0]$GREEN$', "
+        "is cmd and accessed with the union "
+        "'$PURPLE$doc_e->type_u8$GREEN$'.  "
+        "See $LK,\"CDocEntry\",A=\"MN:CDocEntry\"$, "
+        "$LK,\"Doc Type Defines\",A=\"MN:DOCT_TEXT\"$ and "
+        "$LK,\"Doc Type Codes\","
+        "A=\"FF:::/Adam/DolDoc/DocInit.HC,ST_DOC_CMDS\"$.\n"
+        "$FG$";
+  for (i=0;i<DOCT_TYPES_NUM;i++)
+    if (cmd_stats[i])
+      "%4Z:%d\n",i,"ST_DOC_CMDS",cmd_stats[i];
+
+  "\n$GREEN$'$PURPLE$doc_e->type.u8[1]$GREEN$' is "
+        "the scrn color attr of the "
+        "entry.  '$PURPLE$doc_e->type.u16[1]"
+        "$GREEN$' is some flags for blinking and "
+        "stuff.  See $LK,\"Doc Type Flag "
+        "Defines\",A=\"MN:DOCET_BLINK\"$.\n$FG$";
+
+  for (i=16;i<32;i++)
+    if (type_flags_stats[i])
+      "%4d:%d\n",i,type_flags_stats[i];
+
+  "$GREEN$\n'$PURPLE$doc_e->de_flags$GREEN$' is 64-bit.  "
+        "See $LK,\"Doc Flag Defines\",A=\"MN:DOCEf_TAG\"$ and "
+        "$LK,\"Doc Flag Codes\","
+        "A=\"FF:::/Adam/DolDoc/DocInit.HC,ST_DOC_FLAGS\"$.\n"
+        "$FG$";
+  for (i=0;i<64;i++)
+    if (flags_stats[i])
+      "%4Z:%d\n",i,"ST_DOC_FLAGS",flags_stats[i];
+
+  Free(cmd_stats);
+  Free(flags_stats);
+  PressAKey;
+  '\n';
+}
+
+/*See TipOfDay.
+
+Note: Not all CDocEntry's are full-sized nodes.
+Some are MAlloced with a smaller size to save
+mem.    They all have at least the size CDocEntryBase.
+
+Note: CDocEntry's should be alloced from the
+heap of the owning task, doc->mem_task.
+
+The flag arrays doldoc.type_flags_form, etc
+are useful.
+*/
+
+DocProfile("::/Doc/Welcome.DD",0);
+DocProfile("::/Doc/Welcome.DD",DOCF_PLAIN_TEXT);
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/Form.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/Form.HC.HTML new file mode 100755 index 0000000..d77ebc6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/Form.HC.HTML @@ -0,0 +1,82 @@ + + + + + + + + + + + +
+class FDStruct
+{//Use <CTRL-l> and sel "Data", "List" or "Check Box"
+//to generate the formats.
+  F64 num1      format "$DA-TRM,A=\"Float 1:%12.8f\"$\n";
+  F64 num2      format "$DA-TRM,A=\"Float 2:%12e\"$\n";
+  I64 num3      format "$DA-TRM,A=\"Int   1:0x%016X\"$\n";
+  I64 num4      format "$DA-TRM,A=\"Int   2:%12d\"$\n";
+  I64 type      format "$LS,D=\"ST_PERSON_TYPE\"$\n";
+  U8  name[32]  format "$DA-P,A=\"Name   :%s\"$\n";
+  U8  *address1 format "$DA+M,A=\"Address:%s\"$\n"; //+M is unlimited len U8 *.
+  U8  *address2 format "$DA+M,A=\"Address:%s\"$\n"; //+M is unlimited len U8 *.
+  CDate datetime format "$DA-TRM,A=\"Date   :%8D\"$\n";
+  Bool  check   format "$CB,\"Check\"$\n";
+};
+
+U0 FormDemo()
+{
+  FDStruct fds;
+  DefineLstLoad("ST_PERSON_TYPE","Child\0Teen\0Adult\0");
+  fds.num1=12.3e-4;     //Set defaults
+  fds.num2=4.5e3;
+  fds.num3=0x1234;
+  fds.num4=-567;
+  fds.type=1;
+  StrCpy(&fds.name,"John");
+  fds.address1=StrNew("1234 Pine St.");
+  fds.address2=NULL;    //Init to NULL if empty.
+  fds.datetime=Now;
+  fds.check=TRUE;
+  if (DocForm(&fds)) {
+    "#1\t=%e\n",fds.num1;
+    "#2\t=%e\n",fds.num2;
+    "#3\t=%d\n",fds.num3;
+    "#4\t=%d\n",fds.num4;
+    "Type\t=%s\n",DefineSub(fds.type,"ST_PERSON_TYPE");
+    "Name\t=%s\n",fds.name;
+    "Address1=%s\n",fds.address1;
+    "Address2=%s\n",fds.address2;
+    "Date\t=%D\n",fds.datetime;
+    "Check\t=%d\n",fds.check;
+  } else
+    "Cancel\n";
+
+  "\n\nClassRep Example\n";
+  ClassRep(&fds);
+  Free(fds.address1);
+  Free(fds.address2);
+  //See also ClassRepD().
+}
+
+FormDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/MenuBttn.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/MenuBttn.HC.HTML new file mode 100755 index 0000000..16eb91a --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/MenuBttn.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+//This example shows bttns.  Bttns return a menu val
+//unless you rig them to send macros.  Menu entries are
+//about the same as bttns, but don't have a border.
+
+I64 PopUpFreq()
+{//See also PopUpRangeI64()
+  I64 i;
+  CDoc *doc=DocNew;
+  DocPrint(doc,"$TX+CX,\"Set Freq\"$\n" //Centered text
+        "$CM+LX,2,4$$BT,\"100 Hz\",LE=100$"
+        "$CM+LX,18,0$$BT,\"200 Hz\",LE=200$"
+        "$CM+LX,2,4$$BT,\"400 Hz\",LE=400$"
+        "$CM+LX,18,0$$BT,\"800 Hz\",LE=800$\n");
+  i=PopUpMenu(doc);
+  if (i<0) i=0; // <SHIFT-ESC>
+  DocDel(doc);
+  return i;
+}
+
+#define MU_NOTHING      0
+#define MU_SET_FREQ     1
+#define MU_SND_ON       2
+#define MU_SND_OFF      3
+
+U0 MenuBttn()
+{
+  Bool done=FALSE;
+  I64 i,j=0,freq=100;
+  I64 old_flags=DocPut->flags;
+//This allows keyboard navigation to skip nonselible entries.
+  DocPut->flags|=DOCF_FORM;
+  do {
+    DocClear;
+//Use <CTRL-l> to generate cursor movement expressions and check "Quote".
+    "$CM+CX-RE,-4$Menu Demo\n\n";
+    "$LM,8$"; //Set left margin
+//These are bttns that return a val from a menu selection.
+    if (!j)
+      "\n$BT,\"Snd On\",LE=MU_SND_ON$\n\n\n";
+    else
+      "\n$BT,\"Snd Off\",LE=MU_SND_OFF$\n\n\n";
+    "\n$BT,\"Set Freq\",LE=MU_SET_FREQ$\n\n\n"
+          "\n$BT,\"Nothing\",LE=MU_NOTHING$\n\n\n"
+          "\n$BT,\"Done\",LE=DOCM_CANCEL$\n\n\n";
+    i=DocMenu(DocPut);
+    DocBottom;
+    switch (i) {
+      case MU_NOTHING:
+        break;
+      case MU_SND_ON:
+        j=freq;
+        Snd(Freq2Ona(j));
+        break;
+      case MU_SND_OFF:
+        j=0;
+        Snd;
+        break;
+      case MU_SET_FREQ:
+        freq=PopUpFreq;
+        if (j) {
+          j=freq;
+          Snd(Freq2Ona(j));
+        }
+        break;
+      default:
+        done=TRUE;
+    }
+  } while (!done);
+  DocPut->flags=DocPut->flags&~DOCF_FORM |
+        old_flags & DOCF_FORM;
+  DocClear;
+  Snd;
+}
+
+MenuBttn;
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/MenuSprite.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/MenuSprite.HC.HTML new file mode 100755 index 0000000..ebcace6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/MenuSprite.HC.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+U0 MenuSprite()
+{
+  I64 i;
+  DocPut->flags|=DOCF_FORM; //Cursor navigation will skip empty locations.
+  while (TRUE) {
+    DocClear;
+    '\n';
+
+    //Sprite with flags for left-expression and an exit.
+    //See doldoc.dft_de_flags.  Note the %d in the string for the sprite number.
+    Sprite(<1>,"$LTBLUE$$SP+X,\"50 Hz\",LE=50,BI=%d$");
+
+    "\n\n\n"
+          "$MU,\"100 Hz\",LE=100$\n"
+          "$MU,\"200 Hz\",LE=200$\n"
+          "$MU,\"CANCEL\",LE=DOCM_CANCEL$\n";
+    i=DocMenu(DocPut);
+    if (i>0)
+      Snd(Freq2Ona(i));
+    else
+      break;
+  }
+  Snd;
+  DocClear;
+  '\n';
+  DocPut->flags&=~DOCF_FORM;
+}
+
+MenuSprite;
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/NumBible.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/NumBible.HC.HTML new file mode 100755 index 0000000..0ad6517 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/NumBible.HC.HTML @@ -0,0 +1,59 @@ + + + + + + + + + + + +
+//  This makes a new Bible file
+//with line numbers.
+
+U0 NumBible()
+{
+  CDoc *doc_in=DocRead("::/Misc/Bible.TXT.Z",DOCF_PLAIN_TEXT_TABS),
+        *doc_out=DocNew("~/DemoNumBible.DD.Z");
+  CDocEntry *doc_e=doc_in->head.next;
+  while (doc_e!=doc_in) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      DocPrint(doc_out,"%05d %s",doc_e->y+1,doc_e->tag);
+      doc_e=doc_e->next;
+      if (doc_e->type_u8==DOCT_NEW_LINE) {
+        DocPrint(doc_out,"\n");
+        doc_e=doc_e->next;
+      }
+    } else if (doc_e->type_u8==DOCT_NEW_LINE) {
+      DocPrint(doc_out,"%05d\n",doc_e->y+1);
+      doc_e=doc_e->next;
+    } else
+      doc_e=doc_e->next;
+  }
+  doc_out->flags|=DOCF_NO_CURSOR;
+  DocWrite(doc_out);
+  DocDel(doc_out);
+  DocDel(doc_in);
+}
+
+NumBible;
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/TextDemo.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/TextDemo.HC.HTML new file mode 100755 index 0000000..48795f8 --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/TextDemo.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+        "\nSuper    : 3$SY,-3$2$SY,0$=9\n\n"
+        "Sub      : H$SY,3$2$SY,0$O\n\n"
+        "Color    : $RED$Test$FG$\n\n"
+        "Blink    : $BK,1$Test$BK,0$\n\n"
+        "Invert   : $IV,1$Test$IV,0$\n\n"
+        "UnderLine: $UL,1$Test$UL,0$\n\n"
+        "Link     : $LK,\"Genesis,1:1\",\"BF:Genesis,1:1\"$\n\n\n"
+
+        "Bttn   :     $BT-X,\"OKAY\",LE=1$\n\n\n\n";
+
+//You can do it this way if you like.
+        "\nSuper    : 32=9\n\n"
+        "Sub      : H2O\n\n"
+//Can't see color because of syntax highlighting.  Press <CTRL-t>
+        "Color    : Test\n\n"
+        "Blink    : Test\n\n"
+        "Invert   : Test\n\n"
+        "UnderLine: Test\n\n"
+//<CTRL-SHIFT-T> on this link to toggle individual commands.
+        "Link     : Genesis,1:1\n\n\n"
+
+        "Bttn   :     OKAY\n\n\n\n";
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/TreeDemo.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/TreeDemo.HC.HTML new file mode 100755 index 0000000..cb6ddeb --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/TreeDemo.HC.HTML @@ -0,0 +1,70 @@ + + + + + + + + + + + +
+U0 TreeSub(CDoc *doc,CDirEntry *tmpde)
+{
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      DocPrint(doc,"$TR,\"\"$");
+      DocPrint(doc,"$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$\n",
+            tmpde->name,tmpde->full_name);
+      if (tmpde->sub) {
+        DocPrint(doc,"$ID,+2$");
+        TreeSub(doc,tmpde->sub);
+        DocPrint(doc,"$ID,-2$");
+      }
+    } else
+      DocPrint(doc,"$LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->name,tmpde->full_name);
+//Note there is also a routine
+      //to delete an entire CDirEntry tree.
+      //See DirTreeDel().
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+}
+
+U0 TreeDemo()
+{
+  I64 fuf_flags=0;
+  CDoc *doc=DocNew;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  DocPrint(doc,"$TR-C,\"\"$\n");
+  DocPrint(doc,"$ID,+2$");
+  TreeSub(doc,FilesFind("/*",fuf_flags));
+  DocPrint(doc,"$ID,-2$");
+  DocInsDoc(DocPut,doc);
+  DocDel(doc);
+}
+ 
+TreeDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/DolDoc/UnusedDefine.HC.HTML b/public/Wb/Home/Src/Demo/DolDoc/UnusedDefine.HC.HTML new file mode 100755 index 0000000..59198ac --- /dev/null +++ b/public/Wb/Home/Src/Demo/DolDoc/UnusedDefine.HC.HTML @@ -0,0 +1,113 @@ + + + + + + + + + + + +
+/*Scans the sym table and checks
+each HTT_DEFINE_STR entry to see if
+it only occurs once in files.
+
+It's a brute force solution, but
+gets the job done... slowly.
+
+Find() returns a count of matches.
+
+FileOcc() is Find() with
+output Silent().
+*/
+
+U0 UnusedDefineScan()
+{
+  CDoc *old_put_doc,*old_display_doc,*doc;
+  I64 i,cnt=0;
+  CHashTable *table;
+  CHash *tmph;
+  CDocEntry *doc_e,*doc_e2;
+  Bool old_silent=IsSilent;
+
+  try {
+    table=Fs->hash_table;
+    while (table) {
+      for (i=0;i<=table->mask;i++) {
+        tmph=table->body[i];
+        while (tmph) {
+          if (tmph->type&HTT_DEFINE_STR)
+            cnt++;
+          tmph=tmph->next;
+        }
+      }
+      table=table->next;
+    }
+
+    progress1=0;
+    progress1_max=cnt;
+    StrCpy(progress1_desc,"Define Scan");
+
+    table=Fs->hash_table;
+    while (table) {
+      for (i=0;i<=table->mask;i++) {
+        tmph=table->body[i];
+        while (tmph) {
+          if (tmph->type&HTT_DEFINE_STR) {
+            progress1++;
+            if (FileOcc(tmph->str,"/*","+l-i+$")==1) {
+              doc=DocNew;
+              old_put_doc=DocPut;
+              old_display_doc=DocDisplay;
+              Fs->put_doc=Fs->display_doc=doc;
+              Find(tmph->str,"/*","+l-i+$");
+              Fs->put_doc=old_put_doc;
+              Fs->display_doc=old_display_doc;
+              doc_e=doc->head.next;
+              while (doc_e!=doc) {
+                if (doc_e->type_u8==DOCT_LINK) {
+                  "%s ",tmph->str;
+                  doc_e2=DocEntryCopy(doc,doc_e);
+                  DocInsEntry(old_put_doc,doc_e2);
+                  '\n';
+                }
+                doc_e=doc_e->next;
+              }
+              DocDel(doc);
+            }
+          }
+          tmph=tmph->next;
+        }
+      }
+      table=table->next;
+    }
+  } catch
+    PutExcept;
+
+  Silent(old_silent);
+  '\n';
+  ProgressBarsRst;
+}
+
+UnusedDefineScan;
+
+ diff --git a/public/Wb/Home/Src/Demo/Dsk/BlkDevRep.HC.HTML b/public/Wb/Home/Src/Demo/Dsk/BlkDevRep.HC.HTML new file mode 100755 index 0000000..f877e00 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Dsk/BlkDevRep.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+U0 BlkDevRep()
+{//Block Device Report.
+  I64 i;
+  for (i=0;i<BLKDEVS_NUM;i++)
+    if (blkdev.blkdevs[i].bd_signature==BD_SIGNATURE_VAL)
+      //ClassRep() dumps any structure, automatically.
+      ClassRep(&blkdev.blkdevs[i]);
+      //The lastclass arg tells ClassRep the datatype.
+      //lastclass is a language feature of HolyC.
+      //See ::/Demo/LastClass.HC.
+}
+
+BlkDevRep;
+
+ diff --git a/public/Wb/Home/Src/Demo/Dsk/DataBase.HC.HTML b/public/Wb/Home/Src/Demo/Dsk/DataBase.HC.HTML new file mode 100755 index 0000000..c9e5469 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Dsk/DataBase.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+#define DB_FILENAME     "~/DataBaseDemo.BIN"
+#define DB_ACCT_MAX     100
+#define DB_ACCT_BLKS    1
+
+class Acct
+{//Use <CTRL-l> to help generate formats.
+  U8 name[32] format "$DA-P,LEN=32,A=\"Name:%s\"$\n";
+  U8 addr[64] format "$DA-P,LEN=64,A=\"Addr:%s\"$\n";
+  U8 pad[DB_ACCT_BLKS*BLK_SIZE-64-32];
+};
+
+U0 InitDatabase()
+{ //Write new contiguous file
+  CFile *f=FOpen(DB_FILENAME,"w",DB_ACCT_MAX*DB_ACCT_BLKS);
+  FClose(f);
+}
+
+U0 WriteAcct()
+{
+  CFile *f;
+  Acct a;
+  I64 acctnum;
+
+  acctnum=GetI64("Acct #",-1);
+  if (0<=acctnum<DB_ACCT_MAX) {
+    MemSet(&a,0,BLK_SIZE);
+    if (DocForm(&a)) {
+      f=FOpen(DB_FILENAME,"w+");
+      FBlkWrite(f,&a,acctnum*DB_ACCT_BLKS,DB_ACCT_BLKS);
+      FClose(f);
+    }
+  }
+}
+
+U0 ReadAcct()
+{
+  CFile *f;
+  Acct a;
+  I64 acctnum;
+
+  acctnum=GetI64("Acct #",-1);
+  if (0<=acctnum<DB_ACCT_MAX) {
+    f=FOpen(DB_FILENAME,"r");
+    FBlkRead(f,&a,acctnum*DB_ACCT_BLKS,DB_ACCT_BLKS);
+    FClose(f);
+    ClassRep(&a);
+  }
+}
+
+U0 DatabaseDemo()
+{
+  I64 ch;
+  if (!FileFind(DB_FILENAME))
+    InitDatabase;
+  do {
+    "$GREEN$R$FG$ead acct, $GREEN$W$FG$rite acct or $GREEN$<SHIFT-ESC>$FG$:";
+    ch=ToUpper(GetChar);
+    '\n';
+    if (ch=='R') ReadAcct;
+    if (ch=='W') WriteAcct;
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+}
+
+DatabaseDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Dsk/DskRaw.HC.HTML b/public/Wb/Home/Src/Demo/Dsk/DskRaw.HC.HTML new file mode 100755 index 0000000..7ac928e --- /dev/null +++ b/public/Wb/Home/Src/Demo/Dsk/DskRaw.HC.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+U0 RawAccess(I64 drv_let=0)
+{
+  CDrv *dv=Let2Drv(drv_let);
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  I64 blk,old_offset,old_size;
+  U8 *buf=MAlloc(BLK_SIZE);
+
+  DrvRep;
+  PressAKey;
+
+  ClassRep(dv);
+  PressAKey;
+
+  ClassRep(bd);
+  PressAKey;
+
+  //Temporarily change partition range to full device.
+  //Normally, you are limited to just your partition.
+  //This is obviously dangerous!
+  old_offset=dv->drv_offset;
+  old_size  =dv->size;
+  dv->drv_offset=0;
+  dv->size=bd->max_blk+1;
+
+  try {
+    blk=GetI64("Blk to Read: ",old_offset,0,bd->max_blk);
+    BlkRead(dv,buf,blk,1);
+    D(buf,BLK_SIZE);
+  } catch
+    PutExcept;
+
+  dv->drv_offset=old_offset;
+  dv->size  =old_size;
+
+  Free(buf);
+}
+
+RawAccess;
+
+//See BlkRead(), BlkWrite(), DrvLock(), DrvUnlock()
+//DBlk(), DClus(), BlkDevLock() and BlkDevUnlock().
+
+ diff --git a/public/Wb/Home/Src/Demo/Dsk/FPrintF.HC.HTML b/public/Wb/Home/Src/Demo/Dsk/FPrintF.HC.HTML new file mode 100755 index 0000000..eace17d --- /dev/null +++ b/public/Wb/Home/Src/Demo/Dsk/FPrintF.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+/*There is no FPrintF type function and no
+way to grow files. Therefore, use mem to
+hold the file until you are done.  The CDoc
+framework is convenient for this.
+*/
+
+U0 TreeSub(CDoc *doc,CDirEntry *tmpde)
+{
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      DocPrint(doc,"$TR,\"\"$");
+      DocPrint(doc,"$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$\n",
+            tmpde->name,tmpde->full_name);
+      if (tmpde->sub) {
+        DocPrint(doc,"$ID,+2$");
+        TreeSub(doc,tmpde->sub);
+        DocPrint(doc,"$ID,-2$");
+      }
+    } else
+      DocPrint(doc,"$LK,\"%s\",A=\"FI:%s\"$\n",
+            tmpde->name,tmpde->full_name);
+//Note there is also a routine
+      //to delete an entire CDirEntry tree.
+      //See DirTreeDel().
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+}
+
+U0 FPrintFDemo(U8 *output_filename=NULL)
+{
+  I64 fuf_flags=0;
+  CDoc *doc=DocNew(output_filename);
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
+  DocPrint(doc,"$TR-C,\"\"$\n");
+  DocPrint(doc,"$ID,+2$");
+  TreeSub(doc,FilesFind("/*",fuf_flags));
+  DocPrint(doc,"$ID,-2$");
+  DocRecalc(doc);
+  if (output_filename)
+    DocWrite(doc,FALSE);
+  else
+    DocWrite(doc,TRUE);
+  DocDel(doc);
+}
+
+FPrintFDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Dsk/SerializeTree.HC.HTML b/public/Wb/Home/Src/Demo/Dsk/SerializeTree.HC.HTML new file mode 100755 index 0000000..2b7733b --- /dev/null +++ b/public/Wb/Home/Src/Demo/Dsk/SerializeTree.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+/*You probably don't need this.  It makes a directory
+tree into a flat contiguous memory chunk, suitable for
+serial communication and rebuilds it into a tree on the
+other end.
+*/
+
+U0 SerializeTree()
+{
+  CDirEntry *tmpde=FilesFind("/Demo/*.DD*",FUF_RECURSE);
+  I64 size;
+  U8 *ptr;
+  CArcCompress *arc;
+
+  LineRep1(tmpde); //We have CDirEntry.fullname
+  LineRep2(DocPut,tmpde);
+  "$GREEN$***************$FG$\n";
+  ptr=DirTreeSerialize(tmpde,&size);
+  DirTreeDel(tmpde);
+  D(ptr,size);
+  "$GREEN$***************:%7d$FG$\n",size;
+  arc=CompressBuf(ptr,size);
+  Free(ptr);
+  D(arc,arc->compressed_size);
+  "$GREEN$***************:%7d$FG$\n",size;
+  ptr=ExpandBuf(arc);
+  size=arc->expanded_size;
+  Free(arc);
+  D(ptr,size);
+  "$GREEN$***************:%7d$FG$\n",size;
+  tmpde=DirTreeUnserialize(ptr);
+  LineRep2(DocPut,tmpde); //We don't have CDirEntry.fullname
+  DirTreeDel(tmpde);
+}
+
+SerializeTree;
+
+ diff --git a/public/Wb/Home/Src/Demo/Dsk/UnusedSpaceRep.HC.HTML b/public/Wb/Home/Src/Demo/Dsk/UnusedSpaceRep.HC.HTML new file mode 100755 index 0000000..4fabd75 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Dsk/UnusedSpaceRep.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+U0 UnusedSpaceRep()
+{
+  I64 i;
+  CDrv *dv;
+  for (i=0;i<26;i++)
+    if ((dv=Let2Drv(i+'A',FALSE)) &&
+          (dv->fs_type==FSt_FAT32 || dv->fs_type==FSt_REDSEA))
+      "%C: %7.3f%% Free\n",
+            Drv2Let(dv),DrvUnused(Drv2Let(dv))*100.0/(dv->size*BLK_SIZE);
+}
+
+UnusedSpaceRep;
+
+ diff --git a/public/Wb/Home/Src/Demo/Exceptions.HC.HTML b/public/Wb/Home/Src/Demo/Exceptions.HC.HTML new file mode 100755 index 0000000..77fd668 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Exceptions.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//WARNING: Don't return out of a catch{}.  This
+//might get fixed.
+
+//You can use PutExcept() in a catch stmt
+//and it will report args.
+Bool Prompt(I64 i)
+{
+  "%d ",i;
+  return YorN;
+}
+
+U0 D1()
+{
+  "D1\n";
+  if (Prompt(1)) throw('Point1');
+  if (Prompt(2)) throw('Point2');
+}
+
+U0 D2()
+{
+  "D2\n";
+  try {
+    D1;
+    if (Prompt(4)) throw('Point4');
+  } catch {
+    "D2 hndlr\n"
+          "Ch:%c:%P\n",Fs->except_ch,Fs->except_callers[0];
+    if (Fs->except_ch=='Point1') {
+      "Caught in D2\n";
+      Fs->catch_except=TRUE;
+    }
+  }
+}
+
+U0 Demo()
+{
+  try {
+    D2;
+    if (Prompt(3)) throw('Point3');
+  } catch {
+    "Demo hndlr\n"
+          "Ch:%c:%P\n",Fs->except_ch,Fs->except_callers[0];
+    Fs->catch_except=TRUE;
+  }
+}
+
+Demo;
+
+ diff --git a/public/Wb/Home/Src/Demo/ExtChars.HC.HTML b/public/Wb/Home/Src/Demo/ExtChars.HC.HTML new file mode 100755 index 0000000..b96c749 --- /dev/null +++ b/public/Wb/Home/Src/Demo/ExtChars.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+U8 face[8]={
+
+0b00111100,
+0b01000010,
+0b10100101,
+0b10000001,
+0b11000011,
+0b10111101,
+0b01000010,
+0b00111100,
+
+};
+
+
+text.font[255]=face[0](U64);
+
+"Face:.\n";
+
+//Chars 128-255 are treated as letters
+//by the compiler and everything else.
+//Enter them by holding ALT and
+//pressing a 3 digit decimal number or
+//press <CTRL-ALT-a>.
+
+U0 SrcExample()
+{
+  I64 f..=12345;
+  "f..=%d\n",f..;
+}
+
+SrcExample;
+//See ::/Demo/ScrnCodes.HC, ::/Demo/Graphics/CharAnimation.HC,
+//::/Demo/Games/CharDemo.HC and ::/Demo/Graphics/FontEd.HC.
+
+//See char_bmp_alpha and char_bmp_alpha_numeric.
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/BattleLines.HC.HTML b/public/Wb/Home/Src/Demo/Games/BattleLines.HC.HTML new file mode 100755 index 0000000..0a5c1c5 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/BattleLines.HC.HTML @@ -0,0 +1,413 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+#define FRAMES 6
+
+U8 *imgs[FRAMES]={
+<1>,<2>,<3>,<4>,<3>,<2>};
+
+F64 fire_end_time;
+
+class Trooper
+{
+  I64 x,y,dx,dy,att,def,rng,player;
+  F64 animate_time_base,fire_end_time;
+  Trooper *target;
+};
+
+#define TROOPERS_NUM 100
+Trooper tr[2][TROOPERS_NUM];
+
+Bool time_lapse=FALSE;
+
+#define TAP_MODE_RADIUS 50
+Bool tap_mode;
+
+#define AI_NOTHING 0
+#define AI_TARGET  1
+#define AI_RANDOM  2
+#define AI_AI_NUM  3
+I64 ai_mode;
+
+I64 ai_targets[10];
+
+U0 DrawTrooper(CTask *,CDC *dc,Trooper *tmpt)
+{
+  U8 *tmps;
+  I64 x,y,gx,gy;
+  F64 speed,tt;
+
+  if (tmpt->def>0) {
+    x=tmpt->dx>>28;
+    y=tmpt->dy>>28;
+    speed=0.5*Sqrt(x*x+y*y);
+
+    tt=tmpt->animate_time_base+tS*speed;
+    if (time_lapse) {
+      x=(tmpt->x+500*tmpt->dx)>>32;
+      y=(tmpt->y+500*tmpt->dy)>>32;
+    } else {
+      x=tmpt->x.i32[1];
+      y=tmpt->y.i32[1];
+    }
+    if (tmpt->target) {
+      gx=x;gy=y;
+      if (tmpt->dx<0) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,x,y,x,y+1);
+        gx-=13;
+        gy-=7;
+      } else {
+        dc->flags&=~DCF_SYMMETRY|DCF_JUST_MIRROR;
+        gx+=13;
+        gy-=7;
+      }
+
+      dc->color=BLACK;
+      Sprite3(dc,x+1,y,0,<5>);
+
+      if (!tmpt->player)
+        dc->color=LTCYAN;
+      else
+        dc->color=LTPURPLE;
+      Sprite3(dc,x,y,0,<5>);
+
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+      if (!tmpt->player)
+        dc->color=WHITE;
+      else
+        dc->color=LTBLUE;
+      GrLine3(dc,gx,gy,0,tmpt->target->x.i32[1],tmpt->target->y.i32[1],0);
+    } else {
+      if (tmpt->dx<0) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,x,y,x,y+1);
+      } else
+        dc->flags&=~DCF_SYMMETRY|DCF_JUST_MIRROR;
+      tmps=SpriteInterpolate(tt%1.0,imgs[tt%FRAMES],imgs[(tt+1.0)%FRAMES]);
+
+      dc->color=BLACK;
+      Sprite3(dc,x+1,y,0,tmps);
+
+      if (!tmpt->player)
+        dc->color=LTCYAN;
+      else
+        dc->color=LTPURPLE;
+      Sprite3(dc,x,y,0,tmps);
+
+      Free(tmps);
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    }
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  Trooper *tmpt=tr;
+  I64 i,j,cnt[2],
+        x=ms.pos.x-task->pix_left-task->scroll_x,
+        y=ms.pos.y-task->pix_top-task->scroll_y;
+  Bool repulsive=ms.pos.z>0 ^^ ms.rb,
+        active=!winmgr.grab_scroll && (ms.lb||ms.rb);
+
+  for (j=0;j<2;j++) {
+    cnt[j]=0;
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      if (tmpt->def>0) {
+        DrawTrooper(task,dc,tmpt);
+        cnt[j]++;
+      }
+    }
+  }
+  if (tap_mode) {
+    dc->color=YELLOW;
+    GrCircle(dc,x,y,TAP_MODE_RADIUS);
+  } else {
+    if (repulsive) {
+      if (active)
+        dc->color=LTRED;
+      else
+        dc->color=RED;
+    } else {
+      if (active)
+        dc->color=LTBLUE;
+      else
+        dc->color=BLUE;
+    }
+    GrCircle(dc,x,y,AbsI64(ms.pos.z));
+  }
+  dc->color=LTCYAN;
+  GrPrint(dc,(task->win_right-8)*FONT_WIDTH,0,"%03d",cnt[0]);
+  dc->color=LTPURPLE;
+  GrPrint(dc,(task->win_right-4)*FONT_WIDTH,0,"%03d",cnt[1]);
+}
+
+U0 DoAiTarget()
+{
+  I64 i,j;
+  Trooper *tmpt1,*tmpt0;
+  for (i=0;i<10;i++) {
+    tmpt0=&tr[0][ai_targets[i]];
+    for (j=0;j<10;j++) {
+      tmpt1=&tr[1][i*10+j];
+      tmpt1->dx=(tmpt0->x-tmpt1->x)>>11;
+      tmpt1->dy=(tmpt0->y-tmpt1->y)>>11;
+    }
+  }
+}
+
+U0 UpdatePos()
+{
+  I64 i,j;
+  Trooper *tmpt=tr;
+  for (j=0;j<2;j++)
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      tmpt->x+=tmpt->dx;
+      if (tmpt->x>=GR_WIDTH<<32) tmpt->x-=GR_WIDTH<<32;
+      if (tmpt->x<0) tmpt->x+=GR_WIDTH<<32;
+      tmpt->y+=tmpt->dy;
+      if (tmpt->y>=GR_HEIGHT<<32) tmpt->y-=GR_HEIGHT<<32;
+      if (tmpt->y<0) tmpt->y+=GR_HEIGHT<<32;
+    }
+}
+
+U0 ResolveFiring()
+{
+  I64 i,j,dd,dx,dy;
+  Trooper *tmpt=tr,*tmpt0,*tmpt1;
+
+  for (j=0;j<2;j++)
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      if (tmpt->target && tmpt->fire_end_time<tS) {
+        tmpt->target->def-=tmpt->att;
+        tmpt->fire_end_time=0;
+        tmpt->target=NULL;
+      }
+    }
+
+  for (i=0;i<TROOPERS_NUM;i++) {
+    tmpt0=&tr[0][i];
+    for (j=0;j<TROOPERS_NUM;j++) {
+      tmpt1=&tr[1][j];
+      if (tmpt0->def>0 && tmpt1->def>0) {
+        dx=(tmpt0->x-tmpt1->x)>>32;
+        dy=(tmpt0->y-tmpt1->y)>>32;
+        dd=dx*dx+dy*dy;
+        if (dd<tmpt0->rng && !tmpt0->target) {
+          fire_end_time=tmpt0->fire_end_time=tS+0.125;
+          Snd(86);
+          tmpt0->target=tmpt1;
+        }
+        if (dd<tmpt1->rng && !tmpt1->target) {
+          fire_end_time=tmpt1->fire_end_time=tS+0.125;
+          Snd(86);
+          tmpt1->target=tmpt0;
+        }
+      }
+    }
+  }
+
+  if (tS>=fire_end_time)
+    Snd;
+}
+
+U0 UpdateHumanVelocities()
+{
+  F64 intensity;
+  I64 i,j,dx,dy,d,
+        x=ms.pos.x-Fs->pix_left-Fs->scroll_x,
+        y=ms.pos.y-Fs->pix_top-Fs->scroll_y;
+  Bool active=!winmgr.grab_scroll&&(ms.lb||ms.rb);
+  Trooper *tmpt=&tr[0][0];
+  if (tap_mode) {
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      dx=x- tmpt->x.i32[1];
+      dy=y- tmpt->y.i32[1];
+      if ((d=dx*dx+dy*dy) && d<TAP_MODE_RADIUS*TAP_MODE_RADIUS) {
+        intensity=SqrI64(SqrI64(SqrI64(TAP_MODE_RADIUS)-d));
+        dx=intensity*dx/d;
+        dy=intensity*dy/d;
+        tmpt->dx=tmpt->dx-dx;
+        tmpt->dy=tmpt->dy-dy;
+      } else {
+        tmpt->dx-=0.2*tmpt->dx;
+        tmpt->dy-=0.2*tmpt->dy;
+      }
+    }
+  } else if (active) {
+    j=400000000*ms.pos.z;
+    if (ms.rb)
+      j=-j;
+    for (i=0;i<TROOPERS_NUM;i++,tmpt++) {
+      dx=x- tmpt->x.i32[1];
+      dy=y- tmpt->y.i32[1];
+      if (d=dx*dx+dy*dy) {
+        dx=j*dx/d;
+        dy=j*dy/d;
+        tmpt->dx=tmpt->dx-dx;
+        tmpt->dy=tmpt->dy-dy;
+      }
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,j,dx,dy;
+  Trooper *tmpt;
+  MsSet(,,25);
+  tap_mode=FALSE;
+  time_lapse=FALSE;
+  fire_end_time=0;
+  MemSet(tr,0,sizeof(tr));
+  for (i=0;i<10;i++) {
+    ai_targets[i]=RandU16%TROOPERS_NUM;
+    dx=RandI32;
+    dy=RandI32;
+    for (j=0;j<10;j++) {
+      tmpt=&tr[0][i*10+j];
+      tmpt->x=(GR_WIDTH-100-i*10)<<32;
+      tmpt->y=(GR_HEIGHT>>1-50+j*10)<<32;
+      tmpt->att=3;
+      tmpt->def=10;
+      tmpt->rng=50*50;
+      tmpt->animate_time_base=10*Rand;
+      tmpt->player=0;
+
+      tmpt=&tr[1][i*10+j];
+      tmpt->x=(100+i*10)<<32;
+      tmpt->y=(GR_HEIGHT>>1-50+j*10)<<32;
+      if (ai_mode==AI_RANDOM) {
+        tmpt->dx=dx;
+        tmpt->dy=dy;
+      }
+      tmpt->att=3;
+      tmpt->def=10;
+      tmpt->rng=50*50;
+      tmpt->animate_time_base=10*Rand;
+      tmpt->player=1;
+    }
+  }
+  ai_mode=RandU16%AI_AI_NUM;
+}
+
+U0 BattleLines()
+{
+  CMenuEntry *tmpse;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  TimeLapse(,'1');"
+        "  TapMode(,'2');"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=GREEN<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->draw_it=&DrawIt;
+  PopUpOk("The mouse wheel controls\n"
+        "the command force.\n"
+        "Attract or repel with\n"
+        "left or right bttn.\n\n");
+
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU;
+  try {
+    while (TRUE) {
+      switch (ScanChar) {
+        case '1':
+          time_lapse=!time_lapse;
+          tmpse=MenuEntryFind(Fs->cur_menu,"Play/TimeLapse");
+          tmpse->checked=time_lapse;
+          break;
+        case '2':
+          tap_mode=!tap_mode;
+          tmpse=MenuEntryFind(Fs->cur_menu,"Play/TapMode");
+          tmpse->checked=tap_mode;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto wg_done;
+        case '\n':
+          Init;
+          break;
+      }
+      Sleep(40);
+      if (ai_mode==AI_TARGET)
+        DoAiTarget;
+      UpdateHumanVelocities;
+      UpdatePos;
+      ResolveFiring;
+    }
+wg_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+}
+
+BattleLines;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/BigGuns.HC.HTML b/public/Wb/Home/Src/Demo/Games/BigGuns.HC.HTML new file mode 100755 index 0000000..9ffb18b --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/BigGuns.HC.HTML @@ -0,0 +1,346 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+class MyMass:CMass
+{
+  Bool collision;
+};
+
+#define MAP_WIDTH       2048
+#define MAP_HEIGHT      (GR_HEIGHT-3*FONT_HEIGHT)
+
+I64 gun_x,gun_y,active_map=0,gun_recoil;
+F64 gun_theta;
+CDC *map_dcs[2]={NULL,NULL};
+I16 elevs[MAP_WIDTH];
+
+F64 wind_x;
+#define DUST_NUM        512
+I64 dust_x[DUST_NUM],dust_y[DUST_NUM];
+
+CMathODE *ode=NULL;
+
+    <1>/* Graphics Not Rendered in HTML */
+
+
+    <2>/* Graphics Not Rendered in HTML */
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CDC *map=map_dcs[active_map&1];
+  MyMass *tmpm;
+  F64 theta=gun_theta;
+  I64 i,x,y,w,
+        h=-task->horz_scroll.pos,
+        v=-task->vert_scroll.pos;
+  task->horz_scroll.min=0;
+  task->horz_scroll.max=MAP_WIDTH-task->pix_width;
+  task->vert_scroll.min=0;
+  task->vert_scroll.max=MAP_HEIGHT-task->pix_height;
+  map->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,h,v,map);
+
+  Sprite3(dc,gun_x+h,gun_y+v,0,<2>);
+
+  if (theta<-pi/2) {
+    dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+    DCSymmetrySet(dc,gun_x+h,0,gun_x+h,1);
+    theta=-pi-theta;
+  }
+  Sprite3ZB(dc,
+        gun_x+h-gun_recoil*Cos(theta),
+        gun_y+v-gun_recoil*Sin(theta)-10,0,<1>,theta);
+  dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+
+  tmpm=ode->next_mass;
+  dc->color=BLACK;
+  map->color=ROP_COLLISION;
+  map->bkcolor=LTCYAN;
+  while (tmpm!=&ode->next_mass) {
+    map->collision_cnt=0;
+    GrCircle(map,tmpm->x,tmpm->y,2);
+    if (map->collision_cnt)
+      tmpm->collision=TRUE;
+
+    GrCircle(dc,tmpm->x+h,tmpm->y+v,2);
+
+    tmpm=tmpm->next;
+  }
+
+  dc->color=LTGRAY;
+  w=tS*wind_x;
+  for (i=0;i<DUST_NUM;i++) {
+    x=(dust_x[i]+w)%MAP_WIDTH;
+    y=dust_y[i];
+    if (y<elevs[x])
+      GrPlot(dc,x+h,y+v);
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+  MyMass *tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm->DstateDt->DyDt+=1000.0*tmpm->mass;
+    tmpm->DstateDt->DxDt+=25.0*wind_x;
+    tmpm=tmpm->next;
+  }
+}
+
+U0 DrawMap()
+{
+  CDC *map=map_dcs[(active_map+1)&1];
+  I64 x;
+
+  map->color=LTCYAN;
+  GrRect(map,0,0,MAP_WIDTH,MAP_HEIGHT);
+
+  map->color=BLACK;
+  for (x=1;x<MAP_WIDTH;x++)
+    GrLine(map,x-1,elevs[x-1],x,elevs[x]);
+
+  map->color=BROWN;
+  GrFloodFill(map,0,MAP_HEIGHT-1,FALSE);
+
+  active_map++;
+}
+
+U0 FireTask(I64)
+{
+  MyMass *tmpm;
+  I64 i;
+  if (gun_recoil) return;
+
+  tmpm=CAlloc(sizeof(MyMass),Fs->parent_task);
+  tmpm->mass=10.0;
+  tmpm->drag_profile_factor=0.1;
+  tmpm->x=gun_x+27*Cos(gun_theta);
+  tmpm->y=gun_y-15+27*Sin(gun_theta);
+  tmpm->DxDt=600.0*Cos(gun_theta);
+  tmpm->DyDt=600.0*Sin(gun_theta);
+  tmpm->collision=FALSE;
+  while (sys_task_being_scrn_updated==Fs->parent_task)
+    Yield;
+  QueIns(tmpm,ode->last_mass);
+
+  Fs->task_end_cb=&SndTaskEndCB;
+  for (i=0;i<60;i++) {
+    Snd(50*Rand+10);
+    Sleep(2);
+    gun_recoil=i/12;
+  }
+  for (i=0;i<=60;i++) {
+    Sleep(1);
+    gun_recoil=5-i/12;
+  }
+}
+
+U0 ManageShots()
+{
+  I64 i;
+  MyMass *tmpm,*tmpm1;
+  Bool chged=FALSE;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    tmpm1=tmpm->next;
+    if (!(0<=tmpm->x<MAP_WIDTH) ||
+          tmpm->collision) {
+      QueRem(tmpm);
+      for (i=tmpm->x-4;i<=tmpm->x+4;i++)
+        if (0<=i<MAP_WIDTH)
+          elevs[i]=ClampI64(elevs[i]+10-2*AbsI64(i-tmpm->x),0,MAP_HEIGHT-2);
+      Free(tmpm);
+      chged=TRUE;
+    }
+    tmpm=tmpm1;
+  }
+  if (chged)
+    DrawMap;
+}
+
+U0 MoveTask(I64)
+{
+  static F64 quit_time=0;
+  if (quit_time)
+    quit_time=tS+0.1;
+  else {
+    Snd(34);
+    Fs->task_end_cb=&SndTaskEndCB;
+    quit_time=tS+0.1;
+    while (quit_time>tS)
+      Yield;
+    quit_time=0;
+  }
+}
+
+U0 Init()
+{
+  CDC *map;
+  I64 i,x,y,dy;
+  if (!map_dcs[0])
+    map_dcs[0]=DCNew(MAP_WIDTH,MAP_HEIGHT);
+  if (!map_dcs[1])
+    map_dcs[1]=DCNew(MAP_WIDTH,MAP_HEIGHT);
+  map=map_dcs[active_map&1];
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+
+  y=ToI64(0.7*MAP_HEIGHT)<<32;
+  dy=0;
+  for (x=0;x<MAP_WIDTH;x++) {
+    dy=ClampI64(SignI64(RandI16)<<30+dy,-3<<32,3<<32);
+    y=ClampI64(y+dy,ToI64(0.3*MAP_HEIGHT)<<32,(MAP_HEIGHT-2)<<32);
+    elevs[x]=y.i32[1];
+  }
+  gun_x=RandU32%(MAP_WIDTH-100)+50;
+  gun_y=elevs[gun_x];
+  gun_theta=0;
+  gun_recoil=0;
+  for (x=gun_x-20;x<=gun_x+20;x++)
+    elevs[x]=gun_y;
+
+  wind_x=RandI16/250.0;
+  for (i=0;i<DUST_NUM;i++) {
+    dust_x[i]=RandU16%MAP_WIDTH;
+    dust_y[i]=RandU16%MAP_HEIGHT;
+  }
+
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.0001;
+  ode->acceleration_limit=5e5;
+  QueIns(ode,Fs->last_ode);
+  Fs->horz_scroll.min=0;
+  Fs->horz_scroll.max=MAP_WIDTH-Fs->pix_width;
+  Fs->horz_scroll.pos=gun_x-Fs->pix_width/2;
+  Fs->vert_scroll.min=0;
+  Fs->vert_scroll.max=MAP_HEIGHT-Fs->pix_height;
+  Fs->vert_scroll.pos=0;
+  TaskDerivedValsUpdate;
+
+  DrawMap;
+}
+
+U0 CleanUp(CMathODE *ode)
+{
+  if (ode) {
+    QueRem(ode);
+    QueDel(&ode->next_mass,TRUE);
+    ODEDel(ode);
+  }
+}
+
+U0 BigGuns()
+{
+  I64 ch,sc;
+
+  PopUpOk(
+        "I refuse to rip-off the original\n"
+        "so this is intentionally crappy\n"
+        "and included for demonstration\n"
+        "purposes.\n\n"
+        "Write games, don't play them.\n");
+
+  PopUpOk("The map scrolls.\n");
+
+  SettingsPush; //See SettingsPush
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fire(,CH_SPACE);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder(ON);
+  WinMax;
+  DocCursor;
+  DocClear;
+  DocScroll;
+  Init;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      while (ScanKey(&ch,&sc))
+        switch (ch) {
+          case 0:
+            switch (sc.u8[0]) {
+              case SC_CURSOR_RIGHT:
+                gun_theta+=2.0*pi/180;
+                if (gun_theta>0)
+                  gun_theta=0;
+                else
+                  Spawn(&MoveTask,NULL,"Move",,Fs);
+                break;
+              case SC_CURSOR_LEFT:
+                gun_theta-=2.0*pi/180;
+                if (gun_theta<-pi)
+                  gun_theta=-pi;
+                else
+                  Spawn(&MoveTask,NULL,"Move",,Fs);
+                break;
+            }
+            break;
+          case '\n':
+            CleanUp(ode);
+            Init;
+            break;
+          case CH_SPACE:
+            Spawn(&FireTask,NULL,"Fire",,Fs);
+            break;
+          case CH_SHIFT_ESC:
+          case CH_ESC:
+            goto bg_done;
+        }
+      ManageShots;
+      Refresh;
+    }
+bg_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCDel(map_dcs[0]); map_dcs[0]=NULL;
+  DCDel(map_dcs[1]); map_dcs[1]=NULL;
+  CleanUp(ode);
+  MenuPop;
+}
+
+BigGuns;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/BlackDiamond.HC.HTML b/public/Wb/Home/Src/Demo/Games/BlackDiamond.HC.HTML new file mode 100755 index 0000000..c4d62bf --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/BlackDiamond.HC.HTML @@ -0,0 +1,430 @@ + + + + + + + + + + + +
+/*Sprites were created with <CTRL-r>
+and can be edited by moving the
+cursor on top and pressing <CTRL-r>.
+
+<CTRL-t> to see the num of the sprite
+and <CTRL-t> again to get back.  Nums
+are assigned by the editor.
+*/
+
+
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+//See ::/Doc/Credits.DD.
+
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+                <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                <9>/* Graphics Not Rendered in HTML */
+
+RegDft("TempleOS/BlackDiamond","I64 best_score=9999;\n");
+RegExe("TempleOS/BlackDiamond");
+
+#define MAP_HEIGHT      3000
+#define OBJS_NUM        128
+
+I64 x,y,scrn_top_y,penalty,chair_lift_num;
+I64 obj_x[OBJS_NUM],obj_y[OBJS_NUM],obj_types[OBJS_NUM],
+    obj_saved_x[OBJS_NUM],obj_saved_y[OBJS_NUM];
+Bool game_over;
+
+#define T_TREE          0
+#define T_LITTLE_ROCK   1
+#define T_BIG_ROCK      2
+#define T_WOLF          3
+#define T_CHAIR_LIFT    4
+U8 *imgs[5]={<3>,<4>,<5>,<6>,<9>};
+
+#define DC_WOLF_WIDTH   48
+#define DC_WOLF_HEIGHT  38
+U0 DrawRunningWolf(CDC *dc,I64 i)
+{//Draw wolf on small DC so bottom gets clipped looking like sunk into snow.
+//Then, copy onto main DC.
+  U8 *tmps;
+  CDC *dc_wolf=DCNew(DC_WOLF_WIDTH,DC_WOLF_HEIGHT);
+  DCFill(dc_wolf);
+  if (x<obj_x[i]) {
+    dc_wolf->flags|=DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR;
+    DCSymmetrySet(dc_wolf,DC_WOLF_WIDTH/2,0,DC_WOLF_WIDTH/2,1);
+  }
+  if (tS%1.0<0.5)
+    tmps=<6>;
+  else
+    tmps=<7>;
+  Sprite3ZB(dc_wolf,DC_WOLF_WIDTH/2,0.85*DC_WOLF_HEIGHT,
+        0,tmps,0.4*Sin(7*tS));
+  GrBlot(dc,obj_x[i]-DC_WOLF_WIDTH/2,
+        obj_y[i]-scrn_top_y-0.85*DC_WOLF_HEIGHT,dc_wolf);
+  DCDel(dc_wolf);
+  if (0<=(obj_y[i]-scrn_top_y)<GR_HEIGHT)
+    obj_x[i]+=3*SignI64(x-obj_x[i]);
+}
+
+U0 DrawMan(CDC *dc)
+{
+  if(dc->collision_cnt)
+    Sprite3(dc,x,y-scrn_top_y,0,<2>); //Red man
+  else
+    Sprite3(dc,x,y-scrn_top_y,0,<1>); //Normal man
+}
+
+#define WIRE_HEIGHT     595
+#define WIRE_WIDTH      121
+#define WIRE_DIP        800
+#define PULLY_WIDTH     13
+U0 DrawUpperChairLift(CDC *dc)
+{
+  I64 i=chair_lift_num,x,x1,y=obj_y[i]-scrn_top_y-WIRE_HEIGHT,y1;
+  Sprite3(dc,obj_x[i],y+13,0,<8>);
+  dc->thick=2;
+  for (x=-WIRE_WIDTH/2;x<GR_WIDTH+WIRE_WIDTH/2;x+=2) { //Pen width is 2, step 2.
+    x1=x-obj_x[i];
+    y1=y-WIRE_DIP/2+Cosh(Ln(WIRE_DIP)+(Abs(x1)-PULLY_WIDTH)/10000.0)+0.1*x1;
+    if (!(-PULLY_WIDTH<x1<PULLY_WIDTH)) {
+      GrPlot3(dc,x-WIRE_WIDTH/2,y1,0);
+      GrPlot3(dc,x+WIRE_WIDTH/2,y1,0);
+    }
+  }
+  dc->thick=1;
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  Bool man_drawn=FALSE;
+
+  for (i=0;i<OBJS_NUM;i++)
+    if (obj_y[i]-32<=y<=obj_y[i]) {
+      if (obj_types[i]==T_WOLF && AbsI64(x-obj_x[i])>3)
+        DrawRunningWolf(dc,i);
+      else
+        Sprite3(dc,obj_x[i],obj_y[i]-scrn_top_y,0,imgs[obj_types[i]]);
+    }
+
+  dc->collision_cnt=0;
+  dc->color=ROP_COLLISION;
+  dc->bkcolor=WHITE;
+  Sprite3(dc,x,y-scrn_top_y,0,<1>);
+  if (!game_over) {
+    if(dc->collision_cnt) {
+      Snd(58);
+      penalty++; //Time is irregular. Scoring is imperfect. 30fps more or less.
+    } else
+      Snd;
+  }
+
+  dc->color=ROP_EQU;
+  for (i=0;i<OBJS_NUM;i++) {
+    if (!man_drawn && obj_y[i]>=y) {
+      DrawMan(dc);
+      man_drawn=TRUE;
+    }
+    if (obj_types[i]==T_WOLF && AbsI64(x-obj_x[i])>3)
+      DrawRunningWolf(dc,i);
+    else
+      Sprite3(dc,obj_x[i],obj_y[i]-scrn_top_y,0,imgs[obj_types[i]]);
+  }
+  if (!man_drawn)
+    DrawMan(dc);
+  DrawUpperChairLift(dc);
+
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Penalty:%d Best:%d",penalty,best_score);
+  if (game_over && Blink) {
+    dc->color=RED;
+    GrPrint(dc,(Fs->pix_width-9*FONT_WIDTH)/2,
+          (Fs->pix_height-FONT_HEIGHT)/2,"Game Over");
+  }
+}
+
+I64 Compare(I64 e1,I64 e2)
+{
+  return e1-e2;
+}
+
+U0 Init()
+{
+  I64 i,j;
+  for (i=0;i<OBJS_NUM;i++) {
+    obj_saved_y[i]=RandU32%MAP_HEIGHT;
+    obj_saved_x[i]=RandU32%GR_WIDTH;
+    j=RandU16;
+    if (j&7)
+      obj_types[i]=T_TREE;
+    else if (j&31)
+      obj_types[i]=T_LITTLE_ROCK;
+    else if (j&63)
+      obj_types[i]=T_BIG_ROCK;
+    else
+      obj_types[i]=T_WOLF;
+  }
+  QSortI64(obj_saved_y,OBJS_NUM,&Compare); //Break associations. Doesn't matter.
+
+  chair_lift_num=RandU16%OBJS_NUM;
+  obj_types[chair_lift_num]=T_CHAIR_LIFT;
+}
+
+U0 BlackDiamond()
+{
+  I64 ch,sc;
+
+  MenuPush(
+        "File {"
+        "  New(,'\n');"
+        "  Restart(,CH_SPACE);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+
+  Init;
+  try {
+    while (TRUE) {
+bd_restart:
+      MemCpy(obj_x,obj_saved_x,sizeof(obj_x)); //Wolves move. We must reset the
+      MemCpy(obj_y,obj_saved_y,sizeof(obj_y)); //wolves if running same game.
+
+      game_over=FALSE;
+      scrn_top_y=0;
+      x=Fs->pix_width>>1; y=0;
+      penalty=0;
+      while (TRUE) {
+        if (ScanKey(&ch,&sc)) {
+          switch (ch) {
+            case 0:
+              if (!game_over)
+                switch (sc.u8[0]) {
+                  case SC_CURSOR_RIGHT:
+                    x+=10;
+                    if (x>=Fs->pix_width) x-=Fs->pix_width;
+                    break;
+                  case SC_CURSOR_LEFT:
+                    x-=10;
+                    if (x<0) x+=Fs->pix_width;
+                    break;
+                  case SC_CURSOR_UP:
+                    y-=10;
+                    break;
+                  case SC_CURSOR_DOWN:
+                    y+=10;
+                    break;
+                }
+              break;
+
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto bd_done;
+
+            case '\n':
+              Init;
+              goto bd_restart;
+
+            case CH_SPACE:
+              game_over=TRUE;
+              while (scrn_top_y>0||y>0) {//Animate going back to top.
+                scrn_top_y=MaxI64(0,scrn_top_y-4);
+                y=MaxI64(0,y-4);
+                x+=SignI64(Fs->pix_width>>1-x);
+                Sleep(1);
+              }
+              Snd;
+              goto bd_restart;
+          }
+//Don't want keystrokes building-up in the buf.
+          FlushMsgs;
+        }
+        if (!game_over) {
+          y+=2;
+          scrn_top_y++;
+          if (y-scrn_top_y>Fs->pix_height) {//Animate scrolling scrn.
+            while (y-scrn_top_y>Fs->pix_height>>1) {
+              scrn_top_y+=2;
+              Sleep(1);
+            }
+          }
+          if (y>=MAP_HEIGHT) {
+            game_over=TRUE;
+            Beep;
+            if (penalty<=best_score) {
+              best_score=penalty;
+              Beep;
+            }
+          }
+        }
+        Sleep(10);
+      }
+    }
+bd_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/BlackDiamond","I64 best_score=%d;\n",best_score);
+}
+
+BlackDiamond; //Start game when #included.
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/BomberGolf.HC.HTML b/public/Wb/Home/Src/Demo/Games/BomberGolf.HC.HTML new file mode 100755 index 0000000..a21e747 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/BomberGolf.HC.HTML @@ -0,0 +1,389 @@ + + + + + + + + + + + +
+RegDft("TempleOS/BomberGolf","I64 best_score=99999;\n");
+RegExe("TempleOS/BomberGolf");
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <9>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <10>/* Graphics Not Rendered in HTML */
+
+
+#define MAP_WIDTH       600
+#define MAP_HEIGHT      600
+
+#define TREES_NUM       64
+class Tree
+{
+  I64 x,y;
+} trees[TREES_NUM];
+ 
+
+I64 target_cnt,key_cnt;
+
+
+#define TARGETS_NUM     10
+
+#define MDF_TANK                0
+#define MDF_BUNKER      1
+
+#define TANK_V          10.0
+
+class Target
+{
+  F64   x,y,theta;
+  U8    *alive_img,*dead_img1,*dead_img2;
+  U8    type;
+  Bool  dead,pad[6];
+} targets[TARGETS_NUM];
+
+#define FALL_TIME       3.00
+#define EXPLODE_TIME    0.25
+class Bomb
+{
+  Bomb *next,*last;
+  F64 x,y,t;
+  Bool exploding;
+} bomb_head;
+ 
+F64 v,x,y,
+    theta,thetaf; //thetaf is the final theta. theta is gradually changed until it reaches thetaf.
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j;
+  Bomb *tmpb;
+  Target *tmpt;
+  F64 ts=tS,dx,dy;
+
+  dc->color=ROPF_DITHER|BROWN<<16|YELLOW;
+  GrRect3(dc,0,0,0,dc->width,dc->height);
+
+  dc->x=task->pix_width>>1;
+  dc->y=task->pix_height>>1;
+  dc->flags|=DCF_TRANSFORMATION;
+  Mat4x4TranslationEqu(dc->r,x,y,0);
+  Mat4x4RotZ(dc->r,theta);
+  dc->color=BLACK;
+  GrBorder(dc,-MAP_WIDTH>>1,-MAP_HEIGHT>>1,MAP_WIDTH>>1,MAP_HEIGHT>>1);
+  for (i=0;i<TARGETS_NUM;i++) {
+    tmpt=&targets[i];
+    if (tmpt->dead) {
+      if (i&1) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetry3Set(dc,tmpt->x,tmpt->y,0,tmpt->x,tmpt->y,1,
+              tmpt->x+1024*Cos(tmpt->theta),tmpt->y+1024*Sin(tmpt->theta),0);
+      }
+      if (Blink(15))
+        Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->dead_img1,tmpt->theta);
+      else
+        Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->dead_img2,tmpt->theta);
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    } else
+      Sprite3ZB(dc,tmpt->x,tmpt->y,0,tmpt->alive_img,tmpt->theta);
+  }
+
+  for (i=0;i<TREES_NUM;i++)
+    Sprite3(dc,trees[i].x,trees[i].y,0,<2>);
+
+  for (i=0;i<TARGETS_NUM;i++) {
+    tmpt=&targets[i];
+    if (tmpt->dead) {
+      for (j=0;j<40;j++) {
+        dc->thick=4;
+        if (j&1)
+          dc->color=ROPF_DITHER|LTGRAY<<16|BLACK;
+        else
+          dc->color=ROPF_DITHER|DKGRAY<<16|LTGRAY;
+        dx=15*Sin(ts/4+j<<6)+j>>2;
+        dy=10*FullTri(ts/3+j/2.0,20)+j>>2;
+        GrPlot3(dc,tmpt->x+5+dx+0.5*dy,tmpt->y+0.5*dx+dy,0);
+      }
+    }
+  }
+
+  tmpb=bomb_head.next;
+  while (tmpb!=&bomb_head) {
+    if (tmpb->t+FALL_TIME<tS) {
+      if (Blink(10))
+        Sprite3(dc,tmpb->x,tmpb->y,0,<9>);
+      else
+        Sprite3(dc,tmpb->x,tmpb->y,0,<10>);
+    }
+    tmpb=tmpb->next;
+  }
+
+  dc->flags&=~DCF_TRANSFORMATION;
+  Sprite3(dc,task->pix_width>>1,task->pix_height>>1,0,<1>);
+  dc->color=RED;
+  GrPrint(dc,0,0,"Targets:%02d  KeyStrokes:%04d Best:%04d",
+        target_cnt,key_cnt,best_score);
+  if (!target_cnt && Blink(4))
+    GrPrint(dc,(task->pix_width-FONT_WIDTH*14)>>1,
+          (task->pix_height-FONT_HEIGHT)>>1-32,"Game Completed");
+}
+ 
+U0 BombHit(Bomb *tmpb)
+{
+  I64 i;
+  for (i=0;i<TARGETS_NUM;i++) {
+    if (!targets[i].dead &&
+          SqrI64(tmpb->x-targets[i].x)+SqrI64(tmpb->y-targets[i].y)<20*20) {
+      targets[i].dead=TRUE;
+      target_cnt--;
+    }
+  }
+  QueRem(tmpb);
+  Free(tmpb);
+}
+ 
+U0 BombDrop(F64 x,F64 y)
+{
+  Bomb *tmpb=MAlloc(sizeof(Bomb));
+  tmpb->x=x;
+  tmpb->y=y;
+  tmpb->t=tS;
+  tmpb->exploding=FALSE;
+  QueIns(tmpb,bomb_head.last);
+  Sweep(FALL_TIME*1000,74,62);
+}
+ 
+I64 AnimateTask(CTask *)
+{
+  F64 last_t=tS,dt;
+  I64 i;
+  Bomb *tmpb,*tmpb1;
+  Target *tmpt;
+  while (TRUE) {
+    dt=tS-last_t;
+    last_t=tS;
+
+    if (bomb_head.next==&bomb_head) {
+      if (target_cnt)
+        Snd(Freq2Ona(100+60*Clamp(0.1*(1.0+Abs(Wrap(thetaf-theta,-pi)))`4.0,-3,3)));
+      else if (key_cnt<best_score) {
+        best_score=key_cnt;
+        Sleep(150); Snd(74);Sleep(150);Snd;
+        Sleep(150); Snd(74);Sleep(150);Snd;
+      } else
+        Snd;
+    }
+
+    theta+=dt*(thetaf-theta);
+    x+=dt*v*Sin(theta);
+    y+=dt*v*Cos(theta);
+
+    for (i=0;i<TARGETS_NUM;i++) {
+      tmpt=&targets[i];
+      if (!tmpt->dead && tmpt->type==MDF_TANK) {
+        tmpt->x+=dt*TANK_V*Cos(tmpt->theta);
+        tmpt->y+=dt*TANK_V*Sin(tmpt->theta);
+        if (i&1)
+          tmpt->theta+=dt*pi/16;
+        else
+          tmpt->theta-=dt*pi/16;
+      }
+    }
+
+    tmpb=bomb_head.next;
+    while (tmpb!=&bomb_head) {
+      tmpb1=tmpb->next;
+      if (tmpb->t+FALL_TIME+EXPLODE_TIME<tS)
+        BombHit(tmpb);
+      else if (tmpb->t+FALL_TIME<tS && !tmpb->exploding) {
+        Noise(EXPLODE_TIME*1000,62,74);
+        tmpb->exploding=TRUE;
+      }
+      tmpb=tmpb1;
+    }
+
+    Sleep(10);
+  }
+  return 0;
+}
+ 
+U0 Init()
+{
+  I64 i;
+  Target *tmpt;
+
+  v=20;
+  x=-MAP_WIDTH>>1;
+  y=-MAP_HEIGHT>>1;
+  thetaf=theta=1*pi/4;
+
+  QueInit(&bomb_head);
+
+  MemSet(trees,0,sizeof(trees));
+  for (i=0;i<TREES_NUM;i++) {
+    trees[i].x=RandU32%MAP_WIDTH -MAP_WIDTH >>1;
+    trees[i].y=RandU32%MAP_HEIGHT-MAP_HEIGHT>>1;
+  }
+
+  MemSet(targets,0,sizeof(targets));
+  for (i=0;i<TARGETS_NUM;i++) {
+    tmpt=&targets[i];
+    tmpt->x=RandU32%MAP_WIDTH -MAP_WIDTH >>1;
+    tmpt->y=RandU32%MAP_HEIGHT-MAP_HEIGHT>>1;
+    if (i<TARGETS_NUM/3) {
+      tmpt->type=MDF_BUNKER;
+      tmpt->theta=(RandU16&3)*pi/2;
+      tmpt->alive_img=<6>;
+      tmpt->dead_img1=<7>;
+      tmpt->dead_img2=<8>;
+    } else {
+      tmpt->type=MDF_TANK;
+      tmpt->theta=Rand*2*pi;
+      tmpt->alive_img=<3>;
+      tmpt->dead_img1=<4>;
+      tmpt->dead_img2=<5>;
+    }
+  }
+  key_cnt=0;
+  target_cnt=TARGETS_NUM;
+}
+
+U0 CleanUp()
+{
+  QueDel(&bomb_head,TRUE);
+}
+
+U0 BomberGolf()
+{
+  I64 sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Faster(,,SC_CURSOR_UP);"
+        "  Slower(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Bomb(,CH_SPACE);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  Init;
+  try {
+    while (TRUE)
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_UP:
+              v+=10;
+              if (v>300) v=300;
+              break;
+            case SC_CURSOR_DOWN:
+              v-=10;
+              if (v<20) v=20;
+              break;
+            case SC_CURSOR_LEFT:
+              key_cnt++;
+              thetaf+=1.0/(Abs(Wrap(thetaf-theta,-pi))+2*pi);
+              break;
+            case SC_CURSOR_RIGHT:
+              key_cnt++;
+              thetaf-=1.0/(Abs(Wrap(thetaf-theta,-pi))+2*pi);
+              break;
+
+          }
+          break;
+        case CH_SPACE:
+          key_cnt++;
+          BombDrop(-x-0.8*FALL_TIME*v*Sin(theta),-y-0.8*FALL_TIME*v*Cos(theta));
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto bm_done;
+      }
+bm_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/BomberGolf","I64 best_score=%d;\n",best_score);
+}
+ 
+BomberGolf;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/CastleFrankenstein.HC.HTML b/public/Wb/Home/Src/Demo/Games/CastleFrankenstein.HC.HTML new file mode 100755 index 0000000..9dc6497 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/CastleFrankenstein.HC.HTML @@ -0,0 +1,627 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+RegDft("TempleOS/CastleFrankenstein","F64 best_score=9999;\n");
+RegExe("TempleOS/CastleFrankenstein");
+
+//Set snap to 4 and width to 4
+//if you edit this map.
+
+//Don't forget to change the
+//starting pos.
+#define MAN_START_X     0
+#define MAN_START_Y     4.5
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#define MONSTER_SCALE   2.0
+
+                     <2>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+
+
+
+                     <3>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+
+
+                     <4>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+#define PLANT_SCALE     2.0
+
+
+
+                     <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+                       <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+#define SCRN_SCALE              512
+#define PLOT_GRID_WIDTH         24
+#define PLOT_GRID_HEIGHT        24
+#define MAN_HEIGHT              125
+
+#define MAP_SCALE       4
+I64 map_width,map_height;
+U8 *map=NULL,
+*panels_processed_bitmap=NULL;
+
+I64 man_xx,man_yy;
+F64 man_theta;
+
+F64 t0,tf;
+
+#define MONSTERS_NUM    10
+I64 monsters_left;
+class Monster
+{
+  I64 x,y;
+  Bool dead,pad[7];
+} monsters[MONSTERS_NUM];
+
+U0 CFTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  zz=SCRN_SCALE/3+*z;
+  if (zz<1) zz=1;
+  *x=SCRN_SCALE/2* *x/zz;
+  *y=SCRN_SCALE/2* (*y+MAN_HEIGHT)/zz;
+  *x+=dc->x;
+  *y+=dc->y;
+  *z+=dc->z;
+}
+
+#define LOS_SCALE       4
+
+Bool LOSPlot(U8 *,I64 x,I64 y,I64)
+{
+  if (!map[(y/LOS_SCALE)*map_width+(x/LOS_SCALE)])
+    return FALSE;
+  else
+    return TRUE;
+}
+
+Bool LOS(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Line of sight
+  return Line(NULL,x1*LOS_SCALE/SCRN_SCALE,y1*LOS_SCALE/SCRN_SCALE,0,
+        x2*LOS_SCALE/SCRN_SCALE,y2*LOS_SCALE/SCRN_SCALE,0,&LOSPlot);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,*r1,*r2,*r3,*s2w,xx,yy,zz,x,y,x1,y1,z1,
+        c,x1w,y1w,x1h,y1h,xh,yh,zh,
+        cx=task->pix_width/2,
+        cy=task->pix_height/2;
+  U8 *tmps;
+  F64 tt;
+  CD3I32 poly[4];
+  Monster *tmpm;
+
+  DCDepthBufAlloc(dc);
+  MemSet(panels_processed_bitmap,0,(map_width*map_height+7)>>3);
+
+  //World to scrn
+  Mat4x4RotZ(dc->r,man_theta+pi/2);
+  Mat4x4RotX(dc->r,pi/2);
+  DCMat4x4Set(dc,dc->r);
+
+  xh=-man_xx/SCRN_SCALE; yh=-man_yy/SCRN_SCALE; zh=0;
+  Mat4x4MulXYZ(dc->r,&xh,&yh,&zh);
+  Mat4x4TranslationEqu(dc->r,xh,yh,zh);
+
+  //Scrn to world
+  s2w=Mat4x4IdentNew(task);
+  Mat4x4RotX(s2w,-pi/2);
+  Mat4x4RotZ(s2w,-man_theta-pi/2);
+  xh=0; yh=0; zh=SCRN_SCALE;
+  Mat4x4MulXYZ(s2w,&xh,&yh,&zh);
+
+  //Rotate light source
+  xx=dc->ls.x; yy=dc->ls.y; zz=-dc->ls.z;
+  (*dc->transform)(dc,&xx,&yy,&zz);
+  dc->ls.x=xx; dc->ls.y=yy; dc->ls.z=zz;
+
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->transform=&CFTransform;
+  dc->x=cx;
+  dc->y=cy;
+  r1=Mat4x4IdentNew(task);
+  Mat4x4RotX(r1,-pi/2);
+  Mat4x4RotZ(r1,tS);
+  Mat4x4Scale(r1,MONSTER_SCALE);
+
+  r2=Mat4x4IdentNew(task);
+  Mat4x4Scale(r2,MONSTER_SCALE);
+
+  r3=Mat4x4IdentNew(task);
+  Mat4x4RotX(r3,-pi/2);
+  Mat4x4Scale(r3,PLANT_SCALE);
+
+  Seed(1);
+  x1h=man_xx+yh*PLOT_GRID_WIDTH/2+xh*(PLOT_GRID_HEIGHT-1);
+  y1h=man_yy-xh*PLOT_GRID_WIDTH/2+yh*(PLOT_GRID_HEIGHT-1);
+  xh>>=1; yh>>=1;
+  for (j=0;j<PLOT_GRID_HEIGHT*2;j++) {
+    x1w=x1h;
+    y1w=y1h;
+    for (i=0;i<PLOT_GRID_WIDTH*4;i++) {
+      xx=x1w/SCRN_SCALE; yy=y1w/SCRN_SCALE;
+      x=xx*SCRN_SCALE-man_xx; y=yy*SCRN_SCALE-man_yy;
+      if (1<=xx<map_width-1 && 1<=yy<map_height-1 &&
+            !LBts(panels_processed_bitmap,yy*map_width+xx)) {
+        if ((c=map[yy*map_width+xx]) &&
+              LOS(xx*SCRN_SCALE+SCRN_SCALE/2,yy*SCRN_SCALE+SCRN_SCALE/2,
+              man_xx,man_yy)) {
+          if (c==YELLOW)
+            dc->color=DKGRAY;
+          else
+            dc->color=c;
+          poly[0].x=x;
+          poly[0].y=y;
+          poly[0].z=0;
+          poly[1].x=x+SCRN_SCALE;
+          poly[1].y=y;
+          poly[1].z=0;
+          poly[2].x=x+SCRN_SCALE;
+          poly[2].y=y+SCRN_SCALE;
+          poly[2].z=0;
+          poly[3].x=x;
+          poly[3].y=y+SCRN_SCALE;
+          poly[3].z=0;
+          GrFillPoly3(dc,4,poly);
+          if (c==GREEN) {
+            x1=x+SCRN_SCALE/2;
+            y1=y+SCRN_SCALE/2;
+            z1=0;
+            DCTransform(dc,&x1,&y1,&z1);
+            if (z1>0)
+              Sprite3Mat4x4B(dc,x+SCRN_SCALE/2,y+SCRN_SCALE/2,0,<5>,r3);
+          } else if (c==YELLOW) {
+            x1=x+SCRN_SCALE/2;
+            y1=y+SCRN_SCALE/2;
+            z1=0;
+            DCTransform(dc,&x1,&y1,&z1);
+            if (z1>0)
+              Sprite3Mat4x4B(dc,x+SCRN_SCALE/2,y+SCRN_SCALE/2,0,<6>,r3);
+          }
+
+          if (!map[(yy+1)*map_width+xx]) {
+            dc->color=LTGRAY;
+            poly[0].x=x;
+            poly[0].y=y+SCRN_SCALE;
+            poly[0].z=0;
+            poly[1].x=x+SCRN_SCALE;
+            poly[1].y=y+SCRN_SCALE;
+            poly[1].z=0;
+            poly[2].x=x+SCRN_SCALE;
+            poly[2].y=y+SCRN_SCALE;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x;
+            poly[3].y=y+SCRN_SCALE;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+          if (!map[yy*map_width+xx+1]) {
+            dc->color=WHITE;
+            poly[0].x=x+SCRN_SCALE;
+            poly[0].y=y;
+            poly[0].z=0;
+            poly[1].x=x+SCRN_SCALE;
+            poly[1].y=y+SCRN_SCALE;
+            poly[1].z=0;
+            poly[2].x=x+SCRN_SCALE;
+            poly[2].y=y+SCRN_SCALE;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x+SCRN_SCALE;
+            poly[3].y=y;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+          if (!map[(yy-1)*map_width+xx]) {
+            dc->color=LTGRAY;
+            poly[0].x=x;
+            poly[0].y=y;
+            poly[0].z=0;
+            poly[1].x=x+SCRN_SCALE;
+            poly[1].y=y;
+            poly[1].z=0;
+            poly[2].x=x+SCRN_SCALE;
+            poly[2].y=y;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x;
+            poly[3].y=y;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+          if (!map[yy*map_width+xx-1]) {
+            dc->color=WHITE;
+            poly[0].x=x;
+            poly[0].y=y;
+            poly[0].z=0;
+            poly[1].x=x;
+            poly[1].y=y+SCRN_SCALE;
+            poly[1].z=0;
+            poly[2].x=x;
+            poly[2].y=y+SCRN_SCALE;
+            poly[2].z=SCRN_SCALE;
+            poly[3].x=x;
+            poly[3].y=y;
+            poly[3].z=SCRN_SCALE;
+            GrFillPoly3(dc,4,poly);
+          }
+        }
+      }
+      x1w-=yh;
+      y1w+=xh;
+    }
+    x1h-=xh;
+    y1h-=yh;
+  }
+
+  //Draw Monsters
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    x=tmpm->x;
+    y=tmpm->y;
+    if (LOS(x,y,man_xx,man_yy)) {
+      x-=man_xx;
+      y-=man_yy;
+      xx=x;
+      yy=y;
+      zz=0;
+      DCTransform(dc,&xx,&yy,&zz);
+      if (zz>0) {
+        if (tmpm->dead)
+          Sprite3Mat4x4B(dc,x,y,0,<2>,r2);
+        else {
+          tt=Tri(tS,1.0);
+          tmps=SpriteInterpolate(tt,<3>,<4>);
+          Sprite3Mat4x4B(dc,x,y,0,tmps,r1);
+          Free(tmps);
+        }
+      }
+    }
+  }
+  Free(r1);
+  Free(r2);
+  Free(r3);
+
+  //Draw Map heads-up display, scaled 2 pixs
+  Free(dc->r);
+  DCMat4x4Set(dc,Mat4x4IdentNew(task));
+  dc->x=task->pix_width -2*map_width;
+  dc->y=task->pix_height-2*map_height;
+  dc->z=0;
+  dc->transform=&DCTransform;
+  dc->thick=2;
+  for (i=0;i<map_height;i++)
+    for (j=0;j<map_width;j++) {
+      dc->color=map[(map_height-1-i)*map_width+j];
+      GrPlot3(dc,2*j,2*i,0);
+    }
+
+    //Draw Things on heads-up Map
+  dc->color=LTPURPLE;
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+    if (!tmpm->dead)
+      GrPlot3(dc,2*(tmpm->x/SCRN_SCALE),
+            2*(map_height-1-tmpm->y/SCRN_SCALE),0);
+  dc->color=LTCYAN;
+  GrPlot3(dc,2*(man_xx/SCRN_SCALE),2*(map_height-1-man_yy/SCRN_SCALE),0);
+
+  if (tf) {
+    dc->color=LTRED;
+    if (Blink)
+      GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed");
+    tt=tf;
+  } else {
+    dc->color=LTGREEN;
+    GrLine(dc,cx-5,cy,cx+5,cy);
+    GrLine(dc,cx,cy-5,cx,cy+5);
+    tt=tS;
+  }
+  GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",
+        monsters_left,tt-t0,best_score);
+  Free(s2w);
+  Seed(0);
+}
+
+U0 Fire()
+{
+  I64 i,x,y;
+  F64 d,dx,dy,xx=Cos(man_theta),yy=Sin(man_theta);
+  Monster *tmpm;
+
+  Noise(100,53,74);
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    x=tmpm->x;
+    y=tmpm->y;
+    if (!tmpm->dead &&
+          LOS(x,y,man_xx,man_yy)) {
+      dx=x-man_xx;
+      dy=man_yy-y;
+      if (d=Sqrt(dx*dx+dy*dy)) {
+        dx/=d;
+        dy/=d;
+        if (dx*xx+dy*yy>0.995) {
+          tmpm->dead=TRUE;
+          if (!--monsters_left) {
+            tf=tS;
+            if (tf-t0<best_score)
+              best_score=tf-t0;
+          }
+        }
+      }
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,x,y;
+  CDC *dc;
+  Monster *tmpm;
+
+  DocClear;
+  "$BG,BLACK$%h*c",TEXT_ROWS/2,'\n';
+
+  dc=Sprite2DC(<1>);
+  map_width =dc->width/MAP_SCALE+2;
+  map_height=dc->height/MAP_SCALE+2;
+  Free(map);
+  Free(panels_processed_bitmap);
+  map=CAlloc(map_width*map_height*sizeof(U8));
+  panels_processed_bitmap=MAlloc((map_width*map_height+7)>>3);
+  for (y=0;y<map_height-2;y++)
+    for (x=0;x<map_width-2;x++)
+      map[(map_height-2-y)*map_width+x+1]=GrPeek(dc,x*MAP_SCALE,y*MAP_SCALE);
+  DCDel(dc);
+  man_xx=(1+MAN_START_X)*SCRN_SCALE;
+  man_yy=(map_height-1-MAN_START_Y)*SCRN_SCALE;
+  man_theta=0;
+
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    tmpm->dead=FALSE;
+    do {
+      tmpm->x=RandU64%((map_width-2)*SCRN_SCALE)+SCRN_SCALE;
+      tmpm->y=RandU64%((map_height-2)*SCRN_SCALE)+SCRN_SCALE;
+    } while (!map[(tmpm->y/SCRN_SCALE)*map_width+tmpm->x/SCRN_SCALE]);
+  }
+  monsters_left=MONSTERS_NUM;
+  tf=0;
+  t0=tS;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i,x,y,dd;
+  Monster *tmpm;
+
+  while (TRUE) {
+    dd=0.25*SCRN_SCALE*Sin(tS/2);
+    for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+      if (!tmpm->dead) {
+        x=tmpm->x;
+        y=tmpm->y;
+        if (i&1)
+          x+=dd;
+        else
+          y+=dd;
+        if (0<=x<=map_width*SCRN_SCALE &&
+              0<=y<=map_height*SCRN_SCALE &&
+              map[(y/SCRN_SCALE)*map_width+x/SCRN_SCALE]) {
+          if (!map[(y/SCRN_SCALE)*map_width+x/SCRN_SCALE+1] &&
+                x-RoundI64(x,SCRN_SCALE)>SCRN_SCALE/2 ||
+                !map[(y/SCRN_SCALE)*map_width+x/SCRN_SCALE-1] &&
+                x-RoundI64(x,SCRN_SCALE)<SCRN_SCALE/2)
+            x=RoundI64(x,SCRN_SCALE)+SCRN_SCALE/2;
+          if (!map[(y/SCRN_SCALE+1)*map_width+x/SCRN_SCALE] &&
+                y-RoundI64(y,SCRN_SCALE)>SCRN_SCALE/2 ||
+                !map[(y/SCRN_SCALE-1)*map_width+x/SCRN_SCALE] &&
+                y-RoundI64(y,SCRN_SCALE)<SCRN_SCALE/2)
+            y=RoundI64(y,SCRN_SCALE)+SCRN_SCALE/2;
+          tmpm->x=x;
+          tmpm->y=y;
+        }
+      }
+    Sleep(20);
+  }
+}
+
+U0 CleanUp()
+{
+  Free(map);
+  Free(panels_processed_bitmap);
+  map=NULL;
+  panels_processed_bitmap=NULL;
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("3q.A#eGAeA#qAq.A#eGeAeA#qA");
+    Play("3q.A#eGA#AqGq.A#eGA#AqG");
+    Play("4eA#AqGeA#AqGeA#AGAA#AqG");
+  }
+}
+
+U0 MoveMan(F64 theta)
+{
+  I64 x,y,color,step=SCRN_SCALE/2;
+  do {
+    x=man_xx+step*Cos(theta);
+    y=man_yy-step*Sin(theta);
+    x=Clamp(x,0,map_width*SCRN_SCALE);
+    y=Clamp(y,0,map_height*SCRN_SCALE);
+    color=map[y/SCRN_SCALE*map_width+x/SCRN_SCALE];
+    if (color==DKGRAY || color==GREEN) {
+      man_xx=x;
+      man_yy=y;
+      break;
+    } else
+      step>>=1;
+  } while (step);
+}
+
+#define MICRO_STEPS     4
+U0 RotateMan(F64 d)
+{
+  I64 i;
+  for (i=0;i<MICRO_STEPS;i++) {
+    man_theta+=d/MICRO_STEPS;
+    Sleep(15);
+  }
+}
+
+U0 CastleFrankenstein()
+{
+  I64 sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fwd(,,SC_CURSOR_UP);"
+        "  Bwd(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Fire(,CH_SPACE);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=DKGRAY<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case CH_SPACE:
+          Fire;
+          break;
+        case '\n':
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto fs_done;
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_RIGHT:
+              Spawn(&RotateMan,(pi/32)(I64));
+              break;
+            case SC_CURSOR_LEFT:
+              Spawn(&RotateMan,(-pi/32)(I64));
+              break;
+            case SC_CURSOR_UP:
+              MoveMan(man_theta);
+              break;
+            case SC_CURSOR_DOWN:
+              MoveMan(man_theta+pi);
+              break;
+          }
+          break;
+      }
+    }
+fs_done:
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/CastleFrankenstein","F64 best_score=%5.4f;\n",
+        best_score);
+}
+
+CastleFrankenstein;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/CharDemo.HC.HTML b/public/Wb/Home/Src/Demo/Games/CharDemo.HC.HTML new file mode 100755 index 0000000..bdca622 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/CharDemo.HC.HTML @@ -0,0 +1,222 @@ + + + + + + + + + + + +
+/*
+Char graphics are how games on the C64 were made.  You don't need to do it
+this way, unless for fun.  You can just make device context bigger than
+the scrn and scroll around.
+
+See  ::/Demo/Games/RawHide.HC or ::/Demo/Games/BigGuns.HC.
+
+The nice thing about character graphics are the animations.
+*/
+
+#define MAP_WIDTH       (TEXT_COLS*2)
+#define MAP_HEIGHT      (TEXT_ROWS*2)
+
+#define CH_WATER        '^'
+#define CH_LAND         CH_SPACE
+#define CH_TREE         '*'
+
+U16 map[MAP_HEIGHT][MAP_WIDTH];
+
+I64 scrn_pix_x,scrn_pix_y;
+
+U0 DrawIt(CTask *task,CDC *)
+{
+  U16 *ptr;
+  I64 i,j,y=scrn_pix_y>>3;
+  gr.hide_col=gr.hide_row=TRUE;
+  gr.pan_text_x=7-scrn_pix_x&7;
+  gr.pan_text_y=7-scrn_pix_y&7;
+  for (i=0;i<task->win_height;i++) {
+    ptr=&map[y++][scrn_pix_x>>3];
+    for (j=0;j<task->win_width;j++)
+        //By the time you clip to window and handle Fs->scroll_x,Fs->scroll_y,
+        //it is too much trouble to do raw access to gr.text_base like we do
+        //in ::/Demo/Games/Maze.HC.
+      TextChar(task,FALSE,j,i,*ptr++);
+  }
+}
+
+U8 *old_font=text.font;
+U64 waves[4]={
+0x0011AA440011AA44,0x0022558800225588,
+0x0044AA110044AA11,0x0088552200885522};
+
+U0 AnimateEndCB()
+{
+  text.font=old_font;
+  Exit;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  U64 *font=MAlloc(256*8);
+  Fs->task_end_cb=&AnimateEndCB;
+  MemCpy(font,text.font,256*8);
+  text.font=font;
+  font[CH_TREE]=0x18187E7E3C3C18;
+  while (TRUE) {
+    font[CH_WATER]=waves[i++&0x3];
+    Sleep(200);
+    Refresh;
+  }
+}
+
+U0 ScrollTaskX(I64 sign)
+{
+  I64 i;
+  for (i=0;i<32;i++) {
+    scrn_pix_x=ClampI64(scrn_pix_x+sign,0,
+          (MAP_WIDTH-TEXT_COLS+1)*FONT_WIDTH);
+    Refresh;
+  }
+}
+
+U0 ScrollTaskY(I64 sign)
+{
+  I64 i;
+  for (i=0;i<32;i++) {
+    scrn_pix_y=ClampI64(scrn_pix_y+sign,0,
+          (MAP_HEIGHT-TEXT_ROWS+2)*FONT_HEIGHT);
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  I64 i,j,x,y;
+  scrn_pix_x=(MAP_WIDTH-TEXT_COLS)>>1*FONT_WIDTH;
+  scrn_pix_y=(MAP_HEIGHT-TEXT_ROWS)>>1*FONT_HEIGHT;
+
+  MemSetU16(map,CH_WATER+(BLUE<<4+LTBLUE)<<8,MAP_WIDTH*MAP_HEIGHT);
+  for (i=1;i<MAP_WIDTH-1;i++)
+    map[0][i]=map[MAP_HEIGHT-1][i]='.'+(BLUE<<4+RED)<<8;
+  for (i=1;i<MAP_HEIGHT-1;i++)
+    map[i][0]=map[i][MAP_WIDTH-1]='.'+(BLUE<<4+RED)<<8;
+  map[0][0]                     ='.'+(BLUE<<4+RED)<<8;
+  map[0][MAP_WIDTH-1]           ='.'+(BLUE<<4+RED)<<8;
+  map[MAP_HEIGHT-1][0]          ='.'+(BLUE<<4+RED)<<8;
+  map[MAP_HEIGHT-1][MAP_WIDTH-1]='.'+(BLUE<<4+RED)<<8;
+
+  for (i=0;i<20;i++) {
+    x=MAP_WIDTH*Rand;
+    y=MAP_HEIGHT*Rand;
+    for (j=0;j<1000;j++) {
+      map[y][x]=CH_LAND+(YELLOW<<4+BLACK)<<8;
+      x=ClampI64(x+RandU16%3-1,0,MAP_WIDTH-1);
+      y=ClampI64(y+RandU16%3-1,0,MAP_HEIGHT-1);
+    }
+  }
+  for (i=0;i<100;i++) {
+    do {
+      x=MAP_WIDTH*Rand;
+      y=MAP_HEIGHT*Rand;
+    } while (map[y][x].u8[0]!=CH_LAND);
+    for (j=0;j<100;j++) {
+      map[y][x]=CH_TREE+(YELLOW<<4+GREEN)<<8;
+      x=ClampI64(x+RandU16%3-1,0,MAP_WIDTH-1);
+      y=ClampI64(y+RandU16%3-1,0,MAP_HEIGHT-1);
+    }
+  }
+}
+
+U0 CleanUp()
+{
+  gr.pan_text_x=gr.pan_text_y=0;
+  gr.hide_col=gr.hide_row=FALSE;
+}
+
+U0 CharDemo()
+{
+  I64 sc;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "}"
+        );
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              Spawn(&ScrollTaskX,-1,"Scroll",,Fs);
+              break;
+            case SC_CURSOR_RIGHT:
+              Spawn(&ScrollTaskX,1,"Scroll",,Fs);
+              break;
+            case SC_CURSOR_UP:
+              Spawn(&ScrollTaskY,-1,"Scroll",,Fs);
+              break;
+            case SC_CURSOR_DOWN:
+              Spawn(&ScrollTaskY,1,"Scroll",,Fs);
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto sq_done;
+      }
+    }
+sq_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+CharDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/CircleTrace.HC.HTML b/public/Wb/Home/Src/Demo/Games/CircleTrace.HC.HTML new file mode 100755 index 0000000..6a1298b --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/CircleTrace.HC.HTML @@ -0,0 +1,159 @@ + + + + + + + + + + + +
+//Practice tracing circles
+
+//Giotto, a famous artist, drew a freehand circle to get a job.
+
+RegDft("TempleOS/CircleTrace","F64 best_score=999;\n");
+RegExe("TempleOS/CircleTrace");
+
+I64 cx,cy;
+F64 avg_error=0,elapsed_time=0,total_error=0,score=999;
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE)
+    Play("5hEDC4A5RCDECR");
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  GrPrint(dc,0,0,"Error:%6.3f  Time:%6.3f  Score:%6.3f  Best:%8.3f",
+        avg_error,elapsed_time,score,best_score);
+}
+
+#define CIRCLE_RADIUS   100
+#define CIRCUMFERENCE   (2*pi*CIRCLE_RADIUS)
+
+Bool CTPlot(CDC *dc,I64 x,I64 y,I64)
+{
+  F64 rad=Sqrt(Sqr(x-cx)+Sqr(y-cy));
+  GrPlot(dc,x,y);
+  total_error+=Abs(rad-CIRCLE_RADIUS);
+  return TRUE;
+}
+
+U0 CircleTrace()
+{
+  I64 msg_code,arg1,arg2,x1,y1;
+  F64 rad,t0,total_distance;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  cx=Fs->pix_width/2;
+  cy=Fs->pix_height/2;
+
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+  Fs->draw_it=&DrawIt;
+
+  DCFill;
+  dc->color=ROP_XOR+BLACK^TRANSPARENT;
+  GrCircle(dc,cx,cy,CIRCLE_RADIUS);
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
+    switch (msg_code) {
+      case MSG_KEY_UP:
+        break;
+      case MSG_MS_L_DOWN:
+        DCFill;
+        dc->color=ROP_XOR+BLACK^TRANSPARENT;
+        GrCircle(dc,cx,cy,CIRCLE_RADIUS);
+        dc->color=ROP_XOR+RED^TRANSPARENT;
+        t0=tS;
+        total_distance=0.001;
+        total_error=0;
+        x1=arg1; y1=arg2;
+        do {
+          msg_code=ScanMsg(&arg1,&arg2,
+                1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          switch (msg_code) {
+            case MSG_MS_L_UP:
+              break;
+            case MSG_MS_MOVE:
+              if (x1!=arg1 || y1!=arg2) {
+                total_distance+=Sqrt(Sqr(x1-arg1)+Sqr(y1-arg2));
+                Line(dc,x1,y1,0,arg1,arg2,0,&CTPlot);
+                x1=arg1;y1=arg2;
+//undo overlapping pixs on segments
+                GrPlot(dc,x1,y1);
+                rad=Sqrt(Sqr(x1-cx)+Sqr(y1-cy));
+                total_error-=Abs(rad-CIRCLE_RADIUS);
+              }
+              break;
+          }
+          elapsed_time=tS-t0;
+          avg_error=total_error/total_distance;
+          score=elapsed_time*avg_error;
+
+          //Sleep()s until the next time the
+          //window mgr task runs.  The
+          //window mgr calls the UpdateWin() routine
+          //and places msgs in the que, so there's
+          //no need to do anything until the window mgr runs.
+          Refresh;
+
+        } while (msg_code!=MSG_MS_L_UP);
+        music.mute=TRUE; Sleep(200);
+        if (total_distance>0.95*CIRCUMFERENCE) {
+          if (score<best_score) {
+            Snd(86);Sleep(50);Snd;Sleep(50);
+            Snd(86);Sleep(50);Snd;Sleep(50);
+            Snd(86);Sleep(50);
+            best_score=score;
+          } else {
+            Snd(62);Sleep(50);
+          }
+        } else {
+          Snd(34);Sleep(1000);
+        }
+        Snd; Sleep(200); music.mute=FALSE;
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || arg1!=CH_SHIFT_ESC && arg1!=CH_ESC);
+  GetMsg(,,1<<MSG_KEY_UP);
+  SettingsPop;
+  DCFill;
+  DCDel(dc);
+  RegWrite("TempleOS/CircleTrace","F64 best_score=%5.4f;\n",best_score);
+}
+
+CircleTrace;  //Execute when #included
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Collision.HC.HTML b/public/Wb/Home/Src/Demo/Games/Collision.HC.HTML new file mode 100755 index 0000000..9fcd415 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Collision.HC.HTML @@ -0,0 +1,185 @@ + + + + + + + + + + + +
+/*Uses fixed-point arithmetic
+because it used to be faster than floating
+point.  See ::/Demo/Lectures/FixedPoint.HC.
+
+The decimal place is between
+bits 31 and 32.
+*/
+
+#define BALLS_NUM       64
+#define BALL_RADIUS     5
+
+I64 ball_x[BALLS_NUM],ball_y[BALLS_NUM],
+   ball_velocity_x[BALLS_NUM],ball_velocity_y[BALLS_NUM];
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  dc->color=RED;
+  for (i=0;i<BALLS_NUM;i++)
+    GrCircle(dc,ball_x[i].i32[1],ball_y[i].i32[1],BALL_RADIUS);
+}
+
+/****
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+Initial and final velocity vects
+with normal and tangential components.
+All masses are ident, so they
+have been dropped from the equations.
+
+Conservation of Momentum:
+
+V1it+V2it=V1ft+V2ft
+
+V1in+V2in=V1fn+V2fn
+
+Conservation of Energy:
+
+|V1i|2+|V2i|2=|V1f|2+|V2f|2
+****/
+
+U0 AnimateTask(I64)
+{
+  CTask *task=Fs->parent_task;
+  I64 i,j,h,v,distdist,
+        dia=(2*BALL_RADIUS)<<32,
+        diadia=SqrI64(2*BALL_RADIUS)<<32,
+        delta_x,delta_y,v_t1,v_n1,v_t2,v_n2;
+  F64 dist;
+  while (TRUE) {
+    h=task->pix_width;
+    v=task->pix_height;
+    for (i=0;i<BALLS_NUM;i++) {
+      ball_x[i]+=ball_velocity_x[i];
+      ball_y[i]+=ball_velocity_y[i];
+      if (ball_x[i]<BALL_RADIUS<<32) {
+        ball_velocity_x[i]*=-1;
+        ball_x[i]=BALL_RADIUS<<32;
+      }
+      if (ball_x[i]>=(h-BALL_RADIUS)<<32) {
+        ball_velocity_x[i]*=-1;
+        ball_x[i]=(h-BALL_RADIUS)<<32;
+      }
+      if (ball_y[i]<BALL_RADIUS<<32) {
+        ball_velocity_y[i]*=-1;
+        ball_y[i]=BALL_RADIUS<<32;
+      }
+      if (ball_y[i]>=(v-BALL_RADIUS)<<32) {
+        ball_velocity_y[i]*=-1;
+        ball_y[i]=(v-BALL_RADIUS)<<32;
+      }
+    }
+    for (i=0;i<BALLS_NUM;i++) {
+      for (j=i+1;j<BALLS_NUM;j++) {
+        delta_x=ball_x[i]-ball_x[j];
+        delta_y=ball_y[i]-ball_y[j];
+
+        //We shift 16 because multiplying
+        //two 32 shifted would yield 64 shifted
+        //and we want a 32 shifted res.
+        distdist=SqrI64(delta_x>>16)+SqrI64(delta_y>>16);
+
+        //We work with square instead of sqrt
+        //to avoid unnecessarily calculating
+        //square heads (They are slow.)
+        if (distdist && distdist<=diadia) {
+          dist=Sqrt(distdist); //shifted 16 bits
+          delta_x/=dist; //shifted 16
+          delta_y/=dist;
+
+          v_t1=(ball_velocity_x[i]>>16*delta_y-
+                ball_velocity_y[i]>>16*delta_x)>>16;
+          v_n1=(ball_velocity_x[i]>>16*delta_x+
+                ball_velocity_y[i]>>16*delta_y)>>16;
+          v_t2=(ball_velocity_x[j]>>16*delta_y-
+                ball_velocity_y[j]>>16*delta_x)>>16;
+          v_n2=(ball_velocity_x[j]>>16*delta_x+
+                ball_velocity_y[j]>>16*delta_y)>>16;
+
+          if (ball_velocity_x[i]>>16*ball_velocity_x[j]>>16+
+                ball_velocity_y[i]>>16*ball_velocity_y[j]>>16<=0) {
+            ball_velocity_x[i]= v_t1*delta_y-v_n1*delta_x;
+            ball_velocity_y[i]=-v_t1*delta_x-v_n1*delta_y;
+            ball_velocity_x[j]= v_t2*delta_y-v_n2*delta_x;
+            ball_velocity_y[j]=-v_t2*delta_x-v_n2*delta_y;
+          } else {
+            ball_velocity_x[i]= v_t1*delta_y+v_n2*delta_x;
+            ball_velocity_y[i]=-v_t1*delta_x+v_n2*delta_y;
+            ball_velocity_x[j]= v_t2*delta_y+v_n1*delta_x;
+            ball_velocity_y[j]=-v_t2*delta_x+v_n1*delta_y;
+          }
+
+          //Correct for overlap
+          dist=0x10000+(dia/0x10000-dist)/2;
+          ball_x[i]+=dist*delta_x;
+          ball_y[i]+=dist*delta_y;
+          ball_x[j]-=dist*delta_x;
+          ball_y[j]-=dist*delta_y;
+        }
+      }
+    }
+    Sleep(1);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<BALLS_NUM;i++) {
+    ball_x[i]=(RandU16%(Fs->pix_width-BALL_RADIUS*2)+BALL_RADIUS)<<32;
+    ball_y[i]=(RandU16%(Fs->pix_height-BALL_RADIUS*2)+BALL_RADIUS)<<32;
+    ball_velocity_x[i]=RandI32/4;
+    ball_velocity_y[i]=RandI32/4;
+  }
+}
+
+U0 Collision()
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar;
+  SettingsPop;
+}
+
+Collision;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Digits.HC.HTML b/public/Wb/Home/Src/Demo/Games/Digits.HC.HTML new file mode 100755 index 0000000..4598bc9 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Digits.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+//This loads a lst of zero terminated
+//strings into the sym table and
+//gives a name to it.  Strings like
+//this are known as Define entries.
+
+//See ST_RAINBOW_10
+
+U0 PrintDigit(U8 ch)
+{
+//The %Z code displays a Define subentry
+  if ('0'<=ch<='9')
+    "$FG,%Z$%d$FG$",ch-'0',"ST_RAINBOW_10",ch-'0';
+}
+
+U0 PrintPattern(U8 *st)
+{
+  I64 ch;
+  while (ch=*st++)
+    PrintDigit(ch);
+  '\n';
+}
+
+U0 Digits()
+{
+  I64 num,ch,i;
+  U8 answer[1024];
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=DKGRAY<<4+WHITE;
+  DocClear;
+//Set default background and foreground
+  "$WW,1$$BG,DKGRAY$$FD,WHITE$"
+        "\nThis is a memory game.  "
+        "Try to remember the digits and enter them.  "
+        "They are colored based on electrical "
+        "engineering color codes.\n";
+  for (i=0;i<10;i++)
+    "$FG,%Z$%d: %Z\n",i,"ST_RAINBOW_10",i,i,"ST_RAINBOW_10";
+  "$FG$\n"; //set to default background
+  ch=PressAKey;
+  if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
+  while (TRUE) {
+restart:
+    num=0;
+//Set to zeros so we have terminators
+    MemSet(answer,0,sizeof(answer));
+    while (TRUE) {
+      DocClear;
+      "$WW,1$$BG,DKGRAY$$FD,WHITE$\n";
+      "Pattern\nLength:%d\n\n",num+1;
+      answer[num++]=RandU32%10+'0';
+      PrintPattern(answer);
+      ch=PressAKey;
+      if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
+      DocClear;
+      "$WW,1$$BG,DKGRAY$$FD,WHITE$\n";
+      "Guess\nLength:%d\n\n",num;
+      for (i=0;i<num;i++) {
+        ch=GetChar(,FALSE);
+        if (ch==CH_ESC||ch==CH_SHIFT_ESC) goto dg_done;
+        PrintDigit(ch);
+        if (ch!=answer[i]) {
+          "\nScore:%d\n",num;
+          PrintPattern(answer);
+          Beep; Beep;
+          ch=PressAKey;
+          if (ch==CH_ESC||ch==CH_SHIFT_ESC)
+            goto dg_done;
+          else
+            goto restart;
+        }
+      }
+    }
+  }
+dg_done:
+  DocClear;
+  SettingsPop;
+}
+
+Digits;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/DunGen.HC.HTML b/public/Wb/Home/Src/Demo/Games/DunGen.HC.HTML new file mode 100755 index 0000000..be7ec76 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/DunGen.HC.HTML @@ -0,0 +1,478 @@ + + + + + + + + + + + +
+RegDft("TempleOS/DunGen","F64 best_score=9999;\n");
+RegExe("TempleOS/DunGen");
+
+//Set snap to 4 and width to 4
+//if you edit this map.
+
+//Don't forget to change the
+//starting pos.
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+ 
+<4>/* Graphics Not Rendered in HTML */
+
+<5>/* Graphics Not Rendered in HTML */
+
+<6>/* Graphics Not Rendered in HTML */
+
+<7>/* Graphics Not Rendered in HTML */
+
+<8>/* Graphics Not Rendered in HTML */
+
+<9>/* Graphics Not Rendered in HTML */
+
+<10>/* Graphics Not Rendered in HTML */
+
+
+//These are indexed by color #.
+//See COLORS.
+
+U8 *tiles1[16]={NULL,<7> ,<5> ,NULL,NULL,NULL,NULL,NULL,
+  <6> ,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+
+U8 *tiles2[16]={NULL,<8> ,<5> ,NULL,NULL,NULL,NULL,NULL,
+  <6> ,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+
+#define SCRN_SCALE      24
+#define SCRN_WIDTH      24
+#define SCRN_HEIGHT     24
+I64 scrn_x,scrn_y;
+
+#define MAP_SCALE       4
+I64 map_width,map_height;
+U8 *map=NULL;
+
+I64 man_x,man_y,man_dx,man_dy;
+Bool man_attack;
+F64 man_attack_t0;
+
+#define MONSTERS_NUM    10
+I64 monsters_left;
+class Monster
+{
+  I64 x,y,dx,dy;
+  Bool dead,pad[7];
+} monsters[MONSTERS_NUM];
+
+F64 t0,tf;
+
+#define LOS_SCALE       4
+
+Bool LOSPlot(U8 *,I64 x,I64 y,I64)
+{
+  if (!map[(y/LOS_SCALE)*map_width+(x/LOS_SCALE)])
+    return FALSE;
+  else
+    return TRUE;
+}
+
+Bool LOS(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Line of sight
+  return Line(NULL,x1*LOS_SCALE+LOS_SCALE/2,y1*LOS_SCALE+LOS_SCALE/2,0,
+        x2*LOS_SCALE+LOS_SCALE/2,y2*LOS_SCALE+LOS_SCALE/2,0,&LOSPlot);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CDC *dc_t=DCAlias(gr.dc2,task);
+  I64 i,x,y,xx,yy,x1,y1,z1,color,
+        cx=task->pix_width/2,
+        cy=task->pix_height/2;
+  CD3I32 poly[4];
+  U8 **_tiles;
+  F64 tt;
+  Monster *tmpm;
+
+  if (Blink(5))
+    _tiles=tiles1;
+  else
+    _tiles=tiles2;
+
+  Mat4x4RotX(dc_t->r,60*2*pi/360);
+  Mat4x4RotZ(dc_t->r,15*2*pi/360);
+  DCMat4x4Set(dc_t,dc_t->r);
+  dc_t->x=task->pix_width/2;
+  dc_t->y=task->pix_height/2;
+  dc_t->flags|=DCF_TRANSFORMATION;
+
+  //You could make it much more efficient
+  //if you did it like ::/Demo/Games/BigGuns.HC
+  //with a CDC.
+
+  for (y=-SCRN_HEIGHT/2;y<SCRN_HEIGHT/2;y++) {
+    yy=y+scrn_y;
+    if (0<=yy<map_height)
+      for (x=-SCRN_WIDTH/2;x<SCRN_WIDTH/2;x++) {
+        xx=x+scrn_x;
+        if (0<=xx<map_width) {
+          if ((color=map[yy*map_width+xx]) &&
+                LOS(xx,yy,man_x,man_y)) {
+            if (_tiles[color]) {
+              x1=x*SCRN_SCALE;
+              y1=y*SCRN_SCALE;
+              z1=0;
+              DCTransform(dc_t,&x1,&y1,&z1);
+              Sprite3(dc,x1,y1,z1,_tiles[color]);
+            } else {//If no tile defined, do solid color.
+              poly[0].x=x*SCRN_SCALE;
+              poly[0].y=y*SCRN_SCALE;
+              poly[0].z=0;
+              poly[1].x=(x+1)*SCRN_SCALE-1;
+              poly[1].y=y*SCRN_SCALE;
+              poly[1].z=0;
+              poly[2].x=(x+1)*SCRN_SCALE;
+              poly[2].y=(y+1)*SCRN_SCALE-1;
+              poly[2].z=0;
+              poly[3].x=x*SCRN_SCALE-1;
+              poly[3].y=(y+1)*SCRN_SCALE-1;
+              poly[3].z=0;
+              dc_t->color=color;
+              GrFillPoly3(dc_t,4,poly);
+            }
+          }
+        }
+      }
+  }
+
+  for (y=-SCRN_HEIGHT/2;y<SCRN_HEIGHT/2;y++) {
+    yy=y+scrn_y;
+    if (0<=yy<map_height)
+      for (x=-SCRN_WIDTH/2;x<SCRN_WIDTH/2;x++) {
+        xx=x+scrn_x;
+        if (0<=xx<map_width) {
+          if (!map[yy*map_width+xx]) {
+            if (yy+1<map_height && LOS(xx,yy+1,man_x,man_y)) {
+              x1=x*SCRN_SCALE;
+              y1=y*SCRN_SCALE;
+              z1=0;
+              DCTransform(dc_t,&x1,&y1,&z1);
+              Sprite3(dc,x1,y1,z1,<9>);
+            }
+            if (xx+1<map_width && LOS(xx+1,yy,man_x,man_y)) {
+              x1=x*SCRN_SCALE;
+              y1=y*SCRN_SCALE;
+              z1=0;
+              DCTransform(dc_t,&x1,&y1,&z1);
+              Sprite3(dc,x1,y1,z1,<10>);
+            }
+          }
+        }
+      }
+  }
+
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+    if (!tmpm->dead && LOS(tmpm->x,tmpm->y,man_x,man_y)) {
+      x1=(tmpm->x-scrn_x)*SCRN_SCALE+SCRN_SCALE/2;
+      y1=(tmpm->y-scrn_y)*SCRN_SCALE+SCRN_SCALE/2;
+      z1=0;
+      DCTransform(dc_t,&x1,&y1,&z1);
+      if (tmpm->dx<0) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,x1,y1,x1,y1+1);
+      } else
+        dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+      Sprite3(dc,x1,y1,z1,<4>);
+    }
+
+  x1=(man_x-scrn_x)*SCRN_SCALE+SCRN_SCALE/2;
+  y1=(man_y-scrn_y)*SCRN_SCALE+SCRN_SCALE/2;
+  z1=0;
+  if (tS-man_attack_t0<0.2) {
+    x1+=Tri(tS-man_attack_t0,0.2)*SCRN_SCALE*man_dx;
+    y1+=Tri(tS-man_attack_t0,0.2)*SCRN_SCALE*man_dy;
+    if (man_dy!=1)
+      y1-=Saw(tS-man_attack_t0,0.2)*SCRN_SCALE;
+  }
+  DCTransform(dc_t,&x1,&y1,&z1);
+  if (man_dx<0) {
+    dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+    DCSymmetrySet(dc,x1,y1,x1,y1+1);
+  } else
+    dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+
+  if (tS-man_attack_t0<0.2)
+    Sprite3(dc,x1,y1,z1,<3>);
+  else
+    Sprite3(dc,x1,y1,z1,<2>);
+
+  DCDel(dc_t);
+
+  if (tf) {
+    dc->color=LTRED;
+    if (Blink)
+      GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed");
+    tt=tf;
+  } else {
+    dc->color=LTGREEN;
+    tt=tS;
+  }
+  GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",
+        monsters_left,tt-t0,best_score);
+}
+
+U0 Attack()
+{
+  I64 i;
+  Monster *tmpm;
+
+  man_attack_t0=tS;
+  Noise(100,53,74);
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    if (!tmpm->dead &&
+          man_x+man_dx==tmpm->x && man_y+man_dy==tmpm->y) {
+      tmpm->dead=TRUE;
+      if (!--monsters_left) {
+        tf=tS;
+        if (tf-t0<best_score)
+          best_score=tf-t0;
+      }
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,x,y;
+  CDC *dc;
+  Monster *tmpm;
+
+  dc=Sprite2DC(<1>);
+  map_width =dc->width/MAP_SCALE;
+  map_height=dc->height/MAP_SCALE;
+  Free(map);
+  map=MAlloc(map_width*map_height*sizeof(U8));
+  for (y=0;y<map_height;y++)
+    for (x=0;x<map_width;x++)
+      map[y*map_width+x]=GrPeek(dc,x*MAP_SCALE,y*MAP_SCALE);
+  DCDel(dc);
+
+  man_attack_t0=0;
+  man_attack=FALSE;
+  man_x=0;
+  man_y=4;
+  man_dx=0;
+  man_dy=0;
+  scrn_x=0;
+  scrn_y=0;
+  for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++) {
+    tmpm->dead=FALSE;
+    tmpm->dx=0;
+    tmpm->dy=0;
+    do {
+      tmpm->x=RandU64%(map_width-2)+1;
+      tmpm->y=RandU64%(map_height-2)+1;
+    } while (!map[(tmpm->y)*map_width+tmpm->x]);
+  }
+  monsters_left=MONSTERS_NUM;
+  tf=0;
+  t0=tS;
+}
+
+U0 CleanUp()
+{
+  Free(map);
+  map=NULL;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i,x,y,dx,dy;
+  Monster *tmpm;
+
+  while (TRUE) {
+    for (i=0,tmpm=monsters;i<MONSTERS_NUM;i++,tmpm++)
+      if (!tmpm->dead) {
+        dx=RandU16%3-1;
+        dy=RandU16%3-1;
+        x=tmpm->x+dx;
+        y=tmpm->y+dy;
+        if (0<=x<map_width && 0<=y<map_height && map[y*map_width+x]) {
+          tmpm->x=x;
+          tmpm->y=y;
+          tmpm->dx=dx;
+          tmpm->dy=dy;
+        }
+      }
+    Sleep(1000);
+  }
+}
+
+U0 DunGen()
+{
+  I64 ch,sc;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Attack(,CH_SPACE);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      switch (GetMsg(&ch,&sc,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          switch (ch) {
+            case '\n':
+              Init;
+              break;
+            case CH_SPACE:
+              man_attack=TRUE;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto dg_done;
+            case 0:
+              switch (sc.u8[0]) {
+                case SC_CURSOR_RIGHT:
+                  if (man_attack) {
+                    man_dx=1;
+                    man_dy=0;
+                    Attack;
+                  } else
+                    if (man_x+1<map_width &&
+                          map[man_y*map_width+(man_x+1)]==DKGRAY) {
+                      man_x++;
+                      if (man_x-scrn_x>SCRN_WIDTH/2-3) {
+                        scrn_x+=SCRN_WIDTH/2;
+                        if (scrn_x+SCRN_WIDTH/2>map_width)
+                          scrn_x=map_width-SCRN_WIDTH/2;
+                      }
+                    }
+                  break;
+                case SC_CURSOR_LEFT:
+                  if (man_attack) {
+                    man_dx=-1;
+                    man_dy=0;
+                    Attack;
+                  } else
+                    if (man_x-1>=0 &&
+                          map[man_y*map_width+(man_x-1)]==DKGRAY) {
+                      man_x--;
+                      if (man_x-scrn_x<-SCRN_WIDTH/2+3) {
+                        scrn_x-=SCRN_WIDTH/2;
+                        if (scrn_x-SCRN_WIDTH/2<0)
+                          scrn_x=SCRN_WIDTH/2;
+                      }
+                    }
+                  break;
+                case SC_CURSOR_UP:
+                  if (man_attack) {
+                    man_dx=0;
+                    man_dy=-1;
+                    Attack;
+                  } else
+                    if (man_y-1>=0 &&
+                          map[(man_y-1)*map_width+man_x]==DKGRAY) {
+                      man_y--;
+                      if (man_y-scrn_y<-SCRN_HEIGHT/2+3) {
+                        scrn_y-=SCRN_HEIGHT/2;
+                        if (scrn_y-SCRN_HEIGHT/2<0)
+                          scrn_y=SCRN_HEIGHT/2;
+                      }
+                    }
+                  break;
+                case SC_CURSOR_DOWN:
+                  if (man_attack) {
+                    man_dx=0;
+                    man_dy=1;
+                    Attack;
+                  } else
+                    if (man_y+1<map_height &&
+                          map[(man_y+1)*map_width+man_x]==DKGRAY) {
+                      man_y++;
+                      if (man_y-scrn_y>SCRN_HEIGHT/2-3) {
+                        scrn_y+=SCRN_HEIGHT/2;
+                        if (scrn_y+SCRN_HEIGHT/2>map_height)
+                          scrn_y=map_height-SCRN_HEIGHT/2;
+                      }
+                    }
+                  break;
+              }
+          }
+          break;
+        case MSG_KEY_UP:
+          if (ch==CH_SPACE)
+            man_attack=FALSE;
+          break;
+      }
+    }
+dg_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/DunGen","F64 best_score=%5.4f;\n",best_score);
+}
+
+DunGen;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/ElephantWalk.HC.HTML b/public/Wb/Home/Src/Demo/Games/ElephantWalk.HC.HTML new file mode 100755 index 0000000..10d97c7 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/ElephantWalk.HC.HTML @@ -0,0 +1,117 @@ + + + + + + + + + + + +
+//Press <CTRL-t>.
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                /* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//The sprite was created with <CTRL-r>.
+
+U0 ElephantWalk()
+{
+  I64 sc,
+        x=Fs->pix_width>>1,y=Fs->pix_height>>1, //Fs is current CTask struct.
+        x_last=x;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  while (TRUE) {
+    DCFill;
+    if (x>x_last) {
+      DCSymmetrySet(,x,y,x,y-1);
+      gr.dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+    } else
+      gr.dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    x_last=x;
+    Sprite3ZB(gr.dc,x,y,0,<1>,Sin(8*tS)/4);//Use <CTRL-r> "Ptr to Sprite"
+    switch (GetKey(&sc)) {
+      case 0:
+        switch (sc.u8[0]) {//Scan code lowest byte
+          case SC_CURSOR_UP:
+            y-=32;
+            if (y<0)
+              y=Fs->pix_height;
+            break;
+          case SC_CURSOR_DOWN:
+            y+=32;
+            if (y>Fs->pix_height)
+              y=0;
+            break;
+          case SC_CURSOR_LEFT:
+            x-=32;
+            if (x<0)
+              x=Fs->pix_width;
+            break;
+          case SC_CURSOR_RIGHT:
+            x+=32;
+            if (x>Fs->pix_width)
+              x=0;
+            break;
+        }
+        break;
+      case CH_ESC:
+      case CH_SHIFT_ESC:
+        goto ew_done;
+    }
+  }
+ew_done:
+  DCFill;
+}
+
+ElephantWalk;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/FlapBat.HC.HTML b/public/Wb/Home/Src/Demo/Games/FlapBat.HC.HTML new file mode 100755 index 0000000..11e14ea --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/FlapBat.HC.HTML @@ -0,0 +1,305 @@ + + + + + + + + + + + +
+RegDft("TempleOS/FlapBat","F64 best_score=9999;\n");
+RegExe("TempleOS/FlapBat");
+
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+#define BORDER          6
+#define EAT_TIME        0.5
+#define FLAP_TIME       0.5
+#define BAT_BOX 10
+
+Bool flap_down,flap_up;
+F64 flap_phase,delta_phase,bat_y,bat_x,eat_timeout,flap_time;
+F64 frame_x,game_t0,game_tf;
+
+#define BUGS_NUM        32
+I32 bug_cnt,bugs_x[BUGS_NUM],bugs_y[BUGS_NUM];
+Bool bugs_dead[BUGS_NUM];
+
+#define GLOW_PERIOD     3.0
+F64 bugs_glow_phase[BUGS_NUM];
+
+CDC *limit_flood_fill_dc; //Prevent uncontrolled flood-fill flicker.
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,y,x,
+        h=MaxI64(1,task->pix_width-2*BORDER),
+        v=MaxI64(1,task->pix_height-2*BORDER);
+  U8 *tmps,*tmps2,*tmps3;
+  F64 tt=flap_phase*flap_phase*flap_phase,ts=tS;
+
+  bat_x=task->pix_width>>3;
+  Sprite3(dc,(7*task->pix_width)>>3,20,0,<5>);
+
+  dc->color=DKGRAY;
+  GrCircle(dc,bat_x+5+20*Saw(15*tS,2),bat_y,10+20*Saw(15*tS,2),5,-pi/4,pi/2);
+
+  tmps=SpriteInterpolate(tt,<1>,<2>);
+  if (eat_timeout && tS<eat_timeout) {
+    tmps2=SpriteInterpolate(tt,<3>,<4>);
+    tmps3=SpriteInterpolate(1.0-(eat_timeout-tS)/EAT_TIME,tmps2,tmps);
+    Free(tmps);
+    Free(tmps2);
+    tmps=tmps3;
+  }
+
+  DCFill(limit_flood_fill_dc);
+  Sprite3(limit_flood_fill_dc,16,32,0,tmps);
+  if (GrPeek(limit_flood_fill_dc,0,0)!=TRANSPARENT) {//Did FloodFill go crazy?
+    limit_flood_fill_dc->color=TRANSPARENT;
+    GrFloodFill(limit_flood_fill_dc,0,0);
+  }
+  GrBlot(dc,bat_x-16,bat_y-32,limit_flood_fill_dc);
+
+  Free(tmps);
+  for (i=0;i<BUGS_NUM;i++)
+    if (!bugs_dead[i]) {
+      x=(bugs_x[i]+frame_x)%h+BORDER;
+      y=bugs_y[i]%v+BORDER;
+      if (Saw(ts+bugs_glow_phase[i],GLOW_PERIOD)<0.2) {
+        if (i&1)
+          dc->color=YELLOW;
+        else
+          dc->color=LTGREEN;
+      } else
+        dc->color=BLACK;
+      GrPlot(dc,x,y);
+      GrPlot(dc,x+1,y);
+      dc->color=BLACK;
+      GrPlot(dc,x,y-1);
+    }
+  if (game_tf) {
+    dc->color=RED;
+    GrPrint(dc,(task->pix_width-FONT_WIDTH*14)/2,
+          (task->pix_height-FONT_HEIGHT)/2,"Game Completed");
+    tt=game_tf;
+  } else {
+    dc->color=BLACK;
+    tt=tS;
+  }
+  GrPrint(dc,0,0,"Bugs:%3.1f%% Time:%3.2f Best:%3.2f",
+        100.0*(BUGS_NUM-bug_cnt)/BUGS_NUM,tt-game_t0,best_score);
+}
+
+U0 CheckBugs(CTask *task)
+{
+  I64 i,x,y,
+        h=MaxI64(1,task->pix_width-2*BORDER),
+        v=MaxI64(1,task->pix_height-2*BORDER);
+  if (eat_timeout && eat_timeout-tS<0.75*EAT_TIME) {
+    Suspend(task->song_task,FALSE);
+    if (tS>=eat_timeout)
+      eat_timeout=0;
+  }
+  for (i=0;i<BUGS_NUM;i++)
+    if (!bugs_dead[i]) {
+      x=(bugs_x[i]+frame_x)%h+BORDER;
+      y=bugs_y[i]%v+BORDER;
+      if (AbsI64(x-bat_x)<BAT_BOX && AbsI64(y-bat_y)<BAT_BOX) {
+        bugs_dead[i]=TRUE;
+        eat_timeout=tS+EAT_TIME;
+        Snd(74);
+        Suspend(task->song_task);
+        bug_cnt--;
+      }
+    }
+  if (!game_tf && !bug_cnt) {
+    game_tf=tS;
+    Suspend(task->song_task);
+    Snd;
+    if (game_tf-game_t0<best_score)
+      best_score=game_tf-game_t0;
+  }
+  frame_x-=0.1;
+  if (frame_x<0)
+    frame_x+=h;
+}
+
+U0 Init()
+{
+  I64 i;
+  limit_flood_fill_dc=DCNew(32,40);
+  flap_down=flap_up=FALSE;
+  flap_phase=0;
+  bat_x=Fs->pix_width>>3;
+  bat_y=0;
+  frame_x=0;
+  bug_cnt=BUGS_NUM;
+  for (i=0;i<BUGS_NUM;i++) {
+    bugs_dead[i]=FALSE;
+    bugs_x[i]=RandU16;
+    bugs_y[i]=RandU16;
+    bugs_glow_phase[i]=GLOW_PERIOD*Rand;
+  }
+  Suspend(Fs->song_task,FALSE);
+  flap_time=eat_timeout=0;
+  delta_phase=game_tf=0;
+  game_t0=tS;
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("4eB5E4B5C4B5EsEFqE4eB5E4B5C4B5EsEF");
+    Play("5qE4eA5D4ABA5DsDCqD4eB5E4B5C4B");
+    Play("5EsEDqE");
+  }
+}
+
+U0 AnimateTask(I64)
+{
+  while (TRUE) {
+    if (flap_down) {
+      flap_down=FALSE;
+      delta_phase=-0.005*Min(1.0,(tS-flap_time)/FLAP_TIME);
+      flap_time=tS;
+    } else if (flap_up) {
+      flap_up=FALSE;
+      delta_phase= 0.005;
+    }
+    if (delta_phase<0) {
+      bat_y+=75*delta_phase;
+      delta_phase+=0.000015;
+    } else
+      bat_y+=0.15;
+    bat_y=Clamp(bat_y,BORDER,Fs->parent_task->pix_height-BORDER);
+    flap_phase=Clamp(flap_phase+delta_phase,0.0,1.0);
+    CheckBugs(Fs->parent_task);
+    Sleep(1);
+  }
+}
+
+U0 CleanUp()
+{
+  DCDel(limit_flood_fill_dc);
+}
+
+U0 FlapBat()
+{
+  Bool rst_space=TRUE;
+  I64 arg1,arg2;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Flap(,CH_SPACE);"
+        "}"
+        );
+
+  PopUpOk("Use $GREEN$<SPACE>$FG$ to flap.\nHold down to glide.");
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=LTGRAY<<4+WHITE;
+  WinBorder(ON);
+  WinHorz(1,TEXT_COLS/2);
+  WinVert(2,TEXT_ROWS/2);
+  DocCursor;
+  DocClear;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case CH_SPACE:
+              if (rst_space) {
+                flap_down=TRUE;
+                rst_space=FALSE;
+              }
+              break;
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto bl_done;
+          }
+          break;
+        case MSG_KEY_UP:
+          switch (arg1) {
+            case CH_SPACE:
+              flap_up=TRUE;
+              rst_space=TRUE;
+              break;
+          }
+          break;
+      }
+    }
+bl_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/FlapBat","F64 best_score=%5.4f;\n",best_score);
+}
+
+FlapBat;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/FlatTops.HC.HTML b/public/Wb/Home/Src/Demo/Games/FlatTops.HC.HTML new file mode 100755 index 0000000..3114c17 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/FlatTops.HC.HTML @@ -0,0 +1,919 @@ + + + + + + + + + + + +
+#define GAME_SPEED_SCALE        0.1
+
+F64 game_speed,
+    launch_unit_x1,launch_unit_y1,launch_unit_x2,launch_unit_y2,launch_t,
+    return_unit_x1,return_unit_y1,return_unit_x2,return_unit_y2,return_t,
+    set_theta_unit_x1,set_theta_unit_y1,set_theta_unit_x2,set_theta_unit_y2,set_theta_t,
+    next_noise;
+CTask *main_task;
+
+#define OT_CARRIER      0
+#define OT_CRUISER      1
+#define OT_FIGHTER      2
+#define OT_TYPES_NUM    3
+
+#define OF_SHIP         1
+#define OF_ACTIVE       2
+#define OF_RETURNING    4
+#define OF_SHOOTING     8
+
+#define FIRE_WIDTH      56
+#define FIRE_HEIGHT     16
+#define FIRE_X_SCALE    0.5
+#define FIRE_Y_SCALE    0.5
+
+#define FIRE_COLORS     16
+U8 fire_colors[FIRE_COLORS]={
+YELLOW,YELLOW,LTRED,YELLOW, BLACK,YELLOW,RED,YELLOW,
+YELLOW,BLACK,YELLOW,LTRED, RED,YELLOW,DKGRAY,YELLOW};
+
+class Obj
+{
+  Obj *next,*last;
+  Obj *next_in_squadron,*last_in_squadron;
+  Obj *host;
+  U8  player,type;
+  U16 flags;
+  I16 squadron,member_num;
+  F64 x,y,theta,dtheta,
+        speed,turn_rate,
+        life_percent,
+        target_x,target_y,
+        ship_guns,ship_guns_range,
+        air_guns,air_guns_range,
+        fuel,max_fuel,fuel_burn_rate,
+        death_time,next_action_time;
+  I32 torpedos,max_torpedos;
+  F64 torpedos_range;
+  U8  fire[(FIRE_WIDTH*FIRE_HEIGHT+7)/8];
+} obj_head;
+
+class Torpedo
+{
+  Torpedo *next,*last;
+  Obj *target;
+  F64 x,y,theta,speed,timeout;
+} torpedo_head;
+
+#define SA_PARKED       0
+#define SA_LAUNCHING    1
+#define SA_FLYING       2
+#define SA_SET_theta    3
+#define SA_RETURNING    4
+#define SA_DEAD         5
+
+class Squadron : Obj
+{
+  I64 action,dead_mask,total_mask;
+} *squadrons;
+
+U0 SquadronIns(Obj *o,Obj *pred)
+{
+  Obj *succ=pred->next_in_squadron;
+  o->next_in_squadron=succ;
+  o->last_in_squadron=pred;
+  pred->next_in_squadron=o;
+  succ->last_in_squadron=o;
+}
+
+U0 SquadronRem(Obj *o)
+{
+  Obj *pred=o->last_in_squadron,*succ=o->next_in_squadron;
+  pred->next_in_squadron=succ;
+  succ->last_in_squadron=pred;
+}
+
+#define PLAYERS_NUM     2
+
+I64 num_carriers[PLAYERS_NUM]={2,3},
+    num_cruisers[PLAYERS_NUM]={2,3},
+    num_planes_per_squadron[PLAYERS_NUM]={6,5},
+    num_squadrons_per_carrier[PLAYERS_NUM]={2,3},
+    num_alive[PLAYERS_NUM],
+    num_squadrons;
+
+Obj *ObjFind(F64 x,F64 y,
+             I64 flag_mask=OF_ACTIVE|OF_RETURNING,I64 flag_val=OF_ACTIVE,
+             I64 type_mask=-1,I64 player_mask=-1,F64 *_d=NULL)
+{
+  Obj *tmpo=obj_head.next,*best=NULL;
+  F64 dd,best_dd=F64_MAX;
+  while (tmpo!=&obj_head) {
+    if (tmpo->flags&flag_mask==flag_val &&
+          Bt(&type_mask,tmpo->type)&&Bt(&player_mask,tmpo->player)) {
+      dd=Sqr(tmpo->x-x)+Sqr(tmpo->y-y);
+      if (dd<best_dd) {
+        best=tmpo;
+        best_dd=dd;
+      }
+    }
+    tmpo=tmpo->next;
+  }
+  if (_d) *_d=Sqrt(best_dd);
+  return best;
+}
+
+U0 ObjDel(Obj *tmpo)
+{
+  if (tmpo) {
+    if (tS<tmpo->death_time)
+      tmpo->flags&=~OF_ACTIVE;
+    else {
+      if (tmpo->squadron>=0)
+        SquadronRem(tmpo);
+      QueRem(tmpo);
+      if (tmpo->squadron>=0)
+        LBts(&squadrons[tmpo->squadron].dead_mask,tmpo->member_num);
+      num_alive[tmpo->player]--;
+      Free(tmpo);
+    }
+  }
+}
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+<6>/* Graphics Not Rendered in HTML */
+
+U8 *imgs[PLAYERS_NUM][OT_TYPES_NUM]={{<1>,<2>,<3>},{<4>,<5>,<6>}};
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,k;
+  F64 d,cur_time=tS;
+  Obj *tmpo;
+  Torpedo *tmpt;
+
+  tmpt=torpedo_head.next;
+  while (tmpt!=&torpedo_head) {
+    dc->color=WHITE;
+    GrPlot(dc,tmpt->x,tmpt->y);
+    tmpt=tmpt->next;
+  }
+
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->flags&OF_ACTIVE && tmpo->flags&OF_SHIP) {
+      Sprite3ZB(dc,tmpo->x,tmpo->y,0,
+            imgs[tmpo->player][tmpo->type],tmpo->theta+pi/2);
+
+      k=0;
+      for (j=0;j<FIRE_HEIGHT;j++)
+        for (i=0;i<FIRE_WIDTH;i++)
+          if (Bt(tmpo->fire,k++)) {
+            dc->color=fire_colors[ToI64(k+10*tS)&(FIRE_COLORS-1)];
+            GrPlot(dc,
+                  tmpo->x+FIRE_X_SCALE*(i-FIRE_WIDTH /2+(11*tS+i)%1.7)
+            *Cos(tmpo->theta)-
+                  FIRE_Y_SCALE*(j-FIRE_HEIGHT/2+(12*tS+j)%1.7)*Sin(tmpo->theta),
+                  tmpo->y+FIRE_Y_SCALE*(j-FIRE_HEIGHT/2+(19*tS+j)%1.7)
+            *Cos(tmpo->theta)+
+                  FIRE_X_SCALE*(i-FIRE_WIDTH /2+(13*tS+i)%1.7)*Sin(tmpo->theta));
+          }
+      if (Blink) {
+        dc->color=BLACK;
+        GrLine(dc,tmpo->x+5,tmpo->y,tmpo->x+5+10,tmpo->y);
+
+        if (tmpo->life_percent>0) {
+          if (tmpo->life_percent<33)
+            dc->color=RED;
+          else if (tmpo->life_percent<66)
+            dc->color=YELLOW;
+          else
+            dc->color=GREEN;
+          GrLine(dc,tmpo->x+5,tmpo->y,
+                tmpo->x+5+10*tmpo->life_percent/100,tmpo->y);
+        }
+
+        dc->color=BLACK;
+        GrLine(dc,tmpo->x+5,tmpo->y+2,tmpo->x+5+10,tmpo->y+2);
+        d=tmpo->fuel*100/tmpo->max_fuel;
+        if (d>0) {
+          if (d<33)
+            dc->color=RED;
+          else if (d<66)
+            dc->color=YELLOW;
+          else
+            dc->color=GREEN;
+          GrLine(dc,tmpo->x+5,tmpo->y+2,tmpo->x+5+10*d/100,tmpo->y+2);
+        }
+      }
+    }
+    tmpo=tmpo->next;
+  }
+
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->flags&OF_ACTIVE && !(tmpo->flags&OF_SHIP))
+      Sprite3ZB(dc,tmpo->x,tmpo->y,0,
+            imgs[tmpo->player][tmpo->type],tmpo->theta+pi/2);
+    if (tmpo->flags&OF_SHOOTING) {
+      dc->color=LTRED;
+      GrLine(dc,tmpo->x,tmpo->y,tmpo->target_x,tmpo->target_y,3);
+    }
+    tmpo=tmpo->next;
+  }
+
+  dc->flags|=DCF_TRANSFORMATION;
+  if (cur_time<launch_t) {
+    dc->color=LTGREEN;
+    GrArrow3(dc,launch_unit_x1,launch_unit_y1,0,
+          launch_unit_x2,launch_unit_y2,0);
+  }
+  if (cur_time<return_t) {
+    dc->color=LTRED;
+    GrArrow3(dc,return_unit_x1,return_unit_y1,0,
+          return_unit_x2,return_unit_y2,0);
+  }
+  if (cur_time<set_theta_t) {
+    dc->color=YELLOW;
+    GrArrow3(dc,set_theta_unit_x1,set_theta_unit_y1,0,
+          set_theta_unit_x2,set_theta_unit_y2,0);
+  }
+
+  dc->color=YELLOW;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y,
+        "Game Speed: %5.2f",game_speed);
+  dc->color=LTCYAN;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y+FONT_HEIGHT,
+        "Player 1: %d",num_alive[0]);
+  dc->color=LTPURPLE;
+  GrPrint(dc,-task->scroll_x,-task->scroll_y+2*FONT_HEIGHT,
+        "Player 2: %d",num_alive[1]);
+
+  if ((!num_alive[0]||!num_alive[1]) && Blink) {
+    if (!num_alive[1]) {
+      dc->color=LTGREEN;
+      GrPrint(dc,task->pix_width>>1 -(FONT_WIDTH*14)/2-task->scroll_x,
+            task->pix_height>>1-FONT_HEIGHT/2-task->scroll_y,"Game Completed");
+    } else {
+      dc->color=LTRED;
+      GrPrint(dc,task->pix_width>>1 -(FONT_WIDTH*9)/2-task->scroll_x,
+            task->pix_height>>1-FONT_HEIGHT/2-task->scroll_y,"Game Over");
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i,fighter,ship,player,squadron,
+        w=Fs->pix_width,h=Fs->pix_height;
+  Squadron *tmps;
+  Obj *tmpo,*tmpo1;
+  QueInit(&obj_head);
+  QueInit(&torpedo_head);
+
+  next_noise=tS;
+  Fs->scroll_x=0;
+  Fs->scroll_y=0;
+  game_speed=1.0;
+  launch_t=return_t=set_theta_t=0;
+  main_task=Fs;
+  num_squadrons=0;
+  for (player=0;player<PLAYERS_NUM;player++) {
+    num_alive[player]=0;
+    for (ship=0;ship<num_cruisers[player];ship++) {
+      tmpo1=CAlloc(sizeof(Obj));
+      num_alive[player]++;
+      tmpo1->type=OT_CRUISER;   tmpo1->player=player;
+      tmpo1->squadron=-1;       tmpo1->member_num=ship;
+      tmpo1->flags=OF_ACTIVE|OF_SHIP;
+      tmpo1->x=0.8*w*(Rand-0.5)+w>>1; tmpo1->y=0.8*h*(Rand-0.5)+h>>1;
+      tmpo1->host=NULL;
+      tmpo1->speed=35.0;        tmpo1->turn_rate=2.5;
+      tmpo1->theta=2*pi*(Rand-0.5);     tmpo1->dtheta=0;
+      tmpo1->life_percent=100.0;
+      tmpo1->fuel=tmpo1->max_fuel=100000;
+      tmpo1->fuel_burn_rate=100.0;
+      tmpo1->air_guns =5000;    tmpo1->air_guns_range =30.0;
+      tmpo1->ship_guns=10000;   tmpo1->ship_guns_range=30.0;
+      tmpo1->torpedos =tmpo1->max_torpedos=0;
+      tmpo1->torpedos_range =0.0;
+      tmpo1->next_action_time=0;
+      QueIns(tmpo1,obj_head.last);
+    }
+
+    for (ship=0;ship<num_carriers[player];ship++) {
+      tmpo1=CAlloc(sizeof(Obj));
+      num_alive[player]++;
+      tmpo1->type=OT_CARRIER;   tmpo1->player=player;
+      tmpo1->squadron=-1;       tmpo1->member_num=ship;
+      tmpo1->flags=OF_ACTIVE|OF_SHIP;
+      tmpo1->x=0.8*w*(Rand-0.5)+w>>1; tmpo1->y=0.8*h*(Rand-0.5)+h>>1;
+      tmpo1->host=NULL;
+      tmpo1->speed=28.0;        tmpo1->turn_rate=1.0;
+      tmpo1->theta=2*pi*(Rand-0.5);     tmpo1->dtheta=0;
+      tmpo1->life_percent=100.0;
+      tmpo1->fuel=tmpo1->max_fuel=750000;
+      tmpo1->fuel_burn_rate=500.0;
+      tmpo1->air_guns =5000;    tmpo1->air_guns_range =20.0;
+      tmpo1->ship_guns=2000;    tmpo1->ship_guns_range=30.0;
+      tmpo1->torpedos =tmpo1->max_torpedos=0;
+      tmpo1->torpedos_range =0.0;
+      tmpo1->next_action_time=0;
+      QueIns(tmpo1,obj_head.last);
+
+      for (squadron=0;squadron<num_squadrons_per_carrier[player];
+            squadron++,num_squadrons++) {
+        for (fighter=0;fighter<num_planes_per_squadron[player];fighter++) {
+          tmpo=CAlloc(sizeof(Obj));
+          num_alive[player]++;
+          tmpo->type=OT_FIGHTER;         tmpo->player=player;
+          tmpo->squadron=num_squadrons; tmpo->member_num=fighter;
+          tmpo->flags=0;
+          tmpo->host=tmpo1;
+          tmpo->speed=300.0;            tmpo->turn_rate=25.0;
+          tmpo->life_percent=100.0;
+          tmpo->fuel=tmpo->max_fuel=1000;
+          tmpo->fuel_burn_rate=1.0;
+          tmpo->air_guns =35000;        tmpo->air_guns_range =8.0;
+          tmpo->ship_guns=0;            tmpo->ship_guns_range=0.0;
+          tmpo->torpedos =tmpo->max_torpedos=1;
+          tmpo->torpedos_range =20.0;
+          QueIns(tmpo,obj_head.last);
+        }
+      }
+    }
+  }
+  squadrons=CAlloc(num_squadrons*sizeof(Squadron));
+  for (i=0,tmps=squadrons;i<num_squadrons;i++,tmps++) {
+    tmps->next_in_squadron=tmps->last_in_squadron=tmps;
+    tmps->squadron=i;
+  }
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      tmps->host  =tmpo->host;
+      tmps->player=tmpo->player;
+      tmps->total_mask=1<<num_planes_per_squadron[tmpo->player]-1;
+      SquadronIns(tmpo,tmps->last_in_squadron);
+    }
+    tmpo=tmpo->next;
+  }
+}
+
+U0 CleanUp()
+{
+  QueDel(&obj_head,TRUE);
+  QueDel(&torpedo_head,TRUE);
+  Free(squadrons);
+}
+
+Obj *ObjLaunch(I64 player,I64 squadron=-1,
+        Obj *host=NULL,F64 x=F64_MAX,F64 y=F64_MAX,F64 theta=F64_MAX)
+{
+  Obj *tmpo;
+  F64 cur_time=tS;
+  if (!host)
+    host=ObjFind(x,y,,,1<<OT_CARRIER,1<<player);
+  if (host && cur_time>host->next_action_time) {
+    if (theta==F64_MAX)
+      theta=Arg(x-host->x,y-host->y);
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->host==host && (squadron<0||tmpo->squadron==squadron) &&
+            !(tmpo->flags&OF_ACTIVE) &&
+            (tmpo->squadron<0||squadrons[tmpo->squadron].action==SA_PARKED||
+            squadrons[tmpo->squadron].action==SA_LAUNCHING)) {
+        if (tmpo->fuel<=0.0)
+//When low on fuel, not zero, gets launched and captured.
+          LBts(&squadrons[tmpo->squadron].dead_mask,tmpo->member_num);
+        else {
+          tmpo->flags=tmpo->flags&~OF_RETURNING|OF_ACTIVE;
+          tmpo->theta=host->theta;
+          if (x==F64_MAX || y==F64_MAX || Sqr(x-host->x)+Sqr(y-host->y)>3*3)
+            tmpo->dtheta=Wrap(theta-tmpo->theta,-pi);
+          else
+            tmpo->dtheta=0;
+          tmpo->x=host->x;
+          tmpo->y=host->y;
+          host->next_action_time=cur_time+0.25/game_speed;
+          return tmpo;
+        }
+      }
+      tmpo=tmpo->next;
+    }
+  }
+  return NULL;
+}
+
+Squadron *SquadronLaunch(I64 player,F64 x=F64_MAX,F64 y=F64_MAX)
+{
+  Squadron *tmps;
+  Obj *tmpo;
+  if (tmpo=ObjLaunch(player,,,x,y)) {
+    if (player==0) {
+      launch_unit_x1=tmpo->x;
+      launch_unit_y1=tmpo->y;
+      launch_unit_x2=ms.pos.x-main_task->pix_left-main_task->scroll_x;
+      launch_unit_y2=ms.pos.y-main_task->pix_top -main_task->scroll_y;
+      launch_t=tS+0.5;
+    }
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      if (tmps->action==SA_PARKED) {
+        tmps->action=SA_LAUNCHING;
+        tmps->theta=tmpo->theta+tmpo->dtheta;
+      }
+      return tmps;
+    }
+  }
+  return NULL;
+}
+
+Obj *ObjReturn(I64 player,F64 x,F64 y)
+{
+  Obj *tmpo;
+  if (tmpo=ObjFind(x,y,OF_ACTIVE,OF_ACTIVE,1<<OT_FIGHTER,1<<player))
+    tmpo->flags|=OF_RETURNING;
+  return tmpo;
+}
+
+Squadron *SquadronReturn(I64 player,F64 x,F64 y)
+{
+  Squadron *tmps;
+  Obj *tmpo;
+  if (tmpo=ObjReturn(player,x,y)) {
+    if (player==0) {
+      return_unit_x1=tmpo->x;
+      return_unit_y1=tmpo->y;
+      if (tmpo->host) {
+        return_unit_x2=tmpo->host->x;
+        return_unit_y2=tmpo->host->y;
+        return_t=tS+0.5;
+      }
+    }
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      if (tmps->action==SA_FLYING)
+        tmps->action=SA_RETURNING;
+      return tmps;
+    }
+  }
+  return NULL;
+}
+
+Obj *ObjSettheta(I64 player,F64 x=F64_MAX,F64 y=F64_MAX,F64 theta=F64_MAX)
+{
+  Obj *tmpo;
+  if ((tmpo=ObjFind(x,y,,,,1<<player)) && tmpo->flags&OF_ACTIVE &&
+        !(tmpo->flags&OF_RETURNING)) {
+    if (theta==F64_MAX)
+      theta=Arg(x-tmpo->x,y-tmpo->y);
+    tmpo->dtheta+=Wrap(theta-(tmpo->theta+tmpo->dtheta),-pi);
+    return tmpo;
+  }
+  return NULL;
+}
+
+Squadron *SquadronSettheta(I64 player,F64 x=F64_MAX,F64 y=F64_MAX,F64 theta=F64_MAX)
+{
+  Squadron *tmps;
+  Obj *tmpo;
+  if (tmpo=ObjSettheta(player,x,y,theta)) {
+    if (player==0) {
+      set_theta_unit_x1=tmpo->x;
+      set_theta_unit_y1=tmpo->y;
+      set_theta_unit_x2=ms.pos.x-main_task->pix_left-main_task->scroll_x;
+      set_theta_unit_y2=ms.pos.y-main_task->pix_top -main_task->scroll_y;
+      set_theta_t=tS+0.5;
+    }
+    if (tmpo->squadron>=0) {
+      tmps=&squadrons[tmpo->squadron];
+      if (tmps->action==SA_FLYING) {
+        tmps->action=SA_SET_theta;
+        tmps->theta=tmpo->theta+tmpo->dtheta;
+      }
+      return tmps;
+    }
+  }
+  return NULL;
+}
+
+U0 SquadronActions()
+{
+  I64 i,completed_mask;
+  Obj *tmpo;
+  Squadron *tmps;
+  for (i=0,tmps=squadrons;i<num_squadrons;i++,tmps++) {
+    completed_mask=0;
+    switch (tmps->action) {
+      case SA_LAUNCHING:
+        ObjLaunch(tmps->player,i,tmps->host,,,tmps->theta);
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          LBEqu(&completed_mask,tmpo->member_num,tmpo->flags&OF_ACTIVE);
+          tmpo=tmpo->next_in_squadron;
+        }
+        if (completed_mask|tmps->dead_mask==tmps->total_mask)
+          tmps->action=SA_FLYING;
+        break;
+      case SA_FLYING:
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          LBEqu(&completed_mask,tmpo->member_num,!(tmpo->flags&OF_ACTIVE));
+          tmpo=tmpo->next_in_squadron;
+        }
+        if (completed_mask|tmps->dead_mask==tmps->total_mask)
+          tmps->action=SA_PARKED;
+        break;
+      case SA_SET_theta:
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          tmpo->dtheta+=Wrap(tmps->theta-(tmpo->theta+tmpo->dtheta),-pi);
+          tmpo=tmpo->next_in_squadron;
+        }
+        tmps->action=SA_FLYING;
+        break;
+      case SA_RETURNING:
+        tmpo=tmps->next_in_squadron;
+        while (tmpo!=tmps) {
+          tmpo->flags|=OF_RETURNING;
+          LBEqu(&completed_mask,tmpo->member_num,!(tmpo->flags&OF_ACTIVE));
+          tmpo=tmpo->next_in_squadron;
+        }
+        if (completed_mask|tmps->dead_mask==tmps->total_mask)
+          tmps->action=SA_PARKED;
+        break;
+    }
+    if (tmps->dead_mask==tmps->total_mask)
+      tmps->action=SA_DEAD;
+  }
+}
+
+U0 AI(I64 player,F64 period)
+{
+  Obj *tmpo;
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    if (tmpo->player==player) {
+      if (tmpo->type==OT_CARRIER && Rand<5*period)
+        SquadronLaunch(player,tmpo->x,tmpo->y);
+      if (tmpo->flags&OF_ACTIVE && !(tmpo->flags&OF_RETURNING) &&
+            Rand<10.0*period)
+        SquadronSettheta(player,tmpo->x,tmpo->y,tmpo->theta+pi/2*(Rand-0.5));
+    }
+    tmpo=tmpo->next;
+  }
+}
+
+U0 ShipDamage(Obj *tmpo,F64 d)
+{
+  I64 i,x=Rand*FIRE_WIDTH,y=Rand*FIRE_HEIGHT;
+  tmpo->life_percent-=d;
+  while (d>0) {
+    if (!Bts(tmpo->fire,y*FIRE_WIDTH+x))
+      d-=500.0/(FIRE_WIDTH*FIRE_HEIGHT);
+    else
+      d-=25.0/(FIRE_WIDTH*FIRE_HEIGHT);
+    i=RandI16&7;
+    x+=gr_x_offsets[i];
+    y+=gr_y_offsets[i];
+    while (x>=FIRE_WIDTH)
+      x-=FIRE_WIDTH;
+    while (x<0)
+      x+=FIRE_WIDTH;
+    while (y>=FIRE_HEIGHT)
+      y-=FIRE_HEIGHT;
+    while (y<0)
+      y+=FIRE_HEIGHT;
+  }
+}
+
+U0 ShipFix(Obj *tmpo,F64 d)
+{
+  tmpo->life_percent+=d;
+  if (tmpo->life_percent>=100.0) {
+    tmpo->life_percent=100.0;
+    MemSet(tmpo->fire,0,sizeof(Obj.fire));
+    return;
+  }
+  while (d>0)
+    if (Btr(tmpo->fire,FIRE_WIDTH*FIRE_HEIGHT*Rand))
+      d-=400.0/(FIRE_WIDTH*FIRE_HEIGHT);
+    else
+      d-=20.0/(FIRE_WIDTH*FIRE_HEIGHT);
+}
+
+U0 Combat(F64 period)
+{
+  F64 d;
+  Obj *tmpo,*tmpo1;
+  Torpedo *tmpt;
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    tmpo->flags&=~OF_SHOOTING;
+    if (tmpo->flags&OF_ACTIVE &&
+          (tmpo1=ObjFind(tmpo->x,tmpo->y,OF_ACTIVE,OF_ACTIVE,,
+          1<<(tmpo->player^1),&d))) {
+      tmpo->target_x=tmpo1->x;
+      tmpo->target_y=tmpo1->y;
+      if (tmpo1->flags&OF_SHIP) {
+        if (tmpo->torpedos && d<tmpo->torpedos_range && Rand<125*period) {
+          tmpo->torpedos--;
+          tmpt=CAlloc(sizeof(Torpedo));
+          tmpt->x=tmpo->x;
+          tmpt->y=tmpo->y;
+          tmpt->speed=100;
+          d/=tmpt->speed*(GAME_SPEED_SCALE*game_speed);
+          tmpo1->death_time=tmpt->timeout=tS+d;
+          tmpt->target=tmpo1;
+          tmpt->theta=Arg(tmpo1->x-tmpo->x,tmpo1->y-tmpo->y);
+          QueIns(tmpt,torpedo_head.last);
+          Sweep(2000,86,53);
+        } else if (tmpo->ship_guns>0 && d<tmpo->ship_guns_range) {
+          tmpo->flags|=OF_SHOOTING;
+          if (Rand<125.0*period) {
+            ShipDamage(tmpo1,tmpo->ship_guns*Rand*period);
+            if (Rand<10.0*period)
+              tmpo1->fuel*=0.75*Rand+0.25;
+          }
+          if (tS>next_noise) {
+            Noise(100,29,46);
+            next_noise=tS+0.1;
+          }
+        }
+      } else {
+        if (tmpo->air_guns>0 && d<tmpo->air_guns_range) {
+          tmpo->flags|=OF_SHOOTING;
+          if (Rand<125.0*period) {
+            tmpo1->life_percent-=tmpo->air_guns*Rand*period;
+            if (Rand<10.0*period)
+              tmpo1->fuel*=0.75*Rand+0.25;
+          }
+          if (tS>next_noise) {
+            Noise(25,62,86);
+            next_noise=tS+0.025;
+          }
+        }
+      }
+    }
+    tmpo=tmpo->next;
+  }
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    tmpo1=tmpo->next;
+    if (tmpo->type==OT_FIGHTER &&
+          (tmpo->life_percent<=0.0 || tmpo->flags&OF_ACTIVE &&
+          tmpo->fuel<=0.0 || tmpo->host &&
+          !(tmpo->flags&OF_ACTIVE) && tmpo->host->life_percent<=0.0))
+      ObjDel(tmpo);
+    tmpo=tmpo1;
+  }
+  tmpo=obj_head.next;
+  while (tmpo!=&obj_head) {
+    tmpo1=tmpo->next;
+    if (tmpo->life_percent<=0.0)
+      ObjDel(tmpo);
+    tmpo=tmpo1;
+  }
+}
+
+#define ANIMATE_FREQ    50
+U0 AnimateTask(I64)
+{
+  Obj *tmpo;
+  Torpedo *tmpt,*tmpt1;
+  F64 d,period;
+
+  while (TRUE) {
+    period=GAME_SPEED_SCALE*game_speed/ANIMATE_FREQ;
+    SquadronActions;
+
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->flags&OF_ACTIVE && tmpo->fuel>0) {
+        if (tmpo->dtheta) {
+          d=tmpo->dtheta;
+          if (d> tmpo->turn_rate*period) d= tmpo->turn_rate*period;
+          if (d<-tmpo->turn_rate*period) d=-tmpo->turn_rate*period;
+          tmpo->theta +=d;
+          tmpo->dtheta-=d;
+        }
+        tmpo->x+=tmpo->speed*Cos(tmpo->theta)*period*tmpo->life_percent/100.0;
+        tmpo->y+=tmpo->speed*Sin(tmpo->theta)*period*tmpo->life_percent/100.0;
+        tmpo->fuel-=tmpo->speed*tmpo->fuel_burn_rate*period;
+      }
+      tmpo=tmpo->next;
+    }
+
+    tmpt=torpedo_head.next;
+    while (tmpt!=&torpedo_head) {
+      tmpt1=tmpt->next;
+      if (tS>tmpt->timeout) {
+        tmpo=tmpt->target;
+        if (Rand<0.333333) {
+          ShipDamage(tmpo,150*Rand*Rand);
+          if (Rand<0.333333)
+            tmpo->fuel*=0.75*Rand+0.25;
+        }
+        QueRem(tmpt);
+        Free(tmpt);
+      } else {
+        tmpt->x+=tmpt->speed*Cos(tmpt->theta)*period;
+        tmpt->y+=tmpt->speed*Sin(tmpt->theta)*period;
+      }
+      tmpt=tmpt1;
+    }
+
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->host && !(tmpo->flags&OF_ACTIVE)) {
+        tmpo->x=tmpo->host->x;
+        tmpo->y=tmpo->host->y;
+      }
+      tmpo=tmpo->next;
+    }
+
+    tmpo=obj_head.next;
+    while (tmpo!=&obj_head) {
+      if (tmpo->flags&OF_ACTIVE) {
+        if (tmpo->host) {
+          d=Sqrt(Sqr(tmpo->x-tmpo->host->x)+Sqr(tmpo->y-tmpo->host->y));
+          if (d<8 && tmpo->max_fuel-tmpo->fuel>30) {
+            tmpo->life_percent=100.0;
+            if (tmpo->host->fuel>0) {
+              d=tmpo->max_fuel-tmpo->fuel;
+              if (d>tmpo->host->fuel) d=tmpo->host->fuel;
+              tmpo->host->fuel-=d;
+              tmpo->fuel+=d;
+            }
+            tmpo->torpedos=tmpo->max_torpedos;
+            tmpo->x=tmpo->host->x;
+            tmpo->y=tmpo->host->y;
+            tmpo->flags&=~OF_ACTIVE;
+          } else if (d>tmpo->fuel-250)
+            tmpo->flags|=OF_RETURNING;
+          if (tmpo->flags&OF_RETURNING)
+            tmpo->dtheta+=Wrap(Arg(tmpo->host->x-tmpo->x,
+                  tmpo->host->y-tmpo->y)-(tmpo->theta+tmpo->dtheta),-pi);
+        } else if (tmpo->type==OT_CARRIER)
+          ShipFix(tmpo,2.5*period);
+      }
+      tmpo=tmpo->next;
+    }
+
+    AI(1,period);
+    Combat(period);
+    Sleep(1000/ANIMATE_FREQ);
+  }
+}
+
+U0 FlatTops()
+{
+  I64 arg1,arg2;
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLUE<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  PopUpOk("$GREEN${Left-Mouse}$FG$\t\tChange Course\n"
+        "$GREEN${Right-Mouse}$FG$\t\tLaunch Squadron\n"
+        "$GREEN${Right-Double-Mouse}$FG$\tReturn Squadron\n"
+        "$GREEN${Ctrl-Left Grab}$FG$\tScroll Scrn\n");
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Faster(,'+');"
+        "  Slower(,'-');"
+        "}"
+        );
+  Fs->win_inhibit|=WIF_SELF_MS_L|WIF_SELF_MS_R;
+  Init;
+  Fs->draw_it=&DrawIt;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  try {
+    while (TRUE)
+      switch (GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_UP|1<<MSG_MS_R_D_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto nv_done;
+            case '+':
+              game_speed*=1.5;
+              break;
+            case '-':
+              game_speed/=1.5;
+              break;
+          }
+          break;
+        case MSG_MS_L_UP:
+          SquadronSettheta(0,arg1,arg2);
+          break;
+        case MSG_MS_R_UP:
+          SquadronLaunch(0,arg1,arg2);
+          break;
+        case MSG_MS_R_D_UP:
+          SquadronReturn(0,arg1,arg2);
+          break;
+      }
+nv_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+FlatTops;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//Maybe use this in the future  <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Halogen.HC.HTML b/public/Wb/Home/Src/Demo/Games/Halogen.HC.HTML new file mode 100755 index 0000000..d4ad81a --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Halogen.HC.HTML @@ -0,0 +1,193 @@ + + + + + + + + + + + +
+#define ROAD_NUM        512
+#define ROAD_WIDTH_BY_2 200
+#define CAR_WIDTH_BY_2  100
+
+I64 road_x[ROAD_NUM],road_trend;
+F64 speed,distance;
+I64 road_ptr=0,car_x;
+F64 t_last;
+Bool crash;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 w=task->pix_width,h=task->pix_height;
+  I64 i,x,y,xx;
+  xx=w>>1-car_x+road_x[road_ptr&(ROAD_NUM-1)];
+
+  dc->color=LTGRAY;
+  for (i=0;i<ROAD_NUM;i++) {
+    x=w>>1-car_x+road_x[(i+road_ptr)&(ROAD_NUM-1)];
+    y=h-0.5*i;
+    if (y<(h+FONT_HEIGHT)>>1) break;
+    GrPlot(dc,x+ROAD_WIDTH_BY_2-0.4*i,y);
+    GrPlot(dc,x-ROAD_WIDTH_BY_2+0.4*i,y);
+  }
+  dc->color=WHITE;
+
+  x=w>>1-CAR_WIDTH_BY_2;
+  if (x<xx-ROAD_WIDTH_BY_2)
+    crash=TRUE;
+  GrLine(dc,x-10,h,x-40,h-100);
+  GrLine(dc,x+10,h,x+40,h-100);
+
+  x=w>>1+CAR_WIDTH_BY_2;
+  if (x>xx+ROAD_WIDTH_BY_2)
+    crash=TRUE;
+  GrLine(dc,x-10,h,x-40,h-100);
+  GrLine(dc,x+10,h,x+40,h-100);
+
+  dc->color=YELLOW;
+  if (crash)
+    GrPrint(dc,w>>1-FONT_WIDTH*4,(h-FONT_HEIGHT)>>1,"Game Over");
+}
+
+U0 UpdateRoad()
+{
+  F64 t0=tS;
+  distance+=speed*(t0-t_last);
+  t_last=t0;
+  while (distance>1.0) {
+    road_trend=ClampI64(road_trend+SignI64(RandU16%3-1),-5,5);
+    road_x[road_ptr&(ROAD_NUM-1)]=
+          road_x[(road_ptr-1)&(ROAD_NUM-1)]+=road_trend/3;
+    road_ptr++;
+    distance-=1.0;
+  }
+}
+
+U0 Init()
+{
+  I64 i,x=0;
+  DocClear;
+  "$BG,DKGRAY$%h*c",(TEXT_ROWS-1)/2,'\n';
+  speed=0;
+  distance=0;
+  road_trend=0;
+  road_ptr=0;
+  car_x=0;
+  for (i=0;i<ROAD_NUM;i++) {
+    road_x[i]=x;
+    road_trend=ClampI64(road_trend+SignI64(RandU16%3-1),-5,5);
+    x+=road_trend/3;
+  }
+  t_last=tS;
+  crash=FALSE;
+}
+
+U0 Halogen()
+{
+  I64 arg1,arg2,ch=0,sc=0;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=BLACK<<4+WHITE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Accelerate(,,SC_CURSOR_UP);"
+        "  Deccellerate(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Init;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_KEY_UP)) {
+        case MSG_KEY_DOWN:
+          ch=arg1;sc=arg2;
+          switch (ch) {
+            case '\n':
+              Init;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto ha_done;
+          }
+          break;
+        case MSG_KEY_UP:
+          ch=arg1;sc=arg2;
+          if (!ch)
+            switch (sc.u8[0]) {
+              case SC_CURSOR_RIGHT:
+              case SC_CURSOR_LEFT:
+              case SC_CURSOR_UP:
+              case SC_CURSOR_DOWN:
+                sc=0;
+                break;
+            }
+          break;
+      }
+      switch (sc.u8[0]) {
+        case SC_CURSOR_RIGHT:
+          car_x++;
+          break;
+        case SC_CURSOR_LEFT:
+          car_x--;
+          break;
+        case SC_CURSOR_UP:
+          if (++speed>200) speed=200;
+          break;
+        case SC_CURSOR_DOWN:
+          if (--speed<0) speed=0;
+          break;
+      }
+      if (crash)
+        Snd;
+      else {
+        if (speed)
+          Snd(Freq2Ona(speed+10));
+        else
+          Snd;
+        UpdateRoad;
+      }
+      Sleep(10);
+    }
+ha_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  MenuPop;
+  DocClear;
+  SettingsPop;
+}
+
+Halogen;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/MassSpring.HC.HTML b/public/Wb/Home/Src/Demo/Games/MassSpring.HC.HTML new file mode 100755 index 0000000..e541a49 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/MassSpring.HC.HTML @@ -0,0 +1,200 @@ + + + + + + + + + + + +
+class MyMass:CMass
+{
+  F64 radius;
+};
+
+class MySpring:CSpring
+{
+};
+
+CMathODE *ode=NULL;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  MyMass   *tmpm;
+  MySpring *tmps;
+
+  dc->color=RED;
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    GrLine(dc,tmps->end1->x,tmps->end1->y,tmps->end2->x,tmps->end2->y);
+    tmps=tmps->next;
+  }
+
+  dc->color=BLACK;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+    tmpm=tmpm->next;
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{//The forces due to springs and drag are
+//automatically handled by the ode code.
+  //We can add new forces here.
+  F64 d,dd;
+  CD3 p;
+  MyMass *tmpm1,*tmpm2;
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      D3Sub(&p,&tmpm2->state->x,&tmpm1->state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=Sqr(tmpm1->radius+tmpm2->radius)) {
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr(Sqr(tmpm1->radius+tmpm2->radius)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&tmpm2->DstateDt->DxDt,&p);
+        D3SubEqu(&tmpm1->DstateDt->DxDt,&p);
+      }
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+}
+
+U0 PlaceMass(I64 x, I64 y)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass));
+  tmpm->mass=1.0;
+  tmpm->drag_profile_factor=100.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->radius=10*(Rand+0.25);
+  QueIns(tmpm,ode->last_mass);
+}
+
+U0 PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  tmps->const=10000;
+  tmps->rest_len=100;
+  QueIns(tmps,ode->last_spring);
+}
+
+U0 Init()
+{
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  QueRem(ode);
+  QueDel(&ode->next_mass,TRUE);
+  QueDel(&ode->next_spring,TRUE);
+  ODEDel(ode);
+}
+
+U0 MassSpringDemo()
+{
+  I64 msg_code,arg1,arg2;
+  MyMass *tmpm1=NULL,*tmpm2=NULL;
+
+  PopUpOk("Left-Click to place mas\n"
+        "Right-Click and drag to\n"
+        "connect with spring.\n\n"
+        "Springs are 100 pixs long.\n");
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+
+  Init;
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP|1<<MSG_KEY_DOWN);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+          PlaceMass(arg1,arg2);
+          break;
+        case MSG_MS_R_DOWN:
+          tmpm1=MassFind(ode,arg1,arg2);
+          tmpm2=NULL;
+          break;
+        case MSG_MS_R_UP:
+          if (tmpm1 && (tmpm2=MassFind(ode,arg1,arg2)) && tmpm1!=tmpm2)
+            PlaceSpring(tmpm1,tmpm2);
+          tmpm1=tmpm2=NULL;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto ms_done;
+          }
+          break;
+      }
+    }
+ms_done: //Don't goto out of try
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+MassSpringDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Maze.HC.HTML b/public/Wb/Home/Src/Demo/Games/Maze.HC.HTML new file mode 100755 index 0000000..36320b3 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Maze.HC.HTML @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+//See TextBase Layer.
+
+#define ATTR (BLACK<<12+WHITE<<8)
+
+U32 text[TEXT_ROWS][TEXT_COLS];
+
+U0 DrawIt(CTask *task,CDC *)
+{ //gr.text_base gets clear 30fps, so we must use our own permanent text array.
+  MemCpy(gr.text_base+TEXT_COLS,text,(TEXT_ROWS-1)*TEXT_COLS*sizeof(U32));
+
+  // You can copy it this way, if you like:
+  //  I64 i,j;
+  //  for (j=0;j<TEXT_ROWS;j++)
+  //    for (i=0;i<TEXT_COLS;i++)
+  //     TextChar(task,,i,j,text[j][i]);
+
+  TextPrint(task,0,0,ATTR>>8,"Draw a maze with left bttn.");
+  TextPrint(task,0,1,ATTR>>8,"Solve maze starting at right click.");
+}
+
+#define STK_SIZE 2048
+//We would put these as local vars
+//in SolveMaze() but the system stk size
+//is limited, so it's a bad habit.  The heap
+//is the normal TempleOS technique, but
+//it's a pain in this case.
+I64     stk_ptr,
+        stk_x  [STK_SIZE],
+        stk_y  [STK_SIZE],
+        stk_dir[STK_SIZE];
+
+//Four directions:
+//  0=Up,1=right,2=down,3=left
+I64     dir_x[4]={ 0,+1, 0,-1},  // Could use gr_x_offsets2,gr_y_offsets2
+        dir_y[4]={+1, 0,-1, 0};
+
+U0 SolveMaze(I64 x,I64 y)
+{
+  I64 dir=0;
+  stk_ptr=0;
+  stk_x[stk_ptr]=x;
+  stk_y[stk_ptr]=y;
+  stk_dir[stk_ptr++]=dir;
+  while (TRUE) {
+    if (!(0<=x<MinI64(Fs->win_width,TEXT_COLS)) ||
+          !(0<=y<MinI64(Fs->win_height,TEXT_ROWS)) ) {
+      Beep;Beep;
+      break;
+    }
+    if (!text[y][x].u8[0])
+      text[y][x]='.'+ATTR;
+    x+=dir_x[dir];
+    y+=dir_y[dir];
+//u8.[0] is the ASCII
+    if (text[y][x].u8[0]) {
+      x-=dir_x[dir];
+      y-=dir_y[dir];
+      if (++dir==4) {
+        if (--stk_ptr<0) return;
+        x=stk_x[stk_ptr];
+        y=stk_y[stk_ptr];
+        dir=stk_dir[stk_ptr];
+      }
+    } else {
+      dir=0;
+      stk_x[stk_ptr]=x;
+      stk_y[stk_ptr]=y;
+      stk_dir[stk_ptr++]=dir;
+      if (stk_ptr==STK_SIZE) return;
+      Sleep(100);
+      if (ScanChar)
+        throw;
+    }
+  }
+}
+
+U0 Maze()
+{
+  I64 ch,x,y;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  try
+    do {
+      MemSet(text,0,sizeof(text));
+      while (!(ch=ScanChar)) {
+        x=ms.pos_text.x-Fs->win_left-Fs->scroll_x/FONT_WIDTH;
+        y=ms.pos_text.y-Fs->win_top-Fs->scroll_y/FONT_HEIGHT;
+        if (ms.lb&&!winmgr.grab_scroll)
+          text[y][x]=CH_SPACE+ATTRF_INVERT+ATTR;
+        if (ms.rb&&!winmgr.grab_scroll) {
+          text[y][x]='*'+ATTR;
+          SolveMaze(x,y);
+          ch=GetChar;
+          break;
+        }
+        Refresh;
+      }
+    } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  catch
+    PutExcept;
+  SettingsPop;
+}
+
+Maze;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/RainDrops.HC.HTML b/public/Wb/Home/Src/Demo/Games/RainDrops.HC.HTML new file mode 100755 index 0000000..5af7302 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/RainDrops.HC.HTML @@ -0,0 +1,220 @@ + + + + + + + + + + + +
+I64 sc_1,sc_2;
+
+#define DROPS_NUM       0x2000
+
+class Drop
+{
+  I32 x,y;
+} drops[DROPS_NUM];
+
+CDC *cur_dc;
+
+U0 DrawFrame(CTask *task,CDC *dc)
+{
+  I64 w=task->pix_width,h=task->pix_height,
+        cx=w>>1,cy=h>>1;
+
+  dc->color=LTRED;
+  GrLine(dc,cx-20,cy-50,cx,cy-150);
+  GrLine(dc,cx+20,cy-50,cx,cy-150);
+
+  dc->color=LTRED;
+  GrLine(dc,cx-100,cy-100,cx,cy);
+  GrLine(dc,cx+100,cy-100,cx,cy);
+  if (Bt(kbd.down_bitmap,sc_1)) {
+    dc->color=WHITE;
+    GrRect(dc,cx-2,cy-2,5,5);
+  }
+  dc->color=BLACK;
+  GrPrint(dc,cx+10,cy,"Press '1'");
+
+  dc->color=LTRED;
+  GrRect(dc,cx-20,cy+60,41,21);
+
+  dc->color=LTRED;
+  GrLine(dc,cx-200,cy,cx,cy+100);
+  GrLine(dc,cx+200,cy,cx,cy+100);
+  if (Bt(kbd.down_bitmap,sc_2)) {
+    dc->color=WHITE;
+    GrRect(dc,cx-2,cy+100-2,5,5);
+  }
+  dc->color=BLACK;
+  GrPrint(dc,cx+10,cy+100,"Press '2'");
+
+  dc->color=LTRED;
+  GrLine(dc,cx+400,cy+100,cx-250,cy+200);
+}
+
+U0 DrawDrops(CTask *,CDC *dc)
+{
+  I64 i;
+  dc->color=BLUE;
+  for (i=0;i<DROPS_NUM;i++)
+    if (drops[i].y>=0 && GrPeek(dc,drops[i].x,drops[i].y)==WHITE)
+      GrPlot(dc,drops[i].x,drops[i].y);
+}
+
+U0 UpdateCurBase(CTask *task,CDC *dc)
+{
+  cur_dc->color=ROP_EQU;
+  dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(cur_dc,-task->pix_left-task->scroll_x,
+        -task->pix_top-task->scroll_y,dc);
+  dc->flags&=~DCF_NO_TRANSPARENTS;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  DrawFrame(task,dc);
+  DrawDrops(task,dc);
+  UpdateCurBase(task,dc);
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i,j,cur_drop=0,c1,c2,x0,y0,x1,y1,w,h;
+  while (TRUE) {
+    w=Fs->parent_task->pix_width;
+    h=Fs->parent_task->pix_height;
+
+    for (i=0;i<2;i++) {
+      j=0;
+      do {
+        if (++cur_drop>=DROPS_NUM)
+          cur_drop=0;
+        if (drops[cur_drop].y<0)
+          break;
+        j++;
+      } while (j<=DROPS_NUM);
+
+      drops[cur_drop].x=RandU32%w;
+      drops[cur_drop].y=0;
+    }
+
+    for (i=0;i<DROPS_NUM;i++) {
+      if (drops[i].y>=0) {
+        if (drops[i].y>=h-1)
+          drops[i].y=-I32_MAX;
+        else {
+          x0=x1=drops[i].x;
+          y0=y1=drops[i].y;
+          if (GrPeek(cur_dc,x0,y0+1)==WHITE)
+            y1++;
+          else {
+            c1=GrPeek(cur_dc,x0+1,y0);
+            c2=GrPeek(cur_dc,x0-1,y0);
+            if (c1==WHITE && c2!=WHITE)
+              x1++;
+            else if (c2==WHITE && c1!=WHITE)
+              x1--;
+            else if (c1==WHITE && c2==WHITE) {
+              c1=GrPeek(cur_dc,x0+1,y0+1);
+              c2=GrPeek(cur_dc,x0-1,y0+1);
+              if (c1==WHITE && c2!=WHITE)
+                x1++;
+              else if (c2==WHITE && c1!=WHITE)
+                x1--;
+              else if (RandI16>=0)
+                x1++;
+              else
+                x1--;
+            }
+            if (GrPeek(cur_dc,x1,y1+1)==WHITE)
+              y1++;
+          }
+          if (GrPeek(cur_dc,x0,y0)==BLUE) {
+            cur_dc->color=WHITE;
+            GrPlot(cur_dc,x0,y0);
+          }
+          cur_dc->color=BLUE;
+          GrPlot(cur_dc,x1,y1);
+          drops[i].x=x1;
+          drops[i].y=y1;
+        }
+      }
+    }
+    Sleep(10);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  MemSet(drops,0,sizeof(drops));
+  for (i=0;i<DROPS_NUM;i++)
+    drops[i].y=-I32_MAX;
+}
+
+U0 RainDrops()
+{
+  I64 ch,sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  OpenUpper(,'1');"
+        "  OpenLower(,'2');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  cur_dc=DCNew(GR_WIDTH,GR_HEIGHT);
+  sc_1=Char2ScanCode('1');
+  sc_2=Char2ScanCode('2');
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    do
+      switch (ch=GetKey(&sc)) {
+        case '\n':
+          Init;
+          break;
+      }
+    while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  DCDel(cur_dc);
+}
+
+RainDrops;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/RawHide.HC.HTML b/public/Wb/Home/Src/Demo/Games/RawHide.HC.HTML new file mode 100755 index 0000000..f906b0d --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/RawHide.HC.HTML @@ -0,0 +1,622 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+RegDft("TempleOS/RawHide","F64 best_score=9999;\n");
+RegExe("TempleOS/RawHide");
+
+F64 t0,tf;
+I64 outside_cnt;
+
+#define MAP_WIDTH       1000
+#define MAP_HEIGHT      1000
+#define FENCE_WIDTH     320
+#define FENCE_HEIGHT    200
+#define MAP_BORDER      3
+CDC *map_dc;
+
+#define GATE_WIDTH      22
+#define GATE_HEIGHT     7
+F64 gate_theta,gate_t;
+
+
+
+<1>/* Graphics Not Rendered in HTML */  <2>/* Graphics Not Rendered in HTML */  <3>/* Graphics Not Rendered in HTML */
+
+
+<4>/* Graphics Not Rendered in HTML */  <5>/* Graphics Not Rendered in HTML */  <6>/* Graphics Not Rendered in HTML */
+
+
+<7>/* Graphics Not Rendered in HTML */  <8>/* Graphics Not Rendered in HTML */
+
+
+<9>/* Graphics Not Rendered in HTML */
+        <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+#define ANIMAL_WIDTH    20
+#define ANIMAL_HEIGHT   16
+
+U8 *cow_imgs[4]  ={<1>,<2>,<3>,<2>},
+   *bull_imgs[4] ={<4>,<5>,<6>,<5>},
+   *horse_imgs[4]={<7>,<8>,<7>,<8>};
+
+#define ANIMALS_NUM     100
+
+class Animal
+{
+  I64   num,x,y,dx,dy;
+  U8    **imgs;
+  U32   buddy;
+  U8    type,frame0;
+  Bool  dead,pad;
+} *a;
+
+//************************************
+#define WATERFALL_HEIGHT        (MAP_HEIGHT/20)
+#define WATERFALL_DROPS         512
+#define WATERFALL_ACCELERATION  10
+I32 *r_x,*r_width,*wfd_x;
+F64 *wfd_t0,waterfall_tf;
+I64 waterfall_x,waterfall_y,waterfall_width;
+
+U0 RiverNew()
+{
+  r_x=MAlloc(MAP_HEIGHT*sizeof(I32));
+  r_width=MAlloc(MAP_HEIGHT*sizeof(I32));
+  wfd_x=MAlloc(WATERFALL_DROPS*sizeof(I32));
+  wfd_t0=MAlloc(WATERFALL_DROPS*sizeof(F64));
+  waterfall_tf=Sqrt(2*WATERFALL_HEIGHT/WATERFALL_ACCELERATION);
+}
+
+U0 RiverMake()
+{
+  I64 i,x=2*MAP_WIDTH<<32/3,y,dx=0,w=15<<32;
+  waterfall_y=(MAP_HEIGHT-WATERFALL_HEIGHT)/2*Rand+
+    (MAP_HEIGHT-WATERFALL_HEIGHT)/4;
+  for (y=MAP_BORDER;y<MAP_HEIGHT-MAP_BORDER;y++) {
+    r_x[y]=x.i32[1]; r_width[y]=w.i32[1];
+    if (waterfall_y-5<y<waterfall_y+WATERFALL_HEIGHT+5) {
+      waterfall_width=r_width[y];
+      waterfall_x=r_x[y]-waterfall_width/2;
+    } else {
+      dx=ClampI64(dx+RandI32/64,-I32_MAX,I32_MAX)-I32_MAX/256;
+      w=ClampI64(w+RandI32*2,10*U32_MAX,150*U32_MAX);
+      x+=dx;
+    }
+  }
+  for (i=0;i<WATERFALL_DROPS;i++) {
+    wfd_x[i]=Rand*waterfall_width+waterfall_x;
+    wfd_t0[i]=tS-Rand*waterfall_tf;
+  }
+
+  //Plot waterfall cliff
+  Sprite3B(map_dc,waterfall_x,waterfall_y,0,<10>);
+
+  //Plot sand bar
+  x=0;
+  for (y=MAP_BORDER;y<MAP_HEIGHT-MAP_BORDER;y++) {
+    if (!(waterfall_y-9<y<waterfall_y+WATERFALL_HEIGHT+9)) {
+      map_dc->color=YELLOW;
+      map_dc->thick=r_width[y]+10;
+      GrPlot3(map_dc,r_x[y]+x.i32[1],y,0);
+    }
+    x=ClampI64(x+RandI32,-6*U32_MAX,6*U32_MAX);
+  }
+
+  //Plot water
+  for (y=MAP_BORDER;y<MAP_HEIGHT-MAP_BORDER;y++) {
+    map_dc->color=BLUE;
+    map_dc->thick=r_width[y];
+    GrPlot3(map_dc,r_x[y],y,0);
+  }
+}
+
+U0 RiverDel()
+{
+  Free(r_x);
+  Free(r_width);
+  Free(wfd_x);
+  Free(wfd_t0);
+}
+
+//************************************
+class RiverDrop
+{
+  RiverDrop *next,*last;
+  I64 y,dx,dy;
+} rd_head;
+Bool rd_lock;
+
+U0 RiverDropsDel()
+{
+  while (LBts(&rd_lock,0))
+    Yield;
+  QueDel(&rd_head,TRUE);
+  QueInit(&rd_head);
+  LBtr(&rd_lock,0);
+}
+
+U0 RiverDropsNext(CTask *mem_task)
+{
+  RiverDrop *tmpr,*tmpr1;
+  while (LBts(&rd_lock,0))
+    Yield;
+  tmpr=rd_head.next;
+  while (tmpr!=&rd_head) {
+    tmpr1=tmpr->next;
+    if (++tmpr->y>=MAP_HEIGHT-MAP_BORDER) {
+      QueRem(tmpr);
+      Free(tmpr);
+    } else {
+      do {
+        if (RandU16&1 && GrPeek(map_dc,r_x[tmpr->y]+tmpr->dx,
+              tmpr->y+tmpr->dy)==BLUE)
+          break;
+        tmpr->dx=ClampI64(tmpr->dx+RandU16%3-1,-r_width[tmpr->y]/2,
+              r_width[tmpr->y]/2);
+        tmpr->dy=ClampI64(tmpr->dy+RandU16%3-1,-r_width[tmpr->y]/2,
+              r_width[tmpr->y]/2);
+      } while (GrPeek(map_dc,r_x[tmpr->y]+tmpr->dx,
+            tmpr->y+tmpr->dy)!=BLUE &&
+            GrPeek(map_dc,r_x[tmpr->y],tmpr->y)==BLUE);//Might be reiniting
+    }
+    tmpr=tmpr1;
+  }
+  tmpr=MAlloc(sizeof(RiverDrop),mem_task);
+  tmpr->y=MAP_BORDER;
+  tmpr->dx=0;
+  tmpr->dy=0;
+  QueIns(tmpr,rd_head.last);
+  LBtr(&rd_lock,0);
+}
+
+U0 RiverDropsDraw(CDC *dc,I64 cx,I64 cy)
+{
+  I64 i;
+  F64 t=tS;
+  RiverDrop *tmpr;
+  while (LBts(&rd_lock,0))
+    Yield;
+  tmpr=rd_head.next;
+  dc->color=LTBLUE;
+  while (tmpr!=&rd_head) {
+    GrPlot(dc,r_x[tmpr->y]+tmpr->dx-cx,tmpr->y+tmpr->dy-cy);
+    tmpr=tmpr->next;
+  }
+  LBtr(&rd_lock,0);
+
+  dc->color=WHITE;
+  for (i=0;i<WATERFALL_DROPS;i++)
+    GrPlot(dc,wfd_x[i]-cx,waterfall_y+0.5*WATERFALL_ACCELERATION*
+          Sqr(waterfall_tf*Saw(t-wfd_t0[i],waterfall_tf))-cy);
+}
+
+//************************************
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  static I64 last_pos_x=0;
+  static Bool left=TRUE;
+  F64 t;
+  I64 i,frame=4*tS,
+        cx=(MAP_WIDTH -task->pix_width)/2,
+        cy=(MAP_HEIGHT-task->pix_height)/2;
+  if (task->scroll_x+cx<0)
+    task->scroll_x=-cx;
+  if (task->scroll_x+cx>MAP_WIDTH-task->pix_width)
+    task->scroll_x=MAP_WIDTH-task->pix_width-cx;
+  if (task->scroll_y+cy<0)
+    task->scroll_y=-cy;
+  if (task->scroll_y+cy>MAP_HEIGHT-task->pix_height)
+    task->scroll_y=MAP_HEIGHT-task->pix_height-cy;
+
+  map_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,-cx,-cy,map_dc);
+
+  RiverDropsDraw(dc,cx,cy);
+
+  for (i=0;i<ANIMALS_NUM;i++)
+    if (!a[i].dead) {
+      if (a[i].dx<0) {
+        dc->flags|=DCF_JUST_MIRROR|DCF_SYMMETRY;
+        DCSymmetrySet(dc,a[i].x.i32[1]-cx,0,a[i].x.i32[1]-cx,1);
+      }
+      Sprite3(dc,a[i].x.i32[1]-cx,a[i].y.i32[1]-cy,0,
+            a[i].imgs[(frame+a[i].frame0)&3]);
+      dc->flags&=~(DCF_JUST_MIRROR|DCF_SYMMETRY);
+    }
+
+  if (ms.pos.x-last_pos_x>0)
+    left=FALSE;
+  else if (ms.pos.x-last_pos_x<0)
+    left=TRUE;
+  if (left) {
+    dc->flags|=DCF_JUST_MIRROR|DCF_SYMMETRY;
+    DCSymmetrySet(dc,ms.pos.x-task->pix_left-task->scroll_x,0,
+          ms.pos.x-task->pix_left-task->scroll_x,1);
+  }
+  Sprite3(dc,ms.pos.x-task->pix_left-task->scroll_x,
+             ms.pos.y-task->pix_top -task->scroll_y,0,horse_imgs[frame&3]);
+  dc->flags&=~(DCF_JUST_MIRROR|DCF_SYMMETRY);
+  last_pos_x=ms.pos.x;
+
+  if (tf) {
+    dc->color=RED;
+    t=tf-t0;
+    if (Blink)
+      GrPrint(dc,(task->pix_width-FONT_WIDTH*14)>>1-task->scroll_x,
+            (task->pix_height-FONT_HEIGHT)>>1-task->scroll_y,
+            "Game Completed");
+  } else {
+    dc->color=BLACK;
+    t=tS-t0;
+  }
+  GrPrint(dc,-task->scroll_x,-task->scroll_y,
+        "Outside:%03d Time:%7.2fs Best:%7.2fs",
+        outside_cnt,t,best_score);
+}
+
+U0 BuddySel(I64 i)
+{
+  I64 b,best_b=i,score,best_score=I64_MAX;
+  for (b=0;b<ANIMALS_NUM;b++) {
+    if (b!=i && !a[b].dead) {
+      score=RandU32%(512*512)+
+            SqrI64(a[b].x.i32[1]-a[i].x.i32[1])+
+            SqrI64(a[b].y.i32[1]-a[i].y.i32[1]);
+      if (score<best_score) {
+        best_score=score;
+        best_b=b;
+      }
+    }
+  }
+  a[i].buddy=best_b;
+}
+
+
+U0 RedrawGate()
+{
+  F64 tt=tS-gate_t;
+  I64 x1=FENCE_WIDTH-63,y1=FENCE_HEIGHT-1,dx,dy;
+
+  if (tt<0.5)
+    gate_theta=Clamp(gate_theta+0.02,0,pi/2);
+  else if (tt>5.0)
+    gate_theta=Clamp(gate_theta-0.02,0,pi/2);
+
+  dx=GATE_WIDTH*Cos(gate_theta); dy=-0.8*GATE_WIDTH*Sin(gate_theta);
+
+  map_dc->color=LTGREEN;
+  GrRect(map_dc,x1,y1-0.8*GATE_WIDTH-GATE_HEIGHT,
+        46,0.8*GATE_WIDTH+GATE_HEIGHT+3);
+
+  map_dc->color=BLACK;
+
+  GrLine(map_dc,x1,y1,x1+dx,y1+dy);
+  GrLine(map_dc,x1,y1,x1,y1-GATE_HEIGHT);
+  GrLine(map_dc,x1+dx,y1+dy,x1+dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1,y1-GATE_HEIGHT,x1+dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1,y1,x1+dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1,y1-GATE_HEIGHT,x1+dx,y1+dy);
+
+  GrLine(map_dc,x1+45,y1,x1+45-dx,y1+dy);
+  GrLine(map_dc,x1+45,y1,x1+45,y1-GATE_HEIGHT);
+  GrLine(map_dc,x1+45-dx,y1+dy,x1+45-dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1+45,y1-GATE_HEIGHT,x1+45-dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1+45,y1,x1+45-dx,y1+dy-GATE_HEIGHT);
+  GrLine(map_dc,x1+45,y1-GATE_HEIGHT,x1+45-dx,y1+dy);
+}
+
+Bool CheckMap(I64 x,I64 y)
+{
+  I64 i,j,c;
+  if (SqrI64(x-(waterfall_x+waterfall_width/2))>>1+
+        SqrI64(y-(waterfall_y+WATERFALL_HEIGHT/2))<2500)
+    return FALSE;
+  for (j=-4;j<=2;j++)
+    for (i=-4;i<=4;i++) {
+      c=GrPeek(map_dc,x+i,y+j);
+      if (c==LTGRAY || c==BLACK)
+        return FALSE;
+    }
+  return TRUE;
+}
+
+U0 AnimateTask(CTask *parent)
+{
+  I64 i,cx,cy,cursor_x,cursor_y,dd,ddx,ddy,cnt,max_speed=I64_MAX,updates=0,
+        my_outside_cnt;
+  F64 f,d,dx,dy,s,stress;
+  Animal *tmpa,*tmpa1;
+  while (TRUE) {
+    max_speed=ClampU64(max_speed,U32_MAX/3,200*U32_MAX);
+    cx=(MAP_WIDTH -parent->pix_width)/2,
+          cy=(MAP_HEIGHT-parent->pix_height)/2;
+    cursor_x=ms.pos.x+cx-parent->pix_left-parent->scroll_x;
+    cursor_y=ms.pos.y+cy-parent->pix_top -parent->scroll_y;
+    cnt=0;stress=0;
+    my_outside_cnt=0;
+    if (cursor_x<FENCE_WIDTH && cursor_y<FENCE_HEIGHT)
+      gate_t=tS;
+    RedrawGate;
+    for (i=0;i<ANIMALS_NUM;i++) {
+      tmpa=&a[i];
+      if (!tmpa->dead) {
+//Move away from horse
+        ddx=tmpa->x.i32[1]-cursor_x;
+        ddy=tmpa->y.i32[1]-cursor_y;
+        if (dd=SqrI64(ddx)+SqrI64(ddy)) {
+          d=Sqrt(dd);
+          dx=ddx/d;
+          dy=ddy/d;
+          f=5.0e2*U32_MAX/dd;
+          tmpa->dx+=f*dx;
+          tmpa->dy+=f*dy;
+        }
+
+        //Resel buddy about every ANIMALS_NUM*10ms=5.12 seconds
+        tmpa1=&a[tmpa->buddy];
+        if (tmpa1->dead || i==updates%ANIMALS_NUM) {
+          BuddySel(i);
+          tmpa1=&a[tmpa->buddy];
+        }
+
+        //Move toward buddy
+        ddx=tmpa->x.i32[1]-tmpa1->x.i32[1];
+        ddy=tmpa->y.i32[1]-tmpa1->y.i32[1];
+        if (dd=SqrI64(ddx)+SqrI64(ddy)) {
+          d=Sqrt(dd);
+          s=d`1.25-80;
+          stress+=Abs(s);
+          dx=ddx/d;
+          dy=ddy/d;
+          f=-0.001*s*U32_MAX;
+          tmpa->dx+=f*dx;
+          tmpa->dy+=f*dy;
+        }
+
+        //Make velocity similar to buddy
+        tmpa->dx+=0.1*(tmpa1->dx-tmpa->dx);
+        tmpa->dy+=0.1*(tmpa1->dy-tmpa->dy);
+
+        //Add random movement, limit speed and dampen speed
+        tmpa->dx=0.995*ClampI64(tmpa->dx+RandI32/32,-max_speed,max_speed);
+        tmpa->dy=0.995*ClampI64(tmpa->dy+RandI32/32,-max_speed,max_speed);
+
+        //Slow in river
+        if (GrPeek(map_dc,tmpa->x.i32[1],tmpa->y.i32[1])!=LTGREEN) {
+          tmpa->dx/=2;
+          tmpa->dy/=2;
+        }
+
+        if (CheckMap((tmpa->x+tmpa->dx)>>32,(tmpa->y+tmpa->dy)>>32)) {
+          tmpa->x+=tmpa->dx;
+          tmpa->y+=tmpa->dy;
+        }
+
+        //Keep on map
+        if (!(MAP_BORDER+ANIMAL_WIDTH/2
+              <=tmpa->x.i32[1]<MAP_WIDTH-MAP_BORDER-ANIMAL_WIDTH/2)) {
+          tmpa->x -=tmpa->dx;
+          tmpa->dx=-tmpa->dx;
+        }
+        if (!(MAP_BORDER+ANIMAL_HEIGHT
+              <=tmpa->y.i32[1]<MAP_HEIGHT-MAP_BORDER)) {
+          tmpa->y -=tmpa->dy;
+          tmpa->dy=-tmpa->dy;
+        }
+        cnt++;
+        if (tmpa->x>>32>=FENCE_WIDTH || tmpa->y>>32>=FENCE_HEIGHT)
+          my_outside_cnt++;
+      }
+    }
+    outside_cnt=my_outside_cnt;
+
+    if (!(updates&15))
+      RiverDropsNext(parent);
+
+    if (!tf && !outside_cnt) {
+      tf=tS;
+      music.mute=TRUE;
+      Snd(86);Sleep(200);Snd;Sleep(100);
+      if (tf-t0<best_score) {
+        best_score=tf-t0;
+        Snd(86);Sleep(200);Snd;Sleep(100);
+      }
+      music.mute=FALSE;
+    }
+
+    updates++;
+
+    if (cnt)
+      stress/=cnt;
+    else
+      stress=0;
+    if (stress>100.0) {
+      Yield;
+      max_speed=stress/5.0*U32_MAX; //Converge faster at start-up
+    } else {
+      Sleep(10);
+      max_speed=0; //Will be set to normal max speed
+    }
+  }
+}
+
+U0 SongTask(I64)
+{//Randomly generated (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5qC4etG5DC4B5DCECFqFC4sA5D4A5D4qB");
+    Play("5C4etG5DC4B5DCECFqFC4sA5D4A5D4qB");
+    Play("4sGAGA5qG4etG5GD4eBBqB5F4eBA5qE");
+    Play("4sGAGA5qG4etG5GD4eBBqB5F4eBA5qE");
+  }
+}
+
+U0 ReInit()
+{
+  I64 i;
+
+  RiverDropsDel;
+  map_dc->color=LTGREEN;
+  GrRect(map_dc,2,2,MAP_WIDTH-4,MAP_HEIGHT-4);
+
+  RiverMake;
+
+  //Plot fence
+  for (i=FENCE_WIDTH;i>0;i-=16)
+    Sprite3(map_dc,i,FENCE_HEIGHT,0,<9>);
+  map_dc->thick=1;
+  map_dc->color=BROWN;
+  for (i=0;i<FENCE_HEIGHT-16;i+=16)
+    GrLine(map_dc,FENCE_WIDTH-1,i,FENCE_WIDTH-1,i+7);
+  map_dc->color=LTGRAY;
+  GrLine(map_dc,FENCE_WIDTH,0,FENCE_WIDTH,FENCE_HEIGHT-6);
+  RedrawGate;
+
+  map_dc->thick=MAP_BORDER;
+  map_dc->color=RED;
+  GrBorder(map_dc,MAP_BORDER/2,MAP_BORDER/2,
+        MAP_WIDTH-(MAP_BORDER+1)/2,MAP_HEIGHT-(MAP_BORDER+1)/2);
+
+  for (i=MAP_BORDER;i<=MAP_HEIGHT-MAP_BORDER;i++)
+    RiverDropsNext(Fs);
+
+  MemSet(a,0,ANIMALS_NUM*sizeof(Animal));
+  for (i=0;i<ANIMALS_NUM;i++) {
+    a[i].num=i;
+    do {
+      a[i].x=(64+RandU32%(MAP_WIDTH-128))<<32;
+      a[i].y=(64+RandU32%(MAP_WIDTH-128))<<32;
+    } while (!CheckMap(a[i].x>>32,a[i].y>>32));
+    if (i&1)
+      a[i].imgs=cow_imgs;
+    else
+      a[i].imgs=bull_imgs;
+    a[i].frame0=RandU16&3;
+    BuddySel(i);
+  }
+  outside_cnt=ANIMALS_NUM;
+  gate_t=0;
+  gate_theta=0;
+  t0=tS;
+  tf=0;
+}
+
+U0 Init()
+{
+  RiverNew;
+  rd_lock=0;
+  QueInit(&rd_head);
+  map_dc=DCNew(MAP_WIDTH,MAP_HEIGHT);
+  a=MAlloc(ANIMALS_NUM*sizeof(Animal));
+  ReInit;
+}
+
+U0 CleanUp()
+{
+  DCDel(map_dc);
+  Free(a);
+  RiverDropsDel;
+  RiverDel;
+}
+
+U0 RawHide()
+{
+  I64 msg_code,arg1,arg2;
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+
+  PopUpOk(
+        "Coral the cattle.  The coral is in the\n"
+        "upper-left corner if you scroll.\n\n"
+        "Keep holding the $GREEN$<CTRL>$FG$ key and\n"
+        "scroll with $GREEN${CTRL-Left Grab}$FG$.");
+
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_SELF_GRAB_SCROLL-WIF_FOCUS_TASK_MENU;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,Fs,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_R_DOWN);
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:  //Doesn't do anything, yet.
+          break;
+        case MSG_MS_R_DOWN:  //Doesn't do anything, yet.
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              ReInit;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto rh_done;
+          }
+          break;
+      }
+    }
+rh_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/RawHide","F64 best_score=%5.4f;\n",best_score);
+}
+
+RawHide;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Rocket.HC.HTML b/public/Wb/Home/Src/Demo/Games/Rocket.HC.HTML new file mode 100755 index 0000000..5565473 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Rocket.HC.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+#define THRUST  100
+
+Bool    blast_off;
+CMass   m1, //Bottom of rocket
+        m2; //Top of rocket
+CSpring s;
+
+#define ROCKET_HEIGHT   40
+#define GROUND_Y        (GR_HEIGHT-3*FONT_HEIGHT)
+
+
+  <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+CDC     *dc2;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,x,y,cx=GR_WIDTH/2,cy=GROUND_Y;
+  Bool engine_on;
+  F64 nozzle_angle,theta=Arg(m2.x-m1.x,m2.y-m1.y);
+
+  Sprite3(dc,0,GROUND_Y,0,<2>);
+
+  if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) {
+    nozzle_angle=0;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+    nozzle_angle=pi/8;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+    nozzle_angle=-pi/8;
+    engine_on=TRUE;
+  } else
+    engine_on=FALSE;
+
+  if (engine_on) {
+    x=m1.x-10*Cos(theta+nozzle_angle);
+    y=m1.y-10*Sin(theta+nozzle_angle);
+    for (i=0;i<6;i++) {
+      if ((i^winmgr.updates)&1)
+        dc->color=YELLOW;
+      else
+        dc->color=RED;
+      GrLine(dc,cx+(m1.x+i*Cos(theta-pi/2)),cy-(m1.y+i*Sin(theta-pi/2)),cx+x,cy-y);
+      GrLine(dc,cx+(m1.x+i*Cos(theta+pi/2)),cy-(m1.y+i*Sin(theta+pi/2)),cx+x,cy-y);
+    }
+
+    for (i=0;i<10;i++) {
+      switch (RandU16&3) {
+        case 0: dc2->color=WHITE;       break;
+        case 1: dc2->color=LTGRAY;      break;
+        case 2: dc2->color=DKGRAY;      break;
+        case 3: dc2->color=BLACK;       break;
+      }
+      GrPlot(dc2,cx+(x+RandU16%12-6),cy-(y+RandU16%12-6));
+    }
+    Snd(22);
+  } else
+    Snd;
+  Sprite3ZB(dc,cx+(m1.x+m2.x)/2,cy-(m1.y+m2.y)/2,0,<1>,-theta);
+}
+
+U0 MyDerivative(CMathODE *,F64,COrder2D3 *,COrder2D3 *)
+{
+  Bool engine_on;
+  F64 nozzle_angle,theta=Arg(m2.state->x-m1.state->x,m2.state->y-m1.state->y);
+
+  if (Bt(kbd.down_bitmap,SC_CURSOR_UP)) {
+    nozzle_angle=0;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_LEFT)) {
+    nozzle_angle=pi/8;
+    engine_on=TRUE;
+  } else if (Bt(kbd.down_bitmap,SC_CURSOR_RIGHT)) {
+    nozzle_angle=-pi/8;
+    engine_on=TRUE;
+  } else
+    engine_on=FALSE;
+
+  if (engine_on) {
+    m1.DstateDt->DxDt+=THRUST*Cos(theta+nozzle_angle);
+    m1.DstateDt->DyDt+=THRUST*Sin(theta+nozzle_angle);
+  }
+  if (blast_off) {
+    m1.DstateDt->DyDt-=25; //Gravity
+    m2.DstateDt->DyDt-=25;
+  }
+}
+
+U0 Init()
+{
+  DocClear;
+  "$BG,LTCYAN$$GREEN$Up, Left, Right$FG$%h*c",ToI64(GROUND_Y/FONT_HEIGHT),'\n';
+
+  blast_off=FALSE;
+
+  //We don't clear que links.
+  MemSet(&m1.start,0,offset(CMass.end)-offset(CMass.start));
+  m1.y=0;
+
+  MemSet(&m2.start,0,offset(CMass.end)-offset(CMass.start));
+  m2.y=ROCKET_HEIGHT;
+
+  MemSet(&s.start,0,offset(CSpring.end)-offset(CSpring.start));
+  s.end1=&m1;
+  s.end2=&m2;
+  s.rest_len=ROCKET_HEIGHT;
+  s.const=10000;
+
+  DCFill;
+}
+
+U0 TaskEndCB()
+{
+  DCFill;
+  SndTaskEndCB;
+}
+
+U0 Rocket()
+{
+  CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES);
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Up(,,SC_CURSOR_UP);"
+        "  UpLeft(,,SC_CURSOR_LEFT);"
+        "  UpRight(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  dc2=DCAlias;
+  Fs->task_end_cb=&TaskEndCB;
+
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  Init;
+  QueIns(&m1,ode->last_mass);
+  QueIns(&m2,ode->last_mass);
+  QueIns(&s,ode->last_spring);
+
+  QueIns(ode,Fs->last_ode);
+
+  Fs->draw_it=&DrawIt;
+
+  try {
+    GetKey;
+    blast_off=TRUE;
+    while (TRUE) {
+      switch (GetChar(,FALSE)) {
+        case '\n':
+          Init;
+          GetKey;
+          blast_off=TRUE;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto rk_done;
+      }
+    }
+rk_done:
+  } catch
+    PutExcept;
+  QueRem(ode);
+  ODEDel(ode);
+  DocClear;
+  SettingsPop;
+  DCFill;
+  DCDel(dc2);
+  MenuPop;
+}
+
+Rocket;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/RocketScience.HC.HTML b/public/Wb/Home/Src/Demo/Games/RocketScience.HC.HTML new file mode 100755 index 0000000..c22ceb6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/RocketScience.HC.HTML @@ -0,0 +1,328 @@ + + + + + + + + + + + +
+#define THRUST  1000
+
+Bool    blast_off,plane_hit;
+
+CMass   m1, //Bottom of rocket
+        m2, //Top of rocket
+        m3; //Plane
+CSpring s;
+
+#define ROCKET_HEIGHT   40
+#define GROUND_Y        (GR_HEIGHT-3*FONT_HEIGHT)
+
+
+   <1>/* Graphics Not Rendered in HTML */
+
+
+
+   <2>/* Graphics Not Rendered in HTML */
+
+
+
+  <3>/* Graphics Not Rendered in HTML */
+ 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+CDC     *dc2;
+CMathODE *ode;
+
+#define STATE_NOZZLE_ANGLE              0
+#define STATE_NOZZLE_ANGLE_VELOCITY     1
+#define STATE_NUM                       2
+
+CD3     target;
+F64     my_dbg,antispin_coefficient;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,x,y,cx=GR_WIDTH/2,cy=GROUND_Y;
+  F64 theta=Arg(m2.x-m1.x,m2.y-m1.y),
+        nozzle_angle=ode->state[STATE_NOZZLE_ANGLE];
+
+  if (blast_off) {
+    x=m1.x-10*Cos(theta+nozzle_angle);
+    y=m1.y-10*Sin(theta+nozzle_angle);
+    for (i=0;i<6;i++) {
+      if ((i^winmgr.updates)&1)
+        dc->color=YELLOW;
+      else
+        dc->color=RED;
+      GrLine(dc,cx+(m1.x+i*Cos(theta-pi/2)),cy-(m1.y+i*Sin(theta-pi/2)),cx+x,cy-y);
+      GrLine(dc,cx+(m1.x+i*Cos(theta+pi/2)),cy-(m1.y+i*Sin(theta+pi/2)),cx+x,cy-y);
+    }
+
+    for (i=0;i<10;i++) {
+      switch (RandU16&3) {
+        case 0: dc2->color=WHITE;       break;
+        case 1: dc2->color=LTGRAY;      break;
+        case 2: dc2->color=DKGRAY;      break;
+        case 3: dc2->color=BLACK;       break;
+      }
+      GrPlot(dc2,cx+(x+RandU16%12-6),cy-(y+RandU16%12-6));
+    }
+  }
+
+  if (plane_hit)
+    Sprite3(dc,cx+m3.x,cy-m3.y,0,<2>);
+  else
+    Sprite3(dc,cx+m3.x,cy-m3.y,0,<1>);
+
+  if (blast_off && !plane_hit) {
+    dc->color=ROP_COLLISION;
+    dc->bkcolor=LTCYAN;
+    dc->collision_cnt=0;
+    Sprite3ZB(dc,cx+(m1.x+m2.x)/2,cy-(m1.y+m2.y)/2,0,<3>,-theta);
+    if (dc->collision_cnt>100) {
+      Noise(1000,62,81);
+      plane_hit=TRUE;
+    } else
+      Snd(22);
+  } else if (!plane_hit)
+    Snd;
+
+  dc->color=ROP_EQU;
+  Sprite3(dc,0,GROUND_Y,0,<4>);
+  Sprite3ZB(dc,cx+(m1.x+m2.x)/2,cy-(m1.y+m2.y)/2,0,<3>,-theta);
+
+  dc->color=RED;
+  GrCircle(dc,cx+target.x,cy-target.y,5);
+
+  dc->color=BLUE;
+  GrCircle(dc,cx+m3.x,cy-m3.y,5);
+
+  dc->color=BLACK;
+  GrPrint(dc,0,FONT_HEIGHT,"%12.6f",my_dbg);
+}
+
+U0 MyDerivative(CMathODE *,F64,F64 *state,F64 *DstateDt)
+{
+  F64 d,discriminant,v,a,theta=Arg(m2.state->x-m1.state->x,m2.state->y-m1.state->y),
+        DthetaDt,collision_estimate_t,target_heading,target_angle_error,
+        desired_nozzle_angle;
+  CD3 p,p_target,p_body;
+
+  //Unit vect pointing to top of rocket from bottom.
+  D3Sub(&p_body,&m2.state->x,&m1.state->x);
+  D3Unit(&p_body);
+
+  //DthetaDt lets us prevent too much spin.
+  DthetaDt=antispin_coefficient*
+        (m2.state->DyDt*p_body.x-m2.state->DxDt*p_body.y-
+        m1.state->DyDt*p_body.x+m1.state->DxDt*p_body.y)/ROCKET_HEIGHT;
+
+  //p_target is vect from top of rocket to plane.
+  D3Sub(&p_target,&m3.state->x,&m2.state->x);
+
+  //d=0.5at^2+vt
+  d=D3Norm(&p_target);
+
+  D3Copy(&p,&p_target);
+  D3Unit(&p);
+  v=(m2.state->DxDt*p.x+m2.state->DyDt*p.y)-
+        (m3.state->DxDt*p.x+m3.state->DyDt*p.y);
+
+  a=THRUST/(m1.mass+m2.mass);
+
+  discriminant=v*v+4*0.5*a*d;
+  if (discriminant>0)
+    collision_estimate_t=(-v+Sqrt(discriminant))/a;
+  else
+    collision_estimate_t=0;
+  my_dbg=collision_estimate_t;
+
+  //Aim for projected pos of plane at time of impact.
+  D3Copy(&p,&m3.state->DxDt);
+  D3MulEqu(&p,collision_estimate_t);
+  D3AddEqu(&p_target,&p);
+
+  D3Copy(&target,&p_target);
+  D3AddEqu(&target,&m2.state->x);
+
+  target_heading=Arg(p_target.x,p_target.y);
+  target_angle_error=Wrap(theta-target_heading); //Force to range [-pi,pi)
+  desired_nozzle_angle=Clamp(50.0*DthetaDt+750*target_angle_error,-pi/8,pi/8);
+
+  //For realism we limit the speed the nozzle angle can change.
+  DstateDt[STATE_NOZZLE_ANGLE]=state[STATE_NOZZLE_ANGLE_VELOCITY];
+  DstateDt[STATE_NOZZLE_ANGLE_VELOCITY]=
+        Clamp(10000*(desired_nozzle_angle-state[STATE_NOZZLE_ANGLE]),
+        -1000,1000)-10.0*state[STATE_NOZZLE_ANGLE_VELOCITY]; //Damping
+
+  if (blast_off) {
+    m1.DstateDt->DxDt+=THRUST*Cos(theta+state[STATE_NOZZLE_ANGLE]);
+    m1.DstateDt->DyDt+=THRUST*Sin(theta+state[STATE_NOZZLE_ANGLE]);
+
+    m1.DstateDt->DyDt-=25; //Gravity
+    m2.DstateDt->DyDt-=25;
+  }
+
+  //For more realism reduce the mass of the rocket because of fuel.
+  //You might also factor-in fuel slosh in the tank.
+
+  //To do this, you would have to set-up state vars for mass and
+  //do A=F/m manually instead of relyin on ODECallDerivative() to divide
+  //by mass.
+}
+
+U0 Init()
+{
+  DocClear;
+  "$BG,LTCYAN$%h*c",ToI64(GROUND_Y/FONT_HEIGHT),'\n';
+
+  blast_off=FALSE;
+  plane_hit=FALSE;
+
+  do antispin_coefficient=PopUpRangeF64Exp(0.1,10.001,Sqrt(10),
+          "%9.4f","Anti-spin Coefficient\n\n");
+  while (!(0.1<=antispin_coefficient<10.001));
+
+  //We don't clear que links.
+  MemSet(&m1.start,0,offset(CMass.end)-offset(CMass.start));
+  m1.y=0;
+  m1.mass=1.0;
+
+  MemSet(&m2.start,0,offset(CMass.end)-offset(CMass.start));
+  m2.y=ROCKET_HEIGHT;
+  m2.mass=1.0;
+
+  MemSet(&m3.start,0,offset(CMass.end)-offset(CMass.start));
+  m3.y=400;
+  m3.x=-300;
+  m3.DxDt=50;
+  m3.mass=1.0;
+
+  MemSet(&s.start,0,offset(CSpring.end)-offset(CSpring.start));
+  s.end1=&m1;
+  s.end2=&m2;
+  s.rest_len=ROCKET_HEIGHT;
+  s.const=10000;
+
+  ode->state[STATE_NOZZLE_ANGLE]=0;
+  ode->state[STATE_NOZZLE_ANGLE_VELOCITY]=0;
+
+  DCFill;
+}
+
+U0 TaskEndCB()
+{
+  DCFill;
+  SndTaskEndCB;
+}
+
+U0 RocketScience()
+{
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Launch(,CH_SPACE);"
+        "}"
+        );
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  dc2=DCAlias;
+  Fs->task_end_cb=&TaskEndCB;
+
+  ode=ODENew(STATE_NUM,1e-6,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  //  ode->t_scale=0.1; //Uncomment this to go in slow motion.
+
+  Init;
+  QueIns(&m1,ode->last_mass);
+  QueIns(&m2,ode->last_mass);
+  QueIns(&m3,ode->last_mass);
+  QueIns(&s,ode->last_spring);
+
+  QueIns(ode,Fs->last_ode);
+
+  Fs->draw_it=&DrawIt;
+
+  try {
+    GetKey;
+    blast_off=TRUE;
+    while (TRUE) {
+      switch (GetChar(,FALSE)) {
+        case '\n':
+          Init;
+          GetKey;
+          blast_off=TRUE;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto rs_done;
+      }
+    }
+rs_done:
+  } catch
+    PutExcept;
+  QueRem(ode);
+  ODEDel(ode);
+  DocClear;
+  SettingsPop;
+  DCFill;
+  DCDel(dc2);
+  MenuPop;
+}
+
+RocketScience;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Squirt.HC.HTML b/public/Wb/Home/Src/Demo/Games/Squirt.HC.HTML new file mode 100755 index 0000000..d345f52 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Squirt.HC.HTML @@ -0,0 +1,415 @@ + + + + + + + + + + + +
+#define MT_HOSE         1
+#define MT_DROPLET      2
+class MyMass:CMass
+{
+  I64 type;
+  F64 radius;
+};
+
+#define ST_HOSE         1
+class MySpring:CSpring
+{
+  I64 type;
+};
+
+
+
+        <1>/* Graphics Not Rendered in HTML */
+
+        <2>/* Graphics Not Rendered in HTML */
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+#define HOSE_RADIUS     3
+#define LINK_SIZE       6
+#define NOZZLE_START_Y  (GR_HEIGHT-15*FONT_HEIGHT)
+#define NOZZLE_LEN      18
+#define FAUCET_X        (5*HOSE_RADIUS)
+#define FAUCET_Y        (GR_HEIGHT-12*FONT_HEIGHT)
+#define GROUND_Y        (GR_HEIGHT-3*FONT_HEIGHT)
+MyMass *faucet,*nozzle;
+F64 nozzle_theta;
+
+CMathODE *ode=NULL;
+F64 start_up_timeout;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  Bool first;
+  F64 dx,dy,d;
+  I64  x1b,y1b,x2b,y2b,
+        x1a,y1a,x2a,y2a;
+  MyMass   *tmpm,*tmpm1;
+  MySpring *tmps;
+  CD3I32 poly[4];
+
+  Sprite3(dc,0,GROUND_Y,0,<4>);
+  if (start_up_timeout>tS) {
+    ode->drag_v2=0.01; //Let hose settle during start-up
+    ode->drag_v3=0.0001;
+    dc->color=RED;
+    GrPrint(dc,(GR_WIDTH-FONT_WIDTH*6)>>1,GR_HEIGHT>>1,"Squirt");
+    return;
+  } else {
+    ode->drag_v2=0.0005;
+    ode->drag_v3=0.0000025;
+  }
+
+  tmpm=faucet;
+  dc->color=BLACK;
+  GrRect(dc,tmpm->x+8,tmpm->y,8,GROUND_Y-FAUCET_Y);
+  Sprite3(dc,tmpm->x,tmpm->y,0,<1>);
+  dc->color=BLACK;
+  GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+  dc->color=GREEN;
+  GrFloodFill(dc,tmpm->x,tmpm->y);
+
+  tmpm=nozzle;
+  tmpm1=nozzle->last;
+  dx=tmpm->x-tmpm1->x;
+  dy=tmpm->y-tmpm1->y;
+  nozzle_theta=Wrap(Arg(dx,dy));
+  Sprite3ZB(dc,tmpm->x,tmpm->y,0,<2>,nozzle_theta);
+  dc->color=BLACK;
+  GrCircle(dc,tmpm->x,tmpm->y,tmpm->radius);
+  dc->color=GREEN;
+  GrFloodFill(dc,tmpm->x,tmpm->y);
+
+  first=TRUE;
+  tmpm=ode->next_mass;
+  while (tmpm!=&ode->next_mass) {
+    if (tmpm->type==MT_HOSE) {
+      tmpm1=tmpm->last;
+      dx=tmpm->x-tmpm1->x;
+      dy=tmpm->y-tmpm1->y;
+      d=HOSE_RADIUS/Max(Sqrt(dx*dx+dy*dy),0.001);
+      dx*=d;
+      dy*=d;
+      x2a=tmpm->x-dy;
+      y2a=tmpm->y+dx;
+      x2b=tmpm->x+dy;
+      y2b=tmpm->y-dx;
+
+      if (first)
+        first=FALSE;
+      else {
+        dc->color=GREEN;
+        poly[0].x=x1a;
+        poly[0].y=y1a;
+        poly[0].z=0;
+        poly[1].x=x2a;
+        poly[1].y=y2a;
+        poly[1].z=0;
+        poly[2].x=x2b;
+        poly[2].y=y2b;
+        poly[2].z=0;
+        poly[3].x=x1b;
+        poly[3].y=y1b;
+        poly[3].z=0;
+        GrFillPoly3(dc,4,poly);
+      }
+
+      //Fill gaps
+      GrLine(dc,x2a,y2a,x2b,y2b);
+
+      x1a=x2a;
+      y1a=y2a;
+      x1b=x2b;
+      y1b=y2b;
+    } else if (tmpm->type==MT_DROPLET)
+      Sprite3(dc,tmpm->x,tmpm->y,0,<3>);
+    tmpm=tmpm->next;
+  }
+
+  tmps=ode->next_spring;
+  while (tmps!=&ode->next_spring) {
+    if (tmps->type==ST_HOSE) {
+      dx=tmps->end1->x-tmps->end2->x;
+      dy=tmps->end1->y-tmps->end2->y;
+      d=HOSE_RADIUS/Max(Sqrt(dx*dx+dy*dy),0.001);
+      dx*=d;
+      dy*=d;
+      dc->color=BLACK;
+      GrLine(dc,tmps->end1->x-dy,tmps->end1->y+dx,
+            tmps->end2->x-dy,tmps->end2->y+dx);
+      GrLine(dc,tmps->end1->x+dy,tmps->end1->y-dx,
+            tmps->end2->x+dy,tmps->end2->y-dx);
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *state,COrder2D3 *DstateDt)
+{//The forces due to springs and drag are
+//automatically handled by the
+  //ode code.  We can add new forces
+  //here.
+  no_warn t,state,DstateDt;
+  MyMass *tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    if (tmpm1->type==MT_HOSE) {
+      if (tmpm1->state->y+tmpm1->radius>GROUND_Y)
+        tmpm1->DstateDt->DyDt-=Sqr(Sqr(tmpm1->state->y+
+              tmpm1->radius-GROUND_Y))*tmpm1->mass;
+      else
+        tmpm1->DstateDt->DyDt+=500*tmpm1->mass;
+      if (tmpm1==nozzle || tmpm1==faucet) {
+        tmpm1->DstateDt->DxDt=0;
+        tmpm1->DstateDt->DyDt=0;
+      }
+    } else if (tmpm1->type==MT_DROPLET)
+      tmpm1->DstateDt->DyDt=500*tmpm1->mass;
+    tmpm1=tmpm1->next;
+  }
+}
+
+MyMass *PlaceMass(I64 type,I64 x, I64 y,F64 r,
+        F64 dx,F64 dy,F64 mass,CTask *mem_task)
+{
+  MyMass *tmpm=CAlloc(sizeof(MyMass),mem_task);
+  tmpm->type=type;
+  tmpm->mass=mass;
+  tmpm->drag_profile_factor=250.0;
+  tmpm->x=x;
+  tmpm->y=y;
+  tmpm->DxDt=dx;
+  tmpm->DyDt=dy;
+  tmpm->radius=r;
+  QueIns(tmpm,ode->last_mass);
+  return tmpm;
+}
+
+MySpring PlaceSpring(MyMass *tmpm1,MyMass *tmpm2)
+{
+  MySpring *tmps=CAlloc(sizeof(MySpring));
+  tmps->end1=tmpm1;
+  tmps->end2=tmpm2;
+  tmps->const=20000;
+  QueIns(tmps,ode->last_spring);
+  return tmps;
+}
+
+U0 HoseNew()
+{
+  I64 i;
+  MyMass *tmpm1=NULL,*tmpm;
+  MySpring *tmps;
+  for (i=FAUCET_X;i<GR_WIDTH;i+=LINK_SIZE) {
+    tmpm=PlaceMass(MT_HOSE,i/2,GROUND_Y-HOSE_RADIUS,HOSE_RADIUS,0,0,1.0,Fs);
+    if (tmpm1) {
+      tmps=PlaceSpring(tmpm,tmpm1);
+      tmps->rest_len=LINK_SIZE;
+      tmps->type=ST_HOSE;
+      nozzle=tmpm;
+    } else
+      faucet=tmpm;
+    tmpm1=tmpm;
+  }
+  faucet->y=FAUCET_Y;
+  nozzle->y=NOZZLE_START_Y;
+  nozzle_theta=0;
+}
+
+U0 AnimateTask(I64)
+{
+  MyMass   *tmpm,*tmpm1;
+  F64 dx,dy;
+  while (TRUE) {
+    dx=Cos(nozzle_theta);
+    dy=Sin(nozzle_theta);
+    PlaceMass(MT_DROPLET,
+          nozzle->x+NOZZLE_LEN*dx,nozzle->y+NOZZLE_LEN*dy,HOSE_RADIUS,
+          500*dx,500*dy,100.0,Fs->parent_task);
+    if (Rand<0.05) //faucet drip
+      PlaceMass(MT_DROPLET,
+            faucet->x,faucet->y,HOSE_RADIUS,
+            0,0,100.0,Fs->parent_task);
+
+    tmpm=ode->next_mass;
+    while (tmpm!=&ode->next_mass) {
+      tmpm1=tmpm->next;
+      if (tmpm->type==MT_DROPLET && tmpm->y+tmpm->radius>GROUND_Y) {
+        QueRem(tmpm);
+        Free(tmpm);
+      }
+      tmpm=tmpm1;
+    }
+    Refresh;
+  }
+}
+
+#define NOZZLE_MOVE_STEPS       5
+#define NOZZLE_MOVE             15.0
+U0 MoveNozzleTaskX(I64 sign)
+{
+  I64 i;
+  for (i=0;i<NOZZLE_MOVE_STEPS;i++) {
+    nozzle->x=Clamp(nozzle->x+sign*NOZZLE_MOVE/NOZZLE_MOVE_STEPS,
+          HOSE_RADIUS*3,GR_WIDTH-HOSE_RADIUS*3);
+    Refresh;
+  }
+}
+
+U0 MoveNozzleTaskY(I64 sign)
+{
+  I64 i;
+  for (i=0;i<NOZZLE_MOVE_STEPS;i++) {
+    nozzle->y=Clamp(nozzle->y+sign*NOZZLE_MOVE/NOZZLE_MOVE_STEPS,
+          HOSE_RADIUS*3,GROUND_Y);
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  DocClear;
+  "$BG,LTCYAN$%h*c",ToI64(GROUND_Y/FONT_HEIGHT),'\n';
+
+  //Allow hose to settle.
+  start_up_timeout=tS+0.5;
+
+  ode=ODENew(0,5e-2,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->acceleration_limit=5e3;
+
+  HoseNew;
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  Refresh(NOZZLE_MOVE_STEPS); //Let nozzle move tasks die
+  QueRem(ode);
+  QueDel(&ode->next_mass,TRUE);
+  QueDel(&ode->next_spring,TRUE);
+  ODEDel(ode);
+  DocClear;
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5sDCDC4qA5DetDFFeDG4etA5EF4qG5eFC");
+    Play("5sDCDC4qA5DetDFFeDG4etA5EF4qG5eFC");
+    Play("5DCsG4A5G4AqBeBA5qEE4B5eC4B");
+    Play("5DCsG4A5G4AqBeBA5qEE4B5eC4B");
+  }
+}
+
+U0 Squirt()
+{
+  I64 sc;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "}"
+        );
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              Spawn(&MoveNozzleTaskX,-1,"Move Nozzle",,Fs);
+              break;
+            case SC_CURSOR_RIGHT:
+              Spawn(&MoveNozzleTaskX,1,"Move Nozzle",,Fs);
+              break;
+            case SC_CURSOR_UP:
+              Spawn(&MoveNozzleTaskY,-1,"Move Nozzle",,Fs);
+              break;
+            case SC_CURSOR_DOWN:
+              Spawn(&MoveNozzleTaskY,1,"Move Nozzle",,Fs);
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto sq_done;
+      }
+    }
+sq_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+Squirt;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Stadium/Stadium.HC.HTML b/public/Wb/Home/Src/Demo/Games/Stadium/Stadium.HC.HTML new file mode 100755 index 0000000..b126114 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Stadium/Stadium.HC.HTML @@ -0,0 +1,165 @@ + + + + + + + + + + + +
+/*This shows how you can make a
+background very easily.
+*/
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+<2>/* Graphics Not Rendered in HTML */
+
+CDC *background;
+
+#define BALL_TIME       0.2
+#define FANS_NUM 10
+I64 x[FANS_NUM],y[FANS_NUM];
+Bool hit[FANS_NUM];
+F64 theta[FANS_NUM],ball_t;
+I64 target_x,target_y,pitcher_x,pitcher_y;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i,*r;
+  F64 xx,yy,t0;
+  background->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,0,0,background);
+  for (i=0;i<FANS_NUM;i++)
+    Sprite3ZB(dc,x[i],y[i],0,<fan>,theta[i]);
+  if (ball_t) {
+    t0=(tS-ball_t)/BALL_TIME;
+    if (t0>1.0)
+      ball_t=0;
+    else {
+      xx=t0*target_x+(1.0-t0)*pitcher_x;
+      yy=t0*target_y+(1.0-t0)*pitcher_y;
+      xx/=1.5-t0;
+      yy/=1.5-t0;
+      r=Mat4x4New(dc->r,dc->mem_task);
+      Mat4x4Scale(r,1.5-t0);
+      Free(dc->r);
+      DCMat4x4Set(dc,r);
+      dc->flags|=DCF_TRANSFORMATION;
+      Sprite3ZB(dc,xx,yy,0,<ball>,t0);
+    }
+  }
+  dc->color=RED;
+  GrPrint(dc,FONT_WIDTH,FONT_HEIGHT,"Peg the Fans");
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  F64 xx,yy,t0;
+  while (TRUE) {
+    if (ball_t) {
+      t0=(tS-ball_t)/BALL_TIME;
+      xx=t0*target_x+(1.0-t0)*pitcher_x;
+      yy=t0*target_y+(1.0-t0)*pitcher_y;
+    }
+    for (i=0;i<FANS_NUM;i++) {
+      if (ball_t)
+        if (Sqr(x[i]-xx)+Sqr(y[i]-yy)<200) {
+          hit[i]=TRUE;
+          theta[i]=-pi/2;
+        }
+      if (!hit[i]) {
+        x[i]+=SignI64(RandI16);
+        y[i]+=SignI64(RandI16);
+        theta[i]+=Sign(RandI16)/25.0;
+        if (!(0<=x[i]<GR_WIDTH)) x[i]=GR_WIDTH/2;
+        if (!(10<=y[i]<100)) y[i]=50;
+        if (!(-0.75<=theta[i]<0.75)) theta[i]=0;
+      }
+    }
+    Sleep(10);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<FANS_NUM;i++) {
+    x[i]=RandU16%GR_WIDTH;
+    y[i]=50;
+    theta[i]=0;
+    hit[i]=FALSE;
+  }
+}
+
+U0 Stadium()
+{
+  I64 msg_code,arg1,arg2,ch=0;
+
+  SettingsPush; //See SettingsPush
+  Cd(__DIR__);
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+
+  background=GRRead("StadiumBG");
+  Fs->draw_it=&DrawIt;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
+    if (msg_code==MSG_KEY_DOWN) {
+      ch=arg1;
+      if (ch=='\n')
+        Init;
+    } else {
+      target_x=arg1; target_y=arg2;
+      pitcher_x=GR_WIDTH/2; pitcher_y=GR_HEIGHT;
+      ball_t=tS;
+    }
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  GetMsg(,,1<<MSG_KEY_UP);
+
+  DCDel(background);
+  SettingsPop;
+  MenuPop;
+}
+
+Stadium;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Stadium/StadiumBG.DD.HTML b/public/Wb/Home/Src/Demo/Games/Stadium/StadiumBG.DD.HTML new file mode 100755 index 0000000..b5bae83 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Stadium/StadiumBG.DD.HTML @@ -0,0 +1,32 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+ diff --git a/public/Wb/Home/Src/Demo/Games/Stadium/StadiumGen.HC.HTML b/public/Wb/Home/Src/Demo/Games/Stadium/StadiumGen.HC.HTML new file mode 100755 index 0000000..88694de --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Stadium/StadiumGen.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+//Generate "StadiumBG.GR.Z" from "StadiumBG.DD.Z"
+
+U0 StadiumGen()
+{
+  U0 (*fp_old_update)(CDC *dc);
+  CDC *dc,*dc2;
+
+  Cd(__DIR__);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor(OFF);
+  DocClear;
+  Type("StadiumBG.DD");
+  "$CM,0,%d$",TEXT_ROWS-3;
+  fp_old_update=gr.fp_final_scrn_update; //hide mouse cursor
+  gr.fp_final_scrn_update=NULL;
+
+  Refresh(2,TRUE);
+  dc2=DCScrnCapture;
+  dc=DCExt(dc2,0,FONT_HEIGHT,GR_WIDTH,GR_HEIGHT);
+  DCDel(dc2);
+
+  GRWrite("StadiumBG",dc,DCSF_COMPRESSED|DCSF_PALETTE_GET);
+  DCDel(dc);
+
+  DocCursor(ON);
+  gr.fp_final_scrn_update=fp_old_update;
+  DocClear;
+}
+
+StadiumGen;
+
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Talons.HC.HTML b/public/Wb/Home/Src/Demo/Games/Talons.HC.HTML new file mode 100755 index 0000000..b5e58a3 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Talons.HC.HTML @@ -0,0 +1,1264 @@ + + + + + + + + + + + +
+//Uses fixed-point.
+
+RegDft("TempleOS/Talons","F64 best_score=9999;\n");
+RegExe("TempleOS/Talons");
+
+//Keep these power of two so shift is used instead of multiply
+//to index arrays.
+#define MAP_WIDTH               1024
+#define MAP_HEIGHT              1024
+
+#define MAP_SCALE               150
+#define DISPLAY_SCALE           100
+#define CTRLS_SCALE             0.05
+
+//I think I did these so the heads-up showed intelligable numbers.
+//Scaling is a mess.
+#define COORDINATE_SCALE        256
+#define COORDINATE_BITS         8
+
+#define WATER_ELEVATION         15
+#define BIRD_ELEVATION          10
+#define ROCK_ELEVATION          45
+#define SNOW_ELEVATION          55
+
+//Too big makes off-scrn draws take place.
+#define PANEL_SIZE_MAX          16
+
+
+
+
+
+                        <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                        <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+#define LS_TYPES        3
+U8      *landscape_small_imgs[LS_TYPES]={<4>,<5>,<6>},
+        *landscape_large_imgs[LS_TYPES];
+
+#define B_NUM   256
+class Bird
+{
+  Bird *next,*last;
+  CD3I64 p;
+  F64 theta;
+} b_head[mp_cnt];
+
+class Obj
+{
+  Obj *next,*last;
+  CD3I64 p;
+  U8 *img;
+  Bool fish;
+};
+
+class Panel
+{//Polygon or Obj
+  Panel *next;
+  CD3I32 *pts;
+  I64 cnt;
+  U16 update,num_sides;
+  CColorROPU32 color;
+  Obj *next_obj,*last_obj;
+} *panel_head,*panels[MAP_HEIGHT][MAP_WIDTH];
+
+I64 critical_section_flag;
+I16 elevations[MAP_HEIGHT][MAP_WIDTH];
+CD3 normals[MAP_HEIGHT][MAP_WIDTH];
+
+class MPCtrl {
+  I64 init_not_done_flags,update_not_done_flags,app_not_done_flags;
+  I64 strip_width[MP_PROCESSORS_NUM];
+  Bool app_done;
+} mp;
+
+F64 game_t0,game_tf,pitch,roll,heading,phi,speed;
+Bool invert_pitch,rolled_over;
+I64 strip_height,x,y,z,fish_left;
+CD3 v;
+
+U0 WrapAngles()
+{
+  I64 r[4][4],x,y,z;
+
+  phi=Wrap(phi);
+  pitch=Wrap(-phi-pi/2);
+  if (Abs(pitch)>pi/2) {
+    invert_pitch=TRUE;
+    pitch=Wrap(pi-pitch);
+  } else
+    invert_pitch=FALSE;
+  roll=Wrap(roll);
+  if (invert_pitch ^^ -pi/2<=roll<pi/2)
+    rolled_over=FALSE;
+  else
+    rolled_over=TRUE;
+  heading=Wrap(heading,0);
+
+  //World to scrn coordinates
+  Mat4x4IdentEqu(r);
+  Mat4x4RotZ(r,heading);
+  Mat4x4RotX(r,phi);
+  Mat4x4RotZ(r,roll);
+
+  //We use velocity vector for dog-fighting.
+  x=0x100000000*speed; y=0; z=0;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  v.x=x/ToF64(0x100000000); v.y=y/ToF64(0x100000000); v.z=z/ToF64(0x100000000);
+}
+
+U0 EDTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  *z=zz=-*z;
+  if (zz>0) {
+    *x = dc->x + *x * DISPLAY_SCALE/zz; //Foreshortening
+    *y = dc->y - *y * DISPLAY_SCALE/zz;
+  } else {
+    *x = dc->x + *x;
+    *y = dc->y - *y;
+  }
+}
+
+U0 CalcNormals()
+{/*Find the normal vect with a curl.
+
+i,j and k are the axis unit vectors,
+not to be confused with my local index variables.
+
+i  j  k
+0  1  dz2
+1  0  dz1
+
+Normal:  dz1*i + dz2*j - k
+*/
+  I64 i,j;
+  for (j=0;j<MAP_HEIGHT-1;j++) {
+    for (i=0;i<MAP_WIDTH-1;i++) {
+      normals[j][i].x=elevations[j][i+1]-elevations[j][i];
+      normals[j][i].y=elevations[j+1][i]-elevations[j][i];
+      normals[j][i].z=-1;
+      D3Unit(&normals[j][i]);
+    }
+    MemSet(&normals[j][i],0,sizeof(CD3));
+  }
+  for (i=0;i<MAP_WIDTH-1;i++)
+    MemSet(&normals[j][i],0,sizeof(CD3));
+}
+
+Bool TestSameSlope(I64 x,I64 y,I64 w,I64 h)
+{
+  CD3 p,*s;
+  I64 k1,k2;
+  if (!(0<=x && x+w<MAP_WIDTH && 0<=y && y+h<MAP_HEIGHT))
+    return FALSE;
+  s=&normals[y][x];
+  for (k2=0;k2<h;k2++)
+    for (k1=0;k1<w;k1++)
+      if (D3NormSqr(D3Sub(&p,&normals[y+k2][x+k1],s))>.10)
+        return FALSE;
+  return TRUE;
+}
+
+U0 MPDoPanels(CTask *task)
+{
+  I64 i,j,l,k1,k2,w,h,threshold,lo,hi;
+  Bool cont;
+  Panel *tmpp,*start_ptr=NULL,*end_ptr=NULL;
+  CD3I32 *poly;
+  Obj *tmpo;
+  lo=Gs->num*(MAP_HEIGHT-1)/mp_cnt;
+  hi=(Gs->num+1)*(MAP_HEIGHT-1)/mp_cnt;
+  for (threshold=8;threshold>=1;threshold--)
+    for (j=lo;j<hi;j++) {
+      for (i=0;i<MAP_WIDTH-1;i++) {
+        if (!panels[j][i]) {
+          w=1;
+          h=1;
+          do {
+            cont=FALSE;
+            if (w<PANEL_SIZE_MAX && TestSameSlope(i,j,w+1,h)) {
+              w++;
+              cont=TRUE;
+            }
+            if (h<PANEL_SIZE_MAX && TestSameSlope(i,j,w,h+1)) {
+              h++;
+              cont=TRUE;
+            }
+          } while (cont);
+          if (w>=threshold || h>=threshold) {
+            tmpp=CAlloc(sizeof(Panel),task);
+            QueInit(&tmpp->next_obj);
+            l=elevations[j][i];
+            if (l<=WATER_ELEVATION*MAP_SCALE &&
+                  elevations[j][i+w-1]<=WATER_ELEVATION*MAP_SCALE &&
+                  elevations[j+h-1][i]<=WATER_ELEVATION*MAP_SCALE &&
+                  elevations[j+h-1][i+w-1]<=WATER_ELEVATION*MAP_SCALE) {
+              tmpp->color=BLUE;
+              if (Rand<0.05) {
+                tmpo=MAlloc(sizeof(Obj),task);
+                tmpo->p.x=(i+w/2)*MAP_SCALE;
+                tmpo->p.y=(j+h/2)*MAP_SCALE;
+                if (Rand<0.1) {
+                  tmpo->fish=FALSE;
+                  if (RandI16&1)
+                    tmpo->img=landscape_large_imgs[0]; //Boat
+                  else
+                    tmpo->img=landscape_large_imgs[1]; //Boat
+                  tmpo->p.z=(WATER_ELEVATION+2)*MAP_SCALE;
+                } else {
+                  tmpo->fish=TRUE;
+                  tmpo->img=<1>; //Fish
+                  tmpo->p.z=WATER_ELEVATION*MAP_SCALE;
+                }
+                QueIns(tmpo,tmpp->last_obj);
+              }
+            } else {
+              if (l<ROCK_ELEVATION*MAP_SCALE) {
+                if (RandI16&1)
+                  tmpp->color=LTGREEN;
+                else
+                  tmpp->color=GREEN+LTGREEN<<16+ROPF_DITHER;
+                if (Rand<0.03) {
+                  tmpo=MAlloc(sizeof(Obj),task);
+                  tmpo->p.x=(i+w/2)*MAP_SCALE;
+                  tmpo->p.y=(j+h/2)*MAP_SCALE;
+                  tmpo->p.z=l;
+                  tmpo->img=landscape_large_imgs[2]; //Tree
+                  tmpo->fish=FALSE;
+                  QueIns(tmpo,tmpp->last_obj);
+                }
+              } else if (l<SNOW_ELEVATION*MAP_SCALE) {
+                if (!(RandU16&3)) {
+                  if (RandI16&1)
+                    tmpp->color=LTGRAY;
+                  else
+                    tmpp->color=DKGRAY+LTGRAY<<16+ROPF_DITHER;
+                } else {
+                  if (RandI16&1)
+                    tmpp->color=LTGREEN;
+                  else
+                    tmpp->color=GREEN+LTGREEN<<16+ROPF_DITHER;
+                }
+              } else {
+                if (!(RandU16&3)) {
+                  if (RandI16&1)
+                    tmpp->color=WHITE;
+                  else
+                    tmpp->color=LTGRAY;
+                } else {
+                  if (RandI16&1)
+                    tmpp->color=LTGRAY+WHITE<<16+ROPF_DITHER;
+                  else
+                    tmpp->color=DKGRAY+LTGRAY<<16+ROPF_DITHER;
+                }
+              }
+            }
+            tmpp->num_sides=4;
+            poly=tmpp->pts=MAlloc(sizeof(CD3I32)*tmpp->num_sides,task);
+            poly[0].x=MAP_SCALE*i;
+            poly[0].y=MAP_SCALE*j;
+            poly[0].z=elevations[j][i];
+            poly[1].x=MAP_SCALE*(i+w);
+            poly[1].y=MAP_SCALE*j;
+            poly[1].z=elevations[j][i+w];
+            poly[2].x=MAP_SCALE*(i+w);
+            poly[2].y=MAP_SCALE*(j+h);
+            poly[2].z=elevations[j+h][i+w];
+            poly[3].x=MAP_SCALE*i;
+            poly[3].y=MAP_SCALE*(j+h);
+            poly[3].z=elevations[j+h][i];
+            tmpp->next=start_ptr;
+            start_ptr=tmpp;
+            if (!end_ptr)
+              end_ptr=tmpp;
+            for (k2=0;k2<h;k2++)
+              for (k1=0;k1<w;k1++)
+                panels[j+k2][i+k1]=tmpp;
+          }
+        }
+      }
+    }
+  if (end_ptr) {
+    while (LBts(&critical_section_flag,0))
+      Yield;
+    if (end_ptr)
+      end_ptr->next=panel_head;
+    panel_head=start_ptr;
+    LBtr(&critical_section_flag,0);
+  }
+  LBtr(&mp.init_not_done_flags,Gs->num);
+}
+
+U0 InitElevations()
+{
+  I64 i,j,l,x,y,xx,yy,x1,y1,x2,y2;
+  MemSet(elevations,0,sizeof(elevations));
+  for (i=0;i<MAP_WIDTH*MAP_HEIGHT/128;i++) {
+    x=RandU32%MAP_WIDTH;
+    y=RandU32%MAP_HEIGHT;
+    j=1<<(RandU32%6);
+    l=0;
+    while (j--) {
+      if (!l && RandU16<U16_MAX/4)
+        l=RandU16%(j+1);
+      if (l) {
+        x1=ClampI64(x-j,0,MAP_WIDTH-1);
+        x2=ClampI64(x+j,0,MAP_WIDTH-1);
+        y1=ClampI64(y-j,0,MAP_HEIGHT-1);
+        y2=ClampI64(y+j,0,MAP_HEIGHT-1);
+        for (yy=y1;yy<y2;yy++)
+          for (xx=x1;xx<x2;xx++)
+            elevations[yy][xx]+=MAP_SCALE/2;
+        l--;
+      }
+    }
+  }
+
+  for (j=0;j<MAP_HEIGHT;j++)
+    for (i=0;i<MAP_WIDTH;i++)
+      if (elevations[j][i]<WATER_ELEVATION*MAP_SCALE)
+        elevations[j][i]=WATER_ELEVATION*MAP_SCALE;
+}
+
+U0 InitMap()
+{/*We make a topographic data structure "elevations[][]"
+and convert it to panels. "panels[][]" holds the panels
+for each spot.
+*/
+  I64 i;
+  InitElevations;
+  MemSet(panels,0,sizeof(panels));
+  CalcNormals;
+  panel_head=NULL;
+  mp.init_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    Spawn(&MPDoPanels,Fs,"Do Panels",i);
+  while (mp.init_not_done_flags)
+    Sleep(1);
+}
+
+F64 claws_down;
+
+#define HAND_X  (1.0-claws_down)*(0.3*w)+claws_down*(0.4*w)
+#define HAND_Y  (1.0-claws_down)*(h-125)+claws_down*h
+
+
+
+
+<7>/* Graphics Not Rendered in HTML */
+<8>/* Graphics Not Rendered in HTML */
+
+
+
+U0 ClawDraw(CDC *dc,I64 x1,I64 y1,I64 x2,I64 y2,I64 w,I64 segments,Bool talon)
+{
+  I64 i,j;
+  for (i=0,j=segments;i<segments;i++,j--) {
+    dc->thick=w;
+    dc->color=BLACK;
+    GrLine3(dc,
+        j*x1/segments+i*x2/segments,
+        j*y1/segments+i*y2/segments,0,
+        (j-1)*x1/segments+(i+1)*x2/segments,
+        (j-1)*y1/segments+(i+1)*y2/segments,0);
+    dc->thick=w-2;
+    dc->color=YELLOW;
+    GrLine3(dc,
+        j*x1/segments+i*x2/segments,
+        j*y1/segments+i*y2/segments,0,
+        (j-1)*x1/segments+(i+1)*x2/segments,
+        (j-1)*y1/segments+(i+1)*y2/segments,0);
+  }
+  if (talon) {
+    if (y1<y2)
+      Sprite3B(dc,x1,y1,0,<7>);
+    else
+      Sprite3B(dc,x1,y1,0,<8>);
+  }
+}
+
+U0 ClawsDraw(CTask *task,CDC *dc)
+{
+  F64 claws_up=1.0-claws_down;
+  I64 w=task->pix_width,h=task->pix_height;
+  dc->flags|=DCF_SYMMETRY;
+  DCSymmetrySet(dc,w>>1,0,w>>1,1);
+
+  ClawDraw(dc,HAND_X-30,HAND_Y-50*claws_up,HAND_X-5,HAND_Y,     22,4,TRUE);
+  ClawDraw(dc,HAND_X-10,HAND_Y-60*claws_up,HAND_X,HAND_Y,       22,4,TRUE);
+  ClawDraw(dc,HAND_X+10,HAND_Y-60*claws_up,HAND_X,HAND_Y,       22,4,TRUE);
+  ClawDraw(dc,HAND_X+30,HAND_Y-50*claws_up,HAND_X+5,HAND_Y,     22,4,TRUE);
+  ClawDraw(dc,HAND_X+25,HAND_Y+40*claws_up,HAND_X+5,HAND_Y,     22,4,TRUE);
+
+  ClawDraw(dc,HAND_X,HAND_Y,6*w/20,h,38,5,FALSE);
+}
+
+CDC *main_dc;
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  main_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,0,0,main_dc);
+  if (claws_down)
+    ClawsDraw(task,dc);
+}
+
+/*
+<9>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Cores render strips that +/- 15%. The cores check the panel map array
+and render the panel for each square, marking-it done.
+
+The depth buf is not locked in the graphic routines
+so we get some glitches.
+*/
+
+I64 update_jiffy_limit;
+
+U0 MPDrawIt(CTask *task,CDC *dc)
+{
+  I64 j,update=winmgr.updates&65535,strip_width,*s2w,x1,y1,z1,xx,yy,
+        xh,yh,zh,yh2,xh2,x1h,y1h,x1wa,y1wa,x1wb,y1wb,x3,y3,z3,dd,dd_old,
+        cx=task->pix_width>>1,cy=task->pix_height>>1,r[16],*elems1,*elems_hard;
+  Panel reg *tmpp;
+  Bird  *tmpb;
+  Obj   *tmpo;
+  Bool  w_on_map,h_on_map;
+
+  xx=x/(MAP_SCALE*COORDINATE_SCALE);
+  yy=y/(MAP_SCALE*COORDINATE_SCALE);
+
+  //World to scrn coordinates
+  Mat4x4IdentEqu(dc->r);
+  Mat4x4RotZ(dc->r,heading);
+  Mat4x4RotX(dc->r,phi);
+  Mat4x4RotZ(dc->r,roll);
+  DCMat4x4Set(dc,dc->r);
+
+  //Scrn to world coordinates
+
+  //This gives us the vects for stepping through the grid in
+  //the direction the plane is facing. we step horizontally and vertically
+  //and use the reciprocal slope principle
+  //y=mx+b and y=(-1/m)x+b are perpendicular.
+
+  s2w=Mat4x4IdentNew;
+  Mat4x4RotZ(s2w,-roll);
+  Mat4x4RotX(s2w,-phi);
+  Mat4x4RotZ(s2w,-heading);
+
+  xh=0;
+  yh=0;
+  zh=-256;
+  Mat4x4MulXYZ(s2w,&xh,&yh,&zh);
+
+  //The layer for core1 is not cleared automatically
+  //it is persistent.  I have carefully syncronized to the update
+  //cycle initiated by Core0 to prevent flicker.
+
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->transform=&EDTransform;
+  dc->x=cx;
+  dc->y=cy;
+
+  //dc->x and the translation part of dc->r are ident in effect,
+  //but we use both to show-off.        We could add offsets together and
+  //use one or the other.
+
+  x1=-x>>COORDINATE_BITS;
+  y1=-y>>COORDINATE_BITS;
+  z1=-z>>COORDINATE_BITS;
+  Mat4x4MulXYZ(dc->r,&x1,&y1,&z1);
+  Mat4x4TranslationEqu(dc->r,x1,y1,z1);
+
+  //This is a refinement.
+  if (Abs(phi*180/pi)>90) {
+    x3=0;
+    y3=-cy;
+    z3=0;
+    Mat4x4MulXYZ(s2w,&x3,&y3,&z3);
+    xx+=x3;
+    yy+=y3;
+  }
+
+  if (Gs->num&1) {//alt left-right,right-left
+    yh2=-yh;
+    xh2=-xh;
+  } else {
+    yh2=yh;
+    xh2=xh;
+  }
+
+  //Calc starting point.
+  x1wa=xx<<8+xh*strip_height>>1/1.3*(Gs->num+1.15);
+  y1wa=yy<<8+yh*strip_height>>1/1.3*(Gs->num+1.15);
+  x1wb=0;
+  y1wb=0;
+
+  xh=-xh; //Back to front to help with depth.
+  yh=-yh;
+
+  //Take half steps to cover whole grid.
+  xh>>=1;  yh>>=1;
+  xh2>>=1; yh2>>=1;
+  w_on_map=FALSE;
+  dd_old=I64_MAX;
+  for (strip_width=0;cnts.jiffies<update_jiffy_limit;strip_width++) {
+    x1h=x1wa;
+    y1h=y1wa;
+    h_on_map=FALSE;
+    for (j=0;j<strip_height && cnts.jiffies<update_jiffy_limit;j++) {
+      x1=x1h>>8; y1=y1h>>8;
+      if (0<=x1<MAP_WIDTH && 0<=y1<MAP_HEIGHT) {
+        if ((tmpp=panels[y1][x1]) && tmpp->update!=update) {
+          tmpp->update=update;
+          if (tmpp->cnt>8*(1.1-Gs->idle_factor)) {
+            dc->color=tmpp->color;
+            tmpp->cnt=GrFillPoly3(dc,tmpp->num_sides,tmpp->pts);
+          } else
+            tmpp->cnt++;
+          tmpo=tmpp->next_obj;
+          while (tmpo!=&tmpp->next_obj) {
+            Sprite3(dc,tmpo->p.x,tmpo->p.y,tmpo->p.z,tmpo->img);
+            tmpo=tmpo->next;
+          }
+        }
+        h_on_map=TRUE;
+      } else if (h_on_map)
+        break;
+      x1h+=xh;
+      y1h+=yh;
+    }
+    if (h_on_map)
+      w_on_map=TRUE;
+    else if (w_on_map) {
+      strip_width=I64_MAX;
+      break;
+    }
+    x1wb-=yh2;
+    y1wb+=xh2;
+    if (strip_width&1) {
+      x1wa-=x1wb;
+      y1wa-=y1wb;
+    } else {
+      x1wa+=x1wb;
+      y1wa+=y1wb;
+    }
+    if (!w_on_map) {
+      dd=SqrI64(x1wa>>8-MAP_WIDTH>>1)+SqrI64(y1wa>>8-MAP_HEIGHT>>1);
+      if (dd>dd_old)
+        break;
+      dd_old=dd;
+    }
+  }
+
+  tmpb=b_head[Gs->num].next;
+  while (tmpb!=&b_head[Gs->num]) {
+    elems1=SpriteInterpolate(Tri(tS,0.2),<2>,<3>);
+
+    Mat4x4IdentEqu(r);
+    Mat4x4RotZ(r,tmpb->theta);
+    elems_hard=SpriteTransform(elems1,r);
+
+    Sprite3(dc,tmpb->p.x,tmpb->p.y,tmpb->p.z,elems_hard);
+    Free(elems_hard);
+    Free(elems1);
+
+    tmpb=tmpb->next;
+  }
+
+  Free(s2w);
+  mp.strip_width[Gs->num]=strip_width;
+  LBtr(&mp.update_not_done_flags,Gs->num);
+}
+
+U0 CoreAPTalonsTask(CTask *master_task)
+{
+  CDC *dc=DCAlias(main_dc,master_task);
+  while (!mp.app_done) {
+    while (!Bt(&mp.update_not_done_flags,Gs->num) && !mp.app_done)
+      Sleep(1);
+    if (!mp.app_done)
+      MPDrawIt(master_task,dc);
+  }
+
+  //We made an alias of this we don't want freed.
+  dc->depth_buf=NULL;
+
+  DCDel(dc);
+  LBtr(&mp.app_not_done_flags,Gs->num);
+}
+
+U0 DrawHorizon(CDC *dc)
+{
+  I64 x1,y1,z1,x2,y2,z2,xh,yh,zh,*s2w=Mat4x4IdentNew,
+        cx=Fs->pix_width>>1,
+        cy=Fs->pix_height>>1;
+  CD3I32 p[4];
+  I32 *old_db=dc->depth_buf;
+  dc->depth_buf=NULL;
+  CColorROPU32 ground_color;
+
+  if (game_tf && fish_left)
+    DCFill(dc,BLACK);
+  else if (-pi/4<=Wrap(phi-pi)<pi/4)
+    DCFill(dc,LTCYAN);
+  else {
+    if (z/COORDINATE_SCALE<(WATER_ELEVATION+3)*MAP_SCALE)
+      ground_color=BLUE;
+    else
+      ground_color=LTGREEN;
+
+    Mat4x4IdentEqu(dc->r);
+    Mat4x4RotZ(dc->r,heading);
+    Mat4x4RotX(dc->r,phi);
+    Mat4x4RotZ(dc->r,roll);
+
+    DCMat4x4Set(dc,dc->r);
+    dc->flags&=~DCF_TRANSFORMATION;
+    dc->transform=&EDTransform;
+    dc->x=cx;
+    dc->y=cy;
+
+    Mat4x4RotZ(s2w,-roll);
+    Mat4x4RotX(s2w,-phi);
+    Mat4x4RotZ(s2w,-heading);
+
+    xh=0;
+    yh=0;
+    zh=-256;
+    Mat4x4MulXYZ(s2w,&xh,&yh,&zh);
+    Free(s2w);
+
+    x1=xh+yh*32; y1=yh-xh*32; z1=0;
+    (*dc->transform)(dc,&x1,&y1,&z1);
+    x2=xh-yh*32; y2=yh+xh*32; z2=0;
+    (*dc->transform)(dc,&x2,&y2,&z2);
+    DCClipLine(dc,&x1,&y1,&x2,&y2);
+
+    MemSet(p,0,sizeof(p));
+    if (x2<x1) {
+      SwapI64(&x1,&x2);
+      SwapI64(&y1,&y2);
+    }
+    if (!x1 && x2==dc->width-1) {
+      p[0].x=0;
+      p[0].y=0;
+      p[1].x=dc->width-1;
+      p[1].y=0;
+      p[2].x=dc->width-1;
+      p[2].y=y2;
+      p[3].x=0;
+      p[3].y=y1;
+      if (rolled_over)
+        dc->color=ground_color;
+      else
+        dc->color=LTCYAN;
+      GrFillPoly3(dc,4,p);
+      p[0].y=dc->height-1;
+      p[1].y=dc->height-1;
+      if (rolled_over)
+        dc->color=LTCYAN;
+      else
+        dc->color=ground_color;
+      GrFillPoly3(dc,4,p);
+    } else {
+      if (y2<y1) {
+        SwapI64(&x1,&x2);
+        SwapI64(&y1,&y2);
+      }
+      if (!y1 && y2==dc->height-1) {
+        p[0].x=0;
+        p[0].y=0;
+        p[1].x=0;
+        p[1].y=dc->height-1;
+        p[2].x=x2;
+        p[2].y=dc->height-1;
+        p[3].x=x1;
+        p[3].y=0;
+        if (x1<x2 ^^ rolled_over)
+          dc->color=ground_color;
+        else
+          dc->color=LTCYAN;
+        GrFillPoly3(dc,4,p);
+        p[0].x=dc->width-1;
+        p[1].x=dc->width-1;
+        if (x1<x2 ^^ rolled_over)
+          dc->color=LTCYAN;
+        else
+          dc->color=ground_color;
+        GrFillPoly3(dc,4,p);
+      } else
+        DCFill(dc,LTCYAN); //Not correct.
+    }
+  }
+
+  dc->depth_buf=old_db;
+}
+
+U0 Core0Talons()
+{
+  CDC *dc=DCAlias(main_dc,Fs);
+  I64 i,xx,yy,elev,height,cx=Fs->pix_width>>1,cy=Fs->pix_height>>1;
+  F64 min_strip_width,tt;
+
+  update_jiffy_limit=cnts.jiffies+JIFFY_FREQ/40;
+
+  xx=x/(MAP_SCALE*COORDINATE_SCALE);
+  yy=y/(MAP_SCALE*COORDINATE_SCALE);
+  if (0<=xx<MAP_WIDTH && 0<=yy<MAP_HEIGHT)
+    elev=elevations[yy][xx];
+  else
+    elev=I64_MAX;
+
+  height=z/COORDINATE_SCALE-elev;
+  if (height<0 && elev>WATER_ELEVATION*MAP_SCALE && !game_tf) {
+    music.mute=TRUE;
+    Beep;
+    game_tf=tS;
+    music.mute=FALSE;
+  }
+
+  DrawHorizon(dc);
+
+  if (game_tf) {
+    tt=game_tf-game_t0;
+    if (Blink) {
+      dc->color=RED;
+      GrPrint(dc,(Fs->pix_width-9*FONT_WIDTH)/2,
+            (Fs->pix_height-FONT_HEIGHT)/2,"Game Over");
+    }
+  } else {
+    DCDepthBufRst(dc);
+    mp.update_not_done_flags=1<<mp_cnt-1;
+    MPDrawIt(Fs,dc);
+    while (mp.update_not_done_flags)
+      Sleep(1);
+
+    min_strip_width=F64_MAX;
+    for (i=0;i<mp_cnt;i++)
+      min_strip_width=Min(min_strip_width,32.0*mp.strip_width[i]/(i+32.0));
+    strip_height=ClampI64(
+          strip_height*Clamp(0.25*min_strip_width/strip_height,0.9,1.1),
+          64,1024);
+
+    tt=tS-game_t0;
+    if (tt<5.0 && Blink) {
+      dc->color=WHITE;
+      GrPrint(dc,(Fs->pix_width-13*FONT_WIDTH)/2,
+            (Fs->pix_height-FONT_HEIGHT)/2-4*FONT_HEIGHT,"Catch 10 Fish");
+    }
+  }
+
+  dc->thick=2;
+  if (game_tf && fish_left)
+    dc->color=WHITE;
+  else
+    dc->color=BLACK;
+  dc->flags&=~DCF_TRANSFORMATION;
+  GrLine3(dc,cx+5,cy,0,cx-5,cy,0);
+  GrLine3(dc,cx,cy+5,0,cx,cy-5,0);
+  if (invert_pitch)
+    GrPrint(dc,0,0,"Pitch:%5.1f Roll:%5.1f Heading:%5.1f "
+          "Height:%5d [Core Strip:%3d]",
+          pitch*180/pi,Wrap(roll+pi)*180/pi,Wrap(heading+pi,0)*180/pi,
+          height,strip_height);
+  else
+    GrPrint(dc,0,0,"Pitch:%5.1f Roll:%5.1f Heading:%5.1f "
+          "Height:%5d [Core Strip:%3d]",
+          pitch*180/pi,roll*180/pi,heading*180/pi,height,strip_height);
+  GrPrint(dc,0,FONT_HEIGHT,"Fish Remaining:%d Time:%3.2f Best:%3.2f",
+        fish_left,tt,best_score);
+
+  //We made an alias of this we don't want freed.
+  dc->depth_buf=NULL;
+  DCDel(dc);
+  Refresh;
+}
+
+
+Obj *FishFind(I64 x1,I64 y1,I64 *_dd)
+{
+  I64 dd,best_dd=I64_MAX;
+  Obj *res=NULL,*tmpo;
+  Panel *tmpp=panel_head;
+  while (tmpp) {
+    tmpo=tmpp->next_obj;
+    while (tmpo!=&tmpp->next_obj) {
+      if (tmpo->fish) {
+        dd=SqrI64(tmpo->p.x-x1)+SqrI64(tmpo->p.y-y1);
+        if (dd<best_dd) {
+          best_dd=dd;
+          res=tmpo;
+        }
+      }
+      tmpo=tmpo->next;
+    }
+    tmpp=tmpp->next;
+  }
+  *_dd=best_dd;
+  return res;
+}
+
+#define ANIMATE_MS      10
+
+U0 AnimateTask(I64)
+{//Steadily moves the airplane fwd.
+  I64 i,*s2w,x1,y1,z1,dx,dy,dz,dd;
+  F64 t0=tS,ms,theta,d;
+  Obj *tmpo;
+  Bird  *tmpb;
+  while (TRUE) {
+    ms=1000*(tS-t0);
+    t0=tS;
+    if (!game_tf) {
+//Scrn to world coordinates
+      s2w=Mat4x4IdentNew;
+      Mat4x4RotZ(s2w,-roll);
+      Mat4x4RotX(s2w,-phi);
+      Mat4x4RotZ(s2w,-heading);
+
+      dx=0;dy=0;dz=1<<16;
+      Mat4x4MulXYZ(s2w,&dx,&dy,&dz);
+      x-=speed*ms*COORDINATE_SCALE*dx/1<<16;
+      y-=speed*ms*COORDINATE_SCALE*dy/1<<16;
+      z-=speed*ms*COORDINATE_SCALE*dz/1<<16;
+      Free(s2w);
+      x1=x/COORDINATE_SCALE; y1=y/COORDINATE_SCALE; z1=z/COORDINATE_SCALE;
+      if (z1<(WATER_ELEVATION+3)*MAP_SCALE) {
+        if (z1<WATER_ELEVATION*MAP_SCALE) {
+          z=WATER_ELEVATION*MAP_SCALE*COORDINATE_SCALE;
+          if (invert_pitch) {
+            if (pitch<-pi/8)
+              phi+=ms/1000.0*Sign(3*pi/8-phi);
+          } else if (pitch<-pi/8)
+            phi+=ms/1000.0*Sign(-3*pi/8-phi);
+          WrapAngles;
+        }
+        speed=1.0;
+        if (rolled_over || !(tmpo=FishFind(x1,y1,&dd)))
+          claws_down=0;
+        else {
+          d=Sqrt(dd);
+          x1-=tmpo->p.x;
+          y1-=tmpo->p.y;
+          theta=ACos((dx*x1+dy*y1)/(d*1<<16));
+          if (theta>0 && d<MAP_SCALE*4)
+            claws_down=Saw(d,MAP_SCALE*4);
+          else
+            claws_down=0.01;
+          if (d<MAP_SCALE*2) {
+            if (!--fish_left) {
+              game_tf=tS;
+              if (game_tf-game_t0<best_score)
+                best_score=game_tf-game_t0;
+            }
+            QueRem(tmpo);
+            Free(tmpo);
+            music.mute=TRUE;
+            Snd(74); Sleep(200); Snd;
+            music.mute=FALSE;
+          }
+        }
+      } else {
+        claws_down=0;
+        if (-pi/4<=phi<=pi/4)
+          speed+=0.0005;
+        else if (-3*pi/4<=phi<=3*pi/4)
+          speed+=0.0001;
+        else
+          speed-=0.0001;
+        speed=Clamp(speed+(0.0005-0.0002*Abs(phi)/(pi/4)),0.1,5.0);
+      }
+
+      for (i=0;i<mp_cnt;i++) {
+        tmpb=b_head[i].next;
+        while (tmpb!=&b_head[i]) {
+          tmpb->p.x+=10*ms/1000*MAP_SCALE*Cos(tmpb->theta);
+          tmpb->p.y+=10*ms/1000*MAP_SCALE*Sin(tmpb->theta);
+          tmpb->p.z=BIRD_ELEVATION*MAP_SCALE+
+                elevations[tmpb->p.y/MAP_SCALE][tmpb->p.x/MAP_SCALE];
+          tmpb->theta+=2*pi*ms/1000/10;
+          tmpb=tmpb->next;
+        }
+      }
+    }
+    Refresh;
+  }
+}
+
+U0 MPEnd()
+{
+  update_jiffy_limit=0;
+  mp.app_not_done_flags=1<<mp_cnt-1-1;
+  mp.app_done=TRUE;
+//Wait for all cores to exit
+  while (mp.app_not_done_flags)
+    Sleep(1);
+}
+
+U0 TaskEndCB()
+{
+  MPEnd;
+  Exit;
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5eCGFsD4A5e.C4sG5eGDqCDeGsGG4qG");
+    Play("5eCGFsD4A5e.C4sG5eGDqCDeGsGG4qG");
+    Play("5eGECGC4A5FCsC4B5C4B5e.GsG4qGB");
+    Play("5eGECGC4A5FCsC4B5C4B5e.GsG4qGB");
+  }
+}
+
+U0 PreInit()
+{
+  I64 i,*r=Mat4x4IdentNew;
+  Mat4x4Scale(r,10.0);
+  for (i=0;i<LS_TYPES;i++)
+    landscape_large_imgs[i]=SpriteTransform(landscape_small_imgs[i],r);
+  Free(r);
+}
+
+U0 PostCleanUp()
+{
+  I64 i;
+  for (i=0;i<LS_TYPES;i++)
+    Free(landscape_large_imgs[i]);
+}
+
+U0 Init()
+{
+  I64 i,xx,yy;
+  Bird *tmpb;
+
+  main_dc=DCNew(GR_WIDTH,GR_HEIGHT);
+  critical_section_flag=0;
+  game_tf=0;
+  fish_left=10;
+
+  MemSet(&mp,0,sizeof(MPCtrl));
+  InitMap;
+  DCDepthBufAlloc(main_dc);
+
+  strip_height=128;
+
+  phi   =-90.0*pi/180.0;
+  roll  =0;
+  heading=0;
+  speed =2.5;
+  claws_down=0;
+  WrapAngles;
+
+  x=MAP_WIDTH>>1 *COORDINATE_SCALE*MAP_SCALE;
+  y=MAP_HEIGHT>>1*COORDINATE_SCALE*MAP_SCALE;
+  z=64           *COORDINATE_SCALE*MAP_SCALE;
+
+  xx=x/(MAP_SCALE*COORDINATE_SCALE);
+  yy=y/(MAP_SCALE*COORDINATE_SCALE);
+  z+=elevations[yy][xx]*COORDINATE_SCALE;
+
+  for (i=0;i<mp_cnt;i++)
+    QueInit(&b_head[i]);
+
+  for (i=0;i<B_NUM;i++) {
+    tmpb=MAlloc(sizeof(Bird));
+    tmpb->p.x=Rand*MAP_WIDTH*MAP_SCALE;
+    tmpb->p.y=Rand*MAP_HEIGHT*MAP_SCALE;
+    tmpb->p.z=BIRD_ELEVATION*MAP_SCALE+
+          elevations[tmpb->p.y/MAP_SCALE][tmpb->p.x/MAP_SCALE];
+    tmpb->theta=2*pi*Rand;
+    QueIns(tmpb,b_head[i%mp_cnt].last);
+  }
+
+  for (i=1;i<mp_cnt;i++)
+    Spawn(&CoreAPTalonsTask,Fs,"AP Talons",i);
+  Fs->task_end_cb=&TaskEndCB;
+  game_t0=tS;
+}
+
+U0 CleanUp()
+{
+  I64 i;
+  Panel *tmpp=panel_head,*tmpp1;
+  MPEnd;
+  while (tmpp) {
+    tmpp1=tmpp->next;
+    QueDel(&tmpp->next_obj);
+    Free(tmpp->pts);
+    Free(tmpp);
+    tmpp=tmpp1;
+  }
+  for (i=0;i<mp_cnt;i++) {
+    QueDel(&b_head[i]);
+    QueInit(&b_head[i]);
+  }
+  DCDel(main_dc);
+}
+
+U0 Talons()
+{
+  I64 ch,sc;
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Down(,,SC_CURSOR_UP);"
+        "  Up(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  "Initializing...\n";
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  PreInit;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try //in case <CTRL-ALT-c> is pressed.
+    do {
+      if (ScanKey(&ch,&sc)) {
+        switch (ch) {
+          case 0:
+            switch (sc.u8[0]) {
+              start:
+                case SC_CURSOR_DOWN:
+                  phi-=CTRLS_SCALE*Cos(roll);
+                  heading-=CTRLS_SCALE*Sin(roll)*Sin(phi);
+                  break;
+                case SC_CURSOR_UP:
+                  phi+=CTRLS_SCALE*Cos(roll);
+                  heading+=CTRLS_SCALE*Sin(roll)*Sin(phi);
+                  break;
+                case SC_CURSOR_RIGHT:
+                  roll+=CTRLS_SCALE;
+                  break;
+                case SC_CURSOR_LEFT:
+                  roll-=CTRLS_SCALE;
+                  break;
+              end:
+                WrapAngles;
+            }
+            break;
+          case '\n':
+            Fs->draw_it=NULL;
+            CleanUp;
+            Refresh;
+            Init;
+            Fs->draw_it=&DrawIt;
+            break;
+        }
+      } else
+        Core0Talons;
+    } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  PostCleanUp;
+  MenuPop;
+  RegWrite("TempleOS/Talons","F64 best_score=%5.4f;\n",best_score);
+}
+
+Talons;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/TheDead.HC.HTML b/public/Wb/Home/Src/Demo/Games/TheDead.HC.HTML new file mode 100755 index 0000000..b8ff650 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/TheDead.HC.HTML @@ -0,0 +1,218 @@ + + + + + + + + + + + +
+//These are the coordinates of the player.
+I64 x=0,y=GR_HEIGHT/2;
+
+/*This is a FIFO (first-in first-out) data structure
+which keeps track of bullets.  When a new bullet is
+fired, the bullets_in val is increased by one.
+When a bullet expires, the bullets_out val is increased
+by one.  The in and out vals loop-around, back to
+the start of the arrays.  It is known as a ring-buffer.
+*/
+#define BULLETS_NUM 32
+I64 bullets_in=0,bullets_out=0,bx[BULLETS_NUM],by[BULLETS_NUM];
+
+//This is a fifo which keeps track of the bad guys.
+#define DEAD_NUM 32
+I64 dead_in=0,dead_out=0,gx[DEAD_NUM],gy[DEAD_NUM];
+Bool g_dead[DEAD_NUM];
+
+/*This is a sprite created and edited by pressing
+<CTRL-r>.  When created, they are assigned
+a num.  Press <CTRL-t>, to see the hidden DolDoc
+place holder for the sprite.  The text in quotes
+can be set to whatever you want or nothing,
+but the ending num can't be changed.  It
+is controled by the editor.
+*/
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+ 
+<2>/* Graphics Not Rendered in HTML */
+ 
+ 
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+
+//Called by the Window Mgr system task 30fps.
+//The task arg is the task owning the window.
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j;
+//<CTRL-t> now to see the DolDoc place holder
+  //where the sprite num is encoded. $IB...$ stands
+  //for "insert ptr to binary object".
+  Sprite3(dc,x,y,0,<1>);
+
+  i=bullets_out;
+  while (i!=bullets_in) {
+    j=i++ &(BULLETS_NUM-1);
+    GrLine(dc,bx[j],by[j],bx[j]-2,by[j]);
+  }
+  i=dead_out;
+  while (i!=dead_in) {
+    j=i++ &(BULLETS_NUM-1);
+    if (!g_dead[j]) {
+      if (gx[j]%10>4)
+        Sprite3(dc,gx[j],gy[j],0,<2>);
+      else
+        Sprite3(dc,gx[j],gy[j],0,<3>);
+    }
+  }
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"If you aspire to making games,");
+  GrPrint(dc,0,FONT_HEIGHT,"you must learn to make-up rules.");
+}
+
+U0 SongTask(I64)
+{//Randomly generate (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5qDqDsDCDC4etB5C4B5qCqCqCqCqDqDsDCDC4etB5C4B5qCqCqCqCqCq"
+          "CsCCCCetCCBeBBeBBqBqBqCqCsCCCCetCCBeBBeBBqBqB");
+  }
+}
+
+U0 TheDead()
+{
+  I64 i,j,i1,j1,k=0,sc=0,ch=0,msg_code,arg1,arg2;
+  Bool gun_on=FALSE;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Fire(,CH_SPACE);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    do {
+      if (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_KEY_DOWN | 1<<MSG_KEY_UP)) {
+//With keyboard msgs, the two msg args
+        //are the scan code and ascii val for the key.
+        sc=arg2; ch=arg1;
+
+        if (msg_code==MSG_KEY_DOWN) {
+//The low byte of the scan code identifies the key.
+          if (sc.u8[0]==SC_CURSOR_DOWN) {
+            y+=10;
+            if (y>GR_HEIGHT-30)
+              y=GR_HEIGHT-30;
+          } else if (sc.u8[0]==SC_CURSOR_UP) {
+            y-=10;
+            if (y<0)
+              y=0;
+          } else if (sc.u8[0]==SC_CURSOR_RIGHT ||
+                ch==CH_SPACE)
+            gun_on=TRUE;
+        } else if (msg_code==MSG_KEY_UP) {
+          if (sc.u8[0]==SC_CURSOR_RIGHT ||
+                ch==CH_SPACE)
+            gun_on=FALSE;
+        }
+      }
+
+      i=bullets_out;
+      while (i!=bullets_in) {
+        j=i++ &(BULLETS_NUM-1);
+        bx[j]+=5;
+        if (bx[j]>GR_WIDTH)
+          bullets_out++;
+        else {
+          i1=dead_out;
+          while (i1!=dead_in) {
+            j1=i1++ &(DEAD_NUM-1);
+            if (gy[j1]<=by[j]<=gy[j1]+38 &&
+                  gx[j1]<=bx[j]<=gx[j1]+40)
+              g_dead[j1]=TRUE;
+          }
+        }
+      }
+
+      if (gun_on) {
+        j=bullets_in&(BULLETS_NUM-1);
+        bx[j]=x+32;
+        by[j]=y+14;
+        bullets_in++;
+      }
+
+      //Runs one out of four passes through this loop.
+      if (!(k % 4)) {
+        i=dead_out;
+        while (i!=dead_in) {
+          j=i++ &(DEAD_NUM-1);
+          gx[j]-=1;
+          if (gx[j]<25)
+            dead_out++;
+        }
+      }
+
+      //Runs one out of 150 passes through this loop.
+      if (!(k%150)) {
+        j=dead_in&(DEAD_NUM-1);
+        gx[j]=GR_WIDTH-30;
+        gy[j]=RandU32%(GR_HEIGHT-50)+25;
+        g_dead[j]=FALSE;
+        dead_in++;
+      }
+      k++;
+
+      Sleep(10); //Swap this task out for 10 miliseconds.
+    } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+}
+
+TheDead; //Run program when #included
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/TicTacToe.HC.HTML b/public/Wb/Home/Src/Demo/Games/TicTacToe.HC.HTML new file mode 100755 index 0000000..c9a4af8 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/TicTacToe.HC.HTML @@ -0,0 +1,156 @@ + + + + + + + + + + + +
+I8  board  [9];
+I64 board_x[9]={150,250,350,150,250,350,150,250,350};
+I64 board_y[9]={150,150,150,250,250,250,350,350,350};
+
+U0 DrawX(CDC *dc,I64 x,I64 y)
+{
+  dc->thick=5;
+  GrLine3(dc,x-20,y-20,0,x+20,y+20,0);
+  GrLine3(dc,x+20,y-20,0,x-20,y+20,0);
+}
+
+U0 DrawO(CDC *dc,I64 x,I64 y)
+{
+  dc->thick=5;
+  GrCircle3(dc,x,y,0,25);
+}
+
+U0 DrawBoard(I64 player)
+{
+  I64 i;
+  CDC *dc=DCAlias;
+  DCFill;
+  dc->thick=5;
+  GrLine3(dc,200,100,0,200,400,0);
+  GrLine3(dc,300,100,0,300,400,0);
+  GrLine3(dc,100,200,0,400,200,0);
+  GrLine3(dc,100,300,0,400,300,0);
+  for (i=0;i<9;i++)
+    switch (board[i]) {
+      case 1:
+        DrawX(dc,board_x[i],board_y[i]);
+        break;
+      case 2:
+        DrawO(dc,board_x[i],board_y[i]);
+        break;
+
+    }
+//ms.pos.x,ms.pos.y are mouse x,y.
+    //ms.lb     is mouse left bttn
+  if (player==1)
+    DrawX(dc,ms.pos.x-Fs->pix_left,ms.pos.y-Fs->pix_top);
+  else
+    DrawO(dc,ms.pos.x-Fs->pix_left,ms.pos.y-Fs->pix_top);
+  DCDel(dc);
+}
+
+U0 TakeTurn(I64 player)
+{
+  I64 i,x=0,y=0;
+  while (!(100<=x<400) || !(100<=y<400) || board[i]) {
+    if (player==1)
+      Beep;
+    else
+      Beep(74);
+    while (!ms.lb) {
+      DrawBoard(player);
+      Refresh;
+    }
+    while (ms.lb) {
+      DrawBoard(player);
+      Refresh;
+    }
+    x=ms.pos.x-Fs->pix_left;
+    y=ms.pos.y-Fs->pix_top;
+    i=(x-100)/100+(y-100)/100*3;
+  }
+  board[i]=player;
+}
+
+Bool CheckWinner(I64 player)
+{
+  if (  player==board[0]==board[1]==board[2] ||
+        player==board[3]==board[4]==board[5] ||
+        player==board[6]==board[7]==board[8] ||
+
+        player==board[0]==board[3]==board[6] ||
+        player==board[1]==board[4]==board[7] ||
+        player==board[2]==board[5]==board[8] ||
+
+        player==board[0]==board[4]==board[8] ||
+        player==board[2]==board[4]==board[6]   )
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 DoGame()
+{
+  I64 moves=0;
+  MemSet(board,0,sizeof(board));
+  while (TRUE) {
+    TakeTurn(1);
+    if (CheckWinner(1)) {
+      Beep;
+      Beep;
+      Beep;
+      break;
+    }
+    if (++moves==9) break;
+
+    TakeTurn(2);
+    if (CheckWinner(2)) {
+      Beep(74);
+      Beep(74);
+      Beep(74);
+      break;
+    }
+    if (++moves==9) break;
+  }
+}
+
+U0 TicTacToe()
+{
+  WinMax;   //Maximize window
+  DocClear; //Clear window text.
+  "$GREEN$CTRL-ALT-c$FG$ to exit.\n";
+  try
+    while (TRUE)
+      DoGame;
+  catch
+    PutExcept;
+  DCFill;
+}
+
+TicTacToe;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/TreeCheckers.HC.HTML b/public/Wb/Home/Src/Demo/Games/TreeCheckers.HC.HTML new file mode 100755 index 0000000..d2e1b21 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/TreeCheckers.HC.HTML @@ -0,0 +1,388 @@ + + + + + + + + + + + +
+U0 InitDefines()
+{
+  I64 w=GR_WIDTH,h=GR_HEIGHT-FONT_HEIGHT,cols,rows,
+        size=PopUpRangeI64(1,9,,"Size\n"),rad=16-size;
+  if (size<0) throw;
+  DefinePrint("UNITS_NUM","%d",4096/SqrI64(rad)&~1);
+  DefinePrint("CIRCLE_RAD","%d",rad);
+  DefinePrint("MOVE_CIRCLES","%d",40/rad);
+
+  cols=(w-8-rad)/(2*rad)&~1-1;
+  DefinePrint("BORDER_X","%d",(w+rad-cols*2*rad)/2);
+
+  rows=(h-8)/(2*rad)&~1;
+  DefinePrint("BORDER_Y","%d",(h-rows*2*rad)/2);
+
+} InitDefines;
+
+class Unit
+{
+  I64 num,x,y,player,link,color;
+  Bool alive,king;
+} u[UNITS_NUM];
+
+CDC *map_dc;
+I64 cur_player,num_alive[2],start_x,start_y,end_x,end_y;
+Bool show_start;
+
+U0 S2Circle(I64 *_x,I64 *_y)
+{
+  I64 i,j;
+  j=(*_y-BORDER_Y)/(CIRCLE_RAD*2);
+  if (j&1)
+    i=(*_x-CIRCLE_RAD-BORDER_X)/(CIRCLE_RAD*2);
+  else
+    i=(*_x-BORDER_X)/(CIRCLE_RAD*2);
+  *_y=j;
+  *_x=i;
+}
+
+U0 Circle2S(I64 *_x,I64 *_y)
+{
+  I64 j=*_y,i=*_x;
+  *_y=j*CIRCLE_RAD*2+CIRCLE_RAD+BORDER_Y;
+  *_x=i*CIRCLE_RAD*2+CIRCLE_RAD+BORDER_X;
+  if (j&1) *_x+=CIRCLE_RAD;
+}
+
+U0 S2W(I64 *_x,I64 *_y)
+{
+  S2Circle(_x,_y);
+  Circle2S(_x,_y);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i;
+  map_dc->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc,0,0,map_dc);
+
+  if (cur_player==0) {
+    dc->color=LTCYAN;
+    GrFloodFill(dc,0,0);
+    dc->color=CYAN;
+  } else {
+    dc->color=LTPURPLE;
+    GrFloodFill(dc,0,0);
+    dc->color=PURPLE;
+  }
+  GrPrint(dc,2,2,"Player %d",cur_player+1);
+
+  for (i=0;i<UNITS_NUM;i++)
+    if (u[i].alive) {
+      dc->color=u[i].color;
+      GrFloodFill(dc,u[i].x,u[i].y);
+    }
+  for (i=0;i<UNITS_NUM;i++)
+    if (u[i].alive && !u[i].king) {
+      dc->color=BLACK;
+      GrLine(dc,u[i].x,u[i].y,u[u[i].link].x,u[u[i].link].y);
+      if (Blink) {
+        dc->color=BLUE;
+        dc->thick=6;
+        GrPlot3(dc,(u[i].x+u[u[i].link].x)>>1,(u[i].y+u[u[i].link].y)>>1,0);
+      }
+    }
+  if (show_start) {
+    dc->color=LTRED;
+    GrLine(dc,start_x-4,start_y-4,start_x+4,start_y+4);
+    GrLine(dc,start_x-4,start_y+4,start_x+4,start_y-4);
+    GrLine(dc,start_x,start_y,end_x,end_y);
+  }
+  if ((num_alive[0]==1 || num_alive[1]==1) && Blink(4)) {
+    dc->color=BLACK;
+    GrPrint(dc,(task->pix_width-FONT_WIDTH*9)>>1,
+          (task->pix_height-FONT_HEIGHT)>>1,"Game Over");
+  }
+}
+
+Unit *UnitFind(I64 x,I64 y,I64 player)
+{
+  I64 i,dd,best_dd=I64_MAX;
+  Unit *res=NULL;
+  for (i=0;i<UNITS_NUM;i++) {
+    if (u[i].player==player && u[i].alive) {
+      dd=SqrI64(u[i].x-x)+SqrI64(u[i].y-y);
+      if (dd<best_dd) {
+        best_dd=dd;
+        res=&u[i];
+      }
+    }
+  }
+  return res;
+}
+
+U0 KillsChk(I64 x1,I64 y1,I64 player)
+{
+  I64 i,j,x2,y2,dd;
+  Bool found;
+  for (i=0;i<UNITS_NUM;i++) {
+    if (u[i].player!=player && u[i].alive && !u[i].king) {
+      x2=(u[i].x+u[u[i].link].x)>>1;
+      y2=(u[i].y+u[u[i].link].y)>>1;
+      dd=SqrI64(x2-x1)+SqrI64(y2-y1);
+      if (dd<=(CIRCLE_RAD+2)*(CIRCLE_RAD+2)) {
+        u[i].alive=FALSE;
+        Snd(62);Sleep(100);Snd;Sleep(25);
+        num_alive[u[i].player]--;
+        do {
+          found=FALSE;
+          for (j=0;j<UNITS_NUM;j++)
+            if (u[j].alive && u[j].player!=player && !u[j].king &&
+                  !u[u[j].link].alive) {
+              found=TRUE;
+              u[j].alive=FALSE;
+              Snd(62);Sleep(100);Snd;Sleep(25);
+              num_alive[u[j].player]--;
+            }
+        } while (found);
+      }
+    }
+  }
+}
+
+Bool UnitMove(Unit *tmpu,I64 x2,I64 y2)
+{
+  I64 i,r,c,r2,c2,x=start_x,y=start_y;
+  S2W(&x2,&y2);
+  c2=x2; r2=y2;
+  S2Circle(&c2,&r2);
+  for (i=0;i<MOVE_CIRCLES+1;i++) {
+    c=x; r=y;
+    S2Circle(&c,&r);
+    if (c==c2 && r==r2) {
+      end_x=tmpu->x=x2;
+      end_y=tmpu->y=y2;
+      return TRUE;
+    }
+    if (r2!=r) {
+      if (r&1) {
+        if (c<c2) c++;
+      } else {
+        if (c>c2) c--;
+      }
+    }
+    if (r2>r) {
+      x=c; y=++r;
+      Circle2S(&x,&y);
+    } else if (r2<r) {
+      x=c; y=--r;
+      Circle2S(&x,&y);
+    } else if (c2>c) {
+      x=++c; y=r;
+      Circle2S(&x,&y);
+    } else if (c2<c) {
+      x=--c; y=r;
+      Circle2S(&x,&y);
+    }
+  }
+  return FALSE;
+}
+
+CDC *DrawHexMap(I64 *_w,I64 *_h)
+{
+  CDC *dc=DCNew(*_w,*_h);
+  I64 i,j,x,y;
+  *_w=(dc->width-BORDER_X*2-CIRCLE_RAD)/(CIRCLE_RAD*2);
+  *_h=(dc->height-BORDER_Y*2)/(CIRCLE_RAD*2);
+  DCFill(dc,WHITE);
+  dc->color=LTGRAY;
+  for (j=0;j<*_h;j++) {
+    for (i=0;i<*_w;i++) {
+      x=i*CIRCLE_RAD*2+BORDER_X+CIRCLE_RAD;
+      y=j*CIRCLE_RAD*2+BORDER_Y+CIRCLE_RAD;
+      if (j&1) x+=CIRCLE_RAD;
+      S2W(&x,&y);
+      GrCircle(dc,x,y,CIRCLE_RAD);
+    }
+  }
+  *_w*=CIRCLE_RAD*2;
+  *_h*=CIRCLE_RAD*2;
+  return dc;
+}
+
+U0 Init()
+{
+  I64 i,j,j1,j2,dd,best_dd,best,w=Fs->pix_width,h=Fs->pix_height;
+
+  map_dc=DrawHexMap(&w,&h);
+  cur_player=0;
+
+  for (i=0;i<UNITS_NUM/2;i++) {
+    u[i].num=i;
+    u[i+UNITS_NUM/2].num=i+UNITS_NUM/2;
+
+ti_restart:
+    u[i].y=FloorI64(RandU32%h,CIRCLE_RAD*2)+CIRCLE_RAD;
+    u[i+UNITS_NUM/2].y=h-1-u[i].y;
+    j1=u[i].y/(CIRCLE_RAD*2);
+    j2=u[i+UNITS_NUM/2].y/(CIRCLE_RAD*2);
+    u[i].y+=BORDER_Y;
+    u[i+UNITS_NUM/2].y+=BORDER_Y;
+
+    if (!i) {
+      u[i].x=CIRCLE_RAD;
+      if (j1&1)
+        goto ti_restart;
+    } else
+      u[i].x=FloorI64(RandU32%((w-CIRCLE_RAD*2*2)/2),CIRCLE_RAD*2)+CIRCLE_RAD;
+    u[i+UNITS_NUM/2].x=w-1-u[i].x;
+
+    if (j1&1)
+      u[i].x+=CIRCLE_RAD;
+    if (j2&1)
+      u[i+UNITS_NUM/2].x+=CIRCLE_RAD;
+    u[i].x+=BORDER_X;
+    u[i+UNITS_NUM/2].x+=BORDER_X;
+
+    S2W(&u[i].x,&u[i].y);
+    S2W(&u[i+UNITS_NUM/2].x,&u[i+UNITS_NUM/2].y);
+
+    u[i].player=0;
+    u[i+UNITS_NUM/2].player=1;
+
+    u[i].alive=TRUE;
+    u[i+UNITS_NUM/2].alive=TRUE;
+
+    if (!i) {
+      u[i].color=LTCYAN;
+      u[i+UNITS_NUM/2].color=LTPURPLE;
+      u[i].king=TRUE;
+      u[i+UNITS_NUM/2].king=TRUE;
+    } else {
+      u[i].color=CYAN;
+      u[i+UNITS_NUM/2].color=PURPLE;
+      u[i].king=FALSE;
+      u[i+UNITS_NUM/2].king=FALSE;
+    }
+  }
+  for (i=0;i<UNITS_NUM/2;i++) {
+    if (!u[i].king) {
+      best_dd=I64_MAX;
+      for (j=0;j<UNITS_NUM/2;j++) {
+        if (i!=j) {
+          dd=SqrI64(u[i].x-u[j].x)+SqrI64(u[i].y-u[j].y);
+          if ((u[j].x<u[i].x || u[j].king) && dd<best_dd ) {
+            best_dd=dd;
+            best=j;
+          }
+        }
+      }
+      u[i].link=best;
+      u[i+UNITS_NUM/2].link=best+UNITS_NUM/2;
+    }
+  }
+  num_alive[0]=UNITS_NUM/2;
+  num_alive[1]=UNITS_NUM/2;
+}
+
+U0 CleanUp()
+{
+  DCDel(map_dc);
+}
+
+U0 TreeCheckers()
+{
+  I64 msg_code,arg1,arg2,ch,sc;
+  Unit *tmpu;
+
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  PopUpOk("Step on the link mid points.\n");
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU;
+  try {
+cn_start:
+    Init;
+    tmpu=NULL;
+    show_start=FALSE;
+    Fs->draw_it=&DrawIt;
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+      switch (msg_code) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              goto cn_start;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto cn_done;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          if (num_alive[0]>1 && num_alive[1]>1) {
+            tmpu=UnitFind(arg1,arg2,cur_player);
+            end_x=start_x=tmpu->x;
+            end_y=start_y=tmpu->y;
+            show_start=TRUE;
+          }
+          break;
+        case MSG_MS_MOVE:
+          if (tmpu)
+            UnitMove(tmpu,arg1,arg2);
+          break;
+        case MSG_MS_L_UP:
+          UnitMove(tmpu,arg1,arg2);
+          KillsChk(tmpu->x,tmpu->y,cur_player);
+          show_start=FALSE;
+          tmpu=NULL;
+          cur_player=1-cur_player;
+          break;
+      }
+    }
+cn_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+TreeCheckers;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Varoom.HC.HTML b/public/Wb/Home/Src/Demo/Games/Varoom.HC.HTML new file mode 100755 index 0000000..fc78362 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Varoom.HC.HTML @@ -0,0 +1,734 @@ + + + + + + + + + + + +
+
+
+
+
+
+    <1>/* Graphics Not Rendered in HTML */
+
+
+
+    <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+    <3>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+                 <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                 <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+RegDft("TempleOS/Varoom","F64 best_score=9999;\n");
+RegExe("TempleOS/Varoom");
+
+F64 distance,t0,tf;
+Bool game_over;
+
+#define BORDER          7500
+#define RADIUS          10000
+#define WIDTH           2000
+#define SHOULDER        200
+#define D_theta         (2*pi/360)   //Curve track slice is one degree.
+#define D_S             (2*pi*RADIUS/360) //Straight track is degree at 10000.
+#define DIPS            5
+#define DIP_DEPTH       50
+class Track
+{
+  Track *next,*last;
+  I32 num;
+  CColorROPU16 c,pad;
+  I64 x,z;
+  F64 theta,d;
+  CD3I32 left[4],center[4],right[4];
+} track_head,
+  *track_start[MP_PROCESSORS_NUM],*track_end[MP_PROCESSORS_NUM];
+
+CDC *track_map;
+#define MAP_BITS        9
+I64 t_minx,t_maxx,t_minz,t_maxz;
+
+#define BUSHES_NUM      512
+class Bush
+{
+  CD3I32 p;
+  Bool sym,pad[3];
+  U8 *img;
+} b[BUSHES_NUM];
+
+#define CARS_NUM        8
+class Car
+{
+  CD3I32 p;
+  F64 theta,dtheta,speed;
+  U8 *img;
+  Track *t;
+} c[CARS_NUM];
+
+I64 DipY(I64 x,I64 z)
+{
+  F64 m,a;
+  R2P(&m,&a,x,z);
+  return DIP_DEPTH*m*Cos(DIPS*a)/RADIUS;
+}
+
+#define CAR_LENGTH      400
+
+F64 Diptheta(I64 x,I64 z,F64 theta)
+{
+  F64 y_front,y_back;
+  y_front=DipY(x-CAR_LENGTH/2*Cos(theta),z-CAR_LENGTH/2*Sin(theta));
+  y_back =DipY(x+CAR_LENGTH/2*Cos(theta),z+CAR_LENGTH/2*Sin(theta));
+  return ASin((y_front-y_back)/CAR_LENGTH);
+}
+
+Track *TrackFind(Track *_tmpt,I64 x,I64 z)
+{
+  Track *res=_tmpt,*tmpt;
+  I64 dd,best=SqrI64(res->x-x)+SqrI64(res->z-z);
+
+  tmpt=_tmpt;
+  while (TRUE) {
+    tmpt=tmpt->next;
+    if (tmpt==&track_head)
+      tmpt=tmpt->next;
+    dd=SqrI64(tmpt->x-x)+SqrI64(tmpt->z-z);
+    if (dd<best) {
+      best=dd;
+      res=tmpt;
+    } else
+      break;
+  }
+  tmpt=_tmpt;
+  while (TRUE) {
+    tmpt=tmpt->last;
+    if (tmpt==&track_head)
+      tmpt=tmpt->last;
+    dd=SqrI64(tmpt->x-x)+SqrI64(tmpt->z-z);
+    if (dd<best) {
+      best=dd;
+      res=tmpt;
+    } else
+      break;
+  }
+  return res;
+}
+
+U0 TrackSlice(F64 *_x,F64 *_z,F64 theta,F64 d)
+{
+  F64 x=*_x,z=*_z,c=Cos(theta),s=Sin(theta),dx=d*s,dz=-d*c;
+  Track *tmpt,*last=track_head.last;
+  if (last==&track_head)
+    last=NULL;
+
+  tmpt=CAlloc(sizeof(Track));
+  if (last) {
+    MemCpy(&tmpt->center[0],&last->center[3],sizeof(CD3I32));
+    MemCpy(&tmpt->center[1],&last->center[2],sizeof(CD3I32));
+  }
+  tmpt->center[2].x=x+(WIDTH/2)*c+dx;
+  tmpt->center[2].z=z+(WIDTH/2)*s+dz;
+  tmpt->center[2].y=DipY(tmpt->center[2].x,tmpt->center[2].z);
+  tmpt->center[3].x=x-(WIDTH/2)*c+dx;
+  tmpt->center[3].z=z-(WIDTH/2)*s+dz;
+  tmpt->center[3].y=DipY(tmpt->center[3].x,tmpt->center[3].z);
+
+  if (last) {
+    MemCpy(&tmpt->left[0],&last->left[3],sizeof(CD3I32));
+    MemCpy(&tmpt->left[1],&last->left[2],sizeof(CD3I32));
+  }
+  tmpt->left[2].x=x-(WIDTH/2)*c+dx;
+  tmpt->left[2].z=z-(WIDTH/2)*s+dz;
+  tmpt->left[2].y=DipY(tmpt->left[2].x,tmpt->left[2].z);
+  tmpt->left[3].x=x-(WIDTH/2+SHOULDER)*c+dx;
+  tmpt->left[3].z=z-(WIDTH/2+SHOULDER)*s+dz;
+  tmpt->left[3].y=DipY(tmpt->left[3].x,tmpt->left[3].z);
+
+  if (last) {
+    MemCpy(&tmpt->right[0],&last->right[3],sizeof(CD3I32));
+    MemCpy(&tmpt->right[1],&last->right[2],sizeof(CD3I32));
+  }
+  tmpt->right[2].x=x+(WIDTH/2+SHOULDER)*c+dx;
+  tmpt->right[2].z=z+(WIDTH/2+SHOULDER)*s+dz;
+  tmpt->right[2].y=DipY(tmpt->right[2].x,tmpt->right[2].z);
+  tmpt->right[3].x=x+(WIDTH/2)*c+dx;
+  tmpt->right[3].z=z+(WIDTH/2)*s+dz;
+  tmpt->right[3].y=DipY(tmpt->right[3].x,tmpt->right[3].z);
+
+  tmpt->x=x;
+  tmpt->z=z;
+  tmpt->theta=theta;
+  tmpt->num=track_head.last->num+1;
+  tmpt->d  =track_head.last->d+d;
+
+  QueIns(tmpt,track_head.last);
+
+  if (tmpt->num&1)
+    tmpt->c=RED;
+  else
+    tmpt->c=WHITE;
+
+  if (x<t_minx) t_minx=x;
+  if (x>t_maxx) t_maxx=x;
+  if (z<t_minz) t_minz=z;
+  if (z>t_maxz) t_maxz=z;
+
+  x+=dx;
+  *_x=x;
+  z+=dz;
+  *_z=z;
+
+  if (x<t_minx) t_minx=x;
+  if (x>t_maxx) t_maxx=x;
+  if (z<t_minz) t_minz=z;
+  if (z>t_maxz) t_maxz=z;
+}
+
+U0 CoupleEnds()
+{
+  Track *first=track_head.next,*last=track_head.last;
+  MemCpy(&first->center[0],&last->center[3],sizeof(CD3I32));
+  MemCpy(&first->center[1],&last->center[2],sizeof(CD3I32));
+  MemCpy(&first->left[0]  ,&last->left[3]  ,sizeof(CD3I32));
+  MemCpy(&first->left[1]  ,&last->left[2]  ,sizeof(CD3I32));
+  MemCpy(&first->right[0] ,&last->right[3] ,sizeof(CD3I32));
+  MemCpy(&first->right[1] ,&last->right[2] ,sizeof(CD3I32));
+}
+
+U0 InitTrack()
+{
+  I64 i,j;
+  Track *tmpt;
+  F64 x,z,theta,d;
+
+  MemSet(&track_head,0,sizeof(Track));
+  QueInit(&track_head);
+
+  t_minx=t_minz=I64_MAX;
+  t_maxx=t_maxz=I64_MIN;
+
+  x=0; z=0; theta=0;
+  for (d=0;d<6*RADIUS;d+=D_S)
+    TrackSlice(&x,&z,theta,D_S);
+  for (i=0;i<180;i++,theta+=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (d=0;d<RADIUS;d+=D_S)
+    TrackSlice(&x,&z,theta,D_S);
+  for (i=0;i<90;i++,theta-=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (i=0;i<180;i++,theta+=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (i=0;i<90;i++,theta-=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+  for (d=0;d<RADIUS;d+=D_S)
+    TrackSlice(&x,&z,theta,D_S);
+  for (i=0;i<180;i++,theta+=D_theta)
+    TrackSlice(&x,&z,theta,D_theta*RADIUS);
+
+  CoupleEnds;
+
+  tmpt=track_head.next;
+  for (i=0;i<mp_cnt;i++) {
+    j=(i+1)*track_head.last->num/mp_cnt+1;
+    track_start[i]=tmpt;
+    while (tmpt!=&track_head && tmpt->num!=j)
+      tmpt=tmpt->next;
+    track_end[i]=tmpt;
+  }
+
+  t_minx-=BORDER; t_minz-=BORDER;
+  t_maxx+=BORDER; t_maxz+=BORDER;
+  track_map=DCNew((t_maxx-t_minx+1<<MAP_BITS-1)>>MAP_BITS,
+        (t_maxz-t_minz+1<<MAP_BITS-1)>>MAP_BITS);
+
+  track_map->color=LTGRAY;
+  GrRect(track_map,0,0,track_map->width,track_map->height);
+  tmpt=track_head.next;
+  track_map->color=YELLOW;
+  track_map->thick=3;
+  while (tmpt!=&track_head) {
+    GrPlot3(track_map,track_map->width-(tmpt->x-t_minx)>>MAP_BITS,
+          (tmpt->z-t_minz)>>MAP_BITS,0);
+    tmpt=tmpt->next;
+  }
+}
+
+#define HORIZON_DIP     200
+
+Bool PrepPoly(CD3I32 *p,I64 *r,I64 cx,I64 h,CD3I32 *poly)
+{
+  I64 x,y,z,i;
+  F64 s;
+  for (i=0;i<4;i++) {
+    x=p[i].x-c[0].p.x;
+    y=p[i].y-c[0].p.y;
+    z=p[i].z-c[0].p.z;
+    Mat4x4MulXYZ(r,&x,&y,&z);
+    s=100.0/(AbsI64(z)+50);
+    poly[i].y=s*y+h;
+    if (z<-200 || !(-h<poly[i].y<2*h))
+      return FALSE;
+    poly[i].x=s*x+cx;
+    poly[i].z=z+GR_Z_ALL;
+  }
+  return TRUE;
+}
+
+I64 mp_not_done_flags;
+
+U0 MPUpdateWin(CDC *dc2)
+{
+  CTask *task=dc2->win_task;
+  I64   i,x,y,z,
+        w=task->pix_width,h=task->pix_height,r[16],cx=w>>1;
+  F64   s,dip_theta=Diptheta(c[0].p.x,c[0].p.z,c[0].theta);
+  Car   *tmpc;
+  CD3I32 poly[4];
+  Track *tmpt,*tmpt1;
+  CDC   *dc=DCAlias(gr.dc2,task);
+
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,pi-c[0].theta);
+  Mat4x4RotX(r,75*pi/180-dip_theta);
+
+  dc->depth_buf=dc2->depth_buf;
+
+  //Track
+  tmpt =track_start[Gs->num];
+  tmpt1=track_end  [Gs->num];
+  while (tmpt!=tmpt1) {
+    dc->color=DKGRAY;
+    if (PrepPoly(&tmpt->center,r,cx,h,poly)) {
+      GrFillPoly3(dc,4,poly);
+      dc->color=tmpt->c;
+      if (PrepPoly(&tmpt->left,r,cx,h,poly))
+        GrFillPoly3(dc,4,poly);
+      if (PrepPoly(&tmpt->right,r,cx,h,poly))
+        GrFillPoly3(dc,4,poly);
+    }
+    tmpt=tmpt->next;
+  }
+
+  dc->flags|=DCF_TRANSFORMATION;
+  for (i=Gs->num;i<BUSHES_NUM;i+=mp_cnt) {
+    x=b[i].p.x-c[0].p.x; y=b[i].p.y-c[0].p.y; z=b[i].p.z-c[0].p.z;
+    Mat4x4MulXYZ(r,&x,&y,&z);
+    if (z>0) {
+      s=100.0/(AbsI64(z)+50);
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4Scale(dc->r,s*2);
+      DCMat4x4Set(dc,dc->r);
+      if (b[i].sym) {
+        dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+        DCSymmetrySet(dc,s*x+cx,s*y+h,s*x+cx,s*y+h+10);
+      }
+      Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,b[i].img);
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    }
+  }
+  for (i=Gs->num+1;i<CARS_NUM;i+=mp_cnt) {
+    tmpc=&c[i];
+    x=tmpc->p.x-c[0].p.x; y=tmpc->p.y-c[0].p.y; z=tmpc->p.z-c[0].p.z;
+    Mat4x4MulXYZ(r,&x,&y,&z);
+    if (z>0) {
+      s=100.0/(AbsI64(z)+50);
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4Scale(dc->r,s*2);
+      Mat4x4RotX(dc->r,Diptheta(tmpc->p.x,tmpc->p.z,-tmpc->theta));
+      Mat4x4RotY(dc->r,tmpc->theta-c[0].theta);
+      DCMat4x4Set(dc,dc->r);
+      Sprite3B(dc,s*x+cx,s*y+h,z+GR_Z_ALL,tmpc->img);
+    }
+  }
+  dc->depth_buf=NULL;
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 VRTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  zz=400+*z;
+  if (zz<1) zz=1;
+  *x=400* *x/zz;
+  *y=400* *y/zz;
+  *x+=dc->x;
+  *y+=dc->y;
+  *z+=dc->z;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64   i,x,y,z,
+        w=task->pix_width,
+        h=task->pix_height,r[16],
+        cx=w>>1;
+  F64   s,dip_theta=Diptheta(c[0].p.x,c[0].p.z,c[0].theta);
+  Car   *tmpc=&c[0];
+
+  dc->color=LTCYAN;
+  GrRect(dc,0,0,w,HORIZON_DIP*Sin(dip_theta)+FONT_HEIGHT*4.5);
+
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,pi-c[0].theta);
+  Mat4x4RotX(r,75*pi/180-dip_theta);
+
+  DCDepthBufAlloc(dc);
+
+  //Sun
+  x=c[0].p.x; y=0; z=1000000-c[0].p.z;
+  Mat4x4MulXYZ(r,&x,&y,&z);
+  s=100.0/(AbsI64(z)+50);
+  if (y<0) {
+    dc->color=BROWN;
+    GrCircle(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_theta),15);
+    dc->color=YELLOW;
+    GrFloodFill(dc,s*x+cx,15+HORIZON_DIP*Sin(dip_theta));
+  }
+
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPUpdateWin,dc,i);
+  while (mp_not_done_flags)
+    Yield;
+
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,tmpc->dtheta);
+  Mat4x4RotX(r,0.4-8*dip_theta); //Made this up
+  dc->transform=&VRTransform;
+  dc->x=task->pix_width>>1;
+  dc->y=task->pix_height-150;
+  dc->z=GR_Z_ALL;
+  Sprite3Mat4x4B(dc,0,0,-100,c[0].img,r);
+
+  //Map
+  GrBlot(dc,w-track_map->width,h-track_map->height,track_map);
+
+  dc->thick=2;
+  for (i=0;i<CARS_NUM;i++) {
+    if (i)
+      dc->color=LTPURPLE;
+    else
+      dc->color=LTCYAN;
+    GrPlot3(dc,w-(c[i].p.x-t_minx)>>MAP_BITS,
+               h-track_map->height+(c[i].p.z-t_minz)>>MAP_BITS,0);
+  }
+
+  if (game_over) {
+    dc->color=LTRED;
+    if (tf) {
+      s=tf-t0;
+      if (Blink)
+        GrPrint(dc,(w-FONT_WIDTH*14)/2,(h-FONT_HEIGHT)/2,"Game Completed");
+    } else {
+      s=99.9;
+      if (Blink)
+        GrPrint(dc,(w-FONT_WIDTH*9)/2,(h-FONT_HEIGHT)/2,"Game Over");
+    }
+  } else
+    s=tS-t0;
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"%0.1f%% Time:%0.2f Best:%0.2f",
+        100.0*distance/track_head.last->d,s,best_score);
+}
+
+U0 AnimateTask(I64)
+{
+  Car  *tmpc;
+  I64 i,x,z;
+  Bool on_track;
+  Track *tmpt,*tmpt2;
+  while (TRUE) {
+    if (!game_over)
+      Snd(12.0*Log2(c[0].speed/500+0.7));
+    else
+      Snd;
+    for (i=0;i<CARS_NUM;i++) {
+      tmpc=&c[i];
+      tmpc->p.x-=0.01*tmpc->speed*Cos(tmpc->theta-pi/2);
+      tmpc->p.z+=0.01*tmpc->speed*Sin(tmpc->theta-pi/2);
+      tmpt=TrackFind(tmpc->t,tmpc->p.x,tmpc->p.z);
+      if (i) {
+        if (tmpt!=tmpc->t) {
+          tmpt2=tmpt->next;
+          if (tmpt2==&track_head)
+            tmpt2=tmpt2->next;
+          tmpc->theta=Arg(-tmpt2->z+tmpc->p.z,-tmpt2->x+tmpc->p.x);
+        }
+      } else {
+        tmpc->theta+=0.01*tmpc->dtheta;
+        x=track_map->width-(tmpc->p.x-t_minx)>>MAP_BITS;
+        z=(tmpc->p.z-t_minz)>>MAP_BITS;
+        if (GrPeek(track_map,x,z)!=YELLOW) {
+          on_track=FALSE;
+          tmpc->speed-=0.01*tmpc->speed;
+          if (tmpc->speed<0) tmpc->speed=0;
+        } else
+          on_track=TRUE;
+      }
+      tmpc->t=tmpt;
+      tmpc->p.y=DipY(tmpc->p.x,tmpc->p.z);
+    }
+    if (!game_over && on_track) {
+      for (i=1;i<CARS_NUM;i++)
+        if (D3I32DistSqr(&c[i].p,&c[0].p)<CAR_LENGTH>>1*CAR_LENGTH>>1) {
+          game_over=TRUE;
+          Noise(500,22,34);
+          Sleep(500);
+          break;
+        }
+      if (!game_over) {
+        distance+=0.01*c[0].speed;
+        if (distance>track_head.last->d&& c[0].t->num<track_head.last->num>>1) {
+          tf=tS;
+          game_over=TRUE;
+          Beep;
+          if (tf-t0<best_score) {
+            best_score=tf-t0;
+            Beep;
+          }
+        }
+      }
+    }
+    Sleep(10);
+  }
+}
+
+U8 *imgs[8]={<1>,<1>,<2>,<2>,<3>,<4>,<4>,<4>};
+
+
+U0 InitBushes()
+{
+  Bush *tmpb;
+  I64 i,j,x,z;
+  track_map->color=LTGREEN;
+  track_map->thick=1;
+  for (i=0;i<BUSHES_NUM;i++) {
+    tmpb=&b[i];
+
+ib_restart:
+    tmpb->p.x=Rand*(t_maxx-t_minx)+t_minx;
+    tmpb->p.z=Rand*(t_maxz-t_minz)+t_minz;
+    x=track_map->width-(tmpb->p.x-t_minx)>>MAP_BITS;
+    z=(tmpb->p.z-t_minz)>>MAP_BITS;
+    for (j=0;j<8;j++)
+      if (GrPeek(track_map,x+gr_x_offsets[j],z+gr_y_offsets[j])!=LTGRAY)
+        goto ib_restart;
+
+    GrPlot(track_map,x,z);
+    tmpb->p.y=DipY(tmpb->p.x,tmpb->p.z);
+    tmpb->sym=RandU16&1;
+    tmpb->img=imgs[i&7];
+  }
+}
+
+
+U0 Init()
+{
+  Car   *tmpc;
+  Track *tmpt;
+  F64   d;
+  I64   i;
+
+  InitTrack;
+  InitBushes;
+  tmpt=track_head.next;
+  for (i=0;i<CARS_NUM;i++) {
+    tmpc=&c[i];
+    tmpc->t=tmpt;
+    tmpc->p.x=tmpt->x;
+    tmpc->p.z=tmpt->z;
+    tmpc->p.y=DipY(tmpc->p.x,tmpc->p.z);
+    tmpc->theta  =-tmpt->theta;
+    tmpc->dtheta=0;
+    if (!i) {
+      tmpc->img=<5>;
+      tmpc->speed=0;
+    } else {
+      tmpc->img=<6>;
+      tmpc->speed=2500.0;
+    }
+    d=(i+1)*track_head.last->d/CARS_NUM;
+    while (tmpt->next!=&track_head && tmpt->d<d)
+      tmpt=tmpt->next;
+  }
+  distance=0;
+  tf=0;
+  t0=tS;
+  game_over=FALSE;
+}
+
+U0 CleanUp()
+{
+  while (mp_not_done_flags)
+    Yield;
+  QueDel(&track_head,TRUE);
+  DCDel(track_map);
+}
+
+U0 Varoom()
+{
+  I64 sc;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Accelerator(,,SC_CURSOR_UP);"
+        "  Brake(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  try {
+    Fs->text_attr=YELLOW<<4+BLUE;
+    Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+          -WIF_SELF_GRAB_SCROLL-WIF_FOCUS_TASK_MENU;
+    AutoComplete;
+    WinBorder;
+    WinMax;
+    DocCursor;
+    DocClear;
+    Init;
+    Fs->draw_it=&DrawIt;
+    Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+    while (TRUE)
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              c[0].dtheta-=pi/60;
+              break;
+            case SC_CURSOR_RIGHT:
+              c[0].dtheta+=pi/60;
+              break;
+            case SC_CURSOR_UP:
+              c[0].speed+=300;
+              break;
+            case SC_CURSOR_DOWN:
+              c[0].speed-=900;
+              if (c[0].speed<0) c[0].speed=0;
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto vr_done;
+      }
+vr_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/Varoom","F64 best_score=%5.4f;\n",best_score);
+}
+
+Varoom;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Wenceslas.HC.HTML b/public/Wb/Home/Src/Demo/Games/Wenceslas.HC.HTML new file mode 100755 index 0000000..279f923 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Wenceslas.HC.HTML @@ -0,0 +1,623 @@ + + + + + + + + + + + +
+RegDft("TempleOS/Wenceslas","F64 best_score=9999;\n");
+RegExe("TempleOS/Wenceslas");
+
+#define BORDER          5
+#define KING_STEP       6
+
+
+
+
+
+        <1>/* Graphics Not Rendered in HTML */  //See ::/Apps/GrModels for making 3D men.
+
+
+
+
+        <2>/* Graphics Not Rendered in HTML */
+
+
+
+        <3>/* Graphics Not Rendered in HTML */
+
+
+
+        <4>/* Graphics Not Rendered in HTML */
+
+
+
+        <5>/* Graphics Not Rendered in HTML */
+
+
+
+        <6>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+ 
+
+
+        <7>/* Graphics Not Rendered in HTML */
+
+
+
+
+        <8>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+        <9>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+        <10>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+        <11>/* Graphics Not Rendered in HTML */
+
+
+U8 *king_imgs[4]={<2>,<1>,<2>,<3>};
+U8 *peasant_imgs[4]={<5>,<4>,<5>,<6>};
+
+
+#define TREES_NUM       8
+class Tree
+{
+  U16 x,y;
+  I64 fire_frame_idx;
+} trees[TREES_NUM];
+
+U64 snow_x,snow_y,new_snow_mS;
+#define SNOW_TILE_SIZE  128
+CDC *snow_tile;
+
+I64 king_x,king_y,king_mS,king_phase,
+    not_stopped_cnt;
+F64 king_timeout,king_theta,t0,tf,door_open_t0;
+I64 animate_mS,animate_phase;
+
+#define PEASANTS_NUM    10
+class Peasant
+{
+  Peasant *next,*last;
+  F64 x,y,theta,door_opened_t0;
+  Bool stopped;
+} peasant_head;
+
+class Step
+{
+  Step *next,*last;
+  U16 x,y;
+  F64 t0;
+} step_head,king_step_head;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 r[16],i,w=task->pix_width,h=task->pix_height,x,y;
+  U8 *img,*tmps;
+  Step *tmpst;
+  Peasant *tmpp;
+  F64 tt;
+
+  dc->thick=1;
+  for (i=0;i<TREES_NUM;i++) {
+    if (trees[i].y<=h/2) {//Draw trees behind house
+      if (trees[i].fire_frame_idx) {
+        if (trees[i].fire_frame_idx++&1)
+          img=<8>;
+        else
+          img=<9>;
+      } else
+        img=<7>;
+      Sprite3(dc,trees[i].x,trees[i].y,0,img);
+    }
+  }
+
+  Sprite3(dc,w/2,h/2,0,<10>);
+  if (tS<door_open_t0+1.0)
+    Sprite3(dc,w/2,h/2,0,<11>);
+
+  for (i=0;i<TREES_NUM;i++) {
+    if (trees[i].y>h/2) {//Draw trees in front of house
+      if (trees[i].fire_frame_idx) {
+        if (trees[i].fire_frame_idx++&1)
+          img=<8>;
+        else
+          img=<9>;
+      } else
+        img=<7>;
+      Sprite3(dc,trees[i].x,trees[i].y,0,img);
+    }
+  }
+
+  tmpst=step_head.next;
+  while (tmpst!=&step_head) {
+    if (tS-tmpst->t0<2.0)
+      dc->color=DKGRAY;
+    else
+      dc->color=LTGRAY;
+    dc->thick=4;
+    GrPlot3(dc,tmpst->x,tmpst->y,0);
+    tmpst=tmpst->next;
+  }
+
+  DCDepthBufAlloc(dc);
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->thick=1;
+  tmpp=peasant_head.next;
+  while (tmpp!=&peasant_head) {
+    Mat4x4IdentEqu(r);
+    Mat4x4RotY(r,tmpp->theta+pi/2);
+    Mat4x4RotX(r,pi/6);
+    if (tmpp->stopped)
+      Sprite3Mat4x4B(dc,tmpp->x,tmpp->y,GR_Z_ALL,peasant_imgs[0],r);
+    else {
+      tmps=SpriteInterpolate(Saw(animate_mS/250.0,1.0),
+            peasant_imgs[ animate_phase   &3],
+            peasant_imgs[(animate_phase+1)&3]);
+      Sprite3Mat4x4B(dc,tmpp->x,tmpp->y,GR_Z_ALL,tmps,r);
+      Free(tmps);
+    }
+    tmpp=tmpp->next;
+  }
+
+  dc->thick=1;
+  Mat4x4IdentEqu(r);
+  Mat4x4RotY(r,king_theta+pi/2);
+  Mat4x4RotX(r,pi/6);
+  if (tS>king_timeout)
+    Sprite3Mat4x4B(dc,king_x,king_y,GR_Z_ALL,king_imgs[0],r);
+  else {
+    tmps=SpriteInterpolate(Saw(king_mS/250.0,1.0),
+          king_imgs[ king_phase   &3],
+          king_imgs[(king_phase+1)&3]);
+    Sprite3Mat4x4B(dc,king_x,king_y,GR_Z_ALL,tmps,r);
+    Free(tmps);
+  }
+
+  dc->thick=1;
+  dc->color=ROP_MONO|WHITE;
+  for (y=snow_y%SNOW_TILE_SIZE-SNOW_TILE_SIZE;y<=h;y+=SNOW_TILE_SIZE)
+    for (x=snow_x%SNOW_TILE_SIZE-SNOW_TILE_SIZE;x<=w;x+=SNOW_TILE_SIZE)
+      GrBlot(dc,x,y,snow_tile);
+
+  if (tf) {
+    dc->color=LTRED;
+    if (Blink)
+      GrPrint(dc,w/2-(FONT_WIDTH*14)/2,h/2+FONT_HEIGHT,"Game Completed");
+    tt=tf;
+  } else {
+    tt=tS;
+  }
+  dc->color=LTBLUE;
+  GrPrint(dc,0,0,"Freezing Peasants:%d Time:%3.2f Best:%3.2f",
+        not_stopped_cnt,tt-t0,best_score);
+}
+
+U0 StepNew(CTask *task,I64 x,I64 y,F64 theta,Bool left_right,Bool king)
+{
+  Step *tmps;
+
+  if (king) {
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x;
+    tmps->y=y;
+    tmps->t0=tS;
+    QueIns(tmps,king_step_head.last);
+  }
+
+  if (left_right) {
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x-3.5*Sin(theta)+2.0*Cos(theta);
+    tmps->y=y+3.5*Cos(theta)+2.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x-3.5*Sin(theta)+5.0*Cos(theta);
+    tmps->y=y+3.5*Cos(theta)+5.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+  } else {
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x+3.5*Sin(theta)+0.0*Cos(theta);
+    tmps->y=y-3.5*Cos(theta)+0.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+    tmps=MAlloc(sizeof(Step),task);
+    tmps->x=x+3.5*Sin(theta)+3.0*Cos(theta);
+    tmps->y=y-3.5*Cos(theta)+3.0*Sin(theta);
+    tmps->t0=tS;
+    QueIns(tmps,step_head.last);
+  }
+}
+
+U0 Init()
+{
+  I64 i,min_x,max_x,min_y,max_y,
+        w=Fs->pix_width,h=Fs->pix_height;
+  Peasant *tmpp;
+
+  snow_x=snow_y=0;
+  new_snow_mS=0;
+  snow_tile=DCNew(SNOW_TILE_SIZE,SNOW_TILE_SIZE);
+
+  SpriteExtents(<7>,&min_x,&max_x,&min_y,&max_y);
+  for (i=0;i<TREES_NUM;i++) {
+    trees[i].x=RandU16%(w-2*BORDER-(max_x-min_x+1))+BORDER-min_x;
+    trees[i].y=RandU16%(h-2*BORDER-(max_y-min_y+1))+BORDER-min_y;
+    trees[i].fire_frame_idx=0;
+  }
+
+  QueInit(&step_head);
+  QueInit(&king_step_head);
+
+  SpriteExtents(<12>,&min_x,&max_x,&min_y,&max_y);
+  QueInit(&peasant_head);
+  for (i=0;i<PEASANTS_NUM;i++) {
+    tmpp=MAlloc(sizeof(Peasant));
+    tmpp->x=RandU16%(w-2*BORDER-(max_x-min_x+1))+BORDER-min_x;
+    tmpp->y=RandU16%(h-2*BORDER-(max_y-min_y+1))+BORDER-min_y;
+    tmpp->theta=pi*2*Rand;
+    tmpp->door_opened_t0=0;
+    tmpp->stopped=FALSE;
+    QueIns(tmpp,peasant_head.last);
+  }
+  animate_phase=0;
+  animate_mS=0;
+  king_phase=0;
+  king_mS=0;
+  king_timeout=0;
+  king_x=w/2;
+  king_y=h/2;
+  king_theta=-pi/2;
+  door_open_t0=0;
+  t0=tS;
+  tf=0;
+}
+
+U0 CleanUp()
+{
+  DCDel(snow_tile);
+  QueDel(&peasant_head,TRUE);
+  QueDel(&step_head,TRUE);
+  QueDel(&king_step_head,TRUE);
+}
+
+U0 Follow(CTask *,Peasant *tmpp)
+{
+  Step *tmps=king_step_head.next;
+  F64 d,best_d=F64_MAX;
+  while (tmps!=&king_step_head) {
+    if ((d=Sqr(tmps->x-tmpp->x)+Sqr(tmps->y-tmpp->y)) &&
+          d<15*15) {
+      d+=1000*Sqr(tS-tmps->t0);
+      if (d<best_d) {
+        best_d=d;
+        tmpp->theta=Arg(tmps->x-tmpp->x,tmps->y-tmpp->y);
+      }
+    }
+    tmps=tmps->next;
+  }
+}
+
+U0 AnimateTask(I64)
+{
+  Step *tmps,*tmps1;
+  Peasant *tmpp;
+  I64 i,w,h;
+  while (TRUE) {
+    w=Fs->parent_task->pix_width;
+    h=Fs->parent_task->pix_height;
+
+    tmps=step_head.next;
+    while (tmps!=&step_head) {
+      tmps1=tmps->next;
+      if (tS-tmps->t0>5.0) {
+        QueRem(tmps);
+        Free(tmps);
+      }
+      tmps=tmps1;
+    }
+
+    tmps=king_step_head.next;
+    while (tmps!=&king_step_head) {
+      tmps1=tmps->next;
+      if (tS-tmps->t0>3.0) {
+        QueRem(tmps);
+        Free(tmps);
+      }
+      tmps=tmps1;
+    }
+
+    not_stopped_cnt=0;
+    tmpp=peasant_head.next;
+    while (tmpp!=&peasant_head) {
+      if (tmpp->stopped) {
+        if (tmpp->door_opened_t0 && tS>tmpp->door_opened_t0+1.0) {
+          tmpp->door_opened_t0=0;
+          tmpp->y=tmpp->x=-9999;
+        }
+      } else {
+        if (Sqr(tmpp->x-w/2)+Sqr(tmpp->y-h/2)<20*20) {
+          tmpp->stopped=TRUE;
+          tmpp->door_opened_t0=door_open_t0=tS;
+        }
+        for (i=0;i<TREES_NUM;i++) //Hang-out by fire
+          if (trees[i].fire_frame_idx &&
+                Sqr(tmpp->x-trees[i].x)+Sqr(tmpp->y-trees[i].y)<20*20) {
+            tmpp->stopped=TRUE;
+            break;
+          }
+        if (!tmpp->stopped) {
+          Follow(Fs->parent_task,tmpp);
+          tmpp->x+=Cos(tmpp->theta)/100;
+          tmpp->y+=Sin(tmpp->theta)/100;
+          if (!(BORDER/2<=tmpp->x<w-BORDER/2) ||
+                !(BORDER/2<=tmpp->y<h-BORDER/2)) {
+            tmpp->theta+=pi;
+            tmpp->x+=3*Cos(tmpp->theta)/100;
+            tmpp->y+=3*Sin(tmpp->theta)/100;
+          }
+          if (!animate_mS && animate_phase&1)
+            StepNew(Fs->parent_task,tmpp->x,tmpp->y,tmpp->theta,
+                  animate_phase&2,FALSE);
+          not_stopped_cnt++;
+        }
+      }
+      tmpp=tmpp->next;
+    }
+    if (!not_stopped_cnt && !tf) {
+      tf=tS;
+      music.mute=TRUE;
+      Snd(86);Sleep(200);Snd;Sleep(100);
+      if (tf-t0<best_score) {
+        best_score=tf-t0;
+        Snd(86);Sleep(200);Snd;Sleep(100);
+      }
+      music.mute=FALSE;
+    }
+
+    snow_x+=RandU16%3-1;
+    snow_y+=1-SignI64(RandU16&3);
+    if (new_snow_mS++>8) {
+      new_snow_mS=0;
+      snow_tile->color=WHITE;
+      GrPlot(snow_tile,RandU16&(SNOW_TILE_SIZE-1),RandU16&(SNOW_TILE_SIZE-1));
+    }
+
+    Sleep(1);
+    if (animate_mS++>=250) {
+      animate_mS=0;
+      animate_phase=(animate_phase+1)&3;
+    }
+    if (tS<king_timeout) {
+      if (king_mS++>=250) {
+        king_mS=0;
+        king_phase|=1;
+      }
+    }
+  }
+}
+
+U0 BurnTrees()
+{
+  I64 i;
+  for (i=0;i<TREES_NUM;i++)
+    if (Sqr(king_x-trees[i].x)+Sqr(king_y-trees[i].y)<10*10)
+      trees[i].fire_frame_idx=1;
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  music.tempo= 2.480;
+  music.stacatto_factor= 0.902;
+  while (TRUE) {
+    Play("5eCCCDCC4qGeAGAB5qCC");
+    Play("5eCCCDCC4qGeAGAB5qCC");
+    Play("5eGFEDEDqC4eAGAB5qCC");
+  }
+}
+ 
+U0 Wenceslas()
+{
+  I64 sc;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  BurnTree(,CH_SPACE);"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+
+  PopUpOk("
+Good King Wenceslas looked out
+On the feast of Stephen
+When the snow lay round about
+Deep and crisp and even
+Brightly shone the moon that night
+Though the frost was cruel
+When a poor man came in sight
+Gath'ring winter fuel
+
+\"Hither, page, and stand by me
+If thou know'st it, telling
+Yonder peasant, who is he?
+Where and what his dwelling?\"
+\"Sire, he lives a good league hence
+Underneath the mountain
+Right against the forest fence
+By Saint Agnes' fountain.\"
+
+\"Bring me flesh and bring me wine
+Bring me pine logs hither
+Thou and I will see him dine
+When we bear him thither.\"
+Page and monarch forth they went
+Forth they went together
+Through the rude wind's wild lament
+And the bitter weather
+
+");
+  PopUpOk("
+\"Sire, the night is darker now
+And the wind blows stronger
+Fails my heart, I know not how,
+I can go no longer.\"
+\"Mark my footsteps, my good page
+Tread thou in them boldly
+Thou shalt find the winter's rage
+Freeze thy blood less coldly.\"
+
+In his master's steps he trod
+Where the snow lay dinted
+Heat was in the very sod
+Which the Saint had printed
+Therefore, Christian men, be sure
+Wealth or rank possessing
+Ye who now will bless the poor
+Shall yourselves find blessing
+
+");
+  PopUpOk("
+$PURPLE$$TX+CX,\"Winceslas Game\"$$FG$
+
+Start fires by pressing $GREEN$<SPACE>$FG$
+on trees. (Yule logs)
+
+Lead peasants to fires.
+");
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto ws_done;
+        case CH_SPACE:
+          BurnTrees;
+          break;
+        case 0:
+          switch (sc.u8[0]) {
+            start:
+              case SC_CURSOR_RIGHT:
+                if (king_x+KING_STEP<Fs->pix_width-BORDER)
+                  king_x+=KING_STEP;
+                king_theta=0;
+                break;
+              case SC_CURSOR_LEFT:
+                if (king_x-KING_STEP>=BORDER)
+                  king_x-=KING_STEP;
+                king_theta=pi;
+                break;
+              case SC_CURSOR_DOWN:
+                if (king_y+KING_STEP<Fs->pix_height-BORDER)
+                  king_y+=KING_STEP;
+                king_theta=-pi/2;
+                break;
+              case SC_CURSOR_UP:
+                if (king_y-KING_STEP>=BORDER)
+                  king_y-=KING_STEP;
+                king_theta=pi/2;
+                break;
+            end:
+              king_mS=0;
+              king_phase=(king_phase+2)&2;
+              StepNew(Fs,king_x,king_y,king_theta,king_phase&2,TRUE);
+              king_timeout=tS+0.5;
+              break;
+          }
+      }
+    }
+ws_done:
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+  RegWrite("TempleOS/Wenceslas","F64 best_score=%5.4f;\n",best_score);
+}
+
+Wenceslas;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Whap.HC.HTML b/public/Wb/Home/Src/Demo/Games/Whap.HC.HTML new file mode 100755 index 0000000..dcc0ca7 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Whap.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+#define BALLS_NUM       7
+#define SPRINGS_NUM     3
+
+#define STRETCH         500.0
+#define GRAVITY         50.0 //not really gravity
+#define BALL_RADIUS     5
+#define BASE_SIZE       10
+
+CMass balls[BALLS_NUM];
+CSpring springs[SPRINGS_NUM];
+F64 collision_t;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,
+        cx=task->pix_width>>1,
+        cy=task->pix_height>>1;
+  Bool snd_on=FALSE;
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Protect your base.");
+  GrRect(dc,cx-BASE_SIZE,cy-BASE_SIZE,BASE_SIZE*2,BASE_SIZE*2);
+  dc->color=CYAN;
+  GrRect(dc,cx-BASE_SIZE+2,cy-BASE_SIZE+2,BASE_SIZE*2-4,BASE_SIZE*2-4);
+  dc->color=YELLOW;
+  GrLine(dc,balls[0].x,balls[0].y,
+        ms.pos.x-task->pix_left-task->scroll_x,
+        ms.pos.y-task->pix_top-task->scroll_y);
+  for (i=0;i<SPRINGS_NUM;i++)
+    GrLine(dc,springs[i].end1->x,springs[i].end1->y,
+          springs[i].end2->x,springs[i].end2->y);
+
+  dc->color=LTCYAN;
+  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
+  GrFloodFill(dc,balls[0].x,balls[0].y,TRUE);
+  dc->color=BLACK;
+  GrCircle(dc,balls[0].x,balls[0].y,BALL_RADIUS);
+
+  for (i=1;i<BALLS_NUM;i++) {
+    dc->color=LTPURPLE;
+    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
+    GrFloodFill(dc,balls[i].x,balls[i].y,TRUE);
+    if (cx-BASE_SIZE-BALL_RADIUS<=balls[i].x<=cx+BASE_SIZE+BALL_RADIUS &&
+          cy-BASE_SIZE-BALL_RADIUS<=balls[i].y<=cy+BASE_SIZE+BALL_RADIUS)
+      snd_on=TRUE;
+    dc->color=BLACK;
+    GrCircle(dc,balls[i].x,balls[i].y,BALL_RADIUS);
+  }
+  if (snd_on)
+    Snd(74);
+  else
+    Snd;
+}
+
+U0 MyDerivative(CMathODE *ode,F64 t,COrder2D3 *,COrder2D3 *)
+{
+  I64 i,j;
+  F64 d,dd;
+  CD3 p,p2;
+  CTask *task=ode->win_task;
+
+  D3SubEqu(D3Equ(&p2,
+        ms.pos.x-task->pix_left-task->scroll_x,
+        ms.pos.y-task->pix_top-task->scroll_y,0),
+        &balls[0].state->x);
+  D3AddEqu(&balls[0].DstateDt->DxDt,D3MulEqu(&p2,STRETCH));
+
+  D3Equ(&p2,task->pix_width>>1,task->pix_height>>1,0);
+  for (i=1;i<BALLS_NUM;i++) {
+    D3Sub(&p,&p2,&balls[i].state->x);
+    if (d=D3Norm(&p)) {
+//Gravity would be /(d*d*d), but that's too exponential.
+      D3MulEqu(&p,GRAVITY/d);
+      D3AddEqu(&balls[i].DstateDt->DxDt,&p);
+    }
+  }
+
+  for (i=0;i<BALLS_NUM;i++)
+    for (j=i+1;j<BALLS_NUM;j++) {
+      D3Sub(&p,&balls[j].state->x,&balls[i].state->x);
+      dd=D3NormSqr(&p);
+      if (dd<=(2*BALL_RADIUS)*(2*BALL_RADIUS)) {
+        if (t-collision_t>0.05) {
+          Noise(50,102,105);
+          collision_t=t;
+        }
+        d=Sqrt(dd)+0.0001;
+        dd=10.0*Sqr(Sqr((2*BALL_RADIUS)*(2*BALL_RADIUS)-dd));
+        D3MulEqu(&p,dd/d);
+        D3AddEqu(&balls[j].DstateDt->DxDt,&p);
+        D3SubEqu(&balls[i].DstateDt->DxDt,&p);
+      }
+    }
+
+  d=balls[0].state->x;
+  if (d-BALL_RADIUS<0)
+    balls[0].DstateDt->DxDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
+  if (d+BALL_RADIUS>task->pix_width)
+    balls[0].DstateDt->DxDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_width)));
+
+  d=balls[0].state->y;
+  if (d-BALL_RADIUS<0)
+    balls[0].DstateDt->DyDt+=Sqr(Sqr(Sqr(d-BALL_RADIUS)));
+  if (d+BALL_RADIUS>task->pix_height)
+    balls[0].DstateDt->DyDt-=Sqr(Sqr(Sqr((d+BALL_RADIUS)-task->pix_height)));
+}
+
+U0 Whap()
+{
+  I64 i;
+  CMathODE *ode=ODENew(0,1e-2,ODEF_HAS_MASSES);
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        );
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+  MemSet(balls,0,BALLS_NUM*sizeof(CMass));
+  D3Equ(&balls[0].x,100,100,0);
+  for (i=1;i<BALLS_NUM;i++)
+    D3Equ(&balls[i].x,
+          RandI16%500+Fs->pix_width>>1,RandI16%500+Fs->pix_height>>1,0);
+  balls[0].x=ms.pos.x-Fs->pix_left-Fs->scroll_x;
+  balls[0].y=ms.pos.y-Fs->pix_top-Fs->scroll_y;
+  for (i=0;i<BALLS_NUM;i++) {
+    balls[i].mass=1.0;
+    balls[i].drag_profile_factor=1.0;
+    QueIns(&balls[i],ode->last_mass);
+  }
+  balls[2].x=balls[1].x+15;
+  balls[2].y=balls[1].y;
+  balls[3].x=balls[1].x;
+  balls[3].y=balls[1].y+15;
+  MemSet(springs,0,SPRINGS_NUM*sizeof(CSpring));
+  springs[0].end1=&balls[1];
+  springs[0].end2=&balls[2];
+  springs[0].rest_len=15;
+  springs[0].const=10000;
+  QueIns(&springs[0],ode->last_spring);
+  springs[1].end1=&balls[1];
+  springs[1].end2=&balls[3];
+  springs[1].rest_len=15;
+  springs[1].const=10000;
+  QueIns(&springs[1],ode->last_spring);
+  springs[2].end1=&balls[2];
+  springs[2].end2=&balls[3];
+  springs[2].rest_len=sqrt2*15;
+  springs[2].const=10000;
+  QueIns(&springs[2],ode->last_spring);
+
+  collision_t=0;
+  QueIns(ode,Fs->last_ode);
+
+  DocCursor;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar;
+  SettingsPop;
+  QueRem(ode);
+  ODEDel(ode);
+  MenuPop;
+}
+
+Whap;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/Zing.HC.HTML b/public/Wb/Home/Src/Demo/Games/Zing.HC.HTML new file mode 100755 index 0000000..8e3a260 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/Zing.HC.HTML @@ -0,0 +1,236 @@ + + + + + + + + + + + +
+I64 box_x_min,box_x_max,box_y_min,box_y_max;
+
+class Arrow
+{
+  Arrow *next,*last;
+  F64 x,y,dx,dy;
+} head;
+
+   <1>/* Graphics Not Rendered in HTML */
+
+Bool bow_drawn;
+F64 bow_x,bow_y,bow_theta;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  F64 theta,x,y,dx,dy,
+        str_w,str_h,draw_len;
+  Arrow *tmpa;
+  CD3I32 ctrl[5];
+  dc->color=RED;
+  GrBorder(dc,box_x_min,box_y_min,box_x_max,box_y_max);
+
+  x=ClampI64(ms.pos.x-task->pix_left-task->scroll_x,box_x_min,box_x_max);
+  y=ClampI64(ms.pos.y-task->pix_top-task->scroll_y, box_y_min,box_y_max);
+  dx=bow_x-x;
+  dy=bow_y-y;
+
+  if (bow_drawn && (dx|dy))
+    bow_theta=Arg(dx,dy);
+  else {
+    bow_x=x;
+    bow_y=y;
+  }
+
+  draw_len=Sqrt(dx*dx+dy*dy);
+  str_w=draw_len/3;
+  str_h=Sqrt(60*60-str_w*str_w);
+
+  dc->color=BLACK;
+  GrLine(dc,x-str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta),
+        y-str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta),
+        x,y);
+  GrLine(dc,x+str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta),
+        y+str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta),
+        x,y);
+
+  MemSet(ctrl,0,sizeof(ctrl));
+  ctrl[0].x=x-str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta);
+  ctrl[0].y=y-str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta);
+  ctrl[1].x=x-0.75*str_h/2*Cos(bow_theta+pi/2)+draw_len/2*Cos(bow_theta)+
+        str_w*Cos(bow_theta);
+  ctrl[1].y=y-0.75*str_h/2*Sin(bow_theta+pi/2)+draw_len/2*Sin(bow_theta)+
+        str_w*Sin(bow_theta);
+  ctrl[2].x=x+draw_len/2*Cos(bow_theta)+str_w*Cos(bow_theta);
+  ctrl[2].y=y+draw_len/2*Sin(bow_theta)+str_w*Sin(bow_theta);
+  ctrl[3].x=x+0.75*str_h/2*Cos(bow_theta+pi/2)+draw_len/2*Cos(bow_theta)+
+        str_w*Cos(bow_theta);
+  ctrl[3].y=y+0.75*str_h/2*Sin(bow_theta+pi/2)+draw_len/2*Sin(bow_theta)+
+        str_w*Sin(bow_theta);
+  ctrl[4].x=x+str_h/2*Cos(bow_theta+pi/2)+str_w*Cos(bow_theta);
+  ctrl[4].y=y+str_h/2*Sin(bow_theta+pi/2)+str_w*Sin(bow_theta);
+
+  dc->color=BROWN;
+  dc->thick=2;
+  Gr2BSpline3(dc,ctrl,5);
+  dc->thick=1;
+
+  if (bow_drawn)
+    Sprite3ZB(dc,x,y,0,<1>,bow_theta);
+
+  tmpa=head.next;
+  while (tmpa!=&head) {
+    theta=Arg(tmpa->dx,tmpa->dy);
+    Sprite3ZB(dc,tmpa->x,tmpa->y,0,<1>,theta);
+    tmpa=tmpa->next;
+  }
+}
+
+#define ANIMATE_SLEEP_MS        10
+
+U0 AnimateTask(I64)
+{
+  I64 x,y;
+  Arrow *tmpa,*tmpa1;
+  F64 dt,t0=tS;
+  while (TRUE) {
+    dt=tS-t0;
+    t0=tS;
+
+    x=ClampI64(ms.pos.x-Fs->parent_task->pix_left-Fs->parent_task->scroll_x,
+          box_x_min,box_x_max)+Fs->parent_task->pix_left+
+          Fs->parent_task->scroll_x;
+    y=ClampI64(ms.pos.y-Fs->parent_task->pix_top-Fs->parent_task->scroll_y,
+          box_y_min,box_y_max)+Fs->parent_task->pix_top+
+          Fs->parent_task->scroll_y;
+    if (ms.pos.x!=x || ms.pos.y!=y)
+      MsSet(x,y);
+
+    tmpa=head.next;
+    while (tmpa!=&head) {
+      tmpa1=tmpa->next;
+      tmpa->x+=tmpa->dx*dt;
+      tmpa->y+=tmpa->dy*dt;
+      if (!(-Fs->parent_task->scroll_x<=
+            tmpa->x<Fs->parent_task->pix_width-Fs->parent_task->scroll_x) ||
+            !(-Fs->parent_task->scroll_y<=
+            tmpa->y<Fs->parent_task->pix_height-Fs->parent_task->scroll_y)) {
+        QueRem(tmpa);
+        Free(tmpa);
+      }
+      tmpa=tmpa1;
+    }
+    Refresh;
+  }
+}
+
+U0 Init()
+{
+  I64 w=Fs->pix_width,
+        h=Fs->pix_height;
+  QueInit(&head);
+  bow_drawn=FALSE;
+  box_x_min=7*w/16;
+  box_y_min=6*h/8;
+  box_x_max=9*w/16;
+  box_y_max=7*h/8;
+  bow_theta=-pi/2;
+  bow_x=(box_x_min+box_x_max)/2;
+  bow_y=(box_y_min+box_y_max)/2;
+  MsSet(bow_x+Fs->pix_left+Fs->scroll_x,
+        bow_y+Fs->pix_top+Fs->scroll_y);
+}
+
+U0 CleanUp()
+{
+  QueDel(&head,TRUE);
+}
+
+U0 Zing()
+{
+  I64 arg1,arg2;
+  Arrow *tmpa;
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+  try {
+    while (TRUE)
+      switch (GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto zi_done;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          bow_x=arg1;
+          bow_y=arg2;
+          bow_drawn=TRUE;
+          break;
+        case MSG_MS_L_UP:
+          if(arg1-bow_x || arg2-bow_y) {
+            tmpa=MAlloc(sizeof(Arrow));
+            tmpa->dx=10.0*(bow_x-arg1);
+            tmpa->dy=10.0*(bow_y-arg2);
+            tmpa->x=arg1;
+            tmpa->y=arg2;
+            QueIns(tmpa,head.last);
+            Noise(50,110,114);
+          }
+          bow_drawn=FALSE;
+          break;
+      }
+zi_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+Zing;
+
+ diff --git a/public/Wb/Home/Src/Demo/Games/ZoneOut.HC.HTML b/public/Wb/Home/Src/Demo/Games/ZoneOut.HC.HTML new file mode 100755 index 0000000..a02fb8e --- /dev/null +++ b/public/Wb/Home/Src/Demo/Games/ZoneOut.HC.HTML @@ -0,0 +1,349 @@ + + + + + + + + + + + +
+RegDft("TempleOS/ZoneOut","F64 best_score=9999;\n");
+RegExe("TempleOS/ZoneOut");
+
+
+
+
+
+
+
+
+
+
+                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+                   <3>/* Graphics Not Rendered in HTML */
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+#define THEM_NUM        10
+
+class Obj
+{
+  Obj *next,*last;
+  F64 t0,theta;
+  I64 x,y,z;
+  Bool hit,pad[7];
+} us,them[THEM_NUM],shots;
+I64 num_them;
+F64 t0,tf;
+
+#define SCRN_SCALE      512
+#define TANK_HEIGHT     32
+
+U0 ZOTransform(CDC *dc,I64 *x,I64 *y,I64 *z)
+{
+  I64 zz;
+  Mat4x4MulXYZ(dc->r,x,y,z);
+  zz=*z;
+  if (zz<1) zz=1;
+  *x=SCRN_SCALE/2* *x/zz;
+  *y=SCRN_SCALE/2* (*y+TANK_HEIGHT)/zz;
+  *x+=dc->x;
+  *y+=dc->y;
+  *z+=dc->z;
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  Obj *tmpo;
+  I64 i,dd,y,w=task->pix_width,h=task->pix_height,cx=w>>1,cy=h>>1;
+  U8 *img;
+  F64 tt,theta;
+
+  theta=640*Wrap(2*us.theta)/pi;
+  Sprite3(dc,theta-1280,90,0,<4>);
+  Sprite3(dc,theta         ,90,0,<4>);
+  Sprite3(dc,theta+1280,90,0,<4>);
+
+  DCDepthBufAlloc(dc);
+  dc->transform=&ZOTransform;
+  dc->x=cx;
+  dc->y=cy;
+  Mat4x4TranslationEqu(dc->r,-us.x,-us.y,-us.z);
+  Mat4x4RotY(dc->r,us.theta-pi/2);
+  Mat4x4RotX(dc->r,pi/16);
+
+  dc->flags|=DCF_TRANSFORMATION;
+  for (i=0;i<THEM_NUM;i++) {
+    y=them[i].y;
+    tmpo=shots.next;
+    while (tmpo!=&shots) {
+      dd=SqrI64(them[i].x-tmpo->x)+SqrI64(them[i].z-tmpo->z);
+      if (dd<SCRN_SCALE/2*SCRN_SCALE/2) {
+        y-=Sqrt(dd);
+        if (!them[i].hit) {
+          them[i].hit=TRUE;
+          if (!--num_them) {
+            tf=tS;
+            if (tf-t0<best_score)
+              best_score=tf-t0;
+          }
+        }
+      }
+      tmpo=tmpo->next;
+    }
+    if (them[i].hit)
+      img=<2>;
+    else
+      img=<1>;
+    Sprite3YB(dc,them[i].x,y,them[i].z,img,-them[i].theta);
+  }
+  tmpo=shots.next;
+  while (tmpo!=&shots) {
+    Sprite3YB(dc,tmpo->x,tmpo->y,tmpo->z,<3>,-tmpo->theta);
+    tmpo=tmpo->next;
+  }
+  dc->flags&=~DCF_TRANSFORMATION;
+  dc->color=LTGREEN;
+  GrLine(dc,cx-5,cy,cx+5,cy);
+  GrLine(dc,cx,cy-5,cx,cy+5);
+  if (tf) {
+    dc->color=RED;
+    if (Blink)
+      GrPrint(dc,cx-(FONT_WIDTH*14)/2,cy-FONT_HEIGHT/2,"Game Completed");
+    tt=tf;
+  } else {
+    dc->color=BLACK;
+    GrLine(dc,cx-5,cy,cx+5,cy);
+    GrLine(dc,cx,cy-5,cx,cy+5);
+    tt=tS;
+  }
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Enemy:%d Time:%3.2f Best:%3.2f",num_them,tt-t0,best_score);
+}
+
+U0 Fire()
+{
+  Obj *tmpo=MAlloc(sizeof(Obj));
+  tmpo->x=us.x;
+  tmpo->y=TANK_HEIGHT;
+  tmpo->z=us.z;
+  tmpo->theta=us.theta;
+  tmpo->t0=tS;
+  QueIns(tmpo,shots.last);
+}
+
+U0 MoveUs(F64 theta)
+{
+  us.x+=0.1*SCRN_SCALE*Cos(theta);
+  us.z+=0.1*SCRN_SCALE*Sin(theta);
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  Obj *tmpo,*tmpo1;
+  while (TRUE) {
+    for (i=0;i<THEM_NUM;i++) {
+      them[i].x+=SCRN_SCALE/32*Cos(them[i].theta);
+      them[i].z+=SCRN_SCALE/32*Sin(them[i].theta);
+      them[i].theta+=Rand/100.0;
+    }
+    tmpo=shots.next;
+    while (tmpo!=&shots) {
+      tmpo1=tmpo->next;
+      if (tS-tmpo->t0>1.0) {
+        QueRem(tmpo);
+        Free(tmpo);
+      } else {
+        tmpo->x+=0.25*SCRN_SCALE*Cos(tmpo->theta);
+        tmpo->z+=0.25*SCRN_SCALE*Sin(tmpo->theta);
+      }
+      tmpo=tmpo1;
+    }
+    Sleep(20);
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  DocClear;
+  "$BG,LTCYAN$%h12c",'\n';
+  QueInit(&shots);
+  MemSet(&us,0,sizeof(us));
+  MemSet(them,0,sizeof(them));
+  num_them=THEM_NUM;
+  for (i=0;i<THEM_NUM;i++) {
+    them[i].x=10000*Rand-5000;
+    them[i].z=10000*Rand-5000;
+    them[i].theta=2*pi*Rand;
+    them[i].hit=FALSE;
+  }
+  tf=0;
+  t0=tS;
+}
+
+U0 CleanUp()
+{
+  QueDel(&shots,TRUE);
+}
+
+U0 SongTask(I64)
+{//Randomly generate (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG");
+    Play("5sD4B5D4B5qEsG4B5G4B5eD4GsB5F4B5FeD4A5qFG");
+    Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA");
+    Play("5eGDsFGFGqDE4eB5E4sG5D4G5DqF4sGAGA");
+  }
+}
+
+U0 ZoneOut()
+{
+  I64 sc;
+
+  PopUpOk(
+        "I refuse to rip-off the original\n"
+        "so this is intentionally crappy\n"
+        "and included for demonstration\n"
+        "purposes.\n\n"
+        "Write games, don't play them.\n");
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Fwd(,,SC_CURSOR_UP);"
+        "  Bwd(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "  Fire(,CH_SPACE);"
+        "}"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+WHITE;
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetKey(&sc)) {
+        case CH_SPACE:
+          Fire;
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_ESC:
+        case CH_SHIFT_ESC:
+          goto zo_done;
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_RIGHT:
+              us.theta-=pi/256;
+              break;
+            case SC_CURSOR_LEFT:
+              us.theta+=pi/256;
+              break;
+            case SC_CURSOR_UP:
+              MoveUs(us.theta);
+              break;
+            case SC_CURSOR_DOWN:
+              MoveUs(us.theta+pi);
+              break;
+          }
+          break;
+      }
+    }
+zo_done:
+  } catch
+    PutExcept;
+  CleanUp;
+  DocClear;
+  SettingsPop;
+  MenuPop;
+  RegWrite("TempleOS/ZoneOut","F64 best_score=%5.4f;\n",best_score);
+}
+
+ZoneOut;
+
+ diff --git a/public/Wb/Home/Src/Demo/GlblVars.HC.HTML b/public/Wb/Home/Src/Demo/GlblVars.HC.HTML new file mode 100755 index 0000000..14e5b15 --- /dev/null +++ b/public/Wb/Home/Src/Demo/GlblVars.HC.HTML @@ -0,0 +1,107 @@ + + + + + + + + + + + +
+//Demonstrates dynamic initialization of vars.
+//Static vars are, essentually, global vars.
+
+class Test
+{
+  I32 time;
+  U8 name[8];
+};
+
+Test g1[]={
+  {10,"Name1"},
+  {(tS%10.0)*100,"Name2"}, //Dynamic initialization
+  {30,"Name3"}
+};
+
+D(g1,sizeof(g1));
+"Time 1:%d\n",g1[1].time;
+
+U0 Main1()
+{
+  static Test s1[]={
+  {10,"Static1"},
+        {(tS%10.0)*100,"Static2"}, //Dynamic initialization
+        {30,"Static3"}
+  };
+  D(s1,sizeof(s1));
+  "Time 2:%d\n",s1[1].time;
+}
+
+Main1;
+
+/*Now, we'll use the data heap glbl option
+to force global vars onto the data heap.
+
+You can turn the data heap flag
+on and off within your programs, leaving
+ones which need initialization on the code heap.
+
+You can't dynamically initialize data heap
+glbls--they are consts.  This might be a silly
+point, but might res in odd differences, perhaps
+from the order things are evaluated.
+
+Data heap glbls are good for AOT modules
+because they don't take-up room in the .BIN.Z file.
+*/
+
+#ifjit
+#exe {Option(OPTf_GLBLS_ON_DATA_HEAP,ON);};
+
+Test g2[]={
+  {10,"name1"},
+  {(tS%10.0)*100,"name2"}, //No dynamic initialization--cvted to const
+  {30,"name3"}
+};
+
+D(g2,sizeof(g2));
+"Time 3:%d\n",g2[1].time;
+
+U0 Main2()
+{
+  static Test s2[]={
+  {10,"static1"},
+        {(tS%10.0)*100,"static2"}, //No dynamic initialization--cvted to const
+        {30,"static3"}
+  };
+  D(s2,sizeof(s2));
+  "Time 4:%d\n",s2[1].time;
+}
+
+Main2;
+
+#exe {Option(OPTf_GLBLS_ON_DATA_HEAP,ON);};
+#endif
+
+'\n';
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/3DPoly.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/3DPoly.HC.HTML new file mode 100755 index 0000000..585d93c --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/3DPoly.HC.HTML @@ -0,0 +1,148 @@ + + + + + + + + + + + +
+U0 Main()
+{
+  F64 theta=0,phi=0,omega=0;
+  CD3I32 poly[4];
+  CDC *dc=DCAlias;
+  DCDepthBufAlloc(dc);
+  dc->flags|=DCF_TRANSFORMATION|DCF_SYMMETRY;
+  try {
+    while (!ScanChar) {
+      DCDepthBufRst(dc);
+      DCSymmetrySet(dc,Fs->pix_width/2,Fs->pix_height/2,
+            ms.pos.x-Fs->pix_left-Fs->scroll_x,
+            ms.pos.y-Fs->pix_top-Fs->scroll_y);
+      dc->color=LTBLUE;
+      GrLine(dc,Fs->pix_width/2,Fs->pix_height/2,
+            ms.pos.x-Fs->pix_left-Fs->scroll_x,
+            ms.pos.y-Fs->pix_top-Fs->scroll_y);
+
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4RotX(dc->r,omega);
+      Mat4x4RotY(dc->r,phi);
+      Mat4x4RotZ(dc->r,theta);
+      DCMat4x4Set(dc,dc->r);
+
+      dc->x=Fs->pix_width/2;
+      dc->y=Fs->pix_height/2;
+      dc->z=500;
+
+      dc->color=GREEN;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=0;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=0;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=0;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=0;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=RED;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=50;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=50;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=50;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=50;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=BLUE;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=-50;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=-50;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=-50;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=-50;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=RED+GREEN<<16+ROPF_DITHER;
+      poly[0].x=50;
+      poly[0].y=150;
+      poly[0].z=50;
+      poly[1].x=275;
+      poly[1].y=100;
+      poly[1].z=50;
+      poly[2].x=275;
+      poly[2].y=100;
+      poly[2].z=0;
+      poly[3].x=50;
+      poly[3].y=150;
+      poly[3].z=0;
+      GrFillPoly3(dc,4,poly);
+
+      dc->color=BLUE+GREEN<<16+ROPF_DITHER;
+      poly[0].x=100;
+      poly[0].y=200;
+      poly[0].z=-50;
+      poly[1].x=155;
+      poly[1].y=200;
+      poly[1].z=-50;
+      poly[2].x=155;
+      poly[2].y=200;
+      poly[2].z=0;
+      poly[3].x=100;
+      poly[3].y=200;
+      poly[3].z=0;
+      GrFillPoly3(dc,4,poly);
+
+      Refresh;
+      DCFill;
+      theta+=2.1*pi/180.0;
+      phi+=1.1*pi/180.0;
+      omega+=0.5*pi/180.0;
+    }
+  } catch
+    PutExcept;
+
+  DCFill;
+  DCDel(dc);
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/BSpline.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/BSpline.HC.HTML new file mode 100755 index 0000000..6640b4a --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/BSpline.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+#define PTS_NUM 16
+
+U0 BSplineDemo()
+{
+  CDC *dc=DCAlias;
+  I64 arg1,arg2,i=0,msg_code;
+  CD3I32 c[PTS_NUM];
+
+  SettingsPush;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  DocClear;
+  "Sel ctrl points with left mouse.  Right when finished.\n";
+  DCFill;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_R_UP);
+    if (msg_code==MSG_MS_L_UP) {
+      c[i].x=arg1; c[i].y=arg2; c[i].z=0;
+      dc->color=GREEN;
+      GrCircle(dc,arg1,arg2,10);
+      i++;
+    }
+  } while (i<PTS_NUM && msg_code!=MSG_MS_R_UP);
+  dc->color=RED;
+  Gr2BSpline(dc,c,i,TRUE);
+  dc->color=BLUE;
+  Gr3BSpline(dc,c,i,TRUE);
+  DCDel(dc);
+  SettingsPop;
+
+  PressAKey;
+  DCFill;
+}
+
+BSplineDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Balloon.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Balloon.HC.HTML new file mode 100755 index 0000000..0f4a9e4 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Balloon.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+// Classic Commodore 64 Sprite
+
+U8 a[60]={0,127,0,1,255,192,3,255,224,3,231,224,
+          7,217,240,7,223,240,7,217,240,3,231,224,
+          3,255,224,3,255,224,2,255,160,1,127,64,
+          1,62,64,0,156,128,0,156,128,0,73,0,0,73,0,
+          0,62,0,0,62,0,0,28,0};
+
+U0 Balloon()
+{
+  I64 i,j,k;
+
+  CLI
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,0xF);
+  MemSetI64(text.vga_alias,0,640*480/64);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,RED+GREEN+8);
+  for (k=100;k<150;k++) {
+
+    for (i=0;i<20;i++)
+      for (j=0;j<3;j++)
+        *(text.vga_alias(I64)+0x1000+(i+k)*640/8+j)(U8 *)=a[i*3+j];
+
+    Busy(40000);
+
+    for (i=0;i<20;i++)
+      for (j=0;j<3;j++)
+        *(text.vga_alias(I64)+0x1000+(i+k)*640/8+j)(U8 *)=0;
+  }
+
+  STI
+  VGAFlush;
+}
+
+Balloon;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Blot.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Blot.HC.HTML new file mode 100755 index 0000000..ab6c543 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Blot.HC.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+CDC *dc=DCAlias;
+CDC *img1=DCNew(64,64);
+CDC *img2=DCNew(512,512);
+
+img1->color=COLOR_MONO;
+img1->thick=3;
+GrCircle(img1,30,30,20);
+GrFloodFill3(img1,30,30,0,TRUE);
+GrLine3(img1,60,0,0,0,60,0);
+
+DCFill(img2);
+img2->color=RED;
+img2->brush=img1;
+GrCircle(img2,256-30,256-30,128,67);
+img2->color=BLUE;
+img2->thick=6;
+img2->brush=NULL;
+GrLine3(img2,128,128,0,256+128,256+128,0);
+GrLine3(img2,256+128,128,0,128,256+128,0);
+
+img2->color=YELLOW;
+GrRect(img2,256-20,256-20,40,40);
+
+I64 i;
+for (i=0;i<256;i+=4) {
+  Refresh;
+  DCFill;
+  GrBlot(dc,i-256,i-256,img2);
+  Sleep(10);
+}
+U8 *tmpg=DC2Sprite(img1);
+Sprite(tmpg);
+Free(tmpg);
+"%h9c",'\n';
+
+DCDel(img1);
+DCDel(img2);
+DCDel(dc);
+
+PressAKey;
+DCFill;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Bounce.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Bounce.HC.HTML new file mode 100755 index 0000000..6fbb45d --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Bounce.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//Uses fixed-point-arithmetic.
+
+I64 x[16],y[16],dx[16],dy[16];
+
+U0 Init()
+{
+  I64 i;
+  F64 theta;
+  MemSet(x,0,sizeof(x));
+  MemSet(y,0,sizeof(y));
+  for (i=0;i<16;i++) {
+    theta=Rand*2*pi;
+    dx[i]=I32_MAX*Cos(theta);
+    dy[i]=I32_MAX*Sin(theta);
+  }
+}
+ 
+U0 Bounce()
+{
+  CDC *dc=DCAlias;
+  I64 i,ch;
+  Init;
+  try {//Catch <CTRL-ALT-c>
+    do {
+      for (i=0;i<16;i++) {
+        dc->color=i;
+        GrPlot(dc,x[i].i32[1],y[i].i32[1]);
+        x[i]+=dx[i];
+        y[i]+=dy[i];
+        if (!(0<=x[i]<Fs->pix_width<<32)) {
+          x[i]-=dx[i];
+          dx[i]=-dx[i];
+        }
+        if (!(0<=y[i]<Fs->pix_height<<32)) {
+          y[i]-=dy[i];
+          dy[i]=-dy[i];
+        }
+      }
+      Yield;
+    } while (!(ch=ScanChar) || (ch!=CH_SHIFT_ESC && ch!=CH_ESC));
+  } catch
+    PutExcept;
+  DCFill(dc);
+  DCDel(dc);
+}
+ 
+Bounce;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Box.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Box.HC.HTML new file mode 100755 index 0000000..ad6d4fd --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Box.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+I64 glbl_r[4][4];
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 *old_r=dc->r;
+  dc->thick=2;
+  dc->color=RED;
+  dc->x=200;
+  dc->y=200;
+  dc->flags|=DCF_TRANSFORMATION;
+  DCMat4x4Set(dc,glbl_r); //This assigns to dc->r and sets r_norm.
+  GrLine3(dc,-100,-100,-100, -100, 100,-100);
+  GrLine3(dc,-100, 100,-100,  100, 100,-100);
+  GrLine3(dc, 100, 100,-100,  100,-100,-100);
+  GrLine3(dc, 100,-100,-100, -100,-100,-100);
+  GrLine3(dc,-100,-100, 100, -100, 100, 100);
+  GrLine3(dc,-100, 100, 100,  100, 100, 100);
+  GrLine3(dc, 100, 100, 100,  100,-100, 100);
+  GrLine3(dc, 100,-100, 100, -100,-100, 100);
+  GrLine3(dc,-100,-100, 100, -100,-100,-100);
+  GrLine3(dc,-100, 100, 100, -100, 100,-100);
+  GrLine3(dc, 100, 100, 100,  100, 100,-100);
+  GrLine3(dc, 100,-100, 100,  100,-100,-100);
+  dc->r=old_r;
+}
+
+U0 Box()
+{
+  F64 theta=0,phi=0,omega=0,s=1,s1=1.05;
+  SettingsPush; //See SettingsPush
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  while (!ScanChar) {
+    Mat4x4IdentEqu(glbl_r);
+    Mat4x4RotZ(glbl_r,theta);
+    Mat4x4RotX(glbl_r,phi);
+    Mat4x4RotZ(glbl_r,omega);
+    Mat4x4Scale(glbl_r,s);
+
+    Sleep(20);
+    theta+=2*pi/70;
+    phi+=2*pi/90;
+    omega+=2*pi/110;
+    s*=s1;
+    if ( !(0.2<s<1.4) ) s1=1/s1;
+  }
+  SettingsPop;
+}
+
+Box;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Cartesian.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Cartesian.HC.HTML new file mode 100755 index 0000000..b7848df --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Cartesian.HC.HTML @@ -0,0 +1,79 @@ + + + + + + + + + + + +
+//x must be global.
+//Might as well make y global.
+
+F64 x,y,y_last;
+
+U0 Cartesian()
+{
+  U8 *st;
+  I64 ch=0,h,v;
+  Bool first;
+  CDC *dc=DCAlias;
+  do {
+    DocClear;
+    "Enter algebraic equation to graph.\n"
+          "Example: y=2*x\n"
+          "y=";
+    if (st=GetStr) {
+      if (*st) {
+        h=Fs->pix_width/2;
+        v=Fs->pix_height/2;
+        dc->color=RED;
+        GrLine(dc,h,0,h,2*v+1);
+        GrLine(dc,0,v,2*h+1,v);
+        first=TRUE;
+        dc->color=BLACK;
+        for (x=-h;x<=h;x++) {
+          y=-ExePrint("ToF64(%s);",st)(F64);
+          if (!first)
+            GrLine(dc,x-1+h,y_last+v,x+h,y+v);
+          y_last=y;
+          first=FALSE;
+        }
+        ch=GetChar;
+      } else
+        ch=CH_SHIFT_ESC;
+      Free(st);
+    } else
+      ch=CH_SHIFT_ESC;
+    DCFill;
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+  DCDel(dc);
+}
+
+Cartesian;
+
+//For better performance, compile the expression entered by the
+//user one time with LexExpression2Bin() and use Call().
+//See ::/Demo/CompileDemo.HC.
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/CharAnimation.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/CharAnimation.HC.HTML new file mode 100755 index 0000000..35b9376 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/CharAnimation.HC.HTML @@ -0,0 +1,61 @@ + + + + + + + + + + + +
+U8 *old_font=text.font;
+
+// See ::/Kernel/FontStd.HC, ::/Demo/ScrnCodes.HC,
+//::/Demo/ExtChars.HC, and ::/Demo/Graphics/FontEd.HC.
+
+U64 waves[4]={
+0x0011AA440011AA44,0x0022558800225588,
+0x0044AA110044AA11,0x0088552200885522};
+
+U0 AnimateEndCB()
+{
+  text.font=old_font;
+  Exit;
+}
+
+U0 AnimateTask(I64)
+{
+  I64 i;
+  U64 *font=MAlloc(256*8);
+  Fs->task_end_cb=&AnimateEndCB;
+  MemCpy(font,text.font,256*8);
+  text.font=font;
+  while (TRUE) {
+    font[CH_SPACE]=waves[i++&0x3];
+    Sleep(100);
+  }
+}
+
+Spawn(&AnimateTask,NULL,"Animate",,Fs);
+TaskRep;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Collision.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Collision.HC.HTML new file mode 100755 index 0000000..ead78e4 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Collision.HC.HTML @@ -0,0 +1,73 @@ + + + + + + + + + + + +
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 x,y;
+
+  x=ms.pos.x-task->pix_left;
+  y=ms.pos.y-task->pix_top;
+  Sprite3(dc,x,y,0,<1>);
+
+  x=task->pix_width>>1;
+  y=task->pix_height>>1;
+
+  dc->color=ROP_COLLISION;
+  dc->bkcolor=WHITE;
+  dc->collision_cnt=0;
+  Sprite3(dc,x,y,0,<1>);
+
+  dc->color=ROP_EQU;
+  GrPrint(dc,0,(task->pix_height-FONT_HEIGHT)>>1,
+        "Collisions:%d",dc->collision_cnt);
+
+  if (!dc->collision_cnt)
+    Sprite3(dc,x,y,0,<1>);
+  else
+    Sprite3(dc,x,y,0,<2>);
+}
+
+U0 Collision()
+{
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  PressAKey;
+  SettingsPop;
+}
+
+Collision;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/CommonAncestor.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/CommonAncestor.HC.HTML new file mode 100755 index 0000000..051928e --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/CommonAncestor.HC.HTML @@ -0,0 +1,151 @@ + + + + + + + + + + + +
+#define N       32
+ 
+class Node
+{
+  Node *left,*right;
+  I64 n;
+};
+ 
+I64 n1,n2,common_ancestor;
+Node *root;
+ 
+#define X_SPACING       16
+#define Y_SPACING       45
+#define ARROW_SPACING   3
+ 
+U0 ShowTree(CDC *dc,Node *tmpn,I64 *_node_x,I64 *_tree_x,I64 y)
+{
+  I64 node_x;
+  if (tmpn) {
+    if (tmpn->left) {
+      ShowTree(dc,tmpn->left,&node_x,_tree_x,y+Y_SPACING);
+      dc->color=BLUE;
+      GrArrow3(dc,*_tree_x,y,0,
+            node_x+ARROW_SPACING,y+Y_SPACING-ARROW_SPACING,0);
+    }
+    if (tmpn->n==n1 || tmpn->n==n2) {
+      if (tmpn->n==common_ancestor)
+        dc->color=YELLOW;
+      else
+        dc->color=RED;
+    } else if (tmpn->n==common_ancestor)
+      dc->color=GREEN;
+    else
+      dc->color=BLUE;
+
+    *_node_x=*_tree_x;
+    GrPrint(dc,*_node_x,y,"%d",tmpn->n);
+    *_tree_x+=X_SPACING;
+
+    if (tmpn->right) {
+      ShowTree(dc,tmpn->right,&node_x,_tree_x,y+Y_SPACING);
+      dc->color=BLUE;
+      GrArrow3(dc,*_node_x,y,0,
+            node_x-ARROW_SPACING,y+Y_SPACING-ARROW_SPACING,0);
+    }
+  }
+}
+ 
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 node_x=0,tree_x=0;
+  ShowTree(dc,root,&node_x,&tree_x,20);
+}
+
+U0 TreeAdd(Node **_root,Node *tmpn)
+{
+  Node *root=*_root;
+  if (!root)
+    *_root=tmpn;
+  else if (tmpn->n==root->n)
+    Free(tmpn);
+  else if (tmpn->n<root->n)
+    TreeAdd(&root->left,tmpn);
+  else
+    TreeAdd(&root->right,tmpn);
+}
+
+U0 TreeNew()
+{
+  I64 i;
+  Node *tmpn;
+  for (i=0;i<N;i++) {
+    tmpn=CAlloc(sizeof(Node));
+    tmpn->n=RandU16%N;
+
+    if (i==N-1)
+      n1=tmpn->n;
+    else if (i==N-2)
+      n2=tmpn->n;
+
+    TreeAdd(&root,tmpn);
+    Sleep(50);
+  }
+}
+ 
+U0 TreeCommonAncestorFind(Node *root)
+{
+  if (root && root->n!=n1 && root->n!=n2) {
+    common_ancestor=root->n;
+    if (n1<root->n && n2<root->n)
+      TreeCommonAncestorFind(root->left);
+    else if (n1>root->n && n2>root->n)
+      TreeCommonAncestorFind(root->right);
+  }
+}
+ 
+U0 TreeCommonAncestor()
+{//Make tree and find common ancestor to n1 & n2.
+  root=NULL;
+  n1=n2=common_ancestor=0;
+
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  DocClear;
+  "Scroll with {CTRL-Left Grab}.\n";
+  try {
+    TreeNew;
+    TreeCommonAncestorFind(root);
+    PressAKey;
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+TreeCommonAncestor;
+/*Be careful with recursive routines in TempleOS
+because the stack does not grow and will overflow.
+
+See ::/Demo/StkGrow.HC.
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Doodle.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Doodle.HC.HTML new file mode 100755 index 0000000..61d432f --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Doodle.HC.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+//This is a drawing program
+
+U0 Doodle()
+{
+  I64 msg_code,i,x1,y1,x2,y2,arg1,arg2,color=BLACK;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_MS_R_UP:
+        i=PopUpColor;
+        if (i>=0) color=i;
+        break;
+      case MSG_MS_L_DOWN:
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        dc->color=ROP_XOR+color^TRANSPARENT;
+        dc->thick=7;
+        do {
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          x2=arg1; y2=arg2;
+        } while (msg_code!=MSG_MS_L_UP);
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        break;
+      case MSG_KEY_DOWN:
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || !arg1);
+  GetMsg(,,1<<MSG_KEY_UP);
+  DCFill;
+  DCDel(dc);
+  SettingsPop;
+}
+
+Doodle;  //Execute when #included
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/EdSprite.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/EdSprite.HC.HTML new file mode 100755 index 0000000..650af96 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/EdSprite.HC.HTML @@ -0,0 +1,123 @@ + + + + + + + + + + + +
+/*Add an outline to Sprites and
+print them to the cmd line.  They
+can be cut/pasted from there.
+*/
+<1>/* Graphics Not Rendered in HTML */
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+
+<6>/* Graphics Not Rendered in HTML */
+
+
+
+<7>/* Graphics Not Rendered in HTML */
+
+
+<8>/* Graphics Not Rendered in HTML */
+
+
+
+<9>/* Graphics Not Rendered in HTML */
+
+
+
+<10>/* Graphics Not Rendered in HTML */
+
+
+
+<11>/* Graphics Not Rendered in HTML */
+
+
+
+<12>/* Graphics Not Rendered in HTML */
+
+
+
+#define NUM     12
+
+U8 *in_img[NUM]={<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>};
+
+U0 OutLine()
+{
+  I64 n,minx,maxx,miny,maxy,w,h,i,j,k,c;
+  U8 *out_img;
+  CDC *dc;
+  for (n=0;n<NUM;n++) {
+    SpriteExtents(in_img[n],&minx,&maxx,&miny,&maxy);
+    w=maxx-minx+1+2;
+    h=maxy-miny+1+2;
+    dc=DCNew(w,h);
+    dc->color=TRANSPARENT;
+    GrRect(dc,0,0,w,h);
+    Sprite3(dc,-minx+1,-miny+1,0,in_img[n]);
+
+    for (i=0;i<h;i++)
+      for (j=0;j<w;j++)
+        if (GrPeek(dc,j,i)==TRANSPARENT) {
+          for (k=0;k<8;k++) {
+            c=GrPeek(dc,j+gr_x_offsets[k],i+gr_y_offsets[k]);
+            if (c!=-1 && c!=BLACK && c!=TRANSPARENT) {
+              dc->color=BLACK;
+              GrPlot(dc,j,i);
+              break;
+            }
+          }
+        }
+
+    out_img=DC2Sprite(dc);
+    '\n';
+    Sprite(out_img);
+    '\n\n\n\n';
+
+    DCDel(dc);
+    Free(out_img);
+  }
+}
+
+OutLine;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Elephant.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Elephant.HC.HTML new file mode 100755 index 0000000..69d317c --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Elephant.HC.HTML @@ -0,0 +1,236 @@ + + + + + + + + + + + +
+//Scroll Down
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+    <3>/* Graphics Not Rendered in HTML */
+
+
+
+    <4>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+    <5>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    <6>/* Graphics Not Rendered in HTML */
+
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  U8 *tmps;
+  Sprite3(dc,100,task->pix_height-60,0,<3>);
+  Sprite3(dc,194,task->pix_height-140,0,<4>);
+  Sprite3(dc,400,task->pix_height-10,0,<5>);
+  Sprite3(dc,50,task->pix_height-160,0,<6>);
+  tmps=SpriteInterpolate(Tri(tS,2.0),<1>,<2>);
+  Sprite3(dc,0,task->pix_height,0,tmps);
+  Free(tmps);
+}
+
+U0 SongTask(I64)
+{//Randomly generate (by God :-)
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("4qG5eCGqE4A5FCeDF4qB");
+    Play("4G5eCGqE4A5FCeDF4qB");
+    Play("4B5DeF4G5etE4BAqBAetA5EDeE4G");
+    Play("4qB5DeF4G5etE4BAqBAetA5EDeE4G");
+  }
+}
+
+U0 Main()
+{
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  Fs->text_attr=YELLOW<<4+BLACK;
+  "$BG,LTCYAN$%h31c",'\n';
+  View;
+  SettingsPop;
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Extents.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Extents.HC.HTML new file mode 100755 index 0000000..61851bc --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Extents.HC.HTML @@ -0,0 +1,76 @@ + + + + + + + + + + + +
+//Test image which we will determine the extents of.
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+U0 Extents()
+{
+  CDC *dc=DCAlias;
+  I64 min_x,max_x,min_y,max_y;
+
+  //Scrn, not win coordinates.
+  I64 h=Fs->pix_left+Fs->scroll_x,v=Fs->pix_top+Fs->scroll_y;
+
+  DocClear;
+  DCFill;
+
+  //This sets a flag to record the
+  //extents of what we draw and inits
+  //the max's and min's.  Vals are
+  //scrn coordinates.
+  DCExtentsInit(dc);
+
+  dc->thick=3;
+  Sprite3(dc,40,GR_HEIGHT>>1,0,<1>);
+
+  dc->color=LTRED;
+  dc->thick=1;
+
+  //This box is the extents.
+  GrLine(dc,dc->min_x-h,dc->min_y-v,dc->max_x-h,dc->min_y-v);
+  GrLine(dc,dc->min_x-h,dc->min_y-v,dc->min_x-h,dc->max_y-v);
+  GrLine(dc,dc->max_x-h,dc->max_y-v,dc->max_x-h,dc->min_y-v);
+  GrLine(dc,dc->max_x-h,dc->max_y-v,dc->min_x-h,dc->max_y-v);
+
+  DCDel(dc);
+  PressAKey;
+  DCFill;
+
+  SpriteExtents(<1>,&min_x,&max_x,&min_y,&max_y);
+  "X: %d to %d\n",min_x,max_x;
+  "Y: %d to %d\n",min_y,max_y;
+}
+
+Extents;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/FontEd.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/FontEd.HC.HTML new file mode 100755 index 0000000..2c24ef1 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/FontEd.HC.HTML @@ -0,0 +1,183 @@ + + + + + + + + + + + +
+/*After making a font...
+
+You can save it as a binary file with:
+        FileWrite("filename.BIN.Z",text.font,256*FONT_HEIGHT);
+
+You can load it with:
+        U64 *my_font=FileRead("filename.BIN.Z");
+        text.aux_font=my_font;
+
+<CTRL-ALT-f> will toggle main font and aux_font.
+
+If you want to change the system font permanently,
+save to a file with this font editor program
+and cut and paste the code into ::/Kernel/FontStd.HC.
+You will need to recompile Kernel by calling BootHDIns().
+
+See ::/Demo/ExtChars.HC, ::/Demo/Games/CharDemo.HC,
+::/Demo/Graphics/CharAnimation.HC and ::/Demo/ScrnCodes.HC.
+*/
+
+#define BLOW_UP_CHAR_X  (18*FONT_WIDTH)
+#define BLOW_UP_CHAR_Y  (4*FONT_HEIGHT)
+
+U8 cur_ch;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,j,k,c;
+  TextPrint(task,0,0,BLUE<<4+YELLOW,"Press <CTRL-ALT-f> to Toggle Aux Font.");
+  k=0;
+  for (i=0;i<16;i++)
+    for (j=0;j<16;j++) {
+      if (k==cur_ch) {
+        if (Blink)
+          c=(BLUE<<4+YELLOW)<<8 + k++;
+        else
+          c=(YELLOW<<4+BLUE)<<8 + k++;
+      } else
+        c=(BLUE<<4+WHITE)<<8 + k++;
+      TextChar(task,,j,i+2,c);
+    }
+
+  k=0;
+  for (i=0;i<FONT_HEIGHT;i++)
+    for (j=0;j<FONT_WIDTH;j++) {
+      if (Bt(&text.font[cur_ch],k++))
+        dc->color=YELLOW;
+      else
+        dc->color=BLUE;
+      GrRect(dc,BLOW_UP_CHAR_X+j*FONT_WIDTH,
+            BLOW_UP_CHAR_Y+i*FONT_HEIGHT,
+            FONT_WIDTH,FONT_HEIGHT);
+    }
+}
+
+U0 FESave(Bool pmt)
+{
+  U8 old_draw_it=Fs->draw_it;
+  CDoc *doc=DocNew;
+  I64 i;
+  for (i=0;i<256;i++) {
+    DocPrint(doc,"0x%016X,",text.font[i]);
+    if (Bt(char_bmp_safe_dollar,i))
+      DocPrint(doc,"//%c",i);
+    else if (i=='$')
+      DocPrint(doc,"//$$",i);
+    DocPrint(doc,"\n");
+  }
+  Fs->draw_it=NULL;
+  DocWrite(doc,pmt);
+  Fs->draw_it=old_draw_it;
+  DocDel(doc);
+}
+
+U0 FontEd()
+{
+  I64 msg_code,arg1,arg2,k;
+  SettingsPush; //See SettingsPush
+  MenuPush(
+        "File {"
+        "  SaveAs(,CH_CTRLA);"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}");
+  AutoComplete;
+  DocCursor;
+  DocClear;
+  Fs->win_inhibit|=WIG_DBL_CLICK;
+  cur_ch=0;
+  try {
+    Fs->draw_it=&DrawIt;
+    while (TRUE) {
+      switch (msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_R_DOWN|1<<MSG_MS_MOVE)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case 0:
+              switch (arg2.u8[0]) {
+                case SC_CURSOR_LEFT:
+                  cur_ch--;
+                  break;
+                case SC_CURSOR_RIGHT:
+                  cur_ch++;
+                  break;
+                case SC_CURSOR_UP:
+                  cur_ch-=16;
+                  break;
+                case SC_CURSOR_DOWN:
+                  cur_ch+=16;
+                  break;
+
+              }
+              break;
+              goto fe_done;
+            case CH_CTRLA:
+              FESave(TRUE);
+              break;
+            case CH_ESC:
+              FESave(FALSE);
+            case CH_SHIFT_ESC:
+              goto fe_done;
+            default:
+              cur_ch=arg1;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+        case MSG_MS_R_DOWN:
+          if (0<=arg1<FONT_WIDTH*16 && 0<=arg2-2*FONT_HEIGHT<FONT_HEIGHT*16) {
+            cur_ch=(arg2/FONT_HEIGHT-2)*16+arg1/FONT_WIDTH;
+            break;
+          } //fall through
+        case MSG_MS_MOVE:
+          k=((arg2-BLOW_UP_CHAR_Y)/FONT_HEIGHT)*FONT_WIDTH+
+                (arg1-BLOW_UP_CHAR_X)/FONT_WIDTH;
+          if (0<=k<FONT_WIDTH*FONT_HEIGHT) {
+            if (ms.lb||msg_code==MSG_MS_L_DOWN)
+              Bts(&text.font[cur_ch],k);
+            if (ms.rb||msg_code==MSG_MS_R_DOWN)
+              Btr(&text.font[cur_ch],k);
+          }
+          break;
+      }
+    }
+fe_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  MenuPop;
+  SettingsPop;
+}
+
+FontEd;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Grid.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Grid.HC.HTML new file mode 100755 index 0000000..706e348 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Grid.HC.HTML @@ -0,0 +1,61 @@ + + + + + + + + + + + +
+#define GRID    5
+
+U0 DrawMyMs(CDC *dc,I64 x,I64 y)
+{
+  dc->thick=1;
+  dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
+  GrRect(dc,x,y,GRID,GRID);
+}
+
+U0 GridDemo()
+{
+  CGridGlbls old_grid;
+  U0 (*old_draw_ms)(CDC *dc,I64 x,I64 y); //Can't init this type of var.
+  MemCpy(&old_grid,&ms_grid,sizeof(CGridGlbls));
+  GridInit;
+  ms_grid.snap=TRUE; //You can set other stuff.
+  ms_grid.x=GRID;
+  ms_grid.y=GRID;
+  old_draw_ms=gr.fp_draw_ms;
+  gr.fp_draw_ms=&DrawMyMs;
+  while (!ms.lb)  {//Left bttn to exit.
+    GrPlot(,ms.pos.x,ms.pos.y);
+    Yield;
+  }
+  DCFill;
+  gr.fp_draw_ms=old_draw_ms;
+  MemCpy(&ms_grid,&old_grid,sizeof(CGridGlbls));
+}
+
+GridDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Hanoi.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Hanoi.HC.HTML new file mode 100755 index 0000000..076bba6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Hanoi.HC.HTML @@ -0,0 +1,185 @@ + + + + + + + + + + + +
+#define DISKS_NUM       6
+#define PEDESTAL_HEIGHT 20
+#define DISK_HEIGHT     7
+#define DISK_UNIT_WIDTH 5
+
+I64 poles_x[3];
+I64 disks_x[DISKS_NUM],disks_y[DISKS_NUM],disks_pole[DISKS_NUM];
+
+I64 OtherPole(I64 pole1,I64 pole2)
+{
+  return 3-pole1-pole2;
+}
+ 
+I64 TopDisk(I64 pole)
+{
+  I64 i;
+  for (i=0;i<DISKS_NUM;i++)
+    if (disks_pole[i]==pole)
+      return i;
+  return -1;
+}
+
+I64 PosInStk(I64 pole,I64 disk)
+{
+  I64 res=0,i;
+  for (i=DISKS_NUM-1;i>disk;i--)
+    if (disks_pole[i]==pole)
+      res++;
+  return res;
+}
+
+U0 SetDisksRestXY()
+{
+  I64 i;
+  for (i=0;i<DISKS_NUM;i++) {
+    disks_x[i]=poles_x[disks_pole[i]];
+    disks_y[i]=Fs->pix_height-PEDESTAL_HEIGHT
+          -(DISK_HEIGHT+1)/2-1-(DISK_HEIGHT+1)*PosInStk(disks_pole[i],i);
+  }
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i;
+
+  for (i=0;i<3;i++)
+    poles_x[i]=(1+i)*task->pix_width/4;
+
+  dc->color=BLACK;
+  GrRect(dc,poles_x[0]-50,task->pix_height-PEDESTAL_HEIGHT,
+        poles_x[2]-poles_x[0]+100,PEDESTAL_HEIGHT-FONT_HEIGHT);
+  dc->color=DKGRAY;
+  GrRect(dc,poles_x[0]-49,task->pix_height-PEDESTAL_HEIGHT+1,
+        poles_x[2]-poles_x[0]+98,PEDESTAL_HEIGHT-FONT_HEIGHT-2);
+
+  for (i=0;i<3;i++) {
+    dc->color=BLACK;
+    GrRect(dc,poles_x[i]-3,
+          task->pix_height-PEDESTAL_HEIGHT-(DISKS_NUM+1)*(DISK_HEIGHT+1),
+          7,(DISKS_NUM+1)*(DISK_HEIGHT+1));
+    dc->color=YELLOW;
+    GrRect(dc,poles_x[i]-2,
+          task->pix_height-PEDESTAL_HEIGHT+1-(DISKS_NUM+1)*(DISK_HEIGHT+1),
+          5,(DISKS_NUM+1)*(DISK_HEIGHT+1)-1);
+  }
+
+  for (i=0;i<DISKS_NUM;i++) {
+    dc->color=BLACK;
+    GrRect(dc,disks_x[i]-(i+1)*DISK_UNIT_WIDTH,
+          disks_y[i]-DISK_HEIGHT/2,(i+1)*(DISK_UNIT_WIDTH*2)+1,DISK_HEIGHT);
+    dc->color=gr_rainbow_10[i];
+    GrRect(dc,disks_x[i]-(i+1)*DISK_UNIT_WIDTH+1,
+          disks_y[i]-DISK_HEIGHT/2+1,(i+1)*(DISK_UNIT_WIDTH*2)-1,DISK_HEIGHT-2);
+  }
+}
+
+U0 MySleep()
+{
+  if (ScanChar)
+    throw;
+  Sleep(3);
+}
+
+U0 MoveDisks(I64 src_pole,I64 dst_pole,I64 num)
+{
+  I64 top,x,y;
+  if (num>1)
+    MoveDisks(src_pole,OtherPole(src_pole,dst_pole),num-1);
+  DocClear;
+  "$CM+BY,0,0$Disk:%d from %d to %d\n",TopDisk(src_pole),src_pole,dst_pole;
+
+  top=TopDisk(src_pole);
+  for (y=disks_y[top];
+        y>Fs->pix_height-PEDESTAL_HEIGHT-(DISK_HEIGHT+1)/2
+        -(DISK_HEIGHT+1)*(DISKS_NUM+2);y--) {
+    disks_y[top]=y;
+    MySleep;
+  }
+  if (src_pole<dst_pole)
+    for (x=poles_x[src_pole];x<=poles_x[dst_pole];x++) {
+      disks_x[top]=x;
+      MySleep;
+    }
+  else
+    for (x=poles_x[src_pole];x>=poles_x[dst_pole];x--) {
+      disks_x[top]=x;
+      MySleep;
+    }
+
+  disks_pole[top]=dst_pole;
+  for (y=disks_y[top];
+        y<Fs->pix_height-PEDESTAL_HEIGHT-(DISK_HEIGHT+1)/2-1
+        -(DISK_HEIGHT+1)*PosInStk(dst_pole,top);y++) {
+    disks_y[top]=y;
+    MySleep;
+  }
+  SetDisksRestXY;
+  if (num>1)
+    MoveDisks(OtherPole(src_pole,dst_pole),dst_pole,num-1);
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<3;i++)
+    poles_x[i]=(1+i)*Fs->pix_width/4;
+
+  for (i=0;i<DISKS_NUM;i++)
+    disks_pole[i]=0;
+
+  SetDisksRestXY;
+}
+
+U0 Hanoi()
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+
+  Sleep(1000);
+  try {
+    MoveDisks(0,2,DISKS_NUM);
+    Beep; Beep;
+    DocClear;
+    DocBottom;
+    PressAKey;
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+}
+
+Hanoi;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Lattice.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Lattice.HC.HTML new file mode 100755 index 0000000..be3317c --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Lattice.HC.HTML @@ -0,0 +1,297 @@ + + + + + + + + + + + +
+#define TURTLE_SIZE             4
+#define TURTLE_SPEED_STEP       2
+
+#define ANGLES  35
+F64 angles[ANGLES]={
+-2*pi/1,-2*pi/2,-2*pi/3,-2*pi/4,-2*pi/5,
+-2*pi/6,-2*pi/8,-2*pi/9,-2*pi/10,
+-2*pi/12,-2*pi/15,-2*pi/18,-2*pi/20,
+-2*pi/24,-2*pi/30,-2*pi/36,-2*pi/40,
+0,
+2*pi/40,2*pi/36,2*pi/30,2*pi/24,
+2*pi/20,2*pi/18,2*pi/15,2*pi/12,
+2*pi/10,2*pi/9,2*pi/8,2*pi/6,
+2*pi/5,2*pi/4,2*pi/3,2*pi/2,2*pi/1
+};
+
+class Turtle
+{
+  F64 x,y,z,speed,theta,w;
+  I64 dtheta_idx;
+  CColorROPU16 edge,middle;
+  Bool ends,first;
+} tt;
+
+U0 TurtlePlot(CDC *dc,Turtle *t,CColorROPU16 edge,CColorROPU16 middle)
+{
+  F64 w=t->w/2.0-1;
+  if (w<0) w=0;
+  dc->color=middle;
+  GrLine3(dc,t->x+w*Cos(t->theta+pi/2),t->y+w*Sin(t->theta+pi/2),t->z,
+        t->x+w*Cos(t->theta-pi/2),t->y+w*Sin(t->theta-pi/2),t->z);
+  w=t->w/2.0;
+  dc->color=edge;
+  GrPlot3(dc,t->x+w*Cos(t->theta+pi/2),t->y+w*Sin(t->theta+pi/2),t->z);
+  GrPlot3(dc,t->x+w*Cos(t->theta-pi/2),t->y+w*Sin(t->theta-pi/2),t->z);
+}
+
+U0 TurtleMicroMove(Turtle *t,F64 dt)
+{
+  t->x+=dt*t->speed*Cos(t->theta);
+  t->y+=dt*t->speed*Sin(t->theta);
+  t->theta=Wrap(t->theta+dt*angles[t->dtheta_idx]);
+}
+
+U0 TurtleEnd(CDC *dc,Turtle *t,CColorROPU16 edge,CColorROPU16 middle,F64 theta)
+{
+  F64 r,x,y2;
+  Turtle t2;
+  if (r=t->w) {
+    MemCpy(&t2,t,sizeof(Turtle));  //Save
+    x=0;
+    while (TRUE) {
+      t->x+=1/r*Cos(theta);
+      t->y+=1/r*Sin(theta);
+      x+=1/r;
+      y2=r*r-4*x*x;
+      if (y2>=0) {
+        t->w=Sqrt(y2);
+        TurtlePlot(dc,t,edge,middle);
+      } else
+        break;
+    }
+    MemCpy(t,&t2,sizeof(Turtle));
+  }
+}
+
+U0 TurtleMove(CDC *dc,Turtle *t,CColorROPU16 edge,CColorROPU16 middle)
+{
+  I64 i,l=16*AbsI64(t->w+1)*AbsI64(t->speed+1);
+
+  if (t->ends && t->first)
+    TurtleEnd(dc,t,edge,middle,t->theta+pi);
+  t->first=FALSE;
+
+  for (i=0;i<l;i++) {
+    TurtleMicroMove(t,1.0/l);
+    TurtlePlot(dc,t,edge,middle);
+  }
+  if (t->ends)
+    TurtleEnd(dc,t,edge,middle,t->theta);
+}
+
+U0 TurtleInit(Turtle *t)
+{
+  MemSet(t,0,sizeof(Turtle));
+  t->x=Fs->pix_width>>1;
+  t->y=Fs->pix_height>>1;
+  t->z=5;
+  t->edge=BLACK;
+  t->middle=YELLOW;
+  t->dtheta_idx=ANGLES/2;
+  t->first=TRUE;
+  t->ends=TRUE;
+}
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  Turtle t2;
+  MemCpy(&t2,&tt,sizeof(Turtle));
+  GrPrint(dc,0,0,"Layer:%f Speed:%f theta:%5.1f dtheta:%5.1f Width:%f",
+        tt.z,tt.speed,tt.theta*180/pi,angles[tt.dtheta_idx]*180/pi,tt.w);
+
+  TurtleMove(dc,&t2,RED,LTRED);
+  dc->color=LTRED;
+  GrLine(dc,t2.x+TURTLE_SIZE*Cos(t2.theta+pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta+pi/2),
+        t2.x+TURTLE_SIZE*Cos(t2.theta-pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta-pi/2));
+  GrLine(dc,t2.x+TURTLE_SIZE*Cos(t2.theta+pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta+pi/2),
+        t2.x+TURTLE_SIZE*Cos(t2.theta),    t2.y+TURTLE_SIZE*Sin(t2.theta));
+  GrLine(dc,t2.x+TURTLE_SIZE*Cos(t2.theta-pi/2),t2.y+TURTLE_SIZE*Sin(t2.theta-pi/2),
+        t2.x+TURTLE_SIZE*Cos(t2.theta),    t2.y+TURTLE_SIZE*Sin(t2.theta));
+}
+
+U0 SetMenu()
+{
+  I64 i;
+  U8 buf[STR_LEN];
+  CMenuEntry *tmpse;
+  for (i=0;i<=9;i++) {
+    StrPrint(buf,"Settings/Layer%d",i);
+    if (tmpse=MenuEntryFind(Fs->cur_menu,buf)) {
+      if (i==tt.z)
+        tmpse->checked=TRUE;
+      else
+        tmpse->checked=FALSE;
+    }
+  }
+  if (tmpse=MenuEntryFind(Fs->cur_menu,"Settings/Ends")) {
+    if (tt.ends)
+      tmpse->checked=TRUE;
+    else
+      tmpse->checked=FALSE;
+  }
+}
+
+U0 Lattice()
+{
+  Bool aim=FALSE;
+  I64 arg1,arg2;
+  CDC  *dc=DCAlias;
+  DCDepthBufAlloc(dc);
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Step(,CH_SPACE);"
+        "  Accelerator(,,SC_CURSOR_UP);"
+        "  Break(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        "Settings {"
+        "  Color(,'c');"
+        "  Wider(,'+');"
+        "  Narrower(,'-');"
+        "  Ends(,'e');"
+        "  Layer0(,'0');"
+        "  Layer1(,'1');"
+        "  Layer2(,'2');"
+        "  Layer3(,'3');"
+        "  Layer4(,'4');"
+        "  Layer5(,'5');"
+        "  Layer6(,'6');"
+        "  Layer7(,'7');"
+        "  Layer8(,'8');"
+        "  Layer9(,'9');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  TurtleInit(&tt);
+  SetMenu;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_FOCUS_TASK_MENU
+        -WIF_SELF_FOCUS-WIF_SELF_GRAB_SCROLL;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|
+            1<<MSG_MS_R_DOWN|1<<MSG_MS_R_UP|1<<MSG_MS_MOVE)) {
+        case MSG_MS_L_DOWN:
+          tt.first=TRUE;
+          tt.x=arg1;
+          tt.y=arg2;
+          break;
+        case MSG_MS_R_DOWN:
+          aim=TRUE;
+          tt.theta=Arg(arg1-tt.x,arg2-tt.y);
+          break;
+        case MSG_MS_MOVE:
+          if (aim)
+            tt.theta=Arg(arg1-tt.x,arg2-tt.y);
+          break;
+        case MSG_MS_R_UP:
+          tt.theta=Arg(arg1-tt.x,arg2-tt.y);
+          aim=FALSE;
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case 0:
+              switch (arg2.u8[0]) {
+                case SC_CURSOR_LEFT:
+                  if (tt.dtheta_idx)
+                    tt.dtheta_idx--;
+                  break;
+                case SC_CURSOR_RIGHT:
+                  if (tt.dtheta_idx<ANGLES-1)
+                    tt.dtheta_idx++;
+                  break;
+                case SC_CURSOR_UP:
+                  tt.speed+=TURTLE_SPEED_STEP;
+                  break;
+                case SC_CURSOR_DOWN:
+                  if (tt.speed>=TURTLE_SPEED_STEP)
+                    tt.speed-=TURTLE_SPEED_STEP;
+                  break;
+              }
+              break;
+            case '0'...'9':
+              tt.z=arg1-'0';
+              SetMenu;
+              break;
+            case 'c':
+              tt.middle=PopUpColor("Mid Color\n\n");
+              tt.edge  =PopUpColor("Edge Color\n\n");
+              break;
+            case 'e':
+              tt.ends=!tt.ends;
+              break;
+            case '+':
+              tt.w++;
+              break;
+            case '-':
+              if (tt.w)
+                tt.w--;
+              break;
+            case '\n':
+              DCFill(dc);
+              TurtleInit(&tt);
+              SetMenu;
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto lt_done;
+            case CH_SPACE:
+              TurtleMove(dc,&tt,tt.edge,tt.middle);
+              break;
+          }
+      }
+    }
+lt_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCFill(dc);
+  DCDel(dc);
+  MenuPop;
+}
+
+Lattice;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Life.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Life.HC.HTML new file mode 100755 index 0000000..26a185e --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Life.HC.HTML @@ -0,0 +1,129 @@ + + + + + + + + + + + +
+//Conway's Game of Life
+
+CDC *dc[2]; //dbl buf
+I64 cur_dc,;
+Bool restart;
+
+U0 DrawIt(CTask *,CDC *dc2)
+{
+  dc[cur_dc]->flags|=DCF_NO_TRANSPARENTS;
+  GrBlot(dc2,0,0,dc[cur_dc]);
+}
+
+U0 AnimateTask(I64)
+{
+  I64 x,y,x1,y1,cnt,next_dc;
+  while (TRUE) {
+    next_dc=cur_dc^1;
+start_over:
+    restart=FALSE;
+    DCClear(dc[next_dc]);
+    for (y=1;y<Fs->parent_task->pix_height-1;y++) {
+      for (x=1;x<Fs->parent_task->pix_width-1;x++) {
+        cnt=0;
+        for (y1=y-1;y1<=y+1;y1++)
+          for (x1=x-1;x1<=x+1;x1++)
+            if (GrPeek(dc[cur_dc],x1,y1)==GREEN)
+              cnt++;
+        if (restart) goto start_over;
+        if (GrPeek(dc[cur_dc],x,y)==GREEN) {
+          if (cnt==3) {
+            dc[next_dc]->color=GREEN;
+            GrPlot(dc[next_dc],x,y);
+          }
+        } else {
+//        if (cnt==3) {//Use this for the classic rules
+          if (cnt==2) {
+            dc[next_dc]->color=GREEN;
+            GrPlot(dc[next_dc],x,y);
+          }
+        }
+      }
+      Yield;
+    }
+    Sleep(50);
+    cur_dc=next_dc;
+  }
+}
+
+public U0 Life()
+{
+  I64 msg_code,cnt,x1,y1,x2,y2,arg1,arg2;
+
+  dc[0]=DCNew(GR_WIDTH,GR_HEIGHT);
+  dc[1]=DCNew(GR_WIDTH,GR_HEIGHT);
+  cur_dc=0;
+  restart=FALSE;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN);
+    switch (msg_code) {
+      case MSG_MS_L_DOWN:
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        cnt=0;
+        while (msg_code!=MSG_MS_L_UP) {
+          restart=TRUE;
+          dc[cur_dc]->color=GREEN;
+          dc[cur_dc]->thick=0.04*ms.speed;
+          GrLine3(dc[cur_dc],x1,y1,0,x2,y2,0);
+          restart=TRUE;
+          msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          x1=x2; y1=y2;
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc[cur_dc],x1,y1,0,x2,y2,0);
+        break;
+      case MSG_KEY_DOWN:
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || !arg1);
+  GetMsg(,,1<<MSG_KEY_UP);
+  SettingsPop;
+  DCFill;
+  DCDel(dc[0]);
+  DCDel(dc[1]);
+}
+
+Life;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/LightTable.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/LightTable.HC.HTML new file mode 100755 index 0000000..b37bb71 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/LightTable.HC.HTML @@ -0,0 +1,680 @@ + + + + + + + + + + + +
+/*
+There is a coarse and a fine-grained.
+The coarse gets flood-filled but the
+fine grained is only outlines.
+*/
+
+class Photon
+{
+  Photon *next,*last;
+  CD3 p,v,n,p_normal_inhibit;
+} p_root[mp_cnt];
+I64 p_root_locks;
+
+#define ANIMATE_JIFFIES (JIFFY_FREQ*0.01)
+I64 master_sleep_jiffy;
+CTask *animate_tasks[mp_cnt];
+
+#define LENS_COLOR      WHITE
+#define MIRROR_COLOR    DKGRAY
+CDC *map;
+
+I64 photon_cnt,mirror_cnt,snell_cnt,normal_inhibit,zero_normal;
+Bool full_speed,show_normals;
+
+U8      *bmp_refract,*bmp_reflect;
+F64     bmp_scale,find_normal_dist_sqr;
+I64     bmp_mem,bmp_width,bmp_height,bmp_norm_radius;
+
+#define BORDER  10
+I64 BmpPeek(U8 *bmp,I64 x,I64 y)
+{
+  return Bt(bmp,y*bmp_width+x);
+}
+
+U0 BmpPlot(U8 *bmp,I64 x,I64 y,I64)
+{
+  if (0<=x<bmp_width && 0<=y<bmp_height)
+    Bts(bmp,y*bmp_width+x);
+}
+
+U0 BmpLine(U8 *bmp,F64 x1,F64 y1,F64 x2,F64 y2)
+{
+  Line(bmp,x1*bmp_scale,y1*bmp_scale,0,x2*bmp_scale,y2*bmp_scale,0,&BmpPlot);
+}
+
+Photon *PhotonNew()
+{
+  I64 num=photon_cnt++%mp_cnt;
+  Photon *res=CAlloc(sizeof(Photon));
+  while (LBts(&p_root_locks,num))
+    Yield;
+  QueIns(res,p_root[num].last);
+  LBtr(&p_root_locks,num);
+  return res;
+}
+
+#define VECTOR 20
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i;
+  Photon *tmpp;
+  GrBlot(dc,0,0,map);
+  dc->color=WHITE;
+  GrPrint(dc,0,0,"Mem:0x%X %,dMeg Scale:%0.3f (%d,%d)-->(%d,%d)",
+        bmp_mem,bmp_mem/1024/1024,bmp_scale,
+        map->width,map->height,bmp_width,bmp_height);
+  GrPrint(dc,0,FONT_HEIGHT,
+        "PhotonCnt:%d MirrorCnt:%d SnellCnt:%d SnellInhibit:%d ZeroNormal:%d",
+        photon_cnt,mirror_cnt,snell_cnt,normal_inhibit,zero_normal);
+  for (i=0;i<mp_cnt;i++) {
+    while (LBts(&p_root_locks,i))
+      Yield;
+    tmpp=p_root[i].next;
+    while (tmpp!=&p_root[i]) {
+      dc->color=LTRED;
+      GrLine(dc,tmpp->p.x-VECTOR*tmpp->v.x,tmpp->p.y-VECTOR*tmpp->v.y,
+            tmpp->p.x,tmpp->p.y);
+      if (show_normals) {
+        dc->color=LTGREEN;
+        GrLine(dc,tmpp->p.x,tmpp->p.y,
+              tmpp->p.x+VECTOR*tmpp->n.x,tmpp->p.y+VECTOR*tmpp->n.y);
+      }
+      tmpp=tmpp->next;
+    }
+    LBtr(&p_root_locks,i);
+  }
+}
+
+#define WING    9
+
+U0 RayBurst(I64 x1,I64 y1,I64 x2,I64 y2)
+{
+  CD3 p,v,n,n2;
+  I64 i;
+  Photon *tmpp;
+  if ((x1!=x2 || y1!=y2) && BORDER+WING<x2<map->width-BORDER-WING &&
+        BORDER+WING<y2<map->height-BORDER-WING) {
+    D3Equ(&p,x2,y2);
+    D3Equ(&v,x2-x1,y2-y1);
+    D3Unit(&v);
+    D3Equ(&n,v.y,-v.x);
+
+    tmpp=PhotonNew;
+    D3Copy(&tmpp->p,&p);
+    D3Copy(&tmpp->v,&v);
+
+    for (i=2;i<=WING;i+=3) {
+      D3Mul(&n2,i,&n);
+
+      tmpp=PhotonNew;
+      D3Add(&tmpp->p,&p,&n2);
+      D3Copy(&tmpp->v,&v);
+
+      tmpp=PhotonNew;
+      D3Sub(&tmpp->p,&p,&n2);
+      D3Copy(&tmpp->v,&v);
+    }
+  }
+}
+
+U0 RandomBurst()
+{
+  I64 i;
+  F64 theta;
+  Photon *tmpp;
+  for (i=0;i<256;i++) {
+    tmpp=PhotonNew;
+    D3Equ(&tmpp->p,(Fs->pix_width-BORDER*2)*Rand+BORDER,
+                (Fs->pix_height-BORDER*2)*Rand+BORDER);
+    theta=2*pi*Rand;
+    D3Equ(&tmpp->v,Cos(theta),Sin(theta));
+  }
+}
+
+U0 FindNormal(U8 *bmp,Photon *tmpp)
+{
+  CD3 p,p1,p2;
+  F64 step,x,y,theta=Arg(tmpp->v.x,tmpp->v.y),phi;
+  I64 state;
+
+  D3Copy(&tmpp->p_normal_inhibit,&tmpp->p);
+
+  //Coarse grains has black and white filled-in BSplines.
+  //Fine grained has only white outline without being filled-in.
+
+  //Back-up a step and move fwd to get a fined-grained value
+  //for the point of contact.
+  D3SubEqu(&tmpp->p,&tmpp->v);
+  D3Mul(&p,bmp_scale,&tmpp->p);
+  D3Copy(&p1,&p);
+  while (BmpPeek(bmp,p1.x,p1.y)==BLACK &&
+        D3DistSqr(&p,&p1)<find_normal_dist_sqr)
+    D3AddEqu(&p1,&tmpp->v);
+  D3Copy(&p,&p1);
+  D3Div(&tmpp->p,&p,bmp_scale);
+
+  //Draw an arc one direction, finding point of contact.
+  for (step=1.0;step>=0.01;step/=4) {
+    for (phi=0;phi<=pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4-phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4-phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p1;
+      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4+phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4+phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p1;
+    }
+    for (;phi<=3*pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi-pi/4-phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi-pi/4-phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p1;
+    }
+  }
+fn_p1:
+  if (state)
+    D3Equ(&p1,x,y);
+  else
+    D3Copy(&p1,&tmpp->p);
+
+    //Draw an arc other direction, finding point of contact.
+  for (step=1.0;step>=0.01;step/=4) {
+    for (phi=0;phi<=pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4+phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4+phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p2;
+      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4-phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4-phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p2;
+    }
+    for (;phi<=3*pi/4;phi+=step*pi/bmp_norm_radius) {
+      x=p.x+bmp_norm_radius*Cos(theta+pi+pi/4+phi);
+      y=p.y+bmp_norm_radius*Sin(theta+pi+pi/4+phi);
+      if (state=BmpPeek(bmp,x,y))
+        goto fn_p2;
+    }
+  }
+fn_p2:
+  if (state)
+    D3Equ(&p2,x,y);
+  else
+    D3Copy(&p2,&tmpp->p);
+
+  D3Sub(&p,&p1,&p2);
+  if (D3NormSqr(&p)<0.01) {
+    D3Equ(&tmpp->n,Cos(theta),Sin(theta));
+    lock {zero_normal++;}
+  } else {
+    D3Equ(&tmpp->n,p.y,-p.x);
+    if (D3Dot(&tmpp->n,&tmpp->v)<0)
+      D3Equ(&tmpp->n,-p.y,p.x);
+    D3Unit(&tmpp->n);
+  }
+}
+
+U0 Mirror(Photon *tmpp)
+{/*<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+thetaout = pi+thetan -  (thetain-thetan)
+
+*/
+  F64 theta=Arg(tmpp->v.x,tmpp->v.y),thetan;
+  FindNormal(bmp_reflect,tmpp);
+  thetan=Arg(tmpp->n.x,tmpp->n.y);
+
+  D3Equ(&tmpp->v,Cos(2*thetan+pi-theta),Sin(2*thetan+pi-theta));
+  lock {mirror_cnt++;}
+}
+
+U0 SnellsLaw(Photon *tmpp,I64 last,I64 next)
+{
+//n1 and n2 are refraction index.
+//n1 Sin(theta1) == n2 Sin(theta2)
+  F64 theta=Arg(tmpp->v.x,tmpp->v.y),thetan,n1,n2,theta1,theta2;
+  if (last==LENS_COLOR)
+    n1=1.5;
+  else
+    n1=1.0;
+  if (next==LENS_COLOR)
+    n2=1.5;
+  else
+    n2=1.0;
+  FindNormal(bmp_refract,tmpp);
+  thetan=Arg(tmpp->n.x,tmpp->n.y);
+
+  //Dot=m1m2Cos(theta);
+  theta1=ACos(D3Dot(&tmpp->n,&tmpp->v));
+  theta2=ASin(n1*Sin(theta1)/n2);
+  if (Wrap(theta-thetan)>=0)
+    theta=thetan+theta2;
+  else
+    theta=thetan-theta2;
+
+  D3Equ(&tmpp->v,Cos(theta),Sin(theta));
+  lock {snell_cnt++;}
+}
+
+U0 AnimateTask(I64)
+{
+  while (TRUE) {
+    master_sleep_jiffy+=ANIMATE_JIFFIES;
+    if (cnts.jiffies>=master_sleep_jiffy)
+      master_sleep_jiffy=cnts.jiffies+ANIMATE_JIFFIES;
+    SleepUntil(master_sleep_jiffy);
+  }
+}
+
+#define BABY_STEPS      4
+
+U0 MPAnimateTask(I64)
+{
+  I64   i,last_master_jiffy=0,
+        timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES,
+        last,next;
+  Bool  inhibit;
+  CD3   step;
+  Photon *tmpp,*root=&p_root[Gs->num];
+  while (TRUE) {
+    while (LBts(&p_root_locks,Gs->num))
+      Yield;
+    tmpp=root->next;
+    while (tmpp!=root) {
+      for (i=0;i<BABY_STEPS;i++) {
+        last=GrPeek(map,tmpp->p.x,tmpp->p.y);
+        D3Div(&step,&tmpp->v,BABY_STEPS);
+        D3AddEqu(&tmpp->p,&step);
+        if (tmpp->p.x<BORDER) {
+          tmpp->p.x=2*BORDER-tmpp->p.x;
+          tmpp->v.x=-tmpp->v.x;
+        }
+        if (tmpp->p.x>=map->width-BORDER) {
+          tmpp->p.x-=tmpp->p.x-map->width+BORDER;
+          tmpp->v.x=-tmpp->v.x;
+        }
+        if (tmpp->p.y<BORDER) {
+          tmpp->p.y=2*BORDER-tmpp->p.y;
+          tmpp->v.y=-tmpp->v.y;
+        }
+        if (tmpp->p.y>=map->height-BORDER) {
+          tmpp->p.y-=tmpp->p.y-map->height+BORDER;
+          tmpp->v.y=-tmpp->v.y;
+        }
+        next=GrPeek(map,tmpp->p.x,tmpp->p.y);
+
+        if (D3DistSqr(&tmpp->p_normal_inhibit,&tmpp->p)<4.0)
+          inhibit=TRUE;
+        else
+          inhibit=FALSE;
+
+        if (last!=next) {
+          if ((last==BLACK && next==LENS_COLOR) ||
+                (last==LENS_COLOR && next==BLACK)) {
+            if (inhibit)
+              lock {normal_inhibit++;}
+            else
+              SnellsLaw(tmpp,last,next);
+          } else if (last==BLACK && next==MIRROR_COLOR) {
+            if (inhibit)
+              lock {normal_inhibit++;}
+            else
+              Mirror(tmpp);
+          } else if (!inhibit)
+            D3Zero(&tmpp->p_normal_inhibit);
+        } else if (!inhibit)
+          D3Zero(&tmpp->p_normal_inhibit);
+      }
+
+      tmpp=tmpp->next;
+      if (cnts.jiffies>=timeout_jiffy)
+        break;
+    }
+    LBtr(&p_root_locks,Gs->num);
+    if (cnts.jiffies>=timeout_jiffy) {
+      Sleep(1);
+      timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES;
+    }
+    if (!full_speed) {
+      while (master_sleep_jiffy==last_master_jiffy)
+        Sleep(1);
+      last_master_jiffy=master_sleep_jiffy;
+      SleepUntil(master_sleep_jiffy);
+      timeout_jiffy=master_sleep_jiffy+ANIMATE_JIFFIES;
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  master_sleep_jiffy=cnts.jiffies;
+  full_speed=show_normals=FALSE;
+  photon_cnt=mirror_cnt=snell_cnt=normal_inhibit=zero_normal=0;
+  map=DCNew(Fs->pix_width,Fs->pix_height);
+  for (i=0;i<mp_cnt;i++) {
+    while (LBts(&p_root_locks,i))
+      Yield;
+    QueInit(&p_root[i]);
+    LBtr(&p_root_locks,i);
+  }
+//x*y=bmp_mem*8
+  //x/y=640/480
+  //x=640/480*y
+  //640/480*y^2=bmp_mem*8
+  //y=Sqrt(bmp_mem*8*480/640)
+  //bmp_scale=Sqrt(bmp_mem*8*480/640)/480
+  bmp_scale=Sqrt(bmp_mem/2*8*Fs->pix_height/Fs->pix_width)/Fs->pix_height;
+
+  find_normal_dist_sqr=2*Sqr(bmp_scale);
+#assert Sqrt(2)<=BORDER
+
+  bmp_width =bmp_scale*Fs->pix_width;
+  bmp_height=bmp_scale*Fs->pix_height;
+  bmp_refract=CAlloc(bmp_width*bmp_height/8);
+  bmp_reflect=CAlloc(bmp_width*bmp_height/8);
+  bmp_norm_radius=Min(10*bmp_scale,250);
+#assert 10<=BORDER
+}
+
+U0 CleanUp()
+{
+  I64 i;
+  for (i=0;i<mp_cnt;i++) {
+    while (LBts(&p_root_locks,i))
+      Yield;
+    QueDel(&p_root[i],TRUE);
+    LBtr(&p_root_locks,i);
+  }
+  DCDel(map);
+  Free(bmp_refract);
+  Free(bmp_reflect);
+}
+
+#define LTM_REFLECT_LINE        0
+#define LTM_REFLECT_SPLINE      1
+#define LTM_REFRACT_LINE        2
+#define LTM_REFRACT_SPLINE      3
+#define LTM_REFRACT_FLOOD_FILL  4
+#define LTM_TEST_RAY            5
+
+U0 LTMenuSet(I64 mode)
+{
+  CMenuEntry *entry=MenuEntryFind(Fs->cur_menu,"View/ToggleNormals");
+  if (show_normals)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/ReflectLine");
+  if (mode==LTM_REFLECT_LINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/ReflectSpline");
+  if (mode==LTM_REFLECT_SPLINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractLine");
+  if (mode==LTM_REFRACT_LINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractSpline");
+  if (mode==LTM_REFRACT_SPLINE)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/RefractFloodFill");
+  if (mode==LTM_REFRACT_FLOOD_FILL)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+  entry=MenuEntryFind(Fs->cur_menu,"Mode/TestRay");
+  if (mode==LTM_TEST_RAY)
+    entry->checked=TRUE;
+  else
+    entry->checked=FALSE;
+}
+
+#define PTS_NUM 1024
+U0 LightTable()
+{
+  I64 msg_code,mode=LTM_REFLECT_LINE,i,cnt,arg1,arg2,x1,y1,x2,y2;
+  CD3I32 *c=MAlloc(PTS_NUM*sizeof(CD3I32));
+
+  p_root_locks=0;
+  MenuPush(
+        "File {"
+        "  Restart(,'\n');"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Mode {"
+        "  ReflectLine(,'0');"
+        "  ReflectSpline(,'1');"
+        "  RefractLine(,'2');"
+        "  RefractSpline(,'3');"
+        "  RefractFloodFill(,'4');"
+        "  TestRay(,'5');"
+        "}"
+        "Play {"
+        "  RandomBurst(,'r');"
+        "  ElapseTime(,'e');"
+        "}"
+        "View {"
+        "  ToggleNormals(,'n');"
+        "}"
+        );
+  LTMenuSet(mode);
+
+  MemBIOSRep;
+  bmp_mem=GetI64("\n\n\nHow much memory for the high resolution\n"
+        "shadow bitmap that helps improve the\n"
+        "accuracy of the normal vector estimate?\n"
+        "You can choose up to the largest\n"
+        "contiguous chunk of physical memory.\n\n"
+        "Mem (0x%0X):",1024*1024*16);
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-
+        WIF_SELF_BORDER-WIF_FOCUS_TASK_MENU;
+  Fs->text_attr=BLACK<<4+WHITE; //Current CTask is Fs segment register.
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+  Init;
+  Fs->draw_it=&DrawIt;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  for (i=0;i<mp_cnt;i++)
+    animate_tasks[i]=Spawn(&MPAnimateTask,NULL,"MPAnimate",i);
+  try {
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_R_UP);
+lt_restart:
+      switch (msg_code) {
+        case MSG_MS_L_UP:
+          Sweep(100,90,100);
+          x2=arg1; y2=arg2;
+          switch (mode) {
+            case LTM_REFRACT_FLOOD_FILL:
+              map->color=LENS_COLOR;
+              GrFloodFill(map,x2,y2);
+              mode=LTM_REFLECT_LINE;
+              LTMenuSet(mode);
+              break;
+            case LTM_TEST_RAY:
+              RayBurst(x1,y1,x2,y2);
+              break;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          x1=arg1; y1=arg2;
+          switch (mode) {
+            case LTM_REFLECT_LINE:
+            case LTM_REFRACT_LINE:
+              if (mode==LTM_REFLECT_LINE)
+                map->color=ROP_XOR+MIRROR_COLOR;
+              else
+                map->color=ROP_XOR+LENS_COLOR;
+              while (TRUE) {
+                x2=arg1; y2=arg2;
+                GrLine(map,x1,y1,x2,y2);
+                msg_code=GetMsg(&arg1,&arg2,
+                      1<<MSG_KEY_DOWN+1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+                GrLine(map,x1,y1,x2,y2);
+                if (msg_code==MSG_KEY_DOWN)
+                  goto lt_restart;
+                else if (msg_code==MSG_MS_L_UP) {
+                  Sweep(100,90,100);
+                  x2=arg1; y2=arg2;
+                  break;
+                }
+              }
+              if (mode==LTM_REFLECT_LINE)
+                map->color=MIRROR_COLOR;
+              else
+                map->color=LENS_COLOR;
+              GrLine(map,x1,y1,x2,y2);
+              if (mode==LTM_REFLECT_LINE)
+                BmpLine(bmp_reflect,x1,y1,x2,y2);
+              else
+                BmpLine(bmp_refract,x1,y1,x2,y2);
+              break;
+            case LTM_REFLECT_SPLINE:
+            case LTM_REFRACT_SPLINE:
+              cnt=0;
+              if (mode==LTM_REFLECT_SPLINE)
+                map->color=ROP_XOR+MIRROR_COLOR;
+              else
+                map->color=ROP_XOR+LENS_COLOR;
+              do {
+                c[cnt].x=arg1; c[cnt].y=arg2; c[cnt].z=0;
+                Gr2BSpline(map,c,cnt+1);
+                msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_UP+
+                      1<<MSG_MS_MOVE+1<<MSG_MS_R_UP);
+                Gr2BSpline(map,c,cnt+1);
+                if (msg_code==MSG_KEY_DOWN)
+                  goto lt_restart;
+                else if (msg_code==MSG_MS_L_UP) {
+                  Sweep(100,90,100);
+                  cnt++;
+                }
+              } while (cnt<PTS_NUM-1 && msg_code!=MSG_MS_R_UP);
+              if (mode==LTM_REFLECT_SPLINE)
+                map->color=MIRROR_COLOR;
+              else
+                map->color=LENS_COLOR;
+              Gr2BSpline3(map,c,cnt);
+              for (i=0;i<cnt;i++) {
+                c[i].x*=bmp_scale;
+                c[i].y*=bmp_scale;
+              }
+              if (mode==LTM_REFLECT_SPLINE)
+                BSpline2(bmp_reflect,c,cnt,&BmpPlot);
+              else
+                BSpline2(bmp_refract,c,cnt,&BmpPlot);
+              mode=LTM_REFLECT_LINE;
+              LTMenuSet(mode);
+              break;
+          }
+          break;
+        case MSG_MS_R_UP:
+          i=PopUpPickLst("Reflect Line\0Reflect Spline\0Refract Line\0"
+                "Refract Spline\0Refract Flood Fill\0TestRay\0");
+          if (i>=0) {
+            mode=i;
+            LTMenuSet(mode);
+          }
+          break;
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp;
+              Init;
+              mode=LTM_REFLECT_LINE;
+              LTMenuSet(mode);
+              break;
+            case 'r':
+              RandomBurst;
+              break;
+            case 'e':
+              full_speed=TRUE;
+              Sleep(1500);
+              FlushMsgs;
+              full_speed=FALSE;
+              break;
+            case 'n':
+              show_normals=!show_normals;
+              LTMenuSet(mode);
+              break;
+            case '0'...'5':
+              mode=arg1-'0';
+              LTMenuSet(mode);
+              break;
+            case CH_ESC:
+            case CH_SHIFT_ESC:
+              goto lt_done;
+          }
+          break;
+      }
+    }
+lt_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  Free(c);
+  SettingsPop;
+  for (i=0;i<mp_cnt;i++)
+    Kill(animate_tasks[i]);
+  CleanUp;
+  MenuPop;
+}
+
+LightTable;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Lines.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Lines.HC.HTML new file mode 100755 index 0000000..8445bf1 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Lines.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+U0 Main()
+{
+  I64 x1=0,y1=0,x2=0,y2=0,i=1,c=0;
+  I64 vx1=0,vy1=0,vx2=0,vy2=0;
+  CDC *dc=DCAlias;
+  while (!ScanChar) {
+    if (!--i) {
+      i=1000;
+      dc->color=c++&15;
+    }
+    GrLine(dc,x1,y1,x2,y2);
+    vx1=ClampI64(vx1+SignI64(RandI16),-5,5);
+    vy1=ClampI64(vy1+SignI64(RandI16),-5,5);
+    vx2=ClampI64(vx2+SignI64(RandI16),-5,5);
+    vy2=ClampI64(vy2+SignI64(RandI16),-5,5);
+    x1=ClampI64(x1+vx1,0,Fs->pix_width-1);
+    y1=ClampI64(y1+vy1,0,Fs->pix_height-1);
+    x2=ClampI64(x2+vx2,0,Fs->pix_width-1);
+    y2=ClampI64(y2+vy2,0,Fs->pix_height-1);
+    Sleep(1); //Replace this with Yield() ort Sleep(0) and see what happens!
+  }
+  DCFill(dc);
+  DCDel(dc);
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/LowPassFilter.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/LowPassFilter.HC.HTML new file mode 100755 index 0000000..6007d57 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/LowPassFilter.HC.HTML @@ -0,0 +1,114 @@ + + + + + + + + + + + +
+#define STEP_SIZE       400
+
+U0 LowPassFilterDemo()
+{
+  F64 y,y1,t,dt;
+  CDC *dc=DCAlias;
+
+  WinBorder;
+  WinMax;
+  DocClear;
+
+  dc->color=BLUE;
+  GrLine(dc,0,0,0,STEP_SIZE);
+  GrLine(dc,0,STEP_SIZE,GR_WIDTH/2,STEP_SIZE);
+  GrLine(dc,GR_WIDTH/2,STEP_SIZE,GR_WIDTH/2,0);
+  GrLine(dc,GR_WIDTH/2,0,GR_WIDTH,0);
+  PressAKey;
+
+  dc->color=CYAN;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=1.0;
+    if (t<GR_WIDTH/2)
+      y1=STEP_SIZE-STEP_SIZE*Exp(-0.01*t);
+    else
+      y1=STEP_SIZE*Exp(-0.01*(t-GR_WIDTH/2));
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  dc->color=BLACK;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=1.0;
+    if (t<GR_WIDTH/2)
+      y1=0.99*y+.01*STEP_SIZE;
+    else
+      y1=0.99*y;
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  dc->color=RED;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=Rand/10;
+    if (t<GR_WIDTH/2)
+      y1=LowPass1(.01,y,STEP_SIZE,dt);
+    else
+      y1=LowPass1(.01,y,0,dt);
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  dc->color=GREEN;
+  t=0;
+  y=0.0;
+  while (t<GR_WIDTH) {
+    dt=Rand/10;
+    if (t<GR_WIDTH/2)
+      y1=LowPass1(.1,y,STEP_SIZE,dt);
+    else
+      y1=LowPass1(.1,y,0,dt);
+    GrLine(dc,t,y,t+dt,y1);
+    y=y1;
+    t+=dt;
+  }
+  PressAKey;
+
+  DCDel(dc);
+  DCFill;
+}
+
+LowPassFilterDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/MathAudioDemo.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/MathAudioDemo.HC.HTML new file mode 100755 index 0000000..e56336e --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/MathAudioDemo.HC.HTML @@ -0,0 +1,137 @@ + + + + + + + + + + + +
+F64 MySin(F64 d)
+{ //Sin() does not have an address.
+  return Sin(d);
+}
+
+F64 MyCos(F64 d)
+{ //Cos() does not have an address.
+  return Cos(d);
+}
+
+U0 FunDraw1(CDC *dc,F64 (*f)(F64 t))
+{
+  I64 i,w=Fs->pix_width,h=Fs->pix_height;
+  F64 scale=h/5.0;
+  for (i=-w/2;i<=w/2;i++)
+    GrLine(dc,w/2+i,h/2-scale*f(i/scale*2*pi),
+          w/2+i+1,h/2-scale*f((i+1)/scale*2*pi));
+}
+
+U0 FunDraw2(CDC *dc,F64 (*f)(F64 t,F64 p),F64 T)
+{
+  I64 i,w=Fs->pix_width,h=Fs->pix_height;
+  F64 scale=h/5.0;
+  for (i=-w/2;i<=w/2;i++)
+    GrLine(dc,w/2+i,h/2-scale*f(i/scale,T),w/2+i+1,h/2-scale*f((i+1)/scale,T));
+}
+
+U0 Init(CDC *dc)
+{
+  I64 i,w=Fs->pix_width,h=Fs->pix_height;
+  F64 scale=h/5.0;
+  DocClear;
+  DCFill(dc);
+  dc->color=BLACK;
+  GrLine(dc,0,h/2,w-1,h/2);
+  GrLine(dc,w/2,0,w/2,h-1);
+  for (i=-2;i<=2;i++) {
+    dc->color=BLACK;
+    GrLine(dc,w/2-3,h/2-scale*i,w/2+3,h/2-scale*i);
+    if (i) {
+      dc->color=DKGRAY;
+      GrPrint(dc,w/2+5,h/2-scale*i-FONT_HEIGHT/2,"%5.1f",ToF64(i));
+    }
+  }
+  for (i=-4;i<=4;i++) {
+    dc->color=BLACK;
+    GrLine(dc,w/2+scale*i,h/2-3,w/2+scale*i,h/2+3);
+    if (i) {
+      dc->color=DKGRAY;
+      GrPrint(dc,
+            w/2+scale*i-7*FONT_WIDTH/2,h/2+5+FONT_HEIGHT,"%5.1f*T",ToF64(i));
+    }
+  }
+}
+
+U0 SndMathDemo()
+{
+  CDC *dc=DCAlias;
+
+  Init(dc);
+  dc->color=RED;
+  FunDraw1(dc,&MySin);
+  "$RED$Sin$FG$\n";
+  PressAKey;
+  dc->color=BLUE;
+  FunDraw2(dc,&Saw,1.0);
+  "$BLUE$Saw$FG$\n";
+  PressAKey;
+  dc->color=GREEN;
+  FunDraw2(dc,&FullSaw,1.0);
+  "$GREEN$FullSaw$FG$\n";
+  PressAKey;
+
+  Init(dc);
+  dc->color=RED;
+  FunDraw1(dc,&MyCos);
+  "$RED$Cos$FG$\n";
+  PressAKey;
+  dc->color=BLUE;
+  FunDraw2(dc,&Caw,1.0);
+  "$BLUE$Caw$FG$\n";
+  PressAKey;
+  dc->color=GREEN;
+  FunDraw2(dc,&FullCaw,1.0);
+  "$GREEN$FullCaw$FG$\n";
+  PressAKey;
+
+  Init(dc);
+  dc->color=RED;
+  FunDraw1(dc,&MySin);
+  "$RED$Sin$FG$\n";
+  PressAKey;
+  dc->color=BLUE;
+  FunDraw2(dc,&Tri,1.0);
+  "$BLUE$Tri$FG$\n";
+  PressAKey;
+  dc->color=GREEN;
+  FunDraw2(dc,&FullTri,1.0);
+  "$GREEN$FullTri$FG$\n";
+  PressAKey;
+
+  DCFill(dc);
+  DCDel(dc);
+}
+
+SndMathDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/MouseDemo.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/MouseDemo.HC.HTML new file mode 100755 index 0000000..f40578f --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/MouseDemo.HC.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+U0 Mouse()
+{
+  "Press left mouse bttn to exit.\n";
+  while (!ms.lb) { //Left bttn to exit.
+    GrPlot(,ms.pos.x,ms.pos.y);
+    Refresh;
+  }
+  DCFill;
+}
+
+Mouse;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/NetOfDots.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/NetOfDots.HC.HTML new file mode 100755 index 0000000..a801c60 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/NetOfDots.HC.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+//Press <F5> to compile and run.
+
+U0 NetOfDots()
+{
+  I64 i;
+  CDC *dc=DCAlias;
+  DocClear;
+  dc->color=RED;
+  for (i=0;i<480;i+=20)
+    GrLine(dc,i,0,0,480-i,3);
+  DCDel(dc);
+  PressAKey;
+  DCFill;
+}
+
+NetOfDots;  //Run when #included
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Palette.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Palette.HC.HTML new file mode 100755 index 0000000..f40ac12 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Palette.HC.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+U0 PaletteDemo()
+{
+  I64 i,j;
+  CBGR48 bgr;
+  for (i=0;i<COLORS_NUM;i++)
+    "$BLACK$$BG,%d$__%-8Z__$FG$$BG$\n",i,i,"ST_COLORS";
+
+  SettingsPush; //See SettingsPush
+//Alternatively, use GrPaletteSet(gr_palette_gray);
+  for (i=0;i<COLORS_NUM;i++) {
+    j=0xFFFF*i/(COLORS_NUM-1);
+    bgr.b=j;
+    bgr.g=j;
+    bgr.r=j;
+    GrPaletteColorSet(i,bgr);
+  }
+  PressAKey;
+
+  //You can do it this way, too.
+  GrPaletteColorSet(WHITE,0xFFFFFFFF0000);
+  PressAKey;
+
+  //SettingsPop() restores original palette
+  SettingsPop;
+}
+
+PaletteDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/PanText.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/PanText.HC.HTML new file mode 100755 index 0000000..a7227ca --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/PanText.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+U0 PanText()
+{
+  I64 i;
+  for (i=0;i<=7;i++) {
+    gr.pan_text_x=i;
+    Sleep(30);
+  }
+  i--;
+  for (;i>=-7;i--) {
+    gr.pan_text_x=i;
+    Sleep(30);
+  }
+  i++;
+  for (;i<=0;i++) {
+    gr.pan_text_x=i;
+    Sleep(30);
+  }
+
+  for (i=0;i<=7;i++) {
+    gr.pan_text_y=i;
+    Sleep(30);
+  }
+  i--;
+  for (;i>=-7;i--) {
+    gr.pan_text_y=i;
+    Sleep(30);
+  }
+  i++;
+  for (;i<=0;i++) {
+    gr.pan_text_y=i;
+    Sleep(30);
+  }
+}
+
+PanText;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Pick.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Pick.HC.HTML new file mode 100755 index 0000000..37a9fa5 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Pick.HC.HTML @@ -0,0 +1,117 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+#define APPLES_NUM 128
+
+I64     x[APPLES_NUM],y[APPLES_NUM],
+        cur_apple,cur_dist;
+Bool    trigger;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i,best_dist=I64_MAX,best_apple=0;
+
+  dc->flags|=DCF_LOCATE_NEAREST;
+  dc->cur_x=ms.pos.x;
+  dc->cur_y=ms.pos.y;
+  dc->cur_z=0;
+  for (i=0;i<APPLES_NUM;i++) {
+    Sprite3(dc,x[i],y[i],0,<1>);
+    if (dc->nearest_dist<=best_dist) {
+//Distance to nearest pix, squared
+      //Sqrt() is expensive so we work with distance squared.
+      best_dist=dc->nearest_dist;
+      best_apple=i;
+    }
+  }
+  if (trigger) {
+    cur_apple=best_apple;
+    cur_dist=best_dist;
+    trigger=FALSE;
+  }
+  GrPrint(dc,FONT_WIDTH,FONT_HEIGHT,"Dist Squared:%d",cur_dist);
+}
+
+U0 Pick()
+{
+  I64 i,msg_code,arg1,arg2,delta_x,delta_y;
+  for (i=0;i<APPLES_NUM;i++) {
+    x[i]=RandU16%GR_WIDTH;
+    y[i]=RandU16%(GR_HEIGHT-FONT_HEIGHT*3)+FONT_HEIGHT*3;
+  }
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  DocCursor;
+  DocClear;
+
+  trigger=FALSE;
+  cur_apple=cur_dist=0;
+
+  Fs->draw_it=&DrawIt;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  try {
+    while (TRUE) {
+      if (GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN)==MSG_KEY_DOWN)
+        goto pi_done;
+
+        //Wait for window mgr to call DrawIt()
+      trigger=TRUE;
+      do Refresh;
+      while (trigger);
+
+      //Use scrn coordinates, not window (arg1,arg2)
+      //ms.pos.x and ms.pos.y are global vars updated
+      //updated by the window mgr to hold the
+      //scrn coordinates of the mouse.
+      delta_x=x[cur_apple]-ms.pos.x;
+      delta_y=y[cur_apple]-ms.pos.y;
+
+      do {
+        msg_code=GetMsg(&arg1,&arg2,
+              1<<MSG_KEY_DOWN|1<<MSG_MS_MOVE|1<<MSG_MS_L_UP);
+        if (msg_code==MSG_KEY_DOWN)
+          goto pi_done;
+        x[cur_apple]=ms.pos.x+delta_x;
+        y[cur_apple]=ms.pos.y+delta_y;
+      } while (msg_code!=MSG_MS_L_UP);
+    }
+pi_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+}
+
+Pick;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Pick3D.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Pick3D.HC.HTML new file mode 100755 index 0000000..16b84ac --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Pick3D.HC.HTML @@ -0,0 +1,357 @@ + + + + + + + + + + + +
+//This is a whimsical program which demonstrates some techniques.
+
+#define BORDER          20
+
+#define PTY_PT  0
+#define PTY_CIRCLE      1
+#define PTY_LINE        2
+#define PTY_SPRITE      3
+#define PTY_NUM         4
+
+extern class PObj;
+
+class PPt
+{
+  CD3I32 p;
+};
+
+class PCircle
+{
+  PObj  *p;
+  I64   radius;
+};
+
+class PLine
+{
+  PObj  *p1,*p2;
+};
+
+class PCSprite
+{
+  PObj  *p;
+  U8    *img;
+  I64   *r,
+        *dr; //Rounding error might eventually screw this up
+}
+
+class PObj
+{
+  PObj  *next,*last;
+  I64   type,color;
+  union {
+    PPt         p;
+    PCircle     c;
+    PLine       l;
+    PCSprite    g;
+  };
+};
+
+class PickFrame
+{
+  PObj  o_head;
+  I64   o_cnts[PTY_NUM];
+  I64   cx,cy;
+};
+
+#define IMGS_NUM        3
+
+
+
+  <1>/* Graphics Not Rendered in HTML */
+
+
+
+  <2>/* Graphics Not Rendered in HTML */
+
+
+
+
+  <3>/* Graphics Not Rendered in HTML */
+
+
+U8 *imgs[IMGS_NUM]={<1>,<2>,<3>};
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 *r,*old_r;
+  PickFrame *pf=FramePtr("PickFrame",task);
+  PObj *tmpo=pf->o_head.next;
+
+  pf->cx=task->pix_width>>1;
+  pf->cy=task->pix_height>>1;
+
+  DCDepthBufAlloc(dc);
+
+  dc->color=LTRED;
+  dc->thick=3;
+  GrBorder(dc,BORDER,BORDER,2*pf->cx-BORDER,2*pf->cy-BORDER);
+
+  while (tmpo!=&pf->o_head) {
+    dc->color=tmpo->color;
+    switch (tmpo->type) {
+      case PTY_PT:
+        GrLine(dc,pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y+2,
+              pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y-2);
+        GrLine(dc,pf->cx+tmpo->p.p.x-2,pf->cy+tmpo->p.p.y+2,
+              pf->cx+tmpo->p.p.x+2,pf->cy+tmpo->p.p.y-2);
+        break;
+      case PTY_CIRCLE:
+        GrCircle(dc,pf->cx+tmpo->c.p->p.p.x,pf->cy+tmpo->c.p->p.p.y,
+              tmpo->c.radius);
+        break;
+      case PTY_LINE:
+        GrLine(dc,pf->cx+tmpo->l.p1->p.p.x,pf->cy+tmpo->l.p1->p.p.y,
+              pf->cx+tmpo->l.p2->p.p.x,pf->cy+tmpo->l.p2->p.p.y);
+        break;
+      case PTY_SPRITE:
+        old_r=dc->r;
+        dc->r=tmpo->g.r;
+        dc->x=pf->cx+tmpo->g.p->p.p.x;
+        dc->y=pf->cy+tmpo->g.p->p.p.y;
+        dc->z=GR_Z_ALL;
+        dc->flags|=DCF_TRANSFORMATION;
+        Sprite3(dc,0,0,0,tmpo->g.img);
+        dc->flags&=~DCF_TRANSFORMATION;
+        dc->r=old_r;
+
+        //Updated each refresh, not guarenteed to be uniform.
+        //Rounding error might corrupt, as well.
+        r=Mat4x4MulMat4x4New(tmpo->g.dr,tmpo->g.r,task);
+        Free(tmpo->g.r);
+        tmpo->g.r=r;
+
+        break;
+    }
+    tmpo=tmpo->next;
+  }
+}
+
+PObj *PObjNew(PickFrame *pf,I64 type,I64 color)
+{
+  PObj *tmpo=CAlloc(sizeof(PObj));
+  tmpo->type=type;
+  tmpo->color=color;
+  pf->o_cnts[type]++;
+  QueIns(tmpo,pf->o_head.last);
+  return tmpo;
+}
+
+U0 PObjDel(PickFrame *pf,PObj *tmpo)
+{
+  QueRem(tmpo);
+  switch (tmpo->type) {
+    case PTY_SPRITE:
+      Free(tmpo->g.r);
+      Free(tmpo->g.dr);
+      break;
+  }
+  pf->o_cnts[tmpo->type]--;
+  Free(tmpo);
+}
+
+PObj *PPtNew(PickFrame *pf,I64 x,I64 y)
+{
+  PObj *tmpo=PObjNew(pf,PTY_PT,BLACK);
+  tmpo->p.p.x=x;
+  tmpo->p.p.y=y;
+  return tmpo;
+}
+
+PObj *PPtNum(PickFrame *pf,I64 num)
+{
+  PObj *tmpo=pf->o_head.next;
+  while (tmpo!=&pf->o_head) {
+    if (tmpo->type==PTY_PT && !num--)
+      return tmpo;
+    tmpo=tmpo->next;
+  }
+  return NULL;
+}
+
+PObj *PPtFind(PickFrame *pf,I64 x,I64 y)
+{
+  I64 dd,best_dd=I64_MAX;
+  PObj *tmpo=pf->o_head.next,*res=NULL;
+  while (tmpo!=&pf->o_head) {
+    if (tmpo->type==PTY_PT) {
+      dd=SqrI64(tmpo->p.p.x-x)+SqrI64(tmpo->p.p.y-y);
+      if (dd<best_dd) {
+        best_dd=dd;
+        res=tmpo;
+      }
+    }
+    tmpo=tmpo->next;
+  }
+  return res;
+}
+
+PObj *PCircleNew(PickFrame *pf,I64 p_num,I64 r)
+{
+  PObj *tmpo=PObjNew(pf,PTY_CIRCLE,RED);
+  tmpo->c.p=PPtNum(pf,p_num);
+  tmpo->c.radius=r;
+  return tmpo;
+}
+
+PObj *PLineNew(PickFrame *pf,I64 p1_num,I64 p2_num)
+{
+  PObj *tmpo=PObjNew(pf,PTY_LINE,GREEN);
+  tmpo->l.p1=PPtNum(pf,p1_num);
+  tmpo->l.p2=PPtNum(pf,p2_num);
+  return tmpo;
+}
+
+PObj *PCSpriteNew(PickFrame *pf,U8 *img,I64 p_num,I64 *r,I64 *dr)
+{
+  PObj *tmpo=PObjNew(pf,PTY_SPRITE,BLACK);
+  tmpo->g.p=PPtNum(pf,p_num);
+  tmpo->g.img=img;
+  tmpo->g.r=r;
+  tmpo->g.dr=dr;
+  return tmpo;
+}
+
+PickFrame *Init()
+{
+  PickFrame *pf=CAlloc(sizeof(PickFrame));
+  I64 i,*r,*dr;
+
+  pf->cx=Fs->pix_width>>1;
+  pf->cy=Fs->pix_height>>1;
+
+  pf->o_head.next=pf->o_head.last=&pf->o_head;
+  for (i=0;i<50;i++)
+    PPtNew(pf,RandI32%(pf->cx-BORDER),RandI32%(pf->cy-BORDER));
+  for (i=0;i<20;i++)
+    PCircleNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,6);
+  for (i=0;i<20;i++)
+    PLineNew(pf,pf->o_cnts[PTY_PT]*RandU16/U16_MAX,
+          pf->o_cnts[PTY_PT]*RandU16/U16_MAX);
+  for (i=0;i<10;i++) {
+    r=Mat4x4IdentNew;
+    dr=Mat4x4IdentNew;
+    Mat4x4RotZ(dr,0.05*2*(Rand-0.5));
+    Mat4x4RotY(dr,0.05*2*(Rand-0.5));
+    Mat4x4RotX(dr,0.05*2*(Rand-0.5));
+    PCSpriteNew(pf,imgs[IMGS_NUM*RandU16/U16_MAX],
+          pf->o_cnts[PTY_PT]*RandU16/U16_MAX,r,dr);
+  }
+  FramePtrSet("PickFrame",pf);
+  return pf;
+}
+
+U0 CleanUp(PickFrame *pf)
+{
+  PObj *tmpo=pf->o_head.next,*tmpo1;
+  while (tmpo!=&pf->o_head) {
+    tmpo1=tmpo->next;
+    PObjDel(pf,tmpo);
+    tmpo=tmpo1;
+  }
+  Free(pf);
+}
+
+U0 Pick3D()
+{
+  I64 msg_code,arg1,arg2;
+  PObj *tmpo;
+  PickFrame *pf=NULL;
+
+  FramePtrAdd("PickFrame");
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "}"
+        );
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  "$BK,1$Move things around.$BK,0$\n";
+  pf=Init;
+  tmpo=NULL;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS
+        -WIF_SELF_CTRLS-WIF_FOCUS_TASK_MENU;
+  Fs->draw_it=&DrawIt;
+  try {
+    while (TRUE) {
+      switch (msg_code=GetMsg(&arg1,&arg2,
+            1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_MOVE)) {
+        case MSG_KEY_DOWN:
+          switch (arg1) {
+            case '\n':
+              CleanUp(pf);
+              pf=Init;
+              tmpo=NULL;
+              break;
+            case CH_SHIFT_ESC:
+            case CH_ESC:
+              goto pd_done;
+          }
+          break;
+        case MSG_MS_L_DOWN:
+          tmpo=PPtFind(pf,arg1-pf->cx,arg2-pf->cy);
+          break;
+        case MSG_MS_L_UP:
+          if (tmpo) {
+            tmpo->p.p.x=arg1-pf->cx;
+            tmpo->p.p.y=arg2-pf->cy;
+            tmpo=NULL;
+          }
+          break;
+        case MSG_MS_MOVE:
+          if (tmpo) {
+            tmpo->p.p.x=arg1-pf->cx;
+            tmpo->p.p.y=arg2-pf->cy;
+          }
+          break;
+      }
+    }
+pd_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  MenuPop;
+  CleanUp(pf);
+  FramePtrDel("PickFrame");
+}
+
+Pick3D;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/PoleZeros.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/PoleZeros.HC.HTML new file mode 100755 index 0000000..fae7a51 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/PoleZeros.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+#define ZEROS_NUM       2
+Complex zeros[ZEROS_NUM]={{10.0,0},{-30,0}};
+#define POLES_NUM       2
+Complex poles[POLES_NUM]={{-20.0,-15.0},{-20.0,15.0}};
+
+F64 scale;
+
+Complex *PoleZeroFind(I64 x,I64 y)
+{
+  I64 i;
+  F64 dd,best_dd=F64_MAX;
+  Complex *res=NULL;
+  for (i=0;i<POLES_NUM;i++) {
+    dd=Sqr(poles[i].x-x)+Sqr(poles[i].y-y);
+    if (dd<best_dd) {
+      best_dd=dd;
+      res=&poles[i];
+    }
+  }
+  for (i=0;i<ZEROS_NUM;i++) {
+    dd=Sqr(zeros[i].x-x)+Sqr(zeros[i].y-y);
+    if (dd<best_dd) {
+      best_dd=dd;
+      res=&zeros[i];
+    }
+  }
+  return res;
+}
+
+F64 F(Complex *x)
+{
+  F64 m,a;
+  Complex num,denom,n1;
+
+  CPoly(&num,  ZEROS_NUM,zeros,x);
+  CPoly(&denom,POLES_NUM,poles,x);
+  CDiv(&n1,&num,&denom);
+
+  R2P(&m,&a,n1.x,n1.y);
+  if (ms.rb)
+    return pi+a;
+  else
+    return m;
+}
+
+F64 MPDraw(CTask *task)
+{
+  Complex xx;
+  I64 x,y,w=task->pix_width,h=task->pix_height,cx=w/2,cy=h/2,
+        lo=Gs->num*h/mp_cnt,hi=(Gs->num+1)*h/mp_cnt;
+  F64 yy,y_total=0;
+  CDC *dc=DCAlias(,task);
+  for (y=lo;y<hi;y++) {
+    for (x=0;x<w;x++) {
+      CEqu(&xx,x-cx,cy-y);
+      yy=scale*F(&xx);
+      dc->color=Clamp(yy,0,14);
+      y_total+=Clamp(yy,-14,14);
+      GrPlot(dc,x,y);
+    }
+  }
+  DCDel(dc);
+  return y_total;
+}
+
+U0 Draw()
+{
+  CJob *tmpm[MP_PROCESSORS_NUM];
+  F64 y_total,old_y_total=F64_MAX;
+  I64 i,w=Fs->pix_width,h=Fs->pix_height,cx=w/2,cy=h/2;
+  CDC *dc=DCAlias;
+  while (TRUE) {
+    for (i=0;i<mp_cnt;i++)
+      tmpm[i]=JobQue(&MPDraw,Fs,i,0);
+    y_total=0;
+    for (i=0;i<mp_cnt;i++)
+      y_total+=JobResGet(tmpm[i])(F64);
+
+    if (!y_total) break;
+    scale*=7*GR_WIDTH*GR_HEIGHT/y_total;
+    if (Abs(y_total-old_y_total)<1.0*GR_WIDTH*GR_HEIGHT)
+      break;
+    old_y_total=y_total;
+  }
+  dc->color=15;
+  GrLine(dc,0,cy,w,cy);
+  GrLine(dc,cx,0,cx,h);
+  for (i=0;i<ZEROS_NUM;i++)
+    GrPrint(dc,cx+zeros[i].x-FONT_WIDTH/2,cy-zeros[i].y-FONT_HEIGHT/2,"o");
+  for (i=0;i<POLES_NUM;i++)
+    GrPrint(dc,cx+poles[i].x-FONT_WIDTH/2,cy-poles[i].y-FONT_HEIGHT/2,"x");
+  DCDel(dc);
+}
+
+U0 PoleZeros()
+{
+  I64 msg_code,arg1,arg2,p11,p22,cx,cy;
+  Complex *tmpc=NULL;
+
+  PopUpOk(
+        "Drag the poles and zeros with left mouse.\n"
+        "Hold right mouse for phase plot.\n"
+        );
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+  GrPaletteSet(gr_palette_gray);
+  GrPaletteColorSet(15,0xFFFF00000000); //White is red
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  scale=1.0;
+
+  try {
+    Draw;
+    while (TRUE) {
+      msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+
+            1<<MSG_MS_L_UP+1<<MSG_MS_R_DOWN+1<<MSG_MS_R_UP+1<<MSG_MS_MOVE);
+pz_msg:
+      cx=Fs->pix_width/2;
+      cy=Fs->pix_height/2;
+      switch (msg_code) {
+        case MSG_MS_L_DOWN:
+          tmpc=PoleZeroFind(arg1-cx,cy-arg2);
+          break;
+        case MSG_MS_MOVE:
+          if (tmpc) {
+            p11=arg1;p22=arg2;
+//get to last mouse move
+            while (msg_code=ScanMsg(&arg1,&arg2,
+                  1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+
+                  1<<MSG_MS_L_UP+1<<MSG_MS_R_DOWN+
+                  1<<MSG_MS_R_UP+1<<MSG_MS_MOVE))
+              if (msg_code==MSG_MS_MOVE) {
+                p11=arg1;p22=arg2;
+              } else
+                goto pz_msg;
+
+            tmpc->x=p11-cx;
+            tmpc->y=cy-p22;
+            Draw;
+          }
+          break;
+        case MSG_MS_L_UP:
+          if (tmpc) {
+            tmpc->x=arg1-cx;
+            tmpc->y=cy-arg2;
+            tmpc=NULL;
+            Draw;
+          }
+          break;
+        case MSG_MS_R_DOWN:
+        case MSG_MS_R_UP:
+          Draw;
+          break;
+        case MSG_KEY_DOWN:
+          if (arg1==CH_SHIFT_ESC||arg1==CH_ESC)
+            goto pz_done;
+      }
+      Refresh;
+    }
+pz_done:
+    GetMsg(,,1<<MSG_KEY_UP);
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCFill;
+}
+
+PoleZeros;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/PredatorPrey.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/PredatorPrey.HC.HTML new file mode 100755 index 0000000..917c9e7 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/PredatorPrey.HC.HTML @@ -0,0 +1,112 @@ + + + + + + + + + + + +
+//Classic 2nd order nonlinear ordinary differential equation
+
+I64 mp_not_done_flags;
+
+#define OX      10
+#define OY      GR_HEIGHT/2-FONT_HEIGHT
+
+#define MICRO_STEP      0.000001
+
+class State
+{
+  F64 wabbits,hawks,
+        d_wabbits,d_hawks; //Technically, these are not part of the state.
+};
+
+U0 Steps(State *s)
+{
+  I64 i;
+  for (i=0;i<10000;i++) {
+    s->d_wabbits=s->wabbits*(1.0-0.10*s->hawks);
+    s->d_hawks  =-s->hawks *(1.0-0.01*s->wabbits);
+    s->hawks  +=s->d_hawks  *MICRO_STEP;
+    s->wabbits+=s->d_wabbits*MICRO_STEP;
+  }
+}
+
+U0 PlotTrajectory(CTask *parent)
+{
+  I64 i;
+  CDC *dc=DCAlias(,parent);
+  State s;
+
+  MemSet(&s,0,sizeof(State));
+  s.wabbits=RandU16%100 +10;
+  s.hawks  =RandU16%10  +1;
+
+  for (i=0;i<1000;i++) {
+    dc->color=LTGREEN;
+    GrPlot(dc,s.wabbits+OX,OY-s.d_wabbits);
+    dc->color=LTRED;
+    GrPlot(dc,s.hawks  +OX,OY-s.d_hawks);
+    Steps(&s);
+  }
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 PredatorPrey()
+{
+  I64 i;
+  CDC *dc=DCAlias;
+
+  PopUpOk("This will plot multiple predator-prey\n"
+        "trajectories.  It restarts many times\n"
+        "with different, random, initial populations.\n");
+  SettingsPush; //See SettingsPush
+  try {
+    AutoComplete;
+    WinBorder;
+    WinMax;
+    DocClear;
+    Refresh;
+
+    dc->color=BLACK;
+    GrLine(dc,OX,0,OX,GR_HEIGHT-FONT_HEIGHT-1);
+    GrLine(dc,0,OY,GR_WIDTH-1,OY);
+    while (!ScanChar) {
+      mp_not_done_flags=1<<mp_cnt-1;
+      for (i=0;i<mp_cnt;i++)
+        JobQue(&PlotTrajectory,Fs,i);
+      do Yield;
+      while (mp_not_done_flags);
+    }
+  } catch
+    PutExcept;
+  SettingsPop;
+  DCFill(dc);
+  DCDel(dc);
+}
+
+PredatorPrey;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/RotateTank.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/RotateTank.HC.HTML new file mode 100755 index 0000000..50d47bd --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/RotateTank.HC.HTML @@ -0,0 +1,91 @@ + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+                <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+U0 RotateTank()
+{
+  CDC *dc=DCAlias;
+  DCDepthBufAlloc(dc);
+  dc->flags|=DCF_TRANSFORMATION;
+  WinHorz(TEXT_COLS/2-12,TEXT_COLS/2+12);
+  WinVert(TEXT_ROWS/2-12,TEXT_ROWS/2+12);
+  DocClear;
+  try {
+    while (!ScanChar) {
+      DCDepthBufRst(dc);
+      Mat4x4IdentEqu(dc->r);
+      Mat4x4RotY(dc->r,0.25*Sin(tS/10*2*pi)+pi/2);
+      Mat4x4RotX(dc->r,0.4*Sin(tS/5*2*pi));
+      Mat4x4RotZ(dc->r,0.25*Sin(tS/10*2*pi)-pi/2);
+      Mat4x4Scale(dc->r,0.25+Saw(tS,5));
+      DCMat4x4Set(dc,dc->r);//Not needed--Sets scale for pen-width
+
+      dc->x=Fs->pix_width/2;
+      dc->y=Fs->pix_height/2;
+//Offsets the image Z so that no parts are clipped by
+      //the conceptual plane of the scrn.
+      dc->z=GR_Z_ALL;
+
+      Sprite3(dc,0,0,0,<1>);
+      Refresh;
+      DCFill;
+    }
+  } catch
+    PutExcept;
+
+  DCFill;
+  DCDel(dc);
+}
+
+RotateTank;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/ScrnCapture.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/ScrnCapture.HC.HTML new file mode 100755 index 0000000..6332881 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/ScrnCapture.HC.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+//See ::/Demo/Games/Stadium/StadiumGen.HC.
+
+U0 Main()
+{
+  "Capture scrn...\n";
+  PressAKey;
+  GRScrnCaptureWrite("~/DemoScrnShot");
+  "View captured scrn...\n";
+  PressAKey;
+  GRScrnCaptureRead("~/DemoScrnShot");
+  PressAKey;
+  DCFill;
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/ScrollBars.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/ScrollBars.HC.HTML new file mode 100755 index 0000000..35a47df --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/ScrollBars.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+
+
+
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+#define MAP_HEIGHT      2048
+#define MAP_WIDTH       2048
+
+#define TREES_NUM       256
+
+I64 tree_x[TREES_NUM],tree_y[TREES_NUM];
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,h,v;
+
+  task->horz_scroll.min=0;
+  task->horz_scroll.max=MAP_WIDTH-task->pix_width;
+  task->vert_scroll.min=0;
+  task->vert_scroll.max=MAP_HEIGHT-task->pix_height;
+  TaskDerivedValsUpdate(task);
+
+  h=task->horz_scroll.pos;
+  v=task->vert_scroll.pos;
+
+  dc->color=BROWN;
+  dc->thick=4;
+  GrLine3(dc,2-h,2-v,0,MAP_WIDTH-3-h,2-v,0);
+  GrLine3(dc,2-h,MAP_HEIGHT-3-v,0,MAP_WIDTH-3-h,MAP_HEIGHT-3-v,0);
+  GrLine3(dc,2-h,2-v,0,2-h,MAP_HEIGHT-3-v,0);
+  GrLine3(dc,MAP_WIDTH-3-h,2-v,0,MAP_WIDTH-3-h,MAP_HEIGHT-3-v,0);
+
+  //Check bounds if you wish better performance.
+  for (i=0;i<TREES_NUM;i++)
+    Sprite3(dc,tree_x[i]-h,tree_y[i]-v,0,<Tree>);
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<TREES_NUM;i++) {
+    tree_x[i]=RandU16%MAP_WIDTH;
+    tree_y[i]=RandU16%MAP_HEIGHT;
+  }
+}
+
+U0 ScrollBars()
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  Fs->draw_it=&DrawIt;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DocScroll;
+
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+  GetChar(,FALSE);
+  SettingsPop;
+//If you care, you might want to
+  //save the original state of the
+  //scroll bars.
+}
+
+ScrollBars;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Shading.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Shading.HC.HTML new file mode 100755 index 0000000..cf0afec --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Shading.HC.HTML @@ -0,0 +1,208 @@ + + + + + + + + + + + +
+//"ls" is light source.
+
+U0 Lighting(CDC *dc,CD3I32 *ls,CD3I32 *poly,I64 color)
+{//color is a color from 0-7
+  CD3I32 v1,v2;
+  I64 *r=dc->r,i,vn_x,vn_y,vn_z;
+  F64 d;
+
+  v1.x=poly[0].x-poly[1].x;
+  v1.y=poly[0].y-poly[1].y;
+  v1.z=poly[0].z-poly[1].z;
+
+  v2.x=poly[2].x-poly[1].x;
+  v2.y=poly[2].y-poly[1].y;
+  v2.z=poly[2].z-poly[1].z;
+
+  //V1 and V2 are vects along two sides
+  //of the polygon joined at point[1].
+
+  vn_x=v1.y*v2.z-v1.z*v2.y;
+  vn_y=v1.z*v2.x-v1.x*v2.z;
+  vn_z=v1.x*v2.y-v1.y*v2.x;
+
+  if (d=Sqrt(SqrI64(vn_x)+SqrI64(vn_y)+SqrI64(vn_z)))
+    d=1<<16/d;
+  vn_x*=d;
+  vn_y*=d;
+  vn_z*=d;
+//Vn is the cross product of V1 and V3
+  //which means it is perpendicular.  It
+  //is the normal vect to the surface.
+  //It has been scaled to length 65536.
+  Mat4x4MulXYZ(r,&vn_x,&vn_y,&vn_z);
+  i=(vn_x*ls->x+vn_y*ls->y+vn_z*ls->z)>>16;
+//The dot product of the light source
+  //vect and the surface normal
+  //gives an illumination number.
+
+  //TempleOS will generate a random U16
+  //and compare to dither_probability_u16 and
+  //will pick from two colors.
+  //Probability dithering does not work with thick>1 at this time.
+  if (i<0) {
+    dc->color=ROPF_PROBABILITY_DITHER+BLACK<<16+color;
+    dc->dither_probability_u16=-i;
+  } else {
+    dc->color=ROPF_PROBABILITY_DITHER+(color^8)<<16+color;
+    dc->dither_probability_u16=i;
+  }
+}
+
+#define RINGS   8
+#define FACES   32
+#define SLOP    0.03 //Gaps appear without this.
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  CCtrl *c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES);
+  CViewAngles *s=c->state;
+  F64 tt=0.5*(Sin(pi*2*(tS%10.0)/10.0)+2.0),
+        theta,theta2,phi,phi2,radius,d;
+  I64 i,j,cx=task->pix_width/2,cy=task->pix_height/2;
+  CD3I32 poly[3],ls;
+
+  dc->flags|=DCF_TRANSFORMATION;
+  DCDepthBufAlloc(dc);
+
+  Mat4x4IdentEqu(dc->r);
+  Mat4x4RotZ(dc->r,s->az);
+  Mat4x4RotY(dc->r,s->ay);
+  Mat4x4RotX(dc->r,s->ax+pi);
+  Mat4x4Scale(dc->r,tt);
+  DCMat4x4Set(dc,dc->r);
+
+  ls.x=-(ms.pos.x-task->pix_left-task->scroll_x-cx);
+  ls.y=-(ms.pos.y-task->pix_top-task->scroll_y-cy);
+  ls.z=GR_WIDTH/8;
+  d=1<<16/D3I32Norm(&ls);
+  ls.x*=d;
+  ls.y*=d;
+  ls.z*=d;
+
+  dc->x=cx;
+  dc->y=cy;
+  dc->z=MaxI64(cx,cy);
+  radius =MinI64(cx,cy)/2;
+
+  for (i=0;i<RINGS;i++) {
+    phi =    i*pi/2/RINGS;
+    phi2=(i+1)*pi/2/RINGS+SLOP;
+    for (j=0;j<FACES;j++) {
+      theta =j*2*pi/FACES;
+      theta2=(j+1)*2*pi/FACES+SLOP;
+
+      //Upper half
+      poly[0].x=radius*Cos(phi)*Cos(theta);
+      poly[0].y=radius*Cos(phi)*Sin(theta);
+      poly[0].z=radius*Sin(phi);
+      poly[1].x=radius*Cos(phi)*Cos(theta2);
+      poly[1].y=radius*Cos(phi)*Sin(theta2);
+      poly[1].z=radius*Sin(phi);
+      poly[2].x=radius*Cos(phi2)*Cos(theta+2*pi/FACES/2);
+      poly[2].y=radius*Cos(phi2)*Sin(theta+2*pi/FACES/2);
+      poly[2].z=radius*Sin(phi2);
+      Lighting(dc,&ls,poly,BLUE);
+      GrFillPoly3(dc,3,poly);
+
+      poly[2].x=radius*Cos(phi2)*Cos(theta +2*pi/FACES/2);
+      poly[2].y=radius*Cos(phi2)*Sin(theta +2*pi/FACES/2);
+      poly[2].z=radius*Sin(phi2);
+      poly[1].x=radius*Cos(phi2)*Cos(theta2+2*pi/FACES/2);
+      poly[1].y=radius*Cos(phi2)*Sin(theta2+2*pi/FACES/2);
+      poly[1].z=radius*Sin(phi2);
+      poly[0].x=radius*Cos(phi)*Cos(theta2);
+      poly[0].y=radius*Cos(phi)*Sin(theta2);
+      poly[0].z=radius*Sin(phi);
+      Lighting(dc,&ls,poly,BLUE);
+      GrFillPoly3(dc,3,poly);
+
+      //Lower half
+      poly[2].x=radius*Cos(phi)*Cos(theta);
+      poly[2].y=radius*Cos(phi)*Sin(theta);
+      poly[2].z=-radius*Sin(phi);
+      poly[1].x=radius*Cos(phi)*Cos(theta2);
+      poly[1].y=radius*Cos(phi)*Sin(theta2);
+      poly[1].z=-radius*Sin(phi);
+      poly[0].x=radius*Cos(phi2)*Cos(theta+2*pi/FACES/2);
+      poly[0].y=radius*Cos(phi2)*Sin(theta+2*pi/FACES/2);
+      poly[0].z=-radius*Sin(phi2);
+      Lighting(dc,&ls,poly,RED);
+      GrFillPoly3(dc,3,poly);
+
+      poly[0].x=radius*Cos(phi2)*Cos(theta +2*pi/FACES/2);
+      poly[0].y=radius*Cos(phi2)*Sin(theta +2*pi/FACES/2);
+      poly[0].z=-radius*Sin(phi2);
+      poly[1].x=radius*Cos(phi2)*Cos(theta2+2*pi/FACES/2);
+      poly[1].y=radius*Cos(phi2)*Sin(theta2+2*pi/FACES/2);
+      poly[1].z=-radius*Sin(phi2);
+      poly[2].x=radius*Cos(phi)*Cos(theta2);
+      poly[2].y=radius*Cos(phi)*Sin(theta2);
+      poly[2].z=-radius*Sin(phi);
+      Lighting(dc,&ls,poly,RED);
+      GrFillPoly3(dc,3,poly);
+    }
+  }
+}
+
+//See ::/Demo/Graphics/SpritePlot3D.HC.
+//for a CSprite example.
+
+//See SpriteMeshEd() for a fancy example.
+
+U0 Main()
+{
+  CCtrl *c=ViewAnglesNew;
+  CViewAngles *s=c->state;
+  s->sx=2*VIEWANGLES_SNAP;
+  s->sy=7*VIEWANGLES_SNAP;
+  s->sz=6*VIEWANGLES_SNAP;
+
+  SettingsPush; //See SettingsPush
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  try {
+    "\n\nMove mouse to change light source.\n\n";
+    PressAKey;
+  } catch
+    PutExcept;
+  DocClear;
+  SettingsPop;
+  ViewAnglesDel;
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Shadow.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Shadow.HC.HTML new file mode 100755 index 0000000..7316cf0 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Shadow.HC.HTML @@ -0,0 +1,133 @@ + + + + + + + + + + + +
+F64 theta,phi,omega,s;
+CDC *dc0,*dc1;
+
+
+
+
+
+
+
+
+                 <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+U0 GrBlackLighting(CDC *dc,CD3I32 *,CD3I32 *,CD3I32 *,CColorROPU32)
+{
+  dc->color=0;
+}
+
+U0 DrawShadow(CTask *task)
+{
+  I64 r[4][4],*r2;
+
+  Mat4x4IdentEqu(dc1->r);
+  Mat4x4RotZ(dc1->r,theta);
+  Mat4x4RotX(dc1->r,phi);
+  Mat4x4RotZ(dc1->r,omega);
+  Mat4x4Scale(dc1->r,s);
+  Mat4x4TranslationEqu(dc1->r,200,200,5000);
+  dc1->flags|=DCF_TRANSFORMATION;
+  DCMat4x4Set(dc1,dc1->r);
+
+  MemSet(r,0,sizeof(r));
+
+  r[0][0]=GR_SCALE;
+  r[1][1]=GR_SCALE/2; //Pick a plane for the shadow, to suit your taste.
+  r[1][2]=GR_SCALE/2; //It doesn't have to have a norm of 1.0.
+  r[2][2]=GR_SCALE;
+  r[3][3]=GR_SCALE;
+
+  Mat4x4TranslationEqu(r,0,-2200,1000);
+  r2=Mat4x4MulMat4x4New(r,dc1->r,task);
+  Free(dc1->r);
+  DCMat4x4Set(dc1,r2);
+
+  dc1->lighting=&GrBlackLighting;
+  Sprite3(dc1,0,0,0,<1>);
+}
+
+U0 DrawIt(CTask *task,CDC *)
+{
+  DCDepthBufRst(dc0);
+  Mat4x4IdentEqu(dc0->r);
+  Mat4x4RotZ(dc0->r,theta);
+  Mat4x4RotX(dc0->r,phi);
+  Mat4x4RotZ(dc0->r,omega);
+  Mat4x4Scale(dc0->r,s);
+  Mat4x4TranslationEqu(dc0->r,200,200,5000);
+  dc0->flags|=DCF_TRANSFORMATION;
+  DCMat4x4Set(dc0,dc0->r);
+  if (mp_cnt>1)
+    JobQue(&DrawShadow,task,1);
+  else
+    DrawShadow(task);
+  Sprite3(dc0,0,0,0,<1>);
+}
+
+U0 Shadow()
+{//The shadow image b.s.  Any is plausible.
+  dc0=DCAlias(gr.dc2,Fs);
+  dc1=DCAlias(gr.dc2,Fs);
+  DCDepthBufAlloc(dc0);
+  dc1->depth_buf=dc0->depth_buf;
+
+  theta=0;
+  phi=0;
+  omega=0;
+  s=1.5;
+
+  SettingsPush; //See SettingsPush
+  WinMax;
+  Fs->draw_it=&DrawIt;
+
+  while (!ScanChar) {
+    theta+=2*pi/70;
+    phi+=2*pi/90;
+    omega+=2*pi/110;
+    Sleep(20);
+  }
+  SettingsPop;
+  DCDel(dc0);
+  dc1->depth_buf=NULL;
+  DCDel(dc1);
+}
+
+Shadow;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Slider.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Slider.HC.HTML new file mode 100755 index 0000000..382c214 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Slider.HC.HTML @@ -0,0 +1,141 @@ + + + + + + + + + + + +
+/*This was done with <CTRL-SHIFT-L> template code.
+It's conceptually easy to do a ctrl,
+but tedious.  You have complete freedom.
+
+See CCtrl.
+*/
+
+//Start of autocreated Code
+#define SLIDER_RANGE   30
+#define SLIDER_SPACING 20
+#define SLIDER_BORDER  2
+
+class CSliderState
+{
+  I64 left_pos;
+  I64 right_pos;
+} sld;
+
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,SLIDER_SPACING*3+2,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BLUE;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+        SLIDER_SPACING*3+2-2*SLIDER_BORDER,
+        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING,
+        c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
+        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  dc->color=LTRED;
+  GrPrint(dc,c->left+1*SLIDER_SPACING+0-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->left_pos*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->right_pos*10/SLIDER_RANGE);
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-2,7,5);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-1,5,3);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-1,5,3);
+}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
+  c->right=c->left+3*SLIDER_SPACING+2;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+  s->left_pos=ClampI64(s->left_pos,0,SLIDER_RANGE-1);
+  s->right_pos=ClampI64(s->right_pos,0,SLIDER_RANGE-1);
+}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CSliderState *s=c->state;
+  if (x<c->left+1*SLIDER_SPACING+0+SLIDER_SPACING/2)
+    s->left_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else
+    s->right_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&sld;
+  MemSet(&sld,0,sizeof(CSliderState));
+  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+//End of autocreated Code
+
+U0 Main()
+{
+  "This is to demo ctrls.\n";
+  CCtrl *c=SliderNew;
+  PressAKey;
+  "Left: %d  Right: %d\n",
+        sld.left_pos*10/SLIDER_RANGE,
+        sld.right_pos*10/SLIDER_RANGE;
+  SliderDel(c);
+  DocBottom;
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Speedline.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Speedline.HC.HTML new file mode 100755 index 0000000..fe2103f --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Speedline.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+//This is a drawing program
+
+public U0 SpeedLineDemo()
+{
+  I64 msg_code,cnt,x1,y1,x2,y2,arg1,arg2,color=BLACK;
+  CDC *dc=DCAlias;
+  dc->color=color;
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+1<<MSG_MS_R_UP);
+    switch (msg_code) {
+      case MSG_MS_R_UP:
+        color=PopUpColor;
+        if (color>=0)
+          dc->color=color;
+        break;
+      case MSG_MS_L_DOWN:
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        cnt=0;
+        while (msg_code!=MSG_MS_L_UP) {
+          dc->thick=0.04*ms.speed;
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,
+                1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          x1=x2; y1=y2;
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        break;
+      case MSG_KEY_DOWN:
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || !arg1);
+  GetMsg(,,1<<MSG_KEY_UP);
+  DCFill;
+  DCDel(dc);
+  SettingsPop;
+}
+
+SpeedLineDemo;  //Execute when #included
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/SpritePlot.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/SpritePlot.HC.HTML new file mode 100755 index 0000000..f5b3552 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/SpritePlot.HC.HTML @@ -0,0 +1,92 @@ + + + + + + + + + + + +
+/*Sprite graphics can be placed in src code.
+The binary graphic data is stored in the
+file after the text area.  <CTRL-r> is used
+to generate a sprite.  Press <CTRL-t> to
+toggle to plain text mode and see its
+text place holder $SP...$.  You can place any text
+in the tag quotes or none.  The text doesn't matter,
+but the BI=num does.  The num identifies
+the sprite and can't be changed by you.
+
+Insert a ptr to a sprite by pressing <CTRL-r>
+and "Ptr to Sprite".  This creates an "Insert Bin",
+$IB...$ DolDoc cmd you can see by toggling
+to text with <CTRL-t>.
+
+IB's behave like string consts in HolyC when
+compiled.  That is, they are ptrs to data.
+
+This file uses the persistent graphic
+device context CDC, gr.dc, while the other
+demo's use gr.dc2 which must be redrawn at
+30 fps by the window mgr task.  This demo
+is simpler because you do not need
+a window update callback routine.
+*/
+
+
+
+
+
+
+
+
+
+            <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+U0 SpritePlot()
+{
+  CDC *dc=DCAlias;
+  I64 i;
+  DocClear;
+  for (i=0;i<GR_WIDTH>>2;i++) {
+    DCFill;
+    Sprite3(dc,i,GR_HEIGHT>>1,0,<1>);
+    Sleep(3);
+  }
+  "Image size:%d\n",<1>;
+  DCDel(dc);
+  PressAKey;
+  DCFill;
+}
+
+SpritePlot;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/SpritePlot3D.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/SpritePlot3D.HC.HTML new file mode 100755 index 0000000..254d4d8 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/SpritePlot3D.HC.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+      <1>/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+I64 glbl_r[4][4];
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 *old_r=dc->r;
+  dc->x=200;
+  dc->y=200;
+  dc->z=GR_Z_ALL;
+  dc->flags|=DCF_TRANSFORMATION;
+  DCDepthBufAlloc(dc);
+  DCMat4x4Set(dc,glbl_r); //This assigns to dc->r and sets r_norm.
+  DCDepthBufRst(dc);
+  Sprite3(dc,0,0,0,<1>);
+  dc->r=old_r;
+}
+
+U0 SpritePlot3D()
+{
+  F64 theta=0,phi=0;
+
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+  while (!ScanChar) {
+    Mat4x4IdentEqu(glbl_r);
+    Mat4x4RotX(glbl_r,phi);
+    Mat4x4RotZ(glbl_r,theta);
+
+    Sleep(40);
+    theta+=2*pi/100;
+    phi+=2*pi/130;
+  }
+  SettingsPop;
+}
+
+SpritePlot3D;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/SpritePut.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/SpritePut.HC.HTML new file mode 100755 index 0000000..1722827 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/SpritePut.HC.HTML @@ -0,0 +1,70 @@ + + + + + + + + + + + +
+//Use <CTRL-r> to add or edit sprites
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+//Used by ::/Demo/Graphics/SpritePutExt.HC.
+
+U0 SpritePut()
+{
+  I64 i;
+  for (i=0;i<3;i++) {
+    "US Flag:";
+    Sprite(<1>);
+    "%h12c",'\n';
+  }
+  "US Map:";
+  Sprite(<2>);
+  "%h10c",'\n';
+}
+
+SpritePut; //Start program when #included
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/SpritePutExt.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/SpritePutExt.HC.HTML new file mode 100755 index 0000000..8743840 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/SpritePutExt.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+/*If you press <CTRL-t> you will see this:
+
+$IB,"<1>",BI=1,BP="::/Demo/Graphics/SpritePut.HC,2"$
+
+That imports an external sprite.  It's
+called a DOCEF_BIN_PTR_LINK.  See BP="".
+
+Press <CTRL-r> and "Ptr to Sprite".
+Then, enter a file and the number of
+the sprite in the file.  Note: the
+number can get messed-up if you change
+the order of sprites in the source file.
+You can link to a tag string instead of a num.
+*/
+
+U0 SpritePutExt()
+{
+  I64 i;
+  for (i=0;i<3;i++) {
+    "US Map:";
+    Sprite(<1>);
+    "%h12c",'\n'; //"h" is a secondary arg.  Print 12 newline chars.
+  }
+}
+
+SpritePutExt;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/SpriteRaw.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/SpriteRaw.HC.HTML new file mode 100755 index 0000000..f12be80 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/SpriteRaw.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+//Normally, you make sprites with <CTRL-r>.
+//This shows how to build a sprite by hand.
+//See ::/Apps/GrModels.
+
+class MySprite
+{ // See Sprite Elem Types
+  CSpriteColor  color;
+  CSpritePtPt   line1;
+  CSpritePtPt   line2;
+  CSpritePtPt   line3;
+  CSpritePt     fill;
+  CSpriteBase   end;
+};
+
+
+U0 SpriteRawDemo()
+{
+  MySprite s;
+
+  MemSet(&s,0,sizeof(s));
+  s.color.type=SPT_COLOR;
+  s.color.color=GREEN;
+  s.line1.type=SPT_LINE;
+  s.line1.x2=100; s.line1.y2=50;
+  s.line2.type=SPT_LINE;
+  s.line2.x2=50; s.line2.y2=100;
+  s.line3.type=SPT_LINE;
+  s.line3.x1=100; s.line3.y1=50;
+  s.line3.x2=50; s.line3.y2=100;
+  s.fill.type=SPT_FLOOD_FILL;
+  s.fill.x1=20; s.fill.y1=20;
+  s.end.type=SPT_END;
+
+  Sprite(&s);
+  "%h13c",'\n';
+}
+
+SpriteRawDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/SpriteText.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/SpriteText.HC.HTML new file mode 100755 index 0000000..6db8a60 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/SpriteText.HC.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+
+                /* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+U0 SpriteText(U8 *elems)
+{
+  CSprite *tmpg=elems-offset(CSprite.start);
+  U8 *st;
+  while (tmpg->type&SPG_TYPE_MASK) {
+//Study this routine SpriteElem2Summary().
+    st=SpriteElem2Summary(tmpg);
+    "%s\n",st;
+    Free(st);
+    tmpg(U8 *)+=SpriteElemSize(tmpg);
+  }
+}
+
+"$PURPLE$**** LINE SUMMARIES ****$FG$\n";
+SpriteText(<1>);
+
+"\n\n$PURPLE$**** ENTIRE SPRITE CODE ****$FG$\n";
+Sprite2Code(,<1>);
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/SunMoon.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/SunMoon.HC.HTML new file mode 100755 index 0000000..17f873c --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/SunMoon.HC.HTML @@ -0,0 +1,74 @@ + + + + + + + + + + + +
+/*gr.dc is the persistent layer.  You can access
+it directly but two tasks accessing it simultaneously
+with no DCAlias() will screw-up color and stuff.
+*/
+
+U0 SunMoon()
+{
+  I64 i,x,y,radius;
+
+  AutoComplete; //AutoComplete Off
+  WinBorder;    //No Border
+  WinMax;       //Maximize window
+  DocClear;     //Clear command-line text
+  Fs->text_attr=BLACK<<4+WHITE; //Current CTask is Fs segment register.
+
+  for (i=0;i<0x8000;i+=0x200) {
+//Sun
+    x=0.2*GR_WIDTH; y=0.5*GR_HEIGHT; radius=120;
+    gr.dc->color=DKGRAY;
+    GrCircle(gr.dc,x,y,radius);
+    gr.dc->color=ROPF_DITHER+RED<<16+YELLOW;
+    GrFloodFill(gr.dc,x,y);
+
+    //Moon
+    x=0.8*GR_WIDTH-i/0x200; y=0.5*GR_HEIGHT; radius=75;
+    gr.dc->color=DKGRAY;
+    GrCircle(gr.dc,x,y,radius);
+//<CTRL-ALT-a> for the "pi" character.
+    GrCircle(gr.dc,x+0.5*radius,y,1.2*radius,,pi-.31*pi,0.62*pi);
+    gr.dc->color=ROPF_PROBABILITY_DITHER+LTGRAY<<16+BLACK;
+    gr.dc->dither_probability_u16=i;    //U16 can be [0,65535]
+    GrFloodFill(gr.dc,x+0.5*radius,y);
+    gr.dc->dither_probability_u16=2*i;  //U16 can be [0,65535]
+    GrFloodFill(gr.dc,x-0.75*radius,y);
+
+    Refresh; //Typically 30 fps
+    DCFill;
+  }
+
+  Fs->text_attr=WHITE<<4+BLUE;
+}
+
+SunMoon;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Symmetry.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Symmetry.HC.HTML new file mode 100755 index 0000000..c6fb04f --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Symmetry.HC.HTML @@ -0,0 +1,93 @@ + + + + + + + + + + + +
+/*Demonstrates symmetry.
+Right-click and draw line of symmetry.
+If the line of symmetry is a point, symmetry is turned-off.
+*/
+
+U0 SymmetryDemo()
+{
+  I64 msg_code,x1,y1,x2,y2,arg1,arg2;
+  CDC *dc=DCAlias;
+
+  SettingsPush; //See SettingsPush
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER;
+
+  WinBorder;
+  WinMax;
+  DocClear;
+  DCFill;
+  dc->flags|=DCF_SYMMETRY;
+  DCSymmetrySet(dc,Fs->pix_width/2,0,Fs->pix_width/2,1);
+  do {
+    msg_code=GetMsg(&arg1,&arg2,
+          1<<MSG_KEY_DOWN+1<<MSG_MS_L_DOWN+
+          1<<MSG_MS_R_DOWN);
+    switch (msg_code) {
+      case MSG_MS_R_DOWN:
+        dc->flags&=~DCF_SYMMETRY;
+        dc->color=ROP_XOR+RED^TRANSPARENT;
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        while (msg_code!=MSG_MS_R_UP) {
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,
+                1<<MSG_MS_R_UP+1<<MSG_MS_MOVE);
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        if (DCSymmetry3Set(dc,x1,y1,0,x2,y2,0,x2,y2,1))
+          dc->flags|=DCF_SYMMETRY;
+        break;
+      case MSG_MS_L_DOWN:
+        dc->color=ROP_XOR+BLACK^TRANSPARENT;
+        x1=arg1; y1=arg2;
+        x2=arg1; y2=arg2;
+        while (msg_code!=MSG_MS_L_UP) {
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          msg_code=GetMsg(&arg1,&arg2,
+                1<<MSG_MS_L_UP+1<<MSG_MS_MOVE);
+          GrLine3(dc,x1,y1,0,x2,y2,0);
+          x2=arg1; y2=arg2;
+        }
+        GrLine3(dc,x1,y1,0,x2,y2,0);
+        break;
+    }
+  } while (msg_code!=MSG_KEY_DOWN || (arg1!=CH_ESC && arg1!=CH_SHIFT_ESC));
+  GetMsg(,,1<<MSG_KEY_UP);
+  DCFill;
+  DCDel(dc);
+  SettingsPop;
+}
+
+SymmetryDemo;  //Execute when #included
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/Transform.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/Transform.HC.HTML new file mode 100755 index 0000000..a0d73fa --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/Transform.HC.HTML @@ -0,0 +1,253 @@ + + + + + + + + + + + +
+/*This highlights the 4th dimension
+of the transformation matrix which
+is used for storing translations (shifts)
+in matricies so they can be combined
+with a matrix multiplication.
+
+Scroll bar works.
+
+The multiplication takes place in the
+Sprite3ZB routine.
+*/
+
+#define SLIDER_SPACING 20
+#define SLIDER_RANGE   30
+#define SLIDER_BORDER  2
+
+class CSliderState
+{
+  I64 s1,s2,s3;
+  F64 arg1,arg2,scale;
+} s;
+
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTGREEN;
+  GrRect(dc, c->left,c->top,SLIDER_SPACING*4+3,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BROWN;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+        SLIDER_SPACING*4+3-2*SLIDER_BORDER,
+        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+SLIDER_SPACING,c->top+SLIDER_SPACING,
+        c->left+SLIDER_SPACING,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
+        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+3*SLIDER_SPACING+2,c->top+SLIDER_SPACING,
+        c->left+3*SLIDER_SPACING+2,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+
+  dc->color=LTGREEN;
+  GrPrint(dc,c->left+SLIDER_SPACING-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->s1*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->s2*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+3*SLIDER_SPACING+2-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->s3*10/SLIDER_RANGE);
+  GrRect(dc,c->left+SLIDER_SPACING-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s1-2 ,7,5);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s2-2,7,5);
+  GrRect(dc,c->left+3*SLIDER_SPACING+2-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s3-2,7,5);
+  dc->color=GREEN;
+  GrRect(dc,c->left+SLIDER_SPACING-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s1-1 ,5,3);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s2-1,5,3);
+  GrRect(dc,c->left+3*SLIDER_SPACING+2-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->s3-1,5,3);
+}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*4+3)/2;
+  c->right=c->left+SLIDER_SPACING*4+3;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+  s->s1=ClampI64(s->s1,0,SLIDER_RANGE-1);
+  s->s2=ClampI64(s->s2,0,SLIDER_RANGE-1);
+  s->s3=ClampI64(s->s3,1,SLIDER_RANGE-1);
+  s->arg1=pi/2.0*s->s1/SLIDER_RANGE;
+  s->arg2=1.0*(s->s2-SLIDER_RANGE/2)/SLIDER_RANGE;
+  s->scale=2.0*s->s3/SLIDER_RANGE;
+}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CSliderState *s=c->state;
+  if (x<c->left+(c->right-c->left)/3)
+    s->s1=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else if (x<c->left+2*(c->right-c->left)/3)
+    s->s2=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else
+    s->s3=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c=CAlloc(sizeof(CCtrl));
+  c->win_task=Fs;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=&s;
+  MemSet(&s,0,sizeof(s));
+  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,Fs->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c);
+}
+
+
+
+
+
+<1>/* Graphics Not Rendered in HTML */
+
+#define MAP_HEIGHT      2048
+#define MAP_WIDTH       2048
+
+#define TREES_NUM       256
+
+I64 tree_x[TREES_NUM],tree_y[TREES_NUM];
+
+class MPCtrl {
+  I64 mp_cnt;
+  I64 r[16];
+  F64 a;
+} mp;
+
+I64 mp_not_done_flags;
+
+U0 MPDrawIt(CTask *task)
+{
+  CDC *dc=DCAlias(gr.dc2,task);
+  I64 i,lo=Gs->num*TREES_NUM/mp.mp_cnt,hi=(Gs->num+1)*TREES_NUM/mp.mp_cnt;
+  MemCpy(dc->r,mp.r,sizeof(I64)*16);
+  dc->flags|=DCF_TRANSFORMATION;
+  for (i=lo;i<hi;i++)
+    Sprite3ZB(dc,tree_x[i],
+          tree_y[i],0,<tree>,mp.a);
+  DCDel(dc);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64 i,h,v;
+  task->horz_scroll.min=-s.scale*MAP_HEIGHT*Sin(s.arg1);
+  task->horz_scroll.max=s.scale*MAP_WIDTH*Cos(s.arg1)-task->pix_width;
+  task->vert_scroll.min=0;
+  task->vert_scroll.max=s.scale*(MAP_HEIGHT*Cos(s.arg1)+MAP_WIDTH*Sin(s.arg1))
+  -task->pix_height;
+  TaskDerivedValsUpdate(task);
+
+  h=task->horz_scroll.pos;
+  v=task->vert_scroll.pos;
+
+  Mat4x4RotZ(dc->r,s.arg1);
+  Mat4x4Scale(dc->r,s.scale);
+  DCMat4x4Set(dc,dc->r);
+  Mat4x4TranslationEqu(dc->r,-h,-v,0);
+  MemCpy(mp.r,dc->r,sizeof(I64)*16);
+  mp.a=s.arg2;
+
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp.mp_cnt;i++)
+    JobQue(&MPDrawIt,task,i);
+  while (mp_not_done_flags)
+    Yield;
+
+  dc->flags|=DCF_TRANSFORMATION;
+  dc->color=BROWN;
+  dc->thick=4;
+  GrLine3(dc,2,2,0,MAP_WIDTH-3,2,0);
+  GrLine3(dc,2,MAP_HEIGHT-3,0,MAP_WIDTH-3,MAP_HEIGHT-3,0);
+  GrLine3(dc,2,2,0,2,MAP_HEIGHT-3,0);
+  GrLine3(dc,MAP_WIDTH-3,2,0,MAP_WIDTH-3,MAP_HEIGHT-3,0);
+}
+
+U0 Init()
+{
+  I64 i;
+  for (i=0;i<TREES_NUM;i++) {
+    tree_x[i]=RandU16%MAP_WIDTH;
+    tree_y[i]=RandU16%MAP_HEIGHT;
+  }
+}
+
+U0 TransformDemo(I64 _mp_cnt=mp_cnt)
+{
+  SettingsPush; //See SettingsPush
+  Init;
+  Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_FOCUS-WIF_SELF_BORDER
+        -WIF_SELF_GRAB_SCROLL-WIF_FOCUS_TASK_MENU-WIF_SELF_CTRLS;
+  Fs->draw_it=&DrawIt;
+  WinBorder(ON);
+  DocCursor;
+  DocClear;
+  DocScroll;
+
+  Fs->horz_scroll.pos=0;
+  Fs->vert_scroll.pos=0;
+  CCtrl *c=SliderNew;
+  s.s1=0;
+  s.s2=SLIDER_RANGE/2;
+  s.s3=SLIDER_RANGE/2;
+
+  MemSet(&mp,0,sizeof(MPCtrl));
+  mp.mp_cnt=_mp_cnt;
+
+  View;
+  SliderDel(c);
+  SettingsPop;
+//You might want to save the original state of the scroll bars.
+}
+
+TransformDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/WallPaperCtrl.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/WallPaperCtrl.HC.HTML new file mode 100755 index 0000000..d9e0d74 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/WallPaperCtrl.HC.HTML @@ -0,0 +1,139 @@ + + + + + + + + + + + +
+/*Done with <CTRL-SHIFT-L> template code
+that was modified.
+
+This is an advanced demo that shows
+that you can place ctrls on the
+wall paper.
+
+See ::/Demo/Graphics/Slider.HC
+and ::/Demo/Graphics/WallPaperFish.HC
+before messing with this program.
+
+It must be "Adam Included".
+*/
+
+#define SLIDER_RANGE   30
+#define SLIDER_SPACING 20
+#define SLIDER_BORDER  2
+
+class CSliderState
+{
+  I64 left_pos;
+  I64 right_pos;
+};
+
+U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
+{
+  CSliderState *s=c->state;
+
+  dc->color=LTRED;
+  GrRect(dc, c->left,c->top,SLIDER_SPACING*3+2,SLIDER_SPACING*2+SLIDER_RANGE);
+  dc->color=BLUE;
+  GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
+        SLIDER_SPACING*3+2-2*SLIDER_BORDER,
+        SLIDER_SPACING*2+SLIDER_RANGE-2*SLIDER_BORDER);
+  dc->color=BLACK;
+  GrLine(dc,c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING,
+        c->left+1*SLIDER_SPACING+0,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  GrLine(dc,c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING,
+        c->left+2*SLIDER_SPACING+1,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
+  dc->color=LTRED;
+  GrPrint(dc,c->left+1*SLIDER_SPACING+0-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->left_pos*10/SLIDER_RANGE);
+  GrPrint(dc,c->left+2*SLIDER_SPACING+1-FONT_WIDTH/2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE+3,
+        "%d",s->right_pos*10/SLIDER_RANGE);
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-2,7,5);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-3,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-2,7,5);
+  dc->color=YELLOW;
+  GrRect(dc,c->left+1*SLIDER_SPACING+0-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->left_pos-1,5,3);
+  GrRect(dc,c->left+2*SLIDER_SPACING+1-2,
+        c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->right_pos-1,5,3);
+}
+
+U0 UpdateDerivedCtrlSlider(CCtrl *c)
+{
+  CSliderState *s=c->state;
+  c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
+  c->right=c->left+3*SLIDER_SPACING+2;
+  c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
+  c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
+  s->left_pos=ClampI64(s->left_pos,0,SLIDER_RANGE-1);
+  s->right_pos=ClampI64(s->right_pos,0,SLIDER_RANGE-1);
+}
+
+U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool)
+{
+  CSliderState *s=c->state;
+  if (x<c->left+1*SLIDER_SPACING+0+SLIDER_SPACING/2)
+    s->left_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  else
+    s->right_pos=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));
+  if (c->update_derived_vals)
+    (*c->update_derived_vals)(c);
+}
+
+CCtrl *SliderNew()
+{
+  CCtrl *c;
+  if (Fs!=adam_task) {
+    "Must be Adam Included with SHIFT-F5.\n"
+          "(Would crash when code mem was freed.)\n";
+    return NULL;
+  }
+  c=ACAlloc(sizeof(CCtrl));
+  c->win_task=sys_winmgr_task;
+  c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
+  c->type=CTRLT_GENERIC;
+  c->state=ACAlloc(sizeof(CSliderState));
+  c->draw_it=&DrawCtrlSlider;
+  c->left_click=&LeftClickSlider;
+  c->update_derived_vals=&UpdateDerivedCtrlSlider;
+  QueIns(c,sys_winmgr_task->last_ctrl);
+  TaskDerivedValsUpdate;
+  return c;
+}
+
+U0 SliderDel(CCtrl *c)
+{
+  QueRem(c);
+  Free(c->state);
+  Free(c);
+}
+
+SliderNew;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/WallPaperFish.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/WallPaperFish.HC.HTML new file mode 100755 index 0000000..f125ba7 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/WallPaperFish.HC.HTML @@ -0,0 +1,146 @@ + + + + + + + + + + + +
+/* You "Adam include" this because you want the wallpaper
+routine to stay in mem even if this task is killed.
+
+  <CTRL-t> to see the hidden text needed for sprite elements.
+
+  <CTRL-r> to add a sprite to a document.
+*/
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+<2>/* Graphics Not Rendered in HTML */
+
+
+<3>/* Graphics Not Rendered in HTML */
+
+
+<4>/* Graphics Not Rendered in HTML */
+
+
+
+<5>/* Graphics Not Rendered in HTML */
+
+
+
+<6>/* Graphics Not Rendered in HTML */
+
+
+
+<7>/* Graphics Not Rendered in HTML */
+
+
+<8>/* Graphics Not Rendered in HTML */
+
+
+<9>/* Graphics Not Rendered in HTML */
+
+
+#define TYPES_OF_CRITTERS       3
+#define FRAMES_PER_CRITTER      4
+
+U8 *imgs[TYPES_OF_CRITTERS][FRAMES_PER_CRITTER]={
+  {<1>,<2>,<3>,<2>},
+  {<4>,<5>,<6>,<5>},
+  {<7>,<8>,<9>,<8>}
+};
+
+#define CRITTERS_NUM    16
+class Critter
+{
+  I64 x,y,dx,dy,type;
+  F64 t_offset;
+} wall_crits[CRITTERS_NUM];
+
+U0 (*old_wall_paper)(CTask *task);
+
+U0 WallPaperFish(CTask *task)
+{
+  I64 i,j,x,y;
+  CDC *dc=DCAlias(gr.dc2,task);
+  Critter *c=wall_crits;
+
+  task->text_attr=CYAN<<4+WHITE;
+  dc->color=BROWN;
+  for (i=0;i<GR_HEIGHT;i+=20) {
+    j=16*Tri(tS*10,20);
+    GrLine(dc,0,GR_HEIGHT-i-j,GR_HEIGHT-i-j,GR_HEIGHT);
+  }
+  for (i=0;i<CRITTERS_NUM;i++,c++) {
+    j=(tS*4+c->t_offset)%FRAMES_PER_CRITTER;
+    x=c->x>>16%GR_WIDTH;
+    if (x<0) x+=GR_WIDTH;
+    y=c->y>>16%GR_HEIGHT;
+    if (y<0) y+=GR_HEIGHT;
+    if (c->dx<0) {
+      dc->flags|=DCF_SYMMETRY|DCF_JUST_MIRROR;
+      DCSymmetrySet(dc,x,y-1,x,y+1);
+    } else
+      dc->flags&=~(DCF_SYMMETRY|DCF_JUST_MIRROR);
+    Sprite3(dc,x,y,0,imgs[c->type][j]);
+    c->x+=c->dx;  c->y+=c->dy;
+  }
+  DCDel(dc);
+
+  //Uncomment the following if you wish.
+  //old_wall_paper(task);
+}
+
+U0 WallInit()
+{
+  I64 i;
+  Critter *c;
+  if (Fs!=adam_task) {
+    "Must be Adam Included with SHIFT-F5.\n"
+          "(Would crash when code mem was freed.)\n";
+    return;
+  }
+  old_wall_paper=gr.fp_wall_paper;
+  c=wall_crits;
+  for (i=0;i<CRITTERS_NUM;i++,c++) {
+    c->x=(RandU16%GR_WIDTH)<<16;
+    c->y=(RandU16%GR_HEIGHT)<<16;
+    c->type=RandU16%TYPES_OF_CRITTERS;
+    c->dx=RandI16;
+    if (c->dx<0)
+      c->dx-=0x4000;
+    else
+      c->dx+=0x4000;
+    c->dy=RandI16;
+    c->t_offset=Rand*FRAMES_PER_CRITTER;
+  }
+  gr.fp_wall_paper=&WallPaperFish;
+}
+
+WallInit;
+
+ diff --git a/public/Wb/Home/Src/Demo/Graphics/WinZBuf.HC.HTML b/public/Wb/Home/Src/Demo/Graphics/WinZBuf.HC.HTML new file mode 100755 index 0000000..b10be15 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Graphics/WinZBuf.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+U0 DrawIt(CTask *,CDC *dc)
+{
+  I64 i,j;
+  U16 *ptr=gr.win_z_buf;
+  dc->color=BLACK;
+  GrPrint(dc,0,0,"Move the windows around and watch.");
+  for (i=0;i<TEXT_ROWS;i++)
+    for (j=0;j<TEXT_COLS;j++) {
+      dc->color=*ptr++&15;
+      GrPlot(dc,j,i+FONT_HEIGHT);
+    }
+}
+
+U0 ScrollBars()
+{
+  SettingsPush; //See SettingsPush
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar(,FALSE);
+  SettingsPop;
+}
+
+ScrollBars;
+
+ diff --git a/public/Wb/Home/Src/Demo/InFile/InEd.DD.HTML b/public/Wb/Home/Src/Demo/InFile/InEd.DD.HTML new file mode 100755 index 0000000..617c7c7 --- /dev/null +++ b/public/Wb/Home/Src/Demo/InFile/InEd.DD.HTML @@ -0,0 +1,259 @@ + + + + + + + + + + + +
+//Intermediate compiler codes
+#define IC_END                  0x00
+#define IC_START                0x01
+#define IC_NOP1                 0x02
+#define IC_END_EXP              0x03
+#define IC_NOP2                 0x04
+#define IC_LABEL                0x05
+#define IC_CALL_START           0x06
+#define IC_CALL_END             0x07
+#define IC_CALL_END2            0x08
+#define IC_RETURN_VAL           0x09
+#define IC_RETURN_VAL2          0x0A
+#define IC_IMM_I64              0x0B
+#define IC_IMM_F64              0x0C
+#define IC_STR_CONST            0x0D
+#define IC_ABS_ADDR             0x0E
+#define IC_ADDR_IMPORT          0x0F
+#define IC_HEAP_GLBL            0x10
+#define IC_SIZEOF               0x11
+#define IC_TYPE                 0x12
+#define IC_GET_LABEL            0x13
+#define IC_RBP                  0x14
+#define IC_REG                  0x15
+#define IC_FS                   0x16
+#define IC_GS                   0x17
+
+#define IC_LEA                  0x18
+#define IC_MOV                  0x19
+
+#define IC_TO_I64               0x1A
+#define IC_TO_F64               0x1B
+#define IC_TO_BOOL              0x1C
+#define IC_TOUPPER              0x1D
+#define IC_HOLYC_TYPECAST       0x1E
+
+#define IC_ADDR                 0x1F
+#define IC_COM                  0x20
+#define IC_NOT                  0x21
+#define IC_UNARY_MINUS          0x22
+
+#define IC_DEREF                0x23
+#define IC_DEREF_PP             0x24
+#define IC_DEREF_MM             0x25
+#define IC__PP                  0x26
+#define IC__MM                  0x27
+#define IC_PP_                  0x28
+#define IC_MM_                  0x29
+
+#define IC_SHL                  0x2A
+#define IC_SHR                  0x2B
+#define IC_SHL_CONST            0x2C
+#define IC_SHR_CONST            0x2D
+#define IC_POWER                0x2E
+
+#define IC_MUL                  0x2F
+#define IC_DIV                  0x30
+#define IC_MOD                  0x31
+
+#define IC_AND                  0x32
+
+#define IC_OR                   0x33
+#define IC_XOR                  0x34
+
+#define IC_ADD                  0x35
+#define IC_SUB                  0x36
+#define IC_ADD_CONST            0x37
+#define IC_SUB_CONST            0x38
+
+#define IC_EQU_EQU              0x39
+#define IC_NOT_EQU              0x3A
+#define IC_LESS                 0x3B
+#define IC_GREATER              0x3C
+#define IC_LESS_EQU             0x3D
+#define IC_GREATER_EQU          0x3E
+#define IC_PUSH_CMP             0x3F
+
+#define IC_AND_AND              0x40
+
+#define IC_OR_OR                0x41
+#define IC_XOR_XOR              0x42
+
+#define IC_COLON                0x43
+#define IC_QUESTION             0x44
+
+#define IC_ASSIGN               0x45
+#define IC_ASSIGN_PP            0x46
+#define IC_ASSIGN_MM            0x47
+
+#define IC_SHL_EQU              0x48
+#define IC_SHR_EQU              0x49
+#define IC_MUL_EQU              0x4A
+#define IC_DIV_EQU              0x4B
+#define IC_MOD_EQU              0x4C
+#define IC_AND_EQU              0x4D
+#define IC_OR_EQU               0x4E
+#define IC_XOR_EQU              0x4F
+#define IC_ADD_EQU              0x50
+#define IC_SUB_EQU              0x51
+
+#define IC_JMP                  0x52
+#define IC_SWITCH               0x53
+#define IC_NOBOUND_SWITCH       0x54
+
+#define IC_ADD_RSP              0x55
+#define IC_ADD_RSP1             0xC1
+#define IC_ENTER                0x56
+#define IC_PUSH_REGS            0x57
+#define IC_POP_REGS             0x58
+#define IC_LEAVE                0x59
+#define IC_RET                  0x5A
+
+#define IC_CALL                 0x5B
+#define IC_CALL_INDIRECT        0x5C
+#define IC_CALL_INDIRECT2       0x5D
+#define IC_CALL_IMPORT          0x5E
+#define IC_CALL_EXTERN          0x5F
+#define IC_IRQ                  0x60
+
+#define IC_ASM                  0x61
+#define IC_CLI                  0x62
+#define IC_STI                  0x63
+#define IC_CLD                  0x65
+#define IC_STD                  0x66
+#define IC_HLT                  0x67
+#define IC_PUSHFD               0x68
+#define IC_POPFD                0x69
+#define IC_PAUSE                0x6A
+
+#define IC_CLFLUSH              0x6B
+#define IC_INVLPG               0x6C
+#define IC_WBINVD               0x6F
+#define IC_INVD                 0x70
+
+#define IC_IN_U8                0x71
+#define IC_IN_U16               0x72
+#define IC_IN_U32               0x73
+#define IC_OUT_U8               0x74
+#define IC_OUT_U16              0x75
+#define IC_OUT_U32              0x76
+
+#define IC_GET_RFLAGS           0x77
+#define IC_SET_RFLAGS           0x78
+#define IC_GET_RAX              0x79
+#define IC_SET_RAX              0x7A
+#define IC_GET_RBP              0x7B
+#define IC_SET_RBP              0x7C
+#define IC_GET_RSP              0x7D
+#define IC_SET_RSP              0x7E
+#define IC_RIP                  0x7F
+
+#define IC_RDTSC                0x80
+
+#define IC_BT                   0x82
+#define IC_BTS                  0x83
+#define IC_BTR                  0x84
+#define IC_BTC                  0x85
+#define IC_BEQU                 0x86
+#define IC_LBTS                 0x87
+#define IC_LBTR                 0x88
+#define IC_LBTC                 0x89
+#define IC_LBEQU                0x8A
+#define IC_BSF                  0x8B
+#define IC_BSR                  0x8C
+
+#define IC_QUE_INS              0x8D
+#define IC_QUE_INS_REV          0x8E
+#define IC_QUE_REM              0x8F
+
+#define IC_STRLEN               0x90
+#define IC_MEMCPY               0x91
+
+#define IC_MEMSET               0x92
+#define IC_MEMSET_U16           0xC2
+#define IC_MEMSET_U32           0xC3
+#define IC_MEMSET_I64           0xC4
+
+#define IC_BR_ZERO              0x93
+#define IC_BR_NOT_ZERO          0x94
+
+#define IC_BR_NOT_EQU           0x95
+#define IC_BR_EQU_EQU           0x96
+#define IC_BR_GREATER_EQU       0x97
+#define IC_BR_LESS_EQU          0x98
+#define IC_BR_GREATER           0x99
+#define IC_BR_LESS              0x9A
+#define IC_BR_NOT_EQU2          0x9B
+#define IC_BR_EQU_EQU2          0x9C
+#define IC_BR_GREATER_EQU2      0x9D
+#define IC_BR_LESS_EQU2         0x9E
+#define IC_BR_GREATER2          0x9F
+#define IC_BR_LESS2             0xA0
+#define IC_BR_AND_ZERO          0xA1
+#define IC_BR_AND_NOT_ZERO      0xA2
+#define IC_BR_AND_AND_ZERO      0xA3
+#define IC_BR_AND_AND_NOT_ZERO  0xA4
+#define IC_BR_OR_OR_ZERO        0xA5
+#define IC_BR_OR_OR_NOT_ZERO    0xA6
+
+#define IC_BR_BT                0xA7
+#define IC_BR_BTS               0xA8
+#define IC_BR_BTR               0xA9
+#define IC_BR_BTC               0xAA
+#define IC_BR_LBTS              0xAB
+#define IC_BR_LBTR              0xAC
+#define IC_BR_LBTC              0xAD
+#define IC_BR_NOT_BT            0xAE
+#define IC_BR_NOT_BTS           0xAF
+#define IC_BR_NOT_BTR           0xB0
+#define IC_BR_NOT_BTC           0xB1
+#define IC_BR_NOT_LBTS          0xB2
+#define IC_BR_NOT_LBTR          0xB3
+#define IC_BR_NOT_LBTC          0xB4
+
+#define IC_SWAP_U8              0xB5
+#define IC_SWAP_U16             0xB6
+#define IC_SWAP_U32             0xB7
+#define IC_SWAP_I64             0xB8
+
+#define IC_ABS_I64              0xB9
+#define IC_SIGN_I64             0xBA
+#define IC_MIN_I64              0xBB
+#define IC_MIN_U64              0xBC
+#define IC_MAX_I64              0xBD
+#define IC_MAX_U64              0xBE
+#define IC_LIMIT_I64            0xBF
+#define IC_LIMIT_U64            0xC0
+
+#define IC_ICS_NUM              0xC5
+
+ diff --git a/public/Wb/Home/Src/Demo/InFile/InPopUp.HC.HTML b/public/Wb/Home/Src/Demo/InFile/InPopUp.HC.HTML new file mode 100755 index 0000000..7ba36c5 --- /dev/null +++ b/public/Wb/Home/Src/Demo/InFile/InPopUp.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+/* This is not an InFile.  It uses InStr
+to run text as though from an InFile.
+
+This example shows how you can drive pop-up
+windows.
+*/
+
+In(" ");
+"PopUp #1:%X\n",PopUpNoYes;
+
+InStr("Msg(MSG_KEY_DOWN,0,SC_CURSOR_RIGHT);'' CH_SPACE;");
+"PopUp #2:%X\n",PopUpNoYes;
+
+ diff --git a/public/Wb/Home/Src/Demo/InFile/InSetIP.HC.HTML b/public/Wb/Home/Src/Demo/InFile/InSetIP.HC.HTML new file mode 100755 index 0000000..cafcfde --- /dev/null +++ b/public/Wb/Home/Src/Demo/InFile/InSetIP.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+U0 InSetMsDemo()
+{
+  I64 t,l;
+  WinBorder(ON);
+  l=Fs->pix_left+Fs->scroll_x;
+  t=Fs->pix_top+Fs->scroll_y;
+  MsSet(,,,FALSE,FALSE); //Mouse unclicked
+  InSetMs(,l-4,t-4);
+  InSetMs(20,l+20,t+20,,TRUE);
+  MsSet(,,,FALSE,FALSE);
+}
+
+InSetMsDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/KeyBitMap.HC.HTML b/public/Wb/Home/Src/Demo/KeyBitMap.HC.HTML new file mode 100755 index 0000000..60df410 --- /dev/null +++ b/public/Wb/Home/Src/Demo/KeyBitMap.HC.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+
+<1>/* Graphics Not Rendered in HTML */
+
+
+
+
+I64 x=0;
+
+U0 DrawIt(CTask *,CDC *dc)
+{
+  Sprite3(dc,x%100,100,0,<1>);
+}
+
+U0 KeyDownBitMapDemo()
+{
+//This conversion routine is slow.
+  I64 i_sc=Char2ScanCode('i');
+
+  "Press and hold $GREEN$'i'$FG$.\n";
+  while (!Bt(kbd.down_bitmap,i_sc))
+    Yield;
+
+  SettingsPush; //See SettingsPush
+  Fs->draw_it=&DrawIt;
+
+  //kbd.down_bitmap is indexed with the
+  //merged scan code.  (left shift and
+  //right shift combined for example.)
+  //kbd.down_bitmap2 is indexed with the
+  //distinct scan code.  See Char and Scan Codes.
+
+  while (Bt(kbd.down_bitmap,i_sc)) {
+    x++;
+    Sleep(10);
+  }
+  SettingsPop;
+  FlushMsgs;
+}
+
+KeyDownBitMapDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/LastClass.HC.HTML b/public/Wb/Home/Src/Demo/LastClass.HC.HTML new file mode 100755 index 0000000..52f2525 --- /dev/null +++ b/public/Wb/Home/Src/Demo/LastClass.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+U0 StructName(U8 *d,U8 *class_name=lastclass)
+{//lastclass is the prev fun arg's class as a string.
+  "%X is a \"%s\".\n",d,class_name;
+}
+
+class Student
+{
+  Student *next;
+  I64 age;
+  U8 name[32];
+} a;
+
+class School
+{
+  U8 name[32];
+  Student *students;
+} s;
+
+I64 i;
+
+StructName(Fs);
+StructName(&a);
+StructName(&s);
+StructName(&i);
+PressAKey;
+
+//lastclass is used in ClassRep() and ClassRepD().
+ClassRepD(Gs);
+PressAKey;
+
+ClassRep(Fs);
+
+//See also DocForm(), ::/Demo/Dsk/BlkDevRep.HC and ::/Demo/ClassMeta.HC.
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/64BitAsmQuiz.DD.HTML b/public/Wb/Home/Src/Demo/Lectures/64BitAsmQuiz.DD.HTML new file mode 100755 index 0000000..610db10 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/64BitAsmQuiz.DD.HTML @@ -0,0 +1,137 @@ + + + + + + + + + + + +
+                              64-Bit Assembly Quiz
+
+1) In 64-bit mode, how many bytes are always pushed?
+
+        PUSH    12
+        PUSH    EAX
+
+2) What happens to the upper 32-bits?
+
+        XOR     EAX,EAX
+        MOV     EAX,0x12345678
+        MOV     EAX,0x80000000
+
+3) How do you set FS or GS values?
+
+4) If FS points to current task record, what's wrong with this instruction?
+
+        MOV     RAX,U64 FS:[TSS_SOME_MEMBER]
+
+5) Which instruction takes more bytes?
+
+        MOV     RAX,U64 [R8]
+        MOV     RAX,U64 [R13]
+
+6) Are these the same number of bytes?
+
+        MOV     RAX,1234
+        MOV     R8,1234
+        MOV     EAX,1234
+
+7) True or False
+
+  a) You can access the lowest byte of RAX.
+
+  b) You can access the lowest byte of ESI.
+
+  c) You can access the second-to-lowest byte of RAX.
+
+  d) You can access the second-to-lowest byte of ESI.
+
+8) How do you call a subroutine at 0x10,0000,0000 from code at 0x00,0010,0000?
+
+9) How much faster is a REL32 call instruction compared to a software interrupt 
+or SYSCALL?
+
+10) How long does an IN or OUT instruction take on a 1GHz machine and on a 3GHz 
+machine?
+
+11) How do you push all 16 regs?
+
+12) Should you put the regs in a TSS?
+
+13) You can have 4K or 4Meg pages in 32-bit mode.  You can have 4K or what size 
+pages in 64-bit mode?
+
+14) On a fresh CPU with an empty TLB, how many memory accesses (page tables) 
+does it take to access one virtual address?
+
+----
+
+TempleOS identity-maps everything, all the time, so the usual convention of 
+upper memory being for kernel does not apply.  It uses physical addresses, 
+basically.  It puts all code in the lowest 2-Gig memory range so that it can use 
+the CALL REL32 instruction, the fastest.  It never changes privilege levels or 
+messes with page tables, once it is up-and-running.
+
+----
+
+ANSWERS:
+
+1) All stack pushes and pops are 64-bits.
+
+2) The upper 32-bits are set to zero.
+
+3) To set FS or GS, you use WRMSR to write a model specific reg.  See 
+IA32_FS_BASE and SET_FS_BASE.
+
+4) Displacement addressing is now RIP relative, so RIP would be added to 
+TSS_SOME_MEMBER.  (Useless)
+
+5) The R13 instruction takes one more byte because it is like REG_RBP in the 
+ModR.
+
+6) The R8 instruction needs a REX byte prefix to specify upper-8 reg.
+
+7) You can access the lowest byte of any reg.  You can access AH but not the 
+second-to-lowest byte of ESI.
+
+8) To call a subroutine farther than 2Gig away, you put the address into RAX, 
+then CALL RAX.
+
+9) CALL REL32 is significantly faster.  See ::/Demo/Lectures/InterruptDemo.HC.
+
+10) IN or OUT instructions happen at a fixed speed based on the original ISA bus 
+clock.
+
+11) PUSHAD is not available for 64-bit mode, so you do it by hand.
+
+12) The TSS is no longer used to hold the task state because there are 16 regs 
+and they are 64-bits, not 32-bits.  I guess Intel decided doing it by hand was 
+better than TSSes.
+
+13) 64-bit mode has 4K or 2Meg page size.
+
+14) For one access, there are 3-4 levels of page tables plus the location 
+itself.
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/AndNotMod.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/AndNotMod.HC.HTML new file mode 100755 index 0000000..6b12051 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/AndNotMod.HC.HTML @@ -0,0 +1,75 @@ + + + + + + + + + + + +
+//You may wonder why I use "&" instead of "%".
+
+#define SAMPLE_SIZE     100000000
+
+U0 TimeIns()
+{
+  I64 start1,end1,start2,end2,overhead_time,test_time;
+  I64 reg i,reg tmp;
+
+  CPURep;
+
+  //Measure Loop Overhead
+  start1=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++) {
+  }
+  end1=GetTSC;
+  overhead_time=end1-start1;
+
+  //Measure remainder...
+  start2=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    tmp=i%0x400;
+  end2=GetTSC;
+  test_time=end2-start2;
+  "Remainder Version #1 Cycles\t: %10.5f\n",
+        ToF64(test_time-overhead_time)/SAMPLE_SIZE;
+
+  //Measure remainder...
+  start2=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    tmp=i&0x3FF;
+  end2=GetTSC;
+  test_time=end2-start2;
+  "Remainder Version #2 Cycles\t: %10.5f\n",
+        ToF64(test_time-overhead_time)/SAMPLE_SIZE;
+}
+
+TimeIns;
+
+/*  Program Output
+8 Cores 2.660GHz
+Remainder Version #1 Cycles     :   26.85345
+Remainder Version #2 Cycles     :   -0.00800
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/FixedPoint.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/FixedPoint.HC.HTML new file mode 100755 index 0000000..37929c2 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/FixedPoint.HC.HTML @@ -0,0 +1,127 @@ + + + + + + + + + + + +
+/*"Fixed point" means you use ints
+that are scaled by a value.  A common
+example would be using number of pennies
+instead of dollars with a float.
+
+Fixed-point used to be much faster,
+but modern processors do well with
+floats.  It also depends on the compiler
+and my compiler is poor with floats.
+
+I often use 64-bit ints with upper 32-bits
+as int and lower 32-bits as fraction.
+
+See ::/Demo/SubIntAccess.HC for how
+to access upper or lower 32-bits.
+
+For a complete lst of nonstandard compiler
+features, see ::/Doc/HolyC.DD.
+*/
+
+U0 Main()
+{
+  F64 t0,f_sum=0,f_val;
+  I64 i ,i_sum=0,i_val;
+
+  i_val= 2.0000002 *0x100000000;
+  t0=tS;
+  for (i=1000000000;i;i--)
+    i_sum+=i_val;
+  "Int Sum\t\t:%.9f Time:%7.3fs\n",i_sum/ToF64(0x100000000),tS-t0;
+
+  f_val= 2.0000002;
+  t0=tS;
+  for (i=1000000000;i;i--)
+    f_sum+=f_val;
+  "Float Sum\t:%.9f Time:%7.3fs\n",f_sum,tS-t0;
+  '\n';
+}
+
+U0 DoIt2()
+{
+  I64 i=0x123456789ABCDEF0;
+  "i\t\t=%X\n",i;
+
+  "i&0xFFFFFFFF\t=%X\n",i&0xFFFFFFFF;
+  "i>>32\t\t=%X\n",i>>32;
+
+  /*  Standard int types are declared
+with a special compiler feature which
+allows a structure to be accessed as a
+whole.  That's why the i variable can
+be accessed normally in addition to
+structure member access I64.  The actual
+intrinsic compiler type is U64i.
+
+public U64i union I64
+{
+  I8i i8[8];
+  U8i u8[8];
+  I16 i16[4];
+  U16 u16[4];
+  I32 i32[2];
+  U32 u32[2];
+};
+
+It's not quite as great as it seems
+because the compiler decides it cannot
+place i into a reg, so there is a
+penalty.
+
+For a complete lst of nonstandard compiler
+features, see ::/Doc/HolyC.DD.
+*/
+
+  "i.u32[0]\t=%X\n",i.u32[0];
+  "i.u32[1]\t=%X\n",i.u32[1];
+}
+
+CPURep;
+Main;
+DoIt2;
+
+//See ::/Demo/Lectures/FixedPointAdvanced.HC
+
+/*Program Output
+
+16 Cores 3.500GHz
+Int Sum         :2000000199.768690240 Time:  0.803s
+Float Sum       :2000000225.656127040 Time:  3.615s
+
+i               =123456789ABCDEF0
+i&0xFFFFFFFF    =9ABCDEF0
+i>>32           =12345678
+i.u32[0]        =9ABCDEF0
+i.u32[1]        =12345678
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/FixedPointAdvanced.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/FixedPointAdvanced.HC.HTML new file mode 100755 index 0000000..e50ccc0 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/FixedPointAdvanced.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+/*"Fixed point" means you use ints
+that are scaled by a value.  A common
+example would be using number of pennies
+instead of dollars with a float.
+
+Fixed-point used to be much faster,
+but modern processors do well with
+floats.  It also depends on the compiler
+and my compiler is poor with floats.
+
+I often use 64-bit ints with upper 32-bits
+as int and lower 32-bits as fraction.
+
+See ::/Demo/SubIntAccess.HC for how
+to access upper or lower 32-bits.
+*/
+
+#define SAMPLE_SIZE     10000000
+
+I32 coordinates[65536];
+
+asm {
+_ASM_FIXED_POINT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,coordinates
+        MOV     RDI,ToI64(Sin(1.0)*0x100000000)
+        XOR     RBX,RBX //SUM
+        MOV     RCX,SAMPLE_SIZE-1
+@@05:   XOR     RDX,RDX
+        MOV     DX,CX
+        MOVSXD  RAX,U32 [RSI+RDX*4]
+        IMUL    RDI
+        SAR     RAX,32
+        ADD     RBX,RAX
+        DEC     RCX
+        JGE     @@05
+        MOV     RAX,RBX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+SINE_VAL:       DU64    Sin(1.0);
+RET_VAL:        DU64    0;
+
+_ASM_FLOAT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,coordinates
+        FLD     U64 [SINE_VAL]
+        FLDZ
+        MOV     RCX,SAMPLE_SIZE-1
+@@05:   XOR     RDX,RDX
+        MOV     DX,CX
+        FILD    U32 [RSI+RDX*4]
+        FMUL    ST0,ST2
+        FADDP   ST1,ST0
+        DEC     RCX
+        JGE     @@05
+        FISTP   U64 [RET_VAL]
+        MOV     RAX,U64 [RET_VAL]
+        FFREE   ST0
+        FINCSTP
+        POP     RSI
+        POP     RBP
+        RET
+}
+
+_extern _ASM_FIXED_POINT I64 AsmFixedPt();
+_extern _ASM_FLOAT I64 AsmFloat();
+
+U0 Main()
+{
+  I64 start,end,overhead_time,test_time;
+  F64 d1,fsum;
+  I64 reg i,tmp,reg d2,reg sum;
+
+  CPURep;
+
+  //Set-up some sample coordinates
+  for (i=0;i<65536;i++)
+    coordinates[i]=RandU32;
+
+    //Measure Loop Overhead
+  start=GetTSC;
+  for (i=SAMPLE_SIZE-1;i>=0;i--) {
+  }
+  end=GetTSC;
+  overhead_time=end-start;
+  "$RED$Overhead Cycles       :%10.5f$FG$\n",
+        ToF64(overhead_time)/SAMPLE_SIZE;
+
+  //Measure F64 arithmetic
+  // (Some of this is due to crappy
+  // compiler code.)
+  d1=Sin(1.0);
+  fsum=0;
+  start=GetTSC;
+  for (i=SAMPLE_SIZE-1;i>=0;i--)
+    fsum+=d1*coordinates[i&65535];
+  end=GetTSC;
+  test_time=end-start;
+  "Float Sum             :%X\n",ToI64(fsum);
+  "$RED$Float Cycles          :%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+  //Measure fixed point arithmetic
+  d2=Sin(1.0)*0x100000000;
+  sum=0;
+  start=GetTSC;
+  for (i=SAMPLE_SIZE-1;i>=0;i--) {
+    tmp=d2*coordinates[i&65535];
+    sum+=tmp.i32[1];
+  }
+  end=GetTSC;
+  test_time=end-start;
+  "Fixed-Point Sum       :%X\n",sum;
+  "$RED$Fixed-Point Cycles    :%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+  //Measure fixed point arithmetic
+  start=GetTSC;
+  sum=AsmFixedPt;
+  end=GetTSC;
+  test_time=end-start;
+  "Asm Fixed-Point Sum   :%X\n",sum;
+  "$RED$Asm Fixed-Point Cycles:%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+  //Measure float arithmetic
+  start=GetTSC;
+  sum=AsmFloat;
+  end=GetTSC;
+  test_time=end-start;
+  "Asm Float Sum         :%X\n",sum;
+  "$RED$Asm Float Cycles      :%10.5f$FG$\n",
+        ToF64(test_time)/SAMPLE_SIZE;
+
+}
+
+Main;
+
+/*  Program Output
+
+Machine 1:
+8 Cores 2.660GHz
+Overhead Cycles       :   2.00814
+Float Sum             :FFFFE1D361BEED68
+Float Cycles          :  10.16076
+Fixed-Point Sum       :FFFFE1D361729914
+Fixed-Point Cycles    :   5.29392
+Asm Fixed-Point Sum   :FFFFE1D361729914
+Asm Fixed-Point Cycles:   4.20464
+Asm Float Sum         :FFFFE1D361BEED56
+Asm Float Cycles      :   3.04635
+
+Machine 2:
+8 Cores 3.395GHz
+Overhead Cycles       :   4.87040
+Float Sum             :D20A01DB177
+Float Cycles          :  10.11558
+Fixed-Point Sum       :D209FD18CC7
+Fixed-Point Cycles    :   4.50618
+Asm Fixed-Point Sum   :D209FD18CC7
+Asm Fixed-Point Cycles:   3.02426
+Asm Float Sum         :D20A01DB17B
+Asm Float Cycles      :   3.21070
+
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/GraphicsCPULoad.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/GraphicsCPULoad.HC.HTML new file mode 100755 index 0000000..6d4d2ab --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/GraphicsCPULoad.HC.HTML @@ -0,0 +1,65 @@ + + + + + + + + + + + +
+//This is the fastest you can update the whole scrn.
+//See ::/Demo/Lectures/MiniGrLib.HC if this interests you.
+
+F64 VGAPattern(I64 p)
+{//This returns the time to update in seconds.
+  F64 start=tS;
+  I64 plane;
+  for (plane=1;plane<0x10;plane<<=1) {
+    OutU8(VGAP_IDX,VGAR_MAP_MASK);
+    OutU8(VGAP_DATA,plane);
+    MemSetI64(text.vga_alias,p,640*480/64);
+  }
+  return tS-start;
+}
+ 
+ 
+U0 GrDemo()
+{
+  I64 i;
+  F64 t;
+  CPURep;
+  for (i=0;i<16;i++) {
+    t=VGAPattern(0x5555555555555555);
+    "$GREEN$Rate:$RED$%5.1f FPS$FG$"
+          "  $GREEN$Load@30Hz:$RED$%5.1f%%$FG$\n",1/t,100*t*30.0;
+    t=VGAPattern(0x3333333333333333);
+    "$GREEN$Rate:$RED$%5.1f FPS$FG$"
+          "  $GREEN$Load@30Hz:$RED$%5.1f%%$FG$\n",1/t,100*t*30.0;
+  }
+//<CTRL-ALT-v> will flush scrn VGA cache.
+  VGAFlush;
+}
+
+GrDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/InterruptDemo.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/InterruptDemo.HC.HTML new file mode 100755 index 0000000..bcffaf6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/InterruptDemo.HC.HTML @@ -0,0 +1,116 @@ + + + + + + + + + + + +
+//This is the software interrupt num
+//we will use.  See Software Int's for
+//picking a num.  Nums are subject to change.
+
+#define I_F_UNARY_MINUS I_USER
+
+asm {
+
+//This changes the sign of the floating
+//point val in RAX
+F_UNARY_MINUS_INT::
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCHS
+        FSTP    U64 [RSP]
+        POP     RAX
+        IRET
+
+//This does the same thing, but not as
+//an interrupt.
+F_UNARY_MINUS_CALL::
+        PUSH    RAX
+        FLD     U64 [RSP]
+        FCHS
+        FSTP    U64 [RSP]
+        POP     RAX
+        RET
+
+//This invokes the interrupt version
+//with a C callable function.
+_F_UM_INT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,SF_ARG1[RBP]
+        INT     I_F_UNARY_MINUS
+        POP     RBP
+        RET1    8
+
+//This invokes the call version
+//with a C callable function.
+_F_UM_CALL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,SF_ARG1[RBP]
+        CALL    F_UNARY_MINUS_CALL
+        POP     RBP
+        RET1    8
+}
+
+_extern _F_UM_INT F64 UnaryMinusInt(F64 d);
+_extern _F_UM_CALL F64 UnaryMinusCall(F64 d);
+
+#define SAMPLE_SIZE     1000000
+U0 TimeIns()
+{
+  I64 start,end;
+  I64 i,old_irq;
+
+  CPURep;
+  old_irq=IntEntrySet(I_F_UNARY_MINUS,F_UNARY_MINUS_INT,IDTET_TRAP);
+
+  //Measure interrupt time
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    UnaryMinusInt(pi);
+  end=GetTSC;
+  "Interrupt Cycles: %10.5f\n",ToF64(end-start)/SAMPLE_SIZE;
+
+  //Measure call time
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    UnaryMinusCall(pi);
+  end=GetTSC;
+  "Call      Cycles: %10.5f\n",ToF64(end-start)/SAMPLE_SIZE;
+
+  IntEntrySet(I_F_UNARY_MINUS,old_irq,IDTET_IRQ);
+}
+
+TimeIns;
+
+/*  Program Output
+6 Cores 3.395GHz
+Interrupt Cycles:  573.98543
+Call      Cycles:    9.74349
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/MiniCompiler.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/MiniCompiler.HC.HTML new file mode 100755 index 0000000..cbfb5ce --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/MiniCompiler.HC.HTML @@ -0,0 +1,277 @@ + + + + + + + + + + + +
+/*
+-] Main Compiler
+  The mini compiler is like the main compiler, except the main compiler's 
+  lexical analyser removes comments and does preprocessing.  Lex(),Echo(ON).
+  
+  The main compiler generates Intermediate Code at the parser stage.  See 
+  PrsExpression(), PrsStmt().
+  
+  The main compiler optimizes   See Intermediate Code Attributes, 
+  Combining Consts, Choosing Reg Vars.  Use PassTrace() to see the optimization 
+  stages.
+  
+  The main compiler makes machine code in the back end.  See IC Struct, 
+  COCCompile and OptPass789A(), BackEnd.  Set Trace(ON) to see the output of the 
+  backend.
+
+-] Mini Compiler
+  For this mini compiler, some things you should know about 64-bit asm:
+  
+  * Putting a 0x48, known as the REX byte, in front of an inst makes it 64-bit 
+  size.
+  
+  * "PUSH EAX", "POP EAX" and "XOR EAX,EAX" will behave as 64-bit even without 
+  REX because the stk is always 64 bit and because the XOR clears the upper 
+  32-bits.
+  
+  It is okay in TempleOS to change RAX, RBX, RCX, RDX, R8 and R9 without 
+  restoring them to their original values.
+*/
+
+#define TK_EOF          0
+#define TK_NUM          1
+#define TK_OP           2
+#define TK_LEFT         3
+#define TK_RIGHT        4
+
+#define OP_MUL          1
+#define OP_DIV          2
+#define OP_ADD          3
+#define OP_SUB          4
+
+I64 Lex(U8 **_src,I64 *num)
+{//See Lex().
+  U8 *src=*_src;
+  I64 i;
+  while (TRUE) {
+    switch (*src) {
+      case 0:
+      case ';':
+        *_src=src;
+        return TK_EOF;
+      case CH_SPACE:
+      case '\r':
+      case '\n':
+        src++;
+        break;
+      case '0'...'9':
+        i=0;
+        do {
+          i=i*10+*src-'0';
+          src++;
+        } while ('0'<=*src<='9');
+        *num=i;
+        *_src=src;
+        return TK_NUM;
+      case '*':
+        *num=OP_MUL;
+        *_src=src+1;
+        return TK_OP;
+      case '/':
+        *num=OP_DIV;
+        *_src=src+1;
+        return TK_OP;
+      case '+':
+        *num=OP_ADD;
+        *_src=src+1;
+        return TK_OP;
+      case '-':
+        *num=OP_SUB;
+        *_src=src+1;
+        return TK_OP;
+      case '(':
+        *_src=src+1;
+        return TK_LEFT;
+      case ')':
+        *_src=src+1;
+        return TK_RIGHT;
+      default:
+        throw;
+    }
+  }
+}
+
+#define PREC_EOF        0
+#define PREC_TERM       1
+#define PREC_MUL        2
+#define PREC_ADD        3
+#define PREC_PAREN      4
+
+extern I64 Parse(U8 **_src,U8 **_dst);
+
+U0 PrsTerm(U8 **_src,U8 **_dst,I64 prec)
+{//See PrsExpression().
+  I64 i;
+  U8 *src2;
+  U8 *dst2;
+  if (Parse(_src,_dst)==PREC_TERM) {
+    src2=*_src;
+    dst2=*_dst;
+    while (TRUE) {
+//This is inefficient.  The main compiler doesn't back-up like this.
+      i=Parse(&src2,&dst2);
+      if (PREC_MUL<=i<prec) {
+        *_src=src2;
+        *_dst=dst2;
+      } else
+        break;
+    }
+  } else
+    throw;
+}
+
+I64 Parse(U8 **_src,U8 **_dst)
+{//See PrsExpression().
+//See Opcode Fmts for details on asm insts.
+  I64 i;
+  U8 *dst=*_dst;
+  switch (Lex(_src,&i)) {
+    case TK_EOF:
+      *dst++=0x58; //POP RAX
+      *dst++=0xC3; //RET
+      *_dst=dst;
+      return PREC_EOF;
+    case TK_NUM:
+      *dst++=0x48; //REX
+      *dst++=0xB8; //MOV RAX,immediate num
+      *dst(I64 *)++=i;
+
+      *dst++=0x50; //PUSH RAX
+      *_dst=dst;
+      return PREC_TERM;
+    case TK_LEFT:
+      PrsTerm(_src,_dst,PREC_PAREN);
+      if (Parse(_src,_dst)!=PREC_PAREN)
+        throw;
+      return PREC_TERM;
+    case TK_RIGHT:
+      return PREC_PAREN;
+    case TK_OP:
+      switch (i) {
+        case OP_MUL:
+          PrsTerm(_src,&dst,PREC_MUL);
+          *dst++=0x5A; //POP RDX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x48; //REX
+          *dst++=0x0F;
+          *dst++=0xAF; //IMUL RAX,RDX
+          *dst++=0xC2;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_MUL;
+        case OP_DIV:
+          PrsTerm(_src,&dst,PREC_MUL);
+          *dst++=0x5B; //POP RBX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x33; //XOR RDX,RDX
+          *dst++=0xD2;
+
+          *dst++=0x48; //REX
+          *dst++=0xF7; //IDIV RBX
+          *dst++=0xFB;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_MUL;
+        case OP_ADD:
+          PrsTerm(_src,&dst,PREC_ADD);
+          *dst++=0x5A; //POP RDX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x48; //REX
+          *dst++=0x03; //ADD RAX,RDX
+          *dst++=0xC2;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_ADD;
+        case OP_SUB:
+          PrsTerm(_src,&dst,PREC_ADD);
+          *dst++=0x5A; //POP RDX
+          *dst++=0x58; //POP RAX
+
+          *dst++=0x48; //REX
+          *dst++=0x2B; //SUB RAX,RDX
+          *dst++=0xC2;
+
+          *dst++=0x50; //PUSH RAX
+          *_dst=dst;
+          return PREC_ADD;
+      }
+  }
+}
+
+U0 Main()
+{
+  U8 *src,*src2,*code,*dst;
+
+  //Fixed size, no buffer overrun check.
+  //You can make it fancier if you like.
+  code=MAlloc(512,Fs->code_heap);
+
+  while (TRUE) {
+    "This will compile an expression\n"
+          "consisting of ints, parentheses\n"
+          "and the operators +,-,* and /.\n";
+    src=GetStr;
+    if (*src) {
+      src2=src;
+      dst=code;
+      try {
+        PrsTerm(&src2,&dst,PREC_PAREN);
+        if (Parse(&src2,&dst)!=PREC_EOF)
+          throw;
+        "$RED$This code is not efficient, but the compiler is simple.$FG$\n";
+        Un(code,dst-code); //Unassemble the code we created.
+//Call() is a function.  See _CALL::
+        //See also CallInd().  See _CALL_IND::
+        "$LTBLUE$Answer:%d$FG$\n",Call(code);
+      } catch {
+        "$RED$Error$FG$\n";
+        PutExcept;
+      }
+      Free(src);
+    } else {
+      Free(src);
+      break;
+    }
+  }
+  Free(code);
+}
+
+Main;
+
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/MiniGrLib.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/MiniGrLib.HC.HTML new file mode 100755 index 0000000..d9ed957 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/MiniGrLib.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+//See ::/Demo/Lectures/GraphicsCPULoad.HC
+U8 rev[256],    //The VGA bits are bwd
+
+   image[640*480/8];    //We need read-modify write.
+                        //0xA0000 alias memory can't be read.
+ 
+U0 MGInit()
+{
+  I64 i,j;
+  MemSet(image,0,sizeof(image));
+  MemSet(rev,0,sizeof(rev));
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++)
+      if (Bt(&i,j))
+        Bts(&rev[i],7-j);
+}
+ 
+U0 MGUpdate()
+{//Copy image to VGA memory
+//For better performance we could only write what's changed.
+  //0xA0000 alias is slower than normal RAM.
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,0xF);//All color planes at once -- Black and White
+  MemCpy(text.vga_alias,image,sizeof(image)); //Alias of 0xA0000
+}
+ 
+U0 MGPlot(I64 x,I64 y)
+{
+  if (0<=x<640 && 0<=y<480)
+    Bts(image,y*640+x^7);
+}
+ 
+U0 MGHLine(I64 x1,I64 x2,I64 y)
+{//Warning!  No clipping
+//For performance, we do as many whole-bytes as possible.
+  U8 *ptr;
+  I64 i,w,leading,trailing,whole_bytes;
+  if (x2<x1) SwapI64(&x1,&x2);
+  ptr=image+y*640/8+x1>>3;
+  w=x2-x1+1;
+  leading =8-x1&7;
+  trailing=(x2+1)&7;
+  if (leading+trailing>w)
+    *ptr|=rev[(0xFF00>>leading&(0x00FF<<trailing)>>8)];
+  else {
+    whole_bytes=(w-leading-trailing)>>3;
+    if (leading)
+      *ptr++|=rev[(0xFF00>>leading)&0xFF];
+    for (i=0;i<whole_bytes;i++)
+      *ptr++=0xFF;
+    if (trailing)
+      *ptr++|=rev[(0x00FF<<trailing)>>8];
+  }
+}
+ 
+U0 MGLine(I64 x1,I64 y1,I64 x2,I64 y2)
+{//Warning!  No clipping
+  I64 dx=x2-x1,dy=y2-y1;
+  x1<<=32; x2<<=32;
+  y1<<=32; y2<<=32;
+  if (AbsI64(dx)>AbsI64(dy)) {
+    dy=dy<<32/AbsI64(dx);
+    dx=SignI64(dx)<<32;
+    while (x1!=x2) {
+      MGPlot(x1.i32[1],y1.i32[1]);
+      x1+=dx; y1+=dy;
+    }
+  } else {
+    dx=dx<<32/AbsI64(dy);
+    dy=SignI64(dy)<<32;
+    while (y1!=y2) {
+      MGPlot(x1.i32[1],y1.i32[1]);
+      x1+=dx; y1+=dy;
+    }
+  }
+  MGPlot(x1.i32[1],y1.i32[1]);
+}
+ 
+U0 MGCircle(I64 x,I64 y,F64 r)
+{
+  F64 s,c,x1,y1,x2,y2;
+  I64 len;
+  if (r<0) return;
+  x1=r; y1=0;
+  c=Cos(1/r);
+  s=Sin(1/r);
+  len=2*r*pi;
+  MGPlot(x+x1,y+y1);
+  while (len-->=0) {
+
+    //m1@a1 * m2@a2     = m1*m2@(arg1+arg2)
+
+    //(x1+y1i)*(x2+y2i) = x1*x2+(x1*y1+x2*y2)i-y1*y2
+
+    // meti=mCos(t)+imSin(t)
+
+    x2=x1; y2=y1;
+    x1=c*x2-s*y2;
+    y1=s*x2+c*y2;
+    MGPlot(x+x1,y+y1);
+  }
+}
+ 
+ 
+U0 MiniGrLibDemo()
+{
+  I64 i;
+  MGInit;
+
+  for (i=0;i<100;i++)
+    MGHLine(200+i,400+i,300+i);
+  for (i=0;i<500;i+=10)
+    MGLine(i,0,0,480-i);
+  for (i=0;i<300;i+=4)
+    MGCircle(200,100+i,i);
+  MGUpdate;
+  Busy(1500000);
+/*
+We are returning graphics to normal operations under TempleOS.
+It is not normal to by-pass the TempleOS graphcis routines.
+The TempleOS graphics don't know VGA has changed.
+This bit tells TempleOS to update whole scrn.
+*/
+  //<CTRL-ALT-v> will flush scrn VGA cache.
+  VGAFlush;
+}
+ 
+MiniGrLibDemo;
+
+//See RawPutChar() for text.
+//See ::/Demo/Lectures/ScrnMemory.HC for color.
+//See ::/Demo/Lectures/GraphicsCPULoad.HC.
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/NegDisp.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/NegDisp.HC.HTML new file mode 100755 index 0000000..8d101b6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/NegDisp.HC.HTML @@ -0,0 +1,87 @@ + + + + + + + + + + + +
+class Person
+{
+  U8 first    [32];
+  U8 last     [32];
+  U8 address1 [64];
+  U8 address2 [64];
+  U8 city     [32];
+  U8 state_zip[32];
+};
+
+U0 OffsetDemo1()
+{
+  Person *p=MAlloc(sizeof(Person));
+  StrCpy(p->first,    "Terry");
+  StrCpy(p->last,     "Davis");
+  StrCpy(p->address1, "8144 Sickle Lane");
+  StrCpy(p->address2, "");
+  StrCpy(p->city,     "Las Vegas");
+  StrCpy(p->state_zip,"NV 89128");
+}
+
+U(&OffsetDemo1,34);
+PressAKey;
+
+/*
+
+x86 has signed 8-bit  displacements
+    and signed 32-bit displacements.
+
+This example uses 8-bit negative displacements.
+
+*/
+
+class Person
+{ $=-128;
+U8 first    [32];
+U8 last     [32];
+U8 address1 [64];
+U8 address2 [64];
+U8 city     [32];
+U8 state_zip[32];
+};
+
+U0 OffsetDemo2()
+{
+  Person *p=MAlloc(sizeof(Person))(I64)+128;
+  StrCpy(p->first,    "Terry");
+  StrCpy(p->last,     "Davis");
+  StrCpy(p->address1, "8144 Sickle Lane");
+  StrCpy(p->address2, "");
+  StrCpy(p->city,     "Las Vegas");
+  StrCpy(p->state_zip,"NV 89128");
+}
+
+U(&OffsetDemo2,34);
+PressAKey;
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/Optimization.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/Optimization.HC.HTML new file mode 100755 index 0000000..8a6e793 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/Optimization.HC.HTML @@ -0,0 +1,139 @@ + + + + + + + + + + + +
+/*The moral of this story is simple
+inst level optimizations
+don't matter much on a modern Intel CPU
+because they convert complex insts
+to a stream of RISC insts.
+
+I learned this the hard way when I thought
+I was greatly improving my compiler by
+cutting code by a third.  No significant
+speed-up.  Depressing.
+*/
+
+#define SAMPLES (8*10000000+1)
+
+asm {
+
+LIMIT:: DU64    SAMPLES;        //Memory reference should be bad, right?
+
+_BADLY_UNOPTIMIZED::
+        MOV     RAX,0
+        MOV     RCX,1
+@@05:   MOV     RDX,RCX
+        INC     RCX             //if no dependencies, Free!
+        ADD     RAX,RDX
+        MOV     RDX,LIMIT-16    //added 16 displacement to make it worse
+        CMP     RCX,U64 16[RDX]
+        JB      @@05
+        RET
+
+_WELL_OPTIMIZED1::
+        XOR     RAX,RAX
+        MOV     RCX,SAMPLES-1
+@@05:   ADD     RAX,RCX
+        DEC     RCX
+        JNZ     @@05
+        RET
+
+_WELL_OPTIMIZED2:: //Unrolled
+        XOR     RAX,RAX
+        MOV     RCX,SAMPLES-1
+@@05:   ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        ADD     RAX,RCX
+        DEC     RCX
+        JNZ     @@05
+        RET
+
+_WELL_OPTIMIZED3::
+        XOR     RAX,RAX
+        MOV     RCX,SAMPLES-1
+@@05:   ADD     RAX,RCX
+        LOOP    @@05    //Inst has slow speed, but saves code size.
+        RET
+}
+
+_extern _BADLY_UNOPTIMIZED I64 Loop1();
+_extern _WELL_OPTIMIZED1   I64 Loop2();
+_extern _WELL_OPTIMIZED2   I64 Loop3();
+_extern _WELL_OPTIMIZED3   I64 Loop4();
+
+I64 i;
+F64 t0;
+
+CPURep;
+
+"Bad Code\n";
+t0=tS;
+i=Loop1;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+"Good Code #1\n";
+t0=tS;
+i=Loop2;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+"Good Code #2\n";
+t0=tS;
+i=Loop3;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+"Good Code #3\n";
+t0=tS;
+i=Loop4;
+"Res:%d Time:%9.6f\n",i,tS-t0;
+
+/*  Program Output
+8 Cores 2.660GHz
+Bad Code
+Res:3200000040000000 Time: 0.069966
+Good Code #1
+Res:3200000040000000 Time: 0.062567
+Good Code #2
+Res:3200000040000000 Time: 0.062907
+Good Code #3
+Res:3200000040000000 Time: 0.156359
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/PCIInterrupts.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/PCIInterrupts.HC.HTML new file mode 100755 index 0000000..35ba6cb --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/PCIInterrupts.HC.HTML @@ -0,0 +1,104 @@ + + + + + + + + + + + +
+//See PCI.
+
+#if mp_cnt>1
+#define DEST_CPU        1
+#else
+#define DEST_CPU        0
+#endif
+
+#assert I_USER==0x40
+
+interrupt U0 IntMy40()
+{
+  lock {progress1++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntMy41()
+{
+  lock {progress2++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntMy42()
+{
+  lock {progress3++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntMy43()
+{
+  lock {progress4++;}
+*(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+I64 vect[4]={&IntMy40,&IntMy41,&IntMy42,&IntMy43};
+
+U0 Main()
+{
+  I64 i;
+  U8 *da=dev.uncached_alias+IOAPIC_REG;
+  U32 *_d=dev.uncached_alias+IOAPIC_DATA;
+
+  ProgressBarsRst;
+  for (i=I_USER;i<I_USER+4;i++)
+    IntEntrySet(i,vect[i&3],IDTET_IRQ);
+
+    //There are like 4*6 vects.  Bus zero
+    //has the first four vects.
+  for (i=IOREDTAB;i<IOREDTAB+4*2;i+=2) {
+    *da=i+1;
+    *_d=dev.mp_apic_ids[DEST_CPU]<<24;
+    *da=i;
+    *_d=0x4000+0x40+(i-IOREDTAB)/2;
+  }
+
+  Sleep(1000);
+  "The keyboard and timer seem to be active.\n"
+        "IntA:%d IntB:%d IntC:%d IntD:%d\n\n"
+        "IntB is my keybaord and regs a single KEY-UP.\n"
+        "Rerun and press a few keys.\n",
+        progress1,progress2,progress3,progress4;
+
+  //Disable vects
+  for (i=IOREDTAB;i<IOREDTAB+4*2;i+=2) {
+    *da=i+1;
+    *_d=dev.mp_apic_ids[DEST_CPU]<<24;
+    *da=i;
+    *_d=0x14000+0x40+(i-IOREDTAB)/2;
+  }
+  ProgressBarsRst;
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/Ring3.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/Ring3.HC.HTML new file mode 100755 index 0000000..b3b811f --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/Ring3.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+/*TempleOS runs exclusively in ring 0.
+Ring 0 is part of the Charter.
+This demo is for you to play around
+with ring 3.  TempleOS is for
+recreational programming, after all.
+
+This redirects the general protection
+fault, switches to ring 3, and generates
+a fault to switch back.
+*/
+
+U8 *old_stk,*new_rip;
+
+asm {
+INT_TO_RING0::  //Set to handle general protection 0xD fault temporarily.
+        INC     U64 [SYS_PROGRESS1]
+        PUSH    U32 CGDT.ds     //STKSEG
+        MOV     RAX,U64 [&old_stk]
+        PUSH    RAX
+        PUSH    U32 0           //FLAGS--interrupts off
+        PUSH    U32 CGDT.cs64
+        MOV     RAX,U64 [&new_rip]
+        PUSH    RAX
+        IRET
+}
+
+U0 Ring3Demo()
+{
+  U8 *old_vect;
+  "Progress1 Before:%X\n",progress1;
+  CLI
+  old_vect=IntEntrySet(0x0D,INT_TO_RING0,IDTET_TRAP,0);
+
+  TSSBusy(Gs->tss->tr_ring3,OFF);
+  SetRAX(Gs->tss->tr_ring3+3);
+  LTR   AX
+
+  asm {
+    MOV U64 [&old_stk],RSP
+
+    LEA RAX,[R3_CALLBACK]
+    MOV U64 [&new_rip],RAX
+
+    MOV AX,CGDT.ds_ring3+3
+    MOV DS,AX
+    MOV ES,AX
+
+    PUSH        U32 CGDT.ds_ring3+3     //STKSEG
+    PUSH        U64 [&old_stk]
+    PUSH        U32 0           //FLAGS--interrupts off
+    PUSH        U32 CGDT.cs64_ring3+3
+    LEA RAX,[R3_START]
+    PUSH        RAX
+    IRET
+
+    R3_START:
+    INC U64 [SYS_PROGRESS1]
+    CLI //This causes general protection fault #13
+
+    R3_CALLBACK:
+    MOV AX,CGDT.ds
+    MOV DS,AX
+    MOV ES,AX
+  }
+
+  TSSBusy(Gs->tss->tr,OFF);
+  SetRAX(Gs->tss->tr);
+  LTR   AX
+
+  IntEntrySet(0x0D,old_vect,IDTET_IRQ,0);
+  STI
+  "Progress1 After :%X\n",progress1;
+}
+
+Ring3Demo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Lectures/ScrnMemory.HC.HTML b/public/Wb/Home/Src/Demo/Lectures/ScrnMemory.HC.HTML new file mode 100755 index 0000000..c30003a --- /dev/null +++ b/public/Wb/Home/Src/Demo/Lectures/ScrnMemory.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+//This just shows how scrn memory works.
+//See ::/Demo/Lectures/MiniGrLib.HC
+
+U0 PlotXY(I64 x,I64 y)
+{
+//Scrn bits are revd
+  LBts(text.vga_alias,y*GR_WIDTH+x^7);
+}
+
+U0 Main()
+{
+  I64 i;
+  //This makes all 4 color planes active.
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,WHITE);
+  MemSet(text.vga_alias,0,GR_WIDTH*GR_HEIGHT/8);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,RED);
+  for (i=0;i<200;i++)
+    PlotXY(i,i);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,GREEN);
+  for (i=0;i<200;i++)
+    PlotXY(100,i);
+
+  OutU8(VGAP_IDX,VGAR_MAP_MASK);
+  OutU8(VGAP_DATA,BLUE);
+  for (i=0;i<200;i++)
+    PlotXY(200-i,i);
+/*If you want a mixed color sel multiple planes
+but you have to be sure the unseled planes
+are zero, so sel them and make them zero.
+You can't do reads on VGA memory, by the way.
+That means no read-modify-writes, too.
+*/
+  Busy(4000000);
+
+  //TempleOS has a 4 plane memory duplicate of the scrn, gr.scrn_image,
+  //and only writes actual changes.  See GrUpdateVGAGraphics().
+  //<CTRL-ALT-v> will flush scrn VGA cache.
+  VGAFlush;
+}
+
+Main;
+
+//See ::/Demo/Lectures/GraphicsCPULoad.HC.
+
+
+ diff --git a/public/Wb/Home/Src/Demo/MagicPairs.HC.HTML b/public/Wb/Home/Src/Demo/MagicPairs.HC.HTML new file mode 100755 index 0000000..354459b --- /dev/null +++ b/public/Wb/Home/Src/Demo/MagicPairs.HC.HTML @@ -0,0 +1,406 @@ + + + + + + + + + + + +
+/*The magic pairs problem:
+
+Let SumFact(n) be the sum of factors
+of n.
+
+Find all n1,n2 in a range such that
+
+SumFact(n1)-n1-1==n2  and
+SumFact(n2)-n2-1==n1
+
+-----------------------------------------------------
+To find SumFact(k), start with prime factorization:
+
+k=(p1^n1)(p2^n2) ... (pN^nN)
+
+THEN,
+
+SumFact(k)=(1+p1+p1^2...p1^n1)*(1+p2+p2^2...p2^n2)*
+(1+pN+pN^2...pN^nN)
+
+PROOF:
+
+Do a couple examples -- it's obvious:
+
+48=2^4*3
+
+SumFact(48)=(1+2+4+8+16)*(1+3)=1+2+4+8+16+3+6+12+24+48
+
+75=3*5^2
+
+SumFact(75)=(1+3)*(1+5+25)    =1+5+25+3+15+75
+
+Corollary:
+
+SumFact(k)=SumFact(p1^n1)*SumFact(p2^n2)*...*SumFact(pN^nN)
+
+*/
+
+//Primes are needed to sqrt(N).  Therefore, we can use U32.
+class PowPrime
+{
+  I64 n;
+  I64 sumfact; //Sumfacts for powers of primes are needed beyond sqrt(N)
+};
+
+class Prime
+{
+  U32 prime,pow_cnt;
+  PowPrime *pp;
+};
+
+I64 *PrimesNew(I64 N,I64 *_sqrt_primes,I64 *_cbrt_primes)
+{
+  I64 i,j,sqrt=Ceil(Sqrt(N)),cbrt=Ceil(N`(1/3.0)),sqrt_sqrt=Ceil(Sqrt(sqrt)),
+        sqrt_primes=0,cbrt_primes=0;
+  U8 *s=CAlloc((sqrt+1+7)/8);
+  Prime *primes,*p;
+
+  for (i=2;i<=sqrt_sqrt;i++) {
+    if (!Bt(s,i)) {
+      j=i*2;
+      while (j<=sqrt) {
+        Bts(s,j);
+        j+=i;
+      }
+    }
+  }
+  for (i=2;i<=sqrt;i++)
+    if (!Bt(s,i)) {
+      sqrt_primes++; //Count primes
+      if (i<=cbrt)
+        cbrt_primes++;
+    }
+
+  p=primes=CAlloc(sqrt_primes*sizeof(Prime));
+  for (i=2;i<=sqrt;i++)
+    if (!Bt(s,i)) {
+      p->prime=i;
+      p++;
+    }
+  Free(s);
+
+  *_sqrt_primes=sqrt_primes;
+  *_cbrt_primes=cbrt_primes;
+  return primes;
+}
+
+PowPrime *PowPrimesNew(I64 N,I64 sqrt_primes,Prime *primes,I64 *_num_powprimes)
+{
+  I64 i,j,k,sf,num_powprimes=0;
+  Prime *p;
+  PowPrime *powprimes,*pp;
+
+  p=primes;
+  for (i=0;i<sqrt_primes;i++) {
+    num_powprimes+=Floor(Ln(N)/Ln(p->prime));
+    p++;
+  }
+
+  p=primes;
+  pp=powprimes=MAlloc(num_powprimes*sizeof(PowPrime));
+  for (i=0;i<sqrt_primes;i++) {
+    p->pp=pp;
+    j=p->prime;
+    k=1;
+    sf=1;
+    while (j<N) {
+      sf+=j;
+      pp->n=j;
+      pp->sumfact=sf;
+      j*=p->prime;
+      pp++;
+      p->pow_cnt++;
+    }
+    p++;
+  }
+  *_num_powprimes=num_powprimes;
+  return powprimes;
+}
+
+I64 SumFact(I64 n,I64 sqrt_primes,Prime *p)
+{
+  I64 i,k,sf=1;
+  PowPrime *pp;
+  if (n<2)
+    return 1;
+  for (i=0;i<sqrt_primes;i++) {
+    k=0;
+    while (!(n%p->prime)) {
+      n/=p->prime;
+      k++;
+    }
+    if (k) {
+      pp=p->pp+(k-1);
+      sf*=pp->sumfact;
+      if (n==1)
+        return sf;
+    }
+    p++;
+  }
+  return sf*(1+n); //Prime
+}
+
+Bool TestSumFact(I64 n,I64 target_sf,I64 sqrt_primes,I64 cbrt_primes,Prime *p)
+{
+  I64 i=0,k,b,x1,x2;
+  PowPrime *pp;
+  F64 disc;
+  if (n<2)
+    return FALSE;
+  while (i++<cbrt_primes) {
+    k=0;
+    while (!(n%p->prime)) {
+      n/=p->prime;
+      k++;
+    }
+    if (k) {
+      pp=p->pp+(k-1);
+      if (ModU64(&target_sf,pp->sumfact))
+        return FALSE;
+      if (n==1) {
+        if (target_sf==1)
+          return TRUE;
+        else
+          return FALSE;
+      }
+    }
+    p++;
+  }
+/*  At this point we have three possible cases to test
+1)n==p1         ->sf==(1+p1)        ?
+2)n==p1*p1      ->sf==(1+p1+p1^2)   ?
+3)n==p1*p2      ->sf==(p1+1)*(p2+1) ?
+
+*/
+  if (1+n==target_sf) {
+    while (i++<sqrt_primes) {
+      k=0;
+      while (!(n%p->prime)) {
+        n/=p->prime;
+        k++;
+      }
+      if (k) {
+        pp=p->pp+(k-1);
+        if (ModU64(&target_sf,pp->sumfact))
+          return FALSE;
+        if (n==1) {
+          if (target_sf==1)
+            return TRUE;
+          else
+            return FALSE;
+        }
+      }
+      p++;
+    }
+    if (1+n==target_sf)
+      return TRUE;
+    else
+      return FALSE;
+  }
+
+  k=Sqrt(n);
+  if (k*k==n) {
+    if (1+k+n==target_sf)
+      return TRUE;
+    else
+      return FALSE;
+  } else {
+// n==p1*p2 -> sf==(p1+1)*(p2+1) ?  where p1!=1 && p2!=1
+    // if p1==1 || p2==1, it is FALSE because we checked a single prime above.
+
+    // sf==(p1+1)*(n/p1+1)
+    // sf==n+p1+n/p1+1
+    // sf*p1==n*p1+p1^2+n+p1
+    // p1^2+(n+1-sf)*p1+n=0
+    // x=(-b+/-sqrt(b^2-4ac))/2a
+    // a=1
+    // x=(-b+/-sqrt(b^2-4c))/2
+    // b=n+1-sf;c=n
+    b=n+1-target_sf;
+// x=(-b+/-sqrt(b^2-4n))/2
+    disc=b*b-4*n;
+    if (disc<0)
+      return FALSE;
+    x1=(-b-Sqrt(disc))/2;
+    if (x1<=1)
+      return FALSE;
+    x2=n/x1;
+    if (x2>1 && x1*x2==n)
+      return TRUE;
+    else
+      return FALSE;
+  }
+}
+
+U0 PutFactors(I64 n) //For debugging
+{
+  I64 i,k,sqrt=Ceil(Sqrt(n));
+  for (i=2;i<=sqrt;i++) {
+    k=0;
+    while (!(n%i)) {
+      k++;
+      n/=i;
+    }
+    if (k) {
+      "%d",i;
+      if (k>1)
+        "^%d",k;
+      '' CH_SPACE;
+    }
+  }
+  if (n!=1)
+    "%d ",n;
+}
+
+class RangeJob
+{
+  CDoc *doc;
+  I64 num,lo,hi,N,sqrt_primes,cbrt_primes;
+  Prime *primes;
+  CJob *cmd;
+} rj[mp_cnt];
+
+I64 TestCoreSubRange(RangeJob *r)
+{
+  I64 i,j,m,n,n2,sf,res=0,range=r->hi-r->lo,
+        *sumfacts=MAlloc(range*sizeof(I64)),
+        *residue =MAlloc(range*sizeof(I64));
+  U16 *pow_cnt =MAlloc(range*sizeof(U16));
+  Prime *p=r->primes;
+  PowPrime *pp;
+  MemSetI64(sumfacts,1,range);
+  for (n=r->lo;n<r->hi;n++)
+    residue[n-r->lo]=n;
+  for (j=0;j<r->sqrt_primes;j++) {
+    MemSet(pow_cnt,0,range*sizeof(U16));
+    m=1;
+    for (i=0;i<p->pow_cnt;i++) {
+      m*=p->prime;
+      n=m-r->lo%m;
+      while (n<range) {
+        pow_cnt[n]++;
+        n+=m;
+      }
+    }
+    for (n=0;n<range;n++)
+      if (i=pow_cnt[n]) {
+        pp=&p->pp[i-1];
+        sumfacts[n]*=pp->sumfact;
+        residue [n]/=pp->n;
+      }
+    p++;
+  }
+
+  for (n=0;n<range;n++)
+    if (residue[n]!=1)
+      sumfacts[n]*=1+residue[n];
+
+  for (n=r->lo;n<r->hi;n++) {
+    sf=sumfacts[n-r->lo];
+    n2=sf-n-1;
+    if (n<n2<r->N) {
+      if (r->lo<=n2<r->hi && sumfacts[n2-r->lo]-n2-1==n ||
+            TestSumFact(n2,sf,r->sqrt_primes,r->cbrt_primes,r->primes)) {
+        DocPrint(r->doc,"%u:%u\n",n,sf-n-1);
+        res++;
+      }
+    }
+  }
+  Free(pow_cnt);
+  Free(residue);
+  Free(sumfacts);
+  return res;
+}
+
+#define CORE_SUB_RANGE  0x1000
+
+I64 TestCoreRange(RangeJob *r)
+{
+  I64 i,n,res=0;
+  RangeJob rj;
+  MemCpy(&rj,r,sizeof(RangeJob));
+  for (i=r->lo;i<r->hi;i+=CORE_SUB_RANGE) {
+    rj.lo=i;
+    rj.hi=i+CORE_SUB_RANGE;
+    if (rj.hi>r->hi)
+      rj.hi=r->hi;
+    res+=TestCoreSubRange(&rj);
+
+    n=rj.hi-rj.lo;
+    lock {progress1+=n;}
+
+    Yield;
+  }
+  return res;
+}
+
+I64 MagicPairs(I64 N)
+{
+  F64 t0=tS;
+  I64 res=0;
+  I64 sqrt_primes,cbrt_primes,num_powprimes,
+        i,k,n=(N-1)/mp_cnt+1;
+  Prime *primes=PrimesNew(N,&sqrt_primes,&cbrt_primes);
+  PowPrime *powprimes=PowPrimesNew(N,sqrt_primes,primes,&num_powprimes);
+
+  "N:%u SqrtPrimes:%u CbrtPrimes:%u PowersOfPrimes:%u\n",
+        N,sqrt_primes,cbrt_primes,num_powprimes;
+  progress1=0;
+  *progress1_desc=0;
+  progress1_max=N;
+  k=2;
+  for (i=0;i<mp_cnt;i++) {
+    rj[i].doc=DocPut;
+    rj[i].num=i;
+    rj[i].lo=k;
+    k+=n;
+    if (k>N) k=N;
+    rj[i].hi=k;
+    rj[i].N=N;
+    rj[i].sqrt_primes=sqrt_primes;
+    rj[i].cbrt_primes=cbrt_primes;
+    rj[i].primes=primes;
+    rj[i].cmd=JobQue(&TestCoreRange,&rj[i],mp_cnt-1-i,0);
+  }
+  for (i=0;i<mp_cnt;i++)
+    res+=JobResGet(rj[i].cmd);
+  Free(powprimes);
+  Free(primes);
+  "Found:%u Time:%9.4f\n",res,tS-t0;
+  progress1=progress1_max=0;
+  return res;
+}
+
+MagicPairs(1000000);
+
+ diff --git a/public/Wb/Home/Src/Demo/MemDemo.HC.HTML b/public/Wb/Home/Src/Demo/MemDemo.HC.HTML new file mode 100755 index 0000000..89f155a --- /dev/null +++ b/public/Wb/Home/Src/Demo/MemDemo.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+U0 MemDemo()
+{
+  I64 i;
+"$HL,1$$BLACK$
+#define MEM_PAG_BITS            9
+#define MEM_PAG_SIZE            (1<<MEM_PAG_BITS)
+#define MEM_HEAP_HASH_SIZE      1024
+#define MEM_FREE_PAG_HASH_SIZE  0x100
+#define MEM_EXTRA_HASH2_PAGS    2
+
+public class CBlkPool
+{
+  CMemBlk *free_pag_hash[MEM_FREE_PAG_HASH_SIZE],
+          *free_pag_hash2[64-MEM_PAG_BITS];
+};
+
+public class CHeapCtrl
+{
+  CBlkPool *bp;
+  CMemUnused *heap_hash[MEM_HEAP_HASH_SIZE/sizeof(U8 *)];
+};
+
+public class CTask //The Fs segment reg points to current CTask.
+{
+  CHeapCtrl *code_heap,*data_heap;
+};
+$HL,0$$FG$
+
+";
+
+
+  "$PURPLE$Chunks in increments of 8 bytes, owned by the task.$FG$\n";
+  for (i=sizeof(CMemUnused);i<MEM_HEAP_HASH_SIZE;i+=8)
+    if (i==0x48)
+      "...\n";
+    else if (!(0x48<i<0x3C8))
+      "Fs->data_heap->heap_hash[%X/8]"
+          "$BLACK$ -->$FG$[X]$BLACK$ -->$FG$[X]$BLACK$ -->$FG$\n",i;
+  "\n\n";
+
+  "$PURPLE$Pages of 512 bytes, owned by the system.$FG$\n";
+  for (i=MEM_HEAP_HASH_SIZE;i<MEM_FREE_PAG_HASH_SIZE*MEM_PAG_SIZE;
+        i+=MEM_PAG_SIZE)
+    if (i==0x1200)
+      "...\n";
+    else if (!(0x1200<i<0x1F200))
+      "Fs->data_heap->bp->free_pag_hash[%X/512]"
+          "$BLACK$ -->$FG$[X]$BLACK$ -->$FG$[X]$BLACK$ -->$FG$\n",i;
+  "\n\n";
+
+  "$PURPLE$Powers of two, owned by the system.$FG$\n";
+  for (i=Bsf(MEM_FREE_PAG_HASH_SIZE*MEM_PAG_SIZE);i<64;i++)
+    if (i==0x1A)
+      "...\n";
+    else if (!(0x1A<=i<=0x36))
+      "Fs->data_heap->bp->free_pag_hash2[%X] %016X"
+          "$BLACK$ -->$FG$[X]$BLACK$ -->$FG$[X]$BLACK$ -->$FG$\n",i,
+          1<<i+MEM_EXTRA_HASH2_PAGS*MEM_PAG_SIZE;
+  "\n\n";
+}
+
+MemDemo;
+
+
+
+ diff --git a/public/Wb/Home/Src/Demo/MsgLoop.HC.HTML b/public/Wb/Home/Src/Demo/MsgLoop.HC.HTML new file mode 100755 index 0000000..764d3ea --- /dev/null +++ b/public/Wb/Home/Src/Demo/MsgLoop.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+U0 MsgLoop()
+{
+  I64 arg1,arg2,msg_code;
+  "Use msg_code defines in your programs instead of hardcoded nums.\n"
+        "<ESC> to Exit\n";
+
+  //We don't want the mouse bttns to reposition the cursor,
+  //so we inhibit the window mgr from processing them.
+
+  Fs->win_inhibit=WIF_SELF_MS_L|WIF_SELF_MS_R;
+
+  do {
+    msg_code=GetMsg(&arg1,&arg2,~(1<<MSG_NULL));
+    "CMD:%02X ARG1:%08X ARG2:%016X\n",msg_code,arg1,arg2;
+  } while (msg_code!=MSG_KEY_DOWN || arg1!=CH_ESC && arg1!=CH_SHIFT_ESC);
+  GetMsg(,,1<<MSG_KEY_UP);
+
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+}
+
+MsgLoop;
+
+// Press <CTRL-SHIFT-L> and "Insert ASCII/ScanCode".
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/Interrupts.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/Interrupts.HC.HTML new file mode 100755 index 0000000..18f5570 --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/Interrupts.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+interrupt U0 IntBeepOn()
+{
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0; //signal end of interrupt
+  Snd(34);
+}
+
+interrupt U0 IntBeepOff()
+{
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+  Snd;
+}
+
+U0 IntTest()
+{//Modify interrupt descriptor table use by all cores.
+  IntEntrySet(I_USER,&IntBeepOn,IDTET_TRAP);
+  IntEntrySet(I_USER+1,&IntBeepOff,IDTET_TRAP);
+//Issue interupt to core1
+  MPInt(I_USER,1);
+  Sleep(1000);
+  MPInt(I_USER+1,1);
+}
+
+IntTest;
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/LoadTest.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/LoadTest.HC.HTML new file mode 100755 index 0000000..bb7211d --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/LoadTest.HC.HTML @@ -0,0 +1,79 @@ + + + + + + + + + + + +
+Bool app_done;
+I64 app_done_ack;
+
+U0 Job1(I64)
+{//Compile Compiler
+  Silent;
+  while (!app_done) {
+    Cd("::/Compiler");
+    Cmp("Compiler");
+  }
+  lock {app_done_ack--;}
+}
+
+U0 Job2(I64)
+{//Log a file
+  while (!app_done) {
+    AdamLog("%F","::/Demo/MultiCore/LoadTest.HC");
+    Yield;
+  }
+  lock {app_done_ack--;}
+}
+
+U0 Job3(I64)
+{//Log a file
+  while (!app_done) {
+    Cd("::/Compiler");
+    AdamLog("%F","Compiler.PRJ.Z");
+    Yield;
+  }
+  lock {app_done_ack--;}
+}
+
+U0 Main()
+{
+  app_done=FALSE;
+  "Running MultiCore Test...\n";
+  Spawn(&Job1,,,1); //core #1
+  Spawn(&Job2,,,1);
+  Spawn(&Job3,,,1);
+  PressAKey;
+//We don't want to yank code from under MP cores.
+  app_done_ack=3;
+  app_done=TRUE;
+  while (app_done_ack)
+    Yield;
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/Lock.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/Lock.HC.HTML new file mode 100755 index 0000000..7c6eee6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/Lock.HC.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+/*lock{} is a compiler stmt
+which places asm LOCK inst
+prefixes on code.  Only use it on
+read-modify-write stmts.
+It will generate invalid insts
+if you misuse it and it will crash.
+U() to see what code was generated.
+*/
+
+#define CNT     0x1000000
+
+I64 glbl;
+
+U0 MPUnlockedInc(I64)
+{
+  I64 i;
+  for (i=0;i<CNT;i++)
+    glbl++;
+}
+
+U0 UnlockedInc()
+{
+  CJob *tmpm0,*tmpm1;
+  glbl=0;
+  tmpm0=JobQue(&MPUnlockedInc,NULL,0,0);
+  tmpm1=JobQue(&MPUnlockedInc,NULL,1,0);
+  JobResGet(tmpm0);
+  JobResGet(tmpm1);
+  "Correct Cnt:%X Actual Cnt:%X\n",CNT*2,glbl;
+}
+
+U0 MPLockedInc(I64)
+{
+  I64 i;
+  for (i=0;i<CNT;i++)
+    lock  //Can be used without {}
+          glbl++;
+}
+
+U0 LockedInc()
+{
+  CJob *tmpm0,*tmpm1;
+  glbl=0;
+  tmpm0=JobQue(&MPLockedInc,NULL,0,0);
+  tmpm1=JobQue(&MPLockedInc,NULL,1,0);
+  JobResGet(tmpm0);
+  JobResGet(tmpm1);
+  "Correct Cnt:%X Actual Cnt:%X\n",CNT*2,glbl;
+}
+
+UnlockedInc;
+LockedInc;
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/MPAdd.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/MPAdd.HC.HTML new file mode 100755 index 0000000..68a613b --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/MPAdd.HC.HTML @@ -0,0 +1,116 @@ + + + + + + + + + + + +
+I64 mp_n;
+
+I64 MPSum(I64 my_mp_cnt)
+{//We could use the formula n*(n+1)/2
+  I64 lo=mp_n*Gs->num/my_mp_cnt,
+        hi=mp_n*(Gs->num+1)/my_mp_cnt,
+        res=0,i;
+  for (i=lo;i<hi;i++)
+    res+=i;
+  return res;
+}
+
+I64 Sum(I64 n,I64 my_mp_cnt)
+{
+  CJob *tmpm[MP_PROCESSORS_NUM];
+  I64 res=0,i;
+  mp_n=n+1;
+  for (i=0;i<my_mp_cnt;i++)
+    tmpm[i]=JobQue(&MPSum,my_mp_cnt,i,0);
+  for (i=0;i<my_mp_cnt;i++)
+    res+=JobResGet(tmpm[i]);
+  return res;
+}
+
+#define SAMPLE_SIZE 100
+
+F64 Test(I64 n,I64 my_mp_cnt)
+{
+  I64 i,val=0;
+  F64 start,end;
+  start=tS;
+  for (i=0;i<SAMPLE_SIZE;i++)
+    val+=Sum(n,my_mp_cnt);
+  end=tS;
+  "Val:%,d\n",val/SAMPLE_SIZE;
+  "$RED$N:%12,d Time:%10.8f$FG$\n",n,(end-start)/SAMPLE_SIZE;
+  return end-start;
+}
+
+#define VAL_MIN         1000
+#define TEST_MIN        3
+#define TEST_MAX        7
+#define TESTS_NUM       (TEST_MAX-TEST_MIN+1)
+#define PERCENT_MAX     200
+
+U0 MPAdd()
+{
+  I64 i,n,
+        h=Fs->pix_width,
+        v=Fs->pix_height;
+  F64 t1,t2,ress[TESTS_NUM];
+  CDC *dc=DCAlias;
+
+  for (i=0,n=VAL_MIN;i<TESTS_NUM;i++,n*=10) {
+    t1=Test(n,1);
+    t2=Test(n,mp_cnt);
+    ress[i]=t2*100.0/t1;
+    "$GREEN$%8.4f%%$FG$\n\n",ress[i];
+  }
+  PressAKey;
+
+  DocClear;
+
+  dc->color=BLUE;
+  for (i=PERCENT_MAX/10;i<PERCENT_MAX;i+=PERCENT_MAX/10) {
+    GrPrint(dc,0,v-ToF64(i)/PERCENT_MAX*v-FONT_HEIGHT,"%3d%%",i);
+    GrLine(dc,0,v-ToF64(i)/PERCENT_MAX*v,h,v-ToF64(i)/PERCENT_MAX*v);
+  }
+
+  for (i=0;i<TESTS_NUM-1;i++) {
+    dc->color=RED;
+    dc->thick=2;
+    GrLine3(dc,i*h/(TESTS_NUM-1),      v-ress[i  ]/PERCENT_MAX*v,0,
+          (i+1)*h/(TESTS_NUM-1),v-ress[i+1]/PERCENT_MAX*v,0);
+    dc->color=GREEN;
+    GrPrint(dc,i*h/(TESTS_NUM-1),v-FONT_HEIGHT,"10e%d",i+TEST_MIN);
+    GrLine(dc,i*h/(TESTS_NUM-1),0,i*h/(TESTS_NUM-1),v);
+  }
+  PressAKey;
+
+  DCFill;
+  DCDel(dc);
+}
+
+MPAdd;
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/MPPrint.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/MPPrint.HC.HTML new file mode 100755 index 0000000..34846f8 --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/MPPrint.HC.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+U0 Job(CDoc *doc)
+{
+  I64 i;
+  for (i=0;i<2;i++)
+    DocPrint(doc,"$FG,%d$CPU%d ",Gs->num&15,Gs->num);
+}
+
+U0 MPPrintDemo()
+{
+  I64 i;
+  for (i=0;i<500;i++)
+    JobQue(&Job,DocPut,i%mp_cnt);
+  Sleep(500);
+  "$FG$\n";
+}
+
+MPPrintDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/MPRadix.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/MPRadix.HC.HTML new file mode 100755 index 0000000..dfa3c0f --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/MPRadix.HC.HTML @@ -0,0 +1,173 @@ + + + + + + + + + + + +
+/*
+On an 8-core machine, this takes the top 3-bits
+of random numbers and distributes them to the 8 cores
+for sorting.  Then, it merge sorts them.
+*/
+
+#define NUM     1000000
+
+I64 my_mp_cnt=1<<Bsr(mp_cnt);//Power of 2
+
+I32 *arg1,*arg2;
+I32 *b[my_mp_cnt],bn[my_mp_cnt];
+I64 mp_not_done_flags;
+
+I64 Compare(I32 *e1,I32 *e2)
+{
+  return *e1-*e2;
+}
+
+U0 QSortU32(I32 *base,I64 num)
+{//By customizing, we dramatically improve it!
+//Cut and paste from QSortI64().
+  I64 i;
+  I32 *less,*greater,pivot;
+  if (num>1) {
+    do {
+      less=base;
+      greater=base+num;
+      pivot=base[num/2];
+      while (less<greater) {
+        if (*less<=pivot)
+          less++;
+        else {
+          greater--;
+          SwapU32(less,greater);
+        }
+      }
+      i=less-base;
+      if (i==num) {//All less or equ to pivot
+
+        //Point greater to first less
+        do greater--;
+        while (--i && *greater==pivot);
+
+        if (i) {
+          less=base+num/2; //Pivot was not moved, point to it
+          if (less<greater)
+            SwapU32(less,greater);
+          num=i;
+        } else //All equ
+          break;
+      } else if (i<num/2) {
+        QSortU32(base,i);
+        num-=i;
+        base=greater;
+      } else {
+        QSortU32(greater,num-i);
+        num=i;
+      }
+    } while (num>1);
+  }
+}
+
+U0 MPSort(I64 dummy=0)
+{
+  no_warn dummy;
+  QSortU32(b[Gs->num],bn[Gs->num]);
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 MPRadixSortDemo(I64 dummy=0)
+{
+  no_warn dummy;
+  I64 i,j,k1,k2;
+  F64 t0;
+  arg1=MAlloc(NUM*sizeof(I32));
+  for (i=0;i<NUM;i++)
+    arg1[i]=RandI32;
+
+  arg2=MAlloc(NUM*sizeof(I32));
+
+  "$GREEN$QSort$FG$\n";
+  t0=tS;
+  MemCpy(arg2,arg1,sizeof(I32)*NUM);
+  QSort(arg2,NUM,sizeof(I32),&Compare);
+  "Time:%9.6f\n",tS-t0;
+  D(arg2+NUM/4);
+
+  "$GREEN$QSortU32$FG$\n";
+  t0=tS;
+  MemCpy(arg2,arg1,sizeof(I32)*NUM);
+  QSortU32(arg2,NUM);
+  "Time:%9.6f\n",tS-t0;
+  D(arg2+NUM/4);
+
+  for (i=0;i<my_mp_cnt;i++) {
+//We must do full size, just in case.
+    //There will be uneven split between cores
+    //depending on the distribution of rand numbers.
+    b[i]=MAlloc(NUM*sizeof(I32));
+    bn[i]=0;
+  }
+
+  if (my_mp_cnt<2) throw('MultCore');
+
+  "$GREEN$MP Radix QSortU32$FG$\n";
+  t0=tS;
+  k1=32-Bsr(my_mp_cnt);
+  k2=my_mp_cnt/2;
+  for (i=0;i<NUM;i++) {
+    j=arg1[i]>>k1+k2; //This is a preliminary radix sort.
+    b[j][bn[j]++]=arg1[i];
+  }
+  mp_not_done_flags=1<<my_mp_cnt-1;
+  for (i=0;i<my_mp_cnt;i++)
+    Spawn(&MPSort,NULL,NULL,i);
+  while (mp_not_done_flags)
+    Yield;
+  j=0;
+  for (i=0;i<my_mp_cnt;i++) {
+    MemCpy(&arg2[j],b[i],bn[i]*sizeof(I32));
+    j+=bn[i];
+  }
+  "Time:%9.6f\n",tS-t0;
+  D(arg2+NUM/4);
+
+  Free(arg1);
+  Free(arg2);
+  for (i=0;i<my_mp_cnt;i++)
+    Free(b[i]);
+}
+
+MPRadixSortDemo;
+
+/* Results on 8 Cores 3.397GHz Core i7:
+QSort
+Time: 0.759998
+QSortU32
+Time: 0.093684
+MP Radix QSortU32
+Time: 0.045450
+*/
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/Palindrome.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/Palindrome.HC.HTML new file mode 100755 index 0000000..4649d2e --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/Palindrome.HC.HTML @@ -0,0 +1,127 @@ + + + + + + + + + + + +
+#define BORDER_CHARS    1
+
+U8 *buf;
+I64 size,mp_not_done_flags;
+CDoc *doc;
+
+U0 PDNormalize()
+{
+  U8 *r=MAlloc(size+2*BORDER_CHARS),
+        *src=buf,*dst=r;
+  I64 ch;
+  *dst++='['; //Border
+  while (size--) {
+    ch=*src++;
+    if ('a'<=ch<='z') //lower is most common so do first
+      *dst++=ch;
+    else if ('A'<=ch<='Z')
+      *dst++=ch+'a'-'A'; //Convert to lower
+  }
+  *dst++=']'; //Border
+  Free(buf);
+  buf=r;
+  size=dst-r-2*BORDER_CHARS;
+}
+
+U0 PDAnswer(U8 *a,I64 len)
+{
+  DocLock(doc);
+  a-=(len-1)/2;
+  DocPrint(doc,"CPU%02X Len:%2d ",Gs->num,len);
+  while (len--)
+    DocPrint(doc,"%C",*a++); //%C is toupper char
+  DocPrint(doc,"\n");
+  DocUnlock(doc);
+}
+
+U0 MPPalindrome(I64 dummy=0)
+{
+  no_warn dummy;
+  U8 *src=buf+BORDER_CHARS+size*Gs->num/mp_cnt,
+        *f,*b;
+  I64 len,best=0,
+        my_size=(size+mp_cnt-1)/mp_cnt;
+  while (my_size--) {
+
+    //Odd
+    f=src+1;
+    b=src-1;
+    while (*f==*b) {
+      f++;
+      b--;
+    }
+    len=f-b+1-2;
+    if (len>best) {
+      best=len;
+      PDAnswer(src,len);
+    }
+
+    //Even
+    f=src+1;
+    b=src;
+    while (*f==*b) {
+      f++;
+      b--;
+    }
+    len=f-b+1-2;
+    if (len>best) {
+      best=len;
+      PDAnswer(src,len);
+    }
+
+    src++;
+  }
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 Palindrome(U8 *filename)
+{
+  I64 i;
+  F64 t0=tS;
+
+  buf=FileRead(filename,&size);
+  PDNormalize;
+
+  doc=DocPut;
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    JobQue(&MPPalindrome,NULL,i);
+  while (mp_not_done_flags)
+    Yield;
+
+  Free(buf);
+  "Time:%9.5f\n",tS-t0;
+}
+
+Palindrome(BIBLE_FILENAME);
+
+ diff --git a/public/Wb/Home/Src/Demo/MultiCore/Primes.HC.HTML b/public/Wb/Home/Src/Demo/MultiCore/Primes.HC.HTML new file mode 100755 index 0000000..b121d5f --- /dev/null +++ b/public/Wb/Home/Src/Demo/MultiCore/Primes.HC.HTML @@ -0,0 +1,106 @@ + + + + + + + + + + + +
+U8 *master_bitmap;
+I64 prime_range,my_mp_cnt,pending;
+
+U0 PrimesJob(I64 i)
+{
+  I64 j,k,l=Sqrt(prime_range),
+        lo=i*prime_range/my_mp_cnt,
+        hi=(i+1)*prime_range/my_mp_cnt,
+        lo2=lo+sys_cache_line_width,
+        hi2=hi-sys_cache_line_width;
+  if (lo2>hi2) lo2=hi2;
+  for (j=2;j<=l;j++) {
+    if (!Bt(master_bitmap,j)) {
+      if (j>=lo)
+        k=j+j;
+      else {
+        k=lo-lo%j;
+        if (k<lo)
+          k+=j;
+      }
+      while (k<lo2) {
+        LBts(master_bitmap,k);
+        k+=j;
+      }
+      while (k<hi2) {
+        Bts(master_bitmap,k);
+        k+=j;
+      }
+      while (k<hi) {
+        LBts(master_bitmap,k);
+        k+=j;
+      }
+    }
+  }
+  lock pending--;
+}
+
+I64 Primes(I64 range,I64 _my_mp_cnt)
+{
+  I64 i,prime_cnt=0;
+  F64 t0=tS,tf;
+  prime_range=range;
+  if (_my_mp_cnt<=mp_cnt)
+    my_mp_cnt=_my_mp_cnt;
+  else
+    my_mp_cnt=mp_cnt;
+  master_bitmap=CAlloc((prime_range+7)/8+1);
+  Bts(master_bitmap,0);
+  Bts(master_bitmap,1);
+  pending=my_mp_cnt;
+  for (i=0;i<my_mp_cnt;i++)
+    JobQue(&PrimesJob,i,i);
+  while (pending)
+    Yield;
+  tf=tS;
+
+  for (i=0;i<prime_range;i++)
+    if (!Bt(master_bitmap,i))
+      prime_cnt++;
+
+  for (i=MaxI64(prime_range-100,0);i<prime_range;i++)
+    if (!Bt(master_bitmap,i))
+      "%d ",i;
+
+  "\n$RED$CPUs:%d PrimeRange:%,d PrimeCnt:%,d Time:%9.7,f$FG$\n",
+        my_mp_cnt,prime_range,prime_cnt,tf-t0;
+
+  Free(master_bitmap);
+  return prime_cnt;
+}
+
+Primes(100,1);
+Primes(100,mp_cnt);
+Primes(1000000,1);
+Primes(1000000,mp_cnt);
+
+ diff --git a/public/Wb/Home/Src/Demo/NullCase.HC.HTML b/public/Wb/Home/Src/Demo/NullCase.HC.HTML new file mode 100755 index 0000000..25d7808 --- /dev/null +++ b/public/Wb/Home/Src/Demo/NullCase.HC.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+//This shows a switch stmt with some null cases.
+//If no number for the case,
+//it uses one plus prev case number.
+
+U0 NullCase()
+{
+  I64 i;
+  for (i=0;i<20;i++)
+    switch (i) {
+      case: "Zero\n";   break; //Starts at zero
+      case: "One\n";    break; //One plus prev case.
+      case: "Two\n";    break;
+      case: "Three\n";  break;
+      case 10: "Ten\n"; break;
+      case: "Eleven\n"; break; //One plus prev case.
+    }
+}
+
+NullCase;
+
+ diff --git a/public/Wb/Home/Src/Demo/OnceDemo.HC.HTML b/public/Wb/Home/Src/Demo/OnceDemo.HC.HTML new file mode 100755 index 0000000..56da94e --- /dev/null +++ b/public/Wb/Home/Src/Demo/OnceDemo.HC.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+U0 OnceDemo()
+{//Set code to execute next reboot.
+  Once("Beep;");
+  Once("Dir;"); //You can issue multiple and they get queued.
+  "Reboot ";
+  if (YorN)
+    BootRAM;
+}
+
+OnceDemo;
+
+//There are variants for adam AOnce().
+
+ diff --git a/public/Wb/Home/Src/Demo/ParenWarn.HC.HTML b/public/Wb/Home/Src/Demo/ParenWarn.HC.HTML new file mode 100755 index 0000000..174ce4b --- /dev/null +++ b/public/Wb/Home/Src/Demo/ParenWarn.HC.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+Option(OPTf_WARN_PAREN,ON);
+
+F64 d,d1=1,d2=1;
+
+d1=(d2=3.0);
+
+d1=(d2+3.0);
+
+d=(d1+d2)+(d1+d2);
+
+d=(2`3)`2;
+
+d=2`(3`2);
+
+d=-d1`(d+d2);
+
+Option(OPTf_WARN_PAREN,OFF);
+
+ diff --git a/public/Wb/Home/Src/Demo/PhoneNumWords.HC.HTML b/public/Wb/Home/Src/Demo/PhoneNumWords.HC.HTML new file mode 100755 index 0000000..9bd4934 --- /dev/null +++ b/public/Wb/Home/Src/Demo/PhoneNumWords.HC.HTML @@ -0,0 +1,94 @@ + + + + + + + + + + + +
+U8 char_map[26]="22233344455566677778889999";
+
+/*
+Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block; //definition offset in ::/Adam/AutoComplete/ACDefs.DATA
+*/
+U0 PhoneNumWords(U8 *num)
+{
+  I64 ch;
+  U8 *_num=StrNew(num),*dst=_num,
+        *dict=acd.word_lst,*st,*src;
+  while (*num) {
+    if ('0'<=*num<='9')
+      *dst++=*num;
+    num++;
+  }
+  *dst=0;
+
+  while (*dict++) {
+    if (StrLen(dict)>2) {
+      dst=st=StrNew(dict);
+      while (ch=ToUpper(*dst)) {
+        if ('A'<=ch<='Z')
+          *dst=char_map[ch-'A'];
+        else
+          *dst=CH_SPACE;
+        dst++;
+      }
+      *dst=0;
+
+      src=_num;
+      while (*src) {
+        if (!StrNCmp(st,src,StrLen(st))) {
+          ch=*src;
+          *src=0;
+          "%s",_num;
+          *src=ch;
+          "$GREEN$%s$FG$",dict;
+          "%s\n",src+StrLen(st);
+        }
+        src++;
+      }
+      Free(st);
+    }
+    dict+=StrLen(dict)+3;
+  }
+  Free(_num);
+  '\n';
+}
+
+U0 PNWDemo()
+{
+  U8 *st;
+  while ((st=GetStr("Phone Num:")) && *st) {
+    PhoneNumWords(st);
+    Free(st);
+  }
+  Free(st);
+}
+
+PNWDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Print.HC.HTML b/public/Wb/Home/Src/Demo/Print.HC.HTML new file mode 100755 index 0000000..db06101 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Print.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+//TempleOS supports standard Print()
+//codes and extended ones.
+//See Print("") Fmt Strings.
+
+//Demonstrates aux_fmt_num codes.
+
+"%10h?d\n",123456789;
+"%10h?d\n",12345;
+
+"%10h3d\n",123456789;
+"%10h3d\n",12345;
+
+"\nWith the ',' flag:\n";
+"%10,h3d\n",123456789;
+"%10,h3d\n",12345;
+
+"\nFloating Point:\n";
+"%16h?n\n",.00123456789;
+"%16h?n\n",12345.0;
+
+"%16.2h-6n\n",.00123456789;
+"%16.2h-6n\n",12345.0;
+
+'\n';
+
+"%h25c\n",'x'; //Print 25 x's
+
+"%h*c\n",25,'y'; //Print 25 y's
+
+'zzzz\n'; //PutChars() up to 8 characters.
+
+'\n';
+
+
+ diff --git a/public/Wb/Home/Src/Demo/Progress.HC.HTML b/public/Wb/Home/Src/Demo/Progress.HC.HTML new file mode 100755 index 0000000..6171a08 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Progress.HC.HTML @@ -0,0 +1,111 @@ + + + + + + + + + + + +
+/*progress1-progress4 are just global vars
+shown on the wallpaper. I use them in debugging a lot.
+
+If you set progress1_max-progress4_max,
+then a progress bar will display.
+
+If you set progress1_t0-progress4_t0
+then the elapsed time will display.
+
+If you set progress1_tf-progress4_tf
+then the estimated time will display.
+*/
+
+U0 Main1()
+{
+  "\nWith description.\n";
+  PressAKey;
+  progress1_max=200;
+  StrCpy(progress1_desc,"Progress Demo"); //PROGRESS_DESC_LEN is max
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst;
+}
+Main1;
+
+U0 Main2()
+{
+  "\nWith description and elapsed time.\n";
+  PressAKey;
+  progress1_max=200;
+  progress1_t0=tS;
+  StrCpy(progress1_desc,"Progress Demo"); //PROGRESS_DESC_LEN is max
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst;
+}
+Main2;
+
+U0 Main3()
+{
+  "\nWith description, elapsed time and registry total time.\n";
+  PressAKey;
+  progress1_max=200;
+  progress1_t0=tS;
+  RegExe("DemoCompany/ProgressBars");
+  StrCpy(progress1_desc,"Progress Demo"); //PROGRESS_DESC_LEN is max
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst("DemoCompany/ProgressBars");
+}
+Main3;
+
+U0 Main4()
+{
+  "\nNo description.\n";
+  PressAKey;
+  progress1_max=200;
+  while (progress1++!=progress1_max)
+    Sleep(20);
+  ProgressBarsRst;
+}
+Main4;
+
+
+"\nNow, from asm...  It's handy for debugging.\n"
+"Watch the progress on the wallpaper.\n";
+WinBorder(ON);
+PressAKey;
+
+asm {
+_PROGRESS_DEMO::
+        MOV     RCX,12000000
+@@05:   MOV     U64 [&progress1],RCX
+        CALL    &Yield
+        LOOP    @@05
+        MOV     U64 [&progress1],RCX
+        RET
+}
+_extern _PROGRESS_DEMO U0 AsmProgressDemo();
+AsmProgressDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/Prompt.HC.HTML b/public/Wb/Home/Src/Demo/Prompt.HC.HTML new file mode 100755 index 0000000..6c7b784 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Prompt.HC.HTML @@ -0,0 +1,56 @@ + + + + + + + + + + + +
+U0 PromptDemo()
+{
+  F64 d;
+  I64 i;
+  U8 *name;
+  CDate cdt;
+
+  "\n\nNow prompting from the cmd line.\n\n"
+        "$GREEN$<ENTER>$FG$ keeps default.\n\n";
+
+  i=GetI64("Enter int expression(%d):",123);
+  "Int=%d\n",i;
+
+  d=GetF64("Enter float expression(%12g):",1.2e3);
+  "Float=%e\n",d;
+
+  name=GetStr("Name (%s):","John");
+  "Name:%s\n",name;
+  Free(name);
+
+  cdt=GetDate("Date (%D):",Now);
+  "Date=%D\n",cdt;
+}
+
+PromptDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/PullDownMenu.HC.HTML b/public/Wb/Home/Src/Demo/PullDownMenu.HC.HTML new file mode 100755 index 0000000..19835b7 --- /dev/null +++ b/public/Wb/Home/Src/Demo/PullDownMenu.HC.HTML @@ -0,0 +1,120 @@ + + + + + + + + + + + +
+//See Menus
+
+#define M_OPTION1       1
+#define M_OPTION2       2
+
+U0 PullDownMenuDemo()
+{
+  I64 msg_code,arg1,arg2;
+  CMenuEntry *tmpse;
+
+  MenuPush(
+        "File {"
+        "  Open(,'O');"
+        "  Save(,'S');"
+        "  Exit(,CH_SHIFT_ESC);"
+        "}"
+        "Edit {"
+        "  Cut(,,SC_DELETE|SCF_SHIFT);"
+        "  Paste(,,SC_INS|SCF_SHIFT);"
+        "}"
+        "Misc {"
+        "  Beep(,CH_SPACE);"
+        "  Opt1(MSG_CMD,M_OPTION1);"
+        "  Opt2(MSG_CMD,M_OPTION2);"
+        "}"
+        "Help {"
+        "  Help(,,0x3B0000003B);"
+        "  About(,,0x23B0000023B);"
+        "}");
+
+  "A pull-down menu will appear "
+        "if you move the mouse to the top "
+        "of the scrn.\n\n";
+
+  do {
+    msg_code=GetMsg(&arg1,&arg2,1<<MSG_KEY_DOWN+1<<MSG_CMD);
+    "\nCmd:%d ARG1:%X ARG2:%X\n\n",msg_code,arg1,arg2;
+
+    switch (msg_code) {
+      case MSG_KEY_DOWN:
+        switch (arg1) {//ASCII
+          case CH_SPACE:
+            Beep;
+            break;
+          case 0:
+            switch (arg2.u8[0]) {//arg2=Scan code
+              case SC_F1:
+                if (arg2&SCF_SHIFT)
+                  "About PullDown Demo\n";
+                else
+                  "Test the menu.\n";
+                break;
+              case SC_DELETE:
+                if (arg2&SCF_SHIFT)
+                  "Cut\n";
+                break;
+              case SC_INS:
+                if (arg2&SCF_SHIFT)
+                  "Paste\n";
+                break;
+            }
+            break;
+        }
+        break;
+
+      case MSG_CMD:
+//I Recommend making your menu
+      //drive by key strokes, but you can
+      //use the MSG_CMD val.
+        switch (arg1) {
+          case M_OPTION1:
+            "Option # 1\n";
+            if (tmpse=MenuEntryFind(Fs->cur_menu,"Misc/Opt1"))
+              tmpse->checked=!tmpse->checked;
+            break;
+          case M_OPTION2:
+            "Option # 2\n";
+            if (tmpse=MenuEntryFind(Fs->cur_menu,"Misc/Opt2"))
+              tmpse->checked=!tmpse->checked;
+            break;
+        }
+        break;
+    }
+
+  } while (msg_code!=MSG_KEY_DOWN||(arg1!=CH_SHIFT_ESC && arg1!=CH_ESC));
+  MenuPop;
+}
+
+PullDownMenuDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/RadixSort.HC.HTML b/public/Wb/Home/Src/Demo/RadixSort.HC.HTML new file mode 100755 index 0000000..9dfef81 --- /dev/null +++ b/public/Wb/Home/Src/Demo/RadixSort.HC.HTML @@ -0,0 +1,93 @@ + + + + + + + + + + + +
+#define RADIX   256
+#define N       16
+
+U8 a[N];
+
+class Lst
+{
+  Lst *next;
+  U8 *a;
+} l[N],*r[RADIX];
+
+U0 DumpIn()
+{
+  I64 i;
+  "$RED$\n\nInput$FG$\n";
+  for (i=0;i<N;i++)
+    "%d:%d\n",i,a[i];
+}
+
+U0 DumpOut()
+{
+  I64 i,j=0;
+  Lst *tmpl;
+  "$RED$\n\nOutput$FG$\n";
+  for (i=0;i<RADIX;i++) {
+    tmpl=r[i];
+    while (tmpl) {
+      "%d:%d\n",j++,*tmpl->a;
+      tmpl=tmpl->next;
+    }
+  }
+}
+
+U0 Init()
+{
+  I64 i;
+  MemSet(r,0,sizeof(r));
+  for (i=0;i<N;i++) {
+    a[i]=RandU16&255;
+    l[i].next=NULL;
+    l[i].a=&a[i];
+  }
+}
+
+U0 Sort()
+{
+  I64 i;
+  for (i=0;i<N;i++) {
+    l[i].next=r[*l[i].a];
+    r[*l[i].a]=&l[i];
+  }
+}
+
+U0 RadixSort()
+{
+  Init;
+  DumpIn;
+  Sort;
+  DumpOut;
+}
+
+RadixSort;
+
+ diff --git a/public/Wb/Home/Src/Demo/RandDemo.HC.HTML b/public/Wb/Home/Src/Demo/RandDemo.HC.HTML new file mode 100755 index 0000000..a02ffaa --- /dev/null +++ b/public/Wb/Home/Src/Demo/RandDemo.HC.HTML @@ -0,0 +1,95 @@ + + + + + + + + + + + +
+U0 RandPts()
+{
+  I64 i;
+  F64 t0=tS;
+  do {
+    for (i=0;i<1024;i++) {
+      gr.dc->color=RandU16&15;
+      GrPlot(gr.dc,RandU32%GR_WIDTH,RandU32%GR_HEIGHT);
+    }
+    Yield;
+  } while (tS-t0<1);
+  DCFill;
+}
+
+U0 RandDemo()
+{
+  I64 i;
+
+  "Seed(0) will do timer XORed random numbers.  "
+        "A task starts with Seed(0) by dft.\n";
+  PressAKey;
+  Seed;
+  RandPts;
+  DCFill;
+
+  "\nSeed(num) will do deterministic, non-timer random numbers starting at "
+        "a specific seed.  You can run a specific video game over and over "
+        "by typing Seed(num) at the cmd line before the game.\n";
+  PressAKey;
+  Seed(1);
+  RandPts;
+  DCFill;
+
+  "\n\n\nWatch when we specify specific seeds:";
+
+  "\n\nSeed(1);\n";
+  Seed(1);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(2); Different, right?\n";
+  Seed(2);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(1); Repeats earlier values.\n";
+  Seed(1);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(0); Zero is special.\n";
+  Seed(0);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  "\nSeed(0); Non-repeating.\n";
+  Seed(0);
+  for (i=0;i<5;i++)
+    "%d: %d\n",i,RandI16;
+
+  Seed; //Dft should be kept to zero.
+}
+
+RandDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/RegistryDemo.HC.HTML b/public/Wb/Home/Src/Demo/RegistryDemo.HC.HTML new file mode 100755 index 0000000..fd64fdf --- /dev/null +++ b/public/Wb/Home/Src/Demo/RegistryDemo.HC.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+/*The ~/Registry.HC.Z file is HolyC code.
+You can execute a tree branch of it.  The Adam
+branch is executed in the Adam task boot phase.
+Normally, you will place var declarations
+in the branch you make, but since an arthmetic expression
+is valid in HolyC you can place simple expressions
+without vars.
+*/
+
+RegDft("DemoCompany/Game1","F64 best_score=1.23;\n");
+RegDft("DemoCompany/Game1/SimpleVal","1234;\n");
+RegExe("DemoCompany/Game1");
+
+U0 Game()
+{
+  I64 i=RegExe("DemoCompany/Game1/SimpleVal");
+  "High Score:%6.5f\n",best_score;
+  "Val:%d\n",i;
+  i++;
+  best_score=tS;
+//You could combine these into one write by making
+  //the $TR...$ and $ID,2$, $ID,-2$, cmds yourself.
+  RegWrite("DemoCompany/Game1","F64 best_score=%9.5f;\n",best_score);
+  RegWrite("DemoCompany/Game1/SimpleVal","%d;\n",i);
+}
+
+Game;
+
+ diff --git a/public/Wb/Home/Src/Demo/RevFileDemo/DemoPoemBwd.DD.HTML b/public/Wb/Home/Src/Demo/RevFileDemo/DemoPoemBwd.DD.HTML new file mode 100755 index 0000000..16680b1 --- /dev/null +++ b/public/Wb/Home/Src/Demo/RevFileDemo/DemoPoemBwd.DD.HTML @@ -0,0 +1,73 @@ + + + + + + + + + + + +
+Will lead my steps aright.
+In the long way that I must tread alone,
+Guides through the boundless sky thy certain flight,
+He, who, from zone to zone,
+
+And shall not soon depart.
+Deeply hath sunk the lesson thou hast given,
+Hath swallowed up thy form; yet, on my heart
+Thou'rt gone, the abyss of heaven
+
+Soon o'er thy sheltered nest.
+And scream among thy fellows; reed shall bend
+Soon shalt thou find a summer home, and rest,
+And soon that toil shall end,
+
+Though the dark night is near.
+Yet stoop not, weary, to the welcome land,
+At that far height, the cold thin atmosphere:
+All day thy wings have fann'd
+
+Lone wandering, but not lost.
+The desert and illimitable air,--
+Teaches thy way along that pathless coast,--
+There is a Power whose care
+
+On the chafed ocean side?
+Or where the rocking billows rise and sink
+Of weedy lake, or marge of river wide,
+Seek'st thou the plashy brink
+
+Thy figure floats along.
+As, darkly painted on the crimson sky,
+Might mark thy distant flight to do thee wrong,
+Vainly the fowler's eye
+
+Thy solitary way?
+Far, through their rosy depths, dost thou pursue
+While glow the heavens with the last steps of day,
+Whither, 'midst falling dew,
+
+by William Cullen Bryant
+To a Waterfowl;
+
+ diff --git a/public/Wb/Home/Src/Demo/RevFileDemo/Rev.HC.HTML b/public/Wb/Home/Src/Demo/RevFileDemo/Rev.HC.HTML new file mode 100755 index 0000000..889b3f0 --- /dev/null +++ b/public/Wb/Home/Src/Demo/RevFileDemo/Rev.HC.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+/*We use the internal routines from the text editor
+to cut and paste lines to rev the order of
+lines in a text file.
+*/
+
+Cd(__DIR__);;
+
+U0 Rev(U8 *in_name,U8 *out_name)
+{
+  CDoc  *doc_in =DocRead(in_name),
+        *doc_out=DocNew(out_name);
+  DocTop(doc_in);
+  while (doc_in->head.next!=doc_in) {
+    EdLineDown(doc_in,SC_CURSOR_DOWN|SCF_SHIFT);
+    ClipCut(doc_in);
+    DocTop(doc_out);
+    ClipPaste(doc_out);
+  }
+  DocWrite(doc_out);
+}
+
+Rev("DemoPoemBwd.DD.Z","~/DemoPoemFwd.DD.Z");
+
+ diff --git a/public/Wb/Home/Src/Demo/ScrnCodes.HC.HTML b/public/Wb/Home/Src/Demo/ScrnCodes.HC.HTML new file mode 100755 index 0000000..370e5a6 --- /dev/null +++ b/public/Wb/Home/Src/Demo/ScrnCodes.HC.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+/*See TextBase Layer for the format
+of the U32 you pass to TextChar()
+
+See ::/Doc/CharOverview.DD, ::/Demo/ExtChars.HC,
+and ::/Demo/Graphics/FontEd.HC.
+
+Hold <ALT> and press a 3 digit decimal number
+or press <CTRL-ALT-a> to enter extended characters.
+*/
+
+U0 DrawIt(CTask *task,CDC *)
+{
+  I64 i;
+  for (i=0;i<256;i++)
+    TextChar(task,,(i&15)*2,(i/16)*2,i+BLACK<<12+WHITE<<8);
+}
+
+U0 ScrnCodes()
+{
+  SettingsPush; //See SettingsPush
+  DocClear;
+  Fs->draw_it=&DrawIt;
+  GetChar(,FALSE);
+  SettingsPop;
+}
+
+ScrnCodes;
+
+ diff --git a/public/Wb/Home/Src/Demo/Snd/ASCIIOrgan.HC.HTML b/public/Wb/Home/Src/Demo/Snd/ASCIIOrgan.HC.HTML new file mode 100755 index 0000000..3aad6dc --- /dev/null +++ b/public/Wb/Home/Src/Demo/Snd/ASCIIOrgan.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+//Practice your ASCII knowledge ;-)
+
+U0 SafePutChar(U8 ch)
+{
+  if (CH_SHIFT_SPACE<=ch<0x7F) {
+    if (ch=='$')
+      "%02X $RED$$$$FG$ ",ch;
+    else
+      "%02X $RED$%c$FG$ ",ch,ch;
+  } else
+    "%02X $RED$ $FG$ ",ch;
+}
+
+
+
+
+
+
+            <1>/* Graphics Not Rendered in HTML */
+
+U0 ASCIIOrgan()
+{
+  I64 i,ch;
+
+  for (i=0;i<32;i++) {
+    SafePutChar(i);
+    SafePutChar(i+32);
+    SafePutChar(i+64);
+    SafePutChar(i+96);
+    '\n';
+  }
+
+  "\nPress keys to make snds\n"
+        "and press $GREEN$<SHIFT-ESC>$FG$ to exit.\n";
+  do {
+//We don't want echo or scan codes, so we use NULL and FALSE...
+    ch=GetChar(,FALSE);
+    Snd(ch-CH_ESC);
+  } while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
+  Snd;
+
+  //Note the %d in the string for sprite number.
+  '\n\n\n\n\n\n\n';
+  Sprite(<1>,"$SP+PU,\"Click for better organ\","
+        "LM=\"#include \\\"::/Apps/Psalmody/Run\\\";\",BI=%d$");
+  '\n\n\n\n\n';
+}
+
+ASCIIOrgan;
+
+ diff --git a/public/Wb/Home/Src/Demo/Snd/MorseCode.HC.HTML b/public/Wb/Home/Src/Demo/Snd/MorseCode.HC.HTML new file mode 100755 index 0000000..6759e51 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Snd/MorseCode.HC.HTML @@ -0,0 +1,207 @@ + + + + + + + + + + + +
+#define M_DASH_THRESHOLD  0.140
+#define M_SPACE_THRESHOLD 0.300
+
+U8 *morse_lst=
+
+"A.-\0"
+"B-...\0"
+"C-.-.\0"
+"D-..\0"
+"E.\0"
+"F..-.\0"
+"G--.\0"
+"H....\0"
+"I..\0"
+"J.---\0"
+"K-.-\0"
+"L.-..\0"
+"M--\0"
+"N-.\0"
+"O---\0"
+"P.--.\0"
+"Q--.-\0"
+"R.-.\0"
+"S...\0"
+"T-\0"
+"U..-\0"
+"V...-\0"
+"W.--\0"
+"X-..-\0"
+"Y-.--\0"
+"Z--..\0"
+
+"1.----\0"
+"2..---\0"
+"3...--\0"
+"4....-\0"
+"5.....\0"
+"6-....\0"
+"7--...\0"
+"8---..\0"
+"9----.\0"
+"0-----\0"
+
+"/-..-.\0"
+"+.-.-.\0"
+"..-.-.-\0"
+",--..--\0"
+"?..--..\0"
+"(-.--.\0"
+")-.--.-\0"
+"--....-\0"
+"\".-..-.\0"
+"_..--.-\0"
+"'.----.\0"
+":---...\0"
+";-.-.-.\0"
+"=-...-\0";
+
+U0 MorseTable()
+{
+  U8 *st;
+  I64 i=0;
+  for (i=0;i<13;i++ ) {
+    if (st=LstSub(i,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    if (st=LstSub(i+13,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    if (st=LstSub(i+26,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    if (st=LstSub(i+39,morse_lst))
+      "$RED$%C$FG$ %-7s ",*st,st+1;
+    '\n';
+  }
+  '\n';
+}
+
+F64 m_start,m_end,dt_down,dt_up;
+Bool space_sent;
+
+U8 *MorseTimes(CDoc *,CDocEntry *,CTask *mem_task)
+{
+  U8 *st=MAlloc(64,mem_task);
+  StrPrint(st,"Down:%10.6f Up:%10.6f",dt_down,dt_up);
+  return st;
+}
+
+I64 MorseWaitKey()
+{
+  I64 ch;
+  F64 dt;
+  while (TRUE) {
+    if (m_start) {
+      GetMsg(NULL,NULL,1<<MSG_KEY_UP);
+      m_end=tS;
+      Snd;
+      dt_down=m_end-m_start;
+      m_start=0;
+      space_sent=FALSE;
+      if (dt_down<M_DASH_THRESHOLD)
+        return '.';
+      else
+        return '-';
+    } else {
+      if (!space_sent) {
+        while (!ScanMsg(&ch,NULL,1<<MSG_KEY_DOWN)) {
+          dt=tS-m_end;
+          if (dt>=M_SPACE_THRESHOLD) {
+            space_sent=TRUE;
+            return CH_SPACE;
+          }
+          Yield;
+        }
+      } else
+        ch=GetChar(,FALSE);
+      m_start=tS;
+      Snd(74);
+      if (ch==CH_SHIFT_ESC || ch==CH_ESC) {
+        '\n';
+        Snd;
+        throw; //exit program
+      }
+      dt_up=m_start-m_end;
+      if (!space_sent && dt_up>=M_SPACE_THRESHOLD) {
+        space_sent=TRUE;
+        return CH_SPACE;
+      }
+    }
+  }
+}
+
+U0 Morse()
+{
+  CDocEntry *doc_e;
+  I64 ch;
+  U8 buf[8],*dst,*src;
+
+  MorseTable;
+  m_start=0;
+  m_end=tS;
+  dt_down=0;
+  dt_up=0;
+  space_sent=TRUE;
+
+  "$GREEN$";
+
+  doc_e=DocPrint(DocPut,"$TX+TC,\" \"$");
+  doc_e->tag_cb=&MorseTimes;
+
+  "$FG$\n";
+
+  dst=buf;
+  while (TRUE) {
+    ch=MorseWaitKey;
+    if (ch==CH_SPACE) {
+      *dst=0;
+      src=morse_lst;
+      while (*src) {
+        if (!StrCmp(src+1,buf)) {
+          "$GREEN$%C$FG$",*src;
+          break;
+        } else
+          src+=StrLen(src)+1;
+      }
+      '' CH_SPACE;
+      dst=buf;
+    } else {
+      if (dst-buf<sizeof(buf)-1) {
+        '' ch;
+        *dst++=ch;
+      }
+    }
+  }
+  Snd;
+}
+
+Morse;
+
+ diff --git a/public/Wb/Home/Src/Demo/Snd/OhGreat.HC.HTML b/public/Wb/Home/Src/Demo/Snd/OhGreat.HC.HTML new file mode 100755 index 0000000..0442692 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Snd/OhGreat.HC.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+U0 Song()
+{//Song by Terry A. Davis
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  try //Catch <CTRL-ALT-c> exit
+    while (!ScanChar) {
+      Play("6hEqDC5B6CDhE",
+            "God \0is \0a \0g\0od \0of \0love.\n\0");
+      Play("5GqFEFhG6E",
+            " \0 \0 \0 \0 \0He \0");
+      Play("6qDC5B6CDhE5G",
+            "wat\0ches \0us \0from \0a\0bove.\n\0 \0");
+      Play("5qFEFhGB6qC",
+            " \0 \0 \0 \0Our \0world \0");
+      Play("6DhCeDC5hBG",
+            "is\0n't \0al\0ways \0nice.\n\0 \0");
+      Play("5qFEFhG6EqD",
+            " \0 \0 \0 \0Be\0fore \0");
+      Play("6C5B6CDhE5G",
+            "you \0gr\0ipe \0think \0twice.\n\0 \0");
+      Play("5qFEFhG6EqD",
+            " \0 \0 \0 \0He \0wat\0");
+      Play("6C5B6CDhE5G",
+            "ches \0us \0from \0a\0bove.\n\0 \0");
+      Play("5qFEFhG6EqD",
+            " \0 \0 \0 \0He'll \0smack \0");
+      Play("6C5B6CDhE5G",
+            "you \0with \0out \0a \0glove.\n\0 \0");
+      Play("5qFEFhGB6qC",
+            " \0 \0 \0 \0Our \0world \0");
+      Play("6DhCeDC5hBG",
+            "is\0n't \0al\0ways \0nice.\n\0 \0");
+      Play("5qFEFhG");
+    }
+  catch
+    PutExcept;
+  '\n';
+  Snd;
+}
+
+Song;
+
+ diff --git a/public/Wb/Home/Src/Demo/Snd/WaterFowl.HC.HTML b/public/Wb/Home/Src/Demo/Snd/WaterFowl.HC.HTML new file mode 100755 index 0000000..53eea47 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Snd/WaterFowl.HC.HTML @@ -0,0 +1,187 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+U8 *poem=
+"To a Waterfowl
+by William Cullen Bryant
+
+Whither, 'midst falling dew,
+While glow the heavens with the last steps of day,
+Far, through their rosy depths, dost thou pursue
+Thy solitary way?
+
+Vainly the fowler's eye
+Might mark thy distant flight to do thee wrong,
+As, darkly painted on the crimson sky,
+Thy figure floats along.
+
+Seek'st thou the plashy brink
+Of weedy lake, or marge of river wide,
+Or where the rocking billows rise and sink
+On the chafed ocean side?
+
+There is a Power whose care
+Teaches thy way along that pathless coast,--
+The desert and illimitable air,--
+Lone wandering, but not lost.
+
+All day thy wings have fann'd
+At that far height, the cold thin atmosphere:
+Yet stoop not, weary, to the welcome land,
+Though the dark night is near.
+
+And soon that toil shall end,
+Soon shalt thou find a summer home, and rest,
+And scream among thy fellows; reed shall bend
+Soon o'er thy sheltered nest.
+
+Thou'rt gone, the abyss of heaven
+Hath swallowed up thy form; yet, on my heart
+Deeply hath sunk the lesson thou hast given,
+And shall not soon depart.
+
+He, who, from zone to zone,
+Guides through the boundless sky thy certain flight,
+In the long way that I must tread alone,
+Will lead my steps aright.
+";
+
+#define POEM_COLS       53
+#define POEM_TIME       65.0
+
+F64 t0;
+
+U0 DrawIt(CTask *task,CDC *dc)
+{
+  I64   w=task->pix_width,h=task->pix_height;
+  F64   t=1.04-(0.35+0.65*Caw(tS-t0,20))`3,s=1.0-0.5*t,
+        x=w*t,y=h*(0.35-.1*t);
+  dc->color=WHITE;
+  GrPrint(dc,w>>1-(POEM_COLS*FONT_WIDTH)>>1,
+        Caw(tS-t0,POEM_TIME)*(h-3*FONT_HEIGHT),poem);
+  dc->color=BLACK;
+  GrLine(dc,x,y,x-8*s,y+6*s*FullTri(tS,0.4));
+  GrLine(dc,x,y,x+8*s,y+6*s*FullTri(tS,0.4));
+}
+
+U0 SongTask(I64)
+{//Song by Terry A. Davis
+//This specifies a callback routine
+  //to be called when the task dies.
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("5eEDC4B5C4B5C4BA5qReEDC4B5C");
+    Play("4B5C4BA5qReFEDEDEDC4qB");
+    Play("5ReFEDEDEDC4BqR");
+  }
+}
+
+U0 WaterFowl()
+{
+  SettingsPush; //See SettingsPush
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocClear;
+  t0=tS;
+  Fs->draw_it=&DrawIt;
+  Sprite(<1>);
+  "%h*c",TEXT_ROWS-2,'\n';
+  GetChar;
+  DocClear;
+  SettingsPop;
+}
+
+WaterFowl;
+
+
+ diff --git a/public/Wb/Home/Src/Demo/SortFileDemo/F64FileGen.HC.HTML b/public/Wb/Home/Src/Demo/SortFileDemo/F64FileGen.HC.HTML new file mode 100755 index 0000000..23e53cd --- /dev/null +++ b/public/Wb/Home/Src/Demo/SortFileDemo/F64FileGen.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+//This makes a file of N random double values.
+
+Cd(__DIR__);;
+
+U0 F64FileGenTXT(U8 *filename,I64 n)
+{
+  I64 i;
+  CDoc *doc=DocNew(filename);
+  DocPrint(doc,"//This is unsorted.\n");
+  for (i=0;i<n;i++)
+    DocPrint(doc,"%12.6f\n",Rand);
+  DocWrite(doc);
+  DocDel(doc);
+}
+F64FileGenTXT("~/DemoUnsortedF64.DD.Z",10);
+
+U0 F64FileGenDAT(U8 *filename,I64 n)
+{//File/CFile, ::/Demo/Dsk/DataBase.HC
+  I64 i;
+  F64 *a=MAlloc(n*sizeof(F64));
+  for (i=0;i<n;i++)
+    a[i]=Rand;
+  FileWrite(filename,a,n*sizeof(F64));
+  Free(a);
+}
+F64FileGenDAT("~/DemoUnsortedF64.DATA.Z",10);
+
+ diff --git a/public/Wb/Home/Src/Demo/SortFileDemo/F64FileSort.HC.HTML b/public/Wb/Home/Src/Demo/SortFileDemo/F64FileSort.HC.HTML new file mode 100755 index 0000000..0db7c84 --- /dev/null +++ b/public/Wb/Home/Src/Demo/SortFileDemo/F64FileSort.HC.HTML @@ -0,0 +1,103 @@ + + + + + + + + + + + +
+//This takes an input file of doubles and makes a sorted output file.
+
+Cd(__DIR__);;
+
+I64 Compare(F64 e1,F64 e2)
+{
+  return Sign(e1-e2);
+}
+
+U0 F64FileSortTXT(U8 *in_name,U8 *out_name)
+{
+  CCmpCtrl *cc;
+  I64 i,n;
+  F64 *a;
+  CDoc *doc;
+
+  //Pass1: Count the number of F64s.
+  n=0;
+  cc=CmpCtrlNew(MStrPrint("#include \"%s\"",in_name));
+  while (Lex(cc))
+    if (cc->token==TK_F64)
+      n++;
+  CmpCtrlDel(cc);
+
+  a=MAlloc(n*sizeof(F64));
+
+  //Pass2: Read F64s.
+  i=0;
+  cc=CmpCtrlNew(MStrPrint("#include \"%s\"",in_name));
+  while (Lex(cc))
+    if (cc->token==TK_F64)
+      a[i++]=cc->cur_f64;
+  CmpCtrlDel(cc);
+
+  QSortI64(a,n,&Compare); //Sort 64-bit sized values
+
+  //Save
+  doc=DocNew(out_name);
+  DocPrint(doc,"//This is sorted.\n");
+  for (i=0;i<n;i++)
+    DocPrint(doc,"%12.6f\n",a[i]);
+  DocWrite(doc);
+  DocDel(doc);
+
+  Free(a);
+}
+F64FileSortTXT("~/DemoUnsortedF64.DD.Z","~/DemoSortedF64.DD.Z");
+Type("~/DemoUnsortedF64.DD.Z");
+Type("~/DemoSortedF64.DD.Z");
+
+U0 F64FileSortDAT(U8 *in_name,U8 *out_name)
+{//File/CFile, ::/Demo/Dsk/DataBase.HC
+  I64 size;
+  F64 *a=FileRead(in_name,&size);
+  QSortI64(a,size/sizeof(F64),&Compare); //Sort 64-bit sized values
+  FileWrite(out_name,a,size);
+  Free(a);
+}
+F64FileSortDAT("~/DemoUnsortedF64.DATA.Z","~/DemoSortedF64.DATA.Z");
+
+U0 F64FileDumpDAT(U8 *in_name)
+{//File/CFile, ::/Demo/Dsk/DataBase.HC
+  I64 i,n,size;
+  F64 *a=FileRead(in_name,&size);
+  n=size/sizeof(F64);
+  "%s\n",in_name;
+  for (i=0;i<n;i++)
+    "%12.6f\n",a[i];
+  Free(a);
+}
+F64FileDumpDAT("~/DemoUnsortedF64.DATA.Z");
+F64FileDumpDAT("~/DemoSortedF64.DATA.Z");
+
+ diff --git a/public/Wb/Home/Src/Demo/Spy.HC.HTML b/public/Wb/Home/Src/Demo/Spy.HC.HTML new file mode 100755 index 0000000..1ca6169 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Spy.HC.HTML @@ -0,0 +1,93 @@ + + + + + + + + + + + +
+//Pass the task structure you
+//wish to spy upon.
+
+U0 SpyStkRep(CTask *task)
+{
+  CDoc *doc=DocDblBufStart;
+  while (!ScanChar && TaskValidate(task)) {
+    StkRep(task);
+    '\n';
+    "$BK,1$PRESS A KEY$BK,0$\n";
+    DocDblBufSwap;
+    Refresh;
+  }
+  if (DocPut==doc) DocDblBufSwap;
+  DocDblBufEnd;
+}
+
+U0 SpyCallerRep(CTask *task)
+{
+  CDoc *doc=DocDblBufStart;
+  while (!ScanChar && TaskValidate(task)) {
+    CallerRep(task->rbp,task);
+    '\n';
+    "$BK,1$PRESS A KEY$BK,0$\n";
+    DocDblBufSwap;
+    Refresh;
+  }
+  if (DocPut==doc) DocDblBufSwap;
+  DocDblBufEnd;
+}
+
+U0 Spy()
+{
+  I64 i;
+  CTask *task;
+
+  while (TRUE) {
+    task=Fs->next_task;
+    while (task!=Fs) {
+      "$MA+X,T=\"Task:%08X:%16ts\",LM=\"0x%08X\n\"$\n",
+            task,task->task_name,task;
+      task=task->next_task;
+    }
+    '\n';
+    task=GetI64("Task Addr: ",0);
+    if (TaskValidate(task)) {
+      "\n\n\t$BT,\"StkRep\",LM=\"1\n\"$\n\n\n"
+            "\n\n\t$BT,\"CallerRep\",LM=\"2\n\"$\n\n\n";
+      i=GetI64("",0);
+      if (i==1)
+        SpyStkRep(task);
+      else if (i==2)
+        SpyCallerRep(task);
+      else
+        break;
+    } else
+      break;
+  }
+  '\n';
+}
+
+Spy;
+
+ diff --git a/public/Wb/Home/Src/Demo/StkGrow.HC.HTML b/public/Wb/Home/Src/Demo/StkGrow.HC.HTML new file mode 100755 index 0000000..e96850b --- /dev/null +++ b/public/Wb/Home/Src/Demo/StkGrow.HC.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+I64 Recurse(I64 n)
+{
+  if (n)
+    return 1+CallStkGrow(0x800,0x1000000,&Recurse,n-1);
+  else
+    return 0;
+}
+
+I64 Recurse2(I64 n)
+{
+  if (n)
+    return 1+Recurse2(n-1);
+  else
+    return 0;
+}
+
+I64 Recurse3(I64 n,I64 lo,I64 hi)
+{
+  if (lo<=n<hi)
+    return 1+Recurse3(n-1,lo,hi);
+  else if (n)
+    return Recurse3(n-1,lo,hi);
+  else
+    return 0;
+}
+
+#define DEPTH   (2*1024*1024)
+
+U0 StkGrowDemo()
+{
+  F64 t0;
+
+  t0=tS;
+  "%X:%X\n",DEPTH,Recurse(DEPTH);
+  "Time:%7.5fs\n",tS-t0;
+
+  //If you know the max stack ahead of time...
+  //Recurse2's stack is 16 because you have 1 arg,
+  //a return addr and no local variables.
+  t0=tS;
+  "%X:%X\n",DEPTH,CallStkGrow(DEPTH*16+0x800,DEPTH*16+0x800,&Recurse2,DEPTH);
+  "Time:%7.5fs\n",tS-t0;
+
+  //CallStkGrow() works with multiple args.
+  t0=tS;
+  "%X:%X\n",DEPTH,CallStkGrow(DEPTH*32+0x800,DEPTH*32+0x800,
+        &Recurse3,DEPTH,1000,2000);
+  "Time:%7.5fs\n",tS-t0;
+}
+
+StkGrowDemo;
+
+//Be careful because you can fragment memory.
+
+ diff --git a/public/Wb/Home/Src/Demo/SubIntAccess.HC.HTML b/public/Wb/Home/Src/Demo/SubIntAccess.HC.HTML new file mode 100755 index 0000000..b5a2d4f --- /dev/null +++ b/public/Wb/Home/Src/Demo/SubIntAccess.HC.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+/*TempleOS has a feature that allows
+access to bytes and words of larger
+ints.
+
+See U64i union.
+ 
+The versions with "i" are internal data types.
+Use "I64" instead of "U64i" and you
+will have access to subbytes and
+subwords.
+
+Unfortunately, byte access causes the
+compiler to not use a reg for the
+variable.
+
+See ::/Demo/Lectures/FixedPoint.HC.
+*/
+
+I64 q=0xFEDCBA9876543210,q1;
+
+"q\t\t=%016X\n",q;
+q1=q.i16[2];
+"q.i16[2]\t=%016X\n",q1;
+q1=q.u8[5];
+"q.u8[5]\t\t=%016X\n",q1;
+q1=q.i32[1].u8[2];
+"q.i32[1].u8[2]\t=%016X\n",q1;
+q1=q.i32[0].i8[1];
+"q.i32[0].i8[1]\t=%016X\n",q1;
+
+ diff --git a/public/Wb/Home/Src/Demo/SubSwitch.HC.HTML b/public/Wb/Home/Src/Demo/SubSwitch.HC.HTML new file mode 100755 index 0000000..3b4be5a --- /dev/null +++ b/public/Wb/Home/Src/Demo/SubSwitch.HC.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+U0 SubSwitch()
+{
+  I64 i;
+  for (i=0;i<10;i++)
+    switch (i) {
+      case 0: "Zero ";  break;
+      case 2: "Two ";   break;
+      case 4: "Four ";  break;
+      start:
+        "[";
+        case 1: "One";  break;
+        case 3: "Three";break;
+        case 5: "Five"; break;
+      end:
+        "] ";
+        break;
+    }
+  '\n';
+}
+
+SubSwitch;
+
+ diff --git a/public/Wb/Home/Src/Demo/SuggestSpelling.HC.HTML b/public/Wb/Home/Src/Demo/SuggestSpelling.HC.HTML new file mode 100755 index 0000000..09a3de9 --- /dev/null +++ b/public/Wb/Home/Src/Demo/SuggestSpelling.HC.HTML @@ -0,0 +1,123 @@ + + + + + + + + + + + +
+/*This does a really crappy job of
+suggesting spellings.  Write a better
+one for fun.
+*/
+
+U8 *SuggestMatchForm(U8 *src)
+{
+  I64 ch,ch1=0;
+  U8 *res=MStrUtil(src,SUF_TO_UPPER),*dst;
+  dst=src=res;
+  while (ch=*src++)  {
+    if (!StrOcc("AEIOU",ch)) {
+      if (ch=='C') ch='K';
+      if (ch=='Z') ch='S';
+      if (ch!=ch1) //double chars to single
+        *dst++=ch;
+    }
+    ch1=ch;
+  }
+  *dst=0;
+  return res;
+}
+
+/*Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block; //definition offset in ::/Adam/AutoComplete/ACDefs.DATA
+*/
+
+Bool SuggestSpelling(U8 *word)
+{
+  U8 *dict=acd.word_lst,
+        *pf=SuggestMatchForm(word),
+        *wf;
+  I64 len=StrLen(pf),
+        num_cols=Fs->win_width/16,
+        col=0;
+  if (len)
+    while (*dict) {
+      wf=SuggestMatchForm(dict+1);
+      if (!StrNCmp(pf,wf,len)) {
+        "%16s",dict+1;
+        if (++col>=num_cols) {
+          col=0;
+          '\n';
+        }
+      }
+      Free(wf);
+      dict+=StrLen(dict+1)+4;
+    }
+  Free(pf);
+  '\n';
+  return ToBool(len);
+}
+
+U0 SuggestSpellingDemo()
+{
+  U8 *w;
+  while (TRUE) {
+    w=GetStr("Word:");
+    if (*w) {
+      SuggestSpelling(w);
+      Free(w);
+    } else
+      break;
+  }
+}
+
+//If you "Adam Include" this file, it will
+//install this command as a hot-key.
+
+U0 CtrlAltL(I64)
+{
+//ac.cur_word is only set if AutoComplete
+  //is running.
+  if (!TaskValidate(ac.task)) {
+    AutoComplete(ON);
+    Sleep(500);
+  }
+  PopUp("if (SuggestSpelling(ac.cur_word)) View;");
+}
+
+if (Fs!=adam_task)
+  SuggestSpellingDemo;
+else {
+  CtrlAltCBSet('L',&CtrlAltL,"Cmd /Suggest Spelling");
+//Appears in the Adam Task Window
+  "<CTRL-ALT-l> installed\n";
+}
+
+//Note: It would be more appropriate
+//to define a key in MyPutKey().
+
+ diff --git a/public/Wb/Home/Src/Demo/Templates/Game1.HC.HTML b/public/Wb/Home/Src/Demo/Templates/Game1.HC.HTML new file mode 100755 index 0000000..302b77a --- /dev/null +++ b/public/Wb/Home/Src/Demo/Templates/Game1.HC.HTML @@ -0,0 +1,121 @@ + + + + + + + + + + + +
+U0 DrawIt(CTask *task,CDC *dc)
+{
+}
+
+U0 AnimateTask(I64)
+{
+  while (TRUE) {
+    Sleep(10);
+  }
+}
+
+U0 Init()
+{
+}
+
+U0 CleanUp()
+{
+}
+
+U0 SongTask(I64)
+{
+  Fs->task_end_cb=&SndTaskEndCB;
+  MusicSettingsRst;
+  while (TRUE) {
+    Play("4AB5C");
+  }
+}
+
+U0 MyGame()
+{
+  I64 sc;
+  SettingsPush; //See SettingsPush
+  Fs->text_attr=YELLOW<<4+BLUE;
+  Fs->song_task=Spawn(&SongTask,NULL,"Song",,Fs);
+  AutoComplete;
+  WinBorder;
+  WinMax;
+  DocCursor;
+  DocClear;
+
+  MenuPush(
+        "File {"
+        "  Abort(,CH_SHIFT_ESC);"
+        "  Exit(,CH_ESC);"
+        "}"
+        "Play {"
+        "  Restart(,'\n');"
+        "  Up(,,SC_CURSOR_UP);"
+        "  Down(,,SC_CURSOR_DOWN);"
+        "  Left(,,SC_CURSOR_LEFT);"
+        "  Right(,,SC_CURSOR_RIGHT);"
+        "}"
+        );
+
+  Init;
+  Fs->animate_task=Spawn(&AnimateTask,NULL,"Animate",,Fs);
+  Fs->draw_it=&DrawIt;
+
+  try {
+    while (TRUE)
+      switch (GetKey(&sc)) {
+        case 0:
+          switch (sc.u8[0]) {
+            case SC_CURSOR_LEFT:
+              break;
+            case SC_CURSOR_RIGHT:
+              break;
+            case SC_CURSOR_UP:
+              break;
+            case SC_CURSOR_DOWN:
+              break;
+          }
+          break;
+        case '\n':
+          CleanUp;
+          Init;
+          break;
+        case CH_SHIFT_ESC:
+        case CH_ESC:
+          goto mg_done;
+      }
+mg_done: //Don't goto out of try
+  } catch
+    PutExcept;
+  SettingsPop;
+  CleanUp;
+  MenuPop;
+}
+
+MyGame;
+
+ diff --git a/public/Wb/Home/Src/Demo/Templates/Lex1.HC.HTML b/public/Wb/Home/Src/Demo/Templates/Lex1.HC.HTML new file mode 100755 index 0000000..017fd25 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Templates/Lex1.HC.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+U0 MyRead(U8 *filename)
+{
+  CCmpCtrl *cc=CmpCtrlNew(MStrPrint("#include \"%s\"",filename));
+  while (Lex(cc)) {
+    "%03d:",cc->token;
+    switch (cc->token) {
+        case TK_IDENT:          "IDENT:%s",cc->cur_str; break;
+        case TK_STR:            "STR:%s",cc->cur_str;   break;
+        case TK_CHAR_CONST:     "CHAR:%d",cc->cur_i64;  break;
+        case TK_I64:            "I64:%d",cc->cur_i64;   break;
+        case TK_F64:            "F64:%d",cc->cur_f64;   break;
+    }
+    '\n';
+  }
+  CmpCtrlDel(cc);
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/Templates/MultiCore1.HC.HTML b/public/Wb/Home/Src/Demo/Templates/MultiCore1.HC.HTML new file mode 100755 index 0000000..f3de0be --- /dev/null +++ b/public/Wb/Home/Src/Demo/Templates/MultiCore1.HC.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+#define NUM     100
+
+I64 mp_not_done_flags,grand_total;
+
+U0 MPRoutine(CDoc *doc)
+{
+  I64 i,sum=0,
+        lo=NUM*Gs->num/mp_cnt,          //This is how to divide a job
+        hi=NUM*(Gs->num+1)/mp_cnt;
+  for (i=lo;i<hi;i++)
+    sum+=i;
+  DocPrint(doc,"Core#%d:%d-%d:%d\n",Gs->num,lo,hi-1,sum);
+  lock {grand_total+=sum;}
+  LBtr(&mp_not_done_flags,Gs->num);
+}
+
+U0 Main()
+{
+  I64 i;
+  grand_total=0;
+  mp_not_done_flags=1<<mp_cnt-1;
+  for (i=0;i<mp_cnt;i++)
+    Spawn(&MPRoutine,DocPut,NULL,i);
+  while (mp_not_done_flags)
+    Yield;
+  "Grand total:%d\n",grand_total;
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Templates/ODE1.HC.HTML b/public/Wb/Home/Src/Demo/Templates/ODE1.HC.HTML new file mode 100755 index 0000000..4740c62 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Templates/ODE1.HC.HTML @@ -0,0 +1,74 @@ + + + + + + + + + + + +
+class MyMass:CMass
+{
+  F64 radius;
+};
+
+class MySpring:CSpring
+{
+};
+
+CMathODE *ode=NULL;
+
+U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
+{
+  MyMass *tmpm1,*tmpm2;
+
+  tmpm1=ode->next_mass;
+  while (tmpm1!=&ode->next_mass) {
+    tmpm2=tmpm1->next;
+    while (tmpm2!=&ode->next_mass) {
+      tmpm2=tmpm2->next;
+    }
+    tmpm1=tmpm1->next;
+  }
+}
+
+U0 Init()
+{
+  ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
+  ode->derive=&MyDerivative;
+  ode->drag_v2=0.002;
+  ode->drag_v3=0.00001;
+  ode->acceleration_limit=5e3;
+
+  QueIns(ode,Fs->last_ode);
+}
+
+U0 CleanUp()
+{
+  QueRem(ode);
+  QueDel(&ode->next_mass,TRUE);
+  QueDel(&ode->next_spring,TRUE);
+  ODEDel(ode);
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/Templates/Registry1.HC.HTML b/public/Wb/Home/Src/Demo/Templates/Registry1.HC.HTML new file mode 100755 index 0000000..bd62809 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Templates/Registry1.HC.HTML @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+RegDft("MyCompany/MyApp","F64 best_score=9999;\n");
+RegExe("MyCompany/MyApp");
+
+U0 Main()
+{
+  GetChar;
+  RegWrite("MyCompany/MyApp","F64 best_score=%5.4f;\n",best_score);
+}
+
+Main;
+
+ diff --git a/public/Wb/Home/Src/Demo/Templates/Util1.HC.HTML b/public/Wb/Home/Src/Demo/Templates/Util1.HC.HTML new file mode 100755 index 0000000..170c043 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Templates/Util1.HC.HTML @@ -0,0 +1,45 @@ + + + + + + + + + + + +
+U0 MyUtil(U8 *files_find_mask,U8 *fu_flags=NULL)
+{
+  I64 fuf_flags=0;
+  CDirEntry *tmpde,*tmpde1;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
+  while (tmpde) {
+    PutFileLink(tmpde->full_name);
+    '\n';
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/Templates/Util2.HC.HTML b/public/Wb/Home/Src/Demo/Templates/Util2.HC.HTML new file mode 100755 index 0000000..40fb7b8 --- /dev/null +++ b/public/Wb/Home/Src/Demo/Templates/Util2.HC.HTML @@ -0,0 +1,85 @@ + + + + + + + + + + + +
+I64 MyUtilDoc(CDoc *doc,I64 fuf_flags)
+{
+  Bool unlock=DocLock(doc);
+  I64 res=0;
+  CDocEntry *doc_e;
+  DocRecalc(doc);
+  doc_e=doc->head.next;
+  while (doc_e!=doc) {
+    res++;
+    doc_e=doc_e->next;
+  }
+  DocRecalc(doc);
+  if (unlock)
+    DocUnlock(doc);
+  return res;
+}
+
+I64 MyUtilFile(U8 *filename,I64 fuf_flags)
+{
+  I64 res;
+  CDoc *doc=DocRead(filename);
+  if (res=MyUtilDoc(doc,fuf_flags)) {
+    "%8d:%s\n",res,doc->filename.name;
+    DocWrite(doc);
+  }
+  DocDel(doc);
+  return res;
+}
+I64 MyUtilLst(CDirEntry *tmpde,I64 fuf_flags)
+{
+  I64 res=0;
+  CDirEntry *tmpde1;
+  while (tmpde) {
+    tmpde1=tmpde->next;
+    if (tmpde->attr & RS_ATTR_DIR) {
+      if (tmpde->sub) {
+        "Processing Directory: %s\n",tmpde->full_name;
+        res+=MyUtilLst(tmpde->sub,fuf_flags);
+      }
+    } else
+      res+=MyUtilFile(tmpde->full_name,fuf_flags);
+    DirEntryDel(tmpde);
+    tmpde=tmpde1;
+  }
+  return res;
+}
+I64 MyUtil(U8 *files_find_mask="*",U8 *fu_flags=NULL)
+{
+  I64 fuf_flags=0;
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+$");
+  ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+  return MyUtilLst(FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND),
+        fuf_flags&~FUG_FILES_FIND);
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/TimeIns.HC.HTML b/public/Wb/Home/Src/Demo/TimeIns.HC.HTML new file mode 100755 index 0000000..9331d31 --- /dev/null +++ b/public/Wb/Home/Src/Demo/TimeIns.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+/*Allows you to time insts.
+Results vary because the CPU does
+parallel and out-of-order execution.
+*/
+
+#define SAMPLE_SIZE     10000000
+
+U0 TimeIns()
+{
+  I64 i,start,end,overhead_time,test_time;
+  F64 d=5.0;
+
+  //Measure Loop Overhead
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++);
+  end=GetTSC;
+  overhead_time=end-start;
+  "\nOverhead Cycles:%12.6f\n",ToF64(overhead_time)/SAMPLE_SIZE;
+
+  start=GetTSC;
+  for (i=0;i<SAMPLE_SIZE;i++) {
+    #exe {PassTrace(0b10000000000);};
+//Time these insts
+    d*=1.00001;
+    #exe {PassTrace(0);};
+  }
+  end=GetTSC;
+  test_time=end-start;
+
+  "Measured Cycles:%12.6f\n",ToF64(test_time-overhead_time)/SAMPLE_SIZE;
+}
+
+TimeIns;
+TimeIns;
+TimeIns;
+
+ diff --git a/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/DemoInPage.DD.HTML b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/DemoInPage.DD.HTML new file mode 100755 index 0000000..1a1ae44 --- /dev/null +++ b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/DemoInPage.DD.HTML @@ -0,0 +1,49 @@ + + + + + + + + + + + +
+                          The Temple Operating System
+
+TempleOS File Downloads (100% Public Domain)
+
+TempleOS is a free, public domain, open source, x86_64, non-preemptive 
+multi-tasking, multi-cored, ring-0-only, single-address-map (identity-mapped), 
+non-networked, PC operating system.  Paging is, basically, not used.
+
+The CIA obsfucates to foil India, China, Russia and Korea.  They make things 
+more complicated than necessary.  TempleOS is more simple than necessary.  It is 
+obnoxiously simple.  If you look at this "Hello World" joke, you can see why I 
+capped the line count of TempleOS at 100,000.
+
+God said TempleOS must be perfect, so backward compatibility is not promised.
+
+I, Terry Davis, wrote all 80,849 lines of TempleOS over the last 20.6 years, 
+including the 64-bit compiler.  I have been a professional operating system 
+developer since 1990 when I worked on Ticketmaster's VAX OS.
+
+ diff --git a/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML new file mode 100755 index 0000000..eb1585a --- /dev/null +++ b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/HtmlGen.HC.HTML @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+/* This converts ::/Demo/ToHtmlToTXTDemo/DemoInPage.DD to
+an html document named "OutPage.html".
+
+Notice that an entry like $TX,"GOOGLE",HTML="http://www.google.com"$
+will be converted to text in the html with an html link.
+
+I cheated by hardcoding www.templeos.org as the website
+for TempleOS Links.  Why don't you copy
+::/Demo/ToHtmlToTXTDemo/ToHtml.HC to your /Home directory
+and modify it?  You are welcome to link to
+http://www.templeos.org if you want file that come on the
+TempleOS distribution.
+
+You can pass html meta data as args to ToHtml().
+*/
+
+Cd(__DIR__);;
+#include "ToHtml"
+
+ToHtml("DemoInPage.DD.Z","~/DemoOutPage");
+
+ diff --git a/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML new file mode 100755 index 0000000..879e810 --- /dev/null +++ b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/TXTGen.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+/* This converts ::/Demo/ToHtmlToTXTDemo/DemoInPage.DD to
+an plain ASCII text document named, "OutPage.DD".
+
+*/
+
+Cd(__DIR__);;
+
+ToTXT("DemoInPage.DD.Z","~/DemoOutPage");
+
+ diff --git a/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML new file mode 100755 index 0000000..8568ccd --- /dev/null +++ b/public/Wb/Home/Src/Demo/ToHtmlToTXTDemo/ToHtml.HC.HTML @@ -0,0 +1,420 @@ + + + + + + + + + + + +
+#help_index "DolDoc/Conversion"
+
+//See ::/Doc/Credits.DD.
+
+#define DOCET_UNDEF_COLOR       0x100000000
+#define DOCET_LINK_UNDERLINE    0x200000000
+U0 HtmlPutS(CDoc *doc,I64 u32_attr,I64 *_old_u32_attr,Bool underline_update,
+        U8 *st,I64 *_col,U8 *style_bitmap=NULL)
+{
+  U8 *ch,*ptr;
+  u32_attr&=0xFFFFFF00;
+  if (u32_attr&DOCET_INVERT)
+    u32_attr.u8[1]=(u32_attr.u8[1]&15)<<4|u32_attr.u8[1]>>4;
+  if (underline_update &&
+        !(u32_attr&DOCET_UNDERLINE) && *_old_u32_attr&DOCET_UNDERLINE) {
+    if (!(*_old_u32_attr&DOCET_LINK_UNDERLINE))
+      DocPrint(doc,"</u>");
+    *_old_u32_attr&=~DOCET_LINK_UNDERLINE;
+  }
+  if (!(u32_attr&DOCET_BLINK) && *_old_u32_attr&DOCET_BLINK)
+    DocPrint(doc,"</blink>");
+  if (u32_attr&0xFF00!=*_old_u32_attr&0xFF00) {
+    if (!(*_old_u32_attr&DOCET_UNDEF_COLOR))
+      DocPrint(doc,"</span>");
+    DocPrint(doc,"<span class=c%02X>",u32_attr.u8[1]);
+    if (style_bitmap)
+      LBts(style_bitmap,u32_attr.u8[1]);
+  }
+  if (u32_attr&DOCET_BLINK && !(*_old_u32_attr&DOCET_BLINK))
+    DocPrint(doc,"<blink>");
+  if (underline_update) {
+    if (u32_attr&DOCET_UNDERLINE && !(*_old_u32_attr&DOCET_UNDERLINE))
+      DocPrint(doc,"<u>");
+  } else //Keep same underline status.
+    u32_attr=u32_attr&~DOCET_UNDERLINE | *_old_u32_attr&DOCET_UNDERLINE;
+
+  *_old_u32_attr=u32_attr | *_old_u32_attr&DOCET_LINK_UNDERLINE;
+
+  while (ch=*st++) {
+    switch (ch) {
+      case '\t':
+        do {
+          DocPutKey(doc,CH_SPACE,0);
+          *_col=*_col+1;
+        } while (*_col&7);
+        break;
+
+      start:
+        case 'pi':      ptr="pi";       break;
+        case 'theta':   ptr="theta";    break;
+        case 'phi':     ptr="phi";      break;
+        case 'omega':   ptr="omega";    break;
+        case 'inf':     ptr="inf";      break;
+        case 'u':       ptr="u";        break;
+      end:
+        DocPrint(doc,ptr);
+        *_col=*_col+StrLen(ptr);
+        break;
+
+      start:
+        case CH_SHIFT_SPACE: ptr=" ";   break;
+        case '&':       ptr="&amp;";    break;
+        case '<':       ptr="&lt;";     break;
+        case '>':       ptr="&gt;";     break;
+        case '"':       ptr="&quot;";   break;
+      end:
+        DocPrint(doc,ptr);
+        *_col=*_col+1;
+        break;
+
+      default:
+        if (CH_SPACE<=ch<0x7F || ch=='\n')
+          DocPutKey(doc,ch,0);
+        else
+          DocPrint(doc,".");
+        *_col=*_col+1;
+    }
+  }
+}
+
+U8 *TOSLinkCvt2(U8 *filename,I64 line_num)
+{// ::/  --> http://www.templeos.org/Wb/
+//Make your own LinkCvt routine
+  U8 *res=NULL,*st;
+  if (filename) {
+    st=ExtChg(filename,"html");
+    if (st && StrLen(st)>3 && !StrNCmp(st+1,":/",2))
+      res=MStrPrint("http://www.templeos.org/Wb/%s#l%d",st+3,line_num);
+    Free(st);
+  }
+  return res;
+}
+
+U8 *URLBibleGateway(U8 *src)
+{
+  U8 buf[STR_LEN],*dst=buf;
+  if (!MemCmp(src,"BF:",3))
+    src+=3;
+  while (*src) {
+    if (*src==CH_SPACE || *src==',')
+      *dst++='+';
+    else
+      *dst++=*src;
+    src++;
+  }
+  *dst=0;
+  if (StrOcc(buf,'-'))
+    return MStrPrint(
+          "http://www.biblegateway.com/passage/?search=%s&version=NIV",buf);
+  else
+    return MStrPrint(
+          "http://www.biblegateway.com/verse/en/%s",buf);
+}
+
+U8 *TOSLinkCvt1(U8 *link_st)
+{
+  static CDoc *bible=NULL;
+  static I64 locks=0;
+  U8 *res=NULL,*filename,*needle;
+  I64 i,num;
+  if (link_st) {
+    switch (i=EdLinkCvt(link_st,&filename,&needle,&num)) {
+      case LK_FILE_LINE:
+      case LK_PLAIN_LINE:
+      case LK_FILE:
+        res=TOSLinkCvt2(filename,num);
+        break;
+      case -1:
+      case LK_DEF:
+      case LK_HELP_INDEX:
+      case LK_DOC:
+      case LK_DOC_ANCHOR:
+      case LK_DOC_FIND:
+      case LK_DOC_LINE:
+        break;
+      case LK_BIBLE_FIND:
+        while (LBts(&locks,0))
+          Yield;
+        if (!bible)
+          bible=Adam("DocRead(\"%s\");",filename);
+        if (DocFind(bible,num,needle))
+          res=URLBibleGateway(link_st);
+        LBtr(&locks,0);
+        break;
+      default:
+        if (DocFileEd(i,filename,needle,&num,EDF_UNCOLLAPSE|EDF_BAIL))
+          res=TOSLinkCvt2(filename,num);
+    }
+    Free(filename);
+    Free(needle);
+  }
+  return res;
+}
+
+public CDoc *Doc2Html(CDoc *doc_in,U8 *html_header=NULL,U8 *body_header=NULL,
+        U8 *body_footer=NULL,U8 *html_footer=NULL,Bool line_anchors=TRUE,
+        U8 (*link_cvt)(U8 *link_st)=&TOSLinkCvt1,Bool line_nums=FALSE)
+{//Cvt DolDocdoc to HTML file.
+  CDocEntry *doc_e,*style,*doc_e2;
+  I64 i,y,old_y=I64_MIN,col,old_u32_attr=DOCET_UNDEF_COLOR,old_attr,digits;
+  U32 *hl,*src;
+  U8 *st,st_2[2],*link_st,*style_bitmap=CAlloc(256/8);
+  CBGR48 p[COLORS_NUM];
+  GrPaletteGet(p);
+  CDoc *doc_out=DocNew;
+  Bool unlock_doc_in=DocLock(doc_in),no_bwd;
+
+  old_attr=doc_in->win_task->text_attr;
+  doc_in->win_task->text_attr=DOC_ATTR_DFT_TEXT;
+
+  for (i=0xF0;i<=0xFF;i++)
+    LBts(style_bitmap,i);
+
+  DocRecalc(doc_in,RECALCt_NORMAL|RECALCF_TO_HTML);
+
+  digits=Log10(doc_in->head.last->y+1)+1;
+
+  st_2[0]=0; st_2[1]=0;
+  doc_out->flags|=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
+
+  if (!html_header) html_header=
+          "<!DOCTYPE HTML>\n"
+          "<html>\n"
+          "<head>\n"
+          "<meta http-equiv=\"Content-Type\" "
+          "content=\"text/html;charset=US-ASCII\">\n"
+          "<meta name=\"generator\" content=\"TempleOS V5.03\">\n";
+  if (!body_header) body_header=
+          "<body>\n"
+          "<pre style=\"font-family:courier;font-size:10pt\">\n";
+  if (!body_footer) body_footer=
+          "</pre></body>\n";
+  if (!html_footer) html_footer=
+          "</html>\n";
+
+  DocPrint(doc_out,"%s",html_header);
+
+  DocPrint(doc_out,"<style type=\"text/css\">\n");
+  style=doc_out->cur_entry->last;
+  DocPrint(doc_out,
+        "</style>\n"
+        "</head>\n");
+  DocPrint(doc_out,"%s",body_header);
+
+  doc_e=doc_in->head.next;
+  col=doc_e->x;
+  y=doc_e->y;
+  while (doc_e!=doc_in) {
+    if (!(doc_e->de_flags&DOCEF_SKIP)) {
+      if (y!=old_y) {
+        if (line_anchors)
+          DocPrint(doc_out,"<a name=\"l%d\"></a>",y+1);
+        if (line_nums)
+          DocPrint(doc_out,"%0*d ",digits,y+1);
+        old_y=y;
+      }
+      while (y<doc_e->y) {
+        HtmlPutS(doc_out,doc_e->settings.final_u32_attr,&old_u32_attr,FALSE,
+              "\n",&col,style_bitmap);
+        if (++y!=old_y) {
+          if (line_anchors)
+            DocPrint(doc_out,"<a name=\"l%d\"></a>",y+1);
+          if (line_nums)
+            DocPrint(doc_out,"%0*d ",digits,y+1);
+          old_y=y;
+        }
+        col=0;
+      }
+
+      no_bwd=TRUE;
+      doc_e2=doc_e->next;
+      while (doc_e2!=doc_in && doc_e2->y==doc_e->y) {
+        if (doc_e2->x<doc_e->x) {
+          no_bwd=FALSE;
+          break;
+        }
+        doc_e2=doc_e2->next;
+      }
+
+      if (no_bwd)
+        while (col<doc_e->x)
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr&~DOCET_UNDERLINE,
+                &old_u32_attr,TRUE," ",&col,style_bitmap);
+
+      link_st=NULL;
+      if (doc_e->de_flags&DOCEF_HTML_LINK)
+        link_st=StrNew(doc_e->html_link);
+      else if (st=DocEntryLink(doc_in,doc_e)) {
+        link_st=link_cvt(st);
+        Free(st);
+      }
+
+      if (link_st) {
+        if (old_u32_attr&DOCET_UNDERLINE &&!(old_u32_attr&DOCET_LINK_UNDERLINE))
+          DocPrint(doc_out,"</u>");
+        if (old_u32_attr&DOCET_BLINK)
+          DocPrint(doc_out,"</blink>");
+        if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+          DocPrint(doc_out,"</span>");
+        old_u32_attr=DOCET_UNDEF_COLOR|DOCET_UNDERLINE|DOCET_LINK_UNDERLINE;
+        DocPrint(doc_out,"<a href=\"%s\">",link_st);
+      }
+
+      switch (doc_e->type_u8) {
+        case DOCT_TEXT:
+          if (doc_e->de_flags&DOCEF_HIGHLIGHT) {
+            if (doc_e->last==doc_in)
+              MemCpy(&doc_e->settings,&doc_in->settings_head,
+                    sizeof(CDocSettings));
+            else
+              MemCpy(&doc_e->settings,&doc_e->last->settings,
+                    sizeof(CDocSettings));
+            src=hl=DocHighlight(doc_e,doc_e->tag,StrLen(doc_e->tag),
+                  doc_e->type&0xFF00);
+            while (*src) {
+              st_2[0]=*src&0xFF;
+              HtmlPutS(doc_out,*src++,&old_u32_attr,TRUE,
+                    st_2,&col,style_bitmap);
+            }
+            Free(hl);
+          } else
+            HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                  &old_u32_attr,TRUE,doc_e->tag,&col,style_bitmap);
+          break;
+        case DOCT_TAB:
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr,&old_u32_attr,TRUE,
+                "\t",&col,style_bitmap);
+          break;
+        case DOCT_HTML_CODE:
+          if (old_u32_attr&DOCET_UNDERLINE &&
+                !(old_u32_attr&DOCET_LINK_UNDERLINE))
+            DocPrint(doc_out,"</u>");
+          if (old_u32_attr&DOCET_BLINK)
+            DocPrint(doc_out,"</blink>");
+          if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+            DocPrint(doc_out,"</span>");
+          old_u32_attr=DOCET_UNDEF_COLOR;
+          DocPrint(doc_out,"%s",doc_e->tag);
+          break;
+        case DOCT_SPRITE:
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                &old_u32_attr,TRUE,doc_e->tag,&col,style_bitmap);
+          HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                &old_u32_attr,TRUE,"/* Graphics Not Rendered in HTML */",
+                &col,style_bitmap);
+          break;
+        default:
+          if (doc_e->de_flags&DOCEF_TAG)
+            HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+                  &old_u32_attr,TRUE,doc_e->tag,&col,style_bitmap);
+      }
+      if (link_st) {
+        if (old_u32_attr&DOCET_UNDERLINE &&!(old_u32_attr&DOCET_LINK_UNDERLINE))
+          DocPrint(doc_out,"</u>");
+        if (old_u32_attr&DOCET_BLINK)
+          DocPrint(doc_out,"</blink>");
+        if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+          DocPrint(doc_out,"</span>");
+        DocPrint(doc_out,"</a>");
+        old_u32_attr=DOCET_UNDEF_COLOR|DOCET_UNDERLINE|DOCET_LINK_UNDERLINE;
+        Free(link_st);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  while (y++<doc_e->y) {
+    HtmlPutS(doc_out,doc_e->settings.final_u32_attr,
+          &old_u32_attr,TRUE,"\n",&col,style_bitmap);
+    col=0;
+  }
+  if (old_u32_attr&DOCET_UNDERLINE && !(old_u32_attr&DOCET_LINK_UNDERLINE))
+    DocPrint(doc_out,"</u>");
+  if (old_u32_attr&DOCET_BLINK)
+    DocPrint(doc_out,"</blink>");
+  if (!(old_u32_attr&DOCET_UNDEF_COLOR))
+    DocPrint(doc_out,"</span>");
+  old_u32_attr=DOCET_UNDEF_COLOR;
+  DocPrint(doc_out,"%s",body_footer);
+  DocPrint(doc_out,"%s",html_footer);
+
+  doc_out->cur_entry=style->next;
+  for (i=0;i<256;i++)
+    if (Bt(style_bitmap,i))
+      DocPrint(doc_out,
+            ".c%02X{color:#%02x%02x%02x;background-color:#%02x%02x%02x;}\n",
+            i,p[i&15].r>>8,p[i&15].g>>8,p[i&15].b>>8,
+            p[i/16].r>>8,p[i/16].g>>8,p[i/16].b>>8);
+  doc_out->cur_entry=&doc_out->head;
+  DocRecalc(doc_out);
+
+  doc_in->win_task->text_attr=old_attr;
+
+  if (unlock_doc_in)
+    DocUnlock(doc_in);
+  return doc_out;
+}
+
+#help_index "Cmd Line (Typically);DolDoc/Conversion;DolDoc/Cmd Line (Typically)"
+public U0 ToHtml(U8 *_in_name,U8 *_out_name=NULL,U8 *html_header=NULL,
+        U8 *body_header=NULL,U8 *body_footer=NULL,U8 *html_footer=NULL,
+        I64 width=80,Bool line_anchors=TRUE,
+        U8 (*link_cvt)(U8 *link_st)=&TOSLinkCvt1,Bool line_nums=FALSE)
+{//Convert DolDocfile to HTML.
+//Supply your own link_cvt routine.
+  U8 *in_name,*out_name;
+  CDoc *doc_in,*doc_out;
+
+  SettingsPush; //See SettingsPush
+  WinHorz(0,width-1); //Sets doc width for word wrap.
+
+  in_name=ExtDft(_in_name,"HC.Z");
+  if (_out_name)
+    out_name=ExtDft(_out_name,"html");
+  else
+    out_name=ExtChg(_in_name,"html");
+
+  doc_in=DocRead(in_name);
+  doc_out=Doc2Html(doc_in,html_header,body_header,body_footer,html_footer,
+        line_anchors,link_cvt,line_nums);
+  StrCpy(&doc_out->filename.name,out_name);
+
+  SettingsPop;
+
+  DocWrite(doc_out);
+  DocDel(doc_in);
+  DocDel(doc_out);
+  Free(in_name);
+  Free(out_name);
+}
+
+ diff --git a/public/Wb/Home/Src/Demo/WebLogDemo/WebLogRep.HC.HTML b/public/Wb/Home/Src/Demo/WebLogDemo/WebLogRep.HC.HTML new file mode 100755 index 0000000..b362a8a --- /dev/null +++ b/public/Wb/Home/Src/Demo/WebLogDemo/WebLogRep.HC.HTML @@ -0,0 +1,559 @@ + + + + + + + + + + + +
+#define DOWNLOAD_FILE1          "TOS_Distro.ISO"
+#define DOWNLOAD_FILE1_SIZE     16000000
+
+#define HOURS_MAX               (24*3)
+
+class LogStruct
+{
+  LogStruct *next,*last;
+  LogStruct *ip_num_left,*ip_num_right;
+  U32 ip_num,code;
+  I64 size;
+  U8 *file,*link;
+  CDate datetime;
+};
+
+class LinkStruct
+{
+  LinkStruct *left,*right;
+  U8 *link,*file;
+  I64 cnt;
+};
+
+class BlockedStruct
+{
+  BlockedStruct *next,*last;
+  U32 ip_num;
+};
+
+U0 LogStructDel(LogStruct *tmplg)
+{
+  Free(tmplg->file);
+  Free(tmplg->link);
+  Free(tmplg);
+}
+
+U0 PrsSingleLogFile(LogStruct *head,U8 *name,CDate *_dstart,CDate *_dend)
+{
+  CDoc *doc=DocRead(name,
+        DOCF_PLAIN_TEXT_TABS|DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next;
+  U8 *src,*src2,*mon_lst=Define("ST_MONTHS");
+  LogStruct *tmplg;
+  CDateStruct ds;
+  I64 i;
+  "%$Q\n",name;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      tmplg=CAlloc(sizeof(LogStruct));
+      try {
+        src=doc_e->tag;
+        tmplg->ip_num.u8[3]=Str2I64(src,10,&src);
+        if (*src++!='.') throw;
+        tmplg->ip_num.u8[2]=Str2I64(src,10,&src);
+        if (*src++!='.') throw;
+        tmplg->ip_num.u8[1]=Str2I64(src,10,&src);
+        if (*src++!='.') throw;
+        tmplg->ip_num.u8[0]=Str2I64(src,10,&src);
+
+        do if (!*src) throw;
+        while (*src++!='[');
+        MemSet(&ds,0,sizeof(CDateStruct));
+        ds.day_of_mon=Str2I64(src,10,&src);
+        if (*src++!='/') throw;
+        src2=src;
+        do if (!*src2) throw;
+        while (*src2++!='/');
+        * --src2=0;
+        ds.mon=1+LstMatch(src,mon_lst,LMF_IGNORE_CASE);
+        src=++src2;
+        ds.year=Str2I64(src,10,&src);
+        if (*src++!=':') throw;
+        ds.hour=Str2I64(src,10,&src);
+        if (*src++!=':') throw;
+        ds.min=Str2I64(src,10,&src);
+        if (*src++!=':') throw;
+        ds.sec=Str2I64(src,10,&src);
+        tmplg->datetime=Struct2Date(&ds);
+        if (*src++!=CH_SPACE) throw;
+        i=Str2I64(src,10,&src);
+        tmplg->datetime-=(i/100+i%100/60.0)*CDATE_FREQ*60*60;
+        if (!(Str2Date("1/1/2017")<=tmplg->datetime<Str2Date("1/1/2050")))
+          throw;
+        if (tmplg->datetime<*_dstart) *_dstart=tmplg->datetime;
+        if (tmplg->datetime>*_dend)   *_dend  =tmplg->datetime;
+
+        do if (!*src) throw;
+        while (*src++!=']');
+
+        if (*src++!=CH_SPACE) throw;
+        if (*src++!='\"') throw;
+        if (!StrNCmp(src,"GET ",4)) {
+          src2=src+=4;
+          do if (!*src2) throw;
+          while (*src2++!=CH_SPACE);
+          * --src2=0;
+          tmplg->file=StrNew(src);
+          src=++src2;
+
+          do if (!*src) throw;
+          while (*src++!='\"');
+
+          tmplg->code=Str2I64(src,10,&src);
+          if (*src++!=CH_SPACE) throw;
+          tmplg->size=Str2I64(src,10,&src);
+          if (*src++!=CH_SPACE) throw;
+
+          if (*src++!='\"') throw;
+          src2=src;
+          do if (!*src2) throw;
+          while (*src2++!='\"');
+          * --src2=0;
+          tmplg->link=StrNew(src);
+          src=++src2;
+
+          QueIns(tmplg,head->last);
+        } else if (!StrNCmp(src,"HEAD ",5)) {
+          LogStructDel(tmplg);
+        } else
+          throw;
+      } catch {
+        Fs->catch_except=TRUE;
+        "%$Q\n",doc_e->tag;
+        LogStructDel(tmplg);
+      }
+    }
+    doc_e=doc_e->next;
+  }
+  DocDel(doc);
+}
+
+LogStruct *PrsLogFiles(U8 *files_find_mask,CDate *_dstart,CDate *_dend)
+{
+  LogStruct *head=CAlloc(sizeof(LogStruct));
+  CDirEntry *tmpde=FilesFind(files_find_mask),*tmpde1=tmpde;
+  QueInit(head);
+  while (tmpde) {
+    PrsSingleLogFile(head,tmpde->full_name,_dstart,_dend);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+  return head;
+}
+
+U0 LogLstDel(LogStruct *head)
+{
+  LogStruct *tmplg=head->next,*tmplg1;
+  while (tmplg!=head) {
+    tmplg1=tmplg->next;
+    LogStructDel(tmplg);
+    tmplg=tmplg1;
+  }
+}
+
+U0 BlockedStructAdd(BlockedStruct *head,U32 ip_num)
+{
+  BlockedStruct *tmpb=CAlloc(sizeof(BlockedStruct));
+  tmpb->ip_num=ip_num;
+  QueIns(tmpb,head->last);
+}
+
+Bool IsBlocked(BlockedStruct *head,U32 ip_num)
+{
+  BlockedStruct *tmpb=head->next;
+  while (tmpb!=head) {
+    if (tmpb->ip_num==ip_num)
+      return TRUE;
+    tmpb=tmpb->next;
+  }
+  return FALSE;
+}
+
+U0 BlockIPNuip(LogStruct *head)
+{
+  BlockedStruct blocked_head;
+  LogStruct *tmplg=head->next,*tmplg1;
+
+  QueInit(&blocked_head);
+
+  BlockedStructAdd(&blocked_head,68<<24+227<<16+61<<8+6);
+
+  //pass 1: collect robot lst
+  while (tmplg!=head) {
+    if (StrIMatch("ROBOT",tmplg->file) &&
+          !IsBlocked(&blocked_head,tmplg->ip_num))
+      BlockedStructAdd(&blocked_head,tmplg->ip_num);
+    tmplg=tmplg->next;
+  }
+
+  //pass 2: removed blocked ip_nuip
+  tmplg=head->next;
+  while (tmplg!=head) {
+    tmplg1=tmplg->next;
+    if (IsBlocked(&blocked_head,tmplg->ip_num)) {
+      QueRem(tmplg);
+      LogStructDel(tmplg);
+    }
+    tmplg=tmplg1;
+  }
+
+  QueDel(&blocked_head);
+}
+
+Bool IsDownLoad(LogStruct *tmplg)
+{
+  if (StrMatch(DOWNLOAD_FILE1,tmplg->file)&&tmplg->size>=
+        DOWNLOAD_FILE1_SIZE)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool IsIndex(LogStruct *tmplg)
+{
+  if (!StrCmp(tmplg->file,"/index.html") || !StrCmp(tmplg->file,"/"))
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool IsKeeper(LogStruct *tmplg,CDate dstart,CDate dend)
+{
+  if (dstart<=tmplg->datetime<=dend && !StrOcc(tmplg->file,'?') &&
+    StrLen(tmplg->file)>2 && 'A'<=tmplg->file[1]<='Z' &&
+    tmplg->size && tmplg->file[StrLen(tmplg->file)-1]!='/' &&
+    (StrLen(tmplg->file)<3 || MemCmp(&tmplg->file[1],"Wb",2)) &&
+    (StrLen(tmplg->file)<7 || MemCmp(&tmplg->file[1],"Family",6))) {
+    return TRUE;
+
+}  else
+    return FALSE;
+}
+
+Bool IPNumTreeAdd(LogStruct **_head,LogStruct *tmplg)
+{
+  LogStruct *head;
+  if (UnusedStk<0x200) {
+    PrintErr("Stk Overflow");
+    throw;
+  }
+  if (head=*_head) {
+    if (tmplg->ip_num==head->ip_num)
+      return TRUE;
+    else if (tmplg->ip_num<head->ip_num)
+      return IPNumTreeAdd(&head->ip_num_left,tmplg);
+    else
+      return IPNumTreeAdd(&head->ip_num_right,tmplg);
+  } else {
+    tmplg->ip_num_left=NULL;
+    tmplg->ip_num_right=NULL;
+    *_head=tmplg;
+    return FALSE;
+  }
+}
+
+U0 LinkTreeAdd(LinkStruct **_root,LogStruct *tmplg)
+{
+  I64 i;
+  LinkStruct *root,*tmplk;
+  if (UnusedStk<0x200) {
+    PrintErr("Stk Overflow");
+    throw;
+  }
+  if (root=*_root) {
+    if (!(i=StrCmp(tmplg->link,root->link)))
+      root->cnt++;
+    else if (i<0)
+      LinkTreeAdd(&root->left,tmplg);
+    else
+      LinkTreeAdd(&root->right,tmplg);
+  } else {
+    tmplk=CAlloc(sizeof(LinkStruct));
+    tmplk->link=tmplg->link;
+    tmplk->cnt=1;
+    *_root=tmplk;
+  }
+}
+
+U0 FileTreeAdd(LinkStruct **_root,LogStruct *tmplg)
+{
+  I64 i;
+  LinkStruct *root,*tmplk;
+  if (UnusedStk<0x200) {
+    PrintErr("Stk Overflow");
+    throw;
+  }
+  if (root=*_root) {
+    if (!(i=StrCmp(tmplg->file,root->file)))
+      root->cnt++;
+    else if (i<0)
+      FileTreeAdd(&root->left,tmplg);
+    else
+      FileTreeAdd(&root->right,tmplg);
+  } else {
+    tmplk=CAlloc(sizeof(LinkStruct));
+    tmplk->file=tmplg->file;
+    tmplk->cnt=1;
+    *_root=tmplk;
+  }
+}
+
+U0 LinkTreeDel(LinkStruct *root)
+{
+  if (root) {
+    LinkTreeDel(root->left);
+    LinkTreeDel(root->right);
+    Free(root);
+  }
+}
+
+U0 LinkTreeTraverse(LinkStruct *root)
+{
+  if (root) {
+    LinkTreeTraverse(root->left);
+    "%3d:%$Q\n",root->cnt,root->link;
+    LinkTreeTraverse(root->right);
+  }
+}
+
+U0 FileTreeDel(LinkStruct *root)
+{
+  if (root) {
+    FileTreeDel(root->left);
+    FileTreeDel(root->right);
+    Free(root);
+  }
+}
+
+U0 FileTreeTraverse(LinkStruct *root)
+{
+  if (root) {
+    FileTreeTraverse(root->left);
+    "%3d:%$Q\n",root->cnt,root->file;
+    FileTreeTraverse(root->right);
+  }
+}
+
+U0 DownLoadRep(LogStruct *head,CDate dstart,CDate dend)
+{
+  I64 i,j,cnt,dups,
+        hours_start,hours_end,*hour_cnts,*dup_cnts,
+        days_start,days_end,*day_cnts,*day_dup_cnts;
+  LogStruct *tmplg=head->next,*dup_head=NULL;
+  LinkStruct *link_root=NULL;
+  CDateStruct ds;
+
+  i=dstart*24;hours_start=i.u32[1];
+  i=dend  *24;hours_end =i.u32[1];
+
+  days_start=(dstart+local_time_offset)>>32;
+  days_end  =(dend+local_time_offset)>>32;
+
+  hour_cnts=CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  dup_cnts =CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  day_cnts =CAlloc((days_end-days_start+1)*sizeof(I64));
+  day_dup_cnts=CAlloc((days_end-days_start+1)*sizeof(I64));
+  dups=cnt=0;
+  while (tmplg!=head) {
+    if (IsKeeper(tmplg,dstart,dend) && IsDownLoad(tmplg)) {
+      i=tmplg->datetime*24;
+      hour_cnts[i.u32[1]-hours_start]++;
+      day_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+      cnt++;
+      if (IPNumTreeAdd(&dup_head,tmplg)) {
+        day_dup_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+        dup_cnts[i.u32[1]-hours_start]++;
+        dups++;
+      }
+      LinkTreeAdd(&link_root,tmplg);
+    }
+    tmplg=tmplg->next;
+  }
+
+  "\n\nDownloads of /TOS_Distro.ISO\n";
+  for (i=dstart;i<=dend;i+=1<<32)
+    "%D  Dups:%5d  Total:%5d  Uniques:%5d\n",i,
+          day_dup_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start]-
+          day_dup_cnts[(i+local_time_offset)>>32-days_start];
+
+  "\n\nDownloads of /TOS_Distro.ISO\n"
+        "'-' is a dup.  '+' is not a dup.\n";
+  if (hours_end-hours_start>=HOURS_MAX)
+    i=hours_end-HOURS_MAX+1;
+  else
+    i=hours_start;
+  for (;i<=hours_end;i++) {
+    Date2Struct(&ds,i<<32/24+local_time_offset);
+    "%D %02d: ",i<<32/24,ds.hour;
+    for (j=0;j<dup_cnts[i-hours_start];j++)
+      '-';
+    for (;j<hour_cnts[i-hours_start];j++)
+      '+';
+    '\n';
+  }
+  "Total:%d  Dups:%d  Uniques:%d\n",cnt,dups,cnt-dups;
+
+  "\n\nDownloads of /TOS_Distro.ISO\n";
+  LinkTreeTraverse(link_root);
+  '\n';
+
+  LinkTreeDel(link_root);
+  Free(hour_cnts);
+  Free(dup_cnts);
+  Free(day_cnts);
+  Free(day_dup_cnts);
+}
+
+U0 FileRep(LogStruct *head,CDate dstart,CDate dend)
+{
+  LogStruct *tmplg=head->next;
+  LinkStruct *file_root=NULL;
+  while (tmplg!=head) {
+    if (IsKeeper(tmplg,dstart,dend))
+      FileTreeAdd(&file_root,tmplg);
+    tmplg=tmplg->next;
+  }
+  "\n\nFile Hits\n";
+  FileTreeTraverse(file_root);
+  '\n';
+  FileTreeDel(file_root);
+}
+
+U0 IndexRep(LogStruct *head,CDate dstart,CDate dend)
+{
+  I64 i,j,cnt,dups,
+        hours_start,hours_end,*hour_cnts,*dup_cnts,
+        days_start,days_end,*day_cnts,*day_dup_cnts;
+  LogStruct *tmplg=head->next,*dup_head=NULL;
+  LinkStruct *link_root=NULL;
+  CDateStruct ds;
+
+  i=dstart*24;hours_start=i.u32[1];
+  i=dend  *24;hours_end =i.u32[1];
+
+  days_start=(dstart+local_time_offset)>>32;
+  days_end  =(dend+local_time_offset)>>32;
+
+  hour_cnts=CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  dup_cnts =CAlloc((hours_end-hours_start+1)*sizeof(I64));
+  day_cnts =CAlloc((days_end-days_start+1)*sizeof(I64));
+  day_dup_cnts=CAlloc((days_end-days_start+1)*sizeof(I64));
+  dups=cnt=0;
+  while (tmplg!=head) {
+    if (IsKeeper(tmplg,dstart,dend) && IsIndex(tmplg)) {
+      i=tmplg->datetime*24;
+      hour_cnts[i.u32[1]-hours_start]++;
+      day_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+      cnt++;
+      if (IPNumTreeAdd(&dup_head,tmplg)) {
+        day_dup_cnts[(tmplg->datetime+local_time_offset)>>32-days_start]++;
+        dup_cnts[i.u32[1]-hours_start]++;
+        dups++;
+      }
+      LinkTreeAdd(&link_root,tmplg);
+    }
+    tmplg=tmplg->next;
+  }
+
+  "\n\nHits on /index.html\n"
+        "'-' is a dup.  '+' is not a dup.\n";
+  for (i=dstart;i<=dend;i+=1<<32)
+    "%D  Dups:%5d  Total:%5d  Uniques:%5d\n",i,
+          day_dup_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start],
+          day_cnts[(i+local_time_offset)>>32-days_start]-
+          day_dup_cnts[(i+local_time_offset)>>32-days_start];
+
+  "\n\nHits on /index.html\n";
+  if (hours_end-hours_start>=HOURS_MAX)
+    i=hours_end-HOURS_MAX+1;
+  else
+    i=hours_start;
+  for (;i<=hours_end;i++) {
+    Date2Struct(&ds,i<<32/24+local_time_offset);
+    "%D %02d: ",i<<32/24,ds.hour;
+    for (j=0;j<dup_cnts[i-hours_start];j++)
+      '-';
+    for (;j<hour_cnts[i-hours_start];j++)
+      '+';
+    '\n';
+  }
+  "Total:%d  Dups:%d  Uniques:%d\n",cnt,dups,cnt-dups;
+
+  "\n\nHits on /index.html\n";
+  LinkTreeTraverse(link_root);
+  '\n';
+
+  LinkTreeDel(link_root);
+  Free(hour_cnts);
+  Free(dup_cnts);
+  Free(day_cnts);
+  Free(day_dup_cnts);
+}
+
+U0 WebLogRep(U8 *mask,U8 *output_filename)
+{
+  LogStruct *head;
+  CDate dstart=I64_MAX,dend=I64_MIN;
+
+  DocMax;
+
+  head=PrsLogFiles(mask,&dstart,&dend);
+  if (dstart>dend)
+    PrintErr("No Data.\n");
+  else {
+    dstart=GetDate("Start(%D):",dstart);
+    dend  =GetDate("End  (%D):",dend);
+    BlockIPNuip(head);
+
+    DocClear;
+    "$WW,0$";
+    IndexRep(head,dstart,dend);
+    FileRep(head,dstart,dend);
+    DownLoadRep(head,dstart,dend);
+
+    StrCpy(DocPut->filename.name,output_filename);
+    DocWrite(DocPut,TRUE);
+
+    "$WW,1$";
+  }
+  LogLstDel(head);
+}
+
+#if __CMD_LINE__
+Cd(__DIR__);;
+WebLogRep("*.log*","~/DemoWebLog.DD.Z");
+#endif
+
+ diff --git a/public/Wb/Home/Src/Demo/WebLogDemo/WebLogScramble.HC.HTML b/public/Wb/Home/Src/Demo/WebLogDemo/WebLogScramble.HC.HTML new file mode 100755 index 0000000..15af2d2 --- /dev/null +++ b/public/Wb/Home/Src/Demo/WebLogDemo/WebLogScramble.HC.HTML @@ -0,0 +1,100 @@ + + + + + + + + + + + +
+U8 key[4][256];
+
+U0 InitKey()
+{
+  I64 i,j;
+  for (i=0;i<4;i++) {
+    for (j=0;j<256;j++)
+      key[i][j]=j;
+    for (j=0;j<255;j++)
+      SwapU8(&key[i][j],&key[i][j+RandU32%(256-j)]);
+  }
+}
+
+U0 LogScrambleFile(U8 *name)
+{
+  CDoc *doc=DocRead(name,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
+  CDocEntry *doc_e=doc->head.next;
+  I64 i;
+  U32 num;
+  U8 *st,*st2;
+  "Scrambling: %s\n",name;
+  while (doc_e!=doc) {
+    if (doc_e->type_u8==DOCT_TEXT) {
+      st=MAlloc(StrLen(doc_e->tag)+1);
+      st2=MAlloc(StrLen(doc_e->tag)+1);
+      StrFirstRem(doc_e->tag," ",st);
+
+      for (i=3;i>=0;i--) {
+        StrFirstRem(st,".",st2);
+        num.u8[i]=key[i][Str2I64(st2)&255];
+      }
+
+      Free(st);
+      Free(st2);
+
+      st=MStrPrint("%d.%d.%d.%d %s",num.u8[3],num.u8[2],
+            num.u8[1],num.u8[0],doc_e->tag);
+      Free(doc_e->tag);
+      doc_e->tag=st;
+    }
+    doc_e=doc_e->next;
+  }
+  DocWrite(doc);
+  DocDel(doc);
+}
+U0 WebLogScramble(U8 *files_find_mask)
+{
+  CDirEntry *tmpde=FilesFind(files_find_mask,FUF_RECURSE|FUF_JUST_FILES),
+        *tmpde1=tmpde;
+  InitKey;
+  while (tmpde) {
+    LogScrambleFile(tmpde->full_name);
+    tmpde=tmpde->next;
+  }
+  DirTreeDel(tmpde1);
+}
+
+U0 LogScrambleDemo()
+{
+  U8 *dirname;
+  Cd(__DIR__);
+  dirname=DirCur;
+  ST_WARN_ST "This will scramble all .log files in '%s'.\n\n",dirname;
+  Free(dirname);
+  if (AreYouSure)
+    WebLogScramble("*.log*");
+}
+
+LogScrambleDemo;
+
+ diff --git a/public/Wb/Home/Src/Demo/WordSearch.HC.HTML b/public/Wb/Home/Src/Demo/WordSearch.HC.HTML new file mode 100755 index 0000000..b0c604b --- /dev/null +++ b/public/Wb/Home/Src/Demo/WordSearch.HC.HTML @@ -0,0 +1,184 @@ + + + + + + + + + + + +
+//Simple and fancy way of searching
+
+//See ::/Apps/Vocabulary/VocabQuiz.HC.Z
+//for another example of dictionary usage.
+
+#define ROWS_NUM        20
+#define COLS_NUM        20
+#define DIM_MAX MaxI64(ROWS_NUM,COLS_NUM)
+
+U8 m[ROWS_NUM][COLS_NUM];
+
+U0 Init()
+{
+  I64 x,y;
+  for (y=0;y<ROWS_NUM;y++)
+    for (x=0;x<COLS_NUM;x++)
+      m[y][x]='A'+RandU16%26;
+}
+
+U0 Display()
+{
+  I64 x,y;
+  for (y=0;y<ROWS_NUM;y++) {
+    for (x=0;x<COLS_NUM;x++)
+      '' m[y][x];
+    '\n';
+  }
+}
+
+U0 GetWord(U8 *dst,I64 x,I64 y,I64 dx,I64 dy)
+{
+  while (0<=x<COLS_NUM && 0<=y<ROWS_NUM) {
+    *dst++=m[y][x];
+    y+=dy;
+    x+=dx;
+  }
+  *dst=0;
+}
+
+//************************************
+U0 Search(I64 dx,I64 dy)
+{
+  I64 x,y,i,n;
+  U8 buf[DIM_MAX+1],*ptr;
+  for (y=0;y<ROWS_NUM;y++)
+    for (x=0;x<COLS_NUM;x++) {
+      GetWord(buf,x,y,dx,dy);
+      n=StrLen(buf);
+      for (i=n;i>2;i--) {
+        buf[i]=0;
+        if ((ptr=ACDWordPtAt(buf)) && *ptr++==ACD_WORD_CHAR &&
+              !StrICmp(ptr,buf)) {
+          "%s ",buf;
+        }
+      }
+    }
+}
+
+U0 SimpleWordSearch()
+{
+  Search(1,0);
+  Search(0,1);
+  Search(-1,0);
+  Search(0,-1);
+  Search(1,1);
+  Search(-1,-1);
+  Search(1,-1);
+  Search(-1,1);
+  '\n';
+}
+
+//************************************
+U8 words[ROWS_NUM*COLS_NUM*8][DIM_MAX+1];
+U8 *word_ptrs[ROWS_NUM*COLS_NUM*8];
+
+U0 CollectWords(I64 dx,I64 dy,I64 *_n)
+{
+  I64 x,y,n=*_n;
+  for (y=0;y<ROWS_NUM;y++)
+    for (x=0;x<COLS_NUM;x++) {
+      GetWord(&words[n],x,y,dx,dy);
+      word_ptrs[n]=&words[n];
+      n++;
+    }
+  *_n=n;
+}
+
+I64 WordsCompare(U8 *e1,U8 *e2)
+{
+  return StrCmp(e1,e2);
+}
+
+/*Fmt of word lst entry:
+  U8 ACD_WORD_CHAR
+  U8 word[] with terminating zero
+  I16 block; //definition offset in ::/Adam/AutoComplete/ACDefs.DATA
+*/
+
+U0 DisplayWords(I64 n)
+{
+  I64 i=0,k;
+  U8 *w1,*w2,*dict=acd.word_lst;
+  for (i=0;i<n;i++)
+    while (*dict) {
+      w1=word_ptrs[i];
+      w2=dict+1;
+      while (*w2 && *w1==ToUpper(*w2)) {
+        w1++;
+        w2++;
+      }
+      if (ToUpper(*w2)>*w1)
+        break;
+      if (!*w2) {
+        if (StrLen(dict+1)>2) {
+          k=i;
+          while (k<n && !StrNICmp(word_ptrs[k++],dict+1,StrLen(dict+1)))
+            "%s ",dict+1;
+        }
+        w2=dict+1;
+        while (!StrICmp(w2,dict+1))
+          dict+=StrLen(dict+1)+4;
+      } else
+        dict+=StrLen(dict+1)+4;
+    }
+}
+
+U0 FancyWordSearch()
+{
+  I64 n=0;
+  CollectWords(1,0,&n);
+  CollectWords(0,1,&n);
+  CollectWords(-1,0,&n);
+  CollectWords(0,-1,&n);
+  CollectWords(1,1,&n);
+  CollectWords(-1,-1,&n);
+  CollectWords(1,-1,&n);
+  CollectWords(-1,1,&n);
+  QSortI64(word_ptrs,n,&WordsCompare);
+  DisplayWords(n);
+  '\n';
+}
+
+//************************************
+U0 WordSearch()
+{
+  Init;
+  Display;
+  '\n';
+  SimpleWordSearch;
+  FancyWordSearch;
+}
+
+WordSearch;
+
+ diff --git a/public/Wb/Home/Src/Doc/AboutTempleOS.DD.HTML b/public/Wb/Home/Src/Doc/AboutTempleOS.DD.HTML new file mode 100755 index 0000000..4058dba --- /dev/null +++ b/public/Wb/Home/Src/Doc/AboutTempleOS.DD.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+                                    TempleOS
+
+
+Websites:
+www.templeos.org
+
+Owner/President:
+Terry A. Davis
+
+
+ +8144 Sickle Lane +Las Vegas, NV 89128 +(702)254-4223 + +tdavis@templeos.org + + +About Me: + +I was a National Merit Scholar with a 1440 SAT at Arizona State University. I +have a bachelor's in Computer System Engineering from ASU, basically, embedded +systems, and a master's in Electrical Engineering from ASU, control systems. I +worked as a software, hardware and mechanical engineer at Ticketmaster from +1990-1996. + +I designed a 3 axis stepper-motor-driven milling machine 1996-1997 with a +CAD/CAM package for a company I started called Home Automation and Robotic +Equipment. + +
+ +I worked for a company named Xytec Corp. 1997-1999. We made FPGA-based image +processing equipment. I wrote SimStructure from 2000-2001 for H.A.R.E. I +worked as head software/electrical engineer for a company called Graphic +Technologies, 2001-2002, making replacement chips for toner printer cartridges +so they could be refilled. + +Credits: +See ::/Doc/Credits.DD. + +
+ diff --git a/public/Wb/Home/Src/Doc/Asm.DD.HTML b/public/Wb/Home/Src/Doc/Asm.DD.HTML new file mode 100755 index 0000000..7d34c33 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Asm.DD.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+                                   Assembler
+
+See ::/Compiler/OpCodes.DD for opcodes.  They're not standard.  Some invalid 
+insts are not flagged and some valid insts are not implemented. 16-bit asm 
+support is limited.
+
+Here are example inst formats:
+        ADD     RAX,I64 FS:DISP[RSI+RDI*8]
+        ADD     RAX,I64 [DISP]
+
+$ Current compiler output pos (inst ptr).  Even works in HolyC expressions.
+
+$ works in classes.
+  class MyFun
+  {
+    $=-16;
+    I64 local1;
+    I64 local2;
+    $=$+256;
+    I64 crazy;
+  };
+
+LABEL::
+  Defines an exported glbl label.
+
+LABEL:
+  Defines an non-exported glbl label.
+
+@@LABEL:
+  Defines a local label with scope valid between two global labels.
+
+DU8, DU16, DU32, DU64
+  Define BYTE, WORD, DWORD or QWORD. Can be used with DUP() and ASCII strings.  
+For your convenience, the ASCII strings do not have terminating zeros.  Define 
+cmds must end with a semicolon.
+
+USE16, USE32, USE64
+
+IMPORT sym1name, sym2name;
+
+LIST, NOLIST
+
+ALIGN num, fill_byte
+  Align to num boundary and fill with fill_byte.
+
+ORG num
+  Set code addr for JIT or set module Load() addr -- has 16-byte CBinFile header 
+and patch table trailing.
+
+BINFILE "FileName.BIN";
+
+See Assembly Language, ::/Demo/Asm/AsmAndC1.HC, ::/Demo/Asm/AsmAndC2.HC and 
+::/Demo/Asm/AsmAndC3.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/AutoComplete.DD.HTML b/public/Wb/Home/Src/Doc/AutoComplete.DD.HTML new file mode 100755 index 0000000..c219a94 --- /dev/null +++ b/public/Wb/Home/Src/Doc/AutoComplete.DD.HTML @@ -0,0 +1,55 @@ + + + + + + + + + + + +
+AutoComplete is the LTGRAY window on the right of the scrn.  ACInit() collects 
+words from all text files in subdirectories.  Normally, the call to ACInit() is 
+in HomeSys.HC.  It provides auto-complete for typing, jump-to-code and 
+jump-to-dictionary functionality.
+
+<ALT-SHIFT-A>   Closes the LTGRAY AutoComplete window.
+<ALT-a>         Opens the LTGRAY AutoComplete window.
+
+<CTRL-SHIFT-F1> Jumps to the source code for 1st symbol in the window.
+<CTRL-SHIFT-F2> Jumps to the source code for 2nd symbol in the window.
+<CTRL-SHIFT-Fn> Jumps to the source code for n-th symbol in the window.
+<CTRL-F1>       Autocompletes the 1st symbol in the window.
+<CTRL-F2>       Autocompletes the 2nd symbol in the window.
+<CTRL-Fn>       Autocompletes the n-th symbol in the window.
+<CTRL-SHIFT-1>  Jumps to the dictionary for 1st symbol in the window.
+<CTRL-SHIFT-2>  Jumps to the dictionary for 2nd symbol in the window.
+<CTRL-SHIFT-n>  Jumps to the dictionary for n-th symbol in the window.
+<CTRL-1>        Autocompletes the 1st dictionary word in the window.
+<CTRL-2>        Autocompletes the 2nd dictionary word in the window.
+<CTRL-n>        Autocompletes the n-th dictionary word in the window.
+
+If you have the raw Project Gutenberg dictionary file, you can generate the 
+TempleOS processed dictionary files with the stand-alone program 
+::/Adam/AutoComplete/ACDictGen.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/Bit.DD.HTML b/public/Wb/Home/Src/Doc/Bit.DD.HTML new file mode 100755 index 0000000..8b95802 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Bit.DD.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+
+These take a pointer to a bit field.
+Bt:     Bit Test
+Bts:    Bit Test and Set to one
+Btr:    Bit Test and Rst to zero
+Btc:    Bit Test and Compliment (toggle)
+BEqu:   Set bit to value.
+
+Bit operations are "atomic", no interrupt between the reading and writing the 
+bit, important when multitasking.  For multicore use "locked" forms.
+
+These don't take a pointer, but the actual field.
+Bsf:    Bit Scan Fwd (Pos of first low one bit or -1)
+Bsr:    Bit Scan Rev (Pos of first high one bit or -1)
+BCnt:   Bit Cnt (Cnt of set bits)
+
+ diff --git a/public/Wb/Home/Src/Doc/BlkChain.DD.HTML b/public/Wb/Home/Src/Doc/BlkChain.DD.HTML new file mode 100755 index 0000000..f56dbae --- /dev/null +++ b/public/Wb/Home/Src/Doc/BlkChain.DD.HTML @@ -0,0 +1,75 @@ + + + + + + + + + + + +
+                                  Block Chain
+
+There was a technique on the Commodore 64 where disk blocks were chained 
+together with a block pointer at the end of each block.  This is far inferior to 
+having a file allocation table, as in FAT32.
+
+The RedSea file system does not allow files to grow because it only has an 
+allocation bitmap and not a FAT table.  This "flaw" is by design.  I am 
+intentionally crippling this operating system, making it a toy with the wisdom 
+that this will prevent commercialization and corruption.  The toy spirit of the 
+operating system will be preserved going into the future.  The vision for this 
+operating system was a modern Commodore 64, which was a fun toy.
+
+Doing whole file operations is the TempleOS way of doing thinks.  It is the 
+simplest and, ironically, the fastest.  It is obnoxious in the characteristic 
+way that TempleOS is obnoxious, flaunting massive modern resources in a way that 
+makes old programmers protest.
+
+Doing whole file operations will sabotage efforts to change the 640x480 
+resolution and violate the ban on multimedia.  When doing large, whole-file 
+operations, immediately memory fragmentation is a serious problem, but not so 
+for allocations in the range under a Meg (with occasional larger ones).
+
+The file compression scheme in TempleOS only works on whole file operations and 
+the DolDoc format cannot have text tacked onto the end, since binary data is at 
+the end.
+
+I don't want to spoil fun, so of course I offer a way to get awesome performance 
+that is, ironically, superior.  FBlkRead() and FBlkWrite() allow you to read a 
+block offset from the start of a file.  Since files are all contiguous, this is 
+incredibly efficient.  You just have to declare the desired file size when you 
+create it with FOpen() and cannot change it.  See ::/Demo/Dsk/DataBase.HC.
+
+If you like, you are encouraged to to do raw BlkRead() and BlkWrite() directly 
+on a drive.  Just get a pointer to a CDrv with Let2Drv() and you are on your 
+way!  Your computer is supposed to be a fun toy!  You can make an entire 
+partition used for a database, or invent a file system.
+
+On the whole, the RedSea file system with its whole-file-only limitation bring 
+beautiful harmony.  It beautifully captures the spirit of TempleOS with 
+simplicity and, ironic speed, since contiguous is fastest.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+
+ diff --git a/public/Wb/Home/Src/Doc/Boot.DD.HTML b/public/Wb/Home/Src/Doc/Boot.DD.HTML new file mode 100755 index 0000000..84569c2 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Boot.DD.HTML @@ -0,0 +1,142 @@ + + + + + + + + + + + +
+                                  Booting A PC
+
+TempleOS only supports traditional BIOS booting, not the newer technique, UEFI.  
+This document describes BIOS booting.
+
+When you turn-on (power-up) a computer or you do a hardware reset, the computer 
+starts executing the BIOS.  Sometimes, you must change the BIOS boot order to 
+boot the device you want.
+
+The BIOS loads a boot sector from CD/DVD, hard disk or whatever.  The boot 
+sector runs in 16-bit real mode and often loads-in a second file that's bigger 
+if it can't be done by just one sector.  It's a safe bet that boot sectors are 
+hand-coded assembly language.  Most boot sectors use the BIOS to load-in the 
+next stage.
+
+Not only do boot sectors have a size limit, 512 bytes or 2048 bytes for CD/DVD, 
+the files they load have to fit within 640K because they run in 16-bit mode.  
+This means they usually can't just load the whole operating system and start it 
+running.  Some boot loaders, like Grub, have a capability of switching modes 
+before handing-off control to the operating system.  The operating system must 
+load the rest of itself.  With TempleOS, the ::/Kernel.BIN.C file is loaded by 
+the boot sector.  I try to put a minimum in the Kernel Module, so that it will 
+always fit in 640K.  When Kernel.BIN runs, it switches to 32-bit mode, then, to 
+64-bit mode allowing access to more memory.  Then, it loads in the rest of 
+TempleOS by executing ::/StartOS.HC.
+
+All the boot related code for TempleOS is in the /Adam/Opt/Boot directory.
+
+BootDVD.HC      CD/DVD boot sector.
+BootDVDIns.HC   Prep for CD/DVD install by creating /0000Boot/0000Kernel.BIN.C.
+If you are curious about CD/DVDs, see DskISORedSea.HC.  To make a custom 
+bootable CD/DVD, look here Bootable CD.
+
+BootMHD.HC      Stage 1 Master HD boot loader.
+BootMHD2.HC     Stage 2 Master HD boot loader.
+BootMHDIns.HC   Installs Master HD boot loader.
+BootMHD goes on block zero.  /0000Boot/BootMHD2.BIN.C is stored as a file in a 
+partition, risky and unusual, since most master boot loaders place stage 2 in a 
+gap that's not in any partition.  BootMHD2 displays a menu and boots a 
+partition.
+
+BootHD.HC       HD partition boot record.
+BootHDIns.HC    Installs HD partition boot record.
+BootHD is the boot record for a TempleOS partition.  Each partition has its own 
+partition boot record, the first block of the partition.
+
+My boot records don't access directories because that would make them too big 
+for one block and would make them depend on a file system layout.  Instead, they 
+get patched with the LBA, logical block addresses, to load files.  To update 
+with a new TempleOS kernel, you must create a ::/Kernel.BIN.C binary file and 
+patch the boot loader so it knows the LBA blocks to load.  Therefore, you 
+usually recompile the kernel and update the boot sector at the same time with  
+BootHDIns().  BootMHDIns() will install a master boot loader.
+
+With TempleOS, ::/Kernel.BIN.C loads ::/Compiler/Compiler.BIN so it can work 
+with source code from then on.  It compiles start-up scripts beginning with 
+::/StartOS.HC into the Adam Task's memory including the code in the /Adam and /H
+ome directories.
+
+It is possible to do a fast reboot without doing a hardware reset.  You might do 
+this when working on ::/Kernel.BIN.C or your start-up scripts when you want to 
+compile them effect.  See BootRAM().
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Home/Src/Doc/CharOverview.DD.HTML b/public/Wb/Home/Src/Doc/CharOverview.DD.HTML new file mode 100755 index 0000000..095a0a9 --- /dev/null +++ b/public/Wb/Home/Src/Doc/CharOverview.DD.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+                                 Char Overview
+
+A Character is a single byte holding an ASCII code for a letter, num or sym.  
+The TempleOS term is a U8.
+
+Standard ASCII values range from 0 to 127.  Values below 32 are ctrl key's.  So, 
+an ASCII #3 is a <CTRL-c>.  TempleOS uses a few nonstandard values below 32.  
+See Char Definitions.
+
+ASCII #5  is the cursor location in a saved file.
+ASCII #28 is <SHIFT-ESC>.
+ASCII #31 is a <SHIFT-SPACE>.
+
+TempleOS ASCII is 8-bit instead of 7-bit, so it also uses the range from 
+128-255.  Press <CTRL-ALT-a> to see shapes for 128-255.  Technically, <CTRL-ALT-
+a> are scrn codes.
+
+A Key is typically specified with a scan code.  TempleOS scan codes contain the 
+key value in the lowest U8, and flags in the upper 3 bytes.  See 
+Scan Code Flags and Scan Codes.
+
+TempleOS stores scan codes in 8 bytes.
+  Byte 0   is the code.  NumPad keys, SHIFT, ALT, CTRL and GUI keys combined.
+  Byte 1-3 are flags
+
+The upper 4-bytes are copied from lower 4-bytes.
+  Byte 4   is the code.  Left, Right and NumPad keys distinct.
+  Byte 5-7 are flags
+
+Run the program ::/Demo/MsgLoop.HC to examine scan code.  Press <CTRL-SHIFT-l> 
+and "Insert ASCII/ScanCode".
+
+See Key Allocations and CKbdStateGlbls.
+
+A String is a bunch of ASCII characters terminated with a zero.
+
+ diff --git a/public/Wb/Home/Src/Doc/Charter.DD.HTML b/public/Wb/Home/Src/Doc/Charter.DD.HTML new file mode 100755 index 0000000..b802d17 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Charter.DD.HTML @@ -0,0 +1,158 @@ + + + + + + + + + + + +
+                                TempleOS Charter
+
+Why did they make Solomon's Temple?  It was a direction to look, to focus on, a 
+special place for meditation, to do offerings, a community center, a home to 
+God's beauty, that encouraged love of God.  People cherished God's temple, 
+beautifying it with gold and all fine things to show love of God, as great 
+cathedrals were decorated with astounding, awe-striking intricate art and 
+gargoyles, incredible devotion to God with hours of effort, toiling and 
+slaving-away for the glory of God, for families with children to see 
+stained-glass windows and tomes with ridiculously elaborate calligraphy to show 
+love of God, from a people who did little else but show love toward God, lived 
+in dire conditions by today's standards, yet with so much difficulty 
+scraping-by, found the time to devote even all free-time to God!
+
+
+1 Kings 6:21 (King James)
+
+     6:21 So Solomon overlaid the house within with pure gold: and he made
+     a partition by the chains of gold before the oracle; and he overlaid
+     it with gold.
+     
+     6:22 And the whole house he overlaid with gold, until he had finished
+     all the house: also the whole altar that was by the oracle he overlaid
+     with gold.
+     
+     6:23 And within the oracle he made two cherubims of olive tree, each
+     ten cubits high.
+
+
+* TempleOS is God's official temple.  Just like Solomon's temple, this is a 
+community focal point where offerings are made and God's oracle is consulted.
+
+* God said 640x480 16 color graphics is a covenant like circumcision.  Children 
+will do offerings.  Think of 16 colors like the Simpson's cartoons.  In the 
+future, even if one GPU were universal, we would still keep 640x480 16 color and 
+not use GPU acceleration.  Graphics operations should be transparent, not hidden 
+in a GPU.
+
+* God said to use a single-voice 8-bit signed MIDI-like sample for sound.  God 
+does not want death screams, perhaps, because God has PTSD or soldiers have 
+PTSD.  (Imagine wounded on battlefields.) 
+
+* God said His temple must be perfect.  We don't think twice about breaking 
+compatibility.  God said we do a seven year release cycle.  I say the PC 
+hardware follows a 49 year, jubilee cycle, like broadcast TV upgrades.
+
+* The vision is the same usage model and niche as the Commodore 64 -- a 
+non-networked, simple machine where programming was the goal, not just a means 
+to an end.  However, it is modern, 64-bit and multi-cored.  It is special 
+purpose, not general purpose, so some things it will not do.  Also, it's a 
+kayak, not a Titanic. The priority is user developers, not 3rd party developers.
+
+* We do not put any hooks for future changes.  "Perfect" means we always act as 
+though it is final, for all time.  Microsoft allowed the Windows BMP file format 
+to adapt to the future and it became grotesque.
+
+* Low line count is the highest good, so it is easy to learn the whole thing.  
+Users should see the light at the end of the tunnel.  One file system, for 
+example, is better than many file systems.
+
+* There is a limit of 100,000 lines of code for all time, not including 
+applications and demos.  Code comments count, however.  Currently, there are 
+80,849 lines of code.  3rd party libraries are banned because they circumvent 
+the intent of this limit.  The vision is a Commodore 64 ROM -- a fixed core API 
+that is the only dependency of applications.  Dependency on components and 
+libraries creates a hell that is no longer blissful.
+
+* The metric for resolving all TempleOS code governance issues is how fast the 
+compiler compiles itself and the kernel with BootHDIns().  The HolyC language 
+should be changed to optimize this metric, as I did when I changed type casting 
+from prefix standard C to postfix HolyC, but we need a rule to prevent 
+degenerating into a brainfuck language.
+ 
+* Minimal abstraction is a goal.  Sheep are fools.  They always respect a design 
+that is more complicated than another.  Any genius can make it complicated.  
+Like in physics, it takes a supra-genius to make it simple.
+
+* It is for one platformc -- x86_64 desktop PC compatibles, more like 
+super-computers than battery efficient wimpy mobiles.
+
+* All hardware access will be done through x86 IN/OUT instructions, not PCI 
+drivers.  A frame buffer for VGA is an exception.
+
+* One driver for each class of device.  Limited exceptions are allowed.  With 
+divergent device capabilities, it is a nightmare for user applications and what 
+is gained?  A three buuton mouse is like a leg you cannot put weight on.
+
+* Ring-0-only.  Everything runs in kernel mode, including user applications.
+
+* Full access to everything.  All memory, I/O ports, instructions, and similar 
+things must never be off limits.  All functions, variables and class members 
+will be accessible.  There are no C++ public/private protections and all 
+functions, even secondary ones in the kernel, can be called.
+
+* Single-address-map as though paging is not used.  Long mode requires paging, 
+however, so the nearest thing is keeping all memory identity-mapped.
+
+* No networking, so malware is not an issue.
+
+* No encryption or passwords.  Files are compressed, not encrypted.
+
+* Free and public domain.
+
+* 100% open source with all source included.
+
+* Documents are not for printing.  They're dynamic, intended for the scrn.
+
+* Just one 8x8 fixed-width font.  No Unicode, just Extended ASCII.  Other 
+countries can make their own versions.  The versions should be just for one 
+language and platform.
+
+* No multimedia.  Sounds and images will be primarily calculated in real-time, 
+not fetched from storage.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+* "The Simpsons" is a trademark owned by Fox.
+* "Windows" is a trademark owned by MicroSoft Corp.
+
+
+
+                              Possible Amendments
+
+The compiler's parser makes RISC code which it optimizes to CISC.  I discovered 
+this does not matter because the CPU converts it back to RISC and schedules it, 
+internally.  A TempleOS zealot with more zeal than I, might say we should save 
+lines-of-code by removing the CISC optimizing.
+
+ diff --git a/public/Wb/Home/Src/Doc/CmdLineOverview.DD.HTML b/public/Wb/Home/Src/Doc/CmdLineOverview.DD.HTML new file mode 100755 index 0000000..05fd4a7 --- /dev/null +++ b/public/Wb/Home/Src/Doc/CmdLineOverview.DD.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+                             Command Line Overview
+
+The cmd line feeds into the HolyC compiler line-by-line as you type.  A stmt 
+outside a function executes immediately.  Remember to add a semicolon.
+
+Look-up the function headers with AutoComplete by hitting <CTRL-SHIFT-F1> after 
+typing the first few letters.
+
+Click Here to see the directory cmd header.  It accepts default args from C++.
+
+>Dir("*.DD.Z");
+
+If you don't have args, you don't need parenthesis.
+
+>Dir;
+
+Directories are referenced with / not \.  There is a current directory, but not 
+a path.  To run a program, you typically #include it.  There are several 
+shortcuts for #includeing files.  Right-click or hit <ENTER> on a directory 
+listing or press <F5> while editing.
+
+>Ed("NewFile.HC.Z");    Invokes the editor. See Doc Link Type.
+
+Most filenames end in .Z because they are stored compressed.
+
+Drives are specified with a letter.  The boot drive is specified with a ':'.  
+The home dir drive is specified with a '~'.
+
+>Drv('B');      B drive
+
+The drive can be specified in a Cd() command as in:
+
+>Cd("B:/Tmp");  B drive
+>Cd("::/Demo"); Boot drive
+
+The home directory is specified with a '~'.
+
+>Cd("~/Psalmody");      See ::/Home dir.
+
+If a file is not found, .Z is added or removed and a search is done, again.  If 
+a file is still not found, all parent directories are searched.
+
+You can place macros in your PersonalMenu for Cd() commands.  <CTRL-m> to access 
+your menu.
+
+>Find("needle","/Demo/*.HC.Z;*.DD.Z;"); See File Utils.
+
+Cmd Line Routines
+
+Take Tour
+
+ diff --git a/public/Wb/Home/Src/Doc/Comm.HC.HTML b/public/Wb/Home/Src/Doc/Comm.HC.HTML new file mode 100755 index 0000000..72312db --- /dev/null +++ b/public/Wb/Home/Src/Doc/Comm.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+/* RS232 serial ports no longer exist.
+Be sure to Adam Include this by placing
+it in your start-up scripts.
+*/
+
+#help_index "Comm"
+
+#define UART_THR                0
+#define UART_RDR                0
+#define UART_BRDL               0
+#define UART_IER                1
+#define UART_BRDH               1
+#define UART_IIR                2
+#define UART_LCR                3
+#define UART_MCR                4
+#define UART_LSR                5
+#define UART_MSR                6
+
+#define COMf_ENABLED    0
+class CComm
+{
+  I64   base,
+        flags;
+  CFifoU8 *RX_fifo;
+  CFifoU8 *TX_fifo;
+} comm_ports[5];
+
+U0 CommHndlr(I64 port)
+{
+  CComm *c=&comm_ports[port];
+  I64 b=0,stat;
+  if (Bt(&c->flags,COMf_ENABLED)) {
+    stat=InU8(c->base+UART_IIR);
+    if (stat & 4)       //RX
+      FifoU8Ins(c->RX_fifo,InU8(c->base+UART_RDR));
+    if (stat & 2) {     //TX
+      if (FifoU8Rem(c->TX_fifo,&b))
+        OutU8(c->base+UART_THR,b);
+      else
+        OutU8(c->base+UART_IER,1); //RX but no THR empty
+    }
+  }
+}
+
+interrupt U0 IRQComm3()
+{
+  CommHndlr(2);
+  CommHndlr(4);
+  OutU8(0x20,0x20);
+}
+
+interrupt U0 IRQComm4()
+{
+  CommHndlr(1);
+  CommHndlr(3);
+  OutU8(0x20,0x20);
+}
+
+U0 CommInit()
+{
+  MemSet(&comm_ports,0,sizeof(comm_ports));
+  comm_ports[1].base=0x3F8;
+  comm_ports[2].base=0x2F8;
+  comm_ports[3].base=0x3E8;
+  comm_ports[4].base=0x2E8;
+  IntEntrySet(0x23,&IRQComm3);
+  IntEntrySet(0x24,&IRQComm4);
+}
+CommInit;
+
+public CComm *CommInit8n1(I64 port,I64 baud)
+{
+  CComm *c=&comm_ports[port];
+
+  PUSHFD
+  CLI
+  if (LBts(&c->flags,COMf_ENABLED)) {
+    FifoU8Del(c->RX_fifo);
+    FifoU8Del(c->TX_fifo);
+  }
+  c->RX_fifo=FifoU8New(256);
+  c->TX_fifo=FifoU8New(256);
+  OutU8(c->base+UART_LCR,0);    //Set for IER
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_LCR,0x80); //Enable baud rate control
+  OutU8(c->base+UART_BRDL,(0x180/(baud/300)) & 0xFF);   //LSB
+  OutU8(c->base+UART_BRDH,(0x180/(baud/300)) / 256);    //MSB
+  OutU8(c->base+UART_LCR,3);    //8-none-1
+
+  InU8(c->base+UART_RDR);       //read garbage
+  InU8(c->base+UART_LSR);
+
+  OutU8(c->base+UART_MCR,4);
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_MCR,0xA);  //out2 and rts
+  OutU8(0x21,InU8(0x21) & (0xFF-0x18)); //Enable 8259 IRQ 3 & 4
+  OutU8(c->base+UART_IER,1);    //RX but no THR empty
+  POPFD
+
+  return c;
+}
+
+public U0 CommPutChar(I64 port,U8 b)
+{
+  CComm *c=&comm_ports[port];
+  PUSHFD
+  CLI
+  FifoU8Ins(c->TX_fifo,b);
+  OutU8(c->base+UART_IER,3);    //RX and THR empty
+  POPFD
+  Sleep(10); //!!! Remove this line!!!  Linux echo_socket is too slow.
+}
+
+U0 CommPutS(I64 port,U8 *st)
+{
+  I64 b;
+  while (b=*st++)
+    CommPutChar(port,b);
+}
+
+public U0 CommPutBlk(I64 port,U8 *buf,I64 cnt)
+{
+  while (cnt--)
+    CommPutChar(port,*buf++);
+}
+
+public U0 CommPrint(I64 port,U8 *fmt,...)
+{
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CommPutS(port,buf);
+  Free(buf);
+}
+
+ diff --git a/public/Wb/Home/Src/Doc/CompilerOverview.DD.HTML b/public/Wb/Home/Src/Doc/CompilerOverview.DD.HTML new file mode 100755 index 0000000..0f4c387 --- /dev/null +++ b/public/Wb/Home/Src/Doc/CompilerOverview.DD.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+                                 Compiler Index
+
+::/Doc/Asm.DD
+
+::/Doc/Directives.DD
+
+::/Doc/Options.DD
+
+::/Doc/PreProcessor.DD
+
+::/Doc/ScopingLinkage.DD
+
+See Hello World.
+
+ diff --git a/public/Wb/Home/Src/Doc/Credits.DD.HTML b/public/Wb/Home/Src/Doc/Credits.DD.HTML new file mode 100755 index 0000000..0ee38aa --- /dev/null +++ b/public/Wb/Home/Src/Doc/Credits.DD.HTML @@ -0,0 +1,113 @@ + + + + + + + + + + + +
+                                    Credits
+
+I, Terry A. Davis, wrote all of TempleOS over the past 20.6 years (full-time).  
+It can run on some bare metal 64-bit PC's from about 2005-2010 with no layering, 
+libraries, tools, modules or anything from other sources.  Otherwise, you run it 
+in a virtual machine, like VMware, QEMU or VirtualBox.  It is independent and 
+stands alone.  It has no networking, so it certainly doesn't call home.  100% of 
+the src code is including on all distro's, from the kernel to the compiler to 
+the boot loaders!  It is public domain, not GPL.
+
+*) ::/Kernel/FontStd.HC, is taken from FreeDOS.  It's public domain.
+
+*) ::/Kernel/FontCyrillic.HC, is taken from OrientDisplay without permission.
+
+*) ATA Reg and Cmd Definitions are originally from Linux.  Later, I got the 
+spec.
+
+*) The heap algorithm, ::/Kernel/Mem/MAllocFree.HC, is adapted from one I saw at 
+Ticketmaster when I worked on their VAX operating system.
+
+*) The LZW compression algorithm, ::/Kernel/Compress.HC, came from a magazine 
+and I implemented it when I worked for Ticketmaster.
+
+*) The adaptive-step-size-Runge-Kutta algorithm, ::/Adam/AMathODE.HC, is adapted 
+from the book, Numeric Recipies in C.
+
+*) The mountain in some games is from http://www.public-domain-photos.com.  The 
+wolf in BlackDiamond is also from there.  I took watermarked photos and 
+converted to 16 color.
+
+*) The FAT32 file system is owned by MicroSoft.
+
+*) A few features were inspired by MATLAB, such as ans in expressions at the 
+command-line.  There is a lot of MSDOS , Windows, VAXTMOS (VAX Ticketmaster 
+O.S.) and Unix inspiration, too, such as drive letters, command names, etc.
+
+*) I included PCIDevice Lst File.
+
+*) Thanks to whoever wrote this CppHtml.HC.Z.  I'm a novice on web stuff and you 
+helped me with html.  See ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+*) I looked at bootable CD boot sects, but didn't learn anything, finding it 
+easier to make my own.
+
+*) I think I got my original PC speaker code from Borland C.
+
+*) I found PS/2 keyboard and mouse code on the net and documentation.  My code 
+is very different.  I found VGA reg info on the net.
+
+*) Thanks to http://www.osdev.org for a couple tips.
+
+*) God told me to stick with 640x480 16 color and single-voice 8-bit signed 
+MIDI-like sample for sound.   He kept me from zombie-walking into making child 
+windows like Windows.  Instead, I made one window per task with no child 
+windows.  He also guided my progress, very obviously.
+
+*) I got Webster's Dictionary and The King James Bible from Project Gutenberg.
+
+*) John Carmack inspired me to use "Clamp" as a name instead of "Limit".  He 
+inspired me to use "needle" and "haystack" as names.  He inspired me to simplify 
+my Frames-Per-Second code.
+
+*) Bill Gates inspired me to add comments to my Help & Index.
+
+*) I hired an artist, Cody Rigby, for $3,000 worth of pixel art.
+
+*) Erik van der Karbargenbok wrote /Downloads shell scripts -- gw.
+
+*) The random number generator is from Donald Knuth in the wikipedia entry for 
+Linear_congruential_generator.
+
+
+* "MSDOS", "Windows", "MovieMaker", "MS Paint" and "FAT32" are trademarks owned 
+by MicroSoft Corp.
+* "SiteBuilder" is a trademark owned by Yahoo! Inc.
+* "MagicISO" is a trademark owned by MagicISO Corp.
+* "MATLAB" is a trademark owned by The Math Works, Inc.
+* "FreeDOS" is a trademark owned by Jim Hall.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VAX" is a trademark owned by Digital Equipment Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "VAXTMOS" is a trademark owned by Ticketmaster.
+
+ diff --git a/public/Wb/Home/Src/Doc/Ctrls.DD.HTML b/public/Wb/Home/Src/Doc/Ctrls.DD.HTML new file mode 100755 index 0000000..a6691b8 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Ctrls.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+To create a TempleOS graphic ctrl, you define callback functions and insert a 
+CCtrl structure in the CTask queue.  See ::/Demo/Graphics/Slider.HC, 
+::/Demo/Graphics/ScrollBars.HC and TermBttnNew.  There is a template-code ctrl 
+generator, if you press <CTRL-SHIFT-L>.
+
+ diff --git a/public/Wb/Home/Src/Doc/Customize.DD.HTML b/public/Wb/Home/Src/Doc/Customize.DD.HTML new file mode 100755 index 0000000..d00bed8 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Customize.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+
+* You can adjust the mouse movement rate by setting global vars in your start-up 
+file.  See mouse scale.
+
+* You can set your local time zone by setting the local_time_offset global var 
+in a start-up file.  It's units are CDATE_FREQ.  See local time.
+
+* Get rid of this msg here.
+
+ diff --git a/public/Wb/Home/Src/Doc/CutCorners.DD.HTML b/public/Wb/Home/Src/Doc/CutCorners.DD.HTML new file mode 100755 index 0000000..f1f9a9e --- /dev/null +++ b/public/Wb/Home/Src/Doc/CutCorners.DD.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+                                  Cut Corners
+
+There are a few places where I cut corners in the interest of not junking-up 
+code.  This is part of the TempleOS mentality.  I try not to let stupid legacy 
+compatibility issues enter and junk-up TempleOS.
+
+* I made my type-casting operator post-fix because it makes the compiler way 
+cleaner.
+
+* TempleOS does not figure-out FAT32 short name alias numbers.  FAT32DirNew().  
+It can cause hard drive corruption, so I might have to do it.  It would really 
+take a lot of junky code for this hatefully, detestable, legacy issue.  "Please 
+don't make me ruin my beautiful shiny-new TempleOS with that!"  I am also not 
+enthused about FAT32 because it is in patent limbo.  FAT32 might get removed 
+from TempleOS.  There is the RedSea  64-bit file system that works perfectly 
+well.  FAT32 is useful, however, because it assists in transferring between dual 
+booted operating systems.
+
+* I changed the asm opcodes names to remove the ambiguity between insts with 
+different numbers of arguments, making my assembler simpler and I did minimal 
+16-bit asm support, since 64-bit is what you should be using, unless you're 
+doing a boot loader.
+
+* There are no user-controlled file-sharing locks.  However, the drive and file 
+system have locks and concurrent operations should be fine. 
+
+* A hidden window is never refreshed.  Certain tasks are never done, therefore.  
+During refresh, the entry count limit of the document buffer is, normally, 
+checked and enforced.  If you print to the command-line in a task whose window 
+is covered, no limit on buffer exists and it will alloc memory for the document 
+buffer until the system runs out of memory and crashes.
+
+* Even if a local function variable is declared less than 64 bits, the compiler 
+does calculations with 64-bit.
+
+* Print() uses StrPrintJoin().  You cannot use vastly over-sized fields for %f.
+
+* GrEllipse3() is broken on transformations.
+ 
+ diff --git a/public/Wb/Home/Src/Doc/D3.DD.HTML b/public/Wb/Home/Src/Doc/D3.DD.HTML new file mode 100755 index 0000000..6016b8b --- /dev/null +++ b/public/Wb/Home/Src/Doc/D3.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+TempleOS has a class for 3 dimensional points consisting of F64s.  HolyC is not 
+C++ -- it does not support passing or returning values from functions which are 
+not 64-bits, therefore, it can't be implemented with operator overloading.  
+Making all function args and returns 64-bit is a core prinicple of TempleOS.
+
+As a courtesy, most of the CD3 functions return the addr of the destination 
+vect, so you can nestle calls.  They do not alloc new space for the destination 
+vect.
+
+ diff --git a/public/Wb/Home/Src/Doc/Date.DD.HTML b/public/Wb/Home/Src/Doc/Date.DD.HTML new file mode 100755 index 0000000..4e1c23d --- /dev/null +++ b/public/Wb/Home/Src/Doc/Date.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Dates are 32-bit signed ints representing the number of days since the birth of 
+Christ.  Negative values represent B.C.E. dates.
+
+ diff --git a/public/Wb/Home/Src/Doc/DbgFunSeg.DD.HTML b/public/Wb/Home/Src/Doc/DbgFunSeg.DD.HTML new file mode 100755 index 0000000..943a43c --- /dev/null +++ b/public/Wb/Home/Src/Doc/DbgFunSeg.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Use %p to print a pointer with FunSeg+Offset or use %P to print a link to a 
+FunSeg+Offset.
+ 
+ diff --git a/public/Wb/Home/Src/Doc/DbgOverview.DD.HTML b/public/Wb/Home/Src/Doc/DbgOverview.DD.HTML new file mode 100755 index 0000000..ad8231f --- /dev/null +++ b/public/Wb/Home/Src/Doc/DbgOverview.DD.HTML @@ -0,0 +1,102 @@ + + + + + + + + + + + +
+                               Debugging Overview
+
+* You can enter the debugger with Dbg() or <CTRL-ALT-d>.  You might enter the 
+debugger through a fault.  Enter G() or G2() to continue execution.  Place a 
+call to Dbg() in your code at fatal error points to enter the debugger.  If you 
+see a stk dump, record the label+offset and unassemble, U(). U(_RIP); 
+
+* U(&FunName+offset) to unassemble mem or Uf("FunName") to unassemble a 
+function. U(_RIP-16);
+
+* While debugging, you specify addresses of assembly routines with just the 
+label, as in _MALLOC+0x20.  You specify HolyC function names with & before 
+functions as in &Print+0x10.
+
+* I use progress1-progress4 for debugging because they show on the wallpaper.  
+They're just global int vars.
+
+* You can use AdamLog() to send text to the Adam Task window.  It works like 
+Print().  I never use that.  Instead, I use RawPrint().
+
+* D(), DocD(), RawD() to do 16 column hex dump mem with numbering from zero.  
+With DocD the values are updated continually and you can alter mem by editing.
+
+* Dm(), DocDm(), RawDm() to do 16 column hex dump mem with addresses showing.
+
+* Da() to do one column address dump (for stk, etc.) with symbolic addresses.
+
+* Dr() dumps regs.  You can display and modify regs in the debugger with 
+var-like labels, _RAX, _RBX, etc.
+
+* ClassRep() and the dynamic version ClassRepD() can be used to dump structures.
+
+* Prof() and ProfRep() provide code profiling.  See ::/Demo/InFile/InProfile.IN 
+(This is an InFile.)
+
+* Use RawPrint() to print debug info bypassing the window framework.  You pass 
+these routines a count in milliseconds for how long it should be displayed.  You 
+can use Raw(TRUE) to make all output bypass the window framework.  The WinMgr 
+runs on Core0 and will overwrite raw text from other cores when it updates the 
+scrn.
+
+* Use SysDbg() to set a flag which you can read with IsSysDbg() when you wish to 
+trigger some debug activity.  It's just a handy simple flag, nothing fancy.
+
+* There are flags for various trace options that can help debugging when there 
+are compiler bugs.  Often, you place them in #exe{} blocks.
+  
+  Echo() turns on or off raw data going into the lexical analyzer.
+  
+  Trace() unassembles code generated from the HolyC compiler.
+  
+  PassTrace() shows intermediate code coming-out after optimization.  The bits 
+  ctrl which passes are displayed.
+
+
+* There is a heap check utility which can find leaks.  Use HeapLog(), 
+HeapLogAddrRep() and HeapLogSizeRep().  It's a really simple program which 
+intercepts MAlloc() and Free().  You can customize the code to find other heap 
+issues.
+
+* You can define hndlr functions for <CTRL-ALT-letter> keys with CtrlAltCBSet(). 
+ They operate either in a interrupt environment or in the window mgr when it 
+queues kbd msgs.  You can do Raw() output.  <CTRL-ALT-letter> hndlrs take a 
+scan_code as an arg.
+
+* If you recompile Kernel with BootHDIns(), you can set the MemInit, option to 
+initialize memory to a value at boot, the HeapInit option to cause mem alloced 
+off the heap to be initialized or VarInit option so both global and local vars 
+will be initialized to a value, but global AOT variables are always zero if not 
+initialized.  Pick a non-zero value to discover uninitialized var bugs.  You can 
+set sys_var_init_flag, and sys_heap_init_flag directly after booting.
+
+ diff --git a/public/Wb/Home/Src/Doc/Define.DD.HTML b/public/Wb/Home/Src/Doc/Define.DD.HTML new file mode 100755 index 0000000..c0e919b --- /dev/null +++ b/public/Wb/Home/Src/Doc/Define.DD.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+TempleOS has a string indirection feature implemented with the same hash symbol 
+table entry as #define macros, HTT_DEFINE_STR.  Support for string lists is also 
+provided, but it's not very efficient, though, you can make a hash table with a 
+list using HashDefineLstAdd().  See ::/Adam/DolDoc/DocInit.HC.
+
+If you have an @ as the first char of a define list entry, it is an alias for 
+the prev entry num.
+
+Each task can load its own Define strings.  Remember, when a Hash table is 
+searched for a string, if it is not found, the parent task's table is searched.
+
+The DolDoc framework supports text that changes based on entries in the task's 
+symbol table.  Set a text entry with a D= arg, as in $TX,"",D="DD_MYSTRING"$.  
+See ::/Demo/DolDoc/DefineStr.HC, ::/Adam/ADefine.HC and ::/Doc/MemOverview.DD.
+
+See ::/Demo/Define.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/Demands.DD.HTML b/public/Wb/Home/Src/Doc/Demands.DD.HTML new file mode 100755 index 0000000..972c092 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Demands.DD.HTML @@ -0,0 +1,150 @@ + + + + + + + + + + + +
+                                    Demands
+
+I, Terry Davis, am high priest of God's official third temple, TempleOS.  
+TempleOS is an operating system for IBM PC x86_64 desktops that will always dual 
+boot along-side Windows or Linux.  I am in charge of the core 100,000 lines of 
+TempleOS code and I do continual offerings to keep God entertained.  I have 
+divine authority to command any company in the computer industry to do anything 
+that I deem necessary to make God's temple more beautiful, glorious and perfect. 
+I have oversight authority similar to a building inspector or a person enforcing 
+the Americans with Disability Act -- I make commands, God signs-off with a 
+miraculous authentication from an oracle, and Intel, Microsoft or VMware obeys.
+
+
+
+* Windows, Linux and VMware (because of mounted drives) must support RedSea file 
+system when mounting partition, so I can get rid of 1,000 lines of redundant, 
+blemished code -- FAT32.  God's temple must be perfect.  Redundant code for 
+multiple file systems is bad and imperfect.  For this operating system, we want 
+low line count.  More than one driver for the same type of device is also bad.
+
+See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC.
+
+::/Kernel/BlkDev/FileSysFAT.HC  :974 lines for FAT32 gets eliminated.
+::/Kernel/BlkDev/DskClus.HC     :152 All the clus operations become blk.
+
+* Microsoft must cancel SecureBoot because it makes dual booting impossible.  
+TempleOS is an additional operating system that must be used along-side Windows 
+or Linux, not as a replacement.  It must dual boot because it has no networking. 
+Real hardware as opposed to VMware is like the difference between looking in a 
+telescope eye piece vs just looking at an off-line image.  God said the 
+C64/Apple II generation owned ancestral lands.  VMware is like being taken off 
+of our land and moved onto a reservation.  In this case, however, it will not 
+stand.  In fact, God said to replace Windows with Wine, justice.  We can make a 
+100% standard model PC with a standard software for everyone, backed-up in 
+factory ROM.
+
+* VMware needs to support ATAPI CD/DVD/Blu-ray disk burning, directly to real 
+hardware.  Industry needs write-just once media to stop Farenheit 451 non-sense.
+
+* VMware has a bug stretching 640x480 16 color to full screen.
+
+* VMware some PC speaker's distortion is a good idea -- squarewave -- but 
+currently there is too much for hymns.  CIA monkery made fart noises.
+
+* VMware and others must list TempleOS as an official 64-bit operating system 
+and automatically enforce 512 Meg min RAM requirement.
+
+* VMware needs to support more than 16 cores.  I had a 24 core Xeon with 128 Gig 
+of RAM.  I discovered VMware allocates memory too slowly, where QEMU had no 
+problem.
+
+* Until super-simple block devices are available, hard disk should be placed at 
+IDE primary master 1F0/3F6 and CD/DVD/Blu-ray should be placed at the IDE 
+secondary master 170/376.  Currently, the wicked CIA plays musical chairs with 
+controllers each time you make an install.  With tons of ugly code, I do my 
+best.
+/Kernel/BlkDev/DskATAId.HC      :286 lines to figure-out I/O ports is gone.
+/Kernel/PCIBIOS.HC              :290 could be eliminated, but maybe we will keep 
+it so people can play with PCI devices.
+
+* Until super-simple serial ports are available, PS/2 emulated keyboard and 
+mouse must work.  The BIOS must enable these.  The plan is to transition the 
+industry off of USB.  Interum solution is to make virtual RS232 Octart for USB 
+devices in the same way PS/2 mouse is emulated.  All mice will be two button, 
+one wheel.  No more HID insanity, no more multi-end point, just simple tx rx 
+fifos with soft/hard flowcontrol that can jump the queue.  People with special 
+needs can buy PCI cards.  Our kids deserve code this simple ::/Doc/Comm.HC.  The 
+right to do your own port banging is what the C64 being our God given ancestral 
+land means.
+
+* The x86 IN/OUT port instructions, normally have a delay.  Perhaps, VMware & 
+Intel can enable faster x86 IN/OUT instruction timing for ATA/ATAPI PIO, so 
+bandwidth isn't as bad when doing port I/O.  See ATAGetRes().  We don't want to 
+do DMA.  Perhaps, x86 CPU chips need a new TempleOS mode for fast IN/OUT 
+instructions?  I think VMware already does something to speed disk I/O to faster 
+than native speed.
+
+* Perhaps, a new interrupt descriptor table entry type or a new x86 CPU mode can 
+be made that cause fast software interrupts, doing exactly what the CALL REL32 
+does, but with IDT as indirection.  We don't need to change privilege levels or 
+stacks.
+
+* Since I don't use paging (for anything), Intel should have an option for  
+no-paging long mode, and optimize it!
+::/Kernel/Mem/PageTables.HC     :135 lines to identity-map gets eliminated.
+
+* Desktop computers must have a reset switch and a fast reboot option, skipping 
+diagnostics.  I recommend booting TempleOS from a ROM when the reset bttn is 
+pressed and booting UEFI when the power bttn is pressed.  Or, we could build 
+UEFI on a TempleOS layer.  Intel must burn TempleOS into a ROM in the factory 
+for all desktop x86 CPUs to ensure tamper-proof trust in the oracle and because 
+God deserves the glory.  There will be just an English version.  A new ROM 
+version is released every seven years.  The ROM should boot like the DVD boots, 
+but with BOOT_SRC_ROM.
+
+* We do not want UTF, just 8-bit characters.  <CTRL-ALT-f> toggles between 
+Cyrillic and Std Fonts.  We need the twelve window TextBorder characters added 
+to the VGA font 0x02-0x0D.  Japan, China and Korea must switch to alphabets.  
+Maybe, the United States will change to metric, out of good will.  I am 
+beginning to plan fresh ASCII replacement, ::/Doc/NewASCII.DD.
+
+* Microsoft Paint and Linux's Gimp must support TempleOS GR Files.  They are 
+blemish free, unlike BMP files.  The TOSZ Linux utility can be used to make 
+screencasts from TempleOS exported GR Files and AU Files.
+
+* We must have a nice dictionary.  Someone needs to do a Spell Checker, too.
+
+* Intel needs to make DolDoc versions of its x86 CPU data sheets documenting all 
+hardware relevant to TempleOS. 
+
+* We must have the ultimate Bible search engine.  Currently, all we have is     
+filter search.  In the end, it should be a low line-count technique.  Maybe, I 
+allocate 500 lines out of the 20,000 reserve.
+
+* We will make a Standard TempleOS PC.
+
+* "VMware" is a trademark owned by VMware, Inc.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "Windows" and "Paint" are trademarks owned by MicroSoft Corp.
+
+ diff --git a/public/Wb/Home/Src/Doc/DemoIndex.DD.HTML b/public/Wb/Home/Src/Doc/DemoIndex.DD.HTML new file mode 100755 index 0000000..5c47f7a --- /dev/null +++ b/public/Wb/Home/Src/Doc/DemoIndex.DD.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+                              TempleOS Demo Index
+
+These are arranged in increasing order of difficulty, more or less.  This can be 
+used as a tutorial if you start at the beginning and work your way fwd.
+
+<SPACE> to edit a file and <F5> to run it.
+
+::/Doc/HelloWorld.DD
+
++] Games: Beginner
++] Games: Intermediate
++] Games: Advanced
++] Non-Game
++] TempleOS Specific
+
+
+ diff --git a/public/Wb/Home/Src/Doc/Directives.DD.HTML b/public/Wb/Home/Src/Doc/Directives.DD.HTML new file mode 100755 index 0000000..cba8fde --- /dev/null +++ b/public/Wb/Home/Src/Doc/Directives.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#define __DATE__ #exe{StreamPrint("\"%D\"",Now);}
+#define __TIME__ #exe{StreamPrint("\"%T\"",Now);}
+#define __LINE__ #exe{StreamPrint("%d",Fs->last_cc->lex_include_stk->line_num);}
+#define __CMD_LINE__ #exe{StreamPrint("%d",Fs->last_cc->flags&CCF_CMD_LINE && Fs->last_cc->lex_include_stk->depth<1);}
+#define __FILE__ #exe{StreamPrint("\"%s\"",Fs->last_cc->lex_include_stk->full_name);}
+#define __DIR__  #exe{StreamDir;}
+
+See ::/Demo/Directives.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/DolDoc.DD.HTML b/public/Wb/Home/Src/Doc/DolDoc.DD.HTML new file mode 100755 index 0000000..fc095d6 --- /dev/null +++ b/public/Wb/Home/Src/Doc/DolDoc.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+A DolDoc in memory is a Circular Queue of cmds and graphics.  See CDocEntry for 
+the entry structure.  See TipOfDay() for a nice example.
+
+DolDoc's are used for the editor, viewer, browser, and cmd line.
+
+ diff --git a/public/Wb/Home/Src/Doc/DolDocOverview.DD.HTML b/public/Wb/Home/Src/Doc/DolDocOverview.DD.HTML new file mode 100755 index 0000000..4059ea2 --- /dev/null +++ b/public/Wb/Home/Src/Doc/DolDocOverview.DD.HTML @@ -0,0 +1,151 @@ + + + + + + + + + + + +
+                                DolDoc Overview
+
+DolDoc is a TempleOS document type supported by DolDoc Routines.  In a document, 
+commands are bracketed with '$'s.  Use <CTRL-l> to experiment inserting a 
+command.  Then, use <CTRL-t> to toggle to plain text to see it.
+
+Here is the grammar:
+
+<DolDocCmd> := $<TwoLetterCmd>[<FlagList>][,<ArgList>]$ | $ColorName$
+
+<FlagList> := +|- <FlagCode>[<FlagList>]
+
+<ArgList> := <ArgCode>=<ArgExpression>[,<ArgList>]
+
+
+The format of DolDoc cmds is a two character code, +/-flags, a comma and args 
+separated by commas.  Some commands have mandatory args.  Optional args are 
+indicated with <ArgCode>=.  A ColorName bracked by dollars, will change the 
+foreground color.
+
+See ::/Doc/Widget.DD, ::/Demo/DolDoc/DemoDoc.DD, and 
+::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+<TwoLetterCmd>  See Type Defines and PrsDollarCmd().
++] TX Text
++] CR Hard New Line
++] SR Soft New Line
++] CU Cursor pos
++] TB Tab
++] CL Clear
++] PB Page Break
++] PL Page Length
++] LM Left Margin
++] RM Right Margin
++] HD Header
++] FO Footer
++] ID Indent +/- num
++] Text Colors
++] PT User Prompt
++] WW Word Wrap
++] UL Underline
++] IV Invert
++] BK Blink
++] SX Shift X pos
++] SY Shift Y pos
++] CM Cursor Movement
++] AN Anchor
++] LK Link
++] BT Bttn
++] DA Data
++] CB Check Box
++] LS List Widget
++] MA Macro
++] MU Menu Value
++] HX Hex Edit
++] TR Tree Widget
++] SP Sprite
++] IB Insert Binary
++] IS Insert Binary Size
++] SO Song
++] HL Highlighting
++] HC html
++] ER Error
+
+<FlagCode>  See Flag Defines and Simple Flags.
++] +H Hold
++] +L Link
++] +TR Tree
++] +LS List
++] +PU PopUp
++] +C Collapsed
++] +X <ESC> (Exit)
++] +Q <SHIFT-ESC> (Abort Quit)
++] +Z Zero
++] +RD Refresh Data
++] +UD Update Data
++] +TC Tag CallBack
++] +LC Left CallBack
++] +RC Right CallBack
+
+<ArgCode>  See Arg Defines.
++] T="" Tag Str
++] LEN="" Field Length
++] A="" Auxilliary Str
++] D="" Define Str
++] HTML=""
++] LE=<Exp> Left Expression
++] LM="" Left Macro Str
++] RE=<Exp> Right Expression
++] RM="" Right Macro Str
++] BI=<Exp> Bin Number
++] BP="" Bin Ptr
++] RT=<raw_data_type>
++] SX=<Exp> Shift X
++] SY=<Exp> Shift Y
++] SCX=<Exp> Scroll X
++] U=<Exp> User Data
+
+EXAMPLES:
+
+<CTRL-t> to see how the following were done.
+Underlined Inverted Blinking super sub
+This is a big long scrolling msg.
+
+Cursor Movements:
+
+
+
+   Cursor moved 3 rows down and to 3rd column from left.
+                                                                                
+
+
+                                        Note mandatory comma after flags
+
+The following may be changed to modes instead of attr with flags.
+
+                                This is centered
+
+                                                         This is right justified
+
+ diff --git a/public/Wb/Home/Src/Doc/EdPullDown.DD.HTML b/public/Wb/Home/Src/Doc/EdPullDown.DD.HTML new file mode 100755 index 0000000..0aadddf --- /dev/null +++ b/public/Wb/Home/Src/Doc/EdPullDown.DD.HTML @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+File
+{
+  Save(,CH_CTRLS);
+  SaveAs(,CH_CTRLA);
+  Abort(,CH_SHIFT_ESC);
+  Exit(,CH_ESC);
+}
+
+Edit
+{
+  Undo(,CH_CTRLH,0x80E0000080E);
+  Cut(,CH_CTRLX);
+  Copy(,CH_CTRLC);
+  Paste(,CH_CTRLV);
+  DelLine(,CH_CTRLY);
+  FindReplace(,CH_CTRLF);
+  FindNext(,,0x3D0000003D);
+  FindLast(,,0x23D0000023D);
+  GoLine(,CH_CTRLG,0x42200000422);
+  GoBegin(,,0x4C800000448);
+  GoEnd(,,0x4D000000450);
+  GoLeft(,,0x4CB0000044B);
+  GoRight(,,0x4CD0000044D);
+  GoLBrace(,0x5B,0x61A0000061A);
+  GoRBrace(,0x5D,0x61B0000061B);
+  Macro(,,0x3C0000003C);
+  PlayMacro(,,0x23C0000023C);
+  AutoSaveToggle(,CH_CTRLS,0x61F0000061F);
+}
+
+Insert
+{
+  TextWidgets(,CH_CTRLL,0x42600000426);
+  GraphicResource(,CH_CTRLR,0x41300000413);
+  FileName(,,0x3E0000003E);
+  DirName(,,0x23E0000023E);
+  GodWord(,,0x4100000041);
+  GodBiblePassage(,,0x24100000241);
+  GodSong(,,0x4000000040);
+  GodDoodle(,,0x24000000240);
+  IndentIn(,CH_CTRLI,0x41700000417);
+  IndentOut(,CH_CTRLI,0x61700000617);
+  WordWrapOn(,CH_CTRLW,0x41100000411);
+  WordWrapOff(,CH_CTRLW,0x61100000611);
+  UnderlineOn(,CH_CTRLU,0x41600000416);
+  UnderlineOff(,CH_CTRLU,0x61600000616);
+  BlinkOn(,CH_CTRLK,0x42500000425);
+  BlinkOff(2,CH_CTRLK,0x62500000625);
+  InvertOn(,CH_CTRLZ,0x42C0000042C);
+  InvertOff(,CH_CTRLZ,0x62C0000062C);
+  SuperToggle(,CH_CTRLP,0x41900000419);
+  SubToggle(,CH_CTRLP,0x61900000619);
+  PageBreak(,CH_CTRLJ,0x41C0000041C);
+}
+
+Program
+{
+  CodeTools(,CH_CTRLL,0x62600000626);
+  Include(,0,0x3F0000003F);
+  AdamInclude(,0,0x23F0000023F);
+}
+
+View
+{
+  PlainText(,CH_CTRLT);
+  Collapse(,CH_CTRLO,0x61800000618);
+  Uncollapse(,CH_CTRLO,0x41800000418);
+  Border(,CH_CTRLB);
+  FileMgr(,CH_CTRLD,0x42000000420);
+  Search(,CH_CTRLF,0x62100000621);
+}
+
+Help
+{
+  Menu(,CH_CTRLM,0x43200000432);
+  Help(,,0x3B0000003B);
+  About(,,0x23B0000023B);
+}
+
+ diff --git a/public/Wb/Home/Src/Doc/FAQ.DD.HTML b/public/Wb/Home/Src/Doc/FAQ.DD.HTML new file mode 100755 index 0000000..7ef2750 --- /dev/null +++ b/public/Wb/Home/Src/Doc/FAQ.DD.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+                           Frequently Asked Questions
+
++] How come it is public domain, not GPL?
++] Shouldn't it be GNU/TempleOS?
++] Don't you use GNU's gcc?
++] Why do you dual boot?
++] It has links, so is it a browser?
++] Where are the animated 3D icon GIFs?
++] If the compiler is JIT, isn't it an interpretor?
++] Are you a Creationist?
++] Is 'Bt()' in the code Bit Torrent?
++] Is 'Fs->' in the code file system?
++] Is it Pascal?
++] Why doesn't Sleep() make my laptop hibernate?
++] What is Yield() for in loops?
++] What is JIT Compiled Mode?
++] Why do files end in .Z?  Are they encrypted?
++] Is it open source?  How do I build it?
++] Where are object files?  How do I link?
++] What is the FPS refresh rate?
++] How does a task own the speaker?
++] Why does it leak memory?
++] Why do I get a memory leak when editing big files?
++] Why is it in text mode?
++] Where is the kernel memory?
++] Why does it run code from stack addresses?
++] How does it SYSCALL?
++] How do you fault-in stack?
++] How do I set the PATH?
++] How do I boot it with Grub?
++] How do I get Kernel.BIN to boot?
++] Why is there some 16-Bit code?
++] Why are you pushing 32-bit values on the stack?
++] Why are you using 32-bit insts and not setting high 32-bits?
++] How do you use the FS and GS segment registers.
++] How do I set ORG for position of code?
++] How are symbols loaded?
++] Why doesn't assert work?
++] Why doesn't C++ public work?
++] How does the debugger do source debugging?
++] What are the ASCII 5 and ASCII 31 chars doing in my text files?
++] Why is there garbage at the end of my text files?
++] Why are sprites so small?
++] Why don't I need to recompile /Adam and /Home files?
++] Why does it finds files that aren't there?
+
+
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Src/Doc/Features.DD.HTML b/public/Wb/Home/Src/Doc/Features.DD.HTML new file mode 100755 index 0000000..eab7988 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Features.DD.HTML @@ -0,0 +1,98 @@ + + + + + + + + + + + +
+                               TempleOS' Features
+
+* Oracle in with <F7> for words or <SHIFT-F7> for passages.  See tongues.
+
+* x86_64, ring-0-only, single-address-map (identity), multitasking kernel with 
+multicore support.
+
+* Master/Slave MultiCore 
+
+* Free, public domain, 100% open source.
+
+* 64-bit compiler/assembler for HolyC.  Truly compiles, doesn't interpret.  Just
+-in-Time and Ahead-of-Time compilation.  With JIT, no need for object or exe 
+files.
+
+* No 32-bit krufty code.
+
+* 640x480 16 color VGA graphics.
+
+* Keyboard & Mouse support.
+
+* ATA PIO Hard drives, support for FAT32 and RedSea file systems with file 
+compression.
+
+* ATAPI PIO CD/DVD support with RedSea file system.  Can make bootable ISO files 
+so you can roll-your-own distro's.
+
+* Partitioning tool, installer, boot loaders for CD/DVD and hard disk.
+
+* Editor/Browser for a new Document Format.  Source files and the command line 
+window can have graphics, links, icons, trees, colors, super/sub scripts, 
+margins.  Everything is seamless through-out the tool chain.  No need for 
+separate resource files.
+
+* 8-bit ASCII, not just 7-bit.  Supported in entire tool chain.  <CTRL-ALT-a>
+
+* Graphics in source code, no resource files, graphic sprite editor. <CTRL-r>
+
+* 64-bit pointers.  All memory, even more than 4Gig, can be directly accessed by 
+all tasks on all cores at all times.
+
+* Ring-0-only.  Highest CPU privileged mode at all times.  No off-limits insts.  
+No time lost changing modes or address maps.  Switches tasks in half a 
+microsecond.
+
+* 2D/3D graphics library
+
+* Real-time fancy differential-equation solver for physics engines, to use in 
+games.  (Adaptive step-size Runge-Kutta, interpolated for real-time.)
+
+* Auto-completion, jump-to-source tool called AutoComplete with Dictionary.
+
+* Window Manager.  Pan scrn with <CTRL-LeftDrag>.  Zoom scrn on mouse cursor 
+with <CTRL-ALT-z>/<CTRL-ALT-SHIFT-Z>.
+
+* File Manager, <CTRL-d>.
+
+* Code profiler, merge, diff utils.
+
+* PC Speaker support with many hymns.
+
+* Music composing tool.
+
+* Many games, demos and documentation.
+
+* All source code included.  Only compiles with the included TempleOS compiler 
+and assembler.
+
+ diff --git a/public/Wb/Home/Src/Doc/FileLowLevel.DD.HTML b/public/Wb/Home/Src/Doc/FileLowLevel.DD.HTML new file mode 100755 index 0000000..30cf57c --- /dev/null +++ b/public/Wb/Home/Src/Doc/FileLowLevel.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+                       CFile
+
+
+
+
+
+
+
+    BlkRead()         BlkWrite()
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Home/Src/Doc/FileMgr.DD.HTML b/public/Wb/Home/Src/Doc/FileMgr.DD.HTML new file mode 100755 index 0000000..4d3a5f3 --- /dev/null +++ b/public/Wb/Home/Src/Doc/FileMgr.DD.HTML @@ -0,0 +1,107 @@ + + + + + + + + + + + +
+                                  File Manager
+
+<SHIFT CURSOR>
+  Select files.
+
+<CTRL-y> or <DEL>
+  Delete file or tree.
+
+<CTRL-c> or <CTRL-INS>
+  Copy select files to clip.
+
+<CTRL-v> or <SHIFT-INS>
+  Paste clip.
+
+LEFT-CLICK,drag-drop
+  Move a file or tree to a dir.
+
+LEFT-CLICK,same file or <SPACE>
+  Edit file.
+
+<SHIFT-SPACE>
+  Edit Plain Text File.
+
+RIGHT-CLICK or <ENTER>
+  Bring-up menu.
+
+<F5>
+  #include file.
+
+<SHIFT-F5>
+  Adam #include file.
+
+'r'
+  Rename file.
+
+'d'
+  Make Dir.
+
+'c'
+  DskChg (Remount removable media).  Do not do this on blank disks.
+
+'f'
+  Format drive.
+
+'i'
+  Mount ISO.C file.
+
+'u'
+  Unmount drive(s).
+
+'m'
+  Make CD/DVD ISO.C file.  This creates a RedSea ISO file image of the dir the 
+  cursor is on.  The name of the ISO file is "::/Tmp/CDDVD.ISO.C" 
+  blkdev.dft_iso_c_filename and can be redefined in your start-up scripts.  You 
+  may wish to place it on a different drive.
+
+'B'
+  Burn CD/DVD ISO file.  This burns a CD/DVD using the image file, 
+  "::/Tmp/CDDVD.ISO" blkdev.dft_iso_filename to the drive the cursor is on.
+
+
+Instructions on Using CD/DVD's
+  If you have not recompiled Kernel and defined your CD/DVD drive, exit the 
+  FileMgr and use Mount to define your CD/DVD drive.  Place a CD/DVD in the 
+  drive and press 'c' when on top of the CD/DVD drive letter to mount the drive. 
+   It will call DskChg(), the TempleOS cmd to mount removable media.
+
+
+Instructions on Burning CD/DVD's
+  Create a temporary dir to hold files and copy files into the holding dir.  
+  Make an ISO image of the dir by pressing 'M' when on top of the dir.  Press 'B
+  ' when on top of the CD/DVD ROM drive to burn the ISO, "::/Tmp/CDDVD.ISO" 
+  blkdev.dft_iso_filename, to disk.  If you have not recompiled Kernel and 
+  defined your CD/DVD drive, exit the FileMgr and use Mount.
+  
+  Making Your Own Distro
+  
+ diff --git a/public/Wb/Home/Src/Doc/FileMgrPullDown.DD.HTML b/public/Wb/Home/Src/Doc/FileMgrPullDown.DD.HTML new file mode 100755 index 0000000..da5fefe --- /dev/null +++ b/public/Wb/Home/Src/Doc/FileMgrPullDown.DD.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+File
+{
+  Rename(,'r');
+  DirMk(,'d');
+  FmtDrv(,'f');
+  UnmountDrv(,'u');
+  Abort(,CH_SHIFT_ESC);
+  Exit(,CH_ESC);
+}
+
+Edit
+{
+  Ed(,CH_SPACE);
+  Plain(,CH_SHIFT_SPACE);
+  Copy(,CH_CTRLC);
+  Paste(,CH_CTRLV);
+  DeleteFile(,CH_CTRLY);
+}
+
+CDDVD
+{
+  DskChg(,'c');
+  MountISOC(,'i');
+  MakeRedSeaISOC(,'m');
+  BurnISOFile(,'B');
+}
+
+Program
+{
+  Include(,0,0x3F0000003F);
+  AdamInclude(,0,0x23F0000023F);
+}
+
+ diff --git a/public/Wb/Home/Src/Doc/FileUtils.DD.HTML b/public/Wb/Home/Src/Doc/FileUtils.DD.HTML new file mode 100755 index 0000000..11d2571 --- /dev/null +++ b/public/Wb/Home/Src/Doc/FileUtils.DD.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+                                   File Utils
+
+File util FilesFind() wildcard mask consists of a single base dir with multiple 
+file masks separated by ';'.  The '*' and '?' wildcard chars are accepted.  The 
+'~' is your home directory and '!' indicates an exclusion mask.
+
+ 
+"/Kernel/*"             BaseDir: /Kernel        Mask: *
+"/Demo/*.BMP*;*.GR*"    BaseDir: /Demo          Mask: *.BMP* | *.GR*
+"/*.DD*;!*/Bible*"      BaseDir: Root           Mask: *.DD* but not */Bible*
+
+See FilesFindMatch().
+
+Flags are either text or int values.
+
+  FUF_RECURSE           +r Recurse
+  FUF_SINGLE            +s Single File (Optimization for one file in mask.)
+  FUF_FLATTEN_TREE      +f use with '+F'.  Just use +F, probably.
+  FUF_JUST_DIRS         +D just directories
+  FUF_JUST_FILES        +F just files (Flattens trees)
+  FUF_CLUS_ORDER        +O sort by clus (move head one direction)
+  FUF_JUST_TXT          +T just text files      : FILEMASK_TXT
+  FUF_JUST_DD           +$ just DolDoc files    : FILEMASK_DD
+  FUF_JUST_SRC          +S just src files       : FILEMASK_SRC
+  FUF_JUST_AOT          +A just aot files       : FILEMASK_AOT
+  FUF_JUST_JIT          +J just jit files       : FILEMASK_JIT
+  FUF_JUST_GR           +G just graphic files   : FILEMASK_GR
+
+See ST_FILE_UTIL_FLAGS when used in calling program taking text flags.
+
+ diff --git a/public/Wb/Home/Src/Doc/Frame.DD.HTML b/public/Wb/Home/Src/Doc/Frame.DD.HTML new file mode 100755 index 0000000..96c3c09 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Frame.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+If you require separate global vars for multiple instances of a routine, you can 
+use Frames.  See SpriteMeshEd(), ::/Demo/Graphics/Pick3D.HC or Noise().
+
+ diff --git a/public/Wb/Home/Src/Doc/GRFiles.DD.HTML b/public/Wb/Home/Src/Doc/GRFiles.DD.HTML new file mode 100755 index 0000000..a77cefd --- /dev/null +++ b/public/Wb/Home/Src/Doc/GRFiles.DD.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+GR graphics files are 8-bits-per-pixels but only 4-bits of color, with 
+transparency and no palette.  Compression is the standard TempleOS LZW 
+compression.
+
+#define DCF_COMPRESSED          1 //This is the only saved flag.
+#define DCF_PALETTE             2
+
+#define TRANSPARENT             0xFF
+#define BLACK                   0
+#define BLUE                    1
+#define GREEN                   2
+#define CYAN                    3
+#define RED                     4
+#define PURPLE                  5
+#define BROWN                   6
+#define LTGRAY                  7
+#define DKGRAY                  8
+#define LTBLUE                  9
+#define LTGREEN                 10
+#define LTCYAN                  11
+#define LTRED                   12
+#define LTPURPLE                13
+#define YELLOW                  14
+#define WHITE                   15
+
+class CBGR48
+{
+  U16   r,g,b,pad;
+};
+
+CBGR48 gr_palette_std[16]={
+0x000000000000,0x00000000AAAA,0x0000AAAA0000,0x0000AAAAAAAA,
+0xAAAA00000000,0xAAAA0000AAAA,0xAAAA55550000,0xAAAAAAAAAAAA,
+0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
+0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0xFFFFFFFFFFFF};
+
+class GRFile
+{
+  I32   width;
+  I32   width_internal; //Rounded-up to multiple of 8.
+  I32   height;
+  I32   flags;          //DCF_COMPRESSED? See ::/Kernel/Compress.HC.
+  CBGR48 palette[16];   //Included if DCF_PALETTE.
+  U8    body[];
+};
+
+See DCSave(), GRWrite(), DCLoad(), and GRRead().
+
+ diff --git a/public/Wb/Home/Src/Doc/Glossary.DD.HTML b/public/Wb/Home/Src/Doc/Glossary.DD.HTML new file mode 100755 index 0000000..2891eac --- /dev/null +++ b/public/Wb/Home/Src/Doc/Glossary.DD.HTML @@ -0,0 +1,67 @@ + + + + + + + + + + + +
+                                    Glossery
+
++] Abbreviations
++] Task/Process/Thread
++] Adam Task
++] Seth Tasks
++] Code and Data Heaps
++] Parent, Child and PopUp Tasks
++] HolyC
++] AOT Compile Mode
++] JIT Compile Mode
++] Compiler Intermediate Code
++] Drive/Partition
+
+Bt, Bts, Btr, Btc, BEqu
+Define
+DolDoc
+Editor Link Types
+files_find_mask
+Hash Table
+InFile
+Ona
+Pag
+RedSea File System
+Sprite
+
++] CLI, STI, PUSHFD, POPFD
++] Filename Extention Types
++] Naming Convention
++] Fs
++] Gs
++] Heap
++] Join
++] user_data
++] Multicore Core0/CoreAP
+
+
+ diff --git a/public/Wb/Home/Src/Doc/God.DD.HTML b/public/Wb/Home/Src/Doc/God.DD.HTML new file mode 100755 index 0000000..385eaf6 --- /dev/null +++ b/public/Wb/Home/Src/Doc/God.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+The Holy Spirit can puppet you.
+
+
+ diff --git a/public/Wb/Home/Src/Doc/GraphicsOverview.DD.HTML b/public/Wb/Home/Src/Doc/GraphicsOverview.DD.HTML new file mode 100755 index 0000000..10e404c --- /dev/null +++ b/public/Wb/Home/Src/Doc/GraphicsOverview.DD.HTML @@ -0,0 +1,148 @@ + + + + + + + + + + + +
+                               Graphics Overview
+
+Dive into Demo Index to learn.
+
+The order layers are drawn on top of each other is:
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+* See GrUpdateScrn(), GrUpdateTasks() and GrUpdateTaskWin() called by the WinMgr 
+task 30fps.  Notice the task's draw_it() callback being called.  Only tasks on C
+ore0 are allowed to have windows.  There is one window per task, no child 
+windows.  You can have pop-up child tasks.
+
+* CDCs (device contexts) are a data type for controlling graphics on the scrn or 
+graphics in mem.  The device context structure has thick and color.  You use 
+DCAlias() to create your own structure, with its own color and thick.  Free it 
+with DCDel() when finished.
+
+* gr.dc is a device context for persistent data on the scrn, not needing to be 
+redrawn.  You create an alias for this by using DCAlias() and work with that.  
+See ::/Demo/Graphics/NetOfDots.HC.
+
+* There are various flavors of line and point plotting routines.  GrLine() and 
+GrPlot() are the simplest.  The others allow 3D graphics and rotations.
+
+* See ::/Doc/Transform.DD for adding a transformation.
+
+* You change the Fs->draw_it var to point to your DrawIt() function which gets 
+called each scrn refresh (30 fps).  You draw everything in the window over and 
+over again.  See ::/Demo/Graphics/Box.HC.
+
+* Use the graphic sprite resource editor, <CTRL-r>, to create a sprite that can 
+be plotted with Sprite3() or output to the cmd line with Sprite().  Use $IB,"",B
+I=1$ in a src program to insert the addr of sprite binary data item #1.  To 
+learn how the numbers work, after creating a sprite with <CTRL-r>, toggle to 
+plain text with <CTRL-t> and check its num.  Make an assignment to a ptr var or 
+pass to Sprite3() with $IB,"",BI=n$.  Use <CTRL-r>'s "Pointer to Sprite" to make 
+a $IB...$ entry.  See ::/Demo/Graphics/SpritePlot.HC and 
+::/Demo/Graphics/SpritePlot3D.HC.  The origin (zero point) for a sprite is 
+defined by the cursor location when you pressed <CTRL-r> to make it.  You can 
+edit a sprite by clicking the cursor on it and pressing <CTRL-r> again.
+
+* Set DCF_SYMMETRY in the CDC.flags and call DCSymmetrySet() or DCSymmetry3Set()
+.  This will plot a mirror image in addition to the primary image.  Set 
+DCF_JUST_MIRROR to plot just the image, but this required DCF_SYMMETRY to be set 
+at the same time.  Note: You can only have one symmetry active at a time 
+including in CSprites.
+
+* Use DCNew() to create a mem bitmap which can be used to work off-scrn and 
+which can be GrBloted onto the scrn.  If you set brush member of CDC to another 
+CDC, all the graphic routines will GrBlot() the brush instead of GrPlot().  See 
+::/Demo/Graphics/Blot.HC.
+
+* There are a few raster operations available.  They go in bits 8-11 of the dc->
+color member var which is a CColorROPU32.  ROP_COLLISION is special.  It counts 
+the num of pixs drawn on non-background locations.  Using ROP_COLLISION with 
+vector CSprite's is tricky because overlapping pixs from lines in the CSprite 
+reg as collisions.  You can either work with a nonzero count or convert your 
+CSprite to a bitmap if your subelements draw on top of each other.  Be sure to 
+set ->bkcolor before using ROP_COLLISION.  See ::/Demo/Graphics/Collision.HC and 
+Titanium.
+ 
+* The ->dither_probability_u16 member of CDC is a U16 used to statistically sel 
+between two colors to get something resembling more shades of color.  See 
+::/Demo/Graphics/SunMoon.HC and ::/Demo/Graphics/Shading.HC.  It works with many 
+graphic routines, but not those with pens.
+
+* There is a mechanism built-in for generating motion based on differential 
+equations, which allows realistic physics.  You create an CMathODE struct with 
+ODENew(), passing it the num of vars in the state vect.  For realistic physics, 
+you usually have 2 state vars for each dimension (for each mass) because motion 
+is governed by F=mA which is a 2nd order equation.  The two states are pos and 
+velocity and to solve these you need to supply the derivative of pos and 
+velocity.  The derivative of pos is usually simply the current velocity and the 
+derivative of velocity is the acceleration (the sum of forces on a mass divided 
+by mass).  To help provide meaningful names for values in the state vect, you 
+can create an COrder2D3 ptr and point it to a mass in the state vect.  Six 
+elements in the state vect are required for each mass.
+
+See Math/CMathODE.
+See ::/Demo/Games/Rocket.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/GuideLines.DD.HTML b/public/Wb/Home/Src/Doc/GuideLines.DD.HTML new file mode 100755 index 0000000..0f72d00 --- /dev/null +++ b/public/Wb/Home/Src/Doc/GuideLines.DD.HTML @@ -0,0 +1,219 @@ + + + + + + + + + + + +
+                              Directory Structure
+
+/Home All your user data should be placed in here to ease backing-up your data.  
+When you install an application it will create a subdirectory of your /Home 
+directory for storage.
+
+/Apps Applications are placed in subdirectories of /Apps.  Applications should 
+have a file called Install.HC.Z which will install the app, possibly making 
+files or directories in /Home.  The file, Load.HC.Z will load the application 
+into mem.  The file, Run.HC.Z, will usually load and execute the app.  To add an 
+app to your PersonalMenu, use <CTRL-l>, insert a macro with the PopUp option 
+checked and invoke the Run.HC.Z file.
+
+/Demo Here you can find lots of sample code to do various things.
+
+/Doc Here you can find documentation.
+
+/Kernel The core of the operating system is found here.  Since priviledge levels 
+are not used, calling it a kernel is deceptive.  It is AOT compiled by 
+BootHDIns().  It is loaded by the boot loader and must fit in 640K.
+
+/Compiler The compiler module src code is found here.  The compiler is AOT 
+compiled to produce a binary file which is loaded at boot.  It, too, is AOT 
+compiled by BootHDIns().
+
+/Adam The non-kernel part of the operating system is found here.  It is JIT 
+compiled during boot.  The Adam Task is the father of all tasks, like Adam and 
+Eve.
+
+/0000Boot Boot files go here.  Stage 2 of the TempleOS hard drive master boot 
+loader, the old hard drive master boot record which is just blk#0, and the 
+CD/DVD 0000Kernel.BIN.C file go here.  ASCII 0000 is near the top, 
+alphabetically, in case you use MagicISO.
+
+
+
+                                 ::/Home Files
+
+The home dir is specified with '~'.  The home dir is ::/Home unless you change 
+it with HomeSet() or compile the kernel with a cfg option.  An empty /Home dir 
+should be valid because it will get default files from the root dir. 
+
+~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in 
+the upper left border area of a window.
+
+~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key.
+
+~/MakeHome.HC a file compiled by the Adam Task during StartOS.
+
+~/Home* Copy Home* files from the root into ~ and customize them.  These files 
+are invoked when the Adam Task starts-up.
+
+~/Once.HC a file invoked at the start-up of the first user.  Customize this!
+
+~/Registry.HC can be edited by hand or deleted to reset to defaults.  Takes 
+affect next boot.
+
+
+
+                              Application Policies
+
+* Place applications in their own /Apps subdirectory.
+
+* Make a file called Load.HC.Z to load the application.
+
+* Make a file called Run.HC.Z to load and run the application, preferable by #in
+cludeing the Load.HC.Z file.
+
+* Place user data in a subdirectory of /Home, preferably naming the subdirectory 
+the same as the /Apps subdirectory.  Or, place data in the Registry.HC.Z file.  
+See ::/Demo/RegistryDemo.HC.
+
+* If the app needs files in the /Home directory, make an /Apps file called Insta
+ll.HC.Z or Install.IN.Z to create the /Home subdirectory.
+
+ 
+
+                             Programming Guidelines
+
+* Virtual mem/Paging is not used -- it is identity mapped in x86_64 mode.  The 
+stk does not grow, so alloc enough when the task (process) is Spawned and use 
+the heap for most things.  (The heap refers to MAlloc() and Free().)
+
+* You can Free(NULL).
+
+* See Naming Convention and Abbreviations.
+
+* There are two modes of compiling, AOT Compile Mode and JIT Compile Mode.  
+Compilation is done in both -- neither is "interpreted".  Use JIT Mode.
+
+* HolyC
+
+* Use I64 instead of smaller int sizes because the compiler converts everything 
+to 64-bit.  Don't use unsigned unless it actually breaks.  A policy of signed 
+keeps it simple so you don't have to agonize over choices.
+
+     U32 DistDist(U16 x1, U16 y1, U16 x2, U16 y2)
+     {//This requires zero-extend when fetching args.
+       return SqrI64(x1-x2)+SqrI64(y1-y2);
+     }
+     
+     I64 DistDist(I64 x1, I64 y1, I64 x2, I64 y2)
+     {
+       return SqrI64(x1-x2)+SqrI64(y1-y2);
+     }
+
+* In-order, short circuit logic is assumed.
+
+* Avoid boolean expression assignments.  Boolean assignments don't have short 
+circuit logic and are not compiled efficiently.  The Bool type is just an alias 
+for a 1 byte signed int -- nothing forces it to 1 or 0.  There is a ToBool() 
+function that will for to 1 ot 0, however.
+
+* Glbl vars in AOT BIN modules are initialized to zero.  They occupy space in 
+BIN files.
+
+* Bracketing code with PUSHFD CLI and POPFD will protect against simultaneous 
+accesses from tasks on one core.  To protect against multiple cores, you need a 
+locked semaphore.  I think semiphores need to be in their own cache line, but 
+I'm not sure.  I use lock bits in a lot of places not aligned.
+
+* SysDbg() and IsSysDbg() are really handy when working on the compiler or 
+kernel.  It's just a bit you can set and test.
+
+* I don't use U0 * because the size is zero for ptr arithmetic.
+
+* Use CH_SHIFT_SPACE for spaces in quotes in source code because I run 
+Spaces-to-Tabs on source code.
+
+* Do not use #if or #ifdef
+
+
+
+                                Hash Sym Tables
+
+* See ::/Adam/AHash.HC for examples of how the hash tables are set-up.  
+Basically, syms are placed into hash tables and child process hash tables are 
+chained to parents.  This provides scopes for vars and functions.
+
+* adam_task->hash_table holds the HolyC syms loaded in on start-up.
+
+* Fs->hash_table holds user HolyC syms and if a sym is not found, it checks 
+parents.  When a duplicate sym is added to the table, it overshadows the prev 
+sym.  When developing software, typically you include the file at the cmd 
+prompt, make changes and reinclude it.  Old syms are overshadowed but they are 
+still there.  Periodically, kill the TASK and start fresh when mem is low.  If 
+you wish your applications to free themselves instead of staying in mem, spawn 
+or PopUp() a task to run the application and kill it when it's done.
+
+* To display the contents of a hash table, use the Who() routine or the 
+varients.  HashDepthRep() gives a histogram  of how long the chains are, in case 
+you wish to make hash table sizes bigger.
+
+
+
+                               Assembly Language
+
+See ::/Doc/Asm.DD.
+
+* FS must always point to the cur CTask.
+
+* GS must always point to the cur CCPU.
+
+* Don't change the segment regs unless interrupts are off.  It's hard to do, 
+anyway.  SET_FS_BASE and SET_GS_BASE.
+
+* When interacting with HolyC compiled code, preserve RBP, RSI, RDI, R10-R15 
+because the compiler uses these for reg vars.  You are free to clobber RAX, RBX, 
+RCX, RDX, R8 and R9.  See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS
+
+* I recommend using the standard stk frame for functions because Caller() is 
+used to display the call stk, such as for the wallpaper.
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,nnnn
+...
+        LEAVE
+        RET
+
+* The args are removed from the stack with RET1 stmts.
+
+        RET1    16      //remove two args
+
+* No args are passed in regs.
+
+* RAX holds function return values, of course.
+
+* "MagicISO" is a trademark owned by MagicISO Corp.
+
+ diff --git a/public/Wb/Home/Src/Doc/Hash.DD.HTML b/public/Wb/Home/Src/Doc/Hash.DD.HTML new file mode 100755 index 0000000..ace60b9 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Hash.DD.HTML @@ -0,0 +1,79 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+There is a symbol (hash) table for each task.  When a sym is not found, the 
+parent task's sym table is checked.  All tasks chain back to the Adam task.
+
+TempleOS sym tables are implemented with an array of linked-lists.  A num is 
+generated from a string by HashStr() to index into the array of linked-lists.  
+Multiple strings can generate the same num, so linked-lists are built.  Newer 
+entries overshadow older ones.
+
+There are various types of entries.  See Hash Entry Types.
+
+Symbol Look-up (Used many places including the JIT Compiler and Loader.)
+1) Symbol name is hashed by adding and shifting the ASCII of all chars.
+2) hash table->body[] array is indexed.
+3) Linked-lst is traversed until match of text and type of entry.
+4) If not found, hash table->next table is searched.
+
+Duplicate entries are allowed -- they overshadow old entries.
+
+Address-to-Symbol Look-up (Slow because not important. We could use trees.)
+1) FunSeg Cache is scanned.
+2) Hash Tables are scanned.
+
+ diff --git a/public/Wb/Home/Src/Doc/HeapDbg.DD.HTML b/public/Wb/Home/Src/Doc/HeapDbg.DD.HTML new file mode 100755 index 0000000..285bb14 --- /dev/null +++ b/public/Wb/Home/Src/Doc/HeapDbg.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Recompile the kernel with _CFG_HEAP_DBG=TRUE if you want more heap debugging.  
+You are on your own.
+
+ diff --git a/public/Wb/Home/Src/Doc/HelloWorld.DD.HTML b/public/Wb/Home/Src/Doc/HelloWorld.DD.HTML new file mode 100755 index 0000000..6d63dd3 --- /dev/null +++ b/public/Wb/Home/Src/Doc/HelloWorld.DD.HTML @@ -0,0 +1,130 @@ + + + + + + + + + + + +
+//Press F5 in the editor to compile and run.
+
+--------Hello.HC.Z---------
+"Hello World\n";
+
+
+--------Hello.HC.Z---------
+U0 Main()
+{
+  "Hello World\n";
+}
+Main;
+
+
+--------Hello.HC.Z---------
+U0 MyPrint(U8 *st)
+{
+  "%s",st;
+}
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+U0 MyPrint2(U8 *st1,U8 *st2) //Any number of args.
+{
+  "%s %s\n",st1,st2; //Any number of args.
+}
+MyPrint2("Hello","World");
+
+
+--------Hello.HC.Z---------
+U0 MyPrint(U8 *st)
+{
+  "" st; //Empty with no comma means first is fmt str.
+}
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+asm {
+MSG:    DU8 "Hello World\n",0;
+
+//The convention is underscore on C callable.
+//Two colons means exported symbol.
+_HELLO_WORLD::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RSI
+        MOV     RSI,MSG
+        CALL    PUT_STR
+        POP     RSI
+        RET
+}
+Call(_HELLO_WORLD);
+
+
+--------Hello.HC.Z---------
+asm {
+_HELLO_WORLD::
+//You can only clobber RAX,RBX,RCX,RDX
+        MOV     RAX,'Hello '
+        CALL    PUT_CHARS //Up to 8 chars packed into one 64-bit int.
+        MOV     RAX,'World\n'
+        CALL    PUT_CHARS
+        RET
+}
+Call(_HELLO_WORLD);
+
+
+--------Hello.HC.Z---------
+asm {
+_MY_PRINT::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        CALL    PUT_STR
+        POP     RSI
+        POP     RBP
+        RET1    8       //Callee pops the stack to clear args.
+}
+_extern _MY_PRINT U0 MyPrint(U8 *st);
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+asm {
+_MY_PRINT::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    U64 SF_ARG1[RBP]
+        CALL    &PutS   //Callee pops the stack to clear args.
+        POP     RBP
+        RET1    8
+}
+_extern _MY_PRINT U0 MyPrint(U8 *st);
+MyPrint("Hello World\n");
+
+
+ diff --git a/public/Wb/Home/Src/Doc/HelpIndex.DD.HTML b/public/Wb/Home/Src/Doc/HelpIndex.DD.HTML new file mode 100755 index 0000000..b913d67 --- /dev/null +++ b/public/Wb/Home/Src/Doc/HelpIndex.DD.HTML @@ -0,0 +1,124 @@ + + + + + + + + + + + +
+                                      Help
+
++] Keyboard Ctrls
++] Mouse Ctrls
++] Keyboard-Mouse Ctrls
+
+Welcome         About TempleOS
+Command Line    Take Tour
+Demo Index      Key Map
+Features        Requirements
+Charter         Strategic Decisions
+F.A.Q.          Glossary
+HolyC           Compiler Index
+Why Not More?   Demands
+The Std TempleOS PC
+        
++] User Help
++] Admin Help
++] Programmer help
++] System Programmer Help
+
+
+                                     Index
+AutoComplete
+Bit
+Boot
+Call
+Char Overview
+Char Routines
+Circular Queue
+Cmd Line Overview
+Cmd Line Routines
+Compiler Overview
+Compiler Routines
+Compression
+Ctrls
+Data Types
+Date
+Debugging Overview
+Debugging Routines
+Define
+Devices
+Disk
+Doc Overview
+Doc Routines
+Exceptions
+File
+File Utils
+Frames
+God
+Graphics Overview
+Graphics Routines
+Hash
+Help System
+HolyC
+InFile
+Info
+Install
+I/O
+Job
+Key Allocations
+Keyboard Devices
+Link Types
+Math
+Memory Overview
+Memory Routines
+Menus
+Messages
+Misc
+Mouse
+MultiCore
+OpCodes
+Operator Precedences
+PCI
+Print("") Fmt Strings
+Processor
+Profiler
+RedSea
+Registry
+Scan Codes
+ScrnCast
+Sound
+Sprites
+StdIn
+StdOut
+String
+Task
+TextBase Layer
+Time
+Training
+TOSZ
+Utils
+Windows
+
+ diff --git a/public/Wb/Home/Src/Doc/HelpSystem.DD.HTML b/public/Wb/Home/Src/Doc/HelpSystem.DD.HTML new file mode 100755 index 0000000..1e9e630 --- /dev/null +++ b/public/Wb/Home/Src/Doc/HelpSystem.DD.HTML @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+#help_index "Topic/SubTopic;OtherTopic"
+The help index preprocessor compiler directive sets the topics for syms 
+subsequently defined.  You specify subtopics with a '/' tree hierarchy and 
+separate multiple topics with a ';'.  The index ctrls HI:index links.
+
+public causes a sym to appear in help_index reports.
+
+#help_file "filename[.DD.Z]"
+The help file preprocessor directive makes a file into the heading of a 
+HI:index report for the current help index.
+
+ diff --git a/public/Wb/Home/Src/Doc/HolyC.DD.HTML b/public/Wb/Home/Src/Doc/HolyC.DD.HTML new file mode 100755 index 0000000..a2cd37f --- /dev/null +++ b/public/Wb/Home/Src/Doc/HolyC.DD.HTML @@ -0,0 +1,354 @@ + + + + + + + + + + + +
+                                     HolyC
+
+* See ::/Doc/CompilerOverview.DD.
+
+* See Scoping and Linkage for details on extern, import, _extern, _import, etc.
+
+* Built-in types include I0,I8,I16,I32,I64 for signed 0-8 byte ints and U0,U8,U1
+6,U32,U64 for unsigned 0-8 byte ints and F64 for 8 byte floats.
+
+        U0      void, but ZERO size!
+        I8      char
+        U8      unsigned char
+        I16     short
+        U16     unsigned short
+        I32     int
+        U32     unsigned int
+        I64     long (64-bit)
+        U64     unsigned long (64-bit)
+        F64     double
+        no F32 float.
+
+* Function with no args, or just default args can be called without parentheses. 
+
+  >Dir("*");
+  >Dir();
+  >Dir;
+
+* Default args don't have to be on the end.  This code is valid:
+  U0 Test(I64 i=4,I64 j,I64 k=5)
+  {
+    Print("%X %X %X\n",i,j,k);
+  }
+  
+  Test(,3);
+
+* A char const all alone is sent to PutChars().  A string with or without args 
+is sent to Print().  An empty string literal signals a variable fmt_str follows.
+
+  void DemoC(char drv,char *fmt,char *name,int age)
+  {
+    printf("Hello World!\n");
+    printf("%s age %d\n",name,age);
+    printf(fmt,name,age);
+    putchar(drv);
+    putchar('*');
+  }
+  
+  U0 DemoHolyC(U8 drv,U8 *fmt,U8 *name,I64 age)
+  {
+    "Hello World!\n";
+    "%s age %d\n",name,age;
+    "" fmt,name,age;
+    '' drv;
+    '*';
+  }
+
+* When dealing with function addresses such as for callbacks, precede the name 
+with "&".
+
+* Type casting is postfix.  To typecast int or F64, use ToI64(), ToBool() or 
+ToF64(). (TempleOS follows normal C float<-->int conversion, but sometimes you 
+want to override.  These functions are better than multiplying by "1.0" to 
+convert to float.) 
+
+* There is no main() function.  Any code outside of functions gets executed upon 
+start-up, in order.
+
+* There are no bit fields, but there are bit access routines and you can access 
+bytes or words within any int.  See I64 declaration.  A class can be accessed as 
+a whole are subints, if you put a type in front of the class declaration.
+  
+  public I64i union I64         //"I64i" is intrinsic.  We are defining "I64".
+  {
+    I8i i8[8];
+    U8i u8[8];
+    I16 i16[4];
+    U16 u16[4];
+    I32 i32[2];
+    U32 u32[2];
+  };
+  
+  I64 i=0x123456780000DEF0;
+  i.u16[1]=0x9ABC;
+
+* Variable arg count functions (...) can access their args with built-in 
+variables similar to 'this' in C++.  They are 'I64 argc' and 'I64 argv[]'.  
+  
+  I64 AddNums(...)
+  {
+    I64 i,res=0;
+    for (i=0;i<argc;i++)
+      res+=argv[i];
+    return res;
+  }
+  
+  >AddNums(1,2,3);
+  ans=6
+  
+  
+  public U0 GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...)
+  {
+    U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);//SPrintF() with MAlloc()ed string.
+    GrPutS(dc,x,y,buf); //Plot string at x,y pixels. GrPutS is not public.
+    Free(buf);
+  }
+  
+    ...
+  
+    GrPrint(gr.dc,(GR_WIDTH-10*FONT_WIDTH)>>1,(GR_HEIGHT-FONT_HEIGHT)>>1,
+        "Score:%4d",score);  //Print score in the center of the scrn.
+    ...
+  
+
+* Allows "5<i<j+1<20" instead of "5<i && i<j+1 && j+1<20".
+  
+  if (13<=age<20)
+    "Teen-ager";
+
+* if you know a switch stmt will not exceed the lowest or highest case values.  
+switch [] is a little faster because it doesn't check.
+
+* switch stmts always use a jump table.  Don't use them with cases with really 
+big, sparse ranges.
+
+* Allows ranges like "case 4...7:" in switch stmts.
+
+* A no case number causes next higher int case in switch stmts.  See 
+::/Demo/NullCase.HC.
+
+  I64 i;
+  for (i=0;i<20;i++) 
+    switch (i) {
+      case: "Zero\n";   break; //Starts at zero
+      case: "One\n";    break; //One plus prev case.
+      case: "Two\n";    break;
+      case: "Three\n";  break;
+      case 10: "Ten\n"; break;
+      case: "Eleven\n"; break; //One plus prev case.
+  }
+
+* Switch statements can be nestled with a single switch expression!  This is 
+known as a "sub_switch" statement.  start/end are used to group cases.  Don't 
+goto out of, throw an exception out of, or return out of the start front porch 
+area.  See ::/Demo/SubSwitch.HC.
+
+  I64 i;
+  for (i=0;i<10;i++)
+    switch (i) {
+      case 0: "Zero ";  break;
+      case 2: "Two ";   break;
+      case 4: "Four ";  break;
+      start:
+        "[";
+        case 1: "One";  break;
+        case 3: "Three";break;
+        case 5: "Five"; break;
+      end:
+        "] ";
+        break;
+    }
+  OutPut:
+  >Zero [One] Two [Three] Four [Five]
+
+* A no_warn stmt will suppress an unused var warning.
+
+* You can have multiple member vars of a class named "pad" or "reserved", and it 
+won't issue warnings. 
+
+* noreg or reg can be placed before a function local var name.  You can, 
+optionally, specify a reg after the reg keyword.
+
+  U0 Main()
+  {
+    //Only use REGG_LOCAL_VARS or REGG_LOCAL_NON_PTR_VARS for reg vars or else 
+  clobbered.
+    I64 reg R15 i=5, noreg j=4;
+    no_warn i;
+    asm {
+        MOV     RAX,R15
+        CALL    &PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    &PUT_CHARS
+        MOV     RAX,U64 &j[RBP]
+        CALL    &PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    &PUT_CHARS
+    }
+  }
+
+* interrupt, haserrcode, public, argpop or noargpop are function flags. See 
+IRQKbd().
+
+* A single quote can encompass multiple characters.  'ABC' is equ to 0x434241.  
+PutChars() takes multiple characters.
+
+  asm {
+  HELLO_WORLD::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,'Hello '
+        CALL    &PUT_CHARS
+        MOV     RAX,'World\n'
+        CALL    &PUT_CHARS
+        LEAVE
+        RET
+  }
+  Call(HELLO_WORLD);
+  PutChars('Hello ');
+  PutChars('World\n');
+
+* The "`" operator raises a base to a power.
+
+* There is no question-colon operator.
+
+* TempleOS operator precedence
+  `,>>,<<
+  *,/,%
+  &
+  ^
+  |
+  +,-
+  <,>,<=,>=
+  ==,!=
+  &&
+  ^^
+  ||
+  =,<<=,>>=,*=,/=,&=,|=,^=,+=,-=
+
+* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in 
+code.
+
+* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find dup local var type stmts.
+
+* With the #exe{} feature in your src code, you can place programs that insert 
+text into the stream of code being compiled.  See #exe {} for an example where 
+the date/time and compile-time prompting for cfguration data is placed into a 
+program.  StreamPrint() places text into a src program stream following the 
+conclusion of the #exe{} blk.
+
+* No #define functions exist (I'm not a fan)
+
+* No typedef, use class.
+
+* No type-checking
+
+* Can't use <> with #include, use "".
+
+* "$" is an escape character.  Two dollar signs signify an ordinary $.  See 
+DolDoc.  In asm or HolyC code, it also refers to the inst's address or the 
+offset in a class definition. 
+
+* union is more like a class, so you don't reference it with a union label after 
+you define it.  Some common unions are declared in KernelA.HH for 1,2,4 and 8 
+byte objects.  If you place a type in front of a union declaration, that is the 
+type when used by itself.  See ::/Demo/SubIntAccess.HC. 
+
+* class member vars can have meta data. format and data are two meta data types 
+now used.  All compiler structures are saved and you can access the compiler's 
+info about classes and vars.  See ::/Demo/ClassMeta.HC and  DocForm().
+
+* There is a keyword lastclass you use as a dft arg.  It is set to the class 
+name of the prev arg.  See ::/Demo/LastClass.HC, ClassRep(), DocForm()  and 
+::/Demo/Dsk/BlkDevRep.HC.
+
+* See ::/Demo/Exceptions.HC.  try{} catch{} and throw are different from C++. th
+row is a function with an 8-byte or less char arg.  The char string passed in th
+row() can be accessed from within a catch{} using the Fs->except_ch.  Within a c
+atch {} blk, set the var Fs->catch_except to TRUE if you want to terminate the 
+search for a hndlr.  Use PutExcept() as a hndlr, if you like.
+
+* A function is available similar to sizeof which provides the offset of a 
+member of a class.  It's called offset.  You place the class name and member 
+inside as in offset(classname.membername).  It has nothing to do with 16-bit 
+code.  Both sizeof and offset only accept one level of member vars.  That is, 
+you can't do sizeof(classname.membername.submembername).
+
+* There is no continue stmt.  Use goto.
+
+* lock{} can be used to apply asm LOCK prefixes to code for safe multicore 
+read-modify-write accesses.  The code bracked with have LOCK asm prefix's 
+applied to relevant insts within.  It's a little shoddy.  See 
+::/Demo/MultiCore/Lock.HC.
+
+* There is a function called MSize() which gives the size of an object alloced 
+off the heap.  For larger size allocations, the system rounds-up to a power of 
+two, so MSize() lets you know the real size and you can take full advantage of 
+it.
+
+* You CAN Free() a NULL ptr.  Useful variants of MAlloc() can be found Here.  
+Each task has a heap and you can MAlloc and Free off-of other task's heaps, or 
+make an independent heap with HeapCtrlInit().  See HeapLog() for an example.
+
+* The stk does not grow because virtual mem is not used.  I recommend allocating 
+large local vars from the heap.  You can change MEM_DFT_STK and recompile Kernel 
+or request more when doing a Spawn().  You can use CallStkGrow(), but it's odd.  
+See ::/Demo/StkGrow.HC. 
+
+* Only one base class is allowed.
+
+* printf() has new codes.  See Print("") Fmt Strings.
+
+* All values are extended to 64-bit when accessed.  Intermediate calculations 
+are done with 64-bit values.
+
+  U0 Main()
+  {
+    I16 i1;
+    I32 j1;
+    j1=i1=0x12345678;           //Resulting i1 is 0x5678 but j1 is 0x12345678
+  
+    I64 i2=0x8000000000000000;
+    Print("%X\n",i2>>1);        //Res is 0xC000000000000000 as expected
+  
+    U64 u3=0x8000000000000000;
+    Print("%X\n",u3>>1);        //Res is 0x4000000000000000 as expected
+  
+    I32 i4=0x80000000;          //const is loaded into a 64-bit reg var.
+    Print("%X\n",i4>>1);        //Res is 0x40000000
+  
+    I32 i5=-0x80000000;
+    Print("%X\n",i5>>1);        //Res is 0xFFFFFFFFC0000000
+  }
+
+
+ diff --git a/public/Wb/Home/Src/Doc/InFile.DD.HTML b/public/Wb/Home/Src/Doc/InFile.DD.HTML new file mode 100755 index 0000000..ef12804 --- /dev/null +++ b/public/Wb/Home/Src/Doc/InFile.DD.HTML @@ -0,0 +1,49 @@ + + + + + + + + + + + +
+InFiles are used to generate user input to automate operations.  The TempleOS 
+tour is done with an InFile.  It reminds me of a Unix pipe because StdOut of one 
+gets chained into StdIn of another.
+
+When an InFile runs, a child task is Spawn()ed which intercepts real user input 
+and generates fake input.  InFiles are HolyC programs run by the child whose 
+stdout goes to the parent's input buffer.  Msg() can be included in an InFile to 
+send special keys or mouse cmds to the parent.  While an InFile is running, the 
+normal input gets diverted to the InFile task and can be filtered and sent back 
+to the parent task.  Unless you are driving functions which prompt for data, you 
+can probably use an #include file in place of an InFile.
+
+See ::/Demo/InFile/InDir.IN.
+
+Note: In("") can be used if all you need is to send ASCII characters.  It 
+differs from InStr().  You'll probably use In() a lot and not InStr().  With In(
+), for example, you can place answers to the prompts for recompiling the Kernel 
+module during BootHDIns().
+
+ diff --git a/public/Wb/Home/Src/Doc/Install.DD.HTML b/public/Wb/Home/Src/Doc/Install.DD.HTML new file mode 100755 index 0000000..3c29a84 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Install.DD.HTML @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+                              Installing TempleOS
+
+Burn a CD with software that supports ISO files.  Then, boot it.  It's a live 
+CD, so you can look around with or without installing.
+
+Dual booting with another operating system is the best way to use TempleOS.  I 
+only use it in a virtual machine because it won't boot natively on my machine, 
+though.  For native dual booting, you need a partition for TempleOS.  Windows 
+often comes with a restore disk that does not allow repartitioning.  I recommend 
+connecting a spare additional hard drive and using the BIOS to select which 
+drive to boot.
+
+The ::/Misc/OSInstall.HC script will automate much of this.  It runs if you boot 
+the CD/DVD-ROM.
+
+See Boot.DD for an overview of booting.  See Requirements for supported 
+hardware.
+
+Two TempleOS partitions are highly recommended, so you can boot to a back-up and 
+fix the primary when you work on it.  Odds are, you only need a couple gigabytes 
+for your TempleOS partitions.
+
+1)
+  Mount() use if the drive is partitioned.
+    This command mounts a drive making it accessible.  For simplicity, sel 'C' 
+    as the first drive letter for your hard drive.  The first partition will be 
+    'C', second, 'D', etc.  TempleOS needs 3 numbers to utilize a hard drive -- 
+    base0, base1, and unit.  When you enter a hexadecimal number, do it like in 
+    C with a 0x prefix.  If the probe was successful, you can just enter the 
+    number in the probe box instead of base0.
+  
+  DskPrt('C') use if drive is not partitioned
+  
+    This will perform a special Mount() automatically.
+    
+    WARNING:  This command erases everything on a hard drive.  It repartitions a 
+    whole drive and formats the partitions.  This command should be skipped if 
+    you already have your hard drive partitioned.
+    
+    
+    WARNING:  This command doesn't play well with other operating systems.  
+    You'll need to do a BootMHDZero() to restore your drive to a state where 
+    other operating systems can partition it.
+  
+2) Fmt('D',TRUE,FALSE,FSt_FAT32)
+  This command formats a drive with FAT32 or the RedSea file system type.  Use 
+  the drive letter of the partition in place of 'D'.
+  
+  WARNING:  If you are upgrading, be sure not to lose the file, /0000Boot/OldMBR
+  .BIN.C.
+  
+3) CopyTree("T:/","D:/")
+  This command is used to copy files onto a hard drive partition from the 
+  CD/DVD.  Use the drive letter of the partition in place of 'D'.
+  
+4) BootHDIns('D')
+  This command recompiles the source code on a drive and writes to the drive's 
+  boot record.  You'll need to reenter the Mount information so it can be stored 
+  in the kernel.
+  
+5) Use Linux's Grub or TempleOS' BootMHDIns('D')
+  
+  The BootMHDIns() command places a boot loader on a drive.  It saves the old 
+  master boot record to /0000Boot/OldMBR.BIN.C and replaces it.  When you boot, 
+  you will have the option of booting the old master boot record.  This command 
+  can be skipped if you already have a boot loader.  Be sure not to lose the 
+  copy of the old boot record, like if you reformat the drive.
+  
+  Delete /0000Boot/OldMBR.BIN.C if you want to get a fresh copy of a mbr, like 
+  if installing from your own custom CD containing it's own /0000Boot/OldMBR.BIN
+  .C onto a system with a non-TempleOS boot loader.
+  
+  If you have anti-virus software, it might object to having a different master 
+  boot record.
+
+
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Src/Doc/Job.DD.HTML b/public/Wb/Home/Src/Doc/Job.DD.HTML new file mode 100755 index 0000000..ecb46f6 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Job.DD.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+               PopUpPrint                         User          ExePrint
+
+
+
+                  PopUp                                          ExePutS
+
+
+
+ Core0 AdamTask  SrvCmdLine   AP SethTask       UserCmdLine
+
+
+
+
+
+
+         SrvTaskCont                          UserTaskCont
+
+
+
+        JobsHndlr
+
+
+
+         JobRunOne           JobRunOne         ExeCmdLine      ExeCmdLine
+
+
+
+
+CJob nodes are one of five types.  User applications deal with text or msgs.  
+JobRunOne() will call a function, spawn a task or execute some text src code.
+
+#define JOBT_TEXT_INPUT         0 //TaskText()  Feed StdIn 
+#define JOBT_MSG                1 //TaskMsg()   Post msg 
+#define JOBT_EXE_STR            2 //TaskExe()   Compile & execute src code text
+#define JOBT_CALL               3 //JobQue()    Tell MP to call function
+#define JOBT_SPAWN_TASK         4 //Spawn()     Tell MP to spawn task
+
+Several other routines include a call to JobsHndlr() that gives them powerful 
+ability to execute servant cmds.
+
+ diff --git a/public/Wb/Home/Src/Doc/KeyAlloc.DD.HTML b/public/Wb/Home/Src/Doc/KeyAlloc.DD.HTML new file mode 100755 index 0000000..815eb33 --- /dev/null +++ b/public/Wb/Home/Src/Doc/KeyAlloc.DD.HTML @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+                                Key Allocations
+
+See Char for definition of scan codes.
+
+See Key Map for a detailed list of key commands.
+
+When you are at the cmd line, editing documents, browsing documentation and 
+help, entering items in forms or in menu's, the DolDoc editor handles keys.  It 
+allows you to define your own key hndlrs in a MyPutKey() function.  If you 
+choose, you can catch keys, overriding the default hndlrs.  See DocPutKey().  
+The following is an overview of key allocations.
+
+<ALT-keys> and <ALT-SHIFT-keys>  Free for user configurations in your MyPutKey() 
+hndlr, except for ALT-BACKSPACE (undo).  There are a few examples pre-defined, 
+but you can change them if you wish.
+
+<CTRL-ALT-keys> and <CTRL-ALT-SHIFT-keys>  Handled at a system level, NOT by the 
+CDoc editor.  I reserve the right to alloc these, but in the mean time, you can 
+define your own hndlrs with CtrlAltCBSet().  They operate either in a interrupt 
+environment or in the window mgr when it queues kbd msgs.  You can do Raw() 
+output.  <CTRL-ALT-letter> hndlrs take a scan_code as an arg.
+
+<CTRL-function key>  Auto-completes local words.
+
+<CTRL-digit key>  Auto-completes dictionary words.
+
+<CTRL-SHIFT-function key>  Jumps to src code.
+
+<CTRL-SHIFT-digit key>  Jumps to dictionary definition.
+
+<function keys> and <SHIFT-function keys>  I reserve the right to alloc these, 
+but there are some free now.
+
+<CTRL-key> and <CTRL-SHIFT-key>  I reserve the right to alloc to these.  There 
+are not many free.
+
+See Keyboard Devices.
+
+ diff --git a/public/Wb/Home/Src/Doc/KeyDev.DD.HTML b/public/Wb/Home/Src/Doc/KeyDev.DD.HTML new file mode 100755 index 0000000..f7c40a2 --- /dev/null +++ b/public/Wb/Home/Src/Doc/KeyDev.DD.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+The editor mostly stays in a GetKey()/PutKey() loop.  The putkey portion is 
+where keys are acted-upon.  TempleOS has a chain of putkey hndlrs in a 
+Circular Queue with priorities.  The highest priority hndlrs can choose to 
+terminate handling, otherwise, the keys get sent on down the chain.
+
+KeyDevAdd() defines a putkey device with a priority.  "Device" might be a 
+misnomer.  Currently, the following are defined:
+
+Priority    Hndlr
+---------- ---------
+0x20000000 MyPutKey() user hndlr
+0x40000000 KDInputFilterPutKey() for In(), InStr(), and InFile() handling.
+0x60000000 KDRawPutKey() nonwindowed direct to video mem debug output. 
+0x80000000 KDDocPutKey() standard document cmds
+
+Since handling individual keys is slow, TempleOS supports PutS() as well.  If no 
+puts hndlr is defined, individual keys are sent.
+
+CDoc.user_put_key and CDoc.user_put_s are call back routines which offer some 
+neat tricks.  See ::/Apps/Psalmody/JukeBox.HC.  There is a var CDoc.user_put_dat
+a which gets passed to them.
+
+ diff --git a/public/Wb/Home/Src/Doc/Lex.DD.HTML b/public/Wb/Home/Src/Doc/Lex.DD.HTML new file mode 100755 index 0000000..c5ec281 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Lex.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+The compiler's lexical analyzer can be used in your programs to simplify 
+parsing.  See Doc Parsing or Parse Opcode File.
+
+See Tokens.
+
+ diff --git a/public/Wb/Home/Src/Doc/MemOverview.DD.HTML b/public/Wb/Home/Src/Doc/MemOverview.DD.HTML new file mode 100755 index 0000000..1e27208 --- /dev/null +++ b/public/Wb/Home/Src/Doc/MemOverview.DD.HTML @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+                                Memory Overview
+
+Paging is practically not used.  64-bit mode requires paging, however, so it is 
+identity-mapped -- virtual identical to physical.  All tasks on all cores use 
+the same page table map, just as though all addresses are physical addresses.  
+2Meg or 1Gig page table entries are used.  Nothing swaps to disk.
+
+In TempleOS, the lowest 2Gig of memory is called the code heap.  TempleOS's 
+compiler always uses 32-bit signed relative JMP & CALL insts because 64-bit 
+CALLs take two insts.  With signed +/- 32-bit values, code can only call a 
+function within 2Gig distance.  Therefore, TempleOS keeps all code in the lowest 
+2Gig memory addresses including what would normally be called "the kernel".  Two 
+Gig is plenty for code, don't worry.
+
+You can create new, independent heaps using HeapCtrlInit().  Then, use the 
+CHeapCtrl as the 2nd arg to MAlloc().  See HeapLog() for an example.
+
+Memory alloced by a task will be freed when the task is killed.  The Adam Task 
+is a task that never dies.  His memory is like kernel memory in other operating 
+systems.  See ACAlloc(), AMAlloc(), AMAllocIdent() and AStrNew().
+
+All of the regular page tables are marked, "cached".  When accessing hardware, 
+however, you need uncached page table.  The lowest 4Gig addresses have an alias 
+to access hardware located toward the top of mapped space, 0x10000000000.  See 
+dev.uncached_alias.
+
+During an extended powered-on session of TempleOS, in theory, memory will become 
+fragmented, requiring a reboot.  It has never happens to me.
+
+See MemRep() and ::/Demo/MemDemo.HC.
+
+
+                           Single System-wide Mem Map
+
+ 0x0000007C00- 0x000003616F
+  Kernel module, placed here by the boot-loader, BOOT_RAM_BASE.
+
+ 0x0000096600- 0x0000096FFF
+  Boot block relocated here before loading the Kernel module, BootDVD & BootHD.
+
+ 0x0000097000- 0x0000097030 Multicore start-up vect code, MPN_VECT.
+~0x000009F000- 0x000009FFFF Extended BIOS data area.
+ 0x00000A0000- 0x00000BFFFF VGA graphics mem with alias at text.vga_alias.
+ 0x0000100000- 0x0000101FFF CSysFixedArea for misc.
+ 0x000050A000- 0x001FFDFFFF Code Heap mem.
+
+ 0x00E0000000- 0x00FFFFFFFF
+  32-bit devices could alloc memory at 0xF0000000 going up, but this is wrong, 
+  since some PCs already have devices at 0xF0000000.  No PCI devices are 
+  supported, so Mem32DevAlloc() flaws are not an issue.
+
+ 0x0080000000-~0x00DFFFFFFF
+ 0x0100000000-~0xFFFFFFFFFF
+  Data Heap mem.  (The physical memory that exists in this range is data heap.)
+
+ 0x10000000000- 0x100FFFFFFFF
+  Uncached alias of first 4Gig.  (For 32-bit device access.)
+
+             - 0x100FFFFFFFF
+  64-bit devices are alloced with Mem64DevAlloc() counting bwd, but no PCI 
+  devices are actually supported.
+
+
+
+* Note: There is a break in the data-heap block pool.  This has no effect except 
+the obvious effect that fragmentation has on contiguous requests.  I can MAlloc(
+) an 8Gig chunk on my 12Gig machine.  I can MAlloc() an 32Gig chunk on my 64Gig 
+machine.  
+
+* Note: For systems with less than 2Gig RAM, the code and data heap block pools 
+are the same.  For systems with 2-4Gig of RAM, the code heap is 1/4 of the 
+total.  See BlkPoolsInit().
+
+
+                                    History
+
+In 2003, I wanted to make a no-paging ring-0-only 64-bit operating system for 
+super speed with simplicity and full access.  With paging, every memory request 
+requires 5 accesses -- it must access the address itself, 4K, 2Meg, 1Gig, and 
+512Gig page tables, but the CPU's translation look-aside buffer mostly removes 
+the penalty for using paging.  So, I did not want to use paging, but long mode 
+requires it.  I did the next best thing -- I identity-mapped everything and 
+achieved the simplicity I was after with subtle performance boosts, not wasting 
+time changing address maps.  And, I look forward to the day I command Intel to 
+make an optimized no-paging long mode.
+
+I needed VGA A0000-BFFFF memory to be write-through and 0xE0000000-0xFFFFFFFF to 
+be uncached for various devices.  All 64-bit computers allow stopping address 
+translation at 2Meg page size, not using 4K.  I wanted to use 2Meg for 
+everything because it's faster, with one less level of page tables.  I had to 
+make A0000-BFFFF write-through, though, so I could not use 2Meg size on the 
+lowest page.  I did the lowest 2Meg area as 4K pages.  I also unmapped the first 
+4K to cause a fault when dereferencing NULL.
+
+In 2016, I came-up with an alternate idea.  I double mapped the lowest memory 
+with an alias that was uncached.  Accessing the lowest 2Meg area directly was 
+cached but the alias I created up at the top of address space was uncached.  See 
+UncachedAliasAlloc().  Unfortunately, I could no longer boast of the simplicity 
+of identity mapping everything.  Since many of my users are familiar with 
+A0000-BFFFF, it is actually pretty seriously unfortunate that they cannot use 
+the easy-to-understand numbers of A0000-BFFFF, but must access the relocated 
+alias location.  See text.vga_alias.  I also no longer cause a fault when 
+dereferencing NULL.
+
+Then, I switched to 1Gig page sizes.  For the lowest 4Gig, I set-up an alias up 
+at the top of address space.  See UncachedAliasAlloc().  Not all computers 
+support 1Gig page tables, however, so I also support 2Meg.
+
+My original plan was to allow changing the page tables as needed, so I had code 
+for taking control of 2Meg pages and marking them uncached or whatever.  When I 
+did a HDAudio driver, I requested some 32-bit address space as uncached.  Today, 
+all of the first 4Gig can be accessed without caching at the dev.uncached_alias.
+
+ diff --git a/public/Wb/Home/Src/Doc/Menus.DD.HTML b/public/Wb/Home/Src/Doc/Menus.DD.HTML new file mode 100755 index 0000000..dc8d4b0 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Menus.DD.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+A pull-down menu appears when you move the mouse to the top of the scrn.  Menus 
+are created with MenuPush(), MenuFilePush(), MenuNew() or MenuFile() and 
+assigned to Fs->cur_menu.  The format is:
+
+
+File 
+{
+  Open(,'O');
+  Save(,'S');
+  Exit(,CH_SHIFT_ESC);
+}
+Edit {
+  Cut(,,SC_DELETE|SCF_SHIFT);
+  Paste(,,SC_INS|SCF_SHIFT);
+}
+Misc {
+  Opt1(MSG_CMD,M_OPTION1);
+  Opt2(MSG_CMD,M_OPTION2);
+}
+Help
+{
+  Help(,'?');
+  About(,'/');
+}
+
+The first arg is the msg code and it is optional with the default being 
+MSG_KEY_DOWN_UP.  The second arg is the msg arg1 value which is ASCII of the key 
+in the case of MSG_KEY_DOWN.  The third arg is the msg arg2 value which is the 
+scan_code of the key in the case of MSG_KEY_DOWN.
+
+Press <CTRL-SHIFT-l> and "Insert ASCII/ScanCode".
+
+See ::/Demo/PullDownMenu.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/Mouse.DD.HTML b/public/Wb/Home/Src/Doc/Mouse.DD.HTML new file mode 100755 index 0000000..6c36bfb --- /dev/null +++ b/public/Wb/Home/Src/Doc/Mouse.DD.HTML @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+ms.pos.x and ms.pos.y can be used to access the x and y coordinates of the 
+mouse.  They are relative to the scrn, not window.  These can be used if you 
+don't want to use msg passing.  ms.pos.z is the wheel.
+
+ms.pos_text.x and ms.pos_text.y are the text column and row.  See 
+::/Demo/Games/Maze.HC.
+
+See CMsStateGlbls and CMsHardStateGlbls.
+
+The hard designation, as in ms_hard, represents hardware layer items before the 
+application of an abstraction layer.
+
+//****
+ms_hard.pos.x=ms_hard.prescale.x*ms_hard.scale.x*ms_grid.x_speed;
+ms.presnap.x=ToI64(ms.scale.x*ms_hard.pos.x)+ms.offset.x;
+if (ms_grid.snap)
+  ms.pos.x=Trunc(ms.presnap.x/ms_grid.x)*ms_grid.x+ms_grid.x_offset;
+else
+  ms.pos.x=ms.presnap.x;
+//****
+
+ diff --git a/public/Wb/Home/Src/Doc/Msgs.DD.HTML b/public/Wb/Home/Src/Doc/Msgs.DD.HTML new file mode 100755 index 0000000..dee3f4b --- /dev/null +++ b/public/Wb/Home/Src/Doc/Msgs.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+There are a maximum of 63 message types, so a bitmask can be passed.  Messages 
+have two args.  See Message Codes.
+
+ diff --git a/public/Wb/Home/Src/Doc/MultiCore.DD.HTML b/public/Wb/Home/Src/Doc/MultiCore.DD.HTML new file mode 100755 index 0000000..5e9b63c --- /dev/null +++ b/public/Wb/Home/Src/Doc/MultiCore.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+TempleOS does master-slave multicore instead of SMP.  Core0 is the master.  The 
+master core's applications explicitly assign computational jobs to other cores 
+and the TempleOS scheduler does not move tasks between cores.
+
+There are multicore safe locks for file access and heap allocations, however, so 
+TempleOS is symmetrical in some sense.  See ::/Demo/MultiCore/LoadTest.HC.
+
+Only tasks on Core0 can have windows, but other cores can help render them.
+
+Each core has an executive Seth Task which is the father of all tasks on that 
+core.  Adam is the Seth Task on Core0.
+
+You give a job to a Seth Task with JobQue() and get the result with JobResGet(). 
+ You spawn a task on any core with Spawn().
+
+Note: You must use the LOCK asm prefix when changing shared structures in a 
+multicore environment.  The LBts(), LBtr() and LBtc() insts have LOCK prefixes.  
+The compiler has a lock{} feature but it doesn't work well.  See 
+::/Demo/MultiCore/Lock.HC.
+
+See ::/Demo/Graphics/Transform.HC.
+See ::/Kernel/MultiProc.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/NewASCII.DD.HTML b/public/Wb/Home/Src/Doc/NewASCII.DD.HTML new file mode 100755 index 0000000..769a5ec --- /dev/null +++ b/public/Wb/Home/Src/Doc/NewASCII.DD.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+                                   New ASCII
+
+
+We want to use one set for ASCII, ScanCodes and ScreenCodes.
+
+
+0  -63  :
+64 -127 : SHIFT
+128-191 : CTRL
+192-256 : CTRL+SHIFT
+
+No more ALT key in TempleOS.
+
+CTRL-LEFT/RIGHT is already begin/end line.
+CTRL-UP/DOWN    is already top/bottom of document.
+
+What about function keys?
+We will use reduced keyboard, probably.
+
+
+
+God says...
+clearest bade domine chance none quoth privily subjection possessor abolished
+
+
+
+
+ diff --git a/public/Wb/Home/Src/Doc/ODE.DD.HTML b/public/Wb/Home/Src/Doc/ODE.DD.HTML new file mode 100755 index 0000000..030966f --- /dev/null +++ b/public/Wb/Home/Src/Doc/ODE.DD.HTML @@ -0,0 +1,40 @@ + + + + + + + + + + + +
+TempleOS has an advanced algorithm for integrating ordinary differential 
+equations suitable for use in video games.  (Not scientific work.)  It also has 
+some support for systems of masses and springs, to save you some work.
+
+See CMathODE and ODEsUpdate for an overview.
+See ODECallDerivative to see what support there is for masses and springs.
+
+See ::/Demo/Games/Whap.HC, ::/Demo/Games/Rocket.HC, ::/Demo/Games/MassSpring.HC, 
+::/Apps/Span/SpanMain.HC or ::/Apps/X-Caliber/X-Caliber.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/Once.DD.HTML b/public/Wb/Home/Src/Doc/Once.DD.HTML new file mode 100755 index 0000000..78b2712 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Once.DD.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+KMain()
+  includes ::/StartOS.HC
+    includes ~/MakeHome.HC
+      includes ~/HomeSys.HC
+        calls StartUpTasks()
+          includes ~/Once.HC
+            calls OnceExe().
+
+AOnce() appends src code to ~/Registry.HC Once/Adam tree, executed at next boot 
+by Adam.
+
+Once()  appends src code to ~/Registry.HC Once/User tree, executed at next boot 
+by first User term.
+
+At boot, OnceExe(), executes Once/Adam tree, AOnceFlush()s it,
+executes Once/User tree and OnceFlush()s.
+
+ diff --git a/public/Wb/Home/Src/Doc/Options.DD.HTML b/public/Wb/Home/Src/Doc/Options.DD.HTML new file mode 100755 index 0000000..def5955 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Options.DD.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+                                Compiler Options
+
+Use Option().  You might need to do #exe {Option();}.
+
+OPTf_GLBLS_ON_DATA_HEAP without this option, global vars are placed in the code 
+heap which is limited to 2Gig.  In AOT modules, global vars take-up room in the 
+.BIN file, so you might want to use this option, instead.  You might wish to 
+turn it on and off around specific vars.  A disadvantage of data heap global 
+vars in AOT modules is they can't be initialized.
+
+OPTf_EXTERNS_TO_IMPORTS and OPTf_KEEP_PRIVATE are strange options, you'll never 
+need.  They're to allow the same header file for Kernel to act as externs when 
+compiling itself and imports when compiled by AOT modules.
+
+OPTf_WARN_UNUSED_VAR    warning if unused var.  It is applied to functions.
+
+OPTf_WARN_PAREN         warning if parenthesis are not needed.
+
+OPTf_WARN_DUP_TYPES     warning if dup local var type stmts.
+
+OPTf_WARN_HEADER_MISMATCH warning if fun header does not match.
+
+OPTf_NO_REG_VAR forces all function local vars to the stk not regs.  Applied to 
+functions.
+
+OPTf_NO_BUILTIN_CONST Disable 10-byte float consts for pi, log2_10, log10_2, 
+loge_2.  Applied to functions.
+
+ diff --git a/public/Wb/Home/Src/Doc/Pags.DD.HTML b/public/Wb/Home/Src/Doc/Pags.DD.HTML new file mode 100755 index 0000000..bb1cb6a --- /dev/null +++ b/public/Wb/Home/Src/Doc/Pags.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+The word Pag refers to an arbitrilly created MEM_PAG_SIZE unit of heap 
+allocation.  TempleOS does not alter the CPU page tables after setting them up 
+at boot in SYS_INIT_PAGE_TABLES, so the CPU hardware page size is rarely 
+important.
+
+ diff --git a/public/Wb/Home/Src/Doc/PreProcessor.DD.HTML b/public/Wb/Home/Src/Doc/PreProcessor.DD.HTML new file mode 100755 index 0000000..80d5b97 --- /dev/null +++ b/public/Wb/Home/Src/Doc/PreProcessor.DD.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+                                  PreProcessor
+
+There is no separate preprocessor pass.  The parser front-end calls Lex() which 
+has the preprocessor built-in.  The compiler looks ahead a token, most of the 
+time, so you might throw an extra semicolon after a directive if it's not taking 
+affect right away.
+
+Put an extra semicolon #exe {Cd("DirName");;} in case a #include follows.
+
+#include ""     There is no angle bracket <> form of this directive.
+#exe {}         Will execute code at compile-time and can be used to insert code 
+into the stream being compiled using StreamPrint().
+#define         Define string const
+#assert         Print a warning during compilation if an expression is not true. 
+#if             Include code if an expresion is true.
+#else
+#endif
+#ifdef,#ifndef  Include code if a sym is defined.
+#ifaot,#ifjit   Include code if in AOT compiler mode.
+defined()       Is a function that can be used in expressions.
+#help_index, #help_file See Help System.
+
+See PreProcessor.
+
+ diff --git a/public/Wb/Home/Src/Doc/Print.DD.HTML b/public/Wb/Home/Src/Doc/Print.DD.HTML new file mode 100755 index 0000000..938606d --- /dev/null +++ b/public/Wb/Home/Src/Doc/Print.DD.HTML @@ -0,0 +1,144 @@ + + + + + + + + + + + +
+                                 Print Fmt Strs
+
+<fmt_arg> := %[-][0][<width>][.<decimals>][<flags>][h<aux_fmt_num>]<fmt_code>
+
+See StrPrintJoin().
+
+<flags>:
+
+  't' truncate to <width>.
+  ',' add commas every three digits or four nibbles.
+  '$' makes %Q convert '$' to "\x24".
+  '/' makes %Q and %q convert '%' to "%%".
+
+<aux_fmt_num>:
+
+  For "%n", "%d" or "%u", the <aux_fmt_num> causes thousands mode.  "%h?n" will 
+  pick a var exponent multiples of three unit, while "%h-3n" will display milli 
+  units or "%h6n" will display mega units.  The 'k' flag is always on for "%n".  
+  See ::/Demo/Print.HC.
+  
+For "%c" or "%C", the <aux_fmt_num> repeats the char that many times.
+
+<fmt_code>:
+
+  "%n" floating point in engineering notation, exponents being multiples of 
+  three.  If it has a <aux_fmt> code, it will display scientific units letters.
+  
+  "%S" Define() entry.
+  
+  "%C" ToUpper() character.
+  
+  "%h25c",'\n'; 25 new-lines.
+  
+  "%h*c",25,'\n'; 25 new-lines.
+  
+  "%F" text file by filename.
+  
+  "%$F" DolDoc file in memory.
+  
+  "%p" ptr. 
+  
+  "%,p" ptr with no offset. 
+  
+  "%P" link to ptr.
+  
+  "%,P" link to ptr with no offset.
+  
+  "%D" date.  Pass a CDate.
+  
+  "%T" time.  Pass a CDate.
+  
+  "%z" sub_entry of an enumerated list of text entries.  See LstSub().  Pass 
+  sub_entry_num first, list second.
+  
+  "%Z" DefineLstLoad() subentry.  Pass sub_entry_num first, define_name second.
+  
+  "%Q" convert "\" to "\\" and quote to backslash quote. (For use in creating 
+  strs in strs.)
+  
+  "%q" rev a "%Q".
+
+
+                                  Print Family
+
+MStrPrint(U8 *fmt,...) is like StrPrint(U8 *dst,U8 *fmt,...) but it returns a 
+MAllocated str.  It is vary handy because you don't have to worry about 
+overflow.
+
+CatPrint(U8 *_dst,U8 *fmt,...) concatenates a formated string.
+
+In(U8 *fmt,...) sends text to the current task's input buffer.
+InStr(U8 *fmt,...) sends text of an InFile to the keyboard stream of the current 
+TASK but can also do mouse cmds.
+
+XTalk(CTask *task,U8 *fmt,...) and text to another task's input buffer.
+XTalkStr(CTask *task,U8 *fmt,...) sends text of an InFile to the keyboard stream 
+of another TASK but can also do mouse cmds.
+
+DocPrint(CDoc *doc,U8 *fmt,...) sends text to a document.  You can buffer to a 
+Doc and save it, providing the functionality of fprintf.  See 
+::/Demo/Dsk/FPrintF.HC.
+
+Adam(U8 *fmt,...) sends text to the Adam Task to be compiled and run.
+AdamLog(U8 *fmt,...) and AdamErr(U8 *fmt,...) send text to the Adam Task to be 
+displayed.
+
+StreamPrint(U8 *fmt,...) sends text to the stream of code being compiled and 
+must reside in a #exe{} blk.
+
+GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...) and GrVPrint() plots text in graphics 
+mode.
+
+TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...) plots to gr.text_base.
+
+ExePrint(U8 *fmt,...) compiles and execute a string.  Note: It returns the res 
+of the last executed expression.
+
+Once(U8 *fmt,...) Writes User code to Registry to be executed next boot.
+
+AOnce(U8 *fmt,...) Writes Adam code to Registry to be executed next boot.
+
+InPrint(I64 mS,U8 *fmt,...) PutChars()s one at a time with a delay.
+
+RawPrint(I64 mS,U8 *fmt,...) sends direct to scrn memory, bypassing window 
+manager.
+
+User(U8 *fmt,...) Spawns a user and execute a string on start-up.
+
+PopUpPrint(U8 *fmt,...) compiles and execute a string in a pop-up win.  Note: It 
+returns the res of the last executed expression.
+PopUpViewPrint(U8 *fmt,...) creates a pop-up window and views text.
+
+Note: Use Print("%s",src) if you need an unmodified string.
+
+ diff --git a/public/Wb/Home/Src/Doc/Profiler.DD.HTML b/public/Wb/Home/Src/Doc/Profiler.DD.HTML new file mode 100755 index 0000000..affc808 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Profiler.DD.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+The profiler records where the CPU was executing when the 1000Hz timer interrupt 
+occured, so you can learn where time is spent.
+
+Use the Prof() depth argument to record a hit in the N routines which called the 
+current routine, as well.
+
+When done collecting statistics, use ProfRep() for a report.  You might need a 
+DocMax() to expand the command line window buffer to fit it all.
+
+Study the code.  The profiler is very simple.  You might want to enhance it or 
+modify it to debug something in particular.
+
+ diff --git a/public/Wb/Home/Src/Doc/Que.DD.HTML b/public/Wb/Home/Src/Doc/Que.DD.HTML new file mode 100755 index 0000000..1b3e289 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Que.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+A Queue is a bunch of MAlloc()ed chunks of mem linked together in a circle with 
+one ptr to the next value and another ptr to the last value.  These ptrs must be 
+stored in the first locations in the structure.
+
+ diff --git a/public/Wb/Home/Src/Doc/Quirks.DD.HTML b/public/Wb/Home/Src/Doc/Quirks.DD.HTML new file mode 100755 index 0000000..c292cd9 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Quirks.DD.HTML @@ -0,0 +1,101 @@ + + + + + + + + + + + +
+                                     Quirks
+
+* You run a risk of problems if you do file operations on the same files 
+simultaneously because there is no file sharing/locking mechanism.  Generally, 
+the last write wins.
+
+* When using FAT32, TempleOS does not generate unique short-entry names, the 
+ones with the ~s.  Not all FAT32 filenames are valid TempleOS names and it will 
+complain.  Do not access FAT32 drives not dedicated to TempleOS.  Disable them 
+with DrvEnable(OFF), or they will generate error messages.  FAT32 involves a 
+long and short name for each file.
+
+* The stk does not grow because virtual mem is not used.  I recommend allocating 
+large local vars from the heap.  You can change MEM_DFT_STK and recompile Kernel 
+or request more when doing a Spawn().
+
+* The syntax highlighting occassionally glitches.  The compiler doesn't.
+
+* Call DskChg() when you insert a new removable media.
+
+* Accessing CD/DVD's is flacky.  Try Drv() or DskChg() twice.
+
+* You can only extern something once.  There is a varient called _extern which 
+binds a HolyC definition to a asm sym.  This, too, can only be done once.
+
+* A terminal task has a CDoc document structure that remains active even when 
+you change Fs->draw_it.  To prevent links in the CDoc from being activated when 
+the user clicks in the window, do one of three things:
+  
+  A) DocBottom() followed by DocClear() to clear the CDoc so it has no active 
+  widgets.
+  
+  B) Disable window mgr bttn click checking with Fs->win_inhibit set to mask 
+  WIF_SELF_MS_L|WIF_FOCUS_TASK_MS_L_D|WIF_SELF_MS_R|WIF_FOCUS_TASK_MS_R_D.  This 
+  inhibits window mgr operations but still generates messages from bttn clicks.
+
+* switch/case stmts alloc a single jump table--do not use with wide, sparse 
+ranges of case values.
+
+* Don't do a goto out of a try{}.
+
+* A goto label name must not match a global scope object's name.  (It's not 
+worth slowing-down the compiler to handle this case.)
+
+* MemCpy() only goes fwd.
+
+* A Cd() cmd must be followed by two semicolons if a #include is after it.  This 
+is because the preprocessor processes the next token ahead.
+
+* The assembler's error msgs are often off by a line and undefines are cryptic.
+
+* The last semicolon on the cmd line is converted to a dbl semicolon because the 
+compiler looks ahead before doing a cmd.  This normally has no negative effect, 
+but when entering if stmts with else clauses it presents problems.
+
+* You can do a class fwd reference by using extern on the first declaration, but 
+you can only do ptr references to the class.
+
+* When doing something like
+    U0 Main()
+    {
+      U16 *_w=0xA0000;
+      *_w|=0x8000;
+    }
+  The |= will be coded as a U32 Bts inst resulting in a U32 access instead of a 
+  U16 access.  This affects some hardware operations.
+
+* Compiler warning or error message line numbers will be off if you have a block 
+of word-wrapped comments.  You might press <CTRL-t> before doing an editor 
+goto-line-number command.
+
+ diff --git a/public/Wb/Home/Src/Doc/RedSea.DD.HTML b/public/Wb/Home/Src/Doc/RedSea.DD.HTML new file mode 100755 index 0000000..03bd00d --- /dev/null +++ b/public/Wb/Home/Src/Doc/RedSea.DD.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+                               RedSea File System
+
+The RedSea file system is a simple, 64-bit, file system which is similar to 
+FAT32, but with absolute block addresses instead of clus, fixed-sized 64-byte 
+directory entries and no FAT table, just an allocation bitmap.  A clus is just 
+one 512 byte sector.  Files are stored in contiguous blocks and cannot grow in 
+size.
+
+#define CDIR_FILENAME_LEN       38 //Must include terminator zero
+
+The following bit field shows valid 8-Bit ASCII filename characters.
+
+U32 char_bmp_filename[8]=
+{0x0000000, 0x03FF73FB, 0xEFFFFFFF, 0x2FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 
+0xFFFFFFFF, 0xFFFFFFFF};
+
+public class CDirEntry //64-byte fixed-size
+{
+  U16 attr;     //See RS_ATTR_DIR.  I would like to change these.
+  U8 name[CDIR_FILENAME_LEN]; //See char_bmp_filename, FileNameChk
+  I64 clus; (blk) //One sector per clus.
+  I64 size;     //In bytes
+  CDate datetime; //See  DateTime, Implementation of DateTime
+};
+
+public class CRedSeaBoot //RedSea is type FAT32 in partition table to fool BIOS.
+{
+  U8 jump_and_nop[3];
+  U8 signature,reserved[4]; //MBR_PT_REDSEA=0x88. Distinguish from real FAT32.
+  I64 drv_offset;       //For CD/DVD image copy.
+  I64 sects;
+  I64 root_clus; (root_blk)
+  I64 bitmap_sects;
+  I64 unique_id;
+  U8 code[462];
+  U16 signature2;       //0xAA55
+};
+
+See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC.
+
+Files with names ending in .Z are compressed.  See ::/Kernel/Compress.HC.
+
+To replace ISO9660, make hard-drive partition image of a measured size and copy 
+onto a CD/DVD starting at about sector 20, with EL TORITO booting.  512-byte 
+sectors will be placed on top of 2048-byte CD/DCD sectors, so there will be four 
+blocks per CD/DVD sector.
+
+RedSea file system has no bad block table and no redundant allocation table.
+
+See Block Chain for RedSea allocation bitmap discussion.
+
+See Reliability for RedSea reliability discussion.
+
+ diff --git a/public/Wb/Home/Src/Doc/Reliability.DD.HTML b/public/Wb/Home/Src/Doc/Reliability.DD.HTML new file mode 100755 index 0000000..01c7ed7 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Reliability.DD.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+                               RedSea Reliability
+
+TempleOS is like the 1040EZ tax form compared to the full 1040 form.  Obviously, 
+it is simpler.  If you allow mission creep, pretty soon the 1040EZ looks just 
+like the 1040 and the messed-up 1040EZ has no purpose.
+
+The Commodore 64 had a file system that was simple enough for peers in my 
+generation to enjoy the thrill of knowing exactly what is going on at the 
+hardware level and writing fun projects to access it.
+
+My primary design criteria is simplicity.  If it is simple enough for only 
+100,000 people to learn, lets try to make it simpler so that 1 million can learn 
+it.
+
+Obviously, we don't do bad block tables, or redundant FATs.
+
+We use the simplest possible technique, a contiguous-file-only allocation 
+bitmap, not Block Chains or FAT tables.
+
+You can be a good toy or you can be a good professional tool, but not both.  
+TempleOS's file manager will start too slowly once a few thousand files exist 
+because the file manager makes a list of all files on start-up.
+
+Do not have more than a few thousand files or the file manager will not 
+function.
+
+You are encouraged to keep your entire drive limited to, maybe, 100 Meg of files 
+because you are suppoosed to operate as a kayak instead of a Titanic.  If you do 
+this, backing-up will be only a minute or so and you should do it at least once 
+a day. 
+
+Third party software should be run from ISO files or CD/DVDs directly, without 
+installing to hard drive.
+
+Multimedia graphics and sound is, basically, forbidden.  If you ignore this, all 
+hell will break loose because memory will fragment with large files and the 
+original vision of kayak hard-drive back-ups won't work.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+
+ diff --git a/public/Wb/Home/Src/Doc/Requirements.DD.HTML b/public/Wb/Home/Src/Doc/Requirements.DD.HTML new file mode 100755 index 0000000..2a8300c --- /dev/null +++ b/public/Wb/Home/Src/Doc/Requirements.DD.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+                           Requirements for TempleOS
+
+User Skills Required
+* Knowledge of the C programming language.
+
+Supported Hardware
+* x86_64 PC compatible computer.  (Obviously, you need 64-bit hardware for a 
+64-bit operating system.)
+
+* 640x480 16 color VGA graphics.
+
+* Most keyboards and mice.
+
+* Minimum 512Meg RAM.
+
+* Internal PC Speakers.
+
+* CD/DVD-ROMs (not SCSI) but only RedSea file system.
+
+* ATA and SATA hard drives.
+
+Unsupported Hardware
+* No graphics acceleration.
+
+* No sound cards.
+
+* No networking.
+
+* No USB devices, except keyboard and mouse in legacy mode.  No, you can't use 
+flash memory cards.
+
+* No printers.
+
+ diff --git a/public/Wb/Home/Src/Doc/Resource.DD.HTML b/public/Wb/Home/Src/Doc/Resource.DD.HTML new file mode 100755 index 0000000..e3a9359 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Resource.DD.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+                          Graphic Sprite Resource Help
+
+A sprite is an ordered list of elements such as lines, rectangles, bitmaps and 
+color changes.  In a program's source code, you first make a sprite somewhere 
+outside a function.  Then, you insert a pointer to the sprite as an "*elems" arg 
+when calling Sprite() or Sprite3().  See Sprites.
+
+You can create a sprite macro on your PersonalMenu with a payload of HolyC 
+source code to execute when it ESC's back to the cmd line.  If you check 
+"Pop-Up", it will spawn a new task and run the payload.  A pop-up macro can be 
+placed in any document.
+
+ diff --git a/public/Wb/Home/Src/Doc/ScopingLinkage.DD.HTML b/public/Wb/Home/Src/Doc/ScopingLinkage.DD.HTML new file mode 100755 index 0000000..8102d8a --- /dev/null +++ b/public/Wb/Home/Src/Doc/ScopingLinkage.DD.HTML @@ -0,0 +1,178 @@ + + + + + + + + + + + +
+                              Scoping and Linkage
+
+JIT Compile Mode makes use of the current task's hash sym table and its parent 
+tasks' tables.  It fetches syms from parent tasks' tables if not found locally 
+in the current task's table and it places new syms in the current task's table.  
+Conceptually, syms are at the scope of environment vars in other operating 
+systems.
+
+When a sym is placed into a table, older syms with ident names will be 
+overshadowed if they exist.  Duplicates are not allowed in many cases, 
+especially in asm blks.  Dupicates are allowed, by design in other cases, so 
+that you can repeatedly #include the same file from the cmd line while 
+developing it.  Or, so you can repeatedly declare a function with a standard 
+name, like DrawIt().  This case might occur when the Adam Task is starting-up 
+loading-in many little utilities.
+
+extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym of the same 
+name if it exists in the sym table (just in just-in-time code).  It also can be 
+used to generate a fwd reference.
+
+import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym of the same name 
+imported from the task's sym table at Load() time.  If no sym exists to bind to 
+at Load() time, the code using this sym will be left incomplete until the sym is 
+defined.
+
+
+_extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym, of a differe
+nt name.  It must exists in the sym table.  Basically, this binds C to asm.
+
+_import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym, of a different name 
+imported from the task's sym table at Load() time.  If no sym exists to bind to 
+at Load() time, the code using this sym will be left incomplete until the sym is 
+defined.  Basically, this binds C to asm from elsewhere.
+
+
+Ahead of Time Compilation
+                    GlobalScope/FunctionScope
+                    | CodeHeap/DataHeap/Stack/Register
+                    | | TaskHashEntry:ExportSysSym/Define/Function/Class
+                    | | | UsageScope: Module/AsmLocal/AsmBlk/TaskAndChildren/Function
+                    | | | |UsageScope: Glbl/AsmLocal/Remainder/glblThisBlkAndRemainder
+                    | | | || StaticVarInit/DynamicVarInitAllowed/NoInitAllowed
+                    | | | || | Are dups allowed within the namespace? A dup overshadows the original.
+                    | | | || | DupsAllowed/NoDups/NoDupsButPad/WarningUnlessClosedOut
+
+asm export label::  G C S MG   N
+asm        label:   G C   MG   N
+asm local  @@label: G C   AL   N
+asm IMPORT label;   G C   MR   N
+asm export label::  F C S BG   N
+asm        label:   F C   BG   N
+asm local  @@label: F C   AL   N
+asm IMPORT label;   F C   BR   N
+C   goto   label:   F C   FG   N
+
+           #define  x     MR   D
+           function G C S MR   D
+           var      F R   FR   N
+           var      F S   FR   N
+static     var      F C   FR D N
+           var      G C S MR D D
+           var      G D   MR N D
+           class    G     MR   D
+class      member   G     MR   P
+extern     class    G     MR   D
+extern     function G C   MR   W
+import     function G C   MR   D
+import     var      G C   MR   D
+_extern    function G C   MR   D
+_extern    var      G C   MR   D
+_import    function G C   MR   D
+_import    var      G C   MR   D
+
+
+Just in Time Compilation
+                    GlobalScope/FunctionScope
+                    | CodeHeap/DataHeap/Stack/Register
+                    | | TaskHashEntry:ExportSysSym/Define/Function/Class
+                    | | | UsageScope: Module/AsmLocal/AsmBlk/TaskAndChildren/Function
+                    | | | |UsageScope: Glbl/AsmLocal/Remainder/glblThisBlkAndRemainder
+                    | | | || StaticVarInit/DynamicVarInitAllowed/NoInitAllowed
+                    | | | || | Are dups allowed within the namespace? A dup overshadows the original.
+                    | | | || | DupsAllowed/NoDups/NoDupsButPad/WarningUnlessClosedOut
+
+asm export label::  G C S Tg   N
+asm        label:   G C   BG   N
+asm local  @@label: G C   AL   N
+asm IMPORT label;   G C   TR   N
+asm export label::  F C   BG   N
+asm        label:   F C   BG   N
+asm local  @@label: F C   AL   N
+asm IMPORT label;   F C   BR   N
+C   goto   label:   F C   FG   N
+
+           #define  x   D TR   D
+           function G C F TR   D
+           var      F R   FR   N
+           var      F S   FR   N
+static     var      F C   FR D N
+           var      G C G TR D D
+           var      G D G TR S D
+           class    G   C TR   D
+class      member   G     TR   P
+extern     class    G   C TR   D
+extern     function G C F TR   W
+extern     var      G C G TR   D
+extern     var      G D G TR   D
+_extern    function G C F TR   D
+_extern    var      G C G TR   D
+
+
+* Goto labels must not have the same name as global scope objects.  GoTo's are 
+rare and I don't want to slow the compiler and add code to fix this.  You will 
+get errors if a collision happens, so it's not very dangerous, but the error 
+message is baffling.
+
+* The member names pad and reserved are special because multiple instances with 
+the same name are allowed in a class.
+
+* Use reg or noreg in front of local var names to override automatic reg var 
+allocation.  You can, optionally, specify a reg after the reg keyword.
+ 
+* Local non-reg function vars can be accessed in asm blks with &i[RBP] for 
+example.
+
+* Glbl vars and functions can be accessed in asm with and & as in
+        MOV     RAX,I64 [&glbl_var]
+        CALL    I32 &Fun
+        CALL    I32 &SYS_SYM
+
+* In JIT asm code, &SYS_SYM and &Fun don't need IMPORT.
+
+* All offspring tasks of a task inherit syms.
+
+* The sizeof() and HolyC structure members can be used in asm blks.
+
+* Using &i in HolyC or i.u8[2] on a local var, i, will force it to noreg.
+
+* Using try/catch in a function will force all local vars to noreg.
+
+* An unused gap on the stk is left for reg vars.
+
+* Note: static function vars do not go on the data heap, no matter the setting 
+of the OPTf_GLBLS_ON_DATA_HEAP.  They may in the future.
+
+* OPTf_EXTERNS_TO_IMPORTS will treat _extern as _import and extern as import.  
+This allows a header to be used either as a JIT compiled or AOT compiled header.
+
+ diff --git a/public/Wb/Home/Src/Doc/Snd.DD.HTML b/public/Wb/Home/Src/Doc/Snd.DD.HTML new file mode 100755 index 0000000..9c6f366 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Snd.DD.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+Sound is generated with I8 vals called ona's, which are 88 piano key nums, with 
+0 as a rest.  See Note2Ona() and Ona2Freq().  God does not want death screams, 
+perhaps, because God has PTSD or soldiers have PTSD.  (Imagine wounded on 
+battlefields.)  Ona's will allow elegant wave files for export and will allow 
+the creation of simple hardware over the next centuries.
+
+ diff --git a/public/Wb/Home/Src/Doc/Sprite.DD.HTML b/public/Wb/Home/Src/Doc/Sprite.DD.HTML new file mode 100755 index 0000000..5a41f16 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Sprite.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+A CSprite is an ordered list of these elements, created with <CTRL-r>.  
+Normally, they are packed together in a list and the address of the first is 
+passed to routines.
+
+See ::/Demo/Graphics/SpritePlot.HC, ::/Demo/Graphics/SpritePlot3D.HC, 
+::/Demo/Graphics/SpritePut.HC, ::/Demo/Graphics/SpriteRaw.HC and SpriteMeshEd().
+
+Be aware that copying SP, IB, or IS entries with the clip results in duplicate 
+entries with different nums.  You can manually remove dups by editing with <CTRL
+-t> and setting to the original num.
+
+See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+
+ diff --git a/public/Wb/Home/Src/Doc/SpriteBitMap.DD.HTML b/public/Wb/Home/Src/Doc/SpriteBitMap.DD.HTML new file mode 100755 index 0000000..0094f37 --- /dev/null +++ b/public/Wb/Home/Src/Doc/SpriteBitMap.DD.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+                            Sprite BitMap Menu Help
+
+BitMaps have a background color.  If you delete to the clip, what's left will be 
+background colored.
+
+While drawing, you can usually press 'c' to eye-dropper the color under the 
+mouse.  Press 't' for transparent.
+
+ diff --git a/public/Wb/Home/Src/Doc/SpriteEd.DD.HTML b/public/Wb/Home/Src/Doc/SpriteEd.DD.HTML new file mode 100755 index 0000000..06b8503 --- /dev/null +++ b/public/Wb/Home/Src/Doc/SpriteEd.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+                             Sprite Edit Menu Help
+
+Order of elements matters.  They are executed in the order they appear in the 
+side-bar.  You can sel or unsel elements graphically, or with text in the 
+sidebar.  Then, cut, copy, paste, shift or transform them.
+
+You can set the current insert point element by clicking the element in the 
+side-bar and making it RED.
+
+Insert Shift Suborigin is an element which shifts subsequent elements.  Perhaps, 
+you inserted a sprite's elements from the clip and want to shift it around?  
+This command is also useful if you call SpriteInterpolate() in programs.
+
+ diff --git a/public/Wb/Home/Src/Doc/SpriteEdText.DD.HTML b/public/Wb/Home/Src/Doc/SpriteEdText.DD.HTML new file mode 100755 index 0000000..f60924d --- /dev/null +++ b/public/Wb/Home/Src/Doc/SpriteEdText.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+                            Sprite Edit as Text Help
+
+See the format for CSprites.
+
+ diff --git a/public/Wb/Home/Src/Doc/SpriteMain.DD.HTML b/public/Wb/Home/Src/Doc/SpriteMain.DD.HTML new file mode 100755 index 0000000..2ac1064 --- /dev/null +++ b/public/Wb/Home/Src/Doc/SpriteMain.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+                             Sprite Main Menu Help
+
+Order of elements matters.  They are executed in the order they appear in the 
+side-bar.  You can set the insert point for new elements by click the element in 
+the side-bar and making it RED.
+
+After you create a 3D Mesh, you can edit it by seling it in the side-bar so it 
+is colored RED.  Then, click EDIT-3D-MESH.  A shiftable 3D mesh has a 2D offset 
+to position the origin.  You can convert between shiftable and non-shiftable by 
+editing it with the other command.
+
+You can convert all elements to a BitMap if END is RED in the side-bar and you 
+CONVERT-TO-BITMAP.  Later, you can edit that bitmap by seling it in the side bar 
+so it is colored RED and clicking EDIT-BITMAP.
+
+If you have a 3D icon, you might want to place a background-colored rectangle 
+under the 3D icon, so it hovers above.  Use TRANSFORM-OFF and TRANSFORM-ON.  You 
+will also need to set the Z offset of the icon.  Go to the Edit menu and sel 
+EDIT-AS-TEXT and change the third INT to Z offset.  Good luck.
+
+While inserting vector elements, you can usually press 'c' to eye-dropper the 
+color under the mouse.  Press 't' for transparent.
+
+ diff --git a/public/Wb/Home/Src/Doc/SpriteSideBar.DD.HTML b/public/Wb/Home/Src/Doc/SpriteSideBar.DD.HTML new file mode 100755 index 0000000..8b0278d --- /dev/null +++ b/public/Wb/Home/Src/Doc/SpriteSideBar.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+                              Sprite SideBar Help
+
+You can cut and paste elements in this side-bar to reorder, delete or 
+duplicating them.  Click an element in the side-bar after you make changes to 
+cause the changes to take-effect.
+
+You can click on an element to make it the insert point for new elements.
+
+The RED element is the current insert point for new elements.
+ diff --git a/public/Wb/Home/Src/Doc/StandBy.DD.HTML b/public/Wb/Home/Src/Doc/StandBy.DD.HTML new file mode 100755 index 0000000..24a4b10 --- /dev/null +++ b/public/Wb/Home/Src/Doc/StandBy.DD.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+                           AutoComplete is in StandBy
+
+                            System Keys Quick Guide
+                               (Works Everywhere)
+  <SPACE>   Left-Click  
+  <ENTER>   Right-Click  
+   <F1>     Help
+ <CTRL-m>   Personal Menu
+   <ESC>    Save  & Exit
+<SHIFT-ESC> Abort & Exit
+ <WINDOWS>  Pull-Down Menu
+
+                                    Tongues
+                               (Works Everywhere)
+   <F7>     God Word
+<SHIFT-F7>  God Passage
+   <F6>     God Song
+<SHIFT-F6>  God Doodle
+ diff --git a/public/Wb/Home/Src/Doc/Start.DD.HTML b/public/Wb/Home/Src/Doc/Start.DD.HTML new file mode 100755 index 0000000..5079921 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Start.DD.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+                                 TempleOS V5.03
+
+                         Public Domain Operating System
+
+Help & Index, Quick Start: Cmd line
+
+ diff --git a/public/Wb/Home/Src/Doc/StdOutTask.DD.HTML b/public/Wb/Home/Src/Doc/StdOutTask.DD.HTML new file mode 100755 index 0000000..f48f49e --- /dev/null +++ b/public/Wb/Home/Src/Doc/StdOutTask.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+There is one CDoc for the task's border: Fs->border_doc.  There is a pair for 
+the task's client area: Fs->put_doc and Fs->display_doc.  You can, optionally, 
+do double buffering, otherwise Fs->put_doc is the same as Fs->display_doc.  See 
+::/Demo/Spy.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/StdTempleOSPC.DD.HTML b/public/Wb/Home/Src/Doc/StdTempleOSPC.DD.HTML new file mode 100755 index 0000000..16b5418 --- /dev/null +++ b/public/Wb/Home/Src/Doc/StdTempleOSPC.DD.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+                            The Standard TempleOS PC
+
+All desktop PCs will have 8-channel OCTART super-simple high speed serial ports 
+to replace USB.  They are simpler because the driver is as simple as old school 
+RS232 Serial, they have no USB end-points and they have no USB human interface 
+device reports.  Computer mice will all have exactly two bttns and one wheel.  
+Game controllers will all be the standard deluxe game console controllers that 
+are popular today.  It will have 8 big TX and 8 big RX fifos that allow flow 
+control characters to jump the queue.  It should be locked-down to as few 
+options as possible, like 8-1-N only, although hardware may use a USB frame, not 
+an RS232, so stop bits might not be relevant.  Perhaps, just two baud rates -- 
+high and low speed are needed.  Low speed is good for slow microcontrollers and 
+allows longer cable length.  Keyboard, mouse and game controller can be low 
+speed.
+
+The USB creators banned generic devices, requiring a signed, certified driver 
+for everything!  That's no good.  We allow any device and will communicate, 
+generically, using a serial terminal program like the old school HyperTerminal, 
+XTalk or Telnet.
+
+A mouse packet interface should be similar to this:
+
+     TX:        <ENTER>
+     RX:        X:+3 Y:+0 Wheel:+0 LB:OFF RB:OFF
+     TX:        <ENTER>
+     RX:        X:+0 Y:-1 Wheel:+0 LB:ON  RB:OFF
+
+We aspire to be as simple as a Commodore 64 joystick driver:
+
+     VAL=PEEK(56321)
+     if VAL AND 1 THEN y=y-1
+     if VAL AND 2 THEN y=y+1
+     if VAL AND 4 THEN x=x-1
+     if VAL AND 8 THEN x=x+1
+
+The game controller will be more complicated, but much simpler than USB.  It 
+will use a standard text packet of some kind.
+
+On the other end, you might hook-up a thermostat microcontroller and interface 
+as a generic serial device.  The microcontroller in the thermostat would have 
+something simple, not a crazy overkill ethernet connection.
+
+     U8 b;
+     while (TRUE) {
+       b=ReadU8(2); //Read byte from high speed serial channel 2.
+     //(Has been configured for low baud because thermostat should be slow.)
+       if (b==CMD_UP)
+         temperature++;
+       else if (b==CMD_DOWN)
+         temperature--;
+     }
+
+Super-simple block devices will replace ATA/ATAPI hard drives and 
+CD/DVD/BlueRays.  Today, the industry is in flux with nonvolitile memory just 
+invented.  We want a super-simple block device interface for non-volitile memory 
+and for what is currently USB memory sticks, but only if they can be made 
+without bad blocks.  I don't think we want to deal with bad block memory, so 
+maybe we will not do NV-memory.  The standard TempleOS desktop will require a 
+hard disk.
+
+There will be minimal commands:  READ_BLOCK, WRITE_BLOCK, GET_CAPACITY, 
+GET_MODEL, GET_SERIAL_NUM, and EJECT.
+
+We want a CPU mode with virtual IO port addresses similar to how paging creates 
+virtual memory addresses.  We want a 65536 word look-up table that converts 
+virtual IO port numbers to physical IO port numbers.  There will be a standard 
+IO port configuration, so port numbers can be fixed in the code.  We want the 
+primary hard drive on one set of ports and the primary CD/DVD/Blu-ray on another 
+set of ports.  Choose a contiguous set of IO ports.
+
+Meanwhile, a complicated PCI interface can be designed along-side the TempleOS 
+interface for Windows and Linux.  It would almost be possible to carry-on 
+separate lives, however, the super-simple serial requires getting rid of USB 
+since super-simple serial is a new hardware standard.  People can add USB ports 
+with a PCI device card.
+
+God said He wants single-voice 8-bit signed MIDI-like sample for the sound.  God 
+does not want death screams, perhaps, because God has PTSD or soldiers have 
+PTSD.  (Imagine wounded on battlefields.)
+
+The video will be a linear frame buffer 640x480 16 color with one-byte-per-pixel 
+even though it is only 16 color with is 4-bit.  Perhaps, we have a interrupt to 
+sync with the refresh.
+
+I am tmpted to help amateur hardware device designers by making the hardware 
+interface for the PC simple.  I have fond memories of 1993, when I made a 
+wire-wrapped ISA data acquisition card which plugged into my 486 and had some 
+analog-to-digital and digital-to-analog convertors.  I am not designing a bus.  
+Earlier, I said the super-simple high speed serial port replacement could be 
+USB-like in hardware as long as the software driver interface was simple like 
+old school RS232 serial ports.  Requiring a complicated hardware handshake 
+raises the bar, slightly, for the lowest level hardware designers.  Most people 
+will be connecting a microcontroller or something that already has a serial 
+communication design, but if it's not a problem, maybe we should keep it simple 
+at all stages.  It was nice putting an oscilloscope on my serial port wires.
+
+The original PC had general purpose digital IO through the parallel port.  That 
+was fun.  I have enough battles to fight, so I'll leave being a savior to 
+hobbiest hardware engineers to somebody else.
+
+Digital cameras will be super-simple high speed serial, but TempleOS is forever 
+limited to 16 colors and multimedia is banned because large files being loaded 
+into memory fragments memory, so cameras are somewhat unwelcome.  I have enough 
+problems without making the Brits anxious about autonomous gun turrets and 
+killer robots.  The reason I say cameras will be super-simple serial is because 
+we are replacing USB ports with super-simple serial.  PC's will have only 
+super-simple serial ports unless people buy a USB PCI expansion card.  So, the 
+digital cameras will be super-simple serial.
+
+
+                                  Version 1.0
+
+We will make a spec for a $8,000, perfectly standardized, cryogenically-cooled, 
+monster desktop PC.  It will have 16 cores, integrated 4K graphics, and, 
+hopefully, 6 Ghz continuous operation.  Perhaps, 64 Gig of RAM will be standard? 
+God said to help to poor buy them.  It is pointless to have a high powered 
+machine if other people have wimpy machines and cannot run programs you write.  
+Therefore, everybody in the developed world will buy a Standard TempleOS IBM PC 
+over the next ten years, so that will be a quantity of 400 million, perhaps.  
+God said to pay the US national debt with the revenue.  We will standardize 
+everything, not just the TempleOS related items.  The display will be 4K (and of 
+course 640x480 16 color) and no others.  Everybody gets just one monitor, unless 
+you buy special PCI cards.  Everybody gets two speakers, a headphone, a mic, a 
+webcam and touch scrn.  We make the audio one sample rate and one sample size, 
+but TempleOS still gets just a square wave.  (HD Audio is really screwed-up and 
+requires complicated artificial intelligence, just to route output to speakers.)
+
+The Standard Temple IBM PC will be a full-sized tower.  Perhaps, stain-glass 
+will decorate the case because God is sentimentally attached to stained-glass.  
+We should set the size at exactly 2.5 feet by 1.5 feet by 1.5 feet as in the 
+Exodus,25:10-10 for all time.  If there is extra room, make a storage shelf for 
+DVDs.  We do not want a race-to-the-bottom, shrinking the size.  Instead of 
+making it smaller, make it more powerful.  We want to remove all cost pressure 
+from making things small.  It must have a CD/DVD/Blu-ray drive.  The vision is 
+CD/DVDs used for a library of games, not installed on the hard-drive.  We need a 
+network connection, possibly implemented as a super-simple high speed serial 
+device.  What about standard monitor and speakers?  The C64's success was 
+partially due to wide spread, completely standard, hardware.  I think TempleOS 
+will not do bad block devices, so we need a hard drive, not just NV-memory or 
+SSD.
+
+TempleOS will have the priority over Windows or Linux on hardware decisions.  We 
+could make it heterogenious multicore.  I think we want 16 non-hyperthreaded 
+cores.  Core#0 is the only full-featured core needed.  The other cores will have 
+long mode, but not some of these: real mode, protected mode, ring-3, paging, 
+interrupts, in/out port instructions, SSE instructions,  MMX instructions.
+
+God said Intel should do a simulation of heat produced by gates and try 
+spreading-out the heat producing gate circuits on the chip.
+
+God said Linux's Wine should replace Windows.  We will install a standard 
+software set-up on all Standard Temple IBM PC's.
+
+
+                                     Usage
+
+TempleOS is primarily for user developers, like the Commodore 64 was.  I created 
+a total of 50 Meg of content over ten years, so you shouldn't need much room, 
+either.  The installed hard drive space should stay small because the resolution 
+is low, multimedia is banned, 3rd party libraries are banned, and applications 
+can be distributed with ISO files or DVDs.
+
+The ROM will have a command that copies the ROM onto the hard drive, creating 
+identical C and D partitions, so you can have fun modifying TempleOS.  You will 
+have confidence you can fix it easily if you break it.  It should be able to run 
+everything from just the ROM, too.  You will need to specify a /Home directory 
+that is not in the ROM, but on the hard drive. 
+
+The standard set-up will be a C primary drive and a D back-up drive.  Keep the 
+size on each hard drive under 512 Meg and periodically copy all of C to D, so 
+they stay mirrored.  The file manager and other programs read the entire 
+directory structures, so too many files causes problems (unbearably slow).  
+Third party software should be distributed as ISO files or DVDs, like 
+TextAdventure.ISO.  No 3rd party libraries are permitted because they circumvent 
+the intent of the 100,000 line of code limit which is keeping it cognatively 
+small enough to see the light at the end of the tunnel and easily master 
+everything.  Therefore, 3rd party ISO files must bring all required software 
+components with them, except what is found in the TempleOS ROM.
+
+Having all your 3rd party software on separate DVDs or ISO files and TempleOS 
+running from a ROM, keeps it delightfully simple so you have complete 
+understanding of what is going on.  You will have complete confidence and it 
+will be a joy to use.  3rd party applications can store saved data files into 
+your /Home hard drive directory.
+
+The Temple PC will stay unchanged for seven years at a time.  The Bible speaks 
+of a seven year release in Deuteronomy,15:1.  The Commodore stayed unchanged for 
+many years and people became intimately familiar with every aspect.
+
+
+
+I thought 2.5' x 1.5' x 1.5' was ridiculously big, but it looks like it is 
+reasonable for super-cooled refrigeration systems!
+
+
+                                  Version 2.0
+
+
+ +The Standard Temple IBM PC V2.0 will be released seven years after V1.0. Each +unit will have a full, uncut, silicon wafer. V2.0 will be sold, unchanged, for +seven more years, like a Commodore 64. + +* "Commodore 64" is a trademark owned by Polabe Holding NV. +* "Linux" is a trademark owned by Linus Torvalds. +* "Windows" is a trademark owned by MicroSoft Corp. +
+ diff --git a/public/Wb/Home/Src/Doc/Strategy.DD.HTML b/public/Wb/Home/Src/Doc/Strategy.DD.HTML new file mode 100755 index 0000000..d73c56f --- /dev/null +++ b/public/Wb/Home/Src/Doc/Strategy.DD.HTML @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+                        Decisions Making TempleOS Simple
+
+Everybody is obsessed, Jedi mind-tricked, by the notion that when you scale-up, 
+it doesn't get bad, it gets worse.  They automatically think things are going to 
+get bigger.  Guess what happens when you scale down?  It doesn't get good, it 
+gets better!
+
+I limited it to 100,000 lines of code, forever!  I never need a linker or make 
+utility and I can use small labels.
+
+People mock Bill Gates for, "640K should be enough."  I say, "2Gig for code 
+should be enough."  The same people who mock Bill Gates are probably just like 
+the black woman who sued for a trillion dollars.
+
+My Dad worked on converting the Titan missile to the Gemini Mission rocket.  It 
+had to be "man-rated".  You can bet that everything got an order of magnitude 
+more complexity and documentation.  My vision is a souped-up C64, not a 1970's 
+mainframe; a kayak, not a Titanic.
+
+Linux is a semi-tractor -- you need professional drivers for 20 gears.  Linux 
+has file permissions.  Common people are hurt by file permissions.
+
+Windows is a car.
+
+TempleOS is a motorcycle -- if you lean-over too far, a motorcycle will crash.  
+Don't do that!  There are no side air bags on a motorcycle.  DOS and C64 had no 
+memory protections and ran in ring-0, with no security.  This saves an order of 
+magnitude complexity.
+
+Linux and Windows are general purpose operating systems.  They attempt to do any 
+task you want.  TempleOS cherry-picks tasks and is designed to do the same 
+things a C64 did.  This saves and order of magnitude complexity.  For example, 
+the RedSea file system allocates just contiguous files -- you load and save 
+whole files at once.  A benefit is this allows compression.  Also, TempleOS does 
+not do networking or multimedia.  In theory, memory will fragment with lots of 
+big files.  The system would fall to pieces with multimedia, but God said 
+640x480 16 color is a permanent covenant like circumcision.
+
+A three bttn mouse is like a leg you cannot put weight on.  TempleOS just does 
+hardware everybody has, with no divergent code bases for each machine's custom 
+hardware.  There is one graphics driver instead of 50 for different GPUs.  This 
+saves an order of magnitude complexity and makes for a delightful API, so 
+developer's code is not like a frayed rope end.
+
+
+
+* Everything runs in kernel, ring 0, mode.
+
+* One memory map for all tasks on all cores with virtual addresses set equ to 
+physical, just as though paging is not used.
+
+* One platform -- x86_64 PC's, no 32-bit support.
+
+* No security or cryptography.
+
+* No networking.
+
+* Least (greatest) common denominator hardware support.  Mostly, one driver for 
+each device class.  I can't be in the business of different drivers.  
+Compatibility is the greatest challenge for PC operating systems.  Disk code 
+does not use interrupts, avoiding compatibility risks.  PS/2 keyboard/mouse is 
+used instead of USB, also more compatible.
+
+* 640x480 16 colors.  Updates whole scrn at 30 fps, optimized for full scrn 
+games where InvalidRectangles are counter-productive.
+
+* One font, 8x8.  Text and graphic layers done in software with text normally on 
+an 8x8 grid.  It can run in Text mode if graphic initialization fails.
+
+* Compiler extends all values to 64-bit when fetched and does only 64-bit 
+computations intermediately.  Assembler has minimal 16-bit support, good enough 
+for compiling boot loaders.
+
+* No object files.  Use JIT.
+
+* Whole files are processed almost exclusively, allowing compression.
+
+* One language and compiler for command-line, scripts, songs, automations and 
+code.
+
+* One editor/word processor/browser for the command-line window, source code, 
+documentation browser, dialog forms.
+
+* No child windows.  One window per task.  Bttns are widgets, not child windows. 
+ There are child tasks, however.
+
+* No distinction between thread, process or task.
+
+* The Scheduler is for home systems.  It is not preemptiove.  Disk requests are 
+not broken-up, so sharing is bad.  It's wonderfully simple.
+
+* MultiCore is done master/slave, instead of SMP.  Core0 applications explicitly 
+assigns jobs.  Locks are present allowing multicore file, heap, and hardware 
+access, though.
+
+* Sound has single-voice 8-bit signed MIDI-like samples.
+
+* All tasks have a heap and a sym table.  Scope is that of environment vars in 
+other operating systems.  As text is typed at the command line or you run 
+programs by #includeing them, the syms go in the table.  If a sym is not found, 
+the parent task's table is checked.  The father of all tasks has the API syms 
+you'll need waiting in it's table.  No need to #include headers.
+
+* No need for namespaces -- scoping occurs automatically based on task symbol 
+table hierarchy with the Adam Task's symbol system-wide global.
+
+* Sometimes, I cut corners in the interest of keeping the code beautiful.
+
+ diff --git a/public/Wb/Home/Src/Doc/Streams.DD.HTML b/public/Wb/Home/Src/Doc/Streams.DD.HTML new file mode 100755 index 0000000..15310a0 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Streams.DD.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+There are no streams in the traditional sense.  The cmd line output gets sent to 
+the cursor location of a document being edited and by using cursor keys, text 
+can be injected all over the document.  Sprites can be injected and are not 
+serialized!  Furthermore, the input can come from triggering macro widgets.  See 
+Doc Overview and Doc Routines.
+
+If you had a remote term and sent key Scan Codes, the user would press <CTRL-m> 
+to access his Personal Menu to trigger his macros.  However, the local 
+~/PersonalMenu.DD might differ from the remote, causing loss of sync between 
+local and remote sessions.  Also, the window size of local and remote might 
+differ, so word-wrapped text would be different.  Injecting output text with 
+different windows sizes would cause remote and local documents to not be in 
+sync.
+
+See Char Overview and Char Routines.
+
+You can send characters into StdIn.  See In(), XTalk() and InFile.
+
+ diff --git a/public/Wb/Home/Src/Doc/TOSZ.DD.HTML b/public/Wb/Home/Src/Doc/TOSZ.DD.HTML new file mode 100755 index 0000000..03c6dcb --- /dev/null +++ b/public/Wb/Home/Src/Doc/TOSZ.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+                               Linux TOSZ Utility
+
+
+TOSZ [-ascii] filename
+
+Will uncompress a single file from within Linux.  The -ascii flag will convert 
+the irregular TempleOS ASCII 5 and ASCII 31 characters to spaces.  (ASCII 5 is 
+used to mark the cursor pos and ASCII 31 is used for shifted space characters 
+and will cause problems unless you convert them.)
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Src/Doc/TextBase.DD.HTML b/public/Wb/Home/Src/Doc/TextBase.DD.HTML new file mode 100755 index 0000000..818c7d7 --- /dev/null +++ b/public/Wb/Home/Src/Doc/TextBase.DD.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+gr.text_base must be updated 30fps in your Fs->draw_it() callback.  You probably 
+want GrPrint() or just Print().  The DolDoc code takes care of plotting text to 
+gr.text_base.
+
+Bits 0-7        8-Bit ASCII Scrn Code
+Bits 8-11       Foreground color
+Bits 12-15      Background color
+Bits 16-20      Signed X pos shift val
+Bits 21-25      Signed Y pos shift val
+Bit  28         Blink
+Bit  29         Inverted (Swap foreground and background)
+Bit  30         Sel (XOR colors with FF)
+Bit  31         Underline
+
+GrUpdateTaskWin() calls DocUpdateTaskDocs() which calls DocRecalc() where the 
+document text is plotted into gr.text_base.  Then, GrUpdateTextBG() and 
+GrUpdateTextFG() render the gr.text_base onto gr.dc2, a raw graphic bitmap.
+
+See ::/Demo/Games/Maze.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/TimeCycles.DD.HTML b/public/Wb/Home/Src/Doc/TimeCycles.DD.HTML new file mode 100755 index 0000000..49fcea7 --- /dev/null +++ b/public/Wb/Home/Src/Doc/TimeCycles.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Intel/AMD have an inst that returns the num of CPU cycles since boot.  This is 
+not a steady, calibrated real time value.  TempleOS measures it and you can 
+convert with cnts.time_stamp_freq, a value continuously calibrated from other 
+cnts.
+ diff --git a/public/Wb/Home/Src/Doc/TimeDate.DD.HTML b/public/Wb/Home/Src/Doc/TimeDate.DD.HTML new file mode 100755 index 0000000..ef1860e --- /dev/null +++ b/public/Wb/Home/Src/Doc/TimeDate.DD.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+TempleOS uses a 64-bit value, CDate, for date/time.  The upper 32-bits are the 
+days since Christ.  The lower 32-bits store time of day divided by 4 billion 
+which works out to 49710ths of a second.  You can subtract two CDate's to get a 
+time span.
+
+Use CDATE_FREQ to convert.
+
+ diff --git a/public/Wb/Home/Src/Doc/TimeHPET.DD.HTML b/public/Wb/Home/Src/Doc/TimeHPET.DD.HTML new file mode 100755 index 0000000..6a20ce3 --- /dev/null +++ b/public/Wb/Home/Src/Doc/TimeHPET.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+The HPET, high precision event timer, is read with HPET() and has a frequency of 
+cnts.HPET_freq.  A typical freq value is 14.3 Mhz  It might not be available on 
+all systems.
+
+ diff --git a/public/Wb/Home/Src/Doc/TimeJiffy.DD.HTML b/public/Wb/Home/Src/Doc/TimeJiffy.DD.HTML new file mode 100755 index 0000000..02053c9 --- /dev/null +++ b/public/Wb/Home/Src/Doc/TimeJiffy.DD.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+One jiffy is one time slice.  cnts.jiffies returns time slices since boot.
+
+SysTimerRead reads the timer ticks since boot.  It's not as fast as GetTSC.
+
+Use JIFFY_FREQ to convert cnts.jiffies.
+
+Use SYS_TIMER_FREQ to convert SysTimerRead.
+
+ diff --git a/public/Wb/Home/Src/Doc/Tips.DD.HTML b/public/Wb/Home/Src/Doc/Tips.DD.HTML new file mode 100755 index 0000000..2537b90 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Tips.DD.HTML @@ -0,0 +1,280 @@ + + + + + + + + + + + +
+                                      Tips
+
+* Turn-off or reboot (<CTRL-ALT-DEL>) at any time, except during disk writes.  
+Writes are not cached. 
+
+* Use Seed() and the cmd line to switch Rand() to non-timer mode and replay 
+games you like.
+
+* 64-bit values are most efficient for the compiler.
+
+* See Key Map for a list of defined keys.  Define your own keys in MyPutKey().  
+See Keyboard Devices.
+
+* <ALT-m> maximizes a window.  <ALT-SHIFT-w> closes AutoComplete.  <ALT-w> 
+brings back AutoComplete.  <ALT-v> vertically tiles windows.  <ALT-h> 
+horizontally tiles windows.  The ALT keys are defined in ~/HomeKeyPlugIns.HC.  
+You can customize them.
+
+* If you make changes to TempleOS files in your /Home directory, generally you 
+reboot to make them take effect.  (You don't compile anything.)  You should have 
+two TempleOS partitions on your hard drive because a syntax error in a start-up 
+file will make the partition unbootable.  Boot to the second partition or boot 
+to a standard TempleOS CD/DVD and use Mount() to mount your hard drive.
+
+* I copy my files to a mirrored ident partition, periodically with CopyTree() 
+commands in scripts.  I do merge commands with a menu entry like this:
+Merge(\"C:/*\",\"D:/*\",\"+r+d\"); to check my changes.
+
+* <CTRL-m> at the cmd line to access your PersonalMenu.  Place macros there with 
+<CTRL-l>, or icon-like sprites with <CTRL-r>.  Use the Pop-Up option on macros 
+to Spawn() a task to run a file.  It dies when it is finished.  This returns mem 
+to the system.  Be sure to press <CTRL-s> to save your macro/menu area after 
+making changes.
+
+* You can use ans in cmd line expressions.  It holds the res the last cmd line 
+operation.  You can use the cmd prompt as a calculator by just entering 
+expressions like 1+2*3;.  F64 ress can be accessed with ansf.
+
+* Use the PullDown menu at the top of the scrn to learn commands, or for finding 
+the keyboard controls to games.
+
+* You can adjust the mouse movement rate by setting global vars in your start-up 
+file.  See mouse scale.
+
+* You can set your local time zone by setting the local_time_offset global var 
+in a start-up file.  It's units are CDATE_FREQ.  See local time.
+
+* <CTRL-SHIFT-L> in the editor to reindent a HolyC function or renumber an asm 
+routine's local labels.
+
+* You can use filter_lines in the editor text search form (<CTRL-f>) to 
+temporarily display just lines near each match.  A value of filter lines set to 
+5 will display lines within 5 lines of matches.  Then, you can do another find 
+to a different string and achieve a AND search.  When finished, press <ESC>.
+ 
+* You can recompile and reinstall the kernel with BootHDIns().  You'll probably 
+want to make a function for recompiling that uses the In() function to answer 
+the cfg questions.  See my technique Cfg Strs, Update Funs.
+
+* Scale2Mem(min,max,limit=2*1024*1024*1024) can be used for cfg questions when 
+recompiling.  The BootHDIns() cfg prompts accept expressions, not just numbers.  
+The dft disk cache is Scale2Mem(0x80000,0x8000000).
+
+* You can permanently disable AutoComplete commenting-out ACInit() in 
+~/HomeSys.HC.
+
+* Boolean expressions not in if stmts don't have short circuit logic and are 
+compiled inefficiently.
+
+* You can use progress1-progress4 in your programs for whatever you like.  
+They're just global vars that are shown on the wallpaper.  The original intent 
+was to indicate how far along operations were.  There's no coordination, so 
+different apps might interfere.  I use them most for debugging--just values 
+easily viewed.  See ::/Demo/Progress.HC.
+
+* Use DocMax() to adjust the size of the cmd line buf.  It counts CDoc entries, 
+not lines.
+
+* Many data structures have a user_data member.  Those are available for you to 
+store a data item, for convenience.  CTask, CDocEntry and CDirEntry have them.  
+You shouldn't encounter conflicts with TempleOS using them.
+
+* If, for some strange reason, you wanted to reduce mem usage, make a smaller 
+disk cache when you recompile the kernel; disabling AutoComplete; Specify 
+smaller stk sizes when doing Spawn(), chang MEM_DFT_STK, and using DocMax() to 
+reduce the cmd line buffer size.
+
+* Filenames ending in ".Z" will be automatically compressed and uncompressed 
+when read or written.  The compression method is not supported by other 
+operating systems.  You can store files uncompressed by Move()ing them to a 
+filename not ending in ".Z".  See ::/Doc/TOSZ.DD if you want to uncompress while 
+in Linux.
+
+* Merge() can be used to see what's changed.  The +d flag will show differences 
+of files which have changed and allow you to merge code.  (The +r flag will 
+recurse.)
+
+* There is a utility LinkChk() which will check for broken links in 
+documentation.
+
+* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in 
+code.
+
+* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find unnecessary local var type 
+stmts.
+
+* Option(OPTf_ECHO,ON) can be placed in StartOS.HC to echo start-up scripts.
+
+* Use Plain() to edit a plain text file.  You'll need this if your file has $'s. 
+ Use the ToDolDoc() utility to convert plain text to DolDoc's by doubling $'s.
+
+* Use Silent() to disable scrn text output.
+
+* Grab-scroll any window at any time with {CTRL-LEFT-MOUSE-DRAG}.  Null 
+grab-scrolling with {CTRL-RIGHT-MOUSE}.
+
+* Use <CTRL-ALT-z> to zoom-in and <CTRL-ALT-SHIFT-Z> to zoom-out.  You can 
+scroll by moving to the edge of the window.  Set gr.continuous_scroll to TRUE if 
+you want. 
+
+* Use <CTRL-ALT-g> and <CTRL-ALT-SHIFT-G> to display a grid on the scrn.
+
+* Use <CTRL-ALT-a> to enter an extended ASCII char.
+
+* Use <CTRL-ALT-f> to toggle between Std Font and Cyrillic Font.
+
+* Use <CTRL-ALT-s> will capture the scrn as a sprite on the clip.  You can save 
+the cmd line doc as text with <CTRL-a>.
+
+* You can save a sprite as a .GR file in <CTRL-r> on the Sprite BitMap Menu.
+
+* You can eye-dropper colors in the <CTRL-r> sprite editor by pressing 'c'.  
+Press 't' for transparent.
+
+* There are handy functions--F(),R(),FD() and RD() which are defined in 
+~/HomeWrappers.HC.  You are encouraged to change them and add more.  They will 
+perform find-and-replace operations accross multiple files.  The +l flag is 
+particularly useful since it limits to whole labels.  The +lb and +la flags 
+limit to whole labels just before or after.  You are encouraged to add or modify 
+handy wrapper functions to make cmd line operations easier.
+
+* When using Find() while modifying code, work from the bottom-up so that line 
+numbers are correct.  If you work top-down, then inserting or deleting lines 
+causes the lower file links will be incorrect.
+
+* You can save files after making changes, anytime you are within the editor, 
+like when viewing help/macro files.  <CTRL-a> saves as, <CTRL-s> saves with the 
+same name in the scrolling title bar.  Hitting <ESC> will exit and save.  (<SHIF
+T-ESC> will abort).  You can save the cmd line window to a file, too, since 
+you're actually in the editor when you're at the cmd line.
+
+* When using <CTRL-l> to insert links in documents, you can usually leave the Ta
+g Text blank and it will be filled-in automatically based on other entries.
+
+* There is a feature of the precompiler that allows code to be executed in the 
+middle of compilation and data inserted into the compilation stream.  Click here 
+for an example: #exe {.
+
+* If you output to the cmd line and wish to allow users to scroll around and 
+view data, you can use View().
+
+* Use View() in Pop-up macros to linger until the user presses <ESC> or <SHIFT-E
+SC>.
+
+* You can access the word under the cursor at ac.cur_word.
+
+* You can reactivate AutoComplete after closing it by pressing <CTRL-Fun Key> or 
+<ALT-w> if you have it defined.
+
+* <CTRL-SHIFT-T> to toggle to/from plain text just the CDoc cmd under the 
+cursor.  See ::/Demo/DolDoc/TextDemo.HC.
+ 
+* If you toggle to plain text when you are working with graphics in a document, 
+you can add duplicate entries for sprites by entering a $SP...$ cmd with the 
+same num.
+
+* If you toggle to plain text when working with graphics, you can add a str to 
+the $SP...$ entry to keep track of it.  Try $SP,"<2>",BI=2$ where '2' is the 
+sprite num.
+
+* I use spaces-to-tab operations on all my src files to keep them small.  You 
+have to be careful, though, because spaces in strings will be converted.  I use 
+<SHIFT-SPACE> ' ' in such cases.  See S2T() for spaces-to-tabs.
+
+* You can edit an existing sprite by putting the cursor on it and pressing <CTRL
+-r>.
+
+* When editing a sprite, you can cut and paste the elements in the sidebar text 
+list window.
+
+* I recommend keeping CSprite in vect format until you are done creating them, 
+so you can edit the ctrl points.  Then, convert them to bitmaps, so the flood 
+fills work well.  If you are doing interpolation, however, they must be vect.
+
+* GrFloodFill() is slow.  GrRect() is fast.
+
+* You can customize the wallpaper.  See ::/Demo/Graphics/WallPaperFish.HC.
+
+* Your RAM disks will not be reformated when you reboot if the memory location 
+has not changed and it finds the disk intacted.
+
+* try{} catch{} in a function will cause all vars to be non-reg.
+
+* Using a sub-int array, i.u8[3], for example, will force a local var to 
+non-reg.
+
+* You can delete the ~/Registry.HC.Z file.  The policy is that deleting it will 
+restore defaults.  It is a text doc, if you want to edit it.  Be careful of tree 
+indentations.
+
+* Study ::/Adam/Opt/Utils/MemRep.HC and WallPaper() to learn how the system 
+resources are put together.
+
+* The editor's sel-text mechanism allows for disjoint portions of sel text.  
+This is a feature, not a bug -- you can cut-and-paste disjoint text.
+
+* cnts.time_stamp_freq is continuously calibrated.  Be careful because 
+expressions might decrease.  Take a snap-shot, like this: timeout=GetTSC+
+cnts.time_stamp_freq x seconds; and compare against GetTSC().  I recommend just 
+using tS or cnts.jiffies.
+
+* Use HeapLog(), HeapLogAddrRep() and HeapLogSizeRep() to find leaks.  Don't be 
+confused by CDoc allocations.  Those are generated when text is written to the 
+cmd line buffer.
+
+* For advanced heap debugging, play with _CFG_HEAP_DBG.  You're on your own.
+
+* You can use Type() to display .GR files.
+
+* Use Man() to jump to short sym name src code.
+
+* Use Fix() to edit and fix the last compiler err.
+
+* You can use <CTRL-SHIFT-L> to do a check for compile errors.
+
+* You can use DocOpt() to optimize links. (Mostly just removes .Z)
+
+* ZipRep() can highlight src files with lots of redundancy.
+
+* With start/end, common trailing code is fast.  Common leading code is slow.
+
+* The first line of the Psalmody HolyC song files is a comment with a category 
+recognized by JukeBox().  The categories are "no nothing", "has words", "has 
+graphics", or "special".  The third character in the song comment is a digit 
+rating number, shown in JukeBox().  You can set the song rating in JukeBox() by 
+pressing 0-9.  You can press <DEL> to delete songs.
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Src/Doc/Transform.DD.HTML b/public/Wb/Home/Src/Doc/Transform.DD.HTML new file mode 100755 index 0000000..a030491 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Transform.DD.HTML @@ -0,0 +1,56 @@ + + + + + + + + + + + +
+CDC's have a 4x4 matrix for rotating, scaling, skewing and shifting in 3 
+dimensions.  To make the graphics routines use the transform, you must set the 
+DCF_TRANSFORMATION flag.
+
+The matrix consists of ints that have been scaled 32 bits (GR_SCALE).  See 
+::/Demo/Lectures/FixedPoint.HC to learn why.
+
+See Mat4x4IdentEqu(), Mat4x4IdentNew(), Mat4x4Equ() and Mat4x4New().  See 
+Mat4x4RotX(), Mat4x4RotY(), Mat4x4RotZ() and Mat4x4Scale() to rotate about axes 
+and scale.  Combine them with Mat4x4MulMat4x4Equ()/Mat4x4MulMat4x4New() and 
+assign them to the CDC.dc with DCMat4x4Set().  See ::/Demo/Graphics/Box.HC.
+
+You can rotate single points using Mat4x4MulXYZ().
+
+The 4th dimension allows a neat trick where you can place pos shifts 
+(translations), into the matrix and Mat4x4MulMat4x4Equ/Mat4x4MulMat4x4New them 
+to combine rotation/shift operations.  Normally, you can't combine pos shift 
+operations.  See Mat4x4TranslationEqu() and ::/Demo/Graphics/Transform.HC.
+
+Finally, CDC's have an x, y and z which is an additional shift (translation).
+
+The transformation is implemented as a callback on the CDC's transform() member. 
+ The default transform() callback is DCTransform().  See 
+::/Demo/Games/Talons.HC or ::/Demo/Games/CastleFrankenstein.HC to see how to 
+change the transform() callback for foreshortening.
+
+ diff --git a/public/Wb/Home/Src/Doc/Welcome.DD.HTML b/public/Wb/Home/Src/Doc/Welcome.DD.HTML new file mode 100755 index 0000000..404fb6d --- /dev/null +++ b/public/Wb/Home/Src/Doc/Welcome.DD.HTML @@ -0,0 +1,278 @@ + + + + + + + + + + + +
+                              Welcome to TempleOS
+
+TempleOS is a x86_64, multi-cored, non-preemptive multi-tasking, ring-0-only, 
+single-address_mapped (identity-mapped), operating system for recreational 
+programming.  Paging is almost not used.
+
+The people whom can most benefit are:
+  * Professionals doing hobby projects
+  * Teenagers doing projects
+  * Non-professional, older-persons projects
+
+Simplicity is a goal to keep the line count down, so it's easy to tinker with.  
+As it turns-out, simplicity makes it faster in some ways, too.  It never 
+switches privilege levels, never changes address maps, tends to load whole 
+contiguous files and other, similar things which boost speed.  It's only 80,849 
+lines of code including the kernel, the 64-bit compiler, the graphics library 
+and all the tools.  More importantly, it's designed to keep the user's line 
+count down -- you can do a Hello World application in one line of code and can 
+put graphics on the scrn with a three line program!
+
+It's a kayak, not a Titanic -- it will crash if you do something wrong.  You 
+quickly reboot, however.  DOS and the 8-bit home computers of the 80's worked 
+fine without memory protection and most computers in the world -- the embedded 
+ones -- operate without protection.  The resulting simplicity of no protections 
+is why TempleOS has value.  In facts, that's the point of TempleOS.  See the 
+TempleOS Charter.
+
+Conventional thinking is "failure is not an option" for general purpose 
+operating systems.  Since this OS is used in addition to Windows or Linux, 
+however, failure is an option -- just use Windows or Linux if you can't do 
+something.  I cherry-pick what it will and won't do, to make it maximally 
+beautiful.  The following applications more or less form a basis that spans the 
+range of use that TempleOS is intended for:
+
+/Demo/Games/BattleLines.HC
+/Demo/Games/BigGuns.HC
+/Demo/Games/BlackDiamond.HC
+/Demo/Games/BomberGolf.HC
+/Demo/Games/CastleFrankenstein.HC
+/Demo/Games/CharDemo.HC
+/Demo/Games/CircleTrace.HC
+/Demo/Games/Collision.HC
+/Demo/Games/Digits.HC
+/Demo/Games/DunGen.HC
+/Demo/Games/Talons.HC
+/Demo/Games/ElephantWalk.HC
+/Demo/Games/FlapBat.HC
+/Demo/Games/FlatTops.HC
+/Demo/Games/Halogen.HC
+/Demo/Games/MassSpring.HC
+/Demo/Games/Maze.HC
+/Demo/Games/RainDrops.HC
+/Demo/Games/RawHide.HC
+/Demo/Games/Rocket.HC
+/Demo/Games/RocketScience.HC
+/Demo/Games/Squirt.HC
+/Demo/Games/TheDead.HC
+/Demo/Games/TicTacToe.HC
+/Demo/Games/TreeCheckers.HC
+/Demo/Games/Varoom.HC
+/Demo/Games/Wenceslas.HC
+/Demo/Games/Whap.HC
+/Demo/Games/Zing.HC
+/Demo/Games/ZoneOut.HC
+/Apps/Psalmody/Examples/childish.HC
+/Apps/Psalmody/Examples/night.HC
+/Apps/Psalmody/Examples/prosper.HC
+
+Two things to know about TempleOS are that tasks have MAlloc/Free heap memory, 
+not applications, and tasks have compiler symbol tables that persist at a scope 
+like environment variables in other operating systems, and the symbols can 
+include functions.
+
+For other operating systems, I hated learning one language for command line 
+scripts and another for programming.  With TempleOS, the command line feeds 
+right into the HolyC compiler, line by line, and it places code into memory it 
+MAlloc()s.  The compiler is paused at the command line, waiting for input.  
+Naturally, you #include a program to load it into memory and, usually, start it.
+
+During the boot process, many files get compiled before you have access to the 
+command line.  (Don't worry, booting takes only two seconds.)  All the header 
+declarations for the operating system are compiled and are available for use in 
+your programs without needing to #include them.  Everything is truly compiled to 
+native x86_64 machine code, nothing is interpreted and there is no byte code.
+
+Statements at the global scope -- outside the scope of functions -- execute 
+immediately.  There is no main() function.  Instead, you give meaningful names 
+to what would be main() functions and you invoke them by calling them with a 
+statement in the global scope, usually at the bottom of your file.
+
+I started with C syntax, but didn't like the command line for a directory 
+listing looking like this:
+
+>Dir("*.*",FALSE);
+
+So, I added default args from C++ and it looked like this:
+
+>Dir();
+
+I didn't like that, so I made parentheses optional on calls with no args and it, 
+now, looks like this:
+
+>Dir;
+
+The syntax change created an ambiguity when specifying function addresses, like 
+for calling QSort().  To resolve it, I  made a '&' required in front of function 
+names when specifying an address of a function, which is better anyway.
+
+Once I was no longer using standard C/C++ syntax, I decided to change everything 
+I didn't like and call it HolyC.  Here are the new operator precedence rules.  
+It's Biblical!  See Luke,5:37.
+
+There are no object files in TempleOS and, normally, you don't make executable 
+files either, but you can.  That's known as Ahead-of-Time compilation.  Instead, 
+you Just in Time compile.
+
+Tasks have no priority and are never removed from the queue.  Instead, they 
+often poll whatever they are waiting on and swap-out.  (Swapping tasks takes 
+half a microsecond and does not involve disk activity or memory maps.)  See 
+Scheduler.  Polling keeps it simple.  It might be a problem if you had lots of 
+tasks busy, which rarely happens on a home computer.  The order of the tasks in 
+the queue determines front-to-back window order.
+
+The FAT32 filesystem is supported to makes exchanging files with a dual booted 
+other operating system easy and there is the simple, 64-bit TempleOS RedSea 
+filesystem.  The RedSea has allocation bitmap for clus and all files are stored 
+contiguously.  You can't grow files.
+
+TempleOS is geared toward reading and writing whole files.  Since whole files 
+are processed, compression is possible.  Filenames ending in ".Z" are 
+automatically compressed or uncompressed when stored and fetched.  TempleOS does 
+support direct block random access into files, however -- FBlkRead() and 
+FBlkWrite().
+
+If a file is not found, ".Z" is added or removed and a search is done, again.  
+There is no PATH, but parent directories are searched when a file is not found.  
+This feature is especially useful for default account files.
+
+The graphic resolution is poor, 640x480 16 color, but God said it was a covenant 
+like circumcision.  Also, that's all I feel comfortable with without GPU 
+acceleration supported.  A 1600x1200x24 bit scrn takes 37 times more memory, 
+implying 37 times the CPU power.  Also, a fixed size keeps it simple with 
+everybody machine having the same appearance.  Look on the bright-side -- you 
+won't spend as much time twiddling pixels for your game art and you'll have tons 
+of CPU power available, especially with multicore systems.
+
+TempleOS is for hobbyist programmers on single user (at a time) home computers, 
+not mainframes or servers.  The focus task is all-important so symmetrical 
+multiprocessing is almost pointless.  Why does it matter running two apps at the 
+same time twice as fast when you really want to run one faster?  You could say 
+TempleOS does master/slave multiprocessing.  The anticipated use for multicore 
+is primarily putting graphics on the scrn.  Hardware graphics acceleration is 
+not used, so this is possible.  See TempleOS MultiCore.
+
+There is no distinction between the terms task, process or thread.  All have a 
+task record, CTask, pointed to by the FS segment reg and are accessed with Fs-> 
+while Gs-> points to a CCPU for the current CPU core.  Each task can have just 
+one window, but a task can have children with windows.  (The segment regs are 
+just used as extra regs -- there is nothing segmented about TempleOS' memory.)  
+It is approximately the case that TempleOS is multi-threading, 
+single-processing.
+
+In TempleOS, Adam Task refers to the father of all tasks.  He's never supposed 
+to die.  Since tasks inherit the symbols of parents, system-wide stuff is 
+associated with Adam.  His heap is like kernel memory in other operating 
+systems.  Since Adam is immortal, it's safe to alloc objects, not tied to any 
+mortal task, from Adam's heap.  He stays in a server mode, taking requests, so 
+you can ask him to #include something, placing that code system-wide.  A funny 
+story is that originally I called it the root task and even had a /Root 
+directory :-)  Adam executes ::/StartOS.HC at boot time.
+
+For easy back-ups, place everything you author in your /Home directory and 
+subdirectories.  Then, use CopyTree().  That should make upgrading easy, too.  
+Customizable start-up scripts go in your /Home directory.  The default start-up 
+scripts are in the root directory.  Copy the start-up files you wish to 
+customize into /Home and modify them.  See Home Files.  You can make your own 
+distro that includes everything and is a bootable live CD with 
+::/Misc/DoDistro.HC.
+
+Typically, your usage pattern through the day will be repeatedly left or right 
+clicking on filenames in a cmd line Dir() listing.  You left-click files to edit 
+them and right-click to #include them.  To begin a project, type Ed("filename");
+, supplying a filename.  You can also run programs with <F5> when in the editor. 
+<ESC> to save and exit the file.  You'll need to do a new Dir() cmd, 
+periodically, so make a macro on your PersonalMenu.  Access your PersonalMenu by 
+pressing <CTRL-m>, cursoring until you are on top of it and pressing <SPACE>.
+
+<CTRL-t> toggles plain text mode, showing format commands, a little like viewing 
+html code.
+<CTRL-l> inserts a text widgets.
+<CTRL-r> inserts or edit a graphic sprite resource at cursor location.
+<CTRL-d> brings-up the file manager.  It's pretty crappy.  I find I don't need 
+it very often, believe it or not.
+<CTRL-b> toggles window border.
+
+<ALT-m> maximizes a window.
+<ALT-SHIFT-a> closes AutoComplete.
+<ALT-a> brings back AutoComplete.
+<ALT-v> vertically tiles windows.
+<ALT-h> horizontally tiles windows.
+The ALT keys are defined in ~/HomeKeyPlugIns.HC.  You can customize them.
+
+<CTRL-ALT-t> new terminal window.
+<CTRL-ALT-n> switches to the next window.
+<CTRL-ALT-x> kills a window.
+
+Find() is your best friend.  There's a wrapper function called F() in your ~/Hom
+eWrappers.HC.Z file.  Feel free to make wrapper functions for functions you use 
+often and customize the args.  By the way, Find() or R() can be used to replace 
+strings across multiple files.  You can access Find() using <CTRL-SHIFT-f>.
+
+As you browse code, use the AutoComplete window to look-up functions, etc.  <CTR
+L-SHIFT-F1> (or whatever number) to follow a sym to it's source.  You can browse 
+deeper and deeper.  You go back with <SHIFT-ESC>.
+
+Use the Help & Index or Demo Index to find-out what exists.  Press <F1> for help 
+or use the links on your menu (<CTRL-m>).  Also, look in the /Demo or /Apps 
+directories for inspiration.
+
+Software is distributed as RedSea ISO files.  Burn a CD/DVD, or set your CD/DVD 
+in QEMU, VMware or VirtualBox to the ISO file.  Then, access the 'T' drive.  Or, 
+Mount() the ISO.C file and access the 'M' drive in TempleOS.  It must be a 
+contiguous ISO.C file, so rename it under TempleOS to ISO.C.
+
+Ideally, do not install applications such as games onto your hard drive because 
+we wish to keep hard drive usage low, so the whole 'C' drive can be copied 
+quickly to 'D'.  Also, the FileMgr() <CTRL-d> starts too slowly when there are 
+lots of hard drive files, but that is how we want it.
+
+3rd party libraries are banned, since they circumvent the 100,000 line of code 
+limit in the TempleOS Charter.  All applications must only depend on the core 
+TempleOS files and whatever they bring along in the ISO.  This is similar to how 
+Commodore 64 applications only depended on the ROM.
+
+Create a RedSea ISO file with RedSeaISO().  Send an email to 
+tdavis@templeos.org if you want me to post a link to your TempleOS code in the 
+App Store.
+
+Take Tour
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Src/Doc/WhyNotMore.DD.HTML b/public/Wb/Home/Src/Doc/WhyNotMore.DD.HTML new file mode 100755 index 0000000..0121162 --- /dev/null +++ b/public/Wb/Home/Src/Doc/WhyNotMore.DD.HTML @@ -0,0 +1,118 @@ + + + + + + + + + + + +
+                                 Why Not More?
+
+If a feature cannot be made to work correctly and consistently, professional 
+companies usually remove the feature.  Because PC hardware is so diverse, 
+getting things to work on all people's computers is really difficult.  For one 
+thing, you practically have to own all the different hardware to write drivers 
+for it.  If a company wanted to sell a PC operating system, they would offer a 
+warranty and, therefore, could not get away with amateur behavior.  TempleOS 
+absolutely requires 64-bit computers, so we leave behind much trouble, but 
+plenty remains.
+
+The PCI bus interface is what modern hardware uses.  Before PCI, life was simple 
+and devices used I/O ports.  After studying PCI Interrupts and attempting to do 
+a HDAudio driver, I came to realize that modern PCI devices require ten times 
+more code and I cannot even come close to making them work on everyone's machine 
+because with PCI devices there are several models to worry about, unlike with 
+the older ISA bus devices which can be done with one driver.
+
+Currently, I have no PCI drivers.  My drivers use I/O ports and operate in ISA 
+bus mode.  At this point, I only have one driver for each type of device and it 
+is delightfully simple that way.  I have one keyboard driver, one mouse driver, 
+one ATA hard drive driver, one ATAPI CD/DVD driver, one VGA 640x480 16 color 
+video driver and one PC Speaker driver.  I use the PIT and HPET timers and 
+PIC Interrupt Controller.  I use  IRQ0 for timer, IRQ1 for keyboard, and IRQ12 
+for mouse.  If IRQ12 is not firing, I am able to poll the mouse.
+
+In the CPU department, I have state of the art 64-bit long mode with multicore 
+support.  I use the APIC and start-up multicore operation.
+
+I have made an incredible accomplishment by getting it to work on practically 
+everyone's computer as long as it is 64-bit and they run inside VMware, QEMU or 
+VirtualBox.
+
+Adding a USB driver would be really ugly with UHCI, EHCI, OHCI, USB1, USB2, 
+USB3, ICH6, ICH7, ICH8, ICH9, ICH10, ICH11, ICH12, boot mode and regular mode 
+for keyboard/mouse and a diversity of HID reports.  It's hopeless.  I could 
+never offer anything but crappy, limited support and it would just add a ton of 
+crappy code that mostly didn't work.  What would I gain?  Nothing.  A keyboard 
+or mouse would not be improved.  Solid State USB drives would be really nice, 
+but it's not going to happen.
+
+The same story is basically true for GPUs, audio, networking and AHCI hard drive 
+drivers.  God said 640x480 16 color was a covenant like circumcision, so the 
+video will never change, even if a Standard PC was made.  If you attempt 
+multimedia, everything will break because memory will get fragmented with huge 
+multimedia files.  Some day, if super-simple high speed serial allows 
+networking, there will be no browser within the 100,000 line limit and, with 
+only 16 colors, the world wide web is not tolerable.  FTP and telnet might be 
+possible, in the far distant future, if they could fit within the 100,000 line 
+limit.  Currently, there are 80,849 lines of code.
+
+I don't stand a chance working on native hardware, anymore.  I could install and 
+run natively on hardware from about 2005-2010.  It requires BIOS's being nice 
+enough to write USB mode PS/2 legacy keyboard/mouse support.  As it turns-out, 
+sometimes the BIOS has PS/2 drivers but purposely disables them, just to be 
+mean.  The CIA and whole industry is trying to mess everything up, on purpose.  
+Perhaps, at a point of sale in a store, a thief could hack a credit card 
+machine.  Therefore, the BIOS companies actually want it difficult to make 
+drivers and purposely make it broken.
+
+The ATA/ATAPI hard drives often can be run with I/O ports if you can find them.  
+lspci -v on Linux or system information on Windows can help you locate the SATA 
+IO ports the hard drive and CD/DVD have.  They no longer are enabled by the 
+BIOS.  It's hopeless.  I'm stuck with very slow drive performance, but it works 
+for everybody.
+
+UEFI is pointless.  If I am forced to run in VMware, QEMU or VirtualBox, they 
+will always support non-UEFI mode.  Without working, native hard drive and 
+CD/DVD drivers, you can't get very far with UEFI on a native install, not to 
+mention SecureBoot.  UEFI is, first of all, redundant.  If non-UEFI works in a 
+virtual machine, supporting UEFI would only be redundant, ugly nasty code.  My 
+compiler does not create an ELF or PE format.  I would have to ruin the beauty 
+of my compiler, which would make me cry many tears.
+
+God talks.  It seems reasonable that I will get to make the rules for the whole 
+industry, in the future when God is announced publically to the World.
+
+I made ::/Doc/Demands.DD.
+
+When the PC was created, they wanted flexibility because they did not know the 
+future.  Now, the industry is mature and it is time to make a 100% standard PC 
+that everybody uses.  ::/Doc/StdTempleOSPC.DD
+
+
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Src/Doc/Widget.DD.HTML b/public/Wb/Home/Src/Doc/Widget.DD.HTML new file mode 100755 index 0000000..cd751ff --- /dev/null +++ b/public/Wb/Home/Src/Doc/Widget.DD.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+                               DolDoc Widget Help
+
+DolDoc is a TempleOS document type.
+
+"Expression" a num or HolyC algebraic term with operators and HolyC syms can be 
+entered.
+"Macro" Most entries can behave like macro entries if you assign them macro 
+strs.
+"InStr" Like a macro except it is an InFile.  You can't have both an in_str and 
+macro text defined.  
+
+Tag Text is the text that will be displayed for the item.  For links, you can 
+leave it blank and the details of the link will be shown.
+Hide means display nothing, making an entry invis.
+
+Left X relative to the left margin.
+Center X relative to the horizontal center of the window.
+Right X relative to the right margin.
+Top Y relative to the top of the window.
+Center Y relative to the vertical center of the window.
+Bottom Y relative to the bottom of the window.
+
+Blink make the text blink.
+Invert make the text inverted.
+Underline make the text underlined. 
+
+Scroll X Length Expression if a value is entered, the text will scroll in an 
+area of this width.
+Y Offset Expression if a value is entered, the text will be shifted vertically 
+by this many pixs, so you can make superscripts or subscripts.
+X Offset Expression if a value is entered, the text will be shifted horizontally 
+by this many pixs.
+
+Tree The item will behave like a tree widget, with this as the root.
+Collapsed The tree or hidden widget will begin collapsed.
+Define Str will substitute a #define or DefineLoad() string for the tag.
+
+Quote Make the res suitable for including in a program, in quotes, especially fo
+rmat entries in class definitions.
+
+X Expression For cursor movements, the horizontal value.
+Y Expression For cursor movements, the vertical value.
+
+PopUp For macro's, run the macro in a PopUp window.  Do this when making a macro 
+to run a program, so it doesn't tie-up memory.
+
+Escape For macro's, send an <ESC> char to exit before running the macro.  
+Without this, the macro runs in the wrong window, usually.
+
+Refresh Data  updates $DA...$ entry continuously.
+
+Html Link  stores a link which will be embedded if you generate a html version 
+of a document with ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+ diff --git a/public/Wb/Home/Src/Doc/Windows.DD.HTML b/public/Wb/Home/Src/Doc/Windows.DD.HTML new file mode 100755 index 0000000..ec323a2 --- /dev/null +++ b/public/Wb/Home/Src/Doc/Windows.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Only tasks on Core0 can have a window and there can be only one window per task. 
+ The window Z-buffer, top-to-bottom order is determined by the order in the task 
+queue, with the WinMgr on the bottom.  A task can have child task popup windows.
+
+ diff --git a/public/Wb/Home/Src/Downloads/TemplarLetters/TSheikhs/171207SerialPort.DD.HTML b/public/Wb/Home/Src/Downloads/TemplarLetters/TSheikhs/171207SerialPort.DD.HTML new file mode 100755 index 0000000..f7dfeb2 --- /dev/null +++ b/public/Wb/Home/Src/Downloads/TemplarLetters/TSheikhs/171207SerialPort.DD.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+Letter from St.Terry to T.Sheikhs 171207
+
+
+
+
+Sorry I didn't thank you for your serial port web browser
+
+I had dreams of commanding Intel and the nation
+
+looks like I gotta live in the real world
+
+
+Perhaps, I can pull-off being king of AZ/NV
+
+and get a lowbandwith network going in a meaningful way
+
+
+the serial port link out of templeos didn't thrill me
+
+kinda seemed frankenstein but looks like
+
+we gotta live in the real world and I guess the future
+
+is running templeos in vmware in linux
+
+running the serial port out
+
+
+hopefully i can get a bridge built into a cell
+
+phone.  motorola is local xompany
+
+maybe ge a bridge o cb radio
+
+
+I have fond memories of the C64 era and bullitin boards
+
+
+you know it is rich for my soul
+
+
+yes i picture templeos files being echanged
+
+on this new low bandwidth alternate to the
+
+internet, see if I can get it going
+
+
+ diff --git a/public/Wb/Home/Src/Home/DoDistro.HC.HTML b/public/Wb/Home/Src/Home/DoDistro.HC.HTML new file mode 100755 index 0000000..be7cb9a --- /dev/null +++ b/public/Wb/Home/Src/Home/DoDistro.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+//Make Your own Distro by #include-ing this file.
+
+#define STD_DISTRO_DVD_CFG      "TB\nScale2Mem(2048,0x40000)\nT \n\n\n\n"
+
+U0 MakeMyISO(U8 *_out_iso_filename)
+{//Does everything with current drive.
+//If you have not recompiled Kernel and defined your CD/DVD drive, use Mount.
+  U8 *out_iso_filename=FileNameAbs(_out_iso_filename);
+  if (!DrvIsWritable) {
+    "Drive must be writable.  Install on Hard drive, first.\n";
+    return;
+  }
+  DelTree("/Distro");
+  Del(out_iso_filename);
+
+  DirMk("/Distro");
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns;
+
+  Copy("/*","/Distro");
+  Del("/Distro/" KERNEL_BIN_C);
+
+  CopyTree(BOOT_DIR,    "/Distro" BOOT_DIR);
+  CopyTree("/Home",     "/Distro/Home");
+  CopyTree("/Adam",     "/Distro/Adam");
+  CopyTree("/Apps",     "/Distro/Apps");
+  CopyTree("/Compiler", "/Distro/Compiler");
+  CopyTree("/Demo",     "/Distro/Demo");
+  CopyTree("/Doc",      "/Distro/Doc");
+  CopyTree("/Kernel",   "/Distro/Kernel");
+  CopyTree("/Misc",     "/Distro/Misc");
+
+  //To save space, optionally delete dictionary.
+  //Del("/Distro/Adam/AutoComplete/ACDefs.DATA");
+  CopyTree("/Downloads","/Distro/Downloads");     //You can leave this out.
+  DirMk("/Distro/Tmp");
+  DirMk("/Distro/Tmp/ScrnShots");
+  RedSeaISO(out_iso_filename,"/Distro","/Distro" BOOT_DIR_KERNEL_BIN_C);
+
+  //If CD-ROM use MT_CD instead of MT_DVD.
+  //DVDImageWrite('T',out_iso_filename,MT_DVD); //Uncomment to burn.
+
+  //DelTree("/Distro");
+  Free(out_iso_filename);
+}
+
+MakeMyISO("/Tmp/MyDistro.ISO.C");
+
+// Study my account examples Cfg Strs, Update Funs.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/AboutTempleOS.DD.HTML b/public/Wb/Home/Src/Home/Doc/AboutTempleOS.DD.HTML new file mode 100755 index 0000000..4058dba --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/AboutTempleOS.DD.HTML @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+                                    TempleOS
+
+
+Websites:
+www.templeos.org
+
+Owner/President:
+Terry A. Davis
+
+
+ +8144 Sickle Lane +Las Vegas, NV 89128 +(702)254-4223 + +tdavis@templeos.org + + +About Me: + +I was a National Merit Scholar with a 1440 SAT at Arizona State University. I +have a bachelor's in Computer System Engineering from ASU, basically, embedded +systems, and a master's in Electrical Engineering from ASU, control systems. I +worked as a software, hardware and mechanical engineer at Ticketmaster from +1990-1996. + +I designed a 3 axis stepper-motor-driven milling machine 1996-1997 with a +CAD/CAM package for a company I started called Home Automation and Robotic +Equipment. + +
+ +I worked for a company named Xytec Corp. 1997-1999. We made FPGA-based image +processing equipment. I wrote SimStructure from 2000-2001 for H.A.R.E. I +worked as head software/electrical engineer for a company called Graphic +Technologies, 2001-2002, making replacement chips for toner printer cartridges +so they could be refilled. + +Credits: +See ::/Doc/Credits.DD. + +
+ diff --git a/public/Wb/Home/Src/Home/Doc/Asm.DD.HTML b/public/Wb/Home/Src/Home/Doc/Asm.DD.HTML new file mode 100755 index 0000000..7d34c33 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Asm.DD.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+                                   Assembler
+
+See ::/Compiler/OpCodes.DD for opcodes.  They're not standard.  Some invalid 
+insts are not flagged and some valid insts are not implemented. 16-bit asm 
+support is limited.
+
+Here are example inst formats:
+        ADD     RAX,I64 FS:DISP[RSI+RDI*8]
+        ADD     RAX,I64 [DISP]
+
+$ Current compiler output pos (inst ptr).  Even works in HolyC expressions.
+
+$ works in classes.
+  class MyFun
+  {
+    $=-16;
+    I64 local1;
+    I64 local2;
+    $=$+256;
+    I64 crazy;
+  };
+
+LABEL::
+  Defines an exported glbl label.
+
+LABEL:
+  Defines an non-exported glbl label.
+
+@@LABEL:
+  Defines a local label with scope valid between two global labels.
+
+DU8, DU16, DU32, DU64
+  Define BYTE, WORD, DWORD or QWORD. Can be used with DUP() and ASCII strings.  
+For your convenience, the ASCII strings do not have terminating zeros.  Define 
+cmds must end with a semicolon.
+
+USE16, USE32, USE64
+
+IMPORT sym1name, sym2name;
+
+LIST, NOLIST
+
+ALIGN num, fill_byte
+  Align to num boundary and fill with fill_byte.
+
+ORG num
+  Set code addr for JIT or set module Load() addr -- has 16-byte CBinFile header 
+and patch table trailing.
+
+BINFILE "FileName.BIN";
+
+See Assembly Language, ::/Demo/Asm/AsmAndC1.HC, ::/Demo/Asm/AsmAndC2.HC and 
+::/Demo/Asm/AsmAndC3.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/AutoComplete.DD.HTML b/public/Wb/Home/Src/Home/Doc/AutoComplete.DD.HTML new file mode 100755 index 0000000..c219a94 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/AutoComplete.DD.HTML @@ -0,0 +1,55 @@ + + + + + + + + + + + +
+AutoComplete is the LTGRAY window on the right of the scrn.  ACInit() collects 
+words from all text files in subdirectories.  Normally, the call to ACInit() is 
+in HomeSys.HC.  It provides auto-complete for typing, jump-to-code and 
+jump-to-dictionary functionality.
+
+<ALT-SHIFT-A>   Closes the LTGRAY AutoComplete window.
+<ALT-a>         Opens the LTGRAY AutoComplete window.
+
+<CTRL-SHIFT-F1> Jumps to the source code for 1st symbol in the window.
+<CTRL-SHIFT-F2> Jumps to the source code for 2nd symbol in the window.
+<CTRL-SHIFT-Fn> Jumps to the source code for n-th symbol in the window.
+<CTRL-F1>       Autocompletes the 1st symbol in the window.
+<CTRL-F2>       Autocompletes the 2nd symbol in the window.
+<CTRL-Fn>       Autocompletes the n-th symbol in the window.
+<CTRL-SHIFT-1>  Jumps to the dictionary for 1st symbol in the window.
+<CTRL-SHIFT-2>  Jumps to the dictionary for 2nd symbol in the window.
+<CTRL-SHIFT-n>  Jumps to the dictionary for n-th symbol in the window.
+<CTRL-1>        Autocompletes the 1st dictionary word in the window.
+<CTRL-2>        Autocompletes the 2nd dictionary word in the window.
+<CTRL-n>        Autocompletes the n-th dictionary word in the window.
+
+If you have the raw Project Gutenberg dictionary file, you can generate the 
+TempleOS processed dictionary files with the stand-alone program 
+::/Adam/AutoComplete/ACDictGen.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Bit.DD.HTML b/public/Wb/Home/Src/Home/Doc/Bit.DD.HTML new file mode 100755 index 0000000..8b95802 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Bit.DD.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+
+These take a pointer to a bit field.
+Bt:     Bit Test
+Bts:    Bit Test and Set to one
+Btr:    Bit Test and Rst to zero
+Btc:    Bit Test and Compliment (toggle)
+BEqu:   Set bit to value.
+
+Bit operations are "atomic", no interrupt between the reading and writing the 
+bit, important when multitasking.  For multicore use "locked" forms.
+
+These don't take a pointer, but the actual field.
+Bsf:    Bit Scan Fwd (Pos of first low one bit or -1)
+Bsr:    Bit Scan Rev (Pos of first high one bit or -1)
+BCnt:   Bit Cnt (Cnt of set bits)
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/BlkChain.DD.HTML b/public/Wb/Home/Src/Home/Doc/BlkChain.DD.HTML new file mode 100755 index 0000000..f56dbae --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/BlkChain.DD.HTML @@ -0,0 +1,75 @@ + + + + + + + + + + + +
+                                  Block Chain
+
+There was a technique on the Commodore 64 where disk blocks were chained 
+together with a block pointer at the end of each block.  This is far inferior to 
+having a file allocation table, as in FAT32.
+
+The RedSea file system does not allow files to grow because it only has an 
+allocation bitmap and not a FAT table.  This "flaw" is by design.  I am 
+intentionally crippling this operating system, making it a toy with the wisdom 
+that this will prevent commercialization and corruption.  The toy spirit of the 
+operating system will be preserved going into the future.  The vision for this 
+operating system was a modern Commodore 64, which was a fun toy.
+
+Doing whole file operations is the TempleOS way of doing thinks.  It is the 
+simplest and, ironically, the fastest.  It is obnoxious in the characteristic 
+way that TempleOS is obnoxious, flaunting massive modern resources in a way that 
+makes old programmers protest.
+
+Doing whole file operations will sabotage efforts to change the 640x480 
+resolution and violate the ban on multimedia.  When doing large, whole-file 
+operations, immediately memory fragmentation is a serious problem, but not so 
+for allocations in the range under a Meg (with occasional larger ones).
+
+The file compression scheme in TempleOS only works on whole file operations and 
+the DolDoc format cannot have text tacked onto the end, since binary data is at 
+the end.
+
+I don't want to spoil fun, so of course I offer a way to get awesome performance 
+that is, ironically, superior.  FBlkRead() and FBlkWrite() allow you to read a 
+block offset from the start of a file.  Since files are all contiguous, this is 
+incredibly efficient.  You just have to declare the desired file size when you 
+create it with FOpen() and cannot change it.  See ::/Demo/Dsk/DataBase.HC.
+
+If you like, you are encouraged to to do raw BlkRead() and BlkWrite() directly 
+on a drive.  Just get a pointer to a CDrv with Let2Drv() and you are on your 
+way!  Your computer is supposed to be a fun toy!  You can make an entire 
+partition used for a database, or invent a file system.
+
+On the whole, the RedSea file system with its whole-file-only limitation bring 
+beautiful harmony.  It beautifully captures the spirit of TempleOS with 
+simplicity and, ironic speed, since contiguous is fastest.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Boot.DD.HTML b/public/Wb/Home/Src/Home/Doc/Boot.DD.HTML new file mode 100755 index 0000000..84569c2 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Boot.DD.HTML @@ -0,0 +1,142 @@ + + + + + + + + + + + +
+                                  Booting A PC
+
+TempleOS only supports traditional BIOS booting, not the newer technique, UEFI.  
+This document describes BIOS booting.
+
+When you turn-on (power-up) a computer or you do a hardware reset, the computer 
+starts executing the BIOS.  Sometimes, you must change the BIOS boot order to 
+boot the device you want.
+
+The BIOS loads a boot sector from CD/DVD, hard disk or whatever.  The boot 
+sector runs in 16-bit real mode and often loads-in a second file that's bigger 
+if it can't be done by just one sector.  It's a safe bet that boot sectors are 
+hand-coded assembly language.  Most boot sectors use the BIOS to load-in the 
+next stage.
+
+Not only do boot sectors have a size limit, 512 bytes or 2048 bytes for CD/DVD, 
+the files they load have to fit within 640K because they run in 16-bit mode.  
+This means they usually can't just load the whole operating system and start it 
+running.  Some boot loaders, like Grub, have a capability of switching modes 
+before handing-off control to the operating system.  The operating system must 
+load the rest of itself.  With TempleOS, the ::/Kernel.BIN.C file is loaded by 
+the boot sector.  I try to put a minimum in the Kernel Module, so that it will 
+always fit in 640K.  When Kernel.BIN runs, it switches to 32-bit mode, then, to 
+64-bit mode allowing access to more memory.  Then, it loads in the rest of 
+TempleOS by executing ::/StartOS.HC.
+
+All the boot related code for TempleOS is in the /Adam/Opt/Boot directory.
+
+BootDVD.HC      CD/DVD boot sector.
+BootDVDIns.HC   Prep for CD/DVD install by creating /0000Boot/0000Kernel.BIN.C.
+If you are curious about CD/DVDs, see DskISORedSea.HC.  To make a custom 
+bootable CD/DVD, look here Bootable CD.
+
+BootMHD.HC      Stage 1 Master HD boot loader.
+BootMHD2.HC     Stage 2 Master HD boot loader.
+BootMHDIns.HC   Installs Master HD boot loader.
+BootMHD goes on block zero.  /0000Boot/BootMHD2.BIN.C is stored as a file in a 
+partition, risky and unusual, since most master boot loaders place stage 2 in a 
+gap that's not in any partition.  BootMHD2 displays a menu and boots a 
+partition.
+
+BootHD.HC       HD partition boot record.
+BootHDIns.HC    Installs HD partition boot record.
+BootHD is the boot record for a TempleOS partition.  Each partition has its own 
+partition boot record, the first block of the partition.
+
+My boot records don't access directories because that would make them too big 
+for one block and would make them depend on a file system layout.  Instead, they 
+get patched with the LBA, logical block addresses, to load files.  To update 
+with a new TempleOS kernel, you must create a ::/Kernel.BIN.C binary file and 
+patch the boot loader so it knows the LBA blocks to load.  Therefore, you 
+usually recompile the kernel and update the boot sector at the same time with  
+BootHDIns().  BootMHDIns() will install a master boot loader.
+
+With TempleOS, ::/Kernel.BIN.C loads ::/Compiler/Compiler.BIN so it can work 
+with source code from then on.  It compiles start-up scripts beginning with 
+::/StartOS.HC into the Adam Task's memory including the code in the /Adam and /H
+ome directories.
+
+It is possible to do a fast reboot without doing a hardware reset.  You might do 
+this when working on ::/Kernel.BIN.C or your start-up scripts when you want to 
+compile them effect.  See BootRAM().
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/CharOverview.DD.HTML b/public/Wb/Home/Src/Home/Doc/CharOverview.DD.HTML new file mode 100755 index 0000000..095a0a9 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/CharOverview.DD.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+                                 Char Overview
+
+A Character is a single byte holding an ASCII code for a letter, num or sym.  
+The TempleOS term is a U8.
+
+Standard ASCII values range from 0 to 127.  Values below 32 are ctrl key's.  So, 
+an ASCII #3 is a <CTRL-c>.  TempleOS uses a few nonstandard values below 32.  
+See Char Definitions.
+
+ASCII #5  is the cursor location in a saved file.
+ASCII #28 is <SHIFT-ESC>.
+ASCII #31 is a <SHIFT-SPACE>.
+
+TempleOS ASCII is 8-bit instead of 7-bit, so it also uses the range from 
+128-255.  Press <CTRL-ALT-a> to see shapes for 128-255.  Technically, <CTRL-ALT-
+a> are scrn codes.
+
+A Key is typically specified with a scan code.  TempleOS scan codes contain the 
+key value in the lowest U8, and flags in the upper 3 bytes.  See 
+Scan Code Flags and Scan Codes.
+
+TempleOS stores scan codes in 8 bytes.
+  Byte 0   is the code.  NumPad keys, SHIFT, ALT, CTRL and GUI keys combined.
+  Byte 1-3 are flags
+
+The upper 4-bytes are copied from lower 4-bytes.
+  Byte 4   is the code.  Left, Right and NumPad keys distinct.
+  Byte 5-7 are flags
+
+Run the program ::/Demo/MsgLoop.HC to examine scan code.  Press <CTRL-SHIFT-l> 
+and "Insert ASCII/ScanCode".
+
+See Key Allocations and CKbdStateGlbls.
+
+A String is a bunch of ASCII characters terminated with a zero.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Charter.DD.HTML b/public/Wb/Home/Src/Home/Doc/Charter.DD.HTML new file mode 100755 index 0000000..b802d17 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Charter.DD.HTML @@ -0,0 +1,158 @@ + + + + + + + + + + + +
+                                TempleOS Charter
+
+Why did they make Solomon's Temple?  It was a direction to look, to focus on, a 
+special place for meditation, to do offerings, a community center, a home to 
+God's beauty, that encouraged love of God.  People cherished God's temple, 
+beautifying it with gold and all fine things to show love of God, as great 
+cathedrals were decorated with astounding, awe-striking intricate art and 
+gargoyles, incredible devotion to God with hours of effort, toiling and 
+slaving-away for the glory of God, for families with children to see 
+stained-glass windows and tomes with ridiculously elaborate calligraphy to show 
+love of God, from a people who did little else but show love toward God, lived 
+in dire conditions by today's standards, yet with so much difficulty 
+scraping-by, found the time to devote even all free-time to God!
+
+
+1 Kings 6:21 (King James)
+
+     6:21 So Solomon overlaid the house within with pure gold: and he made
+     a partition by the chains of gold before the oracle; and he overlaid
+     it with gold.
+     
+     6:22 And the whole house he overlaid with gold, until he had finished
+     all the house: also the whole altar that was by the oracle he overlaid
+     with gold.
+     
+     6:23 And within the oracle he made two cherubims of olive tree, each
+     ten cubits high.
+
+
+* TempleOS is God's official temple.  Just like Solomon's temple, this is a 
+community focal point where offerings are made and God's oracle is consulted.
+
+* God said 640x480 16 color graphics is a covenant like circumcision.  Children 
+will do offerings.  Think of 16 colors like the Simpson's cartoons.  In the 
+future, even if one GPU were universal, we would still keep 640x480 16 color and 
+not use GPU acceleration.  Graphics operations should be transparent, not hidden 
+in a GPU.
+
+* God said to use a single-voice 8-bit signed MIDI-like sample for sound.  God 
+does not want death screams, perhaps, because God has PTSD or soldiers have 
+PTSD.  (Imagine wounded on battlefields.) 
+
+* God said His temple must be perfect.  We don't think twice about breaking 
+compatibility.  God said we do a seven year release cycle.  I say the PC 
+hardware follows a 49 year, jubilee cycle, like broadcast TV upgrades.
+
+* The vision is the same usage model and niche as the Commodore 64 -- a 
+non-networked, simple machine where programming was the goal, not just a means 
+to an end.  However, it is modern, 64-bit and multi-cored.  It is special 
+purpose, not general purpose, so some things it will not do.  Also, it's a 
+kayak, not a Titanic. The priority is user developers, not 3rd party developers.
+
+* We do not put any hooks for future changes.  "Perfect" means we always act as 
+though it is final, for all time.  Microsoft allowed the Windows BMP file format 
+to adapt to the future and it became grotesque.
+
+* Low line count is the highest good, so it is easy to learn the whole thing.  
+Users should see the light at the end of the tunnel.  One file system, for 
+example, is better than many file systems.
+
+* There is a limit of 100,000 lines of code for all time, not including 
+applications and demos.  Code comments count, however.  Currently, there are 
+80,849 lines of code.  3rd party libraries are banned because they circumvent 
+the intent of this limit.  The vision is a Commodore 64 ROM -- a fixed core API 
+that is the only dependency of applications.  Dependency on components and 
+libraries creates a hell that is no longer blissful.
+
+* The metric for resolving all TempleOS code governance issues is how fast the 
+compiler compiles itself and the kernel with BootHDIns().  The HolyC language 
+should be changed to optimize this metric, as I did when I changed type casting 
+from prefix standard C to postfix HolyC, but we need a rule to prevent 
+degenerating into a brainfuck language.
+ 
+* Minimal abstraction is a goal.  Sheep are fools.  They always respect a design 
+that is more complicated than another.  Any genius can make it complicated.  
+Like in physics, it takes a supra-genius to make it simple.
+
+* It is for one platformc -- x86_64 desktop PC compatibles, more like 
+super-computers than battery efficient wimpy mobiles.
+
+* All hardware access will be done through x86 IN/OUT instructions, not PCI 
+drivers.  A frame buffer for VGA is an exception.
+
+* One driver for each class of device.  Limited exceptions are allowed.  With 
+divergent device capabilities, it is a nightmare for user applications and what 
+is gained?  A three buuton mouse is like a leg you cannot put weight on.
+
+* Ring-0-only.  Everything runs in kernel mode, including user applications.
+
+* Full access to everything.  All memory, I/O ports, instructions, and similar 
+things must never be off limits.  All functions, variables and class members 
+will be accessible.  There are no C++ public/private protections and all 
+functions, even secondary ones in the kernel, can be called.
+
+* Single-address-map as though paging is not used.  Long mode requires paging, 
+however, so the nearest thing is keeping all memory identity-mapped.
+
+* No networking, so malware is not an issue.
+
+* No encryption or passwords.  Files are compressed, not encrypted.
+
+* Free and public domain.
+
+* 100% open source with all source included.
+
+* Documents are not for printing.  They're dynamic, intended for the scrn.
+
+* Just one 8x8 fixed-width font.  No Unicode, just Extended ASCII.  Other 
+countries can make their own versions.  The versions should be just for one 
+language and platform.
+
+* No multimedia.  Sounds and images will be primarily calculated in real-time, 
+not fetched from storage.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+* "The Simpsons" is a trademark owned by Fox.
+* "Windows" is a trademark owned by MicroSoft Corp.
+
+
+
+                              Possible Amendments
+
+The compiler's parser makes RISC code which it optimizes to CISC.  I discovered 
+this does not matter because the CPU converts it back to RISC and schedules it, 
+internally.  A TempleOS zealot with more zeal than I, might say we should save 
+lines-of-code by removing the CISC optimizing.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/CmdLineOverview.DD.HTML b/public/Wb/Home/Src/Home/Doc/CmdLineOverview.DD.HTML new file mode 100755 index 0000000..05fd4a7 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/CmdLineOverview.DD.HTML @@ -0,0 +1,81 @@ + + + + + + + + + + + +
+                             Command Line Overview
+
+The cmd line feeds into the HolyC compiler line-by-line as you type.  A stmt 
+outside a function executes immediately.  Remember to add a semicolon.
+
+Look-up the function headers with AutoComplete by hitting <CTRL-SHIFT-F1> after 
+typing the first few letters.
+
+Click Here to see the directory cmd header.  It accepts default args from C++.
+
+>Dir("*.DD.Z");
+
+If you don't have args, you don't need parenthesis.
+
+>Dir;
+
+Directories are referenced with / not \.  There is a current directory, but not 
+a path.  To run a program, you typically #include it.  There are several 
+shortcuts for #includeing files.  Right-click or hit <ENTER> on a directory 
+listing or press <F5> while editing.
+
+>Ed("NewFile.HC.Z");    Invokes the editor. See Doc Link Type.
+
+Most filenames end in .Z because they are stored compressed.
+
+Drives are specified with a letter.  The boot drive is specified with a ':'.  
+The home dir drive is specified with a '~'.
+
+>Drv('B');      B drive
+
+The drive can be specified in a Cd() command as in:
+
+>Cd("B:/Tmp");  B drive
+>Cd("::/Demo"); Boot drive
+
+The home directory is specified with a '~'.
+
+>Cd("~/Psalmody");      See ::/Home dir.
+
+If a file is not found, .Z is added or removed and a search is done, again.  If 
+a file is still not found, all parent directories are searched.
+
+You can place macros in your PersonalMenu for Cd() commands.  <CTRL-m> to access 
+your menu.
+
+>Find("needle","/Demo/*.HC.Z;*.DD.Z;"); See File Utils.
+
+Cmd Line Routines
+
+Take Tour
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Comm.HC.HTML b/public/Wb/Home/Src/Home/Doc/Comm.HC.HTML new file mode 100755 index 0000000..72312db --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Comm.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+/* RS232 serial ports no longer exist.
+Be sure to Adam Include this by placing
+it in your start-up scripts.
+*/
+
+#help_index "Comm"
+
+#define UART_THR                0
+#define UART_RDR                0
+#define UART_BRDL               0
+#define UART_IER                1
+#define UART_BRDH               1
+#define UART_IIR                2
+#define UART_LCR                3
+#define UART_MCR                4
+#define UART_LSR                5
+#define UART_MSR                6
+
+#define COMf_ENABLED    0
+class CComm
+{
+  I64   base,
+        flags;
+  CFifoU8 *RX_fifo;
+  CFifoU8 *TX_fifo;
+} comm_ports[5];
+
+U0 CommHndlr(I64 port)
+{
+  CComm *c=&comm_ports[port];
+  I64 b=0,stat;
+  if (Bt(&c->flags,COMf_ENABLED)) {
+    stat=InU8(c->base+UART_IIR);
+    if (stat & 4)       //RX
+      FifoU8Ins(c->RX_fifo,InU8(c->base+UART_RDR));
+    if (stat & 2) {     //TX
+      if (FifoU8Rem(c->TX_fifo,&b))
+        OutU8(c->base+UART_THR,b);
+      else
+        OutU8(c->base+UART_IER,1); //RX but no THR empty
+    }
+  }
+}
+
+interrupt U0 IRQComm3()
+{
+  CommHndlr(2);
+  CommHndlr(4);
+  OutU8(0x20,0x20);
+}
+
+interrupt U0 IRQComm4()
+{
+  CommHndlr(1);
+  CommHndlr(3);
+  OutU8(0x20,0x20);
+}
+
+U0 CommInit()
+{
+  MemSet(&comm_ports,0,sizeof(comm_ports));
+  comm_ports[1].base=0x3F8;
+  comm_ports[2].base=0x2F8;
+  comm_ports[3].base=0x3E8;
+  comm_ports[4].base=0x2E8;
+  IntEntrySet(0x23,&IRQComm3);
+  IntEntrySet(0x24,&IRQComm4);
+}
+CommInit;
+
+public CComm *CommInit8n1(I64 port,I64 baud)
+{
+  CComm *c=&comm_ports[port];
+
+  PUSHFD
+  CLI
+  if (LBts(&c->flags,COMf_ENABLED)) {
+    FifoU8Del(c->RX_fifo);
+    FifoU8Del(c->TX_fifo);
+  }
+  c->RX_fifo=FifoU8New(256);
+  c->TX_fifo=FifoU8New(256);
+  OutU8(c->base+UART_LCR,0);    //Set for IER
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_LCR,0x80); //Enable baud rate control
+  OutU8(c->base+UART_BRDL,(0x180/(baud/300)) & 0xFF);   //LSB
+  OutU8(c->base+UART_BRDH,(0x180/(baud/300)) / 256);    //MSB
+  OutU8(c->base+UART_LCR,3);    //8-none-1
+
+  InU8(c->base+UART_RDR);       //read garbage
+  InU8(c->base+UART_LSR);
+
+  OutU8(c->base+UART_MCR,4);
+  OutU8(c->base+UART_IER,0);    //Disable all IRQ
+  OutU8(c->base+UART_MCR,0xA);  //out2 and rts
+  OutU8(0x21,InU8(0x21) & (0xFF-0x18)); //Enable 8259 IRQ 3 & 4
+  OutU8(c->base+UART_IER,1);    //RX but no THR empty
+  POPFD
+
+  return c;
+}
+
+public U0 CommPutChar(I64 port,U8 b)
+{
+  CComm *c=&comm_ports[port];
+  PUSHFD
+  CLI
+  FifoU8Ins(c->TX_fifo,b);
+  OutU8(c->base+UART_IER,3);    //RX and THR empty
+  POPFD
+  Sleep(10); //!!! Remove this line!!!  Linux echo_socket is too slow.
+}
+
+U0 CommPutS(I64 port,U8 *st)
+{
+  I64 b;
+  while (b=*st++)
+    CommPutChar(port,b);
+}
+
+public U0 CommPutBlk(I64 port,U8 *buf,I64 cnt)
+{
+  while (cnt--)
+    CommPutChar(port,*buf++);
+}
+
+public U0 CommPrint(I64 port,U8 *fmt,...)
+{
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CommPutS(port,buf);
+  Free(buf);
+}
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/CompilerOverview.DD.HTML b/public/Wb/Home/Src/Home/Doc/CompilerOverview.DD.HTML new file mode 100755 index 0000000..0f4c387 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/CompilerOverview.DD.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+                                 Compiler Index
+
+::/Doc/Asm.DD
+
+::/Doc/Directives.DD
+
+::/Doc/Options.DD
+
+::/Doc/PreProcessor.DD
+
+::/Doc/ScopingLinkage.DD
+
+See Hello World.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Credits.DD.HTML b/public/Wb/Home/Src/Home/Doc/Credits.DD.HTML new file mode 100755 index 0000000..0ee38aa --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Credits.DD.HTML @@ -0,0 +1,113 @@ + + + + + + + + + + + +
+                                    Credits
+
+I, Terry A. Davis, wrote all of TempleOS over the past 20.6 years (full-time).  
+It can run on some bare metal 64-bit PC's from about 2005-2010 with no layering, 
+libraries, tools, modules or anything from other sources.  Otherwise, you run it 
+in a virtual machine, like VMware, QEMU or VirtualBox.  It is independent and 
+stands alone.  It has no networking, so it certainly doesn't call home.  100% of 
+the src code is including on all distro's, from the kernel to the compiler to 
+the boot loaders!  It is public domain, not GPL.
+
+*) ::/Kernel/FontStd.HC, is taken from FreeDOS.  It's public domain.
+
+*) ::/Kernel/FontCyrillic.HC, is taken from OrientDisplay without permission.
+
+*) ATA Reg and Cmd Definitions are originally from Linux.  Later, I got the 
+spec.
+
+*) The heap algorithm, ::/Kernel/Mem/MAllocFree.HC, is adapted from one I saw at 
+Ticketmaster when I worked on their VAX operating system.
+
+*) The LZW compression algorithm, ::/Kernel/Compress.HC, came from a magazine 
+and I implemented it when I worked for Ticketmaster.
+
+*) The adaptive-step-size-Runge-Kutta algorithm, ::/Adam/AMathODE.HC, is adapted 
+from the book, Numeric Recipies in C.
+
+*) The mountain in some games is from http://www.public-domain-photos.com.  The 
+wolf in BlackDiamond is also from there.  I took watermarked photos and 
+converted to 16 color.
+
+*) The FAT32 file system is owned by MicroSoft.
+
+*) A few features were inspired by MATLAB, such as ans in expressions at the 
+command-line.  There is a lot of MSDOS , Windows, VAXTMOS (VAX Ticketmaster 
+O.S.) and Unix inspiration, too, such as drive letters, command names, etc.
+
+*) I included PCIDevice Lst File.
+
+*) Thanks to whoever wrote this CppHtml.HC.Z.  I'm a novice on web stuff and you 
+helped me with html.  See ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+*) I looked at bootable CD boot sects, but didn't learn anything, finding it 
+easier to make my own.
+
+*) I think I got my original PC speaker code from Borland C.
+
+*) I found PS/2 keyboard and mouse code on the net and documentation.  My code 
+is very different.  I found VGA reg info on the net.
+
+*) Thanks to http://www.osdev.org for a couple tips.
+
+*) God told me to stick with 640x480 16 color and single-voice 8-bit signed 
+MIDI-like sample for sound.   He kept me from zombie-walking into making child 
+windows like Windows.  Instead, I made one window per task with no child 
+windows.  He also guided my progress, very obviously.
+
+*) I got Webster's Dictionary and The King James Bible from Project Gutenberg.
+
+*) John Carmack inspired me to use "Clamp" as a name instead of "Limit".  He 
+inspired me to use "needle" and "haystack" as names.  He inspired me to simplify 
+my Frames-Per-Second code.
+
+*) Bill Gates inspired me to add comments to my Help & Index.
+
+*) I hired an artist, Cody Rigby, for $3,000 worth of pixel art.
+
+*) Erik van der Karbargenbok wrote /Downloads shell scripts -- gw.
+
+*) The random number generator is from Donald Knuth in the wikipedia entry for 
+Linear_congruential_generator.
+
+
+* "MSDOS", "Windows", "MovieMaker", "MS Paint" and "FAT32" are trademarks owned 
+by MicroSoft Corp.
+* "SiteBuilder" is a trademark owned by Yahoo! Inc.
+* "MagicISO" is a trademark owned by MagicISO Corp.
+* "MATLAB" is a trademark owned by The Math Works, Inc.
+* "FreeDOS" is a trademark owned by Jim Hall.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VAX" is a trademark owned by Digital Equipment Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "VAXTMOS" is a trademark owned by Ticketmaster.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Ctrls.DD.HTML b/public/Wb/Home/Src/Home/Doc/Ctrls.DD.HTML new file mode 100755 index 0000000..a6691b8 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Ctrls.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+To create a TempleOS graphic ctrl, you define callback functions and insert a 
+CCtrl structure in the CTask queue.  See ::/Demo/Graphics/Slider.HC, 
+::/Demo/Graphics/ScrollBars.HC and TermBttnNew.  There is a template-code ctrl 
+generator, if you press <CTRL-SHIFT-L>.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Customize.DD.HTML b/public/Wb/Home/Src/Home/Doc/Customize.DD.HTML new file mode 100755 index 0000000..d00bed8 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Customize.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+
+* You can adjust the mouse movement rate by setting global vars in your start-up 
+file.  See mouse scale.
+
+* You can set your local time zone by setting the local_time_offset global var 
+in a start-up file.  It's units are CDATE_FREQ.  See local time.
+
+* Get rid of this msg here.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/CutCorners.DD.HTML b/public/Wb/Home/Src/Home/Doc/CutCorners.DD.HTML new file mode 100755 index 0000000..f1f9a9e --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/CutCorners.DD.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+                                  Cut Corners
+
+There are a few places where I cut corners in the interest of not junking-up 
+code.  This is part of the TempleOS mentality.  I try not to let stupid legacy 
+compatibility issues enter and junk-up TempleOS.
+
+* I made my type-casting operator post-fix because it makes the compiler way 
+cleaner.
+
+* TempleOS does not figure-out FAT32 short name alias numbers.  FAT32DirNew().  
+It can cause hard drive corruption, so I might have to do it.  It would really 
+take a lot of junky code for this hatefully, detestable, legacy issue.  "Please 
+don't make me ruin my beautiful shiny-new TempleOS with that!"  I am also not 
+enthused about FAT32 because it is in patent limbo.  FAT32 might get removed 
+from TempleOS.  There is the RedSea  64-bit file system that works perfectly 
+well.  FAT32 is useful, however, because it assists in transferring between dual 
+booted operating systems.
+
+* I changed the asm opcodes names to remove the ambiguity between insts with 
+different numbers of arguments, making my assembler simpler and I did minimal 
+16-bit asm support, since 64-bit is what you should be using, unless you're 
+doing a boot loader.
+
+* There are no user-controlled file-sharing locks.  However, the drive and file 
+system have locks and concurrent operations should be fine. 
+
+* A hidden window is never refreshed.  Certain tasks are never done, therefore.  
+During refresh, the entry count limit of the document buffer is, normally, 
+checked and enforced.  If you print to the command-line in a task whose window 
+is covered, no limit on buffer exists and it will alloc memory for the document 
+buffer until the system runs out of memory and crashes.
+
+* Even if a local function variable is declared less than 64 bits, the compiler 
+does calculations with 64-bit.
+
+* Print() uses StrPrintJoin().  You cannot use vastly over-sized fields for %f.
+
+* GrEllipse3() is broken on transformations.
+ 
+ diff --git a/public/Wb/Home/Src/Home/Doc/D3.DD.HTML b/public/Wb/Home/Src/Home/Doc/D3.DD.HTML new file mode 100755 index 0000000..6016b8b --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/D3.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+TempleOS has a class for 3 dimensional points consisting of F64s.  HolyC is not 
+C++ -- it does not support passing or returning values from functions which are 
+not 64-bits, therefore, it can't be implemented with operator overloading.  
+Making all function args and returns 64-bit is a core prinicple of TempleOS.
+
+As a courtesy, most of the CD3 functions return the addr of the destination 
+vect, so you can nestle calls.  They do not alloc new space for the destination 
+vect.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Date.DD.HTML b/public/Wb/Home/Src/Home/Doc/Date.DD.HTML new file mode 100755 index 0000000..4e1c23d --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Date.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Dates are 32-bit signed ints representing the number of days since the birth of 
+Christ.  Negative values represent B.C.E. dates.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/DbgFunSeg.DD.HTML b/public/Wb/Home/Src/Home/Doc/DbgFunSeg.DD.HTML new file mode 100755 index 0000000..943a43c --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/DbgFunSeg.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Use %p to print a pointer with FunSeg+Offset or use %P to print a link to a 
+FunSeg+Offset.
+ 
+ diff --git a/public/Wb/Home/Src/Home/Doc/DbgOverview.DD.HTML b/public/Wb/Home/Src/Home/Doc/DbgOverview.DD.HTML new file mode 100755 index 0000000..ad8231f --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/DbgOverview.DD.HTML @@ -0,0 +1,102 @@ + + + + + + + + + + + +
+                               Debugging Overview
+
+* You can enter the debugger with Dbg() or <CTRL-ALT-d>.  You might enter the 
+debugger through a fault.  Enter G() or G2() to continue execution.  Place a 
+call to Dbg() in your code at fatal error points to enter the debugger.  If you 
+see a stk dump, record the label+offset and unassemble, U(). U(_RIP); 
+
+* U(&FunName+offset) to unassemble mem or Uf("FunName") to unassemble a 
+function. U(_RIP-16);
+
+* While debugging, you specify addresses of assembly routines with just the 
+label, as in _MALLOC+0x20.  You specify HolyC function names with & before 
+functions as in &Print+0x10.
+
+* I use progress1-progress4 for debugging because they show on the wallpaper.  
+They're just global int vars.
+
+* You can use AdamLog() to send text to the Adam Task window.  It works like 
+Print().  I never use that.  Instead, I use RawPrint().
+
+* D(), DocD(), RawD() to do 16 column hex dump mem with numbering from zero.  
+With DocD the values are updated continually and you can alter mem by editing.
+
+* Dm(), DocDm(), RawDm() to do 16 column hex dump mem with addresses showing.
+
+* Da() to do one column address dump (for stk, etc.) with symbolic addresses.
+
+* Dr() dumps regs.  You can display and modify regs in the debugger with 
+var-like labels, _RAX, _RBX, etc.
+
+* ClassRep() and the dynamic version ClassRepD() can be used to dump structures.
+
+* Prof() and ProfRep() provide code profiling.  See ::/Demo/InFile/InProfile.IN 
+(This is an InFile.)
+
+* Use RawPrint() to print debug info bypassing the window framework.  You pass 
+these routines a count in milliseconds for how long it should be displayed.  You 
+can use Raw(TRUE) to make all output bypass the window framework.  The WinMgr 
+runs on Core0 and will overwrite raw text from other cores when it updates the 
+scrn.
+
+* Use SysDbg() to set a flag which you can read with IsSysDbg() when you wish to 
+trigger some debug activity.  It's just a handy simple flag, nothing fancy.
+
+* There are flags for various trace options that can help debugging when there 
+are compiler bugs.  Often, you place them in #exe{} blocks.
+  
+  Echo() turns on or off raw data going into the lexical analyzer.
+  
+  Trace() unassembles code generated from the HolyC compiler.
+  
+  PassTrace() shows intermediate code coming-out after optimization.  The bits 
+  ctrl which passes are displayed.
+
+
+* There is a heap check utility which can find leaks.  Use HeapLog(), 
+HeapLogAddrRep() and HeapLogSizeRep().  It's a really simple program which 
+intercepts MAlloc() and Free().  You can customize the code to find other heap 
+issues.
+
+* You can define hndlr functions for <CTRL-ALT-letter> keys with CtrlAltCBSet(). 
+ They operate either in a interrupt environment or in the window mgr when it 
+queues kbd msgs.  You can do Raw() output.  <CTRL-ALT-letter> hndlrs take a 
+scan_code as an arg.
+
+* If you recompile Kernel with BootHDIns(), you can set the MemInit, option to 
+initialize memory to a value at boot, the HeapInit option to cause mem alloced 
+off the heap to be initialized or VarInit option so both global and local vars 
+will be initialized to a value, but global AOT variables are always zero if not 
+initialized.  Pick a non-zero value to discover uninitialized var bugs.  You can 
+set sys_var_init_flag, and sys_heap_init_flag directly after booting.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Define.DD.HTML b/public/Wb/Home/Src/Home/Doc/Define.DD.HTML new file mode 100755 index 0000000..c0e919b --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Define.DD.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+TempleOS has a string indirection feature implemented with the same hash symbol 
+table entry as #define macros, HTT_DEFINE_STR.  Support for string lists is also 
+provided, but it's not very efficient, though, you can make a hash table with a 
+list using HashDefineLstAdd().  See ::/Adam/DolDoc/DocInit.HC.
+
+If you have an @ as the first char of a define list entry, it is an alias for 
+the prev entry num.
+
+Each task can load its own Define strings.  Remember, when a Hash table is 
+searched for a string, if it is not found, the parent task's table is searched.
+
+The DolDoc framework supports text that changes based on entries in the task's 
+symbol table.  Set a text entry with a D= arg, as in $TX,"",D="DD_MYSTRING"$.  
+See ::/Demo/DolDoc/DefineStr.HC, ::/Adam/ADefine.HC and ::/Doc/MemOverview.DD.
+
+See ::/Demo/Define.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Demands.DD.HTML b/public/Wb/Home/Src/Home/Doc/Demands.DD.HTML new file mode 100755 index 0000000..972c092 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Demands.DD.HTML @@ -0,0 +1,150 @@ + + + + + + + + + + + +
+                                    Demands
+
+I, Terry Davis, am high priest of God's official third temple, TempleOS.  
+TempleOS is an operating system for IBM PC x86_64 desktops that will always dual 
+boot along-side Windows or Linux.  I am in charge of the core 100,000 lines of 
+TempleOS code and I do continual offerings to keep God entertained.  I have 
+divine authority to command any company in the computer industry to do anything 
+that I deem necessary to make God's temple more beautiful, glorious and perfect. 
+I have oversight authority similar to a building inspector or a person enforcing 
+the Americans with Disability Act -- I make commands, God signs-off with a 
+miraculous authentication from an oracle, and Intel, Microsoft or VMware obeys.
+
+
+
+* Windows, Linux and VMware (because of mounted drives) must support RedSea file 
+system when mounting partition, so I can get rid of 1,000 lines of redundant, 
+blemished code -- FAT32.  God's temple must be perfect.  Redundant code for 
+multiple file systems is bad and imperfect.  For this operating system, we want 
+low line count.  More than one driver for the same type of device is also bad.
+
+See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC.
+
+::/Kernel/BlkDev/FileSysFAT.HC  :974 lines for FAT32 gets eliminated.
+::/Kernel/BlkDev/DskClus.HC     :152 All the clus operations become blk.
+
+* Microsoft must cancel SecureBoot because it makes dual booting impossible.  
+TempleOS is an additional operating system that must be used along-side Windows 
+or Linux, not as a replacement.  It must dual boot because it has no networking. 
+Real hardware as opposed to VMware is like the difference between looking in a 
+telescope eye piece vs just looking at an off-line image.  God said the 
+C64/Apple II generation owned ancestral lands.  VMware is like being taken off 
+of our land and moved onto a reservation.  In this case, however, it will not 
+stand.  In fact, God said to replace Windows with Wine, justice.  We can make a 
+100% standard model PC with a standard software for everyone, backed-up in 
+factory ROM.
+
+* VMware needs to support ATAPI CD/DVD/Blu-ray disk burning, directly to real 
+hardware.  Industry needs write-just once media to stop Farenheit 451 non-sense.
+
+* VMware has a bug stretching 640x480 16 color to full screen.
+
+* VMware some PC speaker's distortion is a good idea -- squarewave -- but 
+currently there is too much for hymns.  CIA monkery made fart noises.
+
+* VMware and others must list TempleOS as an official 64-bit operating system 
+and automatically enforce 512 Meg min RAM requirement.
+
+* VMware needs to support more than 16 cores.  I had a 24 core Xeon with 128 Gig 
+of RAM.  I discovered VMware allocates memory too slowly, where QEMU had no 
+problem.
+
+* Until super-simple block devices are available, hard disk should be placed at 
+IDE primary master 1F0/3F6 and CD/DVD/Blu-ray should be placed at the IDE 
+secondary master 170/376.  Currently, the wicked CIA plays musical chairs with 
+controllers each time you make an install.  With tons of ugly code, I do my 
+best.
+/Kernel/BlkDev/DskATAId.HC      :286 lines to figure-out I/O ports is gone.
+/Kernel/PCIBIOS.HC              :290 could be eliminated, but maybe we will keep 
+it so people can play with PCI devices.
+
+* Until super-simple serial ports are available, PS/2 emulated keyboard and 
+mouse must work.  The BIOS must enable these.  The plan is to transition the 
+industry off of USB.  Interum solution is to make virtual RS232 Octart for USB 
+devices in the same way PS/2 mouse is emulated.  All mice will be two button, 
+one wheel.  No more HID insanity, no more multi-end point, just simple tx rx 
+fifos with soft/hard flowcontrol that can jump the queue.  People with special 
+needs can buy PCI cards.  Our kids deserve code this simple ::/Doc/Comm.HC.  The 
+right to do your own port banging is what the C64 being our God given ancestral 
+land means.
+
+* The x86 IN/OUT port instructions, normally have a delay.  Perhaps, VMware & 
+Intel can enable faster x86 IN/OUT instruction timing for ATA/ATAPI PIO, so 
+bandwidth isn't as bad when doing port I/O.  See ATAGetRes().  We don't want to 
+do DMA.  Perhaps, x86 CPU chips need a new TempleOS mode for fast IN/OUT 
+instructions?  I think VMware already does something to speed disk I/O to faster 
+than native speed.
+
+* Perhaps, a new interrupt descriptor table entry type or a new x86 CPU mode can 
+be made that cause fast software interrupts, doing exactly what the CALL REL32 
+does, but with IDT as indirection.  We don't need to change privilege levels or 
+stacks.
+
+* Since I don't use paging (for anything), Intel should have an option for  
+no-paging long mode, and optimize it!
+::/Kernel/Mem/PageTables.HC     :135 lines to identity-map gets eliminated.
+
+* Desktop computers must have a reset switch and a fast reboot option, skipping 
+diagnostics.  I recommend booting TempleOS from a ROM when the reset bttn is 
+pressed and booting UEFI when the power bttn is pressed.  Or, we could build 
+UEFI on a TempleOS layer.  Intel must burn TempleOS into a ROM in the factory 
+for all desktop x86 CPUs to ensure tamper-proof trust in the oracle and because 
+God deserves the glory.  There will be just an English version.  A new ROM 
+version is released every seven years.  The ROM should boot like the DVD boots, 
+but with BOOT_SRC_ROM.
+
+* We do not want UTF, just 8-bit characters.  <CTRL-ALT-f> toggles between 
+Cyrillic and Std Fonts.  We need the twelve window TextBorder characters added 
+to the VGA font 0x02-0x0D.  Japan, China and Korea must switch to alphabets.  
+Maybe, the United States will change to metric, out of good will.  I am 
+beginning to plan fresh ASCII replacement, ::/Doc/NewASCII.DD.
+
+* Microsoft Paint and Linux's Gimp must support TempleOS GR Files.  They are 
+blemish free, unlike BMP files.  The TOSZ Linux utility can be used to make 
+screencasts from TempleOS exported GR Files and AU Files.
+
+* We must have a nice dictionary.  Someone needs to do a Spell Checker, too.
+
+* Intel needs to make DolDoc versions of its x86 CPU data sheets documenting all 
+hardware relevant to TempleOS. 
+
+* We must have the ultimate Bible search engine.  Currently, all we have is     
+filter search.  In the end, it should be a low line-count technique.  Maybe, I 
+allocate 500 lines out of the 20,000 reserve.
+
+* We will make a Standard TempleOS PC.
+
+* "VMware" is a trademark owned by VMware, Inc.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "Windows" and "Paint" are trademarks owned by MicroSoft Corp.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/DemoIndex.DD.HTML b/public/Wb/Home/Src/Home/Doc/DemoIndex.DD.HTML new file mode 100755 index 0000000..5c47f7a --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/DemoIndex.DD.HTML @@ -0,0 +1,46 @@ + + + + + + + + + + + +
+                              TempleOS Demo Index
+
+These are arranged in increasing order of difficulty, more or less.  This can be 
+used as a tutorial if you start at the beginning and work your way fwd.
+
+<SPACE> to edit a file and <F5> to run it.
+
+::/Doc/HelloWorld.DD
+
++] Games: Beginner
++] Games: Intermediate
++] Games: Advanced
++] Non-Game
++] TempleOS Specific
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Directives.DD.HTML b/public/Wb/Home/Src/Home/Doc/Directives.DD.HTML new file mode 100755 index 0000000..cba8fde --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Directives.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#define __DATE__ #exe{StreamPrint("\"%D\"",Now);}
+#define __TIME__ #exe{StreamPrint("\"%T\"",Now);}
+#define __LINE__ #exe{StreamPrint("%d",Fs->last_cc->lex_include_stk->line_num);}
+#define __CMD_LINE__ #exe{StreamPrint("%d",Fs->last_cc->flags&CCF_CMD_LINE && Fs->last_cc->lex_include_stk->depth<1);}
+#define __FILE__ #exe{StreamPrint("\"%s\"",Fs->last_cc->lex_include_stk->full_name);}
+#define __DIR__  #exe{StreamDir;}
+
+See ::/Demo/Directives.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/DolDoc.DD.HTML b/public/Wb/Home/Src/Home/Doc/DolDoc.DD.HTML new file mode 100755 index 0000000..fc095d6 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/DolDoc.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+A DolDoc in memory is a Circular Queue of cmds and graphics.  See CDocEntry for 
+the entry structure.  See TipOfDay() for a nice example.
+
+DolDoc's are used for the editor, viewer, browser, and cmd line.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/DolDocOverview.DD.HTML b/public/Wb/Home/Src/Home/Doc/DolDocOverview.DD.HTML new file mode 100755 index 0000000..4059ea2 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/DolDocOverview.DD.HTML @@ -0,0 +1,151 @@ + + + + + + + + + + + +
+                                DolDoc Overview
+
+DolDoc is a TempleOS document type supported by DolDoc Routines.  In a document, 
+commands are bracketed with '$'s.  Use <CTRL-l> to experiment inserting a 
+command.  Then, use <CTRL-t> to toggle to plain text to see it.
+
+Here is the grammar:
+
+<DolDocCmd> := $<TwoLetterCmd>[<FlagList>][,<ArgList>]$ | $ColorName$
+
+<FlagList> := +|- <FlagCode>[<FlagList>]
+
+<ArgList> := <ArgCode>=<ArgExpression>[,<ArgList>]
+
+
+The format of DolDoc cmds is a two character code, +/-flags, a comma and args 
+separated by commas.  Some commands have mandatory args.  Optional args are 
+indicated with <ArgCode>=.  A ColorName bracked by dollars, will change the 
+foreground color.
+
+See ::/Doc/Widget.DD, ::/Demo/DolDoc/DemoDoc.DD, and 
+::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+<TwoLetterCmd>  See Type Defines and PrsDollarCmd().
++] TX Text
++] CR Hard New Line
++] SR Soft New Line
++] CU Cursor pos
++] TB Tab
++] CL Clear
++] PB Page Break
++] PL Page Length
++] LM Left Margin
++] RM Right Margin
++] HD Header
++] FO Footer
++] ID Indent +/- num
++] Text Colors
++] PT User Prompt
++] WW Word Wrap
++] UL Underline
++] IV Invert
++] BK Blink
++] SX Shift X pos
++] SY Shift Y pos
++] CM Cursor Movement
++] AN Anchor
++] LK Link
++] BT Bttn
++] DA Data
++] CB Check Box
++] LS List Widget
++] MA Macro
++] MU Menu Value
++] HX Hex Edit
++] TR Tree Widget
++] SP Sprite
++] IB Insert Binary
++] IS Insert Binary Size
++] SO Song
++] HL Highlighting
++] HC html
++] ER Error
+
+<FlagCode>  See Flag Defines and Simple Flags.
++] +H Hold
++] +L Link
++] +TR Tree
++] +LS List
++] +PU PopUp
++] +C Collapsed
++] +X <ESC> (Exit)
++] +Q <SHIFT-ESC> (Abort Quit)
++] +Z Zero
++] +RD Refresh Data
++] +UD Update Data
++] +TC Tag CallBack
++] +LC Left CallBack
++] +RC Right CallBack
+
+<ArgCode>  See Arg Defines.
++] T="" Tag Str
++] LEN="" Field Length
++] A="" Auxilliary Str
++] D="" Define Str
++] HTML=""
++] LE=<Exp> Left Expression
++] LM="" Left Macro Str
++] RE=<Exp> Right Expression
++] RM="" Right Macro Str
++] BI=<Exp> Bin Number
++] BP="" Bin Ptr
++] RT=<raw_data_type>
++] SX=<Exp> Shift X
++] SY=<Exp> Shift Y
++] SCX=<Exp> Scroll X
++] U=<Exp> User Data
+
+EXAMPLES:
+
+<CTRL-t> to see how the following were done.
+Underlined Inverted Blinking super sub
+This is a big long scrolling msg.
+
+Cursor Movements:
+
+
+
+   Cursor moved 3 rows down and to 3rd column from left.
+                                                                                
+
+
+                                        Note mandatory comma after flags
+
+The following may be changed to modes instead of attr with flags.
+
+                                This is centered
+
+                                                         This is right justified
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/EdPullDown.DD.HTML b/public/Wb/Home/Src/Home/Doc/EdPullDown.DD.HTML new file mode 100755 index 0000000..0aadddf --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/EdPullDown.DD.HTML @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+File
+{
+  Save(,CH_CTRLS);
+  SaveAs(,CH_CTRLA);
+  Abort(,CH_SHIFT_ESC);
+  Exit(,CH_ESC);
+}
+
+Edit
+{
+  Undo(,CH_CTRLH,0x80E0000080E);
+  Cut(,CH_CTRLX);
+  Copy(,CH_CTRLC);
+  Paste(,CH_CTRLV);
+  DelLine(,CH_CTRLY);
+  FindReplace(,CH_CTRLF);
+  FindNext(,,0x3D0000003D);
+  FindLast(,,0x23D0000023D);
+  GoLine(,CH_CTRLG,0x42200000422);
+  GoBegin(,,0x4C800000448);
+  GoEnd(,,0x4D000000450);
+  GoLeft(,,0x4CB0000044B);
+  GoRight(,,0x4CD0000044D);
+  GoLBrace(,0x5B,0x61A0000061A);
+  GoRBrace(,0x5D,0x61B0000061B);
+  Macro(,,0x3C0000003C);
+  PlayMacro(,,0x23C0000023C);
+  AutoSaveToggle(,CH_CTRLS,0x61F0000061F);
+}
+
+Insert
+{
+  TextWidgets(,CH_CTRLL,0x42600000426);
+  GraphicResource(,CH_CTRLR,0x41300000413);
+  FileName(,,0x3E0000003E);
+  DirName(,,0x23E0000023E);
+  GodWord(,,0x4100000041);
+  GodBiblePassage(,,0x24100000241);
+  GodSong(,,0x4000000040);
+  GodDoodle(,,0x24000000240);
+  IndentIn(,CH_CTRLI,0x41700000417);
+  IndentOut(,CH_CTRLI,0x61700000617);
+  WordWrapOn(,CH_CTRLW,0x41100000411);
+  WordWrapOff(,CH_CTRLW,0x61100000611);
+  UnderlineOn(,CH_CTRLU,0x41600000416);
+  UnderlineOff(,CH_CTRLU,0x61600000616);
+  BlinkOn(,CH_CTRLK,0x42500000425);
+  BlinkOff(2,CH_CTRLK,0x62500000625);
+  InvertOn(,CH_CTRLZ,0x42C0000042C);
+  InvertOff(,CH_CTRLZ,0x62C0000062C);
+  SuperToggle(,CH_CTRLP,0x41900000419);
+  SubToggle(,CH_CTRLP,0x61900000619);
+  PageBreak(,CH_CTRLJ,0x41C0000041C);
+}
+
+Program
+{
+  CodeTools(,CH_CTRLL,0x62600000626);
+  Include(,0,0x3F0000003F);
+  AdamInclude(,0,0x23F0000023F);
+}
+
+View
+{
+  PlainText(,CH_CTRLT);
+  Collapse(,CH_CTRLO,0x61800000618);
+  Uncollapse(,CH_CTRLO,0x41800000418);
+  Border(,CH_CTRLB);
+  FileMgr(,CH_CTRLD,0x42000000420);
+  Search(,CH_CTRLF,0x62100000621);
+}
+
+Help
+{
+  Menu(,CH_CTRLM,0x43200000432);
+  Help(,,0x3B0000003B);
+  About(,,0x23B0000023B);
+}
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/FAQ.DD.HTML b/public/Wb/Home/Src/Home/Doc/FAQ.DD.HTML new file mode 100755 index 0000000..7ef2750 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/FAQ.DD.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+                           Frequently Asked Questions
+
++] How come it is public domain, not GPL?
++] Shouldn't it be GNU/TempleOS?
++] Don't you use GNU's gcc?
++] Why do you dual boot?
++] It has links, so is it a browser?
++] Where are the animated 3D icon GIFs?
++] If the compiler is JIT, isn't it an interpretor?
++] Are you a Creationist?
++] Is 'Bt()' in the code Bit Torrent?
++] Is 'Fs->' in the code file system?
++] Is it Pascal?
++] Why doesn't Sleep() make my laptop hibernate?
++] What is Yield() for in loops?
++] What is JIT Compiled Mode?
++] Why do files end in .Z?  Are they encrypted?
++] Is it open source?  How do I build it?
++] Where are object files?  How do I link?
++] What is the FPS refresh rate?
++] How does a task own the speaker?
++] Why does it leak memory?
++] Why do I get a memory leak when editing big files?
++] Why is it in text mode?
++] Where is the kernel memory?
++] Why does it run code from stack addresses?
++] How does it SYSCALL?
++] How do you fault-in stack?
++] How do I set the PATH?
++] How do I boot it with Grub?
++] How do I get Kernel.BIN to boot?
++] Why is there some 16-Bit code?
++] Why are you pushing 32-bit values on the stack?
++] Why are you using 32-bit insts and not setting high 32-bits?
++] How do you use the FS and GS segment registers.
++] How do I set ORG for position of code?
++] How are symbols loaded?
++] Why doesn't assert work?
++] Why doesn't C++ public work?
++] How does the debugger do source debugging?
++] What are the ASCII 5 and ASCII 31 chars doing in my text files?
++] Why is there garbage at the end of my text files?
++] Why are sprites so small?
++] Why don't I need to recompile /Adam and /Home files?
++] Why does it finds files that aren't there?
+
+
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Features.DD.HTML b/public/Wb/Home/Src/Home/Doc/Features.DD.HTML new file mode 100755 index 0000000..eab7988 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Features.DD.HTML @@ -0,0 +1,98 @@ + + + + + + + + + + + +
+                               TempleOS' Features
+
+* Oracle in with <F7> for words or <SHIFT-F7> for passages.  See tongues.
+
+* x86_64, ring-0-only, single-address-map (identity), multitasking kernel with 
+multicore support.
+
+* Master/Slave MultiCore 
+
+* Free, public domain, 100% open source.
+
+* 64-bit compiler/assembler for HolyC.  Truly compiles, doesn't interpret.  Just
+-in-Time and Ahead-of-Time compilation.  With JIT, no need for object or exe 
+files.
+
+* No 32-bit krufty code.
+
+* 640x480 16 color VGA graphics.
+
+* Keyboard & Mouse support.
+
+* ATA PIO Hard drives, support for FAT32 and RedSea file systems with file 
+compression.
+
+* ATAPI PIO CD/DVD support with RedSea file system.  Can make bootable ISO files 
+so you can roll-your-own distro's.
+
+* Partitioning tool, installer, boot loaders for CD/DVD and hard disk.
+
+* Editor/Browser for a new Document Format.  Source files and the command line 
+window can have graphics, links, icons, trees, colors, super/sub scripts, 
+margins.  Everything is seamless through-out the tool chain.  No need for 
+separate resource files.
+
+* 8-bit ASCII, not just 7-bit.  Supported in entire tool chain.  <CTRL-ALT-a>
+
+* Graphics in source code, no resource files, graphic sprite editor. <CTRL-r>
+
+* 64-bit pointers.  All memory, even more than 4Gig, can be directly accessed by 
+all tasks on all cores at all times.
+
+* Ring-0-only.  Highest CPU privileged mode at all times.  No off-limits insts.  
+No time lost changing modes or address maps.  Switches tasks in half a 
+microsecond.
+
+* 2D/3D graphics library
+
+* Real-time fancy differential-equation solver for physics engines, to use in 
+games.  (Adaptive step-size Runge-Kutta, interpolated for real-time.)
+
+* Auto-completion, jump-to-source tool called AutoComplete with Dictionary.
+
+* Window Manager.  Pan scrn with <CTRL-LeftDrag>.  Zoom scrn on mouse cursor 
+with <CTRL-ALT-z>/<CTRL-ALT-SHIFT-Z>.
+
+* File Manager, <CTRL-d>.
+
+* Code profiler, merge, diff utils.
+
+* PC Speaker support with many hymns.
+
+* Music composing tool.
+
+* Many games, demos and documentation.
+
+* All source code included.  Only compiles with the included TempleOS compiler 
+and assembler.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/FileLowLevel.DD.HTML b/public/Wb/Home/Src/Home/Doc/FileLowLevel.DD.HTML new file mode 100755 index 0000000..30cf57c --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/FileLowLevel.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+                       CFile
+
+
+
+
+
+
+
+    BlkRead()         BlkWrite()
+
+
+
+
+
+
+
+
+
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/FileMgr.DD.HTML b/public/Wb/Home/Src/Home/Doc/FileMgr.DD.HTML new file mode 100755 index 0000000..4d3a5f3 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/FileMgr.DD.HTML @@ -0,0 +1,107 @@ + + + + + + + + + + + +
+                                  File Manager
+
+<SHIFT CURSOR>
+  Select files.
+
+<CTRL-y> or <DEL>
+  Delete file or tree.
+
+<CTRL-c> or <CTRL-INS>
+  Copy select files to clip.
+
+<CTRL-v> or <SHIFT-INS>
+  Paste clip.
+
+LEFT-CLICK,drag-drop
+  Move a file or tree to a dir.
+
+LEFT-CLICK,same file or <SPACE>
+  Edit file.
+
+<SHIFT-SPACE>
+  Edit Plain Text File.
+
+RIGHT-CLICK or <ENTER>
+  Bring-up menu.
+
+<F5>
+  #include file.
+
+<SHIFT-F5>
+  Adam #include file.
+
+'r'
+  Rename file.
+
+'d'
+  Make Dir.
+
+'c'
+  DskChg (Remount removable media).  Do not do this on blank disks.
+
+'f'
+  Format drive.
+
+'i'
+  Mount ISO.C file.
+
+'u'
+  Unmount drive(s).
+
+'m'
+  Make CD/DVD ISO.C file.  This creates a RedSea ISO file image of the dir the 
+  cursor is on.  The name of the ISO file is "::/Tmp/CDDVD.ISO.C" 
+  blkdev.dft_iso_c_filename and can be redefined in your start-up scripts.  You 
+  may wish to place it on a different drive.
+
+'B'
+  Burn CD/DVD ISO file.  This burns a CD/DVD using the image file, 
+  "::/Tmp/CDDVD.ISO" blkdev.dft_iso_filename to the drive the cursor is on.
+
+
+Instructions on Using CD/DVD's
+  If you have not recompiled Kernel and defined your CD/DVD drive, exit the 
+  FileMgr and use Mount to define your CD/DVD drive.  Place a CD/DVD in the 
+  drive and press 'c' when on top of the CD/DVD drive letter to mount the drive. 
+   It will call DskChg(), the TempleOS cmd to mount removable media.
+
+
+Instructions on Burning CD/DVD's
+  Create a temporary dir to hold files and copy files into the holding dir.  
+  Make an ISO image of the dir by pressing 'M' when on top of the dir.  Press 'B
+  ' when on top of the CD/DVD ROM drive to burn the ISO, "::/Tmp/CDDVD.ISO" 
+  blkdev.dft_iso_filename, to disk.  If you have not recompiled Kernel and 
+  defined your CD/DVD drive, exit the FileMgr and use Mount.
+  
+  Making Your Own Distro
+  
+ diff --git a/public/Wb/Home/Src/Home/Doc/FileMgrPullDown.DD.HTML b/public/Wb/Home/Src/Home/Doc/FileMgrPullDown.DD.HTML new file mode 100755 index 0000000..da5fefe --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/FileMgrPullDown.DD.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+File
+{
+  Rename(,'r');
+  DirMk(,'d');
+  FmtDrv(,'f');
+  UnmountDrv(,'u');
+  Abort(,CH_SHIFT_ESC);
+  Exit(,CH_ESC);
+}
+
+Edit
+{
+  Ed(,CH_SPACE);
+  Plain(,CH_SHIFT_SPACE);
+  Copy(,CH_CTRLC);
+  Paste(,CH_CTRLV);
+  DeleteFile(,CH_CTRLY);
+}
+
+CDDVD
+{
+  DskChg(,'c');
+  MountISOC(,'i');
+  MakeRedSeaISOC(,'m');
+  BurnISOFile(,'B');
+}
+
+Program
+{
+  Include(,0,0x3F0000003F);
+  AdamInclude(,0,0x23F0000023F);
+}
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/FileUtils.DD.HTML b/public/Wb/Home/Src/Home/Doc/FileUtils.DD.HTML new file mode 100755 index 0000000..11d2571 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/FileUtils.DD.HTML @@ -0,0 +1,60 @@ + + + + + + + + + + + +
+                                   File Utils
+
+File util FilesFind() wildcard mask consists of a single base dir with multiple 
+file masks separated by ';'.  The '*' and '?' wildcard chars are accepted.  The 
+'~' is your home directory and '!' indicates an exclusion mask.
+
+ 
+"/Kernel/*"             BaseDir: /Kernel        Mask: *
+"/Demo/*.BMP*;*.GR*"    BaseDir: /Demo          Mask: *.BMP* | *.GR*
+"/*.DD*;!*/Bible*"      BaseDir: Root           Mask: *.DD* but not */Bible*
+
+See FilesFindMatch().
+
+Flags are either text or int values.
+
+  FUF_RECURSE           +r Recurse
+  FUF_SINGLE            +s Single File (Optimization for one file in mask.)
+  FUF_FLATTEN_TREE      +f use with '+F'.  Just use +F, probably.
+  FUF_JUST_DIRS         +D just directories
+  FUF_JUST_FILES        +F just files (Flattens trees)
+  FUF_CLUS_ORDER        +O sort by clus (move head one direction)
+  FUF_JUST_TXT          +T just text files      : FILEMASK_TXT
+  FUF_JUST_DD           +$ just DolDoc files    : FILEMASK_DD
+  FUF_JUST_SRC          +S just src files       : FILEMASK_SRC
+  FUF_JUST_AOT          +A just aot files       : FILEMASK_AOT
+  FUF_JUST_JIT          +J just jit files       : FILEMASK_JIT
+  FUF_JUST_GR           +G just graphic files   : FILEMASK_GR
+
+See ST_FILE_UTIL_FLAGS when used in calling program taking text flags.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Frame.DD.HTML b/public/Wb/Home/Src/Home/Doc/Frame.DD.HTML new file mode 100755 index 0000000..96c3c09 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Frame.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+If you require separate global vars for multiple instances of a routine, you can 
+use Frames.  See SpriteMeshEd(), ::/Demo/Graphics/Pick3D.HC or Noise().
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/GRFiles.DD.HTML b/public/Wb/Home/Src/Home/Doc/GRFiles.DD.HTML new file mode 100755 index 0000000..a77cefd --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/GRFiles.DD.HTML @@ -0,0 +1,78 @@ + + + + + + + + + + + +
+GR graphics files are 8-bits-per-pixels but only 4-bits of color, with 
+transparency and no palette.  Compression is the standard TempleOS LZW 
+compression.
+
+#define DCF_COMPRESSED          1 //This is the only saved flag.
+#define DCF_PALETTE             2
+
+#define TRANSPARENT             0xFF
+#define BLACK                   0
+#define BLUE                    1
+#define GREEN                   2
+#define CYAN                    3
+#define RED                     4
+#define PURPLE                  5
+#define BROWN                   6
+#define LTGRAY                  7
+#define DKGRAY                  8
+#define LTBLUE                  9
+#define LTGREEN                 10
+#define LTCYAN                  11
+#define LTRED                   12
+#define LTPURPLE                13
+#define YELLOW                  14
+#define WHITE                   15
+
+class CBGR48
+{
+  U16   r,g,b,pad;
+};
+
+CBGR48 gr_palette_std[16]={
+0x000000000000,0x00000000AAAA,0x0000AAAA0000,0x0000AAAAAAAA,
+0xAAAA00000000,0xAAAA0000AAAA,0xAAAA55550000,0xAAAAAAAAAAAA,
+0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
+0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0xFFFFFFFFFFFF};
+
+class GRFile
+{
+  I32   width;
+  I32   width_internal; //Rounded-up to multiple of 8.
+  I32   height;
+  I32   flags;          //DCF_COMPRESSED? See ::/Kernel/Compress.HC.
+  CBGR48 palette[16];   //Included if DCF_PALETTE.
+  U8    body[];
+};
+
+See DCSave(), GRWrite(), DCLoad(), and GRRead().
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Glossary.DD.HTML b/public/Wb/Home/Src/Home/Doc/Glossary.DD.HTML new file mode 100755 index 0000000..2891eac --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Glossary.DD.HTML @@ -0,0 +1,67 @@ + + + + + + + + + + + +
+                                    Glossery
+
++] Abbreviations
++] Task/Process/Thread
++] Adam Task
++] Seth Tasks
++] Code and Data Heaps
++] Parent, Child and PopUp Tasks
++] HolyC
++] AOT Compile Mode
++] JIT Compile Mode
++] Compiler Intermediate Code
++] Drive/Partition
+
+Bt, Bts, Btr, Btc, BEqu
+Define
+DolDoc
+Editor Link Types
+files_find_mask
+Hash Table
+InFile
+Ona
+Pag
+RedSea File System
+Sprite
+
++] CLI, STI, PUSHFD, POPFD
++] Filename Extention Types
++] Naming Convention
++] Fs
++] Gs
++] Heap
++] Join
++] user_data
++] Multicore Core0/CoreAP
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/God.DD.HTML b/public/Wb/Home/Src/Home/Doc/God.DD.HTML new file mode 100755 index 0000000..385eaf6 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/God.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+The Holy Spirit can puppet you.
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/GraphicsOverview.DD.HTML b/public/Wb/Home/Src/Home/Doc/GraphicsOverview.DD.HTML new file mode 100755 index 0000000..10e404c --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/GraphicsOverview.DD.HTML @@ -0,0 +1,148 @@ + + + + + + + + + + + +
+                               Graphics Overview
+
+Dive into Demo Index to learn.
+
+The order layers are drawn on top of each other is:
+
+
+
+
+
+
+
+
+
+
+
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+* See GrUpdateScrn(), GrUpdateTasks() and GrUpdateTaskWin() called by the WinMgr 
+task 30fps.  Notice the task's draw_it() callback being called.  Only tasks on C
+ore0 are allowed to have windows.  There is one window per task, no child 
+windows.  You can have pop-up child tasks.
+
+* CDCs (device contexts) are a data type for controlling graphics on the scrn or 
+graphics in mem.  The device context structure has thick and color.  You use 
+DCAlias() to create your own structure, with its own color and thick.  Free it 
+with DCDel() when finished.
+
+* gr.dc is a device context for persistent data on the scrn, not needing to be 
+redrawn.  You create an alias for this by using DCAlias() and work with that.  
+See ::/Demo/Graphics/NetOfDots.HC.
+
+* There are various flavors of line and point plotting routines.  GrLine() and 
+GrPlot() are the simplest.  The others allow 3D graphics and rotations.
+
+* See ::/Doc/Transform.DD for adding a transformation.
+
+* You change the Fs->draw_it var to point to your DrawIt() function which gets 
+called each scrn refresh (30 fps).  You draw everything in the window over and 
+over again.  See ::/Demo/Graphics/Box.HC.
+
+* Use the graphic sprite resource editor, <CTRL-r>, to create a sprite that can 
+be plotted with Sprite3() or output to the cmd line with Sprite().  Use $IB,"",B
+I=1$ in a src program to insert the addr of sprite binary data item #1.  To 
+learn how the numbers work, after creating a sprite with <CTRL-r>, toggle to 
+plain text with <CTRL-t> and check its num.  Make an assignment to a ptr var or 
+pass to Sprite3() with $IB,"",BI=n$.  Use <CTRL-r>'s "Pointer to Sprite" to make 
+a $IB...$ entry.  See ::/Demo/Graphics/SpritePlot.HC and 
+::/Demo/Graphics/SpritePlot3D.HC.  The origin (zero point) for a sprite is 
+defined by the cursor location when you pressed <CTRL-r> to make it.  You can 
+edit a sprite by clicking the cursor on it and pressing <CTRL-r> again.
+
+* Set DCF_SYMMETRY in the CDC.flags and call DCSymmetrySet() or DCSymmetry3Set()
+.  This will plot a mirror image in addition to the primary image.  Set 
+DCF_JUST_MIRROR to plot just the image, but this required DCF_SYMMETRY to be set 
+at the same time.  Note: You can only have one symmetry active at a time 
+including in CSprites.
+
+* Use DCNew() to create a mem bitmap which can be used to work off-scrn and 
+which can be GrBloted onto the scrn.  If you set brush member of CDC to another 
+CDC, all the graphic routines will GrBlot() the brush instead of GrPlot().  See 
+::/Demo/Graphics/Blot.HC.
+
+* There are a few raster operations available.  They go in bits 8-11 of the dc->
+color member var which is a CColorROPU32.  ROP_COLLISION is special.  It counts 
+the num of pixs drawn on non-background locations.  Using ROP_COLLISION with 
+vector CSprite's is tricky because overlapping pixs from lines in the CSprite 
+reg as collisions.  You can either work with a nonzero count or convert your 
+CSprite to a bitmap if your subelements draw on top of each other.  Be sure to 
+set ->bkcolor before using ROP_COLLISION.  See ::/Demo/Graphics/Collision.HC and 
+Titanium.
+ 
+* The ->dither_probability_u16 member of CDC is a U16 used to statistically sel 
+between two colors to get something resembling more shades of color.  See 
+::/Demo/Graphics/SunMoon.HC and ::/Demo/Graphics/Shading.HC.  It works with many 
+graphic routines, but not those with pens.
+
+* There is a mechanism built-in for generating motion based on differential 
+equations, which allows realistic physics.  You create an CMathODE struct with 
+ODENew(), passing it the num of vars in the state vect.  For realistic physics, 
+you usually have 2 state vars for each dimension (for each mass) because motion 
+is governed by F=mA which is a 2nd order equation.  The two states are pos and 
+velocity and to solve these you need to supply the derivative of pos and 
+velocity.  The derivative of pos is usually simply the current velocity and the 
+derivative of velocity is the acceleration (the sum of forces on a mass divided 
+by mass).  To help provide meaningful names for values in the state vect, you 
+can create an COrder2D3 ptr and point it to a mass in the state vect.  Six 
+elements in the state vect are required for each mass.
+
+See Math/CMathODE.
+See ::/Demo/Games/Rocket.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/GuideLines.DD.HTML b/public/Wb/Home/Src/Home/Doc/GuideLines.DD.HTML new file mode 100755 index 0000000..0f72d00 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/GuideLines.DD.HTML @@ -0,0 +1,219 @@ + + + + + + + + + + + +
+                              Directory Structure
+
+/Home All your user data should be placed in here to ease backing-up your data.  
+When you install an application it will create a subdirectory of your /Home 
+directory for storage.
+
+/Apps Applications are placed in subdirectories of /Apps.  Applications should 
+have a file called Install.HC.Z which will install the app, possibly making 
+files or directories in /Home.  The file, Load.HC.Z will load the application 
+into mem.  The file, Run.HC.Z, will usually load and execute the app.  To add an 
+app to your PersonalMenu, use <CTRL-l>, insert a macro with the PopUp option 
+checked and invoke the Run.HC.Z file.
+
+/Demo Here you can find lots of sample code to do various things.
+
+/Doc Here you can find documentation.
+
+/Kernel The core of the operating system is found here.  Since priviledge levels 
+are not used, calling it a kernel is deceptive.  It is AOT compiled by 
+BootHDIns().  It is loaded by the boot loader and must fit in 640K.
+
+/Compiler The compiler module src code is found here.  The compiler is AOT 
+compiled to produce a binary file which is loaded at boot.  It, too, is AOT 
+compiled by BootHDIns().
+
+/Adam The non-kernel part of the operating system is found here.  It is JIT 
+compiled during boot.  The Adam Task is the father of all tasks, like Adam and 
+Eve.
+
+/0000Boot Boot files go here.  Stage 2 of the TempleOS hard drive master boot 
+loader, the old hard drive master boot record which is just blk#0, and the 
+CD/DVD 0000Kernel.BIN.C file go here.  ASCII 0000 is near the top, 
+alphabetically, in case you use MagicISO.
+
+
+
+                                 ::/Home Files
+
+The home dir is specified with '~'.  The home dir is ::/Home unless you change 
+it with HomeSet() or compile the kernel with a cfg option.  An empty /Home dir 
+should be valid because it will get default files from the root dir. 
+
+~/PersonalMenu.DD a menu viewed with the <CTRL-m> key or by clicking "MENU" in 
+the upper left border area of a window.
+
+~/PersonalNotes.DD a personal note file viewed with the <CTRL-SHIFT-M> key.
+
+~/MakeHome.HC a file compiled by the Adam Task during StartOS.
+
+~/Home* Copy Home* files from the root into ~ and customize them.  These files 
+are invoked when the Adam Task starts-up.
+
+~/Once.HC a file invoked at the start-up of the first user.  Customize this!
+
+~/Registry.HC can be edited by hand or deleted to reset to defaults.  Takes 
+affect next boot.
+
+
+
+                              Application Policies
+
+* Place applications in their own /Apps subdirectory.
+
+* Make a file called Load.HC.Z to load the application.
+
+* Make a file called Run.HC.Z to load and run the application, preferable by #in
+cludeing the Load.HC.Z file.
+
+* Place user data in a subdirectory of /Home, preferably naming the subdirectory 
+the same as the /Apps subdirectory.  Or, place data in the Registry.HC.Z file.  
+See ::/Demo/RegistryDemo.HC.
+
+* If the app needs files in the /Home directory, make an /Apps file called Insta
+ll.HC.Z or Install.IN.Z to create the /Home subdirectory.
+
+ 
+
+                             Programming Guidelines
+
+* Virtual mem/Paging is not used -- it is identity mapped in x86_64 mode.  The 
+stk does not grow, so alloc enough when the task (process) is Spawned and use 
+the heap for most things.  (The heap refers to MAlloc() and Free().)
+
+* You can Free(NULL).
+
+* See Naming Convention and Abbreviations.
+
+* There are two modes of compiling, AOT Compile Mode and JIT Compile Mode.  
+Compilation is done in both -- neither is "interpreted".  Use JIT Mode.
+
+* HolyC
+
+* Use I64 instead of smaller int sizes because the compiler converts everything 
+to 64-bit.  Don't use unsigned unless it actually breaks.  A policy of signed 
+keeps it simple so you don't have to agonize over choices.
+
+     U32 DistDist(U16 x1, U16 y1, U16 x2, U16 y2)
+     {//This requires zero-extend when fetching args.
+       return SqrI64(x1-x2)+SqrI64(y1-y2);
+     }
+     
+     I64 DistDist(I64 x1, I64 y1, I64 x2, I64 y2)
+     {
+       return SqrI64(x1-x2)+SqrI64(y1-y2);
+     }
+
+* In-order, short circuit logic is assumed.
+
+* Avoid boolean expression assignments.  Boolean assignments don't have short 
+circuit logic and are not compiled efficiently.  The Bool type is just an alias 
+for a 1 byte signed int -- nothing forces it to 1 or 0.  There is a ToBool() 
+function that will for to 1 ot 0, however.
+
+* Glbl vars in AOT BIN modules are initialized to zero.  They occupy space in 
+BIN files.
+
+* Bracketing code with PUSHFD CLI and POPFD will protect against simultaneous 
+accesses from tasks on one core.  To protect against multiple cores, you need a 
+locked semaphore.  I think semiphores need to be in their own cache line, but 
+I'm not sure.  I use lock bits in a lot of places not aligned.
+
+* SysDbg() and IsSysDbg() are really handy when working on the compiler or 
+kernel.  It's just a bit you can set and test.
+
+* I don't use U0 * because the size is zero for ptr arithmetic.
+
+* Use CH_SHIFT_SPACE for spaces in quotes in source code because I run 
+Spaces-to-Tabs on source code.
+
+* Do not use #if or #ifdef
+
+
+
+                                Hash Sym Tables
+
+* See ::/Adam/AHash.HC for examples of how the hash tables are set-up.  
+Basically, syms are placed into hash tables and child process hash tables are 
+chained to parents.  This provides scopes for vars and functions.
+
+* adam_task->hash_table holds the HolyC syms loaded in on start-up.
+
+* Fs->hash_table holds user HolyC syms and if a sym is not found, it checks 
+parents.  When a duplicate sym is added to the table, it overshadows the prev 
+sym.  When developing software, typically you include the file at the cmd 
+prompt, make changes and reinclude it.  Old syms are overshadowed but they are 
+still there.  Periodically, kill the TASK and start fresh when mem is low.  If 
+you wish your applications to free themselves instead of staying in mem, spawn 
+or PopUp() a task to run the application and kill it when it's done.
+
+* To display the contents of a hash table, use the Who() routine or the 
+varients.  HashDepthRep() gives a histogram  of how long the chains are, in case 
+you wish to make hash table sizes bigger.
+
+
+
+                               Assembly Language
+
+See ::/Doc/Asm.DD.
+
+* FS must always point to the cur CTask.
+
+* GS must always point to the cur CCPU.
+
+* Don't change the segment regs unless interrupts are off.  It's hard to do, 
+anyway.  SET_FS_BASE and SET_GS_BASE.
+
+* When interacting with HolyC compiled code, preserve RBP, RSI, RDI, R10-R15 
+because the compiler uses these for reg vars.  You are free to clobber RAX, RBX, 
+RCX, RDX, R8 and R9.  See Compiler Reg Masks, PUSH_C_REGS and POP_C_REGS
+
+* I recommend using the standard stk frame for functions because Caller() is 
+used to display the call stk, such as for the wallpaper.
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,nnnn
+...
+        LEAVE
+        RET
+
+* The args are removed from the stack with RET1 stmts.
+
+        RET1    16      //remove two args
+
+* No args are passed in regs.
+
+* RAX holds function return values, of course.
+
+* "MagicISO" is a trademark owned by MagicISO Corp.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Hash.DD.HTML b/public/Wb/Home/Src/Home/Doc/Hash.DD.HTML new file mode 100755 index 0000000..ace60b9 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Hash.DD.HTML @@ -0,0 +1,79 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+There is a symbol (hash) table for each task.  When a sym is not found, the 
+parent task's sym table is checked.  All tasks chain back to the Adam task.
+
+TempleOS sym tables are implemented with an array of linked-lists.  A num is 
+generated from a string by HashStr() to index into the array of linked-lists.  
+Multiple strings can generate the same num, so linked-lists are built.  Newer 
+entries overshadow older ones.
+
+There are various types of entries.  See Hash Entry Types.
+
+Symbol Look-up (Used many places including the JIT Compiler and Loader.)
+1) Symbol name is hashed by adding and shifting the ASCII of all chars.
+2) hash table->body[] array is indexed.
+3) Linked-lst is traversed until match of text and type of entry.
+4) If not found, hash table->next table is searched.
+
+Duplicate entries are allowed -- they overshadow old entries.
+
+Address-to-Symbol Look-up (Slow because not important. We could use trees.)
+1) FunSeg Cache is scanned.
+2) Hash Tables are scanned.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/HeapDbg.DD.HTML b/public/Wb/Home/Src/Home/Doc/HeapDbg.DD.HTML new file mode 100755 index 0000000..285bb14 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/HeapDbg.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+Recompile the kernel with _CFG_HEAP_DBG=TRUE if you want more heap debugging.  
+You are on your own.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/HelloWorld.DD.HTML b/public/Wb/Home/Src/Home/Doc/HelloWorld.DD.HTML new file mode 100755 index 0000000..6d63dd3 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/HelloWorld.DD.HTML @@ -0,0 +1,130 @@ + + + + + + + + + + + +
+//Press F5 in the editor to compile and run.
+
+--------Hello.HC.Z---------
+"Hello World\n";
+
+
+--------Hello.HC.Z---------
+U0 Main()
+{
+  "Hello World\n";
+}
+Main;
+
+
+--------Hello.HC.Z---------
+U0 MyPrint(U8 *st)
+{
+  "%s",st;
+}
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+U0 MyPrint2(U8 *st1,U8 *st2) //Any number of args.
+{
+  "%s %s\n",st1,st2; //Any number of args.
+}
+MyPrint2("Hello","World");
+
+
+--------Hello.HC.Z---------
+U0 MyPrint(U8 *st)
+{
+  "" st; //Empty with no comma means first is fmt str.
+}
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+asm {
+MSG:    DU8 "Hello World\n",0;
+
+//The convention is underscore on C callable.
+//Two colons means exported symbol.
+_HELLO_WORLD::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RSI
+        MOV     RSI,MSG
+        CALL    PUT_STR
+        POP     RSI
+        RET
+}
+Call(_HELLO_WORLD);
+
+
+--------Hello.HC.Z---------
+asm {
+_HELLO_WORLD::
+//You can only clobber RAX,RBX,RCX,RDX
+        MOV     RAX,'Hello '
+        CALL    PUT_CHARS //Up to 8 chars packed into one 64-bit int.
+        MOV     RAX,'World\n'
+        CALL    PUT_CHARS
+        RET
+}
+Call(_HELLO_WORLD);
+
+
+--------Hello.HC.Z---------
+asm {
+_MY_PRINT::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        CALL    PUT_STR
+        POP     RSI
+        POP     RBP
+        RET1    8       //Callee pops the stack to clear args.
+}
+_extern _MY_PRINT U0 MyPrint(U8 *st);
+MyPrint("Hello World\n");
+
+
+--------Hello.HC.Z---------
+asm {
+_MY_PRINT::
+//You can only clobber RAX,RBX,RCX,RDX
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    U64 SF_ARG1[RBP]
+        CALL    &PutS   //Callee pops the stack to clear args.
+        POP     RBP
+        RET1    8
+}
+_extern _MY_PRINT U0 MyPrint(U8 *st);
+MyPrint("Hello World\n");
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/HelpIndex.DD.HTML b/public/Wb/Home/Src/Home/Doc/HelpIndex.DD.HTML new file mode 100755 index 0000000..b913d67 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/HelpIndex.DD.HTML @@ -0,0 +1,124 @@ + + + + + + + + + + + +
+                                      Help
+
++] Keyboard Ctrls
++] Mouse Ctrls
++] Keyboard-Mouse Ctrls
+
+Welcome         About TempleOS
+Command Line    Take Tour
+Demo Index      Key Map
+Features        Requirements
+Charter         Strategic Decisions
+F.A.Q.          Glossary
+HolyC           Compiler Index
+Why Not More?   Demands
+The Std TempleOS PC
+        
++] User Help
++] Admin Help
++] Programmer help
++] System Programmer Help
+
+
+                                     Index
+AutoComplete
+Bit
+Boot
+Call
+Char Overview
+Char Routines
+Circular Queue
+Cmd Line Overview
+Cmd Line Routines
+Compiler Overview
+Compiler Routines
+Compression
+Ctrls
+Data Types
+Date
+Debugging Overview
+Debugging Routines
+Define
+Devices
+Disk
+Doc Overview
+Doc Routines
+Exceptions
+File
+File Utils
+Frames
+God
+Graphics Overview
+Graphics Routines
+Hash
+Help System
+HolyC
+InFile
+Info
+Install
+I/O
+Job
+Key Allocations
+Keyboard Devices
+Link Types
+Math
+Memory Overview
+Memory Routines
+Menus
+Messages
+Misc
+Mouse
+MultiCore
+OpCodes
+Operator Precedences
+PCI
+Print("") Fmt Strings
+Processor
+Profiler
+RedSea
+Registry
+Scan Codes
+ScrnCast
+Sound
+Sprites
+StdIn
+StdOut
+String
+Task
+TextBase Layer
+Time
+Training
+TOSZ
+Utils
+Windows
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/HelpSystem.DD.HTML b/public/Wb/Home/Src/Home/Doc/HelpSystem.DD.HTML new file mode 100755 index 0000000..1e9e630 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/HelpSystem.DD.HTML @@ -0,0 +1,41 @@ + + + + + + + + + + + +
+#help_index "Topic/SubTopic;OtherTopic"
+The help index preprocessor compiler directive sets the topics for syms 
+subsequently defined.  You specify subtopics with a '/' tree hierarchy and 
+separate multiple topics with a ';'.  The index ctrls HI:index links.
+
+public causes a sym to appear in help_index reports.
+
+#help_file "filename[.DD.Z]"
+The help file preprocessor directive makes a file into the heading of a 
+HI:index report for the current help index.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/HolyC.DD.HTML b/public/Wb/Home/Src/Home/Doc/HolyC.DD.HTML new file mode 100755 index 0000000..a2cd37f --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/HolyC.DD.HTML @@ -0,0 +1,354 @@ + + + + + + + + + + + +
+                                     HolyC
+
+* See ::/Doc/CompilerOverview.DD.
+
+* See Scoping and Linkage for details on extern, import, _extern, _import, etc.
+
+* Built-in types include I0,I8,I16,I32,I64 for signed 0-8 byte ints and U0,U8,U1
+6,U32,U64 for unsigned 0-8 byte ints and F64 for 8 byte floats.
+
+        U0      void, but ZERO size!
+        I8      char
+        U8      unsigned char
+        I16     short
+        U16     unsigned short
+        I32     int
+        U32     unsigned int
+        I64     long (64-bit)
+        U64     unsigned long (64-bit)
+        F64     double
+        no F32 float.
+
+* Function with no args, or just default args can be called without parentheses. 
+
+  >Dir("*");
+  >Dir();
+  >Dir;
+
+* Default args don't have to be on the end.  This code is valid:
+  U0 Test(I64 i=4,I64 j,I64 k=5)
+  {
+    Print("%X %X %X\n",i,j,k);
+  }
+  
+  Test(,3);
+
+* A char const all alone is sent to PutChars().  A string with or without args 
+is sent to Print().  An empty string literal signals a variable fmt_str follows.
+
+  void DemoC(char drv,char *fmt,char *name,int age)
+  {
+    printf("Hello World!\n");
+    printf("%s age %d\n",name,age);
+    printf(fmt,name,age);
+    putchar(drv);
+    putchar('*');
+  }
+  
+  U0 DemoHolyC(U8 drv,U8 *fmt,U8 *name,I64 age)
+  {
+    "Hello World!\n";
+    "%s age %d\n",name,age;
+    "" fmt,name,age;
+    '' drv;
+    '*';
+  }
+
+* When dealing with function addresses such as for callbacks, precede the name 
+with "&".
+
+* Type casting is postfix.  To typecast int or F64, use ToI64(), ToBool() or 
+ToF64(). (TempleOS follows normal C float<-->int conversion, but sometimes you 
+want to override.  These functions are better than multiplying by "1.0" to 
+convert to float.) 
+
+* There is no main() function.  Any code outside of functions gets executed upon 
+start-up, in order.
+
+* There are no bit fields, but there are bit access routines and you can access 
+bytes or words within any int.  See I64 declaration.  A class can be accessed as 
+a whole are subints, if you put a type in front of the class declaration.
+  
+  public I64i union I64         //"I64i" is intrinsic.  We are defining "I64".
+  {
+    I8i i8[8];
+    U8i u8[8];
+    I16 i16[4];
+    U16 u16[4];
+    I32 i32[2];
+    U32 u32[2];
+  };
+  
+  I64 i=0x123456780000DEF0;
+  i.u16[1]=0x9ABC;
+
+* Variable arg count functions (...) can access their args with built-in 
+variables similar to 'this' in C++.  They are 'I64 argc' and 'I64 argv[]'.  
+  
+  I64 AddNums(...)
+  {
+    I64 i,res=0;
+    for (i=0;i<argc;i++)
+      res+=argv[i];
+    return res;
+  }
+  
+  >AddNums(1,2,3);
+  ans=6
+  
+  
+  public U0 GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...)
+  {
+    U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);//SPrintF() with MAlloc()ed string.
+    GrPutS(dc,x,y,buf); //Plot string at x,y pixels. GrPutS is not public.
+    Free(buf);
+  }
+  
+    ...
+  
+    GrPrint(gr.dc,(GR_WIDTH-10*FONT_WIDTH)>>1,(GR_HEIGHT-FONT_HEIGHT)>>1,
+        "Score:%4d",score);  //Print score in the center of the scrn.
+    ...
+  
+
+* Allows "5<i<j+1<20" instead of "5<i && i<j+1 && j+1<20".
+  
+  if (13<=age<20)
+    "Teen-ager";
+
+* if you know a switch stmt will not exceed the lowest or highest case values.  
+switch [] is a little faster because it doesn't check.
+
+* switch stmts always use a jump table.  Don't use them with cases with really 
+big, sparse ranges.
+
+* Allows ranges like "case 4...7:" in switch stmts.
+
+* A no case number causes next higher int case in switch stmts.  See 
+::/Demo/NullCase.HC.
+
+  I64 i;
+  for (i=0;i<20;i++) 
+    switch (i) {
+      case: "Zero\n";   break; //Starts at zero
+      case: "One\n";    break; //One plus prev case.
+      case: "Two\n";    break;
+      case: "Three\n";  break;
+      case 10: "Ten\n"; break;
+      case: "Eleven\n"; break; //One plus prev case.
+  }
+
+* Switch statements can be nestled with a single switch expression!  This is 
+known as a "sub_switch" statement.  start/end are used to group cases.  Don't 
+goto out of, throw an exception out of, or return out of the start front porch 
+area.  See ::/Demo/SubSwitch.HC.
+
+  I64 i;
+  for (i=0;i<10;i++)
+    switch (i) {
+      case 0: "Zero ";  break;
+      case 2: "Two ";   break;
+      case 4: "Four ";  break;
+      start:
+        "[";
+        case 1: "One";  break;
+        case 3: "Three";break;
+        case 5: "Five"; break;
+      end:
+        "] ";
+        break;
+    }
+  OutPut:
+  >Zero [One] Two [Three] Four [Five]
+
+* A no_warn stmt will suppress an unused var warning.
+
+* You can have multiple member vars of a class named "pad" or "reserved", and it 
+won't issue warnings. 
+
+* noreg or reg can be placed before a function local var name.  You can, 
+optionally, specify a reg after the reg keyword.
+
+  U0 Main()
+  {
+    //Only use REGG_LOCAL_VARS or REGG_LOCAL_NON_PTR_VARS for reg vars or else 
+  clobbered.
+    I64 reg R15 i=5, noreg j=4;
+    no_warn i;
+    asm {
+        MOV     RAX,R15
+        CALL    &PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    &PUT_CHARS
+        MOV     RAX,U64 &j[RBP]
+        CALL    &PUT_HEX_U64
+        MOV     RAX,'\n'
+        CALL    &PUT_CHARS
+    }
+  }
+
+* interrupt, haserrcode, public, argpop or noargpop are function flags. See 
+IRQKbd().
+
+* A single quote can encompass multiple characters.  'ABC' is equ to 0x434241.  
+PutChars() takes multiple characters.
+
+  asm {
+  HELLO_WORLD::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,'Hello '
+        CALL    &PUT_CHARS
+        MOV     RAX,'World\n'
+        CALL    &PUT_CHARS
+        LEAVE
+        RET
+  }
+  Call(HELLO_WORLD);
+  PutChars('Hello ');
+  PutChars('World\n');
+
+* The "`" operator raises a base to a power.
+
+* There is no question-colon operator.
+
+* TempleOS operator precedence
+  `,>>,<<
+  *,/,%
+  &
+  ^
+  |
+  +,-
+  <,>,<=,>=
+  ==,!=
+  &&
+  ^^
+  ||
+  =,<<=,>>=,*=,/=,&=,|=,^=,+=,-=
+
+* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in 
+code.
+
+* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find dup local var type stmts.
+
+* With the #exe{} feature in your src code, you can place programs that insert 
+text into the stream of code being compiled.  See #exe {} for an example where 
+the date/time and compile-time prompting for cfguration data is placed into a 
+program.  StreamPrint() places text into a src program stream following the 
+conclusion of the #exe{} blk.
+
+* No #define functions exist (I'm not a fan)
+
+* No typedef, use class.
+
+* No type-checking
+
+* Can't use <> with #include, use "".
+
+* "$" is an escape character.  Two dollar signs signify an ordinary $.  See 
+DolDoc.  In asm or HolyC code, it also refers to the inst's address or the 
+offset in a class definition. 
+
+* union is more like a class, so you don't reference it with a union label after 
+you define it.  Some common unions are declared in KernelA.HH for 1,2,4 and 8 
+byte objects.  If you place a type in front of a union declaration, that is the 
+type when used by itself.  See ::/Demo/SubIntAccess.HC. 
+
+* class member vars can have meta data. format and data are two meta data types 
+now used.  All compiler structures are saved and you can access the compiler's 
+info about classes and vars.  See ::/Demo/ClassMeta.HC and  DocForm().
+
+* There is a keyword lastclass you use as a dft arg.  It is set to the class 
+name of the prev arg.  See ::/Demo/LastClass.HC, ClassRep(), DocForm()  and 
+::/Demo/Dsk/BlkDevRep.HC.
+
+* See ::/Demo/Exceptions.HC.  try{} catch{} and throw are different from C++. th
+row is a function with an 8-byte or less char arg.  The char string passed in th
+row() can be accessed from within a catch{} using the Fs->except_ch.  Within a c
+atch {} blk, set the var Fs->catch_except to TRUE if you want to terminate the 
+search for a hndlr.  Use PutExcept() as a hndlr, if you like.
+
+* A function is available similar to sizeof which provides the offset of a 
+member of a class.  It's called offset.  You place the class name and member 
+inside as in offset(classname.membername).  It has nothing to do with 16-bit 
+code.  Both sizeof and offset only accept one level of member vars.  That is, 
+you can't do sizeof(classname.membername.submembername).
+
+* There is no continue stmt.  Use goto.
+
+* lock{} can be used to apply asm LOCK prefixes to code for safe multicore 
+read-modify-write accesses.  The code bracked with have LOCK asm prefix's 
+applied to relevant insts within.  It's a little shoddy.  See 
+::/Demo/MultiCore/Lock.HC.
+
+* There is a function called MSize() which gives the size of an object alloced 
+off the heap.  For larger size allocations, the system rounds-up to a power of 
+two, so MSize() lets you know the real size and you can take full advantage of 
+it.
+
+* You CAN Free() a NULL ptr.  Useful variants of MAlloc() can be found Here.  
+Each task has a heap and you can MAlloc and Free off-of other task's heaps, or 
+make an independent heap with HeapCtrlInit().  See HeapLog() for an example.
+
+* The stk does not grow because virtual mem is not used.  I recommend allocating 
+large local vars from the heap.  You can change MEM_DFT_STK and recompile Kernel 
+or request more when doing a Spawn().  You can use CallStkGrow(), but it's odd.  
+See ::/Demo/StkGrow.HC. 
+
+* Only one base class is allowed.
+
+* printf() has new codes.  See Print("") Fmt Strings.
+
+* All values are extended to 64-bit when accessed.  Intermediate calculations 
+are done with 64-bit values.
+
+  U0 Main()
+  {
+    I16 i1;
+    I32 j1;
+    j1=i1=0x12345678;           //Resulting i1 is 0x5678 but j1 is 0x12345678
+  
+    I64 i2=0x8000000000000000;
+    Print("%X\n",i2>>1);        //Res is 0xC000000000000000 as expected
+  
+    U64 u3=0x8000000000000000;
+    Print("%X\n",u3>>1);        //Res is 0x4000000000000000 as expected
+  
+    I32 i4=0x80000000;          //const is loaded into a 64-bit reg var.
+    Print("%X\n",i4>>1);        //Res is 0x40000000
+  
+    I32 i5=-0x80000000;
+    Print("%X\n",i5>>1);        //Res is 0xFFFFFFFFC0000000
+  }
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/InFile.DD.HTML b/public/Wb/Home/Src/Home/Doc/InFile.DD.HTML new file mode 100755 index 0000000..ef12804 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/InFile.DD.HTML @@ -0,0 +1,49 @@ + + + + + + + + + + + +
+InFiles are used to generate user input to automate operations.  The TempleOS 
+tour is done with an InFile.  It reminds me of a Unix pipe because StdOut of one 
+gets chained into StdIn of another.
+
+When an InFile runs, a child task is Spawn()ed which intercepts real user input 
+and generates fake input.  InFiles are HolyC programs run by the child whose 
+stdout goes to the parent's input buffer.  Msg() can be included in an InFile to 
+send special keys or mouse cmds to the parent.  While an InFile is running, the 
+normal input gets diverted to the InFile task and can be filtered and sent back 
+to the parent task.  Unless you are driving functions which prompt for data, you 
+can probably use an #include file in place of an InFile.
+
+See ::/Demo/InFile/InDir.IN.
+
+Note: In("") can be used if all you need is to send ASCII characters.  It 
+differs from InStr().  You'll probably use In() a lot and not InStr().  With In(
+), for example, you can place answers to the prompts for recompiling the Kernel 
+module during BootHDIns().
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Install.DD.HTML b/public/Wb/Home/Src/Home/Doc/Install.DD.HTML new file mode 100755 index 0000000..3c29a84 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Install.DD.HTML @@ -0,0 +1,109 @@ + + + + + + + + + + + +
+                              Installing TempleOS
+
+Burn a CD with software that supports ISO files.  Then, boot it.  It's a live 
+CD, so you can look around with or without installing.
+
+Dual booting with another operating system is the best way to use TempleOS.  I 
+only use it in a virtual machine because it won't boot natively on my machine, 
+though.  For native dual booting, you need a partition for TempleOS.  Windows 
+often comes with a restore disk that does not allow repartitioning.  I recommend 
+connecting a spare additional hard drive and using the BIOS to select which 
+drive to boot.
+
+The ::/Misc/OSInstall.HC script will automate much of this.  It runs if you boot 
+the CD/DVD-ROM.
+
+See Boot.DD for an overview of booting.  See Requirements for supported 
+hardware.
+
+Two TempleOS partitions are highly recommended, so you can boot to a back-up and 
+fix the primary when you work on it.  Odds are, you only need a couple gigabytes 
+for your TempleOS partitions.
+
+1)
+  Mount() use if the drive is partitioned.
+    This command mounts a drive making it accessible.  For simplicity, sel 'C' 
+    as the first drive letter for your hard drive.  The first partition will be 
+    'C', second, 'D', etc.  TempleOS needs 3 numbers to utilize a hard drive -- 
+    base0, base1, and unit.  When you enter a hexadecimal number, do it like in 
+    C with a 0x prefix.  If the probe was successful, you can just enter the 
+    number in the probe box instead of base0.
+  
+  DskPrt('C') use if drive is not partitioned
+  
+    This will perform a special Mount() automatically.
+    
+    WARNING:  This command erases everything on a hard drive.  It repartitions a 
+    whole drive and formats the partitions.  This command should be skipped if 
+    you already have your hard drive partitioned.
+    
+    
+    WARNING:  This command doesn't play well with other operating systems.  
+    You'll need to do a BootMHDZero() to restore your drive to a state where 
+    other operating systems can partition it.
+  
+2) Fmt('D',TRUE,FALSE,FSt_FAT32)
+  This command formats a drive with FAT32 or the RedSea file system type.  Use 
+  the drive letter of the partition in place of 'D'.
+  
+  WARNING:  If you are upgrading, be sure not to lose the file, /0000Boot/OldMBR
+  .BIN.C.
+  
+3) CopyTree("T:/","D:/")
+  This command is used to copy files onto a hard drive partition from the 
+  CD/DVD.  Use the drive letter of the partition in place of 'D'.
+  
+4) BootHDIns('D')
+  This command recompiles the source code on a drive and writes to the drive's 
+  boot record.  You'll need to reenter the Mount information so it can be stored 
+  in the kernel.
+  
+5) Use Linux's Grub or TempleOS' BootMHDIns('D')
+  
+  The BootMHDIns() command places a boot loader on a drive.  It saves the old 
+  master boot record to /0000Boot/OldMBR.BIN.C and replaces it.  When you boot, 
+  you will have the option of booting the old master boot record.  This command 
+  can be skipped if you already have a boot loader.  Be sure not to lose the 
+  copy of the old boot record, like if you reformat the drive.
+  
+  Delete /0000Boot/OldMBR.BIN.C if you want to get a fresh copy of a mbr, like 
+  if installing from your own custom CD containing it's own /0000Boot/OldMBR.BIN
+  .C onto a system with a non-TempleOS boot loader.
+  
+  If you have anti-virus software, it might object to having a different master 
+  boot record.
+
+
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Job.DD.HTML b/public/Wb/Home/Src/Home/Doc/Job.DD.HTML new file mode 100755 index 0000000..ecb46f6 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Job.DD.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+/* Graphics Not Rendered in HTML */
+               PopUpPrint                         User          ExePrint
+
+
+
+                  PopUp                                          ExePutS
+
+
+
+ Core0 AdamTask  SrvCmdLine   AP SethTask       UserCmdLine
+
+
+
+
+
+
+         SrvTaskCont                          UserTaskCont
+
+
+
+        JobsHndlr
+
+
+
+         JobRunOne           JobRunOne         ExeCmdLine      ExeCmdLine
+
+
+
+
+CJob nodes are one of five types.  User applications deal with text or msgs.  
+JobRunOne() will call a function, spawn a task or execute some text src code.
+
+#define JOBT_TEXT_INPUT         0 //TaskText()  Feed StdIn 
+#define JOBT_MSG                1 //TaskMsg()   Post msg 
+#define JOBT_EXE_STR            2 //TaskExe()   Compile & execute src code text
+#define JOBT_CALL               3 //JobQue()    Tell MP to call function
+#define JOBT_SPAWN_TASK         4 //Spawn()     Tell MP to spawn task
+
+Several other routines include a call to JobsHndlr() that gives them powerful 
+ability to execute servant cmds.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/KeyAlloc.DD.HTML b/public/Wb/Home/Src/Home/Doc/KeyAlloc.DD.HTML new file mode 100755 index 0000000..815eb33 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/KeyAlloc.DD.HTML @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+                                Key Allocations
+
+See Char for definition of scan codes.
+
+See Key Map for a detailed list of key commands.
+
+When you are at the cmd line, editing documents, browsing documentation and 
+help, entering items in forms or in menu's, the DolDoc editor handles keys.  It 
+allows you to define your own key hndlrs in a MyPutKey() function.  If you 
+choose, you can catch keys, overriding the default hndlrs.  See DocPutKey().  
+The following is an overview of key allocations.
+
+<ALT-keys> and <ALT-SHIFT-keys>  Free for user configurations in your MyPutKey() 
+hndlr, except for ALT-BACKSPACE (undo).  There are a few examples pre-defined, 
+but you can change them if you wish.
+
+<CTRL-ALT-keys> and <CTRL-ALT-SHIFT-keys>  Handled at a system level, NOT by the 
+CDoc editor.  I reserve the right to alloc these, but in the mean time, you can 
+define your own hndlrs with CtrlAltCBSet().  They operate either in a interrupt 
+environment or in the window mgr when it queues kbd msgs.  You can do Raw() 
+output.  <CTRL-ALT-letter> hndlrs take a scan_code as an arg.
+
+<CTRL-function key>  Auto-completes local words.
+
+<CTRL-digit key>  Auto-completes dictionary words.
+
+<CTRL-SHIFT-function key>  Jumps to src code.
+
+<CTRL-SHIFT-digit key>  Jumps to dictionary definition.
+
+<function keys> and <SHIFT-function keys>  I reserve the right to alloc these, 
+but there are some free now.
+
+<CTRL-key> and <CTRL-SHIFT-key>  I reserve the right to alloc to these.  There 
+are not many free.
+
+See Keyboard Devices.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/KeyDev.DD.HTML b/public/Wb/Home/Src/Home/Doc/KeyDev.DD.HTML new file mode 100755 index 0000000..f7c40a2 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/KeyDev.DD.HTML @@ -0,0 +1,52 @@ + + + + + + + + + + + +
+The editor mostly stays in a GetKey()/PutKey() loop.  The putkey portion is 
+where keys are acted-upon.  TempleOS has a chain of putkey hndlrs in a 
+Circular Queue with priorities.  The highest priority hndlrs can choose to 
+terminate handling, otherwise, the keys get sent on down the chain.
+
+KeyDevAdd() defines a putkey device with a priority.  "Device" might be a 
+misnomer.  Currently, the following are defined:
+
+Priority    Hndlr
+---------- ---------
+0x20000000 MyPutKey() user hndlr
+0x40000000 KDInputFilterPutKey() for In(), InStr(), and InFile() handling.
+0x60000000 KDRawPutKey() nonwindowed direct to video mem debug output. 
+0x80000000 KDDocPutKey() standard document cmds
+
+Since handling individual keys is slow, TempleOS supports PutS() as well.  If no 
+puts hndlr is defined, individual keys are sent.
+
+CDoc.user_put_key and CDoc.user_put_s are call back routines which offer some 
+neat tricks.  See ::/Apps/Psalmody/JukeBox.HC.  There is a var CDoc.user_put_dat
+a which gets passed to them.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Lex.DD.HTML b/public/Wb/Home/Src/Home/Doc/Lex.DD.HTML new file mode 100755 index 0000000..c5ec281 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Lex.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+The compiler's lexical analyzer can be used in your programs to simplify 
+parsing.  See Doc Parsing or Parse Opcode File.
+
+See Tokens.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/MemOverview.DD.HTML b/public/Wb/Home/Src/Home/Doc/MemOverview.DD.HTML new file mode 100755 index 0000000..1e27208 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/MemOverview.DD.HTML @@ -0,0 +1,143 @@ + + + + + + + + + + + +
+                                Memory Overview
+
+Paging is practically not used.  64-bit mode requires paging, however, so it is 
+identity-mapped -- virtual identical to physical.  All tasks on all cores use 
+the same page table map, just as though all addresses are physical addresses.  
+2Meg or 1Gig page table entries are used.  Nothing swaps to disk.
+
+In TempleOS, the lowest 2Gig of memory is called the code heap.  TempleOS's 
+compiler always uses 32-bit signed relative JMP & CALL insts because 64-bit 
+CALLs take two insts.  With signed +/- 32-bit values, code can only call a 
+function within 2Gig distance.  Therefore, TempleOS keeps all code in the lowest 
+2Gig memory addresses including what would normally be called "the kernel".  Two 
+Gig is plenty for code, don't worry.
+
+You can create new, independent heaps using HeapCtrlInit().  Then, use the 
+CHeapCtrl as the 2nd arg to MAlloc().  See HeapLog() for an example.
+
+Memory alloced by a task will be freed when the task is killed.  The Adam Task 
+is a task that never dies.  His memory is like kernel memory in other operating 
+systems.  See ACAlloc(), AMAlloc(), AMAllocIdent() and AStrNew().
+
+All of the regular page tables are marked, "cached".  When accessing hardware, 
+however, you need uncached page table.  The lowest 4Gig addresses have an alias 
+to access hardware located toward the top of mapped space, 0x10000000000.  See 
+dev.uncached_alias.
+
+During an extended powered-on session of TempleOS, in theory, memory will become 
+fragmented, requiring a reboot.  It has never happens to me.
+
+See MemRep() and ::/Demo/MemDemo.HC.
+
+
+                           Single System-wide Mem Map
+
+ 0x0000007C00- 0x000003616F
+  Kernel module, placed here by the boot-loader, BOOT_RAM_BASE.
+
+ 0x0000096600- 0x0000096FFF
+  Boot block relocated here before loading the Kernel module, BootDVD & BootHD.
+
+ 0x0000097000- 0x0000097030 Multicore start-up vect code, MPN_VECT.
+~0x000009F000- 0x000009FFFF Extended BIOS data area.
+ 0x00000A0000- 0x00000BFFFF VGA graphics mem with alias at text.vga_alias.
+ 0x0000100000- 0x0000101FFF CSysFixedArea for misc.
+ 0x000050A000- 0x001FFDFFFF Code Heap mem.
+
+ 0x00E0000000- 0x00FFFFFFFF
+  32-bit devices could alloc memory at 0xF0000000 going up, but this is wrong, 
+  since some PCs already have devices at 0xF0000000.  No PCI devices are 
+  supported, so Mem32DevAlloc() flaws are not an issue.
+
+ 0x0080000000-~0x00DFFFFFFF
+ 0x0100000000-~0xFFFFFFFFFF
+  Data Heap mem.  (The physical memory that exists in this range is data heap.)
+
+ 0x10000000000- 0x100FFFFFFFF
+  Uncached alias of first 4Gig.  (For 32-bit device access.)
+
+             - 0x100FFFFFFFF
+  64-bit devices are alloced with Mem64DevAlloc() counting bwd, but no PCI 
+  devices are actually supported.
+
+
+
+* Note: There is a break in the data-heap block pool.  This has no effect except 
+the obvious effect that fragmentation has on contiguous requests.  I can MAlloc(
+) an 8Gig chunk on my 12Gig machine.  I can MAlloc() an 32Gig chunk on my 64Gig 
+machine.  
+
+* Note: For systems with less than 2Gig RAM, the code and data heap block pools 
+are the same.  For systems with 2-4Gig of RAM, the code heap is 1/4 of the 
+total.  See BlkPoolsInit().
+
+
+                                    History
+
+In 2003, I wanted to make a no-paging ring-0-only 64-bit operating system for 
+super speed with simplicity and full access.  With paging, every memory request 
+requires 5 accesses -- it must access the address itself, 4K, 2Meg, 1Gig, and 
+512Gig page tables, but the CPU's translation look-aside buffer mostly removes 
+the penalty for using paging.  So, I did not want to use paging, but long mode 
+requires it.  I did the next best thing -- I identity-mapped everything and 
+achieved the simplicity I was after with subtle performance boosts, not wasting 
+time changing address maps.  And, I look forward to the day I command Intel to 
+make an optimized no-paging long mode.
+
+I needed VGA A0000-BFFFF memory to be write-through and 0xE0000000-0xFFFFFFFF to 
+be uncached for various devices.  All 64-bit computers allow stopping address 
+translation at 2Meg page size, not using 4K.  I wanted to use 2Meg for 
+everything because it's faster, with one less level of page tables.  I had to 
+make A0000-BFFFF write-through, though, so I could not use 2Meg size on the 
+lowest page.  I did the lowest 2Meg area as 4K pages.  I also unmapped the first 
+4K to cause a fault when dereferencing NULL.
+
+In 2016, I came-up with an alternate idea.  I double mapped the lowest memory 
+with an alias that was uncached.  Accessing the lowest 2Meg area directly was 
+cached but the alias I created up at the top of address space was uncached.  See 
+UncachedAliasAlloc().  Unfortunately, I could no longer boast of the simplicity 
+of identity mapping everything.  Since many of my users are familiar with 
+A0000-BFFFF, it is actually pretty seriously unfortunate that they cannot use 
+the easy-to-understand numbers of A0000-BFFFF, but must access the relocated 
+alias location.  See text.vga_alias.  I also no longer cause a fault when 
+dereferencing NULL.
+
+Then, I switched to 1Gig page sizes.  For the lowest 4Gig, I set-up an alias up 
+at the top of address space.  See UncachedAliasAlloc().  Not all computers 
+support 1Gig page tables, however, so I also support 2Meg.
+
+My original plan was to allow changing the page tables as needed, so I had code 
+for taking control of 2Meg pages and marking them uncached or whatever.  When I 
+did a HDAudio driver, I requested some 32-bit address space as uncached.  Today, 
+all of the first 4Gig can be accessed without caching at the dev.uncached_alias.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Menus.DD.HTML b/public/Wb/Home/Src/Home/Doc/Menus.DD.HTML new file mode 100755 index 0000000..dc8d4b0 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Menus.DD.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+A pull-down menu appears when you move the mouse to the top of the scrn.  Menus 
+are created with MenuPush(), MenuFilePush(), MenuNew() or MenuFile() and 
+assigned to Fs->cur_menu.  The format is:
+
+
+File 
+{
+  Open(,'O');
+  Save(,'S');
+  Exit(,CH_SHIFT_ESC);
+}
+Edit {
+  Cut(,,SC_DELETE|SCF_SHIFT);
+  Paste(,,SC_INS|SCF_SHIFT);
+}
+Misc {
+  Opt1(MSG_CMD,M_OPTION1);
+  Opt2(MSG_CMD,M_OPTION2);
+}
+Help
+{
+  Help(,'?');
+  About(,'/');
+}
+
+The first arg is the msg code and it is optional with the default being 
+MSG_KEY_DOWN_UP.  The second arg is the msg arg1 value which is ASCII of the key 
+in the case of MSG_KEY_DOWN.  The third arg is the msg arg2 value which is the 
+scan_code of the key in the case of MSG_KEY_DOWN.
+
+Press <CTRL-SHIFT-l> and "Insert ASCII/ScanCode".
+
+See ::/Demo/PullDownMenu.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Mouse.DD.HTML b/public/Wb/Home/Src/Home/Doc/Mouse.DD.HTML new file mode 100755 index 0000000..6c36bfb --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Mouse.DD.HTML @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+ms.pos.x and ms.pos.y can be used to access the x and y coordinates of the 
+mouse.  They are relative to the scrn, not window.  These can be used if you 
+don't want to use msg passing.  ms.pos.z is the wheel.
+
+ms.pos_text.x and ms.pos_text.y are the text column and row.  See 
+::/Demo/Games/Maze.HC.
+
+See CMsStateGlbls and CMsHardStateGlbls.
+
+The hard designation, as in ms_hard, represents hardware layer items before the 
+application of an abstraction layer.
+
+//****
+ms_hard.pos.x=ms_hard.prescale.x*ms_hard.scale.x*ms_grid.x_speed;
+ms.presnap.x=ToI64(ms.scale.x*ms_hard.pos.x)+ms.offset.x;
+if (ms_grid.snap)
+  ms.pos.x=Trunc(ms.presnap.x/ms_grid.x)*ms_grid.x+ms_grid.x_offset;
+else
+  ms.pos.x=ms.presnap.x;
+//****
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Msgs.DD.HTML b/public/Wb/Home/Src/Home/Doc/Msgs.DD.HTML new file mode 100755 index 0000000..dee3f4b --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Msgs.DD.HTML @@ -0,0 +1,33 @@ + + + + + + + + + + + +
+There are a maximum of 63 message types, so a bitmask can be passed.  Messages 
+have two args.  See Message Codes.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/MultiCore.DD.HTML b/public/Wb/Home/Src/Home/Doc/MultiCore.DD.HTML new file mode 100755 index 0000000..5e9b63c --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/MultiCore.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+TempleOS does master-slave multicore instead of SMP.  Core0 is the master.  The 
+master core's applications explicitly assign computational jobs to other cores 
+and the TempleOS scheduler does not move tasks between cores.
+
+There are multicore safe locks for file access and heap allocations, however, so 
+TempleOS is symmetrical in some sense.  See ::/Demo/MultiCore/LoadTest.HC.
+
+Only tasks on Core0 can have windows, but other cores can help render them.
+
+Each core has an executive Seth Task which is the father of all tasks on that 
+core.  Adam is the Seth Task on Core0.
+
+You give a job to a Seth Task with JobQue() and get the result with JobResGet(). 
+ You spawn a task on any core with Spawn().
+
+Note: You must use the LOCK asm prefix when changing shared structures in a 
+multicore environment.  The LBts(), LBtr() and LBtc() insts have LOCK prefixes.  
+The compiler has a lock{} feature but it doesn't work well.  See 
+::/Demo/MultiCore/Lock.HC.
+
+See ::/Demo/Graphics/Transform.HC.
+See ::/Kernel/MultiProc.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/NewASCII.DD.HTML b/public/Wb/Home/Src/Home/Doc/NewASCII.DD.HTML new file mode 100755 index 0000000..769a5ec --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/NewASCII.DD.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+                                   New ASCII
+
+
+We want to use one set for ASCII, ScanCodes and ScreenCodes.
+
+
+0  -63  :
+64 -127 : SHIFT
+128-191 : CTRL
+192-256 : CTRL+SHIFT
+
+No more ALT key in TempleOS.
+
+CTRL-LEFT/RIGHT is already begin/end line.
+CTRL-UP/DOWN    is already top/bottom of document.
+
+What about function keys?
+We will use reduced keyboard, probably.
+
+
+
+God says...
+clearest bade domine chance none quoth privily subjection possessor abolished
+
+
+
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/ODE.DD.HTML b/public/Wb/Home/Src/Home/Doc/ODE.DD.HTML new file mode 100755 index 0000000..030966f --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/ODE.DD.HTML @@ -0,0 +1,40 @@ + + + + + + + + + + + +
+TempleOS has an advanced algorithm for integrating ordinary differential 
+equations suitable for use in video games.  (Not scientific work.)  It also has 
+some support for systems of masses and springs, to save you some work.
+
+See CMathODE and ODEsUpdate for an overview.
+See ODECallDerivative to see what support there is for masses and springs.
+
+See ::/Demo/Games/Whap.HC, ::/Demo/Games/Rocket.HC, ::/Demo/Games/MassSpring.HC, 
+::/Apps/Span/SpanMain.HC or ::/Apps/X-Caliber/X-Caliber.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Once.DD.HTML b/public/Wb/Home/Src/Home/Doc/Once.DD.HTML new file mode 100755 index 0000000..78b2712 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Once.DD.HTML @@ -0,0 +1,47 @@ + + + + + + + + + + + +
+KMain()
+  includes ::/StartOS.HC
+    includes ~/MakeHome.HC
+      includes ~/HomeSys.HC
+        calls StartUpTasks()
+          includes ~/Once.HC
+            calls OnceExe().
+
+AOnce() appends src code to ~/Registry.HC Once/Adam tree, executed at next boot 
+by Adam.
+
+Once()  appends src code to ~/Registry.HC Once/User tree, executed at next boot 
+by first User term.
+
+At boot, OnceExe(), executes Once/Adam tree, AOnceFlush()s it,
+executes Once/User tree and OnceFlush()s.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Options.DD.HTML b/public/Wb/Home/Src/Home/Doc/Options.DD.HTML new file mode 100755 index 0000000..def5955 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Options.DD.HTML @@ -0,0 +1,58 @@ + + + + + + + + + + + +
+                                Compiler Options
+
+Use Option().  You might need to do #exe {Option();}.
+
+OPTf_GLBLS_ON_DATA_HEAP without this option, global vars are placed in the code 
+heap which is limited to 2Gig.  In AOT modules, global vars take-up room in the 
+.BIN file, so you might want to use this option, instead.  You might wish to 
+turn it on and off around specific vars.  A disadvantage of data heap global 
+vars in AOT modules is they can't be initialized.
+
+OPTf_EXTERNS_TO_IMPORTS and OPTf_KEEP_PRIVATE are strange options, you'll never 
+need.  They're to allow the same header file for Kernel to act as externs when 
+compiling itself and imports when compiled by AOT modules.
+
+OPTf_WARN_UNUSED_VAR    warning if unused var.  It is applied to functions.
+
+OPTf_WARN_PAREN         warning if parenthesis are not needed.
+
+OPTf_WARN_DUP_TYPES     warning if dup local var type stmts.
+
+OPTf_WARN_HEADER_MISMATCH warning if fun header does not match.
+
+OPTf_NO_REG_VAR forces all function local vars to the stk not regs.  Applied to 
+functions.
+
+OPTf_NO_BUILTIN_CONST Disable 10-byte float consts for pi, log2_10, log10_2, 
+loge_2.  Applied to functions.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Pags.DD.HTML b/public/Wb/Home/Src/Home/Doc/Pags.DD.HTML new file mode 100755 index 0000000..bb1cb6a --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Pags.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+The word Pag refers to an arbitrilly created MEM_PAG_SIZE unit of heap 
+allocation.  TempleOS does not alter the CPU page tables after setting them up 
+at boot in SYS_INIT_PAGE_TABLES, so the CPU hardware page size is rarely 
+important.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/PreProcessor.DD.HTML b/public/Wb/Home/Src/Home/Doc/PreProcessor.DD.HTML new file mode 100755 index 0000000..80d5b97 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/PreProcessor.DD.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+                                  PreProcessor
+
+There is no separate preprocessor pass.  The parser front-end calls Lex() which 
+has the preprocessor built-in.  The compiler looks ahead a token, most of the 
+time, so you might throw an extra semicolon after a directive if it's not taking 
+affect right away.
+
+Put an extra semicolon #exe {Cd("DirName");;} in case a #include follows.
+
+#include ""     There is no angle bracket <> form of this directive.
+#exe {}         Will execute code at compile-time and can be used to insert code 
+into the stream being compiled using StreamPrint().
+#define         Define string const
+#assert         Print a warning during compilation if an expression is not true. 
+#if             Include code if an expresion is true.
+#else
+#endif
+#ifdef,#ifndef  Include code if a sym is defined.
+#ifaot,#ifjit   Include code if in AOT compiler mode.
+defined()       Is a function that can be used in expressions.
+#help_index, #help_file See Help System.
+
+See PreProcessor.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Print.DD.HTML b/public/Wb/Home/Src/Home/Doc/Print.DD.HTML new file mode 100755 index 0000000..938606d --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Print.DD.HTML @@ -0,0 +1,144 @@ + + + + + + + + + + + +
+                                 Print Fmt Strs
+
+<fmt_arg> := %[-][0][<width>][.<decimals>][<flags>][h<aux_fmt_num>]<fmt_code>
+
+See StrPrintJoin().
+
+<flags>:
+
+  't' truncate to <width>.
+  ',' add commas every three digits or four nibbles.
+  '$' makes %Q convert '$' to "\x24".
+  '/' makes %Q and %q convert '%' to "%%".
+
+<aux_fmt_num>:
+
+  For "%n", "%d" or "%u", the <aux_fmt_num> causes thousands mode.  "%h?n" will 
+  pick a var exponent multiples of three unit, while "%h-3n" will display milli 
+  units or "%h6n" will display mega units.  The 'k' flag is always on for "%n".  
+  See ::/Demo/Print.HC.
+  
+For "%c" or "%C", the <aux_fmt_num> repeats the char that many times.
+
+<fmt_code>:
+
+  "%n" floating point in engineering notation, exponents being multiples of 
+  three.  If it has a <aux_fmt> code, it will display scientific units letters.
+  
+  "%S" Define() entry.
+  
+  "%C" ToUpper() character.
+  
+  "%h25c",'\n'; 25 new-lines.
+  
+  "%h*c",25,'\n'; 25 new-lines.
+  
+  "%F" text file by filename.
+  
+  "%$F" DolDoc file in memory.
+  
+  "%p" ptr. 
+  
+  "%,p" ptr with no offset. 
+  
+  "%P" link to ptr.
+  
+  "%,P" link to ptr with no offset.
+  
+  "%D" date.  Pass a CDate.
+  
+  "%T" time.  Pass a CDate.
+  
+  "%z" sub_entry of an enumerated list of text entries.  See LstSub().  Pass 
+  sub_entry_num first, list second.
+  
+  "%Z" DefineLstLoad() subentry.  Pass sub_entry_num first, define_name second.
+  
+  "%Q" convert "\" to "\\" and quote to backslash quote. (For use in creating 
+  strs in strs.)
+  
+  "%q" rev a "%Q".
+
+
+                                  Print Family
+
+MStrPrint(U8 *fmt,...) is like StrPrint(U8 *dst,U8 *fmt,...) but it returns a 
+MAllocated str.  It is vary handy because you don't have to worry about 
+overflow.
+
+CatPrint(U8 *_dst,U8 *fmt,...) concatenates a formated string.
+
+In(U8 *fmt,...) sends text to the current task's input buffer.
+InStr(U8 *fmt,...) sends text of an InFile to the keyboard stream of the current 
+TASK but can also do mouse cmds.
+
+XTalk(CTask *task,U8 *fmt,...) and text to another task's input buffer.
+XTalkStr(CTask *task,U8 *fmt,...) sends text of an InFile to the keyboard stream 
+of another TASK but can also do mouse cmds.
+
+DocPrint(CDoc *doc,U8 *fmt,...) sends text to a document.  You can buffer to a 
+Doc and save it, providing the functionality of fprintf.  See 
+::/Demo/Dsk/FPrintF.HC.
+
+Adam(U8 *fmt,...) sends text to the Adam Task to be compiled and run.
+AdamLog(U8 *fmt,...) and AdamErr(U8 *fmt,...) send text to the Adam Task to be 
+displayed.
+
+StreamPrint(U8 *fmt,...) sends text to the stream of code being compiled and 
+must reside in a #exe{} blk.
+
+GrPrint(CDC *dc,I64 x,I64 y,U8 *fmt,...) and GrVPrint() plots text in graphics 
+mode.
+
+TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...) plots to gr.text_base.
+
+ExePrint(U8 *fmt,...) compiles and execute a string.  Note: It returns the res 
+of the last executed expression.
+
+Once(U8 *fmt,...) Writes User code to Registry to be executed next boot.
+
+AOnce(U8 *fmt,...) Writes Adam code to Registry to be executed next boot.
+
+InPrint(I64 mS,U8 *fmt,...) PutChars()s one at a time with a delay.
+
+RawPrint(I64 mS,U8 *fmt,...) sends direct to scrn memory, bypassing window 
+manager.
+
+User(U8 *fmt,...) Spawns a user and execute a string on start-up.
+
+PopUpPrint(U8 *fmt,...) compiles and execute a string in a pop-up win.  Note: It 
+returns the res of the last executed expression.
+PopUpViewPrint(U8 *fmt,...) creates a pop-up window and views text.
+
+Note: Use Print("%s",src) if you need an unmodified string.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Profiler.DD.HTML b/public/Wb/Home/Src/Home/Doc/Profiler.DD.HTML new file mode 100755 index 0000000..affc808 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Profiler.DD.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+The profiler records where the CPU was executing when the 1000Hz timer interrupt 
+occured, so you can learn where time is spent.
+
+Use the Prof() depth argument to record a hit in the N routines which called the 
+current routine, as well.
+
+When done collecting statistics, use ProfRep() for a report.  You might need a 
+DocMax() to expand the command line window buffer to fit it all.
+
+Study the code.  The profiler is very simple.  You might want to enhance it or 
+modify it to debug something in particular.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Que.DD.HTML b/public/Wb/Home/Src/Home/Doc/Que.DD.HTML new file mode 100755 index 0000000..1b3e289 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Que.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+A Queue is a bunch of MAlloc()ed chunks of mem linked together in a circle with 
+one ptr to the next value and another ptr to the last value.  These ptrs must be 
+stored in the first locations in the structure.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Quirks.DD.HTML b/public/Wb/Home/Src/Home/Doc/Quirks.DD.HTML new file mode 100755 index 0000000..c292cd9 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Quirks.DD.HTML @@ -0,0 +1,101 @@ + + + + + + + + + + + +
+                                     Quirks
+
+* You run a risk of problems if you do file operations on the same files 
+simultaneously because there is no file sharing/locking mechanism.  Generally, 
+the last write wins.
+
+* When using FAT32, TempleOS does not generate unique short-entry names, the 
+ones with the ~s.  Not all FAT32 filenames are valid TempleOS names and it will 
+complain.  Do not access FAT32 drives not dedicated to TempleOS.  Disable them 
+with DrvEnable(OFF), or they will generate error messages.  FAT32 involves a 
+long and short name for each file.
+
+* The stk does not grow because virtual mem is not used.  I recommend allocating 
+large local vars from the heap.  You can change MEM_DFT_STK and recompile Kernel 
+or request more when doing a Spawn().
+
+* The syntax highlighting occassionally glitches.  The compiler doesn't.
+
+* Call DskChg() when you insert a new removable media.
+
+* Accessing CD/DVD's is flacky.  Try Drv() or DskChg() twice.
+
+* You can only extern something once.  There is a varient called _extern which 
+binds a HolyC definition to a asm sym.  This, too, can only be done once.
+
+* A terminal task has a CDoc document structure that remains active even when 
+you change Fs->draw_it.  To prevent links in the CDoc from being activated when 
+the user clicks in the window, do one of three things:
+  
+  A) DocBottom() followed by DocClear() to clear the CDoc so it has no active 
+  widgets.
+  
+  B) Disable window mgr bttn click checking with Fs->win_inhibit set to mask 
+  WIF_SELF_MS_L|WIF_FOCUS_TASK_MS_L_D|WIF_SELF_MS_R|WIF_FOCUS_TASK_MS_R_D.  This 
+  inhibits window mgr operations but still generates messages from bttn clicks.
+
+* switch/case stmts alloc a single jump table--do not use with wide, sparse 
+ranges of case values.
+
+* Don't do a goto out of a try{}.
+
+* A goto label name must not match a global scope object's name.  (It's not 
+worth slowing-down the compiler to handle this case.)
+
+* MemCpy() only goes fwd.
+
+* A Cd() cmd must be followed by two semicolons if a #include is after it.  This 
+is because the preprocessor processes the next token ahead.
+
+* The assembler's error msgs are often off by a line and undefines are cryptic.
+
+* The last semicolon on the cmd line is converted to a dbl semicolon because the 
+compiler looks ahead before doing a cmd.  This normally has no negative effect, 
+but when entering if stmts with else clauses it presents problems.
+
+* You can do a class fwd reference by using extern on the first declaration, but 
+you can only do ptr references to the class.
+
+* When doing something like
+    U0 Main()
+    {
+      U16 *_w=0xA0000;
+      *_w|=0x8000;
+    }
+  The |= will be coded as a U32 Bts inst resulting in a U32 access instead of a 
+  U16 access.  This affects some hardware operations.
+
+* Compiler warning or error message line numbers will be off if you have a block 
+of word-wrapped comments.  You might press <CTRL-t> before doing an editor 
+goto-line-number command.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/RedSea.DD.HTML b/public/Wb/Home/Src/Home/Doc/RedSea.DD.HTML new file mode 100755 index 0000000..03bd00d --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/RedSea.DD.HTML @@ -0,0 +1,83 @@ + + + + + + + + + + + +
+                               RedSea File System
+
+The RedSea file system is a simple, 64-bit, file system which is similar to 
+FAT32, but with absolute block addresses instead of clus, fixed-sized 64-byte 
+directory entries and no FAT table, just an allocation bitmap.  A clus is just 
+one 512 byte sector.  Files are stored in contiguous blocks and cannot grow in 
+size.
+
+#define CDIR_FILENAME_LEN       38 //Must include terminator zero
+
+The following bit field shows valid 8-Bit ASCII filename characters.
+
+U32 char_bmp_filename[8]=
+{0x0000000, 0x03FF73FB, 0xEFFFFFFF, 0x2FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 
+0xFFFFFFFF, 0xFFFFFFFF};
+
+public class CDirEntry //64-byte fixed-size
+{
+  U16 attr;     //See RS_ATTR_DIR.  I would like to change these.
+  U8 name[CDIR_FILENAME_LEN]; //See char_bmp_filename, FileNameChk
+  I64 clus; (blk) //One sector per clus.
+  I64 size;     //In bytes
+  CDate datetime; //See  DateTime, Implementation of DateTime
+};
+
+public class CRedSeaBoot //RedSea is type FAT32 in partition table to fool BIOS.
+{
+  U8 jump_and_nop[3];
+  U8 signature,reserved[4]; //MBR_PT_REDSEA=0x88. Distinguish from real FAT32.
+  I64 drv_offset;       //For CD/DVD image copy.
+  I64 sects;
+  I64 root_clus; (root_blk)
+  I64 bitmap_sects;
+  I64 unique_id;
+  U8 code[462];
+  U16 signature2;       //0xAA55
+};
+
+See ::/Kernel/BlkDev/FileSysRedSea.HC and ::/Adam/Opt/Boot/DskISORedSea.HC.
+
+Files with names ending in .Z are compressed.  See ::/Kernel/Compress.HC.
+
+To replace ISO9660, make hard-drive partition image of a measured size and copy 
+onto a CD/DVD starting at about sector 20, with EL TORITO booting.  512-byte 
+sectors will be placed on top of 2048-byte CD/DCD sectors, so there will be four 
+blocks per CD/DVD sector.
+
+RedSea file system has no bad block table and no redundant allocation table.
+
+See Block Chain for RedSea allocation bitmap discussion.
+
+See Reliability for RedSea reliability discussion.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Reliability.DD.HTML b/public/Wb/Home/Src/Home/Doc/Reliability.DD.HTML new file mode 100755 index 0000000..01c7ed7 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Reliability.DD.HTML @@ -0,0 +1,71 @@ + + + + + + + + + + + +
+                               RedSea Reliability
+
+TempleOS is like the 1040EZ tax form compared to the full 1040 form.  Obviously, 
+it is simpler.  If you allow mission creep, pretty soon the 1040EZ looks just 
+like the 1040 and the messed-up 1040EZ has no purpose.
+
+The Commodore 64 had a file system that was simple enough for peers in my 
+generation to enjoy the thrill of knowing exactly what is going on at the 
+hardware level and writing fun projects to access it.
+
+My primary design criteria is simplicity.  If it is simple enough for only 
+100,000 people to learn, lets try to make it simpler so that 1 million can learn 
+it.
+
+Obviously, we don't do bad block tables, or redundant FATs.
+
+We use the simplest possible technique, a contiguous-file-only allocation 
+bitmap, not Block Chains or FAT tables.
+
+You can be a good toy or you can be a good professional tool, but not both.  
+TempleOS's file manager will start too slowly once a few thousand files exist 
+because the file manager makes a list of all files on start-up.
+
+Do not have more than a few thousand files or the file manager will not 
+function.
+
+You are encouraged to keep your entire drive limited to, maybe, 100 Meg of files 
+because you are suppoosed to operate as a kayak instead of a Titanic.  If you do 
+this, backing-up will be only a minute or so and you should do it at least once 
+a day. 
+
+Third party software should be run from ISO files or CD/DVDs directly, without 
+installing to hard drive.
+
+Multimedia graphics and sound is, basically, forbidden.  If you ignore this, all 
+hell will break loose because memory will fragment with large files and the 
+original vision of kayak hard-drive back-ups won't work.
+
+
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Requirements.DD.HTML b/public/Wb/Home/Src/Home/Doc/Requirements.DD.HTML new file mode 100755 index 0000000..2a8300c --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Requirements.DD.HTML @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+                           Requirements for TempleOS
+
+User Skills Required
+* Knowledge of the C programming language.
+
+Supported Hardware
+* x86_64 PC compatible computer.  (Obviously, you need 64-bit hardware for a 
+64-bit operating system.)
+
+* 640x480 16 color VGA graphics.
+
+* Most keyboards and mice.
+
+* Minimum 512Meg RAM.
+
+* Internal PC Speakers.
+
+* CD/DVD-ROMs (not SCSI) but only RedSea file system.
+
+* ATA and SATA hard drives.
+
+Unsupported Hardware
+* No graphics acceleration.
+
+* No sound cards.
+
+* No networking.
+
+* No USB devices, except keyboard and mouse in legacy mode.  No, you can't use 
+flash memory cards.
+
+* No printers.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Resource.DD.HTML b/public/Wb/Home/Src/Home/Doc/Resource.DD.HTML new file mode 100755 index 0000000..e3a9359 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Resource.DD.HTML @@ -0,0 +1,42 @@ + + + + + + + + + + + +
+                          Graphic Sprite Resource Help
+
+A sprite is an ordered list of elements such as lines, rectangles, bitmaps and 
+color changes.  In a program's source code, you first make a sprite somewhere 
+outside a function.  Then, you insert a pointer to the sprite as an "*elems" arg 
+when calling Sprite() or Sprite3().  See Sprites.
+
+You can create a sprite macro on your PersonalMenu with a payload of HolyC 
+source code to execute when it ESC's back to the cmd line.  If you check 
+"Pop-Up", it will spawn a new task and run the payload.  A pop-up macro can be 
+placed in any document.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/ScopingLinkage.DD.HTML b/public/Wb/Home/Src/Home/Doc/ScopingLinkage.DD.HTML new file mode 100755 index 0000000..8102d8a --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/ScopingLinkage.DD.HTML @@ -0,0 +1,178 @@ + + + + + + + + + + + +
+                              Scoping and Linkage
+
+JIT Compile Mode makes use of the current task's hash sym table and its parent 
+tasks' tables.  It fetches syms from parent tasks' tables if not found locally 
+in the current task's table and it places new syms in the current task's table.  
+Conceptually, syms are at the scope of environment vars in other operating 
+systems.
+
+When a sym is placed into a table, older syms with ident names will be 
+overshadowed if they exist.  Duplicates are not allowed in many cases, 
+especially in asm blks.  Dupicates are allowed, by design in other cases, so 
+that you can repeatedly #include the same file from the cmd line while 
+developing it.  Or, so you can repeatedly declare a function with a standard 
+name, like DrawIt().  This case might occur when the Adam Task is starting-up 
+loading-in many little utilities.
+
+extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym of the same 
+name if it exists in the sym table (just in just-in-time code).  It also can be 
+used to generate a fwd reference.
+
+import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym of the same name 
+imported from the task's sym table at Load() time.  If no sym exists to bind to 
+at Load() time, the code using this sym will be left incomplete until the sym is 
+defined.
+
+
+_extern binds a new HTT_FUN or HTT_GLBL_VAR sym to an existing sym, of a differe
+nt name.  It must exists in the sym table.  Basically, this binds C to asm.
+
+_import binds a new HTT_FUN or HTT_GLBL_VAR sym to a sym, of a different name 
+imported from the task's sym table at Load() time.  If no sym exists to bind to 
+at Load() time, the code using this sym will be left incomplete until the sym is 
+defined.  Basically, this binds C to asm from elsewhere.
+
+
+Ahead of Time Compilation
+                    GlobalScope/FunctionScope
+                    | CodeHeap/DataHeap/Stack/Register
+                    | | TaskHashEntry:ExportSysSym/Define/Function/Class
+                    | | | UsageScope: Module/AsmLocal/AsmBlk/TaskAndChildren/Function
+                    | | | |UsageScope: Glbl/AsmLocal/Remainder/glblThisBlkAndRemainder
+                    | | | || StaticVarInit/DynamicVarInitAllowed/NoInitAllowed
+                    | | | || | Are dups allowed within the namespace? A dup overshadows the original.
+                    | | | || | DupsAllowed/NoDups/NoDupsButPad/WarningUnlessClosedOut
+
+asm export label::  G C S MG   N
+asm        label:   G C   MG   N
+asm local  @@label: G C   AL   N
+asm IMPORT label;   G C   MR   N
+asm export label::  F C S BG   N
+asm        label:   F C   BG   N
+asm local  @@label: F C   AL   N
+asm IMPORT label;   F C   BR   N
+C   goto   label:   F C   FG   N
+
+           #define  x     MR   D
+           function G C S MR   D
+           var      F R   FR   N
+           var      F S   FR   N
+static     var      F C   FR D N
+           var      G C S MR D D
+           var      G D   MR N D
+           class    G     MR   D
+class      member   G     MR   P
+extern     class    G     MR   D
+extern     function G C   MR   W
+import     function G C   MR   D
+import     var      G C   MR   D
+_extern    function G C   MR   D
+_extern    var      G C   MR   D
+_import    function G C   MR   D
+_import    var      G C   MR   D
+
+
+Just in Time Compilation
+                    GlobalScope/FunctionScope
+                    | CodeHeap/DataHeap/Stack/Register
+                    | | TaskHashEntry:ExportSysSym/Define/Function/Class
+                    | | | UsageScope: Module/AsmLocal/AsmBlk/TaskAndChildren/Function
+                    | | | |UsageScope: Glbl/AsmLocal/Remainder/glblThisBlkAndRemainder
+                    | | | || StaticVarInit/DynamicVarInitAllowed/NoInitAllowed
+                    | | | || | Are dups allowed within the namespace? A dup overshadows the original.
+                    | | | || | DupsAllowed/NoDups/NoDupsButPad/WarningUnlessClosedOut
+
+asm export label::  G C S Tg   N
+asm        label:   G C   BG   N
+asm local  @@label: G C   AL   N
+asm IMPORT label;   G C   TR   N
+asm export label::  F C   BG   N
+asm        label:   F C   BG   N
+asm local  @@label: F C   AL   N
+asm IMPORT label;   F C   BR   N
+C   goto   label:   F C   FG   N
+
+           #define  x   D TR   D
+           function G C F TR   D
+           var      F R   FR   N
+           var      F S   FR   N
+static     var      F C   FR D N
+           var      G C G TR D D
+           var      G D G TR S D
+           class    G   C TR   D
+class      member   G     TR   P
+extern     class    G   C TR   D
+extern     function G C F TR   W
+extern     var      G C G TR   D
+extern     var      G D G TR   D
+_extern    function G C F TR   D
+_extern    var      G C G TR   D
+
+
+* Goto labels must not have the same name as global scope objects.  GoTo's are 
+rare and I don't want to slow the compiler and add code to fix this.  You will 
+get errors if a collision happens, so it's not very dangerous, but the error 
+message is baffling.
+
+* The member names pad and reserved are special because multiple instances with 
+the same name are allowed in a class.
+
+* Use reg or noreg in front of local var names to override automatic reg var 
+allocation.  You can, optionally, specify a reg after the reg keyword.
+ 
+* Local non-reg function vars can be accessed in asm blks with &i[RBP] for 
+example.
+
+* Glbl vars and functions can be accessed in asm with and & as in
+        MOV     RAX,I64 [&glbl_var]
+        CALL    I32 &Fun
+        CALL    I32 &SYS_SYM
+
+* In JIT asm code, &SYS_SYM and &Fun don't need IMPORT.
+
+* All offspring tasks of a task inherit syms.
+
+* The sizeof() and HolyC structure members can be used in asm blks.
+
+* Using &i in HolyC or i.u8[2] on a local var, i, will force it to noreg.
+
+* Using try/catch in a function will force all local vars to noreg.
+
+* An unused gap on the stk is left for reg vars.
+
+* Note: static function vars do not go on the data heap, no matter the setting 
+of the OPTf_GLBLS_ON_DATA_HEAP.  They may in the future.
+
+* OPTf_EXTERNS_TO_IMPORTS will treat _extern as _import and extern as import.  
+This allows a header to be used either as a JIT compiled or AOT compiled header.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Snd.DD.HTML b/public/Wb/Home/Src/Home/Doc/Snd.DD.HTML new file mode 100755 index 0000000..9c6f366 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Snd.DD.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+Sound is generated with I8 vals called ona's, which are 88 piano key nums, with 
+0 as a rest.  See Note2Ona() and Ona2Freq().  God does not want death screams, 
+perhaps, because God has PTSD or soldiers have PTSD.  (Imagine wounded on 
+battlefields.)  Ona's will allow elegant wave files for export and will allow 
+the creation of simple hardware over the next centuries.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Sprite.DD.HTML b/public/Wb/Home/Src/Home/Doc/Sprite.DD.HTML new file mode 100755 index 0000000..5a41f16 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Sprite.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+A CSprite is an ordered list of these elements, created with <CTRL-r>.  
+Normally, they are packed together in a list and the address of the first is 
+passed to routines.
+
+See ::/Demo/Graphics/SpritePlot.HC, ::/Demo/Graphics/SpritePlot3D.HC, 
+::/Demo/Graphics/SpritePut.HC, ::/Demo/Graphics/SpriteRaw.HC and SpriteMeshEd().
+
+Be aware that copying SP, IB, or IS entries with the clip results in duplicate 
+entries with different nums.  You can manually remove dups by editing with <CTRL
+-t> and setting to the original num.
+
+See ::/Adam/Gr/GrSpritePlot.HC for how CSprite are stored.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/SpriteBitMap.DD.HTML b/public/Wb/Home/Src/Home/Doc/SpriteBitMap.DD.HTML new file mode 100755 index 0000000..0094f37 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/SpriteBitMap.DD.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+                            Sprite BitMap Menu Help
+
+BitMaps have a background color.  If you delete to the clip, what's left will be 
+background colored.
+
+While drawing, you can usually press 'c' to eye-dropper the color under the 
+mouse.  Press 't' for transparent.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/SpriteEd.DD.HTML b/public/Wb/Home/Src/Home/Doc/SpriteEd.DD.HTML new file mode 100755 index 0000000..06b8503 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/SpriteEd.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+                             Sprite Edit Menu Help
+
+Order of elements matters.  They are executed in the order they appear in the 
+side-bar.  You can sel or unsel elements graphically, or with text in the 
+sidebar.  Then, cut, copy, paste, shift or transform them.
+
+You can set the current insert point element by clicking the element in the 
+side-bar and making it RED.
+
+Insert Shift Suborigin is an element which shifts subsequent elements.  Perhaps, 
+you inserted a sprite's elements from the clip and want to shift it around?  
+This command is also useful if you call SpriteInterpolate() in programs.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/SpriteEdText.DD.HTML b/public/Wb/Home/Src/Home/Doc/SpriteEdText.DD.HTML new file mode 100755 index 0000000..f60924d --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/SpriteEdText.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+                            Sprite Edit as Text Help
+
+See the format for CSprites.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/SpriteMain.DD.HTML b/public/Wb/Home/Src/Home/Doc/SpriteMain.DD.HTML new file mode 100755 index 0000000..2ac1064 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/SpriteMain.DD.HTML @@ -0,0 +1,53 @@ + + + + + + + + + + + +
+                             Sprite Main Menu Help
+
+Order of elements matters.  They are executed in the order they appear in the 
+side-bar.  You can set the insert point for new elements by click the element in 
+the side-bar and making it RED.
+
+After you create a 3D Mesh, you can edit it by seling it in the side-bar so it 
+is colored RED.  Then, click EDIT-3D-MESH.  A shiftable 3D mesh has a 2D offset 
+to position the origin.  You can convert between shiftable and non-shiftable by 
+editing it with the other command.
+
+You can convert all elements to a BitMap if END is RED in the side-bar and you 
+CONVERT-TO-BITMAP.  Later, you can edit that bitmap by seling it in the side bar 
+so it is colored RED and clicking EDIT-BITMAP.
+
+If you have a 3D icon, you might want to place a background-colored rectangle 
+under the 3D icon, so it hovers above.  Use TRANSFORM-OFF and TRANSFORM-ON.  You 
+will also need to set the Z offset of the icon.  Go to the Edit menu and sel 
+EDIT-AS-TEXT and change the third INT to Z offset.  Good luck.
+
+While inserting vector elements, you can usually press 'c' to eye-dropper the 
+color under the mouse.  Press 't' for transparent.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/SpriteSideBar.DD.HTML b/public/Wb/Home/Src/Home/Doc/SpriteSideBar.DD.HTML new file mode 100755 index 0000000..8b0278d --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/SpriteSideBar.DD.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+                              Sprite SideBar Help
+
+You can cut and paste elements in this side-bar to reorder, delete or 
+duplicating them.  Click an element in the side-bar after you make changes to 
+cause the changes to take-effect.
+
+You can click on an element to make it the insert point for new elements.
+
+The RED element is the current insert point for new elements.
+ diff --git a/public/Wb/Home/Src/Home/Doc/StandBy.DD.HTML b/public/Wb/Home/Src/Home/Doc/StandBy.DD.HTML new file mode 100755 index 0000000..24a4b10 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/StandBy.DD.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+                           AutoComplete is in StandBy
+
+                            System Keys Quick Guide
+                               (Works Everywhere)
+  <SPACE>   Left-Click  
+  <ENTER>   Right-Click  
+   <F1>     Help
+ <CTRL-m>   Personal Menu
+   <ESC>    Save  & Exit
+<SHIFT-ESC> Abort & Exit
+ <WINDOWS>  Pull-Down Menu
+
+                                    Tongues
+                               (Works Everywhere)
+   <F7>     God Word
+<SHIFT-F7>  God Passage
+   <F6>     God Song
+<SHIFT-F6>  God Doodle
+ diff --git a/public/Wb/Home/Src/Home/Doc/Start.DD.HTML b/public/Wb/Home/Src/Home/Doc/Start.DD.HTML new file mode 100755 index 0000000..5079921 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Start.DD.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+                                 TempleOS V5.03
+
+                         Public Domain Operating System
+
+Help & Index, Quick Start: Cmd line
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/StdOutTask.DD.HTML b/public/Wb/Home/Src/Home/Doc/StdOutTask.DD.HTML new file mode 100755 index 0000000..f48f49e --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/StdOutTask.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+There is one CDoc for the task's border: Fs->border_doc.  There is a pair for 
+the task's client area: Fs->put_doc and Fs->display_doc.  You can, optionally, 
+do double buffering, otherwise Fs->put_doc is the same as Fs->display_doc.  See 
+::/Demo/Spy.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/StdTempleOSPC.DD.HTML b/public/Wb/Home/Src/Home/Doc/StdTempleOSPC.DD.HTML new file mode 100755 index 0000000..16b5418 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/StdTempleOSPC.DD.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+                            The Standard TempleOS PC
+
+All desktop PCs will have 8-channel OCTART super-simple high speed serial ports 
+to replace USB.  They are simpler because the driver is as simple as old school 
+RS232 Serial, they have no USB end-points and they have no USB human interface 
+device reports.  Computer mice will all have exactly two bttns and one wheel.  
+Game controllers will all be the standard deluxe game console controllers that 
+are popular today.  It will have 8 big TX and 8 big RX fifos that allow flow 
+control characters to jump the queue.  It should be locked-down to as few 
+options as possible, like 8-1-N only, although hardware may use a USB frame, not 
+an RS232, so stop bits might not be relevant.  Perhaps, just two baud rates -- 
+high and low speed are needed.  Low speed is good for slow microcontrollers and 
+allows longer cable length.  Keyboard, mouse and game controller can be low 
+speed.
+
+The USB creators banned generic devices, requiring a signed, certified driver 
+for everything!  That's no good.  We allow any device and will communicate, 
+generically, using a serial terminal program like the old school HyperTerminal, 
+XTalk or Telnet.
+
+A mouse packet interface should be similar to this:
+
+     TX:        <ENTER>
+     RX:        X:+3 Y:+0 Wheel:+0 LB:OFF RB:OFF
+     TX:        <ENTER>
+     RX:        X:+0 Y:-1 Wheel:+0 LB:ON  RB:OFF
+
+We aspire to be as simple as a Commodore 64 joystick driver:
+
+     VAL=PEEK(56321)
+     if VAL AND 1 THEN y=y-1
+     if VAL AND 2 THEN y=y+1
+     if VAL AND 4 THEN x=x-1
+     if VAL AND 8 THEN x=x+1
+
+The game controller will be more complicated, but much simpler than USB.  It 
+will use a standard text packet of some kind.
+
+On the other end, you might hook-up a thermostat microcontroller and interface 
+as a generic serial device.  The microcontroller in the thermostat would have 
+something simple, not a crazy overkill ethernet connection.
+
+     U8 b;
+     while (TRUE) {
+       b=ReadU8(2); //Read byte from high speed serial channel 2.
+     //(Has been configured for low baud because thermostat should be slow.)
+       if (b==CMD_UP)
+         temperature++;
+       else if (b==CMD_DOWN)
+         temperature--;
+     }
+
+Super-simple block devices will replace ATA/ATAPI hard drives and 
+CD/DVD/BlueRays.  Today, the industry is in flux with nonvolitile memory just 
+invented.  We want a super-simple block device interface for non-volitile memory 
+and for what is currently USB memory sticks, but only if they can be made 
+without bad blocks.  I don't think we want to deal with bad block memory, so 
+maybe we will not do NV-memory.  The standard TempleOS desktop will require a 
+hard disk.
+
+There will be minimal commands:  READ_BLOCK, WRITE_BLOCK, GET_CAPACITY, 
+GET_MODEL, GET_SERIAL_NUM, and EJECT.
+
+We want a CPU mode with virtual IO port addresses similar to how paging creates 
+virtual memory addresses.  We want a 65536 word look-up table that converts 
+virtual IO port numbers to physical IO port numbers.  There will be a standard 
+IO port configuration, so port numbers can be fixed in the code.  We want the 
+primary hard drive on one set of ports and the primary CD/DVD/Blu-ray on another 
+set of ports.  Choose a contiguous set of IO ports.
+
+Meanwhile, a complicated PCI interface can be designed along-side the TempleOS 
+interface for Windows and Linux.  It would almost be possible to carry-on 
+separate lives, however, the super-simple serial requires getting rid of USB 
+since super-simple serial is a new hardware standard.  People can add USB ports 
+with a PCI device card.
+
+God said He wants single-voice 8-bit signed MIDI-like sample for the sound.  God 
+does not want death screams, perhaps, because God has PTSD or soldiers have 
+PTSD.  (Imagine wounded on battlefields.)
+
+The video will be a linear frame buffer 640x480 16 color with one-byte-per-pixel 
+even though it is only 16 color with is 4-bit.  Perhaps, we have a interrupt to 
+sync with the refresh.
+
+I am tmpted to help amateur hardware device designers by making the hardware 
+interface for the PC simple.  I have fond memories of 1993, when I made a 
+wire-wrapped ISA data acquisition card which plugged into my 486 and had some 
+analog-to-digital and digital-to-analog convertors.  I am not designing a bus.  
+Earlier, I said the super-simple high speed serial port replacement could be 
+USB-like in hardware as long as the software driver interface was simple like 
+old school RS232 serial ports.  Requiring a complicated hardware handshake 
+raises the bar, slightly, for the lowest level hardware designers.  Most people 
+will be connecting a microcontroller or something that already has a serial 
+communication design, but if it's not a problem, maybe we should keep it simple 
+at all stages.  It was nice putting an oscilloscope on my serial port wires.
+
+The original PC had general purpose digital IO through the parallel port.  That 
+was fun.  I have enough battles to fight, so I'll leave being a savior to 
+hobbiest hardware engineers to somebody else.
+
+Digital cameras will be super-simple high speed serial, but TempleOS is forever 
+limited to 16 colors and multimedia is banned because large files being loaded 
+into memory fragments memory, so cameras are somewhat unwelcome.  I have enough 
+problems without making the Brits anxious about autonomous gun turrets and 
+killer robots.  The reason I say cameras will be super-simple serial is because 
+we are replacing USB ports with super-simple serial.  PC's will have only 
+super-simple serial ports unless people buy a USB PCI expansion card.  So, the 
+digital cameras will be super-simple serial.
+
+
+                                  Version 1.0
+
+We will make a spec for a $8,000, perfectly standardized, cryogenically-cooled, 
+monster desktop PC.  It will have 16 cores, integrated 4K graphics, and, 
+hopefully, 6 Ghz continuous operation.  Perhaps, 64 Gig of RAM will be standard? 
+God said to help to poor buy them.  It is pointless to have a high powered 
+machine if other people have wimpy machines and cannot run programs you write.  
+Therefore, everybody in the developed world will buy a Standard TempleOS IBM PC 
+over the next ten years, so that will be a quantity of 400 million, perhaps.  
+God said to pay the US national debt with the revenue.  We will standardize 
+everything, not just the TempleOS related items.  The display will be 4K (and of 
+course 640x480 16 color) and no others.  Everybody gets just one monitor, unless 
+you buy special PCI cards.  Everybody gets two speakers, a headphone, a mic, a 
+webcam and touch scrn.  We make the audio one sample rate and one sample size, 
+but TempleOS still gets just a square wave.  (HD Audio is really screwed-up and 
+requires complicated artificial intelligence, just to route output to speakers.)
+
+The Standard Temple IBM PC will be a full-sized tower.  Perhaps, stain-glass 
+will decorate the case because God is sentimentally attached to stained-glass.  
+We should set the size at exactly 2.5 feet by 1.5 feet by 1.5 feet as in the 
+Exodus,25:10-10 for all time.  If there is extra room, make a storage shelf for 
+DVDs.  We do not want a race-to-the-bottom, shrinking the size.  Instead of 
+making it smaller, make it more powerful.  We want to remove all cost pressure 
+from making things small.  It must have a CD/DVD/Blu-ray drive.  The vision is 
+CD/DVDs used for a library of games, not installed on the hard-drive.  We need a 
+network connection, possibly implemented as a super-simple high speed serial 
+device.  What about standard monitor and speakers?  The C64's success was 
+partially due to wide spread, completely standard, hardware.  I think TempleOS 
+will not do bad block devices, so we need a hard drive, not just NV-memory or 
+SSD.
+
+TempleOS will have the priority over Windows or Linux on hardware decisions.  We 
+could make it heterogenious multicore.  I think we want 16 non-hyperthreaded 
+cores.  Core#0 is the only full-featured core needed.  The other cores will have 
+long mode, but not some of these: real mode, protected mode, ring-3, paging, 
+interrupts, in/out port instructions, SSE instructions,  MMX instructions.
+
+God said Intel should do a simulation of heat produced by gates and try 
+spreading-out the heat producing gate circuits on the chip.
+
+God said Linux's Wine should replace Windows.  We will install a standard 
+software set-up on all Standard Temple IBM PC's.
+
+
+                                     Usage
+
+TempleOS is primarily for user developers, like the Commodore 64 was.  I created 
+a total of 50 Meg of content over ten years, so you shouldn't need much room, 
+either.  The installed hard drive space should stay small because the resolution 
+is low, multimedia is banned, 3rd party libraries are banned, and applications 
+can be distributed with ISO files or DVDs.
+
+The ROM will have a command that copies the ROM onto the hard drive, creating 
+identical C and D partitions, so you can have fun modifying TempleOS.  You will 
+have confidence you can fix it easily if you break it.  It should be able to run 
+everything from just the ROM, too.  You will need to specify a /Home directory 
+that is not in the ROM, but on the hard drive. 
+
+The standard set-up will be a C primary drive and a D back-up drive.  Keep the 
+size on each hard drive under 512 Meg and periodically copy all of C to D, so 
+they stay mirrored.  The file manager and other programs read the entire 
+directory structures, so too many files causes problems (unbearably slow).  
+Third party software should be distributed as ISO files or DVDs, like 
+TextAdventure.ISO.  No 3rd party libraries are permitted because they circumvent 
+the intent of the 100,000 line of code limit which is keeping it cognatively 
+small enough to see the light at the end of the tunnel and easily master 
+everything.  Therefore, 3rd party ISO files must bring all required software 
+components with them, except what is found in the TempleOS ROM.
+
+Having all your 3rd party software on separate DVDs or ISO files and TempleOS 
+running from a ROM, keeps it delightfully simple so you have complete 
+understanding of what is going on.  You will have complete confidence and it 
+will be a joy to use.  3rd party applications can store saved data files into 
+your /Home hard drive directory.
+
+The Temple PC will stay unchanged for seven years at a time.  The Bible speaks 
+of a seven year release in Deuteronomy,15:1.  The Commodore stayed unchanged for 
+many years and people became intimately familiar with every aspect.
+
+
+
+I thought 2.5' x 1.5' x 1.5' was ridiculously big, but it looks like it is 
+reasonable for super-cooled refrigeration systems!
+
+
+                                  Version 2.0
+
+
+ +The Standard Temple IBM PC V2.0 will be released seven years after V1.0. Each +unit will have a full, uncut, silicon wafer. V2.0 will be sold, unchanged, for +seven more years, like a Commodore 64. + +* "Commodore 64" is a trademark owned by Polabe Holding NV. +* "Linux" is a trademark owned by Linus Torvalds. +* "Windows" is a trademark owned by MicroSoft Corp. +
+ diff --git a/public/Wb/Home/Src/Home/Doc/Strategy.DD.HTML b/public/Wb/Home/Src/Home/Doc/Strategy.DD.HTML new file mode 100755 index 0000000..d73c56f --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Strategy.DD.HTML @@ -0,0 +1,138 @@ + + + + + + + + + + + +
+                        Decisions Making TempleOS Simple
+
+Everybody is obsessed, Jedi mind-tricked, by the notion that when you scale-up, 
+it doesn't get bad, it gets worse.  They automatically think things are going to 
+get bigger.  Guess what happens when you scale down?  It doesn't get good, it 
+gets better!
+
+I limited it to 100,000 lines of code, forever!  I never need a linker or make 
+utility and I can use small labels.
+
+People mock Bill Gates for, "640K should be enough."  I say, "2Gig for code 
+should be enough."  The same people who mock Bill Gates are probably just like 
+the black woman who sued for a trillion dollars.
+
+My Dad worked on converting the Titan missile to the Gemini Mission rocket.  It 
+had to be "man-rated".  You can bet that everything got an order of magnitude 
+more complexity and documentation.  My vision is a souped-up C64, not a 1970's 
+mainframe; a kayak, not a Titanic.
+
+Linux is a semi-tractor -- you need professional drivers for 20 gears.  Linux 
+has file permissions.  Common people are hurt by file permissions.
+
+Windows is a car.
+
+TempleOS is a motorcycle -- if you lean-over too far, a motorcycle will crash.  
+Don't do that!  There are no side air bags on a motorcycle.  DOS and C64 had no 
+memory protections and ran in ring-0, with no security.  This saves an order of 
+magnitude complexity.
+
+Linux and Windows are general purpose operating systems.  They attempt to do any 
+task you want.  TempleOS cherry-picks tasks and is designed to do the same 
+things a C64 did.  This saves and order of magnitude complexity.  For example, 
+the RedSea file system allocates just contiguous files -- you load and save 
+whole files at once.  A benefit is this allows compression.  Also, TempleOS does 
+not do networking or multimedia.  In theory, memory will fragment with lots of 
+big files.  The system would fall to pieces with multimedia, but God said 
+640x480 16 color is a permanent covenant like circumcision.
+
+A three bttn mouse is like a leg you cannot put weight on.  TempleOS just does 
+hardware everybody has, with no divergent code bases for each machine's custom 
+hardware.  There is one graphics driver instead of 50 for different GPUs.  This 
+saves an order of magnitude complexity and makes for a delightful API, so 
+developer's code is not like a frayed rope end.
+
+
+
+* Everything runs in kernel, ring 0, mode.
+
+* One memory map for all tasks on all cores with virtual addresses set equ to 
+physical, just as though paging is not used.
+
+* One platform -- x86_64 PC's, no 32-bit support.
+
+* No security or cryptography.
+
+* No networking.
+
+* Least (greatest) common denominator hardware support.  Mostly, one driver for 
+each device class.  I can't be in the business of different drivers.  
+Compatibility is the greatest challenge for PC operating systems.  Disk code 
+does not use interrupts, avoiding compatibility risks.  PS/2 keyboard/mouse is 
+used instead of USB, also more compatible.
+
+* 640x480 16 colors.  Updates whole scrn at 30 fps, optimized for full scrn 
+games where InvalidRectangles are counter-productive.
+
+* One font, 8x8.  Text and graphic layers done in software with text normally on 
+an 8x8 grid.  It can run in Text mode if graphic initialization fails.
+
+* Compiler extends all values to 64-bit when fetched and does only 64-bit 
+computations intermediately.  Assembler has minimal 16-bit support, good enough 
+for compiling boot loaders.
+
+* No object files.  Use JIT.
+
+* Whole files are processed almost exclusively, allowing compression.
+
+* One language and compiler for command-line, scripts, songs, automations and 
+code.
+
+* One editor/word processor/browser for the command-line window, source code, 
+documentation browser, dialog forms.
+
+* No child windows.  One window per task.  Bttns are widgets, not child windows. 
+ There are child tasks, however.
+
+* No distinction between thread, process or task.
+
+* The Scheduler is for home systems.  It is not preemptiove.  Disk requests are 
+not broken-up, so sharing is bad.  It's wonderfully simple.
+
+* MultiCore is done master/slave, instead of SMP.  Core0 applications explicitly 
+assigns jobs.  Locks are present allowing multicore file, heap, and hardware 
+access, though.
+
+* Sound has single-voice 8-bit signed MIDI-like samples.
+
+* All tasks have a heap and a sym table.  Scope is that of environment vars in 
+other operating systems.  As text is typed at the command line or you run 
+programs by #includeing them, the syms go in the table.  If a sym is not found, 
+the parent task's table is checked.  The father of all tasks has the API syms 
+you'll need waiting in it's table.  No need to #include headers.
+
+* No need for namespaces -- scoping occurs automatically based on task symbol 
+table hierarchy with the Adam Task's symbol system-wide global.
+
+* Sometimes, I cut corners in the interest of keeping the code beautiful.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Streams.DD.HTML b/public/Wb/Home/Src/Home/Doc/Streams.DD.HTML new file mode 100755 index 0000000..15310a0 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Streams.DD.HTML @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+There are no streams in the traditional sense.  The cmd line output gets sent to 
+the cursor location of a document being edited and by using cursor keys, text 
+can be injected all over the document.  Sprites can be injected and are not 
+serialized!  Furthermore, the input can come from triggering macro widgets.  See 
+Doc Overview and Doc Routines.
+
+If you had a remote term and sent key Scan Codes, the user would press <CTRL-m> 
+to access his Personal Menu to trigger his macros.  However, the local 
+~/PersonalMenu.DD might differ from the remote, causing loss of sync between 
+local and remote sessions.  Also, the window size of local and remote might 
+differ, so word-wrapped text would be different.  Injecting output text with 
+different windows sizes would cause remote and local documents to not be in 
+sync.
+
+See Char Overview and Char Routines.
+
+You can send characters into StdIn.  See In(), XTalk() and InFile.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/TOSZ.DD.HTML b/public/Wb/Home/Src/Home/Doc/TOSZ.DD.HTML new file mode 100755 index 0000000..03c6dcb --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/TOSZ.DD.HTML @@ -0,0 +1,43 @@ + + + + + + + + + + + +
+                               Linux TOSZ Utility
+
+
+TOSZ [-ascii] filename
+
+Will uncompress a single file from within Linux.  The -ascii flag will convert 
+the irregular TempleOS ASCII 5 and ASCII 31 characters to spaces.  (ASCII 5 is 
+used to mark the cursor pos and ASCII 31 is used for shifted space characters 
+and will cause problems unless you convert them.)
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/TextBase.DD.HTML b/public/Wb/Home/Src/Home/Doc/TextBase.DD.HTML new file mode 100755 index 0000000..818c7d7 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/TextBase.DD.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+gr.text_base must be updated 30fps in your Fs->draw_it() callback.  You probably 
+want GrPrint() or just Print().  The DolDoc code takes care of plotting text to 
+gr.text_base.
+
+Bits 0-7        8-Bit ASCII Scrn Code
+Bits 8-11       Foreground color
+Bits 12-15      Background color
+Bits 16-20      Signed X pos shift val
+Bits 21-25      Signed Y pos shift val
+Bit  28         Blink
+Bit  29         Inverted (Swap foreground and background)
+Bit  30         Sel (XOR colors with FF)
+Bit  31         Underline
+
+GrUpdateTaskWin() calls DocUpdateTaskDocs() which calls DocRecalc() where the 
+document text is plotted into gr.text_base.  Then, GrUpdateTextBG() and 
+GrUpdateTextFG() render the gr.text_base onto gr.dc2, a raw graphic bitmap.
+
+See ::/Demo/Games/Maze.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/TimeCycles.DD.HTML b/public/Wb/Home/Src/Home/Doc/TimeCycles.DD.HTML new file mode 100755 index 0000000..49fcea7 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/TimeCycles.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Intel/AMD have an inst that returns the num of CPU cycles since boot.  This is 
+not a steady, calibrated real time value.  TempleOS measures it and you can 
+convert with cnts.time_stamp_freq, a value continuously calibrated from other 
+cnts.
+ diff --git a/public/Wb/Home/Src/Home/Doc/TimeDate.DD.HTML b/public/Wb/Home/Src/Home/Doc/TimeDate.DD.HTML new file mode 100755 index 0000000..ef1860e --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/TimeDate.DD.HTML @@ -0,0 +1,37 @@ + + + + + + + + + + + +
+TempleOS uses a 64-bit value, CDate, for date/time.  The upper 32-bits are the 
+days since Christ.  The lower 32-bits store time of day divided by 4 billion 
+which works out to 49710ths of a second.  You can subtract two CDate's to get a 
+time span.
+
+Use CDATE_FREQ to convert.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/TimeHPET.DD.HTML b/public/Wb/Home/Src/Home/Doc/TimeHPET.DD.HTML new file mode 100755 index 0000000..6a20ce3 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/TimeHPET.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+The HPET, high precision event timer, is read with HPET() and has a frequency of 
+cnts.HPET_freq.  A typical freq value is 14.3 Mhz  It might not be available on 
+all systems.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/TimeJiffy.DD.HTML b/public/Wb/Home/Src/Home/Doc/TimeJiffy.DD.HTML new file mode 100755 index 0000000..02053c9 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/TimeJiffy.DD.HTML @@ -0,0 +1,38 @@ + + + + + + + + + + + +
+One jiffy is one time slice.  cnts.jiffies returns time slices since boot.
+
+SysTimerRead reads the timer ticks since boot.  It's not as fast as GetTSC.
+
+Use JIFFY_FREQ to convert cnts.jiffies.
+
+Use SYS_TIMER_FREQ to convert SysTimerRead.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Tips.DD.HTML b/public/Wb/Home/Src/Home/Doc/Tips.DD.HTML new file mode 100755 index 0000000..2537b90 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Tips.DD.HTML @@ -0,0 +1,280 @@ + + + + + + + + + + + +
+                                      Tips
+
+* Turn-off or reboot (<CTRL-ALT-DEL>) at any time, except during disk writes.  
+Writes are not cached. 
+
+* Use Seed() and the cmd line to switch Rand() to non-timer mode and replay 
+games you like.
+
+* 64-bit values are most efficient for the compiler.
+
+* See Key Map for a list of defined keys.  Define your own keys in MyPutKey().  
+See Keyboard Devices.
+
+* <ALT-m> maximizes a window.  <ALT-SHIFT-w> closes AutoComplete.  <ALT-w> 
+brings back AutoComplete.  <ALT-v> vertically tiles windows.  <ALT-h> 
+horizontally tiles windows.  The ALT keys are defined in ~/HomeKeyPlugIns.HC.  
+You can customize them.
+
+* If you make changes to TempleOS files in your /Home directory, generally you 
+reboot to make them take effect.  (You don't compile anything.)  You should have 
+two TempleOS partitions on your hard drive because a syntax error in a start-up 
+file will make the partition unbootable.  Boot to the second partition or boot 
+to a standard TempleOS CD/DVD and use Mount() to mount your hard drive.
+
+* I copy my files to a mirrored ident partition, periodically with CopyTree() 
+commands in scripts.  I do merge commands with a menu entry like this:
+Merge(\"C:/*\",\"D:/*\",\"+r+d\"); to check my changes.
+
+* <CTRL-m> at the cmd line to access your PersonalMenu.  Place macros there with 
+<CTRL-l>, or icon-like sprites with <CTRL-r>.  Use the Pop-Up option on macros 
+to Spawn() a task to run a file.  It dies when it is finished.  This returns mem 
+to the system.  Be sure to press <CTRL-s> to save your macro/menu area after 
+making changes.
+
+* You can use ans in cmd line expressions.  It holds the res the last cmd line 
+operation.  You can use the cmd prompt as a calculator by just entering 
+expressions like 1+2*3;.  F64 ress can be accessed with ansf.
+
+* Use the PullDown menu at the top of the scrn to learn commands, or for finding 
+the keyboard controls to games.
+
+* You can adjust the mouse movement rate by setting global vars in your start-up 
+file.  See mouse scale.
+
+* You can set your local time zone by setting the local_time_offset global var 
+in a start-up file.  It's units are CDATE_FREQ.  See local time.
+
+* <CTRL-SHIFT-L> in the editor to reindent a HolyC function or renumber an asm 
+routine's local labels.
+
+* You can use filter_lines in the editor text search form (<CTRL-f>) to 
+temporarily display just lines near each match.  A value of filter lines set to 
+5 will display lines within 5 lines of matches.  Then, you can do another find 
+to a different string and achieve a AND search.  When finished, press <ESC>.
+ 
+* You can recompile and reinstall the kernel with BootHDIns().  You'll probably 
+want to make a function for recompiling that uses the In() function to answer 
+the cfg questions.  See my technique Cfg Strs, Update Funs.
+
+* Scale2Mem(min,max,limit=2*1024*1024*1024) can be used for cfg questions when 
+recompiling.  The BootHDIns() cfg prompts accept expressions, not just numbers.  
+The dft disk cache is Scale2Mem(0x80000,0x8000000).
+
+* You can permanently disable AutoComplete commenting-out ACInit() in 
+~/HomeSys.HC.
+
+* Boolean expressions not in if stmts don't have short circuit logic and are 
+compiled inefficiently.
+
+* You can use progress1-progress4 in your programs for whatever you like.  
+They're just global vars that are shown on the wallpaper.  The original intent 
+was to indicate how far along operations were.  There's no coordination, so 
+different apps might interfere.  I use them most for debugging--just values 
+easily viewed.  See ::/Demo/Progress.HC.
+
+* Use DocMax() to adjust the size of the cmd line buf.  It counts CDoc entries, 
+not lines.
+
+* Many data structures have a user_data member.  Those are available for you to 
+store a data item, for convenience.  CTask, CDocEntry and CDirEntry have them.  
+You shouldn't encounter conflicts with TempleOS using them.
+
+* If, for some strange reason, you wanted to reduce mem usage, make a smaller 
+disk cache when you recompile the kernel; disabling AutoComplete; Specify 
+smaller stk sizes when doing Spawn(), chang MEM_DFT_STK, and using DocMax() to 
+reduce the cmd line buffer size.
+
+* Filenames ending in ".Z" will be automatically compressed and uncompressed 
+when read or written.  The compression method is not supported by other 
+operating systems.  You can store files uncompressed by Move()ing them to a 
+filename not ending in ".Z".  See ::/Doc/TOSZ.DD if you want to uncompress while 
+in Linux.
+
+* Merge() can be used to see what's changed.  The +d flag will show differences 
+of files which have changed and allow you to merge code.  (The +r flag will 
+recurse.)
+
+* There is a utility LinkChk() which will check for broken links in 
+documentation.
+
+* You can use Option(OPTf_WARN_PAREN,ON) to find unnecessary parentheses in 
+code.
+
+* You can use Option(OPTf_WARN_DUP_TYPES,ON) to find unnecessary local var type 
+stmts.
+
+* Option(OPTf_ECHO,ON) can be placed in StartOS.HC to echo start-up scripts.
+
+* Use Plain() to edit a plain text file.  You'll need this if your file has $'s. 
+ Use the ToDolDoc() utility to convert plain text to DolDoc's by doubling $'s.
+
+* Use Silent() to disable scrn text output.
+
+* Grab-scroll any window at any time with {CTRL-LEFT-MOUSE-DRAG}.  Null 
+grab-scrolling with {CTRL-RIGHT-MOUSE}.
+
+* Use <CTRL-ALT-z> to zoom-in and <CTRL-ALT-SHIFT-Z> to zoom-out.  You can 
+scroll by moving to the edge of the window.  Set gr.continuous_scroll to TRUE if 
+you want. 
+
+* Use <CTRL-ALT-g> and <CTRL-ALT-SHIFT-G> to display a grid on the scrn.
+
+* Use <CTRL-ALT-a> to enter an extended ASCII char.
+
+* Use <CTRL-ALT-f> to toggle between Std Font and Cyrillic Font.
+
+* Use <CTRL-ALT-s> will capture the scrn as a sprite on the clip.  You can save 
+the cmd line doc as text with <CTRL-a>.
+
+* You can save a sprite as a .GR file in <CTRL-r> on the Sprite BitMap Menu.
+
+* You can eye-dropper colors in the <CTRL-r> sprite editor by pressing 'c'.  
+Press 't' for transparent.
+
+* There are handy functions--F(),R(),FD() and RD() which are defined in 
+~/HomeWrappers.HC.  You are encouraged to change them and add more.  They will 
+perform find-and-replace operations accross multiple files.  The +l flag is 
+particularly useful since it limits to whole labels.  The +lb and +la flags 
+limit to whole labels just before or after.  You are encouraged to add or modify 
+handy wrapper functions to make cmd line operations easier.
+
+* When using Find() while modifying code, work from the bottom-up so that line 
+numbers are correct.  If you work top-down, then inserting or deleting lines 
+causes the lower file links will be incorrect.
+
+* You can save files after making changes, anytime you are within the editor, 
+like when viewing help/macro files.  <CTRL-a> saves as, <CTRL-s> saves with the 
+same name in the scrolling title bar.  Hitting <ESC> will exit and save.  (<SHIF
+T-ESC> will abort).  You can save the cmd line window to a file, too, since 
+you're actually in the editor when you're at the cmd line.
+
+* When using <CTRL-l> to insert links in documents, you can usually leave the Ta
+g Text blank and it will be filled-in automatically based on other entries.
+
+* There is a feature of the precompiler that allows code to be executed in the 
+middle of compilation and data inserted into the compilation stream.  Click here 
+for an example: #exe {.
+
+* If you output to the cmd line and wish to allow users to scroll around and 
+view data, you can use View().
+
+* Use View() in Pop-up macros to linger until the user presses <ESC> or <SHIFT-E
+SC>.
+
+* You can access the word under the cursor at ac.cur_word.
+
+* You can reactivate AutoComplete after closing it by pressing <CTRL-Fun Key> or 
+<ALT-w> if you have it defined.
+
+* <CTRL-SHIFT-T> to toggle to/from plain text just the CDoc cmd under the 
+cursor.  See ::/Demo/DolDoc/TextDemo.HC.
+ 
+* If you toggle to plain text when you are working with graphics in a document, 
+you can add duplicate entries for sprites by entering a $SP...$ cmd with the 
+same num.
+
+* If you toggle to plain text when working with graphics, you can add a str to 
+the $SP...$ entry to keep track of it.  Try $SP,"<2>",BI=2$ where '2' is the 
+sprite num.
+
+* I use spaces-to-tab operations on all my src files to keep them small.  You 
+have to be careful, though, because spaces in strings will be converted.  I use 
+<SHIFT-SPACE> ' ' in such cases.  See S2T() for spaces-to-tabs.
+
+* You can edit an existing sprite by putting the cursor on it and pressing <CTRL
+-r>.
+
+* When editing a sprite, you can cut and paste the elements in the sidebar text 
+list window.
+
+* I recommend keeping CSprite in vect format until you are done creating them, 
+so you can edit the ctrl points.  Then, convert them to bitmaps, so the flood 
+fills work well.  If you are doing interpolation, however, they must be vect.
+
+* GrFloodFill() is slow.  GrRect() is fast.
+
+* You can customize the wallpaper.  See ::/Demo/Graphics/WallPaperFish.HC.
+
+* Your RAM disks will not be reformated when you reboot if the memory location 
+has not changed and it finds the disk intacted.
+
+* try{} catch{} in a function will cause all vars to be non-reg.
+
+* Using a sub-int array, i.u8[3], for example, will force a local var to 
+non-reg.
+
+* You can delete the ~/Registry.HC.Z file.  The policy is that deleting it will 
+restore defaults.  It is a text doc, if you want to edit it.  Be careful of tree 
+indentations.
+
+* Study ::/Adam/Opt/Utils/MemRep.HC and WallPaper() to learn how the system 
+resources are put together.
+
+* The editor's sel-text mechanism allows for disjoint portions of sel text.  
+This is a feature, not a bug -- you can cut-and-paste disjoint text.
+
+* cnts.time_stamp_freq is continuously calibrated.  Be careful because 
+expressions might decrease.  Take a snap-shot, like this: timeout=GetTSC+
+cnts.time_stamp_freq x seconds; and compare against GetTSC().  I recommend just 
+using tS or cnts.jiffies.
+
+* Use HeapLog(), HeapLogAddrRep() and HeapLogSizeRep() to find leaks.  Don't be 
+confused by CDoc allocations.  Those are generated when text is written to the 
+cmd line buffer.
+
+* For advanced heap debugging, play with _CFG_HEAP_DBG.  You're on your own.
+
+* You can use Type() to display .GR files.
+
+* Use Man() to jump to short sym name src code.
+
+* Use Fix() to edit and fix the last compiler err.
+
+* You can use <CTRL-SHIFT-L> to do a check for compile errors.
+
+* You can use DocOpt() to optimize links. (Mostly just removes .Z)
+
+* ZipRep() can highlight src files with lots of redundancy.
+
+* With start/end, common trailing code is fast.  Common leading code is slow.
+
+* The first line of the Psalmody HolyC song files is a comment with a category 
+recognized by JukeBox().  The categories are "no nothing", "has words", "has 
+graphics", or "special".  The third character in the song comment is a digit 
+rating number, shown in JukeBox().  You can set the song rating in JukeBox() by 
+pressing 0-9.  You can press <DEL> to delete songs.
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Transform.DD.HTML b/public/Wb/Home/Src/Home/Doc/Transform.DD.HTML new file mode 100755 index 0000000..a030491 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Transform.DD.HTML @@ -0,0 +1,56 @@ + + + + + + + + + + + +
+CDC's have a 4x4 matrix for rotating, scaling, skewing and shifting in 3 
+dimensions.  To make the graphics routines use the transform, you must set the 
+DCF_TRANSFORMATION flag.
+
+The matrix consists of ints that have been scaled 32 bits (GR_SCALE).  See 
+::/Demo/Lectures/FixedPoint.HC to learn why.
+
+See Mat4x4IdentEqu(), Mat4x4IdentNew(), Mat4x4Equ() and Mat4x4New().  See 
+Mat4x4RotX(), Mat4x4RotY(), Mat4x4RotZ() and Mat4x4Scale() to rotate about axes 
+and scale.  Combine them with Mat4x4MulMat4x4Equ()/Mat4x4MulMat4x4New() and 
+assign them to the CDC.dc with DCMat4x4Set().  See ::/Demo/Graphics/Box.HC.
+
+You can rotate single points using Mat4x4MulXYZ().
+
+The 4th dimension allows a neat trick where you can place pos shifts 
+(translations), into the matrix and Mat4x4MulMat4x4Equ/Mat4x4MulMat4x4New them 
+to combine rotation/shift operations.  Normally, you can't combine pos shift 
+operations.  See Mat4x4TranslationEqu() and ::/Demo/Graphics/Transform.HC.
+
+Finally, CDC's have an x, y and z which is an additional shift (translation).
+
+The transformation is implemented as a callback on the CDC's transform() member. 
+ The default transform() callback is DCTransform().  See 
+::/Demo/Games/Talons.HC or ::/Demo/Games/CastleFrankenstein.HC to see how to 
+change the transform() callback for foreshortening.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Welcome.DD.HTML b/public/Wb/Home/Src/Home/Doc/Welcome.DD.HTML new file mode 100755 index 0000000..404fb6d --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Welcome.DD.HTML @@ -0,0 +1,278 @@ + + + + + + + + + + + +
+                              Welcome to TempleOS
+
+TempleOS is a x86_64, multi-cored, non-preemptive multi-tasking, ring-0-only, 
+single-address_mapped (identity-mapped), operating system for recreational 
+programming.  Paging is almost not used.
+
+The people whom can most benefit are:
+  * Professionals doing hobby projects
+  * Teenagers doing projects
+  * Non-professional, older-persons projects
+
+Simplicity is a goal to keep the line count down, so it's easy to tinker with.  
+As it turns-out, simplicity makes it faster in some ways, too.  It never 
+switches privilege levels, never changes address maps, tends to load whole 
+contiguous files and other, similar things which boost speed.  It's only 80,849 
+lines of code including the kernel, the 64-bit compiler, the graphics library 
+and all the tools.  More importantly, it's designed to keep the user's line 
+count down -- you can do a Hello World application in one line of code and can 
+put graphics on the scrn with a three line program!
+
+It's a kayak, not a Titanic -- it will crash if you do something wrong.  You 
+quickly reboot, however.  DOS and the 8-bit home computers of the 80's worked 
+fine without memory protection and most computers in the world -- the embedded 
+ones -- operate without protection.  The resulting simplicity of no protections 
+is why TempleOS has value.  In facts, that's the point of TempleOS.  See the 
+TempleOS Charter.
+
+Conventional thinking is "failure is not an option" for general purpose 
+operating systems.  Since this OS is used in addition to Windows or Linux, 
+however, failure is an option -- just use Windows or Linux if you can't do 
+something.  I cherry-pick what it will and won't do, to make it maximally 
+beautiful.  The following applications more or less form a basis that spans the 
+range of use that TempleOS is intended for:
+
+/Demo/Games/BattleLines.HC
+/Demo/Games/BigGuns.HC
+/Demo/Games/BlackDiamond.HC
+/Demo/Games/BomberGolf.HC
+/Demo/Games/CastleFrankenstein.HC
+/Demo/Games/CharDemo.HC
+/Demo/Games/CircleTrace.HC
+/Demo/Games/Collision.HC
+/Demo/Games/Digits.HC
+/Demo/Games/DunGen.HC
+/Demo/Games/Talons.HC
+/Demo/Games/ElephantWalk.HC
+/Demo/Games/FlapBat.HC
+/Demo/Games/FlatTops.HC
+/Demo/Games/Halogen.HC
+/Demo/Games/MassSpring.HC
+/Demo/Games/Maze.HC
+/Demo/Games/RainDrops.HC
+/Demo/Games/RawHide.HC
+/Demo/Games/Rocket.HC
+/Demo/Games/RocketScience.HC
+/Demo/Games/Squirt.HC
+/Demo/Games/TheDead.HC
+/Demo/Games/TicTacToe.HC
+/Demo/Games/TreeCheckers.HC
+/Demo/Games/Varoom.HC
+/Demo/Games/Wenceslas.HC
+/Demo/Games/Whap.HC
+/Demo/Games/Zing.HC
+/Demo/Games/ZoneOut.HC
+/Apps/Psalmody/Examples/childish.HC
+/Apps/Psalmody/Examples/night.HC
+/Apps/Psalmody/Examples/prosper.HC
+
+Two things to know about TempleOS are that tasks have MAlloc/Free heap memory, 
+not applications, and tasks have compiler symbol tables that persist at a scope 
+like environment variables in other operating systems, and the symbols can 
+include functions.
+
+For other operating systems, I hated learning one language for command line 
+scripts and another for programming.  With TempleOS, the command line feeds 
+right into the HolyC compiler, line by line, and it places code into memory it 
+MAlloc()s.  The compiler is paused at the command line, waiting for input.  
+Naturally, you #include a program to load it into memory and, usually, start it.
+
+During the boot process, many files get compiled before you have access to the 
+command line.  (Don't worry, booting takes only two seconds.)  All the header 
+declarations for the operating system are compiled and are available for use in 
+your programs without needing to #include them.  Everything is truly compiled to 
+native x86_64 machine code, nothing is interpreted and there is no byte code.
+
+Statements at the global scope -- outside the scope of functions -- execute 
+immediately.  There is no main() function.  Instead, you give meaningful names 
+to what would be main() functions and you invoke them by calling them with a 
+statement in the global scope, usually at the bottom of your file.
+
+I started with C syntax, but didn't like the command line for a directory 
+listing looking like this:
+
+>Dir("*.*",FALSE);
+
+So, I added default args from C++ and it looked like this:
+
+>Dir();
+
+I didn't like that, so I made parentheses optional on calls with no args and it, 
+now, looks like this:
+
+>Dir;
+
+The syntax change created an ambiguity when specifying function addresses, like 
+for calling QSort().  To resolve it, I  made a '&' required in front of function 
+names when specifying an address of a function, which is better anyway.
+
+Once I was no longer using standard C/C++ syntax, I decided to change everything 
+I didn't like and call it HolyC.  Here are the new operator precedence rules.  
+It's Biblical!  See Luke,5:37.
+
+There are no object files in TempleOS and, normally, you don't make executable 
+files either, but you can.  That's known as Ahead-of-Time compilation.  Instead, 
+you Just in Time compile.
+
+Tasks have no priority and are never removed from the queue.  Instead, they 
+often poll whatever they are waiting on and swap-out.  (Swapping tasks takes 
+half a microsecond and does not involve disk activity or memory maps.)  See 
+Scheduler.  Polling keeps it simple.  It might be a problem if you had lots of 
+tasks busy, which rarely happens on a home computer.  The order of the tasks in 
+the queue determines front-to-back window order.
+
+The FAT32 filesystem is supported to makes exchanging files with a dual booted 
+other operating system easy and there is the simple, 64-bit TempleOS RedSea 
+filesystem.  The RedSea has allocation bitmap for clus and all files are stored 
+contiguously.  You can't grow files.
+
+TempleOS is geared toward reading and writing whole files.  Since whole files 
+are processed, compression is possible.  Filenames ending in ".Z" are 
+automatically compressed or uncompressed when stored and fetched.  TempleOS does 
+support direct block random access into files, however -- FBlkRead() and 
+FBlkWrite().
+
+If a file is not found, ".Z" is added or removed and a search is done, again.  
+There is no PATH, but parent directories are searched when a file is not found.  
+This feature is especially useful for default account files.
+
+The graphic resolution is poor, 640x480 16 color, but God said it was a covenant 
+like circumcision.  Also, that's all I feel comfortable with without GPU 
+acceleration supported.  A 1600x1200x24 bit scrn takes 37 times more memory, 
+implying 37 times the CPU power.  Also, a fixed size keeps it simple with 
+everybody machine having the same appearance.  Look on the bright-side -- you 
+won't spend as much time twiddling pixels for your game art and you'll have tons 
+of CPU power available, especially with multicore systems.
+
+TempleOS is for hobbyist programmers on single user (at a time) home computers, 
+not mainframes or servers.  The focus task is all-important so symmetrical 
+multiprocessing is almost pointless.  Why does it matter running two apps at the 
+same time twice as fast when you really want to run one faster?  You could say 
+TempleOS does master/slave multiprocessing.  The anticipated use for multicore 
+is primarily putting graphics on the scrn.  Hardware graphics acceleration is 
+not used, so this is possible.  See TempleOS MultiCore.
+
+There is no distinction between the terms task, process or thread.  All have a 
+task record, CTask, pointed to by the FS segment reg and are accessed with Fs-> 
+while Gs-> points to a CCPU for the current CPU core.  Each task can have just 
+one window, but a task can have children with windows.  (The segment regs are 
+just used as extra regs -- there is nothing segmented about TempleOS' memory.)  
+It is approximately the case that TempleOS is multi-threading, 
+single-processing.
+
+In TempleOS, Adam Task refers to the father of all tasks.  He's never supposed 
+to die.  Since tasks inherit the symbols of parents, system-wide stuff is 
+associated with Adam.  His heap is like kernel memory in other operating 
+systems.  Since Adam is immortal, it's safe to alloc objects, not tied to any 
+mortal task, from Adam's heap.  He stays in a server mode, taking requests, so 
+you can ask him to #include something, placing that code system-wide.  A funny 
+story is that originally I called it the root task and even had a /Root 
+directory :-)  Adam executes ::/StartOS.HC at boot time.
+
+For easy back-ups, place everything you author in your /Home directory and 
+subdirectories.  Then, use CopyTree().  That should make upgrading easy, too.  
+Customizable start-up scripts go in your /Home directory.  The default start-up 
+scripts are in the root directory.  Copy the start-up files you wish to 
+customize into /Home and modify them.  See Home Files.  You can make your own 
+distro that includes everything and is a bootable live CD with 
+::/Misc/DoDistro.HC.
+
+Typically, your usage pattern through the day will be repeatedly left or right 
+clicking on filenames in a cmd line Dir() listing.  You left-click files to edit 
+them and right-click to #include them.  To begin a project, type Ed("filename");
+, supplying a filename.  You can also run programs with <F5> when in the editor. 
+<ESC> to save and exit the file.  You'll need to do a new Dir() cmd, 
+periodically, so make a macro on your PersonalMenu.  Access your PersonalMenu by 
+pressing <CTRL-m>, cursoring until you are on top of it and pressing <SPACE>.
+
+<CTRL-t> toggles plain text mode, showing format commands, a little like viewing 
+html code.
+<CTRL-l> inserts a text widgets.
+<CTRL-r> inserts or edit a graphic sprite resource at cursor location.
+<CTRL-d> brings-up the file manager.  It's pretty crappy.  I find I don't need 
+it very often, believe it or not.
+<CTRL-b> toggles window border.
+
+<ALT-m> maximizes a window.
+<ALT-SHIFT-a> closes AutoComplete.
+<ALT-a> brings back AutoComplete.
+<ALT-v> vertically tiles windows.
+<ALT-h> horizontally tiles windows.
+The ALT keys are defined in ~/HomeKeyPlugIns.HC.  You can customize them.
+
+<CTRL-ALT-t> new terminal window.
+<CTRL-ALT-n> switches to the next window.
+<CTRL-ALT-x> kills a window.
+
+Find() is your best friend.  There's a wrapper function called F() in your ~/Hom
+eWrappers.HC.Z file.  Feel free to make wrapper functions for functions you use 
+often and customize the args.  By the way, Find() or R() can be used to replace 
+strings across multiple files.  You can access Find() using <CTRL-SHIFT-f>.
+
+As you browse code, use the AutoComplete window to look-up functions, etc.  <CTR
+L-SHIFT-F1> (or whatever number) to follow a sym to it's source.  You can browse 
+deeper and deeper.  You go back with <SHIFT-ESC>.
+
+Use the Help & Index or Demo Index to find-out what exists.  Press <F1> for help 
+or use the links on your menu (<CTRL-m>).  Also, look in the /Demo or /Apps 
+directories for inspiration.
+
+Software is distributed as RedSea ISO files.  Burn a CD/DVD, or set your CD/DVD 
+in QEMU, VMware or VirtualBox to the ISO file.  Then, access the 'T' drive.  Or, 
+Mount() the ISO.C file and access the 'M' drive in TempleOS.  It must be a 
+contiguous ISO.C file, so rename it under TempleOS to ISO.C.
+
+Ideally, do not install applications such as games onto your hard drive because 
+we wish to keep hard drive usage low, so the whole 'C' drive can be copied 
+quickly to 'D'.  Also, the FileMgr() <CTRL-d> starts too slowly when there are 
+lots of hard drive files, but that is how we want it.
+
+3rd party libraries are banned, since they circumvent the 100,000 line of code 
+limit in the TempleOS Charter.  All applications must only depend on the core 
+TempleOS files and whatever they bring along in the ISO.  This is similar to how 
+Commodore 64 applications only depended on the ROM.
+
+Create a RedSea ISO file with RedSeaISO().  Send an email to 
+tdavis@templeos.org if you want me to post a link to your TempleOS code in the 
+App Store.
+
+Take Tour
+
+
+* "Linux" is a trademark owned by Linus Torvalds.
+* "Windows" is a trademark owned by MicroSoft Corp.
+* "Commodore 64" is a trademark owned by Polabe Holding NV.
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/WhyNotMore.DD.HTML b/public/Wb/Home/Src/Home/Doc/WhyNotMore.DD.HTML new file mode 100755 index 0000000..0121162 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/WhyNotMore.DD.HTML @@ -0,0 +1,118 @@ + + + + + + + + + + + +
+                                 Why Not More?
+
+If a feature cannot be made to work correctly and consistently, professional 
+companies usually remove the feature.  Because PC hardware is so diverse, 
+getting things to work on all people's computers is really difficult.  For one 
+thing, you practically have to own all the different hardware to write drivers 
+for it.  If a company wanted to sell a PC operating system, they would offer a 
+warranty and, therefore, could not get away with amateur behavior.  TempleOS 
+absolutely requires 64-bit computers, so we leave behind much trouble, but 
+plenty remains.
+
+The PCI bus interface is what modern hardware uses.  Before PCI, life was simple 
+and devices used I/O ports.  After studying PCI Interrupts and attempting to do 
+a HDAudio driver, I came to realize that modern PCI devices require ten times 
+more code and I cannot even come close to making them work on everyone's machine 
+because with PCI devices there are several models to worry about, unlike with 
+the older ISA bus devices which can be done with one driver.
+
+Currently, I have no PCI drivers.  My drivers use I/O ports and operate in ISA 
+bus mode.  At this point, I only have one driver for each type of device and it 
+is delightfully simple that way.  I have one keyboard driver, one mouse driver, 
+one ATA hard drive driver, one ATAPI CD/DVD driver, one VGA 640x480 16 color 
+video driver and one PC Speaker driver.  I use the PIT and HPET timers and 
+PIC Interrupt Controller.  I use  IRQ0 for timer, IRQ1 for keyboard, and IRQ12 
+for mouse.  If IRQ12 is not firing, I am able to poll the mouse.
+
+In the CPU department, I have state of the art 64-bit long mode with multicore 
+support.  I use the APIC and start-up multicore operation.
+
+I have made an incredible accomplishment by getting it to work on practically 
+everyone's computer as long as it is 64-bit and they run inside VMware, QEMU or 
+VirtualBox.
+
+Adding a USB driver would be really ugly with UHCI, EHCI, OHCI, USB1, USB2, 
+USB3, ICH6, ICH7, ICH8, ICH9, ICH10, ICH11, ICH12, boot mode and regular mode 
+for keyboard/mouse and a diversity of HID reports.  It's hopeless.  I could 
+never offer anything but crappy, limited support and it would just add a ton of 
+crappy code that mostly didn't work.  What would I gain?  Nothing.  A keyboard 
+or mouse would not be improved.  Solid State USB drives would be really nice, 
+but it's not going to happen.
+
+The same story is basically true for GPUs, audio, networking and AHCI hard drive 
+drivers.  God said 640x480 16 color was a covenant like circumcision, so the 
+video will never change, even if a Standard PC was made.  If you attempt 
+multimedia, everything will break because memory will get fragmented with huge 
+multimedia files.  Some day, if super-simple high speed serial allows 
+networking, there will be no browser within the 100,000 line limit and, with 
+only 16 colors, the world wide web is not tolerable.  FTP and telnet might be 
+possible, in the far distant future, if they could fit within the 100,000 line 
+limit.  Currently, there are 80,849 lines of code.
+
+I don't stand a chance working on native hardware, anymore.  I could install and 
+run natively on hardware from about 2005-2010.  It requires BIOS's being nice 
+enough to write USB mode PS/2 legacy keyboard/mouse support.  As it turns-out, 
+sometimes the BIOS has PS/2 drivers but purposely disables them, just to be 
+mean.  The CIA and whole industry is trying to mess everything up, on purpose.  
+Perhaps, at a point of sale in a store, a thief could hack a credit card 
+machine.  Therefore, the BIOS companies actually want it difficult to make 
+drivers and purposely make it broken.
+
+The ATA/ATAPI hard drives often can be run with I/O ports if you can find them.  
+lspci -v on Linux or system information on Windows can help you locate the SATA 
+IO ports the hard drive and CD/DVD have.  They no longer are enabled by the 
+BIOS.  It's hopeless.  I'm stuck with very slow drive performance, but it works 
+for everybody.
+
+UEFI is pointless.  If I am forced to run in VMware, QEMU or VirtualBox, they 
+will always support non-UEFI mode.  Without working, native hard drive and 
+CD/DVD drivers, you can't get very far with UEFI on a native install, not to 
+mention SecureBoot.  UEFI is, first of all, redundant.  If non-UEFI works in a 
+virtual machine, supporting UEFI would only be redundant, ugly nasty code.  My 
+compiler does not create an ELF or PE format.  I would have to ruin the beauty 
+of my compiler, which would make me cry many tears.
+
+God talks.  It seems reasonable that I will get to make the rules for the whole 
+industry, in the future when God is announced publically to the World.
+
+I made ::/Doc/Demands.DD.
+
+When the PC was created, they wanted flexibility because they did not know the 
+future.  Now, the industry is mature and it is time to make a 100% standard PC 
+that everybody uses.  ::/Doc/StdTempleOSPC.DD
+
+
+* "QEMU" is a trademark owned by Fabrice Bellard.
+* "VMware" is a trademark owned by VMware, Inc.
+* "VirtualBox" is a trademark owned by Oracle.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Widget.DD.HTML b/public/Wb/Home/Src/Home/Doc/Widget.DD.HTML new file mode 100755 index 0000000..cd751ff --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Widget.DD.HTML @@ -0,0 +1,84 @@ + + + + + + + + + + + +
+                               DolDoc Widget Help
+
+DolDoc is a TempleOS document type.
+
+"Expression" a num or HolyC algebraic term with operators and HolyC syms can be 
+entered.
+"Macro" Most entries can behave like macro entries if you assign them macro 
+strs.
+"InStr" Like a macro except it is an InFile.  You can't have both an in_str and 
+macro text defined.  
+
+Tag Text is the text that will be displayed for the item.  For links, you can 
+leave it blank and the details of the link will be shown.
+Hide means display nothing, making an entry invis.
+
+Left X relative to the left margin.
+Center X relative to the horizontal center of the window.
+Right X relative to the right margin.
+Top Y relative to the top of the window.
+Center Y relative to the vertical center of the window.
+Bottom Y relative to the bottom of the window.
+
+Blink make the text blink.
+Invert make the text inverted.
+Underline make the text underlined. 
+
+Scroll X Length Expression if a value is entered, the text will scroll in an 
+area of this width.
+Y Offset Expression if a value is entered, the text will be shifted vertically 
+by this many pixs, so you can make superscripts or subscripts.
+X Offset Expression if a value is entered, the text will be shifted horizontally 
+by this many pixs.
+
+Tree The item will behave like a tree widget, with this as the root.
+Collapsed The tree or hidden widget will begin collapsed.
+Define Str will substitute a #define or DefineLoad() string for the tag.
+
+Quote Make the res suitable for including in a program, in quotes, especially fo
+rmat entries in class definitions.
+
+X Expression For cursor movements, the horizontal value.
+Y Expression For cursor movements, the vertical value.
+
+PopUp For macro's, run the macro in a PopUp window.  Do this when making a macro 
+to run a program, so it doesn't tie-up memory.
+
+Escape For macro's, send an <ESC> char to exit before running the macro.  
+Without this, the macro runs in the wrong window, usually.
+
+Refresh Data  updates $DA...$ entry continuously.
+
+Html Link  stores a link which will be embedded if you generate a html version 
+of a document with ::/Demo/ToHtmlToTXTDemo/ToHtml.HC.
+
+ diff --git a/public/Wb/Home/Src/Home/Doc/Windows.DD.HTML b/public/Wb/Home/Src/Home/Doc/Windows.DD.HTML new file mode 100755 index 0000000..ec323a2 --- /dev/null +++ b/public/Wb/Home/Src/Home/Doc/Windows.DD.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
+Only tasks on Core0 can have a window and there can be only one window per task. 
+ The window Z-buffer, top-to-bottom order is determined by the order in the task 
+queue, with the WinMgr on the bottom.  A task can have child task popup windows.
+
+ diff --git a/public/Wb/Home/Src/Home/MakeHome.HC.HTML b/public/Wb/Home/Src/Home/MakeHome.HC.HTML new file mode 100755 index 0000000..a081be7 --- /dev/null +++ b/public/Wb/Home/Src/Home/MakeHome.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+//If these are not present in /Home, it uses the version in the root dir.  You
+//can make your own, modified, version of these files in your /Home directory.
+#include "~/HomeLocalize"
+#include "/Adam/Opt/Boot/MakeBoot"
+#include "/Adam/Opt/Utils/MakeUtils"
+#include "~/HomeWrappers"
+MapFileLoad("::/Kernel/Kernel");
+MapFileLoad("::/Compiler/Compiler");
+#include "~/HomeKeyPlugIns"
+#include "~/HomeSys"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Home/Registry.HC.HTML b/public/Wb/Home/Src/Home/Registry.HC.HTML new file mode 100755 index 0000000..a1be755 --- /dev/null +++ b/public/Wb/Home/Src/Home/Registry.HC.HTML @@ -0,0 +1,34 @@ + + + + + + + + + + + +
++] Adam
++] Once
+
+ diff --git a/public/Wb/Home/Src/HomeKeyPlugIns.HC.HTML b/public/Wb/Home/Src/HomeKeyPlugIns.HC.HTML new file mode 100755 index 0000000..2111353 --- /dev/null +++ b/public/Wb/Home/Src/HomeKeyPlugIns.HC.HTML @@ -0,0 +1,233 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 TimeIns()
+{
+  CDate cdt;
+  cdt=Now;
+  "$IV,1$----%D %T----$IV,0$\n",cdt,cdt;
+}
+
+Bool MyPutKey(I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+
+  //See Char for definition of scan codes.
+  //See Key Allocations.
+  //See Keyboard Devices.
+
+  //You can customize keys.  This routine
+  //is called before the main editor
+  //key hndlr DocPutKey().
+  //You can intercept any key.
+
+  //Return TRUE if you completely
+  //handled the key.
+  I64 i;
+  U8 *st1,*st2;
+  if (sc&SCF_ALT && !(sc&SCF_CTRL)) {
+    switch (ch) {
+      case 0:
+        switch (sc.u8[0]) {
+          case SC_F1:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTPURPLE");
+              else
+                "$LTPURPLE$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /PURPLE");
+              else
+                "$PURPLE$";
+            }
+            return TRUE;
+          case SC_F2:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTRED");
+              else
+                "$LTRED$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /RED");
+              else
+                "$RED$";
+            }
+            return TRUE;
+          case SC_F3:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTGREEN");
+              else
+                "$LTGREEN$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /GREEN");
+              else
+                "$GREEN$";
+            }
+            return TRUE;
+          case SC_F4:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Default Color");
+              else
+                "$FG$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /BLUE");
+              else
+                "$BLUE$";
+            }
+            return TRUE;
+          case SC_F7:
+            if (!(sc&SCF_SHIFT)) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Cmd /TimeIns");
+              else
+                TimeIns;
+            }
+            return TRUE;
+        }
+        break;
+      case 'a':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete On");
+        else
+          AutoComplete(ON);
+        return TRUE;
+      case 'A':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete Off");
+        else
+          AutoComplete;
+        return TRUE;
+      case 'h':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileHorz");
+        else
+          WinTileHorz;
+        return TRUE;
+      case 'm':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinMax");
+        else {
+          WinBorder;
+          WinMax;
+        }
+        return TRUE;
+      case 'v':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileVert");
+        else
+          WinTileVert;
+        return TRUE;
+      case 'l':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Put Link to Cur Pos on Clip");
+        else {
+          ClipDel;
+          st1=FileNameAbs(BIBLE_FILENAME);
+          st2=FileNameAbs(DocPut->filename.name);
+          if (!StrCmp(st1,st2)) {
+            Free(st1);
+            st1=BibleLine2Verse(DocPut->cur_entry->y+1,',');
+            DocPrint(sys_clip_doc,"$LK,\"BF:%s\"$",st1);
+          } else
+            DocPrint(sys_clip_doc,"$LK,\"FL:%s,%d\"$",
+                  st2,DocPut->cur_entry->y+1);
+          Free(st1);
+          Free(st2);
+        }
+        return TRUE;
+      case 'L':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Place Anchor, Put Link to Clip");
+        else {
+          i=RandU32;
+          ClipDel;
+          DocPrint(sys_clip_doc,"$LK,\"<TODO>\",A=\"FA:%s,ANC%d\"$",
+                DocPut->filename.name,i);
+          "$AN,\"<TODO>\",A=\"ANC%d\"$",i;
+        }
+        return TRUE;
+
+        //Ins your own ALT-key plug-ins
+      case '1':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /pi");
+        else
+          'pi';
+        return TRUE;
+      case '2':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /theta");
+        else
+          'theta';
+        return TRUE;
+      case '3':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /phi");
+        else
+          'phi';
+        return TRUE;
+      case '4':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /omega");
+        else
+          'omega';
+        return TRUE;
+      case '9':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Indent 5");
+        else
+          "$ID,5$";
+        return TRUE;
+      case '0':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Unindent 5");
+        else
+          "$ID,-5$";
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+Bool MyPutS(U8 *)
+{
+  return FALSE;
+}
+
+KeyDevAdd(&MyPutKey,&MyPutS,0x20000000,TRUE);
+
+ diff --git a/public/Wb/Home/Src/HomeLocalize.HC.HTML b/public/Wb/Home/Src/HomeLocalize.HC.HTML new file mode 100755 index 0000000..3acc465 --- /dev/null +++ b/public/Wb/Home/Src/HomeLocalize.HC.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+//This makes your keyboard fast
+KbdTypeMatic(0);
+
+//Set Time Zone
+local_time_offset=0*60*60*CDATE_FREQ; //Do daylight savings by hand
+
+//adjust these to set mouse move scale
+ms_hard.scale.x=0.5;
+ms_hard.scale.y=0.5;
+ms_hard.scale.z=1.0; //wheel
+
+//don't change these
+ms_hard.prescale.x=ms_hard.pos.x/ms_hard.scale.x;
+ms_hard.prescale.y=ms_hard.pos.y/ms_hard.scale.y;
+ms_hard.prescale.z=ms_hard.pos.z/ms_hard.scale.z;
+
+
+ diff --git a/public/Wb/Home/Src/HomeSys.HC.HTML b/public/Wb/Home/Src/HomeSys.HC.HTML new file mode 100755 index 0000000..87bea8d --- /dev/null +++ b/public/Wb/Home/Src/HomeSys.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 UserStartUp()
+{//Run each time a user a spawned
+  DocTermNew;
+  Type("::/Doc/Start.DD");
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+  Dir;
+}
+
+U0 SrvStartUp()
+{//Run each time a srv task is spawned.
+  DocTermNew;
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+}
+
+U0 StartUpTasks()
+{
+  CTask *user1,*user2;
+  user1=User;
+  user2=User;
+  WinToTop(user1);
+  WinTileVert;
+  "Boot Time:%7.3fs\n",tS;
+  XTalk(user1,"Cd;#include \"Once\";\n");
+  Silent;       //no output to scrn
+  ACInit("/*;!*/Bible.TXT*");
+  Silent(OFF); //no output to scrn
+}
+
+StartUpTasks;
+
+"\nTempleOS V%5.3f\t%D %T\n\n",sys_os_version,sys_compile_time,sys_compile_time;
+
+ diff --git a/public/Wb/Home/Src/HomeWrappers.HC.HTML b/public/Wb/Home/Src/HomeWrappers.HC.HTML new file mode 100755 index 0000000..2bc49ad --- /dev/null +++ b/public/Wb/Home/Src/HomeWrappers.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+#help_index "Cmd Line (Typically)"
+
+//These are customized quick commands.
+//Feel free to add more or change.
+public I64 F(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in all text files.
+  return Find(needle_str,"/*",fu_flags);
+}
+
+public I64 R(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in all text files.
+  return Find(needle_str,"/*",fu_flags,replace_text);
+}
+
+public I64 FD(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in cur dir text files.
+  return Find(needle_str,"*",fu_flags);
+}
+
+public I64 RD(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in cur dir text files.
+  return Find(needle_str,"*",fu_flags,replace_text);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskATA.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskATA.HC.HTML new file mode 100755 index 0000000..67d794f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskATA.HC.HTML @@ -0,0 +1,642 @@ + + + + + + + + + + + +
+U0 ATABlkSel(CBlkDev *bd,I64 blk,I64 cnt)
+{
+  if (bd->type!=BDT_ATAPI && bd->base1)
+    OutU8(bd->base1+ATAR1_CTRL,0x8);
+  if (bd->flags & BDF_EXT_SIZE) { //48 Bit LBA?
+    OutU8(bd->base0+ATAR0_NSECT,cnt.u8[1]);
+    OutU8(bd->base0+ATAR0_SECT,blk.u8[3]);
+    OutU8(bd->base0+ATAR0_LCYL,blk.u8[4]);
+    OutU8(bd->base0+ATAR0_HCYL,blk.u8[5]);
+    OutU8(bd->base0+ATAR0_NSECT,cnt);
+    OutU8(bd->base0+ATAR0_SECT,blk);
+    OutU8(bd->base0+ATAR0_LCYL,blk.u8[1]);
+    OutU8(bd->base0+ATAR0_HCYL,blk.u8[2]);
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  } else { //28 Bit LBA
+    OutU8(bd->base0+ATAR0_NSECT,cnt);
+    OutU8(bd->base0+ATAR0_SECT,blk);
+    OutU8(bd->base0+ATAR0_LCYL,blk.u8[1]);
+    OutU8(bd->base0+ATAR0_HCYL,blk.u8[2]);
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4|blk.u8[3]);
+  }
+}
+
+Bool ATAWaitNotBUSY(CBlkDev *bd,F64 timeout)
+{
+  I64 i;
+  do {
+    for (i=0;i<3;i++)
+      if (!(InU8(bd->base0+ATAR0_STAT)&ATAS_BSY))
+        return TRUE;
+    Yield;
+  } while (!(0<timeout<tS));
+  return FALSE;
+}
+
+Bool ATAWaitDRQ(CBlkDev *bd,F64 timeout)
+{
+  I64 i;
+  do {
+    for (i=0;i<3;i++)
+      if (InU8(bd->base0+ATAR0_STAT)&ATAS_DRQ)
+        return TRUE;
+    Yield;
+  } while (!(0<timeout<tS));
+  return FALSE;
+}
+
+Bool ATANop(CBlkDev *bd,F64 timeout)
+{
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_FEAT,0);
+  OutU8(bd->base0+ATAR0_CMD,ATA_NOP);
+  return ATAWaitNotBUSY(bd,timeout);
+}
+
+U0 ATACmd(CBlkDev *bd,U8 cmd)
+{
+  OutU8(bd->base0+ATAR0_FEAT,0);
+  OutU8(bd->base0+ATAR0_CMD,cmd);
+  bd->last_time=tS;
+  PortNop;
+}
+
+Bool ATAGetRes(CBlkDev *bd,F64 timeout,U8 *buf,I64 cnt,
+                I64 _avail,Bool one_read)
+{
+  I64 avail,overflow;
+  bd->flags&=~BDF_LAST_WAS_WRITE;
+  MemSet(buf,0,cnt);
+  while (cnt>0) {
+    if (!ATAWaitDRQ(bd,timeout))
+      return FALSE;
+    if (_avail)
+      avail=_avail;
+    else
+      avail=InU8(bd->base0+ATAR0_HCYL)<<8+InU8(bd->base0+ATAR0_LCYL);
+    if (avail) {
+      if (avail>cnt) {
+        overflow=avail-cnt;
+        avail=cnt;
+      } else
+        overflow=0;
+      if (avail&2)
+        RepInU16(buf,avail>>1,bd->base0+ATAR0_DATA);
+      else
+        RepInU32(buf,avail>>2,bd->base0+ATAR0_DATA);
+      cnt-=avail;
+      buf+=avail;
+      while (overflow>0) {
+        InU16(bd->base0+ATAR0_DATA);
+        overflow-=2;
+        if (0<timeout<tS)
+          return FALSE;
+      }
+      if (one_read)
+        break;
+    } else
+      Yield;
+  }
+  return ATAWaitNotBUSY(bd,timeout);
+}
+
+Bool ATAPIWritePktWord(CBlkDev *bd,F64 timeout,...)
+{
+  I64 i;
+  for (i=0;i<argc;i++) {
+    if (!ATAWaitDRQ(bd,timeout))
+      return FALSE;
+    OutU16(bd->base0+ATAR0_DATA,EndianU16(argv[i]));
+    bd->last_time=tS;
+  }
+  return TRUE;
+}
+
+Bool ATAPISetMaxSpeed(CBlkDev *bd)
+{
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,0);
+  OutU8(bd->base0+ATAR0_HCYL,0);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0xBB00,0xFFFF,0xFFFF,0,0,0);
+  return ATAWaitNotBUSY(bd,0);
+}
+
+Bool ATAPISeek(CBlkDev *bd,I64 native_blk)
+{
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,0);
+  OutU8(bd->base0+ATAR0_HCYL,0);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0x2B00,native_blk>>16,native_blk,0,0,0);
+  return ATAWaitNotBUSY(bd,0);
+}
+
+Bool ATAPIStartStop(CBlkDev *bd,F64 timeout,Bool start)
+{
+  I64 i;
+  if (start)
+    i=0x100;
+  else
+    i=0;
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  ATACmd(bd,ATA_PACKET);
+//Start/Stop
+  if (ATAPIWritePktWord(bd,timeout,0x1B00,0,i,0,0,0))
+    return ATAWaitNotBUSY(bd,timeout);
+  else
+    return FALSE;
+}
+
+I64 ATAGetDevId(CBlkDev *bd,F64 timeout,Bool keep_id_record)
+{
+  I64 res=BDT_NULL;
+  U16 *id_record=NULL;
+  if (bd->type!=BDT_ATAPI && bd->base1)
+    OutU8(bd->base1+ATAR1_CTRL,0x8);
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  ATACmd(bd,ATA_ID_DEV);
+  if (ATAWaitNotBUSY(bd,timeout)) {
+    if (InU8(bd->base0+ATAR0_STAT)&ATAS_ERR)
+      res=BDT_ATAPI;
+    else {
+      id_record=ACAlloc(512);
+      if (ATAGetRes(bd,timeout,id_record,512,512,FALSE))
+        res=BDT_ATA;
+      else {
+        Free(id_record);
+        id_record=NULL;
+      }
+    }
+  }
+  if (keep_id_record) {
+     Free(bd->dev_id_record);
+     bd->dev_id_record=id_record;
+  }
+  return res;
+}
+
+I64 ATAReadNativeMax(CBlkDev *bd,F64 timeout)
+{//Returns zero on err
+  I64 res=0;
+  Bool okay=TRUE;
+  if (bd->type==BDT_ATAPI) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    ATACmd(bd,ATA_DEV_RST);
+    if (!ATAWaitNotBUSY(bd,0))
+      okay=FALSE;
+  } else {
+    while (InU8(bd->base0+ATAR0_STAT) & ATAS_BSY) {
+      if (bd->flags&BDF_LAST_WAS_WRITE)
+        OutU16(bd->base0+ATAR0_DATA,0);
+      else
+        InU16(bd->base0+ATAR0_DATA);
+      Yield;
+      if (0<timeout<tS)
+        return FALSE;
+    }
+    if (ATAGetDevId(bd,timeout,TRUE)==BDT_NULL)
+      okay=FALSE;
+    else
+      BEqu(&bd->flags,BDf_EXT_SIZE,Bt(&bd->dev_id_record[86],10));
+  }
+  if (okay) {
+    if (bd->flags & BDF_EXT_SIZE && bd->base1) {
+      OutU8(bd->base1+ATAR1_CTRL,0x8);
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+      ATACmd(bd,ATA_READ_NATIVE_MAX_EXT);
+      if (ATAWaitNotBUSY(bd,timeout)) {
+        res.u8[0]=InU8(bd->base0+ATAR0_SECT);
+        res.u8[1]=InU8(bd->base0+ATAR0_LCYL);
+        res.u8[2]=InU8(bd->base0+ATAR0_HCYL);
+
+        OutU8(bd->base1+ATAR1_CTRL,0x80);
+        res.u8[3]=InU8(bd->base0+ATAR0_SECT);
+        res.u8[4]=InU8(bd->base0+ATAR0_LCYL);
+        res.u8[5]=InU8(bd->base0+ATAR0_HCYL);
+
+        if (res>>24==res&0xFFFFFF) {//Kludge to make QEMU work
+          bd->flags&=~BDF_EXT_SIZE;
+          res&=0xFFFFFF;
+        }
+      }
+    } else {
+      if (bd->type!=BDT_ATAPI && bd->base1)
+        OutU8(bd->base1+ATAR1_CTRL,0x8);
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+      ATACmd(bd,ATA_READ_NATIVE_MAX);
+      if (ATAWaitNotBUSY(bd,timeout)) {
+        res.u8[0]=InU8(bd->base0+ATAR0_SECT);
+        res.u8[1]=InU8(bd->base0+ATAR0_LCYL);
+        res.u8[2]=InU8(bd->base0+ATAR0_HCYL);
+        res.u8[3]=InU8(bd->base0+ATAR0_SEL) & 0xF;
+      }
+    }
+  }
+  return bd->max_blk=res;
+}
+
+I64 ATAPIReadCapacity(CBlkDev *bd,I64 *_blk_size=NULL)
+{//Supposedly this can return a res +/- 75 sects.
+//Error might just be for music.
+  Bool unlock=BlkDevLock(bd);
+  U32 buf[2];
+  if (ATAWaitNotBUSY(bd,0)) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,8);
+    OutU8(bd->base0+ATAR0_HCYL,0);
+    ATACmd(bd,ATA_PACKET);
+    ATAPIWritePktWord(bd,0,0x2500,0,0,0,0,0);
+    if (!ATAGetRes(bd,0,buf,8,0,TRUE))
+      buf[0]=buf[1]=0;
+  } else
+    buf[0]=buf[1]=0;
+
+  if (unlock) BlkDevUnlock(bd);
+  if (_blk_size) *_blk_size=EndianU32(buf[1]);
+  return EndianU32(buf[0]);
+}
+
+CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd,I64 blk)
+{
+  CATAPITrack *res=CAlloc(sizeof(CATAPITrack));
+  Bool unlock=BlkDevLock(bd);
+  if (ATAWaitNotBUSY(bd,0)) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,sizeof(CATAPITrack)&0xFF);
+    OutU8(bd->base0+ATAR0_HCYL,sizeof(CATAPITrack)>>8);
+    ATACmd(bd,ATA_PACKET);
+    ATAPIWritePktWord(bd,0,0x5200,blk.u16[1],blk.u16[0],
+          (sizeof(CATAPITrack)&0xFF00)>>8,(sizeof(CATAPITrack)&0x00FF)<<8,0);
+    if (!ATAGetRes(bd,0,res,sizeof(CATAPITrack),0,TRUE)) {
+      Free(res);
+      res=NULL;
+    }
+  } else {
+    Free(res);
+    res=NULL;
+  }
+  if (unlock) BlkDevUnlock(bd);
+  return res;
+}
+
+Bool ATAInit(CBlkDev *bd)
+{
+  Bool unlock=BlkDevLock(bd),okay=FALSE;
+
+  if (bd->type==BDT_ATAPI)
+    bd->flags&=~BDF_EXT_SIZE;
+  else
+    bd->flags|=BDF_EXT_SIZE;
+
+  if (ATAReadNativeMax(bd,tS+0.1)) {
+    ATABlkSel(bd,bd->max_blk,0);
+    if (bd->flags&BDF_EXT_SIZE)
+      ATACmd(bd,ATA_SET_MAX_EXT);
+    else
+      ATACmd(bd,ATA_SET_MAX);
+    if (ATAWaitNotBUSY(bd,0)) {
+      okay=TRUE;
+      if (bd->type==BDT_ATAPI) {
+        if (ATAPIStartStop(bd,0,TRUE)) {
+          if(!ATAPISetMaxSpeed(bd))
+            okay=FALSE;
+        } else
+          okay=FALSE;
+      }
+    }
+  }
+  if (unlock) BlkDevUnlock(bd);
+  return okay;
+}
+
+Bool ATAPIWaitReady(CBlkDev *bd,F64 timeout)
+{
+  do {
+    if (!ATAWaitNotBUSY(bd,timeout) ||
+          !ATANop(bd,timeout) ||
+          !ATAPIStartStop(bd,timeout,TRUE))
+      return FALSE;
+    if (InU8(bd->base0+ATAR0_STAT) & ATAS_DRDY &&
+          !InU8(bd->base0+ATAR0_FEAT));
+    return TRUE;
+    ATAInit(bd);
+    Yield;
+  } while (!(0<timeout<tS));
+  return FALSE;
+}
+
+U0 ATAReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt)
+{
+  I64 retries=3;
+  Bool unlock=BlkDevLock(bd);
+
+  retry:
+  ATABlkSel(bd,blk,cnt);
+  if (bd->flags & BDF_EXT_SIZE)
+    ATACmd(bd,ATA_READ_MULTI_EXT);
+  else
+    ATACmd(bd,ATA_READ_MULTI);
+  if (!ATAGetRes(bd,tS+1.0,buf,cnt*bd->blk_size,BLK_SIZE,FALSE)) {
+    if (retries--) {
+      ATAWaitNotBUSY(bd,0);
+      goto retry;
+    } else
+      throw('BlkDev');
+  }
+
+  blkdev.read_cnt+=(cnt*bd->blk_size)>>BLK_SIZE_BITS;
+  if (unlock) BlkDevUnlock(bd);
+}
+
+I64 ATAProbe(I64 base0,I64 base1,I64 unit)
+{
+  CBlkDev bd;
+  MemSet(&bd,0,sizeof(CBlkDev));
+  bd.type=BDT_ATAPI;
+  bd.base0=base0;
+  bd.base1=base1;
+  bd.unit=unit;
+  bd.blk_size=DVD_BLK_SIZE;
+  return ATAGetDevId(&bd,tS+0.1,FALSE);
+}
+
+Bool ATAPIReadBlks2(CBlkDev *bd,F64 timeout,U8 *buf,
+                I64 native_blk, I64 cnt,Bool lock)
+{
+  Bool res=FALSE,unlock;
+  if (cnt<=0)
+    return FALSE;
+  if (lock)
+    unlock=BlkDevLock(bd);
+  if (ATAPIWaitReady(bd,timeout)) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,bd->blk_size);
+    OutU8(bd->base0+ATAR0_HCYL,bd->blk_size.u8[1]);
+    ATACmd(bd,ATA_PACKET);
+    if (ATAPIWritePktWord(bd,timeout,0xA800,
+          native_blk.u16[1],native_blk,cnt.u16[1],cnt,0) &&
+          ATAGetRes(bd,timeout,buf,cnt*bd->blk_size,0,FALSE)) {
+      blkdev.read_cnt+=(cnt*bd->blk_size)>>BLK_SIZE_BITS;
+      res=TRUE;
+    }
+  }
+//  ATAPIStartStop(bd,0,FALSE);
+  if (lock && unlock) BlkDevUnlock(bd);
+  return res;
+}
+
+U0 ATAPIReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt)
+{
+  CDrv *dv=Let2Drv(bd->first_drv_let);
+  I64 retry,spc=bd->blk_size>>BLK_SIZE_BITS,n,blk2,
+        l2=bd->max_reads<<1+spc<<1;
+  U8 *dvd_buf=MAlloc(l2<<BLK_SIZE_BITS);
+  if (cnt>0) {
+    if (blk<=bd->max_reads)
+      blk2=0;
+    else
+      blk2=FloorU64(blk-bd->max_reads,spc);
+    if (blk2+l2>dv->size+dv->drv_offset)
+      l2=dv->size+dv->drv_offset-blk2;
+    n=(l2+spc-1)/spc;
+
+    retry=4;
+    while (--retry)
+      if (ATAPIReadBlks2(bd,tS+7.0+0.004*n,dvd_buf,blk2/spc,n,TRUE))
+//n is 0x800 if max_reads.  Up to 8 additional seconds
+        break;
+    if (!retry)
+      ATAPIReadBlks2(bd,0,dvd_buf,blk2/spc,n,TRUE);
+    if (bd->flags & BDF_READ_CACHE)
+      DskCacheAdd(dv,dvd_buf,blk2,n*spc);
+    MemCpy(buf,dvd_buf+(blk-blk2)<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
+  }
+  Free(dvd_buf);
+}
+
+Bool ATARBlks(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{
+  I64 n;
+  CBlkDev *bd=dv->bd;
+  while (cnt>0) {
+    n=cnt;
+    if (n>bd->max_reads)
+      n=bd->max_reads;
+    if (bd->type==BDT_ATAPI)
+      ATAPIReadBlks(bd,buf,blk,n);
+    else
+      ATAReadBlks(bd,buf,blk,n);
+    buf+=n<<BLK_SIZE_BITS;
+    blk+=n;
+    cnt-=n;
+  }
+  return TRUE;
+}
+
+U0 ATAWriteBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt)
+{//For low level disk access.
+//Use BlkWrite() instead.
+  I64 i,U32s_avail,sects_avail,retries=3;
+  F64 timeout;
+  Bool unlock=BlkDevLock(bd);
+retry:
+  ATABlkSel(bd,blk,cnt);
+  if (bd->flags&BDF_EXT_SIZE)
+    ATACmd(bd,ATA_WRITE_MULTI_EXT);
+  else
+    ATACmd(bd,ATA_WRITE_MULTI);
+  bd->flags|=BDF_LAST_WAS_WRITE;
+  while (cnt>0) {
+    timeout=tS+1.0;
+    while (TRUE) {
+      i=InU8(bd->base0+ATAR0_STAT);
+      if (!(i & ATAS_DRDY)||!(i & ATAS_DRQ)) {
+        Yield;
+      } else
+        break;
+      if (/* i&ATAS_ERR||*/ tS>timeout) {
+        if (retries--) {
+          ATAWaitNotBUSY(bd,0);
+          goto retry;
+        } else
+          throw('BlkDev');
+      }
+    }
+    sects_avail=1;
+    U32s_avail=sects_avail<<BLK_SIZE_BITS>>2;
+    RepOutU32(buf,U32s_avail,bd->base0+ATAR0_DATA);
+    buf+=U32s_avail<<2;
+    cnt-=sects_avail;
+    retries=3;
+  }
+  ATAWaitNotBUSY(bd,0);
+  if (unlock) BlkDevUnlock(bd);
+}
+
+Bool ATAPISync(CBlkDev *bd)
+{
+  Bool okay=TRUE;
+  if (!ATAWaitNotBUSY(bd,0))
+    okay=FALSE;
+  else {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,0);
+    OutU8(bd->base0+ATAR0_HCYL,0);
+    ATACmd(bd,ATA_PACKET);
+    ATAPIWritePktWord(bd,0,0x3500,0,0,0,0,0);
+    if (!ATAWaitNotBUSY(bd,0))
+      okay=FALSE;
+  }
+  return okay;
+}
+
+U0 ATAPIClose(CBlkDev *bd,I64 close_field=0x200,I64 track=0)
+{//0x200 CD/DVD part 1
+// 0x300    DVD part 2
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,0);
+  OutU8(bd->base0+ATAR0_HCYL,0);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0x5B00,close_field,track,0,0,0);
+  ATAWaitNotBUSY(bd,0);
+}
+
+U0 ATAPIWriteBlks(CBlkDev *bd,U8 *buf, I64 native_blk, I64 cnt)
+{
+  I64 U32s_avail;
+  U8 *buf2;
+  ATAWaitNotBUSY(bd,0);
+  ATAPISeek(bd,native_blk);
+
+  OutU8(bd->base0+ATAR0_FEAT,0);
+  OutU8(bd->base0+ATAR0_LCYL,bd->blk_size);
+  OutU8(bd->base0+ATAR0_HCYL,bd->blk_size.u8[1]);
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_CMD,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0x0400,native_blk.u16[1],native_blk,cnt.u16[1],cnt,0);
+  bd->flags|=BDF_LAST_WAS_WRITE;
+  ATAWaitNotBUSY(bd,0);
+
+  ATAPISeek(bd,native_blk);
+
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,bd->blk_size);
+  OutU8(bd->base0+ATAR0_HCYL,bd->blk_size.u8[1]);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0xAA00,native_blk.u16[1],native_blk,cnt.u16[1],cnt,0);
+  buf2=buf+bd->blk_size*cnt;
+  while (buf<buf2) {
+    ATAWaitDRQ(bd,0);
+    U32s_avail=(InU8(bd->base0+ATAR0_HCYL)<<8+InU8(bd->base0+ATAR0_LCYL))>>2;
+    if (buf+U32s_avail<<2>buf2)
+      U32s_avail=(buf2-buf)>>2;
+    if (U32s_avail) {
+      RepOutU32(buf,U32s_avail,bd->base0+ATAR0_DATA);
+      buf+=U32s_avail<<2;
+      blkdev.write_cnt+=U32s_avail>>(BLK_SIZE_BITS-2);
+    }
+  }
+  ATAWaitNotBUSY(bd,0);
+}
+
+Bool ATAWBlks(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{
+  I64 n,spc;
+  CBlkDev *bd=dv->bd;
+  Bool unlock;
+  spc=bd->blk_size>>BLK_SIZE_BITS;
+  if (bd->type==BDT_ATAPI) {
+    unlock=BlkDevLock(bd);
+    ATAPIWaitReady(bd,0);
+  }
+  while (cnt>0) {
+    n=cnt;
+    if (n>bd->max_writes)
+      n=bd->max_writes;
+    if (bd->type==BDT_ATAPI)
+      ATAPIWriteBlks(bd,buf,blk/spc,(n+spc-1)/spc);
+    else
+      ATAWriteBlks(bd,buf,blk,n);
+    buf+=n<<BLK_SIZE_BITS;
+    blk+=n;
+    cnt-=n;
+    blkdev.write_cnt+=n;
+  }
+  if (bd->type==BDT_ATAPI) {
+    ATAPISync(bd);
+//    ATAPIStartStop(bd,0,FALSE);
+    if (unlock) BlkDevUnlock(bd);
+  }
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskATAId.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskATAId.HC.HTML new file mode 100755 index 0000000..e9871dc --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskATAId.HC.HTML @@ -0,0 +1,324 @@ + + + + + + + + + + + +
+Bool BootDVDProbe(CBlkDev *bd)
+{
+  U8 *img=CAlloc(DVD_BLK_SIZE);
+  I64 i;
+  Bool res=FALSE;
+  "Port: %04X,%04X Unit: %02X  ",bd->base0,bd->base1,bd->unit;
+  if (ATAProbe(bd->base0,bd->base1,bd->unit)==BDT_ATAPI) {
+    " ATAPI";
+    if (ATAPIStartStop(bd,tS+5.0,TRUE)) {
+      " Started";
+      for (i=0;i<2;i++) {//Retry
+        if (ATAPIReadBlks2(bd,tS+7.0,img,sys_boot_blk,1,FALSE)) {
+          if ((img+sys_boot_src.u16[1]<<BLK_SIZE_BITS)(CKernel *)
+                ->compile_time==sys_compile_time) {
+            " Found\n";
+            return TRUE;
+          } else
+            " Read";
+        } else
+          " NoRead";
+      }
+    }
+  }
+  " Nope\n";
+  Free(img);
+  return res;
+}
+
+Bool BootDVDProbeAll(CBlkDev *bd)
+{
+  I64 d1,d2,i,j,k;
+
+  bd->base1=0;
+  for (k=0;k<256;k++) {
+    i=-1;
+    while (TRUE) {
+      j=PCIClassFind(0x010100+k,++i);
+      if (j<0)
+        break;
+      "Subcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
+      d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
+      d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
+      if (d1&1 && d2&1) {
+        if (bd->base0=d1&~7) {
+          bd->unit=0;
+          if (BootDVDProbe(bd))
+            return TRUE;
+          bd->unit=1;
+          if (BootDVDProbe(bd))
+            return TRUE;
+        }
+      }
+      d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
+      d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
+      if (d1&1 && d2&1) {
+        if (bd->base0=d1&~7) {
+          bd->unit=0;
+          if (BootDVDProbe(bd))
+            return TRUE;
+          bd->unit=1;
+          if (BootDVDProbe(bd))
+            return TRUE;
+        }
+      }
+    }
+  }
+
+  d1=0x1F0;
+  d2=0x3F6;
+  if (bd->base0=d1&~7) {
+    bd->unit=0;
+    if (BootDVDProbe(bd))
+      return TRUE;
+    bd->unit=1;
+    if (BootDVDProbe(bd))
+      return TRUE;
+  }
+
+  d1=0x170;
+  d2=0x376;
+  if (bd->base0=d1&~7) {
+    bd->unit=0;
+    if (BootDVDProbe(bd))
+      return TRUE;
+    bd->unit=1;
+    if (BootDVDProbe(bd))
+      return TRUE;
+  }
+}
+
+U0 ATARepEntry(I64 base0,I64 base1,I64 unit,U8 *msg,
+        CATARep **_head,I64 *num_hints)
+{
+  I64 type;
+  base0&=-8;
+  base1&=-4;
+  CATARep *tmpha;
+  if (type=ATAProbe(base0,base1,unit)) {
+    *num_hints+=1;
+    "\n$PURPLE$ $BT+X,\"%d\",LM=\"%d\\n\"$$FG$$LM,4$",*num_hints,*num_hints;
+    if (type==BDT_ATA)
+      "$RED$Hard Drive   $LTBLUE$ATA   ";
+    else
+      "$RED$CD/DVD Drive $LTBLUE$ATAPI ";
+    "%s$FG$\n",msg;
+    if (base0==blkdev.ins_base0 && unit==blkdev.ins_unit)
+      "$PURPLE$(Drive originally installed from.)$FG$\n";
+    "Base0:0x%04X Base1:0x%04X Unit:%d$LM,0$\n",
+          base0,base1,unit;
+    if (_head) {
+      tmpha=CAlloc(sizeof(CATARep));
+      tmpha->next=*_head;
+      *_head=tmpha;
+      tmpha->num=*num_hints;
+      tmpha->type=type;
+      tmpha->base0=base0;
+      tmpha->base1=base1;
+      tmpha->unit=unit;
+    }
+  }
+}
+
+Bool ATARepExitAllApplications()
+{
+  "\nWe're going to probe hardware.\n"
+        "$RED$Exit all other applications.$FG$\n"
+        "Press '$PURPLE$p$FG$' to probe or '$PURPLE$s$FG$' to skip.\n";
+  if (ToUpper(GetChar(,FALSE))=='S')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+public I64 ATARep(Bool pmt=TRUE,Bool just_ide=FALSE,CATARep **_head=NULL)
+{//Report possible ATA devices by probing.  Hard disks and CD/DVDs.
+  I64 d1,d2,i,j,k,cnt=0,unlock_flags=0,num_hints=0;
+#assert BLKDEVS_NUM<=64
+  if (_head) *_head=NULL;
+
+  if (pmt && ATARepExitAllApplications)
+    return 0;
+
+  for (i=0;i<BLKDEVS_NUM;i++)
+    if (blkdev.blkdevs[i].bd_signature==BD_SIGNATURE_VAL)
+      BEqu(&unlock_flags,i,
+            BlkDevLock(&blkdev.blkdevs[i]));
+
+  if (!just_ide)
+    for (k=0;k<256;k++) {
+      i=-1;
+      while (TRUE) {
+        j=PCIClassFind(0x010100+k,++i);
+        if (j<0)
+          break;
+
+        "\nSubcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
+        cnt++;
+
+        d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
+        d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
+        if (d1&1 && d2&1) {
+          ATARepEntry(d1,d2,0,"Primary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Primary IDE",_head,&num_hints);
+        } else {
+          d1=0x1F0; d2=0x3F6;
+          ATARepEntry(d1,d2,0,"Primary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Primary IDE",_head,&num_hints);
+        }
+        d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
+        d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
+        if (d1&1 && d2&1) {
+          ATARepEntry(d1,d2,0,"Secondary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Secondary IDE",_head,&num_hints);
+        } else {
+          d1=0x170; d2=0x376;
+          ATARepEntry(d1,d2,0,"Secondary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Secondary IDE",_head,&num_hints);
+        }
+      }
+    }
+  if (!cnt) {
+    d1=0x1F0; d2=0x3F6;
+    ATARepEntry(d1,d2,0,"Primary IDE",_head,&num_hints);
+    ATARepEntry(d1,d2,1,"Primary IDE",_head,&num_hints);
+
+    d1=0x170; d2=0x376;
+    ATARepEntry(d1,d2,0,"Secondary IDE",_head,&num_hints);
+    ATARepEntry(d1,d2,1,"Secondary IDE",_head,&num_hints);
+  }
+  '\n\n';
+  for (i=0;i<BLKDEVS_NUM;i++)
+    if (Bt(&unlock_flags,i))
+      BlkDevUnlock(&blkdev.blkdevs[i]);
+  return num_hints;
+}
+
+CATARep *ATARepFind(CATARep *haystack_head,I64 needle_num)
+{
+  while (haystack_head) {
+    if (haystack_head->num==needle_num)
+      return haystack_head;
+    haystack_head=haystack_head->next;
+  }
+  return NULL;
+}
+
+CATARep *ATAIDDrvs(CATARep *head,CATARep **_ata_drv,CATARep **_atapi_drv)
+{//This is for when trying to sort-out main hard drives and CD/DVD drives.
+  CATARep *res=NULL,*tmpha=head,*ata_drv=NULL,*atapi_drv=NULL;
+  CBlkDev *bd;
+  Bool was_silent=Silent,ins_found=FALSE;
+  bd=Let2BlkDev(':',FALSE);
+  Silent(was_silent);
+  while (tmpha) {
+    if (!res && bd && bd->type==tmpha->type) {
+      if (bd->type==BDT_ATAPI &&
+            bd->base0==tmpha->base0 && bd->unit==tmpha->unit)
+        res=atapi_drv=tmpha;
+      else if (bd->type==BDT_ATA && bd->base0==tmpha->base0 &&
+            bd->base1==tmpha->base1 && bd->unit==tmpha->unit)
+        res=ata_drv=tmpha;
+    }
+    if (!res || res->type!=tmpha->type) {
+      if (tmpha->type==BDT_ATA) {
+        if (!ata_drv || tmpha->unit<ata_drv->unit ||
+              tmpha->unit==ata_drv->unit && tmpha->num<ata_drv->num)
+          ata_drv=tmpha;
+      } else if (tmpha->type==BDT_ATAPI) {
+        if (!atapi_drv || !ins_found && (tmpha->unit<atapi_drv->unit ||
+              tmpha->unit==atapi_drv->unit && tmpha->num<atapi_drv->num))
+          atapi_drv=tmpha;
+      }
+    }
+    if (tmpha->type==BDT_ATAPI && bd && bd->type==BDT_ATA &&
+      tmpha->base0==blkdev.ins_base0 && tmpha->unit==blkdev.ins_unit) {
+      if (!ins_found) {
+        atapi_drv=tmpha;
+        ins_found=TRUE;
+      }
+    }
+    tmpha=tmpha->next;
+  }
+  if (_ata_drv)   *_ata_drv  =ata_drv;
+  if (_atapi_drv) *_atapi_drv=atapi_drv;
+  return res;
+}
+
+CBlkDev *ATAMount(U8 first_drv_let,I64 type,I64 base0,I64 base1,I64 unit)
+{
+  CBlkDev *res;
+  if (0<=first_drv_let-'A'<DRVS_NUM && (type==BDT_ATA || type==BDT_ATAPI) &&
+        0<=unit<=1) {
+    res=BlkDevNextFreeSlot(first_drv_let,type);
+    res->unit=unit;
+    res->base0=base0;
+    res->base1=base1;
+    if (BlkDevAdd(res,,FALSE,FALSE))
+      return res;
+  }
+  return NULL;
+}
+
+I64 MountIDEAuto()
+{//Try to mount hard drive and CD/DVD, automatically. (Kernel.Cfg option).
+//It uses 'C' and 'T' as first drive letters or whatever you set
+  //in config when compiling Kernel.BIN.
+  I64 res=0;
+  CATARep *head=NULL,*ata_drv=NULL,*atapi_drv=NULL,*tmpha;
+  ATARep(FALSE,TRUE,&head);
+  ATAIDDrvs(head,&ata_drv,&atapi_drv);
+  if (ata_drv && ATAMount(blkdev.first_hd_drv_let,BDT_ATA,
+        ata_drv->base0,ata_drv->base1,ata_drv->unit))
+    res++;
+  if (atapi_drv && ATAMount(blkdev.first_dvd_drv_let,BDT_ATAPI,
+        atapi_drv->base0,atapi_drv->base1,atapi_drv->unit))
+    res++;
+  tmpha=head;
+  while (tmpha) {
+    if (tmpha!=ata_drv && tmpha!=atapi_drv) {
+      if (tmpha->type==BDT_ATA && ATAMount(blkdev.first_hd_drv_let,BDT_ATA,
+            tmpha->base0,tmpha->base1,tmpha->unit))
+        res++;
+      else if (tmpha->type==BDT_ATAPI &&
+            ATAMount(blkdev.first_dvd_drv_let,BDT_ATAPI,
+            tmpha->base0,tmpha->base1,tmpha->unit))
+        res++;
+    }
+    tmpha=tmpha->next;
+  }
+  LinkedLstDel(head);
+  blkdev.mount_ide_auto_cnt=res;
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskAddDev.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskAddDev.HC.HTML new file mode 100755 index 0000000..7a06c67 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskAddDev.HC.HTML @@ -0,0 +1,271 @@ + + + + + + + + + + + +
+U0 BlkDevLockFwdingSet(CBlkDev *bd)
+{  //If two blkdevs on same controller, use just one lock
+  CBlkDev *bd1;
+  I64 i;
+  switch (bd->type) {
+    case BDT_RAM:
+      break;
+    case BDT_ISO_FILE_READ:
+    case BDT_ISO_FILE_WRITE:
+      bd->lock_fwding=Let2BlkDev(*bd->file_dsk_name);
+      break;
+    case BDT_ATA:
+    case BDT_ATAPI:
+      for (i=0;i<BLKDEVS_NUM;i++) {
+        bd1=&blkdev.blkdevs[i];
+        if (bd1->bd_signature==BD_SIGNATURE_VAL && bd!=bd1 &&
+              (bd1->type==BDT_ATAPI || bd1->type==BDT_ATA) &&
+              bd1->base0==bd->base0) {
+          bd->lock_fwding=bd1;
+          break;
+        }
+      }
+      break;
+  }
+}
+
+I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN,
+        Bool whole_drv,Bool make_free)
+{//It will mount just one partition of prt_num>=0.
+//When repartitioing whole drive, whole_drv=TRUE.
+  I64 i,j,ext_base,offset,res=0,num=0;
+  CDrv *dv;
+  CRedSeaBoot br;
+  CMasterBoot mbr;
+
+  bd->bd_signature=BD_SIGNATURE_VAL;
+  if (make_free)
+    dv=DrvMakeFreeSlot(bd->first_drv_let);
+  else
+    dv=DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let));
+  dv->bd=bd;
+  dv->drv_offset=bd->drv_offset;
+  dv->size=bd->max_blk+1-bd->drv_offset;
+  switch (bd->type) {
+    case BDT_RAM:
+    case BDT_ISO_FILE_READ:
+    case BDT_ISO_FILE_WRITE:
+      dv->dv_signature=DRV_SIGNATURE_VAL;
+      dv->prt_num=num;
+      dv->fs_type=FSt_REDSEA;
+//This is to force creation of a RAM
+      //drive during boot, so it is probably
+      //MAlloced to the same addr and can
+      //be assumed to be already formatted.
+      //If this line is removed, RAM Drives
+      //will be alloced on a just-in-time
+      //basis.
+      if (BlkDevInit(bd))
+        res++;
+      else
+        dv->dv_signature=0;
+      break;
+    case BDT_ATA:
+      dv->dv_signature=DRV_SIGNATURE_VAL; //Temporarily validate
+      if (!BlkDevInit(bd))
+        dv->dv_signature=0; //Revoke validation
+      else {
+        dv->dv_signature=0; //Revoke validation
+        if (whole_drv) {
+          dv->dv_signature=DRV_SIGNATURE_VAL;
+          dv->prt_num=num;
+          res++;
+          dv->fs_type=FSt_REDSEA;
+          dv->size=bd->max_blk+1-bd->drv_offset;
+//The following read is a test read.
+          //if it hangs, the drive is not supported.
+          ATAReadBlks(bd,&mbr,0,1);
+          break;
+        }
+        offset=0;
+        ext_base=INVALID_CLUS;
+        while (prt_num<0 || num<=prt_num) {
+          ATAReadBlks(bd,&mbr,offset,1);
+          if (mbr.signature!=0xAA55)
+            break;
+          j=-1;
+          for (i=0;i<4 && (prt_num<0 || num<=prt_num);i++) {
+            if (mbr.p[i].type) {
+              if (make_free)
+                dv=DrvMakeFreeSlot(bd->first_drv_let+res);
+              else
+                dv=DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let+res));
+              dv->bd=bd;
+              dv->drv_offset=mbr.p[i].offset+offset;
+              dv->size  =mbr.p[i].size;
+              switch (mbr.p[i].type) {
+                case MBR_PT_REDSEA:
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  dv->fs_type=FSt_REDSEA;
+                  RedSeaInit(dv);
+                  break;
+                case MBR_PT_FAT32a:
+                case MBR_PT_FAT32b:
+                case MBR_PT_FAT32c:
+                case MBR_PT_FAT32d:
+                case MBR_PT_FAT32e:
+                case MBR_PT_FAT32f:
+                  ATAReadBlks(bd,&br,dv->drv_offset,1);
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  if (br.signature==MBR_PT_REDSEA) {
+                    dv->fs_type=FSt_REDSEA;
+                    RedSeaInit(dv);
+                  } else {
+                    dv->fs_type=FSt_FAT32;
+                    FAT32Init(dv);
+                  }
+                  break;
+                case MBR_PT_NTFS:
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  dv->fs_type=FSt_NTFS;
+                  break;
+                case 5:
+                case 15:
+                  j=i;
+                  break;
+                default:
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  dv->fs_type=FSt_UNKNOWN;
+              }
+              num++;
+            }
+          }
+          if (Let2BlkDevType(bd->first_drv_let+res)!=bd->type)
+            break;
+          if (j<0)
+            break;
+          if (!mbr.p[j].offset)
+            break;
+          if (ext_base==INVALID_CLUS) {
+            offset=mbr.p[j].offset;
+            ext_base=offset;
+          } else
+            offset=mbr.p[j].offset+ext_base;
+        }
+      }
+      break;
+    case BDT_ATAPI:
+      dv->dv_signature=DRV_SIGNATURE_VAL;
+      dv->prt_num=num;
+      res++;
+      dv->fs_type=FSt_ISO9660; //Start with this
+      dv->size=0;
+      break;
+  }
+  if (res)
+    BlkDevLockFwdingSet(bd);
+  else
+    BlkDevDel(bd);
+  return res;
+}
+
+Bool DrvEnable(U8 drv_let,Bool val)
+{//Can unmount or remount, but not mount the first time.
+  CDrv *dv;
+  if (dv=Let2Drv(drv_let,FALSE))
+    return !LBEqu(&dv->fs_type,FStf_DISABLE,!val);
+  else
+    return FALSE;
+}
+
+I64 SysGetI64()
+{
+  U8 st[STR_LEN];
+  GetS(st,STR_LEN,FALSE);
+  return Str2I64(st,16);
+}
+
+Bool GetBaseUnit(CBlkDev *bd)
+{
+  I64 ch;
+  Bool probe;
+  #exe {
+    if (kernel_cfg->opts[CFG_DONT_PROBE])
+      StreamPrint("probe=FALSE;");
+    else
+      StreamPrint("probe=TRUE;");
+  };
+  if (!probe || !BootDVDProbeAll(bd)) {
+    "\nDon't worry.  This is not a product\n"
+          "registration.        TempleOS just needs the\n"
+          "I/O port numbers for the CD/DVD.\n"
+          "\nRetry the ports above or check Windows\n"
+          "system information under I/O ports for\n"
+          "'IDE', 'ATA' or 'SATA'.\n"
+          "In Linux, use 'lspci -v' for ports.\n"
+          "\n\nEnter 4-digit hex I/O Port number.\n"
+          "CD/DVD I/O Port Base0: 0x";
+    bd->base0=SysGetI64;
+    bd->base1=0;
+    bd->unit =0;
+    if (bd->base0) {
+      "\nUnit (0 or 1): ";
+      do ch=GetChar(,FALSE);
+      while (!('0'<=ch<='1'));
+      '' ch;
+      bd->unit=ch-'0';
+      blkdev.dvd_boot_is_good=BootDVDProbe(bd);
+      return TRUE;
+    } else {
+      blkdev.dvd_boot_is_good=FALSE;
+      return FALSE;
+    }
+  }
+  return FALSE;
+}
+
+U0 BlkDevsInitAll()
+{
+  CBlkDev *bd;
+  I64 i;
+  blkdev.blkdevs=CAlloc(sizeof(CBlkDev)*BLKDEVS_NUM);
+  blkdev.drvs=CAlloc(sizeof(CDrv)*DRVS_NUM);
+  for (i=0;i<DRVS_NUM;i++)
+    blkdev.let_to_drv[i]=&blkdev.drvs[i];
+  #exe {
+    if (kernel_cfg->opts[CFG_MOUNT_IDE_AUTO])
+      StreamPrint("MountIDEAuto;");
+    StreamPrint("#exe {Option(OPTf_WARN_PAREN,OFF);}");
+    StreamDoc(kernel_cfg->add_dev);
+    StreamPrint("#exe {Option(OPTf_WARN_PAREN,ON);}");
+  };
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskBlk.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskBlk.HC.HTML new file mode 100755 index 0000000..f9fa4df --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskBlk.HC.HTML @@ -0,0 +1,140 @@ + + + + + + + + + + + +
+#define ZERO_BUF_SIZE   2048
+U0 BlkWriteZero(CDrv *dv,I64 blk,I64 cnt)
+{//Fill blk cnt with zeros in Drv.
+  I64 n;
+  U8 *z=CAlloc(ZERO_BUF_SIZE<<BLK_SIZE_BITS);
+  Bool show_progress;
+  if (cnt>ZERO_BUF_SIZE && dv->bd->type!=BDT_RAM) {
+    progress1=0; progress1_max=cnt;
+    StrCpy(progress1_desc,"Zeroing");
+    show_progress=TRUE;
+  } else
+    show_progress=FALSE;
+  while (cnt>0) {
+    n=cnt;
+    if (n>ZERO_BUF_SIZE)
+      n=ZERO_BUF_SIZE;
+    BlkWrite(dv,z,blk,n);
+    blk+=n;
+    cnt-=n;
+    if (show_progress)
+      progress1+=n;
+    Yield;  //Prevent locking
+  }
+  Free(z);
+  if (show_progress) {
+    *progress1_desc=0;
+    progress1=progress1_max=0;
+  }
+}
+
+Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{//Read blk cnt from Drv to buf.
+  Bool res=TRUE,unlock;
+  CBlkDev *bd=dv->bd;
+  if (cnt<=0) return TRUE;
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    BlkDevInit(bd);
+    if (dv->drv_offset && blk<dv->drv_offset ||
+          blk+cnt>dv->drv_offset+dv->size)
+      throw('Drv');
+    if (bd->flags & BDF_READ_CACHE)
+      RCache(dv,&buf,&blk,&cnt);
+    if (cnt>0) {
+      switch (bd->type) {
+        case BDT_RAM:
+          MemCpy(buf,bd->RAM_dsk+blk<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
+          break;
+        case BDT_ISO_FILE_READ:
+        case BDT_ISO_FILE_WRITE:
+          FBlkRead(bd->file_dsk,buf,blk,cnt);
+          break;
+        case BDT_ATA:
+        case BDT_ATAPI:
+          res=ATARBlks(dv,buf,blk,cnt);
+          break;
+      }
+      bd->last_time=tS;
+      if (bd->flags & BDF_READ_CACHE)
+        DskCacheAdd(dv,buf,blk,cnt);
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return res;
+}
+
+Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{//Write blk cnt from buf to Drv.
+  Bool res=TRUE,unlock;
+  CBlkDev *bd=dv->bd;
+  if (cnt<=0) return TRUE;
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    BlkDevInit(bd);
+    if (bd->flags&BDF_READ_ONLY && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
+      throw('BlkDev');
+    if (dv->drv_offset && blk<dv->drv_offset ||
+          blk+cnt>dv->drv_offset+dv->size)
+      throw('Drv');
+    if (cnt>0) {
+      switch (bd->type) {
+        case BDT_RAM:
+          MemCpy(bd->RAM_dsk+blk<<BLK_SIZE_BITS,buf,cnt<<BLK_SIZE_BITS);
+          break;
+        case BDT_ISO_FILE_READ:
+        case BDT_ISO_FILE_WRITE:
+          FBlkWrite(bd->file_dsk,buf,blk,cnt);
+          break;
+        case BDT_ATA:
+        case BDT_ATAPI:
+          res=ATAWBlks(dv,buf,blk,cnt);
+          break;
+      }
+      bd->last_time=tS;
+      if (bd->flags & BDF_READ_CACHE)
+        DskCacheAdd(dv,buf,blk,cnt);
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskBlkDev.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskBlkDev.HC.HTML new file mode 100755 index 0000000..aa34a8f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskBlkDev.HC.HTML @@ -0,0 +1,218 @@ + + + + + + + + + + + +
+Bool BlkDevLock(CBlkDev *bd)
+{//Make this task have exclusive access to BlkDev.
+  BlkDevChk(bd);
+  while (bd->lock_fwding)
+    bd=bd->lock_fwding; //If two blkdevs on same controller, use just one lock
+  if (!Bt(&bd->locked_flags,BDlf_LOCKED) || bd->owning_task!=Fs) {
+    while (LBts(&bd->locked_flags,BDlf_LOCKED))
+      Yield;
+    bd->owning_task=Fs;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE)
+{//Release exclusive lock on access to BlkDev.
+  BlkDevChk(bd);
+  while (bd->lock_fwding)
+    bd=bd->lock_fwding; //If two blkdevs on same controller, use just one lock
+  if (Bt(&bd->locked_flags,BDlf_LOCKED) && bd->owning_task==Fs) {
+    if (rst)
+      bd->flags&=~(BDF_INITIALIZED|BDF_INIT_IN_PROGRESS);
+    bd->owning_task=NULL;
+    LBtr(&bd->locked_flags,BDlf_LOCKED);
+    Yield; //Prevent deadlock
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool BlkDevInit(CBlkDev *bd)
+{
+  CDirEntry de;
+  U8 buf[STR_LEN];
+  CDrv *dv=Let2Drv(bd->first_drv_let);
+  Bool res=FALSE;
+  if (!LBts(&bd->flags,BDf_INITIALIZED)) {
+    bd->flags|=BDF_INIT_IN_PROGRESS;
+    switch (bd->type) {
+      case BDT_RAM:
+        if (!bd->RAM_dsk) {
+          bd->RAM_dsk=AMAlloc((bd->max_blk+1)<<BLK_SIZE_BITS);
+          bd->max_blk=MSize(bd->RAM_dsk)>>BLK_SIZE_BITS-1;
+        }
+        dv->fs_type=FSt_REDSEA;
+        dv->size=bd->max_blk+1-bd->drv_offset;
+        if (RedSeaValidate(bd->first_drv_let))
+          RedSeaInit(dv);
+        else
+          RedSeaFmt(bd->first_drv_let);
+        res=TRUE;
+        break;
+      case BDT_ISO_FILE_READ:
+        if (FileFind(bd->file_dsk_name,&de,FUF_JUST_FILES)) {
+          bd->max_blk=de.size>>BLK_SIZE_BITS-1;
+          try bd->file_dsk=FOpen(bd->file_dsk_name,"rc",bd->max_blk+1);
+          catch {
+            if (Fs->except_ch=='File')
+              PrintErr("Not Contiguous.  Move file to filename.ISO.C.\n");
+            Fs->catch_except=TRUE;
+          }
+          if (bd->file_dsk) {
+            dv->fs_type=FSt_REDSEA;
+            dv->size=bd->max_blk+1-bd->drv_offset;
+            if (RedSeaValidate(bd->first_drv_let)) {
+              RedSeaInit(dv);
+              res=TRUE;
+            } else
+              PrintErr("Not RedSea\n");
+          }
+        }
+        break;
+      case BDT_ISO_FILE_WRITE:
+        if (!bd->file_dsk_name) {
+          StrPrint(buf,"%C:/Drv%C.ISO.C",
+                blkdev.boot_drv_let,bd->first_drv_let);
+          bd->file_dsk_name=AStrNew(buf);
+        }
+        if (bd->max_blk<7)
+          bd->max_blk=7;
+        bd->file_dsk=FOpen(bd->file_dsk_name,"wc",bd->max_blk+1);
+        dv->fs_type=FSt_REDSEA;
+        dv->size=bd->max_blk+1-bd->drv_offset;
+        RedSeaFmt(bd->first_drv_let);
+        CallExtStr("RedSeaISO9660",bd->file_dsk_name,bd->first_drv_let);
+        res=TRUE;
+        break;
+      case BDT_ATA:
+        bd->max_reads=128;
+        bd->max_writes=1;
+        res=ATAInit(bd);
+        break;
+      case BDT_ATAPI:
+//0xFFFF*4 is too big for my taste
+        bd->max_reads=0x800*4;
+//max of maybe a quarter of disk cache
+        if (bd->max_reads>blkdev.cache_size/BLK_SIZE/4)
+          bd->max_reads=blkdev.cache_size/BLK_SIZE/4 & ~3;
+        if (bd->max_reads<128)
+          bd->max_reads=128;
+        bd->max_writes=0xFFFF*4;
+        if (res=ATAInit(bd))
+          dv->size=bd->max_blk+1;
+        break;
+    }
+    if (res && bd->flags & BDF_READ_CACHE)
+      DskCacheInvalidate(dv);
+    bd->flags&=~BDF_INIT_IN_PROGRESS;
+  } else
+    res=TRUE;
+  return res;
+}
+
+U0 BlkDevsRelease()
+{//When task dies, release all owned BlkDevs.
+  I64 i;
+  CBlkDev *bd;
+  for (i=0;i<BLKDEVS_NUM;i++) {
+    bd=&blkdev.blkdevs[i];
+    if (bd->owning_task==Fs && bd->bd_signature==BD_SIGNATURE_VAL)
+      BlkDevUnlock(bd,TRUE);
+  }
+}
+
+CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type)
+{//Locate free slot for new BlkDev, like during Mount().
+  I64 i=0;
+  CBlkDev *res;
+  if (Let2BlkDevType(first_drv_let)!=type)
+    throw('BlkDev');
+  do {
+    res=&blkdev.blkdevs[i];
+    if (res->bd_signature!=BD_SIGNATURE_VAL) {
+      MemSet(res,0,sizeof(CBlkDev));
+      res->first_drv_let=first_drv_let;
+      res->type=type;
+      res->flags=BDF_READ_CACHE;
+      res->blk_size=BLK_SIZE;
+      res->max_blk=0xEFFFFFFF;
+      switch (type) {
+        case BDT_RAM:
+          res->flags&=~BDF_READ_CACHE;
+          break;
+        case BDT_ISO_FILE_READ:
+          res->flags|=BDF_READ_ONLY;
+          break;
+        case BDT_ATAPI:
+          res->flags|=BDF_REMOVABLE|BDF_READ_ONLY;
+          res->blk_size=DVD_BLK_SIZE;
+          break;
+      }
+      return res;
+    }
+  } while (++i<BLKDEVS_NUM);
+  throw('BlkDev');
+  return NULL; //never gets here
+}
+
+U0 BlkDevDel(CBlkDev *bd)
+{//Delete BlkDev
+  DrvBlkDevDel(bd);
+  FClose(bd->file_dsk);
+  Free(bd->file_dsk_name);
+  Free(bd->dev_id_record);
+  MemSet(bd,0,sizeof(CBlkDev));
+}
+
+CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE)
+{//Check for valid BlkDev. Throw exception.
+  if (!bd || bd->bd_signature!=BD_SIGNATURE_VAL ||
+        !(BDT_NULL<bd->type<BDT_TYPES_NUM)) {
+    if (except)
+      throw('BlkDev');
+    else
+      return NULL;
+  } else
+    return bd;
+}
+
+CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE)
+{//Drv letter to BlkDev ptr.
+  CDrv *dv;
+  if (dv=Let2Drv(drv_let,except))
+    return BlkDevChk(dv->bd,except);
+  else
+    return NULL;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskCDDVD.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskCDDVD.HC.HTML new file mode 100755 index 0000000..cb953a3 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskCDDVD.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+Bool ISOInit(CDrv *dv,I64 blk)
+{
+  CBlkDev *bd=dv->bd;
+  I64 spc=bd->blk_size>>BLK_SIZE_BITS,i=blk/spc,drv_offset=0;
+  CISOPriDesc *iso=MAlloc(bd->blk_size);
+  CISODirEntry *de;
+  Bool unlock,res=FALSE;
+  U8 buf[8];
+
+  try {
+    unlock=DrvLock(dv);
+    dv->fs_type=FSt_ISO9660;
+    dv->spc=spc;
+    dv->data_area=dv->root_clus=dv->drv_offset=bd->drv_offset=dv->size=0;
+    while (TRUE) {
+      dv->size=MaxI64(dv->size,(i+1)*spc);
+      BlkRead(dv,iso,i*spc,spc);
+      buf[0](U32)=iso->id[0](U32);
+      buf[4](U16)=iso->id[4](U8);
+      switch (LstMatch(buf,"CD001\0CDW02\0BEA01\0BOOT2\0NSR02\0NSR03\0TEA01\0",
+            LMF_EXACT)) {
+        case 0:
+          switch (iso->type) {
+            case ISOT_BOOT_RECORD:
+              drv_offset+=(2*DVD_BLK_SIZE+DVD_BLK_SIZE)/BLK_SIZE;
+              break;
+            case ISOT_SUPPLEMENTARY_DESC:
+              de=&iso->root_dir_record;
+              dv->size=iso->vol_space_size.little*bd->blk_size>>BLK_SIZE_BITS;
+              if (!StrCmp(iso->publisher_id,"TempleOS RedSea")) {
+                dv->fs_type=FSt_REDSEA;
+                bd->drv_offset=dv->drv_offset=19<<2+drv_offset;
+                bd->max_blk=dv->size-1;
+                dv->size-=bd->drv_offset;
+                RedSeaInit(dv);
+              } else
+                dv->root_clus=de->loc.little;
+              res=TRUE;
+              goto di_done;
+            case ISOT_TERMINATOR:
+              throw('Drv');
+          }
+          break;
+        default: //Its normal for ISO3346 to read NULL blk as terminator
+          PrintErr("File System Not Supported\n");
+          throw('Drv');
+      }
+      i++;
+    }
+di_done:
+    Free(iso);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch {
+    dv->fs_type=FSt_ISO9660;
+    dv->spc=spc;
+    dv->drv_offset=bd->drv_offset=dv->data_area=dv->root_clus=0;
+    Free(iso);
+    if (unlock)
+      DrvUnlock(dv);
+  }
+  return res;
+}
+
+U0 DVDImageRead(U8 dvd_drv_let,U8 *out_name)
+{//Read entire CD/DVD image into ISO file.
+  CDrv *dv=Let2Drv(dvd_drv_let);
+  CBlkDev *bd=dv->bd;
+  U8 *buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS),
+        *out_name2=ExtDft(out_name,"ISO");
+  CFile *f=FOpen(out_name2,"w");
+  I64 n,spc=bd->blk_size>>BLK_SIZE_BITS,blk=0,cnt,retry;
+  BlkDevInit(bd);
+  if (bd->type!=BDT_ATAPI)
+    throw('BlkDev');
+  if (!out_name)
+    out_name=blkdev.dft_iso_filename;
+  cnt=CeilU64(dv->size,spc);
+  while (cnt>0) {
+    if (cnt>COPY_BUF_BLKS)
+      n=COPY_BUF_BLKS;
+    else
+      n=cnt;
+    if (n>bd->max_reads)
+      n=bd->max_reads;
+
+    retry=4;
+    while (--retry)
+      if (ATAPIReadBlks2(bd,tS+7.0+0.004*n/spc,buf,blk/spc,n/spc,TRUE))
+//n is 0x800 if max_reads.  Up to 8 additional seconds
+        break;
+
+    if (!retry)
+      ATAPIReadBlks2(bd,0,buf,blk/spc,n/spc,TRUE);
+
+    FBlkWrite(f,buf,blk,n);
+    cnt-=n;
+    blk+=n;
+  }
+  FClose(f);
+  Free(buf);
+  Free(out_name2);
+}
+
+class CDualBuf
+{
+  U8 *buf0,*buf1;
+  I64 in_buf,out_buf,cnt;
+  U8 *filename;
+  CBlkDev *dvd_bd;
+};
+
+U0 DVDImageWriteTask(CDualBuf *d)
+{
+  U8 *buf;
+  I64 n,blk=0,cnt=d->cnt;
+  CFile *f;
+  if (FileAttr(d->filename)&RS_ATTR_CONTIGUOUS)
+    f=FOpen(d->filename,"rc");
+  else
+    f=FOpen(d->filename,"r");
+  while (cnt>0) {
+    if (cnt>COPY_BUF_BLKS)
+      n=COPY_BUF_BLKS;
+    else
+      n=cnt;
+    if (n>d->dvd_bd->max_writes)
+      n=d->dvd_bd->max_writes;
+    if (d->in_buf&1)
+      buf=d->buf1;
+    else
+      buf=d->buf0;
+    while (d->in_buf>d->out_buf+1)
+      Yield;
+    FBlkRead(f,buf,blk,n);
+    d->in_buf++;
+    cnt-=n;
+    blk+=n;
+  }
+  FClose(f);
+}
+
+U0 DVDImageWrite(U8 dvd_drv_let,U8 *in_name=NULL,I64 media_type=MT_DVD)
+{//Write CD/DVD ISO file to disk.
+  CDualBuf *d=CAlloc(sizeof(CDualBuf));
+  U8 *buf,*in_name2,*in_name3;
+  I64 i,n,spc,blk=0,cnt;
+  CDrv *dv=Let2Drv(dvd_drv_let);
+  CBlkDev *bd=dv->bd,*bd2;
+  CTask *task;
+  CFile *f;
+
+  if (!in_name)
+    in_name=blkdev.dft_iso_filename;
+  in_name3=ExtDft(in_name,"ISO");
+  in_name2=FileNameAbs(in_name3);
+  f=FOpen(in_name2,"r");
+  if (!f) {
+    Free(d);
+    return;
+  }
+  cnt=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS;
+  FClose(f);
+  if (bd->type!=BDT_ATAPI)
+    throw('BlkDev');
+  bd2=Let2BlkDev(*in_name2);
+  while (bd2->lock_fwding)
+    bd2=bd2->lock_fwding;  //If two blkdevs on same controller, use one lock
+  if ((bd2->type==BDT_ATA || bd2->type==BDT_ATAPI) &&
+        bd2->base0==bd->base0) {
+    PrintErr("Can't burn CD/DVD on same ATA controller as file.\n\n");
+    throw('BlkDev');
+  }
+
+  bd->flags|=BDF_READ_ONLY_OVERRIDE;
+  BlkDevInit(bd);
+  spc=bd->blk_size>>BLK_SIZE_BITS;
+  if (dv->size<cnt)
+    dv->size=cnt;
+
+  d->filename=in_name2;
+  d->dvd_bd=bd;
+  d->buf0=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
+  d->buf1=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
+  d->cnt=cnt;
+
+  task=Spawn(&DVDImageWriteTask,d,"Write CD/DVD");
+  while (d->in_buf<=d->out_buf)
+    Yield;
+
+  BlkDevLock(bd);
+  ATAPIWaitReady(bd,0);
+
+  progress1=0; progress1_max=cnt;
+  StrCpy(progress1_desc,"Writing");
+  while (cnt>0) {
+    if (cnt>COPY_BUF_BLKS)
+      n=COPY_BUF_BLKS;
+    else
+      n=cnt;
+    if (n>bd->max_writes)
+      n=bd->max_writes;
+    if (d->out_buf&1)
+      buf=d->buf1;
+    else
+      buf=d->buf0;
+    while (d->in_buf<=d->out_buf)
+      Yield;
+    ATAPIWriteBlks(bd,buf,blk/spc,(n+spc-1)/spc);
+    d->out_buf++;
+    cnt-=n;
+    blk+=n;
+    progress1+=n;
+  }
+  ATAPISync(bd);
+
+  progress1=0; progress1_max=2;
+  StrCpy(progress1_desc,"Closing");
+  for (i=0;i<2;i++) {
+    ATAPIClose(bd,0x100,i); //Close tracks
+    progress1++;
+  }
+
+  ATAPISync(bd);
+
+  ATAPIClose(bd,0x200); //close disk
+  ATAPISync(bd);
+  if (media_type==MT_DVD) {
+    ATAPIClose(bd,0x300);
+    ATAPISync(bd);
+  }
+
+  *progress1_desc=0;
+  progress1=progress1_max=0;
+
+  bd->flags&=~BDF_READ_ONLY_OVERRIDE;
+  BlkDevUnlock(bd);
+  Free(d->buf0);
+  Free(d->buf1);
+  Free(in_name2);
+  Free(in_name3);
+  Free(d);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskCFile.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskCFile.HC.HTML new file mode 100755 index 0000000..3515493 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskCFile.HC.HTML @@ -0,0 +1,296 @@ + + + + + + + + + + + +
+I64 FSize(CFile *f)
+{//Report size of opened file in bytes.
+  if (f)
+    return f->de.size;
+  else
+    return 0;
+}
+
+CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0)
+{//Allows flags "r","w","w+". "c" for contiguous.
+//(It uses StrOcc() for 'w', 'r', '+', 'c')
+  CFile *f=CAlloc(sizeof(CFile));
+  CDirContext *dirc;
+  U8 *full_name;
+  Bool contiguous=StrOcc(flags,'c');
+
+  f->clus=INVALID_CLUS;
+  f->fblk_num=0;
+  if (cnt>0)
+    f->max_blk=cnt-1;
+  else
+    f->max_blk=I64_MAX;
+  f->file_clus_num=INVALID_CLUS;
+  full_name=FileNameAbs(filename);
+  f->dv=Let2Drv(*full_name);
+  if (f->dv->fs_type==FSt_REDSEA)
+    contiguous=TRUE;
+  if (contiguous) {
+    f->flags|=FF_CONTIGUOUS;
+    if (f->dv->fs_type!=FSt_REDSEA &&
+          !(FileAttr(filename) & RS_ATTR_CONTIGUOUS))
+      throw('File');
+  }
+  f->clus_buf=CAlloc(f->dv->spc<<BLK_SIZE_BITS);
+  if (StrOcc(flags,'w')) {
+    f->flags=f->flags|FF_WRITE|FF_NEEDS_WRITE;
+    if (StrOcc(flags,'+')) {
+      if (FileFind(full_name,&f->de,FUF_JUST_FILES)) {
+        Free(full_name);
+        if (contiguous)
+          f->max_blk=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS-1;
+        return f;
+      }
+    } else
+      Del(full_name,,,FALSE);
+    f->de.full_name=full_name;
+    f->flags|=FF_NEW_FILE;
+    if (dirc=DirContextNew(full_name)) {
+      StrCpy(f->de.name,dirc->mask);
+      if (cnt>0) {//We pre-alloc the whole thing.
+        f->de.clus=ClusAlloc(f->dv,0,
+              (cnt+f->dv->spc-1)/f->dv->spc,contiguous);
+        f->de.size=cnt<<BLK_SIZE_BITS;
+        DirNew(dirc->dv,Fs->cur_dir,&f->de,TRUE);
+        f->flags&=~FF_NEW_FILE;
+      }
+      DirContextDel(dirc);
+      return f;
+    }
+  } else {
+    if (FileFind(full_name,&f->de,FUF_JUST_FILES)) {
+      Free(full_name);
+      f->max_blk=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS-1;
+      return f;
+    }
+  }
+  Free(f->clus_buf);
+  Free(full_name);
+  Free(f);
+  return NULL;
+}
+
+U0 FClose(CFile *f)
+{//Close CFile, updating directory.
+  CDirContext *dirc;
+  if (f) {
+    if (f->flags & FF_BUF_DIRTY) {
+      ClusWrite(f->dv,f->clus_buf,f->clus,1);
+      f->flags&=~FF_BUF_DIRTY;
+    }
+    if (f->flags & FF_NEEDS_WRITE) {
+      if (dirc=DirContextNew(f->de.full_name)) {
+        if (!(f->flags & FF_USE_OLD_DATETIME))
+          f->de.datetime=Now;
+        if (f->flags & FF_NEW_FILE)
+          DirNew(dirc->dv,Fs->cur_dir,&f->de,TRUE);
+        else
+          DirNew(dirc->dv,Fs->cur_dir,&f->de,FALSE);
+        DirContextDel(dirc);
+      } else
+        throw('File');
+    }
+    Free(f->clus_buf);
+    Free(f->de.full_name);
+    Free(f);
+  }
+}
+
+I64 FSetClus(CFile *f,I64 c,I64 blk,Bool read)
+{
+  CDrv *dv=f->dv;
+  I64 i;
+  if (f->clus!=c) {
+    if (f->flags & FF_BUF_DIRTY) {
+      i=dv->spc;
+      if (f->max_blk!=I64_MAX) {
+        i=f->max_blk+1-f->file_clus_num*dv->spc;
+        if (i>dv->spc)
+          i=dv->spc;
+      }
+      ClusBlkWrite(dv,f->clus_buf,f->clus,i);
+      f->flags=f->flags & ~FF_BUF_DIRTY;
+    }
+    f->clus=c;
+    f->file_clus_num=blk/dv->spc;
+    if (read) {
+      i=dv->spc;
+      if (f->max_blk!=I64_MAX) {
+        i=f->max_blk+1-f->file_clus_num*dv->spc;
+        if (i>dv->spc)
+          i=dv->spc;
+      }
+      c=ClusBlkRead(dv,f->clus_buf,c,i);
+    }
+  }
+  return c;
+}
+
+Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
+{//Read [nth,n+cnt) blks of file.
+  CDrv *dv=f->dv;
+  I64 spc=dv->spc,i,j,c=f->de.clus;
+  if (!f || !dv) return FALSE;
+  if (blk==FFB_NEXT_BLK)
+    blk=f->fblk_num;
+  if (blk+cnt-1>f->max_blk)
+    return FALSE;
+  if (cnt<=0) return TRUE;
+
+  if (f->flags & FF_CONTIGUOUS) {
+    BlkRead(dv,buf,Clus2Blk(dv,c)+blk,cnt);
+    blk+=cnt;
+  } else {
+    i=blk/spc;
+    if (0<=f->file_clus_num<=i) {
+      c=f->clus;
+      i-=f->file_clus_num;
+    }
+    if (i>0)
+      c=ClusNumNext(dv,c,i);
+
+    if (i=blk%spc) {
+      c=FSetClus(f,c,blk,TRUE);
+      if (cnt<spc-i)
+        j=cnt;
+      else
+        j=spc-i;
+      MemCpy(buf,f->clus_buf+i<<BLK_SIZE_BITS,j<<BLK_SIZE_BITS);
+      buf+=j<<BLK_SIZE_BITS;
+      cnt-=j;
+      blk+=j;
+    }
+    while (cnt>=spc) {
+      c=FSetClus(f,c,blk,TRUE);
+      MemCpy(buf,f->clus_buf,spc<<BLK_SIZE_BITS);
+      buf+=spc<<BLK_SIZE_BITS;
+      cnt-=spc;
+      blk+=spc;
+    }
+    if (cnt>0) {
+      c=FSetClus(f,c,blk,TRUE);
+      MemCpy(buf,f->clus_buf,cnt<<BLK_SIZE_BITS);
+      buf+=cnt<<BLK_SIZE_BITS;
+      blk+=cnt;
+    }
+  }
+  f->fblk_num=blk;
+  return TRUE;
+}
+
+Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
+{//Write [nth,n+cnt) blks of file.
+  CDrv *dv=f->dv;
+  I64 spc=dv->spc,i,j,c=f->de.clus,c1;
+  if (!f || !dv) return FALSE;
+  if (blk==FFB_NEXT_BLK)
+    blk=f->fblk_num;
+  if (blk+cnt-1>f->max_blk)
+    return FALSE;
+  if (!(f->flags & FF_WRITE))
+    return FALSE;
+  if (cnt<=0) return TRUE;
+  if (f->flags & FF_CONTIGUOUS) {
+    BlkWrite(dv,buf,Clus2Blk(dv,c)+blk,cnt);
+    blk+=cnt;
+  } else {
+    if (!c) {
+      c=ClusAlloc(dv,0,1,FALSE);
+      f->file_clus_num=0;
+      f->clus=c;
+      f->de.clus=c;
+      f->flags|=FF_NEEDS_WRITE|FF_NEW_FILE;
+    }
+    i=blk/spc;
+    if (0<=f->file_clus_num<=i) {
+      c=f->clus;
+      i-=f->file_clus_num;
+    }
+    while (i>0) {
+      c1=c;
+      c=ClusNumNext(dv,c1,1);
+      if (c==INVALID_CLUS) {
+        c=ClusAlloc(dv,c1,i,FALSE);
+        if (i>1)
+          c=ClusNumNext(dv,c,i-1);
+        break;
+      } else
+        i--;
+    }
+
+    if (i=blk%spc) {
+      FSetClus(f,c,blk,TRUE);
+      if (cnt<spc-i)
+        j=cnt;
+      else
+        j=spc-i;
+      MemCpy(f->clus_buf+BLK_SIZE*i,buf,j<<BLK_SIZE_BITS);
+      f->flags|=FF_BUF_DIRTY;
+      buf+=j<<BLK_SIZE_BITS;
+      cnt-=j;
+      blk+=j;
+      if (cnt>0) {
+        c1=c;
+        c=ClusNumNext(dv,c1,1);
+        if (c==INVALID_CLUS)
+          c=ClusAlloc(dv,c1,1,FALSE);
+      }
+    }
+    while (cnt>=spc) {
+      FSetClus(f,c,blk,FALSE);
+      MemCpy(f->clus_buf,buf,spc<<BLK_SIZE_BITS);
+      f->flags|=FF_BUF_DIRTY;
+      buf+=spc<<BLK_SIZE_BITS;
+      cnt-=spc;
+      blk+=spc;
+      if (cnt>0) {
+        c1=c;
+        c=ClusNumNext(dv,c1,1);
+        if (c==INVALID_CLUS)
+          c=ClusAlloc(dv,c1,1,FALSE);
+      }
+    }
+    if (cnt>0) {
+      FSetClus(f,c,blk,TRUE);
+      MemCpy(f->clus_buf,buf,cnt<<BLK_SIZE_BITS);
+      f->flags|=FF_BUF_DIRTY;
+      buf+=cnt<<BLK_SIZE_BITS;
+      blk+=cnt;
+    }
+    if (f->de.size<blk<<BLK_SIZE_BITS)
+      f->de.size=blk<<BLK_SIZE_BITS;
+  }
+  f->fblk_num=blk;
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskCache.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskCache.HC.HTML new file mode 100755 index 0000000..159b918 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskCache.HC.HTML @@ -0,0 +1,176 @@ + + + + + + + + + + + +
+U0 DskCacheInit(I64 size_in_U8s)
+{
+  CCacheBlk *tmpc;
+  I64 i,cnt;
+
+  while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+    Yield;
+  Free(blkdev.cache_ctrl);
+  Free(blkdev.cache_base);
+  Free(blkdev.cache_hash_table);
+  if (size_in_U8s<0x2000) {
+    blkdev.cache_ctrl=NULL;
+    blkdev.cache_base=NULL;
+    blkdev.cache_hash_table=NULL;
+  } else {
+    blkdev.cache_ctrl=ACAlloc(offset(CCacheBlk.body));
+    blkdev.cache_base=AMAlloc(size_in_U8s);
+    QueInit(blkdev.cache_ctrl);
+
+    cnt=MSize(blkdev.cache_base)/sizeof(CCacheBlk);
+    blkdev.cache_size=cnt*BLK_SIZE;
+    for (i=0;i<cnt;i++) {
+      tmpc=blkdev.cache_base+i;
+      QueIns(tmpc,blkdev.cache_ctrl->last_lru);
+      tmpc->next_hash=tmpc->last_hash=tmpc;
+      tmpc->dv=NULL;
+      tmpc->blk=0;
+    }
+
+    blkdev.cache_hash_table=AMAlloc(DSK_CACHE_HASH_SIZE*sizeof(U8 *)*2);
+    for (i=0;i<DSK_CACHE_HASH_SIZE;i++) {
+      tmpc=blkdev.cache_hash_table(U8 *)+i*sizeof(U8 *)*2
+            -offset(CCacheBlk.next_hash);
+      tmpc->next_hash=tmpc->last_hash=tmpc;
+    }
+  }
+  LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+}
+
+I64 DskCacheHash(I64 blk)
+{
+  I64 i=blk & (DSK_CACHE_HASH_SIZE-1);
+  return blkdev.cache_hash_table(U8 *)+i<<4-offset(CCacheBlk.next_hash);
+}
+
+U0 DskCacheQueRem(CCacheBlk *tmpc)
+{
+  QueRem(tmpc);
+  tmpc->next_hash->last_hash=tmpc->last_hash;
+  tmpc->last_hash->next_hash=tmpc->next_hash;
+}
+
+U0 DskCacheQueIns(CCacheBlk *tmpc)
+{
+  CCacheBlk *tmp_n,*tmp_l;
+  QueIns(tmpc,blkdev.cache_ctrl->last_lru);
+  tmp_l=DskCacheHash(tmpc->blk);
+  tmp_n=tmp_l->next_hash;
+  tmpc->last_hash=tmp_l;
+  tmpc->next_hash=tmp_n;
+  tmp_l->next_hash=tmp_n->last_hash=tmpc;
+}
+
+CCacheBlk *DskCacheFind(CDrv *dv,I64 blk)
+{
+  CCacheBlk *tmpc,*tmpc1=DskCacheHash(blk);
+  tmpc=tmpc1->next_hash;
+  while (tmpc!=tmpc1) {
+    if (tmpc->dv==dv && tmpc->blk==blk)
+      return tmpc;
+    tmpc=tmpc->next_hash;
+  }
+  return NULL;
+}
+
+U0 DskCacheAdd(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{
+  CCacheBlk *tmpc;
+  if (blkdev.cache_base) {
+    while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+      Yield;
+    while (cnt-->0) {
+      if (!(tmpc=DskCacheFind(dv,blk)))
+        tmpc=blkdev.cache_ctrl->next_lru;
+      DskCacheQueRem(tmpc);
+      MemCpy(&tmpc->body,buf,BLK_SIZE);
+      tmpc->dv=dv;
+      tmpc->blk=blk;
+      DskCacheQueIns(tmpc);
+      blk++;
+      buf+=BLK_SIZE;
+    }
+    LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+  }
+}
+
+U0 DskCacheInvalidate2(CDrv *dv)
+{
+  CCacheBlk *tmpc,*tmpc1;
+  if (blkdev.cache_base) {
+    while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+      Yield;
+    tmpc=blkdev.cache_ctrl->last_lru;
+    while (tmpc!=blkdev.cache_ctrl) {
+      tmpc1=tmpc->last_lru;
+      if (tmpc->dv==dv) {
+        DskCacheQueRem(tmpc);
+        tmpc->dv=NULL;
+        tmpc->blk=0;
+        tmpc->next_hash=tmpc->last_hash=tmpc;
+        QueIns(tmpc,blkdev.cache_ctrl->last_lru);
+      }
+      tmpc=tmpc1;
+    }
+    LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+  }
+}
+
+U0 RCache(CDrv *dv,U8 **_buf, I64 *_blk, I64 *_cnt)
+{
+  CCacheBlk *tmpc;
+  if (blkdev.cache_base) {
+    while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+      Yield;
+//fetch leading blks from cache
+    while (*_cnt>0) {
+      if (tmpc=DskCacheFind(dv,*_blk)) {
+        MemCpy(*_buf,&tmpc->body,BLK_SIZE);
+        *_cnt-=1;
+        *_buf+=BLK_SIZE;
+        *_blk+=1;
+      } else
+        break;
+    }
+//fetch trailing blks from cache
+    while (*_cnt>0) {
+      if (tmpc=DskCacheFind(dv,*_blk+*_cnt-1)) {
+        MemCpy(*_buf+(*_cnt-1)<<BLK_SIZE_BITS,&tmpc->body,BLK_SIZE);
+        *_cnt-=1;
+      } else
+        break;
+    }
+    LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskClus.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskClus.HC.HTML new file mode 100755 index 0000000..595907b --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskClus.HC.HTML @@ -0,0 +1,176 @@ + + + + + + + + + + + +
+I64 ClusNumNext(CDrv *dv,I64 c,I64 cnt=1)
+{//Return next cnt'th clus in chain.
+  Bool unlock;
+  DrvChk(dv);
+  if (cnt<=0) return c;
+  try {
+    unlock=DrvLock(dv);
+    switch (dv->fs_type) {
+      case FSt_REDSEA:
+        c+=cnt;
+        break;
+      case FSt_FAT32:
+        while (cnt-->0 && 0<c<0x0FFFFFF8) {
+          DrvFATBlkSet(dv,c);
+          c=dv->cur_fat_blk[c & (BLK_SIZE/4-1)];
+        }
+        if (!(0<c<0x0FFFFFF8))
+          c=INVALID_CLUS;
+        break;
+      default:
+        throw('Drv');
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return c;
+}
+
+I64 Clus2Blk(CDrv *dv,I64 c)
+{//Drv clus num to blk num.
+  DrvChk(dv);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      return c;
+    case FSt_FAT32:
+      return dv->data_area+c*dv->spc;
+    default:
+      throw('Drv');
+  }
+}
+
+I64 ClusBlkRead(CDrv *dv,U8 *buf,I64 c,I64 blks)
+{//Accepts blk count, so padding on last clus is not read.
+  I64 i;
+  Bool unlock;
+  DrvChk(dv);
+  if (blks<=0) return c;
+  try {
+    unlock=DrvLock(dv);
+    switch (dv->fs_type) {
+      case FSt_REDSEA:
+        BlkRead(dv,buf,c,blks);
+        c+=blks;
+        break;
+      case FSt_FAT32:
+        while (blks && 0<c<0x0FFFFFF8) {
+          i=blks;
+          if (i>dv->spc)
+            i=dv->spc;
+          BlkRead(dv,buf,dv->data_area+c*dv->spc,i);
+          buf+=i<<BLK_SIZE_BITS;
+          c=ClusNumNext(dv,c,1);
+          blks-=i;
+        }
+        if (blks)
+          throw('Drv');
+        break;
+      default:
+        throw('Drv');
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return c;
+}
+
+I64 ClusRead(CDrv *dv,U8 *buf,I64 c,I64 cnt)
+{//Read clus cnt from drv to buf.
+  return ClusBlkRead(dv,buf,c,cnt*dv->spc);
+}
+
+I64 ClusBlkWrite(CDrv *dv,U8 *buf,I64 c,I64 blks)
+{//Accepts blk count, so padding on last clus is not written.
+  I64 i;
+  Bool unlock;
+  DrvChk(dv);
+  if (blks<=0) return c;
+  try {
+    unlock=DrvLock(dv);
+    switch (dv->fs_type) {
+      case FSt_REDSEA:
+        BlkWrite(dv,buf,c,blks);
+        c=0;
+        break;
+      case FSt_FAT32:
+        while (blks) {
+          if (!(0<c<0x0FFFFFF8))
+            throw('Drv');
+          i=blks;
+          if (i>dv->spc)
+            i=dv->spc;
+          BlkWrite(dv,buf,dv->data_area+c*dv->spc,i);
+          buf+=i<<BLK_SIZE_BITS;
+          c=ClusNumNext(dv,c);
+          blks-=i;
+        }
+        break;
+      default:
+        throw('Drv');
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return c;
+}
+
+I64 ClusWrite(CDrv *dv,U8 *buf,I64 c,I64 cnt)
+{//Write clus cnt from buf to drv.
+  return ClusBlkWrite(dv,buf,c,cnt*dv->spc);
+}
+
+I64 ClusAlloc(CDrv *dv,I64 c=0,I64 cnt=1,Bool contiguous=FALSE)
+{//Alloc clus cnt into chain.
+//c=0 means first clus in chain
+  DrvChk(dv);
+  if (cnt<=0) return c;
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      return RedSeaAllocClus(dv,cnt);
+    case FSt_FAT32:
+      if (contiguous) {
+        if (c) throw('File');
+        return FAT32AllocContiguousClus(dv,cnt);
+      } else
+        return FAT32AllocClus(dv,c,cnt);
+    default:
+      throw('Drv');
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskCopy.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskCopy.HC.HTML new file mode 100755 index 0000000..389794f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskCopy.HC.HTML @@ -0,0 +1,134 @@ + + + + + + + + + + + +
+Bool CopySingleZ(U8 *f1,U8 *f2) //Just one file
+{
+  U8 *file_buf=NULL;
+  I64 size,attr=0,c;
+  CDirEntry de;
+  if (FileFind(f1,&de,FUF_JUST_FILES)) {
+    Free(de.full_name);
+    file_buf=FileRead(f1,&size,&attr);
+    attr=FileAttr(f2,attr);
+    if (file_buf) {
+      "Copying %s to %s\n",f1,f2;
+      c=FileWrite(f2,file_buf,size,de.datetime,attr);
+      Free(file_buf);
+      return ToBool(c);
+    } else
+      PrintErr("File not found: \"%s\".\n",f1);
+  } else
+    PrintErr("File not found: \"%s\".\n",f1);
+  return FALSE;
+}
+
+#define COPY_BUF_BLKS   0x80
+Bool CopySingle(U8 *f1,U8 *f2) //Just one file
+{
+  U8 *absf1=FileNameAbs(f1),*absf2=FileNameAbs(f2),*buf;
+  I64 cnt,n,size,attr1=FileAttr(f1),attr2=FileAttr(f2),i,j;
+  CFile *in_file=NULL,*out_file=NULL;
+  if (!StrCmp(absf1,absf2)) {//onto self?
+    Free(absf1);
+    Free(absf2);
+    return FALSE;
+  }
+  Free(absf1);
+  Free(absf2);
+  if (attr1!=attr2)
+    return CopySingleZ(f1,f2);
+  buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
+  if (attr1 & RS_ATTR_CONTIGUOUS)
+    in_file=FOpen(f1,"rc");
+  else
+    in_file=FOpen(f1,"r");
+  if (in_file) {
+    size=FSize(in_file);
+    cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    if (attr2 & RS_ATTR_CONTIGUOUS)
+      out_file=FOpen(f2,"wc",cnt);
+    else
+      out_file=FOpen(f2,"w",cnt);
+    if (out_file) {
+      "Copying %s to %s\n",f1,f2;
+      j=size;
+      while (cnt>0) {
+        if (cnt>COPY_BUF_BLKS) {
+          n=COPY_BUF_BLKS;
+          i=n<<BLK_SIZE_BITS;
+        } else {
+          n=cnt;
+          i=j;
+        }
+        FBlkRead(in_file, buf,FFB_NEXT_BLK,n);
+        FBlkWrite(out_file,buf,FFB_NEXT_BLK,n);
+        cnt-=n;
+        j-=n<<BLK_SIZE_BITS;
+      }
+      out_file->flags|=FF_USE_OLD_DATETIME;
+      out_file->de.datetime=in_file->de.datetime;
+      out_file->de.size=size;
+      out_file->de.attr=FileAttr(f2,in_file->de.attr);
+      FClose(out_file);
+      FClose(in_file);
+      Free(buf);
+      return TRUE;
+    } else
+      PrintErr("File not found: \"%s\".\n",f2);
+    FClose(in_file);
+  } else
+    PrintErr("File not found: \"%s\".\n",f1);
+  Free(buf);
+  return FALSE;
+}
+
+I64 Del(U8 *files_find_mask,Bool make_mask=FALSE,
+        Bool del_dir=FALSE,Bool print_msg=TRUE)
+{//Delete files.
+  I64 res=0;
+  CDirContext *dirc;
+  if (dirc=DirContextNew(files_find_mask,make_mask)) {
+    switch (dirc->dv->fs_type) {
+      case FSt_REDSEA:
+        res=RedSeaFilesDel(dirc->dv,Fs->cur_dir,dirc->mask,
+              0,del_dir,print_msg);
+        break;
+      case FSt_FAT32:
+        res=FAT32FilesDel(dirc->dv,Fs->cur_dir,dirc->mask,
+              0,del_dir,print_msg);
+        break;
+      default:
+        PrintErr("File System Not Supported\n");
+    }
+    DirContextDel(dirc);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskDirA.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskDirA.HC.HTML new file mode 100755 index 0000000..2ef9c9f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskDirA.HC.HTML @@ -0,0 +1,242 @@ + + + + + + + + + + + +
+Bool DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain=TRUE)
+{//Makes a directory entry in the directory from a CDirEntry node.
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      return RedSeaDirNew(dv,cur_dir,tmpde,free_old_chain);
+    case FSt_FAT32:
+      return FAT32DirNew(dv,cur_dir,tmpde,free_old_chain);
+    default:
+      PrintErr("File System Not Supported\n");
+      return FALSE;
+  }
+}
+
+U0 DirEntryDel(CDirEntry *tmpde)
+{//Free node returned from FilesFind().  Doesn't Free user_data.
+//Does not change the directory on disk.
+  if (tmpde) {
+    Free(tmpde->full_name);
+    Free(tmpde);
+  }
+}
+
+U0 DirEntryDel2(CDirEntry *tmpde)
+{//Free node returned from FilesFind().  Frees user_data
+//Does not change the directory on disk.
+  if (tmpde) {
+    Free(tmpde->full_name);
+    Free(tmpde->user_data);
+    Free(tmpde);
+  }
+}
+
+U0 DirTreeDel(CDirEntry *tmpde)
+{//Free tree returned from FilesFind().  Doesn't Free user_data.
+//Does not change the directory on disk.
+  CDirEntry *tmpde2;
+  while (tmpde) {
+    tmpde2=tmpde->next;
+    if (tmpde->sub)
+      DirTreeDel(tmpde->sub);
+    DirEntryDel(tmpde);
+    tmpde=tmpde2;
+  }
+}
+
+U0 DirTreeDel2(CDirEntry *tmpde)
+{//Free tree returned from FilesFind().  Frees user_data
+//Does not change the directory on disk.
+  CDirEntry *tmpde2;
+  while (tmpde) {
+    tmpde2=tmpde->next;
+    if (tmpde->sub)
+      DirTreeDel2(tmpde->sub);
+    DirEntryDel2(tmpde);
+    tmpde=tmpde2;
+  }
+}
+
+I64 DirEntryCompareName(CDirEntry *e1,CDirEntry *e2)
+{
+  U8 buf1[CDIR_FILENAME_LEN],buf2[CDIR_FILENAME_LEN],
+        buf3[CDIR_FILENAME_LEN],buf4[CDIR_FILENAME_LEN];
+  I64 d1=0,d2=0;
+  if (e1->attr & RS_ATTR_DIR)
+    d1=1;
+  if (e2->attr & RS_ATTR_DIR)
+    d2=1;
+  if (d1!=d2)
+    return d2-d1;
+  else {
+    StrCpy(buf1,e1->name);
+    StrCpy(buf2,e2->name);
+    FileExtRem(buf1,buf3);
+    FileExtRem(buf2,buf4);
+    if (d1=StrCmp(buf3,buf4))
+      return d1;
+    return StrCmp(buf1,buf2);
+  }
+}
+
+I64 DirEntryCompareClus(CDirEntry *e1,CDirEntry *e2)
+{
+  return e1->clus-e2->clus;
+}
+
+#define SK_NAME         0
+#define SK_CLUS 1
+
+U0 DirFilesSort(CDirEntry **_tmpde,I64 key)
+{
+  I64 i,cnt;
+  CDirEntry *tmpde=*_tmpde,*tmpde1,**sort_buf;
+  if (tmpde) {
+    cnt=LinkedLstCnt(tmpde);
+    if (cnt>1) {
+      sort_buf=MAlloc(cnt*sizeof(U8 *));
+      i=0;
+      tmpde1=tmpde;
+      while (tmpde1) {
+        sort_buf[i++]=tmpde1;
+        tmpde1=tmpde1->next;
+      }
+      switch [key] {
+        case SK_NAME:
+          QSortI64(sort_buf,cnt,&DirEntryCompareName);
+          break;
+        case SK_CLUS:
+          QSortI64(sort_buf,cnt,&DirEntryCompareClus);
+          break;
+      }
+      tmpde=sort_buf[0];
+      *_tmpde=tmpde;
+      for (i=0;i<cnt-1;i++) {
+        tmpde1=sort_buf[i];
+        tmpde1->next=sort_buf[i+1];
+      }
+      tmpde1=sort_buf[i];
+      tmpde1->next=NULL;
+      Free(sort_buf);
+
+      tmpde1=tmpde;
+      while (tmpde1) {
+        if (tmpde1->sub)
+          DirFilesSort(&tmpde1->sub,key);
+        tmpde1=tmpde1->next;
+      }
+    } else
+      if (tmpde->sub)
+        DirFilesSort(&tmpde->sub,key);
+  }
+}
+
+CDirEntry *DirFilesFlatten(CDirEntry *tmpde,CDirEntry **_res,I64 fuf_flags)
+{//Returns last node
+  CDirEntry *tmpde1;
+  Bool del;
+  if (tmpde)
+    while (TRUE) {
+      tmpde1=tmpde->next;
+      if (!(tmpde->attr&RS_ATTR_DIR)||!(fuf_flags&FUF_JUST_FILES)) {
+        _res=*_res=tmpde;
+        del=FALSE;
+      } else
+        del=TRUE;
+      if (tmpde->sub) {
+        _res=DirFilesFlatten(tmpde->sub,_res,fuf_flags);
+        tmpde->sub=NULL;
+      }
+      if (del)
+        DirEntryDel(tmpde);
+      if (tmpde1)
+        tmpde=tmpde1;
+      else
+        break;
+    }
+  *_res=NULL;
+  return _res;
+}
+
+U0 PutFileLink(U8 *filename,U8 *full_name=NULL,I64 line=0,Bool plain_text=FALSE)
+{//Put DolDoc file,line link to StdOut, DocPut.
+  U8 *st;
+  if (!filename) return;
+  if (IsRaw) {
+    if (line)
+      "%s,%04d",filename,line;
+    else
+      "%s",filename;
+  } else {
+//LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE
+    if (filename[0]=='A'&&filename[2]==':') {
+      if (line) //See SpriteEdText()
+        "$LK,\"%s,%04d\",A=\"AL:%s,%d\"$",filename+3,line,filename+3,line;
+      else
+        "$LK,\"%s\",A=\"AI:%s\"$",filename+3,filename+3;
+    } else {
+      if (!full_name)
+        full_name=st=FileNameAbs(filename);
+      else
+        st=NULL;
+      if (plain_text) {
+        if (line)
+          "$LK,\"%s,%04d\",A=\"PL:%s,%d\"$",filename,line,full_name,line;
+        else
+          "$LK,\"%s\",A=\"PI:%s\"$",filename,full_name;
+      } else {
+        if (line)
+          "$LK,\"%s,%04d\",A=\"FL:%s,%d\"$",filename,line,full_name,line;
+        else
+          "$LK,\"%s\",A=\"FI:%s\"$",filename,full_name;
+      }
+      Free(st);
+    }
+  }
+}
+
+U0 PutDirLink(U8 *dirname,U8 *full_name=NULL)
+{//Put DolDoc dir macro to StdOut, DocPut.
+  U8 *st;
+  if (!dirname) return;
+  if (IsRaw)
+    "%s",dirname;
+  else {
+    if (!full_name)
+      full_name=st=DirNameAbs(dirname);
+    else
+      st=NULL;
+    "$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$",dirname,full_name;
+    Free(st);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskDirB.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskDirB.HC.HTML new file mode 100755 index 0000000..3765bee --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskDirB.HC.HTML @@ -0,0 +1,225 @@ + + + + + + + + + + + +
+U0 HomeSet(U8 *dirname)
+{//Change home directory.
+  dirname=DirNameAbs(dirname);
+  Free(blkdev.home_dir);
+  blkdev.home_dir=AStrNew(dirname);
+  Free(dirname);
+}
+
+Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE)
+{//Change directory. Optionally, make directories, too.
+  I64 maxlen,cur_dir_clus=0;
+  U8 *chg_to_buf,*new_cur_dir,*buf;
+  CDrv *dv;
+  Bool res=TRUE;
+  if (!dirname)
+    dirname="~";
+  else if (!*dirname)
+    return TRUE;
+  if (dirname[1]==':') {
+    if (*dirname==':') {
+      if (Fs->cur_dv!=Let2Drv(':') && !Drv(*dirname))
+        return FALSE;
+    } else if (Fs->cur_dv!=Let2Drv(*dirname) && !Drv(*dirname))
+      return FALSE;
+    dirname+=2;
+  }
+  if (*dirname=='/' || !*dirname || !Fs->cur_dir) {
+    Free(Fs->cur_dir);
+    Fs->cur_dir=StrNew("/");
+    if (*dirname=='/')
+      dirname++;
+  }
+  chg_to_buf=MStrUtil(dirname,
+        SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  maxlen=StrLen(Fs->cur_dir)+1+StrLen(chg_to_buf)+1;
+  new_cur_dir=MAlloc(maxlen);
+  buf=MAlloc(maxlen);
+  StrCpy(new_cur_dir,Fs->cur_dir);
+  while (*chg_to_buf && res) {
+    StrFirstRem(chg_to_buf,"/",buf);
+    if (!*buf)
+      StrCpy(new_cur_dir,"/");
+    else if (!StrCmp(buf,"..")) {
+      StrLastRem(new_cur_dir,"/");
+      if (!*new_cur_dir)
+        StrCpy(new_cur_dir,"/");
+    } else if (!StrCmp(buf,"~")) {
+      Free(new_cur_dir);
+      new_cur_dir=MAlloc(StrLen(blkdev.home_dir+2)+1+StrLen(chg_to_buf)+1);
+      StrCpy(new_cur_dir,blkdev.home_dir+2);
+      if (Fs->cur_dv!=Let2Drv('~') && !Drv('~'))
+        return FALSE;
+    } else if (StrCmp(buf,".") && *buf) {
+      dv=Fs->cur_dv;
+      cur_dir_clus=Name2DirClus(dv,new_cur_dir);
+      switch (dv->fs_type) {
+        case FSt_REDSEA:
+          res=RedSeaCd(buf,cur_dir_clus);
+          break;
+        case FSt_FAT32:
+          res=FAT32Cd(buf,cur_dir_clus);
+          break;
+        default:
+          PrintErr("File System Not Supported\n");
+          res=FALSE;
+      }
+      if (!res && make_dirs) {
+        Free(Fs->cur_dir);
+        Fs->cur_dir=StrNew(new_cur_dir);
+        res=DirMk(buf);
+      }
+      if (res) {
+        if (StrCmp(new_cur_dir,"/"))
+          CatPrint(new_cur_dir,"/");
+        CatPrint(new_cur_dir,buf);
+      }
+    }
+  }
+  Free(Fs->cur_dir);
+  Fs->cur_dir=StrNew(new_cur_dir);
+  Free(buf);
+  Free(chg_to_buf);
+  Free(new_cur_dir);
+  return res;
+}
+
+Bool IsDir(U8 *dir_name)
+{//Is a str a valid, existing Dir?
+  U8 *mask=MStrPrint("%s/*",dir_name);
+  Bool res,old_silent=Silent;
+  CDirContext *dirc;
+  if (dirc=DirContextNew(mask)) {
+    DirContextDel(dirc);
+    res=TRUE;
+  } else
+    res=FALSE;
+  Free(mask);
+  Silent(old_silent);
+  return res;
+}
+
+I64 Dir(U8 *files_find_mask,Bool full)
+{//List directory.
+  CDirEntry *tmpde1=NULL,*tmpde2;
+  U8 *st;
+  CDateStruct ds;
+  I64 csize=0xFFFF,c=0xFFFF,res=0;
+  tmpde1=FilesFind(files_find_mask);
+  if (!(st=DirCur))
+    PrintErr("Invalid Drive\n");
+  else {
+    if (tmpde1) {
+      Free(st);
+      st=MAllocIdent(tmpde1->full_name);
+      StrLastRem(st,"/");
+      if (!st[2])
+        StrCpy(st+2,"/");
+//Find max columns
+      tmpde2=tmpde1;
+      while (tmpde2) {
+        if (tmpde2->size>csize)
+          csize=tmpde2->size;
+        if (tmpde2->clus>c)
+          c=tmpde2->clus;
+        tmpde2=tmpde2->next;
+      }
+      csize=Bsr(csize)/4+1;
+      c=Bsr(c)/4+1;
+
+      "$MA,T=\"Directory\",LM=\"PopUpCd;Dir;\n\"$ of %s\n",st;
+      if (full)
+        "__DATE__ __TIME__ %*ts %*ts\n",
+              csize,"SIZE",c,"BLK";
+      else
+        "DATE_ TIME_ %*ts\n",csize,"SIZE";
+      while (tmpde1) {
+        tmpde2=tmpde1->next;
+        res++;
+        if (full)
+          "%D %T %0*tX %0*tX ",tmpde1->datetime,tmpde1->datetime,
+                csize,tmpde1->size,c,tmpde1->clus;
+        else {
+          Date2Struct(&ds,tmpde1->datetime+local_time_offset);
+          "%02d/%02d %02d:%02d %0*tX ",ds.mon,ds.day_of_mon,ds.hour,ds.min,
+                csize,tmpde1->size;
+        }
+        if (tmpde1->attr & RS_ATTR_DIR)
+          PutDirLink(tmpde1->name,tmpde1->full_name);
+        else
+          PutFileLink(tmpde1->name,tmpde1->full_name);
+        '\n';
+        DirEntryDel(tmpde1);
+        tmpde1=tmpde2;
+      }
+    } else
+      "No matching entries\n";
+    Free(st);
+  }
+  return res;
+}
+
+Bool DirMk(U8 *filename,I64 entry_cnt=0)
+{//Make directory. Cd() can also make directories.
+//entry_cnt is for preallocating dir blks, leave it zero if you like.
+  U8 *name;
+  CDirContext *dirc;
+  Bool res=FALSE;
+  if (FileFind(filename,,FUF_JUST_DIRS))
+    return FALSE;
+  if (dirc=DirContextNew(filename)) {
+    if (*dirc->mask) {
+      if (!FileNameChk(dirc->mask))
+        PrintErr("Invalid FileName: \"%s\".\n",dirc->mask);
+      else {
+        "Make Directory:%s\n",filename;
+        name=MStrUtil(dirc->mask,
+              SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+        switch (dirc->dv->fs_type) {
+          case FSt_REDSEA:
+            res=RedSeaMkDir(dirc->dv,Fs->cur_dir,name,entry_cnt);
+            break;
+          case FSt_FAT32:
+            res=FAT32MkDir(dirc->dv,Fs->cur_dir,name,entry_cnt);
+            break;
+          default:
+            PrintErr("File System Not Supported\n");
+        }
+        Free(name);
+      }
+    }
+    DirContextDel(dirc);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskDirContext.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskDirContext.HC.HTML new file mode 100755 index 0000000..69860e1 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskDirContext.HC.HTML @@ -0,0 +1,118 @@ + + + + + + + + + + + +
+U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE)
+{//Change back to old cur_dir and drv.
+  CBlkDev *bd;
+  if (!dirc) return;
+  if (restore) {
+    bd=dirc->old_dv->bd;
+    if (!(bd->flags & BDF_INIT_IN_PROGRESS)) {
+      if (dirc->old_dir) {
+        Drv(Drv2Let(dirc->old_dv));
+        Cd(dirc->old_dir);
+      }
+    } else {
+      Fs->cur_dv=dirc->old_dv;
+      Free(Fs->cur_dir);
+      Fs->cur_dir=StrNew("/");
+    }
+  }
+  Free(dirc->old_dir);
+  Free(dirc->mask);
+  Free(dirc);
+}
+
+CDirContext *DirContextNew(U8 *_mask,Bool make_mask=FALSE,
+        Bool make_dirs=FALSE,Bool no_mask=FALSE)
+{//Save cur_dir and drv. Change to new dir.
+  Bool valid=TRUE,old_silent;
+  I64 mask_len=StrLen(_mask);
+  U8 *buf,*mask,*tmp_mask,*semicolon_mask;
+  CDirContext *dirc=CAlloc(sizeof(CDirContext));
+  dirc->old_dir=StrNew(Fs->cur_dir);
+  dirc->old_dv=Fs->cur_dv;
+  mask=MStrUtil(_mask,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  tmp_mask=mask;
+  if (*mask && mask[1]==':') {
+    if (Fs->cur_dv!=Let2Drv(*mask) && !Drv(*mask))
+      valid=FALSE;
+    mask+=2;
+  }
+  if (*mask=='~' && Fs->cur_dv!=Let2Drv('~') && !Drv('~'))
+    valid=FALSE;
+  dirc->dv=Fs->cur_dv;
+  DrvChk(dirc->dv);
+  buf=MAlloc(mask_len+2);
+  StrCpy(buf,mask);
+
+  dirc->mask=MAlloc(mask_len+2);
+  if (no_mask)
+    *dirc->mask=0;
+  else if (StrOcc(buf,';')) {
+    semicolon_mask=MAlloc(mask_len+2);
+    StrCpy(semicolon_mask,mask);
+    StrFirstRem(semicolon_mask,";",buf);
+    StrLastRem(buf,"/",dirc->mask);
+    CatPrint(dirc->mask,";%s",semicolon_mask);
+    Free(semicolon_mask);
+  } else
+    StrLastRem(buf,"/",dirc->mask);
+
+  if (*mask=='/' && !*buf)
+    StrCpy(buf,"/");
+//If began with Dir, change to Dir.
+  if (*buf && !Cd(buf,make_dirs))
+    valid=FALSE;
+  if (valid && make_mask) {
+    if (!*dirc->mask) {
+      Free(dirc->mask);
+      dirc->mask=StrNew("*");
+    } else {
+      if (!make_dirs || FileNameChk(dirc->mask)) {
+        old_silent=Silent;
+//Try mask to see if Dir. If Dir, change to dir and set to "*".
+        if (Cd(dirc->mask,make_dirs)) {
+          Free(dirc->mask);
+          dirc->mask=StrNew("*");
+        }
+        Silent(old_silent);
+      }
+    }
+  }
+  Free(buf);
+  Free(tmp_mask);
+  if (!valid) {
+    DirContextDel(dirc);
+    dirc=NULL;
+  }
+  return dirc;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskDrv.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskDrv.HC.HTML new file mode 100755 index 0000000..e365099 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskDrv.HC.HTML @@ -0,0 +1,397 @@ + + + + + + + + + + + +
+Bool DrvLock(CDrv *dv)
+{//Make this task have exclusive access to drv & BlkDev.
+  DrvChk(dv);
+  BlkDevLock(dv->bd);
+  if (!Bt(&dv->locked_flags,DVlf_LOCKED) || dv->owning_task!=Fs) {
+    while (LBts(&dv->locked_flags,DVlf_LOCKED))
+      Yield;
+    dv->owning_task=Fs;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool DrvUnlock(CDrv *dv,Bool rst=FALSE)
+{//Release exclusive lock on access to drv & BlkDev.
+  DrvChk(dv);
+  if (Bt(&dv->locked_flags,DVlf_LOCKED) && dv->owning_task==Fs) {
+    BlkDevUnlock(dv->bd,rst);
+    dv->owning_task=NULL;
+    LBtr(&dv->locked_flags,DVlf_LOCKED);
+    Yield; //Prevent deadlock
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 DrvsRelease()
+{//When task dies, release all owned drvs.
+  I64 i;
+  CDrv *dv;
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (dv->owning_task==Fs && dv->dv_signature==DRV_SIGNATURE_VAL)
+      DrvUnlock(dv,TRUE);
+  }
+}
+
+CDrv *DrvMakeFreeSlot(U8 drv_let)
+{//Make a slot free for a new drv, like during Mount().
+//!!! drv_let is not a remapped drv.
+  I64 i=Let2Let(drv_let)-'A';
+  CDrv *res;
+  if (!(0<=i<DRVS_NUM))
+    throw('Drv');
+  res=&blkdev.drvs[i];
+  MemSet(res,0,sizeof(CDrv));
+  res->drv_let='A'+i;
+  return res;
+}
+
+U8 DrvNextFreeLet(U8 first_drv_let='C')
+{//Locate free slot for new drv, like during Mount().
+//!!! first_drv_let is not a remapped drv.
+  I64 i=Let2Let(first_drv_let)-'A',type=Let2BlkDevType(first_drv_let);
+  if (!(0<=i<DRVS_NUM))
+    throw('Drv');
+  do
+    if (blkdev.drvs[i].dv_signature!=DRV_SIGNATURE_VAL) {
+      if (Let2BlkDevType(i+'A')!=type)
+        throw('Drv');
+      else
+        return i+'A';
+    }
+  while (++i<DRVS_NUM);
+  throw('Drv');
+  return 0; //Never gets here.
+}
+
+U0 DrvDel(CDrv *dv)
+{//Delete drv
+  if (dv->fs_type==FSt_REDSEA && dv->next_free)
+    RedSeaFreeFreeLst(dv);
+  Free(dv->cur_fat_blk);
+  Free(dv->fis);
+  MemSet(dv,0,sizeof(CDrv));
+}
+
+U0 DrvBlkDevDel(CBlkDev *bd)
+{//Delete drv's of BlkDev
+  I64 i;
+  CDrv *dv;
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (dv->bd==bd)
+      DrvDel(dv);
+  }
+}
+
+U0 DrvFATBlkAlloc(CDrv *dv)
+{
+  DrvChk(dv);
+  Free(dv->cur_fat_blk);
+  dv->cur_fat_blk=AMAlloc(BLK_SIZE);
+  dv->cur_fat_blk_num=0;
+  dv->fat_blk_dirty=0;
+  BlkRead(dv,dv->cur_fat_blk,dv->fat1,1);
+}
+
+U0 DrvFATBlkClean(CDrv *dv,I64 fat_sel=3)
+{
+  if ((dv->fs_type==FSt_FAT32 || dv->fs_type==FSt_REDSEA) &&
+       Bt(&dv->fat_blk_dirty,0)) {
+    if (dv->fat1==dv->fat2) {
+      BlkWrite(dv,dv->cur_fat_blk,dv->fat1+dv->cur_fat_blk_num,1);
+      LBtr(&dv->fat_blk_dirty,0);
+    } else {
+      if (fat_sel==3 || !fat_sel)
+        BlkWrite(dv,dv->cur_fat_blk,dv->fat1+dv->cur_fat_blk_num,1);
+      if (fat_sel==3 || fat_sel==1) {
+        BlkWrite(dv,dv->cur_fat_blk,dv->fat2+dv->cur_fat_blk_num,1);
+        LBtr(&dv->fat_blk_dirty,0);
+      }
+    }
+  }
+}
+
+U0 DrvFATBlkSet(CDrv *dv,I64 c,I64 fat_sel=3)
+{
+  I64 fat_blk_num;
+  if (c==INVALID_CLUS)
+    throw('Drv');
+  switch (dv->fs_type) {
+    case FSt_FAT32:
+      fat_blk_num=c>>(BLK_SIZE_BITS-2);
+      break;
+    case FSt_REDSEA:
+      fat_blk_num=(c-dv->data_area)>>(BLK_SIZE_BITS+3);
+      break;
+    default:
+      throw('Drv');
+  }
+  if (fat_blk_num!=dv->cur_fat_blk_num) {
+    DrvFATBlkClean(dv,fat_sel);
+    dv->cur_fat_blk_num=fat_blk_num;
+    if (fat_sel==3 || !fat_sel)
+      BlkRead(dv,dv->cur_fat_blk,dv->fat1+dv->cur_fat_blk_num,1);
+    else
+      BlkRead(dv,dv->cur_fat_blk,dv->fat2+dv->cur_fat_blk_num,1);
+  }
+}
+
+CDrv *DrvChk(CDrv *dv,Bool except=TRUE)
+{//Check for valid drv. Throw exception.
+  if (!dv || dv->dv_signature!=DRV_SIGNATURE_VAL) {
+    if (except)
+      throw('Drv');
+    else
+      return NULL;
+  } else
+    return dv;
+}
+
+U8 Drv2Let(CDrv *dv=NULL)
+{//Drv ptr to Drv letter.
+  if (!dv)
+    dv=Fs->cur_dv;
+  DrvChk(dv);
+  return dv->drv_let;
+}
+
+U8 Let2Let(U8 drv_let=0)
+{//Drv letter to Drv letter.
+  if (!drv_let)
+    drv_let=Drv2Let(Fs->cur_dv);
+  else if (drv_let==':')
+    drv_let=blkdev.boot_drv_let;
+  else if (drv_let=='~')
+    drv_let=*blkdev.home_dir;
+  return ToUpper(drv_let);
+}
+
+I64 Let2BlkDevType(U8 drv_let)
+{//Drv letter to BlkDev Type. drv_let=0 not allowed. See BDT_NULL.
+  drv_let=Let2Let(drv_let);
+  if ('A'<=drv_let<='B')
+    return BDT_RAM;
+  if ('C'<=drv_let<='L')
+    return BDT_ATA;
+  if ('M'<=drv_let<='P')
+    return BDT_ISO_FILE_READ;
+  if ('Q'<=drv_let<='S')
+    return BDT_ISO_FILE_WRITE;
+  if ('T'<=drv_let<='Z')
+    return BDT_ATAPI;
+  return BDT_NULL;
+}
+
+CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE)
+{//Drv letter to Drv ptr.
+  CDrv *dv;
+  if (!drv_let)
+    dv=Fs->cur_dv;
+  else {
+    drv_let=Let2Let(drv_let);
+    if (!('A'<=drv_let<='Z')) {
+      if (except)
+        throw('Drv');
+      else
+        return NULL;
+    }
+    dv=blkdev.let_to_drv[drv_let-'A'];
+  }
+  return DrvChk(dv,except);
+}
+
+CBlkDev *DrvIsWritable(U8 drv_let=0,Bool except=FALSE)
+{//Is drive writable?
+  CBlkDev *bd;
+  if (!(bd=Let2BlkDev(drv_let,except)) || bd->flags & BDF_READ_ONLY) {
+    if (except)
+      throw('Drv');
+    else
+      return NULL;
+  } else
+    return bd;
+}
+
+U0 DskCacheInvalidate(CDrv *dv)
+{//Needed for removable media. Called by DskChg().
+  Bool unlock;
+  CBlkDev *bd=dv->bd;
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    BlkDevInit(bd);
+    if (bd->flags & BDF_READ_CACHE)
+      DskCacheInvalidate2(dv);
+    if (bd->type==BDT_ATAPI && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
+      ISOInit(dv,(32767/bd->blk_size+1)*bd->blk_size>>BLK_SIZE_BITS);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 DskChg(U8 drv_let=0)
+{//Change disk. (Needed for removable media.)
+  CDrv *dv=Let2Drv(drv_let);
+  CBlkDev *bd=dv->bd;
+  if (!(bd->flags&BDF_INITIALIZED))
+    BlkDevInit(bd);
+  else if (bd->flags&BDF_REMOVABLE) {
+    if (bd->type==BDT_ATAPI)
+      ATAInit(bd); //TODO: This is a kludge for QEMU?
+    DskCacheInvalidate(dv);
+  }
+  Drv(drv_let);
+  RedSeaFreeFreeLst(dv);
+}
+
+Bool DrvMap(U8 drv_let,CDrv *dv)
+{//Make drive letter map to another.
+  drv_let=Let2Let(drv_let);
+  if ('A'<=drv_let<='Z') {
+    blkdev.let_to_drv[drv_let-'A']=dv;
+    dv->drv_let=drv_let;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool Drv(U8 drv_let)
+{//Change drive.  You can set drive with Cd() as well.
+  CDrv *dv=Let2Drv(drv_let);
+  CBlkDev *bd;
+  bd=BlkDevChk(dv->bd);
+  if (dv!=Fs->cur_dv) {
+    if (bd->flags & BDF_REMOVABLE && !(bd->flags & BDF_INITIALIZED))
+      DskChg(Drv2Let(dv));
+    if (bd->type==BDT_RAM ||
+        bd->type==BDT_ISO_FILE_READ || bd->type==BDT_ISO_FILE_WRITE)
+      BlkDevInit(bd);
+  }
+  Fs->cur_dv=dv;
+  Free(Fs->cur_dir);
+  Fs->cur_dir=StrNew("/");
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+    case FSt_FAT32:
+      return TRUE;
+    default:
+      PrintErr("File System Not Supported\n");
+      return FALSE;
+  }
+}
+
+U8 *DrvSerialNum(U8 drv_let=0)
+{//20 bytes max.
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  U16 *st,*res=NULL;
+  I64 i;
+  if (bd->dev_id_record) {
+    st=CAlloc(20+1);
+    for (i=0;i<10;i++)
+      st[i]=EndianU16(bd->dev_id_record[10+i]);
+    res=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
+    Free(st);
+  }
+  return res;
+}
+
+U8 *DrvModelNum(U8 drv_let=0)
+{//40 bytes max.
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  U16 *st,*res=NULL;
+  I64 i;
+  if (bd->dev_id_record) {
+    st=CAlloc(40+1);
+    for (i=0;i<20;i++)
+      st[i]=EndianU16(bd->dev_id_record[27+i]);
+    res=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
+    Free(st);
+  }
+  return res;
+}
+
+U8 blkdev_text_attr[BDT_TYPES_NUM]={BLACK,LTCYAN,WHITE,LTGREEN,LTRED,LTBLUE};
+U8 drv_text_attr[3]={BLACK,BLUE,RED};
+
+U8 DrvTextAttrGet(U8 drv_let=0)
+{//Get color of drive.
+  drv_let=Let2Let(drv_let);
+  if ('A'<=drv_let<='Z')
+    return blkdev_text_attr[Let2BlkDevType(drv_let)]<<4|
+          drv_text_attr[drv_let%sizeof(drv_text_attr)];
+  else
+    return BLACK<<4|WHITE;
+}
+
+U0 DrvRep()
+{//Drive report.
+  CDrv *dv;
+  CBlkDev *bd;
+  I64 ch,i,drv_let,attr;
+  U8 *st;
+  "\nDefined Drives:\n";
+  for (i=0,dv=blkdev.drvs;i<DRVS_NUM;i++,dv++) {
+    if (dv->dv_signature==DRV_SIGNATURE_VAL) {
+      bd=dv->bd;
+      drv_let=Drv2Let(dv);
+      if (Bt(&dv->fs_type,FStf_DISABLE))
+        ch='-';
+      else if (drv_let==blkdev.boot_drv_let)
+        ch=':';
+      else
+        ch='+';
+      attr=DrvTextAttrGet(drv_let);
+      "$FG,%d$$BG,%d$%C %-8Z %-10Z %04X %04X %02X\n",
+            attr&15,attr>>4,drv_let,dv->fs_type&FSG_TYPE_MASK,"ST_DRV_TYPES",
+            bd->type,"ST_BLKDEV_TYPES",bd->base0,bd->base1,bd->unit;
+      if (st=DrvModelNum(drv_let)) {
+        "   Model# :%s\n",st;
+        Free(st);
+      }
+      if (st=DrvSerialNum(drv_let)) {
+        "   Serial#:%s\n",st;
+        Free(st);
+      }
+      if (bd->type==BDT_ISO_FILE_READ || bd->type==BDT_ISO_FILE_WRITE)
+        "   File=\"%s\"\n",bd->file_dsk_name;
+      "   %016X-%016X\n$FG$$BG$",dv->drv_offset,dv->drv_offset+dv->size-1;
+    }
+  }
+  "Home Dir:\"%s\"\n",blkdev.home_dir;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskFile.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskFile.HC.HTML new file mode 100755 index 0000000..3965bbb --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskFile.HC.HTML @@ -0,0 +1,149 @@ + + + + + + + + + + + +
+U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL)
+{//Read whole file from disk.
+  CHashGeneric *tmph;
+  U8 *absname,*altname,*curname,*res=NULL;
+  I64 i,size=0,attr=0;
+  CDirContext *dirc;
+  CArcCompress *arc;
+  absname=FileNameAbs(filename);
+  altname=ToggleZorNotZ(absname);
+  if ((tmph=HashFind(absname,adam_task->hash_table,HTT_FILE))||
+        (tmph=HashFind(altname,adam_task->hash_table,HTT_FILE))) {
+    size=tmph->user_data1;
+    res=MAlloc(size+1);
+    MemCpy(res,tmph->user_data0,size);
+    res[size]=0; //Terminate
+    attr=FileAttr(tmph->str,attr);
+  } else {
+    for (i=0;i<2 && !res;i++) {//Try name, then altname
+      if (!i)
+        curname=absname;
+      else
+        curname=altname;
+      if (dirc=DirContextNew(curname)) {
+        switch (dirc->dv->fs_type) {
+          case FSt_REDSEA:
+            res=RedSeaFileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+            break;
+          case FSt_FAT32:
+            res=FAT32FileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+            break;
+          default:
+            PrintErr("File System Not Supported\n");
+        }
+        DirContextDel(dirc);
+      }
+    }
+
+    //Search parent directories.
+    for (i=0;i<2 && !res;i++) {//Try name, then altname
+      if (!i)
+        curname=absname;
+      else
+        curname=altname;
+      if (dirc=DirContextNew(curname)) {
+        while (!res && StrCmp(Fs->cur_dir,"/")) {
+          Cd("..");
+          switch (Fs->cur_dv->fs_type) {
+            case FSt_REDSEA:
+              res=RedSeaFileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+              break;
+            case FSt_FAT32:
+              res=FAT32FileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+              break;
+            default:
+              PrintErr("File System Not Supported\n");
+          }
+        }
+        DirContextDel(dirc);
+      }
+    }
+    if (!res)
+      PrintErr("File not found: \"%s\".\n",filename);
+    if (res && attr & RS_ATTR_RESIDENT)
+      HashGenericAdd(curname,HTT_FILE,AMAllocIdent(res),size,0,adam_task);
+  }
+  if (res && attr & RS_ATTR_COMPRESSED) {
+    arc=res;
+    size=arc->expanded_size;
+    res=ExpandBuf(arc);
+    Free(arc);
+  }
+  if (_attr) *_attr=attr;
+  if (_size) *_size=size;
+  Free(absname);
+  Free(altname);
+  return res;
+}
+
+I64 FileWrite(U8 *filename,U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0)
+{//Write whole file to disk.
+  I64 c=0;
+  CHashGeneric *tmph;
+  CDirContext *dirc;
+  U8 *fbuf2,*absname=FileNameAbs(filename);
+  if (dirc=DirContextNew(filename,FALSE,TRUE)) {
+    attr=FileAttr(dirc->mask,attr);
+    if (attr&RS_ATTR_COMPRESSED) {
+      fbuf=CompressBuf(fbuf,size);
+      size=fbuf(CArcCompress *)->compressed_size;
+      fbuf2=fbuf;
+    } else
+      fbuf2=NULL;
+    if (!cdt) cdt=Now;
+    switch (dirc->dv->fs_type) {
+      case FSt_REDSEA:
+        c=RedSeaFileWrite(dirc->dv,Fs->cur_dir,dirc->mask,fbuf,size,cdt,attr);
+        break;
+      case FSt_FAT32:
+        c=FAT32FileWrite(dirc->dv,Fs->cur_dir,dirc->mask,fbuf,size,cdt,attr);
+        break;
+      default:
+        PrintErr("File System Not Supported\n");
+    }
+    if (tmph=HashFind(absname,adam_task->hash_table,HTT_FILE)) {
+      if (attr & RS_ATTR_RESIDENT) {
+        Free(tmph->user_data0);
+        tmph->user_data0=AMAllocIdent(fbuf);
+        tmph->user_data1=size;
+      } else
+        HashRemDel(tmph,adam_task->hash_table);
+    } else if (attr & RS_ATTR_RESIDENT)
+      HashGenericAdd(absname,HTT_FILE,AMAllocIdent(fbuf),size,0,adam_task);
+    Free(fbuf2);
+    DirContextDel(dirc);
+  }
+  Free(absname);
+  return c;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskFind.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskFind.HC.HTML new file mode 100755 index 0000000..540849f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskFind.HC.HTML @@ -0,0 +1,182 @@ + + + + + + + + + + + +
+CDirEntry *FilesFind2(U8 *files_find_mask,I64 fuf_flags)
+{
+  CDrv *dv=Fs->cur_dv;
+  CDirEntry *res=NULL;
+  DrvChk(dv);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      res=RedSeaFilesFind(files_find_mask,fuf_flags);
+      break;
+    case FSt_FAT32:
+      res=FAT32FilesFind(files_find_mask,fuf_flags);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+      res=NULL;
+  }
+  if (res) {
+    DirFilesSort(&res,SK_NAME);
+    if (fuf_flags&(FUF_FLATTEN_TREE|FUF_JUST_FILES))
+      DirFilesFlatten(res,&res,fuf_flags);
+    if (fuf_flags&FUF_CLUS_ORDER)
+      DirFilesSort(&res,SK_CLUS);
+  }
+  return res;
+}
+
+CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0)
+{/* See ::/Doc/FileUtils.DD.
+
+Find files and make a directory tree in memory.
+
+When done, you free with DirEntryDel(),DirEntryDel2(),
+DirTreeDel() or DirTreeDel2().
+
+*/
+  CDirEntry *res;
+  CDirContext *dirc;
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+  if (fuf_flags&FUF_SINGLE) {
+    res=MAlloc(sizeof(CDirEntry));
+    if (!FileFind(files_find_mask,res)) {
+      Free(res);
+      return NULL;
+    }
+  } else if (dirc=DirContextNew(files_find_mask,TRUE)) {
+    res=FilesFind2(dirc->mask,fuf_flags);
+    DirContextDel(dirc);
+  } else
+    return NULL;
+  return res;
+}
+
+Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0)
+{//FUF_JUST_DIRS, FUF_JUST_FILES, FUF_Z_OR_NOT_Z, FUF_SCAN_PARENTS
+//If you pass _de, you must Free(_de->full_name);
+  I64 i,j,cur_dir_clus;
+  U8 *altname,*curname,*full_name=NULL;
+  CDirEntry de;
+  CDirContext *dirc;
+  Bool res=FALSE,old_silent;
+  if (fuf_flags&~FUG_FILE_FIND)
+    throw('FUF');
+  if (!filename || *filename && filename[1]==':' && !Let2Drv(*filename,FALSE))
+    return FALSE;
+  altname=ToggleZorNotZ(filename);
+  if (fuf_flags&FUF_Z_OR_NOT_Z)
+    j=2;
+  else
+    j=1;
+  for (i=0;i<j && !res;i++) {
+    if (!i)
+      curname=filename;
+    else
+      curname=altname;
+    old_silent=Silent;
+    if (!(dirc=DirContextNew(curname)))
+      Silent(old_silent);
+    else {
+      Silent(old_silent);
+      cur_dir_clus=Name2DirClus(dirc->dv,Fs->cur_dir);
+      switch (dirc->dv->fs_type) {
+        case FSt_REDSEA:
+          res=RedSeaFileFind(dirc->dv,cur_dir_clus,dirc->mask,
+                &de,fuf_flags);
+          break;
+        case FSt_FAT32:
+          res=FAT32FileFind(dirc->dv,cur_dir_clus,dirc->mask,
+                &de,fuf_flags);
+          break;
+        default:
+          PrintErr("File System Not Supported\n");
+      }
+      if (res && _de) {
+        if (StrCmp(Fs->cur_dir,"/"))
+          full_name=MStrPrint("%C:%s/%s",
+                Drv2Let(Fs->cur_dv),Fs->cur_dir,de.name);
+        else
+          full_name=MStrPrint("%C:/%s",Drv2Let(Fs->cur_dv),de.name);
+      }
+      DirContextDel(dirc);
+    }
+  }
+  for (i=0;i<j && !res && fuf_flags&FUF_SCAN_PARENTS;i++) {
+    if (!i)
+      curname=filename;
+    else
+      curname=altname;
+    old_silent=Silent;
+    if (!(dirc=DirContextNew(curname)))
+      Silent(old_silent);
+    else {
+      Silent(old_silent);
+      cur_dir_clus=Name2DirClus(dirc->dv,Fs->cur_dir);
+      while (!res && StrCmp(Fs->cur_dir,"/")) {
+        Cd("..");
+        cur_dir_clus=Name2DirClus(dirc->dv,Fs->cur_dir);
+        switch (dirc->dv->fs_type) {
+          case FSt_REDSEA:
+            res=RedSeaFileFind(dirc->dv,cur_dir_clus,
+                  dirc->mask,&de,fuf_flags);
+            break;
+          case FSt_FAT32:
+            res=FAT32FileFind(dirc->dv,cur_dir_clus,
+                  dirc->mask,&de,fuf_flags);
+            break;
+          default:
+            PrintErr("File System Not Supported\n");
+        }
+      }
+      if (res && _de) {
+        if (StrCmp(Fs->cur_dir,"/"))
+          full_name=MStrPrint("%C:%s/%s",
+                Drv2Let(Fs->cur_dv),Fs->cur_dir,de.name);
+        else
+          full_name=MStrPrint("%C:/%s",
+                Drv2Let(Fs->cur_dv),de.name);
+      }
+      DirContextDel(dirc);
+    }
+  }
+  if (_de) {
+    if (res) {
+      MemCpy(_de,&de,sizeof(CDirEntry));
+      _de->full_name=full_name;
+    } else
+      MemSet(_de,0,sizeof(CDirEntry));
+  }
+  Free(altname);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskFmt.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskFmt.HC.HTML new file mode 100755 index 0000000..309b474 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskFmt.HC.HTML @@ -0,0 +1,123 @@ + + + + + + + + + + + +
+Bool DrvTypeSet(U8 drv_let,I64 type=FSt_REDSEA)
+{//Very dangerous
+  I64 i,j,ext_base,drv_num,offset,cur_type;
+  CMasterBoot mbr;
+  CBlkDev *bd;
+  drv_let=Let2Let(drv_let);
+  bd=Let2BlkDev(drv_let);
+  drv_num=bd->first_drv_let-'A';
+  switch (bd->type) {
+    case BDT_ATA:
+      offset=0;
+      ext_base=INVALID_CLUS;
+      while (TRUE) {
+        ATAReadBlks(bd,&mbr,offset,1);
+        j=-1;
+        for (i=0;i<4;i++) {
+          cur_type=mbr.p[i].type;
+          if (cur_type) {
+            if (cur_type==5 || cur_type==15)
+              j=i;
+            else {
+              if (drv_num+'A'==drv_let) {
+                switch (type) {
+                  case FSt_REDSEA:
+                    mbr.p[i].type=MBR_PT_REDSEA;
+                    break;
+                  case FSt_FAT32:
+                    mbr.p[i].type=MBR_PT_FAT32a;
+                    break;
+                  default:
+                    throw('Drv');
+                }
+                mbr.p[i].active=0x80;
+                ATAWriteBlks(bd,&mbr,offset,1);
+                return TRUE;
+              }
+              drv_num++;
+            }
+          }
+        }
+        if (j<0)
+          break;
+        if (!mbr.p[j].offset)
+          break;
+        if (ext_base==INVALID_CLUS) {
+          offset=mbr.p[j].offset;
+          ext_base=offset;
+        } else
+          offset=mbr.p[j].offset+ext_base;
+      }
+      break;
+  }
+}
+
+U0 Fmt(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=FSt_FAT32)
+{//Format hard drive or RAM drive.
+//Warning: Destroys all prev info.
+  //quick=FALSE means fill entire drive with zeros.
+  //Choose FSt_FAT32 or FSt_REDSEA.
+  //You don't format a CD/DVD with this.
+  CDrv *dv=Let2Drv(drv_let);
+  Bool old_silent=IsSilent;
+  if (confirm && !AreYouSure)
+    return;
+  if (!dv)  {
+    PrintErr("Invalid Drive\n");
+    return;
+  }
+  switch (type) {
+    case FSt_FAT32:
+      if (dv->bd->type==BDT_ATA) {
+        Silent;
+        Drv(drv_let);
+        Silent(old_silent);
+        FAT32Fmt(drv_let,quick);
+        DskCacheInvalidate(Let2Drv(drv_let));
+        Drv(drv_let);
+        break;
+      }
+      "Using RedSea File System.\n";
+    case FSt_REDSEA:
+      Silent;
+      Drv(drv_let);
+      Silent(old_silent);
+      RedSeaFmt(drv_let,quick);
+      DskCacheInvalidate(Let2Drv(drv_let));
+      Drv(drv_let);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskStrA.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskStrA.HC.HTML new file mode 100755 index 0000000..f1ccaa1 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskStrA.HC.HTML @@ -0,0 +1,374 @@ + + + + + + + + + + + +
+U8 *FileExtDot(U8 *src)
+{//Find dot char in name.
+  I64 ch;
+  while (ch=*src++)
+    if (ch=='.' && *src!='/' && *src!='.')
+      return src-1;
+  return NULL;
+}
+
+U8 *FileExtRem(U8 *src,U8 *dst=NULL)
+{//Remove filename extension from str.
+  U8 *ptr;
+  if (ptr=FileExtDot(src)) {
+    if (dst)
+      StrCpy(dst,ptr+1);
+    *ptr=0;
+  } else if (dst)
+    *dst=0;
+  return dst;
+}
+
+Bool IsDotZ(U8 *filename)
+{//Does name end in .Z?
+  I64 i=StrLen(filename);
+  if (StrOcc(filename,'.')>1 && filename[i-1]=='Z' && filename[i-2]=='.')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool IsDotC(U8 *filename)
+{//Does name end in .C?
+  I64 i=StrLen(filename);
+  if (StrOcc(filename,'.')>1 && filename[i-1]=='C' && filename[i-2]=='.')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool FilesFindMatch(U8 *_test_name,U8 *files_find_mask,I64 fuf_flags=0)
+{//Does filename meet Files Find mask?
+  I64 tn_len=StrLen(_test_name),mask_len=StrLen(files_find_mask);
+  U8 *mask1=MAlloc(mask_len+1),*mask2=MAlloc(mask_len+1),
+        *ptr,*test_name1,*test_name2;
+  Bool res=FALSE;
+  StrCpy(mask1,files_find_mask);
+  if (StrOcc(_test_name,'/')) {
+    test_name1=MAlloc(tn_len+1);
+    test_name2=MAlloc(tn_len+1);
+    StrCpy(test_name1,_test_name);
+    StrLastRem(test_name1,"/",test_name2);
+  } else {
+    test_name1=NULL;
+    test_name2=NULL;
+  }
+  while (TRUE) {
+    StrFirstRem(mask1,";",mask2);
+    if (!test_name2 || StrOcc(mask2,'/'))
+      ptr=_test_name;
+    else
+      ptr=test_name2;
+    if (*mask2) {
+      if (*mask2=='!') {
+        if (WildMatch(ptr,mask2+1)) {
+          res=FALSE;
+          break;
+        }
+      } else {
+        if (WildMatch(ptr,mask2)) {
+          if (Bt(&fuf_flags,FUf_JUST_TXT) &&
+                !FilesFindMatch(_test_name,FILEMASK_TXT)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_DD) &&
+                !FilesFindMatch(_test_name,FILEMASK_DD)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_SRC) &&
+                !FilesFindMatch(_test_name,FILEMASK_SRC)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_AOT) &&
+                !FilesFindMatch(_test_name,FILEMASK_AOT)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_JIT) &&
+                !FilesFindMatch(_test_name,FILEMASK_JIT)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_GR) &&
+                !FilesFindMatch(_test_name,FILEMASK_GR)) {
+            res=FALSE;
+            break;
+          } else
+            res=TRUE;
+        }
+      }
+    } else
+      break;
+  }
+  Free(test_name1);
+  Free(test_name2);
+  Free(mask1);
+  Free(mask2);
+  return res;
+}
+
+U8 *DirNameAbs(U8 *_dirname)
+{//MAlloc absolute dir string with drv letter.
+  I64 maxlen;
+  U8 drv[3],*res,*buf,*buf2,*buf3,*buf4,*dirname,*free_dirname;
+  if (!Fs->cur_dir || !*Fs->cur_dir)
+    return StrNew(_dirname);
+  free_dirname=dirname=MStrUtil(_dirname,
+        SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  *drv=Drv2Let;
+  drv[1]=':';
+  drv[2]=0;
+  if (*dirname && dirname[1]==':') {
+    if (*dirname==':')
+      *drv=blkdev.boot_drv_let;
+    else if (*dirname=='~')
+      *drv=*blkdev.home_dir;
+    else
+      *drv=*dirname;
+    dirname=dirname+2;
+    buf=StrNew("/");
+  } else
+    buf=StrNew(Fs->cur_dir);
+  if (*dirname=='/') {
+    Free(buf);
+    buf=StrNew("/");
+    dirname++;
+  }
+  buf2=StrNew(dirname);
+  maxlen=StrLen(buf)+1+StrLen(buf2)+1;
+  buf3=MAlloc(maxlen);
+  buf4=MAlloc(maxlen);
+  StrCpy(buf3,buf);
+  while (*buf2) {
+    StrFirstRem(buf2,"/",buf4);
+    if (!*buf4)
+      StrCpy(buf3,"/");
+    else if (!StrCmp(buf4,"..")) {
+      StrLastRem(buf3,"/");
+      if (!*buf3)
+        StrCpy(buf3,"/");
+    } else if (!StrCmp(buf4,"~")) {
+      Free(buf3);
+      buf3=MAlloc(StrLen(blkdev.home_dir+2)+1+StrLen(buf2)+1);
+      StrCpy(buf3,blkdev.home_dir+2);
+      *drv=*blkdev.home_dir;
+    } else if (!StrCmp(buf4,"."));
+    else if (*buf4) {
+      if (StrCmp(buf3,"/"))
+        CatPrint(buf3,"/");
+      CatPrint(buf3,buf4);
+    }
+  }
+  Free(buf);
+  res=MAlloc(StrLen(buf3)+3);
+  StrCpy(res,drv);
+  StrCpy(res+2,buf3);
+  Free(buf2);
+  Free(buf3);
+  Free(buf4);
+  Free(free_dirname);
+  return res;
+}
+
+U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=0)
+{//Absolute filename. Accepts FUF_Z_OR_NOT_Z, FUF_SCAN_PARENTS.
+  U8 *res,*filename,*buf,*buf_file,*buf_dir,*free_filename,*free_buf;
+  CDirEntry de;
+  free_filename=filename=MStrUtil(_filename,
+        SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  free_buf=buf=StrNew(filename);
+  if (*buf && buf[1]==':') {
+    buf+=2;
+    filename+=2;
+  }
+  buf_file=MAlloc(StrLen(free_filename)+1);
+  StrLastRem(buf,"/",buf_file);
+  if (*filename=='/' && !*buf)
+    StrCpy(buf,"/");
+  buf_dir=DirNameAbs(free_buf);
+  Free(free_buf);
+  res=MAlloc(StrLen(buf_dir)+1+StrLen(buf_file)+1);
+  StrCpy(res,buf_dir);
+  if (res[StrLen(res)-1]!='/')
+    CatPrint(res,"/");
+  CatPrint(res,buf_file);
+  Free(buf_file);
+  Free(buf_dir);
+  Free(free_filename);
+  if (fuf_flags && FileFind(res,&de,fuf_flags|FUF_JUST_FILES)) {
+    Free(res);
+    res=de.full_name;
+  }
+  return res;
+}
+
+U8 *ExtChg(U8 *filename,U8 *extension)
+{//Change filename extension.
+  U8 *res=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
+  StrCpy(res,filename);
+  if (FileExtDot(filename))
+    FileExtRem(res);
+  return CatPrint(res,".%s",extension);
+}
+
+U8 *ExtDft(U8 *filename,U8 *extension)
+{//Give extension if has none.
+  U8 *res=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
+  StrCpy(res,filename);
+  if (!FileExtDot(filename))
+    CatPrint(res,".%s",extension);
+  return res;
+}
+
+CDirEntry *Cd2DirEntry(CDirEntry *tmpde,U8 *abs_name)
+{
+  I64 i;
+  while (tmpde) {
+    i=StrLen(tmpde->full_name);
+    if (StrNCmp(tmpde->full_name,abs_name,i)||
+          i && tmpde->full_name[i-1]!='/' && abs_name[i] && abs_name[i]!='/')
+      tmpde=tmpde->next;
+    else
+      if (StrLen(abs_name)==i)
+        return tmpde;
+      else
+        return Cd2DirEntry(tmpde->sub,abs_name);
+  }
+  return NULL;
+}
+
+I64 FileAttr(U8 *name,I64 attr=0)
+{
+  if (IsDotZ(name))
+    attr|=RS_ATTR_COMPRESSED;
+  else
+    attr&=~RS_ATTR_COMPRESSED;
+  if (IsDotC(name))
+    attr|=RS_ATTR_CONTIGUOUS;
+  return attr;
+}
+
+Bool FileNameChk(U8 *filename)
+{//Return check for valid filename, not checking existence.
+  U8 *ptr=filename;
+  if (!filename) return FALSE;
+  if (!*ptr) return FALSE;
+  if (*ptr=='.') {
+    if (!ptr[1]) return TRUE;
+    if (ptr[1]=='.' && !ptr[2]) return TRUE;
+  }
+  if (StrLen(filename)>=CDIR_FILENAME_LEN) return FALSE;
+  while (*ptr)
+    if (!Bt(char_bmp_filename,*ptr++))
+      return FALSE;
+  return TRUE;
+}
+
+U8 *ToggleZorNotZ(U8 *name)
+{//MAlloc name with Z if not Z or vice versa.
+  U8 *res;
+  if (IsDotZ(name)) {
+    res=StrNew(name);
+    res[StrLen(name)-2]=0;
+  } else
+    res=MStrPrint("%s.Z",name);
+  return res;
+}
+
+U8 *FileNameTmpTxt()
+{//Make pretty-safe tmp filename in home dir.
+  return MStrPrint("~/SysTmp%X.DD.Z",GetTSC>>8&0xFFFFFFFF);
+}
+
+U8 *DirCur(CTask *task=NULL,CTask *mem_task=NULL)
+{//MAlloc copy of cur dir with drv letter.
+  U8 *st;
+  if (!task) task=Fs;
+  if (!task->cur_dir)
+    return NULL;
+  st=MAlloc(StrLen(task->cur_dir)+3,mem_task);
+  *st=Drv2Let(task->cur_dv);
+  st[1]=':';
+  StrCpy(st+2,task->cur_dir);
+  return st;
+}
+
+U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL)
+{/*Strips file from dirname, scans for file upward until found or
+returns default.
+
+("/Kernel/KHashA.HC.Z",NULL,NULL)       returns "D:/Kernel"
+("/Kernel",NULL,"PRJ.Z")                returns "D:/Kernel/Kernel.PRJ.Z"
+("/Kernel/BlkDev",NULL,"PRJ.Z")         returns "D:/Kernel/Kernel.PRJ.Z"
+("/Apps/Psalmody","Load","HC.Z")        returns "D:/Apps/Psalmody/Load.HC.Z"
+*/
+  U8 *st=DirNameAbs(dirname),*st2,*st3,*res,*dft=NULL,*ext;
+  if (_extension && *_extension) {
+    if (*_extension=='.')
+      ext=StrNew(_extension);
+    else
+      ext=MStrPrint(".%s",_extension);
+  } else
+    ext=StrNew("");
+  while (StrOcc(st,'/')&&!IsDir(st))
+    StrLastRem(st,"/");
+  while (StrOcc(st,'/')) {
+    st2=StrNew(st);
+    st3=StrNew(st);
+    StrLastRem(st2,"/",st3);
+
+    if (name)
+      res=MStrPrint("%s/%s%s",st,name,ext);
+    else {
+      if (*ext)
+        res=MStrPrint("%s/%s%s",st,st3,ext);
+      else
+        res=StrNew(st);
+    }
+    if (!dft)
+      dft=StrNew(res);
+    if (!*ext && (!name||!*name) || FileFind(res)) {
+      Free(st3);
+      Free(st2);
+      Free(st);
+      Free(dft);
+      Free(ext);
+      return res;
+    }
+    Free(st);
+    st=st2;
+    Free(st3);
+  }
+  Free(st);
+  Free(ext);
+  return dft;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/DskStrB.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/DskStrB.HC.HTML new file mode 100755 index 0000000..171cf77 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/DskStrB.HC.HTML @@ -0,0 +1,120 @@ + + + + + + + + + + + +
+Bool CFileNameTo(U8 *dst,U8 *src)
+{
+  MemSet(dst,0,CDIR_FILENAME_LEN);
+  if (!FileNameChk(src))
+    return FALSE;
+  StrCpy(dst,src);
+  return TRUE;
+}
+
+I64 Name2DirClus(CDrv *dv,U8 *dirname)
+{
+  Bool cont=TRUE,unlock;
+  I64 cur_dir_clus;
+  CDirEntry de;
+  U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    cur_dir_clus=dv->root_clus;
+    while (*buf && cont) {
+      StrFirstRem(buf,"/",buf2);
+      if (*buf2) {
+        switch (dv->fs_type) {
+          case FSt_REDSEA:
+            cont=RedSeaFileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          case FSt_FAT32:
+            cont=FAT32FileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          default:
+            throw('Drv');
+        }
+        cur_dir_clus=de.clus;
+      }
+    }
+    if (!cont) {
+      PrintErr("File not found: \"%s\".\n",dirname);
+      cur_dir_clus=0;
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  Free(buf);
+  Free(buf2);
+  return cur_dir_clus;
+}
+
+I64 Name2ParentDirClus(CDrv *dv,U8 *dirname)
+{
+  Bool cont=TRUE,unlock;
+  I64 cur_dir_clus,cur_dir_clus2;
+  CDirEntry de;
+  U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    cur_dir_clus=cur_dir_clus2=dv->root_clus;
+    while (*buf && cont) {
+      cur_dir_clus2=cur_dir_clus;
+      StrFirstRem(buf,"/",buf2);
+      if (*buf2) {
+        switch (dv->fs_type) {
+          case FSt_REDSEA:
+            cont=RedSeaFileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          case FSt_FAT32:
+            cont=FAT32FileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          default:
+            throw('Drv');
+        }
+        cur_dir_clus=de.clus;
+      }
+    }
+    if (!cont) {
+      PrintErr("File not found: \"%s\".\n",dirname);
+      cur_dir_clus2=0;
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  Free(buf);
+  Free(buf2);
+  return cur_dir_clus2;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/FileSysFAT.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/FileSysFAT.HC.HTML new file mode 100755 index 0000000..9302844 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/FileSysFAT.HC.HTML @@ -0,0 +1,990 @@ + + + + + + + + + + + +
+U0 CDate2Dos(U16 *t,U16 *d,CDate cdt)
+{
+  CDateStruct ds;
+  Date2Struct(&ds,cdt);
+  *d=ds.day_of_mon+(ds.mon+(ds.year-1980)<<4)<<5;
+  *t=ds.sec>>1+(ds.min+ds.hour<<6)<<5;
+}
+
+CDate Dos2CDate(U16 t,U16 d)
+{
+  CDateStruct ds;
+  MemSet(&ds,0,sizeof(CDateStruct));
+  ds.day_of_mon=d&0x1F; d=d>>5;
+  ds.mon=d&0xF;
+  ds.year=d>>4+1980;
+  ds.sec=(t&0x1F)*2; t=t>>5;
+  ds.min=t&0x3F;
+  ds.hour=t>>6;
+  return Struct2Date(&ds);
+}
+
+U0 FAT32Init(CDrv *dv)
+{
+  CFAT32Boot br32;
+  Bool unlock;
+  try {
+    unlock=DrvLock(dv);
+    dv->fs_type=FSt_FAT32;
+    BlkRead(dv,&br32,dv->drv_offset,1);
+    dv->file_system_info_sect=dv->drv_offset+br32.file_system_info_sect;
+    dv->fat1=dv->drv_offset+br32.reserved_sects;
+    dv->fat2=dv->fat1+br32.sects_per_fat;
+    dv->data_area=dv->fat2+br32.sects_per_fat
+          -2*br32.sects_per_clus; //Starts at Clus 2
+    dv->spc=br32.sects_per_clus;
+    dv->root_clus=br32.root_clus;
+    DrvFATBlkAlloc(dv);
+    Free(dv->fis);
+    dv->fis=AMAlloc(BLK_SIZE);
+    BlkRead(dv,dv->fis,dv->file_system_info_sect,1);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 FAT32Fmt(U8 drv_let,Bool quick=TRUE)
+{
+  CFAT32Boot *br=CAlloc(BLK_SIZE);
+  CFAT32FileInfoSect *fis=CAlloc(BLK_SIZE);
+  CDrv *dv=Let2Drv(drv_let);
+  I64 i,l;
+  try {
+    DrvLock(dv);
+    DrvTypeSet(drv_let,FSt_FAT32);
+    dv->fs_type=FSt_FAT32;
+    br->jump_and_nop[0]=OC_JMP_REL8;
+    br->jump_and_nop[1]=offset(CFAT32Boot.code)-2;
+    br->jump_and_nop[2]=OC_NOP;
+    br->oem_name[0](I64)='MSWIN4.1';
+    br->bytes_per_sect=BLK_SIZE;
+    if    (dv->size<= 500000)
+      br->sects_per_clus=1;
+    else if (dv->size<=2000000)
+      br->sects_per_clus=2;
+    else if (dv->size<=6000000)
+      br->sects_per_clus=4;
+    else if (dv->size<=12000000)
+      br->sects_per_clus=8;
+    else if (dv->size<=33000000)
+      br->sects_per_clus=16;
+    else if (dv->size<=67000000)
+      br->sects_per_clus=32;
+    else
+      br->sects_per_clus=64;
+
+    br->reserved_sects=32;
+    br->copies_of_fat=2;
+    br->media_desc=0xF8;
+    br->sects=dv->size;
+    l=(br->sects/br->sects_per_clus)>>(BLK_SIZE_BITS-2)+1;
+    br->sects_per_fat=l;
+    br->root_clus=2;
+    br->file_system_info_sect=1;
+    br->log_drv_num=0x80;
+    br->ext_signature=0x29;
+    br->serial_num=RandU32;
+    MemCpy(br->vol_name,"NO NAME    ",11);
+    br->fat_name[0](I64)='FAT32   ';
+    br->signature=0xAA55;
+    fis->signature1='RRaA';
+    fis->signature2='rrAa';
+    fis->free_clus=-1;
+    fis->most_recently_alloced=0;
+    fis->signature3=0xAA550000;
+
+    if (quick)
+      i=br->reserved_sects+2*l+4*br->sects_per_clus;
+    else
+      i=dv->size;
+    BlkWriteZero(dv,dv->drv_offset,i);
+
+    BlkWrite(dv,fis,dv->drv_offset+br->file_system_info_sect,1);
+    BlkWrite(dv,br,dv->drv_offset,1);
+    FAT32Init(dv);
+    ClusAlloc(dv,0,1,FALSE); //Alloc #1
+    br->root_clus=ClusAlloc(dv,0,1,FALSE);
+    BlkWrite(dv,br,dv->drv_offset,1);
+    FAT32Init(dv);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  Free(br);
+  Free(fis);
+}
+
+Bool FATNameTo(U8 *dst,U8 *src)
+{
+  I64 i;
+  MemSet(dst,CH_SPACE,11);
+  if (!FileNameChk(src))
+    return FALSE;
+  if (!StrCmp(src,"..")) {
+    *dst='.';
+    dst[1]='.';
+    return TRUE;
+  } else if (!StrCmp(src,".")) {
+    *dst='.';
+    return TRUE;
+  }
+  i=0;
+  while (i<8 && *src && *src!='.')
+    dst[i++]=ToUpper(*src++);
+  i=8;
+  if (*src=='.') src++;
+  while (*src)
+    if (*src!='.')
+      dst[i++]=ToUpper(*src++);
+    else
+      src++;
+  return TRUE;
+}
+
+I64 FATNameXSum(U8 *src)
+{
+  I64 i,res=0;
+  for (i=0;i<11;i++)
+    if (res&1)
+      res.u8[0]=0x80+res>>1+*src++;
+    else
+      res.u8[0]=res>>1+*src++;
+  return res;
+}
+
+Bool FATFromName(U8 *dst,U8 *src)
+{
+  I64 i,j,k=0;
+  for (j=7;j>=0 && src[j]==CH_SPACE;j--);
+  for(i=0;i<=j;i++)
+    dst[k++]=src[i];
+  for (j=10;j>=8 && src[j]==CH_SPACE;j--);
+  if (*src!='.' && j!=7)
+    dst[k++]='.';
+  for(i=8;i<=j;i++)
+    dst[k++]=src[i];
+  dst[k++]=0;
+  return FileNameChk(dst);
+}
+
+U8 fat_long_name_map[13]={
+  offset(CFAT32DirEntryLong.name1),
+  offset(CFAT32DirEntryLong.name1)+2,
+  offset(CFAT32DirEntryLong.name1)+4,
+  offset(CFAT32DirEntryLong.name1)+6,
+  offset(CFAT32DirEntryLong.name1)+8,
+  offset(CFAT32DirEntryLong.name2),
+  offset(CFAT32DirEntryLong.name2)+2,
+  offset(CFAT32DirEntryLong.name2)+4,
+  offset(CFAT32DirEntryLong.name2)+6,
+  offset(CFAT32DirEntryLong.name2)+8,
+  offset(CFAT32DirEntryLong.name2)+10,
+  offset(CFAT32DirEntryLong.name3),
+  offset(CFAT32DirEntryLong.name3)+2
+};
+
+Bool DirLongNameFill(CDirEntry *tmpde,CFAT32DirEntryLong *de,I64 *xsum)
+{
+  I64 i;
+  U8 *ptr=de;
+  if (de->ord&0x40) {
+    MemSet(tmpde,0,sizeof(CDirEntry));
+    *xsum=de->xsum;
+  } else if (de->type || de->zero || de->xsum!=*xsum) {
+    MemSet(tmpde,0,sizeof(CDirEntry));
+    *xsum=0;
+    return FALSE;
+  }
+  switch (de->ord&0x3F) {
+    case 1:
+      for (i=0;i<13;i++)
+        if (!(tmpde->name[i]=ptr[fat_long_name_map[i]]))
+          return TRUE;
+      break;
+    case 2:
+      for (i=0;i<12;i++)
+        if (!(tmpde->name[i+13]=ptr[fat_long_name_map[i]]))
+          return TRUE;
+      break;
+  }
+  return TRUE;
+}
+
+Bool FAT32CDirFill(CDirEntry *tmpde,
+        CFAT32DirEntry *de,CDate _local_time_offset)
+{
+  Bool res;
+  if (*tmpde->name)
+    res=TRUE;
+  else
+    res=FATFromName(tmpde->name,de->name);
+  tmpde->clus=de->clus_lo+de->clus_hi<<16;
+  tmpde->size=de->size;
+  tmpde->attr=de->attr;
+  tmpde->datetime=Dos2CDate(de->WrtTime,de->WrtDate)-_local_time_offset;
+  return res;
+}
+
+Bool FAT32DirFill(CFAT32DirEntry *de,
+        CDirEntry *tmpde,I64 *_de_cnt,CDate _local_time_offset)
+{//Fill up to 3 entries and store cnt of entries.
+  I64 de_cnt=0,i,l,xsum,ord;
+  U8 *ptr,dname[16];
+  CFAT32DirEntryLong *ld=de;
+  Bool res;
+
+  MemSet(de,0,sizeof(CFAT32DirEntry));
+  res=FATNameTo(de->name,tmpde->name);
+  FATFromName(dname,de->name);
+  if (StrCmp(dname,tmpde->name)) {
+    ord=0x41;
+    xsum=FATNameXSum(de->name);
+    if ((l=StrLen(tmpde->name))>13) {
+      ptr=&ld[de_cnt];
+      MemSet(ptr,0,sizeof(CFAT32DirEntryLong));
+      ld[de_cnt].attr=RS_ATTR_LONG_NAME;
+      ld[de_cnt].xsum=xsum;
+      ld[de_cnt].ord=0x42;
+      for (i=13;i<l;i++)
+        ptr[fat_long_name_map[i-13]]=tmpde->name[i];
+      i++;
+      for (;i<26;i++)
+        ptr[fat_long_name_map[i-13]](U16)=0xFFFF;
+      ord=1;
+      l=13;
+      de_cnt++;
+    }
+    ptr=&de[de_cnt];
+    MemSet(ptr,0,sizeof(CFAT32DirEntryLong));
+    ld[de_cnt].attr=RS_ATTR_LONG_NAME;
+    ld[de_cnt].xsum=xsum;
+    ld[de_cnt].ord=ord;
+    for (i=0;i<l;i++)
+      ptr[fat_long_name_map[i]]=tmpde->name[i];
+    i++;
+    for (;i<13;i++)
+      ptr[fat_long_name_map[i]](U16)=0xFFFF;
+    de_cnt++;
+    MemSet(&de[de_cnt],0,sizeof(CFAT32DirEntry));
+    res=FATNameTo(de[de_cnt].name,tmpde->name);
+  }
+  de[de_cnt].clus_lo=tmpde->clus.u16[0];
+  de[de_cnt].clus_hi=tmpde->clus.u16[1];
+  if (!(tmpde->attr&RS_ATTR_DIR))
+    de[de_cnt].size=tmpde->size;
+  de[de_cnt].attr=tmpde->attr;
+  if (!tmpde->datetime)
+    tmpde->datetime=Now;
+  CDate2Dos(&de[de_cnt].WrtTime,&de[de_cnt].WrtDate,
+        tmpde->datetime+_local_time_offset);
+  if (_de_cnt)
+    *_de_cnt=de_cnt+1;
+  return res;
+}
+
+Bool FAT32FileFind(CDrv *dv,I64 cur_dir_clus,
+        U8 *name,CDirEntry *_res,I64 fuf_flags=0)
+{//FUF_JUST_DIRS, FUF_JUST_FILES
+  Bool res=FALSE,unlock;
+  CFAT32DirEntry *buf;
+  I64 xsum=0,attr,cur_dir_entry,entries_per_clus;
+  U8 dname[CDIR_FILENAME_LEN],ch;
+  CDirEntry long_name;
+  if (fuf_flags&~FUG_FILE_FIND)
+    throw('FUF');
+  MemSet(_res,0,sizeof(CDirEntry));
+  MemSet(&long_name,0,sizeof(CDirEntry));
+  DrvChk(dv);
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else if (!CFileNameTo(dname,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else
+    try {
+      unlock=DrvLock(dv);
+      buf=MAlloc(BLK_SIZE*dv->spc);
+      entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+      ClusRead(dv,buf,cur_dir_clus,1);
+      cur_dir_entry=0;
+      while (ch=*buf[cur_dir_entry].name) {
+        attr=buf[cur_dir_entry].attr;
+        if (ch!=0xE5) {
+          if (attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+            DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+          else {
+            if (!(attr&RS_ATTR_VOL_ID)) {
+              if (xsum==FATNameXSum(buf[cur_dir_entry].name))
+                MemCpy(_res,&long_name,sizeof(CDirEntry));
+              else
+                MemSet(_res,0,sizeof(CDirEntry));
+              if (!(fuf_flags&FUF_JUST_DIRS && !(attr & RS_ATTR_DIR)) &&
+                    !(fuf_flags&FUF_JUST_FILES && attr & RS_ATTR_DIR) &&
+                    FAT32CDirFill(_res,&buf[cur_dir_entry],
+                    dv->fat32_local_time_offset) &&
+                    !StrCmp(dname,_res->name)) {
+                res=TRUE;
+                goto fff_done;
+              }
+            }
+            MemSet(&long_name,0,sizeof(CDirEntry));
+          }
+        } else
+          MemSet(&long_name,0,sizeof(CDirEntry));
+        if (++cur_dir_entry==entries_per_clus) {
+          cur_dir_clus=ClusNumNext(dv,cur_dir_clus);
+          if (!(0<cur_dir_clus<0x0FFFFFF8))
+            break;
+          else {
+            ClusRead(dv,buf,cur_dir_clus,1);
+            cur_dir_entry=0;
+          }
+        }
+      }
+      MemSet(_res,0,sizeof(CDirEntry));
+fff_done:
+      Free(buf);
+      if (unlock)
+        DrvUnlock(dv);
+    } catch
+      if (unlock)
+        DrvUnlock(dv);
+  return res;
+}
+
+U8 *FAT32FileRead(CDrv *dv,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
+{
+  U8 *buf=NULL;
+  CDirEntry de;
+  I64 c,blk_cnt,cur_dir_clus;
+  DrvChk(dv);
+  *_size=0;
+  *_attr=0;
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else
+    try {
+      DrvLock(dv);
+      cur_dir_clus=Name2DirClus(dv,cur_dir);
+      if (FAT32FileFind(dv,cur_dir_clus,filename,&de,FUF_JUST_FILES)) {
+        blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+        buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
+        c=de.clus;
+        if (!(0<c<0x0FFFFFF8))
+          c=0x0FFFFFFF;
+        else
+          c=ClusBlkRead(dv,buf,c,blk_cnt);
+        buf[de.size]=0; //Terminate
+        *_size=de.size;
+        *_attr=FileAttr(de.name,de.attr);
+      }
+      DrvUnlock(dv);
+    } catch
+      DrvUnlock(dv);
+  return buf;
+}
+
+Bool FAT32Cd(U8 *name,I64 cur_dir_clus)
+{
+  CDirEntry de;
+  if (Fs->cur_dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else if (FAT32FileFind(Fs->cur_dv,cur_dir_clus,name,&de,FUF_JUST_DIRS))
+    return TRUE;
+  else
+    PrintErr("File not found: \"%s\".\n",name);
+  return FALSE;
+}
+
+U0 FAT32FreeClus(CDrv *dv,I64 c)
+{
+  I64 next,saved_c=c;
+  Bool unlock,unlock_break;
+  DrvChk(dv);
+  if (!(0<c<0x0FFFFFF8)) return;
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else
+    try {
+      unlock_break=BreakLock;
+      unlock=DrvLock(dv);
+      DrvFATBlkClean(dv);
+      do {
+        DrvFATBlkSet(dv,c,0);
+        next=dv->cur_fat_blk[c&(BLK_SIZE/4-1)];
+        dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=0;
+        LBts(&dv->fat_blk_dirty,0);
+        c=next;
+      } while (0<c<0x0FFFFFF8);
+      DrvFATBlkClean(dv,0);
+
+      c=saved_c;
+      do {
+        DrvFATBlkSet(dv,c,1);
+        next=dv->cur_fat_blk[c&(BLK_SIZE/4-1)];
+        dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=0;
+        LBts(&dv->fat_blk_dirty,0);
+        c=next;
+      } while (0<c<0x0FFFFFF8);
+      DrvFATBlkClean(dv,1);
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    } catch {
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    }
+}
+
+I64 FAT32AllocClus(CDrv *dv,I64 c,I64 cnt)
+{
+  Bool wrap_around=FALSE,unlock,unlock_break;
+  I64 first=INVALID_CLUS,j,l;
+
+  if (cnt<=0) return 0x0FFFFFFF;
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    l=(dv->size+dv->drv_offset-dv->data_area)/dv->spc-1;
+    j=dv->fis->most_recently_alloced;
+    while (cnt-->0) {
+      while (TRUE) {
+        j++;
+        if (j<1) j=1;
+        if (j>=l) {
+          if (wrap_around)
+            throw('Drv');
+          j=1;
+          wrap_around=TRUE;
+        }
+        DrvFATBlkSet(dv,j);
+        if (!dv->cur_fat_blk[j&(BLK_SIZE/4-1)])
+          break;
+      }
+      if (!(0<first<0x0FFFFFF8))
+        first=j;
+      if (0<c<l) {
+        DrvFATBlkSet(dv,c);
+        dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=j;
+        LBts(&dv->fat_blk_dirty,0);
+      }
+      c=j;
+    }
+
+    if (0<c<l) {
+      DrvFATBlkSet(dv,c);
+      dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=0x0FFFFFFF;
+      LBts(&dv->fat_blk_dirty,0);
+    }
+    DrvFATBlkClean(dv);
+
+    dv->fis->most_recently_alloced=j;
+    dv->fis->free_clus=-1;
+    BlkWrite(dv,dv->fis,dv->file_system_info_sect,1);
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  if (unlock)
+    DrvUnlock(dv);
+  if (unlock_break)
+    BreakUnlock;
+  return first;
+}
+
+I64 FAT32AllocContiguousClus(CDrv *dv,I64 cnt)
+{
+  I64 i,first=1;
+  Bool cont,unlock,unlock_break;
+
+  if (cnt<=0) return 0x0FFFFFFF;
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    while (TRUE) {
+      first++;
+      i=0;
+      cont=TRUE;
+      while (cont && i<cnt) {
+        if ((first+i+1)*dv->spc+dv->data_area>dv->size+dv->drv_offset)
+          throw('Drv');
+        DrvFATBlkSet(dv,first+i);
+        if (dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)])
+          cont=FALSE;
+        else
+          i++;
+      }
+      if (!cont)
+        first=first+i;
+      else {
+        DrvFATBlkClean(dv);
+
+        for (i=0;i<cnt;i++) {
+          DrvFATBlkSet(dv,first+i,0);
+          if (i+1==cnt)
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
+          else
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
+          LBts(&dv->fat_blk_dirty,0);
+        }
+        DrvFATBlkClean(dv,0);
+
+        for (i=0;i<cnt;i++) {
+          DrvFATBlkSet(dv,first+i,1);
+          if (i+1==cnt)
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
+          else
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
+          LBts(&dv->fat_blk_dirty,0);
+        }
+        DrvFATBlkClean(dv,1);
+        break;
+      }
+    }
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  if (unlock)
+    DrvUnlock(dv);
+  if (unlock_break)
+    BreakUnlock;
+  return first;
+}
+
+Bool FAT32DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain)
+{
+//See ::/Doc/CutCorners.DD.
+  CFAT32DirEntry *buf,*last_buf,*tmp_buf,de[3];
+  I64 i,attr,avail_cnt,de_cnt,c,
+        cur_dir_entry,entries_per_clus,
+        cur_dir_clus,xsum=0,last_dir_clus=INVALID_CLUS;
+  U8 ch;
+  Bool written=FALSE,unlock,unlock_break;
+  CDirEntry long_name;
+  FAT32DirFill(&de,tmpde,&de_cnt,dv->fat32_local_time_offset);
+  MemSet(&long_name,0,sizeof(CDirEntry));
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf     =MAlloc(BLK_SIZE*dv->spc);
+    last_buf=CAlloc(BLK_SIZE*dv->spc);
+    entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+    ClusRead(dv,buf,cur_dir_clus,1);
+    cur_dir_entry=0;
+    while (ch=*buf[cur_dir_entry].name) {
+      attr=buf[cur_dir_entry].attr;
+      if (ch!=0xE5 && attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+        DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+      else {
+        avail_cnt=FAT32_ENTRIES_PER_BLK-cur_dir_entry
+              &(FAT32_ENTRIES_PER_BLK-1);
+        for (i=0;i<avail_cnt;i++)
+          if (*buf[cur_dir_entry+i].name!=0xE5) {
+            if (*buf[cur_dir_entry+i].name)
+              avail_cnt=i;
+            break;
+          }
+        if (ch==0xE5 && !written && avail_cnt>=de_cnt) {
+          MemCpy(&buf[cur_dir_entry],&de,de_cnt*sizeof(CFAT32DirEntry));
+          BlkWrite(dv,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
+                dv->data_area+cur_dir_clus*dv->spc
+                +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+          cur_dir_entry+=de_cnt-1; //gets inc'ed
+          written=TRUE;
+        } else if (ch!=0xE5 && !(attr&RS_ATTR_VOL_ID)) {
+          if (xsum!=FATNameXSum(buf[cur_dir_entry].name))
+            MemSet(&long_name,0,sizeof(CDirEntry));
+          if (!*long_name.name)
+            FATFromName(long_name.name,buf[cur_dir_entry].name);
+//Del old entry with same name
+          if (!StrCmp(long_name.name,tmpde->name)) {
+            if (free_old_chain)
+              FAT32FreeClus(dv,buf[cur_dir_entry].clus_lo+
+                    buf[cur_dir_entry].clus_hi<<16);
+            if (!written) {
+              MemCpy(&buf[cur_dir_entry],&de[de_cnt-1],sizeof(CFAT32DirEntry));
+              BlkWrite(dv,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
+                    dv->data_area+cur_dir_clus*dv->spc
+                    +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+              written=TRUE;
+            } else {
+              *buf[cur_dir_entry].name=0xE5;
+              i=1;
+              while (i<=cur_dir_entry &&
+                    buf[cur_dir_entry-i].attr&RS_ATTR_LONG_NAME_MASK
+                    ==RS_ATTR_LONG_NAME)
+                *buf[cur_dir_entry-i++].name=0xE5;
+              i--;
+              BlkWrite(dv,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
+                    dv->data_area+cur_dir_clus*dv->spc
+                    +(cur_dir_entry-i)>>FAT32_ENTRIES_BITS,
+                    (i+FAT32_ENTRIES_PER_BLK)>>FAT32_ENTRIES_BITS);
+              if (i==cur_dir_entry && 0<last_dir_clus<0x0FFFFFF8) {
+                i=1;
+                while (i<=entries_per_clus &&
+                      last_buf[entries_per_clus-i].attr
+                      &RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+                  *last_buf[entries_per_clus-i++].name=0xE5;
+                if (--i>0)
+                  BlkWrite(dv,&buf[(entries_per_clus-i)&-FAT32_ENTRIES_PER_BLK],
+                        dv->data_area+last_dir_clus*dv->spc
+                        +(entries_per_clus-i)>>FAT32_ENTRIES_BITS,
+                        (i+FAT32_ENTRIES_PER_BLK-1)>>FAT32_ENTRIES_BITS);
+              }
+            }
+            break;
+          }
+        }
+        MemSet(&long_name,0,sizeof(CDirEntry));
+      }
+      if (++cur_dir_entry==entries_per_clus) {
+        last_dir_clus=cur_dir_clus;
+        tmp_buf=buf; buf=last_buf; last_buf=tmp_buf;
+        c=ClusNumNext(dv,cur_dir_clus);
+        if (!(0<c<0x0FFFFFF8)) {
+          c=ClusAlloc(dv,cur_dir_clus,1,FALSE);
+          MemSet(buf,0,BLK_SIZE*dv->spc);
+          ClusWrite(dv,buf,c,1);
+        } else
+          ClusRead(dv,buf,c,1);
+        cur_dir_clus=c;
+        cur_dir_entry=0;
+      }
+    }
+    if (!written) {
+      avail_cnt=FAT32_ENTRIES_PER_BLK-cur_dir_entry & (FAT32_ENTRIES_PER_BLK-1);
+      if (avail_cnt<de_cnt) {
+        for (i=0;i<avail_cnt;i++)
+          *buf[cur_dir_entry+i].name=0xE5;
+        BlkWrite(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
+              dv->data_area+cur_dir_clus*dv->spc
+              +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+        cur_dir_entry+=avail_cnt;
+        if (cur_dir_entry==entries_per_clus) {
+          last_dir_clus=cur_dir_clus;
+          tmp_buf=buf; buf=last_buf; last_buf=tmp_buf;
+          cur_dir_clus=ClusAlloc(dv,cur_dir_clus,1);
+          cur_dir_entry=0;
+          MemSet(buf,0,BLK_SIZE*dv->spc);
+          ClusWrite(dv,buf,cur_dir_clus,1);
+        }
+      }
+      MemCpy(&buf[cur_dir_entry],&de,de_cnt*sizeof(CFAT32DirEntry));
+      BlkWrite(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
+            dv->data_area+cur_dir_clus*dv->spc+
+            cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+      cur_dir_entry+=de_cnt;
+      if (cur_dir_entry==entries_per_clus) {
+        cur_dir_clus=ClusAlloc(dv,cur_dir_clus,1);
+        MemSet(buf,0,BLK_SIZE*dv->spc);
+        ClusWrite(dv,buf,cur_dir_clus,1);
+      } else {
+        MemSet(&buf[cur_dir_entry],0,sizeof(CFAT32DirEntry));
+        BlkWrite(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
+              dv->data_area+cur_dir_clus*dv->spc
+              +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+      }
+    }
+    Free(last_buf);
+    Free(buf);
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return FALSE;
+}
+
+I64 FAT32FilesDel(CDrv *dv,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
+                     Bool del_dir,Bool print_msg)
+{
+  CFAT32DirEntry *buf,*last_buf,*tmp_buf;
+  I64 i,res=0,attr,xsum=0,last_dir_clus=INVALID_CLUS,
+        cur_dir_entry,entries_per_clus,cur_dir_clus;
+  U8 ch;
+  Bool unlock_break;
+  CDirEntry long_name;
+  MemSet(&long_name,0,sizeof(CDirEntry));
+  try {
+    unlock_break=BreakLock;
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf     =MAlloc(BLK_SIZE*dv->spc);
+    last_buf=CAlloc(BLK_SIZE*dv->spc);
+    entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+    ClusRead(dv,buf,cur_dir_clus,1);
+    cur_dir_entry=0;
+    while (ch=*buf[cur_dir_entry].name) {
+      attr=buf[cur_dir_entry].attr;
+      if (ch!=0xE5 && ch!='.') {
+        if (attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+          DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+        else {
+          if (!(attr & RS_ATTR_VOL_ID) &&
+                (del_dir || !(attr & RS_ATTR_DIR))) {
+            if (xsum!=FATNameXSum(buf[cur_dir_entry].name))
+              MemSet(&long_name,0,sizeof(CDirEntry));
+            if (!*long_name.name)
+              FATFromName(long_name.name,buf[cur_dir_entry].name);
+            if (FilesFindMatch(long_name.name,files_find_mask,fuf_flags)) {
+              if (!(attr & RS_ATTR_DIR)) res++;
+              if (print_msg)
+                "Del %s\n",long_name.name;
+              *buf[cur_dir_entry].name=0xE5;
+              i=1;
+              while (i<=cur_dir_entry &&
+                    buf[cur_dir_entry-i].attr&RS_ATTR_LONG_NAME_MASK
+                    ==RS_ATTR_LONG_NAME)
+                *buf[cur_dir_entry-i++].name=0xE5;
+              i--;
+              BlkWrite(dv,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
+                    dv->data_area+cur_dir_clus*dv->spc
+                    +(cur_dir_entry-i)>>FAT32_ENTRIES_BITS,
+                    (i+FAT32_ENTRIES_PER_BLK)>>FAT32_ENTRIES_BITS);
+              if (i==cur_dir_entry && last_dir_clus!=INVALID_CLUS) {
+                i=1;
+                while (i<=entries_per_clus &&
+                      last_buf[entries_per_clus-i].attr
+                      &RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+                  *last_buf[entries_per_clus-i++].name=0xE5;
+                if (--i>0)
+                  BlkWrite(dv,&buf[(entries_per_clus-i)&-FAT32_ENTRIES_PER_BLK],
+                        dv->data_area+last_dir_clus*dv->spc
+                        +(entries_per_clus-i)>>FAT32_ENTRIES_BITS,
+                        (i+FAT32_ENTRIES_PER_BLK-1)>>FAT32_ENTRIES_BITS);
+              }
+              FAT32FreeClus(dv,buf[cur_dir_entry].clus_lo+
+                    buf[cur_dir_entry].clus_hi<<16);
+            }
+          }
+          MemSet(&long_name,0,sizeof(CDirEntry));
+        }
+      } else
+        MemSet(&long_name,0,sizeof(CDirEntry));
+      if (++cur_dir_entry==entries_per_clus) {
+        last_dir_clus=cur_dir_clus;
+        cur_dir_clus=ClusNumNext(dv,cur_dir_clus,1);
+        tmp_buf=buf; buf=last_buf; last_buf=tmp_buf;
+        ClusRead(dv,buf,cur_dir_clus,1);
+        cur_dir_entry=0;
+      }
+    }
+    Free(buf);
+    Free(last_buf);
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return res;
+}
+
+I64 FAT32FileWrite(CDrv *dv,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
+        CDate cdt,I64 attr)
+{
+  CDirEntry de;
+  I64 c=0,blk_cnt;
+  Bool contiguous;
+  MemSet(&de,0,sizeof(CDirEntry));
+  if (size<0) size=0;
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else if (!CFileNameTo(de.name,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else {
+    FAT32FilesDel(dv,cur_dir,de.name,0,FALSE,FALSE);
+    if (attr & RS_ATTR_CONTIGUOUS)
+      contiguous=TRUE;
+    else
+      contiguous=FALSE;
+    de.size=size;
+    if (blk_cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS)
+      c=ClusAlloc(dv,0,(blk_cnt+dv->spc-1)/dv->spc,contiguous);
+    else
+      c=0x0FFFFFFF;
+    de.clus=c;
+    de.attr=attr;
+    de.datetime=cdt;
+    if (blk_cnt)
+      ClusBlkWrite(dv,buf,c,blk_cnt);
+    FAT32DirNew(dv,cur_dir,&de,TRUE);
+  }
+  return c;
+}
+
+CDirEntry *FAT32FilesFind(U8 *files_find_mask,
+        I64 fuf_flags,CDirEntry *parent=NULL,I64 *_dir_size=NULL)
+{
+  CDrv *dv=Fs->cur_dv;
+  CFAT32DirEntry *buf;
+  I64 attr,xsum=0,dir_size=0,sub_dir_size,
+        cur_dir_clus,cur_dir_entry,entries_per_clus;
+  U8 ch;
+  CDirEntry *res=NULL,*tmpde,long_name;
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+  try {
+    MemSet(&long_name,0,sizeof(CDirEntry));
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,Fs->cur_dir);
+    buf=MAlloc(BLK_SIZE*dv->spc);
+    entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+    ClusRead(dv,buf,cur_dir_clus,1);
+    dir_size+=dv->spc*BLK_SIZE;
+    cur_dir_entry=0;
+    while (ch=*buf[cur_dir_entry].name) {
+      attr=buf[cur_dir_entry].attr;
+      if (ch!=0xE5) {
+        if (attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+          DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+        else {
+          if (!(attr&RS_ATTR_VOL_ID)) {
+            tmpde=MAlloc(sizeof(CDirEntry));
+            if (xsum==FATNameXSum(buf[cur_dir_entry].name))
+              MemCpy(tmpde,&long_name,sizeof(CDirEntry));
+            else
+              MemSet(tmpde,0,sizeof(CDirEntry));
+            if (FAT32CDirFill(tmpde,&buf[cur_dir_entry],
+                  dv->fat32_local_time_offset)) {
+              tmpde->parent=parent;
+              if (Bt(&fuf_flags,FUf_RECURSE) && attr&RS_ATTR_DIR &&
+                    *tmpde->name!='.') {
+                tmpde->next=res;
+                res=tmpde;
+                tmpde->full_name=DirNameAbs(tmpde->name);
+                DrvUnlock(dv);
+                if (Cd(tmpde->name)) {
+                  tmpde->sub=FAT32FilesFind(files_find_mask,fuf_flags,
+                        tmpde,&sub_dir_size);
+                  tmpde->size=sub_dir_size;
+                  Cd("..");
+                }
+                DrvLock(dv);
+              } else {
+                tmpde->full_name=FileNameAbs(tmpde->name);
+                if ((attr&RS_ATTR_DIR || !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
+                      !(Bt(&fuf_flags,FUf_RECURSE) &&
+                      *tmpde->name=='.' && attr&RS_ATTR_DIR) &&
+                      FilesFindMatch(tmpde->full_name,files_find_mask,
+                      fuf_flags)) {
+                  tmpde->next=res;
+                  res=tmpde;
+                } else
+                  DirEntryDel(tmpde);
+              }
+            } else
+              DirEntryDel(tmpde);
+          }
+          MemSet(&long_name,0,sizeof(CDirEntry));
+        }
+      } else
+        MemSet(&long_name,0,sizeof(CDirEntry));
+      if (++cur_dir_entry==entries_per_clus) {
+        cur_dir_clus=ClusNumNext(dv,cur_dir_clus);
+        if (cur_dir_clus==INVALID_CLUS)
+          break;
+        else {
+          ClusRead(dv,buf,cur_dir_clus,1);
+          dir_size+=dv->spc*BLK_SIZE;
+          cur_dir_entry=0;
+        }
+      }
+    }
+    Free(buf);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  if (_dir_size)
+    *_dir_size=dir_size;
+  return res;
+}
+
+Bool FAT32MkDir(CDrv *dv,U8 *cur_dir,U8 *name,I64 entry_cnt)
+{
+  I64 c,cur_dir_clus=Name2DirClus(dv,cur_dir),
+//Rough estimate of size
+        size=CeilU64((entry_cnt+2)<<FAT32_ENTRIES_BITS,dv->spc<<BLK_SIZE_BITS);
+  U8 *buf=CAlloc(size);
+  CDirEntry d_native;
+  CFAT32DirEntry *dFAT=buf;
+  Bool unlock_break;
+
+  try {
+    unlock_break=BreakLock;
+    c=FileWrite(name,buf,size,0,RS_ATTR_DIR);
+    MemSet(&d_native,0,sizeof(CDirEntry));
+    d_native.attr=RS_ATTR_DIR;
+    *d_native.name='.';
+    d_native.name[1]=0;
+    d_native.clus=c;
+    d_native.size=0;
+    d_native.datetime=Now;
+    FAT32DirFill(dFAT,&d_native,NULL,dv->fat32_local_time_offset);
+    dFAT++;
+
+    MemSet(&d_native,0,sizeof(CDirEntry));
+    d_native.attr=RS_ATTR_DIR;
+    *d_native.name='.';
+    d_native.name[1]='.';
+    d_native.name[2]=0;
+    d_native.clus=cur_dir_clus;
+    d_native.size=0;
+    d_native.datetime=Now;
+    FAT32DirFill(dFAT,&d_native,NULL,dv->fat32_local_time_offset);
+    ClusWrite(dv,buf,c,1);
+    Free(buf);
+    if (unlock_break)
+      BreakUnlock;
+  } catch
+    if (unlock_break)
+      BreakUnlock;
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/FileSysRedSea.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/FileSysRedSea.HC.HTML new file mode 100755 index 0000000..f7f1a61 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/FileSysRedSea.HC.HTML @@ -0,0 +1,666 @@ + + + + + + + + + + + +
+// See RedSea File System
+
+U0 RedSeaFreeFreeLst(CDrv *dv)
+{
+  CFreeLst *tmpf,*tmpf1;
+  Bool unlock;
+  try {
+    unlock=DrvLock(dv);
+    if (tmpf=dv->next_free) {
+      while (tmpf!=&dv->next_free) {
+        tmpf1=tmpf->next;
+        Free(tmpf);
+        tmpf=tmpf1;
+      }
+    }
+    dv->next_free=NULL;
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 RedSeaFreeLstBuild(CDrv *dv)
+{
+  Bool unlock;
+  CFreeLst *tmpf;
+  I64 i,first=dv->data_area,max_blk=dv->size+dv->drv_offset;
+  try {
+    unlock=DrvLock(dv);
+    if (dv->next_free)
+      RedSeaFreeFreeLst(dv);
+    QueInit(&dv->next_free);
+    while (first<max_blk) {
+      i=0;  //count free clus
+      while (first+i<max_blk) {
+        DrvFATBlkSet(dv,first+i);
+        if (Bt(dv->cur_fat_blk,(first+i-dv->data_area)&(BLK_SIZE<<3-1)))
+          break;
+        else
+          i++;
+      }
+      if (i) {
+        tmpf=AMAlloc(sizeof(CFreeLst));
+        tmpf->size=i;
+        tmpf->start=first;
+        QueIns(tmpf,dv->last_free);
+      }
+      first+=i+1;
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 RedSeaInit(CDrv *dv)
+{
+  CRedSeaBoot br;
+  Bool unlock;
+  try {
+    unlock=DrvLock(dv);
+    BlkRead(dv,&br,dv->drv_offset,1);
+    if (br.signature!=MBR_PT_REDSEA || br.signature2!=0xAA55)
+      throw('Drv');
+    dv->fs_type=FSt_REDSEA;
+    RedSeaFreeFreeLst(dv);
+    dv->spc=1;
+    dv->size=br.sects;
+    dv->data_area=dv->drv_offset+br.bitmap_sects;
+    dv->root_clus=br.root_clus;
+    dv->fat1=dv->fat2=dv->drv_offset+1;
+    DrvFATBlkAlloc(dv);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+Bool RedSeaValidate(U8 drv_let)
+{
+  CDrv *dv;
+  CRedSeaBoot br;
+  if ((dv=Let2Drv(drv_let,FALSE)) && dv->fs_type==FSt_REDSEA &&
+        BlkRead(dv,&br,dv->drv_offset,1) && br.signature==MBR_PT_REDSEA &&
+        br.signature2==0xAA55)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 RedSeaFmt(U8 drv_let,Bool quick=TRUE)
+{
+  U8 *root_dir;
+  CDirEntry *d_native;
+  CRedSeaBoot *br=CAlloc(BLK_SIZE);
+  CDrv *dv=Let2Drv(drv_let);
+  I64 i,n,root_dir_blks;
+  try {
+    DrvLock(dv);
+//      DrvTypeSet(drv_let,FSt_REDSEA);
+    DrvTypeSet(drv_let,FSt_FAT32);
+    dv->fs_type=FSt_REDSEA;
+    br->signature=MBR_PT_REDSEA;
+    br->signature2=0xAA55;
+    br->drv_offset=dv->drv_offset; //For CD/DVD image copy.
+    br->sects=dv->size;
+    n=(br->sects+BLK_SIZE<<3-1)/BLK_SIZE<<3;
+    br->bitmap_sects=n;
+    br->unique_id=GetTSC^Now()(U64);
+    br->root_clus=0;
+
+    if (quick)
+      i=n+1;
+    else
+      i=dv->size;
+    BlkWriteZero(dv,dv->drv_offset,i);
+
+    BlkWrite(dv,br,dv->drv_offset,1);
+    RedSeaInit(dv);
+    ClusAlloc(dv,0,1,FALSE);    //Alloc #1
+
+    root_dir_blks=MaxI64(1,dv->bd->init_root_dir_blks);
+    br->root_clus=ClusAlloc(dv,0,root_dir_blks,FALSE);
+    BlkWrite(dv,br,dv->drv_offset,1);
+    root_dir=CAlloc(BLK_SIZE*root_dir_blks);
+
+    d_native=root_dir-offset(CDirEntry.start);
+
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    *d_native->name='.';
+    d_native->clus=br->root_clus;
+    d_native->size=BLK_SIZE*root_dir_blks;
+    d_native->datetime=Now;
+
+    d_native(U8 *)+=CDIR_SIZE;
+
+    *d_native->name='.';
+    d_native->name[1]='.';
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    d_native->clus=br->root_clus;
+    d_native->datetime=Now;
+
+    BlkWrite(dv,root_dir,br->root_clus,root_dir_blks);
+    RedSeaInit(dv);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  Free(br);
+  Free(root_dir);
+}
+
+Bool RedSeaFileFind(CDrv *dv,I64 cur_dir_clus,U8 *name,
+        CDirEntry *_res,I64 fuf_flags=0)
+{//FUF_JUST_DIRS, FUF_JUST_FILES
+  CDirEntry *buf,*buf2,*ptr;
+  U8 dname[CDIR_FILENAME_LEN];
+  I64 ch;
+  Bool res=FALSE,unlock;
+  if (fuf_flags&~FUG_FILE_FIND)
+    throw('FUF');
+  MemSet(_res,0,sizeof(CDirEntry));
+  DrvChk(dv);
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else if (!CFileNameTo(dname,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else
+    try {
+      unlock=DrvLock(dv);
+      buf2=MAlloc(BLK_SIZE);
+      BlkRead(dv,buf2,cur_dir_clus,1);
+
+      ptr=buf2(U8 *)-offset(CDirEntry.start);
+      buf=MAlloc(ptr->size);
+      BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+      Free(buf2);
+
+      ptr=buf(U8 *)-offset(CDirEntry.start);
+      *ptr->name='.';
+      ptr->name[1]=0;
+      while (TRUE) {
+        if (!(ch=*ptr->name))
+          break;
+        else if (!(ptr->attr & RS_ATTR_DELETED) &&
+              !(fuf_flags&FUF_JUST_DIRS && !(ptr->attr & RS_ATTR_DIR)) &&
+              !(fuf_flags&FUF_JUST_FILES && ptr->attr & RS_ATTR_DIR) &&
+              !StrCmp(dname,ptr->name)) {
+          MemCpy(&_res->attr,&ptr->attr,CDIR_SIZE);
+          res=TRUE;
+          goto rsff_done;
+        }
+        ptr(U8 *)+=CDIR_SIZE;
+      }
+rsff_done:
+      Free(buf);
+      if (unlock)
+        DrvUnlock(dv);
+    } catch
+      if (unlock)
+        DrvUnlock(dv);
+  return res;
+}
+
+U8 *RedSeaFileRead(CDrv *dv,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
+{
+  U8 *buf=NULL;
+  CDirEntry de;
+  I64 c,blk_cnt,cur_dir_clus;
+  DrvChk(dv);
+  *_size=0;
+  *_attr=0;
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else
+    try {
+      DrvLock(dv);
+      cur_dir_clus=Name2DirClus(dv,cur_dir);
+      if (RedSeaFileFind(dv,cur_dir_clus,filename,&de,FUF_JUST_FILES)) {
+        blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+        buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
+        c=de.clus;
+        c=BlkRead(dv,buf,c,blk_cnt);
+        buf[de.size]=0; //Terminate
+        *_size=de.size;
+        *_attr=FileAttr(de.name,de.attr);
+      }
+      DrvUnlock(dv);
+    } catch
+      DrvUnlock(dv);
+  return buf;
+}
+
+Bool RedSeaCd(U8 *name,I64 cur_dir_clus)
+{
+  CDirEntry de;
+  if (Fs->cur_dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else if (RedSeaFileFind(Fs->cur_dv,cur_dir_clus,name,&de,FUF_JUST_DIRS))
+    return TRUE;
+  else
+    PrintErr("File not found: \"%s\".\n",name);
+  return FALSE;
+}
+
+U0 RedSeaFreeClus(CDrv *dv,I64 c,I64 cnt)
+{
+  CFreeLst *tmpf;
+  Bool found=FALSE,unlock,unlock_break;
+  DrvChk(dv);
+  if (!c) return;
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else
+    try {
+      unlock_break=BreakLock;
+      unlock=DrvLock(dv);
+      if (!dv->next_free)
+        RedSeaFreeLstBuild(dv);
+      tmpf=dv->next_free;
+      while (!found && tmpf!=&dv->next_free) {
+        if (tmpf->start+tmpf->size==c) {
+          tmpf->size+=cnt;
+          found=TRUE;
+        } else if (c+cnt==tmpf->start) {
+          tmpf->size+=cnt;
+          tmpf->start=c;
+          found=TRUE;
+        }
+        tmpf=tmpf->next;
+      }
+      if (!found) {
+        tmpf=AMAlloc(sizeof(CFreeLst));
+        tmpf->size=cnt;
+        tmpf->start=c;
+        QueIns(tmpf,dv->last_free);
+      }
+      while (cnt-->0) {
+        DrvFATBlkSet(dv,c);
+        LBtr(dv->cur_fat_blk,(c-dv->data_area)&(BLK_SIZE<<3-1));
+        LBts(&dv->fat_blk_dirty,0);
+        c++;
+      }
+      DrvFATBlkClean(dv);
+
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    } catch {
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    }
+}
+
+I64 RedSeaAllocClus(CDrv *dv,I64 cnt)
+{
+  CFreeLst *tmpf,*best_free=NULL;
+  I64 i,first,best_size=I64_MAX;
+  Bool unlock,unlock_break;
+  if (cnt<=0)
+    throw('Drv');
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    if (!dv->next_free)
+      RedSeaFreeLstBuild(dv);
+    tmpf=dv->next_free;
+    while (tmpf!=&dv->next_free) {
+      if (tmpf->size>=cnt && tmpf->size<best_size) {
+        best_free=tmpf;
+        best_size=tmpf->size;
+        if (tmpf->size==cnt)
+          break;
+      }
+      tmpf=tmpf->next;
+    }
+    if (!best_free)
+      throw('Drv');
+    first=best_free->start;
+    for (i=0;i<cnt;i++) {
+      DrvFATBlkSet(dv,first+i);
+      LBts(dv->cur_fat_blk,(first+i-dv->data_area)&(BLK_SIZE<<3-1));
+      LBts(&dv->fat_blk_dirty,0);
+    }
+    DrvFATBlkClean(dv);
+    if (best_free->size-=cnt)
+      best_free->start+=cnt;
+    else {
+      QueRem(best_free);
+      Free(best_free);
+    }
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return first;
+}
+
+Bool RedSeaDirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain)
+{
+  CDirEntry *buf,*buf2,*ptr,de2;
+  CRedSeaBoot *br;
+  I64 c,ch,i=1,j=0,n=BLK_SIZE/CDIR_SIZE,dir_size,cur_dir_clus;
+  Bool written=FALSE,unlock,unlock_break;
+  U8 *tmp,*parent_dir;
+  try {
+    unlock_break=BreakLock;
+    tmpde->attr|=RS_ATTR_CONTIGUOUS;
+    unlock=DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf2=MAlloc(BLK_SIZE);
+    BlkRead(dv,buf2,cur_dir_clus,1);
+
+    ptr=buf2(U8 *)-offset(CDirEntry.start);
+    buf=MAlloc(ptr->size);
+    BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+
+    dir_size=ptr->size;
+    ptr=buf(U8 *)-offset(CDirEntry.start)+CDIR_SIZE;
+    Free(buf2);
+    while (TRUE) {
+      if (!(ch=*ptr->name)) {
+        if (!written)
+          MemCpy(&ptr->start,&tmpde->start,CDIR_SIZE);
+        if ((i+1)*CDIR_SIZE+j<<BLK_SIZE_BITS<dir_size)
+          BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+        else {
+          buf2=CAlloc(dir_size+BLK_SIZE);
+          MemCpy(buf2,buf,dir_size);
+          RedSeaFreeClus(dv,cur_dir_clus,dir_size>>BLK_SIZE_BITS);
+          dir_size+=BLK_SIZE;
+          c=ClusAlloc(dv,0,dir_size>>BLK_SIZE_BITS,TRUE);
+          Free(buf);
+          buf=buf2;
+          ptr=buf(U8 *)-offset(CDirEntry.start);
+          ptr->size=dir_size;
+          ptr->clus=c;
+          BlkWrite(dv,buf,c,dir_size>>BLK_SIZE_BITS);
+          if (cur_dir_clus==dv->root_clus) {
+            br=CAlloc(BLK_SIZE);
+            BlkRead(dv,br,dv->drv_offset,1);
+            br->root_clus=c;
+            BlkWrite(dv,br,dv->drv_offset,1);
+            Free(br);
+            dv->root_clus=c;
+          } else {
+            tmp=StrNew(cur_dir);
+            parent_dir=StrNew(cur_dir);
+            StrLastRem(parent_dir,"/",tmp);
+            if (!*parent_dir) {
+              Free(parent_dir);
+              parent_dir=StrNew("/");
+            }
+            if (RedSeaFileFind(dv,Name2DirClus(dv,parent_dir),
+                  tmp,&de2,FUF_JUST_DIRS)) {
+              de2.clus=c;
+              de2.size=dir_size;
+              RedSeaDirNew(dv,parent_dir,&de2,FALSE);
+            } else
+              throw('Drv');
+            Free(tmp);
+            Free(parent_dir);
+          }
+        }
+        break;
+      } else if (ptr->attr & RS_ATTR_DELETED) {
+        if (!written) {
+          MemCpy(&ptr->start,&tmpde->start,CDIR_SIZE);
+          BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+          written=TRUE;
+        }
+      } else {
+        if (!StrCmp(tmpde->name,ptr->name)) {
+          if (free_old_chain)
+            RedSeaFreeClus(dv,ptr->clus,
+                  (ptr->size+BLK_SIZE-1)>>BLK_SIZE_BITS);
+          if (!written)
+            MemCpy(&ptr->start,&tmpde->start,CDIR_SIZE);
+          else
+            ptr->attr|=RS_ATTR_DELETED;
+          BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+          break;
+        }
+      }
+      ptr(U8 *)+=CDIR_SIZE;
+      if (++i>=n) {
+        j++;
+        i=0;
+      }
+    }
+    Free(buf);
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return FALSE;
+}
+
+I64 RedSeaFilesDel(CDrv *dv,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
+                     Bool del_dir,Bool print_msg)
+{
+  CDirEntry *buf,*buf2,*ptr;
+  I64 i=0,res=0,ch,j=0,n=BLK_SIZE/CDIR_SIZE,cur_dir_clus;
+  Bool unlock_break;
+  try {
+    unlock_break=BreakLock;
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf2=MAlloc(BLK_SIZE);
+    BlkRead(dv,buf2,cur_dir_clus,1);
+
+    ptr=buf2(U8 *)-offset(CDirEntry.start);
+    buf=MAlloc(ptr->size);
+    BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+    Free(buf2);
+
+    ptr=buf(U8 *)-offset(CDirEntry.start);
+    *ptr->name='.';
+    ptr->name[1]=0;
+    while (TRUE) {
+      if (!(ch=*ptr->name))
+        break;
+      else if (!(ptr->attr & RS_ATTR_DELETED) && ch!='.' && (del_dir ||
+            !(ptr->attr & RS_ATTR_DIR)) &&
+            FilesFindMatch(ptr->name,files_find_mask,fuf_flags)) {
+        if (!(ptr->attr & RS_ATTR_DIR)) res++;
+        if (print_msg)
+          "Del %s\n",ptr->name;
+        ptr->attr|=RS_ATTR_DELETED;
+        BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+        RedSeaFreeClus(dv,ptr->clus,
+              (ptr->size+BLK_SIZE-1)>>BLK_SIZE_BITS);
+      }
+      ptr(U8 *)+=CDIR_SIZE;
+      if (++i>=n) {
+        j++;
+        i=0;
+      }
+    }
+    Free(buf);
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return res;
+}
+
+I64 RedSeaFileWrite(CDrv *dv,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
+        CDate cdt,I64 attr)
+{
+  CDirEntry de;
+  I64 c=0,blk_cnt;
+  MemSet(&de,0,sizeof(CDirEntry));
+  if (size<0) size=0;
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else if (!CFileNameTo(de.name,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else {
+    RedSeaFilesDel(dv,cur_dir,de.name,0,FALSE,FALSE);
+    de.size=size;
+    if (blk_cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS)
+      c=ClusAlloc(dv,0,blk_cnt,TRUE); //Always contiguous
+    else
+      c=INVALID_CLUS;
+    de.clus=c;
+    de.attr=attr|RS_ATTR_CONTIGUOUS;
+    de.datetime=cdt;
+    if (blk_cnt)
+      BlkWrite(dv,buf,c,blk_cnt);
+    RedSeaDirNew(dv,cur_dir,&de,TRUE);
+  }
+  return c;
+}
+
+CDirEntry *RedSeaFilesFind(U8 *files_find_mask,I64 fuf_flags,
+        CDirEntry *parent=NULL)
+{
+  CDrv *dv=Fs->cur_dv;
+  CDirEntry *buf,*buf2,*ptr,*res=NULL,*tmpde;
+  I64 ch,cur_dir_clus;
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+  try {
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,Fs->cur_dir);
+    buf2=MAlloc(BLK_SIZE);
+    BlkRead(dv,buf2,cur_dir_clus,1);
+
+    ptr=buf2(U8 *)-offset(CDirEntry.start);
+    buf=MAlloc(ptr->size);
+    BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+    Free(buf2);
+
+    ptr=buf(U8 *)-offset(CDirEntry.start);
+    *ptr->name='.';
+    ptr->name[1]=0;
+    ptr(U8 *)+=CDIR_SIZE;
+    ptr->clus=Name2ParentDirClus(dv,Fs->cur_dir);
+    ptr(U8 *)-=CDIR_SIZE;
+    while (TRUE) {
+      if (!(ch=*ptr->name))
+        break;
+      else if (!(ptr->attr & RS_ATTR_DELETED)) {
+        tmpde=CAlloc(sizeof(CDirEntry));
+        MemCpy(&tmpde->start,&ptr->start,CDIR_SIZE);
+        tmpde->parent=parent;
+        if (Bt(&fuf_flags,FUf_RECURSE) && tmpde->attr&RS_ATTR_DIR &&
+              *tmpde->name!='.') {
+          tmpde->next=res;
+          res=tmpde;
+          tmpde->full_name=DirNameAbs(tmpde->name);
+          DrvUnlock(dv);
+          if (Cd(tmpde->name)) {
+            tmpde->sub=RedSeaFilesFind(files_find_mask,fuf_flags,tmpde);
+            Cd("..");
+          }
+          DrvLock(dv);
+        } else {
+          tmpde->full_name=FileNameAbs(tmpde->name);
+          if ((tmpde->attr&RS_ATTR_DIR ||
+                !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
+                !(Bt(&fuf_flags,FUf_RECURSE) && *tmpde->name=='.' &&
+                tmpde->attr&RS_ATTR_DIR) &&
+                FilesFindMatch(tmpde->full_name,files_find_mask,fuf_flags)) {
+            tmpde->next=res;
+            res=tmpde;
+          } else
+            DirEntryDel(tmpde);
+        }
+      }
+      ptr(U8 *)+=CDIR_SIZE;
+    }
+    Free(buf);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  return res;
+}
+
+Bool RedSeaMkDir(CDrv *dv,U8 *cur_dir,U8 *name,I64 entry_cnt)
+{//entry_cnt is for preallocating dir blks.
+  I64   c,cur_dir_clus=Name2DirClus(dv,cur_dir),
+        size=CeilU64((entry_cnt+3)<<6,BLK_SIZE);
+#assert CDIR_SIZE==64
+  U8 *buf=CAlloc(size);
+  CDirEntry *d_native=buf-offset(CDirEntry.start);
+  Bool unlock_break;
+  try {
+    unlock_break=BreakLock;
+    c=FileWrite(name,buf,size,0,RS_ATTR_DIR);
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    StrCpy(d_native->name,name);
+    d_native->clus=c;
+    d_native->size=size;
+    d_native->datetime=Now;
+    d_native(U8 *)+=CDIR_SIZE;
+
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    *d_native->name='.';
+    d_native->name[1]='.';
+    d_native->name[2]=0;
+    d_native->clus=cur_dir_clus;
+    d_native->size=0;
+    d_native->datetime=Now;
+    BlkWrite(dv,buf,c,1);
+    Free(buf);
+    if (unlock_break)
+      BreakUnlock;
+  } catch
+    if (unlock_break)
+      BreakUnlock;
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/BlkDev/MakeBlkDev.HC.HTML b/public/Wb/Home/Src/Kernel/BlkDev/MakeBlkDev.HC.HTML new file mode 100755 index 0000000..9b46f62 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/BlkDev/MakeBlkDev.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+#exe {Cd(__DIR__);};
+#include "DskStrA"
+#include "DskCache"
+#include "DskATA"
+#include "DskATAId"
+#include "DskBlkDev"
+#include "DskDrv"
+#include "DskBlk"
+#include "DskClus"
+#include "DskStrB"
+#include "DskAddDev"
+#include "DskDirA"
+#include "FileSysRedSea"
+#include "FileSysFAT"
+#include "DskDirContext"
+#include "DskFind"
+#include "DskDirB"
+#include "DskFile"
+#include "DskCFile"
+#include "DskCopy"
+#include "DskCDDVD"
+#include "DskFmt"
+#exe {Cd("..");};
+
+ diff --git a/public/Wb/Home/Src/Kernel/Compress.HC.HTML b/public/Wb/Home/Src/Kernel/Compress.HC.HTML new file mode 100755 index 0000000..0ace222 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Compress.HC.HTML @@ -0,0 +1,339 @@ + + + + + + + + + + + +
+//See ::/Doc/Credits.DD.
+//See CArcCompress, CArcEntry, and CArcCtrl
+
+asm {
+/****
+U0 ArcEntryGet(CArcCtrl *c)
+{
+  I64 i;
+  CArcEntry *tmp,*tmp1;
+
+  if (c->entry_used) {
+    i=c->free_idx;
+
+    c->entry_used=FALSE;
+    c->cur_entry=c->next_entry;
+    c->cur_bits_in_use=c->next_bits_in_use;
+    if (c->next_bits_in_use<ARC_BITS_MAX) {
+      c->next_entry = &c->compress[i++];
+      if (i==c->free_limit) {
+        c->next_bits_in_use++;
+        c->free_limit=1<<c->next_bits_in_use;
+      }
+    } else {
+      do if (++i==c->free_limit)
+          i=c->min_table_entry;
+      while (c->hash[i]);
+      tmp=&c->compress[i];
+      c->next_entry=tmp;
+      tmp1=&c->hash[tmp->basecode];
+      while (tmp1) {
+        if (tmp1->next==tmp) {
+          tmp1->next=tmp->next;
+          break;
+        } else
+          tmp1=tmp1->next;
+      }
+    }
+    c->free_idx=i;
+  }
+}
+****/
+_ARC_ENTRY_GET::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        BTR     U64 CArcCtrl.entry_used[RSI],0
+        JNC     I32 @@30
+        MOV     RDX,U64 CArcCtrl.free_idx[RSI]
+        MOV     RAX,U64 CArcCtrl.next_entry[RSI]
+        MOV     U64 CArcCtrl.cur_entry[RSI],RAX
+        MOV     RCX,U64 CArcCtrl.next_bits_in_use[RSI]
+        MOV     U64 CArcCtrl.cur_bits_in_use[RSI],RCX
+        CMP     RCX,ARC_BITS_MAX
+        JAE     @@05
+        MOV     RAX,RDX
+        SHL     RAX,4
+        LEA     RAX,U64 CArcCtrl.compress[RSI+RAX]
+        MOV     U64 CArcCtrl.next_entry[RSI],RAX
+        INC     RDX
+        CMP     U64 CArcCtrl.free_limit[RSI],RDX
+        JNE     @@25
+        INC     RCX
+        MOV     U64 CArcCtrl.next_bits_in_use[RSI],RCX
+        MOV     RAX,1
+        SHL     RAX,CL
+        MOV     U64 CArcCtrl.free_limit[RSI],RAX
+        JMP     @@25
+@@05:   INC     RDX
+        CMP     U64 CArcCtrl.free_limit[RSI],RDX
+        JNE     @@10
+        MOV     RDX,U64 CArcCtrl.min_table_entry[RSI]
+@@10:   MOV     RAX,U64 CArcCtrl.hash[RSI+RDX*8]
+        TEST    RAX,RAX
+        JNZ     @@05
+        MOV     RDI,RDX
+        SHL     RDI,4
+        LEA     RDI,U64 CArcCtrl.compress[RSI+RDI]
+        MOV     U32 CArcCtrl.next_entry[RSI],EDI
+        MOVZX   RBX,U16 CArcEntry.basecode[RDI]
+        LEA     RCX,U64 CArcCtrl.hash[RSI+RBX*8]
+@@15:   TEST    RCX,RCX
+        JZ      @@25
+        MOV     RAX,U64 CArcEntry.next[RCX]
+        CMP     RDI,RAX
+        JNE     @@20
+        MOV     RAX,U64 CArcEntry.next[RDI]
+        MOV     U64 CArcEntry.next[RCX],RAX
+        JMP     @@25
+@@20:   MOV     RCX,RAX
+        JMP     @@15
+@@25:   MOV     U64 CArcCtrl.free_idx[RSI],RDX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    8
+}
+
+_extern _ARC_ENTRY_GET U0 ArcEntryGet(CArcCtrl *c);
+
+I64 ArcDetermineCompressionType(U8 *src,I64 size)
+{
+  while (size--)
+    if (*src++&0x80)
+      return CT_8_BIT;
+  return CT_7_BIT;
+}
+
+U0 ArcCompressBuf(CArcCtrl *c)
+{//Use CompressBuf() unless doing more than one buf.
+  CArcEntry *tmp,*tmp1;
+  I64 ch,basecode;
+  U8 *src_ptr,*src_limit;
+
+  src_ptr=c->src_buf+c->src_pos;
+  src_limit=c->src_buf+c->src_size;
+
+  if (c->saved_basecode==U32_MAX)
+    basecode=*src_ptr++;
+  else
+    basecode=c->saved_basecode;
+
+  while (src_ptr<src_limit && c->dst_pos+c->cur_bits_in_use<=c->dst_size) {
+    ArcEntryGet(c);
+ac_start:
+    if (src_ptr>=src_limit) goto ac_done;
+    ch=*src_ptr++;
+    if (tmp=c->hash[basecode])
+      do {
+        if (tmp->ch==ch) {
+          basecode=tmp-&c->compress[0];
+          goto ac_start;
+        }
+      } while (tmp=tmp->next);
+
+    BFieldOrU32(c->dst_buf,c->dst_pos,basecode);
+    c->dst_pos+=c->cur_bits_in_use;
+
+    c->entry_used=TRUE;
+    tmp=c->cur_entry;
+    tmp->basecode=basecode;
+    tmp->ch=ch;
+    tmp1=&c->hash[basecode];
+    tmp->next=tmp1->next;
+    tmp1->next=tmp;
+
+    basecode=ch;
+  }
+ac_done:
+  c->saved_basecode=basecode;
+  c->src_pos=src_ptr-c->src_buf;
+}
+
+Bool ArcFinishCompression(CArcCtrl *c)
+{//Do closing touch on archivew ctrl struct.
+  if (c->dst_pos+c->cur_bits_in_use<=c->dst_size) {
+    BFieldOrU32(c->dst_buf,c->dst_pos,c->saved_basecode);
+    c->dst_pos+=c->next_bits_in_use;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 ArcExpandBuf(CArcCtrl *c)
+{//Use ExpandBuf() unless you know what you're doing.
+  U8 *dst_ptr,*dst_limit;
+  I64 basecode,lastcode,code;
+  CArcEntry *tmp,*tmp1;
+
+  dst_ptr=c->dst_buf+c->dst_pos;
+  dst_limit=c->dst_buf+c->dst_size;
+
+  while (dst_ptr<dst_limit && c->stk_ptr!=c->stk_base)
+    *dst_ptr++ = * -- c->stk_ptr;
+
+  if (c->stk_ptr==c->stk_base && dst_ptr<dst_limit) {
+    if (c->saved_basecode==U32_MAX) {
+      lastcode=BFieldExtU32(c->src_buf,c->src_pos,
+            c->next_bits_in_use);
+      c->src_pos+=c->next_bits_in_use;
+      *dst_ptr++=lastcode;
+      ArcEntryGet(c);
+      c->last_ch=lastcode;
+    } else
+      lastcode=c->saved_basecode;
+    while (dst_ptr<dst_limit && c->src_pos+c->next_bits_in_use<=c->src_size) {
+      basecode=BFieldExtU32(c->src_buf,c->src_pos,
+            c->next_bits_in_use);
+      c->src_pos+=c->next_bits_in_use;
+      if (c->cur_entry==&c->compress[basecode]) {
+        *c->stk_ptr++=c->last_ch;
+        code=lastcode;
+      } else
+        code=basecode;
+      while (code>=c->min_table_entry) {
+        *c->stk_ptr++=c->compress[code].ch;
+        code=c->compress[code].basecode;
+      }
+      *c->stk_ptr++=code;
+      c->last_ch=code;
+
+      c->entry_used=TRUE;
+      tmp=c->cur_entry;
+      tmp->basecode=lastcode;
+      tmp->ch=c->last_ch;
+      tmp1=&c->hash[lastcode];
+      tmp->next=tmp1->next;
+      tmp1->next=tmp;
+
+      ArcEntryGet(c);
+      while (dst_ptr<dst_limit && c->stk_ptr!=c->stk_base)
+        *dst_ptr++ = * -- c->stk_ptr;
+      lastcode=basecode;
+    }
+    c->saved_basecode=lastcode;
+  }
+  c->dst_pos=dst_ptr-c->dst_buf;
+}
+
+CArcCtrl *ArcCtrlNew(Bool expand,I64 compression_type=CT_8_BIT)
+{//MAlloc archive ctrl struct.
+  CArcCtrl *c;
+  c=CAlloc(sizeof(CArcCtrl));
+  if (expand) {
+    c->stk_base=MAlloc(1<<ARC_BITS_MAX);
+    c->stk_ptr=c->stk_base;
+  }
+  if (compression_type==CT_7_BIT)
+    c->min_bits=7;
+  else
+    c->min_bits=8;
+  c->min_table_entry=1<<c->min_bits;
+  c->free_idx=c->min_table_entry;
+  c->next_bits_in_use=c->min_bits+1;
+  c->free_limit=1<<c->next_bits_in_use;
+  c->saved_basecode=U32_MAX;
+  c->entry_used=TRUE;
+  ArcEntryGet(c);
+  c->entry_used=TRUE;
+  return c;
+}
+
+U0 ArcCtrlDel(CArcCtrl *c)
+{//Free archive ctrl struct.
+  Free(c->stk_base);
+  Free(c);
+}
+
+U8 *ExpandBuf(CArcCompress *arc,CTask *mem_task=NULL)
+{//See ::/Demo/Dsk/SerializeTree.HC.
+  CArcCtrl *c;
+  U8 *res;
+
+  if (!(CT_NONE<=arc->compression_type<=CT_8_BIT) ||
+        arc->expanded_size>mem_mapped_space)
+    throw('Compress');
+
+  res=MAlloc(arc->expanded_size+1,mem_task);
+  res[arc->expanded_size]=0; //terminate
+  switch [arc->compression_type] {
+    case CT_NONE:
+      MemCpy(res,&arc->body,arc->expanded_size);
+      break;
+    case CT_7_BIT:
+    case CT_8_BIT:
+      c=ArcCtrlNew(TRUE,arc->compression_type);
+      c->src_size=arc->compressed_size<<3;
+      c->src_pos=sizeof(CArcCompress)<<3;
+      c->src_buf=arc;
+      c->dst_size=arc->expanded_size;
+      c->dst_buf=res;
+      c->dst_pos=0;
+      ArcExpandBuf(c);
+      ArcCtrlDel(c);
+      break;
+  }
+  return res;
+}
+
+CArcCompress *CompressBuf(U8 *src,I64 size,CTask *mem_task=NULL)
+{//See ::/Demo/Dsk/SerializeTree.HC.
+  CArcCompress *arc;
+  I64 size_out,compression_type=ArcDetermineCompressionType(src,size);
+  CArcCtrl *c=ArcCtrlNew(FALSE,compression_type);
+  c->src_size=size;
+  c->src_buf=src;
+  c->dst_size=(size+sizeof(CArcCompress))<<3;
+  c->dst_buf=CAlloc(c->dst_size>>3);
+  c->dst_pos=sizeof(CArcCompress)<<3;
+  ArcCompressBuf(c);
+  if (ArcFinishCompression(c) && c->src_pos==c->src_size) {
+    size_out=(c->dst_pos+7)>>3;
+    arc=MAlloc(size_out,mem_task);
+    MemCpy(arc,c->dst_buf,size_out);
+    arc->compression_type=compression_type;
+    arc->compressed_size=size_out;
+  } else {
+    arc=MAlloc(size+sizeof(CArcCompress),mem_task);
+    MemCpy(&arc->body,src,size);
+    arc->compression_type=CT_NONE;
+    arc->compressed_size=size+sizeof(CArcCompress);
+  }
+  arc->expanded_size=size;
+  Free(c->dst_buf);
+  ArcCtrlDel(c);
+  return arc;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Display.HC.HTML b/public/Wb/Home/Src/Kernel/Display.HC.HTML new file mode 100755 index 0000000..8d0760f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Display.HC.HTML @@ -0,0 +1,152 @@ + + + + + + + + + + + +
+U0 RawPutChar(I64 ch)
+{/*For RAW output during boot and in debugger.
+
+See GrUpdateTextFG for
+the normal scrn text output routine.
+
+See also GrUpdateScrn().
+*/
+  I64 i,row,col;
+  U8 *ptr,*ptr1,*ptr2;
+
+  if (!(text.raw_flags&RWF_SHOW_DOLLAR)) {
+    if (ch=='$') {
+      if (text.raw_flags&RWF_IN_DOLLAR) {
+        text.raw_flags&=~RWF_IN_DOLLAR;
+        if (!(text.raw_flags & RWF_LAST_DOLLAR)) {
+          text.raw_flags&=~RWF_LAST_DOLLAR;
+          return;
+        }
+      } else {
+        text.raw_flags|=RWF_IN_DOLLAR|RWF_LAST_DOLLAR;
+        return;
+      }
+    }
+    text.raw_flags&=~RWF_LAST_DOLLAR;
+    if (text.raw_flags&RWF_IN_DOLLAR)
+      return;
+  }
+  if (ch=='\t') {
+    RawPutChar(CH_SPACE);
+    while (text.raw_col & 7)
+      RawPutChar(CH_SPACE);
+  } else if (ch==CH_BACKSPACE) {
+    text.raw_col--;
+    RawPutChar(CH_SPACE);
+    text.raw_col--;
+  } else if (ch=='\n') {
+    RawPutChar(CH_SPACE);
+    while (text.raw_col % text.cols)
+      RawPutChar(CH_SPACE);
+
+  } else if (Bt(char_bmp_displayable,ch)) {
+    row=text.raw_col/text.cols%text.rows;
+    col=text.raw_col%text.cols;
+    if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
+      if (text.raw_flags&RWF_SCROLL && text.raw_col && !row && !col) {
+        MemCpy(text.vga_text_alias,text.vga_text_alias+text.cols*2,
+              text.cols*(text.rows-1)*2);
+        MemSet(text.vga_text_alias+text.cols*(text.rows-1)*2,0,text.cols*2);
+        text.raw_col-=text.cols;
+        row=text.rows-1;
+      }
+      ptr=text.vga_text_alias+(row*text.cols+col)*2;
+      ptr[0]=ch;
+      ptr[1]=BLACK<<4+WHITE;
+    } else {
+      OutU8(VGAP_IDX,VGAR_MAP_MASK);
+      OutU8(VGAP_DATA,0x0F); //All planes -- WHITE
+      if (text.raw_flags&RWF_SCROLL && text.raw_col && !row && !col) {
+//Scroll cached image
+        MemCpy(text.raw_scrn_image,
+              text.raw_scrn_image+GR_WIDTH*FONT_HEIGHT>>3,
+              GR_WIDTH*(GR_HEIGHT-FONT_HEIGHT)>>3);
+        MemSet(text.raw_scrn_image+GR_WIDTH*(GR_HEIGHT-FONT_HEIGHT)>>3,0,
+              GR_WIDTH*FONT_HEIGHT>>3);
+
+        MemCpy(text.vga_alias,text.raw_scrn_image,GR_WIDTH*GR_HEIGHT>>3);
+        text.raw_col-=text.cols;
+        row=text.rows-1;
+      }
+      PUSHFD
+      CLI
+      ptr=ptr1=col+row*GR_WIDTH*FONT_HEIGHT>>3;
+      ptr+=text.vga_alias;
+      ptr1+=text.raw_scrn_image; //Write to cached image as well
+      ptr2=&text.font[ch&255];
+      for (i=0;i<FONT_HEIGHT;i++) {
+        *ptr=*ptr1=rev_bits_table[*ptr2++];
+        ptr+=GR_WIDTH>>3;
+        ptr1+=GR_WIDTH>>3;
+      }
+      POPFD
+    }
+    text.raw_col++;
+  }
+}
+
+U0 VGAFlush()
+{//Flush winmgr vga cache, so updates whole scrn.
+  LBts(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0);
+}
+
+U0 WinDerivedValsUpdate(CTask *task)
+{//Those things calculated from other variables.
+  if (!task) task=Fs;
+  //Assert: This is called with TASKf_TASK_LOCK set
+  PUSHFD
+  CLI
+  task->win_width =task->win_right-task->win_left+1;
+  task->win_height=task->win_bottom-task->win_top+1;
+  task->pix_left        =FONT_WIDTH*task->win_left;
+  task->pix_right       =FONT_WIDTH*(task->win_right+1)-1;
+  task->pix_width       =task->pix_right-task->pix_left+1;
+  task->pix_top         =FONT_HEIGHT*task->win_top;
+  task->pix_bottom      =FONT_HEIGHT*(task->win_bottom+1)-1;
+  task->pix_height      =task->pix_bottom-task->pix_top+1;
+  POPFD
+}
+
+Bool WinInside(I64 x,I64 y,CTask *task=NULL,I64 border=0)
+{//Is pixel (x,y) inside task's win? Border to FONT_WIDTH.
+  if (!task) task=Fs;
+  if (TaskValidate(task) && Bt(&task->display_flags,DISPLAYf_SHOW)) {
+    if (Bt(&task->display_flags,DISPLAYf_NO_BORDER))
+      border=0;
+    if (task->pix_left-border<=x<=task->pix_right+border &&
+          task->pix_top-border<=y<=task->pix_bottom+border)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/EdLite.HC.HTML b/public/Wb/Home/Src/Kernel/EdLite.HC.HTML new file mode 100755 index 0000000..363821e --- /dev/null +++ b/public/Wb/Home/Src/Kernel/EdLite.HC.HTML @@ -0,0 +1,386 @@ + + + + + + + + + + + +
+class CLine
+{
+  CLine *next,*last;
+  U8 *line;
+};
+
+U0 EdLiteUpdate(CLine *head,CLine *cur_line,I64 cur_col,I64 line_start_col)
+{
+  I64 ch,i,j,k,k2,cursor_col,cursor_row=-1;
+  U8 *st;
+  CLine *tmpl=cur_line;
+  Bool done_eof=FALSE;
+  text.raw_col=0;
+  for (i=0;i<text.rows/2;i++)
+    if (tmpl->last!=head)
+      tmpl=tmpl->last;
+  for (i=0;i<text.rows;i++) {
+    if (cursor_row<0 && tmpl==cur_line) {
+      k=0;
+      for (j=0;j<cur_col;j++)
+        if (tmpl->line[j]=='\t')
+          k=(k+8)&~7;
+        else
+          k++;
+      cursor_col=k;
+      cursor_row=i;
+    }
+    if (tmpl!=head) {
+      st=tmpl->line;
+      k=0;
+      j=0;
+      while (ch=*st++) {
+        if (ch=='\t')
+          k2=(k+8)&~7;
+        else
+          k2=k+1;
+        if (line_start_col<=k<line_start_col+text.cols) {
+          '' ch;
+          j=k2-line_start_col;
+        }
+        k=k2;
+      }
+      if (j<text.cols)
+        '\n';
+      tmpl=tmpl->next;
+    } else {
+      if (!done_eof) {
+        '<EOF>';
+        done_eof=TRUE;
+      }
+      '\n';
+    }
+  }
+  text.raw_col=text.cols*cursor_row+cursor_col-line_start_col;
+  RawPutChar(0x7F);
+}
+
+Bool EdLite(U8 *filename,I64 num=1,I64 edf_dof_flags=0)
+{//Light weight text editor for debugging.
+  U8 *src,*src2,*src3,*dst,*buf,*bin_data=NULL;
+  I64 i,cnt=0,ch,sc,size,bin_size=0,line_start_col=0,cur_col=0,
+        old_raw_flags=text.raw_flags;
+  CLine head,*tmpl,*tmpl1,*cur_line;
+  Bool  res=FALSE,
+        old_raw=Raw(ON),
+        old_debug=DbgMode(ON),
+        old_single=SingleUser(ON);
+
+  if (!filename) filename=blkdev.tmp_filename;
+  buf=FileRead(filename,&size);
+
+  PUSHFD
+  CLI
+  text.raw_flags=text.raw_flags&~RWF_SCROLL|RWF_SHOW_DOLLAR;
+  kbd.scan_code=0;
+  QueInit(&head);
+  head.line=StrNew("");
+
+  if (buf) {
+    src=buf;
+    while (*src) {
+      src2=src;
+      while ((ch=*src++) && ch!='\r' && ch!='\n');
+      src--;
+      *src++=0;
+      if (!ch)
+        src--;
+      while (ch=='\r' && *src=='\n' || *src==CH_CURSOR)
+        src++;
+      dst=src3=src2;
+      while (ch=*src3++)
+        if (ch!='\n' && ch!=CH_CURSOR)
+          *dst++=ch;
+      *dst=0;
+
+      tmpl=MAlloc(sizeof(CLine));
+      tmpl->line=StrNew(src2);
+      QueIns(tmpl,head.last);
+      cnt++;
+    }
+
+    if (src+1-buf<size) {
+      bin_data=MAlloc(bin_size=size-(src-buf));
+      MemCpy(bin_data,src,bin_size);
+    }
+    Free(buf);
+    res=TRUE;
+  }
+
+  cur_line=head.next;
+  if (--num<0)
+    res=FALSE;
+  else {
+    if (num<=cnt)
+      while (num--)
+        cur_line=cur_line->next;
+    else {
+      cur_line=&head;
+      res=FALSE;
+    }
+  }
+  do {
+    if (cur_line==&head)
+      cur_col=0;
+    while (cur_col-line_start_col<0)
+      line_start_col-=8;
+    while (cur_col-line_start_col>=text.cols)
+      line_start_col+=8;
+    EdLiteUpdate(&head,cur_line,cur_col,line_start_col);
+    switch (ch=GetKey(&sc,FALSE,TRUE)) {
+      case 0:
+        switch (sc.u8[0]) {
+          case SC_CURSOR_UP:
+            if (cur_line->last!=&head)
+              cur_line=cur_line->last;
+            if (cur_col>StrLen(cur_line->line))
+              cur_col=StrLen(cur_line->line);
+            break;
+          case SC_CURSOR_DOWN:
+            if (cur_line!=&head)
+              cur_line=cur_line->next;
+            if (cur_col>StrLen(cur_line->line))
+              cur_col=StrLen(cur_line->line);
+            break;
+          case SC_CURSOR_RIGHT:
+            cur_col++;
+            if (cur_col>StrLen(cur_line->line)) {
+              tmpl=cur_line->next;
+              if (tmpl!=&head) {
+                cur_col=0;
+                cur_line=tmpl;
+              } else
+                cur_col=StrLen(cur_line->line);
+            }
+            break;
+          case SC_CURSOR_LEFT:
+            if (cur_col)
+              cur_col--;
+            else {
+              tmpl=cur_line->last;
+              if (tmpl!=&head) {
+                cur_line=tmpl;
+                cur_col=StrLen(tmpl->line);
+              }
+            }
+            break;
+          case SC_PAGE_UP:
+            for (i=1;i<text.rows;i++) {
+              if (cur_line->last!=&head)
+                cur_line=cur_line->last;
+              if (cur_col>StrLen(cur_line->line))
+                cur_col=StrLen(cur_line->line);
+            }
+            break;
+          case SC_PAGE_DOWN:
+            for (i=1;i<text.rows;i++) {
+              if (cur_line!=&head)
+                cur_line=cur_line->next;
+              if (cur_col>StrLen(cur_line->line))
+                cur_col=StrLen(cur_line->line);
+            }
+            break;
+          case SC_DELETE:
+            if (cur_col==StrLen(cur_line->line)) {
+              tmpl=cur_line->next;
+              if (cur_line!=&head && tmpl!=&head) {
+                src=MStrPrint("%s%s",cur_line->line,tmpl->line);
+                Free(cur_line->line);
+                Free(tmpl->line);
+                cur_line->line=src;
+                QueRem(tmpl);
+                Free(tmpl);
+              }
+            } else
+              StrCpy(cur_line->line+cur_col,cur_line->line+cur_col+1);
+            break;
+        }
+        break;
+      case '\n':
+      case '\r':
+        tmpl=MAlloc(sizeof(CLine));
+        tmpl->line=StrNew(cur_line->line+cur_col);
+        cur_line->line[cur_col]=0;
+        QueIns(tmpl,cur_line);
+        cur_line=tmpl;
+        cur_col=0;
+        break;
+      case CH_BACKSPACE:
+        if (cur_col) {
+          StrCpy(cur_line->line+cur_col-1,cur_line->line+cur_col);
+          cur_col--;
+        } else if (cur_line!=&head && cur_line->last!=&head) {
+          tmpl=cur_line->last;
+          src=MStrPrint("%s%s",tmpl->line,cur_line->line);
+          cur_col=StrLen(tmpl->line);
+          Free(cur_line->line);
+          Free(tmpl->line);
+          tmpl->line=src;
+          QueRem(cur_line);
+          Free(cur_line);
+          cur_line=tmpl;
+        }
+        break;
+      case CH_CTRLY:
+        if (cur_line!=&head) {
+          tmpl=cur_line;
+          cur_line=cur_line->next;
+          QueRem(tmpl);
+          Free(tmpl->line);
+          Free(tmpl);
+          cur_col=0;
+        }
+        break;
+      default:
+        if (Bt(char_bmp_printable,ch)) {
+          if (cur_line==&head) {
+            cur_line=MAlloc(sizeof(CLine));
+            cur_line->line=StrNew("");
+            QueIns(cur_line,head.last);
+          }
+          src=MAlloc(StrLen(cur_line->line)+2);
+          MemCpy(src,cur_line->line,cur_col);
+          src[cur_col]=ch;
+          if (cur_col<StrLen(cur_line->line))
+            StrCpy(src+cur_col+1,cur_line->line+cur_col);
+          else
+            src[cur_col+1]=0;
+          Free(cur_line->line);
+          cur_line->line=src;
+          cur_col++;
+        }
+    }
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+
+  if (ch!=CH_ESC) {
+    if (edf_dof_flags&EDF_WAS_WRITE)
+      res=FALSE;
+  } else {
+    size=bin_size;
+
+    tmpl=head.next;
+    while (tmpl!=&head) {
+      size+=StrLen(tmpl->line)+1;
+      tmpl=tmpl->next;
+    }
+
+    buf=dst=MAlloc(size);
+    tmpl=head.next;
+    while (tmpl!=&head) {
+      i=StrLen(tmpl->line);
+      MemCpy(dst,tmpl->line,i);
+      dst+=i;
+      *dst++='\n';
+      tmpl=tmpl->next;
+    }
+    if (bin_data)
+      MemCpy(dst,bin_data,bin_size);
+    FileWrite(filename,buf,size);
+    Free(buf);
+
+    if (edf_dof_flags&EDF_WAS_WRITE)
+      res=TRUE;
+  }
+
+  tmpl=head.next;
+  while (tmpl!=&head) {
+    tmpl1=tmpl->next;
+    QueRem(tmpl);
+    Free(tmpl->line);
+    Free(tmpl);
+    tmpl=tmpl1;
+  }
+  Free(head.line);
+  Free(bin_data);
+  Raw(old_raw);
+  DbgMode(old_debug);
+  SingleUser(old_single);
+  text.raw_flags=text.raw_flags&~RWF_SHOW_DOLLAR|old_raw_flags&RWF_SHOW_DOLLAR;
+  POPFD
+  return res;
+}
+
+U0 ToFileLine(U8 *_fl_file_line,U8 **_filename,I64 *_linenum)
+{//"FI:D:/Dir/File.HC,123" to "D:/Dir/File.HC" and 123.
+  U8 *st,*fl_file_line=StrNew(_fl_file_line);
+  I64 linenum;
+  StrFirstRem(fl_file_line,":");
+  st=StrNew(fl_file_line);
+  StrLastRem(fl_file_line,",",st);
+  linenum=Str2I64(st);
+  Free(st);
+  *_filename=fl_file_line;
+  *_linenum=linenum;
+}
+
+Bool EdLiteFileLine(U8 *fl_file_line,I64 edf_dof_flags=0)
+{
+  Bool res;
+  U8 *filename;
+  I64 linenum;
+  ToFileLine(fl_file_line,&filename,&linenum);
+  res=EdLite(filename,linenum,edf_dof_flags);
+  Free(filename);
+  return res;
+}
+
+U0 FixSet(U8 *filename,I64 line)
+{//Compiler calls this to set file line for Fix
+  U8 *st=MStrPrint("FL:%s,%d",filename,line);
+  while (LBts(&sys_semas[SEMA_FIX],0))
+    Yield;
+  Free(dbg.fix_file_line);
+  dbg.fix_file_line=AStrNew(st);
+  LBtr(&sys_semas[SEMA_FIX],0);
+}
+
+Bool Fix(I64 edf_dof_flags=0)
+{//Jump to last err src code to fix it.
+  U8 *st;
+  Bool res=FALSE;
+
+  while (LBts(&sys_semas[SEMA_FIX],0))
+    Yield;
+  st=StrNew(dbg.fix_file_line);
+  LBtr(&sys_semas[SEMA_FIX],0);
+
+  if (st) {
+    if (IsRaw)
+      res=EdLiteFileLine(st,edf_dof_flags);
+    else
+      res=Ed(st,edf_dof_flags);
+  }
+  Free(st);
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/FontCyrillic.HC.HTML b/public/Wb/Home/Src/Kernel/FontCyrillic.HC.HTML new file mode 100755 index 0000000..fd9a50b --- /dev/null +++ b/public/Wb/Home/Src/Kernel/FontCyrillic.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+//See ::/Doc/Credits.DD.
+
+U64 sys_font_cyrillic[256]= {
+0x0000000000000000,0x0000000000000000,
+0x000000FF00000000,0x000000FF00FF0000,//..
+0x1818181818181818,0x6C6C6C6C6C6C6C6C,//..
+0x181818F800000000,0x6C6C6CEC0CFC0000,//..
+0x1818181F00000000,0x6C6C6C6F607F0000,//..
+0x000000F818181818,0x000000FC0CEC6C6C,//..
+0x0000001F18181818,0x0000007F606F6C6C,//..
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0008000000000000,//
+0x0000000000000000,0x00180018183C3C18,// !
+0x0000000000363636,0x006C6CFE6CFE6C6C,//"#
+0x00187ED07C16FC30,0x0060660C18306606,//$%
+0x00DC66B61C36361C,0x0000000000181818,//&'
+0x0030180C0C0C1830,0x000C18303030180C,//()
+0x0000187E3C7E1800,0x000018187E181800,//*+
+0x0C18180000000000,0x000000007E000000,//,-
+0x0018180000000000,0x0000060C18306000,//./
+0x003C666E7E76663C,0x007E181818181C18,//01
+0x007E0C183060663C,0x003C66603860663C,//23
+0x0030307E363C3830,0x003C6660603E067E,//45
+0x003C66663E060C38,0x000C0C0C1830607E,//67
+0x003C66663C66663C,0x001C30607C66663C,//89
+0x0018180018180000,0x0C18180018180000,//:;
+0x0030180C060C1830,0x0000007E007E0000,//<=
+0x000C18306030180C,0x001800181830663C,//>?
+0x003C06765676663C,0x006666667E66663C,//@A
+0x003E66663E66663E,0x003C66060606663C,//BC
+0x001E36666666361E,0x007E06063E06067E,//DE
+0x000606063E06067E,0x003C66667606663C,//FG
+0x006666667E666666,0x007E18181818187E,//HI
+0x001C36303030307C,0x0066361E0E1E3666,//JK
+0x007E060606060606,0x00C6C6D6D6FEEEC6,//LM
+0x006666767E6E6666,0x003C66666666663C,//NO
+0x000606063E66663E,0x006C36566666663C,//PQ
+0x006666363E66663E,0x003C66603C06663C,//RS
+0x001818181818187E,0x003C666666666666,//TU
+0x00183C6666666666,0x00C6EEFED6D6C6C6,//VW
+0x0066663C183C6666,0x001818183C666666,//XY
+0x007E060C1830607E,0x003E06060606063E,//Z[
+0x00006030180C0600,0x007C60606060607C,//\]
+0x000000000000663C,0xFFFF000000000000,//^_
+0x000000000030180C,0x007C667C603C0000,//`a
+0x003E6666663E0606,0x003C6606663C0000,//bc
+0x007C6666667C6060,0x003C067E663C0000,//de
+0x000C0C0C3E0C0C38,0x3C607C66667C0000,//fg
+0x00666666663E0606,0x003C1818181C0018,//hi
+0x0E181818181C0018,0x0066361E36660606,//jk
+0x003C18181818181C,0x00C6D6D6FE6C0000,//lm
+0x00666666663E0000,0x003C6666663C0000,//no
+0x06063E66663E0000,0xE0607C66667C0000,//pq
+0x000606066E360000,0x003E603C067C0000,//rs
+0x00380C0C0C3E0C0C,0x007C666666660000,//tu
+0x00183C6666660000,0x006CFED6D6C60000,//vw
+0x00663C183C660000,0x3C607C6666660000,//xy
+0x007E0C18307E0000,0x003018180E181830,//z{
+0x0018181818181818,0x000C18187018180C,//|}
+0x000000000062D68C,0xFFFFFFFFFFFFFFFF,//~
+0x1E30181E3303331E,0x007E333333003300,//..
+0x001E033F331E0038,0x00FC667C603CC37E,//..
+0x007E333E301E0033,0x007E333E301E0007,//..
+0x007E333E301E0C0C,0x3C603E03033E0000,//..
+0x003C067E663CC37E,0x001E033F331E0033,//..
+0x001E033F331E0007,0x001E0C0C0C0E0033,//..
+0x003C1818181C633E,0x001E0C0C0C0E0007,//..
+0x00333F33331E0C33,0x00333F331E000C0C,//..
+0x003F061E063F0038,0x00FE33FE30FE0000,//..
+0x007333337F33367C,0x001E33331E00331E,//..
+0x001E33331E003300,0x001E33331E000700,//..
+0x007E33333300331E,0x007E333333000700,//..
+0x1F303F3333003300,0x001C3E63633E1C63,//..
+0x001E333333330033,0x18187E03037E1818,//..
+0x003F67060F26361C,0x000C3F0C3F1E3333,//..
+0x70337B332F1B1B0F,0x0E1B18187E18D870,//..
+0x000F11110F01111F,0x000101010101111F,//..
+0x000F0107010F000A,0x001515150E151515,//..
+0x000F10100E10100F,0x0011111315191111,//..
+0x001113151911040A,0x001215141414141E,//..
+0x001111111111111F,0x000102040A111111,//..
+0x00040E1515150E04,0x001010101E111111,//..
+0x001F151515151515,0x000E12120E020203,//..
+0x0013151513111111,0x000E11101C10110E,//..
+0x0009151517151509,0x001112141E11111E,//..
+0x000E11110F010618,0x0007090709070000,//..
+0x00010101111F0000,0x000E011F110E000A,//..
+0x0015150E15150000,0x000F100C100F0000,//..
+0x0011131519110000,0x0013151911040A00,//..
+0x0009050305090000,0x00121514141E0000,//..
+0x001111151B110000,0x0011111F11110000,//..
+0x00111111111F0000,0x00040404041F0000,//..
+0x0010101E11110000,0x001F151515150000,//..
+0x000E120E02030000,0x0013151311110000,//..
+0x0007090701010000,0x000E111C110E0000,//..
+0x0009151715090000,0x0012141E111E0000,//..
+0x0004120912040000,0x0004091209040000,//..
+0x001B091200000000,0x000000000009121B,//..
+0x001C141C090D0B09,0x000E110102040004,//..
+0x000304040E040418,0x001E02020F020A04,//..
+0x0004040000000000,0x0004040404000000,//..
+0x000E000A0A0A0000,0x000A000A0A0A0000,//..
+0x0001020408170005,0x00001B0E040E1B00,//..
+0x0001020408150205,0x00000E040404040E,//..
+0x00001F0A0A0A0A1F,0x0004040404150E04,//..
+0x00040E1504040404,0x0001090D1F0D0901,//..
+0x001012161F161210,0x000111151F151101,//..
+0x0001020408110701,0x000000000C0C0000,//..
+0x111F11121414141E,0x101F111111111111,//..
+0x101F151515151515,0x111F1112141E0000,//.pi
+0x040E15150E040400,0x101A111111110000,//..
+0x101F151515150000,0x0000000000000408,//u.
+0x000000000000000A,0x0000000000000D12,//phitheta
+0x000E011F110E0408,0x06040E11010E0000,//omega.
+0x0006080A0A0A000A,0x0000041F0E0E0E04,//inf.
+0x00000A0011000A00,0x00000E1111110E00,//..
+0x0010101D1A150911,0x001C1019121D0911,//..
+0x001C0419121D0911,0x10101C1B12030203,//..
+0x00111F111F111F11,0x0000000600180003,//..
+0x041E141015070502,0x07020E021E020E02,//..
+0x0E040E041F040E04,0x1C08160017001600,//..
+0x1C080E080F080E08,0x00040E041F040E04,//..
+0x1C08090A0C0A0908,0x0609040A0A04120C,//..
+0x001414141E15151E,0xFFFFFFFFFFFFFFFF,//..
+};
+
+ diff --git a/public/Wb/Home/Src/Kernel/FontStd.HC.HTML b/public/Wb/Home/Src/Kernel/FontStd.HC.HTML new file mode 100755 index 0000000..f1a281a --- /dev/null +++ b/public/Wb/Home/Src/Kernel/FontStd.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+//See ::/Doc/Credits.DD.
+
+U64 sys_font_std[256]= {
+0x0000000000000000,0x0000000000000000,
+0x000000FF00000000,0x000000FF00FF0000,//..
+0x1818181818181818,0x6C6C6C6C6C6C6C6C,//..
+0x181818F800000000,0x6C6C6CEC0CFC0000,//..
+0x1818181F00000000,0x6C6C6C6F607F0000,//..
+0x000000F818181818,0x000000FC0CEC6C6C,//..
+0x0000001F18181818,0x0000007F606F6C6C,//..
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0008000000000000,//
+0x0000000000000000,0x00180018183C3C18,// !
+0x0000000000363636,0x006C6CFE6CFE6C6C,//"#
+0x00187ED07C16FC30,0x0060660C18306606,//$%
+0x00DC66B61C36361C,0x0000000000181818,//&'
+0x0030180C0C0C1830,0x000C18303030180C,//()
+0x0000187E3C7E1800,0x000018187E181800,//*+
+0x0C18180000000000,0x000000007E000000,//,-
+0x0018180000000000,0x0000060C18306000,//./
+0x003C666E7E76663C,0x007E181818181C18,//01
+0x007E0C183060663C,0x003C66603860663C,//23
+0x0030307E363C3830,0x003C6660603E067E,//45
+0x003C66663E060C38,0x000C0C0C1830607E,//67
+0x003C66663C66663C,0x001C30607C66663C,//89
+0x0018180018180000,0x0C18180018180000,//:;
+0x0030180C060C1830,0x0000007E007E0000,//<=
+0x000C18306030180C,0x001800181830663C,//>?
+0x003C06765676663C,0x006666667E66663C,//@A
+0x003E66663E66663E,0x003C66060606663C,//BC
+0x001E36666666361E,0x007E06063E06067E,//DE
+0x000606063E06067E,0x003C66667606663C,//FG
+0x006666667E666666,0x007E18181818187E,//HI
+0x001C36303030307C,0x0066361E0E1E3666,//JK
+0x007E060606060606,0x00C6C6D6D6FEEEC6,//LM
+0x006666767E6E6666,0x003C66666666663C,//NO
+0x000606063E66663E,0x006C36566666663C,//PQ
+0x006666363E66663E,0x003C66603C06663C,//RS
+0x001818181818187E,0x003C666666666666,//TU
+0x00183C6666666666,0x00C6EEFED6D6C6C6,//VW
+0x0066663C183C6666,0x001818183C666666,//XY
+0x007E060C1830607E,0x003E06060606063E,//Z[
+0x00006030180C0600,0x007C60606060607C,//\]
+0x000000000000663C,0xFFFF000000000000,//^_
+0x000000000030180C,0x007C667C603C0000,//`a
+0x003E6666663E0606,0x003C6606663C0000,//bc
+0x007C6666667C6060,0x003C067E663C0000,//de
+0x000C0C0C3E0C0C38,0x3C607C66667C0000,//fg
+0x00666666663E0606,0x003C1818181C0018,//hi
+0x0E181818181C0018,0x0066361E36660606,//jk
+0x003C18181818181C,0x00C6D6D6FE6C0000,//lm
+0x00666666663E0000,0x003C6666663C0000,//no
+0x06063E66663E0000,0xE0607C66667C0000,//pq
+0x000606066E360000,0x003E603C067C0000,//rs
+0x00380C0C0C3E0C0C,0x007C666666660000,//tu
+0x00183C6666660000,0x006CFED6D6C60000,//vw
+0x00663C183C660000,0x3C607C6666660000,//xy
+0x007E0C18307E0000,0x003018180E181830,//z{
+0x0018181818181818,0x000C18187018180C,//|}
+0x000000000062D68C,0xFFFFFFFFFFFFFFFF,//~
+0x1E30181E3303331E,0x007E333333003300,//..
+0x001E033F331E0038,0x00FC667C603CC37E,//..
+0x007E333E301E0033,0x007E333E301E0007,//..
+0x007E333E301E0C0C,0x3C603E03033E0000,//..
+0x003C067E663CC37E,0x001E033F331E0033,//..
+0x001E033F331E0007,0x001E0C0C0C0E0033,//..
+0x003C1818181C633E,0x001E0C0C0C0E0007,//..
+0x00333F33331E0C33,0x00333F331E000C0C,//..
+0x003F061E063F0038,0x00FE33FE30FE0000,//..
+0x007333337F33367C,0x001E33331E00331E,//..
+0x001E33331E003300,0x001E33331E000700,//..
+0x007E33333300331E,0x007E333333000700,//..
+0x1F303F3333003300,0x001C3E63633E1C63,//..
+0x001E333333330033,0x18187E03037E1818,//..
+0x003F67060F26361C,0x000C3F0C3F1E3333,//..
+0x70337B332F1B1B0F,0x0E1B18187E18D870,//..
+0x007E333E301E0038,0x001E0C0C0C0E001C,//..
+0x001E33331E003800,0x007E333333003800,//..
+0x003333331F001F00,0x00333B3F3733003F,//..
+0x00007E007C36363C,0x00007E003C66663C,//..
+0x001E3303060C000C,0x000003033F000000,//..
+0x000030303F000000,0xF81973C67C1B3363,//..
+0xC0F9F3E6CF1B3363,0x183C3C1818001800,//..
+0x0000CC663366CC00,0x00003366CC663300,//..
+0x1144114411441144,0x55AA55AA55AA55AA,//..
+0xEEBBEEBBEEBBEEBB,0x1818181818181818,//..
+0x1818181F18181818,0x1818181F181F1818,//..
+0x6C6C6C6F6C6C6C6C,0x6C6C6C7F00000000,//..
+0x1818181F181F0000,0x6C6C6C6F606F6C6C,//..
+0x6C6C6C6C6C6C6C6C,0x6C6C6C6F607F0000,//..
+0x0000007F606F6C6C,0x0000007F6C6C6C6C,//..
+0x0000001F181F1818,0x1818181F00000000,//..
+0x000000F818181818,0x000000FF18181818,//..
+0x181818FF00000000,0x181818F818181818,//..
+0x000000FF00000000,0x181818FF18181818,//..
+0x181818F818F81818,0x6C6C6CEC6C6C6C6C,//..
+0x000000FC0CEC6C6C,0x6C6C6CEC0CFC0000,//..
+0x000000FF00EF6C6C,0x6C6C6CEF00FF0000,//..
+0x6C6C6CEC0CEC6C6C,0x000000FF00FF0000,//..
+0x6C6C6CEF00EF6C6C,0x000000FF00FF1818,//..
+0x000000FF6C6C6C6C,0x181818FF00FF0000,//..
+0x6C6C6CFF00000000,0x000000FC6C6C6C6C,//..
+0x000000F818F81818,0x181818F818F80000,//..
+0x6C6C6CFC00000000,0x6C6C6CEF6C6C6C6C,//..
+0x181818FF00FF1818,0x0000001F18181818,//..
+0x181818F800000000,0xFFFFFFFFFFFFFFFF,//..
+0xFFFFFFFF00000000,0x0F0F0F0F0F0F0F0F,//..
+0xF0F0F0F0F0F0F0F0,0x00000000FFFFFFFF,//..
+0x006E3B133B6E0000,0x03031F331F331E00,//..
+0x0003030303637F00,0x0036363636367F00,//.pi
+0x007F660C180C667F,0x001E3333337E0000,//..
+0x03063E6666666600,0x00181818183B6E00,//u.
+0x3F0C1E33331E0C3F,0x001C36637F63361C,//phitheta
+0x007736366363361C,0x001E33333E180C38,//omega.
+0x00007EDBDB7E0000,0x03067EDBDB7E3060,//inf.
+0x003C06033F03063C,0x003333333333331E,//..
+0x00003F003F003F00,0x003F000C0C3F0C0C,//..
+0x003F00060C180C06,0x003F00180C060C18,//..
+0x1818181818D8D870,0x0E1B1B1818181818,//..
+0x000C0C003F000C0C,0x0000394E00394E00,//..
+0x000000001C36361C,0x0000001818000000,//..
+0x0000001800000000,0x383C3637303030F0,//..
+0x000000363636361E,0x0000003E061C301E,//..
+0x00003C3C3C3C0000,0xFFFFFFFFFFFFFFFF,//..
+};
+
+ diff --git a/public/Wb/Home/Src/Kernel/FunSeg.HC.HTML b/public/Wb/Home/Src/Kernel/FunSeg.HC.HTML new file mode 100755 index 0000000..c30c45a --- /dev/null +++ b/public/Wb/Home/Src/Kernel/FunSeg.HC.HTML @@ -0,0 +1,391 @@ + + + + + + + + + + + +
+I64 HasLower(U8 *src)
+{
+  I64 ch;
+  while (ch=*src++)
+    if ('a'<=ch<='z')
+      return TRUE;
+  return FALSE;
+}
+
+U0 HashFunSegFind(CHashTable *h,U8 *addr,
+        Bool *_has_lower,U64 *_best,CHash **_res)
+{
+  Bool *has_lower=*_has_lower;
+  CHashExport *tmpex;
+  U64 i,j,best=*_best;
+  CHash *res=*_res;
+  for (i=0;i<=h->mask;i++) {
+    tmpex=h->body[i];
+    while (tmpex) {
+      j=0;
+      if (tmpex->type&HTT_FUN) {
+        if (!Bt(&tmpex(CHashFun *)->flags,Cf_EXTERN) &&
+              !Bt(&tmpex(CHashFun *)->flags,Ff_INTERNAL))
+          j=tmpex(CHashFun *)->exe_addr;
+      } else if (tmpex->type&HTT_EXPORT_SYS_SYM)
+        j=tmpex->val;
+      if (j) {
+        j=addr(I64)-j;
+        if (0<=j<=best) {
+          if (tmpex->type&HTT_EXPORT_SYS_SYM) {
+            if (j<best || j==best && !has_lower) {
+              has_lower=HasLower(tmpex->str);
+              best=j;
+              res=tmpex;
+            }
+          } else if (tmpex->type&HTT_FUN) {
+            if (j<best || j==best &&
+                  (res && res->type&HTT_EXPORT_SYS_SYM||!has_lower)) {
+              has_lower=HasLower(tmpex->str);
+              best=j;
+              res=tmpex;
+            }
+          }
+        }
+      }
+      tmpex=tmpex->next;
+    }
+  }
+  *_has_lower=has_lower;
+  *_best=best;
+  *_res =res;
+}
+
+CHash *FunSegFind(U8 *addr,I64 *_offset)
+{//See Hash.
+  CHash *res=NULL;
+  Bool has_lower=FALSE;
+  CTask *task;
+  CHashTable *h;
+  CCPU *c;
+  U64 i,best=0xFFFF;
+  if (!ChkCodePtr(addr)) {
+    *_offset=best;
+    return NULL;
+  }
+  if (IsDbgMode)
+    for (i=0;i<mp_cnt;i++) {
+      c=&cpu_structs[i];
+      task=c->seth_task;
+      do {
+        if (!TaskValidate(task)) goto fs_abort_task;
+        h=task->hash_table;
+        while (h) {
+          HashFunSegFind(h,addr,&has_lower,&best,&res);
+          h=h->next;
+        }
+        task=task->next_task;
+      } while (task!=c->seth_task);
+fs_abort_task:
+    }
+  else {
+    h=Fs->hash_table;
+    while (h) {
+      HashFunSegFind(h,addr,&has_lower,&best,&res);
+      h=h->next;
+    }
+  }
+  *_offset=best;
+  return res;
+}
+
+U0 FunSegCacheAdd(CHash *tmps,U8 *addr)
+{
+  I64 i;
+  CDbgInfo *dbg_info;
+  CFunSegCache *tmpfsc;
+  if (tmps && tmps->type&HTT_FUN &&
+        (dbg_info=tmps(CHashFun *)->dbg_info)) {
+    lock i=dbg.fun_seg_cache_index++;
+    tmpfsc=&dbg.fun_seg_cache[i&(FUN_SEG_CACHE_SIZE-1)];
+    tmpfsc->base=dbg_info->body[0];
+    if (addr<tmpfsc->base)
+      tmpfsc->base=addr;
+    tmpfsc->limit=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line];
+    if (addr>=tmpfsc->limit)
+      tmpfsc->limit=addr+1;
+    i=MinI64(StrLen(tmps->str),FUN_SEG_CACHE_STR_LEN-1);
+    MemCpy(tmpfsc->str,tmps->str,i);
+    tmpfsc->str[i]=0;
+    tmpfsc->time_stamp=tS;
+  }
+}
+
+U8 *FunSegCacheFind(U8 *addr,I64 *_offset)
+{
+  I64 i;
+  F64 timeout;
+  CFunSegCache *tmpfsc=dbg.fun_seg_cache;
+  if (addr==SYS_IDLE_PT) {
+    *_offset=0;
+    return "SYS_IDLE_PT";
+  } else {
+    timeout=tS+8.0;
+    for (i=0;i<FUN_SEG_CACHE_SIZE;i++,tmpfsc++)
+      if (tmpfsc->base<=addr<tmpfsc->limit &&
+            tmpfsc->time_stamp>timeout) {
+        *_offset=addr-tmpfsc->base;
+        return tmpfsc->str;
+      }
+    return NULL;
+  }
+}
+
+U0 StrPrintFunSeg(U8 *buf,I64 addr,I64 field_len,I64 flags)
+{
+  I64 offset;
+  CHashExport *tmpex;
+  U8 *str,*str2;
+  Bool is_fun=FALSE;
+  if (!(flags&PRTF_TRUNCATE))
+    field_len=0;
+  if (addr) {
+    if (str=FunSegCacheFind(addr,&offset)) {
+      if (addr!=SYS_IDLE_PT)
+        is_fun=TRUE;
+    } else  {
+      if (tmpex=FunSegFind(addr,&offset)) {
+        if (tmpex->type&HTT_FUN)
+          is_fun=TRUE;
+        FunSegCacheAdd(tmpex,addr);
+        str=tmpex->str;
+      }
+    }
+    if (str) {
+      if (offset>0xFFFF) offset=0xFFFF;
+      if (flags&PRTF_COMMA) {
+        if (is_fun) {
+          str2=MStrPrint("&%s",str);
+          if (!field_len)
+            StrCpy(buf,str2);
+          else if (flags&PRTF_LEFT_JUSTIFY && StrLen(str2)<field_len)
+            StrCpy(buf,str2);
+          else
+            StrPrint(buf,"%*ts",field_len,str2);
+          Free(str2);
+        } else {
+          if (!field_len)
+            StrCpy(buf,str);
+          else if (flags&PRTF_LEFT_JUSTIFY && StrLen(str)<field_len)
+            StrCpy(buf,str);
+          else
+            StrPrint(buf,"%*ts",field_len,str);
+        }
+      } else {
+        if (is_fun) {
+          str2=MStrPrint("&%s",str);
+          if (field_len && field_len>7) {
+            if (flags&PRTF_LEFT_JUSTIFY && StrLen(str2)<field_len-7)
+              StrPrint(buf,"%s+0x%04X",str2,offset);
+            else
+              StrPrint(buf,"%*ts+0x%04X",field_len-7,str2,offset);
+          } else
+            StrPrint(buf,"%s+0x%04X",str2,offset);
+          Free(str2);
+        } else {
+          if (field_len && field_len>7) {
+            if (flags&PRTF_LEFT_JUSTIFY && StrLen(str)<field_len-7)
+              StrPrint(buf,"%s+0x%04X",str,offset);
+            else
+              StrPrint(buf,"%*ts+0x%04X",field_len-7,str,offset);
+          } else
+            StrPrint(buf,"%s+0x%04X",str,offset);
+        }
+      }
+      return;
+    }
+  }
+  if (flags&PRTF_COMMA)
+    StrCpy(buf,".");
+  else if (flags&PRTF_TRUNCATE && field_len)
+    StrPrint(buf,"%*tX",field_len,addr);
+  else
+    StrPrint(buf,"%X",addr);
+}
+
+I64 SrcLineNum(U8 *addr,I64 cnt=1)
+{//linenum for src of addr.
+  CHashSrcSym *tmph;
+  I64 cur_line,first_line,last_line,num_lines,offset;
+  CDbgInfo *dbg_info;
+  U32 *body;
+  U8 *src,*src2;
+  if (tmph=FunSegFind(addr,&offset)) {
+    if (tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+      if (dbg_info=tmph->dbg_info) {
+        num_lines=dbg_info->max_line-dbg_info->min_line+1;
+        body=dbg_info->body;
+
+        //find first nonzero
+        first_line=0;
+        while (!body[first_line]) {
+          first_line++;
+          if (first_line>=num_lines)
+            return -1;
+        }
+
+        //find last nonzero
+        last_line=num_lines-1;
+        while (!body[last_line] && last_line>first_line)
+          last_line--;
+
+          //interpolate to guess line num
+        cur_line=ClampI64(ToF64(addr-body[first_line])*(last_line-first_line+1)/
+              (body[last_line]-body[first_line]+1),first_line,last_line);
+
+        //retreat while too high
+        while ((!body[cur_line] || body[cur_line]>=addr) && cur_line>first_line)
+          cur_line--;
+
+          //advance while to low
+        while ((!body[cur_line] || body[cur_line]<addr) && cur_line<last_line)
+          cur_line++;
+
+        if (addr<body[cur_line]+cnt)
+          return cur_line+dbg_info->min_line;
+
+      } else if (tmph->src_link) {
+        src =StrNew(tmph->src_link);
+        src2=StrNew(tmph->src_link);
+        StrLastRem(src,",",src2);
+        cur_line=Str2I64(src2);
+        Free(src);
+        Free(src2);
+        return cur_line;
+      }
+    }
+  }
+  return -1;
+}
+
+U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)
+{//MAlloc filename for src of addr.
+  CHashSrcSym *tmph;
+  I64 i,j,ii,offset,best=NULL,d,best_d;
+  U32 *body;
+  CDbgInfo *dbg_info;
+  U8 *src;
+  if ((tmph=FunSegFind(addr,&offset)) &&
+        tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+    if (dbg_info=tmph->dbg_info) {
+      j=dbg_info->max_line-dbg_info->min_line+1;
+      body=dbg_info->body;
+      best_d=I64_MAX;
+      for (i=0;i<j;i++) {
+        if (0<body[i]<=addr<body[i]+cnt) {
+          ii=i+1;
+          while (!body[ii])
+            ii++;
+          if (addr<body[ii]) {
+            d=addr(I64)-body[i];
+            if (d<best_d) {
+              best_d=d;
+              best=tmph->src_link;
+            }
+          }
+        }
+      }
+    } else
+      best=tmph->src_link;
+  }
+  if (best) {
+    src=StrNew(best,mem_task);
+    StrFirstRem(src,":");
+    StrLastRem(src,",");
+    return src;
+  } else
+    return NULL;
+}
+
+U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)
+{//MAlloc file,line link to src of addr.
+  U8 *filename,*st,*st2;
+  I64 linenum;
+  if (filename=SrcFileName(addr,cnt)) {
+    linenum=SrcLineNum(addr,cnt);
+    if (linenum<1)
+      linenum=1;
+    st2=MStrPrint("FL:%s,%d",filename,linenum);
+    Free(filename);
+    st=StrNew(st2,mem_task);
+    Free(st2);
+    return st;
+  }
+  return NULL;
+}
+
+Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL)
+{//Put to StdOut a DolDoc file,line link to src of addr.
+  U8 *src;
+  if (src=SrcEdLink(addr,cnt)) {
+    if (buf)
+      StrPrint(buf,"$LK,\"%p\",A=\"%s\"$",addr,src);
+    else
+      "$LK,\"%p\",A=\"%s\"$",addr,src;
+    Free(src);
+    return TRUE;
+  } else if (buf)
+    *buf=0;
+  return FALSE;
+}
+
+Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0)
+{//Edit src at addr.
+  U8 *st;
+  Bool res=FALSE;
+  if (st=SrcEdLink(addr,cnt)) {
+    if (IsRaw)
+      res=EdLiteFileLine(st,edf_dof_flags);
+    else
+      res=Ed(st,edf_dof_flags);
+    Free(st);
+  }
+  return res;
+}
+
+Bool Man(U8 *st,I64 edf_dof_flags=0)
+{//Owner's manual for symbol.  Edit src code for symbol.
+  Bool res=FALSE;
+  U8 **st2;
+  CHashSrcSym *tmph;
+  if (IsRaw) {
+    if ((tmph=HashFind(st,Fs->hash_table,HTG_SRC_SYM)) && tmph->src_link)
+      res=EdLiteFileLine(tmph->src_link,edf_dof_flags);
+  } else {
+    st2=MStrPrint("MN:%s",st);
+    res=Ed(st2,edf_dof_flags);
+    Free(st2);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Job.HC.HTML b/public/Wb/Home/Src/Kernel/Job.HC.HTML new file mode 100755 index 0000000..3384558 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Job.HC.HTML @@ -0,0 +1,533 @@ + + + + + + + + + + + +
+U0 JobDel(CJob *tmpc)
+{//Free one cmd node.
+  Free(tmpc->aux_str);
+  Free(tmpc);
+}
+
+U0 JobQueDel(CJob *head)
+{
+  CJob *tmpc=head->next,*tmpc1;
+  while (tmpc!=head) {
+    tmpc1=tmpc->next;
+    QueRem(tmpc);
+    JobDel(tmpc);
+    tmpc=tmpc1;
+  }
+}
+
+U0 JobCtrlInit(CJobCtrl *ctrl)
+{
+  QueInit(&ctrl->next_waiting);
+  QueInit(&ctrl->next_done);
+  ctrl->flags=0;
+}
+
+U0 TaskRstAwaitingMsg(CTask *task=NULL)
+{//Pop-ups get parent messages so wake-up our pop-ups if we got a msg.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  do {
+    if (TaskValidate(task))
+      LBtr(&task->task_flags,TASKf_AWAITING_MSG);
+    else
+      break;
+  } while (task=task->popup_task);
+  POPFD
+}
+
+CJob *TaskExe(CTask *srv,CTask *master,U8 *data,I64 flags)
+{//Queues a request to compile and execute src code text.
+  CJob *res;
+  if (!data || !TaskValidate(srv) || master && !TaskValidate(master) ||
+        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))
+    return NULL;
+  res=ACAlloc(sizeof(CJob));
+  res->master_task=master;
+  res->job_code=JOBT_EXE_STR;
+  res->flags=flags;
+  res->aux_str=AStrNew(data);
+  res->ctrl=&srv->srv_ctrl;
+
+  PUSHFD
+  CLI
+  while (LBts(&srv->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+  if (!TaskValidate(srv)) {
+    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);
+    POPFD
+    JobDel(res);
+    return NULL;
+  } else {
+    LBtr(&srv->task_flags,TASKf_IDLE);
+    TaskRstAwaitingMsg(srv);
+    QueIns(res,srv->srv_ctrl.last_waiting);
+    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);
+    if (Bt(&flags,JOBf_WAKE_MASTER)) {
+      Suspend(master);
+      Yield;
+    }
+  }
+  POPFD
+  return res;
+}
+
+CJob *TaskText(CTask *srv,CTask *master,U8 *data,I64 flags)
+{//Post StdIn text to servant task. Tell who the master task is.
+  CJob *res;
+  CTask *task;
+  if (!data || !TaskValidate(srv) || master && !TaskValidate(master) ||
+        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))
+    return NULL;
+  res=ACAlloc(sizeof(CJob));
+  res->master_task=master; //in case somebody cares
+  res->job_code=JOBT_TEXT_INPUT;
+  res->flags=flags;
+  res->aux_str=AStrNew(data);
+
+  PUSHFD
+  task=srv->last_input_filter_task;
+  if (Bt(&flags,JOBf_HIGHEST_PRIORITY) || task==srv) {
+    if (task!=srv)
+      TaskWait(srv);
+    task=Spawn(&InputFilterTask,NULL,"Input Filter",,srv);
+    CLI
+    task->next_input_filter_task=srv->next_input_filter_task;
+    task->last_input_filter_task=srv;
+    srv->next_input_filter_task=task;
+    task->next_input_filter_task->last_input_filter_task=task;
+  } else {
+    CLI
+    task=srv->next_input_filter_task;
+  }
+  res->ctrl=&task->srv_ctrl;
+  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+  if (!TaskValidate(task)) {
+    JobDel(res);
+    res=NULL;
+  } else {
+    LBtr(&task->task_flags,TASKf_IDLE);
+    TaskRstAwaitingMsg(task);
+    QueIns(res,task->srv_ctrl.last_waiting);
+    LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  }
+  POPFD
+  return res;
+}
+
+CJob *TaskMsg(CTask *_srv,CTask *master,
+        I64 msg_code,I64 arg1,I64 arg2,I64 flags)
+{//Post message to servant task.  Tell who the master task is.
+//See flags and msg_code.
+  CJob *tmpc1,*tmpc;
+  CTask *srv=_srv;
+  if (!TaskValidate(srv) || master && !TaskValidate(master)||
+        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))
+    return NULL;
+  tmpc=ACAlloc(sizeof(CJob));
+  tmpc->master_task=master;
+  tmpc->job_code=JOBT_MSG;
+  tmpc->msg_code=AbsI64(msg_code); //negative means do a down and up
+  tmpc->aux1=arg1;
+  tmpc->aux2=arg2;
+  tmpc->flags=flags;
+  PUSHFD
+  if (Bt(&sys_semas[SEMA_RECORD_MACRO],0) &&
+        srv!=sys_macro_task && msg_code==MSG_KEY_DOWN) {
+    tmpc1=AMAllocIdent(tmpc);
+    CLI
+    QueIns(tmpc1,sys_macro_head.last);
+  }
+  CLI
+  while (Bt(&srv->task_flags,TASKf_FILTER_INPUT) &&
+        !Bt(&flags,JOBf_DONT_FILTER))
+    srv=srv->next_input_filter_task;
+  tmpc->ctrl=&srv->srv_ctrl;
+  while (LBts(&srv->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+  if (!TaskValidate(srv)) {
+    JobDel(tmpc);
+    tmpc=NULL;
+  } else {
+    LBtr(&srv->task_flags,TASKf_IDLE);
+    TaskRstAwaitingMsg(srv);
+    QueIns(tmpc,srv->srv_ctrl.last_waiting);
+    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);
+  }
+  POPFD
+  if (msg_code<0) //Down-Up
+    TaskMsg(_srv,master,-msg_code+1,arg1,arg2,flags);
+  return tmpc;
+}
+
+Bool JobResScan(CJob *rqst=NULL,I64 *_res=NULL)
+{//Check rqst complete, return with or without.
+  CJobCtrl *ctrl;
+  CJob *tmpc,*tmpc1;
+  if (!rqst || Bt(&rqst->flags,JOBf_DONE)) {
+    if (!rqst || rqst->master_task)
+      ctrl=&Fs->srv_ctrl;
+    else
+      ctrl=rqst->ctrl;
+    PUSHFD
+    CLI
+    while (LBts(&ctrl->flags,JOBCf_LOCKED))
+      PAUSE
+    tmpc1=&ctrl->next_done;
+    tmpc=tmpc1->next;
+    while (tmpc!=tmpc1) {
+      if (!rqst || rqst==tmpc) {
+        QueRem(tmpc);
+        LBtr(&ctrl->flags,JOBCf_LOCKED);
+        POPFD
+        if (_res)
+          *_res=tmpc->res;
+        JobDel(tmpc);
+        return TRUE;
+      }
+      tmpc=tmpc->next;
+    }
+    LBtr(&ctrl->flags,JOBCf_LOCKED);
+    POPFD
+  }
+  if (_res)
+    *_res=0;
+  return FALSE;
+}
+
+I64 JobResGet(CJob *rqst=NULL)
+{//See ::/Demo/MultiCore/Lock.HC
+  I64 res;
+  CJob *tmpc1;
+  if (!rqst) {
+    tmpc1=&Fs->srv_ctrl.next_done;
+    while (tmpc1==tmpc1->next) {
+      LBts(&Fs->task_flags,TASKf_IDLE);
+      Yield;
+    }
+  } else {
+    while (!Bt(&rqst->flags,JOBf_DONE)) {
+      LBts(&Fs->task_flags,TASKf_IDLE);
+      Yield;
+    }
+  }
+  LBtr(&Fs->task_flags,TASKf_IDLE);
+//Could get taken by someone else.
+  JobResScan(rqst,&res);
+  return res;
+}
+
+U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE)
+{//Wait for idle.
+  CTask *task1;
+  CJob *tmpc1;
+  if (!task) task=Fs;
+  if (TaskValidate(task)) {
+    PUSHFD
+    CLI
+    while (TRUE) {
+      task1=task->last_input_filter_task;
+      tmpc1=&task1->srv_ctrl.next_waiting;
+      if (task1==Fs || !TaskValidate(task1) ||
+            tmpc1==tmpc1->next && Bt(&task1->task_flags,TASKf_IDLE) &&
+            (!cmd_line_pmt || Bt(&task1->task_flags,TASKf_CMD_LINE_PMT)))
+        break;
+      Yield;
+    }
+    POPFD
+  }
+}
+
+U0 PostMsg(CTask *task,I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)
+{//Post message to a task and return immediately.  See msg_code.
+  if (TaskValidate(task)) {
+    if (Bt(&task->task_flags,TASKf_INPUT_FILTER_TASK))
+      TaskMsg(task->last_input_filter_task,NULL,msg_code,arg1,arg2,
+            flags|1<<JOBf_DONT_FILTER);
+    else
+      TaskMsg(task,NULL,msg_code,arg1,arg2,flags);
+  }
+}
+
+U0 PostMsgWait(CTask *task,I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)
+{//Post message to a task and wait until task is idle.See msg_code.
+  PostMsg(task,msg_code,arg1,arg2,flags);
+  TaskWait(task);
+}
+
+U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)
+{//Post message to current task and return immediately.
+//See msg_code.
+  PostMsg(Fs,msg_code,arg1,arg2,flags);
+}
+
+#define JOB_DONE        0
+#define JOB_CONT        1
+#define JOB_EXIT        2
+
+I64 JobRunOne(I64 run_flags,CJobCtrl *ctrl)
+{//Called with ctrl->flags,JOBCf_LOCKED.
+  CJob *tmpc=ctrl->next_waiting;
+  CTask   *master;
+  I64 res,flags=tmpc->flags,old_flags=GetRFlags;
+  if (Bt(&flags,JOBf_EXIT_ON_COMPLETE))
+    res=JOB_EXIT;
+  else
+    res=JOB_CONT;
+  switch (tmpc->job_code) {
+    case JOBT_SPAWN_TASK:
+      QueRem(tmpc);
+      LBts(&tmpc->flags,JOBf_DISPATCHED);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      if (tmpc->aux_str)
+        tmpc->spawned_task=Spawn(tmpc->addr,tmpc->fun_arg,
+              tmpc->aux_str,,tmpc->aux1,tmpc->aux2,tmpc->flags);
+      else
+        tmpc->spawned_task=Spawn(tmpc->addr,tmpc->fun_arg,
+              "Unnamed",,tmpc->aux1,tmpc->aux2,tmpc->flags);
+      break;
+    case JOBT_CALL:
+      QueRem(tmpc);
+      LBts(&tmpc->flags,JOBf_DISPATCHED);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      SetRFlags(run_flags);
+      LBtr(&Fs->task_flags,TASKf_IDLE);
+      try
+              tmpc->res=(*tmpc->addr)(tmpc->fun_arg);
+      catch
+        Fs->catch_except=TRUE;
+      SetRFlags(old_flags);
+      break;
+    case JOBT_EXE_STR:
+      QueRem(tmpc);
+      LBts(&tmpc->flags,JOBf_DISPATCHED);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      SetRFlags(run_flags);
+      LBtr(&Fs->task_flags,TASKf_IDLE);
+      try
+              tmpc->res=ExePrint("%s",tmpc->aux_str);
+      catch
+        Fs->catch_except=TRUE;
+      SetRFlags(old_flags);
+      break;
+    default:
+      res=JOB_DONE;
+  }
+  if (res) {
+    if (master=tmpc->master_task) {
+      if (!Bt(&flags,JOBf_FREE_ON_COMPLETE)) {
+        CLI
+        while (LBts(&master->srv_ctrl.flags,JOBCf_LOCKED))
+          PAUSE
+        QueIns(tmpc,master->srv_ctrl.last_done);
+        LBts(&tmpc->flags,JOBf_DONE);
+        LBtr(&master->srv_ctrl.flags,JOBCf_LOCKED);
+        SetRFlags(old_flags);
+      }
+      if (Bt(&flags,JOBf_FOCUS_MASTER) &&
+            !Bt(&master->win_inhibit,WIf_SELF_FOCUS))
+        sys_focus_task=master;
+      if (Bt(&flags,JOBf_WAKE_MASTER))
+        Suspend(master,FALSE);
+    }
+    if (Bt(&flags,JOBf_FREE_ON_COMPLETE))
+      JobDel(tmpc);
+    else if (!master) {
+      CLI
+      while (LBts(&ctrl->flags,JOBCf_LOCKED))
+        Yield;
+      QueIns(tmpc,ctrl->last_done);
+      LBts(&tmpc->flags,JOBf_DONE);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      SetRFlags(old_flags);
+    }
+  }
+  return res;
+}
+
+I64 JobsHndlr(I64 run_flags,CTask *task=NULL)
+{//Handle all waiting cmds and return.
+  I64 cnt=0,old_flags=GetRFlags;
+  if (!task) task=Fs;
+  while (TRUE) {
+    CLI
+    while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+      PAUSE
+    if (task->srv_ctrl.next_waiting!=&task->srv_ctrl)
+      switch (JobRunOne(run_flags,&task->srv_ctrl)) {
+        case JOB_CONT:
+          cnt++;
+          break;
+        case JOB_EXIT:
+          Exit;
+        case JOB_DONE:
+          goto jh_done;
+      }
+    else
+      goto jh_done;
+  }
+jh_done:
+  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  SetRFlags(old_flags);
+  return cnt;
+}
+
+I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL)
+{//Execute code in PopUp task.
+  I64 res;
+  CJob *tmpc;
+  CTask *task=Spawn(&SrvCmdLine,NULL,"Servant",,parent);
+  if (!parent) {
+    TaskExe(task,parent,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+    if (_pu_task) *_pu_task=task;
+    return 0;
+  } else {
+    Fs->popup_task=task;
+    tmpc=TaskExe(task,parent,buf,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+    if (_pu_task) *_pu_task=task;
+    JobResScan(tmpc,&res);
+    Fs->popup_task=NULL;
+    Kill(task);
+    if (_pu_task) *_pu_task=NULL;
+    return res;
+  }
+}
+
+I64 PopUpPrint(U8 *fmt,...)
+{//Execute code in PopUp task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res;
+  res=PopUp(buf,Fs);
+  Free(buf);
+  return res;
+}
+
+I64 Adam(U8 *fmt,...)
+{//Make adam_task execute code.
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CJob *tmpc;
+  if (Fs==adam_task) {
+    tmpc=TaskExe(adam_task,Fs,buf,0);
+    JobsHndlr(GetRFlags);
+  } else {
+    TaskWait(adam_task);
+    tmpc=TaskExe(adam_task,Fs,buf,1<<JOBf_WAKE_MASTER);
+  }
+  JobResScan(tmpc,&res);
+  Free(buf);
+  return res;
+}
+
+U0 AdamLog(U8 *fmt,...)
+{//Display text in adam_task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (Fs==adam_task)
+    "%s",buf;
+  else if (!IsSingleUser)
+    Adam("\"%%s\",%d;",buf);
+  Free(buf);
+}
+
+U0 AdamErr(U8 *fmt,...)
+{//Display red blinking Err text in adam_task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),
+        *st=MStrPrint(ST_ERR_ST "%s",buf);
+  if (Fs==adam_task)
+    "%s",st;
+  else if (!IsSingleUser)
+    Adam("\"%%s\",%d;",st);
+  Free(st);
+  Free(buf);
+}
+
+U0 XTalk(CTask *task,U8 *fmt,...)
+{//Sends text to other task. See ::/Misc/OSTestSuite.HC.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf),
+        *st2=MStrPrint("\"%%s\",%d;Free(%d);",st,st);
+  TaskText(task,NULL,st2,0);
+  Free(st2);
+  Free(buf);
+}
+
+U0 XTalkWait(CTask *task,U8 *fmt,...)
+{//Send text to other task and wait for it to idle.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf),
+        *st2=MStrPrint("\"%%s\",%d;Free(%d);",st,st);
+  TaskText(task,NULL,st2,0);
+  Free(st2);
+  Free(buf);
+  TaskWait(task);
+}
+
+U0 InStr(U8 *fmt,...)
+{//Send InFile code to self.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK))
+    ExePrint("%s",buf);
+  else
+    TaskText(Fs,NULL,buf,1<<JOBf_HIGHEST_PRIORITY);
+  Free(buf);
+}
+
+U0 InFile(U8 *filename)
+{//Send InFile code file to self.
+  U8 *name=ExtDft(filename,"IN.Z");
+  InStr("Cd(\"%C:%s\");;#include \"%s\"",
+        Drv2Let(Fs->cur_dv),Fs->cur_dir,name);
+  Free(name);
+}
+
+U0 In(U8 *fmt,...)
+{//Send text to own input buffer. See ::/Demo/AcctExample/TOS/TOSDistro.HC.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf);
+  InStr("\"%%s\",%d;Free(%d);",st,st);
+  Free(buf);
+}
+
+U0 XTalkStr(CTask *task,U8 *fmt,...)
+{//Send InFile code to other task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  TaskText(task,NULL,buf,0);
+  Free(buf);
+}
+
+U0 XTalkStrWait(CTask *task,U8 *fmt,...)
+{//Send InFile code to other task and wait for it to idle.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  TaskText(task,NULL,buf,0);
+  Free(buf);
+  TaskWait(task);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KCfg.HC.HTML b/public/Wb/Home/Src/Kernel/KCfg.HC.HTML new file mode 100755 index 0000000..522a480 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KCfg.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+//This is run in a #exe{}.
+
+U8 *kernel_cfg_options="MemInit\0HeapInit\0VarInit\0StaffMode\0"
+"HomeDir\0NoMP\0TextMode\0DontProbe\0MountIDEAuto\0DbgDistro\0Help\0";
+
+#define CFG_MEM_INIT            0
+#define CFG_HEAP_INIT           1
+#define CFG_VAR_INIT            2
+#define CFG_STAFF_MODE          3
+#define CFG_HOME_DIR            4
+#define CFG_NO_MP               5
+#define CFG_TEXT_MODE           6
+#define CFG_DONT_PROBE          7
+#define CFG_MOUNT_IDE_AUTO      8
+#define CFG_DBG_DISTRO  9
+#define CFG_OPTIONS_NUM         10
+
+#define CFG_HELP                10
+
+class CKCfg
+{
+  U8 *dsk_cache_size_exp;
+  CDoc *add_dev;
+  U8 *dbg_distro_file,*dbg_distro_start;
+  U8 *home_dir;
+  Bool opts[CFG_OPTIONS_NUM];
+  U8 mem_init_val,heap_init_val,var_init_val,
+        boot_drv_let,mount_ide_auto_hd_let,mount_ide_auto_cd_let;
+};
+
+CDoc *KCfgAddDev(CKCfg *c)
+{
+  I64 ch;
+  CDoc *doc=DocNew;
+  "\n\nIn anticipation of the drives you will\n"
+        "define shortly, enter the drive letter\n"
+        "of the drive with the account directory.\n"
+        "\n($PURPLE$<ENTER>$FG$ for cur drv) Boot Drv:";
+  ch=Let2Let(GetChar);
+  if ('A'<=ch<='Z')
+    c->boot_drv_let=ch;
+  else
+    c->boot_drv_let=Drv2Let(Fs->cur_dv);
+  "\n\n$BK,1$$PURPLE$Mount drives so they will be present when "
+        "you boot.$FG$$BK,0$\n";
+  Mount2(c->boot_drv_let,doc,FALSE);
+  return doc;
+}
+
+U0 KCfgOptions(CKCfg *c)
+{
+  I64 i;
+  U8 *st=NULL,*st2,*st3;
+  Bool state;
+  do {
+    Free(st);
+    for (i=0;i<CFG_OPTIONS_NUM;i++)
+      if (i==CFG_HOME_DIR)
+        "$PURPLE$%13tz$FG$:\"%s\"\n",i,kernel_cfg_options,c->home_dir;
+      else
+        "$PURPLE$%13tz$FG$:%Z\n",i,kernel_cfg_options,c->opts[i],"ST_OFF_ON";
+    "\nType '$PURPLE$Help$FG$' for help.\n";
+    st=GetStr("Option ($PURPLE$<ENTER>$FG$ when done):","");
+    i=LstMatch(st,kernel_cfg_options,LMF_IGNORE_CASE);
+    if (i==CFG_HELP)
+      "\n"
+            "$PURPLE$MemInit$FG$ Initializes memory above 0x100000 "
+            "to a val at boot.\n"
+            "$PURPLE$HeapInit$FG$ Initializes MAlloc() memory to a val.\n"
+            "$PURPLE$VarInit$FG$ Initializes glbl var memory to a val.\n"
+            "$PURPLE$HomeDir$FG$ Set home dir.\n"
+            "$PURPLE$NoMP$FG$ No multicore.\n"
+            "$PURPLE$TextMode$FG$ Text Mode (requires hard reboot).\n"
+            "$PURPLE$DontProbe$FG$ Just prompt CD/DVD ports, don't probe.\n"
+            "$PURPLE$MountIDEAuto$FG$ Auto Mount IDE drives to 'C' and 'T'.\n"
+            "$PURPLE$DbgDistro$FG$ Include RAM Drv in Kernel.BIN.\n"
+            "\n";
+    else
+      if (0<=i<CFG_OPTIONS_NUM) {
+        state=c->opts[i]=!c->opts[i];
+        switch (i) {
+          case CFG_MEM_INIT:
+            if (state)
+              c->mem_init_val=GetI64("Val (0-255):",255,0,255);
+            break;
+          case CFG_HEAP_INIT:
+            if (state)
+              c->heap_init_val=GetI64("Val (0-255):",255,0,255);
+            break;
+          case CFG_VAR_INIT:
+            if (state)
+              c->var_init_val=GetI64("Val (0-255):",255,0,255);
+            break;
+          case CFG_HOME_DIR:
+            st2=GetStr("Home Dir(\"%s\"):",c->home_dir);
+            if (!*st2)
+              st2=StrNew("::/Home");
+            else if (st2[1]!=':') {
+              st3=MStrPrint("::%s",st2);
+              Free(st2);
+              st2=st3;
+            }
+            Free(c->home_dir);
+            c->home_dir=st2;
+            if (StrCmp(c->home_dir,"::/Home"))
+              c->opts[i]=TRUE;
+            else
+              c->opts[i]=FALSE;
+            break;
+          case CFG_MOUNT_IDE_AUTO:
+            if (state) {
+              "First HD Drive Let:";
+              c->mount_ide_auto_hd_let=Let2Let(GetChar);
+              if (!('A'<=c->mount_ide_auto_hd_let<='Z'))
+                c->mount_ide_auto_hd_let=0;
+              '\n';
+              if (c->mount_ide_auto_hd_let)
+                "First HD Drive:%C\n",c->mount_ide_auto_hd_let;
+              else
+                "First HD Drive:%C\n",'C';
+
+              "First CD Drive Let:";
+              c->mount_ide_auto_cd_let=Let2Let(GetChar);
+              if (!('A'<=c->mount_ide_auto_cd_let<='Z'))
+                c->mount_ide_auto_cd_let=0;
+              '\n';
+              if (c->mount_ide_auto_cd_let)
+                "First CD Drive:%C\n",c->mount_ide_auto_cd_let;
+              else
+                "First CD Drive:%C\n",'T';
+            } else {
+              c->mount_ide_auto_hd_let=0;
+              c->mount_ide_auto_cd_let=0;
+            }
+            break;
+          case CFG_DBG_DISTRO:
+            Free(c->dbg_distro_file);
+            c->dbg_distro_file=0;
+            c->dbg_distro_start=0;
+            if (state) {
+              c->dbg_distro_file=GetStr("Dbg Distro File:");
+              c->dbg_distro_start=GetI64("Dbg Distro Start:");
+            }
+            break;
+        }
+      }
+  } while (*st);
+  Free(st);
+}
+
+CKCfg *KCfgNew()
+{
+  CKCfg *c=CAlloc(sizeof(CKCfg));
+
+  c->add_dev=KCfgAddDev(c);
+  c->home_dir=StrNew("::/Home");
+  c->dsk_cache_size_exp=GetStr(
+        "Disk Cache Size in Bytes,\n"
+        "gets rounded-up funny,\n"
+        "($PURPLE$<ENTER>$FG$ will use default.):",
+        "Scale2Mem(0x80000,0x8000000)");
+  KCfgOptions(c);
+  return c;
+}
+ 
+U0 KCfgDel(CKCfg *c)
+{
+  DocDel(c->add_dev);
+  Free(c->dbg_distro_file);
+  Free(c->home_dir);
+  Free(c->dsk_cache_size_exp);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KDataTypes.HC.HTML b/public/Wb/Home/Src/Kernel/KDataTypes.HC.HTML new file mode 100755 index 0000000..04bfbf0 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KDataTypes.HC.HTML @@ -0,0 +1,354 @@ + + + + + + + + + + + +
+U0 LinkedLstDel(U8 **_lst)
+{//Free entire linked-list.
+  U8 **tmpl;
+  while (_lst) {
+    tmpl=*_lst;
+    Free(_lst);
+    _lst=tmpl;
+  }
+}
+
+U8 *LinkedLstCopy(U8 **_lst,CTask *mem_task=NULL)
+{//MAlloc ident copy of entire linked-list.
+  U8 *res=NULL,**tmpl=&res;
+  while (_lst) {
+    tmpl=*tmpl=MAllocIdent(_lst,mem_task);
+    _lst=*_lst;
+  }
+  return res;
+}
+
+I64 LinkedLstCnt(U8 **_lst)
+{//Count of nodes in linked-list.
+  I64 res=0;
+  while (_lst) {
+    res++;
+    _lst=*_lst;
+  }
+  return res;
+}
+
+I64 LinkedLstSize(U8 **_lst)
+{//Mem size of all nodes in linked-list.
+  I64 res=0;
+  while (_lst) {
+    res+=MSize2(_lst);
+    _lst=*_lst;
+  }
+  return res;
+}
+
+U0 QueDel(CQue *head,Bool querem=FALSE)
+{//Free entries in queue, not head.
+  CQue *tmpq=head->next,*tmpq1;
+  while (tmpq!=head) {
+    tmpq1=tmpq->next;
+    if (querem)
+      QueRem(tmpq);
+    Free(tmpq);
+    tmpq=tmpq1;
+  }
+}
+
+CQue *QueCopy(CQue *head,CTask *mem_task=NULL)
+{//MAlloc ident copy of entire queue and head.
+  CQue *res=MAllocIdent(head,mem_task),*tmpq=head->next,*tmpq1;
+  QueInit(res);
+  while (tmpq!=head) {
+    tmpq1=MAllocIdent(tmpq,mem_task);
+    QueIns(tmpq1,res->last);
+    tmpq=tmpq->next;
+  }
+  return res;
+}
+
+I64 QueCnt(CQue *head)
+{//Count of nodes in queue, not head.
+  CQue *tmpq=head->next;
+  I64 res=0;
+  while (tmpq!=head) {
+    res++;
+    tmpq=tmpq->next;
+  }
+  return res;
+}
+
+I64 QueSize(CQue *head)
+{//Mem size of all nodes in queue, not head.
+  CQue *tmpq=head->next;
+  I64 res=0;
+  while (tmpq!=head) {
+    res+=MSize2(tmpq);
+    tmpq=tmpq->next;
+  }
+  return res;
+}
+
+CQueVectU8 *QueVectU8New(I64 min_idx=0)
+{//Create new queue vecter.
+  CQueVectU8 *res=MAlloc(sizeof(CQueVectU8));
+  QueInit(res);
+  res->total_cnt=res->node_cnt=0;
+  res->min_idx=min_idx;
+  return res;
+}
+
+U0 QueVectU8Put(CQueVectU8 *v,I64 idx,U8 ch)
+{//Put U8 at idx i.
+  CQueVectU8 *tmpv;
+  idx-=v->min_idx;
+  if (idx<0) return;
+  if (idx<v->total_cnt) {
+    tmpv=v;
+    do {
+      idx-=tmpv->node_cnt;
+      if (idx<0) {
+        tmpv->body[idx+tmpv->node_cnt]=ch;
+        return;
+      }
+      tmpv=tmpv->next;
+    } while (tmpv!=v);
+  } else
+    idx-=v->total_cnt;
+
+  while (TRUE) {
+    tmpv=v->last;
+    if (tmpv->node_cnt>=QUE_VECT_U8_CNT) {
+      tmpv=MAlloc(sizeof(CQueVectU8));
+      tmpv->node_cnt=0;
+      QueIns(tmpv,v->last);
+    }
+    if (idx--) {
+      tmpv->body[tmpv->node_cnt++]=0;
+      v->total_cnt++;
+    } else {
+      tmpv->body[tmpv->node_cnt++]=ch;
+      v->total_cnt++;
+      break;
+    }
+  }
+}
+
+U0 QueVectU8Del(CQueVectU8 *v)
+{//Free entire queue vector.
+  if (v) {
+    QueDel(v);
+    Free(v);
+  }
+}
+
+I64 QueVectU8Get(CQueVectU8 *v,I64 idx)
+{//Get U8 at idx i.
+  CQueVectU8 *tmpv;
+  idx-=v->min_idx;
+  if (!(0<=idx<v->total_cnt)) return 0;
+  tmpv=v;
+  do {
+    idx-=tmpv->node_cnt;
+    if (idx<0)
+      return tmpv->body[idx+tmpv->node_cnt];
+    tmpv=tmpv->next;
+  } while (tmpv!=v);
+  return 0;
+}
+
+CFifoU8 *FifoU8New(I64 size,CTask *mem_task=NULL)
+{//Create new fifo.
+  CFifoU8 *f;
+  if (!mem_task) mem_task=Fs;
+  f=MAlloc(sizeof(CFifoU8),mem_task);
+  f->buf=MAlloc(size,mem_task);
+  f->mask=size-1;
+  f->in_ptr=0;
+  f->out_ptr=0;
+  return f;
+}
+
+U0 FifoU8Del(CFifoU8 *f)
+{//Free fifo.
+  Free(f->buf);
+  Free(f);
+}
+
+Bool FifoU8Ins(CFifoU8 *f,U8 b)
+{//Insert U8 into fifo.
+  I64 new_in_ptr;
+  PUSHFD
+  CLI
+  new_in_ptr=(f->in_ptr+1)&f->mask;
+  if (new_in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    f->buf[f->in_ptr]=b;
+    f->in_ptr=new_in_ptr;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoU8Rem(CFifoU8 *f,U8 *_b)
+{//Remove U8 from fifo.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_b=f->buf[f->out_ptr];
+    f->out_ptr=(f->out_ptr+1)&f->mask;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoU8Peek(CFifoU8 *f,U8 *_b)
+{//Peek at front of fifo and don't remove.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_b=f->buf[f->out_ptr];
+    POPFD
+    return TRUE;
+  }
+}
+
+U0 FifoU8Flush(CFifoU8 *f)
+{//Flush fifo getting rid of all U8's.
+  PUSHFD
+  CLI
+  f->out_ptr=f->in_ptr;
+  POPFD
+}
+
+I64 FifoU8Cnt(CFifoU8 *f)
+{//Count of U8's in fifo.
+  I64 res;
+  PUSHFD
+  CLI
+  if (f->out_ptr>f->in_ptr)
+    res=f->mask+1-(f->out_ptr-f->in_ptr);
+  else
+    res=f->in_ptr-f->out_ptr;
+  POPFD
+  return res;
+}
+
+CFifoI64 *FifoI64New(I64 size,CTask *mem_task=NULL)
+{//Create new fifo.
+  CFifoI64 *f;
+  if (!mem_task) mem_task=Fs;
+  f=MAlloc(sizeof(CFifoI64),mem_task);
+  f->buf=MAlloc(size*sizeof(I64),mem_task);
+  f->mask=size-1;
+  f->in_ptr=0;
+  f->out_ptr=0;
+  return f;
+}
+
+U0 FifoI64Del(CFifoI64 *f)
+{//Free fifo.
+  Free(f->buf);
+  Free(f);
+}
+
+Bool FifoI64Ins(CFifoI64 *f,I64 q)
+{//Insert I64 into fifo.
+  I64 new_in_ptr;
+  PUSHFD
+  CLI
+  new_in_ptr=(f->in_ptr+1)&f->mask;
+  if (new_in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    f->buf[f->in_ptr]=q;
+    f->in_ptr=new_in_ptr;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoI64Rem(CFifoI64 *f,I64 *_q)
+{//Remove I64 from fifo.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_q=f->buf[f->out_ptr];
+    f->out_ptr=(f->out_ptr+1)&f->mask;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoI64Peek(CFifoI64 *f,I64 *_q)
+{//Peek at front of fifo and don't remove.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_q=f->buf[f->out_ptr];
+    POPFD
+    return TRUE;
+  }
+}
+
+U0 FifoI64Flush(CFifoI64 *f)
+{//Flush fifo getting rid of all I64's.
+  PUSHFD
+  CLI
+  f->out_ptr=f->in_ptr;
+  POPFD
+}
+
+I64 FifoI64Cnt(CFifoI64 *f)
+{//Count of I64's in fifo.
+  I64 res;
+  PUSHFD
+  CLI
+  if (f->out_ptr>f->in_ptr)
+    res=f->mask+1-(f->out_ptr-f->in_ptr);
+  else
+    res=f->in_ptr-f->out_ptr;
+  POPFD
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KDate.HC.HTML b/public/Wb/Home/Src/Kernel/KDate.HC.HTML new file mode 100755 index 0000000..be3ae18 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KDate.HC.HTML @@ -0,0 +1,227 @@ + + + + + + + + + + + +
+//See ::/Doc/TimeDate.DD
+
+U16 mon_start_days1[12]={
+0,31,59,90,120,151,181,212,243,273,304,334};
+U16 mon_start_days2[12]={
+0,31,60,91,121,152,182,213,244,274,305,335};
+
+I64 YearStartDate(I64 year)
+{//32-bit day since AD 0, given year number.
+  I64 y1=year-1,yd4000=y1/4000,yd400=y1/400,yd100=y1/100,yd4=y1/4;
+  return year*365+yd4-yd100+yd400-yd4000;
+}
+
+CDate Struct2Date(CDateStruct *_ds)
+{//Cvt CDateStruct to CDate.
+  CDate cdt;
+  I64 i1,i2;
+  i1=YearStartDate(_ds->year);
+  i2=YearStartDate(_ds->year+1);
+  if (i2-i1==365)
+    i1+=mon_start_days1[_ds->mon-1];
+  else
+    i1+=mon_start_days2[_ds->mon-1];
+  cdt.date=i1+_ds->day_of_mon-1;
+  cdt.time=(_ds->sec10000+100*(_ds->sec100+100*(_ds->sec
+        +60*(_ds->min+60*_ds->hour))))<<21/(15*15*3*625);
+  return cdt;
+}
+
+I64 DayOfWeek(I64 i)
+{//Day of week, given 32-bit day since AD 0.
+  i+=CDATE_BASE_DAY_OF_WEEK;
+  if (i>=0)
+    return i % 7;
+  else
+    return 6-(6-i)%7;
+}
+
+U0 Date2Struct(CDateStruct *_ds,CDate cdt)
+{//Cvt CDate to CDateStruct.
+  I64 i,k,date=cdt.date;
+  _ds->day_of_week=DayOfWeek(date);
+  _ds->year=(date+1)*100000/CDATE_YEAR_DAYS_INT;
+  i=YearStartDate(_ds->year);
+  while (i>date) {
+    _ds->year--;
+    i=YearStartDate(_ds->year);
+  }
+  date-=i;
+  if (YearStartDate(_ds->year+1)-i==365) {
+    k=0;
+    while (date>=mon_start_days1[k+1] && k<11)
+      k++;
+    date-=mon_start_days1[k];
+  } else {
+    k=0;
+    while (date>=mon_start_days2[k+1] && k<11)
+      k++;
+    date-=mon_start_days2[k];
+  }
+  _ds->mon=k+1;
+  _ds->day_of_mon=date+1;
+  k=(625*15*15*3*cdt.time)>>21+1;
+  _ds->sec10000=ModU64(&k,100);
+  _ds->sec100=ModU64(&k,100);
+  _ds->sec=ModU64(&k,60);
+  _ds->min=ModU64(&k,60);
+  _ds->hour  =k;
+}
+
+I64 FirstDayOfMon(I64 i)
+{//First day of month, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.day_of_mon=1;
+  cdt=Struct2Date(&ds);
+  return cdt.date;
+}
+
+I64 LastDayOfMon(I64 i)
+{//Last day of month, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.mon++;
+  if (ds.mon==13) {
+    ds.mon=0;
+    ds.year++;
+  }
+  ds.day_of_mon=1;
+  cdt=Struct2Date(&ds);
+  return cdt.date-1;
+}
+
+I64 FirstDayOfYear(I64 i)
+{//First day of year, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.day_of_mon=1;
+  ds.mon=1;
+  cdt=Struct2Date(&ds);
+  return cdt.date;
+}
+
+I64 LastDayOfYear(I64 i)
+{//Last day of year, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.day_of_mon=1;
+  ds.mon=1;
+  ds.year++;
+  cdt=Struct2Date(&ds);
+  return cdt.date-1;
+}
+
+I64 Bcd2Bin(U64 b)
+{
+  I64 i,res=0;
+  for (i=0;i<16;i++) {
+    res=res*10+b>>60;
+    b<<=4;
+  }
+  return res;
+}
+
+U0 NowDateTimeStruct(CDateStruct *_ds)
+{
+  I64 i;
+  U8 *b=_ds;
+  Bool is_bcd;
+
+  MemSet(_ds,0,sizeof(CDateStruct));
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_SYS_DATE],0))
+    PAUSE
+
+  OutU8(0x70,0x0A);
+  do {
+    while (InU8(0x71) & 0x80)
+      PAUSE
+
+    OutU8(0x70,0);
+    b[2]=InU8(0x71);
+    OutU8(0x70,2);
+    b[3]=InU8(0x71);
+    OutU8(0x70,4);
+    b[4]=InU8(0x71);
+
+    OutU8(0x70,6);
+    b[5]=InU8(0x71);
+    OutU8(0x70,7);
+    b[6]=InU8(0x71);
+    OutU8(0x70,8);
+    b[7]=InU8(0x71);
+    OutU8(0x70,9);
+    b[8]=InU8(0x71);
+
+    OutU8(0x70,0x0A);
+  } while (InU8(0x71) & 0x80);
+
+  OutU8(0x70,0x0B);
+  if (InU8(0x71) & 4)
+    is_bcd=FALSE;
+  else
+    is_bcd=TRUE;
+
+  LBtr(&sys_semas[SEMA_SYS_DATE],0);
+  POPFD
+  if (is_bcd)
+    for (i=2;i<9;i++)
+      b[i]=Bcd2Bin(b[i]);
+
+  if (_ds->year>255)    _ds->year=255;
+  _ds->year+=2000;
+  if (_ds->mon>12)      _ds->mon=12;
+  if (_ds->day_of_mon>31) _ds->day_of_mon=31;
+  if (_ds->day_of_week>6) _ds->day_of_week=6;
+  if (_ds->hour>23)     _ds->hour=23;
+  if (_ds->min>59)      _ds->min=59;
+  if (_ds->sec>59)      _ds->sec=59;
+}
+
+CDate Now()
+{//Current datetime.
+  CDateStruct ds;
+  NowDateTimeStruct(&ds);
+  return Struct2Date(&ds)-local_time_offset;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KDbg.HC.HTML b/public/Wb/Home/Src/Kernel/KDbg.HC.HTML new file mode 100755 index 0000000..9570b0a --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KDbg.HC.HTML @@ -0,0 +1,683 @@ + + + + + + + + + + + +
+Bool ChkPtr(U8 *ptr)
+{//Check if addr is valid ptr.
+  if (mem_heap_base<=ptr<=mem_mapped_space) {
+    if (*MemPageTable(ptr)&1)
+      return TRUE;
+    else
+      return FALSE;
+  } else if (ptr<mem_boot_base)
+    return FALSE;
+  else if (ptr<VGAM_GRAPHICS)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool ChkCodePtr(U8 *ptr)
+{//Check if addr is valid code addr.
+  if (mem_heap_base<=ptr<=mem_heap_limit) {
+    if (*MemPageTable(ptr)&1)
+      return TRUE;
+    else
+      return FALSE;
+  } else if (ptr<mem_boot_base)
+    return FALSE;
+  else if (ptr<VGAM_GRAPHICS)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool ChkOnStk(U8 *ptr,CTask *task=NULL)
+{//Check if addr is valid stk addr.
+  Bool res=FALSE;
+  PUSHFD
+  CLI
+  if (task) {
+    if (&task->stk->stk_base<=ptr<=
+          (&task->stk->stk_base)(U8 *)+task->stk->stk_size)
+      res=TRUE;
+  } else if (mem_heap_base<=ptr<=mem_heap_limit)
+    res=TRUE;
+  POPFD
+  return res;
+}
+
+I64 UnusedStk(CTask *task=NULL)
+{//Count of usused bytes in task's stk.
+  I64 res;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (task==Fs)
+    res=GetRSP()(U8 *)-(&task->stk->stk_base)(U8 *);
+  else
+    res=task->rsp(U8 *)-(&task->stk->stk_base)(U8 *);
+  POPFD
+  return res;
+}
+
+U8 *Caller(I64 num=1)
+{//Returns the addr of the fun which called this one,
+//or the caller of the caller, etc.
+  U8 **rbp=GetRBP,**ptr;
+  while (num--) {
+    if (rbp>=*rbp)
+      return NULL;
+    rbp=*rbp;
+    if (!ChkOnStk(rbp,Fs))
+      return NULL;
+  }
+  ptr=rbp+1;
+  return *ptr;
+}
+
+U8 *TaskCaller(CTask *task=NULL,I64 num=0,Bool saved_context=FALSE)
+{//Fetches addr of Nth caller on task's stk.
+  U8 **ptr,**rbp,**rsp;
+  if (!task) task=Fs;
+  if (!saved_context && task==Fs)
+    return Caller(num+1);
+  if (!TaskValidate(task))
+    return NULL;
+  rbp=task->rbp;
+  rsp=task->rsp;
+  if (num) {
+    while (ChkOnStk(rbp,task)) {
+      ptr=rbp+1;
+      if (! --num)
+        return *ptr;
+      if (rbp>=*rbp)
+        break;
+      rbp=*rbp;
+    }
+    return NULL;
+  } else {
+    if (task->rip==_RET)
+      return *rsp;
+    else
+      return task->rip;
+  }
+}
+#define STK_REP_LEN     32
+
+U0 StkRep(CTask *task=NULL)
+{//Reports whats on the stk.
+  I64 i,j,addr,
+        **rbp,**rsp,*my_rsp[STK_REP_LEN];
+  CHashTable *old_hash=Fs->hash_table;
+  if (!task) task=Fs;
+  if (!TaskValidate(task))
+    return;
+  PUSHFD
+  CLI
+  if (task==Fs) {
+    rbp=GetRBP;
+    rsp=rbp+3;
+    rbp=*rbp;
+  } else {
+    rsp=task->rsp;
+    rbp=task->rbp;
+  }
+  if (task->rip==_RET)
+    addr=*rsp;
+  else
+    addr=task->rip;
+  MemCpy(my_rsp,rsp,STK_REP_LEN*sizeof(U8 *));
+  POPFD
+  Fs->hash_table=task->hash_table;
+  for (i=0;i<STK_REP_LEN;i++) {
+    "%08X [RSP+%04X]: %016X ",rsp+i,
+          i*sizeof(U8 *),my_rsp[i];
+    while (TRUE) {
+      if (!(&task->stk->stk_base<=rbp<
+            (&task->stk->stk_base)(U8 *)+task->stk->stk_size))
+        break;
+      j=rbp-rsp;
+      if (j>=i)
+        break;
+      addr=my_rsp[j+1];
+      if (rbp>=my_rsp[j])
+        break;
+      rbp=my_rsp[j];
+    }
+    if (my_rsp[i]==addr)
+      "$RED$";
+    "%P$FG$\n",my_rsp[i];
+  }
+  '\n';
+  Fs->hash_table=old_hash;
+}
+
+U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL)
+{//Prints a report of calling routines.
+  I64 **ptr;
+  if (!task) task=Fs;
+  if (!rbp) {
+    if (task==Fs)
+      rbp=GetRBP;
+    else
+      rbp=task->rbp;
+  }
+  "CallerRep:\n";
+  while (ChkOnStk(rbp,task)) {
+    ptr=rbp+1;
+    "%08X:%08tX:%P\n",ptr,*ptr,*ptr;
+    if (rbp>=*rbp)
+      break;
+    rbp=*rbp;
+  }
+}
+
+U0 D(U8 *addr,I64 cnt=0x80,Bool show_offset=TRUE)
+{//Dump mem, showing offsets.
+//See DocD() for a live dump.
+  I64 i,j,ch;
+  U8 *ptr=addr;
+  while (cnt) {
+    if (show_offset)
+      "%08X ",ptr-addr;
+    else
+      "%010X ",ptr;
+    if (cnt>16)
+      j=16;
+    else
+      j=cnt;
+    for (i=0;i<j;i++)
+      "%02X ",ptr[i];
+    for (;i<16;i++)
+      "   ";
+    for (i=0;i<j;i++) {
+      ch=ptr[i];
+      if (ch<CH_SHIFT_SPACE || ch==CH_BACKSPACE)
+        ch='.';
+      '' ch;
+      if (ch=='$')
+        '' ch;
+    }
+    '\n';
+    cnt-=j;
+    ptr+=j;
+  }
+}
+
+U0 Dm(U8 *addr,I64 cnt=0x80)
+{//Show mem addr, not offsets.
+  D(addr,cnt,FALSE);
+}
+
+U0 Da(U8 **addr,I64 cnt=0x10)
+{//Dump mem, showing symbolic addresses.
+  while (cnt-->0) {
+    "%08X:%08X,%P\n",addr,*addr,*addr;
+    addr++;
+  }
+}
+
+U0 RawPrint(I64 mS=100,U8 *fmt,...)
+{//Print using Raw scrn output for a length of time.
+//Your heap must be good.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  Bool old_raw,old_input_filter;
+  PUSHFD
+  CLI
+  old_raw=Raw(ON);
+  old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  "%s",buf;
+  Busy(mS<<10);
+  POPFD
+  LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
+  Raw(old_raw);
+  Free(buf);
+}
+
+U0 RawD(I64 mS=100,U8 *addr,I64 cnt=0x80)
+{//Dumps a block of mem using Raw
+//scrn output for a fixed length
+  //of time.
+  Bool old_raw,old_input_filter;
+  PUSHFD
+  CLI
+  old_raw=Raw(ON);
+  old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  D(addr,cnt);
+  Busy(mS<<10);
+  POPFD
+  LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
+  Raw(old_raw);
+}
+
+U0 RawDm(I64 mS=100,U8 *addr,I64 cnt=0x80)
+{//Dumps a block of mem using Raw
+//scrn output for a fixed length
+  //of time.
+  Bool old_raw,old_input_filter;
+  PUSHFD
+  CLI
+  old_raw=Raw(ON);
+  old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  Dm(addr,cnt);
+  Busy(mS<<10);
+  POPFD
+  LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
+  Raw(old_raw);
+}
+
+I64 *TaskRegAddr(CTask *task,I64 reg_num)
+{
+  switch (reg_num) {
+    case REG_RAX: return &task->rax;
+    case REG_RCX: return &task->rcx;
+    case REG_RDX: return &task->rdx;
+    case REG_RBX: return &task->rbx;
+    case REG_RSP: return &task->rsp;
+    case REG_RBP: return &task->rbp;
+    case REG_RSI: return &task->rsi;
+    case REG_RDI: return &task->rdi;
+    case 8 : return &task->r8;
+    case 9 : return &task->r9;
+    case 10: return &task->r10;
+    case 11: return &task->r11;
+    case 12: return &task->r12;
+    case 13: return &task->r13;
+    case 14: return &task->r14;
+    case 15: return &task->r15;
+  }
+  return NULL;
+}
+
+#define RAWDR_COL       40
+
+U0 RawDr(CTask *task=NULL)
+{
+  I64 i,j,old_col=text.raw_col;
+  Bool old_raw=Raw(ON);
+  U8 buf[200];
+
+  if (!task) task=Fs;
+
+  for (i=0;i<16;i++) {
+    text.raw_col=i*text.cols+RAWDR_COL;
+    ".%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAddr(task,i);
+  }
+
+  text.raw_col=i++*text.cols+RAWDR_COL;
+  ".RIP:%016X\n",task->rip;
+
+  text.raw_col=i++*text.cols+RAWDR_COL;
+  ".%-*tp\n",text.cols-(RAWDR_COL+1)-1,Fs->rip;
+
+  text.raw_col=i++*text.cols+RAWDR_COL;
+  '.';
+  if (Bt(&sys_run_level,RLf_COMPILER)) {
+    j=Fs->rip;
+    Ui(buf,&j,,,TRUE);
+    "%s",buf;
+  } else
+    '\n';
+
+  text.raw_col=i*text.cols+RAWDR_COL;
+  '.';
+  for (j=0;j<text.cols-RAWDR_COL-1;j++)
+    '.';
+
+  text.raw_col=old_col;
+  Raw(old_raw);
+}
+
+U0 Dr(CTask *task=NULL)
+{//Dump regs
+  I64 i;
+  if (!task) task=Fs;
+  for (i=0;i<16;i++)
+    "%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAddr(task,i);
+  "RIP:%016X\n",task->rip;
+}
+
+U8 *SysGetStr2(I64)
+{
+  U8 buf[512];
+  GetS(buf,512,FALSE);
+  return StrNew(buf);
+}
+
+CBpt *BptFind(U8 *needle_addr,CTask *haystack_task=NULL,Bool rem=FALSE)
+{
+  CBpt *res=NULL,*tmpb,*tmpb1,*tmpb2;
+  if (!haystack_task) haystack_task=Fs;
+  PUSHFD
+  CLI
+  tmpb1=&haystack_task->bpt_lst;
+  tmpb=haystack_task->bpt_lst;
+  while (tmpb) {
+    tmpb2=tmpb->next;
+    if (tmpb->addr==needle_addr) {
+      res=tmpb;
+      if (rem)
+        tmpb1->next=tmpb2;
+      else
+        tmpb1=&tmpb->next;
+    } else
+      tmpb1=&tmpb->next;
+    tmpb=tmpb2;
+  }
+  POPFD
+  return res;
+}
+
+Bool BptS(U8 *addr,CTask *task=NULL,Bool live=TRUE)
+{//Set breakpoint.
+  CBpt *tmpb;
+  Bool res=TRUE;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (!(tmpb=BptFind(addr,task,FALSE))) {
+    tmpb=CAlloc(sizeof(CBpt),task);
+    tmpb->addr=addr;
+    tmpb->val=*addr;
+    res=FALSE;
+    tmpb->next=task->bpt_lst;
+    task->bpt_lst=tmpb;
+    if (task==Fs && live)
+      *addr=OC_BPT;
+  }
+  POPFD
+  return res;
+}
+
+Bool BptR(U8 *addr,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE)
+{//Rem breakpoint.
+  CBpt *tmpb;
+  Bool res=FALSE;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (tmpb=BptFind(addr,task,rem)) {
+    if (task==Fs && live)
+      *tmpb->addr=tmpb->val;
+    res=TRUE;
+    if (rem)
+      Free(tmpb);
+  }
+  POPFD
+  return res;
+}
+
+Bool B(U8 *addr,CTask *task=NULL,Bool live=TRUE)
+{//Toggle breakpoint.
+//Return: TRUE if removed.
+  Bool res=FALSE;
+  PUSHFD
+  CLI
+  if (BptFind(addr,task,FALSE)) {
+    BptR(addr,task,live,TRUE);
+    res=TRUE;
+  } else
+    BptS(addr,task,live);
+  POPFD
+  return res;
+}
+
+I64 B2(CTask *task=NULL,Bool live=TRUE)
+{//Rem all breakpoints.
+//Return: cnt of removed.
+  I64 res=0;
+  CBpt *tmpb,*tmpb1;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  tmpb=task->bpt_lst;
+  task->bpt_lst=NULL;
+  while (tmpb) {
+    tmpb1=tmpb->next;
+    if (task==Fs && live)
+      *tmpb->addr=tmpb->val;
+    Free(tmpb);
+    tmpb=tmpb1;
+    res++;
+  }
+  POPFD
+  return res;
+}
+
+U0 G(U8 *ip=INVALID_PTR,CTask *task=NULL)
+{//Go
+  if (!task) task=Fs;
+  if (ip!=INVALID_PTR) task->rip=ip;
+  if (BptFind(task->rip,task))
+    "\nDo one of the following, first:\n"
+          ">S;\t\t\t//Single step\n"
+          ">B2;\t\t\t//Clear all break points\n"
+          ">G2;\t\t\t//Clear all break points and Go\n\n"
+          "After resuming, <CTRL-ALT-n> next focus task\n"
+          "After resuming, <CTRL-ALT-v> flushes scrn VGA cache\n";
+  else {
+    LBtr(&task->task_flags,TASKf_DISABLE_BPTS);
+    LBtr(&task->rflags,RFLAGf_TRAP);//No single step
+    Suspend(task,FALSE);
+    if (task==Fs) {
+      if (IsDbgMode && task->next_cc!=&task->next_cc) {
+        "Exit Dbg\n";
+        Btr(&task->last_cc->flags,CCf_PMT);
+      }
+    } else
+      Exit;
+  }
+}
+
+U0 G2(U8 *ip=INVALID_PTR,CTask *task=NULL)
+{//Rem all breakpoints and Go.
+  if (!task) task=Fs;
+  B2(task);
+  if (ext[EXT_WIN_FOCUS])
+    CallExtNum(EXT_WIN_FOCUS,dbg.focus_task);
+  VGAFlush;
+  G(ip,task);
+}
+
+public U0 S(U8 *ip=INVALID_PTR,CTask *task=NULL) //Single-step.
+{//Single step.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (ip!=INVALID_PTR) task->rip=ip;
+  LBts(&task->task_flags,TASKf_DISABLE_BPTS);
+  LBts(&task->rflags,RFLAGf_TRAP);
+  Suspend(task,FALSE);
+  if (task==Fs) {
+    if (IsDbgMode) {
+      if (task->next_cc!=&task->next_cc)
+        Btr(&task->last_cc->flags,CCf_PMT);
+    }
+  } else
+    Exit;
+  POPFD
+}
+
+U0 DbgHelp()
+{
+  "\n"
+        "The cmd line is basically the same as normal.  Here are some common\n"
+        "debugging commands.\n\n"
+        ">EdLite(\"FileName\");\t\t//Edit file.\n"
+        ">D(0x100000);\t\t\t//Dump page tables.\n"
+        ">Dm(0x100000);\t\t\t//Dump page tables.\n"
+        ">Dm(Fs,sizeof(CTask));\t\t//Dump current task record.\n"
+        ">ClassRep(Fs,\"CTask\",1);\t//Dump current task record.\n"
+        ">ClassRep(Fs,,1);\t\t//(It knows lastclass.)\n"
+        ">CallerRep;\t\t\t//Stack trace report.\n"
+        ">Da(_RSP);\t\t\t//Dump stk.\n"
+        ">Dr;\t\t\t\t//Dump Regs.\n"
+        ">1+2*3+&Print;\t\t\t//Show calculation res.\n"
+        ">*(0x70000)(I64 *)=0x123456789;\t//Assign value to 0x70000-0x70007.\n"
+        ">_RAX=0x1234;\t\t\t//Set RAX to 0x1234.\n"
+        ">_RIP=&Break;\t\t//Set RIP.\n"
+        ">I64 i;\t\t\t\t//Declare variable.\n"
+        ">i=_RCX+_RDX;\t\t\t//Assign to variable.\n"
+        ">U(&Print+0x8);\t\t\t//Unassemble Print.\n"
+        ">Uf(\"Print\");\t\t\t//Unassembler function \"Print\".\n"
+        ">Man(\"Print\");\t\t\t//Edit Src for \"Print\".\n"
+        ">E(_RIP);\t\t\t//Edit Src Code.\n"
+        ">Fix;\t\t\t\t//Edit Last Err Src Code.\n"
+        ">B(&Main+0x20);\t\t\t//Toggle break point.\n"
+        ">B2;\t\t\t\t//Clear all break points.\n"
+        ">S;\t\t\t\t//Single step.\n"
+        ">G;\t\t\t\t//Resume execution.\n"
+        ">G2;\t\t\t\t//B2;VGAFlush;WinFocus;G;\n"
+        ">Exit;\t\t\t\t//Exit (kill) task.\n\n"
+        "After resuming, <CTRL-ALT-n> next focus task.\n"
+        "After resuming, <CTRL-ALT-v> flushes scrn VGA cache.\n\n";
+}
+
+U0 Dbg2()
+{
+  Bool old_win_inhibit,old_waiting_msg,old_single;
+  I64 i,old_getstr2;
+  U8 buf[200];
+  if (dbg.panic) {
+    if (IsRaw) {
+      i=Fs->rip;
+      Ui(buf,&i);
+      "%s",buf;
+    } else
+      U(Fs->rip,1);
+  } else
+    dbg.panic=TRUE;
+  old_waiting_msg=LBtr(&Fs->task_flags,TASKf_AWAITING_MSG);
+  old_win_inhibit=Fs->win_inhibit;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  sys_focus_task=Fs;
+  kbd.scan_code=0;
+  old_getstr2=fp_getstr2;
+  fp_getstr2=&SysGetStr2;
+  old_single=SingleUser(OFF);
+  while (!ms_hard.install_attempts)
+    Yield;
+  SingleUser(old_single);
+  UserTaskCont;
+  fp_getstr2=old_getstr2;
+  Fs->win_inhibit=old_win_inhibit;
+  LBEqu(&Fs->task_flags,TASKf_AWAITING_MSG,old_waiting_msg);
+}
+
+U0 Fault3(I64 fault_num,I64 fault_err_code)
+{
+  no_warn fault_err_code;
+  PUSHFD
+  CLI
+  if (Gs->num && dbg.mp_crash) {
+    mp_cnt=1;
+    dbg.mp_crash->cpu_num=Gs->num;
+    dbg.mp_crash->task=Fs;
+    dbg.mp_crash->rip=Fs->rip;
+    dbg.mp_crash->msg=dbg.msg;
+    dbg.mp_crash->msg_num=dbg.msg_num;
+    MPInt(I_MP_CRASH,0);
+    SysHlt;
+  }
+  "\n\tTempleOS Debugger\n\n"
+        ">Help;\t//For help.\n\n";
+  Beep(62,TRUE);
+  if (fault_num==I_DBG) {
+    if (dbg.msg) {
+      "\n!!! %s",dbg.msg;
+      if (dbg.msg_num)
+        "%016X",dbg.msg_num;
+      " !!!\n\n";
+    }
+  }
+  if (dbg.panic)
+    CallerRep;
+  Dbg2;
+  POPFD
+}
+
+U0 Fault2(I64 fault_num,I64 fault_err_code)
+{//Called from Fault2.
+//Be careful not to swap-out and ruin the saved context
+  Bool was_raw,was_single_user,was_silent,was_in_dbg;
+  I64  i,old_raw_flags=text.raw_flags;
+  was_single_user=SingleUser(ON);
+  if (!IsDbgMode)
+    dbg.focus_task=sys_focus_task;
+  sys_focus_task=NULL;
+  if (fault_num==I_BPT)
+    Fs->rip--;
+  if (Fs->dbg_task)
+    CallExtNum(EXT_DBG_RESUME,fault_num,fault_err_code);
+  else {
+    was_raw=Raw(ON);
+    was_silent=Silent(OFF);
+    text.raw_flags|=RWF_SHOW_DOLLAR|RWF_SCROLL;
+
+    "Task \"";
+    "%s",Fs->task_title;
+    "\"\n";
+    "Fault:0x%02X %Z\t\tErr Code:%08X\n",
+          fault_num,fault_num,"ST_INT_NAMES",fault_err_code;
+    was_in_dbg=DbgMode(ON);
+    "RIP:%08X",Fs->rip; //Sometimes crashes on %p, so do this first
+    ":%p  RSP:%08X\n",Fs->rip,Fs->rsp;
+    if (fault_num==I_PAGE_FAULT) {
+      MOV_RAX_CR2
+      i=GetRAX;
+      "Fault Addr:%08X:%p\n",i,i;
+    }
+    Fault3(fault_num,fault_err_code);
+    DbgMode(was_in_dbg);
+    Silent(was_silent);
+    Raw(was_raw);
+    text.raw_flags=old_raw_flags;
+  }
+  SingleUser(was_single_user);
+  if (LBtr(&Fs->task_flags,TASKf_KILL_AFTER_DBG))
+    Exit;
+}
+
+U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE)
+{//Enter the debugger with panic?
+  PUSHFD
+  CLI
+  dbg.msg=msg;
+  dbg.msg_num=msg_num;
+  dbg.panic=panic;
+  INT I_DBG
+  POPFD
+}
+
+U0 Dbg(U8 *msg=NULL,I64 msg_num=0)
+{//Enter debugger, no panic.
+  Panic(msg,msg_num,FALSE);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KDefine.HC.HTML b/public/Wb/Home/Src/Kernel/KDefine.HC.HTML new file mode 100755 index 0000000..f093f05 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KDefine.HC.HTML @@ -0,0 +1,249 @@ + + + + + + + + + + + +
+CHashDefineStr *DefineLoad(U8 *dname,U8 *st)
+{//Create DEFINE hash entry with string.
+  CHashDefineStr *tmph=CAlloc(sizeof(CHashDefineStr));
+  tmph->type=HTT_DEFINE_STR;
+  tmph->str=StrNew(dname);
+  tmph->data=StrNew(st);
+  tmph->cnt=-1;
+  tmph->src_link=MStrPrint("AD:0x%X",Caller);
+  HashAdd(tmph,Fs->hash_table);
+  return tmph;
+}
+
+CHashDefineStr *DefineLstLoad(U8 *dname,U8 *lst)
+{//Create DEFINE list. Not efficient, but handy.
+  I64 cnt=0;
+  U8 *ptr,**idx;
+  CHashDefineStr *tmph=CAlloc(sizeof(CHashDefineStr));
+  tmph->type=HTT_DEFINE_STR;
+  tmph->str=StrNew(dname);
+  tmph->src_link=MStrPrint("AD:0x%X",Caller);
+  ptr=lst;
+  while (*ptr) {
+    if (*ptr!='@')
+      cnt++;
+    while (*ptr++);
+  }
+  tmph->data=MAlloc(ptr+1-lst);
+  MemCpy(tmph->data,lst,ptr+1-lst);
+  tmph->cnt=cnt;
+
+  idx=tmph->sub_idx=MAlloc(cnt*sizeof(U8 *));
+  ptr=lst;
+  while (*ptr) {
+    if (*ptr!='@')
+      *idx++=ptr;
+    while (*ptr++);
+  }
+
+  HashAdd(tmph,Fs->hash_table);
+  return tmph;
+}
+
+U0 UndefinedDefine(U8 *dname)
+{
+  ST_ERR_ST "Undefined Define: '%s'.\n",dname;
+  throw('UndefDef');
+}
+
+U8 *Define(U8 *dname)
+{//Look for DEFINE named in hash table, return ptr string.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR))
+    return tmph->data;
+  else if (dname)
+    UndefinedDefine(dname);
+  else
+    return NULL;
+}
+
+U8 *DefineSub(I64 sub,U8 *dname)
+{//Return DEFINE list entry indexed by number.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR)) {
+    if (0<=sub<tmph->cnt)
+      return tmph->sub_idx[sub];
+    else
+      return NULL;
+  } else if (dname)
+    UndefinedDefine(dname);
+  else
+    return NULL;
+}
+
+I64 DefineCnt(U8 *dname)
+{//Return cnt of entries in define list.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR))
+    return tmph->cnt;
+  else if (dname)
+    UndefinedDefine(dname);
+  else
+    return -1;
+}
+
+I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0)
+{//Find match for string in define list.
+  return LstMatch(needle,Define(haystack_lst_dname),flags);
+}
+
+U0 DefinePrint(U8 *dname,U8 *src,...)
+{//Create DEFINE entry with Print()ed string.
+  U8 *buf=StrPrintJoin(NULL,src,argc,argv);
+  DefineLoad(dname,buf);
+  Free(buf);
+}
+
+U0 SysDefinesLoad()
+{
+  DefineLstLoad("ST_OFF_ON","Off\0On\0");
+  DefineLstLoad("ST_HTT_TYPES","ExportSysSym\0ImportSysSym\0DefineStr\0GlbVar\0"
+        "Class\0IntType\0Funct\0Word\0DictWord\0KeyWord\0AsmKeyWord\0OpCode\0"
+        "Reg\0File\0Module\0HelpFile\0Frame Ptr\0 \0 \0 \0 \0 \0 \0Private\0"
+        "Public\0Export\0Import\0Imm\0Goto\0Res\0Unres\0Local\0");
+  DefineLstLoad("ST_DAYS_OF_WEEK","Sunday\0Monday\0Tuesday\0Wednesday\0"
+        "Thursday\0Friday\0Saturday\0");
+  DefineLstLoad("ST_MONTHS","January\0February\0March\0April\0May\0"
+        "June\0July\0August\0September\0October\0November\0December\0");
+  DefineLstLoad("ST_FILE_ATTRS","R\0H\0S\0V\0D\0A\0 \0 \0X\0T\0Z\0C\0F\0");
+  DefineLstLoad("ST_FILE_UTIL_FLAGS","r\0d\0i\0a\0c\0R\0p\0m\0x\0s\0"
+        "D\0F\0T\0$\0S\0A\0J\0G\0Z\0O\0P\0f\0l\0lb\0la\0");
+  DefineLstLoad("ST_BLKDEV_TYPES",
+        "NULL\0RAM\0ATA\0FILE_READ\0FILE_WRITE\0ATAPI\0");
+  DefineLstLoad("ST_DRV_TYPES",
+        "NULL\0REDSEA\0FAT32\0ISO9660\0NTFS\0UNKNOWN\0");
+  DefineLstLoad("ST_COLORS","BLACK\0BLUE\0GREEN\0CYAN\0"
+        "RED\0PURPLE\0BROWN\0LTGRAY\0DKGRAY\0LTBLUE\0LTGREEN\0"
+        "LTCYAN\0LTRED\0LTPURPLE\0YELLOW\0WHITE\0");
+  DefineLstLoad("ST_INT_NAMES","Divide Error\0SingleStep\0NMI\0Breakpoint\0"
+        "Overflow\0BOUND Range Exceeded\0Invalid Opcode\0No Math Coprocessor\0"
+        "Double Fault\0Coprocessor Segment Fault\0Invalid TASK\0"
+        "Segment Not Present\0Stk Segment Fault\0General Protection\0"
+        "Page Fault\0 \0Math Fault\0Alignment Check\0Machine Check\0"
+        "SIMD Exception\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 \0MP Crash\0Wake\0Dbg\0");
+}
+
+U8 *Color2Str(U8 *buf,CColorROPU32 c)
+{//CColorROPU32 with flags to DCLighting str.
+  *buf=0;
+  if (c.c0.rop&ROPBF_TWO_SIDED)
+    CatPrint(buf,"TWO|");
+  if (c.c0.rop&ROPBF_HALF_RANGE_COLOR)
+    CatPrint(buf,"HALF|");
+  if (0<=c.c0.color<16)
+    CatPrint(buf,DefineSub(c.c0.color,"ST_COLORS"));
+  else if (c.c0.color==TRANSPARENT)
+    CatPrint(buf,"TRANSPARENT");
+  else
+    CatPrint(buf,"INVALID");
+  if (c&ROPF_DITHER) {
+    CatPrint(buf,"/");
+    if (c.c1.rop&ROPBF_TWO_SIDED)
+      CatPrint(buf,"TWO|");
+    if (c.c1.rop&ROPBF_HALF_RANGE_COLOR)
+      CatPrint(buf,"HALF|");
+    if (0<=c.c1.color<16)
+      CatPrint(buf,DefineSub(c.c1.color,"ST_COLORS"));
+    else if (c.c1.color==TRANSPARENT)
+      CatPrint(buf,"TRANSPARENT");
+    else
+      CatPrint(buf,"INVALID");
+  }
+  return buf;
+}
+
+U8 *str2color_lst="/,)}>";
+
+CColorROPU16 Str2ColorU16(U8 *st)
+{//DCLighting color str with flags to CColorROPU16.
+  CColorROPU16 res=COLOR_INVALID;
+  I64 i;
+  U8 *ptr,*ptr2,*st2;
+  if (!st) return COLOR_INVALID;
+  while (TRUE) {
+    if (!*st||StrOcc(str2color_lst,*st))
+      return res;
+    if (Bt(char_bmp_alpha,*st)) {
+      ptr=st;
+      while (Bt(char_bmp_alpha_numeric,*ptr))
+        ptr++;
+      st2=ptr2=MAlloc(ptr-st+1);
+      while (st<ptr)
+        *ptr2++=*st++;
+      *ptr2++=0;
+      if (!StrICmp(st2,"TWO"))
+        res.rop|=ROPBF_TWO_SIDED;
+      else if (!StrICmp(st2,"HALF"))
+        res.rop|=ROPBF_HALF_RANGE_COLOR;
+      else if ((i=DefineMatch(st2,"ST_COLORS",LMF_IGNORE_CASE))>=0)
+        res.color=i;
+      else if (!StrICmp(st2,"TRANSPARENT"))
+        res.color=TRANSPARENT;
+      else {
+        Free(st2);
+        return COLOR_INVALID;
+      }
+      Free(st2);
+    } else if (*st=='+'||*st=='|'||Bt(char_bmp_white_space,*st))
+      st++;
+    else if ('0'<=*st<='9') {
+      i=Str2I64(st,10,&ptr);
+      if (0<=i<=0xFF) {
+        res.color=i;
+        st=ptr;
+      } else
+        return COLOR_INVALID;
+    } else
+      return COLOR_INVALID;
+  }
+}
+
+CColorROPU32 Str2ColorU32(U8 *st)
+{//DCLighting color str with flags to CColorROPU32.
+  U8 *st2;
+  CColorROPU32 res=0;
+  if (!st) return COLOR_INVALID;
+  st2=MAlloc(StrLen(st)+1);
+  StrFirstRem(st,str2color_lst,st2);
+  res.c0=Str2ColorU16(st2);
+  if (*st) {
+    res.c1=Str2ColorU16(st);
+    res|=ROPF_DITHER;
+  }
+  if (res.c0.color==COLOR_INVALID||res.c1.color==COLOR_INVALID)
+    return COLOR_INVALID;
+  else
+    return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KExcept.HC.HTML b/public/Wb/Home/Src/Kernel/KExcept.HC.HTML new file mode 100755 index 0000000..1b547fe --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KExcept.HC.HTML @@ -0,0 +1,180 @@ + + + + + + + + + + + +
+asm {
+#assert !((REGG_LOCAL_NON_PTR_VARS|REGG_LOCAL_VARS)&~0xFCC0)
+_TEST_EXCEPT::
+        XOR     RAX,RAX
+        MOV     RAX,FS:U64 CTask.last_except[RAX]
+        MOV     RBP,U64 CExcept.rbp[RAX]
+        MOV     RSI,U64 CExcept.rsi[RAX]
+        MOV     RDI,U64 CExcept.rdi[RAX]
+        MOV     R10,U64 CExcept.r10[RAX]
+        MOV     R11,U64 CExcept.r11[RAX]
+        MOV     R12,U64 CExcept.r12[RAX]
+        MOV     R13,U64 CExcept.r13[RAX]
+        MOV     R14,U64 CExcept.r14[RAX]
+        MOV     R15,U64 CExcept.r15[RAX]
+        PUSH    U64 CExcept.rflags[RAX]
+        POPFD
+        JMP     U64 CExcept.hndlr_catch[RAX]
+
+_TAKE_EXCEPT::
+        XOR     RAX,RAX
+        MOV     RAX,FS:U64 CTask.last_except[RAX]
+        MOV     RSP,U64 CExcept.rsp[RAX]
+        JMP     U64 CExcept.hndlr_untry[RAX]
+
+_SAVE_EXCEPT_REGS::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     U64 CExcept.rsi[RAX],RSI
+        MOV     U64 CExcept.rdi[RAX],RDI
+        MOV     U64 CExcept.r10[RAX],R10
+        MOV     U64 CExcept.r11[RAX],R11
+        MOV     U64 CExcept.r12[RAX],R12
+        MOV     U64 CExcept.r13[RAX],R13
+        MOV     U64 CExcept.r14[RAX],R14
+        MOV     U64 CExcept.r15[RAX],R15
+        POP     RBP
+        RET1    8
+}
+
+_extern _TEST_EXCEPT U0 TestExcept();
+_extern _TAKE_EXCEPT U0 TakeExcept();
+_extern _SAVE_EXCEPT_REGS U0 SaveExceptRegs(CExcept *t);
+
+U0 PutExcept(Bool catch_it=TRUE)
+{//Print exception msg and catch exception.
+  "Except:%c:",Fs->except_ch;
+  "%P:%P:%P:%P:%P:%P\n",Fs->except_callers[0],Fs->except_callers[1],
+        Fs->except_callers[2],Fs->except_callers[3],Fs->except_callers[4],
+        Fs->except_callers[5],Fs->except_callers[6],Fs->except_callers[7];
+  Fs->catch_except=catch_it;
+}
+
+#exe {Option(OPTf_NO_REG_VAR,ON);};
+
+class CTryStk
+{
+  I64 rbp;
+  I64 ret_rip;
+  I64 arg1;
+  I64 arg2;
+};
+
+U0 SysTry(U8 *catch_start,U8 *untry_start)
+{
+  I64 *rbp=GetRBP;
+  CExcept *tmpt=MAlloc(sizeof(CExcept));
+  tmpt->hndlr_catch=catch_start;
+  tmpt->hndlr_untry=untry_start;
+  tmpt->rsp=rbp(U8 *)+sizeof(CTryStk);
+  tmpt->rbp=*rbp;
+  tmpt->rflags=GetRFlags;
+  SaveExceptRegs(tmpt);
+  QueIns(tmpt,Fs->last_except);
+}
+
+U0 SysUntry()
+{
+  CExcept *tmpt=Fs->last_except;
+  QueRem(tmpt);
+  Free(tmpt);
+}
+
+U0 throw(I64 ch=0,Bool no_log=FALSE)
+{//ch can be up to 8 chars like PutChars().
+//In the catcher, fetch ch from Fs->except_ch.
+  CExcept *tmpt=Fs->last_except;
+  Bool was_raw;
+  I64 i;
+  Fs->except_ch=ch;
+  for (i=0;i<TASK_EXCEPT_CALLERS;i++)
+    Fs->except_callers[i]=Caller(i+1);
+  Fs->except_rbp=GetRBP;
+  Fs->catch_except=FALSE;
+  if (!no_log)
+    AdamLog("Except:%c:%p:%p:%p:%p:%p:%p\n",ch,Fs->except_callers[0],
+          Fs->except_callers[1],Fs->except_callers[2],Fs->except_callers[3],
+          Fs->except_callers[4],Fs->except_callers[5],Fs->except_callers[6],
+          Fs->except_callers[7]);
+  while (Fs->next_except!=&Fs->next_except) {
+    TestExcept;
+    if (Fs->catch_except)
+      TakeExcept;
+    SetRBP(Fs->except_rbp);
+    tmpt=Fs->last_except;
+    QueRem(tmpt);
+    Free(tmpt);
+  }
+  was_raw=Raw(ON);
+  PutExcept(FALSE);
+  Panic("Unhandled Exception");
+  Raw(was_raw);
+}
+
+#exe {Option(OPTf_NO_REG_VAR,OFF);};
+
+U0 Break()
+{//Send <CTRL-ALT-c>.
+  if (Bt(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC))
+    Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0x20100000201);
+  else {
+    Fs->wake_jiffy=0;
+    TaskRstAwaitingMsg;
+    DrvsRelease();
+    BlkDevsRelease();
+    FlushMsgs;
+    throw('Break');
+  }
+}
+
+Bool BreakLock(CTask *task=NULL)
+{//Disables <CTRL-ALT-c>.
+  if (!task) task=Fs;
+  return !LBts(&task->task_flags,TASKf_BREAK_LOCKED);
+}
+
+Bool BreakUnlock(CTask *task=NULL)
+{//Reenables <CTRL-ALT-c> and issues any pending breaks.
+  Bool res;
+  if (!task) task=Fs;
+  res=LBtr(&task->task_flags,TASKf_BREAK_LOCKED);
+  if (LBtr(&task->task_flags,TASKf_PENDING_BREAK)) {
+    if (task==Fs)
+      Break;
+    else
+      task->rip=&Break;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KExts.HC.HTML b/public/Wb/Home/Src/Kernel/KExts.HC.HTML new file mode 100755 index 0000000..1fb4154 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KExts.HC.HTML @@ -0,0 +1,140 @@ + + + + + + + + + + + +
+/*
+If you are sure a fun won't be called
+before import is resolved, you can use
+"import".  Otherwise, use a fun pointer
+var and check it before calling.
+*/
+import U0 ClassRep(U8 *_d,U8 *class_name=lastclass,
+        I64 max_depth=2,Bool fun=FALSE,I64 offset=0);
+import U8 *DocSave(CDoc *doc,I64 *_size=NULL);
+import Bool DocUnlock(CDoc *doc);
+import Bool Ed(U8 *link_st,I64 edf_dof_flags=0);
+extern U0 AdamErr(U8 *fmt,...);
+extern U0 AdamLog(U8 *fmt,...);
+extern I64 BIOSTotalMem();
+extern I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN,
+        Bool whole_drv,Bool make_free);
+extern CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE);
+extern Bool BlkDevLock(CBlkDev *bd);
+extern CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type);
+extern Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE);
+extern U0 BlkDevsRelease();
+extern Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+extern Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+extern U8 *Caller(I64 num=1);
+extern U8 *CatPrint(U8 *_dst,U8 *fmt,...);
+extern Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE);
+extern U0 DbgHelp();
+extern U8 *Define(U8 *dname);
+extern I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0);
+extern U8 *DefineSub(I64 sub,U8 *dname);
+extern I64 Del(U8 *files_find_mask,Bool make_mask=FALSE,
+        Bool del_dir=FALSE,Bool print_msg=TRUE);
+extern Bool DirMk(U8 *filename,I64 entry_cnt=0);
+extern Bool Drv(U8 drv_let);
+extern U8 Drv2Let(CDrv *dv=NULL);
+extern U0 DrvBlkDevDel(CBlkDev *bd);
+extern CDrv *DrvChk(CDrv *dv,Bool except=TRUE);
+extern U8 DrvTextAttrGet(U8 drv_let=0);
+extern Bool DrvTypeSet(U8 drv_let,I64 type=FSt_REDSEA);
+extern U0 DrvsRelease();
+extern U0 DskCacheInvalidate(CDrv *dv);
+extern U0 Exit();
+extern U8 *ExtDft(U8 *filename,U8 *extension);
+extern I64 FAT32AllocClus(CDrv *dv,I64 c,I64 cnt);
+extern I64 FAT32AllocContiguousClus(CDrv *dv,I64 cnt);
+extern Bool FAT32DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,
+        Bool free_old_chain);
+extern Bool FAT32FileFind(CDrv *dv,I64 cur_dir_clus,U8 *name,
+        CDirEntry *_res,I64 fuf_flags=0);
+extern U0 FAT32Init(CDrv *dv);
+extern Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+extern Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+extern U0 FClose(CFile *f);
+extern CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0);
+extern U8 *FileExtRem(U8 *src,U8 *dst=NULL);
+extern Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0);
+extern U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=0);
+extern U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL);
+extern I64 FileWrite(U8 *filename,U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0);
+extern I64 FlushMsgs(CTask *task=NULL);
+extern I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE);
+extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE);
+extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,
+        CTask *task=NULL,CBlkPool *bp);
+extern Bool ISOInit(CDrv *dv,I64 blk);
+extern Bool IsDbgMode();
+extern Bool IsDir(U8 *dir_name);
+extern Bool IsRaw();
+extern U0 JobCtrlInit(CJobCtrl *ctrl);
+extern U0 JobDel(CJob *tmpc);
+extern U0 JobQueDel(CJob *head);
+extern I64 JobsHndlr(I64 run_flags,CTask *task=NULL);
+extern CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE);
+extern I64 Let2BlkDevType(U8 drv_let);
+extern CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE);
+extern U8 Let2Let(U8 drv_let=0);
+extern U0 MPInt(U8 num,I64 cpu_num=1);
+extern U8 *MStrPrint(U8 *fmt,...);
+extern U0 MsHardSet(I64 x,I64 y,I64 z,I64 l,I64 r);
+extern U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0);
+extern U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE);
+extern I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL);
+extern U0 Print(U8 *fmt,...);
+extern U0 PutChars(U64 ch);
+extern U0 PutS(U8 *st); //Use Print()
+extern I64 RedSeaAllocClus(CDrv *dv,I64 cnt);
+extern Bool RedSeaDirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,
+        Bool free_old_chain);
+extern Bool RedSeaFileFind(CDrv *dv,I64 cur_dir_clus,U8 *name,
+        CDirEntry *_res,I64 fuf_flags=0);
+extern U0 RedSeaFmt(U8 drv_let,Bool quick=TRUE);
+extern U0 RedSeaFreeFreeLst(CDrv *dv);
+extern U0 RedSeaInit(CDrv *dv);
+extern Bool RedSeaValidate(U8 drv_let);
+extern CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,
+    U8 *task_name=NULL,I64 target_cpu,CTask *parent=NULL, //NULL means adam
+    I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE);
+extern U8 *StrPrint(U8 *dst,U8 *fmt,...);
+extern U0 StrPrintFunSeg(U8 *buf,I64 addr,I64 field_len,I64 flags);
+extern Bool Suspend(CTask *task=NULL,Bool state=TRUE);
+extern CJob *TaskMsg(CTask *_srv,CTask *master,
+        I64 msg_code,I64 arg1,I64 arg2,I64 flags);
+extern U0 TaskRstAwaitingMsg(CTask *task=NULL);
+extern Bool TaskValidate(CTask *task);
+extern U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE);
+extern CTask *User(U8 *fmt=NULL,...);
+extern U0 UserTaskCont();
+extern U0 XTalk(CTask *task,U8 *fmt,...);
+extern U0 throw(I64 ch=0,Bool no_log=FALSE);
+
+ diff --git a/public/Wb/Home/Src/Kernel/KGlbls.HC.HTML b/public/Wb/Home/Src/Kernel/KGlbls.HC.HTML new file mode 100755 index 0000000..500bece --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KGlbls.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+//Compiler initializes glbls in AOT bin modules to zero.
+//Globals Set to Zero Here.
+
+CJob sys_macro_head;
+CTask *sys_macro_task;
+CDoc *sys_clip_doc;
+
+CTask *adam_task;
+I64 sys_num_spawned_tasks;
+
+CTask *sys_winmgr_task,*sys_task_being_scrn_updated;
+U8 *rev_bits_table, //Table with U8 bits revd
+   *set_bits_table; //Table with count of set bits in a U8
+CDate local_time_offset;
+F64     *pow10_I64,
+        sys_os_version=5.030;
+
+CAutoCompleteDictGlbls acd;
+CAutoCompleteGlbls ac;
+CBlkDevGlbls    blkdev;
+CCntsGlbls      cnts={1,0,2676302000,2676302,2676302000,0,0,0,FALSE};
+CDbgGlbls       dbg;
+CDevGlbls       dev;
+CGridGlbls      ms_grid; //See ::/Demo/Graphics/Grid.HC.
+CMsStateGlbls   ms,ms_last;
+CKbdStateGlbls  kbd;
+CKeyDevGlbls    keydev;
+CMsHardStateGlbls ms_hard,ms_hard_last;
+CScrnCastGlbls  scrncast;
+CTextGlbls      text;
+
+U8  *(*fp_getstr2)(I64 flags=0);
+U0 (*fp_update_ctrls)(CTask *task);
+CDoc *(*fp_doc_put)(CTask *task=NULL);
+U0 (*fp_set_std_palette)();
+
+ diff --git a/public/Wb/Home/Src/Kernel/KHashA.HC.HTML b/public/Wb/Home/Src/Kernel/KHashA.HC.HTML new file mode 100755 index 0000000..9101bbb --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KHashA.HC.HTML @@ -0,0 +1,296 @@ + + + + + + + + + + + +
+asm {
+//************************************
+SYS_HASH_STR::
+// IN:  RSI=Addr of string
+// OUT: RAX
+        XOR     RAX,RAX
+        TEST    RSI,RSI
+        JZ      @@15
+
+        PUSH    RSI
+        PUSH    RBX
+        XOR     RBX,RBX
+        JMP     @@10
+
+@@05:   SHL1    RBX
+        ADC     RBX,RAX
+@@10:   LODSB
+        TEST    AL,AL
+        JNZ     @@05
+
+        MOV     RAX,RBX
+        SHR     RBX,16
+        ADC     RAX,RBX
+        POP     RBX
+        POP     RSI
+
+@@15:   RET
+//************************************
+SYS_HASH_SINGLE_TABLE_FIND1::
+// IN:  RAX=HASHED STRING VAL
+//      RSI=STR
+//      RBX=TYPE MASK
+//      RDI=TABLE
+//      RCX=INSTANCE, NOT ZERO
+// OUT: RAX=ENTRY OR ZERO NOT FOUND
+//      RDX=POINTER TO POINTER TO ENTRY
+//      RCX IF NOT FOUND ENOUGH, DECREMENTED BY NUM MATCHES
+//      ZERO FLAG SET NOT FOUND
+        MOV     RCX,1
+SYS_HASH_SINGLE_TABLE_FIND::
+        TEST    RCX,RCX
+        JNZ     @@05
+        XOR     RAX,RAX
+        RET
+@@05:   AND     RAX,U64 CHashTable.mask[RDI]
+        MOV     RDX,U64 CHashTable.body[RDI]
+        LEA     RDX,U64 [RDX+RAX*8]
+@@10:   MOV     RAX,U64 [RDX]
+        TEST    RAX,RAX
+        JNZ     @@15
+        RET
+
+@@15:   TEST    U32 CHash.type[RAX],EBX
+        JZ      @@30
+        PUSH    RAX
+        PUSH    RDI
+        PUSH    RSI
+        MOV     RDI,U64 CHash.str[RAX]
+@@20:   LODSB
+        CMP     U8 [RDI],AL
+        JNE     @@25
+        INC     RDI
+        TEST    AL,AL
+        JNZ     @@20
+        POP     RSI
+        POP     RDI
+        POP     RAX
+        LOOP    @@30
+        INC     U32 CHash.use_cnt[RAX]
+        TEST    RAX,RAX
+        RET
+
+@@25:   POP     RSI
+        POP     RDI
+        POP     RAX
+
+@@30:   LEA     RDX,U64 CHash.next[RAX]
+        JMP     @@10
+//************************************
+SYS_HASH_FIND1::
+// IN:  RSI=STR
+//      RBX=TYPE MASK
+//      RDI=TABLE
+//      RCX=INSTANCE NUM
+// OUT: RAX=ENTRY OR ZERO NOT FOUND
+//      ZERO FLAG SET NOT FOUND
+        MOV     RCX,1
+SYS_HASH_FIND::
+        PUSH    RDI
+        CALL    SYS_HASH_STR
+        
+@@05:   PUSH    RAX
+        CALL    SYS_HASH_SINGLE_TABLE_FIND
+        JNZ     @@15
+        POP     RAX
+@@10:   MOV     RDI,U64 CHashTable.next[RDI]
+        TEST    RDI,RDI
+        JNZ     @@05
+        POP     RDI
+        XOR     RAX,RAX
+        RET
+
+@@15:   ADD     RSP,8
+        POP     RDI
+        TEST    RAX,RAX
+        RET
+//************************************
+SYS_HASH_BUCKET_FIND::
+// IN:  RSI=STR
+//      RDI=TABLE
+// OUT: RAX=BUCKET
+        PUSH    RDX
+        CALL    SYS_HASH_STR
+        AND     RAX,U64 CHashTable.mask[RDI]
+        MOV     RDX,U64 CHashTable.body[RDI]
+        LEA     RAX,U64 [RDX+RAX*8]
+        POP     RDX
+        RET
+_HASH_STR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        CALL    SYS_HASH_STR
+        POP     RSI
+        POP     RBP
+        RET1    8
+_HASH_FIND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+        CALL    SYS_HASH_FIND
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+_HASH_SINGLE_TABLE_FIND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+        CALL    SYS_HASH_STR
+        CALL    SYS_HASH_SINGLE_TABLE_FIND
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+_HASH_BUCKET_FIND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        CALL    SYS_HASH_BUCKET_FIND
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_HASH_ADD::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 CHash.str[RCX]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        CALL    SYS_HASH_BUCKET_FIND
+        MOV     RCX,U64 SF_ARG1[RBP]
+        PUSHFD
+        CLI
+        MOV     RBX,U64 [RAX]
+        MOV     U64 CHash.next[RCX],RBX
+        MOV     U64 [RAX],RCX
+
+        POPFD
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_HASH_ADD_AFTER::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG3[RBP]
+        PUSHFD
+        CLI
+        MOV     RAX,SF_ARG2[RBP]
+        MOV     RBX,U64 [RAX]
+        MOV     U64 CHash.next[RCX],RBX
+        MOV     U64 [RAX],RCX
+
+        POPFD
+        POP     RDI
+        POP     RBP
+        RET1    24
+_HASH_REM_DEL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG1[RBP]
+        TEST    RCX,RCX
+        JZ      @@10
+        MOV     RSI,U64 CHash.str[RCX]
+        XOR     RBX,RBX
+        MOV     EBX,U32 CHash.type[RCX]
+        AND     EBX,~HTG_FLAGS_MASK&0xFFFFFFFF
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        CALL    SYS_HASH_STR
+
+        PUSHFD
+        CLI
+        CALL    SYS_HASH_SINGLE_TABLE_FIND
+        JZ      @@05
+        CMP     RAX,U64 SF_ARG1[RBP]
+        JNE     @@05
+
+        MOV     RBX,U64 CHash.next[RAX]
+        MOV     U64 [RDX],RBX
+
+        POPFD
+
+        PUSH_C_REGS
+        PUSH    RAX
+        CALL    &HashDel
+        POP_C_REGS
+
+        POP     RDI
+        POP     RSI
+        MOV     RAX,1
+        POP     RBP
+        RET1    24
+
+@@05:   POPFD
+@@10:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    24
+}
+
+_extern _HASH_STR I64 HashStr(U8 *st); //Hash a string.
+_extern _HASH_FIND CHash *HashFind(U8 *needle_str,CHashTable *haystack_table,
+        I64 mask,I64 instance=1);//Find string in hash table.
+_extern _HASH_SINGLE_TABLE_FIND CHash *HashSingleTableFind(U8 *needle_str,
+        CHashTable *haystack_table,
+        I64 mask,I64 instance=1);//Find string in single hash table.
+_extern _HASH_BUCKET_FIND CHash **HashBucketFind(U8 *needle_str,
+        CHashTable *haystack_table); //Find hash bucket.
+_extern _HASH_ADD U0 HashAdd(CHash *tmph,
+        CHashTable *table); //Add entry to hash table.
+_extern _HASH_REM_DEL Bool HashRemDel(CHash *tmph,CHashTable *table,
+        I64 instance=1);//Remove hash entry and del. Instance must match.
+
+ diff --git a/public/Wb/Home/Src/Kernel/KHashB.HC.HTML b/public/Wb/Home/Src/Kernel/KHashB.HC.HTML new file mode 100755 index 0000000..19576bf --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KHashB.HC.HTML @@ -0,0 +1,281 @@ + + + + + + + + + + + +
+I64 HashTypeNum(CHash *tmph)
+{//Return bit num of hash type, limited to just types.
+  if (tmph)
+    return Bsf(tmph->type&HTG_TYPE_MASK);
+  else
+    return -1;
+}
+
+I64 HashVal(CHash *tmph)
+{//Returns most likely desired value.
+  switch [HashTypeNum(tmph)] {
+    case HTt_EXPORT_SYS_SYM:
+      return tmph(CHashExport *)->val;
+    case HTt_IMPORT_SYS_SYM:
+      return tmph(CHashImport *)->module_base;
+    case HTt_DEFINE_STR:
+    case HTt_CLASS:
+    case HTt_INTERNAL_TYPE:
+    case HTt_WORD:
+    case HTt_DICT_WORD:
+    case HTt_OPCODE:
+    case HTt_HELP_FILE:
+      return tmph;
+    case HTt_GLBL_VAR:
+      if (tmph(CHashGlblVar *)->flags&GVF_EXTERN)
+        return &tmph(CHashGlblVar *)->data_addr;
+      else
+        return tmph(CHashGlblVar *)->data_addr;
+    case HTt_FUN:
+      if (Bt(&tmph(CHashFun *)->flags,Cf_EXTERN))
+        return tmph;
+      else
+        return tmph(CHashFun *)->exe_addr;
+    case HTt_REG:
+      return tmph(CHashReg *)->reg_num|tmph(CHashReg *)->reg_type<<8;
+    case HTt_KEYWORD:
+    case HTt_ASM_KEYWORD:
+    case HTt_MODULE:
+    case HTt_FILE:
+    case HTt_FRAME_PTR:
+      return tmph(CHashGeneric *)->user_data0;
+
+    case -1:            //nobound switch
+    case HTt_TYPES_NUM: //nobound switch
+    default:
+      return 0;
+  }
+}
+
+CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL)
+{//New hash table, power-of-two in size.
+  CHashTable *table;
+  table=CAlloc(sizeof(CHashTable),mem_task);
+  table->body=CAlloc(size<<3,mem_task);
+  table->mask=size-1;
+  return table;
+}
+
+U0 HashDel(CHashSrcSym *tmph)
+{//Free a std TempleOS system hash entry.
+  if (!tmph) return;
+  if (!(tmph->type&HTT_DICT_WORD))
+    Free(tmph->str);
+  if (tmph->type & HTG_SRC_SYM) {
+    Free(tmph->src_link);
+    Free(tmph->idx);
+    Free(tmph->import_name);
+    LinkedLstDel(tmph->ie_lst);
+    if (tmph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM))
+      Free(tmph->dbg_info);
+    if (tmph->type & (HTT_FUN | HTT_CLASS))
+//Assumes code not on heap, so doesn't Free.
+    //ClassMemberLstDel() is an import to the Kernel module
+      ClassMemberLstDel(tmph);
+    else if (tmph->type&HTT_DEFINE_STR)
+      Free(tmph(CHashDefineStr *)->data);
+    else if (tmph->type & HTT_GLBL_VAR) {
+      if (!(tmph(CHashGlblVar *)->flags&GVF_ALIAS))
+        Free(tmph(CHashGlblVar *)->data_addr);
+      LinkedLstDel(tmph(CHashGlblVar *)->dim.next);
+      if (tmph(CHashGlblVar *)->fun_ptr)
+        HashDel(tmph(CHashGlblVar *)->fun_ptr
+              -tmph(CHashGlblVar *)->fun_ptr->ptr_stars_cnt);
+    }
+  } else if (tmph->type & HTT_FILE)
+    Free(tmph(CHashGeneric *)->user_data0);
+  Free(tmph);
+}
+
+U0 HashTableDel(CHashTable *table)
+{//Free std system hash table, calling HashDel() on entries.
+  I64 i;
+  CHashSrcSym *tmph,*tmph1;
+  if (!table) return;
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      tmph1=tmph->next;
+      HashDel(tmph);
+      tmph=tmph1;
+    }
+  }
+  Free(table->body);
+  Free(table);
+}
+
+I64 HashTablePurge(CHashTable *table)
+{//Eliminate ExportSysSyms that have been usurped.
+  I64 i,res=0;
+  CHashSrcSym *tmph,*tmph1,*tmph2;
+  if (!table) return 0;
+  PUSHFD
+  CLI    //Precaution
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      tmph1=tmph->next; //We delete only older ones
+      if (tmph->type&(HTT_FUN|HTT_GLBL_VAR)) {
+        tmph2=tmph->next; //Older always later in chain
+        while (tmph2) {
+          if ((tmph2->type&HTT_EXPORT_SYS_SYM ||
+                tmph2->type&HTG_TYPE_MASK==HTT_INVALID) &&
+                !StrCmp(tmph2->str,tmph->str)) {
+            if (tmph2->type&HTG_TYPE_MASK==HTT_INVALID)
+              tmph2->type=HTT_KEYWORD;//Won't delete HTT_INVALID
+            HashRemDel(tmph2,table);
+            res++;
+            break;
+          }
+          tmph2=tmph2->next;
+        }
+      }
+      tmph=tmph1;
+    }
+  }
+  POPFD
+  return res;
+}
+
+CHashGeneric *HashGenericAdd(U8 *name,I64 type,
+        I64 u0=0,I64 u1=0,I64 u2=0,CTask *task=NULL)
+{//Add any type to task hash_table, 3 user_data values.
+  if (!task) task=Fs;
+  CHashGeneric *res=CAlloc(sizeof(CHashGeneric),task);
+  res->type=type;
+  res->user_data0=u0;
+  res->user_data1=u1;
+  res->user_data2=u2;
+  res->str=StrNew(name,task);
+  HashAdd(res,task->hash_table);
+  return res;
+}
+
+U0 HashSrcFileSet(CCmpCtrl *cc,CHashSrcSym *h,I64 line_num_offset=0)
+{//Set CHashSrcSym link and help_index by cur cc pos.
+  CLexFile *tmpf=cc->lex_include_stk;
+  I64 line_num=tmpf->line_num+line_num_offset;
+  if (line_num<1) line_num=1;
+  Free(h->src_link);
+  h->src_link=MStrPrint("FL:%s,%d",tmpf->full_name,line_num);
+  if (Bt(&cc->opts,OPTf_KEEP_PRIVATE))
+    h->type|=HTF_PRIVATE;
+  Free(h->idx);
+  if (cc->cur_help_idx && *cc->cur_help_idx)
+    h->idx=StrNew(cc->cur_help_idx);
+  else
+    h->idx=NULL;
+}
+
+CHashGeneric *HashPublic(U8 *st,I64 mask,Bool val=TRUE)
+{//Mark a hash entry as public and HashSrcFileSet().
+  CHashGeneric *res;
+  if (res=HashFind(st,Fs->hash_table,mask)) {
+    if (val)
+      res->type|=HTF_PUBLIC;
+    else
+      res->type&=~HTF_PUBLIC;
+    if (res->type&HTG_SRC_SYM)
+      HashSrcFileSet(Fs->last_cc,res);
+    return res;
+  } else
+    return NULL;
+}
+
+I64 HashLstAdd(U8 *lst,I64 type,CHashTable *table)
+{//Add a list to a hash table.
+  I64 i=0;
+  CHashGeneric *tmph;
+  if (lst) {
+    while (*lst) {
+      if (*lst=='@')
+        lst++;
+      else
+        i++;
+      tmph=CAlloc(sizeof(CHashGeneric));
+      tmph->user_data0=i-1;
+      tmph->str=StrNew(lst);
+      tmph->type=type;
+      HashAdd(tmph,table);
+      while (*lst++);
+    }
+  }
+  return i;
+}
+
+I64 HashDefineLstAdd(U8 *dname,I64 type,CHashTable *table)
+{//Add define list to a hash table. See ::/Adam/DolDoc/DocInit.HC.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR))
+    return HashLstAdd(tmph->data,type,table);
+  else
+    return 0;
+}
+
+I64 FramePtr(U8 *name,CTask *task=NULL)
+{//Find entry in task->hash_table, Return user_data.
+  CHashGeneric *tmph;
+  if (!task) task=Fs;
+  if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR))
+    return tmph->user_data0;
+  else
+    return 0;
+}
+
+CHashGeneric *FramePtrAdd(U8 *name,I64 val=0,CTask *task=NULL)
+{//Add named value to task->hash_table.
+  return HashGenericAdd(name,HTT_FRAME_PTR,val,0,0,task);
+}
+
+I64 FramePtrSet(U8 *name,I64 val,CTask *task=NULL)
+{//Find hash entry in task->hash_table. Change user_data0.
+  CHashGeneric *tmph;
+  if (!task) task=Fs;
+  if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR))
+    return LXchgI64(&tmph->user_data0,val);
+  else
+    return 0;
+}
+
+I64 FramePtrDel(U8 *name,CTask *task=NULL)
+{//Remove entry and delete.
+  CHashGeneric *tmph;
+  I64 res=0;
+  if (!task) task=Fs;
+  if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR)) {
+    res=tmph->user_data0;
+    HashRemDel(tmph,task->hash_table);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KInts.HC.HTML b/public/Wb/Home/Src/Kernel/KInts.HC.HTML new file mode 100755 index 0000000..cf58e18 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KInts.HC.HTML @@ -0,0 +1,246 @@ + + + + + + + + + + + +
+asm {
+INT_MP_CRASH_ADDR:: //Forward reference to work around compiler
+        DU32    &IntMPCrash;
+
+INT_WAKE::
+        PUSH    RDX
+        PUSH    RAX
+        MOV     EAX,&dev
+        MOV     EDX,U32 LAPIC_EOI
+        MOV     RAX,U64 CDevGlbls.uncached_alias[RAX]
+        MOV     U32 [RAX+RDX],0
+        POP     RAX
+        POP     RDX
+        IRET
+
+IRQ_TIMER::  //I_TIMER
+        CALL    TASK_CONTEXT_SAVE
+        CLD
+
+        MOV     RAX,U64 [RSP]
+        MOV     U64 CTask.rip[RSI],RAX
+        MOV     RAX,U64 16[RSP]
+        MOV     U64 CTask.rflags[RSI],RAX
+        MOV     RAX,U64 24[RSP]
+        MOV     U64 CTask.rsp[RSI],RAX
+
+        XOR     RAX,RAX
+        MOV     RDI,U64 GS:CCPU.addr[RAX]
+        LOCK
+        INC     U64 CCPU.total_jiffies[RDI]
+
+        BT      U64 CTask.task_flags[RSI],TASKf_IDLE
+        JNC     @@05
+        LOCK
+        INC     U64 CCPU.idle_pt_hits[RDI]
+
+@@05:   MOV     RAX,U64 CCPU.profiler_timer_irq[RDI]
+        TEST    RAX,RAX
+        JZ      @@10
+        PUSH    RSI
+        CALL    RAX     //See ProfTimerInt().
+        JMP     @@15
+@@10:   ADD     RSP,8
+@@15:   CLI
+        MOV     RAX,U64 CCPU.num[RDI]
+        TEST    RAX,RAX
+        JZ      @@20
+
+        MOV     EAX,&dev
+        MOV     EDX,U32 LAPIC_EOI
+        MOV     RAX,U64 CDevGlbls.uncached_alias[RAX]
+        MOV     U32 [RAX+RDX],0
+        JMP     @@25
+
+@@20:   CALL    &IntCore0TimerHndlr     //Only Core 0 calls this.
+@@25:   XOR     RAX,RAX
+        CMP     RSI,U64 GS:CCPU.idle_task[RAX]
+        JE      I32 RESTORE_SETH_TASK_IF_READY
+        JMP     I32 RESTORE_RSI_TASK
+//************************************
+INT_FAULT::
+        PUSH    RBX
+        PUSH    RAX
+        MOV     BL,U8 16[RSP]   //We pushed fault_num IntFaultHndlrsNew().
+        XOR     RAX,RAX
+        MOV     FS:U8 CTask.fault_num[RAX],BL
+        POP     RAX
+        POP     RBX
+        ADD     RSP,8           //Pop fault_num
+
+        CALL    TASK_CONTEXT_SAVE
+
+        XOR     RDX,RDX
+        MOV     U64 CTask.fault_err_code[RSI],RDX
+        MOV     EDX,U32 CTask.fault_num[RSI]
+        BT      U64 [INT_FAULT_ERR_CODE_BITMAP],RDX
+        JNC     @@1
+        POP     U64 CTask.fault_err_code[RSI]
+
+@@1:    MOV     RAX,U64 [RSP]
+        MOV     U64 CTask.rip[RSI],RAX
+        MOV     RAX,U64 16[RSP]
+        MOV     U64 CTask.rflags[RSI],RAX
+        MOV     RSP,U64 24[RSP]
+        MOV     U64 CTask.rsp[RSI],RSP
+        MOV     RBP,CTask.rbp[RSI]
+        PUSH    U64 CTask.fault_err_code[RSI]
+        PUSH    U64 CTask.fault_num[RSI]
+        MOV     RSI,CTask.rsi[RSI]
+        CALL    &Fault2         //See Fault2
+        JMP     I32 RESTORE_FS_TASK
+
+INT_FAULT_ERR_CODE_BITMAP::
+        DU32    0x00027D00,0,0,0,0,0,0,0;
+}
+
+U8 *IntEntryGet(I64 irq)
+{//Get interrupt vector.
+  U8 *res;
+  I64 *src;
+  src=dev.idt(U8 *)+irq*16;
+  res(I64).u16[0]=*src(U16 *);
+  src(U8 *)+=6;
+  res(I64).u16[1]=*src(U16 *)++;
+  res(I64).u32[1]=*src(U32 *);
+  return res;
+}
+
+U8 *IntEntrySet(I64 irq,U0 (*fp_new_hndlr)(),I64 type=IDTET_IRQ,I64 dpl=0)
+{//Set interrupt vector. See IDTET_IRQ.
+//See ::/Demo/Lectures/InterruptDemo.HC.
+  //See ::/Demo/MultiCore/Interrupts.HC.
+  I64 fp=fp_new_hndlr;
+  U8 *res,*dst;
+  PUSHFD
+  CLI
+  res=IntEntryGet(irq);
+  dst=dev.idt(U8 *)+irq*16;
+  *dst(U16 *)++=fp.u16[0];
+  *dst(U16 *)++=offset(CGDT.cs64);
+  *dst(U16 *)++=0x8000+type<<8+dpl<<13;
+  *dst(U16 *)++=fp.u16[1];
+  *dst(U32 *)++=fp.u32[1];
+  *dst(U32 *)=0;
+  POPFD
+  return res;
+}
+
+U0 IntsInit()
+{//Init 8259
+  OutU8(0x20,0x11); //IW1
+  OutU8(0xA0,0x11); //IW1
+  OutU8(0x21,0x20); //IW2
+  OutU8(0xA1,0x28); //IW2
+  OutU8(0x21,0x04); //IW3
+  OutU8(0xA1,0x02); //IW3
+  OutU8(0x21,0x0D); //IW4
+  OutU8(0xA1,0x09); //IW4
+  OutU8(0x21,0xFA); //Mask all but IRQ0 (timer) and IRQ2 Cascade.
+  OutU8(0xA1,0xFF);
+}
+
+interrupt U0 IntNop()
+{//Make unplanned IRQs stop by all means!
+  OutU8(0xA0,0x20);
+  OutU8(0x20,0x20);
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntDivZero()
+{
+  if (Gs->num) {
+    mp_cnt=1;
+    dbg.mp_crash->cpu_num=Gs->num;
+    dbg.mp_crash->task=Fs;
+    MOV RAX,U64 8[RBP] //Get RIP off of stk.
+    dbg.mp_crash->rip=GetRAX;
+    dbg.mp_crash->msg="Div Zero";
+    dbg.mp_crash->msg_num=0;
+    MPInt(I_MP_CRASH,0);
+    SysHlt;
+  }
+  throw('DivZero');
+}
+
+U8 *IntFaultHndlrsNew()
+{
+  I64 i;
+  U8 *res=MAlloc(256*7,Fs->code_heap),*dst=res;
+  for (i=0;i<256;i++) {
+    *dst++=0x6A; //PUSH I8 xx
+    *dst(I8 *)++=i;
+    *dst++=0xE9; //JMP  I32 xxxxxxxx
+    *dst(I32 *)=INT_FAULT-dst-4;
+    dst+=4;
+  }
+  return res;
+}
+
+U0 IntInit1()
+{//Interrupt descriptor table part1.
+  I64 i;
+  CSysLimitBase tmp_ptr;
+  if (!Gs->num) {//Gs cur CCPU struct
+    dev.idt=CAlloc(16*256);
+    for (i=0;i<256;i++)
+      IntEntrySet(i,&IntNop);
+  }
+  tmp_ptr.limit=256*16-1;
+  tmp_ptr.base =dev.idt;
+  SetRAX(&tmp_ptr);
+  LIDT U64 [RAX]
+}
+
+U0 IntInit2()
+{//Interrupt descriptor table part2: Core 0 Only.
+  I64 i;
+  PUSHFD
+  CLI
+  IntEntrySet(I_DIV_ZERO,&IntDivZero);
+  for (i=1;i<0x20;i++)
+    IntEntrySet(i,&dbg.int_fault_code[7*i]);
+/*In theory, we use the PIC mask reg to insure we don't get
+anything but keyboard, mouse and timer IRQs.  In practice, I've
+gotten IRQ 0x27, perhaps because I didn't initialize the APIC.
+I go ahead and ACK PIC in IntNop().
+I have no idea why I got a IRQ 0x27.
+*/
+  IntEntrySet(I_NMI,_SYS_HLT);
+  IntEntrySet(I_TIMER,IRQ_TIMER);
+  IntEntrySet(I_MP_CRASH,*INT_MP_CRASH_ADDR(U32 *));
+  IntEntrySet(I_WAKE,INT_WAKE);
+  IntEntrySet(I_DBG,&dbg.int_fault_code[7*I_DBG]);
+  POPFD
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KLoad.HC.HTML b/public/Wb/Home/Src/Kernel/KLoad.HC.HTML new file mode 100755 index 0000000..4556ffd --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KLoad.HC.HTML @@ -0,0 +1,281 @@ + + + + + + + + + + + +
+U0 LoadOneImport(U8 **_src,U8 *module_base,I64 ld_flags)
+{
+  U8 *src=*_src,*ptr2,*st_ptr;
+  I64 i,etype;
+  CHashExport *tmpex=NULL;
+  CHashImport *tmpiss;
+  Bool first=TRUE;
+
+  while (etype=*src++) {
+    i=*src(U32 *)++;
+    st_ptr=src;
+    src+=StrLen(st_ptr)+1;
+    if (*st_ptr) {
+      if (!first) {
+        *_src=st_ptr-5;
+        return;
+      } else {
+        first=FALSE;
+        if (!(tmpex=HashFind(st_ptr,
+              Fs->hash_table,HTG_ALL-HTT_IMPORT_SYS_SYM))) {
+          if (!(ld_flags & LDF_SILENT))
+            "Unresolved Reference:%s\n",st_ptr;
+          tmpiss=CAlloc(sizeof(CHashImport));
+          tmpiss->str=StrNew(st_ptr);
+          tmpiss->type=HTT_IMPORT_SYS_SYM;
+          tmpiss->module_header_entry=st_ptr-5;
+          tmpiss->module_base=module_base;
+          HashAdd(tmpiss,Fs->hash_table);
+        }
+      }
+    }
+    if (tmpex) {
+      ptr2=module_base+i;
+      if (tmpex->type & HTT_FUN)
+        i=tmpex(CHashFun *)->exe_addr;
+      else if (tmpex->type & HTT_GLBL_VAR)
+        i=tmpex(CHashGlblVar *)->data_addr;
+      else
+        i=tmpex->val;
+      switch (etype) {
+        case IET_REL_I8:  *ptr2(U8 *) =i-ptr2-1; break;
+        case IET_IMM_U8:  *ptr2(U8 *) =i;  break;
+        case IET_REL_I16: *ptr2(U16 *)=i-ptr2-2; break;
+        case IET_IMM_U16: *ptr2(U16 *)=i; break;
+        case IET_REL_I32: *ptr2(U32 *)=i-ptr2-4; break;
+        case IET_IMM_U32: *ptr2(U32 *)=i; break;
+        case IET_REL_I64: *ptr2(I64 *)=i-ptr2-8; break;
+        case IET_IMM_I64: *ptr2(I64 *)=i; break;
+      }
+    }
+  }
+  *_src=src-1;
+}
+
+U0 SysSymImportsResolve(U8 *st_ptr,I64 ld_flags)
+{
+  CHashImport *tmpiss;
+  U8 *ptr;
+  while (tmpiss=HashSingleTableFind(st_ptr,
+        Fs->hash_table,HTT_IMPORT_SYS_SYM)) {
+    ptr=tmpiss->module_header_entry;
+    LoadOneImport(&ptr,tmpiss->module_base,ld_flags);
+    tmpiss->type=HTT_INVALID;
+  }
+}
+
+U0 LoadPass1(U8 *src,U8 *module_base,I64 ld_flags)
+{
+  U8 *ptr2,*ptr3,*st_ptr;
+  I64 i,j,cnt,etype;
+  CHashExport *tmpex=NULL;
+  while (etype=*src++) {
+    i=*src(U32 *)++;
+    st_ptr=src;
+    src+=StrLen(st_ptr)+1;
+    switch (etype) {
+      case IET_REL32_EXPORT:
+      case IET_IMM32_EXPORT:
+      case IET_REL64_EXPORT:
+      case IET_IMM64_EXPORT:
+        tmpex=CAlloc(sizeof(CHashExport));
+        tmpex->str=StrNew(st_ptr);
+        tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+        if (etype==IET_IMM32_EXPORT||etype==IET_IMM64_EXPORT)
+          tmpex->val=i;
+        else
+          tmpex->val=i+module_base;
+        HashAdd(tmpex,Fs->hash_table);
+        SysSymImportsResolve(st_ptr,ld_flags);
+        break;
+      case IET_REL_I0...IET_IMM_I64:
+        src=st_ptr-5;
+        LoadOneImport(&src,module_base,ld_flags);
+        break;
+      case IET_ABS_ADDR:
+        if (ld_flags & LDF_NO_ABSS)
+          src+=i*sizeof(U32);
+        else {
+          cnt=i;
+          for (j=0;j<cnt;j++) {
+            ptr2=module_base+*src(U32 *)++;
+            *ptr2(U32 *)+=module_base;
+          }
+        }
+        break;
+
+      start:
+        case IET_CODE_HEAP:
+          ptr3=MAlloc(*src(I32 *)++,Fs->code_heap);
+          break;
+        case IET_ZEROED_CODE_HEAP:
+          ptr3=CAlloc(*src(I32 *)++,Fs->code_heap);
+          break;
+      end:
+        if (*st_ptr) {
+          tmpex=CAlloc(sizeof(CHashExport));
+          tmpex->str=StrNew(st_ptr);
+          tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+          tmpex->val=ptr3;
+          HashAdd(tmpex,Fs->hash_table);
+        }
+        cnt=i;
+        for (j=0;j<cnt;j++) {
+          ptr2=module_base+*src(U32 *)++;
+          *ptr2(I32 *)+=ptr3;
+        }
+        break;
+
+      start:
+        case IET_DATA_HEAP:
+          ptr3=MAlloc(*src(I64 *)++);
+          break;
+        case IET_ZEROED_DATA_HEAP:
+          ptr3=CAlloc(*src(I64 *)++);
+          break;
+      end:
+        if (*st_ptr) {
+          tmpex=CAlloc(sizeof(CHashExport));
+          tmpex->str=StrNew(st_ptr);
+          tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+          tmpex->val=ptr3;
+          HashAdd(tmpex,Fs->hash_table);
+        }
+        cnt=i;
+        for (j=0;j<cnt;j++) {
+          ptr2=module_base+*src(U32 *)++;
+          *ptr2(I64 *)+=ptr3;
+        }
+        break;
+    }
+  }
+}
+
+U0 LoadPass2(U8 *src,U8 *module_base,I64)
+{
+  U8 *st_ptr;
+  I64 i,etype;
+  while (etype=*src++) {
+    i=*src(U32 *)++;
+    st_ptr=src;
+    src+=StrLen(st_ptr)+1;
+    switch (etype) {
+      case IET_MAIN:
+        Call(i+module_base);
+        break;
+      case IET_ABS_ADDR:
+        src+=sizeof(U32)*i;
+        break;
+      case IET_CODE_HEAP:
+      case IET_ZEROED_CODE_HEAP:
+        src+=4+sizeof(U32)*i;
+        break;
+      case IET_DATA_HEAP:
+      case IET_ZEROED_DATA_HEAP:
+        src+=8+sizeof(U32)*i;
+        break;
+    }
+  }
+}
+
+CBinFile *Load(U8 *filename,I64 ld_flags=0,CBinFile *bfh_addr=INVALID_PTR)
+{//Load a .BIN file module into memory.
+//bfh_addr==INVALID_PTR means don't care what load addr.
+  U8 *fbuf,*module_base,*absname;
+  I64 size,module_align,misalignment;
+  CBinFile *bfh;
+
+  fbuf=ExtDft(filename,"BIN.Z");
+  if (!(bfh=FileRead(fbuf,&size))) {
+    Free(fbuf);
+    return NULL;
+  }
+
+  //See Patch Table Generation
+  module_align=1<<bfh->module_align_bits;
+  if (!module_align || bfh->bin_signature!=BIN_SIGNATURE_VAL) {
+    Free(bfh);
+    Free(fbuf);
+    throw('BinModul');
+  }
+
+  if (bfh_addr==INVALID_PTR) {
+    if (bfh->org==INVALID_PTR) {
+      misalignment=module_align-sizeof(CBinFile);
+      if (misalignment<0)
+        misalignment&=module_align-1;
+      if (Fs->code_heap!=Fs->data_heap) {
+        if (module_align<16)
+          module_align=16;
+        bfh_addr=MAllocAligned(size,module_align,Fs->code_heap,misalignment);
+      } else if (module_align>8)
+        bfh_addr=MAllocAligned(size,module_align,,misalignment);
+      else {//Less than 2Gig system memory
+        bfh_addr=bfh;
+        goto lo_skip; //File is already in code heap area, don't copy.
+      }
+    } else
+      bfh_addr=bfh->org;
+  }
+  MemCpy(bfh_addr,bfh,size);
+  Free(bfh);
+
+  lo_skip:
+  module_base=bfh_addr(U8 *)+sizeof(CBinFile);
+
+  absname=FileNameAbs(fbuf);
+  Free(fbuf);
+  fbuf=StrNew(absname);
+  FileExtRem(fbuf);
+  if (fbuf[1]==':' && StrLen(fbuf)>2)
+    HashGenericAdd(fbuf+2,HTT_MODULE|HTF_PUBLIC,bfh_addr);
+  LoadPass1(bfh_addr(U8 *)+bfh_addr->patch_table_offset,module_base,ld_flags);
+  if (!(ld_flags&LDF_JUST_LOAD))
+    LoadPass2(bfh_addr(U8 *)+bfh_addr->patch_table_offset,module_base,ld_flags);
+  Free(absname);
+  Free(fbuf);
+  return bfh_addr;
+}
+
+U0 LoadKernel()
+{
+  HashGenericAdd(KERNEL_MODULE_NAME,HTT_MODULE|HTF_PUBLIC,
+        mem_boot_base-sizeof(CBinFile));
+
+  //Abs patches done here CPatchTableAbsAddr.
+  LoadPass1(sys_boot_patch_table_base,mem_boot_base,LDF_NO_ABSS|LDF_SILENT);
+
+  //No main routines
+  //  LoadPass2(sys_boot_patch_table_base,mem_boot_base,0);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KMain.HC.HTML b/public/Wb/Home/Src/Kernel/KMain.HC.HTML new file mode 100755 index 0000000..dae91cf --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KMain.HC.HTML @@ -0,0 +1,269 @@ + + + + + + + + + + + +
+U0 SysGlblsInit()
+{
+  I64 i,j;
+  CRAXRBCRCXRDX ee;
+
+  CPUId(0x1,&ee);
+  sys_cache_line_width=ee.rbx.u8[1]*8;
+
+  sys_focus_task=Fs;
+  QueInit(&sys_macro_head);
+
+  blkdev.dft_iso_filename       =AStrNew(DFT_ISO_FILENAME);
+  blkdev.dft_iso_c_filename     =AStrNew(DFT_ISO_C_FILENAME);
+  blkdev.tmp_filename           =AStrNew("~/Tmp.DD.Z");
+  blkdev.dvd_boot_is_good=TRUE;
+  #exe {
+    if (!kernel_cfg->mount_ide_auto_hd_let)
+      kernel_cfg->mount_ide_auto_hd_let='C';
+    if (!kernel_cfg->mount_ide_auto_cd_let)
+      kernel_cfg->mount_ide_auto_cd_let='T';
+    StreamPrint("blkdev.first_hd_drv_let=%d;",
+          kernel_cfg->mount_ide_auto_hd_let);
+    StreamPrint("blkdev.first_dvd_drv_let=%d;",
+          kernel_cfg->mount_ide_auto_cd_let);
+  }
+
+  DbgMode(ON);
+  rev_bits_table=CAlloc(256);
+  set_bits_table=CAlloc(256);
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++) {
+      if (Bt(&i,7-j))   LBts(rev_bits_table+i,j);
+      if (Bt(&i,j))     set_bits_table[i]++;
+    }
+
+  ext=CAlloc(EXT_EXTS_NUM*sizeof(U8 *));
+  fp_getstr2=&SysGetStr2;
+  KeyDevInit;
+
+  #exe {
+    StreamPrint("blkdev.boot_drv_let='%C';",kernel_cfg->boot_drv_let);
+    StreamPrint("#exe{Option(OPTf_WARN_PAREN,OFF);}");
+    StreamPrint("DskCacheInit(%s);",kernel_cfg->dsk_cache_size_exp);
+    StreamPrint("#exe{Option(OPTf_WARN_PAREN,ON);}");
+  };
+
+  pow10_I64=CAlloc(sizeof(F64)*(308+308+1));
+  for (i=-308;i<309;i++)
+    pow10_I64[i+309]=Pow10(i);
+
+  QueInit(&scrncast.snd_head);
+  scrncast.t0_now=Now;
+  scrncast.t0_tS=tS;
+  scrncast.ona=scrncast.snd_head.ona=0;
+
+  ProgressBarsRst;
+
+  QueInit(&dev.pci_head);
+  dev.mem64_ptr=mem_mapped_space;
+
+  dbg.fun_seg_cache=CAlloc(FUN_SEG_CACHE_SIZE*sizeof(CFunSegCache));
+  dbg.int_fault_code=IntFaultHndlrsNew;
+}
+
+U0 SysGrInit()
+{
+  text.font=sys_font_std;
+  text.aux_font=sys_font_cyrillic;
+  text.vga_alias        =dev.uncached_alias+VGAM_GRAPHICS;
+  text.vga_text_alias   =dev.uncached_alias+VGAM_TEXT;
+  if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
+    text.cols=80;
+    text.rows=25;
+    MemSet(text.vga_text_alias,0,text.rows*text.cols<<1);
+    text.border_chars[2] (I64)='........';
+    text.border_chars[10](U32)='....';
+  } else { //if 640x480 16 color
+    text.cols=GR_WIDTH/FONT_WIDTH;
+    text.rows=GR_HEIGHT/FONT_HEIGHT;
+    OutU8(VGAP_IDX,VGAR_MAP_MASK);
+    OutU8(VGAP_DATA,0x0F);
+    MemSet(text.vga_alias,0,GR_WIDTH*GR_HEIGHT>>3);
+    text.raw_scrn_image=CAlloc(GR_WIDTH*GR_HEIGHT/8);
+    text.border_chars[2] (I64)=0x0908070605040302;
+    text.border_chars[10](U32)=0x0D0C0B0A;
+  }
+}
+
+U0 TimersInit()
+{
+  I64 i,*_q;
+  U32 *_d;
+
+  OutU8(0x43,0x34);
+  OutU8(0x40,SYS_TIMER0_PERIOD);
+  OutU8(0x40,SYS_TIMER0_PERIOD>>8);
+
+  //High Precision Event Timer
+  if (PCIReadU16(0,31,0,0)==0x8086) {//Intel?
+//D31 F0, cfg 0xF0=RCBA of PCI-LPC Bridge
+    _d=PCIReadU32(0,31,0,0xF0)(U8 *)&~0x3FFF+0x3404; //HPET cfg
+//7     enable
+    //1:0 HPET is at 0xFED00000,0xFED01000, 0xFED02000 or 0xFED03000.
+    *_d=*_d&3|0x80;
+  }
+
+  _q=dev.uncached_alias+HPET_GCAP_ID;
+  i=*_q; //i.u32[1]= period in femtoS (10e-15)
+  if (100000<i.u32[1]<1000000000) {
+    cnts.HPET_freq    =1000000000000000/i.u32[1];
+    cnts.HPET_kHz_freq=1000000000000/i.u32[1];
+    _q=dev.uncached_alias+HPET_GEN_CONF;
+    *_q|=1; //Enable counting
+    cnts.HPET_initial=HPET;
+  } else {
+    cnts.HPET_freq=0;
+    cnts.HPET_kHz_freq=0;
+    cnts.HPET_initial=0;
+  }
+}
+
+U0 Reboot()
+{//Hardware reset.
+  CLI
+  if (mp_cnt>1)
+    MPHalt;
+  *0x472(U16 *)=0;
+  OutU8(0x70,0x8F);
+  OutU8(0x71,0x00);
+  OutU8(0x70,0x00);
+  OutU8(0x92,InU8(0x92)|1);
+  SysHlt;
+}
+
+U0 KMain()
+{//Continued from KStart64.HC
+  CBlkDev *bd;
+  OutU8(0x61,InU8(0x61)&~3); //Snd;
+  adam_task=Fs;
+  BlkPoolsInit;
+  SysGlblsInit;
+  Mem32DevInit;
+  UncachedAliasAlloc;
+  LoadKernel;
+  SysGrInit;
+  StrCpy(Fs->task_name,"Adam Task CPU00");
+  StrCpy(Fs->task_title,Fs->task_name);
+  Fs->title_src=TTS_TASK_NAME;
+  Fs->win_right=text.cols-2;
+  Fs->win_top++;
+  TaskDerivedValsUpdate;
+
+  SysDefinesLoad;
+  Core0Init;
+  IntInit1;
+
+  //Before this point use Snd() and Busy()
+  //to debug.  After this point, use RawPrint()
+  LBts(&sys_run_level,RLf_RAW);
+  "TempleOS V%5.3f\t%D %T\n\n",
+        sys_os_version,sys_compile_time,sys_compile_time;
+
+  TimersInit;
+  if (BIOSTotalMem<ToI64(0.95*MEM_MIN_MEG*0x100000))
+    RawPrint(4000,"!!! Requires 512Meg of RAM Memory !!!");
+
+  IntsInit;
+  "Enable IRQ's\n";
+  SetRFlags(RFLAGG_NORMAL);
+  Busy(2000);
+  IntInit2;
+  LBts(&sys_run_level,RLf_INTERRUPTS);
+
+  TimeCal;
+  BlkDevsInitAll;
+  "DskChg(':');\n";
+  DskChg(':');
+  #exe {
+    StreamPrint("HomeSet(\"%s\");\n"
+          "blkdev.ins_base0=%d;blkdev.ins_base1=%d;blkdev.ins_unit =%d;\n",
+          kernel_cfg->home_dir,
+          blkdev.ins_base0,blkdev.ins_base1,blkdev.ins_unit);
+  }
+  Gs->idle_task->cur_dv=blkdev.let_to_drv[*blkdev.home_dir-'A'];
+  DrvRep;
+  if (blkdev.dvd_boot_is_good) {
+    bd=Let2BlkDev(':');
+    if (bd->type==BDT_ATAPI) {
+      blkdev.ins_base0=bd->base0;
+      blkdev.ins_base1=bd->base1;
+      blkdev.ins_unit =bd->unit;
+    }
+  }
+  LBts(&sys_run_level,RLf_BLKDEV);
+
+  #exe {
+    if (!kernel_cfg->opts[CFG_NO_MP])
+      StreamPrint("\"MultiCore Start\\n\\n\";"
+            "Core0StartMP;"
+            "LBts(&sys_run_level,RLf_MP);");
+  };
+
+  KbdMsInit;
+  MsInit;
+  KbdInit;
+  Spawn(&MsHardDrvrInstall);
+
+  "Loading Compiler\n";
+  Cd("/Compiler");
+  Load("Compiler",LDF_SILENT);
+  LBts(&sys_run_level,RLf_COMPILER);
+
+  DbgMode(OFF);
+  cnts.time_stamp_freq_initial=TimeCal;
+  Cd("/");
+  try ExeFile("StartOS"); //Continues /StartOS.HC
+  catch {
+    Raw(ON);
+    Silent(OFF);
+    GetOutOfDollar;
+    PutExcept;
+    Dbg;
+  }
+
+  LBts(&sys_run_level,RLf_ADAM_SERVER);
+  SrvTaskCont; //Never to return
+}
+
+asm {   ALIGN   16,OC_NOP
+SYS_KERNEL_END::
+#exe {
+  if (kernel_cfg->opts[CFG_DBG_DISTRO])
+    StreamPrint("DU8 0x%X-(SYS_KERNEL_END-SYS_KERNEL+"
+        "BOOT_RAM_BASE+sizeof(CBinFile)) DUP (0);"
+        "BINFILE \"%s\";",kernel_cfg->dbg_distro_start,
+                          kernel_cfg->dbg_distro_file);
+};
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KMathA.HC.HTML b/public/Wb/Home/Src/Kernel/KMathA.HC.HTML new file mode 100755 index 0000000..beac510 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KMathA.HC.HTML @@ -0,0 +1,679 @@ + + + + + + + + + + + +
+asm {
+//************************************
+_D3_NORM::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        FLD     U64 [RDX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSQRT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_D3_NORM_SQR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        FLD     U64 [RDX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_D3_DIST::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RDX]
+        FSUB    ST0,U64 [RBX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FSUB    ST0,U64 8[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FSUB    ST0,U64 16[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSQRT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_DIST_SQR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RDX]
+        FSUB    ST0,U64 [RBX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FSUB    ST0,U64 8[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FSUB    ST0,U64 16[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_CROSS::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+
+        FLD     U64 8[RDX]
+        FMUL    ST0,U64 16[RBX]
+        FLD     U64 16[RDX]
+        FMUL    ST0,U64 8[RBX]
+        FSUBP   ST1,ST0
+        FSTP    U64 [RAX]
+
+        FLD     U64 [RDX]
+        FMUL    ST0,U64 16[RBX]
+        FLD     U64 16[RDX]
+        FMUL    ST0,U64 [RBX]
+        FSUBRP  ST1,ST0
+        FSTP    U64 8[RAX]
+
+        FLD     U64 [RDX]
+        FMUL    ST0,U64 8[RBX]
+        FLD     U64 8[RDX]
+        FMUL    ST0,U64 [RBX]
+        FSUBP   ST1,ST0
+        FSTP    U64 16[RAX]
+
+        POP     RBP
+        RET1    24
+//************************************
+_D3_DOT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RDX]
+        FMUL    ST0,U64 [RBX]
+        FLD     U64 8[RDX]
+        FMUL    ST0,U64 8[RBX]
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FMUL    ST0,U64 16[RBX]
+        FADDP   ST1,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_ADD::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        FLD     U64 [RDX]
+        FADD    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RDX]
+        FADD    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RDX]
+        FADD    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_SUB::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        FLD     U64 [RDX]
+        FSUB    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RDX]
+        FSUB    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RDX]
+        FSUB    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_MUL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        FLD     U64 SF_ARG2[RBP]
+        FLD     ST0
+        FMUL    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FMUL    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FMUL    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_DIV::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 SF_ARG3[RBP]
+        FLD     ST0
+        FDIVR   ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FDIVR   ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FDIVR   ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_ZERO::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        XOR     RDX,RDX
+        MOV     U64 [RAX],RDX
+        MOV     U64 8[RAX],RDX
+        MOV     U64 16[RAX],RDX
+        POP     RBP
+        RET1    8
+//************************************
+_D3_COPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 [RBX]
+        MOV     U64 [RAX],RDX
+        MOV     RDX,U64 8[RBX]
+        MOV     U64 8[RAX],RDX
+        MOV     RDX,U64 16[RBX]
+        MOV     U64 16[RAX],RDX
+        POP     RBP
+        RET1    16
+//************************************
+_D3_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     U64 [RAX],RDX
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     U64 8[RAX],RDX
+        MOV     RDX,U64 SF_ARG4[RBP]
+        MOV     U64 16[RAX],RDX
+        POP     RBP
+        RET1    32
+//************************************
+_D3_ADD_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RAX]
+        FADD    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RAX]
+        FADD    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RAX]
+        FADD    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_SUB_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RAX]
+        FSUB    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RAX]
+        FSUB    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RAX]
+        FSUB    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_MUL_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        FLD     U64 SF_ARG2[RBP]
+        FLD     ST0
+        FMUL    ST0,U64 [RAX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FMUL    ST0,U64 8[RAX]
+        FSTP    U64 8[RAX]
+        FMUL    ST0,U64 16[RAX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_DIV_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        FLD     U64 SF_ARG2[RBP]
+        FLD     ST0
+        FDIVR   ST0,U64 [RAX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FDIVR   ST0,U64 8[RAX]
+        FSTP    U64 8[RAX]
+        FDIVR   ST0,U64 16[RAX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_UNIT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        FLD     U64 [RAX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RAX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RAX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSQRT
+        FST     U64 SF_ARG1[RBP]
+        MOV     RBX,SF_ARG1[RBP]
+        TEST    RBX,RBX
+        JZ      @@05
+        FLD     ST0
+        FDIVR   ST0,U64 [RAX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FDIVR   ST0,U64 8[RAX]
+        FSTP    U64 8[RAX]
+        FDIVR   ST0,U64 16[RAX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    8
+@@05:   FFREE   ST0
+        FINCSTP
+        POP     RBP
+        RET1    8
+//************************************
+_SQR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD     U64 SF_ARG1[RBP]
+        FMUL    ST0,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_SIGN::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD     U64 SF_ARG1[RBP]
+        FTST
+        FSTSW
+        FFREE   ST0
+        FINCSTP
+        MOV     RDX,RAX
+        XOR     RAX,RAX
+        BT      RDX,14
+        JC      @@05
+        MOV     RAX,1.0
+        BT      RDX,8
+        JNC     @@05
+        MOV     RAX,-1.0
+@@05:   POP     RBP
+        RET1    8
+//************************************
+_ARG::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD     U64 SF_ARG2[RBP]
+        FLD     U64 SF_ARG1[RBP]
+@@05:   FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@05
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_ROUND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        AND     AX,~0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_TRUNC::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_FLOOR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        AND     AX,~0x0C00
+        OR      AX,0x0400
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_CEIL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        AND     AX,~0x0C00
+        OR      AX,0x0800
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+SYS_POW::
+// RAX=RDX`RAX
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,24
+        TEST    RAX,RAX //To power of zero?
+        JNZ     @@05
+        MOV     RAX,1.0
+        JMP     @@20
+@@05:   TEST    RDX,RDX //zero to a power?
+        JNZ     @@10
+        XOR     RAX,RAX
+        JMP     @@20
+@@10:   MOV     RCX,RAX //RCX=pow
+        MOV     U64 -8[RBP],RDX
+        MOV     U64 -16[RBP],RAX
+        FSTCW   U16 -24[RBP]
+        MOV     AX,U16 -24[RBP]
+        MOV     U16 -22[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -24[RBP],AX
+        FLDCW   U16 -24[RBP]
+        FLD     U64 -16[RBP]
+        FLD     U64 -8[RBP]
+        FABS    //base should be pos
+        FYL2X   // y*log2(x)
+        FST     U64 -8[RBP]
+        FRNDINT
+        FLD     U64 -8[RBP]
+        FSUBRP  ST1,ST0
+        F2XM1
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 -16[RBP]
+        FLD     U64 -8[RBP]
+        FLD     U64 -16[RBP]
+        FSCALE  // ST0<<ST1
+        TEST    RDX,RDX //was base neg?
+        JGE     @@15
+        MOV     U64 -16[RBP],RCX
+        FLD     U64 -16[RBP]
+        FISTTP  U64 -16[RBP]
+        TEST    U64 -16[RBP],1
+        JZ      @@15    //was pow odd?
+        FCHS
+@@15:   FSTP    U64 -8[RBP]
+        FFREE   ST0
+        FINCSTP
+        FLDCW   U16 -22[RBP]
+        MOV     RAX,U64 -8[RBP]
+@@20:   LEAVE
+        RET
+//************************************
+_POW::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 SF_ARG1[RBP]
+        CALL    SYS_POW
+        POP     RBP
+        RET1    16
+//************************************
+_POW10::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,16
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLDL2T
+        FLD     U64 SF_ARG1[RBP]
+        FMULP   ST1,ST0
+        FST     U64 SF_ARG1[RBP]
+        FRNDINT
+        FLD     U64 SF_ARG1[RBP]
+        FSUBRP  ST1,ST0
+        F2XM1
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 -16[RBP]
+        FLD     U64 SF_ARG1[RBP]
+        FLD     U64 -16[RBP]
+        FSCALE  // ST0<<ST1
+        FSTP    U64 -16[RBP]
+        FFREE   ST0
+        FINCSTP
+
+        FLDCW   U16 -6[RBP]
+        MOV     RAX,U64 -16[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_EXP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,16
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLDL2E
+        FLD     U64 SF_ARG1[RBP]
+        FMULP   ST1,ST0
+        FST     U64 SF_ARG1[RBP]
+        FRNDINT
+        FLD     U64 SF_ARG1[RBP]
+        FSUBRP  ST1,ST0
+        F2XM1
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 -16[RBP]
+        FLD     U64 SF_ARG1[RBP]
+        FLD     U64 -16[RBP]
+        FSCALE  // ST0<<ST1
+        FSTP    U64 -16[RBP]
+        FFREE   ST0
+        FINCSTP
+
+        FLDCW   U16 -6[RBP]
+        MOV     RAX,U64 -16[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_LOG10::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLDLG2
+        FLD     U64 SF_ARG1[RBP]
+        FYL2X   // y*log2(x)
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_LOG2::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD1
+        FLD     U64 SF_ARG1[RBP]
+        FYL2X   // y*log2(x)
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_LN::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLDLN2
+        FLD     U64 SF_ARG1[RBP]
+        FYL2X   // y*log2(x)
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_FLDCW::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLDCW   U16 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_FSTCW::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOVZX   RAX,U16 -8[RBP]
+        LEAVE
+        RET
+//************************************
+_FSTSW::
+        XOR     RAX,RAX
+        FSTSW
+        RET
+//************************************
+_FCLEX::
+        FCLEX
+        RET
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KMathB.HC.HTML b/public/Wb/Home/Src/Kernel/KMathB.HC.HTML new file mode 100755 index 0000000..f387217 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KMathB.HC.HTML @@ -0,0 +1,188 @@ + + + + + + + + + + + +
+F64 Clamp(F64 d,F64 lo,F64 hi)
+{//Clamp to F64 [] range.
+  if (d<lo)
+    return lo;
+  if (d>hi)
+    return hi;
+  return d;
+}
+
+F64 Min(F64 n1,F64 n2)
+{//Min of two F64s.
+  if (n1<=n2)
+    return n1;
+  else
+    return n2;
+}
+
+F64 Max(F64 n1,F64 n2)
+{//Max of two F64s.
+  if (n1>=n2)
+    return n1;
+  else
+    return n2;
+}
+
+F64 Pow10I64(I64 i)
+{//F64 int powers of ten.
+  if (i>308)
+    return inf;
+  else if (i<-308)
+    return 0.0;
+  else
+    return pow10_I64[i+309];
+}
+
+U64 FloorU64(U64 num,U64 to)
+{//Int multiples of num.
+  return num-num%to;
+}
+
+U64 CeilU64(U64 num,U64 to)
+{//Int multiples of num.
+  num+=to-1;
+  return num-num%to;
+}
+
+I64 RoundI64(I64 num,I64 to)
+{//Int multiples of num.
+  return num-num%to;
+}
+
+I64 FloorI64(I64 num,I64 to)
+{//Int multiples of num.
+  if (num>=0)
+    return num-num%to;
+  else {
+    num++;
+    return num-num%to-to;
+  }
+}
+
+I64 CeilI64(I64 num,I64 to)
+{//Int multiples of num.
+  if (num>=0) {
+    num+=to-1;
+    return num-num%to;
+  } else {
+    num+=to-1;
+    return num-num%to-to;
+  }
+}
+
+//See ::/Doc/Credits.DD.
+#define LIN_CONGRUE_A   6364136223846793005
+#define LIN_CONGRUE_C   1442695040888963407
+
+I16 RandI16()
+{//Random I16.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.i16[0];
+}
+
+U16 RandU16()
+{//Random U16.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.u16[0];
+}
+
+I32 RandI32()
+{//Random I32.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.i32[0];
+}
+
+U32 RandU32()
+{//Random U32.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.u32[0];
+}
+
+I64 RandI64()
+{//Random I64.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res;
+}
+
+U64 RandU64()
+{//Random U64.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res;
+}
+
+F64 Rand()
+{//Random F64.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return (res&0x3FFFFFFFFFFFFFFF)/ToF64(0x4000000000000000);
+}
+
+I64 Seed(I64 seed=0,CTask *task=NULL)
+{//Set Rand() seed. Zero for timer-based.
+  if (!task) task=Fs;
+  if (seed) {
+    LBts(&task->task_flags,TASKf_NONTIMER_RAND);
+    return task->rand_seed=seed;
+  } else {
+    LBtr(&task->task_flags,TASKf_NONTIMER_RAND);
+    return task->rand_seed^=GetTSC;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KMisc.HC.HTML b/public/Wb/Home/Src/Kernel/KMisc.HC.HTML new file mode 100755 index 0000000..b8d4ded --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KMisc.HC.HTML @@ -0,0 +1,357 @@ + + + + + + + + + + + +
+U0 PortNop()
+{//Innoculous (reads IRQ Mask) which should take fixed time
+//because it's an ISA-bus standard.  It takes 1.0uS-2.0uS.
+  InU8(0x21);
+}
+
+U16 EndianU16(U16 d)
+{//Swap big<-->little endian.
+  I64 res=0;
+  res.u8[1]=d.u8[0];
+  res.u8[0]=d.u8[1];
+  return res;
+}
+
+U32 EndianU32(U32 d)
+{//Swap big<-->little endian.
+  I64 res=0;
+  res.u8[3]=d.u8[0];
+  res.u8[2]=d.u8[1];
+  res.u8[1]=d.u8[2];
+  res.u8[0]=d.u8[3];
+  return res;
+}
+
+I64 EndianI64(I64 d)
+{//Swap big<-->little endian.
+  U64 res;
+  res.u8[7]=d.u8[0];
+  res.u8[6]=d.u8[1];
+  res.u8[5]=d.u8[2];
+  res.u8[4]=d.u8[3];
+  res.u8[3]=d.u8[4];
+  res.u8[2]=d.u8[5];
+  res.u8[1]=d.u8[6];
+  res.u8[0]=d.u8[7];
+  return res;
+}
+
+I64 BCnt(I64 d)
+{//Count set bits in I64.
+  I64 res=0,i;
+  for (i=0;i<8;i++)
+    res+=set_bits_table[d.u8[i]];
+  return res;
+}
+
+U0 IntCore0TimerHndlr(CTask *)
+{//Called from IntCore0TimerHndlr
+  I64 i;
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_SYS_TIMER],0))
+      PAUSE
+  lock cnts.jiffies++;
+  cnts.timer+=SYS_TIMER0_PERIOD+1;
+  LBtr(&sys_semas[SEMA_SYS_TIMER],0);
+  for (i=1;i<mp_cnt;i++)
+    MPInt(I_TIMER,i);
+  OutU8(0x20,0x20); //Acknowledge PIC Interrupt
+}
+
+I64 SysTimerRead()
+{//System timer count with overflow already handled.
+  I64 i,res;
+  PUSHFD
+  CLI
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_SYS_TIMER],0))
+      PAUSE
+  OutU8(0x43,0); //Latch Timer0
+  if ((i=InU8(0x40)+InU8(0x40)<<8)==SYS_TIMER0_PERIOD) {
+    if (InU8(0x20) & 1)
+      i=-1;
+  }
+  res=cnts.timer+SYS_TIMER0_PERIOD-i;
+  LBtr(&sys_semas[SEMA_SYS_TIMER],0);
+  POPFD
+  return res;
+}
+
+I64 HPET()
+{ //Get high precision event timer.
+  return *(dev.uncached_alias+HPET_MAIN_CNT)(I64 *);
+}
+
+I64 TimeCal()
+{
+  static I64 time_stamp_start=0,timer_start=0,HPET_start=0;
+  I64 i;
+  if (time_stamp_start) {
+    PUSHFD
+    CLI
+    if (HPET_start) {
+      cnts.time_stamp_freq=cnts.HPET_freq*(GetTSC-time_stamp_start);
+      i=HPET-HPET_start;
+    } else {
+      cnts.time_stamp_freq=SYS_TIMER_FREQ*(GetTSC-time_stamp_start);
+      i=SysTimerRead-timer_start;
+    }
+    if (!i)
+      AdamErr("Timer Cal Error");
+    else {
+      cnts.time_stamp_freq/=i;
+      cnts.time_stamp_kHz_freq=cnts.time_stamp_freq/1000;
+      cnts.time_stamp_calibrated=TRUE;
+    }
+    POPFD
+  }
+  PUSHFD
+  CLI
+  if (cnts.HPET_freq) {
+    timer_start=0;
+    HPET_start=HPET;
+  } else {
+    timer_start=SysTimerRead;
+    HPET_start=0;
+  }
+  time_stamp_start=GetTSC;
+  POPFD
+  return cnts.time_stamp_freq;
+}
+
+F64 tS()
+{//Time since boot in seconds as a float.
+  if (cnts.HPET_freq)
+    return ToF64(HPET-cnts.HPET_initial)/cnts.HPET_freq;
+  else
+    return SysTimerRead/ToF64(SYS_TIMER_FREQ);
+}
+
+Bool Blink(F64 Hz=2.5)
+{//Return TRUE, then FALSE, then TRUE at given frequency.
+  if (!Hz) return 0;
+  return ToI64(cnts.jiffies*2*Hz/JIFFY_FREQ)&1;
+}
+
+U0 Busy(I64 uS)
+{//Loosely timed.
+  I64 i;
+  if (cnts.HPET_freq) {
+    i=HPET+cnts.HPET_freq*uS/1000000;
+    while (HPET<i);
+  } else
+    for (i=0;i<uS;i++)
+      PortNop;
+}
+
+U0 SleepUntil(I64 wake_jiffy)
+{//Not for power-saving.  It is to make a program pause without hogging the CPU.
+  Bool old_idle=LBts(&Fs->task_flags,TASKf_IDLE);
+  Fs->wake_jiffy=wake_jiffy;
+  Yield;
+  LBEqu(&Fs->task_flags,TASKf_IDLE,old_idle);
+}
+
+U0 Sleep(I64 mS)
+{//Not for power-saving.  It is to make a program pause without hogging the CPU.
+  if (!mS)
+    Yield;
+  else
+    SleepUntil(cnts.jiffies+mS*JIFFY_FREQ/1000);
+}
+
+F64 Ona2Freq(I8 ona)
+{//Ona to freq. Ona=60 is 440.0Hz.
+  if (!ona)
+    return 0;
+  else
+    return 440.0/32*2.0`(ona/12.0);
+}
+
+I8 Freq2Ona(F64 freq)
+{//Freq to Ona. 440.0Hz is Ona=60.
+  if (freq>0)
+    return ClampI64(12*Log2(32.0/440.0*freq),1,I8_MAX);
+  else
+    return 0;
+}
+
+U0 Snd(I8 ona=0)
+{//Play ona, a piano key num. 0 means rest.
+  I64 period;
+  CSndData *d;
+  if (!Bt(&sys_semas[SEMA_MUTE],0) &&
+        !LBts(&sys_semas[SEMA_SND],0)) { //Mutex. Just throw-out if in use
+    if (!ona) {
+      scrncast.ona=ona;
+      OutU8(0x61,InU8(0x61)&~3);
+    } else if (ona!=scrncast.ona) {
+      scrncast.ona=ona;
+      period=ClampI64(SYS_TIMER_FREQ/Ona2Freq(ona),1,U16_MAX);
+      OutU8(0x43,0xB6);
+      OutU8(0x42,period);
+      OutU8(0x42,period.u8[1]);
+      OutU8(0x61,3|InU8(0x61));
+    }
+    if (!IsDbgMode && scrncast.record) {
+      d=ACAlloc(sizeof(CSndData));
+      d->ona=ona;
+      d->tS=tS;
+      QueIns(d,scrncast.snd_head.last);
+    }
+    LBtr(&sys_semas[SEMA_SND],0);
+  }
+}
+
+Bool ScrnCast(Bool val=ON,Bool just_audio=FALSE,U8 *print_fmt="B:/Tmp/%X.GR")
+{//WinMgr saves GR files to a dir.
+  Bool old_val;
+  scrncast.just_audio=just_audio;
+  if (val) {
+    if (!(old_val=LBtr(&scrncast.record,0))) {
+      Free(scrncast.print_fmt);
+      scrncast.print_fmt=AStrNew(print_fmt);
+      scrncast.t0_now=Now;
+      scrncast.snd_head.tS=scrncast.t0_tS=tS;
+      scrncast.snd_head.ona=scrncast.ona;
+      LBts(&scrncast.record,0);
+    }
+  } else
+    old_val=LBtr(&scrncast.record,0);
+  Snd;
+  return old_val;
+}
+
+U0 SndRst()
+{//Fix stuck sound.
+  if (Bt(&sys_semas[SEMA_SND],0)) {
+    Sleep(1);
+    if (Bt(&sys_semas[SEMA_SND],0)) {
+      Sleep(1);
+      LBtr(&sys_semas[SEMA_SND],0);
+    }
+  }
+  Snd;
+}
+
+U0 Beep(I8 ona=62,Bool busy=FALSE)
+{//Make beep at given ona freq.
+  Snd(ona);
+  if (busy)
+    Busy(500000);
+  else
+    Sleep(500);
+  Snd;
+  if (busy)
+    Busy(200000);
+  else
+    Sleep(200);
+}
+
+Bool Mute(Bool val)
+{//Turn-off sound.
+  Bool res;
+  if (val) {
+    PUSHFD
+    CLI
+    Snd;
+    res=LBts(&sys_semas[SEMA_MUTE],0);
+    POPFD
+  } else
+    res=LBtr(&sys_semas[SEMA_MUTE],0);
+  return res;
+}
+
+Bool IsMute()
+{//Return is-mute flag.
+  return Bt(&sys_semas[SEMA_MUTE],0);
+}
+
+Bool Silent(Bool val=ON)
+{//Turn-off StdOut console text. (Not sound.)
+  return LBEqu(&Fs->display_flags,DISPLAYf_SILENT,val);
+}
+
+Bool IsSilent()
+{//Return StdOut turned-off?
+  return Bt(&Fs->display_flags,DISPLAYf_SILENT);
+}
+
+Bool SysDbg(Bool val)
+{//Set SysDbg bit you can use while debugging.
+  return LBEqu(&sys_semas[SEMA_DEBUG],0,val);
+}
+
+Bool IsSysDbg()
+{//Return SysDbg bit.
+  return Bt(&sys_semas[SEMA_DEBUG],0);
+}
+
+Bool Raw(Bool val)
+{//Set to direct scrn, BLACK & WHITE, non-windowed output mode.
+  if (!val)
+    VGAFlush;
+  return !LBEqu(&Fs->display_flags,DISPLAYf_NOT_RAW,!val);
+}
+
+Bool IsRaw()
+{//Are we in BLACK & WHITE raw scrn mode?
+  return !Bt(&Fs->display_flags,DISPLAYf_NOT_RAW);
+}
+
+Bool SingleUser(Bool val)
+{//Set single-user mode.
+  return LBEqu(&sys_semas[SEMA_SINGLE_USER],0,val);
+}
+
+Bool IsSingleUser()
+{//Return single-user mode.
+  return Bt(&sys_semas[SEMA_SINGLE_USER],0);
+}
+
+Bool DbgMode(Bool val)
+{//Set dbg-mode.
+  return LBEqu(&sys_semas[SEMA_DBG_MODE],0,val);
+}
+
+Bool IsDbgMode()
+{//Return dbg-mode.
+  return Bt(&sys_semas[SEMA_DBG_MODE],0);
+}
+
+U0 ProgressBarsRst(U8 *path=NULL)
+{//Reset all progress bars to zero.
+  CallExtStr("ProgressBarsRegTf",path);
+  MemSet(sys_progresses,0,sizeof(sys_progresses));
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KStart16.HC.HTML b/public/Wb/Home/Src/Kernel/KStart16.HC.HTML new file mode 100755 index 0000000..7ade1da --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KStart16.HC.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+asm {/* See ::/Doc/Boot.DD.
+TempleOS starts in real, calls some BIOS
+routines, switches to 32 bit, and 64 bit mode
+and continues in HolyC at KMain().
+
+The boot loader jumps here in real-mode (16-bit).
+It actually jumps to the CBinFile header which is
+placed just before this by the compiler.
+The header begins with a short jmp to
+the start of this file's code which begins
+with the following small jump past some data.
+
+This file is first in the Kernel image
+because it is #included first.  Kernel.PRJ
+*/
+USE16
+SYS_KERNEL:: //This must match CKernel.
+        JMP     I16 CORE0_16BIT_INIT
+
+//************************************
+//  ASM Global vars required for 16-bit start-up
+        ALIGN   4,OC_NOP
+SYS_BOOT_SRC::                  DU32    BOOT_SRC_NULL;
+SYS_BOOT_BLK::                  DU32    0;
+SYS_BOOT_PATCH_TABLE_BASE::     DU32    0;
+SYS_RUN_LEVEL::                 DU32    0;
+#exe {StreamPrint("SYS_COMPILE_TIME:: DU64 0x%X;",Now);} //See BootDVDProbe
+#assert SYS_COMPILE_TIME+sizeof(CDate)+sizeof(CBinFile)<DVD_BLK_SIZE
+
+MEM_BOOT_BASE::         DU32    0;      //Offset from start used by reboot
+MEM_E801::              DU16    0,0;
+MEM_E820::              DU8     MEM_E820_ENTRIES_NUM*sizeof(CMemE820) DUP (0);
+MEM_PHYSICAL_SPACE::    DU64    0;
+SYS_GDT_PTR::           DU16    sizeof(CGDT)-1;
+                        DU64    0;
+SYS_PCI_BUSES::         DU16    0;
+
+        ALIGN   16,OC_NOP
+SYS_GDT:: //See CGDT
+GDT_NULL:       DU64    0,0;
+GDT_BOOT_DS:    DU64    0x00CF92000000FFFF,0; //Gets patched.
+GDT_BOOT_CS:    DU64    0x00CF9A000000FFFF,0; //Gets patched.
+GDT_CS32:       DU64    0x00CF9A000000FFFF,0;
+GDT_CS64:       DU64    0x00209A0000000000,0; //The Charter says just ring0.
+GDT_CS64_RING3: DU64    0x0020FA0000000000,0; //Ring3, so you can play with.
+GDT_DS:         DU64    0x00CF92000000FFFF,0;
+GDT_DS_RING3:   DU64    0x00CFF2000000FFFF,0;
+GDT_TR:         DU8     MP_PROCESSORS_NUM*16 DUP(0);
+GDT_TR_RING3:   DU8     MP_PROCESSORS_NUM*16 DUP(0);
+#assert $-SYS_GDT==sizeof(CGDT)
+
+#assert $-SYS_KERNEL==sizeof(CKernel)-sizeof(CBinFile)
+
+//************************************
+CORE0_16BIT_INIT::
+//EAX is SYS_BOOT_SRC. (Val passed from boot blk, BootHD, BootDVD, & BootRAM.)
+        MOV     ECX,EAX
+        MOV     AX,(BOOT_RAM_LIMIT-BOOT_STK_SIZE)/16
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE
+        PUSH    ECX     //Will be SYS_BOOT_SRC. See BootHD, BootDVD & BootRAM.
+        PUSH    EBX
+
+        CALL    U16 GET_RIP
+GET_RIP:        POP     BX
+        SUB     BX,GET_RIP
+        SHR     BX,4
+        MOV     AX,CS
+        ADD     AX,BX
+        PUSH    AX
+        PUSH    U16 @@05
+        RETF
+
+@@05:   STI
+        MOV     AX,CS
+        MOV     DS,AX
+
+        MOV     U32 [SYS_RUN_LEVEL],RLF_16BIT
+
+        MOV     AX,0x4F02
+        MOV     BX,0x12         //640x480 16 color
+#exe {
+  if (!kernel_cfg->opts[CFG_TEXT_MODE])
+    StreamPrint("INT 0x10");    //Enable VGA
+};
+        CMP     AX,0x004F
+        JNE     @@10            //Jmp if fail
+        BTS     U32 [SYS_RUN_LEVEL],RLf_VGA
+@@10:
+
+//Get mem maps.
+        MOV     AX,0xE801
+        INT     0x15
+        MOV     U16 [MEM_E801],CX
+        MOV     U16 [MEM_E801+2],DX
+
+        MOV     CX,MEM_E820_ENTRIES_NUM-1 //Leave one to terminate
+        XOR     EBX,EBX
+        MOV     AX,DS
+        MOV     ES,AX
+        MOV     DI,MEM_E820
+@@15:   PUSH    CX
+        MOV     EAX,0xE820
+        MOV     ECX,sizeof(CMemE820)
+        MOV     EDX,'PAMS'
+        INT     0x15
+        JC      @@20
+        CMP     EAX,'PAMS'
+        JNE     @@20
+        TEST    EBX,EBX
+        JZ      @@20
+        ADD     DI,sizeof(CMemE820)
+        POP     CX
+        LOOP    @@15
+        SUB     SP,2
+@@20:   ADD     SP,2
+
+//Find how much space to map, start with E801 limit.
+        XOR     EAX,EAX
+        MOV     AX,[MEM_E801+2]
+        SHL     EAX,16
+        ADD     EAX,SYS_16MEG_AREA_LIMIT
+        XOR     EDX,EDX
+
+//Find max of E820 to set mapped space.
+        MOV     SI,MEM_E820
+@@25:   MOV     CL,CMemE820.type[SI]
+        TEST    CL,CL
+        JZ      @@35
+        MOV     EBX,CMemE820.base[SI]
+        MOV     ECX,CMemE820.base+4[SI]
+        ADD     EBX,CMemE820.len[SI]
+        ADC     ECX,CMemE820.len+4[SI]
+        SUB     EBX,EAX
+        SBB     ECX,EDX
+        JC      @@30
+        MOV     EAX,CMemE820.base[SI]
+        MOV     EDX,CMemE820.base+4[SI]
+        ADD     EAX,CMemE820.len[SI]
+        ADC     EDX,CMemE820.len+4[SI]
+@@30:   ADD     SI,sizeof(CMemE820)
+        JMP     @@25
+
+@@35:   MOV     [MEM_PHYSICAL_SPACE],EAX
+        MOV     [MEM_PHYSICAL_SPACE+4],EDX
+        
+//Get PCI Bus Info
+        MOV     U16 [SYS_PCI_BUSES],256
+        XOR     DX,DX
+        MOV     AX,0xB101
+        INT     0x1A
+        CMP     DX,'PC'
+        JNE     @@40
+        MOV     CH,0
+        INC     CX
+        MOV     U16 [SYS_PCI_BUSES],CX
+@@40:
+        CLI
+//Enable A20
+        IN      AL,0x92
+        OR      AL,2
+        OUT     0x92,AL
+
+        POP     U32 [SYS_BOOT_BLK]
+        POP     U32 [SYS_BOOT_SRC]      //See BootHD, BootDVD, & BootRAM.
+
+        CLD
+        XOR     EAX,EAX
+        MOV     AX,CS
+        MOV     DS,AX
+        MOV     ES,AX
+        SHL     EAX,4
+
+        MOV     U32 [MEM_BOOT_BASE],EAX
+
+        MOV     DX,CS
+        SUB     DX,sizeof(CBinFile)/16
+#assert !(sizeof(CBinFile)&15)
+        MOV     GS,DX
+
+        MOV     EDX,EAX
+        ADD     EDX,U32 GS:[CBinFile.patch_table_offset]
+        SUB     EDX,sizeof(CBinFile)
+        MOV     U32 [SYS_BOOT_PATCH_TABLE_BASE],EDX
+
+        ADD     U32 [GDT_BOOT_DS+2],EAX
+        ADD     U32 [GDT_BOOT_CS+2],EAX
+        ADD     EAX,I32 SYS_GDT
+        MOV     U32 [SYS_GDT_PTR+CSysLimitBase.base],EAX
+        LGDT    U32 [SYS_GDT_PTR]
+
+        MOV     EAX,SYS_START_CR0
+        MOV_CR0_EAX
+
+/* The assembler doesn't support far jumps so
+we hand code it.  16-bit code is not important
+enough to fully implement in the assembler.
+
+To complete the switch to 32-bit mode, we have to load
+the code segment with a far jump.
+*/
+        DU8     0x66,0xEA; //JMP CGDT.boot_cs:CORE0_32BIT_INIT
+        DU32    CORE0_32BIT_INIT;
+        DU16    CGDT.boot_cs;
+#assert $+16<=0xFFFF
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KStart32.HC.HTML b/public/Wb/Home/Src/Kernel/KStart32.HC.HTML new file mode 100755 index 0000000..8eef388 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KStart32.HC.HTML @@ -0,0 +1,148 @@ + + + + + + + + + + + +
+asm {
+USE32
+//************************************
+//  ASM Global vars not required for 16-bit start-up
+        ALIGN   8,OC_NOP
+MEM_HEAP_BASE::         DU64    0;
+MEM_HEAP_LIMIT::        DU64    0;
+MEM_PAGE_SIZE::         DU64    0;
+MEM_MAPPED_SPACE::      DU64    0;
+MEM_2MEG_NUM::          DU64    0;
+MEM_1GIG_NUM::          DU64    0;
+MEM_512GIG_NUM::        DU64    0;
+MEM_PML2::              DU64    0;
+MEM_PML3::              DU64    0;
+MEM_PML4::              DU64    0;
+
+#exe {
+  StreamPrint(
+"SYS_MEM_INIT_FLAG::    DU8     %d;"
+"SYS_MEM_INIT_VAL::     DU8     %d;"
+"SYS_HEAP_INIT_FLAG::   DU8     %d;"
+"SYS_HEAP_INIT_VAL::    DU8     %d;"
+"SYS_VAR_INIT_FLAG::    DU8     %d;"
+"SYS_VAR_INIT_VAL::     DU8     %d;"
+"SYS_STAFF_MODE_FLAG::  DU8     %d;",
+kernel_cfg->opts[CFG_MEM_INIT], kernel_cfg->mem_init_val,
+kernel_cfg->opts[CFG_HEAP_INIT],kernel_cfg->heap_init_val,
+kernel_cfg->opts[CFG_VAR_INIT], kernel_cfg->var_init_val,
+kernel_cfg->opts[CFG_STAFF_MODE]);
+};
+SYS_HEAP_DBG_FLAG::     DU8     _CFG_HEAP_DBG;
+
+        ALIGN   8,0
+SYS_CTRL_ALT_FLAGS::    DU64    0;
+SYS_EXTERN_TABLE::      DU64    0;
+
+SYS_CODE_BP::           DU64    0;
+SYS_DATA_BP::           DU64    0;
+
+SYS_PROGRESSES::
+SYS_PROGRESS1::         DU64    0;
+SYS_PROGRESS1_MAX::     DU64    0;
+SYS_PROGRESS1_T0::      DU64    0;
+SYS_PROGRESS1_TF::      DU64    0;
+SYS_PROGRESS1_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+SYS_PROGRESS2::         DU64    0;
+SYS_PROGRESS2_MAX::     DU64    0;
+SYS_PROGRESS2_T0::      DU64    0;
+SYS_PROGRESS2_TF::      DU64    0;
+SYS_PROGRESS2_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+SYS_PROGRESS3::         DU64    0;
+SYS_PROGRESS3_MAX::     DU64    0;
+SYS_PROGRESS3_T0::      DU64    0;
+SYS_PROGRESS3_TF::      DU64    0;
+SYS_PROGRESS3_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+SYS_PROGRESS4::         DU64    0;
+SYS_PROGRESS4_MAX::     DU64    0;
+SYS_PROGRESS4_T0::      DU64    0;
+SYS_PROGRESS4_TF::      DU64    0;
+SYS_PROGRESS4_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+#assert $-SYS_PROGRESSES==sizeof(CProgress)*4
+
+SYS_FOCUS_TASK::        DU64    0;
+SYS_CPU_STRUCTS::       DU64    0;
+SYS_MP_CNT::            DU64    1;
+SYS_MP_CNT_INITIAL::    DU64    1;
+SYS_MP_CNT_LOCK::       DU64    1;
+
+        ALIGN   DFT_CACHE_LINE_WIDTH,OC_NOP
+SYS_CACHE_LINE_WIDTH::  DU64    DFT_CACHE_LINE_WIDTH;
+        DU8     DFT_CACHE_LINE_WIDTH-sizeof(CBinFile)-8 DUP(0);
+SYS_SEMAS::             DU8     SEMA_SEMAS_NUM*DFT_CACHE_LINE_WIDTH DUP(0);
+//************************************
+        ALIGN   16,OC_NOP
+CORE0_32BIT_INIT:: //Entry point for BootRAM.
+        PUSH    U32 RFLAGG_START
+        POPFD
+        MOV     EAX,SYS_START_CR0
+        MOV_CR0_EAX
+
+        MOV     AX,CGDT.boot_ds //LOAD DS SELECTOR
+        MOV     DS,AX
+        BTS     U32 [SYS_RUN_LEVEL],RLf_32BIT
+        MOV     ESI,U32 [SYS_BOOT_PATCH_TABLE_BASE]
+        MOV     EDI,U32 [MEM_BOOT_BASE]
+
+        MOV     AX,CGDT.ds
+        MOV     DS,AX
+        MOV     ES,AX
+        MOV     FS,AX
+        MOV     GS,AX
+        MOV     SS,AX
+        MOV     ESP,BOOT_RAM_LIMIT //Tmp Stk
+
+//Patch abs addresses
+        MOV     ECX,U32 CPatchTableAbsAddr.abs_addres_cnt[ESI]
+        LEA     ESI,U32 CPatchTableAbsAddr.abs_addres[ESI]
+@@05:   LODSD
+        ADD     EAX,EDI
+        ADD     U32 [EAX],EDI
+        LOOP    @@05
+
+        DU8     0xEA; //JMP CGDT.cs32:@@10
+        DU32    @@10;
+        DU16    CGDT.cs32;
+
+@@10:   BTS     U32 [SYS_RUN_LEVEL],RLf_PATCHED
+
+        CALL    SYS_FIND_PCIBIOS_SERVICE_DIR
+        CALL    SYS_FIND_PCI_SERVICES
+        CALL    SYS_INIT_PAGE_TABLES
+        CALL    SYS_INIT_16MEG_SYS_CODE_BP
+        PUSH    U32 0   //Return from next call will be 64-bit
+        CALL    SYS_ENTER_LONG_MODE
+
+        //We fall-thou to KStart64, next.
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KStart64.HC.HTML b/public/Wb/Home/Src/Kernel/KStart64.HC.HTML new file mode 100755 index 0000000..831d2a2 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KStart64.HC.HTML @@ -0,0 +1,131 @@ + + + + + + + + + + + +
+asm {
+USE64
+        BTS     U32 [SYS_RUN_LEVEL],RLf_64BIT
+
+        FNINIT
+        MOV     RAX,SYS_FIXED_AREA+CSysFixedArea.init_fpu_mmx
+        FXSAVE  U64 [RAX]
+
+//Init CPU0 Struct
+        PUSH    SYS_FIXED_AREA+CSysFixedArea.adam
+        PUSH    SYS_FIXED_AREA+CSysFixedArea.boot_cpu
+        PUSH    0
+        CALL    &CPUStructInit
+        CALL    SET_GS_BASE
+
+//Init Adam HeapCtrl
+        MOV     EDI,U32 SYS_FIXED_AREA+CSysFixedArea.adam_hc
+        MOV     EAX,U32 SYS_FIXED_AREA+CSysFixedArea.sys_code_bp
+        MOV     U64 CHeapCtrl.bp[RDI],RAX
+        MOV     U32 CHeapCtrl.hc_signature[RDI],HEAP_CTRL_SIGNATURE_VAL
+        
+        LEA     RAX,U64 CHeapCtrl.next_um-CMemUsed.next[RDI]
+        MOV     U64 CHeapCtrl.next_um[RDI],RAX
+        MOV     U64 CHeapCtrl.last_um[RDI],RAX
+
+        MOV     EAX,U32 SYS_FIXED_AREA+CSysFixedArea.adam
+        MOV     U64 CHeapCtrl.mem_task[RDI],RAX
+        MOV     U64 CTask.code_heap[RAX],RDI
+        MOV     U64 CTask.data_heap[RAX],RDI
+        MOV     U32 CTask.task_signature[RAX],TASK_SIGNATURE_VAL
+        
+        BTS     U32 [SYS_RUN_LEVEL],RLf_16MEG_ADAM_HEAP_CTRL
+
+        PUSH    MEM_ADAM_STK
+        PUSH    U32 SYS_FIXED_AREA+CSysFixedArea.adam
+        CALL    &TaskInit
+        CALL    SET_FS_BASE
+        MOV     RSP,U64 CTask.rsp[RAX]
+
+        JMP     I32 &KMain
+
+//************************************
+USE32
+SYS_ENTER_LONG_MODE:: //Switch to long 64-bit mode
+        MOV_EAX_CR4
+        OR      EAX,0xB0
+        MOV_CR4_EAX
+
+        MOV     EAX,[MEM_PML4]
+        MOV_CR3_EAX
+
+        MOV     ECX,IA32_EFER
+        XOR     EDX,EDX
+        MOV     EAX,IA32F_LME
+        WRMSR
+
+        MOV_EAX_CR0
+        BTS     EAX,31  //Enable paging (required for 64-bit mode)
+        MOV_CR0_EAX
+
+        DU8     0xEA;      //JMP CGDT.cs64:@@05
+        DU32    @@05;
+        DU16    CGDT.cs64;
+USE64
+@@05:   MOV     AX,CGDT.ds
+        MOV     DS,AX
+        MOV     ES,AX
+        MOV     SS,AX
+        MOV     FS,AX
+        MOV     GS,AX
+        RET
+
+//************************************
+SYS_RAM_REBOOT:: //This gets copied high.  SYS_RAM_REBOOT
+        PUSH    U32 CGDT.ds             //stk seg
+        PUSH    U32 BOOT_RAM_LIMIT      //stk
+        PUSH    U32 0                   //flags
+        PUSH    U32 CGDT.cs32
+        LEA     RAX,[@@10]
+        PUSH    RAX
+        IRET
+USE32
+@@10:   WBINVD
+
+//Disable paging
+        MOV_EAX_CR0
+        BTR     EAX,31
+        MOV_CR0_EAX
+
+        MOV     ECX,IA32_EFER
+        XOR     EDX,EDX
+        XOR     EAX,EAX
+        WRMSR
+
+        MOV     EBX,BOOT_SRC_RAM
+        MOV     EAX,I32 CORE0_32BIT_INIT
+        JMP     EAX
+SYS_RAM_REBOOT_END::
+USE64
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KTask.HC.HTML b/public/Wb/Home/Src/Kernel/KTask.HC.HTML new file mode 100755 index 0000000..a70b231 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KTask.HC.HTML @@ -0,0 +1,576 @@ + + + + + + + + + + + +
+U0 Exit()
+{//Terminate own task.
+  if (Fs==sys_focus_task && IsDbgMode) {
+    LBts(&Fs->task_flags,TASKf_KILL_AFTER_DBG);
+    G;
+  } else {
+    if (sys_staff_mode_flag)
+      AdamLog("%p:%p:%p:%p:%p:%p\n",Caller(0),Caller(1),Caller(2),Caller(3),
+            Caller(4),Caller(5),Caller(6),Caller(7));
+    if (!Gs->num && !IsDbgMode)
+      SingleUser(OFF);
+    Fs->rflags=GetRFlags;
+    Fs->rsp=GetRSP;
+    Fs->rbp=GetRBP;
+    Fs->rip=$;
+    CLI
+    LBts(&Fs->task_flags,TASKf_KILL_TASK);
+    TaskEndNow;
+  }
+}
+
+Bool TaskValidate(CTask *task)
+{//return TRUE if task looks valid.
+  if (!(0<task<=I32_MAX) || task->addr!=task ||
+        task->task_signature!=TASK_SIGNATURE_VAL)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+I64 BirthWait(CTask **_task,I64 task_num=-1)
+{//Wait for task valid and not task_num.
+  while (!TaskValidate(*_task)||(*_task)->task_num==task_num)
+    Yield;
+  return (*_task)->task_num;
+}
+
+U0 DeathWait(CTask **_task,Bool send_exit=FALSE)
+{//Wait for task death.
+  if (send_exit && TaskValidate(*_task)) {
+    TaskWait(*_task,TRUE);
+    XTalk(*_task,"Exit;\n");
+  }
+  while (TaskValidate(*_task))
+    Yield;
+}
+
+Bool Kill(CTask *task,Bool wait=TRUE,Bool just_break=FALSE)
+{//Terminate other task.
+  I64 i;
+  if (TaskValidate(task)) {
+    if (just_break) {
+      if (task!=Fs)
+        Break;
+      else {//TODO wait
+        sys_focus_task=task;
+        LBts(sys_ctrl_alt_flags,CTRL_ALT_C);
+        return TRUE;
+      }
+    } else {
+      if (task!=sys_winmgr_task) {
+        for (i=0;i<mp_cnt;i++)
+          if (task==cpu_structs[i].seth_task)
+            return FALSE;
+        LBts(&task->task_flags,TASKf_KILL_TASK);
+        if (wait) {
+          do Yield;
+          while (TaskValidate(task) && Bt(&task->task_flags,TASKf_KILL_TASK));
+        }
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+Bool Suspend(CTask *task=NULL,Bool state=TRUE)
+{//Tell scheduler to skip task.
+  Bool res;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (TaskValidate(task))
+    res=LBEqu(&task->task_flags,TASKf_SUSPENDED,state);
+  else
+    res=FALSE;
+  POPFD
+  return res;
+}
+
+Bool IsSuspended(CTask *task=NULL)
+{//You might use this in a DrawIt() or Animatetask().
+  if (!task) task=Fs;
+  if (TaskValidate(task))
+    return Bt(&task->task_flags,TASKf_SUSPENDED);
+  else
+    return FALSE;
+}
+
+CTaskStk *TaskStkNew(I64 stk_size,CTask *task)
+{
+  CTaskStk *tmps=MAlloc(stk_size+offset(CTaskStk.stk_base),task);
+  tmps->next_stk=NULL;
+  tmps->stk_ptr=NULL;
+  tmps->stk_size=MSize(tmps)-offset(CTaskStk.stk_base);
+  return tmps;
+}
+
+#exe {Option(OPTf_NO_REG_VAR,ON);};
+argpop I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size,
+                        /*argpop*/I64 (*fp_addr)(...),...)
+{//Grow stk in call with any fixed num of args.
+//See ::/Demo/StkGrow.HC.
+  CTaskStk *tmps,*tmps2,**_stk;
+  I64 res,*rsp,*rsp2,*old_stk;
+
+  if (UnusedStk>=stk_size_threshold) {
+
+    asm {
+      LEAVE
+      POP       RAX     //return addr
+      ADD       RSP,16  //pop threshold,stk_size
+      POP       RBX     // *f
+      ADD       RSP,8   //pop ARGC
+      PUSH      RAX
+      JMP       RBX     //CALL fp_addr()
+    };
+
+  } else {
+
+    tmps2=TaskStkNew(stk_size,Fs);
+    tmps2->next_stk=tmps=Fs->stk;
+    rsp2=(&tmps2->stk_base)(U8 *)+tmps2->stk_size;
+    old_stk=rsp=&argv[argc];
+    while (argc-->0)
+      *--rsp2=*--rsp;
+    _stk=&Fs->stk;
+    tmps->stk_ptr=rsp=GetRSP;
+    asm {
+      IMPORT    _FREE;  //We are in a function, not at glbl scope.
+//The compiler treats these in isolation.
+
+      PUSHFD
+      POP       RDX     //flags
+      CLI
+      MOV       RBX,U64 &tmps2[RBP]
+      MOV       RAX,&_stk[RBP]
+      MOV       U64 [RAX],RBX   //Fs->stk=tmps2
+      MOV       RSP,U64 &rsp2[RBP]
+      PUSH      RDX
+      POPFD
+
+      CALL      U64 &fp_addr[RBP]
+      MOV       U64 &res[RBP],RAX
+
+      PUSHFD
+      POP       RDX     //flags
+      CLI
+      MOV       RBX,U64 &tmps[RBP]
+      MOV       RAX,&_stk[RBP]
+      MOV       U64 [RAX],RBX   //Fs->stk=tmps
+      MOV       RSP,U64 &rsp[RBP]
+      PUSH      RDX
+      POPFD
+
+      PUSH      U64 &tmps2[RBP]
+      CALL      _FREE
+
+      MOV       RDX,U64 &old_stk[RBP]
+      MOV       RBX,U64 8[RBP]
+      MOV       RAX,U64 &res[RBP]
+      MOV       RBP,U64 [RBP]
+      MOV       RSP,RDX
+      JMP       RBX     //return
+    };
+  }
+  return 0; //dummy to get rid of warning
+}
+;
+#exe {Option(OPTf_NO_REG_VAR,OFF);};
+
+I64 TaskInit(CTask *task,I64 stk_size)
+{//Returns Fs of task
+  CTaskStk *tmps;
+
+  QueInit(&task->code_heap->next_mem_blk);
+  task->code_heap->last_mergable=NULL;
+  if (task->code_heap!=task->data_heap) {
+    QueInit(&task->data_heap->next_mem_blk);
+    task->data_heap->last_mergable=NULL;
+  }
+
+  task->addr=task->next_task=task->last_task=
+        task->next_input_filter_task=task->last_input_filter_task=
+        task;
+
+  task->task_num=sys_num_spawned_tasks++;
+
+  task->rflags=RFLAGG_NORMAL;
+  task->win_inhibit=WIG_TASK_DFT;
+
+  task->next_child_task=task->last_child_task=
+        (&task->next_child_task)(U8 *)-offset(CTask.next_sibling_task);
+
+  JobCtrlInit(&task->srv_ctrl);
+  QueInit(&task->next_cc);
+  QueInit(&task->next_except);
+  QueInit(&task->next_ctrl);
+  QueInit(&task->next_ode);
+
+  task->fpu_mmx=MAllocAligned(sizeof(CFPU),0x10,task);
+  MemCpy(task->fpu_mmx,
+        SYS_FIXED_AREA+offset(CSysFixedArea.init_fpu_mmx),sizeof(CFPU));
+
+  task->hash_table=HashTableNew(TASK_HASH_TABLE_SIZE,task);
+
+  if (!stk_size)
+    stk_size=MEM_DFT_STK;
+  task->stk=tmps=TaskStkNew(stk_size,task);
+  task->rsp=(&tmps->stk_base)(U8 *)+tmps->stk_size;
+
+  task->text_attr       =WHITE<<4+BLUE;
+  task->border_src      =BDS_CONST;
+  task->border_attr     =DrvTextAttrGet(':');
+  task->title_src       =TTS_CONST;
+  task->win_left        =1;
+  task->win_right       =text.cols-2;
+  task->win_top         =13;
+  task->win_bottom      =text.rows-2;
+
+  if (blkdev.home_dir) {//Beware Adam TaskInit. I guess ok until DskChg().
+    task->cur_dv=blkdev.let_to_drv[*blkdev.home_dir-'A'];
+    task->cur_dir=StrNew(blkdev.home_dir+2,task);
+  } else
+    task->cur_dir=StrNew("/Home",task);
+
+  Seed(,task);
+
+  return task;
+}
+
+CTask *Spawn(U0 (*fp_start_addr)(U8 *data),U8 *data=NULL,U8 *task_name=NULL,
+        I64 target_cpu=-1,      //-1 for current CPU. See multi-core.
+        CTask *parent=NULL,     //NULL means adam
+        I64 stk_size=0,         //0=default
+        I64 flags=1<<JOBf_ADD_TO_QUE)
+{//Create task on core running at address.
+//Alloc CTask structure from code heap so addr will be short.
+  //Could be alloced off of data heap.
+  CTask *task;
+  if (target_cpu>=0)
+    return SpawnQue(fp_start_addr,data,task_name,target_cpu,
+          parent,stk_size,flags);
+  task=CAlloc(sizeof(CTask),adam_task->code_heap);
+  task->task_signature=TASK_SIGNATURE_VAL;
+  if (!task_name) task_name="Unnamed Task";
+  if (!parent) parent=Gs->seth_task;
+  task->parent_task=parent;
+  task->gs=parent->gs;
+  if (sys_code_bp)
+    task->code_heap=HeapCtrlInit(,task,sys_code_bp);
+  if (sys_data_bp)
+    task->data_heap=HeapCtrlInit(,task,sys_data_bp);
+  else
+    task->data_heap=task->code_heap;
+  TaskInit(task,stk_size);
+  task->rip=fp_start_addr;
+  task->rsp(U8 *)-=8;
+  *task->rsp=data;
+  task->rsp(U8 *)-=8;
+  *task->rsp=&Exit;
+  task->hash_table->next=parent->hash_table;
+  MemCpy(task->task_name,task_name,TASK_NAME_LEN);
+  StrCpy(task->task_title,task->task_name);
+  task->title_src=TTS_TASK_NAME;
+  PUSHFD
+  CLI
+  if (Bt(&flags,JOBf_ADD_TO_QUE)) {
+    TaskQueInsChild(task);
+    TaskQueIns(task);
+  }
+  POPFD
+  return task;
+}
+
+U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE)
+{//Those things calculated from other variables.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+    PAUSE
+  WinDerivedValsUpdate(task);
+  if (fp_update_ctrls)
+    (*fp_update_ctrls)(task);
+  if (update_z_buf && Bt(&task->display_flags,DISPLAYf_SHOW))
+    LBts(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);
+  LBtr(&task->task_flags,TASKf_TASK_LOCK);
+  POPFD
+}
+
+I64 ExeCmdLine(CCmpCtrl *cc)
+{//Terminal JIT-compile-and-execute loop for CCmpCtrl.
+  I64 res=0,type,old_title_src=Fs->title_src;
+  U8 *ptr,*ptr2,*ptr3,*machine_code,*old_task_title=StrNew(Fs->task_title);
+  F64 t0;
+  CDocEntry *doc_e;
+  CDoc *doc;
+  if (Fs->title_src!=TTS_LOCKED_CONST)
+    Fs->title_src=TTS_CUR_LEX;
+  while (cc->token &&
+        (cc->token!='}' || !(cc->flags & CCF_EXE_BLK)) ) {
+    if (Fs->title_src==TTS_CUR_LEX) {
+      ptr2=&Fs->task_title;
+      ptr3=ptr2+STR_LEN-1;
+      if (cc->lex_include_stk->flags & LFSF_DOC) {
+        doc_e=cc->lex_include_stk->cur_entry;
+        doc=cc->lex_include_stk->doc;
+        while (doc_e!=doc && ptr2<ptr3) {
+          switch (doc_e->type_u8) {
+            case DOCT_TEXT:
+              ptr=doc_e->tag;
+              while (*ptr && ptr2<ptr3)
+                *ptr2++=*ptr++;
+              break;
+            case DOCT_TAB:
+            case DOCT_NEW_LINE:
+              *ptr2++='.';
+              break;
+          }
+          doc_e=doc_e->next;
+        }
+        if (ptr2<ptr3) *ptr2=0;
+      } else
+        if ((ptr=cc->lex_include_stk->line_start) && *ptr)
+          MemCpy(ptr2,ptr,STR_LEN-1);
+    }
+    cc->flags&=~CCF_HAS_MISC_DATA;
+    machine_code=LexStmt2Bin(cc,&type);
+    if (machine_code!=INVALID_PTR) {
+      if (!(cc->flags&CCF_JUST_LOAD)) {
+        t0=tS;
+        res=Call(machine_code);
+        Fs->answer=res;
+        Fs->answer_type=type;
+        Fs->answer_time=tS-t0;
+        Fs->new_answer=TRUE;
+        cc->pmt_line=0;
+      }
+      if (!(cc->flags&CCF_HAS_MISC_DATA))
+        Free(machine_code);
+    }
+  }
+  if (Fs->title_src!=TTS_LOCKED_CONST) {
+    Fs->title_src=old_title_src;
+    StrCpy(Fs->task_title,old_task_title);
+  }
+  Free(old_task_title);
+  if (cc->flags&CCF_JUST_LOAD) {
+    if (cc->error_cnt)
+      return FALSE;
+    else
+      return TRUE;
+  } else
+    return res;
+}
+
+U0 SrvTaskCont()
+{//Act as server task in a loop handling commands.
+  I64 old_flags=GetRFlags;
+  FlushMsgs;
+  while (TRUE) {
+    CLI
+    if (JobsHndlr(old_flags) && Fs->title_src==TTS_TASK_NAME)
+      MemCpy(Fs->task_title,Fs->task_name,TASK_NAME_LEN);
+    FlushMsgs;
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    LBts(&Fs->task_flags,TASKf_AWAITING_MSG);
+    Yield;
+    SetRFlags(old_flags);
+  }
+}
+
+U0 UserTaskCont()
+{//Terminal key-input-execute loop.
+  CCmpCtrl *cc;
+  CDoc *doc;
+  Bool cont=TRUE;
+  do {
+    cc=CmpCtrlNew(,CCF_CMD_LINE|CCF_PMT|CCF_QUESTION_HELP);
+    QueIns(cc,Fs->last_cc);
+    try {
+      Lex(cc);
+      ExeCmdLine(cc);
+      cont=Bt(&cc->flags,CCf_PMT);
+      QueRem(cc);
+      CmpCtrlDel(cc);
+    } catch {
+      if ((doc=Fs->put_doc) && doc->doc_signature==DOC_SIGNATURE_VAL)
+        DocUnlock(doc);
+      PutExcept;
+    }
+  } while (cont);
+}
+
+U0 SrvCmdLine(I64 dummy=0)
+{
+  no_warn dummy;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  CallExtStr("SrvStartUp");
+  SrvTaskCont;
+}
+
+U0 UserCmdLine(I64 dummy=0)
+{//A user task ends-up calling this.
+  no_warn dummy;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  CallExtStr("UserStartUp");
+  if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+    Dbg;
+  UserTaskCont;
+}
+
+CTask *User(U8 *fmt=NULL,...)
+{//Create user term task.
+  U8 *st;
+  CTask *task=Spawn(&UserCmdLine);
+  TaskWait(task);
+  if (fmt) {
+    st=StrPrintJoin(NULL,fmt,argc,argv);
+    XTalk(task,st);
+    Free(st);
+  }
+  return task;
+}
+
+U0 TaskDel(CTask *task)
+{//We delay freeing in case lingering ptr to reincarnated.
+  HeapCtrlDel(task->code_heap);
+  if (task->data_heap!=task->code_heap)
+    HeapCtrlDel(task->data_heap);
+  Free(task);
+}
+
+I64 TaskEnd()
+{//Called with irq's off.
+  CTask *task=Fs,*tmpt,*tmpt1;
+  if (task==sys_task_being_scrn_updated) {
+    LBts(&task->task_flags,TASKf_KILL_TASK);
+    return task->next_task;
+  }
+  if (task->task_end_cb) {
+    task->wake_jiffy=0;
+    LBtr(&task->task_flags,TASKf_KILL_TASK);
+    TaskRstAwaitingMsg(task);
+    Suspend(task,FALSE);
+    task->rip=task->task_end_cb;
+    task->task_end_cb=NULL;
+    return task;
+  }
+  if (task->parent_task && task->parent_task->popup_task==task) {
+    task->parent_task->popup_task=NULL;
+    Kill(task->parent_task,FALSE);
+    return task->parent_task;
+  }
+
+  DrvsRelease;
+  BlkDevsRelease;
+  tmpt1=(&task->next_child_task)(U8 *)-offset(CTask.next_sibling_task);
+  tmpt=tmpt1->next_sibling_task;
+  if (tmpt!=tmpt1) {
+    do {
+      LBts(&tmpt->task_flags,TASKf_KILL_TASK);
+      tmpt=tmpt->next_sibling_task;
+    } while (tmpt!=tmpt1);
+    return task->next_task;
+  }
+  if (LBtr(&task->display_flags,DISPLAYf_SHOW))
+    LBts(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);
+
+  while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+    PAUSE
+  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+
+  JobQueDel(&task->srv_ctrl.next_waiting);
+  JobQueDel(&task->srv_ctrl.next_done);
+
+  if (IsRaw)
+    VGAFlush;
+
+  if (sys_focus_task==task) {
+    if (!Gs->num)
+      SingleUser(OFF);
+    sys_focus_task=NULL;
+    if (fp_set_std_palette)
+      (*fp_set_std_palette)();
+  }
+
+  //QueRem
+  task->task_signature(I64)=0;
+
+  tmpt =task->next_input_filter_task;
+  tmpt1=task->last_input_filter_task;
+  tmpt1->next_input_filter_task=tmpt;
+  tmpt ->last_input_filter_task=tmpt1;
+
+  tmpt =task->next_sibling_task;
+  tmpt1=task->last_sibling_task;
+  tmpt1->next_sibling_task=tmpt;
+  tmpt ->last_sibling_task=tmpt1;
+
+  tmpt =task->next_task; //save to return
+  TaskQueRem(task);
+
+  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  LBtr(&task->task_flags,TASKf_TASK_LOCK);
+
+  task->wake_jiffy=cnts.jiffies+DYING_JIFFIES;
+  while (LBts(&Gs->cpu_flags,CPUf_DYING_TASK_QUE))
+    PAUSE
+  QueIns(task,Gs->last_dying);
+  LBtr(&Gs->cpu_flags,CPUf_DYING_TASK_QUE);
+
+  return tmpt;
+}
+
+U0 TaskKillDying()
+{//Delay freeing to prevent asking for trouble with quick reincarnations.
+//What if the user is doing this: DoTreeCheckers.
+  CTaskDying *task,*task1;
+  if (Gs->kill_jiffy<cnts.jiffies) {//Avoid doing as many lock operations.
+    while (LBts(&Gs->cpu_flags,CPUf_DYING_TASK_QUE))
+      PAUSE
+    task=Gs->next_dying;
+    while (task!=&Gs->next_dying && task->wake_jiffy<cnts.jiffies) {
+      task1=task->next;
+      QueRem(task);
+      TaskDel(task);
+      task=task1;
+    }
+    LBtr(&Gs->cpu_flags,CPUf_DYING_TASK_QUE);
+    Gs->kill_jiffy=cnts.jiffies+DYING_JIFFIES;
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KUtils.HC.HTML b/public/Wb/Home/Src/Kernel/KUtils.HC.HTML new file mode 100755 index 0000000..794ab7f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KUtils.HC.HTML @@ -0,0 +1,502 @@ + + + + + + + + + + + +
+asm {
+_MEMSET::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSB
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMSET_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSW
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMSET_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSD
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMSET_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSQ
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMCPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_MOVSB
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_MEMCMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        CLD
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        XOR     RAX,RAX
+        REPE_CMPSB
+        JZ      @@05
+        MOV     AL,1
+        JA      @@05
+        MOV     RAX,-1
+@@05:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_BEQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        XOR     RAX,RAX
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        TEST    RDX,RDX
+        JZ      @@5
+        BTS     U64 [RBX],RCX
+        JMP     @@10
+@@5:    BTR     U64 [RBX],RCX
+@@10:   ADC     AL,0
+        POP     RBP
+        RET1    24
+_LBEQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        XOR     RAX,RAX
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        TEST    RDX,RDX
+        JZ      @@5
+        LOCK
+        BTS     U64 [RBX],RCX
+        JMP     @@10
+@@5:    LOCK
+        BTR     U64 [RBX],RCX
+@@10:   ADC     AL,0
+        POP     RBP
+        RET1    24
+_CLAMP_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        CMP     RAX,RCX
+        CMOVL   RAX,RCX
+        CMP     RAX,RDX
+        CMOVG   RAX,RDX
+        POP     RBP
+        RET1    24
+_CLAMP_U64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        CMP     RAX,RCX
+        CMOVB   RAX,RCX
+        CMP     RAX,RDX
+        CMOVA   RAX,RDX
+        POP     RBP
+        RET1    24
+_CALL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        TEST    RAX,RAX
+        JZ      @@05
+        CALL    RAX
+@@05:   POP     RBP
+        RET1    8
+_BIT_FIELD_OR_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG2[RBP]
+        SHR     RBX,3
+        ADD     RBX,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        AND     CL,7
+        SHL     RAX,CL
+        OR      U64 [RBX],RAX
+        POP     RBP
+        RET1    24
+_BIT_FIELD_EXT_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG2[RBP]
+        MOV     RCX,RBX
+        SHR     RBX,3
+        ADD     RBX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 [RBX]
+        AND     CL,7
+        SHR     RDX,CL
+        MOV     RCX,U64 SF_ARG3[RBP]
+        MOV     RAX,1
+        SHL     RAX,CL
+        DEC     RAX
+        AND     RAX,RDX
+        POP     RBP
+        RET1    24
+_XCHG_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        XCHG    U64 [RDX],RAX
+        POP     RBP
+        RET1    16
+_XCHG_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     EAX,U32 SF_ARG2[RBP]
+        XCHG    U32 [RDX],EAX
+        POP     RBP
+        RET1    16
+_XCHG_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U16 SF_ARG2[RBP]
+        XCHG    U16 [RDX],AX
+        POP     RBP
+        RET1    16
+_XCHG_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U8 SF_ARG2[RBP]
+        XCHG    U8 [RDX],AL
+        POP     RBP
+        RET1    16
+
+_LXCHG_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        LOCK
+        XCHG    U64 [RDX],RAX
+        POP     RBP
+        RET1    16
+_LXCHG_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     EAX,U32 SF_ARG2[RBP]
+        LOCK
+        XCHG    U32 [RDX],EAX
+        POP     RBP
+        RET1    16
+_LXCHG_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U16 SF_ARG2[RBP]
+        LOCK
+        XCHG    U16 [RDX],AX
+        POP     RBP
+        RET1    16
+_LXCHG_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U8 SF_ARG2[RBP]
+        LOCK
+        XCHG    U8 [RDX],AL
+        POP     RBP
+        RET1    16
+_REP_IN_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_INSD
+        POP     RDI
+        POP     RBP
+        RET1    24
+_REP_IN_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_INSW
+        POP     RDI
+        POP     RBP
+        RET1    24
+_REP_IN_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_INSB
+        POP     RDI
+        POP     RBP
+        RET1    24
+_REP_OUT_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_OUTSD
+        POP     RSI
+        POP     RBP
+        RET1    24
+_REP_OUT_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_OUTSW
+        POP     RSI
+        POP     RBP
+        RET1    24
+_REP_OUT_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_OUTSB
+        POP     RSI
+        POP     RBP
+        RET1    24
+_CPUID::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RAX,U64 SF_ARG1[RBP]
+        CPUID
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     U64 [RSI],RAX
+        MOV     U64 8[RSI],RBX
+        MOV     U64 16[RSI],RCX
+        MOV     U64 24[RSI],RDX
+        POP     RSI
+        POP     RBP
+        RET1    16
+_CALL_IND::     //See _LAST_FUN
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        LEA     RSI,U64 SF_ARG3[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        TEST    RDX,RDX
+        JZ      @@05
+
+        CALL    RDX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+@@05:   MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        XOR     RAX,RAX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+_CALLEXTNUM::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        LEA     RSI,U64 SF_ARG3[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        MOV     RAX,U64 [SYS_EXTERN_TABLE]
+        MOV     RAX,U64 [RAX+RDX*8]
+        TEST    RAX,RAX
+        JZ      @@05
+
+        CALL    RAX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+@@05:   MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+_CALLEXTSTR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        LEA     RSI,U64 SF_ARG3[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        MOV     RSI,U64 SF_ARG1[RBP]
+
+        MOV     RCX,1
+        XOR     RAX,RAX
+        MOV     RDI,U64 FS:CTask.hash_table[RAX]
+        MOV     RBX,HTT_FUN|HTT_EXPORT_SYS_SYM
+        CALL    SYS_HASH_FIND
+        JZ      @@15
+
+        TEST    U32 CHash.type[RAX],HTT_FUN
+        JZ      @@05
+        MOV     RAX,U64 CHashFun.exe_addr[RAX]
+        JMP     @@10
+@@05:   MOV     RAX,U64 CHashExport.val[RAX]
+@@10:   TEST    RAX,RAX
+        JZ      @@15
+
+        CALL    RAX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+@@15:   MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+SET_GS_BASE::
+        PUSH    RAX
+        PUSH    RCX
+        PUSH    RDX
+        MOV     RDX,RAX
+        SHR     RDX,32
+        MOV     ECX,IA32_GS_BASE
+        WRMSR
+        POP     RDX
+        POP     RCX
+        POP     RAX
+        RET
+SET_FS_BASE::
+        PUSH    RAX
+        PUSH    RCX
+        PUSH    RDX
+        MOV     RDX,RAX
+        SHR     RDX,32
+        MOV     ECX,IA32_FS_BASE
+        WRMSR
+        POP     RDX
+        POP     RCX
+        POP     RAX
+_RET::
+        RET
+_SET_MSR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,SF_ARG2[RBP]
+        MOV     RDX,RAX
+        SHR     RDX,32
+        MOV     RCX,SF_ARG1[RBP]
+        WRMSR
+        POP     RBP
+        RET1    16
+_SYS_HLT::
+        CLI
+@@05:   HLT
+        JMP     @@05
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/KernelA.HH.HTML b/public/Wb/Home/Src/Kernel/KernelA.HH.HTML new file mode 100755 index 0000000..0919f77 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KernelA.HH.HTML @@ -0,0 +1,3938 @@ + + + + + + + + + + + +
+// Main TempleOS header
+
+#help_index ""
+extern class CAOT;
+extern class CAOTHeapGlbl;
+extern class CAOTImportExport;
+extern class CCPU;
+extern class CDC;
+extern class CDirContext;
+extern class CDoc;
+extern class CFile;
+extern class CHashClass;
+extern class CHashFun;
+extern class CHeapCtrl;
+extern class CIntermediateCode;
+extern class CJobCtrl;
+extern class CTask;
+
+#define NULL    0
+#define TRUE    1
+#define FALSE   0
+#define ON      1
+#define OFF     0
+#define I8_MIN (-0x80)
+#define I8_MAX 0x7F
+#define U8_MIN 0
+#define U8_MAX 0xFF
+#define I16_MIN (-0x8000)
+#define I16_MAX 0x7FFF
+#define U16_MIN 0
+#define U16_MAX 0xFFFF
+#define I32_MIN (-0x80000000)
+#define I32_MAX 0x7FFFFFFF
+#define U32_MIN 0
+#define U32_MAX 0xFFFFFFFF
+#define I64_MIN (-0x8000000000000000)
+#define I64_MAX 0x7FFFFFFFFFFFFFFF
+#define U64_MIN 0
+#define U64_MAX 0xFFFFFFFFFFFFFFFF
+#define INVALID_PTR     I64_MAX
+#define STR_LEN 144
+
+//(Int to F64 conversion is signed)
+//Turn off 80-bit float constants with OPTf_NO_BUILTIN_CONST.
+#define U64_F64_MAX (0x43F0000000000000(F64))
+#define F64_MAX (0x7FEFFFFFFFFFFFFF(F64))
+#define F64_MIN (0xFFEFFFFFFFFFFFFF(F64))
+#define inf     (0x7FF0000000000000(F64))
+#define inf     (0x7FF0000000000000(F64))
+#define pi      (0x400921FB54442D18(F64))
+#define pi      (0x400921FB54442D18(F64))
+#define exp_1   (0x4005BF0A8B145769(F64)) //The number "e"
+#define log2_10 (0x400A934F0979A371(F64))
+#define log2_e  (0x3FF71547652B82FE(F64))
+#define log10_2 (0x3FD34413509F79FF(F64))
+#define loge_2  (0x3FE62E42FEFA39EF(F64))
+#define sqrt2   (0x3FF6A09E667F3BCD(F64))
+#define eps     (0x3CB0000000000000(F64))
+
+#help_index "Data Types/Simple"
+/*HolyC union structure is treated as a
+whole if no member is specified,
+similar to bit fields.
+
+See EndianI64() and ::/Demo/SubIntAccess.HC.
+*/
+U16i union U16
+{
+  I8i   i8[2];
+  U8i   u8[2];
+};
+
+I16i union I16
+{
+  I8i   i8[2];
+  U8i   u8[2];
+};
+
+U32i union U32
+{
+  I8i   i8[4];
+  U8i   u8[4];
+  I16   i16[2];
+  U16   u16[2];
+};
+
+I32i union I32
+{
+  I8i   i8[4];
+  U8i   u8[4];
+  I16   i16[2];
+  U16   u16[2];
+};
+
+U64i union U64
+{
+  I8i   i8[8];
+  U8i   u8[8];
+  I16   i16[4];
+  U16   u16[4];
+  I32   i32[2];
+  U32   u32[2];
+};
+
+I64i union I64
+{
+  I8i   i8[8];
+  U8i   u8[8];
+  I16   i16[4];
+  U16   u16[4];
+  I32   i32[2];
+  U32   u32[2];
+};
+
+#help_index "Math/Complex;Data Types/Complex"
+public class Complex
+{
+  F64   x,y;
+};
+
+#help_index "Data Types/Circular Queue"
+public class CQue
+{
+  CQue  *next,*last;
+};
+
+#help_index "Graphics/Data Types/D3I32;Math/Data Types/D3I32;Data Types/D3I32"
+public class CD3I32 //Three dimensional I32 pt
+{
+  I32   x,y,z;
+};
+public class CQueD3I32 //Que of three dimensional I32 pts
+{
+  CQueD3I32     *next,*last;
+  CD3I32        p;
+};
+#help_index "Math/Data Types;Data Types"
+public class CD2I32 //Two dimensional I32 pt
+{
+  I32   x,y;
+};
+public class CD2I64 //Two dimensional I64 pt
+{
+  I64   x,y;
+};
+public class CD3I64 //Three dimensional I64 pt
+{
+  I64   x,y,z;
+};
+public class CD2 //Two dimensional F64 pt
+{
+  F64   x,y;
+};
+
+#help_index "Math/CD3;Data Types/CD3"
+public class CD3 //Three dimensional F64 pt
+{
+  F64   x,y,z;
+};
+
+#help_index "Data Types/Queue Vector"
+#define QUE_VECT_U8_CNT         512
+public class CQueVectU8
+{
+  CQueVectU8    *next,*last;
+  I64   total_cnt,node_cnt,min_idx;
+  U8    body[QUE_VECT_U8_CNT];
+};
+
+#help_index "Data Types/Fifo"
+public class CFifoU8
+{
+  U8    *buf;
+  I64   mask,in_ptr,out_ptr;
+};
+public class CFifoI64
+{
+  I64   *buf;
+  I64   mask,in_ptr,out_ptr;
+};
+
+#help_index "Date/CDate"
+#define CDATE_YEAR_DAYS         365.24225
+#define CDATE_YEAR_DAYS_INT     36524225
+#define CDATE_BASE_DAY_OF_WEEK  0
+public I64 class CDate
+{
+  U32   time;
+  I32   date;
+};
+
+#help_index "Date;Date/CDate"
+public class CDateStruct
+{
+  U8    sec10000,sec100,sec,min,hour,
+        day_of_week,day_of_mon,mon;
+  I32   year;
+};
+
+#help_index "Math/ODE"
+public class COrder2D3
+{
+  F64   x,y,z,
+        DxDt,DyDt,DzDt;
+};
+
+#define MSF_INACTIVE            1
+#define MSF_FIXED               2
+public class CMass
+{
+  CMass *next,*last;
+  COrder2D3 *state, //Point to entries in CMathODE.state[]
+        *DstateDt;  //Point to entries in CMathODE.DstateDt[]
+
+  U0    start;
+  U32   flags,num;
+  F64   mass,drag_profile_factor;
+  U0    saved_state;
+  F64   x,y,z,
+        DxDt,DyDt,DzDt;
+  U0    end;
+};
+
+#define SSF_INACTIVE            1
+#define SSF_NO_COMPRESSION      2
+#define SSF_NO_TENSION          4
+public class CSpring
+{
+  CSpring *next,*last;
+  CMass *end1,*end2;
+  F64   f,displacement; //set for you to check
+
+  U0    start;
+  U32   flags,num,
+        end1_num,end2_num;
+  F64   const,rest_len;
+  U0    end;
+};
+
+//Ordinary Differential Equations
+#define ODEF_HAS_MASSES 1
+#define ODEF_PAUSED     2
+#define ODEF_STARTED    4
+#define ODEF_BUSY       8
+
+#define ODEf_HAS_MASSES 0
+#define ODEf_PAUSED     1
+#define ODEf_STARTED    2
+#define ODEf_BUSY       3
+
+public class CMathODE
+{
+  CMathODE *next,*last;
+  I64   flags,n,n_internal;
+  CMass *next_mass,*last_mass;
+  CSpring *next_spring,*last_spring;
+  F64   drag_v,  //drag proportional to velocity
+        drag_v2, //drag proportional to velocity squared
+        drag_v3, //drag proportional to velocity cubed
+        acceleration_limit, //This clips acceleration
+        base_t,
+        t,t_scale,
+        h,h_min,h_max;
+
+  //This is not precise, just a ballpark.
+  //TempleOS CMathODE's are for video games
+  //not science.  It bails if it takes
+  //too long.
+  F64   min_tolerance,max_tolerance;
+
+  F64   tolerance_internal,
+        *array_base,
+        *state,
+        *state_internal,
+        *DstateDt,
+        *state_scale,
+        *initial_state,
+        *tmp0,*tmp1,*tmp2,*tmp3,
+        *tmp4,*tmp5,*tmp6,*tmp7;
+  CTask *mem_task,*win_task;
+  U0    (*derive)(CMathODE *o,F64 t,F64 *state,F64 *DstateDt);
+  U0    (*mp_derive)(CMathODE *o,F64 t, //If break into parallel pieces.
+                I64 cpu_num,F64 *state,F64 *DstateDt);
+  CTask **slave_tasks;
+  I64   mp_not_done_flags;
+  F64   mp_t,*mp_state,*mp_DstateDt;
+
+  I64   user_data;
+};
+
+#help_index "Processor"
+//IDT entry types
+#define IDTET_TASK              0x05
+#define IDTET_IRQ               0x0E
+#define IDTET_TRAP              0x0F //Same as IRQ but doesnt do CLI.
+
+//Interrupts
+//0x00-0x1F are reserved by Intel
+#define I_DIV_ZERO              0x00
+#define I_SINGLE_STEP           0x01
+#define I_NMI                   0x02
+#define I_BPT                   0x03
+#define I_PAGE_FAULT            0x0E
+//0x20-0x2F are used for hardware
+#define I_TIMER                 0x20
+//Software Interrupts
+#define I_MP_CRASH              0x30
+#define I_WAKE                  0x31
+#define I_DBG                   0x32
+//See ST_INT_NAMES
+
+//You might want to start bwd from
+//0xFF for your own interrupts.
+#define I_USER                  0x40
+
+#define MP_PROCESSORS_NUM       128
+
+#define SYS_START_CR0           0x0031
+
+#define RFLAGf_CARRY            0
+#define RFLAGf_PARITY           2
+#define RFLAGf_AUX_CARRY        4
+#define RFLAGf_ZERO             6
+#define RFLAGf_SIGN             7
+#define RFLAGf_TRAP             8 //Single Step
+#define RFLAGf_INT              9
+#define RFLAGf_DIR              10
+#define RFLAGf_OVERFLOW         11
+#define RFLAGf_IOPL0            12 // I/O Privilege Level
+#define RFLAGf_IOPL1            13
+#define RFLAGf_NESTED_TASK      14
+#define RFLAGf_RESUME           16
+#define RFLAGf_V8086            17
+#define RFLAGf_ALIGN_CHECK      18
+#define RFLAGf_VINT             19 //Virtual Interrupt
+#define RFLAGf_VINT_PENDING     20
+#define RFLAGf_ID               21
+
+#define RFLAGG_START            0x0000
+#define RFLAGG_NORMAL           (1<<RFLAGf_INT)
+
+//Global Descriptor Table
+class CGDTEntry
+{
+  U64   lo,hi;
+};
+
+class CGDT
+{
+  CGDTEntry null;
+  CGDTEntry boot_ds;
+  CGDTEntry boot_cs;
+  CGDTEntry cs32;
+  CGDTEntry cs64;       //The Charter says just ring-0.
+  CGDTEntry cs64_ring3; //Ring3, in case you want to play around.
+  CGDTEntry ds;
+  CGDTEntry ds_ring3;
+  CGDTEntry tr[MP_PROCESSORS_NUM];
+  CGDTEntry tr_ring3[MP_PROCESSORS_NUM];
+};
+
+class CSysLimitBase
+{
+  U16   limit;  //Offset of last byte, not size.
+  U8    *base;  //&GDT or &IDT
+};
+
+#help_index "Memory/Info"
+#define MEM_E820_ENTRIES_NUM    48
+class CMemE820
+{
+  U8    *base;
+  I64   len;
+  U8    type,pad[3];
+};
+
+#help_index "Compiler/Internal"
+//Loader flags
+#define LDF_NO_ABSS             1
+#define LDF_JUST_LOAD           2
+#define LDF_SILENT              4
+
+#define BIN_SIGNATURE_VAL       'TOSB'
+class CBinFile
+{//Bin File Header Generation by compiler.
+  U16   jmp;
+  U8    module_align_bits,
+        reserved;
+  U32   bin_signature;
+  I64   org,
+        patch_table_offset, //Patch Table Generation
+        file_size;
+};
+
+class CPatchTableAbsAddr
+{
+  U8    eit_abs_addr;   //IET_ABS_ADDR
+  U32   abs_addres_cnt;
+  U8    zero;
+  U32   abs_addres[1];
+};
+
+//CAOTImportExport Types. Used in PatchTable.
+#define IET_END                 0
+//reserved
+#define IET_REL_I0              2 //Fictitious
+#define IET_IMM_U0              3 //Fictitious
+#define IET_REL_I8              4
+#define IET_IMM_U8              5
+#define IET_REL_I16             6
+#define IET_IMM_U16             7
+#define IET_REL_I32             8
+#define IET_IMM_U32             9
+#define IET_REL_I64             10
+#define IET_IMM_I64             11
+#define IEF_IMM_NOT_REL         1
+//reserved
+#define IET_REL32_EXPORT        16
+#define IET_IMM32_EXPORT        17
+#define IET_REL64_EXPORT        18 //Not implemented
+#define IET_IMM64_EXPORT        19 //Not implemented
+#define IET_ABS_ADDR            20
+#define IET_CODE_HEAP           21 //Not really used
+#define IET_ZEROED_CODE_HEAP    22 //Not really used
+#define IET_DATA_HEAP           23
+#define IET_ZEROED_DATA_HEAP    24 //Not really used
+#define IET_MAIN                25
+
+#help_index "Boot"
+class CKernel
+{//Must match OSStartUp
+  CBinFile h;
+  U32   jmp,
+        boot_src,
+        boot_blk,
+        boot_patch_table_base,
+        sys_run_level;
+  CDate compile_time;
+
+  U0    start;
+  U32   boot_base;
+  U16   mem_E801[2];
+  CMemE820 mem_E820[MEM_E820_ENTRIES_NUM];
+  U64   mem_physical_space;
+  CSysLimitBase sys_gdt_ptr;
+  U16   sys_pci_busses;
+  ;$=($+15)&-16;
+  CGDT  sys_gdt;
+};
+
+//Run-Levels
+#define RLf_16BIT               0
+#define RLf_VGA                 1
+#define RLf_32BIT               2
+#define RLf_PATCHED             3
+#define RLf_16MEG_SYS_CODE_BP   4
+#define RLf_64BIT               5
+#define RLf_16MEG_ADAM_HEAP_CTRL 6
+#define RLf_FULL_HEAPS          7
+#define RLf_RAW                 8
+#define RLf_INTERRUPTS          9
+#define RLf_BLKDEV              10
+#define RLf_MP                  11
+#define RLf_COMPILER            12
+#define RLf_DOC                 13
+#define RLf_WINMGR              14
+#define RLf_REGISTRY            15
+#define RLf_HOME                16
+#define RLf_AUTO_COMPLETE       17
+#define RLf_ADAM_SERVER         18
+#define RLf_ONCE_ADAM           19
+#define RLf_ONCE_USER           20
+
+#define RLF_16BIT               0x000001
+#define RLF_VGA                 0x000002
+#define RLF_32BIT               0x000004
+#define RLF_PATCHED             0x000008
+#define RLF_16MEG_SYS_CODE_BP   0x000010
+#define RLF_64BIT               0x000020
+#define RLF_16MEG_ADAM_HEAP_CTRL 0x000040
+#define RLF_FULL_HEAPS          0x000050
+#define RLF_RAW                 0x000100
+#define RLF_INTERRUPTS          0x000200
+#define RLF_BLKDEV              0x000400
+#define RLF_MP                  0x000800
+#define RLF_COMPILER            0x001000
+#define RLF_DOC                 0x002000
+#define RLF_WINMGR              0x004000
+#define RLF_REGISTRY            0x008000
+#define RLF_HOME                0x010000
+#define RLF_AUTO_COMPLETE       0x020000
+#define RLF_ADAM_SERVER         0x040000
+#define RLF_ONCE_ADAM           0x080000
+#define RLF_ONCE_USER           0x100000
+
+#help_index "Processor"
+#define LAPIC_BASE              0xFEE00000
+
+#define LAPIC_APIC_ID           (LAPIC_BASE+0x020)
+#define LAPIC_APIC_VERSION      (LAPIC_BASE+0x030)
+#define LAPIC_TASK_PRIORITY     (LAPIC_BASE+0x080)
+#define LAPIC_ARIBITRATION_PRIORITY (LAPIC_BASE+0x090)
+#define LAPIC_PROCESSOR_PRIORITY (LAPIC_BASE+0x0A0)
+#define LAPIC_EOI               (LAPIC_BASE+0x0B0)
+#define LAPIC_LOG_DST           (LAPIC_BASE+0x0D0)
+#define LAPIC_DFR               (LAPIC_BASE+0x0E0)
+#define LAPIC_LDR               (LAPIC_BASE+0x0D0)
+
+#define LAPICF_APIC_ENABLED     0x100
+#define LAPIC_SVR               (LAPIC_BASE+0x0F0)
+
+#define LAPIC_ISR               (LAPIC_BASE+0x100)
+#define LAPIC_TMR               (LAPIC_BASE+0x180)
+#define LAPIC_IRR               (LAPIC_BASE+0x200)
+#define LAPIC_ICR_LOW           (LAPIC_BASE+0x300)
+#define LAPIC_ICR_HIGH          (LAPIC_BASE+0x310)
+
+#define LAPIC_LVT_TIMER         (LAPIC_BASE+0x320)
+#define LAPIC_LVT_THERMAL       (LAPIC_BASE+0x330)
+#define LAPIC_LVT_PERF          (LAPIC_BASE+0x340)
+#define LAPIC_LVT_LINT0         (LAPIC_BASE+0x350)
+#define LAPIC_LVT_LINT1         (LAPIC_BASE+0x360)
+#define LAPIC_LVT_ERR           (LAPIC_BASE+0x370)
+
+#define MPN_VECT                0x97
+#define MP_VECT_ADDR            (MPN_VECT*0x1000)
+
+//I/O APIC Memory mapped window
+#define IOAPIC_REG              0xFEC00000 //U8
+#define IOAPIC_DATA             0xFEC00010 //U32
+//I/O APIC Regs
+#define IOAPICID                0x00
+#define IOAPICVER               0x01
+#define IOAPICARB               0x02
+#define IOREDTAB                0x10
+
+//Model specific regs.
+#define IA32F_SCE       0x001
+#define IA32F_LME       0x100
+#define IA32_LAPIC_BASE 0x01B
+#define IA32_EFER       0xC0000080
+#define IA32_FS_BASE    0xC0000100
+#define IA32_GS_BASE    0xC0000101
+
+class CAP16BitInit
+{//AP Multicore
+  U32   jmp;
+  CSysLimitBase ap_gdt_ptr;
+};
+
+#help_index "Time/CPU Cycles;Time/HPET;Time/Jiffies"
+//High Performance Event Timer
+#define HPET_GCAP_ID    (0xFED00000+0x00)
+#define HPET_GEN_CONF   (0xFED00000+0x10)
+#define HPET_MAIN_CNT   (0xFED00000+0xF0)
+
+public class CCntsGlbls
+{
+  I64   jiffies,        //JIFFY_FREQ
+        timer,          //SYS_TIMER_FREQ. Use SysTimerRead().
+        time_stamp_freq,
+        time_stamp_kHz_freq,
+        time_stamp_freq_initial, //Initial freq, sampled once at boot time.
+        HPET_freq,
+        HPET_kHz_freq,
+        HPET_initial;   //Initial count, sampled at boot time.
+  Bool  time_stamp_calibrated;
+};
+
+#define JIFFY_FREQ              1000 // Hz
+#define CDATE_FREQ              49710 // Hz
+#define SYS_TIMER_FREQ          (18333*65536/1000) //Hz
+#define SYS_TIMER0_PERIOD       (65536*182/10/JIFFY_FREQ)
+
+#help_index "Call"
+//Function Stack Frame
+#define SF_RBP  0x00
+#define SF_RIP  0x08
+#define SF_ARG1 0x10
+#define SF_ARG2 0x18
+#define SF_ARG3 0x20
+#define SF_ARG4 0x28
+#define SF_ARG5 0x30
+#define SF_ARG6 0x38
+#define SF_ARG7 0x40
+#define SF_ARG8 0x48
+
+class CRAXRBCRCXRDX
+{
+  I64   rax,rbx,rcx,rdx;
+};
+
+//Asm callable function pointers.
+//They work with CallExtNum() when calling from HolyC.
+#define EXT_WIN_TO_TOP          0
+#define EXT_WIN_FOCUS           1
+#define EXT_HEAPLOG_MALLOC      2
+#define EXT_HEAPLOG_FREE        3
+#define EXT_DBG_RESUME          4
+#define EXT_EXTS_NUM            5
+
+#help_index "Processor"
+#define DFT_CACHE_LINE_WIDTH    128
+
+//Semaphores
+class CSema
+{
+  Bool  val,pad[DFT_CACHE_LINE_WIDTH-1];
+};
+#define SEMA_DEBUG              0
+#define SEMA_RECORD_MACRO       1
+#define SEMA_SYS_TIMER          2
+#define SEMA_SYS_DATE           3
+#define SEMA_DBG_MODE           4
+#define SEMA_SND                5
+#define SEMA_HEAPLOG_ACTIVE     6
+#define SEMA_HEAPLOG_LOCK       7
+#define SEMA_REFRESH_IN_PROGRESS 8
+#define SEMA_FLUSH_VGA_IMAGE    9
+#define SEMA_SINGLE_USER        10
+#define SEMA_DSK_CACHE          11
+#define SEMA_FAR_CALL32         12
+#define SEMA_DEV_MEM            13
+#define SEMA_VGA                14
+#define SEMA_UPDATE_WIN_Z_BUF   15
+#define SEMA_TT                 16
+#define SEMA_MUTE               17
+#define SEMA_JUST_PUMP_MSGS     18
+#define SEMA_TMBEAT             19
+#define SEMA_FIX                20
+#define SEMA_SEMAS_NUM          21
+
+#define CTRL_ALT_DEL            0
+#define CTRL_ALT_C              1
+#define CTRL_ALT_X              2
+#define CTRL_ALT_TAB            3
+
+#help_index "Hash"
+public class CHash
+{//See Hash
+  CHash *next;
+  U8    *str;
+  U32   type,
+        use_cnt; // inc'ed every time search found, never dec'ed.
+};
+
+public class CHashTable
+{
+  CHashTable *next;
+  I64   mask,locked_flags;
+  CHash **body;
+};
+
+#help_index "Hash/System"
+//Hash table types: ST_HTT_TYPES
+#define HTt_EXPORT_SYS_SYM      0
+#define HTt_IMPORT_SYS_SYM      1
+#define HTt_DEFINE_STR          2
+#define HTt_GLBL_VAR            3
+#define HTt_CLASS               4
+#define HTt_INTERNAL_TYPE       5
+#define HTt_FUN                 6
+#define HTt_WORD                7
+#define HTt_DICT_WORD           8
+#define HTt_KEYWORD             9
+#define HTt_ASM_KEYWORD         10
+#define HTt_OPCODE              11
+#define HTt_REG                 12
+#define HTt_FILE                13
+#define HTt_MODULE              14
+#define HTt_HELP_FILE           15
+#define HTt_FRAME_PTR           16
+#define HTt_TYPES_NUM           17
+
+#define HTf_PRIVATE             23
+#define HTf_PUBLIC              24
+#define HTf_EXPORT              25
+#define HTf_IMPORT              26
+#define HTf_IMM                 27
+#define HTf_GOTO_LABEL          28
+#define HTf_RESOLVED            29
+#define HTf_UNRESOLVED          30
+#define HTf_LOCAL               31
+
+#define HTT_INVALID             0
+#define HTT_EXPORT_SYS_SYM      0x00001 //CHashExport
+#define HTT_IMPORT_SYS_SYM      0x00002 //CHashImport
+#define HTT_DEFINE_STR          0x00004 //CHashDefineStr
+#define HTT_GLBL_VAR            0x00008 //CHashGlblVar
+#define HTT_CLASS               0x00010 //CHashClass
+#define HTT_INTERNAL_TYPE       0x00020 //CHashClass
+#define HTT_FUN                 0x00040 //CHashFun
+#define HTT_WORD                0x00080 //CHashAC only in AutoComplete table
+#define HTT_DICT_WORD           0x00100 //CHashGeneric only in AutoComplete tbl
+#define HTT_KEYWORD             0x00200 //CHashGeneric KEYWORD
+#define HTT_ASM_KEYWORD         0x00400 //CHashGeneric ASM_KEYWORD
+#define HTT_OPCODE              0x00800 //CHashOpcode
+#define HTT_REG                 0x01000 //CHashReg
+#define HTT_FILE                0x02000 //CHashGeneric
+#define HTT_MODULE              0x04000 //CHashGeneric
+#define HTT_HELP_FILE           0x08000 //CHashSrcSym
+#define HTT_FRAME_PTR           0x10000 //CHashGeneric
+#define HTG_TYPE_MASK           0x1FFFF
+
+#define HTF_PRIVATE             0x00800000
+#define HTF_PUBLIC              0x01000000
+#define HTF_EXPORT              0x02000000
+#define HTF_IMPORT              0x04000000
+#define HTF_IMM                 0x08000000
+#define HTF_GOTO_LABEL          0x10000000
+#define HTF_RESOLVE             0x20000000
+#define HTF_UNRESOLVED          0x40000000
+#define HTF_LOCAL               0x80000000
+#define HTG_FLAGS_MASK          0xFF000000
+
+#define HTG_SRC_SYM     (HTT_DEFINE_STR|HTT_GLBL_VAR|HTT_FUN|HTT_CLASS|\
+                        HTT_EXPORT_SYS_SYM|HTT_HELP_FILE)
+#define HTG_ALL                 -1
+
+#define KERNEL_MODULE_NAME      "/Kernel/Kernel"
+
+class CDbgInfo
+{
+  U32   min_line,max_line;
+  U32   body[1]; //Code heap is 32-bit value
+};
+
+public class CHashSrcSym:CHash
+{
+  U8    *src_link,
+        *idx;
+  CDbgInfo *dbg_info;
+  U8    *import_name;
+  CAOTImportExport *ie_lst;
+};
+
+public class CHashGeneric:CHash
+{
+  I64   user_data0,user_data1,user_data2;
+};
+
+#define REGT_NONE       0
+#define REGT_R8         1
+#define REGT_R16        2
+#define REGT_R32        3
+#define REGT_R64        4
+#define REGT_SEG        5
+#define REGT_FSTK       6
+#define REGT_MM         7
+#define REGT_XMM        8
+
+public class CHashReg:CHash
+{
+  U8    reg_num,reg_type;
+};
+
+public class CHashAC:CHash
+{
+  I32   num;
+  U32   hits;
+};
+
+public class CHashExport:CHashSrcSym
+{
+  I64   val;
+};
+
+public class CHashImport:CHashSrcSym
+{
+  U8    *module_base,
+        *module_header_entry;
+};
+
+#help_index "Compiler/Internal"
+#define PTR_STARS_NUM   4
+
+//Member Lst Flags
+#define MLF_DFT_AVAILABLE       1
+#define MLF_LASTCLASS           2
+#define MLF_STR_DFT_AVAILABLE   4
+#define MLF_FUN                 8
+#define MLF_DOT_DOT_DOT         16
+#define MLF_NO_UNUSED_WARN      32
+#define MLF_STATIC              64
+
+public class CArrayDim
+{
+  CArrayDim *next;
+  I64   cnt,total_cnt;
+};
+
+#define MLMF_IS_STR     1
+public class CMemberLstMeta
+{
+  CMemberLstMeta *next;
+  U8    *str;
+  I64   flags,
+        user_data;
+};
+
+public class CMemberLst
+{
+  CMemberLst *next,*left,*right,
+        *left_class_base,*right_class_base; //For finding dup class local vars.
+  U8    *str;
+  CHashClass *member_class,*member_class_base;
+  CMemberLstMeta *meta;
+  U32   use_cnt;
+  U16   flags;
+  I8    reg,pad;
+  I64   offset,size;
+  CArrayDim dim;
+  U8    *static_data;
+  union {
+    I64 static_data_rip;
+    I64 dft_val;
+  }
+  CHashFun *fun_ptr;
+};
+
+class CExternUsage
+{
+  CExternUsage *next;
+  I64   rip;
+};
+
+#help_index "Hash/System;Compiler/Internal"
+public class CHashDefineStr:CHashSrcSym
+{
+  U8    *data,**sub_idx;
+  I64   cnt;
+};
+
+#define Cf_EXTERN               0
+#define Cf_INTERNAL_TYPE        1
+
+public class CHashClass:CHashSrcSym
+{//See PrsClassNew(). base_class of CHashFun
+  I64   size,neg_offset;
+  U32   member_cnt;
+  U8    ptr_stars_cnt,raw_type;
+  U16   flags;
+  CMemberLst *member_lst_and_root, //Head of linked list and head of tree.
+        *member_class_base_root, //For finding dup class local vars.
+        *last_in_member_lst;
+  CHashClass    *base_class,
+        *fwd_class;
+};
+
+//Function flags
+#define Ff_INTERRUPT            8
+#define Ff_HASERRCODE           9
+#define Ff_ARGPOP               10
+#define Ff_NOARGPOP             11
+#define Ff_INTERNAL             12
+#define Ff__EXTERN              13
+#define Ff_DOT_DOT_DOT          14
+#define Ff_RET1                 15
+
+public class CHashFun:CHashClass
+{//See PrsFunNew().
+  CHashClass *return_class;
+  U32   arg_cnt,pad,
+        used_reg_mask,clobbered_reg_mask;
+  U8    *exe_addr;
+  CExternUsage *ext_lst;
+};
+
+//Glbl Var Flags
+#define GVF_FUN         1
+#define GVF_IMPORT      2
+#define GVF_EXTERN      4
+#define GVF_DATA_HEAP   8
+#define GVF_ALIAS       16
+#define GVF_ARRAY       32
+
+public class CHashGlblVar:CHashSrcSym
+{
+  I64   size,flags;
+  CHashClass *var_class;
+  CHashFun *fun_ptr;
+  CArrayDim dim;
+  U8    *data_addr;
+  union {
+    I64 data_addr_rip;
+    CAOTHeapGlbl *heap_glbl;
+  }
+};
+#assert offset(CHashClass.size)==offset(CHashGlblVar.size)
+
+#help_index "DolDoc"
+//See TextBase Layer.
+#define ATTRF_BLINK     0x10000000
+#define ATTRF_INVERT    0x20000000
+#define ATTRF_SEL       0x40000000
+#define ATTRF_UNDERLINE 0x80000000
+
+#define ATTRf_BLINK             28
+#define ATTRf_INVERT            29
+#define ATTRf_SEL               30
+#define ATTRf_UNDERLINE         31
+
+//CDocEntry.type codes (Low 8 bits)
+#define DOCT_TEXT               0
+#define DOCT_NEW_LINE           1
+#define DOCT_SOFT_NEW_LINE      2
+#define DOCT_TAB                3
+#define DOCT_PAGE_BREAK         4
+#define DOCT_CURSOR             5
+#define DOCT_MARKER             6
+#define DOCT_PMT                7
+#define DOCT_CLEAR              8
+#define DOCT_PAGE_LEN           9
+#define DOCT_LEFT_MARGIN        10
+#define DOCT_RIGHT_MARGIN       11
+#define DOCT_HEADER             12
+#define DOCT_FOOTER             13
+#define DOCT_INDENT             14
+#define DOCT_FOREGROUND         15
+#define DOCT_BACKGROUND         16
+#define DOCT_DFT_FOREGROUND     17
+#define DOCT_DFT_BACKGROUND     18
+#define DOCT_WORD_WRAP          19
+#define DOCT_HIGHLIGHT          20
+#define DOCT_BLINK              21
+#define DOCT_INVERT             22
+#define DOCT_UNDERLINE          23
+#define DOCT_SHIFTED_X          24
+#define DOCT_SHIFTED_Y          25
+#define DOCT_CURSOR_MOVEMENT    26
+#define DOCT_ANCHOR             27
+#define DOCT_LINK               28
+#define DOCT_BTTN               29
+#define DOCT_DATA               30
+#define DOCT_CHECK_BOX          31
+#define DOCT_LST                32
+#define DOCT_MACRO              33
+#define DOCT_MENU_VAL           34
+#define DOCT_HEX_ED             35
+#define DOCT_TREE               36
+#define DOCT_SPRITE             37
+#define DOCT_INS_BIN            38
+#define DOCT_INS_BIN_SIZE       39
+#define DOCT_SONG               40
+#define DOCT_HTML_CODE          41
+#define DOCT_ERROR              42
+
+#define DOCT_TYPES_NUM          43
+
+//CDocEntry.type flags upper bits
+#define DOCET_BLINK             ATTRF_BLINK
+#define DOCET_INVERT            ATTRF_INVERT
+#define DOCET_SEL               ATTRF_SEL
+#define DOCET_UNDERLINE         ATTRF_UNDERLINE
+#define DOCG_BL_IV_UL           0xB0000000
+
+#define DOCEt_BLINK             ATTRf_BLINK
+#define DOCEt_INVERT            ATTRf_INVERT
+#define DOCEt_SEL               ATTRf_SEL
+#define DOCEt_UNDERLINE         ATTRf_UNDERLINE
+
+#define DOCG_DBL_BUF_FLAGS      (DOCF_OVERSTRIKE|DOCF_PLAIN_TEXT|\
+                DOCF_PLAIN_TEXT_TABS|DOCF_SIZE_MIN|DOCF_NO_CURSOR|\
+                DOCF_FORM|DOCF_DBL_DOLLARS|DOCF_DONT_SWAP_OUT|\
+                DOCF_DO_FULL_REFRESH|DOCF_BORDER_DOC|DOCF_HIDE_CURSOR|\
+                DOCF_DONT_HIGHLIGHT_CURSOR|DOCF_CARRIAGE_RETURN)
+
+//CDocEntry.de_flags.  These first 16 are arg=
+#define DOCEF_TAG               1
+#define DOCEF_LEN               2
+#define DOCEF_AUX_STR           4
+#define DOCEF_DEFINE            8
+#define DOCEF_HTML_LINK         0x10
+#define DOCEF_LEFT_EXP          0x20
+#define DOCEF_LEFT_MACRO        0x40
+#define DOCEF_RIGHT_EXP         0x80
+#define DOCEF_RIGHT_MACRO       0x100
+#define DOCEF_HAS_BIN           0x200
+#define DOCEF_BIN_PTR_LINK      0x400
+#define DOCEF_RAW_TYPE          0x800
+#define DOCEF_SHIFTED_X         0x1000
+#define DOCEF_SHIFTED_Y         0x2000
+#define DOCEF_SCROLLING_X       0x4000
+#define DOCEF_USER_DATA         0x8000
+
+//CDocEntry.de_flags.  These are +/- flags
+#define DOCEF_LEFT_CB           0x10000
+#define DOCEF_LEFT_IN_STR       0x20000
+#define DOCEF_RIGHT_CB          0x40000
+#define DOCEF_RIGHT_IN_STR      0x80000
+#define DOCEF_LEFT_X            0x100000
+#define DOCEF_CENTER_X          0x200000
+#define DOCEF_RIGHT_X           0x400000
+#define DOCEF_TOP_Y             0x800000
+#define DOCEF_CENTER_Y          0x1000000
+#define DOCEF_BOTTOM_Y          0x2000000
+//HL...UL
+#define DOCEF_TAG_CB            0x100000000
+#define DOCEF_PAGE_REL_Y        0x200000000
+#define DOCEF_MARGIN_REL_X      0x400000000
+#define DOCEF_WIN_REL           0x800000000
+#define DOCEF_LINK              0x1000000000
+#define DOCEF_ESC               0x2000000000 //Send <ESC> (Exit and Save)
+#define DOCEF_QUIT              0x4000000000 //Send <SHIFT-ESC> (Abort)
+#define DOCEF_FROM_START        0x8000000000
+#define DOCEF_HAS_BORDER        0x10000000000
+#define DOCEF_SOLID_BORDER      0x20000000000
+#define DOCEF_BORDER_PLOT       0x40000000000
+#define DOCEF_CHECKED_COLLAPSED 0x80000000000 //Checked or Collapsed
+#define DOCEF_CHECK_COLLAPSABLE 0x100000000000
+#define DOCEF_REFRESH_DATA      0x200000000000
+#define DOCEF_UPDATE_DATA       0x400000000000
+//DOCEF_DEREF_DATA is confusing. DocForm() makes doc_e->data point to members
+//of class. For ints, it derefs doc_e->data as a ptr.  For strings, it doesn't.
+#define DOCEF_DEREF_DATA        0x800000000000
+#define DOCEF_REMALLOC_DATA     0x1000000000000
+#define DOCEF_HAS_TERMINATOR    0x2000000000000
+#define DOCEF_ZERO_BASED        0x4000000000000
+#define DOCEF_HOLD              0x8000000000000
+#define DOCEF_TREE              0x10000000000000
+#define DOCEF_LST               0x20000000000000
+#define DOCEF_SKIP              0x40000000000000
+#define DOCEF_POPUP             0x80000000000000
+#define DOCEF_SKIP_IN_FORM      0x100000000000000
+#define DOCEF_FILTER_SKIP       0x200000000000000
+#define DOCEF_NO_CLICK_ON       0x400000000000000
+#define DOCEF_DONT_DRAW         0x800000000000000 //only works on sprites
+#define DOCEF_DFT_LEN           0x1000000000000000
+#define DOCEF_DFT_RAW_TYPE      0x2000000000000000
+
+#define DOCEG_HAS_ALLOC         (DOCEF_TAG|DOCEF_AUX_STR|DOCEF_DEFINE|\
+  DOCEF_HTML_LINK|DOCEF_LEFT_MACRO|DOCEF_RIGHT_MACRO|DOCEF_BIN_PTR_LINK|\
+  DOCEF_REMALLOC_DATA)
+
+#define DOCEG_HAS_ARG           ((DOCEG_HAS_ALLOC&~DOCEF_REMALLOC_DATA)|\
+  DOCEF_LEN|DOCEF_LEFT_EXP|DOCEF_RIGHT_EXP|DOCEF_HAS_BIN|DOCEF_RAW_TYPE|\
+  DOCEF_SHIFTED_X|DOCEF_SHIFTED_Y|DOCEF_SCROLLING_X|DOCEF_USER_DATA)
+
+#define DOCEG_DONT_EDIT (DOCEF_DEFINE|DOCEF_HTML_LINK|\
+  DOCEF_AUX_STR|DOCEF_BIN_PTR_LINK|DOCEF_SCROLLING_X|DOCEF_TAG_CB)
+
+//These are ident to Doc flags
+#define DOCEF_HIGHLIGHT         0x4000000
+#define DOCEF_WORD_WRAP         0x8000000
+#define DOCEF_BLINK             ATTRF_BLINK
+#define DOCEF_INVERT            ATTRF_INVERT
+#define DOCEF_SEL               ATTRF_SEL
+#define DOCEF_UNDERLINE         ATTRF_UNDERLINE
+#define DOCEf_HIGHLIGHT         26
+#define DOCEf_WORD_WRAP         27
+#define DOCEf_BLINK             ATTRf_BLINK
+#define DOCEf_INVERT            ATTRf_INVERT
+#define DOCEf_SEL               ATTRf_SEL
+#define DOCEf_UNDERLINE         ATTRf_UNDERLINE
+
+//CDocEntry.de_flags.  These first 16 are arg=
+#define DOCEf_TAG               0
+#define DOCEf_LEN               1
+#define DOCEf_AUX_STR           2
+#define DOCEf_DEFINE            3
+#define DOCEf_HTML_LINK         4
+#define DOCEf_LEFT_EXP          5
+#define DOCEf_LEFT_MACRO        6
+#define DOCEf_RIGHT_EXP         7
+#define DOCEf_RIGHT_MACRO       8
+#define DOCEf_HAS_BIN           9
+#define DOCEf_BIN_PTR_LINK      10
+#define DOCEf_RAW_TYPE          11
+#define DOCEf_SHIFTED_X         12
+#define DOCEf_SHIFTED_Y         13
+#define DOCEf_SCROLLING_X       14
+#define DOCEf_USER_DATA         15
+
+//CDocEntry.de_flags.  These are +/- flags
+#define DOCEf_LEFT_CB           16
+#define DOCEf_LEFT_IN_STR       17
+#define DOCEf_RIGHT_CB          18
+#define DOCEf_RIGHT_IN_STR      19
+#define DOCEf_LEFT_X            20
+#define DOCEf_CENTER_X          21
+#define DOCEf_RIGHT_X           22
+#define DOCEf_TOP_Y             23
+#define DOCEf_CENTER_Y          24
+#define DOCEf_BOTTOM_Y          25
+//HL...UL
+#define DOCEf_TAG_CB            32
+#define DOCEf_PAGE_REL_Y        33
+#define DOCEf_MARGIN_REL_X      34
+#define DOCEf_WIN_REL           35
+#define DOCEf_LINK              36
+#define DOCEf_ESC               37 //Send <ESC> (Exit and Save)
+#define DOCEf_QUIT              38 //Send <SHIFT-ESC> (Abort)
+#define DOCEf_FROM_START        39
+#define DOCEf_HAS_BORDER        40
+#define DOCEf_SOLID_BORDER      41
+#define DOCEf_BORDER_PLOT       42
+#define DOCEf_CHECKED_COLLAPSED 43 //Checked or Collapsed
+#define DOCEf_CHECK_COLLAPSABLE 44
+#define DOCEf_REFRESH_DATA      45
+#define DOCEf_UPDATE_DATA       46
+#define DOCEf_DEREF_DATA        47
+#define DOCEf_REMALLOC_DATA     48
+#define DOCEf_HAS_TERMINATOR    49
+#define DOCEf_ZERO_BASED        50
+#define DOCEf_HOLD              51
+#define DOCEf_TREE              52
+#define DOCEf_LST               53
+#define DOCEf_SKIP              54
+#define DOCEf_POPUP             55
+#define DOCEf_SKIP_IN_FORM      56
+#define DOCEf_FILTER_SKIP       57
+#define DOCEf_NO_CLICK_ON       58
+#define DOCEf_DONT_DRAW         59 //only works on sprites
+#define DOCEf_DFT_LEN           60
+#define DOCEf_DFT_RAW_TYPE      61
+#define DOCEf_FLAGS_NUM         62
+
+public class CDocBin
+{
+  CDocBin *next,*last;
+  I32   tmp_use_cnt,renum_num;
+  U8    *tag;
+  U0    start;
+  U32   num,flags,size,use_cnt;
+  U0    end;
+  U8    *data;
+#assert !($&7)
+};
+
+#define DOC_SCROLL_SPEED        8
+
+#define DOCSS_NORMAL            0
+#define DOCSS_SINGLE_QUOTE      1
+#define DOCSS_DBL_QUOTE         2
+#define DOCSS_COMMENT           3
+#define DOCSS_CPP_Z_COMMENT     4
+
+#define DOC_ATTR_DFT_TEXT       WHITE<<4+BLACK
+#define DOC_COLOR_ALT_TEXT      LTGRAY
+#define DOC_COLOR_LINK          RED
+#define DOC_COLOR_MACRO         LTBLUE
+#define DOC_COLOR_ANCHOR        DKGRAY
+#define DOC_COLOR_TREE          PURPLE
+#define DOC_COLOR_PMT           GREEN
+#define DOC_COLOR_COMMENT       GREEN
+#define DOC_COLOR_BIN           LTGREEN
+#define DOC_COLOR_STR           BROWN
+#define DOC_COLOR_CHAR_CONST    BROWN
+#define DOC_COLOR_EXPORT_SYS_SYM LTPURPLE
+#define DOC_COLOR_DEFINE_STR    CYAN
+#define DOC_COLOR_GLBL_VAR      LTCYAN
+#define DOC_COLOR_CLASS         LTBLUE
+#define DOC_COLOR_FUN           PURPLE
+#define DOC_COLOR_KEYWORD       BLUE
+#define DOC_COLOR_REG           LTRED
+
+public class CDocSettings
+{
+  U32   final_u32_attr;
+  I16   left_margin,right_margin,indent;
+  U16   page_len,header,footer;
+  I8    shifted_x,shifted_y;
+  U8    state,comment_depth,paren_depth,brace_depth,
+        cur_text_attr,dft_text_attr;
+};
+
+#define DOC_DFT                 I32_MIN
+
+public class CDocEntryBase
+{
+//This is a shortened structure for
+  //cmds like the text cmd which
+  //don't require the full CDocEntry structure.
+  CDocEntryBase *next,*last;
+  U8    *tag;
+  union {
+    U8  type_u8; //this stores the code
+    U32 type; //these store attr flags
+  };
+  I32   page_line_num;
+  I64   de_flags;
+  I32   x,y;
+  U32   min_col,max_col;
+  CDocSettings settings;
+  I64   user_data;
+#assert !($&7)
+};
+
+#define DOCE_LEN_DFT    64
+
+public class CDocEntry:CDocEntryBase
+{
+  union {
+    I64 attr;
+    I64 cursor_x_offset;
+    I64 (*left_cb)(CDoc *doc,CDocEntry *doc_e);
+    I64 left_exp;
+  };
+  U8    *left_macro;
+
+  union {
+    I64 cursor_y_offset;
+    I64 (*right_cb)(CDoc *doc,CDocEntry *doc_e);
+    I64 right_exp;
+  };
+  U8    *right_macro;
+
+  U8    *(*tag_cb)(CDoc *doc,CDocEntry *doc_e,CTask *mem_task);
+  U8    *define_str,
+        *aux_str,
+        *bin_ptr_link,
+        *html_link,
+        *my_fmt_data;
+  I64   hex_ed_width;
+  I32   scroll_len,
+        len, //DOCE_LEN_DFT
+        bin_num;
+  U8    raw_type,pad[3];
+  CDocBin *bin_data;
+  U8    *data;
+#assert !($&7)
+};
+
+//DocForm() DocMenu() DocEd() PopUpMenu()
+#define DOF_SIZE_MIN            0x01
+#define DOF_INTERCEPT_TASK_END  0x02
+#define DOF_DONT_HOME           0x04
+#define DOF_WIN_MAX             0x08
+#define DOF_DONT_TEXT_ATTR      0x10
+#define DOF_DONT_WINMGR_SYNC    0x20
+#define DOF_DONT_SHOW           0x40
+//Combines with  Editor Flags
+
+class CEdFindText
+{
+  U8    find_text[STR_LEN] format "$DA-P,"
+        "A=\"Find        :%s\"$\n",
+        replace_text[STR_LEN] format "$DA-P,"
+        "A=\"Replace     :%s\"$\n";
+  Bool  replace                 format "$CB,\"Replace\"$\n",
+        scan_fwd                format "$CB,\"Fwd\"$\n",
+        scan_sel_text           format "$CB,\"Selection\"$\n",
+        match_case              format "$CB,\"Match Case\"$\n",
+        whole_labels            format "$CB,\"Whole Labels\"$\n",
+        local_var               format "$CB,\"Rename Local Var\"$\n",
+        pmt,pad;
+  I64   filter_lines            format "$DA,A=\"Filter Lines:%d\"$\n";
+};
+
+class CEdFileName
+{
+  CDirContext *dirc;
+  U8    name[256] format "$DA-P,LEN=255,A=\"FileName:%s\"$";
+};
+
+//Ed()
+#define EDF_BAIL                0x100
+#define EDF_COLLAPSE            0x200
+#define EDF_UNCOLLAPSE          0x400
+#define EDF_WAS_WRITE           0x800 //Was exit ESC or SHIFT_ESC?
+//Combines with Document Flags
+
+#define EDf_BAIL                8
+#define EDf_COLLAPSE            9
+#define EDf_UNCOLLAPSE          10
+#define EDf_WAS_WRITE           11
+
+// DOC header flags
+#define DOCF_PLAIN_TEXT         0x1
+#define DOCF_PLAIN_TEXT_TABS    0x2 //has '\t', not DOCT_TAB
+#define DOCF_AUTO_SAVE          0x4
+#define DOCF_NO_CURSOR          0x8
+#define DOCF_CARRIAGE_RETURN    0x10
+#define DOCF_DBL_DOLLARS        0x20
+#define DOCF_COLOR_NAMES        0x40
+//Reserved x1
+#define DOCF_BORDER_DOC         0x100
+#define DOCF_FORM               0x200
+#define DOCF_SIZE_MIN           0x400
+#define DOCF_HIDE_CURSOR        0x800  //use DocCursor
+#define DOCF_DONT_HIGHLIGHT_CURSOR 0x1000 //use DocHighlightCursor
+#define DOCF_NO_SCROLL_BARS     0x2000 //use DocScroll
+#define DOCF_ALLOW_UNDO         0x4000
+#define DOCF_DONT_SHOW          0x8000
+#define DOCF_HAS_SONG           0x10000
+#define DOCF_MORE               0x20000
+#define DOCF_BWD_MOVEMENT       0x40000
+#define DOCF_NULL_GRAB_SCROLL   0x80000
+#define DOCF_DONT_SWAP_OUT      0x100000
+#define DOCF_DO_FULL_REFRESH    0x200000
+#define DOCF_BREAK_UNLOCKED     0x400000
+//Reserved x1
+#define DOCF_HIGHLIGHT          DOCEF_HIGHLIGHT
+#define DOCF_WORD_WRAP          DOCEF_WORD_WRAP
+#define DOCF_BLINK              DOCEF_BLINK
+#define DOCF_INVERT             DOCEF_INVERT
+#define DOCF_SEL                DOCEF_SEL
+#define DOCF_UNDERLINE          DOCEF_UNDERLINE
+
+#define DOCF_OVERSTRIKE         0x100000000
+#define DOCF_IN_DOLLAR          0x200000000
+#define DOCF_SUPERSCRIPT_MODE   0x400000000
+#define DOCF_SUBSCRIPT_MODE     0x800000000
+#define DOCF_UNDO_DIRTY         0x1000000000
+
+#define DOCf_PLAIN_TEXT         0
+#define DOCf_PLAIN_TEXT_TABS    1 //has '\t', not DOCT_TAB
+#define DOCf_AUTO_SAVE          2
+#define DOCf_NO_CURSOR          3
+#define DOCf_CARRIAGE_RETURN    4
+#define DOCf_DBL_DOLLARS        5
+#define DOCf_COLOR_NAMES        6
+//Reserved x1
+#define DOCf_BORDER_DOC         8
+#define DOCf_FORM               9
+#define DOCf_SIZE_MIN           10
+#define DOCf_HIDE_CURSOR        11  //use DocCursor
+#define DOCf_DONT_HIGHLIGHT_CURSOR 12  //use DocHighlightCursor
+#define DOCf_NO_SCROLL_BARS     13  //use DocScroll
+#define DOCf_ALLOW_UNDO         14
+#define DOCf_DONT_SHOW          15
+#define DOCf_HAS_SONG           16
+#define DOCf_MORE               17
+#define DOCf_BWD_MOVEMENT       18
+#define DOCf_NULL_GRAB_SCROLL   19
+#define DOCf_DONT_SWAP_OUT      20
+#define DOCf_DO_FULL_REFRESH    21
+#define DOCf_BREAK_UNLOCKED     22
+//Reserved x1
+
+#define DOCf_HIGHLIGHT          DOCEf_HIGHLIGHT
+#define DOCf_WORD_WRAP          DOCEf_WORD_WRAP
+#define DOCf_BLINK              DOCEf_BLINK
+#define DOCf_INVERT             DOCEf_INVERT
+#define DOCf_SEL                DOCEf_SEL
+#define DOCf_UNDERLINE          DOCEf_UNDERLINE
+
+#define DOCf_OVERSTRIKE         32
+#define DOCf_IN_DOLLAR          33
+#define DOCf_SUPERSCRIPT_MODE   34
+#define DOCf_SUBSCRIPT_MODE     35
+#define DOCf_UNDO_DIRTY         36
+
+//locked flags
+#define DOClf_LOCKED            0
+class CDocUndo
+{
+  CDocUndo *next,*last;
+  I64   size,doc_flags,time_stamp;
+  U8    *body;
+};
+
+//See DocMenu()
+#define DOCM_CANCEL             (-1)
+
+#define DOC_SIGNATURE_VAL       'DocS'
+
+#define RECALCt_NORMAL          0x00
+#define RECALCt_FIND_CURSOR     0x01
+#define RECALCt_TO_SCRN         0x02
+#define RECALCG_MASK            0xFF
+
+#define RECALCF_HAS_CURSOR      0x100
+#define RECALCF_ADD_CURSOR      0x200
+#define RECALCF_TO_HTML         0x400
+
+public class CDoc //Linked Text File header
+{//See Doc for documentation.
+  CDocEntryBase head;
+  I64   flags,locked_flags;
+  CDocEntry *cur_entry,*old_cur_entry;
+  I32   cur_col,old_cur_col,
+        line_start_col,top_line_num,
+        dollar_buf_size,dollar_buf_ptr;
+  U8    *dollar_buf; //When entering $ cmds, it buffers them until the end $.
+
+  CTask *win_task,*mem_task,*owning_task;
+  I32   page_line_num,undo_cnt,
+        x,y,min_x,max_x,min_y,max_y;
+  I64   line,col,best_d,
+        old_win_top,old_win_bottom,
+        old_win_left,old_win_right,
+        cmd_U8;
+  U32   doc_signature,cur_bin_num;
+  I64   max_entries,
+        updates_cnt;
+  CEdFindText *find_replace;
+
+  CEdFileName filename;
+  I64   file_attr;
+  I64   (*left_click_link)(CDoc *doc,CDocEntry *doc_e);
+  I64   (*right_click_link)(CDoc *doc,CDocEntry *doc_e);
+
+  //See ::/Apps/Psalmody/JukeBox.HC
+  U8    *user_put_data; //Passed to user_put_key() and user_put_s()
+  Bool  (*user_put_key)(CDoc *doc,U8 *data,I64 ch,I64 sc);
+  Bool  (*user_put_s)(CDoc *doc,U8 *data,U8 *st);
+
+  CDoc  *parent_doc; //(When browsing deeper, opening deeper docs.)
+  U64   desc; //8 characters. See DocBorderLstDraw().
+
+  CDocBin bin_head;
+  CDocSettings settings_head;
+  CDocUndo undo_head;
+
+  I64   user_data;
+#assert !($&7)
+};
+
+#help_index "Windows"
+/*
+Fs->win_inhibit mask
+
+Some inhibit actions on the task itself.
+Some inhibit actions if the focus task
+tries to do something.
+*/
+#define WIF_SELF_FOCUS          0x0001 //If active this task cannot have focus
+                //MENU          0x0002
+#define WIF_SELF_CTRLS          0x0004
+#define WIF_SELF_MS_L           0x0008
+                //MS_L_D        0x0010
+#define WIF_SELF_MS_R           0x0020
+                //MS_R_D        0x0040
+#define WIF_SELF_MS_WHEEL       0x0080 //Does nothing, yet
+#define WIF_SELF_BORDER         0x0100
+#define WIF_SELF_GRAB_SCROLL    0x0200
+#define WIF_SELF_DOC            0x0400
+#define WIF_SELF_ODE            0x0800
+#define WIF_SELF_KEY_DESC       0x1000
+                //FOCUS         0x00010000
+#define WIF_FOCUS_TASK_MENU     0x00020000
+#define WIF_FOCUS_TASK_CTRLS    0x00040000
+#define WIF_FOCUS_TASK_MS_L     0x00080000
+#define WIF_FOCUS_TASK_MS_L_D   0x00100000
+#define WIF_FOCUS_TASK_MS_R     0x00200000
+#define WIF_FOCUS_TASK_MS_R_D   0x00400000
+#define WIF_FOCUS_TASK_MS_WHEEL 0x00800000 //Does nothing, yet
+#define WIF_FOCUS_TASK_BORDER   0x01000000
+#define WIF_FOCUS_TASK_GRAB_SCROLL 0x02000000
+
+#define WIG_DBL_CLICK           (WIF_FOCUS_TASK_MS_L_D|WIF_FOCUS_TASK_MS_R_D)
+#define WIG_TASK_DFT            (WIF_FOCUS_TASK_MENU|WIG_DBL_CLICK|\
+        0xFFFF-WIF_SELF_DOC-WIF_SELF_ODE)
+#define WIG_NO_FOCUS_TASK_DFT   (WIG_TASK_DFT-WIF_SELF_BORDER\
+        -WIF_SELF_MS_L-WIF_SELF_MS_R-WIG_DBL_CLICK)
+#define WIG_USER_TASK_DFT       WIF_SELF_KEY_DESC
+
+#define WIf_SELF_FOCUS          0
+#define WIf_SELF_CTRLS          2
+#define WIf_SELF_MS_L           3
+#define WIf_SELF_MS_R           5
+#define WIf_SELF_MS_WHEEL       7
+#define WIf_SELF_BORDER         8
+#define WIf_SELF_GRAB_SCROLL    9
+#define WIf_SELF_DOC            10
+#define WIf_SELF_ODE            11
+#define WIf_SELF_KEY_DESC       12
+#define WIf_FOCUS_TASK_MENU     17
+#define WIf_FOCUS_TASK_CTRLS    18
+#define WIf_FOCUS_TASK_MS_L     19
+#define WIf_FOCUS_TASK_MS_L_D   20
+#define WIf_FOCUS_TASK_MS_R     21
+#define WIf_FOCUS_TASK_MS_R_D   22
+#define WIf_FOCUS_TASK_MS_WHEEL 23
+#define WIf_FOCUS_TASK_BORDER   24
+#define WIf_FOCUS_TASK_GRAB_SCROLL 25
+
+class CWinMgrTimingGlbls
+{
+  I64   last_total_jiffies,
+        last_idle_pt_hits[MP_PROCESSORS_NUM],
+        last_swap_cnter[MP_PROCESSORS_NUM];
+  F64   last_calc_idle_time,calc_idle_delta_time;
+  I64   calc_idle_cnt;
+};
+
+#define WINMGR_FPS      (30000.0/1001)
+#define WINMGR_PERIOD   (1001/30000.0)
+
+public class CWinMgrGlbls
+{
+  I64   updates;
+  F64   ode_time,
+        last_ode_time,
+        fps,            //You can read but not write this. You have no control.
+        ideal_refresh_tS,
+        last_refresh_tS;
+  CWinMgrTimingGlbls *t;
+  Bool  show_menu,grab_scroll,grab_scroll_closed;
+};
+
+#help_index "AutoComplete"
+#define ACf_INIT_IN_PROGRESS    0
+#define AC_FILLINS_NUM 10
+public class CAutoCompleteGlbls
+{
+  I64   num_words;
+  CHashTable *hash_table;
+  U8    *cur_word;
+  I64   flags;
+  CTask *task;
+  I64   partial_len,num_fillins,
+        fillin_hits     [AC_FILLINS_NUM+1];
+  CHashAC *fillin_matches[AC_FILLINS_NUM+1];
+};
+
+#help_index "AutoComplete/Dictionary"
+#define ACD_WORD_FILENAME       "/Adam/AutoComplete/ACWords.DATA.Z"
+#define ACD_DEF_FILENAME        "/Adam/AutoComplete/ACDefs.DATA"
+#define ACD_DEF_FILENAME_Z      "/Adam/AutoComplete/ACDefs.DATA.Z"
+
+#define ACD_H1                  0
+#define ACD_H1_END              1
+#define ACD_DEF                 2
+#define ACD_DEF_END             3
+#define ACD_PRONUNCIATION       4
+#define ACD_PRONUNCIATION_END   5
+#define ACD_POS                 6
+#define ACD_POS_END             7
+#define ACD_EXTRA               8
+#define ACD_EXTRA_END           9
+#define ACD_BLK_SIZE            0x4000
+
+#define ACD_END_CHAR            0x00
+#define ACD_WORD_CHAR           0x01
+#define ACD_DEF_CHAR            0x02
+#define ACD_PRONUNCIATION_CHAR  0x03
+#define ACD_POS_CHAR            0x04
+#define ACD_EXTRA_CHAR          0x05
+
+#define ACD_FILLINS_NUM 10
+public class CAutoCompleteDictGlbls
+{
+  U8    *word_lst;
+  I64   word_lst_size,num_words,num_fillins;
+  U8    *fillins[ACD_FILLINS_NUM];
+  Bool  has_words,has_defs;
+};
+
+#help_index "Compiler/Directive"
+//Compiler Option()s
+//You might need to do #exe {Option();}
+//Note: The #exe stmt is lexed-ahead,
+//so it takes effect earlier than you might expect.
+#define OPTf_ECHO               0x00
+#define OPTf_TRACE              0x01
+#define OPTf_WARN_UNUSED_VAR    0x10 //Applied to funs, not stmts
+#define OPTf_WARN_PAREN         0x11 //Warn unnecessary parens
+#define OPTf_WARN_DUP_TYPES     0x12 //Warn dup local var type stmts
+#define OPTf_WARN_HEADER_MISMATCH 0x13
+#define OPTf_EXTERNS_TO_IMPORTS 0x20
+#define OPTf_KEEP_PRIVATE       0x21
+#define OPTf_NO_REG_VAR         0x22  //Applied to funs, not stmts
+#define OPTf_GLBLS_ON_DATA_HEAP 0x23
+//Disable 10-byte float consts for pi,log2_10,log10_2,loge_2
+#define OPTf_NO_BUILTIN_CONST   0x24 //Applied to funs, not stmts
+#define OPTf_USE_IMM64          0x25 //Not completely implemented
+
+#define OPTF_ECHO               (1<<OPTf_ECHO)
+
+#help_index "Compiler/Intermediate Code"
+//See ST_RAW_TYPES
+#define RT_I0           2
+#define RT_U0           3
+#define RT_I8           4
+#define RT_U8           5
+#define RT_I16          6
+#define RT_U16          7
+#define RT_I32          8
+#define RT_U32          9
+#define RT_I64          10
+#define RT_PTR          10 //Signed to allow negative err codes. DOCM_CANCEL
+#define RT_U64          11
+#define RT_F32          12 //Not implemented
+#define RT_UF32         13 //Not implemented, Fictitious
+#define RT_F64          14
+#define RT_UF64         15 //Fictitious
+#define RT_RTS_NUM      16
+#define RTF_UNSIGNED    1
+#define RTG_MASK        0xFF
+
+#define MDf_STK         8
+#define MDf_IMM         9
+#define MDf_REG         10
+#define MDf_DISP        11
+#define MDf_SIB         12
+#define MDf_RIP_DISP32  13
+
+#define MDF_NULL        0x0000
+#define MDF_STK         0x0100
+#define MDF_IMM         0x0200
+#define MDF_REG         0x0400
+#define MDF_DISP        0x0800
+#define MDF_SIB         0x1000
+#define MDF_RIP_DISP32  0x2000
+#define MDG_MASK        0xFF00
+#define MDG_REG_DISP_SIB        (MDF_REG|MDF_DISP|MDF_SIB)
+#define MDG_DISP_SIB_RIP        (MDF_DISP|MDF_SIB|MDF_RIP_DISP32)
+#define MDG_REG_DISP_SIB_RIP    (MDF_REG|MDG_DISP_SIB_RIP)
+
+#define ICF_RES_TO_F64                  0x000000001
+#define ICF_RES_TO_INT                  0x000000002
+#define ICF_ARG1_TO_F64                 0x000000004
+#define ICF_ARG1_TO_INT                 0x000000008
+#define ICF_ARG2_TO_F64                 0x000000010
+#define ICF_ARG2_TO_INT                 0x000000020
+#define ICF_USE_F64                     0x000000040
+#define ICF_USE_UNSIGNED                0x000000080
+#define ICF_USE_INT                     0x000000100 //highest priority
+#define ICF_RES_NOT_USED                0x000000200
+#define ICF_CODE_FINAL                  0x000000400
+#define ICF_BY_VAL                      0x000000800 //By value, not ref.
+#define ICF_SHORT_JMP                   0x000001000
+#define ICF_PUSH_RES                    0x000002000
+#define ICF_PASS_TRACE                  0x000004000
+#define ICF_RES_WAS_STK                 0x000008000
+#define ICF_ARG1_WAS_STK                0x000010000
+#define ICF_ARG2_WAS_STK                0x000020000
+#define ICF_PUSH_CMP                    0x000040000 //for 50<i<j<=100 exps
+#define ICF_POP_CMP                     0x000080000 //for 50<i<j<=100 exps
+#define ICF_SWAP                        0x000100000
+#define ICf_DONT_PUSH_FLOAT0            21 // 3bits
+#define ICf_DONT_POP_FLOAT0             24 // 3bits
+#define ICF_ALT_TEMPLATE                0x008000000
+#define ICF_LOCK                        0x010000000
+#define ICf_LOCK                        28
+#define ICF_NO_RIP                      0x020000000
+#define ICF_DEL_PREV_INS                0x040000000
+#define ICF_PREV_DELETED                0x080000000
+#define ICF_DONT_RESTORE                0x100000000
+#define ICG_NO_CVT_MASK                 0x1FFFFFF00
+
+#define IC_BODY_SIZE                    0x83
+
+#define ECF_HAS_PUSH_CMP                0x01 //for 50<i<j<=100 exps
+
+U16 class CICType
+{
+  U8    raw_type,mode;
+};
+
+class CICArg
+{
+  CICType type;
+  U16   reg; //low is reg, high is index_reg+scale<<6
+  I64   disp;
+};
+
+class CICTreeLinks
+{
+  CHashClass *arg1_class,*arg2_class;
+  CIntermediateCode *arg1_tree,*arg2_tree;
+  CHashClass *class2;
+};
+
+class CIntermediateCodeBase
+{
+  CIntermediateCode *next,*last;
+  U16   ic_code,
+        ic_precedence;
+  I16   ic_cnt,
+        ic_last_start;
+};
+
+class CIntermediateCode:CIntermediateCodeBase
+{
+  I64   ic_flags,
+        ic_data,
+        ic_line;
+  CHashClass *ic_class,*ic_class2;
+  CICArg arg1,arg2,res;
+  U8    arg1_type_pointed_to; //Used for IST_ASSIGN and IST_DEREF ic_codes.
+  union {
+    U8 ic_body[IC_BODY_SIZE];
+    //Tree Links are created in OptPass012.  An ADD opcode, for example,
+    //points back to its two earlier arg CIntermediateCode's.
+
+    //Tree links get destroyed during Pass789A when they get overwrites
+    //by machine code.  (Saves room to union the output machine code buffer
+    //with these links, since they are not needed after pass4.
+
+    //Tree links are used during passes 012 and 3 for determining types.
+    CICTreeLinks t;
+  };
+#assert !($&7)
+};
+
+class CPrsStk
+{
+  I64   ptr,
+        stk[255],
+        ptr2,
+        stk2[255];
+};
+
+#define CMT_LABEL               0
+#define CMT_ASM_LABEL           1
+#define CMT_GOTO_LABEL          2
+#define CMT_STR_CONST           3
+#define CMT_JMP_TABLE           4
+#define CMT_FLOAT_CONSTS        5
+#define CMT_ARRAY_DIM           6
+#define CMT_HASH_ENTRY          7
+
+#define CMF_POP_CMP             0x01
+#define CMF_DEFINED             0x02
+#define CMF_I8_JMP_TABLE        0x04
+#define CMF_U8_JMP_TABLE        0x08
+#define CMF_I16_JMP_TABLE       0x10
+#define CMF_U16_JMP_TABLE       0x20
+
+#define CM_CONSTS_NUM           16
+
+class CCodeMisc
+{
+  CCodeMisc *next,*last,*fwd,*dft,*begin;
+  U8    *str;
+  U32   type,flags;
+  I64   use_cnt;
+  U8    *addr;
+  union {
+    I64 st_len;         //STR_CONST
+    I64 num_consts;     //FLOAT_CONSTS
+    I64 range;
+    I64 rip;            //ASM_LABEL
+  }
+  union {
+    CCodeMisc **jmp_table;
+    F64 *float_consts;
+    CArrayDim *dim;
+    CHash *h;
+  };
+};
+
+#help_index "Compiler/Assembler"
+#define IEF_OP_SIZE16           0x001
+#define IEF_OP_SIZE32           0x002
+#define IEF_PLUS_OPCODE         0x004
+#define IEF_DONT_SWITCH_MODES   0x008
+#define IEF_DFT                 0x010
+#define IEF_NOT_IN_64_BIT       0x020
+#define IEF_48_REX              0x040
+#define IEF_REX_ONLY_R8_R15     0x080
+#define IEF_REX_XOR_LIKE        0x100
+#define IEF_STI_LIKE            0x200
+#define IEF_ENDING_ZERO         0x400
+
+//Slash value
+#define SV_R_REG        8
+#define SV_I_REG        9
+#define SV_STI_LIKE     10 //uasm_slash_val only.
+#define SV_NONE         11
+class CInst
+{
+  U8    ins_entry_num, //This entry num in opcode hash entry
+        opcode_cnt,
+        opcode[4];
+  U16   flags;
+  U8    slash_val,uasm_slash_val,opcode_modifier,
+        arg1,arg2,
+        size1,size2,//Size in bits
+        pad;
+};
+
+//x86 opcodes
+#define OC_OP_SIZE_PREFIX       0x66
+#define OC_ADDR_SIZE_PREFIX     0x67
+#define OC_LOCK_PREFIX          0xF0
+#define OC_NOP                  0x90
+#define OC_BPT                  0xCC
+#define OC_CALL                 0xE8
+#define OC_JMP_REL8             0xEB
+#define OC_NOP2                 (OC_NOP<<8+OC_OP_SIZE_PREFIX)
+
+#define PUSH_C_REGS PUSH RAX PUSH RCX PUSH RDX PUSH RBX PUSH R8 PUSH R9
+#define POP_C_REGS POP R9 POP R8 POP RBX POP RDX POP RCX POP RAX
+
+#define PUSH_REGS PUSH RAX PUSH RCX PUSH RDX PUSH RBX PUSH RBP PUSH RSI \
+PUSH RDI PUSH R8 PUSH R9 PUSH R10 PUSH R11 PUSH R12 PUSH R13 PUSH R14 PUSH R15
+#define POP_REGS POP R15 POP R14 POP R13 POP R12 POP R11 POP R10 POP R9 \
+POP R8 POP RDI POP RSI POP RBP POP RBX POP RDX POP RCX POP RAX
+
+#define REG_RAX         0
+#define REG_RCX         1
+#define REG_RDX         2
+#define REG_RBX         3
+#define REG_RSP         4
+#define REG_RBP         5
+#define REG_RSI         6
+#define REG_RDI         7
+#define REG_R8          8
+#define REG_REGS_NUM    16
+
+#define REG_RIP         16      //Used by compiler, not really it's num
+//Be careful: RBPu8, RSPu8, RSIu8, RDIu8 are 20-24
+#define REG_NONE        32      //noreg flag sets it to this
+#define REG_ALLOC       33      //reg flag sets it to this
+#define REG_UNDEF       I8_MIN
+
+#define REGG_CLOBBERED          0x013F //RAX,RCX,RDX,RBX,R8
+#define REGG_SAVED              0x0030 //RBP,RSP
+#define REGG_STK_TMP            0x0200 //R9
+#define REGG_LOCAL_VARS         0xCCC0 //RSI,RDI,R10,R11,R14,R15
+#define REGG_LOCAL_NON_PTR_VARS 0x3000 //R12,R13
+
+#define AOT_BIN_BLK_BITS 16
+#define AOT_BIN_BLK_SIZE (1<<AOT_BIN_BLK_BITS)
+
+class CAOTBinBlk
+{
+  CAOTBinBlk *next;
+  U8    body[AOT_BIN_BLK_SIZE];
+};
+
+I64 class CAbsCntsI64
+{
+  U16   abs_addres, //Only odd/even matters. Cnt of absolute addres in an exp.
+        c_addres; //Only odd/even matters. Cnt of C addres in an exp.
+  U32   externs; //Only nonzero matters. Some regions have externs banned.
+};
+
+class CAsmUndefHash
+{//Only place created is Exp Parser when an undef is found in an ASM exp.
+  CAsmUndefHash *next;
+  CHashExport   *hash;
+};
+
+class CAsmNum
+{
+  I64   i;
+  U8    *machine_code;
+  CAsmUndefHash *local_asm_undef_hash,*glbl_asm_undef_hash;
+  CAbsCntsI64 abs_cnts;
+};
+
+class CAsmNum2
+{
+  CAsmNum num;
+  I64   U8_cnt,rel;
+  Bool  imm_flag;
+};
+
+class CAsmIns
+{
+  CInst *tmpins;
+  CAsmNum2 imm,disp;
+  I64   U8_cnt,last_opcode_U8,
+        REX,ModrM,SIB;
+  Bool  has_REX,has_ModrM,has_SIB,
+        has_addr_prefix,
+        has_operand_prefix,
+        is_dft,pad[2];
+};
+
+class CAsmArg
+{
+  CAsmNum num;
+  I64   seg,size, //Size in bytes
+        reg1,reg2,
+        reg1_type,reg2_type,
+        scale;
+  Bool  indirect,imm_or_off_present,just_seg,pad[5];
+};
+
+class CAsmUnresolvedRef
+{
+  CAsmUnresolvedRef *next;
+  I64   type,line_num;
+  U8    *machine_code;
+  I64   rip,rel_rip;
+  CAOT  *aot;
+  U8    *str;   //Only for import glbls
+  CAsmUndefHash *asm_undef_hash;
+  Bool  U8_avail,
+        imm_flag;//Only for import glbls
+};
+
+//Opcode Modifier
+#define OM_NO 0
+#define OM_CB 1
+#define OM_CW 2
+#define OM_CD 3
+#define OM_CP 4
+#define OM_IB 5
+#define OM_IW 6
+#define OM_ID 7
+
+#define ARGT_NONE       0
+#define ARGT_REL8       1
+#define ARGT_REL16      2
+#define ARGT_REL32      3
+
+#define ARGT_IMM8       4
+#define ARGT_IMM16      5
+#define ARGT_IMM32      6
+#define ARGT_IMM64      7
+
+#define ARGT_UIMM8      8
+#define ARGT_UIMM16     9
+#define ARGT_UIMM32     10
+#define ARGT_UIMM64     11
+
+#define ARGT_R8         12
+#define ARGT_R16        13
+#define ARGT_R32        14
+#define ARGT_R64        15
+
+#define ARGT_RM8        16
+#define ARGT_RM16       17
+#define ARGT_RM32       18
+#define ARGT_RM64       19
+
+#define ARGT_M8         20
+#define ARGT_M16        21
+#define ARGT_M32        22
+#define ARGT_M64        23
+
+#define ARGT_M1632      24 // Not implemented
+#define ARGT_M16N32     25 // Not implemented
+#define ARGT_M16N16     26 // Not implemented
+#define ARGT_M32N32     27 // Not implemented
+
+#define ARGT_MOFFS8     28
+#define ARGT_MOFFS16    29
+#define ARGT_MOFFS32    30
+#define ARGT_MOFFS64    31
+
+#define ARGT_AL         32
+#define ARGT_AX         33
+#define ARGT_EAX        34
+#define ARGT_RAX        35
+
+#define ARGT_CL         36
+#define ARGT_DX         37
+#define ARGT_SREG       39
+
+#define ARGT_SS         40
+#define ARGT_DS         41
+#define ARGT_ES         42
+#define ARGT_FS         43
+
+#define ARGT_GS         44
+#define ARGT_CS         45
+#define ARGT_ST0        46
+#define ARGT_STI        47
+
+#define ARGT_MM         48 // Not implemented
+#define ARGT_MM32       49 // Not implemented
+#define ARGT_MM64       50 // Not implemented
+#define ARGT_XMM        51 // Not implemented
+
+#define ARGT_XMM32      52 // Not implemented
+#define ARGT_XMM64      53 // Not implemented
+#define ARGT_XMM128     54 // Not implemented
+#define ARGT_XMM0       55 // Not implemented
+
+#help_index "Compiler/Internal;Hash/System"
+#define OCF_ALIAS       1
+public class CHashOpcode:CHash
+{
+  U16   inst_entry_cnt,
+        oc_flags,pad[2];
+  CInst ins[1];
+};
+
+#help_index "Compiler/Intermediate Code"
+#define IEF_GOTO_LABEL          1
+class CAOTImportExport
+{
+  CAOTImportExport *next,*last;
+  I64   rip,flags;
+  CAOT  *aot;
+  U8    *str,
+        *src_link,
+        type,pad[7];
+};
+
+#define AAT_ADD_U8              0
+#define AAT_SUB_U8              1
+#define AAT_ADD_U16             2
+#define AAT_SUB_U16             3
+#define AAT_ADD_U32             4
+#define AAT_SUB_U32             5
+#define AAT_ADD_U64             6
+#define AAT_SUB_U64             7
+class CAOTAbsAddr
+{
+  CAOTAbsAddr *next;
+  I64   rip;
+  U8    type,pad[7];
+};
+
+class CAOTHeapGlblRef
+{
+  CAOTHeapGlblRef *next;
+  I64   rip;
+};
+
+class CAOTHeapGlbl
+{
+  CAOTHeapGlbl *next;
+  U8    *str;
+  I64   size;
+  CAOTHeapGlblRef *references;
+};
+
+class CAOT
+{
+  CAOT  *next,*last;
+  U8    *buf;
+  I64   rip,rip2,
+        aot_U8s,
+        max_align_bits,org;
+  CAOT  *parent_aot;
+  CAOTImportExport *next_ie,*last_ie;
+  CAOTAbsAddr *abss;
+  CAOTHeapGlbl *heap_glbls;
+};
+
+class CStreamBlk
+{
+  CStreamBlk *next,*last;
+  U8    *body;
+};
+
+class CCodeCtrl
+{
+  CCodeCtrl *coc_next;
+  CCodeMisc *coc_next_misc,*coc_last_misc;
+  CIntermediateCodeBase coc_head;
+};
+
+#help_index "Compiler/Lex"
+#define __DATE__ #exe{StreamPrint("\"%D\"",Now);}
+#define __TIME__ #exe{StreamPrint("\"%T\"",Now);}
+#define __LINE__ #exe{StreamPrint("%d",\
+        Fs->last_cc->lex_include_stk->line_num);}
+#define __CMD_LINE__ #exe{StreamPrint("%d",Fs->last_cc->flags&CCF_CMD_LINE &&\
+        Fs->last_cc->lex_include_stk->depth<1);}
+#define __FILE__ #exe{StreamPrint("\"%s\"",\
+        Fs->last_cc->lex_include_stk->full_name);}
+#define __DIR__  #exe{StreamDir;}
+
+#define LFSF_DOC        1
+#define LFSF_DEFINE     2
+class CLexFile
+{
+  CLexFile *next;
+  U8    *buf,
+        *buf_ptr;
+  I64   line_num,flags;
+  U8    *full_name,
+        *line_start;
+  CDoc  *doc;
+  CDocEntry *cur_entry;
+  I32   depth;
+  U8    last_U16,pad[3];
+};
+
+class CAOTCtrl
+{
+  I64   rip; //Inst ptr
+  CAsmArg arg1,arg2;
+  CAOTBinBlk *bin;
+  I64   num_bin_U8s,
+        max_align_bits,org;
+  CAsmUnresolvedRef *local_unresolved,*glbl_unresolved;
+  CAOTAbsAddr *abss;
+  CAOTHeapGlbl *heap_glbls;
+  I64   lst_col,lst_last_rip;
+  U8    *last_label,*lst_last_line;
+  CLexFile *lst_last_lfn;
+  I64   seg_size;
+  Bool  lst;
+};
+
+//Tokens
+#define TK_EOF          0
+#define TK_SUPERSCRIPT  0x001
+#define TK_SUBSCRIPT    0x002
+#define TK_NORMALSCRIPT 0x003
+#define TK_IDENT        0x100
+#define TK_STR          0x101
+#define TK_I64          0x102
+#define TK_CHAR_CONST   0x103
+#define TK_F64          0x104
+#define TK_PLUS_PLUS    0x105
+#define TK_MINUS_MINUS  0x106
+#define TK_DEREFERENCE  0x107
+#define TK_DBL_COLON    0x108
+#define TK_SHL          0x109
+#define TK_SHR          0x10A
+#define TK_EQU_EQU      0x10B
+#define TK_NOT_EQU      0x10C
+#define TK_LESS_EQU     0x10D
+#define TK_GREATER_EQU  0x10E
+#define TK_AND_AND      0x10F
+#define TK_OR_OR        0x110
+#define TK_XOR_XOR      0x111
+#define TK_SHL_EQU      0x112
+#define TK_SHR_EQU      0x113
+#define TK_MUL_EQU      0x114
+#define TK_DIV_EQU      0x115
+#define TK_AND_EQU      0x116
+#define TK_OR_EQU       0x117
+#define TK_XOR_EQU      0x118
+#define TK_ADD_EQU      0x119
+#define TK_SUB_EQU      0x11A
+#define TK_IF           0x11B
+#define TK_IFDEF        0x11C
+#define TK_IFNDEF       0x11D
+#define TK_IFAOT        0x11E
+#define TK_IFJIT        0x11F
+#define TK_ENDIF        0x120
+#define TK_ELSE         0x121
+#define TK_MOD_EQU      0x122
+#define TK_DOT_DOT      0x123
+#define TK_ELLIPSIS     0x124
+#define TK_INS_BIN      0x125
+#define TK_INS_BIN_SIZE 0x126
+#define TK_TKS_NUM      0x127
+
+class CLexHashTableContext
+{
+  CLexHashTableContext *next;
+  I64   old_flags,hash_mask;
+  CHashFun *local_var_lst,
+        *fun;
+  CHashTable *hash_table_lst,
+        *define_hash_table,
+        *local_hash_table,
+        *glbl_hash_table;
+};
+
+//CmpCtrl flags
+#define CCF_CMD_LINE            0x001
+#define CCF_PMT                 0x002
+#define CCf_PMT                 1
+#define CCF_QUESTION_HELP       0x004
+#define CCF_DONT_FREE_BUF       0x008
+#define CCF_NO_DEFINES          0x010
+#define CCF_IN_IF               0x020
+#define CCF_JUST_LOAD           0x040
+#define CCF_KEEP_NEW_LINES      0x080
+#define CCF_KEEP_DOT            0x100
+#define CCF_KEEP_SIGN_NUM       0x200
+#define CCF_KEEP_AT_SIGN        0x400
+#define CCF_NO_CHAR_CONST       0x800
+#define CCf_PASS_TRACE_PRESENT  12
+#define CCF_NOT_CONST           0x0000020000
+#define CCF_NO_REG_OPT          0x0000040000
+#define CCF_IN_QUOTES           0x0000080000
+#define CCF_EXE_BLK             0x0000100000
+#define CCF_HAS_MISC_DATA       0x0000200000
+#define CCF_HAS_RETURN          0x0000400000
+#define CCF_ASM_EXPRESSIONS     0x0000800000
+#define CCF_UNRESOLVED          0x0001000000
+#define CCF_LOCAL               0x0002000000
+#define CCF_FUN_EXP             0x0004000000
+#define CCf_FUN_EXP             26
+#define CCF_POSTINC             0x0008000000
+#define CCF_POSTDEC             0x0010000000
+#define CCF_PREINC              0x0020000000
+#define CCF_PREDEC              0x0040000000
+#define CCF_ARRAY               0x0080000000
+#define CCF_RAX                 0x0100000000
+#define CCF_USE_LAST_U16        0x0200000000
+#define CCf_USE_LAST_U16        33
+#define CCF_LAST_WAS_DOT        0x0400000000
+#define CCF_AOT_COMPILE         0x0800000000
+#define CCf_AOT_COMPILE         35
+#define CCF_NO_ABSS             0x1000000000
+#define CCF_PAREN               0x2000000000
+#define CCf_PAREN               37
+#define CCF_CLASS_DOL_OFFSET    0x4000000000
+#define CCF_DONT_MAKE_RES       0x8000000000
+
+public class CCmpCtrl
+{
+  CCmpCtrl *next,*last;
+  I64   token,
+        flags,
+        cur_i64;
+  F64   cur_f64;
+  U8    *cur_str;
+  I64   cur_str_len,
+        class_dol_offset;
+  U8    *dollar_buf;
+  I64   dollar_cnt;
+  U8    *cur_help_idx;
+  I64   last_U16,
+        min_line,max_line,last_line_num,
+        lock_cnt;
+  U32   *char_bmp_alpha_numeric;
+  CLexHashTableContext htc;
+  CHashGeneric *hash_entry;
+  CAbsCntsI64 abs_cnts;
+  CAsmUndefHash *asm_undef_hash;
+  CMemberLst *local_var_entry;
+  CCodeMisc *lb_leave;
+  U8    *cur_buf_ptr;
+  CLexFile *lex_include_stk,
+        *lex_prs_stk,
+        *fun_lex_file;
+  CStreamBlk *next_stream_blk,*last_stream_blk;
+  CAOT  *aot;
+
+  I64   pass,opts,pass_trace,saved_pass_trace,
+        error_cnt,warning_cnt;
+
+  //For intermediate codes with multiple float ops (int<->float conversions)
+  I64   cur_ic_float_op_num,last_ic_float_op_num;
+  CIntermediateCode *last_float_op_ic;
+  Bool  last_dont_pushable,last_dont_popable,last_float_op_pos,
+        dont_push_float,pad[4];
+
+  CCodeCtrl coc;
+  CPrsStk *ps;
+  CAOTCtrl *aotc;
+  I64   aot_depth,pmt_line;
+#assert !($&7)
+};
+
+#help_index "Compiler"
+public class CCmpGlbls
+{
+  CHashTable *asm_hash;
+  CHashClass *internal_types[RT_RTS_NUM];
+  CIntermediateCode ic_nop;
+  U32   *dual_U16_tokens1,*dual_U16_tokens2,*dual_U16_tokens3,
+        *binary_ops;
+  I64   num_reg_vars,num_non_ptr_vars,
+        stk_tmps_mask,reg_vars_mask,non_ptr_vars_mask;
+  U8    *to_reg_vars_map,*non_ptr_vars_map;
+  I64   size_arg_mask[9],
+        compiled_lines;
+};
+
+#help_index "Debugging/Unassemble"
+class CUAsmGlbls
+{
+  CInst **table_16_32,**table_64;
+  I64   table_16_32_entries,
+        table_64_entries,
+        ins64_arg_mask,
+        signed_arg_mask,
+        mem_arg_mask;
+};
+
+#help_index "Devices;PCI"
+class CPCIDev
+{
+  CPCIDev *next,*last;
+  U16   vendor,dev_id;
+  U8    bus,dev,fun,pad,
+        sub_code,base_code,pad[6],
+        *vendor_str,*dev_id_str;
+};
+
+#help_index "Devices;File/System;PCI"
+public class CATARep
+{
+  CATARep *next;
+  I64   num,type,base0,base1,unit,irq;
+};
+
+//See ::/Doc/Credits.DD.
+#define ATA_NOP                 0x00
+#define ATA_DEV_RST             0x08
+#define ATA_PACKET              0xA0
+#define ATA_READ_NATIVE_MAX     0xF8
+#define ATA_READ_NATIVE_MAX_EXT 0x27
+#define ATA_SET_MAX             0xF9
+#define ATA_SET_MAX_EXT         0x37
+#define ATA_READ_MULTI          0xC4
+#define ATA_READ_MULTI_EXT      0x29
+#define ATA_WRITE_MULTI         0xC5
+#define ATA_WRITE_MULTI_EXT     0x39
+#define ATA_ID_DEV              0xEC
+
+#define ATAS_ERR        0x01
+#define ATAS_DRQ        0x08
+#define ATAS_DF         0x20
+#define ATAS_DRDY       0x40
+#define ATAS_BSY        0x80
+
+#define ATAR0_DATA      0
+#define ATAR0_FEAT      1
+#define ATAR0_NSECT     2
+#define ATAR0_SECT      3
+#define ATAR0_LCYL      4
+#define ATAR0_HCYL      5
+#define ATAR0_SEL       6
+#define ATAR0_STAT      7
+#define ATAR0_CMD       7
+#define ATAR1_CTRL      2
+
+#help_index "File/FileNames"
+#define FILEMASK_JIT    "*.HC*;*.HH*"
+#define FILEMASK_AOT    "*.HC*;*.HH*;*.PRJ*"
+#define FILEMASK_SRC    "*.HC*;*.HH*;*.IN*;*.PRJ*"
+#define FILEMASK_DD     FILEMASK_SRC ";*.DD*"
+#define FILEMASK_TXT    FILEMASK_DD ";*.TXT*"
+#define FILEMASK_GR     "*.GR*"
+
+#help_index "File/Low Level"
+#define BLK_SIZE_BITS   9
+#define BLK_SIZE        (1<<BLK_SIZE_BITS)
+#define DVD_BLK_SIZE    (4*BLK_SIZE)
+#define DVD_BOOT_LOADER_SIZE    DVD_BLK_SIZE*1
+#define INVALID_CLUS (-1)
+
+class CMBRPrt
+{
+  U8    active, //0x80=active  0x00=inactive
+        start_head;
+  U16   start_cyl;
+  U8    type,
+        end_head;
+  U16   end_cyl;
+  U32   offset, //Sects between MBR and first sect
+        size;   //Sects in drv
+};
+
+class CMasterBoot
+{
+  U8    code[440];
+  U32   media_id;
+  U16   zero;
+  CMBRPrt p[4];
+  U16   signature; //AA55
+};
+
+class CRedSeaBoot
+{
+  U8    jump_and_nop[3],
+        signature,reserved[4]; //MBR_PT_REDSEA=0x88. Distinguish from real FAT32
+  I64   drv_offset,     //For CD/DVD image copy.
+        sects,
+        root_clus,
+        bitmap_sects,
+        unique_id;
+  U8    code[462];
+  U16   signature2;     //0xAA55
+};
+
+class CFAT32Boot
+{
+  U8    jump_and_nop[3],
+        oem_name[8];
+  U16   bytes_per_sect;
+  U8    sects_per_clus;
+  U16   reserved_sects;
+  U8    copies_of_fat;
+  U16   max_root_dir_entries,   //Not used
+        old_sects_in_drv;       //Not used
+  U8    media_desc;             //F64 for hard disk
+  U16   old_sects_per_fat,      //Not used
+        sects_per_track,
+        num_heads;
+  U32   hidden_sects,
+        sects,
+        sects_per_fat;
+  U16   flags,
+        version;
+  U32   root_clus;
+  U16   file_system_info_sect,
+        backup_boot_sect;
+  U8    reserved[12],
+        log_drv_num,
+        unused,
+        ext_signature; //0x29
+  U32   serial_num;
+  U8    vol_name[11],
+        fat_name[8],
+        code[420];
+  U16   signature;
+};
+
+class CFAT32FileInfoSect
+{
+  U32   signature1;
+  U8    unknown[480];
+  U32   signature2,
+        free_clus,
+        most_recently_alloced;
+  U8    reserved[12];
+  U32   signature3;
+};
+
+class CFAT32DirEntry
+{
+  U8    name[11],
+        attr,
+        NTres,
+        CrtTimeTenth;
+  U16   CrtTime,
+        CrtDate,
+        LstAccDate,
+        clus_hi,
+        WrtTime,
+        WrtDate,
+        clus_lo;
+  U32   size;
+};
+
+class CFAT32DirEntryLong
+{
+  U8    ord;
+  U16   name1[5];
+  U8    attr,
+        type,
+        xsum;
+  U16   name2[6],
+        zero,
+        name3[2];
+};
+
+#define FAT32_ENTRIES_PER_BLK   (BLK_SIZE/sizeof(CFAT32DirEntry))
+#define FAT32_ENTRIES_BITS      Bsf(FAT32_ENTRIES_PER_BLK)
+
+class CPalindromeU16
+{
+  U16   little,big;
+};
+
+class CPalindromeU32
+{
+  U32   little,big;
+};
+
+class CATAPITrack
+{
+  U16   track_info_len;
+  U8    track_lo,
+        session_lo,
+        reserved;
+  U16   misc1;
+  U8    misc2;
+  U32   track_start,
+        next_writable,
+        free_blks;
+  union {
+    U32 fixed_packet_size;
+    U32 blocking_factor;
+  };
+  union {
+    U32 track_size;
+    U32 rzone_end;
+  };
+  U32   last_recorded;
+  U8    track_hi,
+        session_hi;
+  U16   reserved;
+  U32   read_compatibility,
+        next_layer_jmp,
+        last_layer_jmp;
+};
+
+//ISO9660
+#define ISOT_BOOT_RECORD        0
+#define ISOT_PRI_VOL_DESC       1
+#define ISOT_SUPPLEMENTARY_DESC 2
+#define ISOT_VOL_DRV_DESC       3
+#define ISOT_TERMINATOR         255
+
+class CISODirEntry
+{
+  U8 pad[2];
+  CPalindromeU32 loc;
+  U8 pad[24];
+};
+
+class CISOPriDesc
+{
+  U8    type,
+        id[5],
+        version,
+        pad[73];
+  CPalindromeU32 vol_space_size;
+  U8    pad[32];
+  CPalindromeU16 vol_set_size;
+  CPalindromeU16 vol_seq_num;
+  CPalindromeU16 log_block_size;
+  U8    pad[20];
+  CISODirEntry root_dir_record;
+  U8    pad[128],
+        publisher_id[128],
+        pad[435],
+        file_structure_version,
+        pad[1166];
+};
+
+//Red Sea Attributes
+//See ST_FILE_ATTRS
+#define RS_ATTR_READ_ONLY       0x01 //R
+#define RS_ATTR_HIDDEN          0x02 //H
+#define RS_ATTR_SYSTEM          0x04 //S
+#define RS_ATTR_VOL_ID          0x08 //V
+#define RS_ATTR_DIR             0x10 //D
+#define RS_ATTR_ARCHIVE         0x20 //A
+#define RS_ATTR_LONG_NAME       (RS_ATTR_READ_ONLY|RS_ATTR_HIDDEN|\
+                                RS_ATTR_SYSTEM|RS_ATTR_VOL_ID)
+#define RS_ATTR_LONG_NAME_MASK  (RS_ATTR_LONG_NAME|RS_ATTR_DIR|RS_ATTR_ARCHIVE)
+#define RS_ATTR_DELETED         0x100 //X
+#define RS_ATTR_RESIDENT        0x200 //T
+#define RS_ATTR_COMPRESSED      0x400 //Z
+#define RS_ATTR_CONTIGUOUS      0x800 //C
+#define RS_ATTR_FIXED           0x1000 //F
+
+#help_index "File/CD DVD"
+//Media types for DVDImageWrite()
+#define MT_CD           1
+#define MT_DVD          2
+
+#help_index "File/Low Level;File/Program Routines"
+//CDirEntry flags (Used by FileMgr())
+#define CDIR_FILENAME_LEN       38 //Must include terminator zero
+public class CDirEntry
+{
+  CDirEntry *next,*parent,*sub;
+  U8    *full_name;
+  I64   user_data,user_data2;
+
+  U0    start;
+  U16   attr;
+  U8    name[CDIR_FILENAME_LEN];
+  I64   clus,size;
+  CDate datetime;
+};
+#define CDIR_SIZE (sizeof(CDirEntry)-offset(CDirEntry.start))
+
+#help_index "File/Program Routines"
+//File Util Flags
+//See ST_FILE_UTIL_FLAGS
+#define FUf_RECURSE             0
+#define FUf_DIFF                1
+#define FUf_DEL                 1
+#define FUf_IGNORE              2
+#define FUf_ALL                 3
+#define FUf_CANCEL              4
+#define FUf_REPLACE             5
+#define FUf_RISKY               5
+#define FUf_PUBLIC              6
+#define FUf_MAP                 7
+#define FUf_EXPAND              8
+#define FUf_SINGLE              9
+#define FUf_JUST_DIRS           10
+#define FUf_JUST_FILES          11
+#define FUf_JUST_TXT            12
+#define FUf_JUST_DD             13
+#define FUf_JUST_SRC            14
+#define FUf_JUST_AOT            15
+#define FUf_JUST_JIT            16
+#define FUf_JUST_GR             17
+#define FUf_Z_OR_NOT_Z          18
+#define FUf_CLUS_ORDER  19
+#define FUf_SCAN_PARENTS        20
+#define FUf_FLATTEN_TREE        21
+#define FUf_WHOLE_LABELS        22
+#define FUf_WHOLE_LABELS_BEFORE 23
+#define FUf_WHOLE_LABELS_AFTER  24
+
+#define FUF_RECURSE             0x0000001 //r
+#define FUF_DIFF                0x0000002 //d
+#define FUF_DEL                 0x0000002 //d
+#define FUF_IGNORE              0x0000004 //i
+#define FUF_ALL                 0x0000008 //a
+#define FUF_CANCEL              0x0000010 //c
+#define FUF_REPLACE             0x0000020 //R
+#define FUF_RISKY               0x0000020 //R
+#define FUF_PUBLIC              0x0000040 //p
+#define FUF_MAP                 0x0000080 //m
+#define FUF_EXPAND              0x0000100 //x
+#define FUF_SINGLE              0x0000200 //s
+#define FUF_JUST_DIRS           0x0000400 //D
+#define FUF_JUST_FILES          0x0000800 //F
+#define FUF_JUST_TXT            0x0001000 //T
+#define FUF_JUST_DD             0x0002000 //$
+#define FUF_JUST_SRC            0x0004000 //S
+#define FUF_JUST_AOT            0x0008000 //A
+#define FUF_JUST_JIT            0x0010000 //J
+#define FUF_JUST_GR             0x0020000 //G
+#define FUF_Z_OR_NOT_Z          0x0040000 //Z
+#define FUF_CLUS_ORDER  0x0080000 //O Move disk head one direction
+#define FUF_SCAN_PARENTS        0x0100000 //P
+#define FUF_FLATTEN_TREE        0x0200000 //f
+#define FUF_WHOLE_LABELS        0x0400000 //l
+#define FUF_WHOLE_LABELS_BEFORE 0x0800000 //lb
+#define FUF_WHOLE_LABELS_AFTER  0x1000000 //la
+
+#define FUG_FILES_FIND  (FUF_RECURSE|FUF_SINGLE|FUF_CLUS_ORDER|\
+  FUF_JUST_DIRS|FUF_JUST_FILES|FUF_JUST_TXT|FUF_JUST_DD|\
+  FUF_JUST_SRC|FUF_JUST_AOT|FUF_JUST_JIT|FUF_JUST_GR|FUF_FLATTEN_TREE)
+#define FUG_FILE_FIND   (FUF_JUST_DIRS|FUF_JUST_FILES|FUF_Z_OR_NOT_Z|\
+  FUF_SCAN_PARENTS)
+
+#help_index "File/Low Level"
+//See ST_BLKDEV_TYPES
+#define BDT_NULL                0
+#define BDT_RAM                 1
+#define BDT_ATA                 2
+#define BDT_ISO_FILE_READ       3
+#define BDT_ISO_FILE_WRITE      4
+#define BDT_ATAPI               5
+#define BDT_TYPES_NUM           6
+
+#define BDF_REMOVABLE           0x001
+#define BDF_INITIALIZED         0x002
+#define BDF_READ_ONLY           0x004
+#define BDF_READ_ONLY_OVERRIDE  0x008
+#define BDF_LAST_WAS_WRITE      0x010
+#define BDF_READ_CACHE          0x020
+#define BDF_FMT                 0x040
+#define BDF_INIT_IN_PROGRESS    0x080
+#define BDF_EXT_SIZE            0x100
+
+#define BDf_REMOVABLE           0
+#define BDf_INITIALIZED         1
+#define BDf_READ_ONLY           2
+#define BDf_READ_ONLY_OVERRIDE  3
+#define BDf_LAST_WAS_WRITE      4
+#define BDf_READ_CACHE          5
+#define BDf_FMT                 6
+#define BDf_INIT_IN_PROGRESS    7
+#define BDf_EXT_SIZE            8
+
+//locked flags
+#define BDlf_LOCKED             0
+
+#define BLKDEVS_NUM             26
+#define BD_SIGNATURE_VAL        'BDSV'
+public class CBlkDev
+{
+  CBlkDev *lock_fwding; //If two blkdevs on same controller, use just one lock
+  I64   locked_flags;
+  U32   bd_signature,
+        type,flags;
+  U8    first_drv_let,unit,pad[2];
+  U32   base0,base1,
+        blk_size;
+  I64   drv_offset,init_root_dir_blks,
+        max_blk;
+  U16   *dev_id_record;
+  U8    *RAM_dsk,
+        *file_dsk_name;
+  CFile *file_dsk;
+  CTask *owning_task;
+  F64   last_time;
+  U32   max_reads,max_writes;
+};
+
+//Drive locked_flags
+#define DVlf_LOCKED     0
+
+//See ST_DRV_TYPES
+#define FSt_NULL        0
+#define FSt_REDSEA      1 //Supported
+#define FSt_FAT32       2 //Supported except for short names, to some degree
+#define FSt_ISO9660     3 //Not Supported
+#define FSt_NTFS        4 //Not Supported
+#define FSt_UNKNOWN     5
+#define FSt_TYPES_NUM   6
+#define FSG_TYPE_MASK   0x7FFF
+//File system type flags
+#define FStf_DISABLE    15
+
+#define MBR_PT_FAT12    0x01
+#define MBR_PT_FAT32a   0x0B
+#define MBR_PT_FAT32b   0x0C
+#define MBR_PT_FAT32c   0x1B
+#define MBR_PT_FAT32d   0x1C
+#define MBR_PT_FAT32e   0x8B
+#define MBR_PT_FAT32f   0x8C
+#define MBR_PT_NTFS     0x07
+#define MBR_PT_REDSEA   0x88
+
+class CFreeLst
+{
+  CFreeLst *next,*last;
+  I64   start,size;
+};
+
+#define DRVS_NUM                26
+
+#define DRV_SIGNATURE_VAL       'DVSV'
+public class CDrv
+{
+//Don't access ->drv_let directly in case a drive has been remapped.
+  //Use Drv2Let().
+  I64   locked_flags;
+  U32   dv_signature;
+  U8    drv_let,pad;
+  U16   fs_type;
+  I64   drv_offset,
+        size,
+        prt_num,
+        file_system_info_sect,
+        fat1,fat2,
+        root_clus,
+        data_area,
+        spc; //sectors per clus
+  CDate fat32_local_time_offset;
+  CTask *owning_task;
+  CBlkDev *bd;
+
+  CFAT32FileInfoSect *fis;
+  I64   fat_blk_dirty,
+        cur_fat_blk_num;
+  U32   *cur_fat_blk;
+  CFreeLst *next_free,*last_free;
+};
+
+#define DSK_CACHE_HASH_SIZE     0x2000
+
+class CCacheBlk
+{
+  CCacheBlk *next_lru,*last_lru;
+  CCacheBlk *next_hash,*last_hash;
+  CDrv  *dv;
+  I64   blk;
+  U8    body[BLK_SIZE];
+};
+
+#help_index "File/System"
+#define DFT_ISO_FILENAME        "::/Tmp/CDDVD.ISO"
+#define DFT_ISO_C_FILENAME      "::/Tmp/CDDVD.ISO.C"
+
+public class CBlkDevGlbls
+{
+  CBlkDev *blkdevs;
+  U8    *dft_iso_filename;      //"::/Tmp/CDDVD.ISO"
+  U8    *dft_iso_c_filename;    //"::/Tmp/CDDVD.ISO.C"
+  U8    *tmp_filename;
+  U8    *home_dir;
+  CCacheBlk *cache_base,*cache_ctrl,**cache_hash_table;
+  I64   cache_size,read_cnt,write_cnt;
+  CDrv  *drvs,*let_to_drv[32];
+  I64   mount_ide_auto_cnt,
+        ins_base0,ins_base1;    //Install cd/dvd controller.
+  U8    boot_drv_let,first_hd_drv_let,first_dvd_drv_let;
+  Bool  dvd_boot_is_good,ins_unit,pad[3];
+};
+
+#help_index "File/Internal"
+public class CDirContext
+{
+  CDrv  *old_dv,*dv;
+  U8    *old_dir,*mask;
+};
+
+#help_index "File/CFile"
+#define FFB_NEXT_BLK            I64_MAX
+
+#define FF_WRITE                1
+#define FF_NEW_FILE             2
+#define FF_BUF_DIRTY            4
+#define FF_NEEDS_WRITE          8
+#define FF_CONTIGUOUS           16
+#define FF_USE_OLD_DATETIME     32
+
+public class CFile //See ::/Demo/Dsk/DataBase.HC.
+{
+  I64   flags;
+  CDirEntry de;
+  CDrv  *dv;
+  I64   fblk_num,clus,file_clus_num,max_blk;
+  U8    *clus_buf;
+};
+
+#help_index "Memory/Heap"
+#define _CFG_HEAP_DBG FALSE
+
+#if _CFG_HEAP_DBG
+class CMemUnused
+{
+  CHeapCtrl *hc;
+  U8    *caller1,*caller2;
+  CMemUnused *next;
+  I64   size;
+};
+class CMemUsed
+{
+  CHeapCtrl *hc;
+  U8    *caller1,*caller2;
+  CMemUsed *next,*last;
+  I64   size;
+  U0    start;
+};
+#else
+class CMemUnused
+{
+  U0    hc;
+  U0    caller1,caller2;
+  CMemUnused *next;
+  I64   size;
+};
+class CMemUsed
+{
+  CHeapCtrl *hc;
+  U0    caller1,caller2;
+  U0    next,last;
+  I64   size;
+  U0    start;
+};
+#endif
+
+#help_index "Memory/BlkPool"
+#help_file "::/Doc/Pags"
+
+#define MBS_USED_SIGNATURE_VAL          'MBUs'
+#define MBS_UNUSED_SIGNATURE_VAL        'MBUn'
+class CMemBlk
+{
+  CMemBlk *next,*last;
+  U32   mb_signature,pags;
+};
+
+#define MRT_UNUSED      0
+#define MRT_RAM         1
+#define MRT_DEV         2
+
+class CMemRange
+{
+  CMemRange *next,*last;
+  U32   type,flags;
+  U8    *base;
+  I64   size;
+};
+
+#define MEM_PAG_BITS            9
+#define MEM_PAG_SIZE            (1<<MEM_PAG_BITS)
+#define MEM_HEAP_HASH_SIZE      1024
+#define MEM_FREE_PAG_HASH_SIZE  0x100
+//It is common to MAlloc() exact powers of two.  There is some overhead.
+//We add 2 pags, so a request is not rounded-up to next power of two.
+#define MEM_EXTRA_HASH2_PAGS    2
+
+#define MEM_ADAM_STK            (MEM_PAG_SIZE*512) //Like 16384*MEM_PAG_SIZE
+#define MEM_SETH_STK            (MEM_PAG_SIZE*512)
+#define MEM_INTERRUPT_STK       (MEM_PAG_SIZE*512)
+#define MEM_DFT_STK             (MEM_PAG_SIZE*512)
+
+#define TASK_HASH_TABLE_SIZE    (1<<10)
+
+//locked flags
+#define BPlf_LOCKED             0
+public class CBlkPool
+{
+  I64   locked_flags,alloced_u8s,used_u8s;
+  CMemBlk *mem_free_lst,
+        *mem_free_2meg_lst, //This is for Sup1CodeScraps/Mem/Mem2Meg.HC.
+        *free_pag_hash[MEM_FREE_PAG_HASH_SIZE],
+        *free_pag_hash2[64-MEM_PAG_BITS];
+};
+
+#help_index "Memory/HeapCtrl"
+//locked flags
+#define HClf_LOCKED             0
+
+#define HEAP_CTRL_SIGNATURE_VAL 'HcSV'
+public class CHeapCtrl
+{
+  CBlkPool *bp;
+  U32   hc_signature,pad;
+  I64   locked_flags,alloced_u8s,used_u8s;
+  CTask *mem_task;
+  CMemBlk *next_mem_blk,*last_mem_blk;
+  CMemBlk *last_mergable;
+  CMemUnused *malloc_free_lst;
+  CMemUsed *next_um,*last_um;
+  CMemUnused *heap_hash[MEM_HEAP_HASH_SIZE/sizeof(U8 *)];
+};
+
+#help_index "Devices;Memory/Page Tables"
+public class CDevGlbls
+{
+  I64   *idt;
+  U8    *mem64_ptr;
+  U8    *uncached_alias; //Alias of lowest 4Gig.
+  U8    mp_apic_ids[MP_PROCESSORS_NUM];
+  CMemRange mem32_head;
+  CPCIDev pci_head;
+};
+
+#help_index "Graphics/Color;Graphics/Device Contexts"
+//Raster operations
+#define ROPB_EQU                        0x00
+#define ROPB_XOR                        0x01
+#define ROPB_COLLISION                  0x02
+#define ROPB_MONO                       0x03
+#define ROPBF_HALF_RANGE_COLOR          0x10
+#define ROPBF_TWO_SIDED                 0x20
+#define ROPBF_DITHER                    0x40
+#define ROPBF_PROBABILITY_DITHER        0x80
+
+#define ROP_EQU                         (ROPB_EQU<<8)
+#define ROP_XOR                         (ROPB_XOR<<8)
+#define ROP_COLLISION                   (ROPB_COLLISION<<8)
+#define ROP_MONO                        (ROPB_MONO<<8)
+
+//These are just for ROPF_PROBABILITY_DITHER
+//See DCLighting().
+#define ROPF_HALF_RANGE_COLOR           0x1000
+#define ROPF_TWO_SIDED                  0x2000
+
+//These always go in the c1.rop of a CColorROPU32
+#define ROPF_DITHER                     0x40000000
+#define ROPF_PROBABILITY_DITHER         0x80000000
+
+#help_index "Graphics/Color"
+#define TRANSPARENT             0xFF
+#define BLACK                   0
+#define BLUE                    1
+#define GREEN                   2
+#define CYAN                    3
+#define RED                     4
+#define PURPLE                  5
+#define BROWN                   6
+#define LTGRAY                  7
+#define DKGRAY                  8
+#define LTBLUE                  9
+#define LTGREEN                 10
+#define LTCYAN                  11
+#define LTRED                   12
+#define LTPURPLE                13
+#define YELLOW                  14
+#define WHITE                   15
+
+#define COLORS_NUM              16
+#define COLOR_INVALID           16
+#define COLOR_MONO              0xFF
+
+public U16 class CColorROPU16 //Don't use this, use CColorROPU32
+{
+  U8    color,rop;
+};
+public U32 class CColorROPU32
+{
+  CColorROPU16 c0,c1;
+};
+#define COLORROP_COLORS_MASK    0x00FF00FF
+#define COLORROP_NO_ROP0_MASK   0xFFFF00FF
+#define COLORROP_BITS           16
+public U32 class CBGR24
+{
+  U8    b,g,r,pad;
+};
+public I64 class CBGR48
+{
+  U16   b,g,r,pad;
+};
+
+#help_index "Keyboard Devices;Char/Input;StdIn"
+#define KBD_PORT        0x60
+#define KBD_CTRL        0x64
+public class CKbdStateGlbls
+{
+  I64   scan_code,      //See scan codes
+        last_down_scan_code,
+        cnt,            //Count of keys pressed since boot.
+        timestamp,      //Output: GetTSC when event.
+        new_key_timestamp; //Output: GetTSC when new key event.
+  CFifoU8 *fifo,*fifo2; //Private
+  CFifoI64 *scan_code_fifo;
+
+  //BitTest, Bt(), with a merged scan code.
+  //(Left and right shift merged, for example.)
+  U32   down_bitmap[8],
+//BitTest, Bt(), with an unmerged scan code.
+        down_bitmap2[8];
+
+  Bool  rst,            //Private: Reset KbdMs
+        irqs_working;   //Private
+};
+
+#help_index "Mouse"
+public class CMsHardStateGlbls
+{
+  CD3I64 pos,           //Position in pixels
+        prescale;
+  CD3   scale;
+  F64   speed;          //Output: How fast the user is moving it.
+  I64   timestamp,      //Output: GetTSC when event.
+        install_attempts, //Private
+        pkt_size;       //Private
+  CFifoU8 *fifo,*fifo2; //Private
+  Bool  bttns[5],
+        has_wheel,
+        has_ext_bttns,
+        evt,            //Private
+        installed,      //Private
+        install_in_progress, //Private
+        irqs_working;   //Private
+};
+
+public class CMsStateGlbls
+{
+  CD3I64 pos,           //Position in pixels
+        pos_text,       //Position in text rows,cols
+        presnap,
+        offset;
+  CD3   scale;
+  F64   speed;          //Output: How fast the user is moving it.
+  I64   timestamp;      //Output: GetTSC when event.
+  F64   dbl_time,       //Input: Time threshold for calling it a double click.
+        left_dbl_time,  //Private
+        right_dbl_time; //Private
+  Bool  lb,             //Left Bttn
+        rb,             //Right Bttn
+        show,
+        has_wheel,
+        left_dbl,       //Private
+        left_down_sent, //Private
+        right_dbl,      //Private
+        right_down_sent;//Private
+};
+
+public class CGridGlbls
+{
+  Bool  snap    format "$CB,\"Snap Grid\"$\n",
+        show    format "$CB,\"Show Grid\"$\n",
+        coord   format "$CB,\"Show Coordinates\"$\n";
+  U8    pad[5];
+  F64   x       format "$DA-TRM,A=\"X Spacing:%6.3f\"$\n",
+        y       format "$DA-TRM,A=\"Y Spacing:%6.3f\"$\n",
+        z       format "$DA-TRM,A=\"Z Spacing:%6.3f\"$\n",
+        x_offset format "$DA-TRM,A=\"X Offset :%6.3f\"$\n",
+        y_offset format "$DA-TRM,A=\"Y Offset :%6.3f\"$\n",
+        z_offset format "$DA-TRM,A=\"Z Offset :%6.3f\"$\n",
+        x_speed format "$DA-TRM,A=\"X Speed  :%6.3f\"$\n",
+        y_speed format "$DA-TRM,A=\"Y Speed  :%6.3f\"$\n",
+        z_speed format "$DA-TRM,A=\"Z Speed  :%6.3f\"$\n";
+};
+
+#help_index "Ctrls"
+#define CTRLT_GENERIC           0
+#define CTRLT_WIN_HSCROLL       1 //unique
+#define CTRLT_WIN_VSCROLL       2 //unique
+#define CTRLT_VIEWING_ANGLES    3 //unique
+
+#define CTRLF_SHOW              1
+#define CTRLF_BORDER            2
+#define CTRLF_CAPTURE_LEFT_MS   4
+#define CTRLF_CAPTURE_RIGHT_MS  8
+#define CTRLF_CLICKED           16
+
+#define WSSf_SET_TO_POS         0
+
+public class CWinScroll
+{
+  I64   min,pos,max;
+  U32   flags;
+  U8    color,pad[3];
+};
+
+public class CViewAngles
+{
+  I64   sx,sy,sz;
+  F64   ax,ay,az;
+  CColorROPU32 cx,cy,cz,cbd,cbg,cfg;
+};
+
+public class CCtrl
+{
+  CCtrl *next,*last;
+  CTask *win_task;
+  I64   type,flags;
+
+  //win pix coordinates
+  I64   left,right,top,bottom;
+
+  //scrn pix coordinates (derived)
+  I64   scrn_left,scrn_right,scrn_top,scrn_bottom;
+
+  U8    *state;
+
+  //called on resize
+  U0    (*update_derived_vals)(CCtrl *c);
+  U0    (*draw_it)(CDC *dc,CCtrl *c);
+
+  Bool  (*inside_ctrl)(CCtrl *c,I64 x,I64 y); //For nonbox shapes
+  U0    (*left_click)(CCtrl *c,I64 x,I64 y,Bool down);
+  U0    (*right_click)(CCtrl *c,I64 x,I64 y,Bool down);
+  U0    (*wheel_chg)(CCtrl *c,I64 delta);
+};
+
+#help_index "Menus"
+public class CMenuEntry
+{
+  CMenuEntry *next;
+  CMenuEntry *sub;
+  U8    name[32];
+  I64   msg_code,arg1,arg2;
+  Bool  checked,dir,pad[6];
+};
+
+public class CMenu
+{
+  CMenu *next;
+  CMenuEntry *sub;
+  CTask *task;
+  I64   flags;
+  U8    attr,pad[7];
+};
+
+#help_index "Task"
+class CBpt
+{
+  CBpt  *next;
+  U8    *addr,
+        val,pad[7];
+};
+
+class CExcept
+{
+  CExcept *next,*last;
+  I64   hndlr_catch,hndlr_untry,
+        rsp,rbp,rflags,rsi,rdi,r10,r11,r12,r13,r14,r15;
+};
+
+class CFPU
+{
+  U8    body[512];
+};
+
+#help_index "Job/Exe;Task/Job/Exe"
+#define JOBf_WAKE_MASTER        0
+#define JOBf_FOCUS_MASTER       1
+#define JOBf_EXIT_ON_COMPLETE   2
+#define JOBf_DONT_FILTER        3
+#define JOBf_HIGHEST_PRIORITY   4
+//MP flags
+#define JOBf_DONE               5
+#define JOBf_DISPATCHED         6
+#define JOBf_FREE_ON_COMPLETE   7
+#define JOBf_ADD_TO_QUE         8
+
+#define JOBT_TEXT_INPUT         0 //TaskText()  Feed StdIn
+#define JOBT_MSG                1 //TaskMsg()   Post msg
+#define JOBT_EXE_STR            2 //TaskExe()   Compile & execute src code text
+//MP cmds
+#define JOBT_CALL               3 //JobQue()    Tell MP to call function
+#define JOBT_SPAWN_TASK         4 //Spawn()     Tell MP to spawn task
+
+class CJob
+{
+  CJob *next,*last;
+  CJobCtrl *ctrl;
+  I64   job_code,flags,msg_code;
+
+  I64   (*addr)(U8 *fun_arg);
+  U8    *fun_arg;
+
+  U8    *aux_str;
+  I64   aux1,aux2, //Sometimes called arg1 and arg2. (Windows msg param1 param2)
+        res;
+
+  CTask *spawned_task,
+        *master_task;
+};
+
+#define JOBCf_LOCKED            0
+class CJobCtrl
+{
+  CJob *next_waiting,*last_waiting;
+  CJob *next_done,*last_done;
+  I64   flags;
+};
+
+#help_index "Messages"
+//See ::/Demo/MsgLoop.HC
+#define MSG_NULL                0
+#define MSG_CMD                 1
+#define MSG_KEY_DOWN            2  //(ASCII,scan code) Press <CTRL-SHIFT-L>
+#define MSG_KEY_UP              3  //(ASCII,scan code) Press <CTRL-SHIFT-L>
+#define MSG_MS_MOVE             4  //(x,y)
+#define MSG_MS_L_DOWN           5  //(x,y)
+#define MSG_MS_L_UP             6  //(x,y)
+#define MSG_MS_L_D_DOWN         7  //(x,y)
+#define MSG_MS_L_D_UP           8  //(x,y)
+#define MSG_MS_R_DOWN           9  //(x,y)
+#define MSG_MS_R_UP             10 //(x,y)
+#define MSG_MS_R_D_DOWN         11 //(x,y)
+#define MSG_MS_R_D_UP           12 //(x,y)
+
+//Fake messages used to send both an up and down.
+#define MSG_KEY_DOWN_UP         -2  //Down & UP
+#define MSG_MS_L_DOWN_UP        -5  //Down & Up
+#define MSG_MS_L_D_DOWN_UP      -7  //Down & Up
+#define MSG_MS_R_DOWN_UP        -9  //Down & Up
+#define MSG_MS_R_D_DOWN_UP      -11 //Down & Up
+
+#help_index "Task/Settings"
+#define TSF_SAME_SONG   1
+public class CTaskSettings
+{
+  CTaskSettings *next;
+  U8    *cur_dir;
+  I64   left,right,top,bottom;
+  U0    (*draw_it)(CTask *task,CDC *dc);
+  U0    (*task_end_cb)();
+  CTask *song_task,*animate_task;
+  I64   scroll_x,scroll_y,scroll_z;
+  CBGR48 palette[COLORS_NUM];
+  U32   win_inhibit;
+  U8    text_attr,title_src,
+        border_attr,border_src,
+        task_title[STR_LEN];
+  Bool  border,hide_cursor,highlight_cursor,scroll,autocomplete,pad[3];
+#assert !($&7)
+};
+
+#help_index "Task"
+//CTask.border_src
+#define BDS_CONST               0
+#define BDS_CUR_DRV             1
+#define BDS_ED_FILENAME_DRV     2
+
+//CTask.title_src
+#define TTS_CONST               0
+#define TTS_LOCKED_CONST        1 //This is not strictly enforced
+#define TTS_TASK_NAME           2
+#define TTS_ED_FILENAME         3
+#define TTS_CUR_LEX             4
+
+//CTask.task_flags
+#define TASKf_TASK_LOCK         0
+#define TASKf_KILL_TASK         1
+#define TASKf_SUSPENDED         2
+#define TASKf_IDLE              3
+#define TASKf_CMD_LINE_PMT      4
+#define TASKf_INPUT_FILTER_TASK 5
+#define TASKf_FILTER_INPUT      6
+#define TASKf_HAS_SONG          7
+#define TASKf_DISABLE_BPTS      8
+#define TASKf_AWAITING_MSG      9
+#define TASKf_BREAK_LOCKED      10
+#define TASKf_PENDING_BREAK     11
+#define TASKf_BREAK_TO_SHIFT_ESC 12
+#define TASKf_KILL_AFTER_DBG    13
+
+#define TASKf_NONTIMER_RAND     14
+
+//CTask.display_flags
+#define DISPLAYf_SHOW                   0
+#define DISPLAYf_NOT_RAW                1
+#define DISPLAYf_SILENT                 2
+#define DISPLAYf_NO_BORDER              3
+#define DISPLAYf_WIN_ON_TOP             4
+#define DISPLAYf_CHILDREN_NOT_ON_TOP    5
+
+#define TASK_SIGNATURE_VAL              'TskS'
+#define TASK_NAME_LEN                   32
+#define TASK_EXCEPT_CALLERS             8
+class CTaskStk
+{
+  CTaskStk *next_stk;
+  I64   stk_size,stk_ptr;
+  U0    stk_base;
+};
+
+#define DYING_JIFFIES   ToI64(JIFFY_FREQ/5)
+class CTaskDying
+{
+  CTask *next,*last;
+  I64   wake_jiffy;
+};
+
+public class CTask //The Fs segment reg points to current CTask.
+{
+  CTask *addr; //Self-addressed ptr
+  U32   task_signature,win_inhibit;
+#assert $==offset(CTaskDying.wake_jiffy)
+  I64   wake_jiffy;
+  U32   task_flags,display_flags;
+
+  CHeapCtrl *code_heap,*data_heap;
+
+  CDoc  *put_doc,*display_doc, //When double buffering, these two differ.
+        *border_doc;
+  I64   win_left,win_right,win_top,win_bottom;
+
+  CDrv  *cur_dv;
+  U8    *cur_dir;
+
+  CTask *parent_task,
+        *next_task,*last_task,
+        *next_input_filter_task,*last_input_filter_task,
+        *next_sibling_task,*last_sibling_task,
+        *next_child_task,*last_child_task;
+
+  //These are derived from left,top,right,bottom
+  I64   win_width,win_height,
+        pix_left,pix_right,pix_width, //These are in pixs, not characters
+        pix_top,pix_bottom,pix_height,
+        scroll_x,scroll_y,scroll_z;
+
+  //These must be in this order
+  //for TASK_CONTEXT_SAVE and _TASK_CONTEXT_RESTORE
+  I64   rip,rflags,rsp,rsi,rax,rcx,rdx,rbx,rbp,rdi,
+        r8,r9,r10,r11,r12,r13,r14,r15;
+  CCPU  *gs;
+  CFPU  *fpu_mmx;
+  I64   swap_cnter;
+
+  U0    (*draw_it)(CTask *task,CDC *dc);
+
+  U8    task_title[STR_LEN],
+        task_name[TASK_NAME_LEN],
+        wallpaper_data[STR_LEN],
+
+        title_src,border_src,
+        text_attr,border_attr;
+  U16   win_z_num,pad;
+
+  CTaskStk *stk;
+
+  CExcept *next_except,*last_except;
+  I64   except_rbp,     //throw routine's RBP
+        except_ch;      //throw(ch)
+  U8    *except_callers[TASK_EXCEPT_CALLERS];
+
+  Bool  catch_except;
+  Bool  new_answer;
+  U8    answer_type,pad[5];
+  I64   answer;
+  F64   answer_time;
+  CBpt  *bpt_lst;
+  CCtrl *next_ctrl,*last_ctrl;
+  CMenu *cur_menu;
+  CTaskSettings *next_settings;
+  CMathODE *next_ode,*last_ode;
+  F64   last_ode_time;
+  CHashTable *hash_table;
+
+  CJobCtrl srv_ctrl;
+  CCmpCtrl *next_cc,*last_cc;
+  CHashFun *last_fun;
+
+  U0    (*task_end_cb)();
+  CTask *song_task,*animate_task;
+  I64   rand_seed,
+        task_num,
+        fault_num,fault_err_code;
+  CTask *popup_task,
+        *dbg_task;
+  CWinScroll horz_scroll,vert_scroll;
+
+  I64   user_data;
+#assert !($&7)
+};
+
+class CTSS
+{
+  U32   res1;
+  I64   rsp0,rsp1,rsp2,res2,
+        ist1,ist2,ist3,ist4,ist5,ist6,ist7,res3;
+  U16   res4,io_map_offset;
+  U8    io_map[0x10000/8];
+  I64   *st0,*st1,*st2;
+  U16   tr,tr_ring3;
+};
+
+#define ans     (Fs->answer)
+#define ansf    (Fs->answer(F64))
+
+#define _RAX Fs->rax
+#define _RBX Fs->rbx
+#define _RCX Fs->rcx
+#define _RDX Fs->rdx
+#define _RSI Fs->rsi
+#define _RDI Fs->rdi
+#define _RBP Fs->rbp
+#define _RSP Fs->rsp
+#define _RIP Fs->rip
+#define _R8  Fs->r8
+#define _R9  Fs->r9
+#define _R10 Fs->r10
+#define _R11 Fs->r11
+#define _R12 Fs->r12
+#define _R13 Fs->r13
+#define _R14 Fs->r14
+#define _R15 Fs->r15
+
+#help_index "MultiCore"
+#define CPUf_RAN_A_TASK         0
+#define CPUf_DYING_TASK_QUE     1
+
+public class CCPU //The Gs segment reg points to current CCPU.
+{
+  CCPU  *addr; //Self-addressed ptr
+  I64   num,cpu_flags,
+        startup_rip,
+        idle_pt_hits;
+  F64   idle_factor;
+  I64   total_jiffies;
+  CTask *seth_task,*idle_task;
+  I64   tr,   //task reg
+        swap_cnter;
+  U0    (*profiler_timer_irq)(CTask *task);
+  CTaskDying *next_dying,*last_dying;
+  I64   kill_jiffy;
+  CTSS  *tss;
+  I64   start_stk[16];
+#assert !($&7)
+};
+
+#help_index "Memory/Page Tables"
+#define MEM_MIN_MEG             512 //512 Meg minimum.
+
+#define SYS_FIXED_AREA          0x100000
+#define SYS_16MEG_AREA_LIMIT    0x1000000
+public class CSysFixedArea
+{
+  CFPU  init_fpu_mmx;
+  CCPU  boot_cpu;
+  CTask adam;
+  CBlkPool sys_code_bp;
+  CHeapCtrl adam_hc;
+  $=($+0x1000-1)&-0x1000;
+};
+
+#help_index "Char"
+#define CH_CTRLA        0x01
+#define CH_CTRLB        0x02
+#define CH_CTRLC        0x03
+#define CH_CTRLD        0x04
+#define CH_CTRLE        0x05
+#define CH_CTRLF        0x06
+#define CH_CTRLG        0x07
+#define CH_CTRLH        0x08
+#define CH_CTRLI        0x09
+#define CH_CTRLJ        0x0A
+#define CH_CTRLK        0x0B
+#define CH_CTRLL        0x0C
+#define CH_CTRLM        0x0D
+#define CH_CTRLN        0x0E
+#define CH_CTRLO        0x0F
+#define CH_CTRLP        0x10
+#define CH_CTRLQ        0x11
+#define CH_CTRLR        0x12
+#define CH_CTRLS        0x13
+#define CH_CTRLT        0x14
+#define CH_CTRLU        0x15
+#define CH_CTRLV        0x16
+#define CH_CTRLW        0x17
+#define CH_CTRLX        0x18
+#define CH_CTRLY        0x19
+#define CH_CTRLZ        0x1A
+#define CH_CURSOR       0x05
+#define CH_BACKSPACE    0x08
+#define CH_ESC          0x1B
+#define CH_SHIFT_ESC    0x1C
+#define CH_SHIFT_SPACE  0x1F
+#define CH_SPACE        0x20
+
+#define ST_ERR_ST   "$LTRED$$BK,1$ERROR:$FG$$BK,0$ "
+#define ST_WARN_ST  "$RED$$BK,1$WARNING:$FG$$BK,0$ "
+
+//Scan code flags
+#define SCf_E0_PREFIX   7
+#define SCf_KEY_UP      8
+#define SCf_SHIFT       9
+#define SCf_CTRL        10
+#define SCf_ALT         11
+#define SCf_CAPS        12
+#define SCf_NUM         13
+#define SCf_SCROLL      14
+#define SCf_NEW_KEY     15
+#define SCf_MS_L_DOWN   16
+#define SCf_MS_R_DOWN   17
+#define SCf_DELETE      18
+#define SCf_INS         19
+#define SCf_NO_SHIFT    30
+#define SCf_KEY_DESC    31
+#define SCF_E0_PREFIX   (1<<SCf_E0_PREFIX)
+#define SCF_KEY_UP      (1<<SCf_KEY_UP)
+#define SCF_SHIFT       (1<<SCf_SHIFT)
+#define SCF_CTRL        (1<<SCf_CTRL)
+#define SCF_ALT         (1<<SCf_ALT)
+#define SCF_CAPS        (1<<SCf_CAPS)
+#define SCF_NUM         (1<<SCf_NUM)
+#define SCF_SCROLL      (1<<SCf_SCROLL)
+#define SCF_NEW_KEY     (1<<SCf_NEW_KEY)
+#define SCF_MS_L_DOWN   (1<<SCf_MS_L_DOWN)
+#define SCF_MS_R_DOWN   (1<<SCf_MS_R_DOWN)
+#define SCF_DELETE      (1<<SCf_DELETE)
+#define SCF_INS         (1<<SCf_INS)
+#define SCF_NO_SHIFT    (1<<SCf_NO_SHIFT)
+#define SCF_KEY_DESC    (1<<SCf_KEY_DESC)
+
+//TempleOS places a 1 in bit 7 for
+//keys with an E0 prefix.
+//See ::/Doc/CharOverview.DD and KbdHndlr().
+#define SC_ESC          0x01
+#define SC_BACKSPACE    0x0E
+#define SC_TAB          0x0F
+#define SC_ENTER        0x1C
+#define SC_SHIFT        0x2A
+#define SC_CTRL         0x1D
+#define SC_ALT          0x38
+#define SC_CAPS         0x3A
+#define SC_NUM          0x45
+#define SC_SCROLL       0x46
+#define SC_CURSOR_UP    0x48
+#define SC_CURSOR_DOWN  0x50
+#define SC_CURSOR_LEFT  0x4B
+#define SC_CURSOR_RIGHT 0x4D
+#define SC_PAGE_UP      0x49
+#define SC_PAGE_DOWN    0x51
+#define SC_HOME         0x47
+#define SC_END          0x4F
+#define SC_INS          0x52
+#define SC_DELETE       0x53
+#define SC_F1           0x3B
+#define SC_F2           0x3C
+#define SC_F3           0x3D
+#define SC_F4           0x3E
+#define SC_F5           0x3F
+#define SC_F6           0x40
+#define SC_F7           0x41
+#define SC_F8           0x42
+#define SC_F9           0x43
+#define SC_F10          0x44
+#define SC_F11          0x57
+#define SC_F12          0x58
+#define SC_PAUSE        0x61
+#define SC_GUI          0xDB
+#define SC_PRTSCRN1     0xAA
+#define SC_PRTSCRN2     0xB7
+
+#help_index "Char;Debugging/Raw Output;TextBase Layer/Char"
+//text.raw_flags
+#define RWF_IN_DOLLAR   1
+#define RWF_LAST_DOLLAR 2
+#define RWF_SHOW_DOLLAR 4
+#define RWF_SCROLL      8
+
+public class CTextGlbls
+{
+  I64   raw_col,raw_flags;
+  U8    *raw_scrn_image;
+  I64   rows,cols;              //Use TEXT_ROWS,TEXT_COLS
+  U64   *font,*aux_font;
+  U8    *vga_alias,*vga_text_alias;
+  U8    border_chars[16];
+};
+
+#define FONT_WIDTH      8
+#define FONT_HEIGHT     8
+
+#help_index "Graphics"
+#define GR_WIDTH        640
+#define GR_HEIGHT       480
+
+//z-vals less than zero are in front of scrn and not drawn.
+//we want to shift all Z-vals into a drawable range.
+//GR_Z_ALL is set to half of the Z-range which is an I32.
+#define GR_Z_ALL        (I32_MAX/2)
+
+#help_index "Graphics/Device Contexts"
+//Low 8 bits reserved for flags that go into saved bitmaps
+#define DCF_COMPRESSED          1
+#define DCF_PALETTE             2
+#define DCF_NO_TRANSPARENTS     4 //Can be used to optimized GrBlot().
+
+#define DCF_TRANSFORMATION      0x100
+
+//See DCSymmetrySet() or DCSymmetry3Set()
+#define DCF_SYMMETRY            0x200
+
+//Must be used with DCF_SYMMETRY set also.
+//See ::/Demo/Games/BigGuns.HC
+#define DCF_JUST_MIRROR         0x400
+
+#define DCF_LOCATE_NEAREST      0x800
+#define DCF_DONT_DRAW           0x1000
+#define DCF_ALIAS               0x2000
+#define DCF_SCRN_BITMAP         0x4000
+#define DCF_FILL_NOT_COLOR      0x8000
+#define DCF_RECORD_EXTENTS      0x10000
+#define DCF_ON_TOP              0x20000
+
+//DCSave() flags.
+#define DCSF_COMPRESSED         1
+#define DCSF_PALETTE_GET        2
+
+#define DCS_SIGNATURE_VAL       'DvCS'
+
+class CGrSym
+{
+  I32   sx,sy,sz,pad;
+//Normal of symmetry plane
+  I64   snx,sny,snz;
+};
+
+public class CDC
+{
+  U0    start;
+  CDate cdt;
+  I32   x0,y0,
+        width,width_internal,
+        height,
+        flags;
+  U0    end;
+  CBGR48 palette[COLORS_NUM];
+
+  //public (Change directly)
+  CColorROPU32 color,
+        bkcolor, //Set for use with ROP_COLLISION
+        color2; //Internally used for GrFloodFill()
+  CD3I32 ls; //Light source (should be normalized to 65536).
+
+  //dither_probability_u16 is basically a U16.
+  //It is activated by ROPF_PROBABILITY_DITHER.
+  //0x0000 =100% color.c0
+  //0x8000 =50%  color.c0   50% color.c1
+  //0x10000=100% color.c1
+  //See ::/Demo/Graphics/SunMoon.HC and ::/Demo/Graphics/Shading.HC.
+  U64 dither_probability_u16;
+
+  CDC *brush;
+
+  //Set with DCMat4x4Set().  Free() before setting.
+  I64   *r, //rotation matrix of quads decimal in lo
+        r_norm; //shifted 32 bits.  Used for scaling thick
+
+  //public (Change directly)
+  I32   x,y,z,
+        thick;
+
+  //Can be changed from the default DCTransform()
+  U0    (*transform)(CDC *dc,I64 *x,I64 *y,I64 *z);
+
+  //Can be changed from the default DCLighting()
+  U0    (*lighting)(CDC *dc,CD3I32 *p1,CD3I32 *p2,
+        CD3I32 *p3,CColorROPU32 color);
+
+  //Set by DCSymmetrySet() or DCSymmetry3Set()
+  CGrSym sym;
+
+  I32   cur_x,cur_y,cur_z,pad;
+  I64   collision_cnt;
+
+  I64   nearest_dist,
+        min_x,max_x,min_y,max_y; //Set by DCF_RECORD_EXTENTS (scrn coordinates)
+
+  U32   dc_signature,pad;
+  CTask *mem_task,*win_task;
+  CDC   *alias;
+  U8    *body;
+
+  //Set by DCDepthBufAlloc()
+  I32   *depth_buf;
+  I64   db_z; //private
+#assert !($&7)
+};
+
+#help_index "Devices"
+//VGA Memory
+#define VGAM_GRAPHICS   0xA0000
+#define VGAM_TEXT       0xB8000
+
+//VGA I/O ports
+#define VGAP_ATTR_INDEX         0x03C0
+#define VGAP_ATTR_DATA_WRITE    0x03C0 //alias
+#define VGAP_ATTR_DATA_READ     0x03C1
+#define VGAP_MISC_OUTPUT        0x03C2
+#define VGAP_IDX                0x03C4
+#define VGAP_DATA               0x03C5
+#define VGAP_PALETTE_MASK       0x03C6
+#define VGAP_REG_READ           0x03C7
+#define VGAP_REG_WRITE          0x03C8
+#define VGAP_PALETTE_DATA       0x03C9
+#define VGAP_CRTC_INDEX         0x03D4
+#define VGAP_CRTC_DATA          0x03D5
+#define VGAP_INPUT_STAT         0x03DA
+
+//VGA Registers
+#define VGAR_MAP_MASK           0x02
+
+#help_index "Compression/Piece by Piece"
+#define ARC_BITS_MAX    12
+
+#define CT_NONE         1
+#define CT_7_BIT        2
+#define CT_8_BIT        3
+class CArcEntry
+{
+  CArcEntry *next;
+  U16   basecode;
+  U8    ch,pad;
+  U32   pad;
+};
+
+public class CArcCtrl
+{
+  I64   src_pos,src_size,
+        dst_pos,dst_size;
+  U8    *src_buf,*dst_buf;
+  I64   min_bits,min_table_entry;
+  CArcEntry *cur_entry,*next_entry;
+  I64   cur_bits_in_use,next_bits_in_use;
+  U8    *stk_ptr,*stk_base;
+  I64   free_idx,free_limit,
+        saved_basecode,
+        entry_used,
+        last_ch;
+  CArcEntry compress[1<<ARC_BITS_MAX],
+        *hash[1<<ARC_BITS_MAX];
+};
+
+#help_index "Compression"
+public class CArcCompress
+{
+  I64   compressed_size,expanded_size;
+  U8    compression_type;
+  U0    body;
+};
+
+#define "Char/Input;StdIn"
+//GetStr flags
+#define GSF_SHIFT_ESC_EXIT      1 //This kills task on <SHIFT-ESC>
+#define GSF_WITH_NEW_LINE       2
+
+#define "Char/Operations"
+//Flags for StrUtil and MStrUtil
+#define SUF_REM_CTRL_CHARS      0x001
+#define SUF_REM_LEADING         0x002
+#define SUF_REM_TRAILING        0x004
+#define SUF_REM_SPACES          0x008
+#define SUF_SINGLE_SPACE        0x010
+#define SUF_TO_UPPER            0x020
+#define SUF_TO_LOWER            0x040
+#define SUF_S2T                 0x080
+#define SUF_T2S                 0x100 // Only works with MStrUtil
+#define SUF_SCALE_INDENT        0x200
+#define SUF_SAFE_DOLLAR         0x400
+
+//Flags for StrFind
+#define SFF_IGNORE_CASE         1
+#define SFF_WHOLE_LABELS_BEFORE 2
+#define SFF_WHOLE_LABELS_AFTER  4
+#define SFG_WHOLE_LABELS        (SFF_WHOLE_LABELS_BEFORE|SFF_WHOLE_LABELS_AFTER)
+
+//Flags for LstMatch
+#define LMF_IGNORE_CASE         1
+#define LMF_EXACT               2
+
+#help_index "Keyboard Devices/System"
+#define KDF_HAS_DESCS   1
+class CKeyDevEntry
+{
+  CKeyDevEntry *next,*last;
+  I64   priority,flags;
+  Bool  (*put_key)(I64 ch,I64 sc);
+  Bool  (*put_s)(U8 *st);
+};
+
+class CKeyDevGlbls
+{
+  CKeyDevEntry put_key_head;
+  U0    (**fp_ctrl_alt_cbs)(I64 sc);
+  I64   ctrl_alt_in_irq_flags,
+        **ctrl_alt_ret_addr; //addr of ret addr on stack in kbd irq
+  U8    **ctrl_alt_no_shift_descs,**ctrl_alt_shift_descs,
+        desc[STR_LEN],
+        *hndlr;
+};
+
+#help_index "Snd"
+#help_index "ScrnCast;Snd/AU Files"
+public class CAUData
+{//Fmt of AU files
+  CDate cdt;
+  I8    ona;
+};
+
+class CSndData
+{//Fmt recorded in mem
+  CSndData *next,*last;
+  F64   tS;
+  I8    ona;
+};
+
+public class CScrnCastGlbls
+{
+  CSndData snd_head;
+  CDate t0_now;
+  F64   t0_tS;
+  U8    *print_fmt;
+  CDC   *dc,*dc2_alias;
+  Bool  record,just_audio;
+  I8    ona;
+};
+
+#help_index "Debugging/FunSeg"
+#define FUN_SEG_CACHE_SIZE      256
+class CFunSegCache
+{
+  I64   base,limit;
+  F64   time_stamp;
+  U8    str[1]; //FUN_SEG_CACHE_STR_LEN
+$=64;
+};
+#define FUN_SEG_CACHE_STR_LEN   (sizeof(CFunSegCache)-offset(CFunSegCache.str))
+
+#help_index "Debugging"
+class CMPCrash
+{
+  I64   cpu_num;
+  CTask *task;
+  I64   rip;
+  U8    *msg;
+  I64   msg_num;
+};
+
+public class CDbgGlbls
+{
+  CTask *focus_task;
+  U8    *msg;
+  I64   msg_num;
+  CMPCrash *mp_crash;
+  U8    *int_fault_code,
+        *fix_file_line;
+  CFunSegCache *fun_seg_cache;
+  I64   fun_seg_cache_index;
+  Bool  panic;
+};
+
+#help_index "Boot"
+//Boot related
+#define BOOT_RAM_BASE           0x07C00
+#define BOOT_RAM_LIMIT          0x97000
+#define BOOT_STK_SIZE           BLK_SIZE
+
+#define BOOT_SRC_NULL           0
+#define BOOT_SRC_ROM            1
+#define BOOT_SRC_RAM            2
+#define BOOT_SRC_HARDDRV        3
+#define BOOT_SRC_DVD            4
+
+// In("") StdIn for call to BootHDIns().
+#define STD_DISTRO_DVD_CFG      "TB\nScale2Mem(2048,0x40000)\nT \n\n\n\n"
+
+#help_index "Registry"
+//Registry sys_msg_flags. RegOneTimePopUp()
+#define ARf_FLOODFILL                   0
+#define ARf_CSPRITE_INS_CLIP            1
+#define ARf_PLANAR_SYMMETRY             2
+#define ARf_PSALMODY_JUKEBOX            3
+#define ARf_MESH_ED                     4
+#define ARf_CSPRITE_PTS_RECTANGLES      5
+#define ARf_MANAGE_SLIDER               6
+
+#help_index "Misc/Progress Bars"
+#define PROGRESS_BARS_NUM       4
+#define PROGRESS_DESC_LEN       (64-8-8)
+class CProgress
+{
+  I64   val,max;
+  F64   t0,tf;
+  U8    desc[PROGRESS_DESC_LEN];
+};
+
+#help_index "Char/Operations"
+#define PRTF_PAD_ZERO           0x001
+#define PRTF_LEFT_JUSTIFY       0x002
+#define PRTF_TRUNCATE           0x004
+#define PRTF_COMMA              0x008
+#define PRTF_DOLLAR             0x010
+#define PRTF_SLASH              0x020
+#define PRTF_QUESTION           0x040
+#define PRTF_AUX_FMT_NUM        0x080
+#define PRTF_DECIMAL            0x100
+#define PRTF_NEG                0x200
+#define PRTF_NEG_E              0x400
+#define PRTF_NEG_AUX_FMT_NUM    0x800
+
+#help_index "Misc/Host"
+//Host Operating System
+#define OS_OTHER        0
+#define OS_NATIVE       1
+#define OS_LINUX        2
+#define OS_WINDOWS      3
+//Virtual Machine
+#define VM_OTHER        0
+#define VM_NATIVE       1
+#define VM_VMWARE       2
+#define VM_QEMU         3
+#define VM_VIRTUALBOX   4
+
+#help_index "Registry/Install Registration"
+public class CInsReg
+{
+  Bool  registered;
+  I64   host_os         format "$PURPLE$Install Registration$FG$\n\n"
+                        "Host OS:$LS,D=\"ST_HOST_OSES\"$\n";
+  I64   host_vm         format "Host VM:$LS,D=\"ST_HOST_VMS\"$\n";
+  U8    initials[8]     format "$DA-P,A=\"Your Initials:%s\"$\n";
+  I64   machine_num     format
+                        "$DA-TRM,A=\"This Machine Num (Choose Any):%d\"$\n";
+};
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Kernel/KernelB.HH.HTML b/public/Wb/Home/Src/Kernel/KernelB.HH.HTML new file mode 100755 index 0000000..834fbd6 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KernelB.HH.HTML @@ -0,0 +1,325 @@ + + + + + + + + + + + +
+/*  Kernel ASM symbols.
+KernelB Kernel.PRJ
+KernelB Compiler.PRJ
+KernelB StartOS.HC
+*/
+
+#help_index "Bit"
+#help_file "::/Doc/Bit"
+public _intern IC_BSF I64 Bsf(
+        I64 bit_field_val);//Scan fwd from lowest for 1st set. -1 if not found.
+public _intern IC_BSR I64 Bsr(
+        I64 bit_field_val);//Scan rev from highest for 1st set. -1 if not found.
+public _intern IC_BT Bool Bt(
+        U8 *bit_field,I64 bit); //Bit test.
+public _intern IC_BTC Bool Btc(
+        U8 *bit_field,I64 bit); //Bit test and complement (same as xor with 1).
+public _intern IC_BTR Bool Btr(
+        U8 *bit_field,I64 bit); //Bit test and reset to zero.
+public _intern IC_BTS Bool Bts(
+        U8 *bit_field,I64 bit); //Bit test and set to one.
+public _intern IC_LBTC Bool LBtc(
+        U8 *bit_field,I64 bit); //Locked bit test and complement (xor with 1).
+public _intern IC_LBTR Bool LBtr(
+        U8 *bit_field,I64 bit); //Locked bit test and reset to zero.
+public _intern IC_LBTS Bool LBts(
+        U8 *bit_field,I64 bit); //Locked bit test and set to one.
+public _extern _BEQU Bool BEqu(
+        U8 *bit_field,I64 bit,Bool val);//Set bit equ to val.
+public _extern _BIT_FIELD_EXT_U32 U32 BFieldExtU32(
+        U8 *bit_field,I64 bit,I64 size); //Extract U32 from bit field.
+public _extern _BIT_FIELD_OR_U32 U0 BFieldOrU32(
+        U8 *bit_field,I64 bit,U32 pattern); //Or U32 into bit field.
+public _extern _LBEQU Bool LBEqu(
+        U8 *bit_field,I64 bit,Bool val); //Locked Set bit equ to val.
+
+#help_index "Boot"
+_extern MEM_BOOT_BASE U32 mem_boot_base;
+_extern SYS_BOOT_BLK U32 sys_boot_blk;
+_extern SYS_BOOT_PATCH_TABLE_BASE U32 sys_boot_patch_table_base;
+_extern SYS_BOOT_SRC U32 sys_boot_src;
+_extern SYS_RUN_LEVEL U32 sys_run_level;
+
+#help_index "Call"
+public _extern _CALL I64 Call(U8 *machine_code); //Call addr with no args.
+public _extern _CALLEXTSTR I64 CallExtStr(
+        /*argpop*/ U8 *name,...); //Search sym table for fun and pass it args.
+//Can have any fixed number of arguments.
+public _extern _CALL_IND I64 CallInd(
+        /*argpop*/I64 (*fp_addr)(...),...); //Call with fixed number of args.
+
+#help_index "Call/System Extern Num"
+public _extern SYS_EXTERN_TABLE /*argpop*/
+        I64 (**ext)(...); //Array of fun ptrs.  See Extern Num Definitions
+public _extern _CALLEXTNUM
+        I64 CallExtNum(I64 num,...); //Call ext num with fixed number of args.
+
+#help_index "Char/Conversion"
+public _intern IC_TOUPPER I64 ToUpper(U8 ch); //Cvt char to upper case.
+
+#help_index "Char/Operations"
+public _intern IC_STRLEN I64 StrLen(U8 *st); //String length.
+
+#help_index "Data Types/Circular Queue"
+#help_file "::/Doc/Que"
+public _intern IC_QUE_INIT U0 QueInit(
+        CQue *head); //Init queue head links.
+public _intern IC_QUE_INS U0 QueIns(
+        CQue *entry,CQue *pred);//Insert item into que after predecessor.
+public _intern IC_QUE_INS_REV U0 QueInsRev(
+        CQue *entry,CQue *succ);//Revd insert into que.
+//Ins item into que before successor.
+public _intern IC_QUE_REM U0 QueRem(CQue *entry); //Remove item from queue.
+
+#help_index "I/O;Processor/IO Port"
+public _intern IC_IN_U16 U16 InU16(I64 port); //Read U16 from I/O port.
+public _intern IC_IN_U32 U32 InU32(I64 port); //Read U32 from I/O port.
+public _intern IC_IN_U8 U8 InU8(I64 port); //Read U8 from I/O port.
+public _intern IC_OUT_U16 U0 OutU16(I64 port, I64 val); //Write U16 to I/O port.
+public _intern IC_OUT_U32 U0 OutU32(I64 port, I64 val); //Write U32 to I/O port.
+public _intern IC_OUT_U8  U0 OutU8(I64 port, I64 val); //Write U8 to I/O port.
+public _extern _REP_IN_U16 U0 RepInU16(
+        U8 *buf,I64 cnt,I64 port); //Repeated read U16 from I/O port.
+public _extern _REP_IN_U32 U0 RepInU32(
+        U8 *buf,I64 cnt,I64 port); //Repeated read U32 from I/O port.
+public _extern _REP_IN_U8  U0 RepInU8(
+        U8 *buf,I64 cnt,I64 port); //Repeated read U8 from I/O port.
+public _extern _REP_OUT_U16 U0 RepOutU16(
+        U8 *buf,I64 cnt,I64 port); //Repeated write U16 to I/O port.
+public _extern _REP_OUT_U32 U0 RepOutU32(
+        U8 *buf,I64 cnt,I64 port); //Repeated write U32 to I/O port.
+public _extern _REP_OUT_U8  U0 RepOutU8(
+        U8 *buf,I64 cnt,I64 port); //Repeated write U8 to I/O port.
+
+#help_index "Math"
+public _intern IC_ATAN F64 ATan(F64 d); //Arc Tan (Inverse Tan).
+public _intern IC_ABS F64 Abs(F64 d); //Absolute F64.
+public _intern IC_ABS_I64 I64 AbsI64(I64 i); //Absolute I64.
+public _intern IC_COS F64 Cos(F64 d); //Cosine.
+public _intern IC_MAX_I64 I64 MaxI64(I64 n1,I64 n2); //Max of two I64s.
+public _intern IC_MAX_U64 U64 MaxU64(U64 n1,U64 n2); //Max of two U64s.
+public _intern IC_MIN_I64 I64 MinI64(I64 n1,I64 n2); //Min of two I64s.
+public _intern IC_MIN_U64 U64 MinU64(U64 n1,U64 n2); //Min of two U64s.
+public _intern IC_MOD_U64 U64 ModU64(U64 *q,U64 d); //Div and return U64 Modulo.
+public _intern IC_SIGN_I64 I64 SignI64(I64 i); //Sign of I64: -1,0,1.
+public _intern IC_SIN F64 Sin(F64 d); //Sine.
+public _intern IC_SQR F64 Sqr(F64 d); //Square of F64.
+public _intern IC_SQR_I64  I64 SqrI64(I64 i); //Square of I64.
+public _intern IC_SQR_U64  U64 SqrU64(U64 i); //Square of U64.
+public _intern IC_SQRT F64 Sqrt(F64 d); //Square head of F64.
+public _intern IC_SWAP_I64 U0 SwapI64(
+        I64 *n1,I64 *n2); //Swap two I64s. Not atomic.
+public _intern IC_SWAP_U16 U0 SwapU16(
+        U16 *n1,U16 *n2); //Swap two U16s. Not atomic.
+public _intern IC_SWAP_U32 U0 SwapU32(
+        U32 *n1,U32 *n2); //Swap two U32s. Not atomic.
+public _intern IC_SWAP_U8  U0 SwapU8(
+        U8 *n1,U8 *n2); //Swap two U8s. Not atomic.
+public _intern IC_TAN F64 Tan(F64 d); //Tangent.
+public _intern IC_TO_BOOL Bool ToBool(I64 i); //Convert to Boolean.
+public _intern IC_TO_F64 F64 ToF64(I64 i); //Convert to F64.
+public _intern IC_TO_I64 I64 ToI64(F64 d);  //Convert to I64. Truncates.
+public _extern _ARG F64 Arg(F64 x,F64 y); //Polar coordinate angle.
+public _extern _CEIL F64 Ceil(F64 d); //Ceiling of F64.
+public _extern _CLAMP_I64 I64 ClampI64(
+        I64 num,I64 lo,I64 hi); //Clamp to I64 [] range.
+public _extern _CLAMP_U64 U64 ClampU64(
+        U64 num,U64 lo,U64 hi); //Clamp to U64 [] range.
+public _extern _EXP F64 Exp(F64 d); //Exponential function.
+_extern _FCLEX U0 Fclex();
+_extern _FLDCW U0 Fldcw(U16 w);
+public _extern _FLOOR F64 Floor(F64 d); //Floor of F64.
+_extern _FSTCW U16 Fstcw();
+_extern _FSTSW U16 Fstsw();
+public _extern _LN  F64 Ln(F64 d); //Logarithm.
+public _extern _LOG10 F64 Log10(F64 d); //Log base 10.
+public _extern _LOG2 F64 Log2(F64 d); //Log base 2.
+public _extern _POW F64 Pow(F64 base,F64 power); //F64 base to a power.
+public _extern _POW10 F64 Pow10(F64 d); //Ten to the dth power.
+public _extern _ROUND F64 Round(F64 d); //Round F64 to whole number.
+public _extern _SIGN F64 Sign(F64 d); //Sign of F64: -1,0,1
+public _extern _TRUNC F64 Trunc(F64 d); //Truncate F64.
+
+#help_index "Math/CD3;Data Types/CD3"
+#help_file "::/Doc/D3"
+public _extern _D3_ADD CD3 *D3Add(CD3 *sum,CD3 *d1,CD3 *d2); //sum=d1+d2
+public _extern _D3_ADD_EQU CD3 *D3AddEqu(CD3 *sum,CD3 *d); //sum+=d
+public _extern _D3_COPY CD3 *D3Copy(CD3 *dst,CD3 *src); //dst=src
+public _extern _D3_CROSS CD3 *D3Cross(CD3 *prod,CD3 *d1,CD3 *d2); //prod=d1xd2
+public _extern _D3_DIST F64 D3Dist(CD3 *d1,CD3 *d2); //Distance
+public _extern _D3_DIST_SQR F64 D3DistSqr(CD3 *d1,CD3 *d2); //Distance Squared
+public _extern _D3_DIV CD3 *D3Div(CD3 *quot,CD3 *d,F64 s); //quot=d/s
+public _extern _D3_DIV_EQU CD3 *D3DivEqu(CD3 *quot,F64 s); //quot/=s
+public _extern _D3_DOT F64 D3Dot(CD3 *d1,CD3 *d2); //d1 dot d2
+public _extern _D3_EQU CD3 *D3Equ(
+        CD3 *dst,F64 x=0,F64 y=0,F64 z=0); //dst=(x,y,z)
+public _extern _D3_MUL CD3 *D3Mul(CD3 *prod,F64 s,CD3 *d); //prod=s*d
+public _extern _D3_MUL_EQU CD3 *D3MulEqu(CD3 *prod,F64 s); //prod*=s
+public _extern _D3_NORM F64 D3Norm(CD3 *d); //Norm
+public _extern _D3_NORM_SQR F64 D3NormSqr(CD3 *d); //Norm Squared
+public _extern _D3_SUB CD3 *D3Sub(CD3 *diff,CD3 *d1,CD3 *d2); //diff=d1-d2
+public _extern _D3_SUB_EQU CD3 *D3SubEqu(CD3 *diff,CD3 *d); //diff-=d
+public _extern _D3_UNIT CD3 *D3Unit(CD3 *d); //To unit vect
+public _extern _D3_ZERO CD3 *D3Zero(CD3 *dst); //To zero
+
+#help_index "Memory"
+public _extern _MEMCMP I64 MemCmp(
+        U8 *ptr1,U8 *ptr2,I64 cnt); //Compare chunk of memory.
+public _extern _MEMCPY U8 *MemCpy(
+        U8 *dst,U8 *src,I64 cnt); //Copy chunk of memory. Only goes fwd.
+public _extern _MEMSET U8 *MemSet(
+        U8 *dst,I64 val,I64 cnt); //Set chunk of U8s to value.
+public _extern _MEMSET_I64 I64 *MemSetI64(
+        I64 *dst,I64 val,I64 I64cnt); //Set chunk of I64s to value.
+public _extern _MEMSET_U16 U16 *MemSetU16(
+        U16 *dst,I64 val,I64 U16cnt); //Set chunk of U16s to value.
+public _extern _MEMSET_U32 U32 *MemSetU32(
+        U32 *dst,I64 val,I64 U32cnt); //Set chunk of U32s to value.
+public _extern _MEMSET U8 *MemSetU8(
+        U8 *dst,I64 val,I64 U8cnt); //Set chunk of U8s to value.
+_extern SYS_HEAP_DBG_FLAG       U8 sys_heap_dbg;
+_extern SYS_HEAP_INIT_FLAG      U8 sys_heap_init_flag;
+_extern SYS_HEAP_INIT_VAL       U8 sys_heap_init_val;
+_extern SYS_MEM_INIT_FLAG       U8 sys_mem_init_flag;
+_extern SYS_MEM_INIT_VAL        U8 sys_mem_init_val;
+_extern SYS_STAFF_MODE_FLAG     U8 sys_staff_mode_flag;
+_extern SYS_VAR_INIT_FLAG       U8 sys_var_init_flag;
+_extern SYS_VAR_INIT_VAL        U8 sys_var_init_val;
+
+#help_index "Memory/BlkPool"
+public _extern SYS_CODE_BP CBlkPool *sys_code_bp; //System's BlkPool for code.
+public _extern SYS_DATA_BP CBlkPool *sys_data_bp; //System's BlkPool for data.
+
+#help_index "Memory/Info"
+_extern MEM_HEAP_BASE   U8 *mem_heap_base;
+_extern MEM_HEAP_LIMIT  U8 *mem_heap_limit;
+_extern MEM_MAPPED_SPACE U8 *mem_mapped_space;
+_extern MEM_PHYSICAL_SPACE U8 *mem_physical_space;
+
+#help_index "Messages;Windows"
+public _extern SYS_FOCUS_TASK CTask *sys_focus_task; //Current focus task.
+
+#help_index "Misc"
+public _extern SYS_COMPILE_TIME
+        CDate sys_compile_time; //Date and time kernel was compiled.
+_extern SYS_CTRL_ALT_FLAGS
+        I64 sys_ctrl_alt_flags[1]; //Should be semiphores?
+
+#help_index "Misc/Progress Bars"
+public _extern SYS_PROGRESS1 I64 progress1; //Current progress 1.
+public _extern SYS_PROGRESS1_DESC
+        U8 progress1_desc[PROGRESS_DESC_LEN]; //Progress 1 desc.
+public _extern SYS_PROGRESS1_MAX I64 progress1_max; //Progress 1 max.
+public _extern SYS_PROGRESS1_T0 F64 progress1_t0; //Progress 1 start time.
+public _extern SYS_PROGRESS1_TF F64 progress1_tf; //Progress 1 end time.
+public _extern SYS_PROGRESS2 I64 progress2; //Current progress 2.
+public _extern SYS_PROGRESS2_DESC
+        U8  progress2_desc[PROGRESS_DESC_LEN]; //Progress 2 desc.
+public _extern SYS_PROGRESS2_MAX I64 progress2_max; //Progress 2 max.
+public _extern SYS_PROGRESS2_T0 F64 progress2_t0; //Progress 2 start time.
+public _extern SYS_PROGRESS2_TF F64 progress2_tf; //Progress 2 end time.
+public _extern SYS_PROGRESS3 I64 progress3; //Current progress 3.
+public _extern SYS_PROGRESS3_DESC
+        U8  progress3_desc[PROGRESS_DESC_LEN]; //Progress 3 desc.
+public _extern SYS_PROGRESS3_MAX I64 progress3_max; //Progress 3 max.
+public _extern SYS_PROGRESS3_T0 F64 progress3_t0; //Progress 3 start time.
+public _extern SYS_PROGRESS3_TF F64 progress3_tf; //Progress 3 end time.
+public _extern SYS_PROGRESS4 I64 progress4; //Current progress 4.
+public _extern SYS_PROGRESS4_DESC
+        U8  progress4_desc[PROGRESS_DESC_LEN]; //Progress 4 desc.
+public _extern SYS_PROGRESS4_MAX I64 progress4_max; //Progress 4 max.
+public _extern SYS_PROGRESS4_T0 F64 progress4_t0; //Progress 4 start time.
+public _extern SYS_PROGRESS4_TF F64 progress4_tf; //Progress 4 end time.
+public _extern SYS_PROGRESSES
+        CProgress sys_progresses[PROGRESS_BARS_NUM]; //All progress bars.
+
+#help_index "MultiCore"
+#help_file "::/Doc/MultiCore"
+public _extern SYS_CPU_STRUCTS CCPU *cpu_structs; //Gs points to cur CCPU.
+public _extern SYS_MP_CNT I64 mp_cnt; //Count of cores
+_extern SYS_MP_CNT_INITIAL I64 mp_cnt_initial; //only used during Core0StartMP
+_extern SYS_MP_CNT_LOCK I64 mp_cnt_lock;
+_extern SYS_SEMAS CSema sys_semas[SEMA_SEMAS_NUM];
+
+#help_index "MultiCore;Processor"
+public _intern IC_GS CCPU *Gs(); //GS points to current CCPU.
+
+#help_index "PCI"
+public _extern SYS_PCI_BUSES U16 sys_pci_busses; //Number of PCI buses.
+
+#help_index "Processor"
+public _intern IC_CARRY I64 Carry(); //See ::/Demo/Carry.HC
+public _intern IC_GET_RAX I64 GetRAX(); //Get RAX register value.
+public _intern IC_GET_RBP U8 *GetRBP(); //Get RBP register value.
+public _intern IC_GET_RFLAGS I64 GetRFlags(); //Get RFlags register value.
+public _intern IC_GET_RSP U8 *GetRSP(); //Get RSP register value.
+public _intern IC_POP I64 Pop(); //Pop value from stk.
+public _intern IC_PUSH U0 Push(I64 d); //Push value on stk.
+public _intern IC_SET_RAX U0 SetRAX(I64 d); //Set RAX register value.
+public _intern IC_SET_RBP U0 SetRBP(U8 *d); //Set RBP register value.
+public _intern IC_SET_RFLAGS U0 SetRFlags(I64 d); //Set RFlags register value.
+public _intern IC_SET_RSP U0 SetRSP(U8 *d); //Set RSP register value.
+public _extern _CPUID U0 CPUId(
+        U32 rax,CRAXRBCRCXRDX *res); //Do CPUID inst.
+public _extern _LXCHG_I64 I64 LXchgI64(I64 *dst,I64 d); //Locked eXchange I64s.
+public _extern _LXCHG_U16 U16 LXchgU16(U16 *dst,U16 d); //Locked eXchange U16s.
+public _extern _LXCHG_U32 U32 LXchgU32(U32 *dst,U32 d); //Locked eXchange U32s.
+public _extern _LXCHG_U8  U8 LXchgU8(U8 *dst,U8 d); //Locked eXchange U8s.
+public _extern _SET_MSR U0 SetMSR(
+        I64 model_specific_reg,I64 val); //Model Specific Reg See MSRs.
+public _extern _SYS_HLT U0 SysHlt(); //Loops doing HLT inst.
+public _extern _XCHG_I64 I64 XchgI64(I64 *dst,I64 d); //eXchange I64s.
+public _extern _XCHG_U16 U16 XchgU16(U16 *dst,U16 d); //eXchange U16s.
+public _extern _XCHG_U32 U32 XchgU32(U32 *dst,U32 d); //eXchange U32s.
+public _extern _XCHG_U8  U8 XchgU8(U8 *dst,U8 d); //eXchange U8s.
+_extern SYS_GDT CGDT sys_gdt;
+
+#help_index "Processor/Cache;Memory/Cache"
+public _intern IC_CLFLUSH U0 CLFlush(U8 *a); //Flush cache line inst.
+public _extern SYS_CACHE_LINE_WIDTH
+        I64 sys_cache_line_width; //CPU's Cache line width.
+
+#help_index "Processor/Page Tables;Memory/Page Tables"
+public _intern IC_INVLPG
+        U0 InvlPg(U8 *a); //Invalidate page at addr inst.
+public _extern MEM_PAGE_SIZE U64 mem_page_size;
+
+#help_index "Task;Processor"
+public _intern IC_FS CTask *Fs(); //FS seg reg points to the current CTask.
+
+#help_index "Time/CPU Cycles"
+#help_file "::/Doc/TimeCycles"
+public _intern IC_RDTSC I64 GetTSC(); //Get time stamp counter.
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Kernel/KernelC.HH.HTML b/public/Wb/Home/Src/Kernel/KernelC.HH.HTML new file mode 100755 index 0000000..2cebf28 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KernelC.HH.HTML @@ -0,0 +1,799 @@ + + + + + + + + + + + +
+#help_index "AutoComplete"
+#help_file "::/Doc/AutoComplete"
+public extern CAutoCompleteGlbls ac;
+
+#help_index "AutoComplete/Dictionary"
+public extern CAutoCompleteDictGlbls acd;
+
+#help_index "Bit"
+public extern I64 BCnt(I64 d);
+public extern U8 *rev_bits_table,*set_bits_table;
+
+#help_index "Boot"
+#help_file "::/Doc/Boot"
+public extern U0 Reboot();
+
+#help_index "Call"
+public argpop extern I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size,
+        /*argpop*/I64 (*fp_addr)(...),...);
+//fp_addr can have any fixed number of arguments.
+
+#help_index "Call/FarCall32"
+public _extern _FAR_CALL32 Bool FarCall32(U0 (*fp_addr)());//Not reentrant
+public _extern C32_EAX U32 c32_eax;
+public _extern C32_EBX U32 c32_ebx;
+public _extern C32_ECX U32 c32_ecx;
+public _extern C32_EDI U32 c32_edi;
+public _extern C32_EDX U32 c32_edx;
+public _extern C32_EFLAGS U32 c32_eflags;
+public _extern C32_ESI U32 c32_esi;
+
+#help_index "Char/BitMaps"
+public extern U32 char_bmp_alpha[16],char_bmp_alpha_numeric[16],
+char_bmp_alpha_numeric_no_at[16],       char_bmp_word[16],
+char_bmp_dec_numeric[16],               char_bmp_hex_numeric[16],
+char_bmp_white_space[16],               char_bmp_non_eol_white_space[16],
+char_bmp_zero_cr_nl_cursor[16], char_bmp_zero_tab_cr_nl_cursor[16],
+char_bmp_zero_tab_cr_nl_cursor_dollar[16],
+char_bmp_macro[16],                     char_bmp_printable[16],
+char_bmp_displayable[16],               char_bmp_safe_dollar[16],
+char_bmp_filename[16],                  char_bmp_non_eol[16];
+
+#help_index "Char/Conversion"
+public extern U8 *Char2KeyName(I64 ch,Bool include_ctrl=TRUE);
+public extern I64 Char2ScanCode(I64 ch,I64 sc_flags=0);
+public extern U8 ScanCode2Char(I64 sc);
+public extern U8 *ScanCode2KeyName(I64 sc);
+public extern F64 Str2F64(U8 *src,U8 **_end_ptr=NULL);
+public extern I64 Str2I64(U8 *st,I64 radix=10,U8 **_end_ptr=NULL);
+public extern U8 *StrScan(U8 *src,U8 *fmt,...);
+
+#help_index "Char/Conversion;Time/Date/CDate;Date/CDate"
+public extern CDate Str2Date(U8 *src);
+
+#help_index "Char/Flags"
+public extern U0 ScanFlags(U8 *_dst_flags,U8 *lst,U8 *src);
+public extern U8 *StrPrintFlags(U8 *dst,U8 *lst,I64 flags);
+
+#help_index "Char/Lists"
+public extern I64 LstMatch(U8 *needle, U8 *haystack_lst,I64 flags=0);
+public extern U8 *LstSub(I64 sub, U8 *lst);
+
+#help_index "Char/Operations"
+public extern U8 *MStrPrint(U8 *fmt,...);
+public extern U8 *MStrUtil(U8 *src,I64 flags,F64 indent_scale_factor=0);
+public extern U8 *ScaleIndent(U8 *src,F64 indent_scale_factor);
+public extern I64 Spaces2Tabs(U8 *dst,U8 *src);
+public _extern _STRCMP I64 StrCmp(U8 *st1,U8 *st2);
+public _extern _STRCPY U0 StrCpy(U8 *dst,U8 *src);
+public extern U8 *StrFind(U8 *needle,U8 *haystack_str,I64 flags=0);
+public extern U8 *StrFirstOcc(U8 *src,U8 *marker);
+public extern U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL);
+public _extern _STRICMP I64 StrICmp(U8 *st1,U8 *st2);
+public _extern _STRIMATCH U8 *StrIMatch(U8 *needle,U8 *haystack_str);
+public extern U8 *StrLastOcc(U8 *src,U8 *marker);
+public extern U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL);
+public _extern _STRMATCH U8 *StrMatch(U8 *needle,U8 *haystack_str);
+public _extern _STRNCMP I64 StrNCmp(U8 *st1,U8 *st2,I64 n);
+public _extern _STRNICMP I64 StrNICmp(U8 *st1,U8 *st2,I64 n);
+public extern I64 StrOcc(U8 *src, U8 ch);
+public extern U8 *StrPrint(U8 *dst,U8 *fmt,...);
+public extern U8 *StrPrintJoin(U8 *dst,U8 *fmt,I64 argc,I64 *argv);
+public extern U8 *StrUtil(U8 *_src,I64 flags);
+public extern U8 *Tabs2Spaces(U8 *src);
+public extern Bool WildMatch(U8 *test_str,U8 *wild_str);
+
+#help_index "Char/Operations;Memory"
+public extern U8 *CatPrint(U8 *dst,U8 *fmt,...);
+
+#help_index "Char/Operations;Memory/Adam Heap"
+public extern U8 *AStrNew(U8 *buf);
+
+#help_index "Char/Operations;Memory/Heap"
+public extern U8 *StrNew(U8 *buf,CTask *mem_task=NULL);
+
+#help_index "Char/Output;StdOut"
+public extern U0 GetOutOfDollar();
+public extern Bool IsSilent();
+public extern U0 Print(U8 *fmt,...);
+public extern U0 PrintErr(U8 *fmt,...);
+public extern U0 PrintWarn(U8 *fmt,...);
+public extern U0 PutChars(U64 ch);
+extern U0 PutHex(I64 num,I64 width);
+public extern U0 PutKey(I64 ch=0,I64 sc=0);
+extern U0 PutS(U8 *st); //Use Print()
+public extern Bool Silent(Bool val=ON);
+extern U8 *StrPrintHex(U8 *dst,I64 num;I64 width);
+
+#help_index "Char;Debugging/Raw Output;TextBase Layer/Char"
+public extern CTextGlbls text;
+
+#help_index "Compiler/Lex"
+public extern U0 HashSrcFileSet(CCmpCtrl *cc,
+        CHashSrcSym *h,I64 line_num_offset=0);
+
+#help_index "Compiler;Cmd Line (Typically)"
+extern U8 *Load(U8 *filename,I64 ld_flags=0,
+        CBinFile *bfh_addr=INVALID_PTR); //INVALID_PTR=don't care what load addr
+
+#help_index "Compression"
+public extern CArcCompress *CompressBuf(U8 *src,I64 size,CTask *mem_task=NULL);
+public extern U8 *ExpandBuf(CArcCompress *arc,CTask *mem_task=NULL);
+
+#help_index "Compression/Piece by Piece"
+public extern U0 ArcCompressBuf(CArcCtrl *c);
+public extern U0 ArcCtrlDel(CArcCtrl *c);
+public extern CArcCtrl *ArcCtrlNew(Bool expand,I64 compression_type=CT_8_BIT);
+public extern U0 ArcExpandBuf(CArcCtrl *c);
+public extern Bool ArcFinishCompression(CArcCtrl *c);
+
+#help_index "Data Types/Circular Queue"
+public extern I64       QueCnt(CQue *head);
+public extern CQue      *QueCopy(CQue *head,CTask *mem_task=NULL);
+public extern U0        QueDel(CQue *head,Bool querem=FALSE);
+public extern I64       QueSize(CQue *head);
+
+#help_index "Data Types/Fifo"
+public extern I64       FifoI64Cnt(CFifoI64 *f);
+public extern U0        FifoI64Del(CFifoI64 *f);
+public extern U0        FifoI64Flush(CFifoI64 *f);
+public extern Bool      FifoI64Ins(CFifoI64 *f,I64 q);
+public extern CFifoI64  *FifoI64New(I64 size,CTask *mem_task=NULL);
+public extern Bool      FifoI64Peek(CFifoI64 *f,I64 *_q);
+public extern Bool      FifoI64Rem(CFifoI64 *f,I64 *_q);
+public extern I64       FifoU8Cnt(CFifoU8 *f);
+public extern U0        FifoU8Del(CFifoU8 *f);
+public extern U0        FifoU8Flush(CFifoU8 *f);
+public extern Bool      FifoU8Ins(CFifoU8 *f,U8 b);
+public extern CFifoU8   *FifoU8New(I64 size,CTask *mem_task=NULL);
+public extern Bool      FifoU8Peek(CFifoU8 *f,U8 *_b);
+public extern Bool      FifoU8Rem(CFifoU8 *f,U8 *_b);
+
+#help_index "Data Types/Linked List"
+public extern I64       LinkedLstCnt(U8 **_lst);
+public extern U8        *LinkedLstCopy(U8 **_lst,CTask *mem_task=NULL);
+public extern U0        LinkedLstDel(U8 **_lst);
+public extern I64       LinkedLstSize(U8 **_lst);
+
+#help_index "Data Types/Queue Vector"
+public extern U0        QueVectU8Del(CQueVectU8 *v);
+public extern I64       QueVectU8Get(CQueVectU8 *v,I64 idx);
+public extern CQueVectU8 *QueVectU8New(I64 min_idx=0);
+public extern U0        QueVectU8Put(CQueVectU8 *v,I64 idx,U8 ch);
+
+#help_index "Debugging"
+public extern U8 *Caller(I64 num=1);
+public extern Bool ChkCodePtr(U8 *ptr);
+public extern Bool ChkOnStk(U8 *ptr,CTask *task=NULL);
+public extern Bool ChkPtr(U8 *ptr);
+public extern Bool IsSingleUser();
+public extern Bool IsSysDbg();
+public extern Bool SingleUser(Bool val);
+public extern Bool SysDbg(Bool val);
+public extern U8 *TaskCaller(CTask *task=NULL,
+        I64 num=0,Bool saved_context=FALSE);
+public extern I64 UnusedStk(CTask *task=NULL);
+public extern CDbgGlbls dbg;
+
+#help_index "Debugging/Debugger"
+public extern Bool B(U8 *addr,CTask *task=NULL,Bool live=TRUE) //Toggle bpt.
+public extern I64 B2(CTask *task=NULL,Bool live=TRUE);
+extern CBpt *BptFind(U8 *needle_addr,CTask *haystack_task=NULL,Bool rem=FALSE);
+public extern Bool BptR(U8 *addr,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE);
+public extern Bool BptS(U8 *addr,CTask *task=NULL,Bool live=TRUE);
+public extern Bool DbgMode(Bool val);
+public extern Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0);
+public extern Bool EdLite(U8 *filename,I64 num=1,I64 edf_dof_flags=0);
+extern Bool EdLiteFileLine(U8 *fl_file_line,I64 edf_dof_flags=0);
+public extern Bool Fix(I64 edf_dof_flags=0);
+public extern U0 FixSet(U8 *filename,I64 line);
+public extern U0 G(U8 *ms=INVALID_PTR,CTask *task=NULL);
+public extern U0 G2(U8 *ms=INVALID_PTR,CTask *task=NULL);
+public extern Bool IsDbgMode();
+public extern U0 S(U8 *ms=INVALID_PTR,CTask *task=NULL);
+
+#help_index "Debugging/Debugger;DolDoc/Cmd Line (Typically);"\
+        "Cmd Line (Typically);Help System"
+public extern Bool Man(U8 *st,I64 edf_dof_flags=0);
+
+#help_index "Debugging/Dump"
+public extern U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL);
+public extern U0 D(U8 *addr,I64 cnt=0x80,Bool show_offset=TRUE);
+public extern U0 Da(U8 **addr,I64 cnt=0x10);
+public extern U0 Dm(U8 *addr,I64 cnt=0x80);
+public extern U0 Dr(CTask *task=NULL);
+public extern U0 StkRep(CTask *task=NULL);
+extern I64 *TaskRegAddr(CTask *task,I64 reg_num);
+
+#help_index "Debugging/FunSeg"
+#help_file "::/Doc/DbgFunSeg"
+public extern Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL);
+public extern U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL);
+public extern U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL);
+public extern I64 SrcLineNum(U8 *addr,I64 cnt=1);
+
+#help_index "Debugging/FunSeg;Hash/System"
+public extern CHash *FunSegFind(U8 *addr,I64 *_offset);
+
+#help_index "Debugging/Raw Output"
+public extern Bool IsRaw();
+public extern Bool Raw(Bool val);
+public extern U0 RawD(I64 mS=100,U8 *addr,I64 cnt=0x80);
+public extern U0 RawDm(I64 mS=100,U8 *addr,I64 cnt=0x80);
+extern U0 RawDr(CTask *task=NULL);
+public extern U0 RawPrint(I64 mS=100,U8 *fmt,...);
+public extern U0 RawPutChar(I64 ch);
+public extern U0 VGAFlush();
+
+#help_index "Debugging;Debugging/Debugger"
+public extern U0 Dbg(U8 *msg=NULL,I64 msg_num=0);
+public extern U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE);
+
+#help_index "Define;Char/Define"
+#help_file "::/Doc/Define"
+public extern U8 *Define(U8 *dname);
+public extern CHashDefineStr *DefineLoad(U8 *dname,U8 *st);
+public extern U0 DefinePrint(U8 *dname,U8 *src,...);
+
+#help_index "Define;Char/Define;Char/Lists"
+public extern I64 DefineCnt(U8 *dname);
+public extern CHashDefineStr *DefineLstLoad(U8 *dname,U8 *lst);
+public extern I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0);
+public extern U8 *DefineSub(I64 sub,U8 *dname);
+
+#help_index "Devices;Memory/Page Tables"
+public extern U8 *Mem32DevAlloc(I64 size,I64 alignment);
+public extern U0 Mem32DevFree(U8 *base);
+public extern U8 *Mem64DevAlloc(I64 *_pages1Gig);
+public extern U0 Mem64DevFree(U8 *base,I64 pages1Gig);
+public extern CDevGlbls dev;
+
+#help_index "DolDoc/Clip"
+public extern CDoc *sys_clip_doc;
+
+#help_index "DolDoc/Task;StdOut/Task"
+#help_file "::/Doc/StdOutTask"
+extern CDoc *(*fp_doc_put)(CTask *task=NULL);
+
+#help_index "Exceptions"
+public extern U0 Break();
+public extern Bool BreakLock(CTask *task=NULL);
+public extern Bool BreakUnlock(CTask *task=NULL);
+public extern U0 PutExcept(Bool catch_it=TRUE);
+extern U0 SysTry(U8 *start_label,U8 *skip_label);
+extern U0 SysUntry();
+public extern U0 throw(I64 ch=0,Bool no_log=FALSE);
+
+#help_index "File/CD DVD"
+public extern U0 DVDImageRead(U8 dvd_drv_let,U8 *out_name);
+public extern U0 DVDImageWrite(U8 dvd_drv_let,
+        U8 *in_name=NULL,I64 media_type=MT_DVD);
+
+#help_index "File/CFile"
+public extern Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+public extern Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+public extern U0 FClose(CFile *f);
+public extern CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0);
+public extern I64 FSize(CFile *f);
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+public extern Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE);
+public extern I64 Del(U8 *files_find_mask,Bool make_mask=FALSE,
+        Bool del_dir=FALSE,Bool print_msg=TRUE);
+public extern I64 Dir(U8 *files_find_mask="*",Bool full=FALSE);
+public extern Bool DirMk(U8 *filename,I64 entry_cnt=0);
+public extern Bool Drv(U8 drv_let);
+public extern U0 DskChg(U8 drv_let=0);
+public extern U0 HomeSet(U8 *dirname);
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically);Install"
+public extern Bool DrvMap(U8 drv_let,CDrv *dv);
+
+#help_index "File/FileNames"
+extern CDirEntry *Cd2DirEntry(CDirEntry *tmpde,U8 *abs_name);
+public extern U8 *DirCur(CTask *task=NULL,CTask *mem_task=NULL);
+public extern U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL);
+public extern U8 *DirNameAbs(U8 *dirname);
+public extern CBlkDev *DrvIsWritable(U8 drv_let=0,Bool except=FALSE);
+public extern U8 *ExtChg(U8 *filename,U8 *extension);
+public extern U8 *ExtDft(U8 *filename,U8 *extension);
+public extern U8 *FileExtDot(U8 *src);
+public extern U8 *FileExtRem(U8 *src,U8 *dst=NULL);
+public extern U8 *FileNameAbs(U8 *filename,I64 fuf_flags=0);
+public extern Bool FileNameChk(U8 *filename);
+public extern Bool FilesFindMatch(U8 *_test_name,
+        U8 *files_find_mask,I64 fuf_flags=0);
+public extern Bool IsDir(U8 *dir_name);
+public extern Bool IsDotC(U8 *filename);
+public extern Bool IsDotZ(U8 *filename);
+public extern U0 PutDirLink(U8 *dirname,U8 *full_name=NULL);
+public extern U0 PutFileLink(U8 *filename,U8 *full_name=NULL,
+        I64 line=0,Bool plain_text=FALSE);
+public extern U0 ToFileLine(U8 *_fl_file_line,U8 **_filename,I64 *_linenum);
+public extern U8 *ToggleZorNotZ(U8 *name);
+
+#help_index "File/FileNames;Misc"
+public extern U8 *FileNameTmpTxt();
+
+#help_index "File/Internal"
+public extern U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE);
+public extern CDirContext *DirContextNew(U8 *mask,
+        Bool make_mask=FALSE,Bool make_dirs=FALSE,Bool no_mask=FALSE);
+public extern Bool DirNew(CDrv *dv,U8 *cur_dir,
+        CDirEntry *tmpde,Bool free_old_chain=TRUE);
+extern I64 FileAttr(U8 *name,I64 old_attr=0);
+
+#help_index "File/Low Level"
+#help_file "::/Doc/FileLowLevel"
+public extern CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE);
+public extern U0 BlkDevDel(CBlkDev *bd);
+public extern Bool BlkDevLock(CBlkDev *bd);
+public extern CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type);
+public extern Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE);
+public extern U0 BlkDevsRelease();
+public extern Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+public extern Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+public extern U0 BlkWriteZero(CDrv *dv,I64 blk,I64 cnt);
+public extern I64 Clus2Blk(CDrv *dv,I64 c);
+public extern I64 ClusAlloc(CDrv *dv,I64 c=0,
+        I64 cnt=1,Bool contiguous=FALSE);
+public extern I64 ClusBlkRead(CDrv *dv,U8 *buf,I64 c,I64 blks);
+public extern I64 ClusBlkWrite(CDrv *dv,U8 *buf,I64 c,I64 blks);
+public extern I64 ClusNumNext(CDrv *dv,I64 c,I64 cnt=1);
+public extern I64 ClusRead(CDrv *dv,U8 *buf,I64 c,I64 cnt);
+public extern I64 ClusWrite(CDrv *dv,U8 *buf,I64 c,I64 cnt);
+extern Bool CopySingle(U8 *f1,U8 *f2); //Just one file
+public extern U8 Drv2Let(CDrv *dv=NULL);
+public extern CDrv *DrvChk(CDrv *dv,Bool except=TRUE);
+public extern U0 DrvDel(CDrv *dv);
+public extern Bool DrvLock(CDrv *dv);
+public extern CDrv *DrvMakeFreeSlot(U8 drv_let);
+public extern U8 *DrvModelNum(U8 drv_let=0);
+public extern U8 DrvNextFreeLet(U8 first_drv_let='C');
+public extern U8 *DrvSerialNum(U8 drv_let=0);
+public extern U8 DrvTextAttrGet(U8 drv_let=0);
+public extern Bool DrvUnlock(CDrv *dv,Bool rst=FALSE);
+public extern U0 DrvsRelease();
+extern U0 FAT32FreeClus(CDrv *dv,I64 c);
+public extern CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE);
+public extern I64 Let2BlkDevType(U8 drv_let);
+public extern CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE);
+public extern U8 Let2Let(U8 drv_let=0);
+extern I64 Name2DirClus(CDrv *dv,U8 *dirname);
+extern I64 Name2ParentDirClus(CDrv *dv,U8 *dirname);
+extern U0 RedSeaFreeClus(CDrv *dv,I64 c,I64 cnt);
+
+#help_index "File/Program Routines"
+public extern U0 DirEntryDel(CDirEntry *tmpde);
+public extern U0 DirEntryDel2(CDirEntry *tmpde);
+public extern U0 DirTreeDel(CDirEntry *tmpde);
+public extern U0 DirTreeDel2(CDirEntry *tmpde);
+public extern Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0);
+public extern U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL);
+public extern I64 FileWrite(U8 *filename,
+        U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0);
+
+#help_index "File/Program Routines;File/FileNames"
+public extern CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0);
+
+#help_index "File/System"
+public extern CATARep *ATAIDDrvs(CATARep *head,CATARep **_ata_drv,
+        CATARep **_atapi_drv);
+extern CBlkDev *ATAMount(U8 first_drv_let,
+        I64 type,I64 base0,I64 base1,I64 unit);
+extern Bool ATAPIStartStop(CBlkDev *bd,F64 timeout,Bool start);
+extern I64 ATAProbe(I64 base0,I64 base1,I64 unit);
+extern U0 ATAReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt);
+extern U0 ATAWriteBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt);
+extern I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN,
+        Bool whole_drv,Bool make_free);
+extern U0 DskCacheInit(I64 size_in_U8s);
+public extern U0 DskCacheInvalidate(CDrv *dv);
+public extern I64 MountIDEAuto();
+public extern CBlkDevGlbls blkdev;
+
+#help_index "Graphics/Color"
+extern U0 (*fp_set_std_palette)();
+public extern U8 *Color2Str(U8 *buf,CColorROPU32 c);
+public extern CColorROPU16 Str2ColorU16(U8 *st);
+public extern CColorROPU32 Str2ColorU32(U8 *st);
+
+#help_index "Hash"
+#help_file "::/Doc/Hash"
+public _extern _HASH_ADD U0 HashAdd(CHash *tmph,CHashTable *table);
+public _extern _HASH_ADD_AFTER U0 HashAddAfter(CHash *tmph,
+        CHash *pred,CHashTable *table); //Add hash entry after entry.
+public _extern _HASH_BUCKET_FIND CHash **HashBucketFind(
+        U8 *needle_str,CHashTable *haystack_table);
+public _extern _HASH_FIND CHash *HashFind(U8 *needle_str,
+        CHashTable *haystack_table,I64 mask,I64 instance=1);
+public _extern _HASH_SINGLE_TABLE_FIND CHash *HashSingleTableFind(
+        U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1);
+public _extern _HASH_STR I64 HashStr(U8 *st);
+public extern CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL);
+
+#help_index "Hash/Frame"
+#help_file "::/Doc/Frame"
+public extern I64 FramePtr(U8 *name,CTask *task=NULL);
+public extern CHashGeneric *FramePtrAdd(U8 *name,I64 val=0,CTask *task=NULL);
+public extern I64 FramePtrDel(U8 *name,CTask *task=NULL);
+public extern I64 FramePtrSet(U8 *name,I64 val,CTask *task=NULL);
+
+#help_index "Hash/System"
+public extern U0 HashDel(CHashSrcSym *tmph);
+public extern CHashGeneric *HashGenericAdd(U8 *name,
+        I64 type,I64 val=0,I64 u8=0,I64 u16=0,CTask *task=NULL);
+public extern CHashGeneric *HashPublic(U8 *st,I64 mask,Bool val=TRUE);
+public _extern _HASH_REM_DEL Bool HashRemDel(CHash *tmph,CHashTable *table,
+        I64 instance=1);//instance must match tmph's
+public extern U0 HashTableDel(CHashTable *table);
+public extern I64 HashTablePurge(CHashTable *table);
+public extern I64 HashTypeNum(CHash *tmph);
+public extern I64 HashVal(CHash *tmph);
+extern U0 SysSymImportsResolve(U8 *sptr,I64 ld_flags=0);
+
+#help_index "Hash/System;Char/Lists"
+public extern I64 HashLstAdd(U8 *lst,I64 type,CHashTable *table);
+
+#help_index "Hash/System;Define;Char/Define;Char/Lists"
+public extern I64 HashDefineLstAdd(U8 *dname,I64 type,CHashTable *table);
+
+#help_index "Help System;Debugging/Debugger"
+public extern U0 Help();
+
+#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically);Install"
+public extern U0 DrvRep();
+
+#help_index "Install"
+#help_file "::/Doc/Install"
+extern CATARep *ATARepFind(CATARep *haystack_head,I64 needle_num);
+public extern Bool DrvEnable(U8 drv_let,Bool val);
+
+#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
+public extern U0 Fmt(U8 drv_let,Bool quick=TRUE,
+        Bool confirm=TRUE,I64 type=FSt_FAT32);
+
+#help_index "Install;Memory/BlkPool"
+public extern I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024);
+
+#help_index "Job/Exe;Task/Job/Exe"
+public extern U0 AdamErr(U8 *fmt,...);
+public extern U0 AdamLog(U8 *fmt,...);
+public extern I64 ExeCmdLine(CCmpCtrl *cc);
+public extern U0 JobDel(CJob *tmpc);
+public extern I64 JobsHndlr(I64 run_flags,CTask *task=NULL);
+extern U0 SrvCmdLine();
+public extern U0 SrvTaskCont();
+public extern CJob *TaskExe(CTask *srv,CTask *master,U8 *data,I64 flags);
+public extern U0 TaskRstAwaitingMsg(CTask *task=NULL);
+public extern U0 UserTaskCont();
+
+#help_index "Job/Exe;Task/Job/Exe;Compiler"
+public extern I64 Adam(U8 *fmt,...);
+public extern I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL);
+public extern I64 PopUpPrint(U8 *fmt,...);
+
+#help_index "Job/Exe;Task/Job/Exe;MultiCore"
+public extern I64 JobResGet(CJob *rqst=NULL);
+public extern Bool JobResScan(CJob *rqst=NULL,I64 *_res=NULL);
+
+#help_index "Job/Text & Msgs;Task/Job/Text & Msgs"
+public extern CJob *TaskText(CTask *srv,CTask *master,U8 *data,I64 flags);
+
+#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;InFile;StdIn/InFile"
+public extern U0 In(U8 *fmt,...);
+public extern U0 InFile(U8 *filename);
+public extern U0 InStr(U8 *fmt,...);
+public extern U0 XTalk(CTask *task,U8 *fmt,...);
+public extern U0 XTalkStr(CTask *task,U8 *fmt,...);
+public extern U0 XTalkStrWait(CTask *task,U8 *fmt,...);
+public extern U0 XTalkWait(CTask *task,U8 *fmt,...);
+
+#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;Messages"
+public extern U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0);
+public extern U0 PostMsg(CTask *task,
+        I64 msg_code,I64 arg1,I64 arg2,I64 flags=0);
+public extern U0 PostMsgWait(CTask *task,I64 msg_code,
+        I64 arg1,I64 arg2,I64 flags=0);
+public extern CJob *TaskMsg(CTask *srv,CTask *master,
+                     I64 msg_code,I64 arg1,I64 arg2,I64 flags);
+
+#help_index "Job;Task/Job"
+#help_file "::/Doc/Job"
+
+#help_index "Keyboard Devices/System;Char/System"
+#help_file "::/Doc/KeyDev"
+public extern U0 CtrlAltCBSet(U8 ch,U0 (*fp_hndlr)(I64 sc),
+        U8 *no_shift_desc=NULL,U8 *shift_desc=NULL,Bool in_irq=FALSE);
+public extern U0 KeyDescSet(U8 *fmt,...);
+public extern CKeyDevEntry *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc),
+        Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE);
+public extern U0 KeyDevRem(CKeyDevEntry *tmpk);
+extern CKeyDevGlbls keydev;
+extern CJob sys_macro_head;
+extern CTask *sys_macro_task;
+
+#help_index "Keyboard Devices;Char/Input;StdIn"
+extern U8  *(*fp_getstr2)(I64 flags=0); //GetStr Flags
+public extern Bool AreYouSure();
+public extern I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,
+        Bool raw_cursor=FALSE);
+public extern I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE,
+        Bool raw_cursor=FALSE);
+public extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE);
+public extern U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0);
+extern U0       KbdInit();
+public extern I64 KbdMsEvtTime();
+extern U0       KbdMsHndlr(Bool poll_kbd,Bool poll_ms);
+extern U0       KbdMsInit();
+extern I64      KbdMsgsQue();
+public extern U0 KbdTypeMatic(U8 delay);
+extern Bool     MsHardDrvrInstall();
+public extern I64 PressAKey();
+public extern I64 ScanChar();
+public extern Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE);
+public extern Bool YorN();
+public extern CKbdStateGlbls    kbd;
+
+#help_index "Math"
+public extern I64 CeilI64(I64 num,I64 to);
+public extern U64 CeilU64(U64 num,U64 to);
+public extern F64 Clamp(F64 d,F64 lo,F64 hi);
+public extern I64 FloorI64(I64 num,I64 to);
+public extern U64 FloorU64(U64 num,U64 to);
+public extern F64 Max(F64 n1,F64 n2);
+public extern F64 Min(F64 n1,F64 n2);
+public extern F64 Pow10I64(I64 i);
+public extern F64 Rand(); //With timestamp
+public extern I16 RandI16();
+public extern I32 RandI32();
+public extern I64 RandI64();
+public extern U16 RandU16();
+public extern U32 RandU32();
+public extern U64 RandU64();
+public extern I64 RoundI64(I64 num,I64 to);
+public extern I64 Seed(I64 seed=0,CTask *task=NULL);
+
+#help_index "Memory/Adam Heap"
+public extern U8 *ACAlloc(I64 size);
+public extern U8 *AMAlloc(I64 size);
+public extern U8 *AMAllocIdent(U8 *src);
+
+#help_index "Memory/BlkPool"
+public extern U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pags);
+public extern U0 BlkPoolInit(CBlkPool *bp,I64 pags);
+public extern U8 *MemPagAlloc(I64 pags,CBlkPool *bp=NULL);
+public extern U0 MemPagFree(CMemBlk *m,CBlkPool *bp=NULL);
+
+#help_index "Memory/Heap"
+public extern U8 *CAlloc(I64 size,CTask *mem_task=NULL);
+public extern U8 *CAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0);
+public _extern _FREE U0 Free(U8 *addr);
+public _extern _MALLOC U8 *MAlloc(I64 size,CTask *mem_task=NULL);
+public extern U8 *MAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0);
+public extern U8 *MAllocIdent(U8 *src,CTask *mem_task=NULL);
+public _extern _MHEAP_CTRL CHeapCtrl *MHeapCtrl(U8 *src);
+public _extern _MSIZE I64 MSize(U8 *src);   //size of heap object
+public _extern _MSIZE2 I64 MSize2(U8 *src); //Internal size
+
+#help_index "Memory/HeapCtrl"
+public extern U0 HeapCtrlDel(CHeapCtrl *hc);
+public extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,
+        CTask *task=NULL,CBlkPool *bp);
+
+#help_index "Memory/Page Tables"
+public extern I64 *MemPageTable(U8 *a);
+
+#help_index "Messages"
+#help_file "::/Doc/Msgs"
+public extern I64 FlushMsgs(CTask *task=NULL);
+public extern I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,
+        I64 mask=~1,CTask *task=NULL);
+extern U0 InputFilterTask();
+public extern I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,
+        I64 mask=~1,CTask *task=NULL);
+
+#help_index "Misc"
+public extern I64 EndianI64(I64 d);
+public extern U16 EndianU16(U16 d);
+public extern U32 EndianU32(U32 d);
+public extern U0 QSort(U8 *base,I64 num, I64 width,
+        I64 (*fp_compare)(U8 *e1,U8 *e2));
+public extern U0 QSortI64(I64 *base,I64 num,
+        I64 (*fp_compare)(I64 e1,I64 e2));
+public extern F64 sys_os_version;
+
+#help_index "Misc/Progress Bars"
+public extern U0 ProgressBarsRst(U8 *path=NULL);
+
+#help_index "Mouse"
+#help_file "::/Doc/Mouse"
+public extern U0 GridInit();
+public extern U0 MsSet(I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,
+        I64 l=I64_MAX,I64 r=I64_MAX);
+public extern CMsStateGlbls ms;
+public extern CGridGlbls ms_grid;
+public extern CMsHardStateGlbls ms_hard;
+extern CMsHardStateGlbls ms_hard_last;
+extern CMsStateGlbls ms_last;
+
+#help_index "Mouse/Ptr"
+extern U0 MsInit();
+extern U0 MsUpdate(I64 x,I64 y,I64 z,Bool l,Bool r);
+
+#help_index "MultiCore"
+extern U0 Core0StartMP();
+extern U0 CoreAPSethTask();
+public extern U0 MPInt(U8 num,I64 cpu_num=1);
+public extern U0 MPIntAll(U8 num);
+public extern U0 MPNMInt();
+extern CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,
+        U8 *task_name=NULL,I64 target_cpu,
+        CTask *parent=NULL, //NULL means adam
+        I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE);
+
+#help_index "MultiCore;Boot"
+public extern U0 MPHalt();
+
+#help_index "MultiCore;Job/Exe;Task/Job/Exe"
+public extern CJob *JobQue(I64 (*fp_addr)(U8 *data),U8 *data=NULL,
+        I64 target_cpu=1,I64 flags=1<<JOBf_FREE_ON_COMPLETE,
+        I64 job_code=JOBT_CALL,U8 *aux_str=NULL,I64 aux1=0,I64 aux2=0);
+
+#help_index "PCI"
+public extern I64 PCIClassFind(I64 class_code,I64 n);
+public extern U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg);
+public extern U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg);
+public extern U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg);
+public extern U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
+public extern U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
+public extern U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
+public _extern SYS_PCIBIOS_SERVICE_DIR
+        U32 sys_PCIBIOS_service_dir;//Far call routine in the BIOS
+public _extern SYS_PCI_SERVICES
+        U32 sys_pci_services;//Far call routine in the BIOS
+
+#help_index "PCI;Info;File/System;Devices"
+public extern I64 ATARep(Bool pmt=TRUE,
+        Bool just_ide=FALSE,CATARep **_head=NULL);
+
+#help_index "Processor"
+public extern U8 *IntEntryGet(I64 irq);
+public extern U8 *IntEntrySet(I64 irq,
+        U0 (*fp_new_hndlr)(),I64 type=IDTET_IRQ,I64 dpl=0);
+
+#help_index "ScrnCast;Cmd Line (Typically)"
+public extern Bool ScrnCast(Bool val=ON,Bool just_audio=FALSE,
+        U8 *print_fmt="B:/Tmp/%X.GR")
+public extern CScrnCastGlbls scrncast;
+
+#help_index "Snd"
+#help_file "::/Doc/Snd"
+public extern U0 Beep(I8 ona=62,Bool busy=FALSE);
+public extern I8 Freq2Ona(F64 freq);
+public extern Bool IsMute();
+public extern Bool Mute(Bool val);
+public extern F64 Ona2Freq(I64 ona);
+public extern U0 Snd(I8 ona=0);
+public extern U0 SndRst();
+
+#help_index "StdIn"
+#help_file "::/Doc/Streams"
+
+#help_index "StdOut"
+#help_file "::/Doc/Streams"
+
+#help_index "Task"
+public extern I64 BirthWait(CTask **_task,I64 task_num=-1);
+public extern U0 DeathWait(CTask **_task,Bool send_exit=FALSE);
+public extern U0 Exit();
+public extern Bool IsSuspended(CTask *task=NULL);
+public extern Bool Kill(CTask *task,Bool wait=TRUE,Bool just_break=FALSE);
+public extern Bool Suspend(CTask *task=NULL,Bool state=TRUE);
+_extern _TASK_CONTEXT_RESTORE U0 TaskContextRestore();
+_extern _TASK_END_NOW U0 TaskEndNow();
+extern U0 TaskKillDying();
+public extern U0 TaskQueIns(CTask *task,CTask *pred=NULL);
+public extern U0 TaskQueRem(CTask *task);
+public extern Bool TaskValidate(CTask *task);
+public extern U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE);
+public extern CTask *User(U8 *fmt=NULL,...);
+public extern U0 UserCmdLine();
+public _extern _YIELD U0 Yield();
+public extern CTask *adam_task;
+public extern I64 sys_num_spawned_tasks;
+extern CTask *sys_winmgr_task,*sys_task_being_scrn_updated;
+
+#help_index "Task/Delay;Time/CPU Cycles"
+public extern U0 Busy(I64 uS); //Loosely timed
+public extern U0 PortNop(); //On the order of 1uS
+extern I64 TimeCal();
+
+#help_index "Task/Delay;Time/Jiffies"
+public extern U0 Sleep(I64 mS);
+public extern U0 SleepUntil(I64 wake_jiffy);
+
+#help_index "Task/Misc"
+extern U0 (*fp_update_ctrls)(CTask *task);
+public extern U0 TSSBusy(I64 tr,Bool val=OFF);
+public extern U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE);
+public extern U0 WinDerivedValsUpdate(CTask *task);
+
+#help_index "Task;Job/Exe;Task/Job/Exe;MultiCore"
+public extern CTask *Spawn(U0 (*fp_addr)(U8 *data),U8 *data=NULL,
+        U8 *task_name=NULL,I64 target_cpu=-1,   //-1 means current CPU
+        CTask *parent=NULL, //NULL means adam
+        I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE);
+
+#help_index "Time/CPU Cycles;Time/HPET;Time/Jiffies"
+public extern CCntsGlbls cnts;
+
+#help_index "Time/Date/CDate;Date/CDate"
+#help_file "::/Doc/TimeDate"
+public extern U0 Date2Struct(CDateStruct *_ds,CDate cdt);
+extern U8 *MPrintDate(CDate cdt);
+extern U8 *MPrintTime(CDate cdt);
+public extern CDate Now();
+public extern CDate Struct2Date(CDateStruct *_ds);
+public extern CDate local_time_offset;
+
+#help_index "Time/Date;Date"
+#help_file "::/Doc/Date"
+public extern I64 DayOfWeek(I64 i);
+public extern I64 FirstDayOfMon(I64 i);
+public extern I64 FirstDayOfYear(I64 i);
+public extern I64 LastDayOfMon(I64 i);
+public extern I64 LastDayOfYear(I64 i);
+public extern I64 YearStartDate(I64 year);
+public extern U16 mon_start_days1[12];
+public extern U16 mon_start_days2[12];
+
+#help_index "Time/HPET"
+#help_file "::/Doc/TimeHPET"
+public extern I64 HPET();
+
+#help_index "Time/Jiffies"
+#help_file "::/Doc/TimeJiffy"
+public extern I64 SysTimerRead();//18.33333*65536Hz (SYS_TIMER_FREQ)
+
+#help_index "Time/Seconds"
+public extern Bool Blink(F64 Hz=2.5);
+public extern F64 tS(); //From SysTimerFreq.
+
+#help_index "Windows"
+public extern Bool WinInside(I64 x,I64 y,CTask *task=NULL,I64 border=0);
+
+#help_index ""
+
+ diff --git a/public/Wb/Home/Src/Kernel/KeyDev.HC.HTML b/public/Wb/Home/Src/Kernel/KeyDev.HC.HTML new file mode 100755 index 0000000..f6bcf01 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/KeyDev.HC.HTML @@ -0,0 +1,250 @@ + + + + + + + + + + + +
+U0 PutKey(I64 ch=0,I64 sc=0)
+{//See Keyboard Devices.
+  CKeyDevEntry *tmpk;
+  if (ch||sc) {
+    tmpk=keydev.put_key_head.next;
+    if (!Bt(&Fs->display_flags,DISPLAYf_SILENT)) {
+      if (kbd.scan_code & SCF_SCROLL && sys_focus_task==Fs)
+        while (kbd.scan_code & SCF_SCROLL)
+          Yield; //Wait on SCROLL LOCK Key
+      while (tmpk!=&keydev.put_key_head) {
+        if ((!(sc&SCF_KEY_DESC) || tmpk->flags & KDF_HAS_DESCS) &&
+              (*tmpk->put_key)(ch,sc))
+          break;
+        tmpk=tmpk->next;
+      }
+    }
+  }
+}
+
+U0 PutChars(U64 ch)
+{//Output chars. Up to 8 chars in a single U64.
+//Don't use this.  See Print() shortcut.
+  while (ch) {
+    PutKey(ch&255,0);
+    ch>>=8;
+  }
+}
+
+U0 PutS(U8 *st)
+{//Use Print(). See Keyboard Devices.
+//Don't use this.  See Print() shortcut.
+  I64 ch;
+  U8 *ptr;
+  Bool cont=TRUE;
+  if (!st) return;
+  CKeyDevEntry *tmpk=keydev.put_key_head.next;
+  if (!Bt(&Fs->display_flags,DISPLAYf_SILENT)) {
+    if (kbd.scan_code & SCF_SCROLL && sys_focus_task==Fs)
+      while (kbd.scan_code & SCF_SCROLL)
+        Yield;
+    while (cont && tmpk!=&keydev.put_key_head) {
+      if (tmpk->put_s) {
+        if ((*tmpk->put_s)(st))
+          break;
+      } else {
+        ptr=st;
+        while (ch=*ptr++)
+          if ((*tmpk->put_key)(ch,0))
+            cont=FALSE;
+      }
+      tmpk=tmpk->next;
+    }
+  }
+}
+
+U0 KeyDescSet(U8 *fmt,...)
+{//Call this from key hndlr to report desc in KeyMap().
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  StrCpy(keydev.desc,buf);
+  keydev.hndlr=Caller;
+  Free(buf);
+}
+
+U0 KeyDevRem(CKeyDevEntry *tmpk)
+{//Remove StdOut hook and free.
+  QueRem(tmpk);
+  Free(tmpk);
+}
+
+CKeyDevEntry *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc),
+        Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE)
+{//Places hook in StdOut chain. See Keyboard Devices.
+  CKeyDevEntry *tmpk=keydev.put_key_head.last,
+        *tmpk1=ACAlloc(sizeof(CKeyDevEntry));
+  tmpk1->put_key=fp_put_key;
+  tmpk1->put_s=fp_puts;
+  tmpk1->priority=priority;
+  if (key_descs)
+    tmpk1->flags|=KDF_HAS_DESCS;
+  while (tmpk->priority>priority)
+    tmpk=tmpk->last;
+  QueIns(tmpk1,tmpk);
+  if (tmpk->priority==priority)
+    KeyDevRem(tmpk);
+  return tmpk1;
+}
+
+Bool KDRawPutKey(I64 ch,I64)
+{
+  if (IsRaw) {
+    RawPutChar(ch);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool KDRawPutS(U8 *st)
+{
+  I64 ch;
+  if (IsRaw) {
+    while (ch=*st++)
+      RawPutChar(ch);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool KDInputFilterPutKey(I64 ch,I64 scan_code)
+{
+  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK)) {
+    Msg(MSG_KEY_DOWN,ch,scan_code);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool KDInputFilterPutS(U8 *st)
+{
+  I64 ch;
+  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK)) {
+    while (ch=*st++)
+      Msg(MSG_KEY_DOWN,ch,0);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 CtrlAltDel(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_DEL);
+}
+
+U0 CtrlAltC(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_C);
+}
+
+U0 CtrlAltD(I64)
+{
+  if (!IsDbgMode) {
+    if (Fs==Gs->idle_task)
+      BptS(sys_winmgr_task->rip,sys_winmgr_task);
+    else
+      BptS(*keydev.ctrl_alt_ret_addr);
+  }
+}
+
+U0 CtrlAltF(I64)
+{
+  SwapI64(&text.font,&text.aux_font);
+}
+
+U0 CtrlAltM(I64)
+{
+  Mute(!IsMute);
+}
+
+U0 CtrlAltN(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_TAB);
+}
+
+U0 CtrlAltT(I64)
+{
+  User;
+}
+
+U0 CtrlAltV(I64)
+{
+  VGAFlush;
+}
+
+U0 CtrlAltX(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_X);
+}
+
+U0 CtrlAltCBSet(U8 ch,U0 (*fp_hndlr)(I64 sc),
+        U8 *no_shift_desc=NULL,U8 *shift_desc=NULL,Bool in_irq=FALSE)
+{//Set callback for <CTRL-ALT-letter>.
+  ch=ToUpper(ch)-'A';
+  if (ch<26) {
+    keydev.fp_ctrl_alt_cbs[ch]=fp_hndlr;
+
+    Free(keydev.ctrl_alt_no_shift_descs[ch]);
+    if (no_shift_desc)
+      keydev.ctrl_alt_no_shift_descs[ch]=AStrNew(no_shift_desc);
+    else
+      keydev.ctrl_alt_no_shift_descs[ch]=NULL;
+
+    Free(keydev.ctrl_alt_shift_descs[ch]);
+    if (shift_desc)
+      keydev.ctrl_alt_shift_descs[ch]=AStrNew(shift_desc);
+    else
+      keydev.ctrl_alt_shift_descs[ch]=NULL;
+
+    BEqu(&keydev.ctrl_alt_in_irq_flags,ch,in_irq);
+  }
+}
+
+U0 KeyDevInit()
+{
+  keydev.fp_ctrl_alt_cbs        =CAlloc(26*sizeof(U8 *));
+  keydev.ctrl_alt_no_shift_descs=CAlloc(26*sizeof(U8 *));
+  keydev.ctrl_alt_shift_descs   =CAlloc(26*sizeof(U8 *));
+  keydev.ctrl_alt_in_irq_flags  =0;
+  MemSet(&keydev.put_key_head,0,sizeof(CKeyDevEntry));
+  QueInit(&keydev.put_key_head);
+  KeyDevAdd(&KDInputFilterPutKey,&KDInputFilterPutS,0x40000000,FALSE);
+  KeyDevAdd(&KDRawPutKey,&KDRawPutS,0x60000000,FALSE);
+  CtrlAltCBSet('C',&CtrlAltC,"Cmd /Break Execution",,TRUE);
+  CtrlAltCBSet('D',&CtrlAltD,"Cmd /Enter Debugger",,TRUE);
+  CtrlAltCBSet('F',&CtrlAltF,"Cmd /Toggle Aux Font");
+  CtrlAltCBSet('M',&CtrlAltM,"Cmd /Toggle Mute");
+  CtrlAltCBSet('N',&CtrlAltN,"Cmd /Next Focus Task",,TRUE);
+  CtrlAltCBSet('T',&CtrlAltT,"Cmd /Terminal Window");
+  CtrlAltCBSet('V',&CtrlAltV,"Cmd /VGA Flush",,TRUE);
+  CtrlAltCBSet('X',&CtrlAltX,"Cmd /Kill Focused Task",,TRUE);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Mem/BlkPool.HC.HTML b/public/Wb/Home/Src/Kernel/Mem/BlkPool.HC.HTML new file mode 100755 index 0000000..1931829 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Mem/BlkPool.HC.HTML @@ -0,0 +1,104 @@ + + + + + + + + + + + +
+U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pags)
+{//Add mem to BlkPool.
+  if (sys_mem_init_flag)
+    MemSet(m,sys_mem_init_val,pags*MEM_PAG_SIZE);
+  PUSHFD
+  CLI
+  while (LBts(&bp->locked_flags,BPlf_LOCKED))
+    PAUSE
+  m->next=bp->mem_free_lst;
+  m->pags=pags;
+  m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
+  bp->alloced_u8s+=pags<<MEM_PAG_BITS;
+  bp->mem_free_lst=m;
+  LBtr(&bp->locked_flags,BPlf_LOCKED);
+  POPFD
+}
+
+U0 BlkPoolInit(CBlkPool *bp,I64 pags)
+{//Make mem chunk into a BlkPool.
+  I64 num;
+  CMemBlk *m;
+  MemSet(bp,0,sizeof(CBlkPool));
+  m=(bp(U8 *)+sizeof(CBlkPool)+MEM_PAG_SIZE-1)&~(MEM_PAG_SIZE-1);
+  num=(bp(U8 *)+pags<<MEM_PAG_BITS-m(U8 *))>>MEM_PAG_BITS;
+  bp->alloced_u8s=(pags-num)<<MEM_PAG_BITS; //Compensate before num added.
+  BlkPoolAdd(bp,m,num);
+}
+
+U0 BlkPoolsInit()
+{
+  I64 i,total,lo,hi,code_heap_limit;
+  CMemE820 *m20=MEM_E820;
+  Bool first=TRUE;
+
+  total=BIOSTotalMem;
+
+  if (total<=0x80000000)
+    code_heap_limit=total;
+  else if (total<=0x100000000)
+    code_heap_limit=total/4;
+  else
+    code_heap_limit=0x80000000;
+
+  i=code_heap_limit-SYS_16MEG_AREA_LIMIT; //See RLf_16MEG_SYS_CODE_BP
+  BlkPoolAdd(sys_code_bp,SYS_16MEG_AREA_LIMIT,i>>MEM_PAG_BITS);
+  mem_heap_limit=i+SYS_16MEG_AREA_LIMIT-1;
+
+  if (code_heap_limit<total) {
+    while (m20->type) {
+      if (m20->type==1) {
+        lo=m20->base;
+        hi=m20->base+m20->len;
+        if (lo<code_heap_limit) {
+          if (hi>code_heap_limit)
+            lo=code_heap_limit;
+          else
+            hi=lo; //cancel
+        }
+        if (code_heap_limit<=lo<hi) {
+          if (first) {
+            BlkPoolInit(lo,(hi-lo)>>MEM_PAG_BITS);
+            sys_data_bp=lo;
+            Fs->data_heap=HeapCtrlInit(,Fs,sys_data_bp);
+            first=FALSE;
+          } else
+            BlkPoolAdd(sys_data_bp,lo,(hi-lo)>>MEM_PAG_BITS);
+        }
+      }
+      m20++;
+    }
+  }
+  LBts(&sys_run_level,RLf_FULL_HEAPS);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Mem/HeapCtrl.HC.HTML b/public/Wb/Home/Src/Kernel/Mem/HeapCtrl.HC.HTML new file mode 100755 index 0000000..05b7a04 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Mem/HeapCtrl.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,CTask *task=NULL,CBlkPool *bp)
+{//See HeapLog() for an example.
+//Duplicated for Adam Task.
+  if (!hc)
+    hc=ACAlloc(sizeof(CHeapCtrl));
+  hc->hc_signature=HEAP_CTRL_SIGNATURE_VAL;
+  hc->mem_task=task;
+  hc->bp=bp;
+  QueInit(&hc->next_mem_blk);
+  hc->last_mergable=NULL;
+  hc->next_um=hc->last_um=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
+  return hc;
+}
+
+U0 HeapCtrlDel(CHeapCtrl *hc)
+{//Free all blks alloced to a HeapCtrl.
+  CMemBlk *m,*m1;
+  if (hc) {
+    PUSHFD
+    CLI
+    while (LBts(&hc->locked_flags,HClf_LOCKED))
+      PAUSE
+    m=hc->next_mem_blk;
+    while (m!=&hc->next_mem_blk) {
+      m1=m->next;
+      MemPagTaskFree(m,hc);
+      m=m1;
+    }
+    LBtr(&hc->locked_flags,HClf_LOCKED);
+    POPFD
+    Free(hc);
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Mem/MAllocFree.HC.HTML b/public/Wb/Home/Src/Kernel/Mem/MAllocFree.HC.HTML new file mode 100755 index 0000000..dd1c412 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Mem/MAllocFree.HC.HTML @@ -0,0 +1,495 @@ + + + + + + + + + + + +
+asm {
+//************************************
+//See ::/Doc/Credits.DD.
+_MALLOC::
+// Throws 'OutMem'
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        XOR     RBX,RBX
+        MOV     RDX,U64 SF_ARG2[RBP]
+        TEST    RDX,RDX
+        JNZ     @@05
+        MOV     RDX,U64 FS:CTask.addr[RBX]
+@@05:   CMP     U32 CTask.task_signature[RDX],TASK_SIGNATURE_VAL
+
+#assert CTask.task_signature==CHeapCtrl.hc_signature //location signature same
+
+        JNE     @@10
+        MOV     RDX,U64 CTask.data_heap[RDX]
+@@10:   CMP     U32 CHeapCtrl.hc_signature[RDX],HEAP_CTRL_SIGNATURE_VAL
+        JE      @@15
+        PUSH    RDX
+        CALL    &SysBadMAlloc
+        JMP     I32 _SYS_HLT
+
+@@15:   MOV     RAX,U64 SF_ARG1[RBP]
+        PUSHFD
+        ADD     RAX,CMemUsed.start+7    //round-up to I64
+        AND     AL,0xF8
+#assert CMemUsed.start>=sizeof(CMemUnused)
+        CMP     RAX,CMemUsed.start
+        JAE     @@20
+        MOV     RAX,CMemUsed.start
+@@20:
+
+        CLI
+@@25:   LOCK
+        BTS     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        PAUSE   //don't know if this inst helps
+        JC      @@25
+
+        CMP     RAX,MEM_HEAP_HASH_SIZE
+        JAE     @@30
+        MOV     RSI,U64 CHeapCtrl.heap_hash[RAX+RDX]
+        TEST    RSI,RSI
+        JZ      @@35
+        MOV     RCX,U64 CMemUnused.next[RSI]
+        MOV     U64 CHeapCtrl.heap_hash[RAX+RDX],RCX
+        JMP     I32 MALLOC_ALMOST_DONE
+
+//Big allocation
+@@30:   ADD     RAX,sizeof(CMemBlk)+MEM_PAG_SIZE-1
+        SHR     RAX,MEM_PAG_BITS
+
+        PUSH    RDX //preserve HeapCtrl
+        PUSH    RDX
+        PUSH    RAX
+        CALL    &MemPagTaskAlloc
+        POP     RDX
+        TEST    RAX,RAX
+        JZ      @@45    //Out of memory
+        MOV     RSI,RAX
+        MOV     EAX,U32 CMemBlk.pags[RSI]
+
+        SHL     RAX,MEM_PAG_BITS
+        SUB     RAX,sizeof(CMemBlk)
+        ADD     RSI,sizeof(CMemBlk)
+        JMP     I32 MALLOC_ALMOST_DONE
+
+//Little allocation, chunk-off piece from free lst chunks
+@@35:   LEA     RSI,U64 CHeapCtrl.malloc_free_lst-CMemUnused.next[RDX]
+
+@@40:   MOV     RBX,RSI
+        MOV     RSI,U64 CMemUnused.next[RBX]
+        TEST    RSI,RSI
+        JNZ     I32 @@60
+        PUSH    RAX             //-**** save byte size
+        ADD     RAX,16*MEM_PAG_SIZE-1
+        SHR     RAX,MEM_PAG_BITS
+
+        PUSH    RDX //preserve HeapCtrl
+        PUSH    RDX
+        PUSH    RAX
+        CALL    &MemPagTaskAlloc
+        POP     RDX
+        TEST    RAX,RAX
+        JNZ     @@50
+
+//Out of memory
+@@45:   LOCK
+        BTR     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        POPFD
+        PUSH    TRUE
+        MOV     RAX,'OutMem'
+        PUSH    RAX
+        CALL    I32 &throw
+        JMP     I32 MALLOC_FINAL_EXIT //Never gets here, hopefully.
+
+@@50:   MOV     RSI,RAX
+        MOV     EAX,U32 CMemBlk.pags[RSI]
+        SHL     RAX,MEM_PAG_BITS
+
+//Can it be combined with last chunk? (Never Free these chunks.)
+        MOV     RDI,U64 CHeapCtrl.last_mergable[RDX]
+        LEA     RBX,U64 [RSI+RAX]
+        CMP     RDI,RBX
+        JNE     @@55
+
+        PUSH    RAX
+        MOV     EAX,U32 CMemBlk.pags[RDI]
+        ADD     U32 CMemBlk.pags[RSI],EAX
+//QueRem
+        MOV     RAX,U64 CMemBlk.next[RDI]
+        MOV     RBX,U64 CMemBlk.last[RDI]
+        MOV     U64 CMemBlk.last[RAX],RBX
+        MOV     U64 CMemBlk.next[RBX],RAX
+        POP     RAX
+
+@@55:   MOV     U64 CHeapCtrl.last_mergable[RDX],RSI
+        LEA     RSI,U64 sizeof(CMemBlk)[RSI]
+        SUB     RAX,sizeof(CMemBlk)
+        LEA     RBX,U64 CHeapCtrl.malloc_free_lst-CMemUnused.next[RDX]
+        MOV     RDI,U64 CMemUnused.next[RBX]
+        MOV     U64 CMemUnused.next[RSI],RDI
+        MOV     U64 CMemUnused.size[RSI],RAX
+        MOV     U64 CMemUnused.next[RBX],RSI
+        POP     RAX             //+****
+        JMP     @@70
+@@60:   CMP     U64 CMemUnused.size[RSI],RAX
+        JB      I32 @@40
+        JNE     @@70
+
+@@65:   MOV     RDI,U64 CMemUnused.next[RSI]
+        MOV     U64 CMemUnused.next[RBX],RDI
+        JMP     MALLOC_ALMOST_DONE
+
+@@70:   SUB     U64 CMemUnused.size[RSI],RAX    //UPDATE FREE ENTRY
+        CMP     U64 CMemUnused.size[RSI],sizeof(CMemUnused)
+        JAE     @@75                    //take from top of block
+        ADD     U64 CMemUnused.size[RSI],RAX    //doesn't fit, undo
+        JMP     I32 @@40
+
+@@75:   ADD     RSI,U64 CMemUnused.size[RSI]
+
+MALLOC_ALMOST_DONE:
+//RSI=res-CMemUsed.size
+//RAX=size+CMemUsed.size
+//RDX=HeapCtrl
+        ADD     U64 CHeapCtrl.used_u8s[RDX],RAX
+
+#if _CFG_HEAP_DBG
+//QueIns
+        MOV     RDI,U64 CHeapCtrl.last_um[RDX]
+        MOV     U64 CMemUsed.next[RDI],RSI
+        MOV     U64 CHeapCtrl.last_um[RDX],RSI
+        MOV     U64 CMemUsed.last[RSI],RDI
+        LEA     RDI,U64 CHeapCtrl.next_um-CMemUsed.next[RDX]
+        MOV     U64 CMemUsed.next[RSI],RDI
+
+//Caller1/Caller2
+        PUSH    RDX
+        MOV     RDX,U64 [MEM_HEAP_LIMIT]
+        MOV     RDI,U64 SF_RIP[RBP]
+        CMP     RDI,RDX
+        JB      @@80
+        XOR     RDI,RDI
+        MOV     U64 CMemUsed.caller1[RSI],RDI
+        JMP     @@90
+@@80:   MOV     U64 CMemUsed.caller1[RSI],RDI
+        MOV     RDI,U64 SF_RBP[RBP]
+        CMP     RDI,RDX
+        JB      @@85
+        XOR     RDI,RDI
+        JMP     @@90
+@@85:   MOV     RDI,U64 SF_RIP[RDI]
+        CMP     RDI,RDX
+        JB      @@90
+        XOR     RDI,RDI
+@@90:   MOV     U64 CMemUsed.caller2[RSI],RDI
+        POP     RDX
+
+#endif
+        LOCK
+        BTR     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        POPFD
+
+        MOV     U64 CMemUsed.size[RSI],RAX
+        MOV     U64 CMemUsed.hc[RSI],RDX
+        LEA     RAX,U64 CMemUsed.start[RSI]
+
+        TEST    U8 [SYS_SEMAS+SEMA_HEAPLOG_ACTIVE*DFT_CACHE_LINE_WIDTH],1
+        JZ      @@105
+        PUSH    RAX
+        PUSH    RAX
+        MOV     RAX,U64 [SYS_EXTERN_TABLE]
+        MOV     RAX,U64 EXT_HEAPLOG_MALLOC*8[RAX]
+        TEST    RAX,RAX
+        JZ      @@95
+        CALL    RAX
+        JMP     @@100
+@@95:   ADD     RSP,8
+@@100:  POP     RAX
+
+@@105:  TEST    U8 [SYS_HEAP_INIT_FLAG],1
+        JZ      MALLOC_FINAL_EXIT
+
+        PUSH    RAX
+        MOV     RCX,U64 CMemUsed.size-CMemUsed.start[RAX]
+        SUB     RCX,CMemUsed.start
+        MOV     RDI,RAX
+        MOV     AL,U8 [SYS_HEAP_INIT_VAL]
+        REP_STOSB
+        POP     RAX
+
+MALLOC_FINAL_EXIT:
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+//************************************
+_FREE::
+//Be aware of heap_hash in MemPagTaskAlloc().
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        TEST    U8 [SYS_SEMAS+SEMA_HEAPLOG_ACTIVE*DFT_CACHE_LINE_WIDTH],1
+        JZ      @@15
+        MOV     RBX,U64 SF_ARG1[RBP]
+        TEST    RBX,RBX
+        JZ      @@05
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+@@05:   PUSH    RBX
+        MOV     RAX,U64 [SYS_EXTERN_TABLE]
+        MOV     RAX,U64 EXT_HEAPLOG_FREE*8[RAX]
+        TEST    RAX,RAX
+        JZ      @@10
+        CALL    RAX
+        JMP     @@15
+@@10:   ADD     RSP,8
+
+@@15:   MOV     RSI,U64 SF_ARG1[RBP]
+        TEST    RSI,RSI
+
+#if _CFG_HEAP_DBG
+        JZ      I32 FREE_DONE
+#else
+        JZ      FREE_DONE
+#endif
+
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RSI]
+        TEST    RAX,RAX
+        JGE     @@20    //Aligned alloced chunks have neg size.
+                        //The neg size is offset to start of CMemUsed struct.
+        ADD     RSI,RAX
+
+@@20:   PUSHFD
+        SUB     RSI,CMemUsed.start
+        MOV     RDX,U64 CMemUsed.hc[RSI]
+        CMP     U32 CHeapCtrl.hc_signature[RDX],HEAP_CTRL_SIGNATURE_VAL
+        JE      @@25
+        ADD     RSI,CMemUsed.start
+        PUSH    RSI
+        CALL    &SysBadFree
+        JMP     I32 _SYS_HLT
+
+@@25:   MOV     RAX,U64 CMemUsed.size[RSI]
+        SUB     U64 CHeapCtrl.used_u8s[RDX],RAX
+        CLI
+@@30:   LOCK
+        BTS     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        PAUSE
+        JC      @@30
+#if _CFG_HEAP_DBG
+//QueRem
+        MOV     RDX,U64 CMemUsed.next[RSI]
+        MOV     RDI,U64 CMemUsed.last[RSI]
+        MOV     U64 CMemUsed.last[RDX],RDI
+        MOV     U64 CMemUsed.next[RDI],RDX
+
+//Caller1/Caller2
+        MOV     RDX,U64 [MEM_HEAP_LIMIT]
+        MOV     RDI,U64 SF_RIP[RBP]
+        CMP     RDI,RDX
+        JB      @@35
+        XOR     RDI,RDI
+        MOV     U64 CMemUnused.caller1[RSI],RDI
+        JMP     @@45
+@@35:   MOV     U64 CMemUnused.caller1[RSI],RDI
+        MOV     RDI,U64 SF_RBP[RBP]
+        CMP     RDI,RDX
+        JB      @@40
+        XOR     RDI,RDI
+        JMP     @@45
+@@40:   MOV     RDI,U64 SF_RIP[RDI]
+        CMP     RDI,RDX
+        JB      @@45
+        XOR     RDI,RDI
+@@45:   MOV     U64 CMemUnused.caller2[RSI],RDI
+
+        MOV     RDX,U64 CMemUsed.hc[RSI]
+#endif
+        CMP     RAX,MEM_HEAP_HASH_SIZE
+        JAE     @@50
+
+#assert CMemUnused.size==CMemUsed.size
+//      MOV     U64 CMemUnused.size[RSI],RAX
+
+        MOV     RBX,U64 CHeapCtrl.heap_hash[RAX+RDX]
+        MOV     U64 CMemUnused.next[RSI],RBX
+        MOV     U64 CHeapCtrl.heap_hash[RAX+RDX],RSI
+        JMP     @@55
+
+@@50:   SUB     RSI,sizeof(CMemBlk)
+        PUSH    RDX
+        PUSH    RDX
+        PUSH    RSI
+        CALL    &MemPagTaskFree
+        POP     RDX
+
+@@55:   LOCK
+        BTR     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        POPFD
+FREE_DONE:
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    8
+//************************************
+_MSIZE::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG1[RBP]
+        XOR     RAX,RAX
+        TEST    RBX,RBX
+        JZ      @@10
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+@@05:   SUB     RAX,CMemUsed.start
+@@10:   POP     RBP
+        RET1    8
+//************************************
+_MSIZE2::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG1[RBP]
+        XOR     RAX,RAX
+        TEST    RBX,RBX
+        JZ      @@10
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+@@05:   MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+@@10:   POP     RBP
+        RET1    8
+//************************************
+_MHEAP_CTRL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG1[RBP]
+        XOR     RAX,RAX
+        TEST    RBX,RBX
+        JZ      @@10
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+@@05:   MOV     RAX,U64 CMemUsed.hc-CMemUsed.start[RBX]
+@@10:   POP     RBP
+        RET1    8
+}
+
+_extern _FREE U0 Free(U8 *addr); //Free MAlloc()ed memory chunk.
+_extern _MSIZE I64 MSize(U8 *src); //Size of heap object.
+_extern _MSIZE2 I64 MSize2(U8 *src); //Internal size of heap object.
+_extern _MHEAP_CTRL CHeapCtrl *MHeapCtrl(U8 *src); //CHeapCtrl of object.
+_extern _MALLOC U8 *MAlloc(I64 size,CTask *mem_task=NULL); //Alloc memory chunk.
+//Accepts a CTask or CHeapCtrl. NULL allocs off current task's heap.
+
+U8 *AMAlloc(I64 size)
+{//Alloc memory in Adam's heap.
+  return MAlloc(size,adam_task);
+}
+
+U8 *CAlloc(I64 size,CTask *mem_task=NULL)
+{//Accepts a CTask or CHeapCtrl.  NULL allocs off current task's heap.
+  U8 *res=MAlloc(size,mem_task);
+  MemSet(res,0,size);
+  return res;
+}
+
+U8 *ACAlloc(I64 size)
+{//Alloc and set to zero memory in Adam's heap.
+  return CAlloc(size,adam_task);
+}
+
+U8 *MAllocIdent(U8 *src,CTask *mem_task=NULL)
+{//Accepts a CTask or CHeapCtrl.  NULL allocs off current task's heap.
+  U8 *res;
+  I64 size;
+  if (!src) return NULL;
+  size=MSize(src);
+  res=MAlloc(size,mem_task);
+  MemCpy(res,src,size);
+  return res;
+}
+
+U8 *AMAllocIdent(U8 *src)
+{//Alloc in Adam's heap, ident copy of heap node.
+  return MAllocIdent(src,adam_task);
+}
+
+U8 *MAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0)
+{//Only powers of two alignment. This is awful.
+  I64 mask=alignment-1;
+  U8 *ptr=MAlloc(size+mask+sizeof(I64)+misalignment,mem_task),
+        *res=(ptr+sizeof(I64)+mask)&~mask+misalignment;
+  res(I64 *)[-1]=ptr-res;
+#assert offset(CMemUsed.size)==offset(CMemUsed.start)-sizeof(I64)
+  return res;
+}
+
+U8 *CAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0)
+{//Only powers of two alignment. This is awful.
+  I64 mask=alignment-1;
+  U8 *ptr=MAlloc(size+mask+sizeof(I64)+misalignment,mem_task),
+        *res=(ptr+sizeof(I64)+mask)&~mask+misalignment;
+  res(I64 *)[-1]=ptr-res;
+#assert offset(CMemUsed.size)==offset(CMemUsed.start)-sizeof(I64)
+  MemSet(res,0,size);
+  return res;
+}
+
+U8 *StrNew(U8 *buf,CTask *mem_task=NULL)
+{//Accepts a CTask or CHeapCtrl.  NULL allocs off current task's heap.
+  U8 *res;
+  I64 size;
+  if (buf) {
+    size=StrLen(buf)+1;
+    res=MAlloc(size,mem_task);
+    MemCpy(res,buf,size);
+  } else {
+    res=MAlloc(1,mem_task);
+    *res=0;
+  }
+  return res;
+}
+
+U8 *AStrNew(U8 *buf)
+{//Alloc copy of string in Adam's heap.
+  return StrNew(buf,adam_task);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Mem/MakeMem.HC.HTML b/public/Wb/Home/Src/Kernel/Mem/MakeMem.HC.HTML new file mode 100755 index 0000000..8bfc4d5 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Mem/MakeMem.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#exe {Cd(__DIR__);};
+#include "PageTables"
+#include "MemPag"
+#include "BlkPool"
+#include "MAllocFree"
+#include "HeapCtrl"
+#include "MemPhysical"
+#exe {Cd("..");};
+
+ diff --git a/public/Wb/Home/Src/Kernel/Mem/MemPag.HC.HTML b/public/Wb/Home/Src/Kernel/Mem/MemPag.HC.HTML new file mode 100755 index 0000000..55ae581 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Mem/MemPag.HC.HTML @@ -0,0 +1,198 @@ + + + + + + + + + + + +
+U0 SysBadFree(I64 *ptr)
+{
+  Panic("Bad Free:",ptr);
+}
+
+U0 SysBadMAlloc(I64 *ptr)
+{
+  Panic("Bad MAlloc:",ptr);
+}
+
+U8 *MemPagAlloc(I64 pags,CBlkPool *bp=NULL)
+{/*Alloc pags from BlkPool. Don't link to task.
+(Linking to a task means they will be freed when the task dies.)
+It might give you more than you asked for.
+
+Return: NULL if out of memory.
+*/
+  CMemBlk *res=NULL,*m;
+  I64 i;
+  if (!bp) bp=sys_code_bp;
+  PUSHFD
+  CLI
+  while (LBts(&bp->locked_flags,BPlf_LOCKED))
+    PAUSE
+  if (pags<MEM_FREE_PAG_HASH_SIZE) {
+    if (res=bp->free_pag_hash[pags]) {
+      bp->free_pag_hash[pags]=res->next;
+      goto at_done;
+    }
+    i=Bsr(MEM_FREE_PAG_HASH_SIZE)+1;
+  } else {
+//We'll now round-up to a power of two.
+    //There is some overhead on allocations and
+    //we wouldn't want to round to the next
+    //power of two if a power of two was requested.
+    //So we use a little more than a power of two.
+    pags-=MEM_EXTRA_HASH2_PAGS;
+    i=Bsr(pags)+1;
+    pags=1<<i+MEM_EXTRA_HASH2_PAGS;
+    if (res=bp->free_pag_hash2[i]) {
+      bp->free_pag_hash2[i]=res->next;
+      goto at_done;
+    }
+  }
+  m=&bp->mem_free_lst;
+  while (TRUE) {
+    if (!(res=m->next)) {
+//We're probably out of luck, but lets search for a
+      //freed larger size block... and, screw-it, return the whole thing.
+      do {
+        if (res=bp->free_pag_hash2[++i]) {
+          pags=1<<i+MEM_EXTRA_HASH2_PAGS;
+          bp->free_pag_hash2[i]=res->next;
+          goto at_done;
+        }
+      } while (i<64-MEM_PAG_BITS-1);
+      pags=0;
+      res=NULL; //Out of memory
+      goto at_done2;
+    }
+    if (res->pags<pags)
+      m=res;
+    else {
+      if (res->pags==pags) {
+        m->next=res->next;
+        goto at_done;
+      } else {
+        res->pags-=pags;
+        res(U8 *)+=res->pags<<MEM_PAG_BITS;
+        res->pags=pags;
+        goto at_done;
+      }
+    }
+  }
+at_done:
+  bp->used_u8s+=res->pags<<MEM_PAG_BITS;
+at_done2:
+  LBtr(&bp->locked_flags,BPlf_LOCKED);
+  POPFD
+  return res;
+}
+
+U0 MemPagFree(CMemBlk *m,CBlkPool *bp=NULL)
+{//Return non-task pags to BlkPool.
+  I64 i,pags;
+  if (m) {
+    if (!bp) bp=sys_code_bp;
+    PUSHFD
+    CLI
+    while (LBts(&bp->locked_flags,BPlf_LOCKED))
+      PAUSE
+    pags=m->pags;
+    m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
+    bp->used_u8s-=pags<<MEM_PAG_BITS;
+    if (pags<MEM_FREE_PAG_HASH_SIZE) {
+      m->next=bp->free_pag_hash[pags];
+      bp->free_pag_hash[pags]=m;
+    } else {
+//We'll now round-up to a power of two.
+      //There is some overhead on allocations and
+      //we wouldn't want to round to the next
+      //power of two if a power of two was requested.
+      //So we use a little more than a power of two.
+      pags-=MEM_EXTRA_HASH2_PAGS;
+      i=Bsr(pags);
+      m->next=bp->free_pag_hash2[i];
+      bp->free_pag_hash2[i]=m;
+    }
+    LBtr(&bp->locked_flags,BPlf_LOCKED);
+    POPFD
+  }
+}
+
+CMemBlk *MemPagTaskAlloc(I64 pags,CHeapCtrl *hc)
+{/*hc must be locked.  Don't preempt this routine.
+Currently, this is only called from MAlloc().
+Return: NULL if out of memory.
+*/
+  CMemBlk *res;
+  I64 threshold,cnt,size;
+  CMemUnused *uum,**_uum,**_ptr;
+  if (res=MemPagAlloc(pags,hc->bp)) {
+    QueIns(res,hc->last_mem_blk);
+    res->mb_signature=MBS_USED_SIGNATURE_VAL;
+    hc->alloced_u8s+=res->pags<<MEM_PAG_BITS;
+
+    //Tidy-up free lst (Move into heap hash)
+    //because if free lst gets long, delay causes crash.
+    threshold=MEM_HEAP_HASH_SIZE>>4;
+#assert MEM_HEAP_HASH_SIZE>>4>=sizeof(U8 *)
+    do {
+      cnt=0;
+      _uum=&hc->malloc_free_lst;
+      while (uum=*_uum) {
+#assert !offset(CMemUnused.next)
+        size=uum->size;
+        if (size<threshold) {
+          *_uum=uum->next;
+          _ptr=(&hc->heap_hash)(U8 *)+size;
+          uum->next=*_ptr;
+          *_ptr=uum;
+        } else {
+          cnt++;
+          _uum=uum;
+        }
+      }
+      threshold<<=1;
+    } while (cnt>8 && threshold<=MEM_HEAP_HASH_SIZE);
+  }
+  return res;
+}
+
+U0 MemPagTaskFree(CMemBlk *m,CHeapCtrl *hc)
+{//hc must be locked
+  if (m) {
+    PUSHFD
+    CLI
+    if (m->mb_signature!=MBS_USED_SIGNATURE_VAL)
+      SysBadFree(m);
+    else {
+      QueRem(m);
+      hc->alloced_u8s-=m->pags<<MEM_PAG_BITS;
+      MemPagFree(m,hc->bp);
+    }
+    POPFD
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Mem/MemPhysical.HC.HTML b/public/Wb/Home/Src/Kernel/Mem/MemPhysical.HC.HTML new file mode 100755 index 0000000..4e69504 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Mem/MemPhysical.HC.HTML @@ -0,0 +1,212 @@ + + + + + + + + + + + +
+Bool Mem32DevIns(CMemRange *tmpmr)
+{
+  CMemRange *tmpmr1=dev.mem32_head.next,*tmpmr2;
+  while (tmpmr1!=&dev.mem32_head) {
+    if (!tmpmr1->type && tmpmr->base>=tmpmr1->base &&
+          tmpmr->base+tmpmr->size<=tmpmr1->base+tmpmr1->size) {
+      if (tmpmr->base>tmpmr1->base) {
+        tmpmr2=AMAlloc(sizeof(CMemRange));
+        tmpmr2->type=MRT_UNUSED;
+        tmpmr2->flags=0;
+        tmpmr2->base=tmpmr1->base;
+        tmpmr2->size=tmpmr->base-tmpmr1->base;
+        QueInsRev(tmpmr2,tmpmr1);
+      }
+      QueInsRev(tmpmr,tmpmr1);
+      tmpmr1->size=tmpmr1->base+tmpmr1->size-
+            (tmpmr->base+tmpmr->size);
+      tmpmr1->base=tmpmr->base+tmpmr->size;
+      if (!tmpmr1->size) {
+        QueRem(tmpmr1);
+        Free(tmpmr1);
+      }
+      return TRUE;
+    }
+    tmpmr1=tmpmr1->next;
+  }
+  return FALSE;
+}
+
+U0 Mem32DevInit()
+{
+  CMemRange *tmpmr;
+  CMemE820 *m20=MEM_E820;
+
+  QueInit(&dev.mem32_head);
+  tmpmr=AMAlloc(sizeof(CMemRange));
+  tmpmr->type=MRT_UNUSED;
+  tmpmr->flags=0;
+//Maybe !!! Change this to 0xF0000000 !!!
+  tmpmr->base=0xE0000000;
+  tmpmr->size=0x10000000;
+  QueIns(tmpmr,dev.mem32_head.last);
+
+  if (m20->type) {
+    while (m20->type) {
+      tmpmr=AMAlloc(sizeof(CMemRange));
+      tmpmr->type=m20->type;
+      tmpmr->flags=0;
+      tmpmr->base=m20->base;
+      tmpmr->size=m20->len;
+      if (!Mem32DevIns(tmpmr))
+        Free(tmpmr);
+      m20++;
+    }
+  }
+}
+
+U8 *Mem32DevAlloc(I64 size,I64 alignment)
+{//Alloc 32-bit addr space for device. (Doesn't work.) Not used.
+//For this to work the BIOS E820 map must be searched for gaps in
+  //the 32-bit range and the pool initialized to the gaps.
+  U8 *base,*limit;
+  CMemRange *tmpmr,*tmpmr1;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  tmpmr1=dev.mem32_head.next;
+  while (tmpmr1!=&dev.mem32_head) {
+    base=(tmpmr1->base+alignment-1)&~(alignment-1);
+    limit=base+size-1;
+    if (!tmpmr1->type &&
+          limit<tmpmr1->base+tmpmr1->size) {
+      tmpmr=AMAlloc(sizeof(CMemRange));
+      tmpmr->type=MRT_DEV;
+      tmpmr->flags=0;
+      tmpmr->base=base;
+      tmpmr->size=size;
+      if (!Mem32DevIns(tmpmr)) {
+        Free(tmpmr);
+        LBtr(&sys_semas[SEMA_DEV_MEM],0);
+        return NULL;
+      }
+      LBtr(&sys_semas[SEMA_DEV_MEM],0);
+      return tmpmr->base;
+    }
+    tmpmr1=tmpmr1->next;
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+  return NULL;
+}
+
+U0 Mem32DevFree(U8 *base)
+{//Free 32-bit device address space.
+  CMemRange *tmpmr;
+  if (!base) return;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  tmpmr=dev.mem32_head.next;
+  while (tmpmr!=&dev.mem32_head) {
+    if (tmpmr->base==base) {
+      tmpmr->type=MRT_UNUSED;
+      break;
+    }
+    tmpmr=tmpmr->next;
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+}
+
+U8 *Mem64DevAlloc(I64 *_pages1Gig)
+{//Alloc 64-bit addr space for device.
+  U8 *a;
+  I64 i=*_pages1Gig,*pte;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  while (i--) {
+    a=dev.mem64_ptr-=1<<30;
+    do {
+      pte=MemPageTable(a);
+      *pte=*pte&~0x18 |0x11; //Uncached and present
+      InvlPg(dev.mem64_ptr);
+      a+=mem_page_size;
+    } while (a-dev.mem64_ptr<1<<30);
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+  return dev.mem64_ptr;
+}
+
+U0 Mem64DevFree(U8 *base,I64 pages1Gig)
+{//Free 64-bit device address space.
+  if (!base) return;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  if (base==dev.mem64_ptr)
+    dev.mem64_ptr+=pages1Gig*1<<30;
+//else not freed
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+}
+
+U0 UncachedAliasAlloc() //Make uncached alias for 4 lowest Gig.
+{
+  I64 i=4,*pte;
+  U8 *a;
+  a=dev.uncached_alias=Mem64DevAlloc(&i);
+  do {
+    pte=MemPageTable(a);
+    *pte=0x197+a-dev.uncached_alias;
+    InvlPg(a);
+    a+=mem_page_size;
+  } while (a-dev.uncached_alias<1<<32);
+}
+
+I64 BIOSTotalMem()
+{
+  I64 r01,r20;
+  U16           *m01=MEM_E801;
+  CMemE820      *m20=MEM_E820;
+
+  r01=0x100000+m01[0]<<10+m01[1]<<16;
+  r20=0;
+  if (m20->type) {
+    while (m20->type) {
+      if (m20->type==1)
+        r20+=m20->len;
+      m20++;
+    }
+  }
+  return MaxI64(r01,r20);
+}
+
+I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024)
+{//Helps pick DiskCache and RAMDisk sizes.
+//Can be used in BootHDIns() config scripts.
+  I64 i;
+  if (sys_data_bp)
+    i=sys_data_bp->alloced_u8s;
+  else
+    i=sys_code_bp->alloced_u8s;
+  if (i>=limit)
+    return max;
+  else
+    return min+(max-min)*i/limit;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Mem/PageTables.HC.HTML b/public/Wb/Home/Src/Kernel/Mem/PageTables.HC.HTML new file mode 100755 index 0000000..b79bc3a --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Mem/PageTables.HC.HTML @@ -0,0 +1,236 @@ + + + + + + + + + + + +
+asm {
+// ::/Doc/MemOverview.DD
+
+USE32
+SYS_INIT_PAGE_TABLES::
+//Check 1Gig page capability and set page size.
+        MOV     EAX,0x80000001
+        CPUID
+        MOV     EAX,1<<21
+//      BT      EDX,26
+//      JNC     @@05
+//      MOV     EAX,1<<30
+@@05:   MOV     U32 [MEM_PAGE_SIZE],EAX
+
+//Set mapped space limit
+        MOV     EAX,[MEM_PHYSICAL_SPACE]
+        MOV     EDX,[MEM_PHYSICAL_SPACE+4]
+        BT      U32 [MEM_PAGE_SIZE],30 //Round-up to 1Gig boundary?
+        JNC     @@10
+        ADD     EAX,0x3FFFFFFF
+        ADC     EDX,0
+        AND     EAX,~0x3FFFFFFF
+@@10:   INC     EDX     //Need 4Gig extra for uncached alias up at top of space.
+        MOV     [MEM_MAPPED_SPACE],EAX
+        MOV     [MEM_MAPPED_SPACE+4],EDX
+
+//How many 2Meg pages?
+        MOV     CL,21
+        ADD     EAX,0x1FFFFF
+        ADC     EDX,0
+        SHRD    EAX,EDX
+        SHR     EDX,CL
+        MOV     [MEM_2MEG_NUM],EAX
+        MOV     [MEM_2MEG_NUM+4],EDX
+
+//How many 1Gig pages?
+        MOV     CL,9
+        ADD     EAX,0x1FF
+        ADC     EDX,0
+        SHRD    EAX,EDX
+        SHR     EDX,CL
+        MOV     [MEM_1GIG_NUM],EAX
+        MOV     [MEM_1GIG_NUM+4],EDX
+
+//How many 512Gig pages?
+        MOV     CL,9
+        ADD     EAX,0x1FF
+        ADC     EDX,0
+        SHRD    EAX,EDX
+        SHR     EDX,CL
+        MOV     [MEM_512GIG_NUM],EAX
+        MOV     [MEM_512GIG_NUM+4],EDX
+
+//Set CSysFixedArea to zero
+        MOV     EDI,SYS_FIXED_AREA
+        XOR     EAX,EAX
+        MOV     ECX,sizeof(CSysFixedArea)/4
+        REP_STOSD
+
+        MOV     U32 [MEM_PML2],EDI
+//Check for 1Gig page capability.
+        BT      U32 [MEM_PAGE_SIZE],30
+        JC      @@15
+//Find PML2 Size
+        MOV     EAX,U32 [MEM_2MEG_NUM]
+        ADD     EAX,0x1FF
+        AND     EAX,~0x1FF
+        SHL     EAX,3
+        ADD     EDI,EAX
+
+//Find PML3 Size
+@@15:   MOV     U32 [MEM_PML3],EDI
+        MOV     EAX,U32 [MEM_1GIG_NUM]
+        ADD     EAX,0x1FF
+        AND     EAX,~0x1FF
+        SHL     EAX,3
+        ADD     EDI,EAX
+
+//Find PML4 Size
+        MOV     U32 [MEM_PML4],EDI
+        MOV     EAX,U32 [MEM_512GIG_NUM]
+        ADD     EAX,0x1FF
+        AND     EAX,~0x1FF
+        SHL     EAX,3
+        ADD     EAX,EDI
+
+        MOV     U32 [MEM_HEAP_BASE],EAX
+
+//Set page tables to zero
+        MOV     EDI,U32 [MEM_PML2]
+        SUB     EAX,EDI
+        MOV     ECX,EAX
+        SHR     ECX,2
+        XOR     EAX,EAX
+        REP_STOSD
+
+//Check for 1Gig page capability.
+        BT      U32 [MEM_PAGE_SIZE],30
+        JC      @@30
+
+//PML2: Use 2Meg Pages
+        MOV     EAX,0x87 //bit 7 is page size (2Meg)
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML2]
+        MOV     ECX,[MEM_2MEG_NUM]
+@@20:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x200000
+        ADC     EDX,0
+        LOOP    @@20
+//PML3: Use 2Meg Pages
+        MOV     EAX,[MEM_PML2]
+        OR      EAX,7
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML3]
+        MOV     ECX,[MEM_1GIG_NUM]
+@@25:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x1000
+        ADC     EDX,0
+        LOOP    @@25
+        JMP     @@40
+
+//PML3: Use 1Gig Pages
+@@30:   MOV     EAX,0x87 //bit 7 is page size (1Gig)
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML3]
+        MOV     ECX,[MEM_1GIG_NUM]
+@@35:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x40000000
+        ADC     EDX,0
+        LOOP    @@35
+
+//PML4
+@@40:   MOV     EAX,[MEM_PML3]
+        OR      EAX,7
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML4]
+        MOV     ECX,[MEM_512GIG_NUM]
+@@45:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x1000
+        ADC     EDX,0
+        LOOP    @@45
+        RET
+
+SYS_INIT_16MEG_SYS_CODE_BP::
+// Init sys_code_bp to BIOS E801 lowest 16Meg val.
+// BlkPoolsInit() adds the rest.
+        MOV     U32 [SYS_CODE_BP],SYS_FIXED_AREA+CSysFixedArea.sys_code_bp
+        MOV     U32 [SYS_CODE_BP+4],0
+
+        MOV     U32 [SYS_DATA_BP],0
+        MOV     U32 [SYS_DATA_BP+4],0
+
+        XOR     EAX,EAX
+        MOV     AX,U16 [MEM_E801] //1 Kb blks between 1M and 16M
+        SHL     EAX,10
+        ADD     EAX,0x100000
+        MOV     EDI,U32 [MEM_HEAP_BASE]
+        SUB     EAX,EDI
+
+//EDI=BASE EAX=SIZE
+        TEST    U8 [SYS_MEM_INIT_FLAG],1
+        JZ      @@05
+        PUSH    EAX
+        PUSH    EDI
+        MOV     ECX,EAX
+        MOV     AL,U8 [SYS_MEM_INIT_VAL]
+        REP_STOSB
+        POP     EDI
+        POP     EAX
+
+@@05:   SHR     EAX,MEM_PAG_BITS
+        MOV     ESI,SYS_FIXED_AREA+CSysFixedArea.sys_code_bp
+        MOV     EBX,U32 CBlkPool.mem_free_lst[ESI]
+        MOV     U32 CMemBlk.next[EDI],EBX
+        MOV     U32 CMemBlk.next+4[EDI],0
+        MOV     U32 CBlkPool.mem_free_lst[ESI],EDI
+        MOV     U32 CBlkPool.mem_free_lst+4[ESI],0
+        MOV     U32 CMemBlk.mb_signature[EDI],MBS_UNUSED_SIGNATURE_VAL
+        MOV     U32 CMemBlk.pags[EDI],EAX
+        SHL     EAX,MEM_PAG_BITS
+        ADD     U32 CBlkPool.alloced_u8s[ESI],EAX
+
+        BTS     U32 [SYS_RUN_LEVEL],RLf_16MEG_SYS_CODE_BP
+        RET
+}
+
+I64 *MemPageTable(U8 *a)
+{//Point to page table entry for addr.
+  if (Bt(&mem_page_size,30))
+    return *MEM_PML3(U64 *)+a>>30*8;
+  else
+    return *MEM_PML2(U64 *)+a>>21*8;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/MultiProc.HC.HTML b/public/Wb/Home/Src/Kernel/MultiProc.HC.HTML new file mode 100755 index 0000000..476e390 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/MultiProc.HC.HTML @@ -0,0 +1,420 @@ + + + + + + + + + + + +
+asm {
+        ALIGN   16,OC_NOP
+USE16
+//See TempleOS MultiCore.
+
+//This code gets copied to MP_VECT_ADDR.
+//See MemCpy(MP_VECT_ADDR.
+COREAP_16BIT_INIT::
+        JMP     @@05
+
+        ALIGN   4,OC_NOP
+AP_GDT_PTR:     DU16    sizeof(CGDT)-1;
+                DU64    0;
+
+@@05:   CLI
+        WBINVD
+        MOV     AX,MP_VECT_ADDR/16
+        MOV     DS,AX
+        LGDT    U32 [CAP16BitInit.ap_gdt_ptr]  //See mp->ap_gdt_ptr
+
+        MOV     EAX,SYS_START_CR0
+        MOV_CR0_EAX
+        DU8     0x66,0xEA;               //JMP CGDT.cs32:AP_32BIT_INIT
+        DU32    AP_32BIT_INIT;
+        DU16    CGDT.cs32;
+COREAP_16BIT_INIT_END::
+
+USE32
+AP_32BIT_INIT:
+        MOV     AX,CGDT.ds
+        MOV     DS,AX
+        MOV     ES,AX
+        MOV     FS,AX
+        MOV     GS,AX
+        MOV     SS,AX
+
+@@05:   LOCK
+        BTS     U32 [SYS_MP_CNT_LOCK],0
+        JC      @@05
+
+        MOV     ESI,U32 [SYS_MP_CNT_INITIAL]
+        LOCK
+        INC     U32 [SYS_MP_CNT_INITIAL]
+        LOCK
+        BTR     U32 [SYS_MP_CNT_LOCK],0
+
+        CMP     ESI,MP_PROCESSORS_NUM
+        JAE     I32 _SYS_HLT
+
+        IMUL2   ESI,sizeof(CCPU)
+        ADD     ESI,U32 [SYS_CPU_STRUCTS]
+
+        LEA     ESP,U32 CCPU.start_stk+sizeof(CCPU.start_stk)[ESI]
+        PUSH    U32 RFLAGG_START
+        POPFD
+        PUSH    U32 0   //Return from next call will be 64-bit
+        CALL    SYS_ENTER_LONG_MODE
+USE64
+        FNINIT
+        MOV     RAX,RSI
+        CALL    SET_GS_BASE
+@@10:   MOV     RAX,U64 CCPU.seth_task[RSI]
+        TEST    RAX,RAX
+        JZ      @@10
+        MOV     U64 CTask.gs[RAX],RSI
+        CALL    SET_FS_BASE
+
+        JMP     I32 _TASK_CONTEXT_RESTORE
+}
+
+U0 TSSBusy(I64 tr,Bool val=OFF)
+{//See ::/Demo/Lectures/Ring3.HC.
+  LBEqu((&sys_gdt)(U8 *)+tr+4,9,val);
+}
+
+CTSS *TSSNew(I64 cpu_num)
+{
+  U32 *d,*d1;
+  CTSS *tss=CAlloc(sizeof(CTSS));
+  tss->io_map_offset=offset(CTSS.io_map);
+  MemSet(tss->io_map,0xFF,0x10000/8);
+
+  tss->st0=MAlloc(MEM_INTERRUPT_STK);
+  tss->rsp0=tss->st0(U8 *)+MSize(tss->st0);
+  tss->st1=MAlloc(MEM_INTERRUPT_STK);
+  tss->rsp1=tss->st1(U8 *)+MSize(tss->st1);
+  tss->st2=MAlloc(MEM_INTERRUPT_STK);
+  tss->rsp2=tss->st2(U8 *)+MSize(tss->st2);
+
+  tss->tr      =offset(CGDT.tr)+cpu_num*16;
+  tss->tr_ring3=offset(CGDT.tr_ring3)+cpu_num*16;
+
+  d=(&sys_gdt)(U8 *)+tss->tr;
+  d1=d(U8 *)+4;
+  *d =0x0000FFFF;
+  *d1=0x008F8900;
+  d(U8 *)+=2;
+  *d|=tss & 0x00FFFFFF;
+  *d1++|=tss & 0xFF000000;
+  *d1++=tss>>32;
+  *d1=0;
+
+  d=(&sys_gdt)(U8 *)+tss->tr_ring3;
+  d1=d(U8 *)+4;
+  *d =0x0000FFFF;
+  *d1=0x008FE900;
+  d(U8 *)+=2;
+  *d|=tss & 0x00FFFFFF;
+  *d1++|=tss & 0xFF000000;
+  *d1++=tss>>32;
+  *d1=0;
+
+  return tss;
+}
+
+CCPU *CPUStructInit(I64 num,CCPU *c,CTask *seth_task)
+{//Seth is null when called by adam on CSysFixedArea.boot_cpu0
+  MemSet(c,0,sizeof(CCPU));
+  c->addr=c;
+  c->num=num;
+  c->idle_factor=0.01;
+  QueInit(&c->next_dying);
+  if (Bt(&sys_run_level,RLf_16MEG_ADAM_HEAP_CTRL)) {
+    c->idle_task=Spawn(0,NULL,"Idle Task",,Fs,,0);
+    LBts(&c->idle_task->task_flags,TASKf_IDLE);
+    c->tss=TSSNew(num);
+  }
+  c->seth_task=seth_task;// It waits for this to be filled-in: seth_task
+  return c;
+}
+
+U0 MPInt(U8 num,I64 cpu_num=1)
+{//Generate interrupt for specified core.
+  if (cpu_num>=mp_cnt) {
+    if (!Bt(&sys_run_level,RLf_MP))
+      return;
+    else
+      throw('MultCore');
+  }
+  PUSHFD
+  CLI //Multitasking safe because each core has a local apic and IRQ's are off
+  while (*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)&0x1000)
+    PAUSE
+  *(dev.uncached_alias+LAPIC_ICR_HIGH)(U32 *)=dev.mp_apic_ids[cpu_num]<<24;
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0x4000+num;
+  POPFD
+}
+
+U0 MPIntAll(U8 num)
+{//Generate interrupt for all but own core.
+  PUSHFD
+  CLI //Multitasking safe because each core has a local apic and IRQ's are off
+  while (*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)&0x1000)
+    PAUSE
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4800+num;
+  POPFD
+}
+
+U0 MPNMInt()
+{//Generate nonmaskable interrupt.
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4400;
+}
+
+U0 MPHalt()
+{//Halt all other cores.
+  mp_cnt=1;
+  MPNMInt;
+  Busy(10000);
+}
+
+U0 MPAPICInit()
+{//Called by adam during start-up
+//and other cores during initialization
+  //after Core0StartMP().
+  *(dev.uncached_alias+LAPIC_SVR)(U32 *)|=LAPICF_APIC_ENABLED;
+  dev.mp_apic_ids[Gs->num]=*(dev.uncached_alias+LAPIC_APIC_ID)(U32 *)>>24;
+  *(dev.uncached_alias+LAPIC_LDR)(U32 *)=dev.mp_apic_ids[Gs->num]<<24;
+  *(dev.uncached_alias+LAPIC_DFR)(U32 *)=0xF0000000;
+
+  //  MemSet(dev.uncached_alias+LAPIC_IRR,0,0x20);
+  //  MemSet(dev.uncached_alias+LAPIC_ISR,0,0x20);
+  //  MemSet(dev.uncached_alias+LAPIC_TMR,0,0x20);
+
+  SetRAX(Gs->tss->tr);
+  LTR   AX
+  if (Gs->num) {
+    IntInit1;
+    SetRFlags(RFLAGG_NORMAL);
+  }
+}
+
+#assert !offset(CJobCtrl.next_waiting)
+
+U0 CoreAPSethTask()
+{
+  CJobCtrl *ctrl=&Fs->srv_ctrl;
+  while (TRUE) {
+    STI
+    do {
+      TaskKillDying;
+      do PAUSE
+      while (LBts(&ctrl->flags,JOBCf_LOCKED));
+    } while (ctrl->next_waiting!=ctrl && JobRunOne(GetRFlags,ctrl));
+    CLI
+    LBts(&Fs->task_flags,TASKf_AWAITING_MSG);
+    LBtr(&ctrl->flags,JOBCf_LOCKED);
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    Yield;
+    LBtr(&Fs->task_flags,TASKf_IDLE);
+  }
+}
+
+CJob *JobQue(I64 (*fp_addr)(U8 *data),U8 *data=NULL,
+       I64 target_cpu=1,I64 flags=1<<JOBf_FREE_ON_COMPLETE,
+       I64 job_code=JOBT_CALL,U8 *aux_str=NULL,I64 aux1=0,I64 aux2=0)
+{//Queue multicore jobs, handled by Seth tasks.
+//Set flags to zero if you wish to get the res.
+  //See ::/Demo/MultiCore/Lock.HC
+  CJobCtrl *ctrl;
+  CJob *tmpc;
+  CTask *seth;
+  if (!(0<=target_cpu<mp_cnt))
+    throw('MultCore');
+  tmpc=ACAlloc(sizeof(CJob));
+  if (aux_str)
+    tmpc->aux_str=AStrNew(aux_str);
+  tmpc->job_code=job_code;
+  tmpc->addr=fp_addr;
+  tmpc->fun_arg=data;
+  tmpc->flags=flags;
+  tmpc->aux1=aux1;
+  tmpc->aux2=aux2;
+  seth=cpu_structs[target_cpu].seth_task;
+  tmpc->ctrl=ctrl=&seth->srv_ctrl;
+  PUSHFD
+  CLI
+  while (LBts(&ctrl->flags,JOBCf_LOCKED))
+    Yield;
+  if (ctrl->next_waiting==ctrl && LBtr(&seth->task_flags,TASKf_AWAITING_MSG))
+    MPInt(I_WAKE,target_cpu);
+  QueIns(tmpc,ctrl->last_waiting);
+  LBtr(&ctrl->flags,JOBCf_LOCKED);
+  POPFD
+  return tmpc;
+}
+
+CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,U8 *task_name=NULL,
+        I64 target_cpu, CTask *parent=NULL, //NULL means adam
+        I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE)
+{
+  CTask *res;
+  CJob *tmpc=JobQue(fp_addr,data,target_cpu,
+        flags,JOBT_SPAWN_TASK,task_name,parent,stk_size);
+  CJobCtrl *ctrl;
+
+  while (!Bt(&tmpc->flags,JOBf_DONE)) {
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    Yield;
+  }
+  LBtr(&Fs->task_flags,TASKf_IDLE);
+
+  res=tmpc->spawned_task;
+  ctrl=tmpc->ctrl;
+  PUSHFD
+  CLI
+  while (LBts(&ctrl->flags,JOBCf_LOCKED))
+    Yield;
+  QueRem(tmpc);
+  LBtr(&ctrl->flags,JOBCf_LOCKED);
+  POPFD
+  JobDel(tmpc);
+  return res;
+}
+
+U0 CoreAPSethInit()
+{//Called by multicore's seth task after Core0StartMP()
+//as the first thing a CPU does before waiting for jobs.
+  MPAPICInit;
+  Fs->rip=&CoreAPSethTask;
+  TaskContextRestore;
+}
+
+U0 Core0StartMP()
+{//Called by adam during start-up.
+  CTask *task;
+  U8 buf[STR_LEN];
+  CAP16BitInit *mp=MP_VECT_ADDR;
+  CCPU *c;
+  I64 i,my_mp_cnt;
+  CRAXRBCRCXRDX ee;
+
+  CPUId(0x1,&ee);
+  if (!Bt(&ee.rdx,9))
+    return;
+
+  PUSHFD
+  CLI
+  if (mp_cnt>1) {
+    my_mp_cnt=mp_cnt;
+    MPHalt; //sets mp_cnt to 1
+    for (i=1;i<my_mp_cnt;i++) {
+      c=&cpu_structs[i];
+      JobQueDel(&c->seth_task->srv_ctrl.next_waiting);
+      JobQueDel(&c->seth_task->srv_ctrl.next_done);
+    }
+  }
+  MemSet(&cpu_structs[1],0,sizeof(CCPU)*(MP_PROCESSORS_NUM-1));
+
+  //When you start-up other cores, they jump to an addr
+  //specified by a byte vect number, MPN_VECT which corresponds
+  //to a location 4096*vect number, MP_VECT_ADDR.
+  MemCpy(mp,COREAP_16BIT_INIT,COREAP_16BIT_INIT_END-COREAP_16BIT_INIT);
+  MemCpy(&mp->ap_gdt_ptr,SYS_GDT_PTR,sizeof(CSysLimitBase));
+  mp_cnt_initial=mp_cnt=1;
+  mp_cnt_lock=0;
+
+  *(dev.uncached_alias+LAPIC_LVT_ERR)(U32 *)=
+        *(dev.uncached_alias+LAPIC_LVT_ERR)(U32 *)&0xFFFFFF00+MPN_VECT;
+  WBINVD //Not sure why this is needed. Might just need delay. MemCpy above?
+
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4500; //assert init IPI
+  Busy(10000);
+
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4600+MPN_VECT; //start-up
+  Busy(200);
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4600+MPN_VECT;
+
+  Busy(100000);
+  for (i=0;i<10000;i++)
+    LBts(&mp_cnt_lock,0); //Don't let more through
+  my_mp_cnt=mp_cnt_initial;
+
+  if (my_mp_cnt>MP_PROCESSORS_NUM)
+    my_mp_cnt=MP_PROCESSORS_NUM;
+
+  for (i=1;i<my_mp_cnt;i++) {
+    StrPrint(buf,"Seth Task CPU%02X",i);
+    task=Spawn(&CoreAPSethInit,NULL,buf,,,MEM_SETH_STK,0);
+    task->rflags=RFLAGG_START;
+//CTask alloced off this core's seth_task's heap (Which is Adam)
+    CPUStructInit(i,&cpu_structs[i],task);
+    WBINVD //Not sure why this is needed.  Might just need delay.
+  }
+
+  //Make sure they're all up-and-running
+  for (i=1;i<my_mp_cnt;i++)
+    while (!Bt(&cpu_structs[i].seth_task->task_flags,TASKf_AWAITING_MSG))
+      PAUSE;
+
+  POPFD
+  mp_cnt=my_mp_cnt; //Finalize cnt
+}
+
+U0 Core0Init()
+{//Called by adam during start-up
+  CRAXRBCRCXRDX ee;
+  CPUId(0x1,&ee);
+
+  mp_cnt_initial=mp_cnt=1;
+  mp_cnt_lock=0;
+
+  dbg.mp_crash=ACAlloc(sizeof(CMPCrash));
+
+  //Must be in code heap because init code uses 32 bit addr of cpu_struct
+  adam_task->gs=cpu_structs=
+        CAlloc(sizeof(CCPU)*MP_PROCESSORS_NUM,Fs->code_heap);
+  CPUStructInit(0,cpu_structs,adam_task);
+  asm {//RAX has GS
+    IMPORT SET_GS_BASE;
+    CALL SET_GS_BASE
+  }
+  if (Bt(&ee.rdx,9)) {
+//Unnecessary?
+    //    SetMSR(IA32_LAPIC_BASE,dev.uncached_alias+LAPIC_BASE+0x900);
+    MPAPICInit;
+  }
+}
+
+interrupt U0 IntMPCrash()
+{//Entering the debugger from another core causes an interrupt on Core0
+//Which calls this routine.
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+  mp_cnt=1;
+  Raw(ON);
+  text.raw_flags|=RWF_SHOW_DOLLAR;
+  "MP Crash CPU%02X Task:%08X\n"
+  "RIP:%P\n",dbg.mp_crash->cpu_num,dbg.mp_crash->task,dbg.mp_crash->rip;
+  Panic(dbg.mp_crash->msg,dbg.mp_crash->msg_num);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/PCIBIOS.HC.HTML b/public/Wb/Home/Src/Kernel/PCIBIOS.HC.HTML new file mode 100755 index 0000000..2bce1ac --- /dev/null +++ b/public/Wb/Home/Src/Kernel/PCIBIOS.HC.HTML @@ -0,0 +1,320 @@ + + + + + + + + + + + +
+asm {
+USE32
+
+SYS_PCIBIOS_SERVICE_DIR:: DU32  0;
+SYS_PCI_SERVICES::       DU32   0;
+
+SYS_FIND_PCIBIOS_SERVICE_DIR::
+        MOV     ESI,0xE0000
+        MOV     ECX,(0x100000-0xE0000)/4
+@@05:   CMP     U32 [ESI],'_32_'
+        JNE     @@20
+        PUSH    ECX
+        XOR     ECX,ECX
+        MOV     CL,U8 9[ESI]
+        SHL     ECX,4
+@@10:   MOV     EDI,ESI
+        XOR     EAX,EAX
+        XOR     EDX,EDX
+@@15:   MOV     DL,U8 [EDI]
+        ADD     EAX,EDX
+        INC     EDI
+        DEC     ECX
+        JNZ     @@15
+        POP     ECX
+        TEST    AL,AL
+        JNZ     @@20
+        MOV     U32 [SYS_PCIBIOS_SERVICE_DIR],ESI
+        MOV     ESI,U32 4[ESI]
+        MOV     U32 [SYS_PCIBIOS_SERVICE_CALL],ESI
+        RET
+
+@@20:   ADD     ESI,4
+        LOOP    @@05
+        MOV     U32 [SYS_PCIBIOS_SERVICE_DIR],0
+        RET
+
+SYS_FIND_PCI_SERVICES::
+        MOV     ESI,U32 [SYS_PCIBIOS_SERVICE_DIR]
+        TEST    ESI,ESI
+        JNZ     @@05
+        MOV     U32 [SYS_PCI_SERVICES],0
+        RET
+@@05:   MOV     EAX,'$PCI'
+        XOR     EBX,EBX
+        DU8     0x9A;            //CALL CGDT.cs32:PCIBIOS_SERVICE
+SYS_PCIBIOS_SERVICE_CALL:: DU32 0;
+        DU16    CGDT.cs32;
+        TEST    AL,AL
+        JNZ     @@05
+        LEA     ESI,U32 [EBX+EDX]
+        MOV     U32 [SYS_PCI_SERVICES],ESI
+        RET
+
+@@05:   MOV     U32 [SYS_PCI_SERVICES],0
+        RET
+
+USE64
+C32_EAX::       DU32    0;
+C32_EBX::       DU32    0;
+C32_ECX::       DU32    0;
+C32_EDX::       DU32    0;
+C32_ESI::       DU32    0;
+C32_EDI::       DU32    0;
+C32_EFLAGS::    DU32    0;
+
+C32_RSP::       DU64    0;
+
+_FAR_CALL32::
+//This calls a 32-bit mode routine.
+//(We must switch from 64-bit mode to do it.)
+//
+//NON REENTRANT
+//
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        TEST    RAX,RAX
+        JNZ     @@05
+        POP     RBP
+        RET1    8       //return FALSE
+@@05:   MOV     U32 [C32_ADD],EAX
+        PUSH_REGS
+        PUSHFD
+        XOR     RAX,RAX
+        PUSH    U64 FS:CTask.addr[RAX]
+        PUSH    U64 GS:CCPU.addr[RAX]
+        MOV     U64 [C32_RSP],RSP
+        PUSH    U32 CGDT.ds             //STKSEG
+        PUSH    U32 BOOT_RAM_LIMIT      //STK
+        PUSH    U32 0                   //FLAGS--interrupts off
+        PUSH    U32 CGDT.cs32
+        LEA     RAX,[@@15]
+        PUSH    RAX
+        IRET
+USE32
+@@15:
+        WBINVD
+//disable paging
+        MOV_EAX_CR0
+        BTR     EAX,31
+        MOV_CR0_EAX
+
+        MOV     ECX,IA32_EFER
+        XOR     EDX,EDX
+        XOR     EAX,EAX
+        WRMSR
+
+        MOV     AX,CGDT.ds
+        MOV     FS,AX
+        MOV     GS,AX
+//SS already set
+
+        MOV     EAX,U32 [C32_EAX]
+        MOV     EBX,U32 [C32_EBX]
+        MOV     ECX,U32 [C32_ECX]
+        MOV     EDX,U32 [C32_EDX]
+        MOV     ESI,U32 [C32_ESI]
+        MOV     EDI,U32 [C32_EDI]
+        MOV     U32 [C32_EFLAGS],0
+
+        DU8     0x9A;            //CALL CGDT.cs32:[C32_ADD]
+C32_ADD:: DU32  0;
+        DU16    CGDT.cs32;
+
+        PUSHFD
+        POP     U32 [C32_EFLAGS]
+
+        MOV     U32 [C32_EAX],EAX
+        MOV     U32 [C32_EBX],EBX
+        MOV     U32 [C32_ECX],ECX
+        MOV     U32 [C32_EDX],EDX
+        MOV     U32 [C32_ESI],ESI
+        MOV     U32 [C32_EDI],EDI
+
+        PUSH    U32 0   //Return from next call will be 64-bit
+        CALL    SYS_ENTER_LONG_MODE
+
+USE64   MOV     RSP,U64 [C32_RSP]
+        POP     RAX
+        CALL    SET_GS_BASE
+        POP     RAX
+        CALL    SET_FS_BASE
+
+        POPFD
+        POP_REGS
+        XOR     RAX,RAX
+        MOV     AL,TRUE
+        POP     RBP
+        RET1    8
+}
+
+_extern C32_EAX U32 c32_eax;
+_extern C32_EBX U32 c32_ebx;
+_extern C32_ECX U32 c32_ecx;
+_extern C32_EDX U32 c32_edx;
+_extern C32_ESI U32 c32_esi;
+_extern C32_EDI U32 c32_edi;
+_extern C32_EFLAGS U32 c32_eflags;
+_extern SYS_PCI_SERVICES U32 sys_pci_services;
+
+_extern _FAR_CALL32 Bool FarCall32(U0 (*fp_addr)());//Not reentrant.For PCIBIOS.
+
+U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg)
+{//Read U8 in PCI configspace at bus,dev,fun,reg.
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB108;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  if (FarCall32(sys_pci_services))
+    res=c32_ecx.u8[0];
+  else
+    res=0xFF;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg)
+{//Read U16 in PCI configspace at bus,dev,fun,reg.
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB109;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  if (FarCall32(sys_pci_services))
+    res=c32_ecx.u16[0];
+  else
+    res=0xFFFF;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg)
+{//Read U32 in PCI configspace at bus,dev,fun,reg.
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10A;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  if (FarCall32(sys_pci_services))
+    res=c32_ecx;
+  else
+    res=0xFFFFFFFF;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
+{//Write U8 in PCI configspace at bus,dev,fun,reg.
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10B;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  c32_ecx=val;
+  FarCall32(sys_pci_services);
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+}
+
+U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
+{//Write U16 in PCI configspace at bus,dev,fun,reg.
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10C;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  c32_ecx=val;
+  FarCall32(sys_pci_services);
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+}
+
+U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
+{//Write U32 in PCI configspace at bus,dev,fun,reg.
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10D;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  c32_ecx=val;
+  FarCall32(sys_pci_services);
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+}
+
+I64 PCIClassFind(I64 class_code,I64 n)
+{/*Find bus,dev,fun of Nth class_code dev.
+
+class_code is low three bytes
+n is index starting at zero
+Return: -1 not found
+else bus,dev,fun.
+*/
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB103;
+  c32_esi=n;
+  c32_ecx=class_code;
+  if (FarCall32(sys_pci_services) && !c32_eax.u8[1])
+    res=c32_ebx.u8[1]<<16+(c32_ebx&0xF8)<<5+c32_ebx&7;
+  else
+    res=-1;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+
+ diff --git a/public/Wb/Home/Src/Kernel/QSort.HC.HTML b/public/Wb/Home/Src/Kernel/QSort.HC.HTML new file mode 100755 index 0000000..a05c07f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/QSort.HC.HTML @@ -0,0 +1,135 @@ + + + + + + + + + + + +
+U0 QSortI64(I64 *base,I64 num, I64 (*fp_compare)(I64 e1,I64 e2))
+{/*Quick Sort for width==8.
+fp_compare() passes by value instead of ref.
+
+For ascending strings: return StrCmp(e1,e2);
+For ascending ints   : return e1-e2;
+
+Maybe, look at ::/Demo/MultiCore/MPRadix.HC.
+*/
+  I64 i,*left,*right,pivot;
+  if (num>1) {
+    left =base;
+    right=base+num-1;
+    pivot=base[num/2];
+    do {
+      while ((*fp_compare)(*left,pivot)<0)
+        left++;
+      while ((*fp_compare)(*right,pivot)>0)
+        right--;
+      if (left<=right)
+        SwapI64(left++,right--);
+    } while (left<=right);
+    i=right+1-base;
+    if (1<i<num)
+      QSortI64(base,i,fp_compare);
+    i=base+num-left;
+    if (1<i<num)
+      QSortI64(left,i,fp_compare);
+  }
+}
+
+U0 QSort2a(U8 **base,I64 num,I64 (*fp_compare)(U8 **_e1,U8 **_e2))
+{//Not public.For case of width==size(U8 *)==8.
+//fp_compare() passes by ref.
+  I64 i;
+  U8 **left,**right,*pivot;
+  left =base;
+  right=base+num-1;
+  pivot=base[num/2];
+  do {
+    while ((*fp_compare)(left,&pivot)<0)
+      left++;
+    while ((*fp_compare)(right,&pivot)>0)
+      right--;
+    if (left<=right)
+      SwapI64(left++,right--);
+  } while (left<=right);
+  i=right+1-base;
+  if (1<i<num)
+    QSort2a(base,i,fp_compare);
+  i=base+num-left;
+  if (1<i<num)
+    QSort2a(left,i,fp_compare);
+}
+U0 QSort2b(U8 *base,I64 num, I64 width,
+        I64 (*fp_compare)(U8 *e1,U8 *e2),U8 *tmp)
+{//Not public
+  I64 i;
+  U8 *left,*right,*pivot=tmp+width;
+  left =base;
+  right=base+(num-1)*width;
+  MemCpy(pivot,base+num/2*width,width);
+  do {
+    while ((*fp_compare)(left,pivot)<0)
+      left+=width;
+    while ((*fp_compare)(right,pivot)>0)
+      right-=width;
+    if (left<=right) {
+      if (left!=right) {
+        MemCpy(tmp,right,width);
+        MemCpy(right,left,width);
+        MemCpy(left,tmp,width);
+      }
+      left+=width;
+      right-=width;
+    }
+  } while (left<=right);
+  i=1+(right-base)/width;
+  if (1<i<num)
+    QSort2b(base,i,width,fp_compare,tmp);
+  i=num+(base-left)/width;
+  if (1<i<num)
+    QSort2b(left,i,width,fp_compare,tmp);
+}
+U0 QSort(U8 *base,I64 num, I64 width, I64 (*fp_compare)(U8 *e1,U8 *e2))
+{/*Quick Sort: fp_compare() passes by ref.
+
+For ascending strings: return StrCmp(*e1,*e2);
+For ascending ints   : return *e1-*e2;
+Don't return e1-e2 if numbers can overflow, return -1,0 or 1.
+
+Maybe, look at ::/Demo/MultiCore/MPRadix.HC.
+*/
+  U8 *tmp;
+  if (width && num>1) {
+    if (width==sizeof(U8 *))    //assign instead of MemCpy for width 8
+      QSort2a(base,num,fp_compare);
+    else {
+      tmp=MAlloc(width*2);
+      QSort2b(base,num,width,fp_compare,tmp);
+      Free(tmp);
+    }
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/Sched.HC.HTML b/public/Wb/Home/Src/Kernel/Sched.HC.HTML new file mode 100755 index 0000000..a14170a --- /dev/null +++ b/public/Wb/Home/Src/Kernel/Sched.HC.HTML @@ -0,0 +1,356 @@ + + + + + + + + + + + +
+/*On each core, tasks are linked in a
+circular doubly-linked list queue with
+the Seth task as the head.  On Core0,
+the queue order represents the front-to-back
+window stack order with the window mgr
+as the wallpaper.
+
+The scheduler is round-robin.  It checks
+if a task is ready and runs it or skips it.
+Swapping tasks just involves storing and
+restoring regs (no disk I/O for virtual
+memory and no addr map changes).  It is
+always fully identity-mapped on all cores.
+Tasks can be switched in half a microsecond.
+
+The scheduler checks if a task is
+waiting for a certain time or waiting
+on a message and skips if not ready.
+A task runs until it voluntarily yields ctrl
+with a call to Yield().  Tasks waiting on I/O
+often loop, checking for a status and
+Yielding.  This does not really degrade
+performance, but pegs the CPU Load.
+
+The scheduler checks for a few keys:
+
+<CTRL-ALT-x> kill a task.
+<CTRL-ALT-DEL> reboots.
+<CTRL-ALT-n> Next task.
+<CTRL-ALT-c> breaks execution of a program.
+
+Each core has its own circular task queue.
+For AP processors, they have a "Seth" task
+which stays in a loop waiting for jobs or
+requests to spawn tasks.  See CoreAPSethTask().
+*/
+
+U0 TaskFocusNext()
+{
+  CTask *task,*_task=sys_focus_task;
+  sys_focus_task=NULL;
+  if (!_task) _task=adam_task;
+  task=_task->next_task;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+      sys_focus_task=task;
+      CallExtNum(EXT_WIN_TO_TOP,task,TRUE);
+      return;
+    }
+    task=task->next_task;
+  } while (task!=_task);
+}
+
+asm {
+TASK_CONTEXT_SAVE::
+//OUT:  RSI=FS
+        PUSH    RSI
+        PUSHFD
+        XOR     RSI,RSI
+        MOV     RSI,FS:CTask.addr[RSI]
+        POP     U64 CTask.rflags[RSI]
+        POP     U64 CTask.rsi[RSI]
+        MOV     U64 CTask.rax[RSI],RAX
+
+/*Divert the stk to the Task memory
+and push onto it and divert it back.
+It's a little faster.
+*/
+        MOV     RAX,RSP
+        LEA     RSP,U64 CTask.r15+8[RSI]
+        PUSH    R15
+        PUSH    R14
+        PUSH    R13
+        PUSH    R12
+        PUSH    R11
+        PUSH    R10
+        PUSH    R9
+        PUSH    R8
+        PUSH    RDI
+        PUSH    RBP
+        PUSH    RBX
+        PUSH    RDX
+        PUSH    RCX
+        MOV     RSP,RAX
+
+        MOV     RAX,U64 CTask.fpu_mmx[RSI]
+        FXSAVE  U64 [RAX]
+
+        MOV     RDX,U64 CTask.bpt_lst[RSI]
+@@05:   TEST    RDX,RDX
+        JZ      @@10
+        MOV     RDI,U64 CBpt.addr[RDX]
+        MOV     AL,U8 CBpt.val[RDX]
+        MOV     U8 [RDI],AL
+        MOV     RDX,U64 CBpt.next[RDX]
+        JMP     @@05
+@@10:   RET
+//************************************
+_TASK_CONTEXT_RESTORE::
+        XOR     RAX,RAX
+        INC     U64 GS:CCPU.swap_cnter[RAX]
+        MOV     RSI,FS:CTask.addr[RAX]
+        BT      U32 CTask.rflags[RSI],RFLAGf_INT
+        JNC     @@05
+        BTS     U32 GS:CCPU.cpu_flags[RAX],CPUf_RAN_A_TASK
+@@05:   BT      U64 CTask.task_flags[RSI],TASKf_DISABLE_BPTS
+        JC      @@15
+        MOV     RDX,U64 CTask.bpt_lst[RSI]
+@@10:   TEST    RDX,RDX
+        JZ      @@15
+        MOV     RDI,U64 CBpt.addr[RDX]
+        MOV     U8 [RDI],OC_BPT
+        MOV     RDX,U64 CBpt.next[RDX]
+        JMP     @@10
+
+@@15:   INC     U64 CTask.swap_cnter[RSI]
+
+        MOV     RAX,U64 CTask.fpu_mmx[RSI]
+        FXRSTOR U64 [RAX]
+
+        MOV     RAX,RSP
+        LEA     RSP,U64 CTask.rcx[RSI]
+        POP     RCX
+        POP     RDX
+        POP     RBX
+        POP     RBP
+        POP     RDI
+        POP     R8
+        POP     R9
+        POP     R10
+        POP     R11
+        POP     R12
+        POP     R13
+        POP     R14
+        POP     R15
+        MOV     RSP,RAX
+
+        MOV     RAX,U64 CTask.rax[RSI]
+        PUSH    CGDT.ds
+        PUSH    U64 CTask.rsp[RSI]
+        PUSH    U64 CTask.rflags[RSI]
+        PUSH    CGDT.cs64
+        PUSH    U64 CTask.rip[RSI]
+        MOV     RSI,U64 CTask.rsi[RSI]
+        IRET
+//************************************
+END_RSI_TASK:
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+_TASK_END_NOW::
+        CALL    &TaskEnd
+        MOV     RSI,RAX
+        CALL    SET_FS_BASE
+        JMP     I8 RESTORE_RSI_TASK
+
+_YIELD::
+        PUSHFD
+        TEST    U8 [SYS_SEMAS+SEMA_SINGLE_USER*DFT_CACHE_LINE_WIDTH],1
+        JZ      @@05
+        POPFD           //If single user, don't change task.
+        RET
+
+@@05:   CLI
+        CALL    TASK_CONTEXT_SAVE
+        MOV     EBX,U32 _RET
+        MOV     U64 CTask.rip[RSI],RBX
+        POP     U64 CTask.rflags[RSI]
+        MOV     U64 CTask.rsp[RSI],RSP
+        MOV     RSI,U64 CTask.next_task[RSI]
+
+RESTORE_RSI_TASK:
+        TEST    U64 [SYS_CTRL_ALT_FLAGS],1<<CTRL_ALT_DEL|
+1<<CTRL_ALT_TAB|1<<CTRL_ALT_X|1<<CTRL_ALT_C
+        JNZ     HANDLE_SYSF_KEY_EVENT
+
+RESTORE_RSI_TASK2:
+@@20:   BT      U64 CTask.task_flags[RSI],TASKf_KILL_TASK
+        JC      END_RSI_TASK
+        TEST    U64 CTask.task_flags[RSI],
+                1<<TASKf_AWAITING_MSG|1<<TASKf_SUSPENDED
+        JNZ     @@25
+
+        MOV     RAX,U64 [&cnts.jiffies]
+        CMP     U64 CTask.wake_jiffy[RSI],RAX
+        JG      @@25    //Jmp if not ready, yet.
+
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+        JMP     I32 _TASK_CONTEXT_RESTORE
+
+@@25:   MOV     RSI,U64 CTask.next_task[RSI]
+        XOR     RAX,RAX
+        CMP     U64 GS:CCPU.seth_task[RAX],RSI
+        JNE     @@20    //Jmp if not Seth
+        BTR     U32 GS:CCPU.cpu_flags[RAX],CPUf_RAN_A_TASK
+        JC      @@20    //Jmp if had chance for IRQ already
+        MOV     RAX,U64 GS:CCPU.idle_task[RAX]
+        MOV     RSP,U64 CTask.stk[RAX]
+        ADD     RSP,MEM_DFT_STK+CTaskStk.stk_base       //Rst to top
+        CALL    SET_FS_BASE
+        STI     //Restore idle task so we can unmask IRQs.
+        HLT
+SYS_IDLE_PT::
+        CLI
+
+RESTORE_SETH_TASK_IF_READY:
+        XOR     RAX,RAX
+        MOV     RSI,GS:CCPU.seth_task[RAX]
+        JMP     RESTORE_RSI_TASK
+
+HANDLE_SYSF_KEY_EVENT:
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+        XOR     RBX,RBX
+        MOV     RAX,GS:CCPU.num[RBX]
+        TEST    RAX,RAX
+        JNZ     I32 RESTORE_RSI_TASK2
+
+        MOV     EAX,U32 SYS_CTRL_ALT_FLAGS
+        LOCK
+        BTR     U32 [RAX],CTRL_ALT_DEL
+        JC      I32 &Reboot
+
+        CMP     U64 GS:CCPU.idle_task[RBX],RSI
+        JE      RESTORE_SETH_TASK_IF_READY
+
+        LOCK
+        BTR     U32 [RAX],CTRL_ALT_TAB
+        JNC     @@05
+        CALL    &TaskFocusNext
+        JMP     I32 RESTORE_FS_TASK
+
+@@05:   LOCK
+        BTR     U32 [RAX],CTRL_ALT_X
+        JC      END_FOCUS_USER
+        LOCK
+        BTR     U32 [RAX],CTRL_ALT_C
+        JNC     I32 RESTORE_RSI_TASK
+
+BREAK_FOCUS_USER:
+        MOV     RSI,U64 [SYS_FOCUS_TASK]
+        TEST    RSI,RSI
+        JZ      RESTORE_SETH_TASK_IF_READY
+        BT      U64 CTask.win_inhibit[RSI],WIf_SELF_FOCUS
+        JC      I32 RESTORE_RSI_TASK
+        LOCK
+        BTR     U64 CTask.task_flags[RSI],TASKf_BREAK_LOCKED
+        JNC     @@10
+        LOCK
+        BTS     U64 CTask.task_flags[RSI],TASKf_PENDING_BREAK
+        JMP     I32 RESTORE_RSI_TASK
+
+@@10:   MOV     RAX,&Break
+        MOV     U64 CTask.rip[RSI],RAX
+        BT      U64 CTask.task_flags[RSI],TASKf_BREAK_TO_SHIFT_ESC
+        JC      I32 RESTORE_RSI_TASK
+
+//Do these now, in case interrupt happens.
+        MOV     U64 CTask.wake_jiffy[RSI],0
+        PUSH    RSI
+        CALL    &TaskRstAwaitingMsg
+        JMP     I32 RESTORE_RSI_TASK
+
+END_FOCUS_USER:
+        MOV     RSI,U64 [SYS_FOCUS_TASK]
+        CALL    &TaskFocusNext
+        TEST    RSI,RSI
+        JZ      I32 RESTORE_SETH_TASK_IF_READY
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+        BT      U64 CTask.win_inhibit[RSI],WIf_SELF_FOCUS
+        JC      I32 RESTORE_RSI_TASK
+        LOCK
+        BTS     U64 CTask.task_flags[RSI],TASKf_KILL_TASK
+        JMP     I32 END_RSI_TASK
+
+RESTORE_FS_TASK:
+        XOR     RSI,RSI
+        MOV     RSI,FS:CTask.addr[RSI]
+        JMP     I32 RESTORE_RSI_TASK
+}
+
+_extern _TASK_CONTEXT_RESTORE U0 TaskContextRestore(); //Restore a task context.
+_extern _YIELD U0 Yield(); //Yield cpu to next task.
+_extern _TASK_END_NOW U0 TaskEndNow(); //Terminate current task.
+
+U0 TaskQueIns(CTask *task,CTask *pred=NULL)
+{//Insert a task in the scheduler running task queue.
+//You have no business with this, probably.
+  CTask *last;
+  PUSHFD
+  CLI
+  if (!pred) pred=Fs;
+  last=pred->last_task;
+  last->next_task=pred->last_task=task;
+  task->last_task=last;
+  task->next_task=pred;
+  POPFD
+}
+
+U0 TaskQueRem(CTask *task)
+{//Remove a task from the scheduler running task queue.
+//Use Suspend().
+  CTask *next,*last;
+  PUSHFD
+  CLI
+  next=task->next_task;
+  last=task->last_task;
+  last->next_task=next;
+  next->last_task=last;
+  POPFD
+}
+
+U0 TaskQueInsChild(CTask *task)
+{
+  CTask *last,*pred;
+  PUSHFD
+  CLI
+  pred=task->parent_task->last_child_task;
+  last=pred->last_sibling_task;
+  last->next_sibling_task=pred->last_sibling_task=task;
+  task->last_sibling_task=last;
+  task->next_sibling_task=pred;
+  POPFD
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/SerialDev/Keyboard.HC.HTML b/public/Wb/Home/Src/Kernel/SerialDev/Keyboard.HC.HTML new file mode 100755 index 0000000..8c25930 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/SerialDev/Keyboard.HC.HTML @@ -0,0 +1,523 @@ + + + + + + + + + + + +
+asm {
+NORMAL_KEY_SCAN_DECODE_TABLE::
+        DU8     0,CH_ESC,"1234567890-=",CH_BACKSPACE,'\t';
+        DU8     "qwertyuiop[]",'\n',0,"as";
+        DU8     "dfghjkl;'\`",0,"\\zxcv";
+        DU8     "bnm,./",0,'*',0,CH_SPACE,0,0,0,0,0,0;
+        DU8     0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
+SHIFT_KEY_SCAN_DECODE_TABLE::
+        DU8     0,CH_SHIFT_ESC,"!@#$%^&*()_+",CH_BACKSPACE,'\t';
+        DU8     "QWERTYUIOP{}",'\n',0,"AS";
+        DU8     "DFGHJKL:\"~",0,"|ZXCV";
+        DU8     "BNM<>?",0,'*',0,CH_SHIFT_SPACE,0,0,0,0,0,0;
+        DU8     0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
+CTRL_KEY_SCAN_DECODE_TABLE::
+        DU8     0,CH_ESC,"1234567890-=",CH_BACKSPACE,'\t';
+        DU8     CH_CTRLQ,CH_CTRLW,CH_CTRLE,CH_CTRLR,CH_CTRLT,CH_CTRLY,CH_CTRLU,
+                CH_CTRLI,CH_CTRLO,CH_CTRLP,"[]",'\n',0,CH_CTRLA,CH_CTRLS;
+        DU8     CH_CTRLD,CH_CTRLF,CH_CTRLG,CH_CTRLH,CH_CTRLJ,CH_CTRLK,CH_CTRLL,
+                ";'\`",0,"\\",CH_CTRLZ,CH_CTRLX,CH_CTRLC,CH_CTRLV;
+        DU8     CH_CTRLB,CH_CTRLN,CH_CTRLM,",./",0,'*',0,CH_SPACE,0,0,0,0,0,0;
+        DU8     0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
+}
+
+U0 KbdCmdSend(I64 port, U8 val)
+{
+  F64 timeout=tS+0.125;
+  while (tS<timeout) {
+    if (!(InU8(KBD_CTRL)&2)) {
+      OutU8(port,val);
+      return;
+    }
+  }
+  throw;
+}
+
+I64 KbdCmdRead()
+{
+  F64 timeout=tS+0.125;
+  while (tS<timeout)
+    if (InU8(KBD_CTRL)&1)
+      return InU8(KBD_PORT);
+  throw;
+}
+
+U0 KbdCmdFlush()
+{
+  F64 timeout=tS+0.03;
+  while (tS<timeout)
+    InU8(KBD_PORT);
+}
+
+U0 KbdLEDsSet(I64 sc)
+{
+  U8 v=0;
+  BEqu(&v,0,Bt(&sc,SCf_SCROLL));
+  BEqu(&v,1,Bt(&sc,SCf_NUM));
+  BEqu(&v,2,Bt(&sc,SCf_CAPS));
+  try {
+    KbdCmdSend(KBD_PORT,0xED);
+    KbdCmdSend(KBD_PORT,v);
+  } catch
+    Fs->catch_except=TRUE;
+}
+
+U0 KbdMsCmdAck(...)
+{
+  I64 i,ack,timeout;
+  for (i=0;i<argc;i++) {
+    timeout=5;
+    do {
+      ack=0;
+      try {
+        KbdCmdSend(KBD_CTRL,0xD4);
+        KbdCmdSend(KBD_PORT,argv[i]);
+        ack=KbdCmdRead;
+      } catch {
+        KbdCmdFlush;
+        Fs->catch_except=TRUE;
+      }
+    } while (ack!=0xFA && --timeout);
+    if (!timeout)
+      throw;
+  }
+}
+
+U0 KbdTypeMatic(U8 delay)
+{//Set speed of repeated keys.
+  try {
+    KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
+    KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
+    KbdCmdSend(KBD_PORT,0xF3);
+    KbdCmdSend(KBD_PORT,delay); //Typematic rate
+    KbdCmdSend(KBD_CTRL,0xA8); //Enable Mouse
+  } catch {
+    KbdCmdFlush;
+    Fs->catch_except=TRUE;
+  }
+}
+
+I64 Char2ScanCode(I64 ch,I64 sc_flags=0)
+{//ASCII val to scan code (Slow).
+  I64 i;
+  U8 *table;
+  if (sc_flags) {
+    table=NORMAL_KEY_SCAN_DECODE_TABLE;
+    if (sc_flags & SCF_CTRL || ch<26)
+      table=CTRL_KEY_SCAN_DECODE_TABLE;
+    else if (sc_flags & SCF_SHIFT || 'A'<=ch<='Z') {
+      if (!(sc_flags & SCF_CAPS))
+        table=SHIFT_KEY_SCAN_DECODE_TABLE;
+    } else {
+      if (sc_flags & SCF_CAPS)
+        table=SHIFT_KEY_SCAN_DECODE_TABLE;
+    }
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i|sc_flags;
+    return sc_flags;
+  } else {
+    table=NORMAL_KEY_SCAN_DECODE_TABLE;
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i;
+    table=SHIFT_KEY_SCAN_DECODE_TABLE;
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i|SCF_SHIFT;
+    table=CTRL_KEY_SCAN_DECODE_TABLE;
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i|SCF_CTRL;
+    return 0;
+  }
+}
+
+U8 ScanCode2Char(I64 sc)
+{//Scan code to ASCII val.
+  U8 *table=NORMAL_KEY_SCAN_DECODE_TABLE;
+  if (sc&SCF_E0_PREFIX)
+    return 0;
+  if (sc&SCF_CTRL)
+    table=CTRL_KEY_SCAN_DECODE_TABLE;
+  else if (sc&SCF_SHIFT) {
+    if (!(sc&SCF_CAPS))
+      table=SHIFT_KEY_SCAN_DECODE_TABLE;
+  } else {
+    if (sc&SCF_CAPS)
+      table=SHIFT_KEY_SCAN_DECODE_TABLE;
+  }
+  sc&=0x7F;
+  if (sc>=0x50)
+    return 0;
+  else
+    return table[sc];
+}
+
+U8 scan_code_map[0x100]={
+  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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,SC_SHIFT,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,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,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,SC_ENTER,SC_CTRL,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,SC_HOME,
+        SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
+  SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INS,SC_DELETE,0,0,0,0,
+        0,0,0,0,SC_GUI,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,0,
+};
+
+U8 num_lock_map[0x100]={
+  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,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,0,0,0,8,9,10,0,5,6,7,0,2,
+  3,4,11,0x34,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,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,0,0,0,0,SC_ENTER,SC_CTRL,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,SC_HOME,
+        SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
+  SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INS,SC_DELETE,0,0,0,0,
+        0,0,0,0,SC_GUI,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,0,
+};
+
+U8 *Char2KeyName(I64 ch,Bool include_ctrl=TRUE)
+{//ASCII val to key name.
+  I64 i;
+  U8 buf[STR_LEN];
+  if (ch<=CH_SPACE) {
+    switch [ch] {
+      case '\n':
+        StrCpy(buf,"ENTER");
+        break;
+      case CH_BACKSPACE:
+        StrCpy(buf,"BACKSPACE");
+        break;
+      case '\t':
+        StrCpy(buf,"TAB");
+        break;
+      case CH_ESC:
+        StrCpy(buf,"ESC");
+        break;
+      case CH_SHIFT_ESC:
+        StrCpy(buf,"SHIFT_ESC");
+        break;
+      case 0: //nobound switch
+      case 29:
+      case 30:
+        *buf=0;
+        break;
+      case CH_SHIFT_SPACE:
+        StrCpy(buf,"SHIFT_SPACE");
+        break;
+      case CH_SPACE:
+        StrCpy(buf,"SPACE");
+        break;
+      default:
+        if (include_ctrl)
+          StrCpy(buf,"CTRL ");
+        buf[i=StrLen(buf)]=ch-1+'a';
+        buf[i+1]=0;
+        break;
+    }
+  } else if (Bt(char_bmp_printable,ch)) {
+    *buf=ch;
+    buf[1]=0;
+  } else
+    *buf=0;
+  return StrNew(buf);
+}
+
+U8 *ScanCode2KeyName(I64 sc)
+{//Scan code to key name.
+  I64 ch;
+  U8 buf[STR_LEN],*st;
+  *buf=0;
+  if (sc&SCF_CTRL)
+    CatPrint(buf,"CTRL ");
+  if (sc&SCF_ALT)
+    CatPrint(buf,"ALT ");
+  if (sc&SCF_SHIFT)
+    CatPrint(buf,"SHIFT ");
+  if (sc&SCF_NO_SHIFT)
+    CatPrint(buf,"      ");
+  if (ch=ScanCode2Char(sc&255)) {
+    st=Char2KeyName(ch,FALSE);
+    StrCpy(buf+StrLen(buf),st);
+    Free(st);
+  } else {
+    switch (sc&255) {
+      case SC_BACKSPACE:CatPrint(buf,"BACK");   break;
+      case SC_CAPS:     CatPrint(buf,"CAPS");   break;
+      case SC_NUM:      CatPrint(buf,"NUM");    break;
+      case SC_SCROLL:   CatPrint(buf,"SCROLL"); break;
+      case SC_CURSOR_UP:CatPrint(buf,"UP");     break;
+      case SC_CURSOR_DOWN:CatPrint(buf,"DOWN"); break;
+      case SC_CURSOR_LEFT:CatPrint(buf,"LEFT"); break;
+      case SC_CURSOR_RIGHT:CatPrint(buf,"RIGHT"); break;
+      case SC_PAGE_UP:  CatPrint(buf,"PAGE_UP");  break;
+      case SC_PAGE_DOWN:CatPrint(buf,"PAGE_DOWN");break;
+      case SC_HOME:     CatPrint(buf,"HOME");   break;
+      case SC_END:      CatPrint(buf,"END");    break;
+      case SC_INS:      CatPrint(buf,"INS");    break;
+      case SC_DELETE:   CatPrint(buf,"DELETE"); break;
+      case SC_F1:       CatPrint(buf,"F1");     break;
+      case SC_F2:       CatPrint(buf,"F2");     break;
+      case SC_F3:       CatPrint(buf,"F3");     break;
+      case SC_F4:       CatPrint(buf,"F4");     break;
+      case SC_F5:       CatPrint(buf,"F5");     break;
+      case SC_F6:       CatPrint(buf,"F6");     break;
+      case SC_F7:       CatPrint(buf,"F7");     break;
+      case SC_F8:       CatPrint(buf,"F8");     break;
+      case SC_F9:       CatPrint(buf,"F9");     break;
+      case SC_F10:      CatPrint(buf,"F10");    break;
+      case SC_F11:      CatPrint(buf,"F11");    break;
+      case SC_F12:      CatPrint(buf,"F12");    break;
+      case SC_GUI:      CatPrint(buf,"WINDOWS");  break;
+      case SC_PRTSCRN1: CatPrint(buf,"PRTSCRN1"); break;
+      case SC_PRTSCRN2: CatPrint(buf,"PRTSCRN2"); break;
+    }
+  }
+  return StrNew(buf);
+}
+
+U0 KbdBuildSC(U8 raw_byte,Bool in_irq,U8 *_last_raw_byte,I64 *_last_sc)
+{
+  I64 ch,sc_flags,sc,sc2,sc_raw,new_key_f;
+  Bool set_LEDs=FALSE;
+  if (raw_byte==0xE0) {
+    *_last_sc&=~0x1FF;
+    *_last_raw_byte=raw_byte;
+    return;
+  }
+  sc=raw_byte;
+  BEqu(&sc,SCf_E0_PREFIX,*_last_raw_byte==0xE0);
+  BEqu(&sc,SCf_KEY_UP,raw_byte & 0x80);
+  *_last_raw_byte=raw_byte;
+
+  sc_flags=_last_sc->u32[0]&~0x1FF;
+  sc_raw=sc;
+
+  if (sc_flags & SCF_NUM) {
+    if (sc2=num_lock_map[sc.u8[0]])
+      sc.u8[0]=sc2;
+  } else {
+    if (sc2=scan_code_map[sc.u8[0]])
+      sc.u8[0]=sc2;
+  }
+
+  new_key_f=SCF_NEW_KEY;
+  if (sc&SCF_KEY_UP)
+    switch (sc&~SCF_KEY_UP) {
+      case SC_SHIFT:    sc_flags&=~SCF_SHIFT;   break;
+      case SC_CTRL:     sc_flags&=~SCF_CTRL;    break;
+      case SC_ALT:      sc_flags&=~SCF_ALT;     break;
+      case SC_DELETE:   sc_flags&=~SCF_DELETE;  break;
+      case SC_INS:      sc_flags&=~SCF_INS;     break;
+      case SC_CAPS:     sc_flags^=SCF_CAPS;     set_LEDs=TRUE;  break;
+      case SC_NUM:      sc_flags^=SCF_NUM;      set_LEDs=TRUE;  break;
+      case SC_SCROLL:   sc_flags^=SCF_SCROLL;   set_LEDs=TRUE;  break;
+    }
+  else
+    switch (sc) {
+      case SC_SHIFT:
+        if (Bts(&sc_flags,SCf_SHIFT)) new_key_f=0;
+        break;
+      case SC_CTRL:
+        if (Bts(&sc_flags,SCf_CTRL)) new_key_f=0;
+        break;
+      case SC_ALT:
+        if (Bts(&sc_flags,SCf_ALT)) new_key_f=0;
+        break;
+      case SC_DELETE:
+        sc_flags|=SCF_DELETE;
+        break;
+      case SC_INS:
+        sc_flags|=SCF_INS;
+        break;
+    }
+
+  sc_flags|=new_key_f;
+  sc=sc_flags|sc|(sc_flags|sc_raw)<<32;
+  if (sc_flags & SCF_CTRL && sc_flags & SCF_ALT) {
+    if (!(sc&SCF_KEY_UP)) {
+      if (sc&255==SC_DELETE && !(sc_flags & SCF_SHIFT))
+        CtrlAltDel(sc);
+      else {
+        if (sc&255==SC_ESC)
+          ch='t';
+        else if (sc&255==SC_TAB)
+          ch='n';
+        else
+          ch=ScanCode2Char(sc&255);
+        if ('a'<=ch<='z') {
+          sc&=~(SCF_NEW_KEY|SCF_NEW_KEY<<32);
+          ch-='a';
+          kbd.last_down_scan_code=sc;
+          if (keydev.fp_ctrl_alt_cbs[ch] &&
+                Bt(&keydev.ctrl_alt_in_irq_flags,ch)==in_irq &&
+                (!(sc_flags & SCF_SHIFT)&&keydev.ctrl_alt_no_shift_descs[ch]) ||
+                sc_flags & SCF_SHIFT && keydev.ctrl_alt_shift_descs[ch])
+            (*keydev.fp_ctrl_alt_cbs[ch])(sc);
+        }
+      }
+    }
+  }
+  if (set_LEDs && !in_irq)
+    KbdLEDsSet(sc);
+  *_last_sc=sc;
+}
+
+U0 KbdPktRead()
+{
+  static U8 last_raw_byte=0;
+  static I64 last_sc=0;
+  U8 raw_byte;
+  if (GetTSC>kbd.timestamp+cnts.time_stamp_freq>>3)
+    FifoU8Flush(kbd.fifo);
+  kbd.timestamp=GetTSC;
+  raw_byte=InU8(KBD_PORT);
+  KbdBuildSC(raw_byte,TRUE,&last_raw_byte,&last_sc);
+  if (!FifoU8Cnt(kbd.fifo)) {
+    FifoU8Ins(kbd.fifo,raw_byte);
+    if (raw_byte!=0xE0) {
+      while (FifoU8Rem(kbd.fifo,&raw_byte))
+        FifoU8Ins(kbd.fifo2,raw_byte);
+    }
+  } else {
+    FifoU8Ins(kbd.fifo,raw_byte);
+    while (FifoU8Rem(kbd.fifo,&raw_byte))
+      FifoU8Ins(kbd.fifo2,raw_byte);
+  }
+}
+
+interrupt U0 IRQKbd()
+{
+  CLD
+  OutU8(0x20,0x20);
+  kbd.irqs_working=TRUE;
+  if (ms_hard.install_in_progress) {
+    kbd.rst=TRUE;
+    return;
+  }
+  keydev.ctrl_alt_ret_addr=GetRBP()(I64)+8;
+  KbdPktRead;
+}
+
+U0 KbdInit()
+{
+  try {
+    KbdCmdFlush;
+    KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
+    KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
+    KbdCmdSend(KBD_PORT,0xF0);
+    KbdCmdSend(KBD_PORT,0x02);
+    KbdLEDsSet(kbd.scan_code);
+  } catch {
+    KbdCmdFlush;
+    Fs->catch_except=TRUE;
+  }
+  IntEntrySet(0x21,&IRQKbd);
+  OutU8(0x21,InU8(0x21)&~2);
+}
+
+U0 KbdHndlr()
+{
+  static U8 last_raw_byte=0;
+  U8  raw_byte;
+  FifoU8Rem(kbd.fifo2,&raw_byte);
+  KbdBuildSC(raw_byte,FALSE,&last_raw_byte,&kbd.scan_code);
+  if (raw_byte==0xE0) {
+    FifoU8Rem(kbd.fifo2,&raw_byte);
+    KbdBuildSC(raw_byte,FALSE,&last_raw_byte,&kbd.scan_code);
+  }
+  if (Btr(&kbd.scan_code,SCf_NEW_KEY)) {
+    kbd.new_key_timestamp=kbd.timestamp;
+    Btr(&kbd.scan_code,32+SCf_NEW_KEY);
+    FifoI64Ins(kbd.scan_code_fifo,kbd.scan_code);
+    kbd.cnt++;
+    if (!(kbd.scan_code&SCF_KEY_UP)) {
+      kbd.last_down_scan_code=kbd.scan_code;
+      Bts(kbd.down_bitmap,kbd.scan_code.u8[0]);
+      Bts(kbd.down_bitmap2,kbd.scan_code.u8[4]);
+    } else {
+      Btr(kbd.down_bitmap,kbd.scan_code.u8[0]);
+      Btr(kbd.down_bitmap2,kbd.scan_code.u8[4]);
+    }
+  }
+}
+
+I64 KbdMsgsQue()
+{
+  I64 arg1,arg2,msg_code=MSG_NULL;
+  CTask *task_focus;
+  if (task_focus=sys_focus_task) {
+    while (FifoI64Rem(kbd.scan_code_fifo,&arg2)) {
+      arg1=ScanCode2Char(arg2);
+      if (arg2 & SCF_KEY_UP) {
+        TaskMsg(task_focus,0,MSG_KEY_UP,arg1,arg2,0);
+        msg_code=MSG_KEY_UP;
+      } else {
+        TaskMsg(task_focus,0,MSG_KEY_DOWN,arg1,arg2,0);
+        msg_code=MSG_KEY_DOWN;
+      }
+    }
+  }
+  return msg_code;
+}
+
+I64 KbdMsEvtTime()
+{//Timestamp of last key or mouse event.
+  if (ms_hard.timestamp>kbd.timestamp)
+    return ms_hard.timestamp;
+  else
+    return kbd.new_key_timestamp;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/SerialDev/MakeSerialDev.HC.HTML b/public/Wb/Home/Src/Kernel/SerialDev/MakeSerialDev.HC.HTML new file mode 100755 index 0000000..859ff12 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/SerialDev/MakeSerialDev.HC.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+#exe {Cd(__DIR__);};
+#include "Keyboard"
+#include "Mouse"
+#include "Message"
+#exe {Cd("..");};
+
+ diff --git a/public/Wb/Home/Src/Kernel/SerialDev/Message.HC.HTML b/public/Wb/Home/Src/Kernel/SerialDev/Message.HC.HTML new file mode 100755 index 0000000..58eab18 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/SerialDev/Message.HC.HTML @@ -0,0 +1,275 @@ + + + + + + + + + + + +
+U0 InputFilterTask()
+{
+  CJob *tmpc,*tmpc1;
+  Bool old_filter;
+  I64 old_flags=GetRFlags;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  LBts(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  old_filter=LBts(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);
+  LBEqu(&Fs->task_flags,TASKf_FILTER_INPUT,old_filter);
+  while (TRUE) {
+    CLI
+    JobsHndlr(old_flags);
+    tmpc1=&Fs->srv_ctrl.next_waiting;
+    tmpc=tmpc1->next;
+    if (tmpc==tmpc1)
+      break;
+    else {
+      if (tmpc->job_code==JOBT_TEXT_INPUT) {
+        QueRem(tmpc);
+        SetRFlags(old_flags);
+        try
+                ExePrint("%s",tmpc->aux_str);
+        catch
+          Fs->catch_except=TRUE;
+        JobDel(tmpc);
+      } else
+        break;
+    }
+  }
+  Fs->next_input_filter_task->last_input_filter_task=Fs->last_input_filter_task;
+  Fs->last_input_filter_task->next_input_filter_task=Fs->next_input_filter_task;
+  if (!old_filter)
+    LBtr(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);
+  SetRFlags(old_flags);
+}
+
+I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)
+{/*Check for a message of type specified by a one in the mask.
+Throw-out messages not in mask.
+If no message fit mask, return NULL immediately.
+Remove desired message, return msg_code.
+Note: This delivers messages from parent down to pop-up.
+*/
+  I64 res,old_flags;
+  CJob *tmpc,*tmpc1;
+  if (!task) task=Fs;
+  old_flags=GetRFlags;
+  tmpc1=&task->srv_ctrl.next_waiting;
+  while (TRUE) {
+    CLI
+    if (task==Fs)
+      JobsHndlr(old_flags);
+    tmpc=tmpc1->next;
+    if (tmpc==tmpc1)
+      break;
+    else {
+      if (tmpc->job_code==JOBT_MSG) {
+        QueRem(tmpc);
+        SetRFlags(old_flags);
+        res=tmpc->msg_code;
+        if (_arg1)
+          *_arg1=tmpc->aux1;
+        if (_arg2)
+          *_arg2=tmpc->aux2;
+        JobDel(tmpc);
+        if ((res!=MSG_KEY_DOWN || !(tmpc->aux2&SCF_KEY_DESC) ||
+              !Bt(&task->win_inhibit,WIf_SELF_KEY_DESC)) && Bt(&mask,res))
+          goto sm_done;
+      }
+    }
+    SetRFlags(old_flags);
+  }
+  res=MSG_NULL;
+  if (_arg1)
+    *_arg1=0;
+  if (_arg2)
+    *_arg2=0;
+  if (task->parent_task&&task->parent_task->popup_task==task) {
+    SetRFlags(old_flags);
+    return ScanMsg(_arg1,_arg2,mask,task->parent_task);
+  }
+sm_done:
+  SetRFlags(old_flags);
+  return res;
+}
+
+I64 FlushMsgs(CTask *task=NULL)
+{//Throw away all messages.  Return count.
+  I64 res=0,arg1,arg2;
+  while (ScanMsg(&arg1,&arg2,~1,task))
+    res++;
+  return res;
+}
+
+I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)
+{//Wait for a message of type specified by a one in the mask.
+//Throw-out all messages not in mask.
+  //Returns msg_code. See ::/Demo/MsgLoop.HC.
+  I64 res;
+  if (!task) task=Fs;
+  LBtr(&task->task_flags,TASKf_IDLE);
+  while (!(res=ScanMsg(_arg1,_arg2,mask,task))) {
+    LBts(&task->task_flags,TASKf_IDLE);
+    Yield;
+  }
+  LBtr(&task->task_flags,TASKf_IDLE);
+  return res;
+}
+
+I64 ScanChar()
+{//Checks for MSG_KEY_DOWN and returns 0 immediately if no key.
+//Waits for MSG_KEY_UP of non-zero ASCII key and returns ASCII if key.
+  //ScanMsg() throws away other message types.
+  I64 arg1a,arg2a,arg1b,arg2b;
+  if (!ScanMsg(&arg1a,&arg2a,1<<MSG_KEY_DOWN)||!arg1a)
+    return 0;
+  else
+    do GetMsg(&arg1b,&arg2b,1<<MSG_KEY_UP);
+    while (!arg1b);  //Be careful of SC_SHIFT and SC_CTRL, etc.
+  return arg1a;
+}
+
+Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE)
+{//Checks for MSG_KEY_DOWN and returns FALSE immediately if no key.
+//Sets ASCII and scan_code.
+  //Removes key message and returns TRUE.
+  //ScanMsg() throws away other message types.
+  I64 ch=0,sc=0;
+  if (ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN)) {
+    if (_ch) *_ch=ch;
+    if (_scan_code) *_scan_code=sc;
+    if (echo)
+      PutKey(ch,sc);
+    return TRUE;
+  } else {
+    if (_ch) *_ch=0;
+    if (_scan_code) *_scan_code=0;
+    return FALSE;
+  }
+}
+
+I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE,Bool raw_cursor=FALSE)
+{//Waits for MSG_KEY_DOWN message and returns ASCII.
+//Sets scan_code.
+  //ScanKey() throws away other message types.
+  I64 ch,sc;
+  Bool cursor_on=FALSE;
+  while (!ScanKey(&ch,&sc,FALSE)) {
+    if (IsRaw && raw_cursor) {
+      if (!cursor_on && ToI64(GetTSC*5/cnts.time_stamp_freq)&1) {
+        '.';
+        cursor_on=TRUE;
+      } else if (cursor_on && !(ToI64(GetTSC*5/cnts.time_stamp_freq)&1)) {
+        '' CH_BACKSPACE;
+        cursor_on=FALSE;
+      }
+    }
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    if (IsDbgMode) {
+//We don't want interrupt-driven keyboard when in debugger
+      //because that could have side-effects or crash, so we poll
+      //keyboard when in debugger with interrupts off.
+      PUSHFD
+      CLI
+      KbdMsHndlr(TRUE,FALSE);
+      KbdMsgsQue;
+      POPFD
+    } else {
+      LBts(&Fs->task_flags,TASKf_AWAITING_MSG);
+      Yield;
+    }
+    LBtr(&Fs->task_flags,TASKf_IDLE);
+  }
+  if (IsRaw && raw_cursor && cursor_on)
+    '' CH_BACKSPACE;
+  if (echo)
+    PutKey(ch,sc);
+  if (_scan_code) *_scan_code=sc;
+  return ch;
+}
+
+I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE)
+{//Waits for non-zero ASCII key.
+//Sets scan_code.
+  I64 ch1;
+  do ch1=GetKey(_scan_code,FALSE,raw_cursor);
+  while (!ch1);
+  if (echo)
+    "$PT$%c$FG$",ch1;
+  return ch1;
+}
+
+U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0)
+{//Returns a MAlloc()ed prompted string.  See Flags.
+  U8 *st;
+  if (msg)
+    "" msg,dft;
+  st=(*fp_getstr2)(flags);
+  if (!*st) {
+    Free(st);
+    if (dft)
+      return StrNew(dft);
+    else
+      return StrNew("");
+  }
+  return st;
+}
+
+I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE)
+{//Prompt into fixed length string. Size must include terminator.
+  U8 *st;
+  I64 ch,i=0;
+  if (!size || !buf) return 0;
+  if (allow_ext) {
+    st=GetStr;
+    if (StrLen(st)>size-1) {
+      MemCpy(buf,st,size-1);
+      buf[size-1]=0;
+    } else
+      StrCpy(buf,st);
+    i=StrLen(buf);
+    Free(st);
+  } else {
+    while (TRUE) {
+      ch=GetChar(,FALSE,IsDbgMode);
+      if (ch=='\n') {
+        '' ch;
+        break;
+      } else if (ch==CH_BACKSPACE) {
+        if (i>0) {
+          i--;
+          '' ch;
+        }
+      } else {
+        if (i<size-1) {
+          buf[i++]=ch;
+          '' ch;
+        }
+      }
+    }
+    buf[i]=0;
+  }
+  return i;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/SerialDev/Mouse.HC.HTML b/public/Wb/Home/Src/Kernel/SerialDev/Mouse.HC.HTML new file mode 100755 index 0000000..8e58387 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/SerialDev/Mouse.HC.HTML @@ -0,0 +1,398 @@ + + + + + + + + + + + +
+U0 GridInit()
+{//Init mouse grid struct. See ::/Demo/Graphics/Grid.HC.
+  ms_grid.x=ms_grid.y=ms_grid.z=8;
+  ms_grid.x_offset=ms_grid.y_offset=ms_grid.z_offset=0;
+  ms_grid.x_speed =ms_grid.y_speed =ms_grid.z_speed =1;
+  ms_grid.show=ms_grid.snap=ms_grid.coord=FALSE;
+}
+
+U0 MsUpdate(I64 x,I64 y,I64 z,Bool l,Bool r)
+{
+  ms.presnap.x=ToI64(ms.scale.x*x)+ms.offset.x;
+  ms.presnap.y=ToI64(ms.scale.y*y)+ms.offset.y;
+  ms.presnap.z=ToI64(ms.scale.z*z)+ms.offset.z;
+  if (ms_grid.snap) {
+    ms.pos.x=Trunc(ms.presnap.x/ms_grid.x)*ms_grid.x+ms_grid.x_offset;
+    ms.pos.y=Trunc(ms.presnap.y/ms_grid.y)*ms_grid.y+ms_grid.y_offset;
+    ms.pos.z=Trunc(ms.presnap.z/ms_grid.z)*ms_grid.z+ms_grid.z_offset;
+  } else {
+    ms.pos.x=ms.presnap.x;
+    ms.pos.y=ms.presnap.y;
+    ms.pos.z=ms.presnap.z;
+  }
+
+  ms.pos.x=ClampI64(ms.pos.x,0,GR_WIDTH-1);
+  ms.pos.y=ClampI64(ms.pos.y,0,GR_HEIGHT-1);
+  ms.pos_text.x=ms.pos.x/FONT_WIDTH;
+  if (ms.pos_text.x>=text.cols) {
+    ms.pos_text.x=text.cols-1;
+    ms.pos.x=text.cols*FONT_WIDTH-1;
+  }
+  ms.pos_text.y=ms.pos.y/FONT_HEIGHT;
+  if (ms.pos_text.y>=text.rows) {
+    ms.pos_text.y=text.rows-1;
+    ms.pos.y=text.rows*FONT_HEIGHT-1;
+  }
+  ms.lb=l;
+  ms.rb=r;
+  LBEqu(&kbd.scan_code,SCf_MS_L_DOWN,ms.lb);
+  LBEqu(&kbd.scan_code,SCf_MS_R_DOWN,ms.rb);
+}
+
+U0 MsSet(I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,I64 l=I64_MAX,I64 r=I64_MAX)
+{//Note: Generates a message. See MsSet().
+  if (!(0<=x<GR_WIDTH))
+    x=ms.pos.x;
+  if (!(0<=y<GR_HEIGHT))
+    y=ms.pos.y;
+  if (z==I64_MAX)
+    z=ms.pos.z;
+
+  if (!(FALSE<=l<=TRUE))
+    l=ms.lb;
+  if (!(FALSE<=r<=TRUE))
+    r=ms.rb;
+
+  x=(x-ms.offset.x)/ms.scale.x;
+  y=(y-ms.offset.y)/ms.scale.y;
+  z=(z-ms.offset.z)/ms.scale.z;
+  MsUpdate(x,y,z,l,r);
+  MsHardSet(x,y,z,l,r);
+}
+
+U0 MsInit()
+{
+  MemSet(&ms,0,sizeof(CMsStateGlbls));
+  MemSet(&ms_last,0,sizeof(CMsStateGlbls));
+  ms.offset.x=ms.offset.y=ms.offset.z=0;
+  ms.scale.x=ms.scale.y=ms.scale.z=1.0;
+  ms.pos_text.x=ms.pos_text.y=ms.pos_text.z=0;
+  ms.has_wheel=FALSE;
+  ms.show=TRUE;
+  ms.speed=0;
+  ms.timestamp=GetTSC;
+  ms.dbl_time=0.350;
+  GridInit;
+}
+
+U0 MsHardPktRead()
+{
+  U8 j;
+  if (GetTSC>ms_hard.timestamp+cnts.time_stamp_freq>>3)
+    FifoU8Flush(ms_hard.fifo);
+  ms_hard.timestamp=GetTSC;
+  FifoU8Ins(ms_hard.fifo,InU8(KBD_PORT));
+  if (FifoU8Cnt(ms_hard.fifo)==ms_hard.pkt_size)
+    while (FifoU8Rem(ms_hard.fifo,&j))
+      FifoU8Ins(ms_hard.fifo2,j);
+}
+
+interrupt U0 IRQMsHard()
+{
+  CLD
+  OutU8(0xA0,0x20);
+  OutU8(0x20,0x20);
+  ms_hard.irqs_working=TRUE;
+  if (ms_hard.install_in_progress || !ms_hard.installed) {
+    kbd.rst=TRUE;
+    return;
+  }
+  MsHardPktRead;
+}
+
+U0 MsHardGetType()
+{
+  I64 b;
+  KbdMsCmdAck(0xF2);
+  b=KbdCmdRead;
+  if (b==3)
+    ms_hard.has_wheel=TRUE;
+  else if (b==4)
+    ms_hard.has_ext_bttns=TRUE;
+}
+
+Bool MsHardRst()
+{
+  U8 b,*_b;
+  F64 timeout;
+  Bool res=FALSE;
+
+  ms_hard.has_wheel=FALSE;
+  ms_hard.has_ext_bttns=FALSE;
+
+  if (*0x40E(U16 *)==0x9FC0) {
+    _b=0x9FC00+0x30;
+    *_b=1; //This enables my mouse.  It might be for one machine.
+//USB DMA packets, set-up by BIOS to make legacy PS/2?
+  }
+
+  try {
+    KbdCmdFlush;
+    KbdCmdSend(KBD_CTRL,0xAD); //Disable Kbd
+    KbdCmdSend(KBD_CTRL,0xA8); //Enable Mouse
+
+    KbdMsCmdAck(0xFF); //Rst
+
+    timeout=tS+10.0;
+    do
+      try {
+        KbdCmdRead;
+        timeout=0; //force exit
+      } catch
+        Fs->catch_except=TRUE;
+    while (tS<timeout);
+
+    try
+            KbdCmdRead;
+    catch
+      Fs->catch_except=TRUE;
+
+    KbdMsCmdAck(0xF3,200,0xF3,100,0xF3,80);
+    MsHardGetType;
+    KbdMsCmdAck(0xF3,10);
+    MsHardGetType;
+    KbdMsCmdAck(0xE8,0x03,0xE6,0xF3,100,0xF4);
+    res=TRUE;
+
+    //Enable IRQ 12
+    KbdCmdSend(KBD_CTRL,0x20);
+    b=KbdCmdRead;
+    KbdCmdSend(KBD_CTRL,0x60);
+    KbdCmdSend(KBD_PORT,(b|2)&~0x20);
+
+  } catch
+    Fs->catch_except=TRUE;
+
+    //This is been added to override failure
+    //because the mouse sometimes still works.
+  res=TRUE;
+
+  try
+          KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
+  catch
+    Fs->catch_except=TRUE;
+  if (ms_hard.has_wheel || ms_hard.has_ext_bttns)
+    ms_hard.pkt_size=4;
+  else
+    ms_hard.pkt_size=3;
+  if (!res)
+    try
+            KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
+    catch
+      Fs->catch_except=TRUE;
+  return res;
+}
+
+U0 MsHardSpeedSet()
+{
+  I64 dd,tmp;
+  if ((dd=SqrI64(ms_hard_last.pos.x-ms_hard.pos.x)
+        +SqrI64(ms_hard_last.pos.y-ms_hard.pos.y)) &&
+        (tmp=ms_hard.timestamp-ms_hard_last.timestamp))
+    ms_hard.speed=Sqrt(dd)*cnts.time_stamp_freq/tmp;
+  ms_hard_last.timestamp=ms_hard.timestamp;
+}
+
+U0 MsHardSetPre()
+{
+  I64 old_timestamp=ms_hard_last.timestamp;
+  MemCpy(&ms_hard_last,&ms_hard,sizeof(CMsHardStateGlbls));
+  ms_hard_last.timestamp=old_timestamp;
+}
+
+U0 MsHardSetPost()
+{
+  I64 i;
+  ms_hard.pos.x=ms_hard.prescale.x*ms_hard.scale.x*ms_grid.x_speed;
+  ms_hard.pos.y=ms_hard.prescale.y*ms_hard.scale.y*ms_grid.y_speed;
+  ms_hard.pos.z=ms_hard.prescale.z*ms_hard.scale.z*ms_grid.z_speed;
+
+  i=Trunc(ms.scale.x*ms_hard.pos.x/ms_grid.x)*ms_grid.x+ms.offset.x;
+//TODO ms_grid.x_offset?
+  if (i<0)
+    ms.offset.x-=i;
+  else if (i>=GR_WIDTH)
+    ms.offset.x+=GR_WIDTH-1-i;
+
+  i=Trunc(ms.scale.y*ms_hard.pos.y/ms_grid.y)*ms_grid.y+ms.offset.y;
+  if (i<0)
+    ms.offset.y-=i;
+  else if (i>=GR_HEIGHT)
+    ms.offset.y+=GR_HEIGHT-1-i;
+
+  if (ms_hard.pos.x!=ms_hard_last.pos.x || ms_hard.pos.y!=ms_hard_last.pos.y ||
+        ms_hard.pos.z!=ms_hard_last.pos.z) {
+    ms_hard.evt=TRUE;
+    MsHardSpeedSet;
+  } else
+    for (i=0;i<5;i++)
+      if (ms_hard.bttns[i]!=ms_hard_last.bttns[i]) {
+        ms_hard.evt=TRUE;
+        break;
+      }
+}
+
+U0 MsHardHndlr()
+{
+  I64 i,dx,dy,dz;
+  U8 ms_buf[4];
+
+  MsHardSetPre;
+  for (i=0;i<4;i++)
+    ms_buf[i]=0;
+  for (i=0;i<ms_hard.pkt_size;i++)
+    if (!FifoU8Rem(ms_hard.fifo2,&ms_buf[i]))
+      ms_buf[i]=0;
+
+  ms_hard.bttns[0] = ms_buf[0] & 1;
+  ms_hard.bttns[1] = (ms_buf[0] & 2) >> 1;
+  ms_hard.bttns[2] = (ms_buf[0] & 4) >> 2;
+  ms_hard.bttns[3] = (ms_buf[3] & 0x10) >> 4;
+  ms_hard.bttns[4] = (ms_buf[3] & 0x20) >> 5;
+  if (ms_buf[0] & 0x10)
+    dx=ms_buf[1]-256;
+  else
+    dx=ms_buf[1];
+  if (ms_buf[0] & 0x20)
+    dy=256-ms_buf[2];
+  else
+    dy=-ms_buf[2];
+  if (ms_buf[3] & 0x08)
+    dz=ms_buf[3]&7-8;
+  else
+    dz=ms_buf[3]&7;
+
+  ms_hard.prescale.x+=dx;
+  ms_hard.prescale.y+=dy;
+  ms_hard.prescale.z+=dz;
+
+  MsHardSetPost;
+}
+
+U0 MsHardSet(I64 x,I64 y,I64 z,I64 l,I64 r)
+{
+  ms_hard.timestamp=GetTSC;
+  MsHardSetPre;
+  ms_hard.prescale.x=x/ms_hard.scale.x/ms_grid.x_speed;
+  ms_hard.prescale.y=y/ms_hard.scale.y/ms_grid.y_speed;
+  ms_hard.prescale.z=z/ms_hard.scale.z/ms_grid.z_speed;
+  ms_hard.bttns[0]=l;
+  ms_hard.bttns[1]=r;
+  MsHardSetPost;
+}
+
+U0 KbdMsRst()
+{
+  KbdCmdFlush;
+  FifoU8Flush(kbd.fifo2);
+  FifoU8Flush(ms_hard.fifo2);
+  FifoI64Flush(kbd.scan_code_fifo);
+  kbd.scan_code=0;
+  kbd.rst=FALSE;
+}
+
+Bool MsHardDrvrInstall(I64 dummy=0) //can be spawned
+{
+  no_warn dummy;
+  I64 i;
+  ms_hard.install_in_progress=TRUE;
+  OutU8(0xA1,InU8(0xA1)|0x10);
+  ms_hard.installed=ms_hard.irqs_working=FALSE;
+  IntEntrySet(0x2C,&IRQMsHard);
+  for(i=0;i<5;i++)
+    ms_hard.bttns[i]=0;
+  if (i=MsHardRst)
+    OutU8(0xA1,InU8(0xA1)&~0x10);
+  KbdMsRst;
+  ms_hard.install_attempts++;
+  ms_hard.installed=ms_hard.evt=i;
+  ms_hard.install_in_progress=FALSE;
+  return ms_hard.installed;
+}
+
+U0 KbdMsHndlr(Bool poll_kbd,Bool poll_ms)
+{
+  if (ms_hard.install_in_progress) {
+    Yield;
+    return;
+  }
+  if (kbd.rst)
+    KbdMsRst;
+  else {
+    if (poll_ms && ms_hard.installed && !ms_hard.irqs_working) {
+      PUSHFD
+      CLI
+      while (InU8(KBD_CTRL)&1)
+        MsHardPktRead;
+      POPFD
+    }
+
+    if (poll_kbd)
+      while (InU8(KBD_CTRL)&1)
+        KbdPktRead;
+
+    if (kbd.rst)
+      KbdMsRst;
+    else {
+      while (FifoU8Cnt(kbd.fifo2))
+        KbdHndlr;
+      while (FifoU8Cnt(ms_hard.fifo2))
+        if (ms_hard.installed)
+          MsHardHndlr;
+        else
+          KbdMsRst;
+    }
+  }
+}
+
+U0 KbdMsInit()
+{
+  MemSet(&kbd,0,sizeof(CKbdStateGlbls));
+  kbd.fifo=FifoU8New(8);
+  kbd.fifo2=FifoU8New(0x1000);
+  kbd.scan_code_fifo=FifoI64New(0x1000);
+  kbd.irqs_working=FALSE;
+  MemSet(&ms_hard,0,sizeof(CMsHardStateGlbls));
+  ms_hard.fifo=FifoU8New(8);
+  ms_hard.fifo2=FifoU8New(0x1000);
+  ms_hard.scale.x=0.5;
+  ms_hard.scale.y=0.5;
+  ms_hard.scale.z=1.0;
+  ms_hard.prescale.x=GR_WIDTH/ms_hard.scale.x/2.0;
+  ms_hard.prescale.y=GR_HEIGHT/ms_hard.scale.y/2.0;
+  ms_hard.prescale.z=0/ms_hard.scale.z;
+  ms_hard.pos.x=GR_WIDTH>>1;
+  ms_hard.pos.y=GR_HEIGHT>>1;
+  MemCpy(&ms_hard_last,&ms_hard,sizeof(CMsHardStateGlbls));
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/StrA.HC.HTML b/public/Wb/Home/Src/Kernel/StrA.HC.HTML new file mode 100755 index 0000000..1b2de3d --- /dev/null +++ b/public/Wb/Home/Src/Kernel/StrA.HC.HTML @@ -0,0 +1,717 @@ + + + + + + + + + + + +
+U8 *StrPrintHex(U8 *dst,I64 num;I64 width)
+{
+  U8 *res=dst+width;
+  dst=res;
+  while (width--) {
+    *--dst="0123456789ABCDEF"(U8 *)[num&15];
+    num>>=4;
+  }
+  return res;
+}
+
+U0 PutHex(I64 num,I64 width)
+{
+  U8 buf[17];
+  if (width>16) width=16;
+  *StrPrintHex(buf,num,width)=0;
+  "%s",buf;
+}
+
+asm {
+// IN:  RAX=NUM TO PRINT
+PUT_HEX_U64::
+        PUSH_C_REGS
+        PUSH    16
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_HEX_U32::
+        PUSH_C_REGS
+        PUSH    8
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_HEX_U16::
+        PUSH_C_REGS
+        PUSH    4
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_HEX_U8::
+        PUSH_C_REGS
+        PUSH    2
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_CHARS::
+// IN:  RAX=Char
+        PUSH_C_REGS
+        PUSH    RAX
+        CALL    &PutChars
+        POP_C_REGS
+        RET
+PUT_STR::
+// IN:  RSI=String
+        PUSH_C_REGS
+        PUSH    RSI
+        CALL    &PutS
+        POP_C_REGS
+        RET
+_STRCPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        TEST    RDI,RDI
+        JZ      @@15
+        MOV     RSI,U64 SF_ARG2[RBP]
+        TEST    RSI,RSI
+        JNZ     @@05
+        XOR     RAX,RAX
+        JMP     @@10
+@@05:   LODSB
+@@10:   STOSB
+        TEST    AL,AL
+        JNZ     @@05
+@@15:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_STRCMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   LODSB
+        TEST    AL,AL
+        JZ      @@20
+        SCASB
+        JE      @@05
+        JA      @@15
+@@10:   MOV     RAX,1
+        JMP     @@25
+@@15:   MOV     RAX,-1
+        JMP     @@25
+@@20:   SCASB
+        JNE     @@10
+        XOR     RAX,RAX
+@@25:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+TO_UPPER::
+        CMP     AL,'a'
+        JB      @@05
+        CMP     AL,'z'
+        JA      @@05
+        ADD     AL,'A'-'a'
+@@05:   RET
+_STRICMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   LODSB
+        TEST    AL,AL
+        JZ      @@30
+        CMP     AL,'a'
+        JB      @@10
+        CMP     AL,'z'
+        JA      @@10
+        ADD     AL,'A'-'a'
+@@10:   MOV     BL,U8 [RDI]
+        INC     RDI
+        CMP     BL,'a'
+        JB      @@15
+        CMP     BL,'z'
+        JA      @@15
+        ADD     BL,'A'-'a'
+@@15:   CMP     AL,BL
+        JE      @@05
+        JA      @@25
+@@20:   MOV     RAX,1
+        JMP     @@35
+@@25:   MOV     RAX,-1
+        JMP     @@35
+@@30:   MOV     BL,U8 [RDI]
+        TEST    BL,BL
+        JNE     @@20
+        XOR     RAX,RAX
+@@35:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_STRNCMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG3[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   TEST    RCX,RCX
+        JZ      @@25
+        DEC     RCX
+        LODSB
+        TEST    AL,AL
+        JZ      @@20
+        SCASB
+        JE      @@05
+        JA      @@15
+@@10:   MOV     RAX,1
+        JMP     @@30
+@@15:   MOV     RAX,-1
+        JMP     @@30
+@@20:   MOV     BL,U8 [RDI]
+        TEST    BL,BL
+        JNE     @@10
+@@25:   XOR     RAX,RAX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_STRNICMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG3[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   TEST    RCX,RCX
+        JZ      @@35
+        DEC     RCX
+        LODSB
+        TEST    AL,AL
+        JZ      @@30
+        CMP     AL,'a'
+        JB      @@10
+        CMP     AL,'z'
+        JA      @@10
+        ADD     AL,'A'-'a'
+@@10:   MOV     BL,U8 [RDI]
+        INC     RDI
+        CMP     BL,'a'
+        JB      @@15
+        CMP     BL,'z'
+        JA      @@15
+        ADD     BL,'A'-'a'
+@@15:   CMP     AL,BL
+        JE      @@05
+        JA      @@25
+@@20:   MOV     RAX,1
+        JMP     @@40
+@@25:   MOV     RAX,-1
+        JMP     @@40
+@@30:   SCASB
+        JNE     @@20
+@@35:   XOR     RAX,RAX
+@@40:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_STRMATCH::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        TEST    RSI,RSI
+        JZ      @@25
+        MOV     RDI,U64 SF_ARG1[RBP]
+        TEST    RDI,RDI
+        JZ      @@25
+        MOV     DL,U8 [RDI]
+        TEST    DL,DL
+        JZ      @@20
+        JMP     @@10
+@@05:   INC     RSI
+@@10:   LODSB
+        TEST    AL,AL
+        JZ      @@25
+        CMP     AL,DL
+        JNE     @@10
+        DEC     RSI
+        MOV     RCX,1
+@@15:   MOV     AL,U8 [RDI+RCX]
+        TEST    AL,AL
+        JZ      @@20
+        CMP     AL,U8 [RSI+RCX]
+        JNE     @@05
+        INC     RCX
+        JMP     @@15
+
+        DEC     RSI
+@@20:   MOV     RAX,RSI
+        JMP     @@30
+@@25:   XOR     RAX,RAX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_STRIMATCH::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        TEST    RSI,RSI
+        JZ      @@25
+        MOV     RDI,U64 SF_ARG1[RBP]
+        TEST    RDI,RDI
+        JZ      @@25
+        MOV     AL,U8 [RDI]
+        CALL    TO_UPPER
+        MOV     DL,AL
+        TEST    DL,DL
+        JZ      @@20
+        JMP     @@10
+@@05:   INC     RSI
+@@10:   LODSB
+        CALL    TO_UPPER
+        TEST    AL,AL
+        JZ      @@25
+        CMP     AL,DL
+        JNE     @@10
+        DEC     RSI
+        MOV     RCX,1
+@@15:   MOV     AL,U8 [RDI+RCX]
+        CALL    TO_UPPER
+        TEST    AL,AL
+        JZ      @@20
+        MOV     BL,U8 [RSI+RCX]
+        XCHG    AL,BL
+        CALL    TO_UPPER
+        CMP     AL,BL
+        JNE     @@05
+        INC     RCX
+        JMP     @@15
+
+        DEC     RSI
+@@20:   MOV     RAX,RSI
+        JMP     @@30
+@@25:   XOR     RAX,RAX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+}
+_extern _STRCMP I64 StrCmp(
+        U8 *st1,U8 *st2); //Compare two strings.
+_extern _STRICMP I64 StrICmp(
+        U8 *st1,U8 *st2); //Compare two strings, ignoring case.
+_extern _STRNCMP I64 StrNCmp(
+        U8 *st1,U8 *st2,I64 n); //Compare N bytes in two strings.
+_extern _STRNICMP I64 StrNICmp(
+        U8 *st1,U8 *st2,I64 n); //Compare N bytes in two strings, ignoring case.
+_extern _STRMATCH U8 *StrMatch(
+        U8 *needle,U8 *haystack_str); //Scan for string in string.
+_extern _STRIMATCH U8 *StrIMatch(
+        U8 *needle,U8 *haystack_str);//Scan for string in string, ignoring case.
+_extern _STRCPY U0 StrCpy(
+        U8 *dst,U8 *src); //Copy string.
+
+//These bitmaps go to 0-511 so that Lex() can use them with Token Codes.
+U32
+  char_bmp_alpha[16]=
+  {0x0000000,0x00000000,0x87FFFFFF,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_alpha_numeric[16]=
+  {0x0000000,0x03FF0000,0x87FFFFFF,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_alpha_numeric_no_at[16]=
+  {0x0000000,0x03FF0000,0x87FFFFFE,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_word[16]=
+  {0x0000000,0x03FF0080,0x87FFFFFE,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_filename[16]=
+  {0x0000000,0x03FF73FB,0xEFFFFFFF,0x6FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_dec_numeric[16]=
+  {0x0000000,0x03FF0000,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_hex_numeric[16]=
+  {0x0000000,0x03FF0000,0x7E,0x7E,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_white_space[16]=
+  {0x80002600,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_non_eol_white_space[16]=
+  {0x80000200,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_zero_cr_nl_cursor[16]=
+  {0x00002421,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_zero_tab_cr_nl_cursor[16]=
+  {0x00002621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_zero_tab_cr_nl_cursor_dollar[16]=
+  {0x00002621,0x10,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_macro[16]=
+  {0x80002600,0xFFFFFFDF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_printable[16]=
+  {0x80002600,0xFFFFFFFF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_displayable[16]=
+  {0x80000000,0xFFFFFFFF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_safe_dollar[16]=
+  {0x80000000,0xFFFFFFEF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},//same but no dollar sign
+
+  char_bmp_non_eol[16]=
+  {0xFFFFDBFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+
+U8 *LstSub(I64 sub, U8 *lst)
+{//Point to lst entry.
+//Not efficient.  Use an array of U8 ptrs for efficiency.
+  if (!lst) return NULL;
+  while (*lst && sub>0) {
+    while (*lst)        //Advance to end of cur entry.
+      lst++;
+    lst++;              //Skip trailing zero.
+    if (*lst=='@')      //Check for '@' alias lst entry.
+      lst++;
+    else
+      sub--;
+  }
+  if (sub||!*lst)
+    return NULL;
+  else
+    return lst;
+}
+
+I64 LstMatch(U8 *needle, U8 *haystack_lst,I64 flags=0)
+{//-2 if Ambiguous
+// -1 if not found
+  // Not efficient. Use hash tables for efficiency.
+  I64 n,sub=0,res=-1;
+  U8 *ptr;
+  Bool exact_match=FALSE;
+  if (!haystack_lst) return -1;
+  n=StrLen(needle);
+  while (*haystack_lst) {
+    if (*haystack_lst=='@') {   //Check for '@' alias haystack_lst entry
+      sub--;
+      haystack_lst++;
+    }
+    ptr=needle;
+    if (flags & LMF_IGNORE_CASE)
+      while (*ptr && ToUpper(*ptr)==ToUpper(*haystack_lst)) {
+        ptr++;
+        haystack_lst++;
+      }
+    else
+      while (*ptr && *ptr==*haystack_lst) {
+        ptr++;
+        haystack_lst++;
+      }
+    if (!*ptr) {                //Did we reach end of needle?
+      if (!*haystack_lst)       //Did we reach end of haystack_lst?
+        return sub;             //Found Exact match
+      else {
+        if (res!=-1) {
+          if (!exact_match)
+            res=-2;             //Ambiguous unless later exact match.
+        } else {
+          if (!(flags & LMF_EXACT))
+            res=sub;
+        }
+      }
+    }
+    while (*haystack_lst)       //Advance to end of cur entry.
+      haystack_lst++;
+    haystack_lst++;             //Skip trailing zero
+    sub++;
+  }
+  return res;
+}
+
+I64 StrOcc(U8 *src, I64 ch)
+{//Count occurrences of a char.
+  I64 i=0;
+  if (!src) return 0;
+  while (*src)
+    if (*src++==ch)
+      i++;
+  return i;
+}
+
+I64 Spaces2Tabs(U8 *dst,U8 *src)
+{//Src buf with spaces to dst buf without.
+  U8 *src2;
+  I64 chged=0,space_cnt,space_cnt2,col=0;
+  if (*src)
+    while (TRUE) {
+      src2=src;
+      while (*src2==CH_SPACE)
+        src2++;
+      space_cnt=src2-src;
+      while (col+space_cnt>=8) {
+        space_cnt2=8-col;
+        if (space_cnt2==1)
+          *dst++=CH_SPACE;
+        else {
+          *dst++='\t';
+          chged+=space_cnt2-1;
+        }
+        space_cnt-=space_cnt2;
+        col=0;
+      }
+      if (*src2=='\t') {
+        if (space_cnt==1 && col==7)
+          *dst++=CH_SPACE;
+        else
+          chged+=space_cnt;
+        *dst++='\t';
+        col=0;
+      } else {
+        while (space_cnt--) {
+          *dst++=CH_SPACE;
+          if (++col==8)
+            col=0;
+        }
+        if (*src2) {
+          *dst++=*src2;
+          if (++col==8)
+            col=0;
+        } else
+          break;
+      }
+      src=++src2;
+    }
+  *dst=0;
+  return chged;
+}
+
+U8 *StrUtil(U8 *_src,I64 flags)
+{//Modifies in place. See flags for all the options.
+  U8 *src=_src,*dst=_src;
+  I64 ch;
+
+  if (flags & SUF_REM_LEADING)
+    while (Bt(char_bmp_white_space,*src))
+      src++;
+  while (ch=*src++)
+    if (Bt(char_bmp_white_space,ch)) {
+      if (!(flags & SUF_REM_SPACES)) {
+        if (flags & SUF_SINGLE_SPACE) {
+          *dst++ = CH_SPACE;
+          while ((ch=*src++) && Bt(char_bmp_white_space,ch));
+          src--;
+        } else
+          *dst++ = ch;
+      }
+    } else if (!(flags & SUF_REM_CTRL_CHARS) || ch>=CH_SHIFT_SPACE)
+      *dst++=ch;
+  *dst=0;
+
+  if (flags & SUF_REM_TRAILING)
+    while (dst!=_src && (!*dst || Bt(char_bmp_white_space,*dst)))
+      *dst-- =0;
+  if (flags & SUF_TO_UPPER)
+    for (dst=_src;*dst;dst++) {
+      ch=*dst;
+      if ('a'<=ch<='z')
+        *dst=ch-0x20;
+    }
+  if (flags & SUF_TO_LOWER)
+    for (dst=_src;*dst;dst++) {
+      ch=*dst;
+      if ('A'<=ch<='Z')
+        *dst=ch+0x20;
+    }
+  if (flags & SUF_SAFE_DOLLAR)
+    for (dst=_src;*dst;dst++) {
+      ch=*dst;
+      if (!Bt(char_bmp_safe_dollar,*dst))
+        *dst='.';
+    }
+  if (flags & SUF_S2T)
+    Spaces2Tabs(_src,_src);
+  return _src;
+}
+
+U8 *StrFirstOcc(U8 *src,U8 *marker)
+{//Point to 1st occurrence of marker set in str.
+  I64 ch;
+  while ((ch=*src++) && !StrOcc(marker,ch));
+  if (ch)
+    return src-1;
+  else
+    return NULL;
+}
+
+U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL)
+{//Remove first str segment and place in dst buf or NULL.
+  I64 ch;
+  U8 *ptr=src,*res=dst;
+  if (dst) {
+    while ((ch=*ptr++) && !StrOcc(marker,ch))
+      *dst++=ch;
+    *dst=0;
+  } else
+    while ((ch=*ptr++) && !StrOcc(marker,ch));
+  if (ch)
+    StrCpy(src,ptr);
+  else
+    *src=0;
+  return res;
+}
+
+U8 *StrLastOcc(U8 *src,U8 *marker)
+{//Point to last occurrence of market set in str.
+  I64 ch;
+  U8 *res=NULL;
+  while (ch=*src++)
+    if (StrOcc(marker,ch))
+      res=src-1;
+  return res;
+}
+
+U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL)
+{//Remove last str segment and place in dst buf or NULL.
+  U8 *ptr;
+  if (ptr=StrLastOcc(src,marker)) {
+    if (dst)
+      StrCpy(dst,ptr+1);
+    *ptr=0;
+  } else {
+    if (dst)
+      StrCpy(dst,src);
+    *src=0;
+  }
+  return dst;
+}
+
+U8 *StrFind(U8 *needle,U8 *haystack_str,I64 flags=0)
+{//Find needle_str in haystack_str with options.
+  Bool cont;
+  U8 *saved_haystack_str=haystack_str;
+  I64 plen=StrLen(needle);
+  do {
+    cont=FALSE;
+    if (flags & SFF_IGNORE_CASE)
+      haystack_str=StrIMatch(needle,haystack_str);
+    else
+      haystack_str=StrMatch(needle,haystack_str);
+    if (haystack_str && flags & SFF_WHOLE_LABELS_BEFORE &&
+          haystack_str!=saved_haystack_str &&
+          Bt(char_bmp_alpha_numeric,*(haystack_str-1))) {
+      haystack_str++;
+      if (*haystack_str)
+        cont=TRUE;
+      else
+        haystack_str=NULL;
+    }
+    if (haystack_str && flags & SFF_WHOLE_LABELS_AFTER &&
+          Bt(char_bmp_alpha_numeric,*(haystack_str+plen))) {
+      haystack_str++;
+      if (*haystack_str)
+        cont=TRUE;
+      else
+        haystack_str=NULL;
+    }
+  } while (cont);
+  return haystack_str;
+}
+
+Bool WildMatch(U8 *test_str,U8 *wild_str)
+{//Wildcard match with '*' and '?'.
+  I64 ch1,ch2;
+  U8 *fall_back_src=NULL,*fall_back_wild=NULL;
+  while (TRUE) {
+    if (!(ch1=*test_str++)) {
+      if (*wild_str && *wild_str!='*')
+        return FALSE;
+      else
+        return TRUE;
+    } else {
+      if (!(ch2=*wild_str++))
+        return FALSE;
+      else {
+        if (ch2=='*') {
+          fall_back_wild=wild_str-1;
+          fall_back_src=test_str;
+          if (!(ch2=*wild_str++))
+            return TRUE;
+          while (ch2!=ch1)
+            if (!(ch1=*test_str++))
+              return FALSE;
+        } else
+          if (ch2!='?' && ch1!=ch2) {
+            if (fall_back_wild) {
+              wild_str=fall_back_wild;
+              test_str=fall_back_src;
+              fall_back_wild=NULL;
+              fall_back_src=NULL;
+            } else
+              return FALSE;
+          }
+      }
+    }
+  }
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/StrB.HC.HTML b/public/Wb/Home/Src/Kernel/StrB.HC.HTML new file mode 100755 index 0000000..af2123f --- /dev/null +++ b/public/Wb/Home/Src/Kernel/StrB.HC.HTML @@ -0,0 +1,218 @@ + + + + + + + + + + + +
+U8 *Tabs2Spaces(U8 *src)
+{//MAlloc str with tabs to spaces.
+  I64 ch,i,j,l=StrLen(src)<<1+2,col=0;
+  U8 *dst=MAlloc(l),*tmp;
+  while (ch=*src++) {
+    if (ch=='\t') {
+      j=(col+8) & ~7;
+      for (i=col;i<j;i++) {
+        dst[i]=CH_SPACE;
+        if (i>=l-2) {
+          tmp=MAlloc(l<<1);
+          MemCpy(tmp,dst,i+1);
+          Free(dst);
+          l<<=1;
+          dst=tmp;
+        }
+      }
+      col=j;
+    } else {
+      dst[col]=ch;
+      if (col>=l-2) {
+        tmp=MAlloc(l<<1);
+        MemCpy(tmp,dst,col+1);
+        Free(dst);
+        l<<=1;
+        dst=tmp;
+      }
+      col++;
+    }
+  }
+  dst[col]=0;
+  return dst;
+}
+
+U8 *ScaleIndent(U8 *src,F64 indent_scale_factor)
+{//MAlloced str.  8*0.25-->2 or 8*2.0-->16
+  I64 ch,i,col=0;
+  U8 *dst,*dst2;
+  while (ch=*src++) {
+    if (ch=='\t')
+      col=(col+8) & -0x8;
+    else if (ch==CH_SPACE)
+      col++;
+    else
+      break;
+  }
+  src--;
+  col=Round(indent_scale_factor*col);
+  dst=dst2=MAlloc(StrLen(src)+col/8+col&7+1);
+  for (i=col/8;i>0;i--)
+    *dst2++='\t';
+  for (i=col&7;i>0;i--)
+    *dst2++=CH_SPACE;
+  StrCpy(dst2,src);
+  return dst;
+}
+
+U8 *MStrUtil(U8 *src,I64 flags,F64 indent_scale_factor=0)
+{//MAlloc StrUtil().
+  U8 *dst=StrNew(src),*dst2,*tmp;
+  StrUtil(dst,flags);
+  if (flags & SUF_T2S) {
+    tmp=Tabs2Spaces(dst);
+    Free(dst);
+    dst=tmp;
+  }
+  if (flags & SUF_SCALE_INDENT)
+    dst2=ScaleIndent(dst,indent_scale_factor);
+  else
+    dst2=StrNew(dst); //Shorten to just right size.
+  Free(dst);
+  return dst2;
+}
+
+U0 GetOutOfDollar()
+{//If a $ has been printed, print another $ to exit mode.
+  CDoc *doc;
+  if (IsRaw) {
+    if (text.raw_flags&RWF_IN_DOLLAR)
+      '$';
+  } else {
+    if (fp_doc_put && (doc=(*fp_doc_put)(Fs)) && doc->flags&DOCF_IN_DOLLAR)
+      '$';
+  }
+}
+
+Bool YorN()
+{//Wait for user to answer Y or N.
+  I64 ch;
+  "(y or n)? ";
+  while (TRUE) {
+    ch=ToUpper(GetChar(,FALSE));
+    if (ch=='Y') {
+      "$PT$YES$FG$\n";
+      return TRUE;
+    } else if (ch=='N') {
+      "$PT$NO$FG$\n";
+      return FALSE;
+    }
+  }
+}
+
+I64 PressAKey()
+{//Print "Press a key" and wait for non-zero ASCII key.
+  "$BK,1$PRESS A KEY$BK,0$\n";
+  return GetChar(,FALSE);
+}
+
+Bool AreYouSure()
+{//Print "Are you sure" and waits for Y or N.
+  "ARE YOU SURE ";
+  return YorN;
+}
+
+U0 Help()
+{//Dbg help or master help index file.
+  if (IsDbgMode)
+    DbgHelp;
+  else
+    PopUp("Type(\"::/Doc/HelpIndex.DD\");DocTop;View;");
+}
+
+U0 ScanFlags(U8 *_dst_flags,U8 *lst,U8 *src)
+{/*More than 64 flags. Flags passed by ref.
+
+Examples:
+ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+
+I64 flags=0;
+ScanFlags(&flags,"R\0L\0Dump\0Scan\0","+Dump-R"); //Sets Bit#2, Clears Bit#0.
+*/
+  I64 i;
+  U8 *buf,*ptr;
+  if (src) {
+    buf=MAlloc(StrLen(src)+1);
+    while (*src) {
+      while (*src && *src!='+' && *src!='-')
+        src++;
+      if (*src=='+') {
+        src++;
+        if (*src) {
+          ptr=buf;
+          while (*src && *src!='+' && *src!='-' &&
+                *src!=CH_SPACE && *src!=CH_SHIFT_SPACE)
+            *ptr++=*src++;
+          *ptr=0;
+          i=LstMatch(buf,lst);
+          if (i>=0)
+            LBts(_dst_flags,i);
+          else {
+            Free(buf);
+            throw('ScanFlag');
+          }
+        }
+      } else if (*src=='-') {
+        src++;
+        if (*src) {
+          ptr=buf;
+          while (*src && *src!='+' && *src!='-' &&
+                *src!=CH_SPACE && *src!=CH_SHIFT_SPACE)
+            *ptr++=*src++;
+          *ptr=0;
+          i=LstMatch(buf,lst);
+          if (i>=0)
+            LBtr(_dst_flags,i);
+          else {
+            Free(buf);
+            throw('ScanFlag');
+          }
+        }
+      }
+    }
+    Free(buf);
+  }
+}
+
+U8 *StrPrintFlags(U8 *dst,U8 *lst,I64 flags)
+{//Only 64 flags. Flags passed by value.
+  I64 i;
+  *dst=0;
+  while (flags) {
+    i=Bsf(flags);
+    Btr(&flags,i);
+    CatPrint(dst,"+%z",i,lst);
+  }
+  return dst;
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/StrPrint.HC.HTML b/public/Wb/Home/Src/Kernel/StrPrint.HC.HTML new file mode 100755 index 0000000..e196895 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/StrPrint.HC.HTML @@ -0,0 +1,951 @@ + + + + + + + + + + + +
+U0 SPutChar(U8 **_dst,U8 ch,U8 **_buf)
+{
+  I64 i;
+  U8 *dst=*_dst,*buf;
+  if (_buf) {
+    buf=*_buf;
+    i=dst-buf;
+    if (i>=MSize(buf)) {
+      buf=MAlloc(i<<1+1);
+      MemCpy(buf,*_buf,i);
+      Free(*_buf);
+      dst=buf+i;
+      *_buf=buf;
+    }
+  }
+  *dst++=ch;
+  *_dst=dst;
+}
+
+U0 OutStr(U8 *ptr,U8 **_buf,U8 **_dst,I64 len,I64 flags)
+{
+  I64 i,j;
+  if (!ptr)
+    i=0;
+  else
+    i=StrLen(ptr);
+  if (flags&PRTF_TRUNCATE && i>len)
+    i=len;
+  if (flags&PRTF_LEFT_JUSTIFY) {
+    for (j=0;j<i;j++)
+      SPutChar(_dst,*ptr++,_buf);
+    for (j=0;j<len-i;j++)
+      SPutChar(_dst,CH_SPACE,_buf);
+  } else {
+    for (j=0;j<len-i;j++)
+      SPutChar(_dst,CH_SPACE,_buf);
+    for (j=len-i;j<len;j++)
+      SPutChar(_dst,*ptr++,_buf);
+  }
+}
+
+U8 *MPrintTime(CDate cdt)
+{
+  CDateStruct ds;
+  Date2Struct(&ds,cdt+local_time_offset);
+  return MStrPrint("%02d:%02d:%02d",ds.hour,ds.min,ds.sec);
+}
+
+U8 *MPrintDate(CDate cdt)
+{
+  CDateStruct ds;
+  Date2Struct(&ds,cdt+local_time_offset);
+  return MStrPrint("%02d/%02d/%02d",ds.mon,ds.day_of_mon,ds.year%100);
+}
+
+U8 *MPrintQ(U8 *ptr,I64 flags)
+{
+  U8 **_buf,*buf,**_dst,*dst,buf2[8],*ptr2;
+  I64 ch;
+  buf=MAlloc(STR_LEN);
+  _buf=&buf;
+  dst=buf;
+  _dst=&dst;
+  if (ptr)
+    while (ch=*ptr++) {
+      switch (ch) {
+        case '$':
+          if (flags&PRTF_DOLLAR) {
+            SPutChar(_dst,'\\',_buf);
+            SPutChar(_dst,'d',_buf);
+          } else {
+            SPutChar(_dst,ch,_buf);
+            SPutChar(_dst,ch,_buf);
+          }
+          break;
+        case '%':
+          SPutChar(_dst,ch,_buf);
+          if (flags&PRTF_SLASH)
+            SPutChar(_dst,ch,_buf);
+          break;
+        case '\n':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,'n',_buf);
+          break;
+        case '\r':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,'r',_buf);
+          break;
+        case '\t':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,'t',_buf);
+          break;
+        case '"':
+        case '\\':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,ch,_buf);
+          break;
+        default:
+          if (ch>=CH_SHIFT_SPACE && ch!=0x7F)
+            SPutChar(_dst,ch,_buf);
+          else {
+            StrPrint(buf2,"\\x%02X",ch);
+            ptr2=buf2;
+            while (*ptr2)
+              SPutChar(_dst,*ptr2++,_buf);
+          }
+      }
+    }
+  SPutChar(_dst,0,_buf);
+  return buf;
+}
+
+U8 *MPrintq(U8 *ptr,I64 flags)
+{
+  U8 **_buf,*buf,**_dst,*dst;
+  I64 i,j,ch,ch1;
+  buf=MAlloc(STR_LEN);
+  _buf=&buf;
+  dst=buf;
+  _dst=&dst;
+  if (ptr)
+    while (ch=*ptr++) {
+      ch1=*ptr;
+      switch (ch) {
+        case '\\':
+          switch (ch1) {
+            start:
+              case '0':
+                SPutChar(_dst,0,_buf);
+                break;
+              case '\'':
+                SPutChar(_dst,'\'',_buf);
+                break;
+              case '\`':
+                SPutChar(_dst,'\`',_buf);
+                break;
+              case '"':
+                SPutChar(_dst,'"',_buf);
+                break;
+              case '\\':
+                SPutChar(_dst,'\\',_buf);
+                break;
+              case 'd':
+                SPutChar(_dst,'$',_buf);
+                break;
+              case 'n':
+                SPutChar(_dst,'\n',_buf);
+                break;
+              case 'r':
+                SPutChar(_dst,'\r',_buf);
+                break;
+              case 't':
+                SPutChar(_dst,'\t',_buf);
+                break;
+            end:
+              ptr++;
+              break;
+
+            case 'x':
+            case 'X':
+              i=0;
+              ptr++;
+              for (j=0;j<2;j++) {
+                ch1=ToUpper(*ptr++);
+                if (Bt(char_bmp_hex_numeric,ch1)) {
+                  if (ch1<='9')
+                    i=i<<4+ch1-'0';
+                  else
+                    i=i<<4+ch1-'A'+10;
+                } else {
+                  ptr--;
+                  break;
+                }
+              }
+              SPutChar(_dst,i,_buf);
+              break;
+
+            default:
+              SPutChar(_dst,ch,_buf);
+          }
+          break;
+        case '$':
+          SPutChar(_dst,ch,_buf);
+          if (ch1=='$')
+            ptr++;
+          break;
+        case '%':
+          SPutChar(_dst,ch,_buf);
+          if (flags&PRTF_SLASH && ch1=='%')
+            ptr++;
+          break;
+        default:
+          SPutChar(_dst,ch,_buf);
+      }
+    }
+  SPutChar(_dst,0,_buf);
+  return buf;
+}
+
+U8 *sys_pos_pows_lets=" KMGTPEZY",
+   *sys_neg_pows_lets=" munpfazy",
+   *sys_pos_pows_lst="kilo\0mega\0giga\0tera\0peta\0exa\0zetta\0yotta\0",
+   *sys_neg_pows_lst="milli\0micro\0nano\0pico\0femto\0atto\0zepto\0yocto\0";
+
+#define TMP_BUF_LEN     256
+#define SLOP            8
+
+U8 *StrPrintJoin(U8 *dst,U8 *fmt,I64 argc,I64 *argv)
+{/*Print("") Fmt Strings
+In float formatting, do not exceed 18-digits
+before or after the decimal point
+because the numbers before and after
+the decimal point are stored
+in 64-bits.  Use exponentiated forms
+to avoid this.
+*/
+  I64 i,j,l,ch,k,k0,n,n0,len,dec_len,flags,old_flags,
+        aux_fmt_num,comma_cnt,comma_fmt_cnt,cur_arg=0;
+  U64 m;
+  F64 d,d1;
+  CDoc *doc;
+  U8 *ptr,**_buf,*buf,**_dst,tmp_buf[TMP_BUF_LEN],tmp_buf2[TMP_BUF_LEN*2];
+
+  if (!fmt)
+    throw('StrPrint');
+  if (dst) {
+    _buf=NULL;
+    buf=dst;
+  } else {
+    buf=MAlloc(STR_LEN);
+    _buf=&buf;
+    dst=buf;
+  }
+  _dst=&dst;
+
+  while (ch = *fmt++) {
+    if (ch=='%') {
+      flags=0;
+      if (*fmt=='-') {
+        flags|=PRTF_LEFT_JUSTIFY;
+        fmt++;
+      }
+      if (*fmt=='0') {
+        flags|=PRTF_PAD_ZERO;
+        fmt++;
+      }
+      len=0;
+      while ('0'<=*fmt<='9')
+        len=len*10+ *fmt++ -'0';
+      if (*fmt=='*') {
+        fmt++;
+        if (cur_arg>=argc)
+          throw('StrPrint');
+        len=argv[cur_arg++];
+      }
+      dec_len=0;
+      if (*fmt=='.') {
+        fmt++;
+        while ('0'<=*fmt<='9')
+          dec_len=dec_len*10+ *fmt++ -'0';
+        if (*fmt=='*') {
+          fmt++;
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          dec_len=argv[cur_arg++];
+        }
+        flags|=PRTF_DECIMAL;
+      }
+
+      aux_fmt_num=0;
+      while (TRUE) {
+        switch (*fmt) {
+          start:
+            case '$':
+              flags|=PRTF_DOLLAR;
+              break;
+            case '/':
+              flags|=PRTF_SLASH;
+              break;
+            case ',':
+              flags|=PRTF_COMMA;
+              break;
+            case 't':
+              flags|=PRTF_TRUNCATE;
+              break;
+            case 'l': //harmless
+              break;
+          end:
+            fmt++;
+            break;
+
+          case 'h':
+            fmt++;
+            flags|=PRTF_AUX_FMT_NUM;
+            if (*fmt=='?') {
+              fmt++;
+              flags|=PRTF_QUESTION;
+            } else {
+              if (*fmt=='*') {
+                fmt++;
+                if (cur_arg>=argc)
+                  throw('StrPrint');
+                aux_fmt_num=argv[cur_arg++];
+              } else {
+                if (*fmt=='-') {
+                  fmt++;
+                  flags|=PRTF_NEG_AUX_FMT_NUM;
+                }
+                while ('0'<=*fmt<='9')
+                  aux_fmt_num=aux_fmt_num*10+ *fmt++ -'0';
+                if (flags&PRTF_NEG_AUX_FMT_NUM)
+                  aux_fmt_num=-aux_fmt_num;
+              }
+            }
+            break;
+          default:
+            goto sp_arg;
+        }
+      }
+
+      sp_arg:
+      k=0;
+      switch (*fmt++) {
+        start:
+          case 'F':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            if (flags&PRTF_DOLLAR) {
+              doc=argv[cur_arg++];
+              old_flags=doc->flags;
+              doc->flags|=DOCF_NO_CURSOR;
+              ptr=DocSave(doc);
+              doc->flags=old_flags;
+            } else
+              ptr=FileRead(argv[cur_arg++]);
+            break;
+          case 'Q':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintQ(argv[cur_arg++],flags);
+            break;
+          case 'q':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintq(argv[cur_arg++],flags);
+            break;
+          case 'D':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintDate(argv[cur_arg++]);
+            break;
+          case 'T':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintTime(argv[cur_arg++]);
+            break;
+        end:
+          OutStr(ptr,_buf,_dst,len,flags);
+          Free(ptr);
+          break;
+
+        start:
+          case 's':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=argv[cur_arg++];
+            break;
+          case 'S':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=Define(argv[cur_arg++]);
+            break;
+          case 'z':
+            if (cur_arg+1>=argc)
+              throw('StrPrint');
+            ptr=LstSub(argv[cur_arg],argv[cur_arg+1]);
+            cur_arg=cur_arg+2;
+            break;
+          case 'Z':
+            if (cur_arg+1>=argc)
+              throw('StrPrint');
+            ptr=DefineSub(argv[cur_arg],argv[cur_arg+1]);
+            cur_arg=cur_arg+2;
+            break;
+        end:
+          OutStr(ptr,_buf,_dst,len,flags);
+          break;
+
+        start:
+          case 'c':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            tmp_buf[0](I64)=argv[cur_arg++];
+            tmp_buf[8]=0;
+            break;
+          case 'C':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            tmp_buf[0](I64)=argv[cur_arg++];
+            tmp_buf[8]=0;
+            ptr=tmp_buf;
+            while (*ptr) {
+              *ptr=ToUpper(*ptr);
+              ptr++;
+            }
+            break;
+        end:
+          if (!(flags&PRTF_AUX_FMT_NUM))
+            aux_fmt_num=1;
+          while (aux_fmt_num-->0)
+            OutStr(tmp_buf,_buf,_dst,len,flags);
+          break;
+
+        case 'p':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          StrPrintFunSeg(tmp_buf,argv[cur_arg++],len,flags);
+          OutStr(tmp_buf,_buf,_dst,len,flags);
+          break;
+        case 'P':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          StrPrintFunSeg(tmp_buf,argv[cur_arg],len,flags);
+          if (!IsRaw || !_buf) {
+            StrPrint(tmp_buf2,"$LK,\"%s\",A=\"AD:0x%X\"$",
+                  tmp_buf,argv[cur_arg]);
+            OutStr(tmp_buf2,_buf,_dst,len,flags);
+          } else
+            OutStr(tmp_buf,_buf,_dst,len,flags);
+          cur_arg++;
+          break;
+        case 'd':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (m(I64)<0) {
+            flags|=PRTF_NEG;
+            m=-m;
+          }
+sp_out_dec:
+          if (flags&PRTF_AUX_FMT_NUM) {
+            if (!len) len=12;
+            d=m;
+            goto sp_out_eng;
+          }
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=3;
+            do {
+              tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=3;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+sp_out_comma_num:
+            if (flags&PRTF_NEG)
+              i=1;
+            else
+              i=0;
+            if (len<0)
+              len=0;
+            if (flags&PRTF_TRUNCATE && k+i>len)
+              k=len-i;
+            if (k<0)
+              k=0;
+            if (flags&PRTF_PAD_ZERO) {
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+              comma_cnt=(len-k-i+comma_fmt_cnt-comma_cnt+1)
+              %(comma_fmt_cnt+1)+1;
+              for (;i<len-k;i++) {
+                if (!--comma_cnt) {
+                  SPutChar(_dst,',',_buf);
+                  comma_cnt=comma_fmt_cnt;
+                  if (++i>=len-k)
+                    break;
+                }
+                SPutChar(_dst,'0',_buf);
+              }
+            } else {
+              for (;i<len-k;i++)
+                SPutChar(_dst,CH_SPACE,_buf);
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+            }
+          } else {
+            do {
+              tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+            } while (k<TMP_BUF_LEN-SLOP);
+sp_out_num:
+            if (flags&PRTF_NEG)
+              i=1;
+            else
+              i=0;
+            if (len<0)
+              len=0;
+            if (flags&PRTF_TRUNCATE && k+i>len)
+              k=len-i;
+            if (k<0)
+              k=0;
+            if (flags&PRTF_PAD_ZERO) {
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+              for (;i<len-k;i++)
+                SPutChar(_dst,'0',_buf);
+            } else {
+              for (;i<len-k;i++)
+                SPutChar(_dst,CH_SPACE,_buf);
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+            }
+          }
+          for (i=k-1;i>=0;i--)
+            SPutChar(_dst,tmp_buf[i],_buf);
+          break;
+        case 'u':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          goto sp_out_dec;
+        case 'f':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+
+          if (d==inf) {
+sp_out_inf:
+            if (flags&PRTF_NEG)
+              i=1;
+            else
+              i=0;
+            k=1;
+            if (len<0)
+              len=0;
+            if (flags&PRTF_TRUNCATE && k+i>len)
+              k=len-i;
+            if (k<0)
+              k=0;
+            for (;i<len-k;i++)
+              SPutChar(_dst,CH_SPACE,_buf);
+            if (flags&PRTF_NEG)
+              SPutChar(_dst,'-',_buf);
+            for (i=0;i<k;i++)
+              SPutChar(_dst,'inf',_buf);
+            break;
+          }
+
+          sp_out_f:
+          if (dec_len<0)
+            dec_len=0;
+          n=Log10(d);
+          if (i=dec_len) {
+            if (flags&PRTF_COMMA)
+              i=i-i/4;
+            if (n+i>17) {
+              n+=i-17;
+              d*=Pow10I64(i-n);
+            } else {
+              n=0;
+              d*=Pow10I64(i);
+            }
+            i=dec_len;
+          } else if (n>17) {
+            n-=17;
+            d*=Pow10I64(-n);
+          } else
+            n=0;
+
+          m=Round(d);
+          if (flags&PRTF_COMMA) {
+            comma_cnt=i&3;
+            while (i-- && k<TMP_BUF_LEN-SLOP) {
+              if (i>2 && !comma_cnt--) {
+                tmp_buf[k++]=',';
+                comma_cnt=2;
+                if (!--i) break;
+              }
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!i) break;
+            }
+          } else {
+            while (i-- && k<TMP_BUF_LEN-SLOP) {
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+            }
+          }
+          if (dec_len)
+            tmp_buf[k++]='.';
+          if (flags&PRTF_COMMA) {
+            comma_cnt=3;
+            do {
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=3;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+          } else {
+            do {
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+            } while (k<TMP_BUF_LEN-SLOP);
+          }
+          goto sp_out_num;
+        case 'e':
+          if (!len) len=12;
+          flags|=PRTF_TRUNCATE;
+
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+          if (d==inf) goto sp_out_inf;
+
+          if (d)
+            n=Floor(Log10(d));
+          else
+            n=0;
+sp_out_e:
+          d/=Pow10I64(n);
+
+          k0=k;
+          for (l=0;l<2;l++) {
+            n0=n;
+            if (n<0) {
+              n=-n;
+              flags|=PRTF_NEG_E;
+            } else
+              flags&=~PRTF_NEG_E;
+
+            i=3;
+            do tmp_buf[k++]=ModU64(&n,10)+'0';
+            while (n && i--);
+            if (flags&PRTF_NEG_E)
+              tmp_buf[k++]='-';
+            tmp_buf[k++]='e';
+            dec_len=len-k-2;
+            if (flags&PRTF_NEG)
+              dec_len--;
+
+            if (d) {
+              d1=d+Pow10I64(-dec_len)/2;
+              if (d1<1.0) {
+                d*=10;
+                n=n0-1;
+                k=k0;
+              } else if (d1>=10) {
+                d/=10;
+                n=n0+1;
+                k=k0;
+              } else
+                break;
+            } else
+              break;
+          }
+
+          goto sp_out_f;
+        case 'g':
+          if (!len) len=12;
+          flags|=PRTF_TRUNCATE;
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+          if (d==inf) goto sp_out_inf;
+          if (d)
+            n=Floor(Log10(d));
+          else
+            n=0;
+          if (n>=len-1-dec_len || n<-(dec_len-1))
+            goto sp_out_e;
+          else
+            goto sp_out_f;
+        case 'n':
+          if (!len) len=12;
+          flags|=PRTF_TRUNCATE;
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+sp_out_eng: //Engineering notation
+          if (d==inf) goto sp_out_inf;
+          if (d)
+            n=FloorI64(Floor(Log10(d)),3);
+          else
+            n=0;
+          d/=Pow10I64(n);
+
+          if (n<0) {
+            n=-n;
+            flags|=PRTF_NEG_E;
+          }
+          if (flags&PRTF_AUX_FMT_NUM && -24<=n<=24) {
+            if (flags&PRTF_QUESTION) {
+              if (flags&PRTF_NEG_E)
+                i=-n/3;
+              else
+                i=n/3;
+              j=0;
+            } else {
+              if (flags&PRTF_NEG_E)
+                j=-n-aux_fmt_num;
+              else
+                j=n-aux_fmt_num;
+              d*=Pow10I64(j);
+              i=aux_fmt_num/3;
+            }
+            if (i<0)
+              tmp_buf[k++]=sys_neg_pows_lets[-i];
+            else if (i>0)
+              tmp_buf[k++]=sys_pos_pows_lets[i];
+            else if (len!=0)
+              tmp_buf[k++]=CH_SPACE;
+            if (!(flags&PRTF_DECIMAL)) {
+              dec_len=len-k-2;
+              if (flags&PRTF_NEG)
+                dec_len--;
+              if (j>0) {
+                if (flags&PRTF_COMMA)
+                  dec_len-=4*j/3;
+                else
+                  dec_len-=j;
+              }
+              d1=d+Pow10I64(-dec_len+1)/2;
+              if (d1>=10) {
+                dec_len--;
+                if (d1>=100)
+                  dec_len--;
+              }
+            }
+          } else {
+            i=3;
+            do tmp_buf[k++]=ModU64(&n,10)+'0';
+            while (n && i--);
+            if (flags&PRTF_NEG_E)
+              tmp_buf[k++]='-';
+            tmp_buf[k++]='e';
+            if (!dec_len) {
+              dec_len=len-k-2;
+              if (flags&PRTF_NEG)
+                dec_len--;
+              d1=d+Pow10I64(-dec_len+1)/2;
+              if (d1>=10) {
+                dec_len--;
+                if (d1>=100)
+                  dec_len--;
+              }
+            }
+          }
+          if (flags&PRTF_COMMA) {
+            if (len && dec_len>0 && !(dec_len&3))
+              tmp_buf[k++]=',';
+            dec_len-=dec_len/4;
+          }
+          goto sp_out_f;
+        case 'X':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=4;
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='A'-0x3A;
+              k++;
+              m>>=4;
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=4;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+            goto sp_out_comma_num;
+          } else {
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='A'-0x3A;
+              k++;
+              m>>=4;
+            } while (m && k<TMP_BUF_LEN-SLOP);
+            goto sp_out_num;
+          }
+        case 'x':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=4;
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='a'-0x3A;
+              k++;
+              m>>=4;
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=4;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+            goto sp_out_comma_num;
+          } else {
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='a'-0x3A;
+              k++;
+              m>>=4;
+            } while (m && k<TMP_BUF_LEN-SLOP);
+            goto sp_out_num;
+          }
+        case 'b':
+        case 'B':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=4;
+            do {
+              tmp_buf[k++]= m&1 +'0';
+              m>>=1;
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=4;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+            goto sp_out_comma_num;
+          } else {
+            do {
+              tmp_buf[k++]= m&1 +'0';
+              m>>=1;
+            } while (m && k<TMP_BUF_LEN-SLOP);
+            goto sp_out_num;
+          }
+        case '%':
+          SPutChar(_dst,'%',_buf);
+          break;
+      }
+    } else
+      SPutChar(_dst,ch,_buf);
+  }
+  SPutChar(_dst,0,_buf);
+  return buf;
+}
+
+U8 *StrPrint(U8 *dst,U8 *fmt,...)
+{//See StrPrintJoin().
+  return StrPrintJoin(dst,fmt,argc,argv);
+}
+
+U8 *CatPrint(U8 *_dst,U8 *fmt,...)
+{//StrCat().  See StrPrintJoin().
+  U8 *dst=_dst;
+  while (*dst)
+    dst++;
+  StrPrintJoin(dst,fmt,argc,argv);
+  return _dst;
+}
+
+U0 Print(U8 *fmt,...)
+{//Print("") Fmt Strings.  See StrPrintJoin().
+//Don't use this.  See Print() shortcut.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  PutS(buf);//Don't use PutS().  See Print() shortcut.
+  Free(buf);
+}
+
+U8 *MStrPrint(U8 *fmt,...)
+{//MAlloc StrPrint.  See StrPrintJoin().
+  U8 *res,*buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=StrNew(buf);
+  Free(buf);
+  return res;
+}
+
+U0 PrintErr(U8 *fmt,...)
+{//Print "Err:" and msg in blinking red.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  GetOutOfDollar;
+  "%,p %,p %,p %,p " ST_ERR_ST "%s",Caller,Caller(2),Caller(3),Caller(4),buf;
+  Free(buf);
+}
+
+U0 PrintWarn(U8 *fmt,...)
+{//Print "Warn:" and msg in blinking red.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  GetOutOfDollar;
+  "%,p %,p %,p %,p " ST_WARN_ST "%s",Caller,Caller(2),Caller(3),Caller(4),buf;
+  Free(buf);
+}
+
+ diff --git a/public/Wb/Home/Src/Kernel/StrScan.HC.HTML b/public/Wb/Home/Src/Kernel/StrScan.HC.HTML new file mode 100755 index 0000000..0cf1db3 --- /dev/null +++ b/public/Wb/Home/Src/Kernel/StrScan.HC.HTML @@ -0,0 +1,370 @@ + + + + + + + + + + + +
+I64 Str2I64(U8 *st,I64 radix=10,U8 **_end_ptr=NULL)
+{//String to I64. Similar to strtoul().
+//Allows radix change with "0x20" "0b1010" "0d123" "0o18".
+  //Be careful of Str2I64("0b101",16)-->0xB101.
+  Bool neg=FALSE;
+  I64 ch,res=0;
+  if (!st || !(2<=radix<=36)) {
+    if (_end_ptr) *_end_ptr=st;
+    return 0;
+  }
+  while (Bt(char_bmp_white_space,*st))
+    st++;
+  while (TRUE)
+    switch (*st) {
+      case '-':
+        st++;
+        neg=!neg;
+        break;
+      case '+':
+        st++;
+        break;
+      case '0':
+        st++;
+        ch=ToUpper(*st);
+        if (ch>='B' && (radix<=10 || ch>'A'+radix-11))
+          switch (ch) {
+            case 'B': radix=2;  st++; break;
+            case 'D': radix=10; st++; break;
+            case 'X': radix=16; st++; break;
+          }
+      default:
+        goto ai_cont;
+    }
+ai_cont:
+  while (ch=ToUpper(*st++)) {
+    if (radix>10) {
+      if ('0'<=ch<='9')
+        res=res*radix+ch-'0';
+      else if ('A'<=ch<='A'+radix-11)
+        res=res*radix+ch-'A'+10;
+      else
+        break;
+    } else if ('0'<=ch<='0'+radix-1)
+      res=res*radix+ch-'0';
+    else
+      break;
+  }
+  if (_end_ptr) *_end_ptr=st-1;
+  if (neg)
+    return -res;
+  else
+    return res;
+}
+
+F64 Str2F64(U8 *src,U8 **_end_ptr=NULL)
+{/*String to F64.
+Does not allow more than 18-digits
+before or after the decimal point
+because the numbers before and after
+the decimal point are stored
+in 64-bits.  Use exponentiated forms
+to avoid this.
+*/
+  I64 i,j,k,ch;
+  F64 d;
+  Bool neg=FALSE,neg_e=FALSE;
+
+  ch=*src++;
+  while (Bt(char_bmp_white_space,ch))
+    ch=*src++;
+  if (ch=='-') {
+    neg=TRUE;
+    ch=*src++;
+  }
+  if (!StrNCmp(src-1,"inf",3)) {
+    d=inf;
+    src+=3;
+    goto a2f_end;
+  }
+  if (*src=='inf') {
+    d=inf;
+    src++;
+    goto a2f_end;
+  }
+  i=0;
+  while (TRUE) {
+    if (Bt(char_bmp_dec_numeric,ch))
+      i=i*10+ch-'0';
+    else {
+      if (ch=='.' || ch=='e' || ch=='E')
+        break;
+      d=i;
+      goto a2f_end;
+    }
+    ch=*src++;
+  }
+  if (ch=='.')
+    ch=*src++;
+  k=0;
+  while (TRUE) {
+    if (Bt(char_bmp_dec_numeric,ch)) {
+      i=i*10+ch-'0';
+      k++;
+    } else {
+      if (ch=='e' || ch=='E')
+        break;
+      d=i*Pow10I64(-k);
+      goto a2f_end;
+    }
+    ch=*src++;
+  }
+  ch=*src++;
+  if (ch=='-') {
+    neg_e=TRUE;
+    ch=*src++;
+  }
+  j=0;
+  while (TRUE) {
+    if (Bt(char_bmp_dec_numeric,ch))
+      j=j*10+ch-'0';
+    else {
+      if (neg_e)
+        d=i*Pow10I64(-j-k);
+      else
+        d=i*Pow10I64(j-k);
+      goto a2f_end;
+    }
+    ch=*src++;
+  }
+a2f_end:
+  if (_end_ptr) *_end_ptr=src-1;
+  if (neg)
+    return -d;
+  else
+    return d;
+}
+
+CDate Str2Date(U8 *_src)
+{/*"*+nnnn", "*-nnnn", "mm/dd", "mm/dd/yy"
+It also supports some funs
+SM() start of mon
+EM() end of mon
+SY() start of year
+EY() end of year
+Full expressions are not implimented
+but you can do stuff like SM(*-7)+3
+and it will return the 3rd day after
+the start of mon for seven days before
+today.
+*/
+  CDate res=0;
+  CDateStruct ds,ds_now;
+  U8 *src=MStrUtil(_src,SUF_REM_SPACES|SUF_TO_UPPER),
+        *v=StrNew(src),
+        *ptr=src;
+  Bool start_mon=FALSE,end_mon=FALSE,
+        start_year=FALSE,end_year=FALSE;
+
+  MemSet(&ds,0,sizeof(CDateStruct));
+  if (!StrNCmp(ptr,"SM(",3)) {
+    ptr+=3;
+    start_mon=TRUE;
+  } else if (!StrNCmp(ptr,"EM(",3)) {
+    ptr+=3;
+    end_mon=TRUE;
+  } else if (!StrNCmp(ptr,"SY(",3)) {
+    ptr+=3;
+    start_year=TRUE;
+  } else if (!StrNCmp(ptr,"EY(",3)) {
+    ptr+=3;
+    end_year=TRUE;
+  }
+  if (*ptr=='*') {
+    ptr++;
+    if (*ptr=='+' || *ptr=='-')
+      res.date=Str2I64(ptr,,&ptr);
+    res+=Now+local_time_offset;
+  } else {
+    StrFirstRem(ptr,"/",v); //Put mon into v
+    ds.mon=Str2I64(v);
+    if (StrOcc(ptr,'/')) {
+      StrFirstRem(ptr,"/",v); //Put day into v leaving year in ptr
+      ds.day_of_mon=Str2I64(v);
+      ds.year=Str2I64(ptr,,&ptr);
+      if (ds.year<100) //if not 4 digit year
+        ds.year+=2000;
+    } else {
+      ds.day_of_mon=Str2I64(ptr,,&ptr);
+      Date2Struct(&ds_now,Now+local_time_offset);
+      ds.year=ds_now.year;
+    }
+    res=Struct2Date(&ds);
+  }
+  if (*ptr==')') ptr++;
+
+  if (start_mon)
+    res.date=FirstDayOfMon(res.date);
+  else if (end_mon)
+    res.date=LastDayOfMon(res.date);
+  else if (start_year)
+    res.date=FirstDayOfYear(res.date);
+  else if (end_year)
+    res.date=LastDayOfYear(res.date);
+
+  if (*ptr=='+' || *ptr=='-')
+    res.date+=Str2I64(ptr);
+  Free(src);
+  Free(v);
+  return res-local_time_offset;
+}
+
+U8 *StrScan(U8 *src,U8 *fmt,...)
+{/*Opposite of sprintf().  Pass ptrs to data to be scanned-in.
+For "%s", pass ptr to ptr (be careful because addr
+of array is the same as array--create ptr to array
+and take addr.
+*/
+  U8 *buf,*ptr,**pptr;
+  Bool left_justify=FALSE;
+  I64 ch,cur_arg=0,i,len,*i_ptr,dec_len;
+  F64 *d_ptr;
+  if (!fmt)
+    throw('Scan');
+  while (ch = *fmt++) {
+    if (ch=='%') {
+      if (*fmt=='%') {
+        src++;
+        fmt++;
+      } else {
+        if (*fmt=='-') {
+          left_justify=TRUE;
+          fmt++;
+        } else
+          left_justify=FALSE;
+        len=0;
+        while ('0'<=*fmt<='9')
+          len=len*10+ (*fmt++ -'0');
+        if (*fmt=='*') {
+          fmt++;
+          if (cur_arg>=argc)
+            throw('Scan');
+          len=argv[cur_arg++];
+        }
+        ch=*fmt++;
+        if (ch && !len) {
+          ptr=src;
+          while (*ptr && *ptr!=*fmt)
+            ptr++;
+          len=ptr-src;
+        } else {
+          if (ch=='.') {
+            dec_len=0;
+            while ('0'<=*fmt<='9')
+              dec_len=dec_len*10+ (*fmt++-'0');
+            if (*fmt=='*') {
+              fmt++;
+              if (cur_arg>=argc)
+                throw('Scan');
+              dec_len=argv[cur_arg++];
+            }
+            ch=*fmt++;
+          }
+        }
+        buf=MAlloc(len+1);
+        for (i=0;i<len;i++)
+          buf[i]=*src++;
+        buf[i]=0;
+        switch (ch) {
+          case 's':
+            if (cur_arg>=argc)
+              throw('Scan');
+            pptr=argv[cur_arg++];
+            StrCpy(*pptr,buf);
+            break;
+          case 'c':
+            if (cur_arg>=argc)
+              throw('Scan');
+            ptr=argv[cur_arg++];
+            *ptr=*buf;
+            break;
+          case 'C':
+            if (cur_arg>=argc)
+              throw('Scan');
+            ptr=argv[cur_arg++];
+            *ptr=ToUpper(*buf);
+            break;
+          case 'z':
+            if (cur_arg+1>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=LstMatch(buf,argv[cur_arg++]);
+            break;
+          case 'Z':
+            if (cur_arg+1>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=DefineMatch(buf,argv[cur_arg++]);
+            break;
+          case 'd':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2I64(buf);
+            break;
+          case 'X':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2I64(buf,16);
+            break;
+          case 'b':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2I64(buf,2);
+            break;
+          case 'e':
+          case 'f':
+          case 'g':
+          case 'n':
+            if (cur_arg>=argc)
+              throw('Scan');
+            d_ptr=argv[cur_arg++];
+            *d_ptr=Str2F64(buf);
+            break;
+          case 'D':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2Date(buf);
+            break;
+        }
+        Free(buf);
+      }
+    } else
+      src++;
+  }
+  return src;
+}
+
+ diff --git a/public/Wb/Home/Src/MakeHome.HC.HTML b/public/Wb/Home/Src/MakeHome.HC.HTML new file mode 100755 index 0000000..a081be7 --- /dev/null +++ b/public/Wb/Home/Src/MakeHome.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+//If these are not present in /Home, it uses the version in the root dir.  You
+//can make your own, modified, version of these files in your /Home directory.
+#include "~/HomeLocalize"
+#include "/Adam/Opt/Boot/MakeBoot"
+#include "/Adam/Opt/Utils/MakeUtils"
+#include "~/HomeWrappers"
+MapFileLoad("::/Kernel/Kernel");
+MapFileLoad("::/Compiler/Compiler");
+#include "~/HomeKeyPlugIns"
+#include "~/HomeSys"
+Cd("..");;
+
+ diff --git a/public/Wb/Home/Src/Misc/DoDistro.HC.HTML b/public/Wb/Home/Src/Misc/DoDistro.HC.HTML new file mode 100755 index 0000000..be7cb9a --- /dev/null +++ b/public/Wb/Home/Src/Misc/DoDistro.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+//Make Your own Distro by #include-ing this file.
+
+#define STD_DISTRO_DVD_CFG      "TB\nScale2Mem(2048,0x40000)\nT \n\n\n\n"
+
+U0 MakeMyISO(U8 *_out_iso_filename)
+{//Does everything with current drive.
+//If you have not recompiled Kernel and defined your CD/DVD drive, use Mount.
+  U8 *out_iso_filename=FileNameAbs(_out_iso_filename);
+  if (!DrvIsWritable) {
+    "Drive must be writable.  Install on Hard drive, first.\n";
+    return;
+  }
+  DelTree("/Distro");
+  Del(out_iso_filename);
+
+  DirMk("/Distro");
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns;
+
+  Copy("/*","/Distro");
+  Del("/Distro/" KERNEL_BIN_C);
+
+  CopyTree(BOOT_DIR,    "/Distro" BOOT_DIR);
+  CopyTree("/Home",     "/Distro/Home");
+  CopyTree("/Adam",     "/Distro/Adam");
+  CopyTree("/Apps",     "/Distro/Apps");
+  CopyTree("/Compiler", "/Distro/Compiler");
+  CopyTree("/Demo",     "/Distro/Demo");
+  CopyTree("/Doc",      "/Distro/Doc");
+  CopyTree("/Kernel",   "/Distro/Kernel");
+  CopyTree("/Misc",     "/Distro/Misc");
+
+  //To save space, optionally delete dictionary.
+  //Del("/Distro/Adam/AutoComplete/ACDefs.DATA");
+  CopyTree("/Downloads","/Distro/Downloads");     //You can leave this out.
+  DirMk("/Distro/Tmp");
+  DirMk("/Distro/Tmp/ScrnShots");
+  RedSeaISO(out_iso_filename,"/Distro","/Distro" BOOT_DIR_KERNEL_BIN_C);
+
+  //If CD-ROM use MT_CD instead of MT_DVD.
+  //DVDImageWrite('T',out_iso_filename,MT_DVD); //Uncomment to burn.
+
+  //DelTree("/Distro");
+  Free(out_iso_filename);
+}
+
+MakeMyISO("/Tmp/MyDistro.ISO.C");
+
+// Study my account examples Cfg Strs, Update Funs.
+
+ diff --git a/public/Wb/Home/Src/Misc/OSInstall.HC.HTML b/public/Wb/Home/Src/Misc/OSInstall.HC.HTML new file mode 100755 index 0000000..6d53bee --- /dev/null +++ b/public/Wb/Home/Src/Misc/OSInstall.HC.HTML @@ -0,0 +1,250 @@ + + + + + + + + + + + +
+U0 InstallDrv(U8 drv_let)
+{
+  U8 *st;
+  ExePrint("CopyTree(\"::/\",\"%C:/\");",drv_let);
+  ExePrint("DirMk(\"%C:/Tmp\");",drv_let);
+  ExePrint("DirMk(\"%C:/Tmp/ScrnShots\");",drv_let);
+  ExePrint("DirMk(\"%C:/Home\");",drv_let);
+
+  st=MStrPrint("%C:/Home/DoDistro.HC.Z",drv_let);
+  if (!FileFind(st))
+    Copy("::/Misc/DoDistro.HC.Z",st);
+  Free(st);
+
+  st=MStrPrint("%C:/Home/MakeHome.HC.Z",drv_let);
+  if (!FileFind(st))
+    Copy("::/MakeHome.HC.Z",st);
+  Free(st);
+}
+
+Bool VMPrtDsk(CTask *task,CATARep *ata_drv)
+{
+  if (ata_drv) {
+    XTalkWait(task,"DskPrt(,0.5,0.5);\nC\np%d\nY",ata_drv->num);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 VMInstallDrv(CTask *task,U8 drv_let,
+        CATARep *ata_drv,CATARep *atapi_drv)
+{
+  InstallDrv(drv_let);
+  XTalkWait(task,"BootHDIns('%C');\n\nB\n0x20000\n",drv_let);
+  if (ata_drv)
+    XTalkWait(task,"C\np%d\n",ata_drv->num);
+  if (atapi_drv)
+    XTalkWait(task,"Tp%d\n",atapi_drv->num);
+  XTalkWait(task,"\n\n\n"); //Exit Drives,Dsk Cache,Options
+}
+
+U0 VMInstallWiz()
+{
+  CATARep *head=NULL,*ata_drv=NULL,*atapi_drv=NULL;
+  CTask *task;
+  "\nIt's normal for this to freeze for a moment or two.\n";
+  PressAKey;
+
+  task=User;
+  TaskWait(task);
+  task->border_src=BDS_CONST;
+  task->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  task->text_attr  =LTGRAY<<4+BLUE;
+  task->win_inhibit=WIG_TASK_DFT-WIF_SELF_BORDER;
+  WinHorz(Fs->win_left,Fs->win_right,task);
+  WinVert(Fs->win_top,(Fs->win_top+Fs->win_bottom)>>2-1,task);
+  WinVert(task->win_bottom+3,Fs->win_bottom);
+  WinToTop(Fs);
+
+  ATARep(FALSE,TRUE,&head);
+  ATAIDDrvs(head,&ata_drv,&atapi_drv);
+  if (VMPrtDsk(task,ata_drv)) {
+    VMInstallDrv(task,'C',ata_drv,atapi_drv);
+    VMInstallDrv(task,'D',ata_drv,atapi_drv);
+    BootMHDIns('C');
+  }
+  LinkedLstDel(head);
+  WinVert(task->win_top,Fs->win_bottom);
+  Kill(task);
+}
+
+U0 RegularInstallWiz()
+{
+  I64 unit,drv_let;
+  U8 *st,*base0,*base1;
+  CATARep *head=NULL,*tmpha;
+  I64 ch,num_hints;
+  CTask *task;
+
+  "\nIt's normal for this to freeze for a moment or two.\n";
+  PressAKey;
+
+  task=User;
+  TaskWait(task);
+  task->border_src=BDS_CONST;
+  task->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  task->text_attr  =LTGRAY<<4+BLUE;
+  task->win_inhibit=WIG_TASK_DFT-WIF_SELF_BORDER;
+  WinHorz(Fs->win_left,Fs->win_right,task);
+  WinVert(Fs->win_top,(Fs->win_top+Fs->win_bottom)>>2-1,task);
+  WinVert(task->win_bottom+3,Fs->win_bottom);
+  WinToTop(Fs);
+  XTalk(task,"Mount;\nC\np");
+
+  num_hints=ATARep(FALSE,,&head);
+  "\nInclude '$PURPLE$0x$FG$' for hexidecimal numbers.\n\n";
+  while (TRUE) {
+    base0=GetStr("Hard Drive I/O Port Base0  : ");
+    if (0<Str2I64(base0)<=0xFFFF)
+      break;
+    Free(base0);
+  }
+  if (1<=Str2I64(base0)<=num_hints) {
+    tmpha=ATARepFind(&head,Str2I64(base0));
+    Free(base0);
+    base0=MStrPrint("0x%X",tmpha->base0);
+    base1=MStrPrint("0x%X",tmpha->base1);
+    st   =MStrPrint("0x%X",tmpha->unit);
+    unit=Str2I64(st);
+    Free(st);
+  } else {
+    while (TRUE) {
+      base1=GetStr("Hard Drive I/O Port Base1  : ");
+      if (0<Str2I64(base1)<=0xFFFF)
+        break;
+      Free(base1);
+    }
+    do {
+      st =GetStr("Unit--$PURPLE$0$FG$=Master or $PURPLE$1$FG$=Slave: ","0");
+      unit=Str2I64(st);
+      Free(st);
+    } while (!(0<=unit<=1));
+  }
+  LinkedLstDel(head);
+  XTalkWait(task,"%s\n%s\n%C\n",base0,base1,'0'+unit);
+  DrvRep;
+  do {
+    st=GetStr("\nDestination Partition Letter: ");
+    if (*st)
+      drv_let=Let2Let(*st);
+    else
+      drv_let=0;
+    Free(st);
+  } while (!('A'<=drv_let<='Z'));
+  '\n';
+
+  "$RED$Format %C Partition?$FG$\n",drv_let;
+  if (YorN) {
+    '\n';
+    do {
+      "$PURPLE$1$FG$) Use FAT32\n"
+            "$PURPLE$2$FG$) Use RedSea\n"
+            "\nFile System Type: ";
+      ch=GetChar;
+      '\n';
+    } while (!('1'<=ch<='2'));
+    if (ch=='1')
+      Fmt(drv_let,,FALSE,FSt_FAT32);
+    else
+      Fmt(drv_let,,FALSE,FSt_REDSEA);
+  }
+  InstallDrv(drv_let);
+  XTalkWait(task,"BootHDIns('%C');\n\nB\n0x20000\n"
+        "C\ns%s\n%s\n%C\n\n\n", //Exit Drives,Dsk Cache,Options
+        drv_let,base0,base1,'0'+unit);
+  "$RED$Install Master Boot loader?$FG$";
+  if (YorN) {
+    '\n';
+    BootMHDIns(drv_let);
+  }
+  Free(base0);
+  Free(base1);
+
+  WinVert(task->win_top,Fs->win_bottom);
+  Kill(task);
+}
+
+U0 DoInstructions()
+{
+  CTask *task;
+  AutoComplete;
+  task=Fs->next_task;
+  while (task!=Fs) {
+    if (task!=adam_task && task!=sys_winmgr_task && task!=ac.task) {
+      XTalk(task,"Ed(\"::/Doc/Install.DD.Z\");\n");
+      break;
+    }
+    task=task->next_task;
+  }
+}
+
+Bool DoInstall(Bool pmt_reboot)
+{
+  I64 res=FALSE,vm_install;
+  "\n\n\n\n\nAre you installing inside VMware, QEMU, VirtualBox "
+        "or a similar virtual machine? ";
+  vm_install=YorN;
+  DocBottom;
+
+  if (vm_install) {
+    VMInstallWiz();
+    res=TRUE;
+  } else {
+    "\n\nThis wizard works if you have a partition ready.  "
+          "You can partition the drive or BootHDIns() "
+          "with more options if you do it by hand, not using this wizard.\n\n"
+          "Continue Install Wizard ";
+    if (YorN) {
+      RegularInstallWiz();
+      res=TRUE;
+    } else
+      pmt_reboot=FALSE;
+  }
+  if (pmt_reboot) {
+    "Reboot Now ";
+    if (YorN)
+      Reboot;
+  }
+  return res;
+}
+
+Bool OSInstall(Bool pmt_reboot=TRUE)
+{
+  DoInstructions;
+  return DoInstall(pmt_reboot);
+}
+
+#if __CMD_LINE__
+OSInstall(TRUE);
+#endif
+
+ diff --git a/public/Wb/Home/Src/Misc/OSTestSuite.HC.HTML b/public/Wb/Home/Src/Misc/OSTestSuite.HC.HTML new file mode 100755 index 0000000..7743bc4 --- /dev/null +++ b/public/Wb/Home/Src/Misc/OSTestSuite.HC.HTML @@ -0,0 +1,1754 @@ + + + + + + + + + + + +
+I64 ts_i;
+F64 ts_t0;
+
+U0 TS(U8 *desc)
+{//We must set these because an app can call ProgressBarsRst.
+  U8 *st=MStrPrint("%d. %s",ts_i,desc);
+  if (*desc)
+    progress3_max=1;
+  else
+    progress3_max=0;
+  StrPrint(progress3_desc,"%*hc%s",
+    (PROGRESS_DESC_LEN-StrLen(st))>>1,CH_SPACE,st);
+  Free(st);
+  progress4=ts_i++;
+  progress4_max=171;
+  progress4_t0=ts_t0;
+  *progress4_desc=0;
+  RegExe("TempleOS/OSTestSuite");
+}
+
+U0 TSFile(U8 *name,I64 mS=750)
+{
+  CTask *task=User("#include \"%s\";Sleep(%d);\n",name,mS);
+  DeathWait(&task,TRUE);
+}
+
+U0 TSFileChar(U8 *name,I64 mS=750,I64 ch=CH_SPACE,Bool wait=TRUE)
+{
+  CTask *task=User;
+  if (wait)
+    XTalkWait(task,"#include \"%s\";\n",name);
+  else
+    XTalk(task,"#include \"%s\";\n",name);
+  Sleep(mS);
+  if (ch)
+    PostMsgWait(task,MSG_KEY_DOWN_UP,ch,0);
+  DeathWait(&task,TRUE);
+}
+
+/*
+U0 DoMouseDemo()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/MouseDemo\";\n");
+}
+U0 DoPullDownMenu()
+{
+  XTalkWait(task,"#include \"::/Demo/PullDownMenu\";\n");
+}
+U0 DoTicTacToe()
+{
+  XTalkWait(task,"#include \"::/Demo/Games/TicTacToe\";\n");
+}
+U0 DoLife()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/Life\";\n");
+}
+U0 DoZing()
+{
+  XTalkWait(task,"#include \"::/Demo/Games/Zing\";\n");
+}
+U0 DoSlider()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/Slider\";\n");
+}
+U0 DoScrollBars()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/ScrollBars\";\n");
+}
+U0 DoWhap()
+{
+  XTalkWait(task,"#include \"::/Demo/Games/Whap\";\n");
+}
+U0 DoDataBase()
+{
+  XTalkWait(task,"#include \"::/Demo/Dsk/DataBase\";\n");
+}
+U0 DoDskRaw()
+{
+  XTalkWait(task,"#include \"::/Demo/Dsk/DskRaw\";\n");
+}
+U0 DoTimeClock()
+{
+  XTalkWait(task,"#include \"::/Apps/TimeClock\";\n");
+}
+U0 DoLectures()
+{
+  XTalkWait(task,"#include \"::/Demo/Lectures\";\n");
+}
+U0 DoInFile()
+{
+  XTalkWait(task,"#include \"::/Demo/InFile\";\n");
+}
+U0 DoSpy()
+{
+  XTalkWait(task,"#include \"::/Demo/Spy\";\n");
+}
+U0 DoUnusedDefine()
+{
+  XTalkWait(task,"#include \"::/Demo/DolDoc/UnusedDefine\";\n");
+}
+U0 DoOnceDemo()
+{
+  XTalkWait(task,"#include \"::/Demo/OnceDemo\";\n");
+}
+*/
+
+U0 DoRandDemo()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/RandDemo\";\n");
+  XTalkWait(task," ");
+  XTalkWait(task," ");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLowPassFilter()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/LowPassFilter\";\n");
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMathAudioDemo()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/MathAudioDemo\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMsgLoop()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/MsgLoop\";\n");
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoASCIIOrgan()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Snd/ASCIIOrgan\";\n");
+  Sleep(100);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'A',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'B',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'C',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDoodle()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Doodle\";\n");
+  PostMsgWait(task,MSG_MS_L_DOWN,10,10);
+  PostMsgWait(task,MSG_MS_L_UP,100,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSpeedLine()
+{
+  I64 i=PURPLE+1; //+1 because TRANSPARENT
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Speedline\";\n");
+  PostMsgWait(task,MSG_MS_L_DOWN,10,10);
+  PostMsgWait(task,MSG_MS_L_UP,100,200);
+  PostMsg(task,MSG_MS_R_DOWN_UP,0,0);
+  BirthWait(&task->popup_task);
+  while (i--)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  TaskWait(task);
+  PostMsgWait(task,MSG_MS_L_DOWN,50,10);
+  PostMsgWait(task,MSG_MS_L_UP,150,200);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoKeyBitMap()
+{
+  I64 i_sc=Char2ScanCode('i');
+  CTask *task=User("#include \"::/Demo/KeyBitMap\";\n");
+  Sleep(50);
+  LBts(kbd.down_bitmap,i_sc);
+  Sleep(500);
+  LBtr(kbd.down_bitmap,i_sc);
+  Sleep(50);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDigits()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Digits\";\n");
+  Sleep(100);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'1',0);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSymmetry()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Symmetry\";\n");
+  PostMsgWait(task,MSG_MS_R_DOWN,100,100);
+  PostMsgWait(task,MSG_MS_R_UP,200,200);
+  Sleep(100);
+  PostMsgWait(task,MSG_MS_L_DOWN,10,10);
+  PostMsgWait(task,MSG_MS_L_UP,100,200);
+  Sleep(250);
+  PostMsgWait(task,MSG_MS_L_DOWN,100,200);
+  PostMsgWait(task,MSG_MS_L_UP,400,400);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBSpline()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/BSpline\";\n");
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,50,50);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,300,100);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,150,300);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,0,0);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoScrnCapture()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/ScrnCapture\";\n");
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+  Del("~/DemoScrnShot.GR*");
+}
+
+U0 DoStadium()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Stadium/Stadium\";\n");
+  Sleep(50);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100,10);
+  Sleep(300);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,320,20);
+  Sleep(300);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,520,10);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPalette()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Palette\";\n");
+  Sleep(400);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(400);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoElephantWalk()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/ElephantWalk\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_RIGHT);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoHalogen()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Halogen\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_UP);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_UP,0,SC_CURSOR_UP);
+  PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_RIGHT);
+  Sleep(333);
+  PostMsgWait(task,MSG_KEY_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTheDead()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/TheDead\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(50);
+  }
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBomberGolf()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/BomberGolf\";\n");
+  for (i=0;i<7;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<7;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(200);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoZoneOut()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/Games/ZoneOut\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoVaroom()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Varoom\";\n");
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFlatTops()
+{
+  CTask *task=User("#include \"::/Demo/Games/FlatTops\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,RandI16%400+200,RandI16%300+150);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoWenceslas()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/Games/Wenceslas\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  for (i=0;i<25;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(25);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTreeCheckers()
+{
+  I64 task_num;
+  CTask *task=User("#include \"::/Demo/Games/TreeCheckers\";\n");
+
+  task_num=BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  Sleep(500);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'\n',0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMorseCode()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Snd/MorseCode\";\n");
+  Sleep(50);
+
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(200);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(350);
+
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(50);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(350);
+
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(50);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(25);
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(200);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(25);
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(50);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(500);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPixCollision()
+{
+  I64 w,h;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Collision\";\n");
+  w=task->pix_width>>1 +task->pix_left+task->scroll_x;
+  h=task->pix_height>>1+task->pix_top +task->scroll_y;
+  MsSet(w-35,h-35);
+  InSetMs(10,w+35,w+35);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBlackDiamond()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/BlackDiamond\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(75);
+  }
+  for (i=0;i<12;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(75);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoCtrlR1()
+{
+  I64 i,task_num;
+  CTask *task=User;
+  XTalkWait(task,"//");
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_CTRLR,0);
+  task_num=BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  for (i=0;i<1;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  //Color
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<2;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<2;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  //Width
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<4;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<4;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  //Line
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<7;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,150,95);
+  Sleep(250);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,190,190);
+  Sleep(250);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,110,190);
+  Sleep(250);
+  PostMsg(task,MSG_MS_R_DOWN_UP,100,100);
+
+  //Color
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<2;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<3;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  //Circle
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<10;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,190,190);
+  Sleep(250);
+  PostMsg(task,MSG_MS_R_DOWN_UP,100,100);
+
+  //Exit
+  BirthWait(&task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN+SCF_CTRL);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  Sleep(1000);
+  XTalk(task,"\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoF2Macro()
+{
+  I64 i;
+  U8 *ptr="\"Boo!\\n\";\n";
+  CTask *task=User;
+  DeathWait(&sys_macro_task);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_F2);
+  BirthWait(&sys_macro_task);
+  TaskWait(sys_macro_task);
+
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT|SCF_CTRL);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,CH_SPACE,0); //Press RECORD
+  while (!Bt(&sys_semas[SEMA_RECORD_MACRO],0))
+    Yield;
+
+  while (*ptr)
+    PostMsgWait(task,MSG_KEY_DOWN,*ptr++,0);
+
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,CH_SPACE,0); //Press STOP
+
+  for (i=0;i<10;i++)
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_F2|SCF_SHIFT);
+
+  PostMsg(sys_macro_task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&sys_macro_task);
+
+  Sleep(1000);
+  XTalk(task,"\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLightTable()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/LightTable\";\n\n");
+  TaskWait(task);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'2',0);
+  PostMsgWait(task,MSG_MS_L_DOWN,   100         ,200);
+  PostMsgWait(task,MSG_MS_L_UP,     640-100     ,200);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'3',0);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100         ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100         ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100         ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,120         ,180);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,160         ,120);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,320         ,10);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-160     ,120);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-120     ,180);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-100     ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-100     ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-100     ,200);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,0,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'4',0);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,320,190);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'5',0);
+  PostMsgWait(task,MSG_MS_L_DOWN,460,280);
+  PostMsgWait(task,MSG_MS_L_UP  ,500,220);
+
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPredatorPrey()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/PredatorPrey\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoCharDemo()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/CharDemo\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+  Sleep(750);
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLattice()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Lattice\";\n");
+  for (i=0;i<20;i++)
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,'+',0);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+  }
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+  }
+  for (i=0;i<16;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  }
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoCartesian()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Cartesian\";\n");
+  XTalkWait(task,"0.2*x`1.5\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMPAdd()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/MultiCore/MPAdd\";\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFlapBat()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/Games/FlapBat\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  for (i=0;i<4;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN,CH_SPACE,0);
+    Sleep(100);
+    PostMsgWait(task,MSG_KEY_UP,CH_SPACE,0);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBattleLines()
+{
+  CTask *task=User("#include \"::/Demo/Games/BattleLines\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  MsSet(430,300,,TRUE);
+  InSetMs(10,530,400);
+  MsSet(,,,FALSE);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBigGuns()
+{
+  I64 i,task_num;
+  CTask *task=User("#include \"::/Demo/Games/BigGuns\";\n");
+  task_num=BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDunGen()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/DunGen\";\n");
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  for (i=0;i<12;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(100);
+  }
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTitanium()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Titanium/Run\";\n");
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<3;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN,CH_SPACE,0);
+    LBts(kbd.down_bitmap,SC_CURSOR_RIGHT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_UP,CH_SPACE,0);
+    LBtr(kbd.down_bitmap,SC_CURSOR_RIGHT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_DOWN,CH_SPACE,0);
+    LBts(kbd.down_bitmap,SC_CURSOR_LEFT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_UP,CH_SPACE,0);
+    LBtr(kbd.down_bitmap,SC_CURSOR_LEFT);
+    Sleep(200);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoToTheFront()
+{
+  I64 task_num;
+  CTask *task=User("#include \"::/Apps/ToTheFront/Run\";\n");
+  task_num=BirthWait(&task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,'\n',0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  BirthWait(&task->popup_task,task_num);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  Sleep(5000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPsalmody()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Psalmody/Run\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'z',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'h',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'h',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'g',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'g',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'h',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'h',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'j',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'j',0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT+SCF_CTRL);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'x',0);
+  Sleep(1250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoJukeBox()
+{
+  CTask *task=User("#include \"::/Apps/Psalmody/Load\";"
+        "JukeBox(\"::/Apps/Psalmody/Examples\");\n");
+  BirthWait(&task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(1500);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task->popup_task);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSpan()
+{
+  CTask *task=User("#include \"::/Apps/Span/Run\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoStrut()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Strut/Run\";\n");
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  Refresh(2);
+
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'s',0);
+
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,GR_HEIGHT/2,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,GR_HEIGHT/2,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,GR_HEIGHT/2,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'t',0);
+
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(,,,FALSE);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  LBts(kbd.down_bitmap,Char2ScanCode('1'));
+  Sleep(600);
+  LBtr(kbd.down_bitmap,Char2ScanCode('1'));
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'Z',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'Z',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'Z',0);
+  Sleep(200);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRawHide()
+{
+  CTask *task=User("#include \"::/Demo/Games/RawHide\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(2500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPoleZeros()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/PoleZeros\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoWhap()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Whap\";\n");
+  MsSet(300,200);
+  Sleep(500);
+  InSetMs(3,350,300);
+  Sleep(500);
+  InSetMs(3,450,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoGrid()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/Grid\";\n");
+  MsSet(200,200);
+  Sleep(150);
+  InSetMs(2,400,400);
+  InSetMs(2,200,400);
+  InSetMs(2,200,200);
+  MsSet(,,,TRUE);
+  Sleep(50);
+  MsSet(,,,FALSE);
+  DocBottom(DocPut(task));
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPick()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Pick\";\n");
+  MsSet(200,200);
+  Sleep(500);
+  MsSet(,,,TRUE);
+  InSetMs(4,400,400);
+  MsSet(,,,FALSE);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPick3D()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Pick3D\";\n");
+  MsSet(200,200);
+  Sleep(500);
+  MsSet(,,,TRUE);
+  InSetMs(4,400,400);
+  MsSet(,,,FALSE);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoGrModels()
+{
+  CTask *task=User;
+  I64 i,j,task_num=-1;
+  XTalkWait(task,"#include \"::/Apps/GrModels/Run\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  for (i=0;i<4;i++) {
+    task_num=BirthWait(&task->popup_task,task_num);
+    TaskWait(task->popup_task);
+    for (j=0;j<=i;j++)
+      PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'n',0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoKeepAway()
+{
+  CTask *task=User("#include \"::/Apps/KeepAway/Run\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  MsSet(100,100);
+  Sleep(1500);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,ms.pos.x,ms.pos.y);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRocket()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Rocket\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  Bts(kbd.down_bitmap,SC_CURSOR_UP);
+  Sleep(1000);
+  Btr(kbd.down_bitmap,SC_CURSOR_UP);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  Bts(kbd.down_bitmap,SC_CURSOR_RIGHT);
+  Sleep(1000);
+  Btr(kbd.down_bitmap,SC_CURSOR_RIGHT);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRocketScience()
+{
+  CTask *task=User("#include \"::/Demo/Games/RocketScience\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(2000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMassSpring()
+{
+  CTask *task=User("#include \"::/Demo/Games/MassSpring\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,50,50);  //#1
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,50,200); //#2
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,210,50); //#3
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,310,200);//#4
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,50,50); //1-2
+  PostMsgWait(task,MSG_MS_R_UP,50,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,210,50);//3-4
+  PostMsgWait(task,MSG_MS_R_UP,310,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,50,200);//2-4
+  PostMsgWait(task,MSG_MS_R_UP,310,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,50,50); //1-3
+  PostMsgWait(task,MSG_MS_R_UP,210,50);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSquirt()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Squirt\";\n");
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(100);
+  }
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(100);
+  }
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(100);
+  }
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoXCaliber()
+{
+  I64 i;
+  CTask *task=User;
+  XTalk(task,"#include \"::/Apps/X-Caliber/Run\";\n");
+
+  Sleep(100);
+  if(TaskValidate(task->popup_task)) {
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SCF_CTRL|SC_CURSOR_DOWN);
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    DeathWait(&task->popup_task);
+  }
+
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SCF_SHIFT|SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SCF_SHIFT|SC_CURSOR_RIGHT);
+  }
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_RIGHT,0);
+    Sleep(100);
+    PostMsgWait(task,MSG_KEY_UP,0,SC_CURSOR_RIGHT,0);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFPS()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/CastleFrankenstein\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+  }
+  for (i=0;i<8;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(50);
+  }
+  for (i=0;i<9;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+  }
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTalons()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Talons\";\n");
+  Sleep(500);
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+  }
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPhoneNumWords()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/PhoneNumWords\";\n");
+  XTalkWait(task,"702-254-4223\n\n");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSuggestedSpelling()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/SuggestSpelling\";\n");
+  XTalkWait(task,"effecient\n\n");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFPrintF()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Dsk/FPrintF\";\n");
+  XTalkWait(task,"~/DemoFPrintF.DD.Z");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  XTalkWait(task,"Type(\"~/DemoFPrintF.DD.Z\");\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_CTRLO,0);
+  XTalkWait(task,"Del(\"~/DemoFPrintF.DD*\");\n");
+  Sleep(500);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLastClass()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/LastClass\";\n");
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMiniCompiler()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Lectures/MiniCompiler\";\n");
+  XTalkWait(task,"1+2*(3+4)\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoWebLog()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/WebLogDemo/WebLogRep\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'\n',0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'\n',0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRevFile()
+{
+  CTask *task;
+  Del("~/DemoPoemFwd.DD*");
+  task=User("#include \"::/Demo/RevFileDemo/Rev\";"
+        "Type(\"~/DemoPoemFwd.DD.Z\");Sleep(750);\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSortFile()
+{
+  CTask *task=User("#include \"::/Demo/SortFileDemo/F64FileGen\";"
+        "#include \"::/Demo/SortFileDemo/F64FileSort\";Sleep(750);\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoToHtmlToTXT()
+{
+  CTask *task=User("#include \"::/Demo/ToHtmlToTXTDemo/HtmlGen\";"
+        "#include \"::/Demo/ToHtmlToTXTDemo/TXTGen\";"
+        "Type(\"~/DemoOutPage.TXT\");Sleep(750);\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLogic()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Logic/Run\";\n");
+  XTalkWait(task,"NAND\nNOR\n\n0x100\n0xF0\n0xCC\n0xAA\n\n0x12\n\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPrompt()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Prompt\";\n");
+  XTalkWait(task,"1+2*3<<4\n");
+  XTalkWait(task,"1.0+2*3`2\n");
+  XTalkWait(task,"Terry Davis\n");
+  XTalkWait(task,"*-1\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoNumBible()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/NumBible\";\n");
+  Del("~/DemoNumBible.DD*");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoForm()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/Form\";\n");
+  Sleep(250);
+  XTalk(task,"54321");
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SCF_CTRL|SC_CURSOR_LEFT);
+  XTalk(task,"77777");
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  Sleep(250);
+  XTalk(task,"MyName");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoClickCallBack()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/DolDoc/ClickCallBack\";\n");
+  for (i=0;i<3;i++) {
+    BirthWait(&task->popup_task);
+    TaskWait(task->popup_task);
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(250);
+  }
+  Sleep(500);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMenuBttn()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/MenuBttn\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(500);
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  Sleep(500);
+  PostMsgWait(sys_focus_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  Sleep(500);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMenuSprite()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/MenuSprite\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(50);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(50);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(50);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoExceptions()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Exceptions\";\n");
+  XTalkWait(task,"yy");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDemoDoc()
+{
+  CTask *task=User;
+  XTalkWait(task,"Ed(\"::/Demo/DolDoc/DemoDoc.DD\");\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_CTRLG,0);
+  XTalkWait(task,"100");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFileRead()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/FileRead\";\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDefine()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Define\";\n");
+  XTalkWait(task,"YS\n");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoAsmAndC1()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Asm/AsmAndC1\";\n2\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoAsmAndC2()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Asm/AsmAndC2\";\n2\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 OSTestSuite()
+{
+  CTask *task;
+  ts_t0=tS;
+  ts_i=0;
+
+  TS("BlackDiamond");   DoBlackDiamond;
+  TS("Talons");         DoTalons;
+  TS("FlatTops");       DoFlatTops;
+  TS("DunGen");         DoDunGen;
+  TS("FPS");            DoFPS;
+  TS("ZoneOut");        DoZoneOut;
+  TS("Varoom");         DoVaroom;
+  TS("Rocket");         DoRocket;
+  TS("RocketScience");  DoRocketScience;
+  TS("BattleLines");    DoBattleLines;
+  TS("BigGuns");        DoBigGuns;
+  TS("FlapBat");        DoFlapBat;
+  TS("Titanium");       DoTitanium;
+  TS("ToTheFront");     DoToTheFront;
+  TS("Psalmody");       DoPsalmody;
+  TS("JukeBox");        DoJukeBox;
+  TS("Span");           if (!sys_heap_init_flag) DoSpan; //Has FloodFill
+  TS("Strut");          DoStrut;
+  TS("RawHide");        DoRawHide;
+  TS("KeepAway");       DoKeepAway;
+  TS("XCaliber");       DoXCaliber;
+  TS("Wenceslas");      DoWenceslas;
+  TS("BomberGolf");     DoBomberGolf;
+  TS("TheDead");        DoTheDead;
+  TS("TreeCheckers");   DoTreeCheckers;
+  TS("RadixDort");      TSFile("::/Demo/RadixSort");
+  TS("MPAdd");          DoMPAdd;
+  TS("Primes");         TSFile("::/Demo/MultiCore/Primes");
+  TS("Palindrome");     if (FileFind(BIBLE_FILENAME))
+                                TSFile("::/Demo/MultiCore/Palindrome");
+  TS("MPRadix");        if (mp_cnt>1) TSFile("::/Demo/MultiCore/MPRadix");
+  TS("LoadTest");       if (mp_cnt>1 && DrvIsWritable(':'))
+                                TSFileChar("::/Demo/MultiCore/LoadTest");
+  TS("MPPrint");        if (mp_cnt>1) TSFile("::/Demo/MultiCore/MPPrint");
+  TS("Lock");           if (mp_cnt>1) TSFile("::/Demo/MultiCore/Lock");
+  TS("Interrupts");     if (mp_cnt>1) TSFile("::/Demo/MultiCore/Interrupts");
+  TS("SpritePlot");     TSFileChar("::/Demo/Graphics/SpritePlot");
+  TS("Elephants");      TSFileChar("::/Demo/Graphics/Elephant",,CH_SHIFT_ESC);
+  TS("SpritePlot3D");   TSFileChar("::/Demo/Graphics/SpritePlot3D");
+  TS("SpritePut");      TSFile("::/Demo/Graphics/SpritePut");
+  TS("SpritePutExt");   TSFile("::/Demo/Graphics/SpritePutExt");
+  TS("SpriteText");     TSFile("::/Demo/Graphics/SpriteText");
+  TS("SpriteRaw");      TSFile("::/Demo/Graphics/SpriteRaw");
+  TS("EdSprite");       TSFile("::/Demo/Graphics/EdSprite");
+  TS("Balloon");        TSFile("::/Demo/Graphics/Balloon",0);
+  TS("Carry");          TSFile("::/Demo/Carry");
+  TS("Directives");     TSFile("::/Demo/Directives");
+  TS("RandDemo");       DoRandDemo;
+  TS("Extents");        TSFileChar("::/Demo/Graphics/Extents");
+  TS("NetOfDots");      TSFileChar("::/Demo/Graphics/NetOfDots");
+  TS("SunMoon");        TSFileChar("::/Demo/Graphics/SunMoon");
+  TS("LowPassFilter");  DoLowPassFilter;
+  TS("MathAudioDemo");  DoMathAudioDemo;
+  TS("Lines");          TSFileChar("::/Demo/Graphics/Lines");
+  TS("Bounce"); TSFileChar("::/Demo/Graphics/Bounce",,CH_SHIFT_ESC,FALSE);
+  TS("MsgLoop");        DoMsgLoop;
+  TS("ASCIIOrgan");     DoASCIIOrgan;
+  TS("MorseCode");      DoMorseCode;
+  TS("PixCollision");   DoPixCollision;
+  TS("Doodle");         DoDoodle;
+  TS("MassSpring");     DoMassSpring;
+  TS("SpeedLine");      DoSpeedLine;
+  TS("KeyBitMap");      DoKeyBitMap;
+  TS("BSpline");        DoBSpline;
+  TS("GrModels");       DoGrModels;
+  TS("Blot");           TSFileChar("::/Demo/Graphics/Blot",1800);
+  TS("ScrnCapture");    if (DrvIsWritable('~')) DoScrnCapture;
+  TS("Grid");           DoGrid;
+  TS("Pick");           DoPick;
+  TS("Pick3D");         DoPick3D;
+  TS("Whap");           DoWhap;
+  TS("Palette");        DoPalette;
+  TS("Print");          TSFile("::/Demo/Print");
+  TS("Shading");        TSFileChar("::/Demo/Graphics/Shading",1500);
+  TS("RotateTank");     TSFileChar("::/Demo/Graphics/RotateTank",1500);
+  TS("3DPoly");         TSFileChar("::/Demo/Graphics/3DPoly",1500);
+  TS("Box");            TSFileChar("::/Demo/Graphics/Box",1500);
+  TS("Symmetry");       DoSymmetry;
+  TS("Shadow");         TSFileChar("::/Demo/Graphics/Shadow",1500);
+  TS("Transform");      TSFileChar("::/Demo/Graphics/Transform",,CH_SHIFT_ESC);
+  TS("LightTable");     DoLightTable;
+  TS("PredatorPrey");   DoPredatorPrey;
+  TS("PoleZeros");      DoPoleZeros;
+  TS("Digits");         DoDigits;
+  TS("Stadium");        DoStadium;
+  TS("ElephantWalk");   DoElephantWalk;
+  TS("Halogen");        DoHalogen;
+  TS("Maze");           TSFileChar("::/Demo/Games/Maze",,CH_SHIFT_ESC);
+  TS("FontEd");         TSFileChar("::/Demo/Graphics/FontEd",,CH_SHIFT_ESC);
+  TS("Lattice");        DoLattice;
+  TS("CtrlR1");         DoCtrlR1;
+  TS("F2Macro");        DoF2Macro;
+  TS("SubIntAccess");   TSFile("::/Demo/SubIntAccess");
+  TS("DemoDoc");        DoDemoDoc;
+  TS("TreeDemo");       TSFile("::/Demo/DolDoc/TreeDemo");
+  TS("TextDemo");       TSFile("::/Demo/DolDoc/TextDemo");
+  TS("CursorMove");     TSFile("::/Demo/DolDoc/CursorMove");
+  TS("MiniCompiler");   DoMiniCompiler;
+  TS("MiniGrLib");      TSFile("::/Demo/Lectures/MiniGrLib",0);
+  TS("TimeIns");        TSFileChar("::/Demo/TimeIns");
+  TS("PhoneNumWords");  DoPhoneNumWords;
+  TS("UnusedSpaceRep"); TSFile("::/Demo/Dsk/UnusedSpaceRep");
+  TS("BlkDevRep");      TSFile("::/Demo/Dsk/BlkDevRep");
+  TS("LastClass");      DoLastClass;
+  TS("FPrintF");        if (DrvIsWritable('~')) DoFPrintF;
+  TS("SerializeTree");  TSFile("::/Demo/Dsk/SerializeTree");
+  TS("Exceptions");     DoExceptions;
+  TS("ScrnDCodes");     TSFileChar("::/Demo/ScrnCodes");
+  TS("ExtChars");       TSFile("::/Demo/ExtChars");
+  TS("PanText");        TSFile("::/Demo/Graphics/PanText",0);
+  TS("CharAnimation");  TSFile("::/Demo/Graphics/CharAnimation");
+  TS("CharDemo");       DoCharDemo;
+  TS("DateTime");       TSFile("::/Demo/DateTime");
+  TS("SubSwitch");      TSFile("::/Demo/SubSwitch");
+  TS("NullCase");       TSFile("::/Demo/NullCase");
+  TS("Magicpairs");     TSFile("::/Demo/MagicPairs");
+  TS("Hanoi");          TSFileChar("::/Demo/Graphics/Hanoi",3000);
+  TS("Squirt");         DoSquirt;
+  TS("CommonAncestor");
+        TSFileChar("::/Demo/Graphics/CommonAncestor",1500,CH_SHIFT_ESC);
+  TS("Cartesian");      DoCartesian;
+  TS("RainDrops");      TSFileChar("::/Demo/Games/RainDrops",,CH_SHIFT_ESC);
+  TS("Collision");      TSFileChar("::/Demo/Games/Collision",1500);
+  TS("Logic");          DoLogic;
+  TS("CompileDemo");    TSFile("::/Demo/CompileDemo");
+  TS("Prompt");         DoPrompt;
+  TS("WebLog");         if (DrvIsWritable('~')) DoWebLog;
+  TS("RevFile");        if (DrvIsWritable('~')) DoRevFile;
+  TS("SortFile");       if (DrvIsWritable('~')) DoSortFile;
+  TS("ToHtmlToTXT");    if (DrvIsWritable('~')) DoToHtmlToTXT;
+  TS("RegistryDemo");   if (DrvIsWritable('~'))
+                                TSFile("::/Demo/RegistryDemo");
+  TS("Define");         DoDefine;
+  TS("GlblVars");       TSFile("::/Demo/GlblVars");
+  TS("FileRead");       DoFileRead;
+  TS("ParenWarn");      TSFile("::/Demo/ParenWarn");
+  TS("DefineStr");      TSFile("::/Demo/DolDoc/DefineStr");
+  TS("Data");           TSFile("::/Demo/DolDoc/Data");
+  TS("CallBack");       TSFile("::/Demo/DolDoc/CallBack");
+  TS("ClassMeta");      TSFile("::/Demo/ClassMeta");
+  TS("NumBible");       if (DrvIsWritable('~')) DoNumBible;
+  TS("Form");           DoForm;
+  TS("ClickCallBack");  DoClickCallBack;
+  TS("MenuBttn");       DoMenuBttn;
+  TS("MenuSprite");DoMenuSprite;
+  TS("SuggestedSpelling"); DoSuggestedSpelling;
+  TS("WordSearch");     TSFileChar("::/Demo/WordSearch");
+  TS("StkGrow");        TSFile("::/Demo/StkGrow");
+  TS("MemDemo");        TSFile("::/Demo/MemDemo");
+  TS("WaterFowl");      TSFileChar("::/Demo/Snd/WaterFowl");
+  TS("AsmHelloWorld");  TSFile("::/Demo/Asm/AsmHelloWorld");
+  TS("AsmAndC1");       DoAsmAndC1;
+  TS("AsmAndC2");       DoAsmAndC2;
+  TS("AsmAndC3");       TSFile("::/Demo/Asm/AsmAndC3");
+  TS("MulByHand");      TSFile("::/Demo/Asm/MulByHand");
+  TS("DivByHand");      TSFile("::/Demo/Asm/DivByHand");
+  TS("BuzzFizz");       TSFile("::/Demo/Asm/BuzzFizz");
+  TS("PutDec");         TSFile("::/Demo/Asm/PutDec");
+
+  task=User;
+  TS("Prof");           XTalkWait(task,"DocMax;Prof;HeapLog(ON);\n");
+  TS("PCIRep");         XTalkWait(task,"PCIRep;Sleep(750);\n");
+  TS("MemBIOSRep");     XTalkWait(task,"MemBIOSRep;Sleep(750);\n");
+  TS("MemPageRep");     XTalkWait(task,"MemPageRep;Sleep(750);\n");
+  TS("MemRep");         XTalkWait(task,"MemRep;Sleep(750);\n");
+  TS("ZipRep");         XTalkWait(task,"ZipRep;Sleep(750);\n");
+  TS("ProfRep");        XTalkWait(task,"ProfRep;Sleep(750);\n");
+  TS("HeapLogSizeRep"); XTalkWait(task,"HeapLogSizeRep;Sleep(750);\n");
+  TS("CPURep");         if (mp_cnt>1)
+                                XTalkWait(task,"CPURep(TRUE);Sleep(750);\n");
+  TS("DskChk");         if (DrvIsWritable(':'))
+                                XTalkWait(task,"DskChk;Sleep(750);\n");
+  TS("DrvView");        if (DrvIsWritable(':')) {
+    XTalkWait(task,"DrvView;\n");
+    Sleep(750);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  TS("DskView");        if (DrvIsWritable(':')) {
+    XTalkWait(task,"DskView;\n");
+    Sleep(250); //Short because ATARep takes time.
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  TS("ATARep");         XTalkWait(task,"ATARep;\npSleep(750);\n");
+  TS("HashDepthRep");   XTalkWait(task,
+        "HashDepthRep(adam_task->hash_table);Sleep(750);\n");
+  TS("Who");            XTalkWait(task,"Who;Sleep(750);\n");
+  TS("DrvRep");         XTalkWait(task,"DrvRep;Sleep(750);\n");
+  TS("TaskRep");        XTalkWait(task,"TaskRep;Sleep(750);\n");
+  DeathWait(&task,TRUE);
+
+  ProgressBarsRst("TempleOS/OSTestSuite");
+  "Elapsed Time:%5.3f\n",tS-ts_t0;
+}
+
+OSTestSuite;
+
+ diff --git a/public/Wb/Home/Src/Misc/PCIDevices.DD.HTML b/public/Wb/Home/Src/Misc/PCIDevices.DD.HTML new file mode 100755 index 0000000..a4d9e29 --- /dev/null +++ b/public/Wb/Home/Src/Misc/PCIDevices.DD.HTML @@ -0,0 +1,9460 @@ + + + + + + + + + + + +
+0033    Paradyne Corp.
+        002F    MAIAM Spitfire VGA Accelerator
+        00333   OTI107 Spitfire VGA Accelerator
+003D    master
+        003a    mx98715/25 i740pci
+        003d    mx98715/25 1740pci
+        00D1    mx98715/25 i740 PCI
+0070    Hauppauge Computer Works Inc.
+        6800    PCI\VEN_14F1&DEV_2F30&SUBSY5_205D14F1&REV_01\3&130 Hauppage Nova -TD-500 DVB-T Tuner Device
+        68001   PCI\VEN_14F1&DEV_8810&REV_05 Hauppage Nova -TD-500 DVB-T Tuner Device
+0100    USBPDO-8
+0123    General Dynamics
+0315    SK - Electronics Co., Ltd.
+0402     Acer aspire one
+        1050    0x1050 ethernet controller
+        5606    0x0436 0x4752
+        8086    0x8086 video controller
+        9665    PCI\VEN_10DE&DEV_0059&SUBSYS_2052161F&REV_A2 ZCT8YBT'
+046D    Logitech Inc.
+        0805    atom &#305;ntel &#305;ns&#305;de n.a.
+        0808    n/a Logitech Webcam C600
+        0809    Unknown Webcam Pro 9000
+        082B    n/a n/a
+        0896    5&34B666AE&0&7 Camera
+        08AD    N/A Quickcam Communicate STX
+        08AF    - -
+        08b2    123abc logitech QuickCam. Pro 4000
+        08C6    0x08C1 Logitech OEM Webcam
+        08f0    n/a n/a
+        08F6    0100 QuickCam Communicate
+        092F    QuickCam Express model number: V-UAP9
+        0A0B    A-00008 Logitech ClearChat Pro USB
+        0A1F    USB _ phone toush Logitech G930 Headset
+        5a61    356254 
+        C018    ? Baesline 3 Button Corded Optical Mouse, 2 button + scroll wheel
+        C045    M/N: M-BJ96C. P/N: 830667-0000. PID: c00e Epoxy Hidden
+        C046    n/a n/a
+        c05b    ee ftht
+        C063    k251d DELL 6-Button mouse
+        C226    n/a n/a
+        C227    n/a n/a
+        C22D    n/a n/a
+        C281    J-UA9 Wingman Force J-UA9
+        C312    n/a n/a
+        C404    n/a Logitech TrackMan Wheel
+        C50E    M-RAM99, C-BS35 MediaPlay Cordless Mouse
+        C512    n/a n/a
+        C51B    n/a n/a
+        c51e    Unknown Unknown
+        C526    n/a n/a
+        C52A    Dell Wireless Keyboard w/ mouse HID Keyboard Device
+        C52B    FC8708A607198-10F1043TA3 USB Receiver for Wireless Mouse
+        C52E    n/a USB3 receiver
+        C52F    Logitech Wireless Mouse USB Controller Logitech Wireless Mouse USB Controller
+0483    UPEK
+        2016    UPEK fingerprint sensors  Driver Windows xp
+04A9    Canon
+        314D    unknown uhknown
+04B3    IBM
+        24D5    PCI\VEN_8086&DEV_24D5&SUBSYS_B026144D&REV_02 Audio Controller
+        401             8086 PCI\VEN_8086&DEV_293E&SUBSYS_20F217AA&REV_03\3&B1BFB68&0&D8        
+        401     24C5 PCI\VEN_8086&DEV_24C6&REV_03\3 267A616A
+        4010    cc020000 PCI\VEN_10EC&DEV_5227&SUBSYS_220C17AA&REV_01
+        9876    CC_040100 PCI\VEN_8086&DEV_1C3A&SUBSYS_1C3A1458&REV_04
+04D9    Filco
+        1603    n\a Samsung
+        2011    n/a n/a
+04F2    Chicony Electronics Co. 
+        b008    USB\VID_138A&PID_0001 .oem44.inf
+        B044    . Webcam
+        B175    0001 SN
+        B217    01A000166 Integrated Camera
+        B307    6030 Webcam
+051D    ACPI\VEN_INT&DEV_33A0
+        0002    USB\VID_0B05&PID_580F\E6AZCY495152 Inter (R) Core [TM] 2 Duo cpu
+        051D    USB\VID_0B05&PID_580F\E6AZCY495152 0x051d
+        9876    USB\VID_0B05&PID_580F\E6AZCY495152 USB\VID_0B05&PID_580F\E6AZCY495152
+0529    Aladdin E-Token
+0553     Aiptek USA
+        0200, 0x0201, 0x02      DS38xx Oregon Scientific
+058f    Alcor Micro Corp.
+        0001    6387 AM usb storage
+        0107    0x03 0x01 
+        1234    9380 6387
+        1600    00000000 http://www.alldatasheet.com/datasheet-pdf/pdf/91600/ETC/AU9254A21.html
+        6362    UNKNOWN Unknown 4-in-1 card reader (istar)
+        6366    Unknown Multi Flash Reader USB Device
+        6387    intel g620 USB Mass Storage Device(USB1005B Flash Disk)
+        8CBA    PCI\VEN_8086&DEV_8CBA&SUBSYS_78211462&REV_00\3&115 PCI Simple Communications Controller
+        9254    AU9254A21-HAS http://www.alldatasheet.com/datasheet-pdf/pdf/91600/ETC/AU9254A21.html
+        9380    FC8708-3 Micron=MT29F32G08CBABA
+        9540    Unknown SmartCard Reader
+0590    Omron Corp
+        0028    HEM-790IT hid device class blood pressure monitor
+05ac    Apple Inc.
+        021e    Keyboard IT USB Alluminium Keyboard IT USB
+        1293    Apple iPod 5 Apple iPod 5
+        1297    Apple iPhone  Apple iPhone 4
+        21e     phone 3g Allumium keyboard it USB 
+        8215    BCM2046 Broadcom BCM2046 Bluetooth chipset iMac
+05E1    D-MAX
+        0408    00000000000 USB 2.0 Video Capture Controller
+        0501    120315000000621 web cam
+064e    SUYIN Corporation
+        064e    VID_0000&PID_0000\5&2B3B5BA1&0&1 Suyin
+        a101    suYin Acer Crystal Eye Webcam
+        a103    SuYin WebCam
+        a116    Suiyn Optronics USB 2.0 UVC 0.3M WebCam
+        A219    SUYIN SUYIN 1.3M WebCam
+        B250    SuYin 1.3M HD WebCam
+        c108    dont know its a webcam software
+        d101    SuYin Web Cam
+        D217    SUYIN HP TrueVision HD
+067B    Prolific Technology Inc.
+        2303    2303 HXA Prolific USB 2 Serial Comm Port &#1082;&#1086;&#1085;&#1090;&#1088;&#1086;&#1083;&#1083;&#1077;&#108
+        2305    PL-2303 USB-to-Printer Bridge Controller
+        2393    prolific prolificz
+        2506    PL-2506 Hi-Speed USB to IDE Bridge Controller
+        25a1    PL-2501 Prolific PCLinq3 USB Transfer Cable Driver
+        9876    067B TES
+06FE    Acresso Software Inc.
+        9700    i don't know a netcard used usb interface
+0711    SIIG, Inc.
+093a    KYE Systems Corp. / Pixart Imaging
+        2468    Genius iLook 300 http://genius.ru/products.aspx?pnum=24948&archive=1
+        2600    PAC7311 http://www.speedlink.com/support/bin/24-02-2012/SETUP.rar
+        2608    PAC7311 - Toshiba PX1342E-1 CAM USB\VID_093A&PID_2608&REV_0100&MI_00
+        2620    CNR-WCAM53G WEBCAM http://www.canyon-tech.com/archive/voip/webcams/CNR-WCAM53#pr-switcher
+096E    USB Rockey dongle from Feitain 
+        0201    Rockey4  
+0A5C    Broadcom Corporation
+        0201    Blutonium BCM2035 Bluetooth 2.4 GHz Single Chip Tr Broadcom USB iLine10(tm) Network Adapter
+        10DE    0264 Controlador sm
+        2000     0578A97 Broadcom Bluetooth Firmware Upgrade Device
+        2009      Broadcom Bluetooth Controller
+        200a      Broadcom Bluetooth Controller
+        200f     PCI\VEN_14E4&DEV_43B1&SUBSYS_2B231A3B&REV_03 Broadcom 802.11ac Network Adapter 
+        201d     n450 BROADCOM Bluetooth Device
+        201e      IBM Integrated Bluetooth IV
+        2020      Broadcom Bluetooth Dongle
+        2021     0A5C BCM2035B3 ROM Adapter Generic
+        2033      1ujy100539f Broadcom Blutonium Device Firmware Downloader
+        2035    5&263C7E89&0&1 BCM92035NMD Bluetooth
+        2038      Broadcom Blutonium Device Firmware Downloader (BCM2038)
+        2039     BCM92045B3 ROM BROADCOM Bluetooth Device
+        2045    BCM2045A Broadcom Bluetooth Controller
+        2046     5738z Broadcom USB Bluetooth Device
+        2047      Broadcom USB Bluetooth Device
+        205e     USB\VID_0A5C&PID_5801&MI_00 Broadcom Bluetooth Firmware Upgrade Device
+        2100    BT 50 Broadcom Bluetooth 2.0+eDR USB dongle
+        2101    USB\VID_0A5C&PID_2101 Broadcom Bluetooth 2.0+EDR USB dongle
+        2102     USB\VID_04B4&PID_2102\5&38CD4C16&0&6 ANYCOM Blue USB-200/250
+        2110     39A18BDD Broadcom Bluetooth Controller
+        2111      ANYCOM Blue USB-UHE 200/250
+        2120     2045 Broadcom 2045 Bluetooth 2.0 USB-UHE Device with trace filter
+        2121      Broadcom 2045 Bluetooth 2.0 USB Device with trace filter
+        2122     BCM92045B3 Broadcom Bluetooth 2.0+EDR USB dongle
+        2124      2045B3ROM Bluetooth Dongle
+        2130      Broadcom 2045 Bluetooth 2.0 USB-UHE Device with trace filter
+        2131      Broadcom 2045 Bluetooth 2.0 USB Device with trace filter
+        2140      2046 Flash UHE Class 2
+        2141      2046 Flash non UHE Class 2
+        2142      2046 Flash non UHE Class 1
+        2143      2046 Flash non UHE Class 1
+        2144      2046 Flash non UHE module Class 2
+        2145    bcm9204md  Broadcom BCM9204MD LENO Module
+        2146      Broadcom 2045 Bluetooth 2.1 USB UHE Dongle
+        2147     0A5C&PID_5800 Broadcom 2046 Bluetooth 2.1 USB Dongle
+        2148    GBU421 Broadcom 2046 Bluetooth 2.1 USB UHE Dongle
+        2149      Broadcom 2046 Bluetooth 2.1 USB Dongle
+        214a      Broadcom 2046 Bluetooth 2.1 USB Module
+        214b     52AF1AB24D Broadcom 2046 Bluetooth 2.1 USB Module
+        214c      Broadcom 2046 Bluetooth 2.1 USB Module
+        214d      Broadcom Bluetooth 2.1 UHE Module
+        214e      Thinkpad Bluetooth with Enhanced Data Rate II
+        214f      Broadcom 2046 Bluetooth 2.1 USB UHE Dongle
+        2150      Broadcom 2046 Bluetooth 2.1 USB Dongle
+        2151     2151 Broadcom Bluetooth 2.1 USB Dongle
+        2152      Broadcom 2046 Bluetooth 2.1 USB UHE Dongle
+        2153      Broadcom 2046 Bluetooth 2.1 USB UHE Dongle
+        2154      Broadcom 2046 Bluetooth 2.1 USB UHE Dongle
+        2155      Broadcom Bluetooth USB Dongle
+        2157      BCM2046 B1 USB 500
+        2158      Broadcom 2046 Bluetooth 2.1 Device
+        219C    BCM2070 Broadcom BCM2070 Bluetooth 3.0+HS USB Device 
+        21E1    Broadcom 20702 Bluetooth 4.0 .0112
+        21E3    BCM43142A0 Broadcom Bluetooth 4.0
+        4500    BCM2046B1 Broadcom 2046 Bluetooth 2.1 USB Dongle
+        4502    BCM2046B1 Broadcom 2046 Bluetooth 2.1 USB Dongle
+        4503     BCM2046B1 Broadcom 2046 Bluetooth 2.1 USB Dongle
+        5800     1ujy100539f Unified Security Hub
+        5801    0x5801 Unified Security Hub 
+        6300     965 Pirelli ISB Remote NDIS Device
+        6688    PCI NVIDIA GeForce GT 240M
+        8613    USB\VID_04B4&PID_8613&REV_:001 TD 3104 USB vedio grabber 
+        9876    0x9876 0x9876
+0A89    BREA Technologies Inc.
+0A92    Egosys, Inc.
+        1010    1010&REV_0101&MI_00  RoMI/o by Egosys - Midi USB Cable
+0AC8    ASUS 
+        1234    1 1
+        6719    3330 8086&DEV_0F18&SUBSYS_16DD1043&REV_0E
+        9876    1 1
+0b05    Toshiba Bluetooth RFBUS, RFCOM, RFHID
+        170C    6205 WIFI USB Card
+0c45    Microdia Ltd.
+        0C45    USB\VID_041&PID_6143&REV_0101 USB2.0
+        1111    USB\VID_0C45&PID_612A\5&B0F4C74&0&2 USB webcam
+        5243    USB xda exec Uknown device
+        6007    USB\VID_0C45&PID_6007&REV_0101 Genius WebCam Eye
+        600D    USB\VID_0C45&PID_600D&REV_0101 USB(v1.1) webcam
+        602C    SN9C102C home made
+        602D    VID_0C45&PID_6480&MI_00 USB Webcam
+        6030    USB\VID_0C45&PID_6029\5&18D8BE1C&0&1 USB WebCam 
+        610C    USB\VID_0C45&PID_610B\7&3211544E$$0$$2 usb web camera 
+        6128    USB\VID_0C45&PID_613C&REV_0101 USB &#1074;&#1077;&#1073;-&#1082;&#1072;&#1084;&#1077;&#1088;&#1072;
+        6128_   USB\VID_0C45&PID_6148&REV_0101 USB PC Camera Plus
+        6129    USB\VID_0C45&PID_6128\5&3875c171&0&1 USB WebCam
+        6130    USB\VID_0000&PID_0000\5&1AAEDD8&0&2 USB HUB
+        613A    USB\VID_0C45&PID_613A\5&2F621EE5&0&5 USB WEBCAM
+        613c    USB\VID_0C45&PID_613C\5&377B3285&0&1  USB Webcam
+        613E    5&29957435&0&1 USB Camera
+        624f    Sonix SN9C201 Integrated Webcam in Compal HEL81 series barebones.
+        6270    USB\VID_0C45&PID_6270 USB Microscopr
+        6270a   USB\VID_0C45&PID_6270&REV_0100 webcam with mic link works for win 7
+        6270_   usb\vid_oc45&pid_627b\5&138897&#1044;1&0&5 webcam
+        627F    USB\VID_17A1&PID_0118&REV_0100 USB\VID_17A1&PID_0118&REV_0100
+        62B3    USB\Vid_0c45&Pid_62b3&Rev_0100&MI_00 USB 2.0 PC Camera
+        62BF    USB\Vid_0c45&Pid_62bf USB\Vid_0c45&Pid_62bf&Rev_0100
+        62c0    SNP2UVC Sonix Webcam
+        6353    USB\VID_0000&PID_0000\5&1FFD6427&0&2 USB Microscope
+        641D    USB\VID_0C45&PID_643d 1.3 MPixel Integrated Webcam used in Dell N5010 series
+        6421    USB\VID_0C45&PID_6421&REV_0224&MI_00 USB 2.0 Webcam slim 32
+        642F    USB\VID_0C45&PID_642F&REV_1224 Webcam
+        644b    oc45&oid 641d& 9:07&mi oo oc45&oid 641d& 9:07&mi oo
+        6489    0x6489 Integrated Webcam Universal Serial Bus controllers
+        6840    USB\VID_0C45&PID_6480&MI_00  sonix 1.3 mp laptop integrated webcam
+        7401    n.a. RDing TEMPer1V1.4
+        9876    USB\VID_090C&PID_B371&MI_00\6&462987E&0&0000 webcam
+0cf3    TP-Link
+        1002    Wireless USB 2.0 adapter TL-WN821N Wireless USB 2.0 adapter TL-WN821N
+        3000    USB\VID_0000&PID_0000\6&F763642&0&4 USB\VID_0000&PID_0000\6&F763642&0&4
+        3002    USB\VID_0CF3&PID_3002&REV_0001 USB\VID_0CF3&PID_3002&REV_0001
+        3002_   unknown unknown
+        3005    AR3011 Atheros Bluetooth Module
+        9271    0x0108 TP-LINK 150 Mbps Wireless Lite N Adapter TL-WN721N
+0D2E    Feedback Instruments Ltd.
+0D8C    C-Media Electronics, Inc.
+        000E    00 Generic USB Audio Device
+        0102    6206lc USB 5.1CH audio codec
+        5200    0x5200 C-Media USB 2.0 Mass Storage Controller
+0DF6    Sitecom
+        9071       \t9071\t WL-113 - Wireless Network USB dongle 5 \t9071\t   WL-113 - Wireless Network USB dongle 54g  
+0E11    Compaq Computer Corp.
+        0001    2 PCI to EISA Bridge
+        0002    64320 D2ufG0  <a href   000F    CPQB1A9 StorageWorks Library Adapter (HVD)
+        0012    686P7 686P7
+        0046    Intel Exteme Graphics Smart Array 6400 Controller
+        0049    NC7132 Gigabit Upgrade Module
+        004A    NC6136 Gigabit Server Adapter
+        005A    PowerPC 405GP processor at 200MHz [3305103C] HP Remote Insight Lights-Out II Board
+        00B1    3305103C HP Remote Insight Lights-Out II PCI Device
+        00C0    Adaptec AIC-7899G 64Bit,66MHz,Dual Channel WideUltra3 SCSI
+        0508    Neteligent 4/16 TR PCI UTP/STP Controller
+        1000    Triflex Model 1000 Pentium Bridge
+        2000    Triflex Model 2000 Pentium Bridge
+        3032    95479 n9XQeH  <a href   3033    23505 HTdOCe  <a href   3034    QVision 1280/p v2 GUI Accelerator
+        4000    Triflex Model 4000 Pentium Bridge
+        6010    Model 6010 HotPlug PCI Bridge
+        7020    camara web USB Controller
+        A0EC    Original Compaq fibre Channel HBA
+        A0F0    Advanced System Management Controller
+        A0F3    Triflex PCI to ISA PnP Bridge
+        A0F7    PCI bus 6, device 4, function 4 PCI Hotplug Controller
+        A0F8    ZFMicro USB Open Host Controller
+        A0FC    HPFC-5166A Tachyon TL 64-bit/66-Mhz FC HBA
+        Ae10    Smart-2 Array Controller
+        AE29    MIS-L PCI to ISA Bridge
+        AE2A    MPC CPU to PCI Bridge
+        AE2B    MIS-E PCI to ISA PnP Bridge
+        AE31    1002&DEV-5653&SUBSYS System Management Controller
+        AE32    950 Netelligent 10/100 TX PCI UTP TLAN 2.3
+        AE33    Triflex Dual EIDE Controller
+        AE34    Netelligent 10 T PCI UTP TLAN 2.3
+        AE35    Integrated NetFlex 3/P TLAN 2.3
+        AE40    Dual Port Netelligent 10/100 TX PCI TLAN
+        AE43    Integrated Netelligent 10/100 TX PCI
+        AE69    CETUS-L PCI to ISA Bridge
+        AE6C    DRACO PCI Bridge
+        AE6D    NorthStar CPU to PCI Bridge
+        B011    Dual Port Netelligent 10/100 TX
+        B012    Netelligent 10 T/2 UTP/Coax PCI
+        B01E    NC3120 Fast Ethernet NIC
+        B01F    NC3122 Fast Ethernet NIC
+        B02F    NC1120 Ethernet NIC
+        B030    Netelligent WS 1500 10/100TX Embedded UTP/Coax Controller
+        B04A    699209-003 10/100TX WOL UTP Controller
+        0XB060  CISS SMART2 Array Controller
+        B0C6    NC3161 Fast Ethernet Embedded Controller w/ WOL
+        B0C7    NC3160 Fast Ethernet NIC
+        B0D7    NC3121 rev. A & B Fast Ethernet NIC
+        B0DD    NC3131 Fast Ethernet NIC
+        B0DE    NC3132 Fast Ethernet NIC
+        B0DF    NC6132 Gigabit Module
+        B0E0    NC6133 Gigabit Module
+        B0E1    NC3133 Fast Ethernet Module
+        B123    NC6134 Gigabit NIC
+        B134    NC3163 Fast Ethernet NIC
+        B13C    NC3162 Fast Ethernet NIC
+        B144    NC3123 Fast Ethernet NIC
+        B163    NC3134 Fast Ethernet NIC
+        B164    NC3135 Fast Ethernet Upgrade Module
+        B178    CISSB SMART2 Array Controller
+        B196    0230 Conexant SoftK56 Modem
+        B1A4    NC7131 Gigabit Server Adapter
+        B203    iLo Integrated Lights Out Processor
+        B204    iLo Integrated Lights Out Processor
+        F095    FCA2101 HP StorageWorks 2 Gb, 64-Bit/66-MHz PCI-to-Fibre Channel Host Bus Adapter for Windows 2000, Windows
+        F130    ThunderLAN 1.0 NetFlex-3/P
+        F150    PCI\VEN_14E4&DEV_1698&REV_10 ThunderLAN 2.3 NetFlex-3/P with BNC
+        F700    LP7000 Compaq/Emulex Fibre Channel HBA
+        F800    LP8000 Compaq/Emulex Fibre Channel HBA
+0E8D    MediaTek Inc.
+        0002    2200 PCI Simple Communications Controller / Mobiles China
+        0003    VT6212L usb
+1000    LSI Logic
+        0001    LSI53C810 PCI-SCSI I/O Processor
+        0002    53C820 Fast-wide SCSI gg
+        0003    LSI53C1010-33 PCI to SCSI I/O Processor
+        0004    53C815 SCSI raid controllers
+        0005    53C810AP Fast SCSI
+        0006    LSI53C860/860E PCI to Ultra SCSI I/O Processor
+        000A    LSI53C1510 PCI Dual Channel Wide Ultra2 SCSI Ctrlr
+        000B    LSI53C896/897 PCI Dual Channel Wide Ultra2 SCSI Ctrlr
+        000C    LSI53C895 PCI to Ultra2 SCSI I/O Processor
+        000D    53C885 Ultra Wide SCSI, Ethernet
+        000F    53C875/875E/876/876E PCI to Ultra SCSI I/O Processor
+        0010    LSI53C1510 I2O-Ready PCI RAID Ultra2 SCSI Ctrlr
+        0012    LSI53C895A PCI to Ultra2 SCSI Controller
+        0013    LSI53C875A PCI to Ultra SCSI Controller
+        0020    LSI53C1010-33 PCI to Dual Channel Ultra3 SCSI Ctrlr
+        0021    LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller
+        0030    LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller
+        0031    LSI53C1030ZC PCI-X SCSI Controller
+        0032    LSI53C1035 PCI-X to Ultra320 SCSI Controller
+        0035    LSI53C1035 PCI-X SCSI Controller
+        0040    LSI53C1035 PCI-X to Ultra320 SCSI Controller
+        0050    LSISAS1068E LSISAS1068E / LSI SAS 6i RAID Controller
+        0054    LSISAS1068 LSI Adapter SAS 3000 series 8-port with 1068
+        0056    LSISAS1064ET PCI-Express Fusion-MPT SAS
+        0058    LSISAS1068E PCI-Express Fusion-MPT SAS
+        005B    LSISAS2108/2208 LSI Logic / Symbios Logic MegaRAID SAS 2208 [Thunderbolt] [1000:005b] (rev 05)
+        005e    LSISAS1066 PCI-X Fusion-MPT SAS
+        0060    0x1734 0x10f9
+        0062    LSISAS1078 PCI-Express Fusion-MPT SAS
+        0064    LSISAS2116 PCI-Express Fusion-MPT SAS 2.0
+        0072    SAS2008 Dell PERC H200
+        0073    LSISAS2008 IBM ServeRAID M1015, Dell Perc H310
+        0080    LSI Logic SAS2208 PCI-Express Fusion-MPT SAS 2.0/2.5
+        008F    53C810 LSI 53C8xx SCSI host adapter chip
+        0097    LSISAS3008 SAS3008 PCI-Express Fusion-MPT SAS-3
+        0408    L3-01037-03D U320-2E Raid Controller
+        0621    LSIFC909 Fibre Channel I/O Processor
+        0622    53c885 Dial Channel Fibre Channel I/O Processor
+        0623    LSIFC929 Dual Channel Fibre Channel I/O Processor
+        0624    LSIFC919 Fibre Channel I/O Processor
+        0625    LSIFC919 Fibre Channel I/O Processor
+        0626    LSIFC929X Fibre Channel Adapter
+        0628    LSIFC919X Fibre Channel Adapter
+        0630    LSIFC920 Fibre Channel I/O Processor
+        0640    LSIFC949X Fibre Channel Adapter
+        0642    LSIFC939X Fibre Channel Adapter
+        0646    LSIFC949ES Fibre Channel Adapter
+        0701    53C885 10/100 MBit Ethernet
+        0702    Yellowfin G-NIC Gigabit Ethernet Controller
+        0901    61C102 USB Controller
+        1000    63C815 Fast SCSI Controller
+        1001    53C895 Symbios Ultra2 SCSI controller
+        1010    LSI 53C102000 Single channel SCSI controller
+        1020    LSI53C1020 LSI Logic MegaRAID 320-1 Dell PowerEdge PERC 4/SC
+        1960    6002432 RAID Controller
+        3050    LSISAS2008 PCI-Express Fusion-MPT SAS 2.0
+        9876    7DB82C.YF.F.3.25 5946504E44383243
+1001    Kolter Electronic - Germany
+        0010    ispLSI1032E PCI 1616, 16 TTL-IN, 16 TTL-OUT
+        0011    ispLSI1032E OPTO-PCI, 16 IN / 16 OUT 24 VDC
+        0012    ispLSI1032E PCI-AD, PCI-ADDA analog I/O-card
+        0013    ispLSI1032E PCI-OptoRel, PCI-Relais 16 Relais & Opto
+        0014    ispLSI1032E Timer, Pulse & Counter-card 16..32 bit
+        0015    ispLSI1032E PCI-DAC416, 4 channel D/A16bit precision
+        0016    ispLSI1032E PCI-MFB high-speed analog I/O
+        0017    ispLSI1032E PROTO-3 PCI, digital I/O with chipselect
+        0020    ispLSI1032E Universal digital I/O PCI-Interface
+1002    Advanced Micro Devices, Inc.
+         4370   RV370 ATI RADEON X300/X550/X1050 Series Secondary
+         6760   6470M AMD Radeon HD 6470M
+        00000100 (256)  {4D36E972-E325-11CE-BFC1-08002BE10318}\0016 {4D36E972-E325-11CE-BFC1-08002BE10318}\0016
+        0002    EMU10K1 Audio Cipset (SB) Livel
+        000D    bhjkh ATI RADEON X1200 &#1089;&#1077;&#1088;&#1080;&#1080;
+        0180200a        LXPAY0Y001926158A92000         AMD Athlon(tm) X2 Dual-Core QL-62
+        0300    1002 PCI
+        0B12    R580 ATI Radeon X1900
+        1002    0x675d pcie 0x675d pcie
+        10024152        RV360 ATI RADEON 9250 Series
+        1028    R9 200 Radeon R9 200 Series
+        1043    RV410 ATI MOBILITY/ATI RADEON X700
+        11      0x215r2qzua21 0xbcg62
+        1111    ATI Technologies Inc. / Advanced Micro Devices, In ATI Technologies Inc. 
+        1202    1202 PCI standard host CPU bridge
+        1313    Q770 AMD Radeon R7 Series
+        1314    1314 High Definition Audio Controller
+        1400    1400 PCI standard host CPU bridge
+        1401    1401 PCI standard host CPU bridge
+        1402    1402 PCI standard host CPU bridge
+        1403    1403 PCI standard host CPU bridge
+        1404    1404 PCI standard host CPU bridge
+        1405    1405 PCI standard host CPU bridge
+        1410    1410 PCI standard host CPU bridge
+        1417    1417 PCI Express standard Root Port
+        1419    1419 IOMMU Device
+        1631    0000 bus
+        1714    A4-3400 AMD Radeon. HD 6410D Audio
+        1ab8 hex        2 ati radeon 
+        3150    M24 ATI MOBILITY /ATI RADEON X600
+        3151    RV380 ATI FireMV 2400
+        3152    M24 ATI MOBILITY /ATI RADEON X300
+        3154    M24GL ATI MOBILITY FireGL V3200
+        3171    RV380 ATI FireMV 2400 Secondary
+        3E50    PCI\VEN_1002&DEV_68A8&SUBSYS_159B103C&REV_00 ATI RADEON 6870
+        3E54    RV380GL ATI FireGL V3200
+        3E70    RV380 ATI RADEON X600/X550 Series Secondary
+        3E74    RV380GL ATI FireGL V3200 Secondary
+        4136    A3 Radeon IGP 320
+        4137    RS200 Radeon IGP 340m
+        4143    9550 X1050
+        4144    R300 ATI RADEON 9500
+        4145    R300 Radeon 9200 (M+X)
+        4146    R300 ATI RADEON 9600TX
+        4147    R300GL ATI FireGL Z1
+        4148    R350 ATI RADEON 9800 SE
+        4149    R350 ATI RADEON 9500
+        4150    RV_00 ATI RADEON 9600 Pro Family (Microsoft Driver)
+        4151    RV350 ATI RADEON 9600 Series
+        4152    RV360 ATI RADEON 9600 Series
+        4153    RV350 ATI RADEON 9550/X1050 Series
+        4154    RV350GL ATI FireGL T2
+        4155    RV350 ATI RADEON 9600 Series
+        4158    AA01 PCI\VEN_1002&DEV_AAC8&SUBSYS_AAC8174B&REV_00
+        4164    R300 ATI RADEON 9500 Secondary
+        4166    R300 ATI RADEON 9600TX Secondary
+        4167    R300GL ATI FireGL Z1 Secondary
+        4168    R350 ATI RADEON 9800 SE Secondary
+        4169    R350 ATI RADEON 9500 Secondary
+        4170    RV_00 ATI RADEON 9600/9550/x1050 Series Secondary (
+        4171    RV350 ATI RADEON 9600 Series Secondary
+        4172    REV_00 ATI RADEON 9600 Series Secondary
+        4173    4484 ATI RADEON 9550/X1050 Series Secondary
+        4174    RV350GL ATI FireGL T2 Secondary
+        4175    RV350 RADEON 9200 pro secundar
+        4242    R200AIW All-In-Wonder 8500DV
+        4243    Lucent OHCI IEEE1394 Host Controller
+        4336    rs200 Radeon IGP 320M
+        4337    RS200M RADEON IGP 345M
+        4341    SB200 AC'97 Audio Controller
+        4342    SB200 PCI-PCI Bridge
+        4345    SB200 EHCI USB Controller
+        4347    SB200 USB Controller
+        4348    SB200 USB Controller
+        4349    SB200 PATA-100 IDE Controller
+        434C    SB200 PCI-ISA Bridge
+        434d    SB200 AC'97 Modem Controller
+        4353    SB200 SMBus Controller
+        4354    215CT Mach64 CT
+        4358    113-A52021-104 PCI\VEN_1002&DEV_9553&SUBSYS_00821043&REV_00
+        4361    ALC665 ATI AC97 REALTEK AUDIO DRIVER
+        4363    SB300 ATI SOUTH BRIDGE SB300 DRIVER
+        4369    IXP 3xx PATA 133 Controller
+        436E    IXP 3xx ATI 436E Serial ATA Controller
+        4370    SB400 AC-Link Audio
+        4371    IXP SB400 PCI Standard PCI-to-PCI bridge
+        4372    SMBus Controller SMBus Controller
+        4373    IXP SB400 Standard Enhanced PCI to USB Host Controller
+        4374    IXP SB400 Standard OpenHCD USB Host Controller
+        4375    IXP SB400 Standard OpenHCD USB Host Controller
+        4376    SB4xx PATA 133 Controller
+        4377    IXP SB400 PCI Stanard ISA Bridge
+        4378    SB400 AC'97 Modem Controller
+        4379    SB400 / SB450 (Sil3112) ATI 4379 Serial ATA Controller
+        437A    SB4xx ATI 437A Serial ATA Controller
+        437B    SB450 High Definition Audio Controller 
+        4380&CC_0101    ATI SB600 SATA2
+        4380&CC_0104    ATI SB600 RAID/AHCI Controller
+        4380&CC_0106    ATI RS690m AHCI Controller
+        4381    ATI ? AHCI/Raid Controller
+        4383    SB700 High Definition Audio controller
+        4384    4384 ATI I/O Communications Processor PCI Bus Controller
+        4385    ATI RD600/RS600 ATI I/O Communications Processor SMBus Controller
+        4386    690G Northbridge
+        4387    4387 Standard OpenHCD USB Host Controller
+        4388    4388 Standard OpenHCD USB Host Controller
+        4389    4389 Standard OpenHCD USB Host Controller
+        438A    438A Standard OpenHCD USB Host Controller
+        438B    438B Standard OpenHCD USB Host Controller
+        438C    RD600/RS600 ATI RD600/RS600 IDE Controller
+        438D    SB600 PCI to LPC Bridge
+        439     rv360 ATI Technologies SB700 LPCHost Controller
+        4390    SB750 Integrated SATA II Controller
+        4391    ATI SB700 AHCI Controller
+        4391&CC_0106    AMD SB850 AMD Southbridge incorporating AHCI 1.2 with SATA FIS.based switching support
+        4392    ATI SB700 Raid Controller
+        4393    ATI SB850 RAID-Controller
+        4394&CC_0106    5100 AMD SP5100 South Bridge
+        4396    210888CX Standard Enhanced PCI to USB Host Controller
+        4397    4397 Standard OpenHCD USB Host Controller
+        4398    SB700 Standard OpenHCD USB Host Controller
+        439C    SB7xx PATA 133 Controller
+        439D    SB700 LPC 74A
+        43A0    43A0 PCI Express standard Root Port
+        43A3    43A3 PCI Express standard Root Port
+        4437    ATI Mobility Radeon 7000 IGP RS250M
+        4554    Mach64 ET 
+        4654    Mach64 VT 113--34004-104
+        4742    (GT-C2U2) 3D Rage Pro AGP 1X
+        4744    Rage 3D Pro AGP 2x Rage 3D Pro AGP 2x
+        4747    GT-C2U2 Rage 3D Pro
+        4749    RAGE PRO TURBO AGP 2X ATI ALL IN WONDER PRO (8MB)
+        474C    Rage XC PCI-66 k7 som+
+        474D    Rage XL AGP 2x SLAT
+        474E    Rage XC AGP 2x 
+        474F    Rage XL PCI-66 I Need Driver for the Chip
+        4750    1039 ATI 3D Rage Pro 215GP
+        4751    0x1002 0x4752
+        4752    Rage XL PCI ATI On-Board VGA for HP Proliant 350 G3
+        4753    Rage XC PCI 
+        4754    Mach 64 VT Rage 3D II Graphics Accelerator
+        4755    Rage 3D II+pci 3d rage 2 + dvd
+        4756    Rage 3D IIC AGP Graphics Accelerator
+        4757    3D 11C AGP Rage 3D IIC AGP
+        4758    210888GX Mach64 GX
+        4759    215r2qzua21 m3d agp card on agp slot
+        475A    215r2qua12 Rage IIC AGP
+        4966    RV250 Radeon 9000/9000 Pro
+        4967    RV250 Radeon 9000
+        496E    RV250 Radeon 9000/9000 Pro - Secondary
+        496F    RV250 Radeon 9000 - Secondary
+        4A48    R420 ATI RADEON X800 Series
+        4a49    R420 ATI RADEON X800 PRO
+        4A4A    R420 ATI RADEON X800 Series
+        4a4b    R420 ATI RADEON X800 XT
+        4A4C    R420 ATI RADEON X800 Series
+        4A4D    R420GL ATI FireGL X3-256
+        4A4E    M18 ATI MOBILITY /ATI RADEON 9800
+        4A4F    R420 ATI RADEON X800 SE
+        4A50    R420 ATI RADEON X800 XT Platinum Edition
+        4A54    R420 ATI RADEON X800 VE
+        4A68    R420 ATI RADEON X800 Series Secondary
+        4A69    R420 ATI RADEON X800 PRO Secondary
+        4A6A    R420 ATI RADEON X800 Series Secondary
+        4a6b    R420 ATI RADEON X800 XT Secondary
+        4A6C    R420 ATI RADEON X800 Series Secondary
+        4A6D    R420GL ATI FireGL X3-256 Secondary
+        4A6F    R420 ATI RADEON X800 SE Secondary
+        4A70    R420 ATI RADEON X800 XT Platinum Edition Secondary
+        4A74    R420 ATI RADEON X800 VE Secondary
+        4B49    R481 ATI RADEON X850 XT
+        4B4B    R481 ATI RADEON X850 PRO
+        4B4C    R481 ATI RADEON X850 XT Platinum Edition
+        4B69    R481 ATI RADEON X850 XT Secondary
+        4B6A    R481 ATI RADEON X850 SE Secondary
+        4B6B    R481 ATI RADEON X850 PRO Secondary
+        4B6C    R481 ATI RADEON X850 XT Platinum Edition Secondary
+        4C42    B10E0E11 3D Rage LT Pro AGP-133
+        4C44    Rage 3D LT Pro AGP Rage 3D LT Pro AGP 133 MHz
+        4C45    Rage Mobility M3 AGP
+        4C46    Mobility M3 AGP 0x9495
+        4C47    ati rage pro Rage 3D LT-G
+        4C49    123 Rage 3D LT Pro
+        4C4D    01541014 Rage P/M Mobility AGP 2x
+        4C4E    216lo sasa25 Rage Mobility l
+        4C50    unknown Rage 3D LT Pro PCI
+        4C51    113 Rage 3D LT Pro PCI
+        4C52    1241243 Rage P/M Mobility agp
+        4C53    216L0SASA25 Rage L Mobility PCI
+        4C54    4372 Mach 64 LT
+        4C57    M7 [LW] Mobility Radeon 7500
+        4C58    (0x71C1)          DAC type: Internal DAC(400MHz)   FireGL Mobility
+        4C59    ATI Mobility Radeon 7000 with 16MB (7500 with 16 o ATI Mobility Radeon AGP (0x4C59), ATI Technologies Inc. -kompatible
+        4C5A    Radeon Mobility M6 LZ
+        4C64    Radeon Mobility M9-GL
+        4C66    RV250 ATI MOBILITY RADEON 9000
+        4C6E    0x4C6E ATI FireMV 2400 PCI
+        4D46    ATI mobility128 Rage Mobility 128 AGP 4x
+        4D4C    216l0sasa25 Rage Mobility 128 AGP
+        4D52    ATI Theater 550 Pro ATI Theater 550 Pro
+        4D53    TVT2 Wonder Elite TVT2 Wonder Elite
+        4E44    R300 ATI RADEON 9700 PRO
+        4E45    R300 ATI RADEON 9500 PRO / 9700
+        4e46    R300 ATI RADEON 9600 TX
+        4E47    R300GL ATI FireGL X1
+        4E48    R350 ATI RADEON 9800 PRO
+        4E49    R350 ATI RADEON 9800
+        4E4A    R360 ATI RADEON 9800 XT
+        4E4B    R350GL ATI FireGL X2-256/X2-256t
+        4E50    M10 ATI MOBILITY /ATI RADEON 9600/9700 Series
+        4E51    RV350 ATI RADEON 9600 Series
+        4E52    M10 ATI MOBILITY /ATI RADEON 9500
+        4E54    M10GL ATI MOBILITY FIRE GL T2/T2e
+        4E56    M12 ATI MOBILITY /ATI RADEON 9400
+        4E64    R300 ATI RADEON 9700
+        4E65    R300 ATI RADEON 9500 PRO / 9700 Secondary
+        4e66    R300 ATI RADEON 9600 TX Secondary
+        4E67    R300GL ATI FireGL X1 Secondary
+        4E68    R350 ATI RADEON 9800 PRO Secondary
+        4E69    R350 ATI RADEON 9800 Secondary
+        4E6A    R360 ATI RADEON 9800 XT Secondary
+        4E6B    R350GL ATI FireGL X2-256/X2-256t Secondary
+        4E71    RV350 ATI RADEON 9600 Series Secondary
+        5041    gt Rage 128 Pro PA PCI
+        5042    rage 128 pf pro agp  Rage 128 Pro PB AGP 2x
+        5043    1231324445 Rage 128 Pro PC AGP 4x
+        5044    rv100 Rage 128 Pro PD PCI
+        5045    Rage 128 Pro PE AGP 2x
+        5046    R128 Rage 128 Pro PF AGP 4x
+        5047    215R3BUA22  3d Rage pro agp 2x
+        5048    8212104D Rage 128 Pro PH AGP 2x
+        5049    R128 Rage 128 Pro PI AGP 4x
+        504A    Rage 128 Pro PJ PCI Rage 128 Pro PJ PCI (TMDS)
+        504B    Rage 128 Pro PK AGP Rage 128 Pro PK AGP 2x (TMDS)
+        504C    Rage 128 Pro PL AGP 4x (TMDS)
+        504D    Rage 128 Pro PM PCI Rage 128 Pro PM PCI
+        504E    Rage 128 Pro PN AGP Rage 128 Pro PN AGP 2x
+        504F    Rage 128 Pro PO AGP Rage 128 Pro PO AGP 4x
+        5050    Scheda Grafica Standard PCI(VGA) Rage 128 Pro PP PCI (TMDS)
+        5051    Rage 128 Pro PQ AGP Rage 128 Pro PQ AGP 2x (TMDS)
+        5052    Rage 128 Pro PR AGP Rage 128 Pro PR AGP 4x (TMDS)
+        5053    Rage 128 Pro PS PCI Rage 128 Pro PS PCI
+        5054    Rage 128 Pro PT AGP Rage 128 Pro PT AGP 2x
+        5055    rage 128 pro agp 4x tmds rage 128 pro agp 4x tmds
+        5056    Rage 128 Pro PV PCI Rage 128 Pro PV PCI (TMDS)
+        5057    Rage 128 Pro PW AGP Rage 128 Pro PW AGP 2x (TMDS)
+        5058    Rage 128 Pro PX AGP 4x (TMDS)
+        5144    Radeon 7200 QD SDR/DDR Radeon 7200 QD SDR/DDR
+        5145    Radeon QE
+        5146    Radeon QF
+        5147    Radeon QG
+        5148    R200 Radeon R200 QH
+        5149    Radeon R200 QI
+        514A    Radeon R200 QJ
+        514B    Radeon R200 QK
+        514C    R200 Radeon 8500 / 8500LE
+        514D    R200 Redeon 9100 Series
+        514E    Radeon R200 QM
+        514F    Radeon R200 QN
+        5157    RV200 Radeon 7500
+        5158    radeon 9200 Radeon 7500 QX
+        5159    RV100 Radeon 7000 series AGP 
+        515A    Radeon VE QZ
+        515E    Radeon ES1000 Radeon ES1000
+        5168    ati Radeon R200 Qh
+        5169    Radeon R200 Qi
+        516A    Radeon R200 Qj
+        516B    Radeon R200 Qk
+        516C    E7505 Radeon 8500 / 8500LE
+        516D    R200 Redeon 9100 Series - Secondary
+        5245    215R2QZUA21 Rage 128 GL PCI
+        5246    Rage 128 Rage 32MB
+        5247    Rage 32MB Rage 128 RG
+        524B    g01080-108 Rage 128 VR RK PCI
+        524C    Rage 128 VR RL AGP 2x
+        5345    Rage 128 4x SE PCI
+        5346    Rage 128 SF 4x AGP 2x Rage 128 SF 4x AGP 2x
+        5347    Rage 128 SG 4x AGP 4x
+        5348    Rage 128 4x SH
+        534B    Rage 128 SK PCI Rage 128 4x SK PCI
+        534C    Rage 128 SL AGP 2x Rage 128 4x SL AGP 2x
+        534D    Rage 128 SM AGP 4x Rage 128 4x SM AGP 4x
+        534E    Rage 128 4x 
+        5354    Mach 64 ST
+        5446    unknown Rage 128 Pro Ultra TF
+        544C    Rage 128 Pro TL
+        5452    5452 Rage 128 Pro TR
+        5455    Rage 128 Pro Ultra TU
+        5457    RS200M RADEON IGP 345M
+        5460    M22 ATI MOBILITY /ATI RADEON X300
+        5461    M22 ATI MOBILITY /ATI RADEON X300
+        5462    M24C ATI MOBILITY /ATI RADEON X600 SE
+        5464    M22GL ATI MOBILITY FireGL V3100
+        5548    R423 ATI RADEON X800 Series
+        5549    R423 ATI RADEON X800 GTO
+        554A    R423 ATI RADEON X800 XT Platinum Edition
+        554b    R423 ATI RADEON X800 GT
+        554D    R430 ATI RADEON X800 CrossFire Edition
+        554E    R430 ATI RADEON X800 GT
+        554F    R430 ATI RADEON X800 GTO
+        5550    R423GL ATI FireGL V7100
+        5551    R423GL ATI FireGL V5100
+        5568    R423 ATI RADEON X800 Series Secondary
+        5569    R423 ATI RADEON X800 GTO Secondary
+        556A    R423 ATI RADEON X800 XT Platinum Edition Secondary
+        556B    R423 ATI RADEON X800 GT Secondary
+        556D    R430 ATI RADEON X800 CrossFire Edition Secondary
+        556E    R430 ATI RADEON X800 GT Secondary
+        556F    R430 ATI RADEON X800 GTO Secondary
+        5570    R423GL ATI FireGL V7100 Secondary
+        5571    R423GL ATI FireGL V5100  Secondary
+        564A    M26GL ATI MOBILITY FireGL V5000
+        564B    M26GL ATI MOBILITY FireGL V5000
+        564F    M26 ATI MOBILITY /ATI RADEON X700 XL
+        5652    M26 ATI MOBILITY /ATI RADEON X700
+        5653    RV410 ATI MOBILITY/ATI RADEON X700
+        5654    264VT Mach64 VT
+        5655    Mach 64 VT3
+        5656    Mach 64 VT4 PCI Mach 64 VT4 PCI
+        5657    RV410 ATI RADEON X550/X700 Series
+        5673    M26 ATI MOBILITY /ATI RADEON X700 Secondary
+        5677    RV410 ATI RADEON X550/X700 Series Secondary
+        5830    RS300 Host Bridge
+        5831    RS300 Host Bridge
+        5832    RS300 Host Bridge
+        5833    RS300M ATI Radeon 9000/9100 IGP Chipset - Host-PCI Bridge
+        5834    RS300 Radeon 9100 IGP
+        5835    RS300M Mobilitiy Radeon 9000 IGP (RGP)
+        5838    RS330M ATI Radeon 9000/9100 IGP Chipset - AGP Controller
+        5854    RS480 ATI RADEON Xpress Series
+        5874    RS482 ATI RADEON Xpress Series
+        5940    RV280 Radeon 9200 Pro Secondary
+        5941    RV280 ATI Radeon 9200 - Secondary
+        5950    RS480 PCI standard Host CPU Bridge
+        5954    RS482 ATI RADEON Xpress 200
+        5955    RS480M ATI RADEON Xpress 200M
+        5960    RV280 Radeon 9200 Pro
+        5960 AGP        A051400005470 PN 1024-RC26-1F-SA
+        5961    RV280 ATI RADEON 9200 se agp
+        5962    Rev_01 Radeon 9200
+        5964    Radeon 9200 Radeon 9200 SE Series
+        5965    unknown FireMV 2200
+        5974    RS482 ATI RADEON Xpress Series
+        5974&SUBSYS_022A10      RS482 ATI Radeon Xpress 200M (Mobile)
+        5975    RS482M (200M) ATI RADEON Xpress Series
+        5a23    RD890 AMD IOMMU
+        5a31    RS400/133 Host Bridge
+        5A33    RC410 Northbridge: Radeon Xpress 200
+        5A3F    5A3F PCI standard PCI-to-PCI bridge
+        5A41    ATI RADEON Xp   0x5A41  ATI RADEON Xpress 1200 Series   0x1002 0x5A41   ATI RADEON Xpress 1200 Series   0x1002
+        5A41    RS400 ATI RADEON Xpress Series
+        5A42    RS400M ATI RADEON Xpress Series
+        5A43    RS400 ATI RADEON Xpress Series
+        5A60    SUBSYS_FF311179 Video Controller
+        5A61    RC410 ATI Radeon Xpress 200
+        5A613   RC410 ATI RADEON Xpress Series
+        5A62    PCI\VEN_1002&DEV_5A62&SUBSYS_2A051584&REV_00 ATI Radeon X 200
+        5A63    RC410 ATI RADEON Xpress Series
+        5b60    RV370 ATI RADEON X300/X550/X1050 Series..
+        5b62    RV380x ATI RADEON X600 Series
+        5B63    REV_00\4&178951BB&0&0008 ATI RADEON X300/X550/X1050 Series
+        5B64    RV370GL ATI FireGL V3100
+        5B65    RV370 ATI FireMV 2200
+        5B6O    RV370 ATI RADEON X300/X550/X1050 Series
+        5B70    RV380 Radeon
+        5B72    RV380x ATI RADEON X600 Series Secondary
+        5B73    RV370 0 SerieATI RADEON X300 Secondary
+        5B74    RV370GL ATI FireGL V3100 Secondary
+        5B75    RV370 ATI FireMV 2200 Secondary
+        5C61    bk-ati ver008.016m.085.006 Mobility Radeon 9200
+        5C63    RV280 (M9+) Mobility Radeon 9200
+        5D44    RV280 Radeon 9200 SE Series - Secondary
+        5D45    RV280 ATI FireMV 2200 PCI Secondary
+        5D48    M28 ATI MOBILITY/ATI RADEON X800  XT
+        5D49    M28GL ATI MOBILITY FireGL V5100
+        5d4a    M28 ATI MOBILITY /ATI RADEON X800
+        5d4d    R480 ATI RADEON X850 XT Platinum Edition
+        5d4f    R480 ATI RADEON X800 GTO
+        5D50    R480GL ATI FireGL V7200
+        5d52    R480 ATI RADEON X850 XT
+        5D57    R423 ATI RADEON X800 XT
+        5d6d    R480 ATI RADEON X850 XT Platinum Edition Secondary
+        5D6F    R480 ATI RADEON X800 GTO Secondary
+        5D70    R480GL ATI FireGL V7200 Secondary
+        5D72    R480 ATI RADEON X850 XT Secondary
+        5D77    R423 ATI RADEON X800 XT Secondary
+        5E48    RV410GL ATI FireGL V5000
+        5E4A    RV410 ATI RADEON X700 XT
+        5E4B    RV410 ATI RADEON X700 PRO
+        5E4C    RV410 ATI RADEON X700 SE
+        5E4D    RV410 ATI RADEON X700
+        5E4F    RV410 ATI RADEON X700/X550 Series
+        5E68    RV410GL ATI FireGL V5000 Secondary
+        5E6A    RV410 ATI RADEON X700 XT Secondary
+        5E6B    RV410 ATI RADEON X700 PRO Secondary
+        5E6C    RV410 ATI RADEON X700 SE Secondary
+        5E6D    RV410 ATI RADEON X700 Secondary
+        5E6F    RV410 ATI RADEON X700/X550 Series Secondary
+        60760   123123132 11
+        6600    AMD Radeon HD 8600M/8700M/8750M
+        6718    CAYMAN XT AMD Radeon HD 6970
+        6719    Cayman AMD Radeon HD 6950
+        6738    HD6870 MSI
+        6739    Barts (Pro) AMD Radeon HD 6850
+        673E    0x2310 0x1787
+        6740    Powered by AMD ATI Radeon HD 6700M
+        6741    Whistler AMD Radeon. HD 6700M/HD 6600M Series 
+        6741_   AMD Radeon HD 7450M (6470M)&#12289;6630M&#12289;In PCI\VEN_1002&DEV_6741&SUBSYS_21E317AA&REV_00
+        6749    unknown unknown
+        674A    V3900 AMD FirePro V3900 graphics
+        6750    1996 AMD Radeon HD 6570
+        6758    NI AMD Radeon HD 6670
+        6759    1996 AMD Radeon HD 6570
+        675D    HD7570 AMD Radeon HD7570
+        6760    3305M AMD/ATi Radeon 6760M
+        6761    AMD Radeon HD 6430M 6430M
+        6778    7470 AMD Radeon HD 7470
+        6779    AMD Radeon HD 6470m AMD Radeon HD 6470m
+        677B    Unknown Radeon HD 7450
+        6798    6798 AMD Radeon 7970 Series
+        6810    R9 200 Radeon R9 200 Series
+        6819    AMD Radeon HD 7800 Series PCI\VEN_1002&DEV_6819&SUBSYS_32601682&REV_00
+        6840    SUBSY AMD Radeon HD 7600M Series
+        6841    subsys 1789103c AMD Radeon HD 7500M/7600M
+        6898    EG CYPRESS XT ATI Radeon HD 5800 Series
+        6899    EG CYPRESS PRO ATI Radeon HD 5800 Series
+        689C    EG Cypress XT HEMLOCK ATI Radeon HD 5970 Series
+        68A0    EG BROADWAY XT ATI Mobility Radeon HD 5800 Series
+        68A1    EG BROADWAY PRO/LP ATI Mobility Radeon HD 5800 Series
+        68A8    AMD Radeon HD6870M (at least the one from Dell) AMD Radeon HD6870M (at least the one from Dell)
+        68B0    EG BROADWAY XT ATI Mobility Radeon HD 5800 Series
+        68B8    EG JUNIPER XT ATI Radeon HD 5700 Series
+        68BA    1482174B ATI Radeon HD 6700 Series graphics card
+        68BE    EG JUNIPER LE ATI Radeon HD 5700 Series
+        68C1    DEV_68C1&SUBSYS_144A103C&REV_00 ATI Mobility Radeon HD 5650M
+        68C8    RV830 FirePro v4800
+        68c9    RV830 FirePro 3D V3800
+        68D8    Redwood ATI Radeon HD 5670
+        68D9    RV830/Redwood HD 5570
+        68E0    HD 5470 ATI Mobility Radeon HD 5470
+        68E4    RV810 Ati Radeon HD 6370Mmobile
+        68f9    Cedar ATI Radeon HD 5450
+        700F    A3/U1 PCI to AGP Bridge
+        7010    RS200 PCI to AGP Bridge
+        7100    R520 ATI RADEON X1800 Series
+        7101    M58 ATI MOBILITY /ATI RADEON X1800 XT
+        7102    PCIE ATI MOBILITY /ATI RADEON X1800
+        7103    M58GL ATI MOBILITY FireGL V7200
+        7104    R520GL ATI FireGL V7200
+        7105    R520GL ATI FireGL V5300
+        7106    M58GL ATI MOBILITY FireGL V7100
+        7108    R520 ATI RADEON X1800 Series
+        7109    R520 ATI RADEON X1800 Series
+        710A    R520 ATI RADEON X1800 Series
+        710B    R520 ATI RADEON X1800 Series
+        710C    R520 ATI RADEON X1800 Series
+        710E    R520GL ATI FireGL V7300
+        710F    R520GL ATI FireGL V7350
+        7120    R520 ATI RADEON X1800 Series Secondary
+        7124    R520GL ATI FireGL V7200 Secondary
+        7125    R520GL ATI FireGL V5300 Secondary
+        7128    R520 ATI RADEON X1800 Series Secondary
+        7129    R520 ATI RADEON X1800 Series Secondary
+        712A    R520 ATI RADEON X1800 Series Secondary
+        712B    R520 ATI RADEON X1800 Series Secondary
+        712C    R520 ATI RADEON X1800 Series Secondary
+        712E    R520GL ATI FireGL V7300 Secondary
+        712F    R520GL ATI FireGL V7350 Secondary
+        7140    RV515 ATI RADEON X1600 Series
+        7142    RV515 ATI RADEON X1300/X1550 Series
+        7143    RV515 ATI RADEON X1300/ X1550 Series
+        7145    M54 ATI MOBILITY /ATI RADEON X1400
+        7146    RV505 ATI RADEON X1300 / X1550 Series
+        7147    RV515 ATI RADEON X1550 64-bit
+        7149    M52 ATI MOBILITY RADEON X1300
+        714A    M52 ATI MOBILITY /ATI RADEON X1300
+        714B    M52 ATI MOBILITY /ATI RADEON X1300
+        714C    M52 ATI MOBILITY /ATI RADEON X1300
+        714D    RV515 ATI RADEON X1300 Series
+        714E    RV515PCI ATI RADEON X1300 Series
+        7152    RV515GL ATI FireGL V3300
+        7153    RV515GL ATI FireGL V3350
+        715E    RV515 ATI RADEON X1300 Series
+        715F    RV515 ATI RADEON X1550 64-bit
+        7160    RV515 ATI RADEON X1600 Series Secondary
+        7162    RV515 ATI RADEON X1300/X1550 Series Secondary
+        7163    RV515 ATI RADEON X1550 Series Secondary
+        7166    RV515 ATI RADEON X1300 / X1550 Series Secondary
+        7167    RV515 ATI RADEON X1550 64-bit Secondary
+        716D    RV515 ATI RADEON X1300 Series Secondary
+        716E    RV515PCI ATI RADEON X1300 Series Secondary
+        7172    RV515GL ATI FireGL V3300 Secondary
+        7173    RV515GL ATI FireGL V3350 Secondary
+        717E    RV515 ATI RADEON X1300 Series Secondary
+        717F    RV515 ATI RADEON X1550 32-bit Secondary
+        7180    RV515 ATI RADEON X1300/X1550 Series =x1400
+        7181    RV515 ATI RADEON X1600 Series
+        7183    RV515 ATI RADEON X1300/X1550 Series
+        7186    M54 ATI MOBILITY /ATI RADEON X1450
+        7187    RV515 ATI RADEON X1300/X1550 Series
+        7188    M64 ATI MOBILITY /ATI RADEON X2300
+        718A    M54 ATI MOBILITY /ATI RADEON X2300
+        718B    M52 ATI MOBILITY /ATI RADEON X1350
+        718C    M52 ATI MOBILITY /ATI RADEON X1350
+        718D    M54 ATI MOBILITY /ATI RADEON X1450
+        718F    RV515PCI ATI RADEON X1300 Series
+        7193    RV515 ATI RADEON X1550 Series
+        7196    M62 ATI MOBILITY /ATI RADEON X1350
+        719B    RV515 ATI FireMV 2250
+        719F    RV515 ATI RADEON X1550 64-bit
+        71A0    RV515 ATI RADEON X1300/X1550 Series Secondary
+        71A1    RV515 ATI RADEON X1600 Series Secondary
+        71A3    RV515 ATI RADEON X1300/X1550 Series Secondary
+        71A7    RV515 ATI RADEON X1300/X1550 Series Secondary
+        71AF    RV515PCI ATI RADEON X1300 Series Secondary
+        71B3    RV515 ATI RADEON X1550 Series Secondary
+        71BB    RV515 ATI FireMV 2250 Secondary
+        71C0    RV530 ATI RADEON X1600 Series
+        71C1    RV535 ATI RADEON X1650 Series
+        71c2    RV530 ATI RADEON X1600 Series
+        71C3    RV535 ATI RADEON X1650 Series
+        71C4    M56GL ATI MOBILITY FireGL V5200
+        71c5    M56 ATI MOBILITY / ATI RADEON X1600
+        71C5 PCIE       M56 ATI MOBILITY /ATI RADEON X1600
+        71C6    RV530 ATI RADEON X1650 Series
+        71C7    RV535 ATI RADEON X1650 Series
+        71CD    RV530 ATI RADEON X1600 &#1057;&#1077;&#1088;&#1080;&#1080;
+        71ce    RV530 ATI RADEON X1600 Pro / ATI RADEON X1300 XT
+        71D2    RV530GL ATI FireGL V3400
+        71D4    M56GL ATI MOBILITY FireGL V5250
+        71D5    M56 ATI MOBILITY /ATI RADEON X1700
+        71D6    M56 ATI MOBILITY /ATI RADEON X1700 XT
+        71DA    RV530GL ATI FireGL V5200
+        71DE    M56 ATI MOBILITY /ATI RADEON X1700
+        71E0    RV530 ATI RADEON X1600 Series Secondary
+        71E1    RV535 ATI RADEON X1650 Series Secondary
+        71e2    RV530 ATI RADEON X1600 Series Secondary
+        71E3    RV535 ATI RADEON X1300 Series Secondary
+        71E6    RV530 ATI RADEON X1600 Series Secondary
+        71E7    RV535 ATI RADEON X1650 Series Secondary
+        71ED    RV530 ATI RADEON X1600 Series Secondary
+        71EE    RV530 ATI RADEON X1600 Pro / ATI RADEON X1300 XT Secondary
+        71F2    RV530GL ATI FireGL V3400 Secondary
+        71FA    RV530GL ATI FireGL V5200 Secondary
+        7205    1106 S3G Unichrome IGP KM400/KN400
+        7210    M71 ATI MOBILITY /ATI RADEON HD 2300
+        7211    M71 ATI MOBILITY /ATI RADEON HD 2300
+        7240    R580 ATI RADEON X1950 Series
+        7243    R580 ATI RADEON X1900 Series
+        7244    R580 ATI RADEON X1950 Series
+        7245    R580 ATI RADEON X1900 Series
+        7246    R580 ATI RADEON X1900 Series
+        7247    R580 ATI RADEON X1900 Series
+        7248    R580 ATI RADEON X1900 Series
+        7249    R580 ATI RADEON X1900 Series
+        724A    R580 ATI RADEON X1900 Series
+        724B    R580 ATI RADEON X1900 Series
+        724C    R580 ATI RADEON X1900 Series
+        724D    R580 ATI RADEON X1900 Series
+        724E    R580 ATI FireStream 2U
+        724F    R580 ATI RADEON X1900 Series
+        7260    R580 ATI RADEON X1950 Series Secondary
+        7263    R580 ATI RADEON X1900 Series Secondary
+        7264    R580 ATI RADEON X1950 Series Secondary
+        7265    R580 ATI RADEON X1900 Series Secondary
+        7266    R580 ATI RADEON X1900 Series Secondary
+        7267    R580 ATI RADEON X1900 Series Secondary
+        7268    R580 ATI RADEON X1900 Series Secondary
+        7269    R580 ATI RADEON X1900 Series Secondary
+        726A    R580 ATI RADEON X1900 Series Secondary
+        726B    R580 ATI RADEON X1900 Series Secondary
+        726C    R580 ATI RADEON X1900 Series Secondary
+        726D    R580 ATI RADEON X1900 Series Secondary
+        726E    R580 ATI FireStream 2U Secondary
+        726F    R580 ATI RADEON X1900 Series Secondary
+        7280    R580 ATI RADEON X1950 Series
+        7284    M58 ATI MOBILITY /ATI RADEON X1900
+        7286    R580 ATI RAEDON X1950 
+        7288    R580 ATI RADEON X1950 GT
+        7291    R560 ATI RADEON X1650 Series
+        7293    R580 ATI RADEON X1650 Series
+        72A0    R580 ATI RADEON X1950 Series Secondary
+        72A8    R580 ATI RADEON X1950 GT Secondary
+        72B1    R580 ATI RADEON X1650 Series Secondary
+        72B3    R580 ATI RADEON X1650 Series Secondary
+        7801    7801 SATA Controller
+        7807    7807 Standard OpenHCD USB Host Controller
+        7808    7808 Standard Enhanced PCI to USB Host Controller
+        7809    7809 Standard OpenHCD USB Host Controller
+        780B    780B SMBus
+        780D    780D HDMI Audio
+        780E    780E PCI standard ISA bridge
+        780F    780F PCI standard PCI-to-PCI bridge
+        7814    7814 AMD USB 3.0 Host Controller
+        7833    RS350 Radeon 9100 Pro
+        79      unknown, 2200 mhz Campo Valor Juego de instrucciones    x86, x86-64, MMX, 3DNow!, SSE, SSE2, SSE3
+        791     RS690M ATI Mobility Radeon x1200
+        7910    7910 PCI standard host CPU bridge
+        7912    7912 PCI standard PCI-to-PCI bridge
+        7914    7914 PCI standard PCI-to-PCI bridge
+        7915    7915 PCI standard PCI-to-PCI bridge
+        7916    7916 PCI standard PCI-to-PCI bridge
+        791a    791A HDMI Audio
+        791E    RS690 ATI RADEON X1200 Series
+        791F    RS690M ATI Radeon X1250
+        791Z    SUBSYS_826D1043 REV_00
+        7937    Samsung R25P ATI Technoligies Inc
+        793F    RS600 ATI RADEON Xpress 1200 Series
+        7941    RS690M ATI RADEON Xpress 1200 Series
+        7942    RS600M ATI RADEON Xpress 1250
+        796E    RS690 ATI RADEON 2100
+        8086    1050 PCI
+        9000    RV350 ATI Radeon 9600
+        9094    RV730 ATI Radeon HD 4600 Series
+        9400    R600 ATI Radeon HD 2900 XT
+        9401    R600 ATI RADEON HD 2900 XT
+        9402    R600 ATI RADEON HD 2900 XT
+        9403    R600 ATI RADEON HD 2900 PRO
+        9405    R600 ATI RADEON HD 2900 GT
+        940A    R600GL ATI FireGL V8650
+        940B    R600GL ATI FireGL V8600
+        940F    R600GL ATI FireGL V7600
+        9440    RV770 ATI Radeon HD 4870
+        9441    R700 ATI Radeon HD 4870 X2
+        9442    RV770 ATI Radeon HD 4800 Series
+        9443    R700 ATI Radeon HD 4850 X2
+        9444    RV770 ATI FirePro V8750 (FireGL)
+        9446    RV770 ATI FirePro V7770 (FireGL)
+        9447    R700 ATI FirePro V8700 Duo (FireGL)
+        944A    M98 ATI Mobility Radeon HD 4850
+        944B    M98 ATI Mobility Radeon HD 4850 X2
+        944C    RV770 ATI Radeon HD 4800 Series
+        944E    RV770 ATI Radeon HD 4700 Series
+        9450    RV770 AMD FireStream 9270
+        9452    RV770 AMD FireStream 9250
+        9456    RV770 ATI FirePro V8700 (FireGL)
+        945A    M98 ATI Mobility Radeon HD 4870
+        9460    RV790 ATI Radeon HD 4800 Series
+        9462    RV790 ATI Mobility Radeon HD 5650
+        9480    M96 ATI Mobility Radeon HD 4650
+        9487    RV730 ATI Radeon Graphics Processor
+        9488    M96 ATI Mobility Radeon HD 4670
+        948F    RV730 ATI Radeon Graphics Processor
+        9490    RV730 ATI Radeon HD 4600 Series
+        9491    M96 ATI Radeon E4600
+        9495    RV730 ATI RADEON HD4650
+        9498    RV730 ATI Radeon HD 4600
+        949C    RV730 ATI FirePro V7750 (FireGL)
+        949E    RV730 ATI FirePro V5700 (FireGL)
+        949F    RV730 ATI FirePro V3750 (FireGL)
+        94A0    M97 ATI Mobility Radeon HD 4830
+        94A1    M97 ATI Mobility Radeon HD 4860
+        94A3    M97 ATI FirePro M7740
+        94B1    RV740 ATI Radeon Graphics Processor
+        94B3    RV740 ATI Radeon HD 4770
+        94B4    RV740 ATI Radeon HD 4700 Series
+        94B5    AA38 ATI Radeon HD 4650
+        94C1    RV610-DT (Pro) ATI Radeon HD 2400 XT
+        94C3    RV610 ATI Radeon HD 2400 PRO PCI-E
+        94C4    RV610LE ATI Radeon HD 2400 PRO AGP
+        94C5    RV610 ATI RADEON HD 2400 LE
+        94C7    RV610 ATI RADEON HD 2350
+        94C8    M72 ATI MOBILITY /ATI RADEON HD 2400 XT
+        94C9    M72 ATI MOBILITY /ATI RADEON HD 2400
+        94CB    M72 ATI RADEON E2400
+        94CC    RV610 ATI RADEON HD 2400
+        9501    RV670 XT ATI Radeon HD 3870
+        9504    M76 ATI MOBILITY /ATI RADEON HD 3850
+        9505    RV630 ATI RADEON HD 3850
+        9506    M76 ATI MOBILITY /ATI RADEON HD 3850 X2
+        9507    RV670 ATI Radeon HD 3830
+        9508    M76 ATI MOBILITY /ATI RADEON HD 3870
+        9509    M76 ATI MOBILITY /ATI RADEON HD 3870 X2
+        950F    R680 ATI RADEON HD 3870 X2
+        9511    RV630GL ATI FireGL V7700
+        9513    R680 ATI Radeon HD 3850 X2
+        9515    RV670 AGP ATI Radeon HD 3850 AGP
+        9519    RV670 AMD FireStream 9170
+        9540    RV710 ATI Radeon HD 4550
+        9541    RV710 ATI Radeon Graphics Processor
+        954E    RV710 ATI Radeon Graphics Processor
+        954F    RV710 ATI Radeon HD 4350
+        9552    M92 ATI Mobility Radeon HD 4330 ..........
+        9553    M92 ATI Mobility Radeon HD 5145
+        9555    M93 ATI Mobility Radeon HD 4500 Series
+        9557    M93 ATI FirePro RG220
+        9581    M76M ATI Mobility Radeon HD 2600
+        9583    M76 ATI MOBILITY /ATI RADEON HD 2600 XT
+        9586    RV630 ATI RADEON HD 2600 XT AGP
+        9587    RV630 PRO ATI Radeon HD 2600 Pro AGP
+        9588    RV630 XT ATI Radeon HD 2600 XT
+        9589    &#1055;&#1056;&#1054; RV630 ATI Radeon HD 2600 Pro
+        958B    M76 ATI MOBILITY / ATI RADEON HD 2600 XT Gemini
+        958C    RV630GL ATI FireGL V5600
+        958D    RV630GL ATI FireGL V3600
+        958E    RV630 ATI RADEON HD 2600 LE
+        958F    M76 ATI Mobility FireGL Graphics Processor
+        9590    RV630 ATI RADEON HD 3650 Serieshttp://www.pcidatabase.com/update_device.php?__ec_i=ec.1307313611.e071ed73c
+        9591    M86-M ATI Mobility Radeon HD 3650
+        9593    M86 ATI Mobility Radeon HD 3670
+        9595    M86 ATI Mobility FireGL V5700
+        9596    RV630 ATI RADEON HD 3600 Series
+        9597    RV630 ATI RADEON HD 3600 Series
+        9598    RV630 ATI Radeon HD 3600 Series 
+        9599    RV630 ATI RADEON HD 3600 Series
+        959B    M86 ATI Mobility FireGL Graphics Processor
+        95C0    RV610 ATI RADEON HD 3470
+        95C2    M72 ATI MOBILITY /ATI RADEON HD 3430
+        95c4    M82-S ATI Mobility Radeon HD 3450
+        95C5    RV620 LE ATI Radeon HD 3450
+        95C6    RV620 ATI Radeon HD 3450
+        95C7    RV610 ATI RADEON HD 3430
+        95C9    RV620 ATI Radeon HD 3450
+        95CC    RV620 ATI FirePRO V3700
+        95CD    RV610 ATI FireMV 2450
+        95CE    RV610 ATI FireMV 2260
+        95CF    RV610 ATI FireMV 2260
+        9610    RS780 ATI Radeon HD 3200 Graphics
+        9611    RS780 ATI RADEON 3100 Graphics
+        9612    RS780M ATI RADEON HD 3200 Graphics
+        9613    RS780M ATI RADEON 3100 Graphics
+        9614    RS780 ATI RADEON HD 3300 Graphics
+        9615    RS780 AMD 780E
+        9616    RS780 AMD 760G
+        9644    A4-3420 AMD Radeon. HD 6410D
+        9647    AMD A6-3410MX APU With AMD Radeon HD 6520G &#1089;&#1090;&#1072;&#1085;&#1076;&#1072;&#1088;&#1090;&#1085;&#1099;&#1081; vga &#1075;&#1088;&#10
+        9648     9648 AMD Radeon(TM) HD 6480G
+        9649    HD 6480G AMD Radeon(TM) HD 6480G
+        970F    970F High Definition Audio Controller
+        9710    RS880 ATI Radeon HD 4200
+        9711    RS880 ATI Radeon 4100
+        9712    4250 ATI Mobility Radeon HD 4200 Series (ATI Mobility Radeon HD 4250)
+        9713    RS880MC ATI Mobility Radeon 4100
+        9715    RS880 ATI Radeon HD 4250 Graphics
+        9802    AMD E-350 AMD Radeon HD 6310 series
+        9803    2411E6FE Display driver http://support1.toshiba-tro.de/tedd-files2/0/display-20110404110958.zip
+        9804    AMD Radeon HD 6310 Graphics  AMD Radeon HD 6310 Gr AMD Radeon HD 6310 Graphics
+        9806    AMD Radeon HD 6320 E-450 APU
+        9807    unknow amd radeon hd 6290 graphic
+        9808    E2-1800 E-Series APU (E2-1800, maybe more)
+        9809    7310M ATI Radeon 7310M
+        9834    AMD Radeon HD 8210 PCI\VEN_1002&DEV_9834&SUBSYS_380217AA&REV_00
+        9851    3801 AMD Radeon(TM) R4 Graphics
+        9876    ATI GTC (GT-C2U2) ATI 3D Rage Pro AGP 2X
+        9902    9902 HDMI Audio
+        9998    9998 Radeon HD 8370D
+        9999    (0x9498 ATI Radeon HD 4600
+        999C    999C Radeon HD 8550D
+        AA01    Ati Function driver for high definition audio1 Ati Mobility Radeon HD HDMI Audio realtek
+        AA08    All with HDMI support High Definition Audio Device
+        AA10    677 HDMI Audio Support
+        AA20    RV630 ATI Radeon HD 3600 Series
+        AA28    3400 Radeon HD 3400 Series
+        AA58    AA58 High Definition Audio Controller
+        aa68     0x040300  0x00
+        AC12    Theater HD T507 (DVB-T) TV tuner/capture device
+        CAB0    A3/U1 S2K CPU to PCI Bridge
+        CAB1    A3/U1 Slot1 CPU to PCI Bridge
+        cab2    RS200 CPU to PCI Bridge
+        CBB2    RS200 CPU to PCI Bridge
+        o876    
+        7800    
+1003    ULSI
+        0201    0x0201 GUI Accelerator
+1004    VLSI Technology
+        0005    PCI\VEN_13F0 DEV_0200
+        0006    82C593 ISA Bridge
+        0007    82C594 Wildcat System Controller
+        0008    82C596/597 Wildcat ISA Bridge
+        0009    82C597-AFC2 
+        000C    82C541 
+        000D    82C543 
+        0100    dtdftdfz CPU to PCI Bridge for notebook
+        0101    82C532 Peripheral Controller
+        0102    82C534 PCI to PCI Bridge
+        0103    82C538 PCI to ISA Bridge
+        0104    82C535 Host Bridge
+        0105    82C147 IrDA Controller
+        0200    82C975 RISC GUI Accelerator
+        0280    82C925 RISC GUI Accelerator
+        0304    SAA7785 ThunderBird PCI Audio Accelerator
+        0305    SAA7785 ThunderBird joystick port
+        0306    SAA7785 ThunderBird 16650 UART
+        0307    KTX0208X Philips Seismic Edge 705
+        0308    1 Philips PSC705 GamePort Enumerator
+        0702    VAS96011 Golden Gate II
+1006    Reply Group
+        3044    n/a 1 OHCI Compliant IEEE 1394 Host Controller
+1007    Netframe Systems Inc.
+1008    Epson
+        9876    23 23
+100A    ..as Ltd. de Phoenix del .. de Tecnolog..
+        8235    VIA 82C3128 U87088R06
+100B    National Semiconductors
+        0001    DP83810 10/100 Ethernet MAC
+        0002    PC87415 PCI-IDE DMA Master Mode Interface Ctrlr
+        000E    PC87560 Legacy I/O Controller
+        000F    CS4210 IEEE 1394 OHCI Controller
+        0011    PC87560 PCI System I/O
+        0012    USB Controller
+        001B    LM4560 Advanced PCI Audio Accelerator
+        0020    DP83815 MacPhyter 10/100 Mb/s Ethernet MAC & PHY
+        0020h   DP83815 10/100 MacPhyter3v PCI Adapter
+        0021    PC82440 PCI to ISA Bridge
+        0022    DP83820/1 10/100/1000 Mb/s PCI Ethernet NIC
+        0028    Geode GX2 PCI Host Bridge
+        002A    CS5535 GeodeLink PCI South Bridge
+        002D    5535 Geode IDE Controller
+        002E    Castle () GEODE - GX3 Audio CS5535
+        002F    Geode USB Controller
+        0030    NSC Geode VGA Compatible Device
+        0500    SCx200 LPC Bridge and GPIO
+        0501    SCx200 SMI Status and ACPI
+        0502    SC1100/SCx200 IDE Controller
+        0503    SC1100/SCx200 XpressAUDIO
+        0504    SCx200 Video Processor
+        0505    SCx200 X-Bus Expansion Interface
+        0510    SC1100 LPC Bridge and GPIO
+        0511    SC1100 SMI Status and ACPI
+        0515    SC1100 X-Bus Expansion Interface
+        23      
+        D001    M2764AFI PCI-IDE Interface
+100C    Tseng Labs
+        3202    ET4000W32P-A GUI Accelerator
+        3205    ET4000W32P-B GUI Accelerator
+        3206    ET4000W32P-C GUI Accelerator
+        3207    54005443 GUI Accelerator
+        3208    ET6000 Graphics/Multimedia Engine
+        4702    ET6300 
+100D    AST Research
+100E    Weitek
+        0564    STPC Client Host Bridge
+        55CC    STPC Client South Bridge
+        9000    P9000 WeitekPower GUI Accelerator
+        9001    P9000 GUI Accelerator
+        9100    P9100 GUI Accelerator
+1010    Video Logic Ltd.
+1011    Digital Equipment Corporation
+        0001    DC21050 PCI-PCI Bridge
+        0002    DC21040 Tulip Ethernet Adapter
+        0004    DC21030 PCI Graphics Accelerator
+        0007    Zephyr NV-RAM
+        0008    KZPSA SCSI to SCSI Adapter
+        0009    DC21140 Fast Ethernet Ctrlr
+        000A    DC21230 Video Codec
+        000C    1011 6IfPpL  <a href    000D    TGA2 TGA2 PDXGB
+        000F    DEFPA FDDI
+        0014    DC21041 Tulip Plus Ethernet Adapter
+        0016    DGLPB ATM
+        0019    DC21142/3 Olicom RapidFire 2327 Fast Ethernet Adapter
+        0021    21052[-AB] PCI-PCI Bridge
+        0022    DC21150-AA PCI-PCI Bridge
+        0023    DC21150 PCI to PCI Bridge
+        0024    DC21151/2 PCI-PCI Bridge
+        0025    21153 PCI-PCI Bridge
+        0026    21154 PCI-PCI Bridge
+        0034    Modem56 CardBus
+        0045    DC21553 PCI to PCI Bridge
+        0046    21554 PCI-to-PCI Bridge
+        1011    DC21050 PCI-PCI Bridge
+        1065    DAC960 Mylex DAC1164P Disk Array Controller
+        2000    3X-KPCON-AA Fault Mgr (3.3v/5v Universal PCI)
+1012    Micronics Computers Inc.
+1013    Cirrus Logic
+        0038    FW82371EB pci
+        0040    CL-GD7555 Flat Panel GUI Accelerator
+        004C    CL-GD7556 64-bit Accelerated LCD/CRT Controller
+        00A0    CL-GD5440 GUI Accelerator
+        00A2    CL-GD5432 Alpine GUI Accelerator
+        00A4    CL-GD5434 Alpine GUI Accelerator
+        00A8    CL-GD5434 Alpine GUI Accelerator
+        00AC    CL-GD5426 Video card (i guess?)
+        00B8    CL-GD5446 64-bit VisualMedia Accelerator
+        00BC    CL-GD5480 64-bit SGRAM GUI accelerator
+        00D0    CL-GD5462 Laguna VisualMedia graphics accelerator
+        00D4    CL-GD5455 Laguna 3D VisualMedia Graphics Accel
+        00D5    CL-GD5464 Laguna BD
+        00D6    CL-GD5465 Laguna 3D VisualMedia Graphics Accel
+        00E8    CL-GD5436U 
+        1013    cs4630cm accelerator do audio do pci de sound fusion
+        1100    CL-PD6729 PCI-to-PC Card host adapter
+        1110    CL-PD6832 PCMCIA/CardBus Controller
+        1112    CL-PD6834 PCMCIA/CardBus Controller
+        1113    CL-PD6833 PCI-to-CardBus Host Adapter
+        1200    CL-GD7542 Nordic GUI Accelerator
+        1202    GD7543 Viking GUI Accelerator
+        1204    CL-GD7541 Nordic-lite VGA Cntrlr
+        4000    1085 Ambient CLM Data Fax Voice
+        4400    CL-CD4400 Communications Controller
+        6001    CS4610/4611 CrystalClear SoundFusion PCI Audio Accelerator
+        6003    CS4630-CM Crystal Sound Fusion a
+        6004    CS464 CrystalClear SoundFusion PCI Audio Accel
+        6005    CS4010 Crystal Soundfusion(tm) CS 40210
+        9876    cirrus logic crystal CS 4614 SoundFusion PCI Audio Accelerator
+1014    International Business Machines Corp.
+        0002    MCA Bridge MCA Bridge
+        0005    Alta Lite CPU Bridge
+        0007    Alta MP CPU Bridge
+        000A    Fire Coral ISA Bridge w/PnP
+        0017    CPU to PCI Bridge
+        0018    Auto LANStreamer TR Auto LANStreamer
+        001B    GXT-150P Graphics Adapter
+        001D    82G2675 scsi-2 fast pci adapter
+        0020    82351/2 MCA Bridge
+        0022    82351/2 PCI to PCI Bridge 
+        002D    Python 
+        002E    ServeRAID I/II/3x/4H Coppertime RAID SCSI Adapter
+        0036    Miami/PCI 32-bit LocalBus Bridge
+        0037    IBM27-82660 PowerPC to PCI Bridge and Memory Ctrlr
+        003A    CPU to PCI Bridge
+        003E    85H9533 IBM Token Ring PCI
+        0045    SSA Adapter
+        0046    MPIC Interrupt Controller
+        0047    PCI to PCI Bridge
+        0048    00003720 PCI to PCI Bridge
+        0049    Warhead SCSI Controller
+        004D    IBM 3780IDSP MPEG-2 Decoder
+        004E    ATM Controller
+        004F    ATM Controller
+        0050    ATM Controller
+        0053    85h9533 25 MBit ATM controller
+        0057    85g1897 MPEG PCI Bridge
+        005C    i82557B 10/100 PCI Ethernet Adapter
+        005D    05J3506 TCP/IP networking device
+        007C    ATM Controller
+        007D    3780IDSP MPEG-2 Decoder
+        0090    GXT-3000P 
+        0095    20H2999 PCI Docking Bridge
+        0096    Chukar chipset SCSI Controller
+        00A1    PowerNP NPr2.7 ATM support device
+        00A5    ATM Controller
+        00A6    ATM 155Mbps MM Controller
+        00B7    GXT2000 256-bit Graphics Rasterizer
+        00BE    ATM 622Mbps Controller
+        00CE    02li537 Adapter 2 Token Ring Card
+        00F9    CPC700 Memory Controller and PCI Bridge
+        00FC    CPC710 PCI-64 Bridge
+        0105    CPC710 PCI-32 Bridge
+        010F    0680 Remote Supervisor+Serial Port+Mouse/Keyb
+        011B    cbeh3w Raid controller
+        0142    Yotta Video Compositor Input
+        0144    Yotta Video Compositor Output
+        0153    
+        0156    405GP PLB to PCI Bridge
+        0170    RC1000 Rasterizer/IBM GT1000 Geometr
+        0188    x PCI Bridge
+        01a2    82801 Modem: Intel Corporation 82440MX AC'97 Modem Controller (prog-if 00 [Generic])
+        01A7    IBM 133 PCI-X Bridge R1.1
+        01BD    ServeRAID 4/5 Morpheus SCSI RAID Controller
+        01ef    440GP PLB to PCI-X Bridge
+        01ff    FC 4962 CCIN 4962 FRU 09P5023 10/100 Mbps Ethernet PCI Adapter II
+        0246    
+        027F    440GX Embedded PowerPC CPU
+        0289    8086 0890
+        028c    112 SCSI Storage Controller
+        0295    NECSCE 11508082 IBM SurePOS Riser Card Function 0
+        0297    NECSCE 11508082 IBM SurePOS Riser Card Function 1 (UARTs)
+        02A1      Calgary PCI-X Host Bridge
+        0302    b8331462 PCI-X Host Bridge
+        0308    1 IBM CalIOC2 (Calgary on PCI-E)
+        0339    n/a n/a
+        10e5    41U0441 / 41U0442 IBM 4764-001 PCI-X Cryptographic Coprocessor (1410e501)
+        FFFF    MPIC 2 Interrupt Controller
+        IBM37C0 Unknown IBM Netfinity Advanced System Management Processor
+        IBM37D0 n/a n/a
+1016    Fujitsu ICL Computers
+1017    Spea Software AG
+        5343    v7-mpeg modul SPEA 3D Accelerator
+1018    Unisys Systems
+        3330    544469821 5444469821
+1019    Elitegroup Computer System
+        1B10    sis-648D VIA chipset
+        9876    5.03.2600.2180 32bit Unicode Intel(R) Celeron(R) CPU 2.80GHz
+101A    NCR Corporation
+        0005    8156 100VG/AnyLAN Adapter
+        0009    Altera FLEX PCI-X dual port  
+101B    Vitesse Semiconductor
+101E    American Megatrends Inc.
+        9010    MegaRAID 428 Ultra Wide SCSI RAID Controller2
+        9030    EIDE Controller
+        9031    EIDE Controller
+        9032    IDE and SCSI Cntrlr
+        9033    I960 SCSI Controller
+        9040    amd sempron(tm)2200+ Multimedia card
+        9060    MegaRAID 434 Ultra GT RAID Controller
+        9063    MegaRAC 780 Remote Assistant
+        9095    9095 SGPIO/SES/IPMI Initiator
+101F    PictureTel Corp.
+1020    Hitachi Computer Electronics
+1021    Oki Electric Industry
+1022    Advanced Micro Devices
+        1100    Athlon 64 / Opteron HyperTransport Technology Configuration
+        1101    Athlon 64 / Opteron Address Map
+        1102    Athlon 64 / Opteron AMD Hammer - DRAM Controller 
+        1103    Athlon 64 / Opteron AMD Hammer - Miscellaneous Control 
+        1200    1200 PCI standard host CPU bridge
+        1201    1201 PCI standard host CPU bridge
+        1203    1203 PCI standard host CPU bridge
+        1204    1204 PCI standard host CPU bridge
+        1419    PCI\VEN_1022&DEV_1419&SUBSYS_14191022&REV_00 AMD Input/Outpu Memory Management Unit
+        1510    1510 PCI standard host CPU bridge
+        1513    1513 PCI standard PCI-to-PCI bridge
+        1514    1514 PCI standard PCI-to-PCI bridge
+        1515    1515 PCI standard PCI-to-PCI bridge
+        1700    1700 PCI standard host CPU bridge
+        1701    1701 PCI standard host CPU bridge
+        1702    1702 PCI standard host CPU bridge
+        1703    1703 PCI standard host CPU bridge
+        1704    1704 PCI standard host CPU bridge
+        1716    1716 PCI standard host CPU bridge
+        1718    1718 PCI standard host CPU bridge
+        1719    1719 PCI standard host CPU bridge
+        2000    Am79C970/1/2/3/5/6 PCnet LANCE PCI Ethernet Controller
+        2001    Am79C978 PCnet-Home Networking Ctrlr (1/10 Mbps)
+        2003    Am1772 Wireless LAN chipset SMC 2602W V3 http://www.smc.com/index.cfm?event=downloads.doSearchCriteria&loca
+        2020    Am53C974 SCSI Controller
+        2040    Am79C974 Ethernet Controller
+        2081    Unknown GeodeLX graphics adapter
+        2082    GX3 Geode GX3 AES Crypto Driver
+        208F    CS5536 GeodeLink PCI South Bridge
+        2093    CS5536 CS5536 Audio Controller
+        2094    CS5536 CS5536 OHCI USB Host Controller
+        2095    CS5536 CS5536 EHCI USB Host Controller
+        2096    Number: CS5536 CS5536 USB Device Controller
+        2097    CS5536 CS5536 USB OTG Controller
+        209A    CS5536 CS5536 IDE Controller
+        2433    690LC Chill Control Connector
+        3000    SC520 ELAN Microcontroller PCI Host Bridge
+        5e4b    RV410 Radeon X700 Pro
+        7004    AMD-751 CPU to PCI Bridge
+        7006    AMD-751 Processor-to-PCI Bridge / Memory Ctrlr
+        7007    AMD-751 AGP and PCI-to-PCI Bridge (1x/2x AGP)
+        700A    AMD-IGR4 AGP Host to PCI Bridge
+        700B    AMD-IGR4 AGP PCI to PCI Bridge
+        700C    AMD-762 CPU to PCI Bridge (SMP chipset)
+        700D    AMD-762 CPU to PCI Bridge (AGP 4x)
+        700E    AMD-761 North Bridge
+        700F    AMD-761 CPU to AGP Bridge  (AGP 4x)
+        7400    AMD-755 PCI to ISA Bridge
+        7401    AMD-755 Bus Master IDE Controller
+        7403    AMD-755 Power Management Controller
+        7404    AMD-755 PCI to USB Open Host Controller
+        7408    AMD-756 PCI-ISA Bridge
+        7409    AMD-756 EIDE Controller
+        740B    AMD-756 Power Management
+        740C    10 USB Open Host Controller
+        7410    AMD-766 PCI to ISA/LPC Bridge
+        7411    AMD-766 Enhanced IDE Controller
+        7412    AMD-766 USB Controller
+        7413    AMD-766 Power Management Controller
+        7414    AMD-766 USB OpenHCI Host Controller
+        7440    AMD-768 LPC Bridge
+        7441    AMD-768 EIDE Controller
+        7443    AMD-768 System Management
+        7445    AMD-768 AC97 Audio
+        7446    AMD-768 AC97 Modem
+        7448    AMD-768 PCI Bridge
+        7449    AMD-768 USB Controller
+        7450    AMD-8131 PCI-X Bridge
+        7451    AMD-8131 PCI-X IOAPIC
+        7454    AMD-8151 System Controller
+        7455    AMD-8151 AGP Bridge
+        7458    AMD-8132 PCI-X Bridge
+        7459    AMD-8132 PCI-X IOAPIC
+        7460    AMD-8111 PCI Bridge
+        7461    AMD-8111 USB 2.0 Controller
+        7462    AMD-8111 Ethernet Controller
+        7463    AMD-8111 USB Enhanced Host Controller
+        7464    AMD-8111 USB OpenHCI Host Controller
+        7468    AMD-8111 LPC Bridge
+        7469    AMD-8111 UltraATA/133 Controller
+        746A    AMD-8111 SMBus 2.0 Controller
+        746B    AMD-8111 System Management
+        746D    AMD-8111 (not sure but definitively not c-media cm  Audio Controller
+        746E    AMD-8111 AC'97 Modem
+        756B    AMD-8111 ACPI Controller
+        7801    amd_sata AMD SATA Controller
+        7801_   amd_sata AMD SATA Controller
+        7804    AMD SATA Controller AMD SATA Controller
+        7807    Standard OpenHCD USB Host Controller - Amd Usb Fil Standard OpenHCD USB Host Controller - Amd Usb Filter Driver
+        7808    Standard PCI-to-USB extended host controller  Standard PCI-to-USB extended host controller 
+        7809    7809 Standard OpenHCD USB Host Controller
+        780b    2128103C SM Bus controller
+        780D    780D High Definition Audio Controller
+        780E    780E PCI standard ISA bridge
+        780F    780F PCI standard PCI-to-PCI bridge
+        7812    amd_sata  AMD USB 3.0 Host Controller
+        7814    7814 FCH USB XHCI Controller
+        840     4u Used to blow up the motherboard.  Highly explosive.  Use at ur own risk
+        9601    9601 PCI standard host CPU bridge
+        9602    9602 PCI standard PCI-to-PCI bridge
+        9604    9604 PCI standard PCI-to-PCI bridge
+        9605    9605 PCI standard PCI-to-PCI bridge
+        9606    9609 PCI standard PCI-to-PCI bridge
+        9642    AMD-6370D AMD Radeon HD6370D
+1023    TRIDENT MICRO
+        0194    82C194 CardBus Controller
+        2000    4DWAVE-DX advanced PCI DirectSound accelerator
+        2001    4D WAVE DX SOUND ACCELERATOR PCI Audio
+        2100    Cyber-XP4 Video Accelerator
+        2200    Volari V3 Video adapter
+        8400    84001023 sausgauos
+        8420    51331071 Trident Cyber Blade i7 AGP (55)
+        8500    VT8361 Via Tech VT8361/VT8601 Graphics Controller
+        8520    Trident Video Accelerator CyberBlade i1 Windows xp
+        8620    CyberBlade-i1 trident
+        8820    Ai1 TRIDENT DISPLAY CONTROLER /CyberALADDiN-T Driver
+        9320    TGUI9320 32-bit GUI Accelerator
+        9350    TGUI9350 32-bit GUI Accelerator
+        9360    7tskbc Flat panel Cntrlr
+        9382    Cyber9382 
+        9383    Cyber9383 
+        9385    Cyber9385 
+        9386    Cyber9386 Video Accelerator
+        9388    Cyber9388 Video Accelerator
+        9397    Cyber9397 Video Accelerator 3D
+        939A    Cyber9397DVD Video Accelerator
+        9420    TGUI9420 DGi GUI Accelerator
+        9430    TGUI9430 GUI Accelerator
+        9440    TGUI9682 DGi GUI Acclerator
+        9460    TGUI9460 32-bit GUI Accelerator
+        9470    TGUI9470 
+        9520    ox16 Video Accelerator
+        9525    Cyber9525 Video Accelerator
+        9540    Cyber9540 Video Acclerator
+        9660    TGUI9660 GUI Accelerator
+        9680    TGUI9680 GUI Accelerator
+        9682    TGUI9680 Trident A CAB01
+        9683    TGUI9683 GUI Accelerator
+        9685    ProVIDIA 9685 2MB VGA
+        9750    3DImage 9750 PCI/AGP trident dgi
+        9753    TGUI9753 Video Accelerator
+        9754    TGUI9753 Wave Video Accelerator
+        9759    TGUI975? Image GUI Accelerator
+        9783    TGUI9783 
+        9785    TGUI9785 
+        9850    3D Image 9850 AGP 4mb
+        9880    Blade 3D 9880 gggggg
+        9910    00011178 CyberBlade XP
+        9930    CyberBlade XPm 
+        9960    9960 Trident Video Accelerator CyberBlade-1A31
+1025    Acer Incorporated
+        0028    AC97 Agere Systems soft modem chip
+        1435    M1435 USB\VID_0502&PID_3476&MI_01\6&207B7CA8&0&0001
+        1445    M1445 VL Bridge & EIDE
+        1449    M1449 ISA Bridge
+        1451    M1451 Pentium Chipset
+        1461    M1461 P54C Chipset
+        1489    M1489 
+        1511    M1511 
+        1512    M1512 
+        1513    M1513 
+        1521    M1521 CPU Bridge
+        1523    M1523 ISA Bridge
+        1531    M1531 North Bridge
+        1533    M1533 ISA South Bridge
+        1535    M1535 PCI South Bridge
+        1541    M1541 AGP PCI North Bridge Aladdin V/V+
+        1542    M1542 AGP+PCI North Bridge
+        1543    M1543C PCi South Bridge Aladdin IV+/V
+        1561    M1561 driver video
+        1621    M1621 PCI North Bridge Aladdin Pro II
+        1631    M1631 PCI North Bridge Aladdin Pro III
+        1641    M1641 PCI North Bridge Aladdin Pro IV
+        3141    M3141 GUI Accelerator
+        3143    M3143 GUI Accelerator
+        3145    M3145 GUI Accelerator
+        3147    M3147 GUI Accelerator
+        3149    M3149 GUI Accelerator
+        3151    M3151 GUI Accelerator
+        3307    M3307 MPEG-1 Decoder
+        3309    M3309 MPEG Decoder
+        5212    M4803 
+        5215    M5217 EIDE Controller
+        5217    M5217 I/O Controller
+        5219    M5219 I/O Controller
+        5225    M5225 EIDE Controller
+        5229    M522 EIDE Controlle
+        5235    1025 I/O Controller
+        5237    M5237 Intel(R) 5 Series/3400 Series Chipset Family 4 Port SATA AHCI Controller - 3B29
+        5239    
+        5240    EIDE Controller
+        5241    PCMCIA Bridge
+        5242    General Purpose Controller
+        5243    PCI to PCI Bridge
+        5244    Floppy Disk Controller
+        5247    M1541 PCI-PCI Bridge
+        5427    PCI to AGP Bridge
+        5451    M5451 PCI AC-Link Controller Audio Device
+        5453    M5453 M5453 AC-Link Controller Modem Device
+        7101    M7101 PCI PMU Power Management Controller
+1028    Dell Inc.
+        0001    PowerEdge 2 /Si Expandable RAID Controller (PERC) (SCSI)
+        0002    PowerEdge 3/Di Expandable RAID Controller
+        0003    PowerEdge 3/Si Expandable RAID Controller
+        0004    PowerEdge 3/Si Expandable RAID Controller
+        0005    PowerEdge 3/Di Expandable RAID Controller
+        0006    PowerEdge 3/Di Expandable RAID Controller
+        0007    270 Remote Assistant Card
+        0008    PowerEdge 3/Di RAC Virtual UART Port
+        000A    PowerEdge 3/Di Expandable RAID Controller
+        000C    53C885 23800 SCSI Adapter Embedded Systems Management Device 4
+        000D    ? LSI53C895 PCI to Ultra2 SCSI I/O Processor with LVD Link
+        000E    000E PERC 4/DI Raid Controller
+        0010    DRAC4 HJ866 - ESM4 &#1059;&#1076;&#1072;&#1083;&#1077;&#1085;&#1085;&#1099;&#1081; &#1044;&#1086;&#1089;&#
+        0011    DRAC4 Dell Remote Access Controller v4
+        0012    DRAC4-UART Dell RAC v4 Virtual UART
+        0013    PERC 4e/Si and PERC 4e/Di Expandable RAID Controller
+        0014    DRAC4-0 Dell Remote Access Controller subsystem
+        0015    PERC 5/i RAID Controller Integrated RAID controller
+        012c    915gm/gms,910gml Intel Gigabit controller
+        016d    82541GI Dell PRO/1000 MT Network Connection
+        0287    DELL PERC 320/DC Adaptec 2200S SCSI RAID controller
+        1000    FA82537EP A Intel 537 epg v.92 modem repackaged by dell
+        1050    0200 ethernet controller
+        1f0c    4050 PCI Simple Communication Controller
+        1foc    n4050 pci simple communication controller
+        2107    0115 HID Keyboard Device
+        3002    AR3011 Dell Wireless 1702 Bluetooth v3.0+HS
+        3582    ispiron 4700 video controller
+        675d    hd7570 amd radeon hd7570
+        6821    3 3
+        8184    Dell Wireless 5540 Dell Wireless 5540 HSPA Mini Card
+        9876    PowerEdge 3/Si Expandable RAID Controller
+102A    LSI Logic Headland Division
+        0000    HYDRA 4 port usb hub
+        0003    0x0000 USB\VID_0000&PID_0000\6&76F8B18&0&2
+        0010    ASPEN i486 Chipset
+        002A    6.1.7601.18328 4 port usb hub
+        102A    HYDRA P5 Chipset
+        9876    HYDRA P5 CHIPSET
+102B    Matrox Electronic Systems Ltd.
+        0010    MGA-I Impression?
+        0040    chip=0x2539102b Matrox P650 very new model (20080724)
+        051     MGA-2164W matrox
+        0518    MGA-PX2085 Atlas GUI Accelerator
+        0519    MGA-2064W Strorm GUI Accelerator
+        051A    mga-1164sg-a Hurricane/Cyclone 64-bit graphics chip
+        051B    MGA-2164W Matrox
+        051E    MGA-1164SG Chinook
+        051F    MGA-200B Mistral
+        0520    Matrox lnc MGA-G200B AGP
+        0521    Matrox lnc MGA-G200B 102B
+        0522    G200e Matrox G200e (ServerEngines) - English
+        0525    i440B Intel Pentium III
+        0527    Parhelia AGP 
+        0528    Parhelia Parhelia 128MB/256MB/PCI/HR256
+        0530    Matrox  G200eV Matrox G200eV
+        0534    ? G200eR
+        0540    M9138 M9138 LP PCIe x16
+        0D10    MGA-I Athena GUI accelerator
+        1000    MGA-G100 Twister
+        1001    MGA-G100 Twister AGP
+        1525    Fusion G450 AGP 
+        1527    Fusion Plus G800 AGP 
+        2007    Mistral GUI+3D Accelerator
+        2527    MGA-G550 AGP Chipset
+        2537    Parhelia-LX Parhelia Chipset AGP
+        2538    Matrox Millennium P650 LP PCIe 64 Matrox Millennium P650 LP PCIe 64
+        2539    G550/P650 Dual DVI Matrox Graphics Board dual DVI
+        4536    Meteor 2 STD/MC/Dig Video Capture Card
+        522     MGA-G200E Matrox G200e (ServerEngines)
+        525     G450 G45+
+        532     G200eW Matrox G200eW 8 MB DDR2 
+        6573    Shark 10/100 Multiport Switch NIC
+        80A0    RT.x10 Multimedia Device
+        9876    RT 2000 Multimedia device
+102C    Asiliant (Chips And Technologies)
+        00B8    64310 Wingine DGX - DRAM Graphics Accelerator
+        00C0    69000 AGP/PCI Flat Panel/CRT VGA Accelerator
+        00D0    65545 Flat panel/crt VGA Cntrlr
+        00D8    65540 Flat Panel/CRT VGA Controller
+        00DC    65548 GUI Accelerator
+        00E0    65550 LCD/CRT controller
+        00E4    65554 Flat Panel/LCD CRT GUI Accelerator
+        00E5    65555 VGA GUI Accelerator
+        00F0    68554 vga Controller
+        00F4    68554 graphic driver
+        00F5    68555 GUI Controller
+        01E0    65560 PCI Flat Panel/CRT VGA Accelerator
+        0C30    69030 AGP/PCI Flat Panel/CRT VGA Accelerator
+102D    Wyse Technology
+        50DC    3328 Audio
+102E    Olivetti Advanced Technology
+102F    Toshiba America
+        0009    r4x00 CPU Bridge
+        000A    TX3927 CPU Bridge?
+        0020    Meteor 155 ATM PCI Adapter
+        0030    TC35815CF PCI\VEN_8086
+        0031    TX4938 Integrated 10/100 Mbit Ethernet Controller
+        0100    8185 Realtek RTS5208 Card Reader
+        0105    TC86C001FG GOKU-S Bus Master IDE Controller
+        0106    TC86C001FG GOKU-S USB Host Controller
+        0107    TC86C001FG GOKU-S USB Device Controller
+        0108    TC86C001FG GOKU-S I2C Bus/SIO/GPIO Controller
+        0180    TX4927 MIPS Processor
+        0181    TX4925 MIPS RISC PCI Controller (PCIC)
+        0182    TX4937 MIPS RISC PCI Controller (PCIC)
+        01BA    SE1000 SpursEngine
+        0805    TC35815CF PCI\VEN_1179&DEV_0805&CC_0880
+        102F    ACPI\SMCFO30\4&69EE968&0 PCI\VEN_1179&DEV_0805&SUBSYS_00011179&REV_05\4&7562792&0&68F0
+1030    TMC Research
+1031    miro Computer Products AG
+        5601    MiroVIDEO DC20 I/O & JPEG
+        5607    2IVDC-PCX1 1250400 033893932 video in and out with motion jpeg compression and deco
+        5631    Media 3D 
+        6057    MiroVIDEO DC30D DC30D-601601-4.0
+1033    NEC Electronics
+        0001    upD98409 PCI to 486 like bus Bridge
+        0002    PCI to VL98 Bridge
+        0003    ATM Controller
+        0004    R4000 PCI bus Bridge
+        0005    pci 7432 PCI to 486 like peripheral bus Bridge
+        0006    GUI Accelerator
+        0007    unknown from Creative.com PCI to ux-bus Bridge
+        0008    GUI Accelerator (vga equivalent)
+        0009    graphic Cntrlr for 98
+        001A    Nile II 
+        001D    uPD98405 NEASCOT-S20 ATM Integrated SAR Ctrlr
+        0021    Vrc4373 Nile I
+        0029    PoverVR PCX1 3D Accelerator
+        002A    PoverVR 3D Accelerator
+        002f    NEC D72874GC 1394 Host Controller
+        0034    PCI\VEN_1033&DEV_0034&SUBSYS_00341033&REV_43 PCI\VEN_1033&DEV_0034&SUBSYS_00341033
+        0035    udp9210 Dual OHCI controllers plus Single EHCI controller
+        0036    uPD98409 NEASCOT-S40C ATM Light SAR Controller
+        003E    uPD66369 NAPCCARD CardBus Controller
+        0046    PoverVR PCX2 3D Accelerator
+        005A    Vrc5074 Nile 4
+        0063    uPD72862 Firewarden IEEE1394 OHCI Host Controller
+        0067    PowerVR Neon 250 PowerVR series II graphics processor
+        0074    NEC FMK 56 V90 56k Voice Modem
+        009B    Vrc5476 
+        00A6    
+        00BE    VR4122 64-bit CPU with Northbridge
+        00CD    uPD72870 IEEE1394 1-Chip OHCI Host Controller
+        00CE    uPD72871/2 IEEE1394 1-Chip OHCI Host Controller
+        00E0                    0x1033   USB 2.0 Host Controller
+        00E0    uPD720100A uPD720102GC USB 2.0 Host Controller
+        00E7    uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr
+        00F2    D72874GC IEEE1394+OHCI+1.1+3-port+PHY-Link+Ctrlr
+        0165    - AVerMedia A313 MiniCard Hybrid DVB-T
+        0194    0C0330 Renesas Electronics USB 3.0 Host Controller
+        0520    NEC D72874GC 1394 CARD
+        1033    0720101GJ NEC PCI to USB Open Host Controller
+        9876    uPD720100A uPD720102GC USB 2.0 Host Controller
+1034    Burndy Corporation
+1036    Future Domain
+        0000    TMC-18C30 Fast SCSI
+1037    Hitachi Micro Systems Inc
+1038    AMP Incorporated
+1039    Silicon Integrated Systems
+        &#65296;        
+        0       
+         7012   HDAUDIO\FUNC_01&VEN_&DEV_504514F1&SUBSYS_1631C106& PCI Audio Accelerator
+        0001    HPSiS760 Anthlon 64 cpu to PCI bridge
+        0002    520 Virtual PCI to PCI Bridge (AGP)
+        0003    SiS760 SiS AGP Controller / SiS Accelerated Graphics Port 
+        0005    0900 Pentium chipset
+        0006    SiS 85C501 PCI/ISA Cache Memory Controller (PCMC)
+        0008    SiS 85C503 PCI System I/O (PSIO)
+        0009    5595 SIS PMU device
+        0016    SiS740 SMBus ControllerP4kjc
+        0018    SiS950 vga
+        0160    SiS160 SiS160 811 Wireless LAN Adapter
+        0180    SiS180 SiS 180/181 RAID Controller 
+        0181    ? Raid Controller(?Mode Raid1)
+        0182    ? Raid Controller(?Mode Raid0+1)
+        0183    ?SIS965 ?SATA
+        0186    1039 0330
+        0190    SiS968, SiS965, SiS966, SiS965L, SiS966L SiS191 Gigabit LAN & SiS190 LAN
+        0191    SIS191 SIS191
+        0200    SiS5597/98 Onboard Graphics Controller
+        0204    SiS 6215 PCI1
+        0205    SiS 6205 PCI Graphics & Video Accelerator
+        0300    SiS330 GUI Accelerator+3D
+        0305    SiS305 2D/3D/Video/DVD Accelerator
+        0315    Geforce2 MX400 2D/3D Accelerator
+        0325    SiS6330 Silicon Integrated Systems (SiS)
+        0330    SiS330 Xabre 2D/3D Accelerator (AG400T8-D64)
+        0406    85C501 PCI/ISA Cache Memory Controller (PCMC)
+        0496    85C496 CPU to PCI & PCI to ISA Bridge
+        0530    SiS530 Host-to-PCI bridge
+        0540    SiS540 Host-to-PCI Bridge
+        0550    SiS550/1/2 North Bridge
+        0596    SiS596 Pentium PCI chipset with IDE
+        0597    SiS620 EIDE Controller (step C)
+        0601    SiS83C601 PCI EIDE Controller
+        0620    SiS620 Host-to-PCI Bridge
+        0630    SiS6330 Host-to-PCI Bridge
+        0635    SiS 635 Host-to-PCI Bridge
+        0640    SiS 640 Host-to-PCI Bridge
+        0645    SiS 645 Host-to-PCI Bridge
+        0646    SiS645DX Host-to-PCI Bridge
+        0648    SiS648MX Host-to-PCI Bridge
+        0649    sis649 Host-to-PCI Bridge
+        0650    SiS961 Host-to-PCI Bridge
+        0651    SiS651 Host-to-PCI Bridge
+        0655    SiS655 Host-to-PCI Bridge
+        0656    ??? CPU to PCI Bridge
+        0658    SiS R658 CPU to PCI Bridge
+        0659    SiS R659 CPU to PCI Bridge
+        0660    vt8237a Host-to-PCI Bridge
+        0661    SiS 661FX SiS 661FX/GX Chipset - Host-PCI Bridge
+        0662    ??? CPU to PCI Bridge
+        0663    ??? CPU to PCI Bridge
+        0730    SiS 730 Host-to-PCI Bridge
+        0735    SiS 735 Host-to-PCI Bridge
+        0740    SiS 074 LPC Bridge
+        0741    SIS741 CPU to PCI Bridge
+        0745    SiS745 Host-to-PCI Bridge
+        0746    SiS746 Host-to-PCI Bridge
+        0748    SiS748 CPU to PCI Bridge
+        0755    SiSM650? Host-to-PCI Bridge
+        0756    SiS755FX CPU to PCI Bridge
+        0760    SiS760 Athlon 64 CPU to PCI Bridge
+        0761    88e8056 Athlon 64 CPU to PCI Bridge
+        0762    ??? Athlon 64 CPU to PCI Bridge
+        0900    SiS 900 SiS 900 Fast Ethernet Adapter
+        0901    Device ID = 0900 SiS900 SiS900 10/100 Ethernet Adapter
+        0962    SiS962 LPC Bridge
+        0963    SiS963 PCI to ISA Bridge
+        0964    SiS964 SiS 964 MuTIOL Media I/O Bridge 
+        0999    sis950 pci\ven_1039&subsys_200b163&rev_a0\3&61aaa01\0&17
+        1039    SiS5597a SiS5597 SVGAa
+        1040    
+        10ec    961/2 bus controler
+        1182    ? Raid Controller(?Mode Raid5)
+        1183    SIS966/968  SATA IDE Controller
+        1184    SIS966(AHCI)&#12289;SIS968(RAID) Raid/AHCI Controller
+        1185    SIS968 AHCI Controller
+        1234    SiS5597a SiS5597 SVGAa
+        191     MTC ms9377c PCI /ven_1039
+        3602    SiS83C602 IDE Controller
+        4321    Video Controller Video Controller (VGA Compatible)
+        5107    SiS5107 Hot Docking Controller
+        5300    SiS540 AGP
+        5315    SiS530/1/2 GUI Accelerator
+        5401    SiS5401 486 PCI Chipset
+        5511    SiS5511/5512 PCI/ISA System Memory Controller
+        5513    All SIS SouthBridge SiS 5513 IDE UDMA Controller / SiS 85C513 IDE Controller
+        5517    SiS5517 CPU to PCI Bridge
+        5518    SiS5518 UDMA IDE Controller
+        5571    SiS5571 Memory/PCI bridge
+        5581    SiS 5581 p5 chipset
+        5582    SiS5582 PCI to ISA Bridge
+        5591    MTC ms9377c (SIS 741                       PCI\VEN_1039
+        5596    SiS661FX  VGA Controller
+        5597    SiS5597 Host to PCI bridge
+        5600    SiS600 Host-to-PCI Bridge
+        5630    SiS630 Host-to-PCI Bridge
+        5811    
+        6204    SiS6204 video decoder/mpeg interface
+        6205    SiS6215 PCI VGA Controller
+        6225    SiS 950 m2284dxs PCI Graphics & Video Accelerator
+        6236    SG3730il Graphics
+        6300    SiS630/730 GUI Accelerator+3D
+        6306    SiS530/620 Integrated 3D  SVGA Controller
+        6325    pc&#305;\VEN_1039&DEV_6325 sis-651dx
+        6326    0x1039 sis 6326 AGP
+        6330    SiS661FX/M661FX/760/741/M760/M741 GUI 2D/3D Accelerator
+        6331     04 USB Host Controller
+        6351    SIS M672 FX SiS IGP Graphics family SIS66x/SIS76x & SIS67x
+        6355    962 962lua
+        6787    SiS5597a Smart Link 56K Voice Modem (download from driverguide.com)
+        6972    
+        7001    SiS 7001 SiS 7001 PCI to USB Open Host Controller 
+        7002    SiS 7001 PCI to USB Open Host Controller USB 2.0 Enhanced Host Controller
+        7005    SiS551/2 Memory Stick Controller
+        7007    1039 OHCI Compliant FireWire Controller
+        7012    SiS 7012 SiS 7012 Audio Device / Realtek AC'97 Audio
+        7013            SiS5597a Smart Link 56K Voice Modem (download from driverguide.com)
+        7013    SiS7013 Smart Link 56K Voice Modem
+        7015    SiS550 dd Software Audio dd
+        7016    SiS191 10/100 Ethernet Adapter
+        7018    SiS7018 Onboard audio
+        7019    SiS550/1/2 Hardware Audio
+        7300    SiS7013 GUI Accelerator+3D
+        7502    649 Realtek HDA Audio Driver.
+        8139    2012 2012
+        96325   pc&#305;\ven_1039&dev_6325 sis 650 integrated gfx controller (IGP)
+        964     sis964 LPC BRIDGE
+        9876    sis6215 pci vga card for win95 & nt4 only
+        9989    SiS5597a Smart Link 56K Voice Modem (download from driverguide.com)
+        _7012   HDAUDIO\FUNC_01&VEN_&DEV_504514F1&SUBSYS_1631C106& PCI Audio Accelerator
+        5811    
+103A    Seiko Epson Corporation
+103B    Tatung Corp. Of America
+        103b    82801DB LAN Controller with 82562EM/EX PHY
+103C    Hewlett-Packard
+        0024    ? Standard Vista USB Keyboard
+        0180000a        0x00000000 HID Keyboard Device
+        0A01    HP2400 HP Scanjet 2400
+        1005    A4977A Visialize EG
+        1008    Donner GFX 001
+        100A    hpVisualizeFX Hewlett-Packard VisualizeFX Series Video
+        1028    ACPI/HPQ0004/3&b1bfb68&0 HP ProtectSmart Hard Drive Protection - HP 3D DriveGuard
+        1029    HPFC-5200B Tachyon XL2 Fibre Channel Adapter
+        102A    Tach TS Tachyon TS Fibre Channel Host Adapter
+        1030    J2585B DeskDirect 10/100VG LAN Adapter
+        1031    J2585B222 DeskDirect 10/100
+        1040    J2973A DeskDirect 10BaseT NIC
+        1041    J2585B DeskDirect 10/100VG NIC
+        1042    J2970A DeskDirect 10BaseT/2 NIC
+        1048    SAS 
+        1049    DIVA1 
+        104A    DIVA2 intel
+        104B    SP2 
+        104D    J3242A EL-10 Ethernet Adapter
+        1064    79C970 PCnet Ethernet Controller
+        10C1    PCI\VEN_10DE&DEV_0543&SUBSYS_30CF103C&REV_A2 NetServer Smart IRQ Router
+        10ED    TopTools HP Communications Port
+        1200    82557B 10/100 NIC
+        1219    NetServer PCI Hot-Plug Controller
+        121A    NetServer SMIC Controller
+        121B    NetServer Legacy COM Port Decoder
+        121C    NetServer PCI COM Port Decoder
+        1229    zx1 System Bus Adapter
+        122A    zx1 I/O Controller
+        122B    zx1 Local Bus Adapter
+        12FA    Broadcom BCM4306 Broadcom Wireless miniPCI in a HP laptop
+        1302    1302103C HP Management Shared Memory Device
+        137a    AR5007 Atheros AR5007
+        1411    HPOJ750 HP PSC 750
+        171d    HP Integrated Module with Bluetooth Wireless HP Integrated Module with Bluetooth Wireless
+        1F1D    USB\VID_03F0&PID_241D&REV_0002 3G Broadband device
+        201D    ? 3G Broadband device
+        231D    USB\VID_03F0&PID_0a01\6&23104BA&0&7 HP Integrated Module with Bluetooth Wireless Technology
+        241D    USB\VID_0000_PID_0000_0000\5&25243b3b&0&1 HP compaq nx6125
+        2910    E2910A PCI Bus Exerciser
+        292     E2924A PCI Host Interface Adapter
+        2920    Fast Host Interface
+        2924    QDS-BRCM1051 PCI Host Interface Adapter
+        2925    E2925A 32 bit PCI Bus Exerciser and Analyzer
+        2926    E2926A 64 bit PCI Bus Exerciser and Analyzer
+        2927    E2927a 64 Bit, 66/50MHz PCI Analyzer & Exerciser
+        294     qds brcm1051 pci hostinterface
+        2940    E2940A 64 bit, 66/50MHz CompactPCI Analyzer&Exerciser
+        311d    rev 001 ATHEROS AR3011 bluetooth 3.0+HS adapter
+        3206    unknown Adaptec Embedded Serial ATA HostRAID
+        3207    not sure not sure
+        3220    P600 P600 SmartArray Raid Controller
+        3230    Smart Array P400 Controller Smart Array P400 Controller
+        323A    Smart Array P410i Controller Smart Array P410i Controller
+        3302    3305103C Integrated Lights Out 2.0 Interfaz IPMI
+        3A1D    hs2340 HP hs2340 HSPA+ MobileBroadband
+        5461    unknown HP integrated Module with Bluetooth 2.0 Wireless support
+        6007    ACPI\VEN_HPQ&DEV_6007 HP Mobile Data Protection Sensor
+        9876    rev 001 ATHEROS AR3011 bluetooth 3.0+HS adapter
+103E    Solliday Engineering
+103F    Logic Modeling
+1041    Computrend
+1043    Asustek Computer Inc.
+        0675    p5g41c-mlx Crestline
+        1969    P5LD2 - EAYZ Attansic L1 Gigabit Ethernet 10/100/1000Base-T Adapter
+        5653    M5A78L-M LX V2 ATI Radeon 3000 Graphics (Microsoft Corporation - WDDM v1.1)
+        8103    NV31 NV31 [GeForce FX 5600 Ultra]
+        82c6    RTL8168 Gigabit Ethernet(NDIS 6.0)
+1044    Distributed Processing Tech
+        1012    Domino RAID Engine
+        800A    13D09B4F 802.11 bg WLAN
+        A400    2124A/9X SmartCache III/RAID SCSI Controller
+        A500    unknown PCI Bridge
+        A501    c03c I2O SmartRAID V Controller
+        A511    Raptor SmartRAID Controller
+1045    OPTi Inc.
+        0005    
+        A0F8    82C750 PCI USB Controller
+        C101    82C264 GUI Accelerator
+        C178    82C178 pci usb card 2- port
+        C556    82C556 Viper
+        C557    82C557 CPU Bridge (Viper)
+        C558    82C558 ISA Bridge w/PnP
+        C567    82C750 Vendetta chipset: host bridge
+        C568    82C750 Vendetta chipset: ISA bridge
+        C569    82C579 Pentium to PCI Bridge
+        C621    82C621 PCI IDE Controller (PIC)
+        C700    82C700 82C700 FireStar PCI to ISA Bridge
+        C701    82C701 FireStar mobile chipset: host bridge
+        C814    82C814 FireBridge II Docking Station Controller
+        C822    82C822 CPU to PCI & PCI to ISA PnP bridge
+        C824    82C824 FireFox 32-Bit PC Card Controller
+        C825    82C825 function 0 PCI-to-ISA Bridge
+        C832    82C832 CPU-to-PCI and PCI-to-ISA Bridge
+        C861    82C861 OPTi 82C861 PCI to USB Open Host Controller
+        C881    82C881 FireLink 1394 OHCI Link Controller
+        C895    82C895 
+        C931    82C931 ISA Sound & Game Port controller.
+        C935    82C935 MachOne integrated PCI audio processor
+        D568    82C825 PCI bus master IDE controller
+        D768    82C750 Ultra DMA IDE controller
+1046    IPC Corporation LTD
+        5600    03001426 00/4&1a671
+1047    Genoa Systems Corp.
+1048    ELSA GmbH
+        0253    0x0c92 ELSA GLADIAC 528
+        0C60    Elsa Gladiac MX NVidia Geforce 2 MX
+        0C71    Elsa Gladiac 721 NVidia GeForce3 Ti 200
+        1000    Quick Step 1000 ISDN Controller
+        3000    QuickStep 3000 
+        8901    ELSA GLoria XL
+1049    Fountain Technology
+104A    STMicroelectronics
+        0008    STG 2000X diamond
+        0009    STG 1764X 
+        0010    STG4000 PowerVR KYRO series 3 graphics processor
+        0123    V65204 SPEAr1300
+        0209    STPC Consmr/Indstrl North/South Bridges
+        020A    STPC Atlas/Elite North Bridge
+        0210    STPC Atlas ISA Bridge
+        021A    STPC Consmr-S/Elite ISA Bridge
+        021B    STPC Consumer-II ISA Bridge
+        0228    STPC Atlas IDE Controller
+        0230    STPC Atlas USB Controller
+        0500    ST70137 ADSL
+        0981    jmc260 10/100 Ethernet Adapter
+        1746    mp280 mp280
+        2774    STE10/100A PCI 10/100 Ethernet Controller
+        3520    MPEG-II Video Decoder
+        7108    STi7108 Advanced HD AVC decoder with 3D graphics acceleration
+        CC00    STA2X11 ConneXt I/O Hub multifunction device
+        CC01    STA2X11 ConneXt I/O Hub multifunction device
+        CC02    STA2X11 ConneXt I/O Hub multifunction device
+        CC03    STA2X11 ConneXt I/O Hub multifunction device
+        CC04    STA2X11 ConneXt I/O Hub multifunction device
+        CC05    STA2X11 ConneXt I/O Hub multifunction device
+        CC06    STA2X11 ConneXt I/O Hub multifunction device
+        CC07    STA2X11 ConneXt I/O Hub multifunction device
+        CC08    STA2X11 ConneXt I/O Hub multifunction device
+        CC09    STA2X11 ConneXt I/O Hub multifunction device
+        CC0A    STA2X11 ConneXt I/O Hub multifunction device
+        CC0B    STA2X11 ConneXt I/O Hub multifunction device
+        CC0C    STA2X11 ConneXt I/O Hub multifunction device
+        CC0D    STA2X11 ConneXt I/O Hub multifunction device
+        CC0E    STA2X11 ConneXt I/O Hub multifunction device
+        CC0F    STA2X11 ConneXt I/O Hub multifunction device
+        CC10    STA2X11 ConneXt I/O Hub multifunction device
+        CC11    STA2X11 ConneXt I/O Hub multifunction device
+        CC12    STA2X11 ConneXt I/O Hub multifunction device
+        CC13    STA2X11 ConneXt I/O Hub multifunction device
+        CC14    STA2X11 ConneXt I/O Hub multifunction device
+        CC15    STA2X11 ConneXt I/O Hub multifunction device
+        CC16    STA2X11 ConneXt I/O Hub multifunction device
+        CC17    STA2X11 ConneXt I/O Hub multifunction device
+        CD00    V65204 SPEAr1300
+        CD80    SPEAr1300 Root Complex of SPEAr1300
+        SMO8800 Unknown ST Microelectronics Free Fall Sensor
+        SMO8810 Unknown STMicroelectronics Freefall Sensor
+104B    Mylex / Buslogic
+        1040    BA81C15 BT958 SCSI Host Adaptor
+        8130    - Flashpoint LT
+104C    Texas Instruments
+         803B   0366107B Texas Instruments Card Reader
+        014e    4610,4515,4610fm device
+        0500    TNETE100A/110A/211 ThunderLAN 100 Mbit LAN Controller
+        0508    TI380PCI PCI interface for TI380 compressors
+        1000    TI PCI Eagle i/f AS 
+        104C    PCI\VEN_104C&DEV_803B&SUBSYS_FF021179&REV_00 PCI Simple Communications Controller
+        3B04    028000 otros dispositivos
+        3D04    TVP4010 Permedia
+        3D07    TVP4020 AGP Permedia 2
+        8000    TSB12LV21 LYNX IEEE1394 FireWire Host Controller
+        8009    TSB12LV22 OHCI-Lynx PCI IEEE 1394 Host Controller
+        8010    TSB12LV26 OHCI-Lynx IEEE 1394 Host Controller
+        8011    PCI4450 OHCI-Lynx IEEE 1394 Controller
+        8017    PCI4410 OHCI-Lynx IEEE 1394 Controller
+        8019    TSB12LV23 OHCI-Lynx PCI IEEE 1394 Host Controller
+        8020    TSB12LV26 OHCI Compliant FireWire Controller
+        8021    TSB43AB23 1394a-2000 OHCI PHY/Link Layer CONTROLLER
+        8023    TSB43AB21/A IEEE1394a-2000 OHCI PHY/Link-Layer Ctrlr
+        8024    TSB43AB23 1394a-2000 OHCI PHY/Link Layer Ctrl
+        8025    TSB82AA2 1394b OHCI-Lynx IEEE 1394 Host Controller
+        8026    TSB43AB21A 1394a-2000 OHCI PHY/Link Layer Ctrlr
+        8027    PCI4451 OHCI-Lynx IEEE 1394 Controller
+        8029    040803-2158 OHCI Compliant IEEE-1394 FireWire Controller 
+        802e    PCI7420 OHCI Compliant IEEE 1394 Host Controller
+        8031    8031 Generic CardBus Controller
+        8033    PCI0021 Integrated FlashMedia / Card Reader
+        8034    10981734 SDA Standard Compliant SD Host Controller
+        8035    N/A PCI GemCore based SmartCard controller
+        8036    PCI6515 Texas Instruments PCIxxx12 Cardbus Controller
+        8038    PCI\VEN_104C&DEV_8038&SUBSYS_01861028&REV_00\4&2FA Texas Instruments PCI GemCore based SmartCard Controller
+        8039    104C 104C
+        803a    PCIxx12 OHCI Compliant IEEE 1394 Host controller
+        803B    PCIxx12 Integrated FlashMed Texas Instruments Card Reader
+        803c    PCI0024 SDA Standard Compliant SD Host Controller
+        803D    0780 Texas Instruments PCI GemCore based SmartCard controller
+        8119    na iRDA Compatible Controller
+        8201    006B103C TI UltraMedia Firmware Loader Device
+        8204    4610, 4515, 4610FM, 7510 PCI 7510/4510 Cardbus Controller
+        8231    XIO2000A PCI-Express to PCI/PCI-X bridge
+        8232    1 Controladora de v.deo multimedia
+        8241    Texas Instruments USB 3.0 XHCI Host Controller Texas Instruments USB 3.0 XHCI Host Controller
+        8400    ACX100AGHK D-Link AirPlus DWL-520+, Uses a TI 802.11b 22 MBPS Chip
+        8671    bogus bogus
+        9065    TMX320C6412 Fixed Point Digital Signal Processor
+        9066    USR5410 U.S. Robotics 802.11g Wireless Turbo PC Card 
+        A001    TDC1570 64-bit PCI ATM SAR
+        A100    TDC1561 32-bit PCI ATM SAR
+        A102    TNETA1575 HyperSAR Plus w/PCI host & UTOPIA i/f
+        0XA106  TMS320C6205 Fixed Point Digital Signal Processor
+        A186    TMS320C6416T TI C6416T DSP
+        a828    PCI2050BPDV PCI-to-PCI Bridge
+        AC10    PCI1050 PC Card Controller
+        AC11    PCI1030/1053 PC Card Controller
+        AC12    PCI1131 PC card CardBus Controller
+        AC13    PCI9066 Texas Instruments........ PCIxx12 Integrated FlashMedia Controller
+        AC15    PCI-1131 CardBus Controller
+        AC16    PCI1250 PC Card CardBus Controller
+        AC17    PCI1220 CardBus Controller
+        AC18    PCI1260 PC card CardBus Controller
+        AC19    PCI1221 PC card CardBus Controller
+        AC1A    PCI1210 PC card CardBus Controller
+        AC1B    PCI1450 PC card CardBus Controller
+        AC1C    PCI1225 PC Card CardBus Controller
+        ac1e    PCI1211 PCI To PCMCIA  bridge
+        AC1F    PCI1251B PC card CardBus Controller
+        AC20    PCI2030 PCI to PCI Bridge
+        AC21    PCI2031 PCI to PCI Bridge
+        AC22    PCI2032 PCI Docking Bridge
+        AC23    PCI2250 PCI-to-PCI Bridge
+        AC28    PCI2050/2050I PCI-to-PCI Bridge
+        AC30    PCI1260 PC card CardBus Controller
+        AC40    PCI4450 PC card CardBus Controller
+        AC41    PCI4410 PC card CardBus Controller
+        AC42    PCI4451 PC card CardBus Controller
+        AC43    PCI4550 PC card CardBus Controller
+        AC44    PCI4510SDFSDFSD PC Card Controller SDFSDAFSADFSDAFSDAF
+        AC46    PCI4520 PCCard CardBus Controller
+        ac47    7510/4510 Cardbus
+        AC50    PCI1410 PC card cardBus Controller
+        AC51    PCI-1420 Texas Instruments 1420
+        AC52    PCI1451 PC card CardBus Controller
+        AC53    PCI1421 PC card CardBus Controller - 5-in-1 Media Card Reader
+        AC54    PCI-1510 PCCard CardBus Controller w/UltraMedia
+        AC55    PCI1520 PCCard CardBus Controller
+        AC56    PCI1510 PCCard CardBus Controller
+        AC57    PCI1530 PCCard CardBus Controller
+        AC58    PCI1515 PCCard CardBus Controller
+        AC59    PCI1620 PCCard CardBus Controller w/UltraMedia
+        AC5A    PCI1610 PCCard CardBus Controller w/UltraMedia
+        ac60     09050844 PCI2040 PCI to DSP Bridge
+        ac8e    PCI7420 Generic CardBus Controller 
+        AC8F    7420/7620 FlashMedia
+        B000    TMS320C645x Device ID: 0xB001 
+        B001    TMS320DM642 DSP with a C64x+ core and M/S PCI interface
+        FE00    tsb12lv26 FireWire Host Controller
+        FE03    12C01A FireWire Host Controller
+104D    Sony Corporation
+        011B    RT2571WF USB Ralink Wireless LAN
+        5001    SNY5001 Sony Firmware Extension Parser listed as ACPI&#92;SNY5001 in device manager.
+        6001    SNY6001 Sony Programmable I/O Control Device
+        8009    CXD1947 PCI bus 9
+        8039    CXD3222 OHCI i.LINK (IEEE 1394) PCI Host Ctrlr
+        8056    0x127a Rockwell HCF 56K Modem
+        8087    PCI\VEN_104D&DEV_8086 SONY MPEG ENCODER
+        808A    Qc pass Memory Stick Controller
+104E    Oak Technology
+        0017    OTI-64017 
+        0107    OTI107 Spitfire VGA Accelerator
+        0109    Video Adapter
+        0217    OTI-64217 
+        0317    OTI-64317 
+        0611    OTI-610 T9732
+        317     OTI107 Spitfire VGA Accelerator
+104F    Co-Time Computer Ltd.
+        104F    iatca8262 Multi I/O
+1050    Winbond Electronics Corp.
+         6692   W6692/92A/92CFyr6 PCI BusISDN S/T-Controllerry
+        0000    004005-34c8c8 Ethernet Controller (NE2000 compatible)
+        0001    W83769F PCI/IDE controller
+        0033    W89C33 Winbond W89C33 mPCI 802.11 Wireless LAN Adapter
+        0105    W82C105 Ethernet Adapter
+        0628    W83628F/629D PCI to ISA Bridge Set
+        0840    W89C840F 100/10Mbps Ethernet Controller
+        0940    w89c940f winbond pci ethernet
+        1050    W99200aF Video capture card mpeg-1
+        5A5A    W89C940F ELANC-PCI Twisted-pair Ether-LAN Ctrlr
+        6692    W6692CF PCI BusISDN S/T-Controller
+        8481    Unknown SD Host Controller
+        9921    W99200AF MPEG1 capture card
+        9922    W9922PF MPEG-1/2 Decoder
+        9960    W9960CF Video Codec
+        9961    W9961CF H.263/H.261 Video Codec
+        9970    W9970CF VGA controller
+        9971    W9971CF W9971CF
+        6692    
+1051    Anigma Corp.
+        0100    Motorola MC145575 
+1053    Young Micro Systems
+1054    Hitachi Ltd
+        0003    06A2 0003
+        0001    PCI Bridge
+        0002    pci bus PCI bus Cntrlr
+        0003    06A2 hts547575a9e384
+        3505    SH7751 SuperH (SH) 32-Bit RISC MCU/MPU Series
+1055    Standard Microsystems Corp.
+        0810    EFAR 486 host Bridge
+        0922    Pentium/p54c host Bridge
+        0926    I don.t know pentium 133 intel   everex setpnot mx ISA Bridge
+        9130    SLC90E66 Ultra ATA/66 IDE Controller
+        9460    SLC90E66 Victory66 PCI to ISA Bridge
+        9461    SLC90E66 Victory66 UDMA EIDE Controller
+        9462    SLC90E66 Victory66 USB Host Controller
+        9463    SLC90E66 Victory66 Power Management Controller
+        e420    LAN9420/LAN9420i PCI 10/100 Ethernet controller
+1056    ICL
+        2001f   Divio NW700LQ. 0243CDTAA. V90479. 1 Philips P89C51RD271BA. 1D041700A0. AeD0217G
+1057    Motorola
+        0*5600  52-6116-2A Motorola FM 56 PCI Speakerphone Modem
+        0001    MPC105 PCI Bridge / Memory Controller (PCIB/MC)
+        0002    MPC106 PCI Bridge/Memory Controller (PCIB/MC)
+        0003    MPC8240 Integrated Processor
+        0004    MPC107 PCI Bridge/Memory Controller for PPC
+        0006    MPC8245 Integrated Processor
+        0100    MC145575 HCF-PCI
+        0431    KTI829c 100VG Ethernet Controller
+        1801    DSP56301 24-bit Digital Signal Processor
+        1802    DSP56305 24-Bit Digital Signal Processor
+        18C0    MPC8265A/66 PowerQUICC II PCI Bridge
+        3052    0644dfea15 MotorolaSM56Modem_PCI device
+        3055    SM56 Motorola SM56 Data Fax Modem 
+        3057    HDAUDIO\FUNC_02om&VEN_1057&DEV_3057&SUBSYS_0001000 Modem Device on High Definition Audio Bus
+        3410    DSP56361 Digital Signal Processor
+        3421    56IVMR/Phoenix 56ISM Modem
+        4801    Raven PowerPC Chipset
+        4802    Falcon memory control chipset
+        4803    Hawk 
+        4806    CPX8216 
+        4809    CPX8216T HotSwap Controller
+        5600    WDM MOT8888 SM 56 PCI Speakerphone/Data,Fax  Modem
+        5602    SM56 PCI Modem
+        5608    52-6116-2A 21-864-4 OR 62802-51 QZ0024 M5T90-000 Motorola SM56 Speakerphone Modem
+        5803    MPC5200 32-Bit Embedded PowerPC Processor
+        6400    MPC190 Security Co-Processor
+        9876    1543 3052
+1058    Electronics & Telecommunication Res
+1059    Kontron Canada
+105A    Promise Technology
+        0262    Promise Technology Ultra66/FastTrak66
+        0D30    PDC20265/R MBUltra100/MBFastTrack100 Lite
+        0D38    PDC20263 FastTrak66 Lite EIDE Controller
+        105A    DC5300 EIDE Controller
+        1275    PDC20275 MBUltra133
+        1960    ? SuperTrak 66/100 RAID
+        1962    ? SuperTrak SX 6000
+        3318    PDC20318 SATA150 TX4
+        3319    PDC20319 FastTrak S150 TX4
+        3371    PDC20371? FastTrak S150 TX2+
+        3373    PDC20378 FastTrak 378/SATA 378 RAID Controller
+        3375    PDC20375 SATA150 TX2+
+        3376    PDC20376 FastTrak 376 Controller
+        3515    PDC40719 FastTrak TX43xx
+        3519    PDC40519 FastTrak TX42xx
+        3570    PDC20771 FastTrak TX2300 SATA300 Controller
+        3571    PDC20571 Fasttrack TX2200
+        3574    PDC20579 SATAII 150 579
+        3d17    PDC40718-GP SATA 300 TX4 Controller
+        3D18    PDC20518/40518 SATAII 150TX2+/SATAII150 TX4
+        3D73    PDC40775 SATAII 300 TX2+
+        3F19    scsi FastTrak TX2650/4650/4652
+        3F20    PDC42819 FastTrak TX2650(3F21)/4650(3F22)/PDC42819(3716)
+        4302    ? SuperTrak EX 43X0
+        4303    ? SuperTrak EX 4350
+        4D30    PDC20267 FastTrack100 on Intel MB SE7500CW2
+        4D33    PDC20246 FastTrak/Ultra33 ATA RAID controller
+        4D38    PDC20262 Ultra66/FastTrak66
+        4D68    PDC20268/R Ultra100TX2/FastTrak100TX/LP
+        4D69    PDC20269 Ultra133TX2
+        5275    PDC20276 MBUltra133/MBFastTrak133
+        5300    DC5300 EIDE Controller
+        6268    PDC20270 FastTrak100 TX2/TX4/LP
+        6269    PDC20271 FastTrak TX2000 EIDE controller
+        6300    ? FastTrak SX 8300
+        6301    ? FastTrak SX8300-1
+        6302    6302 FastTrak SX 4300
+        6303    ? FastTrak SX 4
+        6304    ? FastTrak SX8300-2
+        6305    ? FastTrak SX8300-3
+        6306    ? FastTrak SX 4300-2
+        6307    ? FastTrak SX 4300-3
+        6621    PDC 20621(?) FastTrak SX4000
+        6622    PDC 20622 (?) FastTrak S150SX4
+        6629    PDC20619 FastTrak TX4000
+        7250    7250 Vitesse 7250 SAS RAID
+        7275    PDC 20277 SBUltra133/SBFastTrak 133 Lite
+        8000    ? SATAII150 SX8
+        8002    ? SATAII150 SX8
+        8003    PDC 20621 FastTrak SX4000
+        8004    ? SATAII150 SX8
+        8006    ? SATAII150 SX8
+        8350    ? SuperTrak EX8350/16350/8300/16300
+        8650    ? SuperTrak EX SAS RAID
+        C350    ? SuperTrak EX 123X0
+        E350    ? SuperTrak EX 243X0
+105B    Mobham chip
+105C    Wipro Infotech Limited
+105D    Number Nine Visual Technology
+        2309    Imagine 128 GUI Accelerator
+        2339    I128s2 Imagine 128 Series 2
+        493D    T2R Revolution 3D
+        5348    Revolution IV Revolution IV
+105E    Vtech Engineering Canada Ltd.
+105F    Infotronic America Inc.
+1060    United Microelectronics
+        0001    UM82C881 486 Chipset
+        0002    UM82C886 ISA Bridge
+        0101    UM8673F EIDE Controller
+        0881    UM8881 HB4 486 PCI Chipset
+        0886    UM8886F ISA Bridge
+        0891    UM82C891 Pentium CPU to PCI bridge
+        1001    UM886A IDE Cntrlr (dual function)
+        673A    UM8886BF EIDE Controller
+        673B    EIDE Master/DMA
+        8710    UM8710 VGA Cntrlr
+        8821    21611a3b CPU/PCI Bridge
+        8822    PCI/ISA Bridge
+        8851    Pentium CPU/PCI Bridge
+        8852    LG-772 Pentium CPU/ISA Bridge
+        886A    UM8886A ISA Bridge with EIDE
+        8881    UM8881F HB4 486 PCI Chipset
+        8886    UM8886 ISA Bridge (w/o IDE support)
+        888A    UM8886A 
+        8891    UM8891 586 Chipset
+        9017    UM9017F Ethernet
+        9018    UM9018 Ethernet
+        9026    UM9026 Fast Ethernet
+        E881    UM8881 486 Chipset
+        E886    UM8886N ISA Bridge w/EIDE
+        E88A    UM8886N PCI / ISA Bridge
+        E891    UM8891N um8891n
+1061    8x8 Inc.
+        0001    AGX013/016 GUI Accelerator
+        0002    IIT3104 MPEG Decoder
+1062    Maspar Computer Corp.
+1063    Ocean Office Automation
+1064    Alcatel Cit
+1065    Texas Microsystems
+        8139    nic Realtek 8139C Network Card
+1066    Picopower Technology
+        0000    PT80C826 VL Bridge
+        0001    PT86C521 Vesuvius V1-LS System Controller
+        0002    PT86C523 Vesuvius V3-LS ISA Bridge
+        0003    PT80C524 Nile PCI to PCI Bridge
+        0004    PT80C525 Nile-II PCI to PCI Bridge
+        0005    PCI\en_14E&DEV4318_REV|02 System Controller
+        8002    PT86C523 ISA Bridge
+1067    Mitsubishi Electronics
+        1002    G500 VolumePro Volume Rendering Accelerator
+1068    Diversified Technology
+106A    Aten Research Inc.
+106B    Apple Inc.
+        0001    Bandit PowerPC Host-PCI Bridge
+        0002    Grand Central I/O Controller
+        0003    Control Video 
+        0004    PlanB Video-in
+        0007    OHare I/O Controller
+        0009    BCM5703X BCM5703X
+        000C    
+        000E    Hydra Mac I/O Controller
+        0010    Heathrow Mac I/O Controller
+        0017    Paddington Mac I/O Controller
+        0018    UniNorth FireWire Controller
+        001F    UniNorth Host-PCI bridge
+        0020    UniNorth AGP interface
+        0026    Pangea USB Interface
+        0027    Pangea AGP interface
+        002D    UniNorth 1.5 AGP Bridge
+        002E    UniNorth 1.5 PCI Bridge
+        002F    UniNorth 1.5 Internal PCI
+        0030    UniNorth/Pangea FireWire Controller
+        003B    Intrepid Integrated ATA Controller
+        004f    Shasta Mac I/O controler
+        0050    Shasta IDE controler
+        0051    Shasta Sungem ethernet controler
+        0052    Shasta Firewire controler
+        0053    Shasta PCI Bridge
+        0054    Shasta PCI Bridge
+        0055    Shasta PCI Bridge
+        0058    U3L AGP Bridge
+        008A    Apple RAID Controller Mac Pro RAID Card
+        008C    BCM4321 802.11a/b/g/n AirPort Extreme
+106C    Hyundai Electronics America
+        8801    Dual Pentium ISA/PCI Motherboard
+        8802    P54C Tr8 PowerPC ISA/PCI Motherboard
+        8803    Dual Window Graphics Accelerator
+        8804    ht019a PCI LAN Controller
+        8805    00b 100-BaseT LAN Controller
+106D    Sequent Computer Systems
+106E    DFI Inc.
+        4362    88E8053 Yukon PCI-E Gigabit Ethernet Controller (copper)
+106F    City Gate Development LTD
+1070    Daewoo Telecom Ltd.
+1071    Mitac
+1072    GIT Co. Ltd.
+1073    Yamaha Corporation
+        0001    3D graphics Cntrlr
+        0002    YGV615 RPA3 3D-Graphics Controller
+        0003    00011179 
+        0004    YMF754B DS-1S Audio PCI Audio Controller
+        0005    DS1 DS1 Audio
+        0006    DS1 DS1 Audio
+        0008    DS1 DS1 Audio
+        000A    YMF740 DS-1L PCI Audio Controller
+        000C    YMF740C DS-1L PCI audio controller
+        000D    YMF724F YamahaDS1 native audio 
+        0010    YMF744B-V DS-1 PCI audio controller
+        0012    YMF754B DS-1E PCI Audio Controller
+        0020    744 DS-1 Audio
+        1000    SW1000XG Sound system
+        2000    DS2416 Digital Mixing Card
+        9876    ymf724b-v9941 yamaha
+1074    Nexgen Microsystems
+        4E78    82C500/1 Nx586 Chipset
+1075    Advanced Integration Research
+1077    QLogic Corporation
+        1016    ISP10160 Single Channel Ultra3 SCSI Processor
+        1020    ISP093a/2460 Fast-wide SCSI - Sparc PCI
+        1022    ISP1022A Fast-wide SCSI
+        1080    ISP1080 SCSI Host Adapter
+        1216    ISP12160 Dual Channel Ultra3 SCSI Processor
+        1240    ISP1240 SCSI Host Adapter
+        1280    ISP1280 SCSI Host Adapter
+        2020    ISP2020A Fast!SCSI Basic Adapter
+        2100    ISP2100 64-bit Fibre Channel Adapter
+        2200    ISP2200 PCI Fibre Channel Adapter
+        2300    ISP 2300 64-bit PCI FC-AL Adapter
+        2312    ISP 2312 Fibre Channel Adapter
+        2422    ISP2422 QLogic PCI to Fibre Channel Host Adapter for QLA2460
+        2432    ISP2432 4Gb PCI Single/Dual Fibre Channel HBA
+        2532    ISP2532 8Gb PCIe x8 Single/Dual Fibre Channel HBA
+        3010    n/a n/a
+        3032    ISP4032 QLOGIC Dual Port 1GBPS PCI-E HBA
+        4000    
+        4010    
+        6312    SP202 Qlogic FC-HBA QLA200
+        6422    EP2422 4-Gbps Fibre Channel to PCI-X 2.0 266MHz controller for Embedded Applications
+        6432    EP2432 4-Gbps Fibre Channel to PCIe controller for Embedded Applications
+        8000    8142 QLE8142 QLogic PCI Express to 10 GbE Dual Channel CNA
+        8001    8142 QLE8142 QLogic PCI Express to 10 GbE Dual Channel CNA (FCoE)
+        8020    8242 QLogic Dual Port 10 Gigabit Ethernet CNA
+        8021    8242 QLogic [FCoE] Adapter
+        8022    ISP8242 QLE8142 QLogic PCI Express to 10 GbE Dual Channel CNA (iSCSI)
+1078    Cyrix Corporation
+        0000    Cx5520 ISA Bridge
+        0001    MediaGXm Cyrix Integrated CPU
+        0002    Cx5520 ISA Bridge
+        0100    Cx5530 ISA bridge
+        0101    Cx5530 SMI status and ACPI timer
+        0102    Cx5530 IDE Controller
+        0103    Cx5530 XpressAUDIO
+        0104    Cx5530 Video Controller
+        0400    ZFMicro CPU to PCI Bridge
+        0401    ZFMicro Power Management Controller
+        0402    ZFMicro IDE Controller
+        0403    ZFMicro Expansion Bus
+1079    I-Bus
+        0d01    
+        10decb79        zdvzdv zdzvz
+107A    Networth controls
+107B    Gateway 2000
+107C    Goldstar Co. Ltd.
+107D    Leadtek Research
+        0000    P86C850 Graphic GLU-Logic
+107E    Testernec
+        0001    FLIPPER FRED Local Bus I/F to PCI Peripheral
+        0002    100 vg anylan Cntrlr
+        0004    5526 Fibre Channel Host Adapter
+        0005    x526 Fibre Channel Host Adapter
+        0008    4575/5525/5575/6575 (i)chipSAR+ 155 MBit ATM controller
+        9003    5535-4P-BRI-ST 
+        9007    5535-4P-BRI-U 
+        9008    5535-1P-SR 
+        900C    5535-1P-SR-ST 
+        900E    5535-1P-SR-U 
+        9011    5535-1P-PRI 
+        9013    5535-2P-PRI 
+        9023    5535-4P-BRI-ST 
+        9027    5536-4P-BRI-U 
+        9031    5535-1P-PRI 
+        9033    5536-2P-PRI Adapter
+        9060    6535 CompactPCI T1/E1/J1Communications Ctrlr
+        9070    4538 PMC T1/E1/J1 Communications Controller
+        9080    4532-002/005 PMC ATM Over OC-3/STM-1 Comm Controller
+        9081    4532-001/004 PMC ATM Over OC-3/STM-1 Comm Controller
+        9082    4532-000/003 PMC ATM Over OC-3/STM-1 Comm Controller
+        9090    107 PMC ATM Over T3/E3 Communications Ctrlr
+        90A0    4539 PMC Quad T1/E1/J1 Communications Ctrlr
+107F    Data Technology Corporation
+        0802    mb87j3560 pinacale capture card
+        0803    EIDE Bus Master Controller
+        0806    EIDE Controller
+        2015    EIDE Controller
+1080    Cypress Semiconductor
+        0600    82C596/9 CPU to PCI & PCI to ISA Bridge
+        C691    Cypress CY7c68001 AN2131QC 0230
+        C693    82C693 PCI to ISA Bridge
+1081    Radius Inc.
+        0D47    2330 Radius PCI to NuBUS Bridge
+1082    EFA Corporation Of America
+1083    Forex Computer Corporation
+        0001    FR710 PCI Enhanced IDE Adapter
+        0613    PCI
+1084    Parador
+1085    Tulip Computers Int'l BV
+        0001    UsbDgn Datalaster Interface for OBD automotive
+1086    J. Bond Computer Systems
+1087    Cache Computer
+        9200    
+1088    Microcomputer Systems (M) Son
+1089    Data General Corporation
+        5555    3059 3249
+108A    SBS  Operations
+        0001    Model 617 PCI-VME Bus Adapter
+        0003    Model 616 PCI to VME Bridge
+        0010    Model 618 VME Bridge
+        0040    dataBLIZZARD 
+        3000    Model 2106 VME Bridge
+108C    Oakleigh Systems Inc.
+108D    Olicom
+        0001    OC-3136/37 Token-Ring 16/4 PCI Adapter
+        0002    OC-3139f Fastload 16/4 PCI/III Token Ring Adapter
+        0004    OC-3139/40 RapidFire Token Ring 16/4 Adapter
+        0005    OC-3250 GoCard Token Ring 16/4 Adapter
+        0006    OC-3530 RapidFire Token Ring 100 Adapter
+        0007    OC-3141 RapidFire Token Ring 16/4 Adapter
+        0008    OC-3540 RapidFire HSTR 100/16/4 Adapter
+        000A    OC-3150 RapidFire Token-Ring 16/4 PCI Adapter
+        0011    OC-2805 Ethernet Controller
+        0012    OC-2325 Ethernet PCI/II 10/100 Controller
+        0013    OC-2183/85 PCI/II Ethernet Controller
+        0014    OC-2326 Ethernet PCI/II 10/100 Controller
+        0019    PCI/VEN_8086&DEV_1039&SUBSYS_02671014&REV_81\4&252 10/100 Ethernet Controller
+        0021    OC-6151/52 155 Mbit ATM Adapter
+        0022    ATM Adapter
+108E    Sun Microsystems
+        0001    SPARC EBUS 
+        1000    PCIO PCI Input/Output Controller
+        1001    PCIO Happy Meal Ethernet
+        1100    RIO EBUS 
+        1101    RIO GEM 
+        1102    RIO 1394 
+        1103    RIO USB 
+        2BAD    GEM Sun Gigabit Ethernet Card
+        5000    SME2411 UltraSPARC-IIi Advanced PCI Bridge
+        5043    SunPCI Co-processor
+        7063    SunPCi PCI card with Intel or AMD processor
+        8000    STP2223BGA UPA to PCI Interface (UPA)
+        8001    Schizo PCI Bus Module
+        A000    UltraSPARC IIi Sabre
+        A001    UltraSPARC IIe Hummingbird
+        abba    CE (Cassini Ethernet) 10/100/1000 Ethernet adapter
+108F    Systemsoft Corporation
+1090    Encore Computer Corporation
+1091    Intergraph Corporation
+        0020    1091 3D Graphics Processor
+        0021    3D graphics processor w/texturing
+        0040    3D graphics frame buffer
+        0041    3D graphics frame buffer
+        0060    Proprietary bus Bridge
+        00E4    Powerstorm 4D50T 
+        0720    Motion JPEG Codec
+1092    Diamond Computer Systems
+        00A0    SpeedStar Pro SE GUI Accelerator
+        00A8    SpeedStar 64 GUI Accelerator
+        0550    Viper V550 
+        08D4    Supra 2260 WinModem
+        094C    SupraExpress 56i Pro SupraExpress 56i Pro
+        09C8    SUP2761 SupraExpress 56i Pro VCC
+        1002    R6793-12 RS56-pci
+        1092    Viper V330 2710a
+        6120    Maximum DVD
+        8810    Stealth SE GUI Accelerator
+        8811    Stealth 64/SE GUI Accelerator
+        8880    Stealth Video 
+        8881    Stealth Video GUI Accelerator
+        88B0    Stealth 64 Video GUI Accelerator
+        88B1    Stealth 64 Video GUI Accelerator
+        88C0    Stealth 64 GUI Accelerator
+        88C1    Stealth 64 GUI Accelerator
+        88D0    Stealth 64 GUI Accelerator
+        88D1    Stealth 64 GUI Accelerator
+        88F0    Stealth 64 Video GUI Accelerator
+        88F1    Stealth 64 Video GUI Accelerator
+        9876    Supra Express 56i Pro CW #2
+        9999    Monster Sound Diamand Technology DT0398
+1093    National Instruments
+        0160    PCI-DIO-96 data adquisition input and output
+        0161    PCI-1200 Multifunction data acquisition board
+        0162    PCI-MIO-16XE-50 24MIO  6-03-2
+        1150    PCI-DIO-32HS High Speed Digital I/O Board
+        1170    PCI-MIO-16XE-10 
+        1180    PCI-VEN-1180  base system device
+        1190    PCI-MIO-16E-4 
+        11B0    
+        11C0    
+        11D0    
+        11E0    
+        1270    PCI-6032E Multifunction Data Acquisition Card
+        12b0    PCI-6534 High Speed DIO
+        1310    PCI-6602 Data Acquisition Device
+        1320    
+        1330    PCI-6031E 
+        1340    PCI-6033E Multifunction Data Acquisition Card
+        1350    PCI-6071E  NI PCI-6071E Multifunction I/O & NI-DAQ
+        1360    
+        14e0    PCI611X PCI611X
+        17D0    PCI-6503 
+        18B0    
+        28b0    NI 6014 I/O Terminal NI-DAQ (Legacy) and NI-DAQmx
+        2A60    PCI-6023E 
+        2A70    PCI-6024E Multifunction Data Acquisition Card
+        2A80    PCI-6025E Multifunction Data Acquisition Card
+        2B20    PCI-6527 
+        2C80    PCI-6035E 
+        2CA0    PCI-6034E
+        702C    NI PXI-7831R NI FPGA Modul
+        70af    PCI-6221 16-Bit, 250 kS/s, 16 Analog Inputs
+        70b8    NI PCI-6251 Multifunction DAQ Device
+        70E3    1 NI PXI-8431/8 (RS485/RS422)
+        70E4    70E41093 NI PCI-8430/8 (RS-232) Interface
+        710e    PCIe-GPIB GPIB Controller Interface Board
+        7146    NI-PCI-6132 NI-PCI-6132
+        71BC    PCI-6221  16-Bit, 250 kS/s, 16 Analog Inputs  (DSUB37)
+        7414    PCIe-GPIB+ NI PCIe-GPIB+ GPIB with analyzer
+        B001    IMAQ-PCI-1408 
+        B011    IMAQ-PXI-1408 
+        B021    IMAQ-PCI-1424 
+        B031    IMAQ-PCI-1413 
+        B041    IMAQ-PCI-1407 1pcs
+        B051    IMAQ-PXI-1407 
+        B061    IMAQ-PCI-1411 
+        B071    IMAQ-PCI-1422 IMAQ-PCI-1422
+        B081    IMAQ-PXI-1422 
+        B091    IMAQ-PXI-1411 bluethooth
+        C4C4    NI PCIe-1433 NI PCIe-1433 extended (deca) Camera Link frame grabber
+        C801    PCI-GPIB GPIB Controller Interface Board
+        C811    
+        C821    
+        C831    TNT5002 PCI-GPIB
+        C840    
+        d130    PCI-232/2 2-port RS-232 Serial Interface Board
+1094    Apostolos
+1095    Silicon Image, Inc.
+        0240    SIL3112 SATA/Raid controller(2XSATA150)
+        0242    SIL3132 SATAII/Raid controller
+        0244    SIL3132 eSATA/Raid controller
+        0640    PCI0640A/B EIDE Ctrlr
+        0641    pci0640 pci eide adapter with raid 1
+        0642    PCI0642 IDE Cntrlr w/RAID 1
+        0643    PCI0643 PCI EIDE controller
+        0646    CMD646 EIDE/UDMA Controller
+        0647    PCI0647 9738
+        0648    PCI-648 Bus Master Ultra DMA PCI-IDE/ATA Chip
+        0649    PCI-649 PATA100 ATAPI/RAID Controller
+        0650    PBC0650A Fast SCSI-II Ctrlr
+        0670    USB0670 PCI-USB
+        0673    USB0673 PCI-USB ASIC
+        0680    SiI 0680/680A PATA133 ATAPI/RAID Controller
+        1025    PCI0647 9738
+        1392    1390/1392 High Definition Audio HDMI output
+        2455    SI3124 SATALink 4-Port PCI-X Host Controller
+        3112    SIL3112 SATA/Raid controller(2XSATA150)
+        3114    Sil 3114 SATALink/SATARaid Controller
+        3124    SiI 3124 PCI-X to Serial ATA Controller
+        3132    SiI 3132 RR252x SATA Controller
+        3512    Sil 3512 SATALink/SATARaid Controllerhttp://www.pcidatabase.com/update_device.php?__ec_i=ec.1378825283.616786
+        3531    3531 SiI 3531 SATA Controller
+        9876    0x9876 0x9876
+1096    Alacron
+        1106    0x3059 Realtek AC97 Audio for VIA (R) Audio Controller
+        3059    VT8233 South Bridge
+1097    Appian Graphics
+        0038    EIDE Controller (single FIFO)
+1098    Quantum Designs Ltd.
+        0001    QD8500 EIDE Controller
+        0002    QD8580 EIDE Controller
+1099    Samsung Electronics Co. Ltd.
+109A    Packard Bell
+        8280    0x036en 4 channel video digitizer cardm
+109B    Gemlight Computer Ltd.
+109C    Megachips Corporation
+109D    Zida Technologies Ltd.
+109E    Brooktree Corporation
+        0350    036E rb8701.1
+        0350&SUBSYS_000000      Bt848h tv tuner driverhj
+        0351    Bt848 BrookTree Bt848 Video Capture Device - Audio Section      PCI
+        0369    Bt878fusion 878a Video Capture
+        036C    th&#305;k 
+        036E    A8FEFC28 AVerMediaAverTV WDM AudioCapture (878)
+        036E&SUBSYS_000000      Conextant Fucion 878A 25878-123 Video Capture
+        036E&SUBSYS_000000      Conextant Fucion 878A 25878-123 Video Capture
+        036F    bx878 Video Capture
+        0370    Bt880B Video Capture (10 bit High qualtiy cap)
+        0878    Conexant Fusion 878A 25878-13 0549Y1JF Multimedia Controller Conexant Fusion 878A 25878-13 0549Y1JF
+        0879    Bt879khf Video Capture (Audio Section)
+        0880    Bt880 Video Capture (Audio Section)
+        109E    Brooktree Corp BT848 SVR-2000 V1.02m Multimedia Video Controllerm
+        109E - 0x036E   1822-0001 0400 video devce
+        2115    BtV 2115 BtV Mediastream Controller 9x
+        2125    109E BtV Mediastream Controller
+        2164    BtV 2164 Display Adapter
+        2165    BtV 2165 MediaStream Controller
+        36e     878a 25878-13
+        36E&SUBSYS_0000000      Bt360 MediaStream &#1050;&#1086;&#1085;&#1090;&#10 Brooktree Corp
+        36E&SUBSYS_0000000      CONEXANT FUSION 878A 25878-13 E153498.1 conexant 878a
+        8230    BtV 8230 ATM Segment/Reassembly Controller (SRC)
+        8472    Bt8471/72 32/64-channel HDLC Controllers
+        8474    Bt8474 128-channel HDLC Controller
+109F    Trigem Computer Inc.
+        036F    20020001 Video Capturee
+10A0    Meidensha Corporation
+10A1    Juko Electronics Inc. Ltd.
+10A2    Quantum Corporation
+10A3    Everex Systems Inc.
+10A4    Globe Manufacturing Sales
+        0X5969  
+10A5    Racal Interlan
+10A8    Sierra Semiconductor
+        0000    0100 ethernet controller
+10A9    Silicon Graphics
+        0004    O2 MACE 
+        0005    RAD Audio 
+        0006    HPCEX 
+        0007    RPCEX 
+        0008    DiVO VIP 
+        0009    Alteon Gigabit Ethernet
+        0010    AMP Video I/O
+        0011    GRIP 
+        0012    SGH PSHAC GSN 
+        1001    Magic Carpet 
+        1002    Lithium 
+        1003    Dual JPEG 1 
+        1004    Dual JPEG 2 
+        1005    Dual JPEG 3 
+        1006    Dual JPEG 4 
+        1007    Dual JPEG 5 
+        1008    Cesium 
+        2001    Fibre Channel
+        2002    ASDE 
+        8001    O2 1394 
+        8002    G-net NT 
+10AB    Digicom
+        1005    USB\VID_0000@PID_0000\6@390392D@0@1 USB Pendrive
+        1007    USB\VID_0000@PID_0000\6@390392D@0@1 usb pendrive
+        8086    2200 PCI Simple Communications Controller 
+10AC    Honeywell IASD
+10AD    Winbond Systems Labs
+        0001    W83769F EIDE Ctrlr
+        0103    sl82c103 PCI-ide mode 4.5 Cntrlr
+        0105    W83789F Sonata bus master PCI-IDE controller
+        0565    W83C553F PCI/ISA bridge
+10AE    Cornerstone Technology
+10AF    Micro Computer Systems Inc.
+10B0    Gainward GmbH 
+10B1    Cabletron Systems Inc.
+10B2    Raytheon Company
+10B3    Databook Inc.
+10B4    STB Systems
+10B5    PLX Technology Inc.
+        0324    
+        0480    IOP 480 Integrated PowerPC I/O Processor
+        0960    PCI 9080RDK-960 PCI Reference Design Kit for PCI 9080
+        1030    Gazel R685 ISDN card
+        1054    Gazel R697 dual channel ISDN card
+        1078    PCI 9050 Vision Systems VScom PCI-210
+        1103    PCI 9050 Vision Systems VScom PCI-200
+        1146    PCI 9050 Vision Systems VScom PCI-010S
+        1147    PCI 9050 Vision Systems VScom PCI-020S
+        1151    Gazel R753 ISDN card
+        1152    Gazel R753 ISDN card
+        2724    Thales PCSM Security Card
+        2748    9054 TPCX Transientrecorder Card
+        3001    plx9030 gpscard
+        5406    PCI RDK9054-LITE PCI Reference Design Kit for PLX PCI 9054
+        5601    PCI 9056 32-bit; 66MHz PCI Bus Master I/O Accelerator, 17 x 17mm FPBGA
+        6520    PCI6520 G PCI-X to PCI-X Bridge
+        6ACC    PCI 9030 General Mechatronics 6 Axis Motion Control Card for EMC2
+        8111    PEX 8311 1 Lane PCI Express to PCI bridge (PEX8111); 1 Lane PCI Express to Generic Local Bus bridge (PEX8311)
+        8112    PEX8112 1 Lane PCI Express to PCI bridge
+        8508    PEX8508 8 Lane, 5 Port PCI Express Switch
+        8509    PEX8509 8-lane PCI-Express Switch
+        8516    PEX 8516 Versatile PCI Express Switch
+        8518    PEX8518-AB25BI PLX PCI-e switch
+        8532    PEX 8532 Versatile PCI Express Switch
+        8548    8548 48-lane PCIe switch
+        8609    PEX 8609 8 Lane, 8 Port PCI Express Switch
+        8664    PEX 8664 64-Lane, 16-Port PCI Express Gen 2 (5.0 GT/s) Switch, 35 x 35mm FCBGA
+        8748    PEX 8748 48-Lane, 12-Port PCI Express Gen 3  Multi-Root Switch
+        9030    PCI 9030 PCI SMARTarget I/O Accelerator
+        9036    PCI9036 Interface chip - value 1k
+        9050    PCI 9050 Target PCI Interface Chip - value 1k
+        9052    PCI 9052 PCI 9052 Target PLX PCI Interface Chip
+        9054    PCI 9054 PCI I/O Accelerator
+        9056    PCI9056 32-bit, 66 MHz PCI Bus-Mastering I/O Accelerator for PowerQUICC and Generic 32-bit, 66 MHz Local Bus
+        9060    PCI9060 PCI Bus Master Interface Chip
+        906D    PCI 9060SD PCI Bus Master Interface Chip
+        906E    PCI 9060ES PCI Bus Master Interface Chip
+        9080    PCI 9080 High performance PCI to Local Bus chip
+10B6    Madge Networks
+        0001    Smart 16/4 Ringnode (PCI1b)
+        0002    Smart 16/4 Ringnode (PCIBM2/CardBus)
+        0003    Smart 16/4 Ringnode
+        0004    Smart 16/4 Ringnode Mk1 (PCIBM1)
+        0006    16/4 CardBus Adapter (Eric 2)
+        0007    Presto PCI 1716 
+        0009    Smart 100/16/4 PCi-HS Ringnode
+        000A    Smart 100/16/4 PCI Ringnode
+        000B    16/4 CardBus  Adapter Mk2
+        1000    Horizon ATM adapter
+        1001    Ambassador ATM adapter
+        1002    Ambassador ATM Adapter
+10B7    3Com Corporation
+        0001    3C985 1000BaseSX Gigabit Etherlink
+        0013    3com p/n: 3CRDAG675 3Com11a/b/g Wireless PCI Adapter 
+        1000    3C905CX-TXNM 3COM 3C905CX-TXNM with 40-0664-003 ASIC
+        1006    14e4:1645 Broadcom Corporation NetXtreme BCM5701 Gigabit Ethernet
+        1007    3C556 V.90 Mini-PCI Modem
+        1700    3C940 Gigabit Ethernet PCI CODEC
+        1F1F    3CRWE777A AirConnect Wireless LAN PCI Card
+        3390    3C339 Token Link Velocity
+        3590    3C359 TokenLink Velocity XL Adapter
+        4500    3C450 Cyclone
+        5055    3C555 Laptop Hurricane
+        5057    3C575 Megahertz 10/100 LAN CardBus PC Card
+        5157    3C575B Megahertz 10/100 LAN CardBus PC Card
+        5257    3CCFE575CT Cyclone Fast Ethernet CardBus PC Card
+        5900    3C590 Ethernet III Bus Fast PCI
+        5920    3C592 PCI/EISA 10Mbps Demon/Vortex
+        5950    3COM 3C595-TX 100MB PCI Ethernet Adapter
+        5951    3C595 Fast EtherLink PCI T4
+        5952    3C595 Fast EtherLink PCI MII
+        5970    3C597 PCI/EISA Fast Demon/Vortex
+        5B57    3C595 Megahertz 10/100 LAN CardBus
+        6055    3C556 10/100 Fast Ethernet MiniPCI Adapter
+        6056    3CN3AC1556B MiniPCI 10/100 Ethernet+Modem56k (see devid:1007)
+        6560    3CCFE656 Cyclone CardBus PC Card
+        6561    FEM656 10/100 LAN+56K Modem CardBus PC Card
+        6562    3CCFEM656 Cyclone CardBus PC Card
+        6563    FEM656B 10/100 LAN+56K Modem CardBus PC Card
+        6564    3CCFEM656 Cyclone CardBus PC Card
+        6565    3CCFEM656C Global 10/100 Fast Ethernet+56K Modem
+        7646    3CSOHO100B-TX 3com
+        7770    ??? AirConnect Wireless PCI
+        8811    Token Ring
+        9000    3C900-TPO Fast Etherlink PCI TPO NIC
+        9001    3C900-COMBO Fast Etherlink XL PCI Combo NIC
+        9004    3C900-TPO EtherLink XL TPO 10Mb
+        9005    3C900B-COMBO Fast Etherlink 10Mbps Combo NIC
+        9006    3C900B-TPC EtherLink XL TPC
+        900A    3C900B-FL EtherLink PCI Fiber NIC
+        9041    3C905-T4 Fast Etherlink XL 10/100
+        9050    3C905B - Combo Fast Etherlink XL PCI 10/100
+        9051    3C905-T4 Fast Etherlink XL 10/100
+        9055    APCI/pnpb006 Fast Etherlink 10/100 PCI TX NIC
+        9056    3C905B-T4 Fast EtherLink XL 10/100
+        9058    3C905B-COMBO Deluxe EtherLink 10/100 PCI Combo NIC
+        905A    3C905B-FX Fast EtherLink 100 Fiber NIC
+        9200    3C905 CX-TXM 3Com 10/100 Managed NIC 3C905CX-TX-M
+        9201    3C920B-EMB Integrated Fast Ethernet Controller
+        9202    3C920B-EMB 3C920B-EMB 3Com + Realtek 8201L
+        9210    3C920B-EMB-WNM Integrated Fast Ethernet Controller
+        9300    3csoho100b-tx 3ComSOHO100B-TX
+        9800    3C980-TX Fast EtherLink XL Server Adapter2
+        9805    3C980-TX Python-T 10/100baseTX NIC
+        9876    3C920B-EMB 3C920B-EMB 3Com + Realtek 8201L
+        9902    3CR990-TX-95 EtherLink 10/100 PCI with 3XP Processor
+        9903    3CR990-TX-97 EtherLink 10/100 PCI with 3XP Processor
+        9905    3C990B-FX 100FX PCI Server NIC w/3XP
+        9908    3CR990SVR95 EtherLink 10/100 Server PCI with 3XP
+        9909    3CR990SVR97 EtherLink 10/100 Server PCI with 3XP
+        D004    3C900B-TPO EtherLink XL PCI
+10B8    Standard Microsystems Corporation
+        0005    LAN83C170QF/171 EPIC/XF 10/100 Mbps Fast Ethernet Ctrlr
+        0006    LAN83C175 EPIC/C Ethernet CardBus Integrated Ctrlr
+        1000    37C665 FDC
+        1001    37C922 FDC
+        A011    83C170QF Fast ethernet controller
+        B106    SMC34C90 CardBus Controller
+10B9    Ali Corporation
+        0101    CMI8338/C3DX PCI Audio Device (OEM)
+        0102    CMI8338/C3DX PCI Audio Device (OEM)
+        0111    CMI8738/C3DX C-Media Audio Device (OEM)
+        0780    ??? Multi-IO Card
+        0782    ??? Multi-IO Card
+        10b9    ALI M5273 A1 0402t505 CK46828100B
+        10CE    5288 cpi
+        1435    M1435 VL Bridge
+        1445    M1445 CPU to PCI & PCI to ISA Bridge w/EIDE
+        1449    M1449 ISA Bridge
+        1451    M1451 Pentium CPU to PCI Bridge
+        1461    M1461 P54C Chipset
+        1489    M1489 486 PCI Chipset
+        1511    M1575 Aladdin 2 Host Bridge
+        1513    M1513 Aladdin 2 South Bridge
+        1521    M1521 Bios
+        1523    M1523 ISA Bridge
+        1533    M1535+ PCI South Bridge
+        1535    M1535x ISA Bridge
+        1541    M1541 Aladdin V AGPset Host Bridge
+        1543    M1543 a1 Aladdin V chipset South Bridge
+        1561    M1561 North Bridge
+        1563    M1563 South Bridge with Hypertransport Support
+        1632    M1632 North Bridge
+        1641    M1641 CPU to PCI Bridge
+        1644    M1644 AGP System Controller
+        1646    M1646 AGP System Controller
+        1647    M1647 CPU to PCI Bridge
+        1651    M1651 CPU to PCI Bridge
+        1661    M1661 AGP System Controller
+        1667    M1667 AGP System Controller
+        1671    M1671 Super P4 Nouth Bridge
+        1672    M1672 AGP System Controller
+        1681    M1681 P4 Nouth Bridge with HyperTransport
+        1687    M1687 K8 North Bridge with HyperTransport
+        1849    52871849 02\3&267A616A
+        3141    M3141 GUI Accelerator
+        3143    M3143 GUI Accelerator
+        3145    M3145 GUI Accelerator
+        3147    M3147 GUI Accelerator
+        3149    M3149 GUI Accelerator
+        3151    M3151 GUI Accelerator
+        3307    M3307 MPEG-1 Decoder
+        3309    M3309 MPEG Decoder
+        3432423 23128091 131312
+        5212    M4803 
+        5215    MS4803 EIDE Ctrlr
+        5217    m5217h I/O (?)
+        5219    PCI\VEN_10B9&DEV_5451&CC_040100 Ali M5219 PCI BUS MASTER IDE Controller
+        5225    M5225 IDE Controller
+        5228    M1563 M5228 PATA/RAID Controller
+        5229    M5229 Southbridge EIDE Controller
+        5229&REV_00     ? Ali EIDE
+        5229&REV_20     ? PATA 33
+        5229&REV_C2     ? PATA 66
+        5229&REV_C4     ? PATA 100
+        5229&REV_C5     chipset PATA 133
+        5235    M1621 ALI M6503c
+        5236    M5273 EHCI USB 2.0
+        5237    M5273 A1 for windows 2000 OpenHCI 1.1 USB to  2.0
+        5239    523910A9 USB EHCI2.0 Controller
+        5249    M5249 HyperTransport to PCI Bridge
+        5251    M5251 IEEE P1394 OpenHCI 1.0 Controller
+        5253    M5253 IEEE P1394 OpenHCI 1.0 Controller
+        5261    M5261 Ethernet Controller
+        5263    Albatron K8ULTRA-U Pro ULi PCI Fast Ethernet Controller
+        528     52871849 02\3&267A616A
+        5281    M1565/1566 ALI M5281/5283  SATA/RAID Controller
+        5286    52291849 Realtek PCIE CardReader
+        5287    ULI M1573 SATA/Raid controller
+        5288    ULI M1575/M1697  M5288 SATA/Raid controller (Asrock 939SLI32-eSata2)
+        5289    ULI M1567/M1689  M5289 SATA/Raid controller
+        5450    65525 Agere Systems AC97 Modem
+        5451    M5451 Ali Audio Accelerator
+        5455    M1563M Southbridge AC'97 Audio Controller
+        5457    M1563M AC97 Modem controller
+        0X5459  MDV92XP NetoDragon PCI Soft Modem V92 NetoDragon
+        5461    M5461 High Definition Audio Controller
+        5471    M1563M Southbridge Memory Stick Host
+        5473    M1563M Southbridge MMC/SD controller
+        7101    M7101 Power Management Controller
+        7471    M1563M Southbridge Memory Stick Host
+        9876    mdv92xp xhcth700000b
+10BA    Mitsubishi Electronics Corp.
+        0304    GUI Accelerator
+10BB    Dapha Electronics Corporation
+10BC    Advanced Logic Research Inc.
+10BD    Surecom Technology
+        0803     MYSON Technology Inc SURECOM EP-320X-S 100/10M Et Ethernet PCI Adapter
+        0E34    NE34 Ethernet Adapter (NE2000 PCI clone)
+        5240    0055 IDE Cntrlr
+        5241    8086 PCMCIA Bridge
+        5242    General Purpose Cntrlr
+        5243    00000000 Bus Cntrlr
+        5244    FCD Cntrlr
+        8136    Unkown Unkown
+        8139    surecom EP-320X-R adapter with realtek 8139c chip realtek 8139c
+10BE    Tsenglabs International Corp.
+10BF    MOST Corp.
+10C0    Boca Research Inc.
+10C1    ICM Corp. Ltd.
+10C2    Auspex Systems Inc.
+10C3    Samsung Semiconductors
+        8920    5335fn800829 MCP67 High Definition Audio 
+        8925    
+10C4    Award Software Int'l Inc.
+        8363    s/n124102160 10C4
+        EA60    CP210x Silicon Labs CP210x USB to UART Bridge
+10C5    Xerox Corporation
+10C6    Rambus Inc.
+10C8    Neomagic Corporation
+        0004    831610F7 MagicGraph 128XD
+        0000    NM2097 Graphics Cntrlr
+        0003    NM2093 MagicGraph 128ZV Video Controller
+        0004    NM2160 MagicGraph 128XD
+        0005    NM2200 MagicMedia 256AV
+        0006    NM2360 MagicMedia 256ZX/256M6D
+        0016    NM2380 MagicMedia 256XL+
+        0025    NM2230 MagicMedia 256AV+
+        0083    NM2097 Graphic Controller NeoMagic MagicGraph128ZV+
+        8005    NM2200 MagicMedia 256AV Audio Device
+        8006    NM2360 MagicMedia 256ZX Audio Device
+        8016    NM2380 MagicMedia 256XL+ Audio Device
+10C9    Dataexpert Corporation
+10CA    Fujitsu Siemens
+        9876    ROOT\MEDIA\0000 PCI\VEN_1217&DEV_7110&SUBSYS_106A1734&REV_00
+10CB    Omron Corporation
+10CD    Advanced System Products
+        1100    ASC1100 PCI SCSI Host Adapter
+        1200    ASC1200 Fast SCSI-II
+        1300    ABP-3925 ABP-3925
+        2300    F914C536 PCI Ultra Wide SCSI Host Adapter
+        2500    ASC38C0800/1600 PCI Ultra 80/160 SCSI Controllers
+        4000    ASC30C0400 IEEE-1394 OHCI PCI Controller
+10CF    Fujitsu Ltd.
+        10C5    FMV-103 Serial Parallel Card
+        2001    MB86605 PCI SCSI Host Adapter (Fast Wide SCSI-2)
+        2002    MB86606 Fast Wide SCSI Controller
+        2005    MB86974 10/100 Fast Ethernet Adapter
+        200C    MB86974 IEEE1394 OpenHCI Controller
+        2010    OHCI FireWire Controller
+        2011    12711718 MPEG2 R-Engine (MPEG2 Hardware Encoder)
+        2019    MB86295 Coral-P Graphics Chip
+        201E    MB86296 Coral-PA Graphics Chip
+        202A    u/k u/k
+        202B    mb86297 Carmine Graphisc adapter
+10D1    Future+ Systems
+10D2    Molex Incorporated
+10D3    Jabil Circuit Inc.
+10D4    Hualon Microelectronics
+10D5    Autologic Inc.
+10D6    Wilson .co .ltd
+        FF51    0x0100 ATJ2091N
+        ff66    0x0100 ATJ2091N
+10D7    BCM Advanced Research
+10D8    Advanced Peripherals Labs
+10D9    Macronix International Co. Ltd.
+        0066    MX86101P sdas
+        0512    MX98713 Fast Ethernet Adapter
+        0531    MX98715/25 Single Chip Fast Ethernet NIC Controller
+        0532    MX98723/727 PCI/CardBus Fast Ethernet Controller
+        0553    MX987x5 Ethernet Adapter
+        8625    MX86250 xiankasqudong
+        8626    MX86251 PCI\VEN_10D9&DEV_8626&SUBSYS_00000000&REV_00\4&1F7DBC9F&0&08F0 
+        8627    MX86251FC Voodoo Rush MX86251
+        8888    MX86250 9619E
+        C115    lc82c115  Linksys LNE100TX 
+10DB    Rohm Research
+10DC    CERN-European Lab. for Particle Physics
+        0001    STAR/RD24 PCI-SCI  PMC  mezzanine
+        0002    ATT 2C15-3 (FPGA) SCI bridge  on PCI 5 Volt card
+        0004    EP20S780 ALTERA STRATIX
+        0010    680-1110-150/400 Simple PMC/PCI to S-LINK interface
+        0011    680-1110-200/450 Simple S-LINK to PMC/PCI interface
+        0012    S32PCI64 32-bit S-LINK to 64-bit PCI interface
+        0021    HIPPI destination
+        0022    HIPPI source
+        0033    EP20KE (APEX-FPGA) ALICE DDL to  PCI interface (RORC)
+        0101    SL651 7057 C200 Acquisition card for the SPS Orbit System (MACI)
+        016A    XC4VFX100 CALICE ODR
+        10DC    ATT 2C15-3 (FPGA) TTC sr   first TTC chip receiver PMC
+        301     PLX PCI 9030 based on the PLX PCI 9030 to build a MIL1553 bus interface
+        324     PLX PCI96556 64 Bit/66MHz PCI to Local Bus Bridge
+        8086    a002 geodelink pci south
+10DD    Evans & Sutherland
+        0001    3D graphics processor
+10DE    NVIDIA
+         04EF   NV3 Riva 128
+        0001    Lucent 0x00da SoundMAX Integrated Digital Audio
+        0002    0x0002 HDMI Audio Driver Driver
+        0003    It seems to be Realtek ALC888/9 nVIDIA High Definition Audio/HDMI 
+        0006    Realtek realtek based HD Audio
+        0008    NV1 Edge 3D
+        0009    NV1 Edge 3D
+        000B    7025 HDMI Audio Driver Driver 1.00.00.59
+        0010    NV2 Mutara V08
+        0011    Various - see list on site NVIDIA High Def Audio
+        0018    NV3 Riva 128
+        0019    NV3 Riva 128ZX
+        001D    NV35 nVidia GeForce FX 5900XT
+        0020    GTX680M NVIDIA RIVA TNT
+        0028                    NV05    0DF4  MCP67 
+        0028    NVIDIA GeForce 635M ACPI\NSC1200
+        0029    NV05 NVIDIA RIVA TNT 2 Ultra
+        002A    0df4 TNT2
+        002B    NV5 Riva TNT2
+        002C    NV05 NVIDIA Vanta/Vanta LT
+        002D    NV05 NVIDIA RIVA TNT2 Model 64/Model 64 AGP 32M
+        002E    NV6 VANTA
+        002F    NV6 VANTA
+        0035    MCP04 MCP04 PATA Controller
+        0036    MCP04 MCP04 SATA/RAID Controller
+        003E    MCP04 MCP04 SATA/RAID Controller
+        0040    NV40 NVIDIA GeForce 6800 Ultra
+        0041    NV40 NVIDIA GeForce 6800
+        0042    NV40 NVIDIA GeForce 6800 LE
+        0043    NV40 NVIDIA GeForce 6800 XE
+        0044    NV40 NVIDIA GeForce 6800 XT
+        0045    NV40 NVIDIA GeForce 6800 GT
+        0046    NV45 NVIDIA GeForce 6800 GT
+        0047    NV40 NVIDIA GeForce 6800 GS
+        0048    NV40 NVIDIA GeForce 6800 XT
+        0049    NV40 NVIDIA NV40GL
+        004D    NV40 NVIDIA Quadro FX 3400
+        004E    NV40 NVIDIA Quadro FX 4000
+        0052    NV06 NVIDIA nForce PCI System Management
+        0053    CK804 CK804 PATA Controller
+        0054    CK804 CK804 SATA/RAID Controller
+        0055    CK804 CK804 SATA/RAID Controller
+        0057    CK804 NVIDIA Network Bus Enumerator
+        0059    sdsd nForce Audio Controller
+        005E    nForce4 nForce4 HyperTransport Bridge
+        0060    MCP68 PCI to ISA Bridge
+        0064    MCP SMBus Controller
+        0065    nForce MCP2/MCP2-T/MCP2-U PATA Controller
+        0066    nForce MCP2 nForce 2 Networking Controller
+        0067    MCP2 Nvidia 7050 chipset HDMI Audio
+        0068    MCP2 EHCI USB 2.0 Controller
+        006A    MCP2s nForce AC97s
+        006B    nForce MCP-T? Audio Processing Unit (Dolby Digital)
+        006C    nForce PCI to PCI Bridge
+        006D    nForce MCP-T Audio Codec Interface
+        006E    nForce MCP2 OHCI Compliant IEEE 1394 Controller
+        0085    MCP2S MCP2S PATA Controller
+        008C    RLT8201BL Single-Port 10/100M Fast Ethernet PHYceiver
+        008E    MCP2S MCP2S SATA/RAID Controller
+        0090    G70 NVIDIA GeForce 7800 GTX
+        0091    G70 NVIDIA GeForce 7800 GTX
+        0092    G70 NVIDIA GeForce 7800 GT
+        0093    G70 NVIDIA GeForce 7800 GS
+        0094    G70 NVIDIA GeForce 7800SE/XT/LE/LT/ZT
+        0095    G70 NVIDIA GeForce 7800 SLI
+        0098    G70 NVIDIA GeForce Go 7800
+        0099    G70 NVIDIA GeForce Go 7800 GTX
+        009C    G70 NVIDIA Quadro FX 350M
+        009D    G70 NVIDIA Quadro FX 4500
+        009E    G70 NVIDIA G70GL
+        00A0    NV10de Aladdin TNT2
+        00C0    NV41 NVIDIA GeForce 6800 GS
+        00C1    NV41 NVIDIA GeForce 6800
+        00C2    NV41 NVIDIA GeForce GTX670M
+        00C3    NV41 NVIDIA GeForce 6800 XT
+        00C8    NV41.8 NVIDIA GeForce Go 6800
+        00C9    NV41 NVIDIA GeForce Go 6800 Ultra
+        00CC    NV41 NVIDIA Quadro FX Go 1400
+        00CD    NV41 NVIDIA Quadro FX 3450/4000 SDI
+        00CE    NV41 NVIDIA Quadro FX 1400
+        00D0    nForce 3 LPC Bridge
+        00D1    nForce 3 Host Bridge
+        00D2    nForce 3? PCI-to-PCI Bridge
+        00D4    MCP2 SMBus Controller
+        00D5    nForce3-150 CK8 PATA 133/PATA to SATA Bridge
+        00D6    MCP3 nForce 3 Networking Controller
+        00D7    nForce MCP3? OpenHCD USB Host Controller
+        00D8    nForce MCP3? Enhanced PCI to USB Host Controller
+        00D9    nForce 3 Agere System PCI Soft Modem
+        00DA    MCP3 AC97 Audio Controller
+        00DD    nForce MCP3? PCI-to-PCI Bridge
+        00DF    MCP73 nForce3 Networking Controller
+        00E0    nForce3 250 LPC Interface Bridge
+        00E1    nForce3 250 Host/PCI Bridge
+        00E2    nForce 8400 M AGP Host to PCI Bridge
+        00E3    nForce 250 CK8S SATA/RAID Controller
+        00E4    nForce3 200 PCI System Management
+        00E5    nForce3 250 Parallel ATA Controller
+        00E7    nForce3 250 OpenHCD USB Controller
+        00E8    nForce3 250 Enhanced PCI to USB Controller
+        00EA    nForce3 250  Audio Codec Interface (Realtek ALC658)
+        00ED    nForce gt 220 PCI-PCI Bridge
+        00EE    nForce 250 CK8S SATA/RAID Controller
+        00F0    BR02 NVIDIA Device
+        00F1    BR02 NVIDIA GeForce 6600 GT
+        00F2    BR02 NVIDIA GeForce 6600
+        00F3    BR02 NVIDIA GeForce 6200
+        00F4    BR02 NVIDIA GeForce 6600 gt
+        00F5    BR02 NVIDIA GeForce 7800 GS
+        00F6    BR02 NVIDIA GeForce 6800 GS/XT
+        00F8    BR02 NVIDIA Quadro FX 3400/4400
+        00F9    BR02 NVIDIA GeForce 6800 Series GPU
+        00FA    BR02 NVIDIA GeForce PCX 5750
+        00FB    BR02 NVIDIA GeForce PCX 5900
+        00FC    BR02 NVIDIA GeForce PCX 5300
+        00FD    BR02 NVIDIA Quadro PCI-E Series
+        00FE    BR02 NVIDIA Quadro FX 1300
+        00FF    BR02 NVIDIA GeForce PCX 4300
+        0100    NV10 HDAUDIO\FUNC_01&VEN_10EC&DEV_0269&SUBSYS_11790644&REV_1002\4&1422899C&0&0001
+        0101    NV10 NVIDIA GeForce DDR
+        0102    NV10 GeForce 256 Ultra
+        0103    NV10 NVIDIA Quadro
+        0110    NV12 NVIDIA GeForce2 MX/MX 400
+        0111    NV11 NVIDIA GeForce2 MX 100/200
+        0112    NV9 NVIDIA GeForce 9800gt
+        0112h   ??? Nvidia GeForce2 Go/MX Ultra Video Adapter
+        0113    NV11 NVIDIA Quadro2 MXR/EX
+        0140    NV43 NVIDIA GeForce 6600 GT
+        0141    NV43 nVIDIA GeForce 6600 PCI-E Video Adapter
+        0142    NV43 NVIDIA GeForce 6600 LE
+        0143    NV43 NVIDIA GeForce 6600 VE
+        0144    NV43 NVIDIA GeForce Go 6600
+        0145    NV43 NVIDIA GeForce 6610 XL
+        0146    NV43 NVIDIA GeForce Go 6200 TE/6600 TE
+        0147    NV43 NVIDIA GeForce 6700 XL
+        0148    NV43 NVIDIA GeForce Go 6600
+        0149    NV43 NVIDIA GeForce Go 6600 GT
+        014A    NV43 NVIDIA Quadro NVS 440
+        014B    NV43 NVIDIA NV43
+        014C    NV43 NVIDIA Quadro FX 540M
+        014D    NV43 NVIDIA Quadro FX 550
+        014E    NV43 NVIDIA Quadro FX 540
+        014F    NV43 NVIDIA GeForce 6200 go
+        0150    NV15 NVIDIA GeForce2 GTS/GeForce2 Pro
+        0151    NV15 NVIDIA GeForce2 Ti
+        0152    NV15 NVIDIA GeForce2 Ultra
+        0153    NV15 NVIDIA Quadro2 Pro
+        016     1 1
+        0160    NV44 NVIDIA GeForce 6500 
+        0161    NV44 NVIDIA GeForce 6200 TurboCache(TM)
+        0162    NV44 NVIDIA GeForce 6200SE TurboCache(TM)
+        0163    NV44 NVIDIA GeForce 6200 LE
+        0164    NV44 NVIDIA NV44
+        0165    NV44 NVIDIA Quadro NVS 285
+        0166    NV44 NVIDIA GeForce Go 6250
+        0167    NV44 NVIDIA GeForce Go 6200
+        0168    NV44 NVIDIA GeForce Go 6400
+        0169    NV44 NVIDIA GeForce 6250
+        016a    NV44 NVIDIA GeForce 7100 GS
+        016B    NV44 NVIDIA NV44GLM
+        016C    NV44 NVIDIA NV44GLM
+        016D    NV44 NVIDIA NV44GLM
+        016E    NV44 NVIDIA NV44GL
+        0170    NV17 NVIDIA GeForce4 MX 460
+        0171    NV17 NVIDIA GeForce4 MX 440 with AGP 4X 64mb
+        0172    NV17 NVIDIA GeForce4 MX 420
+        0173    NV17 NVIDIA GeForce4 MX 440-SE
+        0174    NV17 NVIDIA GeForce4 MX 440 Go
+        0175    NV17 NVIDIA GeForce4 MX 420 Go
+        0176    NV17 NVIDIA GeForce4 MX 420 Go 32M
+        0177    NV17 NVIDIA GeForce4 460 Go
+        0178    NV17 NVIDIA Quadro4 550 XGL
+        0179    NV17.2 NVIDIA GeForce4 MX 440 Go 64M
+        017A    NV17 NVIDIA Quadro NVS
+        017B    NV17GL.3 Quadro4 550 XGL
+        017C    NV17 NVIDIA Quadro4 500 Go GL
+        017D    NV17 NVIDIA GeForce4 410 Go 16M
+        0181    NV18 NVIDIA GeForce4 MX 440 with AGP8X
+        0182    NV18 NVIDIA GeForce4 MX 440SE with AGP8X
+        0183    NV18 NVIDIA GeForce4 MX 420 with AGP8X
+        0185    NV18 NVIDIA GeForce4 MX 4000 128 mb 64 bit
+        0186    NV18 NVIDIA GeForce4 448 Go
+        0187    NV18 NVIDIA GeForce4000 Go
+        0188    NV18 NVIDIA Quadro4 580 XGL
+        018A    NV18 NVIDIA Quadro NVS with AGP8X
+        018B    NV18 NVIDIA Quadro4 380 XGL
+        018C    NV18 NVIDIA Quadro NVS 50 PCI
+        018D    NV18 NVIDIA GeForce4 448 Go
+        0191    G80 NVIDIA GeForce 8800 GTX
+        0193    G80 NVIDIA GeForce 8800 GTS
+        0194    G80 NVIDIA GeForce 8800 Ultra
+        0197    G80 NVIDIA Tesla C870
+        019D    G80 NVIDIA Quadro FX 5600
+        019E    G80 NVIDIA Quadro FX 4600
+        01A0    CR11 NVIDIA GeForce2 Integrated GPU
+        01A4    nForce AGP Controller
+        01A5    nForce AGP Controller
+        01A6    nForce AGP Controller
+        01A8    nForce 210 Memory Controller (SDR) ddr3
+        01A9    nForce 420 Memory Controller (SDR)
+        01AA    nForce 220/230 Memory Controller (DDR)
+        01AB    nForce 415/420/430 Memory Controller (DDR)
+        01AC    nForce 2x0/415/4x0 Memory Controller
+        01AD    nForce 2x0/415/4x0 Memory Controller
+        01B0    MCP73 nForce Dolby Digital Audio Controller
+        01B1    MCP3 nForce AC'97 Audio Controller
+        01B2    nForce HUB Interface
+        01B4    MCP nForce 1/2 SMBus Controller
+        01B7    nForce AGP Bridge
+        01B8    nForce PCI Bridge
+        01BC    MCP nForce IDE/ATA Controller
+        01C1    nForce MCP AC97 Modem
+        01C2    MCP OHCI USB Controller
+        01C3    MCP73 ethernet nForce Networking Controller
+        01D0    G72 NVIDIA GeForce 7350 LE
+        01D1    G72 NVIDIA GeForce 7300 LE
+        01D2    G72 NVIDIA GeForce 7550 LE
+        01D3    GS7200 NVIDIA GeForce 7300 SE/7200 GS
+        01D5    G72 NVIDIA GeForce 7300 LE
+        01D7    G72 NVIDIA GeForce Go 7300
+        01D8    G72 NVIDIA GeForce Go 7400
+        01DB    G72 NVIDIA Quadro NVS 120M
+        01DC    G72 NVIDIA Quadro FX 350M
+        01DD    G72 NVIDIA GeForce 7500 LE
+        01DE    G72 NVIDIA Quadro FX 350
+        01DF    G72 NVIDIA GeForce 7300 GS
+        01E0    nForce2 AGP Controller
+        01E1    nForce2 AGP Controller
+        01E8    nForce2 AGP Host to PCI Bridge
+        01EA    nForce2 Memory Controller 0
+        01EB    nForce2 Memory Controller 1
+        01EC    nForce2 Memory Controller 2
+        01ED    nForce2 Memory Controller 3
+        01EE    nForce2 Memory Controller 4
+        01EF    nForce2 Memory Controller 5
+        01F0    CR17 NVIDIA GeForce4 MX Integrated GPU
+        0200    NV20 NVIDIA GeForce3
+        0201    NV20 NVIDIA GeForce3 Ti 200
+        0202    NV20 NVIDIA GeForce3 Ti 500
+        0203    NV20 NVIDIA Quadro DCC
+        0210    NV48 NVIDIA NV48
+        0211    NV48 NVIDIA GeForce 6800
+        0212    NV48 NVIDIA GeForce 6800 LE
+        0215    NV48 NVIDIA GeForce 6800 GT
+        0218    NV48 NVIDIA GeForce 6800 XT
+        0220    NV44 NVIDIA NV44
+        0221    NV44 nVidia Geforce 6200 AGP
+        0222    NV44 NVIDIA GeForce 6200 A-LE
+        0228    NV44 NVIDIA NV44M
+        0240    C51 NVIDIA GeForce 6150
+        0241    C51 NVIDIA GeForce 6150 LE
+        0242    C51 NVIDIA GeForce 6100
+        0243    C51 PCI Express Bridge
+        0244    Geforce Go 7600 Geforce Go 6150
+        0245    C51 NVIDIA Quadro NVS 210S / NVIDIA GeForce 6150LE
+        0246    C51 PCI Express Bridge
+        0247    C51 Geforce 6100 Go
+        0248    C51 PCI Express Bridge
+        0249    C51 PCI Express Bridge
+        024A    C51 PCI Express Bridge
+        024B    C51 PCI Express Bridge
+        024C    C51 PCI Express Bridge
+        024D    C51 PCI Express Bridge
+        024E    C51 PCI Express Bridge
+        024F    C51 PCI Express Bridge
+        0250    NV25 NVIDIA GeForce4 Ti 4600
+        0251    NV25 NVIDIA GeForce4 Ti 4400
+        0252    NV25 NVIDIA GeForce4 Ti
+        0253    NV25 NVIDIA GeForce4 Ti 4200
+        0258    NV25 NVIDIA Quadro4 900 XGL
+        0259    NV25 NVIDIA Quadro4 750 XGL
+        025B    NV25 NVIDIA Quadro4 700 XGL
+        0260    0260 PCI standard ISA bridge
+        0264    NVIDIA SMB Bus Controller NVIDIA nForce PCI System Management
+        0265    MCP51 Standard Dual Channel PCI IDE Controller
+        0266    MCP51S NVIDIA nForce 430/410 Serial ATA Controller
+        0267    MCP51S NVIDIA nForce 430/410 Serial ATA Controller
+        0268    MCP51 NVIDIA nForce Networking Controller
+        0269    MCP51 NVIDIA nForce 10/100 Mbps Ethernet
+        026B    MCP51 MCP51 AC'97 Audio 
+        026C    MCP51 Realtek HD Audio Driver
+        026D    026D Standard OpenHCD USB Host Controller
+        026e    MCP51 USB Controller (EHCI)  MCP51 USB Controller
+        026F    026F PCI standard PCI-to-PCI bridge
+        0270    0270 nForce Memory Controller
+        0271    nForce NVIDIA nForce System Management Controller
+        027E    027E nForce Memory Controller
+        027F    027F nForce Memory Controller
+        0280    NV28 NVIDIA GeForce4 Ti 4800
+        0281    NV28 NVIDIA GeForce4 Ti 4200 with AGP8X
+        0282    NV28 NVIDIA GeForce4 Ti 4800 SE
+        0286    NV25 NVIDIA GeForce4 4200 Go
+        0288    NV28 NVIDIA Quadro4 980 XGL
+        0289    NV28 NVIDIA Quadro4 780 XGL
+        028C    NV28 NVIDIA Quadro4 700 Go GL
+        0290    G71 NVIDIA GeForce 7900 GTX
+        0291    G71 NVIDIA GeForce 7900 GT/GTO
+        0292    G71 NVIDIA GeForce 7900 GS
+        0293    G71 NVIDIA GeForce 7950 GX2
+        0294    G71 NVIDIA GeForce 7950 GX2
+        0295    G71 NVIDIA GeForce 7950 GT
+        0297    G71 NVIDIA GeForce Go 7950 GTX
+        0298    G71 NVIDIA GeForce Go 7900 GS
+        0299    G71 NVIDIA GeForce Go 7900 GTX
+        029B    G71 NVIDIA Quadro FX 1500M
+        029C    G71 NVIDIA Quadro FX 5500
+        029D    G71 NVIDIA Quadro FX 3500
+        029E    G71 NVIDIA Quadro FX 1500
+        029F    G71 NVIDIA Quadro FX 4500 X2
+        02A0    NV2A NVIDIA NV2A GeForce 3 Integrated (XBOX)
+        02e0    BR02 NVIDIA GeForce 7600 GT
+        02E1    BR02 NVIDIA GeForce 7600 GS
+        02E2    BR02 NVIDIA GeForce 7300 GT
+        02E3    BR02 NVIDIA GeForce 7900 GS
+        02E4    BR02 NVIDIA GeForce 7950 GT
+        02F3    02F3 PCI standard RAM controller
+        02F8    02F8 nForce Memory Controller
+        02F9    02F9 nForce Memory Controller
+        02FA    02FA nForce HyperTransport Bridge
+        02FC    02FC PCI standard PCI-to-PCI bridge
+        02FD    02FD PCI stanard PCI-to-PCI bridge
+        02FE    02FE nForce Memory Controll
+        0300    NV30 NVIDIA NV30
+        0301    NV30 NVIDIA GeForce FX 5800 Ultra
+        0302    NV30 NVIDIA GeForce FX 5800
+        0308    NV30 NVIDIA Quadro FX 2000
+        0309    NV30 NVIDIA Quadro FX 1000
+        030A    NV30 NVIDIA ICE FX 2000
+        0311    NV31 NVIDIA GeForce FX 5600 Ultra
+        0312    NV31 NVIDIA GeForce FX 5600
+        0313    NV31 NVIDIA NV31
+        0314    NV31 NVIDIA GeForce FX 5600XT
+        0316    NV31 NVIDIA NV31M
+        0317    NV31 NVIDIA NV31M Pro
+        0318    NV31 NVIDIA NV31GL
+        0319    NV31 NVIDIA NV31GL
+        031A    NV31 NVIDIA GeForce FX Go 5600
+        031B    NV31 NVIDIA GeForce FX Go 5650
+        031C    NV31 NVIDIA Quadro FX Go 700
+        031D    NV31 NVIDIA NV31GLM
+        031E    NV31 NVIDIA NV31GLM Pro
+        031F    NV31 NVIDIA NV31GLM Pro
+        0320    NV34 NVIDIA GeForce FX 5200
+        0321    NV34 NVIDIA GeForce FX 5200 Ultra
+        0322    NV34.3 NVIDIA GeForce FX 5200
+        0323    NV34 NVIDIA GeForce FX 5200LE
+        0324    NV34 NVIDIA GeForce FX Go 5200 64mb
+        0325    NV34 NVIDIA GeForce FX Go 5250/5500
+        0326    FX 5500 NVIDIA GeForce FX 5500
+        0327    NV34 NVIDIA GeForce FX 5100
+        0328    NV34 NVIDIA GeForce FX Go 5200 32/64M
+        0329    NV34 NVIDIA NV34MAP
+        032A    NV34 NVIDIA Quadro NVS 55/280 PCI
+        032B    NV34 NVIDIA Quadro FX 500/FX 600
+        032C    NV34 NVIDIA GeForce FX Go 53x0
+        032D    NV34 NVIDIA GeForce FX Go 5100
+        032F    NV34 NVIDIA NV34GL
+        0330    NV35 NVIDIA GeForce FX 5900 Ultra
+        0331    NV35 NVIDIA GeForce FX 5900
+        0332    NV35 NVIDIA GeForce FX 5900XT
+        0333    NV35 NVIDIA GeForce FX 5950 Ultra
+        0334    NV35 NVIDIA GeForce FX 5900ZT
+        0338    NV35 NVIDIA Quadro FX 3000
+        033F    NV35 NVIDIA Quadro FX 700
+        0341    NV36 NVIDIA GeForce FX 5700 Ultra
+        0342    NV36 NVIDIA GeForce FX 5700
+        0343    NV36 NVIDIA GeForce FX 5700LE
+        0344    NV36 NVIDIA GeForce FX 5700VE
+        0345    NV36 NVIDIA NV36
+        0347    NV36 NVIDIA GeForce FX Go 5700
+        0348    NV36 NVIDIA GeForce FX Go 5700
+        0349    NV36 NVIDIA NV36M Pro
+        034B    NV36 NVIDIA NV36MAP
+        034C    NV36 NVIDIA Quadro FX Go 1000
+        034E    NV36 NVIDIA Quadro FX 1100
+        034F    NV36 NVIDIA NV36GL
+        0368    (0xCB84 integrated chip nForce Pro 3400) SMBus controller
+        036C    81FB1043 Standard OpenHCD USB Hostcontroller
+        036d    81FB1043 Standard PCI-to-USB Enhanced Hostcontroller
+        036E    MCP55 MCP55 PATA Controller
+        036F    MCP55 MCP55 SATA/RAID Controller
+        0371    MCP55 High Definition Audio Controller
+        0373    rev.1 NVIDIA nForce Networking Controller
+        037E    MCP55 MCP55 SATA/RAID Controller
+        037F    MCP55S MCP55 SATA/RAID Controller
+        038B    G73 NVIDIA GeForce 7650 GS
+        0390    G73 NVIDIA GeForce 7650 GS
+        0391    G73 NVIDIA GeForce 7600 GT
+        0392    GS NVIDIA GeForce 7600 GS
+        0393    G73 NVIDIA GeForce 7300 GT
+        0394    G73 NVIDIA GeForce 7600 LE
+        0395    G73 NVIDIA GeForce 7300 GT
+        0398    G70 NVIDIA GeForce Go 7600
+        039E    G73 NVIDIA Quadro FX 560
+        039F    SUBSYS_00000000 REV_A1\4&1B41B794&0&00E0
+        03AC    GT216GLM Nvidia Quadro FX 880M
+        03D0    MCP61  NVIDIA GEForce 6150SE nForce 430
+        03D1    C61 nForce 520 LE
+        03D2    C61 NVIDIA GeForce 6100 nForce 400
+        03D5    C61 NVIDIA GeForce 6100 nForce 420
+        03D6    GT218 NVidia GeForce 7025 nForce 630a
+        03E0    nForce 430, MCP61 LPC Bridge PCI standard ISA bridge
+        03E1    NV3 Riva128
+        03E7    MCP61 MCP61 SATA/RAID Controller
+        03EA    MCP61 Memory Controller Memory controller
+        03eb    MCP6P1, 85B36Q1, G822B1, MCP61 SMBus NVIDIA nForce PCI .............. ....................
+        03EC    MCP61 MCP61 PATA Controller
+        03EF    nForce 405, MCP61 Ethernet Nvidia Networking Card
+        03EF &  MCP51 & MCP61 GeForce 6100
+        03F0    ALC660/ALC662 Realtek High Defnition Audio getarnt als nVidia MCP
+        03F1    MCP61 USB Controller Serial bus controller
+        03F2    MCP61 USB Controller Serial bus controller
+        03F3    MCP61 PCI bridge Bridge
+        03F4    Co-Processor NVIDIA nForce System Management Controller
+        03F5    MCP61 Memory Controller Memory controller
+        03F6    MCP61 MCP61 SATA/RAID Controller
+        03F7    MCP51 MCP61 SATA/RAID Controller
+        0400    G84 NVIDIA GeForce 8600 GTS
+        0401    G84 NVIDIA GeForce 8600 GT
+        0402    G84 NVIDIA GeForce 8600 GT
+        0403    G84 NVIDIA GeForce 8600GS
+        0404    G84 NVIDIA GeForce 8400 GS
+        0405    unknown GeForce 9500m GS
+        0406    G84 NVIDIA GeForce 8300 GS
+        0407    NVIDIA GeForce 8600M GT NVIDIA GeForce 8600M GT
+        0409    No Idea Nvidia GeForce 8700M GT
+        040a    G84 NVIDIA Quadro FX 370
+        040C    NVIDIA Quadro NVS 570M Mobile Quadro FX/NVS video card
+        040E    G84 NVIDIA Quadro FX 570
+        040F    G84 NVIDIA Quadro FX 1700
+        0420    G86 NVIDIA GeForce 8400 SE
+        0421    G86 NVIDIA GeForce 8500 GT
+        0422    G86 NVIDIA GeForce 8400 GS
+        0423    G86 NVIDIA GeForce 8300 GS
+        0424    G86 NVIDIA GeForce 8400 GS
+        0425    NVIDIA 8600m GS NVIDIA 8600m GS
+        0426    G86M Geforce 8400M GT GPU
+        0427    G86M Geforce 8400M GS
+        0428    NVIDIA GeForce 8400M G NVIDIA GeForce 8400M G
+        0429    Unknown nVidia Quadro NVS 135M or Quadro NVS 140M 
+        042b    9600 NVIDIA Quadro NVS 135M
+        042C    G86 NVIDIA GeForce 8600gts
+        042D    Quadro FX 360 M Quadro FX 360 M (Mobile)
+        042E    GeForce 9300M G Mobile graphics
+        042f    G86 NVIDIA Quadro NVS 290
+        0447    NVIDIA nForce AR Chipset NVIDIA nForce System Management Controller
+        0448    MCP65 MCP65 PATA Controller
+        044C    MCP65 MCP65 RAID
+        044D    MCP65 MCP65 AHCI
+        044E    MCP67D MCP67D AHCI
+        044F    MCP65 MCP65 ?AHCI
+        0450    E0001458 A3
+        045D    MCP65 MCP65 SATA Controller(IDE mode)
+        04EF    NV3 Riva 128
+        0523    NVidia GeForce 9400GT GPU
+        0531    7150 NVIDIA GeForce Go 7150M (UMA)
+        0533    -PCI\VEN 10DEV 0533&SUBSYS 30EA103C&REV A2\3&2411E nVidia GeForce 7000M / nForce 610M
+        053A    C68 NVIDIA GeForce 7050 PV / NVIDIA nForce 630a
+        053B    C68 NVIDIA GeForce 7050 PV / NVIDIA nForce 630a
+        053E    C68 NVIDIA GeForce 7025 / NVIDIA nForce 630a
+        054     NVidia nForce 4 SLI IDE Controller
+        0542    30CF nForce PCI System Management
+        0543            Coprocessor Coprocessor
+        0543    Coprocessor Coprocessor
+        0548    ENE0100 ENE0100c
+        054c    MCP67 MCP67 Ethernet Vista
+        0550    Myson MTD803/TAMARACK TC6020 PCI Ethernet controller
+        0554    MCP67 MCP67 AHCI
+        0555    MCP67 MCP67 AHCI
+        0556    MCP67 MCP67 AHCI
+        0558    MCP67 MCP67 RAID
+        0559    MCP67 MCP67 RAID
+        055A    MCP67 MCP67 RAID
+        0560    MCP67 MCP67 PATA Controller
+        056C    MCP73 MCP73 PATA
+        05E0    GT200b1 GeForce GTX 295
+        05E1    GT200 NVIDIA GeForce GTX 280
+        05E2    GT200 NVIDIA GeForce GTX 260
+        05E3    GT200b GeForce GTX 285
+        05E6    GT200 NVIDIA GeForce GT 240M
+        05E7    GT200 NVIDIA Tesla C1060
+        05F8    GT200 NVIDIA Quadroplex 2200 S4
+        05F9    GT200 NVIDIA Quadro CX
+        05FD    GT200 NVIDIA Quadro FX 5800
+        05FE    GT200 NVIDIA Quadro FX 4800
+        05FF    G200GL NVIDIA Quadro FX 3800
+        0600    G92 NVIDIA GeForce 8800 GTS 512
+        0601    G92 NVIDIA GeForce 9800 GT
+        0602    G92 NVIDIA GeForce 8800 GT
+        0604    G92 NVIDIA GeForce 9800 GX2
+        0605    G92 NVIDIA GeForce 9800 GT
+        0606    G92 NVIDIA GeForce 8800 GS
+        0608    G92 NVIDIA Geforce 9800M GTX
+        060B    G92 GeForce 9800M GT
+        060D    G92 NVIDIA GeForce 8800 GS
+        0610    G93 NVIDIA GeForce 9300 GSO
+        0611    G92 NVIDIA GeForce 8800 GT
+        0612    G92 NVIDIA GeForce 9800 GTX/9800 GTX+
+        0613    G92 NVIDIA GeForce 9800 GTX+
+        0614    G92 NVIDIA GeForce 9800 GT
+        0615    0615 GeForce GTS 250
+        0619    G92 NVIDIA Quadro FX 4700 X2
+        061A    G92 NVIDIA Quadro FX 3700
+        061B    G92 NVIDIA Quadro VX 200
+        061D    G92 Nvidia Quadro 2800M
+        061F    02EF NVIDIA Quadro FX 3800M
+        0622    G94 gt220
+        0623    G94 NVIDIA GeForce 9600 GS
+        0625    G94 NVIDIA GeForce 9600 GSO 512
+        062C    na G-Force 9800M GTS
+        062D    G94 NVIDIA GeForce 9600 GT
+        062E    G94 NVIDIA GeForce 9600 GT
+        0637    G94 NVIDIA GeForce 9600 GT
+        0638    0638 NVIDIA Quadro FX 1800
+        0640    60770 81yJUT  <a href   0641    jwh058862 NVIDIA GeForce 9400 GT
+        0642    G96 NVIDIA GeForce 8400 GS
+        0643    G95 NVIDIA GeForce 9500 GT
+        0644    G96 NVIDIA GeForce 9500 GS
+        0645    G96 NVIDIA GeForce 9500 GS
+        0646    G95 Geforce 9500GS
+        0648    G96 NVIDIA GeForce 9600 GS
+        0649    G96 nVidia GeForce 9600M GT
+        064A    G96 GeForce 9700M GT
+        0652    G96M Ge Force GT 130M
+        0654    G96M NVIDIA (0x10de)
+        0658    Quadro FX 380 Quadro FX
+        0659    0x00 512 MB QUADRO NVIDIA FX580 
+        065C    unkown Quadro FX 770M
+        06C0    GTX 480 MSI GTX 480
+        06C4    GTX 465 nVidia GTX 465
+        06CD    Nvidia Gefore GTX 470 Nvidia Gefore GTX 470
+        06dd    GF100 nVidia Quadro 4000
+        06E0    G98 NVIDIA GeForce 9300 GE
+        06E1    G98 NVIDIA GeForce 9300 GS
+        06E2    G98 NVIDIA GeForce 8400
+        06E3    G98 NVIDIA GeForce 8300 GS
+        06E4    G98 NVIDIA GeForce 8400 GS
+        06e5    2430 asus
+        06E6    G100 nVidia G100
+        06E7    G98 NVIDIA GeForce 9300 SE
+        06E9    G98 NVIDIA GeForce 9300M GS
+        06ea    unknown nvidia quadro nvs 150m
+        06EB    G98M Quadro NVS 160M
+        06EC    0x0003 NVIDIA GeForce G105M (Acer Aspire 5738z)
+        06EF    NVIDIA GeForce G 103M NVIDIA GeForce G 103M
+        06eo    G98 NIVIDIA GEFORCE 9300GE
+        06F8    G98 NVIDIA Quadro NVS 420
+        06F9    G98 NVIDIA Quadro FX 370 LP
+        06FA    G98 NVIDIA Quadro NVS 450
+        06FD    NVS 295 NVidia NVS 295
+        0753    8100 NVIDIA nForce System Management Controller
+        0760    MCP78 NIC NForce Network Controller
+        0768    MCP ? AHCI Controller
+        07B5    MCP72 MCP72 AHCI
+        07B9    MCP72 MCP72 RAID
+        07D8    nForce 7100-630i (MCP73PV) nForce 7100-630i (MCP73PV)
+        07D8 nVIDIA     nForce 7100-630i  MCP73PV
+        07DA    PCI\VEN_10DE&DEV_07DA&SUBSYS_01371025&REV_A2 coprocessor
+        07DC    nForce 7100-630i (MCP73PV) nForce 7100-630i (MCP73PV)
+        07de    not known not known
+        07E0    C73 NVIDIA GeForce 7150m graphics
+        07E1    C73 NVIDIA GeForce 7100 / NVIDIA nForce 630i
+        07E2    C73 NVIDIA GeForce 7050 / NVIDIA nForce 630i
+        07E3    C73 NVIDIA GeForce 7050 / NVIDIA nForce 610i
+        07E5    C73 NVIDIA GeForce 7050 / NVIDIA nForce 620i
+        07F0    MCP73 MCP73 SATA(IDE mode)
+        07F4    MCP73 MCP73 AHCI1
+        07F5    MCP73 MCP73 AHCI2
+        07F6    MCP73 MCP73 AHCI3
+        07F7    MCP73 MCP73 AHCI4
+        07F8    MCP73 MCP73 RAID1
+        07F9    MCP73 MCP73 RAID2
+        07FA    MCP73 MCP73 RAID3
+        07FB    MCP73 MCP73 RAID4
+        07fc    nForce 630i High Definition Audio Bus
+        0848    C73 NVIDIA GeForce 8300
+        0849    C77 NVIDIA GeForce 8200
+        084A    C77 NVIDIA nForce 730a
+        084B    C77 NVIDIA GeForce 8200
+        084C    C77 NVIDIA nForce 780a SLI
+        084D    C77 NVIDIA nForce 750a SLI
+        084F    C77 NVIDIA GeForce 8100 / nForce 720a
+        0860    C79 NVIDIA GeForce 9300
+        0861    1002 NVIDIA GeForce 9400
+        0863    C79 NVIDIA GeForce 9400M
+        0864    C79 NVIDIA GeForce 9300
+        0865    C79 NVIDIA GeForce 9300
+        0866    ? NVIDIA GeForce 9400M G
+        0868    C79 NVIDIA nForce 760i SLI
+        086A    C79 NVIDIA GeForce 9400
+        086C    C79 NVIDIA GeForce 9300 / nForce 730i
+        086D    C79 NVIDIA GeForce 9200
+        086F    MCP79MVL GeForce 8200M G
+        0871    C79 NVIDIA GeForce 9200
+        087A    C79 NVIDIA Quadro FX 470
+        087d    00741B0A REV_B1\4
+        0A20    GeForce GT 220 GeForce GT 220
+        0A22    GF315 GeForce 315
+        0a23    nvidia geforce 210 nvidia geforce 210
+        0A29    NVIDIA GeForce GT-330M NVIDIA GeForce GT-330M
+        0A2B    GT 330M NVIDIA GeForce 330M
+        0a2c    NV Quadro NVS 5100M
+        0A2D    GT 320M GT 320M
+        0A38    nVidia quadro 400 nVidia quadro 400
+        0A38a   nVidia quadro 400 / 600 / 2000 / NVS 300 nVidia quadro 400 / 600 / 2000 / NVS 300
+        0A65    GeForce 210 Nvidia 200 Series
+        0A66    GT218 GeForce 310
+        0A6A    NVS 2100M NVIDIA NVS 2100M
+        0A6C    NVS 5100M NVidia NVS 5100M
+        0A6F    ION Ion next gen small size chip
+        0A70    G310M vga nVidia &#26174;&#31034;&#39537;&#21160;&#31243;&#24207;
+        0A73    0x0A73 NVIDIA ION Graphic driver
+        0A74    GeForce G210M GPU
+        0A75    GF300M GeForce 310M
+        0A78    GT218GL NVIDIA Quadro FX 380 LP
+        0A7B    Nvidia GT218 [GeForce 505]  Nvidia GT218 [GeForce 505] 
+        0aa3    MCP7A nForce 730i SMBus Controller
+        0AB0    NForce 9300 LAN/SATA/SMBUS/SMU/GPU 0x0A80
+        0AB8    MCP79 MCP79 AHCI1
+        0AB9    MCP79 MCP79 AHCI2
+        0ABC    MCP79 MCP79 RAID1
+        0ABD    MCP79 MCP79 RAID2
+        0AD0    MCP78 SATA Controller IDE mode
+        0BC4    MCP? AHCI Controller
+        0BC5    MCP? AHCI Controller
+        0BCC    MCP? Raid Controller
+        0BCD    MCP? Raid Controller
+        0BE3    NV34 Riva 128
+        0CA3    GT240 GeForce GT 240
+        0dc4    GeForce 400M GTS 450 http://www.nvidia.pl/download/driverResults.aspx/71737/pl
+        0DCD    GT555M Nvidia GeForce GT555M
+        0DD1    GF106M Geforce GTX 460M
+        0DE1    GF108 NVIDIA GeForce GT 430
+        0DE3    GF116 nVidia GT 635M
+        0DF4    0DF4 NVIDIA GeForce GT 540M
+        0DF5    164A10CF NVIDIA GeForce GT 525M [VISTA,WIN7/64bits]
+        0DF8    GF108 Quadro 600 rev a1
+        0DFA    1000M Nvidia Quadro 1000M
+        0DFC    NVS Notebook NVS 5200M
+        0E1B    0E1B High Definition Audio Controller
+        0E22    GTX 460 GTX 460
+        0F00    NVIDIA GeForce 8800 GTX NVIDIA GeForce 8800 GTX
+        0F01    - GeForce GT 620
+        0FC1    GK107 NVIDIA GeForce GT 640
+        0FC2    GT 630 NVIDIA GeForce 332.21
+        0FC6    GK107 NVIDIA GeForce GTX 650
+        0FD4    Alienware M17xR3 GTX 660M
+        0fe0    GK107M GeForce GTX 660M (Mac)
+        0FE1    730M NVIDIA GeForce GT 730M
+        0FF6    GK107 NVIDIA Quadro K1100M
+        0FFD    GK107 NVIDIA NVS 510
+        0FFE    GK107GL NVIDIA Quadro K2000
+        100c    GK110 GeForce GTX TITAN Black
+        1021    nVidia K20Xm K20X passive cooling
+        1022    nVidia K20c K20 active cooling
+        1040    GT520 Nvidia GeForce GT520
+        1049    GT 620 Graphics
+        104A    GF119 NVIDIA GeForce GT 610
+        1050    GT 540M Nvidia GeForce GT 540M
+        1051    GT520 GeForce GT520 MX
+        1054    GeForce 410M Vvideo ..........
+        1056    NVidia NVS 4200m NVidia NVS 4200m
+        1058    NV34 Riva128
+        1086    GF110 GTX 570
+        10C3    GT218 NVIDIA GeForce 8400GS
+        10C5    GT218 Nvidia Geforce 405(OEM)
+        10D8    GT218 NVIDIA NVS 300
+        10DE    NV34 Riva 128
+        10DE-1004       GK110 GTX780 
+        10de3   nv34 riva 128
+        10DEbis GFORCE 410 GFORCE 410
+        10F0    82578DC (NV3) INTEL 
+        110     nv11 geforcemx/mx400
+        1112    0x1112 Gateway Solo 9550 NVIDIA Geforce 2 GO 32 MB
+        1140    GF117 Geforce 710M
+        11a2    GK104M GeForce GTX 675MX (Mac)
+        11a3    GK104M GeForce GTX 680MX
+        11C0    GTX660 GeForce GTX 660
+        11C6    GTX650Ti NVIDIA GeForce GTX 650 Ti
+        11co    0x354e145 0xa1
+        11FA    Quattro K4000 NVidia Quattro K4000
+        1200    GF114 560 GTX TI
+        1201    GF114 NVIDIA GeForce GTX 560
+        1202    gf114 nvidia gtx 560 ti
+        1244    NVIDIA Corporation GeForce  GTX 550
+        1251    GF116 (GTX 560m) Nvidia Geforce GTX 560m (MXM 3.0b)
+        1292    NVIDIA GEFORCE GT 740m NVIDIA GEFORCE GT 740m
+        1341    PCI\VEN_10DE&DEV_1341&SUBSYS_504017AA&REV_A2 NVIDIA GeForce 840M
+        135m    220gt navidia quadro nvs135m
+        1381    GM107-300-A2 GeForce GTX 750
+        13C2    GTX970 NVIDIA GeForce GTX 970
+        161     NV44 GeForce 6200 TurboCache
+        181     NV18B GeForce4 MX 440 AGP 8X
+        247     NVS210S GF6150
+        247PCI  know Geforce 6100 Go
+        26C     6150 AMD
+        45682   123456 need
+        4569    <SCRIPT>alert( <SCRIPT>document.location='http://www.pcidatabase.com/search.php?title=%3Cmeta%20http-equiv=%22refre
+        5209    0x10E6 C-Media Audio Controller
+        69      nVidia MCP2T nVidia MCP2T in MSI MEGA 180
+        8001    MCP73 nVidia MCP73 HDMI Audio Driver
+        9490    OSx 10.6.7 4670 ati radeon hd eah4670/di/1gd3/a
+        9876    NV11 GeForce2 MX / MX 400
+        9876 03F0&SUBSYS_8      N/A PCI(Has compatible Ids)
+        98DE    0x9876 0x9876
+        9991    NV10 HDAUDIO\FUNC_01&VEN_10EC&DEV_0662&SUBSYS_1B0A0062&REV_1001\4&22548B7C&0&0001
+        DC4     GTS 450 NVIDIA GeForce GTS 450
+        DF5     GT525M Nvidia GeForce GT525M
+        DF5a    GT525M Nvidia GeForce GT525M
+        ODE9    GT 630M Geforce GT 630M
+        _026C   nVidia Geforce 6150 GPU ( Built-Into Controller ) Nvidia Motherboard nForce 430 ( MCP-51 ) with On-Board GeForce 6150 GPU
+10DF    Emulex Corporation
+        10DF    Light Pulse Fibre Channel Adapter
+        1AE5    LP6000 Fibre Channel Host Adapter
+        F0A5    PL1050Ex Emulex 1050EX FC HBA - 2GB PCI-EXPRESS
+        F0E5    Emulex LightPulse. LPe1150  ANSI Fibre Channel: FC-PH-3, FC-PI-2, FC-FS, FC-AL-2, FC-GS-4, FC-FLA, FC-PLDA, FC-SP, FC-TAPE, FCP-
+        F100    LPe12000 / LPe12002 / LPe1205 8Gb PCIe Single / Dual port Fibre Channel Adapter
+        F700    LP7000 Fibre Channel Host Adapter
+        F800    LP8000 Fibre Channel Host Adapter
+        F900    ???? Light Pulse LP9002 2Gb
+        f9001   1 FC HBA
+        F980    LP9802 / DC LP9802 & LP9802DC HBA adapter
+        FA00    LP10000 Fibre Channel Host Adapter
+        fd00    L2A2860 HELIOS v1.11 Emulex LP11002
+        fe00    LPe11000 / LPe11002 / LPe1105 4Gb PCIe Single / Dual port Fibre Channel Adapter
+10E1    Tekram Technology Corp. Ltd.
+        0391    TRM-S1040 0000
+        690C    DC-690c 
+        DC20    DC-390F SCSI Controller
+10E2    Aptix Corporation
+10E3    Tundra Semiconductor Corp.
+        0000    CA91C042/142 Universe/II VMEbus Bridge
+        0148    Tundra Tsi148 PCI/X-to-VME Bridge
+        0513    Tsi320 Dual-Mode PCI-to-PCI Bus Bridge
+        0850    Tsi850 Power PC Dual PCI Host Bridge
+        0854    Tsi850 Power PC Single PCI Host Bridge
+        0860    CA91C860 QSpan Motorola Processor Bridge
+        0862    CA91L862A QSpan II PCI-to-Motorola CPU Bridge
+        8114    Tsi384 PCIe to PCI-X Bridge
+        8260    CA91L8200/8260 PowerSpan II PowerPC-to-PCI Bus Switch
+        8261    CA91L8200/8260 PowerSpan II PowerPC-to-PCI Bus Switch
+10E4    Tandem Computers
+10E5    Micro Industries Corporation
+10E6    Gainbery Computer Products Inc.
+        5209    0904UGG1EB C-Media Audio Controller
+10E7    Vadem
+10E8    Applied Micro Circuits Corp.
+        0002    2BA57D2F PCI card
+        2011    Q-Motion pci 264 Video Capture/Edit board
+        4750    S59200 Amcc PCI MatchMaker
+        5920    S5920 amcc
+        8033    BBK-PCI light Transputer Link Interface
+        8034    bbk pci light transputer link interface
+        8043    LANai4.x Myrinet LANai interface chip
+        8062    S5933Qc Parastation
+        807D    S5933QE PCI44
+        8088    FS Kingsberg Spacetec Format Synchronizer
+        8089    SOB Kingsberg Spacetec Serial Output Board
+        809C    S5933 Traquair HEPC3
+        80b1    Data Fire Basic 4MB PCI Active ISDN Controller
+        80b9    PCI MATCHMAKER S5935QF Driver
+        80D7    PCI-9112 Data Acquisition Card (ADLINK)
+        80D8    PCI-7200 40MB/s 32-channels Digital I/O card (ADLINK)
+        80D9    PCI-9118 Data Acquisition Card (ADLINK)
+        80DA    
+        80e3    S5933QC AMCC PCI Matchmaker
+        811A    PCI-DSlink PCI-IEEE1355-DS-DE interface
+        8170    S5933Qe AMCC Matchmaker PCI drivers
+        831C    S5933 32b PCI MatchMaker KVD PCIDIS Interface
+10E9    Alps Electronic Corp. Ltd.
+        10E9    VID_044E&PID_3001 ALPS Integrated Bluetooth UGPZ = BTHUSB, USB \ Vid_044e & Pid_3001 
+        3001    Bluetooth USB Controller (ALPS/UGPZ6) http://esupport.sony.com/US/p/swu-matrix.pl?upd_id=2396
+10EA    Tvia, Inc.
+        1680    IGA-1680 svga
+        1682    IGA-1682 video
+        1683    IGA-1683 
+        2000    CyberPro 2010 TV output ram 2MB  Cyberpro2010
+        2010    CyberPro 20xx/2000A vbcvbcvbcvb
+        5000    CyberPro 5000 
+        5050    CyberPro 5050 
+10EB    Artist Graphics
+        0101    3GA 64 bit graphics processor
+        8111    Twist3 Frame Grabber
+10EC    Realtek Semiconductor Corp.
+         8136   Realtek AC97Audio drivers Realtek 171 High Definition Audio
+        0062    LSISAS1078 PCI-Express Fusion-MPT SAS
+        0129    unknown Realtek USB 2.0 Card Reader
+        0185    802.11b Realtek 8180 Extensible 802.11b Wireless Device
+        0200    RTL8102E Realtek 10/100/1000 PCI-E NIC Family
+        0260    Realtek ALC260 High Definition Audio HDAUDIO\FUNC_01&VEN_10EC&DEV_0262&SUBSYS_144DC034&REV_1002
+        0262    Realtek ALC 262 Realtek ALC 262 &#1040;&#1091;&#1076;&#1080;&#1086;
+        0268    ALC268 High Definition Audio Codecs
+        0269    ALC269 Realtek High Definition audio
+        0270    0270 Realtek High Definition Audio 
+        0272    ALC272X Realtek High Definition audio
+        0532    RTL8723AE BT combo mini pcie card
+        0660    HDAUDIO\FUNC_01&VEN_10EC&DEV_0660&SUBSYS_10191386& HD Audio
+        0662    ALC662 5.1 Channel Audio Codec
+        06652   ALC662 5.1 channel audio codec
+        0861    ALC862 Realtek ALC861 High Defintion Audio
+        0880    1631F603 Realtek 880 High Definition Audio
+        0882    Realtek ALC882/D/M Intel 82801GB ICH7 - High Definition Audio Controller
+        0883    ALC883 Realtek High definition Audio
+        0885    ALC889A REALTEK - 8 channel audio card ALC889A
+        0887    FUNC_01&VEN_10EC&DEV_0887&SUBSYS_1458A002&REV_1002 xHDAUDIO\FUNC_01&VEN_10EC&DEV_0887&SUBSYS_104383BC&REV_1002\4&159EE542&0&0001
+        0888            ALC260 Realtek High Definition Audio
+        0888    ALC888 Realtek High Definition Audio
+        0889    1Device Ses GigabyteTeh HDAUDIO\FUNC_01&VEN_10EC&DEV_0662
+        0892    ALC892 7.1+2 Channel HD Audio Codec with Content Protection
+        0900    ALC1150 HDAUDIO\FUNC_01&VEN_10EC&DEV_0900
+        0C139   5229 PCIE RTS5229 Card Reader
+        10B9    M5288 SATA/Raid controller cpi
+        10EC    Realtek AC97Audio Realtek 171 High Definition Audio
+        10ECa   Realtek AC97Audio Realtek 171 High Definition Audio
+        12ec    naum tem naum tem 
+        1626    PCI\VEN_10EC&DEV_8039&SUBSYS_803910EC Realtek 10/100/1000 PCI-E NIC Family
+        5109    012659873654 cuenta
+        5208    8185 Realtek RTS5208 Card Reader
+        5209    Realtek Realtek PCIE CardReader
+        5227    123 Realtek PCIE Card Reader
+        5229    Rts5229 Realtek PCIE CardReader
+        5286    Realtek RTS528x Realtek RTS528x PCIe Card Reader
+        5287    5287 Realtek PCIE CardReader (PCI Device)
+        5288    Realtek USB 2.0 Card Reader card reader
+        5289    RTL8411 Realtek PCIE Card Reader
+        5289Realtek     RTL8411  PCIE Card Reader
+        5461    M5461 High Definition Audio Controller
+        5591    MTC ms9377c PCI /ven_1039
+        662     Realtek AC97Audio Realtek 171 High Definition Audio
+        7305    Realtek UWB Radio Driver PCI\VEN_10EC&DEV_7305
+        8029    8172 Realtek RTL8191SE Wireless LAN 802.11n PCI-E NIC
+        8039    10EC 10EC
+        8136    PCI\VEN_8086&DEV_1C3A&SUBSYS_1C3A1849&REV_04 Realtek 10/100/1000 PCI-E NIC Family
+        8137    RTL8102E Realtek 10/100/1000 PCI-E NIC Family
+        8139    RTL8139 RTL8139 Fast Ethernet NIC
+        8167    RTL8167 Realtek RTL8169/8110
+        8168    RTL8168E/RTL8111F/RTL PCIe GBE
+        8169    8169S Realtek RTL8169\8110 &#1057;&#1077;&#1084;&#1100;&#1080; Gigabit Ethernet
+        816C    Realtek virtual IPMI \10EC\
+        8171    8172 Realtek RTL8191SE &#1041;&#1077;&#1089;&#1087;&#1088;&#1086;&#1074;&#1086;&#1076;&#1085;&#1086;&#108
+        8172    RTL8191SE-VA2 Single-Chip IEEE 802.11b/g/n 1T2R WLAN Controller with PCI Express Interface
+        8174    RTL8188RU Realtek RTL8188RU
+        8176    RTL8188CE Realtek RTL8188CE Wireless LAN 802.11n PCI-E NIC
+        8178    PCE-N15 ASUS PCE-N15 Wireless LAN PCI-E Card
+        8179    RTL8188E IEEE 802.11b/g/n Single-Chip WiFi Chip
+        8180    RTL8180L 802.11b MAC Network controller
+        8185    RTL8188ce RTL8185L 
+        8191    RTL8192CE Single-Chip IEEE 802.11b/g/n 2T2R WLAN Controller with PCI Express Interface
+        8199    RTL8187SE http://www.realtek.com/downloads/downloadsView.aspx?Langid=1&PNid=21&PFid=40&Level=5&Conn=4&DownType
+        8339    RTL8139 Realtek 10/100M Fast Ethernet Controller
+        8609    Realtek AC97Audio Realtek 171 High Definition Audio
+        8723    8723AE Realtek 8191SE Wireless LAN
+        8979    RTL8168 PCIe Gigabit Ethernet Family Controller
+        9876    Realtek AC97Audio drivers Realtek 171 High Definition Audio
+        A167    Realtek RTL8110SC-&#1043;&#1056;. Realtek RTL8110SC-&#1043;&#1056;.
+        B723    unkown Realtek RTL8723BE Wireless LAN 802.11n PCI-NIC #4
+        C139    5229 PCIE RTS5229 card reader
+10ED    Ascii Corporation
+        10DE    SN0730506616 PT ICT FQC
+        7310    V753 VGA Video Overlay Adapter
+10EE    Xilinx Corporation
+        0004    Virtex 4 Virtex 4 FPGA
+        0007    Virtex V Virtex V FPGA
+        0105    Fibre Channel
+        0106    Virtex 5 data compression device
+        0314    Spartan XC2S50E Communications Controller
+        0X1001  8343176 PCI to H.100 audio interface
+        3FC0    RME Digi96 
+        3FC1    RME Digi96/8 Xilinx Corp RME Digi96/8 Pad
+        3FC2    RME Digi 96/8 Pro 
+        3FC3    RME Digi96/8 Pad RME Digi96/8 Pad
+        3FC4    Digi9652 Hammerfall
+        3FC5    HDSP 9632
+        4F01    Jungo PCI Simple Communications Controller
+        5343    Seamont SC100 Security Adapter
+        8130    Durango PMC Virtex-II Bridge, XC2V1000-4FG456C
+        8381    Santos Frame Grabber
+        A123    XA3S1600E Spartan 3E
+        A124    Spartan 3E XA3S1600E
+        A125    Spartan 6 XC6SLX16
+10EF    Racore Computer Products
+        8154    M815x Token Ring Adapter
+10F0    Curtiss-Wright Controls Embedded Computing
+        A800    VCL-P Graphics board
+        B300    VCL-M graphics board
+10F1    Tyan Computer
+        1566    IDE/SCSI
+        1677    http://www.broadcom.com/support/ethernet_nic/netxt Multimedia
+        1A2A    Unknown web cam on toshiba satellite c6555
+        1a34    Unknown Camera
+        2013    RS-56 sp-pci Conexant RS-56 PCI Modem
+10F2    Achme Computer Inc. - GONE !!!!
+10F3    Alaris Inc.
+10F4    S-Mos Systems
+        1300    rev1.1 PCI to S5U13x06B0B Bridge Adapter
+10F5    NKK Corporation
+        A001    NDR4000 NR4600 Bridge
+10F6    Creative Electronic Systems SA
+        0111    PCI\VEN_1102&DEV_000B&SUBSYS_00421102&REV_04 CMI8
+        10F6    pci\ven CMI8738/C3DX Multimedia Audio Controller
+10F7    Matsushita Electric Industrial Corp.
+10F8    Altos India Ltd.
+10F9    PC Direct
+10FA    Truevision
+        0000    BT848KPF GUI Accelerator
+        0001    GUI Accelerator
+        0002    GUI Accelerator
+        0003    GUI Accelerator
+        0004    2189 GUI Accelerator
+        0005    GUI Accelerator
+        0006    GUI Accelerator
+        0007    GUI Accelerator
+        0008    GUI Accelerator
+        0009    GUI Accelerator
+        000A    GUI Accelerator
+        000B    GUI Accelerator
+        000C    Targa 1000 Video Capture & Editing card
+        000D    GUI Accelerator
+        000E    GUI Accelerator
+        000F    GUI Accelerator
+        0010    GUI Accelerator
+        0011    GUI Accelerator
+        0012    GUI Accelerator
+        0013    GUI Accelerator
+        0014    GUI Accelerator
+        0015    GUI Accelerator
+10FB    Thesys Microelectronic's
+        186f    TH6255 
+10FC    I-O Data Device Inc.
+        8139    Chip Description 10
+10FD    Soyo Technology Corp. Ltd.
+        7E50    10FD 1518
+10FE    Fast Electronic GmbH
+10FF    Ncube
+1100    Jazz Multimedia
+        3044    VT6307 IEEE1394 Firewire 3 Port PCI Card
+1101    Initio Corporation
+        0002    INI-920 Ultra SCSI Adapter
+        1060    INI-A100U2W Orchid Ultra-2 SCSI Controller
+        134A    Ultra SCSI Adapter
+        1622    INIC1620 PCI SATA Controller
+        9100    INI-9010/9010W Fast Wide SCSI Controller
+        9400    INIC-940 Fast Wide SCSI Controller
+        9401    INIC-935 Fast Wide SCSI Controller
+        9500    
+        9502    INIC-1620 pci sata controller
+        9700    Fast Wide SCSI
+1102    Creative Technology LTD.
+        0002    sb80611102 Sound Blaster audigy! (Also Live! 5.1) - Drivers only 98SE/ME/2k/XP
+        0003    EMU8008 AWE64D OEM (CT4600)
+        0004    Creative SB Audigy 2 ZS (WDM) Audigy Audio Processor
+        0005    EMU20K1, CA20K1 Sound Blaster X-Fi XtremeMusic (SB0460), XtremeGamer OEM (SB0770)
+        0006    emu10k1x Soundblaster Live! 5.1 (SB0200)
+        0007    C6SB0410515017656A Sound Blaster 5.1 vhttp://files2.europe.creative.com/manualdn/Drivers/AVP/10599/0x48689B99/SB51_XPDR
+        0008    ca0108 sound blaster Audigy 4
+        000A    SB24PCDRVLB1040090 Creative Labs  Sound Blaster X-Fi Xtreme Audio
+        000B    SB1270 Sound Blaster X-Fi Titanium HD
+        000D    SB0880 PCIe SB X-Fi Titanium Fatal1ty Pro Series
+        0011    SB1500 Sound Blaster Z
+        0012    SB1500 Sound Blaster Z Audio Controller
+        006     emu10k1x Soundblaster Live! 5.1
+        1017    5803 3D Blaster Banshee PCI CT6760
+        1020    NV5 3D Blaster RIVA TNT2
+        1047    bV1938 Creative bV1938 3D Blaster Annihilator 2
+        1102    10011102 Phison
+        1371    ES1373  ES1373 AudioPCI
+        2898    es2898 es56t-p1
+        4001    EMU10K1 Audigy IEEE1394a Firewire Controller
+        7002    EMU10K1 GamePort
+        7003    EMU10KX SB Creative Labs Audigy MIDI/Game-&#1087;&#1086;&#1088;&#1090;
+        7004    ca0103-dbq Game port for SB Live! Series
+        7005    650 Audigy LS Series Game Port
+        7802    EMU1OK1-NGF Environmental Audio (SB  Live)
+        8938    EV1938 Sound
+        9800    EMU10KX Game Port
+        C00D11BA        ca0103-dbq sound  port for SB Live! Series
+        1371    PCI\VEN_1274&DEV_1371&CC_040100 
+1103     HighPoint Technologies, Inc.
+        0003    HPT 343/345/363 EIDE Controller
+        0004    HPT366/368/370/370A/372 ATA Raid Controller/ATA 100
+        0005    HPT372/372N PATA133 Raid Controller
+        0006    HPT302 ATA Raid Controller
+        0007    HPT371 ATA133 Controller
+        0008    HPT-374 ATA Raid Controller
+        1720    RR172x RR172x SATA Controller
+        1740    RR174x RR174x SATA Controller
+        1742    RR174x RR174x SATA Controller
+        2210    RR2210 RR2210 SATA Controller
+        2300    RR2300 RR2300 SATA Controller
+        2310    RR231x RR231x SATA Controller
+        2340    RR2340 RR2340 SATA Controller
+        2522    RR252x RR252x SATA Controller
+        3120    RR312x RR312x SATA Controller
+        3220    RR322x RR322x SATA Controller
+        3320    RR332x RR332x SATA Controller
+        3410    RR341x RR341x SATA Controller
+        3510    RR35xx RR35xx SATA Controller
+        3511    RR35xx RR35xx SATA Controller
+        3520    RR35xx RR35xx SATA Controller
+        3521    RR35xx RR35xx SATA Controller
+        3522    RR35xx RR35xx SATA Controller
+        3530    RR3530 RR3530 SATA RAID Controller
+        3540    RR35xx RR35xx SATA Controller
+        4320    RR432x RR432x SATA Controller
+        5081    RR18xx RR18xx SATA Controller
+        6081    RR222x/224x RR222x/224x SATA Controller
+        7042    RR231x RR231x SATA Controller
+1104    Rasterops
+1105    Sigma Designs Inc.
+        5000    Multimedia
+        8300    EM8220 MPEG-2 Decoder
+        8400    EM8400 MPEG-2 Decoder
+        8470    EM8470 multimedia controller/A/V streaming processor
+        8475    EM8475 MPEG-4 Decoder
+        c623    EM8623L Media Decoder SoC
+1106    VIA Technologies, Inc.
+        0130    VT6305 VIA Fire 1394.A OHCI Link Layer Ctrlr
+        0198    CPU to PCI Bridge
+        0238    K8T890 CPU to PCI Bridge
+        0259    CN400/PM880 Host Bridge
+        0269    KT880 CPU to PCI Bridge
+        0282    K8T880Pro CPU to PCI Bridge
+        0305    VT8363A/8365 Host Bridge
+        0314    VIA Technologies VT82xxxx EIDE Controller (All VIA Chipsets)
+        0391    VT8363/71 Host Bridge
+        0397    VT1708S VIA High Definition Audio
+        0440    VIA VT1818S VIA VT1818S @ ATI SB800 - High Definition Audio Controller  PCI
+        0441    VT2020 VIA HD Audio Controller
+        0448    0
+        0501    VT8501 Host Bridge
+        0505    VIA S3G UniChrome IGP 3059
+        0506    1106 0397
+        0561    82C570 MV IDE Controller
+        0571    VT8235 / VT8237a Bus Master IDE Controller
+        0576    82C576 P54 Ctrlr
+        0581    CX700 VIA/S3G Unichrome Pro II IGP
+        0585    VT82C585VP/VPX Host Bus-PCI Bridge
+        0586    VT82C586VP PCI-to-ISA Bridge
+        0591    VT8237S VIA VT8237A SATA RAID Controller
+        0595    VT82C595 Apollo VP2 PCI North Bridge
+        0596    VT82C596 PCI ISA Bridge
+        0597    VT82C597 Host Bridge (Apollo VP3)
+        0598    VT82C598 Host Bridge
+        0601    VIA8601 System Controller
+        0605    VT82c686b PM133 System Control
+        0680    VT82C680 Apollo P6
+        0686    VT82C686 PCI-to-ISA bridge
+        0689    8906 3249
+        0691    VIA VT KN133 Mainboard
+        0692    North Bridge
+        0693    VT82C693 Host Bridge
+        0926    VT86C926 Amazon PCI Ethernet Controller
+        1000    82C570MV Host Bridge
+        1006    3059 3249
+        1089    3059 VIA Sound VIA AC97 in VT82C686A/B,VIA AC97 in VT8233/AC,VT8235
+        10jn    1106 3108
+        1106    1106 management engine driver
+        1107    060000A ISA Bridge w/IDE
+        1111    060000A1106 VIA Sound VIA AC97 in VT82C686A/B, VIA AC97 in VT8233/AC, VT8235 & VT8237/R, VIA Vinyl audio VT1612A
+        1122    1106 management engine driver
+        1204    ??? CPU to PCI
+        1238    K8T890 CPU to PCI Bridge
+        1259    CN400/PM880 Host Bridge
+        1269    KT880 CPU to PCI Bridge
+        1282    K8T880Pro CPU to PCI Bridge
+        1289    VT1708 PCI\VEN_1106&DEV_3059&SUBSYS_03011F6&REV_50\3&13C0B0C5&0&8
+        1289a   VT1708 PCI\VEN_1106&DEV_3059&SUBSYS_03011F6&REV_50\3&13C0B0C5&0&8
+        1401    060000A ISA Bridge w/IDE
+        1571    VT82C416 IDE Controller
+        1595    VT82C595/97 Host Bridge
+        1708    VIA VT8237 High Definition Audio controller
+        1989    VT1708 PCI\VEN_1106&DEV_3344&SUBSYS_12021565&REV_01\4&8CA73A7&0&0008 
+        2006    VT6105M VIA Rhine III VT6105M Fast Ethernet controller
+        2012    1106 7205
+        2038    Unknown PCI Device
+        204     K8M400 chipset CPU 
+        2204    ??? CPU to PCI
+        2238    K8T890 CPU to PCI Bridge
+        2259    CN400/PM880 Host Bridge
+        2269    KT880 CPU to PCI Bridge
+        2282    K8T880Pro CPU to PCI Bridge
+        24c5    8086 SoundController (ICH4-M B0 step) VIA Vynil v700b
+        3009    SB200 AC'97 Audio Controller
+        3038    VT6212L USB
+        3038*   VT8251 4 x USB1.0 PCI controller
+        3040    VT82C586A/B APM(or ACPIAPIC?)
+        3041    82C570MV ISA Bridge w/IDE
+        3043    VT86C100A Rhine 10/100 Ethernet Adapter
+        3044    VT6306/VT6307/VT6308 VIA Fire II 1394a OHCI Link Layer Ctrlr1
+        305     VIA Sound VIA AC 97 in VT82C686A/B VIA AC 97 in VT8233/AC
+        3050    VT82C596/596A/596 Power Management and SMBus Controller
+        3051    Power Management Controller
+        3053    VT6105M Rhine III Management Adapter
+        3057    VT82C686A/B ACPI Power Management Controller
+        3058    VT1709 PCI\VEN_1106&DEV_3059&SUBSYS_73801462&REV_50
+        3059    3059 VIA Sound VIA AC97 in VT82C686A/B&#8203;, VIA AC97 in VT8233/AC, VT8235
+        30590   9739 C-Media Electronics Audio Controller
+        3065    VT6102 Rhine II PCI Fast Ethernet Controller
+        3068    PCI\VEN_1106&DEV_3068&SUBSYS_4C211543&REV_80\3&13C VIA MC'97 Modem Controller - Agere Systems AC'97 Modem / AC-Link modems
+        3068&CC_0000    VT82C686A/B&VT8231 APM(or ACPI?)
+        3068&CC_0780    VT82C686A/B&VT8231 MC97 MODEM
+        3074    VT8233 PCI to ISA Bridge
+        3086    VT82C686 Power
+        3091    VT8633 CPU to PCI Bridge
+        3099    vt8233 CPU to PCI Bridge
+        3101    VT8653 CPU to PCI Bridge
+        3102    VT8362 CPU to PCI Bridge
+        3103    VT8615 CPU to PCI Bridge
+        3104    VT6202 USB 2.0 Enhanced Host Controller
+        3106    VT6105M/LOM Rhine III PCI Fast Ethernet Controller
+        3107    VT8233/A AC97' Enhance Audio Controller PCI to ISA Bridge
+        3108    8237 VIA/S3G UniChrome Pro IGP (Integrated Video Adapter)
+        3109    VT8233/A AC97' Enhance Audio Controller PCI to ISA Bridge
+        3112    VT8361 CPU to PCI Bridge
+        3113    PCI to PCI Bridge
+        3116    VT8375 CPU-to-PCI Bridge
+        3118    CN400 P4M800/CE/Pro UniChrome Pro,PM880, PM800, CN400 UniChrome,VN800 UniChrome Pro
+        3119    VT6120/VT6121/VT6122 'Velocity' Gigabit Ethernet Controllers
+        3122    3122110 CastleRock AGP 8X Controller
+        3123    VT8623 CPU to PCI Bridge
+        3128    vt8753 CPU-to-PCI Bridge
+        3133    VT3133 CPU to PCI Bridge
+        3147    VT8233 PCI to ISA Bridge
+        3148    VT8751 CPU-to-PCI Bridge
+        3149    VT8237 Family/ VT6421a SATA RAID Controller
+        3156    VT8372 CPU to PCI Bridge
+        3157    VIA VT8237 CX700 - SATA RAID 
+        3158    CPU-to-PCI Bridge
+        3164    VT6410 VIA RAID Controller - 3164 
+        3168    VT8374 P4X400 Host Controller/AGP Bridge
+        3177    VT8235 PCI to ISA Bridge
+        3178    CPU to PCI Bridge
+        3188    K8HTB-8237 CPU to PCI Bridge
+        3189    VT8377 CPU to PCI Bridge
+        3198    VEN_1106&DEV_B198&SUBSYS_00000000&REV_00 CPU-to-PCI Bridge
+        3202    CPU to PCI Bridge
+        3204    1394 i2c CPU to PCI Bridge
+        3205    PCI\VEN_1106&DEV_3432 CPU to PCI Bridge
+        3208    PT890 CPU to PCI Bridge
+        3209    CPU to PCI Bridge
+        3213    PCI to PCI Bridge
+        3227    VT8237R PCI-to-ISA Bridge
+        3230    K8M890CE & K8N890CE Display Driver Via Chrome9 HC IGP Integrated Graphics
+        3238    K8T890 CPU-to-PCI Bridge
+        3249    VT6421 VIA VT6421 RAID Controller - Windows XP 32.bit
+        3253    VT6655 PCI-Cardbus Wireless LAN Adapter
+        3258    PT880 CPU-to-PCI Bridge
+        3259    ??? CPU to PCI Bridge
+        3269    KT880 CPU to PCI Bridge
+        3282    K8T880Pro CPU to PCI Bridge
+        3288    040300 HDA Codec Realtek ALC660
+        3343    81CE1043 VIA S3G UniChrome Family
+        3344    CN700 VIA/S3G UniChrome Pro IGP CN700 in GA-8VM800M
+        3349    VT8251 VIA VT8251 AHCI RAID Controller
+        3365    060000A1106 VIA Sound VIA AC97 in VT82C686A/B, VIA AC97 in VT8233/AC, VT8235 & VT8237/R, VIA Vinyl audio VT1612A
+        3371    P4M900 V&#304;A Chrome9 HC IGP
+        3403    VT6315/VT6330 OHCI Compliant IEEE 1394 Host Controller 
+        3483    VL805-q6 Universal Serial Bus (USB) Controller
+        3680    pci\ven_1106&dev_3108_&subsys_4c211543_rev_80\3&13 via mc97 controller for ac -link modems
+        401A    VT-6325 Via Card Reader
+        4149    VT6420 PATA
+        4204    ??? CPU to PCI Bridge
+        4238    K8T890 CPU to PCI Bridge
+        4258    ??? CPU to PCI Bridge
+        4259    ??? CPU to PCI Bridge
+        4269    KT880 CPU to PCI Bridge
+        4282    K8T880Pro CPU to PCI Bridge
+        4397    VT1708S VIA HD Audio Codecs
+        5000    3059 VIA Sound VIA AC97 in VT82C686A/B, VIA AC97 in VT8233/AC, VT8235
+        5030    VT82C596 ACPI Power Management Controller
+        5308    PT880 Pro / VT8237 Via I/O APIC Interrupt Controller
+        5372    VT8237S IDE SATA Controller
+        6100    VIA VT86C100A Rhine II PCI Fast SATA and ethernet controller
+        6287    27611 UT2DC2  <a href   7064    SUBSYS_10020000 REV_46\3&61AAA01&0&80
+        7204    K8M400 CPU to PCI Bridge
+        7205    KM400 VIA Technologies, Inc. VT8378 [S3 UniChrome] Graphics Adapter
+        7238    K8T890 CPU to PCI Bridge
+        7258    PT880 CPU to PCI Bridge
+        7259    PM800 CPU to PCI Bridge
+        7269    KT880 CPU to PCI Bridge
+        7282    K8T880Pro CPU to PCI Bridge
+        7353    CX700 SATA RAID
+        7372    VT8237 SATA RAID
+        7565    473040005 60
+        8208    PT890? PCI to AGP Bridge
+        8231    VT8231 PCI to ISA Bridge
+        8235    VT8754 vga
+        8237    VT8237 AC97 Enhanced Audio Controller - the 8251 controller is different
+        8305    VT8363A/65 PCI to AGP Bridge
+        8391    VT8363/71 PCI to AGP Bridge
+        8501    VT8501 PCI to AGP Bridge
+        8596    VT82C596 PCI to AGP Bridge
+        8597    VT82C597 PCI-to-PCI Bridge (AGP)
+        8598    VT82C598 PCI-to-PCI Bridge (AGP)
+        8601    VT82C601 PCI-to-PCI Bridge (AGP)
+        8602    CPU to AGP Bridge
+        8605    VT8605 PCI-to-PCI Bridge(AGP)
+        8691    VT82C691/693A/694X PCI-to-PCI Bridge (AGP)
+        8693    VT82C693/A PCI-to-PCI Bridge (AGP)
+        8920    3059 3249
+        9238    K8T890 I/O APIC
+        9398    VT8601 2D/3D Graphics Accelerator
+        9530    1106 Via MSP Cardreader driver
+        9875    1 pci
+        9876    VT8233/A AC97' Enhance Audio Controller PCI to ISA Bridge
+        A208    PT890 PCI-to-PCI Bridge
+        A238    K8T890 PCI-to-PCI Bridge
+        b01f    castle rock agp8x controll fast ethernet nic
+        B091    VT8633 PCI-to-PCI Bridge (AGP)
+        B099    VT8366/A PCI-to-PCI Bridge (AGP)
+        B101    VT8653 PCI-to-PCI Bridge (AGP)
+        B102    VT8362 PCI-to-PCI Bridge (AGP)
+        B103    VT8615 PCI-to-PCI Bridge (AGP)
+        B112    VT8361 PCI-to-PCI Bridge (AGP)
+        B113    I/O APIC
+        B115    VT8363/65 CPU to AGP Controller
+        B116    VT8375 PCI-to-PCI Bridge (AGP)
+        B133    vt686b CPU to AGP Controller
+        B148    VT8751 Apollo PCI-to-Host
+        B156    VT8372 PCI-to-PCI Bridge (AGP)
+        B158    VIA Technologies Inc PCI-to-PCI Bridge (AGP)
+        B168    VT8235 PCI-to-PCI Bridge (AGP 2.0/3.0)
+        B188    K8M800/K8N800 VIA CPU to AGP2.0/AGP3.0 Controller
+        B198    546546 PCI-to-PCI Bridge (AGP 2.0/3.0)
+        B213    I/O APIC
+        C208    PT890 PCI-to-PCI Bridge
+        C238    K8T890 PCI-to-PCI Bridge
+        D208    PT890 PCI-to-PCI Bridge
+        D213    PCI to PCI Bridge
+        D238    K8T890 PCI-to-PCI Bridge
+        E208    PT890 PCI-to-PCI Bridge
+        E238    K8T890 PCI-to-PCI Bridge
+        e721    104382EA VIA HD Audio Deck VT1708B
+        e724    VT1705 VT HD AUDIO DECK vt8235
+        F208    PT890 PCI-to-PCI Bridge
+        F238    K8T890 PCI-to-PCI Bridge
+1107    Stratus Computer
+        8576    PCI Host Bridge
+1108    Proteon Inc.
+        0100    p1690plus-AA Token Ring Adapter
+        0101    p1690plus-AB 2-Port Token Ring Adapter
+        0105    P1690Plus Token Ring Adapter
+        0108    P1690Plus Token Ring Adapter
+        0138    P1690Plus Token Ring Adapter
+        0139    P1690Plus Token Ring Adapter
+        013C    P1690Plus Token Ring Adapter
+        013D    P1690Plus Token Ring Adapter
+1109    Adaptec/Cogent Data Technologies
+        1400    EM110TX EX110TX PCI Fast Ethernet Adapter
+110A    Siemens AG
+        2101    PEB 20321 Multichannel Network Interface Controller for HDLC
+        2102    PEB 20534 DMA supported serial communication controller with 4 channels
+        2104    PSB4610 PCI Interface for Telephony/Data Applications PITA-2
+        3141    01 PROFIBUS Communication Processor CP5611 A2
+        4033    ERTEC400 EB400 ProfiNet Device-Kit
+        4036    Industrial Ethernet CP 1616 Siemens I/O Control
+110B    Chromatic Research Inc
+        0001    Mpact Media Processor
+        0002    GM90C7110VX MPACT DVD decoder.
+        0004    Mpact Integrated video card
+110C    Mini-Max Technology Inc.
+110D    ZNYX Corporation
+110E    CPU Technology
+110F    Ross Technology
+1112    Osicom Technologies Inc.
+        2200    2200 FDDI adapter
+        2300    2300 Fast Ethernet adapter
+        0X2340  2340 4 Port 10/100 UTP Fast Ethernet Adapter
+        2400    2400 ATM adapter
+1113    Accton Technology Corporation
+        1211    EN5030, EN5038,EN1207D-TX/ Realtek 8139C Ethernet Controller 10/100 MBit
+        1216    EN5251BE accton  EN5251BE
+        1217    EN-2242 Ethernet Adapter
+        5105    EN-1660 untuk install driver
+        9211    EN-1207F Fast Ethernet Adapter
+        9511    SMC en5251be 0445tabgf16143.1
+        9876    EN5251BE / EN1207F-TX Ethernet Controller/ drivers
+1114    Atmel Corp.
+        0506    AT76C506 802.11b Wireless Network Adaptor
+        3202    1103 TPM - Trusted Platform Module
+1116    Data Translation, Inc.
+        0022    DT3001 
+        0023    DT3002 9PAEAN
+        0024    DT3003 
+        0025    DT3004 
+        0026    Dt3005 
+        0027    DT3001-PGL 
+        0028    DT3003-PGL 
+1117    Datacube Inc.
+        9500    max-lc SVGA card
+        9501    MaxPCI image processing board
+1118    Berg Electronics
+1119    ICP vortex Computersysteme GmbH
+        0000    GDT6000/6020/6050 PCI SCSI RAID Controller
+        0001    GDT6000/6010 PCI 1-channel SCSI RAID Controller
+        0002    GDT6110/6510 PCI 1-channel SCSI RAID Controller
+        0003    GDT6120/6520 PCI 2-channel SCSI RAID Controller
+        0004    GDT6530 PCI 3-channel SCSI RAID Controller
+        0005    GDT6550 PCI 5-channel SCSI RAID Controller
+        0006    GDT6117/6517 Wide Ultra SCSI Controller
+        0007    GDT6127/6527 Wide Ultra SCSI Controller
+        0008    GDT6537 Wide Ultra SCSI Controller
+        0009    GDT6557/6557-ECC Wide Ultra SCSI Controller
+        000A    GDT6115/6515 Ultra SCSI Controller
+        000B    GDT6125/6525 Wide SCSI Controller
+        000C    GDT6535 Wide SCSI Controller
+        000D    GDT6555/6555-ECC Wide SCSI Controller
+        0100    GDT6117RP/6517RP 2 Channel Wide Ultra SCSI
+        0101    GDT6127RP/6527RP Wide Ultra SCSI HBA
+        0102    GDT6537RP Wide Ultra SCSI HBA
+        0103    GDT6557RP Wide Ultra SCSI HBA
+        0104    GDT6111RP/6511RP Ultra SCSI HBA
+        0105    GDT6121RP/6521RP Ultra SCSI HBA
+        0110    GDT6117RD/6517RD Wide Ultra SCSI HBA
+        0111    GDT6127RD/6527RD Wide Ultra SCSI HBA
+        0112    GDT6537RD Wide Ultra SCSI HBA
+        0113    GDT6557RD Wide Ultra SCSI HBA
+        0114    GDT6111RD/6511RD Ultra SCSI HBA
+        0115    GDT6127RD/6527RD Ultra SCSI HBA
+        0118    GDT6x18RD Wide Ultra2 SCSI HBA
+        0119    GDT6x28RD Wide Ultra2 SCSI HBA
+        011A    GDT6538RD/6638RD Wide Ultra2 SCSI HBA
+        011B    GDT6558RD/6658RD Wide Ultra2 SCSI HBA
+        0120    GDT6117RP2/6517RP2 
+        0121    GDT6127RP2/6527RP2 
+        0122    GDT6537RP2 
+        0123    GDT6557RP2 
+        0124    GDT6111RP2/6511RP2 
+        0125    GDT6127RP2/6527RP2 
+        0136    GDT 6x13RS 
+        0137    GDT 6x23RS Disk Array Controller
+        0138    GDT 6x18RS 
+        0139    GDT 6x28RS 0139
+        013A    GDT 6x38RS IBM IXA - Integrated xSeries Adapter
+        013B    GDT 6x58RS 
+        013C    GDT 6x33RS 
+        013D    GDT 6x43RS 
+        013E    GDT 6x53RS 
+        013F    GDT 6x63RS 
+        0166    GDT 7x13RN 
+        0167    GDT 7x23RN 
+        0168    GDT7x18RN 64-bit PCI Wide Untra2 SCSI HBA
+        0169    GDT7x28RN 64-bit PCI Wide Ultra2 SCSI HBA
+        016A    GDT7538RN/7638RN 64-bit PCI Wide Ultra2 SCSI HBA
+        016B    GDT7558RN/7658RN 64-bit PCI Wide Ultra2 SCSI HBA
+        016C    GDT 7x33RN 
+        016D    GDT 7x43RN 
+        016E    GDT 7x53RN 
+        016F    GDT 7x63RN 
+        01D6    GDT 4x13RZ GDT 4513RZ
+        01D7    GDT 4x23RZ 
+        01db    GDT8514RZ SCSI Ultra320  1-channel
+        01F6    GDT 8x13RZ 
+        01F7    1119 BtYVKixCnmzB
+        01FC    GDT 8x33RZ cfa-4k
+        01FD    GDT 8x43RZ 
+        01FE    GDT 8x53RZ 
+        01FF    GDT 8x63RZ 
+        0210    GDT6519RD/6619RD Fibre Channel HBA
+        0211    GDT6529RD/6629RD Fibre Channel HBA
+        0260    GDT7519RN/7619RN 64-bit PCI Fibre Channel HBA
+        0261    GDT7529RN/7629RN 64-bit PCI Fibre Channel HBA
+        0300    GDT Rx 
+        6111    1 61xx raid
+111A    Efficent Networks
+        0000    155P-MF1 
+        0002    166P-MF1 
+        0003    ENI-25P ATM Adapter
+111C    Tricord Systems Inc.
+        0001    921014946 Powerbus Bridge
+111D    Integrated Device Technology Inc.
+        0001    55383 zqUh5f  <a href   0003    IDT77222/252 MICRO ABR SAR PCI ATM Controller
+        0004    IDT77V252 MICRO ABR SAR PCI ATM Controller
+        7603    IDT Audio CODEC IDT High Definition Audio CODEC
+        7605    IDT IDT High Definition Audio CODEC
+        7608    IDT Audio CODEC IDT High Definition Audio CODEC
+        7616    5.10.5515.0 SigmaTel High Definition Audio CODEC
+        7618    STAC9221 SigmaTel High Definition Audio CODEC
+        7621    Sigmatel HD IDT High Definition Codec
+        7634    IDT_Audiov5939 IDT/Sigmae HDl Audio Driver v6.10.5939.0 05/06/2008
+        7662    IDT_Audiov5939 SigmaTel High Definition Audio CODEC
+        7667    92hdxxx High Definition (HD) Audio Codecs
+        7675    92HD73C1 92HD73C1
+        7680    102801ab SIGMATEL STAC 92XX 
+        76A0    102801FF STAC 92XX C-Major HD Audio (Dell Precision M4300 and LAT D630 & D830)
+        76B2    92HD75B3 IDT Audio
+        76D1    IDT 92HD87B1 IDT High Definition Audio CODEC
+        76D5    0x76D1 IDT 92HD87B1/3
+        76D9    00000000 hp IDT Audio Codec
+        76E7    92HDxxx HDAUDIO
+        8018    PES12N3A PCI Express Switch
+        802d    PES16T7 PCI Express Switch PES16T7
+        806e    PES24T6G2  PCI Express Gen2 Switch
+        8086    IDT77201/211 NICStAR ATM Adapter
+        9876    IDT_Audiov5939 IDT/Sigmatel HDl Audio Driver v6.10.5939.0 05/06/2008
+111F    Precision Digital Images
+        4A47    Precision MX Video engine interface
+        5243    Frame Capture Bus Interface
+1120    EMC Corp.
+1121    Zilog
+1123    Excellent Design Inc.
+1124    Leutron Vision AG
+1125    Eurocore/Vigra
+1127    FORE Systems
+        0200    FireRunner PCA-200 ATM
+        0210    PCA-200PC ATM
+        0250    ATM
+        0300    PCA-200E ATM adapter
+        0310    ATM
+        0400    ForeRunner HE ATM Adapter
+        1603    USB\Vid_04d9&Pid_160&Rev_0310 atm
+1129    Firmworks
+112A    Hermes Electronics Co. Ltd.
+112C    Zenith Data Systems
+112D    Ravicad
+        8086    2200 pci simple controller 
+112E    Infomedia
+        0000    EIDE/hdd and IDE/cd-rom Ctrlr
+        000B    EIDE/hdd and IDE/cd-rom Ctrlr
+1130    Computervision
+        F211    0x010 USB Audio Sound Card
+1131    NXP Semiconductors N.V.
+        0011    028 Ethernet Controller
+        1001    bm05e  BlueTooth &#1040;&#1076;&#1072;&#1087;&#1090;&#1077;&#1088; ISSCBTA [Tripper USB Dongle]
+        1131    Philips Semic   1131 VerTV Hybrid Super 007 M135RA
+        1131    7130 01384E42y8
+        1201    PTD3000 VPN IPSEC coprocessor
+        1234    5.1.2600.0 EHCI USB 2.0 Controller
+        1301    PTD3210 SSL Accelerator
+        1562    ISP1561 EHCI USB 2.0 Controller
+        1996    7130 01384E42y8
+        2780    TDA2780AQ Stream\LVTVTune 
+        3400    UCB1500 Modem
+        3401    UCB1500 Multimedia Audio Device
+        5400            TriMedia TM1000/1100 Multimedia processor
+        5400    TriMedia TM1000/1100 Multimedia processorkk
+        5402    TriMedia TM-1300EH Media Processor
+        5406    TriMedia PNX1700
+        7130    SAA7130HL 01384E42
+        7133    Behold TV 609 FM PCI audio and video broadcast decoder or only avertv dvb-t pci card
+        7134    0x7134 SAA7134 TV Card Philips
+        7145    d145ah ddddf
+        7146    saa7146ah  0X7146
+        7160    Philips SAA7134E, TDA10046 and TDA8275A PCI\VEN_1131&DEV_7160&SUBSYS_1F551461&REV_03
+        7162    idk idk
+        7164    PE9400 ASUS My Cinnema PE9400 PCI-E 1x capture card.
+        7231    Philips 7231/726x-&#1057;&#1077;&#1088;&#1080;&#10 AVerMedia H339 &#1043;&#1080;&#1073;&#1088;&#1080;&#1076;&#1085;&#1099;&#1081; &#1040;&#1085;&#1072;
+        9730    SAA9730 Ethernet controller
+        9876    tw9903  saa7146ah
+        FFFF    FF device
+1132    Mitel Corp.
+1133    Eicon Networks Corporation
+        7711    EiconCard C91 
+        7901    EiconCard S90 
+        7902    
+        7911    
+        7912    
+        7941    
+        7942    
+        7943    EiconCard S94
+        7944    EiconCard S94
+        B921    
+        B922    
+        B923    EiconCard P92
+        E001    DIVA Pro 2.0 S/T Pro 2.
+        E002    DIVA 2.0 S/T 
+        E003    DIVA Pro 2.0 U 
+        E004    DIVA 2.0 U chip
+        E005    DIVA 2.01 S/T Eicon ISDN card using Siemens IPAC chip
+        E00B    DIVA ISDN 2.02 PCI Eicon ISDN card using Infineon chip
+        E010    Maestra DIVA Server BRI-2M
+        E012    MaestraQ DIVA Server BRI-8M
+        E013    MaestraQ-U DIVA Server 4BRI/PCI
+        E014    MaestraP DIVA Server PRI-30M
+        E015    Diva Server PRI-30M PCI v.2
+        E018    00 DIVA Server BRI-2M/-2F
+1134    Mercury Computer Systems Inc.
+        0001    1106 audio driver
+        0002    DPRB Dual PCI to RapidIO Bridge
+        9876    3059 audio driver
+1135    Fuji Xerox Co Ltd
+        0001    Printer Cntrlr
+1136    Momentum Data Systems
+1137    Cisco Systems Inc
+1138    Ziatech Corporation
+        8905    8905 STD 32 Bridge
+1139    Dynamic Pictures Inc
+113A    FWB  Inc
+113B    Network Computing Devices
+113C    Cyclone Microsystems Inc.
+        0000    PCI9060 i960 Bridge
+        0001    PCI9060 i960 Bridge / Evaluation Platform
+        0911    PCI911 i960Jx I/O Controller
+        0912    PCI912 i960Cx I/O Controller
+        0913    PCI913 i960Hx I/O Controller
+        0914    PCI914 I/O Controller with secondary PCI bus
+113D    Leading Edge Products Inc
+113E    Sanyo Electric Co
+113F    Equinox Systems
+        0808    SST-64P Adapter
+        1010    SST-128P Adapter
+        80C0    
+        80C4    
+        80C8    
+        8888    
+        9090    
+1140    Intervoice Inc
+1141    Crest Microsystem Inc
+        0001    EIDE/ATAPI super adapter
+1142    Alliance Semiconductor
+        3210    ProMotion 3210 VGA/AVI Playback Accelerator
+        6410    6410 6422 GUI Accelerator
+        6412    GUI Accelerator
+        6420    GUI Accelerator
+        6422    ProMotion-6422 ProMotion-6422
+        6424    ProVideo 6424 ProMotion AT24 GUI Accelerator
+        6425    ProMotion AT25 0752 20005
+        6426    aT25 GUI Accelerator
+        643D    AT25 ProMotion-AT3D
+        9876    ProMotion 6422 139K76B 9808
+        3210    9809 139K76B
+1143    Netpower Inc
+1144    Cincinnati Milacron
+        0001    Noservo Cntrlr
+1145    Workbit Corp
+        F)21    ???? HDCClassName       F020    CardBus ATAPI Host Adapter
+        F021    NPATA32 CardBus CompactFlash Adapter
+        f024    NPATA-32 CardBus CompactFlash Adapter
+1146    Force Computers
+1147    Interface Corp
+        1123    123 131dq
+1148    Marvell Semiconductor Germany GmbH
+        4000    SK-NET FDDI adapter
+        4200    Token Ring Adapter
+        4300    SysKonnect Genesis SK-NET Gigabit Ethernet Adapter
+        4320    Marvell Yukon D-Link DGE530T SysKonnect Marvel RDK 8001
+        4362    88E8053 Marvell Yukon 88E8053 based Ethernet Controller
+        9000    Marvell Yukon II PCI-X PCI-X 10/100/1000Base-T Server
+        9E00    Marvell Yukon EC PCI Express 10/100/1000Base-T Desktop
+1149    Win System Corporation
+114A    VMIC
+        5565    VMIPCI-5565 Ultrahigh-Speed Fiber-Optics Reflective Memory w/ Interrupts
+        5579    VMIPCI-5579 Reflective Memory Card
+        5588    VMICPCI5588 VMICPCI5588 Reflective Memory Card
+        6504    Timer/SRAM FPGA
+        7587    VMIVME-7587 
+114B    Canopus corporation
+114C    Annabooks
+114D    IC Corporation
+        2189    0x1002114D PCTel HSP56 PCI Modem
+114E    Nikon Systems Inc
+114F    Digi International
+        0002    AccelePort EPC ACPI\NSC6001
+        0003    RightSwitch SE-6 
+        0004    AccelePort Xem driver
+        0005    AccelePort Xr 
+        0006    AccelePort C/X 
+        0007    DataFire PCI 1 S/T Digi Data Fire PCI 1 S/T
+        0009    AccelePort Xr/J 
+        000A    AccelePort EPC/J 
+        000C    DataFirePRIme T1 
+        000D    SyncPort X.25/FR 2-port
+        0011    AccelePort8r EIA-232 
+        0012    AccelePort8r EIA-422 
+        0013    AccelePort Xr 
+        0014    AccelePort8r EIA-422 
+        0015    AccelePort Xem 
+        0016    AccelePort EPC/X 
+        0017    AccelePort C/X 
+        0019    DataFire PCI 1 U 
+        001A    DataFirePRIme E1 
+        001B    AccelePort C/X (IBM) 
+        001D    DataFire RAS T1/E1/PRI
+        001F    ClydeNonCsu6034
+        0020    ClydeNonCsu6032
+        0021    ClydeNonCsu4
+        0022    ClydeNonCsu2
+        0023    AccelePort RAS 
+        0024    DataFire RAS B4 ST/U 
+        0026    AccelePort 4r 920 
+        0027    AccelePort 8r 920 
+        0029    DigiClassic PCI 
+        0034    AccelePort 2r 920 
+        0035    DataFire DSP T1/E1/PRI, Compact PCI
+        0040    AccelePort Xp 
+        0042    AccelePort 2p PCI 
+        0070    DataFire Micro V 
+        0071    DataFire Micro V Descargar
+        0072    DataFire Micro V 
+        0073    DataFire Micro V 
+        00c8    20F0 Digi Neo 2
+        6001    Avanstar ACPI\VEN_HPQ&DEV_6001
+1150    Thinking Machines Corporation
+1151    JAE Electronics Inc.
+1153    Land Win Electronic Corp
+1154    Melco Inc
+1155    Pine Technology Ltd
+        0810    486 CPU/PCI Bridge
+        0922    2838 Pentium CPU/PCI Bridge
+        0926    PCI/ISA Bridge
+1156    Periscope Engineering
+1157    Avsys Corporation
+1158    Voarx R&D Inc
+        3011    3011 Tokenet/vg 1001/10m anylan
+        9050    Lanfleet/Truevalue
+        9051    Lanfleet/Truevalue
+1159    Mutech
+        0001    MV1000 
+        0002    MV-1500 Frame Grabber
+115A    Harlequin Ltd
+115B    Parallax Graphics
+115C    Photron Ltd.
+115D    Xircom
+        0003    RBEM56G-100 Cardbus Ethernet 10/100+Modem 56
+        0005    NEC VersaPro VA70j need to reinstall driver CardBus Ethernet 10/100
+        0007    CardBus Ethernet 10/100
+        000B    CardBus Ethernet 10/100
+        000C    MPCI 3A56GSP-100 PA Mini-PCI V.90 56k Modem
+        000F    CardBus Ethernet 10/100
+        002b    168c Winmodem built into NEC Versa VXi
+        0076    2U6MLA-35295-M5-E Xircom MPCI3B-56G (Lucent SCORPIO) Soft
+        00d3    2333333333333 Xircom MPCI Modem 56
+        00D4    MPCI Modem 56k
+        0101    Ms0612006303 CardBus 56k Modem
+        0103    CardBus Ehternet + 56k Modem
+115E    Peer Protocols Inc
+115F    Maxtor Corporation
+1160    Megasoft Inc
+1161    PFU Ltd
+        0001    921014946 Host Bridge
+1162    OA Laboratory Co Ltd
+1163    mohamed alsherif
+        0001    Verite 1000 3D Blaster
+        2000    Rendition V2200 (1179-002) Rendition V2200 (BLITZ 2200 AGP)
+1164    Advanced Peripherals Tech
+1165    Imagraph Corporation
+        0001    Motion JPEG rec/play w/audio
+        0060      Foresight Imaging I-Color
+        0088    03200-150 AccuStream 50a, 75a & 205a Frame Grabber & Video Streamer
+1166    Broadcom / ServerWorks
+        0005    NB6536 (CNB20-LE) PCI to PCI Bridge, bus/dev/func 0/0/1
+        0006    NB6536 (CNB20-HE) Host Bridge, function 2 and function 3
+        0007    NB6635 (CNB20-LE/HE) CPU to PCI Bridge
+        0008    NB6536 (CNB20-HE) Hostbridge & MCH, bus/dev/func 0/0/0
+        0009    NB6536 (CNB20-LE) AGP interface
+        0010    CIOB30 
+        0011    CMIC-HE 
+        0012    CMIC-LE 
+        0013    CNB20-HE Hostbridge and MCH
+        0014    CNB20-HE Host Bridge
+        0015    CMIC-GC Hostbridge and MCH
+        0016    CMIC-GC Host Bridge
+        0017    CMIC-SL 
+        0101    CIOB-X2 
+        0103    47553  
+        0110    CIOB-E I/O Bridge with Gigabit Ethernet ServerWorks Grand Champion
+        0200    OSB4 PCI to ISA Bridge
+        0201    CSB5 ISA bridge
+        0203    CSB6 PCI to ISA Bridge
+        0211    OSB4 PATA33 Controller
+        0212    CSB5 PATA66
+        0213    CSB6 PATA100 RAID Controller
+        0217    CSB6 PATA100 IDE Controller
+        0220    OSB4 OpenHCI Compliant USB Controller
+        0221    OSB6 OHCI Compliant USB Controller
+        0223    0x0223 USB controller
+        0225    CSB5 PCI Bridge
+        0227    CSB6 PCI Bridge
+        0230    ??? PCI to ISA bridge
+        0240    RaidCore4000 Apple K2 SATA AHCI&RAID Controller
+        0241    RC5000Series&BC48??(4850L&4852...) ServerWorks Frodo4 SATA RAID Controller
+        0242    RaidCore4000 Series ServerWorks Frodo8 8xSATA RAID
+        024A    BC5785 Broadcom5785/Serverworks HT1000 AHCI Controller
+        024B    BC5785 BC5785/ServerWorks HT1000 SATA(IDE MODE)
+        0252    RaidCore5000 Series ServerWorks Elrond 8xSAS/SATAII
+1167    Mutoh Industries Inc
+1168    Thine Electronics Inc
+        7145    1002 ATI Mobility Radeon X 1400
+1169    Centre f/Dev. of Adv. Computing
+        0102    QL5032 32 Channel Digital Input Card Interface
+        0202    QL5032 16 Channel Digital Output, 16 Channel Digital Input Interface
+        0302    QL5032 32 Channel Analog Input Interface
+        0402    QL5032 16 Channel Analog Output / Analog Input Interface
+        0502    QL5232 8 Channel Timer Counter Interface
+        0902    QL5232 PCI to TigerSHARC FPGA Interface
+        2001    Ql5032-33APQ208C PCI to C-DAC RTU bus interface FPGA
+116A    Luminex Software, Inc
+        6100    Bus/Tag Channel
+        6800    Escon Channel
+        7100    Bus/Tag Channel
+        7800    nvidia harmony Escon Channel
+116B    Connectware Inc
+116C    Intelligent Resources
+116E    Electronics for Imaging
+        0015    VX120 Fiery EX2000D RIP Card Melbourne VX120
+        0500    Vx500 Printer ASIC
+1170    Inventec Corporation
+1172    Altera Corporation
+        0001    EPF6016ATC144-2 S CCA5000243A
+        0004    -epf6016qc240-2 Multi-serial card
+        0007    StratixIIGX Altera FPGA board
+        1234    5SGXEA7N Stratix V FPGA
+        D4AA    EP1AGX90EF1152C6N Arria GX
+1173    Adobe Systems
+1174    Bridgeport Machines
+1175    Mitron Computer Inc.
+1176    SBE
+        8474    42000133 Conexant Multichannel Synchronous Communications Controller (MUSYCC)
+1177    Silicon Engineering
+1178    Alfa Inc
+        AFA1    Fast Ethernet
+1179    Toshiba corporation
+         8136   RTL8101E Realtek 10/100/1000 PCI-E NIC Family
+        0102    toshiba america info systems Trusted Platform Module
+        0103    833810 Extended PCI IDE Controller Type-B
+        01179   0x8136 PCI\VEN_8086&DEV_3B03&SUBSYS_02FE1028&REV_05\3&11583659&0&F8
+        0201    PCI\VEN_1814&DEV_3298&SUBSYS_1451033 Ralink Chipset 802.11b/g WLAN Card
+        0404    
+        0406    Tecra a2 Video Capture device
+        0407    NVIDIA GeForce 8600M GT NVIDIA GeForce 8600M GT
+        051D    LEN0068 ACPI
+        0601    0555873412 Toshiba CPU to PCI bridge
+        0602    TOS6205 PCI to ISA Bridge for Notebooks
+        0603    ToPIC95 PCI to CardBus Bridge for Notebooks
+        0604    PCI\VEN_104C&DEV_803B&SUBSYS_FF1E1179 PCI to PCI Bridge for Notebooks
+        0605    ACPI\IBM0068 PCI to ISA Bridge for Notebooks
+        0606    PCI to ISA Bridge for Notebooks
+        0609    0322 PCI to PCI Bridge for Notebooks
+        060A    ToPIC95B Toshiba ToPIC95 CardBus Controller
+        060F    ToPIC97 CardBus Controller
+        0611    PNP0510 PCI-ISA Bridge
+        0617    ToPIC100 PCI to CardBus Bridge with ZV support
+        0618    CPU to PCI and PCI to ISA Bridge
+        0701    1E3D PCI Communication Device
+        0804    0x0804 Toshiba Smart Media Host Controller
+        0805    ACPI\TOS1901\2&DABA3FF&er.com1 ACPI\ASD0001\2&DABA3FF&1
+        0D01    0x0D01 FIR Port Type-O
+        1179    32 Dispositivo de comunicaciones pci
+        13A8    XR17C158/154/152 Multi-channel PCI UART
+        168     AREG9485 WB Qualcomm Atheros AR9485WB-EG wireless Network Adapter
+        3b64    intel 3b64 Management Engine Driver
+        8136    0x8136 pci\ven_10 EC
+        9876    ACPI\TOS1901 SD Card Controller
+117A    A-Trend Technology
+117B    LG (Lucky Goldstar) Electronics Inc.
+        8320    NOFM12 VGA
+117C    Atto Technology
+        0030    ExpressPCI UL5D Dual-Channel Low-Profile Ultra320 SCSI PCIe Host Bus Adapter
+        0042    ExpressSAS H60F Low-Profile 16-Internal Port 6Gb/s SAS/SATA PCIe 2.0 Host Bus Adapter
+117D    Becton & Dickinson
+117E    T/R Systems
+        0001    Printer Host
+117F    Integrated Circuit Systems
+1180    RicohCompany,Ltd.
+        0475    RL5c592 Cardbus Controller
+        0476    RL5c476 II RICOH SmartCard Reader
+        0478    RB5c478 Cardbus Controller
+        0552    R5C552 FireWire (IEEE 1394) Controller
+        0575    44192 I11fXI  <a href   059     1 1
+        0592    0880 Ricoh R5C833 R5C8xx Memory Stick Controller
+        05xx    R5U8xx Ricoh R5U8xx Card Reader Driver - Win xp
+        0822    R5C832 SDA Standard Compliant SD Host Controller
+        0832    ACPI\ENE0100\4&15458EF3&0 ACPI\ENE0100\4&15458EF3&0
+        0843    022E1028 Ricoh SD Host Controller
+        0847    delete delete
+        0852    R5C852 Ricoh xD-Picture Card Controller
+        1108    30CF Ricoh Memory Stick Host Controller
+        2792    0x8086 PCI\VEN_1180&DEV_0852&SUBSYS_022F1028&REV_12 
+        5551    Unknown IEEE 1394 Controller
+        852     01cf1028  Ricoh xD-Picture Card Host Controller;0852h xd picture card controller
+        9876    CC_088000 Ricoh Memory Stick Host Controlle
+        98760x0843      R5C853 Ricoh SD/Host Controller
+        E2030   0592 Ricoh PCIe Memory Stick Host Controller
+        E230    9086104D Ricoh PCIe Memory Stick &#1061;&#1086;&#1089;&#1090;-&#1050;&#1086;&#1085;&#1090;&#1088;&#1086;&#108
+        e476    Ricoh R5C843 Multipurpose chip, this e476 seems to be the CardBus controller part
+        e822    R5U822 Ricoh PCIe SD/MMC Host Controller
+        e823    R5U822 Ricoh PCIe SDXC/MMC Host Controller
+        e832    R5U832 Ricoh PCIe IEEE1394 Fireware Host Controller
+        E852    Uknown Ricoh PCIe xD-Picture Card Controller
+1183    Fujikura Ltd
+1184    Forks Inc
+1185    Dataworld
+        8929    EIDE Controller
+1186    D-Link System Inc
+        0100    88e8003 Ethernet Adapter
+        1002    DFE-550TX/580TX/DFE-550FX Fast Ethernet Adapter
+        1100    driv16c003206 Fast Ethernet Adapter
+        1300    DL10038C or DL10038E Realtek RTL8139 Family PCI Fast Ethernet Adapter
+        1301    DGE-528T  Fast Ethernet Adapter
+        1340    DFE-690TXD Fast Ethernet CardBus PC Card
+        1561    DRP-32TXD CardBus PC Card
+        3065    14001186 D-Link DFE-500Tx PCI fast Ethernet adapter Re v.A
+        3106    DFE 520TX/530TX+ rev E1 Fast Ethernet Adapter
+        3300    D-Link Air Wireless Network (DWL-G510) IEEE 802.11g PCI card
+        3b00    0x3b001186 D-LINK DWL-650+
+        3c09    DWL-G510 Version C1 Ralink RT61
+        4000    DL2000 Gigabit Ethernet Adapter
+        4001    DFE-650TX D Link Fast Ethernet PCMCIA Card
+        4200    DFE-520TX_C1 -
+        4300    dlg10086 Used on DGE-528T Gigabit adaptor
+        4302    dg530t DGE-530T
+        4b00    DGE-560T D-Link System Inc DGE-560T PCI Express Gigabit Ethernet Adapter (rev 13)
+        4B01    DGE-530T Gigabit Ethernet Adapter
+        4C00    DGE-530T Gigabit Ethernet Adapter
+        9876    876 d
+1187    Philips Healthcare
+1188    Shima Seiki Manufacturing Ltd.
+1189    Matsushita Electronics
+        1592    VL/PCI Bridge
+118A    Hilevel Technology
+118B    Hypertec Pty Ltd
+118C    Corollary Inc
+        0014    PCIB C-bus II to PCI bus host bridge chip
+        1117    MAC-94C201B3 Corollary/Intel Memory Controller Chip
+118D    BitFlow Inc
+        0001    n/a Raptor-PCI framegrabber
+        0012    Model 12 Road Runner Frame Grabber
+        0014    Model 14 Road Runner Frame Grabber
+        0024    Model 24 Road Runner Frame Grabber
+        0044    Model 44 Road Runner Frame Grabber
+        0112    Model 12 Road Runner Frame Grabber
+        0114    Model 14 Road Runner Frame Grabber
+        0124    Model 24 Road Runner Frame Grabber
+        0144    Model 44 Road Runner Frame Grabber
+        0212    Model 12 Road Runner Frame Grabber
+        0214    Model 14 Road Runner Frame Grabber
+        0224    Model 24 Road Runner Frame Grabber
+        0244    Model 44 Road Runner Frame Grabber
+        0312    Model 12 Road Runner Frame Grabber
+        0314    Model 14 Road Runner Frame Grabber
+        0324    Model 24 Road Runner Frame Grabber
+        0344    Model 44 Road Runner Frame Grabber
+118E    Hermstedt AG
+        0042    
+        0142    
+        0242    
+        0342    
+        0440    
+        0442    
+        0842    02321038 red
+118F    Green Logic
+1190    Tripace
+        2550    TC-2550 Single Chip Ultra (Wide) SCSI Processor
+        C721    EIDE
+        C731    TP-910/920/940 PCI Ultra (Wide) SCSI Adapter
+1191    Acard Technology Corp.
+        0001    IDE Ctrlr
+        0002    ATP850UF UltraDMA33 EIDE Controller (AEC6210UF)
+        0003    SCSI-2 cache Cntrlr
+        0004    4111111111111111 UltraDMA33 EIDE Controller
+        0005    ATP850UF UltraDMA33 EIDE Controller (AEC6210UF)
+        0006    ATP860A UltraDMA66 EDIE Controller (AEC6260)
+        0007    ATP860R UltraDMA66 EIDE Controller (AEC6260)
+        0008    ATP865 2CH PCI UltraDMA133 IDE Controller
+        0009    ATP865 AEC6280PATA133|AEC6880 PATA RAID|AEC6290 SATA|AEC6890 SATA RAID|AEC6891 SATA RAID
+        000a    aec6885 ACARD AEC-6885/6895/6896 RAID Controller
+        000B    373953244361001 ACARD AEC-6897/6898 RAID Controller
+        000D    ATP8620 2S1P PCI-X SATA(3G)/UDMA Combo Controller
+        8001    ATP8600 SCSI-2 RAID (cache?) Adapter (AEC6820U)
+        8002    ATP850S/5412751206270000 AEC6710S/U/UW SCSI-2 Host Adapter 
+        8010    ATP870 Ultra Wide SCSI Controller
+        8020    ATP870 AEC6712U/TU Ultra SCSI Controller
+        8030    ATP870 AEC 6712S/TS Ultra SCSI Controller
+        8040    ATP870 SCSI Controller
+        8050    AEC6715UW Ultra Wide SCSI Controller
+        8060    4116360015430005 SCSI Host Adapter/PAYPAL.COM/X.COM
+        8081    5412751206270000 PCI Ultra160 LVD/SE SCSI Adapter
+        808A    ATP885 AEC6710S/U/UW SCSI-2 Host Adapter
+1192    Densan Co. Ltd
+1194    Toucan Technology
+1195    Ratoc System Inc
+1196    Hytec Electronics Ltd
+1197    Gage Applied Technologies
+        010C    CompuScope 82G 8-bit 2GS/s Analog Input Card
+1198    Lambda Systems Inc
+1199    Attachmate Corp.
+        0001    IRMA 3270 PCI Adapter IRMA 3270 PCI Adapter
+        0002    Advanced ISCA PCI Adapter
+        0201    SDLC PCI Adapter
+119A    Mind/Share Inc.
+119B    Omega Micro Inc.
+        1221    82C092G PCI PCMCIA bridge
+119C    Information Technology Inst.
+119D    Bug Sapporo Japan
+119E    Fujitsu Microelectronics Ltd.
+        0001    MB86697 FireStream 155 ATM adapter
+        0003    MB86695 FireStream 50 ATM adapter
+119F    Bull Hn Information Systems
+11A1    Hamamatsu Photonics K.K.
+11A2    Sierra Research and Technology
+11A3    Deuretzbacher GmbH & Co. Eng. KG
+11A4    Barco
+11A5    MicroUnity Systems Engineering Inc.
+11A6    Pure Data
+11A7    Power Computing Corp.
+11A8    Systech Corp.
+        7302    NTX-8023-PCI 2MB Long Card
+        7308    NTX-8023-PCI 8MB Long Card
+        7402    NTX-8023-PCI 2MB Short Card
+        7408    NTX-8023-PCI 8MB Short Card
+11A9    InnoSys Inc.
+        4240    AMCC S5933Q pci matchmaker 9622qac
+11AA    Actel
+11AB    Marvell Semiconductor
+        0028    NV05 MCP67 High Definition Audio
+        0146    GT-64010/A System Ctrlr for R4xxx/5000 Family CPUs
+        11AB    88E8055 PCI-E Gigabit Ethernet Controller
+        11AB-4632       88E8055 Marvell Yukon 88E8055 PCI-E Gigabit Ethernet Controller
+        11ABc   88E8055 PCI-E Gigabit Ethernet Controller
+        13F8    W8300 802.11 Adapter
+        1fa6    88W8310 The Libertas WLAN 802.11b/g
+        1FA7    88W8310 Libertas WLAN 802.11b/g
+        1fa8    WG311 54M Wireless 802.11b PCI wifi Adapter Card
+        1FAA    8335 (MRV8835) Marvell Libertas 802.11 b/g Wireless (8335)
+        2A30    88W8687 PCI-Express 802.11bg Wireless
+        4320    88E8001 Marvell Yukon PCI E Gigabit drivers for d
+        4350    88E8036 Yukon PCI-E Fast Ethernet Controller
+        4351    88E8036 Yukon PCI-E Fast Ethernet Controller
+        4352    88E8038 Marvell Yukon 88E8038 PCI-E Fasvt Ethernet Controller
+        4353    88E8039 88E8039 PCIe Fast Ethernet Controller
+        4354    88E8040 Marvell Yukon 88E8040 PCI-E Fast Ethernet Controller
+        4355    88E8001 Marvell Yukon 88E8040T PCI-E Fast Ethernet Controller
+        4357    88E8042 marvell ethernet lan No painel 
+        4360    88E8050 Yukon PCI-E ASF Gigabit Ethernet Controller
+        4361    88E8036 Marvell Yukon 88E8036 Network Card
+        4362    88E8053 Marvell Yukon 88E8053 PCI-E Gigabit Ethernet Controller
+        4363    88E8042 Yukon PCI-E Gigabit Ethernet Controller
+        4364    81f81043 Yukon PCI-E Gigabit Ethernet Controller
+        4365    88E8070 Yukon Gigabit Controller DRIVER
+        436A    88E8058 Marvell Yukon 88E8058
+        436b    88E8072 Marvell Yukon 8072
+        436b-1  88E8072 Marvell Yukon PCI-E Gigabit Ethernet Controller
+        436C    88E8072 Marvell 8072 Ethernet Nic
+        4380    88e8071 Marvell Yukon 88E8057 PCI-E Gigabit Ethernet Controller
+        4381    88E8059 Marvell Yukon 88E8059 PCI-E Gigabit Ethernet Controller
+        4611    GT-64115 System Controller
+        4620    GT-64120 System Controller for R5000 & R7000 (64-bit PCI)
+        4801    88w8335 8 port switched ethernet ctrlr
+        4809    EV-48300 Evaluation board for the GT-48300
+        5005    F5D5005 Belkin Desktop Gigabit PCI card
+        5040    88SX5040 4-port SATA I PCI-X Controller
+        5041    88SX504 4-port SATA I PCI-X Controller
+        5080    RocketRAID 62x SATA Controller
+        5081    RocketRAID 182x SATA Controller
+        6041    MV88SX6041 Marvell Technology Group Ltd. MV88SX6041 4-port SATA II PCI-X Controller (rev 03)
+        6081    0007 PCI-X RocketRAID 222x SATA Controller
+        6101    88SE6101 PATA 133 One Channel
+        6111    ? 61xx RAID
+        6120    ? 61xx RAID
+        6121    88SE6121 61xx AHCI
+        6122    ? 61xx RAID
+        6140    4355 61xx RAID
+        6145    88SE6145 Marvell 6145 SATA II PCI-E Controller 4 SATA2 300MB/s ports - Thor 4S/1P
+        6320    GT-64130/131 System Controller for PowerPC Processors
+        6440    88SE6320 64xx/63xx SAS
+        6480    MV6446x PowerPC System Controller
+        6485    MV6446x  Marvel 88SE6480 is the chip on the mainboard
+        9128    SE9128 SATA3  6 GB/s  SATA3/Raid Controller
+        91A2                    91xx Sata 6G RAID Controller
+        9653    GT-96100A Advanced Communication Controller
+        9876    88E8038 marvell yukon 88E8038 pci-e fast ethernet controller
+        F003    GT-64010 Primary Image Piranha Image Generator
+        F004    GT64120 Primary Image Barracuda Image Generator
+        F006    GT-64120A Primary Image Cruncher Geometry Accelerator
+        FFFF    88SA8040 PATA2SATA/SATA2PATA Bridge
+11AC    Canon Information Systems
+11AD    Lite-On Technology Corp.
+        0001    LC82C168 Fast Ethernet Adapter
+        0002    LC82C169 NETGEAR FA310TX Fast Ethernet PCI Adapter
+        C115    LC82C115 PNIC II PCI MAC/PHY
+11AE    Scitex Corporation Ltd
+        4153    Bridge Controller
+        5842    Bridge Controller
+11AF    Avid Technology, Inc.
+        0001    9704 Cinema
+        000A      Nitris
+        000B      Nitris DX / Mojo DX
+11B0    Quicklogic Corp
+        0001    V960PBC/PSC i960 Local Bus to PCI Bridge
+        0002    V961PBC/PSC i960Jx Local Bus to PCI Bridge
+        0004    V962PBC/PSC i960Cx/Hx Local Bus to PCI Bridge
+        0010    V292PBC/PSC Am29K Local Bus to PCI Bridge
+        0021    V363EPC i960Sx Local Bus to PCI Bridge
+        0022    V363EPC i960Jx Local Bus to PCI Bridge
+        0024    V363EPC i960Cx/Hx Local Bus to PCI Bridge
+        0030    V363EPC Am29K Local Bus to PCI Bridge
+        0100    V320USC PCI System Ctrlr for 32-bit MIPS CPU
+        0101    V320USC PCI System Ctrlr for 32-bit MIPS CPU
+        0102    V320USC PCI System Ctrlr for Super-H SH3 CPU
+        0103    V320USC PCI System Ctrlr for Super-H SH4 CPU
+        0200    V370PDC High Performance PCI SDRAM Controller
+        0292    V292PBC Am29030/40 Bridge
+        0500    V340HPC PCI System Ctrlr for 64-bit MIPS CPU
+        0960    V96xPBC i960 Bridges for i960 Processors
+        4750    V3 V962PBC-40LP / VLSI VP06597A SCRAMNet
+        C960    V96DPC i960 Dual PCI Bridge
+11B1    Apricot Computers
+11B2    Eastman Kodak
+11B3    Barr Systems Inc.
+11B4    Leitch Technology International
+11B5    Radstone Technology Ltd.
+        0001    PMC/PMX1553 1553 Bus Interface Card
+        0002    PMCF1 FLASH memory Card
+        0003    PMCMMA Multi Media Adapter
+        0004    PMCVGO Video Graphics Overlay
+        0005    PMCPCIS PPzero Slave Interface Card
+        0006    PMCPCIM PPzero Master Interface Card
+        0007    PMCQ1 Serial/1553 Interface Card
+        0008    EPMCQ2 Intelligent Serial/Ethernet Card
+        0009    PMCPIO1 Parallel I/O Module
+        000a    PMCFA1C Fibre Channel Adapter
+        000b    PMCHH1 High Speed DSP Gateway Module
+        000c    PMCMA2 Memory Adaptor Module
+        0012    PMCF1 FLASH memory Card (V2)
+        0013    PMC1553EX 1553 Bus Interface Card
+        0014    PMC1553E 1553 Bus Interface Card
+        2200    PMCFA2C Dual Fibre Channel Adapter
+11B6    United Video Corp
+11B7    Motorola
+11B8    Xpoint Technologies Inc
+        0001    Quad PeerMaster 
+11B9    Pathlight Technology Inc.
+        C0ED    SSA Ctrlr 
+11BA    Videotron Corp
+11BB    Pyramid Technology
+11BC    Network Peripherals Inc
+        0001    NPI NuCard PCI FDDI
+11BD    Pinnacle system
+        0015    660806-2.0 rob2d
+        1111    1456 www.unibobodioulasso.0fees.net
+        1158    48 Tunner Royal TS 1
+        11BD    MB87J3560 maintenance informatique
+        11PE    49 Tunner Royal TS 2
+        2020    assistance en ligne 70009823/76199706
+        BEBE    51015777 MAINTENANCE INFORMATIQUE VENTE DE CONSOMABLE
+        BEDE    51014521 Pinnacle Studio 700 PCI
+11BE    International Microcircuits Inc
+11BF    Astrodesign Inc.
+11C1    LSI Corporation
+        0440    LT Winmodem 56k Data+Fax+Voice+DSVD
+        0441    5517158 modem driver
+        0442    1646T00 LT WinModem 56K Data+Fax
+        0443    LT Winmodem 1646T00
+        0444    LT Winmodem 845G
+        0445    LT Winmodem 
+        0446    NVidia SMBus PCI\VEN_10DE&DEV_03d1&subsys_26011019&rev_a2\3&2411e6fe&0&68
+        0447    LT Winmodem windowsme
+        0448    LT Winmodem 56k SV2P2
+        0449    LT Winmodem 56k 0449144F
+        044A    LT Winmodem 56k pci ven_1904
+        044B    LT Winmodem USB\VID_13FD&PID_1650&REV_0446
+        044C    LT Winmodem SV95PL-TOO
+        044D    LT Winmodem 
+        044E    12232 LT WinModem 56k Data+Fax or Agere F-1156IV/A3
+        044F    90094-1 LT V.90+DSL WildFire Modem
+        0450    1468VQH19R-1(INT) LT Winmodem 56K
+        0451    LT Winmodem LT WinModem 56k Data+Fax+Voice+DSVD
+        0452    LT Winmodem 1513144
+        0453    LT Winmodem 
+        0454    LT Winmodem 
+        0455    LT Winmodem 
+        0456    LT Winmodem 
+        0457    LT Winmodem 
+        0458    1648C Mars 3 Mercury v.92 v.44
+        0459    LT Winmodem 
+        045A    LT Winmodem 
+        045D    LT WinModem mars2
+        0461    90094 V90 Wildfire Modem
+        0462    1690 56K.V90/ADSL Wildwire Modem
+        0464    This is NOT a Riptide! (as previously stated) Lucent Wildwire v.90 + DSL modem
+        0480    Venus Winmodem  56k.V90/ADSL Wildfire Modem 
+        048b    1648T00 creative modem blaster di5733-1
+        048C    1648c-tv5 net-comm modem
+        048d    lt winmodem 9m56pml-g
+        048E    svp92pl-t00 56k V.92modem
+        048F    SV92P-T00 Agere PCI Soft Modem. SV92PL
+        0540    
+        0600    sv5 SV92P-T00 Agere PCI Soft Modem. SV92PL
+        0620    SV92PP Agere PCI Soft Modem 
+        0630    11c1063011c1 #1: 32 pins, 8 each on 4 sides #2: 20 pins, 10 ea on 2 sides. - hp / compaq - Modem_HP_sp45489
+        1040    Prespa Agere Systems HDA Modem
+        11c1    ............ Agere Systems .......... HDA
+        3026    0x11c11040 Agere Modem
+        3055    Modem on Audio Bus Agere Systems HDA Modem v6081
+        4758    210888GX Mach64 GX
+        5400    OR3TP12 FPSC FPGA with 32/64bit, 33/66MHz core
+        5801    USB Open Host Controller
+        5802    USS-312MC 2-port PCI-to-USB OpenHCI Host Ctrlr
+        5803    USS-344 QuadraBus 4-port USB OpenHCI Host Ctrlr
+        5805    uss344 USB Advanced Host Controller
+        5811    FW322/323 1394A PCI PHY/Link Open Host Ctrlr I/F
+        5901    FW643 firewire chip for macbook pro
+        9876    lucent 1646T00 LT WinModem 56K Data+Fax
+        AB20    WaveLAN PCI Wireless LAN Adapter
+        AB30    wlsam48d Mini-PCI WaveLAN a/b/g
+        ED00    ET-131x PCI-E Ethernet Controller
+        7121    
+        fsu 00  
+11C2    Sand Microelectronics
+11C4    Document Technologies Ind.
+11C5    Shiva Corporatin
+11C6    Dainippon Screen Mfg. Co
+        3001    1 VM-1200 Opto Unit Controller
+11C7    D.C.M. Data Systems
+11C8    Dolphin Interconnect Solutions
+        0658    PSB 32 32 bit , 33 Mhz PCI-SCI Bridge
+        D665    PSB64 64 bit , 33 Mhz PCI-SCI Bridge
+        D667    PSB66 64 bit , 66 Mhz PCI-SCI Bridge. (D33x)
+11C9    MAGMA
+        0010    1106 16-line serial port w/DMA
+        0011    4-line serial port w/DMA
+11CA    LSI Systems Inc
+11CB    Specialix International Ltd.
+        2000    PCI-9050-1100083-11 port small IC
+        4000    SUPI-1 XIO/SIO Host
+        8000    T225 Bridge RIO Host
+11CC    Michels & Kleberhoff Computer GmbH
+11CD    HAL Computer Systems Inc.
+11CE    Primary Rate Inc
+        102B    1001 FF00102B
+11CF    Pioneer Electronic Corporation
+11D0    BAE SYSTEMS - Manassas
+11D1    AuraVision Corporation
+        01F7    VxP524 PCI Video Processor
+        01F8    VxP524 PCI Video Processor
+        01f9    rev_03 tuner card
+        VXP520  tag4769 Video card
+11D2    Intercom Inc.
+11D3    Trancell Systems Inc
+11D4    Analog Devices, Inc.
+        11D4    1986 AD1988B 8-channel High Definition Audio CODEC
+        11d4ncah6n      266e&subsys 01791028
+        1535    ADSP-21535 Blackfin DSP PCI Bus Interface
+        1805    62412-51 U52018.2-0.6
+        1884    AD1884HD SoundMAX Integrated Digital HD Audio
+        1889    AD1980 Sound Chip
+        194A    AD1984A SoundMAX Integrated Digital Audio
+        1981    7037 SoundMAX Integrated Digital Audio
+        1983    AD1983HD SoundMAX Integrated Digital HD Audio
+        1984    Analog Devices ADI 1984 Analog Devices ADI 1984 Integrated HD Audio
+        1986    ADI1986A SoundMAX Digital HD Audio
+        1988    AD1981 HD Audio Codec
+        198B    AD1988B SoundMAX AD1988B 8channel CODEC
+        2192    ADSP-2192 DSP Microcomputer (function #0)
+        219A    ADSP-2192 DSP Microcomputer (function #1)
+        219E    ADSP-2192 DSP Microcomputer (function #2)
+        2F44    ADSP-1882 SafeNet Crypto Accelerator chip
+        989B    AD1989B SoundMax Integrated Digital HD Audio
+11D5    Tahoma Technology
+        0115    10115 Versatec Parallel Interface (VPI) + Centronics
+        0116    10118 DR11-W emulator
+        0117    10117 Versatec Parallel Interface (VPI) + Centronics
+        0118    10118 DR11-W emulator
+11D6    Tekelec Technologies
+11D7    TRENTON Technology, Inc.
+11D8    Image Technologies Development
+11D9    Tec Corporation
+11DA    Novell
+        2000    2 Virtual-Bus / AlacrityVM bridge
+11DB    Sega Enterprises Ltd
+        1234    Dreamcast Broadband Adapter
+11DC    Questra Corp
+11DD    Crosfield Electronics Ltd
+11DE    Zoran Corporation
+        6057    59568 Mc3aDo  <a href   6067    zr36067pqc zoran
+        6120    ZR36120PQC MPEG VideoBVPSXI Capture Card
+        6O57    ZR36057PQC ZORAN PCI Bridge (interface for transferring video across the PCI bus)
+        9876    
+11E1    Gec Plessey Semi Inc
+11E2    Samsung Information Systems America
+11E3    Quicklogic Corp
+11E4    Second Wave Inc
+11E5    IIX Consulting
+11E6    Mitsui-Zosen System Research
+11E8    Digital Processing Systems Inc
+11E9    Highwater Designs Ltd
+11EA    Elsag Bailey
+11EB    Formation, Inc
+11EC    Coreco Inc
+        0028    NV05 MCP67 High Definition Audio
+        2064    
+11ED    Mediamatics
+11EE    Dome Imaging Systems Inc
+11EF    Nicolet Technologies BV
+11F0    Triya
+        2772    FASTline UTP Quattr PCI\VEN_8086&DEV_2772&SUBSYS_0CCB105B&REV_02\3&2411E6FE&0&10
+        4       FASTline UTP Quattr PCI\VEN_8086&DEV_2772&SUBSYS_0CCB105B&REV_02\3&2411E6FE&0&10
+        4231    1 2
+        4232    FASTline UTP Quattr PCI\VEN_8086&DEV_2772&SUBSYS_0CCB105B&REV_02\3&2411E6FE&0&10
+        4233    FASTline FO 
+        4234    FASTline UTP 
+        4235    FASTline-II UTP 
+        4236    FASTline-II FO 
+        4731    GIGAline Gigabit Ethernet Adapter
+        9876    1 2
+11F2    Picture Tel Japan KK
+11F3    Keithley Instruments, Inc
+11F4    Kinetic Systems Corporation
+        2915    2915 
+11F5    Computing Devices Intl
+11F6    Powermatic Data Systems Ltd
+        0112    ATT2MD11 ReadyLink ENET100-VG4
+        0113    FreedomLine 100
+        1401    832AE28030680 ReadyLink RL2000
+        2011    TXA9882 ReadyLink  RL100ATX/PCI Fast Ethernet Adapter
+        2201    TXA9883 ReadyLink 100TX (Winbond W89C840)
+        9881    TXA9881? ReadyLink RL100TX Fast Ethernet Adapter
+11F7    Scientific Atlanta
+11F8    PMC-Sierra Inc.
+        7364    PM7364 FREEDM-32 Frame Engine & Datalink Mgr
+        7366    PM7364 FREEDM-8 Frame Engine & Datalink Manager
+        7367    PM7367 FREEDM-32P32 Frame Engine & Datalink Mgr
+        7375    PM7375 LASAR-155 ATM SAR
+        7380    PM7380 FREEDM-32P672 Frm Engine & Datalink Mgr
+        7382    PM7382 FREEDM-32P256 Frm Engine & Datalink Mgr
+        7384    PM7384 FREEDM-84P672 Frm Engine & Datalink Mgr
+        8000    PM8000 SPC 6G SAS/SATA Controller
+        8010    PM8010 SRC 6G SAS/SATA RAID Controller
+11F9    I-Cube Inc
+11FA    Kasan Electronics Co Ltd
+11FB    Datel Inc
+        0417    417 PCI-417 High Speed A/D Board
+11FD    High Street Consultants
+11FE    Comtrol Corp
+        0001    RocketPort 
+        0002    RocketPort 
+        0003    RocketPort 
+        0004    RocketPort 
+        0005    RocketPort 
+        0006    RocketPort 
+        0007    RocketPort 
+        0008    RocketPort 
+        0009    RocketPort 
+        000A    RocketPort 
+        000B    RocketPort 
+        000C    RocketPort 
+        000D    RocketPort 
+        8015    RocketPort 4-port UART 16954
+11FF    Scion Corp
+1200    CSS Corp
+1201    Vista Controls Corp
+1202    Network General Corp
+        0001    NAIATMPCI PCI ATM Adapter
+1203    Bayer Corporation Agfa Div
+        0001    Unknown Unknown
+1204    Lattice Semiconductor Corp
+        9876    12 wwDW
+1205    Array Corp
+1206    Amdahl Corp
+1208    Parsytec GmbH
+        4853    HS-Link Device
+1209    Sci Systems Inc
+        0100    PCI 9054 PLX PCI BRIDGE
+120A    Synaptel
+120B    Adaptive Solutions
+120D    Compression Labs Inc.
+120E    Cyclades Corporation
+        0100    Cyclom-Y Multiport Serial Card
+        0101    Cyclom-Y Multiport Serial Card
+        0102    Cyclom-4Y Multiport Serial Card
+        0103    Cyclom-4Y Multiport Serial Card
+        0104    Cyclom-8Y Multiport Serial Card
+        0105    Cyclom-8Y Multiport Serial Card
+        0200    Cyclom-Z Intelligent Multiport Serial
+        0201    Cyclom-Z Intelligent Serial Card
+        0300    PC300 RX 2 1105
+        0301    PC300 RX 1 
+        0302    PC300 TE 2 
+        0303    PC300 TE 1 teclado
+120F    Essential Communications
+        0001    Roadrunner 
+1210    Hyperparallel Technologies
+        25f4    No data No data
+1211    Braintech Inc
+1213    Applied Intelligent Systems Inc
+1214    Performance Technologies Inc
+1215    Interware Co Ltd
+1216    Purup-Eskofot A/S
+        0003    188A2L432B PTM400 PCI Taxi Module
+1217    O2Micro Inc
+        00f7    0x00f71217 1394 Open Host Controller Interface
+        1217    EN-2242 111111111
+        6729    OZ6729 PCI to PCMCIA Bridge
+        673A    OZ6730 PCI to PCMCIA Bridge
+        6832    OZ6832/3 CardBus Controller
+        6836    OZ6836/6860 CardBus Controller
+        6872    OZ6812 CardBus Controller
+        6925    OZ6922 CardBus Controller
+        6933    OZ6933 CardBus Controller
+        6972    OZ6912 CardBus Controller
+        7110    OZ711Mx MemoryCardBus Accelerator
+        7112    
+        7113    0Z711EC1 PCMCIA/SmartCardBus Contoller
+        7114    OZ711M1 CardBus Controller
+        7120    Unknown device O2Micro Integrated MMC/SD controller
+        7130    501179 O2Micro Integrated MMC/SD/MS/xD/SM Controller
+        7134    OZ711MP1/MS1 MemoryCardBus Controller 6-in-1
+        7135    OZ711EZ1 MemoryCardBus Contoller
+        7136    OZ711SP1 O2Micro CardBus Controller
+        71E2    
+        7212    
+        7213    
+        7222    unknow pci to pcmcia bridge
+        7223    OZ711M3/MC3 MemoryCardBus Controller
+        8130    0x8130 o2 sd card reader
+        8231    OZ600XXX O2Micro OZ600XXX Memory Card 
+        8330     PCI\VEN_1217&DEV_8331&SUBSYS_049A1028&REV_05\4&34 Mass storage controller [0180]
+        8331    OZ600xxx O2Micro Integrated MS/PRO controller
+1218    Hybricon Corp
+1219    First Virtual Corp
+121A    3dfx Interactive Inc
+        0003    
+        003     
+        0001    Voodoo Voodoo 3D Acceleration Chip
+        0002    Voodoo2 Voodoo 2 3D Accelerator
+        0003    Voodoo Banshee Voodoo Banshee
+        0005    Voodoo3 All Voodoo3 chips, 3000
+        0007    Voodoo4 
+        0009    Voodoo5 AGP X2, or PCI. Chip: 2x VSA100 with 32Mo
+        0010    Rampage Rev.A AGPx4, 0.25., 200/2x200 core/RAM
+        0057    Voodoo 3/3000 Avenger
+121B    Advanced Telecommunications Modules
+121C    Nippon Texa Co Ltd
+121D    LiPPERT Embedded Computers GmbH
+121E    CSPI
+121F    Arcus Technology Inc
+1220    Ariel Corporation
+        1220    9622qac AMCC 5933 TMS320C80 DSP/Imaging Board
+        4242      controller audio multimediale
+1221    Contec Microelectronics Europe BV
+1222    Ancor Communications Inc
+1223    Artesyn Embedded Technologies
+        0001    KatanaQp Real-Time Processing Blade in a standard single-slot AdvancedTCA. formfactor
+        0002    KosaiPM Intel. Pentium-M. based AMC Module
+        0016    PCIe-8120 PCIe-8120 MGW Octasic DSP card 
+        003     Katana3752 Advanced Tri-Processor Blade
+        004     Katana3750 Advanced Tri-Processor Blade
+        0044    Memory controller Memory controller
+        005     Katana752i Real-time Processing Blade
+        006     Katana750i Real-time Processing Blade
+        007     CC1000dm Processor PMC Carrier Card
+        008     Pm3Gv Up to 8 E1/T1/J1 interfaces for PMC-compatible baseboards
+        009     Pm3GE1T1 Third Generation E1 and T1/J1 interfaces for PMC-compatible baseboards
+        010     SpiderwareSG SIGTRAN Signalling Gateway Blade
+        011     SpiderwareSS7 64 SS7 signaling channels on a single blade
+        012     SpiderSS7 Portable, STREAMS-Based Implementation of the ITU SS7 Protocol Stack
+        013     Spider FRAME RELAY STREAMS-Based Frame Relay Implementation
+        014     Spider STREAMS Implementation of the UNIX STREAMS Environment
+        015     Spider DSF Transparent STREAMS Interface for High Speed LAN or Shared Memory Systems
+        7207    pcie7207 PCIe7207 Server Accelerator
+1224    Interactive Images
+        1000    CL560? Plum Audio, Video and VTR Controller
+1225    Power I/O Inc.
+1227    Tech-Source
+1228    Norsk Elektro Optikk A/S
+1229    Data Kinesis Inc.
+122A    Integrated Telecom
+122B    LG Industrial Systems Co. Ltd.
+122C    sci-worx GmbH
+122D    Aztech System Ltd
+        1206    ICH2 Asus
+        4201    MR2800W AMR 56K modem
+        50DC    pci 120 Audio
+        80DA    3328 Audio
+122E    Absolute Analysis
+122F    Andrew Corp.
+        37AF    0x9030 Reflectometer using PLX 9030
+1230    Fishcamp Engineering
+1231    Woodward McCoach Inc.
+1233    Bus-Tech Inc.
+1234    Technical Corp
+1236    Sigma Designs, Inc
+        0000    RealMagic64/GX SD6425
+        0531    MX98715/25 Single Chip Fast Ethernet NIC Controller
+        3d01    000 RealMagic/2D
+        6401    REALmagic64/GX GUI
+        9708    realmagic64/gx sd6425
+1237    Alta Technology Corp.
+1238    Adtran
+1239    The 3DO Company
+123A    Visicom Laboratories Inc.
+123B    Seeq Technology Inc.
+123C    Century Systems Inc.
+123D    Engineering Design Team Inc.
+        0010    PCI-DV PCI-DV Digital Video Interface
+123F    C-Cube Microsystems
+        00E4    cl 480 MPEG
+        6120    12.03 DVD device
+        8120    176 i440B
+        8888    12.03 cPEG C 3.0 DVD/MPEG2 Decoder
+1240    Marathon Technologies Corp.
+1241    DSC Communications
+        1603    1 keyboard
+1242    JNI Corporation
+        1460    JNIC-1460 2-Gb/s Fibre Channel-PCI 64-bit 66 MHz
+        1560    JNIC-1560 Dual Channel 2 Gb/s Fibre Channel-PCI-X
+        4643    JNI PCI 64-bit Fibrechannel JNI PCI 64-bit Fibrechannel (needs clone)
+1243    Delphax
+1244    AVM AUDIOVISUELLES MKTG & Computer GmbH
+        0700    B1 ISDN controller
+        0800    C4 ISDN Controller
+        0A00    A1 ISDN Controller
+        0E00    0x1244 Fritz!PCI 2.0 ISDN Controller
+        1100    C2 ISDN Controller
+        1200    T1 ISDN Controller
+        2700    E13 32A5KYW / 2CAKRCT DSP TNETD5100GHK / TNETD5015
+        2900    - AVM Fritz!Card DSL v2.0 PCI
+1245    APD S.A.
+1246    Dipix Technologies Inc
+1247    Xylon Research Inc.
+1248    Central Data Corp.
+1249    Samsung Electronics Co. Ltd.
+124A    AEG Electrocom GmbH
+        10BD    82566DM-2 Intel Gigabit network connection
+        4023    BWU713 v2.0 Blitzz Wireless G
+124C    Solitron Technologies Inc.
+        0220    . .
+124D    Stallion Technologies
+        0000    EasyConnect 8/32 
+        0002    EasyConnect 8/64 
+        0003    EasyIO PCI 
+124E    Cylink
+124F    Infortrend Technology Inc
+        0041    IFT-2000 PCI RAID Controller
+1250    Hitachi Microcomputer System Ltd.
+        1978    
+        2898    
+1251    VLSI Solution OY
+1253    Guzik Technical Enterprises
+1254    Linear Systems Ltd.
+1255    Optibase Ltd.
+        1110    MPEG Forge 
+        1210    MPEG Fusion 
+        2110    VideoPlex-pci VideoPlex pci bpc1825 rev a
+        2120    VideoPlex plus VideoPlex BPC 1851 A
+        2130    VideoQuest 
+1256    Perceptive Solutions Inc.
+        4201    PCI-2240i EIDE Adapter
+        4401    PCI-2220i Dale EIDE Adapter
+        5201    PCI-2000 IntelliCache SCSI Adapter
+1257    Vertex Networks Inc.
+1258    Gilbarco Inc.
+        1988    0001 
+1259    Allied Telesyn International
+        2503    Realtek 8139b 
+        2560    82845G AT-2560 Fast Ethernet Adapter (i82557B)
+        c107    Realtek 8110S 
+125A    ABB Power Systems
+125B    Asix Electronics Corp.
+        0B95    AX88772A USB2.0 to 10/100M Fast Ethernet Controller
+        1400    AX88140A ASIX AX88140 Based PCI Fast Ethernet Adapter
+        1720    AX88172 USB2 to Fast Ethernet Adapter
+125C    Aurora Technologies Inc.
+125D    ESS Technology
+        0000    ESS336H PCI Fax Modem (early model)
+        1961    Multimedia Device ESS Solo-1 Soundcard
+        1968    ES2839 Maestro-2 PCI audio accelerator
+        1969    ES1969 Solo-1 PCI AudioDrive family
+        1978    ES1978 ESS Maestro-2E PCI Audiodrive
+        1980    0x0401 subsys_0012103c_rev_12
+        1988    ES1999 ESS Allegro PCI Audio (WDM)
+        1989    ES1980 ESS Maestro 3 PCI Audio Accelerator
+        1990    ES2898S 
+        1992    
+        1998    Maestro 3i Maestro 3i
+        1999    ES1980S TAWE0548S
+        199B    ES1938/41/46 solo audio Maestro-3.COMM PCI Voice+audio
+        2808    ES336H PCI Fax Modem (later model)
+        2828    ES2828S TeleDrive
+        2838    PCI\VEN_125D&DEV_2838&SUBSYS_2838125D&REV_01 PCI Data Fax Modem
+        2839    2838 Superlink Modem/V.92 chipset 56K
+        2898    2898 TelDrive ES56T-PI family V.90 PCI modem
+125E    Specialvideo Engineering SRL
+125F    Concurrent Technologies Inc.
+        2084    AMCC S5933 AMCC Bridge + 2 x Super I/O (National PC97338)
+1260    Intersil Corporation
+        3860    PRISM 2.5  PRISM 2.5 802.11b 11Mbps Wireless Controller
+        3872    PRISM 3 LAN-Express IEEE 802.11b PCI Adapter
+        3873    ISL3886A PRISMII.5 IEE802.11g Wireless LAN
+        3886    200206BE Creatix CTX405 WLAN Controller / ZyAir G100 - WLAN
+        3890    ISL3890 PRISM GT 802.11g 54Mbps Wireless Controller
+        8130    HMP8130 NTSC/PAL Video Decoder
+        8131    HMP8131 NTSC/PAL Video Decoder
+1261    Matsushita-Kotobuki Electronics Indu
+1262    ES Computer Co. Ltd.
+1263    Sonic Solutions
+1264    Aval Nagasaki Corp.
+1265    Casio Computer Co. Ltd.
+1266    Microdyne Corp.
+        0001    023132 NE10/100 Adapter (i82557B)
+        1910    NE2000Plus (RT8029) Ethernet Adapter
+1267    S.A. Telecommunications
+        1016    NICCY PCI card
+        4243    Satellite receiver board / MPEG2 decoder
+        5352    PCR2101 
+        5A4B    telsatturbo 
+1268    Tektronix
+        0204    Unknown Tektronix IO Processor / Tektronix PCI Acquisition Interface Rev 204
+1269    Thomson-CSF/TTM
+126A    Lexmark International Inc.
+        2698    631xesb/6321esb/3100 sm bus controller
+        269B    631xESB/6321ESB/3100 SM Bus Controller
+126B    Adax Inc.
+126C    Nortel Networks Corp.
+        1F1F    e-mobility 802.11b Wireless LAN PCI Card
+126D    Splash Technology Inc.
+126E    Sumitomo Metal Industries Ltd.
+126F    Silicon Motion
+        0501    SM501/SM502 Mobile Multimedia Companion Chip (MMCC)
+        0710    SM710 LynxEM
+        0712    SM712 LynxEM+
+        0720    SM720 / SM722 Lynx3DM
+        0810    SM810 LynxE
+        0811    SM811 LynxE
+        0820    SM820 Lynx3D
+        0910    SM910 SILICON MOTION
+        2260    SM2260 PCIe SSD (NVMe/AHCI)
+1270    Olympus Optical Co. Ltd.
+1271    GW Instruments
+1272    themrtaish
+        0780    PCI\VEN_8086&DEV_1C3A&SUBSYS_307c17aa &7rev_04 PCI\VEN_8086&DEV_1C3A
+        1272    PCI\VEN_8086&DEV_1C3A&CC_078000 PCI\VEN_8086&DEV_1C3A&SUBSYS_1C3A1458
+        1c3A    0X78000 0X78000
+        9876    PCI\VEN_1272&DEV_0780&SUBSYS_00000008&REV_7A\3&61A PCI\VEN_1272&DEV_0780&SUBSYS_00000008&REV_7A\3&61AAA01&0&58
+1273    Hughes Network Systems
+        0002    DirecPC t9p17af-01
+1274    Ensoniq
+        0X1005  Serial PCI Port
+        1274    1880x1274 multimedia audio device
+        1371    ES 1371 Creative AudioPCI (ES1371,ES1373)
+        1373    ES1373 Sound Blaster Audio(PCI)
+        5000    ES1371 AudioPCI
+        5880    5880x Soundblaster (CT4750)
+        9876    
+1275    Network Appliance
+1276    Switched Network Technologies Inc.
+1277    Comstream
+1278    Transtech Parallel Systems
+        0701    TPE3/TM3 PowerPC Node
+        1001    TMB17 TMB17 Motherboard
+1279    Transmeta Corp.
+        0060    TM8000 Efficeon Virtual Northbridge
+        0061    TMTM8000 Efficeon AGP Bridge
+        0295    Virtual Northbridge
+        0395    LongRun Northbridge
+        0396    SDRAM Controller
+        0397    18490397 BIOS scratchpad
+127B    Pixera Corp
+127C    Crosspoint Solutions Inc.
+127D    Vela Research LP
+127E    Winnov L.P.
+        0010    Unknown Videum 1000 AV Plus
+127F    Fujifilm
+1280    Photoscript Group Ltd.
+1281    Yokogawa Electronic Corp.
+1282    Davicom Semiconductor Inc.
+        1282    DM9102AF DEV
+        9009    DM9009 Ethernet Adapter
+        9100    
+        9102    DM9102/A/AF 10/100 Mbps Fast Ethernet Controller
+1283    Waldo
+        0801    Audio Digital Controller Audio Digital Controller
+        673A    IT8330G IDE Controller
+        8152    IT8152F/G Advanced RISC-to-PCI Companion Chip
+        8172    IT8172G Ultra RISC (MIPS, SH4) Companion Chip
+        8211    IT8211F ATA/ATAPI Controller
+        8212    ITE8212 ATA 133 IDE RAID Controller
+        8213    IT8213F IDE Controller
+        8330    IT8330G Host Bridge
+        8872    IT8871/72 PCI-ISA I/O chip with SMB & Parallel Port
+        8875    IT8875F PCI Parallel Port
+        8888    IT8888F PCI to ISA Bridge
+        8889    IT8889F sound
+        9876    IT8875F PCI I/O CARD
+        E886    IT8330G PCI to ISA Bridge
+1285    Platform Technologies Inc.
+        0100    ES1849 Maestro-1 AudioDrive
+1286    MAZeT GmbH
+1287    LuxSonor Inc.
+        001E    LS220D DVD Decoder
+        001F    LS220C DVD Decoder
+        0020    LS242 MPEG/DVD video decoder
+1288    Timestep Corp.
+1289    AVC Technology Inc.
+        1006    1106 1708
+128A    Asante Technologies Inc.
+        F001    Ethernet 10/100 controller ethernet
+128B    Transwitch Corp.
+128C    Retix Corp.
+128D    G2 Networks Inc.
+        0021    ATM Adapter
+128F    Tateno Dennou Inc.
+1290    Sord Computer Corp.
+        0010    ? ?
+1291    NCS Computer Italia
+1292    Tritech Microelectronics Intl PTE
+1293    Media Reality Technology
+1294    Rhetorex Inc.
+1295    Imagenation Corp.
+1296    Kofax Image Products
+1297    Shuttle Computer
+1298    Spellcaster Telecommunications Inc.
+1299    Knowledge Technology Laboratories
+129A    Curtiss Wright Controls Electronic Systems
+        0415    PBT-415 PCI 66MHz Analyzer and 33MHz Exerciser
+        0515    PBT-515 PCI 66MHz Analyzer and Exerciser
+        0615    PBT-615 PCI 66MHz and PCI-X 100MHz Bus Analyzer and Exerciser
+        0715    Vanguard PCI/PMC/cPCI PCI 66MHz and PCI-X 133MHz Bus Analyzer and Exerciser
+        DD10    DPIO Digital Parallel Input Output Device 32bit, 33MHz PCI bus
+        DD11    DPIO2 Digital Parallel Input Output Device 64bit, 33MHz PCI bus
+        DD12    DPIO2-66 Digital Parallel Input Output Device 64bit, 66MHz PCI bus
+129B    Image Access
+129D    CompCore Multimedia Inc.
+129E    Victor Co. of Japan Ltd.
+129F    OEC Medical Systems Inc.
+12A0    Allen Bradley Co.
+        0008    1784-PKTX Allen-Bradley 1784-PKTX
+12A1    Simpact Inc
+12A2    NewGen Systems Corp.
+12A3    Lucent Technologies AMR
+        ECB8    1646T00 V.92 Lucent Modem
+12A4    NTT Electronics  Corp.
+12A5    Vision Dynamics Ltd.
+12A6    Scalable Networks Inc.
+12A7    AMO GmbH
+12A8    News Datacom
+12A9    Xiotech Corp.
+12AA    SDL Communications Inc.
+        5568    Wan405 WANic 400 series X.21 controller
+        556C    NAI HSSI Sniffer PCI Adapter
+12AB    Yuan Yuan Enterprise Co. Ltd.
+        3000    JRS-3DS100 PCI
+12AC    MeasureX Corp.
+12AD    MULTIDATA GmbH
+        0010    1 HERMES-S0
+        0020    1 HERMES-PRI
+        0080    1 HERMES-PRI/PCIX
+12AE    Alteon Networks Inc.
+        0001    3C986 ACEnic 1000 BASE-SX Ethernet adapter
+        0002    3C986-T Copper Gigabit Ethernet Adapter
+12AF    TDK USA Corp.
+12B0    Jorge Scientific Corp.
+12B1    GammaLink
+12B2    General Signal Networks
+12B3    Interface Corp. Ltd.
+12B4    Future Tel Inc.
+12B5    Granite Systems Inc.
+12B7    Acumen
+12B8    Korg
+12B9    3Com Corporation
+        00c2    00000005 pci simple communication controller
+        1006    5610 5610 56K FaxModem WinModem
+        1007    AD1807JS US Robotics 56K DATA FAX WINMODEM
+        1008    USR5610B USR5610B (0005610-02) 56K Performance Pro Modem (PCI Internal)
+        12b9    00000005 pci simple communication controller
+        3F0     3CP2977 US Robotics 56K Fax PCI aka Model 0726, V.90 56K Internal Faxmodem
+12BA    Bittware, Inc
+        0032    Hammerhead-Lite-PCI DSP Prototyping & Development Card
+        0041    Stratix5 Family FPGA Altera FPGA
+12BB    Nippon Unisoft Corp.
+12BC    Array Microsystems
+12BD    Computerm Corp.
+12BF    Fujifilm Microdevices
+12C0    Infimed
+12C1    GMM Research Corp.
+        9080    Sync4hs/CCP/PCI/MP Communications Processor
+12C2    Mentec Ltd.
+12C3    Holtek Microelectronics Inc.
+        0058    HT80232 LAN Adapter (NE2000-compatible)
+        5598    HT80229 Ethernet Adapter (NE2000-compatible)
+12C4    Connect Tech Inc.
+        0001    
+        0002    
+        0003    
+        0004    
+        0005    Blue Heat-8 RS232 BlueHeat 8 Port RS232 Serial Board
+        0006    
+        0007    
+        0008    
+        0009    
+        000A    
+        000B    
+        000C    
+        000D    
+        000E    
+        000F    
+        0300    
+        0301    
+        0302    
+        0303    
+        0304    
+        0305    
+        0306    
+        0307    
+        0308     32 Starcom UM100 Wireless modem for WiMax 
+        0309    
+        030A    
+        030B    
+12C5    Picture Elements Inc.
+        007F    ISE PEI Imaging Subsystem Engine
+        0081    PCIVST PCI Thresholding Engine
+        0085    Video Simulator/Sender
+        0086    THR2 Multi-scale Thresholder
+12C6    Mitani Corp.
+12C7    Dialogic Corp.
+        0546    kssjsjj D120JCT-LS Card
+        0561    BRI/2 Type Card (Voice Driver)
+        0647    D/240JCT-T1 Card
+        0648    064812C7 D/300JCT-E1 Card
+        0649    030000 D/300JCT-E1 Card
+        0651    MSI PCI Card
+        0673    BRI/160-PCI Card
+        0674    BRI/120-PCI Card
+        0675    BRI/80-PCI Card
+        0676    067612C7 D/41JCT Card
+        0685    D/480JCT-2T1 Card
+        0687    D/600JCT-2E1 (75 Ohm) Card
+        0689    D/600JCT-2E1 Dialogic 2E1 - JCT series
+        0707    D/320JCT (Resource Only) Card
+        0708    D/160JCT (Resource Only) Card
+12C8    G Force Co. Ltd.
+12C9    Gigi Operations
+12CA    Integrated Computing Engines, Inc.
+12CB    Antex Electronics Corp.
+        0027    StudioCard studiocard
+        002D    BX-12 agp
+        002E    SC-2000 
+        002F    LX-44 
+        0030    SC-22 
+        0031    BX-44 
+        0032    LX-24M 20-bit 2-in, 4-out audio card w/MPEG-2
+        0033    LX-22M 
+        0034    BX-8 
+        0035    BX-12e 
+12CC    Pluto Technologies International
+12CD    Aims Lab
+12CE    Netspeed Inc.
+12CF    Prophet Systems Inc.
+12D0    GDE Systems Inc.
+12D1    Huawei Technologies Co., Ltd.
+        1001    MSM6246 Huawei E1750 3G modem (labled T-Mobile
+        1003    173 HUAWEI Mobile Connect - 3G Modem
+        140B    EC159 HUAWEI MOBILE BROADBAND MODEM
+        1412    09HT1407 MW6208E
+        1446    E1800 3G Modem
+        14c5    K4204 HSPA+ USB Stick
+        1506    E5776 Huawei Technologies Co., Ltd. E398 LTE/UMTS/GSM Modem/Networkcard
+        1520    -e620 -vodacom mobile connect
+        1802    unknown unknown
+        3609    N/A M88++
+12D3    Vingmed Sound A/S
+12D4    Ulticom, Inc.
+        0301    EP1S SS7 Telecommunications Interface Adapter
+12D5    Equator Technologies
+        1000    MAP-CA Broadband Signal Processor
+        1002    MAP-1000 Digital Signal Processor
+12D6    Analogic Corp.
+12D7    Biotronic SRL
+12D8    Pericom Semiconductor
+        2304    PI7C9X2G304SL GENII PCI Express Packet Switch
+        71E2    PI7C7300 3 Port PCI to PCI bridge
+        8140    PI7C8140 4 Port PCI to PCI bridge
+        8150    PI7C8150 2-Port PCI to PCI Bridge
+        8152    PI7C8152 2-Port PCI-To-PCI Bridge
+        A404    PI7C9X20404SL PCIe Packet Switch
+        E111    P17C9X PCI to PCIe Bridge
+        e130    PI7C9X130 PCI-X Bridge
+12D9    Aculab Plc.
+12DA    TrueTime
+12DB    Annapolis Micro Systems Inc.
+        0003    FoxFire II
+12DC    Symicron Computer Communication Ltd.
+12DD    Management Graphics Inc.
+12DE    Rainbow Technologies
+        0200    2005063294 Cryptoswift 200
+12DF    SBS Technologies Inc.
+        2102    Infineon PEB 20534 Communications Controller
+        8236    Unknown PCI Controller
+12E0    Chase Research PLC
+        0010    ST16C654 Quad UART
+        0020    ST16C654 Quad UART
+        0030    ST16C654 Quad UART
+12E1    Nintendo Co. Ltd.
+12E2    Datum Inc. Bancomm-Timing Division
+12E3    Imation Corp. - Medical Imaging Syst
+12E4    Brooktrout Technology Inc.
+        1000    TR1000 PRI PRI Controller
+        1140    NV34 ISDN Controller
+        B005    TR1000 BRI BRI Controller
+        B006    TR1000 BRI BRI Controller
+12E6    Cirel Systems
+12E7    Sebring Systems Inc
+12E8    CRISC Corp.
+12E9    GE Spacenet
+12EB    Aureal Semiconductor
+        0001    AU8820 Vortex 1 Digital Audio Processor
+        0002    AU8830A2 Vortex 2 Audio Processor
+        0003    312EB&REV3 Aureal Soundcard
+12EC    3A International Inc.
+        8139    0xxxx 0xxxx
+        8140    10 asf
+12ED    Optivision Inc.
+12EE    Orange Micro, Inc.
+12EF    Vienna Systems
+12F0    Pentek
+12F1    Sorenson Vision Inc.
+12F2    Gammagraphx Inc.
+        1002    215RAAGCGA11F Grapics Radeon X850
+        3059    VT8235 AC97 Enhanced Audio Controller - the 8251 controller is different
+12F4    Megatel
+12F5    Forks
+12F7    Cognex
+12F8    Electronic-Design GmbH
+        0002    VideoMaker s3 trio
+12F9    FourFold Technologies
+12FB    Spectrum Signal Processing
+12FC    Capital Equipment Corp
+        5cec    PCI-488 GPIB IEEE 488
+12FE    esd Electronic System Design GmbH
+1303    Innovative Integration
+        0001    0239 cM67 CompactPCI DSP Card
+        0002    1 M44/cM44 DSP board
+        0003    1 Quattro6x DSP board
+        0004    1 Chico/ChicoPlus Data Acquisition Board
+        0005    1 Code Hammer Jtag Debugger board
+        0006    1 Matador DSP board
+        0007    1 Quixote DSP board
+        0008    1 Quadia C64x DSP
+        0009    1 Quadia DSP Baseboard
+1304    Juniper Networks Inc.
+        0004    PTX SAm FPGA PTX SAM FPGA
+1307    ComputerBoards
+        0001    PCI-DAS1602/16 
+        0006    PCI-GPIB PCI 488.2
+        000B    PCI-DIO48H 
+        000C    PCI-PDISO8 
+        000D    PCI-PDISO16 
+        000F    PCI-DAS1200 
+        0010    PCI-DAS1602/12 
+        0014    PCI-DIO24H 24 Bit Digital Input/Output Board
+        0015    PCI-DIO24H/CTR3 
+        0016    PCI-DIO24H/CTR16 
+        0017    PCI-DIO96H 
+        0018    PCI-CTR05 
+        0019    PCI-DAS1200/JR xkbhavu
+        001A    PCI-DAS1001 
+        001B    PCI-DAS1002 
+        001C    PCI-DAS1602JR/16 AR2425
+        001D    PCI-DAS6402/16 
+        001E    PCI-DAS6402/12 
+        001F    PCI-DAS16/M1 
+        0020    PCI-DDA02/12 
+        0021    PCI-DDA04/12 
+        0022    PCI-DDA08/12 
+        0023    PCI-DDA02/16 
+        0024    PCI-DDA04/16 
+        0025    PCI-DDA08/16 
+        0026    PCI-DAC04/12-HS 
+        0027    PCI-DAC04/16-HS 
+        0028    PCI-DIO24 24 Bit Digital Input/Output Board
+        0029    PCI-DAS08 
+        002C    PCI-INT32 PCI-INT32
+        0033    PCI-DUAL-AC5 
+        0034    PCI-DAS-TC 
+        0035    PCI-DAS64/M1/16 65+6
+        0036    PCI-DAS64/M2/16 Dell
+        0037    PCI-DAS64/M3/16 
+        004C    PCI-DAS1000 
+        004D    PCI-QUAD04 
+        0064    PCI-CTR10 10 channels, 16 bit counter/timer with 32-Bits of Digital I/O
+        0361    ? ?
+1308    Jato Technologies Inc.
+        0001    NetCelerator Adapter
+130A    Mitsubishi Electric Microcomputer
+130B    Colorgraphic Communications Corp
+        130b    0x9876 0x9876
+130F    Advanet Inc.
+1310    Gespac
+        0003    9060 CompactPCI Interface
+        000D    FPGA PCI Bridge
+1312    Microscan Systems Inc
+1313    Yaskawa Electric Co.
+1316    Teradyne Inc.
+1317    ADMtek Inc
+        0531    nm0403A03461H121S122P ADMtek AN986
+        0981    AN981 FastNIC 10/100 Fast Ethernet Adapter
+        0985    an983B Linksys LNE 100TX Fast Ethernet Adapter(LNE100TX v4)
+        1985    AN985 CardBus 10/100 Fast Ethernet&#1050;&#1086;&#1085;&#1090;&#1088;&#1086;&#1083;&#1083;&#1077;&#1088;
+        2850    016 HSP56 MicroModem
+        5120    ADM5120 ADMtek ADM5120 SOC (rev: 0)
+        7892    PCT 789T-A HSP56 MicroModem
+        8201    ADM8211 802.11b Wireless PCI Card
+        9511    ADM9511 PCI 10/100 Fast Ethernet Adapter
+        9513    ADM9513 PCI 10/100 Fast Ethernet Adapter
+        8201    13d1 1317
+1318    Packet Engines, Inc.
+        0911    G-NIC II 1000BT Network Interface Card
+1319    Forte Media
+        0801    FM0801-as PCI Card MediaForte made in singapore (driver - ct
+        0802    FM801-as Xwave PCI Joystick
+        1000    FM801-as PCI Audio
+        1001    FM801 Joystick
+        1319    FM0801-as Xwave PCI audio controller
+        4901    FM801-AU ForteMedia PCI Audio Card
+        802     fm801-au PCI Audio
+131F    SIIG
+        2002    72svec CyberSerial 16850
+        2011    1655 Siig Inc Duet 1S(16550)+1P
+        2012    Duet 1S(16850)+1P
+        2020    SIIG cyber8000 Communication controller
+        2030    SIIG CyberSerial PCI 16C550 SIIG Cyber Serial Dual PCI Board
+        2042    Trio 1S(16850)+2P
+        2050    Siig Inc CyberSerial (4-port) 16550 Siig Inc CyberSerial (4-port) 16550
+        2051    CyberSerial 16650
+        2052    CyberSerial 16850
+        2060    JJ_P21022-B Trio 2S(16550)+1P
+        2061    Trio 2S(16650)+1P
+        2062    1969 Trio 2S(16850)+1P
+        9876    JJ_P21022-B Trio 2S(16550)+1P
+1325    austriamicrosystems
+1326    Seachange International
+1328    CIFELLI SYSTEMS CORPORATION
+        2048    
+        8888    rev 1.5 cPEG. C 3.0 DVD/MPEG2 decoder
+1331    RadiSys Corporation
+1332    Curtiss-Wright Controls Embedded Computing
+        5410    MM-5410D PCI 32bit Bulk Memory w/DMA
+        5415    MM-5415CN PCI Battery Backed SDRAM Adapter
+        5425    MM-5425CN PCI Memory Module with Battery Backup
+        6140    MM-6140D Memory Module
+1335    Videomail Inc.
+133D    Prisa Networks
+        1000    SST-5136-PFB-PCI Industrial I/O Card
+133F    SCM Microsystems
+1342    Promax Systems Inc
+1344    Micron Technology, Inc.
+        3240    CopperHead CopperTail SC1 AMC AC97
+        3320    MT8LLN21PADF North Bridge
+        3321    21PAD North Bridge
+        3470    MT7LLN22NCNE South Bridge
+        4020    123 CopperHead CopperTail SC1 IDE Controller4
+        4030    CopperHead CopperTail SC1 USB Controller
+1347    Spectracom Corporation
+134A    DTC Technology Corp.
+        0001    F01 2ASV17184.1 Domex DMX 3191D PCI SCSI Controller
+        0002    Domex DMX3192U/3194UP SCSI Adapter
+        3510A   DTC50C18 scsi
+134B    ARK Research Corp.
+134C    Chori Joho System Co. Ltd
+134D    PCTEL Inc.
+        2188    fa82537ep intel
+        2189    HSP688T pctel HSP56 V92 PCI Modem
+        2486    82537 V.92 MDC Modem
+        7890    8086 HSP56 MicroModem
+        7891    PCT 789T-c1 HSP MicroModem 56
+        7892    PCT 789T-A HSP56 MicroModem
+        7893    S911 K017 HSP MicroModem 56
+        7894    688w HSP MicroModem 56
+        7895    PCT789T HSP MicroModem 56
+        7896    pct789t-c HSP MicroModem 56
+        7897    97860963 HSP MicroModem 56/PCT789T
+        9714    PCT 288-1A PCTEL
+        D800    pct388p-a pctel 56k modem
+        8086    hfp56 dev
+135A    Brain Boxes Limited
+        0042    16550 4-port RS-232
+        0181    16550 PCI LPT and RS-232
+        0224    PLX9050 PLX PCI Bus Logic
+        0228    f97260118 pq100akj9737
+135B    Giganet Inc.
+135C    Quatech Inc
+135D    ABB Network Partner AB
+135E    Sealevel Systems Inc.
+        0EC3    8012e PCIe 8 Relay Output/8 Isolated Input Board 
+        5101    5101 Route 56
+        5102    PCI-ACB RS-232 synchronous card
+        7101    Single Port RS-232/422/485/520
+        7201      Dual Port RS-232/422/485 Interface
+        7202    Dual Port RS-232 Interface
+        7401    Four Port RS-232 Interface
+        7402    Four Port RS-422/485 Interface
+        7801    Eight Port RS-232 Interface
+        8001    8001 Digital I/O Adapter
+135F    I-Data International A-S
+1360    Meinberg Funkuhren GmbH & Co. KG
+        0101    PCI32 DCF77 Radio Clock
+        0102    PCI509 DCF77 Radio Clock
+        0103    PCI510 DCF77 Radio Clock
+        0104    PCI511 DCF77 Radio Clock
+        0105    PEX511 DCF77 Receiver
+        0106    PZF180PEX High Precision DCF77 Radio Clock
+        0201    GPS167PCI GPS Receiver
+        0202    GPS168PCI GPS Receiver
+        0203    GPS169PCI GPS Receiver
+        0204    GPS170PCI GPS Receiver
+        0205    GPS170PEX GPS Receiver
+        0206    GPS180PEX GPS receiver
+        0207    GLN180PEX GPS/GLONASS receiver
+        0208    GPS180AMC GPS Receiver
+        0301    TCR510PCI IRIG Timecode Reader
+        0302    TCR167PCI IRIG Timecode Reader
+        0303    TCR511PCI IRIG Timecode Reader
+        0304    TCR511PEX IRIG Timecode Receiver
+        0305    TCR170PEX IRIG Timecode Reader
+        0306    TCR180PEX IRIG Timecode Reader
+        0501    PTP270PEX PTP/IEEE1588 Slave Card
+        0601    FRC511PEX Free Running Clock
+1361    Soliton Systems K.K.
+1363    Phoenix Technologies Ltd
+1365    Hypercope Corp.
+        9050    HYSDN 
+1366    Teijin Seiki Co. Ltd.
+1367    Hitachi Zosen Corporation
+1368    Skyware Corporation
+1369    Digigram
+136B    Kawasaki Steel Corporation
+136C    Adtek System Science Co Ltd
+1375    Boeing - Sunnyvale
+        2571    NA NA
+137A    Mark Of The Unicorn Inc
+        0001    
+        0003    PCI-424 Original PCI-424 Original
+        0004    PCI-424 X PCI-424 X
+        0005    PCIe-424 PCIe-424
+137B    PPT Vision
+137C    Iwatsu Electric Co Ltd
+137D    Dynachip Corporation
+137E    Patriot Scientific Corp.
+1380    Sanritz Automation Co LTC
+1381    Brains Co. Ltd
+1382    Marian - Electronic & Software
+        0001    f97260118 Sek'D ARC88 professional soundcard
+        2009    PLX TECHNOLOGY \n PCI9052 \n 0435 \n BX9497.1 MALA SEK'D Prodif 96 Pro - professional audio card
+        2048    2048 Prodif Plus sound card
+        2088    Marc 8 Midi 8-in, 8-out sound card
+1384    Stellar Semiconductor Inc
+1385    Netgear
+        4100    MA401 802.11b Wireless Adapter
+        4105    
+        620A    GA620 Toshiba
+        622A    GA622 
+        630A    GA630 
+        8169    10ec Gigabit Ethernet Adapter
+        81690   GA630 Fast Ethernet Adapter
+        F311    FA311 Fast Ethernet Adapter
+        F312    
+1387    Curtiss-Wright Controls Electronic Systems
+        4640    -none- sl240
+        5310    N/A SCRAMNet GT200
+1388    Hitachi Information Technology Co Ltd
+1389    Applicom International
+        0001    PCI1500PFB Intelligent fieldbus Adapter
+        0104    PCI-CANIO PCI-CANIO adapter
+138A    Validity Sensors, Inc.
+        0001    0001 REV_0372
+        0005    0008 VFS301 Fingerprint Scanner
+        0006    0006 VFS351 Fingerprint Scanner
+        0007    0007 VFS451 Fingerprint Scanner
+        0009    0008 VFS421 Fingerprint Scanner
+        0011    11 Validity Fingerprint Reader
+        0018    Biometric Devices Validity Sensors, Inc. (WBF) (PID=0018)
+        003C    0086 VFS431 Validity-Fingerprint Driver
+        003D    0104 Validity Fingerprint Sensor
+        11      VFS5011 Fingerprint Reader
+138B    Tokimec Inc
+138E    Basler GMBH
+138F    Patapsco Designs Inc
+1390    Concept Development Inc.
+1393    Moxa Technologies Co Ltd
+        1010    
+        1020    
+        1022    unknown unknown
+        1040    C104H/PCI SmartIo
+        1041    CP104U series 
+        1042    
+        104h    C104H/PCI Smartio
+        1140    
+        1141    
+        1320    CP-132 Industio
+        1321    
+        1340    CP--134U-I-DB9 V2.3 UPCI Board UniversalPCI board, 4 ports RS-422/485 with Isolation DB9M
+        1401    
+        1680    C168H/PCI Smartio
+        1681    CP-168U CP-168U Smart Serial Board
+        2040    CP-204J Intellio
+        2180    C218 Intellio Turbo PCI
+        2210    --- ---
+        2240    --- ---
+        3200    C320 Intellio Turbo PCI
+        5020    e400 
+        6800    0x0000 dvr capture card
+1394    Level One Communications
+        0001    0x1394 Gigabit Ethernet Adapter
+        1394    INTEL 1394 Net adapter 
+1395    Ambicom Inc
+1396    Cipher Systems Inc
+1397    Cologne Chip Designs GmbH
+        0B4D    HFC-8S 16B8D8S0 ISDN HDLC FIFO Controller
+        2BD0    HFC-PCI A ISDN 2BDS0 ISDN HDLC FIFO Controller
+        8B4D    HFC-4S ISDN 8B4D4S0 ISDN HDLC FIFO Controller
+        B000    B000 HCF-PCI card
+        B006    B006 HCF-PCI card
+        B007    B007 HCF-PCI card
+        B008    n/a usb webcam
+        B009    B009 HCF-PCI card
+        B00A    B00A HCF-PCI card
+        B00B    B00B HCF-PCI card
+        B00C    B00C HCF-PCI card
+        B100    B100 HCF-PCI card
+1398    Clarion Co. Ltd
+139A    Alacritech Inc
+        0007    SES2000 Alacritech iSCSI Controller
+139D    Xstreams PLC/ EPL Limited
+139E    Echostar Data Networks
+13A0    Crystal Group Inc
+13A1    Kawasaki Heavy Industries Ltd
+13A3    HI-FN Inc.
+        0005    7751 Security Processor
+        0006    6500 Public Key Processor
+        0007    7811 Security Processor
+        0012    7951 Security Processor
+        0014    7814 Security Processor
+        0015    8065 Security Processor
+        0017    8165 Security Processor
+        0018    8154 Security Processor
+        001d    7956 Cryptographic Processor
+        0020    7954/7955 Cryptographic Processor
+        0026    8155 Security Processor
+        16      8065 Security Processor
+13A4    Rascom Inc
+13A7    amc330
+        6240    Network Controller BSRV2-301A
+13A8    Exar Corp.
+        0152    XR17C152 Dual UART
+        0154    XR17C154 Four Channel PCI Bus UART
+        0158    XR17C158 Eight Channel PCI Bus UART (5V)
+        0354    XR17V354 High Performance Quad PCI Express UART
+        0358    XR17V358 High Performance Octal PCI Express UART
+13A9    Siemens Healthcare
+13AA    Nortel Networks - BWA Division
+13AF    T.Sqware
+13B1    Tamura Corporation
+13B4    Wellbean Co Inc
+13B5    ARM Ltd
+13B6    DLoG Gesellschaft f.r elektronische Datentechnik mbH
+        13b6    S/N 26296347 sguiu
+13B8    Nokia Telecommunications OY
+13BD    Sharp Corporation
+13BF    Sharewave Inc
+13C0    Microgate Corp.
+        0010    SyncLink Adapter single port multiprotocol serial adapter
+        0020    SyncLink SCC low speed single port multiprotocol serial adapter
+        0030    SyncLink 4 Port Adapter 4 port multiprotocol serial adapter
+        0070    SyncLink GT Adapter single port multiprotocol serial adapter
+        0080    SyncLink GT4 Adapter 4 port multiprotocol serial adapter
+        0090    SyncLink AC Adapter one port asynchronous serial adapter
+        00a0    SyncLink GT2 Adapter 2 port multiprotocol serial adapter
+        0210    SyncLink Serial Adapter version 2 single port multiprotocol serial adapter
+13C1    LSI
+        1000    9548qad ATA-RAID Controller
+        1001    7000/8000 series ATA-133 Storage Controller
+        1002    9000 series SATA/PATA Storage Controller
+        1003    9550SX/9590SE Series SATA2 Raid Controller
+        1004    9650SE Series PCI-Express SATA2 Raid Controller
+        1005    9690SA Series PCI-Express SATA2/SAS Raid Controller
+        1010    9750 Series PCI-Express2 SAS2/SATA2 Raid Controller
+13C2    Technotrend Systemtechnik GMBH
+13C3    Janz Computer AG
+13C7    Blue Chip Technology Ltd
+        0ADC    Multi-Function Analogue/Digital IO card
+        0B10    . Parallel I/O Card
+        0D10    . Digital I/O Card
+        5744    . Watchdog Card
+13CC    Metheus Corporation
+13CF    Studio Audio & Video Ltd
+13D0    B2C2 Inc
+        2103    T228502 B2C2 Sky2PC Core Chip sky star 2 <technisat>
+        2200    
+13D1    AboCom Systems, Inc
+        AB02    PCMCIA 10/100 mbps Ethernet Adapter
+        AB03    
+        AB06    FE2000VX CardBus /Atelco Fibreline Ethernet Adptr
+        AB08    SMC8035TX EZ Card. 10/100 Fast Ethernet CardBus Adapter
+13D4    Graphics Microsystems Inc
+13D6    K.I. Technology Co Ltd
+13D7    Toshiba Engineering Corporation
+        0205    6208 toshiba
+        8086    6205 toshiba
+13D8    Phobos Corporation
+        1000    XQ11800FP XaQti 1000Mbit/sec Gbit Ethernet Controller
+13D9    Apex Inc
+13DC    Netboost Corporation
+13DE    ABB Robotics Products AB
+13DF    E-Tech Inc.
+        0001    PCI56RVP Modem
+13E0    GVC Corporation
+13E3    Nest Inc
+13E4    Calculex Inc
+13E5    Telesoft Design Ltd
+13E9    Intraserver Technology Inc
+13EA    Dallas Semiconductor
+        3131    DS3131 BoSS Bit Synchronous HDLC Controller
+        3134    DS3134 Chateau Channelized T1/E1/HDLC Controller
+13F0    IC Plus Corporation
+        0200    0x0200 IP100A Integrated 10/100 Ethernet MAC + PHY
+        0201    ST201 Fast Ehternet Adapter
+        0300    NX1001 Network Adapter
+        1021    Tamarack 9021A Tamarack 9021A Gigabit Ethernet adapter
+        1023    NX1101a Gigabit Ethernet Controller
+        13F0    PCI\VEN_13F0&DEV_0200&SUBSYS_82131043&REV_41\4&19 82131043
+13F1    OCE - Industries S.A.
+        0028    NV05 MCP67 High Definition Audio
+13F4    Troika Networks Inc
+13F6    C-Media Electronics Inc.
+        0211    pcnet ht2001 9932 serl
+        00111   520098396000734 sound card
+        0100    CMI8338/PCI C3DX PCI
+        0101    CMI8338-031 PCI Audio Device
+        0111    0434119232 PCI-SCCME8738LX-2
+        0112    CMI-8378B/PCI-6CH PCI Audio Chip
+        0191    PCI\VEN_13F6&DEV_0111&REV_10 CMI 8738 8CH Sound Card
+        0211    PCI_021113F6&rev_10\2&EBB567F&0&79  Driver controller pci simple comunications - PCtel HSP56 Micro Modem Driver  
+        0300    0x4005 pci audio driver
+        111     PCI\VEN_13F6&DEPCI\VEN_13F6&DEV_0511&SUBSYS_051113 C-Media Audio Controller
+        8788    CMI8788/PCI-8CH C-Media Oxygen HD
+        9876    CMI8738 C-Media Audio Controller
+        9891    CMI8738 C-Media Audio Controller
+13F9    NTT Advanced Technology Corp.
+13FA    Pentland Systems Ltd.
+13FB    Aydin Corp
+13FD    Micro Science Inc
+        160E    Initio1606l SATA/150 &#1091;&#1089;&#1090;&#1088;&#1086;&#1081;&#1089;&#1090;&#1074;&#1072; USB 2.0
+        161F    1D59CB92 s
+        1840    INIC-1608L SATA/150 device to USB 2.0 Host interface (http://www.initio.com/Html/inic-1608.html)
+13FE    Advantech Co., Ltd.
+        1011    13FE Advantech SRamDisk Device
+        1240    PS2134CE-0 4-Axis Stepping/Servo Motor Card
+        1600    PCI-1610CU/9-AE 4-port RS-232 UNI PCI COMM card w/S&I&D
+        1680    PCI-1680U-A 2-port CAN UniversalPCI Communication Card with Isolation
+        16FF    PCI-1610CU/9-AE 4-port RS-232 UNI PCI COMM card w/S&I&D
+        1713    PCI-1713 32-channel Isolated Analog Input Card
+        1723    PCI-1723 16-bit, 8-ch Analog Output PCI Card with 16-ch Digital I/O
+        1724    PCI-1723 14-bit, 32-channel Isolated Analog Output Card
+        1755    PCI-1755 80 MB/s, 32-ch Digital I/O PCI Card
+        1760    amcc pci matchmaker s5920q pci
+        1761    PCI-1751 48 Digital IO + Counter 
+        1762    PCI-1762 16-ch Relay and 16-ch Isolated Digital Input PCI Card
+        1a00    0x03 0x0200
+        3730    PCM-3730I 16Bit dig. I/O Board
+13FF    Silicon Spice Inc.
+1400    ArtX Inc
+        0001    
+        0003    
+        0004    030000 030000
+        1401    9432 TX hd 2600xt
+1402    Meilhaus Electronic GmbH Germany
+        2E00    ME-2000/2600 Multifunction Data Aquistion card
+        4610    ME-4610 Multi-IO board (16x 16bit ADC, 32x TTL I/O)
+        4650    ME-4650 Multi-IO board (16x 16bit ADC, 32x TTL I/O)
+1404    Fundamental Software Inc
+1406    Oce Print Logics Technologies S.A.
+1407    Lava Computer MFG Inc.
+        0100    0439 Lava Dual Serial 550 PCI
+        0101    Lava Quattro PCI A/B
+        0102    Lava Quattro PCI C/D
+        0110    0110 Lava DSerial PCI Port A
+        0111    nep5p Lava DSerial PCI Port B
+        0180    Lava Octopus PCI Ports  Lava Octopus PCI Ports 1-4
+        0181    Lava Octopus PCI Ports 5-8
+        0200    9923 LavaPort Dual-650 PCI
+        0201    LavaPort Quad-650 PCI A/B
+        0202    LavaPort Quad-650 PCI C/D
+        0220    LavaPort Quad-650 PCI A/B
+        0221    LavaPort Quad-650 PCI C/D
+        0400    Lava 8255 PIO PCI
+        0500    P4 Lava Single Serial 550 PCI
+        0510    0510 Lava SP Serial 550 PCI
+        0511    Lava SP BIDIR Parallel PCI
+        0520    s Lava RS422 SS-PCI
+        0600    4-0 9253 LavaPort 650 PCI
+        0A00    LavaPort PCI COM Port Accelerator
+        120     Lava Quattro 550 PCI A/B
+        121     Lava Quattro 550 PCI C/D
+        520     s s
+        8000    197B&CC_0880 Lava Parallel
+        8001    Lava Dual Parallel port A
+        8002    9923 Lava Dual Parallel port A
+        8003    0x00010002030C2BB0 Lava Dual Parallel port B
+        8800    2003 BOCA Research IOPPAR
+1408    Aloka Co. Ltd
+1409    SUNIX Co., Ltd.
+        1409    7168 PCI Serial port
+        7168    1889 PCI Serial Port (WinXP --> Win 8.1) (Win 2003 - 2008R2)
+        7268    PCI / ISA IEEE1284 ECP/EPP/SPP/BPP Signal Chips So PCI parallel port
+        7268    PCI / ISA IEEE1284 ECP/EPP/SPP/BPP PAR4008A PCI parallel port
+140A    DSP Research Inc
+140B    Ramix Inc
+        0610    
+        615     NA Na
+        682     NA NA
+140D    Matsushita Electric Works Ltd
+140F    Salient Systems Corp
+1412    IC Ensemble, Inc.
+        1712    ICE1712 M-audio Delta 44 (http://www.m-audio.com)
+        1724    VT1723 Envy24PT/HT PCI Multi-Channel Audio Controller (&#1072;&#1091;&#1076;&#1080;&#1086;&#1082;&#1086;&#1
+1413    Addonics
+1415    Oxford Semiconductor Ltd - now part of PLX Technology 
+        8401    OX9162 PCI Interface to local bus
+        8403    OX12PCI840 PCI Parallel Card
+        9500    OX16PCI952 Quad UART (disabled)
+        9501    OX16PCI954 Quad UART
+        9505    OXuPCI952 Dual UART
+        950A    OX16PCI954 Dual PCI UARTS
+        950B    OXCF950 Integrated High Performance UART
+        9510    OX16PCI954 PCI Interface (disabled)
+        9511    OX9160 PCI Interface to 8-bit local bus
+        9512    OX16PCI954 PCI Interface to 32-bit bus
+        9513    OX16PCI954 Parallel Port
+        9521    OX16PCI952 Dual UART
+        9523    OX16PCI952 Integrated Parallel Port
+        c110    OXPCIe952 Parallel PCI Express Card (Manhattan 158176)
+        c158    OXPCIe952 Scheda PCI Express Seriale Due porte, X1 linea 
+        c15d    OXPCIe952 2 native UARTs (function 1)
+        c208    OXPCIe954 Quad UARTs
+        c20d    OXPCIe954 Quad UARTs (function 1)
+        c308    OXPCIe958 Octo UARTs
+        c30d    OXPCIe958 Octo UARTs (function 1)
+1418    Kyushu Electronics Systems Inc
+        0781    RaLink RT2860 300Mbps  802.11n Wireless Card
+1419    Excel Switching Corp
+141B    Zoom Telephonics Inc
+141E    Fanuc Co. Ltd
+141F    Visiontech Ltd
+        6181    KFIR MPEG decoder
+1420    Psion Dacom PLC
+1425    Chelsio Communications
+        0030    N/A T310 10GbE Single Port Adapter
+        31      N/A T320 10GbE Dual Port Adapter
+        32      N/A T302 1GbE Dual Port Adapter
+        33      N/A T304 1GbE Quad Port Adapter
+        34      N/A B320 10GbE Dual Port Adapter
+        35      N/A S310-CR 10GbE Single Port Adapter
+        36      N/A S320-LP-CR 10GbE Dual Port Adapter
+        37      N/A N320-G2-CR 10GbE Dual Port Adapter
+        4401    N/A T420-CR Unified Wire Ethernet Controller
+        4402    N/A T422-CR Unified Wire Ethernet Controller
+        4403    N/A T440-CR Unified Wire Ethernet Controller
+        4404    N/A T420-BCH Unified Wire Ethernet Controller
+        4405    N/A T440-BCH Unified Wire Ethernet Controller
+        4406    N/A T440-CH Unified Wire Ethernet Controller
+        4407    N/A T420-SO Unified Wire Ethernet Controller
+        4408    N/A T420-CX Unified Wire Ethernet Controller
+        4409    N/A T420-BT Unified Wire Ethernet Controller
+        440a    N/A T404-BT Unified Wire Ethernet Controller
+        440d    N/A T480 Unified Wire Ethernet Controller
+        440e    N/A T440-LP-CR Unified Wire Ethernet Controller
+        7145    1002 N/A
+1428    Edec Co Ltd
+1429    Unex Technology Corp.
+142A    Kingmax Technology Inc
+142B    Radiolan
+142C    Minton Optic Industry Co Ltd
+142D    Pixstream Inc
+1430    ITT Aerospace/Communications Division
+1433    Eltec Elektronik AG
+1435    RTD Embedded Technologies, Inc.
+        0531    DELETE DELETE
+        6020    SPM6020 PCI-104 dspModule
+        6030    SPM6030 PC/104-Plus dspModule
+        6420    SPM186420 PC/104-Plus dspModule
+        6430    SPM176430 PC/104-Plus dspModule
+        7520    DM7520 PC/104-Plus dataModule
+        7540    SDM7540 PC/104-Plus dataModule with SmartCal
+1436    CIS Technology Inc
+1437    Nissin Inc Co
+1438    Atmel-Dream
+143F    Lightwell Co Ltd - Zax Division
+1441    Agie SA.
+1443    Unibrain S.A.
+1445    Logical Co Ltd
+1446    Graphin Co., LTD
+        6A73    not known not known
+1447    Aim GMBH
+1448    Alesis Studio
+        0001    ADAT/EDIT Audio Editing
+144A    ADLINK Technology Inc
+        348A    LPCI-3488A Low-profile High-Performance IEEE488 GPIB Interface Card for PCI Bus
+        7230    PLX PCI-9052 PLX PCI-9052
+        7248    PCI-9052 PLX PCI9052
+        7250    PCI-7250 PLX PCI-9050
+        7256    PCI-7256 PCI-7256 16-CH Latching Relay & 16-CH Isolated Digital Input Card
+        7296    PCI-7296 (PLX PCI-9052) 96-ch digital I/O card
+        7432    PCI-7432 
+        7433    PCI-7433 64-ch digital Input card
+        7434    PCI-7434 
+        7841    PCI-7841 SJA 1000- baseddual port  CAN bus card
+        8133    PCI-8133 Dell Wireless 5720 VZW Mobile Broadband Card
+        8554    PCI-8554 
+        9111    PCI-9111 
+        9113    PCI-9113 
+        9114    PCI-9114 
+144B    Loronix Information Systems, Inc.
+        0601    
+144D    sanyo
+1450    Octave Communications Ind.
+1451    SP3D Chip Design GMBH
+1453    Mycom Inc
+1458    Giga-Byte Technologies
+        1458    0x29e0 microsoft
+        5000    0x29e0 GA-X48T-DQ6
+        67B1    0x29e0 GA-X48T-DQ6
+145C    Cryptek
+145F    Baldor Electric Company
+        0001    NextMove PCI Multi-axis Motion Controller
+        0002    NextMove PCI-2 Multi-axis Motion Controller
+1460    Dynarc Inc
+1462    Micro-Star International Co Ltd
+        00C1    NV41.1 NX6800-TD256E
+        4720    883 Audio controller
+        5071    883 Audio controller
+        5964    PCI\VEN_1002&DEV_7291&SUBSYS_08101462&REV_9A0PCI\V RADEON 9250/9200 series AGP
+        7120    
+        7960    MCP2T MCP2T
+1463    Fast Corporation
+1464    Interactive Circuits & Systems Ltd
+1468    Ambit Microsystems Corp.
+1469    Cleveland Motion Controls
+146C    Ruby Tech Corp.
+146D    Tachyon Inc.
+146E    WMS Gaming
+1471    Integrated Telecom Express Inc
+        0188    RoadRunner 10 ADSL PCI
+1473    Zapex Technologies Inc
+1474    Doug Carson & Associates
+1477    Net Insight
+1478    Diatrend Corporation
+147B    Abit Computer Corp.
+147F    Nihon Unisys Ltd.
+1482    Isytec - Integrierte Systemtechnik Gmbh
+1483    Labway Coporation
+1485    Erma - Electronic GMBH
+1489    KYE Systems Corporation
+148A    Opto 22
+148B    Innomedialogic Inc.
+148C    C.P. Technology Co. Ltd
+        4011    RV250 RADEON 9000 PRO EVIL COMMANDO
+        4152    0x1002 0x2079
+148D    Digicom Systems Inc.
+        1003    Rockwell HCF chipset Creative ModemBlaster V.90 PCI DI5655
+148E    OSI Plus Corporation
+148F    Plant Equipment Inc.
+        1000    unknown Ralink Motorola BC4 Bluetooth 3.0+HS Adapter
+        148f    5370 TP-LINK 7200ND
+        2000    Unknown Ralink Motorola BC8 Bluetooth 3.0 + HS Adapter
+        2070    1.0 802.11 g WLAN
+        2573    1192Af7b 802.11 bg
+        2870    1.0 802.11 n WLAN
+        3000    RT3290 ralink rt3290_bluetooth_01
+        3070    RT3070L FreeWifiLink D3-10000N
+        3572    RT3572 Ralink 3572
+        5370    Ralink RT2870 802.11n USB Wireless LAN Card
+        9021    Unknown Netopia USB b/g Adapter (black)
+1490    TC Labs Pty Ltd.
+1491    Futronic 
+        0020    USB Fingerprint Scanner Model FS80 USB Fingerprint Scanner Model FS80
+        0021    USB Fingerprint Scanner Model FS80 USB Fingerprint Scanner Model FS80
+1493    Maker Communications
+1495    Tokai Communications Industry Co. Ltd
+1496    Joytech Computer Co. Ltd.
+1497    SMA Technologie AG
+1498    Tews Technologies
+1499    Micro-Technology Co Ltd
+149A    Andor Technology Ltd
+149B    Seiko Instruments Inc
+149E    Mapletree Networks Inc.
+149F    Lectron Co Ltd
+14A0    Softing AG
+14A2    Millennium Engineering Inc
+14A4    GVC/BCM Advanced Research
+14A9    Hivertec Inc.
+        ad1f    1 1
+14AB    Mentor Graphics Corp.
+14B1    Nextcom K.K.
+        0FECF0000       i865P/PE/G/i848P rev. A2 Intel 82801EB (ICH5) rev. 02
+        1033    R6795-12 RH56D-PCI
+        2F30    01 zyxel omni 56k CI lus rev.
+14B3    Xpeed Inc.
+        0000    9ff-usa-a99-99-0970 DSL NIC
+14B4    Philips Business Electronics B.V.
+14B5    Creamware GmbH
+        0200    Scope 
+        0300    Pulsar 
+        0400    Pulsar SRB 
+        0600    Pulsar 2 
+        0800    DSP-Board
+        0900    1039 DSP-Board
+        0A00    DSP-Board
+        0B00    DSP-Board
+14B6    Quantum Data Corp.
+14B7    Proxim Inc.
+        0001    Symphony 4110 pci9052
+14B9    Aironet Wireless Communication
+        0001    PC4800 werwerwerwe
+        0340    Cisco Systems 340 PCI Wireless LAN Adptr
+        2500    PC2500 DS Wireless PCI LAN Adapter
+        3100    PC3100 FH Wireless PCI LAN Adapter
+        3101    PC3100 FH Wireless PCI LAN Adapter
+        3500    PC3500 FH Wireless PCI LAN Adapter
+        4500    PC4500 DS Wireless PCI LAN Adapter
+        4800    PC4800 DS Wireless PCI LAN Adapter
+        A504    A504 Cisco MAC Cisco Aironet 350 Series Mini-PCI (MPI350)
+        A506    AIR-MP21G 802.11b/g wireless adapter
+14BA    Internix Inc.
+14BB    Semtech Corporation
+14BE    L3 Communications
+14C0    Compal Electronics, Inc.
+14C1    Myricom Inc.
+        8043    LANai 9.2 0129 MyriNet
+14C2    DTK Computer
+14C4    Iwasaki Information Systems Co Ltd
+14C5    ABB AB (Sweden)
+14C6    Data Race Inc
+14C7    Modular Technology Ltd.
+14C8    Turbocomm Tech Inc
+        0003    0000066779 0
+14C9    Odin Telesystems Inc
+14CB    Billionton Systems Inc./Cadmus Micro Inc
+14CD    Universal Scientific Ind.
+        03      0x02 0x1212
+        1001    BCM4356 802.11 ac wireless module
+        168a    NA Multi-Card reader
+14CF    TEK Microsystems Inc.
+        2920    FPMC-FIO1-F100-1 Serial I/O Controller aka FPMC-DFLEX64
+14D4    Panacom Technology Corporation
+        0400    Panacom 7 Interface chip
+14D5    Nitsuko Corporation
+14D6    Accusys Inc
+14D7    Hirakawa Hewtech Corp
+14D8    Hopf Elektronik GMBH
+14D9    Alpha Processor Inc
+        0010    AP1011/SP1011 Sturgeon HyperTransport-PCI Bridge
+14DB    Avlab Technology Inc.
+        2100    PCI IO 1S download drivers
+        2101    PCI IO 1S-650 
+        2102    PCI IO 1S-850 
+        2110    PCI IO 1S1P OX16PCI952
+        2111    PCI IO 1S1P-650 
+        2112    PCI IO 1S1P-850 
+        2120    TK9902 0701 Parallel Port device
+        2121    PCI IO 2P Avlab Technology PCI IO 2P
+        2130    PCI IO 2S 2 Port PCI Serial Card
+        2131    PCI IO 2S-650 pci serial port
+        2132    PCI IO 2S-850 
+        2140    PCI IO 2P1S 
+        2141    PCI IO 2P1S-650 
+        2142    PCI IO 2P1S-850 
+        2144    PCI IO 2P2S 
+        2145    PCI IO 2P2S-650 
+        2146    PCI IO 2P2S-850 
+        2150    PCI IO 4S 
+        2151    PCI IO 4S-654 
+        2152    PCI IO 4S-850 
+        2160    PCI IO 2S1P 
+        2161    PCI IO 2S1P-650 
+        2162    PCI IO 2S1P-850 
+        2180    PCI IO 8S VEN_14DB&DEV_2180&SUBSYS_218014DB&REV_00
+        2181    PCI IO 8S-654 Avlab Technology Inc
+        2182    PCI IO 8S-850 Avlab Technology Inc
+14DC    Amplicon Liveline Limited
+        0000    PCI 230 
+        0001    PCI242H 4-port high speed RS-232
+        0002    PCI244H 8-port high speed RS-232
+        0003    PCI247H 2-port high speed RS-232
+        0004    PCI248H 2-port high speed RS-422/485
+        0005    PCI249H 2-port high speed RS-232 and RS-422/485
+        0006    PCI260 16-channel analog input (with timers)
+        0007    PCI224 16-chan 12-bit analog output (w/ timers)
+        0008    PCI234 4-chan 16-bit analog output (w/ timers)
+        0009    PCI236 24-channel digital I/O
+        000A    PCI272 72-channel digital I/O
+        000B    PCI215 48-channel digital I/O (w/ 6 timers)
+        000C    PCI263 16-channel reed relay output
+14DD    Imodl Inc.
+14DE    Applied Integration Corporation
+14E3    Amtelco
+14E4    Broadcom
+        0038    BCM88038 100G packet processor 
+        0102    T2500 Intel (R)
+        0318    n/a n/a
+        034F    NV36GL? ???
+        04B5    BCM4312 Broadcom 54bg Wireless
+        0732    BCM88732 2x40G/8x10G MAC Aggregation Switch with 80G Uplink
+        0800    BCM33xx/47xx Sentry5 Chipcommon I/O Controller
+        0804    BCM33xx/47xx Sentry5 PCI Bridge
+        0805    BCM33xx/47xx Sentry5 MIPS32 CPU
+        0806    BCM33xx/47xx Sentry5 Ethernet Controller
+        080B    BCM33xx/47xx Sentry5 Crypto Accelerator
+        080F    BCM33xx/47xx Sentry5 DDR/SDR RAM Controller
+        0811    BCM33xx/47xx Sentry5 External Interface
+        0816    BCM3302 Sentry5 MIPS32 CPU
+        1234    7175144F networkcontroller
+        1361    BCM4313 Ethernet
+        14E4    BCM57780 802.11b/g Wireless Lan Controller
+        1570    720p FaceTime HD camera Webcam found on Macbook Pro with Retina Display, 2014 (aka. Macbook Pro /w Retina 11,3)
+        1600    BCM5752 NetXtreme BCM5752 Gigabit Ethernet PCI Express
+        1601    BCM5752M NetXtreme Desktop/Mobile
+        1610    BCM70010 Broadcom BCN70010 Video Decoder
+        1612    BCM70010/BCM70012 Crystal HD Video Decoder
+        1615    BCM70015 Broadcom Crystal HD Video Decoder
+        161F    BCM70010/BCM70012 AVC/VC-1/MPEG PCI Express. HD Decoder Chipset for Netbooks/Nettops
+        1639    BCM5709 NetXtreme Gigabit Ethernet II
+        163B    BCM5709 Broadcom NetXtreme II BCM5706/5708/5709/5716 Driver
+        1644     BCM5751F ven_1102dev_0004
+        1645    BCM570123 broadtcomBCM5701 Gigabit EthernetASD
+        1646    BCM5702x1 NetXtreme Gigabit Ethernet
+        1647    BCM57788 NetLink tm Gigabit Ethernet pcie
+        1648    BCM5704 NetXtreme Dual Gigabit Adapter
+        164C    BCM5708 Broadcom NetXtreme II Gigabit Ethernet Adapter
+        164D    83471043 NetXtreme Fast Ethernet Controller
+        1650    BCM57711 Broadcom PCIe 10Gb Network Controller 
+        1653    BCM5788 Broadcom NetXtreme Gigabit Ethernet
+        1654    BCM5705A2 NetXtreme Gigabit Ethernet
+        1658    BM5750 NtXtreme Gigabit Ethernet
+        1659    BCM5721 NetXtreme Gigabit Ethernet PCI Express
+        165A    94309 Broadcom NetXtreme BCM5722 Gigabit
+        165D    Aspire5733Z Broadcom NetXtreme Gigabit Ethernet
+        165E    3C905B NetXtreme Gigabit Ethernet
+        165F    BCM5720 Broadcom NetXtreme 5720 Gigabit Ethernet
+        166a    BCM5780 Broadcom NetXtreme Gigabit Ethernet 5780
+        166B    BCM5780S NetXtreme Gigabit Ethernet
+        166D    BCM5705MFE NetXtreme Ethernet 100kB
+        166E    BCM5705 NetXtreme Gigabit Ethernet
+        167     BCM5751F NetXtreme Fast Ethernet Controller
+        1672    BCM5754M NetXtreme Gigabit Ethernet
+        1673    B5755M NetXtreme Gigabit Ethernet
+        1674    57XX 57XX Series Broadcom Driver X86/X64
+        1676    BCM5750A1 NetXtreme Gigabit Ethernet
+        1677    BCM5751 NetXtreme Desktop/Mobile
+        1677*   BCM5782 Broadcom Netxtreme Gigabit Ethernet
+        167A    BCM5754 Broadcom NetXtreme Gigabit Ethernet Controller
+        167B    BCM5755/5780 NetXtreme Gigabit Ethernet
+        167C    BCM5750 NetXtreme Gigabit Ethernet
+        167d    BCM5751M Broadcom NetXtreme Gigabit Ethernet
+        167E    BCM5751FKFB vierkant
+        1680    BCM5761E NetXtreme Desktop/Mobile
+        1681    BCM5761 Broadcom 57XX Gigabit Integrated Controller 
+        1684    BCM5764 Broadcom NetXtreme Gigabit Ethernet
+        1690    BCM5776 NexTreme Desktop/Mobile
+        1691    BCM57788 Broadcom BCM57788 LOM 
+        1691_   BCM57788A Broadcom NetLink (TM) Gigabit Ethernet
+        1692    BCM57780 NetLink
+        1693    BCM5787 Ethernet Controller Broadcom Netlink Gigabit
+        1696    BCM5782 Broadcom NetXtreme Gigabit Ethernet 
+        1698    02941028 NetLink Ethernet-FOR DELL LAPTOP AND MAYBE OTHERS
+        169A    BCM5787 Broadcom Netlink (TM) gigabit ethernet Driver
+        169B    BCM5786 NetXtreme Gigabit Ethernet
+        169C    17351043 Broadcom NetLink (TM) Gigabit Ethernet
+        169D    BCM5782k, BCM5789 Broadcom Ethernet Adapter
+        169E    BCM5754 NetXtreme Gigabit Ethernet PCI Express
+        16A6    BCM5702X Gigabit Ethernet
+        16A7    BCM5703X Gigabit Ethernet
+        16A8    BLM5701 NetXtreme Gigabit Ethernet
+        16AA    B06BDRV BroadCom NetExtreme II Server
+        16B1    BCM57781 BCM57781
+        16B5    BCM57785X Broadcom NetLink Gigabit Ethernet
+        16BE    16BE8 CardReader Broadcom 1.0.0.221
+        16BF    0x16BF CardReader Broadcom 15.0.7.2
+        16C6    BCM5702A3 NetXtreme Gigabit Ethernet
+        16C7    BCM 94311 DELL Wireless 1390 WLAN MiniCard
+        16DD    BCM5781 NetXtreme Gigabit Ethernet
+        16f7    BCM5753 NetXtreme BCM5753 Gigabit PCI Express
+        16FD    BCM5753M NetXtreme Gigabit Ethernet PciXpress
+        16FE    BCM5753F NetXtreme Gigabit Ethernet
+        170C    PCI\VEN_14E4&DEV_1692&CC_020000 Broadcom 440x 10/100 Integrated Controller
+        170D    BCM5901 NetXtreme
+        170E    BCM5901 NetXtreme 100Base-TX
+        1713    BCM5906m Broadcom NetLink (TM) Fast Ethernet
+        21E3    BCM43142A0 Broadcom Bluetooth 4.0
+        333     BCM53333 16p 1G (PHY)
+        3352    BCM3352 BCM3352 QAMLink. Single-Chip 4-Line VoIP
+        3360    BCM3360 Advanced PHY Broadband Gateway Cable Modem
+        4211    intel CORE I5 10Mb/s NIC
+        4212    BCM V.90 56k Modem
+        4301    Broadcom BCM4301 802.11g Wireless LAN Controller Dell Truemobile 1180 802.11g MiniPCI
+        4303    BCM4303 BCM4301 802.11b802.11b Wireless LAN Controller
+        4305    BCM4307 V.90 56k Modem
+        4306    BCM4306 Unknown device 4306 (rev 02)
+        4307    BCM4306 802.11b Wireless LAN Controller
+        4310    BCM4310 BCM4301USB Controller
+        4311    BCM4311 802.11b/g Wireless LAN
+        4312    BCM4310 broadcom wireless 1490 (dell)
+        4313    BCM4310 UART wireless network card
+        4315    BCM4315/BCM22062000 Broadcom Wireless b/g (Tested Drivers)
+        4318    BCM4318 Broadcom 802.11b/g WLAN
+        4320    BCM4306 802.11B/G Wireless Lan Controller 3-&#1103; &#1056;&#1077;&#1076;&#1072;&#1082;&#1094;&#1080;&#1103;
+        4321    BCM4306 802.11a Wireless LAN Controller
+        4322    BCM4306 UART
+        4323    BCM4306 V.90 56k Modem
+        4324    Broadcom 43225 802.11a/b/g Wireless LAN
+        4325    BCM4306 802.11b/g Wireless LAN Controller
+        4326    BCM4306 Chipcommon I/O Controller?
+        4328    BCM4321KFBG Broadcom BCM43xx 1.0 (5.10.91.27)
+        4329    BCM43XX Broadcom 802.11n Network Adapter
+        432B    4322 Broadcom Wireless LAN Driver 
+        4331    BCM4331 Broadcom BCM4331
+        4353    BCM943224HMS Broadcom Half Mini PCI Express Wifi card / DL1520 (aka Dell Wireless 1520 802.11n Mini Card WLAN Dri
+        4357    BCM94322c5HM Broadcom WiFi 802.11b/g/n
+        4358    BCM943227HM4L Broadcom 802.11n WLAN module
+        4359    BCM943228HM4L Half-mini wireless-N card DW1530
+        4365    061117AA Broadcom 43142 Wireless LAN Adapter
+        43a1    0x4360 Broadcom BCM4708A0
+        4401    BCM4401 10/100 Integrated Ethernet Controller
+        4402    BCM440 10/100 Integrated Ethernet Controller
+        4403    BCM4402 V.90 56k Modem
+        4410    BCM4413 iLine32 HomePNA 2.0
+        4411    BCM4212 V.90 56k Modem
+        4412    BCM4412 10/100BaseT Ethernet
+        4430    BCM44xx CardBus iLine32 HomePNA 2.0
+        4432    BCM44xx CardBus 10/100BaseT Ethernet
+        4610    BCM4610 Sentry5 PCI to SB Bridge
+        4611    BCM4610 Sentry5 iLine32 HomePNA 1.0
+        4612    BCM4610 Sentry5 V.90 56k Modem
+        4613    BCM4610 Sentry5 Ethernet Controller
+        4614    BCM4610 Sentry5 External Interface
+        4615    BCM4610 Sentry5 USB Controller
+        4704    BCM4704 Sentry5 PCI to SB Bridge
+        4708    BCM4704 Crypto Accelerator
+        4710    BCM4710 Sentry5 PCI to SB Bridge
+        4711    BCM47xx Sentry5 iLine32 HomePNA 2.0
+        4712    BCM47xx Sentry5 V.92 56k modem
+        4713    BCM47xx Sentry5 Ethernet Controller
+        4714    BCM47xx Sentry5 External Interface
+        4715    BCM47xx Sentry5 USB Controller
+        4716    BCM47xx Sentry5 USB Host Controller
+        4717    BCM47xx Sentry5 USB Device Controller
+        4718    BCM47xx Sentry5 Crypto Accelerator
+        4720    BCM4712 MIPS CPU
+        4726    7175144f 01
+        4727    BCM1503HMGIPAD_NT61 Dell Wireless 1501/1503/1701 Half Mini Card Driver  (used google chrome to download file)
+        4728    7175144f 01
+        53343   BCM53343 16P 1G  (PHY)
+        5365    BCM5365P Sentry5 PCI to SB Bridge
+        5600    BCM5600 StrataSwitch 24+2 Ethernet Switch Controller
+        5605    BCM5605 StrataSwitch 24+2 Ethernet Switch Controller
+        5615    BCM5784 StrataSwitch 24+2 Ethernet Switch Controller
+        5625    BCM5625 StrataSwitch 24+2 Ethernet Switch Controller
+        5645    BCM5645 StrataSwitch 24+2 Ethernet Switch Controller
+        5670    BCM5670 8-Port 10GE Ethernet Switch Fabric
+        5680    BCM5680 G-Switch 8-Port Gigabit Ethernet Switch Controller
+        5690    BCM5690 12-port Multi-Layer Gigabit Ethernet Switch
+        5691    BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller
+        5802    BCM5802 The BCM5802 Security Processor integrates Broadcom.s IPSec engine (DES, 3DES, HMAC-SHA-1, HMAC-MD5),
+        5805    BCM5805 The BCM5805 Security Processor integrates a high-performance IPSec engine (DES, 3DES, HMAC-SHA-1, HM
+        5820    BCM5820 Crypto Accelerator
+        5821    BCM5821 Crypto Accelerator
+        5822    BCM5822 Crypto Accelerator
+        5823    BCM5823 Crypto Accelerator
+        5824    BCM5824 Crypto Accelerator
+        5825    BCM5825 BCM5825
+        5840    BCM5840 Crypto Accelerator
+        5841    BCM5841 Crypto Accelerator
+        5850    BCM5850 Crypto Accelerator
+        7321    BCM5751 network card integrated
+        7411    BCM7411 High Definition Video/Audio Decoder
+        78655   BCM5787M Wireless-N WLAN
+        8010    BCM53010 Next generation router SOC with gigabit switch
+        8011    BCM53011 Next generation router SOC with gigabit switch
+        8012    BCM53012 Next generation router SOC with gigabit switch
+        8016    BCM53016 Next generation router SOC with gigabit switch with RGMII/SDIO, but disable 3 GPHY
+        8018    BCM53018 Next generation router SOC with gigabit switch with RGMII/SDIO
+        8019    BCM53019 Next generation router SOC with gigabit switch without RGMII/SDIO
+        8022    BCM53022 Next generation router SOC with gigabit switch with RGMII/SDIO
+        8023    BCM53023 Next generation router SOC with gigabit switch with SATA instead of RGMII/SDIO
+        8025    BCM53025 Next generation router SOC with gigabit switch with RGMII/SDIO, GMII, SGMII and SATA
+        8202    BCM8202 Packet Processor ASIC
+        8334    BCM53334 24 1G
+        8342    BCM53342 8 1G (PHY)
+        8344    BCM53344  24P 1G +4P 1G  (PHY)
+        8346    BCM53346 24P 1G +4P 1G/10G  (PHY)
+        8393    BCM53393 14P (1G,  (no PHY)
+        8394    BCM53394 10P 1G + 4x1/2.5/5/10G  (no PHY) 
+        8401    BCM53401 160Gbps L2+ Ethernet Switch
+        8402    BCM53402 160Gbps L2+ Ethernet Switch
+        8405    BCM53405 160Gbps L2+ Ethernet Switch
+        8406    BCM53406 160Gbps L2+ Ethernet Switch
+        8408    BCM53408 160Gbps L2+ Ethernet Switch
+        8411    BCM53411 160Gbps L2+ Ethernet Switch
+        8412    BCM53412 160Gbps L2+ Ethernet Switch
+        8415    BCM53415 160Gbps L2+ Ethernet Switch
+        8416    BCM53416 160Gbps L2+ Ethernet Switch
+        8418    BCM53418 160Gbps L2+ Ethernet Switch
+        8433    BCM53433 L2+ Ethernet switch: 16P 1G
+        8434    BCM53434 L2+ Ethernet switch: 24P 1G
+        8442    BCM53442 L2+ Ethernet switch: 8P 1G + 4P 1G
+        8443    BCM53443 L2+ Ethernet switch: 16P 1G + 4P 1G
+        8444    BCM53444 L2+ Ethernet switch: 24P 1G + 4P 1G
+        8446    BCM53446 L2+ Ethernet switch: 24P 1G +2P 1G/10G +2P 1G/10G
+        8447    BCM53447 L2+ Ethernet switch: 24P 1G +2P 1G/10G +2P 1G/10G
+        8448    BCM53448 L2+ Ethernet switch: 8P 1G + 8P 1G/2.5G + 4P 10G
+        8449    BCM53449 L2+ Ethernet switch: 16P 1G + 8P 1G/2.5G + 4P 10G + 2P 20G
+        9867    900000000 900000000
+        9876    Texas Instruments PCI GemCore based SmartCard cont 0x14E4
+        A8D6    BCM6368 Broadcom 802.11n WLAN chip
+        B061    BCM56061 160Gbps L2+ Ethernet Switch
+        B062    BCM56062 160Gbps L2+ Ethernet Switch
+        B063    BCM56063 160Gbps L2+ Ethernet Switch
+        B064    BCM56064 160Gbps L2+ Ethernet Switch
+        B150    BCM56150 Hurricane2 (Lightly Managed) 24P 1G +4P 1G/10G  (PHY)
+        b152    BCM56152 24P  1G (PHY)
+        B160    BCM56160 L2+ switch: 24P 1G +2P 1G/10G +2P 1G/10G
+        B161    BCM56161 L2+ Ethernet switch: 24P 1G +2P 1G/10G +2P 1G/10G
+        B162    BCM56162 L2+ Ethernet switch: 24P 1G +4P 1G
+        B340    BCM56340 48-port multi-layer switch with embedded CPU
+        B450    BCM56450 100G Multi-layer Ethernet Switch
+        B640    BCM56640 260Gbps Extensible Switch with 100GE
+        B842    BCM56842 320Gbps Ethernet Multilayer Switch
+        B845    BCM56845 640G Multi-layer Ethernet Switch
+        B850    BCM56850 1.28T I/O Multi-layer Ethernet Switch
+        B960    BCM56960 3.2T I/O Multi-layer Ethernet Switch
+        dev_4311        1364103c subsys
+14EA    Planex Communications, Inc.
+        AB06    XFNW-3603-T 10/100 Fast Ethernet CardBus (RTL8139)
+14EB    Seiko Epson Corporation
+        0020    BEMx.x PCI to S5U13xxxB00B Bridge Adapter
+        0C01    S1D13808 Embedded Memory Display Controller
+14EC    Acqiris
+        16BE    CardReader_Broadcom 1.0.0.222_W7x86_A
+14ED    Datakinetics Ltd
+14EF    Carry Computer Eng. Co Ltd
+14F1    Conexant
+        0F00    cx11252-11 HSF Generic Modem
+        0F30    0x14F1 0x14F1
+        1031    332 dfd
+        1033    RH56D RH56D-PCI
+        1033a   RH56D RH56D-PCI
+        1035    R6795-11 RH56D/SP-PCI, R6795-11, E416921/1, 0336 Mexico
+        1036    Conexant RH56D/SP-PCI 
+        1056    105614f1 subsys
+        1059    DI15630-5, DI5631, DI5633 SmartHCF
+        10B4    Conextant HFC All Conextant HFC Modems (PCI)
+        10B6    unknown Conexant HCF PCI Soft modem
+        1416    Contexant
+        1456    1456 HCFp Modem
+        14F1    0x14F1 0x14F1
+        1611    ? AccessRunner ADSL Modem
+        1612    8 8
+        2013    RS56-PCI in-Build CX11235 modem
+        2400    unknown unknown
+        2702    cx11252-11 HSFi or Soft V92 PCI Modem
+        2710    PCI modem card Conexant
+        2740    CC_0780 Pci Simple Communtications Controller
+        2B10    0x14F1 0x14F1
+        2BFA    0x0000ffff Conexant HDA D110 MDC v.92 Modem
+        2C06    136 Conexant HD Audio SoftV92 Data Fax Modem with SmartCP
+        2F00    00101767 HSF 56k HSFi Modem
+        2f01    0x0780 missing driver for pci simple communications controller
+        2F10    USR90-12 CXT / USR 56K Fax Host int
+        2F20    CX11256 SoftV92 Data Fax Modem with SmartCP
+        2F30    CX11252-41z PCI SoftV92 Modem
+        2F30&   01 hp/compaq alhena 5-gl6
+        2F40    200014F1 PCI Soft Data Fax Modem with SmartCP
+        2F50    99269 SmartLink 2801
+        2F52    C0220001 01\3&61AAA01&0&50
+        2F81       
+        2F82    cx9510-11z Conexant PCI-E Soft Data/Fax Modem with SmartCP
+        5045    4.0.3.1 http://h10025.www1.hp.com/ewfrf/wc/softwareDownloadIndex?softwareitem=ob-43284-1&lc=en&dlc=en&cc=us&
+        50451   14f12f30 Conextant High Definition
+        50452           14e4 Conextant High Definition SmartAudio 221
+        50452   PCI\VEN_14F1&DEV_5051 Conextant High Definition Audio-Venice 5051
+        5047    Not sure HDAUDIO Soft Data Fax Modm- Conexant Sound Card Audio Driver
+        5051    4.0.1.6 Conexant HD-Audio SmartAudio 221
+        5051_   DG31PR Conexant HD-Audio SmartAudio 221
+        5051__  CX20561 Conexant HD-Audio SmartAudio 221
+        5066    Cx20561 HDAUDIO\Func_01&VEN_14F1&DEV_5069&SUBSYS_17AA214C&REV_1003
+        5069    20585 conexant 20585 smartAudio HD
+        506C    0x506C Conexant High Definition Audio
+        506E    001 Conexant 20672 SmartAudio HD
+        50A1    CX20641/CX20651 Conexant HD Audio
+        50A2    Conexant CX20642 Conexant HD Audio
+        5B7A    Belived to be a CX23416 Single-Chip MPEG-2 Encoder with Integrated Analog Video/Broadcast Audio Decoder
+        8800    Conexant CX23881 PAL audio/video decoder
+        88000   0x14F1 0x14F1
+        8801    CX23880 PCI Broadcast Audio/Video Decoder
+        8802    CX2388x MPEG Encoder 
+        8811    CX2388x Audio Capture ike
+        8852    cx23885 Leadtek Winfast PxDVR3200 H (XC3028)
+        8880    CX23888 PCI Express Video and Broadcast Audio Decoder
+        9876    PCI\VEN_14F1&DEV_2F20&SUBSYS_200C14F1&REV_00\4&CF8 Communication controller
+        x27d8   A62516F3 INTEL IDT Audio
+14F2    Mobility Electronics, Inc.
+        0001    Moselle Split Bridge
+        0002    Capilano Split Bridge
+        0120    win7_rtm.090713-1257 Merlin Split Bridge
+        0121    PCI Parallel Port
+        0122    unknown PCI Serial Port
+        0123    6.1.7600.16385 PCI PS/2 Keyboard Port
+        0124    3103 PCI PS/2 Mouse Port
+14F4    Tokyo Electronic Industry Co. Ltd.
+14F5    Sopac Ltd
+        2F00    x x
+14F6    Coyote Technologies LLC
+14F7    Wolf Technology Inc
+14F8    Audiocodes Inc
+14F9    AG Communications
+14FB    Transas Marine (UK) Ltd
+14FC    Quadrics Ltd
+14FD    Silex Technology Inc.
+        0001    H260u H260u printer server for HP Printer
+14FE    Archtek Telecom Corp.
+14FF    Twinhead International Corp.
+1501    Banksoft Canada Ltd
+1502    Mitsubishi Electric Logistics Support Co
+1503    Kawasaki LSI USA Inc
+1504    Kaiser Electronics
+1506    Chameleon Systems Inc
+1507    Htec Ltd.
+        0001    MPC105 Eagle 
+        0002    MPC106 Grackle 
+        0003    MPC8240 Kahlua 
+        0100    MPC145575 HFC-PCI 
+        0431    KTI829c 100VG 
+        4801    Raven 
+        4802    Falcon 
+        4803    Hawk 
+        4806    CPX8216 
+1509    First International Computer Inc
+150B    Yamashita Systems Corp
+150C    Kyopal Co Ltd
+150D    Warpspped Inc
+150E    C-Port Corporation
+150F    Intec GMBH
+1510    Behavior Tech Computer Corp
+1511    Centillium Technology Corp
+1512    Rosun Technologies Inc
+1513    Raychem
+1514    TFL LAN Inc
+1515    ICS Advent
+1516    Myson Technology Inc
+        0800    Myson MTD803/TAMARACK TC6020 PCI Ethernet controller
+        0803    Myson MTD803/TAMARACK TC6020 PCI Ethernet controller
+        0891    Myson MTD803/TAMARACK TC6020 PCI Ethernet controller
+1517    Echotek Corporation
+1518    Kontron Modular Computers GmbH (PEP Modular Computers GMBH)
+1519    Telefon Aktiebolaget LM Ericsson
+        0020    0123456789 HSIC Device
+        2004    1 PCI Interface bus
+151A    Globetek Inc.
+        1002    PCI-1002&DEV_4341&subsys_82441033&rev_01\ 4341
+        1004    PCI-1004 
+        1008    PCI-1008 
+151B    Combox Ltd
+        9080    me594v02100 combox combox cb 300a
+151C    Digital Audio Labs Inc
+151D    Fujitsu Computer Products Of America
+        9876    ? ?
+151E    Matrix Corp.
+151F    Topic Semiconductor Corp
+        0001    TOPIC FM-56PCI-TP TOPIC FM-56PCI-TP
+        0568    1.0.1.8 56k Internal Data Fax Voice Modem
+1520    Chaplet System Inc
+1521    Bell Corporation
+1522    Mainpine Limited
+        0100    PBridge+ PCI Interface Chip
+1523    Music Semiconductors
+        8       MU9C8K64 Content Addressable Memory
+1524    ENE Technology Inc
+         0751   08011558 pci
+        0100    ACPI\ENE0100  ENE CIR Receiver 
+        0510    1.4.5.0 PCI Memory Card Reader Controller
+        0530    CB-712/714/810 Memory Stick Card Reader
+        0550    CB-712/714/810 Secure Digital Card Reader
+        0551    10C11734 ven1524&dev_0551&SUBSYS_009F1025&REV_01
+        0555    10c11734 ven1524&dev_0551&SUBSYS_009F1025&REV_01
+        0610    ??? PCI Smart Card Reader Controller
+        0730    0x0751 CardBus Controller
+        100     ACPI/ENE0100/3&21436425&0 ENE CIR Receiver
+        1025    1025123 PCI\VEN_127a&DEV_1025&SUBSYS_1025123A&REV_01\4&1351887D&0&58F0
+        1211    CB-1211 CardBus Controller
+        1225    CB-1225 CardBus Controller
+        1410    CB-1420 CardBus Controller
+        1411    CB-710/2/4/810 pci device
+        1412    CB-712/714/810 Cardbus Controller
+        1420    CB-1420 CardBus Controller
+        1421    CB-720/2/4 CardBus Controller
+        1422    CB-722/4 CardBus Controller
+        510     1.4.5.0 PCI Memory Card Reader Controller
+        551     10C11734 ven1524&dev_0551&SUBSYS_009F1025&REV_01
+        9876    1941 1941
+        FC10    card bus pci device
+1525    Impact Technologies
+1526    ISS Inc
+1527    Solectron
+1528    Acksys
+1529    American Microsystems Inc
+152A    Quickturn Design Systems
+152B    Flytech Technology Co Ltd
+152C    Macraigor Systems LLC
+152D    Quanta Computer Inc
+        2329    2338 J micron JM20329
+        2519    n/a JMicron Technology Corp. / JMicron USA Technology Corp
+152E    Melec Inc
+        2507    0
+152F    Philips - Crypto
+1532    Echelon Corporation
+1533    Baltimore
+1534    Road Corporation
+1535    Evergreen Technologies Inc
+1537    Datalex Communcations
+1538    Aralion Inc.
+        0301    ARS106S Tekram DC200 PATA100 RAID Controller
+        0303    ARS0304S ARS0304S PATA133 RAID5
+1539    Atelier Informatiques et Electronique Et
+153A    ONO Sokki
+153B    Terratec Electronic GMBH
+        1115    ICE1712 Envy24 IC Ensemble Inc ICE1712 Envy24 Multichannel Audio Controller
+        1143    SAA7134HL Philips Semiconductors SAA7134HL Multimedia Capture Device
+        6003    CS4614/22/24 CrystalClear SoundFusion PCI Audio Accel
+153C    Antal Electronic
+153D    Filanet Corporation
+153E    Techwell Inc
+153F    MIPS Technologies, Inc
+        dead    xx12345 Not a chip ...
+1540    Provideo Multimedia Co Ltd
+        9524    saa7130 PAL/SECAM TV card w/ FM1216ME MK3 tuner (+FM radio)
+1541    Telocity Inc.
+1542    Vivid Technology Inc
+1543    Silicon Laboratories
+        1052    30201543 Modem Intel 537EP (Chipset KAIOMY)
+        3052    30201543 Modem Intel 537EP (Chipset KAIOMY)
+        3155    InfineonTPMProfessional ModemDeviceonHighDefinitionAudioBus
+1544    DCM Technologies Ltd.
+1545    VisionTek
+1546    IOI Technology Corp.
+1547    Mitutoyo Corporation
+1548    Jet Propulsion Laboratory
+1549    Interconnect Systems Solutions
+        80FF    PCI-ISA-001 PCI/ISA Bus Bridge
+154A    Max Technologies Inc.
+        9016    AF9016 USB DVB-T Device AF9015
+        9876    AF9015 USB DVB-T Device  CE950081
+154B    Computex Co Ltd
+        3038    VT6212L USB
+154C    Visual Technology Inc.
+154D    PAN International Industrial Corp
+154E    Servotest Ltd
+154F    Stratabeam Technology
+1550    Open Network Co Ltd
+1551    Smart Electronic Development GMBH
+1553    Chicony Electronics Co Ltd
+1554    Prolink Microsystems Corp.
+1555    Gesytec GmbH
+        0002    PLX PCI 9050 Easylon PCI Bus Interface
+1556    PLDA
+        5555    001 an cpci application
+1557    Mediastar Co. Ltd
+1558    Clevo/Kapok Computer
+        1558    0x1558 gtx 670mx GPU
+1559    SI Logic Ltd
+155A    Innomedia Inc
+155B    Protac International Corp
+155C    s
+155D    MAC System Co Ltd
+155E    KUKA Roboter GmbH
+        0020    MFC3 Multi Function Card Version 3
+155F    Perle Systems Limited
+1560    Terayon Communications Systems
+1561    Viewgraphics Inc
+1562    Symbol Technologies, Inc.
+        0001    LA-41x3 Spectrum24 Wireless LAN PCI Card
+        0002    LA-5030 Symbol Wireless Networker 802.11a/g CardBus
+        0003    LA-5033 Symbol Wireless Networker 802.11a/g PCI
+1563    A-Trend Technology Co Ltd
+1564    Yamakatsu Electronics Industry Co Ltd
+1565    Biostar Microtech Intl Corp
+1566    Ardent Technologies Inc
+1567    Jungsoft
+1568    DDK Electronics Inc
+1569    Palit Microsystems Inc
+156A    Avtec Systems Inc
+        5000    NA Wideband Advanced Signal Processor
+        5100    NA High Data Rate Radio
+156B    S2io Inc
+156C    Vidac Electronics GMBH
+156D    Alpha-Top Corp
+156E    Alfa Inc.
+156F    M-Systems Flash Disk Pioneers Ltd
+1570    Lecroy Corporation
+1571    Contemporary Controls
+        A001    TFF GHB
+        A002    CCSI PCI20-485D ARCnet
+        A003    CCSI PCI20-485X ARCnet
+        A004    CCSI PCI20-CXB ARCnet
+        A005    CCSI PCI20-CXS ARCnet
+        A006    CCSI PCI20-FOG-SMA ARCnet
+        A007    CCSI PCI20-FOG-ST ARCnet
+        A008    CCSI PCI20-TB5 SONY
+        A009    CCSI PCI20-5-485 5 Mbit ARCnet
+        A00A    CCSI PCI20-5-485D 5 Mbit ARCnet
+        A00B    CCSI PCI20-5-485X 5 Mbit ARCnet
+        A00C    CCSI PIC20-5-FOG-ST 5 Mbit ARCnet
+        A00D    CCSI PCI20-5-FOG-SMA 5 Mbit ARCnet
+        A00E    COM200C22 ARCNET
+        A201    CCSI PCI22-485 10 Mbit ARCnet
+        A202    CCSI PCI22-485D 10 Mbit ARCnet
+        A203    CCSI PCI22-485X 10 Mbit ARCnet
+        A204    CCSI PCI22-CHB 10 Mbit ARCnet
+        A205    CCSI PCI22-FOG-ST 10 Mbit ARCnet
+        A206    CCSI PCI22-THB 10 Mbit ARCnet
+1572    Otis Elevator Company
+1573    Lattice - Vantis
+1574    Fairchild Semiconductor
+1575    Voltaire Advanced Data Security Ltd
+1576    Viewcast Com
+1578    Hitt
+1579    Dual Technology Corporation
+157A    Japan Elecronics Ind. Inc
+157B    Star Multimedia Corp.
+157C    Eurosoft (UK)
+        8001    Fix2000 PCI Y2K Compliance Card
+157D    Gemflex Networks
+157E    Transition Networks
+157F    PX Instruments Technology Ltd
+1580    Primex Aerospace Co.
+1581    SEH Computertechnik GMBH
+1582    Cytec Corporation
+1583    Inet Technologies Inc
+1584    Vetronix Corporation Engenharia Ltda
+        5054    VAS5055 VAS Vetronix Automotive Service
+        4003    VAS5052 VAS Vetronix Automotive Service
+1585    Marconi Commerce Systems SRL
+1586    Lancast Inc
+        0803    
+1587    Konica Corporation
+1588    Solidum Systems Corp
+        1100    PAX.port 1100 PAX.ware 1100 dual Gb classifier engine
+        2000    AMD '971 SNP 8023 packet classifier - AMD component
+        8023    SNP8023 PAX.ware 100 packet classifier
+1589    Atlantek Microsystems Pty Ltd
+158A    Digalog Systems Inc
+158B    Allied Data Technologies
+        0005    HLF-VMPEU560-C Standar HSP Modem
+        0015    HLF-VMPEU560-C Standar HSP Modem Series
+158C    Hitachi Semiconductor & Devices Sales Co
+158D    Point Multimedia Systems
+158E    Lara Technology Inc
+158F    Ditect Coop
+1590    3pardata Inc.
+1591    ARN
+1592    Syba Tech Ltd.
+        0781    W83787IF Multi-IO Card
+        0782    W837871F Parallel Port Card (EPP)
+        0783    TC32001 PCI I/O Multi-IO Card
+        0785    907ab184740802 Multi-IO Card
+        0786    Winbond w83787if Multi-IO Card
+        0787    winbond w83787if Multi-IO Card 2 series
+        0788    w837871f Multi-IO Card
+        078A    007AB192367002ND Multi-IO Card
+1593    Bops Inc
+1594    Netgame Ltd
+1595    Diva Systems Corp.
+1596    Folsom Research Inc
+1597    Memec Design Services
+1598    Granite Microsystems
+1599    Delta Electronics Inc
+159A    General Instrument
+159B    Faraday Technology Corp
+159C    Stratus Computer Systems
+159D    Ningbo Harrison Electronics Co Ltd
+159E    A-Max Technology Co Ltd
+159F    Galea Network Security
+15A0    Compumaster SRL
+15A1    Geocast Network Systems Inc
+15A2    Catalyst Enterprises Inc
+        0001    TA700 PCI Bus Analyzer/Exerciser
+15A3    Italtel
+15A4    X-Net OY
+15A5    Toyota MACS Inc
+15A6    Sunlight Ultrasound Technologies Ltd
+15A7    SSE Telecom Inc
+15A8    Shanghai Communications Technologies Cen
+15AA    Moreton Bay
+15AB    Bluesteel Networks Inc
+15AC    North Atlantic Instruments
+15AD    VMware Inc.
+        0405    9500MGS VMWARE SVGA II
+        0710    0740 Virtual SVGA
+        0720    VMXNET VMware PCI Ethernet Adapter
+        0740    58 VMW5858are VMCI Bus Device
+        0770    n/a Standard Enhanced PCI to USB Host Controller
+        0778    0778 Sabrent USB-to-Parallel Adapter
+        07B0    VMXNET 3 VMware vSphere 4 PCI Ethernet Adapter
+        0801    n/a PCI Memory Controller
+        1975    N/A High Definition Audio Codec
+        1977    N/A High Definition Audio Controller
+15AE    Amersham Pharmacia Biotech
+15B0    Zoltrix International Limited
+        0001    FM-3986 Pctel
+        0003    FM-3986 Pctel
+        2BD0    2BD0 soft56k voice,data,fax CARP
+15B1    Source Technology Inc
+15B2    Mosaid Technologies Inc.
+15B3    Mellanox Technology
+        5274    MT21108 InfiniBridge
+        5A44    MT23108 InfiniHost I
+        6274    MT25204 InfiniHost III Lx
+        6278    MT25208A0-FCC InfiniHost TM III Ex
+        6282    MT25218 MT25218 [InfiniHost III Ex]
+        634A    MT2518 Mellanox ConnectX VPI (MT2548) - PCIe 2.0 2.5GT/s, IB DDR /10GigE Network Adaptor
+        6732    MT26418 ConnectX VPI (MT26418) - PCIe 2.0 5GT/s, IB DDR / 10GigE
+15B4    CCI/Triad
+15B5    Cimetrics Inc
+15B6    Texas Memory Systems Inc
+15B7    Sandisk Corp.
+15B8    Addi-Data GMBH
+        3009    xPCI-3504 Analog output board
+15B9    Maestro Digital Communications
+15BA    Impacct Technology Corp
+15BB    Portwell Inc
+15BC    Agilent Technologies
+        0101    n2530a DX2+ FC-AL Adapter
+        0103    QX4 4 Port Fibre Channel Controller
+        0B01    SUBSYS_000015BC&REV_00 Agilen PCI-GPIB
+        1200    0x15bc Agilent QX4 Fibre Channel Controller
+        2530    ??? HP Communications Port
+        2531    ??? HP Toptools Remote Control Adapter
+        2532    ??? HP Toptools Remote Control Adapter
+        2929    E2929A PCI/PCI-X Bus Analyzer
+15BD    DFI Inc.
+15BE    Sola Electronics
+15BF    High Tech Computer Corp (HTC)
+15C0    BVM Limited
+15C1    Quantel
+15C2    Newer Technology Inc
+        0038    2.4G part of the iMon-IR-RC-Display-Kit
+15C3    Taiwan Mycomp Co Ltd
+15C4    EVSX Inc
+15C5    Procomp Informatics Ltd
+15C6    Technical University Of Budapest
+15C7    Tateyama System Laboratory Co Ltd
+15C8    Penta Media Co. Ltd
+15C9    Serome Technology Inc
+15CA    Bitboys OY
+15CB    AG Electronics Ltd
+15CC    Hotrail Inc.
+15CD    Dreamtech Co Ltd
+15CE    Genrad Inc.
+15CF    Hilscher GMBH
+15D1    Infineon Technologies AG
+        0001    TC11IB TriCore 32-bit Single-chip Microctrlr
+        0003    PEB 20544 E v1.1 6 Port Optimized Comm Ctrlr (SPOCC)
+        0004    PNPA000 Infineon Technologies AG
+        000B    SLB9635 TPM
+15D2    FIC (First International Computer Inc)
+15D3    NDS Technologies Israel Ltd
+15D4    Iwill Corporation
+15D5    Tatung Co.
+15D6    Entridia Corporation
+15D7    Rockwell-Collins Inc
+        RS56    hcf cx11252-41z hcf 56
+15D8    Cybernetics Technology Co Ltd
+        9001    
+15D9    Super Micro Computer Inc
+        9876    1234 4567
+15DA    Cyberfirm Inc.
+15DB    Applied Computing Systems Inc.
+15DC    Litronic Inc.
+        0001    Argus 300 PCI Cryptography Module
+15DD    Sigmatel Inc.
+        7664    vgn-ar51j idt high audio
+        7680    2772 SIGMATEL STAC 92XX C-Major HD Audio
+        769     7690 9200 HD .......... ..........
+        7690    10F70000 You'll Love me 4 this/ visit http://wendhelofopportunity.info Support Me!
+        8384    HDAUDIO\FUNC_01&VEN_8384&DEV_7616&SUBSYS_1028020A& Intel Audio Studio
+        9876    1 1
+15DE    Malleable Technologies Inc
+15E0    Cacheflow Inc
+        7134    01385168 01
+15E1    Voice Technologies Group
+15E2    Quicknet Technologies Inc
+        0500    Internet PhoneJack PCI Card
+15E3    Networth Technologies Inc
+15E4    VSN Systemen BV
+15E5    Valley Technologies Inc
+15E6    Agere Inc.
+        00000002        1646t00 v.90 Lucent Modem
+15E7    GET Engineering Corp.
+        755     QUAD-P NTDS Parallel Adapter
+15E8    National Datacomm Corp.
+        0130    NCP130 Wireless NIC
+        0131    Prism II InstantWave HR PCI card
+15E9    Pacific Digital Corp.
+        1841    NetStaQ ADMA-100 ATA controller
+15EA    Tokyo Denshi Sekei K.K.
+15EB    Drsearch GMBH
+15EC    Beckhoff Automation GmbH
+15ED    Macrolink Inc
+15EE    IN Win Development Inc.
+15EF    Intelligent Paradigm Inc
+        0028    8280BDM SoundMAX Controller (ICH7-M B0 Setup) SigmaTelHigh Definition Audio CODEC
+        24c5    8280BDM SoundMAX Controller (ICH4-M B0 Setup) VIA-Vynil v700b
+        7616    102801F7 SigmaTelHigh Definition Audio CODEC
+15F0    B-Tree Systems Inc
+15F1    Times N Systems Inc
+        2F30    CX11252-15 Conexant HSFi
+15F2    SPOT Imaging Solutions a division of Diagnostic Instruments, Inc
+        0001    Spot RT Spot RT Interface Board
+        0002    Spot RT #2 Spot RT Interface Board
+        0003    Spot Insight Spot Insight Interface Board
+15F3    Digitmedia Corp.
+15F4    Valuesoft
+15F5    Power Micro Research
+15F6    Extreme Packet Device Inc
+15F7    Banctec
+15F8    Koga Electronics Co
+15F9    Zenith Electronics Co
+15FA    Axzam Corporation
+15FB    Zilog Inc.
+15FC    Techsan Electronics Co Ltd
+15FD    N-Cubed.Net
+15FE    Kinpo Electronics Inc
+15FF    Fastpoint Technologies Inc.
+1600    Northrop Grumman - Canada Ltd
+1601    Tenta Technology
+1602    Prosys-TEC Inc.
+1603    Nokia Wireless Business Communications
+1604    Central System Research Co Ltd
+1605    Pairgain Technologies
+1606    Europop AG
+1607    Lava Semiconductor Manufacturing Inc.
+1608    Automated Wagering International
+1609    Sciemetric Instruments Inc
+160A    Kollmorgen Servotronix
+        3184    6656 Via VT6656 Wireless Lan Adapter
+160B    Onkyo Corp.
+160C    Oregon Micro Systems Inc.
+160D    Aaeon Electronics Inc
+160E    CML Emergency Services
+160F    ITEC Co Ltd
+1610    Tottori Sanyo Electric Co Ltd
+1611    Bel Fuse Inc.
+1612    Telesynergy Research Inc.
+1613    System Craft Inc.
+1614    Jace Tech Inc.
+1615    Equus Computer Systems Inc
+1616    Iotech Inc.
+        0409    DaqBoard/2000 16-Bit, 200-kHz PCI Data Acquisition DaqBoards with DBK Signal Conditioning Support 
+1617    Rapidstream Inc
+1618    Esec SA
+1619    FarSite Communications Limited
+        0400    FarSync T2P Two Port Intelligent Sync Comms Card
+        0440    FarSync T4P Four Port Intelligent Sync Comms Card
+        0610    FarSync T1U One Port Intelligent Sync Comms Card
+        0620    FarSync T2U Two Port Intelligent Sync Comms Card
+        0640    FarSync T4U Four Port Intelligent Sync Comms Card
+        1610    FarSync TE1 One Port Intelligent Sync Comms Card
+        1612    FarSync TE1e (PCI Express) One Port Intelligent Sync Comms Card
+        2610    FarSync DSL-S1 G.SHDSL Intelligent Sync Comms Card
+        3640    FarSync T4E Four Port Intelligent Sync Comms Card
+        4620    FarSync T2Ue (PCI Express) Two Port Intelligent Sync Comms Card
+        4640    FarSync T4Ue (PCI Express) Four Port Intelligent Sync Comms Card
+        5621    FarSync T2Ee (PCI Express) Two Port Intelligent Sync Comms Card
+        5641    FarSync T4Ee (PCI Express) Four Port Intelligent Sync Comms Card
+        6620    FarSync-T2U-PMC Two Port Intelligent Sync Comms Card
+161B    Mobilian Israel Ltd
+161C    Berkshire Products
+161D    Gatec
+161E    Kyoei Sangyo Co Ltd
+161F    Arima Computer Corporation
+1620    Sigmacom Co Ltd
+1621    Lynx Studio Technology Inc
+        0020    LynxTWO-A 4 in/4 out Professional Digital Audio Card
+        0021    LynxTWO-B 2 in/6 out Professional Digital Audio Card
+        0022    LynxTWO-C 6 in/2 out Professional Digital Audio Card
+        0023    Lynx L22 2 in/2 out Professional Digital Audio Card
+        0024    Lynx AES16 16 in/16 out AES/EBU Audio Card
+        0025    Lynx AES16-SRC 16 in/16 out AES/EBU Audio Card w/SRC
+1622    Nokia Home Communications
+1623    KRF Tech Ltd
+1624    CE Infosys GMBH
+1625    Warp Nine Engineering
+1626    TDK Semiconductor Corp.
+1627    BCom Electronics Inc
+1629    Kongsberg Spacetec a.s.
+        1003    Format Synchronizer v3.0
+        2002    Fast Universal Data Output
+162A    Sejin Computerland Co Ltd
+162B    Shanghai Bell Company Limited
+162C    C&H Technologies Inc
+162D    Reprosoft Co Ltd
+        0100    driver Repeographics controller
+        0101    Reprographics Controller
+        0102    Reprographics Controller
+        0103    Reprographics Controller
+162E    Margi Systems Inc
+162F    Rohde & Schwarz GMBH & Co KG
+        1111    TS-PRL1 General Purpose Relay Card
+        1112    TS-PMA Matrix Card
+1630    Sky Computers Inc
+1631    NEC Computer International
+1632    Verisys Inc
+1633    Adac Corporation
+1634    Visionglobal Network Corp.
+1635    Decros / S.ICZ a.s.
+1636    Jean Company Ltd
+1637    NSI
+1638    Eumitcom Technology Inc
+        1100    WL11000P  WL11000P
+163A    Air Prime Inc
+163B    Glotrex Co Ltd
+        2416    Techwell - TW2804  Model - JSA-2416Drivers on this DVR Video Capture Card 16CH
+163C    intel
+        3052    R6793-11 RS56/HSP-PCI
+        FF02    82801 GB PCI Bridge - 244E
+163D    Heidelberg Digital LLC
+163E    3dpower
+163F    Renishaw PLC
+1640    Intelliworxx Inc
+1641    MKNet Corporation
+1642    Bitland
+1643    Hajime Industries Ltd
+1644    Western Avionics Ltd
+1645    Quick-Serv. Computer Co. Ltd
+1646    Nippon Systemware Co Ltd
+1647    Hertz Systemtechnik GMBH
+1648    MeltDown Systems LLC
+1649    Jupiter Systems
+164A    Aiwa Co. Ltd
+164C    Department Of Defense
+164D    Ishoni Networks
+164E    Micrel Inc.
+164F    Datavoice (Pty) Ltd.
+        0001    PLX 9054 PCI interface chip
+        0002    PLX 9054 PCI interaface chip
+1650    Admore Technology Inc.
+1651    Chaparral Network Storage
+1652    Spectrum Digital Inc.
+1653    Nature Worldwide Technology Corp
+1654    Sonicwall Inc
+1655    Dazzle Multimedia Inc.
+1656    Insyde Software Corp
+1657    Brocade Communications Systems
+        0646    BRE040 Brocade 400 series PCIe HBA
+1658    Med Associates Inc.
+        0704    905410B5 DIG 704 PCI - Interface with Millisecond Timer and Interrupts
+1659    Shiba Denshi Systems Inc.
+165A    Epix Inc.
+        C100    PIXCI CL1 PCI camera link video capture board
+        D200    PIXCI D2X PCI digital video capture board
+        D300    PIXCI D3X PCI digital video capture board
+        F001    PIXCI EL1 PCI-E camera link video capture board
+165B    Real-Time Digital Inc.
+165C    Kondo Kagaku
+        0002    FT232BL FT232BL
+165D    Hsing Tech. Enterprise Co. Ltd.
+165E    Hyunju Computer Co. Ltd.
+165F    Comartsystem Korea
+        2000    XILINX SPARTAN 16 Channel Audio Capture Card
+1660    Network Security Technologies Inc. (NetSec)
+1661    Worldspace Corp.
+1662    Int Labs
+1663    Elmec Inc. Ltd.
+1664    Fastfame Technology Co. Ltd.
+1665    Edax Inc.
+1666    Norpak Corporation
+1667    CoSystems Inc.
+1668    Actiontec Electronics Inc.
+        0100    0304 PCI to PCI Bridge
+166A    Komatsu Ltd.
+166B    Supernet Inc.
+166C    Shade Ltd.
+166D    Sibyte Inc.
+        0001    BCM1125/BCM1250 PCI Configuration Header 
+        0002    BCM1125/BCM1250 HyperTransport Configuration Heade MIPS BCM1125/BCM1250 processors
+166E    Schneider Automation Inc.
+166F    Televox Software Inc.
+1670    Rearden Steel
+1671    Atan Technology Inc.
+1672    Unitec Co. Ltd.
+1673    pctel
+1675    Square Wave Technology
+1676    Emachines Inc.
+        1001    5.10.00.5760 Realtek AC' 97 Audio Driver
+1677    Bernecker + Rainer
+        20ad    5ACPCI.MFIO-K01 Profibus DP / K-Feldbus / COM
+1678    INH Semiconductor
+1679    Tokyo Electron Device Ltd.
+167F    iba AG
+        4634    FOB-IO Card
+        4C32    L2B PCI Board
+        5344    SD \ VID_03 .... OID_5344 .... PID_SU01G .... REV_ FOB-SD Card
+        5443    FOB-TDC Card
+        F0B1    ibaFOB-io-D ibaFOB-io-D
+        F0B2    ibaFOB-2io-D ibaFOB-2io-D
+        F0B4    ibaFOB-4io-D ibaFOB-4io-D
+        F1B2    ibaFOB-2i-D ibaFOB-2i-D
+        F5DE    ibaFOB-SDexp ibaFOB-SDexp
+        FDCE    ibaFOB-TDCexp ibaFOB-TDCexp
+        FEC1    ibaFOB-io-ExpressCard ibaFOB-io-ExpressCard
+1680    Dunti Corp.
+1681    Hercules
+        0050    HWGPCI-54 Hercules WiFi PCI 802.11G
+1682    PINE Technology, Ltd.
+        2931    unknown HD-467X-DDF2 video card 
+        9875    779A HD 7700 Series
+1688    CastleNet Technology Inc.
+        0013    AR5213 
+168A    Utimaco Safeware AG
+168B    Circut Assembly Corp.
+168C    Atheros Communications Inc.
+         001c   AR5005GS pci\ven_10ac&dev_ooo
+        00027   E017105B Atheros AR5B95 Wireless LAN 802.11 a/b/g/n Controller
+        00030   PCI\VEN_168C&DEV_0030&SUBSYS_16A810CF&REV_01 TP-LINK 450Mbps Wireless N Adapter
+        0007    AR5007UG ROOT\MS_SSTPMINIPORT\0000
+        0011    11L/b/g Wireless LAN Mini PCI Adapter 11L/b/g Wireless LAN Mini PCI Adapter
+        0012    AR5211  PCI\VEN_1217&DEV_7130&SUBSYS_FF501179&REV_01 DELL Latitude C510 as mini-PCI board behind the larg
+        0013    Netgear WPN311 Netgear RangeMax WPN311 PCI Wireless NIC
+        0019    AR5bmb5 802.11a Wireless Adapter
+        001A    Atheros AR5005GS http://support1.toshiba-tro.de/tools/updates/atheros-wlan/atheros-wlan-xp-7702331.zip
+        001B    AR5006X 802.11abg NIC
+        001c    AR5007EG Atheros AR5007EG Wireless Network Adapter
+        001C other      AR5BXB63 Atheros AR5BXB63 WWAN Chip
+        001c_again      AR5BXB61 AR5006EX AR5423a
+        001D    TP-Link TL-WN350GD PCI\VEN_168C&DEV_002B&SUBSYS_E034105B&REV_01\4&124A40C8&0&00E1
+        002     c660 PCI/VEN_168C&DEV_002B&SUBSYS_7173144F&REV_01\4&200004B7&0&00E1
+        0023    AR5416 802.11a/b/g/n&#1041;&#1077;&#1089;&#1087;&#1088;&#1086;&#1074;&#1086;&#1076;&#1085;&#1086;&#1081; PC
+        0024    AR5B97 Atheros 802.11a/b/g/n
+        0027    E017105B Atheros AR5B95 Wireless LAN 802.11 a/b/g/n Controller
+        002A    AR9283-ALIA or DW1525 Wireless Network Adapter
+        002B    66318898888811ad Atheros AR5B95 
+        002C    AR5006 Wireless 802.11 a/b/g/n WiFi Adapter (PCI-Express)
+        002D    AR9287 rev01 802.11b/g/n
+        002E    AR9287 Atheros ar9287 PCI &#1052;&#1086;&#1078;&#1083;&#1080;&#1074;&#1086;&#1089;&#1090;&#1110;: &#1047;&#
+        0030    1102 - 1103 Killer Wireless - N
+        0032    168Cx0032 Atheros AR9485
+        0034    DW1901 802.11a/b/g/n, BT4.0+HS 
+        0036    AR956x Qualcomm Atheros AR956x Wireless Network Adapter
+        0037    AR1111 Atheros AR1111 WB-EG Wireless Network Adapter
+        003e    QCA61x4 Wireless Network Adapter
+        007     AR5007UG Wireless Network Adapter
+        0280    0x002b PCI\VEN_168C&DEV_002B&SUBSYS_30AF185F
+        032     0x0280 Dell Wireless DW1703 802.11b/g/n, BT4.0 + HS 
+        1014    AR9285 Atheros AR5212 802.11abg wireless Drivers
+        14F1    nForce6100-430   PCI\VEN_168C&DEV_001A&SUBSYS_04181468&REV_01\4&FCF0450&0&10A4
+        168C    AREG9485WB-0036 Qualcomm Atheros AR9485WB-EG Wireless Network Adapter
+        1a3b    ar8132 802.11a/b/g/n Wireless PCI Adapte
+        3002    AR3011 Bluetooth 3.0
+        6666    AR5007UG Atheros AR5B95 Wireless LAN 802.11 a/b/g/n Controller
+        9876    AR5419 Atheros AR5B95 Wireless LAN 802.11 a/b/g/n Controller
+        FF1B    AR 5001 Wireless LAN G
+        FF96    AR5212 LAN-Express AS IEEE 802.11g miniPCI adapter
+168D    NMI Electronics Ltd.
+168E    Hyundai MultiCAV Computer Co. Ltd.
+168F    KDS Innotech Corp.
+1690    NetContinuum, Inc.
+        0742    BCM2070 BRCM Bluetooth Controller BCM2070
+1693    FERMA
+        0212    PLX PCI9054 EPONINE ESR-PCI Board
+        0213    Motorola MPC8245 EPONINE MTM120 PCI Board
+1695    EPoX Computer Co., Ltd.
+16AE    SafeNet Inc.
+        000A    SafeXcel-1841 Crypto Accelerator
+        1141    SafeXcel-1141 Crypto Accelerator
+16B3    CNF Mobile Solutions
+16B8    Sonnet Technologies, Inc.
+16CA    Cenatek Inc.
+        0001    Rocket Drive Solid State Disk
+16CB    Minolta Co. Ltd.
+16CC    Inari Inc.
+16D0    Systemax
+16E0    Third Millenium Test Solutions, Inc.
+16E5    Intellon Corporation
+16EC    U.S. Robotics
+        0116    RTL8169S RealTek 8169S chip
+        0303    Rev_0200 U.S. Robotics 56K FAX USB V1.1.0 /  V.92 USB modem
+        1007    0637 U.S. Robotics 56K Win INT
+        2013    11323A U.S. Robotics 56K Voice Host Int
+        2F00    USRobotics 5660A - Internal Soft Modem http://www.usr.com/support/product-template.asp?prod=5660a
+        2f12    E129336-1 U.S.Robotic (A- Modem/PCI)
+        3685    1518 Wireless Access Adapter Model 022415
+        5685    E129336-1 U.S. Robotics 56K Voice Host Int (A-Modem/ PCI)
+16F0    LaserLinc Inc.
+16F1    Adicti Corp.
+16F3    Jetway Information Co., Ltd
+16F6    VideoTele.com Inc.
+1700    Antara LLC
+1701    Interactive Computer Products Inc.
+1702    Internet Machines Corp.
+1703    Desana Systems
+1704    Clearwater Networks
+1705    Digital First
+1706    Pacific Broadband Communications
+1707    Cogency Semiconductor Inc.
+1708    Harris Corp.
+1709    Zarlink Semiconductor
+170A    Alpine Electronics Inc.
+170B    NetOctave Inc.
+        0100    NSP2000-SSL Crypto Aceletator
+170C    YottaYotta Inc.
+170D    SensoMotoric Instruments GmbH
+170E    San Valley Systems, Inc.
+170F    Cyberdyne Inc.
+1710    Pelago Networks
+        5812    5812 itech numeric small keyboard
+        9835    9825 2 serial, 1 LPT port PCI Card
+1711    MyName Technologies, Inc.
+1712    NICE Systems Inc.
+        3038    VT6212L usb
+        7130    0x1712 unknown
+1713    TOPCON Corp.
+1725    Vitesse Semiconductor
+        7174    VSC7174 VSC7174 PCI/PCI-X SATA Controller
+1734    Fujitsu-Siemens Computers GmbH
+        007a    Rage XL ATI Rage XL (rev 27)
+        1011    AIC-7902W Adaptec AIC-7902 Dual Channel U320 SCSI
+        1012    CSB6 Serverworks Southbridge with RAID/IDE (rev a0), OHCI USB (rev 05), GCLE-2 Host Bridge
+        1013    BCM5703 Broadcom Corp. NetXtreme Gigabyte Ethernet
+        10b9    0x00541000 SAS 3000 series, 8-port with 1068 -StorPort
+1737    LinkSys
+        0071    RT2870 Dual Band Wireless N USB Network Adapter
+        1032    EG1032 v3 Linksys Instant Gigabit Desktop Network Interface
+173B    Altima Communications Inc.
+        03E8    AC1000 Gigabit Ethernet Adapter
+        03EA    AC1002 Gigabit Ethernet Adapter
+1743    Peppercon AG
+        8139    ROL/F-100 Fast Ethernet Adapter with ROL
+174B    PC Partner Limited
+        0260    RV280 Saphire Radeon 9250
+        0261    RV280 Sapphire Radeon 9250 - Secondary
+        7176    RV250 RADEON 9000 ATLANTIS PRO
+        7177    RV280 RADEON 9000 ATLANTIS PRO - Secondary
+        71C6    RV530 ATI RADEON X1650 Series
+        7244    RV580 Sapphire ATI  X1950 XT
+        7C12    RV280 RADEON 9200 ATLANTIS - Secondary
+        7C13    RV280 RADEON 9200 ATLANTIS
+        9501    RV620  ATI Radeon HD 3450
+        E106    0x954F Graphics Chipset ATI Radeon HD 4300/4500 Series          
+        e131    RV770 ATI 4870
+        E140    5870 Sapphire HD 5870 1GB GDDR5
+1752    Global Brands Manufacture Ltd.
+1753    TeraRecon, Inc.
+        1001    VP500 VolumePro 500
+        1004    VP1000 VolumePro 1000
+1755    Alchemy Semiconductor Inc.
+        000     
+        0000    Au1500 Au1500 Processor
+176A    General Dynamics Canada
+1775    General Electric
+1789    Ennyah Technologies Corp
+1793    Unitech Electronics Co., Ltd
+17A1    Tascorp
+        0128     17A1 USB2.0 JPEG WebCam 
+17A7    Start Network Technology Co., Ltd.
+17AA    Legend Ltd. (Beijing)
+        0106    Intel HD Graphics 2000 Intel Sandy Bridge-MB GT1 - Integrated Graphics Controller [D2/J1/Q0] [Lenovo
+        7145    138A Mobility ATI Radeon X1400
+17AB    Phillips Components
+17AF    Hightech Information Systems, Ltd.
+        4150    200 HIS Excalibur Radeon 6870
+        7291    RV560 HIS  Radeon X1650 XT
+17BE    Philips Semiconductors
+17C0    Wistron Corp.
+        12ab    intel
+17C4    Movita
+17CC    NetChip
+        1978    net 2280 usb 2.0 device controller
+        2280    Net 2280 USB 2.0 Device Controller
+17cd    Cadence Design Systems
+17D5    Neterion Inc.
+        5831    X1 Xframe 10GbE PCI-X Adapter
+        5832    X2 Xframe II 10GbE PCI-X 2.0 Adapter
+        5833    X3 E3100 PCI-Express 10Gb Ethernet Interface
+17db    Cray, Inc.
+        0101    NA Seastar Network
+        0201    NA Gemini Network
+        0301    NA Aries Network
+17E9    DH electronics GmbH / Sabrent
+        02a7    0000 USB VGA/DVI Adapter UV-D4A1-B
+        4318    n/a Dell GigabitEthernet (USB-G1000)
+17EE    Connect Components, Ltd.
+        4153    RV350 Radeon 9550
+17F3    RDC Semiconductor Co., Ltd.
+        1010    D1010 IDE Controller 
+        1011    D1011 Standard IDE Controller
+        1030    M1030 PCI to PCI-E Bridge
+        2010    M2010 GPU (VGA )
+        3010    M3010 HD Audio
+        6021      Host Bridge
+        6036      PCI to ISA Bridge
+        6040    R6040x Ethernet MACx
+        6060     modem USB Controller (OHCI)
+        6061     V90479. 1 USB 2.0 Controller (EHCI)
+17FE    INPROCOMM
+        2220    2120 Generic IEEE 802.11b/g Wireless LAN Card
+1813    Ambient Technologies Inc
+        3059    VT8237 AC97 Enhanced Audio Controller - the 8251 controller is different
+        4000    MD5628D-L-A intel V.92 HaM Modem
+        4100    Ambient MD8820 Intel HaM V.92 Modem
+1814    Ralink Technology, Corp.
+        0001    ...B742000 ...I don't know
+        0101    2460  802.11b RT2460  802.11b Baseband/MAC integrated chip
+        0201    PCI\VEN_1814&DEV_3298&SUBSYS_1451033 Ralink Chipset 802.11b/g WLAN Card
+        0201 (1)        WiFiSKY Ralink RT2500 802.11b/g WLAN Card
+        0201 (2)        001167F044E5 W-LAN 802.11b/g
+        0201 (3)        RT2560F RaLink
+        0201(3) WMP54G Wireless-G PCI adapter
+        0301    RT2561 Ralink RT2561 Wireless-G PCI
+        0301 (2)        RT2561 Ralink RT2561 Wireless-G PCI
+        0302    RT2525 2.4GHz transceiver + RT2560 MAC/BBP wireless p/n same Chipset in D-Link DWL-G510
+        0401    RT 2661 Ralink MIMO RT 2661 Wireless 54 Mbps
+        0601    RT2860T b/g/n  Wlan
+        0701    RT2860T 802.11 bgn
+        0781    RT2790T/RT2860/RT2890/RT2700E Wireless 802.11 bgn PCI-e
+        1418    0x14FI 802.11b/g Wireless LAN
+        14F1    0x1814 PCI\VEN_168C&DEV_001A&SUBSYS_04181468&REV_01\4&FCF0450&0&10A4
+        201     25601814&REV_01 Ralink RT2500 Wireless Lan Card
+        3060    RT3060 Ralink corp. RT3060 Wireless 802.11n PCI adapter
+        3090    Ralink RT3090 Ralink RT3090 Wireless Lan Card with Bluetooth
+        3290    1010 802.11n   Bluetooth 4.0
+        3298    -3290 Ralink Bluetooth
+        3592    RT3592 Wireless LAN a/b/g/n plus Bluetooth 3.0 combo
+        5360    RT5360  http://www.wikidevi.com/wiki/D-Link_DWA-525_rev_A2
+        5390    ASUS X55VD VEN_1814&DEV_5390&SUBSYS_E054105B&REV00 802.11n Wireless Lan Card - Asus X55V - Win 7 64bit - Foxconn Wireless
+        539B    RT5390R Ralink RT5390R 802.11b/g/n WiFi
+        9876    b8341462 Edimax 54 MBit WLan 802.11g rt 2500
+1815    devolo AG
+1820    InfiniCon Systems, Inc.
+1824    Avocent
+1841    Panda Platinum
+1860    Primagraphics Ltd.
+186C    Humusoft S.R.O
+        1014    AR5BXB6 Atheros 802.11abg
+1887    Elan Digital Systems Ltd
+1888    Varisys Limited
+        0301    
+        0601    
+        0710    
+        0720    
+        2503    Bt881 Video Capture (10 bit High qualtiy cap)
+        2504    Bt878 Video Capture
+        3503    nVidia NV28 VGA Geforce4 MX440
+        3505    nVidia NV28 VGA Geforce4 Ti4200
+188D    Millogic Ltd.
+1890    Egenera, Inc.
+18BC    Info-Tek Corp.
+18C9    ARVOO Engineering BV
+        1011    Leonardo CL Video processor
+        1012    Leonardo CL-P Video processor
+        1013    Leonardo CL-DB Video processor
+        1014    Leonardo CL-P-DB Video processor
+        1015    Leonardo CL-DVR Video processor
+        1016    Leonardo CL-DVR-DB Video processor
+        2011    Picasso 2SQ Framegrabber
+        2012    Picasso 3C/3Cpro Framegrabber
+        2013    Picasso LS Framegrabber
+        2014    Picasso CL Framegrabber
+        2015    Picasso FI Framegrabber
+        2016    Picasso SDI Framegrabber
+        2017    Picasso DUO Framegrabber
+        2021    Colory Framegrabber
+        3011    Valentino Video Output Board
+18CA    XGI Technology Inc
+        0020    Volari Z9s Volari Z series (Select GPU Graphic Drivers
+        0040    Silicon Intgrated System Volari Family Z Series
+18F1    Spectrum Systementwicklung Microelectronic GmbH
+18F4    Napatech A/S
+18F7    Commtech, Inc.
+        0001    ESCC-PCI-335 Fastcom:ESCC-PCI-335 Syncronous RS422/485 serial communication adapter
+        0002    422/4-PCI-335 Fastcom:422/4-PCI-335 Asyncronous RS422/485 serial adapter
+        0004    422/2-PCI-335 Fastcom:422/2-PCI-335 Asyncronous RS422/485 serial adapter
+        000a    232/4-PCI-335 Fastcom:232/4-PCI-335 Asyncronous RS232 serial adapter
+18FB    Resilience Corporation
+1904    Ritmo
+        2031    n /a silan sc92031 Network adapter
+        8139            8129 Realtek RTL8139 PCI Fast Ethernet Adapter
+        8139    8139 Realtek RTL8139 PCI Fast Ethernet Adapter
+1905    WIS Technology, Inc.
+1910    Seaway Networks
+        0001    SW5000-NCA Seaway Network Content Accelerator
+1912    Renesas Electronics
+        0014    YET-D720201-0014 usb3.0 renesas
+        0015     upd720202  nec
+        0015_   EC01-P Renesas Electronics USB 3.0 Host Controller
+1931    Option NV
+1941    Stelar
+1954    One Stop Systems, Inc.
+1969    Atheros Communications
+        1026    AR8121/AR8113  PCI-E ETHERNET CONTROLLER 
+        1048    Atheros L1 Gigabit Ethernet 10/100/1000 Base-T Controller
+        1060    AR8162 PCI-E Fast Ethernet Controller
+        1062    AR8132 Atheros AR8132 PCI-E&#1050;&#1086;&#1085;&#1090;&#1088;&#1086;&#1083;&#1083;&#1077;&#1088; &#1041;&#
+        1062c   Atheros L1  Gigabit Ethernet 10/100/1000 Base-T Controller
+        1063    AR8131 Atheros AR8131 PCI-E Gigabit Ethernet Controller
+        1073    AR8151 Atheros AR8151
+        1083    78161462 Atheros AR8151 PCI-E Gigabit Ethernet Controller (NDIS 6.20)
+        1090    AR8162+ Fast Ethernet
+        1091    AR8161/8165 PCI-E Gigabit Ethernet Controller
+        10a0    Atheros AR8172/8176/8178 Controller Ethernet Qualcomm Atheros AR8172/8176/8178 PCI-E Fast (NDIS 6.30)
+        168c    Atheros L1  Gigabit Ethernet 10/100/1000 Base-T Controller 
+        1969    Atheros L3 Atheros AR815x/816x Ethernet Controller Driver 
+        2048    Atheros L2 Fast Ethernet 10/100 Base-T Controller
+        2049    234543 der
+        2060    fd501179&rev-c1 AR8152 v1.1 Fast Ethernet
+        2061    1 Ethernet Controller
+        2062    FB501179 Qualcomm Atheros AR8152/8158
+        4747    1969 VEN_1969
+        9876    Atheros L2 Fast Ethernet 10/100 Base-T Controller 
+        E091    Killer E2200 Killer E2200 Network Card
+        R091    Killer E2200 Killer E2200 Network Card
+1971    AGEIA Technologies, Inc.
+        0001    PCI\VEN_1971&DEV_0000&SUBSYS_0003105B&REV_00 AGEIA PhysX 100 Series PCI Express Card
+        1011    PCI\\VEN_1971&DEV_1011&CC_FF00 AGEIA PhysX 100 Series PCI Card
+        1021    AGEIA PhysX 200 Series PCI Express Card
+197B    JMicron Technology Corp.
+        0250    JMC25 JMC250 PCI Express, Gigabit Ethernet
+        0256    JMC2XX JMC260 PCI Express Fast Ethernet
+        0260    ethernet JMC260 PCI Express Fast Ethernet
+        0261    0261 JMB38X MS Host Controller
+        1234    12345678 1234567
+        197b    JMB38X JMB38X SD/MMC 
+        2360    JMicron JMB36X JMB36X
+        2361    JMB363 PCI Express to SATA II and PATA Host Controller
+        2363    JMB36X JMicron JMB362/JMB363 AHCI Controller
+        2366    JMB36X JMicron JMB366 AHCI/IDE Controller
+        2368    JMB368 IDE Comtroller
+        2380    JMB38X IEEE 1394 Host Controller
+        2381    JMB38X JMB38X SD Host Controller
+        2382    JMB38X JMB38X SD/MMC Host Controller
+        2383    0261 JMB38X MS Host Controller
+        2384    JMB38X JMB38X xD Host Controller
+        2391    JMB38X JMB38X SD/MMC - JMicron PCIe SD Host Controller
+        2392    721179  JMB38X SD/MMC - JMicron PCIe SD Host Controller
+        2393     Chip Number:   JMB38X Chip Description:        JMB38X SD/MMC Host Controller
+        7002    JMB38Xam5 JMB38X SD/MMC Host Controller
+        JMB38   JMB38X JMB38X SD/MMC Host Controller
+198a    Nallatech
+        0210      XMC-210
+        0220      XMC-220
+        0230      XMC-230
+        0240      XMC-240
+        1180     pm 965 PCIe-180
+        1280      PCIe-280
+        1395    STRATIX V PCIe-395 standard
+        198a    pm 965 PCIe-180
+        3395    STRATIX V PCIe-395 BSP
+        402F       BenNUEY PCIX
+        4030      H100-PCIX
+        4031      BenNUEY PCI-104-V4
+        4032      BenONE-PCIe
+        4033     PCI\VEN_198A&DEV_4033&SUBSYS_00000000&REV_00 BenONE-Xilinx-Kit-ROHS
+        4034      BenNUEY PCIX RoHS
+1991    Topstar Digital Technologies Co., Ltd.
+19a2    ServerEngines
+        0710    Emulex OneConnect 10Gb NIC (be3) (rev01)
+        0712    Emulex OneConnect 10Gb iSCSI Initiator (be3) (rev 01)
+        0714    Emulex OneConnect 10Gb FCoE Emulex OneConnect 10Gb FCoE &#1048;&#1085;&#1080;&#1094;&#1080;&#1072;&#1090;&#1086;&#1088; (be3) (&
+19A8    DAQDATA GmbH
+19AC    Kasten Chase Applied Research
+        0001    ACA2400 Crypto Accelerator
+19B6    Mikrotik
+        110c    AR5413 Atheros chipset for 802.11a/b/g
+19E2    Vector Informatik GmbH
+19E3    DDRdrive LLC
+        5801    NA DDRdrive X1
+        5808    NA DDRdrive X8
+        DD52      DDRdrive X1-30
+1A08    Linux Networx
+1a41    Tilera Corporation
+1A42    Imaginant
+1B13    Jaton Corporation USA
+        0001    GeForce4 MX 440 nVidia Corporation NV17
+1B21    Asustek - ASMedia Technology Inc.
+        0612    Asmedia 106x SATA Controler Link Below to Mainboard Driver inside
+        1041    SUBSYS_2104174C USB 3.0 Host Controller Driver for Windows 7
+        1042    pci\ven_14f1&dev_2f50&subsys_205f14f1&rev_01\4&cf8 Asmedia ASM104x USB 3.0 Host Controller
+1B6F    Etron
+        7023    DEV_7023&REV_010 Etron USB 3.0 Extensible Host Controller
+1B73    Fresco Logic Inc.
+        1000    1 PCI\VEN_1000&DEV_0020&SUBSYS_10301000&REV_01PCI\VEN
+        1009    Unknown USB3.0 host controller
+        1100    n/a USB 3.0 eXtensibile Host controller
+1B91    Averna
+1BAD    ReFLEX CES
+1C0F    Monarch Innovative Technologies Pvt Ltd's 
+1C32    Highland Technology, Inc.
+1c39    Thomson Video Networks
+        0300    PEGAVIO Pegasus Board PCI-e interface
+1DE1    Tekram
+        0045    RaidCore5000 Series Tekram SAS860 Embedded 8xSAS/SATAII RAID
+        0058    RC5000Series Tekram Elrond 8xSAS/SATAII RAID
+        0391    TRM-S1040 SCSI ASIC
+        2020    DC-390 SCSI Controller
+        690C    DC-690C IDE Cache Controller
+        DC29    DC290M Bus Master IDE PCI 2 controllers
+1FCF    Miranda Technologies Ltd.
+2001    Temporal Research Ltd
+        3C19    Ralink RT5370 USB <=> Wireless N 150 Adapter
+        F103    .7D01 .driver
+2646    Kingston Technology Co.
+        0001    12333 22323
+        2646    6.06324 22323
+270F    ChainTek Computer Co. Ltd.
+2EC1    Zenic Inc
+3388    Hint Corp.
+        0020    HB2/HB6 Universal PCI-PCI Bridge (transparent mode)
+        0021    HB1 pci-pci 0304 ZS095A0
+        0022    HB1  0304 PCI-PCI Bridge
+        0026    PCI6154BB Universal PCI-PCI Bridge (transparent mode)
+        0028    HB8 Dual Mode PCI-X-to-PCI-X Bridge (transparent mode)
+        0029    HB8 Dual Mode PCI-X-to-PCI-X Bridge (non-transparent mode)
+        0030    HB7 Transparent PCI-X-to-PCI-X Bridge
+        0031    PCI 6156 Synchronous 32-Bit, 33 MHz PCI-to-PCI Bridge for Video Capture Applications
+        8011    II CPU to PCI Bridge
+        8012    cmi 8330 PCI to ISA Bridge
+        8013    PLX Registration Record Management EIDE Controller
+3411    Quantum Designs (H.K.) Inc.
+3513    ARCOM Control Systems Ltd.
+38EF    4links
+3D3D    3Dlabs, Inc. Ltd
+        0001    GLint 300SX 3D Accelerator
+        0002    GLint 500TX Sapphire 3D Accelerator
+        0003    GLint Delta Geometry processor
+        0004    3C0SX 2D+3D Accelerator
+        0005    Permedia 2D+3D Accelerator
+        0006    GLint MX 3D Accelerator
+        0007    3D Extreme Permedia II 2D+3D Accelerator
+        0008    GLint Gamma G1 
+        0009    Permedia2v 2d+3d chipset, integrated ramdac
+        000A    8086 Driver Ethernet Pci Ven 1969
+        000C    Permedia 3 video card
+        000D    GLINT R4 3D Accelerator
+        000E    GLINT Gamma G2 
+        0020    0x0024 3Dlabs Wildcat VP 880 Pro
+        0030    0x030000 3Dlabs Wildcat Realizm 800
+        0100    Permedia II 2D+3D Accelerator
+        1004    Permedia 3D+3D Accelerator
+        3D04    Permedia 2D+3D Accelerator
+        3D07104c        same as above?  I have no idea ?
+        FFFF    GLint VGA 
+4005    Avance Logic Inc.
+        0300    3220 PCI Audio Device
+        0308    3220 PCI Audio Device + modem
+        0309    ALS300  PCI Input Controller
+        1064    ALG2064 GUI Accelerator
+        2064    <DELETE> GUI Accelerator
+        2128    ALG2364A GUI Accelerator
+        2301    ALG2301 GUI Accelerator
+        2302    ALG2302 GUI Accelerator
+        2303    AVG2302 GUI Accelerator
+        2364    ALG2364 GUI Accelerator
+        2464    ALG2464 GUI Accelerator
+        2501    ALG2564A/25128A GUI Accelerator
+        4000    ALS4000 Audio Chipset
+4144    Alpha Data
+        0040    ADM-XRC Virtex-E Bridge
+        0041    ADM-XRC-II Lite Virtex-II Bridge
+        0042    ADM-XRC-II Virtex-II Bridge
+        0043    ADM-XPL Virtex-II Pro Bridge
+        0044    ADM-XP Virtex-II Pro PCI/PCI-X Bridge
+        0045    ADP-WRC-II Virtex-II Bridge
+        0046    ADP-DRC-II Virtex-II Bridge
+        0049    ADP-XPI Virtex-II Pro PCI
+        004A    ADP-XPI (PCI-X) Virtex-II Pro PCI-X Bridge
+        004F    ADM-XRC-4FX Virtex-II Pro PCI-X Bridge
+        0050    ADM-XRC-5LX Virtex-4LX Bridge
+        0051    ADM-XRC-5T1 ADM-XRC-5T1
+        0052    ADM-XRC-5T2 Xilinx Virtex 5 PMC
+        0056    ADM-AMC-5A2 Virtex 5 AMC FPGA board
+        0057    ADM-XRC-5TZ Xilinx Virtex 5 FPGA PMC 
+        0058    ADC-VXS VXS FPGA and PMC Carrier Board
+        005B    ADM-XRC-5T2-ADV ADM-XRC-5T2 with JPEG 2000 devices
+        005C    ADM-XRC-5T-DA1 FPGA PMC with Analog I/O Interface
+        005F    ADM-XRC-5T2-ADV6 As per XRC-5T2 but with 6 JPEG2000 devices
+        0300    ADM-XRC-6T1 Xilinx Virtex 6 FPGA XMC
+        0301    ADM-XRC-6TGE Xilinx Virtex 6 FPGA XMC
+        0303    ADPe-XRC-6T-L Full lenght PCI Express Xilinx Virtex-6 FPGA platform
+        0305    ADPe-XRC-6T Full length PC Card Xilinx Virtex-6 FPGA platform
+416C    Aladdin Knowledge Systems
+        0100    AlladinCARD Puerto paralelo PCI
+        0200    CPC 
+4348    wch.cn
+        1453    202204073 WCH353L
+        3253    32534348 SIE9835 PCI=>DUAL SERIAL
+        5053    4348 4980
+        7053    35255 PCI Serial Port
+        7173    ch350L  CH35X
+4680    UMAX Computer Corp.
+4843    Hercules Computer Technology
+4943    Growth Networks
+4954    Integral Technologies
+4978    Axil Computer Inc.
+4C48    Lung Hwa Electronics
+4C53    SBS-OR Industrial Computers
+        0000    PLUSTEST Diagnostics Device
+        0001    pustest Diagnostics Device
+4CA1    Seanix Technology Inc
+4D51    Mediaq Inc.
+        0200    MQ-200 
+4D54    Microtechnica Co Ltd
+4DDC    ILC Data Device Corp.
+4E8     Samsung Windows Portable Devices
+        618c    rev_0400 usb lan adapter4
+        618d    rev_0400 usb lan adapter4
+5053    TBS/Voyetra Technologies
+        2010    14441 Daytona Audio Adapter
+508A    Samsung T10 MP3 Player
+5136    S S Technologies
+        4678    12363383 S S Technologies
+5143    Qualcomm Inc. USA
+        9204    Unknown WAN Card Lenovo Notebook
+5333    S3 Graphics Co., Ltd
+        0551    86C551 Plato/PX
+        5333    S3 86c765 via
+        5631    86C325 Virge 3D 
+        8800    86C866 Vision 866 GUI Accelerator
+        8801    86C964 Vision 964 GUI Accelerator
+        8810    86C732-P S3 TRIO32  IACB2  86C732-P
+        8811    8622mcq04 Trio 64/64V
+        8812    86CM65? Aurora 64V+
+        8813    86C764 Trio 32/64 GUI Accelerator v3
+        8814    86C767 Trio 64UV+
+        8815    86CM66 Aurora128
+        883D    86C988 ViRGE/VX 3D GUI Accelerator
+        8870    Fire GL 
+        8880    86C868 Vision 868 GUI Accelerator VRAM rev. 0
+        8881    86C868 Vision 868 GUI Accelerator VRAM rev. 1
+        8882    86C868 Vision 868 GUI Accelerator VRAM rev. 2
+        8883    86C868 Vision 868 GUI Accelerator VRAM rev. 3
+        88B0    86C928 Vision 928 GUI Accelerator VRAM rev. 0
+        88B1    86C928 Vision 928 GUI Accelerator VRAM rev. 1
+        88B2    86C928 Vision 928 GUI Accelerator VRAM rev. 2
+        88B3    86C928 Vision 928 GUI Accelerator VRAM rev. 3
+        88C0    86C864 Vision 864 GUI Accelerator DRAM rev. 0
+        88C1    86C864 Vision 864 GUI Accelerator DRAM rev. 1
+        88C2    86C864 Vision 864 GUI Accelerator DRAM rev. 2
+        88C3    86C864 Vision 864 GUI Accelerator DRAM rev. 3
+        88D0    86C964 Vision 964 GUI Accelerator VRAM rev. 0
+        88D1    86C964 Vision 964-P GUI Accelerator VRAM rev. 1
+        88D2    86C964 Vision 964-P GUI Accelerator DRAM rev 2
+        88D3    86C964 Vision 964-P GUI Accelerator VRAM rev. 3
+        88F0    86C968 Vision 968 GUI Accelerator VRAM rev. 0
+        88F1    86C968 Vision 968 GUI Accelerator VRAM rev. 1
+        88F2    86C968 Vision 968 GUI Accelerator VRAM rev. 2
+        88F3    86C968 Vision 968 GUI Accelerator VRAM rev. 3
+        8900    86C775 Trio64V2/DX
+        8901    pci\ven_5333dev_8C2E&SUBSYS_00011179&REV_05\4&74C6 S3 trio64uv+ for windows 7
+        8902    86C551 SMA Family
+        8903    TrioV Family
+        8904    86C365/366 Trio3D QFP/BGA
+        8905    86c765 86C765 Trio64V+ compatible
+        8906    86c765 86C765 Trio64V+ compatible
+        8907    86c765 86C765 Trio64V+ compatible
+        8908    9711 MCN74 86C765 Trio64V+ compatible
+        8909    7699688 86C765 Trio64V+ compatible
+        890A    0x00091011 86C765 Trio64V+ compatible
+        890B    9726 c19394.00 86C765 Trio64V+ compatible
+        890C    86C765 86C765 Trio64V+ compatible
+        890D    86C765 Trio64V+ compatible 86C765 Trio64V+ compatible
+        890E    9711 MCN74 86C765 Trio64V+ compatible
+        890F    86c765 86C765 Trio64V+ compatible
+        8A01    86C375/86C385 ViRGE /DX & /GX
+        8A10    86C357 ViRGE /GX2
+        8A11    86C359 ViRGE /GX2+ Macrovision
+        8A12    86C359 ViRGE /GX2+
+        8A13    86C368 Trio3D2x & Trio3D2x+ AGP / Trio3D2x & Trio3D2x+ 8MB
+        8A20    86C391 S3savage3D
+        8A21    86C390 Savage3D/MV
+        8A22    86c398 Savage 4
+        8A23    86C394-397 Savage 4
+        8A25    86C370 Savage4
+        8A26    86C395B ProSavage
+        8C00    85C260 ViRGE/M3 (ViRGE/MX)
+        8C01    86C260 ViRGE/M5 (ViRGE/MX)
+        8C02    86C240 ViRGE/MXC
+        8C03    86C280 ViRGE /MX+mv
+        8C10    86C270/274/290/294 Savage MX/IX/MX+MV/IX+MV
+        8C12    86C270/274/290/294 Savage MX/IX/MX+MV/IX+MV
+        8C13    82C294 SAVAGE IX
+        8C22    86C508 SuperSavage 128/MX
+        8C2A    86C544 SuperSavage 128/IX
+        8C2B    86C553 SuperSavage 128/IX DDR
+        8C2C    86C564 SuperSavage/IX
+        8C2D    86C573 SuperSavage/IX DDR
+        8C2E    86C584 SuperSavage/IXC SDRAM
+        8C2F    86C594 SuperSavage/IXC DDR
+        8D01    86C380/381 Twister/Twister T
+        8D02    86c387 Twister K
+        8D04    86C410 ProSavage DDR P4X333
+        8E00    86C777/787 DeltaChrome S8/F1
+        8E01    86C732 DeltaChromeX9m
+        9102    86c410 Inno Savage 2000
+        9876    86C390 Savage3D/MV
+        CA00    86C617 SonicVibes PCI Audio Accelerator
+544C    Teralogic Inc
+        0350    00212673158479 IAM
+5555    Genroco Inc.
+        0003    VPI General Digital Video Component Digital Video OEM computer module
+5853    Citrix Systems, Inc.
+        0001    n/a Citrix XenServer PV SCSI Host Adapter
+        0002    n/a Citrix PV Bus Device
+        C000    N/A XenServer Device of Windows Update
+6409    Logitec Corp.
+6666    Decision Computer International Co.
+        0001    815 PCCOM4
+        0002    PCCOM8
+6945    ASMedia Technology Inc.
+7604    O.N. Electric Co. Ltd.
+7d1     D-Link Corporation
+        3304    graphic card 802.11N usb wifi device
+        3c03    DWL-G122 Wifi PCI Same chipset of RALINK  RT2500
+        3C07    D-Link Wireless G DWA-110 USB Adapter PCI\VEN_1799&DEV_700F&SUBSYS_700F1799&REV_20\3&61AAA01&0&48
+8080    Xirlink, Inc
+        1040    VIA 82C259 rev 0 PCI\VEN_8086&DEV_0084&SUBSYS_13158086&REV_00
+8086    Intel Corporation
+         27B8   82801GB/GR Intel(R) 82801GB/GR (ICH7 Family) LPC Interface Controller
+        0004    0x05971028 IUSB3\ROOT
+        0008    Extended Express System Support Ctrlr
+        0011    0x108D Ethernet Controller
+        0042    Intel graphics Intel Q57/H55 Clarkdale (Onboard on D2912-A1x)
+        0044    0044 Intel(R) Processor DRAM Controller
+        0046    Intel(R) HD Graphics (Core i3) Intel(R) HD Graphics
+        0054    not known Audio
+        0082    6205 Centrino Advanced-N 6205 
+        0083    Mobile Intel. 5 Series Chipset Intel Centrino Wireless-N 1000
+        0084    Intel PROSet WiFi 1000 Intel Wireless Link WiFi 1000, download -> http://downloadmirror.intel.com/20791/eng/Wireless_14.3.0
+        0085    0x0280 Intel Centrino(R) Advanced-N 6205
+        0087    1306 00E1
+        008A    ??? Intel Centrino Wireless-N1030
+        008B    Intel Wireless-N 1030 Intel(R) Centrino(R) Wireless-N 1030 
+        0091    622ANHW Intel. Centrino. Advanced-N 6230
+        0100    0100 2nd Generation Intel(R) Core(TM) Processor Family DRAM Controller
+        0102    0001 Intel HD Graphics 3000
+        0104    2nd Gen Intel(R) Core(TM) Processor Family DRAM Controller (Host Bus Controller)
+        0106    HD Graphics 3000/2000 asus x501a
+        010A    010A Lenovo TS130 Intel Video Adapter HD
+        0111    82915 Intel Graphics Conroller
+        0116    intel core i3 Intel HD Graphics 3000
+        0123    0300 hardwareids
+        0152    Intel HD Graphics 2500 3rd Generation Intel Core Processors with Intel HD Graphics 2500
+        0153    Intel. Dynamic Platform and Thermal Framework Driv Use the Link, choose Win7 64Bit -> Others -> Intel DPTF Driver -> Global. Then download, install and
+        0154    0x01548086  3rd Gen Core processor DRAM Controller (rev 09)
+        0162    Core I5, Core I7, Ivy Bridge Graphics embedded
+        0166    I3 Intel(R) HD Graphics 4000
+        0189    Intel Centrino Wireless-N 1030 Bluetooth Adapter Intel Centrino Wireless Bluetooth 3.0 + High Speed Adapter
+        027AE   82945GM Mobile Intel(R) 945 Express Chipset Family
+        027D8   293esd High Definition Audio Controller
+        0283E   AA01211025 Intel(R) ICH8 Family SMBus Controller
+        0308    3220 PCI Audio Device + modem
+        0309    80303 I/O Processor PCI-to-PCI Bridge Unit
+        030D    80312 I/O Companion Unit PCI-to-PCI Bridge
+        0318    80219 General Purpose PCI Processor Address Translation Unit
+        0319    80219 General Purpose PCI Processor Address Translation Unit
+        0326    670xPXH I/OxAPIC Interrupt Controller
+        0327    6700PXH I/OxAPIC Interrupt Controller B
+        0329    6700PXH PCI Express-to-PCI Express Bridge A
+        032A    6700PXH PCI Express-to-PCI Express Bridge B
+        032C    6702PXH PCI Express-to-PCI Express Bridge
+        0330    80332 A-Segment Bridge
+        0331    80332 A-Segment IOAPIC
+        0332    80332 B-Segment Bridge
+        0333    80332 B-Segment IOAPIC
+        0334    80332 Address Translation Unit
+        0335    80331 PCI-X Bridge
+        0336    80331 Address Translation Unit (ATU)
+        0340    41210 Serial to Parallel PCI Bridge A
+        0341    41210 Serial to Parallel PCI Bridge B
+        0370    80333 Segment-A PCI Express-to-PCI Express Bridge
+        0371    80333 A-Bus IOAPIC
+        0372    0893 network controller
+        0373    80333 B-Bus IOAPIC
+        0374    80333 Address Translation Unit
+        0401    266E P040100
+        0402    ACPI x86-based PC HD Graphics 4200
+        0412    Intel HD Graphics 4600 ven_8086&dev_0412
+        0416    SUBSYS_197A103C Intel(R) HD Graphics 4600
+        0482    82375MB PCI\VEN_8086&DEV_3B64&SUBSYS_20391B0A&REV_06
+        0483    82424TX/ZX CPU (i486) Bridge (Saturn)
+        0484    82378ZB/IB SIO ISA Bridge
+        0486    PCI\VEN_8086&DEV_1C22&SUBSYS_2AC2103C&REV_04 HP Pro 3400  XPx32/7x32 drivers
+        04931028        0x1502 Intel 82579 Gigabit Network Card
+        04A3    82434bX/zX Mercury/Neptune Cache/DRAM Controller
+        0500    E8870 Processor Bus Controller
+        0501    E8870 Memory Controller
+        0502    E8870 Scalability Port 0
+        0503    E8870 Scalability Port 1 / Glob. Perf. Monitor
+        0510    E8870IO Hub Interface Port 0 (8-bit compatible)
+        0511    E8870IO Hub Interface Port 2
+        0512    E8870IO Hub Interface Port 2
+        0513    E8870IO Hub Interface Port 3
+        0514    E8870IO Hub Interface Port 4
+        0515    E8870IO Server I/O Hub (SIOH)
+        0516    E8870IO Reliabilty, Availability, Serviceability
+        0530    E8870SP Scalability Port 0
+        0531    E8870SP Scalability Port 1
+        0532    E8870SP Scalability Port 2
+        0533    E8870SP Scalability Port 3
+        0534    E8870SP Scalability Port 4
+        0535    E8870SP Scalability Port 5
+        0536    E8870SP Scalability Port Switch Global Registers
+        0537    E8870SP Interleave Configuration Registers
+        0600    1043 Storage RAID Controller
+        0780    3.0/2.0 Intel B75 Express Chipset
+        0800    10B01734 pci/ven_8086&dev_27da&subsys_30b2103c&rev_02\3&b1bfb68&0&fb
+        0885    612BNXHMW Intel Centrino Wireless-N + WiMAX 6150
+        0887    Intel Centrino Chipset Intel Centrino Wireless-N 2230
+        0888    Intel Centrino Wireless-N 2230
+        088E    40608086 Intel Centrino Advanced N 6235
+        0890    Intel Network Controller
+        0894    86881 Centrino Wireless-N 105
+        0896    Wireless-N 130 Intel Centrino Wireless-N 130
+        08AE    802.11n Intel Centrino Wireless-N 100
+        08B1    PCI\VEN_8086&DEV_08B1 Intel(R) Dual Band Wireless-AC 7260
+        08B3    ? Intel Dual Band Wireless-AC 3160
+        0960    80960RP i960 RP Microprocessor/Bridge
+        0962    80960RM/RN i960RM/RN Microprocessor/Bridge
+        0964    80960RP i960 RP Microprocessor Bridge
+        0A03    0A03 Intel(R) Dynamic Platform and Thermal Framework Processor Participant
+        0A04    0A04 PCI standard host CPU bridge
+        0A0C    0A0C High Definition Audio Controller
+        0A16    3000 Intel HD Graphics Controller
+        0A1E    0A1 Intel(R) HD Graphics
+        0BE1    0000000 Intel Graphics Media Accelerator 3600 Series
+        0C00    0C00 Intel(R) 4th Gen Core processor DRAM Controller
+        0C05    V9201015 Intel(R) 6 Series/C200 Series Chipset Family SMBus Controller
+        0F00    0F00 Intel(R) Pentium(R)/Celeron(R) processor N-/J- series SoC Transaction Router
+        0F04    0F04 High Definition Audio Controller
+        0F12    0F12 Intel(R) Pentium(R)/Celeron(R) processor N-/J- series Platform Control Unit - SMBus Port
+        0F18    0F18 Intel(R) Trusted Execution Engine Interface
+        0F1C    0F1C Intel(R) Pentium(R)/Celeron(R) processor N-/J- series Platform Conrol Unit LPC: Bridge to Intel Lega
+        0F23    0F23 Intel(R) Pentium(R)/Celeron(R) processor N-/J- series AHCI
+        0f31    5200 Iris pro 5200
+        0F35    0F35 Intel(R) USB 3.0 eXtensible Host Controller
+        0F48    0F48 Intel(R) Pentium(R)/Celeron(R) processor N-/J- series PCI Express Root Port
+        0F4A    0F4A Intel(R) Pentium(R)/Celeron(R) processor N-/J- series PCI Express Root Port
+        100     0100 2nd Generation Intel(R) Core(TM) Processor Family DRAM Controller
+        1000    82542 Gigabit Ethernet Controller
+        1001    2572 10/100/1000 Ethernet Controller (Fiber)
+        1002    Pro 100 LAN+Modem 56 CardBus II
+        1004    82543GC Gigabit Ethernet Controller (Copper)
+        1008    82544EI/GC Gigabit Ethernet Controller (Copper)
+        1009    82845G/GL/GV/GE/PE Integrated Graphics Device Intel
+        100C    82543EI/GC Gigabit Ethernet Controller (Copper)
+        100D    82544GC Gigabit Ethernet Controller (LOM)
+        100E    02000 Intel Pro 1000/MT
+        100F    82545EM Intel(R) PRO/1000 MT Network Connection
+        1010    82546EB Dual Port Gigabit Ethernet Controller (Copper)
+        1011    82545EM Gigabit Ethernet Controller (Fiber)
+        1012    82546EB Dual Port Gigabit Ethernet Controller (Fiber)
+        1013    82541EI Gigabit Ethernet Controller (Copper)
+        1014    82541ER Gigabit Ethernet Controller
+        1015    82540EM Gigabit Ethernet Controller (LOM)
+        1016    82540EP Gigabit Ethernet Controller (LOM)
+        1017    82540EP Gigabit Ethernet Controller (LOM)
+        1018    82541EI PRO/1000 MT Mobile connection
+        1019    82547EI Gigabit Ethernet Controller (LOM)
+        101A    82547EI Gigabit Ethernet Controller (LOM)
+        101d    82546EB Dual Port Gigabit Ethernet Controller
+        101E    82540EP Gigabit Ethernet Controller (Mobile)
+        1026    82545ep Gigabit Ethernet Controller
+        1027    82545GM Gigabit Ethernet Controller (Fiber)
+        1028    82545GM Gigabit Ethernet Controller
+        1029    82559 Fast Ethernet PCI/CardBus Controller
+        1030    82801 PCI Networking device
+        1031    82801CAM PRO/100 VE Network Connection
+        1032    82801CAM PRO/100 VE Network Connection
+        1033    PB 642365-003 multimedia video controller
+        1034    82801CAM PRO/100 VM Network Connection
+        1035    82562EH Phoneline Network Connection
+        1036    82562EH Phoneline Network Connection
+        1037    82801CAM LAN Controller
+        1038    82801CAM PRO/100 VM/KM Network Connection
+        1039    10011734  82562
+        103A    82801DB LAN Controller with 82562ET/EZ (CNR) PHY
+        103B    82801DB LAN Controller with 82562EM/EX PHY
+        103C    82801DB LAN Controller with 82562EM/EX (CNR) PHY
+        103D    05221014 PRO/100 VE Network Connection
+        103E    82801DB PRO/100 VM Network Connection
+        1040    536EP V.92 PCI (DSP) Data Fax Modema
+        1042    8086 PRO/Wireless 2011 LAN PCI Card
+        1043    82801 Intel(R) PRO/Wireless 2100 LAN Card Driver
+        1048    82597EX 10 Gigabit Ethernet Controller
+        1049    82566MM NIC Gigabit Network Connection Interface Controller
+        104A    Intel 82566DM Gigabit Ethernet gigabit ethernet
+        104B    82566DC Gigabit Ethernet
+        104D    82566MC Intel Gigabit 82566MC
+        1050    82562EZ PRO/100 VE Network Connection
+        1051    82801EB/ER PRO/100 VE Network Connection
+        1052    82801EB/ER PRO/100 VM Network Connection
+        1053    82801EB/ER PRO/100 VM ork NetConnectionw
+        1054    82801EB/ER PRO/100 VE Network Connection (mobile)
+        1055    82801EB/ER PRO/100 VM Network Connection (mobile)
+        1059    82551QM Fast Ethernet PCI/CardBus Controller
+        105E    82579V Intel(R) PRO/1000 PT Dual Port Server Adapter
+        1064    Intel Pro VE 82562EZ PLC
+        1065    82801FB/FR/FW/FRW LAN Controller Intel Corporation 82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller
+        1068    82562 1068h 82562ET/EZ/GT/GZ PRO/100 VE Ethernet Controller
+        1075    82547EI Gigabit Ethernet Controller
+        1076    82541EI Gigabit Ethernet Controller
+        1077    82547EI Gigabit Ethernet Controller (Mobile)
+        1078    82541ER Gigabit Ethernet Controller
+        1079    82546EB Dual Port Gigabit Ethernet Controller
+        107A    82546EB Dual Port Gigabit Ethernet Controller (Fiber)
+        107B    82546EB Dual Port Gigabit Ethernet Controller (Copper)
+        107C    82541PI Gigabit Ethernet Controller (Copper) rev 5
+        1080    0321CGEA04 FA82537EP - Intel 537EP V.92 (PCI)  modem
+        108B    PC82573V Intel network controller (PCIE Gigabit Ethernet)
+        108c    82573E Intel Corporation 82573E Gigabit Ethernet Controller (Copper)
+        108E    ICH7R Intel(R) Active Management Technology - KCS
+        108F    ICH7R Intel(R) Active Management Technology - SOL
+        1092    27DA PRO/100 VE Network Controller
+        1094    Onboard - Intel PRO 100/VE nic get PRO2KXP.exe from Intel
+        1096    Intel PRO/1000 EB Intel PRO/1000 EB
+        109A    82573L Intel PRO/1000 PL Network Adaptor
+        109c    e1qexpress HP E1Q Express
+        10a7    82575 ? 82575EB Gigabit Network Connection
+        10a9    82575 ? 82575EB Gigabit Backplane Connection
+        10b5    82546GB Quad Port Gigabit Ethernet Controller
+        10b9    82572GI Intel PRO/1000 PT Desktop
+        10BD    82566DM Intel 82566DM Gigabit Ethernet Adapter
+        10C0    8082 Intel(R) 82562V-2 10/100 Network Connection
+        10c4            82562GT Intel 82562GT 10/100 Network Controller
+        10c4    82562EZ PLC Intel 82562GT 10/100 Network Controller
+        10c9    82576? 82576 Gigabit ET Dual Port Server Adapter
+        10cd    82567 Intel(R) 82567LF-2 Gigabit Network Connection
+        10CE    82567V-2 Intel 82567V-2 Gigabit Network Connection
+        10d3    82574L Intel. 82574L Gigabit Ethernet Controller
+        10d6    82575 82566 DM-2-gigabyte
+        10DE    02761028 Intel Gigabit network connection
+        10e6    82576 ? 82576 Gigabit Network Connection
+        10e7    82576 ? 82576 Gigabit Network Connection
+        10E8    82576 E64750-xxx Intel Gigabit ET Quad Port Server Adapter
+        10EA    82577LM Intel 82577LM Gigabit LAN Controller
+        10EC    Realtek AC97Audio Realtek 171 High Definition Audio
+        10EF    Intel. 82578DM Gigabit Ethernet Controller Intel. 82578DM Gigabit Ethernet Controller
+        10F0    82578 Intel(R) 82578DC Gigabit NIC
+        10F5    82567LM Intel.  82567LM-2 Gigabit Network Connection
+        10fb    82599 10 Gb Ethernet controller
+        1100    82815/EP/P Host-Hub Interface Bridge / DRAM Ctrlr
+        1101    82815/EP/P AGP Bridge
+        1102    82915GV Internal Graphics Device
+        1110    82815 Host-Hub Interface Bridge / DRAM Ctrlr
+        1112    82815 Internal Graphics Device
+        1120    82815 Host-Hub Interface Bridge / DRAM Ctrlr
+        1121    82815 AGP Bridge
+        112D    2200 pci simple controller 
+        1130    82815/82815EM/EP Host-Hub Interface Bridge / DRAM Ctrlr
+        1131    82815/82815EM/EP AGP Bridge
+        1132    65416http://www.pcidatabase.com/update_device.php? Internal Graphics Device [810/815 chipset AGP]
+        1161    82806AA I/O APIC Device
+        1162    BECC XScale 80200 Companion Chip (FPGA)
+        1179    82546EB Dual Port Gigabit Ethernet Controller
+        12      03491025 00
+        1200    IXP1200 Network Processor
+        1209    8255xER/IT Fast Ethernet Controller for xp pc
+        1221    82092AA PCMCIA Bridge
+        1222    2792 IDE Ctrlr
+        1223    Conexant Cx20468 @ Intel 82801FB ICH6 - AC'97 Audi Audio Controller
+        1225    82452KX/GX Orion Extended Express CPU to PCI Bridge
+        1226    82596 EtherExpress PRO/10
+        1227    82801db ich4 LAN Controller with 82562EM
+        1228    EE PRO/100 Smart Intelligent 10/100 Fast Ethernet Adapter
+        1229    1e22 Intel(R) PRO/100 http://ftp.dell.com/network/R56484.EXE
+        122D    82437FX System Controller (TSC)
+        122E    82371AB/EB PCI PCI to ISA Bridge (Triton)
+        1230    FW82371AB IDE Interface (Triton)
+        1231    16345 DSVD Modem
+        1234    82371MX PCI to ISA Bridge
+        1235    82439TX Mobile System Controller (MTSC)
+        1237    82440LX/EX PCI & Memory
+        1239    82371FB IDE Interface (Triton)
+        123B    82380PB PCI to PCI Docking Bridge
+        123C    82380AB Mobile PCI-to-ISA Bridge (MISA)
+        123D    683053 Programmable Interrupt Device
+        123E    82466GX Integrated Hot-Plug Controller (IHPC)
+        123F    82466GX Integrated Hot-Plug Controller (IHPC)
+        124     PCI\VEN_8086&DEV_9C22 24c6
+        1240    82752 AGP Graphics Accelerator
+        124B            293esd Mobile PCI-to-PCIsdsdsdI2)
+        124B    PCI\VEN_8086&DEV_2E17&CC_070002 24c6
+        124C    9776 Mobile PCI-to-PCI Bridge (MPCI2)
+        1250    82430HX System Controller (TXC)
+        12D8    92XX SIGMATEL STAC 92XX C-Major HD Audio
+        1360    82806AA Hub Interface to PCI Bridge
+        1361    82806AA Advanced Interrupt Controller
+        13ca    VVVV VVVVVV
+        1460    82870P2 Hub Interface-to-PCI Bridge
+        1461    14611014 I/OxAPIC Interrupt Controller
+        1462    82870P2 Hot Plug Controller
+        1502    0x04931028 Intel 82579LM Gigabit Network Card
+        1503    Intel 82579v Gigabit Network Connection
+        150a    82576 ? 82576NS Gigabit Ethernet Controller
+        150C    82583V Intel. 82583V Gigabit Ethernet  Controller
+        150d    82576 ? 82576 Gigabit Backplane Connection
+        150e    82580 ? 82580 Gigabit Network Connection
+        150f    82580 ? 82580 Gigabit Fiber Network Connection
+        1510    82580 ? 82580 Gigabit Backplane Connection
+        1511    82580 ? 82580 Gigabit SFP Connection
+        1516    82580 ? 82580 Gigabit Network Connection
+        1518    82576 ? 82576NS SerDes Gigabit Network Connection
+        1521    I350 i350 Gigabit Network Connection
+        1525    82567V-4 Intel 82567V-4 Gigabit Network Connection
+        1526    82576 Intel Gigabit ET2 Quad Port Server Adapter
+        1533    210 Intel I210 Gigabit Network Connection
+        153A    USB\VID_0424&PID_2504&REV_0001 Intel I217-LM Ethernet Connection
+        153B    I217-V Intel Gigabit Ethernet Controller I217-V
+        1559    0x8CBA Intel Ethernet I218-V
+        155a    I218LM Gigabit Ethernet
+        15A1    0x8CBA Intel. Ethernet Connection I218-V
+        15A2    I218LM Gigabit Ethernet
+        167D    2200bg PCI Simple Communications Controller
+        1960    80960RP i960RP Microprocessor
+        1962    ??? Promise SuperTrak SX6000 IDE RAID Controller
+        1A12    ??? Eicon DIVA Server Voice PRI 2.0 (PCI)
+        1A13    ??? Eicon DIVA Server Voice PRI 2.0 (PCI)
+        1A20    82840 
+        1A21    82840 Host-Hub Interface A Bridge / DRAM Ctrlr
+        1A22    82840 Host to I/O Hub Bridge (Quad PCI)
+        1A23    82840 AGP Bridge
+        1A24    82840 Hub Interface B Bridge
+        1A30    82845G[GL/GV/GE/PE] Host-Hub Interface Bridge
+        1A31    82845[MP/MZ] AGP Bridge
+        1A38    5000P 5000 Series Chipset DMA Engine
+        1A3E    Z77 C216 Chipset - Platform controller hub
+        1c02    1C02 Intel(R) 6/C200 Series Chipset Family 6 Port SATA AHCI Controller
+        1c02_   8086&dev_1c02 Intel(R) Desktop/Workstation/Server Express Chipset SATA AHCI Controller
+        1C03    Intel(R) Mobile Express Chipset SATA AHCI Controll Intel(R) CPT Chipset Family 6 Port SATA AHCI Controller 
+        1C10    1C10 Intel(R) 6/C200 Series Chipset Family PCI Express Root Port
+        1C18    1C18 Intel(R) 6/C200 Series Chipset Family PCI Express Root Port
+        1C1A    1C3Afsfsdf 1C3Asfsfsdf
+        1C1C    1C1C Intel(R) 6/C200 Series Chipset Family PCI Express Root Port
+        1C1E    1C1E Intel(R) 6/C200 Series Chipset Family PCI Express Root Port
+        1C20    1C20 High Definition Audio Controller
+        1C22    win7 64-bit  Intel(R) 6 Series/C200 Series Chipset Family SMBus Controller
+        1C26    HM65 Intel(R) 6/C200 Series Chipset Family USB Enhanced Host Controller
+        1C2D    1C2D Intel(R) 6/C200 Series Chipset Family USB Enhanced Host Controller
+        1c34a   0780 pci simple communications controller
+        1c3a    161C103C Intel Management Engine Interface
+        1c3a.   161C103C Intel Management Engine Interface
+        1C3b    111 Series Chipset Family HECI Controller #2
+        1C3D    Intel(R) 6 Series Series Chipset Family Intel(R) Active Management Technology - SOL
+        1C49    FCD01179 04
+        1C4C    Q65 Intel(R) Q65 Express Chipset Family LPC Interface Controller
+        1D3A    X79 series chipset HECI Controller X79/C600 series chipset Management Engine Interface
+        1D3D    CC0700 Intel Active Management Technology AMT
+        1e00    Intel H77 Express Chipset 2 ports IDE Controller
+        1e02    SUBSYS_102E17AA&REV_04 Intel 7 Series/C216 Chipset Family SATA AHCI Controller
+        1E03    PCI\CC_010601 Intel(R) 7 Series Chipset Family SATA AHCI Controller
+        1e08    Intel H77 Express Chipset 2 ports IDE Controller
+        1E10    C216 Intel(R) 7 Series/C216 Chipset Family PCI Express Root Port
+        1E12    1E12 Intel(R) 7 Series/C216 Chipset Family PCI Express Root Port
+        1E16    C216 Intel(R) 7 Series/C216 Chipset Family PCI Express Root Port
+        1E20    1E20 High Definition Audio Controller
+        1E22    Intel(R) 7 SeriesC216 Chipset Family SMBus Host Co SM-Bus Controller of the Intel Z77 Chipset
+        1E26    C216 Intel(R) 7 Series/C216 Chipset Family USB Enhanced Host Controller
+        1E2D    C216 Intel(R) 7 Series/C216 Chipset Family USB Enhanced Host Controller
+        1e31    Intel USB 3.0 eXtensible Host Controller 1E31 Intel USB 3.0
+        1E3A    PCI\VEN_8086&DEV_1E3A&SUBSYS Intel Management Engine Interface (MEI)
+        1E3A_   C216 8555555555555999999999999999999999999999999999999999999999999999999900000000000000000001222222222222
+        1E3A__  Z77 C216 Chipset - Platform controller hub
+        1E3D    602317 Intel(R) AMT LMS_SOL for AMT 8.xx
+        1E59    140889 Intel(R) HM76 Express Chipset LPC Controller
+        1f41    Avoton SoC Intel Corporation Ethernet Connection I354
+        2000    CA 95054 505943621
+        2014    0x18C9 Framegrabber
+        2048    Atheros L2 Fast Ethernet 10/100 Base-T Controller
+        2124    27DA PRO/100 VE Network Connection
+        2125    82801G  AC97 Audio Controller. website to download - http://www.intel.com/design/chipsets/manuals/29802801.p
+        2222    82801 Intel Management Interface
+        2250    5110P Intel(R) Xeon Phi(TM) Coprocessor
+        2255    810D1043 02\3
+        225C    SE10 Intel(R) Xeon Phi(TM) Coprocessor
+        225D    3120 Intel(R) Xeon Phi(TM) Coprocessor
+        225E    31S1P Intel(R) Xeon Phi(TM) Coprocessor
+        2406    82801 / ? AC97 Modem Controller / PCI Modem
+        2410    82801AA LPC Interface
+        2411    82801AA IDE Controller (UltraATA/66)
+        2412    82801AA USB Controller
+        2413    82801AA SMBus Controller
+        2415    Intel 82801DBM SM/BUS Controller 24C3 Aureal (AD1881 SOUNDMAX) Placa Mpie Asaki P3-141
+        2416    82801ER AC'97 Modem Controller
+        2418    82801AA Hub Interface-to-PCI Bridge    82801 PCI-2448 0x2448
+        2420    82801AB LPC Interface
+        2421    82801AB IDE Controller (UltraATA/33)
+        2422    82801AB USB Controller
+        2423    82801AB SMBus Controller
+        2425    82801BA Audio controler
+        2426    82801AB AC97 Modem Controller
+        2428    82801AB Hub Interface-to-PCI Bridge
+        2431    82810 pci bus
+        2440    82801BA/BAM AC'97 LPC Interface Bridge, ICH2
+        2441    82801BA IDE Controller (UltraATA/66)
+        2442    82801BA/BAM USB Controller, USB-A
+        2443    82801BA/BAM SMBus Controller
+        2444    82801BA/BAM USB Controller, USB-B
+        2445    Intel i945G/GZ AC97 Audio Controller
+        2446    82801BA/BAM AC97 Modem Controller
+        2448    82801BAM/CAM/DBM Hub Interface to PCI Bridge
+        2449    82559ER 82559ER Integrated 10Base-T/100Base-TX Ethernet Controller
+        244A    82801BAM IDE Controller
+        244B    82801BA IDE Controller
+        244C    82801BAM LPC Interface Bridge
+        244E    82801DB Intel(R) 82801 PCI Bridge
+        2450    82801E LPC Interface Bridge
+        2452    82801E USB Controller
+        2453    82801E SMBus Controller
+        2459    82801E LAN0 Controller
+        245B    82801E IDE Controller
+        245D    82801E Multimedia Audio Controller
+        245E    82801E Hub Interface to PCI Bridge
+        2480    82801CA LPC Interface Bridge
+        2481    82801CA IDE Controller (UltraATA/66)
+        2482    82801CA/CAM USB Controller
+        2483    82801CA/CAM SMBus Controller
+        2484    82801CA/CAM USB Controller
+        2485    82801CA/CAM AC97 Audio Controller
+        2486    82801CA/CAM AC 97 Modem Controller
+        2487    82801CA/CAM USB Controller
+        248A    82801CAM UltraATA IDE Controller
+        248B    82801CA UltraATA/100 IDE Controller
+        248C    82801CAM LPC Interface or ISA bridge: see Notes
+        248D    82801?? USB 2.0 EHCI Contoroller
+        24C0    82801DB/DBL LPC Interface Bridge
+        24C2    82801DB/DBL/DBM USB UHCI Controller #1
+        24C3    82801DB/DBL/DBM modem
+        24C4    82801DB/DBL/DBM USB UHCI Controller
+        24C5    82801DBM SoundMAXController (ICH4-M B0 step) Realtek AC97
+        24C5&SUBSYS_041111      2200bg PCI Simple Communications Controller
+        24C5a   82801DBM SoundMAXController  VIA Vynil v700b
+        24c5j   SUBSYS_21179 Soundmax Integrated Digital Audio
+        24C5n   82801DBM SoundMAXController (ICH4-M B0 step) Intel 82801 DB DBM/DA AC 97 Audio Controller
+        24c5x   C-Media AC97 Audio Device Audio Controller
+        24C6    82801 /8086 AC97 Modem Controller / PCI Modem
+        24C7    82801DB/DBL/DBM USB UHCI Controller #3
+        24CA    82801DBM IDE Controller (UltraATA/100)
+        24CB    82801DB/DBL IDE Controller (UltraATA/100)
+        24CC    82801DBM LPC Interface Bridge
+        24CD    82801DB/DBL/DBM USB EHCI Controller
+        24D0    82801EB/ER LPC Interface Bridge
+        24D1    82801EB/ER SATA Controller
+        24D2    82801EB/ER USB UHCI Controller 1
+        24D3    82801EB/ER SMBus Controller
+        24D4    82801EB/ER USB UHCI Controller #2
+        24D5    AD1888/AD1980 Analog Devices AD1888/AD1980 @ Intel 82801EB ICH5 - AC'97 Audio Controller [A-2/A-3]
+        24D6    82801EB/ER Motorola SM56 Data Fax Modem
+        24D7    82801EB/ER USB UHCI Controller #3
+        24DB    82801EB/ER EIDE Controller
+        24DC    82801EB LPC Interface Controller
+        24DD    82801EB/ER USB EHCI Controller
+        24DE    82801EB/ER USB UHCI Controller #4
+        24DF    82801ER SATA Controller (RAID)
+        24E4    24e4 intel 
+        2500    82820 Host-Hub Interface Bridge / DRAM Ctrlr
+        2501    82820 Host Bridge (MCH)
+        2502    82820 
+        2503    82820 
+        2504    82820 
+        250B    82820 Host Bridge (MCH)
+        250F    82820 AGP Bridge
+        2520    82805AA Memory Translator Hub (MTH)
+        2521    8280 Audio Device on High Definition Audio Bus
+        2530    82850/E Host-Hub Interface Bridge(A2 step)
+        2531    82860 Host-Hub Interface_A Bridge (DP mode)
+        2532    82850/850E/860 AGP Bridge
+        2533    82860 Hub Interface_B Bridge
+        2534    82860 Hub Interface_C Bridge
+        2535    82860 PCI Bridge
+        2536    82860 PCI Bridge
+        2539    82860 (Quad Processor mode)
+        2540    E7500 Host-HI Bridge & DRAM Controller
+        2541    E7500/E7501 DRAM Controller Error Reporting
+        2543    E7500/E7501 HI_B Virtual PCI-to-PCI Bridge
+        2544    E7500/E7501 HI_B PCI-to-PCI Bridge Error Reporting
+        2545    E7500/E7501 HI_C Virtual PCI-to-PCI Bridge
+        2546    E7500/E7501 HI_C PCI-to-PCI Bridge Error Reporting
+        2547    E7500/E7501 HI_D Virtual PCI-to-PCI Bridge
+        2548    E7500/E7501 HI_D PCI-to-PCI Bridge Error Reporting
+        254C    E7501 Host Controller
+        2550    E7505 Host Controller
+        2551    25511014 Host RAS Controller
+        2552    E7205/E7505 PCI-to-AGP Bridge
+        2553    E7505 Hub Interface_B PCI-to-PCI Bridge
+        2554    E7505 Hub I/F_B PCI-to-PCI Bridge Error Report
+        255d    E7205 Host Controller
+        2560    82845G/GL/GV/GE/PE DRAM Controller / Host-Hub I/F Bridge
+        2561    82845G/GL/GV/GE/PE Host-to-AGP Bridge
+        2562    82845G Integrated Graphics Device
+        2562@cc 82801FR SATA RAID CONTROLLER
+        2570    82865G/PE/P, 82848P DRAM Controller / Host-Hub Interface
+        2571    82865G/PE/P, 82848P PCI-to-AGP Bridge
+        2572    intel d865glc Integrated Graphics Device
+        2573    82865G/PE/P, 82848P PCI-to-CSA Bridge
+        2576    82865G/PE/P, 82848P Overflow Configuration
+        2578    82875P/E7210 DRAM Controller / Host-Hub Interface
+        2579    82875P PCI-to-AGP Bridge
+        257A    
+        257B    82875P/E7210 PCI to CSA Bridge
+        257E    82875P/E7210 Overflow Configuration
+        2580    915G/P/GV Host Bridge / DRAM Controller
+        2581    915G/P/GV, 925X/XE? Host-PCI Express Bridge
+        2582    142550 82915g/gv/910gl Express Chipset Family
+        2582.   82915g/gv/910gl Express Chipset Family 82915g/gv/910gl Express Chipset Family
+        2584    82925X/XE Host Bridge / DRAM Controller
+        2585    
+        2588    E7221 Host Bridge/DRAM Controller
+        2589    E7221 PCI Express Bridge
+        258A    E7221 Internal Graphics
+        2590    915GM Mobile Intel(R) 915GM/PM/GMS/910GML Express Processor to DRAM Controller
+        2592    Intel 82852/82855  Graphic controller family
+        25A1    6300ESB LPC Interface Bridge
+        25A2    6300ESB PATA100 IDE Controller
+        25A3    6300ESB SATA Controller(IDE Mode)
+        25A4    6300ESB SMBus Controller
+        25A6    6300ESB AC'97 Audio Controller
+        25A7    6300ESB AC'97 Modem Controller
+        25A9    6300ESB USB 1.1 UHCI Controller #1
+        25AA    6300ESB USB 1.1 UHCI Controller #2
+        25AB    6300ESB Watchdog Timer
+        25AC    6300ESB APIC1
+        25AD    6300ESB USB 2.0 EHCI Controller
+        25AE    6300ESB Hub Interface to PCI-X Bridge
+        25B0    6300ESB Serial ATA Controller (RAID mode)
+        2600    E8500 Hub Interface 1.5
+        2601    E8500 PCI Express Port D
+        2602    E8500 PCI Express Port C0
+        2603    E8500 PCI Express Port C1
+        2604    E8500 PCI Express Port B0
+        2605    E8500 PCI Express Port B1
+        2606    E8500 PCI Express Port A0
+        2607    E8500 PCI Express Port A1
+        2640    82801FB/FR LPC Interface Bridge
+        2641    82801FBM LPC Interface Bridge (ICH6-M)
+        2651    82801Fb SATA Controller
+        2652    82801FR SATA RAID Controller
+        2652&CC_0101    82801FR/FRW SATA Controller
+        2652&CC_0104    82801FR/FRW SATA Raid Controller
+        2652&CC_0106    82801FR/FRW AHCI Controller
+        2653    82801FBM SATA AHCI Controller
+        2653&CC_0101    82801FBM SATA IDE Controller
+        2653&CC_0106    82801FBM AHCI Controller
+        2658    82801FB/FR/FW/FRW USB UHCI Controller #1
+        2659    82801FB/FR/FW/FRW USB UHCI Controller #2
+        265A    82801FB/FR/FW/FRW USB UHCI Controller #3
+        265B    82801FB/FR/FW/FRW USB UHCI Controller #4
+        265C    82801FB/FR/FW/FRW USB 2.0 EHCI Controller
+        266     VIA Technologies Vinyl AC'97 Codec Combo Driver (W VIA AC97 codec incorporated into VT82C686VT8251 SouthbridA/B, VT8231, VT8233/A/C, VT8235, VT8237/R
+        2660    82801FB/FR/FW/FRW PCI Express Port 1
+        2662    82801FB/FR/FW/FRW PCI Express Port 2
+        2664    82801FB PCI Express Port 3
+        2666    82801FB/FR/FW/FRW PCI Express Port 4
+        2668    11511583659 82801FB (ICH6) High Definition Audio Controller
+        2669    2028026 jkn 
+        266A    82801BA/CA SMBus Controller
+        266C    82801FB/FR/FW/FRW LAN Controller
+        266D    czc82809kr http://www.dell.com/support/drivers/us/en/19/DriverDetails/DriverFileFormats?DriverId=R104087&FileId
+        266E    Driver audio digitale integrato ADI SoundMAX Driver audio digitale integrato ADI SoundMAX - HP DV4000
+        266F    82801FB/FBM/FW/FR/FRW PATA100 Controller - 266F
+        2670    631xESB/6321ESB/3100  LPC Interface Controller
+        2678    8280 8280 (ICH6) High Defininition Audio Controller
+        2680    631x/632x ESB2&3100 SATA Controller(IDE Mode)
+        2681    62089A2 631xESB/632xESB SATA AHCI Controller
+        2682    ESB2 Intel(R) ESB2 SATA RAID Controller
+        269B    631xESB/6321ESB/3100 SMBus Controller
+        269E    631x/632x ESB2 PATA100 IDE Controller
+        27      82801G  ICH7 Family
+        2770    82945G/GZ/P/PL Intel(R) 945G/GZ/GC/P/PL Processor to I/O Controller
+        2771    82945G/GZ/P/PL Host to PCI Express Bridge
+        2772    82945G/GZ PCI\VEN_8086&DEV_2772&SUBSYS_2A57103C&REV_02\3&11583659&0&10
+        2776    82945G INTEL(R) 82945G EXPRESS FAMILY
+        277C    82975X Intel 975X Express Chipset
+        2780    82915G Graphics device
+        2782    82915G Graphics device: 82915G/GV/910GL Express Chipset Family
+        2792    038000 Mobile Intel(R) 915GM/GMS/, 910GML Express Chipset Family
+        2794    945 Mobile chipset
+        27A0    874079 Mobile Intel(R) 945GM/GU/PM/GMS/940GML/943GML and Intel(R) 945GT Express Processor to DRAM Controlle
+        27A1    Intel 82945PM Memory Controller Intel Corporation Mobile 945PM Express PCI Express Root Port
+        27A2    HPQ0006 Mobile Intel(R) 945 Express Chipset Family
+        27A6    945GM Intel 945GM/950
+        27B8    945GL Intel(R) ICH7 Family LPC Interface Controller
+        27B9    ICH7 Intel(R) ICH7M/U LPC Interface Controller
+        27BC    NM10 NM10 Family LPC Interface Controller
+        27c0    82801GB/GR/GH Intel(R) N10/ICH7 Family Serial ATA Storage Controller
+        27C1    82801GB/GR/GH AHCI Controller
+        27c3    82801GR/GH Raid Controller
+        27c4    82801GBM/GHM SATA IDE Controller
+        27C5    82801GBM/GHM Intel(R) ICH7/M/MDH SATA AHCI Controller
+        27C6    82801GHM Raid Controller
+        27c8    946 Intel(R) N10/ICH7 Family USB Universal Host Controller
+        27c9    USB UHCI Controller Intel(R) N10/ICH7 Family USB Universal Host Controller
+        27CA    ICH7 Intel(R) N10/ICH7 Family USB Universal Host Controller
+        27CB    ICH7 Intel(R) N10/ICH7 Family USB Universal Host Controller
+        27CC    82801G Intel(R) N10/ICH7 Family USB2 Enhanced Host Controller
+        27D0    82801G Intel(R) 82801G (ICH7 Family) PCI Express Root Port
+        27D2    82801G Intel(R) 82801G (ICH7 Family) PCI Express Root Port
+        27D4    ICH7 Intel(R) N10/ICH7 Family PCI Express Root Port
+        27d8    27D8 UAA Bus Driver for HD Audio
+        27d8xzx PCI\VEN_8086&DEV_2485&SUBSYS_AD021458&REV_02 Microsoft UAA Bus HD Audio
+        27D9    A62516F3 IDT High Definition Audio Driver       
+        27DA    82801G Intel(R) N10/ICH7 Family SMBus Controller
+        27DC    336C1462 Intel. PRO/100 VE Desktop Adapter
+        27DC0x27DC      336C1462 Intel. PRO/100 VE Desktop Adapter
+        27DE    RTL8100C AUDIO (ALC850) << Realtek 
+        27df    82801GB/GBM Intel(R) ICH7 Family Ultra ATA Storage Controller
+        27RR    ALC850 no
+        2802    8086 INTEL(R) HIGH DEFINITION AUDIO HDMI
+        2803    0111 Intel(R) High Definition Audio HDMI Service
+        2804    80860101 IntcDAudModel
+        2807    Intel HD Audio Intel HDMI Audio Chip
+        2812    2812 Intel(R) ICH8DH LPC Interface Controller
+        2815    902D104D Intel(R) ICH8M LPC Interface Controller - 2815 Driver
+        2820    82801HB/HR/HH/HO SATA IDE Controller:4 port
+        2821    82821HR/HH/HO AHCI Controller
+        2822    82801HR/HH/HO&82801IR/IH/IO(AIE=0)/ICH10R Raid Controller
+        2824    82801HB ICH8 AHCI Controller
+        2825    82801IIH Intel Q35
+        2828    82801HBM/HEM SATA IDE Controller
+        2829    82801HBM Intel(R) ICH8M SATA AHCI Controller
+        282A    ICH8M/9M/ICH10M/i5M Raid Controller
+        2830    2830 Intel(R) ICH8 Family USB Universal Host Controller
+        2831    2831 Intel(R) ICH8 Family USB Universal Host Controller
+        2832    2832 Intel(R) ICH8 Family USB Universal Host Controller
+        2834    2834 Intel(R) ICH8 Family USB Universal Host Controller
+        2835    2835 Intel(R) ICH8 Family USB Universal Host Controller
+        2836    2836 Intel(R) ICH8 Family USB2 Enhanced Host Controller
+        283A    81EC1043 (?) ICH8 Family USB2 Enhanced Host Controller
+        283E    PCI\VEN_8086&DEV_283E&SUBSYS_20A917AA&REV_03\3&B1B Intel(R) ICH8 Family SMBus Controller
+        283F    283F Intel(R) ICH8 Family PCI Express Root Port
+        284     888 Microsoft UAA bus for HD audio
+        2841    ICH8 Intel(R) ICH8 Family PCI Express Root Port
+        2843    ICH8 Intel(R) ICH8 Family PCI Express Root Port
+        2845    ICH8 Intel(R) ICH8 Family PCI Express Root Port
+        2847    2847 Intel(R) ICH8 Family PCI Express Root Port
+        284B    888 Microsoft UAA bus for HD audio
+        2850    82801HBM/HEM Intel(R) ICH8M Ultra ATA Storage Controller
+        2880    0000000 Intel Display Audio
+        2888    Q945 Q945
+        2914    ICH9D0 LPC bridge of ICH9
+        2916    3 PCI Simple Communications-Controller 
+        2918    ATK0110 driver for WindowsXP/Vista/Win7 32&64-bit http://dlcdnet.asus.com/pub/ASUS/misc/utils/MB_WIN7_ATK.ZIP
+        2919    ICH9M Intel(R) ICH9M/M-E Family 4 Port SATA AHCI Controller
+        2920    82801(IB)/IR/IH/IO SATA IDE Controller:4 port
+        2921    82801IR/IH/IO SATA IDE Controller:2 port1
+        2922    82801IR/IH/IO AHCI Controller
+        2923    82801IB ICH9 AHCI Controller
+        2925    82801IR/IH/IO(AIE=1) Raid Controller
+        2926    82801IR/IH/IO SATA IDE Controller:2 port2
+        2928    ?(ICH9M Family) SATA IDE Controller:2port1
+        2929    ICH9M/ME ICH9M/ME AHCI Controller
+        292D    ?(ICH9M Family) SATA IDE Controller:2port2
+        292E    ?(ICH9M Family) SATA IDE Controller:1port2
+        2930            8086 2930
+        2930    Intel ICH9 Family SMBus Controller Intel ICH9 Family SMBus Controller
+        2932    ICH9 Intel(R) ICH9 Family Thermal Subsystem
+        2934    ICH9 Intel(R) ICH9 Family USB Universal Host Controller
+        2935    ICH9 Intel(R) ICH9 Family USB Universal Host Controller
+        2936    0x02141028 Intel(R) ICH9 Family USB Univeral Host Controller
+        2937    ICH9 Intel(R) ICH9 Family USB Universal Host Controller
+        2938    ICH9 Intel(R) ICH9 Family USB Universal Host Controller
+        2939    ICH9 Intel(R) ICH9 Family USB Universal Host Controller
+        293A    ICH9 Intel(R) ICH9 Family USB2 Enhanced Host Controller
+        293C    ICH9 Intel(R) ICH9 Family USB2 Enhanced Host Controller
+        293E            486486  82801IB/IR/IH (ICH9 Family) HD Audio Controller
+        293E    486486 82801IB/IR/IH (ICH9 Family) HD Audio Controller
+        2940    ICH9 Intel(R) ICH9 Family PCI Express Root Port
+        2942    ICH9 Intel(R) ICH9 Family PCI Express Root Port
+        2944    ICH9 Intel(R) ICH9 Family PCI Express Root Port
+        2948    ICH9 Intel(R) ICH9 Family PCI Express Root Port
+        294C    82566DC-2 Intel(R) 82566DC-2 Gigabit Network Connection
+        2972    82946GZ  Onboard Video Device for 82946GZ chips
+        2986    265452 Intel
+        2987    Q965/Q963 Intel PCI Serial Port
+        2992    Q965/Q963 Intel(R) Express Chipset video
+        2993    G965 Intel(R) Express Chipset Dell Version
+        2994    2802103C Intel Management Engine Interface (HECI)
+        2996    Q963/Q965 IDE Controller
+        2997    Q965/Q963 PCI Serial Port
+        29a0    ?(82P965) Intel P965/G965 Processor to I/O Controller
+        29a1    ?(82Q965, 82G965, 82P965) Intel P965/G965 PCI Express Root Port
+        29A2    Intel 82G965 Graphics and Memory Controller Hub (G Intel 82G965 Graphics and Memory Controller Hub (GMCH)
+        29A4    86881 
+        29A6    G965 IDE Controller
+        29B2    Q35 Intel(R) Q35 Express Chipset Family
+        29B3    Q35 Intel Graphics
+        29B4    Q35-Chipset Intel. ME: Management Engine
+        29B4&subys      4F4A8086&rev_02 Management Engine Driver
+        29B6    Q35 IDE Controller
+        29B7    Q35-Chipset Serial Over LAN
+        29C2    8086 Intel(R) G33 chipset GMA3100 video Driver
+        29C2_   Intel G33 Intel(R) G33 chipset GMA3100 video Driver
+        29C4    Intel DG33BU Intel ME: Management Engine Interface
+        29C6    G3x IDE Controller
+        29D4    281e103c Intel Management Interface
+        29D6    Q33 IDE Controller
+        29E6    x48 IDE Controller
+        29F6    32xx IDE Controller
+        2A00    PM965 Mobile Intel(R) PM965/GM965/GL960/GS965 Express Processor to DRAM Controller
+        2A02    88B31033 Intel GM965, Intel X3100
+        2A03    82Q965 Mobile Intel(R) 965 Express Chipset Family
+        2A04    Q965/Q96 Intel PCI communication controller-Intel Management Engine Interface update
+        2A06    965PM IDE Controller
+        2A07    Q965/Q963 Intel PCI Serial Port
+        2A08    Q965 Chipset Intel(R) Extended Thermal Model MCH
+        2A12    965 Mobile Intel(R) 965 Express Chipset Family
+        2A16    96xMG IDE Controller
+        2A40    2A40 Mobile Intel(R) 4 Series Chipset Processor to DRAM Controller
+        2A42    Mobile Intel 4 Series Chipset Family Intel Mobile Graphic
+        2A43    Mobile Intel 4 Series Chipset Family Intel Mobile Graphic
+        2A44    Mobile 4 Series Chipset IC658
+        2A46    M4x IDE Controller
+        2a47    20EC17AA Active Management Technology - SOL
+        2A52    Cantiga IDE Controller
+        2C62    2C62 QuickPath Architecture Generic Non-core Registers
+        2D01    2D01 QuickPath Architecture System Address Decoder
+        2D10    2D10 QPI Link
+        2D11    2D11 QPI Physical
+        2E06    4x IDE Controller
+        2E12    - Intel Q45/Q43 Express Chipset
+        2e13    Intel Q43/Q45/G43/G45 (Eaglelake) Graphics Control Intel(R) 4 Series Internal Chipset
+        2E14    PCI\VEN_8086&DEV_2E14 Intel Management Engine Interface (HECI)
+        2E15    PCI\VEN_8086&DEV_29C2&SUBSYS_29C28086&REV_10\3&115 Intel AMT LMS_SOL for AMT 5.xx
+        2E16    4x IDE Controller
+        2E17    3646103C Intel AMT LMS_SOL for AMT 5.xx
+        2E24    pci\VEN 8086&DEV_3B64&subsys _ 76361462&rev _06 pci simple communications controller
+        2E24&CC PCI\VEN_8086 Intel Management Engine Interface
+        2E26    4x IDE Controller
+        2e29    2e29 Intel(R) 4 Series Chipset PCI Express Root Port - 2E29
+        2E30    2E30 Intel(R) 4 Series Chipset Processor to I/O Controller
+        2E32    PCI\VEN_8086&DEV_2E32&SUBSYS_31031565&REV_03 Intel G41 express graphics
+        2E33    G41TY EXPRESS CHIPSET ghaphics chipset g41TY
+        2E33_   G41 EXPRESS CHIPSET ghaphics chipset g41 ghaphics chipset g41 
+        2E46    4x IDE Controller
+        2E96    4x IDE Controller
+        2f00    815B104D multimedia audio device (codec AC97) SoundMAX or VIA
+        3092    SRCU32 I2O 1.5 RAID Controller
+        3200    31244 PCI-X to Serial ATA Controller
+        3252351341324   2802103 SUBSYS
+        3340    82855PM Host-Hub Interface Bridge
+        3341    82855PM AGP Bridge
+        3342    82855PM Power Management
+        3400    3400 Intel(R) 5520/5500/X58 I/O Hub to ESI Port
+        3408    7500 Intel(R) 7500/5520/5500/X58 I/O Hub PCI Express Root Port
+        3409    7500 Intel 7500 Chipset PCIe Root Port
+        340A    7500 Intel(R) 7500/5520/5500/X58 I/O Hub PCI Express Root Port
+        340B    7500 Intel 7500 Chipset PCIe Root Port
+        340C    7500 Intel 7500 Chipset PCIe Root Port
+        340E    7500 Intel(R) 7500/5520/5500/X58 I/O Hub PCI Express Root Port
+        3410    7500 Intel 7500 Chipset PCIe Root Port
+        3422    3422 Intel(R) 7500/5520/5500/X58 I/O Hub GPIO and Scratch Pad Registers
+        3423    The Intel. Server RAID Controller U2-1 (SRCU21) an SRCU21/SRCU31 Microsoft Windows* 2000 Memory Management Files
+        342E    7500 Intel(R) 7500/5520/5500/X58 I/O Hub System Management Registers
+        3438    7500 Intel(R) 7500/5520/5500/X58 I/O Hub Throttle Registers
+        3463    PCI\VEN_14E4&DEV_1692&SUBSYS_04831025&REV_01 NTPNP_PCI0002
+        3464    22 NTPNP_PCI0002
+        3465    PCI\VEN_14E4&DEV_1692&SUBSYS_04831025&REV_01 NTPNP_PCI0002
+        348D    82541EI Gigabit Ethernet Controller
+        34c5    82801DBM SoundMAXController (ICH4-M B0 step) Realtek AC97 (NOT an intel)
+        3575    82830[MP] Host-Hub I/F Bridge / SDRAM Controller
+        3576    82830M/MP Host-AGP Bridge
+        3577    82830vm Integrated Graphics Device
+        3578    82830[MP] CPU to I/O Bridge
+        3579    82835 SDRAM Controller / Host-hub Interface
+        357B    82835 Integrated Graphics Device
+        3580    852GM/GMV Host-Hub Interface Bridge
+        3581    82852GME/PM Virtual PCI to AGP Bridge
+        3582    852GM/GMV or 82852/82855 GM/GME Integrated Graphics Device
+        3584    852GM/GMV System Memory Controller
+        3585    852GM Configuration Process
+        3590    E7520 Memory Controller Hub
+        3591    E7520 Memory Controller Hub
+        3592    E7320 Memory Controller Hub
+        3593    E7320 MCH Error Reporting Registers
+        3594    E7520 DMA Controller Registers
+        3595    E7525 PCI Express Port A
+        3596    E7525 PCI Express Port B
+        3597    E7525 PCI Express Port B
+        3598    E7520 PCI Express Port B1
+        3599    E7520 PCI Express Port C
+        359A    E7520 PCI Express Port C1
+        359B    E7525 Extended Configuration Registers
+        359E    E7525 MCH Control Registers
+        360B    PCI\VEN_8086&DEV_2994&SUBSYS_13E910 intel simple communication controller
+        3A00    ICH10 Family ICH10 4 port SATA IDE Controller
+        3A02    82801JD ICH10D SATA Controller
+        3A03    ICH10 ICH10 AHCI
+        3A05    82801JD ICH10D SATA Controller
+        3A06    ICH10 Family SATA2(2Port1)
+        3A14    82801JDO 82801JDO ICH10DO
+        3A16    ICH10R Intel(R) ICH10R LPC Interface Controller
+        3A1A    82801JD 82801JD ICH10D
+        3A20    ICH10 Family Intel(R) ICH10 Family 4 port Serial ATA Storage Controller
+        3A22    ICH10R AHCI Controller
+        3A23    ICH10 ICH10 AHCI
+        3A26    ICH10 Family Intel(R) ICH10 Family 2 port Serial ATA Storage Controller
+        3A30    50011458 INTEL(R) ICH10 Family SMB controller 
+        3A34    ICH10 Intel(R) ICH10 Family USB Universal Host Controller
+        3A35    ICH10 Intel(R) ICH10 Family USB Universal Host Controller
+        3A36    ICH10 Intel(R) ICH10 Family USB Universal Host Controller
+        3A37    ICH10 Intel(R) ICH10 Family USB Universal Host Controller
+        3A38    ICH10 Intel(R) ICH10 Family USB Universal Host Controller
+        3A39    ICH10 Intel(R) ICH10 Family USB Universal Host Controller
+        3A3A    ICH10 Intel(R) ICH10 Family USB Universal Host Controller
+        3A3C    ICH10 Intel(R) ICH10 Family USB Enhanced Host Controller
+        3A3E    Microsoft UAA Bus Driver for High Definition Audio Microsoft UAA Bus Driver for High Definition Audio
+        3A40    ICH10 Intel(R) ICH10 Family PCI Express Root Port
+        3A42    ICH10 Intel(R) ICH10 Family PCI Express Root Port
+        3a60    ICH10 SM-Bus Controller
+        3B00    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B01    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B02    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B03    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B06    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B07    3B07 Intel(R) 5/3400 Series Chipset LPC Interface Controller
+        3B08    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B09    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B0A    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B0B    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B0D    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B0F    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B12    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B14    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B16    Intel(R) 5 Series/3400 Series Chipset Family LPC Interface Controller
+        3B20    PCH (Ibex P SATA IDE 4-Port Desktop
+        3B21    PCH (Ibex Peak) SATA IDE 2-Port Desktop
+        3B22    PCH (Ibex Peak) SATA AHCI 6-Port Desktop
+        3B23    PCH (Ibex Peak) SATA AHCI 4-Port Desktop
+        3B24    PCH SATA Enhanced RAID
+        3B25    PCH SATA Raid Controller
+        3B26    PCH (Ibex Peak) SATA IDE 2-Port Secondary Desktop
+        3B28    PCH (Ibex Peak) SATA IDE 4-Port Mobile
+        3B29    PCH (Ibex Peak) SATA AHCI 4-Port Mobile
+        3B2B    PCHM SATA Enhanced RAID
+        3B2C    PCHM SATA Raid Controller
+        3B2D    PCHM SATA IDE Controller:2 port
+        3B2E    PCH (Ibex Peak) SATA IDE 4-Port Mobile
+        3B2F    PCH (Ibex Peak) Intel(R) 5/3400 Series Chipset Family 6 Port SATA AHCI Controller
+        3B30    3B30 Intel(R) 5/3400 Series Chipset Family SMBus Controller
+        3B32    3B64 Intel(R) 5/3400 Series Chipset Family Thermal Subsystem
+        3B34    3B34 Standard Enhanced PCI to USB Host Controller
+        3B3C    3B3C Standard Enhanced PCI to USB Host Controller
+        3B42    3B42 Intel(R) 5/3400 Series Chipset Family PCI Express Root Port
+        3B44    3B44 Intel(R) 5/3400 Series Chipset Family PCI Express Root Port
+        3B46    3B46 Intel(R) 5/3400 Series Series Chipset Family PCI Express Root Port
+        3B48    3B48 Intel(R) 5/3400 Series Chipset Family PCI Express Root Port
+        3B56    3B56 High Definition Audio Controller
+        3b63    ff1e1179 06
+        3B64    3B64 Management Engine Driver
+        3B64&subsys     REV_06 Intel Management Engine Interface
+        3B64&SUBSYS_048210      Intel 3B09 Management Engine Driver
+        3B64&subsys_048710      REV_06 Intel Management Engine Interface
+        3B64&SUBSYS_116817      REV_06 Intel Management Engine Interface
+        3B64SUBSYS_FF1E117      REV_06 intel
+        3b64_&subsys_fd3c1      ven_8086&dev_3b64&subsys_fd3c1179&rev_06 ven_8086&dev_3b64&subsys_fd3c1179&rev_06 [Toshiba C660-1CN]
+        3b65    ff1e1179 06
+        3B67    Vendor ID 0x8086  Intel(R) Active Management Technology - Serial Over LAN (SOL) 
+        4000    Creatix V.90 HaM Modem
+        402f    - Intel (R) 5400 Chipset QuickData Technology device - 402F
+        4220    Intel Pro/Wireless 2200BG Intel 54 MBit/s Notebook WLAN Card
+        4222    10208086 Intel 3945ABG Wireless LAN controller
+        4223    2915ABG Intel (R) PRO/Wireless 2200BG Network Connection, (R) PRO/Wireless 2915ABG Network Connection
+        42231   2915ABG Intel (R) PRO/Wireless 2200BG Network Connection, (R) PRO/Wireless 2915ABG Network Connection
+        4224    Intel Pro Wireless 2915ABG 802.11a/b/g WLan adapter
+        4227    3945ABG Intel(R) PRO/Wireless 3945ABG
+        4229    Intel 4965AGN Intel. Wireless WiFi Link 4965AGN(supporting 802.11a/b/g/Draft-N)
+        422B      Intel(R) Centrino(R) Ultimate-N 6300 AGN
+        422C    BCM4311KFBG Intel(R) Centrino(R) Advanced-N 6200 AGN
+        422D    Intel 4965AGN Intel. Wireless WiFi Link 4965AGN
+        4230    Intel 4965AGN Intel. Wireless WiFi Link 4965AGN
+        4232    Intel. WiFi Link 5100 Carte Intel. WiFi Link 5100 AGN
+        4233    Intel 4965AGN Intel. Wireless WiFi Link 4965AGN
+        4235    5300AGN Intel. WiFi Link 5300 AGN
+        4236    5300AGN Intel(R) WiFi Link 5300 AGN
+        4237    27DA Intel (R) WiFi Link 5100 AGN
+        4238    6300 Intel Centrino Ultimate-N 6300 AGN
+        4239    0x4239 Intel(R) Centrino(R) Advanced-N 6200 AGN
+        423A    5350AGN PRO/Wireless 5350 AGN [Echo Peak]
+        423C    5150AGN WiMAX/WiFi Link 5150
+        4318    1370 (0280) Dell Wireless 1370 WLAN Mini-PCI Card
+        444E    TurboMemory Intel TurboMemory
+        4813    1370 (0280) Dell Wireless 1370 WLAN Mini-PCI Card
+        482     82375MB PCI\VEN8086
+        4836    242121 2425678
+        4888    3945 intel 3945abg wireless lan controller
+        5001    \Device\0000004c Modem - PPP
+        5005    PRO/DSL 2200 Modem - PPPoA
+        5029    ?(EP80579) AHCI Controller
+        502A    Tolaoai SATA Controller
+        502B    Tolapai SATA Controller
+        5200    NH82801GR PCI to PCI Bridge
+        5201    i960 Network Controller
+        5309    80303 I/O Processor Address Translation Unit
+        530D    80312 I/O Companion Unit Address Translation
+        6741_   0x8086 Intel USB 3.0
+        6960    EHCI 960 emulator
+        7000    82371SB PIIX3 PCI-to-ISA Bridge (Triton II)
+        7010    82371SB PIIX3 IDE Interface (Triton II)
+        7020    82371SB PIIX3 USB Host Controller (Triton II)
+        7030    82437VX System Controller
+        7051    PB 642365-003 Intel Business Video Conferencing Card
+        7100    82439TX System Controller (MTXC), part of 430TX chipset
+        7110    82371AB/EB/MB Intel 82371AB/EB PCI to ISA bridge (ISA mode)
+        7111    82371AB/EB/MB Intel(R) 82371AB/EB PCI Bus Master IDE Controller
+        7112    82371AB/EB/MB PIIX4/4E/4M USB Interface
+        7113    82371AB/EB/MB PIIX4/4E/4M Power Management Controller
+        7120    Intel(R) 82801IMB Host-Hub Interface Bridge / DRAM Ctrlr
+        7121    801F104 Graphics Controller
+        7122    82810-DC100 Host-Hub Interface Bridge / DRAM Ctrlr
+        7123            82810-DC100 Intel.. 82810 Graphics Controller
+        7123    82810-DC100 Intel. 82810 Graphics Controller
+        7124    82810E Host-Hub Interface Bridge / DRAM Ctrlr
+        7125    82810E Intel Direct AGP 810Chipset 
+        7126    82810-DC133 Host Bridge and Memory Controller Hub
+        7127    82810-DC133 Graphics Device (FSB 133 MHz)
+        7128    82810-M DC-100 Host Bridge and Memory Controller Hub
+        712A    82810-M DC-133 Host Bridge and Memory Controller Hub
+        7180    rmc Host/PCI bridge in 440LX/EX AGP chipset
+        7181    82443 ex/lx AGP device in 440LX/EX AGP chipset
+        7182    440LX/EX intel
+        7190    82443BX/ZX Intel 82443BX Pentium(R) II Processor to PCI Bridge
+        7191    82443BX/ZX Intel 82443BX Pentium(R) II Processor to AGP Controller
+        7192    82443BX/ZX 440BX/ZX chipset Host-to-PCI Bridge
+        7194    82443MX AC'97 Audio device
+        7195    82443MX AC97 Audio Controller
+        7196    82440 - 443MX AC97 Modem Controller (Winmodem)
+        7198    82443MX PCI to ISA Bridge
+        7199    82443MX EIDE Controller
+        719A    82443MX USB Universal Host Controller
+        719B    82443MX Power Management Controller
+        71A0    82443GX Host-to-PCI Bridge
+        71A1    intel 82801 IB ICH9  fabricated by Intel 
+        71A2    82443GX Host-to-PCI Bridge
+        7221    82810 graphics device
+        7600    82372FB/82468GX LPC/FWH Interface
+        7601    82372FB/82468GX EIDE Controller
+        7602    82372FB/82468GX USB Host Controller
+        7603    82372FB/82468GX SM Bus Controller
+        7605    82372FB IEEE1394 OpenHCI Host Controller
+        7800    82740 AGP Graphics Accelerator
+        78000   PCI\VEN_8086&DEV_3B64&CC_0780 PCI\VEN_8086&DEV_3B64&CC_0780
+        803b    0x104d 0x81ef
+        8083    Intel PM45 Intel Wireless WiFi Link 5100 ABGN 10/100/1000 Base T
+        8086    http://dlcdnet.asus.com/pub/ASUS/nb/Drivers/MEI/ME 0x8086&DEV_3B64&CC_0780
+        8086&DEV        9.3.0.1019 intel
+        8086&DEV-24C5   VIA vynil v700b VIA vynil v700b
+        8086&DEV_1040   SUBSYS_148A103C REV_00\3&61AAA01&0&50 
+        8086&DEV_24C5   82801DBM SoundMax Controller VIA vynil v700b
+        8086&DEV_3B64   SUBSYS_03701025 pci simple communications controller
+        8086&DEV_3B64&SUBS      SUBSYS_144A103C pci simple communications controller
+        8086&DEV_7191&SUBS      Intel 3B69Management Engine Driver Management Engine Driver
+        80861   (0x2994) Intel(R) Management Engine Interface
+        8108    SCH US15WP Intel(R) Graphics Media Accelerator 500  https://downloadcenter.intel.com/confirm.aspx?httpDown=http
+        811A    Atom SCH Atom SCH PATA
+        8186    i dont know i dont know
+        82801   24D5 Realtek AC97
+        84C4    82454KX/GX 450KX/GX PCI Bridge (Orion)
+        84C5    82453KX/GX 450KX/GX Memory Controller (Orion)
+        84CA    82451NX 450NX PCIset Memory & I/O Controller
+        84CB    82454NX/82467GX PCI Expander Bridge
+        84E0    82461GX System Address controller
+        84E1    82462GX System Data Controller
+        84E2    82465GX Graphics Expander Bridge
+        84E3    82463GX Memory Address Controller
+        84E4    82464GX Memory Data Controller
+        84E6    82466GX Wide and fast PCI eXpander Bridge
+        84EA    82460GX AGP Bridge (GXB function 1)
+        85A1    6300ESB LPC Bridge
+        85A2    6300ESB IDE Controller
+        85A3    6300ESB Serial ATA Controller
+        85A4    6300ESB SMBus Controller
+        85A6    6300ESB AC'97 Audio Controller
+        85A7    6300ESB AC'97 Modem Controller
+        85A9    6300ESB USB 1.1 UHCI Controller #1
+        85AA    6300ESB USB 1.1 UHCI Controller #2
+        8C02    C220 Intel(R) 8 Series/C220 Series SATA AHCI Controller
+        8C22    8C22 Intel(R) 8 Series/C220 Series SMBus Controller
+        8c31    PCI\VEN_8086&DEV_8C3A&SUBSYS_85341043&REV_04 Intel USB 3.0 eXtensible
+        8C3A    0x8C31 Intel(R) Management Engine Interface
+        8C5C    8C5C Intel(R) H81 LPC Controller
+        8CBA    PCI\VEN_8086&DEV_8CBA&SUBSYS_8CBA1849&REV_00 PCI Simple Communications Controller
+        8d3a    PCI\VEN_8086&DEV_8D3A&SUBSYS_86001043 Intel Management Engine Interface (MEI)
+        9620    I2O RAID PCI to PCI Bridge
+        9621    SRCU21 I2O 1.5 RAID Controller
+        9622    SRCUxx I2O 1.5 RAID Controller
+        9641    SRCU31 I2O 1.5 RAID Controller
+        96A1    SRCU31L I2O 1.5 RAID Controller
+        9779    0x2992 0x2992
+        9874    AC97 AUDIO CONTROLLER
+        9876    i845 intel brokdale
+        9876 2804       80860101 IntcDAudModel
+        9877    1 1
+        9888    HDAUDIO\FUNC_01&VEN_8086&DEV_27d8&SUBSYS_80860101& HDAUDIO\FUNC_01&VEN_8086&DEV_27d8&REV_1000
+        9998    42468068  02
+        9999    pci30b2103c Interface chip
+        9C03    9C03 Intel(R) 8 Series SATA Controller
+        9C14    9C14 Intel(R) 9 Series PCI Express Root Port
+        9C20    9C20 High Definition Audio Controller
+        9C22    9C22 Intel(R) 8 Series SMBus Controller
+        9C24    9C24 Intel(R) 8 Series Thermal
+        9C26    9C26 Intel(R) 8 Series USB Enhanced Host Controller
+        9C31    Unknown Intel USB 3.0 eXtensible Host Controller
+        9C3A    PCI\VEN_8086 Intel Management Engine Interface driver
+        9c3a  Subsys_05eb1      9c3a Subsys_05eb1028 & rev_04\3 & 11583659 PCI Simple Communication Controller
+        9c3a Subsys_05eb1       12 PCI Simple Communication Controller
+        9C43    9C43 Intel(R) 8 Series LPC Controller
+        9CB1    PCI\VEN_8086&DEV_9CB1 Intel USB 3.0 Driver for Intel 8 and U/Y Series 
+        A001    3150 Intel Media Accelerator 3150
+        A002    GMA 3150 Intel. Grafik-Media-Accelerator 3150 (Intel. GMA 3150)
+        A011    02\3 Intel(R) Graphics Media Accelerator 3150
+        A012    GMA3150 Intel. Graphics Media Accelerator 3150
+        AO11    02\3 3&33FD14CA&0&10
+        AO12    0x0283E Intel(R) ICH8 Family SMBus Controller
+        B152    S21152BB PCI to PCI Bridge
+        B154    1C20 PCI to PCI Bridge
+        B555    21555 Non-Transparent PCI-to-PCI Bridge
+        C50     fd sdf
+        E13A    7600 NXMOQSN00430812D49
+        F4E     0F4E Intel(R) Pentium(R)/Celeron(R) processor N-/J- series PCI Express Root Port
+        PCI\VEN_8086&DEV_2      11583659 PCI\VEN_8086&DEV_27DA&SUBSYS_31031565
+        PCI\VEN_8086&DEV_2      11583659 PCI\VEN_8086&DEV_8C22&SUBSYS_FA301179&REV_04\3&11583659&0&FB
+        PCI\VEN_8086&DEV_3      11583658 PCI\VEN_8086&DEV_3B64&SUBSYS_04821025&REV_06
+        x27c8   PCI\VEN_8086&DEV_27D8&SUBSYS_02D61028&REV_01\3&61A Microsoft UAA Bus HD Audio
+        x27d8   A62516F3 INTEL IDT Audio
+        x999    2930 PCI\VEN_8086&DEV_2930&SUBSYS_037E1014&REV_02\3&61AAA01&0&FB
+        _1c3a   REV_04 REV-04
+        _1E3A   0c05 i5-3210
+        _3B64   3b69 Chip Description:Management Engine Driver
+        __1c3a  SUBYS_308C17AA REV-04 3&11583659
+        ___1C3A 8086 Intel(R) Management Engine Interface
+        8671    
+8087    Intel
+        0028    NV05 MCP67 High Definition Audio
+        07D6    612BNXHMW Intel Centrino Wireless-N + WiMAX 6150
+80EE    Oracle Corporation - InnoTek Systemberatung GmbH
+        7145    VBoxVideo 0x8168 VirtualBox Graphics Adapter
+        BEEF    VBoxVideo 0x8168 VirtualBox Graphics Adapter
+        CAFE    N/A - Virtual Device VirtualBox Device
+8866    T-Square Design Inc.
+        1685    T2-Mp3-001 MP3 player/FM radio/voice recorder 256 Mo flash
+        1689    T2-MP3-001 MP3 player/FM radio/voice recorder 256 Mo flash
+8888    Silicon Magic
+8E0E    Computone Corporation
+9004    Adaptec Inc
+        0078    aic-7880x AHA-2940UW/CN
+        1078    AIC-7810C RAID Coprocessor
+        1135    0x0035 Texas Instruments
+        1160    AIC-1160 Fibre Channel Adapter
+        2178    AIC-7821 SCSI Controller
+        3860    AIC-2930U Ultra SCSI Ctrlr
+        3B78    AHA-4944W/4944UW QuadChannel Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr
+        5075    AIC-755x SCSI Ctrlr
+        5078    AIC-7850P Fast/Wide SCSI Controller
+        5175    AIC-755x SCSI Ctrlr
+        5178    AIC-7850 FAST-SCSI Ctrlr
+        5275    AIC-755x SCSI Ctrlr
+        5278    AIC-7850 Fast SCSI Ctrlr
+        5375    AIC-755x SCSI Ctrlr
+        5378    AIC-7850 Fast SCSI Ctrlr
+        5475    AIC-755x SCSI Ctrlr
+        5478    AIC-7850 Fast SCSI Ctrlr
+        5575    AVA-2930 SCSI Ctrlr
+        5578    AIC-7855 Fast SCSI Ctrlr
+        5675    AIC-755x SCSI Ctrlr
+        5678    AIC-7856 Fast SCSI Ctrlr
+        5775    AIC-755x SCSI Ctrlr
+        5778    AIC-7850 Fast SCSI Ctrlr
+        5800    AIC-5800 PCI-to-1394 Ctrlr
+        5900    ANA-5910/30/40 ATM155 & 25 LAN Controller
+        5905    ANA-5910A/30A/40A ATM Adpater
+        6038    AHA-2930C Ultra SCSI Adpater (VAR)
+        6075    AIC-7560? CardBus Ultra SCSI Controller
+        6078    AIC-7860 PCI SCSI Controller
+        6178    AIC-7861 PCI SCSI Controller
+        6278    AIC-7860 SCSI Ctrlr
+        6378    AIC-7860 SCSI Ctrlr
+        6478    AIC-786x SCSI Ctrlr
+        6578    AIC-786x SCSI Ctrlr
+        6678    AIC-786x SCSI Ctrlr
+        6778    AIC-786x SCSI Ctrlr
+        6915    ANA620xx/69011A Fast Ethernet
+        7078    AIC-7870 Fast and Wide SCSI Ctrlr
+        7178    AHA-2940/2940W Fast/Fast-Wide SCSI Ctrlr
+        7278    AHA-3940/3940W Multichannel Fast/Fast-Wide SCSI Ctrlr
+        7378    AHA-3985 4-chan RAID SCSI Ctrlr
+        7478    AHA-2944 SCSI Ctrlr
+        7578    AHA-3944/3944W Multichannel Fast/Fast-Wide Diff. SCSI Ctrlr
+        7678    AHA-4944W/4944UW QuadChannel Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr
+        7778    AIC-787x SCSI Ctrlr
+        7810    aic 7810 Memory control IC
+        7815    AIC-7515 RAID + Memory Controller IC
+        7850    aic-7850P Fast/Wide SCSI-2 Controller
+        7855    AHA-2930 Single channel SCSI Host Adapter
+        7860    AIC-7860 PCI SCSI Controller
+        7870    AIC-7870 Fast/Wide SCSI-2 Controller
+        7871    aha 2940 SCSI
+        7872    aha 3940 Multiple SCSI channels
+        7873    aha 3985 Multiple SCSI channels
+        7874    aha 2944 Differential SCSI
+        7880    aic7880p Fast 20 SCSI
+        7890    AIC-7890 SCSI controller
+        7891    AIC-789x SCSI controller
+        7892    AIC-789x SCSI controller
+        7893    AIC-789x SCSI controller
+        7894    AIC-789x SCSI controller
+        7895    AIC-7895 Ultra-Wide SCSI Ctrlr on AHA-2940 AHA-394x
+        7896    AIC-789x SCSI controller
+        7897    AIC-789x SCSI controller
+        8078    AIC-7880P Ultra Wide SCSI
+        8178    AHA-2940U/2940UW Ultra/Ultra-Wide SCSI Ctrlr
+        8278    AHA-3940Uxx AHA-3940U/3940UW/3940UWD SCSI Ctrlr
+        8378    AIC-7883U SCSI Controller
+        8478    ADAPTEC 2940UW CN SCSI Ultra-Wide Diff. SCSI Ctrlr
+        8578    AHA-3944U/3944UWD Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr
+        8678    AHA-4944UW QuadChannel Ultra-Wide Diff. SCSI Ctrlr
+        8778    AIC-788x Ultra-Wide SCSI Ctrlr
+        8878    AIC-7888? Ultra Wide SCSI Controller
+        8B78    ABA-1030 AIC-7880P
+        EC78    AHA-4944W/4944UW QuadChannel Fast-Wide/Ultra-Wide Diff. SCSI Ctrlr
+9005    Adaptec Inc
+        0010    AIC-7890AB scsi controller AHA-2940U2W/U2B,2950U2W Ultra2 SCSI
+        0011    11111 AHA-2930U2 Ultra2 SCSI Host Adapter
+        0013    AIC-7890/1 SCSI Controller
+        001F    AIC-7890 AB for Windows  XP Ultra2-Wide SCSI controller
+        0020    AIC-789x SCSI Controller
+        002F    AIC-789x SCSI Controller
+        0030    AIC-789x SCSI Controller
+        003F    AIC-789x SCSI Controller
+        0050    AHA-3940U2x/3950U2x Ultra2 SCSI Adapter
+        0051    AHA-3950U2x Ultra2 SCSI Adapter
+        0053    AIC-7896 SCSI Controller
+        005F    AIC-7896/7 Ultra2 SCSI Controller
+        0080    AIC-7892Q Ultra160/m PCI SCSI Controller
+        0081    AIC-7892B Ultra160 SCSI Controller
+        0083    AIC-7892D Ultra160 SCSI Controller
+        008F    AIC-7892 Ultra160 SCSI Controller
+        00C0    AIC-7899A Ultra160 SCSI Controller
+        00C1    AIC-7899B Ultra160 SCSI Controller
+        00C3    AIC-7899D Ultra160 SCSI Controller
+        00C5    RAID Subsystem HBA
+        00CF    AIC-7899G Ultra160 SCSI Controller
+        0241    1420 Adaptec 1420SA Serial AHA HostRAID Controller
+        0258    AAC-RAID Adaptec AAR-2610SA SATA 6-Port Raid
+        0285    Adaptec 2410SA SATA RAID PCIX133 32/64bit
+        0286    SUBSYS_95801014REV_02 SUBSYS_95801014REV_02
+        041F    AIC 9410 SAS/SATA Controller
+        043E    AIC9450W SAS/SATA Controller
+        41E     AIC-9410W Razor ASIC
+        564A    AIC-7211W iSCSI Controller
+        8000    ASC-29320A Ultra320 SCSI Controller
+        800F    AIC-7901 Ultra320 SCSI Controller
+        8010    ASC-39320 Ultra320 SCSI Controller
+        8011    ASC-39320D Ultra320 SCSI Controller
+        8012    ASC-29320 Ultra320 SCSI Controller
+        8014    ASC-29320LP Ultra320 SCSI Controller
+        8015    ASC-39320 Ultra320 SCSI Controller
+        8016    ASC-39320A Ultra320 SCSI Controller
+        8017    ASC-29320ALP Ultra320 SCSI Controller
+        801C    AIC-????? Ultra320 SCSI Controller
+        801D    AIC-7902B Ultra320 SCSI Controller
+        801E    AIC-7901 Ultra320 SCSI Controller
+        801F    AIC-7902 Ultra320 SCSI Controller
+        8080    ASC-29320A Ultra320 HostRAID Controller
+        808F    AIC-7901 Ultra320 HostRAID Controller
+        8090    ASC-39320 HostRAID SCSI Controller
+        8091    ASC-39320D HostRAID SCSI Controller
+        8092    ASC-29320 HostRAID SCSI Controller
+        8093    ASC-29320LPE HostRAID SCSI Controller
+        8094    ASC-29320LP HostRAID SCSI Controller
+        8095    ASC-39320 HostRAID SCSI Controller
+        8096    ASC-39320A HostRAID SCSI Controller
+        8097    ASC-29320ALP HostRAID SCSI Controller
+        809C    ASC-39320D HostRAID SCSI Controller
+        809D    AIC-7902B HostRAID SCSI Controller
+        809E    AIC-7901A HostRAID SCSI Controller
+        809F    AIC-7902B HostRAID SCSI Controller
+919A    Gigapixel Corp
+9412    Holtek
+        6565    HT6565 IDE Controller?
+9699    Omni Media Technology Inc.
+9710    MosChip Semiconductor Technology
+        7705    MCS7705 USB 1.1 to Single Parallel Controller 
+        7830    MCS7830 USB 2.0 to 10/100M Fast Ethernet Controller
+        8729    mcs7830 usb 2.0 10/100M ethernet adaptor
+        9805    mcs9805cv MosChip PCI Parallel Port
+        9815    9815 MCS9815 / M-CAB Parallel Adapter
+        9835    9835 2 serial, 1 LPT port PCI Card
+        9845    NM9845CV 2 serial
+        9865    MCS9865 PCI Porta Paralela
+        9900    MCS9900CV-AA NetMOS Single Parallel Port Card
+        9904    MCS9900 PCIe to Multi IO Controller
+        9912    MCS9901CV-CC PCIe to Dual Serial and Single Parallel
+        9922    MCS9922 PCIe to Dual Serial Port Controller
+9902    StarGen, Inc.
+        0001    SG2010 PCI-to-PCI Bridge
+        0002    SG2010 PCI to high speed serial bridge
+        0003    SG1010 6 port serial switch /PCI-to-PCI bridge
+A0A0    Aopen Inc.
+A0F1    Unisys Corporation
+        9876    0x9876 0x9876
+A200    NEC Corp.
+        a200    saa1735hl tv
+A259    Hewlett Packard
+        3038    82945G PCI\VEN_103C&DEV_3302&SUBSYS_3305103C&REV_00
+A304    Sony
+        3038    10EC USB
+A727    3com Corporation
+        0013    3com p/n: 3CRDAG675 3com 11 a/b/g wireless PCI Adapter
+AA42    Abekas, Inc
+        03A3    9400-0931 CharKey
+AC1E    Digital Receiver Technology Inc
+B1B3    Shiva Europe Ltd.
+B894    Brown & Sharpe Mfg. Co.
+BEEF    Mindstream Computing
+C001    TSI Telsys
+C0A9    Micron/Crucial Technology
+C0DE    Motorola
+        5600    62802 
+        C0DE    ENF656 oZ0030
+C0FE    Motion Engineering Inc.
+C622    Hudson Soft Co Ltd
+CA50    Varian, Inc
+CAFE    Chrysalis-ITS
+CCCC    Catapult Communications
+D4D4    Curtiss-Wright Controls Embedded Computing
+        010F    PMC-211 PMC-211
+        0601    PCI Mezzanine Card
+DC93    Dawicontrol
+DEAD    Indigita Corporation
+DEAF    Middle Digital, Inc
+        9050    PC Weasel PCI VGA Device
+        9051    PC Weasel PCI Serial Comm. Device
+        9052    PC Weasel PCI
+E159    Tiger Jet Network Inc
+        0001    Ambient MD3200 A Yeastar TDM400
+        0002    Sedlbauer Speed PCI
+        0600    Tiger 600 PCI-to-PCI Bridge
+E4BF    EKF Elektronik GMBH
+EA01    Eagle Technology
+EABB    Aashima Technology B.V.
+EACE    Endace Measurement Systems Ltd.
+        24C5    1 VIA Vynil v700b
+        3100    DAG 3.10 OC-3/OC-12
+        3200    DAG 3.2x OC-3/OC-12
+        320E    DAG 3.2E Fast Ethernet
+        340E    DAG 3.4E Fast Ethernet
+        341E    DAG 3.41E Fast Ethernet
+        3500    DAG 3.5 OC-3/OC-12
+        351C    DAG 3.5ECM Fast Ethernet
+        4100    DAG 4.10 OC-48
+        4110    DAG 4.11 OC-48
+        4200    DAG 4.2 OC-48
+        420E    DAG 4.2E Dual Gigabit Ethernet
+        430e    DAG 4.3E Dual Gigabit Ethernet
+ECC0    Echo Digital Audio Corporation
+        0050    
+        0051    
+        0060    
+        0070    
+        0071    
+        0072    
+        0080    MiaMIDI 4/2 channel (analog/digital) audio card
+        0100    GINA3G 6/8 channel (analog/digital) audio card
+        3410    0x0001 Motorola
+EDD8    ARK Logic, Inc
+        A091    ARK1000PV Stingray GUI Accelerator
+        A099    ARK2000PV Stingray GUI Accelerator
+        A0A1    ARK2000MT Stingray 64
+        A0A9    ARK2000MI Quadro645 GUI Accelerator
+        A0B1    ARK2000MI+ GUI Accelerator
+F5F5    F5 Networks Inc.
+FA57    Interagon AS
+        0001    PMC Pattern Matching Chip
+
+ diff --git a/public/Wb/Home/Src/Once.HC.HTML b/public/Wb/Home/Src/Once.HC.HTML new file mode 100755 index 0000000..91edd0d --- /dev/null +++ b/public/Wb/Home/Src/Once.HC.HTML @@ -0,0 +1,86 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+//This file is executed by the
+//first terminal window upon start-up.
+//See Once and Home Files.
+
+//Delete the rest from this file.
+
+U0 Tmp()
+{
+  OnceExe;
+  switch (sys_boot_src.u16[0]) {
+    case BOOT_SRC_ROM:
+      "Continue booting hard drive ";
+      if (YorN) {
+        DocBottom;
+        ExeFile("C:/Home/Once");
+      }
+      break;
+    case BOOT_SRC_DVD:
+      "\nIf you answer 'No' you can play with\n"
+            "the live CD without installing.\n\n"
+            "Install onto hard drive ";
+      if (YorN) {
+        DocBottom;
+        RunFile("::/Misc/OSInstall",,TRUE);
+      }
+      if (FileFind("::/Misc/Tour")) {
+        "\nTake Tour";
+        if (YorN) {
+          DocBottom;
+          Cd("::/Misc/Tour");
+          InFile("Tour");
+        }
+      }
+      break;
+    case BOOT_SRC_RAM:
+    case BOOT_SRC_HARDDRV:
+      "$PURPLE$$TX+CX,\"Tip of the Day\"$$FG$\n";
+      TipOfDay;
+      Type("::/Doc/Customize.DD");
+      if (FileFind("::/Misc/Tour")) {
+        "\nTake Tour";
+        if (YorN) {
+          DocBottom;
+          Cd("::/Misc/Tour");
+          InFile("Tour");
+        }
+      }
+      break;
+  }
+}
+
+Tmp;
+
+ diff --git a/public/Wb/Home/Src/PersonalMenu.DD.HTML b/public/Wb/Home/Src/PersonalMenu.DD.HTML new file mode 100755 index 0000000..d237f64 --- /dev/null +++ b/public/Wb/Home/Src/PersonalMenu.DD.HTML @@ -0,0 +1,161 @@ + + + + + + + + + + + +
+Copy this file to your /Home directory and modify it.  This version is the 
+default. 
+
+Cd;Dir;
+
+Cd("::/Demo");Dir;
+
+Cd("::/Demo/Graphics");Dir;
+
+Cd("::/Demo/Snd");Dir;
+
+Cd("::/Demo/DolDoc");Dir;
+
+Cd("::/Demo/Games");Dir;
+
+Cd("::/Demo/MultiCore");Dir;
+
+Cd("::/Demo/Asm");Dir;
+
+Cd("::/Doc");Dir;
+
+Cd("::/Demo/Lectures");Dir;
+
+Cd("::/Apps");Dir;
+
+
+Run TOSStdIns() if you wish to
+use the official staff /Home files.
+Cd("::/Demo/AcctExample");Dir;
+
+
+Make all with BootHDIns().
+Cd("::/Kernel");Dir;
+
+Cd("::/Compiler");Dir;
+
+
+The ::/StartOS.HC file is compiled every time you boot.
+Cd("::/Adam");Dir;
+    
+
+Welcome   Help & Index  Demo Index
+FastReboot Take Tour    Key Map
+
+
+
+          Fun Games
+
+
+
+
+
+
+
+
+Titanium/* Graphics Not Rendered in HTML */ Diamond/* Graphics Not Rendered in HTML */  Bat/* Graphics Not Rendered in HTML */   Varoom/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+FlatTops/* Graphics Not Rendered in HTML */  Golf /* Graphics Not Rendered in HTML */ KeepAway/* Graphics Not Rendered in HTML */ RawHide/* Graphics Not Rendered in HTML */
+
+
+
+
+
+
+
+
+
+
+
+X-Caliber/* Graphics Not Rendered in HTML */ Wenceslas/* Graphics Not Rendered in HTML */  Lines/* Graphics Not Rendered in HTML */
+
+
+
+
+         Unfun Games
+
+
+
+
+
+
+
+
+
+ Talons/* Graphics Not Rendered in HTML */  Frankenstein/* Graphics Not Rendered in HTML */ ZoneOut/* Graphics Not Rendered in HTML */ 
+
+
+
+
+
+
+
+
+
+ToTheFront/* Graphics Not Rendered in HTML */  Span /* Graphics Not Rendered in HTML */ Checkers/* Graphics Not Rendered in HTML */ Digits/* Graphics Not Rendered in HTML */
+
+
+
+
+             Code Scraps
+
+
+
+
+
+
+ Strut/* Graphics Not Rendered in HTML */ BigGuns/* Graphics Not Rendered in HTML */ TheDead/* Graphics Not Rendered in HTML */ DunGen/* Graphics Not Rendered in HTML */ Models/* Graphics Not Rendered in HTML */
+
+
+
+
+              Nongames
+
+
+
+
+
+
+
+JukeBox/* Graphics Not Rendered in HTML */ Psalmody/* Graphics Not Rendered in HTML */ Budget/* Graphics Not Rendered in HTML */ Logic/* Graphics Not Rendered in HTML */ Vocab/* Graphics Not Rendered in HTML */ 
+
+
+List all syms in alpabetic order
+List all syms in numeric order
+
+ diff --git a/public/Wb/Home/Src/PersonalNotes.DD.HTML b/public/Wb/Home/Src/PersonalNotes.DD.HTML new file mode 100755 index 0000000..a9f3a81 --- /dev/null +++ b/public/Wb/Home/Src/PersonalNotes.DD.HTML @@ -0,0 +1,35 @@ + + + + + + + + + + + +
+Place your notes or TODO here.
+<CTRL-SHIFT-M>
+
+
+
+ diff --git a/public/Wb/Home/Src/StartOS.HC.HTML b/public/Wb/Home/Src/StartOS.HC.HTML new file mode 100755 index 0000000..c4bf7ba --- /dev/null +++ b/public/Wb/Home/Src/StartOS.HC.HTML @@ -0,0 +1,77 @@ + + + + + + + + + + + +
+//This is executed by the Adam task at boot.
+//See Adam Start-up.
+
+#help_index "Compiler/Directive"
+public extern I8i Option(I64i num,I8i val);
+Option(0,0); //(0,0)=EchoOff   (0,1)=EchoOn
+
+#include "/Kernel/KernelA.HH"
+#include "/Compiler/CompilerA.HH"
+#include "/Kernel/KernelB.HH"
+#include "/Kernel/KernelC.HH"
+#include "/Compiler/CompilerB.HH"
+
+Option(OPTf_WARN_PAREN,ON);
+Option(OPTf_WARN_DUP_TYPES,ON);
+HashTablePurge(adam_task->hash_table);
+
+#include "/Adam/MakeAdam"
+
+//Dbg("Type 'G;'");
+DocTermNew;
+WinVert(2,10);
+
+sys_winmgr_task=Spawn(&WinMgrTask,NULL,"Window Mgr");
+Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_BORDER
+        -WIF_SELF_GRAB_SCROLL-WIF_SELF_CTRLS;
+LBts(&Fs->display_flags,DISPLAYf_CHILDREN_NOT_ON_TOP);
+LBts(&Fs->display_flags,DISPLAYf_SHOW);
+RegInit;
+LBts(&sys_run_level,RLf_REGISTRY);
+if (!ins_reg.registered)
+  InsUnreg;
+
+WallPaperInit;
+
+if (DrvIsWritable)
+  DirMk("/Tmp"); //Good to have a Tmp
+
+Option(OPTf_WARN_PAREN,OFF);
+Option(OPTf_WARN_DUP_TYPES,OFF);
+LBts(&sys_run_level,RLf_HOME);
+
+#help_index ""
+#include "~/MakeHome"
+
+//After this file, the Adam task enters server mode.
+
+ diff --git a/public/Wb/HomeKeyPlugIns.HC.HTML b/public/Wb/HomeKeyPlugIns.HC.HTML new file mode 100755 index 0000000..2111353 --- /dev/null +++ b/public/Wb/HomeKeyPlugIns.HC.HTML @@ -0,0 +1,233 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 TimeIns()
+{
+  CDate cdt;
+  cdt=Now;
+  "$IV,1$----%D %T----$IV,0$\n",cdt,cdt;
+}
+
+Bool MyPutKey(I64 ch,I64 sc)
+{//ch=ASCII; sc=scan_code
+
+  //See Char for definition of scan codes.
+  //See Key Allocations.
+  //See Keyboard Devices.
+
+  //You can customize keys.  This routine
+  //is called before the main editor
+  //key hndlr DocPutKey().
+  //You can intercept any key.
+
+  //Return TRUE if you completely
+  //handled the key.
+  I64 i;
+  U8 *st1,*st2;
+  if (sc&SCF_ALT && !(sc&SCF_CTRL)) {
+    switch (ch) {
+      case 0:
+        switch (sc.u8[0]) {
+          case SC_F1:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTPURPLE");
+              else
+                "$LTPURPLE$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /PURPLE");
+              else
+                "$PURPLE$";
+            }
+            return TRUE;
+          case SC_F2:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTRED");
+              else
+                "$LTRED$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /RED");
+              else
+                "$RED$";
+            }
+            return TRUE;
+          case SC_F3:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /LTGREEN");
+              else
+                "$LTGREEN$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /GREEN");
+              else
+                "$GREEN$";
+            }
+            return TRUE;
+          case SC_F4:
+            if (sc&SCF_SHIFT) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /Default Color");
+              else
+                "$FG$";
+            } else {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Dol /BLUE");
+              else
+                "$BLUE$";
+            }
+            return TRUE;
+          case SC_F7:
+            if (!(sc&SCF_SHIFT)) {
+              if (sc&SCF_KEY_DESC)
+                KeyDescSet("Cmd /TimeIns");
+              else
+                TimeIns;
+            }
+            return TRUE;
+        }
+        break;
+      case 'a':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete On");
+        else
+          AutoComplete(ON);
+        return TRUE;
+      case 'A':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /AutoComplete Off");
+        else
+          AutoComplete;
+        return TRUE;
+      case 'h':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileHorz");
+        else
+          WinTileHorz;
+        return TRUE;
+      case 'm':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinMax");
+        else {
+          WinBorder;
+          WinMax;
+        }
+        return TRUE;
+      case 'v':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Cmd /WinTileVert");
+        else
+          WinTileVert;
+        return TRUE;
+      case 'l':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Put Link to Cur Pos on Clip");
+        else {
+          ClipDel;
+          st1=FileNameAbs(BIBLE_FILENAME);
+          st2=FileNameAbs(DocPut->filename.name);
+          if (!StrCmp(st1,st2)) {
+            Free(st1);
+            st1=BibleLine2Verse(DocPut->cur_entry->y+1,',');
+            DocPrint(sys_clip_doc,"$LK,\"BF:%s\"$",st1);
+          } else
+            DocPrint(sys_clip_doc,"$LK,\"FL:%s,%d\"$",
+                  st2,DocPut->cur_entry->y+1);
+          Free(st1);
+          Free(st2);
+        }
+        return TRUE;
+      case 'L':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Edit/Place Anchor, Put Link to Clip");
+        else {
+          i=RandU32;
+          ClipDel;
+          DocPrint(sys_clip_doc,"$LK,\"<TODO>\",A=\"FA:%s,ANC%d\"$",
+                DocPut->filename.name,i);
+          "$AN,\"<TODO>\",A=\"ANC%d\"$",i;
+        }
+        return TRUE;
+
+        //Ins your own ALT-key plug-ins
+      case '1':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /pi");
+        else
+          'pi';
+        return TRUE;
+      case '2':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /theta");
+        else
+          'theta';
+        return TRUE;
+      case '3':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /phi");
+        else
+          'phi';
+        return TRUE;
+      case '4':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /omega");
+        else
+          'omega';
+        return TRUE;
+      case '9':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Indent 5");
+        else
+          "$ID,5$";
+        return TRUE;
+      case '0':
+        if (sc&SCF_KEY_DESC)
+          KeyDescSet("Dol /Unindent 5");
+        else
+          "$ID,-5$";
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+Bool MyPutS(U8 *)
+{
+  return FALSE;
+}
+
+KeyDevAdd(&MyPutKey,&MyPutS,0x20000000,TRUE);
+
+ diff --git a/public/Wb/HomeLocalize.HC.HTML b/public/Wb/HomeLocalize.HC.HTML new file mode 100755 index 0000000..3acc465 --- /dev/null +++ b/public/Wb/HomeLocalize.HC.HTML @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+//This makes your keyboard fast
+KbdTypeMatic(0);
+
+//Set Time Zone
+local_time_offset=0*60*60*CDATE_FREQ; //Do daylight savings by hand
+
+//adjust these to set mouse move scale
+ms_hard.scale.x=0.5;
+ms_hard.scale.y=0.5;
+ms_hard.scale.z=1.0; //wheel
+
+//don't change these
+ms_hard.prescale.x=ms_hard.pos.x/ms_hard.scale.x;
+ms_hard.prescale.y=ms_hard.pos.y/ms_hard.scale.y;
+ms_hard.prescale.z=ms_hard.pos.z/ms_hard.scale.z;
+
+
+ diff --git a/public/Wb/HomeSys.HC.HTML b/public/Wb/HomeSys.HC.HTML new file mode 100755 index 0000000..87bea8d --- /dev/null +++ b/public/Wb/HomeSys.HC.HTML @@ -0,0 +1,69 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+U0 UserStartUp()
+{//Run each time a user a spawned
+  DocTermNew;
+  Type("::/Doc/Start.DD");
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+  Dir;
+}
+
+U0 SrvStartUp()
+{//Run each time a srv task is spawned.
+  DocTermNew;
+  LBts(&Fs->display_flags,DISPLAYf_SHOW);
+  WinToTop;
+  WinZBufUpdate;
+}
+
+U0 StartUpTasks()
+{
+  CTask *user1,*user2;
+  user1=User;
+  user2=User;
+  WinToTop(user1);
+  WinTileVert;
+  "Boot Time:%7.3fs\n",tS;
+  XTalk(user1,"Cd;#include \"Once\";\n");
+  Silent;       //no output to scrn
+  ACInit("/*;!*/Bible.TXT*");
+  Silent(OFF); //no output to scrn
+}
+
+StartUpTasks;
+
+"\nTempleOS V%5.3f\t%D %T\n\n",sys_os_version,sys_compile_time,sys_compile_time;
+
+ diff --git a/public/Wb/HomeWrappers.HC.HTML b/public/Wb/HomeWrappers.HC.HTML new file mode 100755 index 0000000..2bc49ad --- /dev/null +++ b/public/Wb/HomeWrappers.HC.HTML @@ -0,0 +1,57 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+#help_index "Cmd Line (Typically)"
+
+//These are customized quick commands.
+//Feel free to add more or change.
+public I64 F(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in all text files.
+  return Find(needle_str,"/*",fu_flags);
+}
+
+public I64 R(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in all text files.
+  return Find(needle_str,"/*",fu_flags,replace_text);
+}
+
+public I64 FD(U8 *needle_str,U8 *fu_flags=NULL)
+{//Find text in cur dir text files.
+  return Find(needle_str,"*",fu_flags);
+}
+
+public I64 RD(U8 *needle_str,U8 *replace_text=NULL,U8 *fu_flags="+l-i")
+{//Find text and replace in cur dir text files.
+  return Find(needle_str,"*",fu_flags,replace_text);
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskATA.HC.HTML b/public/Wb/Kernel/BlkDev/DskATA.HC.HTML new file mode 100755 index 0000000..67d794f --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskATA.HC.HTML @@ -0,0 +1,642 @@ + + + + + + + + + + + +
+U0 ATABlkSel(CBlkDev *bd,I64 blk,I64 cnt)
+{
+  if (bd->type!=BDT_ATAPI && bd->base1)
+    OutU8(bd->base1+ATAR1_CTRL,0x8);
+  if (bd->flags & BDF_EXT_SIZE) { //48 Bit LBA?
+    OutU8(bd->base0+ATAR0_NSECT,cnt.u8[1]);
+    OutU8(bd->base0+ATAR0_SECT,blk.u8[3]);
+    OutU8(bd->base0+ATAR0_LCYL,blk.u8[4]);
+    OutU8(bd->base0+ATAR0_HCYL,blk.u8[5]);
+    OutU8(bd->base0+ATAR0_NSECT,cnt);
+    OutU8(bd->base0+ATAR0_SECT,blk);
+    OutU8(bd->base0+ATAR0_LCYL,blk.u8[1]);
+    OutU8(bd->base0+ATAR0_HCYL,blk.u8[2]);
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  } else { //28 Bit LBA
+    OutU8(bd->base0+ATAR0_NSECT,cnt);
+    OutU8(bd->base0+ATAR0_SECT,blk);
+    OutU8(bd->base0+ATAR0_LCYL,blk.u8[1]);
+    OutU8(bd->base0+ATAR0_HCYL,blk.u8[2]);
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4|blk.u8[3]);
+  }
+}
+
+Bool ATAWaitNotBUSY(CBlkDev *bd,F64 timeout)
+{
+  I64 i;
+  do {
+    for (i=0;i<3;i++)
+      if (!(InU8(bd->base0+ATAR0_STAT)&ATAS_BSY))
+        return TRUE;
+    Yield;
+  } while (!(0<timeout<tS));
+  return FALSE;
+}
+
+Bool ATAWaitDRQ(CBlkDev *bd,F64 timeout)
+{
+  I64 i;
+  do {
+    for (i=0;i<3;i++)
+      if (InU8(bd->base0+ATAR0_STAT)&ATAS_DRQ)
+        return TRUE;
+    Yield;
+  } while (!(0<timeout<tS));
+  return FALSE;
+}
+
+Bool ATANop(CBlkDev *bd,F64 timeout)
+{
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_FEAT,0);
+  OutU8(bd->base0+ATAR0_CMD,ATA_NOP);
+  return ATAWaitNotBUSY(bd,timeout);
+}
+
+U0 ATACmd(CBlkDev *bd,U8 cmd)
+{
+  OutU8(bd->base0+ATAR0_FEAT,0);
+  OutU8(bd->base0+ATAR0_CMD,cmd);
+  bd->last_time=tS;
+  PortNop;
+}
+
+Bool ATAGetRes(CBlkDev *bd,F64 timeout,U8 *buf,I64 cnt,
+                I64 _avail,Bool one_read)
+{
+  I64 avail,overflow;
+  bd->flags&=~BDF_LAST_WAS_WRITE;
+  MemSet(buf,0,cnt);
+  while (cnt>0) {
+    if (!ATAWaitDRQ(bd,timeout))
+      return FALSE;
+    if (_avail)
+      avail=_avail;
+    else
+      avail=InU8(bd->base0+ATAR0_HCYL)<<8+InU8(bd->base0+ATAR0_LCYL);
+    if (avail) {
+      if (avail>cnt) {
+        overflow=avail-cnt;
+        avail=cnt;
+      } else
+        overflow=0;
+      if (avail&2)
+        RepInU16(buf,avail>>1,bd->base0+ATAR0_DATA);
+      else
+        RepInU32(buf,avail>>2,bd->base0+ATAR0_DATA);
+      cnt-=avail;
+      buf+=avail;
+      while (overflow>0) {
+        InU16(bd->base0+ATAR0_DATA);
+        overflow-=2;
+        if (0<timeout<tS)
+          return FALSE;
+      }
+      if (one_read)
+        break;
+    } else
+      Yield;
+  }
+  return ATAWaitNotBUSY(bd,timeout);
+}
+
+Bool ATAPIWritePktWord(CBlkDev *bd,F64 timeout,...)
+{
+  I64 i;
+  for (i=0;i<argc;i++) {
+    if (!ATAWaitDRQ(bd,timeout))
+      return FALSE;
+    OutU16(bd->base0+ATAR0_DATA,EndianU16(argv[i]));
+    bd->last_time=tS;
+  }
+  return TRUE;
+}
+
+Bool ATAPISetMaxSpeed(CBlkDev *bd)
+{
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,0);
+  OutU8(bd->base0+ATAR0_HCYL,0);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0xBB00,0xFFFF,0xFFFF,0,0,0);
+  return ATAWaitNotBUSY(bd,0);
+}
+
+Bool ATAPISeek(CBlkDev *bd,I64 native_blk)
+{
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,0);
+  OutU8(bd->base0+ATAR0_HCYL,0);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0x2B00,native_blk>>16,native_blk,0,0,0);
+  return ATAWaitNotBUSY(bd,0);
+}
+
+Bool ATAPIStartStop(CBlkDev *bd,F64 timeout,Bool start)
+{
+  I64 i;
+  if (start)
+    i=0x100;
+  else
+    i=0;
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  ATACmd(bd,ATA_PACKET);
+//Start/Stop
+  if (ATAPIWritePktWord(bd,timeout,0x1B00,0,i,0,0,0))
+    return ATAWaitNotBUSY(bd,timeout);
+  else
+    return FALSE;
+}
+
+I64 ATAGetDevId(CBlkDev *bd,F64 timeout,Bool keep_id_record)
+{
+  I64 res=BDT_NULL;
+  U16 *id_record=NULL;
+  if (bd->type!=BDT_ATAPI && bd->base1)
+    OutU8(bd->base1+ATAR1_CTRL,0x8);
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  ATACmd(bd,ATA_ID_DEV);
+  if (ATAWaitNotBUSY(bd,timeout)) {
+    if (InU8(bd->base0+ATAR0_STAT)&ATAS_ERR)
+      res=BDT_ATAPI;
+    else {
+      id_record=ACAlloc(512);
+      if (ATAGetRes(bd,timeout,id_record,512,512,FALSE))
+        res=BDT_ATA;
+      else {
+        Free(id_record);
+        id_record=NULL;
+      }
+    }
+  }
+  if (keep_id_record) {
+     Free(bd->dev_id_record);
+     bd->dev_id_record=id_record;
+  }
+  return res;
+}
+
+I64 ATAReadNativeMax(CBlkDev *bd,F64 timeout)
+{//Returns zero on err
+  I64 res=0;
+  Bool okay=TRUE;
+  if (bd->type==BDT_ATAPI) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    ATACmd(bd,ATA_DEV_RST);
+    if (!ATAWaitNotBUSY(bd,0))
+      okay=FALSE;
+  } else {
+    while (InU8(bd->base0+ATAR0_STAT) & ATAS_BSY) {
+      if (bd->flags&BDF_LAST_WAS_WRITE)
+        OutU16(bd->base0+ATAR0_DATA,0);
+      else
+        InU16(bd->base0+ATAR0_DATA);
+      Yield;
+      if (0<timeout<tS)
+        return FALSE;
+    }
+    if (ATAGetDevId(bd,timeout,TRUE)==BDT_NULL)
+      okay=FALSE;
+    else
+      BEqu(&bd->flags,BDf_EXT_SIZE,Bt(&bd->dev_id_record[86],10));
+  }
+  if (okay) {
+    if (bd->flags & BDF_EXT_SIZE && bd->base1) {
+      OutU8(bd->base1+ATAR1_CTRL,0x8);
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+      ATACmd(bd,ATA_READ_NATIVE_MAX_EXT);
+      if (ATAWaitNotBUSY(bd,timeout)) {
+        res.u8[0]=InU8(bd->base0+ATAR0_SECT);
+        res.u8[1]=InU8(bd->base0+ATAR0_LCYL);
+        res.u8[2]=InU8(bd->base0+ATAR0_HCYL);
+
+        OutU8(bd->base1+ATAR1_CTRL,0x80);
+        res.u8[3]=InU8(bd->base0+ATAR0_SECT);
+        res.u8[4]=InU8(bd->base0+ATAR0_LCYL);
+        res.u8[5]=InU8(bd->base0+ATAR0_HCYL);
+
+        if (res>>24==res&0xFFFFFF) {//Kludge to make QEMU work
+          bd->flags&=~BDF_EXT_SIZE;
+          res&=0xFFFFFF;
+        }
+      }
+    } else {
+      if (bd->type!=BDT_ATAPI && bd->base1)
+        OutU8(bd->base1+ATAR1_CTRL,0x8);
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+      ATACmd(bd,ATA_READ_NATIVE_MAX);
+      if (ATAWaitNotBUSY(bd,timeout)) {
+        res.u8[0]=InU8(bd->base0+ATAR0_SECT);
+        res.u8[1]=InU8(bd->base0+ATAR0_LCYL);
+        res.u8[2]=InU8(bd->base0+ATAR0_HCYL);
+        res.u8[3]=InU8(bd->base0+ATAR0_SEL) & 0xF;
+      }
+    }
+  }
+  return bd->max_blk=res;
+}
+
+I64 ATAPIReadCapacity(CBlkDev *bd,I64 *_blk_size=NULL)
+{//Supposedly this can return a res +/- 75 sects.
+//Error might just be for music.
+  Bool unlock=BlkDevLock(bd);
+  U32 buf[2];
+  if (ATAWaitNotBUSY(bd,0)) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,8);
+    OutU8(bd->base0+ATAR0_HCYL,0);
+    ATACmd(bd,ATA_PACKET);
+    ATAPIWritePktWord(bd,0,0x2500,0,0,0,0,0);
+    if (!ATAGetRes(bd,0,buf,8,0,TRUE))
+      buf[0]=buf[1]=0;
+  } else
+    buf[0]=buf[1]=0;
+
+  if (unlock) BlkDevUnlock(bd);
+  if (_blk_size) *_blk_size=EndianU32(buf[1]);
+  return EndianU32(buf[0]);
+}
+
+CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bd,I64 blk)
+{
+  CATAPITrack *res=CAlloc(sizeof(CATAPITrack));
+  Bool unlock=BlkDevLock(bd);
+  if (ATAWaitNotBUSY(bd,0)) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,sizeof(CATAPITrack)&0xFF);
+    OutU8(bd->base0+ATAR0_HCYL,sizeof(CATAPITrack)>>8);
+    ATACmd(bd,ATA_PACKET);
+    ATAPIWritePktWord(bd,0,0x5200,blk.u16[1],blk.u16[0],
+          (sizeof(CATAPITrack)&0xFF00)>>8,(sizeof(CATAPITrack)&0x00FF)<<8,0);
+    if (!ATAGetRes(bd,0,res,sizeof(CATAPITrack),0,TRUE)) {
+      Free(res);
+      res=NULL;
+    }
+  } else {
+    Free(res);
+    res=NULL;
+  }
+  if (unlock) BlkDevUnlock(bd);
+  return res;
+}
+
+Bool ATAInit(CBlkDev *bd)
+{
+  Bool unlock=BlkDevLock(bd),okay=FALSE;
+
+  if (bd->type==BDT_ATAPI)
+    bd->flags&=~BDF_EXT_SIZE;
+  else
+    bd->flags|=BDF_EXT_SIZE;
+
+  if (ATAReadNativeMax(bd,tS+0.1)) {
+    ATABlkSel(bd,bd->max_blk,0);
+    if (bd->flags&BDF_EXT_SIZE)
+      ATACmd(bd,ATA_SET_MAX_EXT);
+    else
+      ATACmd(bd,ATA_SET_MAX);
+    if (ATAWaitNotBUSY(bd,0)) {
+      okay=TRUE;
+      if (bd->type==BDT_ATAPI) {
+        if (ATAPIStartStop(bd,0,TRUE)) {
+          if(!ATAPISetMaxSpeed(bd))
+            okay=FALSE;
+        } else
+          okay=FALSE;
+      }
+    }
+  }
+  if (unlock) BlkDevUnlock(bd);
+  return okay;
+}
+
+Bool ATAPIWaitReady(CBlkDev *bd,F64 timeout)
+{
+  do {
+    if (!ATAWaitNotBUSY(bd,timeout) ||
+          !ATANop(bd,timeout) ||
+          !ATAPIStartStop(bd,timeout,TRUE))
+      return FALSE;
+    if (InU8(bd->base0+ATAR0_STAT) & ATAS_DRDY &&
+          !InU8(bd->base0+ATAR0_FEAT));
+    return TRUE;
+    ATAInit(bd);
+    Yield;
+  } while (!(0<timeout<tS));
+  return FALSE;
+}
+
+U0 ATAReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt)
+{
+  I64 retries=3;
+  Bool unlock=BlkDevLock(bd);
+
+  retry:
+  ATABlkSel(bd,blk,cnt);
+  if (bd->flags & BDF_EXT_SIZE)
+    ATACmd(bd,ATA_READ_MULTI_EXT);
+  else
+    ATACmd(bd,ATA_READ_MULTI);
+  if (!ATAGetRes(bd,tS+1.0,buf,cnt*bd->blk_size,BLK_SIZE,FALSE)) {
+    if (retries--) {
+      ATAWaitNotBUSY(bd,0);
+      goto retry;
+    } else
+      throw('BlkDev');
+  }
+
+  blkdev.read_cnt+=(cnt*bd->blk_size)>>BLK_SIZE_BITS;
+  if (unlock) BlkDevUnlock(bd);
+}
+
+I64 ATAProbe(I64 base0,I64 base1,I64 unit)
+{
+  CBlkDev bd;
+  MemSet(&bd,0,sizeof(CBlkDev));
+  bd.type=BDT_ATAPI;
+  bd.base0=base0;
+  bd.base1=base1;
+  bd.unit=unit;
+  bd.blk_size=DVD_BLK_SIZE;
+  return ATAGetDevId(&bd,tS+0.1,FALSE);
+}
+
+Bool ATAPIReadBlks2(CBlkDev *bd,F64 timeout,U8 *buf,
+                I64 native_blk, I64 cnt,Bool lock)
+{
+  Bool res=FALSE,unlock;
+  if (cnt<=0)
+    return FALSE;
+  if (lock)
+    unlock=BlkDevLock(bd);
+  if (ATAPIWaitReady(bd,timeout)) {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,bd->blk_size);
+    OutU8(bd->base0+ATAR0_HCYL,bd->blk_size.u8[1]);
+    ATACmd(bd,ATA_PACKET);
+    if (ATAPIWritePktWord(bd,timeout,0xA800,
+          native_blk.u16[1],native_blk,cnt.u16[1],cnt,0) &&
+          ATAGetRes(bd,timeout,buf,cnt*bd->blk_size,0,FALSE)) {
+      blkdev.read_cnt+=(cnt*bd->blk_size)>>BLK_SIZE_BITS;
+      res=TRUE;
+    }
+  }
+//  ATAPIStartStop(bd,0,FALSE);
+  if (lock && unlock) BlkDevUnlock(bd);
+  return res;
+}
+
+U0 ATAPIReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt)
+{
+  CDrv *dv=Let2Drv(bd->first_drv_let);
+  I64 retry,spc=bd->blk_size>>BLK_SIZE_BITS,n,blk2,
+        l2=bd->max_reads<<1+spc<<1;
+  U8 *dvd_buf=MAlloc(l2<<BLK_SIZE_BITS);
+  if (cnt>0) {
+    if (blk<=bd->max_reads)
+      blk2=0;
+    else
+      blk2=FloorU64(blk-bd->max_reads,spc);
+    if (blk2+l2>dv->size+dv->drv_offset)
+      l2=dv->size+dv->drv_offset-blk2;
+    n=(l2+spc-1)/spc;
+
+    retry=4;
+    while (--retry)
+      if (ATAPIReadBlks2(bd,tS+7.0+0.004*n,dvd_buf,blk2/spc,n,TRUE))
+//n is 0x800 if max_reads.  Up to 8 additional seconds
+        break;
+    if (!retry)
+      ATAPIReadBlks2(bd,0,dvd_buf,blk2/spc,n,TRUE);
+    if (bd->flags & BDF_READ_CACHE)
+      DskCacheAdd(dv,dvd_buf,blk2,n*spc);
+    MemCpy(buf,dvd_buf+(blk-blk2)<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
+  }
+  Free(dvd_buf);
+}
+
+Bool ATARBlks(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{
+  I64 n;
+  CBlkDev *bd=dv->bd;
+  while (cnt>0) {
+    n=cnt;
+    if (n>bd->max_reads)
+      n=bd->max_reads;
+    if (bd->type==BDT_ATAPI)
+      ATAPIReadBlks(bd,buf,blk,n);
+    else
+      ATAReadBlks(bd,buf,blk,n);
+    buf+=n<<BLK_SIZE_BITS;
+    blk+=n;
+    cnt-=n;
+  }
+  return TRUE;
+}
+
+U0 ATAWriteBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt)
+{//For low level disk access.
+//Use BlkWrite() instead.
+  I64 i,U32s_avail,sects_avail,retries=3;
+  F64 timeout;
+  Bool unlock=BlkDevLock(bd);
+retry:
+  ATABlkSel(bd,blk,cnt);
+  if (bd->flags&BDF_EXT_SIZE)
+    ATACmd(bd,ATA_WRITE_MULTI_EXT);
+  else
+    ATACmd(bd,ATA_WRITE_MULTI);
+  bd->flags|=BDF_LAST_WAS_WRITE;
+  while (cnt>0) {
+    timeout=tS+1.0;
+    while (TRUE) {
+      i=InU8(bd->base0+ATAR0_STAT);
+      if (!(i & ATAS_DRDY)||!(i & ATAS_DRQ)) {
+        Yield;
+      } else
+        break;
+      if (/* i&ATAS_ERR||*/ tS>timeout) {
+        if (retries--) {
+          ATAWaitNotBUSY(bd,0);
+          goto retry;
+        } else
+          throw('BlkDev');
+      }
+    }
+    sects_avail=1;
+    U32s_avail=sects_avail<<BLK_SIZE_BITS>>2;
+    RepOutU32(buf,U32s_avail,bd->base0+ATAR0_DATA);
+    buf+=U32s_avail<<2;
+    cnt-=sects_avail;
+    retries=3;
+  }
+  ATAWaitNotBUSY(bd,0);
+  if (unlock) BlkDevUnlock(bd);
+}
+
+Bool ATAPISync(CBlkDev *bd)
+{
+  Bool okay=TRUE;
+  if (!ATAWaitNotBUSY(bd,0))
+    okay=FALSE;
+  else {
+    if (bd->flags & BDF_EXT_SIZE)
+      OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+    else
+      OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+    OutU8(bd->base0+ATAR0_LCYL,0);
+    OutU8(bd->base0+ATAR0_HCYL,0);
+    ATACmd(bd,ATA_PACKET);
+    ATAPIWritePktWord(bd,0,0x3500,0,0,0,0,0);
+    if (!ATAWaitNotBUSY(bd,0))
+      okay=FALSE;
+  }
+  return okay;
+}
+
+U0 ATAPIClose(CBlkDev *bd,I64 close_field=0x200,I64 track=0)
+{//0x200 CD/DVD part 1
+// 0x300    DVD part 2
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,0);
+  OutU8(bd->base0+ATAR0_HCYL,0);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0x5B00,close_field,track,0,0,0);
+  ATAWaitNotBUSY(bd,0);
+}
+
+U0 ATAPIWriteBlks(CBlkDev *bd,U8 *buf, I64 native_blk, I64 cnt)
+{
+  I64 U32s_avail;
+  U8 *buf2;
+  ATAWaitNotBUSY(bd,0);
+  ATAPISeek(bd,native_blk);
+
+  OutU8(bd->base0+ATAR0_FEAT,0);
+  OutU8(bd->base0+ATAR0_LCYL,bd->blk_size);
+  OutU8(bd->base0+ATAR0_HCYL,bd->blk_size.u8[1]);
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_CMD,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0x0400,native_blk.u16[1],native_blk,cnt.u16[1],cnt,0);
+  bd->flags|=BDF_LAST_WAS_WRITE;
+  ATAWaitNotBUSY(bd,0);
+
+  ATAPISeek(bd,native_blk);
+
+  if (bd->flags & BDF_EXT_SIZE)
+    OutU8(bd->base0+ATAR0_SEL,0xEF|bd->unit<<4);
+  else
+    OutU8(bd->base0+ATAR0_SEL,0xE0|bd->unit<<4);
+  OutU8(bd->base0+ATAR0_LCYL,bd->blk_size);
+  OutU8(bd->base0+ATAR0_HCYL,bd->blk_size.u8[1]);
+  ATACmd(bd,ATA_PACKET);
+  ATAPIWritePktWord(bd,0,0xAA00,native_blk.u16[1],native_blk,cnt.u16[1],cnt,0);
+  buf2=buf+bd->blk_size*cnt;
+  while (buf<buf2) {
+    ATAWaitDRQ(bd,0);
+    U32s_avail=(InU8(bd->base0+ATAR0_HCYL)<<8+InU8(bd->base0+ATAR0_LCYL))>>2;
+    if (buf+U32s_avail<<2>buf2)
+      U32s_avail=(buf2-buf)>>2;
+    if (U32s_avail) {
+      RepOutU32(buf,U32s_avail,bd->base0+ATAR0_DATA);
+      buf+=U32s_avail<<2;
+      blkdev.write_cnt+=U32s_avail>>(BLK_SIZE_BITS-2);
+    }
+  }
+  ATAWaitNotBUSY(bd,0);
+}
+
+Bool ATAWBlks(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{
+  I64 n,spc;
+  CBlkDev *bd=dv->bd;
+  Bool unlock;
+  spc=bd->blk_size>>BLK_SIZE_BITS;
+  if (bd->type==BDT_ATAPI) {
+    unlock=BlkDevLock(bd);
+    ATAPIWaitReady(bd,0);
+  }
+  while (cnt>0) {
+    n=cnt;
+    if (n>bd->max_writes)
+      n=bd->max_writes;
+    if (bd->type==BDT_ATAPI)
+      ATAPIWriteBlks(bd,buf,blk/spc,(n+spc-1)/spc);
+    else
+      ATAWriteBlks(bd,buf,blk,n);
+    buf+=n<<BLK_SIZE_BITS;
+    blk+=n;
+    cnt-=n;
+    blkdev.write_cnt+=n;
+  }
+  if (bd->type==BDT_ATAPI) {
+    ATAPISync(bd);
+//    ATAPIStartStop(bd,0,FALSE);
+    if (unlock) BlkDevUnlock(bd);
+  }
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskATAId.HC.HTML b/public/Wb/Kernel/BlkDev/DskATAId.HC.HTML new file mode 100755 index 0000000..e9871dc --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskATAId.HC.HTML @@ -0,0 +1,324 @@ + + + + + + + + + + + +
+Bool BootDVDProbe(CBlkDev *bd)
+{
+  U8 *img=CAlloc(DVD_BLK_SIZE);
+  I64 i;
+  Bool res=FALSE;
+  "Port: %04X,%04X Unit: %02X  ",bd->base0,bd->base1,bd->unit;
+  if (ATAProbe(bd->base0,bd->base1,bd->unit)==BDT_ATAPI) {
+    " ATAPI";
+    if (ATAPIStartStop(bd,tS+5.0,TRUE)) {
+      " Started";
+      for (i=0;i<2;i++) {//Retry
+        if (ATAPIReadBlks2(bd,tS+7.0,img,sys_boot_blk,1,FALSE)) {
+          if ((img+sys_boot_src.u16[1]<<BLK_SIZE_BITS)(CKernel *)
+                ->compile_time==sys_compile_time) {
+            " Found\n";
+            return TRUE;
+          } else
+            " Read";
+        } else
+          " NoRead";
+      }
+    }
+  }
+  " Nope\n";
+  Free(img);
+  return res;
+}
+
+Bool BootDVDProbeAll(CBlkDev *bd)
+{
+  I64 d1,d2,i,j,k;
+
+  bd->base1=0;
+  for (k=0;k<256;k++) {
+    i=-1;
+    while (TRUE) {
+      j=PCIClassFind(0x010100+k,++i);
+      if (j<0)
+        break;
+      "Subcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
+      d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
+      d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
+      if (d1&1 && d2&1) {
+        if (bd->base0=d1&~7) {
+          bd->unit=0;
+          if (BootDVDProbe(bd))
+            return TRUE;
+          bd->unit=1;
+          if (BootDVDProbe(bd))
+            return TRUE;
+        }
+      }
+      d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
+      d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
+      if (d1&1 && d2&1) {
+        if (bd->base0=d1&~7) {
+          bd->unit=0;
+          if (BootDVDProbe(bd))
+            return TRUE;
+          bd->unit=1;
+          if (BootDVDProbe(bd))
+            return TRUE;
+        }
+      }
+    }
+  }
+
+  d1=0x1F0;
+  d2=0x3F6;
+  if (bd->base0=d1&~7) {
+    bd->unit=0;
+    if (BootDVDProbe(bd))
+      return TRUE;
+    bd->unit=1;
+    if (BootDVDProbe(bd))
+      return TRUE;
+  }
+
+  d1=0x170;
+  d2=0x376;
+  if (bd->base0=d1&~7) {
+    bd->unit=0;
+    if (BootDVDProbe(bd))
+      return TRUE;
+    bd->unit=1;
+    if (BootDVDProbe(bd))
+      return TRUE;
+  }
+}
+
+U0 ATARepEntry(I64 base0,I64 base1,I64 unit,U8 *msg,
+        CATARep **_head,I64 *num_hints)
+{
+  I64 type;
+  base0&=-8;
+  base1&=-4;
+  CATARep *tmpha;
+  if (type=ATAProbe(base0,base1,unit)) {
+    *num_hints+=1;
+    "\n$PURPLE$ $BT+X,\"%d\",LM=\"%d\\n\"$$FG$$LM,4$",*num_hints,*num_hints;
+    if (type==BDT_ATA)
+      "$RED$Hard Drive   $LTBLUE$ATA   ";
+    else
+      "$RED$CD/DVD Drive $LTBLUE$ATAPI ";
+    "%s$FG$\n",msg;
+    if (base0==blkdev.ins_base0 && unit==blkdev.ins_unit)
+      "$PURPLE$(Drive originally installed from.)$FG$\n";
+    "Base0:0x%04X Base1:0x%04X Unit:%d$LM,0$\n",
+          base0,base1,unit;
+    if (_head) {
+      tmpha=CAlloc(sizeof(CATARep));
+      tmpha->next=*_head;
+      *_head=tmpha;
+      tmpha->num=*num_hints;
+      tmpha->type=type;
+      tmpha->base0=base0;
+      tmpha->base1=base1;
+      tmpha->unit=unit;
+    }
+  }
+}
+
+Bool ATARepExitAllApplications()
+{
+  "\nWe're going to probe hardware.\n"
+        "$RED$Exit all other applications.$FG$\n"
+        "Press '$PURPLE$p$FG$' to probe or '$PURPLE$s$FG$' to skip.\n";
+  if (ToUpper(GetChar(,FALSE))=='S')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+public I64 ATARep(Bool pmt=TRUE,Bool just_ide=FALSE,CATARep **_head=NULL)
+{//Report possible ATA devices by probing.  Hard disks and CD/DVDs.
+  I64 d1,d2,i,j,k,cnt=0,unlock_flags=0,num_hints=0;
+#assert BLKDEVS_NUM<=64
+  if (_head) *_head=NULL;
+
+  if (pmt && ATARepExitAllApplications)
+    return 0;
+
+  for (i=0;i<BLKDEVS_NUM;i++)
+    if (blkdev.blkdevs[i].bd_signature==BD_SIGNATURE_VAL)
+      BEqu(&unlock_flags,i,
+            BlkDevLock(&blkdev.blkdevs[i]));
+
+  if (!just_ide)
+    for (k=0;k<256;k++) {
+      i=-1;
+      while (TRUE) {
+        j=PCIClassFind(0x010100+k,++i);
+        if (j<0)
+          break;
+
+        "\nSubcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
+        cnt++;
+
+        d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
+        d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
+        if (d1&1 && d2&1) {
+          ATARepEntry(d1,d2,0,"Primary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Primary IDE",_head,&num_hints);
+        } else {
+          d1=0x1F0; d2=0x3F6;
+          ATARepEntry(d1,d2,0,"Primary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Primary IDE",_head,&num_hints);
+        }
+        d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
+        d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
+        if (d1&1 && d2&1) {
+          ATARepEntry(d1,d2,0,"Secondary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Secondary IDE",_head,&num_hints);
+        } else {
+          d1=0x170; d2=0x376;
+          ATARepEntry(d1,d2,0,"Secondary IDE",_head,&num_hints);
+          ATARepEntry(d1,d2,1,"Secondary IDE",_head,&num_hints);
+        }
+      }
+    }
+  if (!cnt) {
+    d1=0x1F0; d2=0x3F6;
+    ATARepEntry(d1,d2,0,"Primary IDE",_head,&num_hints);
+    ATARepEntry(d1,d2,1,"Primary IDE",_head,&num_hints);
+
+    d1=0x170; d2=0x376;
+    ATARepEntry(d1,d2,0,"Secondary IDE",_head,&num_hints);
+    ATARepEntry(d1,d2,1,"Secondary IDE",_head,&num_hints);
+  }
+  '\n\n';
+  for (i=0;i<BLKDEVS_NUM;i++)
+    if (Bt(&unlock_flags,i))
+      BlkDevUnlock(&blkdev.blkdevs[i]);
+  return num_hints;
+}
+
+CATARep *ATARepFind(CATARep *haystack_head,I64 needle_num)
+{
+  while (haystack_head) {
+    if (haystack_head->num==needle_num)
+      return haystack_head;
+    haystack_head=haystack_head->next;
+  }
+  return NULL;
+}
+
+CATARep *ATAIDDrvs(CATARep *head,CATARep **_ata_drv,CATARep **_atapi_drv)
+{//This is for when trying to sort-out main hard drives and CD/DVD drives.
+  CATARep *res=NULL,*tmpha=head,*ata_drv=NULL,*atapi_drv=NULL;
+  CBlkDev *bd;
+  Bool was_silent=Silent,ins_found=FALSE;
+  bd=Let2BlkDev(':',FALSE);
+  Silent(was_silent);
+  while (tmpha) {
+    if (!res && bd && bd->type==tmpha->type) {
+      if (bd->type==BDT_ATAPI &&
+            bd->base0==tmpha->base0 && bd->unit==tmpha->unit)
+        res=atapi_drv=tmpha;
+      else if (bd->type==BDT_ATA && bd->base0==tmpha->base0 &&
+            bd->base1==tmpha->base1 && bd->unit==tmpha->unit)
+        res=ata_drv=tmpha;
+    }
+    if (!res || res->type!=tmpha->type) {
+      if (tmpha->type==BDT_ATA) {
+        if (!ata_drv || tmpha->unit<ata_drv->unit ||
+              tmpha->unit==ata_drv->unit && tmpha->num<ata_drv->num)
+          ata_drv=tmpha;
+      } else if (tmpha->type==BDT_ATAPI) {
+        if (!atapi_drv || !ins_found && (tmpha->unit<atapi_drv->unit ||
+              tmpha->unit==atapi_drv->unit && tmpha->num<atapi_drv->num))
+          atapi_drv=tmpha;
+      }
+    }
+    if (tmpha->type==BDT_ATAPI && bd && bd->type==BDT_ATA &&
+      tmpha->base0==blkdev.ins_base0 && tmpha->unit==blkdev.ins_unit) {
+      if (!ins_found) {
+        atapi_drv=tmpha;
+        ins_found=TRUE;
+      }
+    }
+    tmpha=tmpha->next;
+  }
+  if (_ata_drv)   *_ata_drv  =ata_drv;
+  if (_atapi_drv) *_atapi_drv=atapi_drv;
+  return res;
+}
+
+CBlkDev *ATAMount(U8 first_drv_let,I64 type,I64 base0,I64 base1,I64 unit)
+{
+  CBlkDev *res;
+  if (0<=first_drv_let-'A'<DRVS_NUM && (type==BDT_ATA || type==BDT_ATAPI) &&
+        0<=unit<=1) {
+    res=BlkDevNextFreeSlot(first_drv_let,type);
+    res->unit=unit;
+    res->base0=base0;
+    res->base1=base1;
+    if (BlkDevAdd(res,,FALSE,FALSE))
+      return res;
+  }
+  return NULL;
+}
+
+I64 MountIDEAuto()
+{//Try to mount hard drive and CD/DVD, automatically. (Kernel.Cfg option).
+//It uses 'C' and 'T' as first drive letters or whatever you set
+  //in config when compiling Kernel.BIN.
+  I64 res=0;
+  CATARep *head=NULL,*ata_drv=NULL,*atapi_drv=NULL,*tmpha;
+  ATARep(FALSE,TRUE,&head);
+  ATAIDDrvs(head,&ata_drv,&atapi_drv);
+  if (ata_drv && ATAMount(blkdev.first_hd_drv_let,BDT_ATA,
+        ata_drv->base0,ata_drv->base1,ata_drv->unit))
+    res++;
+  if (atapi_drv && ATAMount(blkdev.first_dvd_drv_let,BDT_ATAPI,
+        atapi_drv->base0,atapi_drv->base1,atapi_drv->unit))
+    res++;
+  tmpha=head;
+  while (tmpha) {
+    if (tmpha!=ata_drv && tmpha!=atapi_drv) {
+      if (tmpha->type==BDT_ATA && ATAMount(blkdev.first_hd_drv_let,BDT_ATA,
+            tmpha->base0,tmpha->base1,tmpha->unit))
+        res++;
+      else if (tmpha->type==BDT_ATAPI &&
+            ATAMount(blkdev.first_dvd_drv_let,BDT_ATAPI,
+            tmpha->base0,tmpha->base1,tmpha->unit))
+        res++;
+    }
+    tmpha=tmpha->next;
+  }
+  LinkedLstDel(head);
+  blkdev.mount_ide_auto_cnt=res;
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskAddDev.HC.HTML b/public/Wb/Kernel/BlkDev/DskAddDev.HC.HTML new file mode 100755 index 0000000..7a06c67 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskAddDev.HC.HTML @@ -0,0 +1,271 @@ + + + + + + + + + + + +
+U0 BlkDevLockFwdingSet(CBlkDev *bd)
+{  //If two blkdevs on same controller, use just one lock
+  CBlkDev *bd1;
+  I64 i;
+  switch (bd->type) {
+    case BDT_RAM:
+      break;
+    case BDT_ISO_FILE_READ:
+    case BDT_ISO_FILE_WRITE:
+      bd->lock_fwding=Let2BlkDev(*bd->file_dsk_name);
+      break;
+    case BDT_ATA:
+    case BDT_ATAPI:
+      for (i=0;i<BLKDEVS_NUM;i++) {
+        bd1=&blkdev.blkdevs[i];
+        if (bd1->bd_signature==BD_SIGNATURE_VAL && bd!=bd1 &&
+              (bd1->type==BDT_ATAPI || bd1->type==BDT_ATA) &&
+              bd1->base0==bd->base0) {
+          bd->lock_fwding=bd1;
+          break;
+        }
+      }
+      break;
+  }
+}
+
+I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN,
+        Bool whole_drv,Bool make_free)
+{//It will mount just one partition of prt_num>=0.
+//When repartitioing whole drive, whole_drv=TRUE.
+  I64 i,j,ext_base,offset,res=0,num=0;
+  CDrv *dv;
+  CRedSeaBoot br;
+  CMasterBoot mbr;
+
+  bd->bd_signature=BD_SIGNATURE_VAL;
+  if (make_free)
+    dv=DrvMakeFreeSlot(bd->first_drv_let);
+  else
+    dv=DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let));
+  dv->bd=bd;
+  dv->drv_offset=bd->drv_offset;
+  dv->size=bd->max_blk+1-bd->drv_offset;
+  switch (bd->type) {
+    case BDT_RAM:
+    case BDT_ISO_FILE_READ:
+    case BDT_ISO_FILE_WRITE:
+      dv->dv_signature=DRV_SIGNATURE_VAL;
+      dv->prt_num=num;
+      dv->fs_type=FSt_REDSEA;
+//This is to force creation of a RAM
+      //drive during boot, so it is probably
+      //MAlloced to the same addr and can
+      //be assumed to be already formatted.
+      //If this line is removed, RAM Drives
+      //will be alloced on a just-in-time
+      //basis.
+      if (BlkDevInit(bd))
+        res++;
+      else
+        dv->dv_signature=0;
+      break;
+    case BDT_ATA:
+      dv->dv_signature=DRV_SIGNATURE_VAL; //Temporarily validate
+      if (!BlkDevInit(bd))
+        dv->dv_signature=0; //Revoke validation
+      else {
+        dv->dv_signature=0; //Revoke validation
+        if (whole_drv) {
+          dv->dv_signature=DRV_SIGNATURE_VAL;
+          dv->prt_num=num;
+          res++;
+          dv->fs_type=FSt_REDSEA;
+          dv->size=bd->max_blk+1-bd->drv_offset;
+//The following read is a test read.
+          //if it hangs, the drive is not supported.
+          ATAReadBlks(bd,&mbr,0,1);
+          break;
+        }
+        offset=0;
+        ext_base=INVALID_CLUS;
+        while (prt_num<0 || num<=prt_num) {
+          ATAReadBlks(bd,&mbr,offset,1);
+          if (mbr.signature!=0xAA55)
+            break;
+          j=-1;
+          for (i=0;i<4 && (prt_num<0 || num<=prt_num);i++) {
+            if (mbr.p[i].type) {
+              if (make_free)
+                dv=DrvMakeFreeSlot(bd->first_drv_let+res);
+              else
+                dv=DrvMakeFreeSlot(DrvNextFreeLet(bd->first_drv_let+res));
+              dv->bd=bd;
+              dv->drv_offset=mbr.p[i].offset+offset;
+              dv->size  =mbr.p[i].size;
+              switch (mbr.p[i].type) {
+                case MBR_PT_REDSEA:
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  dv->fs_type=FSt_REDSEA;
+                  RedSeaInit(dv);
+                  break;
+                case MBR_PT_FAT32a:
+                case MBR_PT_FAT32b:
+                case MBR_PT_FAT32c:
+                case MBR_PT_FAT32d:
+                case MBR_PT_FAT32e:
+                case MBR_PT_FAT32f:
+                  ATAReadBlks(bd,&br,dv->drv_offset,1);
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  if (br.signature==MBR_PT_REDSEA) {
+                    dv->fs_type=FSt_REDSEA;
+                    RedSeaInit(dv);
+                  } else {
+                    dv->fs_type=FSt_FAT32;
+                    FAT32Init(dv);
+                  }
+                  break;
+                case MBR_PT_NTFS:
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  dv->fs_type=FSt_NTFS;
+                  break;
+                case 5:
+                case 15:
+                  j=i;
+                  break;
+                default:
+                  dv->dv_signature=DRV_SIGNATURE_VAL;
+                  dv->prt_num=num;
+                  res++;
+                  dv->fs_type=FSt_UNKNOWN;
+              }
+              num++;
+            }
+          }
+          if (Let2BlkDevType(bd->first_drv_let+res)!=bd->type)
+            break;
+          if (j<0)
+            break;
+          if (!mbr.p[j].offset)
+            break;
+          if (ext_base==INVALID_CLUS) {
+            offset=mbr.p[j].offset;
+            ext_base=offset;
+          } else
+            offset=mbr.p[j].offset+ext_base;
+        }
+      }
+      break;
+    case BDT_ATAPI:
+      dv->dv_signature=DRV_SIGNATURE_VAL;
+      dv->prt_num=num;
+      res++;
+      dv->fs_type=FSt_ISO9660; //Start with this
+      dv->size=0;
+      break;
+  }
+  if (res)
+    BlkDevLockFwdingSet(bd);
+  else
+    BlkDevDel(bd);
+  return res;
+}
+
+Bool DrvEnable(U8 drv_let,Bool val)
+{//Can unmount or remount, but not mount the first time.
+  CDrv *dv;
+  if (dv=Let2Drv(drv_let,FALSE))
+    return !LBEqu(&dv->fs_type,FStf_DISABLE,!val);
+  else
+    return FALSE;
+}
+
+I64 SysGetI64()
+{
+  U8 st[STR_LEN];
+  GetS(st,STR_LEN,FALSE);
+  return Str2I64(st,16);
+}
+
+Bool GetBaseUnit(CBlkDev *bd)
+{
+  I64 ch;
+  Bool probe;
+  #exe {
+    if (kernel_cfg->opts[CFG_DONT_PROBE])
+      StreamPrint("probe=FALSE;");
+    else
+      StreamPrint("probe=TRUE;");
+  };
+  if (!probe || !BootDVDProbeAll(bd)) {
+    "\nDon't worry.  This is not a product\n"
+          "registration.        TempleOS just needs the\n"
+          "I/O port numbers for the CD/DVD.\n"
+          "\nRetry the ports above or check Windows\n"
+          "system information under I/O ports for\n"
+          "'IDE', 'ATA' or 'SATA'.\n"
+          "In Linux, use 'lspci -v' for ports.\n"
+          "\n\nEnter 4-digit hex I/O Port number.\n"
+          "CD/DVD I/O Port Base0: 0x";
+    bd->base0=SysGetI64;
+    bd->base1=0;
+    bd->unit =0;
+    if (bd->base0) {
+      "\nUnit (0 or 1): ";
+      do ch=GetChar(,FALSE);
+      while (!('0'<=ch<='1'));
+      '' ch;
+      bd->unit=ch-'0';
+      blkdev.dvd_boot_is_good=BootDVDProbe(bd);
+      return TRUE;
+    } else {
+      blkdev.dvd_boot_is_good=FALSE;
+      return FALSE;
+    }
+  }
+  return FALSE;
+}
+
+U0 BlkDevsInitAll()
+{
+  CBlkDev *bd;
+  I64 i;
+  blkdev.blkdevs=CAlloc(sizeof(CBlkDev)*BLKDEVS_NUM);
+  blkdev.drvs=CAlloc(sizeof(CDrv)*DRVS_NUM);
+  for (i=0;i<DRVS_NUM;i++)
+    blkdev.let_to_drv[i]=&blkdev.drvs[i];
+  #exe {
+    if (kernel_cfg->opts[CFG_MOUNT_IDE_AUTO])
+      StreamPrint("MountIDEAuto;");
+    StreamPrint("#exe {Option(OPTf_WARN_PAREN,OFF);}");
+    StreamDoc(kernel_cfg->add_dev);
+    StreamPrint("#exe {Option(OPTf_WARN_PAREN,ON);}");
+  };
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskBlk.HC.HTML b/public/Wb/Kernel/BlkDev/DskBlk.HC.HTML new file mode 100755 index 0000000..f9fa4df --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskBlk.HC.HTML @@ -0,0 +1,140 @@ + + + + + + + + + + + +
+#define ZERO_BUF_SIZE   2048
+U0 BlkWriteZero(CDrv *dv,I64 blk,I64 cnt)
+{//Fill blk cnt with zeros in Drv.
+  I64 n;
+  U8 *z=CAlloc(ZERO_BUF_SIZE<<BLK_SIZE_BITS);
+  Bool show_progress;
+  if (cnt>ZERO_BUF_SIZE && dv->bd->type!=BDT_RAM) {
+    progress1=0; progress1_max=cnt;
+    StrCpy(progress1_desc,"Zeroing");
+    show_progress=TRUE;
+  } else
+    show_progress=FALSE;
+  while (cnt>0) {
+    n=cnt;
+    if (n>ZERO_BUF_SIZE)
+      n=ZERO_BUF_SIZE;
+    BlkWrite(dv,z,blk,n);
+    blk+=n;
+    cnt-=n;
+    if (show_progress)
+      progress1+=n;
+    Yield;  //Prevent locking
+  }
+  Free(z);
+  if (show_progress) {
+    *progress1_desc=0;
+    progress1=progress1_max=0;
+  }
+}
+
+Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{//Read blk cnt from Drv to buf.
+  Bool res=TRUE,unlock;
+  CBlkDev *bd=dv->bd;
+  if (cnt<=0) return TRUE;
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    BlkDevInit(bd);
+    if (dv->drv_offset && blk<dv->drv_offset ||
+          blk+cnt>dv->drv_offset+dv->size)
+      throw('Drv');
+    if (bd->flags & BDF_READ_CACHE)
+      RCache(dv,&buf,&blk,&cnt);
+    if (cnt>0) {
+      switch (bd->type) {
+        case BDT_RAM:
+          MemCpy(buf,bd->RAM_dsk+blk<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
+          break;
+        case BDT_ISO_FILE_READ:
+        case BDT_ISO_FILE_WRITE:
+          FBlkRead(bd->file_dsk,buf,blk,cnt);
+          break;
+        case BDT_ATA:
+        case BDT_ATAPI:
+          res=ATARBlks(dv,buf,blk,cnt);
+          break;
+      }
+      bd->last_time=tS;
+      if (bd->flags & BDF_READ_CACHE)
+        DskCacheAdd(dv,buf,blk,cnt);
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return res;
+}
+
+Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{//Write blk cnt from buf to Drv.
+  Bool res=TRUE,unlock;
+  CBlkDev *bd=dv->bd;
+  if (cnt<=0) return TRUE;
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    BlkDevInit(bd);
+    if (bd->flags&BDF_READ_ONLY && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
+      throw('BlkDev');
+    if (dv->drv_offset && blk<dv->drv_offset ||
+          blk+cnt>dv->drv_offset+dv->size)
+      throw('Drv');
+    if (cnt>0) {
+      switch (bd->type) {
+        case BDT_RAM:
+          MemCpy(bd->RAM_dsk+blk<<BLK_SIZE_BITS,buf,cnt<<BLK_SIZE_BITS);
+          break;
+        case BDT_ISO_FILE_READ:
+        case BDT_ISO_FILE_WRITE:
+          FBlkWrite(bd->file_dsk,buf,blk,cnt);
+          break;
+        case BDT_ATA:
+        case BDT_ATAPI:
+          res=ATAWBlks(dv,buf,blk,cnt);
+          break;
+      }
+      bd->last_time=tS;
+      if (bd->flags & BDF_READ_CACHE)
+        DskCacheAdd(dv,buf,blk,cnt);
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskBlkDev.HC.HTML b/public/Wb/Kernel/BlkDev/DskBlkDev.HC.HTML new file mode 100755 index 0000000..aa34a8f --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskBlkDev.HC.HTML @@ -0,0 +1,218 @@ + + + + + + + + + + + +
+Bool BlkDevLock(CBlkDev *bd)
+{//Make this task have exclusive access to BlkDev.
+  BlkDevChk(bd);
+  while (bd->lock_fwding)
+    bd=bd->lock_fwding; //If two blkdevs on same controller, use just one lock
+  if (!Bt(&bd->locked_flags,BDlf_LOCKED) || bd->owning_task!=Fs) {
+    while (LBts(&bd->locked_flags,BDlf_LOCKED))
+      Yield;
+    bd->owning_task=Fs;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE)
+{//Release exclusive lock on access to BlkDev.
+  BlkDevChk(bd);
+  while (bd->lock_fwding)
+    bd=bd->lock_fwding; //If two blkdevs on same controller, use just one lock
+  if (Bt(&bd->locked_flags,BDlf_LOCKED) && bd->owning_task==Fs) {
+    if (rst)
+      bd->flags&=~(BDF_INITIALIZED|BDF_INIT_IN_PROGRESS);
+    bd->owning_task=NULL;
+    LBtr(&bd->locked_flags,BDlf_LOCKED);
+    Yield; //Prevent deadlock
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool BlkDevInit(CBlkDev *bd)
+{
+  CDirEntry de;
+  U8 buf[STR_LEN];
+  CDrv *dv=Let2Drv(bd->first_drv_let);
+  Bool res=FALSE;
+  if (!LBts(&bd->flags,BDf_INITIALIZED)) {
+    bd->flags|=BDF_INIT_IN_PROGRESS;
+    switch (bd->type) {
+      case BDT_RAM:
+        if (!bd->RAM_dsk) {
+          bd->RAM_dsk=AMAlloc((bd->max_blk+1)<<BLK_SIZE_BITS);
+          bd->max_blk=MSize(bd->RAM_dsk)>>BLK_SIZE_BITS-1;
+        }
+        dv->fs_type=FSt_REDSEA;
+        dv->size=bd->max_blk+1-bd->drv_offset;
+        if (RedSeaValidate(bd->first_drv_let))
+          RedSeaInit(dv);
+        else
+          RedSeaFmt(bd->first_drv_let);
+        res=TRUE;
+        break;
+      case BDT_ISO_FILE_READ:
+        if (FileFind(bd->file_dsk_name,&de,FUF_JUST_FILES)) {
+          bd->max_blk=de.size>>BLK_SIZE_BITS-1;
+          try bd->file_dsk=FOpen(bd->file_dsk_name,"rc",bd->max_blk+1);
+          catch {
+            if (Fs->except_ch=='File')
+              PrintErr("Not Contiguous.  Move file to filename.ISO.C.\n");
+            Fs->catch_except=TRUE;
+          }
+          if (bd->file_dsk) {
+            dv->fs_type=FSt_REDSEA;
+            dv->size=bd->max_blk+1-bd->drv_offset;
+            if (RedSeaValidate(bd->first_drv_let)) {
+              RedSeaInit(dv);
+              res=TRUE;
+            } else
+              PrintErr("Not RedSea\n");
+          }
+        }
+        break;
+      case BDT_ISO_FILE_WRITE:
+        if (!bd->file_dsk_name) {
+          StrPrint(buf,"%C:/Drv%C.ISO.C",
+                blkdev.boot_drv_let,bd->first_drv_let);
+          bd->file_dsk_name=AStrNew(buf);
+        }
+        if (bd->max_blk<7)
+          bd->max_blk=7;
+        bd->file_dsk=FOpen(bd->file_dsk_name,"wc",bd->max_blk+1);
+        dv->fs_type=FSt_REDSEA;
+        dv->size=bd->max_blk+1-bd->drv_offset;
+        RedSeaFmt(bd->first_drv_let);
+        CallExtStr("RedSeaISO9660",bd->file_dsk_name,bd->first_drv_let);
+        res=TRUE;
+        break;
+      case BDT_ATA:
+        bd->max_reads=128;
+        bd->max_writes=1;
+        res=ATAInit(bd);
+        break;
+      case BDT_ATAPI:
+//0xFFFF*4 is too big for my taste
+        bd->max_reads=0x800*4;
+//max of maybe a quarter of disk cache
+        if (bd->max_reads>blkdev.cache_size/BLK_SIZE/4)
+          bd->max_reads=blkdev.cache_size/BLK_SIZE/4 & ~3;
+        if (bd->max_reads<128)
+          bd->max_reads=128;
+        bd->max_writes=0xFFFF*4;
+        if (res=ATAInit(bd))
+          dv->size=bd->max_blk+1;
+        break;
+    }
+    if (res && bd->flags & BDF_READ_CACHE)
+      DskCacheInvalidate(dv);
+    bd->flags&=~BDF_INIT_IN_PROGRESS;
+  } else
+    res=TRUE;
+  return res;
+}
+
+U0 BlkDevsRelease()
+{//When task dies, release all owned BlkDevs.
+  I64 i;
+  CBlkDev *bd;
+  for (i=0;i<BLKDEVS_NUM;i++) {
+    bd=&blkdev.blkdevs[i];
+    if (bd->owning_task==Fs && bd->bd_signature==BD_SIGNATURE_VAL)
+      BlkDevUnlock(bd,TRUE);
+  }
+}
+
+CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type)
+{//Locate free slot for new BlkDev, like during Mount().
+  I64 i=0;
+  CBlkDev *res;
+  if (Let2BlkDevType(first_drv_let)!=type)
+    throw('BlkDev');
+  do {
+    res=&blkdev.blkdevs[i];
+    if (res->bd_signature!=BD_SIGNATURE_VAL) {
+      MemSet(res,0,sizeof(CBlkDev));
+      res->first_drv_let=first_drv_let;
+      res->type=type;
+      res->flags=BDF_READ_CACHE;
+      res->blk_size=BLK_SIZE;
+      res->max_blk=0xEFFFFFFF;
+      switch (type) {
+        case BDT_RAM:
+          res->flags&=~BDF_READ_CACHE;
+          break;
+        case BDT_ISO_FILE_READ:
+          res->flags|=BDF_READ_ONLY;
+          break;
+        case BDT_ATAPI:
+          res->flags|=BDF_REMOVABLE|BDF_READ_ONLY;
+          res->blk_size=DVD_BLK_SIZE;
+          break;
+      }
+      return res;
+    }
+  } while (++i<BLKDEVS_NUM);
+  throw('BlkDev');
+  return NULL; //never gets here
+}
+
+U0 BlkDevDel(CBlkDev *bd)
+{//Delete BlkDev
+  DrvBlkDevDel(bd);
+  FClose(bd->file_dsk);
+  Free(bd->file_dsk_name);
+  Free(bd->dev_id_record);
+  MemSet(bd,0,sizeof(CBlkDev));
+}
+
+CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE)
+{//Check for valid BlkDev. Throw exception.
+  if (!bd || bd->bd_signature!=BD_SIGNATURE_VAL ||
+        !(BDT_NULL<bd->type<BDT_TYPES_NUM)) {
+    if (except)
+      throw('BlkDev');
+    else
+      return NULL;
+  } else
+    return bd;
+}
+
+CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE)
+{//Drv letter to BlkDev ptr.
+  CDrv *dv;
+  if (dv=Let2Drv(drv_let,except))
+    return BlkDevChk(dv->bd,except);
+  else
+    return NULL;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskCDDVD.HC.HTML b/public/Wb/Kernel/BlkDev/DskCDDVD.HC.HTML new file mode 100755 index 0000000..cb953a3 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskCDDVD.HC.HTML @@ -0,0 +1,274 @@ + + + + + + + + + + + +
+Bool ISOInit(CDrv *dv,I64 blk)
+{
+  CBlkDev *bd=dv->bd;
+  I64 spc=bd->blk_size>>BLK_SIZE_BITS,i=blk/spc,drv_offset=0;
+  CISOPriDesc *iso=MAlloc(bd->blk_size);
+  CISODirEntry *de;
+  Bool unlock,res=FALSE;
+  U8 buf[8];
+
+  try {
+    unlock=DrvLock(dv);
+    dv->fs_type=FSt_ISO9660;
+    dv->spc=spc;
+    dv->data_area=dv->root_clus=dv->drv_offset=bd->drv_offset=dv->size=0;
+    while (TRUE) {
+      dv->size=MaxI64(dv->size,(i+1)*spc);
+      BlkRead(dv,iso,i*spc,spc);
+      buf[0](U32)=iso->id[0](U32);
+      buf[4](U16)=iso->id[4](U8);
+      switch (LstMatch(buf,"CD001\0CDW02\0BEA01\0BOOT2\0NSR02\0NSR03\0TEA01\0",
+            LMF_EXACT)) {
+        case 0:
+          switch (iso->type) {
+            case ISOT_BOOT_RECORD:
+              drv_offset+=(2*DVD_BLK_SIZE+DVD_BLK_SIZE)/BLK_SIZE;
+              break;
+            case ISOT_SUPPLEMENTARY_DESC:
+              de=&iso->root_dir_record;
+              dv->size=iso->vol_space_size.little*bd->blk_size>>BLK_SIZE_BITS;
+              if (!StrCmp(iso->publisher_id,"TempleOS RedSea")) {
+                dv->fs_type=FSt_REDSEA;
+                bd->drv_offset=dv->drv_offset=19<<2+drv_offset;
+                bd->max_blk=dv->size-1;
+                dv->size-=bd->drv_offset;
+                RedSeaInit(dv);
+              } else
+                dv->root_clus=de->loc.little;
+              res=TRUE;
+              goto di_done;
+            case ISOT_TERMINATOR:
+              throw('Drv');
+          }
+          break;
+        default: //Its normal for ISO3346 to read NULL blk as terminator
+          PrintErr("File System Not Supported\n");
+          throw('Drv');
+      }
+      i++;
+    }
+di_done:
+    Free(iso);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch {
+    dv->fs_type=FSt_ISO9660;
+    dv->spc=spc;
+    dv->drv_offset=bd->drv_offset=dv->data_area=dv->root_clus=0;
+    Free(iso);
+    if (unlock)
+      DrvUnlock(dv);
+  }
+  return res;
+}
+
+U0 DVDImageRead(U8 dvd_drv_let,U8 *out_name)
+{//Read entire CD/DVD image into ISO file.
+  CDrv *dv=Let2Drv(dvd_drv_let);
+  CBlkDev *bd=dv->bd;
+  U8 *buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS),
+        *out_name2=ExtDft(out_name,"ISO");
+  CFile *f=FOpen(out_name2,"w");
+  I64 n,spc=bd->blk_size>>BLK_SIZE_BITS,blk=0,cnt,retry;
+  BlkDevInit(bd);
+  if (bd->type!=BDT_ATAPI)
+    throw('BlkDev');
+  if (!out_name)
+    out_name=blkdev.dft_iso_filename;
+  cnt=CeilU64(dv->size,spc);
+  while (cnt>0) {
+    if (cnt>COPY_BUF_BLKS)
+      n=COPY_BUF_BLKS;
+    else
+      n=cnt;
+    if (n>bd->max_reads)
+      n=bd->max_reads;
+
+    retry=4;
+    while (--retry)
+      if (ATAPIReadBlks2(bd,tS+7.0+0.004*n/spc,buf,blk/spc,n/spc,TRUE))
+//n is 0x800 if max_reads.  Up to 8 additional seconds
+        break;
+
+    if (!retry)
+      ATAPIReadBlks2(bd,0,buf,blk/spc,n/spc,TRUE);
+
+    FBlkWrite(f,buf,blk,n);
+    cnt-=n;
+    blk+=n;
+  }
+  FClose(f);
+  Free(buf);
+  Free(out_name2);
+}
+
+class CDualBuf
+{
+  U8 *buf0,*buf1;
+  I64 in_buf,out_buf,cnt;
+  U8 *filename;
+  CBlkDev *dvd_bd;
+};
+
+U0 DVDImageWriteTask(CDualBuf *d)
+{
+  U8 *buf;
+  I64 n,blk=0,cnt=d->cnt;
+  CFile *f;
+  if (FileAttr(d->filename)&RS_ATTR_CONTIGUOUS)
+    f=FOpen(d->filename,"rc");
+  else
+    f=FOpen(d->filename,"r");
+  while (cnt>0) {
+    if (cnt>COPY_BUF_BLKS)
+      n=COPY_BUF_BLKS;
+    else
+      n=cnt;
+    if (n>d->dvd_bd->max_writes)
+      n=d->dvd_bd->max_writes;
+    if (d->in_buf&1)
+      buf=d->buf1;
+    else
+      buf=d->buf0;
+    while (d->in_buf>d->out_buf+1)
+      Yield;
+    FBlkRead(f,buf,blk,n);
+    d->in_buf++;
+    cnt-=n;
+    blk+=n;
+  }
+  FClose(f);
+}
+
+U0 DVDImageWrite(U8 dvd_drv_let,U8 *in_name=NULL,I64 media_type=MT_DVD)
+{//Write CD/DVD ISO file to disk.
+  CDualBuf *d=CAlloc(sizeof(CDualBuf));
+  U8 *buf,*in_name2,*in_name3;
+  I64 i,n,spc,blk=0,cnt;
+  CDrv *dv=Let2Drv(dvd_drv_let);
+  CBlkDev *bd=dv->bd,*bd2;
+  CTask *task;
+  CFile *f;
+
+  if (!in_name)
+    in_name=blkdev.dft_iso_filename;
+  in_name3=ExtDft(in_name,"ISO");
+  in_name2=FileNameAbs(in_name3);
+  f=FOpen(in_name2,"r");
+  if (!f) {
+    Free(d);
+    return;
+  }
+  cnt=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS;
+  FClose(f);
+  if (bd->type!=BDT_ATAPI)
+    throw('BlkDev');
+  bd2=Let2BlkDev(*in_name2);
+  while (bd2->lock_fwding)
+    bd2=bd2->lock_fwding;  //If two blkdevs on same controller, use one lock
+  if ((bd2->type==BDT_ATA || bd2->type==BDT_ATAPI) &&
+        bd2->base0==bd->base0) {
+    PrintErr("Can't burn CD/DVD on same ATA controller as file.\n\n");
+    throw('BlkDev');
+  }
+
+  bd->flags|=BDF_READ_ONLY_OVERRIDE;
+  BlkDevInit(bd);
+  spc=bd->blk_size>>BLK_SIZE_BITS;
+  if (dv->size<cnt)
+    dv->size=cnt;
+
+  d->filename=in_name2;
+  d->dvd_bd=bd;
+  d->buf0=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
+  d->buf1=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
+  d->cnt=cnt;
+
+  task=Spawn(&DVDImageWriteTask,d,"Write CD/DVD");
+  while (d->in_buf<=d->out_buf)
+    Yield;
+
+  BlkDevLock(bd);
+  ATAPIWaitReady(bd,0);
+
+  progress1=0; progress1_max=cnt;
+  StrCpy(progress1_desc,"Writing");
+  while (cnt>0) {
+    if (cnt>COPY_BUF_BLKS)
+      n=COPY_BUF_BLKS;
+    else
+      n=cnt;
+    if (n>bd->max_writes)
+      n=bd->max_writes;
+    if (d->out_buf&1)
+      buf=d->buf1;
+    else
+      buf=d->buf0;
+    while (d->in_buf<=d->out_buf)
+      Yield;
+    ATAPIWriteBlks(bd,buf,blk/spc,(n+spc-1)/spc);
+    d->out_buf++;
+    cnt-=n;
+    blk+=n;
+    progress1+=n;
+  }
+  ATAPISync(bd);
+
+  progress1=0; progress1_max=2;
+  StrCpy(progress1_desc,"Closing");
+  for (i=0;i<2;i++) {
+    ATAPIClose(bd,0x100,i); //Close tracks
+    progress1++;
+  }
+
+  ATAPISync(bd);
+
+  ATAPIClose(bd,0x200); //close disk
+  ATAPISync(bd);
+  if (media_type==MT_DVD) {
+    ATAPIClose(bd,0x300);
+    ATAPISync(bd);
+  }
+
+  *progress1_desc=0;
+  progress1=progress1_max=0;
+
+  bd->flags&=~BDF_READ_ONLY_OVERRIDE;
+  BlkDevUnlock(bd);
+  Free(d->buf0);
+  Free(d->buf1);
+  Free(in_name2);
+  Free(in_name3);
+  Free(d);
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskCFile.HC.HTML b/public/Wb/Kernel/BlkDev/DskCFile.HC.HTML new file mode 100755 index 0000000..3515493 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskCFile.HC.HTML @@ -0,0 +1,296 @@ + + + + + + + + + + + +
+I64 FSize(CFile *f)
+{//Report size of opened file in bytes.
+  if (f)
+    return f->de.size;
+  else
+    return 0;
+}
+
+CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0)
+{//Allows flags "r","w","w+". "c" for contiguous.
+//(It uses StrOcc() for 'w', 'r', '+', 'c')
+  CFile *f=CAlloc(sizeof(CFile));
+  CDirContext *dirc;
+  U8 *full_name;
+  Bool contiguous=StrOcc(flags,'c');
+
+  f->clus=INVALID_CLUS;
+  f->fblk_num=0;
+  if (cnt>0)
+    f->max_blk=cnt-1;
+  else
+    f->max_blk=I64_MAX;
+  f->file_clus_num=INVALID_CLUS;
+  full_name=FileNameAbs(filename);
+  f->dv=Let2Drv(*full_name);
+  if (f->dv->fs_type==FSt_REDSEA)
+    contiguous=TRUE;
+  if (contiguous) {
+    f->flags|=FF_CONTIGUOUS;
+    if (f->dv->fs_type!=FSt_REDSEA &&
+          !(FileAttr(filename) & RS_ATTR_CONTIGUOUS))
+      throw('File');
+  }
+  f->clus_buf=CAlloc(f->dv->spc<<BLK_SIZE_BITS);
+  if (StrOcc(flags,'w')) {
+    f->flags=f->flags|FF_WRITE|FF_NEEDS_WRITE;
+    if (StrOcc(flags,'+')) {
+      if (FileFind(full_name,&f->de,FUF_JUST_FILES)) {
+        Free(full_name);
+        if (contiguous)
+          f->max_blk=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS-1;
+        return f;
+      }
+    } else
+      Del(full_name,,,FALSE);
+    f->de.full_name=full_name;
+    f->flags|=FF_NEW_FILE;
+    if (dirc=DirContextNew(full_name)) {
+      StrCpy(f->de.name,dirc->mask);
+      if (cnt>0) {//We pre-alloc the whole thing.
+        f->de.clus=ClusAlloc(f->dv,0,
+              (cnt+f->dv->spc-1)/f->dv->spc,contiguous);
+        f->de.size=cnt<<BLK_SIZE_BITS;
+        DirNew(dirc->dv,Fs->cur_dir,&f->de,TRUE);
+        f->flags&=~FF_NEW_FILE;
+      }
+      DirContextDel(dirc);
+      return f;
+    }
+  } else {
+    if (FileFind(full_name,&f->de,FUF_JUST_FILES)) {
+      Free(full_name);
+      f->max_blk=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS-1;
+      return f;
+    }
+  }
+  Free(f->clus_buf);
+  Free(full_name);
+  Free(f);
+  return NULL;
+}
+
+U0 FClose(CFile *f)
+{//Close CFile, updating directory.
+  CDirContext *dirc;
+  if (f) {
+    if (f->flags & FF_BUF_DIRTY) {
+      ClusWrite(f->dv,f->clus_buf,f->clus,1);
+      f->flags&=~FF_BUF_DIRTY;
+    }
+    if (f->flags & FF_NEEDS_WRITE) {
+      if (dirc=DirContextNew(f->de.full_name)) {
+        if (!(f->flags & FF_USE_OLD_DATETIME))
+          f->de.datetime=Now;
+        if (f->flags & FF_NEW_FILE)
+          DirNew(dirc->dv,Fs->cur_dir,&f->de,TRUE);
+        else
+          DirNew(dirc->dv,Fs->cur_dir,&f->de,FALSE);
+        DirContextDel(dirc);
+      } else
+        throw('File');
+    }
+    Free(f->clus_buf);
+    Free(f->de.full_name);
+    Free(f);
+  }
+}
+
+I64 FSetClus(CFile *f,I64 c,I64 blk,Bool read)
+{
+  CDrv *dv=f->dv;
+  I64 i;
+  if (f->clus!=c) {
+    if (f->flags & FF_BUF_DIRTY) {
+      i=dv->spc;
+      if (f->max_blk!=I64_MAX) {
+        i=f->max_blk+1-f->file_clus_num*dv->spc;
+        if (i>dv->spc)
+          i=dv->spc;
+      }
+      ClusBlkWrite(dv,f->clus_buf,f->clus,i);
+      f->flags=f->flags & ~FF_BUF_DIRTY;
+    }
+    f->clus=c;
+    f->file_clus_num=blk/dv->spc;
+    if (read) {
+      i=dv->spc;
+      if (f->max_blk!=I64_MAX) {
+        i=f->max_blk+1-f->file_clus_num*dv->spc;
+        if (i>dv->spc)
+          i=dv->spc;
+      }
+      c=ClusBlkRead(dv,f->clus_buf,c,i);
+    }
+  }
+  return c;
+}
+
+Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
+{//Read [nth,n+cnt) blks of file.
+  CDrv *dv=f->dv;
+  I64 spc=dv->spc,i,j,c=f->de.clus;
+  if (!f || !dv) return FALSE;
+  if (blk==FFB_NEXT_BLK)
+    blk=f->fblk_num;
+  if (blk+cnt-1>f->max_blk)
+    return FALSE;
+  if (cnt<=0) return TRUE;
+
+  if (f->flags & FF_CONTIGUOUS) {
+    BlkRead(dv,buf,Clus2Blk(dv,c)+blk,cnt);
+    blk+=cnt;
+  } else {
+    i=blk/spc;
+    if (0<=f->file_clus_num<=i) {
+      c=f->clus;
+      i-=f->file_clus_num;
+    }
+    if (i>0)
+      c=ClusNumNext(dv,c,i);
+
+    if (i=blk%spc) {
+      c=FSetClus(f,c,blk,TRUE);
+      if (cnt<spc-i)
+        j=cnt;
+      else
+        j=spc-i;
+      MemCpy(buf,f->clus_buf+i<<BLK_SIZE_BITS,j<<BLK_SIZE_BITS);
+      buf+=j<<BLK_SIZE_BITS;
+      cnt-=j;
+      blk+=j;
+    }
+    while (cnt>=spc) {
+      c=FSetClus(f,c,blk,TRUE);
+      MemCpy(buf,f->clus_buf,spc<<BLK_SIZE_BITS);
+      buf+=spc<<BLK_SIZE_BITS;
+      cnt-=spc;
+      blk+=spc;
+    }
+    if (cnt>0) {
+      c=FSetClus(f,c,blk,TRUE);
+      MemCpy(buf,f->clus_buf,cnt<<BLK_SIZE_BITS);
+      buf+=cnt<<BLK_SIZE_BITS;
+      blk+=cnt;
+    }
+  }
+  f->fblk_num=blk;
+  return TRUE;
+}
+
+Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
+{//Write [nth,n+cnt) blks of file.
+  CDrv *dv=f->dv;
+  I64 spc=dv->spc,i,j,c=f->de.clus,c1;
+  if (!f || !dv) return FALSE;
+  if (blk==FFB_NEXT_BLK)
+    blk=f->fblk_num;
+  if (blk+cnt-1>f->max_blk)
+    return FALSE;
+  if (!(f->flags & FF_WRITE))
+    return FALSE;
+  if (cnt<=0) return TRUE;
+  if (f->flags & FF_CONTIGUOUS) {
+    BlkWrite(dv,buf,Clus2Blk(dv,c)+blk,cnt);
+    blk+=cnt;
+  } else {
+    if (!c) {
+      c=ClusAlloc(dv,0,1,FALSE);
+      f->file_clus_num=0;
+      f->clus=c;
+      f->de.clus=c;
+      f->flags|=FF_NEEDS_WRITE|FF_NEW_FILE;
+    }
+    i=blk/spc;
+    if (0<=f->file_clus_num<=i) {
+      c=f->clus;
+      i-=f->file_clus_num;
+    }
+    while (i>0) {
+      c1=c;
+      c=ClusNumNext(dv,c1,1);
+      if (c==INVALID_CLUS) {
+        c=ClusAlloc(dv,c1,i,FALSE);
+        if (i>1)
+          c=ClusNumNext(dv,c,i-1);
+        break;
+      } else
+        i--;
+    }
+
+    if (i=blk%spc) {
+      FSetClus(f,c,blk,TRUE);
+      if (cnt<spc-i)
+        j=cnt;
+      else
+        j=spc-i;
+      MemCpy(f->clus_buf+BLK_SIZE*i,buf,j<<BLK_SIZE_BITS);
+      f->flags|=FF_BUF_DIRTY;
+      buf+=j<<BLK_SIZE_BITS;
+      cnt-=j;
+      blk+=j;
+      if (cnt>0) {
+        c1=c;
+        c=ClusNumNext(dv,c1,1);
+        if (c==INVALID_CLUS)
+          c=ClusAlloc(dv,c1,1,FALSE);
+      }
+    }
+    while (cnt>=spc) {
+      FSetClus(f,c,blk,FALSE);
+      MemCpy(f->clus_buf,buf,spc<<BLK_SIZE_BITS);
+      f->flags|=FF_BUF_DIRTY;
+      buf+=spc<<BLK_SIZE_BITS;
+      cnt-=spc;
+      blk+=spc;
+      if (cnt>0) {
+        c1=c;
+        c=ClusNumNext(dv,c1,1);
+        if (c==INVALID_CLUS)
+          c=ClusAlloc(dv,c1,1,FALSE);
+      }
+    }
+    if (cnt>0) {
+      FSetClus(f,c,blk,TRUE);
+      MemCpy(f->clus_buf,buf,cnt<<BLK_SIZE_BITS);
+      f->flags|=FF_BUF_DIRTY;
+      buf+=cnt<<BLK_SIZE_BITS;
+      blk+=cnt;
+    }
+    if (f->de.size<blk<<BLK_SIZE_BITS)
+      f->de.size=blk<<BLK_SIZE_BITS;
+  }
+  f->fblk_num=blk;
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskCache.HC.HTML b/public/Wb/Kernel/BlkDev/DskCache.HC.HTML new file mode 100755 index 0000000..159b918 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskCache.HC.HTML @@ -0,0 +1,176 @@ + + + + + + + + + + + +
+U0 DskCacheInit(I64 size_in_U8s)
+{
+  CCacheBlk *tmpc;
+  I64 i,cnt;
+
+  while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+    Yield;
+  Free(blkdev.cache_ctrl);
+  Free(blkdev.cache_base);
+  Free(blkdev.cache_hash_table);
+  if (size_in_U8s<0x2000) {
+    blkdev.cache_ctrl=NULL;
+    blkdev.cache_base=NULL;
+    blkdev.cache_hash_table=NULL;
+  } else {
+    blkdev.cache_ctrl=ACAlloc(offset(CCacheBlk.body));
+    blkdev.cache_base=AMAlloc(size_in_U8s);
+    QueInit(blkdev.cache_ctrl);
+
+    cnt=MSize(blkdev.cache_base)/sizeof(CCacheBlk);
+    blkdev.cache_size=cnt*BLK_SIZE;
+    for (i=0;i<cnt;i++) {
+      tmpc=blkdev.cache_base+i;
+      QueIns(tmpc,blkdev.cache_ctrl->last_lru);
+      tmpc->next_hash=tmpc->last_hash=tmpc;
+      tmpc->dv=NULL;
+      tmpc->blk=0;
+    }
+
+    blkdev.cache_hash_table=AMAlloc(DSK_CACHE_HASH_SIZE*sizeof(U8 *)*2);
+    for (i=0;i<DSK_CACHE_HASH_SIZE;i++) {
+      tmpc=blkdev.cache_hash_table(U8 *)+i*sizeof(U8 *)*2
+            -offset(CCacheBlk.next_hash);
+      tmpc->next_hash=tmpc->last_hash=tmpc;
+    }
+  }
+  LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+}
+
+I64 DskCacheHash(I64 blk)
+{
+  I64 i=blk & (DSK_CACHE_HASH_SIZE-1);
+  return blkdev.cache_hash_table(U8 *)+i<<4-offset(CCacheBlk.next_hash);
+}
+
+U0 DskCacheQueRem(CCacheBlk *tmpc)
+{
+  QueRem(tmpc);
+  tmpc->next_hash->last_hash=tmpc->last_hash;
+  tmpc->last_hash->next_hash=tmpc->next_hash;
+}
+
+U0 DskCacheQueIns(CCacheBlk *tmpc)
+{
+  CCacheBlk *tmp_n,*tmp_l;
+  QueIns(tmpc,blkdev.cache_ctrl->last_lru);
+  tmp_l=DskCacheHash(tmpc->blk);
+  tmp_n=tmp_l->next_hash;
+  tmpc->last_hash=tmp_l;
+  tmpc->next_hash=tmp_n;
+  tmp_l->next_hash=tmp_n->last_hash=tmpc;
+}
+
+CCacheBlk *DskCacheFind(CDrv *dv,I64 blk)
+{
+  CCacheBlk *tmpc,*tmpc1=DskCacheHash(blk);
+  tmpc=tmpc1->next_hash;
+  while (tmpc!=tmpc1) {
+    if (tmpc->dv==dv && tmpc->blk==blk)
+      return tmpc;
+    tmpc=tmpc->next_hash;
+  }
+  return NULL;
+}
+
+U0 DskCacheAdd(CDrv *dv,U8 *buf, I64 blk, I64 cnt)
+{
+  CCacheBlk *tmpc;
+  if (blkdev.cache_base) {
+    while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+      Yield;
+    while (cnt-->0) {
+      if (!(tmpc=DskCacheFind(dv,blk)))
+        tmpc=blkdev.cache_ctrl->next_lru;
+      DskCacheQueRem(tmpc);
+      MemCpy(&tmpc->body,buf,BLK_SIZE);
+      tmpc->dv=dv;
+      tmpc->blk=blk;
+      DskCacheQueIns(tmpc);
+      blk++;
+      buf+=BLK_SIZE;
+    }
+    LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+  }
+}
+
+U0 DskCacheInvalidate2(CDrv *dv)
+{
+  CCacheBlk *tmpc,*tmpc1;
+  if (blkdev.cache_base) {
+    while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+      Yield;
+    tmpc=blkdev.cache_ctrl->last_lru;
+    while (tmpc!=blkdev.cache_ctrl) {
+      tmpc1=tmpc->last_lru;
+      if (tmpc->dv==dv) {
+        DskCacheQueRem(tmpc);
+        tmpc->dv=NULL;
+        tmpc->blk=0;
+        tmpc->next_hash=tmpc->last_hash=tmpc;
+        QueIns(tmpc,blkdev.cache_ctrl->last_lru);
+      }
+      tmpc=tmpc1;
+    }
+    LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+  }
+}
+
+U0 RCache(CDrv *dv,U8 **_buf, I64 *_blk, I64 *_cnt)
+{
+  CCacheBlk *tmpc;
+  if (blkdev.cache_base) {
+    while (LBts(&sys_semas[SEMA_DSK_CACHE],0))
+      Yield;
+//fetch leading blks from cache
+    while (*_cnt>0) {
+      if (tmpc=DskCacheFind(dv,*_blk)) {
+        MemCpy(*_buf,&tmpc->body,BLK_SIZE);
+        *_cnt-=1;
+        *_buf+=BLK_SIZE;
+        *_blk+=1;
+      } else
+        break;
+    }
+//fetch trailing blks from cache
+    while (*_cnt>0) {
+      if (tmpc=DskCacheFind(dv,*_blk+*_cnt-1)) {
+        MemCpy(*_buf+(*_cnt-1)<<BLK_SIZE_BITS,&tmpc->body,BLK_SIZE);
+        *_cnt-=1;
+      } else
+        break;
+    }
+    LBtr(&sys_semas[SEMA_DSK_CACHE],0);
+  }
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskClus.HC.HTML b/public/Wb/Kernel/BlkDev/DskClus.HC.HTML new file mode 100755 index 0000000..595907b --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskClus.HC.HTML @@ -0,0 +1,176 @@ + + + + + + + + + + + +
+I64 ClusNumNext(CDrv *dv,I64 c,I64 cnt=1)
+{//Return next cnt'th clus in chain.
+  Bool unlock;
+  DrvChk(dv);
+  if (cnt<=0) return c;
+  try {
+    unlock=DrvLock(dv);
+    switch (dv->fs_type) {
+      case FSt_REDSEA:
+        c+=cnt;
+        break;
+      case FSt_FAT32:
+        while (cnt-->0 && 0<c<0x0FFFFFF8) {
+          DrvFATBlkSet(dv,c);
+          c=dv->cur_fat_blk[c & (BLK_SIZE/4-1)];
+        }
+        if (!(0<c<0x0FFFFFF8))
+          c=INVALID_CLUS;
+        break;
+      default:
+        throw('Drv');
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return c;
+}
+
+I64 Clus2Blk(CDrv *dv,I64 c)
+{//Drv clus num to blk num.
+  DrvChk(dv);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      return c;
+    case FSt_FAT32:
+      return dv->data_area+c*dv->spc;
+    default:
+      throw('Drv');
+  }
+}
+
+I64 ClusBlkRead(CDrv *dv,U8 *buf,I64 c,I64 blks)
+{//Accepts blk count, so padding on last clus is not read.
+  I64 i;
+  Bool unlock;
+  DrvChk(dv);
+  if (blks<=0) return c;
+  try {
+    unlock=DrvLock(dv);
+    switch (dv->fs_type) {
+      case FSt_REDSEA:
+        BlkRead(dv,buf,c,blks);
+        c+=blks;
+        break;
+      case FSt_FAT32:
+        while (blks && 0<c<0x0FFFFFF8) {
+          i=blks;
+          if (i>dv->spc)
+            i=dv->spc;
+          BlkRead(dv,buf,dv->data_area+c*dv->spc,i);
+          buf+=i<<BLK_SIZE_BITS;
+          c=ClusNumNext(dv,c,1);
+          blks-=i;
+        }
+        if (blks)
+          throw('Drv');
+        break;
+      default:
+        throw('Drv');
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return c;
+}
+
+I64 ClusRead(CDrv *dv,U8 *buf,I64 c,I64 cnt)
+{//Read clus cnt from drv to buf.
+  return ClusBlkRead(dv,buf,c,cnt*dv->spc);
+}
+
+I64 ClusBlkWrite(CDrv *dv,U8 *buf,I64 c,I64 blks)
+{//Accepts blk count, so padding on last clus is not written.
+  I64 i;
+  Bool unlock;
+  DrvChk(dv);
+  if (blks<=0) return c;
+  try {
+    unlock=DrvLock(dv);
+    switch (dv->fs_type) {
+      case FSt_REDSEA:
+        BlkWrite(dv,buf,c,blks);
+        c=0;
+        break;
+      case FSt_FAT32:
+        while (blks) {
+          if (!(0<c<0x0FFFFFF8))
+            throw('Drv');
+          i=blks;
+          if (i>dv->spc)
+            i=dv->spc;
+          BlkWrite(dv,buf,dv->data_area+c*dv->spc,i);
+          buf+=i<<BLK_SIZE_BITS;
+          c=ClusNumNext(dv,c);
+          blks-=i;
+        }
+        break;
+      default:
+        throw('Drv');
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  return c;
+}
+
+I64 ClusWrite(CDrv *dv,U8 *buf,I64 c,I64 cnt)
+{//Write clus cnt from buf to drv.
+  return ClusBlkWrite(dv,buf,c,cnt*dv->spc);
+}
+
+I64 ClusAlloc(CDrv *dv,I64 c=0,I64 cnt=1,Bool contiguous=FALSE)
+{//Alloc clus cnt into chain.
+//c=0 means first clus in chain
+  DrvChk(dv);
+  if (cnt<=0) return c;
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      return RedSeaAllocClus(dv,cnt);
+    case FSt_FAT32:
+      if (contiguous) {
+        if (c) throw('File');
+        return FAT32AllocContiguousClus(dv,cnt);
+      } else
+        return FAT32AllocClus(dv,c,cnt);
+    default:
+      throw('Drv');
+  }
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskCopy.HC.HTML b/public/Wb/Kernel/BlkDev/DskCopy.HC.HTML new file mode 100755 index 0000000..389794f --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskCopy.HC.HTML @@ -0,0 +1,134 @@ + + + + + + + + + + + +
+Bool CopySingleZ(U8 *f1,U8 *f2) //Just one file
+{
+  U8 *file_buf=NULL;
+  I64 size,attr=0,c;
+  CDirEntry de;
+  if (FileFind(f1,&de,FUF_JUST_FILES)) {
+    Free(de.full_name);
+    file_buf=FileRead(f1,&size,&attr);
+    attr=FileAttr(f2,attr);
+    if (file_buf) {
+      "Copying %s to %s\n",f1,f2;
+      c=FileWrite(f2,file_buf,size,de.datetime,attr);
+      Free(file_buf);
+      return ToBool(c);
+    } else
+      PrintErr("File not found: \"%s\".\n",f1);
+  } else
+    PrintErr("File not found: \"%s\".\n",f1);
+  return FALSE;
+}
+
+#define COPY_BUF_BLKS   0x80
+Bool CopySingle(U8 *f1,U8 *f2) //Just one file
+{
+  U8 *absf1=FileNameAbs(f1),*absf2=FileNameAbs(f2),*buf;
+  I64 cnt,n,size,attr1=FileAttr(f1),attr2=FileAttr(f2),i,j;
+  CFile *in_file=NULL,*out_file=NULL;
+  if (!StrCmp(absf1,absf2)) {//onto self?
+    Free(absf1);
+    Free(absf2);
+    return FALSE;
+  }
+  Free(absf1);
+  Free(absf2);
+  if (attr1!=attr2)
+    return CopySingleZ(f1,f2);
+  buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
+  if (attr1 & RS_ATTR_CONTIGUOUS)
+    in_file=FOpen(f1,"rc");
+  else
+    in_file=FOpen(f1,"r");
+  if (in_file) {
+    size=FSize(in_file);
+    cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+    if (attr2 & RS_ATTR_CONTIGUOUS)
+      out_file=FOpen(f2,"wc",cnt);
+    else
+      out_file=FOpen(f2,"w",cnt);
+    if (out_file) {
+      "Copying %s to %s\n",f1,f2;
+      j=size;
+      while (cnt>0) {
+        if (cnt>COPY_BUF_BLKS) {
+          n=COPY_BUF_BLKS;
+          i=n<<BLK_SIZE_BITS;
+        } else {
+          n=cnt;
+          i=j;
+        }
+        FBlkRead(in_file, buf,FFB_NEXT_BLK,n);
+        FBlkWrite(out_file,buf,FFB_NEXT_BLK,n);
+        cnt-=n;
+        j-=n<<BLK_SIZE_BITS;
+      }
+      out_file->flags|=FF_USE_OLD_DATETIME;
+      out_file->de.datetime=in_file->de.datetime;
+      out_file->de.size=size;
+      out_file->de.attr=FileAttr(f2,in_file->de.attr);
+      FClose(out_file);
+      FClose(in_file);
+      Free(buf);
+      return TRUE;
+    } else
+      PrintErr("File not found: \"%s\".\n",f2);
+    FClose(in_file);
+  } else
+    PrintErr("File not found: \"%s\".\n",f1);
+  Free(buf);
+  return FALSE;
+}
+
+I64 Del(U8 *files_find_mask,Bool make_mask=FALSE,
+        Bool del_dir=FALSE,Bool print_msg=TRUE)
+{//Delete files.
+  I64 res=0;
+  CDirContext *dirc;
+  if (dirc=DirContextNew(files_find_mask,make_mask)) {
+    switch (dirc->dv->fs_type) {
+      case FSt_REDSEA:
+        res=RedSeaFilesDel(dirc->dv,Fs->cur_dir,dirc->mask,
+              0,del_dir,print_msg);
+        break;
+      case FSt_FAT32:
+        res=FAT32FilesDel(dirc->dv,Fs->cur_dir,dirc->mask,
+              0,del_dir,print_msg);
+        break;
+      default:
+        PrintErr("File System Not Supported\n");
+    }
+    DirContextDel(dirc);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskDirA.HC.HTML b/public/Wb/Kernel/BlkDev/DskDirA.HC.HTML new file mode 100755 index 0000000..2ef9c9f --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskDirA.HC.HTML @@ -0,0 +1,242 @@ + + + + + + + + + + + +
+Bool DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain=TRUE)
+{//Makes a directory entry in the directory from a CDirEntry node.
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      return RedSeaDirNew(dv,cur_dir,tmpde,free_old_chain);
+    case FSt_FAT32:
+      return FAT32DirNew(dv,cur_dir,tmpde,free_old_chain);
+    default:
+      PrintErr("File System Not Supported\n");
+      return FALSE;
+  }
+}
+
+U0 DirEntryDel(CDirEntry *tmpde)
+{//Free node returned from FilesFind().  Doesn't Free user_data.
+//Does not change the directory on disk.
+  if (tmpde) {
+    Free(tmpde->full_name);
+    Free(tmpde);
+  }
+}
+
+U0 DirEntryDel2(CDirEntry *tmpde)
+{//Free node returned from FilesFind().  Frees user_data
+//Does not change the directory on disk.
+  if (tmpde) {
+    Free(tmpde->full_name);
+    Free(tmpde->user_data);
+    Free(tmpde);
+  }
+}
+
+U0 DirTreeDel(CDirEntry *tmpde)
+{//Free tree returned from FilesFind().  Doesn't Free user_data.
+//Does not change the directory on disk.
+  CDirEntry *tmpde2;
+  while (tmpde) {
+    tmpde2=tmpde->next;
+    if (tmpde->sub)
+      DirTreeDel(tmpde->sub);
+    DirEntryDel(tmpde);
+    tmpde=tmpde2;
+  }
+}
+
+U0 DirTreeDel2(CDirEntry *tmpde)
+{//Free tree returned from FilesFind().  Frees user_data
+//Does not change the directory on disk.
+  CDirEntry *tmpde2;
+  while (tmpde) {
+    tmpde2=tmpde->next;
+    if (tmpde->sub)
+      DirTreeDel2(tmpde->sub);
+    DirEntryDel2(tmpde);
+    tmpde=tmpde2;
+  }
+}
+
+I64 DirEntryCompareName(CDirEntry *e1,CDirEntry *e2)
+{
+  U8 buf1[CDIR_FILENAME_LEN],buf2[CDIR_FILENAME_LEN],
+        buf3[CDIR_FILENAME_LEN],buf4[CDIR_FILENAME_LEN];
+  I64 d1=0,d2=0;
+  if (e1->attr & RS_ATTR_DIR)
+    d1=1;
+  if (e2->attr & RS_ATTR_DIR)
+    d2=1;
+  if (d1!=d2)
+    return d2-d1;
+  else {
+    StrCpy(buf1,e1->name);
+    StrCpy(buf2,e2->name);
+    FileExtRem(buf1,buf3);
+    FileExtRem(buf2,buf4);
+    if (d1=StrCmp(buf3,buf4))
+      return d1;
+    return StrCmp(buf1,buf2);
+  }
+}
+
+I64 DirEntryCompareClus(CDirEntry *e1,CDirEntry *e2)
+{
+  return e1->clus-e2->clus;
+}
+
+#define SK_NAME         0
+#define SK_CLUS 1
+
+U0 DirFilesSort(CDirEntry **_tmpde,I64 key)
+{
+  I64 i,cnt;
+  CDirEntry *tmpde=*_tmpde,*tmpde1,**sort_buf;
+  if (tmpde) {
+    cnt=LinkedLstCnt(tmpde);
+    if (cnt>1) {
+      sort_buf=MAlloc(cnt*sizeof(U8 *));
+      i=0;
+      tmpde1=tmpde;
+      while (tmpde1) {
+        sort_buf[i++]=tmpde1;
+        tmpde1=tmpde1->next;
+      }
+      switch [key] {
+        case SK_NAME:
+          QSortI64(sort_buf,cnt,&DirEntryCompareName);
+          break;
+        case SK_CLUS:
+          QSortI64(sort_buf,cnt,&DirEntryCompareClus);
+          break;
+      }
+      tmpde=sort_buf[0];
+      *_tmpde=tmpde;
+      for (i=0;i<cnt-1;i++) {
+        tmpde1=sort_buf[i];
+        tmpde1->next=sort_buf[i+1];
+      }
+      tmpde1=sort_buf[i];
+      tmpde1->next=NULL;
+      Free(sort_buf);
+
+      tmpde1=tmpde;
+      while (tmpde1) {
+        if (tmpde1->sub)
+          DirFilesSort(&tmpde1->sub,key);
+        tmpde1=tmpde1->next;
+      }
+    } else
+      if (tmpde->sub)
+        DirFilesSort(&tmpde->sub,key);
+  }
+}
+
+CDirEntry *DirFilesFlatten(CDirEntry *tmpde,CDirEntry **_res,I64 fuf_flags)
+{//Returns last node
+  CDirEntry *tmpde1;
+  Bool del;
+  if (tmpde)
+    while (TRUE) {
+      tmpde1=tmpde->next;
+      if (!(tmpde->attr&RS_ATTR_DIR)||!(fuf_flags&FUF_JUST_FILES)) {
+        _res=*_res=tmpde;
+        del=FALSE;
+      } else
+        del=TRUE;
+      if (tmpde->sub) {
+        _res=DirFilesFlatten(tmpde->sub,_res,fuf_flags);
+        tmpde->sub=NULL;
+      }
+      if (del)
+        DirEntryDel(tmpde);
+      if (tmpde1)
+        tmpde=tmpde1;
+      else
+        break;
+    }
+  *_res=NULL;
+  return _res;
+}
+
+U0 PutFileLink(U8 *filename,U8 *full_name=NULL,I64 line=0,Bool plain_text=FALSE)
+{//Put DolDoc file,line link to StdOut, DocPut.
+  U8 *st;
+  if (!filename) return;
+  if (IsRaw) {
+    if (line)
+      "%s,%04d",filename,line;
+    else
+      "%s",filename;
+  } else {
+//LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE
+    if (filename[0]=='A'&&filename[2]==':') {
+      if (line) //See SpriteEdText()
+        "$LK,\"%s,%04d\",A=\"AL:%s,%d\"$",filename+3,line,filename+3,line;
+      else
+        "$LK,\"%s\",A=\"AI:%s\"$",filename+3,filename+3;
+    } else {
+      if (!full_name)
+        full_name=st=FileNameAbs(filename);
+      else
+        st=NULL;
+      if (plain_text) {
+        if (line)
+          "$LK,\"%s,%04d\",A=\"PL:%s,%d\"$",filename,line,full_name,line;
+        else
+          "$LK,\"%s\",A=\"PI:%s\"$",filename,full_name;
+      } else {
+        if (line)
+          "$LK,\"%s,%04d\",A=\"FL:%s,%d\"$",filename,line,full_name,line;
+        else
+          "$LK,\"%s\",A=\"FI:%s\"$",filename,full_name;
+      }
+      Free(st);
+    }
+  }
+}
+
+U0 PutDirLink(U8 *dirname,U8 *full_name=NULL)
+{//Put DolDoc dir macro to StdOut, DocPut.
+  U8 *st;
+  if (!dirname) return;
+  if (IsRaw)
+    "%s",dirname;
+  else {
+    if (!full_name)
+      full_name=st=DirNameAbs(dirname);
+    else
+      st=NULL;
+    "$MA,T=\"%s\",LM=\"Cd(\\\"%s\\\");Dir;\n\"$",dirname,full_name;
+    Free(st);
+  }
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskDirB.HC.HTML b/public/Wb/Kernel/BlkDev/DskDirB.HC.HTML new file mode 100755 index 0000000..3765bee --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskDirB.HC.HTML @@ -0,0 +1,225 @@ + + + + + + + + + + + +
+U0 HomeSet(U8 *dirname)
+{//Change home directory.
+  dirname=DirNameAbs(dirname);
+  Free(blkdev.home_dir);
+  blkdev.home_dir=AStrNew(dirname);
+  Free(dirname);
+}
+
+Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE)
+{//Change directory. Optionally, make directories, too.
+  I64 maxlen,cur_dir_clus=0;
+  U8 *chg_to_buf,*new_cur_dir,*buf;
+  CDrv *dv;
+  Bool res=TRUE;
+  if (!dirname)
+    dirname="~";
+  else if (!*dirname)
+    return TRUE;
+  if (dirname[1]==':') {
+    if (*dirname==':') {
+      if (Fs->cur_dv!=Let2Drv(':') && !Drv(*dirname))
+        return FALSE;
+    } else if (Fs->cur_dv!=Let2Drv(*dirname) && !Drv(*dirname))
+      return FALSE;
+    dirname+=2;
+  }
+  if (*dirname=='/' || !*dirname || !Fs->cur_dir) {
+    Free(Fs->cur_dir);
+    Fs->cur_dir=StrNew("/");
+    if (*dirname=='/')
+      dirname++;
+  }
+  chg_to_buf=MStrUtil(dirname,
+        SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  maxlen=StrLen(Fs->cur_dir)+1+StrLen(chg_to_buf)+1;
+  new_cur_dir=MAlloc(maxlen);
+  buf=MAlloc(maxlen);
+  StrCpy(new_cur_dir,Fs->cur_dir);
+  while (*chg_to_buf && res) {
+    StrFirstRem(chg_to_buf,"/",buf);
+    if (!*buf)
+      StrCpy(new_cur_dir,"/");
+    else if (!StrCmp(buf,"..")) {
+      StrLastRem(new_cur_dir,"/");
+      if (!*new_cur_dir)
+        StrCpy(new_cur_dir,"/");
+    } else if (!StrCmp(buf,"~")) {
+      Free(new_cur_dir);
+      new_cur_dir=MAlloc(StrLen(blkdev.home_dir+2)+1+StrLen(chg_to_buf)+1);
+      StrCpy(new_cur_dir,blkdev.home_dir+2);
+      if (Fs->cur_dv!=Let2Drv('~') && !Drv('~'))
+        return FALSE;
+    } else if (StrCmp(buf,".") && *buf) {
+      dv=Fs->cur_dv;
+      cur_dir_clus=Name2DirClus(dv,new_cur_dir);
+      switch (dv->fs_type) {
+        case FSt_REDSEA:
+          res=RedSeaCd(buf,cur_dir_clus);
+          break;
+        case FSt_FAT32:
+          res=FAT32Cd(buf,cur_dir_clus);
+          break;
+        default:
+          PrintErr("File System Not Supported\n");
+          res=FALSE;
+      }
+      if (!res && make_dirs) {
+        Free(Fs->cur_dir);
+        Fs->cur_dir=StrNew(new_cur_dir);
+        res=DirMk(buf);
+      }
+      if (res) {
+        if (StrCmp(new_cur_dir,"/"))
+          CatPrint(new_cur_dir,"/");
+        CatPrint(new_cur_dir,buf);
+      }
+    }
+  }
+  Free(Fs->cur_dir);
+  Fs->cur_dir=StrNew(new_cur_dir);
+  Free(buf);
+  Free(chg_to_buf);
+  Free(new_cur_dir);
+  return res;
+}
+
+Bool IsDir(U8 *dir_name)
+{//Is a str a valid, existing Dir?
+  U8 *mask=MStrPrint("%s/*",dir_name);
+  Bool res,old_silent=Silent;
+  CDirContext *dirc;
+  if (dirc=DirContextNew(mask)) {
+    DirContextDel(dirc);
+    res=TRUE;
+  } else
+    res=FALSE;
+  Free(mask);
+  Silent(old_silent);
+  return res;
+}
+
+I64 Dir(U8 *files_find_mask,Bool full)
+{//List directory.
+  CDirEntry *tmpde1=NULL,*tmpde2;
+  U8 *st;
+  CDateStruct ds;
+  I64 csize=0xFFFF,c=0xFFFF,res=0;
+  tmpde1=FilesFind(files_find_mask);
+  if (!(st=DirCur))
+    PrintErr("Invalid Drive\n");
+  else {
+    if (tmpde1) {
+      Free(st);
+      st=MAllocIdent(tmpde1->full_name);
+      StrLastRem(st,"/");
+      if (!st[2])
+        StrCpy(st+2,"/");
+//Find max columns
+      tmpde2=tmpde1;
+      while (tmpde2) {
+        if (tmpde2->size>csize)
+          csize=tmpde2->size;
+        if (tmpde2->clus>c)
+          c=tmpde2->clus;
+        tmpde2=tmpde2->next;
+      }
+      csize=Bsr(csize)/4+1;
+      c=Bsr(c)/4+1;
+
+      "$MA,T=\"Directory\",LM=\"PopUpCd;Dir;\n\"$ of %s\n",st;
+      if (full)
+        "__DATE__ __TIME__ %*ts %*ts\n",
+              csize,"SIZE",c,"BLK";
+      else
+        "DATE_ TIME_ %*ts\n",csize,"SIZE";
+      while (tmpde1) {
+        tmpde2=tmpde1->next;
+        res++;
+        if (full)
+          "%D %T %0*tX %0*tX ",tmpde1->datetime,tmpde1->datetime,
+                csize,tmpde1->size,c,tmpde1->clus;
+        else {
+          Date2Struct(&ds,tmpde1->datetime+local_time_offset);
+          "%02d/%02d %02d:%02d %0*tX ",ds.mon,ds.day_of_mon,ds.hour,ds.min,
+                csize,tmpde1->size;
+        }
+        if (tmpde1->attr & RS_ATTR_DIR)
+          PutDirLink(tmpde1->name,tmpde1->full_name);
+        else
+          PutFileLink(tmpde1->name,tmpde1->full_name);
+        '\n';
+        DirEntryDel(tmpde1);
+        tmpde1=tmpde2;
+      }
+    } else
+      "No matching entries\n";
+    Free(st);
+  }
+  return res;
+}
+
+Bool DirMk(U8 *filename,I64 entry_cnt=0)
+{//Make directory. Cd() can also make directories.
+//entry_cnt is for preallocating dir blks, leave it zero if you like.
+  U8 *name;
+  CDirContext *dirc;
+  Bool res=FALSE;
+  if (FileFind(filename,,FUF_JUST_DIRS))
+    return FALSE;
+  if (dirc=DirContextNew(filename)) {
+    if (*dirc->mask) {
+      if (!FileNameChk(dirc->mask))
+        PrintErr("Invalid FileName: \"%s\".\n",dirc->mask);
+      else {
+        "Make Directory:%s\n",filename;
+        name=MStrUtil(dirc->mask,
+              SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+        switch (dirc->dv->fs_type) {
+          case FSt_REDSEA:
+            res=RedSeaMkDir(dirc->dv,Fs->cur_dir,name,entry_cnt);
+            break;
+          case FSt_FAT32:
+            res=FAT32MkDir(dirc->dv,Fs->cur_dir,name,entry_cnt);
+            break;
+          default:
+            PrintErr("File System Not Supported\n");
+        }
+        Free(name);
+      }
+    }
+    DirContextDel(dirc);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskDirContext.HC.HTML b/public/Wb/Kernel/BlkDev/DskDirContext.HC.HTML new file mode 100755 index 0000000..69860e1 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskDirContext.HC.HTML @@ -0,0 +1,118 @@ + + + + + + + + + + + +
+U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE)
+{//Change back to old cur_dir and drv.
+  CBlkDev *bd;
+  if (!dirc) return;
+  if (restore) {
+    bd=dirc->old_dv->bd;
+    if (!(bd->flags & BDF_INIT_IN_PROGRESS)) {
+      if (dirc->old_dir) {
+        Drv(Drv2Let(dirc->old_dv));
+        Cd(dirc->old_dir);
+      }
+    } else {
+      Fs->cur_dv=dirc->old_dv;
+      Free(Fs->cur_dir);
+      Fs->cur_dir=StrNew("/");
+    }
+  }
+  Free(dirc->old_dir);
+  Free(dirc->mask);
+  Free(dirc);
+}
+
+CDirContext *DirContextNew(U8 *_mask,Bool make_mask=FALSE,
+        Bool make_dirs=FALSE,Bool no_mask=FALSE)
+{//Save cur_dir and drv. Change to new dir.
+  Bool valid=TRUE,old_silent;
+  I64 mask_len=StrLen(_mask);
+  U8 *buf,*mask,*tmp_mask,*semicolon_mask;
+  CDirContext *dirc=CAlloc(sizeof(CDirContext));
+  dirc->old_dir=StrNew(Fs->cur_dir);
+  dirc->old_dv=Fs->cur_dv;
+  mask=MStrUtil(_mask,SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  tmp_mask=mask;
+  if (*mask && mask[1]==':') {
+    if (Fs->cur_dv!=Let2Drv(*mask) && !Drv(*mask))
+      valid=FALSE;
+    mask+=2;
+  }
+  if (*mask=='~' && Fs->cur_dv!=Let2Drv('~') && !Drv('~'))
+    valid=FALSE;
+  dirc->dv=Fs->cur_dv;
+  DrvChk(dirc->dv);
+  buf=MAlloc(mask_len+2);
+  StrCpy(buf,mask);
+
+  dirc->mask=MAlloc(mask_len+2);
+  if (no_mask)
+    *dirc->mask=0;
+  else if (StrOcc(buf,';')) {
+    semicolon_mask=MAlloc(mask_len+2);
+    StrCpy(semicolon_mask,mask);
+    StrFirstRem(semicolon_mask,";",buf);
+    StrLastRem(buf,"/",dirc->mask);
+    CatPrint(dirc->mask,";%s",semicolon_mask);
+    Free(semicolon_mask);
+  } else
+    StrLastRem(buf,"/",dirc->mask);
+
+  if (*mask=='/' && !*buf)
+    StrCpy(buf,"/");
+//If began with Dir, change to Dir.
+  if (*buf && !Cd(buf,make_dirs))
+    valid=FALSE;
+  if (valid && make_mask) {
+    if (!*dirc->mask) {
+      Free(dirc->mask);
+      dirc->mask=StrNew("*");
+    } else {
+      if (!make_dirs || FileNameChk(dirc->mask)) {
+        old_silent=Silent;
+//Try mask to see if Dir. If Dir, change to dir and set to "*".
+        if (Cd(dirc->mask,make_dirs)) {
+          Free(dirc->mask);
+          dirc->mask=StrNew("*");
+        }
+        Silent(old_silent);
+      }
+    }
+  }
+  Free(buf);
+  Free(tmp_mask);
+  if (!valid) {
+    DirContextDel(dirc);
+    dirc=NULL;
+  }
+  return dirc;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskDrv.HC.HTML b/public/Wb/Kernel/BlkDev/DskDrv.HC.HTML new file mode 100755 index 0000000..e365099 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskDrv.HC.HTML @@ -0,0 +1,397 @@ + + + + + + + + + + + +
+Bool DrvLock(CDrv *dv)
+{//Make this task have exclusive access to drv & BlkDev.
+  DrvChk(dv);
+  BlkDevLock(dv->bd);
+  if (!Bt(&dv->locked_flags,DVlf_LOCKED) || dv->owning_task!=Fs) {
+    while (LBts(&dv->locked_flags,DVlf_LOCKED))
+      Yield;
+    dv->owning_task=Fs;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool DrvUnlock(CDrv *dv,Bool rst=FALSE)
+{//Release exclusive lock on access to drv & BlkDev.
+  DrvChk(dv);
+  if (Bt(&dv->locked_flags,DVlf_LOCKED) && dv->owning_task==Fs) {
+    BlkDevUnlock(dv->bd,rst);
+    dv->owning_task=NULL;
+    LBtr(&dv->locked_flags,DVlf_LOCKED);
+    Yield; //Prevent deadlock
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 DrvsRelease()
+{//When task dies, release all owned drvs.
+  I64 i;
+  CDrv *dv;
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (dv->owning_task==Fs && dv->dv_signature==DRV_SIGNATURE_VAL)
+      DrvUnlock(dv,TRUE);
+  }
+}
+
+CDrv *DrvMakeFreeSlot(U8 drv_let)
+{//Make a slot free for a new drv, like during Mount().
+//!!! drv_let is not a remapped drv.
+  I64 i=Let2Let(drv_let)-'A';
+  CDrv *res;
+  if (!(0<=i<DRVS_NUM))
+    throw('Drv');
+  res=&blkdev.drvs[i];
+  MemSet(res,0,sizeof(CDrv));
+  res->drv_let='A'+i;
+  return res;
+}
+
+U8 DrvNextFreeLet(U8 first_drv_let='C')
+{//Locate free slot for new drv, like during Mount().
+//!!! first_drv_let is not a remapped drv.
+  I64 i=Let2Let(first_drv_let)-'A',type=Let2BlkDevType(first_drv_let);
+  if (!(0<=i<DRVS_NUM))
+    throw('Drv');
+  do
+    if (blkdev.drvs[i].dv_signature!=DRV_SIGNATURE_VAL) {
+      if (Let2BlkDevType(i+'A')!=type)
+        throw('Drv');
+      else
+        return i+'A';
+    }
+  while (++i<DRVS_NUM);
+  throw('Drv');
+  return 0; //Never gets here.
+}
+
+U0 DrvDel(CDrv *dv)
+{//Delete drv
+  if (dv->fs_type==FSt_REDSEA && dv->next_free)
+    RedSeaFreeFreeLst(dv);
+  Free(dv->cur_fat_blk);
+  Free(dv->fis);
+  MemSet(dv,0,sizeof(CDrv));
+}
+
+U0 DrvBlkDevDel(CBlkDev *bd)
+{//Delete drv's of BlkDev
+  I64 i;
+  CDrv *dv;
+  for (i=0;i<DRVS_NUM;i++) {
+    dv=&blkdev.drvs[i];
+    if (dv->bd==bd)
+      DrvDel(dv);
+  }
+}
+
+U0 DrvFATBlkAlloc(CDrv *dv)
+{
+  DrvChk(dv);
+  Free(dv->cur_fat_blk);
+  dv->cur_fat_blk=AMAlloc(BLK_SIZE);
+  dv->cur_fat_blk_num=0;
+  dv->fat_blk_dirty=0;
+  BlkRead(dv,dv->cur_fat_blk,dv->fat1,1);
+}
+
+U0 DrvFATBlkClean(CDrv *dv,I64 fat_sel=3)
+{
+  if ((dv->fs_type==FSt_FAT32 || dv->fs_type==FSt_REDSEA) &&
+       Bt(&dv->fat_blk_dirty,0)) {
+    if (dv->fat1==dv->fat2) {
+      BlkWrite(dv,dv->cur_fat_blk,dv->fat1+dv->cur_fat_blk_num,1);
+      LBtr(&dv->fat_blk_dirty,0);
+    } else {
+      if (fat_sel==3 || !fat_sel)
+        BlkWrite(dv,dv->cur_fat_blk,dv->fat1+dv->cur_fat_blk_num,1);
+      if (fat_sel==3 || fat_sel==1) {
+        BlkWrite(dv,dv->cur_fat_blk,dv->fat2+dv->cur_fat_blk_num,1);
+        LBtr(&dv->fat_blk_dirty,0);
+      }
+    }
+  }
+}
+
+U0 DrvFATBlkSet(CDrv *dv,I64 c,I64 fat_sel=3)
+{
+  I64 fat_blk_num;
+  if (c==INVALID_CLUS)
+    throw('Drv');
+  switch (dv->fs_type) {
+    case FSt_FAT32:
+      fat_blk_num=c>>(BLK_SIZE_BITS-2);
+      break;
+    case FSt_REDSEA:
+      fat_blk_num=(c-dv->data_area)>>(BLK_SIZE_BITS+3);
+      break;
+    default:
+      throw('Drv');
+  }
+  if (fat_blk_num!=dv->cur_fat_blk_num) {
+    DrvFATBlkClean(dv,fat_sel);
+    dv->cur_fat_blk_num=fat_blk_num;
+    if (fat_sel==3 || !fat_sel)
+      BlkRead(dv,dv->cur_fat_blk,dv->fat1+dv->cur_fat_blk_num,1);
+    else
+      BlkRead(dv,dv->cur_fat_blk,dv->fat2+dv->cur_fat_blk_num,1);
+  }
+}
+
+CDrv *DrvChk(CDrv *dv,Bool except=TRUE)
+{//Check for valid drv. Throw exception.
+  if (!dv || dv->dv_signature!=DRV_SIGNATURE_VAL) {
+    if (except)
+      throw('Drv');
+    else
+      return NULL;
+  } else
+    return dv;
+}
+
+U8 Drv2Let(CDrv *dv=NULL)
+{//Drv ptr to Drv letter.
+  if (!dv)
+    dv=Fs->cur_dv;
+  DrvChk(dv);
+  return dv->drv_let;
+}
+
+U8 Let2Let(U8 drv_let=0)
+{//Drv letter to Drv letter.
+  if (!drv_let)
+    drv_let=Drv2Let(Fs->cur_dv);
+  else if (drv_let==':')
+    drv_let=blkdev.boot_drv_let;
+  else if (drv_let=='~')
+    drv_let=*blkdev.home_dir;
+  return ToUpper(drv_let);
+}
+
+I64 Let2BlkDevType(U8 drv_let)
+{//Drv letter to BlkDev Type. drv_let=0 not allowed. See BDT_NULL.
+  drv_let=Let2Let(drv_let);
+  if ('A'<=drv_let<='B')
+    return BDT_RAM;
+  if ('C'<=drv_let<='L')
+    return BDT_ATA;
+  if ('M'<=drv_let<='P')
+    return BDT_ISO_FILE_READ;
+  if ('Q'<=drv_let<='S')
+    return BDT_ISO_FILE_WRITE;
+  if ('T'<=drv_let<='Z')
+    return BDT_ATAPI;
+  return BDT_NULL;
+}
+
+CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE)
+{//Drv letter to Drv ptr.
+  CDrv *dv;
+  if (!drv_let)
+    dv=Fs->cur_dv;
+  else {
+    drv_let=Let2Let(drv_let);
+    if (!('A'<=drv_let<='Z')) {
+      if (except)
+        throw('Drv');
+      else
+        return NULL;
+    }
+    dv=blkdev.let_to_drv[drv_let-'A'];
+  }
+  return DrvChk(dv,except);
+}
+
+CBlkDev *DrvIsWritable(U8 drv_let=0,Bool except=FALSE)
+{//Is drive writable?
+  CBlkDev *bd;
+  if (!(bd=Let2BlkDev(drv_let,except)) || bd->flags & BDF_READ_ONLY) {
+    if (except)
+      throw('Drv');
+    else
+      return NULL;
+  } else
+    return bd;
+}
+
+U0 DskCacheInvalidate(CDrv *dv)
+{//Needed for removable media. Called by DskChg().
+  Bool unlock;
+  CBlkDev *bd=dv->bd;
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    BlkDevInit(bd);
+    if (bd->flags & BDF_READ_CACHE)
+      DskCacheInvalidate2(dv);
+    if (bd->type==BDT_ATAPI && !(bd->flags & BDF_READ_ONLY_OVERRIDE))
+      ISOInit(dv,(32767/bd->blk_size+1)*bd->blk_size>>BLK_SIZE_BITS);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 DskChg(U8 drv_let=0)
+{//Change disk. (Needed for removable media.)
+  CDrv *dv=Let2Drv(drv_let);
+  CBlkDev *bd=dv->bd;
+  if (!(bd->flags&BDF_INITIALIZED))
+    BlkDevInit(bd);
+  else if (bd->flags&BDF_REMOVABLE) {
+    if (bd->type==BDT_ATAPI)
+      ATAInit(bd); //TODO: This is a kludge for QEMU?
+    DskCacheInvalidate(dv);
+  }
+  Drv(drv_let);
+  RedSeaFreeFreeLst(dv);
+}
+
+Bool DrvMap(U8 drv_let,CDrv *dv)
+{//Make drive letter map to another.
+  drv_let=Let2Let(drv_let);
+  if ('A'<=drv_let<='Z') {
+    blkdev.let_to_drv[drv_let-'A']=dv;
+    dv->drv_let=drv_let;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool Drv(U8 drv_let)
+{//Change drive.  You can set drive with Cd() as well.
+  CDrv *dv=Let2Drv(drv_let);
+  CBlkDev *bd;
+  bd=BlkDevChk(dv->bd);
+  if (dv!=Fs->cur_dv) {
+    if (bd->flags & BDF_REMOVABLE && !(bd->flags & BDF_INITIALIZED))
+      DskChg(Drv2Let(dv));
+    if (bd->type==BDT_RAM ||
+        bd->type==BDT_ISO_FILE_READ || bd->type==BDT_ISO_FILE_WRITE)
+      BlkDevInit(bd);
+  }
+  Fs->cur_dv=dv;
+  Free(Fs->cur_dir);
+  Fs->cur_dir=StrNew("/");
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+    case FSt_FAT32:
+      return TRUE;
+    default:
+      PrintErr("File System Not Supported\n");
+      return FALSE;
+  }
+}
+
+U8 *DrvSerialNum(U8 drv_let=0)
+{//20 bytes max.
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  U16 *st,*res=NULL;
+  I64 i;
+  if (bd->dev_id_record) {
+    st=CAlloc(20+1);
+    for (i=0;i<10;i++)
+      st[i]=EndianU16(bd->dev_id_record[10+i]);
+    res=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
+    Free(st);
+  }
+  return res;
+}
+
+U8 *DrvModelNum(U8 drv_let=0)
+{//40 bytes max.
+  CBlkDev *bd=Let2BlkDev(drv_let);
+  U16 *st,*res=NULL;
+  I64 i;
+  if (bd->dev_id_record) {
+    st=CAlloc(40+1);
+    for (i=0;i<20;i++)
+      st[i]=EndianU16(bd->dev_id_record[27+i]);
+    res=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
+    Free(st);
+  }
+  return res;
+}
+
+U8 blkdev_text_attr[BDT_TYPES_NUM]={BLACK,LTCYAN,WHITE,LTGREEN,LTRED,LTBLUE};
+U8 drv_text_attr[3]={BLACK,BLUE,RED};
+
+U8 DrvTextAttrGet(U8 drv_let=0)
+{//Get color of drive.
+  drv_let=Let2Let(drv_let);
+  if ('A'<=drv_let<='Z')
+    return blkdev_text_attr[Let2BlkDevType(drv_let)]<<4|
+          drv_text_attr[drv_let%sizeof(drv_text_attr)];
+  else
+    return BLACK<<4|WHITE;
+}
+
+U0 DrvRep()
+{//Drive report.
+  CDrv *dv;
+  CBlkDev *bd;
+  I64 ch,i,drv_let,attr;
+  U8 *st;
+  "\nDefined Drives:\n";
+  for (i=0,dv=blkdev.drvs;i<DRVS_NUM;i++,dv++) {
+    if (dv->dv_signature==DRV_SIGNATURE_VAL) {
+      bd=dv->bd;
+      drv_let=Drv2Let(dv);
+      if (Bt(&dv->fs_type,FStf_DISABLE))
+        ch='-';
+      else if (drv_let==blkdev.boot_drv_let)
+        ch=':';
+      else
+        ch='+';
+      attr=DrvTextAttrGet(drv_let);
+      "$FG,%d$$BG,%d$%C %-8Z %-10Z %04X %04X %02X\n",
+            attr&15,attr>>4,drv_let,dv->fs_type&FSG_TYPE_MASK,"ST_DRV_TYPES",
+            bd->type,"ST_BLKDEV_TYPES",bd->base0,bd->base1,bd->unit;
+      if (st=DrvModelNum(drv_let)) {
+        "   Model# :%s\n",st;
+        Free(st);
+      }
+      if (st=DrvSerialNum(drv_let)) {
+        "   Serial#:%s\n",st;
+        Free(st);
+      }
+      if (bd->type==BDT_ISO_FILE_READ || bd->type==BDT_ISO_FILE_WRITE)
+        "   File=\"%s\"\n",bd->file_dsk_name;
+      "   %016X-%016X\n$FG$$BG$",dv->drv_offset,dv->drv_offset+dv->size-1;
+    }
+  }
+  "Home Dir:\"%s\"\n",blkdev.home_dir;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskFile.HC.HTML b/public/Wb/Kernel/BlkDev/DskFile.HC.HTML new file mode 100755 index 0000000..3965bbb --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskFile.HC.HTML @@ -0,0 +1,149 @@ + + + + + + + + + + + +
+U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL)
+{//Read whole file from disk.
+  CHashGeneric *tmph;
+  U8 *absname,*altname,*curname,*res=NULL;
+  I64 i,size=0,attr=0;
+  CDirContext *dirc;
+  CArcCompress *arc;
+  absname=FileNameAbs(filename);
+  altname=ToggleZorNotZ(absname);
+  if ((tmph=HashFind(absname,adam_task->hash_table,HTT_FILE))||
+        (tmph=HashFind(altname,adam_task->hash_table,HTT_FILE))) {
+    size=tmph->user_data1;
+    res=MAlloc(size+1);
+    MemCpy(res,tmph->user_data0,size);
+    res[size]=0; //Terminate
+    attr=FileAttr(tmph->str,attr);
+  } else {
+    for (i=0;i<2 && !res;i++) {//Try name, then altname
+      if (!i)
+        curname=absname;
+      else
+        curname=altname;
+      if (dirc=DirContextNew(curname)) {
+        switch (dirc->dv->fs_type) {
+          case FSt_REDSEA:
+            res=RedSeaFileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+            break;
+          case FSt_FAT32:
+            res=FAT32FileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+            break;
+          default:
+            PrintErr("File System Not Supported\n");
+        }
+        DirContextDel(dirc);
+      }
+    }
+
+    //Search parent directories.
+    for (i=0;i<2 && !res;i++) {//Try name, then altname
+      if (!i)
+        curname=absname;
+      else
+        curname=altname;
+      if (dirc=DirContextNew(curname)) {
+        while (!res && StrCmp(Fs->cur_dir,"/")) {
+          Cd("..");
+          switch (Fs->cur_dv->fs_type) {
+            case FSt_REDSEA:
+              res=RedSeaFileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+              break;
+            case FSt_FAT32:
+              res=FAT32FileRead(dirc->dv,Fs->cur_dir,dirc->mask,&size,&attr);
+              break;
+            default:
+              PrintErr("File System Not Supported\n");
+          }
+        }
+        DirContextDel(dirc);
+      }
+    }
+    if (!res)
+      PrintErr("File not found: \"%s\".\n",filename);
+    if (res && attr & RS_ATTR_RESIDENT)
+      HashGenericAdd(curname,HTT_FILE,AMAllocIdent(res),size,0,adam_task);
+  }
+  if (res && attr & RS_ATTR_COMPRESSED) {
+    arc=res;
+    size=arc->expanded_size;
+    res=ExpandBuf(arc);
+    Free(arc);
+  }
+  if (_attr) *_attr=attr;
+  if (_size) *_size=size;
+  Free(absname);
+  Free(altname);
+  return res;
+}
+
+I64 FileWrite(U8 *filename,U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0)
+{//Write whole file to disk.
+  I64 c=0;
+  CHashGeneric *tmph;
+  CDirContext *dirc;
+  U8 *fbuf2,*absname=FileNameAbs(filename);
+  if (dirc=DirContextNew(filename,FALSE,TRUE)) {
+    attr=FileAttr(dirc->mask,attr);
+    if (attr&RS_ATTR_COMPRESSED) {
+      fbuf=CompressBuf(fbuf,size);
+      size=fbuf(CArcCompress *)->compressed_size;
+      fbuf2=fbuf;
+    } else
+      fbuf2=NULL;
+    if (!cdt) cdt=Now;
+    switch (dirc->dv->fs_type) {
+      case FSt_REDSEA:
+        c=RedSeaFileWrite(dirc->dv,Fs->cur_dir,dirc->mask,fbuf,size,cdt,attr);
+        break;
+      case FSt_FAT32:
+        c=FAT32FileWrite(dirc->dv,Fs->cur_dir,dirc->mask,fbuf,size,cdt,attr);
+        break;
+      default:
+        PrintErr("File System Not Supported\n");
+    }
+    if (tmph=HashFind(absname,adam_task->hash_table,HTT_FILE)) {
+      if (attr & RS_ATTR_RESIDENT) {
+        Free(tmph->user_data0);
+        tmph->user_data0=AMAllocIdent(fbuf);
+        tmph->user_data1=size;
+      } else
+        HashRemDel(tmph,adam_task->hash_table);
+    } else if (attr & RS_ATTR_RESIDENT)
+      HashGenericAdd(absname,HTT_FILE,AMAllocIdent(fbuf),size,0,adam_task);
+    Free(fbuf2);
+    DirContextDel(dirc);
+  }
+  Free(absname);
+  return c;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskFind.HC.HTML b/public/Wb/Kernel/BlkDev/DskFind.HC.HTML new file mode 100755 index 0000000..540849f --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskFind.HC.HTML @@ -0,0 +1,182 @@ + + + + + + + + + + + +
+CDirEntry *FilesFind2(U8 *files_find_mask,I64 fuf_flags)
+{
+  CDrv *dv=Fs->cur_dv;
+  CDirEntry *res=NULL;
+  DrvChk(dv);
+  switch (dv->fs_type) {
+    case FSt_REDSEA:
+      res=RedSeaFilesFind(files_find_mask,fuf_flags);
+      break;
+    case FSt_FAT32:
+      res=FAT32FilesFind(files_find_mask,fuf_flags);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+      res=NULL;
+  }
+  if (res) {
+    DirFilesSort(&res,SK_NAME);
+    if (fuf_flags&(FUF_FLATTEN_TREE|FUF_JUST_FILES))
+      DirFilesFlatten(res,&res,fuf_flags);
+    if (fuf_flags&FUF_CLUS_ORDER)
+      DirFilesSort(&res,SK_CLUS);
+  }
+  return res;
+}
+
+CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0)
+{/* See ::/Doc/FileUtils.DD.
+
+Find files and make a directory tree in memory.
+
+When done, you free with DirEntryDel(),DirEntryDel2(),
+DirTreeDel() or DirTreeDel2().
+
+*/
+  CDirEntry *res;
+  CDirContext *dirc;
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+  if (fuf_flags&FUF_SINGLE) {
+    res=MAlloc(sizeof(CDirEntry));
+    if (!FileFind(files_find_mask,res)) {
+      Free(res);
+      return NULL;
+    }
+  } else if (dirc=DirContextNew(files_find_mask,TRUE)) {
+    res=FilesFind2(dirc->mask,fuf_flags);
+    DirContextDel(dirc);
+  } else
+    return NULL;
+  return res;
+}
+
+Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0)
+{//FUF_JUST_DIRS, FUF_JUST_FILES, FUF_Z_OR_NOT_Z, FUF_SCAN_PARENTS
+//If you pass _de, you must Free(_de->full_name);
+  I64 i,j,cur_dir_clus;
+  U8 *altname,*curname,*full_name=NULL;
+  CDirEntry de;
+  CDirContext *dirc;
+  Bool res=FALSE,old_silent;
+  if (fuf_flags&~FUG_FILE_FIND)
+    throw('FUF');
+  if (!filename || *filename && filename[1]==':' && !Let2Drv(*filename,FALSE))
+    return FALSE;
+  altname=ToggleZorNotZ(filename);
+  if (fuf_flags&FUF_Z_OR_NOT_Z)
+    j=2;
+  else
+    j=1;
+  for (i=0;i<j && !res;i++) {
+    if (!i)
+      curname=filename;
+    else
+      curname=altname;
+    old_silent=Silent;
+    if (!(dirc=DirContextNew(curname)))
+      Silent(old_silent);
+    else {
+      Silent(old_silent);
+      cur_dir_clus=Name2DirClus(dirc->dv,Fs->cur_dir);
+      switch (dirc->dv->fs_type) {
+        case FSt_REDSEA:
+          res=RedSeaFileFind(dirc->dv,cur_dir_clus,dirc->mask,
+                &de,fuf_flags);
+          break;
+        case FSt_FAT32:
+          res=FAT32FileFind(dirc->dv,cur_dir_clus,dirc->mask,
+                &de,fuf_flags);
+          break;
+        default:
+          PrintErr("File System Not Supported\n");
+      }
+      if (res && _de) {
+        if (StrCmp(Fs->cur_dir,"/"))
+          full_name=MStrPrint("%C:%s/%s",
+                Drv2Let(Fs->cur_dv),Fs->cur_dir,de.name);
+        else
+          full_name=MStrPrint("%C:/%s",Drv2Let(Fs->cur_dv),de.name);
+      }
+      DirContextDel(dirc);
+    }
+  }
+  for (i=0;i<j && !res && fuf_flags&FUF_SCAN_PARENTS;i++) {
+    if (!i)
+      curname=filename;
+    else
+      curname=altname;
+    old_silent=Silent;
+    if (!(dirc=DirContextNew(curname)))
+      Silent(old_silent);
+    else {
+      Silent(old_silent);
+      cur_dir_clus=Name2DirClus(dirc->dv,Fs->cur_dir);
+      while (!res && StrCmp(Fs->cur_dir,"/")) {
+        Cd("..");
+        cur_dir_clus=Name2DirClus(dirc->dv,Fs->cur_dir);
+        switch (dirc->dv->fs_type) {
+          case FSt_REDSEA:
+            res=RedSeaFileFind(dirc->dv,cur_dir_clus,
+                  dirc->mask,&de,fuf_flags);
+            break;
+          case FSt_FAT32:
+            res=FAT32FileFind(dirc->dv,cur_dir_clus,
+                  dirc->mask,&de,fuf_flags);
+            break;
+          default:
+            PrintErr("File System Not Supported\n");
+        }
+      }
+      if (res && _de) {
+        if (StrCmp(Fs->cur_dir,"/"))
+          full_name=MStrPrint("%C:%s/%s",
+                Drv2Let(Fs->cur_dv),Fs->cur_dir,de.name);
+        else
+          full_name=MStrPrint("%C:/%s",
+                Drv2Let(Fs->cur_dv),de.name);
+      }
+      DirContextDel(dirc);
+    }
+  }
+  if (_de) {
+    if (res) {
+      MemCpy(_de,&de,sizeof(CDirEntry));
+      _de->full_name=full_name;
+    } else
+      MemSet(_de,0,sizeof(CDirEntry));
+  }
+  Free(altname);
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskFmt.HC.HTML b/public/Wb/Kernel/BlkDev/DskFmt.HC.HTML new file mode 100755 index 0000000..309b474 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskFmt.HC.HTML @@ -0,0 +1,123 @@ + + + + + + + + + + + +
+Bool DrvTypeSet(U8 drv_let,I64 type=FSt_REDSEA)
+{//Very dangerous
+  I64 i,j,ext_base,drv_num,offset,cur_type;
+  CMasterBoot mbr;
+  CBlkDev *bd;
+  drv_let=Let2Let(drv_let);
+  bd=Let2BlkDev(drv_let);
+  drv_num=bd->first_drv_let-'A';
+  switch (bd->type) {
+    case BDT_ATA:
+      offset=0;
+      ext_base=INVALID_CLUS;
+      while (TRUE) {
+        ATAReadBlks(bd,&mbr,offset,1);
+        j=-1;
+        for (i=0;i<4;i++) {
+          cur_type=mbr.p[i].type;
+          if (cur_type) {
+            if (cur_type==5 || cur_type==15)
+              j=i;
+            else {
+              if (drv_num+'A'==drv_let) {
+                switch (type) {
+                  case FSt_REDSEA:
+                    mbr.p[i].type=MBR_PT_REDSEA;
+                    break;
+                  case FSt_FAT32:
+                    mbr.p[i].type=MBR_PT_FAT32a;
+                    break;
+                  default:
+                    throw('Drv');
+                }
+                mbr.p[i].active=0x80;
+                ATAWriteBlks(bd,&mbr,offset,1);
+                return TRUE;
+              }
+              drv_num++;
+            }
+          }
+        }
+        if (j<0)
+          break;
+        if (!mbr.p[j].offset)
+          break;
+        if (ext_base==INVALID_CLUS) {
+          offset=mbr.p[j].offset;
+          ext_base=offset;
+        } else
+          offset=mbr.p[j].offset+ext_base;
+      }
+      break;
+  }
+}
+
+U0 Fmt(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=FSt_FAT32)
+{//Format hard drive or RAM drive.
+//Warning: Destroys all prev info.
+  //quick=FALSE means fill entire drive with zeros.
+  //Choose FSt_FAT32 or FSt_REDSEA.
+  //You don't format a CD/DVD with this.
+  CDrv *dv=Let2Drv(drv_let);
+  Bool old_silent=IsSilent;
+  if (confirm && !AreYouSure)
+    return;
+  if (!dv)  {
+    PrintErr("Invalid Drive\n");
+    return;
+  }
+  switch (type) {
+    case FSt_FAT32:
+      if (dv->bd->type==BDT_ATA) {
+        Silent;
+        Drv(drv_let);
+        Silent(old_silent);
+        FAT32Fmt(drv_let,quick);
+        DskCacheInvalidate(Let2Drv(drv_let));
+        Drv(drv_let);
+        break;
+      }
+      "Using RedSea File System.\n";
+    case FSt_REDSEA:
+      Silent;
+      Drv(drv_let);
+      Silent(old_silent);
+      RedSeaFmt(drv_let,quick);
+      DskCacheInvalidate(Let2Drv(drv_let));
+      Drv(drv_let);
+      break;
+    default:
+      PrintErr("File System Not Supported\n");
+  }
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskStrA.HC.HTML b/public/Wb/Kernel/BlkDev/DskStrA.HC.HTML new file mode 100755 index 0000000..f1ccaa1 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskStrA.HC.HTML @@ -0,0 +1,374 @@ + + + + + + + + + + + +
+U8 *FileExtDot(U8 *src)
+{//Find dot char in name.
+  I64 ch;
+  while (ch=*src++)
+    if (ch=='.' && *src!='/' && *src!='.')
+      return src-1;
+  return NULL;
+}
+
+U8 *FileExtRem(U8 *src,U8 *dst=NULL)
+{//Remove filename extension from str.
+  U8 *ptr;
+  if (ptr=FileExtDot(src)) {
+    if (dst)
+      StrCpy(dst,ptr+1);
+    *ptr=0;
+  } else if (dst)
+    *dst=0;
+  return dst;
+}
+
+Bool IsDotZ(U8 *filename)
+{//Does name end in .Z?
+  I64 i=StrLen(filename);
+  if (StrOcc(filename,'.')>1 && filename[i-1]=='Z' && filename[i-2]=='.')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool IsDotC(U8 *filename)
+{//Does name end in .C?
+  I64 i=StrLen(filename);
+  if (StrOcc(filename,'.')>1 && filename[i-1]=='C' && filename[i-2]=='.')
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool FilesFindMatch(U8 *_test_name,U8 *files_find_mask,I64 fuf_flags=0)
+{//Does filename meet Files Find mask?
+  I64 tn_len=StrLen(_test_name),mask_len=StrLen(files_find_mask);
+  U8 *mask1=MAlloc(mask_len+1),*mask2=MAlloc(mask_len+1),
+        *ptr,*test_name1,*test_name2;
+  Bool res=FALSE;
+  StrCpy(mask1,files_find_mask);
+  if (StrOcc(_test_name,'/')) {
+    test_name1=MAlloc(tn_len+1);
+    test_name2=MAlloc(tn_len+1);
+    StrCpy(test_name1,_test_name);
+    StrLastRem(test_name1,"/",test_name2);
+  } else {
+    test_name1=NULL;
+    test_name2=NULL;
+  }
+  while (TRUE) {
+    StrFirstRem(mask1,";",mask2);
+    if (!test_name2 || StrOcc(mask2,'/'))
+      ptr=_test_name;
+    else
+      ptr=test_name2;
+    if (*mask2) {
+      if (*mask2=='!') {
+        if (WildMatch(ptr,mask2+1)) {
+          res=FALSE;
+          break;
+        }
+      } else {
+        if (WildMatch(ptr,mask2)) {
+          if (Bt(&fuf_flags,FUf_JUST_TXT) &&
+                !FilesFindMatch(_test_name,FILEMASK_TXT)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_DD) &&
+                !FilesFindMatch(_test_name,FILEMASK_DD)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_SRC) &&
+                !FilesFindMatch(_test_name,FILEMASK_SRC)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_AOT) &&
+                !FilesFindMatch(_test_name,FILEMASK_AOT)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_JIT) &&
+                !FilesFindMatch(_test_name,FILEMASK_JIT)) {
+            res=FALSE;
+            break;
+          } else if (Bt(&fuf_flags,FUf_JUST_GR) &&
+                !FilesFindMatch(_test_name,FILEMASK_GR)) {
+            res=FALSE;
+            break;
+          } else
+            res=TRUE;
+        }
+      }
+    } else
+      break;
+  }
+  Free(test_name1);
+  Free(test_name2);
+  Free(mask1);
+  Free(mask2);
+  return res;
+}
+
+U8 *DirNameAbs(U8 *_dirname)
+{//MAlloc absolute dir string with drv letter.
+  I64 maxlen;
+  U8 drv[3],*res,*buf,*buf2,*buf3,*buf4,*dirname,*free_dirname;
+  if (!Fs->cur_dir || !*Fs->cur_dir)
+    return StrNew(_dirname);
+  free_dirname=dirname=MStrUtil(_dirname,
+        SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  *drv=Drv2Let;
+  drv[1]=':';
+  drv[2]=0;
+  if (*dirname && dirname[1]==':') {
+    if (*dirname==':')
+      *drv=blkdev.boot_drv_let;
+    else if (*dirname=='~')
+      *drv=*blkdev.home_dir;
+    else
+      *drv=*dirname;
+    dirname=dirname+2;
+    buf=StrNew("/");
+  } else
+    buf=StrNew(Fs->cur_dir);
+  if (*dirname=='/') {
+    Free(buf);
+    buf=StrNew("/");
+    dirname++;
+  }
+  buf2=StrNew(dirname);
+  maxlen=StrLen(buf)+1+StrLen(buf2)+1;
+  buf3=MAlloc(maxlen);
+  buf4=MAlloc(maxlen);
+  StrCpy(buf3,buf);
+  while (*buf2) {
+    StrFirstRem(buf2,"/",buf4);
+    if (!*buf4)
+      StrCpy(buf3,"/");
+    else if (!StrCmp(buf4,"..")) {
+      StrLastRem(buf3,"/");
+      if (!*buf3)
+        StrCpy(buf3,"/");
+    } else if (!StrCmp(buf4,"~")) {
+      Free(buf3);
+      buf3=MAlloc(StrLen(blkdev.home_dir+2)+1+StrLen(buf2)+1);
+      StrCpy(buf3,blkdev.home_dir+2);
+      *drv=*blkdev.home_dir;
+    } else if (!StrCmp(buf4,"."));
+    else if (*buf4) {
+      if (StrCmp(buf3,"/"))
+        CatPrint(buf3,"/");
+      CatPrint(buf3,buf4);
+    }
+  }
+  Free(buf);
+  res=MAlloc(StrLen(buf3)+3);
+  StrCpy(res,drv);
+  StrCpy(res+2,buf3);
+  Free(buf2);
+  Free(buf3);
+  Free(buf4);
+  Free(free_dirname);
+  return res;
+}
+
+U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=0)
+{//Absolute filename. Accepts FUF_Z_OR_NOT_Z, FUF_SCAN_PARENTS.
+  U8 *res,*filename,*buf,*buf_file,*buf_dir,*free_filename,*free_buf;
+  CDirEntry de;
+  free_filename=filename=MStrUtil(_filename,
+        SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
+  free_buf=buf=StrNew(filename);
+  if (*buf && buf[1]==':') {
+    buf+=2;
+    filename+=2;
+  }
+  buf_file=MAlloc(StrLen(free_filename)+1);
+  StrLastRem(buf,"/",buf_file);
+  if (*filename=='/' && !*buf)
+    StrCpy(buf,"/");
+  buf_dir=DirNameAbs(free_buf);
+  Free(free_buf);
+  res=MAlloc(StrLen(buf_dir)+1+StrLen(buf_file)+1);
+  StrCpy(res,buf_dir);
+  if (res[StrLen(res)-1]!='/')
+    CatPrint(res,"/");
+  CatPrint(res,buf_file);
+  Free(buf_file);
+  Free(buf_dir);
+  Free(free_filename);
+  if (fuf_flags && FileFind(res,&de,fuf_flags|FUF_JUST_FILES)) {
+    Free(res);
+    res=de.full_name;
+  }
+  return res;
+}
+
+U8 *ExtChg(U8 *filename,U8 *extension)
+{//Change filename extension.
+  U8 *res=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
+  StrCpy(res,filename);
+  if (FileExtDot(filename))
+    FileExtRem(res);
+  return CatPrint(res,".%s",extension);
+}
+
+U8 *ExtDft(U8 *filename,U8 *extension)
+{//Give extension if has none.
+  U8 *res=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
+  StrCpy(res,filename);
+  if (!FileExtDot(filename))
+    CatPrint(res,".%s",extension);
+  return res;
+}
+
+CDirEntry *Cd2DirEntry(CDirEntry *tmpde,U8 *abs_name)
+{
+  I64 i;
+  while (tmpde) {
+    i=StrLen(tmpde->full_name);
+    if (StrNCmp(tmpde->full_name,abs_name,i)||
+          i && tmpde->full_name[i-1]!='/' && abs_name[i] && abs_name[i]!='/')
+      tmpde=tmpde->next;
+    else
+      if (StrLen(abs_name)==i)
+        return tmpde;
+      else
+        return Cd2DirEntry(tmpde->sub,abs_name);
+  }
+  return NULL;
+}
+
+I64 FileAttr(U8 *name,I64 attr=0)
+{
+  if (IsDotZ(name))
+    attr|=RS_ATTR_COMPRESSED;
+  else
+    attr&=~RS_ATTR_COMPRESSED;
+  if (IsDotC(name))
+    attr|=RS_ATTR_CONTIGUOUS;
+  return attr;
+}
+
+Bool FileNameChk(U8 *filename)
+{//Return check for valid filename, not checking existence.
+  U8 *ptr=filename;
+  if (!filename) return FALSE;
+  if (!*ptr) return FALSE;
+  if (*ptr=='.') {
+    if (!ptr[1]) return TRUE;
+    if (ptr[1]=='.' && !ptr[2]) return TRUE;
+  }
+  if (StrLen(filename)>=CDIR_FILENAME_LEN) return FALSE;
+  while (*ptr)
+    if (!Bt(char_bmp_filename,*ptr++))
+      return FALSE;
+  return TRUE;
+}
+
+U8 *ToggleZorNotZ(U8 *name)
+{//MAlloc name with Z if not Z or vice versa.
+  U8 *res;
+  if (IsDotZ(name)) {
+    res=StrNew(name);
+    res[StrLen(name)-2]=0;
+  } else
+    res=MStrPrint("%s.Z",name);
+  return res;
+}
+
+U8 *FileNameTmpTxt()
+{//Make pretty-safe tmp filename in home dir.
+  return MStrPrint("~/SysTmp%X.DD.Z",GetTSC>>8&0xFFFFFFFF);
+}
+
+U8 *DirCur(CTask *task=NULL,CTask *mem_task=NULL)
+{//MAlloc copy of cur dir with drv letter.
+  U8 *st;
+  if (!task) task=Fs;
+  if (!task->cur_dir)
+    return NULL;
+  st=MAlloc(StrLen(task->cur_dir)+3,mem_task);
+  *st=Drv2Let(task->cur_dv);
+  st[1]=':';
+  StrCpy(st+2,task->cur_dir);
+  return st;
+}
+
+U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL)
+{/*Strips file from dirname, scans for file upward until found or
+returns default.
+
+("/Kernel/KHashA.HC.Z",NULL,NULL)       returns "D:/Kernel"
+("/Kernel",NULL,"PRJ.Z")                returns "D:/Kernel/Kernel.PRJ.Z"
+("/Kernel/BlkDev",NULL,"PRJ.Z")         returns "D:/Kernel/Kernel.PRJ.Z"
+("/Apps/Psalmody","Load","HC.Z")        returns "D:/Apps/Psalmody/Load.HC.Z"
+*/
+  U8 *st=DirNameAbs(dirname),*st2,*st3,*res,*dft=NULL,*ext;
+  if (_extension && *_extension) {
+    if (*_extension=='.')
+      ext=StrNew(_extension);
+    else
+      ext=MStrPrint(".%s",_extension);
+  } else
+    ext=StrNew("");
+  while (StrOcc(st,'/')&&!IsDir(st))
+    StrLastRem(st,"/");
+  while (StrOcc(st,'/')) {
+    st2=StrNew(st);
+    st3=StrNew(st);
+    StrLastRem(st2,"/",st3);
+
+    if (name)
+      res=MStrPrint("%s/%s%s",st,name,ext);
+    else {
+      if (*ext)
+        res=MStrPrint("%s/%s%s",st,st3,ext);
+      else
+        res=StrNew(st);
+    }
+    if (!dft)
+      dft=StrNew(res);
+    if (!*ext && (!name||!*name) || FileFind(res)) {
+      Free(st3);
+      Free(st2);
+      Free(st);
+      Free(dft);
+      Free(ext);
+      return res;
+    }
+    Free(st);
+    st=st2;
+    Free(st3);
+  }
+  Free(st);
+  Free(ext);
+  return dft;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/DskStrB.HC.HTML b/public/Wb/Kernel/BlkDev/DskStrB.HC.HTML new file mode 100755 index 0000000..171cf77 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/DskStrB.HC.HTML @@ -0,0 +1,120 @@ + + + + + + + + + + + +
+Bool CFileNameTo(U8 *dst,U8 *src)
+{
+  MemSet(dst,0,CDIR_FILENAME_LEN);
+  if (!FileNameChk(src))
+    return FALSE;
+  StrCpy(dst,src);
+  return TRUE;
+}
+
+I64 Name2DirClus(CDrv *dv,U8 *dirname)
+{
+  Bool cont=TRUE,unlock;
+  I64 cur_dir_clus;
+  CDirEntry de;
+  U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    cur_dir_clus=dv->root_clus;
+    while (*buf && cont) {
+      StrFirstRem(buf,"/",buf2);
+      if (*buf2) {
+        switch (dv->fs_type) {
+          case FSt_REDSEA:
+            cont=RedSeaFileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          case FSt_FAT32:
+            cont=FAT32FileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          default:
+            throw('Drv');
+        }
+        cur_dir_clus=de.clus;
+      }
+    }
+    if (!cont) {
+      PrintErr("File not found: \"%s\".\n",dirname);
+      cur_dir_clus=0;
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  Free(buf);
+  Free(buf2);
+  return cur_dir_clus;
+}
+
+I64 Name2ParentDirClus(CDrv *dv,U8 *dirname)
+{
+  Bool cont=TRUE,unlock;
+  I64 cur_dir_clus,cur_dir_clus2;
+  CDirEntry de;
+  U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
+  DrvChk(dv);
+  try {
+    unlock=DrvLock(dv);
+    cur_dir_clus=cur_dir_clus2=dv->root_clus;
+    while (*buf && cont) {
+      cur_dir_clus2=cur_dir_clus;
+      StrFirstRem(buf,"/",buf2);
+      if (*buf2) {
+        switch (dv->fs_type) {
+          case FSt_REDSEA:
+            cont=RedSeaFileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          case FSt_FAT32:
+            cont=FAT32FileFind(dv,cur_dir_clus,buf2,&de,FUF_JUST_DIRS);
+            break;
+          default:
+            throw('Drv');
+        }
+        cur_dir_clus=de.clus;
+      }
+    }
+    if (!cont) {
+      PrintErr("File not found: \"%s\".\n",dirname);
+      cur_dir_clus2=0;
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+  Free(buf);
+  Free(buf2);
+  return cur_dir_clus2;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/FileSysFAT.HC.HTML b/public/Wb/Kernel/BlkDev/FileSysFAT.HC.HTML new file mode 100755 index 0000000..9302844 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/FileSysFAT.HC.HTML @@ -0,0 +1,990 @@ + + + + + + + + + + + +
+U0 CDate2Dos(U16 *t,U16 *d,CDate cdt)
+{
+  CDateStruct ds;
+  Date2Struct(&ds,cdt);
+  *d=ds.day_of_mon+(ds.mon+(ds.year-1980)<<4)<<5;
+  *t=ds.sec>>1+(ds.min+ds.hour<<6)<<5;
+}
+
+CDate Dos2CDate(U16 t,U16 d)
+{
+  CDateStruct ds;
+  MemSet(&ds,0,sizeof(CDateStruct));
+  ds.day_of_mon=d&0x1F; d=d>>5;
+  ds.mon=d&0xF;
+  ds.year=d>>4+1980;
+  ds.sec=(t&0x1F)*2; t=t>>5;
+  ds.min=t&0x3F;
+  ds.hour=t>>6;
+  return Struct2Date(&ds);
+}
+
+U0 FAT32Init(CDrv *dv)
+{
+  CFAT32Boot br32;
+  Bool unlock;
+  try {
+    unlock=DrvLock(dv);
+    dv->fs_type=FSt_FAT32;
+    BlkRead(dv,&br32,dv->drv_offset,1);
+    dv->file_system_info_sect=dv->drv_offset+br32.file_system_info_sect;
+    dv->fat1=dv->drv_offset+br32.reserved_sects;
+    dv->fat2=dv->fat1+br32.sects_per_fat;
+    dv->data_area=dv->fat2+br32.sects_per_fat
+          -2*br32.sects_per_clus; //Starts at Clus 2
+    dv->spc=br32.sects_per_clus;
+    dv->root_clus=br32.root_clus;
+    DrvFATBlkAlloc(dv);
+    Free(dv->fis);
+    dv->fis=AMAlloc(BLK_SIZE);
+    BlkRead(dv,dv->fis,dv->file_system_info_sect,1);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 FAT32Fmt(U8 drv_let,Bool quick=TRUE)
+{
+  CFAT32Boot *br=CAlloc(BLK_SIZE);
+  CFAT32FileInfoSect *fis=CAlloc(BLK_SIZE);
+  CDrv *dv=Let2Drv(drv_let);
+  I64 i,l;
+  try {
+    DrvLock(dv);
+    DrvTypeSet(drv_let,FSt_FAT32);
+    dv->fs_type=FSt_FAT32;
+    br->jump_and_nop[0]=OC_JMP_REL8;
+    br->jump_and_nop[1]=offset(CFAT32Boot.code)-2;
+    br->jump_and_nop[2]=OC_NOP;
+    br->oem_name[0](I64)='MSWIN4.1';
+    br->bytes_per_sect=BLK_SIZE;
+    if    (dv->size<= 500000)
+      br->sects_per_clus=1;
+    else if (dv->size<=2000000)
+      br->sects_per_clus=2;
+    else if (dv->size<=6000000)
+      br->sects_per_clus=4;
+    else if (dv->size<=12000000)
+      br->sects_per_clus=8;
+    else if (dv->size<=33000000)
+      br->sects_per_clus=16;
+    else if (dv->size<=67000000)
+      br->sects_per_clus=32;
+    else
+      br->sects_per_clus=64;
+
+    br->reserved_sects=32;
+    br->copies_of_fat=2;
+    br->media_desc=0xF8;
+    br->sects=dv->size;
+    l=(br->sects/br->sects_per_clus)>>(BLK_SIZE_BITS-2)+1;
+    br->sects_per_fat=l;
+    br->root_clus=2;
+    br->file_system_info_sect=1;
+    br->log_drv_num=0x80;
+    br->ext_signature=0x29;
+    br->serial_num=RandU32;
+    MemCpy(br->vol_name,"NO NAME    ",11);
+    br->fat_name[0](I64)='FAT32   ';
+    br->signature=0xAA55;
+    fis->signature1='RRaA';
+    fis->signature2='rrAa';
+    fis->free_clus=-1;
+    fis->most_recently_alloced=0;
+    fis->signature3=0xAA550000;
+
+    if (quick)
+      i=br->reserved_sects+2*l+4*br->sects_per_clus;
+    else
+      i=dv->size;
+    BlkWriteZero(dv,dv->drv_offset,i);
+
+    BlkWrite(dv,fis,dv->drv_offset+br->file_system_info_sect,1);
+    BlkWrite(dv,br,dv->drv_offset,1);
+    FAT32Init(dv);
+    ClusAlloc(dv,0,1,FALSE); //Alloc #1
+    br->root_clus=ClusAlloc(dv,0,1,FALSE);
+    BlkWrite(dv,br,dv->drv_offset,1);
+    FAT32Init(dv);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  Free(br);
+  Free(fis);
+}
+
+Bool FATNameTo(U8 *dst,U8 *src)
+{
+  I64 i;
+  MemSet(dst,CH_SPACE,11);
+  if (!FileNameChk(src))
+    return FALSE;
+  if (!StrCmp(src,"..")) {
+    *dst='.';
+    dst[1]='.';
+    return TRUE;
+  } else if (!StrCmp(src,".")) {
+    *dst='.';
+    return TRUE;
+  }
+  i=0;
+  while (i<8 && *src && *src!='.')
+    dst[i++]=ToUpper(*src++);
+  i=8;
+  if (*src=='.') src++;
+  while (*src)
+    if (*src!='.')
+      dst[i++]=ToUpper(*src++);
+    else
+      src++;
+  return TRUE;
+}
+
+I64 FATNameXSum(U8 *src)
+{
+  I64 i,res=0;
+  for (i=0;i<11;i++)
+    if (res&1)
+      res.u8[0]=0x80+res>>1+*src++;
+    else
+      res.u8[0]=res>>1+*src++;
+  return res;
+}
+
+Bool FATFromName(U8 *dst,U8 *src)
+{
+  I64 i,j,k=0;
+  for (j=7;j>=0 && src[j]==CH_SPACE;j--);
+  for(i=0;i<=j;i++)
+    dst[k++]=src[i];
+  for (j=10;j>=8 && src[j]==CH_SPACE;j--);
+  if (*src!='.' && j!=7)
+    dst[k++]='.';
+  for(i=8;i<=j;i++)
+    dst[k++]=src[i];
+  dst[k++]=0;
+  return FileNameChk(dst);
+}
+
+U8 fat_long_name_map[13]={
+  offset(CFAT32DirEntryLong.name1),
+  offset(CFAT32DirEntryLong.name1)+2,
+  offset(CFAT32DirEntryLong.name1)+4,
+  offset(CFAT32DirEntryLong.name1)+6,
+  offset(CFAT32DirEntryLong.name1)+8,
+  offset(CFAT32DirEntryLong.name2),
+  offset(CFAT32DirEntryLong.name2)+2,
+  offset(CFAT32DirEntryLong.name2)+4,
+  offset(CFAT32DirEntryLong.name2)+6,
+  offset(CFAT32DirEntryLong.name2)+8,
+  offset(CFAT32DirEntryLong.name2)+10,
+  offset(CFAT32DirEntryLong.name3),
+  offset(CFAT32DirEntryLong.name3)+2
+};
+
+Bool DirLongNameFill(CDirEntry *tmpde,CFAT32DirEntryLong *de,I64 *xsum)
+{
+  I64 i;
+  U8 *ptr=de;
+  if (de->ord&0x40) {
+    MemSet(tmpde,0,sizeof(CDirEntry));
+    *xsum=de->xsum;
+  } else if (de->type || de->zero || de->xsum!=*xsum) {
+    MemSet(tmpde,0,sizeof(CDirEntry));
+    *xsum=0;
+    return FALSE;
+  }
+  switch (de->ord&0x3F) {
+    case 1:
+      for (i=0;i<13;i++)
+        if (!(tmpde->name[i]=ptr[fat_long_name_map[i]]))
+          return TRUE;
+      break;
+    case 2:
+      for (i=0;i<12;i++)
+        if (!(tmpde->name[i+13]=ptr[fat_long_name_map[i]]))
+          return TRUE;
+      break;
+  }
+  return TRUE;
+}
+
+Bool FAT32CDirFill(CDirEntry *tmpde,
+        CFAT32DirEntry *de,CDate _local_time_offset)
+{
+  Bool res;
+  if (*tmpde->name)
+    res=TRUE;
+  else
+    res=FATFromName(tmpde->name,de->name);
+  tmpde->clus=de->clus_lo+de->clus_hi<<16;
+  tmpde->size=de->size;
+  tmpde->attr=de->attr;
+  tmpde->datetime=Dos2CDate(de->WrtTime,de->WrtDate)-_local_time_offset;
+  return res;
+}
+
+Bool FAT32DirFill(CFAT32DirEntry *de,
+        CDirEntry *tmpde,I64 *_de_cnt,CDate _local_time_offset)
+{//Fill up to 3 entries and store cnt of entries.
+  I64 de_cnt=0,i,l,xsum,ord;
+  U8 *ptr,dname[16];
+  CFAT32DirEntryLong *ld=de;
+  Bool res;
+
+  MemSet(de,0,sizeof(CFAT32DirEntry));
+  res=FATNameTo(de->name,tmpde->name);
+  FATFromName(dname,de->name);
+  if (StrCmp(dname,tmpde->name)) {
+    ord=0x41;
+    xsum=FATNameXSum(de->name);
+    if ((l=StrLen(tmpde->name))>13) {
+      ptr=&ld[de_cnt];
+      MemSet(ptr,0,sizeof(CFAT32DirEntryLong));
+      ld[de_cnt].attr=RS_ATTR_LONG_NAME;
+      ld[de_cnt].xsum=xsum;
+      ld[de_cnt].ord=0x42;
+      for (i=13;i<l;i++)
+        ptr[fat_long_name_map[i-13]]=tmpde->name[i];
+      i++;
+      for (;i<26;i++)
+        ptr[fat_long_name_map[i-13]](U16)=0xFFFF;
+      ord=1;
+      l=13;
+      de_cnt++;
+    }
+    ptr=&de[de_cnt];
+    MemSet(ptr,0,sizeof(CFAT32DirEntryLong));
+    ld[de_cnt].attr=RS_ATTR_LONG_NAME;
+    ld[de_cnt].xsum=xsum;
+    ld[de_cnt].ord=ord;
+    for (i=0;i<l;i++)
+      ptr[fat_long_name_map[i]]=tmpde->name[i];
+    i++;
+    for (;i<13;i++)
+      ptr[fat_long_name_map[i]](U16)=0xFFFF;
+    de_cnt++;
+    MemSet(&de[de_cnt],0,sizeof(CFAT32DirEntry));
+    res=FATNameTo(de[de_cnt].name,tmpde->name);
+  }
+  de[de_cnt].clus_lo=tmpde->clus.u16[0];
+  de[de_cnt].clus_hi=tmpde->clus.u16[1];
+  if (!(tmpde->attr&RS_ATTR_DIR))
+    de[de_cnt].size=tmpde->size;
+  de[de_cnt].attr=tmpde->attr;
+  if (!tmpde->datetime)
+    tmpde->datetime=Now;
+  CDate2Dos(&de[de_cnt].WrtTime,&de[de_cnt].WrtDate,
+        tmpde->datetime+_local_time_offset);
+  if (_de_cnt)
+    *_de_cnt=de_cnt+1;
+  return res;
+}
+
+Bool FAT32FileFind(CDrv *dv,I64 cur_dir_clus,
+        U8 *name,CDirEntry *_res,I64 fuf_flags=0)
+{//FUF_JUST_DIRS, FUF_JUST_FILES
+  Bool res=FALSE,unlock;
+  CFAT32DirEntry *buf;
+  I64 xsum=0,attr,cur_dir_entry,entries_per_clus;
+  U8 dname[CDIR_FILENAME_LEN],ch;
+  CDirEntry long_name;
+  if (fuf_flags&~FUG_FILE_FIND)
+    throw('FUF');
+  MemSet(_res,0,sizeof(CDirEntry));
+  MemSet(&long_name,0,sizeof(CDirEntry));
+  DrvChk(dv);
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else if (!CFileNameTo(dname,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else
+    try {
+      unlock=DrvLock(dv);
+      buf=MAlloc(BLK_SIZE*dv->spc);
+      entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+      ClusRead(dv,buf,cur_dir_clus,1);
+      cur_dir_entry=0;
+      while (ch=*buf[cur_dir_entry].name) {
+        attr=buf[cur_dir_entry].attr;
+        if (ch!=0xE5) {
+          if (attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+            DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+          else {
+            if (!(attr&RS_ATTR_VOL_ID)) {
+              if (xsum==FATNameXSum(buf[cur_dir_entry].name))
+                MemCpy(_res,&long_name,sizeof(CDirEntry));
+              else
+                MemSet(_res,0,sizeof(CDirEntry));
+              if (!(fuf_flags&FUF_JUST_DIRS && !(attr & RS_ATTR_DIR)) &&
+                    !(fuf_flags&FUF_JUST_FILES && attr & RS_ATTR_DIR) &&
+                    FAT32CDirFill(_res,&buf[cur_dir_entry],
+                    dv->fat32_local_time_offset) &&
+                    !StrCmp(dname,_res->name)) {
+                res=TRUE;
+                goto fff_done;
+              }
+            }
+            MemSet(&long_name,0,sizeof(CDirEntry));
+          }
+        } else
+          MemSet(&long_name,0,sizeof(CDirEntry));
+        if (++cur_dir_entry==entries_per_clus) {
+          cur_dir_clus=ClusNumNext(dv,cur_dir_clus);
+          if (!(0<cur_dir_clus<0x0FFFFFF8))
+            break;
+          else {
+            ClusRead(dv,buf,cur_dir_clus,1);
+            cur_dir_entry=0;
+          }
+        }
+      }
+      MemSet(_res,0,sizeof(CDirEntry));
+fff_done:
+      Free(buf);
+      if (unlock)
+        DrvUnlock(dv);
+    } catch
+      if (unlock)
+        DrvUnlock(dv);
+  return res;
+}
+
+U8 *FAT32FileRead(CDrv *dv,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
+{
+  U8 *buf=NULL;
+  CDirEntry de;
+  I64 c,blk_cnt,cur_dir_clus;
+  DrvChk(dv);
+  *_size=0;
+  *_attr=0;
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else
+    try {
+      DrvLock(dv);
+      cur_dir_clus=Name2DirClus(dv,cur_dir);
+      if (FAT32FileFind(dv,cur_dir_clus,filename,&de,FUF_JUST_FILES)) {
+        blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+        buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
+        c=de.clus;
+        if (!(0<c<0x0FFFFFF8))
+          c=0x0FFFFFFF;
+        else
+          c=ClusBlkRead(dv,buf,c,blk_cnt);
+        buf[de.size]=0; //Terminate
+        *_size=de.size;
+        *_attr=FileAttr(de.name,de.attr);
+      }
+      DrvUnlock(dv);
+    } catch
+      DrvUnlock(dv);
+  return buf;
+}
+
+Bool FAT32Cd(U8 *name,I64 cur_dir_clus)
+{
+  CDirEntry de;
+  if (Fs->cur_dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else if (FAT32FileFind(Fs->cur_dv,cur_dir_clus,name,&de,FUF_JUST_DIRS))
+    return TRUE;
+  else
+    PrintErr("File not found: \"%s\".\n",name);
+  return FALSE;
+}
+
+U0 FAT32FreeClus(CDrv *dv,I64 c)
+{
+  I64 next,saved_c=c;
+  Bool unlock,unlock_break;
+  DrvChk(dv);
+  if (!(0<c<0x0FFFFFF8)) return;
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else
+    try {
+      unlock_break=BreakLock;
+      unlock=DrvLock(dv);
+      DrvFATBlkClean(dv);
+      do {
+        DrvFATBlkSet(dv,c,0);
+        next=dv->cur_fat_blk[c&(BLK_SIZE/4-1)];
+        dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=0;
+        LBts(&dv->fat_blk_dirty,0);
+        c=next;
+      } while (0<c<0x0FFFFFF8);
+      DrvFATBlkClean(dv,0);
+
+      c=saved_c;
+      do {
+        DrvFATBlkSet(dv,c,1);
+        next=dv->cur_fat_blk[c&(BLK_SIZE/4-1)];
+        dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=0;
+        LBts(&dv->fat_blk_dirty,0);
+        c=next;
+      } while (0<c<0x0FFFFFF8);
+      DrvFATBlkClean(dv,1);
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    } catch {
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    }
+}
+
+I64 FAT32AllocClus(CDrv *dv,I64 c,I64 cnt)
+{
+  Bool wrap_around=FALSE,unlock,unlock_break;
+  I64 first=INVALID_CLUS,j,l;
+
+  if (cnt<=0) return 0x0FFFFFFF;
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    l=(dv->size+dv->drv_offset-dv->data_area)/dv->spc-1;
+    j=dv->fis->most_recently_alloced;
+    while (cnt-->0) {
+      while (TRUE) {
+        j++;
+        if (j<1) j=1;
+        if (j>=l) {
+          if (wrap_around)
+            throw('Drv');
+          j=1;
+          wrap_around=TRUE;
+        }
+        DrvFATBlkSet(dv,j);
+        if (!dv->cur_fat_blk[j&(BLK_SIZE/4-1)])
+          break;
+      }
+      if (!(0<first<0x0FFFFFF8))
+        first=j;
+      if (0<c<l) {
+        DrvFATBlkSet(dv,c);
+        dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=j;
+        LBts(&dv->fat_blk_dirty,0);
+      }
+      c=j;
+    }
+
+    if (0<c<l) {
+      DrvFATBlkSet(dv,c);
+      dv->cur_fat_blk[c&(BLK_SIZE/4-1)]=0x0FFFFFFF;
+      LBts(&dv->fat_blk_dirty,0);
+    }
+    DrvFATBlkClean(dv);
+
+    dv->fis->most_recently_alloced=j;
+    dv->fis->free_clus=-1;
+    BlkWrite(dv,dv->fis,dv->file_system_info_sect,1);
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  if (unlock)
+    DrvUnlock(dv);
+  if (unlock_break)
+    BreakUnlock;
+  return first;
+}
+
+I64 FAT32AllocContiguousClus(CDrv *dv,I64 cnt)
+{
+  I64 i,first=1;
+  Bool cont,unlock,unlock_break;
+
+  if (cnt<=0) return 0x0FFFFFFF;
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    while (TRUE) {
+      first++;
+      i=0;
+      cont=TRUE;
+      while (cont && i<cnt) {
+        if ((first+i+1)*dv->spc+dv->data_area>dv->size+dv->drv_offset)
+          throw('Drv');
+        DrvFATBlkSet(dv,first+i);
+        if (dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)])
+          cont=FALSE;
+        else
+          i++;
+      }
+      if (!cont)
+        first=first+i;
+      else {
+        DrvFATBlkClean(dv);
+
+        for (i=0;i<cnt;i++) {
+          DrvFATBlkSet(dv,first+i,0);
+          if (i+1==cnt)
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
+          else
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
+          LBts(&dv->fat_blk_dirty,0);
+        }
+        DrvFATBlkClean(dv,0);
+
+        for (i=0;i<cnt;i++) {
+          DrvFATBlkSet(dv,first+i,1);
+          if (i+1==cnt)
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=0x0FFFFFFF;
+          else
+            dv->cur_fat_blk[(first+i)&(BLK_SIZE/4-1)]=first+i+1;
+          LBts(&dv->fat_blk_dirty,0);
+        }
+        DrvFATBlkClean(dv,1);
+        break;
+      }
+    }
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  if (unlock)
+    DrvUnlock(dv);
+  if (unlock_break)
+    BreakUnlock;
+  return first;
+}
+
+Bool FAT32DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain)
+{
+//See ::/Doc/CutCorners.DD.
+  CFAT32DirEntry *buf,*last_buf,*tmp_buf,de[3];
+  I64 i,attr,avail_cnt,de_cnt,c,
+        cur_dir_entry,entries_per_clus,
+        cur_dir_clus,xsum=0,last_dir_clus=INVALID_CLUS;
+  U8 ch;
+  Bool written=FALSE,unlock,unlock_break;
+  CDirEntry long_name;
+  FAT32DirFill(&de,tmpde,&de_cnt,dv->fat32_local_time_offset);
+  MemSet(&long_name,0,sizeof(CDirEntry));
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf     =MAlloc(BLK_SIZE*dv->spc);
+    last_buf=CAlloc(BLK_SIZE*dv->spc);
+    entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+    ClusRead(dv,buf,cur_dir_clus,1);
+    cur_dir_entry=0;
+    while (ch=*buf[cur_dir_entry].name) {
+      attr=buf[cur_dir_entry].attr;
+      if (ch!=0xE5 && attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+        DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+      else {
+        avail_cnt=FAT32_ENTRIES_PER_BLK-cur_dir_entry
+              &(FAT32_ENTRIES_PER_BLK-1);
+        for (i=0;i<avail_cnt;i++)
+          if (*buf[cur_dir_entry+i].name!=0xE5) {
+            if (*buf[cur_dir_entry+i].name)
+              avail_cnt=i;
+            break;
+          }
+        if (ch==0xE5 && !written && avail_cnt>=de_cnt) {
+          MemCpy(&buf[cur_dir_entry],&de,de_cnt*sizeof(CFAT32DirEntry));
+          BlkWrite(dv,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
+                dv->data_area+cur_dir_clus*dv->spc
+                +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+          cur_dir_entry+=de_cnt-1; //gets inc'ed
+          written=TRUE;
+        } else if (ch!=0xE5 && !(attr&RS_ATTR_VOL_ID)) {
+          if (xsum!=FATNameXSum(buf[cur_dir_entry].name))
+            MemSet(&long_name,0,sizeof(CDirEntry));
+          if (!*long_name.name)
+            FATFromName(long_name.name,buf[cur_dir_entry].name);
+//Del old entry with same name
+          if (!StrCmp(long_name.name,tmpde->name)) {
+            if (free_old_chain)
+              FAT32FreeClus(dv,buf[cur_dir_entry].clus_lo+
+                    buf[cur_dir_entry].clus_hi<<16);
+            if (!written) {
+              MemCpy(&buf[cur_dir_entry],&de[de_cnt-1],sizeof(CFAT32DirEntry));
+              BlkWrite(dv,&buf[cur_dir_entry & -FAT32_ENTRIES_PER_BLK],
+                    dv->data_area+cur_dir_clus*dv->spc
+                    +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+              written=TRUE;
+            } else {
+              *buf[cur_dir_entry].name=0xE5;
+              i=1;
+              while (i<=cur_dir_entry &&
+                    buf[cur_dir_entry-i].attr&RS_ATTR_LONG_NAME_MASK
+                    ==RS_ATTR_LONG_NAME)
+                *buf[cur_dir_entry-i++].name=0xE5;
+              i--;
+              BlkWrite(dv,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
+                    dv->data_area+cur_dir_clus*dv->spc
+                    +(cur_dir_entry-i)>>FAT32_ENTRIES_BITS,
+                    (i+FAT32_ENTRIES_PER_BLK)>>FAT32_ENTRIES_BITS);
+              if (i==cur_dir_entry && 0<last_dir_clus<0x0FFFFFF8) {
+                i=1;
+                while (i<=entries_per_clus &&
+                      last_buf[entries_per_clus-i].attr
+                      &RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+                  *last_buf[entries_per_clus-i++].name=0xE5;
+                if (--i>0)
+                  BlkWrite(dv,&buf[(entries_per_clus-i)&-FAT32_ENTRIES_PER_BLK],
+                        dv->data_area+last_dir_clus*dv->spc
+                        +(entries_per_clus-i)>>FAT32_ENTRIES_BITS,
+                        (i+FAT32_ENTRIES_PER_BLK-1)>>FAT32_ENTRIES_BITS);
+              }
+            }
+            break;
+          }
+        }
+        MemSet(&long_name,0,sizeof(CDirEntry));
+      }
+      if (++cur_dir_entry==entries_per_clus) {
+        last_dir_clus=cur_dir_clus;
+        tmp_buf=buf; buf=last_buf; last_buf=tmp_buf;
+        c=ClusNumNext(dv,cur_dir_clus);
+        if (!(0<c<0x0FFFFFF8)) {
+          c=ClusAlloc(dv,cur_dir_clus,1,FALSE);
+          MemSet(buf,0,BLK_SIZE*dv->spc);
+          ClusWrite(dv,buf,c,1);
+        } else
+          ClusRead(dv,buf,c,1);
+        cur_dir_clus=c;
+        cur_dir_entry=0;
+      }
+    }
+    if (!written) {
+      avail_cnt=FAT32_ENTRIES_PER_BLK-cur_dir_entry & (FAT32_ENTRIES_PER_BLK-1);
+      if (avail_cnt<de_cnt) {
+        for (i=0;i<avail_cnt;i++)
+          *buf[cur_dir_entry+i].name=0xE5;
+        BlkWrite(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
+              dv->data_area+cur_dir_clus*dv->spc
+              +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+        cur_dir_entry+=avail_cnt;
+        if (cur_dir_entry==entries_per_clus) {
+          last_dir_clus=cur_dir_clus;
+          tmp_buf=buf; buf=last_buf; last_buf=tmp_buf;
+          cur_dir_clus=ClusAlloc(dv,cur_dir_clus,1);
+          cur_dir_entry=0;
+          MemSet(buf,0,BLK_SIZE*dv->spc);
+          ClusWrite(dv,buf,cur_dir_clus,1);
+        }
+      }
+      MemCpy(&buf[cur_dir_entry],&de,de_cnt*sizeof(CFAT32DirEntry));
+      BlkWrite(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
+            dv->data_area+cur_dir_clus*dv->spc+
+            cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+      cur_dir_entry+=de_cnt;
+      if (cur_dir_entry==entries_per_clus) {
+        cur_dir_clus=ClusAlloc(dv,cur_dir_clus,1);
+        MemSet(buf,0,BLK_SIZE*dv->spc);
+        ClusWrite(dv,buf,cur_dir_clus,1);
+      } else {
+        MemSet(&buf[cur_dir_entry],0,sizeof(CFAT32DirEntry));
+        BlkWrite(dv,&buf[cur_dir_entry &-FAT32_ENTRIES_PER_BLK],
+              dv->data_area+cur_dir_clus*dv->spc
+              +cur_dir_entry>>FAT32_ENTRIES_BITS,1);
+      }
+    }
+    Free(last_buf);
+    Free(buf);
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return FALSE;
+}
+
+I64 FAT32FilesDel(CDrv *dv,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
+                     Bool del_dir,Bool print_msg)
+{
+  CFAT32DirEntry *buf,*last_buf,*tmp_buf;
+  I64 i,res=0,attr,xsum=0,last_dir_clus=INVALID_CLUS,
+        cur_dir_entry,entries_per_clus,cur_dir_clus;
+  U8 ch;
+  Bool unlock_break;
+  CDirEntry long_name;
+  MemSet(&long_name,0,sizeof(CDirEntry));
+  try {
+    unlock_break=BreakLock;
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf     =MAlloc(BLK_SIZE*dv->spc);
+    last_buf=CAlloc(BLK_SIZE*dv->spc);
+    entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+    ClusRead(dv,buf,cur_dir_clus,1);
+    cur_dir_entry=0;
+    while (ch=*buf[cur_dir_entry].name) {
+      attr=buf[cur_dir_entry].attr;
+      if (ch!=0xE5 && ch!='.') {
+        if (attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+          DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+        else {
+          if (!(attr & RS_ATTR_VOL_ID) &&
+                (del_dir || !(attr & RS_ATTR_DIR))) {
+            if (xsum!=FATNameXSum(buf[cur_dir_entry].name))
+              MemSet(&long_name,0,sizeof(CDirEntry));
+            if (!*long_name.name)
+              FATFromName(long_name.name,buf[cur_dir_entry].name);
+            if (FilesFindMatch(long_name.name,files_find_mask,fuf_flags)) {
+              if (!(attr & RS_ATTR_DIR)) res++;
+              if (print_msg)
+                "Del %s\n",long_name.name;
+              *buf[cur_dir_entry].name=0xE5;
+              i=1;
+              while (i<=cur_dir_entry &&
+                    buf[cur_dir_entry-i].attr&RS_ATTR_LONG_NAME_MASK
+                    ==RS_ATTR_LONG_NAME)
+                *buf[cur_dir_entry-i++].name=0xE5;
+              i--;
+              BlkWrite(dv,&buf[(cur_dir_entry-i)&-FAT32_ENTRIES_PER_BLK],
+                    dv->data_area+cur_dir_clus*dv->spc
+                    +(cur_dir_entry-i)>>FAT32_ENTRIES_BITS,
+                    (i+FAT32_ENTRIES_PER_BLK)>>FAT32_ENTRIES_BITS);
+              if (i==cur_dir_entry && last_dir_clus!=INVALID_CLUS) {
+                i=1;
+                while (i<=entries_per_clus &&
+                      last_buf[entries_per_clus-i].attr
+                      &RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+                  *last_buf[entries_per_clus-i++].name=0xE5;
+                if (--i>0)
+                  BlkWrite(dv,&buf[(entries_per_clus-i)&-FAT32_ENTRIES_PER_BLK],
+                        dv->data_area+last_dir_clus*dv->spc
+                        +(entries_per_clus-i)>>FAT32_ENTRIES_BITS,
+                        (i+FAT32_ENTRIES_PER_BLK-1)>>FAT32_ENTRIES_BITS);
+              }
+              FAT32FreeClus(dv,buf[cur_dir_entry].clus_lo+
+                    buf[cur_dir_entry].clus_hi<<16);
+            }
+          }
+          MemSet(&long_name,0,sizeof(CDirEntry));
+        }
+      } else
+        MemSet(&long_name,0,sizeof(CDirEntry));
+      if (++cur_dir_entry==entries_per_clus) {
+        last_dir_clus=cur_dir_clus;
+        cur_dir_clus=ClusNumNext(dv,cur_dir_clus,1);
+        tmp_buf=buf; buf=last_buf; last_buf=tmp_buf;
+        ClusRead(dv,buf,cur_dir_clus,1);
+        cur_dir_entry=0;
+      }
+    }
+    Free(buf);
+    Free(last_buf);
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return res;
+}
+
+I64 FAT32FileWrite(CDrv *dv,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
+        CDate cdt,I64 attr)
+{
+  CDirEntry de;
+  I64 c=0,blk_cnt;
+  Bool contiguous;
+  MemSet(&de,0,sizeof(CDirEntry));
+  if (size<0) size=0;
+  if (dv->fs_type!=FSt_FAT32)
+    PrintErr("Not FAT32 Drv\n");
+  else if (!CFileNameTo(de.name,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else {
+    FAT32FilesDel(dv,cur_dir,de.name,0,FALSE,FALSE);
+    if (attr & RS_ATTR_CONTIGUOUS)
+      contiguous=TRUE;
+    else
+      contiguous=FALSE;
+    de.size=size;
+    if (blk_cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS)
+      c=ClusAlloc(dv,0,(blk_cnt+dv->spc-1)/dv->spc,contiguous);
+    else
+      c=0x0FFFFFFF;
+    de.clus=c;
+    de.attr=attr;
+    de.datetime=cdt;
+    if (blk_cnt)
+      ClusBlkWrite(dv,buf,c,blk_cnt);
+    FAT32DirNew(dv,cur_dir,&de,TRUE);
+  }
+  return c;
+}
+
+CDirEntry *FAT32FilesFind(U8 *files_find_mask,
+        I64 fuf_flags,CDirEntry *parent=NULL,I64 *_dir_size=NULL)
+{
+  CDrv *dv=Fs->cur_dv;
+  CFAT32DirEntry *buf;
+  I64 attr,xsum=0,dir_size=0,sub_dir_size,
+        cur_dir_clus,cur_dir_entry,entries_per_clus;
+  U8 ch;
+  CDirEntry *res=NULL,*tmpde,long_name;
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+  try {
+    MemSet(&long_name,0,sizeof(CDirEntry));
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,Fs->cur_dir);
+    buf=MAlloc(BLK_SIZE*dv->spc);
+    entries_per_clus=dv->spc<<FAT32_ENTRIES_BITS;
+    ClusRead(dv,buf,cur_dir_clus,1);
+    dir_size+=dv->spc*BLK_SIZE;
+    cur_dir_entry=0;
+    while (ch=*buf[cur_dir_entry].name) {
+      attr=buf[cur_dir_entry].attr;
+      if (ch!=0xE5) {
+        if (attr&RS_ATTR_LONG_NAME_MASK==RS_ATTR_LONG_NAME)
+          DirLongNameFill(&long_name,&buf[cur_dir_entry],&xsum);
+        else {
+          if (!(attr&RS_ATTR_VOL_ID)) {
+            tmpde=MAlloc(sizeof(CDirEntry));
+            if (xsum==FATNameXSum(buf[cur_dir_entry].name))
+              MemCpy(tmpde,&long_name,sizeof(CDirEntry));
+            else
+              MemSet(tmpde,0,sizeof(CDirEntry));
+            if (FAT32CDirFill(tmpde,&buf[cur_dir_entry],
+                  dv->fat32_local_time_offset)) {
+              tmpde->parent=parent;
+              if (Bt(&fuf_flags,FUf_RECURSE) && attr&RS_ATTR_DIR &&
+                    *tmpde->name!='.') {
+                tmpde->next=res;
+                res=tmpde;
+                tmpde->full_name=DirNameAbs(tmpde->name);
+                DrvUnlock(dv);
+                if (Cd(tmpde->name)) {
+                  tmpde->sub=FAT32FilesFind(files_find_mask,fuf_flags,
+                        tmpde,&sub_dir_size);
+                  tmpde->size=sub_dir_size;
+                  Cd("..");
+                }
+                DrvLock(dv);
+              } else {
+                tmpde->full_name=FileNameAbs(tmpde->name);
+                if ((attr&RS_ATTR_DIR || !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
+                      !(Bt(&fuf_flags,FUf_RECURSE) &&
+                      *tmpde->name=='.' && attr&RS_ATTR_DIR) &&
+                      FilesFindMatch(tmpde->full_name,files_find_mask,
+                      fuf_flags)) {
+                  tmpde->next=res;
+                  res=tmpde;
+                } else
+                  DirEntryDel(tmpde);
+              }
+            } else
+              DirEntryDel(tmpde);
+          }
+          MemSet(&long_name,0,sizeof(CDirEntry));
+        }
+      } else
+        MemSet(&long_name,0,sizeof(CDirEntry));
+      if (++cur_dir_entry==entries_per_clus) {
+        cur_dir_clus=ClusNumNext(dv,cur_dir_clus);
+        if (cur_dir_clus==INVALID_CLUS)
+          break;
+        else {
+          ClusRead(dv,buf,cur_dir_clus,1);
+          dir_size+=dv->spc*BLK_SIZE;
+          cur_dir_entry=0;
+        }
+      }
+    }
+    Free(buf);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  if (_dir_size)
+    *_dir_size=dir_size;
+  return res;
+}
+
+Bool FAT32MkDir(CDrv *dv,U8 *cur_dir,U8 *name,I64 entry_cnt)
+{
+  I64 c,cur_dir_clus=Name2DirClus(dv,cur_dir),
+//Rough estimate of size
+        size=CeilU64((entry_cnt+2)<<FAT32_ENTRIES_BITS,dv->spc<<BLK_SIZE_BITS);
+  U8 *buf=CAlloc(size);
+  CDirEntry d_native;
+  CFAT32DirEntry *dFAT=buf;
+  Bool unlock_break;
+
+  try {
+    unlock_break=BreakLock;
+    c=FileWrite(name,buf,size,0,RS_ATTR_DIR);
+    MemSet(&d_native,0,sizeof(CDirEntry));
+    d_native.attr=RS_ATTR_DIR;
+    *d_native.name='.';
+    d_native.name[1]=0;
+    d_native.clus=c;
+    d_native.size=0;
+    d_native.datetime=Now;
+    FAT32DirFill(dFAT,&d_native,NULL,dv->fat32_local_time_offset);
+    dFAT++;
+
+    MemSet(&d_native,0,sizeof(CDirEntry));
+    d_native.attr=RS_ATTR_DIR;
+    *d_native.name='.';
+    d_native.name[1]='.';
+    d_native.name[2]=0;
+    d_native.clus=cur_dir_clus;
+    d_native.size=0;
+    d_native.datetime=Now;
+    FAT32DirFill(dFAT,&d_native,NULL,dv->fat32_local_time_offset);
+    ClusWrite(dv,buf,c,1);
+    Free(buf);
+    if (unlock_break)
+      BreakUnlock;
+  } catch
+    if (unlock_break)
+      BreakUnlock;
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/FileSysRedSea.HC.HTML b/public/Wb/Kernel/BlkDev/FileSysRedSea.HC.HTML new file mode 100755 index 0000000..f7f1a61 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/FileSysRedSea.HC.HTML @@ -0,0 +1,666 @@ + + + + + + + + + + + +
+// See RedSea File System
+
+U0 RedSeaFreeFreeLst(CDrv *dv)
+{
+  CFreeLst *tmpf,*tmpf1;
+  Bool unlock;
+  try {
+    unlock=DrvLock(dv);
+    if (tmpf=dv->next_free) {
+      while (tmpf!=&dv->next_free) {
+        tmpf1=tmpf->next;
+        Free(tmpf);
+        tmpf=tmpf1;
+      }
+    }
+    dv->next_free=NULL;
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 RedSeaFreeLstBuild(CDrv *dv)
+{
+  Bool unlock;
+  CFreeLst *tmpf;
+  I64 i,first=dv->data_area,max_blk=dv->size+dv->drv_offset;
+  try {
+    unlock=DrvLock(dv);
+    if (dv->next_free)
+      RedSeaFreeFreeLst(dv);
+    QueInit(&dv->next_free);
+    while (first<max_blk) {
+      i=0;  //count free clus
+      while (first+i<max_blk) {
+        DrvFATBlkSet(dv,first+i);
+        if (Bt(dv->cur_fat_blk,(first+i-dv->data_area)&(BLK_SIZE<<3-1)))
+          break;
+        else
+          i++;
+      }
+      if (i) {
+        tmpf=AMAlloc(sizeof(CFreeLst));
+        tmpf->size=i;
+        tmpf->start=first;
+        QueIns(tmpf,dv->last_free);
+      }
+      first+=i+1;
+    }
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+U0 RedSeaInit(CDrv *dv)
+{
+  CRedSeaBoot br;
+  Bool unlock;
+  try {
+    unlock=DrvLock(dv);
+    BlkRead(dv,&br,dv->drv_offset,1);
+    if (br.signature!=MBR_PT_REDSEA || br.signature2!=0xAA55)
+      throw('Drv');
+    dv->fs_type=FSt_REDSEA;
+    RedSeaFreeFreeLst(dv);
+    dv->spc=1;
+    dv->size=br.sects;
+    dv->data_area=dv->drv_offset+br.bitmap_sects;
+    dv->root_clus=br.root_clus;
+    dv->fat1=dv->fat2=dv->drv_offset+1;
+    DrvFATBlkAlloc(dv);
+    if (unlock)
+      DrvUnlock(dv);
+  } catch
+    if (unlock)
+      DrvUnlock(dv);
+}
+
+Bool RedSeaValidate(U8 drv_let)
+{
+  CDrv *dv;
+  CRedSeaBoot br;
+  if ((dv=Let2Drv(drv_let,FALSE)) && dv->fs_type==FSt_REDSEA &&
+        BlkRead(dv,&br,dv->drv_offset,1) && br.signature==MBR_PT_REDSEA &&
+        br.signature2==0xAA55)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+U0 RedSeaFmt(U8 drv_let,Bool quick=TRUE)
+{
+  U8 *root_dir;
+  CDirEntry *d_native;
+  CRedSeaBoot *br=CAlloc(BLK_SIZE);
+  CDrv *dv=Let2Drv(drv_let);
+  I64 i,n,root_dir_blks;
+  try {
+    DrvLock(dv);
+//      DrvTypeSet(drv_let,FSt_REDSEA);
+    DrvTypeSet(drv_let,FSt_FAT32);
+    dv->fs_type=FSt_REDSEA;
+    br->signature=MBR_PT_REDSEA;
+    br->signature2=0xAA55;
+    br->drv_offset=dv->drv_offset; //For CD/DVD image copy.
+    br->sects=dv->size;
+    n=(br->sects+BLK_SIZE<<3-1)/BLK_SIZE<<3;
+    br->bitmap_sects=n;
+    br->unique_id=GetTSC^Now()(U64);
+    br->root_clus=0;
+
+    if (quick)
+      i=n+1;
+    else
+      i=dv->size;
+    BlkWriteZero(dv,dv->drv_offset,i);
+
+    BlkWrite(dv,br,dv->drv_offset,1);
+    RedSeaInit(dv);
+    ClusAlloc(dv,0,1,FALSE);    //Alloc #1
+
+    root_dir_blks=MaxI64(1,dv->bd->init_root_dir_blks);
+    br->root_clus=ClusAlloc(dv,0,root_dir_blks,FALSE);
+    BlkWrite(dv,br,dv->drv_offset,1);
+    root_dir=CAlloc(BLK_SIZE*root_dir_blks);
+
+    d_native=root_dir-offset(CDirEntry.start);
+
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    *d_native->name='.';
+    d_native->clus=br->root_clus;
+    d_native->size=BLK_SIZE*root_dir_blks;
+    d_native->datetime=Now;
+
+    d_native(U8 *)+=CDIR_SIZE;
+
+    *d_native->name='.';
+    d_native->name[1]='.';
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    d_native->clus=br->root_clus;
+    d_native->datetime=Now;
+
+    BlkWrite(dv,root_dir,br->root_clus,root_dir_blks);
+    RedSeaInit(dv);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  Free(br);
+  Free(root_dir);
+}
+
+Bool RedSeaFileFind(CDrv *dv,I64 cur_dir_clus,U8 *name,
+        CDirEntry *_res,I64 fuf_flags=0)
+{//FUF_JUST_DIRS, FUF_JUST_FILES
+  CDirEntry *buf,*buf2,*ptr;
+  U8 dname[CDIR_FILENAME_LEN];
+  I64 ch;
+  Bool res=FALSE,unlock;
+  if (fuf_flags&~FUG_FILE_FIND)
+    throw('FUF');
+  MemSet(_res,0,sizeof(CDirEntry));
+  DrvChk(dv);
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else if (!CFileNameTo(dname,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else
+    try {
+      unlock=DrvLock(dv);
+      buf2=MAlloc(BLK_SIZE);
+      BlkRead(dv,buf2,cur_dir_clus,1);
+
+      ptr=buf2(U8 *)-offset(CDirEntry.start);
+      buf=MAlloc(ptr->size);
+      BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+      Free(buf2);
+
+      ptr=buf(U8 *)-offset(CDirEntry.start);
+      *ptr->name='.';
+      ptr->name[1]=0;
+      while (TRUE) {
+        if (!(ch=*ptr->name))
+          break;
+        else if (!(ptr->attr & RS_ATTR_DELETED) &&
+              !(fuf_flags&FUF_JUST_DIRS && !(ptr->attr & RS_ATTR_DIR)) &&
+              !(fuf_flags&FUF_JUST_FILES && ptr->attr & RS_ATTR_DIR) &&
+              !StrCmp(dname,ptr->name)) {
+          MemCpy(&_res->attr,&ptr->attr,CDIR_SIZE);
+          res=TRUE;
+          goto rsff_done;
+        }
+        ptr(U8 *)+=CDIR_SIZE;
+      }
+rsff_done:
+      Free(buf);
+      if (unlock)
+        DrvUnlock(dv);
+    } catch
+      if (unlock)
+        DrvUnlock(dv);
+  return res;
+}
+
+U8 *RedSeaFileRead(CDrv *dv,U8 *cur_dir,U8 *filename,I64 *_size,I64 *_attr)
+{
+  U8 *buf=NULL;
+  CDirEntry de;
+  I64 c,blk_cnt,cur_dir_clus;
+  DrvChk(dv);
+  *_size=0;
+  *_attr=0;
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else
+    try {
+      DrvLock(dv);
+      cur_dir_clus=Name2DirClus(dv,cur_dir);
+      if (RedSeaFileFind(dv,cur_dir_clus,filename,&de,FUF_JUST_FILES)) {
+        blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
+        buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
+        c=de.clus;
+        c=BlkRead(dv,buf,c,blk_cnt);
+        buf[de.size]=0; //Terminate
+        *_size=de.size;
+        *_attr=FileAttr(de.name,de.attr);
+      }
+      DrvUnlock(dv);
+    } catch
+      DrvUnlock(dv);
+  return buf;
+}
+
+Bool RedSeaCd(U8 *name,I64 cur_dir_clus)
+{
+  CDirEntry de;
+  if (Fs->cur_dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else if (RedSeaFileFind(Fs->cur_dv,cur_dir_clus,name,&de,FUF_JUST_DIRS))
+    return TRUE;
+  else
+    PrintErr("File not found: \"%s\".\n",name);
+  return FALSE;
+}
+
+U0 RedSeaFreeClus(CDrv *dv,I64 c,I64 cnt)
+{
+  CFreeLst *tmpf;
+  Bool found=FALSE,unlock,unlock_break;
+  DrvChk(dv);
+  if (!c) return;
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else
+    try {
+      unlock_break=BreakLock;
+      unlock=DrvLock(dv);
+      if (!dv->next_free)
+        RedSeaFreeLstBuild(dv);
+      tmpf=dv->next_free;
+      while (!found && tmpf!=&dv->next_free) {
+        if (tmpf->start+tmpf->size==c) {
+          tmpf->size+=cnt;
+          found=TRUE;
+        } else if (c+cnt==tmpf->start) {
+          tmpf->size+=cnt;
+          tmpf->start=c;
+          found=TRUE;
+        }
+        tmpf=tmpf->next;
+      }
+      if (!found) {
+        tmpf=AMAlloc(sizeof(CFreeLst));
+        tmpf->size=cnt;
+        tmpf->start=c;
+        QueIns(tmpf,dv->last_free);
+      }
+      while (cnt-->0) {
+        DrvFATBlkSet(dv,c);
+        LBtr(dv->cur_fat_blk,(c-dv->data_area)&(BLK_SIZE<<3-1));
+        LBts(&dv->fat_blk_dirty,0);
+        c++;
+      }
+      DrvFATBlkClean(dv);
+
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    } catch {
+      if (unlock)
+        DrvUnlock(dv);
+      if (unlock_break)
+        BreakUnlock;
+    }
+}
+
+I64 RedSeaAllocClus(CDrv *dv,I64 cnt)
+{
+  CFreeLst *tmpf,*best_free=NULL;
+  I64 i,first,best_size=I64_MAX;
+  Bool unlock,unlock_break;
+  if (cnt<=0)
+    throw('Drv');
+  try {
+    unlock_break=BreakLock;
+    unlock=DrvLock(dv);
+    if (!dv->next_free)
+      RedSeaFreeLstBuild(dv);
+    tmpf=dv->next_free;
+    while (tmpf!=&dv->next_free) {
+      if (tmpf->size>=cnt && tmpf->size<best_size) {
+        best_free=tmpf;
+        best_size=tmpf->size;
+        if (tmpf->size==cnt)
+          break;
+      }
+      tmpf=tmpf->next;
+    }
+    if (!best_free)
+      throw('Drv');
+    first=best_free->start;
+    for (i=0;i<cnt;i++) {
+      DrvFATBlkSet(dv,first+i);
+      LBts(dv->cur_fat_blk,(first+i-dv->data_area)&(BLK_SIZE<<3-1));
+      LBts(&dv->fat_blk_dirty,0);
+    }
+    DrvFATBlkClean(dv);
+    if (best_free->size-=cnt)
+      best_free->start+=cnt;
+    else {
+      QueRem(best_free);
+      Free(best_free);
+    }
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return first;
+}
+
+Bool RedSeaDirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,Bool free_old_chain)
+{
+  CDirEntry *buf,*buf2,*ptr,de2;
+  CRedSeaBoot *br;
+  I64 c,ch,i=1,j=0,n=BLK_SIZE/CDIR_SIZE,dir_size,cur_dir_clus;
+  Bool written=FALSE,unlock,unlock_break;
+  U8 *tmp,*parent_dir;
+  try {
+    unlock_break=BreakLock;
+    tmpde->attr|=RS_ATTR_CONTIGUOUS;
+    unlock=DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf2=MAlloc(BLK_SIZE);
+    BlkRead(dv,buf2,cur_dir_clus,1);
+
+    ptr=buf2(U8 *)-offset(CDirEntry.start);
+    buf=MAlloc(ptr->size);
+    BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+
+    dir_size=ptr->size;
+    ptr=buf(U8 *)-offset(CDirEntry.start)+CDIR_SIZE;
+    Free(buf2);
+    while (TRUE) {
+      if (!(ch=*ptr->name)) {
+        if (!written)
+          MemCpy(&ptr->start,&tmpde->start,CDIR_SIZE);
+        if ((i+1)*CDIR_SIZE+j<<BLK_SIZE_BITS<dir_size)
+          BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+        else {
+          buf2=CAlloc(dir_size+BLK_SIZE);
+          MemCpy(buf2,buf,dir_size);
+          RedSeaFreeClus(dv,cur_dir_clus,dir_size>>BLK_SIZE_BITS);
+          dir_size+=BLK_SIZE;
+          c=ClusAlloc(dv,0,dir_size>>BLK_SIZE_BITS,TRUE);
+          Free(buf);
+          buf=buf2;
+          ptr=buf(U8 *)-offset(CDirEntry.start);
+          ptr->size=dir_size;
+          ptr->clus=c;
+          BlkWrite(dv,buf,c,dir_size>>BLK_SIZE_BITS);
+          if (cur_dir_clus==dv->root_clus) {
+            br=CAlloc(BLK_SIZE);
+            BlkRead(dv,br,dv->drv_offset,1);
+            br->root_clus=c;
+            BlkWrite(dv,br,dv->drv_offset,1);
+            Free(br);
+            dv->root_clus=c;
+          } else {
+            tmp=StrNew(cur_dir);
+            parent_dir=StrNew(cur_dir);
+            StrLastRem(parent_dir,"/",tmp);
+            if (!*parent_dir) {
+              Free(parent_dir);
+              parent_dir=StrNew("/");
+            }
+            if (RedSeaFileFind(dv,Name2DirClus(dv,parent_dir),
+                  tmp,&de2,FUF_JUST_DIRS)) {
+              de2.clus=c;
+              de2.size=dir_size;
+              RedSeaDirNew(dv,parent_dir,&de2,FALSE);
+            } else
+              throw('Drv');
+            Free(tmp);
+            Free(parent_dir);
+          }
+        }
+        break;
+      } else if (ptr->attr & RS_ATTR_DELETED) {
+        if (!written) {
+          MemCpy(&ptr->start,&tmpde->start,CDIR_SIZE);
+          BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+          written=TRUE;
+        }
+      } else {
+        if (!StrCmp(tmpde->name,ptr->name)) {
+          if (free_old_chain)
+            RedSeaFreeClus(dv,ptr->clus,
+                  (ptr->size+BLK_SIZE-1)>>BLK_SIZE_BITS);
+          if (!written)
+            MemCpy(&ptr->start,&tmpde->start,CDIR_SIZE);
+          else
+            ptr->attr|=RS_ATTR_DELETED;
+          BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+          break;
+        }
+      }
+      ptr(U8 *)+=CDIR_SIZE;
+      if (++i>=n) {
+        j++;
+        i=0;
+      }
+    }
+    Free(buf);
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    if (unlock)
+      DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return FALSE;
+}
+
+I64 RedSeaFilesDel(CDrv *dv,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
+                     Bool del_dir,Bool print_msg)
+{
+  CDirEntry *buf,*buf2,*ptr;
+  I64 i=0,res=0,ch,j=0,n=BLK_SIZE/CDIR_SIZE,cur_dir_clus;
+  Bool unlock_break;
+  try {
+    unlock_break=BreakLock;
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,cur_dir);
+    buf2=MAlloc(BLK_SIZE);
+    BlkRead(dv,buf2,cur_dir_clus,1);
+
+    ptr=buf2(U8 *)-offset(CDirEntry.start);
+    buf=MAlloc(ptr->size);
+    BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+    Free(buf2);
+
+    ptr=buf(U8 *)-offset(CDirEntry.start);
+    *ptr->name='.';
+    ptr->name[1]=0;
+    while (TRUE) {
+      if (!(ch=*ptr->name))
+        break;
+      else if (!(ptr->attr & RS_ATTR_DELETED) && ch!='.' && (del_dir ||
+            !(ptr->attr & RS_ATTR_DIR)) &&
+            FilesFindMatch(ptr->name,files_find_mask,fuf_flags)) {
+        if (!(ptr->attr & RS_ATTR_DIR)) res++;
+        if (print_msg)
+          "Del %s\n",ptr->name;
+        ptr->attr|=RS_ATTR_DELETED;
+        BlkWrite(dv,buf(U8 *)+j<<BLK_SIZE_BITS,cur_dir_clus+j,1);
+        RedSeaFreeClus(dv,ptr->clus,
+              (ptr->size+BLK_SIZE-1)>>BLK_SIZE_BITS);
+      }
+      ptr(U8 *)+=CDIR_SIZE;
+      if (++i>=n) {
+        j++;
+        i=0;
+      }
+    }
+    Free(buf);
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  } catch {
+    DrvUnlock(dv);
+    if (unlock_break)
+      BreakUnlock;
+  }
+  return res;
+}
+
+I64 RedSeaFileWrite(CDrv *dv,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
+        CDate cdt,I64 attr)
+{
+  CDirEntry de;
+  I64 c=0,blk_cnt;
+  MemSet(&de,0,sizeof(CDirEntry));
+  if (size<0) size=0;
+  if (dv->fs_type!=FSt_REDSEA)
+    PrintErr("Not RedSea Drv\n");
+  else if (!CFileNameTo(de.name,name))
+    PrintErr("Invalid FileName: \"%s\".\n",name);
+  else {
+    RedSeaFilesDel(dv,cur_dir,de.name,0,FALSE,FALSE);
+    de.size=size;
+    if (blk_cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS)
+      c=ClusAlloc(dv,0,blk_cnt,TRUE); //Always contiguous
+    else
+      c=INVALID_CLUS;
+    de.clus=c;
+    de.attr=attr|RS_ATTR_CONTIGUOUS;
+    de.datetime=cdt;
+    if (blk_cnt)
+      BlkWrite(dv,buf,c,blk_cnt);
+    RedSeaDirNew(dv,cur_dir,&de,TRUE);
+  }
+  return c;
+}
+
+CDirEntry *RedSeaFilesFind(U8 *files_find_mask,I64 fuf_flags,
+        CDirEntry *parent=NULL)
+{
+  CDrv *dv=Fs->cur_dv;
+  CDirEntry *buf,*buf2,*ptr,*res=NULL,*tmpde;
+  I64 ch,cur_dir_clus;
+  if (fuf_flags&~FUG_FILES_FIND)
+    throw('FUF');
+  try {
+    DrvLock(dv);
+    cur_dir_clus=Name2DirClus(dv,Fs->cur_dir);
+    buf2=MAlloc(BLK_SIZE);
+    BlkRead(dv,buf2,cur_dir_clus,1);
+
+    ptr=buf2(U8 *)-offset(CDirEntry.start);
+    buf=MAlloc(ptr->size);
+    BlkRead(dv,buf,cur_dir_clus,ptr->size>>BLK_SIZE_BITS);
+    Free(buf2);
+
+    ptr=buf(U8 *)-offset(CDirEntry.start);
+    *ptr->name='.';
+    ptr->name[1]=0;
+    ptr(U8 *)+=CDIR_SIZE;
+    ptr->clus=Name2ParentDirClus(dv,Fs->cur_dir);
+    ptr(U8 *)-=CDIR_SIZE;
+    while (TRUE) {
+      if (!(ch=*ptr->name))
+        break;
+      else if (!(ptr->attr & RS_ATTR_DELETED)) {
+        tmpde=CAlloc(sizeof(CDirEntry));
+        MemCpy(&tmpde->start,&ptr->start,CDIR_SIZE);
+        tmpde->parent=parent;
+        if (Bt(&fuf_flags,FUf_RECURSE) && tmpde->attr&RS_ATTR_DIR &&
+              *tmpde->name!='.') {
+          tmpde->next=res;
+          res=tmpde;
+          tmpde->full_name=DirNameAbs(tmpde->name);
+          DrvUnlock(dv);
+          if (Cd(tmpde->name)) {
+            tmpde->sub=RedSeaFilesFind(files_find_mask,fuf_flags,tmpde);
+            Cd("..");
+          }
+          DrvLock(dv);
+        } else {
+          tmpde->full_name=FileNameAbs(tmpde->name);
+          if ((tmpde->attr&RS_ATTR_DIR ||
+                !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
+                !(Bt(&fuf_flags,FUf_RECURSE) && *tmpde->name=='.' &&
+                tmpde->attr&RS_ATTR_DIR) &&
+                FilesFindMatch(tmpde->full_name,files_find_mask,fuf_flags)) {
+            tmpde->next=res;
+            res=tmpde;
+          } else
+            DirEntryDel(tmpde);
+        }
+      }
+      ptr(U8 *)+=CDIR_SIZE;
+    }
+    Free(buf);
+    DrvUnlock(dv);
+  } catch
+    DrvUnlock(dv);
+  return res;
+}
+
+Bool RedSeaMkDir(CDrv *dv,U8 *cur_dir,U8 *name,I64 entry_cnt)
+{//entry_cnt is for preallocating dir blks.
+  I64   c,cur_dir_clus=Name2DirClus(dv,cur_dir),
+        size=CeilU64((entry_cnt+3)<<6,BLK_SIZE);
+#assert CDIR_SIZE==64
+  U8 *buf=CAlloc(size);
+  CDirEntry *d_native=buf-offset(CDirEntry.start);
+  Bool unlock_break;
+  try {
+    unlock_break=BreakLock;
+    c=FileWrite(name,buf,size,0,RS_ATTR_DIR);
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    StrCpy(d_native->name,name);
+    d_native->clus=c;
+    d_native->size=size;
+    d_native->datetime=Now;
+    d_native(U8 *)+=CDIR_SIZE;
+
+    d_native->attr=RS_ATTR_DIR|RS_ATTR_CONTIGUOUS;
+    *d_native->name='.';
+    d_native->name[1]='.';
+    d_native->name[2]=0;
+    d_native->clus=cur_dir_clus;
+    d_native->size=0;
+    d_native->datetime=Now;
+    BlkWrite(dv,buf,c,1);
+    Free(buf);
+    if (unlock_break)
+      BreakUnlock;
+  } catch
+    if (unlock_break)
+      BreakUnlock;
+  return TRUE;
+}
+
+ diff --git a/public/Wb/Kernel/BlkDev/MakeBlkDev.HC.HTML b/public/Wb/Kernel/BlkDev/MakeBlkDev.HC.HTML new file mode 100755 index 0000000..9b46f62 --- /dev/null +++ b/public/Wb/Kernel/BlkDev/MakeBlkDev.HC.HTML @@ -0,0 +1,54 @@ + + + + + + + + + + + +
+#exe {Cd(__DIR__);};
+#include "DskStrA"
+#include "DskCache"
+#include "DskATA"
+#include "DskATAId"
+#include "DskBlkDev"
+#include "DskDrv"
+#include "DskBlk"
+#include "DskClus"
+#include "DskStrB"
+#include "DskAddDev"
+#include "DskDirA"
+#include "FileSysRedSea"
+#include "FileSysFAT"
+#include "DskDirContext"
+#include "DskFind"
+#include "DskDirB"
+#include "DskFile"
+#include "DskCFile"
+#include "DskCopy"
+#include "DskCDDVD"
+#include "DskFmt"
+#exe {Cd("..");};
+
+ diff --git a/public/Wb/Kernel/Compress.HC.HTML b/public/Wb/Kernel/Compress.HC.HTML new file mode 100755 index 0000000..0ace222 --- /dev/null +++ b/public/Wb/Kernel/Compress.HC.HTML @@ -0,0 +1,339 @@ + + + + + + + + + + + +
+//See ::/Doc/Credits.DD.
+//See CArcCompress, CArcEntry, and CArcCtrl
+
+asm {
+/****
+U0 ArcEntryGet(CArcCtrl *c)
+{
+  I64 i;
+  CArcEntry *tmp,*tmp1;
+
+  if (c->entry_used) {
+    i=c->free_idx;
+
+    c->entry_used=FALSE;
+    c->cur_entry=c->next_entry;
+    c->cur_bits_in_use=c->next_bits_in_use;
+    if (c->next_bits_in_use<ARC_BITS_MAX) {
+      c->next_entry = &c->compress[i++];
+      if (i==c->free_limit) {
+        c->next_bits_in_use++;
+        c->free_limit=1<<c->next_bits_in_use;
+      }
+    } else {
+      do if (++i==c->free_limit)
+          i=c->min_table_entry;
+      while (c->hash[i]);
+      tmp=&c->compress[i];
+      c->next_entry=tmp;
+      tmp1=&c->hash[tmp->basecode];
+      while (tmp1) {
+        if (tmp1->next==tmp) {
+          tmp1->next=tmp->next;
+          break;
+        } else
+          tmp1=tmp1->next;
+      }
+    }
+    c->free_idx=i;
+  }
+}
+****/
+_ARC_ENTRY_GET::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        BTR     U64 CArcCtrl.entry_used[RSI],0
+        JNC     I32 @@30
+        MOV     RDX,U64 CArcCtrl.free_idx[RSI]
+        MOV     RAX,U64 CArcCtrl.next_entry[RSI]
+        MOV     U64 CArcCtrl.cur_entry[RSI],RAX
+        MOV     RCX,U64 CArcCtrl.next_bits_in_use[RSI]
+        MOV     U64 CArcCtrl.cur_bits_in_use[RSI],RCX
+        CMP     RCX,ARC_BITS_MAX
+        JAE     @@05
+        MOV     RAX,RDX
+        SHL     RAX,4
+        LEA     RAX,U64 CArcCtrl.compress[RSI+RAX]
+        MOV     U64 CArcCtrl.next_entry[RSI],RAX
+        INC     RDX
+        CMP     U64 CArcCtrl.free_limit[RSI],RDX
+        JNE     @@25
+        INC     RCX
+        MOV     U64 CArcCtrl.next_bits_in_use[RSI],RCX
+        MOV     RAX,1
+        SHL     RAX,CL
+        MOV     U64 CArcCtrl.free_limit[RSI],RAX
+        JMP     @@25
+@@05:   INC     RDX
+        CMP     U64 CArcCtrl.free_limit[RSI],RDX
+        JNE     @@10
+        MOV     RDX,U64 CArcCtrl.min_table_entry[RSI]
+@@10:   MOV     RAX,U64 CArcCtrl.hash[RSI+RDX*8]
+        TEST    RAX,RAX
+        JNZ     @@05
+        MOV     RDI,RDX
+        SHL     RDI,4
+        LEA     RDI,U64 CArcCtrl.compress[RSI+RDI]
+        MOV     U32 CArcCtrl.next_entry[RSI],EDI
+        MOVZX   RBX,U16 CArcEntry.basecode[RDI]
+        LEA     RCX,U64 CArcCtrl.hash[RSI+RBX*8]
+@@15:   TEST    RCX,RCX
+        JZ      @@25
+        MOV     RAX,U64 CArcEntry.next[RCX]
+        CMP     RDI,RAX
+        JNE     @@20
+        MOV     RAX,U64 CArcEntry.next[RDI]
+        MOV     U64 CArcEntry.next[RCX],RAX
+        JMP     @@25
+@@20:   MOV     RCX,RAX
+        JMP     @@15
+@@25:   MOV     U64 CArcCtrl.free_idx[RSI],RDX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    8
+}
+
+_extern _ARC_ENTRY_GET U0 ArcEntryGet(CArcCtrl *c);
+
+I64 ArcDetermineCompressionType(U8 *src,I64 size)
+{
+  while (size--)
+    if (*src++&0x80)
+      return CT_8_BIT;
+  return CT_7_BIT;
+}
+
+U0 ArcCompressBuf(CArcCtrl *c)
+{//Use CompressBuf() unless doing more than one buf.
+  CArcEntry *tmp,*tmp1;
+  I64 ch,basecode;
+  U8 *src_ptr,*src_limit;
+
+  src_ptr=c->src_buf+c->src_pos;
+  src_limit=c->src_buf+c->src_size;
+
+  if (c->saved_basecode==U32_MAX)
+    basecode=*src_ptr++;
+  else
+    basecode=c->saved_basecode;
+
+  while (src_ptr<src_limit && c->dst_pos+c->cur_bits_in_use<=c->dst_size) {
+    ArcEntryGet(c);
+ac_start:
+    if (src_ptr>=src_limit) goto ac_done;
+    ch=*src_ptr++;
+    if (tmp=c->hash[basecode])
+      do {
+        if (tmp->ch==ch) {
+          basecode=tmp-&c->compress[0];
+          goto ac_start;
+        }
+      } while (tmp=tmp->next);
+
+    BFieldOrU32(c->dst_buf,c->dst_pos,basecode);
+    c->dst_pos+=c->cur_bits_in_use;
+
+    c->entry_used=TRUE;
+    tmp=c->cur_entry;
+    tmp->basecode=basecode;
+    tmp->ch=ch;
+    tmp1=&c->hash[basecode];
+    tmp->next=tmp1->next;
+    tmp1->next=tmp;
+
+    basecode=ch;
+  }
+ac_done:
+  c->saved_basecode=basecode;
+  c->src_pos=src_ptr-c->src_buf;
+}
+
+Bool ArcFinishCompression(CArcCtrl *c)
+{//Do closing touch on archivew ctrl struct.
+  if (c->dst_pos+c->cur_bits_in_use<=c->dst_size) {
+    BFieldOrU32(c->dst_buf,c->dst_pos,c->saved_basecode);
+    c->dst_pos+=c->next_bits_in_use;
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 ArcExpandBuf(CArcCtrl *c)
+{//Use ExpandBuf() unless you know what you're doing.
+  U8 *dst_ptr,*dst_limit;
+  I64 basecode,lastcode,code;
+  CArcEntry *tmp,*tmp1;
+
+  dst_ptr=c->dst_buf+c->dst_pos;
+  dst_limit=c->dst_buf+c->dst_size;
+
+  while (dst_ptr<dst_limit && c->stk_ptr!=c->stk_base)
+    *dst_ptr++ = * -- c->stk_ptr;
+
+  if (c->stk_ptr==c->stk_base && dst_ptr<dst_limit) {
+    if (c->saved_basecode==U32_MAX) {
+      lastcode=BFieldExtU32(c->src_buf,c->src_pos,
+            c->next_bits_in_use);
+      c->src_pos+=c->next_bits_in_use;
+      *dst_ptr++=lastcode;
+      ArcEntryGet(c);
+      c->last_ch=lastcode;
+    } else
+      lastcode=c->saved_basecode;
+    while (dst_ptr<dst_limit && c->src_pos+c->next_bits_in_use<=c->src_size) {
+      basecode=BFieldExtU32(c->src_buf,c->src_pos,
+            c->next_bits_in_use);
+      c->src_pos+=c->next_bits_in_use;
+      if (c->cur_entry==&c->compress[basecode]) {
+        *c->stk_ptr++=c->last_ch;
+        code=lastcode;
+      } else
+        code=basecode;
+      while (code>=c->min_table_entry) {
+        *c->stk_ptr++=c->compress[code].ch;
+        code=c->compress[code].basecode;
+      }
+      *c->stk_ptr++=code;
+      c->last_ch=code;
+
+      c->entry_used=TRUE;
+      tmp=c->cur_entry;
+      tmp->basecode=lastcode;
+      tmp->ch=c->last_ch;
+      tmp1=&c->hash[lastcode];
+      tmp->next=tmp1->next;
+      tmp1->next=tmp;
+
+      ArcEntryGet(c);
+      while (dst_ptr<dst_limit && c->stk_ptr!=c->stk_base)
+        *dst_ptr++ = * -- c->stk_ptr;
+      lastcode=basecode;
+    }
+    c->saved_basecode=lastcode;
+  }
+  c->dst_pos=dst_ptr-c->dst_buf;
+}
+
+CArcCtrl *ArcCtrlNew(Bool expand,I64 compression_type=CT_8_BIT)
+{//MAlloc archive ctrl struct.
+  CArcCtrl *c;
+  c=CAlloc(sizeof(CArcCtrl));
+  if (expand) {
+    c->stk_base=MAlloc(1<<ARC_BITS_MAX);
+    c->stk_ptr=c->stk_base;
+  }
+  if (compression_type==CT_7_BIT)
+    c->min_bits=7;
+  else
+    c->min_bits=8;
+  c->min_table_entry=1<<c->min_bits;
+  c->free_idx=c->min_table_entry;
+  c->next_bits_in_use=c->min_bits+1;
+  c->free_limit=1<<c->next_bits_in_use;
+  c->saved_basecode=U32_MAX;
+  c->entry_used=TRUE;
+  ArcEntryGet(c);
+  c->entry_used=TRUE;
+  return c;
+}
+
+U0 ArcCtrlDel(CArcCtrl *c)
+{//Free archive ctrl struct.
+  Free(c->stk_base);
+  Free(c);
+}
+
+U8 *ExpandBuf(CArcCompress *arc,CTask *mem_task=NULL)
+{//See ::/Demo/Dsk/SerializeTree.HC.
+  CArcCtrl *c;
+  U8 *res;
+
+  if (!(CT_NONE<=arc->compression_type<=CT_8_BIT) ||
+        arc->expanded_size>mem_mapped_space)
+    throw('Compress');
+
+  res=MAlloc(arc->expanded_size+1,mem_task);
+  res[arc->expanded_size]=0; //terminate
+  switch [arc->compression_type] {
+    case CT_NONE:
+      MemCpy(res,&arc->body,arc->expanded_size);
+      break;
+    case CT_7_BIT:
+    case CT_8_BIT:
+      c=ArcCtrlNew(TRUE,arc->compression_type);
+      c->src_size=arc->compressed_size<<3;
+      c->src_pos=sizeof(CArcCompress)<<3;
+      c->src_buf=arc;
+      c->dst_size=arc->expanded_size;
+      c->dst_buf=res;
+      c->dst_pos=0;
+      ArcExpandBuf(c);
+      ArcCtrlDel(c);
+      break;
+  }
+  return res;
+}
+
+CArcCompress *CompressBuf(U8 *src,I64 size,CTask *mem_task=NULL)
+{//See ::/Demo/Dsk/SerializeTree.HC.
+  CArcCompress *arc;
+  I64 size_out,compression_type=ArcDetermineCompressionType(src,size);
+  CArcCtrl *c=ArcCtrlNew(FALSE,compression_type);
+  c->src_size=size;
+  c->src_buf=src;
+  c->dst_size=(size+sizeof(CArcCompress))<<3;
+  c->dst_buf=CAlloc(c->dst_size>>3);
+  c->dst_pos=sizeof(CArcCompress)<<3;
+  ArcCompressBuf(c);
+  if (ArcFinishCompression(c) && c->src_pos==c->src_size) {
+    size_out=(c->dst_pos+7)>>3;
+    arc=MAlloc(size_out,mem_task);
+    MemCpy(arc,c->dst_buf,size_out);
+    arc->compression_type=compression_type;
+    arc->compressed_size=size_out;
+  } else {
+    arc=MAlloc(size+sizeof(CArcCompress),mem_task);
+    MemCpy(&arc->body,src,size);
+    arc->compression_type=CT_NONE;
+    arc->compressed_size=size+sizeof(CArcCompress);
+  }
+  arc->expanded_size=size;
+  Free(c->dst_buf);
+  ArcCtrlDel(c);
+  return arc;
+}
+
+ diff --git a/public/Wb/Kernel/Display.HC.HTML b/public/Wb/Kernel/Display.HC.HTML new file mode 100755 index 0000000..8d0760f --- /dev/null +++ b/public/Wb/Kernel/Display.HC.HTML @@ -0,0 +1,152 @@ + + + + + + + + + + + +
+U0 RawPutChar(I64 ch)
+{/*For RAW output during boot and in debugger.
+
+See GrUpdateTextFG for
+the normal scrn text output routine.
+
+See also GrUpdateScrn().
+*/
+  I64 i,row,col;
+  U8 *ptr,*ptr1,*ptr2;
+
+  if (!(text.raw_flags&RWF_SHOW_DOLLAR)) {
+    if (ch=='$') {
+      if (text.raw_flags&RWF_IN_DOLLAR) {
+        text.raw_flags&=~RWF_IN_DOLLAR;
+        if (!(text.raw_flags & RWF_LAST_DOLLAR)) {
+          text.raw_flags&=~RWF_LAST_DOLLAR;
+          return;
+        }
+      } else {
+        text.raw_flags|=RWF_IN_DOLLAR|RWF_LAST_DOLLAR;
+        return;
+      }
+    }
+    text.raw_flags&=~RWF_LAST_DOLLAR;
+    if (text.raw_flags&RWF_IN_DOLLAR)
+      return;
+  }
+  if (ch=='\t') {
+    RawPutChar(CH_SPACE);
+    while (text.raw_col & 7)
+      RawPutChar(CH_SPACE);
+  } else if (ch==CH_BACKSPACE) {
+    text.raw_col--;
+    RawPutChar(CH_SPACE);
+    text.raw_col--;
+  } else if (ch=='\n') {
+    RawPutChar(CH_SPACE);
+    while (text.raw_col % text.cols)
+      RawPutChar(CH_SPACE);
+
+  } else if (Bt(char_bmp_displayable,ch)) {
+    row=text.raw_col/text.cols%text.rows;
+    col=text.raw_col%text.cols;
+    if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
+      if (text.raw_flags&RWF_SCROLL && text.raw_col && !row && !col) {
+        MemCpy(text.vga_text_alias,text.vga_text_alias+text.cols*2,
+              text.cols*(text.rows-1)*2);
+        MemSet(text.vga_text_alias+text.cols*(text.rows-1)*2,0,text.cols*2);
+        text.raw_col-=text.cols;
+        row=text.rows-1;
+      }
+      ptr=text.vga_text_alias+(row*text.cols+col)*2;
+      ptr[0]=ch;
+      ptr[1]=BLACK<<4+WHITE;
+    } else {
+      OutU8(VGAP_IDX,VGAR_MAP_MASK);
+      OutU8(VGAP_DATA,0x0F); //All planes -- WHITE
+      if (text.raw_flags&RWF_SCROLL && text.raw_col && !row && !col) {
+//Scroll cached image
+        MemCpy(text.raw_scrn_image,
+              text.raw_scrn_image+GR_WIDTH*FONT_HEIGHT>>3,
+              GR_WIDTH*(GR_HEIGHT-FONT_HEIGHT)>>3);
+        MemSet(text.raw_scrn_image+GR_WIDTH*(GR_HEIGHT-FONT_HEIGHT)>>3,0,
+              GR_WIDTH*FONT_HEIGHT>>3);
+
+        MemCpy(text.vga_alias,text.raw_scrn_image,GR_WIDTH*GR_HEIGHT>>3);
+        text.raw_col-=text.cols;
+        row=text.rows-1;
+      }
+      PUSHFD
+      CLI
+      ptr=ptr1=col+row*GR_WIDTH*FONT_HEIGHT>>3;
+      ptr+=text.vga_alias;
+      ptr1+=text.raw_scrn_image; //Write to cached image as well
+      ptr2=&text.font[ch&255];
+      for (i=0;i<FONT_HEIGHT;i++) {
+        *ptr=*ptr1=rev_bits_table[*ptr2++];
+        ptr+=GR_WIDTH>>3;
+        ptr1+=GR_WIDTH>>3;
+      }
+      POPFD
+    }
+    text.raw_col++;
+  }
+}
+
+U0 VGAFlush()
+{//Flush winmgr vga cache, so updates whole scrn.
+  LBts(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0);
+}
+
+U0 WinDerivedValsUpdate(CTask *task)
+{//Those things calculated from other variables.
+  if (!task) task=Fs;
+  //Assert: This is called with TASKf_TASK_LOCK set
+  PUSHFD
+  CLI
+  task->win_width =task->win_right-task->win_left+1;
+  task->win_height=task->win_bottom-task->win_top+1;
+  task->pix_left        =FONT_WIDTH*task->win_left;
+  task->pix_right       =FONT_WIDTH*(task->win_right+1)-1;
+  task->pix_width       =task->pix_right-task->pix_left+1;
+  task->pix_top         =FONT_HEIGHT*task->win_top;
+  task->pix_bottom      =FONT_HEIGHT*(task->win_bottom+1)-1;
+  task->pix_height      =task->pix_bottom-task->pix_top+1;
+  POPFD
+}
+
+Bool WinInside(I64 x,I64 y,CTask *task=NULL,I64 border=0)
+{//Is pixel (x,y) inside task's win? Border to FONT_WIDTH.
+  if (!task) task=Fs;
+  if (TaskValidate(task) && Bt(&task->display_flags,DISPLAYf_SHOW)) {
+    if (Bt(&task->display_flags,DISPLAYf_NO_BORDER))
+      border=0;
+    if (task->pix_left-border<=x<=task->pix_right+border &&
+          task->pix_top-border<=y<=task->pix_bottom+border)
+      return TRUE;
+  }
+  return FALSE;
+}
+
+ diff --git a/public/Wb/Kernel/EdLite.HC.HTML b/public/Wb/Kernel/EdLite.HC.HTML new file mode 100755 index 0000000..363821e --- /dev/null +++ b/public/Wb/Kernel/EdLite.HC.HTML @@ -0,0 +1,386 @@ + + + + + + + + + + + +
+class CLine
+{
+  CLine *next,*last;
+  U8 *line;
+};
+
+U0 EdLiteUpdate(CLine *head,CLine *cur_line,I64 cur_col,I64 line_start_col)
+{
+  I64 ch,i,j,k,k2,cursor_col,cursor_row=-1;
+  U8 *st;
+  CLine *tmpl=cur_line;
+  Bool done_eof=FALSE;
+  text.raw_col=0;
+  for (i=0;i<text.rows/2;i++)
+    if (tmpl->last!=head)
+      tmpl=tmpl->last;
+  for (i=0;i<text.rows;i++) {
+    if (cursor_row<0 && tmpl==cur_line) {
+      k=0;
+      for (j=0;j<cur_col;j++)
+        if (tmpl->line[j]=='\t')
+          k=(k+8)&~7;
+        else
+          k++;
+      cursor_col=k;
+      cursor_row=i;
+    }
+    if (tmpl!=head) {
+      st=tmpl->line;
+      k=0;
+      j=0;
+      while (ch=*st++) {
+        if (ch=='\t')
+          k2=(k+8)&~7;
+        else
+          k2=k+1;
+        if (line_start_col<=k<line_start_col+text.cols) {
+          '' ch;
+          j=k2-line_start_col;
+        }
+        k=k2;
+      }
+      if (j<text.cols)
+        '\n';
+      tmpl=tmpl->next;
+    } else {
+      if (!done_eof) {
+        '<EOF>';
+        done_eof=TRUE;
+      }
+      '\n';
+    }
+  }
+  text.raw_col=text.cols*cursor_row+cursor_col-line_start_col;
+  RawPutChar(0x7F);
+}
+
+Bool EdLite(U8 *filename,I64 num=1,I64 edf_dof_flags=0)
+{//Light weight text editor for debugging.
+  U8 *src,*src2,*src3,*dst,*buf,*bin_data=NULL;
+  I64 i,cnt=0,ch,sc,size,bin_size=0,line_start_col=0,cur_col=0,
+        old_raw_flags=text.raw_flags;
+  CLine head,*tmpl,*tmpl1,*cur_line;
+  Bool  res=FALSE,
+        old_raw=Raw(ON),
+        old_debug=DbgMode(ON),
+        old_single=SingleUser(ON);
+
+  if (!filename) filename=blkdev.tmp_filename;
+  buf=FileRead(filename,&size);
+
+  PUSHFD
+  CLI
+  text.raw_flags=text.raw_flags&~RWF_SCROLL|RWF_SHOW_DOLLAR;
+  kbd.scan_code=0;
+  QueInit(&head);
+  head.line=StrNew("");
+
+  if (buf) {
+    src=buf;
+    while (*src) {
+      src2=src;
+      while ((ch=*src++) && ch!='\r' && ch!='\n');
+      src--;
+      *src++=0;
+      if (!ch)
+        src--;
+      while (ch=='\r' && *src=='\n' || *src==CH_CURSOR)
+        src++;
+      dst=src3=src2;
+      while (ch=*src3++)
+        if (ch!='\n' && ch!=CH_CURSOR)
+          *dst++=ch;
+      *dst=0;
+
+      tmpl=MAlloc(sizeof(CLine));
+      tmpl->line=StrNew(src2);
+      QueIns(tmpl,head.last);
+      cnt++;
+    }
+
+    if (src+1-buf<size) {
+      bin_data=MAlloc(bin_size=size-(src-buf));
+      MemCpy(bin_data,src,bin_size);
+    }
+    Free(buf);
+    res=TRUE;
+  }
+
+  cur_line=head.next;
+  if (--num<0)
+    res=FALSE;
+  else {
+    if (num<=cnt)
+      while (num--)
+        cur_line=cur_line->next;
+    else {
+      cur_line=&head;
+      res=FALSE;
+    }
+  }
+  do {
+    if (cur_line==&head)
+      cur_col=0;
+    while (cur_col-line_start_col<0)
+      line_start_col-=8;
+    while (cur_col-line_start_col>=text.cols)
+      line_start_col+=8;
+    EdLiteUpdate(&head,cur_line,cur_col,line_start_col);
+    switch (ch=GetKey(&sc,FALSE,TRUE)) {
+      case 0:
+        switch (sc.u8[0]) {
+          case SC_CURSOR_UP:
+            if (cur_line->last!=&head)
+              cur_line=cur_line->last;
+            if (cur_col>StrLen(cur_line->line))
+              cur_col=StrLen(cur_line->line);
+            break;
+          case SC_CURSOR_DOWN:
+            if (cur_line!=&head)
+              cur_line=cur_line->next;
+            if (cur_col>StrLen(cur_line->line))
+              cur_col=StrLen(cur_line->line);
+            break;
+          case SC_CURSOR_RIGHT:
+            cur_col++;
+            if (cur_col>StrLen(cur_line->line)) {
+              tmpl=cur_line->next;
+              if (tmpl!=&head) {
+                cur_col=0;
+                cur_line=tmpl;
+              } else
+                cur_col=StrLen(cur_line->line);
+            }
+            break;
+          case SC_CURSOR_LEFT:
+            if (cur_col)
+              cur_col--;
+            else {
+              tmpl=cur_line->last;
+              if (tmpl!=&head) {
+                cur_line=tmpl;
+                cur_col=StrLen(tmpl->line);
+              }
+            }
+            break;
+          case SC_PAGE_UP:
+            for (i=1;i<text.rows;i++) {
+              if (cur_line->last!=&head)
+                cur_line=cur_line->last;
+              if (cur_col>StrLen(cur_line->line))
+                cur_col=StrLen(cur_line->line);
+            }
+            break;
+          case SC_PAGE_DOWN:
+            for (i=1;i<text.rows;i++) {
+              if (cur_line!=&head)
+                cur_line=cur_line->next;
+              if (cur_col>StrLen(cur_line->line))
+                cur_col=StrLen(cur_line->line);
+            }
+            break;
+          case SC_DELETE:
+            if (cur_col==StrLen(cur_line->line)) {
+              tmpl=cur_line->next;
+              if (cur_line!=&head && tmpl!=&head) {
+                src=MStrPrint("%s%s",cur_line->line,tmpl->line);
+                Free(cur_line->line);
+                Free(tmpl->line);
+                cur_line->line=src;
+                QueRem(tmpl);
+                Free(tmpl);
+              }
+            } else
+              StrCpy(cur_line->line+cur_col,cur_line->line+cur_col+1);
+            break;
+        }
+        break;
+      case '\n':
+      case '\r':
+        tmpl=MAlloc(sizeof(CLine));
+        tmpl->line=StrNew(cur_line->line+cur_col);
+        cur_line->line[cur_col]=0;
+        QueIns(tmpl,cur_line);
+        cur_line=tmpl;
+        cur_col=0;
+        break;
+      case CH_BACKSPACE:
+        if (cur_col) {
+          StrCpy(cur_line->line+cur_col-1,cur_line->line+cur_col);
+          cur_col--;
+        } else if (cur_line!=&head && cur_line->last!=&head) {
+          tmpl=cur_line->last;
+          src=MStrPrint("%s%s",tmpl->line,cur_line->line);
+          cur_col=StrLen(tmpl->line);
+          Free(cur_line->line);
+          Free(tmpl->line);
+          tmpl->line=src;
+          QueRem(cur_line);
+          Free(cur_line);
+          cur_line=tmpl;
+        }
+        break;
+      case CH_CTRLY:
+        if (cur_line!=&head) {
+          tmpl=cur_line;
+          cur_line=cur_line->next;
+          QueRem(tmpl);
+          Free(tmpl->line);
+          Free(tmpl);
+          cur_col=0;
+        }
+        break;
+      default:
+        if (Bt(char_bmp_printable,ch)) {
+          if (cur_line==&head) {
+            cur_line=MAlloc(sizeof(CLine));
+            cur_line->line=StrNew("");
+            QueIns(cur_line,head.last);
+          }
+          src=MAlloc(StrLen(cur_line->line)+2);
+          MemCpy(src,cur_line->line,cur_col);
+          src[cur_col]=ch;
+          if (cur_col<StrLen(cur_line->line))
+            StrCpy(src+cur_col+1,cur_line->line+cur_col);
+          else
+            src[cur_col+1]=0;
+          Free(cur_line->line);
+          cur_line->line=src;
+          cur_col++;
+        }
+    }
+  } while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
+
+  if (ch!=CH_ESC) {
+    if (edf_dof_flags&EDF_WAS_WRITE)
+      res=FALSE;
+  } else {
+    size=bin_size;
+
+    tmpl=head.next;
+    while (tmpl!=&head) {
+      size+=StrLen(tmpl->line)+1;
+      tmpl=tmpl->next;
+    }
+
+    buf=dst=MAlloc(size);
+    tmpl=head.next;
+    while (tmpl!=&head) {
+      i=StrLen(tmpl->line);
+      MemCpy(dst,tmpl->line,i);
+      dst+=i;
+      *dst++='\n';
+      tmpl=tmpl->next;
+    }
+    if (bin_data)
+      MemCpy(dst,bin_data,bin_size);
+    FileWrite(filename,buf,size);
+    Free(buf);
+
+    if (edf_dof_flags&EDF_WAS_WRITE)
+      res=TRUE;
+  }
+
+  tmpl=head.next;
+  while (tmpl!=&head) {
+    tmpl1=tmpl->next;
+    QueRem(tmpl);
+    Free(tmpl->line);
+    Free(tmpl);
+    tmpl=tmpl1;
+  }
+  Free(head.line);
+  Free(bin_data);
+  Raw(old_raw);
+  DbgMode(old_debug);
+  SingleUser(old_single);
+  text.raw_flags=text.raw_flags&~RWF_SHOW_DOLLAR|old_raw_flags&RWF_SHOW_DOLLAR;
+  POPFD
+  return res;
+}
+
+U0 ToFileLine(U8 *_fl_file_line,U8 **_filename,I64 *_linenum)
+{//"FI:D:/Dir/File.HC,123" to "D:/Dir/File.HC" and 123.
+  U8 *st,*fl_file_line=StrNew(_fl_file_line);
+  I64 linenum;
+  StrFirstRem(fl_file_line,":");
+  st=StrNew(fl_file_line);
+  StrLastRem(fl_file_line,",",st);
+  linenum=Str2I64(st);
+  Free(st);
+  *_filename=fl_file_line;
+  *_linenum=linenum;
+}
+
+Bool EdLiteFileLine(U8 *fl_file_line,I64 edf_dof_flags=0)
+{
+  Bool res;
+  U8 *filename;
+  I64 linenum;
+  ToFileLine(fl_file_line,&filename,&linenum);
+  res=EdLite(filename,linenum,edf_dof_flags);
+  Free(filename);
+  return res;
+}
+
+U0 FixSet(U8 *filename,I64 line)
+{//Compiler calls this to set file line for Fix
+  U8 *st=MStrPrint("FL:%s,%d",filename,line);
+  while (LBts(&sys_semas[SEMA_FIX],0))
+    Yield;
+  Free(dbg.fix_file_line);
+  dbg.fix_file_line=AStrNew(st);
+  LBtr(&sys_semas[SEMA_FIX],0);
+}
+
+Bool Fix(I64 edf_dof_flags=0)
+{//Jump to last err src code to fix it.
+  U8 *st;
+  Bool res=FALSE;
+
+  while (LBts(&sys_semas[SEMA_FIX],0))
+    Yield;
+  st=StrNew(dbg.fix_file_line);
+  LBtr(&sys_semas[SEMA_FIX],0);
+
+  if (st) {
+    if (IsRaw)
+      res=EdLiteFileLine(st,edf_dof_flags);
+    else
+      res=Ed(st,edf_dof_flags);
+  }
+  Free(st);
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/FontCyrillic.HC.HTML b/public/Wb/Kernel/FontCyrillic.HC.HTML new file mode 100755 index 0000000..fd9a50b --- /dev/null +++ b/public/Wb/Kernel/FontCyrillic.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+//See ::/Doc/Credits.DD.
+
+U64 sys_font_cyrillic[256]= {
+0x0000000000000000,0x0000000000000000,
+0x000000FF00000000,0x000000FF00FF0000,//..
+0x1818181818181818,0x6C6C6C6C6C6C6C6C,//..
+0x181818F800000000,0x6C6C6CEC0CFC0000,//..
+0x1818181F00000000,0x6C6C6C6F607F0000,//..
+0x000000F818181818,0x000000FC0CEC6C6C,//..
+0x0000001F18181818,0x0000007F606F6C6C,//..
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0008000000000000,//
+0x0000000000000000,0x00180018183C3C18,// !
+0x0000000000363636,0x006C6CFE6CFE6C6C,//"#
+0x00187ED07C16FC30,0x0060660C18306606,//$%
+0x00DC66B61C36361C,0x0000000000181818,//&'
+0x0030180C0C0C1830,0x000C18303030180C,//()
+0x0000187E3C7E1800,0x000018187E181800,//*+
+0x0C18180000000000,0x000000007E000000,//,-
+0x0018180000000000,0x0000060C18306000,//./
+0x003C666E7E76663C,0x007E181818181C18,//01
+0x007E0C183060663C,0x003C66603860663C,//23
+0x0030307E363C3830,0x003C6660603E067E,//45
+0x003C66663E060C38,0x000C0C0C1830607E,//67
+0x003C66663C66663C,0x001C30607C66663C,//89
+0x0018180018180000,0x0C18180018180000,//:;
+0x0030180C060C1830,0x0000007E007E0000,//<=
+0x000C18306030180C,0x001800181830663C,//>?
+0x003C06765676663C,0x006666667E66663C,//@A
+0x003E66663E66663E,0x003C66060606663C,//BC
+0x001E36666666361E,0x007E06063E06067E,//DE
+0x000606063E06067E,0x003C66667606663C,//FG
+0x006666667E666666,0x007E18181818187E,//HI
+0x001C36303030307C,0x0066361E0E1E3666,//JK
+0x007E060606060606,0x00C6C6D6D6FEEEC6,//LM
+0x006666767E6E6666,0x003C66666666663C,//NO
+0x000606063E66663E,0x006C36566666663C,//PQ
+0x006666363E66663E,0x003C66603C06663C,//RS
+0x001818181818187E,0x003C666666666666,//TU
+0x00183C6666666666,0x00C6EEFED6D6C6C6,//VW
+0x0066663C183C6666,0x001818183C666666,//XY
+0x007E060C1830607E,0x003E06060606063E,//Z[
+0x00006030180C0600,0x007C60606060607C,//\]
+0x000000000000663C,0xFFFF000000000000,//^_
+0x000000000030180C,0x007C667C603C0000,//`a
+0x003E6666663E0606,0x003C6606663C0000,//bc
+0x007C6666667C6060,0x003C067E663C0000,//de
+0x000C0C0C3E0C0C38,0x3C607C66667C0000,//fg
+0x00666666663E0606,0x003C1818181C0018,//hi
+0x0E181818181C0018,0x0066361E36660606,//jk
+0x003C18181818181C,0x00C6D6D6FE6C0000,//lm
+0x00666666663E0000,0x003C6666663C0000,//no
+0x06063E66663E0000,0xE0607C66667C0000,//pq
+0x000606066E360000,0x003E603C067C0000,//rs
+0x00380C0C0C3E0C0C,0x007C666666660000,//tu
+0x00183C6666660000,0x006CFED6D6C60000,//vw
+0x00663C183C660000,0x3C607C6666660000,//xy
+0x007E0C18307E0000,0x003018180E181830,//z{
+0x0018181818181818,0x000C18187018180C,//|}
+0x000000000062D68C,0xFFFFFFFFFFFFFFFF,//~
+0x1E30181E3303331E,0x007E333333003300,//..
+0x001E033F331E0038,0x00FC667C603CC37E,//..
+0x007E333E301E0033,0x007E333E301E0007,//..
+0x007E333E301E0C0C,0x3C603E03033E0000,//..
+0x003C067E663CC37E,0x001E033F331E0033,//..
+0x001E033F331E0007,0x001E0C0C0C0E0033,//..
+0x003C1818181C633E,0x001E0C0C0C0E0007,//..
+0x00333F33331E0C33,0x00333F331E000C0C,//..
+0x003F061E063F0038,0x00FE33FE30FE0000,//..
+0x007333337F33367C,0x001E33331E00331E,//..
+0x001E33331E003300,0x001E33331E000700,//..
+0x007E33333300331E,0x007E333333000700,//..
+0x1F303F3333003300,0x001C3E63633E1C63,//..
+0x001E333333330033,0x18187E03037E1818,//..
+0x003F67060F26361C,0x000C3F0C3F1E3333,//..
+0x70337B332F1B1B0F,0x0E1B18187E18D870,//..
+0x000F11110F01111F,0x000101010101111F,//..
+0x000F0107010F000A,0x001515150E151515,//..
+0x000F10100E10100F,0x0011111315191111,//..
+0x001113151911040A,0x001215141414141E,//..
+0x001111111111111F,0x000102040A111111,//..
+0x00040E1515150E04,0x001010101E111111,//..
+0x001F151515151515,0x000E12120E020203,//..
+0x0013151513111111,0x000E11101C10110E,//..
+0x0009151517151509,0x001112141E11111E,//..
+0x000E11110F010618,0x0007090709070000,//..
+0x00010101111F0000,0x000E011F110E000A,//..
+0x0015150E15150000,0x000F100C100F0000,//..
+0x0011131519110000,0x0013151911040A00,//..
+0x0009050305090000,0x00121514141E0000,//..
+0x001111151B110000,0x0011111F11110000,//..
+0x00111111111F0000,0x00040404041F0000,//..
+0x0010101E11110000,0x001F151515150000,//..
+0x000E120E02030000,0x0013151311110000,//..
+0x0007090701010000,0x000E111C110E0000,//..
+0x0009151715090000,0x0012141E111E0000,//..
+0x0004120912040000,0x0004091209040000,//..
+0x001B091200000000,0x000000000009121B,//..
+0x001C141C090D0B09,0x000E110102040004,//..
+0x000304040E040418,0x001E02020F020A04,//..
+0x0004040000000000,0x0004040404000000,//..
+0x000E000A0A0A0000,0x000A000A0A0A0000,//..
+0x0001020408170005,0x00001B0E040E1B00,//..
+0x0001020408150205,0x00000E040404040E,//..
+0x00001F0A0A0A0A1F,0x0004040404150E04,//..
+0x00040E1504040404,0x0001090D1F0D0901,//..
+0x001012161F161210,0x000111151F151101,//..
+0x0001020408110701,0x000000000C0C0000,//..
+0x111F11121414141E,0x101F111111111111,//..
+0x101F151515151515,0x111F1112141E0000,//.pi
+0x040E15150E040400,0x101A111111110000,//..
+0x101F151515150000,0x0000000000000408,//u.
+0x000000000000000A,0x0000000000000D12,//phitheta
+0x000E011F110E0408,0x06040E11010E0000,//omega.
+0x0006080A0A0A000A,0x0000041F0E0E0E04,//inf.
+0x00000A0011000A00,0x00000E1111110E00,//..
+0x0010101D1A150911,0x001C1019121D0911,//..
+0x001C0419121D0911,0x10101C1B12030203,//..
+0x00111F111F111F11,0x0000000600180003,//..
+0x041E141015070502,0x07020E021E020E02,//..
+0x0E040E041F040E04,0x1C08160017001600,//..
+0x1C080E080F080E08,0x00040E041F040E04,//..
+0x1C08090A0C0A0908,0x0609040A0A04120C,//..
+0x001414141E15151E,0xFFFFFFFFFFFFFFFF,//..
+};
+
+ diff --git a/public/Wb/Kernel/FontStd.HC.HTML b/public/Wb/Kernel/FontStd.HC.HTML new file mode 100755 index 0000000..f1a281a --- /dev/null +++ b/public/Wb/Kernel/FontStd.HC.HTML @@ -0,0 +1,163 @@ + + + + + + + + + + + +
+//See ::/Doc/Credits.DD.
+
+U64 sys_font_std[256]= {
+0x0000000000000000,0x0000000000000000,
+0x000000FF00000000,0x000000FF00FF0000,//..
+0x1818181818181818,0x6C6C6C6C6C6C6C6C,//..
+0x181818F800000000,0x6C6C6CEC0CFC0000,//..
+0x1818181F00000000,0x6C6C6C6F607F0000,//..
+0x000000F818181818,0x000000FC0CEC6C6C,//..
+0x0000001F18181818,0x0000007F606F6C6C,//..
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0000000000000000,
+0x0000000000000000,0x0008000000000000,//
+0x0000000000000000,0x00180018183C3C18,// !
+0x0000000000363636,0x006C6CFE6CFE6C6C,//"#
+0x00187ED07C16FC30,0x0060660C18306606,//$%
+0x00DC66B61C36361C,0x0000000000181818,//&'
+0x0030180C0C0C1830,0x000C18303030180C,//()
+0x0000187E3C7E1800,0x000018187E181800,//*+
+0x0C18180000000000,0x000000007E000000,//,-
+0x0018180000000000,0x0000060C18306000,//./
+0x003C666E7E76663C,0x007E181818181C18,//01
+0x007E0C183060663C,0x003C66603860663C,//23
+0x0030307E363C3830,0x003C6660603E067E,//45
+0x003C66663E060C38,0x000C0C0C1830607E,//67
+0x003C66663C66663C,0x001C30607C66663C,//89
+0x0018180018180000,0x0C18180018180000,//:;
+0x0030180C060C1830,0x0000007E007E0000,//<=
+0x000C18306030180C,0x001800181830663C,//>?
+0x003C06765676663C,0x006666667E66663C,//@A
+0x003E66663E66663E,0x003C66060606663C,//BC
+0x001E36666666361E,0x007E06063E06067E,//DE
+0x000606063E06067E,0x003C66667606663C,//FG
+0x006666667E666666,0x007E18181818187E,//HI
+0x001C36303030307C,0x0066361E0E1E3666,//JK
+0x007E060606060606,0x00C6C6D6D6FEEEC6,//LM
+0x006666767E6E6666,0x003C66666666663C,//NO
+0x000606063E66663E,0x006C36566666663C,//PQ
+0x006666363E66663E,0x003C66603C06663C,//RS
+0x001818181818187E,0x003C666666666666,//TU
+0x00183C6666666666,0x00C6EEFED6D6C6C6,//VW
+0x0066663C183C6666,0x001818183C666666,//XY
+0x007E060C1830607E,0x003E06060606063E,//Z[
+0x00006030180C0600,0x007C60606060607C,//\]
+0x000000000000663C,0xFFFF000000000000,//^_
+0x000000000030180C,0x007C667C603C0000,//`a
+0x003E6666663E0606,0x003C6606663C0000,//bc
+0x007C6666667C6060,0x003C067E663C0000,//de
+0x000C0C0C3E0C0C38,0x3C607C66667C0000,//fg
+0x00666666663E0606,0x003C1818181C0018,//hi
+0x0E181818181C0018,0x0066361E36660606,//jk
+0x003C18181818181C,0x00C6D6D6FE6C0000,//lm
+0x00666666663E0000,0x003C6666663C0000,//no
+0x06063E66663E0000,0xE0607C66667C0000,//pq
+0x000606066E360000,0x003E603C067C0000,//rs
+0x00380C0C0C3E0C0C,0x007C666666660000,//tu
+0x00183C6666660000,0x006CFED6D6C60000,//vw
+0x00663C183C660000,0x3C607C6666660000,//xy
+0x007E0C18307E0000,0x003018180E181830,//z{
+0x0018181818181818,0x000C18187018180C,//|}
+0x000000000062D68C,0xFFFFFFFFFFFFFFFF,//~
+0x1E30181E3303331E,0x007E333333003300,//..
+0x001E033F331E0038,0x00FC667C603CC37E,//..
+0x007E333E301E0033,0x007E333E301E0007,//..
+0x007E333E301E0C0C,0x3C603E03033E0000,//..
+0x003C067E663CC37E,0x001E033F331E0033,//..
+0x001E033F331E0007,0x001E0C0C0C0E0033,//..
+0x003C1818181C633E,0x001E0C0C0C0E0007,//..
+0x00333F33331E0C33,0x00333F331E000C0C,//..
+0x003F061E063F0038,0x00FE33FE30FE0000,//..
+0x007333337F33367C,0x001E33331E00331E,//..
+0x001E33331E003300,0x001E33331E000700,//..
+0x007E33333300331E,0x007E333333000700,//..
+0x1F303F3333003300,0x001C3E63633E1C63,//..
+0x001E333333330033,0x18187E03037E1818,//..
+0x003F67060F26361C,0x000C3F0C3F1E3333,//..
+0x70337B332F1B1B0F,0x0E1B18187E18D870,//..
+0x007E333E301E0038,0x001E0C0C0C0E001C,//..
+0x001E33331E003800,0x007E333333003800,//..
+0x003333331F001F00,0x00333B3F3733003F,//..
+0x00007E007C36363C,0x00007E003C66663C,//..
+0x001E3303060C000C,0x000003033F000000,//..
+0x000030303F000000,0xF81973C67C1B3363,//..
+0xC0F9F3E6CF1B3363,0x183C3C1818001800,//..
+0x0000CC663366CC00,0x00003366CC663300,//..
+0x1144114411441144,0x55AA55AA55AA55AA,//..
+0xEEBBEEBBEEBBEEBB,0x1818181818181818,//..
+0x1818181F18181818,0x1818181F181F1818,//..
+0x6C6C6C6F6C6C6C6C,0x6C6C6C7F00000000,//..
+0x1818181F181F0000,0x6C6C6C6F606F6C6C,//..
+0x6C6C6C6C6C6C6C6C,0x6C6C6C6F607F0000,//..
+0x0000007F606F6C6C,0x0000007F6C6C6C6C,//..
+0x0000001F181F1818,0x1818181F00000000,//..
+0x000000F818181818,0x000000FF18181818,//..
+0x181818FF00000000,0x181818F818181818,//..
+0x000000FF00000000,0x181818FF18181818,//..
+0x181818F818F81818,0x6C6C6CEC6C6C6C6C,//..
+0x000000FC0CEC6C6C,0x6C6C6CEC0CFC0000,//..
+0x000000FF00EF6C6C,0x6C6C6CEF00FF0000,//..
+0x6C6C6CEC0CEC6C6C,0x000000FF00FF0000,//..
+0x6C6C6CEF00EF6C6C,0x000000FF00FF1818,//..
+0x000000FF6C6C6C6C,0x181818FF00FF0000,//..
+0x6C6C6CFF00000000,0x000000FC6C6C6C6C,//..
+0x000000F818F81818,0x181818F818F80000,//..
+0x6C6C6CFC00000000,0x6C6C6CEF6C6C6C6C,//..
+0x181818FF00FF1818,0x0000001F18181818,//..
+0x181818F800000000,0xFFFFFFFFFFFFFFFF,//..
+0xFFFFFFFF00000000,0x0F0F0F0F0F0F0F0F,//..
+0xF0F0F0F0F0F0F0F0,0x00000000FFFFFFFF,//..
+0x006E3B133B6E0000,0x03031F331F331E00,//..
+0x0003030303637F00,0x0036363636367F00,//.pi
+0x007F660C180C667F,0x001E3333337E0000,//..
+0x03063E6666666600,0x00181818183B6E00,//u.
+0x3F0C1E33331E0C3F,0x001C36637F63361C,//phitheta
+0x007736366363361C,0x001E33333E180C38,//omega.
+0x00007EDBDB7E0000,0x03067EDBDB7E3060,//inf.
+0x003C06033F03063C,0x003333333333331E,//..
+0x00003F003F003F00,0x003F000C0C3F0C0C,//..
+0x003F00060C180C06,0x003F00180C060C18,//..
+0x1818181818D8D870,0x0E1B1B1818181818,//..
+0x000C0C003F000C0C,0x0000394E00394E00,//..
+0x000000001C36361C,0x0000001818000000,//..
+0x0000001800000000,0x383C3637303030F0,//..
+0x000000363636361E,0x0000003E061C301E,//..
+0x00003C3C3C3C0000,0xFFFFFFFFFFFFFFFF,//..
+};
+
+ diff --git a/public/Wb/Kernel/FunSeg.HC.HTML b/public/Wb/Kernel/FunSeg.HC.HTML new file mode 100755 index 0000000..c30c45a --- /dev/null +++ b/public/Wb/Kernel/FunSeg.HC.HTML @@ -0,0 +1,391 @@ + + + + + + + + + + + +
+I64 HasLower(U8 *src)
+{
+  I64 ch;
+  while (ch=*src++)
+    if ('a'<=ch<='z')
+      return TRUE;
+  return FALSE;
+}
+
+U0 HashFunSegFind(CHashTable *h,U8 *addr,
+        Bool *_has_lower,U64 *_best,CHash **_res)
+{
+  Bool *has_lower=*_has_lower;
+  CHashExport *tmpex;
+  U64 i,j,best=*_best;
+  CHash *res=*_res;
+  for (i=0;i<=h->mask;i++) {
+    tmpex=h->body[i];
+    while (tmpex) {
+      j=0;
+      if (tmpex->type&HTT_FUN) {
+        if (!Bt(&tmpex(CHashFun *)->flags,Cf_EXTERN) &&
+              !Bt(&tmpex(CHashFun *)->flags,Ff_INTERNAL))
+          j=tmpex(CHashFun *)->exe_addr;
+      } else if (tmpex->type&HTT_EXPORT_SYS_SYM)
+        j=tmpex->val;
+      if (j) {
+        j=addr(I64)-j;
+        if (0<=j<=best) {
+          if (tmpex->type&HTT_EXPORT_SYS_SYM) {
+            if (j<best || j==best && !has_lower) {
+              has_lower=HasLower(tmpex->str);
+              best=j;
+              res=tmpex;
+            }
+          } else if (tmpex->type&HTT_FUN) {
+            if (j<best || j==best &&
+                  (res && res->type&HTT_EXPORT_SYS_SYM||!has_lower)) {
+              has_lower=HasLower(tmpex->str);
+              best=j;
+              res=tmpex;
+            }
+          }
+        }
+      }
+      tmpex=tmpex->next;
+    }
+  }
+  *_has_lower=has_lower;
+  *_best=best;
+  *_res =res;
+}
+
+CHash *FunSegFind(U8 *addr,I64 *_offset)
+{//See Hash.
+  CHash *res=NULL;
+  Bool has_lower=FALSE;
+  CTask *task;
+  CHashTable *h;
+  CCPU *c;
+  U64 i,best=0xFFFF;
+  if (!ChkCodePtr(addr)) {
+    *_offset=best;
+    return NULL;
+  }
+  if (IsDbgMode)
+    for (i=0;i<mp_cnt;i++) {
+      c=&cpu_structs[i];
+      task=c->seth_task;
+      do {
+        if (!TaskValidate(task)) goto fs_abort_task;
+        h=task->hash_table;
+        while (h) {
+          HashFunSegFind(h,addr,&has_lower,&best,&res);
+          h=h->next;
+        }
+        task=task->next_task;
+      } while (task!=c->seth_task);
+fs_abort_task:
+    }
+  else {
+    h=Fs->hash_table;
+    while (h) {
+      HashFunSegFind(h,addr,&has_lower,&best,&res);
+      h=h->next;
+    }
+  }
+  *_offset=best;
+  return res;
+}
+
+U0 FunSegCacheAdd(CHash *tmps,U8 *addr)
+{
+  I64 i;
+  CDbgInfo *dbg_info;
+  CFunSegCache *tmpfsc;
+  if (tmps && tmps->type&HTT_FUN &&
+        (dbg_info=tmps(CHashFun *)->dbg_info)) {
+    lock i=dbg.fun_seg_cache_index++;
+    tmpfsc=&dbg.fun_seg_cache[i&(FUN_SEG_CACHE_SIZE-1)];
+    tmpfsc->base=dbg_info->body[0];
+    if (addr<tmpfsc->base)
+      tmpfsc->base=addr;
+    tmpfsc->limit=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line];
+    if (addr>=tmpfsc->limit)
+      tmpfsc->limit=addr+1;
+    i=MinI64(StrLen(tmps->str),FUN_SEG_CACHE_STR_LEN-1);
+    MemCpy(tmpfsc->str,tmps->str,i);
+    tmpfsc->str[i]=0;
+    tmpfsc->time_stamp=tS;
+  }
+}
+
+U8 *FunSegCacheFind(U8 *addr,I64 *_offset)
+{
+  I64 i;
+  F64 timeout;
+  CFunSegCache *tmpfsc=dbg.fun_seg_cache;
+  if (addr==SYS_IDLE_PT) {
+    *_offset=0;
+    return "SYS_IDLE_PT";
+  } else {
+    timeout=tS+8.0;
+    for (i=0;i<FUN_SEG_CACHE_SIZE;i++,tmpfsc++)
+      if (tmpfsc->base<=addr<tmpfsc->limit &&
+            tmpfsc->time_stamp>timeout) {
+        *_offset=addr-tmpfsc->base;
+        return tmpfsc->str;
+      }
+    return NULL;
+  }
+}
+
+U0 StrPrintFunSeg(U8 *buf,I64 addr,I64 field_len,I64 flags)
+{
+  I64 offset;
+  CHashExport *tmpex;
+  U8 *str,*str2;
+  Bool is_fun=FALSE;
+  if (!(flags&PRTF_TRUNCATE))
+    field_len=0;
+  if (addr) {
+    if (str=FunSegCacheFind(addr,&offset)) {
+      if (addr!=SYS_IDLE_PT)
+        is_fun=TRUE;
+    } else  {
+      if (tmpex=FunSegFind(addr,&offset)) {
+        if (tmpex->type&HTT_FUN)
+          is_fun=TRUE;
+        FunSegCacheAdd(tmpex,addr);
+        str=tmpex->str;
+      }
+    }
+    if (str) {
+      if (offset>0xFFFF) offset=0xFFFF;
+      if (flags&PRTF_COMMA) {
+        if (is_fun) {
+          str2=MStrPrint("&%s",str);
+          if (!field_len)
+            StrCpy(buf,str2);
+          else if (flags&PRTF_LEFT_JUSTIFY && StrLen(str2)<field_len)
+            StrCpy(buf,str2);
+          else
+            StrPrint(buf,"%*ts",field_len,str2);
+          Free(str2);
+        } else {
+          if (!field_len)
+            StrCpy(buf,str);
+          else if (flags&PRTF_LEFT_JUSTIFY && StrLen(str)<field_len)
+            StrCpy(buf,str);
+          else
+            StrPrint(buf,"%*ts",field_len,str);
+        }
+      } else {
+        if (is_fun) {
+          str2=MStrPrint("&%s",str);
+          if (field_len && field_len>7) {
+            if (flags&PRTF_LEFT_JUSTIFY && StrLen(str2)<field_len-7)
+              StrPrint(buf,"%s+0x%04X",str2,offset);
+            else
+              StrPrint(buf,"%*ts+0x%04X",field_len-7,str2,offset);
+          } else
+            StrPrint(buf,"%s+0x%04X",str2,offset);
+          Free(str2);
+        } else {
+          if (field_len && field_len>7) {
+            if (flags&PRTF_LEFT_JUSTIFY && StrLen(str)<field_len-7)
+              StrPrint(buf,"%s+0x%04X",str,offset);
+            else
+              StrPrint(buf,"%*ts+0x%04X",field_len-7,str,offset);
+          } else
+            StrPrint(buf,"%s+0x%04X",str,offset);
+        }
+      }
+      return;
+    }
+  }
+  if (flags&PRTF_COMMA)
+    StrCpy(buf,".");
+  else if (flags&PRTF_TRUNCATE && field_len)
+    StrPrint(buf,"%*tX",field_len,addr);
+  else
+    StrPrint(buf,"%X",addr);
+}
+
+I64 SrcLineNum(U8 *addr,I64 cnt=1)
+{//linenum for src of addr.
+  CHashSrcSym *tmph;
+  I64 cur_line,first_line,last_line,num_lines,offset;
+  CDbgInfo *dbg_info;
+  U32 *body;
+  U8 *src,*src2;
+  if (tmph=FunSegFind(addr,&offset)) {
+    if (tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+      if (dbg_info=tmph->dbg_info) {
+        num_lines=dbg_info->max_line-dbg_info->min_line+1;
+        body=dbg_info->body;
+
+        //find first nonzero
+        first_line=0;
+        while (!body[first_line]) {
+          first_line++;
+          if (first_line>=num_lines)
+            return -1;
+        }
+
+        //find last nonzero
+        last_line=num_lines-1;
+        while (!body[last_line] && last_line>first_line)
+          last_line--;
+
+          //interpolate to guess line num
+        cur_line=ClampI64(ToF64(addr-body[first_line])*(last_line-first_line+1)/
+              (body[last_line]-body[first_line]+1),first_line,last_line);
+
+        //retreat while too high
+        while ((!body[cur_line] || body[cur_line]>=addr) && cur_line>first_line)
+          cur_line--;
+
+          //advance while to low
+        while ((!body[cur_line] || body[cur_line]<addr) && cur_line<last_line)
+          cur_line++;
+
+        if (addr<body[cur_line]+cnt)
+          return cur_line+dbg_info->min_line;
+
+      } else if (tmph->src_link) {
+        src =StrNew(tmph->src_link);
+        src2=StrNew(tmph->src_link);
+        StrLastRem(src,",",src2);
+        cur_line=Str2I64(src2);
+        Free(src);
+        Free(src2);
+        return cur_line;
+      }
+    }
+  }
+  return -1;
+}
+
+U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)
+{//MAlloc filename for src of addr.
+  CHashSrcSym *tmph;
+  I64 i,j,ii,offset,best=NULL,d,best_d;
+  U32 *body;
+  CDbgInfo *dbg_info;
+  U8 *src;
+  if ((tmph=FunSegFind(addr,&offset)) &&
+        tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
+    if (dbg_info=tmph->dbg_info) {
+      j=dbg_info->max_line-dbg_info->min_line+1;
+      body=dbg_info->body;
+      best_d=I64_MAX;
+      for (i=0;i<j;i++) {
+        if (0<body[i]<=addr<body[i]+cnt) {
+          ii=i+1;
+          while (!body[ii])
+            ii++;
+          if (addr<body[ii]) {
+            d=addr(I64)-body[i];
+            if (d<best_d) {
+              best_d=d;
+              best=tmph->src_link;
+            }
+          }
+        }
+      }
+    } else
+      best=tmph->src_link;
+  }
+  if (best) {
+    src=StrNew(best,mem_task);
+    StrFirstRem(src,":");
+    StrLastRem(src,",");
+    return src;
+  } else
+    return NULL;
+}
+
+U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL)
+{//MAlloc file,line link to src of addr.
+  U8 *filename,*st,*st2;
+  I64 linenum;
+  if (filename=SrcFileName(addr,cnt)) {
+    linenum=SrcLineNum(addr,cnt);
+    if (linenum<1)
+      linenum=1;
+    st2=MStrPrint("FL:%s,%d",filename,linenum);
+    Free(filename);
+    st=StrNew(st2,mem_task);
+    Free(st2);
+    return st;
+  }
+  return NULL;
+}
+
+Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL)
+{//Put to StdOut a DolDoc file,line link to src of addr.
+  U8 *src;
+  if (src=SrcEdLink(addr,cnt)) {
+    if (buf)
+      StrPrint(buf,"$LK,\"%p\",A=\"%s\"$",addr,src);
+    else
+      "$LK,\"%p\",A=\"%s\"$",addr,src;
+    Free(src);
+    return TRUE;
+  } else if (buf)
+    *buf=0;
+  return FALSE;
+}
+
+Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0)
+{//Edit src at addr.
+  U8 *st;
+  Bool res=FALSE;
+  if (st=SrcEdLink(addr,cnt)) {
+    if (IsRaw)
+      res=EdLiteFileLine(st,edf_dof_flags);
+    else
+      res=Ed(st,edf_dof_flags);
+    Free(st);
+  }
+  return res;
+}
+
+Bool Man(U8 *st,I64 edf_dof_flags=0)
+{//Owner's manual for symbol.  Edit src code for symbol.
+  Bool res=FALSE;
+  U8 **st2;
+  CHashSrcSym *tmph;
+  if (IsRaw) {
+    if ((tmph=HashFind(st,Fs->hash_table,HTG_SRC_SYM)) && tmph->src_link)
+      res=EdLiteFileLine(tmph->src_link,edf_dof_flags);
+  } else {
+    st2=MStrPrint("MN:%s",st);
+    res=Ed(st2,edf_dof_flags);
+    Free(st2);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/Job.HC.HTML b/public/Wb/Kernel/Job.HC.HTML new file mode 100755 index 0000000..3384558 --- /dev/null +++ b/public/Wb/Kernel/Job.HC.HTML @@ -0,0 +1,533 @@ + + + + + + + + + + + +
+U0 JobDel(CJob *tmpc)
+{//Free one cmd node.
+  Free(tmpc->aux_str);
+  Free(tmpc);
+}
+
+U0 JobQueDel(CJob *head)
+{
+  CJob *tmpc=head->next,*tmpc1;
+  while (tmpc!=head) {
+    tmpc1=tmpc->next;
+    QueRem(tmpc);
+    JobDel(tmpc);
+    tmpc=tmpc1;
+  }
+}
+
+U0 JobCtrlInit(CJobCtrl *ctrl)
+{
+  QueInit(&ctrl->next_waiting);
+  QueInit(&ctrl->next_done);
+  ctrl->flags=0;
+}
+
+U0 TaskRstAwaitingMsg(CTask *task=NULL)
+{//Pop-ups get parent messages so wake-up our pop-ups if we got a msg.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  do {
+    if (TaskValidate(task))
+      LBtr(&task->task_flags,TASKf_AWAITING_MSG);
+    else
+      break;
+  } while (task=task->popup_task);
+  POPFD
+}
+
+CJob *TaskExe(CTask *srv,CTask *master,U8 *data,I64 flags)
+{//Queues a request to compile and execute src code text.
+  CJob *res;
+  if (!data || !TaskValidate(srv) || master && !TaskValidate(master) ||
+        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))
+    return NULL;
+  res=ACAlloc(sizeof(CJob));
+  res->master_task=master;
+  res->job_code=JOBT_EXE_STR;
+  res->flags=flags;
+  res->aux_str=AStrNew(data);
+  res->ctrl=&srv->srv_ctrl;
+
+  PUSHFD
+  CLI
+  while (LBts(&srv->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+  if (!TaskValidate(srv)) {
+    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);
+    POPFD
+    JobDel(res);
+    return NULL;
+  } else {
+    LBtr(&srv->task_flags,TASKf_IDLE);
+    TaskRstAwaitingMsg(srv);
+    QueIns(res,srv->srv_ctrl.last_waiting);
+    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);
+    if (Bt(&flags,JOBf_WAKE_MASTER)) {
+      Suspend(master);
+      Yield;
+    }
+  }
+  POPFD
+  return res;
+}
+
+CJob *TaskText(CTask *srv,CTask *master,U8 *data,I64 flags)
+{//Post StdIn text to servant task. Tell who the master task is.
+  CJob *res;
+  CTask *task;
+  if (!data || !TaskValidate(srv) || master && !TaskValidate(master) ||
+        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))
+    return NULL;
+  res=ACAlloc(sizeof(CJob));
+  res->master_task=master; //in case somebody cares
+  res->job_code=JOBT_TEXT_INPUT;
+  res->flags=flags;
+  res->aux_str=AStrNew(data);
+
+  PUSHFD
+  task=srv->last_input_filter_task;
+  if (Bt(&flags,JOBf_HIGHEST_PRIORITY) || task==srv) {
+    if (task!=srv)
+      TaskWait(srv);
+    task=Spawn(&InputFilterTask,NULL,"Input Filter",,srv);
+    CLI
+    task->next_input_filter_task=srv->next_input_filter_task;
+    task->last_input_filter_task=srv;
+    srv->next_input_filter_task=task;
+    task->next_input_filter_task->last_input_filter_task=task;
+  } else {
+    CLI
+    task=srv->next_input_filter_task;
+  }
+  res->ctrl=&task->srv_ctrl;
+  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+  if (!TaskValidate(task)) {
+    JobDel(res);
+    res=NULL;
+  } else {
+    LBtr(&task->task_flags,TASKf_IDLE);
+    TaskRstAwaitingMsg(task);
+    QueIns(res,task->srv_ctrl.last_waiting);
+    LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  }
+  POPFD
+  return res;
+}
+
+CJob *TaskMsg(CTask *_srv,CTask *master,
+        I64 msg_code,I64 arg1,I64 arg2,I64 flags)
+{//Post message to servant task.  Tell who the master task is.
+//See flags and msg_code.
+  CJob *tmpc1,*tmpc;
+  CTask *srv=_srv;
+  if (!TaskValidate(srv) || master && !TaskValidate(master)||
+        srv->popup_task && !Bt(&srv->task_flags,TASKf_FILTER_INPUT))
+    return NULL;
+  tmpc=ACAlloc(sizeof(CJob));
+  tmpc->master_task=master;
+  tmpc->job_code=JOBT_MSG;
+  tmpc->msg_code=AbsI64(msg_code); //negative means do a down and up
+  tmpc->aux1=arg1;
+  tmpc->aux2=arg2;
+  tmpc->flags=flags;
+  PUSHFD
+  if (Bt(&sys_semas[SEMA_RECORD_MACRO],0) &&
+        srv!=sys_macro_task && msg_code==MSG_KEY_DOWN) {
+    tmpc1=AMAllocIdent(tmpc);
+    CLI
+    QueIns(tmpc1,sys_macro_head.last);
+  }
+  CLI
+  while (Bt(&srv->task_flags,TASKf_FILTER_INPUT) &&
+        !Bt(&flags,JOBf_DONT_FILTER))
+    srv=srv->next_input_filter_task;
+  tmpc->ctrl=&srv->srv_ctrl;
+  while (LBts(&srv->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+  if (!TaskValidate(srv)) {
+    JobDel(tmpc);
+    tmpc=NULL;
+  } else {
+    LBtr(&srv->task_flags,TASKf_IDLE);
+    TaskRstAwaitingMsg(srv);
+    QueIns(tmpc,srv->srv_ctrl.last_waiting);
+    LBtr(&srv->srv_ctrl.flags,JOBCf_LOCKED);
+  }
+  POPFD
+  if (msg_code<0) //Down-Up
+    TaskMsg(_srv,master,-msg_code+1,arg1,arg2,flags);
+  return tmpc;
+}
+
+Bool JobResScan(CJob *rqst=NULL,I64 *_res=NULL)
+{//Check rqst complete, return with or without.
+  CJobCtrl *ctrl;
+  CJob *tmpc,*tmpc1;
+  if (!rqst || Bt(&rqst->flags,JOBf_DONE)) {
+    if (!rqst || rqst->master_task)
+      ctrl=&Fs->srv_ctrl;
+    else
+      ctrl=rqst->ctrl;
+    PUSHFD
+    CLI
+    while (LBts(&ctrl->flags,JOBCf_LOCKED))
+      PAUSE
+    tmpc1=&ctrl->next_done;
+    tmpc=tmpc1->next;
+    while (tmpc!=tmpc1) {
+      if (!rqst || rqst==tmpc) {
+        QueRem(tmpc);
+        LBtr(&ctrl->flags,JOBCf_LOCKED);
+        POPFD
+        if (_res)
+          *_res=tmpc->res;
+        JobDel(tmpc);
+        return TRUE;
+      }
+      tmpc=tmpc->next;
+    }
+    LBtr(&ctrl->flags,JOBCf_LOCKED);
+    POPFD
+  }
+  if (_res)
+    *_res=0;
+  return FALSE;
+}
+
+I64 JobResGet(CJob *rqst=NULL)
+{//See ::/Demo/MultiCore/Lock.HC
+  I64 res;
+  CJob *tmpc1;
+  if (!rqst) {
+    tmpc1=&Fs->srv_ctrl.next_done;
+    while (tmpc1==tmpc1->next) {
+      LBts(&Fs->task_flags,TASKf_IDLE);
+      Yield;
+    }
+  } else {
+    while (!Bt(&rqst->flags,JOBf_DONE)) {
+      LBts(&Fs->task_flags,TASKf_IDLE);
+      Yield;
+    }
+  }
+  LBtr(&Fs->task_flags,TASKf_IDLE);
+//Could get taken by someone else.
+  JobResScan(rqst,&res);
+  return res;
+}
+
+U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE)
+{//Wait for idle.
+  CTask *task1;
+  CJob *tmpc1;
+  if (!task) task=Fs;
+  if (TaskValidate(task)) {
+    PUSHFD
+    CLI
+    while (TRUE) {
+      task1=task->last_input_filter_task;
+      tmpc1=&task1->srv_ctrl.next_waiting;
+      if (task1==Fs || !TaskValidate(task1) ||
+            tmpc1==tmpc1->next && Bt(&task1->task_flags,TASKf_IDLE) &&
+            (!cmd_line_pmt || Bt(&task1->task_flags,TASKf_CMD_LINE_PMT)))
+        break;
+      Yield;
+    }
+    POPFD
+  }
+}
+
+U0 PostMsg(CTask *task,I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)
+{//Post message to a task and return immediately.  See msg_code.
+  if (TaskValidate(task)) {
+    if (Bt(&task->task_flags,TASKf_INPUT_FILTER_TASK))
+      TaskMsg(task->last_input_filter_task,NULL,msg_code,arg1,arg2,
+            flags|1<<JOBf_DONT_FILTER);
+    else
+      TaskMsg(task,NULL,msg_code,arg1,arg2,flags);
+  }
+}
+
+U0 PostMsgWait(CTask *task,I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)
+{//Post message to a task and wait until task is idle.See msg_code.
+  PostMsg(task,msg_code,arg1,arg2,flags);
+  TaskWait(task);
+}
+
+U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0)
+{//Post message to current task and return immediately.
+//See msg_code.
+  PostMsg(Fs,msg_code,arg1,arg2,flags);
+}
+
+#define JOB_DONE        0
+#define JOB_CONT        1
+#define JOB_EXIT        2
+
+I64 JobRunOne(I64 run_flags,CJobCtrl *ctrl)
+{//Called with ctrl->flags,JOBCf_LOCKED.
+  CJob *tmpc=ctrl->next_waiting;
+  CTask   *master;
+  I64 res,flags=tmpc->flags,old_flags=GetRFlags;
+  if (Bt(&flags,JOBf_EXIT_ON_COMPLETE))
+    res=JOB_EXIT;
+  else
+    res=JOB_CONT;
+  switch (tmpc->job_code) {
+    case JOBT_SPAWN_TASK:
+      QueRem(tmpc);
+      LBts(&tmpc->flags,JOBf_DISPATCHED);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      if (tmpc->aux_str)
+        tmpc->spawned_task=Spawn(tmpc->addr,tmpc->fun_arg,
+              tmpc->aux_str,,tmpc->aux1,tmpc->aux2,tmpc->flags);
+      else
+        tmpc->spawned_task=Spawn(tmpc->addr,tmpc->fun_arg,
+              "Unnamed",,tmpc->aux1,tmpc->aux2,tmpc->flags);
+      break;
+    case JOBT_CALL:
+      QueRem(tmpc);
+      LBts(&tmpc->flags,JOBf_DISPATCHED);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      SetRFlags(run_flags);
+      LBtr(&Fs->task_flags,TASKf_IDLE);
+      try
+              tmpc->res=(*tmpc->addr)(tmpc->fun_arg);
+      catch
+        Fs->catch_except=TRUE;
+      SetRFlags(old_flags);
+      break;
+    case JOBT_EXE_STR:
+      QueRem(tmpc);
+      LBts(&tmpc->flags,JOBf_DISPATCHED);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      SetRFlags(run_flags);
+      LBtr(&Fs->task_flags,TASKf_IDLE);
+      try
+              tmpc->res=ExePrint("%s",tmpc->aux_str);
+      catch
+        Fs->catch_except=TRUE;
+      SetRFlags(old_flags);
+      break;
+    default:
+      res=JOB_DONE;
+  }
+  if (res) {
+    if (master=tmpc->master_task) {
+      if (!Bt(&flags,JOBf_FREE_ON_COMPLETE)) {
+        CLI
+        while (LBts(&master->srv_ctrl.flags,JOBCf_LOCKED))
+          PAUSE
+        QueIns(tmpc,master->srv_ctrl.last_done);
+        LBts(&tmpc->flags,JOBf_DONE);
+        LBtr(&master->srv_ctrl.flags,JOBCf_LOCKED);
+        SetRFlags(old_flags);
+      }
+      if (Bt(&flags,JOBf_FOCUS_MASTER) &&
+            !Bt(&master->win_inhibit,WIf_SELF_FOCUS))
+        sys_focus_task=master;
+      if (Bt(&flags,JOBf_WAKE_MASTER))
+        Suspend(master,FALSE);
+    }
+    if (Bt(&flags,JOBf_FREE_ON_COMPLETE))
+      JobDel(tmpc);
+    else if (!master) {
+      CLI
+      while (LBts(&ctrl->flags,JOBCf_LOCKED))
+        Yield;
+      QueIns(tmpc,ctrl->last_done);
+      LBts(&tmpc->flags,JOBf_DONE);
+      LBtr(&ctrl->flags,JOBCf_LOCKED);
+      SetRFlags(old_flags);
+    }
+  }
+  return res;
+}
+
+I64 JobsHndlr(I64 run_flags,CTask *task=NULL)
+{//Handle all waiting cmds and return.
+  I64 cnt=0,old_flags=GetRFlags;
+  if (!task) task=Fs;
+  while (TRUE) {
+    CLI
+    while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+      PAUSE
+    if (task->srv_ctrl.next_waiting!=&task->srv_ctrl)
+      switch (JobRunOne(run_flags,&task->srv_ctrl)) {
+        case JOB_CONT:
+          cnt++;
+          break;
+        case JOB_EXIT:
+          Exit;
+        case JOB_DONE:
+          goto jh_done;
+      }
+    else
+      goto jh_done;
+  }
+jh_done:
+  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  SetRFlags(old_flags);
+  return cnt;
+}
+
+I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL)
+{//Execute code in PopUp task.
+  I64 res;
+  CJob *tmpc;
+  CTask *task=Spawn(&SrvCmdLine,NULL,"Servant",,parent);
+  if (!parent) {
+    TaskExe(task,parent,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
+    if (_pu_task) *_pu_task=task;
+    return 0;
+  } else {
+    Fs->popup_task=task;
+    tmpc=TaskExe(task,parent,buf,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
+    if (_pu_task) *_pu_task=task;
+    JobResScan(tmpc,&res);
+    Fs->popup_task=NULL;
+    Kill(task);
+    if (_pu_task) *_pu_task=NULL;
+    return res;
+  }
+}
+
+I64 PopUpPrint(U8 *fmt,...)
+{//Execute code in PopUp task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  I64 res;
+  res=PopUp(buf,Fs);
+  Free(buf);
+  return res;
+}
+
+I64 Adam(U8 *fmt,...)
+{//Make adam_task execute code.
+  I64 res;
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  CJob *tmpc;
+  if (Fs==adam_task) {
+    tmpc=TaskExe(adam_task,Fs,buf,0);
+    JobsHndlr(GetRFlags);
+  } else {
+    TaskWait(adam_task);
+    tmpc=TaskExe(adam_task,Fs,buf,1<<JOBf_WAKE_MASTER);
+  }
+  JobResScan(tmpc,&res);
+  Free(buf);
+  return res;
+}
+
+U0 AdamLog(U8 *fmt,...)
+{//Display text in adam_task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (Fs==adam_task)
+    "%s",buf;
+  else if (!IsSingleUser)
+    Adam("\"%%s\",%d;",buf);
+  Free(buf);
+}
+
+U0 AdamErr(U8 *fmt,...)
+{//Display red blinking Err text in adam_task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),
+        *st=MStrPrint(ST_ERR_ST "%s",buf);
+  if (Fs==adam_task)
+    "%s",st;
+  else if (!IsSingleUser)
+    Adam("\"%%s\",%d;",st);
+  Free(st);
+  Free(buf);
+}
+
+U0 XTalk(CTask *task,U8 *fmt,...)
+{//Sends text to other task. See ::/Misc/OSTestSuite.HC.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf),
+        *st2=MStrPrint("\"%%s\",%d;Free(%d);",st,st);
+  TaskText(task,NULL,st2,0);
+  Free(st2);
+  Free(buf);
+}
+
+U0 XTalkWait(CTask *task,U8 *fmt,...)
+{//Send text to other task and wait for it to idle.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf),
+        *st2=MStrPrint("\"%%s\",%d;Free(%d);",st,st);
+  TaskText(task,NULL,st2,0);
+  Free(st2);
+  Free(buf);
+  TaskWait(task);
+}
+
+U0 InStr(U8 *fmt,...)
+{//Send InFile code to self.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK))
+    ExePrint("%s",buf);
+  else
+    TaskText(Fs,NULL,buf,1<<JOBf_HIGHEST_PRIORITY);
+  Free(buf);
+}
+
+U0 InFile(U8 *filename)
+{//Send InFile code file to self.
+  U8 *name=ExtDft(filename,"IN.Z");
+  InStr("Cd(\"%C:%s\");;#include \"%s\"",
+        Drv2Let(Fs->cur_dv),Fs->cur_dir,name);
+  Free(name);
+}
+
+U0 In(U8 *fmt,...)
+{//Send text to own input buffer. See ::/Demo/AcctExample/TOS/TOSDistro.HC.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=AStrNew(buf);
+  InStr("\"%%s\",%d;Free(%d);",st,st);
+  Free(buf);
+}
+
+U0 XTalkStr(CTask *task,U8 *fmt,...)
+{//Send InFile code to other task.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  TaskText(task,NULL,buf,0);
+  Free(buf);
+}
+
+U0 XTalkStrWait(CTask *task,U8 *fmt,...)
+{//Send InFile code to other task and wait for it to idle.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  TaskText(task,NULL,buf,0);
+  Free(buf);
+  TaskWait(task);
+}
+
+ diff --git a/public/Wb/Kernel/KCfg.HC.HTML b/public/Wb/Kernel/KCfg.HC.HTML new file mode 100755 index 0000000..522a480 --- /dev/null +++ b/public/Wb/Kernel/KCfg.HC.HTML @@ -0,0 +1,204 @@ + + + + + + + + + + + +
+//This is run in a #exe{}.
+
+U8 *kernel_cfg_options="MemInit\0HeapInit\0VarInit\0StaffMode\0"
+"HomeDir\0NoMP\0TextMode\0DontProbe\0MountIDEAuto\0DbgDistro\0Help\0";
+
+#define CFG_MEM_INIT            0
+#define CFG_HEAP_INIT           1
+#define CFG_VAR_INIT            2
+#define CFG_STAFF_MODE          3
+#define CFG_HOME_DIR            4
+#define CFG_NO_MP               5
+#define CFG_TEXT_MODE           6
+#define CFG_DONT_PROBE          7
+#define CFG_MOUNT_IDE_AUTO      8
+#define CFG_DBG_DISTRO  9
+#define CFG_OPTIONS_NUM         10
+
+#define CFG_HELP                10
+
+class CKCfg
+{
+  U8 *dsk_cache_size_exp;
+  CDoc *add_dev;
+  U8 *dbg_distro_file,*dbg_distro_start;
+  U8 *home_dir;
+  Bool opts[CFG_OPTIONS_NUM];
+  U8 mem_init_val,heap_init_val,var_init_val,
+        boot_drv_let,mount_ide_auto_hd_let,mount_ide_auto_cd_let;
+};
+
+CDoc *KCfgAddDev(CKCfg *c)
+{
+  I64 ch;
+  CDoc *doc=DocNew;
+  "\n\nIn anticipation of the drives you will\n"
+        "define shortly, enter the drive letter\n"
+        "of the drive with the account directory.\n"
+        "\n($PURPLE$<ENTER>$FG$ for cur drv) Boot Drv:";
+  ch=Let2Let(GetChar);
+  if ('A'<=ch<='Z')
+    c->boot_drv_let=ch;
+  else
+    c->boot_drv_let=Drv2Let(Fs->cur_dv);
+  "\n\n$BK,1$$PURPLE$Mount drives so they will be present when "
+        "you boot.$FG$$BK,0$\n";
+  Mount2(c->boot_drv_let,doc,FALSE);
+  return doc;
+}
+
+U0 KCfgOptions(CKCfg *c)
+{
+  I64 i;
+  U8 *st=NULL,*st2,*st3;
+  Bool state;
+  do {
+    Free(st);
+    for (i=0;i<CFG_OPTIONS_NUM;i++)
+      if (i==CFG_HOME_DIR)
+        "$PURPLE$%13tz$FG$:\"%s\"\n",i,kernel_cfg_options,c->home_dir;
+      else
+        "$PURPLE$%13tz$FG$:%Z\n",i,kernel_cfg_options,c->opts[i],"ST_OFF_ON";
+    "\nType '$PURPLE$Help$FG$' for help.\n";
+    st=GetStr("Option ($PURPLE$<ENTER>$FG$ when done):","");
+    i=LstMatch(st,kernel_cfg_options,LMF_IGNORE_CASE);
+    if (i==CFG_HELP)
+      "\n"
+            "$PURPLE$MemInit$FG$ Initializes memory above 0x100000 "
+            "to a val at boot.\n"
+            "$PURPLE$HeapInit$FG$ Initializes MAlloc() memory to a val.\n"
+            "$PURPLE$VarInit$FG$ Initializes glbl var memory to a val.\n"
+            "$PURPLE$HomeDir$FG$ Set home dir.\n"
+            "$PURPLE$NoMP$FG$ No multicore.\n"
+            "$PURPLE$TextMode$FG$ Text Mode (requires hard reboot).\n"
+            "$PURPLE$DontProbe$FG$ Just prompt CD/DVD ports, don't probe.\n"
+            "$PURPLE$MountIDEAuto$FG$ Auto Mount IDE drives to 'C' and 'T'.\n"
+            "$PURPLE$DbgDistro$FG$ Include RAM Drv in Kernel.BIN.\n"
+            "\n";
+    else
+      if (0<=i<CFG_OPTIONS_NUM) {
+        state=c->opts[i]=!c->opts[i];
+        switch (i) {
+          case CFG_MEM_INIT:
+            if (state)
+              c->mem_init_val=GetI64("Val (0-255):",255,0,255);
+            break;
+          case CFG_HEAP_INIT:
+            if (state)
+              c->heap_init_val=GetI64("Val (0-255):",255,0,255);
+            break;
+          case CFG_VAR_INIT:
+            if (state)
+              c->var_init_val=GetI64("Val (0-255):",255,0,255);
+            break;
+          case CFG_HOME_DIR:
+            st2=GetStr("Home Dir(\"%s\"):",c->home_dir);
+            if (!*st2)
+              st2=StrNew("::/Home");
+            else if (st2[1]!=':') {
+              st3=MStrPrint("::%s",st2);
+              Free(st2);
+              st2=st3;
+            }
+            Free(c->home_dir);
+            c->home_dir=st2;
+            if (StrCmp(c->home_dir,"::/Home"))
+              c->opts[i]=TRUE;
+            else
+              c->opts[i]=FALSE;
+            break;
+          case CFG_MOUNT_IDE_AUTO:
+            if (state) {
+              "First HD Drive Let:";
+              c->mount_ide_auto_hd_let=Let2Let(GetChar);
+              if (!('A'<=c->mount_ide_auto_hd_let<='Z'))
+                c->mount_ide_auto_hd_let=0;
+              '\n';
+              if (c->mount_ide_auto_hd_let)
+                "First HD Drive:%C\n",c->mount_ide_auto_hd_let;
+              else
+                "First HD Drive:%C\n",'C';
+
+              "First CD Drive Let:";
+              c->mount_ide_auto_cd_let=Let2Let(GetChar);
+              if (!('A'<=c->mount_ide_auto_cd_let<='Z'))
+                c->mount_ide_auto_cd_let=0;
+              '\n';
+              if (c->mount_ide_auto_cd_let)
+                "First CD Drive:%C\n",c->mount_ide_auto_cd_let;
+              else
+                "First CD Drive:%C\n",'T';
+            } else {
+              c->mount_ide_auto_hd_let=0;
+              c->mount_ide_auto_cd_let=0;
+            }
+            break;
+          case CFG_DBG_DISTRO:
+            Free(c->dbg_distro_file);
+            c->dbg_distro_file=0;
+            c->dbg_distro_start=0;
+            if (state) {
+              c->dbg_distro_file=GetStr("Dbg Distro File:");
+              c->dbg_distro_start=GetI64("Dbg Distro Start:");
+            }
+            break;
+        }
+      }
+  } while (*st);
+  Free(st);
+}
+
+CKCfg *KCfgNew()
+{
+  CKCfg *c=CAlloc(sizeof(CKCfg));
+
+  c->add_dev=KCfgAddDev(c);
+  c->home_dir=StrNew("::/Home");
+  c->dsk_cache_size_exp=GetStr(
+        "Disk Cache Size in Bytes,\n"
+        "gets rounded-up funny,\n"
+        "($PURPLE$<ENTER>$FG$ will use default.):",
+        "Scale2Mem(0x80000,0x8000000)");
+  KCfgOptions(c);
+  return c;
+}
+ 
+U0 KCfgDel(CKCfg *c)
+{
+  DocDel(c->add_dev);
+  Free(c->dbg_distro_file);
+  Free(c->home_dir);
+  Free(c->dsk_cache_size_exp);
+  Free(c);
+}
+
+ diff --git a/public/Wb/Kernel/KDataTypes.HC.HTML b/public/Wb/Kernel/KDataTypes.HC.HTML new file mode 100755 index 0000000..04bfbf0 --- /dev/null +++ b/public/Wb/Kernel/KDataTypes.HC.HTML @@ -0,0 +1,354 @@ + + + + + + + + + + + +
+U0 LinkedLstDel(U8 **_lst)
+{//Free entire linked-list.
+  U8 **tmpl;
+  while (_lst) {
+    tmpl=*_lst;
+    Free(_lst);
+    _lst=tmpl;
+  }
+}
+
+U8 *LinkedLstCopy(U8 **_lst,CTask *mem_task=NULL)
+{//MAlloc ident copy of entire linked-list.
+  U8 *res=NULL,**tmpl=&res;
+  while (_lst) {
+    tmpl=*tmpl=MAllocIdent(_lst,mem_task);
+    _lst=*_lst;
+  }
+  return res;
+}
+
+I64 LinkedLstCnt(U8 **_lst)
+{//Count of nodes in linked-list.
+  I64 res=0;
+  while (_lst) {
+    res++;
+    _lst=*_lst;
+  }
+  return res;
+}
+
+I64 LinkedLstSize(U8 **_lst)
+{//Mem size of all nodes in linked-list.
+  I64 res=0;
+  while (_lst) {
+    res+=MSize2(_lst);
+    _lst=*_lst;
+  }
+  return res;
+}
+
+U0 QueDel(CQue *head,Bool querem=FALSE)
+{//Free entries in queue, not head.
+  CQue *tmpq=head->next,*tmpq1;
+  while (tmpq!=head) {
+    tmpq1=tmpq->next;
+    if (querem)
+      QueRem(tmpq);
+    Free(tmpq);
+    tmpq=tmpq1;
+  }
+}
+
+CQue *QueCopy(CQue *head,CTask *mem_task=NULL)
+{//MAlloc ident copy of entire queue and head.
+  CQue *res=MAllocIdent(head,mem_task),*tmpq=head->next,*tmpq1;
+  QueInit(res);
+  while (tmpq!=head) {
+    tmpq1=MAllocIdent(tmpq,mem_task);
+    QueIns(tmpq1,res->last);
+    tmpq=tmpq->next;
+  }
+  return res;
+}
+
+I64 QueCnt(CQue *head)
+{//Count of nodes in queue, not head.
+  CQue *tmpq=head->next;
+  I64 res=0;
+  while (tmpq!=head) {
+    res++;
+    tmpq=tmpq->next;
+  }
+  return res;
+}
+
+I64 QueSize(CQue *head)
+{//Mem size of all nodes in queue, not head.
+  CQue *tmpq=head->next;
+  I64 res=0;
+  while (tmpq!=head) {
+    res+=MSize2(tmpq);
+    tmpq=tmpq->next;
+  }
+  return res;
+}
+
+CQueVectU8 *QueVectU8New(I64 min_idx=0)
+{//Create new queue vecter.
+  CQueVectU8 *res=MAlloc(sizeof(CQueVectU8));
+  QueInit(res);
+  res->total_cnt=res->node_cnt=0;
+  res->min_idx=min_idx;
+  return res;
+}
+
+U0 QueVectU8Put(CQueVectU8 *v,I64 idx,U8 ch)
+{//Put U8 at idx i.
+  CQueVectU8 *tmpv;
+  idx-=v->min_idx;
+  if (idx<0) return;
+  if (idx<v->total_cnt) {
+    tmpv=v;
+    do {
+      idx-=tmpv->node_cnt;
+      if (idx<0) {
+        tmpv->body[idx+tmpv->node_cnt]=ch;
+        return;
+      }
+      tmpv=tmpv->next;
+    } while (tmpv!=v);
+  } else
+    idx-=v->total_cnt;
+
+  while (TRUE) {
+    tmpv=v->last;
+    if (tmpv->node_cnt>=QUE_VECT_U8_CNT) {
+      tmpv=MAlloc(sizeof(CQueVectU8));
+      tmpv->node_cnt=0;
+      QueIns(tmpv,v->last);
+    }
+    if (idx--) {
+      tmpv->body[tmpv->node_cnt++]=0;
+      v->total_cnt++;
+    } else {
+      tmpv->body[tmpv->node_cnt++]=ch;
+      v->total_cnt++;
+      break;
+    }
+  }
+}
+
+U0 QueVectU8Del(CQueVectU8 *v)
+{//Free entire queue vector.
+  if (v) {
+    QueDel(v);
+    Free(v);
+  }
+}
+
+I64 QueVectU8Get(CQueVectU8 *v,I64 idx)
+{//Get U8 at idx i.
+  CQueVectU8 *tmpv;
+  idx-=v->min_idx;
+  if (!(0<=idx<v->total_cnt)) return 0;
+  tmpv=v;
+  do {
+    idx-=tmpv->node_cnt;
+    if (idx<0)
+      return tmpv->body[idx+tmpv->node_cnt];
+    tmpv=tmpv->next;
+  } while (tmpv!=v);
+  return 0;
+}
+
+CFifoU8 *FifoU8New(I64 size,CTask *mem_task=NULL)
+{//Create new fifo.
+  CFifoU8 *f;
+  if (!mem_task) mem_task=Fs;
+  f=MAlloc(sizeof(CFifoU8),mem_task);
+  f->buf=MAlloc(size,mem_task);
+  f->mask=size-1;
+  f->in_ptr=0;
+  f->out_ptr=0;
+  return f;
+}
+
+U0 FifoU8Del(CFifoU8 *f)
+{//Free fifo.
+  Free(f->buf);
+  Free(f);
+}
+
+Bool FifoU8Ins(CFifoU8 *f,U8 b)
+{//Insert U8 into fifo.
+  I64 new_in_ptr;
+  PUSHFD
+  CLI
+  new_in_ptr=(f->in_ptr+1)&f->mask;
+  if (new_in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    f->buf[f->in_ptr]=b;
+    f->in_ptr=new_in_ptr;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoU8Rem(CFifoU8 *f,U8 *_b)
+{//Remove U8 from fifo.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_b=f->buf[f->out_ptr];
+    f->out_ptr=(f->out_ptr+1)&f->mask;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoU8Peek(CFifoU8 *f,U8 *_b)
+{//Peek at front of fifo and don't remove.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_b=f->buf[f->out_ptr];
+    POPFD
+    return TRUE;
+  }
+}
+
+U0 FifoU8Flush(CFifoU8 *f)
+{//Flush fifo getting rid of all U8's.
+  PUSHFD
+  CLI
+  f->out_ptr=f->in_ptr;
+  POPFD
+}
+
+I64 FifoU8Cnt(CFifoU8 *f)
+{//Count of U8's in fifo.
+  I64 res;
+  PUSHFD
+  CLI
+  if (f->out_ptr>f->in_ptr)
+    res=f->mask+1-(f->out_ptr-f->in_ptr);
+  else
+    res=f->in_ptr-f->out_ptr;
+  POPFD
+  return res;
+}
+
+CFifoI64 *FifoI64New(I64 size,CTask *mem_task=NULL)
+{//Create new fifo.
+  CFifoI64 *f;
+  if (!mem_task) mem_task=Fs;
+  f=MAlloc(sizeof(CFifoI64),mem_task);
+  f->buf=MAlloc(size*sizeof(I64),mem_task);
+  f->mask=size-1;
+  f->in_ptr=0;
+  f->out_ptr=0;
+  return f;
+}
+
+U0 FifoI64Del(CFifoI64 *f)
+{//Free fifo.
+  Free(f->buf);
+  Free(f);
+}
+
+Bool FifoI64Ins(CFifoI64 *f,I64 q)
+{//Insert I64 into fifo.
+  I64 new_in_ptr;
+  PUSHFD
+  CLI
+  new_in_ptr=(f->in_ptr+1)&f->mask;
+  if (new_in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    f->buf[f->in_ptr]=q;
+    f->in_ptr=new_in_ptr;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoI64Rem(CFifoI64 *f,I64 *_q)
+{//Remove I64 from fifo.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_q=f->buf[f->out_ptr];
+    f->out_ptr=(f->out_ptr+1)&f->mask;
+    POPFD
+    return TRUE;
+  }
+}
+
+Bool FifoI64Peek(CFifoI64 *f,I64 *_q)
+{//Peek at front of fifo and don't remove.
+  PUSHFD
+  CLI
+  if (f->in_ptr==f->out_ptr) {
+    POPFD
+    return FALSE;
+  } else {
+    *_q=f->buf[f->out_ptr];
+    POPFD
+    return TRUE;
+  }
+}
+
+U0 FifoI64Flush(CFifoI64 *f)
+{//Flush fifo getting rid of all I64's.
+  PUSHFD
+  CLI
+  f->out_ptr=f->in_ptr;
+  POPFD
+}
+
+I64 FifoI64Cnt(CFifoI64 *f)
+{//Count of I64's in fifo.
+  I64 res;
+  PUSHFD
+  CLI
+  if (f->out_ptr>f->in_ptr)
+    res=f->mask+1-(f->out_ptr-f->in_ptr);
+  else
+    res=f->in_ptr-f->out_ptr;
+  POPFD
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/KDate.HC.HTML b/public/Wb/Kernel/KDate.HC.HTML new file mode 100755 index 0000000..be3ae18 --- /dev/null +++ b/public/Wb/Kernel/KDate.HC.HTML @@ -0,0 +1,227 @@ + + + + + + + + + + + +
+//See ::/Doc/TimeDate.DD
+
+U16 mon_start_days1[12]={
+0,31,59,90,120,151,181,212,243,273,304,334};
+U16 mon_start_days2[12]={
+0,31,60,91,121,152,182,213,244,274,305,335};
+
+I64 YearStartDate(I64 year)
+{//32-bit day since AD 0, given year number.
+  I64 y1=year-1,yd4000=y1/4000,yd400=y1/400,yd100=y1/100,yd4=y1/4;
+  return year*365+yd4-yd100+yd400-yd4000;
+}
+
+CDate Struct2Date(CDateStruct *_ds)
+{//Cvt CDateStruct to CDate.
+  CDate cdt;
+  I64 i1,i2;
+  i1=YearStartDate(_ds->year);
+  i2=YearStartDate(_ds->year+1);
+  if (i2-i1==365)
+    i1+=mon_start_days1[_ds->mon-1];
+  else
+    i1+=mon_start_days2[_ds->mon-1];
+  cdt.date=i1+_ds->day_of_mon-1;
+  cdt.time=(_ds->sec10000+100*(_ds->sec100+100*(_ds->sec
+        +60*(_ds->min+60*_ds->hour))))<<21/(15*15*3*625);
+  return cdt;
+}
+
+I64 DayOfWeek(I64 i)
+{//Day of week, given 32-bit day since AD 0.
+  i+=CDATE_BASE_DAY_OF_WEEK;
+  if (i>=0)
+    return i % 7;
+  else
+    return 6-(6-i)%7;
+}
+
+U0 Date2Struct(CDateStruct *_ds,CDate cdt)
+{//Cvt CDate to CDateStruct.
+  I64 i,k,date=cdt.date;
+  _ds->day_of_week=DayOfWeek(date);
+  _ds->year=(date+1)*100000/CDATE_YEAR_DAYS_INT;
+  i=YearStartDate(_ds->year);
+  while (i>date) {
+    _ds->year--;
+    i=YearStartDate(_ds->year);
+  }
+  date-=i;
+  if (YearStartDate(_ds->year+1)-i==365) {
+    k=0;
+    while (date>=mon_start_days1[k+1] && k<11)
+      k++;
+    date-=mon_start_days1[k];
+  } else {
+    k=0;
+    while (date>=mon_start_days2[k+1] && k<11)
+      k++;
+    date-=mon_start_days2[k];
+  }
+  _ds->mon=k+1;
+  _ds->day_of_mon=date+1;
+  k=(625*15*15*3*cdt.time)>>21+1;
+  _ds->sec10000=ModU64(&k,100);
+  _ds->sec100=ModU64(&k,100);
+  _ds->sec=ModU64(&k,60);
+  _ds->min=ModU64(&k,60);
+  _ds->hour  =k;
+}
+
+I64 FirstDayOfMon(I64 i)
+{//First day of month, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.day_of_mon=1;
+  cdt=Struct2Date(&ds);
+  return cdt.date;
+}
+
+I64 LastDayOfMon(I64 i)
+{//Last day of month, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.mon++;
+  if (ds.mon==13) {
+    ds.mon=0;
+    ds.year++;
+  }
+  ds.day_of_mon=1;
+  cdt=Struct2Date(&ds);
+  return cdt.date-1;
+}
+
+I64 FirstDayOfYear(I64 i)
+{//First day of year, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.day_of_mon=1;
+  ds.mon=1;
+  cdt=Struct2Date(&ds);
+  return cdt.date;
+}
+
+I64 LastDayOfYear(I64 i)
+{//Last day of year, given 32-bit day since AD 0.
+  CDateStruct ds;
+  CDate cdt=0;
+  cdt.date=i;
+  Date2Struct(&ds,cdt);
+  ds.day_of_mon=1;
+  ds.mon=1;
+  ds.year++;
+  cdt=Struct2Date(&ds);
+  return cdt.date-1;
+}
+
+I64 Bcd2Bin(U64 b)
+{
+  I64 i,res=0;
+  for (i=0;i<16;i++) {
+    res=res*10+b>>60;
+    b<<=4;
+  }
+  return res;
+}
+
+U0 NowDateTimeStruct(CDateStruct *_ds)
+{
+  I64 i;
+  U8 *b=_ds;
+  Bool is_bcd;
+
+  MemSet(_ds,0,sizeof(CDateStruct));
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_SYS_DATE],0))
+    PAUSE
+
+  OutU8(0x70,0x0A);
+  do {
+    while (InU8(0x71) & 0x80)
+      PAUSE
+
+    OutU8(0x70,0);
+    b[2]=InU8(0x71);
+    OutU8(0x70,2);
+    b[3]=InU8(0x71);
+    OutU8(0x70,4);
+    b[4]=InU8(0x71);
+
+    OutU8(0x70,6);
+    b[5]=InU8(0x71);
+    OutU8(0x70,7);
+    b[6]=InU8(0x71);
+    OutU8(0x70,8);
+    b[7]=InU8(0x71);
+    OutU8(0x70,9);
+    b[8]=InU8(0x71);
+
+    OutU8(0x70,0x0A);
+  } while (InU8(0x71) & 0x80);
+
+  OutU8(0x70,0x0B);
+  if (InU8(0x71) & 4)
+    is_bcd=FALSE;
+  else
+    is_bcd=TRUE;
+
+  LBtr(&sys_semas[SEMA_SYS_DATE],0);
+  POPFD
+  if (is_bcd)
+    for (i=2;i<9;i++)
+      b[i]=Bcd2Bin(b[i]);
+
+  if (_ds->year>255)    _ds->year=255;
+  _ds->year+=2000;
+  if (_ds->mon>12)      _ds->mon=12;
+  if (_ds->day_of_mon>31) _ds->day_of_mon=31;
+  if (_ds->day_of_week>6) _ds->day_of_week=6;
+  if (_ds->hour>23)     _ds->hour=23;
+  if (_ds->min>59)      _ds->min=59;
+  if (_ds->sec>59)      _ds->sec=59;
+}
+
+CDate Now()
+{//Current datetime.
+  CDateStruct ds;
+  NowDateTimeStruct(&ds);
+  return Struct2Date(&ds)-local_time_offset;
+}
+
+ diff --git a/public/Wb/Kernel/KDbg.HC.HTML b/public/Wb/Kernel/KDbg.HC.HTML new file mode 100755 index 0000000..9570b0a --- /dev/null +++ b/public/Wb/Kernel/KDbg.HC.HTML @@ -0,0 +1,683 @@ + + + + + + + + + + + +
+Bool ChkPtr(U8 *ptr)
+{//Check if addr is valid ptr.
+  if (mem_heap_base<=ptr<=mem_mapped_space) {
+    if (*MemPageTable(ptr)&1)
+      return TRUE;
+    else
+      return FALSE;
+  } else if (ptr<mem_boot_base)
+    return FALSE;
+  else if (ptr<VGAM_GRAPHICS)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool ChkCodePtr(U8 *ptr)
+{//Check if addr is valid code addr.
+  if (mem_heap_base<=ptr<=mem_heap_limit) {
+    if (*MemPageTable(ptr)&1)
+      return TRUE;
+    else
+      return FALSE;
+  } else if (ptr<mem_boot_base)
+    return FALSE;
+  else if (ptr<VGAM_GRAPHICS)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+Bool ChkOnStk(U8 *ptr,CTask *task=NULL)
+{//Check if addr is valid stk addr.
+  Bool res=FALSE;
+  PUSHFD
+  CLI
+  if (task) {
+    if (&task->stk->stk_base<=ptr<=
+          (&task->stk->stk_base)(U8 *)+task->stk->stk_size)
+      res=TRUE;
+  } else if (mem_heap_base<=ptr<=mem_heap_limit)
+    res=TRUE;
+  POPFD
+  return res;
+}
+
+I64 UnusedStk(CTask *task=NULL)
+{//Count of usused bytes in task's stk.
+  I64 res;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (task==Fs)
+    res=GetRSP()(U8 *)-(&task->stk->stk_base)(U8 *);
+  else
+    res=task->rsp(U8 *)-(&task->stk->stk_base)(U8 *);
+  POPFD
+  return res;
+}
+
+U8 *Caller(I64 num=1)
+{//Returns the addr of the fun which called this one,
+//or the caller of the caller, etc.
+  U8 **rbp=GetRBP,**ptr;
+  while (num--) {
+    if (rbp>=*rbp)
+      return NULL;
+    rbp=*rbp;
+    if (!ChkOnStk(rbp,Fs))
+      return NULL;
+  }
+  ptr=rbp+1;
+  return *ptr;
+}
+
+U8 *TaskCaller(CTask *task=NULL,I64 num=0,Bool saved_context=FALSE)
+{//Fetches addr of Nth caller on task's stk.
+  U8 **ptr,**rbp,**rsp;
+  if (!task) task=Fs;
+  if (!saved_context && task==Fs)
+    return Caller(num+1);
+  if (!TaskValidate(task))
+    return NULL;
+  rbp=task->rbp;
+  rsp=task->rsp;
+  if (num) {
+    while (ChkOnStk(rbp,task)) {
+      ptr=rbp+1;
+      if (! --num)
+        return *ptr;
+      if (rbp>=*rbp)
+        break;
+      rbp=*rbp;
+    }
+    return NULL;
+  } else {
+    if (task->rip==_RET)
+      return *rsp;
+    else
+      return task->rip;
+  }
+}
+#define STK_REP_LEN     32
+
+U0 StkRep(CTask *task=NULL)
+{//Reports whats on the stk.
+  I64 i,j,addr,
+        **rbp,**rsp,*my_rsp[STK_REP_LEN];
+  CHashTable *old_hash=Fs->hash_table;
+  if (!task) task=Fs;
+  if (!TaskValidate(task))
+    return;
+  PUSHFD
+  CLI
+  if (task==Fs) {
+    rbp=GetRBP;
+    rsp=rbp+3;
+    rbp=*rbp;
+  } else {
+    rsp=task->rsp;
+    rbp=task->rbp;
+  }
+  if (task->rip==_RET)
+    addr=*rsp;
+  else
+    addr=task->rip;
+  MemCpy(my_rsp,rsp,STK_REP_LEN*sizeof(U8 *));
+  POPFD
+  Fs->hash_table=task->hash_table;
+  for (i=0;i<STK_REP_LEN;i++) {
+    "%08X [RSP+%04X]: %016X ",rsp+i,
+          i*sizeof(U8 *),my_rsp[i];
+    while (TRUE) {
+      if (!(&task->stk->stk_base<=rbp<
+            (&task->stk->stk_base)(U8 *)+task->stk->stk_size))
+        break;
+      j=rbp-rsp;
+      if (j>=i)
+        break;
+      addr=my_rsp[j+1];
+      if (rbp>=my_rsp[j])
+        break;
+      rbp=my_rsp[j];
+    }
+    if (my_rsp[i]==addr)
+      "$RED$";
+    "%P$FG$\n",my_rsp[i];
+  }
+  '\n';
+  Fs->hash_table=old_hash;
+}
+
+U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL)
+{//Prints a report of calling routines.
+  I64 **ptr;
+  if (!task) task=Fs;
+  if (!rbp) {
+    if (task==Fs)
+      rbp=GetRBP;
+    else
+      rbp=task->rbp;
+  }
+  "CallerRep:\n";
+  while (ChkOnStk(rbp,task)) {
+    ptr=rbp+1;
+    "%08X:%08tX:%P\n",ptr,*ptr,*ptr;
+    if (rbp>=*rbp)
+      break;
+    rbp=*rbp;
+  }
+}
+
+U0 D(U8 *addr,I64 cnt=0x80,Bool show_offset=TRUE)
+{//Dump mem, showing offsets.
+//See DocD() for a live dump.
+  I64 i,j,ch;
+  U8 *ptr=addr;
+  while (cnt) {
+    if (show_offset)
+      "%08X ",ptr-addr;
+    else
+      "%010X ",ptr;
+    if (cnt>16)
+      j=16;
+    else
+      j=cnt;
+    for (i=0;i<j;i++)
+      "%02X ",ptr[i];
+    for (;i<16;i++)
+      "   ";
+    for (i=0;i<j;i++) {
+      ch=ptr[i];
+      if (ch<CH_SHIFT_SPACE || ch==CH_BACKSPACE)
+        ch='.';
+      '' ch;
+      if (ch=='$')
+        '' ch;
+    }
+    '\n';
+    cnt-=j;
+    ptr+=j;
+  }
+}
+
+U0 Dm(U8 *addr,I64 cnt=0x80)
+{//Show mem addr, not offsets.
+  D(addr,cnt,FALSE);
+}
+
+U0 Da(U8 **addr,I64 cnt=0x10)
+{//Dump mem, showing symbolic addresses.
+  while (cnt-->0) {
+    "%08X:%08X,%P\n",addr,*addr,*addr;
+    addr++;
+  }
+}
+
+U0 RawPrint(I64 mS=100,U8 *fmt,...)
+{//Print using Raw scrn output for a length of time.
+//Your heap must be good.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  Bool old_raw,old_input_filter;
+  PUSHFD
+  CLI
+  old_raw=Raw(ON);
+  old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  "%s",buf;
+  Busy(mS<<10);
+  POPFD
+  LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
+  Raw(old_raw);
+  Free(buf);
+}
+
+U0 RawD(I64 mS=100,U8 *addr,I64 cnt=0x80)
+{//Dumps a block of mem using Raw
+//scrn output for a fixed length
+  //of time.
+  Bool old_raw,old_input_filter;
+  PUSHFD
+  CLI
+  old_raw=Raw(ON);
+  old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  D(addr,cnt);
+  Busy(mS<<10);
+  POPFD
+  LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
+  Raw(old_raw);
+}
+
+U0 RawDm(I64 mS=100,U8 *addr,I64 cnt=0x80)
+{//Dumps a block of mem using Raw
+//scrn output for a fixed length
+  //of time.
+  Bool old_raw,old_input_filter;
+  PUSHFD
+  CLI
+  old_raw=Raw(ON);
+  old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  Dm(addr,cnt);
+  Busy(mS<<10);
+  POPFD
+  LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
+  Raw(old_raw);
+}
+
+I64 *TaskRegAddr(CTask *task,I64 reg_num)
+{
+  switch (reg_num) {
+    case REG_RAX: return &task->rax;
+    case REG_RCX: return &task->rcx;
+    case REG_RDX: return &task->rdx;
+    case REG_RBX: return &task->rbx;
+    case REG_RSP: return &task->rsp;
+    case REG_RBP: return &task->rbp;
+    case REG_RSI: return &task->rsi;
+    case REG_RDI: return &task->rdi;
+    case 8 : return &task->r8;
+    case 9 : return &task->r9;
+    case 10: return &task->r10;
+    case 11: return &task->r11;
+    case 12: return &task->r12;
+    case 13: return &task->r13;
+    case 14: return &task->r14;
+    case 15: return &task->r15;
+  }
+  return NULL;
+}
+
+#define RAWDR_COL       40
+
+U0 RawDr(CTask *task=NULL)
+{
+  I64 i,j,old_col=text.raw_col;
+  Bool old_raw=Raw(ON);
+  U8 buf[200];
+
+  if (!task) task=Fs;
+
+  for (i=0;i<16;i++) {
+    text.raw_col=i*text.cols+RAWDR_COL;
+    ".%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAddr(task,i);
+  }
+
+  text.raw_col=i++*text.cols+RAWDR_COL;
+  ".RIP:%016X\n",task->rip;
+
+  text.raw_col=i++*text.cols+RAWDR_COL;
+  ".%-*tp\n",text.cols-(RAWDR_COL+1)-1,Fs->rip;
+
+  text.raw_col=i++*text.cols+RAWDR_COL;
+  '.';
+  if (Bt(&sys_run_level,RLf_COMPILER)) {
+    j=Fs->rip;
+    Ui(buf,&j,,,TRUE);
+    "%s",buf;
+  } else
+    '\n';
+
+  text.raw_col=i*text.cols+RAWDR_COL;
+  '.';
+  for (j=0;j<text.cols-RAWDR_COL-1;j++)
+    '.';
+
+  text.raw_col=old_col;
+  Raw(old_raw);
+}
+
+U0 Dr(CTask *task=NULL)
+{//Dump regs
+  I64 i;
+  if (!task) task=Fs;
+  for (i=0;i<16;i++)
+    "%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAddr(task,i);
+  "RIP:%016X\n",task->rip;
+}
+
+U8 *SysGetStr2(I64)
+{
+  U8 buf[512];
+  GetS(buf,512,FALSE);
+  return StrNew(buf);
+}
+
+CBpt *BptFind(U8 *needle_addr,CTask *haystack_task=NULL,Bool rem=FALSE)
+{
+  CBpt *res=NULL,*tmpb,*tmpb1,*tmpb2;
+  if (!haystack_task) haystack_task=Fs;
+  PUSHFD
+  CLI
+  tmpb1=&haystack_task->bpt_lst;
+  tmpb=haystack_task->bpt_lst;
+  while (tmpb) {
+    tmpb2=tmpb->next;
+    if (tmpb->addr==needle_addr) {
+      res=tmpb;
+      if (rem)
+        tmpb1->next=tmpb2;
+      else
+        tmpb1=&tmpb->next;
+    } else
+      tmpb1=&tmpb->next;
+    tmpb=tmpb2;
+  }
+  POPFD
+  return res;
+}
+
+Bool BptS(U8 *addr,CTask *task=NULL,Bool live=TRUE)
+{//Set breakpoint.
+  CBpt *tmpb;
+  Bool res=TRUE;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (!(tmpb=BptFind(addr,task,FALSE))) {
+    tmpb=CAlloc(sizeof(CBpt),task);
+    tmpb->addr=addr;
+    tmpb->val=*addr;
+    res=FALSE;
+    tmpb->next=task->bpt_lst;
+    task->bpt_lst=tmpb;
+    if (task==Fs && live)
+      *addr=OC_BPT;
+  }
+  POPFD
+  return res;
+}
+
+Bool BptR(U8 *addr,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE)
+{//Rem breakpoint.
+  CBpt *tmpb;
+  Bool res=FALSE;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (tmpb=BptFind(addr,task,rem)) {
+    if (task==Fs && live)
+      *tmpb->addr=tmpb->val;
+    res=TRUE;
+    if (rem)
+      Free(tmpb);
+  }
+  POPFD
+  return res;
+}
+
+Bool B(U8 *addr,CTask *task=NULL,Bool live=TRUE)
+{//Toggle breakpoint.
+//Return: TRUE if removed.
+  Bool res=FALSE;
+  PUSHFD
+  CLI
+  if (BptFind(addr,task,FALSE)) {
+    BptR(addr,task,live,TRUE);
+    res=TRUE;
+  } else
+    BptS(addr,task,live);
+  POPFD
+  return res;
+}
+
+I64 B2(CTask *task=NULL,Bool live=TRUE)
+{//Rem all breakpoints.
+//Return: cnt of removed.
+  I64 res=0;
+  CBpt *tmpb,*tmpb1;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  tmpb=task->bpt_lst;
+  task->bpt_lst=NULL;
+  while (tmpb) {
+    tmpb1=tmpb->next;
+    if (task==Fs && live)
+      *tmpb->addr=tmpb->val;
+    Free(tmpb);
+    tmpb=tmpb1;
+    res++;
+  }
+  POPFD
+  return res;
+}
+
+U0 G(U8 *ip=INVALID_PTR,CTask *task=NULL)
+{//Go
+  if (!task) task=Fs;
+  if (ip!=INVALID_PTR) task->rip=ip;
+  if (BptFind(task->rip,task))
+    "\nDo one of the following, first:\n"
+          ">S;\t\t\t//Single step\n"
+          ">B2;\t\t\t//Clear all break points\n"
+          ">G2;\t\t\t//Clear all break points and Go\n\n"
+          "After resuming, <CTRL-ALT-n> next focus task\n"
+          "After resuming, <CTRL-ALT-v> flushes scrn VGA cache\n";
+  else {
+    LBtr(&task->task_flags,TASKf_DISABLE_BPTS);
+    LBtr(&task->rflags,RFLAGf_TRAP);//No single step
+    Suspend(task,FALSE);
+    if (task==Fs) {
+      if (IsDbgMode && task->next_cc!=&task->next_cc) {
+        "Exit Dbg\n";
+        Btr(&task->last_cc->flags,CCf_PMT);
+      }
+    } else
+      Exit;
+  }
+}
+
+U0 G2(U8 *ip=INVALID_PTR,CTask *task=NULL)
+{//Rem all breakpoints and Go.
+  if (!task) task=Fs;
+  B2(task);
+  if (ext[EXT_WIN_FOCUS])
+    CallExtNum(EXT_WIN_FOCUS,dbg.focus_task);
+  VGAFlush;
+  G(ip,task);
+}
+
+public U0 S(U8 *ip=INVALID_PTR,CTask *task=NULL) //Single-step.
+{//Single step.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (ip!=INVALID_PTR) task->rip=ip;
+  LBts(&task->task_flags,TASKf_DISABLE_BPTS);
+  LBts(&task->rflags,RFLAGf_TRAP);
+  Suspend(task,FALSE);
+  if (task==Fs) {
+    if (IsDbgMode) {
+      if (task->next_cc!=&task->next_cc)
+        Btr(&task->last_cc->flags,CCf_PMT);
+    }
+  } else
+    Exit;
+  POPFD
+}
+
+U0 DbgHelp()
+{
+  "\n"
+        "The cmd line is basically the same as normal.  Here are some common\n"
+        "debugging commands.\n\n"
+        ">EdLite(\"FileName\");\t\t//Edit file.\n"
+        ">D(0x100000);\t\t\t//Dump page tables.\n"
+        ">Dm(0x100000);\t\t\t//Dump page tables.\n"
+        ">Dm(Fs,sizeof(CTask));\t\t//Dump current task record.\n"
+        ">ClassRep(Fs,\"CTask\",1);\t//Dump current task record.\n"
+        ">ClassRep(Fs,,1);\t\t//(It knows lastclass.)\n"
+        ">CallerRep;\t\t\t//Stack trace report.\n"
+        ">Da(_RSP);\t\t\t//Dump stk.\n"
+        ">Dr;\t\t\t\t//Dump Regs.\n"
+        ">1+2*3+&Print;\t\t\t//Show calculation res.\n"
+        ">*(0x70000)(I64 *)=0x123456789;\t//Assign value to 0x70000-0x70007.\n"
+        ">_RAX=0x1234;\t\t\t//Set RAX to 0x1234.\n"
+        ">_RIP=&Break;\t\t//Set RIP.\n"
+        ">I64 i;\t\t\t\t//Declare variable.\n"
+        ">i=_RCX+_RDX;\t\t\t//Assign to variable.\n"
+        ">U(&Print+0x8);\t\t\t//Unassemble Print.\n"
+        ">Uf(\"Print\");\t\t\t//Unassembler function \"Print\".\n"
+        ">Man(\"Print\");\t\t\t//Edit Src for \"Print\".\n"
+        ">E(_RIP);\t\t\t//Edit Src Code.\n"
+        ">Fix;\t\t\t\t//Edit Last Err Src Code.\n"
+        ">B(&Main+0x20);\t\t\t//Toggle break point.\n"
+        ">B2;\t\t\t\t//Clear all break points.\n"
+        ">S;\t\t\t\t//Single step.\n"
+        ">G;\t\t\t\t//Resume execution.\n"
+        ">G2;\t\t\t\t//B2;VGAFlush;WinFocus;G;\n"
+        ">Exit;\t\t\t\t//Exit (kill) task.\n\n"
+        "After resuming, <CTRL-ALT-n> next focus task.\n"
+        "After resuming, <CTRL-ALT-v> flushes scrn VGA cache.\n\n";
+}
+
+U0 Dbg2()
+{
+  Bool old_win_inhibit,old_waiting_msg,old_single;
+  I64 i,old_getstr2;
+  U8 buf[200];
+  if (dbg.panic) {
+    if (IsRaw) {
+      i=Fs->rip;
+      Ui(buf,&i);
+      "%s",buf;
+    } else
+      U(Fs->rip,1);
+  } else
+    dbg.panic=TRUE;
+  old_waiting_msg=LBtr(&Fs->task_flags,TASKf_AWAITING_MSG);
+  old_win_inhibit=Fs->win_inhibit;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  sys_focus_task=Fs;
+  kbd.scan_code=0;
+  old_getstr2=fp_getstr2;
+  fp_getstr2=&SysGetStr2;
+  old_single=SingleUser(OFF);
+  while (!ms_hard.install_attempts)
+    Yield;
+  SingleUser(old_single);
+  UserTaskCont;
+  fp_getstr2=old_getstr2;
+  Fs->win_inhibit=old_win_inhibit;
+  LBEqu(&Fs->task_flags,TASKf_AWAITING_MSG,old_waiting_msg);
+}
+
+U0 Fault3(I64 fault_num,I64 fault_err_code)
+{
+  no_warn fault_err_code;
+  PUSHFD
+  CLI
+  if (Gs->num && dbg.mp_crash) {
+    mp_cnt=1;
+    dbg.mp_crash->cpu_num=Gs->num;
+    dbg.mp_crash->task=Fs;
+    dbg.mp_crash->rip=Fs->rip;
+    dbg.mp_crash->msg=dbg.msg;
+    dbg.mp_crash->msg_num=dbg.msg_num;
+    MPInt(I_MP_CRASH,0);
+    SysHlt;
+  }
+  "\n\tTempleOS Debugger\n\n"
+        ">Help;\t//For help.\n\n";
+  Beep(62,TRUE);
+  if (fault_num==I_DBG) {
+    if (dbg.msg) {
+      "\n!!! %s",dbg.msg;
+      if (dbg.msg_num)
+        "%016X",dbg.msg_num;
+      " !!!\n\n";
+    }
+  }
+  if (dbg.panic)
+    CallerRep;
+  Dbg2;
+  POPFD
+}
+
+U0 Fault2(I64 fault_num,I64 fault_err_code)
+{//Called from Fault2.
+//Be careful not to swap-out and ruin the saved context
+  Bool was_raw,was_single_user,was_silent,was_in_dbg;
+  I64  i,old_raw_flags=text.raw_flags;
+  was_single_user=SingleUser(ON);
+  if (!IsDbgMode)
+    dbg.focus_task=sys_focus_task;
+  sys_focus_task=NULL;
+  if (fault_num==I_BPT)
+    Fs->rip--;
+  if (Fs->dbg_task)
+    CallExtNum(EXT_DBG_RESUME,fault_num,fault_err_code);
+  else {
+    was_raw=Raw(ON);
+    was_silent=Silent(OFF);
+    text.raw_flags|=RWF_SHOW_DOLLAR|RWF_SCROLL;
+
+    "Task \"";
+    "%s",Fs->task_title;
+    "\"\n";
+    "Fault:0x%02X %Z\t\tErr Code:%08X\n",
+          fault_num,fault_num,"ST_INT_NAMES",fault_err_code;
+    was_in_dbg=DbgMode(ON);
+    "RIP:%08X",Fs->rip; //Sometimes crashes on %p, so do this first
+    ":%p  RSP:%08X\n",Fs->rip,Fs->rsp;
+    if (fault_num==I_PAGE_FAULT) {
+      MOV_RAX_CR2
+      i=GetRAX;
+      "Fault Addr:%08X:%p\n",i,i;
+    }
+    Fault3(fault_num,fault_err_code);
+    DbgMode(was_in_dbg);
+    Silent(was_silent);
+    Raw(was_raw);
+    text.raw_flags=old_raw_flags;
+  }
+  SingleUser(was_single_user);
+  if (LBtr(&Fs->task_flags,TASKf_KILL_AFTER_DBG))
+    Exit;
+}
+
+U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE)
+{//Enter the debugger with panic?
+  PUSHFD
+  CLI
+  dbg.msg=msg;
+  dbg.msg_num=msg_num;
+  dbg.panic=panic;
+  INT I_DBG
+  POPFD
+}
+
+U0 Dbg(U8 *msg=NULL,I64 msg_num=0)
+{//Enter debugger, no panic.
+  Panic(msg,msg_num,FALSE);
+}
+
+ diff --git a/public/Wb/Kernel/KDefine.HC.HTML b/public/Wb/Kernel/KDefine.HC.HTML new file mode 100755 index 0000000..f093f05 --- /dev/null +++ b/public/Wb/Kernel/KDefine.HC.HTML @@ -0,0 +1,249 @@ + + + + + + + + + + + +
+CHashDefineStr *DefineLoad(U8 *dname,U8 *st)
+{//Create DEFINE hash entry with string.
+  CHashDefineStr *tmph=CAlloc(sizeof(CHashDefineStr));
+  tmph->type=HTT_DEFINE_STR;
+  tmph->str=StrNew(dname);
+  tmph->data=StrNew(st);
+  tmph->cnt=-1;
+  tmph->src_link=MStrPrint("AD:0x%X",Caller);
+  HashAdd(tmph,Fs->hash_table);
+  return tmph;
+}
+
+CHashDefineStr *DefineLstLoad(U8 *dname,U8 *lst)
+{//Create DEFINE list. Not efficient, but handy.
+  I64 cnt=0;
+  U8 *ptr,**idx;
+  CHashDefineStr *tmph=CAlloc(sizeof(CHashDefineStr));
+  tmph->type=HTT_DEFINE_STR;
+  tmph->str=StrNew(dname);
+  tmph->src_link=MStrPrint("AD:0x%X",Caller);
+  ptr=lst;
+  while (*ptr) {
+    if (*ptr!='@')
+      cnt++;
+    while (*ptr++);
+  }
+  tmph->data=MAlloc(ptr+1-lst);
+  MemCpy(tmph->data,lst,ptr+1-lst);
+  tmph->cnt=cnt;
+
+  idx=tmph->sub_idx=MAlloc(cnt*sizeof(U8 *));
+  ptr=lst;
+  while (*ptr) {
+    if (*ptr!='@')
+      *idx++=ptr;
+    while (*ptr++);
+  }
+
+  HashAdd(tmph,Fs->hash_table);
+  return tmph;
+}
+
+U0 UndefinedDefine(U8 *dname)
+{
+  ST_ERR_ST "Undefined Define: '%s'.\n",dname;
+  throw('UndefDef');
+}
+
+U8 *Define(U8 *dname)
+{//Look for DEFINE named in hash table, return ptr string.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR))
+    return tmph->data;
+  else if (dname)
+    UndefinedDefine(dname);
+  else
+    return NULL;
+}
+
+U8 *DefineSub(I64 sub,U8 *dname)
+{//Return DEFINE list entry indexed by number.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR)) {
+    if (0<=sub<tmph->cnt)
+      return tmph->sub_idx[sub];
+    else
+      return NULL;
+  } else if (dname)
+    UndefinedDefine(dname);
+  else
+    return NULL;
+}
+
+I64 DefineCnt(U8 *dname)
+{//Return cnt of entries in define list.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR))
+    return tmph->cnt;
+  else if (dname)
+    UndefinedDefine(dname);
+  else
+    return -1;
+}
+
+I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0)
+{//Find match for string in define list.
+  return LstMatch(needle,Define(haystack_lst_dname),flags);
+}
+
+U0 DefinePrint(U8 *dname,U8 *src,...)
+{//Create DEFINE entry with Print()ed string.
+  U8 *buf=StrPrintJoin(NULL,src,argc,argv);
+  DefineLoad(dname,buf);
+  Free(buf);
+}
+
+U0 SysDefinesLoad()
+{
+  DefineLstLoad("ST_OFF_ON","Off\0On\0");
+  DefineLstLoad("ST_HTT_TYPES","ExportSysSym\0ImportSysSym\0DefineStr\0GlbVar\0"
+        "Class\0IntType\0Funct\0Word\0DictWord\0KeyWord\0AsmKeyWord\0OpCode\0"
+        "Reg\0File\0Module\0HelpFile\0Frame Ptr\0 \0 \0 \0 \0 \0 \0Private\0"
+        "Public\0Export\0Import\0Imm\0Goto\0Res\0Unres\0Local\0");
+  DefineLstLoad("ST_DAYS_OF_WEEK","Sunday\0Monday\0Tuesday\0Wednesday\0"
+        "Thursday\0Friday\0Saturday\0");
+  DefineLstLoad("ST_MONTHS","January\0February\0March\0April\0May\0"
+        "June\0July\0August\0September\0October\0November\0December\0");
+  DefineLstLoad("ST_FILE_ATTRS","R\0H\0S\0V\0D\0A\0 \0 \0X\0T\0Z\0C\0F\0");
+  DefineLstLoad("ST_FILE_UTIL_FLAGS","r\0d\0i\0a\0c\0R\0p\0m\0x\0s\0"
+        "D\0F\0T\0$\0S\0A\0J\0G\0Z\0O\0P\0f\0l\0lb\0la\0");
+  DefineLstLoad("ST_BLKDEV_TYPES",
+        "NULL\0RAM\0ATA\0FILE_READ\0FILE_WRITE\0ATAPI\0");
+  DefineLstLoad("ST_DRV_TYPES",
+        "NULL\0REDSEA\0FAT32\0ISO9660\0NTFS\0UNKNOWN\0");
+  DefineLstLoad("ST_COLORS","BLACK\0BLUE\0GREEN\0CYAN\0"
+        "RED\0PURPLE\0BROWN\0LTGRAY\0DKGRAY\0LTBLUE\0LTGREEN\0"
+        "LTCYAN\0LTRED\0LTPURPLE\0YELLOW\0WHITE\0");
+  DefineLstLoad("ST_INT_NAMES","Divide Error\0SingleStep\0NMI\0Breakpoint\0"
+        "Overflow\0BOUND Range Exceeded\0Invalid Opcode\0No Math Coprocessor\0"
+        "Double Fault\0Coprocessor Segment Fault\0Invalid TASK\0"
+        "Segment Not Present\0Stk Segment Fault\0General Protection\0"
+        "Page Fault\0 \0Math Fault\0Alignment Check\0Machine Check\0"
+        "SIMD Exception\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 \0MP Crash\0Wake\0Dbg\0");
+}
+
+U8 *Color2Str(U8 *buf,CColorROPU32 c)
+{//CColorROPU32 with flags to DCLighting str.
+  *buf=0;
+  if (c.c0.rop&ROPBF_TWO_SIDED)
+    CatPrint(buf,"TWO|");
+  if (c.c0.rop&ROPBF_HALF_RANGE_COLOR)
+    CatPrint(buf,"HALF|");
+  if (0<=c.c0.color<16)
+    CatPrint(buf,DefineSub(c.c0.color,"ST_COLORS"));
+  else if (c.c0.color==TRANSPARENT)
+    CatPrint(buf,"TRANSPARENT");
+  else
+    CatPrint(buf,"INVALID");
+  if (c&ROPF_DITHER) {
+    CatPrint(buf,"/");
+    if (c.c1.rop&ROPBF_TWO_SIDED)
+      CatPrint(buf,"TWO|");
+    if (c.c1.rop&ROPBF_HALF_RANGE_COLOR)
+      CatPrint(buf,"HALF|");
+    if (0<=c.c1.color<16)
+      CatPrint(buf,DefineSub(c.c1.color,"ST_COLORS"));
+    else if (c.c1.color==TRANSPARENT)
+      CatPrint(buf,"TRANSPARENT");
+    else
+      CatPrint(buf,"INVALID");
+  }
+  return buf;
+}
+
+U8 *str2color_lst="/,)}>";
+
+CColorROPU16 Str2ColorU16(U8 *st)
+{//DCLighting color str with flags to CColorROPU16.
+  CColorROPU16 res=COLOR_INVALID;
+  I64 i;
+  U8 *ptr,*ptr2,*st2;
+  if (!st) return COLOR_INVALID;
+  while (TRUE) {
+    if (!*st||StrOcc(str2color_lst,*st))
+      return res;
+    if (Bt(char_bmp_alpha,*st)) {
+      ptr=st;
+      while (Bt(char_bmp_alpha_numeric,*ptr))
+        ptr++;
+      st2=ptr2=MAlloc(ptr-st+1);
+      while (st<ptr)
+        *ptr2++=*st++;
+      *ptr2++=0;
+      if (!StrICmp(st2,"TWO"))
+        res.rop|=ROPBF_TWO_SIDED;
+      else if (!StrICmp(st2,"HALF"))
+        res.rop|=ROPBF_HALF_RANGE_COLOR;
+      else if ((i=DefineMatch(st2,"ST_COLORS",LMF_IGNORE_CASE))>=0)
+        res.color=i;
+      else if (!StrICmp(st2,"TRANSPARENT"))
+        res.color=TRANSPARENT;
+      else {
+        Free(st2);
+        return COLOR_INVALID;
+      }
+      Free(st2);
+    } else if (*st=='+'||*st=='|'||Bt(char_bmp_white_space,*st))
+      st++;
+    else if ('0'<=*st<='9') {
+      i=Str2I64(st,10,&ptr);
+      if (0<=i<=0xFF) {
+        res.color=i;
+        st=ptr;
+      } else
+        return COLOR_INVALID;
+    } else
+      return COLOR_INVALID;
+  }
+}
+
+CColorROPU32 Str2ColorU32(U8 *st)
+{//DCLighting color str with flags to CColorROPU32.
+  U8 *st2;
+  CColorROPU32 res=0;
+  if (!st) return COLOR_INVALID;
+  st2=MAlloc(StrLen(st)+1);
+  StrFirstRem(st,str2color_lst,st2);
+  res.c0=Str2ColorU16(st2);
+  if (*st) {
+    res.c1=Str2ColorU16(st);
+    res|=ROPF_DITHER;
+  }
+  if (res.c0.color==COLOR_INVALID||res.c1.color==COLOR_INVALID)
+    return COLOR_INVALID;
+  else
+    return res;
+}
+
+ diff --git a/public/Wb/Kernel/KExcept.HC.HTML b/public/Wb/Kernel/KExcept.HC.HTML new file mode 100755 index 0000000..1b547fe --- /dev/null +++ b/public/Wb/Kernel/KExcept.HC.HTML @@ -0,0 +1,180 @@ + + + + + + + + + + + +
+asm {
+#assert !((REGG_LOCAL_NON_PTR_VARS|REGG_LOCAL_VARS)&~0xFCC0)
+_TEST_EXCEPT::
+        XOR     RAX,RAX
+        MOV     RAX,FS:U64 CTask.last_except[RAX]
+        MOV     RBP,U64 CExcept.rbp[RAX]
+        MOV     RSI,U64 CExcept.rsi[RAX]
+        MOV     RDI,U64 CExcept.rdi[RAX]
+        MOV     R10,U64 CExcept.r10[RAX]
+        MOV     R11,U64 CExcept.r11[RAX]
+        MOV     R12,U64 CExcept.r12[RAX]
+        MOV     R13,U64 CExcept.r13[RAX]
+        MOV     R14,U64 CExcept.r14[RAX]
+        MOV     R15,U64 CExcept.r15[RAX]
+        PUSH    U64 CExcept.rflags[RAX]
+        POPFD
+        JMP     U64 CExcept.hndlr_catch[RAX]
+
+_TAKE_EXCEPT::
+        XOR     RAX,RAX
+        MOV     RAX,FS:U64 CTask.last_except[RAX]
+        MOV     RSP,U64 CExcept.rsp[RAX]
+        JMP     U64 CExcept.hndlr_untry[RAX]
+
+_SAVE_EXCEPT_REGS::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     U64 CExcept.rsi[RAX],RSI
+        MOV     U64 CExcept.rdi[RAX],RDI
+        MOV     U64 CExcept.r10[RAX],R10
+        MOV     U64 CExcept.r11[RAX],R11
+        MOV     U64 CExcept.r12[RAX],R12
+        MOV     U64 CExcept.r13[RAX],R13
+        MOV     U64 CExcept.r14[RAX],R14
+        MOV     U64 CExcept.r15[RAX],R15
+        POP     RBP
+        RET1    8
+}
+
+_extern _TEST_EXCEPT U0 TestExcept();
+_extern _TAKE_EXCEPT U0 TakeExcept();
+_extern _SAVE_EXCEPT_REGS U0 SaveExceptRegs(CExcept *t);
+
+U0 PutExcept(Bool catch_it=TRUE)
+{//Print exception msg and catch exception.
+  "Except:%c:",Fs->except_ch;
+  "%P:%P:%P:%P:%P:%P\n",Fs->except_callers[0],Fs->except_callers[1],
+        Fs->except_callers[2],Fs->except_callers[3],Fs->except_callers[4],
+        Fs->except_callers[5],Fs->except_callers[6],Fs->except_callers[7];
+  Fs->catch_except=catch_it;
+}
+
+#exe {Option(OPTf_NO_REG_VAR,ON);};
+
+class CTryStk
+{
+  I64 rbp;
+  I64 ret_rip;
+  I64 arg1;
+  I64 arg2;
+};
+
+U0 SysTry(U8 *catch_start,U8 *untry_start)
+{
+  I64 *rbp=GetRBP;
+  CExcept *tmpt=MAlloc(sizeof(CExcept));
+  tmpt->hndlr_catch=catch_start;
+  tmpt->hndlr_untry=untry_start;
+  tmpt->rsp=rbp(U8 *)+sizeof(CTryStk);
+  tmpt->rbp=*rbp;
+  tmpt->rflags=GetRFlags;
+  SaveExceptRegs(tmpt);
+  QueIns(tmpt,Fs->last_except);
+}
+
+U0 SysUntry()
+{
+  CExcept *tmpt=Fs->last_except;
+  QueRem(tmpt);
+  Free(tmpt);
+}
+
+U0 throw(I64 ch=0,Bool no_log=FALSE)
+{//ch can be up to 8 chars like PutChars().
+//In the catcher, fetch ch from Fs->except_ch.
+  CExcept *tmpt=Fs->last_except;
+  Bool was_raw;
+  I64 i;
+  Fs->except_ch=ch;
+  for (i=0;i<TASK_EXCEPT_CALLERS;i++)
+    Fs->except_callers[i]=Caller(i+1);
+  Fs->except_rbp=GetRBP;
+  Fs->catch_except=FALSE;
+  if (!no_log)
+    AdamLog("Except:%c:%p:%p:%p:%p:%p:%p\n",ch,Fs->except_callers[0],
+          Fs->except_callers[1],Fs->except_callers[2],Fs->except_callers[3],
+          Fs->except_callers[4],Fs->except_callers[5],Fs->except_callers[6],
+          Fs->except_callers[7]);
+  while (Fs->next_except!=&Fs->next_except) {
+    TestExcept;
+    if (Fs->catch_except)
+      TakeExcept;
+    SetRBP(Fs->except_rbp);
+    tmpt=Fs->last_except;
+    QueRem(tmpt);
+    Free(tmpt);
+  }
+  was_raw=Raw(ON);
+  PutExcept(FALSE);
+  Panic("Unhandled Exception");
+  Raw(was_raw);
+}
+
+#exe {Option(OPTf_NO_REG_VAR,OFF);};
+
+U0 Break()
+{//Send <CTRL-ALT-c>.
+  if (Bt(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC))
+    Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0x20100000201);
+  else {
+    Fs->wake_jiffy=0;
+    TaskRstAwaitingMsg;
+    DrvsRelease();
+    BlkDevsRelease();
+    FlushMsgs;
+    throw('Break');
+  }
+}
+
+Bool BreakLock(CTask *task=NULL)
+{//Disables <CTRL-ALT-c>.
+  if (!task) task=Fs;
+  return !LBts(&task->task_flags,TASKf_BREAK_LOCKED);
+}
+
+Bool BreakUnlock(CTask *task=NULL)
+{//Reenables <CTRL-ALT-c> and issues any pending breaks.
+  Bool res;
+  if (!task) task=Fs;
+  res=LBtr(&task->task_flags,TASKf_BREAK_LOCKED);
+  if (LBtr(&task->task_flags,TASKf_PENDING_BREAK)) {
+    if (task==Fs)
+      Break;
+    else
+      task->rip=&Break;
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/KExts.HC.HTML b/public/Wb/Kernel/KExts.HC.HTML new file mode 100755 index 0000000..1fb4154 --- /dev/null +++ b/public/Wb/Kernel/KExts.HC.HTML @@ -0,0 +1,140 @@ + + + + + + + + + + + +
+/*
+If you are sure a fun won't be called
+before import is resolved, you can use
+"import".  Otherwise, use a fun pointer
+var and check it before calling.
+*/
+import U0 ClassRep(U8 *_d,U8 *class_name=lastclass,
+        I64 max_depth=2,Bool fun=FALSE,I64 offset=0);
+import U8 *DocSave(CDoc *doc,I64 *_size=NULL);
+import Bool DocUnlock(CDoc *doc);
+import Bool Ed(U8 *link_st,I64 edf_dof_flags=0);
+extern U0 AdamErr(U8 *fmt,...);
+extern U0 AdamLog(U8 *fmt,...);
+extern I64 BIOSTotalMem();
+extern I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN,
+        Bool whole_drv,Bool make_free);
+extern CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE);
+extern Bool BlkDevLock(CBlkDev *bd);
+extern CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type);
+extern Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE);
+extern U0 BlkDevsRelease();
+extern Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+extern Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+extern U8 *Caller(I64 num=1);
+extern U8 *CatPrint(U8 *_dst,U8 *fmt,...);
+extern Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE);
+extern U0 DbgHelp();
+extern U8 *Define(U8 *dname);
+extern I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0);
+extern U8 *DefineSub(I64 sub,U8 *dname);
+extern I64 Del(U8 *files_find_mask,Bool make_mask=FALSE,
+        Bool del_dir=FALSE,Bool print_msg=TRUE);
+extern Bool DirMk(U8 *filename,I64 entry_cnt=0);
+extern Bool Drv(U8 drv_let);
+extern U8 Drv2Let(CDrv *dv=NULL);
+extern U0 DrvBlkDevDel(CBlkDev *bd);
+extern CDrv *DrvChk(CDrv *dv,Bool except=TRUE);
+extern U8 DrvTextAttrGet(U8 drv_let=0);
+extern Bool DrvTypeSet(U8 drv_let,I64 type=FSt_REDSEA);
+extern U0 DrvsRelease();
+extern U0 DskCacheInvalidate(CDrv *dv);
+extern U0 Exit();
+extern U8 *ExtDft(U8 *filename,U8 *extension);
+extern I64 FAT32AllocClus(CDrv *dv,I64 c,I64 cnt);
+extern I64 FAT32AllocContiguousClus(CDrv *dv,I64 cnt);
+extern Bool FAT32DirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,
+        Bool free_old_chain);
+extern Bool FAT32FileFind(CDrv *dv,I64 cur_dir_clus,U8 *name,
+        CDirEntry *_res,I64 fuf_flags=0);
+extern U0 FAT32Init(CDrv *dv);
+extern Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+extern Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+extern U0 FClose(CFile *f);
+extern CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0);
+extern U8 *FileExtRem(U8 *src,U8 *dst=NULL);
+extern Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0);
+extern U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=0);
+extern U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL);
+extern I64 FileWrite(U8 *filename,U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0);
+extern I64 FlushMsgs(CTask *task=NULL);
+extern I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE);
+extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE);
+extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,
+        CTask *task=NULL,CBlkPool *bp);
+extern Bool ISOInit(CDrv *dv,I64 blk);
+extern Bool IsDbgMode();
+extern Bool IsDir(U8 *dir_name);
+extern Bool IsRaw();
+extern U0 JobCtrlInit(CJobCtrl *ctrl);
+extern U0 JobDel(CJob *tmpc);
+extern U0 JobQueDel(CJob *head);
+extern I64 JobsHndlr(I64 run_flags,CTask *task=NULL);
+extern CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE);
+extern I64 Let2BlkDevType(U8 drv_let);
+extern CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE);
+extern U8 Let2Let(U8 drv_let=0);
+extern U0 MPInt(U8 num,I64 cpu_num=1);
+extern U8 *MStrPrint(U8 *fmt,...);
+extern U0 MsHardSet(I64 x,I64 y,I64 z,I64 l,I64 r);
+extern U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0);
+extern U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE);
+extern I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL);
+extern U0 Print(U8 *fmt,...);
+extern U0 PutChars(U64 ch);
+extern U0 PutS(U8 *st); //Use Print()
+extern I64 RedSeaAllocClus(CDrv *dv,I64 cnt);
+extern Bool RedSeaDirNew(CDrv *dv,U8 *cur_dir,CDirEntry *tmpde,
+        Bool free_old_chain);
+extern Bool RedSeaFileFind(CDrv *dv,I64 cur_dir_clus,U8 *name,
+        CDirEntry *_res,I64 fuf_flags=0);
+extern U0 RedSeaFmt(U8 drv_let,Bool quick=TRUE);
+extern U0 RedSeaFreeFreeLst(CDrv *dv);
+extern U0 RedSeaInit(CDrv *dv);
+extern Bool RedSeaValidate(U8 drv_let);
+extern CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,
+    U8 *task_name=NULL,I64 target_cpu,CTask *parent=NULL, //NULL means adam
+    I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE);
+extern U8 *StrPrint(U8 *dst,U8 *fmt,...);
+extern U0 StrPrintFunSeg(U8 *buf,I64 addr,I64 field_len,I64 flags);
+extern Bool Suspend(CTask *task=NULL,Bool state=TRUE);
+extern CJob *TaskMsg(CTask *_srv,CTask *master,
+        I64 msg_code,I64 arg1,I64 arg2,I64 flags);
+extern U0 TaskRstAwaitingMsg(CTask *task=NULL);
+extern Bool TaskValidate(CTask *task);
+extern U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE);
+extern CTask *User(U8 *fmt=NULL,...);
+extern U0 UserTaskCont();
+extern U0 XTalk(CTask *task,U8 *fmt,...);
+extern U0 throw(I64 ch=0,Bool no_log=FALSE);
+
+ diff --git a/public/Wb/Kernel/KGlbls.HC.HTML b/public/Wb/Kernel/KGlbls.HC.HTML new file mode 100755 index 0000000..500bece --- /dev/null +++ b/public/Wb/Kernel/KGlbls.HC.HTML @@ -0,0 +1,66 @@ + + + + + + + + + + + +
+//Compiler initializes glbls in AOT bin modules to zero.
+//Globals Set to Zero Here.
+
+CJob sys_macro_head;
+CTask *sys_macro_task;
+CDoc *sys_clip_doc;
+
+CTask *adam_task;
+I64 sys_num_spawned_tasks;
+
+CTask *sys_winmgr_task,*sys_task_being_scrn_updated;
+U8 *rev_bits_table, //Table with U8 bits revd
+   *set_bits_table; //Table with count of set bits in a U8
+CDate local_time_offset;
+F64     *pow10_I64,
+        sys_os_version=5.030;
+
+CAutoCompleteDictGlbls acd;
+CAutoCompleteGlbls ac;
+CBlkDevGlbls    blkdev;
+CCntsGlbls      cnts={1,0,2676302000,2676302,2676302000,0,0,0,FALSE};
+CDbgGlbls       dbg;
+CDevGlbls       dev;
+CGridGlbls      ms_grid; //See ::/Demo/Graphics/Grid.HC.
+CMsStateGlbls   ms,ms_last;
+CKbdStateGlbls  kbd;
+CKeyDevGlbls    keydev;
+CMsHardStateGlbls ms_hard,ms_hard_last;
+CScrnCastGlbls  scrncast;
+CTextGlbls      text;
+
+U8  *(*fp_getstr2)(I64 flags=0);
+U0 (*fp_update_ctrls)(CTask *task);
+CDoc *(*fp_doc_put)(CTask *task=NULL);
+U0 (*fp_set_std_palette)();
+
+ diff --git a/public/Wb/Kernel/KHashA.HC.HTML b/public/Wb/Kernel/KHashA.HC.HTML new file mode 100755 index 0000000..9101bbb --- /dev/null +++ b/public/Wb/Kernel/KHashA.HC.HTML @@ -0,0 +1,296 @@ + + + + + + + + + + + +
+asm {
+//************************************
+SYS_HASH_STR::
+// IN:  RSI=Addr of string
+// OUT: RAX
+        XOR     RAX,RAX
+        TEST    RSI,RSI
+        JZ      @@15
+
+        PUSH    RSI
+        PUSH    RBX
+        XOR     RBX,RBX
+        JMP     @@10
+
+@@05:   SHL1    RBX
+        ADC     RBX,RAX
+@@10:   LODSB
+        TEST    AL,AL
+        JNZ     @@05
+
+        MOV     RAX,RBX
+        SHR     RBX,16
+        ADC     RAX,RBX
+        POP     RBX
+        POP     RSI
+
+@@15:   RET
+//************************************
+SYS_HASH_SINGLE_TABLE_FIND1::
+// IN:  RAX=HASHED STRING VAL
+//      RSI=STR
+//      RBX=TYPE MASK
+//      RDI=TABLE
+//      RCX=INSTANCE, NOT ZERO
+// OUT: RAX=ENTRY OR ZERO NOT FOUND
+//      RDX=POINTER TO POINTER TO ENTRY
+//      RCX IF NOT FOUND ENOUGH, DECREMENTED BY NUM MATCHES
+//      ZERO FLAG SET NOT FOUND
+        MOV     RCX,1
+SYS_HASH_SINGLE_TABLE_FIND::
+        TEST    RCX,RCX
+        JNZ     @@05
+        XOR     RAX,RAX
+        RET
+@@05:   AND     RAX,U64 CHashTable.mask[RDI]
+        MOV     RDX,U64 CHashTable.body[RDI]
+        LEA     RDX,U64 [RDX+RAX*8]
+@@10:   MOV     RAX,U64 [RDX]
+        TEST    RAX,RAX
+        JNZ     @@15
+        RET
+
+@@15:   TEST    U32 CHash.type[RAX],EBX
+        JZ      @@30
+        PUSH    RAX
+        PUSH    RDI
+        PUSH    RSI
+        MOV     RDI,U64 CHash.str[RAX]
+@@20:   LODSB
+        CMP     U8 [RDI],AL
+        JNE     @@25
+        INC     RDI
+        TEST    AL,AL
+        JNZ     @@20
+        POP     RSI
+        POP     RDI
+        POP     RAX
+        LOOP    @@30
+        INC     U32 CHash.use_cnt[RAX]
+        TEST    RAX,RAX
+        RET
+
+@@25:   POP     RSI
+        POP     RDI
+        POP     RAX
+
+@@30:   LEA     RDX,U64 CHash.next[RAX]
+        JMP     @@10
+//************************************
+SYS_HASH_FIND1::
+// IN:  RSI=STR
+//      RBX=TYPE MASK
+//      RDI=TABLE
+//      RCX=INSTANCE NUM
+// OUT: RAX=ENTRY OR ZERO NOT FOUND
+//      ZERO FLAG SET NOT FOUND
+        MOV     RCX,1
+SYS_HASH_FIND::
+        PUSH    RDI
+        CALL    SYS_HASH_STR
+        
+@@05:   PUSH    RAX
+        CALL    SYS_HASH_SINGLE_TABLE_FIND
+        JNZ     @@15
+        POP     RAX
+@@10:   MOV     RDI,U64 CHashTable.next[RDI]
+        TEST    RDI,RDI
+        JNZ     @@05
+        POP     RDI
+        XOR     RAX,RAX
+        RET
+
+@@15:   ADD     RSP,8
+        POP     RDI
+        TEST    RAX,RAX
+        RET
+//************************************
+SYS_HASH_BUCKET_FIND::
+// IN:  RSI=STR
+//      RDI=TABLE
+// OUT: RAX=BUCKET
+        PUSH    RDX
+        CALL    SYS_HASH_STR
+        AND     RAX,U64 CHashTable.mask[RDI]
+        MOV     RDX,U64 CHashTable.body[RDI]
+        LEA     RAX,U64 [RDX+RAX*8]
+        POP     RDX
+        RET
+_HASH_STR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        CALL    SYS_HASH_STR
+        POP     RSI
+        POP     RBP
+        RET1    8
+_HASH_FIND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+        CALL    SYS_HASH_FIND
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+_HASH_SINGLE_TABLE_FIND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG4[RBP]
+        CALL    SYS_HASH_STR
+        CALL    SYS_HASH_SINGLE_TABLE_FIND
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    32
+_HASH_BUCKET_FIND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        CALL    SYS_HASH_BUCKET_FIND
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_HASH_ADD::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 CHash.str[RCX]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        CALL    SYS_HASH_BUCKET_FIND
+        MOV     RCX,U64 SF_ARG1[RBP]
+        PUSHFD
+        CLI
+        MOV     RBX,U64 [RAX]
+        MOV     U64 CHash.next[RCX],RBX
+        MOV     U64 [RAX],RCX
+
+        POPFD
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_HASH_ADD_AFTER::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG3[RBP]
+        PUSHFD
+        CLI
+        MOV     RAX,SF_ARG2[RBP]
+        MOV     RBX,U64 [RAX]
+        MOV     U64 CHash.next[RCX],RBX
+        MOV     U64 [RAX],RCX
+
+        POPFD
+        POP     RDI
+        POP     RBP
+        RET1    24
+_HASH_REM_DEL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG1[RBP]
+        TEST    RCX,RCX
+        JZ      @@10
+        MOV     RSI,U64 CHash.str[RCX]
+        XOR     RBX,RBX
+        MOV     EBX,U32 CHash.type[RCX]
+        AND     EBX,~HTG_FLAGS_MASK&0xFFFFFFFF
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        CALL    SYS_HASH_STR
+
+        PUSHFD
+        CLI
+        CALL    SYS_HASH_SINGLE_TABLE_FIND
+        JZ      @@05
+        CMP     RAX,U64 SF_ARG1[RBP]
+        JNE     @@05
+
+        MOV     RBX,U64 CHash.next[RAX]
+        MOV     U64 [RDX],RBX
+
+        POPFD
+
+        PUSH_C_REGS
+        PUSH    RAX
+        CALL    &HashDel
+        POP_C_REGS
+
+        POP     RDI
+        POP     RSI
+        MOV     RAX,1
+        POP     RBP
+        RET1    24
+
+@@05:   POPFD
+@@10:   POP     RDI
+        POP     RSI
+        XOR     RAX,RAX
+        POP     RBP
+        RET1    24
+}
+
+_extern _HASH_STR I64 HashStr(U8 *st); //Hash a string.
+_extern _HASH_FIND CHash *HashFind(U8 *needle_str,CHashTable *haystack_table,
+        I64 mask,I64 instance=1);//Find string in hash table.
+_extern _HASH_SINGLE_TABLE_FIND CHash *HashSingleTableFind(U8 *needle_str,
+        CHashTable *haystack_table,
+        I64 mask,I64 instance=1);//Find string in single hash table.
+_extern _HASH_BUCKET_FIND CHash **HashBucketFind(U8 *needle_str,
+        CHashTable *haystack_table); //Find hash bucket.
+_extern _HASH_ADD U0 HashAdd(CHash *tmph,
+        CHashTable *table); //Add entry to hash table.
+_extern _HASH_REM_DEL Bool HashRemDel(CHash *tmph,CHashTable *table,
+        I64 instance=1);//Remove hash entry and del. Instance must match.
+
+ diff --git a/public/Wb/Kernel/KHashB.HC.HTML b/public/Wb/Kernel/KHashB.HC.HTML new file mode 100755 index 0000000..19576bf --- /dev/null +++ b/public/Wb/Kernel/KHashB.HC.HTML @@ -0,0 +1,281 @@ + + + + + + + + + + + +
+I64 HashTypeNum(CHash *tmph)
+{//Return bit num of hash type, limited to just types.
+  if (tmph)
+    return Bsf(tmph->type&HTG_TYPE_MASK);
+  else
+    return -1;
+}
+
+I64 HashVal(CHash *tmph)
+{//Returns most likely desired value.
+  switch [HashTypeNum(tmph)] {
+    case HTt_EXPORT_SYS_SYM:
+      return tmph(CHashExport *)->val;
+    case HTt_IMPORT_SYS_SYM:
+      return tmph(CHashImport *)->module_base;
+    case HTt_DEFINE_STR:
+    case HTt_CLASS:
+    case HTt_INTERNAL_TYPE:
+    case HTt_WORD:
+    case HTt_DICT_WORD:
+    case HTt_OPCODE:
+    case HTt_HELP_FILE:
+      return tmph;
+    case HTt_GLBL_VAR:
+      if (tmph(CHashGlblVar *)->flags&GVF_EXTERN)
+        return &tmph(CHashGlblVar *)->data_addr;
+      else
+        return tmph(CHashGlblVar *)->data_addr;
+    case HTt_FUN:
+      if (Bt(&tmph(CHashFun *)->flags,Cf_EXTERN))
+        return tmph;
+      else
+        return tmph(CHashFun *)->exe_addr;
+    case HTt_REG:
+      return tmph(CHashReg *)->reg_num|tmph(CHashReg *)->reg_type<<8;
+    case HTt_KEYWORD:
+    case HTt_ASM_KEYWORD:
+    case HTt_MODULE:
+    case HTt_FILE:
+    case HTt_FRAME_PTR:
+      return tmph(CHashGeneric *)->user_data0;
+
+    case -1:            //nobound switch
+    case HTt_TYPES_NUM: //nobound switch
+    default:
+      return 0;
+  }
+}
+
+CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL)
+{//New hash table, power-of-two in size.
+  CHashTable *table;
+  table=CAlloc(sizeof(CHashTable),mem_task);
+  table->body=CAlloc(size<<3,mem_task);
+  table->mask=size-1;
+  return table;
+}
+
+U0 HashDel(CHashSrcSym *tmph)
+{//Free a std TempleOS system hash entry.
+  if (!tmph) return;
+  if (!(tmph->type&HTT_DICT_WORD))
+    Free(tmph->str);
+  if (tmph->type & HTG_SRC_SYM) {
+    Free(tmph->src_link);
+    Free(tmph->idx);
+    Free(tmph->import_name);
+    LinkedLstDel(tmph->ie_lst);
+    if (tmph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM))
+      Free(tmph->dbg_info);
+    if (tmph->type & (HTT_FUN | HTT_CLASS))
+//Assumes code not on heap, so doesn't Free.
+    //ClassMemberLstDel() is an import to the Kernel module
+      ClassMemberLstDel(tmph);
+    else if (tmph->type&HTT_DEFINE_STR)
+      Free(tmph(CHashDefineStr *)->data);
+    else if (tmph->type & HTT_GLBL_VAR) {
+      if (!(tmph(CHashGlblVar *)->flags&GVF_ALIAS))
+        Free(tmph(CHashGlblVar *)->data_addr);
+      LinkedLstDel(tmph(CHashGlblVar *)->dim.next);
+      if (tmph(CHashGlblVar *)->fun_ptr)
+        HashDel(tmph(CHashGlblVar *)->fun_ptr
+              -tmph(CHashGlblVar *)->fun_ptr->ptr_stars_cnt);
+    }
+  } else if (tmph->type & HTT_FILE)
+    Free(tmph(CHashGeneric *)->user_data0);
+  Free(tmph);
+}
+
+U0 HashTableDel(CHashTable *table)
+{//Free std system hash table, calling HashDel() on entries.
+  I64 i;
+  CHashSrcSym *tmph,*tmph1;
+  if (!table) return;
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      tmph1=tmph->next;
+      HashDel(tmph);
+      tmph=tmph1;
+    }
+  }
+  Free(table->body);
+  Free(table);
+}
+
+I64 HashTablePurge(CHashTable *table)
+{//Eliminate ExportSysSyms that have been usurped.
+  I64 i,res=0;
+  CHashSrcSym *tmph,*tmph1,*tmph2;
+  if (!table) return 0;
+  PUSHFD
+  CLI    //Precaution
+  for (i=0;i<=table->mask;i++) {
+    tmph=table->body[i];
+    while (tmph) {
+      tmph1=tmph->next; //We delete only older ones
+      if (tmph->type&(HTT_FUN|HTT_GLBL_VAR)) {
+        tmph2=tmph->next; //Older always later in chain
+        while (tmph2) {
+          if ((tmph2->type&HTT_EXPORT_SYS_SYM ||
+                tmph2->type&HTG_TYPE_MASK==HTT_INVALID) &&
+                !StrCmp(tmph2->str,tmph->str)) {
+            if (tmph2->type&HTG_TYPE_MASK==HTT_INVALID)
+              tmph2->type=HTT_KEYWORD;//Won't delete HTT_INVALID
+            HashRemDel(tmph2,table);
+            res++;
+            break;
+          }
+          tmph2=tmph2->next;
+        }
+      }
+      tmph=tmph1;
+    }
+  }
+  POPFD
+  return res;
+}
+
+CHashGeneric *HashGenericAdd(U8 *name,I64 type,
+        I64 u0=0,I64 u1=0,I64 u2=0,CTask *task=NULL)
+{//Add any type to task hash_table, 3 user_data values.
+  if (!task) task=Fs;
+  CHashGeneric *res=CAlloc(sizeof(CHashGeneric),task);
+  res->type=type;
+  res->user_data0=u0;
+  res->user_data1=u1;
+  res->user_data2=u2;
+  res->str=StrNew(name,task);
+  HashAdd(res,task->hash_table);
+  return res;
+}
+
+U0 HashSrcFileSet(CCmpCtrl *cc,CHashSrcSym *h,I64 line_num_offset=0)
+{//Set CHashSrcSym link and help_index by cur cc pos.
+  CLexFile *tmpf=cc->lex_include_stk;
+  I64 line_num=tmpf->line_num+line_num_offset;
+  if (line_num<1) line_num=1;
+  Free(h->src_link);
+  h->src_link=MStrPrint("FL:%s,%d",tmpf->full_name,line_num);
+  if (Bt(&cc->opts,OPTf_KEEP_PRIVATE))
+    h->type|=HTF_PRIVATE;
+  Free(h->idx);
+  if (cc->cur_help_idx && *cc->cur_help_idx)
+    h->idx=StrNew(cc->cur_help_idx);
+  else
+    h->idx=NULL;
+}
+
+CHashGeneric *HashPublic(U8 *st,I64 mask,Bool val=TRUE)
+{//Mark a hash entry as public and HashSrcFileSet().
+  CHashGeneric *res;
+  if (res=HashFind(st,Fs->hash_table,mask)) {
+    if (val)
+      res->type|=HTF_PUBLIC;
+    else
+      res->type&=~HTF_PUBLIC;
+    if (res->type&HTG_SRC_SYM)
+      HashSrcFileSet(Fs->last_cc,res);
+    return res;
+  } else
+    return NULL;
+}
+
+I64 HashLstAdd(U8 *lst,I64 type,CHashTable *table)
+{//Add a list to a hash table.
+  I64 i=0;
+  CHashGeneric *tmph;
+  if (lst) {
+    while (*lst) {
+      if (*lst=='@')
+        lst++;
+      else
+        i++;
+      tmph=CAlloc(sizeof(CHashGeneric));
+      tmph->user_data0=i-1;
+      tmph->str=StrNew(lst);
+      tmph->type=type;
+      HashAdd(tmph,table);
+      while (*lst++);
+    }
+  }
+  return i;
+}
+
+I64 HashDefineLstAdd(U8 *dname,I64 type,CHashTable *table)
+{//Add define list to a hash table. See ::/Adam/DolDoc/DocInit.HC.
+  CHashDefineStr *tmph;
+  if (tmph=HashFind(dname,Fs->hash_table,HTT_DEFINE_STR))
+    return HashLstAdd(tmph->data,type,table);
+  else
+    return 0;
+}
+
+I64 FramePtr(U8 *name,CTask *task=NULL)
+{//Find entry in task->hash_table, Return user_data.
+  CHashGeneric *tmph;
+  if (!task) task=Fs;
+  if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR))
+    return tmph->user_data0;
+  else
+    return 0;
+}
+
+CHashGeneric *FramePtrAdd(U8 *name,I64 val=0,CTask *task=NULL)
+{//Add named value to task->hash_table.
+  return HashGenericAdd(name,HTT_FRAME_PTR,val,0,0,task);
+}
+
+I64 FramePtrSet(U8 *name,I64 val,CTask *task=NULL)
+{//Find hash entry in task->hash_table. Change user_data0.
+  CHashGeneric *tmph;
+  if (!task) task=Fs;
+  if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR))
+    return LXchgI64(&tmph->user_data0,val);
+  else
+    return 0;
+}
+
+I64 FramePtrDel(U8 *name,CTask *task=NULL)
+{//Remove entry and delete.
+  CHashGeneric *tmph;
+  I64 res=0;
+  if (!task) task=Fs;
+  if (tmph=HashFind(name,task->hash_table,HTT_FRAME_PTR)) {
+    res=tmph->user_data0;
+    HashRemDel(tmph,task->hash_table);
+  }
+  return res;
+}
+
+ diff --git a/public/Wb/Kernel/KInts.HC.HTML b/public/Wb/Kernel/KInts.HC.HTML new file mode 100755 index 0000000..cf58e18 --- /dev/null +++ b/public/Wb/Kernel/KInts.HC.HTML @@ -0,0 +1,246 @@ + + + + + + + + + + + +
+asm {
+INT_MP_CRASH_ADDR:: //Forward reference to work around compiler
+        DU32    &IntMPCrash;
+
+INT_WAKE::
+        PUSH    RDX
+        PUSH    RAX
+        MOV     EAX,&dev
+        MOV     EDX,U32 LAPIC_EOI
+        MOV     RAX,U64 CDevGlbls.uncached_alias[RAX]
+        MOV     U32 [RAX+RDX],0
+        POP     RAX
+        POP     RDX
+        IRET
+
+IRQ_TIMER::  //I_TIMER
+        CALL    TASK_CONTEXT_SAVE
+        CLD
+
+        MOV     RAX,U64 [RSP]
+        MOV     U64 CTask.rip[RSI],RAX
+        MOV     RAX,U64 16[RSP]
+        MOV     U64 CTask.rflags[RSI],RAX
+        MOV     RAX,U64 24[RSP]
+        MOV     U64 CTask.rsp[RSI],RAX
+
+        XOR     RAX,RAX
+        MOV     RDI,U64 GS:CCPU.addr[RAX]
+        LOCK
+        INC     U64 CCPU.total_jiffies[RDI]
+
+        BT      U64 CTask.task_flags[RSI],TASKf_IDLE
+        JNC     @@05
+        LOCK
+        INC     U64 CCPU.idle_pt_hits[RDI]
+
+@@05:   MOV     RAX,U64 CCPU.profiler_timer_irq[RDI]
+        TEST    RAX,RAX
+        JZ      @@10
+        PUSH    RSI
+        CALL    RAX     //See ProfTimerInt().
+        JMP     @@15
+@@10:   ADD     RSP,8
+@@15:   CLI
+        MOV     RAX,U64 CCPU.num[RDI]
+        TEST    RAX,RAX
+        JZ      @@20
+
+        MOV     EAX,&dev
+        MOV     EDX,U32 LAPIC_EOI
+        MOV     RAX,U64 CDevGlbls.uncached_alias[RAX]
+        MOV     U32 [RAX+RDX],0
+        JMP     @@25
+
+@@20:   CALL    &IntCore0TimerHndlr     //Only Core 0 calls this.
+@@25:   XOR     RAX,RAX
+        CMP     RSI,U64 GS:CCPU.idle_task[RAX]
+        JE      I32 RESTORE_SETH_TASK_IF_READY
+        JMP     I32 RESTORE_RSI_TASK
+//************************************
+INT_FAULT::
+        PUSH    RBX
+        PUSH    RAX
+        MOV     BL,U8 16[RSP]   //We pushed fault_num IntFaultHndlrsNew().
+        XOR     RAX,RAX
+        MOV     FS:U8 CTask.fault_num[RAX],BL
+        POP     RAX
+        POP     RBX
+        ADD     RSP,8           //Pop fault_num
+
+        CALL    TASK_CONTEXT_SAVE
+
+        XOR     RDX,RDX
+        MOV     U64 CTask.fault_err_code[RSI],RDX
+        MOV     EDX,U32 CTask.fault_num[RSI]
+        BT      U64 [INT_FAULT_ERR_CODE_BITMAP],RDX
+        JNC     @@1
+        POP     U64 CTask.fault_err_code[RSI]
+
+@@1:    MOV     RAX,U64 [RSP]
+        MOV     U64 CTask.rip[RSI],RAX
+        MOV     RAX,U64 16[RSP]
+        MOV     U64 CTask.rflags[RSI],RAX
+        MOV     RSP,U64 24[RSP]
+        MOV     U64 CTask.rsp[RSI],RSP
+        MOV     RBP,CTask.rbp[RSI]
+        PUSH    U64 CTask.fault_err_code[RSI]
+        PUSH    U64 CTask.fault_num[RSI]
+        MOV     RSI,CTask.rsi[RSI]
+        CALL    &Fault2         //See Fault2
+        JMP     I32 RESTORE_FS_TASK
+
+INT_FAULT_ERR_CODE_BITMAP::
+        DU32    0x00027D00,0,0,0,0,0,0,0;
+}
+
+U8 *IntEntryGet(I64 irq)
+{//Get interrupt vector.
+  U8 *res;
+  I64 *src;
+  src=dev.idt(U8 *)+irq*16;
+  res(I64).u16[0]=*src(U16 *);
+  src(U8 *)+=6;
+  res(I64).u16[1]=*src(U16 *)++;
+  res(I64).u32[1]=*src(U32 *);
+  return res;
+}
+
+U8 *IntEntrySet(I64 irq,U0 (*fp_new_hndlr)(),I64 type=IDTET_IRQ,I64 dpl=0)
+{//Set interrupt vector. See IDTET_IRQ.
+//See ::/Demo/Lectures/InterruptDemo.HC.
+  //See ::/Demo/MultiCore/Interrupts.HC.
+  I64 fp=fp_new_hndlr;
+  U8 *res,*dst;
+  PUSHFD
+  CLI
+  res=IntEntryGet(irq);
+  dst=dev.idt(U8 *)+irq*16;
+  *dst(U16 *)++=fp.u16[0];
+  *dst(U16 *)++=offset(CGDT.cs64);
+  *dst(U16 *)++=0x8000+type<<8+dpl<<13;
+  *dst(U16 *)++=fp.u16[1];
+  *dst(U32 *)++=fp.u32[1];
+  *dst(U32 *)=0;
+  POPFD
+  return res;
+}
+
+U0 IntsInit()
+{//Init 8259
+  OutU8(0x20,0x11); //IW1
+  OutU8(0xA0,0x11); //IW1
+  OutU8(0x21,0x20); //IW2
+  OutU8(0xA1,0x28); //IW2
+  OutU8(0x21,0x04); //IW3
+  OutU8(0xA1,0x02); //IW3
+  OutU8(0x21,0x0D); //IW4
+  OutU8(0xA1,0x09); //IW4
+  OutU8(0x21,0xFA); //Mask all but IRQ0 (timer) and IRQ2 Cascade.
+  OutU8(0xA1,0xFF);
+}
+
+interrupt U0 IntNop()
+{//Make unplanned IRQs stop by all means!
+  OutU8(0xA0,0x20);
+  OutU8(0x20,0x20);
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+}
+
+interrupt U0 IntDivZero()
+{
+  if (Gs->num) {
+    mp_cnt=1;
+    dbg.mp_crash->cpu_num=Gs->num;
+    dbg.mp_crash->task=Fs;
+    MOV RAX,U64 8[RBP] //Get RIP off of stk.
+    dbg.mp_crash->rip=GetRAX;
+    dbg.mp_crash->msg="Div Zero";
+    dbg.mp_crash->msg_num=0;
+    MPInt(I_MP_CRASH,0);
+    SysHlt;
+  }
+  throw('DivZero');
+}
+
+U8 *IntFaultHndlrsNew()
+{
+  I64 i;
+  U8 *res=MAlloc(256*7,Fs->code_heap),*dst=res;
+  for (i=0;i<256;i++) {
+    *dst++=0x6A; //PUSH I8 xx
+    *dst(I8 *)++=i;
+    *dst++=0xE9; //JMP  I32 xxxxxxxx
+    *dst(I32 *)=INT_FAULT-dst-4;
+    dst+=4;
+  }
+  return res;
+}
+
+U0 IntInit1()
+{//Interrupt descriptor table part1.
+  I64 i;
+  CSysLimitBase tmp_ptr;
+  if (!Gs->num) {//Gs cur CCPU struct
+    dev.idt=CAlloc(16*256);
+    for (i=0;i<256;i++)
+      IntEntrySet(i,&IntNop);
+  }
+  tmp_ptr.limit=256*16-1;
+  tmp_ptr.base =dev.idt;
+  SetRAX(&tmp_ptr);
+  LIDT U64 [RAX]
+}
+
+U0 IntInit2()
+{//Interrupt descriptor table part2: Core 0 Only.
+  I64 i;
+  PUSHFD
+  CLI
+  IntEntrySet(I_DIV_ZERO,&IntDivZero);
+  for (i=1;i<0x20;i++)
+    IntEntrySet(i,&dbg.int_fault_code[7*i]);
+/*In theory, we use the PIC mask reg to insure we don't get
+anything but keyboard, mouse and timer IRQs.  In practice, I've
+gotten IRQ 0x27, perhaps because I didn't initialize the APIC.
+I go ahead and ACK PIC in IntNop().
+I have no idea why I got a IRQ 0x27.
+*/
+  IntEntrySet(I_NMI,_SYS_HLT);
+  IntEntrySet(I_TIMER,IRQ_TIMER);
+  IntEntrySet(I_MP_CRASH,*INT_MP_CRASH_ADDR(U32 *));
+  IntEntrySet(I_WAKE,INT_WAKE);
+  IntEntrySet(I_DBG,&dbg.int_fault_code[7*I_DBG]);
+  POPFD
+}
+
+ diff --git a/public/Wb/Kernel/KLoad.HC.HTML b/public/Wb/Kernel/KLoad.HC.HTML new file mode 100755 index 0000000..4556ffd --- /dev/null +++ b/public/Wb/Kernel/KLoad.HC.HTML @@ -0,0 +1,281 @@ + + + + + + + + + + + +
+U0 LoadOneImport(U8 **_src,U8 *module_base,I64 ld_flags)
+{
+  U8 *src=*_src,*ptr2,*st_ptr;
+  I64 i,etype;
+  CHashExport *tmpex=NULL;
+  CHashImport *tmpiss;
+  Bool first=TRUE;
+
+  while (etype=*src++) {
+    i=*src(U32 *)++;
+    st_ptr=src;
+    src+=StrLen(st_ptr)+1;
+    if (*st_ptr) {
+      if (!first) {
+        *_src=st_ptr-5;
+        return;
+      } else {
+        first=FALSE;
+        if (!(tmpex=HashFind(st_ptr,
+              Fs->hash_table,HTG_ALL-HTT_IMPORT_SYS_SYM))) {
+          if (!(ld_flags & LDF_SILENT))
+            "Unresolved Reference:%s\n",st_ptr;
+          tmpiss=CAlloc(sizeof(CHashImport));
+          tmpiss->str=StrNew(st_ptr);
+          tmpiss->type=HTT_IMPORT_SYS_SYM;
+          tmpiss->module_header_entry=st_ptr-5;
+          tmpiss->module_base=module_base;
+          HashAdd(tmpiss,Fs->hash_table);
+        }
+      }
+    }
+    if (tmpex) {
+      ptr2=module_base+i;
+      if (tmpex->type & HTT_FUN)
+        i=tmpex(CHashFun *)->exe_addr;
+      else if (tmpex->type & HTT_GLBL_VAR)
+        i=tmpex(CHashGlblVar *)->data_addr;
+      else
+        i=tmpex->val;
+      switch (etype) {
+        case IET_REL_I8:  *ptr2(U8 *) =i-ptr2-1; break;
+        case IET_IMM_U8:  *ptr2(U8 *) =i;  break;
+        case IET_REL_I16: *ptr2(U16 *)=i-ptr2-2; break;
+        case IET_IMM_U16: *ptr2(U16 *)=i; break;
+        case IET_REL_I32: *ptr2(U32 *)=i-ptr2-4; break;
+        case IET_IMM_U32: *ptr2(U32 *)=i; break;
+        case IET_REL_I64: *ptr2(I64 *)=i-ptr2-8; break;
+        case IET_IMM_I64: *ptr2(I64 *)=i; break;
+      }
+    }
+  }
+  *_src=src-1;
+}
+
+U0 SysSymImportsResolve(U8 *st_ptr,I64 ld_flags)
+{
+  CHashImport *tmpiss;
+  U8 *ptr;
+  while (tmpiss=HashSingleTableFind(st_ptr,
+        Fs->hash_table,HTT_IMPORT_SYS_SYM)) {
+    ptr=tmpiss->module_header_entry;
+    LoadOneImport(&ptr,tmpiss->module_base,ld_flags);
+    tmpiss->type=HTT_INVALID;
+  }
+}
+
+U0 LoadPass1(U8 *src,U8 *module_base,I64 ld_flags)
+{
+  U8 *ptr2,*ptr3,*st_ptr;
+  I64 i,j,cnt,etype;
+  CHashExport *tmpex=NULL;
+  while (etype=*src++) {
+    i=*src(U32 *)++;
+    st_ptr=src;
+    src+=StrLen(st_ptr)+1;
+    switch (etype) {
+      case IET_REL32_EXPORT:
+      case IET_IMM32_EXPORT:
+      case IET_REL64_EXPORT:
+      case IET_IMM64_EXPORT:
+        tmpex=CAlloc(sizeof(CHashExport));
+        tmpex->str=StrNew(st_ptr);
+        tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+        if (etype==IET_IMM32_EXPORT||etype==IET_IMM64_EXPORT)
+          tmpex->val=i;
+        else
+          tmpex->val=i+module_base;
+        HashAdd(tmpex,Fs->hash_table);
+        SysSymImportsResolve(st_ptr,ld_flags);
+        break;
+      case IET_REL_I0...IET_IMM_I64:
+        src=st_ptr-5;
+        LoadOneImport(&src,module_base,ld_flags);
+        break;
+      case IET_ABS_ADDR:
+        if (ld_flags & LDF_NO_ABSS)
+          src+=i*sizeof(U32);
+        else {
+          cnt=i;
+          for (j=0;j<cnt;j++) {
+            ptr2=module_base+*src(U32 *)++;
+            *ptr2(U32 *)+=module_base;
+          }
+        }
+        break;
+
+      start:
+        case IET_CODE_HEAP:
+          ptr3=MAlloc(*src(I32 *)++,Fs->code_heap);
+          break;
+        case IET_ZEROED_CODE_HEAP:
+          ptr3=CAlloc(*src(I32 *)++,Fs->code_heap);
+          break;
+      end:
+        if (*st_ptr) {
+          tmpex=CAlloc(sizeof(CHashExport));
+          tmpex->str=StrNew(st_ptr);
+          tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+          tmpex->val=ptr3;
+          HashAdd(tmpex,Fs->hash_table);
+        }
+        cnt=i;
+        for (j=0;j<cnt;j++) {
+          ptr2=module_base+*src(U32 *)++;
+          *ptr2(I32 *)+=ptr3;
+        }
+        break;
+
+      start:
+        case IET_DATA_HEAP:
+          ptr3=MAlloc(*src(I64 *)++);
+          break;
+        case IET_ZEROED_DATA_HEAP:
+          ptr3=CAlloc(*src(I64 *)++);
+          break;
+      end:
+        if (*st_ptr) {
+          tmpex=CAlloc(sizeof(CHashExport));
+          tmpex->str=StrNew(st_ptr);
+          tmpex->type=HTT_EXPORT_SYS_SYM|HTF_IMM;
+          tmpex->val=ptr3;
+          HashAdd(tmpex,Fs->hash_table);
+        }
+        cnt=i;
+        for (j=0;j<cnt;j++) {
+          ptr2=module_base+*src(U32 *)++;
+          *ptr2(I64 *)+=ptr3;
+        }
+        break;
+    }
+  }
+}
+
+U0 LoadPass2(U8 *src,U8 *module_base,I64)
+{
+  U8 *st_ptr;
+  I64 i,etype;
+  while (etype=*src++) {
+    i=*src(U32 *)++;
+    st_ptr=src;
+    src+=StrLen(st_ptr)+1;
+    switch (etype) {
+      case IET_MAIN:
+        Call(i+module_base);
+        break;
+      case IET_ABS_ADDR:
+        src+=sizeof(U32)*i;
+        break;
+      case IET_CODE_HEAP:
+      case IET_ZEROED_CODE_HEAP:
+        src+=4+sizeof(U32)*i;
+        break;
+      case IET_DATA_HEAP:
+      case IET_ZEROED_DATA_HEAP:
+        src+=8+sizeof(U32)*i;
+        break;
+    }
+  }
+}
+
+CBinFile *Load(U8 *filename,I64 ld_flags=0,CBinFile *bfh_addr=INVALID_PTR)
+{//Load a .BIN file module into memory.
+//bfh_addr==INVALID_PTR means don't care what load addr.
+  U8 *fbuf,*module_base,*absname;
+  I64 size,module_align,misalignment;
+  CBinFile *bfh;
+
+  fbuf=ExtDft(filename,"BIN.Z");
+  if (!(bfh=FileRead(fbuf,&size))) {
+    Free(fbuf);
+    return NULL;
+  }
+
+  //See Patch Table Generation
+  module_align=1<<bfh->module_align_bits;
+  if (!module_align || bfh->bin_signature!=BIN_SIGNATURE_VAL) {
+    Free(bfh);
+    Free(fbuf);
+    throw('BinModul');
+  }
+
+  if (bfh_addr==INVALID_PTR) {
+    if (bfh->org==INVALID_PTR) {
+      misalignment=module_align-sizeof(CBinFile);
+      if (misalignment<0)
+        misalignment&=module_align-1;
+      if (Fs->code_heap!=Fs->data_heap) {
+        if (module_align<16)
+          module_align=16;
+        bfh_addr=MAllocAligned(size,module_align,Fs->code_heap,misalignment);
+      } else if (module_align>8)
+        bfh_addr=MAllocAligned(size,module_align,,misalignment);
+      else {//Less than 2Gig system memory
+        bfh_addr=bfh;
+        goto lo_skip; //File is already in code heap area, don't copy.
+      }
+    } else
+      bfh_addr=bfh->org;
+  }
+  MemCpy(bfh_addr,bfh,size);
+  Free(bfh);
+
+  lo_skip:
+  module_base=bfh_addr(U8 *)+sizeof(CBinFile);
+
+  absname=FileNameAbs(fbuf);
+  Free(fbuf);
+  fbuf=StrNew(absname);
+  FileExtRem(fbuf);
+  if (fbuf[1]==':' && StrLen(fbuf)>2)
+    HashGenericAdd(fbuf+2,HTT_MODULE|HTF_PUBLIC,bfh_addr);
+  LoadPass1(bfh_addr(U8 *)+bfh_addr->patch_table_offset,module_base,ld_flags);
+  if (!(ld_flags&LDF_JUST_LOAD))
+    LoadPass2(bfh_addr(U8 *)+bfh_addr->patch_table_offset,module_base,ld_flags);
+  Free(absname);
+  Free(fbuf);
+  return bfh_addr;
+}
+
+U0 LoadKernel()
+{
+  HashGenericAdd(KERNEL_MODULE_NAME,HTT_MODULE|HTF_PUBLIC,
+        mem_boot_base-sizeof(CBinFile));
+
+  //Abs patches done here CPatchTableAbsAddr.
+  LoadPass1(sys_boot_patch_table_base,mem_boot_base,LDF_NO_ABSS|LDF_SILENT);
+
+  //No main routines
+  //  LoadPass2(sys_boot_patch_table_base,mem_boot_base,0);
+}
+
+ diff --git a/public/Wb/Kernel/KMain.HC.HTML b/public/Wb/Kernel/KMain.HC.HTML new file mode 100755 index 0000000..dae91cf --- /dev/null +++ b/public/Wb/Kernel/KMain.HC.HTML @@ -0,0 +1,269 @@ + + + + + + + + + + + +
+U0 SysGlblsInit()
+{
+  I64 i,j;
+  CRAXRBCRCXRDX ee;
+
+  CPUId(0x1,&ee);
+  sys_cache_line_width=ee.rbx.u8[1]*8;
+
+  sys_focus_task=Fs;
+  QueInit(&sys_macro_head);
+
+  blkdev.dft_iso_filename       =AStrNew(DFT_ISO_FILENAME);
+  blkdev.dft_iso_c_filename     =AStrNew(DFT_ISO_C_FILENAME);
+  blkdev.tmp_filename           =AStrNew("~/Tmp.DD.Z");
+  blkdev.dvd_boot_is_good=TRUE;
+  #exe {
+    if (!kernel_cfg->mount_ide_auto_hd_let)
+      kernel_cfg->mount_ide_auto_hd_let='C';
+    if (!kernel_cfg->mount_ide_auto_cd_let)
+      kernel_cfg->mount_ide_auto_cd_let='T';
+    StreamPrint("blkdev.first_hd_drv_let=%d;",
+          kernel_cfg->mount_ide_auto_hd_let);
+    StreamPrint("blkdev.first_dvd_drv_let=%d;",
+          kernel_cfg->mount_ide_auto_cd_let);
+  }
+
+  DbgMode(ON);
+  rev_bits_table=CAlloc(256);
+  set_bits_table=CAlloc(256);
+  for (i=0;i<256;i++)
+    for (j=0;j<8;j++) {
+      if (Bt(&i,7-j))   LBts(rev_bits_table+i,j);
+      if (Bt(&i,j))     set_bits_table[i]++;
+    }
+
+  ext=CAlloc(EXT_EXTS_NUM*sizeof(U8 *));
+  fp_getstr2=&SysGetStr2;
+  KeyDevInit;
+
+  #exe {
+    StreamPrint("blkdev.boot_drv_let='%C';",kernel_cfg->boot_drv_let);
+    StreamPrint("#exe{Option(OPTf_WARN_PAREN,OFF);}");
+    StreamPrint("DskCacheInit(%s);",kernel_cfg->dsk_cache_size_exp);
+    StreamPrint("#exe{Option(OPTf_WARN_PAREN,ON);}");
+  };
+
+  pow10_I64=CAlloc(sizeof(F64)*(308+308+1));
+  for (i=-308;i<309;i++)
+    pow10_I64[i+309]=Pow10(i);
+
+  QueInit(&scrncast.snd_head);
+  scrncast.t0_now=Now;
+  scrncast.t0_tS=tS;
+  scrncast.ona=scrncast.snd_head.ona=0;
+
+  ProgressBarsRst;
+
+  QueInit(&dev.pci_head);
+  dev.mem64_ptr=mem_mapped_space;
+
+  dbg.fun_seg_cache=CAlloc(FUN_SEG_CACHE_SIZE*sizeof(CFunSegCache));
+  dbg.int_fault_code=IntFaultHndlrsNew;
+}
+
+U0 SysGrInit()
+{
+  text.font=sys_font_std;
+  text.aux_font=sys_font_cyrillic;
+  text.vga_alias        =dev.uncached_alias+VGAM_GRAPHICS;
+  text.vga_text_alias   =dev.uncached_alias+VGAM_TEXT;
+  if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
+    text.cols=80;
+    text.rows=25;
+    MemSet(text.vga_text_alias,0,text.rows*text.cols<<1);
+    text.border_chars[2] (I64)='........';
+    text.border_chars[10](U32)='....';
+  } else { //if 640x480 16 color
+    text.cols=GR_WIDTH/FONT_WIDTH;
+    text.rows=GR_HEIGHT/FONT_HEIGHT;
+    OutU8(VGAP_IDX,VGAR_MAP_MASK);
+    OutU8(VGAP_DATA,0x0F);
+    MemSet(text.vga_alias,0,GR_WIDTH*GR_HEIGHT>>3);
+    text.raw_scrn_image=CAlloc(GR_WIDTH*GR_HEIGHT/8);
+    text.border_chars[2] (I64)=0x0908070605040302;
+    text.border_chars[10](U32)=0x0D0C0B0A;
+  }
+}
+
+U0 TimersInit()
+{
+  I64 i,*_q;
+  U32 *_d;
+
+  OutU8(0x43,0x34);
+  OutU8(0x40,SYS_TIMER0_PERIOD);
+  OutU8(0x40,SYS_TIMER0_PERIOD>>8);
+
+  //High Precision Event Timer
+  if (PCIReadU16(0,31,0,0)==0x8086) {//Intel?
+//D31 F0, cfg 0xF0=RCBA of PCI-LPC Bridge
+    _d=PCIReadU32(0,31,0,0xF0)(U8 *)&~0x3FFF+0x3404; //HPET cfg
+//7     enable
+    //1:0 HPET is at 0xFED00000,0xFED01000, 0xFED02000 or 0xFED03000.
+    *_d=*_d&3|0x80;
+  }
+
+  _q=dev.uncached_alias+HPET_GCAP_ID;
+  i=*_q; //i.u32[1]= period in femtoS (10e-15)
+  if (100000<i.u32[1]<1000000000) {
+    cnts.HPET_freq    =1000000000000000/i.u32[1];
+    cnts.HPET_kHz_freq=1000000000000/i.u32[1];
+    _q=dev.uncached_alias+HPET_GEN_CONF;
+    *_q|=1; //Enable counting
+    cnts.HPET_initial=HPET;
+  } else {
+    cnts.HPET_freq=0;
+    cnts.HPET_kHz_freq=0;
+    cnts.HPET_initial=0;
+  }
+}
+
+U0 Reboot()
+{//Hardware reset.
+  CLI
+  if (mp_cnt>1)
+    MPHalt;
+  *0x472(U16 *)=0;
+  OutU8(0x70,0x8F);
+  OutU8(0x71,0x00);
+  OutU8(0x70,0x00);
+  OutU8(0x92,InU8(0x92)|1);
+  SysHlt;
+}
+
+U0 KMain()
+{//Continued from KStart64.HC
+  CBlkDev *bd;
+  OutU8(0x61,InU8(0x61)&~3); //Snd;
+  adam_task=Fs;
+  BlkPoolsInit;
+  SysGlblsInit;
+  Mem32DevInit;
+  UncachedAliasAlloc;
+  LoadKernel;
+  SysGrInit;
+  StrCpy(Fs->task_name,"Adam Task CPU00");
+  StrCpy(Fs->task_title,Fs->task_name);
+  Fs->title_src=TTS_TASK_NAME;
+  Fs->win_right=text.cols-2;
+  Fs->win_top++;
+  TaskDerivedValsUpdate;
+
+  SysDefinesLoad;
+  Core0Init;
+  IntInit1;
+
+  //Before this point use Snd() and Busy()
+  //to debug.  After this point, use RawPrint()
+  LBts(&sys_run_level,RLf_RAW);
+  "TempleOS V%5.3f\t%D %T\n\n",
+        sys_os_version,sys_compile_time,sys_compile_time;
+
+  TimersInit;
+  if (BIOSTotalMem<ToI64(0.95*MEM_MIN_MEG*0x100000))
+    RawPrint(4000,"!!! Requires 512Meg of RAM Memory !!!");
+
+  IntsInit;
+  "Enable IRQ's\n";
+  SetRFlags(RFLAGG_NORMAL);
+  Busy(2000);
+  IntInit2;
+  LBts(&sys_run_level,RLf_INTERRUPTS);
+
+  TimeCal;
+  BlkDevsInitAll;
+  "DskChg(':');\n";
+  DskChg(':');
+  #exe {
+    StreamPrint("HomeSet(\"%s\");\n"
+          "blkdev.ins_base0=%d;blkdev.ins_base1=%d;blkdev.ins_unit =%d;\n",
+          kernel_cfg->home_dir,
+          blkdev.ins_base0,blkdev.ins_base1,blkdev.ins_unit);
+  }
+  Gs->idle_task->cur_dv=blkdev.let_to_drv[*blkdev.home_dir-'A'];
+  DrvRep;
+  if (blkdev.dvd_boot_is_good) {
+    bd=Let2BlkDev(':');
+    if (bd->type==BDT_ATAPI) {
+      blkdev.ins_base0=bd->base0;
+      blkdev.ins_base1=bd->base1;
+      blkdev.ins_unit =bd->unit;
+    }
+  }
+  LBts(&sys_run_level,RLf_BLKDEV);
+
+  #exe {
+    if (!kernel_cfg->opts[CFG_NO_MP])
+      StreamPrint("\"MultiCore Start\\n\\n\";"
+            "Core0StartMP;"
+            "LBts(&sys_run_level,RLf_MP);");
+  };
+
+  KbdMsInit;
+  MsInit;
+  KbdInit;
+  Spawn(&MsHardDrvrInstall);
+
+  "Loading Compiler\n";
+  Cd("/Compiler");
+  Load("Compiler",LDF_SILENT);
+  LBts(&sys_run_level,RLf_COMPILER);
+
+  DbgMode(OFF);
+  cnts.time_stamp_freq_initial=TimeCal;
+  Cd("/");
+  try ExeFile("StartOS"); //Continues /StartOS.HC
+  catch {
+    Raw(ON);
+    Silent(OFF);
+    GetOutOfDollar;
+    PutExcept;
+    Dbg;
+  }
+
+  LBts(&sys_run_level,RLf_ADAM_SERVER);
+  SrvTaskCont; //Never to return
+}
+
+asm {   ALIGN   16,OC_NOP
+SYS_KERNEL_END::
+#exe {
+  if (kernel_cfg->opts[CFG_DBG_DISTRO])
+    StreamPrint("DU8 0x%X-(SYS_KERNEL_END-SYS_KERNEL+"
+        "BOOT_RAM_BASE+sizeof(CBinFile)) DUP (0);"
+        "BINFILE \"%s\";",kernel_cfg->dbg_distro_start,
+                          kernel_cfg->dbg_distro_file);
+};
+}
+
+ diff --git a/public/Wb/Kernel/KMathA.HC.HTML b/public/Wb/Kernel/KMathA.HC.HTML new file mode 100755 index 0000000..beac510 --- /dev/null +++ b/public/Wb/Kernel/KMathA.HC.HTML @@ -0,0 +1,679 @@ + + + + + + + + + + + +
+asm {
+//************************************
+_D3_NORM::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        FLD     U64 [RDX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSQRT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_D3_NORM_SQR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        FLD     U64 [RDX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_D3_DIST::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RDX]
+        FSUB    ST0,U64 [RBX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FSUB    ST0,U64 8[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FSUB    ST0,U64 16[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSQRT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_DIST_SQR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RDX]
+        FSUB    ST0,U64 [RBX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RDX]
+        FSUB    ST0,U64 8[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FSUB    ST0,U64 16[RBX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_CROSS::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+
+        FLD     U64 8[RDX]
+        FMUL    ST0,U64 16[RBX]
+        FLD     U64 16[RDX]
+        FMUL    ST0,U64 8[RBX]
+        FSUBP   ST1,ST0
+        FSTP    U64 [RAX]
+
+        FLD     U64 [RDX]
+        FMUL    ST0,U64 16[RBX]
+        FLD     U64 16[RDX]
+        FMUL    ST0,U64 [RBX]
+        FSUBRP  ST1,ST0
+        FSTP    U64 8[RAX]
+
+        FLD     U64 [RDX]
+        FMUL    ST0,U64 8[RBX]
+        FLD     U64 8[RDX]
+        FMUL    ST0,U64 [RBX]
+        FSUBP   ST1,ST0
+        FSTP    U64 16[RAX]
+
+        POP     RBP
+        RET1    24
+//************************************
+_D3_DOT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RDX]
+        FMUL    ST0,U64 [RBX]
+        FLD     U64 8[RDX]
+        FMUL    ST0,U64 8[RBX]
+        FADDP   ST1,ST0
+        FLD     U64 16[RDX]
+        FMUL    ST0,U64 16[RBX]
+        FADDP   ST1,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_ADD::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        FLD     U64 [RDX]
+        FADD    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RDX]
+        FADD    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RDX]
+        FADD    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_SUB::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        FLD     U64 [RDX]
+        FSUB    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RDX]
+        FSUB    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RDX]
+        FSUB    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_MUL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG3[RBP]
+        FLD     U64 SF_ARG2[RBP]
+        FLD     ST0
+        FMUL    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FMUL    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FMUL    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_DIV::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 SF_ARG3[RBP]
+        FLD     ST0
+        FDIVR   ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FDIVR   ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FDIVR   ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    24
+//************************************
+_D3_ZERO::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        XOR     RDX,RDX
+        MOV     U64 [RAX],RDX
+        MOV     U64 8[RAX],RDX
+        MOV     U64 16[RAX],RDX
+        POP     RBP
+        RET1    8
+//************************************
+_D3_COPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 [RBX]
+        MOV     U64 [RAX],RDX
+        MOV     RDX,U64 8[RBX]
+        MOV     U64 8[RAX],RDX
+        MOV     RDX,U64 16[RBX]
+        MOV     U64 16[RAX],RDX
+        POP     RBP
+        RET1    16
+//************************************
+_D3_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG2[RBP]
+        MOV     U64 [RAX],RDX
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     U64 8[RAX],RDX
+        MOV     RDX,U64 SF_ARG4[RBP]
+        MOV     U64 16[RAX],RDX
+        POP     RBP
+        RET1    32
+//************************************
+_D3_ADD_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RAX]
+        FADD    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RAX]
+        FADD    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RAX]
+        FADD    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_SUB_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RBX,U64 SF_ARG2[RBP]
+        FLD     U64 [RAX]
+        FSUB    ST0,U64 [RBX]
+        FSTP    U64 [RAX]
+        FLD     U64 8[RAX]
+        FSUB    ST0,U64 8[RBX]
+        FSTP    U64 8[RAX]
+        FLD     U64 16[RAX]
+        FSUB    ST0,U64 16[RBX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_MUL_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        FLD     U64 SF_ARG2[RBP]
+        FLD     ST0
+        FMUL    ST0,U64 [RAX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FMUL    ST0,U64 8[RAX]
+        FSTP    U64 8[RAX]
+        FMUL    ST0,U64 16[RAX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_DIV_EQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        FLD     U64 SF_ARG2[RBP]
+        FLD     ST0
+        FDIVR   ST0,U64 [RAX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FDIVR   ST0,U64 8[RAX]
+        FSTP    U64 8[RAX]
+        FDIVR   ST0,U64 16[RAX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    16
+//************************************
+_D3_UNIT::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        FLD     U64 [RAX]
+        FMUL    ST0,ST0
+        FLD     U64 8[RAX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FLD     U64 16[RAX]
+        FMUL    ST0,ST0
+        FADDP   ST1,ST0
+        FSQRT
+        FST     U64 SF_ARG1[RBP]
+        MOV     RBX,SF_ARG1[RBP]
+        TEST    RBX,RBX
+        JZ      @@05
+        FLD     ST0
+        FDIVR   ST0,U64 [RAX]
+        FSTP    U64 [RAX]
+        FLD     ST0
+        FDIVR   ST0,U64 8[RAX]
+        FSTP    U64 8[RAX]
+        FDIVR   ST0,U64 16[RAX]
+        FSTP    U64 16[RAX]
+        POP     RBP
+        RET1    8
+@@05:   FFREE   ST0
+        FINCSTP
+        POP     RBP
+        RET1    8
+//************************************
+_SQR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD     U64 SF_ARG1[RBP]
+        FMUL    ST0,ST0
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_SIGN::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD     U64 SF_ARG1[RBP]
+        FTST
+        FSTSW
+        FFREE   ST0
+        FINCSTP
+        MOV     RDX,RAX
+        XOR     RAX,RAX
+        BT      RDX,14
+        JC      @@05
+        MOV     RAX,1.0
+        BT      RDX,8
+        JNC     @@05
+        MOV     RAX,-1.0
+@@05:   POP     RBP
+        RET1    8
+//************************************
+_ARG::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD     U64 SF_ARG2[RBP]
+        FLD     U64 SF_ARG1[RBP]
+@@05:   FPATAN
+        FSTSW
+        TEST    AX,0x400
+        JNZ     @@05
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    16
+//************************************
+_ROUND::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        AND     AX,~0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_TRUNC::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_FLOOR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        AND     AX,~0x0C00
+        OR      AX,0x0400
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_CEIL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        AND     AX,~0x0C00
+        OR      AX,0x0800
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLD     U64 SF_ARG1[RBP]
+        FRNDINT
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,SF_ARG1[RBP]
+
+        FLDCW   U16 -6[RBP]
+        LEAVE
+        RET1    8
+//************************************
+SYS_POW::
+// RAX=RDX`RAX
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,24
+        TEST    RAX,RAX //To power of zero?
+        JNZ     @@05
+        MOV     RAX,1.0
+        JMP     @@20
+@@05:   TEST    RDX,RDX //zero to a power?
+        JNZ     @@10
+        XOR     RAX,RAX
+        JMP     @@20
+@@10:   MOV     RCX,RAX //RCX=pow
+        MOV     U64 -8[RBP],RDX
+        MOV     U64 -16[RBP],RAX
+        FSTCW   U16 -24[RBP]
+        MOV     AX,U16 -24[RBP]
+        MOV     U16 -22[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -24[RBP],AX
+        FLDCW   U16 -24[RBP]
+        FLD     U64 -16[RBP]
+        FLD     U64 -8[RBP]
+        FABS    //base should be pos
+        FYL2X   // y*log2(x)
+        FST     U64 -8[RBP]
+        FRNDINT
+        FLD     U64 -8[RBP]
+        FSUBRP  ST1,ST0
+        F2XM1
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 -16[RBP]
+        FLD     U64 -8[RBP]
+        FLD     U64 -16[RBP]
+        FSCALE  // ST0<<ST1
+        TEST    RDX,RDX //was base neg?
+        JGE     @@15
+        MOV     U64 -16[RBP],RCX
+        FLD     U64 -16[RBP]
+        FISTTP  U64 -16[RBP]
+        TEST    U64 -16[RBP],1
+        JZ      @@15    //was pow odd?
+        FCHS
+@@15:   FSTP    U64 -8[RBP]
+        FFREE   ST0
+        FINCSTP
+        FLDCW   U16 -22[RBP]
+        MOV     RAX,U64 -8[RBP]
+@@20:   LEAVE
+        RET
+//************************************
+_POW::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 SF_ARG1[RBP]
+        CALL    SYS_POW
+        POP     RBP
+        RET1    16
+//************************************
+_POW10::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,16
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLDL2T
+        FLD     U64 SF_ARG1[RBP]
+        FMULP   ST1,ST0
+        FST     U64 SF_ARG1[RBP]
+        FRNDINT
+        FLD     U64 SF_ARG1[RBP]
+        FSUBRP  ST1,ST0
+        F2XM1
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 -16[RBP]
+        FLD     U64 SF_ARG1[RBP]
+        FLD     U64 -16[RBP]
+        FSCALE  // ST0<<ST1
+        FSTP    U64 -16[RBP]
+        FFREE   ST0
+        FINCSTP
+
+        FLDCW   U16 -6[RBP]
+        MOV     RAX,U64 -16[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_EXP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,16
+        FSTCW   U16 -8[RBP]
+        MOV     AX,U16 -8[RBP]
+        MOV     U16 -6[RBP],AX
+        OR      AX,0x0C00
+        MOV     U16 -8[RBP],AX
+        FLDCW   U16 -8[RBP]
+
+        FLDL2E
+        FLD     U64 SF_ARG1[RBP]
+        FMULP   ST1,ST0
+        FST     U64 SF_ARG1[RBP]
+        FRNDINT
+        FLD     U64 SF_ARG1[RBP]
+        FSUBRP  ST1,ST0
+        F2XM1
+        FLD1
+        FADDP   ST1,ST0
+        FSTP    U64 -16[RBP]
+        FLD     U64 SF_ARG1[RBP]
+        FLD     U64 -16[RBP]
+        FSCALE  // ST0<<ST1
+        FSTP    U64 -16[RBP]
+        FFREE   ST0
+        FINCSTP
+
+        FLDCW   U16 -6[RBP]
+        MOV     RAX,U64 -16[RBP]
+        LEAVE
+        RET1    8
+//************************************
+_LOG10::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLDLG2
+        FLD     U64 SF_ARG1[RBP]
+        FYL2X   // y*log2(x)
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_LOG2::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLD1
+        FLD     U64 SF_ARG1[RBP]
+        FYL2X   // y*log2(x)
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_LN::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLDLN2
+        FLD     U64 SF_ARG1[RBP]
+        FYL2X   // y*log2(x)
+        FSTP    U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_FLDCW::
+        PUSH    RBP
+        MOV     RBP,RSP
+        FLDCW   U16 SF_ARG1[RBP]
+        POP     RBP
+        RET1    8
+//************************************
+_FSTCW::
+        PUSH    RBP
+        MOV     RBP,RSP
+        SUB     RSP,8
+        FSTCW   U16 -8[RBP]
+        MOVZX   RAX,U16 -8[RBP]
+        LEAVE
+        RET
+//************************************
+_FSTSW::
+        XOR     RAX,RAX
+        FSTSW
+        RET
+//************************************
+_FCLEX::
+        FCLEX
+        RET
+}
+
+ diff --git a/public/Wb/Kernel/KMathB.HC.HTML b/public/Wb/Kernel/KMathB.HC.HTML new file mode 100755 index 0000000..f387217 --- /dev/null +++ b/public/Wb/Kernel/KMathB.HC.HTML @@ -0,0 +1,188 @@ + + + + + + + + + + + +
+F64 Clamp(F64 d,F64 lo,F64 hi)
+{//Clamp to F64 [] range.
+  if (d<lo)
+    return lo;
+  if (d>hi)
+    return hi;
+  return d;
+}
+
+F64 Min(F64 n1,F64 n2)
+{//Min of two F64s.
+  if (n1<=n2)
+    return n1;
+  else
+    return n2;
+}
+
+F64 Max(F64 n1,F64 n2)
+{//Max of two F64s.
+  if (n1>=n2)
+    return n1;
+  else
+    return n2;
+}
+
+F64 Pow10I64(I64 i)
+{//F64 int powers of ten.
+  if (i>308)
+    return inf;
+  else if (i<-308)
+    return 0.0;
+  else
+    return pow10_I64[i+309];
+}
+
+U64 FloorU64(U64 num,U64 to)
+{//Int multiples of num.
+  return num-num%to;
+}
+
+U64 CeilU64(U64 num,U64 to)
+{//Int multiples of num.
+  num+=to-1;
+  return num-num%to;
+}
+
+I64 RoundI64(I64 num,I64 to)
+{//Int multiples of num.
+  return num-num%to;
+}
+
+I64 FloorI64(I64 num,I64 to)
+{//Int multiples of num.
+  if (num>=0)
+    return num-num%to;
+  else {
+    num++;
+    return num-num%to-to;
+  }
+}
+
+I64 CeilI64(I64 num,I64 to)
+{//Int multiples of num.
+  if (num>=0) {
+    num+=to-1;
+    return num-num%to;
+  } else {
+    num+=to-1;
+    return num-num%to-to;
+  }
+}
+
+//See ::/Doc/Credits.DD.
+#define LIN_CONGRUE_A   6364136223846793005
+#define LIN_CONGRUE_C   1442695040888963407
+
+I16 RandI16()
+{//Random I16.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.i16[0];
+}
+
+U16 RandU16()
+{//Random U16.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.u16[0];
+}
+
+I32 RandI32()
+{//Random I32.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.i32[0];
+}
+
+U32 RandU32()
+{//Random U32.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res.u32[0];
+}
+
+I64 RandI64()
+{//Random I64.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res;
+}
+
+U64 RandU64()
+{//Random U64.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return res;
+}
+
+F64 Rand()
+{//Random F64.
+  I64 res=Fs->rand_seed;
+  res=LIN_CONGRUE_A*res^(res&0xFFFFFFFF0000)>>16+LIN_CONGRUE_C;
+  if (!Bt(&Fs->task_flags,TASKf_NONTIMER_RAND))
+    res^=GetTSC;
+  Fs->rand_seed=res;
+  return (res&0x3FFFFFFFFFFFFFFF)/ToF64(0x4000000000000000);
+}
+
+I64 Seed(I64 seed=0,CTask *task=NULL)
+{//Set Rand() seed. Zero for timer-based.
+  if (!task) task=Fs;
+  if (seed) {
+    LBts(&task->task_flags,TASKf_NONTIMER_RAND);
+    return task->rand_seed=seed;
+  } else {
+    LBtr(&task->task_flags,TASKf_NONTIMER_RAND);
+    return task->rand_seed^=GetTSC;
+  }
+}
+
+ diff --git a/public/Wb/Kernel/KMisc.HC.HTML b/public/Wb/Kernel/KMisc.HC.HTML new file mode 100755 index 0000000..b8d4ded --- /dev/null +++ b/public/Wb/Kernel/KMisc.HC.HTML @@ -0,0 +1,357 @@ + + + + + + + + + + + +
+U0 PortNop()
+{//Innoculous (reads IRQ Mask) which should take fixed time
+//because it's an ISA-bus standard.  It takes 1.0uS-2.0uS.
+  InU8(0x21);
+}
+
+U16 EndianU16(U16 d)
+{//Swap big<-->little endian.
+  I64 res=0;
+  res.u8[1]=d.u8[0];
+  res.u8[0]=d.u8[1];
+  return res;
+}
+
+U32 EndianU32(U32 d)
+{//Swap big<-->little endian.
+  I64 res=0;
+  res.u8[3]=d.u8[0];
+  res.u8[2]=d.u8[1];
+  res.u8[1]=d.u8[2];
+  res.u8[0]=d.u8[3];
+  return res;
+}
+
+I64 EndianI64(I64 d)
+{//Swap big<-->little endian.
+  U64 res;
+  res.u8[7]=d.u8[0];
+  res.u8[6]=d.u8[1];
+  res.u8[5]=d.u8[2];
+  res.u8[4]=d.u8[3];
+  res.u8[3]=d.u8[4];
+  res.u8[2]=d.u8[5];
+  res.u8[1]=d.u8[6];
+  res.u8[0]=d.u8[7];
+  return res;
+}
+
+I64 BCnt(I64 d)
+{//Count set bits in I64.
+  I64 res=0,i;
+  for (i=0;i<8;i++)
+    res+=set_bits_table[d.u8[i]];
+  return res;
+}
+
+U0 IntCore0TimerHndlr(CTask *)
+{//Called from IntCore0TimerHndlr
+  I64 i;
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_SYS_TIMER],0))
+      PAUSE
+  lock cnts.jiffies++;
+  cnts.timer+=SYS_TIMER0_PERIOD+1;
+  LBtr(&sys_semas[SEMA_SYS_TIMER],0);
+  for (i=1;i<mp_cnt;i++)
+    MPInt(I_TIMER,i);
+  OutU8(0x20,0x20); //Acknowledge PIC Interrupt
+}
+
+I64 SysTimerRead()
+{//System timer count with overflow already handled.
+  I64 i,res;
+  PUSHFD
+  CLI
+  if (mp_cnt>1)
+    while (LBts(&sys_semas[SEMA_SYS_TIMER],0))
+      PAUSE
+  OutU8(0x43,0); //Latch Timer0
+  if ((i=InU8(0x40)+InU8(0x40)<<8)==SYS_TIMER0_PERIOD) {
+    if (InU8(0x20) & 1)
+      i=-1;
+  }
+  res=cnts.timer+SYS_TIMER0_PERIOD-i;
+  LBtr(&sys_semas[SEMA_SYS_TIMER],0);
+  POPFD
+  return res;
+}
+
+I64 HPET()
+{ //Get high precision event timer.
+  return *(dev.uncached_alias+HPET_MAIN_CNT)(I64 *);
+}
+
+I64 TimeCal()
+{
+  static I64 time_stamp_start=0,timer_start=0,HPET_start=0;
+  I64 i;
+  if (time_stamp_start) {
+    PUSHFD
+    CLI
+    if (HPET_start) {
+      cnts.time_stamp_freq=cnts.HPET_freq*(GetTSC-time_stamp_start);
+      i=HPET-HPET_start;
+    } else {
+      cnts.time_stamp_freq=SYS_TIMER_FREQ*(GetTSC-time_stamp_start);
+      i=SysTimerRead-timer_start;
+    }
+    if (!i)
+      AdamErr("Timer Cal Error");
+    else {
+      cnts.time_stamp_freq/=i;
+      cnts.time_stamp_kHz_freq=cnts.time_stamp_freq/1000;
+      cnts.time_stamp_calibrated=TRUE;
+    }
+    POPFD
+  }
+  PUSHFD
+  CLI
+  if (cnts.HPET_freq) {
+    timer_start=0;
+    HPET_start=HPET;
+  } else {
+    timer_start=SysTimerRead;
+    HPET_start=0;
+  }
+  time_stamp_start=GetTSC;
+  POPFD
+  return cnts.time_stamp_freq;
+}
+
+F64 tS()
+{//Time since boot in seconds as a float.
+  if (cnts.HPET_freq)
+    return ToF64(HPET-cnts.HPET_initial)/cnts.HPET_freq;
+  else
+    return SysTimerRead/ToF64(SYS_TIMER_FREQ);
+}
+
+Bool Blink(F64 Hz=2.5)
+{//Return TRUE, then FALSE, then TRUE at given frequency.
+  if (!Hz) return 0;
+  return ToI64(cnts.jiffies*2*Hz/JIFFY_FREQ)&1;
+}
+
+U0 Busy(I64 uS)
+{//Loosely timed.
+  I64 i;
+  if (cnts.HPET_freq) {
+    i=HPET+cnts.HPET_freq*uS/1000000;
+    while (HPET<i);
+  } else
+    for (i=0;i<uS;i++)
+      PortNop;
+}
+
+U0 SleepUntil(I64 wake_jiffy)
+{//Not for power-saving.  It is to make a program pause without hogging the CPU.
+  Bool old_idle=LBts(&Fs->task_flags,TASKf_IDLE);
+  Fs->wake_jiffy=wake_jiffy;
+  Yield;
+  LBEqu(&Fs->task_flags,TASKf_IDLE,old_idle);
+}
+
+U0 Sleep(I64 mS)
+{//Not for power-saving.  It is to make a program pause without hogging the CPU.
+  if (!mS)
+    Yield;
+  else
+    SleepUntil(cnts.jiffies+mS*JIFFY_FREQ/1000);
+}
+
+F64 Ona2Freq(I8 ona)
+{//Ona to freq. Ona=60 is 440.0Hz.
+  if (!ona)
+    return 0;
+  else
+    return 440.0/32*2.0`(ona/12.0);
+}
+
+I8 Freq2Ona(F64 freq)
+{//Freq to Ona. 440.0Hz is Ona=60.
+  if (freq>0)
+    return ClampI64(12*Log2(32.0/440.0*freq),1,I8_MAX);
+  else
+    return 0;
+}
+
+U0 Snd(I8 ona=0)
+{//Play ona, a piano key num. 0 means rest.
+  I64 period;
+  CSndData *d;
+  if (!Bt(&sys_semas[SEMA_MUTE],0) &&
+        !LBts(&sys_semas[SEMA_SND],0)) { //Mutex. Just throw-out if in use
+    if (!ona) {
+      scrncast.ona=ona;
+      OutU8(0x61,InU8(0x61)&~3);
+    } else if (ona!=scrncast.ona) {
+      scrncast.ona=ona;
+      period=ClampI64(SYS_TIMER_FREQ/Ona2Freq(ona),1,U16_MAX);
+      OutU8(0x43,0xB6);
+      OutU8(0x42,period);
+      OutU8(0x42,period.u8[1]);
+      OutU8(0x61,3|InU8(0x61));
+    }
+    if (!IsDbgMode && scrncast.record) {
+      d=ACAlloc(sizeof(CSndData));
+      d->ona=ona;
+      d->tS=tS;
+      QueIns(d,scrncast.snd_head.last);
+    }
+    LBtr(&sys_semas[SEMA_SND],0);
+  }
+}
+
+Bool ScrnCast(Bool val=ON,Bool just_audio=FALSE,U8 *print_fmt="B:/Tmp/%X.GR")
+{//WinMgr saves GR files to a dir.
+  Bool old_val;
+  scrncast.just_audio=just_audio;
+  if (val) {
+    if (!(old_val=LBtr(&scrncast.record,0))) {
+      Free(scrncast.print_fmt);
+      scrncast.print_fmt=AStrNew(print_fmt);
+      scrncast.t0_now=Now;
+      scrncast.snd_head.tS=scrncast.t0_tS=tS;
+      scrncast.snd_head.ona=scrncast.ona;
+      LBts(&scrncast.record,0);
+    }
+  } else
+    old_val=LBtr(&scrncast.record,0);
+  Snd;
+  return old_val;
+}
+
+U0 SndRst()
+{//Fix stuck sound.
+  if (Bt(&sys_semas[SEMA_SND],0)) {
+    Sleep(1);
+    if (Bt(&sys_semas[SEMA_SND],0)) {
+      Sleep(1);
+      LBtr(&sys_semas[SEMA_SND],0);
+    }
+  }
+  Snd;
+}
+
+U0 Beep(I8 ona=62,Bool busy=FALSE)
+{//Make beep at given ona freq.
+  Snd(ona);
+  if (busy)
+    Busy(500000);
+  else
+    Sleep(500);
+  Snd;
+  if (busy)
+    Busy(200000);
+  else
+    Sleep(200);
+}
+
+Bool Mute(Bool val)
+{//Turn-off sound.
+  Bool res;
+  if (val) {
+    PUSHFD
+    CLI
+    Snd;
+    res=LBts(&sys_semas[SEMA_MUTE],0);
+    POPFD
+  } else
+    res=LBtr(&sys_semas[SEMA_MUTE],0);
+  return res;
+}
+
+Bool IsMute()
+{//Return is-mute flag.
+  return Bt(&sys_semas[SEMA_MUTE],0);
+}
+
+Bool Silent(Bool val=ON)
+{//Turn-off StdOut console text. (Not sound.)
+  return LBEqu(&Fs->display_flags,DISPLAYf_SILENT,val);
+}
+
+Bool IsSilent()
+{//Return StdOut turned-off?
+  return Bt(&Fs->display_flags,DISPLAYf_SILENT);
+}
+
+Bool SysDbg(Bool val)
+{//Set SysDbg bit you can use while debugging.
+  return LBEqu(&sys_semas[SEMA_DEBUG],0,val);
+}
+
+Bool IsSysDbg()
+{//Return SysDbg bit.
+  return Bt(&sys_semas[SEMA_DEBUG],0);
+}
+
+Bool Raw(Bool val)
+{//Set to direct scrn, BLACK & WHITE, non-windowed output mode.
+  if (!val)
+    VGAFlush;
+  return !LBEqu(&Fs->display_flags,DISPLAYf_NOT_RAW,!val);
+}
+
+Bool IsRaw()
+{//Are we in BLACK & WHITE raw scrn mode?
+  return !Bt(&Fs->display_flags,DISPLAYf_NOT_RAW);
+}
+
+Bool SingleUser(Bool val)
+{//Set single-user mode.
+  return LBEqu(&sys_semas[SEMA_SINGLE_USER],0,val);
+}
+
+Bool IsSingleUser()
+{//Return single-user mode.
+  return Bt(&sys_semas[SEMA_SINGLE_USER],0);
+}
+
+Bool DbgMode(Bool val)
+{//Set dbg-mode.
+  return LBEqu(&sys_semas[SEMA_DBG_MODE],0,val);
+}
+
+Bool IsDbgMode()
+{//Return dbg-mode.
+  return Bt(&sys_semas[SEMA_DBG_MODE],0);
+}
+
+U0 ProgressBarsRst(U8 *path=NULL)
+{//Reset all progress bars to zero.
+  CallExtStr("ProgressBarsRegTf",path);
+  MemSet(sys_progresses,0,sizeof(sys_progresses));
+}
+
+ diff --git a/public/Wb/Kernel/KStart16.HC.HTML b/public/Wb/Kernel/KStart16.HC.HTML new file mode 100755 index 0000000..7ade1da --- /dev/null +++ b/public/Wb/Kernel/KStart16.HC.HTML @@ -0,0 +1,237 @@ + + + + + + + + + + + +
+asm {/* See ::/Doc/Boot.DD.
+TempleOS starts in real, calls some BIOS
+routines, switches to 32 bit, and 64 bit mode
+and continues in HolyC at KMain().
+
+The boot loader jumps here in real-mode (16-bit).
+It actually jumps to the CBinFile header which is
+placed just before this by the compiler.
+The header begins with a short jmp to
+the start of this file's code which begins
+with the following small jump past some data.
+
+This file is first in the Kernel image
+because it is #included first.  Kernel.PRJ
+*/
+USE16
+SYS_KERNEL:: //This must match CKernel.
+        JMP     I16 CORE0_16BIT_INIT
+
+//************************************
+//  ASM Global vars required for 16-bit start-up
+        ALIGN   4,OC_NOP
+SYS_BOOT_SRC::                  DU32    BOOT_SRC_NULL;
+SYS_BOOT_BLK::                  DU32    0;
+SYS_BOOT_PATCH_TABLE_BASE::     DU32    0;
+SYS_RUN_LEVEL::                 DU32    0;
+#exe {StreamPrint("SYS_COMPILE_TIME:: DU64 0x%X;",Now);} //See BootDVDProbe
+#assert SYS_COMPILE_TIME+sizeof(CDate)+sizeof(CBinFile)<DVD_BLK_SIZE
+
+MEM_BOOT_BASE::         DU32    0;      //Offset from start used by reboot
+MEM_E801::              DU16    0,0;
+MEM_E820::              DU8     MEM_E820_ENTRIES_NUM*sizeof(CMemE820) DUP (0);
+MEM_PHYSICAL_SPACE::    DU64    0;
+SYS_GDT_PTR::           DU16    sizeof(CGDT)-1;
+                        DU64    0;
+SYS_PCI_BUSES::         DU16    0;
+
+        ALIGN   16,OC_NOP
+SYS_GDT:: //See CGDT
+GDT_NULL:       DU64    0,0;
+GDT_BOOT_DS:    DU64    0x00CF92000000FFFF,0; //Gets patched.
+GDT_BOOT_CS:    DU64    0x00CF9A000000FFFF,0; //Gets patched.
+GDT_CS32:       DU64    0x00CF9A000000FFFF,0;
+GDT_CS64:       DU64    0x00209A0000000000,0; //The Charter says just ring0.
+GDT_CS64_RING3: DU64    0x0020FA0000000000,0; //Ring3, so you can play with.
+GDT_DS:         DU64    0x00CF92000000FFFF,0;
+GDT_DS_RING3:   DU64    0x00CFF2000000FFFF,0;
+GDT_TR:         DU8     MP_PROCESSORS_NUM*16 DUP(0);
+GDT_TR_RING3:   DU8     MP_PROCESSORS_NUM*16 DUP(0);
+#assert $-SYS_GDT==sizeof(CGDT)
+
+#assert $-SYS_KERNEL==sizeof(CKernel)-sizeof(CBinFile)
+
+//************************************
+CORE0_16BIT_INIT::
+//EAX is SYS_BOOT_SRC. (Val passed from boot blk, BootHD, BootDVD, & BootRAM.)
+        MOV     ECX,EAX
+        MOV     AX,(BOOT_RAM_LIMIT-BOOT_STK_SIZE)/16
+        MOV     SS,AX
+        MOV     SP,BOOT_STK_SIZE
+        PUSH    ECX     //Will be SYS_BOOT_SRC. See BootHD, BootDVD & BootRAM.
+        PUSH    EBX
+
+        CALL    U16 GET_RIP
+GET_RIP:        POP     BX
+        SUB     BX,GET_RIP
+        SHR     BX,4
+        MOV     AX,CS
+        ADD     AX,BX
+        PUSH    AX
+        PUSH    U16 @@05
+        RETF
+
+@@05:   STI
+        MOV     AX,CS
+        MOV     DS,AX
+
+        MOV     U32 [SYS_RUN_LEVEL],RLF_16BIT
+
+        MOV     AX,0x4F02
+        MOV     BX,0x12         //640x480 16 color
+#exe {
+  if (!kernel_cfg->opts[CFG_TEXT_MODE])
+    StreamPrint("INT 0x10");    //Enable VGA
+};
+        CMP     AX,0x004F
+        JNE     @@10            //Jmp if fail
+        BTS     U32 [SYS_RUN_LEVEL],RLf_VGA
+@@10:
+
+//Get mem maps.
+        MOV     AX,0xE801
+        INT     0x15
+        MOV     U16 [MEM_E801],CX
+        MOV     U16 [MEM_E801+2],DX
+
+        MOV     CX,MEM_E820_ENTRIES_NUM-1 //Leave one to terminate
+        XOR     EBX,EBX
+        MOV     AX,DS
+        MOV     ES,AX
+        MOV     DI,MEM_E820
+@@15:   PUSH    CX
+        MOV     EAX,0xE820
+        MOV     ECX,sizeof(CMemE820)
+        MOV     EDX,'PAMS'
+        INT     0x15
+        JC      @@20
+        CMP     EAX,'PAMS'
+        JNE     @@20
+        TEST    EBX,EBX
+        JZ      @@20
+        ADD     DI,sizeof(CMemE820)
+        POP     CX
+        LOOP    @@15
+        SUB     SP,2
+@@20:   ADD     SP,2
+
+//Find how much space to map, start with E801 limit.
+        XOR     EAX,EAX
+        MOV     AX,[MEM_E801+2]
+        SHL     EAX,16
+        ADD     EAX,SYS_16MEG_AREA_LIMIT
+        XOR     EDX,EDX
+
+//Find max of E820 to set mapped space.
+        MOV     SI,MEM_E820
+@@25:   MOV     CL,CMemE820.type[SI]
+        TEST    CL,CL
+        JZ      @@35
+        MOV     EBX,CMemE820.base[SI]
+        MOV     ECX,CMemE820.base+4[SI]
+        ADD     EBX,CMemE820.len[SI]
+        ADC     ECX,CMemE820.len+4[SI]
+        SUB     EBX,EAX
+        SBB     ECX,EDX
+        JC      @@30
+        MOV     EAX,CMemE820.base[SI]
+        MOV     EDX,CMemE820.base+4[SI]
+        ADD     EAX,CMemE820.len[SI]
+        ADC     EDX,CMemE820.len+4[SI]
+@@30:   ADD     SI,sizeof(CMemE820)
+        JMP     @@25
+
+@@35:   MOV     [MEM_PHYSICAL_SPACE],EAX
+        MOV     [MEM_PHYSICAL_SPACE+4],EDX
+        
+//Get PCI Bus Info
+        MOV     U16 [SYS_PCI_BUSES],256
+        XOR     DX,DX
+        MOV     AX,0xB101
+        INT     0x1A
+        CMP     DX,'PC'
+        JNE     @@40
+        MOV     CH,0
+        INC     CX
+        MOV     U16 [SYS_PCI_BUSES],CX
+@@40:
+        CLI
+//Enable A20
+        IN      AL,0x92
+        OR      AL,2
+        OUT     0x92,AL
+
+        POP     U32 [SYS_BOOT_BLK]
+        POP     U32 [SYS_BOOT_SRC]      //See BootHD, BootDVD, & BootRAM.
+
+        CLD
+        XOR     EAX,EAX
+        MOV     AX,CS
+        MOV     DS,AX
+        MOV     ES,AX
+        SHL     EAX,4
+
+        MOV     U32 [MEM_BOOT_BASE],EAX
+
+        MOV     DX,CS
+        SUB     DX,sizeof(CBinFile)/16
+#assert !(sizeof(CBinFile)&15)
+        MOV     GS,DX
+
+        MOV     EDX,EAX
+        ADD     EDX,U32 GS:[CBinFile.patch_table_offset]
+        SUB     EDX,sizeof(CBinFile)
+        MOV     U32 [SYS_BOOT_PATCH_TABLE_BASE],EDX
+
+        ADD     U32 [GDT_BOOT_DS+2],EAX
+        ADD     U32 [GDT_BOOT_CS+2],EAX
+        ADD     EAX,I32 SYS_GDT
+        MOV     U32 [SYS_GDT_PTR+CSysLimitBase.base],EAX
+        LGDT    U32 [SYS_GDT_PTR]
+
+        MOV     EAX,SYS_START_CR0
+        MOV_CR0_EAX
+
+/* The assembler doesn't support far jumps so
+we hand code it.  16-bit code is not important
+enough to fully implement in the assembler.
+
+To complete the switch to 32-bit mode, we have to load
+the code segment with a far jump.
+*/
+        DU8     0x66,0xEA; //JMP CGDT.boot_cs:CORE0_32BIT_INIT
+        DU32    CORE0_32BIT_INIT;
+        DU16    CGDT.boot_cs;
+#assert $+16<=0xFFFF
+}
+
+ diff --git a/public/Wb/Kernel/KStart32.HC.HTML b/public/Wb/Kernel/KStart32.HC.HTML new file mode 100755 index 0000000..8eef388 --- /dev/null +++ b/public/Wb/Kernel/KStart32.HC.HTML @@ -0,0 +1,148 @@ + + + + + + + + + + + +
+asm {
+USE32
+//************************************
+//  ASM Global vars not required for 16-bit start-up
+        ALIGN   8,OC_NOP
+MEM_HEAP_BASE::         DU64    0;
+MEM_HEAP_LIMIT::        DU64    0;
+MEM_PAGE_SIZE::         DU64    0;
+MEM_MAPPED_SPACE::      DU64    0;
+MEM_2MEG_NUM::          DU64    0;
+MEM_1GIG_NUM::          DU64    0;
+MEM_512GIG_NUM::        DU64    0;
+MEM_PML2::              DU64    0;
+MEM_PML3::              DU64    0;
+MEM_PML4::              DU64    0;
+
+#exe {
+  StreamPrint(
+"SYS_MEM_INIT_FLAG::    DU8     %d;"
+"SYS_MEM_INIT_VAL::     DU8     %d;"
+"SYS_HEAP_INIT_FLAG::   DU8     %d;"
+"SYS_HEAP_INIT_VAL::    DU8     %d;"
+"SYS_VAR_INIT_FLAG::    DU8     %d;"
+"SYS_VAR_INIT_VAL::     DU8     %d;"
+"SYS_STAFF_MODE_FLAG::  DU8     %d;",
+kernel_cfg->opts[CFG_MEM_INIT], kernel_cfg->mem_init_val,
+kernel_cfg->opts[CFG_HEAP_INIT],kernel_cfg->heap_init_val,
+kernel_cfg->opts[CFG_VAR_INIT], kernel_cfg->var_init_val,
+kernel_cfg->opts[CFG_STAFF_MODE]);
+};
+SYS_HEAP_DBG_FLAG::     DU8     _CFG_HEAP_DBG;
+
+        ALIGN   8,0
+SYS_CTRL_ALT_FLAGS::    DU64    0;
+SYS_EXTERN_TABLE::      DU64    0;
+
+SYS_CODE_BP::           DU64    0;
+SYS_DATA_BP::           DU64    0;
+
+SYS_PROGRESSES::
+SYS_PROGRESS1::         DU64    0;
+SYS_PROGRESS1_MAX::     DU64    0;
+SYS_PROGRESS1_T0::      DU64    0;
+SYS_PROGRESS1_TF::      DU64    0;
+SYS_PROGRESS1_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+SYS_PROGRESS2::         DU64    0;
+SYS_PROGRESS2_MAX::     DU64    0;
+SYS_PROGRESS2_T0::      DU64    0;
+SYS_PROGRESS2_TF::      DU64    0;
+SYS_PROGRESS2_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+SYS_PROGRESS3::         DU64    0;
+SYS_PROGRESS3_MAX::     DU64    0;
+SYS_PROGRESS3_T0::      DU64    0;
+SYS_PROGRESS3_TF::      DU64    0;
+SYS_PROGRESS3_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+SYS_PROGRESS4::         DU64    0;
+SYS_PROGRESS4_MAX::     DU64    0;
+SYS_PROGRESS4_T0::      DU64    0;
+SYS_PROGRESS4_TF::      DU64    0;
+SYS_PROGRESS4_DESC::    DU8     PROGRESS_DESC_LEN DUP(0);
+#assert $-SYS_PROGRESSES==sizeof(CProgress)*4
+
+SYS_FOCUS_TASK::        DU64    0;
+SYS_CPU_STRUCTS::       DU64    0;
+SYS_MP_CNT::            DU64    1;
+SYS_MP_CNT_INITIAL::    DU64    1;
+SYS_MP_CNT_LOCK::       DU64    1;
+
+        ALIGN   DFT_CACHE_LINE_WIDTH,OC_NOP
+SYS_CACHE_LINE_WIDTH::  DU64    DFT_CACHE_LINE_WIDTH;
+        DU8     DFT_CACHE_LINE_WIDTH-sizeof(CBinFile)-8 DUP(0);
+SYS_SEMAS::             DU8     SEMA_SEMAS_NUM*DFT_CACHE_LINE_WIDTH DUP(0);
+//************************************
+        ALIGN   16,OC_NOP
+CORE0_32BIT_INIT:: //Entry point for BootRAM.
+        PUSH    U32 RFLAGG_START
+        POPFD
+        MOV     EAX,SYS_START_CR0
+        MOV_CR0_EAX
+
+        MOV     AX,CGDT.boot_ds //LOAD DS SELECTOR
+        MOV     DS,AX
+        BTS     U32 [SYS_RUN_LEVEL],RLf_32BIT
+        MOV     ESI,U32 [SYS_BOOT_PATCH_TABLE_BASE]
+        MOV     EDI,U32 [MEM_BOOT_BASE]
+
+        MOV     AX,CGDT.ds
+        MOV     DS,AX
+        MOV     ES,AX
+        MOV     FS,AX
+        MOV     GS,AX
+        MOV     SS,AX
+        MOV     ESP,BOOT_RAM_LIMIT //Tmp Stk
+
+//Patch abs addresses
+        MOV     ECX,U32 CPatchTableAbsAddr.abs_addres_cnt[ESI]
+        LEA     ESI,U32 CPatchTableAbsAddr.abs_addres[ESI]
+@@05:   LODSD
+        ADD     EAX,EDI
+        ADD     U32 [EAX],EDI
+        LOOP    @@05
+
+        DU8     0xEA; //JMP CGDT.cs32:@@10
+        DU32    @@10;
+        DU16    CGDT.cs32;
+
+@@10:   BTS     U32 [SYS_RUN_LEVEL],RLf_PATCHED
+
+        CALL    SYS_FIND_PCIBIOS_SERVICE_DIR
+        CALL    SYS_FIND_PCI_SERVICES
+        CALL    SYS_INIT_PAGE_TABLES
+        CALL    SYS_INIT_16MEG_SYS_CODE_BP
+        PUSH    U32 0   //Return from next call will be 64-bit
+        CALL    SYS_ENTER_LONG_MODE
+
+        //We fall-thou to KStart64, next.
+}
+
+ diff --git a/public/Wb/Kernel/KStart64.HC.HTML b/public/Wb/Kernel/KStart64.HC.HTML new file mode 100755 index 0000000..831d2a2 --- /dev/null +++ b/public/Wb/Kernel/KStart64.HC.HTML @@ -0,0 +1,131 @@ + + + + + + + + + + + +
+asm {
+USE64
+        BTS     U32 [SYS_RUN_LEVEL],RLf_64BIT
+
+        FNINIT
+        MOV     RAX,SYS_FIXED_AREA+CSysFixedArea.init_fpu_mmx
+        FXSAVE  U64 [RAX]
+
+//Init CPU0 Struct
+        PUSH    SYS_FIXED_AREA+CSysFixedArea.adam
+        PUSH    SYS_FIXED_AREA+CSysFixedArea.boot_cpu
+        PUSH    0
+        CALL    &CPUStructInit
+        CALL    SET_GS_BASE
+
+//Init Adam HeapCtrl
+        MOV     EDI,U32 SYS_FIXED_AREA+CSysFixedArea.adam_hc
+        MOV     EAX,U32 SYS_FIXED_AREA+CSysFixedArea.sys_code_bp
+        MOV     U64 CHeapCtrl.bp[RDI],RAX
+        MOV     U32 CHeapCtrl.hc_signature[RDI],HEAP_CTRL_SIGNATURE_VAL
+        
+        LEA     RAX,U64 CHeapCtrl.next_um-CMemUsed.next[RDI]
+        MOV     U64 CHeapCtrl.next_um[RDI],RAX
+        MOV     U64 CHeapCtrl.last_um[RDI],RAX
+
+        MOV     EAX,U32 SYS_FIXED_AREA+CSysFixedArea.adam
+        MOV     U64 CHeapCtrl.mem_task[RDI],RAX
+        MOV     U64 CTask.code_heap[RAX],RDI
+        MOV     U64 CTask.data_heap[RAX],RDI
+        MOV     U32 CTask.task_signature[RAX],TASK_SIGNATURE_VAL
+        
+        BTS     U32 [SYS_RUN_LEVEL],RLf_16MEG_ADAM_HEAP_CTRL
+
+        PUSH    MEM_ADAM_STK
+        PUSH    U32 SYS_FIXED_AREA+CSysFixedArea.adam
+        CALL    &TaskInit
+        CALL    SET_FS_BASE
+        MOV     RSP,U64 CTask.rsp[RAX]
+
+        JMP     I32 &KMain
+
+//************************************
+USE32
+SYS_ENTER_LONG_MODE:: //Switch to long 64-bit mode
+        MOV_EAX_CR4
+        OR      EAX,0xB0
+        MOV_CR4_EAX
+
+        MOV     EAX,[MEM_PML4]
+        MOV_CR3_EAX
+
+        MOV     ECX,IA32_EFER
+        XOR     EDX,EDX
+        MOV     EAX,IA32F_LME
+        WRMSR
+
+        MOV_EAX_CR0
+        BTS     EAX,31  //Enable paging (required for 64-bit mode)
+        MOV_CR0_EAX
+
+        DU8     0xEA;      //JMP CGDT.cs64:@@05
+        DU32    @@05;
+        DU16    CGDT.cs64;
+USE64
+@@05:   MOV     AX,CGDT.ds
+        MOV     DS,AX
+        MOV     ES,AX
+        MOV     SS,AX
+        MOV     FS,AX
+        MOV     GS,AX
+        RET
+
+//************************************
+SYS_RAM_REBOOT:: //This gets copied high.  SYS_RAM_REBOOT
+        PUSH    U32 CGDT.ds             //stk seg
+        PUSH    U32 BOOT_RAM_LIMIT      //stk
+        PUSH    U32 0                   //flags
+        PUSH    U32 CGDT.cs32
+        LEA     RAX,[@@10]
+        PUSH    RAX
+        IRET
+USE32
+@@10:   WBINVD
+
+//Disable paging
+        MOV_EAX_CR0
+        BTR     EAX,31
+        MOV_CR0_EAX
+
+        MOV     ECX,IA32_EFER
+        XOR     EDX,EDX
+        XOR     EAX,EAX
+        WRMSR
+
+        MOV     EBX,BOOT_SRC_RAM
+        MOV     EAX,I32 CORE0_32BIT_INIT
+        JMP     EAX
+SYS_RAM_REBOOT_END::
+USE64
+}
+
+ diff --git a/public/Wb/Kernel/KTask.HC.HTML b/public/Wb/Kernel/KTask.HC.HTML new file mode 100755 index 0000000..a70b231 --- /dev/null +++ b/public/Wb/Kernel/KTask.HC.HTML @@ -0,0 +1,576 @@ + + + + + + + + + + + +
+U0 Exit()
+{//Terminate own task.
+  if (Fs==sys_focus_task && IsDbgMode) {
+    LBts(&Fs->task_flags,TASKf_KILL_AFTER_DBG);
+    G;
+  } else {
+    if (sys_staff_mode_flag)
+      AdamLog("%p:%p:%p:%p:%p:%p\n",Caller(0),Caller(1),Caller(2),Caller(3),
+            Caller(4),Caller(5),Caller(6),Caller(7));
+    if (!Gs->num && !IsDbgMode)
+      SingleUser(OFF);
+    Fs->rflags=GetRFlags;
+    Fs->rsp=GetRSP;
+    Fs->rbp=GetRBP;
+    Fs->rip=$;
+    CLI
+    LBts(&Fs->task_flags,TASKf_KILL_TASK);
+    TaskEndNow;
+  }
+}
+
+Bool TaskValidate(CTask *task)
+{//return TRUE if task looks valid.
+  if (!(0<task<=I32_MAX) || task->addr!=task ||
+        task->task_signature!=TASK_SIGNATURE_VAL)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+I64 BirthWait(CTask **_task,I64 task_num=-1)
+{//Wait for task valid and not task_num.
+  while (!TaskValidate(*_task)||(*_task)->task_num==task_num)
+    Yield;
+  return (*_task)->task_num;
+}
+
+U0 DeathWait(CTask **_task,Bool send_exit=FALSE)
+{//Wait for task death.
+  if (send_exit && TaskValidate(*_task)) {
+    TaskWait(*_task,TRUE);
+    XTalk(*_task,"Exit;\n");
+  }
+  while (TaskValidate(*_task))
+    Yield;
+}
+
+Bool Kill(CTask *task,Bool wait=TRUE,Bool just_break=FALSE)
+{//Terminate other task.
+  I64 i;
+  if (TaskValidate(task)) {
+    if (just_break) {
+      if (task!=Fs)
+        Break;
+      else {//TODO wait
+        sys_focus_task=task;
+        LBts(sys_ctrl_alt_flags,CTRL_ALT_C);
+        return TRUE;
+      }
+    } else {
+      if (task!=sys_winmgr_task) {
+        for (i=0;i<mp_cnt;i++)
+          if (task==cpu_structs[i].seth_task)
+            return FALSE;
+        LBts(&task->task_flags,TASKf_KILL_TASK);
+        if (wait) {
+          do Yield;
+          while (TaskValidate(task) && Bt(&task->task_flags,TASKf_KILL_TASK));
+        }
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
+Bool Suspend(CTask *task=NULL,Bool state=TRUE)
+{//Tell scheduler to skip task.
+  Bool res;
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  if (TaskValidate(task))
+    res=LBEqu(&task->task_flags,TASKf_SUSPENDED,state);
+  else
+    res=FALSE;
+  POPFD
+  return res;
+}
+
+Bool IsSuspended(CTask *task=NULL)
+{//You might use this in a DrawIt() or Animatetask().
+  if (!task) task=Fs;
+  if (TaskValidate(task))
+    return Bt(&task->task_flags,TASKf_SUSPENDED);
+  else
+    return FALSE;
+}
+
+CTaskStk *TaskStkNew(I64 stk_size,CTask *task)
+{
+  CTaskStk *tmps=MAlloc(stk_size+offset(CTaskStk.stk_base),task);
+  tmps->next_stk=NULL;
+  tmps->stk_ptr=NULL;
+  tmps->stk_size=MSize(tmps)-offset(CTaskStk.stk_base);
+  return tmps;
+}
+
+#exe {Option(OPTf_NO_REG_VAR,ON);};
+argpop I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size,
+                        /*argpop*/I64 (*fp_addr)(...),...)
+{//Grow stk in call with any fixed num of args.
+//See ::/Demo/StkGrow.HC.
+  CTaskStk *tmps,*tmps2,**_stk;
+  I64 res,*rsp,*rsp2,*old_stk;
+
+  if (UnusedStk>=stk_size_threshold) {
+
+    asm {
+      LEAVE
+      POP       RAX     //return addr
+      ADD       RSP,16  //pop threshold,stk_size
+      POP       RBX     // *f
+      ADD       RSP,8   //pop ARGC
+      PUSH      RAX
+      JMP       RBX     //CALL fp_addr()
+    };
+
+  } else {
+
+    tmps2=TaskStkNew(stk_size,Fs);
+    tmps2->next_stk=tmps=Fs->stk;
+    rsp2=(&tmps2->stk_base)(U8 *)+tmps2->stk_size;
+    old_stk=rsp=&argv[argc];
+    while (argc-->0)
+      *--rsp2=*--rsp;
+    _stk=&Fs->stk;
+    tmps->stk_ptr=rsp=GetRSP;
+    asm {
+      IMPORT    _FREE;  //We are in a function, not at glbl scope.
+//The compiler treats these in isolation.
+
+      PUSHFD
+      POP       RDX     //flags
+      CLI
+      MOV       RBX,U64 &tmps2[RBP]
+      MOV       RAX,&_stk[RBP]
+      MOV       U64 [RAX],RBX   //Fs->stk=tmps2
+      MOV       RSP,U64 &rsp2[RBP]
+      PUSH      RDX
+      POPFD
+
+      CALL      U64 &fp_addr[RBP]
+      MOV       U64 &res[RBP],RAX
+
+      PUSHFD
+      POP       RDX     //flags
+      CLI
+      MOV       RBX,U64 &tmps[RBP]
+      MOV       RAX,&_stk[RBP]
+      MOV       U64 [RAX],RBX   //Fs->stk=tmps
+      MOV       RSP,U64 &rsp[RBP]
+      PUSH      RDX
+      POPFD
+
+      PUSH      U64 &tmps2[RBP]
+      CALL      _FREE
+
+      MOV       RDX,U64 &old_stk[RBP]
+      MOV       RBX,U64 8[RBP]
+      MOV       RAX,U64 &res[RBP]
+      MOV       RBP,U64 [RBP]
+      MOV       RSP,RDX
+      JMP       RBX     //return
+    };
+  }
+  return 0; //dummy to get rid of warning
+}
+;
+#exe {Option(OPTf_NO_REG_VAR,OFF);};
+
+I64 TaskInit(CTask *task,I64 stk_size)
+{//Returns Fs of task
+  CTaskStk *tmps;
+
+  QueInit(&task->code_heap->next_mem_blk);
+  task->code_heap->last_mergable=NULL;
+  if (task->code_heap!=task->data_heap) {
+    QueInit(&task->data_heap->next_mem_blk);
+    task->data_heap->last_mergable=NULL;
+  }
+
+  task->addr=task->next_task=task->last_task=
+        task->next_input_filter_task=task->last_input_filter_task=
+        task;
+
+  task->task_num=sys_num_spawned_tasks++;
+
+  task->rflags=RFLAGG_NORMAL;
+  task->win_inhibit=WIG_TASK_DFT;
+
+  task->next_child_task=task->last_child_task=
+        (&task->next_child_task)(U8 *)-offset(CTask.next_sibling_task);
+
+  JobCtrlInit(&task->srv_ctrl);
+  QueInit(&task->next_cc);
+  QueInit(&task->next_except);
+  QueInit(&task->next_ctrl);
+  QueInit(&task->next_ode);
+
+  task->fpu_mmx=MAllocAligned(sizeof(CFPU),0x10,task);
+  MemCpy(task->fpu_mmx,
+        SYS_FIXED_AREA+offset(CSysFixedArea.init_fpu_mmx),sizeof(CFPU));
+
+  task->hash_table=HashTableNew(TASK_HASH_TABLE_SIZE,task);
+
+  if (!stk_size)
+    stk_size=MEM_DFT_STK;
+  task->stk=tmps=TaskStkNew(stk_size,task);
+  task->rsp=(&tmps->stk_base)(U8 *)+tmps->stk_size;
+
+  task->text_attr       =WHITE<<4+BLUE;
+  task->border_src      =BDS_CONST;
+  task->border_attr     =DrvTextAttrGet(':');
+  task->title_src       =TTS_CONST;
+  task->win_left        =1;
+  task->win_right       =text.cols-2;
+  task->win_top         =13;
+  task->win_bottom      =text.rows-2;
+
+  if (blkdev.home_dir) {//Beware Adam TaskInit. I guess ok until DskChg().
+    task->cur_dv=blkdev.let_to_drv[*blkdev.home_dir-'A'];
+    task->cur_dir=StrNew(blkdev.home_dir+2,task);
+  } else
+    task->cur_dir=StrNew("/Home",task);
+
+  Seed(,task);
+
+  return task;
+}
+
+CTask *Spawn(U0 (*fp_start_addr)(U8 *data),U8 *data=NULL,U8 *task_name=NULL,
+        I64 target_cpu=-1,      //-1 for current CPU. See multi-core.
+        CTask *parent=NULL,     //NULL means adam
+        I64 stk_size=0,         //0=default
+        I64 flags=1<<JOBf_ADD_TO_QUE)
+{//Create task on core running at address.
+//Alloc CTask structure from code heap so addr will be short.
+  //Could be alloced off of data heap.
+  CTask *task;
+  if (target_cpu>=0)
+    return SpawnQue(fp_start_addr,data,task_name,target_cpu,
+          parent,stk_size,flags);
+  task=CAlloc(sizeof(CTask),adam_task->code_heap);
+  task->task_signature=TASK_SIGNATURE_VAL;
+  if (!task_name) task_name="Unnamed Task";
+  if (!parent) parent=Gs->seth_task;
+  task->parent_task=parent;
+  task->gs=parent->gs;
+  if (sys_code_bp)
+    task->code_heap=HeapCtrlInit(,task,sys_code_bp);
+  if (sys_data_bp)
+    task->data_heap=HeapCtrlInit(,task,sys_data_bp);
+  else
+    task->data_heap=task->code_heap;
+  TaskInit(task,stk_size);
+  task->rip=fp_start_addr;
+  task->rsp(U8 *)-=8;
+  *task->rsp=data;
+  task->rsp(U8 *)-=8;
+  *task->rsp=&Exit;
+  task->hash_table->next=parent->hash_table;
+  MemCpy(task->task_name,task_name,TASK_NAME_LEN);
+  StrCpy(task->task_title,task->task_name);
+  task->title_src=TTS_TASK_NAME;
+  PUSHFD
+  CLI
+  if (Bt(&flags,JOBf_ADD_TO_QUE)) {
+    TaskQueInsChild(task);
+    TaskQueIns(task);
+  }
+  POPFD
+  return task;
+}
+
+U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE)
+{//Those things calculated from other variables.
+  if (!task) task=Fs;
+  PUSHFD
+  CLI
+  while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+    PAUSE
+  WinDerivedValsUpdate(task);
+  if (fp_update_ctrls)
+    (*fp_update_ctrls)(task);
+  if (update_z_buf && Bt(&task->display_flags,DISPLAYf_SHOW))
+    LBts(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);
+  LBtr(&task->task_flags,TASKf_TASK_LOCK);
+  POPFD
+}
+
+I64 ExeCmdLine(CCmpCtrl *cc)
+{//Terminal JIT-compile-and-execute loop for CCmpCtrl.
+  I64 res=0,type,old_title_src=Fs->title_src;
+  U8 *ptr,*ptr2,*ptr3,*machine_code,*old_task_title=StrNew(Fs->task_title);
+  F64 t0;
+  CDocEntry *doc_e;
+  CDoc *doc;
+  if (Fs->title_src!=TTS_LOCKED_CONST)
+    Fs->title_src=TTS_CUR_LEX;
+  while (cc->token &&
+        (cc->token!='}' || !(cc->flags & CCF_EXE_BLK)) ) {
+    if (Fs->title_src==TTS_CUR_LEX) {
+      ptr2=&Fs->task_title;
+      ptr3=ptr2+STR_LEN-1;
+      if (cc->lex_include_stk->flags & LFSF_DOC) {
+        doc_e=cc->lex_include_stk->cur_entry;
+        doc=cc->lex_include_stk->doc;
+        while (doc_e!=doc && ptr2<ptr3) {
+          switch (doc_e->type_u8) {
+            case DOCT_TEXT:
+              ptr=doc_e->tag;
+              while (*ptr && ptr2<ptr3)
+                *ptr2++=*ptr++;
+              break;
+            case DOCT_TAB:
+            case DOCT_NEW_LINE:
+              *ptr2++='.';
+              break;
+          }
+          doc_e=doc_e->next;
+        }
+        if (ptr2<ptr3) *ptr2=0;
+      } else
+        if ((ptr=cc->lex_include_stk->line_start) && *ptr)
+          MemCpy(ptr2,ptr,STR_LEN-1);
+    }
+    cc->flags&=~CCF_HAS_MISC_DATA;
+    machine_code=LexStmt2Bin(cc,&type);
+    if (machine_code!=INVALID_PTR) {
+      if (!(cc->flags&CCF_JUST_LOAD)) {
+        t0=tS;
+        res=Call(machine_code);
+        Fs->answer=res;
+        Fs->answer_type=type;
+        Fs->answer_time=tS-t0;
+        Fs->new_answer=TRUE;
+        cc->pmt_line=0;
+      }
+      if (!(cc->flags&CCF_HAS_MISC_DATA))
+        Free(machine_code);
+    }
+  }
+  if (Fs->title_src!=TTS_LOCKED_CONST) {
+    Fs->title_src=old_title_src;
+    StrCpy(Fs->task_title,old_task_title);
+  }
+  Free(old_task_title);
+  if (cc->flags&CCF_JUST_LOAD) {
+    if (cc->error_cnt)
+      return FALSE;
+    else
+      return TRUE;
+  } else
+    return res;
+}
+
+U0 SrvTaskCont()
+{//Act as server task in a loop handling commands.
+  I64 old_flags=GetRFlags;
+  FlushMsgs;
+  while (TRUE) {
+    CLI
+    if (JobsHndlr(old_flags) && Fs->title_src==TTS_TASK_NAME)
+      MemCpy(Fs->task_title,Fs->task_name,TASK_NAME_LEN);
+    FlushMsgs;
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    LBts(&Fs->task_flags,TASKf_AWAITING_MSG);
+    Yield;
+    SetRFlags(old_flags);
+  }
+}
+
+U0 UserTaskCont()
+{//Terminal key-input-execute loop.
+  CCmpCtrl *cc;
+  CDoc *doc;
+  Bool cont=TRUE;
+  do {
+    cc=CmpCtrlNew(,CCF_CMD_LINE|CCF_PMT|CCF_QUESTION_HELP);
+    QueIns(cc,Fs->last_cc);
+    try {
+      Lex(cc);
+      ExeCmdLine(cc);
+      cont=Bt(&cc->flags,CCf_PMT);
+      QueRem(cc);
+      CmpCtrlDel(cc);
+    } catch {
+      if ((doc=Fs->put_doc) && doc->doc_signature==DOC_SIGNATURE_VAL)
+        DocUnlock(doc);
+      PutExcept;
+    }
+  } while (cont);
+}
+
+U0 SrvCmdLine(I64 dummy=0)
+{
+  no_warn dummy;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  CallExtStr("SrvStartUp");
+  SrvTaskCont;
+}
+
+U0 UserCmdLine(I64 dummy=0)
+{//A user task ends-up calling this.
+  no_warn dummy;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  CallExtStr("UserStartUp");
+  if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
+    Dbg;
+  UserTaskCont;
+}
+
+CTask *User(U8 *fmt=NULL,...)
+{//Create user term task.
+  U8 *st;
+  CTask *task=Spawn(&UserCmdLine);
+  TaskWait(task);
+  if (fmt) {
+    st=StrPrintJoin(NULL,fmt,argc,argv);
+    XTalk(task,st);
+    Free(st);
+  }
+  return task;
+}
+
+U0 TaskDel(CTask *task)
+{//We delay freeing in case lingering ptr to reincarnated.
+  HeapCtrlDel(task->code_heap);
+  if (task->data_heap!=task->code_heap)
+    HeapCtrlDel(task->data_heap);
+  Free(task);
+}
+
+I64 TaskEnd()
+{//Called with irq's off.
+  CTask *task=Fs,*tmpt,*tmpt1;
+  if (task==sys_task_being_scrn_updated) {
+    LBts(&task->task_flags,TASKf_KILL_TASK);
+    return task->next_task;
+  }
+  if (task->task_end_cb) {
+    task->wake_jiffy=0;
+    LBtr(&task->task_flags,TASKf_KILL_TASK);
+    TaskRstAwaitingMsg(task);
+    Suspend(task,FALSE);
+    task->rip=task->task_end_cb;
+    task->task_end_cb=NULL;
+    return task;
+  }
+  if (task->parent_task && task->parent_task->popup_task==task) {
+    task->parent_task->popup_task=NULL;
+    Kill(task->parent_task,FALSE);
+    return task->parent_task;
+  }
+
+  DrvsRelease;
+  BlkDevsRelease;
+  tmpt1=(&task->next_child_task)(U8 *)-offset(CTask.next_sibling_task);
+  tmpt=tmpt1->next_sibling_task;
+  if (tmpt!=tmpt1) {
+    do {
+      LBts(&tmpt->task_flags,TASKf_KILL_TASK);
+      tmpt=tmpt->next_sibling_task;
+    } while (tmpt!=tmpt1);
+    return task->next_task;
+  }
+  if (LBtr(&task->display_flags,DISPLAYf_SHOW))
+    LBts(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);
+
+  while (LBts(&task->task_flags,TASKf_TASK_LOCK))
+    PAUSE
+  while (LBts(&task->srv_ctrl.flags,JOBCf_LOCKED))
+    PAUSE
+
+  JobQueDel(&task->srv_ctrl.next_waiting);
+  JobQueDel(&task->srv_ctrl.next_done);
+
+  if (IsRaw)
+    VGAFlush;
+
+  if (sys_focus_task==task) {
+    if (!Gs->num)
+      SingleUser(OFF);
+    sys_focus_task=NULL;
+    if (fp_set_std_palette)
+      (*fp_set_std_palette)();
+  }
+
+  //QueRem
+  task->task_signature(I64)=0;
+
+  tmpt =task->next_input_filter_task;
+  tmpt1=task->last_input_filter_task;
+  tmpt1->next_input_filter_task=tmpt;
+  tmpt ->last_input_filter_task=tmpt1;
+
+  tmpt =task->next_sibling_task;
+  tmpt1=task->last_sibling_task;
+  tmpt1->next_sibling_task=tmpt;
+  tmpt ->last_sibling_task=tmpt1;
+
+  tmpt =task->next_task; //save to return
+  TaskQueRem(task);
+
+  LBtr(&task->srv_ctrl.flags,JOBCf_LOCKED);
+  LBtr(&task->task_flags,TASKf_TASK_LOCK);
+
+  task->wake_jiffy=cnts.jiffies+DYING_JIFFIES;
+  while (LBts(&Gs->cpu_flags,CPUf_DYING_TASK_QUE))
+    PAUSE
+  QueIns(task,Gs->last_dying);
+  LBtr(&Gs->cpu_flags,CPUf_DYING_TASK_QUE);
+
+  return tmpt;
+}
+
+U0 TaskKillDying()
+{//Delay freeing to prevent asking for trouble with quick reincarnations.
+//What if the user is doing this: DoTreeCheckers.
+  CTaskDying *task,*task1;
+  if (Gs->kill_jiffy<cnts.jiffies) {//Avoid doing as many lock operations.
+    while (LBts(&Gs->cpu_flags,CPUf_DYING_TASK_QUE))
+      PAUSE
+    task=Gs->next_dying;
+    while (task!=&Gs->next_dying && task->wake_jiffy<cnts.jiffies) {
+      task1=task->next;
+      QueRem(task);
+      TaskDel(task);
+      task=task1;
+    }
+    LBtr(&Gs->cpu_flags,CPUf_DYING_TASK_QUE);
+    Gs->kill_jiffy=cnts.jiffies+DYING_JIFFIES;
+  }
+}
+
+ diff --git a/public/Wb/Kernel/KUtils.HC.HTML b/public/Wb/Kernel/KUtils.HC.HTML new file mode 100755 index 0000000..794ab7f --- /dev/null +++ b/public/Wb/Kernel/KUtils.HC.HTML @@ -0,0 +1,502 @@ + + + + + + + + + + + +
+asm {
+_MEMSET::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSB
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMSET_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSW
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMSET_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSD
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMSET_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_STOSQ
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RBP
+        RET1    24
+_MEMCPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        CLD
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        REP_MOVSB
+        MOV     RAX,RDI
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_MEMCMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        CLD
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDI,U64 SF_ARG2[RBP]
+        MOV     RCX,U64 SF_ARG3[RBP]
+        XOR     RAX,RAX
+        REPE_CMPSB
+        JZ      @@05
+        MOV     AL,1
+        JA      @@05
+        MOV     RAX,-1
+@@05:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_BEQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        XOR     RAX,RAX
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        TEST    RDX,RDX
+        JZ      @@5
+        BTS     U64 [RBX],RCX
+        JMP     @@10
+@@5:    BTR     U64 [RBX],RCX
+@@10:   ADC     AL,0
+        POP     RBP
+        RET1    24
+_LBEQU::
+        PUSH    RBP
+        MOV     RBP,RSP
+        XOR     RAX,RAX
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RBX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        TEST    RDX,RDX
+        JZ      @@5
+        LOCK
+        BTS     U64 [RBX],RCX
+        JMP     @@10
+@@5:    LOCK
+        BTR     U64 [RBX],RCX
+@@10:   ADC     AL,0
+        POP     RBP
+        RET1    24
+_CLAMP_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        CMP     RAX,RCX
+        CMOVL   RAX,RCX
+        CMP     RAX,RDX
+        CMOVG   RAX,RDX
+        POP     RBP
+        RET1    24
+_CLAMP_U64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        CMP     RAX,RCX
+        CMOVB   RAX,RCX
+        CMP     RAX,RDX
+        CMOVA   RAX,RDX
+        POP     RBP
+        RET1    24
+_CALL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        TEST    RAX,RAX
+        JZ      @@05
+        CALL    RAX
+@@05:   POP     RBP
+        RET1    8
+_BIT_FIELD_OR_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG2[RBP]
+        SHR     RBX,3
+        ADD     RBX,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        AND     CL,7
+        SHL     RAX,CL
+        OR      U64 [RBX],RAX
+        POP     RBP
+        RET1    24
+_BIT_FIELD_EXT_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG2[RBP]
+        MOV     RCX,RBX
+        SHR     RBX,3
+        ADD     RBX,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 [RBX]
+        AND     CL,7
+        SHR     RDX,CL
+        MOV     RCX,U64 SF_ARG3[RBP]
+        MOV     RAX,1
+        SHL     RAX,CL
+        DEC     RAX
+        AND     RAX,RDX
+        POP     RBP
+        RET1    24
+_XCHG_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        XCHG    U64 [RDX],RAX
+        POP     RBP
+        RET1    16
+_XCHG_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     EAX,U32 SF_ARG2[RBP]
+        XCHG    U32 [RDX],EAX
+        POP     RBP
+        RET1    16
+_XCHG_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U16 SF_ARG2[RBP]
+        XCHG    U16 [RDX],AX
+        POP     RBP
+        RET1    16
+_XCHG_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U8 SF_ARG2[RBP]
+        XCHG    U8 [RDX],AL
+        POP     RBP
+        RET1    16
+
+_LXCHG_I64::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RAX,U64 SF_ARG2[RBP]
+        LOCK
+        XCHG    U64 [RDX],RAX
+        POP     RBP
+        RET1    16
+_LXCHG_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     EAX,U32 SF_ARG2[RBP]
+        LOCK
+        XCHG    U32 [RDX],EAX
+        POP     RBP
+        RET1    16
+_LXCHG_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U16 SF_ARG2[RBP]
+        LOCK
+        XCHG    U16 [RDX],AX
+        POP     RBP
+        RET1    16
+_LXCHG_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOVZX   RAX,U8 SF_ARG2[RBP]
+        LOCK
+        XCHG    U8 [RDX],AL
+        POP     RBP
+        RET1    16
+_REP_IN_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_INSD
+        POP     RDI
+        POP     RBP
+        RET1    24
+_REP_IN_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_INSW
+        POP     RDI
+        POP     RBP
+        RET1    24
+_REP_IN_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_INSB
+        POP     RDI
+        POP     RBP
+        RET1    24
+_REP_OUT_U32::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_OUTSD
+        POP     RSI
+        POP     RBP
+        RET1    24
+_REP_OUT_U16::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_OUTSW
+        POP     RSI
+        POP     RBP
+        RET1    24
+_REP_OUT_U8::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RSI,U64 SF_ARG1[RBP]
+        MOV     RDX,U64 SF_ARG3[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]
+        REP_OUTSB
+        POP     RSI
+        POP     RBP
+        RET1    24
+_CPUID::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        MOV     RAX,U64 SF_ARG1[RBP]
+        CPUID
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     U64 [RSI],RAX
+        MOV     U64 8[RSI],RBX
+        MOV     U64 16[RSI],RCX
+        MOV     U64 24[RSI],RDX
+        POP     RSI
+        POP     RBP
+        RET1    16
+_CALL_IND::     //See _LAST_FUN
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        LEA     RSI,U64 SF_ARG3[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        TEST    RDX,RDX
+        JZ      @@05
+
+        CALL    RDX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+@@05:   MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        XOR     RAX,RAX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+_CALLEXTNUM::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RDX,U64 SF_ARG1[RBP]
+        MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        LEA     RSI,U64 SF_ARG3[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        MOV     RAX,U64 [SYS_EXTERN_TABLE]
+        MOV     RAX,U64 [RAX+RDX*8]
+        TEST    RAX,RAX
+        JZ      @@05
+
+        CALL    RAX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+@@05:   MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+_CALLEXTSTR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        LEA     RSI,U64 SF_ARG3[RBP]    //argv
+        SHL     RCX,3
+        SUB     RSP,RCX
+        MOV     RDI,RSP
+        REP_MOVSB
+        MOV     RSI,U64 SF_ARG1[RBP]
+
+        MOV     RCX,1
+        XOR     RAX,RAX
+        MOV     RDI,U64 FS:CTask.hash_table[RAX]
+        MOV     RBX,HTT_FUN|HTT_EXPORT_SYS_SYM
+        CALL    SYS_HASH_FIND
+        JZ      @@15
+
+        TEST    U32 CHash.type[RAX],HTT_FUN
+        JZ      @@05
+        MOV     RAX,U64 CHashFun.exe_addr[RAX]
+        JMP     @@10
+@@05:   MOV     RAX,U64 CHashExport.val[RAX]
+@@10:   TEST    RAX,RAX
+        JZ      @@15
+
+        CALL    RAX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+
+@@15:   MOV     RCX,U64 SF_ARG2[RBP]    //argc
+        SHL     RCX,3
+        ADD     RSP,RCX
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET
+SET_GS_BASE::
+        PUSH    RAX
+        PUSH    RCX
+        PUSH    RDX
+        MOV     RDX,RAX
+        SHR     RDX,32
+        MOV     ECX,IA32_GS_BASE
+        WRMSR
+        POP     RDX
+        POP     RCX
+        POP     RAX
+        RET
+SET_FS_BASE::
+        PUSH    RAX
+        PUSH    RCX
+        PUSH    RDX
+        MOV     RDX,RAX
+        SHR     RDX,32
+        MOV     ECX,IA32_FS_BASE
+        WRMSR
+        POP     RDX
+        POP     RCX
+        POP     RAX
+_RET::
+        RET
+_SET_MSR::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,SF_ARG2[RBP]
+        MOV     RDX,RAX
+        SHR     RDX,32
+        MOV     RCX,SF_ARG1[RBP]
+        WRMSR
+        POP     RBP
+        RET1    16
+_SYS_HLT::
+        CLI
+@@05:   HLT
+        JMP     @@05
+}
+
+ diff --git a/public/Wb/Kernel/KernelA.HH b/public/Wb/Kernel/KernelA.HH old mode 100644 new mode 100755 diff --git a/public/Wb/Kernel/KernelA.HH.HTML b/public/Wb/Kernel/KernelA.HH.HTML new file mode 100755 index 0000000..0919f77 --- /dev/null +++ b/public/Wb/Kernel/KernelA.HH.HTML @@ -0,0 +1,3938 @@ + + + + + + + + + + + +
+// Main TempleOS header
+
+#help_index ""
+extern class CAOT;
+extern class CAOTHeapGlbl;
+extern class CAOTImportExport;
+extern class CCPU;
+extern class CDC;
+extern class CDirContext;
+extern class CDoc;
+extern class CFile;
+extern class CHashClass;
+extern class CHashFun;
+extern class CHeapCtrl;
+extern class CIntermediateCode;
+extern class CJobCtrl;
+extern class CTask;
+
+#define NULL    0
+#define TRUE    1
+#define FALSE   0
+#define ON      1
+#define OFF     0
+#define I8_MIN (-0x80)
+#define I8_MAX 0x7F
+#define U8_MIN 0
+#define U8_MAX 0xFF
+#define I16_MIN (-0x8000)
+#define I16_MAX 0x7FFF
+#define U16_MIN 0
+#define U16_MAX 0xFFFF
+#define I32_MIN (-0x80000000)
+#define I32_MAX 0x7FFFFFFF
+#define U32_MIN 0
+#define U32_MAX 0xFFFFFFFF
+#define I64_MIN (-0x8000000000000000)
+#define I64_MAX 0x7FFFFFFFFFFFFFFF
+#define U64_MIN 0
+#define U64_MAX 0xFFFFFFFFFFFFFFFF
+#define INVALID_PTR     I64_MAX
+#define STR_LEN 144
+
+//(Int to F64 conversion is signed)
+//Turn off 80-bit float constants with OPTf_NO_BUILTIN_CONST.
+#define U64_F64_MAX (0x43F0000000000000(F64))
+#define F64_MAX (0x7FEFFFFFFFFFFFFF(F64))
+#define F64_MIN (0xFFEFFFFFFFFFFFFF(F64))
+#define inf     (0x7FF0000000000000(F64))
+#define inf     (0x7FF0000000000000(F64))
+#define pi      (0x400921FB54442D18(F64))
+#define pi      (0x400921FB54442D18(F64))
+#define exp_1   (0x4005BF0A8B145769(F64)) //The number "e"
+#define log2_10 (0x400A934F0979A371(F64))
+#define log2_e  (0x3FF71547652B82FE(F64))
+#define log10_2 (0x3FD34413509F79FF(F64))
+#define loge_2  (0x3FE62E42FEFA39EF(F64))
+#define sqrt2   (0x3FF6A09E667F3BCD(F64))
+#define eps     (0x3CB0000000000000(F64))
+
+#help_index "Data Types/Simple"
+/*HolyC union structure is treated as a
+whole if no member is specified,
+similar to bit fields.
+
+See EndianI64() and ::/Demo/SubIntAccess.HC.
+*/
+U16i union U16
+{
+  I8i   i8[2];
+  U8i   u8[2];
+};
+
+I16i union I16
+{
+  I8i   i8[2];
+  U8i   u8[2];
+};
+
+U32i union U32
+{
+  I8i   i8[4];
+  U8i   u8[4];
+  I16   i16[2];
+  U16   u16[2];
+};
+
+I32i union I32
+{
+  I8i   i8[4];
+  U8i   u8[4];
+  I16   i16[2];
+  U16   u16[2];
+};
+
+U64i union U64
+{
+  I8i   i8[8];
+  U8i   u8[8];
+  I16   i16[4];
+  U16   u16[4];
+  I32   i32[2];
+  U32   u32[2];
+};
+
+I64i union I64
+{
+  I8i   i8[8];
+  U8i   u8[8];
+  I16   i16[4];
+  U16   u16[4];
+  I32   i32[2];
+  U32   u32[2];
+};
+
+#help_index "Math/Complex;Data Types/Complex"
+public class Complex
+{
+  F64   x,y;
+};
+
+#help_index "Data Types/Circular Queue"
+public class CQue
+{
+  CQue  *next,*last;
+};
+
+#help_index "Graphics/Data Types/D3I32;Math/Data Types/D3I32;Data Types/D3I32"
+public class CD3I32 //Three dimensional I32 pt
+{
+  I32   x,y,z;
+};
+public class CQueD3I32 //Que of three dimensional I32 pts
+{
+  CQueD3I32     *next,*last;
+  CD3I32        p;
+};
+#help_index "Math/Data Types;Data Types"
+public class CD2I32 //Two dimensional I32 pt
+{
+  I32   x,y;
+};
+public class CD2I64 //Two dimensional I64 pt
+{
+  I64   x,y;
+};
+public class CD3I64 //Three dimensional I64 pt
+{
+  I64   x,y,z;
+};
+public class CD2 //Two dimensional F64 pt
+{
+  F64   x,y;
+};
+
+#help_index "Math/CD3;Data Types/CD3"
+public class CD3 //Three dimensional F64 pt
+{
+  F64   x,y,z;
+};
+
+#help_index "Data Types/Queue Vector"
+#define QUE_VECT_U8_CNT         512
+public class CQueVectU8
+{
+  CQueVectU8    *next,*last;
+  I64   total_cnt,node_cnt,min_idx;
+  U8    body[QUE_VECT_U8_CNT];
+};
+
+#help_index "Data Types/Fifo"
+public class CFifoU8
+{
+  U8    *buf;
+  I64   mask,in_ptr,out_ptr;
+};
+public class CFifoI64
+{
+  I64   *buf;
+  I64   mask,in_ptr,out_ptr;
+};
+
+#help_index "Date/CDate"
+#define CDATE_YEAR_DAYS         365.24225
+#define CDATE_YEAR_DAYS_INT     36524225
+#define CDATE_BASE_DAY_OF_WEEK  0
+public I64 class CDate
+{
+  U32   time;
+  I32   date;
+};
+
+#help_index "Date;Date/CDate"
+public class CDateStruct
+{
+  U8    sec10000,sec100,sec,min,hour,
+        day_of_week,day_of_mon,mon;
+  I32   year;
+};
+
+#help_index "Math/ODE"
+public class COrder2D3
+{
+  F64   x,y,z,
+        DxDt,DyDt,DzDt;
+};
+
+#define MSF_INACTIVE            1
+#define MSF_FIXED               2
+public class CMass
+{
+  CMass *next,*last;
+  COrder2D3 *state, //Point to entries in CMathODE.state[]
+        *DstateDt;  //Point to entries in CMathODE.DstateDt[]
+
+  U0    start;
+  U32   flags,num;
+  F64   mass,drag_profile_factor;
+  U0    saved_state;
+  F64   x,y,z,
+        DxDt,DyDt,DzDt;
+  U0    end;
+};
+
+#define SSF_INACTIVE            1
+#define SSF_NO_COMPRESSION      2
+#define SSF_NO_TENSION          4
+public class CSpring
+{
+  CSpring *next,*last;
+  CMass *end1,*end2;
+  F64   f,displacement; //set for you to check
+
+  U0    start;
+  U32   flags,num,
+        end1_num,end2_num;
+  F64   const,rest_len;
+  U0    end;
+};
+
+//Ordinary Differential Equations
+#define ODEF_HAS_MASSES 1
+#define ODEF_PAUSED     2
+#define ODEF_STARTED    4
+#define ODEF_BUSY       8
+
+#define ODEf_HAS_MASSES 0
+#define ODEf_PAUSED     1
+#define ODEf_STARTED    2
+#define ODEf_BUSY       3
+
+public class CMathODE
+{
+  CMathODE *next,*last;
+  I64   flags,n,n_internal;
+  CMass *next_mass,*last_mass;
+  CSpring *next_spring,*last_spring;
+  F64   drag_v,  //drag proportional to velocity
+        drag_v2, //drag proportional to velocity squared
+        drag_v3, //drag proportional to velocity cubed
+        acceleration_limit, //This clips acceleration
+        base_t,
+        t,t_scale,
+        h,h_min,h_max;
+
+  //This is not precise, just a ballpark.
+  //TempleOS CMathODE's are for video games
+  //not science.  It bails if it takes
+  //too long.
+  F64   min_tolerance,max_tolerance;
+
+  F64   tolerance_internal,
+        *array_base,
+        *state,
+        *state_internal,
+        *DstateDt,
+        *state_scale,
+        *initial_state,
+        *tmp0,*tmp1,*tmp2,*tmp3,
+        *tmp4,*tmp5,*tmp6,*tmp7;
+  CTask *mem_task,*win_task;
+  U0    (*derive)(CMathODE *o,F64 t,F64 *state,F64 *DstateDt);
+  U0    (*mp_derive)(CMathODE *o,F64 t, //If break into parallel pieces.
+                I64 cpu_num,F64 *state,F64 *DstateDt);
+  CTask **slave_tasks;
+  I64   mp_not_done_flags;
+  F64   mp_t,*mp_state,*mp_DstateDt;
+
+  I64   user_data;
+};
+
+#help_index "Processor"
+//IDT entry types
+#define IDTET_TASK              0x05
+#define IDTET_IRQ               0x0E
+#define IDTET_TRAP              0x0F //Same as IRQ but doesnt do CLI.
+
+//Interrupts
+//0x00-0x1F are reserved by Intel
+#define I_DIV_ZERO              0x00
+#define I_SINGLE_STEP           0x01
+#define I_NMI                   0x02
+#define I_BPT                   0x03
+#define I_PAGE_FAULT            0x0E
+//0x20-0x2F are used for hardware
+#define I_TIMER                 0x20
+//Software Interrupts
+#define I_MP_CRASH              0x30
+#define I_WAKE                  0x31
+#define I_DBG                   0x32
+//See ST_INT_NAMES
+
+//You might want to start bwd from
+//0xFF for your own interrupts.
+#define I_USER                  0x40
+
+#define MP_PROCESSORS_NUM       128
+
+#define SYS_START_CR0           0x0031
+
+#define RFLAGf_CARRY            0
+#define RFLAGf_PARITY           2
+#define RFLAGf_AUX_CARRY        4
+#define RFLAGf_ZERO             6
+#define RFLAGf_SIGN             7
+#define RFLAGf_TRAP             8 //Single Step
+#define RFLAGf_INT              9
+#define RFLAGf_DIR              10
+#define RFLAGf_OVERFLOW         11
+#define RFLAGf_IOPL0            12 // I/O Privilege Level
+#define RFLAGf_IOPL1            13
+#define RFLAGf_NESTED_TASK      14
+#define RFLAGf_RESUME           16
+#define RFLAGf_V8086            17
+#define RFLAGf_ALIGN_CHECK      18
+#define RFLAGf_VINT             19 //Virtual Interrupt
+#define RFLAGf_VINT_PENDING     20
+#define RFLAGf_ID               21
+
+#define RFLAGG_START            0x0000
+#define RFLAGG_NORMAL           (1<<RFLAGf_INT)
+
+//Global Descriptor Table
+class CGDTEntry
+{
+  U64   lo,hi;
+};
+
+class CGDT
+{
+  CGDTEntry null;
+  CGDTEntry boot_ds;
+  CGDTEntry boot_cs;
+  CGDTEntry cs32;
+  CGDTEntry cs64;       //The Charter says just ring-0.
+  CGDTEntry cs64_ring3; //Ring3, in case you want to play around.
+  CGDTEntry ds;
+  CGDTEntry ds_ring3;
+  CGDTEntry tr[MP_PROCESSORS_NUM];
+  CGDTEntry tr_ring3[MP_PROCESSORS_NUM];
+};
+
+class CSysLimitBase
+{
+  U16   limit;  //Offset of last byte, not size.
+  U8    *base;  //&GDT or &IDT
+};
+
+#help_index "Memory/Info"
+#define MEM_E820_ENTRIES_NUM    48
+class CMemE820
+{
+  U8    *base;
+  I64   len;
+  U8    type,pad[3];
+};
+
+#help_index "Compiler/Internal"
+//Loader flags
+#define LDF_NO_ABSS             1
+#define LDF_JUST_LOAD           2
+#define LDF_SILENT              4
+
+#define BIN_SIGNATURE_VAL       'TOSB'
+class CBinFile
+{//Bin File Header Generation by compiler.
+  U16   jmp;
+  U8    module_align_bits,
+        reserved;
+  U32   bin_signature;
+  I64   org,
+        patch_table_offset, //Patch Table Generation
+        file_size;
+};
+
+class CPatchTableAbsAddr
+{
+  U8    eit_abs_addr;   //IET_ABS_ADDR
+  U32   abs_addres_cnt;
+  U8    zero;
+  U32   abs_addres[1];
+};
+
+//CAOTImportExport Types. Used in PatchTable.
+#define IET_END                 0
+//reserved
+#define IET_REL_I0              2 //Fictitious
+#define IET_IMM_U0              3 //Fictitious
+#define IET_REL_I8              4
+#define IET_IMM_U8              5
+#define IET_REL_I16             6
+#define IET_IMM_U16             7
+#define IET_REL_I32             8
+#define IET_IMM_U32             9
+#define IET_REL_I64             10
+#define IET_IMM_I64             11
+#define IEF_IMM_NOT_REL         1
+//reserved
+#define IET_REL32_EXPORT        16
+#define IET_IMM32_EXPORT        17
+#define IET_REL64_EXPORT        18 //Not implemented
+#define IET_IMM64_EXPORT        19 //Not implemented
+#define IET_ABS_ADDR            20
+#define IET_CODE_HEAP           21 //Not really used
+#define IET_ZEROED_CODE_HEAP    22 //Not really used
+#define IET_DATA_HEAP           23
+#define IET_ZEROED_DATA_HEAP    24 //Not really used
+#define IET_MAIN                25
+
+#help_index "Boot"
+class CKernel
+{//Must match OSStartUp
+  CBinFile h;
+  U32   jmp,
+        boot_src,
+        boot_blk,
+        boot_patch_table_base,
+        sys_run_level;
+  CDate compile_time;
+
+  U0    start;
+  U32   boot_base;
+  U16   mem_E801[2];
+  CMemE820 mem_E820[MEM_E820_ENTRIES_NUM];
+  U64   mem_physical_space;
+  CSysLimitBase sys_gdt_ptr;
+  U16   sys_pci_busses;
+  ;$=($+15)&-16;
+  CGDT  sys_gdt;
+};
+
+//Run-Levels
+#define RLf_16BIT               0
+#define RLf_VGA                 1
+#define RLf_32BIT               2
+#define RLf_PATCHED             3
+#define RLf_16MEG_SYS_CODE_BP   4
+#define RLf_64BIT               5
+#define RLf_16MEG_ADAM_HEAP_CTRL 6
+#define RLf_FULL_HEAPS          7
+#define RLf_RAW                 8
+#define RLf_INTERRUPTS          9
+#define RLf_BLKDEV              10
+#define RLf_MP                  11
+#define RLf_COMPILER            12
+#define RLf_DOC                 13
+#define RLf_WINMGR              14
+#define RLf_REGISTRY            15
+#define RLf_HOME                16
+#define RLf_AUTO_COMPLETE       17
+#define RLf_ADAM_SERVER         18
+#define RLf_ONCE_ADAM           19
+#define RLf_ONCE_USER           20
+
+#define RLF_16BIT               0x000001
+#define RLF_VGA                 0x000002
+#define RLF_32BIT               0x000004
+#define RLF_PATCHED             0x000008
+#define RLF_16MEG_SYS_CODE_BP   0x000010
+#define RLF_64BIT               0x000020
+#define RLF_16MEG_ADAM_HEAP_CTRL 0x000040
+#define RLF_FULL_HEAPS          0x000050
+#define RLF_RAW                 0x000100
+#define RLF_INTERRUPTS          0x000200
+#define RLF_BLKDEV              0x000400
+#define RLF_MP                  0x000800
+#define RLF_COMPILER            0x001000
+#define RLF_DOC                 0x002000
+#define RLF_WINMGR              0x004000
+#define RLF_REGISTRY            0x008000
+#define RLF_HOME                0x010000
+#define RLF_AUTO_COMPLETE       0x020000
+#define RLF_ADAM_SERVER         0x040000
+#define RLF_ONCE_ADAM           0x080000
+#define RLF_ONCE_USER           0x100000
+
+#help_index "Processor"
+#define LAPIC_BASE              0xFEE00000
+
+#define LAPIC_APIC_ID           (LAPIC_BASE+0x020)
+#define LAPIC_APIC_VERSION      (LAPIC_BASE+0x030)
+#define LAPIC_TASK_PRIORITY     (LAPIC_BASE+0x080)
+#define LAPIC_ARIBITRATION_PRIORITY (LAPIC_BASE+0x090)
+#define LAPIC_PROCESSOR_PRIORITY (LAPIC_BASE+0x0A0)
+#define LAPIC_EOI               (LAPIC_BASE+0x0B0)
+#define LAPIC_LOG_DST           (LAPIC_BASE+0x0D0)
+#define LAPIC_DFR               (LAPIC_BASE+0x0E0)
+#define LAPIC_LDR               (LAPIC_BASE+0x0D0)
+
+#define LAPICF_APIC_ENABLED     0x100
+#define LAPIC_SVR               (LAPIC_BASE+0x0F0)
+
+#define LAPIC_ISR               (LAPIC_BASE+0x100)
+#define LAPIC_TMR               (LAPIC_BASE+0x180)
+#define LAPIC_IRR               (LAPIC_BASE+0x200)
+#define LAPIC_ICR_LOW           (LAPIC_BASE+0x300)
+#define LAPIC_ICR_HIGH          (LAPIC_BASE+0x310)
+
+#define LAPIC_LVT_TIMER         (LAPIC_BASE+0x320)
+#define LAPIC_LVT_THERMAL       (LAPIC_BASE+0x330)
+#define LAPIC_LVT_PERF          (LAPIC_BASE+0x340)
+#define LAPIC_LVT_LINT0         (LAPIC_BASE+0x350)
+#define LAPIC_LVT_LINT1         (LAPIC_BASE+0x360)
+#define LAPIC_LVT_ERR           (LAPIC_BASE+0x370)
+
+#define MPN_VECT                0x97
+#define MP_VECT_ADDR            (MPN_VECT*0x1000)
+
+//I/O APIC Memory mapped window
+#define IOAPIC_REG              0xFEC00000 //U8
+#define IOAPIC_DATA             0xFEC00010 //U32
+//I/O APIC Regs
+#define IOAPICID                0x00
+#define IOAPICVER               0x01
+#define IOAPICARB               0x02
+#define IOREDTAB                0x10
+
+//Model specific regs.
+#define IA32F_SCE       0x001
+#define IA32F_LME       0x100
+#define IA32_LAPIC_BASE 0x01B
+#define IA32_EFER       0xC0000080
+#define IA32_FS_BASE    0xC0000100
+#define IA32_GS_BASE    0xC0000101
+
+class CAP16BitInit
+{//AP Multicore
+  U32   jmp;
+  CSysLimitBase ap_gdt_ptr;
+};
+
+#help_index "Time/CPU Cycles;Time/HPET;Time/Jiffies"
+//High Performance Event Timer
+#define HPET_GCAP_ID    (0xFED00000+0x00)
+#define HPET_GEN_CONF   (0xFED00000+0x10)
+#define HPET_MAIN_CNT   (0xFED00000+0xF0)
+
+public class CCntsGlbls
+{
+  I64   jiffies,        //JIFFY_FREQ
+        timer,          //SYS_TIMER_FREQ. Use SysTimerRead().
+        time_stamp_freq,
+        time_stamp_kHz_freq,
+        time_stamp_freq_initial, //Initial freq, sampled once at boot time.
+        HPET_freq,
+        HPET_kHz_freq,
+        HPET_initial;   //Initial count, sampled at boot time.
+  Bool  time_stamp_calibrated;
+};
+
+#define JIFFY_FREQ              1000 // Hz
+#define CDATE_FREQ              49710 // Hz
+#define SYS_TIMER_FREQ          (18333*65536/1000) //Hz
+#define SYS_TIMER0_PERIOD       (65536*182/10/JIFFY_FREQ)
+
+#help_index "Call"
+//Function Stack Frame
+#define SF_RBP  0x00
+#define SF_RIP  0x08
+#define SF_ARG1 0x10
+#define SF_ARG2 0x18
+#define SF_ARG3 0x20
+#define SF_ARG4 0x28
+#define SF_ARG5 0x30
+#define SF_ARG6 0x38
+#define SF_ARG7 0x40
+#define SF_ARG8 0x48
+
+class CRAXRBCRCXRDX
+{
+  I64   rax,rbx,rcx,rdx;
+};
+
+//Asm callable function pointers.
+//They work with CallExtNum() when calling from HolyC.
+#define EXT_WIN_TO_TOP          0
+#define EXT_WIN_FOCUS           1
+#define EXT_HEAPLOG_MALLOC      2
+#define EXT_HEAPLOG_FREE        3
+#define EXT_DBG_RESUME          4
+#define EXT_EXTS_NUM            5
+
+#help_index "Processor"
+#define DFT_CACHE_LINE_WIDTH    128
+
+//Semaphores
+class CSema
+{
+  Bool  val,pad[DFT_CACHE_LINE_WIDTH-1];
+};
+#define SEMA_DEBUG              0
+#define SEMA_RECORD_MACRO       1
+#define SEMA_SYS_TIMER          2
+#define SEMA_SYS_DATE           3
+#define SEMA_DBG_MODE           4
+#define SEMA_SND                5
+#define SEMA_HEAPLOG_ACTIVE     6
+#define SEMA_HEAPLOG_LOCK       7
+#define SEMA_REFRESH_IN_PROGRESS 8
+#define SEMA_FLUSH_VGA_IMAGE    9
+#define SEMA_SINGLE_USER        10
+#define SEMA_DSK_CACHE          11
+#define SEMA_FAR_CALL32         12
+#define SEMA_DEV_MEM            13
+#define SEMA_VGA                14
+#define SEMA_UPDATE_WIN_Z_BUF   15
+#define SEMA_TT                 16
+#define SEMA_MUTE               17
+#define SEMA_JUST_PUMP_MSGS     18
+#define SEMA_TMBEAT             19
+#define SEMA_FIX                20
+#define SEMA_SEMAS_NUM          21
+
+#define CTRL_ALT_DEL            0
+#define CTRL_ALT_C              1
+#define CTRL_ALT_X              2
+#define CTRL_ALT_TAB            3
+
+#help_index "Hash"
+public class CHash
+{//See Hash
+  CHash *next;
+  U8    *str;
+  U32   type,
+        use_cnt; // inc'ed every time search found, never dec'ed.
+};
+
+public class CHashTable
+{
+  CHashTable *next;
+  I64   mask,locked_flags;
+  CHash **body;
+};
+
+#help_index "Hash/System"
+//Hash table types: ST_HTT_TYPES
+#define HTt_EXPORT_SYS_SYM      0
+#define HTt_IMPORT_SYS_SYM      1
+#define HTt_DEFINE_STR          2
+#define HTt_GLBL_VAR            3
+#define HTt_CLASS               4
+#define HTt_INTERNAL_TYPE       5
+#define HTt_FUN                 6
+#define HTt_WORD                7
+#define HTt_DICT_WORD           8
+#define HTt_KEYWORD             9
+#define HTt_ASM_KEYWORD         10
+#define HTt_OPCODE              11
+#define HTt_REG                 12
+#define HTt_FILE                13
+#define HTt_MODULE              14
+#define HTt_HELP_FILE           15
+#define HTt_FRAME_PTR           16
+#define HTt_TYPES_NUM           17
+
+#define HTf_PRIVATE             23
+#define HTf_PUBLIC              24
+#define HTf_EXPORT              25
+#define HTf_IMPORT              26
+#define HTf_IMM                 27
+#define HTf_GOTO_LABEL          28
+#define HTf_RESOLVED            29
+#define HTf_UNRESOLVED          30
+#define HTf_LOCAL               31
+
+#define HTT_INVALID             0
+#define HTT_EXPORT_SYS_SYM      0x00001 //CHashExport
+#define HTT_IMPORT_SYS_SYM      0x00002 //CHashImport
+#define HTT_DEFINE_STR          0x00004 //CHashDefineStr
+#define HTT_GLBL_VAR            0x00008 //CHashGlblVar
+#define HTT_CLASS               0x00010 //CHashClass
+#define HTT_INTERNAL_TYPE       0x00020 //CHashClass
+#define HTT_FUN                 0x00040 //CHashFun
+#define HTT_WORD                0x00080 //CHashAC only in AutoComplete table
+#define HTT_DICT_WORD           0x00100 //CHashGeneric only in AutoComplete tbl
+#define HTT_KEYWORD             0x00200 //CHashGeneric KEYWORD
+#define HTT_ASM_KEYWORD         0x00400 //CHashGeneric ASM_KEYWORD
+#define HTT_OPCODE              0x00800 //CHashOpcode
+#define HTT_REG                 0x01000 //CHashReg
+#define HTT_FILE                0x02000 //CHashGeneric
+#define HTT_MODULE              0x04000 //CHashGeneric
+#define HTT_HELP_FILE           0x08000 //CHashSrcSym
+#define HTT_FRAME_PTR           0x10000 //CHashGeneric
+#define HTG_TYPE_MASK           0x1FFFF
+
+#define HTF_PRIVATE             0x00800000
+#define HTF_PUBLIC              0x01000000
+#define HTF_EXPORT              0x02000000
+#define HTF_IMPORT              0x04000000
+#define HTF_IMM                 0x08000000
+#define HTF_GOTO_LABEL          0x10000000
+#define HTF_RESOLVE             0x20000000
+#define HTF_UNRESOLVED          0x40000000
+#define HTF_LOCAL               0x80000000
+#define HTG_FLAGS_MASK          0xFF000000
+
+#define HTG_SRC_SYM     (HTT_DEFINE_STR|HTT_GLBL_VAR|HTT_FUN|HTT_CLASS|\
+                        HTT_EXPORT_SYS_SYM|HTT_HELP_FILE)
+#define HTG_ALL                 -1
+
+#define KERNEL_MODULE_NAME      "/Kernel/Kernel"
+
+class CDbgInfo
+{
+  U32   min_line,max_line;
+  U32   body[1]; //Code heap is 32-bit value
+};
+
+public class CHashSrcSym:CHash
+{
+  U8    *src_link,
+        *idx;
+  CDbgInfo *dbg_info;
+  U8    *import_name;
+  CAOTImportExport *ie_lst;
+};
+
+public class CHashGeneric:CHash
+{
+  I64   user_data0,user_data1,user_data2;
+};
+
+#define REGT_NONE       0
+#define REGT_R8         1
+#define REGT_R16        2
+#define REGT_R32        3
+#define REGT_R64        4
+#define REGT_SEG        5
+#define REGT_FSTK       6
+#define REGT_MM         7
+#define REGT_XMM        8
+
+public class CHashReg:CHash
+{
+  U8    reg_num,reg_type;
+};
+
+public class CHashAC:CHash
+{
+  I32   num;
+  U32   hits;
+};
+
+public class CHashExport:CHashSrcSym
+{
+  I64   val;
+};
+
+public class CHashImport:CHashSrcSym
+{
+  U8    *module_base,
+        *module_header_entry;
+};
+
+#help_index "Compiler/Internal"
+#define PTR_STARS_NUM   4
+
+//Member Lst Flags
+#define MLF_DFT_AVAILABLE       1
+#define MLF_LASTCLASS           2
+#define MLF_STR_DFT_AVAILABLE   4
+#define MLF_FUN                 8
+#define MLF_DOT_DOT_DOT         16
+#define MLF_NO_UNUSED_WARN      32
+#define MLF_STATIC              64
+
+public class CArrayDim
+{
+  CArrayDim *next;
+  I64   cnt,total_cnt;
+};
+
+#define MLMF_IS_STR     1
+public class CMemberLstMeta
+{
+  CMemberLstMeta *next;
+  U8    *str;
+  I64   flags,
+        user_data;
+};
+
+public class CMemberLst
+{
+  CMemberLst *next,*left,*right,
+        *left_class_base,*right_class_base; //For finding dup class local vars.
+  U8    *str;
+  CHashClass *member_class,*member_class_base;
+  CMemberLstMeta *meta;
+  U32   use_cnt;
+  U16   flags;
+  I8    reg,pad;
+  I64   offset,size;
+  CArrayDim dim;
+  U8    *static_data;
+  union {
+    I64 static_data_rip;
+    I64 dft_val;
+  }
+  CHashFun *fun_ptr;
+};
+
+class CExternUsage
+{
+  CExternUsage *next;
+  I64   rip;
+};
+
+#help_index "Hash/System;Compiler/Internal"
+public class CHashDefineStr:CHashSrcSym
+{
+  U8    *data,**sub_idx;
+  I64   cnt;
+};
+
+#define Cf_EXTERN               0
+#define Cf_INTERNAL_TYPE        1
+
+public class CHashClass:CHashSrcSym
+{//See PrsClassNew(). base_class of CHashFun
+  I64   size,neg_offset;
+  U32   member_cnt;
+  U8    ptr_stars_cnt,raw_type;
+  U16   flags;
+  CMemberLst *member_lst_and_root, //Head of linked list and head of tree.
+        *member_class_base_root, //For finding dup class local vars.
+        *last_in_member_lst;
+  CHashClass    *base_class,
+        *fwd_class;
+};
+
+//Function flags
+#define Ff_INTERRUPT            8
+#define Ff_HASERRCODE           9
+#define Ff_ARGPOP               10
+#define Ff_NOARGPOP             11
+#define Ff_INTERNAL             12
+#define Ff__EXTERN              13
+#define Ff_DOT_DOT_DOT          14
+#define Ff_RET1                 15
+
+public class CHashFun:CHashClass
+{//See PrsFunNew().
+  CHashClass *return_class;
+  U32   arg_cnt,pad,
+        used_reg_mask,clobbered_reg_mask;
+  U8    *exe_addr;
+  CExternUsage *ext_lst;
+};
+
+//Glbl Var Flags
+#define GVF_FUN         1
+#define GVF_IMPORT      2
+#define GVF_EXTERN      4
+#define GVF_DATA_HEAP   8
+#define GVF_ALIAS       16
+#define GVF_ARRAY       32
+
+public class CHashGlblVar:CHashSrcSym
+{
+  I64   size,flags;
+  CHashClass *var_class;
+  CHashFun *fun_ptr;
+  CArrayDim dim;
+  U8    *data_addr;
+  union {
+    I64 data_addr_rip;
+    CAOTHeapGlbl *heap_glbl;
+  }
+};
+#assert offset(CHashClass.size)==offset(CHashGlblVar.size)
+
+#help_index "DolDoc"
+//See TextBase Layer.
+#define ATTRF_BLINK     0x10000000
+#define ATTRF_INVERT    0x20000000
+#define ATTRF_SEL       0x40000000
+#define ATTRF_UNDERLINE 0x80000000
+
+#define ATTRf_BLINK             28
+#define ATTRf_INVERT            29
+#define ATTRf_SEL               30
+#define ATTRf_UNDERLINE         31
+
+//CDocEntry.type codes (Low 8 bits)
+#define DOCT_TEXT               0
+#define DOCT_NEW_LINE           1
+#define DOCT_SOFT_NEW_LINE      2
+#define DOCT_TAB                3
+#define DOCT_PAGE_BREAK         4
+#define DOCT_CURSOR             5
+#define DOCT_MARKER             6
+#define DOCT_PMT                7
+#define DOCT_CLEAR              8
+#define DOCT_PAGE_LEN           9
+#define DOCT_LEFT_MARGIN        10
+#define DOCT_RIGHT_MARGIN       11
+#define DOCT_HEADER             12
+#define DOCT_FOOTER             13
+#define DOCT_INDENT             14
+#define DOCT_FOREGROUND         15
+#define DOCT_BACKGROUND         16
+#define DOCT_DFT_FOREGROUND     17
+#define DOCT_DFT_BACKGROUND     18
+#define DOCT_WORD_WRAP          19
+#define DOCT_HIGHLIGHT          20
+#define DOCT_BLINK              21
+#define DOCT_INVERT             22
+#define DOCT_UNDERLINE          23
+#define DOCT_SHIFTED_X          24
+#define DOCT_SHIFTED_Y          25
+#define DOCT_CURSOR_MOVEMENT    26
+#define DOCT_ANCHOR             27
+#define DOCT_LINK               28
+#define DOCT_BTTN               29
+#define DOCT_DATA               30
+#define DOCT_CHECK_BOX          31
+#define DOCT_LST                32
+#define DOCT_MACRO              33
+#define DOCT_MENU_VAL           34
+#define DOCT_HEX_ED             35
+#define DOCT_TREE               36
+#define DOCT_SPRITE             37
+#define DOCT_INS_BIN            38
+#define DOCT_INS_BIN_SIZE       39
+#define DOCT_SONG               40
+#define DOCT_HTML_CODE          41
+#define DOCT_ERROR              42
+
+#define DOCT_TYPES_NUM          43
+
+//CDocEntry.type flags upper bits
+#define DOCET_BLINK             ATTRF_BLINK
+#define DOCET_INVERT            ATTRF_INVERT
+#define DOCET_SEL               ATTRF_SEL
+#define DOCET_UNDERLINE         ATTRF_UNDERLINE
+#define DOCG_BL_IV_UL           0xB0000000
+
+#define DOCEt_BLINK             ATTRf_BLINK
+#define DOCEt_INVERT            ATTRf_INVERT
+#define DOCEt_SEL               ATTRf_SEL
+#define DOCEt_UNDERLINE         ATTRf_UNDERLINE
+
+#define DOCG_DBL_BUF_FLAGS      (DOCF_OVERSTRIKE|DOCF_PLAIN_TEXT|\
+                DOCF_PLAIN_TEXT_TABS|DOCF_SIZE_MIN|DOCF_NO_CURSOR|\
+                DOCF_FORM|DOCF_DBL_DOLLARS|DOCF_DONT_SWAP_OUT|\
+                DOCF_DO_FULL_REFRESH|DOCF_BORDER_DOC|DOCF_HIDE_CURSOR|\
+                DOCF_DONT_HIGHLIGHT_CURSOR|DOCF_CARRIAGE_RETURN)
+
+//CDocEntry.de_flags.  These first 16 are arg=
+#define DOCEF_TAG               1
+#define DOCEF_LEN               2
+#define DOCEF_AUX_STR           4
+#define DOCEF_DEFINE            8
+#define DOCEF_HTML_LINK         0x10
+#define DOCEF_LEFT_EXP          0x20
+#define DOCEF_LEFT_MACRO        0x40
+#define DOCEF_RIGHT_EXP         0x80
+#define DOCEF_RIGHT_MACRO       0x100
+#define DOCEF_HAS_BIN           0x200
+#define DOCEF_BIN_PTR_LINK      0x400
+#define DOCEF_RAW_TYPE          0x800
+#define DOCEF_SHIFTED_X         0x1000
+#define DOCEF_SHIFTED_Y         0x2000
+#define DOCEF_SCROLLING_X       0x4000
+#define DOCEF_USER_DATA         0x8000
+
+//CDocEntry.de_flags.  These are +/- flags
+#define DOCEF_LEFT_CB           0x10000
+#define DOCEF_LEFT_IN_STR       0x20000
+#define DOCEF_RIGHT_CB          0x40000
+#define DOCEF_RIGHT_IN_STR      0x80000
+#define DOCEF_LEFT_X            0x100000
+#define DOCEF_CENTER_X          0x200000
+#define DOCEF_RIGHT_X           0x400000
+#define DOCEF_TOP_Y             0x800000
+#define DOCEF_CENTER_Y          0x1000000
+#define DOCEF_BOTTOM_Y          0x2000000
+//HL...UL
+#define DOCEF_TAG_CB            0x100000000
+#define DOCEF_PAGE_REL_Y        0x200000000
+#define DOCEF_MARGIN_REL_X      0x400000000
+#define DOCEF_WIN_REL           0x800000000
+#define DOCEF_LINK              0x1000000000
+#define DOCEF_ESC               0x2000000000 //Send <ESC> (Exit and Save)
+#define DOCEF_QUIT              0x4000000000 //Send <SHIFT-ESC> (Abort)
+#define DOCEF_FROM_START        0x8000000000
+#define DOCEF_HAS_BORDER        0x10000000000
+#define DOCEF_SOLID_BORDER      0x20000000000
+#define DOCEF_BORDER_PLOT       0x40000000000
+#define DOCEF_CHECKED_COLLAPSED 0x80000000000 //Checked or Collapsed
+#define DOCEF_CHECK_COLLAPSABLE 0x100000000000
+#define DOCEF_REFRESH_DATA      0x200000000000
+#define DOCEF_UPDATE_DATA       0x400000000000
+//DOCEF_DEREF_DATA is confusing. DocForm() makes doc_e->data point to members
+//of class. For ints, it derefs doc_e->data as a ptr.  For strings, it doesn't.
+#define DOCEF_DEREF_DATA        0x800000000000
+#define DOCEF_REMALLOC_DATA     0x1000000000000
+#define DOCEF_HAS_TERMINATOR    0x2000000000000
+#define DOCEF_ZERO_BASED        0x4000000000000
+#define DOCEF_HOLD              0x8000000000000
+#define DOCEF_TREE              0x10000000000000
+#define DOCEF_LST               0x20000000000000
+#define DOCEF_SKIP              0x40000000000000
+#define DOCEF_POPUP             0x80000000000000
+#define DOCEF_SKIP_IN_FORM      0x100000000000000
+#define DOCEF_FILTER_SKIP       0x200000000000000
+#define DOCEF_NO_CLICK_ON       0x400000000000000
+#define DOCEF_DONT_DRAW         0x800000000000000 //only works on sprites
+#define DOCEF_DFT_LEN           0x1000000000000000
+#define DOCEF_DFT_RAW_TYPE      0x2000000000000000
+
+#define DOCEG_HAS_ALLOC         (DOCEF_TAG|DOCEF_AUX_STR|DOCEF_DEFINE|\
+  DOCEF_HTML_LINK|DOCEF_LEFT_MACRO|DOCEF_RIGHT_MACRO|DOCEF_BIN_PTR_LINK|\
+  DOCEF_REMALLOC_DATA)
+
+#define DOCEG_HAS_ARG           ((DOCEG_HAS_ALLOC&~DOCEF_REMALLOC_DATA)|\
+  DOCEF_LEN|DOCEF_LEFT_EXP|DOCEF_RIGHT_EXP|DOCEF_HAS_BIN|DOCEF_RAW_TYPE|\
+  DOCEF_SHIFTED_X|DOCEF_SHIFTED_Y|DOCEF_SCROLLING_X|DOCEF_USER_DATA)
+
+#define DOCEG_DONT_EDIT (DOCEF_DEFINE|DOCEF_HTML_LINK|\
+  DOCEF_AUX_STR|DOCEF_BIN_PTR_LINK|DOCEF_SCROLLING_X|DOCEF_TAG_CB)
+
+//These are ident to Doc flags
+#define DOCEF_HIGHLIGHT         0x4000000
+#define DOCEF_WORD_WRAP         0x8000000
+#define DOCEF_BLINK             ATTRF_BLINK
+#define DOCEF_INVERT            ATTRF_INVERT
+#define DOCEF_SEL               ATTRF_SEL
+#define DOCEF_UNDERLINE         ATTRF_UNDERLINE
+#define DOCEf_HIGHLIGHT         26
+#define DOCEf_WORD_WRAP         27
+#define DOCEf_BLINK             ATTRf_BLINK
+#define DOCEf_INVERT            ATTRf_INVERT
+#define DOCEf_SEL               ATTRf_SEL
+#define DOCEf_UNDERLINE         ATTRf_UNDERLINE
+
+//CDocEntry.de_flags.  These first 16 are arg=
+#define DOCEf_TAG               0
+#define DOCEf_LEN               1
+#define DOCEf_AUX_STR           2
+#define DOCEf_DEFINE            3
+#define DOCEf_HTML_LINK         4
+#define DOCEf_LEFT_EXP          5
+#define DOCEf_LEFT_MACRO        6
+#define DOCEf_RIGHT_EXP         7
+#define DOCEf_RIGHT_MACRO       8
+#define DOCEf_HAS_BIN           9
+#define DOCEf_BIN_PTR_LINK      10
+#define DOCEf_RAW_TYPE          11
+#define DOCEf_SHIFTED_X         12
+#define DOCEf_SHIFTED_Y         13
+#define DOCEf_SCROLLING_X       14
+#define DOCEf_USER_DATA         15
+
+//CDocEntry.de_flags.  These are +/- flags
+#define DOCEf_LEFT_CB           16
+#define DOCEf_LEFT_IN_STR       17
+#define DOCEf_RIGHT_CB          18
+#define DOCEf_RIGHT_IN_STR      19
+#define DOCEf_LEFT_X            20
+#define DOCEf_CENTER_X          21
+#define DOCEf_RIGHT_X           22
+#define DOCEf_TOP_Y             23
+#define DOCEf_CENTER_Y          24
+#define DOCEf_BOTTOM_Y          25
+//HL...UL
+#define DOCEf_TAG_CB            32
+#define DOCEf_PAGE_REL_Y        33
+#define DOCEf_MARGIN_REL_X      34
+#define DOCEf_WIN_REL           35
+#define DOCEf_LINK              36
+#define DOCEf_ESC               37 //Send <ESC> (Exit and Save)
+#define DOCEf_QUIT              38 //Send <SHIFT-ESC> (Abort)
+#define DOCEf_FROM_START        39
+#define DOCEf_HAS_BORDER        40
+#define DOCEf_SOLID_BORDER      41
+#define DOCEf_BORDER_PLOT       42
+#define DOCEf_CHECKED_COLLAPSED 43 //Checked or Collapsed
+#define DOCEf_CHECK_COLLAPSABLE 44
+#define DOCEf_REFRESH_DATA      45
+#define DOCEf_UPDATE_DATA       46
+#define DOCEf_DEREF_DATA        47
+#define DOCEf_REMALLOC_DATA     48
+#define DOCEf_HAS_TERMINATOR    49
+#define DOCEf_ZERO_BASED        50
+#define DOCEf_HOLD              51
+#define DOCEf_TREE              52
+#define DOCEf_LST               53
+#define DOCEf_SKIP              54
+#define DOCEf_POPUP             55
+#define DOCEf_SKIP_IN_FORM      56
+#define DOCEf_FILTER_SKIP       57
+#define DOCEf_NO_CLICK_ON       58
+#define DOCEf_DONT_DRAW         59 //only works on sprites
+#define DOCEf_DFT_LEN           60
+#define DOCEf_DFT_RAW_TYPE      61
+#define DOCEf_FLAGS_NUM         62
+
+public class CDocBin
+{
+  CDocBin *next,*last;
+  I32   tmp_use_cnt,renum_num;
+  U8    *tag;
+  U0    start;
+  U32   num,flags,size,use_cnt;
+  U0    end;
+  U8    *data;
+#assert !($&7)
+};
+
+#define DOC_SCROLL_SPEED        8
+
+#define DOCSS_NORMAL            0
+#define DOCSS_SINGLE_QUOTE      1
+#define DOCSS_DBL_QUOTE         2
+#define DOCSS_COMMENT           3
+#define DOCSS_CPP_Z_COMMENT     4
+
+#define DOC_ATTR_DFT_TEXT       WHITE<<4+BLACK
+#define DOC_COLOR_ALT_TEXT      LTGRAY
+#define DOC_COLOR_LINK          RED
+#define DOC_COLOR_MACRO         LTBLUE
+#define DOC_COLOR_ANCHOR        DKGRAY
+#define DOC_COLOR_TREE          PURPLE
+#define DOC_COLOR_PMT           GREEN
+#define DOC_COLOR_COMMENT       GREEN
+#define DOC_COLOR_BIN           LTGREEN
+#define DOC_COLOR_STR           BROWN
+#define DOC_COLOR_CHAR_CONST    BROWN
+#define DOC_COLOR_EXPORT_SYS_SYM LTPURPLE
+#define DOC_COLOR_DEFINE_STR    CYAN
+#define DOC_COLOR_GLBL_VAR      LTCYAN
+#define DOC_COLOR_CLASS         LTBLUE
+#define DOC_COLOR_FUN           PURPLE
+#define DOC_COLOR_KEYWORD       BLUE
+#define DOC_COLOR_REG           LTRED
+
+public class CDocSettings
+{
+  U32   final_u32_attr;
+  I16   left_margin,right_margin,indent;
+  U16   page_len,header,footer;
+  I8    shifted_x,shifted_y;
+  U8    state,comment_depth,paren_depth,brace_depth,
+        cur_text_attr,dft_text_attr;
+};
+
+#define DOC_DFT                 I32_MIN
+
+public class CDocEntryBase
+{
+//This is a shortened structure for
+  //cmds like the text cmd which
+  //don't require the full CDocEntry structure.
+  CDocEntryBase *next,*last;
+  U8    *tag;
+  union {
+    U8  type_u8; //this stores the code
+    U32 type; //these store attr flags
+  };
+  I32   page_line_num;
+  I64   de_flags;
+  I32   x,y;
+  U32   min_col,max_col;
+  CDocSettings settings;
+  I64   user_data;
+#assert !($&7)
+};
+
+#define DOCE_LEN_DFT    64
+
+public class CDocEntry:CDocEntryBase
+{
+  union {
+    I64 attr;
+    I64 cursor_x_offset;
+    I64 (*left_cb)(CDoc *doc,CDocEntry *doc_e);
+    I64 left_exp;
+  };
+  U8    *left_macro;
+
+  union {
+    I64 cursor_y_offset;
+    I64 (*right_cb)(CDoc *doc,CDocEntry *doc_e);
+    I64 right_exp;
+  };
+  U8    *right_macro;
+
+  U8    *(*tag_cb)(CDoc *doc,CDocEntry *doc_e,CTask *mem_task);
+  U8    *define_str,
+        *aux_str,
+        *bin_ptr_link,
+        *html_link,
+        *my_fmt_data;
+  I64   hex_ed_width;
+  I32   scroll_len,
+        len, //DOCE_LEN_DFT
+        bin_num;
+  U8    raw_type,pad[3];
+  CDocBin *bin_data;
+  U8    *data;
+#assert !($&7)
+};
+
+//DocForm() DocMenu() DocEd() PopUpMenu()
+#define DOF_SIZE_MIN            0x01
+#define DOF_INTERCEPT_TASK_END  0x02
+#define DOF_DONT_HOME           0x04
+#define DOF_WIN_MAX             0x08
+#define DOF_DONT_TEXT_ATTR      0x10
+#define DOF_DONT_WINMGR_SYNC    0x20
+#define DOF_DONT_SHOW           0x40
+//Combines with  Editor Flags
+
+class CEdFindText
+{
+  U8    find_text[STR_LEN] format "$DA-P,"
+        "A=\"Find        :%s\"$\n",
+        replace_text[STR_LEN] format "$DA-P,"
+        "A=\"Replace     :%s\"$\n";
+  Bool  replace                 format "$CB,\"Replace\"$\n",
+        scan_fwd                format "$CB,\"Fwd\"$\n",
+        scan_sel_text           format "$CB,\"Selection\"$\n",
+        match_case              format "$CB,\"Match Case\"$\n",
+        whole_labels            format "$CB,\"Whole Labels\"$\n",
+        local_var               format "$CB,\"Rename Local Var\"$\n",
+        pmt,pad;
+  I64   filter_lines            format "$DA,A=\"Filter Lines:%d\"$\n";
+};
+
+class CEdFileName
+{
+  CDirContext *dirc;
+  U8    name[256] format "$DA-P,LEN=255,A=\"FileName:%s\"$";
+};
+
+//Ed()
+#define EDF_BAIL                0x100
+#define EDF_COLLAPSE            0x200
+#define EDF_UNCOLLAPSE          0x400
+#define EDF_WAS_WRITE           0x800 //Was exit ESC or SHIFT_ESC?
+//Combines with Document Flags
+
+#define EDf_BAIL                8
+#define EDf_COLLAPSE            9
+#define EDf_UNCOLLAPSE          10
+#define EDf_WAS_WRITE           11
+
+// DOC header flags
+#define DOCF_PLAIN_TEXT         0x1
+#define DOCF_PLAIN_TEXT_TABS    0x2 //has '\t', not DOCT_TAB
+#define DOCF_AUTO_SAVE          0x4
+#define DOCF_NO_CURSOR          0x8
+#define DOCF_CARRIAGE_RETURN    0x10
+#define DOCF_DBL_DOLLARS        0x20
+#define DOCF_COLOR_NAMES        0x40
+//Reserved x1
+#define DOCF_BORDER_DOC         0x100
+#define DOCF_FORM               0x200
+#define DOCF_SIZE_MIN           0x400
+#define DOCF_HIDE_CURSOR        0x800  //use DocCursor
+#define DOCF_DONT_HIGHLIGHT_CURSOR 0x1000 //use DocHighlightCursor
+#define DOCF_NO_SCROLL_BARS     0x2000 //use DocScroll
+#define DOCF_ALLOW_UNDO         0x4000
+#define DOCF_DONT_SHOW          0x8000
+#define DOCF_HAS_SONG           0x10000
+#define DOCF_MORE               0x20000
+#define DOCF_BWD_MOVEMENT       0x40000
+#define DOCF_NULL_GRAB_SCROLL   0x80000
+#define DOCF_DONT_SWAP_OUT      0x100000
+#define DOCF_DO_FULL_REFRESH    0x200000
+#define DOCF_BREAK_UNLOCKED     0x400000
+//Reserved x1
+#define DOCF_HIGHLIGHT          DOCEF_HIGHLIGHT
+#define DOCF_WORD_WRAP          DOCEF_WORD_WRAP
+#define DOCF_BLINK              DOCEF_BLINK
+#define DOCF_INVERT             DOCEF_INVERT
+#define DOCF_SEL                DOCEF_SEL
+#define DOCF_UNDERLINE          DOCEF_UNDERLINE
+
+#define DOCF_OVERSTRIKE         0x100000000
+#define DOCF_IN_DOLLAR          0x200000000
+#define DOCF_SUPERSCRIPT_MODE   0x400000000
+#define DOCF_SUBSCRIPT_MODE     0x800000000
+#define DOCF_UNDO_DIRTY         0x1000000000
+
+#define DOCf_PLAIN_TEXT         0
+#define DOCf_PLAIN_TEXT_TABS    1 //has '\t', not DOCT_TAB
+#define DOCf_AUTO_SAVE          2
+#define DOCf_NO_CURSOR          3
+#define DOCf_CARRIAGE_RETURN    4
+#define DOCf_DBL_DOLLARS        5
+#define DOCf_COLOR_NAMES        6
+//Reserved x1
+#define DOCf_BORDER_DOC         8
+#define DOCf_FORM               9
+#define DOCf_SIZE_MIN           10
+#define DOCf_HIDE_CURSOR        11  //use DocCursor
+#define DOCf_DONT_HIGHLIGHT_CURSOR 12  //use DocHighlightCursor
+#define DOCf_NO_SCROLL_BARS     13  //use DocScroll
+#define DOCf_ALLOW_UNDO         14
+#define DOCf_DONT_SHOW          15
+#define DOCf_HAS_SONG           16
+#define DOCf_MORE               17
+#define DOCf_BWD_MOVEMENT       18
+#define DOCf_NULL_GRAB_SCROLL   19
+#define DOCf_DONT_SWAP_OUT      20
+#define DOCf_DO_FULL_REFRESH    21
+#define DOCf_BREAK_UNLOCKED     22
+//Reserved x1
+
+#define DOCf_HIGHLIGHT          DOCEf_HIGHLIGHT
+#define DOCf_WORD_WRAP          DOCEf_WORD_WRAP
+#define DOCf_BLINK              DOCEf_BLINK
+#define DOCf_INVERT             DOCEf_INVERT
+#define DOCf_SEL                DOCEf_SEL
+#define DOCf_UNDERLINE          DOCEf_UNDERLINE
+
+#define DOCf_OVERSTRIKE         32
+#define DOCf_IN_DOLLAR          33
+#define DOCf_SUPERSCRIPT_MODE   34
+#define DOCf_SUBSCRIPT_MODE     35
+#define DOCf_UNDO_DIRTY         36
+
+//locked flags
+#define DOClf_LOCKED            0
+class CDocUndo
+{
+  CDocUndo *next,*last;
+  I64   size,doc_flags,time_stamp;
+  U8    *body;
+};
+
+//See DocMenu()
+#define DOCM_CANCEL             (-1)
+
+#define DOC_SIGNATURE_VAL       'DocS'
+
+#define RECALCt_NORMAL          0x00
+#define RECALCt_FIND_CURSOR     0x01
+#define RECALCt_TO_SCRN         0x02
+#define RECALCG_MASK            0xFF
+
+#define RECALCF_HAS_CURSOR      0x100
+#define RECALCF_ADD_CURSOR      0x200
+#define RECALCF_TO_HTML         0x400
+
+public class CDoc //Linked Text File header
+{//See Doc for documentation.
+  CDocEntryBase head;
+  I64   flags,locked_flags;
+  CDocEntry *cur_entry,*old_cur_entry;
+  I32   cur_col,old_cur_col,
+        line_start_col,top_line_num,
+        dollar_buf_size,dollar_buf_ptr;
+  U8    *dollar_buf; //When entering $ cmds, it buffers them until the end $.
+
+  CTask *win_task,*mem_task,*owning_task;
+  I32   page_line_num,undo_cnt,
+        x,y,min_x,max_x,min_y,max_y;
+  I64   line,col,best_d,
+        old_win_top,old_win_bottom,
+        old_win_left,old_win_right,
+        cmd_U8;
+  U32   doc_signature,cur_bin_num;
+  I64   max_entries,
+        updates_cnt;
+  CEdFindText *find_replace;
+
+  CEdFileName filename;
+  I64   file_attr;
+  I64   (*left_click_link)(CDoc *doc,CDocEntry *doc_e);
+  I64   (*right_click_link)(CDoc *doc,CDocEntry *doc_e);
+
+  //See ::/Apps/Psalmody/JukeBox.HC
+  U8    *user_put_data; //Passed to user_put_key() and user_put_s()
+  Bool  (*user_put_key)(CDoc *doc,U8 *data,I64 ch,I64 sc);
+  Bool  (*user_put_s)(CDoc *doc,U8 *data,U8 *st);
+
+  CDoc  *parent_doc; //(When browsing deeper, opening deeper docs.)
+  U64   desc; //8 characters. See DocBorderLstDraw().
+
+  CDocBin bin_head;
+  CDocSettings settings_head;
+  CDocUndo undo_head;
+
+  I64   user_data;
+#assert !($&7)
+};
+
+#help_index "Windows"
+/*
+Fs->win_inhibit mask
+
+Some inhibit actions on the task itself.
+Some inhibit actions if the focus task
+tries to do something.
+*/
+#define WIF_SELF_FOCUS          0x0001 //If active this task cannot have focus
+                //MENU          0x0002
+#define WIF_SELF_CTRLS          0x0004
+#define WIF_SELF_MS_L           0x0008
+                //MS_L_D        0x0010
+#define WIF_SELF_MS_R           0x0020
+                //MS_R_D        0x0040
+#define WIF_SELF_MS_WHEEL       0x0080 //Does nothing, yet
+#define WIF_SELF_BORDER         0x0100
+#define WIF_SELF_GRAB_SCROLL    0x0200
+#define WIF_SELF_DOC            0x0400
+#define WIF_SELF_ODE            0x0800
+#define WIF_SELF_KEY_DESC       0x1000
+                //FOCUS         0x00010000
+#define WIF_FOCUS_TASK_MENU     0x00020000
+#define WIF_FOCUS_TASK_CTRLS    0x00040000
+#define WIF_FOCUS_TASK_MS_L     0x00080000
+#define WIF_FOCUS_TASK_MS_L_D   0x00100000
+#define WIF_FOCUS_TASK_MS_R     0x00200000
+#define WIF_FOCUS_TASK_MS_R_D   0x00400000
+#define WIF_FOCUS_TASK_MS_WHEEL 0x00800000 //Does nothing, yet
+#define WIF_FOCUS_TASK_BORDER   0x01000000
+#define WIF_FOCUS_TASK_GRAB_SCROLL 0x02000000
+
+#define WIG_DBL_CLICK           (WIF_FOCUS_TASK_MS_L_D|WIF_FOCUS_TASK_MS_R_D)
+#define WIG_TASK_DFT            (WIF_FOCUS_TASK_MENU|WIG_DBL_CLICK|\
+        0xFFFF-WIF_SELF_DOC-WIF_SELF_ODE)
+#define WIG_NO_FOCUS_TASK_DFT   (WIG_TASK_DFT-WIF_SELF_BORDER\
+        -WIF_SELF_MS_L-WIF_SELF_MS_R-WIG_DBL_CLICK)
+#define WIG_USER_TASK_DFT       WIF_SELF_KEY_DESC
+
+#define WIf_SELF_FOCUS          0
+#define WIf_SELF_CTRLS          2
+#define WIf_SELF_MS_L           3
+#define WIf_SELF_MS_R           5
+#define WIf_SELF_MS_WHEEL       7
+#define WIf_SELF_BORDER         8
+#define WIf_SELF_GRAB_SCROLL    9
+#define WIf_SELF_DOC            10
+#define WIf_SELF_ODE            11
+#define WIf_SELF_KEY_DESC       12
+#define WIf_FOCUS_TASK_MENU     17
+#define WIf_FOCUS_TASK_CTRLS    18
+#define WIf_FOCUS_TASK_MS_L     19
+#define WIf_FOCUS_TASK_MS_L_D   20
+#define WIf_FOCUS_TASK_MS_R     21
+#define WIf_FOCUS_TASK_MS_R_D   22
+#define WIf_FOCUS_TASK_MS_WHEEL 23
+#define WIf_FOCUS_TASK_BORDER   24
+#define WIf_FOCUS_TASK_GRAB_SCROLL 25
+
+class CWinMgrTimingGlbls
+{
+  I64   last_total_jiffies,
+        last_idle_pt_hits[MP_PROCESSORS_NUM],
+        last_swap_cnter[MP_PROCESSORS_NUM];
+  F64   last_calc_idle_time,calc_idle_delta_time;
+  I64   calc_idle_cnt;
+};
+
+#define WINMGR_FPS      (30000.0/1001)
+#define WINMGR_PERIOD   (1001/30000.0)
+
+public class CWinMgrGlbls
+{
+  I64   updates;
+  F64   ode_time,
+        last_ode_time,
+        fps,            //You can read but not write this. You have no control.
+        ideal_refresh_tS,
+        last_refresh_tS;
+  CWinMgrTimingGlbls *t;
+  Bool  show_menu,grab_scroll,grab_scroll_closed;
+};
+
+#help_index "AutoComplete"
+#define ACf_INIT_IN_PROGRESS    0
+#define AC_FILLINS_NUM 10
+public class CAutoCompleteGlbls
+{
+  I64   num_words;
+  CHashTable *hash_table;
+  U8    *cur_word;
+  I64   flags;
+  CTask *task;
+  I64   partial_len,num_fillins,
+        fillin_hits     [AC_FILLINS_NUM+1];
+  CHashAC *fillin_matches[AC_FILLINS_NUM+1];
+};
+
+#help_index "AutoComplete/Dictionary"
+#define ACD_WORD_FILENAME       "/Adam/AutoComplete/ACWords.DATA.Z"
+#define ACD_DEF_FILENAME        "/Adam/AutoComplete/ACDefs.DATA"
+#define ACD_DEF_FILENAME_Z      "/Adam/AutoComplete/ACDefs.DATA.Z"
+
+#define ACD_H1                  0
+#define ACD_H1_END              1
+#define ACD_DEF                 2
+#define ACD_DEF_END             3
+#define ACD_PRONUNCIATION       4
+#define ACD_PRONUNCIATION_END   5
+#define ACD_POS                 6
+#define ACD_POS_END             7
+#define ACD_EXTRA               8
+#define ACD_EXTRA_END           9
+#define ACD_BLK_SIZE            0x4000
+
+#define ACD_END_CHAR            0x00
+#define ACD_WORD_CHAR           0x01
+#define ACD_DEF_CHAR            0x02
+#define ACD_PRONUNCIATION_CHAR  0x03
+#define ACD_POS_CHAR            0x04
+#define ACD_EXTRA_CHAR          0x05
+
+#define ACD_FILLINS_NUM 10
+public class CAutoCompleteDictGlbls
+{
+  U8    *word_lst;
+  I64   word_lst_size,num_words,num_fillins;
+  U8    *fillins[ACD_FILLINS_NUM];
+  Bool  has_words,has_defs;
+};
+
+#help_index "Compiler/Directive"
+//Compiler Option()s
+//You might need to do #exe {Option();}
+//Note: The #exe stmt is lexed-ahead,
+//so it takes effect earlier than you might expect.
+#define OPTf_ECHO               0x00
+#define OPTf_TRACE              0x01
+#define OPTf_WARN_UNUSED_VAR    0x10 //Applied to funs, not stmts
+#define OPTf_WARN_PAREN         0x11 //Warn unnecessary parens
+#define OPTf_WARN_DUP_TYPES     0x12 //Warn dup local var type stmts
+#define OPTf_WARN_HEADER_MISMATCH 0x13
+#define OPTf_EXTERNS_TO_IMPORTS 0x20
+#define OPTf_KEEP_PRIVATE       0x21
+#define OPTf_NO_REG_VAR         0x22  //Applied to funs, not stmts
+#define OPTf_GLBLS_ON_DATA_HEAP 0x23
+//Disable 10-byte float consts for pi,log2_10,log10_2,loge_2
+#define OPTf_NO_BUILTIN_CONST   0x24 //Applied to funs, not stmts
+#define OPTf_USE_IMM64          0x25 //Not completely implemented
+
+#define OPTF_ECHO               (1<<OPTf_ECHO)
+
+#help_index "Compiler/Intermediate Code"
+//See ST_RAW_TYPES
+#define RT_I0           2
+#define RT_U0           3
+#define RT_I8           4
+#define RT_U8           5
+#define RT_I16          6
+#define RT_U16          7
+#define RT_I32          8
+#define RT_U32          9
+#define RT_I64          10
+#define RT_PTR          10 //Signed to allow negative err codes. DOCM_CANCEL
+#define RT_U64          11
+#define RT_F32          12 //Not implemented
+#define RT_UF32         13 //Not implemented, Fictitious
+#define RT_F64          14
+#define RT_UF64         15 //Fictitious
+#define RT_RTS_NUM      16
+#define RTF_UNSIGNED    1
+#define RTG_MASK        0xFF
+
+#define MDf_STK         8
+#define MDf_IMM         9
+#define MDf_REG         10
+#define MDf_DISP        11
+#define MDf_SIB         12
+#define MDf_RIP_DISP32  13
+
+#define MDF_NULL        0x0000
+#define MDF_STK         0x0100
+#define MDF_IMM         0x0200
+#define MDF_REG         0x0400
+#define MDF_DISP        0x0800
+#define MDF_SIB         0x1000
+#define MDF_RIP_DISP32  0x2000
+#define MDG_MASK        0xFF00
+#define MDG_REG_DISP_SIB        (MDF_REG|MDF_DISP|MDF_SIB)
+#define MDG_DISP_SIB_RIP        (MDF_DISP|MDF_SIB|MDF_RIP_DISP32)
+#define MDG_REG_DISP_SIB_RIP    (MDF_REG|MDG_DISP_SIB_RIP)
+
+#define ICF_RES_TO_F64                  0x000000001
+#define ICF_RES_TO_INT                  0x000000002
+#define ICF_ARG1_TO_F64                 0x000000004
+#define ICF_ARG1_TO_INT                 0x000000008
+#define ICF_ARG2_TO_F64                 0x000000010
+#define ICF_ARG2_TO_INT                 0x000000020
+#define ICF_USE_F64                     0x000000040
+#define ICF_USE_UNSIGNED                0x000000080
+#define ICF_USE_INT                     0x000000100 //highest priority
+#define ICF_RES_NOT_USED                0x000000200
+#define ICF_CODE_FINAL                  0x000000400
+#define ICF_BY_VAL                      0x000000800 //By value, not ref.
+#define ICF_SHORT_JMP                   0x000001000
+#define ICF_PUSH_RES                    0x000002000
+#define ICF_PASS_TRACE                  0x000004000
+#define ICF_RES_WAS_STK                 0x000008000
+#define ICF_ARG1_WAS_STK                0x000010000
+#define ICF_ARG2_WAS_STK                0x000020000
+#define ICF_PUSH_CMP                    0x000040000 //for 50<i<j<=100 exps
+#define ICF_POP_CMP                     0x000080000 //for 50<i<j<=100 exps
+#define ICF_SWAP                        0x000100000
+#define ICf_DONT_PUSH_FLOAT0            21 // 3bits
+#define ICf_DONT_POP_FLOAT0             24 // 3bits
+#define ICF_ALT_TEMPLATE                0x008000000
+#define ICF_LOCK                        0x010000000
+#define ICf_LOCK                        28
+#define ICF_NO_RIP                      0x020000000
+#define ICF_DEL_PREV_INS                0x040000000
+#define ICF_PREV_DELETED                0x080000000
+#define ICF_DONT_RESTORE                0x100000000
+#define ICG_NO_CVT_MASK                 0x1FFFFFF00
+
+#define IC_BODY_SIZE                    0x83
+
+#define ECF_HAS_PUSH_CMP                0x01 //for 50<i<j<=100 exps
+
+U16 class CICType
+{
+  U8    raw_type,mode;
+};
+
+class CICArg
+{
+  CICType type;
+  U16   reg; //low is reg, high is index_reg+scale<<6
+  I64   disp;
+};
+
+class CICTreeLinks
+{
+  CHashClass *arg1_class,*arg2_class;
+  CIntermediateCode *arg1_tree,*arg2_tree;
+  CHashClass *class2;
+};
+
+class CIntermediateCodeBase
+{
+  CIntermediateCode *next,*last;
+  U16   ic_code,
+        ic_precedence;
+  I16   ic_cnt,
+        ic_last_start;
+};
+
+class CIntermediateCode:CIntermediateCodeBase
+{
+  I64   ic_flags,
+        ic_data,
+        ic_line;
+  CHashClass *ic_class,*ic_class2;
+  CICArg arg1,arg2,res;
+  U8    arg1_type_pointed_to; //Used for IST_ASSIGN and IST_DEREF ic_codes.
+  union {
+    U8 ic_body[IC_BODY_SIZE];
+    //Tree Links are created in OptPass012.  An ADD opcode, for example,
+    //points back to its two earlier arg CIntermediateCode's.
+
+    //Tree links get destroyed during Pass789A when they get overwrites
+    //by machine code.  (Saves room to union the output machine code buffer
+    //with these links, since they are not needed after pass4.
+
+    //Tree links are used during passes 012 and 3 for determining types.
+    CICTreeLinks t;
+  };
+#assert !($&7)
+};
+
+class CPrsStk
+{
+  I64   ptr,
+        stk[255],
+        ptr2,
+        stk2[255];
+};
+
+#define CMT_LABEL               0
+#define CMT_ASM_LABEL           1
+#define CMT_GOTO_LABEL          2
+#define CMT_STR_CONST           3
+#define CMT_JMP_TABLE           4
+#define CMT_FLOAT_CONSTS        5
+#define CMT_ARRAY_DIM           6
+#define CMT_HASH_ENTRY          7
+
+#define CMF_POP_CMP             0x01
+#define CMF_DEFINED             0x02
+#define CMF_I8_JMP_TABLE        0x04
+#define CMF_U8_JMP_TABLE        0x08
+#define CMF_I16_JMP_TABLE       0x10
+#define CMF_U16_JMP_TABLE       0x20
+
+#define CM_CONSTS_NUM           16
+
+class CCodeMisc
+{
+  CCodeMisc *next,*last,*fwd,*dft,*begin;
+  U8    *str;
+  U32   type,flags;
+  I64   use_cnt;
+  U8    *addr;
+  union {
+    I64 st_len;         //STR_CONST
+    I64 num_consts;     //FLOAT_CONSTS
+    I64 range;
+    I64 rip;            //ASM_LABEL
+  }
+  union {
+    CCodeMisc **jmp_table;
+    F64 *float_consts;
+    CArrayDim *dim;
+    CHash *h;
+  };
+};
+
+#help_index "Compiler/Assembler"
+#define IEF_OP_SIZE16           0x001
+#define IEF_OP_SIZE32           0x002
+#define IEF_PLUS_OPCODE         0x004
+#define IEF_DONT_SWITCH_MODES   0x008
+#define IEF_DFT                 0x010
+#define IEF_NOT_IN_64_BIT       0x020
+#define IEF_48_REX              0x040
+#define IEF_REX_ONLY_R8_R15     0x080
+#define IEF_REX_XOR_LIKE        0x100
+#define IEF_STI_LIKE            0x200
+#define IEF_ENDING_ZERO         0x400
+
+//Slash value
+#define SV_R_REG        8
+#define SV_I_REG        9
+#define SV_STI_LIKE     10 //uasm_slash_val only.
+#define SV_NONE         11
+class CInst
+{
+  U8    ins_entry_num, //This entry num in opcode hash entry
+        opcode_cnt,
+        opcode[4];
+  U16   flags;
+  U8    slash_val,uasm_slash_val,opcode_modifier,
+        arg1,arg2,
+        size1,size2,//Size in bits
+        pad;
+};
+
+//x86 opcodes
+#define OC_OP_SIZE_PREFIX       0x66
+#define OC_ADDR_SIZE_PREFIX     0x67
+#define OC_LOCK_PREFIX          0xF0
+#define OC_NOP                  0x90
+#define OC_BPT                  0xCC
+#define OC_CALL                 0xE8
+#define OC_JMP_REL8             0xEB
+#define OC_NOP2                 (OC_NOP<<8+OC_OP_SIZE_PREFIX)
+
+#define PUSH_C_REGS PUSH RAX PUSH RCX PUSH RDX PUSH RBX PUSH R8 PUSH R9
+#define POP_C_REGS POP R9 POP R8 POP RBX POP RDX POP RCX POP RAX
+
+#define PUSH_REGS PUSH RAX PUSH RCX PUSH RDX PUSH RBX PUSH RBP PUSH RSI \
+PUSH RDI PUSH R8 PUSH R9 PUSH R10 PUSH R11 PUSH R12 PUSH R13 PUSH R14 PUSH R15
+#define POP_REGS POP R15 POP R14 POP R13 POP R12 POP R11 POP R10 POP R9 \
+POP R8 POP RDI POP RSI POP RBP POP RBX POP RDX POP RCX POP RAX
+
+#define REG_RAX         0
+#define REG_RCX         1
+#define REG_RDX         2
+#define REG_RBX         3
+#define REG_RSP         4
+#define REG_RBP         5
+#define REG_RSI         6
+#define REG_RDI         7
+#define REG_R8          8
+#define REG_REGS_NUM    16
+
+#define REG_RIP         16      //Used by compiler, not really it's num
+//Be careful: RBPu8, RSPu8, RSIu8, RDIu8 are 20-24
+#define REG_NONE        32      //noreg flag sets it to this
+#define REG_ALLOC       33      //reg flag sets it to this
+#define REG_UNDEF       I8_MIN
+
+#define REGG_CLOBBERED          0x013F //RAX,RCX,RDX,RBX,R8
+#define REGG_SAVED              0x0030 //RBP,RSP
+#define REGG_STK_TMP            0x0200 //R9
+#define REGG_LOCAL_VARS         0xCCC0 //RSI,RDI,R10,R11,R14,R15
+#define REGG_LOCAL_NON_PTR_VARS 0x3000 //R12,R13
+
+#define AOT_BIN_BLK_BITS 16
+#define AOT_BIN_BLK_SIZE (1<<AOT_BIN_BLK_BITS)
+
+class CAOTBinBlk
+{
+  CAOTBinBlk *next;
+  U8    body[AOT_BIN_BLK_SIZE];
+};
+
+I64 class CAbsCntsI64
+{
+  U16   abs_addres, //Only odd/even matters. Cnt of absolute addres in an exp.
+        c_addres; //Only odd/even matters. Cnt of C addres in an exp.
+  U32   externs; //Only nonzero matters. Some regions have externs banned.
+};
+
+class CAsmUndefHash
+{//Only place created is Exp Parser when an undef is found in an ASM exp.
+  CAsmUndefHash *next;
+  CHashExport   *hash;
+};
+
+class CAsmNum
+{
+  I64   i;
+  U8    *machine_code;
+  CAsmUndefHash *local_asm_undef_hash,*glbl_asm_undef_hash;
+  CAbsCntsI64 abs_cnts;
+};
+
+class CAsmNum2
+{
+  CAsmNum num;
+  I64   U8_cnt,rel;
+  Bool  imm_flag;
+};
+
+class CAsmIns
+{
+  CInst *tmpins;
+  CAsmNum2 imm,disp;
+  I64   U8_cnt,last_opcode_U8,
+        REX,ModrM,SIB;
+  Bool  has_REX,has_ModrM,has_SIB,
+        has_addr_prefix,
+        has_operand_prefix,
+        is_dft,pad[2];
+};
+
+class CAsmArg
+{
+  CAsmNum num;
+  I64   seg,size, //Size in bytes
+        reg1,reg2,
+        reg1_type,reg2_type,
+        scale;
+  Bool  indirect,imm_or_off_present,just_seg,pad[5];
+};
+
+class CAsmUnresolvedRef
+{
+  CAsmUnresolvedRef *next;
+  I64   type,line_num;
+  U8    *machine_code;
+  I64   rip,rel_rip;
+  CAOT  *aot;
+  U8    *str;   //Only for import glbls
+  CAsmUndefHash *asm_undef_hash;
+  Bool  U8_avail,
+        imm_flag;//Only for import glbls
+};
+
+//Opcode Modifier
+#define OM_NO 0
+#define OM_CB 1
+#define OM_CW 2
+#define OM_CD 3
+#define OM_CP 4
+#define OM_IB 5
+#define OM_IW 6
+#define OM_ID 7
+
+#define ARGT_NONE       0
+#define ARGT_REL8       1
+#define ARGT_REL16      2
+#define ARGT_REL32      3
+
+#define ARGT_IMM8       4
+#define ARGT_IMM16      5
+#define ARGT_IMM32      6
+#define ARGT_IMM64      7
+
+#define ARGT_UIMM8      8
+#define ARGT_UIMM16     9
+#define ARGT_UIMM32     10
+#define ARGT_UIMM64     11
+
+#define ARGT_R8         12
+#define ARGT_R16        13
+#define ARGT_R32        14
+#define ARGT_R64        15
+
+#define ARGT_RM8        16
+#define ARGT_RM16       17
+#define ARGT_RM32       18
+#define ARGT_RM64       19
+
+#define ARGT_M8         20
+#define ARGT_M16        21
+#define ARGT_M32        22
+#define ARGT_M64        23
+
+#define ARGT_M1632      24 // Not implemented
+#define ARGT_M16N32     25 // Not implemented
+#define ARGT_M16N16     26 // Not implemented
+#define ARGT_M32N32     27 // Not implemented
+
+#define ARGT_MOFFS8     28
+#define ARGT_MOFFS16    29
+#define ARGT_MOFFS32    30
+#define ARGT_MOFFS64    31
+
+#define ARGT_AL         32
+#define ARGT_AX         33
+#define ARGT_EAX        34
+#define ARGT_RAX        35
+
+#define ARGT_CL         36
+#define ARGT_DX         37
+#define ARGT_SREG       39
+
+#define ARGT_SS         40
+#define ARGT_DS         41
+#define ARGT_ES         42
+#define ARGT_FS         43
+
+#define ARGT_GS         44
+#define ARGT_CS         45
+#define ARGT_ST0        46
+#define ARGT_STI        47
+
+#define ARGT_MM         48 // Not implemented
+#define ARGT_MM32       49 // Not implemented
+#define ARGT_MM64       50 // Not implemented
+#define ARGT_XMM        51 // Not implemented
+
+#define ARGT_XMM32      52 // Not implemented
+#define ARGT_XMM64      53 // Not implemented
+#define ARGT_XMM128     54 // Not implemented
+#define ARGT_XMM0       55 // Not implemented
+
+#help_index "Compiler/Internal;Hash/System"
+#define OCF_ALIAS       1
+public class CHashOpcode:CHash
+{
+  U16   inst_entry_cnt,
+        oc_flags,pad[2];
+  CInst ins[1];
+};
+
+#help_index "Compiler/Intermediate Code"
+#define IEF_GOTO_LABEL          1
+class CAOTImportExport
+{
+  CAOTImportExport *next,*last;
+  I64   rip,flags;
+  CAOT  *aot;
+  U8    *str,
+        *src_link,
+        type,pad[7];
+};
+
+#define AAT_ADD_U8              0
+#define AAT_SUB_U8              1
+#define AAT_ADD_U16             2
+#define AAT_SUB_U16             3
+#define AAT_ADD_U32             4
+#define AAT_SUB_U32             5
+#define AAT_ADD_U64             6
+#define AAT_SUB_U64             7
+class CAOTAbsAddr
+{
+  CAOTAbsAddr *next;
+  I64   rip;
+  U8    type,pad[7];
+};
+
+class CAOTHeapGlblRef
+{
+  CAOTHeapGlblRef *next;
+  I64   rip;
+};
+
+class CAOTHeapGlbl
+{
+  CAOTHeapGlbl *next;
+  U8    *str;
+  I64   size;
+  CAOTHeapGlblRef *references;
+};
+
+class CAOT
+{
+  CAOT  *next,*last;
+  U8    *buf;
+  I64   rip,rip2,
+        aot_U8s,
+        max_align_bits,org;
+  CAOT  *parent_aot;
+  CAOTImportExport *next_ie,*last_ie;
+  CAOTAbsAddr *abss;
+  CAOTHeapGlbl *heap_glbls;
+};
+
+class CStreamBlk
+{
+  CStreamBlk *next,*last;
+  U8    *body;
+};
+
+class CCodeCtrl
+{
+  CCodeCtrl *coc_next;
+  CCodeMisc *coc_next_misc,*coc_last_misc;
+  CIntermediateCodeBase coc_head;
+};
+
+#help_index "Compiler/Lex"
+#define __DATE__ #exe{StreamPrint("\"%D\"",Now);}
+#define __TIME__ #exe{StreamPrint("\"%T\"",Now);}
+#define __LINE__ #exe{StreamPrint("%d",\
+        Fs->last_cc->lex_include_stk->line_num);}
+#define __CMD_LINE__ #exe{StreamPrint("%d",Fs->last_cc->flags&CCF_CMD_LINE &&\
+        Fs->last_cc->lex_include_stk->depth<1);}
+#define __FILE__ #exe{StreamPrint("\"%s\"",\
+        Fs->last_cc->lex_include_stk->full_name);}
+#define __DIR__  #exe{StreamDir;}
+
+#define LFSF_DOC        1
+#define LFSF_DEFINE     2
+class CLexFile
+{
+  CLexFile *next;
+  U8    *buf,
+        *buf_ptr;
+  I64   line_num,flags;
+  U8    *full_name,
+        *line_start;
+  CDoc  *doc;
+  CDocEntry *cur_entry;
+  I32   depth;
+  U8    last_U16,pad[3];
+};
+
+class CAOTCtrl
+{
+  I64   rip; //Inst ptr
+  CAsmArg arg1,arg2;
+  CAOTBinBlk *bin;
+  I64   num_bin_U8s,
+        max_align_bits,org;
+  CAsmUnresolvedRef *local_unresolved,*glbl_unresolved;
+  CAOTAbsAddr *abss;
+  CAOTHeapGlbl *heap_glbls;
+  I64   lst_col,lst_last_rip;
+  U8    *last_label,*lst_last_line;
+  CLexFile *lst_last_lfn;
+  I64   seg_size;
+  Bool  lst;
+};
+
+//Tokens
+#define TK_EOF          0
+#define TK_SUPERSCRIPT  0x001
+#define TK_SUBSCRIPT    0x002
+#define TK_NORMALSCRIPT 0x003
+#define TK_IDENT        0x100
+#define TK_STR          0x101
+#define TK_I64          0x102
+#define TK_CHAR_CONST   0x103
+#define TK_F64          0x104
+#define TK_PLUS_PLUS    0x105
+#define TK_MINUS_MINUS  0x106
+#define TK_DEREFERENCE  0x107
+#define TK_DBL_COLON    0x108
+#define TK_SHL          0x109
+#define TK_SHR          0x10A
+#define TK_EQU_EQU      0x10B
+#define TK_NOT_EQU      0x10C
+#define TK_LESS_EQU     0x10D
+#define TK_GREATER_EQU  0x10E
+#define TK_AND_AND      0x10F
+#define TK_OR_OR        0x110
+#define TK_XOR_XOR      0x111
+#define TK_SHL_EQU      0x112
+#define TK_SHR_EQU      0x113
+#define TK_MUL_EQU      0x114
+#define TK_DIV_EQU      0x115
+#define TK_AND_EQU      0x116
+#define TK_OR_EQU       0x117
+#define TK_XOR_EQU      0x118
+#define TK_ADD_EQU      0x119
+#define TK_SUB_EQU      0x11A
+#define TK_IF           0x11B
+#define TK_IFDEF        0x11C
+#define TK_IFNDEF       0x11D
+#define TK_IFAOT        0x11E
+#define TK_IFJIT        0x11F
+#define TK_ENDIF        0x120
+#define TK_ELSE         0x121
+#define TK_MOD_EQU      0x122
+#define TK_DOT_DOT      0x123
+#define TK_ELLIPSIS     0x124
+#define TK_INS_BIN      0x125
+#define TK_INS_BIN_SIZE 0x126
+#define TK_TKS_NUM      0x127
+
+class CLexHashTableContext
+{
+  CLexHashTableContext *next;
+  I64   old_flags,hash_mask;
+  CHashFun *local_var_lst,
+        *fun;
+  CHashTable *hash_table_lst,
+        *define_hash_table,
+        *local_hash_table,
+        *glbl_hash_table;
+};
+
+//CmpCtrl flags
+#define CCF_CMD_LINE            0x001
+#define CCF_PMT                 0x002
+#define CCf_PMT                 1
+#define CCF_QUESTION_HELP       0x004
+#define CCF_DONT_FREE_BUF       0x008
+#define CCF_NO_DEFINES          0x010
+#define CCF_IN_IF               0x020
+#define CCF_JUST_LOAD           0x040
+#define CCF_KEEP_NEW_LINES      0x080
+#define CCF_KEEP_DOT            0x100
+#define CCF_KEEP_SIGN_NUM       0x200
+#define CCF_KEEP_AT_SIGN        0x400
+#define CCF_NO_CHAR_CONST       0x800
+#define CCf_PASS_TRACE_PRESENT  12
+#define CCF_NOT_CONST           0x0000020000
+#define CCF_NO_REG_OPT          0x0000040000
+#define CCF_IN_QUOTES           0x0000080000
+#define CCF_EXE_BLK             0x0000100000
+#define CCF_HAS_MISC_DATA       0x0000200000
+#define CCF_HAS_RETURN          0x0000400000
+#define CCF_ASM_EXPRESSIONS     0x0000800000
+#define CCF_UNRESOLVED          0x0001000000
+#define CCF_LOCAL               0x0002000000
+#define CCF_FUN_EXP             0x0004000000
+#define CCf_FUN_EXP             26
+#define CCF_POSTINC             0x0008000000
+#define CCF_POSTDEC             0x0010000000
+#define CCF_PREINC              0x0020000000
+#define CCF_PREDEC              0x0040000000
+#define CCF_ARRAY               0x0080000000
+#define CCF_RAX                 0x0100000000
+#define CCF_USE_LAST_U16        0x0200000000
+#define CCf_USE_LAST_U16        33
+#define CCF_LAST_WAS_DOT        0x0400000000
+#define CCF_AOT_COMPILE         0x0800000000
+#define CCf_AOT_COMPILE         35
+#define CCF_NO_ABSS             0x1000000000
+#define CCF_PAREN               0x2000000000
+#define CCf_PAREN               37
+#define CCF_CLASS_DOL_OFFSET    0x4000000000
+#define CCF_DONT_MAKE_RES       0x8000000000
+
+public class CCmpCtrl
+{
+  CCmpCtrl *next,*last;
+  I64   token,
+        flags,
+        cur_i64;
+  F64   cur_f64;
+  U8    *cur_str;
+  I64   cur_str_len,
+        class_dol_offset;
+  U8    *dollar_buf;
+  I64   dollar_cnt;
+  U8    *cur_help_idx;
+  I64   last_U16,
+        min_line,max_line,last_line_num,
+        lock_cnt;
+  U32   *char_bmp_alpha_numeric;
+  CLexHashTableContext htc;
+  CHashGeneric *hash_entry;
+  CAbsCntsI64 abs_cnts;
+  CAsmUndefHash *asm_undef_hash;
+  CMemberLst *local_var_entry;
+  CCodeMisc *lb_leave;
+  U8    *cur_buf_ptr;
+  CLexFile *lex_include_stk,
+        *lex_prs_stk,
+        *fun_lex_file;
+  CStreamBlk *next_stream_blk,*last_stream_blk;
+  CAOT  *aot;
+
+  I64   pass,opts,pass_trace,saved_pass_trace,
+        error_cnt,warning_cnt;
+
+  //For intermediate codes with multiple float ops (int<->float conversions)
+  I64   cur_ic_float_op_num,last_ic_float_op_num;
+  CIntermediateCode *last_float_op_ic;
+  Bool  last_dont_pushable,last_dont_popable,last_float_op_pos,
+        dont_push_float,pad[4];
+
+  CCodeCtrl coc;
+  CPrsStk *ps;
+  CAOTCtrl *aotc;
+  I64   aot_depth,pmt_line;
+#assert !($&7)
+};
+
+#help_index "Compiler"
+public class CCmpGlbls
+{
+  CHashTable *asm_hash;
+  CHashClass *internal_types[RT_RTS_NUM];
+  CIntermediateCode ic_nop;
+  U32   *dual_U16_tokens1,*dual_U16_tokens2,*dual_U16_tokens3,
+        *binary_ops;
+  I64   num_reg_vars,num_non_ptr_vars,
+        stk_tmps_mask,reg_vars_mask,non_ptr_vars_mask;
+  U8    *to_reg_vars_map,*non_ptr_vars_map;
+  I64   size_arg_mask[9],
+        compiled_lines;
+};
+
+#help_index "Debugging/Unassemble"
+class CUAsmGlbls
+{
+  CInst **table_16_32,**table_64;
+  I64   table_16_32_entries,
+        table_64_entries,
+        ins64_arg_mask,
+        signed_arg_mask,
+        mem_arg_mask;
+};
+
+#help_index "Devices;PCI"
+class CPCIDev
+{
+  CPCIDev *next,*last;
+  U16   vendor,dev_id;
+  U8    bus,dev,fun,pad,
+        sub_code,base_code,pad[6],
+        *vendor_str,*dev_id_str;
+};
+
+#help_index "Devices;File/System;PCI"
+public class CATARep
+{
+  CATARep *next;
+  I64   num,type,base0,base1,unit,irq;
+};
+
+//See ::/Doc/Credits.DD.
+#define ATA_NOP                 0x00
+#define ATA_DEV_RST             0x08
+#define ATA_PACKET              0xA0
+#define ATA_READ_NATIVE_MAX     0xF8
+#define ATA_READ_NATIVE_MAX_EXT 0x27
+#define ATA_SET_MAX             0xF9
+#define ATA_SET_MAX_EXT         0x37
+#define ATA_READ_MULTI          0xC4
+#define ATA_READ_MULTI_EXT      0x29
+#define ATA_WRITE_MULTI         0xC5
+#define ATA_WRITE_MULTI_EXT     0x39
+#define ATA_ID_DEV              0xEC
+
+#define ATAS_ERR        0x01
+#define ATAS_DRQ        0x08
+#define ATAS_DF         0x20
+#define ATAS_DRDY       0x40
+#define ATAS_BSY        0x80
+
+#define ATAR0_DATA      0
+#define ATAR0_FEAT      1
+#define ATAR0_NSECT     2
+#define ATAR0_SECT      3
+#define ATAR0_LCYL      4
+#define ATAR0_HCYL      5
+#define ATAR0_SEL       6
+#define ATAR0_STAT      7
+#define ATAR0_CMD       7
+#define ATAR1_CTRL      2
+
+#help_index "File/FileNames"
+#define FILEMASK_JIT    "*.HC*;*.HH*"
+#define FILEMASK_AOT    "*.HC*;*.HH*;*.PRJ*"
+#define FILEMASK_SRC    "*.HC*;*.HH*;*.IN*;*.PRJ*"
+#define FILEMASK_DD     FILEMASK_SRC ";*.DD*"
+#define FILEMASK_TXT    FILEMASK_DD ";*.TXT*"
+#define FILEMASK_GR     "*.GR*"
+
+#help_index "File/Low Level"
+#define BLK_SIZE_BITS   9
+#define BLK_SIZE        (1<<BLK_SIZE_BITS)
+#define DVD_BLK_SIZE    (4*BLK_SIZE)
+#define DVD_BOOT_LOADER_SIZE    DVD_BLK_SIZE*1
+#define INVALID_CLUS (-1)
+
+class CMBRPrt
+{
+  U8    active, //0x80=active  0x00=inactive
+        start_head;
+  U16   start_cyl;
+  U8    type,
+        end_head;
+  U16   end_cyl;
+  U32   offset, //Sects between MBR and first sect
+        size;   //Sects in drv
+};
+
+class CMasterBoot
+{
+  U8    code[440];
+  U32   media_id;
+  U16   zero;
+  CMBRPrt p[4];
+  U16   signature; //AA55
+};
+
+class CRedSeaBoot
+{
+  U8    jump_and_nop[3],
+        signature,reserved[4]; //MBR_PT_REDSEA=0x88. Distinguish from real FAT32
+  I64   drv_offset,     //For CD/DVD image copy.
+        sects,
+        root_clus,
+        bitmap_sects,
+        unique_id;
+  U8    code[462];
+  U16   signature2;     //0xAA55
+};
+
+class CFAT32Boot
+{
+  U8    jump_and_nop[3],
+        oem_name[8];
+  U16   bytes_per_sect;
+  U8    sects_per_clus;
+  U16   reserved_sects;
+  U8    copies_of_fat;
+  U16   max_root_dir_entries,   //Not used
+        old_sects_in_drv;       //Not used
+  U8    media_desc;             //F64 for hard disk
+  U16   old_sects_per_fat,      //Not used
+        sects_per_track,
+        num_heads;
+  U32   hidden_sects,
+        sects,
+        sects_per_fat;
+  U16   flags,
+        version;
+  U32   root_clus;
+  U16   file_system_info_sect,
+        backup_boot_sect;
+  U8    reserved[12],
+        log_drv_num,
+        unused,
+        ext_signature; //0x29
+  U32   serial_num;
+  U8    vol_name[11],
+        fat_name[8],
+        code[420];
+  U16   signature;
+};
+
+class CFAT32FileInfoSect
+{
+  U32   signature1;
+  U8    unknown[480];
+  U32   signature2,
+        free_clus,
+        most_recently_alloced;
+  U8    reserved[12];
+  U32   signature3;
+};
+
+class CFAT32DirEntry
+{
+  U8    name[11],
+        attr,
+        NTres,
+        CrtTimeTenth;
+  U16   CrtTime,
+        CrtDate,
+        LstAccDate,
+        clus_hi,
+        WrtTime,
+        WrtDate,
+        clus_lo;
+  U32   size;
+};
+
+class CFAT32DirEntryLong
+{
+  U8    ord;
+  U16   name1[5];
+  U8    attr,
+        type,
+        xsum;
+  U16   name2[6],
+        zero,
+        name3[2];
+};
+
+#define FAT32_ENTRIES_PER_BLK   (BLK_SIZE/sizeof(CFAT32DirEntry))
+#define FAT32_ENTRIES_BITS      Bsf(FAT32_ENTRIES_PER_BLK)
+
+class CPalindromeU16
+{
+  U16   little,big;
+};
+
+class CPalindromeU32
+{
+  U32   little,big;
+};
+
+class CATAPITrack
+{
+  U16   track_info_len;
+  U8    track_lo,
+        session_lo,
+        reserved;
+  U16   misc1;
+  U8    misc2;
+  U32   track_start,
+        next_writable,
+        free_blks;
+  union {
+    U32 fixed_packet_size;
+    U32 blocking_factor;
+  };
+  union {
+    U32 track_size;
+    U32 rzone_end;
+  };
+  U32   last_recorded;
+  U8    track_hi,
+        session_hi;
+  U16   reserved;
+  U32   read_compatibility,
+        next_layer_jmp,
+        last_layer_jmp;
+};
+
+//ISO9660
+#define ISOT_BOOT_RECORD        0
+#define ISOT_PRI_VOL_DESC       1
+#define ISOT_SUPPLEMENTARY_DESC 2
+#define ISOT_VOL_DRV_DESC       3
+#define ISOT_TERMINATOR         255
+
+class CISODirEntry
+{
+  U8 pad[2];
+  CPalindromeU32 loc;
+  U8 pad[24];
+};
+
+class CISOPriDesc
+{
+  U8    type,
+        id[5],
+        version,
+        pad[73];
+  CPalindromeU32 vol_space_size;
+  U8    pad[32];
+  CPalindromeU16 vol_set_size;
+  CPalindromeU16 vol_seq_num;
+  CPalindromeU16 log_block_size;
+  U8    pad[20];
+  CISODirEntry root_dir_record;
+  U8    pad[128],
+        publisher_id[128],
+        pad[435],
+        file_structure_version,
+        pad[1166];
+};
+
+//Red Sea Attributes
+//See ST_FILE_ATTRS
+#define RS_ATTR_READ_ONLY       0x01 //R
+#define RS_ATTR_HIDDEN          0x02 //H
+#define RS_ATTR_SYSTEM          0x04 //S
+#define RS_ATTR_VOL_ID          0x08 //V
+#define RS_ATTR_DIR             0x10 //D
+#define RS_ATTR_ARCHIVE         0x20 //A
+#define RS_ATTR_LONG_NAME       (RS_ATTR_READ_ONLY|RS_ATTR_HIDDEN|\
+                                RS_ATTR_SYSTEM|RS_ATTR_VOL_ID)
+#define RS_ATTR_LONG_NAME_MASK  (RS_ATTR_LONG_NAME|RS_ATTR_DIR|RS_ATTR_ARCHIVE)
+#define RS_ATTR_DELETED         0x100 //X
+#define RS_ATTR_RESIDENT        0x200 //T
+#define RS_ATTR_COMPRESSED      0x400 //Z
+#define RS_ATTR_CONTIGUOUS      0x800 //C
+#define RS_ATTR_FIXED           0x1000 //F
+
+#help_index "File/CD DVD"
+//Media types for DVDImageWrite()
+#define MT_CD           1
+#define MT_DVD          2
+
+#help_index "File/Low Level;File/Program Routines"
+//CDirEntry flags (Used by FileMgr())
+#define CDIR_FILENAME_LEN       38 //Must include terminator zero
+public class CDirEntry
+{
+  CDirEntry *next,*parent,*sub;
+  U8    *full_name;
+  I64   user_data,user_data2;
+
+  U0    start;
+  U16   attr;
+  U8    name[CDIR_FILENAME_LEN];
+  I64   clus,size;
+  CDate datetime;
+};
+#define CDIR_SIZE (sizeof(CDirEntry)-offset(CDirEntry.start))
+
+#help_index "File/Program Routines"
+//File Util Flags
+//See ST_FILE_UTIL_FLAGS
+#define FUf_RECURSE             0
+#define FUf_DIFF                1
+#define FUf_DEL                 1
+#define FUf_IGNORE              2
+#define FUf_ALL                 3
+#define FUf_CANCEL              4
+#define FUf_REPLACE             5
+#define FUf_RISKY               5
+#define FUf_PUBLIC              6
+#define FUf_MAP                 7
+#define FUf_EXPAND              8
+#define FUf_SINGLE              9
+#define FUf_JUST_DIRS           10
+#define FUf_JUST_FILES          11
+#define FUf_JUST_TXT            12
+#define FUf_JUST_DD             13
+#define FUf_JUST_SRC            14
+#define FUf_JUST_AOT            15
+#define FUf_JUST_JIT            16
+#define FUf_JUST_GR             17
+#define FUf_Z_OR_NOT_Z          18
+#define FUf_CLUS_ORDER  19
+#define FUf_SCAN_PARENTS        20
+#define FUf_FLATTEN_TREE        21
+#define FUf_WHOLE_LABELS        22
+#define FUf_WHOLE_LABELS_BEFORE 23
+#define FUf_WHOLE_LABELS_AFTER  24
+
+#define FUF_RECURSE             0x0000001 //r
+#define FUF_DIFF                0x0000002 //d
+#define FUF_DEL                 0x0000002 //d
+#define FUF_IGNORE              0x0000004 //i
+#define FUF_ALL                 0x0000008 //a
+#define FUF_CANCEL              0x0000010 //c
+#define FUF_REPLACE             0x0000020 //R
+#define FUF_RISKY               0x0000020 //R
+#define FUF_PUBLIC              0x0000040 //p
+#define FUF_MAP                 0x0000080 //m
+#define FUF_EXPAND              0x0000100 //x
+#define FUF_SINGLE              0x0000200 //s
+#define FUF_JUST_DIRS           0x0000400 //D
+#define FUF_JUST_FILES          0x0000800 //F
+#define FUF_JUST_TXT            0x0001000 //T
+#define FUF_JUST_DD             0x0002000 //$
+#define FUF_JUST_SRC            0x0004000 //S
+#define FUF_JUST_AOT            0x0008000 //A
+#define FUF_JUST_JIT            0x0010000 //J
+#define FUF_JUST_GR             0x0020000 //G
+#define FUF_Z_OR_NOT_Z          0x0040000 //Z
+#define FUF_CLUS_ORDER  0x0080000 //O Move disk head one direction
+#define FUF_SCAN_PARENTS        0x0100000 //P
+#define FUF_FLATTEN_TREE        0x0200000 //f
+#define FUF_WHOLE_LABELS        0x0400000 //l
+#define FUF_WHOLE_LABELS_BEFORE 0x0800000 //lb
+#define FUF_WHOLE_LABELS_AFTER  0x1000000 //la
+
+#define FUG_FILES_FIND  (FUF_RECURSE|FUF_SINGLE|FUF_CLUS_ORDER|\
+  FUF_JUST_DIRS|FUF_JUST_FILES|FUF_JUST_TXT|FUF_JUST_DD|\
+  FUF_JUST_SRC|FUF_JUST_AOT|FUF_JUST_JIT|FUF_JUST_GR|FUF_FLATTEN_TREE)
+#define FUG_FILE_FIND   (FUF_JUST_DIRS|FUF_JUST_FILES|FUF_Z_OR_NOT_Z|\
+  FUF_SCAN_PARENTS)
+
+#help_index "File/Low Level"
+//See ST_BLKDEV_TYPES
+#define BDT_NULL                0
+#define BDT_RAM                 1
+#define BDT_ATA                 2
+#define BDT_ISO_FILE_READ       3
+#define BDT_ISO_FILE_WRITE      4
+#define BDT_ATAPI               5
+#define BDT_TYPES_NUM           6
+
+#define BDF_REMOVABLE           0x001
+#define BDF_INITIALIZED         0x002
+#define BDF_READ_ONLY           0x004
+#define BDF_READ_ONLY_OVERRIDE  0x008
+#define BDF_LAST_WAS_WRITE      0x010
+#define BDF_READ_CACHE          0x020
+#define BDF_FMT                 0x040
+#define BDF_INIT_IN_PROGRESS    0x080
+#define BDF_EXT_SIZE            0x100
+
+#define BDf_REMOVABLE           0
+#define BDf_INITIALIZED         1
+#define BDf_READ_ONLY           2
+#define BDf_READ_ONLY_OVERRIDE  3
+#define BDf_LAST_WAS_WRITE      4
+#define BDf_READ_CACHE          5
+#define BDf_FMT                 6
+#define BDf_INIT_IN_PROGRESS    7
+#define BDf_EXT_SIZE            8
+
+//locked flags
+#define BDlf_LOCKED             0
+
+#define BLKDEVS_NUM             26
+#define BD_SIGNATURE_VAL        'BDSV'
+public class CBlkDev
+{
+  CBlkDev *lock_fwding; //If two blkdevs on same controller, use just one lock
+  I64   locked_flags;
+  U32   bd_signature,
+        type,flags;
+  U8    first_drv_let,unit,pad[2];
+  U32   base0,base1,
+        blk_size;
+  I64   drv_offset,init_root_dir_blks,
+        max_blk;
+  U16   *dev_id_record;
+  U8    *RAM_dsk,
+        *file_dsk_name;
+  CFile *file_dsk;
+  CTask *owning_task;
+  F64   last_time;
+  U32   max_reads,max_writes;
+};
+
+//Drive locked_flags
+#define DVlf_LOCKED     0
+
+//See ST_DRV_TYPES
+#define FSt_NULL        0
+#define FSt_REDSEA      1 //Supported
+#define FSt_FAT32       2 //Supported except for short names, to some degree
+#define FSt_ISO9660     3 //Not Supported
+#define FSt_NTFS        4 //Not Supported
+#define FSt_UNKNOWN     5
+#define FSt_TYPES_NUM   6
+#define FSG_TYPE_MASK   0x7FFF
+//File system type flags
+#define FStf_DISABLE    15
+
+#define MBR_PT_FAT12    0x01
+#define MBR_PT_FAT32a   0x0B
+#define MBR_PT_FAT32b   0x0C
+#define MBR_PT_FAT32c   0x1B
+#define MBR_PT_FAT32d   0x1C
+#define MBR_PT_FAT32e   0x8B
+#define MBR_PT_FAT32f   0x8C
+#define MBR_PT_NTFS     0x07
+#define MBR_PT_REDSEA   0x88
+
+class CFreeLst
+{
+  CFreeLst *next,*last;
+  I64   start,size;
+};
+
+#define DRVS_NUM                26
+
+#define DRV_SIGNATURE_VAL       'DVSV'
+public class CDrv
+{
+//Don't access ->drv_let directly in case a drive has been remapped.
+  //Use Drv2Let().
+  I64   locked_flags;
+  U32   dv_signature;
+  U8    drv_let,pad;
+  U16   fs_type;
+  I64   drv_offset,
+        size,
+        prt_num,
+        file_system_info_sect,
+        fat1,fat2,
+        root_clus,
+        data_area,
+        spc; //sectors per clus
+  CDate fat32_local_time_offset;
+  CTask *owning_task;
+  CBlkDev *bd;
+
+  CFAT32FileInfoSect *fis;
+  I64   fat_blk_dirty,
+        cur_fat_blk_num;
+  U32   *cur_fat_blk;
+  CFreeLst *next_free,*last_free;
+};
+
+#define DSK_CACHE_HASH_SIZE     0x2000
+
+class CCacheBlk
+{
+  CCacheBlk *next_lru,*last_lru;
+  CCacheBlk *next_hash,*last_hash;
+  CDrv  *dv;
+  I64   blk;
+  U8    body[BLK_SIZE];
+};
+
+#help_index "File/System"
+#define DFT_ISO_FILENAME        "::/Tmp/CDDVD.ISO"
+#define DFT_ISO_C_FILENAME      "::/Tmp/CDDVD.ISO.C"
+
+public class CBlkDevGlbls
+{
+  CBlkDev *blkdevs;
+  U8    *dft_iso_filename;      //"::/Tmp/CDDVD.ISO"
+  U8    *dft_iso_c_filename;    //"::/Tmp/CDDVD.ISO.C"
+  U8    *tmp_filename;
+  U8    *home_dir;
+  CCacheBlk *cache_base,*cache_ctrl,**cache_hash_table;
+  I64   cache_size,read_cnt,write_cnt;
+  CDrv  *drvs,*let_to_drv[32];
+  I64   mount_ide_auto_cnt,
+        ins_base0,ins_base1;    //Install cd/dvd controller.
+  U8    boot_drv_let,first_hd_drv_let,first_dvd_drv_let;
+  Bool  dvd_boot_is_good,ins_unit,pad[3];
+};
+
+#help_index "File/Internal"
+public class CDirContext
+{
+  CDrv  *old_dv,*dv;
+  U8    *old_dir,*mask;
+};
+
+#help_index "File/CFile"
+#define FFB_NEXT_BLK            I64_MAX
+
+#define FF_WRITE                1
+#define FF_NEW_FILE             2
+#define FF_BUF_DIRTY            4
+#define FF_NEEDS_WRITE          8
+#define FF_CONTIGUOUS           16
+#define FF_USE_OLD_DATETIME     32
+
+public class CFile //See ::/Demo/Dsk/DataBase.HC.
+{
+  I64   flags;
+  CDirEntry de;
+  CDrv  *dv;
+  I64   fblk_num,clus,file_clus_num,max_blk;
+  U8    *clus_buf;
+};
+
+#help_index "Memory/Heap"
+#define _CFG_HEAP_DBG FALSE
+
+#if _CFG_HEAP_DBG
+class CMemUnused
+{
+  CHeapCtrl *hc;
+  U8    *caller1,*caller2;
+  CMemUnused *next;
+  I64   size;
+};
+class CMemUsed
+{
+  CHeapCtrl *hc;
+  U8    *caller1,*caller2;
+  CMemUsed *next,*last;
+  I64   size;
+  U0    start;
+};
+#else
+class CMemUnused
+{
+  U0    hc;
+  U0    caller1,caller2;
+  CMemUnused *next;
+  I64   size;
+};
+class CMemUsed
+{
+  CHeapCtrl *hc;
+  U0    caller1,caller2;
+  U0    next,last;
+  I64   size;
+  U0    start;
+};
+#endif
+
+#help_index "Memory/BlkPool"
+#help_file "::/Doc/Pags"
+
+#define MBS_USED_SIGNATURE_VAL          'MBUs'
+#define MBS_UNUSED_SIGNATURE_VAL        'MBUn'
+class CMemBlk
+{
+  CMemBlk *next,*last;
+  U32   mb_signature,pags;
+};
+
+#define MRT_UNUSED      0
+#define MRT_RAM         1
+#define MRT_DEV         2
+
+class CMemRange
+{
+  CMemRange *next,*last;
+  U32   type,flags;
+  U8    *base;
+  I64   size;
+};
+
+#define MEM_PAG_BITS            9
+#define MEM_PAG_SIZE            (1<<MEM_PAG_BITS)
+#define MEM_HEAP_HASH_SIZE      1024
+#define MEM_FREE_PAG_HASH_SIZE  0x100
+//It is common to MAlloc() exact powers of two.  There is some overhead.
+//We add 2 pags, so a request is not rounded-up to next power of two.
+#define MEM_EXTRA_HASH2_PAGS    2
+
+#define MEM_ADAM_STK            (MEM_PAG_SIZE*512) //Like 16384*MEM_PAG_SIZE
+#define MEM_SETH_STK            (MEM_PAG_SIZE*512)
+#define MEM_INTERRUPT_STK       (MEM_PAG_SIZE*512)
+#define MEM_DFT_STK             (MEM_PAG_SIZE*512)
+
+#define TASK_HASH_TABLE_SIZE    (1<<10)
+
+//locked flags
+#define BPlf_LOCKED             0
+public class CBlkPool
+{
+  I64   locked_flags,alloced_u8s,used_u8s;
+  CMemBlk *mem_free_lst,
+        *mem_free_2meg_lst, //This is for Sup1CodeScraps/Mem/Mem2Meg.HC.
+        *free_pag_hash[MEM_FREE_PAG_HASH_SIZE],
+        *free_pag_hash2[64-MEM_PAG_BITS];
+};
+
+#help_index "Memory/HeapCtrl"
+//locked flags
+#define HClf_LOCKED             0
+
+#define HEAP_CTRL_SIGNATURE_VAL 'HcSV'
+public class CHeapCtrl
+{
+  CBlkPool *bp;
+  U32   hc_signature,pad;
+  I64   locked_flags,alloced_u8s,used_u8s;
+  CTask *mem_task;
+  CMemBlk *next_mem_blk,*last_mem_blk;
+  CMemBlk *last_mergable;
+  CMemUnused *malloc_free_lst;
+  CMemUsed *next_um,*last_um;
+  CMemUnused *heap_hash[MEM_HEAP_HASH_SIZE/sizeof(U8 *)];
+};
+
+#help_index "Devices;Memory/Page Tables"
+public class CDevGlbls
+{
+  I64   *idt;
+  U8    *mem64_ptr;
+  U8    *uncached_alias; //Alias of lowest 4Gig.
+  U8    mp_apic_ids[MP_PROCESSORS_NUM];
+  CMemRange mem32_head;
+  CPCIDev pci_head;
+};
+
+#help_index "Graphics/Color;Graphics/Device Contexts"
+//Raster operations
+#define ROPB_EQU                        0x00
+#define ROPB_XOR                        0x01
+#define ROPB_COLLISION                  0x02
+#define ROPB_MONO                       0x03
+#define ROPBF_HALF_RANGE_COLOR          0x10
+#define ROPBF_TWO_SIDED                 0x20
+#define ROPBF_DITHER                    0x40
+#define ROPBF_PROBABILITY_DITHER        0x80
+
+#define ROP_EQU                         (ROPB_EQU<<8)
+#define ROP_XOR                         (ROPB_XOR<<8)
+#define ROP_COLLISION                   (ROPB_COLLISION<<8)
+#define ROP_MONO                        (ROPB_MONO<<8)
+
+//These are just for ROPF_PROBABILITY_DITHER
+//See DCLighting().
+#define ROPF_HALF_RANGE_COLOR           0x1000
+#define ROPF_TWO_SIDED                  0x2000
+
+//These always go in the c1.rop of a CColorROPU32
+#define ROPF_DITHER                     0x40000000
+#define ROPF_PROBABILITY_DITHER         0x80000000
+
+#help_index "Graphics/Color"
+#define TRANSPARENT             0xFF
+#define BLACK                   0
+#define BLUE                    1
+#define GREEN                   2
+#define CYAN                    3
+#define RED                     4
+#define PURPLE                  5
+#define BROWN                   6
+#define LTGRAY                  7
+#define DKGRAY                  8
+#define LTBLUE                  9
+#define LTGREEN                 10
+#define LTCYAN                  11
+#define LTRED                   12
+#define LTPURPLE                13
+#define YELLOW                  14
+#define WHITE                   15
+
+#define COLORS_NUM              16
+#define COLOR_INVALID           16
+#define COLOR_MONO              0xFF
+
+public U16 class CColorROPU16 //Don't use this, use CColorROPU32
+{
+  U8    color,rop;
+};
+public U32 class CColorROPU32
+{
+  CColorROPU16 c0,c1;
+};
+#define COLORROP_COLORS_MASK    0x00FF00FF
+#define COLORROP_NO_ROP0_MASK   0xFFFF00FF
+#define COLORROP_BITS           16
+public U32 class CBGR24
+{
+  U8    b,g,r,pad;
+};
+public I64 class CBGR48
+{
+  U16   b,g,r,pad;
+};
+
+#help_index "Keyboard Devices;Char/Input;StdIn"
+#define KBD_PORT        0x60
+#define KBD_CTRL        0x64
+public class CKbdStateGlbls
+{
+  I64   scan_code,      //See scan codes
+        last_down_scan_code,
+        cnt,            //Count of keys pressed since boot.
+        timestamp,      //Output: GetTSC when event.
+        new_key_timestamp; //Output: GetTSC when new key event.
+  CFifoU8 *fifo,*fifo2; //Private
+  CFifoI64 *scan_code_fifo;
+
+  //BitTest, Bt(), with a merged scan code.
+  //(Left and right shift merged, for example.)
+  U32   down_bitmap[8],
+//BitTest, Bt(), with an unmerged scan code.
+        down_bitmap2[8];
+
+  Bool  rst,            //Private: Reset KbdMs
+        irqs_working;   //Private
+};
+
+#help_index "Mouse"
+public class CMsHardStateGlbls
+{
+  CD3I64 pos,           //Position in pixels
+        prescale;
+  CD3   scale;
+  F64   speed;          //Output: How fast the user is moving it.
+  I64   timestamp,      //Output: GetTSC when event.
+        install_attempts, //Private
+        pkt_size;       //Private
+  CFifoU8 *fifo,*fifo2; //Private
+  Bool  bttns[5],
+        has_wheel,
+        has_ext_bttns,
+        evt,            //Private
+        installed,      //Private
+        install_in_progress, //Private
+        irqs_working;   //Private
+};
+
+public class CMsStateGlbls
+{
+  CD3I64 pos,           //Position in pixels
+        pos_text,       //Position in text rows,cols
+        presnap,
+        offset;
+  CD3   scale;
+  F64   speed;          //Output: How fast the user is moving it.
+  I64   timestamp;      //Output: GetTSC when event.
+  F64   dbl_time,       //Input: Time threshold for calling it a double click.
+        left_dbl_time,  //Private
+        right_dbl_time; //Private
+  Bool  lb,             //Left Bttn
+        rb,             //Right Bttn
+        show,
+        has_wheel,
+        left_dbl,       //Private
+        left_down_sent, //Private
+        right_dbl,      //Private
+        right_down_sent;//Private
+};
+
+public class CGridGlbls
+{
+  Bool  snap    format "$CB,\"Snap Grid\"$\n",
+        show    format "$CB,\"Show Grid\"$\n",
+        coord   format "$CB,\"Show Coordinates\"$\n";
+  U8    pad[5];
+  F64   x       format "$DA-TRM,A=\"X Spacing:%6.3f\"$\n",
+        y       format "$DA-TRM,A=\"Y Spacing:%6.3f\"$\n",
+        z       format "$DA-TRM,A=\"Z Spacing:%6.3f\"$\n",
+        x_offset format "$DA-TRM,A=\"X Offset :%6.3f\"$\n",
+        y_offset format "$DA-TRM,A=\"Y Offset :%6.3f\"$\n",
+        z_offset format "$DA-TRM,A=\"Z Offset :%6.3f\"$\n",
+        x_speed format "$DA-TRM,A=\"X Speed  :%6.3f\"$\n",
+        y_speed format "$DA-TRM,A=\"Y Speed  :%6.3f\"$\n",
+        z_speed format "$DA-TRM,A=\"Z Speed  :%6.3f\"$\n";
+};
+
+#help_index "Ctrls"
+#define CTRLT_GENERIC           0
+#define CTRLT_WIN_HSCROLL       1 //unique
+#define CTRLT_WIN_VSCROLL       2 //unique
+#define CTRLT_VIEWING_ANGLES    3 //unique
+
+#define CTRLF_SHOW              1
+#define CTRLF_BORDER            2
+#define CTRLF_CAPTURE_LEFT_MS   4
+#define CTRLF_CAPTURE_RIGHT_MS  8
+#define CTRLF_CLICKED           16
+
+#define WSSf_SET_TO_POS         0
+
+public class CWinScroll
+{
+  I64   min,pos,max;
+  U32   flags;
+  U8    color,pad[3];
+};
+
+public class CViewAngles
+{
+  I64   sx,sy,sz;
+  F64   ax,ay,az;
+  CColorROPU32 cx,cy,cz,cbd,cbg,cfg;
+};
+
+public class CCtrl
+{
+  CCtrl *next,*last;
+  CTask *win_task;
+  I64   type,flags;
+
+  //win pix coordinates
+  I64   left,right,top,bottom;
+
+  //scrn pix coordinates (derived)
+  I64   scrn_left,scrn_right,scrn_top,scrn_bottom;
+
+  U8    *state;
+
+  //called on resize
+  U0    (*update_derived_vals)(CCtrl *c);
+  U0    (*draw_it)(CDC *dc,CCtrl *c);
+
+  Bool  (*inside_ctrl)(CCtrl *c,I64 x,I64 y); //For nonbox shapes
+  U0    (*left_click)(CCtrl *c,I64 x,I64 y,Bool down);
+  U0    (*right_click)(CCtrl *c,I64 x,I64 y,Bool down);
+  U0    (*wheel_chg)(CCtrl *c,I64 delta);
+};
+
+#help_index "Menus"
+public class CMenuEntry
+{
+  CMenuEntry *next;
+  CMenuEntry *sub;
+  U8    name[32];
+  I64   msg_code,arg1,arg2;
+  Bool  checked,dir,pad[6];
+};
+
+public class CMenu
+{
+  CMenu *next;
+  CMenuEntry *sub;
+  CTask *task;
+  I64   flags;
+  U8    attr,pad[7];
+};
+
+#help_index "Task"
+class CBpt
+{
+  CBpt  *next;
+  U8    *addr,
+        val,pad[7];
+};
+
+class CExcept
+{
+  CExcept *next,*last;
+  I64   hndlr_catch,hndlr_untry,
+        rsp,rbp,rflags,rsi,rdi,r10,r11,r12,r13,r14,r15;
+};
+
+class CFPU
+{
+  U8    body[512];
+};
+
+#help_index "Job/Exe;Task/Job/Exe"
+#define JOBf_WAKE_MASTER        0
+#define JOBf_FOCUS_MASTER       1
+#define JOBf_EXIT_ON_COMPLETE   2
+#define JOBf_DONT_FILTER        3
+#define JOBf_HIGHEST_PRIORITY   4
+//MP flags
+#define JOBf_DONE               5
+#define JOBf_DISPATCHED         6
+#define JOBf_FREE_ON_COMPLETE   7
+#define JOBf_ADD_TO_QUE         8
+
+#define JOBT_TEXT_INPUT         0 //TaskText()  Feed StdIn
+#define JOBT_MSG                1 //TaskMsg()   Post msg
+#define JOBT_EXE_STR            2 //TaskExe()   Compile & execute src code text
+//MP cmds
+#define JOBT_CALL               3 //JobQue()    Tell MP to call function
+#define JOBT_SPAWN_TASK         4 //Spawn()     Tell MP to spawn task
+
+class CJob
+{
+  CJob *next,*last;
+  CJobCtrl *ctrl;
+  I64   job_code,flags,msg_code;
+
+  I64   (*addr)(U8 *fun_arg);
+  U8    *fun_arg;
+
+  U8    *aux_str;
+  I64   aux1,aux2, //Sometimes called arg1 and arg2. (Windows msg param1 param2)
+        res;
+
+  CTask *spawned_task,
+        *master_task;
+};
+
+#define JOBCf_LOCKED            0
+class CJobCtrl
+{
+  CJob *next_waiting,*last_waiting;
+  CJob *next_done,*last_done;
+  I64   flags;
+};
+
+#help_index "Messages"
+//See ::/Demo/MsgLoop.HC
+#define MSG_NULL                0
+#define MSG_CMD                 1
+#define MSG_KEY_DOWN            2  //(ASCII,scan code) Press <CTRL-SHIFT-L>
+#define MSG_KEY_UP              3  //(ASCII,scan code) Press <CTRL-SHIFT-L>
+#define MSG_MS_MOVE             4  //(x,y)
+#define MSG_MS_L_DOWN           5  //(x,y)
+#define MSG_MS_L_UP             6  //(x,y)
+#define MSG_MS_L_D_DOWN         7  //(x,y)
+#define MSG_MS_L_D_UP           8  //(x,y)
+#define MSG_MS_R_DOWN           9  //(x,y)
+#define MSG_MS_R_UP             10 //(x,y)
+#define MSG_MS_R_D_DOWN         11 //(x,y)
+#define MSG_MS_R_D_UP           12 //(x,y)
+
+//Fake messages used to send both an up and down.
+#define MSG_KEY_DOWN_UP         -2  //Down & UP
+#define MSG_MS_L_DOWN_UP        -5  //Down & Up
+#define MSG_MS_L_D_DOWN_UP      -7  //Down & Up
+#define MSG_MS_R_DOWN_UP        -9  //Down & Up
+#define MSG_MS_R_D_DOWN_UP      -11 //Down & Up
+
+#help_index "Task/Settings"
+#define TSF_SAME_SONG   1
+public class CTaskSettings
+{
+  CTaskSettings *next;
+  U8    *cur_dir;
+  I64   left,right,top,bottom;
+  U0    (*draw_it)(CTask *task,CDC *dc);
+  U0    (*task_end_cb)();
+  CTask *song_task,*animate_task;
+  I64   scroll_x,scroll_y,scroll_z;
+  CBGR48 palette[COLORS_NUM];
+  U32   win_inhibit;
+  U8    text_attr,title_src,
+        border_attr,border_src,
+        task_title[STR_LEN];
+  Bool  border,hide_cursor,highlight_cursor,scroll,autocomplete,pad[3];
+#assert !($&7)
+};
+
+#help_index "Task"
+//CTask.border_src
+#define BDS_CONST               0
+#define BDS_CUR_DRV             1
+#define BDS_ED_FILENAME_DRV     2
+
+//CTask.title_src
+#define TTS_CONST               0
+#define TTS_LOCKED_CONST        1 //This is not strictly enforced
+#define TTS_TASK_NAME           2
+#define TTS_ED_FILENAME         3
+#define TTS_CUR_LEX             4
+
+//CTask.task_flags
+#define TASKf_TASK_LOCK         0
+#define TASKf_KILL_TASK         1
+#define TASKf_SUSPENDED         2
+#define TASKf_IDLE              3
+#define TASKf_CMD_LINE_PMT      4
+#define TASKf_INPUT_FILTER_TASK 5
+#define TASKf_FILTER_INPUT      6
+#define TASKf_HAS_SONG          7
+#define TASKf_DISABLE_BPTS      8
+#define TASKf_AWAITING_MSG      9
+#define TASKf_BREAK_LOCKED      10
+#define TASKf_PENDING_BREAK     11
+#define TASKf_BREAK_TO_SHIFT_ESC 12
+#define TASKf_KILL_AFTER_DBG    13
+
+#define TASKf_NONTIMER_RAND     14
+
+//CTask.display_flags
+#define DISPLAYf_SHOW                   0
+#define DISPLAYf_NOT_RAW                1
+#define DISPLAYf_SILENT                 2
+#define DISPLAYf_NO_BORDER              3
+#define DISPLAYf_WIN_ON_TOP             4
+#define DISPLAYf_CHILDREN_NOT_ON_TOP    5
+
+#define TASK_SIGNATURE_VAL              'TskS'
+#define TASK_NAME_LEN                   32
+#define TASK_EXCEPT_CALLERS             8
+class CTaskStk
+{
+  CTaskStk *next_stk;
+  I64   stk_size,stk_ptr;
+  U0    stk_base;
+};
+
+#define DYING_JIFFIES   ToI64(JIFFY_FREQ/5)
+class CTaskDying
+{
+  CTask *next,*last;
+  I64   wake_jiffy;
+};
+
+public class CTask //The Fs segment reg points to current CTask.
+{
+  CTask *addr; //Self-addressed ptr
+  U32   task_signature,win_inhibit;
+#assert $==offset(CTaskDying.wake_jiffy)
+  I64   wake_jiffy;
+  U32   task_flags,display_flags;
+
+  CHeapCtrl *code_heap,*data_heap;
+
+  CDoc  *put_doc,*display_doc, //When double buffering, these two differ.
+        *border_doc;
+  I64   win_left,win_right,win_top,win_bottom;
+
+  CDrv  *cur_dv;
+  U8    *cur_dir;
+
+  CTask *parent_task,
+        *next_task,*last_task,
+        *next_input_filter_task,*last_input_filter_task,
+        *next_sibling_task,*last_sibling_task,
+        *next_child_task,*last_child_task;
+
+  //These are derived from left,top,right,bottom
+  I64   win_width,win_height,
+        pix_left,pix_right,pix_width, //These are in pixs, not characters
+        pix_top,pix_bottom,pix_height,
+        scroll_x,scroll_y,scroll_z;
+
+  //These must be in this order
+  //for TASK_CONTEXT_SAVE and _TASK_CONTEXT_RESTORE
+  I64   rip,rflags,rsp,rsi,rax,rcx,rdx,rbx,rbp,rdi,
+        r8,r9,r10,r11,r12,r13,r14,r15;
+  CCPU  *gs;
+  CFPU  *fpu_mmx;
+  I64   swap_cnter;
+
+  U0    (*draw_it)(CTask *task,CDC *dc);
+
+  U8    task_title[STR_LEN],
+        task_name[TASK_NAME_LEN],
+        wallpaper_data[STR_LEN],
+
+        title_src,border_src,
+        text_attr,border_attr;
+  U16   win_z_num,pad;
+
+  CTaskStk *stk;
+
+  CExcept *next_except,*last_except;
+  I64   except_rbp,     //throw routine's RBP
+        except_ch;      //throw(ch)
+  U8    *except_callers[TASK_EXCEPT_CALLERS];
+
+  Bool  catch_except;
+  Bool  new_answer;
+  U8    answer_type,pad[5];
+  I64   answer;
+  F64   answer_time;
+  CBpt  *bpt_lst;
+  CCtrl *next_ctrl,*last_ctrl;
+  CMenu *cur_menu;
+  CTaskSettings *next_settings;
+  CMathODE *next_ode,*last_ode;
+  F64   last_ode_time;
+  CHashTable *hash_table;
+
+  CJobCtrl srv_ctrl;
+  CCmpCtrl *next_cc,*last_cc;
+  CHashFun *last_fun;
+
+  U0    (*task_end_cb)();
+  CTask *song_task,*animate_task;
+  I64   rand_seed,
+        task_num,
+        fault_num,fault_err_code;
+  CTask *popup_task,
+        *dbg_task;
+  CWinScroll horz_scroll,vert_scroll;
+
+  I64   user_data;
+#assert !($&7)
+};
+
+class CTSS
+{
+  U32   res1;
+  I64   rsp0,rsp1,rsp2,res2,
+        ist1,ist2,ist3,ist4,ist5,ist6,ist7,res3;
+  U16   res4,io_map_offset;
+  U8    io_map[0x10000/8];
+  I64   *st0,*st1,*st2;
+  U16   tr,tr_ring3;
+};
+
+#define ans     (Fs->answer)
+#define ansf    (Fs->answer(F64))
+
+#define _RAX Fs->rax
+#define _RBX Fs->rbx
+#define _RCX Fs->rcx
+#define _RDX Fs->rdx
+#define _RSI Fs->rsi
+#define _RDI Fs->rdi
+#define _RBP Fs->rbp
+#define _RSP Fs->rsp
+#define _RIP Fs->rip
+#define _R8  Fs->r8
+#define _R9  Fs->r9
+#define _R10 Fs->r10
+#define _R11 Fs->r11
+#define _R12 Fs->r12
+#define _R13 Fs->r13
+#define _R14 Fs->r14
+#define _R15 Fs->r15
+
+#help_index "MultiCore"
+#define CPUf_RAN_A_TASK         0
+#define CPUf_DYING_TASK_QUE     1
+
+public class CCPU //The Gs segment reg points to current CCPU.
+{
+  CCPU  *addr; //Self-addressed ptr
+  I64   num,cpu_flags,
+        startup_rip,
+        idle_pt_hits;
+  F64   idle_factor;
+  I64   total_jiffies;
+  CTask *seth_task,*idle_task;
+  I64   tr,   //task reg
+        swap_cnter;
+  U0    (*profiler_timer_irq)(CTask *task);
+  CTaskDying *next_dying,*last_dying;
+  I64   kill_jiffy;
+  CTSS  *tss;
+  I64   start_stk[16];
+#assert !($&7)
+};
+
+#help_index "Memory/Page Tables"
+#define MEM_MIN_MEG             512 //512 Meg minimum.
+
+#define SYS_FIXED_AREA          0x100000
+#define SYS_16MEG_AREA_LIMIT    0x1000000
+public class CSysFixedArea
+{
+  CFPU  init_fpu_mmx;
+  CCPU  boot_cpu;
+  CTask adam;
+  CBlkPool sys_code_bp;
+  CHeapCtrl adam_hc;
+  $=($+0x1000-1)&-0x1000;
+};
+
+#help_index "Char"
+#define CH_CTRLA        0x01
+#define CH_CTRLB        0x02
+#define CH_CTRLC        0x03
+#define CH_CTRLD        0x04
+#define CH_CTRLE        0x05
+#define CH_CTRLF        0x06
+#define CH_CTRLG        0x07
+#define CH_CTRLH        0x08
+#define CH_CTRLI        0x09
+#define CH_CTRLJ        0x0A
+#define CH_CTRLK        0x0B
+#define CH_CTRLL        0x0C
+#define CH_CTRLM        0x0D
+#define CH_CTRLN        0x0E
+#define CH_CTRLO        0x0F
+#define CH_CTRLP        0x10
+#define CH_CTRLQ        0x11
+#define CH_CTRLR        0x12
+#define CH_CTRLS        0x13
+#define CH_CTRLT        0x14
+#define CH_CTRLU        0x15
+#define CH_CTRLV        0x16
+#define CH_CTRLW        0x17
+#define CH_CTRLX        0x18
+#define CH_CTRLY        0x19
+#define CH_CTRLZ        0x1A
+#define CH_CURSOR       0x05
+#define CH_BACKSPACE    0x08
+#define CH_ESC          0x1B
+#define CH_SHIFT_ESC    0x1C
+#define CH_SHIFT_SPACE  0x1F
+#define CH_SPACE        0x20
+
+#define ST_ERR_ST   "$LTRED$$BK,1$ERROR:$FG$$BK,0$ "
+#define ST_WARN_ST  "$RED$$BK,1$WARNING:$FG$$BK,0$ "
+
+//Scan code flags
+#define SCf_E0_PREFIX   7
+#define SCf_KEY_UP      8
+#define SCf_SHIFT       9
+#define SCf_CTRL        10
+#define SCf_ALT         11
+#define SCf_CAPS        12
+#define SCf_NUM         13
+#define SCf_SCROLL      14
+#define SCf_NEW_KEY     15
+#define SCf_MS_L_DOWN   16
+#define SCf_MS_R_DOWN   17
+#define SCf_DELETE      18
+#define SCf_INS         19
+#define SCf_NO_SHIFT    30
+#define SCf_KEY_DESC    31
+#define SCF_E0_PREFIX   (1<<SCf_E0_PREFIX)
+#define SCF_KEY_UP      (1<<SCf_KEY_UP)
+#define SCF_SHIFT       (1<<SCf_SHIFT)
+#define SCF_CTRL        (1<<SCf_CTRL)
+#define SCF_ALT         (1<<SCf_ALT)
+#define SCF_CAPS        (1<<SCf_CAPS)
+#define SCF_NUM         (1<<SCf_NUM)
+#define SCF_SCROLL      (1<<SCf_SCROLL)
+#define SCF_NEW_KEY     (1<<SCf_NEW_KEY)
+#define SCF_MS_L_DOWN   (1<<SCf_MS_L_DOWN)
+#define SCF_MS_R_DOWN   (1<<SCf_MS_R_DOWN)
+#define SCF_DELETE      (1<<SCf_DELETE)
+#define SCF_INS         (1<<SCf_INS)
+#define SCF_NO_SHIFT    (1<<SCf_NO_SHIFT)
+#define SCF_KEY_DESC    (1<<SCf_KEY_DESC)
+
+//TempleOS places a 1 in bit 7 for
+//keys with an E0 prefix.
+//See ::/Doc/CharOverview.DD and KbdHndlr().
+#define SC_ESC          0x01
+#define SC_BACKSPACE    0x0E
+#define SC_TAB          0x0F
+#define SC_ENTER        0x1C
+#define SC_SHIFT        0x2A
+#define SC_CTRL         0x1D
+#define SC_ALT          0x38
+#define SC_CAPS         0x3A
+#define SC_NUM          0x45
+#define SC_SCROLL       0x46
+#define SC_CURSOR_UP    0x48
+#define SC_CURSOR_DOWN  0x50
+#define SC_CURSOR_LEFT  0x4B
+#define SC_CURSOR_RIGHT 0x4D
+#define SC_PAGE_UP      0x49
+#define SC_PAGE_DOWN    0x51
+#define SC_HOME         0x47
+#define SC_END          0x4F
+#define SC_INS          0x52
+#define SC_DELETE       0x53
+#define SC_F1           0x3B
+#define SC_F2           0x3C
+#define SC_F3           0x3D
+#define SC_F4           0x3E
+#define SC_F5           0x3F
+#define SC_F6           0x40
+#define SC_F7           0x41
+#define SC_F8           0x42
+#define SC_F9           0x43
+#define SC_F10          0x44
+#define SC_F11          0x57
+#define SC_F12          0x58
+#define SC_PAUSE        0x61
+#define SC_GUI          0xDB
+#define SC_PRTSCRN1     0xAA
+#define SC_PRTSCRN2     0xB7
+
+#help_index "Char;Debugging/Raw Output;TextBase Layer/Char"
+//text.raw_flags
+#define RWF_IN_DOLLAR   1
+#define RWF_LAST_DOLLAR 2
+#define RWF_SHOW_DOLLAR 4
+#define RWF_SCROLL      8
+
+public class CTextGlbls
+{
+  I64   raw_col,raw_flags;
+  U8    *raw_scrn_image;
+  I64   rows,cols;              //Use TEXT_ROWS,TEXT_COLS
+  U64   *font,*aux_font;
+  U8    *vga_alias,*vga_text_alias;
+  U8    border_chars[16];
+};
+
+#define FONT_WIDTH      8
+#define FONT_HEIGHT     8
+
+#help_index "Graphics"
+#define GR_WIDTH        640
+#define GR_HEIGHT       480
+
+//z-vals less than zero are in front of scrn and not drawn.
+//we want to shift all Z-vals into a drawable range.
+//GR_Z_ALL is set to half of the Z-range which is an I32.
+#define GR_Z_ALL        (I32_MAX/2)
+
+#help_index "Graphics/Device Contexts"
+//Low 8 bits reserved for flags that go into saved bitmaps
+#define DCF_COMPRESSED          1
+#define DCF_PALETTE             2
+#define DCF_NO_TRANSPARENTS     4 //Can be used to optimized GrBlot().
+
+#define DCF_TRANSFORMATION      0x100
+
+//See DCSymmetrySet() or DCSymmetry3Set()
+#define DCF_SYMMETRY            0x200
+
+//Must be used with DCF_SYMMETRY set also.
+//See ::/Demo/Games/BigGuns.HC
+#define DCF_JUST_MIRROR         0x400
+
+#define DCF_LOCATE_NEAREST      0x800
+#define DCF_DONT_DRAW           0x1000
+#define DCF_ALIAS               0x2000
+#define DCF_SCRN_BITMAP         0x4000
+#define DCF_FILL_NOT_COLOR      0x8000
+#define DCF_RECORD_EXTENTS      0x10000
+#define DCF_ON_TOP              0x20000
+
+//DCSave() flags.
+#define DCSF_COMPRESSED         1
+#define DCSF_PALETTE_GET        2
+
+#define DCS_SIGNATURE_VAL       'DvCS'
+
+class CGrSym
+{
+  I32   sx,sy,sz,pad;
+//Normal of symmetry plane
+  I64   snx,sny,snz;
+};
+
+public class CDC
+{
+  U0    start;
+  CDate cdt;
+  I32   x0,y0,
+        width,width_internal,
+        height,
+        flags;
+  U0    end;
+  CBGR48 palette[COLORS_NUM];
+
+  //public (Change directly)
+  CColorROPU32 color,
+        bkcolor, //Set for use with ROP_COLLISION
+        color2; //Internally used for GrFloodFill()
+  CD3I32 ls; //Light source (should be normalized to 65536).
+
+  //dither_probability_u16 is basically a U16.
+  //It is activated by ROPF_PROBABILITY_DITHER.
+  //0x0000 =100% color.c0
+  //0x8000 =50%  color.c0   50% color.c1
+  //0x10000=100% color.c1
+  //See ::/Demo/Graphics/SunMoon.HC and ::/Demo/Graphics/Shading.HC.
+  U64 dither_probability_u16;
+
+  CDC *brush;
+
+  //Set with DCMat4x4Set().  Free() before setting.
+  I64   *r, //rotation matrix of quads decimal in lo
+        r_norm; //shifted 32 bits.  Used for scaling thick
+
+  //public (Change directly)
+  I32   x,y,z,
+        thick;
+
+  //Can be changed from the default DCTransform()
+  U0    (*transform)(CDC *dc,I64 *x,I64 *y,I64 *z);
+
+  //Can be changed from the default DCLighting()
+  U0    (*lighting)(CDC *dc,CD3I32 *p1,CD3I32 *p2,
+        CD3I32 *p3,CColorROPU32 color);
+
+  //Set by DCSymmetrySet() or DCSymmetry3Set()
+  CGrSym sym;
+
+  I32   cur_x,cur_y,cur_z,pad;
+  I64   collision_cnt;
+
+  I64   nearest_dist,
+        min_x,max_x,min_y,max_y; //Set by DCF_RECORD_EXTENTS (scrn coordinates)
+
+  U32   dc_signature,pad;
+  CTask *mem_task,*win_task;
+  CDC   *alias;
+  U8    *body;
+
+  //Set by DCDepthBufAlloc()
+  I32   *depth_buf;
+  I64   db_z; //private
+#assert !($&7)
+};
+
+#help_index "Devices"
+//VGA Memory
+#define VGAM_GRAPHICS   0xA0000
+#define VGAM_TEXT       0xB8000
+
+//VGA I/O ports
+#define VGAP_ATTR_INDEX         0x03C0
+#define VGAP_ATTR_DATA_WRITE    0x03C0 //alias
+#define VGAP_ATTR_DATA_READ     0x03C1
+#define VGAP_MISC_OUTPUT        0x03C2
+#define VGAP_IDX                0x03C4
+#define VGAP_DATA               0x03C5
+#define VGAP_PALETTE_MASK       0x03C6
+#define VGAP_REG_READ           0x03C7
+#define VGAP_REG_WRITE          0x03C8
+#define VGAP_PALETTE_DATA       0x03C9
+#define VGAP_CRTC_INDEX         0x03D4
+#define VGAP_CRTC_DATA          0x03D5
+#define VGAP_INPUT_STAT         0x03DA
+
+//VGA Registers
+#define VGAR_MAP_MASK           0x02
+
+#help_index "Compression/Piece by Piece"
+#define ARC_BITS_MAX    12
+
+#define CT_NONE         1
+#define CT_7_BIT        2
+#define CT_8_BIT        3
+class CArcEntry
+{
+  CArcEntry *next;
+  U16   basecode;
+  U8    ch,pad;
+  U32   pad;
+};
+
+public class CArcCtrl
+{
+  I64   src_pos,src_size,
+        dst_pos,dst_size;
+  U8    *src_buf,*dst_buf;
+  I64   min_bits,min_table_entry;
+  CArcEntry *cur_entry,*next_entry;
+  I64   cur_bits_in_use,next_bits_in_use;
+  U8    *stk_ptr,*stk_base;
+  I64   free_idx,free_limit,
+        saved_basecode,
+        entry_used,
+        last_ch;
+  CArcEntry compress[1<<ARC_BITS_MAX],
+        *hash[1<<ARC_BITS_MAX];
+};
+
+#help_index "Compression"
+public class CArcCompress
+{
+  I64   compressed_size,expanded_size;
+  U8    compression_type;
+  U0    body;
+};
+
+#define "Char/Input;StdIn"
+//GetStr flags
+#define GSF_SHIFT_ESC_EXIT      1 //This kills task on <SHIFT-ESC>
+#define GSF_WITH_NEW_LINE       2
+
+#define "Char/Operations"
+//Flags for StrUtil and MStrUtil
+#define SUF_REM_CTRL_CHARS      0x001
+#define SUF_REM_LEADING         0x002
+#define SUF_REM_TRAILING        0x004
+#define SUF_REM_SPACES          0x008
+#define SUF_SINGLE_SPACE        0x010
+#define SUF_TO_UPPER            0x020
+#define SUF_TO_LOWER            0x040
+#define SUF_S2T                 0x080
+#define SUF_T2S                 0x100 // Only works with MStrUtil
+#define SUF_SCALE_INDENT        0x200
+#define SUF_SAFE_DOLLAR         0x400
+
+//Flags for StrFind
+#define SFF_IGNORE_CASE         1
+#define SFF_WHOLE_LABELS_BEFORE 2
+#define SFF_WHOLE_LABELS_AFTER  4
+#define SFG_WHOLE_LABELS        (SFF_WHOLE_LABELS_BEFORE|SFF_WHOLE_LABELS_AFTER)
+
+//Flags for LstMatch
+#define LMF_IGNORE_CASE         1
+#define LMF_EXACT               2
+
+#help_index "Keyboard Devices/System"
+#define KDF_HAS_DESCS   1
+class CKeyDevEntry
+{
+  CKeyDevEntry *next,*last;
+  I64   priority,flags;
+  Bool  (*put_key)(I64 ch,I64 sc);
+  Bool  (*put_s)(U8 *st);
+};
+
+class CKeyDevGlbls
+{
+  CKeyDevEntry put_key_head;
+  U0    (**fp_ctrl_alt_cbs)(I64 sc);
+  I64   ctrl_alt_in_irq_flags,
+        **ctrl_alt_ret_addr; //addr of ret addr on stack in kbd irq
+  U8    **ctrl_alt_no_shift_descs,**ctrl_alt_shift_descs,
+        desc[STR_LEN],
+        *hndlr;
+};
+
+#help_index "Snd"
+#help_index "ScrnCast;Snd/AU Files"
+public class CAUData
+{//Fmt of AU files
+  CDate cdt;
+  I8    ona;
+};
+
+class CSndData
+{//Fmt recorded in mem
+  CSndData *next,*last;
+  F64   tS;
+  I8    ona;
+};
+
+public class CScrnCastGlbls
+{
+  CSndData snd_head;
+  CDate t0_now;
+  F64   t0_tS;
+  U8    *print_fmt;
+  CDC   *dc,*dc2_alias;
+  Bool  record,just_audio;
+  I8    ona;
+};
+
+#help_index "Debugging/FunSeg"
+#define FUN_SEG_CACHE_SIZE      256
+class CFunSegCache
+{
+  I64   base,limit;
+  F64   time_stamp;
+  U8    str[1]; //FUN_SEG_CACHE_STR_LEN
+$=64;
+};
+#define FUN_SEG_CACHE_STR_LEN   (sizeof(CFunSegCache)-offset(CFunSegCache.str))
+
+#help_index "Debugging"
+class CMPCrash
+{
+  I64   cpu_num;
+  CTask *task;
+  I64   rip;
+  U8    *msg;
+  I64   msg_num;
+};
+
+public class CDbgGlbls
+{
+  CTask *focus_task;
+  U8    *msg;
+  I64   msg_num;
+  CMPCrash *mp_crash;
+  U8    *int_fault_code,
+        *fix_file_line;
+  CFunSegCache *fun_seg_cache;
+  I64   fun_seg_cache_index;
+  Bool  panic;
+};
+
+#help_index "Boot"
+//Boot related
+#define BOOT_RAM_BASE           0x07C00
+#define BOOT_RAM_LIMIT          0x97000
+#define BOOT_STK_SIZE           BLK_SIZE
+
+#define BOOT_SRC_NULL           0
+#define BOOT_SRC_ROM            1
+#define BOOT_SRC_RAM            2
+#define BOOT_SRC_HARDDRV        3
+#define BOOT_SRC_DVD            4
+
+// In("") StdIn for call to BootHDIns().
+#define STD_DISTRO_DVD_CFG      "TB\nScale2Mem(2048,0x40000)\nT \n\n\n\n"
+
+#help_index "Registry"
+//Registry sys_msg_flags. RegOneTimePopUp()
+#define ARf_FLOODFILL                   0
+#define ARf_CSPRITE_INS_CLIP            1
+#define ARf_PLANAR_SYMMETRY             2
+#define ARf_PSALMODY_JUKEBOX            3
+#define ARf_MESH_ED                     4
+#define ARf_CSPRITE_PTS_RECTANGLES      5
+#define ARf_MANAGE_SLIDER               6
+
+#help_index "Misc/Progress Bars"
+#define PROGRESS_BARS_NUM       4
+#define PROGRESS_DESC_LEN       (64-8-8)
+class CProgress
+{
+  I64   val,max;
+  F64   t0,tf;
+  U8    desc[PROGRESS_DESC_LEN];
+};
+
+#help_index "Char/Operations"
+#define PRTF_PAD_ZERO           0x001
+#define PRTF_LEFT_JUSTIFY       0x002
+#define PRTF_TRUNCATE           0x004
+#define PRTF_COMMA              0x008
+#define PRTF_DOLLAR             0x010
+#define PRTF_SLASH              0x020
+#define PRTF_QUESTION           0x040
+#define PRTF_AUX_FMT_NUM        0x080
+#define PRTF_DECIMAL            0x100
+#define PRTF_NEG                0x200
+#define PRTF_NEG_E              0x400
+#define PRTF_NEG_AUX_FMT_NUM    0x800
+
+#help_index "Misc/Host"
+//Host Operating System
+#define OS_OTHER        0
+#define OS_NATIVE       1
+#define OS_LINUX        2
+#define OS_WINDOWS      3
+//Virtual Machine
+#define VM_OTHER        0
+#define VM_NATIVE       1
+#define VM_VMWARE       2
+#define VM_QEMU         3
+#define VM_VIRTUALBOX   4
+
+#help_index "Registry/Install Registration"
+public class CInsReg
+{
+  Bool  registered;
+  I64   host_os         format "$PURPLE$Install Registration$FG$\n\n"
+                        "Host OS:$LS,D=\"ST_HOST_OSES\"$\n";
+  I64   host_vm         format "Host VM:$LS,D=\"ST_HOST_VMS\"$\n";
+  U8    initials[8]     format "$DA-P,A=\"Your Initials:%s\"$\n";
+  I64   machine_num     format
+                        "$DA-TRM,A=\"This Machine Num (Choose Any):%d\"$\n";
+};
+
+#help_index ""
+
+ diff --git a/public/Wb/Kernel/KernelB.HH b/public/Wb/Kernel/KernelB.HH old mode 100644 new mode 100755 diff --git a/public/Wb/Kernel/KernelB.HH.HTML b/public/Wb/Kernel/KernelB.HH.HTML new file mode 100755 index 0000000..834fbd6 --- /dev/null +++ b/public/Wb/Kernel/KernelB.HH.HTML @@ -0,0 +1,325 @@ + + + + + + + + + + + +
+/*  Kernel ASM symbols.
+KernelB Kernel.PRJ
+KernelB Compiler.PRJ
+KernelB StartOS.HC
+*/
+
+#help_index "Bit"
+#help_file "::/Doc/Bit"
+public _intern IC_BSF I64 Bsf(
+        I64 bit_field_val);//Scan fwd from lowest for 1st set. -1 if not found.
+public _intern IC_BSR I64 Bsr(
+        I64 bit_field_val);//Scan rev from highest for 1st set. -1 if not found.
+public _intern IC_BT Bool Bt(
+        U8 *bit_field,I64 bit); //Bit test.
+public _intern IC_BTC Bool Btc(
+        U8 *bit_field,I64 bit); //Bit test and complement (same as xor with 1).
+public _intern IC_BTR Bool Btr(
+        U8 *bit_field,I64 bit); //Bit test and reset to zero.
+public _intern IC_BTS Bool Bts(
+        U8 *bit_field,I64 bit); //Bit test and set to one.
+public _intern IC_LBTC Bool LBtc(
+        U8 *bit_field,I64 bit); //Locked bit test and complement (xor with 1).
+public _intern IC_LBTR Bool LBtr(
+        U8 *bit_field,I64 bit); //Locked bit test and reset to zero.
+public _intern IC_LBTS Bool LBts(
+        U8 *bit_field,I64 bit); //Locked bit test and set to one.
+public _extern _BEQU Bool BEqu(
+        U8 *bit_field,I64 bit,Bool val);//Set bit equ to val.
+public _extern _BIT_FIELD_EXT_U32 U32 BFieldExtU32(
+        U8 *bit_field,I64 bit,I64 size); //Extract U32 from bit field.
+public _extern _BIT_FIELD_OR_U32 U0 BFieldOrU32(
+        U8 *bit_field,I64 bit,U32 pattern); //Or U32 into bit field.
+public _extern _LBEQU Bool LBEqu(
+        U8 *bit_field,I64 bit,Bool val); //Locked Set bit equ to val.
+
+#help_index "Boot"
+_extern MEM_BOOT_BASE U32 mem_boot_base;
+_extern SYS_BOOT_BLK U32 sys_boot_blk;
+_extern SYS_BOOT_PATCH_TABLE_BASE U32 sys_boot_patch_table_base;
+_extern SYS_BOOT_SRC U32 sys_boot_src;
+_extern SYS_RUN_LEVEL U32 sys_run_level;
+
+#help_index "Call"
+public _extern _CALL I64 Call(U8 *machine_code); //Call addr with no args.
+public _extern _CALLEXTSTR I64 CallExtStr(
+        /*argpop*/ U8 *name,...); //Search sym table for fun and pass it args.
+//Can have any fixed number of arguments.
+public _extern _CALL_IND I64 CallInd(
+        /*argpop*/I64 (*fp_addr)(...),...); //Call with fixed number of args.
+
+#help_index "Call/System Extern Num"
+public _extern SYS_EXTERN_TABLE /*argpop*/
+        I64 (**ext)(...); //Array of fun ptrs.  See Extern Num Definitions
+public _extern _CALLEXTNUM
+        I64 CallExtNum(I64 num,...); //Call ext num with fixed number of args.
+
+#help_index "Char/Conversion"
+public _intern IC_TOUPPER I64 ToUpper(U8 ch); //Cvt char to upper case.
+
+#help_index "Char/Operations"
+public _intern IC_STRLEN I64 StrLen(U8 *st); //String length.
+
+#help_index "Data Types/Circular Queue"
+#help_file "::/Doc/Que"
+public _intern IC_QUE_INIT U0 QueInit(
+        CQue *head); //Init queue head links.
+public _intern IC_QUE_INS U0 QueIns(
+        CQue *entry,CQue *pred);//Insert item into que after predecessor.
+public _intern IC_QUE_INS_REV U0 QueInsRev(
+        CQue *entry,CQue *succ);//Revd insert into que.
+//Ins item into que before successor.
+public _intern IC_QUE_REM U0 QueRem(CQue *entry); //Remove item from queue.
+
+#help_index "I/O;Processor/IO Port"
+public _intern IC_IN_U16 U16 InU16(I64 port); //Read U16 from I/O port.
+public _intern IC_IN_U32 U32 InU32(I64 port); //Read U32 from I/O port.
+public _intern IC_IN_U8 U8 InU8(I64 port); //Read U8 from I/O port.
+public _intern IC_OUT_U16 U0 OutU16(I64 port, I64 val); //Write U16 to I/O port.
+public _intern IC_OUT_U32 U0 OutU32(I64 port, I64 val); //Write U32 to I/O port.
+public _intern IC_OUT_U8  U0 OutU8(I64 port, I64 val); //Write U8 to I/O port.
+public _extern _REP_IN_U16 U0 RepInU16(
+        U8 *buf,I64 cnt,I64 port); //Repeated read U16 from I/O port.
+public _extern _REP_IN_U32 U0 RepInU32(
+        U8 *buf,I64 cnt,I64 port); //Repeated read U32 from I/O port.
+public _extern _REP_IN_U8  U0 RepInU8(
+        U8 *buf,I64 cnt,I64 port); //Repeated read U8 from I/O port.
+public _extern _REP_OUT_U16 U0 RepOutU16(
+        U8 *buf,I64 cnt,I64 port); //Repeated write U16 to I/O port.
+public _extern _REP_OUT_U32 U0 RepOutU32(
+        U8 *buf,I64 cnt,I64 port); //Repeated write U32 to I/O port.
+public _extern _REP_OUT_U8  U0 RepOutU8(
+        U8 *buf,I64 cnt,I64 port); //Repeated write U8 to I/O port.
+
+#help_index "Math"
+public _intern IC_ATAN F64 ATan(F64 d); //Arc Tan (Inverse Tan).
+public _intern IC_ABS F64 Abs(F64 d); //Absolute F64.
+public _intern IC_ABS_I64 I64 AbsI64(I64 i); //Absolute I64.
+public _intern IC_COS F64 Cos(F64 d); //Cosine.
+public _intern IC_MAX_I64 I64 MaxI64(I64 n1,I64 n2); //Max of two I64s.
+public _intern IC_MAX_U64 U64 MaxU64(U64 n1,U64 n2); //Max of two U64s.
+public _intern IC_MIN_I64 I64 MinI64(I64 n1,I64 n2); //Min of two I64s.
+public _intern IC_MIN_U64 U64 MinU64(U64 n1,U64 n2); //Min of two U64s.
+public _intern IC_MOD_U64 U64 ModU64(U64 *q,U64 d); //Div and return U64 Modulo.
+public _intern IC_SIGN_I64 I64 SignI64(I64 i); //Sign of I64: -1,0,1.
+public _intern IC_SIN F64 Sin(F64 d); //Sine.
+public _intern IC_SQR F64 Sqr(F64 d); //Square of F64.
+public _intern IC_SQR_I64  I64 SqrI64(I64 i); //Square of I64.
+public _intern IC_SQR_U64  U64 SqrU64(U64 i); //Square of U64.
+public _intern IC_SQRT F64 Sqrt(F64 d); //Square head of F64.
+public _intern IC_SWAP_I64 U0 SwapI64(
+        I64 *n1,I64 *n2); //Swap two I64s. Not atomic.
+public _intern IC_SWAP_U16 U0 SwapU16(
+        U16 *n1,U16 *n2); //Swap two U16s. Not atomic.
+public _intern IC_SWAP_U32 U0 SwapU32(
+        U32 *n1,U32 *n2); //Swap two U32s. Not atomic.
+public _intern IC_SWAP_U8  U0 SwapU8(
+        U8 *n1,U8 *n2); //Swap two U8s. Not atomic.
+public _intern IC_TAN F64 Tan(F64 d); //Tangent.
+public _intern IC_TO_BOOL Bool ToBool(I64 i); //Convert to Boolean.
+public _intern IC_TO_F64 F64 ToF64(I64 i); //Convert to F64.
+public _intern IC_TO_I64 I64 ToI64(F64 d);  //Convert to I64. Truncates.
+public _extern _ARG F64 Arg(F64 x,F64 y); //Polar coordinate angle.
+public _extern _CEIL F64 Ceil(F64 d); //Ceiling of F64.
+public _extern _CLAMP_I64 I64 ClampI64(
+        I64 num,I64 lo,I64 hi); //Clamp to I64 [] range.
+public _extern _CLAMP_U64 U64 ClampU64(
+        U64 num,U64 lo,U64 hi); //Clamp to U64 [] range.
+public _extern _EXP F64 Exp(F64 d); //Exponential function.
+_extern _FCLEX U0 Fclex();
+_extern _FLDCW U0 Fldcw(U16 w);
+public _extern _FLOOR F64 Floor(F64 d); //Floor of F64.
+_extern _FSTCW U16 Fstcw();
+_extern _FSTSW U16 Fstsw();
+public _extern _LN  F64 Ln(F64 d); //Logarithm.
+public _extern _LOG10 F64 Log10(F64 d); //Log base 10.
+public _extern _LOG2 F64 Log2(F64 d); //Log base 2.
+public _extern _POW F64 Pow(F64 base,F64 power); //F64 base to a power.
+public _extern _POW10 F64 Pow10(F64 d); //Ten to the dth power.
+public _extern _ROUND F64 Round(F64 d); //Round F64 to whole number.
+public _extern _SIGN F64 Sign(F64 d); //Sign of F64: -1,0,1
+public _extern _TRUNC F64 Trunc(F64 d); //Truncate F64.
+
+#help_index "Math/CD3;Data Types/CD3"
+#help_file "::/Doc/D3"
+public _extern _D3_ADD CD3 *D3Add(CD3 *sum,CD3 *d1,CD3 *d2); //sum=d1+d2
+public _extern _D3_ADD_EQU CD3 *D3AddEqu(CD3 *sum,CD3 *d); //sum+=d
+public _extern _D3_COPY CD3 *D3Copy(CD3 *dst,CD3 *src); //dst=src
+public _extern _D3_CROSS CD3 *D3Cross(CD3 *prod,CD3 *d1,CD3 *d2); //prod=d1xd2
+public _extern _D3_DIST F64 D3Dist(CD3 *d1,CD3 *d2); //Distance
+public _extern _D3_DIST_SQR F64 D3DistSqr(CD3 *d1,CD3 *d2); //Distance Squared
+public _extern _D3_DIV CD3 *D3Div(CD3 *quot,CD3 *d,F64 s); //quot=d/s
+public _extern _D3_DIV_EQU CD3 *D3DivEqu(CD3 *quot,F64 s); //quot/=s
+public _extern _D3_DOT F64 D3Dot(CD3 *d1,CD3 *d2); //d1 dot d2
+public _extern _D3_EQU CD3 *D3Equ(
+        CD3 *dst,F64 x=0,F64 y=0,F64 z=0); //dst=(x,y,z)
+public _extern _D3_MUL CD3 *D3Mul(CD3 *prod,F64 s,CD3 *d); //prod=s*d
+public _extern _D3_MUL_EQU CD3 *D3MulEqu(CD3 *prod,F64 s); //prod*=s
+public _extern _D3_NORM F64 D3Norm(CD3 *d); //Norm
+public _extern _D3_NORM_SQR F64 D3NormSqr(CD3 *d); //Norm Squared
+public _extern _D3_SUB CD3 *D3Sub(CD3 *diff,CD3 *d1,CD3 *d2); //diff=d1-d2
+public _extern _D3_SUB_EQU CD3 *D3SubEqu(CD3 *diff,CD3 *d); //diff-=d
+public _extern _D3_UNIT CD3 *D3Unit(CD3 *d); //To unit vect
+public _extern _D3_ZERO CD3 *D3Zero(CD3 *dst); //To zero
+
+#help_index "Memory"
+public _extern _MEMCMP I64 MemCmp(
+        U8 *ptr1,U8 *ptr2,I64 cnt); //Compare chunk of memory.
+public _extern _MEMCPY U8 *MemCpy(
+        U8 *dst,U8 *src,I64 cnt); //Copy chunk of memory. Only goes fwd.
+public _extern _MEMSET U8 *MemSet(
+        U8 *dst,I64 val,I64 cnt); //Set chunk of U8s to value.
+public _extern _MEMSET_I64 I64 *MemSetI64(
+        I64 *dst,I64 val,I64 I64cnt); //Set chunk of I64s to value.
+public _extern _MEMSET_U16 U16 *MemSetU16(
+        U16 *dst,I64 val,I64 U16cnt); //Set chunk of U16s to value.
+public _extern _MEMSET_U32 U32 *MemSetU32(
+        U32 *dst,I64 val,I64 U32cnt); //Set chunk of U32s to value.
+public _extern _MEMSET U8 *MemSetU8(
+        U8 *dst,I64 val,I64 U8cnt); //Set chunk of U8s to value.
+_extern SYS_HEAP_DBG_FLAG       U8 sys_heap_dbg;
+_extern SYS_HEAP_INIT_FLAG      U8 sys_heap_init_flag;
+_extern SYS_HEAP_INIT_VAL       U8 sys_heap_init_val;
+_extern SYS_MEM_INIT_FLAG       U8 sys_mem_init_flag;
+_extern SYS_MEM_INIT_VAL        U8 sys_mem_init_val;
+_extern SYS_STAFF_MODE_FLAG     U8 sys_staff_mode_flag;
+_extern SYS_VAR_INIT_FLAG       U8 sys_var_init_flag;
+_extern SYS_VAR_INIT_VAL        U8 sys_var_init_val;
+
+#help_index "Memory/BlkPool"
+public _extern SYS_CODE_BP CBlkPool *sys_code_bp; //System's BlkPool for code.
+public _extern SYS_DATA_BP CBlkPool *sys_data_bp; //System's BlkPool for data.
+
+#help_index "Memory/Info"
+_extern MEM_HEAP_BASE   U8 *mem_heap_base;
+_extern MEM_HEAP_LIMIT  U8 *mem_heap_limit;
+_extern MEM_MAPPED_SPACE U8 *mem_mapped_space;
+_extern MEM_PHYSICAL_SPACE U8 *mem_physical_space;
+
+#help_index "Messages;Windows"
+public _extern SYS_FOCUS_TASK CTask *sys_focus_task; //Current focus task.
+
+#help_index "Misc"
+public _extern SYS_COMPILE_TIME
+        CDate sys_compile_time; //Date and time kernel was compiled.
+_extern SYS_CTRL_ALT_FLAGS
+        I64 sys_ctrl_alt_flags[1]; //Should be semiphores?
+
+#help_index "Misc/Progress Bars"
+public _extern SYS_PROGRESS1 I64 progress1; //Current progress 1.
+public _extern SYS_PROGRESS1_DESC
+        U8 progress1_desc[PROGRESS_DESC_LEN]; //Progress 1 desc.
+public _extern SYS_PROGRESS1_MAX I64 progress1_max; //Progress 1 max.
+public _extern SYS_PROGRESS1_T0 F64 progress1_t0; //Progress 1 start time.
+public _extern SYS_PROGRESS1_TF F64 progress1_tf; //Progress 1 end time.
+public _extern SYS_PROGRESS2 I64 progress2; //Current progress 2.
+public _extern SYS_PROGRESS2_DESC
+        U8  progress2_desc[PROGRESS_DESC_LEN]; //Progress 2 desc.
+public _extern SYS_PROGRESS2_MAX I64 progress2_max; //Progress 2 max.
+public _extern SYS_PROGRESS2_T0 F64 progress2_t0; //Progress 2 start time.
+public _extern SYS_PROGRESS2_TF F64 progress2_tf; //Progress 2 end time.
+public _extern SYS_PROGRESS3 I64 progress3; //Current progress 3.
+public _extern SYS_PROGRESS3_DESC
+        U8  progress3_desc[PROGRESS_DESC_LEN]; //Progress 3 desc.
+public _extern SYS_PROGRESS3_MAX I64 progress3_max; //Progress 3 max.
+public _extern SYS_PROGRESS3_T0 F64 progress3_t0; //Progress 3 start time.
+public _extern SYS_PROGRESS3_TF F64 progress3_tf; //Progress 3 end time.
+public _extern SYS_PROGRESS4 I64 progress4; //Current progress 4.
+public _extern SYS_PROGRESS4_DESC
+        U8  progress4_desc[PROGRESS_DESC_LEN]; //Progress 4 desc.
+public _extern SYS_PROGRESS4_MAX I64 progress4_max; //Progress 4 max.
+public _extern SYS_PROGRESS4_T0 F64 progress4_t0; //Progress 4 start time.
+public _extern SYS_PROGRESS4_TF F64 progress4_tf; //Progress 4 end time.
+public _extern SYS_PROGRESSES
+        CProgress sys_progresses[PROGRESS_BARS_NUM]; //All progress bars.
+
+#help_index "MultiCore"
+#help_file "::/Doc/MultiCore"
+public _extern SYS_CPU_STRUCTS CCPU *cpu_structs; //Gs points to cur CCPU.
+public _extern SYS_MP_CNT I64 mp_cnt; //Count of cores
+_extern SYS_MP_CNT_INITIAL I64 mp_cnt_initial; //only used during Core0StartMP
+_extern SYS_MP_CNT_LOCK I64 mp_cnt_lock;
+_extern SYS_SEMAS CSema sys_semas[SEMA_SEMAS_NUM];
+
+#help_index "MultiCore;Processor"
+public _intern IC_GS CCPU *Gs(); //GS points to current CCPU.
+
+#help_index "PCI"
+public _extern SYS_PCI_BUSES U16 sys_pci_busses; //Number of PCI buses.
+
+#help_index "Processor"
+public _intern IC_CARRY I64 Carry(); //See ::/Demo/Carry.HC
+public _intern IC_GET_RAX I64 GetRAX(); //Get RAX register value.
+public _intern IC_GET_RBP U8 *GetRBP(); //Get RBP register value.
+public _intern IC_GET_RFLAGS I64 GetRFlags(); //Get RFlags register value.
+public _intern IC_GET_RSP U8 *GetRSP(); //Get RSP register value.
+public _intern IC_POP I64 Pop(); //Pop value from stk.
+public _intern IC_PUSH U0 Push(I64 d); //Push value on stk.
+public _intern IC_SET_RAX U0 SetRAX(I64 d); //Set RAX register value.
+public _intern IC_SET_RBP U0 SetRBP(U8 *d); //Set RBP register value.
+public _intern IC_SET_RFLAGS U0 SetRFlags(I64 d); //Set RFlags register value.
+public _intern IC_SET_RSP U0 SetRSP(U8 *d); //Set RSP register value.
+public _extern _CPUID U0 CPUId(
+        U32 rax,CRAXRBCRCXRDX *res); //Do CPUID inst.
+public _extern _LXCHG_I64 I64 LXchgI64(I64 *dst,I64 d); //Locked eXchange I64s.
+public _extern _LXCHG_U16 U16 LXchgU16(U16 *dst,U16 d); //Locked eXchange U16s.
+public _extern _LXCHG_U32 U32 LXchgU32(U32 *dst,U32 d); //Locked eXchange U32s.
+public _extern _LXCHG_U8  U8 LXchgU8(U8 *dst,U8 d); //Locked eXchange U8s.
+public _extern _SET_MSR U0 SetMSR(
+        I64 model_specific_reg,I64 val); //Model Specific Reg See MSRs.
+public _extern _SYS_HLT U0 SysHlt(); //Loops doing HLT inst.
+public _extern _XCHG_I64 I64 XchgI64(I64 *dst,I64 d); //eXchange I64s.
+public _extern _XCHG_U16 U16 XchgU16(U16 *dst,U16 d); //eXchange U16s.
+public _extern _XCHG_U32 U32 XchgU32(U32 *dst,U32 d); //eXchange U32s.
+public _extern _XCHG_U8  U8 XchgU8(U8 *dst,U8 d); //eXchange U8s.
+_extern SYS_GDT CGDT sys_gdt;
+
+#help_index "Processor/Cache;Memory/Cache"
+public _intern IC_CLFLUSH U0 CLFlush(U8 *a); //Flush cache line inst.
+public _extern SYS_CACHE_LINE_WIDTH
+        I64 sys_cache_line_width; //CPU's Cache line width.
+
+#help_index "Processor/Page Tables;Memory/Page Tables"
+public _intern IC_INVLPG
+        U0 InvlPg(U8 *a); //Invalidate page at addr inst.
+public _extern MEM_PAGE_SIZE U64 mem_page_size;
+
+#help_index "Task;Processor"
+public _intern IC_FS CTask *Fs(); //FS seg reg points to the current CTask.
+
+#help_index "Time/CPU Cycles"
+#help_file "::/Doc/TimeCycles"
+public _intern IC_RDTSC I64 GetTSC(); //Get time stamp counter.
+
+#help_index ""
+
+ diff --git a/public/Wb/Kernel/KernelC.HH b/public/Wb/Kernel/KernelC.HH old mode 100644 new mode 100755 diff --git a/public/Wb/Kernel/KernelC.HH.HTML b/public/Wb/Kernel/KernelC.HH.HTML new file mode 100755 index 0000000..2cebf28 --- /dev/null +++ b/public/Wb/Kernel/KernelC.HH.HTML @@ -0,0 +1,799 @@ + + + + + + + + + + + +
+#help_index "AutoComplete"
+#help_file "::/Doc/AutoComplete"
+public extern CAutoCompleteGlbls ac;
+
+#help_index "AutoComplete/Dictionary"
+public extern CAutoCompleteDictGlbls acd;
+
+#help_index "Bit"
+public extern I64 BCnt(I64 d);
+public extern U8 *rev_bits_table,*set_bits_table;
+
+#help_index "Boot"
+#help_file "::/Doc/Boot"
+public extern U0 Reboot();
+
+#help_index "Call"
+public argpop extern I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size,
+        /*argpop*/I64 (*fp_addr)(...),...);
+//fp_addr can have any fixed number of arguments.
+
+#help_index "Call/FarCall32"
+public _extern _FAR_CALL32 Bool FarCall32(U0 (*fp_addr)());//Not reentrant
+public _extern C32_EAX U32 c32_eax;
+public _extern C32_EBX U32 c32_ebx;
+public _extern C32_ECX U32 c32_ecx;
+public _extern C32_EDI U32 c32_edi;
+public _extern C32_EDX U32 c32_edx;
+public _extern C32_EFLAGS U32 c32_eflags;
+public _extern C32_ESI U32 c32_esi;
+
+#help_index "Char/BitMaps"
+public extern U32 char_bmp_alpha[16],char_bmp_alpha_numeric[16],
+char_bmp_alpha_numeric_no_at[16],       char_bmp_word[16],
+char_bmp_dec_numeric[16],               char_bmp_hex_numeric[16],
+char_bmp_white_space[16],               char_bmp_non_eol_white_space[16],
+char_bmp_zero_cr_nl_cursor[16], char_bmp_zero_tab_cr_nl_cursor[16],
+char_bmp_zero_tab_cr_nl_cursor_dollar[16],
+char_bmp_macro[16],                     char_bmp_printable[16],
+char_bmp_displayable[16],               char_bmp_safe_dollar[16],
+char_bmp_filename[16],                  char_bmp_non_eol[16];
+
+#help_index "Char/Conversion"
+public extern U8 *Char2KeyName(I64 ch,Bool include_ctrl=TRUE);
+public extern I64 Char2ScanCode(I64 ch,I64 sc_flags=0);
+public extern U8 ScanCode2Char(I64 sc);
+public extern U8 *ScanCode2KeyName(I64 sc);
+public extern F64 Str2F64(U8 *src,U8 **_end_ptr=NULL);
+public extern I64 Str2I64(U8 *st,I64 radix=10,U8 **_end_ptr=NULL);
+public extern U8 *StrScan(U8 *src,U8 *fmt,...);
+
+#help_index "Char/Conversion;Time/Date/CDate;Date/CDate"
+public extern CDate Str2Date(U8 *src);
+
+#help_index "Char/Flags"
+public extern U0 ScanFlags(U8 *_dst_flags,U8 *lst,U8 *src);
+public extern U8 *StrPrintFlags(U8 *dst,U8 *lst,I64 flags);
+
+#help_index "Char/Lists"
+public extern I64 LstMatch(U8 *needle, U8 *haystack_lst,I64 flags=0);
+public extern U8 *LstSub(I64 sub, U8 *lst);
+
+#help_index "Char/Operations"
+public extern U8 *MStrPrint(U8 *fmt,...);
+public extern U8 *MStrUtil(U8 *src,I64 flags,F64 indent_scale_factor=0);
+public extern U8 *ScaleIndent(U8 *src,F64 indent_scale_factor);
+public extern I64 Spaces2Tabs(U8 *dst,U8 *src);
+public _extern _STRCMP I64 StrCmp(U8 *st1,U8 *st2);
+public _extern _STRCPY U0 StrCpy(U8 *dst,U8 *src);
+public extern U8 *StrFind(U8 *needle,U8 *haystack_str,I64 flags=0);
+public extern U8 *StrFirstOcc(U8 *src,U8 *marker);
+public extern U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL);
+public _extern _STRICMP I64 StrICmp(U8 *st1,U8 *st2);
+public _extern _STRIMATCH U8 *StrIMatch(U8 *needle,U8 *haystack_str);
+public extern U8 *StrLastOcc(U8 *src,U8 *marker);
+public extern U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL);
+public _extern _STRMATCH U8 *StrMatch(U8 *needle,U8 *haystack_str);
+public _extern _STRNCMP I64 StrNCmp(U8 *st1,U8 *st2,I64 n);
+public _extern _STRNICMP I64 StrNICmp(U8 *st1,U8 *st2,I64 n);
+public extern I64 StrOcc(U8 *src, U8 ch);
+public extern U8 *StrPrint(U8 *dst,U8 *fmt,...);
+public extern U8 *StrPrintJoin(U8 *dst,U8 *fmt,I64 argc,I64 *argv);
+public extern U8 *StrUtil(U8 *_src,I64 flags);
+public extern U8 *Tabs2Spaces(U8 *src);
+public extern Bool WildMatch(U8 *test_str,U8 *wild_str);
+
+#help_index "Char/Operations;Memory"
+public extern U8 *CatPrint(U8 *dst,U8 *fmt,...);
+
+#help_index "Char/Operations;Memory/Adam Heap"
+public extern U8 *AStrNew(U8 *buf);
+
+#help_index "Char/Operations;Memory/Heap"
+public extern U8 *StrNew(U8 *buf,CTask *mem_task=NULL);
+
+#help_index "Char/Output;StdOut"
+public extern U0 GetOutOfDollar();
+public extern Bool IsSilent();
+public extern U0 Print(U8 *fmt,...);
+public extern U0 PrintErr(U8 *fmt,...);
+public extern U0 PrintWarn(U8 *fmt,...);
+public extern U0 PutChars(U64 ch);
+extern U0 PutHex(I64 num,I64 width);
+public extern U0 PutKey(I64 ch=0,I64 sc=0);
+extern U0 PutS(U8 *st); //Use Print()
+public extern Bool Silent(Bool val=ON);
+extern U8 *StrPrintHex(U8 *dst,I64 num;I64 width);
+
+#help_index "Char;Debugging/Raw Output;TextBase Layer/Char"
+public extern CTextGlbls text;
+
+#help_index "Compiler/Lex"
+public extern U0 HashSrcFileSet(CCmpCtrl *cc,
+        CHashSrcSym *h,I64 line_num_offset=0);
+
+#help_index "Compiler;Cmd Line (Typically)"
+extern U8 *Load(U8 *filename,I64 ld_flags=0,
+        CBinFile *bfh_addr=INVALID_PTR); //INVALID_PTR=don't care what load addr
+
+#help_index "Compression"
+public extern CArcCompress *CompressBuf(U8 *src,I64 size,CTask *mem_task=NULL);
+public extern U8 *ExpandBuf(CArcCompress *arc,CTask *mem_task=NULL);
+
+#help_index "Compression/Piece by Piece"
+public extern U0 ArcCompressBuf(CArcCtrl *c);
+public extern U0 ArcCtrlDel(CArcCtrl *c);
+public extern CArcCtrl *ArcCtrlNew(Bool expand,I64 compression_type=CT_8_BIT);
+public extern U0 ArcExpandBuf(CArcCtrl *c);
+public extern Bool ArcFinishCompression(CArcCtrl *c);
+
+#help_index "Data Types/Circular Queue"
+public extern I64       QueCnt(CQue *head);
+public extern CQue      *QueCopy(CQue *head,CTask *mem_task=NULL);
+public extern U0        QueDel(CQue *head,Bool querem=FALSE);
+public extern I64       QueSize(CQue *head);
+
+#help_index "Data Types/Fifo"
+public extern I64       FifoI64Cnt(CFifoI64 *f);
+public extern U0        FifoI64Del(CFifoI64 *f);
+public extern U0        FifoI64Flush(CFifoI64 *f);
+public extern Bool      FifoI64Ins(CFifoI64 *f,I64 q);
+public extern CFifoI64  *FifoI64New(I64 size,CTask *mem_task=NULL);
+public extern Bool      FifoI64Peek(CFifoI64 *f,I64 *_q);
+public extern Bool      FifoI64Rem(CFifoI64 *f,I64 *_q);
+public extern I64       FifoU8Cnt(CFifoU8 *f);
+public extern U0        FifoU8Del(CFifoU8 *f);
+public extern U0        FifoU8Flush(CFifoU8 *f);
+public extern Bool      FifoU8Ins(CFifoU8 *f,U8 b);
+public extern CFifoU8   *FifoU8New(I64 size,CTask *mem_task=NULL);
+public extern Bool      FifoU8Peek(CFifoU8 *f,U8 *_b);
+public extern Bool      FifoU8Rem(CFifoU8 *f,U8 *_b);
+
+#help_index "Data Types/Linked List"
+public extern I64       LinkedLstCnt(U8 **_lst);
+public extern U8        *LinkedLstCopy(U8 **_lst,CTask *mem_task=NULL);
+public extern U0        LinkedLstDel(U8 **_lst);
+public extern I64       LinkedLstSize(U8 **_lst);
+
+#help_index "Data Types/Queue Vector"
+public extern U0        QueVectU8Del(CQueVectU8 *v);
+public extern I64       QueVectU8Get(CQueVectU8 *v,I64 idx);
+public extern CQueVectU8 *QueVectU8New(I64 min_idx=0);
+public extern U0        QueVectU8Put(CQueVectU8 *v,I64 idx,U8 ch);
+
+#help_index "Debugging"
+public extern U8 *Caller(I64 num=1);
+public extern Bool ChkCodePtr(U8 *ptr);
+public extern Bool ChkOnStk(U8 *ptr,CTask *task=NULL);
+public extern Bool ChkPtr(U8 *ptr);
+public extern Bool IsSingleUser();
+public extern Bool IsSysDbg();
+public extern Bool SingleUser(Bool val);
+public extern Bool SysDbg(Bool val);
+public extern U8 *TaskCaller(CTask *task=NULL,
+        I64 num=0,Bool saved_context=FALSE);
+public extern I64 UnusedStk(CTask *task=NULL);
+public extern CDbgGlbls dbg;
+
+#help_index "Debugging/Debugger"
+public extern Bool B(U8 *addr,CTask *task=NULL,Bool live=TRUE) //Toggle bpt.
+public extern I64 B2(CTask *task=NULL,Bool live=TRUE);
+extern CBpt *BptFind(U8 *needle_addr,CTask *haystack_task=NULL,Bool rem=FALSE);
+public extern Bool BptR(U8 *addr,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE);
+public extern Bool BptS(U8 *addr,CTask *task=NULL,Bool live=TRUE);
+public extern Bool DbgMode(Bool val);
+public extern Bool E(U8 *addr,I64 cnt=512,I64 edf_dof_flags=0);
+public extern Bool EdLite(U8 *filename,I64 num=1,I64 edf_dof_flags=0);
+extern Bool EdLiteFileLine(U8 *fl_file_line,I64 edf_dof_flags=0);
+public extern Bool Fix(I64 edf_dof_flags=0);
+public extern U0 FixSet(U8 *filename,I64 line);
+public extern U0 G(U8 *ms=INVALID_PTR,CTask *task=NULL);
+public extern U0 G2(U8 *ms=INVALID_PTR,CTask *task=NULL);
+public extern Bool IsDbgMode();
+public extern U0 S(U8 *ms=INVALID_PTR,CTask *task=NULL);
+
+#help_index "Debugging/Debugger;DolDoc/Cmd Line (Typically);"\
+        "Cmd Line (Typically);Help System"
+public extern Bool Man(U8 *st,I64 edf_dof_flags=0);
+
+#help_index "Debugging/Dump"
+public extern U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL);
+public extern U0 D(U8 *addr,I64 cnt=0x80,Bool show_offset=TRUE);
+public extern U0 Da(U8 **addr,I64 cnt=0x10);
+public extern U0 Dm(U8 *addr,I64 cnt=0x80);
+public extern U0 Dr(CTask *task=NULL);
+public extern U0 StkRep(CTask *task=NULL);
+extern I64 *TaskRegAddr(CTask *task,I64 reg_num);
+
+#help_index "Debugging/FunSeg"
+#help_file "::/Doc/DbgFunSeg"
+public extern Bool PutSrcLink(U8 *addr,I64 cnt=1,U8 *buf=NULL);
+public extern U8 *SrcEdLink(U8 *addr,I64 cnt=1,CTask *mem_task=NULL);
+public extern U8 *SrcFileName(U8 *addr,I64 cnt=1,CTask *mem_task=NULL);
+public extern I64 SrcLineNum(U8 *addr,I64 cnt=1);
+
+#help_index "Debugging/FunSeg;Hash/System"
+public extern CHash *FunSegFind(U8 *addr,I64 *_offset);
+
+#help_index "Debugging/Raw Output"
+public extern Bool IsRaw();
+public extern Bool Raw(Bool val);
+public extern U0 RawD(I64 mS=100,U8 *addr,I64 cnt=0x80);
+public extern U0 RawDm(I64 mS=100,U8 *addr,I64 cnt=0x80);
+extern U0 RawDr(CTask *task=NULL);
+public extern U0 RawPrint(I64 mS=100,U8 *fmt,...);
+public extern U0 RawPutChar(I64 ch);
+public extern U0 VGAFlush();
+
+#help_index "Debugging;Debugging/Debugger"
+public extern U0 Dbg(U8 *msg=NULL,I64 msg_num=0);
+public extern U0 Panic(U8 *msg=NULL,I64 msg_num=0,Bool panic=TRUE);
+
+#help_index "Define;Char/Define"
+#help_file "::/Doc/Define"
+public extern U8 *Define(U8 *dname);
+public extern CHashDefineStr *DefineLoad(U8 *dname,U8 *st);
+public extern U0 DefinePrint(U8 *dname,U8 *src,...);
+
+#help_index "Define;Char/Define;Char/Lists"
+public extern I64 DefineCnt(U8 *dname);
+public extern CHashDefineStr *DefineLstLoad(U8 *dname,U8 *lst);
+public extern I64 DefineMatch(U8 *needle,U8 *haystack_lst_dname,I64 flags=0);
+public extern U8 *DefineSub(I64 sub,U8 *dname);
+
+#help_index "Devices;Memory/Page Tables"
+public extern U8 *Mem32DevAlloc(I64 size,I64 alignment);
+public extern U0 Mem32DevFree(U8 *base);
+public extern U8 *Mem64DevAlloc(I64 *_pages1Gig);
+public extern U0 Mem64DevFree(U8 *base,I64 pages1Gig);
+public extern CDevGlbls dev;
+
+#help_index "DolDoc/Clip"
+public extern CDoc *sys_clip_doc;
+
+#help_index "DolDoc/Task;StdOut/Task"
+#help_file "::/Doc/StdOutTask"
+extern CDoc *(*fp_doc_put)(CTask *task=NULL);
+
+#help_index "Exceptions"
+public extern U0 Break();
+public extern Bool BreakLock(CTask *task=NULL);
+public extern Bool BreakUnlock(CTask *task=NULL);
+public extern U0 PutExcept(Bool catch_it=TRUE);
+extern U0 SysTry(U8 *start_label,U8 *skip_label);
+extern U0 SysUntry();
+public extern U0 throw(I64 ch=0,Bool no_log=FALSE);
+
+#help_index "File/CD DVD"
+public extern U0 DVDImageRead(U8 dvd_drv_let,U8 *out_name);
+public extern U0 DVDImageWrite(U8 dvd_drv_let,
+        U8 *in_name=NULL,I64 media_type=MT_DVD);
+
+#help_index "File/CFile"
+public extern Bool FBlkRead(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+public extern Bool FBlkWrite(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
+public extern U0 FClose(CFile *f);
+public extern CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0);
+public extern I64 FSize(CFile *f);
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
+public extern Bool Cd(U8 *dirname=NULL,Bool make_dirs=FALSE);
+public extern I64 Del(U8 *files_find_mask,Bool make_mask=FALSE,
+        Bool del_dir=FALSE,Bool print_msg=TRUE);
+public extern I64 Dir(U8 *files_find_mask="*",Bool full=FALSE);
+public extern Bool DirMk(U8 *filename,I64 entry_cnt=0);
+public extern Bool Drv(U8 drv_let);
+public extern U0 DskChg(U8 drv_let=0);
+public extern U0 HomeSet(U8 *dirname);
+
+#help_index "File/Cmd Line (Typically);Cmd Line (Typically);Install"
+public extern Bool DrvMap(U8 drv_let,CDrv *dv);
+
+#help_index "File/FileNames"
+extern CDirEntry *Cd2DirEntry(CDirEntry *tmpde,U8 *abs_name);
+public extern U8 *DirCur(CTask *task=NULL,CTask *mem_task=NULL);
+public extern U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL);
+public extern U8 *DirNameAbs(U8 *dirname);
+public extern CBlkDev *DrvIsWritable(U8 drv_let=0,Bool except=FALSE);
+public extern U8 *ExtChg(U8 *filename,U8 *extension);
+public extern U8 *ExtDft(U8 *filename,U8 *extension);
+public extern U8 *FileExtDot(U8 *src);
+public extern U8 *FileExtRem(U8 *src,U8 *dst=NULL);
+public extern U8 *FileNameAbs(U8 *filename,I64 fuf_flags=0);
+public extern Bool FileNameChk(U8 *filename);
+public extern Bool FilesFindMatch(U8 *_test_name,
+        U8 *files_find_mask,I64 fuf_flags=0);
+public extern Bool IsDir(U8 *dir_name);
+public extern Bool IsDotC(U8 *filename);
+public extern Bool IsDotZ(U8 *filename);
+public extern U0 PutDirLink(U8 *dirname,U8 *full_name=NULL);
+public extern U0 PutFileLink(U8 *filename,U8 *full_name=NULL,
+        I64 line=0,Bool plain_text=FALSE);
+public extern U0 ToFileLine(U8 *_fl_file_line,U8 **_filename,I64 *_linenum);
+public extern U8 *ToggleZorNotZ(U8 *name);
+
+#help_index "File/FileNames;Misc"
+public extern U8 *FileNameTmpTxt();
+
+#help_index "File/Internal"
+public extern U0 DirContextDel(CDirContext *dirc,Bool restore=TRUE);
+public extern CDirContext *DirContextNew(U8 *mask,
+        Bool make_mask=FALSE,Bool make_dirs=FALSE,Bool no_mask=FALSE);
+public extern Bool DirNew(CDrv *dv,U8 *cur_dir,
+        CDirEntry *tmpde,Bool free_old_chain=TRUE);
+extern I64 FileAttr(U8 *name,I64 old_attr=0);
+
+#help_index "File/Low Level"
+#help_file "::/Doc/FileLowLevel"
+public extern CBlkDev *BlkDevChk(CBlkDev *bd,Bool except=TRUE);
+public extern U0 BlkDevDel(CBlkDev *bd);
+public extern Bool BlkDevLock(CBlkDev *bd);
+public extern CBlkDev *BlkDevNextFreeSlot(U8 first_drv_let,I64 type);
+public extern Bool BlkDevUnlock(CBlkDev *bd,Bool rst=FALSE);
+public extern U0 BlkDevsRelease();
+public extern Bool BlkRead(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+public extern Bool BlkWrite(CDrv *dv,U8 *buf, I64 blk, I64 cnt);
+public extern U0 BlkWriteZero(CDrv *dv,I64 blk,I64 cnt);
+public extern I64 Clus2Blk(CDrv *dv,I64 c);
+public extern I64 ClusAlloc(CDrv *dv,I64 c=0,
+        I64 cnt=1,Bool contiguous=FALSE);
+public extern I64 ClusBlkRead(CDrv *dv,U8 *buf,I64 c,I64 blks);
+public extern I64 ClusBlkWrite(CDrv *dv,U8 *buf,I64 c,I64 blks);
+public extern I64 ClusNumNext(CDrv *dv,I64 c,I64 cnt=1);
+public extern I64 ClusRead(CDrv *dv,U8 *buf,I64 c,I64 cnt);
+public extern I64 ClusWrite(CDrv *dv,U8 *buf,I64 c,I64 cnt);
+extern Bool CopySingle(U8 *f1,U8 *f2); //Just one file
+public extern U8 Drv2Let(CDrv *dv=NULL);
+public extern CDrv *DrvChk(CDrv *dv,Bool except=TRUE);
+public extern U0 DrvDel(CDrv *dv);
+public extern Bool DrvLock(CDrv *dv);
+public extern CDrv *DrvMakeFreeSlot(U8 drv_let);
+public extern U8 *DrvModelNum(U8 drv_let=0);
+public extern U8 DrvNextFreeLet(U8 first_drv_let='C');
+public extern U8 *DrvSerialNum(U8 drv_let=0);
+public extern U8 DrvTextAttrGet(U8 drv_let=0);
+public extern Bool DrvUnlock(CDrv *dv,Bool rst=FALSE);
+public extern U0 DrvsRelease();
+extern U0 FAT32FreeClus(CDrv *dv,I64 c);
+public extern CBlkDev *Let2BlkDev(U8 drv_let=0,Bool except=TRUE);
+public extern I64 Let2BlkDevType(U8 drv_let);
+public extern CDrv *Let2Drv(U8 drv_let=0,Bool except=TRUE);
+public extern U8 Let2Let(U8 drv_let=0);
+extern I64 Name2DirClus(CDrv *dv,U8 *dirname);
+extern I64 Name2ParentDirClus(CDrv *dv,U8 *dirname);
+extern U0 RedSeaFreeClus(CDrv *dv,I64 c,I64 cnt);
+
+#help_index "File/Program Routines"
+public extern U0 DirEntryDel(CDirEntry *tmpde);
+public extern U0 DirEntryDel2(CDirEntry *tmpde);
+public extern U0 DirTreeDel(CDirEntry *tmpde);
+public extern U0 DirTreeDel2(CDirEntry *tmpde);
+public extern Bool FileFind(U8 *filename,CDirEntry *_de=NULL,I64 fuf_flags=0);
+public extern U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL);
+public extern I64 FileWrite(U8 *filename,
+        U8 *fbuf,I64 size,CDate cdt=0,I64 attr=0);
+
+#help_index "File/Program Routines;File/FileNames"
+public extern CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0);
+
+#help_index "File/System"
+public extern CATARep *ATAIDDrvs(CATARep *head,CATARep **_ata_drv,
+        CATARep **_atapi_drv);
+extern CBlkDev *ATAMount(U8 first_drv_let,
+        I64 type,I64 base0,I64 base1,I64 unit);
+extern Bool ATAPIStartStop(CBlkDev *bd,F64 timeout,Bool start);
+extern I64 ATAProbe(I64 base0,I64 base1,I64 unit);
+extern U0 ATAReadBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt);
+extern U0 ATAWriteBlks(CBlkDev *bd,U8 *buf, I64 blk, I64 cnt);
+extern I64 BlkDevAdd(CBlkDev *bd,I64 prt_num=I64_MIN,
+        Bool whole_drv,Bool make_free);
+extern U0 DskCacheInit(I64 size_in_U8s);
+public extern U0 DskCacheInvalidate(CDrv *dv);
+public extern I64 MountIDEAuto();
+public extern CBlkDevGlbls blkdev;
+
+#help_index "Graphics/Color"
+extern U0 (*fp_set_std_palette)();
+public extern U8 *Color2Str(U8 *buf,CColorROPU32 c);
+public extern CColorROPU16 Str2ColorU16(U8 *st);
+public extern CColorROPU32 Str2ColorU32(U8 *st);
+
+#help_index "Hash"
+#help_file "::/Doc/Hash"
+public _extern _HASH_ADD U0 HashAdd(CHash *tmph,CHashTable *table);
+public _extern _HASH_ADD_AFTER U0 HashAddAfter(CHash *tmph,
+        CHash *pred,CHashTable *table); //Add hash entry after entry.
+public _extern _HASH_BUCKET_FIND CHash **HashBucketFind(
+        U8 *needle_str,CHashTable *haystack_table);
+public _extern _HASH_FIND CHash *HashFind(U8 *needle_str,
+        CHashTable *haystack_table,I64 mask,I64 instance=1);
+public _extern _HASH_SINGLE_TABLE_FIND CHash *HashSingleTableFind(
+        U8 *needle_str,CHashTable *haystack_table,I64 mask,I64 instance=1);
+public _extern _HASH_STR I64 HashStr(U8 *st);
+public extern CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL);
+
+#help_index "Hash/Frame"
+#help_file "::/Doc/Frame"
+public extern I64 FramePtr(U8 *name,CTask *task=NULL);
+public extern CHashGeneric *FramePtrAdd(U8 *name,I64 val=0,CTask *task=NULL);
+public extern I64 FramePtrDel(U8 *name,CTask *task=NULL);
+public extern I64 FramePtrSet(U8 *name,I64 val,CTask *task=NULL);
+
+#help_index "Hash/System"
+public extern U0 HashDel(CHashSrcSym *tmph);
+public extern CHashGeneric *HashGenericAdd(U8 *name,
+        I64 type,I64 val=0,I64 u8=0,I64 u16=0,CTask *task=NULL);
+public extern CHashGeneric *HashPublic(U8 *st,I64 mask,Bool val=TRUE);
+public _extern _HASH_REM_DEL Bool HashRemDel(CHash *tmph,CHashTable *table,
+        I64 instance=1);//instance must match tmph's
+public extern U0 HashTableDel(CHashTable *table);
+public extern I64 HashTablePurge(CHashTable *table);
+public extern I64 HashTypeNum(CHash *tmph);
+public extern I64 HashVal(CHash *tmph);
+extern U0 SysSymImportsResolve(U8 *sptr,I64 ld_flags=0);
+
+#help_index "Hash/System;Char/Lists"
+public extern I64 HashLstAdd(U8 *lst,I64 type,CHashTable *table);
+
+#help_index "Hash/System;Define;Char/Define;Char/Lists"
+public extern I64 HashDefineLstAdd(U8 *dname,I64 type,CHashTable *table);
+
+#help_index "Help System;Debugging/Debugger"
+public extern U0 Help();
+
+#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically);Install"
+public extern U0 DrvRep();
+
+#help_index "Install"
+#help_file "::/Doc/Install"
+extern CATARep *ATARepFind(CATARep *haystack_head,I64 needle_num);
+public extern Bool DrvEnable(U8 drv_let,Bool val);
+
+#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
+public extern U0 Fmt(U8 drv_let,Bool quick=TRUE,
+        Bool confirm=TRUE,I64 type=FSt_FAT32);
+
+#help_index "Install;Memory/BlkPool"
+public extern I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024);
+
+#help_index "Job/Exe;Task/Job/Exe"
+public extern U0 AdamErr(U8 *fmt,...);
+public extern U0 AdamLog(U8 *fmt,...);
+public extern I64 ExeCmdLine(CCmpCtrl *cc);
+public extern U0 JobDel(CJob *tmpc);
+public extern I64 JobsHndlr(I64 run_flags,CTask *task=NULL);
+extern U0 SrvCmdLine();
+public extern U0 SrvTaskCont();
+public extern CJob *TaskExe(CTask *srv,CTask *master,U8 *data,I64 flags);
+public extern U0 TaskRstAwaitingMsg(CTask *task=NULL);
+public extern U0 UserTaskCont();
+
+#help_index "Job/Exe;Task/Job/Exe;Compiler"
+public extern I64 Adam(U8 *fmt,...);
+public extern I64 PopUp(U8 *buf,CTask *parent=NULL,CTask **_pu_task=NULL);
+public extern I64 PopUpPrint(U8 *fmt,...);
+
+#help_index "Job/Exe;Task/Job/Exe;MultiCore"
+public extern I64 JobResGet(CJob *rqst=NULL);
+public extern Bool JobResScan(CJob *rqst=NULL,I64 *_res=NULL);
+
+#help_index "Job/Text & Msgs;Task/Job/Text & Msgs"
+public extern CJob *TaskText(CTask *srv,CTask *master,U8 *data,I64 flags);
+
+#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;InFile;StdIn/InFile"
+public extern U0 In(U8 *fmt,...);
+public extern U0 InFile(U8 *filename);
+public extern U0 InStr(U8 *fmt,...);
+public extern U0 XTalk(CTask *task,U8 *fmt,...);
+public extern U0 XTalkStr(CTask *task,U8 *fmt,...);
+public extern U0 XTalkStrWait(CTask *task,U8 *fmt,...);
+public extern U0 XTalkWait(CTask *task,U8 *fmt,...);
+
+#help_index "Job/Text & Msgs;Task/Job/Text & Msgs;Messages"
+public extern U0 Msg(I64 msg_code,I64 arg1,I64 arg2,I64 flags=0);
+public extern U0 PostMsg(CTask *task,
+        I64 msg_code,I64 arg1,I64 arg2,I64 flags=0);
+public extern U0 PostMsgWait(CTask *task,I64 msg_code,
+        I64 arg1,I64 arg2,I64 flags=0);
+public extern CJob *TaskMsg(CTask *srv,CTask *master,
+                     I64 msg_code,I64 arg1,I64 arg2,I64 flags);
+
+#help_index "Job;Task/Job"
+#help_file "::/Doc/Job"
+
+#help_index "Keyboard Devices/System;Char/System"
+#help_file "::/Doc/KeyDev"
+public extern U0 CtrlAltCBSet(U8 ch,U0 (*fp_hndlr)(I64 sc),
+        U8 *no_shift_desc=NULL,U8 *shift_desc=NULL,Bool in_irq=FALSE);
+public extern U0 KeyDescSet(U8 *fmt,...);
+public extern CKeyDevEntry *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc),
+        Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE);
+public extern U0 KeyDevRem(CKeyDevEntry *tmpk);
+extern CKeyDevGlbls keydev;
+extern CJob sys_macro_head;
+extern CTask *sys_macro_task;
+
+#help_index "Keyboard Devices;Char/Input;StdIn"
+extern U8  *(*fp_getstr2)(I64 flags=0); //GetStr Flags
+public extern Bool AreYouSure();
+public extern I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,
+        Bool raw_cursor=FALSE);
+public extern I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE,
+        Bool raw_cursor=FALSE);
+public extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE);
+public extern U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0);
+extern U0       KbdInit();
+public extern I64 KbdMsEvtTime();
+extern U0       KbdMsHndlr(Bool poll_kbd,Bool poll_ms);
+extern U0       KbdMsInit();
+extern I64      KbdMsgsQue();
+public extern U0 KbdTypeMatic(U8 delay);
+extern Bool     MsHardDrvrInstall();
+public extern I64 PressAKey();
+public extern I64 ScanChar();
+public extern Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE);
+public extern Bool YorN();
+public extern CKbdStateGlbls    kbd;
+
+#help_index "Math"
+public extern I64 CeilI64(I64 num,I64 to);
+public extern U64 CeilU64(U64 num,U64 to);
+public extern F64 Clamp(F64 d,F64 lo,F64 hi);
+public extern I64 FloorI64(I64 num,I64 to);
+public extern U64 FloorU64(U64 num,U64 to);
+public extern F64 Max(F64 n1,F64 n2);
+public extern F64 Min(F64 n1,F64 n2);
+public extern F64 Pow10I64(I64 i);
+public extern F64 Rand(); //With timestamp
+public extern I16 RandI16();
+public extern I32 RandI32();
+public extern I64 RandI64();
+public extern U16 RandU16();
+public extern U32 RandU32();
+public extern U64 RandU64();
+public extern I64 RoundI64(I64 num,I64 to);
+public extern I64 Seed(I64 seed=0,CTask *task=NULL);
+
+#help_index "Memory/Adam Heap"
+public extern U8 *ACAlloc(I64 size);
+public extern U8 *AMAlloc(I64 size);
+public extern U8 *AMAllocIdent(U8 *src);
+
+#help_index "Memory/BlkPool"
+public extern U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pags);
+public extern U0 BlkPoolInit(CBlkPool *bp,I64 pags);
+public extern U8 *MemPagAlloc(I64 pags,CBlkPool *bp=NULL);
+public extern U0 MemPagFree(CMemBlk *m,CBlkPool *bp=NULL);
+
+#help_index "Memory/Heap"
+public extern U8 *CAlloc(I64 size,CTask *mem_task=NULL);
+public extern U8 *CAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0);
+public _extern _FREE U0 Free(U8 *addr);
+public _extern _MALLOC U8 *MAlloc(I64 size,CTask *mem_task=NULL);
+public extern U8 *MAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0);
+public extern U8 *MAllocIdent(U8 *src,CTask *mem_task=NULL);
+public _extern _MHEAP_CTRL CHeapCtrl *MHeapCtrl(U8 *src);
+public _extern _MSIZE I64 MSize(U8 *src);   //size of heap object
+public _extern _MSIZE2 I64 MSize2(U8 *src); //Internal size
+
+#help_index "Memory/HeapCtrl"
+public extern U0 HeapCtrlDel(CHeapCtrl *hc);
+public extern CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,
+        CTask *task=NULL,CBlkPool *bp);
+
+#help_index "Memory/Page Tables"
+public extern I64 *MemPageTable(U8 *a);
+
+#help_index "Messages"
+#help_file "::/Doc/Msgs"
+public extern I64 FlushMsgs(CTask *task=NULL);
+public extern I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,
+        I64 mask=~1,CTask *task=NULL);
+extern U0 InputFilterTask();
+public extern I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,
+        I64 mask=~1,CTask *task=NULL);
+
+#help_index "Misc"
+public extern I64 EndianI64(I64 d);
+public extern U16 EndianU16(U16 d);
+public extern U32 EndianU32(U32 d);
+public extern U0 QSort(U8 *base,I64 num, I64 width,
+        I64 (*fp_compare)(U8 *e1,U8 *e2));
+public extern U0 QSortI64(I64 *base,I64 num,
+        I64 (*fp_compare)(I64 e1,I64 e2));
+public extern F64 sys_os_version;
+
+#help_index "Misc/Progress Bars"
+public extern U0 ProgressBarsRst(U8 *path=NULL);
+
+#help_index "Mouse"
+#help_file "::/Doc/Mouse"
+public extern U0 GridInit();
+public extern U0 MsSet(I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,
+        I64 l=I64_MAX,I64 r=I64_MAX);
+public extern CMsStateGlbls ms;
+public extern CGridGlbls ms_grid;
+public extern CMsHardStateGlbls ms_hard;
+extern CMsHardStateGlbls ms_hard_last;
+extern CMsStateGlbls ms_last;
+
+#help_index "Mouse/Ptr"
+extern U0 MsInit();
+extern U0 MsUpdate(I64 x,I64 y,I64 z,Bool l,Bool r);
+
+#help_index "MultiCore"
+extern U0 Core0StartMP();
+extern U0 CoreAPSethTask();
+public extern U0 MPInt(U8 num,I64 cpu_num=1);
+public extern U0 MPIntAll(U8 num);
+public extern U0 MPNMInt();
+extern CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,
+        U8 *task_name=NULL,I64 target_cpu,
+        CTask *parent=NULL, //NULL means adam
+        I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE);
+
+#help_index "MultiCore;Boot"
+public extern U0 MPHalt();
+
+#help_index "MultiCore;Job/Exe;Task/Job/Exe"
+public extern CJob *JobQue(I64 (*fp_addr)(U8 *data),U8 *data=NULL,
+        I64 target_cpu=1,I64 flags=1<<JOBf_FREE_ON_COMPLETE,
+        I64 job_code=JOBT_CALL,U8 *aux_str=NULL,I64 aux1=0,I64 aux2=0);
+
+#help_index "PCI"
+public extern I64 PCIClassFind(I64 class_code,I64 n);
+public extern U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg);
+public extern U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg);
+public extern U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg);
+public extern U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
+public extern U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
+public extern U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
+public _extern SYS_PCIBIOS_SERVICE_DIR
+        U32 sys_PCIBIOS_service_dir;//Far call routine in the BIOS
+public _extern SYS_PCI_SERVICES
+        U32 sys_pci_services;//Far call routine in the BIOS
+
+#help_index "PCI;Info;File/System;Devices"
+public extern I64 ATARep(Bool pmt=TRUE,
+        Bool just_ide=FALSE,CATARep **_head=NULL);
+
+#help_index "Processor"
+public extern U8 *IntEntryGet(I64 irq);
+public extern U8 *IntEntrySet(I64 irq,
+        U0 (*fp_new_hndlr)(),I64 type=IDTET_IRQ,I64 dpl=0);
+
+#help_index "ScrnCast;Cmd Line (Typically)"
+public extern Bool ScrnCast(Bool val=ON,Bool just_audio=FALSE,
+        U8 *print_fmt="B:/Tmp/%X.GR")
+public extern CScrnCastGlbls scrncast;
+
+#help_index "Snd"
+#help_file "::/Doc/Snd"
+public extern U0 Beep(I8 ona=62,Bool busy=FALSE);
+public extern I8 Freq2Ona(F64 freq);
+public extern Bool IsMute();
+public extern Bool Mute(Bool val);
+public extern F64 Ona2Freq(I64 ona);
+public extern U0 Snd(I8 ona=0);
+public extern U0 SndRst();
+
+#help_index "StdIn"
+#help_file "::/Doc/Streams"
+
+#help_index "StdOut"
+#help_file "::/Doc/Streams"
+
+#help_index "Task"
+public extern I64 BirthWait(CTask **_task,I64 task_num=-1);
+public extern U0 DeathWait(CTask **_task,Bool send_exit=FALSE);
+public extern U0 Exit();
+public extern Bool IsSuspended(CTask *task=NULL);
+public extern Bool Kill(CTask *task,Bool wait=TRUE,Bool just_break=FALSE);
+public extern Bool Suspend(CTask *task=NULL,Bool state=TRUE);
+_extern _TASK_CONTEXT_RESTORE U0 TaskContextRestore();
+_extern _TASK_END_NOW U0 TaskEndNow();
+extern U0 TaskKillDying();
+public extern U0 TaskQueIns(CTask *task,CTask *pred=NULL);
+public extern U0 TaskQueRem(CTask *task);
+public extern Bool TaskValidate(CTask *task);
+public extern U0 TaskWait(CTask *task=NULL,Bool cmd_line_pmt=FALSE);
+public extern CTask *User(U8 *fmt=NULL,...);
+public extern U0 UserCmdLine();
+public _extern _YIELD U0 Yield();
+public extern CTask *adam_task;
+public extern I64 sys_num_spawned_tasks;
+extern CTask *sys_winmgr_task,*sys_task_being_scrn_updated;
+
+#help_index "Task/Delay;Time/CPU Cycles"
+public extern U0 Busy(I64 uS); //Loosely timed
+public extern U0 PortNop(); //On the order of 1uS
+extern I64 TimeCal();
+
+#help_index "Task/Delay;Time/Jiffies"
+public extern U0 Sleep(I64 mS);
+public extern U0 SleepUntil(I64 wake_jiffy);
+
+#help_index "Task/Misc"
+extern U0 (*fp_update_ctrls)(CTask *task);
+public extern U0 TSSBusy(I64 tr,Bool val=OFF);
+public extern U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE);
+public extern U0 WinDerivedValsUpdate(CTask *task);
+
+#help_index "Task;Job/Exe;Task/Job/Exe;MultiCore"
+public extern CTask *Spawn(U0 (*fp_addr)(U8 *data),U8 *data=NULL,
+        U8 *task_name=NULL,I64 target_cpu=-1,   //-1 means current CPU
+        CTask *parent=NULL, //NULL means adam
+        I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE);
+
+#help_index "Time/CPU Cycles;Time/HPET;Time/Jiffies"
+public extern CCntsGlbls cnts;
+
+#help_index "Time/Date/CDate;Date/CDate"
+#help_file "::/Doc/TimeDate"
+public extern U0 Date2Struct(CDateStruct *_ds,CDate cdt);
+extern U8 *MPrintDate(CDate cdt);
+extern U8 *MPrintTime(CDate cdt);
+public extern CDate Now();
+public extern CDate Struct2Date(CDateStruct *_ds);
+public extern CDate local_time_offset;
+
+#help_index "Time/Date;Date"
+#help_file "::/Doc/Date"
+public extern I64 DayOfWeek(I64 i);
+public extern I64 FirstDayOfMon(I64 i);
+public extern I64 FirstDayOfYear(I64 i);
+public extern I64 LastDayOfMon(I64 i);
+public extern I64 LastDayOfYear(I64 i);
+public extern I64 YearStartDate(I64 year);
+public extern U16 mon_start_days1[12];
+public extern U16 mon_start_days2[12];
+
+#help_index "Time/HPET"
+#help_file "::/Doc/TimeHPET"
+public extern I64 HPET();
+
+#help_index "Time/Jiffies"
+#help_file "::/Doc/TimeJiffy"
+public extern I64 SysTimerRead();//18.33333*65536Hz (SYS_TIMER_FREQ)
+
+#help_index "Time/Seconds"
+public extern Bool Blink(F64 Hz=2.5);
+public extern F64 tS(); //From SysTimerFreq.
+
+#help_index "Windows"
+public extern Bool WinInside(I64 x,I64 y,CTask *task=NULL,I64 border=0);
+
+#help_index ""
+
+ diff --git a/public/Wb/Kernel/KeyDev.HC.HTML b/public/Wb/Kernel/KeyDev.HC.HTML new file mode 100755 index 0000000..f6bcf01 --- /dev/null +++ b/public/Wb/Kernel/KeyDev.HC.HTML @@ -0,0 +1,250 @@ + + + + + + + + + + + +
+U0 PutKey(I64 ch=0,I64 sc=0)
+{//See Keyboard Devices.
+  CKeyDevEntry *tmpk;
+  if (ch||sc) {
+    tmpk=keydev.put_key_head.next;
+    if (!Bt(&Fs->display_flags,DISPLAYf_SILENT)) {
+      if (kbd.scan_code & SCF_SCROLL && sys_focus_task==Fs)
+        while (kbd.scan_code & SCF_SCROLL)
+          Yield; //Wait on SCROLL LOCK Key
+      while (tmpk!=&keydev.put_key_head) {
+        if ((!(sc&SCF_KEY_DESC) || tmpk->flags & KDF_HAS_DESCS) &&
+              (*tmpk->put_key)(ch,sc))
+          break;
+        tmpk=tmpk->next;
+      }
+    }
+  }
+}
+
+U0 PutChars(U64 ch)
+{//Output chars. Up to 8 chars in a single U64.
+//Don't use this.  See Print() shortcut.
+  while (ch) {
+    PutKey(ch&255,0);
+    ch>>=8;
+  }
+}
+
+U0 PutS(U8 *st)
+{//Use Print(). See Keyboard Devices.
+//Don't use this.  See Print() shortcut.
+  I64 ch;
+  U8 *ptr;
+  Bool cont=TRUE;
+  if (!st) return;
+  CKeyDevEntry *tmpk=keydev.put_key_head.next;
+  if (!Bt(&Fs->display_flags,DISPLAYf_SILENT)) {
+    if (kbd.scan_code & SCF_SCROLL && sys_focus_task==Fs)
+      while (kbd.scan_code & SCF_SCROLL)
+        Yield;
+    while (cont && tmpk!=&keydev.put_key_head) {
+      if (tmpk->put_s) {
+        if ((*tmpk->put_s)(st))
+          break;
+      } else {
+        ptr=st;
+        while (ch=*ptr++)
+          if ((*tmpk->put_key)(ch,0))
+            cont=FALSE;
+      }
+      tmpk=tmpk->next;
+    }
+  }
+}
+
+U0 KeyDescSet(U8 *fmt,...)
+{//Call this from key hndlr to report desc in KeyMap().
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  StrCpy(keydev.desc,buf);
+  keydev.hndlr=Caller;
+  Free(buf);
+}
+
+U0 KeyDevRem(CKeyDevEntry *tmpk)
+{//Remove StdOut hook and free.
+  QueRem(tmpk);
+  Free(tmpk);
+}
+
+CKeyDevEntry *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc),
+        Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE)
+{//Places hook in StdOut chain. See Keyboard Devices.
+  CKeyDevEntry *tmpk=keydev.put_key_head.last,
+        *tmpk1=ACAlloc(sizeof(CKeyDevEntry));
+  tmpk1->put_key=fp_put_key;
+  tmpk1->put_s=fp_puts;
+  tmpk1->priority=priority;
+  if (key_descs)
+    tmpk1->flags|=KDF_HAS_DESCS;
+  while (tmpk->priority>priority)
+    tmpk=tmpk->last;
+  QueIns(tmpk1,tmpk);
+  if (tmpk->priority==priority)
+    KeyDevRem(tmpk);
+  return tmpk1;
+}
+
+Bool KDRawPutKey(I64 ch,I64)
+{
+  if (IsRaw) {
+    RawPutChar(ch);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool KDRawPutS(U8 *st)
+{
+  I64 ch;
+  if (IsRaw) {
+    while (ch=*st++)
+      RawPutChar(ch);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool KDInputFilterPutKey(I64 ch,I64 scan_code)
+{
+  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK)) {
+    Msg(MSG_KEY_DOWN,ch,scan_code);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+Bool KDInputFilterPutS(U8 *st)
+{
+  I64 ch;
+  if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK)) {
+    while (ch=*st++)
+      Msg(MSG_KEY_DOWN,ch,0);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 CtrlAltDel(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_DEL);
+}
+
+U0 CtrlAltC(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_C);
+}
+
+U0 CtrlAltD(I64)
+{
+  if (!IsDbgMode) {
+    if (Fs==Gs->idle_task)
+      BptS(sys_winmgr_task->rip,sys_winmgr_task);
+    else
+      BptS(*keydev.ctrl_alt_ret_addr);
+  }
+}
+
+U0 CtrlAltF(I64)
+{
+  SwapI64(&text.font,&text.aux_font);
+}
+
+U0 CtrlAltM(I64)
+{
+  Mute(!IsMute);
+}
+
+U0 CtrlAltN(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_TAB);
+}
+
+U0 CtrlAltT(I64)
+{
+  User;
+}
+
+U0 CtrlAltV(I64)
+{
+  VGAFlush;
+}
+
+U0 CtrlAltX(I64)
+{
+  LBts(sys_ctrl_alt_flags,CTRL_ALT_X);
+}
+
+U0 CtrlAltCBSet(U8 ch,U0 (*fp_hndlr)(I64 sc),
+        U8 *no_shift_desc=NULL,U8 *shift_desc=NULL,Bool in_irq=FALSE)
+{//Set callback for <CTRL-ALT-letter>.
+  ch=ToUpper(ch)-'A';
+  if (ch<26) {
+    keydev.fp_ctrl_alt_cbs[ch]=fp_hndlr;
+
+    Free(keydev.ctrl_alt_no_shift_descs[ch]);
+    if (no_shift_desc)
+      keydev.ctrl_alt_no_shift_descs[ch]=AStrNew(no_shift_desc);
+    else
+      keydev.ctrl_alt_no_shift_descs[ch]=NULL;
+
+    Free(keydev.ctrl_alt_shift_descs[ch]);
+    if (shift_desc)
+      keydev.ctrl_alt_shift_descs[ch]=AStrNew(shift_desc);
+    else
+      keydev.ctrl_alt_shift_descs[ch]=NULL;
+
+    BEqu(&keydev.ctrl_alt_in_irq_flags,ch,in_irq);
+  }
+}
+
+U0 KeyDevInit()
+{
+  keydev.fp_ctrl_alt_cbs        =CAlloc(26*sizeof(U8 *));
+  keydev.ctrl_alt_no_shift_descs=CAlloc(26*sizeof(U8 *));
+  keydev.ctrl_alt_shift_descs   =CAlloc(26*sizeof(U8 *));
+  keydev.ctrl_alt_in_irq_flags  =0;
+  MemSet(&keydev.put_key_head,0,sizeof(CKeyDevEntry));
+  QueInit(&keydev.put_key_head);
+  KeyDevAdd(&KDInputFilterPutKey,&KDInputFilterPutS,0x40000000,FALSE);
+  KeyDevAdd(&KDRawPutKey,&KDRawPutS,0x60000000,FALSE);
+  CtrlAltCBSet('C',&CtrlAltC,"Cmd /Break Execution",,TRUE);
+  CtrlAltCBSet('D',&CtrlAltD,"Cmd /Enter Debugger",,TRUE);
+  CtrlAltCBSet('F',&CtrlAltF,"Cmd /Toggle Aux Font");
+  CtrlAltCBSet('M',&CtrlAltM,"Cmd /Toggle Mute");
+  CtrlAltCBSet('N',&CtrlAltN,"Cmd /Next Focus Task",,TRUE);
+  CtrlAltCBSet('T',&CtrlAltT,"Cmd /Terminal Window");
+  CtrlAltCBSet('V',&CtrlAltV,"Cmd /VGA Flush",,TRUE);
+  CtrlAltCBSet('X',&CtrlAltX,"Cmd /Kill Focused Task",,TRUE);
+}
+
+ diff --git a/public/Wb/Kernel/Mem/BlkPool.HC.HTML b/public/Wb/Kernel/Mem/BlkPool.HC.HTML new file mode 100755 index 0000000..1931829 --- /dev/null +++ b/public/Wb/Kernel/Mem/BlkPool.HC.HTML @@ -0,0 +1,104 @@ + + + + + + + + + + + +
+U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pags)
+{//Add mem to BlkPool.
+  if (sys_mem_init_flag)
+    MemSet(m,sys_mem_init_val,pags*MEM_PAG_SIZE);
+  PUSHFD
+  CLI
+  while (LBts(&bp->locked_flags,BPlf_LOCKED))
+    PAUSE
+  m->next=bp->mem_free_lst;
+  m->pags=pags;
+  m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
+  bp->alloced_u8s+=pags<<MEM_PAG_BITS;
+  bp->mem_free_lst=m;
+  LBtr(&bp->locked_flags,BPlf_LOCKED);
+  POPFD
+}
+
+U0 BlkPoolInit(CBlkPool *bp,I64 pags)
+{//Make mem chunk into a BlkPool.
+  I64 num;
+  CMemBlk *m;
+  MemSet(bp,0,sizeof(CBlkPool));
+  m=(bp(U8 *)+sizeof(CBlkPool)+MEM_PAG_SIZE-1)&~(MEM_PAG_SIZE-1);
+  num=(bp(U8 *)+pags<<MEM_PAG_BITS-m(U8 *))>>MEM_PAG_BITS;
+  bp->alloced_u8s=(pags-num)<<MEM_PAG_BITS; //Compensate before num added.
+  BlkPoolAdd(bp,m,num);
+}
+
+U0 BlkPoolsInit()
+{
+  I64 i,total,lo,hi,code_heap_limit;
+  CMemE820 *m20=MEM_E820;
+  Bool first=TRUE;
+
+  total=BIOSTotalMem;
+
+  if (total<=0x80000000)
+    code_heap_limit=total;
+  else if (total<=0x100000000)
+    code_heap_limit=total/4;
+  else
+    code_heap_limit=0x80000000;
+
+  i=code_heap_limit-SYS_16MEG_AREA_LIMIT; //See RLf_16MEG_SYS_CODE_BP
+  BlkPoolAdd(sys_code_bp,SYS_16MEG_AREA_LIMIT,i>>MEM_PAG_BITS);
+  mem_heap_limit=i+SYS_16MEG_AREA_LIMIT-1;
+
+  if (code_heap_limit<total) {
+    while (m20->type) {
+      if (m20->type==1) {
+        lo=m20->base;
+        hi=m20->base+m20->len;
+        if (lo<code_heap_limit) {
+          if (hi>code_heap_limit)
+            lo=code_heap_limit;
+          else
+            hi=lo; //cancel
+        }
+        if (code_heap_limit<=lo<hi) {
+          if (first) {
+            BlkPoolInit(lo,(hi-lo)>>MEM_PAG_BITS);
+            sys_data_bp=lo;
+            Fs->data_heap=HeapCtrlInit(,Fs,sys_data_bp);
+            first=FALSE;
+          } else
+            BlkPoolAdd(sys_data_bp,lo,(hi-lo)>>MEM_PAG_BITS);
+        }
+      }
+      m20++;
+    }
+  }
+  LBts(&sys_run_level,RLf_FULL_HEAPS);
+}
+
+ diff --git a/public/Wb/Kernel/Mem/HeapCtrl.HC.HTML b/public/Wb/Kernel/Mem/HeapCtrl.HC.HTML new file mode 100755 index 0000000..05b7a04 --- /dev/null +++ b/public/Wb/Kernel/Mem/HeapCtrl.HC.HTML @@ -0,0 +1,64 @@ + + + + + + + + + + + +
+CHeapCtrl *HeapCtrlInit(CHeapCtrl *hc=NULL,CTask *task=NULL,CBlkPool *bp)
+{//See HeapLog() for an example.
+//Duplicated for Adam Task.
+  if (!hc)
+    hc=ACAlloc(sizeof(CHeapCtrl));
+  hc->hc_signature=HEAP_CTRL_SIGNATURE_VAL;
+  hc->mem_task=task;
+  hc->bp=bp;
+  QueInit(&hc->next_mem_blk);
+  hc->last_mergable=NULL;
+  hc->next_um=hc->last_um=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
+  return hc;
+}
+
+U0 HeapCtrlDel(CHeapCtrl *hc)
+{//Free all blks alloced to a HeapCtrl.
+  CMemBlk *m,*m1;
+  if (hc) {
+    PUSHFD
+    CLI
+    while (LBts(&hc->locked_flags,HClf_LOCKED))
+      PAUSE
+    m=hc->next_mem_blk;
+    while (m!=&hc->next_mem_blk) {
+      m1=m->next;
+      MemPagTaskFree(m,hc);
+      m=m1;
+    }
+    LBtr(&hc->locked_flags,HClf_LOCKED);
+    POPFD
+    Free(hc);
+  }
+}
+
+ diff --git a/public/Wb/Kernel/Mem/MAllocFree.HC.HTML b/public/Wb/Kernel/Mem/MAllocFree.HC.HTML new file mode 100755 index 0000000..dd1c412 --- /dev/null +++ b/public/Wb/Kernel/Mem/MAllocFree.HC.HTML @@ -0,0 +1,495 @@ + + + + + + + + + + + +
+asm {
+//************************************
+//See ::/Doc/Credits.DD.
+_MALLOC::
+// Throws 'OutMem'
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        XOR     RBX,RBX
+        MOV     RDX,U64 SF_ARG2[RBP]
+        TEST    RDX,RDX
+        JNZ     @@05
+        MOV     RDX,U64 FS:CTask.addr[RBX]
+@@05:   CMP     U32 CTask.task_signature[RDX],TASK_SIGNATURE_VAL
+
+#assert CTask.task_signature==CHeapCtrl.hc_signature //location signature same
+
+        JNE     @@10
+        MOV     RDX,U64 CTask.data_heap[RDX]
+@@10:   CMP     U32 CHeapCtrl.hc_signature[RDX],HEAP_CTRL_SIGNATURE_VAL
+        JE      @@15
+        PUSH    RDX
+        CALL    &SysBadMAlloc
+        JMP     I32 _SYS_HLT
+
+@@15:   MOV     RAX,U64 SF_ARG1[RBP]
+        PUSHFD
+        ADD     RAX,CMemUsed.start+7    //round-up to I64
+        AND     AL,0xF8
+#assert CMemUsed.start>=sizeof(CMemUnused)
+        CMP     RAX,CMemUsed.start
+        JAE     @@20
+        MOV     RAX,CMemUsed.start
+@@20:
+
+        CLI
+@@25:   LOCK
+        BTS     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        PAUSE   //don't know if this inst helps
+        JC      @@25
+
+        CMP     RAX,MEM_HEAP_HASH_SIZE
+        JAE     @@30
+        MOV     RSI,U64 CHeapCtrl.heap_hash[RAX+RDX]
+        TEST    RSI,RSI
+        JZ      @@35
+        MOV     RCX,U64 CMemUnused.next[RSI]
+        MOV     U64 CHeapCtrl.heap_hash[RAX+RDX],RCX
+        JMP     I32 MALLOC_ALMOST_DONE
+
+//Big allocation
+@@30:   ADD     RAX,sizeof(CMemBlk)+MEM_PAG_SIZE-1
+        SHR     RAX,MEM_PAG_BITS
+
+        PUSH    RDX //preserve HeapCtrl
+        PUSH    RDX
+        PUSH    RAX
+        CALL    &MemPagTaskAlloc
+        POP     RDX
+        TEST    RAX,RAX
+        JZ      @@45    //Out of memory
+        MOV     RSI,RAX
+        MOV     EAX,U32 CMemBlk.pags[RSI]
+
+        SHL     RAX,MEM_PAG_BITS
+        SUB     RAX,sizeof(CMemBlk)
+        ADD     RSI,sizeof(CMemBlk)
+        JMP     I32 MALLOC_ALMOST_DONE
+
+//Little allocation, chunk-off piece from free lst chunks
+@@35:   LEA     RSI,U64 CHeapCtrl.malloc_free_lst-CMemUnused.next[RDX]
+
+@@40:   MOV     RBX,RSI
+        MOV     RSI,U64 CMemUnused.next[RBX]
+        TEST    RSI,RSI
+        JNZ     I32 @@60
+        PUSH    RAX             //-**** save byte size
+        ADD     RAX,16*MEM_PAG_SIZE-1
+        SHR     RAX,MEM_PAG_BITS
+
+        PUSH    RDX //preserve HeapCtrl
+        PUSH    RDX
+        PUSH    RAX
+        CALL    &MemPagTaskAlloc
+        POP     RDX
+        TEST    RAX,RAX
+        JNZ     @@50
+
+//Out of memory
+@@45:   LOCK
+        BTR     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        POPFD
+        PUSH    TRUE
+        MOV     RAX,'OutMem'
+        PUSH    RAX
+        CALL    I32 &throw
+        JMP     I32 MALLOC_FINAL_EXIT //Never gets here, hopefully.
+
+@@50:   MOV     RSI,RAX
+        MOV     EAX,U32 CMemBlk.pags[RSI]
+        SHL     RAX,MEM_PAG_BITS
+
+//Can it be combined with last chunk? (Never Free these chunks.)
+        MOV     RDI,U64 CHeapCtrl.last_mergable[RDX]
+        LEA     RBX,U64 [RSI+RAX]
+        CMP     RDI,RBX
+        JNE     @@55
+
+        PUSH    RAX
+        MOV     EAX,U32 CMemBlk.pags[RDI]
+        ADD     U32 CMemBlk.pags[RSI],EAX
+//QueRem
+        MOV     RAX,U64 CMemBlk.next[RDI]
+        MOV     RBX,U64 CMemBlk.last[RDI]
+        MOV     U64 CMemBlk.last[RAX],RBX
+        MOV     U64 CMemBlk.next[RBX],RAX
+        POP     RAX
+
+@@55:   MOV     U64 CHeapCtrl.last_mergable[RDX],RSI
+        LEA     RSI,U64 sizeof(CMemBlk)[RSI]
+        SUB     RAX,sizeof(CMemBlk)
+        LEA     RBX,U64 CHeapCtrl.malloc_free_lst-CMemUnused.next[RDX]
+        MOV     RDI,U64 CMemUnused.next[RBX]
+        MOV     U64 CMemUnused.next[RSI],RDI
+        MOV     U64 CMemUnused.size[RSI],RAX
+        MOV     U64 CMemUnused.next[RBX],RSI
+        POP     RAX             //+****
+        JMP     @@70
+@@60:   CMP     U64 CMemUnused.size[RSI],RAX
+        JB      I32 @@40
+        JNE     @@70
+
+@@65:   MOV     RDI,U64 CMemUnused.next[RSI]
+        MOV     U64 CMemUnused.next[RBX],RDI
+        JMP     MALLOC_ALMOST_DONE
+
+@@70:   SUB     U64 CMemUnused.size[RSI],RAX    //UPDATE FREE ENTRY
+        CMP     U64 CMemUnused.size[RSI],sizeof(CMemUnused)
+        JAE     @@75                    //take from top of block
+        ADD     U64 CMemUnused.size[RSI],RAX    //doesn't fit, undo
+        JMP     I32 @@40
+
+@@75:   ADD     RSI,U64 CMemUnused.size[RSI]
+
+MALLOC_ALMOST_DONE:
+//RSI=res-CMemUsed.size
+//RAX=size+CMemUsed.size
+//RDX=HeapCtrl
+        ADD     U64 CHeapCtrl.used_u8s[RDX],RAX
+
+#if _CFG_HEAP_DBG
+//QueIns
+        MOV     RDI,U64 CHeapCtrl.last_um[RDX]
+        MOV     U64 CMemUsed.next[RDI],RSI
+        MOV     U64 CHeapCtrl.last_um[RDX],RSI
+        MOV     U64 CMemUsed.last[RSI],RDI
+        LEA     RDI,U64 CHeapCtrl.next_um-CMemUsed.next[RDX]
+        MOV     U64 CMemUsed.next[RSI],RDI
+
+//Caller1/Caller2
+        PUSH    RDX
+        MOV     RDX,U64 [MEM_HEAP_LIMIT]
+        MOV     RDI,U64 SF_RIP[RBP]
+        CMP     RDI,RDX
+        JB      @@80
+        XOR     RDI,RDI
+        MOV     U64 CMemUsed.caller1[RSI],RDI
+        JMP     @@90
+@@80:   MOV     U64 CMemUsed.caller1[RSI],RDI
+        MOV     RDI,U64 SF_RBP[RBP]
+        CMP     RDI,RDX
+        JB      @@85
+        XOR     RDI,RDI
+        JMP     @@90
+@@85:   MOV     RDI,U64 SF_RIP[RDI]
+        CMP     RDI,RDX
+        JB      @@90
+        XOR     RDI,RDI
+@@90:   MOV     U64 CMemUsed.caller2[RSI],RDI
+        POP     RDX
+
+#endif
+        LOCK
+        BTR     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        POPFD
+
+        MOV     U64 CMemUsed.size[RSI],RAX
+        MOV     U64 CMemUsed.hc[RSI],RDX
+        LEA     RAX,U64 CMemUsed.start[RSI]
+
+        TEST    U8 [SYS_SEMAS+SEMA_HEAPLOG_ACTIVE*DFT_CACHE_LINE_WIDTH],1
+        JZ      @@105
+        PUSH    RAX
+        PUSH    RAX
+        MOV     RAX,U64 [SYS_EXTERN_TABLE]
+        MOV     RAX,U64 EXT_HEAPLOG_MALLOC*8[RAX]
+        TEST    RAX,RAX
+        JZ      @@95
+        CALL    RAX
+        JMP     @@100
+@@95:   ADD     RSP,8
+@@100:  POP     RAX
+
+@@105:  TEST    U8 [SYS_HEAP_INIT_FLAG],1
+        JZ      MALLOC_FINAL_EXIT
+
+        PUSH    RAX
+        MOV     RCX,U64 CMemUsed.size-CMemUsed.start[RAX]
+        SUB     RCX,CMemUsed.start
+        MOV     RDI,RAX
+        MOV     AL,U8 [SYS_HEAP_INIT_VAL]
+        REP_STOSB
+        POP     RAX
+
+MALLOC_FINAL_EXIT:
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+//************************************
+_FREE::
+//Be aware of heap_hash in MemPagTaskAlloc().
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+
+        TEST    U8 [SYS_SEMAS+SEMA_HEAPLOG_ACTIVE*DFT_CACHE_LINE_WIDTH],1
+        JZ      @@15
+        MOV     RBX,U64 SF_ARG1[RBP]
+        TEST    RBX,RBX
+        JZ      @@05
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+@@05:   PUSH    RBX
+        MOV     RAX,U64 [SYS_EXTERN_TABLE]
+        MOV     RAX,U64 EXT_HEAPLOG_FREE*8[RAX]
+        TEST    RAX,RAX
+        JZ      @@10
+        CALL    RAX
+        JMP     @@15
+@@10:   ADD     RSP,8
+
+@@15:   MOV     RSI,U64 SF_ARG1[RBP]
+        TEST    RSI,RSI
+
+#if _CFG_HEAP_DBG
+        JZ      I32 FREE_DONE
+#else
+        JZ      FREE_DONE
+#endif
+
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RSI]
+        TEST    RAX,RAX
+        JGE     @@20    //Aligned alloced chunks have neg size.
+                        //The neg size is offset to start of CMemUsed struct.
+        ADD     RSI,RAX
+
+@@20:   PUSHFD
+        SUB     RSI,CMemUsed.start
+        MOV     RDX,U64 CMemUsed.hc[RSI]
+        CMP     U32 CHeapCtrl.hc_signature[RDX],HEAP_CTRL_SIGNATURE_VAL
+        JE      @@25
+        ADD     RSI,CMemUsed.start
+        PUSH    RSI
+        CALL    &SysBadFree
+        JMP     I32 _SYS_HLT
+
+@@25:   MOV     RAX,U64 CMemUsed.size[RSI]
+        SUB     U64 CHeapCtrl.used_u8s[RDX],RAX
+        CLI
+@@30:   LOCK
+        BTS     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        PAUSE
+        JC      @@30
+#if _CFG_HEAP_DBG
+//QueRem
+        MOV     RDX,U64 CMemUsed.next[RSI]
+        MOV     RDI,U64 CMemUsed.last[RSI]
+        MOV     U64 CMemUsed.last[RDX],RDI
+        MOV     U64 CMemUsed.next[RDI],RDX
+
+//Caller1/Caller2
+        MOV     RDX,U64 [MEM_HEAP_LIMIT]
+        MOV     RDI,U64 SF_RIP[RBP]
+        CMP     RDI,RDX
+        JB      @@35
+        XOR     RDI,RDI
+        MOV     U64 CMemUnused.caller1[RSI],RDI
+        JMP     @@45
+@@35:   MOV     U64 CMemUnused.caller1[RSI],RDI
+        MOV     RDI,U64 SF_RBP[RBP]
+        CMP     RDI,RDX
+        JB      @@40
+        XOR     RDI,RDI
+        JMP     @@45
+@@40:   MOV     RDI,U64 SF_RIP[RDI]
+        CMP     RDI,RDX
+        JB      @@45
+        XOR     RDI,RDI
+@@45:   MOV     U64 CMemUnused.caller2[RSI],RDI
+
+        MOV     RDX,U64 CMemUsed.hc[RSI]
+#endif
+        CMP     RAX,MEM_HEAP_HASH_SIZE
+        JAE     @@50
+
+#assert CMemUnused.size==CMemUsed.size
+//      MOV     U64 CMemUnused.size[RSI],RAX
+
+        MOV     RBX,U64 CHeapCtrl.heap_hash[RAX+RDX]
+        MOV     U64 CMemUnused.next[RSI],RBX
+        MOV     U64 CHeapCtrl.heap_hash[RAX+RDX],RSI
+        JMP     @@55
+
+@@50:   SUB     RSI,sizeof(CMemBlk)
+        PUSH    RDX
+        PUSH    RDX
+        PUSH    RSI
+        CALL    &MemPagTaskFree
+        POP     RDX
+
+@@55:   LOCK
+        BTR     U32 CHeapCtrl.locked_flags[RDX],HClf_LOCKED
+        POPFD
+FREE_DONE:
+        POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    8
+//************************************
+_MSIZE::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG1[RBP]
+        XOR     RAX,RAX
+        TEST    RBX,RBX
+        JZ      @@10
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+@@05:   SUB     RAX,CMemUsed.start
+@@10:   POP     RBP
+        RET1    8
+//************************************
+_MSIZE2::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG1[RBP]
+        XOR     RAX,RAX
+        TEST    RBX,RBX
+        JZ      @@10
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+@@05:   MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+@@10:   POP     RBP
+        RET1    8
+//************************************
+_MHEAP_CTRL::
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RBX,U64 SF_ARG1[RBP]
+        XOR     RAX,RAX
+        TEST    RBX,RBX
+        JZ      @@10
+        MOV     RAX,U64 CMemUsed.size-CMemUsed.start[RBX]
+        TEST    RAX,RAX
+        JGE     @@05    //Aligned alloced chunks have neg size
+        ADD     RBX,RAX
+@@05:   MOV     RAX,U64 CMemUsed.hc-CMemUsed.start[RBX]
+@@10:   POP     RBP
+        RET1    8
+}
+
+_extern _FREE U0 Free(U8 *addr); //Free MAlloc()ed memory chunk.
+_extern _MSIZE I64 MSize(U8 *src); //Size of heap object.
+_extern _MSIZE2 I64 MSize2(U8 *src); //Internal size of heap object.
+_extern _MHEAP_CTRL CHeapCtrl *MHeapCtrl(U8 *src); //CHeapCtrl of object.
+_extern _MALLOC U8 *MAlloc(I64 size,CTask *mem_task=NULL); //Alloc memory chunk.
+//Accepts a CTask or CHeapCtrl. NULL allocs off current task's heap.
+
+U8 *AMAlloc(I64 size)
+{//Alloc memory in Adam's heap.
+  return MAlloc(size,adam_task);
+}
+
+U8 *CAlloc(I64 size,CTask *mem_task=NULL)
+{//Accepts a CTask or CHeapCtrl.  NULL allocs off current task's heap.
+  U8 *res=MAlloc(size,mem_task);
+  MemSet(res,0,size);
+  return res;
+}
+
+U8 *ACAlloc(I64 size)
+{//Alloc and set to zero memory in Adam's heap.
+  return CAlloc(size,adam_task);
+}
+
+U8 *MAllocIdent(U8 *src,CTask *mem_task=NULL)
+{//Accepts a CTask or CHeapCtrl.  NULL allocs off current task's heap.
+  U8 *res;
+  I64 size;
+  if (!src) return NULL;
+  size=MSize(src);
+  res=MAlloc(size,mem_task);
+  MemCpy(res,src,size);
+  return res;
+}
+
+U8 *AMAllocIdent(U8 *src)
+{//Alloc in Adam's heap, ident copy of heap node.
+  return MAllocIdent(src,adam_task);
+}
+
+U8 *MAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0)
+{//Only powers of two alignment. This is awful.
+  I64 mask=alignment-1;
+  U8 *ptr=MAlloc(size+mask+sizeof(I64)+misalignment,mem_task),
+        *res=(ptr+sizeof(I64)+mask)&~mask+misalignment;
+  res(I64 *)[-1]=ptr-res;
+#assert offset(CMemUsed.size)==offset(CMemUsed.start)-sizeof(I64)
+  return res;
+}
+
+U8 *CAllocAligned(I64 size,I64 alignment,
+        CTask *mem_task=NULL,I64 misalignment=0)
+{//Only powers of two alignment. This is awful.
+  I64 mask=alignment-1;
+  U8 *ptr=MAlloc(size+mask+sizeof(I64)+misalignment,mem_task),
+        *res=(ptr+sizeof(I64)+mask)&~mask+misalignment;
+  res(I64 *)[-1]=ptr-res;
+#assert offset(CMemUsed.size)==offset(CMemUsed.start)-sizeof(I64)
+  MemSet(res,0,size);
+  return res;
+}
+
+U8 *StrNew(U8 *buf,CTask *mem_task=NULL)
+{//Accepts a CTask or CHeapCtrl.  NULL allocs off current task's heap.
+  U8 *res;
+  I64 size;
+  if (buf) {
+    size=StrLen(buf)+1;
+    res=MAlloc(size,mem_task);
+    MemCpy(res,buf,size);
+  } else {
+    res=MAlloc(1,mem_task);
+    *res=0;
+  }
+  return res;
+}
+
+U8 *AStrNew(U8 *buf)
+{//Alloc copy of string in Adam's heap.
+  return StrNew(buf,adam_task);
+}
+
+ diff --git a/public/Wb/Kernel/Mem/MakeMem.HC.HTML b/public/Wb/Kernel/Mem/MakeMem.HC.HTML new file mode 100755 index 0000000..8bfc4d5 --- /dev/null +++ b/public/Wb/Kernel/Mem/MakeMem.HC.HTML @@ -0,0 +1,39 @@ + + + + + + + + + + + +
+#exe {Cd(__DIR__);};
+#include "PageTables"
+#include "MemPag"
+#include "BlkPool"
+#include "MAllocFree"
+#include "HeapCtrl"
+#include "MemPhysical"
+#exe {Cd("..");};
+
+ diff --git a/public/Wb/Kernel/Mem/MemPag.HC.HTML b/public/Wb/Kernel/Mem/MemPag.HC.HTML new file mode 100755 index 0000000..55ae581 --- /dev/null +++ b/public/Wb/Kernel/Mem/MemPag.HC.HTML @@ -0,0 +1,198 @@ + + + + + + + + + + + +
+U0 SysBadFree(I64 *ptr)
+{
+  Panic("Bad Free:",ptr);
+}
+
+U0 SysBadMAlloc(I64 *ptr)
+{
+  Panic("Bad MAlloc:",ptr);
+}
+
+U8 *MemPagAlloc(I64 pags,CBlkPool *bp=NULL)
+{/*Alloc pags from BlkPool. Don't link to task.
+(Linking to a task means they will be freed when the task dies.)
+It might give you more than you asked for.
+
+Return: NULL if out of memory.
+*/
+  CMemBlk *res=NULL,*m;
+  I64 i;
+  if (!bp) bp=sys_code_bp;
+  PUSHFD
+  CLI
+  while (LBts(&bp->locked_flags,BPlf_LOCKED))
+    PAUSE
+  if (pags<MEM_FREE_PAG_HASH_SIZE) {
+    if (res=bp->free_pag_hash[pags]) {
+      bp->free_pag_hash[pags]=res->next;
+      goto at_done;
+    }
+    i=Bsr(MEM_FREE_PAG_HASH_SIZE)+1;
+  } else {
+//We'll now round-up to a power of two.
+    //There is some overhead on allocations and
+    //we wouldn't want to round to the next
+    //power of two if a power of two was requested.
+    //So we use a little more than a power of two.
+    pags-=MEM_EXTRA_HASH2_PAGS;
+    i=Bsr(pags)+1;
+    pags=1<<i+MEM_EXTRA_HASH2_PAGS;
+    if (res=bp->free_pag_hash2[i]) {
+      bp->free_pag_hash2[i]=res->next;
+      goto at_done;
+    }
+  }
+  m=&bp->mem_free_lst;
+  while (TRUE) {
+    if (!(res=m->next)) {
+//We're probably out of luck, but lets search for a
+      //freed larger size block... and, screw-it, return the whole thing.
+      do {
+        if (res=bp->free_pag_hash2[++i]) {
+          pags=1<<i+MEM_EXTRA_HASH2_PAGS;
+          bp->free_pag_hash2[i]=res->next;
+          goto at_done;
+        }
+      } while (i<64-MEM_PAG_BITS-1);
+      pags=0;
+      res=NULL; //Out of memory
+      goto at_done2;
+    }
+    if (res->pags<pags)
+      m=res;
+    else {
+      if (res->pags==pags) {
+        m->next=res->next;
+        goto at_done;
+      } else {
+        res->pags-=pags;
+        res(U8 *)+=res->pags<<MEM_PAG_BITS;
+        res->pags=pags;
+        goto at_done;
+      }
+    }
+  }
+at_done:
+  bp->used_u8s+=res->pags<<MEM_PAG_BITS;
+at_done2:
+  LBtr(&bp->locked_flags,BPlf_LOCKED);
+  POPFD
+  return res;
+}
+
+U0 MemPagFree(CMemBlk *m,CBlkPool *bp=NULL)
+{//Return non-task pags to BlkPool.
+  I64 i,pags;
+  if (m) {
+    if (!bp) bp=sys_code_bp;
+    PUSHFD
+    CLI
+    while (LBts(&bp->locked_flags,BPlf_LOCKED))
+      PAUSE
+    pags=m->pags;
+    m->mb_signature=MBS_UNUSED_SIGNATURE_VAL;
+    bp->used_u8s-=pags<<MEM_PAG_BITS;
+    if (pags<MEM_FREE_PAG_HASH_SIZE) {
+      m->next=bp->free_pag_hash[pags];
+      bp->free_pag_hash[pags]=m;
+    } else {
+//We'll now round-up to a power of two.
+      //There is some overhead on allocations and
+      //we wouldn't want to round to the next
+      //power of two if a power of two was requested.
+      //So we use a little more than a power of two.
+      pags-=MEM_EXTRA_HASH2_PAGS;
+      i=Bsr(pags);
+      m->next=bp->free_pag_hash2[i];
+      bp->free_pag_hash2[i]=m;
+    }
+    LBtr(&bp->locked_flags,BPlf_LOCKED);
+    POPFD
+  }
+}
+
+CMemBlk *MemPagTaskAlloc(I64 pags,CHeapCtrl *hc)
+{/*hc must be locked.  Don't preempt this routine.
+Currently, this is only called from MAlloc().
+Return: NULL if out of memory.
+*/
+  CMemBlk *res;
+  I64 threshold,cnt,size;
+  CMemUnused *uum,**_uum,**_ptr;
+  if (res=MemPagAlloc(pags,hc->bp)) {
+    QueIns(res,hc->last_mem_blk);
+    res->mb_signature=MBS_USED_SIGNATURE_VAL;
+    hc->alloced_u8s+=res->pags<<MEM_PAG_BITS;
+
+    //Tidy-up free lst (Move into heap hash)
+    //because if free lst gets long, delay causes crash.
+    threshold=MEM_HEAP_HASH_SIZE>>4;
+#assert MEM_HEAP_HASH_SIZE>>4>=sizeof(U8 *)
+    do {
+      cnt=0;
+      _uum=&hc->malloc_free_lst;
+      while (uum=*_uum) {
+#assert !offset(CMemUnused.next)
+        size=uum->size;
+        if (size<threshold) {
+          *_uum=uum->next;
+          _ptr=(&hc->heap_hash)(U8 *)+size;
+          uum->next=*_ptr;
+          *_ptr=uum;
+        } else {
+          cnt++;
+          _uum=uum;
+        }
+      }
+      threshold<<=1;
+    } while (cnt>8 && threshold<=MEM_HEAP_HASH_SIZE);
+  }
+  return res;
+}
+
+U0 MemPagTaskFree(CMemBlk *m,CHeapCtrl *hc)
+{//hc must be locked
+  if (m) {
+    PUSHFD
+    CLI
+    if (m->mb_signature!=MBS_USED_SIGNATURE_VAL)
+      SysBadFree(m);
+    else {
+      QueRem(m);
+      hc->alloced_u8s-=m->pags<<MEM_PAG_BITS;
+      MemPagFree(m,hc->bp);
+    }
+    POPFD
+  }
+}
+
+ diff --git a/public/Wb/Kernel/Mem/MemPhysical.HC.HTML b/public/Wb/Kernel/Mem/MemPhysical.HC.HTML new file mode 100755 index 0000000..4e69504 --- /dev/null +++ b/public/Wb/Kernel/Mem/MemPhysical.HC.HTML @@ -0,0 +1,212 @@ + + + + + + + + + + + +
+Bool Mem32DevIns(CMemRange *tmpmr)
+{
+  CMemRange *tmpmr1=dev.mem32_head.next,*tmpmr2;
+  while (tmpmr1!=&dev.mem32_head) {
+    if (!tmpmr1->type && tmpmr->base>=tmpmr1->base &&
+          tmpmr->base+tmpmr->size<=tmpmr1->base+tmpmr1->size) {
+      if (tmpmr->base>tmpmr1->base) {
+        tmpmr2=AMAlloc(sizeof(CMemRange));
+        tmpmr2->type=MRT_UNUSED;
+        tmpmr2->flags=0;
+        tmpmr2->base=tmpmr1->base;
+        tmpmr2->size=tmpmr->base-tmpmr1->base;
+        QueInsRev(tmpmr2,tmpmr1);
+      }
+      QueInsRev(tmpmr,tmpmr1);
+      tmpmr1->size=tmpmr1->base+tmpmr1->size-
+            (tmpmr->base+tmpmr->size);
+      tmpmr1->base=tmpmr->base+tmpmr->size;
+      if (!tmpmr1->size) {
+        QueRem(tmpmr1);
+        Free(tmpmr1);
+      }
+      return TRUE;
+    }
+    tmpmr1=tmpmr1->next;
+  }
+  return FALSE;
+}
+
+U0 Mem32DevInit()
+{
+  CMemRange *tmpmr;
+  CMemE820 *m20=MEM_E820;
+
+  QueInit(&dev.mem32_head);
+  tmpmr=AMAlloc(sizeof(CMemRange));
+  tmpmr->type=MRT_UNUSED;
+  tmpmr->flags=0;
+//Maybe !!! Change this to 0xF0000000 !!!
+  tmpmr->base=0xE0000000;
+  tmpmr->size=0x10000000;
+  QueIns(tmpmr,dev.mem32_head.last);
+
+  if (m20->type) {
+    while (m20->type) {
+      tmpmr=AMAlloc(sizeof(CMemRange));
+      tmpmr->type=m20->type;
+      tmpmr->flags=0;
+      tmpmr->base=m20->base;
+      tmpmr->size=m20->len;
+      if (!Mem32DevIns(tmpmr))
+        Free(tmpmr);
+      m20++;
+    }
+  }
+}
+
+U8 *Mem32DevAlloc(I64 size,I64 alignment)
+{//Alloc 32-bit addr space for device. (Doesn't work.) Not used.
+//For this to work the BIOS E820 map must be searched for gaps in
+  //the 32-bit range and the pool initialized to the gaps.
+  U8 *base,*limit;
+  CMemRange *tmpmr,*tmpmr1;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  tmpmr1=dev.mem32_head.next;
+  while (tmpmr1!=&dev.mem32_head) {
+    base=(tmpmr1->base+alignment-1)&~(alignment-1);
+    limit=base+size-1;
+    if (!tmpmr1->type &&
+          limit<tmpmr1->base+tmpmr1->size) {
+      tmpmr=AMAlloc(sizeof(CMemRange));
+      tmpmr->type=MRT_DEV;
+      tmpmr->flags=0;
+      tmpmr->base=base;
+      tmpmr->size=size;
+      if (!Mem32DevIns(tmpmr)) {
+        Free(tmpmr);
+        LBtr(&sys_semas[SEMA_DEV_MEM],0);
+        return NULL;
+      }
+      LBtr(&sys_semas[SEMA_DEV_MEM],0);
+      return tmpmr->base;
+    }
+    tmpmr1=tmpmr1->next;
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+  return NULL;
+}
+
+U0 Mem32DevFree(U8 *base)
+{//Free 32-bit device address space.
+  CMemRange *tmpmr;
+  if (!base) return;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  tmpmr=dev.mem32_head.next;
+  while (tmpmr!=&dev.mem32_head) {
+    if (tmpmr->base==base) {
+      tmpmr->type=MRT_UNUSED;
+      break;
+    }
+    tmpmr=tmpmr->next;
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+}
+
+U8 *Mem64DevAlloc(I64 *_pages1Gig)
+{//Alloc 64-bit addr space for device.
+  U8 *a;
+  I64 i=*_pages1Gig,*pte;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  while (i--) {
+    a=dev.mem64_ptr-=1<<30;
+    do {
+      pte=MemPageTable(a);
+      *pte=*pte&~0x18 |0x11; //Uncached and present
+      InvlPg(dev.mem64_ptr);
+      a+=mem_page_size;
+    } while (a-dev.mem64_ptr<1<<30);
+  }
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+  return dev.mem64_ptr;
+}
+
+U0 Mem64DevFree(U8 *base,I64 pages1Gig)
+{//Free 64-bit device address space.
+  if (!base) return;
+  while (LBts(&sys_semas[SEMA_DEV_MEM],0))
+    Yield;
+  if (base==dev.mem64_ptr)
+    dev.mem64_ptr+=pages1Gig*1<<30;
+//else not freed
+  LBtr(&sys_semas[SEMA_DEV_MEM],0);
+}
+
+U0 UncachedAliasAlloc() //Make uncached alias for 4 lowest Gig.
+{
+  I64 i=4,*pte;
+  U8 *a;
+  a=dev.uncached_alias=Mem64DevAlloc(&i);
+  do {
+    pte=MemPageTable(a);
+    *pte=0x197+a-dev.uncached_alias;
+    InvlPg(a);
+    a+=mem_page_size;
+  } while (a-dev.uncached_alias<1<<32);
+}
+
+I64 BIOSTotalMem()
+{
+  I64 r01,r20;
+  U16           *m01=MEM_E801;
+  CMemE820      *m20=MEM_E820;
+
+  r01=0x100000+m01[0]<<10+m01[1]<<16;
+  r20=0;
+  if (m20->type) {
+    while (m20->type) {
+      if (m20->type==1)
+        r20+=m20->len;
+      m20++;
+    }
+  }
+  return MaxI64(r01,r20);
+}
+
+I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024)
+{//Helps pick DiskCache and RAMDisk sizes.
+//Can be used in BootHDIns() config scripts.
+  I64 i;
+  if (sys_data_bp)
+    i=sys_data_bp->alloced_u8s;
+  else
+    i=sys_code_bp->alloced_u8s;
+  if (i>=limit)
+    return max;
+  else
+    return min+(max-min)*i/limit;
+}
+
+ diff --git a/public/Wb/Kernel/Mem/PageTables.HC.HTML b/public/Wb/Kernel/Mem/PageTables.HC.HTML new file mode 100755 index 0000000..b79bc3a --- /dev/null +++ b/public/Wb/Kernel/Mem/PageTables.HC.HTML @@ -0,0 +1,236 @@ + + + + + + + + + + + +
+asm {
+// ::/Doc/MemOverview.DD
+
+USE32
+SYS_INIT_PAGE_TABLES::
+//Check 1Gig page capability and set page size.
+        MOV     EAX,0x80000001
+        CPUID
+        MOV     EAX,1<<21
+//      BT      EDX,26
+//      JNC     @@05
+//      MOV     EAX,1<<30
+@@05:   MOV     U32 [MEM_PAGE_SIZE],EAX
+
+//Set mapped space limit
+        MOV     EAX,[MEM_PHYSICAL_SPACE]
+        MOV     EDX,[MEM_PHYSICAL_SPACE+4]
+        BT      U32 [MEM_PAGE_SIZE],30 //Round-up to 1Gig boundary?
+        JNC     @@10
+        ADD     EAX,0x3FFFFFFF
+        ADC     EDX,0
+        AND     EAX,~0x3FFFFFFF
+@@10:   INC     EDX     //Need 4Gig extra for uncached alias up at top of space.
+        MOV     [MEM_MAPPED_SPACE],EAX
+        MOV     [MEM_MAPPED_SPACE+4],EDX
+
+//How many 2Meg pages?
+        MOV     CL,21
+        ADD     EAX,0x1FFFFF
+        ADC     EDX,0
+        SHRD    EAX,EDX
+        SHR     EDX,CL
+        MOV     [MEM_2MEG_NUM],EAX
+        MOV     [MEM_2MEG_NUM+4],EDX
+
+//How many 1Gig pages?
+        MOV     CL,9
+        ADD     EAX,0x1FF
+        ADC     EDX,0
+        SHRD    EAX,EDX
+        SHR     EDX,CL
+        MOV     [MEM_1GIG_NUM],EAX
+        MOV     [MEM_1GIG_NUM+4],EDX
+
+//How many 512Gig pages?
+        MOV     CL,9
+        ADD     EAX,0x1FF
+        ADC     EDX,0
+        SHRD    EAX,EDX
+        SHR     EDX,CL
+        MOV     [MEM_512GIG_NUM],EAX
+        MOV     [MEM_512GIG_NUM+4],EDX
+
+//Set CSysFixedArea to zero
+        MOV     EDI,SYS_FIXED_AREA
+        XOR     EAX,EAX
+        MOV     ECX,sizeof(CSysFixedArea)/4
+        REP_STOSD
+
+        MOV     U32 [MEM_PML2],EDI
+//Check for 1Gig page capability.
+        BT      U32 [MEM_PAGE_SIZE],30
+        JC      @@15
+//Find PML2 Size
+        MOV     EAX,U32 [MEM_2MEG_NUM]
+        ADD     EAX,0x1FF
+        AND     EAX,~0x1FF
+        SHL     EAX,3
+        ADD     EDI,EAX
+
+//Find PML3 Size
+@@15:   MOV     U32 [MEM_PML3],EDI
+        MOV     EAX,U32 [MEM_1GIG_NUM]
+        ADD     EAX,0x1FF
+        AND     EAX,~0x1FF
+        SHL     EAX,3
+        ADD     EDI,EAX
+
+//Find PML4 Size
+        MOV     U32 [MEM_PML4],EDI
+        MOV     EAX,U32 [MEM_512GIG_NUM]
+        ADD     EAX,0x1FF
+        AND     EAX,~0x1FF
+        SHL     EAX,3
+        ADD     EAX,EDI
+
+        MOV     U32 [MEM_HEAP_BASE],EAX
+
+//Set page tables to zero
+        MOV     EDI,U32 [MEM_PML2]
+        SUB     EAX,EDI
+        MOV     ECX,EAX
+        SHR     ECX,2
+        XOR     EAX,EAX
+        REP_STOSD
+
+//Check for 1Gig page capability.
+        BT      U32 [MEM_PAGE_SIZE],30
+        JC      @@30
+
+//PML2: Use 2Meg Pages
+        MOV     EAX,0x87 //bit 7 is page size (2Meg)
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML2]
+        MOV     ECX,[MEM_2MEG_NUM]
+@@20:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x200000
+        ADC     EDX,0
+        LOOP    @@20
+//PML3: Use 2Meg Pages
+        MOV     EAX,[MEM_PML2]
+        OR      EAX,7
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML3]
+        MOV     ECX,[MEM_1GIG_NUM]
+@@25:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x1000
+        ADC     EDX,0
+        LOOP    @@25
+        JMP     @@40
+
+//PML3: Use 1Gig Pages
+@@30:   MOV     EAX,0x87 //bit 7 is page size (1Gig)
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML3]
+        MOV     ECX,[MEM_1GIG_NUM]
+@@35:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x40000000
+        ADC     EDX,0
+        LOOP    @@35
+
+//PML4
+@@40:   MOV     EAX,[MEM_PML3]
+        OR      EAX,7
+        XOR     EDX,EDX
+        MOV     EDI,[MEM_PML4]
+        MOV     ECX,[MEM_512GIG_NUM]
+@@45:   MOV     U32 [EDI],EAX
+        ADD     EDI,4
+        MOV     U32 [EDI],EDX
+        ADD     EDI,4
+        ADD     EAX,0x1000
+        ADC     EDX,0
+        LOOP    @@45
+        RET
+
+SYS_INIT_16MEG_SYS_CODE_BP::
+// Init sys_code_bp to BIOS E801 lowest 16Meg val.
+// BlkPoolsInit() adds the rest.
+        MOV     U32 [SYS_CODE_BP],SYS_FIXED_AREA+CSysFixedArea.sys_code_bp
+        MOV     U32 [SYS_CODE_BP+4],0
+
+        MOV     U32 [SYS_DATA_BP],0
+        MOV     U32 [SYS_DATA_BP+4],0
+
+        XOR     EAX,EAX
+        MOV     AX,U16 [MEM_E801] //1 Kb blks between 1M and 16M
+        SHL     EAX,10
+        ADD     EAX,0x100000
+        MOV     EDI,U32 [MEM_HEAP_BASE]
+        SUB     EAX,EDI
+
+//EDI=BASE EAX=SIZE
+        TEST    U8 [SYS_MEM_INIT_FLAG],1
+        JZ      @@05
+        PUSH    EAX
+        PUSH    EDI
+        MOV     ECX,EAX
+        MOV     AL,U8 [SYS_MEM_INIT_VAL]
+        REP_STOSB
+        POP     EDI
+        POP     EAX
+
+@@05:   SHR     EAX,MEM_PAG_BITS
+        MOV     ESI,SYS_FIXED_AREA+CSysFixedArea.sys_code_bp
+        MOV     EBX,U32 CBlkPool.mem_free_lst[ESI]
+        MOV     U32 CMemBlk.next[EDI],EBX
+        MOV     U32 CMemBlk.next+4[EDI],0
+        MOV     U32 CBlkPool.mem_free_lst[ESI],EDI
+        MOV     U32 CBlkPool.mem_free_lst+4[ESI],0
+        MOV     U32 CMemBlk.mb_signature[EDI],MBS_UNUSED_SIGNATURE_VAL
+        MOV     U32 CMemBlk.pags[EDI],EAX
+        SHL     EAX,MEM_PAG_BITS
+        ADD     U32 CBlkPool.alloced_u8s[ESI],EAX
+
+        BTS     U32 [SYS_RUN_LEVEL],RLf_16MEG_SYS_CODE_BP
+        RET
+}
+
+I64 *MemPageTable(U8 *a)
+{//Point to page table entry for addr.
+  if (Bt(&mem_page_size,30))
+    return *MEM_PML3(U64 *)+a>>30*8;
+  else
+    return *MEM_PML2(U64 *)+a>>21*8;
+}
+
+ diff --git a/public/Wb/Kernel/MultiProc.HC.HTML b/public/Wb/Kernel/MultiProc.HC.HTML new file mode 100755 index 0000000..476e390 --- /dev/null +++ b/public/Wb/Kernel/MultiProc.HC.HTML @@ -0,0 +1,420 @@ + + + + + + + + + + + +
+asm {
+        ALIGN   16,OC_NOP
+USE16
+//See TempleOS MultiCore.
+
+//This code gets copied to MP_VECT_ADDR.
+//See MemCpy(MP_VECT_ADDR.
+COREAP_16BIT_INIT::
+        JMP     @@05
+
+        ALIGN   4,OC_NOP
+AP_GDT_PTR:     DU16    sizeof(CGDT)-1;
+                DU64    0;
+
+@@05:   CLI
+        WBINVD
+        MOV     AX,MP_VECT_ADDR/16
+        MOV     DS,AX
+        LGDT    U32 [CAP16BitInit.ap_gdt_ptr]  //See mp->ap_gdt_ptr
+
+        MOV     EAX,SYS_START_CR0
+        MOV_CR0_EAX
+        DU8     0x66,0xEA;               //JMP CGDT.cs32:AP_32BIT_INIT
+        DU32    AP_32BIT_INIT;
+        DU16    CGDT.cs32;
+COREAP_16BIT_INIT_END::
+
+USE32
+AP_32BIT_INIT:
+        MOV     AX,CGDT.ds
+        MOV     DS,AX
+        MOV     ES,AX
+        MOV     FS,AX
+        MOV     GS,AX
+        MOV     SS,AX
+
+@@05:   LOCK
+        BTS     U32 [SYS_MP_CNT_LOCK],0
+        JC      @@05
+
+        MOV     ESI,U32 [SYS_MP_CNT_INITIAL]
+        LOCK
+        INC     U32 [SYS_MP_CNT_INITIAL]
+        LOCK
+        BTR     U32 [SYS_MP_CNT_LOCK],0
+
+        CMP     ESI,MP_PROCESSORS_NUM
+        JAE     I32 _SYS_HLT
+
+        IMUL2   ESI,sizeof(CCPU)
+        ADD     ESI,U32 [SYS_CPU_STRUCTS]
+
+        LEA     ESP,U32 CCPU.start_stk+sizeof(CCPU.start_stk)[ESI]
+        PUSH    U32 RFLAGG_START
+        POPFD
+        PUSH    U32 0   //Return from next call will be 64-bit
+        CALL    SYS_ENTER_LONG_MODE
+USE64
+        FNINIT
+        MOV     RAX,RSI
+        CALL    SET_GS_BASE
+@@10:   MOV     RAX,U64 CCPU.seth_task[RSI]
+        TEST    RAX,RAX
+        JZ      @@10
+        MOV     U64 CTask.gs[RAX],RSI
+        CALL    SET_FS_BASE
+
+        JMP     I32 _TASK_CONTEXT_RESTORE
+}
+
+U0 TSSBusy(I64 tr,Bool val=OFF)
+{//See ::/Demo/Lectures/Ring3.HC.
+  LBEqu((&sys_gdt)(U8 *)+tr+4,9,val);
+}
+
+CTSS *TSSNew(I64 cpu_num)
+{
+  U32 *d,*d1;
+  CTSS *tss=CAlloc(sizeof(CTSS));
+  tss->io_map_offset=offset(CTSS.io_map);
+  MemSet(tss->io_map,0xFF,0x10000/8);
+
+  tss->st0=MAlloc(MEM_INTERRUPT_STK);
+  tss->rsp0=tss->st0(U8 *)+MSize(tss->st0);
+  tss->st1=MAlloc(MEM_INTERRUPT_STK);
+  tss->rsp1=tss->st1(U8 *)+MSize(tss->st1);
+  tss->st2=MAlloc(MEM_INTERRUPT_STK);
+  tss->rsp2=tss->st2(U8 *)+MSize(tss->st2);
+
+  tss->tr      =offset(CGDT.tr)+cpu_num*16;
+  tss->tr_ring3=offset(CGDT.tr_ring3)+cpu_num*16;
+
+  d=(&sys_gdt)(U8 *)+tss->tr;
+  d1=d(U8 *)+4;
+  *d =0x0000FFFF;
+  *d1=0x008F8900;
+  d(U8 *)+=2;
+  *d|=tss & 0x00FFFFFF;
+  *d1++|=tss & 0xFF000000;
+  *d1++=tss>>32;
+  *d1=0;
+
+  d=(&sys_gdt)(U8 *)+tss->tr_ring3;
+  d1=d(U8 *)+4;
+  *d =0x0000FFFF;
+  *d1=0x008FE900;
+  d(U8 *)+=2;
+  *d|=tss & 0x00FFFFFF;
+  *d1++|=tss & 0xFF000000;
+  *d1++=tss>>32;
+  *d1=0;
+
+  return tss;
+}
+
+CCPU *CPUStructInit(I64 num,CCPU *c,CTask *seth_task)
+{//Seth is null when called by adam on CSysFixedArea.boot_cpu0
+  MemSet(c,0,sizeof(CCPU));
+  c->addr=c;
+  c->num=num;
+  c->idle_factor=0.01;
+  QueInit(&c->next_dying);
+  if (Bt(&sys_run_level,RLf_16MEG_ADAM_HEAP_CTRL)) {
+    c->idle_task=Spawn(0,NULL,"Idle Task",,Fs,,0);
+    LBts(&c->idle_task->task_flags,TASKf_IDLE);
+    c->tss=TSSNew(num);
+  }
+  c->seth_task=seth_task;// It waits for this to be filled-in: seth_task
+  return c;
+}
+
+U0 MPInt(U8 num,I64 cpu_num=1)
+{//Generate interrupt for specified core.
+  if (cpu_num>=mp_cnt) {
+    if (!Bt(&sys_run_level,RLf_MP))
+      return;
+    else
+      throw('MultCore');
+  }
+  PUSHFD
+  CLI //Multitasking safe because each core has a local apic and IRQ's are off
+  while (*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)&0x1000)
+    PAUSE
+  *(dev.uncached_alias+LAPIC_ICR_HIGH)(U32 *)=dev.mp_apic_ids[cpu_num]<<24;
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0x4000+num;
+  POPFD
+}
+
+U0 MPIntAll(U8 num)
+{//Generate interrupt for all but own core.
+  PUSHFD
+  CLI //Multitasking safe because each core has a local apic and IRQ's are off
+  while (*(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)&0x1000)
+    PAUSE
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4800+num;
+  POPFD
+}
+
+U0 MPNMInt()
+{//Generate nonmaskable interrupt.
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4400;
+}
+
+U0 MPHalt()
+{//Halt all other cores.
+  mp_cnt=1;
+  MPNMInt;
+  Busy(10000);
+}
+
+U0 MPAPICInit()
+{//Called by adam during start-up
+//and other cores during initialization
+  //after Core0StartMP().
+  *(dev.uncached_alias+LAPIC_SVR)(U32 *)|=LAPICF_APIC_ENABLED;
+  dev.mp_apic_ids[Gs->num]=*(dev.uncached_alias+LAPIC_APIC_ID)(U32 *)>>24;
+  *(dev.uncached_alias+LAPIC_LDR)(U32 *)=dev.mp_apic_ids[Gs->num]<<24;
+  *(dev.uncached_alias+LAPIC_DFR)(U32 *)=0xF0000000;
+
+  //  MemSet(dev.uncached_alias+LAPIC_IRR,0,0x20);
+  //  MemSet(dev.uncached_alias+LAPIC_ISR,0,0x20);
+  //  MemSet(dev.uncached_alias+LAPIC_TMR,0,0x20);
+
+  SetRAX(Gs->tss->tr);
+  LTR   AX
+  if (Gs->num) {
+    IntInit1;
+    SetRFlags(RFLAGG_NORMAL);
+  }
+}
+
+#assert !offset(CJobCtrl.next_waiting)
+
+U0 CoreAPSethTask()
+{
+  CJobCtrl *ctrl=&Fs->srv_ctrl;
+  while (TRUE) {
+    STI
+    do {
+      TaskKillDying;
+      do PAUSE
+      while (LBts(&ctrl->flags,JOBCf_LOCKED));
+    } while (ctrl->next_waiting!=ctrl && JobRunOne(GetRFlags,ctrl));
+    CLI
+    LBts(&Fs->task_flags,TASKf_AWAITING_MSG);
+    LBtr(&ctrl->flags,JOBCf_LOCKED);
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    Yield;
+    LBtr(&Fs->task_flags,TASKf_IDLE);
+  }
+}
+
+CJob *JobQue(I64 (*fp_addr)(U8 *data),U8 *data=NULL,
+       I64 target_cpu=1,I64 flags=1<<JOBf_FREE_ON_COMPLETE,
+       I64 job_code=JOBT_CALL,U8 *aux_str=NULL,I64 aux1=0,I64 aux2=0)
+{//Queue multicore jobs, handled by Seth tasks.
+//Set flags to zero if you wish to get the res.
+  //See ::/Demo/MultiCore/Lock.HC
+  CJobCtrl *ctrl;
+  CJob *tmpc;
+  CTask *seth;
+  if (!(0<=target_cpu<mp_cnt))
+    throw('MultCore');
+  tmpc=ACAlloc(sizeof(CJob));
+  if (aux_str)
+    tmpc->aux_str=AStrNew(aux_str);
+  tmpc->job_code=job_code;
+  tmpc->addr=fp_addr;
+  tmpc->fun_arg=data;
+  tmpc->flags=flags;
+  tmpc->aux1=aux1;
+  tmpc->aux2=aux2;
+  seth=cpu_structs[target_cpu].seth_task;
+  tmpc->ctrl=ctrl=&seth->srv_ctrl;
+  PUSHFD
+  CLI
+  while (LBts(&ctrl->flags,JOBCf_LOCKED))
+    Yield;
+  if (ctrl->next_waiting==ctrl && LBtr(&seth->task_flags,TASKf_AWAITING_MSG))
+    MPInt(I_WAKE,target_cpu);
+  QueIns(tmpc,ctrl->last_waiting);
+  LBtr(&ctrl->flags,JOBCf_LOCKED);
+  POPFD
+  return tmpc;
+}
+
+CTask *SpawnQue(U0 (*fp_addr)(U8 *data),U8 *data=NULL,U8 *task_name=NULL,
+        I64 target_cpu, CTask *parent=NULL, //NULL means adam
+        I64 stk_size=0,I64 flags=1<<JOBf_ADD_TO_QUE)
+{
+  CTask *res;
+  CJob *tmpc=JobQue(fp_addr,data,target_cpu,
+        flags,JOBT_SPAWN_TASK,task_name,parent,stk_size);
+  CJobCtrl *ctrl;
+
+  while (!Bt(&tmpc->flags,JOBf_DONE)) {
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    Yield;
+  }
+  LBtr(&Fs->task_flags,TASKf_IDLE);
+
+  res=tmpc->spawned_task;
+  ctrl=tmpc->ctrl;
+  PUSHFD
+  CLI
+  while (LBts(&ctrl->flags,JOBCf_LOCKED))
+    Yield;
+  QueRem(tmpc);
+  LBtr(&ctrl->flags,JOBCf_LOCKED);
+  POPFD
+  JobDel(tmpc);
+  return res;
+}
+
+U0 CoreAPSethInit()
+{//Called by multicore's seth task after Core0StartMP()
+//as the first thing a CPU does before waiting for jobs.
+  MPAPICInit;
+  Fs->rip=&CoreAPSethTask;
+  TaskContextRestore;
+}
+
+U0 Core0StartMP()
+{//Called by adam during start-up.
+  CTask *task;
+  U8 buf[STR_LEN];
+  CAP16BitInit *mp=MP_VECT_ADDR;
+  CCPU *c;
+  I64 i,my_mp_cnt;
+  CRAXRBCRCXRDX ee;
+
+  CPUId(0x1,&ee);
+  if (!Bt(&ee.rdx,9))
+    return;
+
+  PUSHFD
+  CLI
+  if (mp_cnt>1) {
+    my_mp_cnt=mp_cnt;
+    MPHalt; //sets mp_cnt to 1
+    for (i=1;i<my_mp_cnt;i++) {
+      c=&cpu_structs[i];
+      JobQueDel(&c->seth_task->srv_ctrl.next_waiting);
+      JobQueDel(&c->seth_task->srv_ctrl.next_done);
+    }
+  }
+  MemSet(&cpu_structs[1],0,sizeof(CCPU)*(MP_PROCESSORS_NUM-1));
+
+  //When you start-up other cores, they jump to an addr
+  //specified by a byte vect number, MPN_VECT which corresponds
+  //to a location 4096*vect number, MP_VECT_ADDR.
+  MemCpy(mp,COREAP_16BIT_INIT,COREAP_16BIT_INIT_END-COREAP_16BIT_INIT);
+  MemCpy(&mp->ap_gdt_ptr,SYS_GDT_PTR,sizeof(CSysLimitBase));
+  mp_cnt_initial=mp_cnt=1;
+  mp_cnt_lock=0;
+
+  *(dev.uncached_alias+LAPIC_LVT_ERR)(U32 *)=
+        *(dev.uncached_alias+LAPIC_LVT_ERR)(U32 *)&0xFFFFFF00+MPN_VECT;
+  WBINVD //Not sure why this is needed. Might just need delay. MemCpy above?
+
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4500; //assert init IPI
+  Busy(10000);
+
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4600+MPN_VECT; //start-up
+  Busy(200);
+  *(dev.uncached_alias+LAPIC_ICR_LOW)(U32 *)=0xC4600+MPN_VECT;
+
+  Busy(100000);
+  for (i=0;i<10000;i++)
+    LBts(&mp_cnt_lock,0); //Don't let more through
+  my_mp_cnt=mp_cnt_initial;
+
+  if (my_mp_cnt>MP_PROCESSORS_NUM)
+    my_mp_cnt=MP_PROCESSORS_NUM;
+
+  for (i=1;i<my_mp_cnt;i++) {
+    StrPrint(buf,"Seth Task CPU%02X",i);
+    task=Spawn(&CoreAPSethInit,NULL,buf,,,MEM_SETH_STK,0);
+    task->rflags=RFLAGG_START;
+//CTask alloced off this core's seth_task's heap (Which is Adam)
+    CPUStructInit(i,&cpu_structs[i],task);
+    WBINVD //Not sure why this is needed.  Might just need delay.
+  }
+
+  //Make sure they're all up-and-running
+  for (i=1;i<my_mp_cnt;i++)
+    while (!Bt(&cpu_structs[i].seth_task->task_flags,TASKf_AWAITING_MSG))
+      PAUSE;
+
+  POPFD
+  mp_cnt=my_mp_cnt; //Finalize cnt
+}
+
+U0 Core0Init()
+{//Called by adam during start-up
+  CRAXRBCRCXRDX ee;
+  CPUId(0x1,&ee);
+
+  mp_cnt_initial=mp_cnt=1;
+  mp_cnt_lock=0;
+
+  dbg.mp_crash=ACAlloc(sizeof(CMPCrash));
+
+  //Must be in code heap because init code uses 32 bit addr of cpu_struct
+  adam_task->gs=cpu_structs=
+        CAlloc(sizeof(CCPU)*MP_PROCESSORS_NUM,Fs->code_heap);
+  CPUStructInit(0,cpu_structs,adam_task);
+  asm {//RAX has GS
+    IMPORT SET_GS_BASE;
+    CALL SET_GS_BASE
+  }
+  if (Bt(&ee.rdx,9)) {
+//Unnecessary?
+    //    SetMSR(IA32_LAPIC_BASE,dev.uncached_alias+LAPIC_BASE+0x900);
+    MPAPICInit;
+  }
+}
+
+interrupt U0 IntMPCrash()
+{//Entering the debugger from another core causes an interrupt on Core0
+//Which calls this routine.
+  *(dev.uncached_alias+LAPIC_EOI)(U32 *)=0;
+  mp_cnt=1;
+  Raw(ON);
+  text.raw_flags|=RWF_SHOW_DOLLAR;
+  "MP Crash CPU%02X Task:%08X\n"
+  "RIP:%P\n",dbg.mp_crash->cpu_num,dbg.mp_crash->task,dbg.mp_crash->rip;
+  Panic(dbg.mp_crash->msg,dbg.mp_crash->msg_num);
+}
+
+ diff --git a/public/Wb/Kernel/PCIBIOS.HC.HTML b/public/Wb/Kernel/PCIBIOS.HC.HTML new file mode 100755 index 0000000..2bce1ac --- /dev/null +++ b/public/Wb/Kernel/PCIBIOS.HC.HTML @@ -0,0 +1,320 @@ + + + + + + + + + + + +
+asm {
+USE32
+
+SYS_PCIBIOS_SERVICE_DIR:: DU32  0;
+SYS_PCI_SERVICES::       DU32   0;
+
+SYS_FIND_PCIBIOS_SERVICE_DIR::
+        MOV     ESI,0xE0000
+        MOV     ECX,(0x100000-0xE0000)/4
+@@05:   CMP     U32 [ESI],'_32_'
+        JNE     @@20
+        PUSH    ECX
+        XOR     ECX,ECX
+        MOV     CL,U8 9[ESI]
+        SHL     ECX,4
+@@10:   MOV     EDI,ESI
+        XOR     EAX,EAX
+        XOR     EDX,EDX
+@@15:   MOV     DL,U8 [EDI]
+        ADD     EAX,EDX
+        INC     EDI
+        DEC     ECX
+        JNZ     @@15
+        POP     ECX
+        TEST    AL,AL
+        JNZ     @@20
+        MOV     U32 [SYS_PCIBIOS_SERVICE_DIR],ESI
+        MOV     ESI,U32 4[ESI]
+        MOV     U32 [SYS_PCIBIOS_SERVICE_CALL],ESI
+        RET
+
+@@20:   ADD     ESI,4
+        LOOP    @@05
+        MOV     U32 [SYS_PCIBIOS_SERVICE_DIR],0
+        RET
+
+SYS_FIND_PCI_SERVICES::
+        MOV     ESI,U32 [SYS_PCIBIOS_SERVICE_DIR]
+        TEST    ESI,ESI
+        JNZ     @@05
+        MOV     U32 [SYS_PCI_SERVICES],0
+        RET
+@@05:   MOV     EAX,'$PCI'
+        XOR     EBX,EBX
+        DU8     0x9A;            //CALL CGDT.cs32:PCIBIOS_SERVICE
+SYS_PCIBIOS_SERVICE_CALL:: DU32 0;
+        DU16    CGDT.cs32;
+        TEST    AL,AL
+        JNZ     @@05
+        LEA     ESI,U32 [EBX+EDX]
+        MOV     U32 [SYS_PCI_SERVICES],ESI
+        RET
+
+@@05:   MOV     U32 [SYS_PCI_SERVICES],0
+        RET
+
+USE64
+C32_EAX::       DU32    0;
+C32_EBX::       DU32    0;
+C32_ECX::       DU32    0;
+C32_EDX::       DU32    0;
+C32_ESI::       DU32    0;
+C32_EDI::       DU32    0;
+C32_EFLAGS::    DU32    0;
+
+C32_RSP::       DU64    0;
+
+_FAR_CALL32::
+//This calls a 32-bit mode routine.
+//(We must switch from 64-bit mode to do it.)
+//
+//NON REENTRANT
+//
+        PUSH    RBP
+        MOV     RBP,RSP
+        MOV     RAX,U64 SF_ARG1[RBP]
+        TEST    RAX,RAX
+        JNZ     @@05
+        POP     RBP
+        RET1    8       //return FALSE
+@@05:   MOV     U32 [C32_ADD],EAX
+        PUSH_REGS
+        PUSHFD
+        XOR     RAX,RAX
+        PUSH    U64 FS:CTask.addr[RAX]
+        PUSH    U64 GS:CCPU.addr[RAX]
+        MOV     U64 [C32_RSP],RSP
+        PUSH    U32 CGDT.ds             //STKSEG
+        PUSH    U32 BOOT_RAM_LIMIT      //STK
+        PUSH    U32 0                   //FLAGS--interrupts off
+        PUSH    U32 CGDT.cs32
+        LEA     RAX,[@@15]
+        PUSH    RAX
+        IRET
+USE32
+@@15:
+        WBINVD
+//disable paging
+        MOV_EAX_CR0
+        BTR     EAX,31
+        MOV_CR0_EAX
+
+        MOV     ECX,IA32_EFER
+        XOR     EDX,EDX
+        XOR     EAX,EAX
+        WRMSR
+
+        MOV     AX,CGDT.ds
+        MOV     FS,AX
+        MOV     GS,AX
+//SS already set
+
+        MOV     EAX,U32 [C32_EAX]
+        MOV     EBX,U32 [C32_EBX]
+        MOV     ECX,U32 [C32_ECX]
+        MOV     EDX,U32 [C32_EDX]
+        MOV     ESI,U32 [C32_ESI]
+        MOV     EDI,U32 [C32_EDI]
+        MOV     U32 [C32_EFLAGS],0
+
+        DU8     0x9A;            //CALL CGDT.cs32:[C32_ADD]
+C32_ADD:: DU32  0;
+        DU16    CGDT.cs32;
+
+        PUSHFD
+        POP     U32 [C32_EFLAGS]
+
+        MOV     U32 [C32_EAX],EAX
+        MOV     U32 [C32_EBX],EBX
+        MOV     U32 [C32_ECX],ECX
+        MOV     U32 [C32_EDX],EDX
+        MOV     U32 [C32_ESI],ESI
+        MOV     U32 [C32_EDI],EDI
+
+        PUSH    U32 0   //Return from next call will be 64-bit
+        CALL    SYS_ENTER_LONG_MODE
+
+USE64   MOV     RSP,U64 [C32_RSP]
+        POP     RAX
+        CALL    SET_GS_BASE
+        POP     RAX
+        CALL    SET_FS_BASE
+
+        POPFD
+        POP_REGS
+        XOR     RAX,RAX
+        MOV     AL,TRUE
+        POP     RBP
+        RET1    8
+}
+
+_extern C32_EAX U32 c32_eax;
+_extern C32_EBX U32 c32_ebx;
+_extern C32_ECX U32 c32_ecx;
+_extern C32_EDX U32 c32_edx;
+_extern C32_ESI U32 c32_esi;
+_extern C32_EDI U32 c32_edi;
+_extern C32_EFLAGS U32 c32_eflags;
+_extern SYS_PCI_SERVICES U32 sys_pci_services;
+
+_extern _FAR_CALL32 Bool FarCall32(U0 (*fp_addr)());//Not reentrant.For PCIBIOS.
+
+U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg)
+{//Read U8 in PCI configspace at bus,dev,fun,reg.
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB108;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  if (FarCall32(sys_pci_services))
+    res=c32_ecx.u8[0];
+  else
+    res=0xFF;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg)
+{//Read U16 in PCI configspace at bus,dev,fun,reg.
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB109;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  if (FarCall32(sys_pci_services))
+    res=c32_ecx.u16[0];
+  else
+    res=0xFFFF;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg)
+{//Read U32 in PCI configspace at bus,dev,fun,reg.
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10A;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  if (FarCall32(sys_pci_services))
+    res=c32_ecx;
+  else
+    res=0xFFFFFFFF;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
+{//Write U8 in PCI configspace at bus,dev,fun,reg.
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10B;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  c32_ecx=val;
+  FarCall32(sys_pci_services);
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+}
+
+U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
+{//Write U16 in PCI configspace at bus,dev,fun,reg.
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10C;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  c32_ecx=val;
+  FarCall32(sys_pci_services);
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+}
+
+U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
+{//Write U32 in PCI configspace at bus,dev,fun,reg.
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB10D;
+  c32_ebx=bus<<8+dev<<3+fun;
+  c32_edi=rg;
+  c32_ecx=val;
+  FarCall32(sys_pci_services);
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+}
+
+I64 PCIClassFind(I64 class_code,I64 n)
+{/*Find bus,dev,fun of Nth class_code dev.
+
+class_code is low three bytes
+n is index starting at zero
+Return: -1 not found
+else bus,dev,fun.
+*/
+  I64 res;
+  PUSHFD
+  CLI
+  while (LBts(&sys_semas[SEMA_FAR_CALL32],0))
+    Yield;
+  c32_eax=0xB103;
+  c32_esi=n;
+  c32_ecx=class_code;
+  if (FarCall32(sys_pci_services) && !c32_eax.u8[1])
+    res=c32_ebx.u8[1]<<16+(c32_ebx&0xF8)<<5+c32_ebx&7;
+  else
+    res=-1;
+  LBtr(&sys_semas[SEMA_FAR_CALL32],0);
+  POPFD
+  return res;
+}
+
+
+ diff --git a/public/Wb/Kernel/QSort.HC.HTML b/public/Wb/Kernel/QSort.HC.HTML new file mode 100755 index 0000000..a05c07f --- /dev/null +++ b/public/Wb/Kernel/QSort.HC.HTML @@ -0,0 +1,135 @@ + + + + + + + + + + + +
+U0 QSortI64(I64 *base,I64 num, I64 (*fp_compare)(I64 e1,I64 e2))
+{/*Quick Sort for width==8.
+fp_compare() passes by value instead of ref.
+
+For ascending strings: return StrCmp(e1,e2);
+For ascending ints   : return e1-e2;
+
+Maybe, look at ::/Demo/MultiCore/MPRadix.HC.
+*/
+  I64 i,*left,*right,pivot;
+  if (num>1) {
+    left =base;
+    right=base+num-1;
+    pivot=base[num/2];
+    do {
+      while ((*fp_compare)(*left,pivot)<0)
+        left++;
+      while ((*fp_compare)(*right,pivot)>0)
+        right--;
+      if (left<=right)
+        SwapI64(left++,right--);
+    } while (left<=right);
+    i=right+1-base;
+    if (1<i<num)
+      QSortI64(base,i,fp_compare);
+    i=base+num-left;
+    if (1<i<num)
+      QSortI64(left,i,fp_compare);
+  }
+}
+
+U0 QSort2a(U8 **base,I64 num,I64 (*fp_compare)(U8 **_e1,U8 **_e2))
+{//Not public.For case of width==size(U8 *)==8.
+//fp_compare() passes by ref.
+  I64 i;
+  U8 **left,**right,*pivot;
+  left =base;
+  right=base+num-1;
+  pivot=base[num/2];
+  do {
+    while ((*fp_compare)(left,&pivot)<0)
+      left++;
+    while ((*fp_compare)(right,&pivot)>0)
+      right--;
+    if (left<=right)
+      SwapI64(left++,right--);
+  } while (left<=right);
+  i=right+1-base;
+  if (1<i<num)
+    QSort2a(base,i,fp_compare);
+  i=base+num-left;
+  if (1<i<num)
+    QSort2a(left,i,fp_compare);
+}
+U0 QSort2b(U8 *base,I64 num, I64 width,
+        I64 (*fp_compare)(U8 *e1,U8 *e2),U8 *tmp)
+{//Not public
+  I64 i;
+  U8 *left,*right,*pivot=tmp+width;
+  left =base;
+  right=base+(num-1)*width;
+  MemCpy(pivot,base+num/2*width,width);
+  do {
+    while ((*fp_compare)(left,pivot)<0)
+      left+=width;
+    while ((*fp_compare)(right,pivot)>0)
+      right-=width;
+    if (left<=right) {
+      if (left!=right) {
+        MemCpy(tmp,right,width);
+        MemCpy(right,left,width);
+        MemCpy(left,tmp,width);
+      }
+      left+=width;
+      right-=width;
+    }
+  } while (left<=right);
+  i=1+(right-base)/width;
+  if (1<i<num)
+    QSort2b(base,i,width,fp_compare,tmp);
+  i=num+(base-left)/width;
+  if (1<i<num)
+    QSort2b(left,i,width,fp_compare,tmp);
+}
+U0 QSort(U8 *base,I64 num, I64 width, I64 (*fp_compare)(U8 *e1,U8 *e2))
+{/*Quick Sort: fp_compare() passes by ref.
+
+For ascending strings: return StrCmp(*e1,*e2);
+For ascending ints   : return *e1-*e2;
+Don't return e1-e2 if numbers can overflow, return -1,0 or 1.
+
+Maybe, look at ::/Demo/MultiCore/MPRadix.HC.
+*/
+  U8 *tmp;
+  if (width && num>1) {
+    if (width==sizeof(U8 *))    //assign instead of MemCpy for width 8
+      QSort2a(base,num,fp_compare);
+    else {
+      tmp=MAlloc(width*2);
+      QSort2b(base,num,width,fp_compare,tmp);
+      Free(tmp);
+    }
+  }
+}
+
+ diff --git a/public/Wb/Kernel/Sched.HC.HTML b/public/Wb/Kernel/Sched.HC.HTML new file mode 100755 index 0000000..a14170a --- /dev/null +++ b/public/Wb/Kernel/Sched.HC.HTML @@ -0,0 +1,356 @@ + + + + + + + + + + + +
+/*On each core, tasks are linked in a
+circular doubly-linked list queue with
+the Seth task as the head.  On Core0,
+the queue order represents the front-to-back
+window stack order with the window mgr
+as the wallpaper.
+
+The scheduler is round-robin.  It checks
+if a task is ready and runs it or skips it.
+Swapping tasks just involves storing and
+restoring regs (no disk I/O for virtual
+memory and no addr map changes).  It is
+always fully identity-mapped on all cores.
+Tasks can be switched in half a microsecond.
+
+The scheduler checks if a task is
+waiting for a certain time or waiting
+on a message and skips if not ready.
+A task runs until it voluntarily yields ctrl
+with a call to Yield().  Tasks waiting on I/O
+often loop, checking for a status and
+Yielding.  This does not really degrade
+performance, but pegs the CPU Load.
+
+The scheduler checks for a few keys:
+
+<CTRL-ALT-x> kill a task.
+<CTRL-ALT-DEL> reboots.
+<CTRL-ALT-n> Next task.
+<CTRL-ALT-c> breaks execution of a program.
+
+Each core has its own circular task queue.
+For AP processors, they have a "Seth" task
+which stays in a loop waiting for jobs or
+requests to spawn tasks.  See CoreAPSethTask().
+*/
+
+U0 TaskFocusNext()
+{
+  CTask *task,*_task=sys_focus_task;
+  sys_focus_task=NULL;
+  if (!_task) _task=adam_task;
+  task=_task->next_task;
+  do {
+    if (!Bt(&task->win_inhibit,WIf_SELF_FOCUS)) {
+      sys_focus_task=task;
+      CallExtNum(EXT_WIN_TO_TOP,task,TRUE);
+      return;
+    }
+    task=task->next_task;
+  } while (task!=_task);
+}
+
+asm {
+TASK_CONTEXT_SAVE::
+//OUT:  RSI=FS
+        PUSH    RSI
+        PUSHFD
+        XOR     RSI,RSI
+        MOV     RSI,FS:CTask.addr[RSI]
+        POP     U64 CTask.rflags[RSI]
+        POP     U64 CTask.rsi[RSI]
+        MOV     U64 CTask.rax[RSI],RAX
+
+/*Divert the stk to the Task memory
+and push onto it and divert it back.
+It's a little faster.
+*/
+        MOV     RAX,RSP
+        LEA     RSP,U64 CTask.r15+8[RSI]
+        PUSH    R15
+        PUSH    R14
+        PUSH    R13
+        PUSH    R12
+        PUSH    R11
+        PUSH    R10
+        PUSH    R9
+        PUSH    R8
+        PUSH    RDI
+        PUSH    RBP
+        PUSH    RBX
+        PUSH    RDX
+        PUSH    RCX
+        MOV     RSP,RAX
+
+        MOV     RAX,U64 CTask.fpu_mmx[RSI]
+        FXSAVE  U64 [RAX]
+
+        MOV     RDX,U64 CTask.bpt_lst[RSI]
+@@05:   TEST    RDX,RDX
+        JZ      @@10
+        MOV     RDI,U64 CBpt.addr[RDX]
+        MOV     AL,U8 CBpt.val[RDX]
+        MOV     U8 [RDI],AL
+        MOV     RDX,U64 CBpt.next[RDX]
+        JMP     @@05
+@@10:   RET
+//************************************
+_TASK_CONTEXT_RESTORE::
+        XOR     RAX,RAX
+        INC     U64 GS:CCPU.swap_cnter[RAX]
+        MOV     RSI,FS:CTask.addr[RAX]
+        BT      U32 CTask.rflags[RSI],RFLAGf_INT
+        JNC     @@05
+        BTS     U32 GS:CCPU.cpu_flags[RAX],CPUf_RAN_A_TASK
+@@05:   BT      U64 CTask.task_flags[RSI],TASKf_DISABLE_BPTS
+        JC      @@15
+        MOV     RDX,U64 CTask.bpt_lst[RSI]
+@@10:   TEST    RDX,RDX
+        JZ      @@15
+        MOV     RDI,U64 CBpt.addr[RDX]
+        MOV     U8 [RDI],OC_BPT
+        MOV     RDX,U64 CBpt.next[RDX]
+        JMP     @@10
+
+@@15:   INC     U64 CTask.swap_cnter[RSI]
+
+        MOV     RAX,U64 CTask.fpu_mmx[RSI]
+        FXRSTOR U64 [RAX]
+
+        MOV     RAX,RSP
+        LEA     RSP,U64 CTask.rcx[RSI]
+        POP     RCX
+        POP     RDX
+        POP     RBX
+        POP     RBP
+        POP     RDI
+        POP     R8
+        POP     R9
+        POP     R10
+        POP     R11
+        POP     R12
+        POP     R13
+        POP     R14
+        POP     R15
+        MOV     RSP,RAX
+
+        MOV     RAX,U64 CTask.rax[RSI]
+        PUSH    CGDT.ds
+        PUSH    U64 CTask.rsp[RSI]
+        PUSH    U64 CTask.rflags[RSI]
+        PUSH    CGDT.cs64
+        PUSH    U64 CTask.rip[RSI]
+        MOV     RSI,U64 CTask.rsi[RSI]
+        IRET
+//************************************
+END_RSI_TASK:
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+_TASK_END_NOW::
+        CALL    &TaskEnd
+        MOV     RSI,RAX
+        CALL    SET_FS_BASE
+        JMP     I8 RESTORE_RSI_TASK
+
+_YIELD::
+        PUSHFD
+        TEST    U8 [SYS_SEMAS+SEMA_SINGLE_USER*DFT_CACHE_LINE_WIDTH],1
+        JZ      @@05
+        POPFD           //If single user, don't change task.
+        RET
+
+@@05:   CLI
+        CALL    TASK_CONTEXT_SAVE
+        MOV     EBX,U32 _RET
+        MOV     U64 CTask.rip[RSI],RBX
+        POP     U64 CTask.rflags[RSI]
+        MOV     U64 CTask.rsp[RSI],RSP
+        MOV     RSI,U64 CTask.next_task[RSI]
+
+RESTORE_RSI_TASK:
+        TEST    U64 [SYS_CTRL_ALT_FLAGS],1<<CTRL_ALT_DEL|
+1<<CTRL_ALT_TAB|1<<CTRL_ALT_X|1<<CTRL_ALT_C
+        JNZ     HANDLE_SYSF_KEY_EVENT
+
+RESTORE_RSI_TASK2:
+@@20:   BT      U64 CTask.task_flags[RSI],TASKf_KILL_TASK
+        JC      END_RSI_TASK
+        TEST    U64 CTask.task_flags[RSI],
+                1<<TASKf_AWAITING_MSG|1<<TASKf_SUSPENDED
+        JNZ     @@25
+
+        MOV     RAX,U64 [&cnts.jiffies]
+        CMP     U64 CTask.wake_jiffy[RSI],RAX
+        JG      @@25    //Jmp if not ready, yet.
+
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+        JMP     I32 _TASK_CONTEXT_RESTORE
+
+@@25:   MOV     RSI,U64 CTask.next_task[RSI]
+        XOR     RAX,RAX
+        CMP     U64 GS:CCPU.seth_task[RAX],RSI
+        JNE     @@20    //Jmp if not Seth
+        BTR     U32 GS:CCPU.cpu_flags[RAX],CPUf_RAN_A_TASK
+        JC      @@20    //Jmp if had chance for IRQ already
+        MOV     RAX,U64 GS:CCPU.idle_task[RAX]
+        MOV     RSP,U64 CTask.stk[RAX]
+        ADD     RSP,MEM_DFT_STK+CTaskStk.stk_base       //Rst to top
+        CALL    SET_FS_BASE
+        STI     //Restore idle task so we can unmask IRQs.
+        HLT
+SYS_IDLE_PT::
+        CLI
+
+RESTORE_SETH_TASK_IF_READY:
+        XOR     RAX,RAX
+        MOV     RSI,GS:CCPU.seth_task[RAX]
+        JMP     RESTORE_RSI_TASK
+
+HANDLE_SYSF_KEY_EVENT:
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+        XOR     RBX,RBX
+        MOV     RAX,GS:CCPU.num[RBX]
+        TEST    RAX,RAX
+        JNZ     I32 RESTORE_RSI_TASK2
+
+        MOV     EAX,U32 SYS_CTRL_ALT_FLAGS
+        LOCK
+        BTR     U32 [RAX],CTRL_ALT_DEL
+        JC      I32 &Reboot
+
+        CMP     U64 GS:CCPU.idle_task[RBX],RSI
+        JE      RESTORE_SETH_TASK_IF_READY
+
+        LOCK
+        BTR     U32 [RAX],CTRL_ALT_TAB
+        JNC     @@05
+        CALL    &TaskFocusNext
+        JMP     I32 RESTORE_FS_TASK
+
+@@05:   LOCK
+        BTR     U32 [RAX],CTRL_ALT_X
+        JC      END_FOCUS_USER
+        LOCK
+        BTR     U32 [RAX],CTRL_ALT_C
+        JNC     I32 RESTORE_RSI_TASK
+
+BREAK_FOCUS_USER:
+        MOV     RSI,U64 [SYS_FOCUS_TASK]
+        TEST    RSI,RSI
+        JZ      RESTORE_SETH_TASK_IF_READY
+        BT      U64 CTask.win_inhibit[RSI],WIf_SELF_FOCUS
+        JC      I32 RESTORE_RSI_TASK
+        LOCK
+        BTR     U64 CTask.task_flags[RSI],TASKf_BREAK_LOCKED
+        JNC     @@10
+        LOCK
+        BTS     U64 CTask.task_flags[RSI],TASKf_PENDING_BREAK
+        JMP     I32 RESTORE_RSI_TASK
+
+@@10:   MOV     RAX,&Break
+        MOV     U64 CTask.rip[RSI],RAX
+        BT      U64 CTask.task_flags[RSI],TASKf_BREAK_TO_SHIFT_ESC
+        JC      I32 RESTORE_RSI_TASK
+
+//Do these now, in case interrupt happens.
+        MOV     U64 CTask.wake_jiffy[RSI],0
+        PUSH    RSI
+        CALL    &TaskRstAwaitingMsg
+        JMP     I32 RESTORE_RSI_TASK
+
+END_FOCUS_USER:
+        MOV     RSI,U64 [SYS_FOCUS_TASK]
+        CALL    &TaskFocusNext
+        TEST    RSI,RSI
+        JZ      I32 RESTORE_SETH_TASK_IF_READY
+        MOV     RAX,RSI
+        CALL    SET_FS_BASE
+        BT      U64 CTask.win_inhibit[RSI],WIf_SELF_FOCUS
+        JC      I32 RESTORE_RSI_TASK
+        LOCK
+        BTS     U64 CTask.task_flags[RSI],TASKf_KILL_TASK
+        JMP     I32 END_RSI_TASK
+
+RESTORE_FS_TASK:
+        XOR     RSI,RSI
+        MOV     RSI,FS:CTask.addr[RSI]
+        JMP     I32 RESTORE_RSI_TASK
+}
+
+_extern _TASK_CONTEXT_RESTORE U0 TaskContextRestore(); //Restore a task context.
+_extern _YIELD U0 Yield(); //Yield cpu to next task.
+_extern _TASK_END_NOW U0 TaskEndNow(); //Terminate current task.
+
+U0 TaskQueIns(CTask *task,CTask *pred=NULL)
+{//Insert a task in the scheduler running task queue.
+//You have no business with this, probably.
+  CTask *last;
+  PUSHFD
+  CLI
+  if (!pred) pred=Fs;
+  last=pred->last_task;
+  last->next_task=pred->last_task=task;
+  task->last_task=last;
+  task->next_task=pred;
+  POPFD
+}
+
+U0 TaskQueRem(CTask *task)
+{//Remove a task from the scheduler running task queue.
+//Use Suspend().
+  CTask *next,*last;
+  PUSHFD
+  CLI
+  next=task->next_task;
+  last=task->last_task;
+  last->next_task=next;
+  next->last_task=last;
+  POPFD
+}
+
+U0 TaskQueInsChild(CTask *task)
+{
+  CTask *last,*pred;
+  PUSHFD
+  CLI
+  pred=task->parent_task->last_child_task;
+  last=pred->last_sibling_task;
+  last->next_sibling_task=pred->last_sibling_task=task;
+  task->last_sibling_task=last;
+  task->next_sibling_task=pred;
+  POPFD
+}
+
+ diff --git a/public/Wb/Kernel/SerialDev/Keyboard.HC.HTML b/public/Wb/Kernel/SerialDev/Keyboard.HC.HTML new file mode 100755 index 0000000..8c25930 --- /dev/null +++ b/public/Wb/Kernel/SerialDev/Keyboard.HC.HTML @@ -0,0 +1,523 @@ + + + + + + + + + + + +
+asm {
+NORMAL_KEY_SCAN_DECODE_TABLE::
+        DU8     0,CH_ESC,"1234567890-=",CH_BACKSPACE,'\t';
+        DU8     "qwertyuiop[]",'\n',0,"as";
+        DU8     "dfghjkl;'\`",0,"\\zxcv";
+        DU8     "bnm,./",0,'*',0,CH_SPACE,0,0,0,0,0,0;
+        DU8     0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
+SHIFT_KEY_SCAN_DECODE_TABLE::
+        DU8     0,CH_SHIFT_ESC,"!@#$%^&*()_+",CH_BACKSPACE,'\t';
+        DU8     "QWERTYUIOP{}",'\n',0,"AS";
+        DU8     "DFGHJKL:\"~",0,"|ZXCV";
+        DU8     "BNM<>?",0,'*',0,CH_SHIFT_SPACE,0,0,0,0,0,0;
+        DU8     0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
+CTRL_KEY_SCAN_DECODE_TABLE::
+        DU8     0,CH_ESC,"1234567890-=",CH_BACKSPACE,'\t';
+        DU8     CH_CTRLQ,CH_CTRLW,CH_CTRLE,CH_CTRLR,CH_CTRLT,CH_CTRLY,CH_CTRLU,
+                CH_CTRLI,CH_CTRLO,CH_CTRLP,"[]",'\n',0,CH_CTRLA,CH_CTRLS;
+        DU8     CH_CTRLD,CH_CTRLF,CH_CTRLG,CH_CTRLH,CH_CTRLJ,CH_CTRLK,CH_CTRLL,
+                ";'\`",0,"\\",CH_CTRLZ,CH_CTRLX,CH_CTRLC,CH_CTRLV;
+        DU8     CH_CTRLB,CH_CTRLN,CH_CTRLM,",./",0,'*',0,CH_SPACE,0,0,0,0,0,0;
+        DU8     0,0,0,0,0,0,0,0,0,0,'-',0,0,0,'+',0;
+}
+
+U0 KbdCmdSend(I64 port, U8 val)
+{
+  F64 timeout=tS+0.125;
+  while (tS<timeout) {
+    if (!(InU8(KBD_CTRL)&2)) {
+      OutU8(port,val);
+      return;
+    }
+  }
+  throw;
+}
+
+I64 KbdCmdRead()
+{
+  F64 timeout=tS+0.125;
+  while (tS<timeout)
+    if (InU8(KBD_CTRL)&1)
+      return InU8(KBD_PORT);
+  throw;
+}
+
+U0 KbdCmdFlush()
+{
+  F64 timeout=tS+0.03;
+  while (tS<timeout)
+    InU8(KBD_PORT);
+}
+
+U0 KbdLEDsSet(I64 sc)
+{
+  U8 v=0;
+  BEqu(&v,0,Bt(&sc,SCf_SCROLL));
+  BEqu(&v,1,Bt(&sc,SCf_NUM));
+  BEqu(&v,2,Bt(&sc,SCf_CAPS));
+  try {
+    KbdCmdSend(KBD_PORT,0xED);
+    KbdCmdSend(KBD_PORT,v);
+  } catch
+    Fs->catch_except=TRUE;
+}
+
+U0 KbdMsCmdAck(...)
+{
+  I64 i,ack,timeout;
+  for (i=0;i<argc;i++) {
+    timeout=5;
+    do {
+      ack=0;
+      try {
+        KbdCmdSend(KBD_CTRL,0xD4);
+        KbdCmdSend(KBD_PORT,argv[i]);
+        ack=KbdCmdRead;
+      } catch {
+        KbdCmdFlush;
+        Fs->catch_except=TRUE;
+      }
+    } while (ack!=0xFA && --timeout);
+    if (!timeout)
+      throw;
+  }
+}
+
+U0 KbdTypeMatic(U8 delay)
+{//Set speed of repeated keys.
+  try {
+    KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
+    KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
+    KbdCmdSend(KBD_PORT,0xF3);
+    KbdCmdSend(KBD_PORT,delay); //Typematic rate
+    KbdCmdSend(KBD_CTRL,0xA8); //Enable Mouse
+  } catch {
+    KbdCmdFlush;
+    Fs->catch_except=TRUE;
+  }
+}
+
+I64 Char2ScanCode(I64 ch,I64 sc_flags=0)
+{//ASCII val to scan code (Slow).
+  I64 i;
+  U8 *table;
+  if (sc_flags) {
+    table=NORMAL_KEY_SCAN_DECODE_TABLE;
+    if (sc_flags & SCF_CTRL || ch<26)
+      table=CTRL_KEY_SCAN_DECODE_TABLE;
+    else if (sc_flags & SCF_SHIFT || 'A'<=ch<='Z') {
+      if (!(sc_flags & SCF_CAPS))
+        table=SHIFT_KEY_SCAN_DECODE_TABLE;
+    } else {
+      if (sc_flags & SCF_CAPS)
+        table=SHIFT_KEY_SCAN_DECODE_TABLE;
+    }
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i|sc_flags;
+    return sc_flags;
+  } else {
+    table=NORMAL_KEY_SCAN_DECODE_TABLE;
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i;
+    table=SHIFT_KEY_SCAN_DECODE_TABLE;
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i|SCF_SHIFT;
+    table=CTRL_KEY_SCAN_DECODE_TABLE;
+    for (i=0;i<0x50;i++)
+      if (table[i]==ch)
+        return i|SCF_CTRL;
+    return 0;
+  }
+}
+
+U8 ScanCode2Char(I64 sc)
+{//Scan code to ASCII val.
+  U8 *table=NORMAL_KEY_SCAN_DECODE_TABLE;
+  if (sc&SCF_E0_PREFIX)
+    return 0;
+  if (sc&SCF_CTRL)
+    table=CTRL_KEY_SCAN_DECODE_TABLE;
+  else if (sc&SCF_SHIFT) {
+    if (!(sc&SCF_CAPS))
+      table=SHIFT_KEY_SCAN_DECODE_TABLE;
+  } else {
+    if (sc&SCF_CAPS)
+      table=SHIFT_KEY_SCAN_DECODE_TABLE;
+  }
+  sc&=0x7F;
+  if (sc>=0x50)
+    return 0;
+  else
+    return table[sc];
+}
+
+U8 scan_code_map[0x100]={
+  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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,SC_SHIFT,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,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,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,SC_ENTER,SC_CTRL,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,SC_HOME,
+        SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
+  SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INS,SC_DELETE,0,0,0,0,
+        0,0,0,0,SC_GUI,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,0,
+};
+
+U8 num_lock_map[0x100]={
+  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,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,0,0,0,8,9,10,0,5,6,7,0,2,
+  3,4,11,0x34,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,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,0,0,0,0,SC_ENTER,SC_CTRL,0,0,
+  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+  0,0,0,0,0,0x35,0,0,SC_ALT,0,0,0,0,0,0,0,
+  0,0,0,0,0,0,0,SC_HOME,
+        SC_CURSOR_UP,SC_PAGE_UP,0,SC_CURSOR_LEFT,0,SC_CURSOR_RIGHT,0,SC_END,
+  SC_CURSOR_DOWN,SC_PAGE_DOWN,SC_INS,SC_DELETE,0,0,0,0,
+        0,0,0,0,SC_GUI,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,0,
+};
+
+U8 *Char2KeyName(I64 ch,Bool include_ctrl=TRUE)
+{//ASCII val to key name.
+  I64 i;
+  U8 buf[STR_LEN];
+  if (ch<=CH_SPACE) {
+    switch [ch] {
+      case '\n':
+        StrCpy(buf,"ENTER");
+        break;
+      case CH_BACKSPACE:
+        StrCpy(buf,"BACKSPACE");
+        break;
+      case '\t':
+        StrCpy(buf,"TAB");
+        break;
+      case CH_ESC:
+        StrCpy(buf,"ESC");
+        break;
+      case CH_SHIFT_ESC:
+        StrCpy(buf,"SHIFT_ESC");
+        break;
+      case 0: //nobound switch
+      case 29:
+      case 30:
+        *buf=0;
+        break;
+      case CH_SHIFT_SPACE:
+        StrCpy(buf,"SHIFT_SPACE");
+        break;
+      case CH_SPACE:
+        StrCpy(buf,"SPACE");
+        break;
+      default:
+        if (include_ctrl)
+          StrCpy(buf,"CTRL ");
+        buf[i=StrLen(buf)]=ch-1+'a';
+        buf[i+1]=0;
+        break;
+    }
+  } else if (Bt(char_bmp_printable,ch)) {
+    *buf=ch;
+    buf[1]=0;
+  } else
+    *buf=0;
+  return StrNew(buf);
+}
+
+U8 *ScanCode2KeyName(I64 sc)
+{//Scan code to key name.
+  I64 ch;
+  U8 buf[STR_LEN],*st;
+  *buf=0;
+  if (sc&SCF_CTRL)
+    CatPrint(buf,"CTRL ");
+  if (sc&SCF_ALT)
+    CatPrint(buf,"ALT ");
+  if (sc&SCF_SHIFT)
+    CatPrint(buf,"SHIFT ");
+  if (sc&SCF_NO_SHIFT)
+    CatPrint(buf,"      ");
+  if (ch=ScanCode2Char(sc&255)) {
+    st=Char2KeyName(ch,FALSE);
+    StrCpy(buf+StrLen(buf),st);
+    Free(st);
+  } else {
+    switch (sc&255) {
+      case SC_BACKSPACE:CatPrint(buf,"BACK");   break;
+      case SC_CAPS:     CatPrint(buf,"CAPS");   break;
+      case SC_NUM:      CatPrint(buf,"NUM");    break;
+      case SC_SCROLL:   CatPrint(buf,"SCROLL"); break;
+      case SC_CURSOR_UP:CatPrint(buf,"UP");     break;
+      case SC_CURSOR_DOWN:CatPrint(buf,"DOWN"); break;
+      case SC_CURSOR_LEFT:CatPrint(buf,"LEFT"); break;
+      case SC_CURSOR_RIGHT:CatPrint(buf,"RIGHT"); break;
+      case SC_PAGE_UP:  CatPrint(buf,"PAGE_UP");  break;
+      case SC_PAGE_DOWN:CatPrint(buf,"PAGE_DOWN");break;
+      case SC_HOME:     CatPrint(buf,"HOME");   break;
+      case SC_END:      CatPrint(buf,"END");    break;
+      case SC_INS:      CatPrint(buf,"INS");    break;
+      case SC_DELETE:   CatPrint(buf,"DELETE"); break;
+      case SC_F1:       CatPrint(buf,"F1");     break;
+      case SC_F2:       CatPrint(buf,"F2");     break;
+      case SC_F3:       CatPrint(buf,"F3");     break;
+      case SC_F4:       CatPrint(buf,"F4");     break;
+      case SC_F5:       CatPrint(buf,"F5");     break;
+      case SC_F6:       CatPrint(buf,"F6");     break;
+      case SC_F7:       CatPrint(buf,"F7");     break;
+      case SC_F8:       CatPrint(buf,"F8");     break;
+      case SC_F9:       CatPrint(buf,"F9");     break;
+      case SC_F10:      CatPrint(buf,"F10");    break;
+      case SC_F11:      CatPrint(buf,"F11");    break;
+      case SC_F12:      CatPrint(buf,"F12");    break;
+      case SC_GUI:      CatPrint(buf,"WINDOWS");  break;
+      case SC_PRTSCRN1: CatPrint(buf,"PRTSCRN1"); break;
+      case SC_PRTSCRN2: CatPrint(buf,"PRTSCRN2"); break;
+    }
+  }
+  return StrNew(buf);
+}
+
+U0 KbdBuildSC(U8 raw_byte,Bool in_irq,U8 *_last_raw_byte,I64 *_last_sc)
+{
+  I64 ch,sc_flags,sc,sc2,sc_raw,new_key_f;
+  Bool set_LEDs=FALSE;
+  if (raw_byte==0xE0) {
+    *_last_sc&=~0x1FF;
+    *_last_raw_byte=raw_byte;
+    return;
+  }
+  sc=raw_byte;
+  BEqu(&sc,SCf_E0_PREFIX,*_last_raw_byte==0xE0);
+  BEqu(&sc,SCf_KEY_UP,raw_byte & 0x80);
+  *_last_raw_byte=raw_byte;
+
+  sc_flags=_last_sc->u32[0]&~0x1FF;
+  sc_raw=sc;
+
+  if (sc_flags & SCF_NUM) {
+    if (sc2=num_lock_map[sc.u8[0]])
+      sc.u8[0]=sc2;
+  } else {
+    if (sc2=scan_code_map[sc.u8[0]])
+      sc.u8[0]=sc2;
+  }
+
+  new_key_f=SCF_NEW_KEY;
+  if (sc&SCF_KEY_UP)
+    switch (sc&~SCF_KEY_UP) {
+      case SC_SHIFT:    sc_flags&=~SCF_SHIFT;   break;
+      case SC_CTRL:     sc_flags&=~SCF_CTRL;    break;
+      case SC_ALT:      sc_flags&=~SCF_ALT;     break;
+      case SC_DELETE:   sc_flags&=~SCF_DELETE;  break;
+      case SC_INS:      sc_flags&=~SCF_INS;     break;
+      case SC_CAPS:     sc_flags^=SCF_CAPS;     set_LEDs=TRUE;  break;
+      case SC_NUM:      sc_flags^=SCF_NUM;      set_LEDs=TRUE;  break;
+      case SC_SCROLL:   sc_flags^=SCF_SCROLL;   set_LEDs=TRUE;  break;
+    }
+  else
+    switch (sc) {
+      case SC_SHIFT:
+        if (Bts(&sc_flags,SCf_SHIFT)) new_key_f=0;
+        break;
+      case SC_CTRL:
+        if (Bts(&sc_flags,SCf_CTRL)) new_key_f=0;
+        break;
+      case SC_ALT:
+        if (Bts(&sc_flags,SCf_ALT)) new_key_f=0;
+        break;
+      case SC_DELETE:
+        sc_flags|=SCF_DELETE;
+        break;
+      case SC_INS:
+        sc_flags|=SCF_INS;
+        break;
+    }
+
+  sc_flags|=new_key_f;
+  sc=sc_flags|sc|(sc_flags|sc_raw)<<32;
+  if (sc_flags & SCF_CTRL && sc_flags & SCF_ALT) {
+    if (!(sc&SCF_KEY_UP)) {
+      if (sc&255==SC_DELETE && !(sc_flags & SCF_SHIFT))
+        CtrlAltDel(sc);
+      else {
+        if (sc&255==SC_ESC)
+          ch='t';
+        else if (sc&255==SC_TAB)
+          ch='n';
+        else
+          ch=ScanCode2Char(sc&255);
+        if ('a'<=ch<='z') {
+          sc&=~(SCF_NEW_KEY|SCF_NEW_KEY<<32);
+          ch-='a';
+          kbd.last_down_scan_code=sc;
+          if (keydev.fp_ctrl_alt_cbs[ch] &&
+                Bt(&keydev.ctrl_alt_in_irq_flags,ch)==in_irq &&
+                (!(sc_flags & SCF_SHIFT)&&keydev.ctrl_alt_no_shift_descs[ch]) ||
+                sc_flags & SCF_SHIFT && keydev.ctrl_alt_shift_descs[ch])
+            (*keydev.fp_ctrl_alt_cbs[ch])(sc);
+        }
+      }
+    }
+  }
+  if (set_LEDs && !in_irq)
+    KbdLEDsSet(sc);
+  *_last_sc=sc;
+}
+
+U0 KbdPktRead()
+{
+  static U8 last_raw_byte=0;
+  static I64 last_sc=0;
+  U8 raw_byte;
+  if (GetTSC>kbd.timestamp+cnts.time_stamp_freq>>3)
+    FifoU8Flush(kbd.fifo);
+  kbd.timestamp=GetTSC;
+  raw_byte=InU8(KBD_PORT);
+  KbdBuildSC(raw_byte,TRUE,&last_raw_byte,&last_sc);
+  if (!FifoU8Cnt(kbd.fifo)) {
+    FifoU8Ins(kbd.fifo,raw_byte);
+    if (raw_byte!=0xE0) {
+      while (FifoU8Rem(kbd.fifo,&raw_byte))
+        FifoU8Ins(kbd.fifo2,raw_byte);
+    }
+  } else {
+    FifoU8Ins(kbd.fifo,raw_byte);
+    while (FifoU8Rem(kbd.fifo,&raw_byte))
+      FifoU8Ins(kbd.fifo2,raw_byte);
+  }
+}
+
+interrupt U0 IRQKbd()
+{
+  CLD
+  OutU8(0x20,0x20);
+  kbd.irqs_working=TRUE;
+  if (ms_hard.install_in_progress) {
+    kbd.rst=TRUE;
+    return;
+  }
+  keydev.ctrl_alt_ret_addr=GetRBP()(I64)+8;
+  KbdPktRead;
+}
+
+U0 KbdInit()
+{
+  try {
+    KbdCmdFlush;
+    KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
+    KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
+    KbdCmdSend(KBD_PORT,0xF0);
+    KbdCmdSend(KBD_PORT,0x02);
+    KbdLEDsSet(kbd.scan_code);
+  } catch {
+    KbdCmdFlush;
+    Fs->catch_except=TRUE;
+  }
+  IntEntrySet(0x21,&IRQKbd);
+  OutU8(0x21,InU8(0x21)&~2);
+}
+
+U0 KbdHndlr()
+{
+  static U8 last_raw_byte=0;
+  U8  raw_byte;
+  FifoU8Rem(kbd.fifo2,&raw_byte);
+  KbdBuildSC(raw_byte,FALSE,&last_raw_byte,&kbd.scan_code);
+  if (raw_byte==0xE0) {
+    FifoU8Rem(kbd.fifo2,&raw_byte);
+    KbdBuildSC(raw_byte,FALSE,&last_raw_byte,&kbd.scan_code);
+  }
+  if (Btr(&kbd.scan_code,SCf_NEW_KEY)) {
+    kbd.new_key_timestamp=kbd.timestamp;
+    Btr(&kbd.scan_code,32+SCf_NEW_KEY);
+    FifoI64Ins(kbd.scan_code_fifo,kbd.scan_code);
+    kbd.cnt++;
+    if (!(kbd.scan_code&SCF_KEY_UP)) {
+      kbd.last_down_scan_code=kbd.scan_code;
+      Bts(kbd.down_bitmap,kbd.scan_code.u8[0]);
+      Bts(kbd.down_bitmap2,kbd.scan_code.u8[4]);
+    } else {
+      Btr(kbd.down_bitmap,kbd.scan_code.u8[0]);
+      Btr(kbd.down_bitmap2,kbd.scan_code.u8[4]);
+    }
+  }
+}
+
+I64 KbdMsgsQue()
+{
+  I64 arg1,arg2,msg_code=MSG_NULL;
+  CTask *task_focus;
+  if (task_focus=sys_focus_task) {
+    while (FifoI64Rem(kbd.scan_code_fifo,&arg2)) {
+      arg1=ScanCode2Char(arg2);
+      if (arg2 & SCF_KEY_UP) {
+        TaskMsg(task_focus,0,MSG_KEY_UP,arg1,arg2,0);
+        msg_code=MSG_KEY_UP;
+      } else {
+        TaskMsg(task_focus,0,MSG_KEY_DOWN,arg1,arg2,0);
+        msg_code=MSG_KEY_DOWN;
+      }
+    }
+  }
+  return msg_code;
+}
+
+I64 KbdMsEvtTime()
+{//Timestamp of last key or mouse event.
+  if (ms_hard.timestamp>kbd.timestamp)
+    return ms_hard.timestamp;
+  else
+    return kbd.new_key_timestamp;
+}
+
+ diff --git a/public/Wb/Kernel/SerialDev/MakeSerialDev.HC.HTML b/public/Wb/Kernel/SerialDev/MakeSerialDev.HC.HTML new file mode 100755 index 0000000..859ff12 --- /dev/null +++ b/public/Wb/Kernel/SerialDev/MakeSerialDev.HC.HTML @@ -0,0 +1,36 @@ + + + + + + + + + + + +
+#exe {Cd(__DIR__);};
+#include "Keyboard"
+#include "Mouse"
+#include "Message"
+#exe {Cd("..");};
+
+ diff --git a/public/Wb/Kernel/SerialDev/Message.HC.HTML b/public/Wb/Kernel/SerialDev/Message.HC.HTML new file mode 100755 index 0000000..58eab18 --- /dev/null +++ b/public/Wb/Kernel/SerialDev/Message.HC.HTML @@ -0,0 +1,275 @@ + + + + + + + + + + + +
+U0 InputFilterTask()
+{
+  CJob *tmpc,*tmpc1;
+  Bool old_filter;
+  I64 old_flags=GetRFlags;
+  Fs->win_inhibit=WIG_USER_TASK_DFT;
+  LBts(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
+  old_filter=LBts(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);
+  LBEqu(&Fs->task_flags,TASKf_FILTER_INPUT,old_filter);
+  while (TRUE) {
+    CLI
+    JobsHndlr(old_flags);
+    tmpc1=&Fs->srv_ctrl.next_waiting;
+    tmpc=tmpc1->next;
+    if (tmpc==tmpc1)
+      break;
+    else {
+      if (tmpc->job_code==JOBT_TEXT_INPUT) {
+        QueRem(tmpc);
+        SetRFlags(old_flags);
+        try
+                ExePrint("%s",tmpc->aux_str);
+        catch
+          Fs->catch_except=TRUE;
+        JobDel(tmpc);
+      } else
+        break;
+    }
+  }
+  Fs->next_input_filter_task->last_input_filter_task=Fs->last_input_filter_task;
+  Fs->last_input_filter_task->next_input_filter_task=Fs->next_input_filter_task;
+  if (!old_filter)
+    LBtr(&Fs->last_input_filter_task->task_flags,TASKf_FILTER_INPUT);
+  SetRFlags(old_flags);
+}
+
+I64 ScanMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)
+{/*Check for a message of type specified by a one in the mask.
+Throw-out messages not in mask.
+If no message fit mask, return NULL immediately.
+Remove desired message, return msg_code.
+Note: This delivers messages from parent down to pop-up.
+*/
+  I64 res,old_flags;
+  CJob *tmpc,*tmpc1;
+  if (!task) task=Fs;
+  old_flags=GetRFlags;
+  tmpc1=&task->srv_ctrl.next_waiting;
+  while (TRUE) {
+    CLI
+    if (task==Fs)
+      JobsHndlr(old_flags);
+    tmpc=tmpc1->next;
+    if (tmpc==tmpc1)
+      break;
+    else {
+      if (tmpc->job_code==JOBT_MSG) {
+        QueRem(tmpc);
+        SetRFlags(old_flags);
+        res=tmpc->msg_code;
+        if (_arg1)
+          *_arg1=tmpc->aux1;
+        if (_arg2)
+          *_arg2=tmpc->aux2;
+        JobDel(tmpc);
+        if ((res!=MSG_KEY_DOWN || !(tmpc->aux2&SCF_KEY_DESC) ||
+              !Bt(&task->win_inhibit,WIf_SELF_KEY_DESC)) && Bt(&mask,res))
+          goto sm_done;
+      }
+    }
+    SetRFlags(old_flags);
+  }
+  res=MSG_NULL;
+  if (_arg1)
+    *_arg1=0;
+  if (_arg2)
+    *_arg2=0;
+  if (task->parent_task&&task->parent_task->popup_task==task) {
+    SetRFlags(old_flags);
+    return ScanMsg(_arg1,_arg2,mask,task->parent_task);
+  }
+sm_done:
+  SetRFlags(old_flags);
+  return res;
+}
+
+I64 FlushMsgs(CTask *task=NULL)
+{//Throw away all messages.  Return count.
+  I64 res=0,arg1,arg2;
+  while (ScanMsg(&arg1,&arg2,~1,task))
+    res++;
+  return res;
+}
+
+I64 GetMsg(I64 *_arg1=NULL,I64 *_arg2=NULL,I64 mask=~1,CTask *task=NULL)
+{//Wait for a message of type specified by a one in the mask.
+//Throw-out all messages not in mask.
+  //Returns msg_code. See ::/Demo/MsgLoop.HC.
+  I64 res;
+  if (!task) task=Fs;
+  LBtr(&task->task_flags,TASKf_IDLE);
+  while (!(res=ScanMsg(_arg1,_arg2,mask,task))) {
+    LBts(&task->task_flags,TASKf_IDLE);
+    Yield;
+  }
+  LBtr(&task->task_flags,TASKf_IDLE);
+  return res;
+}
+
+I64 ScanChar()
+{//Checks for MSG_KEY_DOWN and returns 0 immediately if no key.
+//Waits for MSG_KEY_UP of non-zero ASCII key and returns ASCII if key.
+  //ScanMsg() throws away other message types.
+  I64 arg1a,arg2a,arg1b,arg2b;
+  if (!ScanMsg(&arg1a,&arg2a,1<<MSG_KEY_DOWN)||!arg1a)
+    return 0;
+  else
+    do GetMsg(&arg1b,&arg2b,1<<MSG_KEY_UP);
+    while (!arg1b);  //Be careful of SC_SHIFT and SC_CTRL, etc.
+  return arg1a;
+}
+
+Bool ScanKey(I64 *_ch=NULL,I64 *_scan_code=NULL,Bool echo=FALSE)
+{//Checks for MSG_KEY_DOWN and returns FALSE immediately if no key.
+//Sets ASCII and scan_code.
+  //Removes key message and returns TRUE.
+  //ScanMsg() throws away other message types.
+  I64 ch=0,sc=0;
+  if (ScanMsg(&ch,&sc,1<<MSG_KEY_DOWN)) {
+    if (_ch) *_ch=ch;
+    if (_scan_code) *_scan_code=sc;
+    if (echo)
+      PutKey(ch,sc);
+    return TRUE;
+  } else {
+    if (_ch) *_ch=0;
+    if (_scan_code) *_scan_code=0;
+    return FALSE;
+  }
+}
+
+I64 GetKey(I64 *_scan_code=NULL,Bool echo=FALSE,Bool raw_cursor=FALSE)
+{//Waits for MSG_KEY_DOWN message and returns ASCII.
+//Sets scan_code.
+  //ScanKey() throws away other message types.
+  I64 ch,sc;
+  Bool cursor_on=FALSE;
+  while (!ScanKey(&ch,&sc,FALSE)) {
+    if (IsRaw && raw_cursor) {
+      if (!cursor_on && ToI64(GetTSC*5/cnts.time_stamp_freq)&1) {
+        '.';
+        cursor_on=TRUE;
+      } else if (cursor_on && !(ToI64(GetTSC*5/cnts.time_stamp_freq)&1)) {
+        '' CH_BACKSPACE;
+        cursor_on=FALSE;
+      }
+    }
+    LBts(&Fs->task_flags,TASKf_IDLE);
+    if (IsDbgMode) {
+//We don't want interrupt-driven keyboard when in debugger
+      //because that could have side-effects or crash, so we poll
+      //keyboard when in debugger with interrupts off.
+      PUSHFD
+      CLI
+      KbdMsHndlr(TRUE,FALSE);
+      KbdMsgsQue;
+      POPFD
+    } else {
+      LBts(&Fs->task_flags,TASKf_AWAITING_MSG);
+      Yield;
+    }
+    LBtr(&Fs->task_flags,TASKf_IDLE);
+  }
+  if (IsRaw && raw_cursor && cursor_on)
+    '' CH_BACKSPACE;
+  if (echo)
+    PutKey(ch,sc);
+  if (_scan_code) *_scan_code=sc;
+  return ch;
+}
+
+I64 GetChar(I64 *_scan_code=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE)
+{//Waits for non-zero ASCII key.
+//Sets scan_code.
+  I64 ch1;
+  do ch1=GetKey(_scan_code,FALSE,raw_cursor);
+  while (!ch1);
+  if (echo)
+    "$PT$%c$FG$",ch1;
+  return ch1;
+}
+
+U8 *GetStr(U8 *msg=NULL,U8 *dft=NULL,I64 flags=0)
+{//Returns a MAlloc()ed prompted string.  See Flags.
+  U8 *st;
+  if (msg)
+    "" msg,dft;
+  st=(*fp_getstr2)(flags);
+  if (!*st) {
+    Free(st);
+    if (dft)
+      return StrNew(dft);
+    else
+      return StrNew("");
+  }
+  return st;
+}
+
+I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE)
+{//Prompt into fixed length string. Size must include terminator.
+  U8 *st;
+  I64 ch,i=0;
+  if (!size || !buf) return 0;
+  if (allow_ext) {
+    st=GetStr;
+    if (StrLen(st)>size-1) {
+      MemCpy(buf,st,size-1);
+      buf[size-1]=0;
+    } else
+      StrCpy(buf,st);
+    i=StrLen(buf);
+    Free(st);
+  } else {
+    while (TRUE) {
+      ch=GetChar(,FALSE,IsDbgMode);
+      if (ch=='\n') {
+        '' ch;
+        break;
+      } else if (ch==CH_BACKSPACE) {
+        if (i>0) {
+          i--;
+          '' ch;
+        }
+      } else {
+        if (i<size-1) {
+          buf[i++]=ch;
+          '' ch;
+        }
+      }
+    }
+    buf[i]=0;
+  }
+  return i;
+}
+
+ diff --git a/public/Wb/Kernel/SerialDev/Mouse.HC.HTML b/public/Wb/Kernel/SerialDev/Mouse.HC.HTML new file mode 100755 index 0000000..8e58387 --- /dev/null +++ b/public/Wb/Kernel/SerialDev/Mouse.HC.HTML @@ -0,0 +1,398 @@ + + + + + + + + + + + +
+U0 GridInit()
+{//Init mouse grid struct. See ::/Demo/Graphics/Grid.HC.
+  ms_grid.x=ms_grid.y=ms_grid.z=8;
+  ms_grid.x_offset=ms_grid.y_offset=ms_grid.z_offset=0;
+  ms_grid.x_speed =ms_grid.y_speed =ms_grid.z_speed =1;
+  ms_grid.show=ms_grid.snap=ms_grid.coord=FALSE;
+}
+
+U0 MsUpdate(I64 x,I64 y,I64 z,Bool l,Bool r)
+{
+  ms.presnap.x=ToI64(ms.scale.x*x)+ms.offset.x;
+  ms.presnap.y=ToI64(ms.scale.y*y)+ms.offset.y;
+  ms.presnap.z=ToI64(ms.scale.z*z)+ms.offset.z;
+  if (ms_grid.snap) {
+    ms.pos.x=Trunc(ms.presnap.x/ms_grid.x)*ms_grid.x+ms_grid.x_offset;
+    ms.pos.y=Trunc(ms.presnap.y/ms_grid.y)*ms_grid.y+ms_grid.y_offset;
+    ms.pos.z=Trunc(ms.presnap.z/ms_grid.z)*ms_grid.z+ms_grid.z_offset;
+  } else {
+    ms.pos.x=ms.presnap.x;
+    ms.pos.y=ms.presnap.y;
+    ms.pos.z=ms.presnap.z;
+  }
+
+  ms.pos.x=ClampI64(ms.pos.x,0,GR_WIDTH-1);
+  ms.pos.y=ClampI64(ms.pos.y,0,GR_HEIGHT-1);
+  ms.pos_text.x=ms.pos.x/FONT_WIDTH;
+  if (ms.pos_text.x>=text.cols) {
+    ms.pos_text.x=text.cols-1;
+    ms.pos.x=text.cols*FONT_WIDTH-1;
+  }
+  ms.pos_text.y=ms.pos.y/FONT_HEIGHT;
+  if (ms.pos_text.y>=text.rows) {
+    ms.pos_text.y=text.rows-1;
+    ms.pos.y=text.rows*FONT_HEIGHT-1;
+  }
+  ms.lb=l;
+  ms.rb=r;
+  LBEqu(&kbd.scan_code,SCf_MS_L_DOWN,ms.lb);
+  LBEqu(&kbd.scan_code,SCf_MS_R_DOWN,ms.rb);
+}
+
+U0 MsSet(I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,I64 l=I64_MAX,I64 r=I64_MAX)
+{//Note: Generates a message. See MsSet().
+  if (!(0<=x<GR_WIDTH))
+    x=ms.pos.x;
+  if (!(0<=y<GR_HEIGHT))
+    y=ms.pos.y;
+  if (z==I64_MAX)
+    z=ms.pos.z;
+
+  if (!(FALSE<=l<=TRUE))
+    l=ms.lb;
+  if (!(FALSE<=r<=TRUE))
+    r=ms.rb;
+
+  x=(x-ms.offset.x)/ms.scale.x;
+  y=(y-ms.offset.y)/ms.scale.y;
+  z=(z-ms.offset.z)/ms.scale.z;
+  MsUpdate(x,y,z,l,r);
+  MsHardSet(x,y,z,l,r);
+}
+
+U0 MsInit()
+{
+  MemSet(&ms,0,sizeof(CMsStateGlbls));
+  MemSet(&ms_last,0,sizeof(CMsStateGlbls));
+  ms.offset.x=ms.offset.y=ms.offset.z=0;
+  ms.scale.x=ms.scale.y=ms.scale.z=1.0;
+  ms.pos_text.x=ms.pos_text.y=ms.pos_text.z=0;
+  ms.has_wheel=FALSE;
+  ms.show=TRUE;
+  ms.speed=0;
+  ms.timestamp=GetTSC;
+  ms.dbl_time=0.350;
+  GridInit;
+}
+
+U0 MsHardPktRead()
+{
+  U8 j;
+  if (GetTSC>ms_hard.timestamp+cnts.time_stamp_freq>>3)
+    FifoU8Flush(ms_hard.fifo);
+  ms_hard.timestamp=GetTSC;
+  FifoU8Ins(ms_hard.fifo,InU8(KBD_PORT));
+  if (FifoU8Cnt(ms_hard.fifo)==ms_hard.pkt_size)
+    while (FifoU8Rem(ms_hard.fifo,&j))
+      FifoU8Ins(ms_hard.fifo2,j);
+}
+
+interrupt U0 IRQMsHard()
+{
+  CLD
+  OutU8(0xA0,0x20);
+  OutU8(0x20,0x20);
+  ms_hard.irqs_working=TRUE;
+  if (ms_hard.install_in_progress || !ms_hard.installed) {
+    kbd.rst=TRUE;
+    return;
+  }
+  MsHardPktRead;
+}
+
+U0 MsHardGetType()
+{
+  I64 b;
+  KbdMsCmdAck(0xF2);
+  b=KbdCmdRead;
+  if (b==3)
+    ms_hard.has_wheel=TRUE;
+  else if (b==4)
+    ms_hard.has_ext_bttns=TRUE;
+}
+
+Bool MsHardRst()
+{
+  U8 b,*_b;
+  F64 timeout;
+  Bool res=FALSE;
+
+  ms_hard.has_wheel=FALSE;
+  ms_hard.has_ext_bttns=FALSE;
+
+  if (*0x40E(U16 *)==0x9FC0) {
+    _b=0x9FC00+0x30;
+    *_b=1; //This enables my mouse.  It might be for one machine.
+//USB DMA packets, set-up by BIOS to make legacy PS/2?
+  }
+
+  try {
+    KbdCmdFlush;
+    KbdCmdSend(KBD_CTRL,0xAD); //Disable Kbd
+    KbdCmdSend(KBD_CTRL,0xA8); //Enable Mouse
+
+    KbdMsCmdAck(0xFF); //Rst
+
+    timeout=tS+10.0;
+    do
+      try {
+        KbdCmdRead;
+        timeout=0; //force exit
+      } catch
+        Fs->catch_except=TRUE;
+    while (tS<timeout);
+
+    try
+            KbdCmdRead;
+    catch
+      Fs->catch_except=TRUE;
+
+    KbdMsCmdAck(0xF3,200,0xF3,100,0xF3,80);
+    MsHardGetType;
+    KbdMsCmdAck(0xF3,10);
+    MsHardGetType;
+    KbdMsCmdAck(0xE8,0x03,0xE6,0xF3,100,0xF4);
+    res=TRUE;
+
+    //Enable IRQ 12
+    KbdCmdSend(KBD_CTRL,0x20);
+    b=KbdCmdRead;
+    KbdCmdSend(KBD_CTRL,0x60);
+    KbdCmdSend(KBD_PORT,(b|2)&~0x20);
+
+  } catch
+    Fs->catch_except=TRUE;
+
+    //This is been added to override failure
+    //because the mouse sometimes still works.
+  res=TRUE;
+
+  try
+          KbdCmdSend(KBD_CTRL,0xAE); //Enable Keyboard
+  catch
+    Fs->catch_except=TRUE;
+  if (ms_hard.has_wheel || ms_hard.has_ext_bttns)
+    ms_hard.pkt_size=4;
+  else
+    ms_hard.pkt_size=3;
+  if (!res)
+    try
+            KbdCmdSend(KBD_CTRL,0xA7); //Disable Mouse
+    catch
+      Fs->catch_except=TRUE;
+  return res;
+}
+
+U0 MsHardSpeedSet()
+{
+  I64 dd,tmp;
+  if ((dd=SqrI64(ms_hard_last.pos.x-ms_hard.pos.x)
+        +SqrI64(ms_hard_last.pos.y-ms_hard.pos.y)) &&
+        (tmp=ms_hard.timestamp-ms_hard_last.timestamp))
+    ms_hard.speed=Sqrt(dd)*cnts.time_stamp_freq/tmp;
+  ms_hard_last.timestamp=ms_hard.timestamp;
+}
+
+U0 MsHardSetPre()
+{
+  I64 old_timestamp=ms_hard_last.timestamp;
+  MemCpy(&ms_hard_last,&ms_hard,sizeof(CMsHardStateGlbls));
+  ms_hard_last.timestamp=old_timestamp;
+}
+
+U0 MsHardSetPost()
+{
+  I64 i;
+  ms_hard.pos.x=ms_hard.prescale.x*ms_hard.scale.x*ms_grid.x_speed;
+  ms_hard.pos.y=ms_hard.prescale.y*ms_hard.scale.y*ms_grid.y_speed;
+  ms_hard.pos.z=ms_hard.prescale.z*ms_hard.scale.z*ms_grid.z_speed;
+
+  i=Trunc(ms.scale.x*ms_hard.pos.x/ms_grid.x)*ms_grid.x+ms.offset.x;
+//TODO ms_grid.x_offset?
+  if (i<0)
+    ms.offset.x-=i;
+  else if (i>=GR_WIDTH)
+    ms.offset.x+=GR_WIDTH-1-i;
+
+  i=Trunc(ms.scale.y*ms_hard.pos.y/ms_grid.y)*ms_grid.y+ms.offset.y;
+  if (i<0)
+    ms.offset.y-=i;
+  else if (i>=GR_HEIGHT)
+    ms.offset.y+=GR_HEIGHT-1-i;
+
+  if (ms_hard.pos.x!=ms_hard_last.pos.x || ms_hard.pos.y!=ms_hard_last.pos.y ||
+        ms_hard.pos.z!=ms_hard_last.pos.z) {
+    ms_hard.evt=TRUE;
+    MsHardSpeedSet;
+  } else
+    for (i=0;i<5;i++)
+      if (ms_hard.bttns[i]!=ms_hard_last.bttns[i]) {
+        ms_hard.evt=TRUE;
+        break;
+      }
+}
+
+U0 MsHardHndlr()
+{
+  I64 i,dx,dy,dz;
+  U8 ms_buf[4];
+
+  MsHardSetPre;
+  for (i=0;i<4;i++)
+    ms_buf[i]=0;
+  for (i=0;i<ms_hard.pkt_size;i++)
+    if (!FifoU8Rem(ms_hard.fifo2,&ms_buf[i]))
+      ms_buf[i]=0;
+
+  ms_hard.bttns[0] = ms_buf[0] & 1;
+  ms_hard.bttns[1] = (ms_buf[0] & 2) >> 1;
+  ms_hard.bttns[2] = (ms_buf[0] & 4) >> 2;
+  ms_hard.bttns[3] = (ms_buf[3] & 0x10) >> 4;
+  ms_hard.bttns[4] = (ms_buf[3] & 0x20) >> 5;
+  if (ms_buf[0] & 0x10)
+    dx=ms_buf[1]-256;
+  else
+    dx=ms_buf[1];
+  if (ms_buf[0] & 0x20)
+    dy=256-ms_buf[2];
+  else
+    dy=-ms_buf[2];
+  if (ms_buf[3] & 0x08)
+    dz=ms_buf[3]&7-8;
+  else
+    dz=ms_buf[3]&7;
+
+  ms_hard.prescale.x+=dx;
+  ms_hard.prescale.y+=dy;
+  ms_hard.prescale.z+=dz;
+
+  MsHardSetPost;
+}
+
+U0 MsHardSet(I64 x,I64 y,I64 z,I64 l,I64 r)
+{
+  ms_hard.timestamp=GetTSC;
+  MsHardSetPre;
+  ms_hard.prescale.x=x/ms_hard.scale.x/ms_grid.x_speed;
+  ms_hard.prescale.y=y/ms_hard.scale.y/ms_grid.y_speed;
+  ms_hard.prescale.z=z/ms_hard.scale.z/ms_grid.z_speed;
+  ms_hard.bttns[0]=l;
+  ms_hard.bttns[1]=r;
+  MsHardSetPost;
+}
+
+U0 KbdMsRst()
+{
+  KbdCmdFlush;
+  FifoU8Flush(kbd.fifo2);
+  FifoU8Flush(ms_hard.fifo2);
+  FifoI64Flush(kbd.scan_code_fifo);
+  kbd.scan_code=0;
+  kbd.rst=FALSE;
+}
+
+Bool MsHardDrvrInstall(I64 dummy=0) //can be spawned
+{
+  no_warn dummy;
+  I64 i;
+  ms_hard.install_in_progress=TRUE;
+  OutU8(0xA1,InU8(0xA1)|0x10);
+  ms_hard.installed=ms_hard.irqs_working=FALSE;
+  IntEntrySet(0x2C,&IRQMsHard);
+  for(i=0;i<5;i++)
+    ms_hard.bttns[i]=0;
+  if (i=MsHardRst)
+    OutU8(0xA1,InU8(0xA1)&~0x10);
+  KbdMsRst;
+  ms_hard.install_attempts++;
+  ms_hard.installed=ms_hard.evt=i;
+  ms_hard.install_in_progress=FALSE;
+  return ms_hard.installed;
+}
+
+U0 KbdMsHndlr(Bool poll_kbd,Bool poll_ms)
+{
+  if (ms_hard.install_in_progress) {
+    Yield;
+    return;
+  }
+  if (kbd.rst)
+    KbdMsRst;
+  else {
+    if (poll_ms && ms_hard.installed && !ms_hard.irqs_working) {
+      PUSHFD
+      CLI
+      while (InU8(KBD_CTRL)&1)
+        MsHardPktRead;
+      POPFD
+    }
+
+    if (poll_kbd)
+      while (InU8(KBD_CTRL)&1)
+        KbdPktRead;
+
+    if (kbd.rst)
+      KbdMsRst;
+    else {
+      while (FifoU8Cnt(kbd.fifo2))
+        KbdHndlr;
+      while (FifoU8Cnt(ms_hard.fifo2))
+        if (ms_hard.installed)
+          MsHardHndlr;
+        else
+          KbdMsRst;
+    }
+  }
+}
+
+U0 KbdMsInit()
+{
+  MemSet(&kbd,0,sizeof(CKbdStateGlbls));
+  kbd.fifo=FifoU8New(8);
+  kbd.fifo2=FifoU8New(0x1000);
+  kbd.scan_code_fifo=FifoI64New(0x1000);
+  kbd.irqs_working=FALSE;
+  MemSet(&ms_hard,0,sizeof(CMsHardStateGlbls));
+  ms_hard.fifo=FifoU8New(8);
+  ms_hard.fifo2=FifoU8New(0x1000);
+  ms_hard.scale.x=0.5;
+  ms_hard.scale.y=0.5;
+  ms_hard.scale.z=1.0;
+  ms_hard.prescale.x=GR_WIDTH/ms_hard.scale.x/2.0;
+  ms_hard.prescale.y=GR_HEIGHT/ms_hard.scale.y/2.0;
+  ms_hard.prescale.z=0/ms_hard.scale.z;
+  ms_hard.pos.x=GR_WIDTH>>1;
+  ms_hard.pos.y=GR_HEIGHT>>1;
+  MemCpy(&ms_hard_last,&ms_hard,sizeof(CMsHardStateGlbls));
+}
+
+ diff --git a/public/Wb/Kernel/StrA.HC.HTML b/public/Wb/Kernel/StrA.HC.HTML new file mode 100755 index 0000000..1b2de3d --- /dev/null +++ b/public/Wb/Kernel/StrA.HC.HTML @@ -0,0 +1,717 @@ + + + + + + + + + + + +
+U8 *StrPrintHex(U8 *dst,I64 num;I64 width)
+{
+  U8 *res=dst+width;
+  dst=res;
+  while (width--) {
+    *--dst="0123456789ABCDEF"(U8 *)[num&15];
+    num>>=4;
+  }
+  return res;
+}
+
+U0 PutHex(I64 num,I64 width)
+{
+  U8 buf[17];
+  if (width>16) width=16;
+  *StrPrintHex(buf,num,width)=0;
+  "%s",buf;
+}
+
+asm {
+// IN:  RAX=NUM TO PRINT
+PUT_HEX_U64::
+        PUSH_C_REGS
+        PUSH    16
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_HEX_U32::
+        PUSH_C_REGS
+        PUSH    8
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_HEX_U16::
+        PUSH_C_REGS
+        PUSH    4
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_HEX_U8::
+        PUSH_C_REGS
+        PUSH    2
+        PUSH    RAX
+        CALL    &PutHex
+        POP_C_REGS
+        RET
+PUT_CHARS::
+// IN:  RAX=Char
+        PUSH_C_REGS
+        PUSH    RAX
+        CALL    &PutChars
+        POP_C_REGS
+        RET
+PUT_STR::
+// IN:  RSI=String
+        PUSH_C_REGS
+        PUSH    RSI
+        CALL    &PutS
+        POP_C_REGS
+        RET
+_STRCPY::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RDI,U64 SF_ARG1[RBP]
+        TEST    RDI,RDI
+        JZ      @@15
+        MOV     RSI,U64 SF_ARG2[RBP]
+        TEST    RSI,RSI
+        JNZ     @@05
+        XOR     RAX,RAX
+        JMP     @@10
+@@05:   LODSB
+@@10:   STOSB
+        TEST    AL,AL
+        JNZ     @@05
+@@15:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_STRCMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   LODSB
+        TEST    AL,AL
+        JZ      @@20
+        SCASB
+        JE      @@05
+        JA      @@15
+@@10:   MOV     RAX,1
+        JMP     @@25
+@@15:   MOV     RAX,-1
+        JMP     @@25
+@@20:   SCASB
+        JNE     @@10
+        XOR     RAX,RAX
+@@25:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+TO_UPPER::
+        CMP     AL,'a'
+        JB      @@05
+        CMP     AL,'z'
+        JA      @@05
+        ADD     AL,'A'-'a'
+@@05:   RET
+_STRICMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   LODSB
+        TEST    AL,AL
+        JZ      @@30
+        CMP     AL,'a'
+        JB      @@10
+        CMP     AL,'z'
+        JA      @@10
+        ADD     AL,'A'-'a'
+@@10:   MOV     BL,U8 [RDI]
+        INC     RDI
+        CMP     BL,'a'
+        JB      @@15
+        CMP     BL,'z'
+        JA      @@15
+        ADD     BL,'A'-'a'
+@@15:   CMP     AL,BL
+        JE      @@05
+        JA      @@25
+@@20:   MOV     RAX,1
+        JMP     @@35
+@@25:   MOV     RAX,-1
+        JMP     @@35
+@@30:   MOV     BL,U8 [RDI]
+        TEST    BL,BL
+        JNE     @@20
+        XOR     RAX,RAX
+@@35:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_STRNCMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG3[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   TEST    RCX,RCX
+        JZ      @@25
+        DEC     RCX
+        LODSB
+        TEST    AL,AL
+        JZ      @@20
+        SCASB
+        JE      @@05
+        JA      @@15
+@@10:   MOV     RAX,1
+        JMP     @@30
+@@15:   MOV     RAX,-1
+        JMP     @@30
+@@20:   MOV     BL,U8 [RDI]
+        TEST    BL,BL
+        JNE     @@10
+@@25:   XOR     RAX,RAX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_STRNICMP::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RCX,U64 SF_ARG3[RBP]
+        MOV     RSI,U64 SF_ARG2[RBP]
+        MOV     RDI,U64 SF_ARG1[RBP]
+@@05:   TEST    RCX,RCX
+        JZ      @@35
+        DEC     RCX
+        LODSB
+        TEST    AL,AL
+        JZ      @@30
+        CMP     AL,'a'
+        JB      @@10
+        CMP     AL,'z'
+        JA      @@10
+        ADD     AL,'A'-'a'
+@@10:   MOV     BL,U8 [RDI]
+        INC     RDI
+        CMP     BL,'a'
+        JB      @@15
+        CMP     BL,'z'
+        JA      @@15
+        ADD     BL,'A'-'a'
+@@15:   CMP     AL,BL
+        JE      @@05
+        JA      @@25
+@@20:   MOV     RAX,1
+        JMP     @@40
+@@25:   MOV     RAX,-1
+        JMP     @@40
+@@30:   SCASB
+        JNE     @@20
+@@35:   XOR     RAX,RAX
+@@40:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    24
+_STRMATCH::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        TEST    RSI,RSI
+        JZ      @@25
+        MOV     RDI,U64 SF_ARG1[RBP]
+        TEST    RDI,RDI
+        JZ      @@25
+        MOV     DL,U8 [RDI]
+        TEST    DL,DL
+        JZ      @@20
+        JMP     @@10
+@@05:   INC     RSI
+@@10:   LODSB
+        TEST    AL,AL
+        JZ      @@25
+        CMP     AL,DL
+        JNE     @@10
+        DEC     RSI
+        MOV     RCX,1
+@@15:   MOV     AL,U8 [RDI+RCX]
+        TEST    AL,AL
+        JZ      @@20
+        CMP     AL,U8 [RSI+RCX]
+        JNE     @@05
+        INC     RCX
+        JMP     @@15
+
+        DEC     RSI
+@@20:   MOV     RAX,RSI
+        JMP     @@30
+@@25:   XOR     RAX,RAX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+_STRIMATCH::
+        PUSH    RBP
+        MOV     RBP,RSP
+        PUSH    RSI
+        PUSH    RDI
+        MOV     RSI,U64 SF_ARG2[RBP]
+        TEST    RSI,RSI
+        JZ      @@25
+        MOV     RDI,U64 SF_ARG1[RBP]
+        TEST    RDI,RDI
+        JZ      @@25
+        MOV     AL,U8 [RDI]
+        CALL    TO_UPPER
+        MOV     DL,AL
+        TEST    DL,DL
+        JZ      @@20
+        JMP     @@10
+@@05:   INC     RSI
+@@10:   LODSB
+        CALL    TO_UPPER
+        TEST    AL,AL
+        JZ      @@25
+        CMP     AL,DL
+        JNE     @@10
+        DEC     RSI
+        MOV     RCX,1
+@@15:   MOV     AL,U8 [RDI+RCX]
+        CALL    TO_UPPER
+        TEST    AL,AL
+        JZ      @@20
+        MOV     BL,U8 [RSI+RCX]
+        XCHG    AL,BL
+        CALL    TO_UPPER
+        CMP     AL,BL
+        JNE     @@05
+        INC     RCX
+        JMP     @@15
+
+        DEC     RSI
+@@20:   MOV     RAX,RSI
+        JMP     @@30
+@@25:   XOR     RAX,RAX
+@@30:   POP     RDI
+        POP     RSI
+        POP     RBP
+        RET1    16
+}
+_extern _STRCMP I64 StrCmp(
+        U8 *st1,U8 *st2); //Compare two strings.
+_extern _STRICMP I64 StrICmp(
+        U8 *st1,U8 *st2); //Compare two strings, ignoring case.
+_extern _STRNCMP I64 StrNCmp(
+        U8 *st1,U8 *st2,I64 n); //Compare N bytes in two strings.
+_extern _STRNICMP I64 StrNICmp(
+        U8 *st1,U8 *st2,I64 n); //Compare N bytes in two strings, ignoring case.
+_extern _STRMATCH U8 *StrMatch(
+        U8 *needle,U8 *haystack_str); //Scan for string in string.
+_extern _STRIMATCH U8 *StrIMatch(
+        U8 *needle,U8 *haystack_str);//Scan for string in string, ignoring case.
+_extern _STRCPY U0 StrCpy(
+        U8 *dst,U8 *src); //Copy string.
+
+//These bitmaps go to 0-511 so that Lex() can use them with Token Codes.
+U32
+  char_bmp_alpha[16]=
+  {0x0000000,0x00000000,0x87FFFFFF,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_alpha_numeric[16]=
+  {0x0000000,0x03FF0000,0x87FFFFFF,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_alpha_numeric_no_at[16]=
+  {0x0000000,0x03FF0000,0x87FFFFFE,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_word[16]=
+  {0x0000000,0x03FF0080,0x87FFFFFE,0x07FFFFFE,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_filename[16]=
+  {0x0000000,0x03FF73FB,0xEFFFFFFF,0x6FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_dec_numeric[16]=
+  {0x0000000,0x03FF0000,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_hex_numeric[16]=
+  {0x0000000,0x03FF0000,0x7E,0x7E,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_white_space[16]=
+  {0x80002600,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_non_eol_white_space[16]=
+  {0x80000200,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_zero_cr_nl_cursor[16]=
+  {0x00002421,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_zero_tab_cr_nl_cursor[16]=
+  {0x00002621,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_zero_tab_cr_nl_cursor_dollar[16]=
+  {0x00002621,0x10,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+
+  char_bmp_macro[16]=
+  {0x80002600,0xFFFFFFDF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_printable[16]=
+  {0x80002600,0xFFFFFFFF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_displayable[16]=
+  {0x80000000,0xFFFFFFFF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},
+
+  char_bmp_safe_dollar[16]=
+  {0x80000000,0xFFFFFFEF,0xFFFFFFFF,0x7FFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0,0,0,0,0,0,0,0},//same but no dollar sign
+
+  char_bmp_non_eol[16]=
+  {0xFFFFDBFE,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
+  0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
+
+U8 *LstSub(I64 sub, U8 *lst)
+{//Point to lst entry.
+//Not efficient.  Use an array of U8 ptrs for efficiency.
+  if (!lst) return NULL;
+  while (*lst && sub>0) {
+    while (*lst)        //Advance to end of cur entry.
+      lst++;
+    lst++;              //Skip trailing zero.
+    if (*lst=='@')      //Check for '@' alias lst entry.
+      lst++;
+    else
+      sub--;
+  }
+  if (sub||!*lst)
+    return NULL;
+  else
+    return lst;
+}
+
+I64 LstMatch(U8 *needle, U8 *haystack_lst,I64 flags=0)
+{//-2 if Ambiguous
+// -1 if not found
+  // Not efficient. Use hash tables for efficiency.
+  I64 n,sub=0,res=-1;
+  U8 *ptr;
+  Bool exact_match=FALSE;
+  if (!haystack_lst) return -1;
+  n=StrLen(needle);
+  while (*haystack_lst) {
+    if (*haystack_lst=='@') {   //Check for '@' alias haystack_lst entry
+      sub--;
+      haystack_lst++;
+    }
+    ptr=needle;
+    if (flags & LMF_IGNORE_CASE)
+      while (*ptr && ToUpper(*ptr)==ToUpper(*haystack_lst)) {
+        ptr++;
+        haystack_lst++;
+      }
+    else
+      while (*ptr && *ptr==*haystack_lst) {
+        ptr++;
+        haystack_lst++;
+      }
+    if (!*ptr) {                //Did we reach end of needle?
+      if (!*haystack_lst)       //Did we reach end of haystack_lst?
+        return sub;             //Found Exact match
+      else {
+        if (res!=-1) {
+          if (!exact_match)
+            res=-2;             //Ambiguous unless later exact match.
+        } else {
+          if (!(flags & LMF_EXACT))
+            res=sub;
+        }
+      }
+    }
+    while (*haystack_lst)       //Advance to end of cur entry.
+      haystack_lst++;
+    haystack_lst++;             //Skip trailing zero
+    sub++;
+  }
+  return res;
+}
+
+I64 StrOcc(U8 *src, I64 ch)
+{//Count occurrences of a char.
+  I64 i=0;
+  if (!src) return 0;
+  while (*src)
+    if (*src++==ch)
+      i++;
+  return i;
+}
+
+I64 Spaces2Tabs(U8 *dst,U8 *src)
+{//Src buf with spaces to dst buf without.
+  U8 *src2;
+  I64 chged=0,space_cnt,space_cnt2,col=0;
+  if (*src)
+    while (TRUE) {
+      src2=src;
+      while (*src2==CH_SPACE)
+        src2++;
+      space_cnt=src2-src;
+      while (col+space_cnt>=8) {
+        space_cnt2=8-col;
+        if (space_cnt2==1)
+          *dst++=CH_SPACE;
+        else {
+          *dst++='\t';
+          chged+=space_cnt2-1;
+        }
+        space_cnt-=space_cnt2;
+        col=0;
+      }
+      if (*src2=='\t') {
+        if (space_cnt==1 && col==7)
+          *dst++=CH_SPACE;
+        else
+          chged+=space_cnt;
+        *dst++='\t';
+        col=0;
+      } else {
+        while (space_cnt--) {
+          *dst++=CH_SPACE;
+          if (++col==8)
+            col=0;
+        }
+        if (*src2) {
+          *dst++=*src2;
+          if (++col==8)
+            col=0;
+        } else
+          break;
+      }
+      src=++src2;
+    }
+  *dst=0;
+  return chged;
+}
+
+U8 *StrUtil(U8 *_src,I64 flags)
+{//Modifies in place. See flags for all the options.
+  U8 *src=_src,*dst=_src;
+  I64 ch;
+
+  if (flags & SUF_REM_LEADING)
+    while (Bt(char_bmp_white_space,*src))
+      src++;
+  while (ch=*src++)
+    if (Bt(char_bmp_white_space,ch)) {
+      if (!(flags & SUF_REM_SPACES)) {
+        if (flags & SUF_SINGLE_SPACE) {
+          *dst++ = CH_SPACE;
+          while ((ch=*src++) && Bt(char_bmp_white_space,ch));
+          src--;
+        } else
+          *dst++ = ch;
+      }
+    } else if (!(flags & SUF_REM_CTRL_CHARS) || ch>=CH_SHIFT_SPACE)
+      *dst++=ch;
+  *dst=0;
+
+  if (flags & SUF_REM_TRAILING)
+    while (dst!=_src && (!*dst || Bt(char_bmp_white_space,*dst)))
+      *dst-- =0;
+  if (flags & SUF_TO_UPPER)
+    for (dst=_src;*dst;dst++) {
+      ch=*dst;
+      if ('a'<=ch<='z')
+        *dst=ch-0x20;
+    }
+  if (flags & SUF_TO_LOWER)
+    for (dst=_src;*dst;dst++) {
+      ch=*dst;
+      if ('A'<=ch<='Z')
+        *dst=ch+0x20;
+    }
+  if (flags & SUF_SAFE_DOLLAR)
+    for (dst=_src;*dst;dst++) {
+      ch=*dst;
+      if (!Bt(char_bmp_safe_dollar,*dst))
+        *dst='.';
+    }
+  if (flags & SUF_S2T)
+    Spaces2Tabs(_src,_src);
+  return _src;
+}
+
+U8 *StrFirstOcc(U8 *src,U8 *marker)
+{//Point to 1st occurrence of marker set in str.
+  I64 ch;
+  while ((ch=*src++) && !StrOcc(marker,ch));
+  if (ch)
+    return src-1;
+  else
+    return NULL;
+}
+
+U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL)
+{//Remove first str segment and place in dst buf or NULL.
+  I64 ch;
+  U8 *ptr=src,*res=dst;
+  if (dst) {
+    while ((ch=*ptr++) && !StrOcc(marker,ch))
+      *dst++=ch;
+    *dst=0;
+  } else
+    while ((ch=*ptr++) && !StrOcc(marker,ch));
+  if (ch)
+    StrCpy(src,ptr);
+  else
+    *src=0;
+  return res;
+}
+
+U8 *StrLastOcc(U8 *src,U8 *marker)
+{//Point to last occurrence of market set in str.
+  I64 ch;
+  U8 *res=NULL;
+  while (ch=*src++)
+    if (StrOcc(marker,ch))
+      res=src-1;
+  return res;
+}
+
+U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL)
+{//Remove last str segment and place in dst buf or NULL.
+  U8 *ptr;
+  if (ptr=StrLastOcc(src,marker)) {
+    if (dst)
+      StrCpy(dst,ptr+1);
+    *ptr=0;
+  } else {
+    if (dst)
+      StrCpy(dst,src);
+    *src=0;
+  }
+  return dst;
+}
+
+U8 *StrFind(U8 *needle,U8 *haystack_str,I64 flags=0)
+{//Find needle_str in haystack_str with options.
+  Bool cont;
+  U8 *saved_haystack_str=haystack_str;
+  I64 plen=StrLen(needle);
+  do {
+    cont=FALSE;
+    if (flags & SFF_IGNORE_CASE)
+      haystack_str=StrIMatch(needle,haystack_str);
+    else
+      haystack_str=StrMatch(needle,haystack_str);
+    if (haystack_str && flags & SFF_WHOLE_LABELS_BEFORE &&
+          haystack_str!=saved_haystack_str &&
+          Bt(char_bmp_alpha_numeric,*(haystack_str-1))) {
+      haystack_str++;
+      if (*haystack_str)
+        cont=TRUE;
+      else
+        haystack_str=NULL;
+    }
+    if (haystack_str && flags & SFF_WHOLE_LABELS_AFTER &&
+          Bt(char_bmp_alpha_numeric,*(haystack_str+plen))) {
+      haystack_str++;
+      if (*haystack_str)
+        cont=TRUE;
+      else
+        haystack_str=NULL;
+    }
+  } while (cont);
+  return haystack_str;
+}
+
+Bool WildMatch(U8 *test_str,U8 *wild_str)
+{//Wildcard match with '*' and '?'.
+  I64 ch1,ch2;
+  U8 *fall_back_src=NULL,*fall_back_wild=NULL;
+  while (TRUE) {
+    if (!(ch1=*test_str++)) {
+      if (*wild_str && *wild_str!='*')
+        return FALSE;
+      else
+        return TRUE;
+    } else {
+      if (!(ch2=*wild_str++))
+        return FALSE;
+      else {
+        if (ch2=='*') {
+          fall_back_wild=wild_str-1;
+          fall_back_src=test_str;
+          if (!(ch2=*wild_str++))
+            return TRUE;
+          while (ch2!=ch1)
+            if (!(ch1=*test_str++))
+              return FALSE;
+        } else
+          if (ch2!='?' && ch1!=ch2) {
+            if (fall_back_wild) {
+              wild_str=fall_back_wild;
+              test_str=fall_back_src;
+              fall_back_wild=NULL;
+              fall_back_src=NULL;
+            } else
+              return FALSE;
+          }
+      }
+    }
+  }
+}
+
+ diff --git a/public/Wb/Kernel/StrB.HC.HTML b/public/Wb/Kernel/StrB.HC.HTML new file mode 100755 index 0000000..af2123f --- /dev/null +++ b/public/Wb/Kernel/StrB.HC.HTML @@ -0,0 +1,218 @@ + + + + + + + + + + + +
+U8 *Tabs2Spaces(U8 *src)
+{//MAlloc str with tabs to spaces.
+  I64 ch,i,j,l=StrLen(src)<<1+2,col=0;
+  U8 *dst=MAlloc(l),*tmp;
+  while (ch=*src++) {
+    if (ch=='\t') {
+      j=(col+8) & ~7;
+      for (i=col;i<j;i++) {
+        dst[i]=CH_SPACE;
+        if (i>=l-2) {
+          tmp=MAlloc(l<<1);
+          MemCpy(tmp,dst,i+1);
+          Free(dst);
+          l<<=1;
+          dst=tmp;
+        }
+      }
+      col=j;
+    } else {
+      dst[col]=ch;
+      if (col>=l-2) {
+        tmp=MAlloc(l<<1);
+        MemCpy(tmp,dst,col+1);
+        Free(dst);
+        l<<=1;
+        dst=tmp;
+      }
+      col++;
+    }
+  }
+  dst[col]=0;
+  return dst;
+}
+
+U8 *ScaleIndent(U8 *src,F64 indent_scale_factor)
+{//MAlloced str.  8*0.25-->2 or 8*2.0-->16
+  I64 ch,i,col=0;
+  U8 *dst,*dst2;
+  while (ch=*src++) {
+    if (ch=='\t')
+      col=(col+8) & -0x8;
+    else if (ch==CH_SPACE)
+      col++;
+    else
+      break;
+  }
+  src--;
+  col=Round(indent_scale_factor*col);
+  dst=dst2=MAlloc(StrLen(src)+col/8+col&7+1);
+  for (i=col/8;i>0;i--)
+    *dst2++='\t';
+  for (i=col&7;i>0;i--)
+    *dst2++=CH_SPACE;
+  StrCpy(dst2,src);
+  return dst;
+}
+
+U8 *MStrUtil(U8 *src,I64 flags,F64 indent_scale_factor=0)
+{//MAlloc StrUtil().
+  U8 *dst=StrNew(src),*dst2,*tmp;
+  StrUtil(dst,flags);
+  if (flags & SUF_T2S) {
+    tmp=Tabs2Spaces(dst);
+    Free(dst);
+    dst=tmp;
+  }
+  if (flags & SUF_SCALE_INDENT)
+    dst2=ScaleIndent(dst,indent_scale_factor);
+  else
+    dst2=StrNew(dst); //Shorten to just right size.
+  Free(dst);
+  return dst2;
+}
+
+U0 GetOutOfDollar()
+{//If a $ has been printed, print another $ to exit mode.
+  CDoc *doc;
+  if (IsRaw) {
+    if (text.raw_flags&RWF_IN_DOLLAR)
+      '$';
+  } else {
+    if (fp_doc_put && (doc=(*fp_doc_put)(Fs)) && doc->flags&DOCF_IN_DOLLAR)
+      '$';
+  }
+}
+
+Bool YorN()
+{//Wait for user to answer Y or N.
+  I64 ch;
+  "(y or n)? ";
+  while (TRUE) {
+    ch=ToUpper(GetChar(,FALSE));
+    if (ch=='Y') {
+      "$PT$YES$FG$\n";
+      return TRUE;
+    } else if (ch=='N') {
+      "$PT$NO$FG$\n";
+      return FALSE;
+    }
+  }
+}
+
+I64 PressAKey()
+{//Print "Press a key" and wait for non-zero ASCII key.
+  "$BK,1$PRESS A KEY$BK,0$\n";
+  return GetChar(,FALSE);
+}
+
+Bool AreYouSure()
+{//Print "Are you sure" and waits for Y or N.
+  "ARE YOU SURE ";
+  return YorN;
+}
+
+U0 Help()
+{//Dbg help or master help index file.
+  if (IsDbgMode)
+    DbgHelp;
+  else
+    PopUp("Type(\"::/Doc/HelpIndex.DD\");DocTop;View;");
+}
+
+U0 ScanFlags(U8 *_dst_flags,U8 *lst,U8 *src)
+{/*More than 64 flags. Flags passed by ref.
+
+Examples:
+ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
+
+I64 flags=0;
+ScanFlags(&flags,"R\0L\0Dump\0Scan\0","+Dump-R"); //Sets Bit#2, Clears Bit#0.
+*/
+  I64 i;
+  U8 *buf,*ptr;
+  if (src) {
+    buf=MAlloc(StrLen(src)+1);
+    while (*src) {
+      while (*src && *src!='+' && *src!='-')
+        src++;
+      if (*src=='+') {
+        src++;
+        if (*src) {
+          ptr=buf;
+          while (*src && *src!='+' && *src!='-' &&
+                *src!=CH_SPACE && *src!=CH_SHIFT_SPACE)
+            *ptr++=*src++;
+          *ptr=0;
+          i=LstMatch(buf,lst);
+          if (i>=0)
+            LBts(_dst_flags,i);
+          else {
+            Free(buf);
+            throw('ScanFlag');
+          }
+        }
+      } else if (*src=='-') {
+        src++;
+        if (*src) {
+          ptr=buf;
+          while (*src && *src!='+' && *src!='-' &&
+                *src!=CH_SPACE && *src!=CH_SHIFT_SPACE)
+            *ptr++=*src++;
+          *ptr=0;
+          i=LstMatch(buf,lst);
+          if (i>=0)
+            LBtr(_dst_flags,i);
+          else {
+            Free(buf);
+            throw('ScanFlag');
+          }
+        }
+      }
+    }
+    Free(buf);
+  }
+}
+
+U8 *StrPrintFlags(U8 *dst,U8 *lst,I64 flags)
+{//Only 64 flags. Flags passed by value.
+  I64 i;
+  *dst=0;
+  while (flags) {
+    i=Bsf(flags);
+    Btr(&flags,i);
+    CatPrint(dst,"+%z",i,lst);
+  }
+  return dst;
+}
+
+ diff --git a/public/Wb/Kernel/StrPrint.HC.HTML b/public/Wb/Kernel/StrPrint.HC.HTML new file mode 100755 index 0000000..e196895 --- /dev/null +++ b/public/Wb/Kernel/StrPrint.HC.HTML @@ -0,0 +1,951 @@ + + + + + + + + + + + +
+U0 SPutChar(U8 **_dst,U8 ch,U8 **_buf)
+{
+  I64 i;
+  U8 *dst=*_dst,*buf;
+  if (_buf) {
+    buf=*_buf;
+    i=dst-buf;
+    if (i>=MSize(buf)) {
+      buf=MAlloc(i<<1+1);
+      MemCpy(buf,*_buf,i);
+      Free(*_buf);
+      dst=buf+i;
+      *_buf=buf;
+    }
+  }
+  *dst++=ch;
+  *_dst=dst;
+}
+
+U0 OutStr(U8 *ptr,U8 **_buf,U8 **_dst,I64 len,I64 flags)
+{
+  I64 i,j;
+  if (!ptr)
+    i=0;
+  else
+    i=StrLen(ptr);
+  if (flags&PRTF_TRUNCATE && i>len)
+    i=len;
+  if (flags&PRTF_LEFT_JUSTIFY) {
+    for (j=0;j<i;j++)
+      SPutChar(_dst,*ptr++,_buf);
+    for (j=0;j<len-i;j++)
+      SPutChar(_dst,CH_SPACE,_buf);
+  } else {
+    for (j=0;j<len-i;j++)
+      SPutChar(_dst,CH_SPACE,_buf);
+    for (j=len-i;j<len;j++)
+      SPutChar(_dst,*ptr++,_buf);
+  }
+}
+
+U8 *MPrintTime(CDate cdt)
+{
+  CDateStruct ds;
+  Date2Struct(&ds,cdt+local_time_offset);
+  return MStrPrint("%02d:%02d:%02d",ds.hour,ds.min,ds.sec);
+}
+
+U8 *MPrintDate(CDate cdt)
+{
+  CDateStruct ds;
+  Date2Struct(&ds,cdt+local_time_offset);
+  return MStrPrint("%02d/%02d/%02d",ds.mon,ds.day_of_mon,ds.year%100);
+}
+
+U8 *MPrintQ(U8 *ptr,I64 flags)
+{
+  U8 **_buf,*buf,**_dst,*dst,buf2[8],*ptr2;
+  I64 ch;
+  buf=MAlloc(STR_LEN);
+  _buf=&buf;
+  dst=buf;
+  _dst=&dst;
+  if (ptr)
+    while (ch=*ptr++) {
+      switch (ch) {
+        case '$':
+          if (flags&PRTF_DOLLAR) {
+            SPutChar(_dst,'\\',_buf);
+            SPutChar(_dst,'d',_buf);
+          } else {
+            SPutChar(_dst,ch,_buf);
+            SPutChar(_dst,ch,_buf);
+          }
+          break;
+        case '%':
+          SPutChar(_dst,ch,_buf);
+          if (flags&PRTF_SLASH)
+            SPutChar(_dst,ch,_buf);
+          break;
+        case '\n':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,'n',_buf);
+          break;
+        case '\r':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,'r',_buf);
+          break;
+        case '\t':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,'t',_buf);
+          break;
+        case '"':
+        case '\\':
+          SPutChar(_dst,'\\',_buf);
+          SPutChar(_dst,ch,_buf);
+          break;
+        default:
+          if (ch>=CH_SHIFT_SPACE && ch!=0x7F)
+            SPutChar(_dst,ch,_buf);
+          else {
+            StrPrint(buf2,"\\x%02X",ch);
+            ptr2=buf2;
+            while (*ptr2)
+              SPutChar(_dst,*ptr2++,_buf);
+          }
+      }
+    }
+  SPutChar(_dst,0,_buf);
+  return buf;
+}
+
+U8 *MPrintq(U8 *ptr,I64 flags)
+{
+  U8 **_buf,*buf,**_dst,*dst;
+  I64 i,j,ch,ch1;
+  buf=MAlloc(STR_LEN);
+  _buf=&buf;
+  dst=buf;
+  _dst=&dst;
+  if (ptr)
+    while (ch=*ptr++) {
+      ch1=*ptr;
+      switch (ch) {
+        case '\\':
+          switch (ch1) {
+            start:
+              case '0':
+                SPutChar(_dst,0,_buf);
+                break;
+              case '\'':
+                SPutChar(_dst,'\'',_buf);
+                break;
+              case '\`':
+                SPutChar(_dst,'\`',_buf);
+                break;
+              case '"':
+                SPutChar(_dst,'"',_buf);
+                break;
+              case '\\':
+                SPutChar(_dst,'\\',_buf);
+                break;
+              case 'd':
+                SPutChar(_dst,'$',_buf);
+                break;
+              case 'n':
+                SPutChar(_dst,'\n',_buf);
+                break;
+              case 'r':
+                SPutChar(_dst,'\r',_buf);
+                break;
+              case 't':
+                SPutChar(_dst,'\t',_buf);
+                break;
+            end:
+              ptr++;
+              break;
+
+            case 'x':
+            case 'X':
+              i=0;
+              ptr++;
+              for (j=0;j<2;j++) {
+                ch1=ToUpper(*ptr++);
+                if (Bt(char_bmp_hex_numeric,ch1)) {
+                  if (ch1<='9')
+                    i=i<<4+ch1-'0';
+                  else
+                    i=i<<4+ch1-'A'+10;
+                } else {
+                  ptr--;
+                  break;
+                }
+              }
+              SPutChar(_dst,i,_buf);
+              break;
+
+            default:
+              SPutChar(_dst,ch,_buf);
+          }
+          break;
+        case '$':
+          SPutChar(_dst,ch,_buf);
+          if (ch1=='$')
+            ptr++;
+          break;
+        case '%':
+          SPutChar(_dst,ch,_buf);
+          if (flags&PRTF_SLASH && ch1=='%')
+            ptr++;
+          break;
+        default:
+          SPutChar(_dst,ch,_buf);
+      }
+    }
+  SPutChar(_dst,0,_buf);
+  return buf;
+}
+
+U8 *sys_pos_pows_lets=" KMGTPEZY",
+   *sys_neg_pows_lets=" munpfazy",
+   *sys_pos_pows_lst="kilo\0mega\0giga\0tera\0peta\0exa\0zetta\0yotta\0",
+   *sys_neg_pows_lst="milli\0micro\0nano\0pico\0femto\0atto\0zepto\0yocto\0";
+
+#define TMP_BUF_LEN     256
+#define SLOP            8
+
+U8 *StrPrintJoin(U8 *dst,U8 *fmt,I64 argc,I64 *argv)
+{/*Print("") Fmt Strings
+In float formatting, do not exceed 18-digits
+before or after the decimal point
+because the numbers before and after
+the decimal point are stored
+in 64-bits.  Use exponentiated forms
+to avoid this.
+*/
+  I64 i,j,l,ch,k,k0,n,n0,len,dec_len,flags,old_flags,
+        aux_fmt_num,comma_cnt,comma_fmt_cnt,cur_arg=0;
+  U64 m;
+  F64 d,d1;
+  CDoc *doc;
+  U8 *ptr,**_buf,*buf,**_dst,tmp_buf[TMP_BUF_LEN],tmp_buf2[TMP_BUF_LEN*2];
+
+  if (!fmt)
+    throw('StrPrint');
+  if (dst) {
+    _buf=NULL;
+    buf=dst;
+  } else {
+    buf=MAlloc(STR_LEN);
+    _buf=&buf;
+    dst=buf;
+  }
+  _dst=&dst;
+
+  while (ch = *fmt++) {
+    if (ch=='%') {
+      flags=0;
+      if (*fmt=='-') {
+        flags|=PRTF_LEFT_JUSTIFY;
+        fmt++;
+      }
+      if (*fmt=='0') {
+        flags|=PRTF_PAD_ZERO;
+        fmt++;
+      }
+      len=0;
+      while ('0'<=*fmt<='9')
+        len=len*10+ *fmt++ -'0';
+      if (*fmt=='*') {
+        fmt++;
+        if (cur_arg>=argc)
+          throw('StrPrint');
+        len=argv[cur_arg++];
+      }
+      dec_len=0;
+      if (*fmt=='.') {
+        fmt++;
+        while ('0'<=*fmt<='9')
+          dec_len=dec_len*10+ *fmt++ -'0';
+        if (*fmt=='*') {
+          fmt++;
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          dec_len=argv[cur_arg++];
+        }
+        flags|=PRTF_DECIMAL;
+      }
+
+      aux_fmt_num=0;
+      while (TRUE) {
+        switch (*fmt) {
+          start:
+            case '$':
+              flags|=PRTF_DOLLAR;
+              break;
+            case '/':
+              flags|=PRTF_SLASH;
+              break;
+            case ',':
+              flags|=PRTF_COMMA;
+              break;
+            case 't':
+              flags|=PRTF_TRUNCATE;
+              break;
+            case 'l': //harmless
+              break;
+          end:
+            fmt++;
+            break;
+
+          case 'h':
+            fmt++;
+            flags|=PRTF_AUX_FMT_NUM;
+            if (*fmt=='?') {
+              fmt++;
+              flags|=PRTF_QUESTION;
+            } else {
+              if (*fmt=='*') {
+                fmt++;
+                if (cur_arg>=argc)
+                  throw('StrPrint');
+                aux_fmt_num=argv[cur_arg++];
+              } else {
+                if (*fmt=='-') {
+                  fmt++;
+                  flags|=PRTF_NEG_AUX_FMT_NUM;
+                }
+                while ('0'<=*fmt<='9')
+                  aux_fmt_num=aux_fmt_num*10+ *fmt++ -'0';
+                if (flags&PRTF_NEG_AUX_FMT_NUM)
+                  aux_fmt_num=-aux_fmt_num;
+              }
+            }
+            break;
+          default:
+            goto sp_arg;
+        }
+      }
+
+      sp_arg:
+      k=0;
+      switch (*fmt++) {
+        start:
+          case 'F':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            if (flags&PRTF_DOLLAR) {
+              doc=argv[cur_arg++];
+              old_flags=doc->flags;
+              doc->flags|=DOCF_NO_CURSOR;
+              ptr=DocSave(doc);
+              doc->flags=old_flags;
+            } else
+              ptr=FileRead(argv[cur_arg++]);
+            break;
+          case 'Q':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintQ(argv[cur_arg++],flags);
+            break;
+          case 'q':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintq(argv[cur_arg++],flags);
+            break;
+          case 'D':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintDate(argv[cur_arg++]);
+            break;
+          case 'T':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=MPrintTime(argv[cur_arg++]);
+            break;
+        end:
+          OutStr(ptr,_buf,_dst,len,flags);
+          Free(ptr);
+          break;
+
+        start:
+          case 's':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=argv[cur_arg++];
+            break;
+          case 'S':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            ptr=Define(argv[cur_arg++]);
+            break;
+          case 'z':
+            if (cur_arg+1>=argc)
+              throw('StrPrint');
+            ptr=LstSub(argv[cur_arg],argv[cur_arg+1]);
+            cur_arg=cur_arg+2;
+            break;
+          case 'Z':
+            if (cur_arg+1>=argc)
+              throw('StrPrint');
+            ptr=DefineSub(argv[cur_arg],argv[cur_arg+1]);
+            cur_arg=cur_arg+2;
+            break;
+        end:
+          OutStr(ptr,_buf,_dst,len,flags);
+          break;
+
+        start:
+          case 'c':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            tmp_buf[0](I64)=argv[cur_arg++];
+            tmp_buf[8]=0;
+            break;
+          case 'C':
+            if (cur_arg>=argc)
+              throw('StrPrint');
+            tmp_buf[0](I64)=argv[cur_arg++];
+            tmp_buf[8]=0;
+            ptr=tmp_buf;
+            while (*ptr) {
+              *ptr=ToUpper(*ptr);
+              ptr++;
+            }
+            break;
+        end:
+          if (!(flags&PRTF_AUX_FMT_NUM))
+            aux_fmt_num=1;
+          while (aux_fmt_num-->0)
+            OutStr(tmp_buf,_buf,_dst,len,flags);
+          break;
+
+        case 'p':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          StrPrintFunSeg(tmp_buf,argv[cur_arg++],len,flags);
+          OutStr(tmp_buf,_buf,_dst,len,flags);
+          break;
+        case 'P':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          StrPrintFunSeg(tmp_buf,argv[cur_arg],len,flags);
+          if (!IsRaw || !_buf) {
+            StrPrint(tmp_buf2,"$LK,\"%s\",A=\"AD:0x%X\"$",
+                  tmp_buf,argv[cur_arg]);
+            OutStr(tmp_buf2,_buf,_dst,len,flags);
+          } else
+            OutStr(tmp_buf,_buf,_dst,len,flags);
+          cur_arg++;
+          break;
+        case 'd':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (m(I64)<0) {
+            flags|=PRTF_NEG;
+            m=-m;
+          }
+sp_out_dec:
+          if (flags&PRTF_AUX_FMT_NUM) {
+            if (!len) len=12;
+            d=m;
+            goto sp_out_eng;
+          }
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=3;
+            do {
+              tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=3;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+sp_out_comma_num:
+            if (flags&PRTF_NEG)
+              i=1;
+            else
+              i=0;
+            if (len<0)
+              len=0;
+            if (flags&PRTF_TRUNCATE && k+i>len)
+              k=len-i;
+            if (k<0)
+              k=0;
+            if (flags&PRTF_PAD_ZERO) {
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+              comma_cnt=(len-k-i+comma_fmt_cnt-comma_cnt+1)
+              %(comma_fmt_cnt+1)+1;
+              for (;i<len-k;i++) {
+                if (!--comma_cnt) {
+                  SPutChar(_dst,',',_buf);
+                  comma_cnt=comma_fmt_cnt;
+                  if (++i>=len-k)
+                    break;
+                }
+                SPutChar(_dst,'0',_buf);
+              }
+            } else {
+              for (;i<len-k;i++)
+                SPutChar(_dst,CH_SPACE,_buf);
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+            }
+          } else {
+            do {
+              tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+            } while (k<TMP_BUF_LEN-SLOP);
+sp_out_num:
+            if (flags&PRTF_NEG)
+              i=1;
+            else
+              i=0;
+            if (len<0)
+              len=0;
+            if (flags&PRTF_TRUNCATE && k+i>len)
+              k=len-i;
+            if (k<0)
+              k=0;
+            if (flags&PRTF_PAD_ZERO) {
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+              for (;i<len-k;i++)
+                SPutChar(_dst,'0',_buf);
+            } else {
+              for (;i<len-k;i++)
+                SPutChar(_dst,CH_SPACE,_buf);
+              if (flags&PRTF_NEG)
+                SPutChar(_dst,'-',_buf);
+            }
+          }
+          for (i=k-1;i>=0;i--)
+            SPutChar(_dst,tmp_buf[i],_buf);
+          break;
+        case 'u':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          goto sp_out_dec;
+        case 'f':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+
+          if (d==inf) {
+sp_out_inf:
+            if (flags&PRTF_NEG)
+              i=1;
+            else
+              i=0;
+            k=1;
+            if (len<0)
+              len=0;
+            if (flags&PRTF_TRUNCATE && k+i>len)
+              k=len-i;
+            if (k<0)
+              k=0;
+            for (;i<len-k;i++)
+              SPutChar(_dst,CH_SPACE,_buf);
+            if (flags&PRTF_NEG)
+              SPutChar(_dst,'-',_buf);
+            for (i=0;i<k;i++)
+              SPutChar(_dst,'inf',_buf);
+            break;
+          }
+
+          sp_out_f:
+          if (dec_len<0)
+            dec_len=0;
+          n=Log10(d);
+          if (i=dec_len) {
+            if (flags&PRTF_COMMA)
+              i=i-i/4;
+            if (n+i>17) {
+              n+=i-17;
+              d*=Pow10I64(i-n);
+            } else {
+              n=0;
+              d*=Pow10I64(i);
+            }
+            i=dec_len;
+          } else if (n>17) {
+            n-=17;
+            d*=Pow10I64(-n);
+          } else
+            n=0;
+
+          m=Round(d);
+          if (flags&PRTF_COMMA) {
+            comma_cnt=i&3;
+            while (i-- && k<TMP_BUF_LEN-SLOP) {
+              if (i>2 && !comma_cnt--) {
+                tmp_buf[k++]=',';
+                comma_cnt=2;
+                if (!--i) break;
+              }
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!i) break;
+            }
+          } else {
+            while (i-- && k<TMP_BUF_LEN-SLOP) {
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+            }
+          }
+          if (dec_len)
+            tmp_buf[k++]='.';
+          if (flags&PRTF_COMMA) {
+            comma_cnt=3;
+            do {
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=3;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+          } else {
+            do {
+              if (n) {
+                n--;
+                tmp_buf[k++]='0';
+              } else
+                tmp_buf[k++]=ModU64(&m,10)+'0';
+              if (!m) break;
+            } while (k<TMP_BUF_LEN-SLOP);
+          }
+          goto sp_out_num;
+        case 'e':
+          if (!len) len=12;
+          flags|=PRTF_TRUNCATE;
+
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+          if (d==inf) goto sp_out_inf;
+
+          if (d)
+            n=Floor(Log10(d));
+          else
+            n=0;
+sp_out_e:
+          d/=Pow10I64(n);
+
+          k0=k;
+          for (l=0;l<2;l++) {
+            n0=n;
+            if (n<0) {
+              n=-n;
+              flags|=PRTF_NEG_E;
+            } else
+              flags&=~PRTF_NEG_E;
+
+            i=3;
+            do tmp_buf[k++]=ModU64(&n,10)+'0';
+            while (n && i--);
+            if (flags&PRTF_NEG_E)
+              tmp_buf[k++]='-';
+            tmp_buf[k++]='e';
+            dec_len=len-k-2;
+            if (flags&PRTF_NEG)
+              dec_len--;
+
+            if (d) {
+              d1=d+Pow10I64(-dec_len)/2;
+              if (d1<1.0) {
+                d*=10;
+                n=n0-1;
+                k=k0;
+              } else if (d1>=10) {
+                d/=10;
+                n=n0+1;
+                k=k0;
+              } else
+                break;
+            } else
+              break;
+          }
+
+          goto sp_out_f;
+        case 'g':
+          if (!len) len=12;
+          flags|=PRTF_TRUNCATE;
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+          if (d==inf) goto sp_out_inf;
+          if (d)
+            n=Floor(Log10(d));
+          else
+            n=0;
+          if (n>=len-1-dec_len || n<-(dec_len-1))
+            goto sp_out_e;
+          else
+            goto sp_out_f;
+        case 'n':
+          if (!len) len=12;
+          flags|=PRTF_TRUNCATE;
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          d=argv[cur_arg++](F64);
+          if (d<0) {
+            flags|=PRTF_NEG;
+            d=-d;
+          }
+sp_out_eng: //Engineering notation
+          if (d==inf) goto sp_out_inf;
+          if (d)
+            n=FloorI64(Floor(Log10(d)),3);
+          else
+            n=0;
+          d/=Pow10I64(n);
+
+          if (n<0) {
+            n=-n;
+            flags|=PRTF_NEG_E;
+          }
+          if (flags&PRTF_AUX_FMT_NUM && -24<=n<=24) {
+            if (flags&PRTF_QUESTION) {
+              if (flags&PRTF_NEG_E)
+                i=-n/3;
+              else
+                i=n/3;
+              j=0;
+            } else {
+              if (flags&PRTF_NEG_E)
+                j=-n-aux_fmt_num;
+              else
+                j=n-aux_fmt_num;
+              d*=Pow10I64(j);
+              i=aux_fmt_num/3;
+            }
+            if (i<0)
+              tmp_buf[k++]=sys_neg_pows_lets[-i];
+            else if (i>0)
+              tmp_buf[k++]=sys_pos_pows_lets[i];
+            else if (len!=0)
+              tmp_buf[k++]=CH_SPACE;
+            if (!(flags&PRTF_DECIMAL)) {
+              dec_len=len-k-2;
+              if (flags&PRTF_NEG)
+                dec_len--;
+              if (j>0) {
+                if (flags&PRTF_COMMA)
+                  dec_len-=4*j/3;
+                else
+                  dec_len-=j;
+              }
+              d1=d+Pow10I64(-dec_len+1)/2;
+              if (d1>=10) {
+                dec_len--;
+                if (d1>=100)
+                  dec_len--;
+              }
+            }
+          } else {
+            i=3;
+            do tmp_buf[k++]=ModU64(&n,10)+'0';
+            while (n && i--);
+            if (flags&PRTF_NEG_E)
+              tmp_buf[k++]='-';
+            tmp_buf[k++]='e';
+            if (!dec_len) {
+              dec_len=len-k-2;
+              if (flags&PRTF_NEG)
+                dec_len--;
+              d1=d+Pow10I64(-dec_len+1)/2;
+              if (d1>=10) {
+                dec_len--;
+                if (d1>=100)
+                  dec_len--;
+              }
+            }
+          }
+          if (flags&PRTF_COMMA) {
+            if (len && dec_len>0 && !(dec_len&3))
+              tmp_buf[k++]=',';
+            dec_len-=dec_len/4;
+          }
+          goto sp_out_f;
+        case 'X':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=4;
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='A'-0x3A;
+              k++;
+              m>>=4;
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=4;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+            goto sp_out_comma_num;
+          } else {
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='A'-0x3A;
+              k++;
+              m>>=4;
+            } while (m && k<TMP_BUF_LEN-SLOP);
+            goto sp_out_num;
+          }
+        case 'x':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=4;
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='a'-0x3A;
+              k++;
+              m>>=4;
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=4;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+            goto sp_out_comma_num;
+          } else {
+            do {
+              tmp_buf[k]= m&15 +'0';
+              if (tmp_buf[k]>'9') tmp_buf[k]+='a'-0x3A;
+              k++;
+              m>>=4;
+            } while (m && k<TMP_BUF_LEN-SLOP);
+            goto sp_out_num;
+          }
+        case 'b':
+        case 'B':
+          if (cur_arg>=argc)
+            throw('StrPrint');
+          m=argv[cur_arg++];
+          if (flags&PRTF_COMMA) {
+            comma_fmt_cnt=comma_cnt=4;
+            do {
+              tmp_buf[k++]= m&1 +'0';
+              m>>=1;
+              if (!m) break;
+              if (!--comma_cnt) {
+                tmp_buf[k++]=',';
+                comma_cnt=4;
+              }
+            } while (k<TMP_BUF_LEN-SLOP);
+            goto sp_out_comma_num;
+          } else {
+            do {
+              tmp_buf[k++]= m&1 +'0';
+              m>>=1;
+            } while (m && k<TMP_BUF_LEN-SLOP);
+            goto sp_out_num;
+          }
+        case '%':
+          SPutChar(_dst,'%',_buf);
+          break;
+      }
+    } else
+      SPutChar(_dst,ch,_buf);
+  }
+  SPutChar(_dst,0,_buf);
+  return buf;
+}
+
+U8 *StrPrint(U8 *dst,U8 *fmt,...)
+{//See StrPrintJoin().
+  return StrPrintJoin(dst,fmt,argc,argv);
+}
+
+U8 *CatPrint(U8 *_dst,U8 *fmt,...)
+{//StrCat().  See StrPrintJoin().
+  U8 *dst=_dst;
+  while (*dst)
+    dst++;
+  StrPrintJoin(dst,fmt,argc,argv);
+  return _dst;
+}
+
+U0 Print(U8 *fmt,...)
+{//Print("") Fmt Strings.  See StrPrintJoin().
+//Don't use this.  See Print() shortcut.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  PutS(buf);//Don't use PutS().  See Print() shortcut.
+  Free(buf);
+}
+
+U8 *MStrPrint(U8 *fmt,...)
+{//MAlloc StrPrint.  See StrPrintJoin().
+  U8 *res,*buf=StrPrintJoin(NULL,fmt,argc,argv);
+  res=StrNew(buf);
+  Free(buf);
+  return res;
+}
+
+U0 PrintErr(U8 *fmt,...)
+{//Print "Err:" and msg in blinking red.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  GetOutOfDollar;
+  "%,p %,p %,p %,p " ST_ERR_ST "%s",Caller,Caller(2),Caller(3),Caller(4),buf;
+  Free(buf);
+}
+
+U0 PrintWarn(U8 *fmt,...)
+{//Print "Warn:" and msg in blinking red.
+  U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
+  GetOutOfDollar;
+  "%,p %,p %,p %,p " ST_WARN_ST "%s",Caller,Caller(2),Caller(3),Caller(4),buf;
+  Free(buf);
+}
+
+ diff --git a/public/Wb/Kernel/StrScan.HC.HTML b/public/Wb/Kernel/StrScan.HC.HTML new file mode 100755 index 0000000..0cf1db3 --- /dev/null +++ b/public/Wb/Kernel/StrScan.HC.HTML @@ -0,0 +1,370 @@ + + + + + + + + + + + +
+I64 Str2I64(U8 *st,I64 radix=10,U8 **_end_ptr=NULL)
+{//String to I64. Similar to strtoul().
+//Allows radix change with "0x20" "0b1010" "0d123" "0o18".
+  //Be careful of Str2I64("0b101",16)-->0xB101.
+  Bool neg=FALSE;
+  I64 ch,res=0;
+  if (!st || !(2<=radix<=36)) {
+    if (_end_ptr) *_end_ptr=st;
+    return 0;
+  }
+  while (Bt(char_bmp_white_space,*st))
+    st++;
+  while (TRUE)
+    switch (*st) {
+      case '-':
+        st++;
+        neg=!neg;
+        break;
+      case '+':
+        st++;
+        break;
+      case '0':
+        st++;
+        ch=ToUpper(*st);
+        if (ch>='B' && (radix<=10 || ch>'A'+radix-11))
+          switch (ch) {
+            case 'B': radix=2;  st++; break;
+            case 'D': radix=10; st++; break;
+            case 'X': radix=16; st++; break;
+          }
+      default:
+        goto ai_cont;
+    }
+ai_cont:
+  while (ch=ToUpper(*st++)) {
+    if (radix>10) {
+      if ('0'<=ch<='9')
+        res=res*radix+ch-'0';
+      else if ('A'<=ch<='A'+radix-11)
+        res=res*radix+ch-'A'+10;
+      else
+        break;
+    } else if ('0'<=ch<='0'+radix-1)
+      res=res*radix+ch-'0';
+    else
+      break;
+  }
+  if (_end_ptr) *_end_ptr=st-1;
+  if (neg)
+    return -res;
+  else
+    return res;
+}
+
+F64 Str2F64(U8 *src,U8 **_end_ptr=NULL)
+{/*String to F64.
+Does not allow more than 18-digits
+before or after the decimal point
+because the numbers before and after
+the decimal point are stored
+in 64-bits.  Use exponentiated forms
+to avoid this.
+*/
+  I64 i,j,k,ch;
+  F64 d;
+  Bool neg=FALSE,neg_e=FALSE;
+
+  ch=*src++;
+  while (Bt(char_bmp_white_space,ch))
+    ch=*src++;
+  if (ch=='-') {
+    neg=TRUE;
+    ch=*src++;
+  }
+  if (!StrNCmp(src-1,"inf",3)) {
+    d=inf;
+    src+=3;
+    goto a2f_end;
+  }
+  if (*src=='inf') {
+    d=inf;
+    src++;
+    goto a2f_end;
+  }
+  i=0;
+  while (TRUE) {
+    if (Bt(char_bmp_dec_numeric,ch))
+      i=i*10+ch-'0';
+    else {
+      if (ch=='.' || ch=='e' || ch=='E')
+        break;
+      d=i;
+      goto a2f_end;
+    }
+    ch=*src++;
+  }
+  if (ch=='.')
+    ch=*src++;
+  k=0;
+  while (TRUE) {
+    if (Bt(char_bmp_dec_numeric,ch)) {
+      i=i*10+ch-'0';
+      k++;
+    } else {
+      if (ch=='e' || ch=='E')
+        break;
+      d=i*Pow10I64(-k);
+      goto a2f_end;
+    }
+    ch=*src++;
+  }
+  ch=*src++;
+  if (ch=='-') {
+    neg_e=TRUE;
+    ch=*src++;
+  }
+  j=0;
+  while (TRUE) {
+    if (Bt(char_bmp_dec_numeric,ch))
+      j=j*10+ch-'0';
+    else {
+      if (neg_e)
+        d=i*Pow10I64(-j-k);
+      else
+        d=i*Pow10I64(j-k);
+      goto a2f_end;
+    }
+    ch=*src++;
+  }
+a2f_end:
+  if (_end_ptr) *_end_ptr=src-1;
+  if (neg)
+    return -d;
+  else
+    return d;
+}
+
+CDate Str2Date(U8 *_src)
+{/*"*+nnnn", "*-nnnn", "mm/dd", "mm/dd/yy"
+It also supports some funs
+SM() start of mon
+EM() end of mon
+SY() start of year
+EY() end of year
+Full expressions are not implimented
+but you can do stuff like SM(*-7)+3
+and it will return the 3rd day after
+the start of mon for seven days before
+today.
+*/
+  CDate res=0;
+  CDateStruct ds,ds_now;
+  U8 *src=MStrUtil(_src,SUF_REM_SPACES|SUF_TO_UPPER),
+        *v=StrNew(src),
+        *ptr=src;
+  Bool start_mon=FALSE,end_mon=FALSE,
+        start_year=FALSE,end_year=FALSE;
+
+  MemSet(&ds,0,sizeof(CDateStruct));
+  if (!StrNCmp(ptr,"SM(",3)) {
+    ptr+=3;
+    start_mon=TRUE;
+  } else if (!StrNCmp(ptr,"EM(",3)) {
+    ptr+=3;
+    end_mon=TRUE;
+  } else if (!StrNCmp(ptr,"SY(",3)) {
+    ptr+=3;
+    start_year=TRUE;
+  } else if (!StrNCmp(ptr,"EY(",3)) {
+    ptr+=3;
+    end_year=TRUE;
+  }
+  if (*ptr=='*') {
+    ptr++;
+    if (*ptr=='+' || *ptr=='-')
+      res.date=Str2I64(ptr,,&ptr);
+    res+=Now+local_time_offset;
+  } else {
+    StrFirstRem(ptr,"/",v); //Put mon into v
+    ds.mon=Str2I64(v);
+    if (StrOcc(ptr,'/')) {
+      StrFirstRem(ptr,"/",v); //Put day into v leaving year in ptr
+      ds.day_of_mon=Str2I64(v);
+      ds.year=Str2I64(ptr,,&ptr);
+      if (ds.year<100) //if not 4 digit year
+        ds.year+=2000;
+    } else {
+      ds.day_of_mon=Str2I64(ptr,,&ptr);
+      Date2Struct(&ds_now,Now+local_time_offset);
+      ds.year=ds_now.year;
+    }
+    res=Struct2Date(&ds);
+  }
+  if (*ptr==')') ptr++;
+
+  if (start_mon)
+    res.date=FirstDayOfMon(res.date);
+  else if (end_mon)
+    res.date=LastDayOfMon(res.date);
+  else if (start_year)
+    res.date=FirstDayOfYear(res.date);
+  else if (end_year)
+    res.date=LastDayOfYear(res.date);
+
+  if (*ptr=='+' || *ptr=='-')
+    res.date+=Str2I64(ptr);
+  Free(src);
+  Free(v);
+  return res-local_time_offset;
+}
+
+U8 *StrScan(U8 *src,U8 *fmt,...)
+{/*Opposite of sprintf().  Pass ptrs to data to be scanned-in.
+For "%s", pass ptr to ptr (be careful because addr
+of array is the same as array--create ptr to array
+and take addr.
+*/
+  U8 *buf,*ptr,**pptr;
+  Bool left_justify=FALSE;
+  I64 ch,cur_arg=0,i,len,*i_ptr,dec_len;
+  F64 *d_ptr;
+  if (!fmt)
+    throw('Scan');
+  while (ch = *fmt++) {
+    if (ch=='%') {
+      if (*fmt=='%') {
+        src++;
+        fmt++;
+      } else {
+        if (*fmt=='-') {
+          left_justify=TRUE;
+          fmt++;
+        } else
+          left_justify=FALSE;
+        len=0;
+        while ('0'<=*fmt<='9')
+          len=len*10+ (*fmt++ -'0');
+        if (*fmt=='*') {
+          fmt++;
+          if (cur_arg>=argc)
+            throw('Scan');
+          len=argv[cur_arg++];
+        }
+        ch=*fmt++;
+        if (ch && !len) {
+          ptr=src;
+          while (*ptr && *ptr!=*fmt)
+            ptr++;
+          len=ptr-src;
+        } else {
+          if (ch=='.') {
+            dec_len=0;
+            while ('0'<=*fmt<='9')
+              dec_len=dec_len*10+ (*fmt++-'0');
+            if (*fmt=='*') {
+              fmt++;
+              if (cur_arg>=argc)
+                throw('Scan');
+              dec_len=argv[cur_arg++];
+            }
+            ch=*fmt++;
+          }
+        }
+        buf=MAlloc(len+1);
+        for (i=0;i<len;i++)
+          buf[i]=*src++;
+        buf[i]=0;
+        switch (ch) {
+          case 's':
+            if (cur_arg>=argc)
+              throw('Scan');
+            pptr=argv[cur_arg++];
+            StrCpy(*pptr,buf);
+            break;
+          case 'c':
+            if (cur_arg>=argc)
+              throw('Scan');
+            ptr=argv[cur_arg++];
+            *ptr=*buf;
+            break;
+          case 'C':
+            if (cur_arg>=argc)
+              throw('Scan');
+            ptr=argv[cur_arg++];
+            *ptr=ToUpper(*buf);
+            break;
+          case 'z':
+            if (cur_arg+1>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=LstMatch(buf,argv[cur_arg++]);
+            break;
+          case 'Z':
+            if (cur_arg+1>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=DefineMatch(buf,argv[cur_arg++]);
+            break;
+          case 'd':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2I64(buf);
+            break;
+          case 'X':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2I64(buf,16);
+            break;
+          case 'b':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2I64(buf,2);
+            break;
+          case 'e':
+          case 'f':
+          case 'g':
+          case 'n':
+            if (cur_arg>=argc)
+              throw('Scan');
+            d_ptr=argv[cur_arg++];
+            *d_ptr=Str2F64(buf);
+            break;
+          case 'D':
+            if (cur_arg>=argc)
+              throw('Scan');
+            i_ptr=argv[cur_arg++];
+            *i_ptr=Str2Date(buf);
+            break;
+        }
+        Free(buf);
+      }
+    } else
+      src++;
+  }
+  return src;
+}
+
+ diff --git a/public/Wb/MakeHome.HC.HTML b/public/Wb/MakeHome.HC.HTML new file mode 100755 index 0000000..a081be7 --- /dev/null +++ b/public/Wb/MakeHome.HC.HTML @@ -0,0 +1,44 @@ + + + + + + + + + + + +
+Cd(__DIR__);;
+
+//If these are not present in /Home, it uses the version in the root dir.  You
+//can make your own, modified, version of these files in your /Home directory.
+#include "~/HomeLocalize"
+#include "/Adam/Opt/Boot/MakeBoot"
+#include "/Adam/Opt/Utils/MakeUtils"
+#include "~/HomeWrappers"
+MapFileLoad("::/Kernel/Kernel");
+MapFileLoad("::/Compiler/Compiler");
+#include "~/HomeKeyPlugIns"
+#include "~/HomeSys"
+Cd("..");;
+
+ diff --git a/public/Wb/Misc/DoDistro.HC.HTML b/public/Wb/Misc/DoDistro.HC.HTML new file mode 100755 index 0000000..be7cb9a --- /dev/null +++ b/public/Wb/Misc/DoDistro.HC.HTML @@ -0,0 +1,80 @@ + + + + + + + + + + + +
+//Make Your own Distro by #include-ing this file.
+
+#define STD_DISTRO_DVD_CFG      "TB\nScale2Mem(2048,0x40000)\nT \n\n\n\n"
+
+U0 MakeMyISO(U8 *_out_iso_filename)
+{//Does everything with current drive.
+//If you have not recompiled Kernel and defined your CD/DVD drive, use Mount.
+  U8 *out_iso_filename=FileNameAbs(_out_iso_filename);
+  if (!DrvIsWritable) {
+    "Drive must be writable.  Install on Hard drive, first.\n";
+    return;
+  }
+  DelTree("/Distro");
+  Del(out_iso_filename);
+
+  DirMk("/Distro");
+  In(STD_DISTRO_DVD_CFG);
+  BootDVDIns;
+
+  Copy("/*","/Distro");
+  Del("/Distro/" KERNEL_BIN_C);
+
+  CopyTree(BOOT_DIR,    "/Distro" BOOT_DIR);
+  CopyTree("/Home",     "/Distro/Home");
+  CopyTree("/Adam",     "/Distro/Adam");
+  CopyTree("/Apps",     "/Distro/Apps");
+  CopyTree("/Compiler", "/Distro/Compiler");
+  CopyTree("/Demo",     "/Distro/Demo");
+  CopyTree("/Doc",      "/Distro/Doc");
+  CopyTree("/Kernel",   "/Distro/Kernel");
+  CopyTree("/Misc",     "/Distro/Misc");
+
+  //To save space, optionally delete dictionary.
+  //Del("/Distro/Adam/AutoComplete/ACDefs.DATA");
+  CopyTree("/Downloads","/Distro/Downloads");     //You can leave this out.
+  DirMk("/Distro/Tmp");
+  DirMk("/Distro/Tmp/ScrnShots");
+  RedSeaISO(out_iso_filename,"/Distro","/Distro" BOOT_DIR_KERNEL_BIN_C);
+
+  //If CD-ROM use MT_CD instead of MT_DVD.
+  //DVDImageWrite('T',out_iso_filename,MT_DVD); //Uncomment to burn.
+
+  //DelTree("/Distro");
+  Free(out_iso_filename);
+}
+
+MakeMyISO("/Tmp/MyDistro.ISO.C");
+
+// Study my account examples Cfg Strs, Update Funs.
+
+ diff --git a/public/Wb/Misc/OSInstall.HC.HTML b/public/Wb/Misc/OSInstall.HC.HTML new file mode 100755 index 0000000..6d53bee --- /dev/null +++ b/public/Wb/Misc/OSInstall.HC.HTML @@ -0,0 +1,250 @@ + + + + + + + + + + + +
+U0 InstallDrv(U8 drv_let)
+{
+  U8 *st;
+  ExePrint("CopyTree(\"::/\",\"%C:/\");",drv_let);
+  ExePrint("DirMk(\"%C:/Tmp\");",drv_let);
+  ExePrint("DirMk(\"%C:/Tmp/ScrnShots\");",drv_let);
+  ExePrint("DirMk(\"%C:/Home\");",drv_let);
+
+  st=MStrPrint("%C:/Home/DoDistro.HC.Z",drv_let);
+  if (!FileFind(st))
+    Copy("::/Misc/DoDistro.HC.Z",st);
+  Free(st);
+
+  st=MStrPrint("%C:/Home/MakeHome.HC.Z",drv_let);
+  if (!FileFind(st))
+    Copy("::/MakeHome.HC.Z",st);
+  Free(st);
+}
+
+Bool VMPrtDsk(CTask *task,CATARep *ata_drv)
+{
+  if (ata_drv) {
+    XTalkWait(task,"DskPrt(,0.5,0.5);\nC\np%d\nY",ata_drv->num);
+    return TRUE;
+  } else
+    return FALSE;
+}
+
+U0 VMInstallDrv(CTask *task,U8 drv_let,
+        CATARep *ata_drv,CATARep *atapi_drv)
+{
+  InstallDrv(drv_let);
+  XTalkWait(task,"BootHDIns('%C');\n\nB\n0x20000\n",drv_let);
+  if (ata_drv)
+    XTalkWait(task,"C\np%d\n",ata_drv->num);
+  if (atapi_drv)
+    XTalkWait(task,"Tp%d\n",atapi_drv->num);
+  XTalkWait(task,"\n\n\n"); //Exit Drives,Dsk Cache,Options
+}
+
+U0 VMInstallWiz()
+{
+  CATARep *head=NULL,*ata_drv=NULL,*atapi_drv=NULL;
+  CTask *task;
+  "\nIt's normal for this to freeze for a moment or two.\n";
+  PressAKey;
+
+  task=User;
+  TaskWait(task);
+  task->border_src=BDS_CONST;
+  task->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  task->text_attr  =LTGRAY<<4+BLUE;
+  task->win_inhibit=WIG_TASK_DFT-WIF_SELF_BORDER;
+  WinHorz(Fs->win_left,Fs->win_right,task);
+  WinVert(Fs->win_top,(Fs->win_top+Fs->win_bottom)>>2-1,task);
+  WinVert(task->win_bottom+3,Fs->win_bottom);
+  WinToTop(Fs);
+
+  ATARep(FALSE,TRUE,&head);
+  ATAIDDrvs(head,&ata_drv,&atapi_drv);
+  if (VMPrtDsk(task,ata_drv)) {
+    VMInstallDrv(task,'C',ata_drv,atapi_drv);
+    VMInstallDrv(task,'D',ata_drv,atapi_drv);
+    BootMHDIns('C');
+  }
+  LinkedLstDel(head);
+  WinVert(task->win_top,Fs->win_bottom);
+  Kill(task);
+}
+
+U0 RegularInstallWiz()
+{
+  I64 unit,drv_let;
+  U8 *st,*base0,*base1;
+  CATARep *head=NULL,*tmpha;
+  I64 ch,num_hints;
+  CTask *task;
+
+  "\nIt's normal for this to freeze for a moment or two.\n";
+  PressAKey;
+
+  task=User;
+  TaskWait(task);
+  task->border_src=BDS_CONST;
+  task->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
+  task->text_attr  =LTGRAY<<4+BLUE;
+  task->win_inhibit=WIG_TASK_DFT-WIF_SELF_BORDER;
+  WinHorz(Fs->win_left,Fs->win_right,task);
+  WinVert(Fs->win_top,(Fs->win_top+Fs->win_bottom)>>2-1,task);
+  WinVert(task->win_bottom+3,Fs->win_bottom);
+  WinToTop(Fs);
+  XTalk(task,"Mount;\nC\np");
+
+  num_hints=ATARep(FALSE,,&head);
+  "\nInclude '$PURPLE$0x$FG$' for hexidecimal numbers.\n\n";
+  while (TRUE) {
+    base0=GetStr("Hard Drive I/O Port Base0  : ");
+    if (0<Str2I64(base0)<=0xFFFF)
+      break;
+    Free(base0);
+  }
+  if (1<=Str2I64(base0)<=num_hints) {
+    tmpha=ATARepFind(&head,Str2I64(base0));
+    Free(base0);
+    base0=MStrPrint("0x%X",tmpha->base0);
+    base1=MStrPrint("0x%X",tmpha->base1);
+    st   =MStrPrint("0x%X",tmpha->unit);
+    unit=Str2I64(st);
+    Free(st);
+  } else {
+    while (TRUE) {
+      base1=GetStr("Hard Drive I/O Port Base1  : ");
+      if (0<Str2I64(base1)<=0xFFFF)
+        break;
+      Free(base1);
+    }
+    do {
+      st =GetStr("Unit--$PURPLE$0$FG$=Master or $PURPLE$1$FG$=Slave: ","0");
+      unit=Str2I64(st);
+      Free(st);
+    } while (!(0<=unit<=1));
+  }
+  LinkedLstDel(head);
+  XTalkWait(task,"%s\n%s\n%C\n",base0,base1,'0'+unit);
+  DrvRep;
+  do {
+    st=GetStr("\nDestination Partition Letter: ");
+    if (*st)
+      drv_let=Let2Let(*st);
+    else
+      drv_let=0;
+    Free(st);
+  } while (!('A'<=drv_let<='Z'));
+  '\n';
+
+  "$RED$Format %C Partition?$FG$\n",drv_let;
+  if (YorN) {
+    '\n';
+    do {
+      "$PURPLE$1$FG$) Use FAT32\n"
+            "$PURPLE$2$FG$) Use RedSea\n"
+            "\nFile System Type: ";
+      ch=GetChar;
+      '\n';
+    } while (!('1'<=ch<='2'));
+    if (ch=='1')
+      Fmt(drv_let,,FALSE,FSt_FAT32);
+    else
+      Fmt(drv_let,,FALSE,FSt_REDSEA);
+  }
+  InstallDrv(drv_let);
+  XTalkWait(task,"BootHDIns('%C');\n\nB\n0x20000\n"
+        "C\ns%s\n%s\n%C\n\n\n", //Exit Drives,Dsk Cache,Options
+        drv_let,base0,base1,'0'+unit);
+  "$RED$Install Master Boot loader?$FG$";
+  if (YorN) {
+    '\n';
+    BootMHDIns(drv_let);
+  }
+  Free(base0);
+  Free(base1);
+
+  WinVert(task->win_top,Fs->win_bottom);
+  Kill(task);
+}
+
+U0 DoInstructions()
+{
+  CTask *task;
+  AutoComplete;
+  task=Fs->next_task;
+  while (task!=Fs) {
+    if (task!=adam_task && task!=sys_winmgr_task && task!=ac.task) {
+      XTalk(task,"Ed(\"::/Doc/Install.DD.Z\");\n");
+      break;
+    }
+    task=task->next_task;
+  }
+}
+
+Bool DoInstall(Bool pmt_reboot)
+{
+  I64 res=FALSE,vm_install;
+  "\n\n\n\n\nAre you installing inside VMware, QEMU, VirtualBox "
+        "or a similar virtual machine? ";
+  vm_install=YorN;
+  DocBottom;
+
+  if (vm_install) {
+    VMInstallWiz();
+    res=TRUE;
+  } else {
+    "\n\nThis wizard works if you have a partition ready.  "
+          "You can partition the drive or BootHDIns() "
+          "with more options if you do it by hand, not using this wizard.\n\n"
+          "Continue Install Wizard ";
+    if (YorN) {
+      RegularInstallWiz();
+      res=TRUE;
+    } else
+      pmt_reboot=FALSE;
+  }
+  if (pmt_reboot) {
+    "Reboot Now ";
+    if (YorN)
+      Reboot;
+  }
+  return res;
+}
+
+Bool OSInstall(Bool pmt_reboot=TRUE)
+{
+  DoInstructions;
+  return DoInstall(pmt_reboot);
+}
+
+#if __CMD_LINE__
+OSInstall(TRUE);
+#endif
+
+ diff --git a/public/Wb/Misc/OSTestSuite.HC.HTML b/public/Wb/Misc/OSTestSuite.HC.HTML new file mode 100755 index 0000000..7743bc4 --- /dev/null +++ b/public/Wb/Misc/OSTestSuite.HC.HTML @@ -0,0 +1,1754 @@ + + + + + + + + + + + +
+I64 ts_i;
+F64 ts_t0;
+
+U0 TS(U8 *desc)
+{//We must set these because an app can call ProgressBarsRst.
+  U8 *st=MStrPrint("%d. %s",ts_i,desc);
+  if (*desc)
+    progress3_max=1;
+  else
+    progress3_max=0;
+  StrPrint(progress3_desc,"%*hc%s",
+    (PROGRESS_DESC_LEN-StrLen(st))>>1,CH_SPACE,st);
+  Free(st);
+  progress4=ts_i++;
+  progress4_max=171;
+  progress4_t0=ts_t0;
+  *progress4_desc=0;
+  RegExe("TempleOS/OSTestSuite");
+}
+
+U0 TSFile(U8 *name,I64 mS=750)
+{
+  CTask *task=User("#include \"%s\";Sleep(%d);\n",name,mS);
+  DeathWait(&task,TRUE);
+}
+
+U0 TSFileChar(U8 *name,I64 mS=750,I64 ch=CH_SPACE,Bool wait=TRUE)
+{
+  CTask *task=User;
+  if (wait)
+    XTalkWait(task,"#include \"%s\";\n",name);
+  else
+    XTalk(task,"#include \"%s\";\n",name);
+  Sleep(mS);
+  if (ch)
+    PostMsgWait(task,MSG_KEY_DOWN_UP,ch,0);
+  DeathWait(&task,TRUE);
+}
+
+/*
+U0 DoMouseDemo()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/MouseDemo\";\n");
+}
+U0 DoPullDownMenu()
+{
+  XTalkWait(task,"#include \"::/Demo/PullDownMenu\";\n");
+}
+U0 DoTicTacToe()
+{
+  XTalkWait(task,"#include \"::/Demo/Games/TicTacToe\";\n");
+}
+U0 DoLife()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/Life\";\n");
+}
+U0 DoZing()
+{
+  XTalkWait(task,"#include \"::/Demo/Games/Zing\";\n");
+}
+U0 DoSlider()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/Slider\";\n");
+}
+U0 DoScrollBars()
+{
+  XTalkWait(task,"#include \"::/Demo/Graphics/ScrollBars\";\n");
+}
+U0 DoWhap()
+{
+  XTalkWait(task,"#include \"::/Demo/Games/Whap\";\n");
+}
+U0 DoDataBase()
+{
+  XTalkWait(task,"#include \"::/Demo/Dsk/DataBase\";\n");
+}
+U0 DoDskRaw()
+{
+  XTalkWait(task,"#include \"::/Demo/Dsk/DskRaw\";\n");
+}
+U0 DoTimeClock()
+{
+  XTalkWait(task,"#include \"::/Apps/TimeClock\";\n");
+}
+U0 DoLectures()
+{
+  XTalkWait(task,"#include \"::/Demo/Lectures\";\n");
+}
+U0 DoInFile()
+{
+  XTalkWait(task,"#include \"::/Demo/InFile\";\n");
+}
+U0 DoSpy()
+{
+  XTalkWait(task,"#include \"::/Demo/Spy\";\n");
+}
+U0 DoUnusedDefine()
+{
+  XTalkWait(task,"#include \"::/Demo/DolDoc/UnusedDefine\";\n");
+}
+U0 DoOnceDemo()
+{
+  XTalkWait(task,"#include \"::/Demo/OnceDemo\";\n");
+}
+*/
+
+U0 DoRandDemo()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/RandDemo\";\n");
+  XTalkWait(task," ");
+  XTalkWait(task," ");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLowPassFilter()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/LowPassFilter\";\n");
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMathAudioDemo()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/MathAudioDemo\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMsgLoop()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/MsgLoop\";\n");
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoASCIIOrgan()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Snd/ASCIIOrgan\";\n");
+  Sleep(100);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'A',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'B',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'C',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDoodle()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Doodle\";\n");
+  PostMsgWait(task,MSG_MS_L_DOWN,10,10);
+  PostMsgWait(task,MSG_MS_L_UP,100,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSpeedLine()
+{
+  I64 i=PURPLE+1; //+1 because TRANSPARENT
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Speedline\";\n");
+  PostMsgWait(task,MSG_MS_L_DOWN,10,10);
+  PostMsgWait(task,MSG_MS_L_UP,100,200);
+  PostMsg(task,MSG_MS_R_DOWN_UP,0,0);
+  BirthWait(&task->popup_task);
+  while (i--)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  TaskWait(task);
+  PostMsgWait(task,MSG_MS_L_DOWN,50,10);
+  PostMsgWait(task,MSG_MS_L_UP,150,200);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoKeyBitMap()
+{
+  I64 i_sc=Char2ScanCode('i');
+  CTask *task=User("#include \"::/Demo/KeyBitMap\";\n");
+  Sleep(50);
+  LBts(kbd.down_bitmap,i_sc);
+  Sleep(500);
+  LBtr(kbd.down_bitmap,i_sc);
+  Sleep(50);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDigits()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Digits\";\n");
+  Sleep(100);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'1',0);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSymmetry()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Symmetry\";\n");
+  PostMsgWait(task,MSG_MS_R_DOWN,100,100);
+  PostMsgWait(task,MSG_MS_R_UP,200,200);
+  Sleep(100);
+  PostMsgWait(task,MSG_MS_L_DOWN,10,10);
+  PostMsgWait(task,MSG_MS_L_UP,100,200);
+  Sleep(250);
+  PostMsgWait(task,MSG_MS_L_DOWN,100,200);
+  PostMsgWait(task,MSG_MS_L_UP,400,400);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBSpline()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/BSpline\";\n");
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,50,50);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,300,100);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,150,300);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,0,0);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoScrnCapture()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/ScrnCapture\";\n");
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+  Del("~/DemoScrnShot.GR*");
+}
+
+U0 DoStadium()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Stadium/Stadium\";\n");
+  Sleep(50);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100,10);
+  Sleep(300);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,320,20);
+  Sleep(300);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,520,10);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPalette()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Palette\";\n");
+  Sleep(400);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(400);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoElephantWalk()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/ElephantWalk\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_RIGHT);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoHalogen()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Halogen\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_UP);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_UP,0,SC_CURSOR_UP);
+  PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_RIGHT);
+  Sleep(333);
+  PostMsgWait(task,MSG_KEY_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTheDead()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/TheDead\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(50);
+  }
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBomberGolf()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/BomberGolf\";\n");
+  for (i=0;i<7;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<7;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(200);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoZoneOut()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/Games/ZoneOut\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoVaroom()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Varoom\";\n");
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFlatTops()
+{
+  CTask *task=User("#include \"::/Demo/Games/FlatTops\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,RandI16%400+200,RandI16%300+150);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoWenceslas()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/Games/Wenceslas\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(100);
+  for (i=0;i<25;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(25);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTreeCheckers()
+{
+  I64 task_num;
+  CTask *task=User("#include \"::/Demo/Games/TreeCheckers\";\n");
+
+  task_num=BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  Sleep(500);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'\n',0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMorseCode()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Snd/MorseCode\";\n");
+  Sleep(50);
+
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(200);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(350);
+
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(50);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(350);
+
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(50);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(25);
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(200);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(25);
+  PostMsg(task,MSG_KEY_DOWN,CH_SPACE,0);
+  Sleep(50);
+  PostMsg(task,MSG_KEY_UP,CH_SPACE,0);
+  Sleep(500);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPixCollision()
+{
+  I64 w,h;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Collision\";\n");
+  w=task->pix_width>>1 +task->pix_left+task->scroll_x;
+  h=task->pix_height>>1+task->pix_top +task->scroll_y;
+  MsSet(w-35,h-35);
+  InSetMs(10,w+35,w+35);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBlackDiamond()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/BlackDiamond\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(75);
+  }
+  for (i=0;i<12;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(75);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoCtrlR1()
+{
+  I64 i,task_num;
+  CTask *task=User;
+  XTalkWait(task,"//");
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_CTRLR,0);
+  task_num=BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  for (i=0;i<1;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  //Color
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<2;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<2;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  //Width
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<4;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<4;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  //Line
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<7;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,150,95);
+  Sleep(250);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,190,190);
+  Sleep(250);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,110,190);
+  Sleep(250);
+  PostMsg(task,MSG_MS_R_DOWN_UP,100,100);
+
+  //Color
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<2;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<3;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  //Circle
+  task_num=BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  for (i=0;i<10;i++)
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_L_DOWN,150,150);
+  PostMsgWait(task,MSG_MS_L_UP,190,190);
+  Sleep(250);
+  PostMsg(task,MSG_MS_R_DOWN_UP,100,100);
+
+  //Exit
+  BirthWait(&task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN+SCF_CTRL);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  PostMsg(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  Sleep(1000);
+  XTalk(task,"\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoF2Macro()
+{
+  I64 i;
+  U8 *ptr="\"Boo!\\n\";\n";
+  CTask *task=User;
+  DeathWait(&sys_macro_task);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_F2);
+  BirthWait(&sys_macro_task);
+  TaskWait(sys_macro_task);
+
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT|SCF_CTRL);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,CH_SPACE,0); //Press RECORD
+  while (!Bt(&sys_semas[SEMA_RECORD_MACRO],0))
+    Yield;
+
+  while (*ptr)
+    PostMsgWait(task,MSG_KEY_DOWN,*ptr++,0);
+
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(sys_macro_task,MSG_KEY_DOWN_UP,CH_SPACE,0); //Press STOP
+
+  for (i=0;i<10;i++)
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_F2|SCF_SHIFT);
+
+  PostMsg(sys_macro_task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&sys_macro_task);
+
+  Sleep(1000);
+  XTalk(task,"\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLightTable()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/LightTable\";\n\n");
+  TaskWait(task);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'2',0);
+  PostMsgWait(task,MSG_MS_L_DOWN,   100         ,200);
+  PostMsgWait(task,MSG_MS_L_UP,     640-100     ,200);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'3',0);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100         ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100         ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,100         ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,120         ,180);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,160         ,120);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,320         ,10);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-160     ,120);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-120     ,180);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-100     ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-100     ,200);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,640-100     ,200);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,0,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'4',0);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,320,190);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'5',0);
+  PostMsgWait(task,MSG_MS_L_DOWN,460,280);
+  PostMsgWait(task,MSG_MS_L_UP  ,500,220);
+
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPredatorPrey()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/PredatorPrey\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoCharDemo()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/CharDemo\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+  Sleep(750);
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLattice()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Lattice\";\n");
+  for (i=0;i<20;i++)
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,'+',0);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+  }
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+  }
+  for (i=0;i<16;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  }
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoCartesian()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Cartesian\";\n");
+  XTalkWait(task,"0.2*x`1.5\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMPAdd()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/MultiCore/MPAdd\";\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFlapBat()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/Games/FlapBat\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  for (i=0;i<4;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN,CH_SPACE,0);
+    Sleep(100);
+    PostMsgWait(task,MSG_KEY_UP,CH_SPACE,0);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBattleLines()
+{
+  CTask *task=User("#include \"::/Demo/Games/BattleLines\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  MsSet(430,300,,TRUE);
+  InSetMs(10,530,400);
+  MsSet(,,,FALSE);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoBigGuns()
+{
+  I64 i,task_num;
+  CTask *task=User("#include \"::/Demo/Games/BigGuns\";\n");
+  task_num=BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  BirthWait(&task->popup_task,task_num);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDunGen()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/DunGen\";\n");
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  for (i=0;i<12;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(100);
+  }
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTitanium()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Titanium/Run\";\n");
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  for (i=0;i<3;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN,CH_SPACE,0);
+    LBts(kbd.down_bitmap,SC_CURSOR_RIGHT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_UP,CH_SPACE,0);
+    LBtr(kbd.down_bitmap,SC_CURSOR_RIGHT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_DOWN,CH_SPACE,0);
+    LBts(kbd.down_bitmap,SC_CURSOR_LEFT);
+    Sleep(200);
+    PostMsgWait(task,MSG_KEY_UP,CH_SPACE,0);
+    LBtr(kbd.down_bitmap,SC_CURSOR_LEFT);
+    Sleep(200);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoToTheFront()
+{
+  I64 task_num;
+  CTask *task=User("#include \"::/Apps/ToTheFront/Run\";\n");
+  task_num=BirthWait(&task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,'\n',0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  task_num=BirthWait(&task->popup_task,task_num);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  BirthWait(&task->popup_task,task_num);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  Sleep(5000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPsalmody()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Psalmody/Run\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'z',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'h',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'h',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'g',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'g',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'h',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'h',0);
+  PostMsgWait(task,MSG_KEY_DOWN,'j',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_UP,'j',0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT+SCF_CTRL);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'x',0);
+  Sleep(1250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoJukeBox()
+{
+  CTask *task=User("#include \"::/Apps/Psalmody/Load\";"
+        "JukeBox(\"::/Apps/Psalmody/Examples\");\n");
+  BirthWait(&task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(1500);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task->popup_task);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSpan()
+{
+  CTask *task=User("#include \"::/Apps/Span/Run\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoStrut()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Strut/Run\";\n");
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  Refresh(2);
+
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'s',0);
+
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,GR_HEIGHT/2,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,GR_HEIGHT/2,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,GR_HEIGHT/2,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'t',0);
+
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(GR_WIDTH-200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(GR_WIDTH/2,400,,TRUE);
+  PostMsgWait(task,MSG_MS_L_DOWN,0,0);
+  MsSet(200,200,,TRUE);
+  PostMsgWait(task,MSG_MS_L_UP,0,0);
+
+  MsSet(,,,FALSE);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  LBts(kbd.down_bitmap,Char2ScanCode('1'));
+  Sleep(600);
+  LBtr(kbd.down_bitmap,Char2ScanCode('1'));
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'Z',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'Z',0);
+  Sleep(200);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'Z',0);
+  Sleep(200);
+
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRawHide()
+{
+  CTask *task=User("#include \"::/Demo/Games/RawHide\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(2500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPoleZeros()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/PoleZeros\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoWhap()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Whap\";\n");
+  MsSet(300,200);
+  Sleep(500);
+  InSetMs(3,350,300);
+  Sleep(500);
+  InSetMs(3,450,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoGrid()
+{
+  CTask *task=User("#include \"::/Demo/Graphics/Grid\";\n");
+  MsSet(200,200);
+  Sleep(150);
+  InSetMs(2,400,400);
+  InSetMs(2,200,400);
+  InSetMs(2,200,200);
+  MsSet(,,,TRUE);
+  Sleep(50);
+  MsSet(,,,FALSE);
+  DocBottom(DocPut(task));
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPick()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Pick\";\n");
+  MsSet(200,200);
+  Sleep(500);
+  MsSet(,,,TRUE);
+  InSetMs(4,400,400);
+  MsSet(,,,FALSE);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPick3D()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Graphics/Pick3D\";\n");
+  MsSet(200,200);
+  Sleep(500);
+  MsSet(,,,TRUE);
+  InSetMs(4,400,400);
+  MsSet(,,,FALSE);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoGrModels()
+{
+  CTask *task=User;
+  I64 i,j,task_num=-1;
+  XTalkWait(task,"#include \"::/Apps/GrModels/Run\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  for (i=0;i<4;i++) {
+    task_num=BirthWait(&task->popup_task,task_num);
+    TaskWait(task->popup_task);
+    for (j=0;j<=i;j++)
+      PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'n',0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoKeepAway()
+{
+  CTask *task=User("#include \"::/Apps/KeepAway/Run\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  MsSet(100,100);
+  Sleep(1500);
+  PostMsgWait(task,MSG_MS_R_DOWN_UP,ms.pos.x,ms.pos.y);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRocket()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Rocket\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+  Bts(kbd.down_bitmap,SC_CURSOR_UP);
+  Sleep(1000);
+  Btr(kbd.down_bitmap,SC_CURSOR_UP);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  Bts(kbd.down_bitmap,SC_CURSOR_RIGHT);
+  Sleep(1000);
+  Btr(kbd.down_bitmap,SC_CURSOR_RIGHT);
+  Sleep(1000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRocketScience()
+{
+  CTask *task=User("#include \"::/Demo/Games/RocketScience\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(2000);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMassSpring()
+{
+  CTask *task=User("#include \"::/Demo/Games/MassSpring\";\n");
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,50,50);  //#1
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,50,200); //#2
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,210,50); //#3
+  PostMsgWait(task,MSG_MS_L_DOWN_UP,310,200);//#4
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,50,50); //1-2
+  PostMsgWait(task,MSG_MS_R_UP,50,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,210,50);//3-4
+  PostMsgWait(task,MSG_MS_R_UP,310,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,50,200);//2-4
+  PostMsgWait(task,MSG_MS_R_UP,310,200);
+  Sleep(500);
+  PostMsgWait(task,MSG_MS_R_DOWN,50,50); //1-3
+  PostMsgWait(task,MSG_MS_R_UP,210,50);
+  Sleep(1500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSquirt()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Squirt\";\n");
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(100);
+  }
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_LEFT);
+    Sleep(100);
+  }
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(100);
+  }
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(100);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoXCaliber()
+{
+  I64 i;
+  CTask *task=User;
+  XTalk(task,"#include \"::/Apps/X-Caliber/Run\";\n");
+
+  Sleep(100);
+  if(TaskValidate(task->popup_task)) {
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,0,SCF_CTRL|SC_CURSOR_DOWN);
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    DeathWait(&task->popup_task);
+  }
+
+  for (i=0;i<5;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SCF_SHIFT|SC_CURSOR_UP);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SCF_SHIFT|SC_CURSOR_RIGHT);
+  }
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    PostMsgWait(task,MSG_KEY_DOWN,0,SC_CURSOR_RIGHT,0);
+    Sleep(100);
+    PostMsgWait(task,MSG_KEY_UP,0,SC_CURSOR_RIGHT,0);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFPS()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/CastleFrankenstein\";\n");
+  for (i=0;i<15;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+  }
+  for (i=0;i<8;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(50);
+  }
+  for (i=0;i<9;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+  }
+  for (i=0;i<6;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoTalons()
+{
+  I64 i;
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Games/Talons\";\n");
+  Sleep(500);
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP);
+    Sleep(50);
+  }
+  for (i=0;i<10;i++) {
+    PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+    Sleep(50);
+  }
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPhoneNumWords()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/PhoneNumWords\";\n");
+  XTalkWait(task,"702-254-4223\n\n");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSuggestedSpelling()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/SuggestSpelling\";\n");
+  XTalkWait(task,"effecient\n\n");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFPrintF()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Dsk/FPrintF\";\n");
+  XTalkWait(task,"~/DemoFPrintF.DD.Z");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  XTalkWait(task,"Type(\"~/DemoFPrintF.DD.Z\");\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_CTRLO,0);
+  XTalkWait(task,"Del(\"~/DemoFPrintF.DD*\");\n");
+  Sleep(500);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLastClass()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/LastClass\";\n");
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMiniCompiler()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Lectures/MiniCompiler\";\n");
+  XTalkWait(task,"1+2*(3+4)\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoWebLog()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/WebLogDemo/WebLogRep\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'\n',0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,'\n',0);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoRevFile()
+{
+  CTask *task;
+  Del("~/DemoPoemFwd.DD*");
+  task=User("#include \"::/Demo/RevFileDemo/Rev\";"
+        "Type(\"~/DemoPoemFwd.DD.Z\");Sleep(750);\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoSortFile()
+{
+  CTask *task=User("#include \"::/Demo/SortFileDemo/F64FileGen\";"
+        "#include \"::/Demo/SortFileDemo/F64FileSort\";Sleep(750);\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoToHtmlToTXT()
+{
+  CTask *task=User("#include \"::/Demo/ToHtmlToTXTDemo/HtmlGen\";"
+        "#include \"::/Demo/ToHtmlToTXTDemo/TXTGen\";"
+        "Type(\"~/DemoOutPage.TXT\");Sleep(750);\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoLogic()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Apps/Logic/Run\";\n");
+  XTalkWait(task,"NAND\nNOR\n\n0x100\n0xF0\n0xCC\n0xAA\n\n0x12\n\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoPrompt()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Prompt\";\n");
+  XTalkWait(task,"1+2*3<<4\n");
+  XTalkWait(task,"1.0+2*3`2\n");
+  XTalkWait(task,"Terry Davis\n");
+  XTalkWait(task,"*-1\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoNumBible()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/NumBible\";\n");
+  Del("~/DemoNumBible.DD*");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoForm()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/Form\";\n");
+  Sleep(250);
+  XTalk(task,"54321");
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SCF_CTRL|SC_CURSOR_LEFT);
+  XTalk(task,"77777");
+  Sleep(250);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN);
+  Sleep(250);
+  XTalk(task,"MyName");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoClickCallBack()
+{
+  I64 i;
+  CTask *task=User("#include \"::/Demo/DolDoc/ClickCallBack\";\n");
+  for (i=0;i<3;i++) {
+    BirthWait(&task->popup_task);
+    TaskWait(task->popup_task);
+    PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+    Sleep(250);
+  }
+  Sleep(500);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMenuBttn()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/MenuBttn\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(500);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(500);
+  PostMsg(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  BirthWait(&task->popup_task);
+  TaskWait(task->popup_task);
+  Sleep(500);
+  PostMsgWait(sys_focus_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
+  Sleep(500);
+  PostMsgWait(task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task->popup_task);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoMenuSprite()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/MenuSprite\";\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(50);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(50);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,0,SC_CURSOR_DOWN,0);
+  Sleep(50);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(300);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoExceptions()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Exceptions\";\n");
+  XTalkWait(task,"yy");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDemoDoc()
+{
+  CTask *task=User;
+  XTalkWait(task,"Ed(\"::/Demo/DolDoc/DemoDoc.DD\");\n");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_CTRLG,0);
+  XTalkWait(task,"100");
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_ESC,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoFileRead()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/DolDoc/FileRead\";\n");
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  Sleep(750);
+  PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoDefine()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Define\";\n");
+  XTalkWait(task,"YS\n");
+  Sleep(750);
+  DeathWait(&task,TRUE);
+}
+
+U0 DoAsmAndC1()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Asm/AsmAndC1\";\n2\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 DoAsmAndC2()
+{
+  CTask *task=User;
+  XTalkWait(task,"#include \"::/Demo/Asm/AsmAndC2\";\n2\n");
+  DeathWait(&task,TRUE);
+}
+
+U0 OSTestSuite()
+{
+  CTask *task;
+  ts_t0=tS;
+  ts_i=0;
+
+  TS("BlackDiamond");   DoBlackDiamond;
+  TS("Talons");         DoTalons;
+  TS("FlatTops");       DoFlatTops;
+  TS("DunGen");         DoDunGen;
+  TS("FPS");            DoFPS;
+  TS("ZoneOut");        DoZoneOut;
+  TS("Varoom");         DoVaroom;
+  TS("Rocket");         DoRocket;
+  TS("RocketScience");  DoRocketScience;
+  TS("BattleLines");    DoBattleLines;
+  TS("BigGuns");        DoBigGuns;
+  TS("FlapBat");        DoFlapBat;
+  TS("Titanium");       DoTitanium;
+  TS("ToTheFront");     DoToTheFront;
+  TS("Psalmody");       DoPsalmody;
+  TS("JukeBox");        DoJukeBox;
+  TS("Span");           if (!sys_heap_init_flag) DoSpan; //Has FloodFill
+  TS("Strut");          DoStrut;
+  TS("RawHide");        DoRawHide;
+  TS("KeepAway");       DoKeepAway;
+  TS("XCaliber");       DoXCaliber;
+  TS("Wenceslas");      DoWenceslas;
+  TS("BomberGolf");     DoBomberGolf;
+  TS("TheDead");        DoTheDead;
+  TS("TreeCheckers");   DoTreeCheckers;
+  TS("RadixDort");      TSFile("::/Demo/RadixSort");
+  TS("MPAdd");          DoMPAdd;
+  TS("Primes");         TSFile("::/Demo/MultiCore/Primes");
+  TS("Palindrome");     if (FileFind(BIBLE_FILENAME))
+                                TSFile("::/Demo/MultiCore/Palindrome");
+  TS("MPRadix");        if (mp_cnt>1) TSFile("::/Demo/MultiCore/MPRadix");
+  TS("LoadTest");       if (mp_cnt>1 && DrvIsWritable(':'))
+                                TSFileChar("::/Demo/MultiCore/LoadTest");
+  TS("MPPrint");        if (mp_cnt>1) TSFile("::/Demo/MultiCore/MPPrint");
+  TS("Lock");           if (mp_cnt>1) TSFile("::/Demo/MultiCore/Lock");
+  TS("Interrupts");     if (mp_cnt>1) TSFile("::/Demo/MultiCore/Interrupts");
+  TS("SpritePlot");     TSFileChar("::/Demo/Graphics/SpritePlot");
+  TS("Elephants");      TSFileChar("::/Demo/Graphics/Elephant",,CH_SHIFT_ESC);
+  TS("SpritePlot3D");   TSFileChar("::/Demo/Graphics/SpritePlot3D");
+  TS("SpritePut");      TSFile("::/Demo/Graphics/SpritePut");
+  TS("SpritePutExt");   TSFile("::/Demo/Graphics/SpritePutExt");
+  TS("SpriteText");     TSFile("::/Demo/Graphics/SpriteText");
+  TS("SpriteRaw");      TSFile("::/Demo/Graphics/SpriteRaw");
+  TS("EdSprite");       TSFile("::/Demo/Graphics/EdSprite");
+  TS("Balloon");        TSFile("::/Demo/Graphics/Balloon",0);
+  TS("Carry");          TSFile("::/Demo/Carry");
+  TS("Directives");     TSFile("::/Demo/Directives");
+  TS("RandDemo");       DoRandDemo;
+  TS("Extents");        TSFileChar("::/Demo/Graphics/Extents");
+  TS("NetOfDots");      TSFileChar("::/Demo/Graphics/NetOfDots");
+  TS("SunMoon");        TSFileChar("::/Demo/Graphics/SunMoon");
+  TS("LowPassFilter");  DoLowPassFilter;
+  TS("MathAudioDemo");  DoMathAudioDemo;
+  TS("Lines");          TSFileChar("::/Demo/Graphics/Lines");
+  TS("Bounce"); TSFileChar("::/Demo/Graphics/Bounce",,CH_SHIFT_ESC,FALSE);
+  TS("MsgLoop");        DoMsgLoop;
+  TS("ASCIIOrgan");     DoASCIIOrgan;
+  TS("MorseCode");      DoMorseCode;
+  TS("PixCollision");   DoPixCollision;
+  TS("Doodle");         DoDoodle;
+  TS("MassSpring");     DoMassSpring;
+  TS("SpeedLine");      DoSpeedLine;
+  TS("KeyBitMap");      DoKeyBitMap;
+  TS("BSpline");        DoBSpline;
+  TS("GrModels");       DoGrModels;
+  TS("Blot");           TSFileChar("::/Demo/Graphics/Blot",1800);
+  TS("ScrnCapture");    if (DrvIsWritable('~')) DoScrnCapture;
+  TS("Grid");           DoGrid;
+  TS("Pick");           DoPick;
+  TS("Pick3D");         DoPick3D;
+  TS("Whap");           DoWhap;
+  TS("Palette");        DoPalette;
+  TS("Print");          TSFile("::/Demo/Print");
+  TS("Shading");        TSFileChar("::/Demo/Graphics/Shading",1500);
+  TS("RotateTank");     TSFileChar("::/Demo/Graphics/RotateTank",1500);
+  TS("3DPoly");         TSFileChar("::/Demo/Graphics/3DPoly",1500);
+  TS("Box");            TSFileChar("::/Demo/Graphics/Box",1500);
+  TS("Symmetry");       DoSymmetry;
+  TS("Shadow");         TSFileChar("::/Demo/Graphics/Shadow",1500);
+  TS("Transform");      TSFileChar("::/Demo/Graphics/Transform",,CH_SHIFT_ESC);
+  TS("LightTable");     DoLightTable;
+  TS("PredatorPrey");   DoPredatorPrey;
+  TS("PoleZeros");      DoPoleZeros;
+  TS("Digits");         DoDigits;
+  TS("Stadium");        DoStadium;
+  TS("ElephantWalk");   DoElephantWalk;
+  TS("Halogen");        DoHalogen;
+  TS("Maze");           TSFileChar("::/Demo/Games/Maze",,CH_SHIFT_ESC);
+  TS("FontEd");         TSFileChar("::/Demo/Graphics/FontEd",,CH_SHIFT_ESC);
+  TS("Lattice");        DoLattice;
+  TS("CtrlR1");         DoCtrlR1;
+  TS("F2Macro");        DoF2Macro;
+  TS("SubIntAccess");   TSFile("::/Demo/SubIntAccess");
+  TS("DemoDoc");        DoDemoDoc;
+  TS("TreeDemo");       TSFile("::/Demo/DolDoc/TreeDemo");
+  TS("TextDemo");       TSFile("::/Demo/DolDoc/TextDemo");
+  TS("CursorMove");     TSFile("::/Demo/DolDoc/CursorMove");
+  TS("MiniCompiler");   DoMiniCompiler;
+  TS("MiniGrLib");      TSFile("::/Demo/Lectures/MiniGrLib",0);
+  TS("TimeIns");        TSFileChar("::/Demo/TimeIns");
+  TS("PhoneNumWords");  DoPhoneNumWords;
+  TS("UnusedSpaceRep"); TSFile("::/Demo/Dsk/UnusedSpaceRep");
+  TS("BlkDevRep");      TSFile("::/Demo/Dsk/BlkDevRep");
+  TS("LastClass");      DoLastClass;
+  TS("FPrintF");        if (DrvIsWritable('~')) DoFPrintF;
+  TS("SerializeTree");  TSFile("::/Demo/Dsk/SerializeTree");
+  TS("Exceptions");     DoExceptions;
+  TS("ScrnDCodes");     TSFileChar("::/Demo/ScrnCodes");
+  TS("ExtChars");       TSFile("::/Demo/ExtChars");
+  TS("PanText");        TSFile("::/Demo/Graphics/PanText",0);
+  TS("CharAnimation");  TSFile("::/Demo/Graphics/CharAnimation");
+  TS("CharDemo");       DoCharDemo;
+  TS("DateTime");       TSFile("::/Demo/DateTime");
+  TS("SubSwitch");      TSFile("::/Demo/SubSwitch");
+  TS("NullCase");       TSFile("::/Demo/NullCase");
+  TS("Magicpairs");     TSFile("::/Demo/MagicPairs");
+  TS("Hanoi");          TSFileChar("::/Demo/Graphics/Hanoi",3000);
+  TS("Squirt");         DoSquirt;
+  TS("CommonAncestor");
+        TSFileChar("::/Demo/Graphics/CommonAncestor",1500,CH_SHIFT_ESC);
+  TS("Cartesian");      DoCartesian;
+  TS("RainDrops");      TSFileChar("::/Demo/Games/RainDrops",,CH_SHIFT_ESC);
+  TS("Collision");      TSFileChar("::/Demo/Games/Collision",1500);
+  TS("Logic");          DoLogic;
+  TS("CompileDemo");    TSFile("::/Demo/CompileDemo");
+  TS("Prompt");         DoPrompt;
+  TS("WebLog");         if (DrvIsWritable('~')) DoWebLog;
+  TS("RevFile");        if (DrvIsWritable('~')) DoRevFile;
+  TS("SortFile");       if (DrvIsWritable('~')) DoSortFile;
+  TS("ToHtmlToTXT");    if (DrvIsWritable('~')) DoToHtmlToTXT;
+  TS("RegistryDemo");   if (DrvIsWritable('~'))
+                                TSFile("::/Demo/RegistryDemo");
+  TS("Define");         DoDefine;
+  TS("GlblVars");       TSFile("::/Demo/GlblVars");
+  TS("FileRead");       DoFileRead;
+  TS("ParenWarn");      TSFile("::/Demo/ParenWarn");
+  TS("DefineStr");      TSFile("::/Demo/DolDoc/DefineStr");
+  TS("Data");           TSFile("::/Demo/DolDoc/Data");
+  TS("CallBack");       TSFile("::/Demo/DolDoc/CallBack");
+  TS("ClassMeta");      TSFile("::/Demo/ClassMeta");
+  TS("NumBible");       if (DrvIsWritable('~')) DoNumBible;
+  TS("Form");           DoForm;
+  TS("ClickCallBack");  DoClickCallBack;
+  TS("MenuBttn");       DoMenuBttn;
+  TS("MenuSprite");DoMenuSprite;
+  TS("SuggestedSpelling"); DoSuggestedSpelling;
+  TS("WordSearch");     TSFileChar("::/Demo/WordSearch");
+  TS("StkGrow");        TSFile("::/Demo/StkGrow");
+  TS("MemDemo");        TSFile("::/Demo/MemDemo");
+  TS("WaterFowl");      TSFileChar("::/Demo/Snd/WaterFowl");
+  TS("AsmHelloWorld");  TSFile("::/Demo/Asm/AsmHelloWorld");
+  TS("AsmAndC1");       DoAsmAndC1;
+  TS("AsmAndC2");       DoAsmAndC2;
+  TS("AsmAndC3");       TSFile("::/Demo/Asm/AsmAndC3");
+  TS("MulByHand");      TSFile("::/Demo/Asm/MulByHand");
+  TS("DivByHand");      TSFile("::/Demo/Asm/DivByHand");
+  TS("BuzzFizz");       TSFile("::/Demo/Asm/BuzzFizz");
+  TS("PutDec");         TSFile("::/Demo/Asm/PutDec");
+
+  task=User;
+  TS("Prof");           XTalkWait(task,"DocMax;Prof;HeapLog(ON);\n");
+  TS("PCIRep");         XTalkWait(task,"PCIRep;Sleep(750);\n");
+  TS("MemBIOSRep");     XTalkWait(task,"MemBIOSRep;Sleep(750);\n");
+  TS("MemPageRep");     XTalkWait(task,"MemPageRep;Sleep(750);\n");
+  TS("MemRep");         XTalkWait(task,"MemRep;Sleep(750);\n");
+  TS("ZipRep");         XTalkWait(task,"ZipRep;Sleep(750);\n");
+  TS("ProfRep");        XTalkWait(task,"ProfRep;Sleep(750);\n");
+  TS("HeapLogSizeRep"); XTalkWait(task,"HeapLogSizeRep;Sleep(750);\n");
+  TS("CPURep");         if (mp_cnt>1)
+                                XTalkWait(task,"CPURep(TRUE);Sleep(750);\n");
+  TS("DskChk");         if (DrvIsWritable(':'))
+                                XTalkWait(task,"DskChk;Sleep(750);\n");
+  TS("DrvView");        if (DrvIsWritable(':')) {
+    XTalkWait(task,"DrvView;\n");
+    Sleep(750);
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  TS("DskView");        if (DrvIsWritable(':')) {
+    XTalkWait(task,"DskView;\n");
+    Sleep(250); //Short because ATARep takes time.
+    PostMsgWait(task,MSG_KEY_DOWN_UP,CH_SPACE,0);
+  }
+  TS("ATARep");         XTalkWait(task,"ATARep;\npSleep(750);\n");
+  TS("HashDepthRep");   XTalkWait(task,
+        "HashDepthRep(adam_task->hash_table);Sleep(750);\n");
+  TS("Who");            XTalkWait(task,"Who;Sleep(750);\n");
+  TS("DrvRep");         XTalkWait(task,"DrvRep;Sleep(750);\n");
+  TS("TaskRep");        XTalkWait(task,"TaskRep;Sleep(750);\n");
+  DeathWait(&task,TRUE);
+
+  ProgressBarsRst("TempleOS/OSTestSuite");
+  "Elapsed Time:%5.3f\n",tS-ts_t0;
+}
+
+OSTestSuite;
+
+ diff --git a/public/Wb/Once.HC.HTML b/public/Wb/Once.HC.HTML new file mode 100755 index 0000000..91edd0d --- /dev/null +++ b/public/Wb/Once.HC.HTML @@ -0,0 +1,86 @@ + + + + + + + + + + + +
+//Place this file in /Home and change
+//anything you want.
+
+//This file is executed by the
+//first terminal window upon start-up.
+//See Once and Home Files.
+
+//Delete the rest from this file.
+
+U0 Tmp()
+{
+  OnceExe;
+  switch (sys_boot_src.u16[0]) {
+    case BOOT_SRC_ROM:
+      "Continue booting hard drive ";
+      if (YorN) {
+        DocBottom;
+        ExeFile("C:/Home/Once");
+      }
+      break;
+    case BOOT_SRC_DVD:
+      "\nIf you answer 'No' you can play with\n"
+            "the live CD without installing.\n\n"
+            "Install onto hard drive ";
+      if (YorN) {
+        DocBottom;
+        RunFile("::/Misc/OSInstall",,TRUE);
+      }
+      if (FileFind("::/Misc/Tour")) {
+        "\nTake Tour";
+        if (YorN) {
+          DocBottom;
+          Cd("::/Misc/Tour");
+          InFile("Tour");
+        }
+      }
+      break;
+    case BOOT_SRC_RAM:
+    case BOOT_SRC_HARDDRV:
+      "$PURPLE$$TX+CX,\"Tip of the Day\"$$FG$\n";
+      TipOfDay;
+      Type("::/Doc/Customize.DD");
+      if (FileFind("::/Misc/Tour")) {
+        "\nTake Tour";
+        if (YorN) {
+          DocBottom;
+          Cd("::/Misc/Tour");
+          InFile("Tour");
+        }
+      }
+      break;
+  }
+}
+
+Tmp;
+
+ diff --git a/public/Wb/PersonalMenu.DD.HTML b/public/Wb/PersonalMenu.DD.HTML index f0bf8f8..d237f64 100755 --- a/public/Wb/PersonalMenu.DD.HTML +++ b/public/Wb/PersonalMenu.DD.HTML @@ -53,18 +53,18 @@ Cd("::/Apps");Dir; -Run TOSStdIns() if you wish to +Run TOSStdIns() if you wish to use the official staff /Home files. Cd("::/Demo/AcctExample");Dir; -Make all with BootHDIns(). +Make all with BootHDIns(). Cd("::/Kernel");Dir; Cd("::/Compiler");Dir; -The ::/StartOS.HC file is compiled every time you boot. +The ::/StartOS.HC file is compiled every time you boot. Cd("::/Adam");Dir; diff --git a/public/Wb/StartOS.HC.HTML b/public/Wb/StartOS.HC.HTML new file mode 100755 index 0000000..c4bf7ba --- /dev/null +++ b/public/Wb/StartOS.HC.HTML @@ -0,0 +1,77 @@ + + + + + + + + + + + +
+//This is executed by the Adam task at boot.
+//See Adam Start-up.
+
+#help_index "Compiler/Directive"
+public extern I8i Option(I64i num,I8i val);
+Option(0,0); //(0,0)=EchoOff   (0,1)=EchoOn
+
+#include "/Kernel/KernelA.HH"
+#include "/Compiler/CompilerA.HH"
+#include "/Kernel/KernelB.HH"
+#include "/Kernel/KernelC.HH"
+#include "/Compiler/CompilerB.HH"
+
+Option(OPTf_WARN_PAREN,ON);
+Option(OPTf_WARN_DUP_TYPES,ON);
+HashTablePurge(adam_task->hash_table);
+
+#include "/Adam/MakeAdam"
+
+//Dbg("Type 'G;'");
+DocTermNew;
+WinVert(2,10);
+
+sys_winmgr_task=Spawn(&WinMgrTask,NULL,"Window Mgr");
+Fs->win_inhibit=WIG_TASK_DFT-WIF_SELF_BORDER
+        -WIF_SELF_GRAB_SCROLL-WIF_SELF_CTRLS;
+LBts(&Fs->display_flags,DISPLAYf_CHILDREN_NOT_ON_TOP);
+LBts(&Fs->display_flags,DISPLAYf_SHOW);
+RegInit;
+LBts(&sys_run_level,RLf_REGISTRY);
+if (!ins_reg.registered)
+  InsUnreg;
+
+WallPaperInit;
+
+if (DrvIsWritable)
+  DirMk("/Tmp"); //Good to have a Tmp
+
+Option(OPTf_WARN_PAREN,OFF);
+Option(OPTf_WARN_DUP_TYPES,OFF);
+LBts(&sys_run_level,RLf_HOME);
+
+#help_index ""
+#include "~/MakeHome"
+
+//After this file, the Adam task enters server mode.
+
+